ghostrail 0.1.0 → 0.3.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 (75) hide show
  1. package/README.md +20 -1
  2. package/dist/agent/claude-code.d.ts.map +1 -1
  3. package/dist/agent/claude-code.js +11 -4
  4. package/dist/agent/claude-code.js.map +1 -1
  5. package/dist/backend/container.d.ts.map +1 -1
  6. package/dist/backend/container.js +24 -2
  7. package/dist/backend/container.js.map +1 -1
  8. package/dist/backend/docker.d.ts +6 -1
  9. package/dist/backend/docker.d.ts.map +1 -1
  10. package/dist/backend/docker.js +7 -2
  11. package/dist/backend/docker.js.map +1 -1
  12. package/dist/backend/local-worktree.d.ts.map +1 -1
  13. package/dist/backend/local-worktree.js +15 -2
  14. package/dist/backend/local-worktree.js.map +1 -1
  15. package/dist/backend/types.d.ts +14 -0
  16. package/dist/backend/types.d.ts.map +1 -1
  17. package/dist/cli/commands.d.ts +40 -0
  18. package/dist/cli/commands.d.ts.map +1 -1
  19. package/dist/cli/commands.js +145 -0
  20. package/dist/cli/commands.js.map +1 -1
  21. package/dist/cli.d.ts.map +1 -1
  22. package/dist/cli.js +7 -1
  23. package/dist/cli.js.map +1 -1
  24. package/dist/commands/help.d.ts.map +1 -1
  25. package/dist/commands/help.js +11 -0
  26. package/dist/commands/help.js.map +1 -1
  27. package/dist/factory/build.d.ts.map +1 -1
  28. package/dist/factory/build.js +3 -0
  29. package/dist/factory/build.js.map +1 -1
  30. package/dist/loop/engine.d.ts +2 -0
  31. package/dist/loop/engine.d.ts.map +1 -1
  32. package/dist/loop/engine.js +1 -0
  33. package/dist/loop/engine.js.map +1 -1
  34. package/dist/respond/respond.d.ts +2 -0
  35. package/dist/respond/respond.d.ts.map +1 -1
  36. package/dist/respond/respond.js +1 -0
  37. package/dist/respond/respond.js.map +1 -1
  38. package/dist/skill/install.d.ts +56 -0
  39. package/dist/skill/install.d.ts.map +1 -0
  40. package/dist/skill/install.js +93 -0
  41. package/dist/skill/install.js.map +1 -0
  42. package/dist/triage/engine.d.ts +2 -0
  43. package/dist/triage/engine.d.ts.map +1 -1
  44. package/dist/triage/engine.js +1 -0
  45. package/dist/triage/engine.js.map +1 -1
  46. package/dist/vendor/skilltend/apply.d.ts +25 -0
  47. package/dist/vendor/skilltend/apply.d.ts.map +1 -0
  48. package/dist/vendor/skilltend/apply.js +85 -0
  49. package/dist/vendor/skilltend/apply.js.map +1 -0
  50. package/dist/vendor/skilltend/detect.d.ts +35 -0
  51. package/dist/vendor/skilltend/detect.d.ts.map +1 -0
  52. package/dist/vendor/skilltend/detect.js +187 -0
  53. package/dist/vendor/skilltend/detect.js.map +1 -0
  54. package/dist/vendor/skilltend/frontmatter.d.ts +5 -0
  55. package/dist/vendor/skilltend/frontmatter.d.ts.map +1 -0
  56. package/dist/vendor/skilltend/frontmatter.js +59 -0
  57. package/dist/vendor/skilltend/frontmatter.js.map +1 -0
  58. package/dist/vendor/skilltend/fsFacade.d.ts +24 -0
  59. package/dist/vendor/skilltend/fsFacade.d.ts.map +1 -0
  60. package/dist/vendor/skilltend/fsFacade.js +68 -0
  61. package/dist/vendor/skilltend/fsFacade.js.map +1 -0
  62. package/dist/vendor/skilltend/paths.d.ts +28 -0
  63. package/dist/vendor/skilltend/paths.d.ts.map +1 -0
  64. package/dist/vendor/skilltend/paths.js +24 -0
  65. package/dist/vendor/skilltend/paths.js.map +1 -0
  66. package/dist/vendor/skilltend/plan.d.ts +46 -0
  67. package/dist/vendor/skilltend/plan.d.ts.map +1 -0
  68. package/dist/vendor/skilltend/plan.js +79 -0
  69. package/dist/vendor/skilltend/plan.js.map +1 -0
  70. package/dist/vendor/skilltend/registry.d.ts +56 -0
  71. package/dist/vendor/skilltend/registry.d.ts.map +1 -0
  72. package/dist/vendor/skilltend/registry.js +480 -0
  73. package/dist/vendor/skilltend/registry.js.map +1 -0
  74. package/package.json +2 -2
  75. package/skill/ghostrail/SKILL.md +145 -0
