@openagt/skill-branches 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md CHANGED
@@ -9,12 +9,12 @@ Your work goes on a branch named `agent-<name>`, unless whoever started you cont
9
9
 
10
10
  ## The command
11
11
 
12
- `branches` is a dependency of this repository (`@openagt/skill-branches`). If `node_modules` is missing, install with the lockfile's package manager (`npm install` for `package-lock.json`). Then run `npx branches` inside your checkout, never a bare `branches`: a fresh clone has none. `status`, `name` and `push` (with no flag) are yours; the rest are the caller's.
12
+ Run the `branches` command inside your checkout, always by its full name: `npx @openagt/skill-branches@0.1`. `status`, `name` and `push` (with no flag) are yours; the rest are the caller's.
13
13
 
14
14
  ## Where you are
15
15
 
16
16
  ```
17
- npx branches status
17
+ npx @openagt/skill-branches@0.1 status
18
18
  ```
19
19
 
20
20
  It prints JSON; `branch` is the branch you are on.
@@ -24,7 +24,7 @@ It prints JSON; `branch` is the branch you are on.
24
24
  Before your first change, name the session with `[a-z0-9-]+`, starting with a letter or digit, saying what the work is, unless your branch already differs from `path`'s last segment: then it is named, keep it.
25
25
 
26
26
  ```
27
- npx branches name <name>
27
+ npx @openagt/skill-branches@0.1 name <name>
28
28
  ```
29
29
 
30
30
  It renames your branch to `agent-<name>` and prints it in `branch`: `agent-<name>-2`, `-3`, … when `<name>` was taken; a name outside `[a-z0-9-]+` is refused as `invalid-name`.
@@ -44,7 +44,7 @@ Nothing is committed for you.
44
44
  ## Before you finish
45
45
 
46
46
  ```
47
- npx branches status
47
+ npx @openagt/skill-branches@0.1 status
48
48
  ```
49
49
 
50
50
  It must report `"clean": true`. `clean` is false while anything is uncommitted or untracked: commit or delete what you added; if what remains is not yours, say so and finish.
@@ -54,7 +54,7 @@ It must report `"clean": true`. `clean` is false while anything is uncommitted o
54
54
  Only when your task or the person asks you to push or publish your work, and once clean:
55
55
 
56
56
  ```
57
- npx branches push
57
+ npx @openagt/skill-branches@0.1 push
58
58
  ```
59
59
 
60
60
  It pushes your branch to origin and prints it in `branch`. `clean` false is refused as `dirty`: commit or delete first.
@@ -64,7 +64,7 @@ It pushes your branch to origin and prints it in `branch`. `clean` false is refu
64
64
  Only when the person asks you to merge your work into the project's main branch, and once clean:
65
65
 
66
66
  ```
67
- npx branches merge <your branch>
67
+ npx @openagt/skill-branches@0.1 merge <your branch>
68
68
  ```
69
69
 
70
70
  It merges your branch into the main branch, in the project's own folder. A conflict changes nothing and names the files in `files`: say so and stop. Your checkout and your branch stay.
@@ -22,4 +22,10 @@ export declare function attachCheckout(repo: string, opts: {
22
22
  branch: string;
23
23
  base?: string;
24
24
  } & CheckoutSkills, git?: GitRunner): Promise<AddedWorktree>;
25
+ /**
26
+ * The links of a checkout that is already there, brought to what a new one gets: the package's
27
+ * command and skill, and the caller's skills. For a continued agent whose checkout stayed, made by
28
+ * whatever version ran then. A link that is there is left alone, so this is safe to ask again.
29
+ */
30
+ export declare function relinkCheckout(repo: string, path: string, opts?: CheckoutSkills, git?: GitRunner): Promise<void>;
25
31
  //# sourceMappingURL=checkout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAgC,MAAM,qBAAqB,CAAA;AAEjG,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAG/E,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAG5D;;;;;GAKG;AAEH,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;CAC9B;AAED,qGAAqG;AACrG,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,EACzD,GAAG,GAAE,SAA2B,GAC/B,OAAO,CAAC,aAAa,CAAC,CAIxB;AAED,sJAAsJ;AACtJ,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,EACzE,GAAG,GAAE,SAA2B,GAC/B,OAAO,CAAC,aAAa,CAAC,CAIxB"}
