@duyquangnvx/agent-cli 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/abort.d.ts +2 -0
  3. package/dist/abort.js +11 -0
  4. package/dist/abort.js.map +1 -0
  5. package/dist/agent-cli.d.ts +17 -0
  6. package/dist/agent-cli.js +28 -0
  7. package/dist/agent-cli.js.map +1 -0
  8. package/dist/agent.d.ts +4 -0
  9. package/dist/agent.js +14 -0
  10. package/dist/agent.js.map +1 -0
  11. package/dist/built-ins.d.ts +1 -2
  12. package/dist/built-ins.js +0 -10
  13. package/dist/built-ins.js.map +1 -1
  14. package/dist/clock.d.ts +10 -0
  15. package/dist/clock.js +35 -0
  16. package/dist/clock.js.map +1 -0
  17. package/dist/command-spec.js +8 -1
  18. package/dist/command-spec.js.map +1 -1
  19. package/dist/confirm.d.ts +2 -0
  20. package/dist/confirm.js +4 -2
  21. package/dist/confirm.js.map +1 -1
  22. package/dist/cost.d.ts +9 -0
  23. package/dist/cost.js +16 -0
  24. package/dist/cost.js.map +1 -0
  25. package/dist/define.d.ts +133 -32
  26. package/dist/define.js +5 -1
  27. package/dist/define.js.map +1 -1
  28. package/dist/doctor-rows.d.ts +2 -2
  29. package/dist/doctor-rows.js +42 -5
  30. package/dist/doctor-rows.js.map +1 -1
  31. package/dist/doctor.d.ts +2 -1
  32. package/dist/doctor.js +26 -28
  33. package/dist/doctor.js.map +1 -1
  34. package/dist/errno.d.ts +12 -0
  35. package/dist/errno.js +40 -0
  36. package/dist/errno.js.map +1 -0
  37. package/dist/error-table.d.ts +34 -0
  38. package/dist/error-table.js +10 -0
  39. package/dist/error-table.js.map +1 -0
  40. package/dist/errors.d.ts +17 -12
  41. package/dist/errors.js +59 -38
  42. package/dist/errors.js.map +1 -1
  43. package/dist/execute.d.ts +9 -3
  44. package/dist/execute.js +38 -5
  45. package/dist/execute.js.map +1 -1
  46. package/dist/exit-classes.d.ts +31 -0
  47. package/dist/exit-classes.js +107 -0
  48. package/dist/exit-classes.js.map +1 -0
  49. package/dist/files.d.ts +9 -0
  50. package/dist/files.js +59 -0
  51. package/dist/files.js.map +1 -0
  52. package/dist/flags.d.ts +17 -3
  53. package/dist/flags.js +26 -4
  54. package/dist/flags.js.map +1 -1
  55. package/dist/global-install.d.ts +1 -0
  56. package/dist/global-install.js +2 -2
  57. package/dist/global-install.js.map +1 -1
  58. package/dist/help-json.d.ts +2 -1
  59. package/dist/help-json.js +18 -2
  60. package/dist/help-json.js.map +1 -1
  61. package/dist/help.d.ts +4 -2
  62. package/dist/help.js +62 -6
  63. package/dist/help.js.map +1 -1
  64. package/dist/index.d.ts +10 -4
  65. package/dist/index.js +2 -2
  66. package/dist/index.js.map +1 -1
  67. package/dist/interrupts.d.ts +17 -3
  68. package/dist/interrupts.js +43 -25
  69. package/dist/interrupts.js.map +1 -1
  70. package/dist/invocation.d.ts +7 -2
  71. package/dist/invocation.js +11 -3
  72. package/dist/invocation.js.map +1 -1
  73. package/dist/list.d.ts +1 -0
  74. package/dist/list.js +4 -2
  75. package/dist/list.js.map +1 -1
  76. package/dist/npm.d.ts +5 -0
  77. package/dist/npm.js +19 -17
  78. package/dist/npm.js.map +1 -1
  79. package/dist/output.d.ts +18 -4
  80. package/dist/output.js +65 -23
  81. package/dist/output.js.map +1 -1
  82. package/dist/outputs.d.ts +11 -0
  83. package/dist/outputs.js +22 -0
  84. package/dist/outputs.js.map +1 -0
  85. package/dist/package-root.d.ts +6 -0
  86. package/dist/package-root.js +17 -0
  87. package/dist/package-root.js.map +1 -0
  88. package/dist/parse-input.d.ts +2 -0
  89. package/dist/parse-input.js +5 -3
  90. package/dist/parse-input.js.map +1 -1
  91. package/dist/project.d.ts +4 -0
  92. package/dist/project.js +48 -0
  93. package/dist/project.js.map +1 -0
  94. package/dist/route.d.ts +2 -0
  95. package/dist/route.js +2 -1
  96. package/dist/route.js.map +1 -1
  97. package/dist/run-cli.d.ts +24 -5
  98. package/dist/run-cli.js +122 -17
  99. package/dist/run-cli.js.map +1 -1
  100. package/dist/run-process.js +6 -3
  101. package/dist/run-process.js.map +1 -1
  102. package/dist/secrets.d.ts +13 -0
  103. package/dist/secrets.js +29 -0
  104. package/dist/secrets.js.map +1 -0
  105. package/dist/spawn.d.ts +29 -0
  106. package/dist/spawn.js +79 -0
  107. package/dist/spawn.js.map +1 -0
  108. package/dist/spill.d.ts +16 -0
  109. package/dist/spill.js +60 -0
  110. package/dist/spill.js.map +1 -0
  111. package/dist/style.js +5 -12
  112. package/dist/style.js.map +1 -1
  113. package/dist/tail.d.ts +2 -0
  114. package/dist/tail.js +5 -0
  115. package/dist/tail.js.map +1 -0
  116. package/dist/tools.d.ts +6 -0
  117. package/dist/tools.js +69 -0
  118. package/dist/tools.js.map +1 -0
  119. package/dist/update.js +7 -7
  120. package/dist/update.js.map +1 -1
  121. package/dist/usage.d.ts +3 -0
  122. package/dist/usage.js +6 -3
  123. package/dist/usage.js.map +1 -1
  124. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ import { CliError } from "./errors.js";