@@ -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;AAuBD,eAAO,MAAM,cAAc,EAAE,UAAU,EAyatC,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,480 @@
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
+ /** An agent whose home is `$VAR` when set, else `~/<fallback>`. */
32
+ function envHome(ctx, varName, fallback) {
33
+ const v = ctx.env[varName]?.trim();
34
+ return v ? v : inHome(ctx, fallback);
35
+ }
36
+ export const AGENT_REGISTRY = [
37
+ {
38
+ name: "claude",
39
+ label: "Claude Code",
40
+ detectDirs: (c) => [claudeConfigDir(c)],
41
+ globalSkillsDir: (c) => path.join(claudeConfigDir(c), "skills"),
42
+ localDir: ".claude/skills",
43
+ },
44
+ {
45
+ name: "cursor",
46
+ label: "Cursor",
47
+ detectDirs: (c) => [inHome(c, ".cursor")],
48
+ globalSkillsDir: (c) => inHome(c, ".cursor", "skills"),
49
+ localDir: ".agents/skills",
50
+ },
51
+ {
52
+ name: "copilot",
53
+ label: "GitHub Copilot",
54
+ detectDirs: (c) => [inHome(c, ".copilot")],
55
+ globalSkillsDir: (c) => inHome(c, ".copilot", "skills"),
56
+ localDir: ".agents/skills",
57
+ },
58
+ {
59
+ name: "gemini",
60
+ label: "Gemini CLI",
61
+ detectDirs: (c) => [inHome(c, ".gemini")],
62
+ globalSkillsDir: (c) => inHome(c, ".gemini", "skills"),
63
+ localDir: ".agents/skills",
64
+ },
65
+ {
66
+ name: "codex",
67
+ label: "Codex",
68
+ detectDirs: (c) => [codexHome(c)],
69
+ globalSkillsDir: (c) => path.join(codexHome(c), "skills"),
70
+ localDir: ".agents/skills",
71
+ },
72
+ {
73
+ name: "windsurf",
74
+ label: "Windsurf",
75
+ detectDirs: (c) => [inHome(c, ".codeium", "windsurf")],
76
+ globalSkillsDir: (c) => inHome(c, ".codeium", "windsurf", "skills"),
77
+ localDir: ".windsurf/skills",
78
+ },
79
+ {
80
+ name: "antigravity",
81
+ label: "Antigravity",
82
+ detectDirs: (c) => [inHome(c, ".gemini", "antigravity")],
83
+ globalSkillsDir: (c) => inHome(c, ".gemini", "antigravity", "skills"),
84
+ localDir: ".agents/skills",
85
+ },
86
+ {
87
+ name: "cline",
88
+ label: "Cline",
89
+ detectDirs: (c) => [inHome(c, ".cline")],
90
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
91
+ localDir: ".agents/skills",
92
+ },
93
+ {
94
+ name: "opencode",
95
+ label: "OpenCode",
96
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "opencode")],
97
+ globalSkillsDir: (c) => path.join(xdgConfigHome(c), "opencode", "skills"),
98
+ localDir: ".agents/skills",
99
+ },
100
+ {
101
+ name: "roo",
102
+ label: "Roo Code",
103
+ detectDirs: (c) => [inHome(c, ".roo")],
104
+ globalSkillsDir: (c) => inHome(c, ".roo", "skills"),
105
+ localDir: ".roo/skills",
106
+ },
107
+ {
108
+ name: "zed",
109
+ label: "Zed",
110
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "zed")],
111
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
112
+ localDir: ".agents/skills",
113
+ },
114
+ // Additional agents ported from vercel-labs/skills (src/agents.ts), whose list
115
+ // is maintained by PRs from the agent authors. Each entry only activates when
116
+ // its detectDirs exist, so breadth here is inert until a user has that agent.
117
+ {
118
+ name: "aider-desk",
119
+ label: "AiderDesk",
120
+ detectDirs: (c) => [inHome(c, ".aider-desk")],
121
+ globalSkillsDir: (c) => inHome(c, ".aider-desk", "skills"),
122
+ localDir: ".aider-desk/skills",
123
+ },
124
+ {
125
+ name: "amp",
126
+ label: "Amp",
127
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "amp")],
128
+ globalSkillsDir: (c) => path.join(xdgConfigHome(c), "agents", "skills"),
129
+ localDir: ".agents/skills",
130
+ },
131
+ {
132
+ name: "antigravity-cli",
133
+ label: "Antigravity CLI",
134
+ detectDirs: (c) => [inHome(c, ".gemini", "antigravity-cli")],
135
+ globalSkillsDir: (c) => inHome(c, ".gemini", "antigravity-cli", "skills"),
136
+ localDir: ".agents/skills",
137
+ },
138
+ {
139
+ name: "augment",
140
+ label: "Augment",
141
+ detectDirs: (c) => [inHome(c, ".augment")],
142
+ globalSkillsDir: (c) => inHome(c, ".augment", "skills"),
143
+ localDir: ".augment/skills",
144
+ },
145
+ {
146
+ name: "bob",
147
+ label: "IBM Bob",
148
+ detectDirs: (c) => [inHome(c, ".bob")],
149
+ globalSkillsDir: (c) => inHome(c, ".bob", "skills"),
150
+ localDir: ".bob/skills",
151
+ },
152
+ {
153
+ name: "codearts-agent",
154
+ label: "CodeArts Agent",
155
+ detectDirs: (c) => [inHome(c, ".codeartsdoer")],
156
+ globalSkillsDir: (c) => inHome(c, ".codeartsdoer", "skills"),
157
+ localDir: ".codeartsdoer/skills",
158
+ },
159
+ {
160
+ name: "codemaker",
161
+ label: "Codemaker",
162
+ detectDirs: (c) => [inHome(c, ".codemaker")],
163
+ globalSkillsDir: (c) => inHome(c, ".codemaker", "skills"),
164
+ localDir: ".codemaker/skills",
165
+ },
166
+ {
167
+ name: "codestudio",
168
+ label: "Code Studio",
169
+ detectDirs: (c) => [inHome(c, ".codestudio")],
170
+ globalSkillsDir: (c) => inHome(c, ".codestudio", "skills"),
171
+ localDir: ".codestudio/skills",
172
+ },
173
+ {
174
+ name: "command-code",
175
+ label: "Command Code",
176
+ detectDirs: (c) => [inHome(c, ".commandcode")],
177
+ globalSkillsDir: (c) => inHome(c, ".commandcode", "skills"),
178
+ localDir: ".commandcode/skills",
179
+ },
180
+ {
181
+ name: "cortex",
182
+ label: "Cortex Code",
183
+ detectDirs: (c) => [inHome(c, ".snowflake", "cortex")],
184
+ globalSkillsDir: (c) => inHome(c, ".snowflake", "cortex", "skills"),
185
+ localDir: ".cortex/skills",
186
+ },
187
+ {
188
+ name: "crush",
189
+ label: "Crush",
190
+ detectDirs: (c) => [inHome(c, ".config", "crush")],
191
+ globalSkillsDir: (c) => inHome(c, ".config", "crush", "skills"),
192
+ localDir: ".crush/skills",
193
+ },
194
+ {
195
+ name: "deepagents",
196
+ label: "Deep Agents",
197
+ detectDirs: (c) => [inHome(c, ".deepagents")],
198
+ globalSkillsDir: (c) => inHome(c, ".deepagents", "agent", "skills"),
199
+ localDir: ".agents/skills",
200
+ },
201
+ {
202
+ name: "devin",
203
+ label: "Devin for Terminal",
204
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "devin")],
205
+ globalSkillsDir: (c) => path.join(xdgConfigHome(c), "devin", "skills"),
206
+ localDir: ".devin/skills",
207
+ },
208
+ {
209
+ name: "dexto",
210
+ label: "Dexto",
211
+ detectDirs: (c) => [inHome(c, ".dexto")],
212
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
213
+ localDir: ".agents/skills",
214
+ },
215
+ {
216
+ name: "droid",
217
+ label: "Droid",
218
+ detectDirs: (c) => [inHome(c, ".factory")],
219
+ globalSkillsDir: (c) => inHome(c, ".factory", "skills"),
220
+ localDir: ".factory/skills",
221
+ },
222
+ {
223
+ name: "firebender",
224
+ label: "Firebender",
225
+ detectDirs: (c) => [inHome(c, ".firebender")],
226
+ globalSkillsDir: (c) => inHome(c, ".firebender", "skills"),
227
+ localDir: ".agents/skills",
228
+ },
229
+ {
230
+ name: "forgecode",
231
+ label: "ForgeCode",
232
+ detectDirs: (c) => [inHome(c, ".forge")],
233
+ globalSkillsDir: (c) => inHome(c, ".forge", "skills"),
234
+ localDir: ".forge/skills",
235
+ },
236
+ {
237
+ name: "goose",
238
+ label: "Goose",
239
+ detectDirs: (c) => [path.join(xdgConfigHome(c), "goose")],
240
+ globalSkillsDir: (c) => path.join(xdgConfigHome(c), "goose", "skills"),
241
+ localDir: ".goose/skills",
242
+ },
243
+ {
244
+ name: "inference-sh",
245
+ label: "inference.sh",
246
+ detectDirs: (c) => [inHome(c, ".inferencesh")],
247
+ globalSkillsDir: (c) => inHome(c, ".inferencesh", "skills"),
248
+ localDir: ".inferencesh/skills",
249
+ },
250
+ {
251
+ name: "junie",
252
+ label: "Junie",
253
+ detectDirs: (c) => [inHome(c, ".junie")],
254
+ globalSkillsDir: (c) => inHome(c, ".junie", "skills"),
255
+ localDir: ".junie/skills",
256
+ },
257
+ {
258
+ name: "iflow-cli",
259
+ label: "iFlow CLI",
260
+ detectDirs: (c) => [inHome(c, ".iflow")],
261
+ globalSkillsDir: (c) => inHome(c, ".iflow", "skills"),
262
+ localDir: ".iflow/skills",
263
+ },
264
+ {
265
+ name: "kilo",
266
+ label: "Kilo Code",
267
+ detectDirs: (c) => [inHome(c, ".kilocode")],
268
+ globalSkillsDir: (c) => inHome(c, ".kilocode", "skills"),
269
+ localDir: ".kilocode/skills",
270
+ },
271
+ {
272
+ name: "kimi-code-cli",
273
+ label: "Kimi Code CLI",
274
+ detectDirs: (c) => [inHome(c, ".kimi-code"), inHome(c, ".kimi")],
275
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
276
+ localDir: ".agents/skills",
277
+ },
278
+ {
279
+ name: "kiro-cli",
280
+ label: "Kiro CLI",
281
+ detectDirs: (c) => [inHome(c, ".kiro")],
282
+ globalSkillsDir: (c) => inHome(c, ".kiro", "skills"),
283
+ localDir: ".kiro/skills",
284
+ },
285
+ {
286
+ name: "kode",
287
+ label: "Kode",
288
+ detectDirs: (c) => [inHome(c, ".kode")],
289
+ globalSkillsDir: (c) => inHome(c, ".kode", "skills"),
290
+ localDir: ".kode/skills",
291
+ },
292
+ {
293
+ name: "lingma",
294
+ label: "Lingma",
295
+ detectDirs: (c) => [inHome(c, ".lingma")],
296
+ globalSkillsDir: (c) => inHome(c, ".lingma", "skills"),
297
+ localDir: ".lingma/skills",
298
+ },
299
+ {
300
+ name: "loaf",
301
+ label: "Loaf",
302
+ detectDirs: (c) => [inHome(c, ".loaf")],
303
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
304
+ localDir: ".agents/skills",
305
+ },
306
+ {
307
+ name: "mcpjam",
308
+ label: "MCPJam",
309
+ detectDirs: (c) => [inHome(c, ".mcpjam")],
310
+ globalSkillsDir: (c) => inHome(c, ".mcpjam", "skills"),
311
+ localDir: ".mcpjam/skills",
312
+ },
313
+ {
314
+ name: "moxby",
315
+ label: "Moxby",
316
+ detectDirs: (c) => [inHome(c, ".moxby")],
317
+ globalSkillsDir: (c) => inHome(c, ".moxby", "skills"),
318
+ localDir: ".moxby/skills",
319
+ },
320
+ {
321
+ name: "mux",
322
+ label: "Mux",
323
+ detectDirs: (c) => [inHome(c, ".mux")],
324
+ globalSkillsDir: (c) => inHome(c, ".mux", "skills"),
325
+ localDir: ".mux/skills",
326
+ },
327
+ {
328
+ name: "openhands",
329
+ label: "OpenHands",
330
+ detectDirs: (c) => [inHome(c, ".openhands")],
331
+ globalSkillsDir: (c) => inHome(c, ".openhands", "skills"),
332
+ localDir: ".openhands/skills",
333
+ },
334
+ {
335
+ name: "ona",
336
+ label: "Ona",
337
+ detectDirs: (c) => [inHome(c, ".ona")],
338
+ globalSkillsDir: (c) => inHome(c, ".ona", "skills"),
339
+ localDir: ".ona/skills",
340
+ },
341
+ {
342
+ name: "pi",
343
+ label: "Pi",
344
+ detectDirs: (c) => [inHome(c, ".pi", "agent")],
345
+ globalSkillsDir: (c) => inHome(c, ".pi", "agent", "skills"),
346
+ localDir: ".pi/skills",
347
+ },
348
+ {
349
+ name: "qoder",
350
+ label: "Qoder",
351
+ detectDirs: (c) => [inHome(c, ".qoder")],
352
+ globalSkillsDir: (c) => inHome(c, ".qoder", "skills"),
353
+ localDir: ".qoder/skills",
354
+ },
355
+ {
356
+ name: "qoder-cn",
357
+ label: "Qoder CN",
358
+ detectDirs: (c) => [inHome(c, ".qoder-cn")],
359
+ globalSkillsDir: (c) => inHome(c, ".qoder-cn", "skills"),
360
+ localDir: ".qoder/skills",
361
+ },
362
+ {
363
+ name: "qwen-code",
364
+ label: "Qwen Code",
365
+ detectDirs: (c) => [inHome(c, ".qwen")],
366
+ globalSkillsDir: (c) => inHome(c, ".qwen", "skills"),
367
+ localDir: ".qwen/skills",
368
+ },
369
+ {
370
+ name: "reasonix",
371
+ label: "Reasonix",
372
+ detectDirs: (c) => [inHome(c, ".reasonix")],
373
+ globalSkillsDir: (c) => inHome(c, ".reasonix", "skills"),
374
+ localDir: ".reasonix/skills",
375
+ },
376
+ {
377
+ name: "rovodev",
378
+ label: "Rovo Dev",
379
+ detectDirs: (c) => [inHome(c, ".rovodev")],
380
+ globalSkillsDir: (c) => inHome(c, ".rovodev", "skills"),
381
+ localDir: ".rovodev/skills",
382
+ },
383
+ {
384
+ name: "tabnine-cli",
385
+ label: "Tabnine CLI",
386
+ detectDirs: (c) => [inHome(c, ".tabnine")],
387
+ globalSkillsDir: (c) => inHome(c, ".tabnine", "agent", "skills"),
388
+ localDir: ".tabnine/agent/skills",
389
+ },
390
+ {
391
+ name: "terramind",
392
+ label: "Terramind",
393
+ detectDirs: (c) => [inHome(c, ".terramind")],
394
+ globalSkillsDir: (c) => inHome(c, ".terramind", "skills"),
395
+ localDir: ".terramind/skills",
396
+ },
397
+ {
398
+ name: "tinycloud",
399
+ label: "Tinycloud",
400
+ detectDirs: (c) => [inHome(c, ".tinycloud")],
401
+ globalSkillsDir: (c) => inHome(c, ".tinycloud", "skills"),
402
+ localDir: ".tinycloud/skills",
403
+ },
404
+ {
405
+ name: "trae",
406
+ label: "Trae",
407
+ detectDirs: (c) => [inHome(c, ".trae")],
408
+ globalSkillsDir: (c) => inHome(c, ".trae", "skills"),
409
+ localDir: ".trae/skills",
410
+ },
411
+ {
412
+ name: "trae-cn",
413
+ label: "Trae CN",
414
+ detectDirs: (c) => [inHome(c, ".trae-cn")],
415
+ globalSkillsDir: (c) => inHome(c, ".trae-cn", "skills"),
416
+ localDir: ".trae/skills",
417
+ },
418
+ {
419
+ name: "warp",
420
+ label: "Warp",
421
+ detectDirs: (c) => [inHome(c, ".warp")],
422
+ globalSkillsDir: (c) => inHome(c, ".agents", "skills"),
423
+ localDir: ".agents/skills",
424
+ },
425
+ {
426
+ name: "zencoder",
427
+ label: "Zencoder",
428
+ detectDirs: (c) => [inHome(c, ".zencoder")],
429
+ globalSkillsDir: (c) => inHome(c, ".zencoder", "skills"),
430
+ localDir: ".zencoder/skills",
431
+ },
432
+ {
433
+ name: "zenflow",
434
+ label: "Zenflow",
435
+ detectDirs: (c) => [inHome(c, ".zencoder")],
436
+ globalSkillsDir: (c) => inHome(c, ".zencoder", "skills"),
437
+ localDir: ".zencoder/skills",
438
+ },
439
+ {
440
+ name: "neovate",
441
+ label: "Neovate",
442
+ detectDirs: (c) => [inHome(c, ".neovate")],
443
+ globalSkillsDir: (c) => inHome(c, ".neovate", "skills"),
444
+ localDir: ".neovate/skills",
445
+ },
446
+ {
447
+ name: "pochi",
448
+ label: "Pochi",
449
+ detectDirs: (c) => [inHome(c, ".pochi")],
450
+ globalSkillsDir: (c) => inHome(c, ".pochi", "skills"),
451
+ localDir: ".pochi/skills",
452
+ },
453
+ {
454
+ name: "adal",
455
+ label: "AdaL",
456
+ detectDirs: (c) => [inHome(c, ".adal")],
457
+ globalSkillsDir: (c) => inHome(c, ".adal", "skills"),
458
+ localDir: ".adal/skills",
459
+ },
460
+ ];
461
+ /** Absolute project-local skills dir for an agent. */
462
+ export function localSkillsDir(a, ctx) {
463
+ return path.join(ctx.cwd, ...a.localDir.split("/"));
464
+ }
465
+ /** Fallback agent when nothing is auto-detected in a fresh environment. */
466
+ export const DEFAULT_AGENT = "claude";
467
+ export function agentByName(name) {
468
+ return AGENT_REGISTRY.find((a) => a.name === name);
469
+ }
470
+ /**
471
+ * The shared cross-agent skills directory (the `.agents/skills` standard). Used
472
+ * as the canonical home for the symlink install mode: the skill lives here once
473
+ * and each agent links to it.
474
+ */
475
+ export function sharedSkillsDir(ctx, scope) {
476
+ return scope === "global"
477
+ ? inHome(ctx, ".agents", "skills")
478
+ : path.join(ctx.cwd, ".agents", "skills");
479
+ }
480
+ //# sourceMappingURL=registry.js.map