Skip to content

Branch management: the first skill (plan) #1725

Description

@suleimansh

Plan for the first skill of skills-plus (#1681): worktree management, called branch management. Nothing built yet; this is for reading before code.

1. The skill

One npm package, @superskill/branch-management, shipping three things: SKILL.md, a CLI, and the same functions as an API. Per your skills-via-npm idea: the skill is versioned and pinned like any dependency, and SKILL.md reaches the agent from node_modules.

What SKILL.md tells the agent (replaces the Workspace and Session name sections of system_prompt.md):

  • You are started inside your own checkout, .the-framework/branches/tf-agent-<id>/. Everything you read or write is under it. The repo around it is the user's own working tree; never touch it.
  • Name the session: pick <name> ([a-z0-9-]+), run branch-management name <name>. It renames your branch to tf-<name> (a rename, not a new branch) and prints the final name — it may differ if the name was taken.
  • Commit as you go, on that branch. The framework publishes only what you committed and never commits for you (The catch-all safety commit will commit anything: 7,632 cache files went to main unnoticed #1638).
  • Before you finish: branch-management status must report a clean tree. Uncommitted work stays in your checkout and blocks its reclaim.
  • Do not push and do not open the pull request yourself; emit open-pr. Publishing is the dashboard's, per handoff level.

Not the agent's job: creating the checkout. An agent that creates its own would start inside the user's checkout, which #736 and #997 exist to prevent, and only Claude Code can switch its cwd mid-session. So the launcher (daemon or CLI) creates it before the process starts — through the same package. The skill states that requirement the way a skill says "make sure X is running".

2. The package

Git operations, as a CLI for the agent and an API for the dashboard; one implementation, every surface a caller:

command does today
create <id> [--base <ref>] worktree + branch tf-agent-<id>, dependency dirs linked in addWorktree, linkDependencies
attach <id> <branch> re-checkout for a continued agent attachWorktree
name <name> rename the current branch to tf-<name>, refresh the branches/tf-<name> link renameAgentBranch (dead today: the prompt has the agent branch itself)
status [path] branch, clean?, on the remote? worktreeClean, branchPushed, currentBranch
list [--sizes] every checkout under branches/ as JSON listWorktrees, listProjectWorktrees (git half)
remove <id> [--no-push] the retention rule: keep if dirty, push, remove once the remote has it, delete tf- branches that hold nothing removeProjectWorktree (git half)
prune remove for every checkout pruneProjectWorktrees

The package knows git only. Whether the agent is still running, and whether its handoff is local (--no-push), are the caller's facts, passed in.

Plain instructions, no code: the naming rule, commit-as-you-go, the workspace boundary, the end-of-session check.

3. Git conventions — the glue

Everything the dashboard reads about a branch it reads from git and the filesystem, never from the skill:

  • .the-framework/branches/<dir>/ — one checkout per agent; <dir> = tf-agent-<id>; branches symlink at the repo root; branches/tf-<name> symlink once named.
  • Branch names: tf-agent-<id> at birth, tf-<name> after naming. tf-* = minted by the framework, the only branches it may delete; tf-data never.
  • Session name = the checkout's branch minus tf-. New: read from git, so setSessionName(), the set-session-name block and the rename at cli.ts:626 go.
  • <checkout>/.the-framework/agent.json and events.jsonl — the live record, archived to tf-data:agents/<user>/. Written by the harness wrapper, not the skill.
  • Reclaimable = clean tree and tip contained in a remote ref. The cloud-agent anchor case should collapse into this rule (the anchor is a pushed ref); verified in step 1.

4. What core keeps

Callers, thin: the retained-worktrees list and the Remove / Delete / Prune buttons, teardown after an agent ends, the periodic sweep (tick, lock, busy set, say-it-once log), Delete's archive removal on tf-data, and handoff (push / PR / merge) — a later skill, not this one.

5. Files

  • Into the package (~1,000 lines + tests + SPECs): store/worktree.ts, store/worktree-deps.ts, branch-names.ts, branch-links.ts (minus the periodic pass), the git half of worktrees.ts.
  • Kept in core: merged-worktrees.ts (becomes prune on the daemon tick), data-branch.ts, dashboard-rpc/{control,reads}.ts, dashboard/agent-handoff.ts, the allocation and teardown sites in daemon-runtime.ts.
  • Deleted: the "birth branch the agent walked away from" logic (no second branch once naming is a rename); renameAgentBranch and the setSessionName plumbing (15 files, specs included); the the-framework/ legacy prefix (0 such branches on origin); the periodic branch-links reconcile (links are made at create/name/remove).

6. Order

  1. packages/branch-management in this monorepo: lift the files, framework imports it as a workspace dep. No behaviour change; publish 0.0.x to hold the name.
  2. The CLI on top; the daemon puts its bin on the agent's PATH.
  3. SKILL.md, appended to the system prompt the way system_prompt.md is today; name replaces "create and checkout tf-<name>"; the deletions above; FEATURES-SPEC.md updated.
  4. Dogfood on this repo, then the sweep.
  5. skills/branch-management.md as a symlink into node_modules, when the catalogue exists.

Questions

  • Package and bin name: @superskill/branch-management / branch-management?
  • Session name from the branch, dropping setSessionName(): yes?
  • You own @superskill: publish yourself, or add Suleiman?

🤖 curated · Fable 5, effort high

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions