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 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/triage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,KAAK,UAAU,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { applyTriagePlan } from "./apply.js";
2
+ export { TRIAGE_PLAN_PATH, triageTick } from "./engine.js";
3
+ export { parseTriagePlan } from "./plan.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/triage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAmB,gBAAgB,EAAyB,UAAU,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAmB,eAAe,EAAsC,MAAM,WAAW,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The triage agent's output contract. It writes a JSON plan to a file in the
3
+ * workspace; ghostrail parses and validates it here, then applies it through the
4
+ * {@link TriageSource}. The agent never mutates the tracker directly.
5
+ */
6
+ /** One proposed sub-issue in a split plan. */
7
+ export interface SubIssuePlan {
8
+ title: string;
9
+ description?: string;
10
+ /**
11
+ * Indices (into the same `subIssues` array) of earlier sub-issues that must be
12
+ * done first. Each index must be a non-negative integer strictly less than
13
+ * this sub-issue's own index (dependencies point backward, so no cycles).
14
+ */
15
+ dependsOn?: number[];
16
+ }
17
+ /** A validated triage plan: either split the parent, or leave it as atomic. */
18
+ export type TriagePlan = {
19
+ status: "split";
20
+ reason?: string;
21
+ subIssues: SubIssuePlan[];
22
+ } | {
23
+ status: "noop";
24
+ reason?: string;
25
+ };
26
+ /** The result of parsing a plan: the plan, or a validation error. */
27
+ export type ParsedPlan = TriagePlan | {
28
+ status: "invalid";
29
+ error: string;
30
+ };
31
+ /**
32
+ * Parse and validate the raw plan JSON the agent wrote. A `split` plan needs a
33
+ * non-empty `subIssues` array of `{ title, description?, dependsOn? }`; a `noop`
34
+ * plan needs nothing else. Anything malformed yields `{ status: "invalid" }`.
35
+ */
36
+ export declare function parseTriagePlan(raw: string): ParsedPlan;
37
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/triage/plan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,YAAY,EAAE,CAAA;CAAE,GAC/D;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAkC3E;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA8BvD"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The triage agent's output contract. It writes a JSON plan to a file in the
3
+ * workspace; ghostrail parses and validates it here, then applies it through the
4
+ * {@link TriageSource}. The agent never mutates the tracker directly.
5
+ */
6
+ function invalid(error) {
7
+ return { status: "invalid", error };
8
+ }
9
+ function isRecord(value) {
10
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11
+ }
12
+ /** Validate one sub-issue at position `index`; return its normalized form or an error message. */
13
+ function parseSubIssue(raw, index) {
14
+ if (!isRecord(raw))
15
+ return `subIssues[${index}] must be an object`;
16
+ const { title, description, dependsOn } = raw;
17
+ if (typeof title !== "string" || title.trim().length === 0) {
18
+ return `subIssues[${index}].title must be a non-empty string`;
19
+ }
20
+ const out = { title };
21
+ if (description !== undefined) {
22
+ if (typeof description !== "string")
23
+ return `subIssues[${index}].description must be a string`;
24
+ out.description = description;
25
+ }
26
+ if (dependsOn !== undefined) {
27
+ if (!Array.isArray(dependsOn))
28
+ return `subIssues[${index}].dependsOn must be an array`;
29
+ for (const dep of dependsOn) {
30
+ if (!Number.isInteger(dep) || dep < 0 || dep >= index) {
31
+ return `subIssues[${index}].dependsOn must be earlier indices (0..${index - 1})`;
32
+ }
33
+ }
34
+ out.dependsOn = dependsOn;
35
+ }
36
+ return out;
37
+ }
38
+ /**
39
+ * Parse and validate the raw plan JSON the agent wrote. A `split` plan needs a
40
+ * non-empty `subIssues` array of `{ title, description?, dependsOn? }`; a `noop`
41
+ * plan needs nothing else. Anything malformed yields `{ status: "invalid" }`.
42
+ */
43
+ export function parseTriagePlan(raw) {
44
+ let value;
45
+ try {
46
+ value = JSON.parse(raw);
47
+ }
48
+ catch (error) {
49
+ return invalid(`not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
50
+ }
51
+ if (!isRecord(value))
52
+ return invalid("plan must be a JSON object");
53
+ const { status, reason } = value;
54
+ if (reason !== undefined && typeof reason !== "string")
55
+ return invalid("reason must be a string");
56
+ const reasonField = reason === undefined ? {} : { reason: reason };
57
+ if (status === "noop")
58
+ return { status: "noop", ...reasonField };
59
+ if (status === "split") {
60
+ const { subIssues } = value;
61
+ if (!Array.isArray(subIssues) || subIssues.length === 0) {
62
+ return invalid('a "split" plan needs a non-empty subIssues array');
63
+ }
64
+ const parsed = [];
65
+ for (let i = 0; i < subIssues.length; i++) {
66
+ const result = parseSubIssue(subIssues[i], i);
67
+ if (typeof result === "string")
68
+ return invalid(result);
69
+ parsed.push(result);
70
+ }
71
+ return { status: "split", subIssues: parsed, ...reasonField };
72
+ }
73
+ return invalid('status must be "split" or "noop"');
74
+ }
75
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/triage/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { FsFacade } from "./fsFacade.js";
2
+ import { type SkillTarget } from "./paths.js";
3
+ import { type TargetPlan } from "./plan.js";
4
+ import type { SkillIdentity } from "./registry.js";
5
+ /** Inspect each target and decide what installing `content` would do. Read-only. */
6
+ export declare function planTargets(targets: readonly SkillTarget[], content: string, skill: SkillIdentity, fs: FsFacade, force?: boolean): Promise<TargetPlan[]>;
7
+ /** What `applyPlans` actually did, for the caller to report. */
8
+ export interface ApplyResult {
9
+ created: string[];
10
+ updated: string[];
11
+ unchanged: string[];
12
+ /** Conflicts are never written; they are returned for the caller to explain. */
13
+ conflicts: TargetPlan[];
14
+ }
15
+ /**
16
+ * Write the plans. `create` and `update` are applied; `unchanged` is a no-op
17
+ * (which is what makes re-running safe); `conflict` is refused and reported, so
18
+ * a foreign file is never clobbered without `--force`.
19
+ */
20
+ export declare function applyPlans(plans: readonly TargetPlan[], content: string, fs: FsFacade): Promise<ApplyResult>;
21
+ /** Remove the skill from each directory. Returns the paths actually removed. */
22
+ export declare function removeSkill(skillsDirs: readonly string[], skill: SkillIdentity, fs: FsFacade): Promise<string[]>;
23
+ /** True when nothing would change — the "already up to date" case for `--check`. */
24
+ export declare function isUpToDate(plans: readonly TargetPlan[]): boolean;
25
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/apply.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,KAAK,UAAU,EAAsB,MAAM,WAAW,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,oFAAoF;AACpF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,EACpB,EAAE,EAAE,QAAQ,EACZ,KAAK,UAAQ,GACZ,OAAO,CAAC,UAAU,EAAE,CAAC,CA2BvB;AAED,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gFAAgF;IAChF,SAAS,EAAE,UAAU,EAAE,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,QAAQ,GACX,OAAO,CAAC,WAAW,CAAC,CA4BtB;AAED,gFAAgF;AAChF,wBAAsB,WAAW,CAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,KAAK,EAAE,aAAa,EACpB,EAAE,EAAE,QAAQ,GACX,OAAO,CAAC,MAAM,EAAE,CAAC,CASnB;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAEhE"}
@@ -0,0 +1,85 @@
1
+ // Part of the future `skilltend` package. Not vendored from a14y: a14y keeps
2
+ // this orchestration inside its 786-line CLI `index.ts`, mixed with presentation.
3
+ // Here it is engine logic — build plans, then apply them — so the library decides
4
+ // *what* happens and the consuming product decides how to say it.
5
+ import path from "node:path";
6
+ import { parseSkillVersion } from "./frontmatter.js";
7
+ import { skillDir } from "./paths.js";
8
+ import { planFile, planLink } from "./plan.js";
9
+ /** Inspect each target and decide what installing `content` would do. Read-only. */
10
+ export async function planTargets(targets, content, skill, fs, force = false) {
11
+ const fetchedVersion = parseSkillVersion(content);
12
+ const plans = [];
13
+ for (const target of targets) {
14
+ if (target.kind === "link") {
15
+ const st = await fs.lstat(target.managedPath);
16
+ const existing = st === null
17
+ ? { kind: "absent" }
18
+ : st.isSymbolicLink
19
+ ? { kind: "symlink", linkTarget: await fs.readlink(target.managedPath) }
20
+ : { kind: "other" };
21
+ plans.push(planLink({ target, fetchedVersion, existing, force }));
22
+ continue;
23
+ }
24
+ // copy / canonical: a real SKILL.md file.
25
+ const current = await fs.readFile(target.managedPath);
26
+ // A symlink anywhere on the way would make us write through to someone
27
+ // else's file, so treat it as one.
28
+ const fileStat = await fs.lstat(target.managedPath);
29
+ const dirStat = await fs.lstat(path.dirname(target.managedPath));
30
+ const isSymlink = Boolean(fileStat?.isSymbolicLink) || Boolean(dirStat?.isSymbolicLink);
31
+ plans.push(planFile({ skill, target, fetched: content, current, isSymlink, force }));
32
+ }
33
+ return plans;
34
+ }
35
+ /**
36
+ * Write the plans. `create` and `update` are applied; `unchanged` is a no-op
37
+ * (which is what makes re-running safe); `conflict` is refused and reported, so
38
+ * a foreign file is never clobbered without `--force`.
39
+ */
40
+ export async function applyPlans(plans, content, fs) {
41
+ const result = { created: [], updated: [], unchanged: [], conflicts: [] };
42
+ for (const plan of plans) {
43
+ const { target, action } = plan;
44
+ if (action === "conflict") {
45
+ result.conflicts.push(plan);
46
+ continue;
47
+ }
48
+ if (action === "unchanged") {
49
+ result.unchanged.push(target.managedPath);
50
+ continue;
51
+ }
52
+ if (target.kind === "link") {
53
+ if (target.linkTo === undefined)
54
+ continue;
55
+ await fs.mkdirp(path.dirname(target.managedPath));
56
+ // Replace whatever is there; planLink already refused unless it was ours
57
+ // or the caller passed --force.
58
+ await fs.rm(target.managedPath);
59
+ await fs.symlink(target.linkTo, target.managedPath);
60
+ }
61
+ else {
62
+ await fs.mkdirp(path.dirname(target.managedPath));
63
+ await fs.writeFile(target.managedPath, content);
64
+ }
65
+ (action === "create" ? result.created : result.updated).push(target.managedPath);
66
+ }
67
+ return result;
68
+ }
69
+ /** Remove the skill from each directory. Returns the paths actually removed. */
70
+ export async function removeSkill(skillsDirs, skill, fs) {
71
+ const removed = [];
72
+ for (const dir of skillsDirs) {
73
+ const target = skillDir(dir, skill);
74
+ if ((await fs.lstat(target)) === null)
75
+ continue;
76
+ await fs.rm(target);
77
+ removed.push(target);
78
+ }
79
+ return removed;
80
+ }
81
+ /** True when nothing would change — the "already up to date" case for `--check`. */
82
+ export function isUpToDate(plans) {
83
+ return plans.length > 0 && plans.every((p) => p.action === "unchanged");
84
+ }
85
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { FsFacade } from "./fsFacade.js";
2
+ import { type Scope, type SkillTarget } from "./paths.js";
3
+ import { type AgentEntry, type PathCtx, type SkillIdentity } from "./registry.js";
4
+ export type InstallMethod = "copy" | "link";
5
+ /** Build install targets for the given agents, scope, and method. */
6
+ export declare function buildTargets(agents: AgentEntry[], scope: Scope, ctx: PathCtx, skill: SkillIdentity, method?: InstallMethod): SkillTarget[];
7
+ export interface DetectMatch {
8
+ agent: AgentEntry;
9
+ /** The marker directory that matched (shown to the user). */
10
+ dir: string;
11
+ }
12
+ /** Detect configured agents along with the marker dir that matched. */
13
+ export declare function detectAgentMatches(ctx: PathCtx, fs: FsFacade): Promise<DetectMatch[]>;
14
+ /** Detect which registered agents are configured under the given scope. */
15
+ export declare function detectAgents(ctx: PathCtx, fs: FsFacade): Promise<AgentEntry[]>;
16
+ /** Targets for an explicit `--agent <name>` selection. Throws on unknown names. */
17
+ export declare function agentTargets(names: string[], scope: Scope, ctx: PathCtx, skill: SkillIdentity, method?: InstallMethod): SkillTarget[];
18
+ /** Single target for an explicit `--target <dir>` (bypasses scope + registry). */
19
+ export declare function explicitTarget(dir: string, ctx: PathCtx, skill: SkillIdentity): SkillTarget;
20
+ export interface RemovalTarget {
21
+ agents: string[];
22
+ label: string;
23
+ /** The skill directory or symlink to remove. */
24
+ path: string;
25
+ kind: "link" | "dir";
26
+ version: string | null;
27
+ }
28
+ /**
29
+ * Find every place the skill is installed under the given scope — the
30
+ * shared `.agents/skills` dir and each registered agent's skills dir — whether
31
+ * it's a real copy or a symlink. Foreign directories of the same name (not our skill) are
32
+ * ignored so uninstall never deletes someone else's files.
33
+ */
34
+ export declare function scanInstalled(ctx: PathCtx, scope: Scope, fs: FsFacade, skill: SkillIdentity): Promise<RemovalTarget[]>;
35
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/detect.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,WAAW,EAA0C,MAAM,YAAY,CAAC;AAClG,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,aAAa,EAInB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AA4F5C,qEAAqE;AACrE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,UAAU,EAAE,EACpB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,aAAa,EACpB,MAAM,GAAE,aAAsB,GAC7B,WAAW,EAAE,CAKf;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,UAAU,CAAC;IAClB,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,uEAAuE;AACvE,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAW3F;AAED,2EAA2E;AAC3E,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAEpF;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,aAAa,EACpB,MAAM,GAAE,aAAsB,GAC7B,WAAW,EAAE,CAWf;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,GAAG,WAAW,CAQ3F;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,aAAa,EAAE,CAAC,CAgD1B"}
@@ -0,0 +1,187 @@
1
+ // Vendored from timothyjordan/a14y @ 07ef2bbb8593
2
+ // (packages/apps/cli/src/skills/detect.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
+ import { SkillsConfigError, skillDir, skillFile } from "./paths.js";
12
+ import { AGENT_REGISTRY, agentByName, localSkillsDir, sharedSkillsDir, } from "./registry.js";
13
+ function requireBase(ctx, scope) {
14
+ if (scope === "global" && !ctx.home) {
15
+ throw new SkillsConfigError("Could not determine your home directory. Pass --target <dir> or use --local.");
16
+ }
17
+ if (scope === "local" && !ctx.cwd) {
18
+ throw new SkillsConfigError("Could not determine the current directory.");
19
+ }
20
+ }
21
+ function agentSkillsDir(a, scope, ctx) {
22
+ return scope === "global" ? a.globalSkillsDir(ctx) : localSkillsDir(a, ctx);
23
+ }
24
+ /** Copy targets: a real SKILL.md in each agent's own skills dir (deduped). */
25
+ function buildCopyTargets(agents, scope, ctx, skill) {
26
+ const byPath = new Map();
27
+ for (const a of agents) {
28
+ const file = skillFile(agentSkillsDir(a, scope, ctx), skill);
29
+ const hit = byPath.get(file);
30
+ if (hit) {
31
+ hit.agents.push(a.name);
32
+ hit.labels.push(a.label);
33
+ }
34
+ else {
35
+ byPath.set(file, { agents: [a.name], labels: [a.label] });
36
+ }
37
+ }
38
+ return [...byPath.entries()].map(([managedPath, v]) => ({
39
+ kind: "copy",
40
+ agents: v.agents,
41
+ label: v.labels.join(" + "),
42
+ managedPath,
43
+ }));
44
+ }
45
+ /**
46
+ * Link targets: one canonical SKILL.md in the shared `.agents/skills` dir, plus
47
+ * a symlink from every other agent's skill dir to it. Agents whose skills dir
48
+ * *is* the shared dir are served by the canonical directly (no extra symlink).
49
+ */
50
+ function buildLinkTargets(agents, scope, ctx, skill) {
51
+ const shared = sharedSkillsDir(ctx, scope);
52
+ const canonicalDir = skillDir(shared, skill);
53
+ const canonicalFile = skillFile(shared, skill);
54
+ const direct = [];
55
+ const links = new Map();
56
+ for (const a of agents) {
57
+ const dir = agentSkillsDir(a, scope, ctx);
58
+ if (path.resolve(dir) === path.resolve(shared)) {
59
+ direct.push(a.label);
60
+ continue;
61
+ }
62
+ const linkPath = skillDir(dir, skill);
63
+ const hit = links.get(linkPath);
64
+ if (hit) {
65
+ hit.agents.push(a.name);
66
+ hit.labels.push(a.label);
67
+ }
68
+ else {
69
+ links.set(linkPath, { agents: [a.name], labels: [a.label] });
70
+ }
71
+ }
72
+ const canonical = {
73
+ kind: "canonical",
74
+ agents: ["shared"],
75
+ label: direct.length ? `Shared + ${direct.join(" + ")}` : "Shared (.agents/skills)",
76
+ managedPath: canonicalFile,
77
+ };
78
+ const linkTargets = [...links.entries()].map(([managedPath, v]) => ({
79
+ kind: "link",
80
+ agents: v.agents,
81
+ label: v.labels.join(" + "),
82
+ managedPath,
83
+ linkTo: canonicalDir,
84
+ }));
85
+ return [canonical, ...linkTargets];
86
+ }
87
+ /** Build install targets for the given agents, scope, and method. */
88
+ export function buildTargets(agents, scope, ctx, skill, method = "copy") {
89
+ requireBase(ctx, scope);
90
+ return method === "link"
91
+ ? buildLinkTargets(agents, scope, ctx, skill)
92
+ : buildCopyTargets(agents, scope, ctx, skill);
93
+ }
94
+ /** Detect configured agents along with the marker dir that matched. */
95
+ export async function detectAgentMatches(ctx, fs) {
96
+ const matches = [];
97
+ for (const a of AGENT_REGISTRY) {
98
+ for (const dir of a.detectDirs(ctx)) {
99
+ if (await fs.dirExists(dir)) {
100
+ matches.push({ agent: a, dir });
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ return matches;
106
+ }
107
+ /** Detect which registered agents are configured under the given scope. */
108
+ export async function detectAgents(ctx, fs) {
109
+ return (await detectAgentMatches(ctx, fs)).map((m) => m.agent);
110
+ }
111
+ /** Targets for an explicit `--agent <name>` selection. Throws on unknown names. */
112
+ export function agentTargets(names, scope, ctx, skill, method = "copy") {
113
+ const agents = [];
114
+ for (const name of names) {
115
+ const entry = agentByName(name);
116
+ if (!entry) {
117
+ const known = AGENT_REGISTRY.map((a) => a.name).join(", ");
118
+ throw new SkillsConfigError(`Unknown agent "${name}". Known agents: ${known}.`);
119
+ }
120
+ if (!agents.includes(entry))
121
+ agents.push(entry);
122
+ }
123
+ return buildTargets(agents, scope, ctx, skill, method);
124
+ }
125
+ /** Single target for an explicit `--target <dir>` (bypasses scope + registry). */
126
+ export function explicitTarget(dir, ctx, skill) {
127
+ const skillsDir = path.resolve(ctx.cwd || ".", dir);
128
+ return {
129
+ kind: "copy",
130
+ agents: ["custom"],
131
+ label: `custom target (${dir})`,
132
+ managedPath: skillFile(skillsDir, skill),
133
+ };
134
+ }
135
+ /**
136
+ * Find every place the skill is installed under the given scope — the
137
+ * shared `.agents/skills` dir and each registered agent's skills dir — whether
138
+ * it's a real copy or a symlink. Foreign directories of the same name (not our skill) are
139
+ * ignored so uninstall never deletes someone else's files.
140
+ */
141
+ export async function scanInstalled(ctx, scope, fs, skill) {
142
+ requireBase(ctx, scope);
143
+ // Candidate skills dirs: the shared dir plus every agent's own dir.
144
+ const candidates = [
145
+ { skillsDir: sharedSkillsDir(ctx, scope), label: "Shared (.agents/skills)", agent: "shared" },
146
+ ...AGENT_REGISTRY.map((a) => ({
147
+ skillsDir: agentSkillsDir(a, scope, ctx),
148
+ label: a.label,
149
+ agent: a.name,
150
+ })),
151
+ ];
152
+ const byPath = new Map();
153
+ for (const c of candidates) {
154
+ const dir = skillDir(c.skillsDir, skill);
155
+ const seen = byPath.get(dir);
156
+ if (seen) {
157
+ seen.agents.push(c.agent);
158
+ seen.labels.push(c.label);
159
+ continue;
160
+ }
161
+ const st = await fs.lstat(dir);
162
+ if (!st)
163
+ continue;
164
+ if (st.isSymbolicLink) {
165
+ byPath.set(dir, { agents: [c.agent], labels: [c.label], kind: "link", version: null });
166
+ }
167
+ else if (st.isDirectory) {
168
+ const content = await fs.readFile(skillFile(c.skillsDir, skill));
169
+ if (content && parseSkillName(content) === skill.name) {
170
+ byPath.set(dir, {
171
+ agents: [c.agent],
172
+ labels: [c.label],
173
+ kind: "dir",
174
+ version: parseSkillVersion(content),
175
+ });
176
+ }
177
+ }
178
+ }
179
+ return [...byPath.entries()].map(([p, v]) => ({
180
+ agents: v.agents,
181
+ label: v.labels.join(" + "),
182
+ path: p,
183
+ kind: v.kind,
184
+ version: v.version,
185
+ }));
186
+ }
187
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Top-level `name:` from the frontmatter, or null. */
2
+ export declare function parseSkillName(content: string): string | null;
3
+ /** `metadata.version` from the frontmatter, or null when absent/unparseable. */
4
+ export declare function parseSkillVersion(content: string): string | null;
5
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/frontmatter.ts"],"names":[],"mappings":"AA4BA,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK7D;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBhE"}
@@ -0,0 +1,59 @@
1
+ // Vendored from timothyjordan/a14y @ 07ef2bbb8593
2
+ // (packages/apps/cli/src/skills/frontmatter.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
+ // Minimal, zero-dependency reads of the two SKILL.md frontmatter fields the
10
+ // installer cares about: the top-level `name` (to tell our own skill apart from
11
+ // a foreign file) and the nested `metadata.version` (to surface old -> new on an
12
+ // update). The frontmatter shape is fixed and simple, so a focused scan beats
13
+ // pulling a YAML parser into the published CLI bundle.
14
+ function extractFrontmatter(content) {
15
+ // Optional BOM, then a `---` fence, the body, then a closing `---` fence.
16
+ const match = /^\uFEFF?---\r?\n([\s\S]*?)\r?\n---/.exec(content);
17
+ return match?.[1] ?? null;
18
+ }
19
+ function stripQuotes(value) {
20
+ const t = value.trim();
21
+ if ((t.startsWith('"') && t.endsWith('"')) || (t.startsWith("'") && t.endsWith("'"))) {
22
+ return t.slice(1, -1);
23
+ }
24
+ return t;
25
+ }
26
+ /** Top-level `name:` from the frontmatter, or null. */
27
+ export function parseSkillName(content) {
28
+ const fm = extractFrontmatter(content);
29
+ if (!fm)
30
+ return null;
31
+ const value = /^name:[ \t]*(.+?)[ \t]*$/m.exec(fm)?.[1];
32
+ return value === undefined ? null : stripQuotes(value);
33
+ }
34
+ /** `metadata.version` from the frontmatter, or null when absent/unparseable. */
35
+ export function parseSkillVersion(content) {
36
+ const fm = extractFrontmatter(content);
37
+ if (!fm)
38
+ return null;
39
+ const lines = fm.split(/\r?\n/);
40
+ let inMetadata = false;
41
+ for (const line of lines) {
42
+ if (/^metadata:[ \t]*$/.test(line)) {
43
+ inMetadata = true;
44
+ continue;
45
+ }
46
+ if (!inMetadata)
47
+ continue;
48
+ // A non-indented line ends the metadata block.
49
+ if (/^\S/.test(line)) {
50
+ inMetadata = false;
51
+ continue;
52
+ }
53
+ const value = /^[ \t]+version:[ \t]*(.+?)[ \t]*$/.exec(line)?.[1];
54
+ if (value !== undefined)
55
+ return stripQuotes(value);
56
+ }
57
+ return null;
58
+ }
59
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../src/vendor/skilltend/frontmatter.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,6DAA6D;AAC7D,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,gEAAgE;AAChE,4EAA4E;AAC5E,gFAAgF;AAChF,iFAAiF;AACjF,8EAA8E;AAC9E,uDAAuD;AAEvD,SAAS,kBAAkB,CAAC,OAAe;IACzC,0EAA0E;IAC1E,MAAM,KAAK,GAAG,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACrF,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,MAAM,KAAK,GAAG,2BAA2B,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,UAAU,GAAG,IAAI,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,+CAA+C;QAC/C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,UAAU,GAAG,KAAK,CAAC;YACnB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Tiny filesystem seam so the orchestrator can run against an in-memory fake in
3
+ * unit tests. `readFile`/`lstat`/`readlink` return null on ENOENT instead of
4
+ * throwing so the caller treats "absent" as a value, not an exception.
5
+ */
6
+ export interface FsFacade {
7
+ readFile(path: string): Promise<string | null>;
8
+ writeFile(path: string, content: string): Promise<void>;
9
+ mkdirp(path: string): Promise<void>;
10
+ lstat(path: string): Promise<{
11
+ isSymbolicLink: boolean;
12
+ isDirectory: boolean;
13
+ } | null>;
14
+ /** Symlink target of `path`, or null when it is absent or not a symlink. */
15
+ readlink(path: string): Promise<string | null>;
16
+ /** Create a symlink at `linkPath` pointing to `target` (dir-type). */
17
+ symlink(target: string, linkPath: string): Promise<void>;
18
+ /** Remove a file, symlink, or directory tree. No-op when absent. */
19
+ rm(path: string): Promise<void>;
20
+ /** True when `path` exists and is a directory (used for agent auto-detect). */
21
+ dirExists(path: string): Promise<boolean>;
22
+ }
23
+ export declare const nodeFs: FsFacade;
24
+ //# sourceMappingURL=fsFacade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsFacade.d.ts","sourceRoot":"","sources":["../../../src/vendor/skilltend/fsFacade.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,cAAc,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACvF,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,sEAAsE;IACtE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,oEAAoE;IACpE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,+EAA+E;IAC/E,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C;AAMD,eAAO,MAAM,MAAM,EAAE,QA+CpB,CAAC"}