@ykdz/template 0.0.37 → 0.0.40

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 (225) hide show
  1. package/dist/application.d.ts +1 -52
  2. package/dist/application.js +0 -81
  3. package/dist/cli.js +14 -28
  4. package/dist/input-schemas.d.ts +30 -0
  5. package/dist/input-schemas.js +75 -0
  6. package/dist/main.d.ts +3 -14
  7. package/dist/main.js +496 -378
  8. package/dist/result-schemas.d.ts +222 -0
  9. package/dist/result-schemas.js +74 -0
  10. package/dist/standard-schema.d.ts +3 -0
  11. package/dist/standard-schema.js +29 -0
  12. package/node_modules/@standard-schema/spec/LICENSE +21 -0
  13. package/node_modules/@standard-schema/spec/README.md +198 -0
  14. package/node_modules/@standard-schema/spec/dist/index.cjs +18 -0
  15. package/node_modules/@standard-schema/spec/dist/index.d.cts +119 -0
  16. package/node_modules/@standard-schema/spec/dist/index.d.ts +119 -0
  17. package/node_modules/@standard-schema/spec/dist/index.js +0 -0
  18. package/node_modules/@standard-schema/spec/package.json +52 -0
  19. package/node_modules/@types/node/LICENSE +21 -0
  20. package/node_modules/@types/node/README.md +15 -0
  21. package/node_modules/@types/node/assert/strict.d.ts +111 -0
  22. package/node_modules/@types/node/assert.d.ts +1115 -0
  23. package/node_modules/@types/node/async_hooks.d.ts +619 -0
  24. package/node_modules/@types/node/buffer.buffer.d.ts +477 -0
  25. package/node_modules/@types/node/buffer.d.ts +1941 -0
  26. package/node_modules/@types/node/child_process.d.ts +1480 -0
  27. package/node_modules/@types/node/cluster.d.ts +578 -0
  28. package/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  29. package/node_modules/@types/node/console.d.ts +453 -0
  30. package/node_modules/@types/node/constants.d.ts +21 -0
  31. package/node_modules/@types/node/crypto.d.ts +5484 -0
  32. package/node_modules/@types/node/dgram.d.ts +715 -0
  33. package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  34. package/node_modules/@types/node/dns/promises.d.ts +503 -0
  35. package/node_modules/@types/node/dns.d.ts +923 -0
  36. package/node_modules/@types/node/domain.d.ts +166 -0
  37. package/node_modules/@types/node/events.d.ts +967 -0
  38. package/node_modules/@types/node/fs/promises.d.ts +1354 -0
  39. package/node_modules/@types/node/fs.d.ts +4777 -0
  40. package/node_modules/@types/node/globals.d.ts +170 -0
  41. package/node_modules/@types/node/globals.typedarray.d.ts +41 -0
  42. package/node_modules/@types/node/http.d.ts +2246 -0
  43. package/node_modules/@types/node/http2.d.ts +2882 -0
  44. package/node_modules/@types/node/https.d.ts +585 -0
  45. package/node_modules/@types/node/index.d.ts +101 -0
  46. package/node_modules/@types/node/inspector.d.ts +323 -0
  47. package/node_modules/@types/node/inspector.generated.d.ts +4406 -0
  48. package/node_modules/@types/node/module.d.ts +844 -0
  49. package/node_modules/@types/node/net.d.ts +1197 -0
  50. package/node_modules/@types/node/os.d.ts +507 -0
  51. package/node_modules/@types/node/package.json +140 -0
  52. package/node_modules/@types/node/path.d.ts +200 -0
  53. package/node_modules/@types/node/perf_hooks.d.ts +1054 -0
  54. package/node_modules/@types/node/process.d.ts +2101 -0
  55. package/node_modules/@types/node/punycode.d.ts +117 -0
  56. package/node_modules/@types/node/querystring.d.ts +152 -0
  57. package/node_modules/@types/node/readline/promises.d.ts +161 -0
  58. package/node_modules/@types/node/readline.d.ts +600 -0
  59. package/node_modules/@types/node/repl.d.ts +438 -0
  60. package/node_modules/@types/node/sea.d.ts +162 -0
  61. package/node_modules/@types/node/sqlite.d.ts +1182 -0
  62. package/node_modules/@types/node/stream/consumers.d.ts +45 -0
  63. package/node_modules/@types/node/stream/promises.d.ts +90 -0
  64. package/node_modules/@types/node/stream/web.d.ts +596 -0
  65. package/node_modules/@types/node/stream.d.ts +1707 -0
  66. package/node_modules/@types/node/string_decoder.d.ts +67 -0
  67. package/node_modules/@types/node/test.d.ts +2656 -0
  68. package/node_modules/@types/node/timers/promises.d.ts +108 -0
  69. package/node_modules/@types/node/timers.d.ts +285 -0
  70. package/node_modules/@types/node/tls.d.ts +1314 -0
  71. package/node_modules/@types/node/trace_events.d.ts +197 -0
  72. package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +473 -0
  73. package/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  74. package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  75. package/node_modules/@types/node/ts5.6/index.d.ts +103 -0
  76. package/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  77. package/node_modules/@types/node/ts5.7/index.d.ts +103 -0
  78. package/node_modules/@types/node/tty.d.ts +209 -0
  79. package/node_modules/@types/node/url.d.ts +1103 -0
  80. package/node_modules/@types/node/util.d.ts +2376 -0
  81. package/node_modules/@types/node/v8.d.ts +1010 -0
  82. package/node_modules/@types/node/vm.d.ts +1160 -0
  83. package/node_modules/@types/node/wasi.d.ts +202 -0
  84. package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
  85. package/node_modules/@types/node/web-globals/crypto.d.ts +32 -0
  86. package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  87. package/node_modules/@types/node/web-globals/events.d.ts +97 -0
  88. package/node_modules/@types/node/web-globals/fetch.d.ts +62 -0
  89. package/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  90. package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  91. package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
  92. package/node_modules/@types/node/worker_threads.d.ts +894 -0
  93. package/node_modules/@types/node/zlib.d.ts +768 -0
  94. package/node_modules/@valibot/to-json-schema/LICENSE.md +9 -0
  95. package/node_modules/@valibot/to-json-schema/README.md +475 -0
  96. package/node_modules/@valibot/to-json-schema/dist/index.cjs +800 -0
  97. package/node_modules/@valibot/to-json-schema/dist/index.d.cts +991 -0
  98. package/node_modules/@valibot/to-json-schema/dist/index.d.mts +991 -0
  99. package/node_modules/@valibot/to-json-schema/dist/index.min.cjs +1 -0
  100. package/node_modules/@valibot/to-json-schema/dist/index.min.mjs +1 -0
  101. package/node_modules/@valibot/to-json-schema/dist/index.mjs +795 -0
  102. package/node_modules/@valibot/to-json-schema/package.json +75 -0
  103. package/node_modules/@ykdz/cli-contract/LICENSE +21 -0
  104. package/node_modules/@ykdz/cli-contract/dist/atomic-variant-compiler.d.ts +17 -0
  105. package/node_modules/@ykdz/cli-contract/dist/atomic-variant-compiler.js +55 -0
  106. package/node_modules/@ykdz/cli-contract/dist/cli-contract.d.ts +1164 -0
  107. package/node_modules/@ykdz/cli-contract/dist/cli-contract.js +1408 -0
  108. package/node_modules/@ykdz/cli-contract/dist/cli-execution.d.ts +54 -0
  109. package/node_modules/@ykdz/cli-contract/dist/cli-execution.js +708 -0
  110. package/node_modules/@ykdz/cli-contract/dist/cli-invocation.d.ts +174 -0
  111. package/node_modules/@ykdz/cli-contract/dist/cli-invocation.js +524 -0
  112. package/node_modules/@ykdz/cli-contract/dist/cli-write-error.d.ts +10 -0
  113. package/node_modules/@ykdz/cli-contract/dist/cli-write-error.js +14 -0
  114. package/node_modules/@ykdz/cli-contract/dist/contract-definition-error.d.ts +260 -0
  115. package/node_modules/@ykdz/cli-contract/dist/contract-definition-error.js +130 -0
  116. package/node_modules/@ykdz/cli-contract/dist/contract-execution-error.d.ts +63 -0
  117. package/node_modules/@ykdz/cli-contract/dist/contract-execution-error.js +17 -0
  118. package/node_modules/@ykdz/cli-contract/dist/contract-schema-compiler.d.ts +6 -0
  119. package/node_modules/@ykdz/cli-contract/dist/contract-schema-compiler.js +532 -0
  120. package/node_modules/@ykdz/cli-contract/dist/contract-schema.d.ts +14 -0
  121. package/node_modules/@ykdz/cli-contract/dist/contract-schema.js +1 -0
  122. package/node_modules/@ykdz/cli-contract/dist/description.d.ts +2 -0
  123. package/node_modules/@ykdz/cli-contract/dist/description.js +13 -0
  124. package/node_modules/@ykdz/cli-contract/dist/index.d.ts +8 -0
  125. package/node_modules/@ykdz/cli-contract/dist/index.js +7 -0
  126. package/node_modules/@ykdz/cli-contract/dist/json-value.d.ts +4 -0
  127. package/node_modules/@ykdz/cli-contract/dist/json-value.js +64 -0
  128. package/node_modules/@ykdz/cli-contract/dist/node.d.ts +21 -0
  129. package/node_modules/@ykdz/cli-contract/dist/node.js +109 -0
  130. package/node_modules/@ykdz/cli-contract/dist/outcome-fact.d.ts +162 -0
  131. package/node_modules/@ykdz/cli-contract/dist/outcome-fact.js +113 -0
  132. package/node_modules/@ykdz/cli-contract/dist/outcome-wire.d.ts +53 -0
  133. package/node_modules/@ykdz/cli-contract/dist/outcome-wire.js +189 -0
  134. package/node_modules/@ykdz/cli-contract/dist/stream-variant-compiler.d.ts +16 -0
  135. package/node_modules/@ykdz/cli-contract/dist/stream-variant-compiler.js +45 -0
  136. package/node_modules/@ykdz/cli-contract/package.json +69 -0
  137. package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +20 -0
  138. package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +27 -28
  139. package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.d.ts +19 -0
  140. package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.js +1 -1
  141. package/node_modules/@ykdz/template-builtin-presets/dist/src/index.d.ts +2 -1
  142. package/node_modules/@ykdz/template-builtin-presets/dist/src/index.js +2 -1
  143. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +9 -5
  144. package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +0 -4
  145. package/node_modules/@ykdz/template-builtin-presets/package.json +2 -1
  146. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/AGENTS.md.template +10 -4
  147. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/devcontainer.json +3 -0
  148. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/artifact.ts +128 -59
  149. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/handoff.ts +80 -8
  150. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +7 -3
  151. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli.ts +9 -19
  152. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/main.ts +144 -60
  153. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/standard-schema.ts +37 -0
  154. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/journeys/lookup.journey.ts +71 -0
  155. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +118 -59
  156. package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +0 -1
  157. package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +2 -1
  158. package/node_modules/@ykdz/template-core/dist/project-blueprint.d.ts +15 -0
  159. package/node_modules/@ykdz/template-core/dist/project-blueprint.js +1 -1
  160. package/node_modules/@ykdz/template-core/dist/project-github.d.ts +1 -1
  161. package/node_modules/undici-types/LICENSE +21 -0
  162. package/node_modules/undici-types/README.md +6 -0
  163. package/node_modules/undici-types/agent.d.ts +32 -0
  164. package/node_modules/undici-types/api.d.ts +43 -0
  165. package/node_modules/undici-types/balanced-pool.d.ts +30 -0
  166. package/node_modules/undici-types/cache-interceptor.d.ts +179 -0
  167. package/node_modules/undici-types/cache.d.ts +36 -0
  168. package/node_modules/undici-types/client-stats.d.ts +15 -0
  169. package/node_modules/undici-types/client.d.ts +123 -0
  170. package/node_modules/undici-types/connector.d.ts +36 -0
  171. package/node_modules/undici-types/content-type.d.ts +21 -0
  172. package/node_modules/undici-types/cookies.d.ts +30 -0
  173. package/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
  174. package/node_modules/undici-types/dispatcher.d.ts +279 -0
  175. package/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
  176. package/node_modules/undici-types/errors.d.ts +177 -0
  177. package/node_modules/undici-types/eventsource.d.ts +66 -0
  178. package/node_modules/undici-types/fetch.d.ts +211 -0
  179. package/node_modules/undici-types/formdata.d.ts +108 -0
  180. package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  181. package/node_modules/undici-types/global-origin.d.ts +7 -0
  182. package/node_modules/undici-types/h2c-client.d.ts +73 -0
  183. package/node_modules/undici-types/handlers.d.ts +15 -0
  184. package/node_modules/undici-types/header.d.ts +160 -0
  185. package/node_modules/undici-types/index.d.ts +91 -0
  186. package/node_modules/undici-types/interceptors.d.ts +80 -0
  187. package/node_modules/undici-types/mock-agent.d.ts +68 -0
  188. package/node_modules/undici-types/mock-call-history.d.ts +111 -0
  189. package/node_modules/undici-types/mock-client.d.ts +27 -0
  190. package/node_modules/undici-types/mock-errors.d.ts +12 -0
  191. package/node_modules/undici-types/mock-interceptor.d.ts +94 -0
  192. package/node_modules/undici-types/mock-pool.d.ts +27 -0
  193. package/node_modules/undici-types/package.json +55 -0
  194. package/node_modules/undici-types/patch.d.ts +29 -0
  195. package/node_modules/undici-types/pool-stats.d.ts +19 -0
  196. package/node_modules/undici-types/pool.d.ts +41 -0
  197. package/node_modules/undici-types/proxy-agent.d.ts +29 -0
  198. package/node_modules/undici-types/readable.d.ts +68 -0
  199. package/node_modules/undici-types/retry-agent.d.ts +8 -0
  200. package/node_modules/undici-types/retry-handler.d.ts +125 -0
  201. package/node_modules/undici-types/round-robin-pool.d.ts +41 -0
  202. package/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  203. package/node_modules/undici-types/socks5-proxy-agent.d.ts +25 -0
  204. package/node_modules/undici-types/util.d.ts +18 -0
  205. package/node_modules/undici-types/utility.d.ts +7 -0
  206. package/node_modules/undici-types/webidl.d.ts +347 -0
  207. package/node_modules/undici-types/websocket.d.ts +188 -0
  208. package/package.json +5 -3
  209. package/dist/command-result.d.ts +0 -9
  210. package/dist/command-result.js +0 -231
  211. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/journeys/greet.journey.ts +0 -46
  212. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/greet.test.ts +0 -15
  213. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/devcontainer/docker-client.Dockerfile +0 -3
  214. package/node_modules/commander/LICENSE +0 -22
  215. package/node_modules/commander/Readme.md +0 -1172
  216. package/node_modules/commander/index.js +0 -21
  217. package/node_modules/commander/lib/argument.js +0 -147
  218. package/node_modules/commander/lib/command.js +0 -2790
  219. package/node_modules/commander/lib/error.js +0 -36
  220. package/node_modules/commander/lib/help.js +0 -731
  221. package/node_modules/commander/lib/option.js +0 -377
  222. package/node_modules/commander/lib/suggestSimilar.js +0 -99
  223. package/node_modules/commander/package-support.json +0 -19
  224. package/node_modules/commander/package.json +0 -64
  225. package/node_modules/commander/typings/index.d.ts +0 -1113
