@duyquangnvx/agent-cli 0.16.0 → 0.18.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 (252) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +2 -2
  3. package/agents-section.md +5 -0
  4. package/dist/agent-cli.d.ts +69 -11
  5. package/dist/agent-cli.js +69 -10
  6. package/dist/agent-cli.js.map +1 -1
  7. package/dist/built-ins/agents-md.d.ts +9 -9
  8. package/dist/built-ins/agents-md.js +8 -8
  9. package/dist/built-ins/agents-md.js.map +1 -1
  10. package/dist/built-ins/doctor-rows.js +5 -3
  11. package/dist/built-ins/doctor-rows.js.map +1 -1
  12. package/dist/built-ins/doctor.d.ts +1 -1
  13. package/dist/built-ins/doctor.js +16 -15
  14. package/dist/built-ins/doctor.js.map +1 -1
  15. package/dist/built-ins/install/dependency.js +1 -1
  16. package/dist/built-ins/install/dependency.js.map +1 -1
  17. package/dist/built-ins/install/global-npm.js +6 -4
  18. package/dist/built-ins/install/global-npm.js.map +1 -1
  19. package/dist/built-ins/npm.d.ts +3 -2
  20. package/dist/built-ins/npm.js +16 -9
  21. package/dist/built-ins/npm.js.map +1 -1
  22. package/dist/{project-root.js → built-ins/project-root.js} +1 -1
  23. package/dist/built-ins/project-root.js.map +1 -0
  24. package/dist/built-ins/skill/hub.d.ts +3 -2
  25. package/dist/built-ins/skill/hub.js +43 -16
  26. package/dist/built-ins/skill/hub.js.map +1 -1
  27. package/dist/built-ins/skill/install-command.d.ts +3 -4
  28. package/dist/built-ins/skill/install-command.js +20 -21
  29. package/dist/built-ins/skill/install-command.js.map +1 -1
  30. package/dist/built-ins/skill/packaged.js +5 -2
  31. package/dist/built-ins/skill/packaged.js.map +1 -1
  32. package/dist/built-ins/skill/skill.d.ts +5 -2
  33. package/dist/built-ins/skill/skill.js +1 -1
  34. package/dist/built-ins/skill/skill.js.map +1 -1
  35. package/dist/built-ins/update.d.ts +1 -1
  36. package/dist/built-ins/update.js +4 -9
  37. package/dist/built-ins/update.js.map +1 -1
  38. package/dist/check-examples.d.ts +6 -0
  39. package/dist/check-examples.js +53 -0
  40. package/dist/check-examples.js.map +1 -0
  41. package/dist/check-next-steps.d.ts +10 -0
  42. package/dist/check-next-steps.js +47 -0
  43. package/dist/check-next-steps.js.map +1 -0
  44. package/dist/command-errors.d.ts +8 -0
  45. package/dist/command-errors.js +25 -0
  46. package/dist/command-errors.js.map +1 -0
  47. package/dist/{flags.d.ts → command-line/flags.d.ts} +7 -4
  48. package/dist/{flags.js → command-line/flags.js} +8 -10
  49. package/dist/command-line/flags.js.map +1 -0
  50. package/dist/{input.d.ts → command-line/input.d.ts} +1 -1
  51. package/dist/{input.js → command-line/input.js} +1 -1
  52. package/dist/command-line/input.js.map +1 -0
  53. package/dist/{invocation.d.ts → command-line/invocation.d.ts} +6 -3
  54. package/dist/{invocation.js → command-line/invocation.js} +9 -5
  55. package/dist/command-line/invocation.js.map +1 -0
  56. package/dist/{parse-input.d.ts → command-line/parse-input.d.ts} +2 -2
  57. package/dist/{parse-input.js → command-line/parse-input.js} +3 -3
  58. package/dist/command-line/parse-input.js.map +1 -0
  59. package/dist/command-line/route-line.d.ts +15 -0
  60. package/dist/command-line/route-line.js +18 -0
  61. package/dist/command-line/route-line.js.map +1 -0
  62. package/dist/{route.d.ts → command-line/route.d.ts} +2 -2
  63. package/dist/{route.js → command-line/route.js} +1 -1
  64. package/dist/command-line/route.js.map +1 -0
  65. package/dist/command-line/shell-words.d.ts +12 -0
  66. package/dist/command-line/shell-words.js +83 -0
  67. package/dist/command-line/shell-words.js.map +1 -0
  68. package/dist/command-line/suggest.js.map +1 -0
  69. package/dist/command-line/tokenize.js.map +1 -0
  70. package/dist/{usage.d.ts → command-line/usage.d.ts} +1 -1
  71. package/dist/{usage.js → command-line/usage.js} +2 -2
  72. package/dist/command-line/usage.js.map +1 -0
  73. package/dist/command-spec.d.ts +13 -4
  74. package/dist/command-spec.js +22 -11
  75. package/dist/command-spec.js.map +1 -1
  76. package/dist/{agent.d.ts → context/agent.d.ts} +1 -1
  77. package/dist/context/agent.js.map +1 -0
  78. package/dist/{confirm.d.ts → context/confirm.d.ts} +3 -3
  79. package/dist/{confirm.js → context/confirm.js} +9 -11
  80. package/dist/context/confirm.js.map +1 -0
  81. package/dist/{cost.d.ts → context/cost.d.ts} +3 -3
  82. package/dist/context/cost.js +16 -0
  83. package/dist/context/cost.js.map +1 -0
  84. package/dist/context/declared.d.ts +8 -0
  85. package/dist/context/declared.js +10 -0
  86. package/dist/context/declared.js.map +1 -0
  87. package/dist/{errno.d.ts → context/errno.d.ts} +4 -3
  88. package/dist/{errno.js → context/errno.js} +14 -7
  89. package/dist/context/errno.js.map +1 -0
  90. package/dist/{files.js → context/files.js} +1 -1
  91. package/dist/context/files.js.map +1 -0
  92. package/dist/{interrupts.d.ts → context/interrupts.d.ts} +14 -10
  93. package/dist/{interrupts.js → context/interrupts.js} +30 -27
  94. package/dist/context/interrupts.js.map +1 -0
  95. package/dist/{operator.d.ts → context/operator.d.ts} +4 -3
  96. package/dist/{operator.js → context/operator.js} +4 -3
  97. package/dist/context/operator.js.map +1 -0
  98. package/dist/{outputs.d.ts → context/outputs.d.ts} +6 -5
  99. package/dist/{outputs.js → context/outputs.js} +10 -9
  100. package/dist/context/outputs.js.map +1 -0
  101. package/dist/{project.d.ts → context/project.d.ts} +4 -3
  102. package/dist/{project.js → context/project.js} +8 -7
  103. package/dist/context/project.js.map +1 -0
  104. package/dist/{secrets.d.ts → context/secrets.d.ts} +8 -1
  105. package/dist/context/secrets.js +85 -0
  106. package/dist/context/secrets.js.map +1 -0
  107. package/dist/{side-task.d.ts → context/side-task.d.ts} +2 -2
  108. package/dist/{side-task.js → context/side-task.js} +1 -1
  109. package/dist/context/side-task.js.map +1 -0
  110. package/dist/{spawn.d.ts → context/spawn.d.ts} +4 -3
  111. package/dist/{spawn.js → context/spawn.js} +7 -6
  112. package/dist/context/spawn.js.map +1 -0
  113. package/dist/{spill.d.ts → context/spill.d.ts} +4 -3
  114. package/dist/{spill.js → context/spill.js} +4 -4
  115. package/dist/context/spill.js.map +1 -0
  116. package/dist/{stdin.d.ts → context/stdin.d.ts} +2 -2
  117. package/dist/{stdin.js → context/stdin.js} +2 -2
  118. package/dist/context/stdin.js.map +1 -0
  119. package/dist/{tools.d.ts → context/tools.d.ts} +4 -3
  120. package/dist/{tools.js → context/tools.js} +8 -10
  121. package/dist/context/tools.js.map +1 -0
  122. package/dist/context.d.ts +51 -27
  123. package/dist/define-command.d.ts +47 -0
  124. package/dist/define-command.js +25 -0
  125. package/dist/define-command.js.map +1 -0
  126. package/dist/define.d.ts +81 -61
  127. package/dist/define.js +0 -14
  128. package/dist/define.js.map +1 -1
  129. package/dist/error-table.d.ts +9 -6
  130. package/dist/error-table.js +6 -6
  131. package/dist/error-table.js.map +1 -1
  132. package/dist/errors.d.ts +15 -1
  133. package/dist/errors.js +24 -6
  134. package/dist/errors.js.map +1 -1
  135. package/dist/execute.d.ts +8 -7
  136. package/dist/execute.js +52 -23
  137. package/dist/execute.js.map +1 -1
  138. package/dist/exit-classes.d.ts +1 -2
  139. package/dist/exit-classes.js +41 -48
  140. package/dist/exit-classes.js.map +1 -1
  141. package/dist/help-json.d.ts +4 -3
  142. package/dist/help-json.js +33 -11
  143. package/dist/help-json.js.map +1 -1
  144. package/dist/help.js +1 -0
  145. package/dist/help.js.map +1 -1
  146. package/dist/index.d.ts +19 -26
  147. package/dist/index.js +6 -18
  148. package/dist/index.js.map +1 -1
  149. package/dist/list.d.ts +6 -5
  150. package/dist/list.js +17 -11
  151. package/dist/list.js.map +1 -1
  152. package/dist/next-step.d.ts +23 -0
  153. package/dist/next-step.js +20 -0
  154. package/dist/next-step.js.map +1 -0
  155. package/dist/output.d.ts +11 -5
  156. package/dist/output.js +25 -11
  157. package/dist/output.js.map +1 -1
  158. package/dist/root-spec.d.ts +5 -0
  159. package/dist/root-spec.js +15 -0
  160. package/dist/root-spec.js.map +1 -0
  161. package/dist/run-cli.d.ts +2 -2
  162. package/dist/run-cli.js +12 -11
  163. package/dist/run-cli.js.map +1 -1
  164. package/dist/run-command.d.ts +4 -4
  165. package/dist/run-command.js +66 -37
  166. package/dist/run-command.js.map +1 -1
  167. package/dist/run-options.d.ts +11 -4
  168. package/dist/run-process.js +22 -7
  169. package/dist/run-process.js.map +1 -1
  170. package/dist/runtime-codes.d.ts +33 -0
  171. package/dist/runtime-codes.js +50 -0
  172. package/dist/runtime-codes.js.map +1 -0
  173. package/dist/style.js +1 -1
  174. package/dist/style.js.map +1 -1
  175. package/dist/testing.d.ts +27 -0
  176. package/dist/testing.js +66 -0
  177. package/dist/testing.js.map +1 -0
  178. package/dist/version.d.ts +4 -1
  179. package/dist/version.js +6 -1
  180. package/dist/version.js.map +1 -1
  181. package/docs/README.md +51 -0
  182. package/docs/example/archive.test.ts +280 -0
  183. package/docs/example/archive.ts +160 -0
  184. package/docs/example/bin.test.ts +118 -0
  185. package/docs/example/bin.ts +5 -0
  186. package/docs/example/bundle.test.ts +57 -0
  187. package/docs/example/bundle.ts +57 -0
  188. package/docs/example/cli.test.ts +428 -0
  189. package/docs/example/cli.ts +191 -0
  190. package/docs/example/commit.test.ts +78 -0
  191. package/docs/example/commit.ts +26 -0
  192. package/docs/example/define.ts +16 -0
  193. package/docs/example/errors.ts +17 -0
  194. package/docs/example/export.test.ts +64 -0
  195. package/docs/example/export.ts +32 -0
  196. package/docs/example/fake-ports.ts +14 -0
  197. package/docs/example/folder.ts +48 -0
  198. package/docs/example/import.test.ts +53 -0
  199. package/docs/example/import.ts +50 -0
  200. package/docs/example/package.json +21 -0
  201. package/docs/example/ports.ts +105 -0
  202. package/docs/example/serve.test.ts +49 -0
  203. package/docs/example/serve.ts +40 -0
  204. package/docs/example/store.ts +62 -0
  205. package/docs/example/tsdown.config.ts +33 -0
  206. package/docs/getting-started.md +19 -0
  207. package/docs/guides/commands.md +35 -0
  208. package/docs/guides/doctor.md +52 -0
  209. package/docs/guides/effects-and-plans.md +44 -0
  210. package/docs/guides/errors.md +57 -0
  211. package/docs/guides/lists.md +18 -0
  212. package/docs/guides/local-state.md +28 -0
  213. package/docs/guides/long-runs.md +109 -0
  214. package/docs/guides/remote-services.md +124 -0
  215. package/docs/guides/shipping.md +61 -0
  216. package/docs/guides/testing.md +69 -0
  217. package/docs/principles.md +39 -0
  218. package/docs/reference.md +25 -0
  219. package/package.json +12 -1
  220. package/dist/agent.js.map +0 -1
  221. package/dist/confirm.js.map +0 -1
  222. package/dist/cost.js +0 -16
  223. package/dist/cost.js.map +0 -1
  224. package/dist/errno.js.map +0 -1
  225. package/dist/files.js.map +0 -1
  226. package/dist/flags.js.map +0 -1
  227. package/dist/input.js.map +0 -1
  228. package/dist/interrupts.js.map +0 -1
  229. package/dist/invocation.js.map +0 -1
  230. package/dist/operator.js.map +0 -1
  231. package/dist/outputs.js.map +0 -1
  232. package/dist/parse-input.js.map +0 -1
  233. package/dist/project-root.js.map +0 -1
  234. package/dist/project.js.map +0 -1
  235. package/dist/route.js.map +0 -1
  236. package/dist/secrets.js +0 -31
  237. package/dist/secrets.js.map +0 -1
  238. package/dist/side-task.js.map +0 -1
  239. package/dist/spawn.js.map +0 -1
  240. package/dist/spill.js.map +0 -1
  241. package/dist/stdin.js.map +0 -1
  242. package/dist/suggest.js.map +0 -1
  243. package/dist/tokenize.js.map +0 -1
  244. package/dist/tools.js.map +0 -1
  245. package/dist/usage.js.map +0 -1
  246. /package/dist/{project-root.d.ts → built-ins/project-root.d.ts} +0 -0
  247. /package/dist/{suggest.d.ts → command-line/suggest.d.ts} +0 -0
  248. /package/dist/{suggest.js → command-line/suggest.js} +0 -0
  249. /package/dist/{tokenize.d.ts → command-line/tokenize.d.ts} +0 -0
  250. /package/dist/{tokenize.js → command-line/tokenize.js} +0 -0
  251. /package/dist/{agent.js → context/agent.js} +0 -0
  252. /package/dist/{files.d.ts → context/files.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin.js","sourceRoot":"","sources":["../../src/context/stdin.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
- import type { Env } from "./context.js";
2
- import { type Commands, type DoctorCheck, type Tool } from "./define.js";
1
+ import type { Env } from "../context.js";
2
+ import type { Commands, DoctorCheck, Tool } from "../define.js";
3
+ import { type Rerun } from "../next-step.js";
3
4
  export declare const TOOL_MISSING = "TOOL_MISSING";
4
5
  /** Where `name` is found on `PATH` from `env`, or undefined. */
5
6
  export declare function findTool(name: string, env: Env): Promise<string | undefined>;
6
7
  /** Fails with `TOOL_MISSING`, naming every missing tool at once, unless all are on `PATH`. */
7
- export declare function checkTools(tools: readonly Tool[], env: Env, callerLine: string): Promise<void>;
8
+ export declare function checkTools(tools: readonly Tool[], env: Env, rerun: Rerun): Promise<void>;
8
9
  /** One `doctor` row per distinct tool the CLI and its Commands declare, with its install command as the fix. */
9
10
  export declare function toolRows(tools: readonly Tool[], commands: Commands): DoctorCheck[];
@@ -1,8 +1,9 @@
1
1
  import { constants } from "node:fs";
2
2
  import { access } from "node:fs/promises";
3
3
  import { delimiter, extname, join } from "node:path";
4
- import { isCommand } from "./define.js";
5
- import { CliError, errnoOf, isNothingThere } from "./errors.js";
4
+ import { errnoOf, isNothingThere, runtimeError } from "../errors.js";
5
+ import { wholeLine } from "../next-step.js";
6
+ import { declaredIn } from "./declared.js";
6
7
  export const TOOL_MISSING = "TOOL_MISSING";
7
8
  const WINDOWS_EXTENSIONS = ".COM;.EXE;.BAT;.CMD";
8
9
  function pathOf(env) {
@@ -45,25 +46,22 @@ export async function findTool(name, env) {
45
46
  return undefined;
46
47
  }
47
48
  /** Fails with `TOOL_MISSING`, naming every missing tool at once, unless all are on `PATH`. */
48
- export async function checkTools(tools, env, callerLine) {
49
+ export async function checkTools(tools, env, rerun) {
49
50
  const found = await Promise.all(tools.map((tool) => findTool(tool.name, env)));
50
51
  const missing = tools.filter((_tool, index) => found[index] === undefined);
51
52
  if (missing.length === 0)
52
53
  return;
53
54
  const names = missing.map(({ name }) => name).join(", ");
54
- throw new CliError({
55
+ throw runtimeError({
55
56
  code: TOOL_MISSING,
56
57
  message: `${missing.length === 1 ? "a tool it runs is" : "tools it runs are"} not on PATH: ${names}`,
57
- hint: `install ${missing.map(({ name, install }) => `${name} (\`${install}\`)`).join(", ")}, then run \`${callerLine}\` again`,
58
+ hint: "run the Next steps in order: each install, then the command again",
59
+ next: [...missing.map(({ install }) => wholeLine(install)), rerun],
58
60
  });
59
61
  }
60
- function toolsIn(node) {
61
- return isCommand(node) ? [...(node.tools ?? [])] : Object.values(node).flatMap(toolsIn);
62
- }
63
62
  /** One `doctor` row per distinct tool the CLI and its Commands declare, with its install command as the fix. */
64
63
  export function toolRows(tools, commands) {
65
- const byName = new Map([...tools, ...toolsIn(commands)].map((tool) => [tool.name, tool]));
66
- return [...byName.values()].map(({ name, install }) => ({
64
+ return declaredIn(tools, commands, (command) => command.tools).map(({ name, install }) => ({
67
65
  name,
68
66
  run: async (ctx) => {
69
67
  const file = await findTool(name, ctx.env);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/context/tools.ts"],"names":[],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -1,10 +1,14 @@
1
1
  import type * as z from "zod";
2
2
  import type { Clock } from "./clock.js";
3
- import type { FileAccess } from "./errno.js";
4
- import type { Files } from "./files.js";
5
- import type { CommandLineChange } from "./invocation.js";
6
- import type { Secret } from "./secrets.js";
7
- import type { ContextSpawn, ContextSpawnDetached } from "./spawn.js";
3
+ import type { CommandLineChange } from "./command-line/invocation.js";
4
+ import type { FileAccess } from "./context/errno.js";
5
+ import type { Files } from "./context/files.js";
6
+ import type { DeadlineOptions } from "./context/interrupts.js";
7
+ import type { Secret } from "./context/secrets.js";
8
+ import type { ContextSpawn, ContextSpawnDetached } from "./context/spawn.js";
9
+ import type { CliErrorInit, ErrorTable, NoErrors } from "./error-table.js";
10
+ import type { CliError } from "./errors.js";
11
+ import type { Rerun } from "./next-step.js";
8
12
  export type Env = Readonly<Record<string, string | undefined>>;
9
13
  export interface PollOptions {
10
14
  readonly intervalMs: number;
@@ -17,7 +21,18 @@ export interface BuildStamp {
17
21
  readonly dirty: boolean;
18
22
  readonly builtAt: string;
19
23
  }
20
- export interface Context<Ports = unknown, Settings = unknown> {
24
+ /**
25
+ * What a Command declares it needs, which types its `ctx`: `secretName`, the names of its `secrets`,
26
+ * and `errors`, the part of the Error table its `errors` names.
27
+ */
28
+ export interface Needs<SecretName extends string = string, Errors extends ErrorTable = ErrorTable> {
29
+ readonly secretName: SecretName;
30
+ readonly errors: Errors;
31
+ }
32
+ /** The Needs of a Command that declares no Secrets and no errors. */
33
+ export type NoNeeds = Needs<never, NoErrors>;
34
+ /** `Declared` is what the Command declares it needs, so `secret` and `fail` take only those. */
35
+ export interface Context<Ports = unknown, Settings = unknown, Declared extends Needs = NoNeeds> {
21
36
  readonly cwd: string;
22
37
  readonly env: Env;
23
38
  /** The CLI's version, as `--version` prints it. */
@@ -56,15 +71,11 @@ export interface Context<Ports = unknown, Settings = unknown> {
56
71
  * Returns a signal that aborts with `ctx.signal`, and with `DEADLINE_EXCEEDED` (exit 75) once
57
72
  * `ms` have passed. The run reports that deadline for each error, or leaf of an `AggregateError`,
58
73
  * that is not a `CliError` and whose `cause` chain holds its abort; any other error is reported
59
- * as it is, so a `CliError` keeping the abort as `cause` keeps its own code.
74
+ * as it is, so a `CliError` keeping the abort as `cause` keeps its own code. With `ignoreStop`,
75
+ * it follows neither `ctx.signal` nor the run deadline: it bounds a call inside `runToEnd` that
76
+ * Ctrl-C must not cut short, and its hint warns the call may have been billed.
60
77
  */
61
- deadline(ms: number): AbortSignal;
62
- /**
63
- * Returns a signal that aborts with `DEADLINE_EXCEEDED` (exit 75) once `ms` have passed, and
64
- * follows neither `ctx.signal` nor the run deadline: it bounds a call inside `runToEnd` that
65
- * Ctrl-C must not cut short. Its abort is reported as `ctx.deadline`'s is.
66
- */
67
- timeout(ms: number): AbortSignal;
78
+ deadline(ms: number, options?: DeadlineOptions): AbortSignal;
68
79
  /**
69
80
  * Runs a step that must not stop halfway: the run waits for it even when stopped, and then
70
81
  * prints `finishing <name>` on stderr.
@@ -76,13 +87,13 @@ export interface Context<Ports = unknown, Settings = unknown> {
76
87
  * returned value replaces it. Delivered data spills like returned data.
77
88
  */
78
89
  deliver(data: unknown): void;
79
- /** The outside systems the CLI declared with `agentCli<Ports>()`. */
90
+ /** The outside systems the CLI declared with `agentCli({ ports })`. */
80
91
  readonly ports: Ports;
81
92
  /**
82
93
  * Reads, lists, removes and atomically writes files and folders, paths resolved against `cwd`. A
83
94
  * failure fails the run naming the path: `PERMISSION_DENIED` (exit 2, with a hint on allowing the
84
95
  * path in a Coding agent's sandbox), `DISK_FULL` (exit 2), `NOT_FOUND`, `NOT_A_FILE` or
85
- * `ALREADY_EXISTS` (exit 1); the codes are exported.
96
+ * `ALREADY_EXISTS` (exit 1); the codes are on `runtimeCodes`.
86
97
  */
87
98
  readonly files: Files;
88
99
  /**
@@ -111,10 +122,16 @@ export interface Context<Ports = unknown, Settings = unknown> {
111
122
  */
112
123
  readonly project: Project<Settings> | undefined;
113
124
  /**
114
- * Reads `name` from the env, then from `$XDG_CONFIG_HOME/<cli>/.env` (default `~/.config`), with
115
- * where it came from; a `.env` it cannot read fails the run with `PERMISSION_DENIED`.
125
+ * One of the Command's declared `secrets`, with where it came from: the env, then
126
+ * `$XDG_CONFIG_HOME/<cli>/.env` (default `~/.config`). The Runtime checked each before the
127
+ * Command started, so it is always set.
116
128
  */
117
- secret(name: string): Secret | undefined;
129
+ secret(name: Declared["secretName"]): Secret;
130
+ /**
131
+ * The `CliError` for one of the Command's declared `errors`, as `cliError` builds it, for the
132
+ * Command to throw: `details` must match the code's schema.
133
+ */
134
+ fail<Code extends keyof Declared["errors"] & string>(code: Code, init: CliErrorInit<Declared["errors"][Code]>, options?: ErrorOptions): CliError;
118
135
  /**
119
136
  * The `.env` that `secret` reads: `$XDG_CONFIG_HOME/<cli>/.env`, or `~/.config/<cli>/.env`
120
137
  * without it. Name it in a hint that asks for a missing key.
@@ -128,16 +145,15 @@ export interface Context<Ports = unknown, Settings = unknown> {
128
145
  /** Whether the caller passed `--force`; always false for a Command without it. */
129
146
  readonly force: boolean;
130
147
  /**
131
- * The command line as the caller typed it, starting with the CLI's name and shell-quoted, with
132
- * each flag in `remove` dropped along with its value (`--from 3` and `--from=3`, every time it was
133
- * given) and the words in `add` placed before any `--`. When an `orStdin` arg was given `-`, the
134
- * line ends in `< <name file>`, since the shell kept what it fed in. Build every hint that names a
135
- * command to run with it.
148
+ * The caller's own line as a Next step, with each flag in `remove` dropped along with its value
149
+ * (`--from 3` and `--from=3`, every time it was given) and the words in `add` placed before any
150
+ * `--`. When an `orStdin` arg was given `-`, the line ends in `< <name file>`, since the shell
151
+ * kept what it fed in.
136
152
  */
137
- commandLine(change?: CommandLineChange): string;
153
+ rerun(change?: CommandLineChange): Rerun;
138
154
  }
139
155
  /** A serve Command's `Context`, whose run it may end itself. */
140
- export interface ServeContext<Ports = unknown, Settings = unknown> extends Context<Ports, Settings> {
156
+ export interface ServeContext<Ports = unknown, Settings = unknown, Declared extends Needs = NoNeeds> extends Context<Ports, Settings, Declared> {
141
157
  /**
142
158
  * Ends the run with exit 0, printing nothing more, as a stop does; for a Daemon that a newer one
143
159
  * replaces. Stop the work before calling it: `ctx.signal` does not abort.
@@ -148,7 +164,14 @@ export interface ServeContext<Ports = unknown, Settings = unknown> extends Conte
148
164
  * The slice of `Context` the ports factory receives, which exists before the ports do; a test that
149
165
  * keeps the real factory gives it the test's env and fakes.
150
166
  */
151
- export type PortsBase = Pick<Context, "env" | "cwd" | "packageRoot" | "secret" | "envFile" | "spawn" | "spawnDetached" | "files" | "clock" | "signal" | "progress" | "version" | "build" | "self" | "fileError">;
167
+ export interface PortsBase extends PortsBaseOfContext {
168
+ /**
169
+ * Reads `name` as `ctx.secret` does, or `undefined` when it is unset: the factory serves every
170
+ * Command, whatever Secrets it declares. A `.env` it cannot read fails with `PERMISSION_DENIED`.
171
+ */
172
+ secret(name: string): Secret | undefined;
173
+ }
174
+ type PortsBaseOfContext = Pick<Context, "env" | "cwd" | "packageRoot" | "envFile" | "spawn" | "spawnDetached" | "files" | "clock" | "signal" | "progress" | "version" | "build" | "self" | "fileError">;
152
175
  export interface Project<Settings = unknown> {
153
176
  /** The folder holding the Project file. */
154
177
  readonly root: string;
@@ -159,3 +182,4 @@ export interface ProjectFile<Settings = unknown> {
159
182
  readonly file: string;
160
183
  readonly schema: z.ZodType<Settings>;
161
184
  }
185
+ export {};
@@ -0,0 +1,47 @@
1
+ import type * as z from "zod";
2
+ import { type StandardFlagName } from "./command-line/flags.js";
3
+ import type { Needs } from "./context.js";
4
+ import type { ActCommand, Command, DestructiveCommand, InputSchema, ListCommand, NoInput, ReadCommand, ServeCommand, WriteCommand } from "./define.js";
5
+ import type { ErrorTable, NoErrors } from "./error-table.js";
6
+ import type { RowSchema } from "./list.js";
7
+ type Kebab<Key extends string> = Key extends `${infer Head}${infer Tail}` ? `${Head extends Lowercase<Head> ? Head : `-${Lowercase<Head>}`}${Kebab<Tail>}` : Key;
8
+ type Taken<Schema extends InputSchema> = Extract<Kebab<Extract<keyof Schema["shape"], string>>, StandardFlagName>;
9
+ type Unreserved<Schema extends InputSchema> = [Taken<Schema>] extends [never] ? unknown : {
10
+ readonly standardFlagDeclared: Taken<Schema>;
11
+ };
12
+ interface WithoutStandardFlags<Args extends InputSchema, Options extends InputSchema> {
13
+ readonly args?: Unreserved<Args>;
14
+ readonly options?: Unreserved<Options>;
15
+ }
16
+ type Returns<Schema extends z.ZodType> = z.input<Schema>;
17
+ type Prints<Schema extends z.ZodType> = z.output<Schema>;
18
+ interface WithOutput<Schema extends z.ZodType> {
19
+ readonly output: Schema;
20
+ }
21
+ interface WithoutOutput {
22
+ readonly output?: undefined;
23
+ }
24
+ type LiteralSecretNames<Name extends string> = NoInfer<string extends Name ? {
25
+ readonly secrets?: {
26
+ readonly "give each Secret's name as a literal, or the object as const": never;
27
+ };
28
+ } : unknown>;
29
+ /** Declares a Command whose `ctx.ports` is the CLI's `Ports`. */
30
+ export interface DefineCommand<Ports, Settings = unknown, Table extends ErrorTable = NoErrors> {
31
+ <Row extends RowSchema, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ListCommand<Args, Options, Row, Ports, Settings, Needs<SecretName, Pick<Table, Code>>> & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ListCommand<Args, Options, Row, Ports, Settings, Needs<SecretName, Pick<Table, Code>>>;
32
+ <Schema extends z.ZodType, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ReadCommand<Args, Options, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema> & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ReadCommand<Args, Options, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema>;
33
+ <Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ReadCommand<Args, Options, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ReadCommand<Args, Options, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput;
34
+ <Schema extends z.ZodType, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ActCommand<Args, Options, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema> & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ActCommand<Args, Options, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema>;
35
+ <Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ActCommand<Args, Options, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ActCommand<Args, Options, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput;
36
+ <Schema extends z.ZodType, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ServeCommand<Args, Options, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema> & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ServeCommand<Args, Options, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema>;
37
+ <Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: ServeCommand<Args, Options, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): ServeCommand<Args, Options, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput;
38
+ <Plan, Schema extends z.ZodType, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: WriteCommand<Args, Options, Plan, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema> & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): WriteCommand<Args, Options, Plan, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema>;
39
+ <Plan, Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: WriteCommand<Args, Options, Plan, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): WriteCommand<Args, Options, Plan, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput;
40
+ <Plan, Schema extends z.ZodType, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: DestructiveCommand<Args, Options, Plan, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema> & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): DestructiveCommand<Args, Options, Plan, Returns<Schema>, Ports, Settings, Prints<Schema>, Needs<SecretName, Pick<Table, Code>>> & WithOutput<Schema>;
41
+ <Plan, Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput, const SecretName extends string = never, Code extends keyof Table & string = never>(command: DestructiveCommand<Args, Options, Plan, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput & WithoutStandardFlags<Args, Options> & LiteralSecretNames<SecretName>): DestructiveCommand<Args, Options, Plan, Data, Ports, Settings, Data, Needs<SecretName, Pick<Table, Code>>> & WithoutOutput;
42
+ }
43
+ /** Throws when the Command's declaration breaks a rule its type cannot express; `label` names it. */
44
+ export declare function checkCommand(command: Command, label: string, table: ErrorTable): void;
45
+ export declare function defineCommandFor<Ports, Settings, Table extends ErrorTable = NoErrors>(): DefineCommand<Ports, Settings, Table>;
46
+ export declare const defineCommand: DefineCommand<unknown>;
47
+ export {};
@@ -0,0 +1,25 @@
1
+ import { checkForce, checkNoStandardFlags } from "./command-line/flags.js";
2
+ import { checkArrayArgLast, checkNoBooleanArrayOption, checkStdinFields, } from "./command-line/input.js";
3
+ /** Throws when the Command's declaration breaks a rule its type cannot express; `label` names it. */
4
+ export function checkCommand(command, label, table) {
5
+ checkNoStandardFlags(command, label);
6
+ checkForce(command, label);
7
+ checkArrayArgLast(label, command.args);
8
+ checkStdinFields(label, command.args, command.options);
9
+ checkNoBooleanArrayOption(label, command.options);
10
+ checkErrors(command, label, table);
11
+ }
12
+ function checkErrors(command, label, table) {
13
+ const unknown = (command.errors ?? []).filter((code) => !Object.hasOwn(table, code));
14
+ if (unknown.length > 0) {
15
+ throw new Error(`${label} declares ${unknown.join(", ")} in errors, a code the Error table lacks`);
16
+ }
17
+ }
18
+ export function defineCommandFor() {
19
+ return declared;
20
+ }
21
+ function declared(command) {
22
+ return command;
23
+ }
24
+ export const defineCommand = defineCommandFor();
25
+ //# sourceMappingURL=define-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-command.js","sourceRoot":"","sources":["../src/define-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAyB,MAAM,yBAAyB,CAAC;AAClG,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAgXjC,qGAAqG;AACrG,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,KAAa,EAAE,KAAiB;IAC7E,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3B,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,yBAAyB,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,OAAgB,EAAE,KAAa,EAAE,KAAiB;IACrE,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACrF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,aAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C,CAClF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB;IAK9B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,QAAQ,CAA2B,OAAiB;IAC3D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAA2B,gBAAgB,EAAE,CAAC"}
package/dist/define.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type * as z from "zod";
2
- import type { BuildStamp, Context, PortsBase, ProjectFile, ServeContext } from "./context.js";
2
+ import type { SideTaskRun } from "./context/side-task.js";
3
+ import type { Context, Needs, NoNeeds, PortsBase, ProjectFile, ServeContext } from "./context.js";
3
4
  import type { ErrorTable } from "./error-table.js";
4
- import { type StandardFlagName } from "./flags.js";
5
5
  import type { Page, PageInput, RowSchema } from "./list.js";
6
- import type { SideTaskRun } from "./side-task.js";
6
+ import type { NextStep } from "./next-step.js";
7
7
  import type { Style } from "./style.js";
8
8
  /** Shown in help and help JSON. */
9
9
  export interface Example {
@@ -25,19 +25,22 @@ export interface Tool {
25
25
  /** The command that installs it, shown when it is missing. */
26
26
  readonly install: string;
27
27
  }
28
+ /** A key or token a Command needs, read as `ctx.secret` reads it. */
29
+ export interface SecretDeclaration<Name extends string = string> {
30
+ readonly name: Name;
31
+ /** Where to obtain the key, such as the page that issues it; shown when it is missing. */
32
+ readonly get: string;
33
+ }
28
34
  /** Bounds a whole run, so a long run stops before the caller's own timeout and can be continued. */
29
35
  export interface RunDeadline<In> {
30
36
  readonly ms: number;
31
37
  /**
32
- * The command line that continues the work, given as the hint of the run's `DEADLINE_EXCEEDED`;
33
- * `commandLine` is `ctx.commandLine`. Once the deadline passes, every error of the run becomes
34
- * `DEADLINE_EXCEEDED`.
38
+ * The Next step that continues the work, given by the run's `DEADLINE_EXCEEDED`; `rerun` is
39
+ * `ctx.rerun`. Once the deadline passes, every error of the run becomes `DEADLINE_EXCEEDED`.
35
40
  */
36
- resume(input: In, commandLine: Context["commandLine"]): string;
41
+ resume(input: In, rerun: Context["rerun"]): NextStep;
37
42
  }
38
- interface CommandBase<Args extends InputSchema, Options extends InputSchema> {
39
- /** The word the Command is listed under in `commands`; it labels the Command in errors and spill files. */
40
- readonly name: string;
43
+ interface CommandBase<Args extends InputSchema, Options extends InputSchema, Declared extends Needs> {
41
44
  /** One line, shown in help and help JSON. */
42
45
  readonly description: string;
43
46
  /** A paragraph printed after the options in text help, and carried as `help` in help JSON. */
@@ -56,6 +59,18 @@ interface CommandBase<Args extends InputSchema, Options extends InputSchema> {
56
59
  * `TOOL_MISSING` (exit 2), naming each with its `install`, and `doctor` checks each.
57
60
  */
58
61
  readonly tools?: readonly Tool[];
62
+ /**
63
+ * Read after `tools`, before `plan`, `run` or `start`, `--dry-run` included: missing ones fail the
64
+ * run with `SECRET_MISSING` (exit 2), naming each with its `get` and the CLI's `.env`. `ctx.secret`
65
+ * reads only these, help JSON lists them, and `doctor` checks each.
66
+ */
67
+ readonly secrets?: readonly SecretDeclaration<Declared["secretName"]>[];
68
+ /**
69
+ * The codes of the CLI's Error table the Command throws, listed with their class in help JSON;
70
+ * `ctx.fail` throws only these. A run ending in a table code missing here, an `AggregateError`
71
+ * leaf included, fails as a bug (exit 70). Runtime codes are never listed.
72
+ */
73
+ readonly errors?: readonly (keyof Declared["errors"] & string)[];
59
74
  /**
60
75
  * Positional operands, in the schema's order; each field's `.describe()` is its help. The last
61
76
  * field may be a `z.array(...)`, which takes every remaining operand, and one string field may be
@@ -71,19 +86,35 @@ interface CommandBase<Args extends InputSchema, Options extends InputSchema> {
71
86
  /** At `ms`, `ctx.signal` aborts and the run ends with `DEADLINE_EXCEEDED` (exit 75). */
72
87
  readonly deadline?: RunDeadline<Input<Args, Options>>;
73
88
  }
74
- interface UnpagedCommand<Args extends InputSchema, Options extends InputSchema> extends CommandBase<Args, Options> {
75
- /** The schema of the data the Command prints, published as JSON Schema in help JSON. */
76
- readonly output?: z.ZodType;
89
+ /** `Data` is what the Command returns or delivers; `Printed` is what prints, its `output`'s parse of it. */
90
+ interface UnpagedCommand<Args extends InputSchema, Options extends InputSchema, Data, Printed, Declared extends Needs> extends CommandBase<Args, Options, Declared> {
91
+ /**
92
+ * The schema of the data the Command prints, published as JSON Schema in help JSON. The
93
+ * Runtime parses returned and delivered data with it before printing: data it rejects fails the
94
+ * run as a bug (exit 70), and its defaults and transforms show in what prints.
95
+ */
96
+ readonly output?: z.ZodType<Printed, Data>;
77
97
  readonly rows?: never;
78
- }
79
- export interface ReadCommand<Args extends InputSchema, Options extends InputSchema, Data, Ports = unknown, Settings = unknown> extends UnpagedCommand<Args, Options> {
80
- readonly effect: "read";
81
- run(input: Input<Args, Options>, ctx: Context<Ports, Settings>): Data | Promise<Data>;
82
98
  /**
83
99
  * Turns the data into short text; `--json` prints the data itself. `style` colours only when a
84
- * person watches a terminal or `FORCE_COLOR` is set.
100
+ * person watches a terminal or `FORCE_COLOR` is set. Without it, text prints the data as TOON, or
101
+ * nothing when the data is `undefined`.
85
102
  */
86
- render(data: Data, style: Style): string;
103
+ render?(data: Printed, style: Style): string;
104
+ }
105
+ interface UnpagedRunCommand<Args extends InputSchema, Options extends InputSchema, Data, Ports, Settings, Printed, Declared extends Needs> extends UnpagedCommand<Args, Options, Data, Printed, Declared> {
106
+ run(input: Input<Args, Options>, ctx: Context<Ports, Settings, Declared>): Data | Promise<Data>;
107
+ }
108
+ export interface ReadCommand<Args extends InputSchema, Options extends InputSchema, Data, Ports = unknown, Settings = unknown, Printed = Data, Declared extends Needs = NoNeeds> extends UnpagedRunCommand<Args, Options, Data, Ports, Settings, Printed, Declared> {
109
+ readonly effect: "read";
110
+ }
111
+ /**
112
+ * A Command that changes the state of a program already running, such as a page in a browser tab,
113
+ * which ends with that program: not files or remote services, which are `write`. It runs as a read
114
+ * Command does, with no Plan and of the Standard flags only `--json`, and running it again may act again.
115
+ */
116
+ export interface ActCommand<Args extends InputSchema, Options extends InputSchema, Data, Ports = unknown, Settings = unknown, Printed = Data, Declared extends Needs = NoNeeds> extends UnpagedRunCommand<Args, Options, Data, Ports, Settings, Printed, Declared> {
117
+ readonly effect: "act";
87
118
  }
88
119
  /**
89
120
  * A read Command whose data is a page of rows, from `paginate` or `page`; the Runtime adds `--limit`
@@ -91,29 +122,29 @@ export interface ReadCommand<Args extends InputSchema, Options extends InputSche
91
122
  * the command line for the following page, and as text ends it with a line saying how many rows were
92
123
  * shown and either that command line or that no pages remain. A page never spills, and `--fields` keeps only the named fields.
93
124
  */
94
- export interface ListCommand<Args extends InputSchema, Options extends InputSchema, Row extends RowSchema, Ports = unknown, Settings = unknown> extends CommandBase<Args, Options> {
125
+ export interface ListCommand<Args extends InputSchema, Options extends InputSchema, Row extends RowSchema, Ports = unknown, Settings = unknown, Declared extends Needs = NoNeeds> extends CommandBase<Args, Options, Declared> {
95
126
  readonly effect: "read";
96
127
  /** The schema of one row; the page's output schema is derived from it. */
97
128
  readonly rows: Row;
98
129
  readonly output?: never;
99
- run(input: Flatten<OutputOf<Args> & OutputOf<Options> & PageInput>, ctx: Context<Ports, Settings>): Page<z.output<Row>> | Promise<Page<z.output<Row>>>;
100
- /** Receives the page; render `page.items`. */
101
- render(page: Page<z.output<Row>>, style: Style): string;
130
+ run(input: Flatten<OutputOf<Args> & OutputOf<Options> & PageInput>, ctx: Context<Ports, Settings, Declared>): Page<z.output<Row>> | Promise<Page<z.output<Row>>>;
131
+ /** Receives the page; render `page.items`. Without it, text prints `page.items` as TOON. */
132
+ render?(page: Page<z.output<Row>>, style: Style): string;
102
133
  }
103
134
  /**
104
135
  * A Command that changes something: `plan` has no side effects, `apply` performs the Plan. The
105
136
  * Runtime adds `--dry-run`, which prints the Plan and stops; between `plan` and `apply` it checks
106
137
  * `outputs`, then `cost`, then `confirm`, each refusal's hint holding the command line plus its flag.
107
138
  */
108
- interface PlannedCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data, Ports, Settings> extends UnpagedCommand<Args, Options> {
109
- plan(input: Input<Args, Options>, ctx: Context<Ports, Settings>): Plan | Promise<Plan>;
110
- apply(plan: Plan, ctx: Context<Ports, Settings>): Data | Promise<Data>;
111
- render(data: Data, style: Style): string;
139
+ interface PlannedCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data, Ports, Settings, Printed, Declared extends Needs> extends UnpagedCommand<Args, Options, Data, Printed, Declared> {
140
+ plan(input: Input<Args, Options>, ctx: Context<Ports, Settings, Declared>): Plan | Promise<Plan>;
141
+ apply(plan: Plan, ctx: Context<Ports, Settings, Declared>): Data | Promise<Data>;
112
142
  /**
113
143
  * `--dry-run --json` prints the Plan itself, or `{ plan, outputs?, cost }` when the Command
114
- * declares `outputs` or `cost`; a byte array in it prints as an index-keyed object.
144
+ * declares `outputs` or `cost`; a byte array in it prints as an index-keyed object. Without it,
145
+ * text prints `Would run <command line>:` and under it the Plan as TOON, indented two spaces.
115
146
  */
116
- renderPlan(plan: Plan, style: Style): string;
147
+ renderPlan?(plan: Plan, style: Style): string;
117
148
  /**
118
149
  * A sentence stating what the Plan costs, or undefined when it is cheap. Declaring it adds
119
150
  * `--yes`; a run whose cost is a sentence and lacks it refuses with `NOT_CONFIRMED` (exit 2), and
@@ -133,10 +164,10 @@ interface PlannedCommand<Args extends InputSchema, Options extends InputSchema,
133
164
  */
134
165
  readonly force?: string;
135
166
  }
136
- export interface WriteCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data, Ports = unknown, Settings = unknown> extends PlannedCommand<Args, Options, Plan, Data, Ports, Settings> {
167
+ export interface WriteCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data, Ports = unknown, Settings = unknown, Printed = Data, Declared extends Needs = NoNeeds> extends PlannedCommand<Args, Options, Plan, Data, Ports, Settings, Printed, Declared> {
137
168
  readonly effect: "write";
138
169
  }
139
- export interface DestructiveCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data, Ports = unknown, Settings = unknown> extends PlannedCommand<Args, Options, Plan, Data, Ports, Settings> {
170
+ export interface DestructiveCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data, Ports = unknown, Settings = unknown, Printed = Data, Declared extends Needs = NoNeeds> extends PlannedCommand<Args, Options, Plan, Data, Ports, Settings, Printed, Declared> {
140
171
  readonly effect: "destructive";
141
172
  /**
142
173
  * The value the caller must repeat as `--confirm`, naming the target the Plan changes; without it
@@ -148,16 +179,20 @@ export interface DestructiveCommand<Args extends InputSchema, Options extends In
148
179
  * A Command that keeps running, such as a preview server, until Ctrl-C or SIGTERM stops it or it
149
180
  * calls `ctx.end()`, either with exit 0. Of the Standard flags it gets only `--json`.
150
181
  */
151
- export interface ServeCommand<Args extends InputSchema, Options extends InputSchema, Data, Ports = unknown, Settings = unknown> extends UnpagedCommand<Args, Options> {
182
+ export interface ServeCommand<Args extends InputSchema, Options extends InputSchema, Data, Ports = unknown, Settings = unknown, Printed = Data, Declared extends Needs = NoNeeds> extends UnpagedCommand<Args, Options, Data, Printed, Declared> {
152
183
  readonly effect: "serve";
153
184
  /** Starts the work and returns its data, which prints at once; stop the work on `ctx.signal`. */
154
- start(input: Input<Args, Options>, ctx: ServeContext<Ports, Settings>): Data | Promise<Data>;
155
- render(data: Data, style: Style): string;
185
+ start(input: Input<Args, Options>, ctx: ServeContext<Ports, Settings, Declared>): Data | Promise<Data>;
156
186
  }
157
- export type Command<Ports = unknown, Settings = unknown> = ReadCommand<InputSchema, InputSchema, unknown, Ports, Settings> | ListCommand<InputSchema, InputSchema, RowSchema, Ports, Settings> | WriteCommand<InputSchema, InputSchema, unknown, unknown, Ports, Settings> | DestructiveCommand<InputSchema, InputSchema, unknown, unknown, Ports, Settings> | ServeCommand<InputSchema, InputSchema, unknown, Ports, Settings>;
187
+ export type Command<Ports = unknown, Settings = unknown> = ReadCommand<InputSchema, InputSchema, unknown, Ports, Settings, unknown, Needs> | ActCommand<InputSchema, InputSchema, unknown, Ports, Settings, unknown, Needs> | ListCommand<InputSchema, InputSchema, RowSchema, Ports, Settings, Needs> | WriteCommand<InputSchema, InputSchema, unknown, unknown, Ports, Settings, unknown, Needs> | DestructiveCommand<InputSchema, InputSchema, unknown, unknown, Ports, Settings, unknown, Needs> | ServeCommand<InputSchema, InputSchema, unknown, Ports, Settings, unknown, Needs>;
158
188
  export interface Commands<Ports = unknown, Settings = unknown> {
159
189
  readonly [key: string]: Command<Ports, Settings> | Commands<Ports, Settings>;
160
190
  }
191
+ export type HubSkillSource = {
192
+ readonly source: string;
193
+ } | {
194
+ readonly page: string;
195
+ };
161
196
  export interface PackagedSkillSource {
162
197
  readonly packaged: string;
163
198
  readonly agents?: string;
@@ -167,8 +202,6 @@ interface CliBase<Ports, Settings> {
167
202
  readonly version: string;
168
203
  /** One line saying what the CLI does, shown under the first line of its help and in help JSON. */
169
204
  readonly description: string;
170
- /** The commit the build was made from and when, stamped by the bundler; `--version` prints it. */
171
- readonly build?: BuildStamp;
172
205
  /** Every code the CLI throws; a code missing here exits 70, as a bug. */
173
206
  readonly errors?: ErrorTable;
174
207
  /** Builds the real ports when a run first reads `ctx.ports`; `runCli`'s `ports` replaces them in a test. */
@@ -179,10 +212,16 @@ interface CliBase<Ports, Settings> {
179
212
  * typically the git URL of the Skill Hub its release commits the skill to; without `skill`,
180
213
  * `doctor` and `update` give no line that installs it.
181
214
  *
215
+ * `{ page }` is an `https` page of a Skill Hub that gives each user their own install line, such
216
+ * as an API Skill Hub's page for the skill. `doctor` and `update` then give no line that installs
217
+ * it: for a missing copy, or one that states no version, they name the page, `doctor` in the
218
+ * `skill` row's message and `update` as a Notice. A copy older than the CLI still gets
219
+ * `npx -y skills update <name>`, which reinstalls from the user's own URL.
220
+ *
182
221
  * `{ packaged }` is a Packaged skill: a folder, relative to the package root, holding `SKILL.md`
183
222
  * and its files. The Runtime then adds the Built-in `skill install`, which copies that folder to
184
223
  * `.claude/skills/<name>` at the package manager's project root (removing files the package no
185
- * longer has). With `agents`, it also writes that text verbatim as the CLI's block in the
224
+ * longer has). With `agents`, it also writes that text verbatim as the CLI's Agents section in the
186
225
  * `AGENTS.md` there, between `<!-- BEGIN:<name> -->` and `<!-- END:<name> -->`, and names the
187
226
  * `@AGENTS.md` line `CLAUDE.md` lacks. A copy of another `metadata.version` refreshes at once;
188
227
  * in a copy at the package's version, a file that differs was edited, and replacing or removing
@@ -193,13 +232,11 @@ interface CliBase<Ports, Settings> {
193
232
  * `skill: { copy, copyVersion, packageVersion, home? }`, `home` naming that folder. Every other
194
233
  * Command run from an install gives that row's problem as a Notice before the Command runs, or
195
234
  * one saying the copy could not be checked when a file is unreadable. With `agents`, the
196
- * advisory `agents` row reports a project root `AGENTS.md` without the CLI's block, or with
235
+ * advisory `agents` row reports a project root `AGENTS.md` without the CLI's Agents section, or with
197
236
  * another one (fix: `<run-as> skill install`), and a `CLAUDE.md` without `@AGENTS.md`. Only a CLI with several
198
237
  * Commands may declare it: `defineCli` throws otherwise.
199
238
  */
200
- readonly skill?: {
201
- readonly source: string;
202
- } | PackagedSkillSource;
239
+ readonly skill?: HubSkillSource | PackagedSkillSource;
203
240
  /**
204
241
  * Work that runs beside every Command run, such as a usage count; return `undefined` to decline.
205
242
  * It starts once the input is parsed, before `plan`, `run` or `start`, so it also runs for a run a
@@ -268,6 +305,8 @@ export interface CommandTreeCli<Ports = unknown, Settings = unknown> extends Cli
268
305
  readonly doctor?: readonly DoctorCheck<Ports, Settings>[];
269
306
  /** Tools `doctor` checks besides the Commands' own; no Command requires them. */
270
307
  readonly tools?: readonly Tool[];
308
+ /** Secrets `doctor` checks besides the Commands' own; no Command requires them. */
309
+ readonly secrets?: readonly SecretDeclaration[];
271
310
  }
272
311
  /** An Agent CLI that is one Command, run with no Command name, as in `tool <args>`. */
273
312
  export interface SingleCommandCli<Ports = unknown, Settings = unknown> extends CliBase<Ports, Settings> {
@@ -275,24 +314,5 @@ export interface SingleCommandCli<Ports = unknown, Settings = unknown> extends C
275
314
  readonly commands?: never;
276
315
  }
277
316
  export type Cli<Ports = unknown, Settings = unknown> = CommandTreeCli<Ports, Settings> | SingleCommandCli<Ports, Settings>;
278
- type Kebab<Key extends string> = Key extends `${infer Head}${infer Tail}` ? `${Head extends Lowercase<Head> ? Head : `-${Lowercase<Head>}`}${Kebab<Tail>}` : Key;
279
- type Taken<Schema extends InputSchema> = Extract<Kebab<Extract<keyof Schema["shape"], string>>, StandardFlagName>;
280
- type Unreserved<Schema extends InputSchema> = [Taken<Schema>] extends [never] ? unknown : {
281
- readonly standardFlagDeclared: Taken<Schema>;
282
- };
283
- interface WithoutStandardFlags<Args extends InputSchema, Options extends InputSchema> {
284
- readonly args?: Unreserved<Args>;
285
- readonly options?: Unreserved<Options>;
286
- }
287
- /** Declares a Command whose `ctx.ports` is the CLI's `Ports`. */
288
- export interface DefineCommand<Ports, Settings = unknown> {
289
- <Row extends RowSchema, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: ListCommand<Args, Options, Row, Ports, Settings> & WithoutStandardFlags<Args, Options>): ListCommand<Args, Options, Row, Ports, Settings>;
290
- <Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: ReadCommand<Args, Options, Data, Ports, Settings> & WithoutStandardFlags<Args, Options>): ReadCommand<Args, Options, Data, Ports, Settings>;
291
- <Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: ServeCommand<Args, Options, Data, Ports, Settings> & WithoutStandardFlags<Args, Options>): ServeCommand<Args, Options, Data, Ports, Settings>;
292
- <Plan, Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: WriteCommand<Args, Options, Plan, Data, Ports, Settings> & WithoutStandardFlags<Args, Options>): WriteCommand<Args, Options, Plan, Data, Ports, Settings>;
293
- <Plan, Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: DestructiveCommand<Args, Options, Plan, Data, Ports, Settings> & WithoutStandardFlags<Args, Options>): DestructiveCommand<Args, Options, Plan, Data, Ports, Settings>;
294
- }
295
- export declare function defineCommandFor<Ports, Settings>(): DefineCommand<Ports, Settings>;
296
- export declare const defineCommand: DefineCommand<unknown>;
297
317
  export declare function isCommand(node: Command | Commands): node is Command;
298
318
  export {};
package/dist/define.js CHANGED
@@ -1,17 +1,3 @@
1
- import { checkForce, checkNoStandardFlags } from "./flags.js";
2
- import { checkArrayArgLast, checkNoBooleanArrayOption, checkStdinFields } from "./input.js";
3
- function checkedCommand(command) {
4
- checkNoStandardFlags(command);
5
- checkForce(command);
6
- checkArrayArgLast(command.name, command.args);
7
- checkStdinFields(command.name, command.args, command.options);
8
- checkNoBooleanArrayOption(command.name, command.options);
9
- return command;
10
- }
11
- export function defineCommandFor() {
12
- return checkedCommand;
13
- }
14
- export const defineCommand = defineCommandFor();
15
1
  // A group's values are always objects, so a string `effect` can only belong to a Command.
16
2
  export function isCommand(node) {
17
3
  return typeof node.effect === "string";
@@ -1 +1 @@
1
- {"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAyB,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA4Y5F,SAAS,cAAc,CAA2B,OAAiB;IACjE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,UAAU,CAAC,OAAO,CAAC,CAAC;IACpB,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,yBAAyB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAA2B,gBAAgB,EAAE,CAAC;AAExE,0FAA0F;AAC1F,MAAM,UAAU,SAAS,CAAC,IAAwB;IAChD,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAmbA,0FAA0F;AAC1F,MAAM,UAAU,SAAS,CAAC,IAAwB;IAChD,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC;AACzC,CAAC"}