2
+ /** Keeps each code's literal class and `details` schema, so `cliError` can type its throw sites. */
3
+ export function defineErrors(table) {
4
+ return table;
5
+ }
6
+ /** A `CliError` for a code of `table`, whose `details` must match the code's schema. */
7
+ export function cliError(_table, code, init, options) {
8
+ return new CliError({ ...init, code }, options);
9
+ }
10
+ //# sourceMappingURL=error-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-table.js","sourceRoot":"","sources":["../src/error-table.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAcvC,oGAAoG;AACpG,MAAM,UAAU,YAAY,CAAiC,KAAY;IACvE,OAAO,KAAK,CAAC;AACf,CAAC;AAmBD,wFAAwF;AACxF,MAAM,UAAU,QAAQ,CACtB,MAAa,EACb,IAAU,EACV,IAA+B,EAC/B,OAAsB;IAEtB,OAAO,IAAI,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC"}
package/dist/errors.d.ts CHANGED
@@ -1,34 +1,39 @@
1
1
  import type { Env } from "./define.js";
2
2
  import type { Style } from "./style.js";
3
- export interface CliErrorDetails {
3
+ export interface CliErrorFields {
4
4
  readonly code: string;
5
5
  readonly message: string;
6
6
  readonly hint: string;
7
- readonly retryable: boolean;
7
+ /** Facts the caller acts on without parsing the message, shaped by the code's schema. */
8
+ readonly details?: unknown;
9
+ /** ISO 8601: when a wait-class failure may pass, set only when the source said so. */
10
+ readonly retryAt?: string;
8
11
  }
9
12
  export declare class CliError extends Error {
10
13
  readonly code: string;
11
14
  readonly hint: string;
12
- readonly retryable: boolean;
13
- constructor({ code, message, hint, retryable }: CliErrorDetails, options?: ErrorOptions);
15
+ readonly details: unknown;
16
+ readonly retryAt: string | undefined;
17
+ constructor({ code, message, hint, details, retryAt }: CliErrorFields, options?: ErrorOptions);
14
18
  }
15
- export type UsageErrorDetails = Omit<CliErrorDetails, "retryable">;
16
- /** The caller called the Agent CLI wrong; retrying the same call can't succeed. */
19
+ export type UsageErrorFields = Pick<CliErrorFields, "code" | "message" | "hint">;
20
+ /** The caller called the Agent CLI wrong; the same call can't succeed. */
17
21
  export declare class UsageError extends CliError {
18
- constructor(details: UsageErrorDetails);
22
+ constructor(fields: UsageErrorFields);
19
23
  }
24
+ export declare const INTERNAL_CODE = "INTERNAL";
20
25
  export interface ErrorFormat {
21
26
  readonly cliName: string;
22
27
  readonly json: boolean;
23
28
  readonly env: Env;
24
29
  readonly style: Style;
30
+ /** Whether `error` is a bug: not a `CliError`, or one whose code nobody declared. */
31
+ readonly isBug: (error: unknown) => boolean;
25
32
  }
33
+ export declare function errnoOf(error: unknown): string | undefined;
26
34
  export declare function isMissingFile(error: unknown): boolean;
27
35
  export declare function debugVariable(cliName: string): string;
28
36
  export declare function messageOf(error: unknown): string;
37
+ /** The errors a run failed with: each one an `AggregateError` holds, or the one it threw. */
38
+ export declare function errorsOf(error: unknown): readonly unknown[];
29
39
  export declare function formatRuntimeError(error: unknown, format: ErrorFormat): string;
30
- /** A failure that still prints the Command's data on stdout, as `doctor` does with its rows. */
31
- export declare class FailureWithData extends CliError {
32
- readonly data: unknown;
33
- constructor(details: CliErrorDetails, data: unknown);
34
- }
package/dist/errors.js CHANGED
@@ -1,25 +1,32 @@
1
1
  export class CliError extends Error {
2
2
  code;
3
3
  hint;
4
- retryable;
5
- constructor({ code, message, hint, retryable }, options) {
4
+ details;
5
+ retryAt;
6
+ constructor({ code, message, hint, details, retryAt }, options) {
6
7
  super(message, options);
7
8
  this.name = "CliError";
8
9
  this.code = code;
9
10
  this.hint = hint;
10
- this.retryable = retryable;
11
+ this.details = details;
12
+ this.retryAt = retryAt;
11
13
  }
12
14
  }
13
- /** The caller called the Agent CLI wrong; retrying the same call can't succeed. */
15
+ /** The caller called the Agent CLI wrong; the same call can't succeed. */
14
16
  export class UsageError extends CliError {
15
- constructor(details) {
16
- super({ ...details, retryable: false });
17
+ constructor(fields) {
18
+ super(fields);
17
19
  this.name = "UsageError";
18
20
  }
19
21
  }
20
- const INTERNAL_CODE = "INTERNAL";
22
+ export const INTERNAL_CODE = "INTERNAL";
23
+ export function errnoOf(error) {
24
+ return error instanceof Error && "code" in error && typeof error.code === "string"
25
+ ? error.code
26
+ : undefined;
27
+ }
21
28
  export function isMissingFile(error) {
22
- return error instanceof Error && "code" in error && error.code === "ENOENT";
29
+ return errnoOf(error) === "ENOENT";
23
30
  }
24
31
  export function debugVariable(cliName) {
25
32
  return `${cliName.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_DEBUG`;
@@ -30,43 +37,57 @@ export function messageOf(error) {
30
37
  function isDebug({ env, cliName }) {
31
38
  return Boolean(env[debugVariable(cliName)]);
32
39
  }
33
- function detailsOf(error, format) {
40
+ function bugHint(format) {
41
+ return isDebug(format)
42
+ ? "the stack trace shows where it failed"
43
+ : `rerun with ${debugVariable(format.cliName)}=1 to see the stack trace`;
44
+ }
45
+ function fieldsOf(error, format) {
34
46
  if (error instanceof CliError) {
35
- const { code, message, hint, retryable } = error;
36
- return { code, message, hint, retryable };
47
+ const { code, message, hint, details, retryAt } = error;
48
+ return { code, message, hint: format.isBug(error) ? bugHint(format) : hint, details, retryAt };
37
49
  }
38
- return {
39
- code: INTERNAL_CODE,
40
- message: messageOf(error),
41
- hint: isDebug(format)
42
- ? "the stack trace shows where it failed"
43
- : `rerun with ${debugVariable(format.cliName)}=1 to see the stack trace`,
44
- retryable: false,
45
- };
50
+ return { code: INTERNAL_CODE, message: messageOf(error), hint: bugHint(format) };
46
51
  }
47
- function stackOf(error, format) {
48
- return isDebug(format) && !(error instanceof CliError) && error instanceof Error
49
- ? error.stack
50
- : undefined;
52
+ function causesOf(error) {
53
+ return error instanceof Error && error.cause !== undefined
54
+ ? [error.cause, ...causesOf(error.cause)]
55
+ : [];
51
56
  }
52
- export function formatRuntimeError(error, format) {
53
- const details = detailsOf(error, format);
54
- const stack = stackOf(error, format);
55
- if (format.json) {
56
- return `${JSON.stringify({ ...details, stack })}\n`;
57
- }
57
+ function traceOf(error) {
58
+ return error instanceof Error ? (error.stack ?? error.message) : String(error);
59
+ }
60
+ /** Under debug: a bug's stack trace, then every error's cause chain. */
61
+ function debugTrace(error, format) {
62
+ if (!isDebug(format))
63
+ return undefined;
64
+ const lines = [
65
+ ...(format.isBug(error) ? [traceOf(error)] : []),
66
+ ...causesOf(error).map((cause) => `caused by: ${traceOf(cause)}`),
67
+ ];
68
+ return lines.length === 0 ? undefined : lines.join("\n");
69
+ }
70
+ /** The errors a run failed with: each one an `AggregateError` holds, or the one it threw. */
71
+ export function errorsOf(error) {
72
+ return error instanceof AggregateError && error.errors.length > 0 ? error.errors : [error];
73
+ }
74
+ function errorLines(error, format) {
75
+ const fields = fieldsOf(error, format);
76
+ const stack = debugTrace(error, format);
58
77
  const { style } = format;
59
- const label = style.red(error instanceof CliError ? "error:" : "internal error:");
78
+ const label = style.red(format.isBug(error) ? "internal error:" : "error:");
60
79
  const trace = stack === undefined ? "" : `${stack}\n`;
61
- return `${label} ${details.message}\n${trace}${style.cyan("hint:")} ${details.hint}\n`;
80
+ return `${label} ${fields.message}\n${trace}${style.cyan("hint:")} ${fields.hint}\n`;
62
81
  }
63
- /** A failure that still prints the Command's data on stdout, as `doctor` does with its rows. */
64
- export class FailureWithData extends CliError {
65
- data;
66
- constructor(details, data) {
67
- super(details);
68
- this.name = "FailureWithData";
69
- this.data = data;
82
+ export function formatRuntimeError(error, format) {
83
+ const errors = errorsOf(error);
84
+ if (format.json) {
85
+ const printed = errors.map((each) => ({
86
+ ...fieldsOf(each, format),
87
+ stack: debugTrace(each, format),
88
+ }));
89
+ return `${JSON.stringify({ errors: printed })}\n`;
70
90
  }
91
+ return errors.map((each) => errorLines(each, format)).join("");
71
92
  }
72
93
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/execute.d.ts CHANGED
@@ -10,12 +10,18 @@ export interface ExecuteFlags {
10
10
  readonly dryRun: boolean;
11
11
  /** The target the caller named with `--confirm`, if any. */
12
12
  readonly confirm: string | undefined;
13
+ /** Whether the caller approved the cost with `--yes`. */
14
+ readonly yes: boolean;
15
+ /** Whether the caller allowed replacing existing outputs with `--force`. */
16
+ readonly force: boolean;
13
17
  /** The page a List Command's `run` receives with its input. */
14
18
  readonly page: PageInput;
15
19
  /** The caller's command line and the Command's, for the hint of a confirmation error. */
16
20
  readonly invocation: Invocation;
17
21
  readonly commandLine: string;
22
+ /** Prints a serve Command's data the moment `start` returns it. */
23
+ readonly started: (outcome: Outcome) => Promise<void>;
18
24
  }
19
- /** How the Command prints data it fails with, which is the data its `run` or `apply` returns. */
20
- export declare function renderOf(command: Command): (data: unknown, style: Style) => string;
21
- export declare function execute(command: Command, input: Record<string, unknown>, ctx: Context, { dryRun, confirm, page, invocation, commandLine }: ExecuteFlags): Promise<Outcome>;
25
+ /** Delivered data as the Command prints it, which is the data its `run` or `apply` returns. */
26
+ export declare function deliveredOutcome(command: Command, data: unknown): Outcome;
27
+ export declare function execute(command: Command, input: Record<string, unknown>, ctx: Context, { dryRun, confirm, yes, force, page, invocation, commandLine, started }: ExecuteFlags): Promise<Outcome>;
package/dist/execute.js CHANGED
@@ -1,23 +1,56 @@
1
+ import { untilAborted } from "./abort.js";
1
2
  import { checkConfirmation } from "./confirm.js";
3
+ import { checkCost } from "./cost.js";
4
+ import { checkOutputs } from "./outputs.js";
5
+ import { checkTools } from "./tools.js";
2
6
  function outcomeOf(value, render) {
3
7
  return { value, render: (style) => render(value, style) };
4
8
  }
5
- /** How the Command prints data it fails with, which is the data its `run` or `apply` returns. */
6
- export function renderOf(command) {
9
+ /** Delivered data as the Command prints it, which is the data its `run` or `apply` returns. */
10
+ export function deliveredOutcome(command, data) {
7
11
  // The union of render signatures only accepts the intersection of their data types.
8
- return (data, style) => command.render(data, style);
12
+ return outcomeOf(data, command.render);
9
13
  }
10
- export async function execute(command, input, ctx, { dryRun, confirm, page, invocation, commandLine }) {
14
+ function dryRunOutcome(command, plan) {
15
+ const renderPlan = (style) => command.renderPlan(plan, style);
16
+ if (command.outputs === undefined && command.cost === undefined) {
17
+ return { value: plan, render: renderPlan };
18
+ }
19
+ const outputs = command.outputs?.(plan);
20
+ const cost = command.cost?.(plan);
21
+ return {
22
+ // A costed Command's dry run keeps one JSON shape, with `cost: null` when the run is cheap.
23
+ value: {
24
+ plan,
25
+ ...(outputs === undefined ? {} : { outputs }),
26
+ ...(command.cost === undefined ? {} : { cost: cost ?? null }),
27
+ },
28
+ render: (style) => [
29
+ renderPlan(style),
30
+ ...(outputs === undefined ? [] : ["outputs:", ...outputs.map((path) => ` ${path}`)]),
31
+ ...(cost === undefined ? [] : [`cost: ${cost}`]),
32
+ ].join("\n"),
33
+ };
34
+ }
35
+ export async function execute(command, input, ctx, { dryRun, confirm, yes, force, page, invocation, commandLine, started }) {
36
+ await checkTools(command.tools ?? [], ctx.env);
11
37
  if (command.rows !== undefined) {
12
38
  return outcomeOf(await command.run({ ...input, ...page }, ctx), (data, style) => command.render(data, style));
13
39
  }
14
40
  if (command.effect === "read") {
15
41
  return outcomeOf(await command.run(input, ctx), (data, style) => command.render(data, style));
16
42
  }
43
+ if (command.effect === "serve") {
44
+ const data = await command.start(input, ctx);
45
+ await started(outcomeOf(data, (value, style) => command.render(value, style)));
46
+ return untilAborted(ctx.signal);
47
+ }
17
48
  const plan = await command.plan(input, ctx);
18
49
  if (dryRun) {
19
- return outcomeOf(plan, (value, style) => command.renderPlan(value, style));
50
+ return dryRunOutcome(command, plan);
20
51
  }
52
+ await checkOutputs({ invocation, commandLine, force, files: ctx.files }, command.outputs?.(plan));
53
+ checkCost({ invocation, commandLine, yes }, command.cost?.(plan));
21
54
  if (command.effect === "destructive") {
22
55
  checkConfirmation({ invocation, commandLine, given: confirm }, command.confirm(plan));
23
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAsBjD,SAAS,SAAS,CAAQ,KAAY,EAAE,MAA8C;IACpF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,oFAAoF;IACpF,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAE,OAAO,CAAC,MAAkD,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAgB,EAChB,KAA8B,EAC9B,GAAY,EACZ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAgB;IAEhE,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC9E,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAC5B,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACrC,iBAAiB,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AACjG,CAAC"}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Cli } from "./define.js";
2
+ import type { DeclaredExitClass, ErrorTable } from "./error-table.js";
3
+ /** Who must act on a failure (ADR 0005), which sets the exit code. */
4
+ export type ExitClass = "caller" | "operator" | "source" | "wait" | "bug" | "interrupted";
5
+ export declare const SIGNAL_EXIT_CODES: {
6
+ readonly SIGINT: 130;
7
+ readonly SIGTERM: 143;
8
+ };
9
+ export type StopSignal = keyof typeof SIGNAL_EXIT_CODES;
10
+ export declare const EXIT_CODES: {
11
+ readonly caller: 1;
12
+ readonly operator: 2;
13
+ readonly source: 3;
14
+ readonly wait: 75;
15
+ readonly bug: 70;
16
+ };
17
+ /** The codes of `errors` that the Runtime already declares, which a CLI cannot redeclare. */
18
+ export declare function runtimeCodesIn(errors: ErrorTable): string[];
19
+ export declare function isBug(error: unknown, errors: ErrorTable): boolean;
20
+ /**
21
+ * The classes other than bug and interrupt that a run of `cli` can end in: those of the Runtime's
22
+ * codes it can reach, and those of its own table.
23
+ */
24
+ export declare function reachableExitClasses(cli: Cli): Set<DeclaredExitClass>;
25
+ /** The signal named by an interrupt's abort reason; any other reason counts as Ctrl-C. */
26
+ export declare function stopSignalOf(reason: unknown): StopSignal;
27
+ /**
28
+ * The exit code of a run that failed with `error`, given the CLI's error table; `stop` is the
29
+ * signal that interrupted it, if any.
30
+ */
31
+ export declare function exitCodeOf(error: unknown, errors: ErrorTable, stop: AbortSignal | undefined): number;
@@ -0,0 +1,107 @@
1
+ import { CONFIRMATION_MISMATCH, CONFIRMATION_REQUIRED } from "./confirm.js";
2
+ import { NOT_CONFIRMED } from "./cost.js";
3
+ import { DOCTOR_PROBLEMS } from "./doctor.js";
4
+ import { DISK_FULL, NOT_FOUND, PERMISSION_DENIED } from "./errno.js";
5
+ import { CliError, errorsOf, INTERNAL_CODE, UsageError } from "./errors.js";
6
+ import { NOT_GLOBAL_INSTALL } from "./global-install.js";
7
+ import { DEADLINE_EXCEEDED, INTERRUPTED } from "./interrupts.js";
8
+ import { UNKNOWN_FIELD } from "./list.js";
9
+ import { INSTALL_FAILED, NO_LATEST, NPM_FAILED, REGISTRY_AUTH, REGISTRY_UNREACHABLE, } from "./npm.js";
10
+ import { OUTPUT_EXISTS } from "./outputs.js";
11
+ import { PROJECT_INVALID } from "./project.js";
12
+ import { TOOL_FAILED } from "./spawn.js";
13
+ import { TOOL_MISSING } from "./tools.js";
14
+ import { INVALID_INPUT, UNKNOWN_COMMAND, UNKNOWN_OPTION } from "./usage.js";
15
+ export const SIGNAL_EXIT_CODES = { SIGINT: 130, SIGTERM: 143 };
16
+ export const EXIT_CODES = {
17
+ caller: 1,
18
+ operator: 2,
19
+ source: 3,
20
+ wait: 75,
21
+ bug: 70,
22
+ };
23
+ // Built on call: the modules that throw these codes import this one back (through output.ts), so
24
+ // their constants are not initialised yet while this module loads.
25
+ /** The codes the Runtime and its built-in Commands raise, each with the class that must act on it. */
26
+ function runtimeCodes() {
27
+ return {
28
+ [INVALID_INPUT]: "caller",
29
+ [UNKNOWN_OPTION]: "caller",
30
+ [UNKNOWN_COMMAND]: "caller",
31
+ [UNKNOWN_FIELD]: "caller",
32
+ [CONFIRMATION_REQUIRED]: "caller",
33
+ [CONFIRMATION_MISMATCH]: "caller",
34
+ [NOT_CONFIRMED]: "operator",
35
+ [OUTPUT_EXISTS]: "caller",
36
+ [INTERRUPTED]: "interrupted",
37
+ [DEADLINE_EXCEEDED]: "wait",
38
+ [INTERNAL_CODE]: "bug",
39
+ [PERMISSION_DENIED]: "operator",
40
+ [DISK_FULL]: "operator",
41
+ [NOT_FOUND]: "caller",
42
+ [TOOL_FAILED]: "operator",
43
+ [TOOL_MISSING]: "operator",
44
+ [PROJECT_INVALID]: "operator",
45
+ [DOCTOR_PROBLEMS]: "operator",
46
+ [NOT_GLOBAL_INSTALL]: "operator",
47
+ [REGISTRY_UNREACHABLE]: "operator",
48
+ [REGISTRY_AUTH]: "operator",
49
+ [INSTALL_FAILED]: "operator",
50
+ [NPM_FAILED]: "operator",
51
+ [NO_LATEST]: "source",
52
+ };
53
+ }
54
+ /** The codes of `errors` that the Runtime already declares, which a CLI cannot redeclare. */
55
+ export function runtimeCodesIn(errors) {
56
+ return Object.keys(errors).filter((code) => Object.hasOwn(runtimeCodes(), code));
57
+ }
58
+ // A code that neither the Runtime nor the CLI declares was thrown by mistake: a bug.
59
+ function exitClassOfOne(error, errors) {
60
+ if (!(error instanceof CliError))
61
+ return "bug";
62
+ if (error instanceof UsageError)
63
+ return "caller";
64
+ return runtimeCodes()[error.code] ?? errors[error.code]?.class ?? "bug";
65
+ }
66
+ export function isBug(error, errors) {
67
+ return exitClassOfOne(error, errors) === "bug";
68
+ }
69
+ // Of several errors, the class that must act first decides; any bug makes the whole run one.
70
+ const ACT_FIRST = ["caller", "operator", "source", "wait", "interrupted"];
71
+ function exitClassOf(error, errors) {
72
+ const classes = errorsOf(error).map((each) => exitClassOfOne(each, errors));
73
+ if (classes.includes("bug"))
74
+ return "bug";
75
+ return ACT_FIRST.find((exitClass) => classes.includes(exitClass)) ?? "bug";
76
+ }
77
+ /**
78
+ * The classes other than bug and interrupt that a run of `cli` can end in: those of the Runtime's
79
+ * codes it can reach, and those of its own table.
80
+ */
81
+ export function reachableExitClasses(cli) {
82
+ // Any CLI can write files or refuse an unconfirmed cost (the operator's); only `update` fails as
83
+ // the source's, when the registry has no release.
84
+ const runtime = [
85
+ "caller",
86
+ "operator",
87
+ "wait",
88
+ ...(cli.commands !== undefined && cli.install !== undefined ? ["source"] : []),
89
+ ];
90
+ const own = Object.values(cli.errors ?? {}).map((declaration) => declaration.class);
91
+ return new Set([...runtime, ...own]);
92
+ }
93
+ /** The signal named by an interrupt's abort reason; any other reason counts as Ctrl-C. */
94
+ export function stopSignalOf(reason) {
95
+ return reason === "SIGTERM" ? "SIGTERM" : "SIGINT";
96
+ }
97
+ /**
98
+ * The exit code of a run that failed with `error`, given the CLI's error table; `stop` is the
99
+ * signal that interrupted it, if any.
100
+ */
101
+ export function exitCodeOf(error, errors, stop) {
102
+ const exitClass = exitClassOf(error, errors);
103
+ return exitClass === "interrupted"
104
+ ? SIGNAL_EXIT_CODES[stopSignalOf(stop?.reason)]
105
+ : EXIT_CODES[exitClass];
106
+ }
107
+ //# sourceMappingURL=exit-classes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-classes.js","sourceRoot":"","sources":["../src/exit-classes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,aAAa,EACb,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAW,CAAC;AAIxE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,EAAE;CAC6D,CAAC;AAEvE,iGAAiG;AACjG,mEAAmE;AACnE,sGAAsG;AACtG,SAAS,YAAY;IACnB,OAAO;QACL,CAAC,aAAa,CAAC,EAAE,QAAQ;QACzB,CAAC,cAAc,CAAC,EAAE,QAAQ;QAC1B,CAAC,eAAe,CAAC,EAAE,QAAQ;QAC3B,CAAC,aAAa,CAAC,EAAE,QAAQ;QACzB,CAAC,qBAAqB,CAAC,EAAE,QAAQ;QACjC,CAAC,qBAAqB,CAAC,EAAE,QAAQ;QACjC,CAAC,aAAa,CAAC,EAAE,UAAU;QAC3B,CAAC,aAAa,CAAC,EAAE,QAAQ;QACzB,CAAC,WAAW,CAAC,EAAE,aAAa;QAC5B,CAAC,iBAAiB,CAAC,EAAE,MAAM;QAC3B,CAAC,aAAa,CAAC,EAAE,KAAK;QACtB,CAAC,iBAAiB,CAAC,EAAE,UAAU;QAC/B,CAAC,SAAS,CAAC,EAAE,UAAU;QACvB,CAAC,SAAS,CAAC,EAAE,QAAQ;QACrB,CAAC,WAAW,CAAC,EAAE,UAAU;QACzB,CAAC,YAAY,CAAC,EAAE,UAAU;QAC1B,CAAC,eAAe,CAAC,EAAE,UAAU;QAC7B,CAAC,eAAe,CAAC,EAAE,UAAU;QAC7B,CAAC,kBAAkB,CAAC,EAAE,UAAU;QAChC,CAAC,oBAAoB,CAAC,EAAE,UAAU;QAClC,CAAC,aAAa,CAAC,EAAE,UAAU;QAC3B,CAAC,cAAc,CAAC,EAAE,UAAU;QAC5B,CAAC,UAAU,CAAC,EAAE,UAAU;QACxB,CAAC,SAAS,CAAC,EAAE,QAAQ;KACtB,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,qFAAqF;AACrF,SAAS,cAAc,CAAC,KAAc,EAAE,MAAkB;IACxD,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,KAAK,YAAY,UAAU;QAAE,OAAO,QAAQ,CAAC;IACjD,OAAO,YAAY,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,KAAc,EAAE,MAAkB;IACtD,OAAO,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,CAAC;AACjD,CAAC;AAED,6FAA6F;AAC7F,MAAM,SAAS,GAAyB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;AAEhG,SAAS,WAAW,CAAC,KAAc,EAAE,MAAkB;IACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC;AAC7E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAQ;IAC3C,iGAAiG;IACjG,kDAAkD;IAClD,MAAM,OAAO,GAAwB;QACnC,QAAQ;QACR,UAAU;QACV,MAAM;QACN,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,QAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACxF,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACpF,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,YAAY,CAAC,MAAe;IAC1C,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc,EACd,MAAkB,EAClB,IAA6B;IAE7B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,SAAS,KAAK,aAAa;QAChC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /** The file system as Commands write to it; a test replaces it through `runCli`. */
2
+ export interface Files {
3
+ /** Writes `data` to the absolute `path` whole or not at all. */
4
+ write(path: string, data: string | Uint8Array): Promise<void>;
5
+ /** Whether anything exists at the absolute `path`. */
6
+ exists(path: string): Promise<boolean>;
7
+ }
8
+ /** Real files for one run: the first write to each folder sweeps the temp files of dead writers. */
9
+ export declare function realFiles(): Files;
package/dist/files.js ADDED
@@ -0,0 +1,59 @@
1
+ import { access, readdir, rename, rm, writeFile } from "node:fs/promises";
2
+ import { basename, dirname, join } from "node:path";
3
+ import { errnoOf, isMissingFile } from "./errors.js";
4
+ const TEMP_FILE = /^\..+\.agent-cli-(\d+)\.tmp$/;
5
+ function tempPathOf(path) {
6
+ return join(dirname(path), `.${basename(path)}.agent-cli-${process.pid}.tmp`);
7
+ }
8
+ function isAlive(pid) {
9
+ try {
10
+ process.kill(pid, 0);
11
+ return true;
12
+ }
13
+ catch (error) {
14
+ // EPERM: the process exists but belongs to another user.
15
+ return errnoOf(error) === "EPERM";
16
+ }
17
+ }
18
+ async function sweep(folder) {
19
+ const names = await readdir(folder);
20
+ const dead = names.filter((name) => {
21
+ const pid = TEMP_FILE.exec(name)?.[1];
22
+ return pid !== undefined && !isAlive(Number(pid));
23
+ });
24
+ await Promise.all(dead.map((name) => rm(join(folder, name), { force: true })));
25
+ }
26
+ /** Real files for one run: the first write to each folder sweeps the temp files of dead writers. */
27
+ export function realFiles() {
28
+ const swept = new Set();
29
+ return {
30
+ exists: async (path) => {
31
+ try {
32
+ await access(path);
33
+ return true;
34
+ }
35
+ catch (error) {
36
+ if (isMissingFile(error))
37
+ return false;
38
+ throw error;
39
+ }
40
+ },
41
+ write: async (path, data) => {
42
+ const folder = dirname(path);
43
+ if (!swept.has(folder)) {
44
+ await sweep(folder);
45
+ swept.add(folder);
46
+ }
47
+ const temp = tempPathOf(path);
48
+ try {
49
+ await writeFile(temp, data);
50
+ await rename(temp, path);
51
+ }
52
+ catch (error) {
53
+ await rm(temp, { force: true });
54
+ throw error;
55
+ }
56
+ },
57
+ };
58
+ }
59
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUrD,MAAM,SAAS,GAAG,8BAA8B,CAAC;AAEjD,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yDAAyD;QACzD,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC;IACpC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,MAAc;IACjC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,GAAG,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,SAAS;IACvB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,OAAO;QACL,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACrB,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;gBACnB,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,aAAa,CAAC,KAAK,CAAC;oBAAE,OAAO,KAAK,CAAC;gBACvC,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;gBACpB,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC5B,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChC,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/flags.d.ts CHANGED
@@ -25,6 +25,12 @@ export declare const DRY_RUN_FLAG: StandardFlag & {
25
25
  export declare const CONFIRM_FLAG: StandardFlag & {
26
26
  readonly flag: "--confirm";
27
27
  };
28
+ export declare const YES_FLAG: StandardFlag & {
29
+ readonly flag: "--yes";
30
+ };
31
+ export declare const FORCE_FLAG: StandardFlag & {
32
+ readonly flag: "--force";
33
+ };
28
34
  declare const EFFECT_FLAGS: {
29
35
  readonly read: readonly [StandardFlag & {
30
36
  readonly flag: "--json";
@@ -41,10 +47,18 @@ declare const EFFECT_FLAGS: {
41
47
  }, StandardFlag & {
42
48
  readonly flag: "--confirm";
43
49
  }];
50
+ readonly serve: readonly [StandardFlag & {
51
+ readonly flag: "--json";
52
+ }];
44
53
  };
45
- export type StandardFlagName = NameOf<(typeof ROUTING_FLAGS)[number]> | NameOf<(typeof EFFECT_FLAGS)[Effect][number]["flag"]> | ListFlagName;
46
- /** The Standard flags of a Command with this Effect, and of a List Command. */
47
- export declare function standardFlagsFor(effect: Effect, list: ListSpec | undefined): readonly StandardFlag[];
54
+ export type StandardFlagName = NameOf<(typeof ROUTING_FLAGS)[number]> | NameOf<(typeof EFFECT_FLAGS)[Effect][number]["flag"]> | NameOf<typeof YES_FLAG.flag> | NameOf<typeof FORCE_FLAG.flag> | ListFlagName;
55
+ /** What a Command declares beyond its Effect that adds Standard flags. */
56
+ export interface Declared {
57
+ readonly outputs: boolean;
58
+ readonly cost: boolean;
59
+ }
60
+ /** The Standard flags of a Command with this Effect and declarations, and of a List Command. */
61
+ export declare function standardFlagsFor(effect: Effect, { outputs, cost }: Declared, list: ListSpec | undefined): readonly StandardFlag[];
48
62
  /** Throws when the Command declares an arg or option under a Standard flag's name. */
49
63
  export declare function checkNoStandardFlags(command: Command): void;
50
64
  export {};
package/dist/flags.js CHANGED
@@ -28,16 +28,38 @@ export const CONFIRM_FLAG = standardFlag("--confirm", {
28
28
  takes: "value",
29
29
  schema: z.string(),
30
30
  });
31
+ export const YES_FLAG = standardFlag("--yes", {
32
+ description: "approve the cost the run states; --dry-run shows it",
33
+ takes: "nothing",
34
+ schema: z.boolean(),
35
+ });
36
+ export const FORCE_FLAG = standardFlag("--force", {
37
+ description: "replace the files the run writes when they exist; --dry-run lists them",
38
+ takes: "nothing",
39
+ schema: z.boolean(),
40
+ });
31
41
  const EFFECT_FLAGS = {
32
42
  read: [JSON_FLAG],
33
43
  write: [JSON_FLAG, DRY_RUN_FLAG],
34
44
  destructive: [JSON_FLAG, DRY_RUN_FLAG, CONFIRM_FLAG],
45
+ serve: [JSON_FLAG],
35
46
  };
36
47
  // Every name is reserved on every Command, whatever flags it gets, so a name means one thing.
37
- const RESERVED = new Map([...ROUTING_FLAGS, ...EFFECT_FLAGS.destructive.map(({ flag }) => flag), ...LIST_FLAGS].map((flag) => [nameOf(flag), flag]));
38
- /** The Standard flags of a Command with this Effect, and of a List Command. */
39
- export function standardFlagsFor(effect, list) {
40
- return [...EFFECT_FLAGS[effect], ...(list?.standardFlags ?? [])];
48
+ const RESERVED = new Map([
49
+ ...ROUTING_FLAGS,
50
+ ...EFFECT_FLAGS.destructive.map(({ flag }) => flag),
51
+ YES_FLAG.flag,
52
+ FORCE_FLAG.flag,
53
+ ...LIST_FLAGS,
54
+ ].map((flag) => [nameOf(flag), flag]));
55
+ /** The Standard flags of a Command with this Effect and declarations, and of a List Command. */
56
+ export function standardFlagsFor(effect, { outputs, cost }, list) {
57
+ return [
58
+ ...EFFECT_FLAGS[effect],
59
+ ...(outputs ? [FORCE_FLAG] : []),
60
+ ...(cost ? [YES_FLAG] : []),
61
+ ...(list?.standardFlags ?? []),
62
+ ];
41
63
  }
42
64
  /** Throws when the Command declares an arg or option under a Standard flag's name. */
43
65
  export function checkNoStandardFlags(command) {