@@ -0,0 +1,708 @@
1
+ import { createCompletionFact, createDataFact, createFailureFact, createStreamRecordFact, createStreamSuccessFact, formatFieldUsage, getCompiledCli, isCompiledExecutable, isIssuedOutcomeFact, usageFailureHelpArgv, } from "#/cli-contract";
2
+ import { invocationBelongsTo, } from "#/cli-invocation";
3
+ import { CliWriteError } from "#/cli-write-error";
4
+ import { ContractExecutionError, } from "#/contract-execution-error";
5
+ import { copyJsonValue } from "#/json-value";
6
+ import { isIssuedTextProjection } from "#/outcome-fact";
7
+ import { createCompletionEnvelope, createDataEnvelope, createFailureEnvelope, createStreamHeaderEnvelope, createStreamRecordEnvelope, createStreamSuccessEnvelope, createUsageFailureEnvelope, } from "#/outcome-wire";
8
+ /**
9
+ * 执行同一契约签发的调用:验证 raw input,将模式的验证结果和宿主依赖交给 handler,
10
+ * 再验证、投影结果并顺序等待宿主写入。帮助、版本和用法失败不执行业务 handler。
11
+ *
12
+ * 宿主负责参数来源、依赖构造、输出端口和真实进程退出;应 await 本函数,
13
+ * 等可控写入完成后再使用终止结果的 exitCode,不能提前结束进程。
14
+ *
15
+ * 消费者模式、handler、generator 或呈现器抛出的值保留原始身份;核心检测的契约违反
16
+ * 使用 ContractExecutionError,输出端口失败使用 CliWriteError。执行拒绝时不自动写诊断,
17
+ * 活动流会执行必要清理,已经写出的合法前缀不会撤回,也不会追加伪造的成功终态。
18
+ */
19
+ // oxlint-disable-next-line typescript/consistent-return
20
+ export async function executeCli(cliContract, options) {
21
+ const compiled = getCompiledCli(cliContract);
22
+ if (!invocationBelongsTo(options.invocation, cliContract)) {
23
+ throw new ContractExecutionError([
24
+ {
25
+ code: "invocationContractMismatch",
26
+ expectedCommand: compiled.root,
27
+ receivedCommand: options.invocation.command,
28
+ },
29
+ ]);
30
+ }
31
+ const command = compiled.commands[options.invocation.command];
32
+ if (command === undefined) {
33
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
34
+ }
35
+ switch (options.invocation.kind) {
36
+ case "help": {
37
+ await writeCliOutput(options.write, {
38
+ destination: "stdout",
39
+ chunk: createHelpText(compiled, command),
40
+ });
41
+ return Object.freeze({
42
+ kind: "help",
43
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
44
+ command: command.id,
45
+ exitCode: 0,
46
+ });
47
+ }
48
+ case "version": {
49
+ const version = compiled.contract.grammar.controls.version;
50
+ if (version === undefined) {
51
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
52
+ }
53
+ await writeCliOutput(options.write, {
54
+ destination: "stdout",
55
+ chunk: `${version.value}\n`,
56
+ });
57
+ return Object.freeze({
58
+ kind: "version",
59
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
60
+ command: command.id,
61
+ exitCode: 0,
62
+ });
63
+ }
64
+ case "usageFailure": {
65
+ await writeUsageFailure(compiled, options.write, {
66
+ command: command.id,
67
+ issues: options.invocation.issues,
68
+ usage: options.invocation.usage.synopsis,
69
+ });
70
+ return Object.freeze({
71
+ kind: "usageFailure",
72
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 命令来自当前 Contract 的编译树,泛型身份在此恢复。
73
+ command: command.id,
74
+ issues: options.invocation.issues,
75
+ exitCode: compiled.usageFailureExitCode,
76
+ });
77
+ }
78
+ case "parsed": {
79
+ if (!isCompiledExecutable(command)) {
80
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
81
+ }
82
+ const validation = validateSynchronously(command.input, options.invocation.input, { command: command.id, location: "input" });
83
+ if (validation.issues !== undefined) {
84
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
85
+ const issues = Object.freeze([
86
+ Object.freeze({
87
+ code: "inputRejected",
88
+ evidence: Object.freeze(validation.issues.map(normalizeSchemaIssueEvidence)),
89
+ }),
90
+ ]);
91
+ await writeUsageFailure(compiled, options.write, {
92
+ command: command.id,
93
+ issues,
94
+ usage: command.usage.synopsis,
95
+ });
96
+ return Object.freeze({
97
+ kind: "usageFailure",
98
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 命令来自当前 Contract 的编译树,泛型身份在此恢复。
99
+ command: command.id,
100
+ issues,
101
+ exitCode: compiled.usageFailureExitCode,
102
+ });
103
+ }
104
+ return executeApplicationResult(command, validation.value, options, options.invocation.outputFormat);
105
+ }
106
+ }
107
+ }
108
+ function createHelpText(compiled, command) {
109
+ const headings = compiled.contract.grammar.controls.help.headings;
110
+ const wording = compiled.contract.grammar.controls.help.wording;
111
+ const segments = [command.description];
112
+ const commands = Object.values(compiled.commands).filter((candidate) => candidate.parent === command.id);
113
+ const fields = isCommandGroup(command) ? [] : command.fields;
114
+ const usageConstraints = isCommandGroup(command)
115
+ ? []
116
+ : command.usageConstraints;
117
+ const positionalFields = fields.filter((field) => field.kind === "positional" || field.kind === "variadicPositional");
118
+ const optionFields = fields.filter((field) => field.kind !== "positional" && field.kind !== "variadicPositional");
119
+ const options = [
120
+ ...optionFields.map((field) => formatHelpField(field, wording)),
121
+ ...formatCoreControls(compiled),
122
+ ];
123
+ appendHelpSegment(segments, headings?.usage, [
124
+ helpLine(command.usage.synopsis),
125
+ ]);
126
+ appendHelpSegment(segments, headings?.commands, commands.map((candidate) => helpDetail(`${[candidate.name, ...candidate.aliases].join(", ")}${isCommandGroup(candidate) ? ` <${requireHelpFactWording(wording?.commandPlaceholder)}>` : ""}`, candidate.description)));
127
+ appendHelpSegment(segments, headings?.arguments, positionalFields.map((field) => formatHelpField(field, wording)));
128
+ appendHelpSegment(segments, headings?.options, options);
129
+ appendHelpSegment(segments, headings?.constraints, usageConstraints.map((constraint) => helpLine(formatUsageConstraint(constraint, wording))));
130
+ appendHelpSegment(segments, headings?.supplement, command.helpSupplement === undefined
131
+ ? []
132
+ : [{ kind: "lines", lines: command.helpSupplement }]);
133
+ return `${segments.join("\n\n")}\n`;
134
+ }
135
+ function isCommandGroup(command) {
136
+ return command.kind === "rootGroup" || command.kind === "commandGroup";
137
+ }
138
+ function helpLine(value) {
139
+ return { kind: "line", value };
140
+ }
141
+ function helpDetail(summary, detail) {
142
+ return { kind: "detail", summary, detail };
143
+ }
144
+ function appendHelpSegment(segments, heading, entries) {
145
+ if (entries.length === 0)
146
+ return;
147
+ const lines = heading === undefined ? [] : [heading];
148
+ for (const entry of entries) {
149
+ if (entry.kind === "line")
150
+ lines.push(` ${entry.value}`);
151
+ else if (entry.kind === "detail")
152
+ lines.push(` ${entry.summary}`, ` ${entry.detail}`);
153
+ else
154
+ lines.push(...entry.lines.map((line) => (line === "" ? "" : ` ${line}`)));
155
+ }
156
+ segments.push(lines.join("\n"));
157
+ }
158
+ function formatCoreControls(compiled) {
159
+ const help = compiled.contract.grammar.controls.help;
160
+ const version = compiled.contract.grammar.controls.version;
161
+ const output = compiled.contract.grammar.controls.output;
162
+ const versionEntry = version === undefined
163
+ ? undefined
164
+ : version.description === undefined
165
+ ? helpLine([version.longOption, version.shortAlias]
166
+ .filter((spelling) => spelling !== undefined)
167
+ .join(", "))
168
+ : helpDetail([version.longOption, version.shortAlias]
169
+ .filter((spelling) => spelling !== undefined)
170
+ .join(", "), version.description);
171
+ return [
172
+ helpLine([help.longOption, help.shortAlias]
173
+ .filter((spelling) => spelling !== undefined)
174
+ .join(", ")),
175
+ ...(versionEntry === undefined ? [] : [versionEntry]),
176
+ ...(output.selector === undefined
177
+ ? []
178
+ : [
179
+ helpLine(`${output.selector} <${output.formats.join("|")}> ${renderHelpFactTemplate(help.wording?.choices, { choices: output.formats.map((format) => JSON.stringify(format)).join(", ") })} ${renderHelpFactTemplate(help.wording?.default, { value: JSON.stringify(output.defaultFormat) })}`),
180
+ ]),
181
+ ...Object.entries(output.compatibilityFlags ?? {}).map(([flag, format]) => helpLine(output.selector === undefined
182
+ ? `${flag} = ${format}`
183
+ : `${flag} = ${output.selector} ${format}`)),
184
+ ];
185
+ }
186
+ async function writeUsageFailure(compiled, write, failure) {
187
+ await writeCliOutput(write, {
188
+ destination: "stderr",
189
+ chunk: `${JSON.stringify(createUsageFailureEnvelope(failure.command, failure.issues, failure.usage, usageFailureHelpArgv(compiled.commands, failure.command)))}\n`,
190
+ });
191
+ }
192
+ function formatUsageConstraint(constraint, wording) {
193
+ if (constraint.kind === "requires")
194
+ return renderHelpFactTemplate(wording?.requires, {
195
+ field: constraint.field,
196
+ requires: constraint.requires,
197
+ });
198
+ if (constraint.kind === "exclusive")
199
+ return renderHelpFactTemplate(wording?.exclusive, {
200
+ fields: constraint.fields.join(", "),
201
+ });
202
+ return renderHelpFactTemplate(wording?.forbiddenCombination, {
203
+ values: constraint.values
204
+ .map(({ field, value }) => `${field}=${JSON.stringify(value)}`)
205
+ .join(", "),
206
+ });
207
+ }
208
+ function renderHelpFactTemplate(template, values) {
209
+ const factTemplate = requireHelpFactWording(template);
210
+ return factTemplate.replace(/\{([A-Za-z][A-Za-z0-9]*)\}/g, (_match, key) => {
211
+ const value = values[key];
212
+ if (value === undefined) {
213
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
214
+ }
215
+ return value;
216
+ });
217
+ }
218
+ function requireHelpFactWording(value) {
219
+ if (value === undefined) {
220
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
221
+ }
222
+ return value;
223
+ }
224
+ function formatHelpField(field, wording) {
225
+ const cardinality = formatFieldUsage(field, true);
226
+ const choices = field.choices === undefined
227
+ ? ""
228
+ : ` ${renderHelpFactTemplate(wording?.choices, { choices: field.choices.map((choice) => JSON.stringify(choice)).join(", ") })}`;
229
+ const defaultValue = field.default === undefined
230
+ ? ""
231
+ : ` ${renderHelpFactTemplate(wording?.default, { value: JSON.stringify(field.default) })}`;
232
+ return helpDetail(`${cardinality}${choices}${defaultValue}`, field.description);
233
+ }
234
+ async function executeApplicationResult(compiled, input, options, outputFormat) {
235
+ const issuedOutcomeFacts = new WeakSet();
236
+ const successOutcome = compiled.success.kind === "completion"
237
+ ? {
238
+ completion: () => createCompletionFact(compiled.id, issuedOutcomeFacts),
239
+ }
240
+ : compiled.success.kind === "data"
241
+ ? {
242
+ data: Object.freeze(Object.fromEntries(Object.keys(compiled.success.variants).map((variant) => [
243
+ variant,
244
+ (payload) => createDataFact(compiled.id, variant, payload, issuedOutcomeFacts),
245
+ ]))),
246
+ }
247
+ : {
248
+ record: Object.freeze(Object.fromEntries(Object.keys(compiled.success.records).map((variant) => [
249
+ variant,
250
+ (payload) => createStreamRecordFact(compiled.id, variant, payload, issuedOutcomeFacts),
251
+ ]))),
252
+ streamSuccess: () => createStreamSuccessFact(compiled.id, issuedOutcomeFacts),
253
+ };
254
+ const outcome = Object.freeze({
255
+ ...successOutcome,
256
+ failure: Object.freeze(Object.fromEntries(Object.keys(compiled.failures).map((variant) => [
257
+ variant,
258
+ (payload) => createFailureFact(compiled.id, variant, payload, issuedOutcomeFacts),
259
+ ]))),
260
+ });
261
+ if (typeof compiled.handler !== "function") {
262
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
263
+ }
264
+ const handlerResult = compiled.handler({
265
+ input,
266
+ dependencies: options.dependencies,
267
+ outcome,
268
+ });
269
+ if (compiled.success.kind === "stream") {
270
+ const generator = requireAsyncGenerator(handlerResult, compiled.id);
271
+ return executeStreamResult(compiled, generator, issuedOutcomeFacts, options, outputFormat);
272
+ }
273
+ const result = await handlerResult;
274
+ const projected = projectApplicationFact(compiled, result, issuedOutcomeFacts, outputFormat, "atomic");
275
+ await writeProjectedOutput(options.write, projected.output);
276
+ return Object.freeze({
277
+ kind: "applicationResult",
278
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 命令来自当前 Contract 的编译树,泛型身份在此恢复。
279
+ command: compiled.id,
280
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 结果经该命令的结果模式验证并由本次执行签发。
281
+ result: projected.result,
282
+ exitCode: projected.exitCode,
283
+ });
284
+ }
285
+ function requireAsyncGenerator(value, command) {
286
+ if (!hasAsyncGeneratorProtocol(value)) {
287
+ throwExecutionIssue({
288
+ code: "streamHandlerMustReturnAsyncGenerator",
289
+ command,
290
+ });
291
+ }
292
+ return value;
293
+ }
294
+ function hasAsyncGeneratorProtocol(value) {
295
+ try {
296
+ return (typeof value === "object" &&
297
+ value !== null &&
298
+ Symbol.asyncIterator in value &&
299
+ typeof value[Symbol.asyncIterator] === "function" &&
300
+ "next" in value &&
301
+ typeof value.next === "function" &&
302
+ "return" in value &&
303
+ typeof value.return === "function");
304
+ }
305
+ catch {
306
+ return false;
307
+ }
308
+ }
309
+ async function writeCliOutput(write, output) {
310
+ try {
311
+ await write(output);
312
+ }
313
+ catch (cause) {
314
+ throw new CliWriteError(output.destination, cause);
315
+ }
316
+ }
317
+ async function executeStreamResult(compiled, generator, issuedOutcomeFacts, options, outputFormat) {
318
+ if (compiled.success.kind !== "stream") {
319
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
320
+ }
321
+ let active = true;
322
+ try {
323
+ if (outputFormat === "structured") {
324
+ await writeCliOutput(options.write, {
325
+ destination: "stdout",
326
+ chunk: `${JSON.stringify(createStreamHeaderEnvelope(compiled.id))}\n`,
327
+ });
328
+ }
329
+ for (;;) {
330
+ const step = await generator.next();
331
+ if (!step.done) {
332
+ const projected = projectApplicationFact(compiled, step.value, issuedOutcomeFacts, outputFormat, "record");
333
+ await writeProjectedOutput(options.write, projected.output);
334
+ continue;
335
+ }
336
+ active = false;
337
+ const projected = projectApplicationFact(compiled, step.value, issuedOutcomeFacts, outputFormat, "terminal");
338
+ await writeProjectedOutput(options.write, projected.output);
339
+ return Object.freeze({
340
+ kind: "applicationResult",
341
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 命令来自当前 Contract 的编译树,泛型身份在此恢复。
342
+ command: compiled.id,
343
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 结果经该命令的结果模式验证并由本次执行签发。
344
+ result: projected.result,
345
+ exitCode: projected.exitCode,
346
+ });
347
+ }
348
+ }
349
+ catch (cause) {
350
+ if (active && typeof generator.return === "function") {
351
+ try {
352
+ await generator.return(undefined);
353
+ }
354
+ catch {
355
+ // 清理异常不能掩盖触发中断的写入或程序缺陷。
356
+ }
357
+ }
358
+ throw cause;
359
+ }
360
+ }
361
+ async function writeProjectedOutput(write, output) {
362
+ if (output !== undefined)
363
+ await writeCliOutput(write, output);
364
+ }
365
+ function projectApplicationFact(compiled, value, issuedOutcomeFacts, outputFormat, phase) {
366
+ if (!isIssuedOutcomeFact(value, issuedOutcomeFacts)) {
367
+ throwExecutionIssue({ code: "invalidOutcomeFact", command: compiled.id });
368
+ }
369
+ const result = value;
370
+ if (phase === "record") {
371
+ if (result.kind !== "record" || compiled.success.kind !== "stream") {
372
+ throwExecutionIssue({
373
+ code: "outcomeKindMismatch",
374
+ command: compiled.id,
375
+ expected: "stream",
376
+ received: result.kind,
377
+ });
378
+ }
379
+ const record = compiled.success.records[result.variant];
380
+ if (record === undefined) {
381
+ throwExecutionIssue({
382
+ code: "undeclaredOutcomeVariant",
383
+ command: compiled.id,
384
+ location: "record",
385
+ variant: result.variant,
386
+ });
387
+ }
388
+ const data = projectAtomicData(record.schema, result.data, {
389
+ command: compiled.id,
390
+ location: "record",
391
+ variant: result.variant,
392
+ });
393
+ const chunk = outputFormat === "structured"
394
+ ? `${JSON.stringify(createStreamRecordEnvelope(result.variant, data))}\n`
395
+ : formatStreamRecordText(record.text, data);
396
+ return { result, output: { destination: "stdout", chunk }, exitCode: 0 };
397
+ }
398
+ if (phase === "terminal" && result.kind === "streamSuccess") {
399
+ if (compiled.success.kind !== "stream") {
400
+ throwExecutionIssue({
401
+ code: "outcomeKindMismatch",
402
+ command: compiled.id,
403
+ expected: "stream",
404
+ received: result.kind,
405
+ });
406
+ }
407
+ let chunk;
408
+ if (outputFormat === "structured")
409
+ chunk = `${JSON.stringify(createStreamSuccessEnvelope())}\n`;
410
+ else {
411
+ const presenter = compiled.success.text;
412
+ if (typeof presenter !== "function")
413
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
414
+ chunk = formatCompletionText(presenter());
415
+ }
416
+ return {
417
+ result,
418
+ output: chunk === "" ? undefined : { destination: "stdout", chunk },
419
+ exitCode: 0,
420
+ };
421
+ }
422
+ if (phase === "terminal" && result.kind !== "failure") {
423
+ throwExecutionIssue({
424
+ code: "outcomeKindMismatch",
425
+ command: compiled.id,
426
+ expected: "stream",
427
+ received: result.kind,
428
+ });
429
+ }
430
+ if (result.kind === "failure") {
431
+ const failure = compiled.failures[result.variant];
432
+ if (failure === undefined) {
433
+ throwExecutionIssue({
434
+ code: "undeclaredOutcomeVariant",
435
+ command: compiled.id,
436
+ location: "failure",
437
+ variant: result.variant,
438
+ });
439
+ }
440
+ const data = projectAtomicData(failure.schema, result.data, {
441
+ command: compiled.id,
442
+ location: "failure",
443
+ variant: result.variant,
444
+ });
445
+ const normalized = createFailureFact(compiled.id, result.variant, data, issuedOutcomeFacts);
446
+ if (outputFormat === "text") {
447
+ const presenter = failure.text;
448
+ if (typeof presenter !== "function") {
449
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
450
+ }
451
+ return {
452
+ result: normalized,
453
+ output: {
454
+ destination: "stderr",
455
+ chunk: formatAtomicText(presenter(data)),
456
+ },
457
+ exitCode: failure.exitCode,
458
+ };
459
+ }
460
+ return {
461
+ result: normalized,
462
+ output: {
463
+ destination: "stderr",
464
+ chunk: `${JSON.stringify(createFailureEnvelope(compiled.id, result.variant, data))}\n`,
465
+ },
466
+ exitCode: failure.exitCode,
467
+ };
468
+ }
469
+ if (compiled.success.kind === "completion") {
470
+ if (result.kind !== "completion") {
471
+ throwExecutionIssue({
472
+ code: "outcomeKindMismatch",
473
+ command: compiled.id,
474
+ expected: "completion",
475
+ received: result.kind,
476
+ });
477
+ }
478
+ if (outputFormat === "text") {
479
+ const presenter = compiled.success.text;
480
+ if (typeof presenter !== "function") {
481
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
482
+ }
483
+ const chunk = formatCompletionText(presenter());
484
+ return {
485
+ result,
486
+ output: chunk === "" ? undefined : { destination: "stdout", chunk },
487
+ exitCode: 0,
488
+ };
489
+ }
490
+ return {
491
+ result,
492
+ output: {
493
+ destination: "stdout",
494
+ chunk: `${JSON.stringify(createCompletionEnvelope(compiled.id))}\n`,
495
+ },
496
+ exitCode: 0,
497
+ };
498
+ }
499
+ if (compiled.success.kind !== "data" || result.kind !== "data") {
500
+ throwExecutionIssue({
501
+ code: "outcomeKindMismatch",
502
+ command: compiled.id,
503
+ expected: "data",
504
+ received: result.kind,
505
+ });
506
+ }
507
+ const variant = compiled.success.variants[result.variant];
508
+ if (variant === undefined) {
509
+ throwExecutionIssue({
510
+ code: "undeclaredOutcomeVariant",
511
+ command: compiled.id,
512
+ location: "data",
513
+ variant: result.variant,
514
+ });
515
+ }
516
+ const data = projectAtomicData(variant.schema, result.data, {
517
+ command: compiled.id,
518
+ location: "data",
519
+ variant: result.variant,
520
+ });
521
+ const normalized = createDataFact(compiled.id, result.variant, data, issuedOutcomeFacts);
522
+ if (outputFormat === "text") {
523
+ const presenter = variant.text;
524
+ if (typeof presenter !== "function") {
525
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
526
+ }
527
+ return {
528
+ result: normalized,
529
+ output: {
530
+ destination: "stdout",
531
+ chunk: formatAtomicText(presenter(data)),
532
+ },
533
+ exitCode: variant.exitCode,
534
+ };
535
+ }
536
+ return {
537
+ result: normalized,
538
+ output: {
539
+ destination: "stdout",
540
+ chunk: `${JSON.stringify(createDataEnvelope(compiled.id, result.variant, data))}\n`,
541
+ },
542
+ exitCode: variant.exitCode,
543
+ };
544
+ }
545
+ function formatCompletionText(value) {
546
+ if (isSilentText(value))
547
+ return "";
548
+ return formatAtomicText(value);
549
+ }
550
+ function formatTextLine(value) {
551
+ if (!isIssuedTextProjection(value) ||
552
+ value.kind !== "line" ||
553
+ typeof value.value !== "string" ||
554
+ value.value.length === 0 ||
555
+ value.value.includes("\r") ||
556
+ value.value.includes("\n") ||
557
+ value.value.includes("\0")) {
558
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
559
+ }
560
+ return `${value.value}\n`;
561
+ }
562
+ function formatAtomicText(value) {
563
+ if (isIssuedTextProjection(value) && value.kind === "lines") {
564
+ return formatTextLines(value.lines);
565
+ }
566
+ return formatTextLine(value);
567
+ }
568
+ function formatTextLines(value) {
569
+ if (!Array.isArray(value) ||
570
+ value.every((line) => typeof line === "string" && line.length === 0) ||
571
+ value.some((line) => typeof line !== "string" ||
572
+ line.includes("\r") ||
573
+ line.includes("\n") ||
574
+ line.includes("\0"))) {
575
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
576
+ }
577
+ return `${value.join("\n")}\n`;
578
+ }
579
+ function formatStreamRecordText(presenter, data) {
580
+ if (typeof presenter !== "function") {
581
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
582
+ }
583
+ const value = presenter(data);
584
+ if (isIssuedTextProjection(value) && value.kind === "fragment") {
585
+ if (typeof value.value !== "string" ||
586
+ value.value.length === 0 ||
587
+ value.value.includes("\0")) {
588
+ throw new ContractExecutionError([{ code: "invalidCliContract" }]);
589
+ }
590
+ return value.value;
591
+ }
592
+ return formatTextLine(value);
593
+ }
594
+ function isSilentText(value) {
595
+ return isIssuedTextProjection(value) && value.kind === "silent";
596
+ }
597
+ // oxlint-disable-next-line typescript/consistent-return -- 验证失败分支通过 throwExecutionIssue 以 never 终止。
598
+ function projectAtomicData(schema, value, target) {
599
+ const validation = validateSynchronously(schema, value, target);
600
+ if (validation.issues !== undefined) {
601
+ throwExecutionIssue({
602
+ code: "outputSchemaRejected",
603
+ ...target,
604
+ expected: "schemaAccepted",
605
+ received: "schemaRejected",
606
+ });
607
+ }
608
+ try {
609
+ return copyJsonValue(validation.value);
610
+ }
611
+ catch {
612
+ throwExecutionIssue({
613
+ code: "invalidJsonValue",
614
+ ...target,
615
+ expected: "jsonValue",
616
+ received: "nonJsonValue",
617
+ });
618
+ }
619
+ }
620
+ function validateSynchronously(schema, value, target) {
621
+ const result = schema["~standard"].validate(value);
622
+ if (isPromise(result)) {
623
+ throwExecutionIssue({
624
+ code: "asynchronousSchemaValidation",
625
+ ...target,
626
+ expected: "synchronousStandardResult",
627
+ received: "promise",
628
+ });
629
+ }
630
+ if (!isStandardResult(result)) {
631
+ throwExecutionIssue({
632
+ code: "invalidStandardResult",
633
+ ...target,
634
+ expected: "standardResult",
635
+ received: describeValueKind(result),
636
+ });
637
+ }
638
+ return result;
639
+ }
640
+ function describeValueKind(value) {
641
+ if (value === null)
642
+ return "null";
643
+ if (Array.isArray(value))
644
+ return "array";
645
+ return typeof value;
646
+ }
647
+ function throwExecutionIssue(issue) {
648
+ throw new ContractExecutionError([issue]);
649
+ }
650
+ function isStandardResult(value) {
651
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
652
+ return false;
653
+ }
654
+ if (!("issues" in value) || value.issues === undefined) {
655
+ return "value" in value;
656
+ }
657
+ return (!("value" in value) &&
658
+ Array.isArray(value.issues) &&
659
+ value.issues.length > 0 &&
660
+ value.issues.every(isStandardIssue));
661
+ }
662
+ function isStandardIssue(value) {
663
+ if (typeof value !== "object" ||
664
+ value === null ||
665
+ !("message" in value) ||
666
+ typeof value.message !== "string") {
667
+ return false;
668
+ }
669
+ if (!("path" in value) || value.path === undefined) {
670
+ return true;
671
+ }
672
+ return (Array.isArray(value.path) &&
673
+ value.path.every((segment) => {
674
+ const key = typeof segment === "object" && segment !== null && "key" in segment
675
+ ? segment.key
676
+ : segment;
677
+ return (typeof key === "string" ||
678
+ typeof key === "number" ||
679
+ typeof key === "symbol");
680
+ }));
681
+ }
682
+ function normalizeSchemaIssueEvidence(issue) {
683
+ const path = normalizeSchemaPath(issue.path);
684
+ return Object.freeze(path === undefined
685
+ ? { message: issue.message }
686
+ : { message: issue.message, path });
687
+ }
688
+ function normalizeSchemaPath(path) {
689
+ if (path === undefined) {
690
+ return undefined;
691
+ }
692
+ const normalized = [];
693
+ for (const segment of path) {
694
+ const key = typeof segment === "object" && segment !== null ? segment.key : segment;
695
+ if (typeof key !== "string" &&
696
+ !(typeof key === "number" && Number.isFinite(key))) {
697
+ return undefined;
698
+ }
699
+ normalized.push(key);
700
+ }
701
+ return Object.freeze(normalized);
702
+ }
703
+ function isPromise(value) {
704
+ return (typeof value === "object" &&
705
+ value !== null &&
706
+ "then" in value &&
707
+ typeof value.then === "function");
708
+ }