@wirecat/cli-base 0.0.0-stage → 0.21.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 (201) hide show
  1. package/LICENSE +204 -0
  2. package/README.md +376 -2
  3. package/config/biome.base.json +56 -0
  4. package/config/cspell.json +57 -0
  5. package/config/lefthook.yml +34 -0
  6. package/config/rumdl.toml +9 -0
  7. package/config/tsconfig.base.json +21 -0
  8. package/config/tsconfig.scripts.json +13 -0
  9. package/config/tsconfig.test.json +11 -0
  10. package/config/vale/CliDocs/Filler.yml +9 -0
  11. package/config/vale/CliDocs/SentenceLength.yml +6 -0
  12. package/config/vale/Tg/Tone.yml +7 -0
  13. package/config/wirecat/LICENSE +204 -0
  14. package/config/wirecat/biome.base.json +56 -0
  15. package/config/wirecat/check.mjs +41 -0
  16. package/config/wirecat/cspell.json +80 -0
  17. package/config/wirecat/lefthook.yml +26 -0
  18. package/config/wirecat/manifest.json +23 -0
  19. package/config/wirecat/markdownlint.json +10 -0
  20. package/config/wirecat/rumdl.toml +9 -0
  21. package/dist/codegen/index.d.ts +12 -0
  22. package/dist/codegen/index.d.ts.map +1 -0
  23. package/dist/codegen/index.js +11 -0
  24. package/dist/codegen/index.js.map +1 -0
  25. package/dist/codegen/manifest.d.ts +47 -0
  26. package/dist/codegen/manifest.d.ts.map +1 -0
  27. package/dist/codegen/manifest.js +73 -0
  28. package/dist/codegen/manifest.js.map +1 -0
  29. package/dist/codegen/model.d.ts +146 -0
  30. package/dist/codegen/model.d.ts.map +1 -0
  31. package/dist/codegen/model.js +7 -0
  32. package/dist/codegen/model.js.map +1 -0
  33. package/dist/codegen/names.d.ts +4 -0
  34. package/dist/codegen/names.d.ts.map +1 -0
  35. package/dist/codegen/names.js +46 -0
  36. package/dist/codegen/names.js.map +1 -0
  37. package/dist/codegen/pipeline.d.ts +24 -0
  38. package/dist/codegen/pipeline.d.ts.map +1 -0
  39. package/dist/codegen/pipeline.js +193 -0
  40. package/dist/codegen/pipeline.js.map +1 -0
  41. package/dist/codegen/runtime.d.ts +24 -0
  42. package/dist/codegen/runtime.d.ts.map +1 -0
  43. package/dist/codegen/runtime.js +38 -0
  44. package/dist/codegen/runtime.js.map +1 -0
  45. package/dist/codegen/tree.d.ts +29 -0
  46. package/dist/codegen/tree.d.ts.map +1 -0
  47. package/dist/codegen/tree.js +87 -0
  48. package/dist/codegen/tree.js.map +1 -0
  49. package/dist/codegen/typescript.d.ts +6 -0
  50. package/dist/codegen/typescript.d.ts.map +1 -0
  51. package/dist/codegen/typescript.js +78 -0
  52. package/dist/codegen/typescript.js.map +1 -0
  53. package/dist/codegen/valibot.d.ts +10 -0
  54. package/dist/codegen/valibot.d.ts.map +1 -0
  55. package/dist/codegen/valibot.js +132 -0
  56. package/dist/codegen/valibot.js.map +1 -0
  57. package/dist/commands/index.d.ts +76 -0
  58. package/dist/commands/index.d.ts.map +1 -0
  59. package/dist/commands/index.js +62 -0
  60. package/dist/commands/index.js.map +1 -0
  61. package/dist/commands/page.d.ts +80 -0
  62. package/dist/commands/page.d.ts.map +1 -0
  63. package/dist/commands/page.js +100 -0
  64. package/dist/commands/page.js.map +1 -0
  65. package/dist/completion/index.d.ts +37 -0
  66. package/dist/completion/index.d.ts.map +1 -0
  67. package/dist/completion/index.js +87 -0
  68. package/dist/completion/index.js.map +1 -0
  69. package/dist/config.d.ts +20 -0
  70. package/dist/config.d.ts.map +1 -0
  71. package/dist/config.js +61 -0
  72. package/dist/config.js.map +1 -0
  73. package/dist/credentials.d.ts +48 -0
  74. package/dist/credentials.d.ts.map +1 -0
  75. package/dist/credentials.js +120 -0
  76. package/dist/credentials.js.map +1 -0
  77. package/dist/deadline.d.ts +14 -0
  78. package/dist/deadline.d.ts.map +1 -0
  79. package/dist/deadline.js +88 -0
  80. package/dist/deadline.js.map +1 -0
  81. package/dist/dev/bin.d.ts +3 -0
  82. package/dist/dev/bin.d.ts.map +1 -0
  83. package/dist/dev/bin.js +8 -0
  84. package/dist/dev/bin.js.map +1 -0
  85. package/dist/dev/main.d.ts +7 -0
  86. package/dist/dev/main.d.ts.map +1 -0
  87. package/dist/dev/main.js +149 -0
  88. package/dist/dev/main.js.map +1 -0
  89. package/dist/dev/next-version.d.ts +11 -0
  90. package/dist/dev/next-version.d.ts.map +1 -0
  91. package/dist/dev/next-version.js +33 -0
  92. package/dist/dev/next-version.js.map +1 -0
  93. package/dist/dev/slow-tests.d.ts +14 -0
  94. package/dist/dev/slow-tests.d.ts.map +1 -0
  95. package/dist/dev/slow-tests.js +17 -0
  96. package/dist/dev/slow-tests.js.map +1 -0
  97. package/dist/dev/test-matrix.d.ts +35 -0
  98. package/dist/dev/test-matrix.d.ts.map +1 -0
  99. package/dist/dev/test-matrix.js +93 -0
  100. package/dist/dev/test-matrix.js.map +1 -0
  101. package/dist/errors.d.ts +34 -0
  102. package/dist/errors.d.ts.map +1 -0
  103. package/dist/errors.js +36 -0
  104. package/dist/errors.js.map +1 -0
  105. package/dist/executable.d.ts +3 -0
  106. package/dist/executable.d.ts.map +1 -0
  107. package/dist/executable.js +41 -0
  108. package/dist/executable.js.map +1 -0
  109. package/dist/exit-codes.d.ts +11 -0
  110. package/dist/exit-codes.d.ts.map +1 -0
  111. package/dist/exit-codes.js +25 -0
  112. package/dist/exit-codes.js.map +1 -0
  113. package/dist/http/index.d.ts +20 -0
  114. package/dist/http/index.d.ts.map +1 -0
  115. package/dist/http/index.js +46 -0
  116. package/dist/http/index.js.map +1 -0
  117. package/dist/index.d.ts +20 -0
  118. package/dist/index.d.ts.map +1 -0
  119. package/dist/index.js +19 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/keyring.d.ts +27 -0
  122. package/dist/keyring.d.ts.map +1 -0
  123. package/dist/keyring.js +45 -0
  124. package/dist/keyring.js.map +1 -0
  125. package/dist/legacy-paths.d.ts +33 -0
  126. package/dist/legacy-paths.d.ts.map +1 -0
  127. package/dist/legacy-paths.js +128 -0
  128. package/dist/legacy-paths.js.map +1 -0
  129. package/dist/logger.d.ts +12 -0
  130. package/dist/logger.d.ts.map +1 -0
  131. package/dist/logger.js +7 -0
  132. package/dist/logger.js.map +1 -0
  133. package/dist/logging.d.ts +31 -0
  134. package/dist/logging.d.ts.map +1 -0
  135. package/dist/logging.js +58 -0
  136. package/dist/logging.js.map +1 -0
  137. package/dist/mcp/index.d.ts +32 -0
  138. package/dist/mcp/index.d.ts.map +1 -0
  139. package/dist/mcp/index.js +113 -0
  140. package/dist/mcp/index.js.map +1 -0
  141. package/dist/output-buffer.d.ts +16 -0
  142. package/dist/output-buffer.d.ts.map +1 -0
  143. package/dist/output-buffer.js +69 -0
  144. package/dist/output-buffer.js.map +1 -0
  145. package/dist/paths.d.ts +35 -0
  146. package/dist/paths.d.ts.map +1 -0
  147. package/dist/paths.js +45 -0
  148. package/dist/paths.js.map +1 -0
  149. package/dist/pretty.d.ts +12 -0
  150. package/dist/pretty.d.ts.map +1 -0
  151. package/dist/pretty.js +83 -0
  152. package/dist/pretty.js.map +1 -0
  153. package/dist/release/index.d.ts +38 -0
  154. package/dist/release/index.d.ts.map +1 -0
  155. package/dist/release/index.js +91 -0
  156. package/dist/release/index.js.map +1 -0
  157. package/dist/release/markdown.d.ts +36 -0
  158. package/dist/release/markdown.d.ts.map +1 -0
  159. package/dist/release/markdown.js +153 -0
  160. package/dist/release/markdown.js.map +1 -0
  161. package/dist/release/structure.d.ts +16 -0
  162. package/dist/release/structure.d.ts.map +1 -0
  163. package/dist/release/structure.js +74 -0
  164. package/dist/release/structure.js.map +1 -0
  165. package/dist/renderer.d.ts +34 -0
  166. package/dist/renderer.d.ts.map +1 -0
  167. package/dist/renderer.js +55 -0
  168. package/dist/renderer.js.map +1 -0
  169. package/dist/result-fields.d.ts +4 -0
  170. package/dist/result-fields.d.ts.map +1 -0
  171. package/dist/result-fields.js +56 -0
  172. package/dist/result-fields.js.map +1 -0
  173. package/dist/retry.d.ts +27 -0
  174. package/dist/retry.d.ts.map +1 -0
  175. package/dist/retry.js +26 -0
  176. package/dist/retry.js.map +1 -0
  177. package/dist/sanitize.d.ts +25 -0
  178. package/dist/sanitize.d.ts.map +1 -0
  179. package/dist/sanitize.js +52 -0
  180. package/dist/sanitize.js.map +1 -0
  181. package/dist/skill/index.d.ts +78 -0
  182. package/dist/skill/index.d.ts.map +1 -0
  183. package/dist/skill/index.js +190 -0
  184. package/dist/skill/index.js.map +1 -0
  185. package/dist/streams.d.ts +24 -0
  186. package/dist/streams.d.ts.map +1 -0
  187. package/dist/streams.js +26 -0
  188. package/dist/streams.js.map +1 -0
  189. package/dist/testing/index.d.ts +24 -0
  190. package/dist/testing/index.d.ts.map +1 -0
  191. package/dist/testing/index.js +29 -0
  192. package/dist/testing/index.js.map +1 -0
  193. package/dist/time.d.ts +21 -0
  194. package/dist/time.d.ts.map +1 -0
  195. package/dist/time.js +19 -0
  196. package/dist/time.js.map +1 -0
  197. package/dist/update/index.d.ts +76 -0
  198. package/dist/update/index.d.ts.map +1 -0
  199. package/dist/update/index.js +160 -0
  200. package/dist/update/index.js.map +1 -0
  201. package/package.json +126 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,MAAM,OAAO;AACX,4FAA4F;AAC5F,kHAAkH,CAAA;AAEpH,MAAM,gBAAgB,GAAG,2FAA2F,CAAA;AAEpH,MAAM,WAAW,GAAG,qBAAqB,CAAA;AAEzC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE;IACpC,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAClC,IAAI,IAAI,GAAG,MAAM;QAAE,OAAO,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAA;IACrD,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAA;AAC9G,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE;IACtD,IAAI,EAAE,GAAG,CAAC,CAAA;IACV,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACxE,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAClC,CAAC;IACD,OAAO,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC1D,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA"}
@@ -0,0 +1,78 @@
1
+ import { Command } from "commander";
2
+ import type { Renderer } from "../renderer.js";
3
+ import type { Streams } from "../streams.js";
4
+ type Env = Readonly<Record<string, string | undefined>>;
5
+ export interface SkillApp {
6
+ /** `tg` — what an agent types. */
7
+ command: string;
8
+ /** `tg-cli` — the skill's directory name, and the `name` in its frontmatter. */
9
+ appName: string;
10
+ version: string;
11
+ }
12
+ export declare const SKILL_TARGETS: readonly ["claude", "agents"];
13
+ export type SkillTarget = (typeof SKILL_TARGETS)[number];
14
+ /** `~/.claude/skills` is Claude Code's; `~/.agents/skills` is read by Codex and Gemini CLI. */
15
+ export declare const skillPath: (target: SkillTarget, appName: string, env: Env) => string;
16
+ /**
17
+ * `metadata.version` from the frontmatter — where the Agent Skills specification keeps fields of its
18
+ * own — or a top-level `version:`, which pre-release builds of this package wrote.
19
+ */
20
+ export declare const skillVersion: (content: string) => string | undefined;
21
+ /** Adds or replaces `metadata.version` as a string; every other byte stays as it was. */
22
+ export declare const withVersion: (content: string, version: string) => string;
23
+ /** Writes the stamped SKILL.md to each target, creating directories; the same run twice gives the same files. */
24
+ export declare const installSkill: (app: SkillApp, skill: URL, { targets, env }?: {
25
+ targets?: readonly SkillTarget[];
26
+ env?: Env;
27
+ }) => string[];
28
+ /** What the command writes to and where home is, for this invocation — the host's own output resolution. */
29
+ export type SkillEnvironment = (command: Command) => {
30
+ renderer: Renderer;
31
+ streams: Streams;
32
+ env?: Env;
33
+ };
34
+ /**
35
+ * `more`: skills a library ships for every CLI built on it, by name — `skill show <name>` prints one with
36
+ * `{{command}}` turned into this CLI's command. They are printed, not installed: two CLIs would install
37
+ * the same name.
38
+ */
39
+ export declare const skillCommand: (app: SkillApp, skill: URL, environment: SkillEnvironment, more?: Readonly<Record<string, URL>>) => Command;
40
+ export interface SkillHintRequest {
41
+ app: SkillApp;
42
+ /** The words the CLI was run with: no hint while it runs `skill` or `complete`. */
43
+ argv: readonly string[];
44
+ env: Env;
45
+ /** The update notice's state file — one file for both daily notices. */
46
+ statePath: string;
47
+ /** The setting `skillHint`; `false` turns the hint off. */
48
+ enabled?: boolean;
49
+ now?: () => number;
50
+ }
51
+ /**
52
+ * One line for an agent whose copy of SKILL.md is missing or older than this CLI, at most once a
53
+ * day, or `undefined`. The host prints it on stderr. Any failure is silence.
54
+ */
55
+ export declare const skillHint: ({ app, argv, env, statePath, enabled, now }: SkillHintRequest) => string | undefined;
56
+ export interface SkillResource {
57
+ uri: string;
58
+ name: string;
59
+ title: string;
60
+ description: string;
61
+ mimeType: "text/markdown";
62
+ read: () => {
63
+ contents: {
64
+ uri: string;
65
+ mimeType: "text/markdown";
66
+ text: string;
67
+ }[];
68
+ };
69
+ /** A line for the server's `instructions`. */
70
+ instruction: string;
71
+ }
72
+ /**
73
+ * What an MCP server registers to serve SKILL.md as `<command>://skill`, for a client with no shell —
74
+ * `server.registerResource(r.name, r.uri, { title, description, mimeType }, r.read)`. The SDK stays the host's.
75
+ */
76
+ export declare const skillResource: (app: SkillApp, skill: URL) => SkillResource;
77
+ export {};
78
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skill/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAE3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAG5C,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;AAEvD,MAAM,WAAW,QAAQ;IACvB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,aAAa,YAAI,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAC1D,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAIxD,+FAA+F;AAC/F,eAAO,MAAM,SAAS,WAAY,WAAW,WAAW,MAAM,OAAO,GAAG,KAAG,MACoB,CAAA;AAoB/F;;;GAGG;AACH,eAAO,MAAM,YAAY,YAAa,MAAM,KAAG,MAAM,GAAG,SAMvD,CAAA;AAOD,yFAAyF;AACzF,eAAO,MAAM,WAAW,YAAa,MAAM,WAAW,MAAM,KAAG,MAoB9D,CAAA;AAED,iHAAiH;AACjH,eAAO,MAAM,YAAY,QAClB,QAAQ,SACN,GAAG,qBACsC;IAAE,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,KAC9F,MAAM,EAiBR,CAAA;AAED,4GAA4G;AAC5G,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,CAAA;AAExG;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAClB,QAAQ,SACN,GAAG,eACG,gBAAgB,SACvB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAClC,OAiDF,CAAA;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,QAAQ,CAAA;IACb,mFAAmF;IACnF,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,GAAG,EAAE,GAAG,CAAA;IACR,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAgBD;;;GAGG;AACH,eAAO,MAAM,SAAS,gDAAmE,gBAAgB,uBAaxG,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,eAAe,CAAA;IACzB,IAAI,EAAE,MAAM;QAAE,QAAQ,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,eAAe,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAA;IACpF,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAS,QAAQ,SAAS,GAAG,KAAG,aAWzD,CAAA"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * The CLI's own SKILL.md for coding agents: printing it, installing it where agents look for skills,
3
+ * telling an agent once a day that its copy is missing or old, and serving it to an MCP client.
4
+ *
5
+ * Nothing here prints by itself. The command writes through the renderer and streams the host hands
6
+ * it, and the hint is a string the host puts on stderr — never stdout, which an agent parses.
7
+ */
8
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
+ import { homedir } from "node:os";
10
+ import { dirname, join } from "node:path";
11
+ import { Command, Option } from "commander";
12
+ import { CliError } from "../errors.js";
13
+ import { CHECK_EVERY_MS, isNewer, readNoticeState, writeUpdateState } from "../update/index.js";
14
+ export const SKILL_TARGETS = ["claude", "agents"];
15
+ const homeOf = (env) => env.HOME || env.USERPROFILE || homedir();
16
+ /** `~/.claude/skills` is Claude Code's; `~/.agents/skills` is read by Codex and Gemini CLI. */
17
+ export const skillPath = (target, appName, env) => join(homeOf(env), target === "claude" ? ".claude" : ".agents", "skills", appName, "SKILL.md");
18
+ const FRONTMATTER = /^---(\r?\n)([\s\S]*?\r?\n)?---(\r?\n|$)/;
19
+ const scalar = (key, indent) => new RegExp(`^${indent}${key}:[ \\t]*["']?([^"'\\r\\n]*?)["']?[ \\t]*\\r?\\n?$`);
20
+ const frontmatterLines = (content) => (FRONTMATTER.exec(content)?.[2] ?? "").split(/(?<=\n)/);
21
+ /** Where `metadata:` and its indented lines are, as `[start, end)`; a flow map (`metadata: {…}`) is refused. */
22
+ const metadataBlock = (lines) => {
23
+ const start = lines.findIndex((line) => /^metadata:/.test(line));
24
+ if (start === -1)
25
+ return undefined;
26
+ if (!/^metadata:[ \t]*\r?\n?$/.test(lines[start])) {
27
+ throw new CliError("configuration_error", "SKILL.md: write `metadata` as an indented block, not on one line");
28
+ }
29
+ let end = start + 1;
30
+ while (end < lines.length && /^[ \t]/.test(lines[end]))
31
+ end++;
32
+ return [start, end];
33
+ };
34
+ /**
35
+ * `metadata.version` from the frontmatter — where the Agent Skills specification keeps fields of its
36
+ * own — or a top-level `version:`, which pre-release builds of this package wrote.
37
+ */
38
+ export const skillVersion = (content) => {
39
+ const lines = frontmatterLines(content);
40
+ const block = metadataBlock(lines);
41
+ const nested = block && lines.slice(block[0] + 1, block[1]).find((line) => scalar("version", "[ \\t]+").test(line));
42
+ const line = nested ?? lines.find((line) => scalar("version", "").test(line));
43
+ return line === undefined ? undefined : scalar("version", "[ \\t]*").exec(line)?.[1];
44
+ };
45
+ const skillName = (content) => {
46
+ const line = frontmatterLines(content).find((line) => scalar("name", "").test(line));
47
+ return line === undefined ? undefined : scalar("name", "").exec(line)?.[1];
48
+ };
49
+ /** Adds or replaces `metadata.version` as a string; every other byte stays as it was. */
50
+ export const withVersion = (content, version) => {
51
+ const match = FRONTMATTER.exec(content);
52
+ if (!match)
53
+ return `---\nmetadata:\n version: "${version}"\n---\n${content}`;
54
+ const [whole, eol = "\n", body = "", close = ""] = match;
55
+ const lines = body.split(/(?<=\n)/).filter((line) => line !== "");
56
+ const block = metadataBlock(lines);
57
+ if (!block) {
58
+ lines.push(`metadata:${eol}`, ` version: "${version}"${eol}`);
59
+ }
60
+ else {
61
+ const [start, end] = block;
62
+ const indent = /^[ \t]+/.exec(lines[start + 1] ?? "")?.[0] ?? " ";
63
+ const at = lines.slice(start + 1, end).findIndex((line) => scalar("version", "[ \\t]+").test(line));
64
+ if (at === -1)
65
+ lines.splice(start + 1, 0, `${indent}version: "${version}"${eol}`);
66
+ else {
67
+ const old = lines[start + 1 + at];
68
+ const lineEol = /\r?\n$/.exec(old)?.[0] ?? "";
69
+ lines[start + 1 + at] = `${/^[ \t]+/.exec(old)?.[0]}version: "${version}"${lineEol}`;
70
+ }
71
+ }
72
+ return `---${eol}${lines.join("")}---${close}${content.slice(whole.length)}`;
73
+ };
74
+ /** Writes the stamped SKILL.md to each target, creating directories; the same run twice gives the same files. */
75
+ export const installSkill = (app, skill, { targets = SKILL_TARGETS, env = process.env } = {}) => {
76
+ const source = readFileSync(skill, "utf8");
77
+ // The specification requires it, and an agent that checks skips a skill whose name and directory differ.
78
+ const name = skillName(source);
79
+ if (name !== app.appName) {
80
+ throw new CliError("configuration_error", `SKILL.md is named ${name === undefined ? "nothing" : `"${name}"`}, but installs into a directory "${app.appName}"; the two must match`);
81
+ }
82
+ const content = withVersion(source, app.version);
83
+ return targets.map((target) => {
84
+ const path = skillPath(target, app.appName, env);
85
+ mkdirSync(dirname(path), { recursive: true });
86
+ writeFileSync(path, content);
87
+ return path;
88
+ });
89
+ };
90
+ /**
91
+ * `more`: skills a library ships for every CLI built on it, by name — `skill show <name>` prints one with
92
+ * `{{command}}` turned into this CLI's command. They are printed, not installed: two CLIs would install
93
+ * the same name.
94
+ */
95
+ export const skillCommand = (app, skill, environment, more = {}) => {
96
+ const command = new Command("skill").description("the instructions an agent is given for this tool");
97
+ const machine = (self) => {
98
+ const { json, jsonl } = self.optsWithGlobals();
99
+ return json === true || jsonl === true;
100
+ };
101
+ const named = Object.keys(more);
102
+ const show = command
103
+ .command("show")
104
+ .description(`print SKILL.md — \`${app.command} skill install\` puts it where Claude Code, Codex and Gemini CLI look for it`);
105
+ if (named.length > 0)
106
+ show.argument("[name]", `one of the skills shipped for a task: ${named.join(", ")}`);
107
+ show.action(function (given) {
108
+ // Without a declared argument Commander passes the options here, not a name.
109
+ const name = typeof given === "string" ? given : undefined;
110
+ const { renderer, streams } = environment(this);
111
+ const source = name === undefined ? skill : more[name];
112
+ if (!source) {
113
+ throw new CliError("validation_error", `no skill "${name}" — there are: ${named.join(", ")}`);
114
+ }
115
+ const content = name === undefined
116
+ ? readFileSync(source, "utf8").trimEnd()
117
+ : readFileSync(source, "utf8").trimEnd().replaceAll("{{command}}", app.command);
118
+ // The file itself even into a pipe: saving it is a redirect, and a redirect is where every
119
+ // other command switches to JSON. Asked for by name, it is JSON like the rest.
120
+ if (machine(this))
121
+ renderer.result({ name: name ?? app.appName, content });
122
+ else
123
+ streams.data(content);
124
+ });
125
+ command
126
+ .command("install")
127
+ .description(`write SKILL.md to ~/.claude/skills/${app.appName}/ (Claude Code) and ~/.agents/skills/${app.appName}/ (Codex, Gemini CLI)`)
128
+ .addOption(new Option("--for <agents>", "which agents to install for").choices(["claude", "agents", "all"]).default("all"))
129
+ .action(function ({ for: chosen }) {
130
+ const { renderer, env } = environment(this);
131
+ const targets = chosen === "all" ? SKILL_TARGETS : [chosen];
132
+ const written = installSkill(app, skill, { targets, ...(env ? { env } : {}) });
133
+ renderer.result({ name: app.appName, version: app.version, written });
134
+ renderer.success(`${app.appName} ${app.version} skill installed: ${written.join(", ")}`);
135
+ });
136
+ return command;
137
+ };
138
+ const isAgent = (env) => Boolean(env.AI_AGENT || env.CLAUDECODE);
139
+ const needsInstall = (app, env) => {
140
+ const installed = SKILL_TARGETS.flatMap((target) => {
141
+ try {
142
+ return [skillVersion(readFileSync(skillPath(target, app.appName, env), "utf8"))];
143
+ }
144
+ catch {
145
+ return [];
146
+ }
147
+ });
148
+ // A location never installed to is a choice (`--for claude`); only no copy at all, or an old one, is worth a line.
149
+ return installed.length === 0 || installed.some((version) => version === undefined || isNewer(app.version, version));
150
+ };
151
+ /**
152
+ * One line for an agent whose copy of SKILL.md is missing or older than this CLI, at most once a
153
+ * day, or `undefined`. The host prints it on stderr. Any failure is silence.
154
+ */
155
+ export const skillHint = ({ app, argv, env, statePath, enabled = true, now = Date.now }) => {
156
+ try {
157
+ if (!enabled || !isAgent(env))
158
+ return undefined;
159
+ if (argv.includes("skill") || argv.includes("complete"))
160
+ return undefined;
161
+ const at = now();
162
+ const shown = readNoticeState(statePath).skillHintAt;
163
+ if (shown !== undefined && at - shown < CHECK_EVERY_MS)
164
+ return undefined;
165
+ if (!needsInstall(app, env))
166
+ return undefined;
167
+ writeUpdateState(statePath, { skillHintAt: at });
168
+ return `agents: \`${app.command} skill install\` installs this tool's guide`;
169
+ }
170
+ catch {
171
+ return undefined;
172
+ }
173
+ };
174
+ /**
175
+ * What an MCP server registers to serve SKILL.md as `<command>://skill`, for a client with no shell —
176
+ * `server.registerResource(r.name, r.uri, { title, description, mimeType }, r.read)`. The SDK stays the host's.
177
+ */
178
+ export const skillResource = (app, skill) => {
179
+ const uri = `${app.command}://skill`;
180
+ return {
181
+ uri,
182
+ name: "skill",
183
+ title: `${app.appName} SKILL.md`,
184
+ description: `How to use ${app.command}: the guide an agent is given for this tool.`,
185
+ mimeType: "text/markdown",
186
+ read: () => ({ contents: [{ uri, mimeType: "text/markdown", text: readFileSync(skill, "utf8") }] }),
187
+ instruction: `- The full guide is the resource ${uri}; \`${app.command} skill install\` installs it as an agent skill.`,
188
+ };
189
+ };
190
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skill/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGvC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAY/F,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAG1D,MAAM,MAAM,GAAG,CAAC,GAAQ,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,WAAW,IAAI,OAAO,EAAE,CAAA;AAE7E,+FAA+F;AAC/F,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAmB,EAAE,OAAe,EAAE,GAAQ,EAAU,EAAE,CAClF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;AAE/F,MAAM,WAAW,GAAG,yCAAyC,CAAA;AAC7D,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,MAAc,EAAE,EAAE,CAC7C,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,GAAG,mDAAmD,CAAC,CAAA;AAEjF,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAY,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;AAE/G,gHAAgH;AAChH,MAAM,aAAa,GAAG,CAAC,KAAwB,EAAgC,EAAE;IAC/E,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAChE,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IAClC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAW,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,QAAQ,CAAC,qBAAqB,EAAE,kEAAkE,CAAC,CAAA;IAC/G,CAAC;IACD,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,CAAA;IACnB,OAAO,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,CAAC;QAAE,GAAG,EAAE,CAAA;IACvE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AACrB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAsB,EAAE;IAClE,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACnH,MAAM,IAAI,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7E,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACtF,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,OAAe,EAAsB,EAAE;IACxD,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACpF,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAC5E,CAAC,CAAA;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,OAAe,EAAU,EAAE;IACtE,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,+BAA+B,OAAO,WAAW,OAAO,EAAE,CAAA;IAC7E,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,KAAK,CAAA;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,EAAE,eAAe,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;IAChE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAA;QAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;QAClE,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACnG,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,MAAM,aAAa,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;aAC5E,CAAC;YACJ,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,CAAW,CAAA;YAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YAC7C,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,OAAO,IAAI,OAAO,EAAE,CAAA;QACtF,CAAC;IACH,CAAC;IACD,OAAO,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;AAC9E,CAAC,CAAA;AAED,iHAAiH;AACjH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAa,EACb,KAAU,EACV,EAAE,OAAO,GAAG,aAAa,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,GAAoD,EAAE,EAC1F,EAAE;IACZ,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC1C,yGAAyG;IACzG,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,QAAQ,CAChB,qBAAqB,EACrB,qBAAqB,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,oCAAoC,GAAG,CAAC,OAAO,uBAAuB,CACxI,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAChD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAChD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7C,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAKD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAa,EACb,KAAU,EACV,WAA6B,EAC7B,IAAI,GAAkC,EAAE,EAC/B,EAAE;IACX,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,kDAAkD,CAAC,CAAA;IACpG,MAAM,OAAO,GAAG,CAAC,IAAa,EAAE,EAAE;QAChC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,eAAe,EAAuC,CAAA;QACnF,OAAO,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,CAAA;IACxC,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CACV,sBAAsB,GAAG,CAAC,OAAO,8EAA8E,CAChH,CAAA;IACH,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,yCAAyC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC1G,IAAI,CAAC,MAAM,CAAC,UAAyB,KAAc;QACjD,6EAA6E;QAC7E,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;QAC1D,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,aAAa,IAAI,kBAAkB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/F,CAAC;QACD,MAAM,OAAO,GACX,IAAI,KAAK,SAAS;YAChB,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE;YACxC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QACnF,2FAA2F;QAC3F,+EAA+E;QAC/E,IAAI,OAAO,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;;YACrE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CACV,sCAAsC,GAAG,CAAC,OAAO,wCAAwC,GAAG,CAAC,OAAO,uBAAuB,CAC5H;SACA,SAAS,CACR,IAAI,MAAM,CAAC,gBAAgB,EAAE,6BAA6B,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAChH;SACA,MAAM,CAAC,UAAyB,EAAE,GAAG,EAAE,MAAM,EAAwC;QACpF,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QACrE,QAAQ,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,qBAAqB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC1F,CAAC,CAAC,CAAA;IAEJ,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAcD,MAAM,OAAO,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,CAAA;AAE9E,MAAM,YAAY,GAAG,CAAC,GAAa,EAAE,GAAQ,EAAW,EAAE;IACxD,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACjD,IAAI,CAAC;YACH,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;QAClF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC,CAAC,CAAA;IACF,mHAAmH;IACnH,OAAO,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;AACtH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAoB,EAAE,EAAE;IAC3G,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;QAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,SAAS,CAAA;QACzE,MAAM,EAAE,GAAG,GAAG,EAAE,CAAA;QAChB,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,WAAW,CAAA;QACpD,IAAI,KAAK,KAAK,SAAS,IAAI,EAAE,GAAG,KAAK,GAAG,cAAc;YAAE,OAAO,SAAS,CAAA;QACxE,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;QAC7C,gBAAgB,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAA;QAChD,OAAO,aAAa,GAAG,CAAC,OAAO,6CAA6C,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAaD;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAa,EAAE,KAAU,EAAiB,EAAE;IACxE,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,UAAU,CAAA;IACpC,OAAO;QACL,GAAG;QACH,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,GAAG,GAAG,CAAC,OAAO,WAAW;QAChC,WAAW,EAAE,cAAc,GAAG,CAAC,OAAO,8CAA8C;QACpF,QAAQ,EAAE,eAAe;QACzB,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACnG,WAAW,EAAE,oCAAoC,GAAG,OAAO,GAAG,CAAC,OAAO,iDAAiD;KACxH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The line every machine mode depends on: **stdout carries data, stderr carries everything
3
+ * else.** Two functions and no formatting decisions — the renderer that chooses tables, colour
4
+ * and spinners is `CLI-5` and sits on top of this, never beside it.
5
+ */
6
+ export interface Streams {
7
+ data: (text: string) => void;
8
+ diagnostic: (text: string) => void;
9
+ /**
10
+ * A line that replaces itself — a progress counter, and nothing else.
11
+ *
12
+ * It lives here rather than beside the renderer so that a test capturing streams captures this
13
+ * too: the invariant it could break is rule 3, and an output channel the machine-output test
14
+ * cannot see is exactly how that gets broken quietly. An empty string clears the line.
15
+ */
16
+ progress?: (text: string) => void;
17
+ }
18
+ export declare const processStreams: Streams;
19
+ /** Collects both halves separately, so a test can assert nothing leaked across. */
20
+ export declare const captureStreams: () => Streams & {
21
+ stdout: string[];
22
+ stderr: string[];
23
+ };
24
+ //# sourceMappingURL=streams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streams.d.ts","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED,eAAO,MAAM,cAAc,EAAE,OAY5B,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,cAAc,QAAO,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAW/E,CAAA"}
@@ -0,0 +1,26 @@
1
+ export const processStreams = {
2
+ data: (text) => {
3
+ process.stdout.write(`${text}\n`);
4
+ },
5
+ diagnostic: (text) => {
6
+ process.stderr.write(`${text}\n`);
7
+ },
8
+ progress: (text) => {
9
+ // Carriage return and no newline, so the next line overwrites this one. Padded to the width of
10
+ // what was there before, or the tail of a longer previous line is left on screen.
11
+ process.stderr.write(`\r${text.padEnd(72)}${text === "" ? "\r" : ""}`);
12
+ },
13
+ };
14
+ /** Collects both halves separately, so a test can assert nothing leaked across. */
15
+ export const captureStreams = () => {
16
+ const stdout = [];
17
+ const stderr = [];
18
+ return {
19
+ stdout,
20
+ stderr,
21
+ data: (text) => stdout.push(text),
22
+ diagnostic: (text) => stderr.push(text),
23
+ progress: (text) => stderr.push(text),
24
+ };
25
+ };
26
+ //# sourceMappingURL=streams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streams.js","sourceRoot":"","sources":["../src/streams.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,cAAc,GAAY;IACrC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;IACnC,CAAC;IACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAA;IACnC,CAAC;IACD,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QACjB,+FAA+F;QAC/F,kFAAkF;QAClF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACxE,CAAC;CACF,CAAA;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAqD,EAAE;IACnF,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,OAAO;QACL,MAAM;QACN,MAAM;QACN,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACjC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;KACtC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The seams a test needs, so that "no test touched the real machine" is a property of the code
3
+ * rather than a hope about every test remembering to opt out.
4
+ */
5
+ export { brokenKeyring, memoryKeyring } from "../keyring.js";
6
+ export { captureStreams } from "../streams.js";
7
+ import type { MonotonicClock, SleepLike, WallClock } from "../time.js";
8
+ export interface FakeClock {
9
+ clock: MonotonicClock;
10
+ now: WallClock;
11
+ sleep: SleepLike;
12
+ /** Every sleep asked for, in order, with the reason the caller gave. Nothing actually waits. */
13
+ waits: {
14
+ ms: number;
15
+ reason?: string;
16
+ }[];
17
+ advance(ms: number): void;
18
+ }
19
+ /**
20
+ * Time that never passes unless a test says so. A retry test that really sleeps 250 ms is a retry
21
+ * test nobody runs, so `sleep` resolves at once and records what it was asked for.
22
+ */
23
+ export declare const fakeClock: (startMs?: number) => FakeClock;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,cAAc,CAAA;IACrB,GAAG,EAAE,SAAS,CAAA;IACd,KAAK,EAAE,SAAS,CAAA;IAChB,gGAAgG;IAChG,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,wBAAkB,SAiBvC,CAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The seams a test needs, so that "no test touched the real machine" is a property of the code
3
+ * rather than a hope about every test remembering to opt out.
4
+ */
5
+ export { brokenKeyring, memoryKeyring } from "../keyring.js";
6
+ export { captureStreams } from "../streams.js";
7
+ /**
8
+ * Time that never passes unless a test says so. A retry test that really sleeps 250 ms is a retry
9
+ * test nobody runs, so `sleep` resolves at once and records what it was asked for.
10
+ */
11
+ export const fakeClock = (startMs = 0) => {
12
+ let elapsed = startMs;
13
+ const waits = [];
14
+ return {
15
+ waits,
16
+ clock: () => elapsed,
17
+ now: () => new Date(startMs + elapsed),
18
+ sleep: async (ms, signal, reason) => {
19
+ if (signal?.aborted)
20
+ throw new DOMException("The operation was aborted.", "AbortError");
21
+ waits.push(reason === undefined ? { ms } : { ms, reason });
22
+ elapsed += ms;
23
+ },
24
+ advance: (ms) => {
25
+ elapsed += ms;
26
+ },
27
+ };
28
+ };
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAa9C;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAO,GAAG,CAAC,EAAa,EAAE;IAClD,IAAI,OAAO,GAAG,OAAO,CAAA;IACrB,MAAM,KAAK,GAAsC,EAAE,CAAA;IAEnD,OAAO;QACL,KAAK;QACL,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO;QACpB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACtC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAClC,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,IAAI,YAAY,CAAC,4BAA4B,EAAE,YAAY,CAAC,CAAA;YACvF,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YAC1D,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
package/dist/time.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The two clocks and the one timer core needs. All three are injectable, which is what makes
3
+ * timeout and backoff testable without anything actually waiting.
4
+ */
5
+ /**
6
+ * Why the client is waiting. The real sleep ignores it; a test uses it to tell an attempt's
7
+ * deadline apart from a delay between attempts, which are the only two reasons core ever waits.
8
+ * Without it a test that records waits sees both and cannot assert on either.
9
+ */
10
+ export type SleepReason = "timeout" | "retry";
11
+ /** Rejects with an `AbortError` if the signal fires first, the way `fetch` does. */
12
+ export type SleepLike = (ms: number, signal?: AbortSignal, reason?: SleepReason) => Promise<void>;
13
+ /** Monotonic milliseconds. Durations come from here; a wall clock can step backwards. */
14
+ export type MonotonicClock = () => number;
15
+ /** Wall time. Timestamps that a person or another system will read come from here. */
16
+ export type WallClock = () => Date;
17
+ export declare const abortError: () => DOMException;
18
+ export declare const realSleep: SleepLike;
19
+ export declare const monotonic: MonotonicClock;
20
+ export declare const wallClock: WallClock;
21
+ //# sourceMappingURL=time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,CAAA;AAE7C,oFAAoF;AACpF,MAAM,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEjG,yFAAyF;AACzF,MAAM,MAAM,cAAc,GAAG,MAAM,MAAM,CAAA;AAEzC,sFAAsF;AACtF,MAAM,MAAM,SAAS,GAAG,MAAM,IAAI,CAAA;AAElC,eAAO,MAAM,UAAU,QAAO,YAA4E,CAAA;AAE1G,eAAO,MAAM,SAAS,EAAE,SAgBpB,CAAA;AAEJ,eAAO,MAAM,SAAS,EAAE,cAAwC,CAAA;AAEhE,eAAO,MAAM,SAAS,EAAE,SAA4B,CAAA"}
package/dist/time.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The two clocks and the one timer core needs. All three are injectable, which is what makes
3
+ * timeout and backoff testable without anything actually waiting.
4
+ */
5
+ export const abortError = () => new DOMException("The operation was aborted.", "AbortError");
6
+ export const realSleep = (ms, signal) => new Promise((resolve, reject) => {
7
+ if (signal?.aborted) {
8
+ reject(abortError());
9
+ return;
10
+ }
11
+ const timer = setTimeout(resolve, ms);
12
+ signal?.addEventListener("abort", () => {
13
+ clearTimeout(timer);
14
+ reject(abortError());
15
+ }, { once: true });
16
+ });
17
+ export const monotonic = () => performance.now();
18
+ export const wallClock = () => new Date();
19
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAiB,EAAE,CAAC,IAAI,YAAY,CAAC,4BAA4B,EAAE,YAAY,CAAC,CAAA;AAE1G,MAAM,CAAC,MAAM,SAAS,GAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CACjD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC9B,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;QACpB,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IACrC,MAAM,EAAE,gBAAgB,CACtB,OAAO,EACP,GAAG,EAAE;QACH,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IACtB,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAA;AACH,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,SAAS,GAAmB,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAA;AAEhE,MAAM,CAAC,MAAM,SAAS,GAAc,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAA"}
@@ -0,0 +1,76 @@
1
+ export { executableEnvironment, executableOnPath } from "../executable.js";
2
+ import * as v from "valibot";
3
+ import type { FetchLike } from "../http/index.js";
4
+ export type Installer = "pnpm" | "npm" | "bun" | "npx" | "checkout" | "unknown";
5
+ /**
6
+ * Read from where the running file really lives — `realpath` of the script, not `which`: the
7
+ * command on `PATH` is a shim or a link, and only its target says who installed it. Paths measured
8
+ * on 2026-09-24 by installing into throwaway prefixes.
9
+ */
10
+ export declare const installerOf: (scriptPath: string) => Installer;
11
+ /** The argv that updates a global install, or `undefined` where there is nothing to run. */
12
+ export declare const updateCommand: (installer: Installer, packageName: string) => string[] | undefined;
13
+ /** Plain `x.y.z` only: a pre-release is never offered, so it never counts as newer. */
14
+ export declare const isNewer: (candidate: string, current: string) => boolean;
15
+ /** The `latest` version on npm, or `undefined` on any failure — a hint may never fail a command. */
16
+ export declare const latestVersion: (packageName: string, fetch: FetchLike, { timeoutMs }?: {
17
+ timeoutMs?: number;
18
+ }) => Promise<string | undefined>;
19
+ export declare const CHECK_EVERY_MS: number;
20
+ export interface NotifyContext {
21
+ /** `pretty`, `json` or `jsonl` — the line exists only for the first. */
22
+ format: string;
23
+ stderrIsTTY: boolean;
24
+ quiet: boolean;
25
+ /** The setting; `false` turns the check off. */
26
+ enabled: boolean;
27
+ installer: Installer;
28
+ env: Readonly<Record<string, string | undefined>>;
29
+ /** Extra variables that turn it off, for the CLI's own prefix: `MAX_NO_UPDATE_CHECK`. */
30
+ offVariables?: readonly string[];
31
+ }
32
+ /** Whether a person is at a terminal who could be told — the only case a check is worth making. */
33
+ export declare const mayNotify: ({ format, stderrIsTTY, quiet, enabled, installer, env, offVariables, }: NotifyContext) => boolean;
34
+ declare const updateState: v.ObjectSchema<{
35
+ readonly checkedAt: v.NumberSchema<undefined>;
36
+ readonly latest: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
37
+ /** When the skill hint (`cli-base/skill`) was last shown — the other daily notice kept in this file. */
38
+ readonly skillHintAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
39
+ }, undefined>;
40
+ export type UpdateState = v.InferOutput<typeof updateState>;
41
+ /** The file as it is, `checkedAt: 0` when it is missing or unreadable. */
42
+ export declare const readNoticeState: (path: string) => UpdateState;
43
+ /** What the last check found. A missing or unreadable file is "never checked", not an error. */
44
+ export declare const readUpdateState: (path: string) => UpdateState | undefined;
45
+ /**
46
+ * Merged into the file as it is at the moment of writing: the update notice reads before it asks
47
+ * npm and writes after, and the skill hint may have written in between.
48
+ */
49
+ export declare const writeUpdateState: (path: string, state: Partial<UpdateState>) => void;
50
+ export declare const checkIsDue: (state: UpdateState | undefined, now: number) => boolean;
51
+ /** Resolve Windows shims from explicit PATH entries; cross-spawn quotes them through the trusted shell. */
52
+ export declare const spawnPlan: ([command, ...args]: readonly string[], platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv, exists?: (path: string) => boolean) => {
53
+ file: string;
54
+ args: string[];
55
+ shell: boolean;
56
+ };
57
+ /** Runs the update and answers its exit code. stdout stays one result: the package manager's output goes to stderr. */
58
+ export declare const runUpdate: (argv: readonly string[]) => number;
59
+ export interface NoticeRequest extends NotifyContext {
60
+ /** The words the CLI was run with, to leave `update` and `complete` alone. */
61
+ argv: readonly string[];
62
+ packageName: string;
63
+ /** The command a person types: `braze`, `max`. */
64
+ command: string;
65
+ version: string;
66
+ /** Where the last answer from npm is kept — the CLI's state directory. */
67
+ statePath: string;
68
+ fetch: FetchLike;
69
+ now?: () => number;
70
+ }
71
+ /**
72
+ * The daily "a newer version exists" line, or `undefined`. Meant to be started beside the command
73
+ * and awaited after it, so asking npm costs the command nothing; any failure is silence.
74
+ */
75
+ export declare const updateNotice: ({ argv, packageName, command, version, statePath, fetch, now, ...context }: NoticeRequest) => Promise<string | undefined>;
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/update/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE1E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAA;AAE/E;;;;GAIG;AACH,eAAO,MAAM,WAAW,eAAgB,MAAM,KAAG,SAOhD,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,aAAa,cAAe,SAAS,eAAe,MAAM,KAAG,MAAM,EAAE,GAAG,SAYpF,CAAA;AAED,uFAAuF;AACvF,eAAO,MAAM,OAAO,cAAe,MAAM,WAAW,MAAM,KAAG,OAS5D,CAAA;AAED,oGAAoG;AACpG,eAAO,MAAM,aAAa,gBACX,MAAM,SACZ,SAAS,kBACM;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAC3C,OAAO,CAAC,MAAM,GAAG,SAAS,CAY5B,CAAA;AAED,eAAO,MAAM,cAAc,QAAsB,CAAA;AAEjD,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,OAAO,CAAA;IACd,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,SAAS,CAAA;IACpB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;IACjD,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAED,mGAAmG;AACnG,eAAO,MAAM,SAAS,2EAQnB,aAAa,KAAG,OAQuB,CAAA;AAE1C,QAAA,MAAM,WAAW;;;IAGf,wGAAwG;;aAExG,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,WAAW,CAAC,CAAA;AAE3D,0EAA0E;AAC1E,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,WAM9C,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,WAAW,GAAG,SAG5D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,SAAU,MAAM,SAAS,OAAO,CAAC,WAAW,CAAC,KAAG,IAM5E,CAAA;AAED,eAAO,MAAM,UAAU,UAAW,WAAW,GAAG,SAAS,OAAO,MAAM,KAAG,OACT,CAAA;AAEhE,2GAA2G;AAC3G,eAAO,MAAM,SAAS,uBACA,SAAS,MAAM,EAAE,aAC3B,MAAM,CAAC,QAAQ,QACpB,MAAM,CAAC,UAAU,WACd,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO;;;;CAC4D,CAAA;AAE/F,uHAAuH;AACvH,eAAO,MAAM,SAAS,SAAU,SAAS,MAAM,EAAE,KAAG,MASnD,CAAA;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,8EAA8E;IAC9E,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,+EAStB,aAAa,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAsB5C,CAAA"}