1
+ {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAgC,MAAM,qBAAqB,CAAA;AAEjG,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAG/E,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAG5D;;;;;GAKG;AAEH,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;CAC9B;AAED,qGAAqG;AACrG,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,EACzD,GAAG,GAAE,SAA2B,GAC/B,OAAO,CAAC,aAAa,CAAC,CAIxB;AAED,sJAAsJ;AACtJ,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,EACzE,GAAG,GAAE,SAA2B,GAC/B,OAAO,CAAC,aAAa,CAAC,CAIxB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3I"}
package/dist/checkout.js CHANGED
@@ -17,14 +17,23 @@ export async function attachCheckout(repo, opts, git = nodeGitRunner()) {
17
17
  await settle(repo, worktree.path, git, opts.skills);
18
18
  return worktree;
19
19
  }
20
+ /**
21
+ * The links of a checkout that is already there, brought to what a new one gets: the package's
22
+ * command and skill, and the caller's skills. For a continued agent whose checkout stayed, made by
23
+ * whatever version ran then. A link that is there is left alone, so this is safe to ask again.
24
+ */
25
+ export async function relinkCheckout(repo, path, opts = {}, git = nodeGitRunner()) {
26
+ await linkOwnCommand(repo, path, git);
27
+ await linkSkill(repo, path, undefined, git, opts.skills);
28
+ }
20
29
  /**
21
30
  * What a checkout gets besides its files. All best-effort: the checkouts are the package's state
22
31
  * and hidden from the project's git the moment the first one exists (#1600) — as an untracked
23
32
  * directory at the root, `.branches/` would ride any sweeping `git add -A` onto a code branch —
24
33
  * through the repository's own exclude file, so no tracked file changes; `node_modules` is
25
34
  * gitignored, so a fresh checkout has none and a link that cannot be made is a worse run, not a
26
- * failed one; the package's own command is linked into a checkout that has none, so the skill's
27
- * `npx branches` runs it and downloads nothing (`command-link.ts`); a link under `.branches/` is a view, and the next reconcile pass makes it.
35
+ * failed one; the package and its command are linked into a checkout that has neither, so the skill's
36
+ * `npx @openagt/skill-branches@0.1` runs this copy and downloads nothing (`command-link.ts`); a link under `.branches/` is a view, and the next reconcile pass makes it.
28
37
  */
29
38
  async function settle(repo, path, git, skills = []) {
30
39
  await excludeFromGit(repo, `/${BRANCHES_DIR}`, undefined, git).catch(() => { });
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAsB,MAAM,eAAe,CAAA;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAkB,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAclD,qGAAqG;AACrG,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,IAAyD,EACzD,GAAG,GAAc,aAAa,EAAE;IAEhC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC1J,MAAM,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACnD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,sJAAsJ;AACtJ,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,IAAyE,EACzE,GAAG,GAAc,aAAa,EAAE;IAEhC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC3I,MAAM,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACnD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,MAAM,CAAC,IAAY,EAAE,IAAY,EAAE,GAAc,EAAE,MAAM,GAAyB,EAAE;IACjG,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,YAAY,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAC9E,MAAM,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IAClD,sGAAsG;IACtG,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;IACrC,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IACnD,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAC3D,CAAC"}
1
+ {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"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"}
package/dist/cleanup.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type GitRunner } from '@openagt/agent-data';
2
+ import { type SkillLink } from './skill-links.js';
2
3
  /**
3
4
  * `cleanup`: what this tool left in a project, removed, for a person who takes the project out of
4
5
  * a dashboard and asks for the tool's files to go too. The tool removes its own and nothing else:
@@ -30,4 +31,11 @@ export interface CleanupOutcome {
30
31
  * line saying why it stayed.
31
32
  */
32
33
  export declare function cleanup(repo: string, reclaimOne: (agentId: string) => Promise<string | undefined>, git?: GitRunner): Promise<CleanupOutcome>;
34
+ /**
35
+ * Take back the rules that hide `skills`' links, for a caller that had skills of its own linked
36
+ * into the checkouts (`SkillLink`) and now removes what it left in the project. Under this
37
+ * tool's own rule for its links: a rule goes once no agent checkout is left anywhere in the
38
+ * repository, since every checkout reads the one exclude file.
39
+ */
40
+ export declare function liftSkillRules(repo: string, skills: readonly SkillLink[], git?: GitRunner): Promise<void>;
33
41
  //# sourceMappingURL=cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAOxH;;;;;;;;;;;;;;;GAeG;AAEH,iFAAiF;AACjF,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,IAAI,EAAE,CAAA;CACb;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAsCnK"}
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAIxH,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAGjG;;;;;;;;;;;;;;;GAeG;AAEH,iFAAiF;AACjF,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,IAAI,EAAE,CAAA;CACb;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAsCnK;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhI"}
package/dist/cleanup.js CHANGED
@@ -3,8 +3,8 @@ import { basename, dirname, join } from 'node:path';
3
3
  import { BRANCHES_DIR, nodeGitRunner, repositoryCheckouts, unexcludeFromGit } from '@openagt/agent-data';
4
4
  import { reconcileBranchLinks } from './branch-links.js';
5
5
  import { isAgentBranch } from './branch-names.js';
6
- import { COMMAND } from './command-link.js';
7
- import { HARNESS_SKILL_DIRS, SKILL_NAME } from './skill-links.js';
6
+ import { COMMAND_LINKS } from './command-link.js';
7
+ import { HARNESS_SKILL_DIRS, SKILL_NAME, skillLinkPaths } from './skill-links.js';
8
8
  import { worktreeDirEntries } from './worktree.js';
9
9
  /**
10
10
  * `reclaimOne` removes one agent's checkout under the reclaim rule and answers nothing, or the
@@ -44,7 +44,7 @@ export async function cleanup(repo, reclaimOne, git = nodeGitRunner()) {
44
44
  if (checkouts) {
45
45
  // A link lives in an agent's checkout: with none left in the repository, the rules hide nothing.
46
46
  if (!kept.some(entry => isAgentBranch(basename(entry.path))) && !checkouts.some(path => basename(dirname(path)) === BRANCHES_DIR && isAgentBranch(basename(path)))) {
47
- for (const rule of [`/node_modules/.bin/${COMMAND}`, ...HARNESS_SKILL_DIRS.map(skills => `/${skills}/${SKILL_NAME}`)]) {
47
+ for (const rule of [...COMMAND_LINKS.map(link => `/${link}`), ...HARNESS_SKILL_DIRS.map(skills => `/${skills}/${SKILL_NAME}`)]) {
48
48
  await unexcludeFromGit(repo, rule, undefined, git).catch(() => { });
49
49
  }
50
50
  }
@@ -54,6 +54,22 @@ export async function cleanup(repo, reclaimOne, git = nodeGitRunner()) {
54
54
  }
55
55
  return { ok: true, removed, kept };
56
56
  }
57
+ /**
58
+ * Take back the rules that hide `skills`' links, for a caller that had skills of its own linked
59
+ * into the checkouts (`SkillLink`) and now removes what it left in the project. Under this
60
+ * tool's own rule for its links: a rule goes once no agent checkout is left anywhere in the
61
+ * repository, since every checkout reads the one exclude file.
62
+ */
63
+ export async function liftSkillRules(repo, skills, git = nodeGitRunner()) {
64
+ const checkouts = await repositoryCheckouts(repo, git).catch(() => undefined);
65
+ if (!checkouts)
66
+ return;
67
+ if ((await worktreeDirEntries(repo)).length > 0 || checkouts.some(path => basename(dirname(path)) === BRANCHES_DIR && isAgentBranch(basename(path))))
68
+ return;
69
+ for (const skill of skills)
70
+ for (const path of skillLinkPaths(skill))
71
+ await unexcludeFromGit(repo, `/${path}`, undefined, git).catch(() => { });
72
+ }
57
73
  async function anyHolds(checkouts, name) {
58
74
  for (const checkout of checkouts)
59
75
  if (await lstat(join(checkout, name)).then(() => true, () => false))
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,44 @@
1
1
  import { type GitRunner } from '@openagt/agent-data';
2
2
  /**
3
- * This package's command, linked into a checkout that has none: `node_modules/.bin/branches`.
3
+ * A package's command, linked into a checkout that has none: each command at
4
+ * `node_modules/.bin/<command>`, and the package itself at `node_modules/<package>`.
4
5
  *
5
- * The skill tells the agent to run `npx branches`. In a project that depends on this package the
6
- * checkout already has the command, linked with the project's other tools. In a project with
7
- * nothing installed (an empty folder a dashboard added) it has none, and `npx` then downloads
8
- * whatever package holds the name `branches` on npm and runs it: a stranger's code, in the
9
- * person's project. With the command linked here `npx` finds it in the checkout and downloads
10
- * nothing.
6
+ * A skill's text tells the agent to run its command by the package's full name,
7
+ * `npx @openagt/skill-branches@0.1`. `npx` looks for a copy of the package in the checkout, and asks
8
+ * npm for one otherwise; a copy it finds, it runs by the command's name from `node_modules/.bin`.
9
+ * In a project that depends on the package the checkout already has both, linked with the
10
+ * project's other tools. In a project with nothing installed (an empty folder a dashboard added)
11
+ * it has neither, so both are linked here: the agent then runs the very copy that made its
12
+ * checkout, with nothing downloaded and no network.
11
13
  *
12
- * Hidden from the project's git through the repository's exclude file, like the skill's link: the
13
- * link is the package's state, not the agent's work. Best-effort: a command already there (the
14
- * project's own copy) is left alone, and a link that cannot be made is a worse run, not a failed
15
- * one.
14
+ * The package is linked only beside its own commands. Beside another tool that holds a command's
15
+ * name in the project, the full name would run that tool, so there it is left to npm.
16
+ *
17
+ * Hidden from the project's git through the repository's exclude file, like a skill's link: a link
18
+ * is the package's state, not the agent's work. Best-effort: an entry already there (the project's
19
+ * own copy) is left alone, a link of this package's that points nowhere is made again, and a link
20
+ * that cannot be made is a worse run, not a failed one.
16
21
  */
17
- /** The command's name, and where a checkout holds its tools. */
18
- export declare const COMMAND = "branches";
22
+ /** A package to link into a checkout: its name, its directory (the one holding its `package.json`), and its commands, each a name and its script. */
23
+ export interface PackageLink {
24
+ name: string;
25
+ dir: string;
26
+ bins: Readonly<Record<string, string>>;
27
+ }
28
+ /** This package, as a {@link PackageLink}: its directory is beside `bin/`. */
29
+ export declare const OWN_PACKAGE: PackageLink;
30
+ /** The paths of a package's links, relative to a checkout: what the exclude file hides, and the rules a cleanup lifts. */
31
+ export declare function packageLinkPaths(pkg: PackageLink): string[];
32
+ /** The paths of this package's own links. */
33
+ export declare const COMMAND_LINKS: readonly string[];
34
+ export declare function linkPackage(repo: string, checkout: string, pkg: PackageLink, git?: GitRunner): Promise<void>;
35
+ /** This package's own command and package, linked into `checkout`. */
19
36
  export declare function linkOwnCommand(repo: string, checkout: string, git?: GitRunner): Promise<void>;
37
+ /**
38
+ * Whether something is at `path`. lstat, not stat: a link that is there counts, whatever it points
39
+ * at. One exception is taken away first: a link to an absolute path that is gone. That is a link
40
+ * this package made to an install that has since moved (the project's own links are relative), and
41
+ * left there it would keep the place of a working one.
42
+ */
43
+ export declare function entryExists(path: string): Promise<boolean>;
20
44
  //# sourceMappingURL=command-link.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-link.d.ts","sourceRoot":"","sources":["../src/command-link.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAGnF;;;;;;;;;;;;;;GAcG;AAEH,gEAAgE;AAChE,eAAO,MAAM,OAAO,aAAa,CAAA;AAGjC,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAWpH"}
1
+ {"version":3,"file":"command-link.d.ts","sourceRoot":"","sources":["../src/command-link.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAGnF;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qJAAqJ;AACrJ,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACvC;AAKD,8EAA8E;AAC9E,eAAO,MAAM,WAAW,EAAE,WAA+H,CAAA;AAEzJ,0HAA0H;AAC1H,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,EAAE,CAE3D;AAED,6CAA6C;AAC7C,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAAkC,CAAA;AAE7E,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAUnI;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9G;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhE"}
@@ -1,34 +1,56 @@
1
- import { lstat, mkdir, symlink } from 'node:fs/promises';
2
- import { join } from 'node:path';
1
+ import { lstat, mkdir, readlink, realpath, stat, symlink, unlink } from 'node:fs/promises';
2
+ import { dirname, isAbsolute, join } from 'node:path';
3
3
  import { excludeFromGit, nodeGitRunner } from '@openagt/agent-data';
4
4
  import { CLI_BIN_DIR } from './bin-dir.js';
5
+ /** Where a checkout holds its tools. */
6
+ const BIN_DIR = 'node_modules/.bin';
7
+ /** This package, as a {@link PackageLink}: its directory is beside `bin/`. */
8
+ export const OWN_PACKAGE = { name: '@openagt/skill-branches', dir: dirname(CLI_BIN_DIR), bins: { branches: join(CLI_BIN_DIR, 'branches') } };
9
+ /** The paths of a package's links, relative to a checkout: what the exclude file hides, and the rules a cleanup lifts. */
10
+ export function packageLinkPaths(pkg) {
11
+ return [...Object.keys(pkg.bins).map(command => `${BIN_DIR}/${command}`), `node_modules/${pkg.name}`];
12
+ }
13
+ /** The paths of this package's own links. */
14
+ export const COMMAND_LINKS = packageLinkPaths(OWN_PACKAGE);
15
+ export async function linkPackage(repo, checkout, pkg, git = nodeGitRunner()) {
16
+ let ours = true;
17
+ for (const [command, script] of Object.entries(pkg.bins)) {
18
+ const path = `${BIN_DIR}/${command}`;
19
+ if (!(await entryExists(join(checkout, path))))
20
+ await link(repo, checkout, path, script, 'file', git);
21
+ ours &&= await realpath(join(checkout, path)).then(async (found) => found === (await realpath(script)), () => false);
22
+ }
23
+ const path = `node_modules/${pkg.name}`;
24
+ // 'junction' is the only directory-link type Windows grants without elevation; it is ignored on POSIX.
25
+ if (ours && !(await entryExists(join(checkout, path))))
26
+ await link(repo, checkout, path, pkg.dir, process.platform === 'win32' ? 'junction' : 'dir', git);
27
+ }
28
+ /** This package's own command and package, linked into `checkout`. */
29
+ export function linkOwnCommand(repo, checkout, git = nodeGitRunner()) {
30
+ return linkPackage(repo, checkout, OWN_PACKAGE, git);
31
+ }
5
32
  /**
6
- * This package's command, linked into a checkout that has none: `node_modules/.bin/branches`.
7
- *
8
- * The skill tells the agent to run `npx branches`. In a project that depends on this package the
9
- * checkout already has the command, linked with the project's other tools. In a project with
10
- * nothing installed (an empty folder a dashboard added) it has none, and `npx` then downloads
11
- * whatever package holds the name `branches` on npm and runs it: a stranger's code, in the
12
- * person's project. With the command linked here `npx` finds it in the checkout and downloads
13
- * nothing.
14
- *
15
- * Hidden from the project's git through the repository's exclude file, like the skill's link: the
16
- * link is the package's state, not the agent's work. Best-effort: a command already there (the
17
- * project's own copy) is left alone, and a link that cannot be made is a worse run, not a failed
18
- * one.
33
+ * Whether something is at `path`. lstat, not stat: a link that is there counts, whatever it points
34
+ * at. One exception is taken away first: a link to an absolute path that is gone. That is a link
35
+ * this package made to an install that has since moved (the project's own links are relative), and
36
+ * left there it would keep the place of a working one.
19
37
  */
20
- /** The command's name, and where a checkout holds its tools. */
21
- export const COMMAND = 'branches';
22
- const BIN_DIR = 'node_modules/.bin';
23
- export async function linkOwnCommand(repo, checkout, git = nodeGitRunner()) {
24
- const link = join(checkout, BIN_DIR, COMMAND);
25
- // lstat, not stat: a link that is there counts, whatever it points at.
26
- if (await lstat(link).then(() => true, () => false))
27
- return;
28
- await excludeFromGit(repo, `/${BIN_DIR}/${COMMAND}`, undefined, git).catch(() => { });
38
+ export async function entryExists(path) {
39
+ const entry = await lstat(path).catch(() => undefined);
40
+ if (!entry)
41
+ return false;
42
+ if (!entry.isSymbolicLink())
43
+ return true;
44
+ const target = await readlink(path).catch(() => undefined);
45
+ if (target === undefined || !isAbsolute(target) || (await stat(target).then(() => true, () => false)))
46
+ return true;
47
+ return unlink(path).then(() => false, () => true);
48
+ }
49
+ async function link(repo, checkout, path, target, type, git) {
50
+ await excludeFromGit(repo, `/${path}`, undefined, git).catch(() => { });
29
51
  try {
30
- await mkdir(join(checkout, BIN_DIR), { recursive: true });
31
- await symlink(join(CLI_BIN_DIR, COMMAND), link);
52
+ await mkdir(dirname(join(checkout, path)), { recursive: true });
53
+ await symlink(target, join(checkout, path), type);
32
54
  }
33
55
  catch {
34
56
  // A filesystem that refuses the link: the agent still starts.
@@ -1 +1 @@
1
- {"version":3,"file":"command-link.js","sourceRoot":"","sources":["../src/command-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAkB,MAAM,qBAAqB,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C;;;;;;;;;;;;;;GAcG;AAEH,gEAAgE;AAChE,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAA;AACjC,MAAM,OAAO,GAAG,mBAAmB,CAAA;AAEnC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,QAAgB,EAAE,GAAG,GAAc,aAAa,EAAE;IACnG,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IAC7C,uEAAuE;IACvE,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC;QAAE,OAAM;IAC3D,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,OAAO,IAAI,OAAO,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACpF,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAA;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"command-link.js","sourceRoot":"","sources":["../src/command-link.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,12 +4,13 @@ export { linkDependencies, findDependencyDirs, nodeLinkFs, type LinkFs } from '.
4
4
  export { reconcileBranchLinks, type LinksFs, type BranchLinksDeps } from './branch-links.js';
5
5
  export { reclaimWorktree, discardWorktree, type ReclaimOptions, type ReclaimOutcome, type ReclaimRefusal } from './reclaim.js';
6
6
  export { projectRoot, nameBranch, isSessionName, type NameBranchOutcome, type NameBranchRefusal } from './worktree.js';
7
- export { createCheckout, attachCheckout, type CheckoutSkills } from './checkout.js';
7
+ export { createCheckout, attachCheckout, relinkCheckout, type CheckoutSkills } from './checkout.js';
8
+ export { liftSkillRules } from './cleanup.js';
8
9
  export { pushCheckout, pushBranchByName, type PushOutcome, type PushRefusal } from './push.js';
9
10
  export { mergeBranch, type MergeOutcome, type MergeRefusal } from './merge.js';
10
11
  export { readBranchStates, parseCommits, parseNumstat, parsePorcelain, type BranchState, type BranchCommit, type BranchFile } from './branch-state.js';
11
12
  export { runCli, USAGE, type CliIo, type CliRefusal } from './cli.js';
12
13
  export { CLI_BIN_DIR } from './bin-dir.js';
13
- export { linkOwnCommand } from './command-link.js';
14
- export { linkSkill, HARNESS_SKILL_DIRS, SKILL_DIR, SKILL_NAME, OWN_SKILL, type SkillLink } from './skill-links.js';
14
+ export { linkOwnCommand, linkPackage, packageLinkPaths, type PackageLink } from './command-link.js';
15
+ export { linkSkill, skillLinkPaths, HARNESS_SKILL_DIRS, SKILL_DIR, SKILL_NAME, OWN_SKILL, type SkillLink } from './skill-links.js';
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,SAAS,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAClG,OAAO,EAAE,oBAAoB,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC9H,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACtJ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,SAAS,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAClG,OAAO,EAAE,oBAAoB,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC9H,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACtJ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACnG,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -4,12 +4,13 @@ export { linkDependencies, findDependencyDirs, nodeLinkFs } from './worktree-dep
4
4
  export { reconcileBranchLinks } from './branch-links.js';
5
5
  export { reclaimWorktree, discardWorktree } from './reclaim.js';
6
6
  export { projectRoot, nameBranch, isSessionName } from './worktree.js';
7
- export { createCheckout, attachCheckout } from './checkout.js';
7
+ export { createCheckout, attachCheckout, relinkCheckout } from './checkout.js';
8
+ export { liftSkillRules } from './cleanup.js';
8
9
  export { pushCheckout, pushBranchByName } from './push.js';
9
10
  export { mergeBranch } from './merge.js';
10
11
  export { readBranchStates, parseCommits, parseNumstat, parsePorcelain } from './branch-state.js';
11
12
  export { runCli, USAGE } from './cli.js';
12
13
  export { CLI_BIN_DIR } from './bin-dir.js';
13
- export { linkOwnCommand } from './command-link.js';
14
- export { linkSkill, HARNESS_SKILL_DIRS, SKILL_DIR, SKILL_NAME, OWN_SKILL } from './skill-links.js';
14
+ export { linkOwnCommand, linkPackage, packageLinkPaths } from './command-link.js';
15
+ export { linkSkill, skillLinkPaths, HARNESS_SKILL_DIRS, SKILL_DIR, SKILL_NAME, OWN_SKILL } from './skill-links.js';
15
16
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,GAOjB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAA;AAClG,OAAO,EAAE,oBAAoB,EAAsC,MAAM,mBAAmB,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAiE,MAAM,cAAc,CAAA;AAC9H,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAkD,MAAM,eAAe,CAAA;AACtH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAuB,MAAM,eAAe,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAsC,MAAM,WAAW,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAwC,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAwD,MAAM,mBAAmB,CAAA;AACtJ,OAAO,EAAE,MAAM,EAAE,KAAK,EAA+B,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAkB,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,GAOjB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAA;AAClG,OAAO,EAAE,oBAAoB,EAAsC,MAAM,mBAAmB,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAiE,MAAM,cAAc,CAAA;AAC9H,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAkD,MAAM,eAAe,CAAA;AACtH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAuB,MAAM,eAAe,CAAA;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAsC,MAAM,WAAW,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAwC,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAwD,MAAM,mBAAmB,CAAA;AACtJ,OAAO,EAAE,MAAM,EAAE,KAAK,EAA+B,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAoB,MAAM,mBAAmB,CAAA;AACnG,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAkB,MAAM,kBAAkB,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { type GitRunner } from '@openagt/agent-data';
2
2
  import { type LinkFs } from './worktree-deps.js';
3
+ import { type PackageLink } from './command-link.js';
3
4
  /**
4
5
  * The skill, where the agent's harness looks for one (#1739). A harness discovers skills under a
5
6
  * directory of its own at the checkout root — `.claude/skills/<name>/SKILL.md` for Claude Code,
@@ -29,6 +30,8 @@ export declare const SKILL_DIR: string;
29
30
  export interface SkillLink {
30
31
  name: string;
31
32
  dir: string;
33
+ /** The package the skill's text calls by its full name, when the skill has a command: linked with its commands (`command-link.ts`). */
34
+ package?: PackageLink;
32
35
  }
33
36
  /** This package's own skill, as a {@link SkillLink}. */
34
37
  export declare const OWN_SKILL: SkillLink;
@@ -37,7 +40,10 @@ export declare const OWN_SKILL: SkillLink;
37
40
  * the caller names (see {@link SkillLink}) — and hide the links from the project's git
38
41
  * through the repository's exclude file: a symlink at the checkout root would otherwise ride any
39
42
  * sweeping `git add -A` onto the agent's branch. Best-effort: an entry already at a link's path is
40
- * left alone, and a link that cannot be made is a worse run, not a failed one.
43
+ * left alone and gets no rule, a link of this package's that points nowhere is made again, and a
44
+ * link that cannot be made is a worse run, not a failed one.
41
45
  */
42
46
  export declare function linkSkill(repo: string, checkout: string, fs?: LinkFs, git?: GitRunner, skills?: readonly SkillLink[]): Promise<void>;
47
+ /** The paths of a skill's links, relative to a checkout: its text for every harness, and its package's links when it has one. */
48
+ export declare function skillLinkPaths(skill: SkillLink): string[];
43
49
  //# sourceMappingURL=skill-links.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-links.d.ts","sourceRoot":"","sources":["../src/skill-links.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,SAAS,EAAkB,MAAM,qBAAqB,CAAA;AACnF,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAE5D;;;;;;;;GAQG;AAEH,6GAA6G;AAC7G,eAAO,MAAM,UAAU,aAAa,CAAA;AAEpC,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,YAAI,gBAAgB,EAAE,gBAAgB,CAAU,CAAA;AAE/E;;;GAGG;AACH,eAAO,MAAM,SAAS,QAAsD,CAAA;AAE5E;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wDAAwD;AACxD,eAAO,MAAM,SAAS,EAAE,SAAgD,CAAA;AAExE;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,EAAE,GAAE,MAAqB,EACzB,GAAG,GAAE,SAA2B,EAChC,MAAM,GAAE,SAAS,SAAS,EAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"skill-links.d.ts","sourceRoot":"","sources":["../src/skill-links.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,SAAS,EAAkB,MAAM,qBAAqB,CAAA;AACnF,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAA8C,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEhG;;;;;;;;GAQG;AAEH,6GAA6G;AAC7G,eAAO,MAAM,UAAU,aAAa,CAAA;AAEpC,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,YAAI,gBAAgB,EAAE,gBAAgB,CAAU,CAAA;AAE/E;;;GAGG;AACH,eAAO,MAAM,SAAS,QAAsD,CAAA;AAE5E;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,uIAAuI;IACvI,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB;AAED,wDAAwD;AACxD,eAAO,MAAM,SAAS,EAAE,SAAgD,CAAA;AAExE;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,EAAE,GAAE,MAAqB,EACzB,GAAG,GAAE,SAA2B,EAChC,MAAM,GAAE,SAAS,SAAS,EAAO,GAChC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,iIAAiI;AACjI,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAEzD"}
@@ -2,6 +2,7 @@ import { dirname, join } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { nodeGitRunner, excludeFromGit } from '@openagt/agent-data';
4
4
  import { nodeLinkFs } from './worktree-deps.js';
5
+ import { entryExists, linkPackage, packageLinkPaths } from './command-link.js';
5
6
  /**
6
7
  * The skill, where the agent's harness looks for one (#1739). A harness discovers skills under a
7
8
  * directory of its own at the checkout root — `.claude/skills/<name>/SKILL.md` for Claude Code,
@@ -27,17 +28,19 @@ export const OWN_SKILL = { name: SKILL_NAME, dir: SKILL_DIR };
27
28
  * the caller names (see {@link SkillLink}) — and hide the links from the project's git
28
29
  * through the repository's exclude file: a symlink at the checkout root would otherwise ride any
29
30
  * sweeping `git add -A` onto the agent's branch. Best-effort: an entry already at a link's path is
30
- * left alone, and a link that cannot be made is a worse run, not a failed one.
31
+ * left alone and gets no rule, a link of this package's that points nowhere is made again, and a
32
+ * link that cannot be made is a worse run, not a failed one.
31
33
  */
32
34
  export async function linkSkill(repo, checkout, fs = nodeLinkFs(), git = nodeGitRunner(), skills = []) {
33
35
  for (const skill of [OWN_SKILL, ...skills]) {
34
36
  for (const dir of HARNESS_SKILL_DIRS) {
35
37
  const rel = `${dir}/${skill.name}`;
36
- await excludeFromGit(repo, `/${rel}`, undefined, git).catch(() => { });
37
38
  try {
38
39
  const path = join(checkout, rel);
39
- if (await fs.entryExists(path))
40
+ // The project's own copy, tracked or not, stays, and gets no rule: a rule would hide what a person adds there.
41
+ if (await entryExists(path))
40
42
  continue;
43
+ await excludeFromGit(repo, `/${rel}`, undefined, git).catch(() => { });
41
44
  await fs.mkdir(join(checkout, dir));
42
45
  await fs.symlinkDir(skill.dir, path);
43
46
  }
@@ -45,6 +48,12 @@ export async function linkSkill(repo, checkout, fs = nodeLinkFs(), git = nodeGit
45
48
  // A filesystem that refuses the link: the agent still starts, without the skill.
46
49
  }
47
50
  }
51
+ if (skill.package)
52
+ await linkPackage(repo, checkout, skill.package, git);
48
53
  }
49
54
  }
55
+ /** The paths of a skill's links, relative to a checkout: its text for every harness, and its package's links when it has one. */
56
+ export function skillLinkPaths(skill) {
57
+ return [...HARNESS_SKILL_DIRS.map(dir => `${dir}/${skill.name}`), ...(skill.package ? packageLinkPaths(skill.package) : [])];
58
+ }
50
59
  //# sourceMappingURL=skill-links.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-links.js","sourceRoot":"","sources":["../src/skill-links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,aAAa,EAAkB,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACnF,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAA;AAE5D;;;;;;;;GAQG;AAEH,6GAA6G;AAC7G,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAA;AAEpC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAU,CAAA;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AAe5E,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAc,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;AAExE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,QAAgB,EAChB,EAAE,GAAW,UAAU,EAAE,EACzB,GAAG,GAAc,aAAa,EAAE,EAChC,MAAM,GAAyB,EAAE;IAEjC,KAAK,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAA;YAClC,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACrE,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;gBAChC,IAAI,MAAM,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;oBAAE,SAAQ;gBACxC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAA;gBACnC,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;YACnF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"skill-links.js","sourceRoot":"","sources":["../src/skill-links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,aAAa,EAAkB,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACnF,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAoB,MAAM,mBAAmB,CAAA;AAEhG;;;;;;;;GAQG;AAEH,6GAA6G;AAC7G,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAA;AAEpC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAU,CAAA;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AAiB5E,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAc,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;AAExE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,QAAgB,EAChB,EAAE,GAAW,UAAU,EAAE,EACzB,GAAG,GAAc,aAAa,EAAE,EAChC,MAAM,GAAyB,EAAE;IAEjC,KAAK,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAA;YAClC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;gBAChC,+GAA+G;gBAC/G,IAAI,MAAM,WAAW,CAAC,IAAI,CAAC;oBAAE,SAAQ;gBACrC,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBACrE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAA;gBACnC,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,iFAAiF;YACnF,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,OAAO;YAAE,MAAM,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IAC1E,CAAC;AACH,CAAC;AAED,iIAAiI;AACjI,MAAM,UAAU,cAAc,CAAC,KAAgB;IAC7C,OAAO,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAC9H,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagt/skill-branches",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "Branch management for coding agents: one git checkout per agent under .branches/, named as its branch, reclaimed once its work is on the remote.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,7 +39,7 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "@openagt/agent-data": "0.0.2"
42
+ "@openagt/agent-data": "0.0.3"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^20.0.0",