Skip to content

feat: add tools and skills from LaunchDarkly - #947

Open
ctawiah wants to merge 1 commit into
ctawiah/keep-unused-attachments-1e8afrom
ctawiah/add-attachments-1e8a
Open

ctawiah wants to merge 1 commit into
ctawiah/keep-unused-attachments-1e8afrom
ctawiah/add-attachments-1e8a

Conversation

@ctawiah

@ctawiah ctawiah commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Context

ldcli sync prompts add writes the files of variations that exist in LaunchDarkly, and records their baseline in sync.lock and in the LaunchDarkly manifest. The tools and skills of each variation come with it. But no command starts syncing a tool or skill on its own.

This stack adds sync tools add and sync skills add in three PRs, to keep each PR small. This PR adds the add itself. The next PR routes the commands to it by scope, and the PR after that adds the commands.

What changes

  • bootstrap.Run takes a Kind. For a tool or a skill, it calls the new addAttachments.
  • Without --key values, add asks for a project and for one tool or skill with a search picker. SelectAttachment moves from prompt/attach.go into interactive, so attach and add share it. Without a terminal, the error names the flags: --project and --key are required with --no-input.
  • Add checks every selection before it writes. It refuses a tool or skill with a file, or with a sync.lock row and no file. It also refuses one that LaunchDarkly does not have. So one bad selection writes nothing.
  • A dry run lists the files with their line counts, and --diff shows their content, as for variations.
  • Add writes the files with Store.ReplaceAttachments, records the rows, and saves. If the save fails, it removes the new files.

The errors name the next step:

tool demo/lookup is already synced. Edit .launchdarkly/demo/tools/lookup.json and run ldcli sync tools.
skill demo/triage has a sync.lock entry but no local file. Run ldcli sync skills to restore it.
tool demo/nope does not exist in LaunchDarkly.

A dry run with --diff:

1 file to create:
  .launchdarkly/demo/skills/triage.md   +8

.launchdarkly/demo/skills/triage.md
    ---
    key: triage
    description: Triage a ticket
    ---

    # Triage

    Pick a queue.

Design notes

  • The write reuses ReplaceAttachments from feat: apply tool and skill rows in a sync #941. The preview reuses writePreviews and the new RenderAttachment, a small wrapper of the existing renderer. Store.Render renders variation files, so it does not fit a tool alone.
  • AttachmentPath and AttachmentExists give the repository path and the existence check of one tool or skill file.
  • The error for a tool that LaunchDarkly does not have names no create flags yet. A later PR in the stack adds them, with the flags.
  • This PR must ship in the same ldcli release as feat: apply tool and skill rows in a sync #941, with the next two PRs. feat: apply tool and skill rows in a sync #941 can apply tool and skill rows, and these three PRs make that reachable from the command line.

Review focus

  • Do all the checks run before the first write, so that one bad selection writes nothing?
  • Is the cleanup after a failed save complete?

Verification

  • go test ./... and golangci-lint run (v2.9.0) pass.
  • The new bootstrap/attachments_test.go covers adds by key, each refusal, the dry run, the cleanup after a failed save, and the errors without input.
  • No command reaches this code yet. The acceptance tests of the next PR run it through Runner.Run, and the PR after that runs it through the commands.

Related changes

This stack builds on #937 to #941, which are merged.

  1. fix: exclude expanded tools from prompt diffs #957: Exclude expanded tools from prompt diffs (ctawiah/fix-prompt-tool-diff-5b1c)
  2. fix: plan a tool or skill row when a variation newly references it #945: Plan a tool or skill row when a variation newly references it (ctawiah/plan-referenced-attachments-1e8a)
  3. feat: keep unused tools and skills, and detach any resource kind #946: Keep unused tools and skills, and detach any resource kind (ctawiah/keep-unused-attachments-1e8a)
  4. This PR: add tools and skills from LaunchDarkly (ctawiah/add-attachments-1e8a)
  5. feat: route sync, add, and detach by scope #948: Route sync, add, and detach by scope (ctawiah/route-scopes-1e8a)
  6. feat: add the sync all, sync tools, and sync skills commands #949: Add the sync all, sync tools, and sync skills commands (ctawiah/scope-commands-1e8a)
  7. feat: create a tool or a skill from the content of an add #950: Create a tool or a skill from the content of an add (ctawiah/create-attachments-1e8a)
  8. feat: add the create flags of sync tools add and sync skills add #951: Add the create flags of sync tools add and sync skills add (ctawiah/create-attachment-flags-1e8a)
  9. refactor: share the selection of a new variation, and check any kind before an add #952: Share the selection of a new variation, and check any kind before an add (ctawiah/share-variation-selection-1e8a)
  10. feat: create a prompt variation from the content of an add #953: Create a prompt variation from the content of an add (ctawiah/create-variations-1e8a)
  11. feat: add the create flags of sync prompts add #954: Add the create flags of sync prompts add (ctawiah/create-variation-flags-1e8a)

Note

Overview
Extends bootstrap so Run can add tools and skills on their own (via Options.Kind), not only prompt variations. New addAttachments loads selections from LaunchDarkly (or an interactive project + attachment picker), validates every selection before any write (already on disk, orphan sync.lock row, or missing remotely), then writes under .launchdarkly and updates baselines—with rollback if manifest save fails. Dry run / --diff reuse the same preview path as variations.

Shared SelectAttachment (and AttachmentSearcher) moves into interactive for reuse by bootstrap and prompt attach. Local layer gains RenderAttachment, AttachmentPath, and AttachmentExists; ReplaceAttachments renders through the shared helper.

Reviewed by Cursor Bugbot for commit ed4bca5. Bugbot is set up for automated code reviews on this repo. Configure here.

@ctawiah
ctawiah added this pull request to stack #955 October 22, 2026 22:19
@cursor
cursor Bot force-pushed the ctawiah/add-attachments-1e8a branch from 75dde49 to ed4bca5 Compare October 23, 2026 00:13
@ctawiah
ctawiah removed this pull request from stack #955 October 23, 2026 00:15
@ctawiah
ctawiah added this pull request to stack #960 October 23, 2026 00:16
@ctawiah
ctawiah marked this pull request as ready for review October 23, 2026 14:09
@ctawiah
ctawiah requested a review from a team as a code owner October 23, 2026 14:09
@ctawiah
ctawiah requested review from nkester-ld and tiffanylphan and removed request for a team October 23, 2026 14:09
@cursor
cursor Bot force-pushed the ctawiah/add-attachments-1e8a branch from ed4bca5 to e468e2f Compare October 23, 2026 14:27
@cursor
cursor Bot force-pushed the ctawiah/add-attachments-1e8a branch from e468e2f to 16a81e2 Compare October 23, 2026 14:40
The add of the bootstrap package can now add tools and skills, as it adds
variations. With Kind set to tool or skill, Run reads each selected tool
or skill from LaunchDarkly, writes its file, and records its sync.lock
and remote manifest entries. Without a selection, it asks for the
project and then for one tool or skill, with the search picker of
attach. A dry run lists the files.

Add refuses a key that LaunchDarkly does not have, a key that is
already synced, and a key that has a sync.lock entry but no file. It
checks every key before it writes. If the baseline save fails, it
removes the new files.

The tool and skill picker moves from the prompt package to the
interactive package, so that bootstrap and attach share it. No command
reaches the new add yet.
@cursor
cursor Bot force-pushed the ctawiah/add-attachments-1e8a branch from 16a81e2 to cbed8fd Compare October 23, 2026 14:44
}

// Run writes the files of the selected variations and records their baseline.
// Run writes the files of the selected resources and records their baseline.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate that the comments have been maintained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants