@ykdz/template 0.0.38 → 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 (220) 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 +5 -0
  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/package.json +2 -1
  145. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/AGENTS.md.template +3 -3
  146. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/artifact.ts +128 -59
  147. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/handoff.ts +80 -8
  148. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +7 -3
  149. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli.ts +9 -19
  150. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/main.ts +144 -60
  151. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/standard-schema.ts +37 -0
  152. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/journeys/lookup.journey.ts +71 -0
  153. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +118 -59
  154. package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +2 -1
  155. package/node_modules/@ykdz/template-core/dist/project-blueprint.d.ts +15 -0
  156. package/node_modules/@ykdz/template-core/dist/project-blueprint.js +1 -1
  157. package/node_modules/undici-types/LICENSE +21 -0
  158. package/node_modules/undici-types/README.md +6 -0
  159. package/node_modules/undici-types/agent.d.ts +32 -0
  160. package/node_modules/undici-types/api.d.ts +43 -0
  161. package/node_modules/undici-types/balanced-pool.d.ts +30 -0
  162. package/node_modules/undici-types/cache-interceptor.d.ts +179 -0
  163. package/node_modules/undici-types/cache.d.ts +36 -0
  164. package/node_modules/undici-types/client-stats.d.ts +15 -0
  165. package/node_modules/undici-types/client.d.ts +123 -0
  166. package/node_modules/undici-types/connector.d.ts +36 -0
  167. package/node_modules/undici-types/content-type.d.ts +21 -0
  168. package/node_modules/undici-types/cookies.d.ts +30 -0
  169. package/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
  170. package/node_modules/undici-types/dispatcher.d.ts +279 -0
  171. package/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
  172. package/node_modules/undici-types/errors.d.ts +177 -0
  173. package/node_modules/undici-types/eventsource.d.ts +66 -0
  174. package/node_modules/undici-types/fetch.d.ts +211 -0
  175. package/node_modules/undici-types/formdata.d.ts +108 -0
  176. package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  177. package/node_modules/undici-types/global-origin.d.ts +7 -0
  178. package/node_modules/undici-types/h2c-client.d.ts +73 -0
  179. package/node_modules/undici-types/handlers.d.ts +15 -0
  180. package/node_modules/undici-types/header.d.ts +160 -0
  181. package/node_modules/undici-types/index.d.ts +91 -0
  182. package/node_modules/undici-types/interceptors.d.ts +80 -0
  183. package/node_modules/undici-types/mock-agent.d.ts +68 -0
  184. package/node_modules/undici-types/mock-call-history.d.ts +111 -0
  185. package/node_modules/undici-types/mock-client.d.ts +27 -0
  186. package/node_modules/undici-types/mock-errors.d.ts +12 -0
  187. package/node_modules/undici-types/mock-interceptor.d.ts +94 -0
  188. package/node_modules/undici-types/mock-pool.d.ts +27 -0
  189. package/node_modules/undici-types/package.json +55 -0
  190. package/node_modules/undici-types/patch.d.ts +29 -0
  191. package/node_modules/undici-types/pool-stats.d.ts +19 -0
  192. package/node_modules/undici-types/pool.d.ts +41 -0
  193. package/node_modules/undici-types/proxy-agent.d.ts +29 -0
  194. package/node_modules/undici-types/readable.d.ts +68 -0
  195. package/node_modules/undici-types/retry-agent.d.ts +8 -0
  196. package/node_modules/undici-types/retry-handler.d.ts +125 -0
  197. package/node_modules/undici-types/round-robin-pool.d.ts +41 -0
  198. package/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  199. package/node_modules/undici-types/socks5-proxy-agent.d.ts +25 -0
  200. package/node_modules/undici-types/util.d.ts +18 -0
  201. package/node_modules/undici-types/utility.d.ts +7 -0
  202. package/node_modules/undici-types/webidl.d.ts +347 -0
  203. package/node_modules/undici-types/websocket.d.ts +188 -0
  204. package/package.json +5 -3
  205. package/dist/command-result.d.ts +0 -9
  206. package/dist/command-result.js +0 -231
  207. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/journeys/greet.journey.ts +0 -46
  208. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/greet.test.ts +0 -15
  209. package/node_modules/commander/LICENSE +0 -22
  210. package/node_modules/commander/Readme.md +0 -1172
  211. package/node_modules/commander/index.js +0 -21
  212. package/node_modules/commander/lib/argument.js +0 -147
  213. package/node_modules/commander/lib/command.js +0 -2790
  214. package/node_modules/commander/lib/error.js +0 -36
  215. package/node_modules/commander/lib/help.js +0 -731
  216. package/node_modules/commander/lib/option.js +0 -377
  217. package/node_modules/commander/lib/suggestSimilar.js +0 -99
  218. package/node_modules/commander/package-support.json +0 -19
  219. package/node_modules/commander/package.json +0 -64
  220. package/node_modules/commander/typings/index.d.ts +0 -1113
@@ -0,0 +1,109 @@
1
+ /** 完整示例:https://github.com/YKDZ/cli-contract/tree/v0.2.1/packages/example */
2
+ /// <reference types="node" preserve="true" />
3
+ /**
4
+ * 将调用方提供的 Writable 接到核心输出端口,按核心选择的 stdout/stderr 路由写入。
5
+ * 每次写入等待 callback;write 返回 false 时还等待 drain,以承接执行内核的顺序与背压。
6
+ *
7
+ * 适配器不读取全局 process,也不关闭流、设置退出状态或接管 CLI 框架生命周期。
8
+ * 宿主应等待 executeCli 完成,再处理退出;写入异常交回调用方,不自动忽略 EPIPE。
9
+ */
10
+ export function nodeCliOutput({ stdout, stderr, }) {
11
+ return (output) => writeNodeCliOutput(selectWritable(output, stdout, stderr));
12
+ }
13
+ /**
14
+ * 检查错误对象及其 cause 链是否携带 EPIPE,可用于识别 CliWriteError 保留的断管原因。
15
+ * 这里只检测断管,不吞掉异常、恢复写入或决定进程退出码;其他异常仍由宿主处理。
16
+ */
17
+ export function isNodeBrokenPipe(error) {
18
+ const seen = new Set();
19
+ let current = error;
20
+ while (isObject(current) && !seen.has(current)) {
21
+ seen.add(current);
22
+ if (readProperty(current, "code") === "EPIPE")
23
+ return true;
24
+ current = readProperty(current, "cause");
25
+ }
26
+ return false;
27
+ }
28
+ function selectWritable(output, stdout, stderr) {
29
+ return {
30
+ writable: output.destination === "stdout" ? stdout : stderr,
31
+ chunk: output.chunk,
32
+ };
33
+ }
34
+ function writeNodeCliOutput({ writable, chunk, }) {
35
+ return new Promise((resolve, reject) => {
36
+ let settled = false;
37
+ let writeReturned = false;
38
+ let waitingForDrain = false;
39
+ let drainObserved = false;
40
+ let callbackObserved = false;
41
+ const cleanup = () => {
42
+ writable.removeListener("drain", onDrain);
43
+ writable.removeListener("error", onError);
44
+ };
45
+ const settle = (error, deferErrorCleanup = false) => {
46
+ if (settled)
47
+ return;
48
+ settled = true;
49
+ if (deferErrorCleanup) {
50
+ writable.removeListener("drain", onDrain);
51
+ queueMicrotask(cleanup);
52
+ }
53
+ else {
54
+ cleanup();
55
+ }
56
+ if (error === undefined || error === null)
57
+ resolve();
58
+ else
59
+ reject(error);
60
+ };
61
+ const completeWhenReady = () => {
62
+ if (writeReturned &&
63
+ callbackObserved &&
64
+ (!waitingForDrain || drainObserved)) {
65
+ settle();
66
+ }
67
+ };
68
+ const onDrain = () => {
69
+ drainObserved = true;
70
+ completeWhenReady();
71
+ };
72
+ const onError = (error) => {
73
+ if (settled) {
74
+ cleanup();
75
+ return;
76
+ }
77
+ settle(error);
78
+ };
79
+ const onCallback = (error) => {
80
+ if (error !== undefined && error !== null) {
81
+ settle(error, true);
82
+ return;
83
+ }
84
+ callbackObserved = true;
85
+ completeWhenReady();
86
+ };
87
+ writable.once("drain", onDrain);
88
+ writable.once("error", onError);
89
+ try {
90
+ waitingForDrain = !writable.write(chunk, onCallback);
91
+ writeReturned = true;
92
+ completeWhenReady();
93
+ }
94
+ catch (error) {
95
+ settle(error);
96
+ }
97
+ });
98
+ }
99
+ function isObject(value) {
100
+ return typeof value === "object" && value !== null;
101
+ }
102
+ function readProperty(value, key) {
103
+ try {
104
+ return Reflect.get(value, key);
105
+ }
106
+ catch {
107
+ return undefined;
108
+ }
109
+ }
@@ -0,0 +1,162 @@
1
+ import type { ContractSchema } from "#/contract-schema";
2
+ declare const outcomeFactType: unique symbol;
3
+ declare const textProjectionType: unique symbol;
4
+ export interface TextLine {
5
+ readonly kind: "line";
6
+ readonly value: string;
7
+ readonly [textProjectionType]: true;
8
+ }
9
+ export interface TextLines {
10
+ readonly kind: "lines";
11
+ readonly lines: readonly string[];
12
+ readonly [textProjectionType]: true;
13
+ }
14
+ export interface SilentText {
15
+ readonly kind: "silent";
16
+ readonly [textProjectionType]: true;
17
+ }
18
+ export interface TextFragment {
19
+ readonly kind: "fragment";
20
+ readonly value: string;
21
+ readonly [textProjectionType]: true;
22
+ }
23
+ export type CompletionTextPresenter = () => TextLine | TextLines | SilentText;
24
+ export type AtomicTextPresenter<Payload> = {
25
+ bivarianceHack(payload: Payload): TextLine | TextLines;
26
+ }["bivarianceHack"];
27
+ export type StreamTextPresenter<Payload> = {
28
+ bivarianceHack(payload: Payload): TextLine | TextFragment;
29
+ }["bivarianceHack"];
30
+ declare function createTextLine(value: string): TextLine;
31
+ declare function createTextLines(values: readonly [string, ...string[]]): TextLines;
32
+ declare function createTextFragment(value: string): TextFragment;
33
+ /** 在呈现器中显式构造文本投影;这里只验证文本值,实际通道路由与分帧由执行内核负责。 */
34
+ export declare const text: Readonly<{
35
+ /**
36
+ * 构造非空单行,拒绝 CR、LF、NUL;核心写出时追加恰好一个 LF。
37
+ * 适用于原子结果、流记录及流成功终态,呈现器应提供完整文本而不依赖核心补写文案。
38
+ */
39
+ line: typeof createTextLine;
40
+ /**
41
+ * 构造有序行组,至少一行非空;每行拒绝 CR、LF、NUL,空成员显式保留空白行。
42
+ * 核心用 LF 连接并追加一个终止 LF。用于原子结果、失败、流成功终态或帮助补充,
43
+ * 不用于流记录;例如 text.lines(["处理完成", "", "详细说明"])。
44
+ */
45
+ lines: typeof createTextLines;
46
+ /**
47
+ * 仅用于流记录中需要连续拼接的增量文本;必须非空且不含 NUL,可以含换行。
48
+ * 核心原样写出,不追加 LF,因此不承诺一行对应一条记录。
49
+ */
50
+ fragment: typeof createTextFragment;
51
+ /**
52
+ * completion 成功或流成功终态显式选择不写文本字节;仍须由呈现器返回此值。
53
+ * 省略呈现器不等于静默,data、failure 和流记录也不能用它代替输出。
54
+ */
55
+ silent: SilentText;
56
+ }>;
57
+ export declare function isIssuedTextProjection(value: unknown): value is TextLine | TextLines | TextFragment | SilentText;
58
+ export type DataVariantDefinition<Payload = unknown, TextEnabled extends boolean = boolean> = {
59
+ readonly description: string;
60
+ readonly schema: ContractSchema<Payload>;
61
+ readonly exitCode: number;
62
+ } & (TextEnabled extends true ? Readonly<{
63
+ readonly text: AtomicTextPresenter<Payload>;
64
+ }> : TextEnabled extends false ? Readonly<{
65
+ readonly text?: never;
66
+ }> : Readonly<{
67
+ readonly text?: AtomicTextPresenter<Payload>;
68
+ }>);
69
+ export type DataVariantDefinitions<TextEnabled extends boolean = boolean> = Readonly<Record<string, DataVariantDefinition<unknown, TextEnabled>>>;
70
+ export type StreamRecordDefinition<Payload = unknown, TextEnabled extends boolean = boolean> = Readonly<{
71
+ readonly description: string;
72
+ readonly schema: ContractSchema<Payload>;
73
+ }> & (TextEnabled extends true ? Readonly<{
74
+ readonly text: StreamTextPresenter<Payload>;
75
+ }> : TextEnabled extends false ? Readonly<{
76
+ readonly text?: never;
77
+ }> : Readonly<{
78
+ readonly text?: StreamTextPresenter<Payload>;
79
+ }>);
80
+ export type StreamRecordDefinitions<TextEnabled extends boolean = boolean> = Readonly<Record<string, StreamRecordDefinition<unknown, TextEnabled>>>;
81
+ export type FailureVariantDefinition<Payload = unknown, TextEnabled extends boolean = boolean> = {
82
+ readonly description: string;
83
+ readonly schema: ContractSchema<Payload>;
84
+ readonly exitCode: number;
85
+ } & (TextEnabled extends true ? Readonly<{
86
+ readonly text: AtomicTextPresenter<Payload>;
87
+ }> : TextEnabled extends false ? Readonly<{
88
+ readonly text?: never;
89
+ }> : Readonly<{
90
+ readonly text?: AtomicTextPresenter<Payload>;
91
+ }>);
92
+ export type FailureVariantDefinitions<TextEnabled extends boolean = boolean> = Readonly<Record<string, FailureVariantDefinition<unknown, TextEnabled>>>;
93
+ export interface CompletionFact<Command extends string = string> {
94
+ readonly kind: "completion";
95
+ readonly command: Command;
96
+ readonly [outcomeFactType]: true;
97
+ }
98
+ export interface DataFact<Command extends string = string, Variant extends string = string, Data = unknown> {
99
+ readonly kind: "data";
100
+ readonly command: Command;
101
+ readonly variant: Variant;
102
+ readonly data: Data;
103
+ readonly [outcomeFactType]: true;
104
+ }
105
+ export interface FailureFact<Command extends string = string, Variant extends string = string, Data = unknown> {
106
+ readonly kind: "failure";
107
+ readonly command: Command;
108
+ readonly variant: Variant;
109
+ readonly data: Data;
110
+ readonly [outcomeFactType]: true;
111
+ }
112
+ export interface StreamRecordFact<Command extends string = string, Variant extends string = string, Data = unknown> {
113
+ readonly kind: "record";
114
+ readonly command: Command;
115
+ readonly variant: Variant;
116
+ readonly data: Data;
117
+ readonly [outcomeFactType]: true;
118
+ }
119
+ export interface StreamSuccessFact<Command extends string = string> {
120
+ readonly kind: "streamSuccess";
121
+ readonly command: Command;
122
+ readonly [outcomeFactType]: true;
123
+ }
124
+ export type OutcomeFact = CompletionFact | DataFact | FailureFact | StreamRecordFact | StreamSuccessFact;
125
+ export interface CompletionOutcome<Command extends string> {
126
+ completion(): CompletionFact<Command>;
127
+ }
128
+ type DataVariantPayload<Variant> = Variant extends DataVariantDefinition<infer Payload> ? Payload : never;
129
+ export type DataFactUnion<Command extends string, Variants extends DataVariantDefinitions> = {
130
+ readonly [Variant in keyof Variants & string]: DataFact<Command, Variant, DataVariantPayload<Variants[Variant]>>;
131
+ }[keyof Variants & string];
132
+ export type DataOutcome<Command extends string, Variants extends DataVariantDefinitions> = Readonly<{
133
+ readonly data: Readonly<{
134
+ [Variant in keyof Variants]: (payload: DataVariantPayload<Variants[Variant]>) => DataFact<Command, Variant & string, DataVariantPayload<Variants[Variant]>>;
135
+ }>;
136
+ }>;
137
+ type FailureVariantPayload<Variant> = Variant extends FailureVariantDefinition<infer Payload> ? Payload : never;
138
+ export type FailureFactUnion<Command extends string, Failures extends FailureVariantDefinitions> = {
139
+ readonly [Variant in keyof Failures & string]: FailureFact<Command, Variant, FailureVariantPayload<Failures[Variant]>>;
140
+ }[keyof Failures & string];
141
+ export type FailureOutcome<Command extends string, Failures extends FailureVariantDefinitions> = Readonly<{
142
+ readonly failure: Readonly<{
143
+ [Variant in keyof Failures]: (payload: FailureVariantPayload<Failures[Variant]>) => FailureFact<Command, Variant & string, FailureVariantPayload<Failures[Variant]>>;
144
+ }>;
145
+ }>;
146
+ type StreamRecordPayload<Variant> = Variant extends StreamRecordDefinition<infer Payload> ? Payload : never;
147
+ export type StreamRecordFactUnion<Command extends string, Records extends StreamRecordDefinitions> = {
148
+ readonly [Variant in keyof Records & string]: StreamRecordFact<Command, Variant, StreamRecordPayload<Records[Variant]>>;
149
+ }[keyof Records & string];
150
+ export type StreamOutcome<Command extends string, Records extends StreamRecordDefinitions> = Readonly<{
151
+ readonly record: Readonly<{
152
+ [Variant in keyof Records]: (payload: StreamRecordPayload<Records[Variant]>) => StreamRecordFact<Command, Variant & string, StreamRecordPayload<Records[Variant]>>;
153
+ }>;
154
+ streamSuccess(): StreamSuccessFact<Command>;
155
+ }>;
156
+ export declare function createCompletionFact<Command extends string>(command: Command, issuedOutcomeFacts: WeakSet<object>): CompletionFact<Command>;
157
+ export declare function createDataFact<Command extends string, Variant extends string, Data>(command: Command, variant: Variant, data: Data, issuedOutcomeFacts: WeakSet<object>): DataFact<Command, Variant, Data>;
158
+ export declare function createFailureFact<Command extends string, Variant extends string, Data>(command: Command, variant: Variant, data: Data, issuedOutcomeFacts: WeakSet<object>): FailureFact<Command, Variant, Data>;
159
+ export declare function createStreamRecordFact<Command extends string, Variant extends string, Data>(command: Command, variant: Variant, data: Data, issuedOutcomeFacts: WeakSet<object>): StreamRecordFact<Command, Variant, Data>;
160
+ export declare function createStreamSuccessFact<Command extends string>(command: Command, issuedOutcomeFacts: WeakSet<object>): StreamSuccessFact<Command>;
161
+ export declare function isIssuedOutcomeFact(value: unknown, issuedOutcomeFacts: WeakSet<object>): value is OutcomeFact;
162
+ export {};
@@ -0,0 +1,113 @@
1
+ const outcomeFactType = Symbol("OutcomeFact.type");
2
+ const textProjectionType = Symbol("TextProjection.type");
3
+ const issuedTextProjections = new WeakSet();
4
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- 文本投影仅由这些工厂签发,运行时身份由 WeakSet 核对。 */
5
+ function createTextLine(value) {
6
+ if (value.length === 0 ||
7
+ value.includes("\r") ||
8
+ value.includes("\n") ||
9
+ value.includes("\0")) {
10
+ throw new TypeError("invalidTextLine");
11
+ }
12
+ const projection = Object.freeze({ kind: "line", value });
13
+ issuedTextProjections.add(projection);
14
+ return projection;
15
+ }
16
+ function createTextLines(values) {
17
+ if (!Array.isArray(values) ||
18
+ values.length === 0 ||
19
+ values.some((value) => typeof value !== "string" ||
20
+ value.includes("\r") ||
21
+ value.includes("\n") ||
22
+ value.includes("\0")) ||
23
+ values.every((value) => value.length === 0)) {
24
+ throw new TypeError("invalidTextLines");
25
+ }
26
+ const projection = Object.freeze({
27
+ kind: "lines",
28
+ lines: Object.freeze([...values]),
29
+ });
30
+ issuedTextProjections.add(projection);
31
+ return projection;
32
+ }
33
+ const silentProjection = Object.freeze({ kind: "silent" });
34
+ issuedTextProjections.add(silentProjection);
35
+ const silentText = silentProjection;
36
+ function createTextFragment(value) {
37
+ if (value.length === 0 || value.includes("\0")) {
38
+ throw new TypeError("invalidTextFragment");
39
+ }
40
+ const projection = Object.freeze({ kind: "fragment", value });
41
+ issuedTextProjections.add(projection);
42
+ return projection;
43
+ }
44
+ /* oxlint-enable typescript/no-unsafe-type-assertion */
45
+ /** 在呈现器中显式构造文本投影;这里只验证文本值,实际通道路由与分帧由执行内核负责。 */
46
+ export const text = Object.freeze({
47
+ /**
48
+ * 构造非空单行,拒绝 CR、LF、NUL;核心写出时追加恰好一个 LF。
49
+ * 适用于原子结果、流记录及流成功终态,呈现器应提供完整文本而不依赖核心补写文案。
50
+ */
51
+ line: createTextLine,
52
+ /**
53
+ * 构造有序行组,至少一行非空;每行拒绝 CR、LF、NUL,空成员显式保留空白行。
54
+ * 核心用 LF 连接并追加一个终止 LF。用于原子结果、失败、流成功终态或帮助补充,
55
+ * 不用于流记录;例如 text.lines(["处理完成", "", "详细说明"])。
56
+ */
57
+ lines: createTextLines,
58
+ /**
59
+ * 仅用于流记录中需要连续拼接的增量文本;必须非空且不含 NUL,可以含换行。
60
+ * 核心原样写出,不追加 LF,因此不承诺一行对应一条记录。
61
+ */
62
+ fragment: createTextFragment,
63
+ /**
64
+ * completion 成功或流成功终态显式选择不写文本字节;仍须由呈现器返回此值。
65
+ * 省略呈现器不等于静默,data、failure 和流记录也不能用它代替输出。
66
+ */
67
+ silent: silentText,
68
+ });
69
+ export function isIssuedTextProjection(value) {
70
+ return (typeof value === "object" &&
71
+ value !== null &&
72
+ issuedTextProjections.has(value));
73
+ }
74
+ /* oxlint-disable typescript/no-unsafe-type-assertion -- 结果事实的私有类型品牌由签发工厂与 WeakSet 共同保证。 */
75
+ export function createCompletionFact(command, issuedOutcomeFacts) {
76
+ const fact = Object.freeze({ kind: "completion", command });
77
+ issuedOutcomeFacts.add(fact);
78
+ return fact;
79
+ }
80
+ export function createDataFact(command, variant, data, issuedOutcomeFacts) {
81
+ const fact = Object.freeze({ kind: "data", command, variant, data });
82
+ issuedOutcomeFacts.add(fact);
83
+ return fact;
84
+ }
85
+ export function createFailureFact(command, variant, data, issuedOutcomeFacts) {
86
+ const fact = Object.freeze({
87
+ kind: "failure",
88
+ command,
89
+ variant,
90
+ data,
91
+ });
92
+ issuedOutcomeFacts.add(fact);
93
+ return fact;
94
+ }
95
+ export function createStreamRecordFact(command, variant, data, issuedOutcomeFacts) {
96
+ const fact = Object.freeze({
97
+ kind: "record",
98
+ command,
99
+ variant,
100
+ data,
101
+ });
102
+ issuedOutcomeFacts.add(fact);
103
+ return fact;
104
+ }
105
+ export function createStreamSuccessFact(command, issuedOutcomeFacts) {
106
+ const fact = Object.freeze({ kind: "streamSuccess", command });
107
+ issuedOutcomeFacts.add(fact);
108
+ return fact;
109
+ }
110
+ /* oxlint-enable typescript/no-unsafe-type-assertion */
111
+ export function isIssuedOutcomeFact(value, issuedOutcomeFacts) {
112
+ return (typeof value === "object" && value !== null && issuedOutcomeFacts.has(value));
113
+ }
@@ -0,0 +1,53 @@
1
+ import type { JsonObject } from "#/contract-schema";
2
+ export declare function createCompletionEnvelope<Command extends string>(command: Command): Readonly<{
3
+ schemaVersion: "1";
4
+ command: Command;
5
+ kind: "completion";
6
+ }>;
7
+ export declare function createCompletionWireSchema(command: string): JsonObject;
8
+ export declare function createDataEnvelope<Command extends string, Variant extends string, Data>(command: Command, variant: Variant, data: Data): Readonly<{
9
+ schemaVersion: "1";
10
+ command: Command;
11
+ kind: "data";
12
+ variant: Variant;
13
+ data: Data;
14
+ }>;
15
+ export declare function createDataWireSchema(command: string, variant: string, dataSchema: JsonObject): JsonObject;
16
+ export declare function createFailureEnvelope<Command extends string, Variant extends string, Data>(command: Command, variant: Variant, data: Data): Readonly<{
17
+ schemaVersion: "1";
18
+ command: Command;
19
+ kind: "failure";
20
+ variant: Variant;
21
+ data: Data;
22
+ }>;
23
+ export declare function createFailureWireSchema(command: string, variant: string, dataSchema: JsonObject): JsonObject;
24
+ export declare function createStreamHeaderEnvelope<Command extends string>(command: Command): Readonly<{
25
+ schemaVersion: "1";
26
+ command: Command;
27
+ kind: "stream";
28
+ }>;
29
+ export declare function createStreamRecordEnvelope<Variant extends string, Data>(variant: Variant, data: Data): Readonly<{
30
+ kind: "record";
31
+ variant: Variant;
32
+ data: Data;
33
+ }>;
34
+ export declare function createStreamSuccessEnvelope(): Readonly<{
35
+ kind: "streamSuccess";
36
+ }>;
37
+ export declare function createStreamHeaderWireSchema(command: string): JsonObject;
38
+ export declare function createStreamRecordWireSchema(variant: string, dataSchema: JsonObject): JsonObject;
39
+ export declare function createStreamSuccessWireSchema(): JsonObject;
40
+ export interface UsageFailureWireScope {
41
+ readonly command: string;
42
+ readonly usage: string;
43
+ readonly helpArgv: readonly string[];
44
+ }
45
+ export declare function createUsageFailureEnvelope<Command extends string>(command: Command, issues: unknown, usage: string, helpArgv: readonly string[]): Readonly<{
46
+ schemaVersion: "1";
47
+ command: Command;
48
+ kind: "usageFailure";
49
+ issues: unknown;
50
+ usage: string;
51
+ helpArgv: readonly string[];
52
+ }>;
53
+ export declare function createUsageFailureWireSchema(scopes: readonly UsageFailureWireScope[]): JsonObject;
@@ -0,0 +1,189 @@
1
+ const schemaVersion = "1";
2
+ export function createCompletionEnvelope(command) {
3
+ return Object.freeze({
4
+ schemaVersion,
5
+ command,
6
+ kind: "completion",
7
+ });
8
+ }
9
+ export function createCompletionWireSchema(command) {
10
+ const envelope = createCompletionEnvelope(command);
11
+ return createEnvelopeSchema(envelope, {});
12
+ }
13
+ export function createDataEnvelope(command, variant, data) {
14
+ return createAtomicEnvelope(command, "data", variant, data);
15
+ }
16
+ export function createDataWireSchema(command, variant, dataSchema) {
17
+ const envelope = createDataEnvelope(command, variant, null);
18
+ return createEnvelopeSchema(envelope, { data: dataSchema });
19
+ }
20
+ export function createFailureEnvelope(command, variant, data) {
21
+ return createAtomicEnvelope(command, "failure", variant, data);
22
+ }
23
+ function createAtomicEnvelope(command, kind, variant, data) {
24
+ return Object.freeze({
25
+ schemaVersion,
26
+ command,
27
+ kind,
28
+ variant,
29
+ data,
30
+ });
31
+ }
32
+ export function createFailureWireSchema(command, variant, dataSchema) {
33
+ const envelope = createFailureEnvelope(command, variant, null);
34
+ return createEnvelopeSchema(envelope, { data: dataSchema });
35
+ }
36
+ export function createStreamHeaderEnvelope(command) {
37
+ return Object.freeze({ schemaVersion, command, kind: "stream" });
38
+ }
39
+ export function createStreamRecordEnvelope(variant, data) {
40
+ return Object.freeze({ kind: "record", variant, data });
41
+ }
42
+ export function createStreamSuccessEnvelope() {
43
+ return Object.freeze({ kind: "streamSuccess" });
44
+ }
45
+ export function createStreamHeaderWireSchema(command) {
46
+ return createEnvelopeSchema(createStreamHeaderEnvelope(command), {});
47
+ }
48
+ export function createStreamRecordWireSchema(variant, dataSchema) {
49
+ return createEnvelopeSchema(createStreamRecordEnvelope(variant, null), {
50
+ data: dataSchema,
51
+ });
52
+ }
53
+ export function createStreamSuccessWireSchema() {
54
+ return createEnvelopeSchema(createStreamSuccessEnvelope(), {});
55
+ }
56
+ export function createUsageFailureEnvelope(command, issues, usage, helpArgv) {
57
+ return Object.freeze({
58
+ schemaVersion,
59
+ command,
60
+ kind: "usageFailure",
61
+ issues,
62
+ usage,
63
+ helpArgv,
64
+ });
65
+ }
66
+ export function createUsageFailureWireSchema(scopes) {
67
+ return {
68
+ $schema: "https://json-schema.org/draft/2020-12/schema",
69
+ oneOf: scopes.map(({ command, usage, helpArgv }) => createEnvelopeSchema(createUsageFailureEnvelope(command, null, usage, helpArgv), {
70
+ issues: {
71
+ items: { oneOf: usageIssueSchemas() },
72
+ minItems: 1,
73
+ type: "array",
74
+ },
75
+ })),
76
+ };
77
+ }
78
+ function usageIssueSchemas() {
79
+ const string = { type: "string" };
80
+ const position = { minimum: 0, type: "integer" };
81
+ const occurrence = objectSchema({ option: string, position }, [
82
+ "position",
83
+ "option",
84
+ ]);
85
+ const occurrences = (minimum) => ({
86
+ items: occurrence,
87
+ minItems: minimum,
88
+ type: "array",
89
+ });
90
+ const evidence = objectSchema({
91
+ message: string,
92
+ path: {
93
+ items: { oneOf: [string, { type: "number" }] },
94
+ type: "array",
95
+ },
96
+ }, ["message"]);
97
+ const constraintValue = objectSchema({
98
+ field: string,
99
+ value: { oneOf: [{ type: "boolean" }, string] },
100
+ }, ["field", "value"]);
101
+ const outputOccurrence = objectSchema({
102
+ format: { enum: ["structured", "text"] },
103
+ option: string,
104
+ position,
105
+ }, ["position", "option", "format"]);
106
+ return [
107
+ issueSchema("conflictingFlag", {
108
+ field: string,
109
+ negativeOccurrences: occurrences(1),
110
+ positiveOccurrences: occurrences(1),
111
+ }),
112
+ issueSchema("conflictingOutputFormat", {
113
+ occurrences: { items: outputOccurrence, minItems: 2, type: "array" },
114
+ }),
115
+ issueSchema("exclusiveUsageConstraint", {
116
+ fields: { items: string, minItems: 2, type: "array" },
117
+ }),
118
+ issueSchema("forbiddenUsageCombination", {
119
+ values: { items: constraintValue, minItems: 2, type: "array" },
120
+ }),
121
+ issueSchema("inputRejected", {
122
+ evidence: { items: evidence, minItems: 1, type: "array" },
123
+ }),
124
+ issueSchema("invalidFieldChoice", {
125
+ choices: { items: string, minItems: 1, type: "array" },
126
+ field: string,
127
+ position,
128
+ value: string,
129
+ }),
130
+ issueSchema("invalidOutputFormat", {
131
+ option: string,
132
+ position,
133
+ received: { oneOf: [string, { type: "null" }] },
134
+ }),
135
+ issueSchema("missingOptionValue", {
136
+ field: string,
137
+ option: string,
138
+ position,
139
+ }),
140
+ issueSchema("missingRequiredField", { field: string }),
141
+ issueSchema("repeatedOption", {
142
+ field: string,
143
+ occurrences: occurrences(2),
144
+ }),
145
+ issueSchema("requiredByUsageConstraint", {
146
+ field: string,
147
+ requires: string,
148
+ }),
149
+ issueSchema("unexpectedOptionValue", {
150
+ field: string,
151
+ option: string,
152
+ position,
153
+ value: string,
154
+ }),
155
+ issueSchema("unexpectedPositional", { position, value: string }),
156
+ issueSchema("unknownCommand", {
157
+ command: string,
158
+ position,
159
+ suggestedCommand: string,
160
+ }),
161
+ issueSchema("unknownOption", {
162
+ option: string,
163
+ position,
164
+ suggestedOption: string,
165
+ }),
166
+ ];
167
+ }
168
+ function issueSchema(code, properties) {
169
+ return objectSchema({ code: { const: code }, ...properties }, [
170
+ "code",
171
+ ...Object.keys(properties).filter((key) => key !== "suggestedCommand" && key !== "suggestedOption"),
172
+ ]);
173
+ }
174
+ function objectSchema(properties, required) {
175
+ return { additionalProperties: false, properties, required, type: "object" };
176
+ }
177
+ function createEnvelopeSchema(envelope, propertySchemas) {
178
+ return {
179
+ $schema: "https://json-schema.org/draft/2020-12/schema",
180
+ additionalProperties: false,
181
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- 闭合问题联合只生成 JSON Schema 的 JSON 值。
182
+ properties: Object.fromEntries(Object.entries(envelope).map(([key, value]) => [
183
+ key,
184
+ propertySchemas[key] ?? { const: value },
185
+ ])),
186
+ required: Object.keys(envelope),
187
+ type: "object",
188
+ };
189
+ }
@@ -0,0 +1,16 @@
1
+ import type { ContractDefinitionIssue } from "#/contract-definition-error";
2
+ import type { ContractSchema, JsonObject } from "#/contract-schema";
3
+ import type { StreamRecordDefinition } from "#/outcome-fact";
4
+ export type RuntimeStreamRecord = StreamRecordDefinition & {
5
+ readonly schema: ContractSchema;
6
+ };
7
+ export interface StreamRecordManifest {
8
+ readonly description: string;
9
+ readonly inputSchema: JsonObject;
10
+ readonly outputSchema: JsonObject;
11
+ }
12
+ export declare function compileStreamRecords(command: string, definitions: Readonly<Record<string, StreamRecordDefinition>>, issues: ContractDefinitionIssue[]): Readonly<{
13
+ readonly runtime: Readonly<Record<string, RuntimeStreamRecord>>;
14
+ readonly manifest: Readonly<Record<string, StreamRecordManifest>>;
15
+ readonly wire: Readonly<Record<string, JsonObject>>;
16
+ }>;