ghostrail 0.0.0 → 0.2.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.
Files changed (163) hide show
  1. package/README.md +49 -3
  2. package/dist/agent/claude-code.d.ts +10 -0
  3. package/dist/agent/claude-code.d.ts.map +1 -1
  4. package/dist/agent/claude-code.js +20 -0
  5. package/dist/agent/claude-code.js.map +1 -1
  6. package/dist/agent/result.d.ts.map +1 -1
  7. package/dist/agent/result.js +13 -2
  8. package/dist/agent/result.js.map +1 -1
  9. package/dist/backend/container.d.ts +18 -0
  10. package/dist/backend/container.d.ts.map +1 -1
  11. package/dist/backend/container.js +33 -10
  12. package/dist/backend/container.js.map +1 -1
  13. package/dist/backend/git-credentials.d.ts +18 -0
  14. package/dist/backend/git-credentials.d.ts.map +1 -0
  15. package/dist/backend/git-credentials.js +30 -0
  16. package/dist/backend/git-credentials.js.map +1 -0
  17. package/dist/backend/local-worktree.d.ts.map +1 -1
  18. package/dist/backend/local-worktree.js +21 -0
  19. package/dist/backend/local-worktree.js.map +1 -1
  20. package/dist/backend/types.d.ts +12 -1
  21. package/dist/backend/types.d.ts.map +1 -1
  22. package/dist/claude-profile/classify.d.ts +41 -0
  23. package/dist/claude-profile/classify.d.ts.map +1 -0
  24. package/dist/claude-profile/classify.js +103 -0
  25. package/dist/claude-profile/classify.js.map +1 -0
  26. package/dist/claude-profile/index.d.ts +3 -0
  27. package/dist/claude-profile/index.d.ts.map +1 -0
  28. package/dist/claude-profile/index.js +3 -0
  29. package/dist/claude-profile/index.js.map +1 -0
  30. package/dist/claude-profile/setup.d.ts +33 -0
  31. package/dist/claude-profile/setup.d.ts.map +1 -0
  32. package/dist/claude-profile/setup.js +81 -0
  33. package/dist/claude-profile/setup.js.map +1 -0
  34. package/dist/cli/commands.d.ts +67 -2
  35. package/dist/cli/commands.d.ts.map +1 -1
  36. package/dist/cli/commands.js +420 -17
  37. package/dist/cli/commands.js.map +1 -1
  38. package/dist/cli.d.ts.map +1 -1
  39. package/dist/cli.js +13 -1
  40. package/dist/cli.js.map +1 -1
  41. package/dist/commands/help.d.ts.map +1 -1
  42. package/dist/commands/help.js +20 -2
  43. package/dist/commands/help.js.map +1 -1
  44. package/dist/config/load.d.ts.map +1 -1
  45. package/dist/config/load.js +61 -9
  46. package/dist/config/load.js.map +1 -1
  47. package/dist/config/schema.d.ts +51 -3
  48. package/dist/config/schema.d.ts.map +1 -1
  49. package/dist/config/schema.js +4 -0
  50. package/dist/config/schema.js.map +1 -1
  51. package/dist/factory/build.d.ts +24 -0
  52. package/dist/factory/build.d.ts.map +1 -1
  53. package/dist/factory/build.js +80 -11
  54. package/dist/factory/build.js.map +1 -1
  55. package/dist/loop/concurrency.d.ts +13 -0
  56. package/dist/loop/concurrency.d.ts.map +1 -0
  57. package/dist/loop/concurrency.js +27 -0
  58. package/dist/loop/concurrency.js.map +1 -0
  59. package/dist/loop/engine.d.ts.map +1 -1
  60. package/dist/loop/engine.js +19 -14
  61. package/dist/loop/engine.js.map +1 -1
  62. package/dist/loop/index.d.ts +2 -0
  63. package/dist/loop/index.d.ts.map +1 -1
  64. package/dist/loop/index.js +2 -0
  65. package/dist/loop/index.js.map +1 -1
  66. package/dist/loop/ports.d.ts +37 -1
  67. package/dist/loop/ports.d.ts.map +1 -1
  68. package/dist/loop/watch.d.ts +25 -0
  69. package/dist/loop/watch.d.ts.map +1 -0
  70. package/dist/loop/watch.js +45 -0
  71. package/dist/loop/watch.js.map +1 -0
  72. package/dist/publish/gh.d.ts +20 -1
  73. package/dist/publish/gh.d.ts.map +1 -1
  74. package/dist/publish/gh.js +37 -3
  75. package/dist/publish/gh.js.map +1 -1
  76. package/dist/publish/githost.d.ts +12 -0
  77. package/dist/publish/githost.d.ts.map +1 -1
  78. package/dist/publish/githost.js +14 -0
  79. package/dist/publish/githost.js.map +1 -1
  80. package/dist/publish/github-publisher.d.ts +1 -1
  81. package/dist/publish/github-publisher.d.ts.map +1 -1
  82. package/dist/publish/github-publisher.js +6 -5
  83. package/dist/publish/github-publisher.js.map +1 -1
  84. package/dist/respond/respond.d.ts +10 -1
  85. package/dist/respond/respond.d.ts.map +1 -1
  86. package/dist/respond/respond.js +37 -3
  87. package/dist/respond/respond.js.map +1 -1
  88. package/dist/secrets/env-file.d.ts +23 -0
  89. package/dist/secrets/env-file.d.ts.map +1 -0
  90. package/dist/secrets/env-file.js +70 -0
  91. package/dist/secrets/env-file.js.map +1 -0
  92. package/dist/secrets/index.d.ts +4 -0
  93. package/dist/secrets/index.d.ts.map +1 -0
  94. package/dist/secrets/index.js +4 -0
  95. package/dist/secrets/index.js.map +1 -0
  96. package/dist/secrets/load.d.ts +24 -0
  97. package/dist/secrets/load.d.ts.map +1 -0
  98. package/dist/secrets/load.js +43 -0
  99. package/dist/secrets/load.js.map +1 -0
  100. package/dist/skill/install.d.ts +56 -0
  101. package/dist/skill/install.d.ts.map +1 -0
  102. package/dist/skill/install.js +93 -0
  103. package/dist/skill/install.js.map +1 -0
  104. package/dist/source/linear.d.ts +51 -8
  105. package/dist/source/linear.d.ts.map +1 -1
  106. package/dist/source/linear.js +213 -23
  107. package/dist/source/linear.js.map +1 -1
  108. package/dist/triage/apply.d.ts +28 -0
  109. package/dist/triage/apply.d.ts.map +1 -0
  110. package/dist/triage/apply.js +68 -0
  111. package/dist/triage/apply.js.map +1 -0
  112. package/dist/triage/engine.d.ts +31 -0
  113. package/dist/triage/engine.d.ts.map +1 -0
  114. package/dist/triage/engine.js +122 -0
  115. package/dist/triage/engine.js.map +1 -0
  116. package/dist/triage/index.d.ts +4 -0
  117. package/dist/triage/index.d.ts.map +1 -0
  118. package/dist/triage/index.js +4 -0
  119. package/dist/triage/index.js.map +1 -0
  120. package/dist/triage/plan.d.ts +37 -0
  121. package/dist/triage/plan.d.ts.map +1 -0
  122. package/dist/triage/plan.js +75 -0
  123. package/dist/triage/plan.js.map +1 -0
  124. package/dist/vendor/skilltend/apply.d.ts +25 -0
  125. package/dist/vendor/skilltend/apply.d.ts.map +1 -0
  126. package/dist/vendor/skilltend/apply.js +85 -0
  127. package/dist/vendor/skilltend/apply.js.map +1 -0
  128. package/dist/vendor/skilltend/detect.d.ts +35 -0
  129. package/dist/vendor/skilltend/detect.d.ts.map +1 -0
  130. package/dist/vendor/skilltend/detect.js +187 -0
  131. package/dist/vendor/skilltend/detect.js.map +1 -0
  132. package/dist/vendor/skilltend/frontmatter.d.ts +5 -0
  133. package/dist/vendor/skilltend/frontmatter.d.ts.map +1 -0
  134. package/dist/vendor/skilltend/frontmatter.js +59 -0
  135. package/dist/vendor/skilltend/frontmatter.js.map +1 -0
  136. package/dist/vendor/skilltend/fsFacade.d.ts +24 -0
  137. package/dist/vendor/skilltend/fsFacade.d.ts.map +1 -0
  138. package/dist/vendor/skilltend/fsFacade.js +68 -0
  139. package/dist/vendor/skilltend/fsFacade.js.map +1 -0
  140. package/dist/vendor/skilltend/paths.d.ts +28 -0
  141. package/dist/vendor/skilltend/paths.d.ts.map +1 -0
  142. package/dist/vendor/skilltend/paths.js +24 -0
  143. package/dist/vendor/skilltend/paths.js.map +1 -0
  144. package/dist/vendor/skilltend/plan.d.ts +46 -0
  145. package/dist/vendor/skilltend/plan.d.ts.map +1 -0
  146. package/dist/vendor/skilltend/plan.js +79 -0
  147. package/dist/vendor/skilltend/plan.js.map +1 -0
  148. package/dist/vendor/skilltend/registry.d.ts +56 -0
  149. package/dist/vendor/skilltend/registry.d.ts.map +1 -0
  150. package/dist/vendor/skilltend/registry.js +129 -0
  151. package/dist/vendor/skilltend/registry.js.map +1 -0
  152. package/docker/factory.Dockerfile +39 -0
  153. package/package.json +4 -3
  154. package/skill/ghostrail/SKILL.md +145 -0
  155. package/templates/{fix-bugs-local → code-local}/README.md +3 -3
  156. package/templates/code-local/ghostrail.toml +44 -0
  157. package/templates/code-local/prompts/resolve-issue.md +31 -0
  158. package/templates/code-local/prompts/respond.md +27 -0
  159. package/templates/code-local/prompts/triage.md +51 -0
  160. package/templates/content-loop/ghostrail.toml +5 -2
  161. package/templates/content-loop/prompts/respond.md +25 -0
  162. package/templates/fix-bugs-local/ghostrail.toml +0 -37
  163. package/templates/fix-bugs-local/prompts/fix-bug.md +0 -27
