Repository navigation
Conversation
ctawiah
added this pull request to stack #955
October 22, 2026 22:19
cursor
Bot
force-pushed
the
ctawiah/create-attachments-1e8a
branch
from
October 23, 2026 00:13
c69f654 to
b34a204
Compare
ctawiah
removed this pull request from stack #955
October 23, 2026 00:15
ctawiah
added this pull request to stack #960
October 23, 2026 00:16
This was referenced Oct 23, 2026
ctawiah
marked this pull request as ready for review
October 23, 2026 14:10
ctawiah
requested review from
nkester-ld and
zakk-verrilli-ld
and removed request for
a team
October 23, 2026 14:10
An add of a tool or a skill can now carry the content of a new resource: the input schema and the description of a tool, or the Markdown, the name, and the description of a skill. The new package internal/sync/create checks that content before any request, asks in a terminal for the values that are missing, and builds the resource with upsert. If LaunchDarkly has the resource with the content that the user passed, add starts syncing it through the existing add. If the content differs, add stops and changes nothing. Otherwise add plans the create in memory, asks for confirmation, and only then writes the file. It then applies the plan of that one resource through the normal sync path. A changed state or a rejected create removes the file again. A write with no response keeps the file, so that the next sync finishes the create. A skill file with upsert now keeps its name, because the create sends it. The checks of an add for a file or a sync.lock entry move into CheckNotSynced, so that the create uses the same checks. requiredValue moves from link into create. The command flags come in the next change.
cursor
Bot
force-pushed
the
ctawiah/create-attachments-1e8a
branch
from
October 23, 2026 14:27
b34a204 to
3eff865
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
sync tools addandsync skills addstart syncing a tool or skill that exists in LaunchDarkly. To create a new one, a user must write the file by hand withupsert: true, and then run sync. This PR and the next letaddcreate a missing tool or skill from flags. This PR has the create flow, throughRunner.Run. The next PR adds the flags. The work is in two PRs to keep each one small.What changes
AddAction.Createholds the content of a create. For a tool, that is the input schema and the description. For a skill, it is the Markdown, the name, and the description. A nil value is the existing add.inputSchema,schema, orformatVersionkey, gets--json-schema is the input schema only. Pass the value of "inputSchema", and pass the description with --description."$(cat file)"has the fingerprint of the file.--nameor--descriptionwithout the content flag gets--name and --description need --content. add creates a skill only when --content is set.--key. The key, the name, and the description must pass the create rules of LaunchDarkly.tool creation requires --project and --key without interactive input.create_serverrow in memory, and asks for confirmation unless--yesis set. Only then does it write the file withupsert: true. It applies the plan of that one resource through the normal sync path, so other pending changes stay as they are.name:, because a create sends that name.With the flags of the next PR, against a stand-in for the LaunchDarkly API:
An adopt and a refusal:
Design notes
internal/sync/createholds the input and its rules, so thatpromptimportscreateand not the other way around.Targetasks for the project and the key,Input.Askasks for the name and the description of a skill, andInput.Attachmentbuilds the resource. The input fields are pointers, so--content ""is a blank value and not a missing flag.runCreatereuses the sync path and adds no second apply. It usesplanAttachmentfor the reviewed row, thenreviewAndConfirmPlan. After the write, it usesloadStatewith a filter for the one ID,checkUnchanged,applyPlan, andRollbackCreation.applyPlannow returns the outcomes. So the create removes the file only when its own row failed with a definite error, not after a failed save.watchapplies a plan without deletes by itself, so a file that exists during the question can let a running watch create the resource first.sync.lockrow move from the add intobootstrap.CheckNotSynced, so both use one copy. The create runs them again right before the write, because a file can appear while the question waits.link.requiredValuemoves intocreateasRequiredValue, and its test moves with it.Review focus
Verification
go test ./...andgolangci-lint run(v2.9.0) pass.prompt/create_test.goruns each case of the add table throughRunner.Run, without a terminal and with an input reader that fails on any read:--yes400, a write with no response that the next sync finishes, and a409that reads againTestCreateAsksBeforeItWritesTheFilerecords whether the file exists when the question reads its answer. It fails when the write moves before the question.TestCreateKeepsTheFileAfterAWriteWithNoResponsefails when the removal ignoresMutationMayHaveSucceeded.create/create_test.gocovers the content rules, the builders, the adopt comparison, and the error for missing flags.ldcliand ran the flag-only script of the sync commands against a stand-in for the LaunchDarkly API. Its output is the same as before this PR. The next PR has the manual checks of the create.Related changes
This stack builds on #937 to #941, which are merged.
ctawiah/fix-prompt-tool-diff-5b1c)ctawiah/plan-referenced-attachments-1e8a)ctawiah/keep-unused-attachments-1e8a)ctawiah/add-attachments-1e8a)ctawiah/route-scopes-1e8a)ctawiah/scope-commands-1e8a)ctawiah/create-attachments-1e8a)ctawiah/create-attachment-flags-1e8a)ctawiah/share-variation-selection-1e8a)ctawiah/create-variations-1e8a)ctawiah/create-variation-flags-1e8a)Note
Overview
sync tools add/sync skills addcan create a missing tool or skill from create flags (wired throughAddAction.Create; CLI flags land in a follow-up PR). A newinternal/sync/createpackage validates input before any API call, resolves--project/--key(and skill name/description) interactively, buildsupsertattachments, and compares only flag-provided fields when LaunchDarkly already has the resource.When
Createis set,runAddrunsrunCreate: refuse if already synced (bootstrap.CheckNotSynced), adopt into normal add if remote content matches flags, error if it differs, otherwise plancreate_server, confirm (unless--yes), write the local file, and apply via the existing sync path for that resource only. The file is written after confirmation; it is rolled back on definite create failure or post-review state drift, but kept on ambiguous write errors so a later sync can finish.CheckNotSyncedis extracted from bootstrap add for shared use. Skill files withupsert: truenow persistnamein front matter.applyPlanreturns outcomes so create can remove the file only when its row failed with a definite error.Reviewed by Cursor Bugbot for commit b34a204. Bugbot is set up for automated code reviews on this repo. Configure here.