@@ -0,0 +1,68 @@
1
+ // Vendored from timothyjordan/a14y @ 07ef2bbb8593
2
+ // (packages/apps/cli/src/skills/fsFacade.ts), Apache-2.0.
3
+ //
4
+ // This directory is the future `skilltend` package: a white-label engine for
5
+ // installing and maintaining ONE agent skill across coding agents. It contains
6
+ // no skills of its own and no product name — the caller supplies the skill's
7
+ // identity. Keep changes here minimal and mechanical so the eventual extraction
8
+ // to a standalone package stays a directory move (see TJ-1464).
9
+ import { promises as fs } from "node:fs";
10
+ function isEnoent(e) {
11
+ return e?.code === "ENOENT";
12
+ }
13
+ export const nodeFs = {
14
+ async readFile(p) {
15
+ try {
16
+ return await fs.readFile(p, "utf8");
17
+ }
18
+ catch (e) {
19
+ if (isEnoent(e))
20
+ return null;
21
+ throw e;
22
+ }
23
+ },
24
+ async writeFile(p, content) {
25
+ await fs.writeFile(p, content, "utf8");
26
+ },
27
+ async mkdirp(p) {
28
+ await fs.mkdir(p, { recursive: true });
29
+ },
30
+ async lstat(p) {
31
+ try {
32
+ const s = await fs.lstat(p);
33
+ return { isSymbolicLink: s.isSymbolicLink(), isDirectory: s.isDirectory() };
34
+ }
35
+ catch (e) {
36
+ if (isEnoent(e))
37
+ return null;
38
+ throw e;
39
+ }
40
+ },
41
+ async readlink(p) {
42
+ try {
43
+ return await fs.readlink(p);
44
+ }
45
+ catch (e) {
46
+ const code = e.code;
47
+ if (code === "ENOENT" || code === "EINVAL")
48
+ return null;
49
+ throw e;
50
+ }
51
+ },
52
+ async symlink(target, linkPath) {
53
+ await fs.symlink(target, linkPath, "dir");
54
+ },
55
+ async rm(p) {
56
+ await fs.rm(p, { recursive: true, force: true });
57
+ },
58
+ async dirExists(p) {
59
+ try {
60
+ const s = await fs.stat(p);
61
+ return s.isDirectory();
62
+ }
63
+ catch {
64
+ return false;
65
+ }
66
+ },
67
+ };
68
+ //# sourceMappingURL=fsFacade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsFacade.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/fsFacade.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,0DAA0D;AAC1D,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,gEAAgE;AAChE,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAsBzC,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAQ,CAAuC,EAAE,IAAI,KAAK,QAAQ,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAa;IAC9B,KAAK,CAAC,QAAQ,CAAC,CAAC;QACd,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC7B,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO;QACxB,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,CAAC;QACZ,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,KAAK,CAAC,CAAC;QACX,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC9E,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC7B,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,CAAC;QACd,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,GAAI,CAA2B,CAAC,IAAI,CAAC;YAC/C,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACxD,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ;QAC5B,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD,KAAK,CAAC,EAAE,CAAC,CAAC;QACR,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { SkillIdentity } from "./registry.js";
2
+ export type Scope = "global" | "local";
3
+ export declare class SkillsConfigError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ export type TargetKind = "copy" | "canonical" | "link";
7
+ export interface SkillTarget {
8
+ /**
9
+ * - `copy`: a real SKILL.md written into the agent's own skills dir.
10
+ * - `canonical`: the single shared SKILL.md (`.agents/skills/<name>/SKILL.md`)
11
+ * used by the symlink install mode.
12
+ * - `link`: a symlink at an agent's skill dir pointing at the canonical dir.
13
+ */
14
+ kind: TargetKind;
15
+ /** Agent keys served by this target (>1 when they share a path). */
16
+ agents: string[];
17
+ /** Combined human label, e.g. "Cline + Zed". */
18
+ label: string;
19
+ /** copy/canonical: the SKILL.md file path. link: the symlink path. */
20
+ managedPath: string;
21
+ /** link only: absolute canonical skill directory the symlink points at. */
22
+ linkTo?: string;
23
+ }
24
+ /** `<skillsDir>/<name>/SKILL.md`. */
25
+ export declare function skillFile(skillsDir: string, skill: SkillIdentity): string;
26
+ /** `<skillsDir>/<name>`. */
27
+ export declare function skillDir(skillsDir: string, skill: SkillIdentity): string;
28
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/paths.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvC,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,IAAI,EAAE,UAAU,CAAC;IACjB,oEAAoE;IACpE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAEzE;AAED,4BAA4B;AAC5B,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAExE"}
@@ -0,0 +1,24 @@
1
+ // Vendored from timothyjordan/a14y @ 07ef2bbb8593
2
+ // (packages/apps/cli/src/skills/paths.ts), Apache-2.0.
3
+ //
4
+ // This directory is the future `skilltend` package: a white-label engine for
5
+ // installing and maintaining ONE agent skill across coding agents. It contains
6
+ // no skills of its own and no product name — the caller supplies the skill's
7
+ // identity. Keep changes here minimal and mechanical so the eventual extraction
8
+ // to a standalone package stays a directory move (see TJ-1464).
9
+ import path from "node:path";
10
+ export class SkillsConfigError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "SkillsConfigError";
14
+ }
15
+ }
16
+ /** `<skillsDir>/<name>/SKILL.md`. */
17
+ export function skillFile(skillsDir, skill) {
18
+ return path.join(skillsDir, skill.name, skill.filename);
19
+ }
20
+ /** `<skillsDir>/<name>`. */
21
+ export function skillDir(skillsDir, skill) {
22
+ return path.join(skillsDir, skill.name);
23
+ }
24
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/paths.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,uDAAuD;AACvD,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,gEAAgE;AAChE,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAsBD,qCAAqC;AACrC,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,KAAoB;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,QAAQ,CAAC,SAAiB,EAAE,KAAoB;IAC9D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { SkillTarget } from "./paths.js";
2
+ import type { SkillIdentity } from "./registry.js";
3
+ export type SkillAction = "create" | "update" | "unchanged" | "conflict";
4
+ export interface TargetPlan {
5
+ target: SkillTarget;
6
+ action: SkillAction;
7
+ oldVersion: string | null;
8
+ newVersion: string | null;
9
+ isSymlink: boolean;
10
+ /** Why a `conflict` was raised — surfaced to the user. */
11
+ conflictReason?: string;
12
+ }
13
+ export interface FilePlanInput {
14
+ /** Whose skill this is — decides which on-disk files we consider ours. */
15
+ skill: SkillIdentity;
16
+ target: SkillTarget;
17
+ /** Freshly downloaded SKILL.md body. */
18
+ fetched: string;
19
+ /** Current on-disk content, or null when the file is absent. */
20
+ current: string | null;
21
+ /** True when the file or its skill directory is a symlink. */
22
+ isSymlink: boolean;
23
+ /** `--force`: overwrite user-modified files and write through symlinks. */
24
+ force: boolean;
25
+ }
26
+ /**
27
+ * Plan a `copy`/`canonical` target (a real SKILL.md file). Idempotent:
28
+ * byte-identical content is a no-op. We own files whose frontmatter `name` matches
29
+ * the supplied identity; a differing foreign file (or a symlink we'd write through) is a
30
+ * conflict the user resolves with `--force`.
31
+ */
32
+ export declare function planFile(input: FilePlanInput): TargetPlan;
33
+ export interface LinkPlanInput {
34
+ target: SkillTarget;
35
+ /** Version of the freshly downloaded skill (for reporting). */
36
+ fetchedVersion: string | null;
37
+ /** Current state of the symlink path. */
38
+ existing: {
39
+ kind: "absent" | "symlink" | "other";
40
+ linkTarget?: string | null;
41
+ };
42
+ force: boolean;
43
+ }
44
+ /** Plan a `link` target (a symlink at an agent's skill dir to the canonical dir). */
45
+ export declare function planLink(input: LinkPlanInput): TargetPlan;
46
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/plan.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;AAEzE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,8DAA8D;IAC9D,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAyBzD;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yCAAyC;IACzC,QAAQ,EAAE;QAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC/E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAiCzD"}
@@ -0,0 +1,79 @@
1
+ // Vendored from timothyjordan/a14y @ 07ef2bbb8593
2
+ // (packages/apps/cli/src/skills/plan.ts), Apache-2.0.
3
+ //
4
+ // This directory is the future `skilltend` package: a white-label engine for
5
+ // installing and maintaining ONE agent skill across coding agents. It contains
6
+ // no skills of its own and no product name — the caller supplies the skill's
7
+ // identity. Keep changes here minimal and mechanical so the eventual extraction
8
+ // to a standalone package stays a directory move (see TJ-1464).
9
+ import path from "node:path";
10
+ import { parseSkillName, parseSkillVersion } from "./frontmatter.js";
11
+ /**
12
+ * Plan a `copy`/`canonical` target (a real SKILL.md file). Idempotent:
13
+ * byte-identical content is a no-op. We own files whose frontmatter `name` matches
14
+ * the supplied identity; a differing foreign file (or a symlink we'd write through) is a
15
+ * conflict the user resolves with `--force`.
16
+ */
17
+ export function planFile(input) {
18
+ const { skill, target, fetched, current, isSymlink, force } = input;
19
+ const newVersion = parseSkillVersion(fetched);
20
+ const oldVersion = current !== null ? parseSkillVersion(current) : null;
21
+ let action;
22
+ let conflictReason;
23
+ if (current === null) {
24
+ action = "create";
25
+ }
26
+ else if (current === fetched) {
27
+ action = "unchanged";
28
+ }
29
+ else if (isSymlink && !force) {
30
+ action = "conflict";
31
+ conflictReason = "symlink — managed elsewhere; pass --force to write through it";
32
+ }
33
+ else if (parseSkillName(current) === skill.name && !isSymlink) {
34
+ action = "update";
35
+ }
36
+ else if (force) {
37
+ action = "update";
38
+ }
39
+ else {
40
+ action = "conflict";
41
+ conflictReason = "existing file looks user-modified; pass --force to overwrite";
42
+ }
43
+ return { target, action, oldVersion, newVersion, isSymlink, conflictReason };
44
+ }
45
+ /** Plan a `link` target (a symlink at an agent's skill dir to the canonical dir). */
46
+ export function planLink(input) {
47
+ const { target, existing, force } = input;
48
+ const base = {
49
+ target,
50
+ oldVersion: null,
51
+ newVersion: input.fetchedVersion,
52
+ isSymlink: existing.kind === "symlink",
53
+ };
54
+ if (existing.kind === "absent") {
55
+ return { ...base, action: "create" };
56
+ }
57
+ if (existing.kind === "symlink") {
58
+ const points = existing.linkTarget ?? "";
59
+ if (target.linkTo && path.resolve(points) === path.resolve(target.linkTo)) {
60
+ return { ...base, action: "unchanged" };
61
+ }
62
+ return force
63
+ ? { ...base, action: "update" }
64
+ : {
65
+ ...base,
66
+ action: "conflict",
67
+ conflictReason: "symlink points elsewhere; pass --force to relink",
68
+ };
69
+ }
70
+ // A real directory or file already lives here.
71
+ return force
72
+ ? { ...base, action: "update" }
73
+ : {
74
+ ...base,
75
+ action: "conflict",
76
+ conflictReason: "a real directory exists here; pass --force to replace it with a symlink",
77
+ };
78
+ }
79
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Who the skill is. Supplied by the consuming product rather than baked in, so
3
+ * this engine stays white-label: it installs whatever skill it is handed, under
4
+ * whatever name, and never mentions a product of its own.
5
+ */
6
+ export interface SkillIdentity {
7
+ /** Directory name under each agent's `skills/`, and the skill's frontmatter `name`. */
8
+ name: string;
9
+ /** Skill filename. Effectively always `SKILL.md` per the agent-skills convention. */
10
+ filename: string;
11
+ }
12
+ /** The agent-skills convention: `<skillsDir>/<name>/SKILL.md`. */
13
+ export declare const DEFAULT_SKILL_FILENAME = "SKILL.md";
14
+ /** Build an identity for `name`, defaulting the filename to the convention. */
15
+ export declare function skillIdentity(name: string, filename?: string): SkillIdentity;
16
+ export interface PathCtx {
17
+ /** Home directory (injected `os.homedir()`). */
18
+ home: string;
19
+ /** Current working directory (injected `process.cwd()`). */
20
+ cwd: string;
21
+ /** Environment (injected `process.env`) for XDG / agent-specific overrides. */
22
+ env: Record<string, string | undefined>;
23
+ }
24
+ export interface AgentEntry {
25
+ /** Stable key used by `--agent`. */
26
+ name: string;
27
+ /** Human label for output, e.g. "Claude Code". */
28
+ label: string;
29
+ /** Dirs whose existence marks the agent as configured (any match detects it). */
30
+ detectDirs(ctx: PathCtx): string[];
31
+ /** Absolute skills directory for a global (home) install. */
32
+ globalSkillsDir(ctx: PathCtx): string;
33
+ /**
34
+ * Relative skills dir for a project-local install, and the label shown in the
35
+ * harness picker.
36
+ *
37
+ * Note the asymmetry with `globalSkillsDir`: in a *project*, many agents read
38
+ * the shared cross-agent `.agents/skills` convention, while in the *home*
39
+ * directory each keeps its own. Verified against vercel-labs/skills, whose
40
+ * agent list is maintained by PRs from the agent authors themselves.
41
+ */
42
+ localDir: string;
43
+ }
44
+ export declare const AGENT_REGISTRY: AgentEntry[];
45
+ /** Absolute project-local skills dir for an agent. */
46
+ export declare function localSkillsDir(a: AgentEntry, ctx: PathCtx): string;
47
+ /** Fallback agent when nothing is auto-detected in a fresh environment. */
48
+ export declare const DEFAULT_AGENT = "claude";
49
+ export declare function agentByName(name: string): AgentEntry | undefined;
50
+ /**
51
+ * The shared cross-agent skills directory (the `.agents/skills` standard). Used
52
+ * as the canonical home for the symlink install mode: the skill lives here once
53
+ * and each agent links to it.
54
+ */
55
+ export declare function sharedSkillsDir(ctx: PathCtx, scope: "global" | "local"): string;
56
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/registry.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,kEAAkE;AAClE,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAyB,GAAG,aAAa,CAE5F;AAED,MAAM,WAAW,OAAO;IACtB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IACnC,6DAA6D;IAC7D,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC;IACtC;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAkBD,eAAO,MAAM,cAAc,EAAE,UAAU,EA8EtC,CAAC;AAEF,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAElE;AAED,2EAA2E;AAC3E,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAI/E"}
@@ -0,0 +1,129 @@
1
+ // Vendored from timothyjordan/a14y @ 07ef2bbb8593
2
+ // (packages/apps/cli/src/skills/registry.ts), Apache-2.0.
3
+ //
4
+ // This directory is the future `skilltend` package: a white-label engine for
5
+ // installing and maintaining ONE agent skill across coding agents. It contains
6
+ // no skills of its own and no product name — the caller supplies the skill's
7
+ // identity. Keep changes here minimal and mechanical so the eventual extraction
8
+ // to a standalone package stays a directory move (see TJ-1464).
9
+ import path from "node:path";
10
+ /** The agent-skills convention: `<skillsDir>/<name>/SKILL.md`. */
11
+ export const DEFAULT_SKILL_FILENAME = "SKILL.md";
12
+ /** Build an identity for `name`, defaulting the filename to the convention. */
13
+ export function skillIdentity(name, filename = DEFAULT_SKILL_FILENAME) {
14
+ return { name, filename };
15
+ }
16
+ function inHome(ctx, ...segs) {
17
+ return path.join(ctx.home, ...segs);
18
+ }
19
+ function xdgConfigHome(ctx) {
20
+ const x = ctx.env.XDG_CONFIG_HOME?.trim();
21
+ return x ? x : path.join(ctx.home, ".config");
22
+ }
23
+ function claudeConfigDir(ctx) {
24
+ const c = ctx.env.CLAUDE_CONFIG_DIR?.trim();
25
+ return c ? c : inHome(ctx, ".claude");
26
+ }
27
+ function codexHome(ctx) {
28
+ const c = ctx.env.CODEX_HOME?.trim();
29
+ return c ? c : inHome(ctx, ".codex");
30
+ }
31
+ export const AGENT_REGISTRY = [
32
+ {
33
+ name: "claude",
34
+ label: "Claude Code",
35
+ detectDirs: (c) => [claudeConfigDir(c)],
36
+ globalSkillsDir: (c) => path.join(claudeConfigDir(c), "skills"),
37
+ localDir: ".claude/skills",
38
+ },
39
+ {
40
+ name: "cursor",
41
+ label: "Cursor",
42
+ detectDirs: (c) => [inHome(c, ".cursor")],
43
+ globalSkillsDir: (c) => inHome(c, ".cursor", "skills"),
44
+ localDir: ".agents/skills",
45
+ },
46
+ {
47
+ name: "copilot",
48
+ label: "GitHub Copilot",
49
+ detectDirs: (c) => [inHome(c, ".copilot")],
50
+ globalSkillsDir: (c) => inHome(c, ".copilot", "skills"),
51
+ localDir: ".agents/skills",
52
+ },
53
+ {
54
+ name: "gemini",
55
+ label: "Gemini CLI",
56
+ detectDirs: (c) => [inHome(c, ".gemini")],
57
+ globalSkillsDir: (c) => inHome(c, ".gemini", "skills"),
58
+ localDir: ".agents/skills",
59
+ },
60
+ {
61
+ name: "codex",
62
+ label: "Codex",
63
+ detectDirs: (c) => [codexHome(c)],
64
+ globalSkillsDir: (c) => path.join(codexHome(c), "skills"),
65
+ localDir: ".agents/skills",
66
+ },
67
+ {
68
+ name: "windsurf",
69
+ label: "Windsurf",
70
+ detectDirs: (c) => [inHome(c, ".codeium", "windsurf")],
71
+ globalSkillsDir: (c) => inHome(c, ".codeium", "windsurf", "skills"),
72
+ localDir: ".windsurf/skills",
73
+ },
74
+ {
75
+ name: "antigravity",
76
+ label: "Antigravity",
77
+ detectDirs: (c) => [inHome(c, ".gemini", "antigravity")],
78
+ globalSkillsDir: (c) => inHome(c, ".gemini", "antigravity", "skills"),
79
+ localDir: ".agents/skills",
80
+ },
81
+ {
82
+ name: "cline",
83
+ label: "Cline",
84
+ detectDirs: (c) => [inHome(c, ".cline")],
85
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
86
+ localDir: ".agents/skills",
87
+ },
88
+ {
89
+ name: "opencode",
90
+ label: "OpenCode",
91
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "opencode")],
92
+ globalSkillsDir: (c) => path.join(xdgConfigHome(c), "opencode", "skills"),
93
+ localDir: ".agents/skills",
94
+ },
95
+ {
96
+ name: "roo",
97
+ label: "Roo Code",
98
+ detectDirs: (c) => [inHome(c, ".roo")],
99
+ globalSkillsDir: (c) => inHome(c, ".roo", "skills"),
100
+ localDir: ".roo/skills",
101
+ },
102
+ {
103
+ name: "zed",
104
+ label: "Zed",
105
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "zed")],
106
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
107
+ localDir: ".agents/skills",
108
+ },
109
+ ];
110
+ /** Absolute project-local skills dir for an agent. */
111
+ export function localSkillsDir(a, ctx) {
112
+ return path.join(ctx.cwd, ...a.localDir.split("/"));
113
+ }
114
+ /** Fallback agent when nothing is auto-detected in a fresh environment. */
115
+ export const DEFAULT_AGENT = "claude";
116
+ export function agentByName(name) {
117
+ return AGENT_REGISTRY.find((a) => a.name === name);
118
+ }
119
+ /**
120
+ * The shared cross-agent skills directory (the `.agents/skills` standard). Used
121
+ * as the canonical home for the symlink install mode: the skill lives here once
122
+ * and each agent links to it.
123
+ */
124
+ export function sharedSkillsDir(ctx, scope) {
125
+ return scope === "global"
126
+ ? inHome(ctx, ".agents", "skills")
127
+ : path.join(ctx.cwd, ".agents", "skills");
128
+ }
129
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ # Ghostrail factory toolchain image.
2
+ #
3
+ # The agent and the gate run INSIDE the backend workspace, so a container run
4
+ # needs the full toolchain, not a bare shell:
5
+ # - node + pnpm -> the gate (CI-mirror commands)
6
+ # - git + gh -> commit, push, and open the PR
7
+ # - claude -> the agent's inner loop (`claude -p`)
8
+ #
9
+ # Build it (see scripts/build-factory-image.sh) and point the config at it:
10
+ # [backend]
11
+ # kind = "container"
12
+ # image = "ghostrail-factory:local"
13
+ #
14
+ # Credentials are never baked in; they are forwarded per run from the host
15
+ # environment (ANTHROPIC_API_KEY, GH_TOKEN/GITHUB_TOKEN, LINEAR_API_KEY).
16
+ FROM node:22-slim
17
+
18
+ # git, the GitHub CLI, and TLS roots. gh comes from its own apt repository.
19
+ RUN apt-get update \
20
+ && apt-get install -y --no-install-recommends ca-certificates curl git gnupg \
21
+ && install -m 0755 -d /etc/apt/keyrings \
22
+ && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
23
+ -o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
24
+ && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
25
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
26
+ > /etc/apt/sources.list.d/github-cli.list \
27
+ && apt-get update \
28
+ && apt-get install -y --no-install-recommends gh \
29
+ && rm -rf /var/lib/apt/lists/*
30
+
31
+ # pnpm via corepack (bundled with Node), and the Claude Code CLI for the agent.
32
+ RUN corepack enable \
33
+ && npm install -g @anthropic-ai/claude-code
34
+
35
+ # Route GitHub https auth through gh's credential helper, so an in-container
36
+ # `git push` authenticates from the forwarded GH_TOKEN (no token in any URL).
37
+ RUN git config --system credential."https://github.com".helper "!gh auth git-credential"
38
+
39
+ WORKDIR /work
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghostrail",
3
- "version": "0.0.0",
3
+ "version": "0.2.0",
4
4
  "description": "Open source software factory for coding agents. Config-driven loops, pluggable isolation backends, human merge gate.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -24,7 +24,7 @@
24
24
  "bin": {
25
25
  "ghostrail": "dist/bin.js"
26
26
  },
27
- "files": ["dist", "templates", "LICENSE", "NOTICE", "README.md"],
27
+ "files": ["dist", "templates", "skill", "docker", "LICENSE", "NOTICE", "README.md"],
28
28
  "engines": {
29
29
  "node": ">=22"
30
30
  },
@@ -37,7 +37,8 @@
37
37
  "format": "biome format --write .",
38
38
  "test": "vitest run",
39
39
  "test:unit": "vitest run",
40
- "test:watch": "vitest"
40
+ "test:watch": "vitest",
41
+ "prepublishOnly": "pnpm lint && pnpm typecheck && pnpm test:unit && pnpm build"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@biomejs/biome": "1.9.4",