@logixjs/cli 1.0.1

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 (46) hide show
  1. package/LICENSE +201 -0
  2. package/dist/Commands.d.ts +61 -0
  3. package/dist/Commands.js +16 -0
  4. package/dist/Commands.js.map +1 -0
  5. package/dist/anchorAutofill-V6CAXQHT.js +128 -0
  6. package/dist/anchorAutofill-V6CAXQHT.js.map +1 -0
  7. package/dist/anchorIndex-IEFARUZM.js +15 -0
  8. package/dist/anchorIndex-IEFARUZM.js.map +1 -0
  9. package/dist/bin/logix-devserver.d.ts +1 -0
  10. package/dist/bin/logix-devserver.js +32 -0
  11. package/dist/bin/logix-devserver.js.map +1 -0
  12. package/dist/bin/logix.d.ts +1 -0
  13. package/dist/bin/logix.js +37 -0
  14. package/dist/bin/logix.js.map +1 -0
  15. package/dist/chunk-6DZEO5HP.js +102 -0
  16. package/dist/chunk-6DZEO5HP.js.map +1 -0
  17. package/dist/chunk-HGHTOYNL.js +27 -0
  18. package/dist/chunk-HGHTOYNL.js.map +1 -0
  19. package/dist/chunk-PZ5AY32C.js +10 -0
  20. package/dist/chunk-PZ5AY32C.js.map +1 -0
  21. package/dist/chunk-RF7XSP3P.js +22 -0
  22. package/dist/chunk-RF7XSP3P.js.map +1 -0
  23. package/dist/chunk-TDQVD2IA.js +1193 -0
  24. package/dist/chunk-TDQVD2IA.js.map +1 -0
  25. package/dist/chunk-VRPSB3SV.js +143 -0
  26. package/dist/chunk-VRPSB3SV.js.map +1 -0
  27. package/dist/contractSuiteRun-5Y7LVI72.js +15 -0
  28. package/dist/contractSuiteRun-5Y7LVI72.js.map +1 -0
  29. package/dist/describe-5MFSLD7R.js +218 -0
  30. package/dist/describe-5MFSLD7R.js.map +1 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.js +10 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/irDiff-WYXZEVA7.js +351 -0
  35. package/dist/irDiff-WYXZEVA7.js.map +1 -0
  36. package/dist/irExport-EI2VYIMT.js +87 -0
  37. package/dist/irExport-EI2VYIMT.js.map +1 -0
  38. package/dist/irValidate-JEQGVRL5.js +229 -0
  39. package/dist/irValidate-JEQGVRL5.js.map +1 -0
  40. package/dist/spyEvidence-JTJDS2WN.js +15 -0
  41. package/dist/spyEvidence-JTJDS2WN.js.map +1 -0
  42. package/dist/transformModule-D6YE3U5W.js +15 -0
  43. package/dist/transformModule-D6YE3U5W.js.map +1 -0
  44. package/dist/trialRun-SWVYG67P.js +15 -0
  45. package/dist/trialRun-SWVYG67P.js.map +1 -0
  46. package/package.json +69 -0
@@ -0,0 +1,1193 @@
1
+ import {
2
+ stableStringifyJson
3
+ } from "./chunk-RF7XSP3P.js";
4
+ import {
5
+ asSerializableErrorSummary,
6
+ exitCodeFromErrorSummary,
7
+ makeCliError,
8
+ makeErrorCommandResult,
9
+ sortArtifactsByOutputKey
10
+ } from "./chunk-6DZEO5HP.js";
11
+ import {
12
+ __export
13
+ } from "./chunk-PZ5AY32C.js";
14
+
15
+ // src/Commands.ts
16
+ var Commands_exports = {};
17
+ __export(Commands_exports, {
18
+ formatCommandResult: () => formatCommandResult,
19
+ main: () => main,
20
+ printHelp: () => printHelp,
21
+ runCli: () => runCli
22
+ });
23
+ import { Effect as Effect3, Logger } from "effect";
24
+
25
+ // src/internal/args.ts
26
+ import path from "path";
27
+ import { Effect } from "effect";
28
+ var decapitalize = (s) => s.length === 0 ? s : `${s[0].toLowerCase()}${s.slice(1)}`;
29
+ var parseConfigValue = (value) => {
30
+ const trimmed = value.trim();
31
+ if (trimmed === "true") return true;
32
+ if (trimmed === "false") return false;
33
+ const asNumber = Number(trimmed);
34
+ return Number.isFinite(asNumber) ? asNumber : trimmed;
35
+ };
36
+ var parseEntryRefFromOptions = (opts) => {
37
+ const entryRaw = typeof opts.entry === "string" ? opts.entry.trim() : void 0;
38
+ if (!entryRaw) {
39
+ return Effect.fail(
40
+ makeCliError({
41
+ code: "CLI_INVALID_ARGUMENT",
42
+ message: "\u7F3A\u5C11\u5165\u53E3\uFF1A\u8BF7\u63D0\u4F9B --entry <modulePath>#<exportName>"
43
+ })
44
+ );
45
+ }
46
+ const hash = entryRaw.lastIndexOf("#");
47
+ if (hash > 0 && hash < entryRaw.length - 1) {
48
+ return Effect.succeed({ modulePath: entryRaw.slice(0, hash), exportName: entryRaw.slice(hash + 1) });
49
+ }
50
+ return Effect.fail(
51
+ makeCliError({
52
+ code: "CLI_INVALID_ARGUMENT",
53
+ message: `--entry \u975E\u6CD5\uFF1A${entryRaw}\uFF08\u671F\u671B <modulePath>#<exportName>\uFF09`
54
+ })
55
+ );
56
+ };
57
+ var parseIrValidateInputFromOptions = (opts) => {
58
+ const dir = typeof opts.inDir === "string" ? opts.inDir.trim() : void 0;
59
+ const file = typeof opts.artifact === "string" ? opts.artifact.trim() : void 0;
60
+ if (dir && file) {
61
+ return Effect.fail(
62
+ makeCliError({
63
+ code: "CLI_INVALID_ARGUMENT",
64
+ message: "\u53C2\u6570\u4E92\u65A5\uFF1A\u8BF7\u4EC5\u63D0\u4F9B --in \u6216 --artifact\u3002"
65
+ })
66
+ );
67
+ }
68
+ if (dir) return Effect.succeed({ kind: "dir", dir });
69
+ if (file) return Effect.succeed({ kind: "file", file });
70
+ return Effect.fail(
71
+ makeCliError({
72
+ code: "CLI_INVALID_ARGUMENT",
73
+ message: "\u7F3A\u5C11\u8F93\u5165\uFF1A\u8BF7\u63D0\u4F9B --in <dir> \u6216 --artifact <file>"
74
+ })
75
+ );
76
+ };
77
+ var parseIrDiffInputFromOptions = (opts) => {
78
+ const before = typeof opts.before === "string" ? opts.before.trim() : void 0;
79
+ const after = typeof opts.after === "string" ? opts.after.trim() : void 0;
80
+ if (!before || !after) {
81
+ return Effect.fail(
82
+ makeCliError({
83
+ code: "CLI_INVALID_ARGUMENT",
84
+ message: "\u7F3A\u5C11\u8F93\u5165\uFF1A\u8BF7\u63D0\u4F9B --before <dir|file> \u4E0E --after <dir|file>"
85
+ })
86
+ );
87
+ }
88
+ return Effect.succeed({ before, after });
89
+ };
90
+ var booleanOptionNames = /* @__PURE__ */ new Set([
91
+ "allowWarn",
92
+ "includeAnchorAutofill",
93
+ "includeContextPack",
94
+ "includeTrace",
95
+ "includeUiKitRegistry",
96
+ "json",
97
+ "requireRulesManifest"
98
+ ]);
99
+ var flagsWithValue = /* @__PURE__ */ new Set([
100
+ "--after",
101
+ "--artifact",
102
+ "--baseline",
103
+ "--before",
104
+ "--budgetBytes",
105
+ "--cliConfig",
106
+ "--config",
107
+ "--diagnosticsLevel",
108
+ "--entry",
109
+ "--host",
110
+ "--in",
111
+ "--inputs",
112
+ "--maxEvents",
113
+ "--maxRawMode",
114
+ "--maxUsedServices",
115
+ "--mode",
116
+ "--ops",
117
+ "--out",
118
+ "--outRoot",
119
+ "--packMaxBytes",
120
+ "--profile",
121
+ "--repoRoot",
122
+ "--runId",
123
+ "--timeout",
124
+ "--tsconfig"
125
+ ]);
126
+ var isKnownBooleanFlag = (flag) => {
127
+ if (!flag.startsWith("--")) return false;
128
+ const name = flag.slice(2);
129
+ if (booleanOptionNames.has(name)) return true;
130
+ if (name.startsWith("no")) {
131
+ const canonical = decapitalize(name.slice(2));
132
+ return booleanOptionNames.has(canonical);
133
+ }
134
+ return false;
135
+ };
136
+ var canonicalOptionKey = (flag) => {
137
+ if (!flag.startsWith("--")) return void 0;
138
+ const name = flag.slice(2);
139
+ if (isKnownBooleanFlag(flag)) {
140
+ if (name.startsWith("no")) return decapitalize(name.slice(2));
141
+ return name;
142
+ }
143
+ return name;
144
+ };
145
+ var parseOptionOccurrences = (tokens) => {
146
+ const out = [];
147
+ for (let i = 0; i < tokens.length; i++) {
148
+ const token = tokens[i];
149
+ if (token.startsWith("-")) {
150
+ const key = canonicalOptionKey(token);
151
+ const allowMultiple = key === "config";
152
+ if (flagsWithValue.has(token)) {
153
+ const value = tokens[i + 1];
154
+ if (value !== void 0) {
155
+ out.push({ key, tokens: [token, value], allowMultiple });
156
+ i += 1;
157
+ continue;
158
+ }
159
+ out.push({ key, tokens: [token], allowMultiple });
160
+ continue;
161
+ }
162
+ out.push({ key, tokens: [token], allowMultiple });
163
+ continue;
164
+ }
165
+ out.push({ tokens: [token], allowMultiple: true });
166
+ }
167
+ return out;
168
+ };
169
+ var dedupeOptionTokensLastWins = (tokens) => {
170
+ const occurrences = parseOptionOccurrences(tokens);
171
+ const seen = /* @__PURE__ */ new Set();
172
+ const kept = [];
173
+ for (let i = occurrences.length - 1; i >= 0; i--) {
174
+ const occ = occurrences[i];
175
+ if (!occ.key || occ.allowMultiple) {
176
+ kept.push(occ);
177
+ continue;
178
+ }
179
+ if (seen.has(occ.key)) continue;
180
+ seen.add(occ.key);
181
+ kept.push(occ);
182
+ }
183
+ kept.reverse();
184
+ return kept.flatMap((o) => o.tokens);
185
+ };
186
+ var commandTokenShapes = [
187
+ ["describe"],
188
+ ["trialrun"],
189
+ ["ir", "export"],
190
+ ["ir", "validate"],
191
+ ["ir", "diff"],
192
+ ["contract-suite", "run"],
193
+ ["spy", "evidence"],
194
+ ["anchor", "index"],
195
+ ["anchor", "autofill"],
196
+ ["transform", "module"]
197
+ ];
198
+ var findCommandTokens = (argv) => {
199
+ for (let i = 0; i < argv.length; i++) {
200
+ const token = argv[i];
201
+ if (token.startsWith("-")) {
202
+ if (flagsWithValue.has(token)) i += 1;
203
+ continue;
204
+ }
205
+ for (const shape of commandTokenShapes) {
206
+ if (shape[0] !== token) continue;
207
+ let ok = true;
208
+ for (let j = 1; j < shape.length; j++) {
209
+ if (argv[i + j] !== shape[j]) {
210
+ ok = false;
211
+ break;
212
+ }
213
+ }
214
+ if (!ok) continue;
215
+ return { tokens: shape, indices: shape.map((_, j) => i + j) };
216
+ }
217
+ }
218
+ return void 0;
219
+ };
220
+ var normalizeArgvForEffectCli = (argv) => {
221
+ const extracted = findCommandTokens(argv);
222
+ if (!extracted) return dedupeOptionTokensLastWins(argv);
223
+ const drop = new Set(extracted.indices);
224
+ const rest = argv.filter((_, idx) => !drop.has(idx));
225
+ return [...extracted.tokens, ...dedupeOptionTokensLastWins(rest)];
226
+ };
227
+ var ANSI_CSI_REGEX = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
228
+ var renderValidationError = (err) => {
229
+ if (err instanceof Error && typeof err.message === "string" && err.message.length > 0) {
230
+ return err.message.replace(ANSI_CSI_REGEX, "").trim();
231
+ }
232
+ return typeof err === "string" ? err : "CLI validation failed";
233
+ };
234
+ var defaultParsedOptions = () => ({
235
+ host: "node",
236
+ repoRoot: ".",
237
+ diagnosticsLevel: "light",
238
+ includeTrace: false,
239
+ config: {},
240
+ allowWarn: false,
241
+ includeContextPack: false,
242
+ requireRulesManifest: false,
243
+ includeUiKitRegistry: false,
244
+ includeAnchorAutofill: false,
245
+ describeJson: false
246
+ });
247
+ var invalidArgument = (message, helpText) => makeCliError({
248
+ code: "CLI_INVALID_ARGUMENT",
249
+ message,
250
+ hint: helpText
251
+ });
252
+ var missingFlagError = (message, helpText) => makeCliError({
253
+ code: "CLI_INVALID_ARGUMENT",
254
+ message,
255
+ hint: helpText
256
+ });
257
+ var parseManualOptions = (tokens, helpText) => Effect.sync(() => {
258
+ const options = { ...defaultParsedOptions() };
259
+ const readValue = (flag, index) => {
260
+ const value = tokens[index + 1];
261
+ if (!value || value.startsWith("--")) {
262
+ throw missingFlagError(`\u7F3A\u5C11\u53C2\u6570\u503C\uFF1A${flag}`, helpText);
263
+ }
264
+ return value;
265
+ };
266
+ for (let i = 0; i < tokens.length; i++) {
267
+ const token = tokens[i];
268
+ if (!token.startsWith("--")) {
269
+ throw invalidArgument(`\u672A\u77E5\u53C2\u6570\uFF1A${token}`, helpText);
270
+ }
271
+ const valueFlag = flagsWithValue.has(token);
272
+ const key = canonicalOptionKey(token);
273
+ if (valueFlag) {
274
+ const value = readValue(token, i);
275
+ i += 1;
276
+ switch (key) {
277
+ case "runId":
278
+ options.runId = value;
279
+ break;
280
+ case "out":
281
+ options.out = value;
282
+ break;
283
+ case "outRoot":
284
+ options.outRoot = value;
285
+ break;
286
+ case "budgetBytes":
287
+ options.budgetBytes = Number(value);
288
+ break;
289
+ case "mode":
290
+ options.mode = value;
291
+ break;
292
+ case "tsconfig":
293
+ options.tsconfig = value;
294
+ break;
295
+ case "host":
296
+ options.host = value;
297
+ break;
298
+ case "cliConfig":
299
+ options.cliConfig = value;
300
+ break;
301
+ case "profile":
302
+ options.profile = value;
303
+ break;
304
+ case "repoRoot":
305
+ options.repoRoot = value;
306
+ break;
307
+ case "entry":
308
+ options.entry = value;
309
+ break;
310
+ case "in":
311
+ options.inDir = value;
312
+ break;
313
+ case "artifact":
314
+ options.artifact = value;
315
+ break;
316
+ case "before":
317
+ options.before = value;
318
+ break;
319
+ case "after":
320
+ options.after = value;
321
+ break;
322
+ case "ops":
323
+ options.opsPath = value;
324
+ break;
325
+ case "diagnosticsLevel":
326
+ options.diagnosticsLevel = value;
327
+ break;
328
+ case "maxEvents":
329
+ options.maxEvents = Number(value);
330
+ break;
331
+ case "timeout":
332
+ options.timeoutMs = Number(value);
333
+ break;
334
+ case "config": {
335
+ const eq = value.indexOf("=");
336
+ if (eq <= 0) {
337
+ throw invalidArgument(`\u975E\u6CD5 --config\uFF1A${value}\uFF08\u671F\u671B K=V\uFF09`, helpText);
338
+ }
339
+ const k = value.slice(0, eq);
340
+ const v = value.slice(eq + 1);
341
+ options.config = { ...options.config, [k]: parseConfigValue(v) };
342
+ break;
343
+ }
344
+ case "baseline":
345
+ options.baselineDir = value;
346
+ break;
347
+ case "packMaxBytes":
348
+ options.packMaxBytes = Number(value);
349
+ break;
350
+ case "inputs":
351
+ options.inputsFile = value;
352
+ break;
353
+ case "maxUsedServices":
354
+ options.maxUsedServices = Number(value);
355
+ break;
356
+ case "maxRawMode":
357
+ options.maxRawMode = Number(value);
358
+ break;
359
+ default:
360
+ throw invalidArgument(`\u672A\u77E5\u53C2\u6570\uFF1A${token}`, helpText);
361
+ }
362
+ continue;
363
+ }
364
+ switch (key) {
365
+ case "includeTrace":
366
+ options.includeTrace = !token.startsWith("--no");
367
+ break;
368
+ case "allowWarn":
369
+ options.allowWarn = !token.startsWith("--no");
370
+ break;
371
+ case "includeContextPack":
372
+ options.includeContextPack = !token.startsWith("--no");
373
+ break;
374
+ case "requireRulesManifest":
375
+ options.requireRulesManifest = !token.startsWith("--no");
376
+ break;
377
+ case "includeUiKitRegistry":
378
+ options.includeUiKitRegistry = !token.startsWith("--no");
379
+ break;
380
+ case "includeAnchorAutofill":
381
+ options.includeAnchorAutofill = !token.startsWith("--no");
382
+ break;
383
+ case "json":
384
+ options.describeJson = !token.startsWith("--no");
385
+ break;
386
+ default:
387
+ throw invalidArgument(`\u672A\u77E5\u53C2\u6570\uFF1A${token}`, helpText);
388
+ }
389
+ }
390
+ return options;
391
+ });
392
+ var parseManualLeaf = (argv, helpText) => Effect.gen(function* () {
393
+ const normalized = normalizeArgvForEffectCli(argv);
394
+ const extracted = findCommandTokens(normalized);
395
+ if (!extracted) {
396
+ return yield* Effect.fail(
397
+ makeCliError({
398
+ code: "CLI_INVALID_COMMAND",
399
+ message: "\u7F3A\u5C11\u547D\u4EE4\uFF1A\u8BF7\u63D0\u4F9B <group> <subcommand>\uFF08\u6216 trialrun\uFF09",
400
+ hint: helpText
401
+ })
402
+ );
403
+ }
404
+ const drop = new Set(extracted.indices);
405
+ const rest = normalized.filter((_, idx) => !drop.has(idx));
406
+ const options = yield* parseManualOptions(rest, helpText);
407
+ const commandKey = extracted.tokens.join(".");
408
+ switch (commandKey) {
409
+ case "describe":
410
+ if (!options.describeJson) {
411
+ return yield* Effect.fail(invalidArgument("describe \u4EC5\u652F\u6301\u673A\u5668\u53EF\u8BFB\u8F93\u51FA\uFF0C\u8BF7\u663E\u5F0F\u63D0\u4F9B --json", helpText));
412
+ }
413
+ return { command: "describe", options, format: "json" };
414
+ case "ir.export":
415
+ return { command: "ir.export", options, entry: yield* parseEntryRefFromOptions(options) };
416
+ case "ir.validate":
417
+ return { command: "ir.validate", options, input: yield* parseIrValidateInputFromOptions(options) };
418
+ case "ir.diff": {
419
+ const diff = yield* parseIrDiffInputFromOptions(options);
420
+ return { command: "ir.diff", options, before: diff.before, after: diff.after };
421
+ }
422
+ case "trialrun":
423
+ return {
424
+ command: "trialrun",
425
+ options,
426
+ entry: yield* parseEntryRefFromOptions(options),
427
+ diagnosticsLevel: options.diagnosticsLevel,
428
+ ...typeof options.maxEvents === "number" ? { maxEvents: options.maxEvents } : null,
429
+ ...typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : null,
430
+ includeTrace: options.includeTrace,
431
+ config: options.config
432
+ };
433
+ case "contract-suite.run":
434
+ return {
435
+ command: "contract-suite.run",
436
+ options,
437
+ entry: yield* parseEntryRefFromOptions(options),
438
+ diagnosticsLevel: options.diagnosticsLevel,
439
+ ...typeof options.maxEvents === "number" ? { maxEvents: options.maxEvents } : null,
440
+ ...typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : null,
441
+ includeTrace: options.includeTrace,
442
+ config: options.config,
443
+ allowWarn: options.allowWarn,
444
+ ...options.baselineDir ? { baselineDir: options.baselineDir } : null,
445
+ includeContextPack: options.includeContextPack,
446
+ ...typeof options.packMaxBytes === "number" ? { packMaxBytes: options.packMaxBytes } : null,
447
+ requireRulesManifest: options.requireRulesManifest,
448
+ ...options.inputsFile ? { inputsFile: options.inputsFile } : null,
449
+ includeUiKitRegistry: options.includeUiKitRegistry,
450
+ includeAnchorAutofill: options.includeAnchorAutofill,
451
+ repoRoot: options.repoRoot
452
+ };
453
+ case "spy.evidence":
454
+ return {
455
+ command: "spy.evidence",
456
+ options,
457
+ entry: yield* parseEntryRefFromOptions(options),
458
+ ...typeof options.maxUsedServices === "number" ? { maxUsedServices: options.maxUsedServices } : null,
459
+ ...typeof options.maxRawMode === "number" ? { maxRawMode: options.maxRawMode } : null,
460
+ ...typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : null
461
+ };
462
+ case "anchor.index":
463
+ return { command: "anchor.index", options, repoRoot: options.repoRoot };
464
+ case "anchor.autofill":
465
+ return { command: "anchor.autofill", options, repoRoot: options.repoRoot };
466
+ case "transform.module": {
467
+ const opsPath = typeof options.opsPath === "string" && options.opsPath.length > 0 ? options.opsPath : void 0;
468
+ if (!opsPath) {
469
+ return yield* Effect.fail(invalidArgument("\u7F3A\u5C11\u8F93\u5165\uFF1A\u8BF7\u63D0\u4F9B --ops <delta.json|->", helpText));
470
+ }
471
+ return { command: "transform.module", options, repoRoot: options.repoRoot, opsPath };
472
+ }
473
+ default:
474
+ return yield* Effect.fail(
475
+ makeCliError({
476
+ code: "CLI_INVALID_COMMAND",
477
+ message: `\u672A\u77E5\u547D\u4EE4\uFF1A${commandKey}`,
478
+ hint: helpText
479
+ })
480
+ );
481
+ }
482
+ });
483
+ var parseCliInvocation = (argv, options) => {
484
+ if (argv.includes("-h") || argv.includes("--help") || argv.length === 0) {
485
+ return Effect.succeed({ kind: "help", text: options.helpText });
486
+ }
487
+ return parseManualLeaf(argv, options.helpText).pipe(
488
+ Effect.flatMap((leaf) => {
489
+ const runId = typeof leaf.options.runId === "string" ? leaf.options.runId.trim() : void 0;
490
+ if (!runId) {
491
+ return Effect.fail(makeCliError({ code: "CLI_MISSING_RUNID", message: "\u7F3A\u5C11 --runId\uFF08\u5FC5\u987B\u663E\u5F0F\u63D0\u4F9B\uFF09" }));
492
+ }
493
+ const outDirExplicit = typeof leaf.options.out === "string" ? leaf.options.out.trim() : void 0;
494
+ const outRoot = typeof leaf.options.outRoot === "string" ? leaf.options.outRoot.trim() : void 0;
495
+ const outDir = outDirExplicit ?? (outRoot ? path.join(outRoot, leaf.command, runId) : void 0);
496
+ const budgetBytes = typeof leaf.options.budgetBytes === "number" ? leaf.options.budgetBytes : void 0;
497
+ const mode = leaf.options.mode;
498
+ const tsconfig = typeof leaf.options.tsconfig === "string" ? leaf.options.tsconfig.trim() : void 0;
499
+ const global = {
500
+ runId,
501
+ ...outDir ? { outDir } : null,
502
+ ...budgetBytes ? { budgetBytes } : null,
503
+ ...mode ? { mode } : null,
504
+ ...tsconfig ? { tsconfig } : null,
505
+ host: leaf.options.host
506
+ };
507
+ switch (leaf.command) {
508
+ case "describe":
509
+ return Effect.succeed({ kind: "command", command: "describe", global, format: leaf.format });
510
+ case "ir.export":
511
+ return Effect.succeed({ kind: "command", command: "ir.export", global, entry: leaf.entry });
512
+ case "ir.validate":
513
+ return Effect.succeed({ kind: "command", command: "ir.validate", global, input: leaf.input });
514
+ case "ir.diff":
515
+ return Effect.succeed({ kind: "command", command: "ir.diff", global, before: leaf.before, after: leaf.after });
516
+ case "trialrun":
517
+ return Effect.succeed({
518
+ kind: "command",
519
+ command: "trialrun",
520
+ global,
521
+ entry: leaf.entry,
522
+ diagnosticsLevel: leaf.diagnosticsLevel,
523
+ ...typeof leaf.maxEvents === "number" ? { maxEvents: leaf.maxEvents } : null,
524
+ ...typeof leaf.timeoutMs === "number" ? { timeoutMs: leaf.timeoutMs } : null,
525
+ includeTrace: leaf.includeTrace,
526
+ config: leaf.config
527
+ });
528
+ case "contract-suite.run":
529
+ return Effect.succeed({
530
+ kind: "command",
531
+ command: "contract-suite.run",
532
+ global,
533
+ entry: leaf.entry,
534
+ diagnosticsLevel: leaf.diagnosticsLevel,
535
+ ...typeof leaf.maxEvents === "number" ? { maxEvents: leaf.maxEvents } : null,
536
+ ...typeof leaf.timeoutMs === "number" ? { timeoutMs: leaf.timeoutMs } : null,
537
+ includeTrace: leaf.includeTrace,
538
+ config: leaf.config,
539
+ allowWarn: leaf.allowWarn,
540
+ ...leaf.baselineDir ? { baselineDir: leaf.baselineDir } : null,
541
+ includeContextPack: leaf.includeContextPack,
542
+ ...typeof leaf.packMaxBytes === "number" ? { packMaxBytes: leaf.packMaxBytes } : null,
543
+ requireRulesManifest: leaf.requireRulesManifest,
544
+ ...leaf.inputsFile ? { inputsFile: leaf.inputsFile } : null,
545
+ includeUiKitRegistry: leaf.includeUiKitRegistry,
546
+ includeAnchorAutofill: leaf.includeAnchorAutofill,
547
+ repoRoot: leaf.repoRoot
548
+ });
549
+ case "spy.evidence":
550
+ return Effect.succeed({
551
+ kind: "command",
552
+ command: "spy.evidence",
553
+ global,
554
+ entry: leaf.entry,
555
+ ...typeof leaf.maxUsedServices === "number" ? { maxUsedServices: leaf.maxUsedServices } : null,
556
+ ...typeof leaf.maxRawMode === "number" ? { maxRawMode: leaf.maxRawMode } : null,
557
+ ...typeof leaf.timeoutMs === "number" ? { timeoutMs: leaf.timeoutMs } : null
558
+ });
559
+ case "anchor.index":
560
+ return Effect.succeed({ kind: "command", command: "anchor.index", global, repoRoot: leaf.repoRoot });
561
+ case "anchor.autofill":
562
+ return Effect.succeed({ kind: "command", command: "anchor.autofill", global, repoRoot: leaf.repoRoot });
563
+ case "transform.module":
564
+ return Effect.succeed(
565
+ { kind: "command", command: "transform.module", global, repoRoot: leaf.repoRoot, opsPath: leaf.opsPath }
566
+ );
567
+ }
568
+ }),
569
+ Effect.catch(
570
+ (cause) => Effect.fail(
571
+ makeCliError({
572
+ code: "CLI_INVALID_ARGUMENT",
573
+ message: renderValidationError(cause),
574
+ hint: options.helpText,
575
+ cause
576
+ })
577
+ )
578
+ )
579
+ );
580
+ };
581
+
582
+ // src/internal/cliConfig.ts
583
+ import { Effect as Effect2 } from "effect";
584
+ import fs from "fs/promises";
585
+ import path2 from "path";
586
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
587
+ var asNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
588
+ var asPositiveInt = (value) => {
589
+ const n = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
590
+ if (!Number.isFinite(n) || n <= 0) return void 0;
591
+ return Math.floor(n);
592
+ };
593
+ var capitalize = (s) => s.length === 0 ? s : `${s[0].toUpperCase()}${s.slice(1)}`;
594
+ var readJsonFile = (filePath) => Effect2.tryPromise({
595
+ try: async () => JSON.parse(await fs.readFile(filePath, "utf8")),
596
+ catch: (cause) => makeCliError({
597
+ code: "CLI_INVALID_INPUT",
598
+ message: `[Logix][CLI] \u65E0\u6CD5\u8BFB\u53D6/\u89E3\u6790\u914D\u7F6E\u6587\u4EF6\uFF1A${filePath}`,
599
+ cause
600
+ })
601
+ });
602
+ var statExists = (filePath) => Effect2.tryPromise({
603
+ try: async () => {
604
+ await fs.stat(filePath);
605
+ return true;
606
+ },
607
+ catch: (cause) => cause
608
+ }).pipe(Effect2.catch(() => Effect2.succeed(false)));
609
+ var findUp = (startDir, fileName) => Effect2.gen(function* () {
610
+ let dir = path2.resolve(startDir);
611
+ while (true) {
612
+ const candidate = path2.join(dir, fileName);
613
+ if (yield* statExists(candidate)) return candidate;
614
+ const parent = path2.dirname(dir);
615
+ if (parent === dir) return void 0;
616
+ dir = parent;
617
+ }
618
+ });
619
+ var getFlag = (argv, name) => {
620
+ const idx = argv.lastIndexOf(`--${name}`);
621
+ if (idx < 0) return void 0;
622
+ const next = argv[idx + 1];
623
+ if (!next || next.startsWith("--")) {
624
+ throw makeCliError({ code: "CLI_INVALID_ARGUMENT", message: `--${name} \u7F3A\u5C11\u53C2\u6570` });
625
+ }
626
+ return next;
627
+ };
628
+ var parseCliConfigPath = (argv) => getFlag(argv, "cliConfig") ?? void 0;
629
+ var parseProfile = (argv) => {
630
+ const raw = getFlag(argv, "profile");
631
+ return asNonEmptyString(raw);
632
+ };
633
+ var validateDefaults = (input, label) => {
634
+ if (!isRecord(input)) {
635
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label} \u5FC5\u987B\u662F\u5BF9\u8C61` });
636
+ }
637
+ const knownKeys = /* @__PURE__ */ new Set([
638
+ "outRoot",
639
+ "repoRoot",
640
+ "tsconfig",
641
+ "host",
642
+ "budgetBytes",
643
+ "diagnosticsLevel",
644
+ "maxEvents",
645
+ "timeout",
646
+ "baseline",
647
+ "inputs",
648
+ "packMaxBytes",
649
+ "allowWarn",
650
+ "includeTrace",
651
+ "includeContextPack",
652
+ "includeUiKitRegistry",
653
+ "requireRulesManifest",
654
+ "includeAnchorAutofill",
655
+ "entry"
656
+ ]);
657
+ for (const key of Object.keys(input)) {
658
+ if (!knownKeys.has(key)) {
659
+ throw makeCliError({
660
+ code: "CLI_INVALID_INPUT",
661
+ message: `[Logix][CLI] ${label} \u5305\u542B\u672A\u77E5\u5B57\u6BB5\uFF1A${key}`,
662
+ hint: "\u8BF7\u66F4\u65B0\u914D\u7F6E\u6587\u4EF6\u6216\u5347\u7EA7 CLI\uFF1B\u914D\u7F6E schemaVersion=1 \u4E0D\u5141\u8BB8\u672A\u77E5\u5B57\u6BB5\u3002"
663
+ });
664
+ }
665
+ }
666
+ const diagnosticsLevel = input.diagnosticsLevel;
667
+ if (diagnosticsLevel !== void 0 && diagnosticsLevel !== "off" && diagnosticsLevel !== "light" && diagnosticsLevel !== "full") {
668
+ throw makeCliError({
669
+ code: "CLI_INVALID_INPUT",
670
+ message: `[Logix][CLI] ${label}.diagnosticsLevel \u975E\u6CD5\uFF1A${String(diagnosticsLevel)}\uFF08\u671F\u671B off|light|full\uFF09`
671
+ });
672
+ }
673
+ const allowWarn = input.allowWarn;
674
+ if (allowWarn !== void 0 && typeof allowWarn !== "boolean") {
675
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.allowWarn \u5FC5\u987B\u662F boolean` });
676
+ }
677
+ const includeTrace = input.includeTrace;
678
+ if (includeTrace !== void 0 && typeof includeTrace !== "boolean") {
679
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.includeTrace \u5FC5\u987B\u662F boolean` });
680
+ }
681
+ const includeContextPack = input.includeContextPack;
682
+ if (includeContextPack !== void 0 && typeof includeContextPack !== "boolean") {
683
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.includeContextPack \u5FC5\u987B\u662F boolean` });
684
+ }
685
+ const includeUiKitRegistry = input.includeUiKitRegistry;
686
+ if (includeUiKitRegistry !== void 0 && typeof includeUiKitRegistry !== "boolean") {
687
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.includeUiKitRegistry \u5FC5\u987B\u662F boolean` });
688
+ }
689
+ const requireRulesManifest = input.requireRulesManifest;
690
+ if (requireRulesManifest !== void 0 && typeof requireRulesManifest !== "boolean") {
691
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.requireRulesManifest \u5FC5\u987B\u662F boolean` });
692
+ }
693
+ const includeAnchorAutofill = input.includeAnchorAutofill;
694
+ if (includeAnchorAutofill !== void 0 && typeof includeAnchorAutofill !== "boolean") {
695
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.includeAnchorAutofill \u5FC5\u987B\u662F boolean` });
696
+ }
697
+ const budgetBytes = input.budgetBytes;
698
+ if (budgetBytes !== void 0 && asPositiveInt(budgetBytes) === void 0) {
699
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.budgetBytes \u5FC5\u987B\u662F\u6B63\u6574\u6570` });
700
+ }
701
+ const maxEvents = input.maxEvents;
702
+ if (maxEvents !== void 0 && asPositiveInt(maxEvents) === void 0) {
703
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.maxEvents \u5FC5\u987B\u662F\u6B63\u6574\u6570` });
704
+ }
705
+ const timeout = input.timeout;
706
+ if (timeout !== void 0 && asPositiveInt(timeout) === void 0) {
707
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.timeout \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08ms\uFF09` });
708
+ }
709
+ const packMaxBytes = input.packMaxBytes;
710
+ if (packMaxBytes !== void 0 && asPositiveInt(packMaxBytes) === void 0) {
711
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.packMaxBytes \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08bytes\uFF09` });
712
+ }
713
+ const outRoot = input.outRoot;
714
+ if (outRoot !== void 0 && asNonEmptyString(outRoot) === void 0) {
715
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.outRoot \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32` });
716
+ }
717
+ const repoRoot = input.repoRoot;
718
+ if (repoRoot !== void 0 && asNonEmptyString(repoRoot) === void 0) {
719
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.repoRoot \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32` });
720
+ }
721
+ const tsconfig = input.tsconfig;
722
+ if (tsconfig !== void 0 && asNonEmptyString(tsconfig) === void 0) {
723
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.tsconfig \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32` });
724
+ }
725
+ const host = input.host;
726
+ if (host !== void 0 && host !== "node" && host !== "browser-mock") {
727
+ throw makeCliError({
728
+ code: "CLI_INVALID_INPUT",
729
+ message: `[Logix][CLI] ${label}.host \u975E\u6CD5\uFF1A${String(host)}\uFF08\u671F\u671B node|browser-mock\uFF09`
730
+ });
731
+ }
732
+ const baseline = input.baseline;
733
+ if (baseline !== void 0 && asNonEmptyString(baseline) === void 0) {
734
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.baseline \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32` });
735
+ }
736
+ const inputs = input.inputs;
737
+ if (inputs !== void 0 && asNonEmptyString(inputs) === void 0) {
738
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.inputs \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32` });
739
+ }
740
+ const entry = input.entry;
741
+ if (entry !== void 0 && asNonEmptyString(entry) === void 0) {
742
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] ${label}.entry \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32` });
743
+ }
744
+ return {
745
+ ...outRoot !== void 0 ? { outRoot: asNonEmptyString(outRoot) } : null,
746
+ ...repoRoot !== void 0 ? { repoRoot: asNonEmptyString(repoRoot) } : null,
747
+ ...tsconfig !== void 0 ? { tsconfig: asNonEmptyString(tsconfig) } : null,
748
+ ...host !== void 0 ? { host } : null,
749
+ ...budgetBytes !== void 0 ? { budgetBytes: asPositiveInt(budgetBytes) } : null,
750
+ ...diagnosticsLevel !== void 0 ? { diagnosticsLevel } : null,
751
+ ...maxEvents !== void 0 ? { maxEvents: asPositiveInt(maxEvents) } : null,
752
+ ...timeout !== void 0 ? { timeout: asPositiveInt(timeout) } : null,
753
+ ...baseline !== void 0 ? { baseline: asNonEmptyString(baseline) } : null,
754
+ ...inputs !== void 0 ? { inputs: asNonEmptyString(inputs) } : null,
755
+ ...packMaxBytes !== void 0 ? { packMaxBytes: asPositiveInt(packMaxBytes) } : null,
756
+ ...allowWarn !== void 0 ? { allowWarn } : null,
757
+ ...includeTrace !== void 0 ? { includeTrace } : null,
758
+ ...includeContextPack !== void 0 ? { includeContextPack } : null,
759
+ ...includeUiKitRegistry !== void 0 ? { includeUiKitRegistry } : null,
760
+ ...requireRulesManifest !== void 0 ? { requireRulesManifest } : null,
761
+ ...includeAnchorAutofill !== void 0 ? { includeAnchorAutofill } : null,
762
+ ...entry !== void 0 ? { entry: asNonEmptyString(entry) } : null
763
+ };
764
+ };
765
+ var validateConfigFile = (input, filePath) => {
766
+ if (!isRecord(input)) {
767
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: `[Logix][CLI] \u914D\u7F6E\u6587\u4EF6\u5FC5\u987B\u662F JSON object\uFF1A${filePath}` });
768
+ }
769
+ const schemaVersion = input.schemaVersion;
770
+ if (schemaVersion !== 1) {
771
+ throw makeCliError({
772
+ code: "CLI_INVALID_INPUT",
773
+ message: `[Logix][CLI] \u914D\u7F6E\u6587\u4EF6 schemaVersion \u975E\u6CD5\uFF1A${String(schemaVersion)}\uFF08\u671F\u671B 1\uFF09`
774
+ });
775
+ }
776
+ const defaultsRaw = input.defaults;
777
+ const profilesRaw = input.profiles;
778
+ const defaults = defaultsRaw !== void 0 ? validateDefaults(defaultsRaw, "defaults") : void 0;
779
+ let profiles;
780
+ if (profilesRaw !== void 0) {
781
+ if (!isRecord(profilesRaw)) {
782
+ throw makeCliError({ code: "CLI_INVALID_INPUT", message: "[Logix][CLI] profiles \u5FC5\u987B\u662F\u5BF9\u8C61\uFF08Record<string, defaults>\uFF09" });
783
+ }
784
+ profiles = {};
785
+ for (const [name, raw] of Object.entries(profilesRaw)) {
786
+ const key = asNonEmptyString(name);
787
+ if (!key) continue;
788
+ profiles[key] = validateDefaults(raw, `profiles.${key}`);
789
+ }
790
+ }
791
+ return {
792
+ schemaVersion: 1,
793
+ ...defaults ? { defaults } : null,
794
+ ...profiles ? { profiles } : null
795
+ };
796
+ };
797
+ var toArgvPrefix = (defaults) => {
798
+ const tokens = [];
799
+ if (defaults.outRoot) tokens.push("--outRoot", defaults.outRoot);
800
+ if (defaults.repoRoot) tokens.push("--repoRoot", defaults.repoRoot);
801
+ if (defaults.tsconfig) tokens.push("--tsconfig", defaults.tsconfig);
802
+ if (defaults.host) tokens.push("--host", defaults.host);
803
+ if (defaults.budgetBytes) tokens.push("--budgetBytes", String(defaults.budgetBytes));
804
+ if (defaults.diagnosticsLevel) tokens.push("--diagnosticsLevel", defaults.diagnosticsLevel);
805
+ if (defaults.maxEvents) tokens.push("--maxEvents", String(defaults.maxEvents));
806
+ if (defaults.timeout) tokens.push("--timeout", String(defaults.timeout));
807
+ if (defaults.baseline) tokens.push("--baseline", defaults.baseline);
808
+ if (defaults.inputs) tokens.push("--inputs", defaults.inputs);
809
+ if (defaults.packMaxBytes) tokens.push("--packMaxBytes", String(defaults.packMaxBytes));
810
+ if (defaults.entry) tokens.push("--entry", defaults.entry);
811
+ const bool = (key, flag) => {
812
+ const value = defaults[key];
813
+ if (value === true) tokens.push(`--${flag}`);
814
+ if (value === false) tokens.push(`--no${capitalize(flag)}`);
815
+ };
816
+ bool("allowWarn", "allowWarn");
817
+ bool("includeTrace", "includeTrace");
818
+ bool("includeContextPack", "includeContextPack");
819
+ bool("includeUiKitRegistry", "includeUiKitRegistry");
820
+ bool("requireRulesManifest", "requireRulesManifest");
821
+ bool("includeAnchorAutofill", "includeAnchorAutofill");
822
+ return tokens;
823
+ };
824
+ var resolveCliConfigArgvPrefixResolution = (argv) => Effect2.gen(function* () {
825
+ const explicitPathRaw = parseCliConfigPath(argv);
826
+ const profile = parseProfile(argv);
827
+ const configPath = explicitPathRaw ? path2.resolve(process.cwd(), explicitPathRaw) : yield* findUp(process.cwd(), "logix.cli.json");
828
+ if (!configPath) {
829
+ if (profile) {
830
+ throw makeCliError({
831
+ code: "CLI_INVALID_INPUT",
832
+ message: `[Logix][CLI] \u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF0C\u4F46\u6307\u5B9A\u4E86 --profile ${profile}`,
833
+ hint: "\u8BF7\u5728\u5F53\u524D\u76EE\u5F55\u6216\u4E0A\u5C42\u76EE\u5F55\u653E\u7F6E logix.cli.json\uFF0C\u6216\u4F7F\u7528 --cliConfig <path> \u6307\u5B9A\u3002"
834
+ });
835
+ }
836
+ return {
837
+ prefix: [],
838
+ ...explicitPathRaw ? { cliConfigPathArg: explicitPathRaw } : null,
839
+ ...profile ? { profile } : null,
840
+ layers: [],
841
+ discovery: { found: false }
842
+ };
843
+ }
844
+ if (explicitPathRaw && !(yield* statExists(configPath))) {
845
+ throw makeCliError({
846
+ code: "CLI_INVALID_INPUT",
847
+ message: `[Logix][CLI] \u6307\u5B9A\u7684\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${explicitPathRaw}`
848
+ });
849
+ }
850
+ const raw = yield* readJsonFile(configPath);
851
+ const config = validateConfigFile(raw, configPath);
852
+ const layers = [];
853
+ if (config.defaults) {
854
+ layers.push({
855
+ source: "defaults",
856
+ tokens: toArgvPrefix(config.defaults)
857
+ });
858
+ }
859
+ if (profile) {
860
+ const profileDefaults = config.profiles?.[profile];
861
+ if (!profileDefaults) {
862
+ throw makeCliError({
863
+ code: "CLI_INVALID_INPUT",
864
+ message: `[Logix][CLI] \u672A\u627E\u5230 profile\uFF1A${profile}`
865
+ });
866
+ }
867
+ layers.push({
868
+ source: "profile",
869
+ profile,
870
+ tokens: toArgvPrefix(profileDefaults)
871
+ });
872
+ }
873
+ return {
874
+ prefix: layers.flatMap((layer) => layer.tokens),
875
+ ...explicitPathRaw ? { cliConfigPathArg: explicitPathRaw } : null,
876
+ ...profile ? { profile } : null,
877
+ discoveredPath: configPath,
878
+ layers,
879
+ discovery: {
880
+ found: true,
881
+ path: configPath,
882
+ ok: true,
883
+ config,
884
+ profiles: Object.keys(config.profiles ?? {}).sort()
885
+ }
886
+ };
887
+ });
888
+ var resolveCliConfigArgvPrefix = (argv) => resolveCliConfigArgvPrefixResolution(argv).pipe(Effect2.map((resolved) => resolved.prefix));
889
+
890
+ // src/Commands.ts
891
+ var formatCommandResult = (result) => stableStringifyJson(result);
892
+ var printHelp = () => `logix
893
+
894
+ \u7528\u6CD5:
895
+ logix describe --runId <id> --json [--out <dir>]
896
+ logix ir export --runId <id> --entry <modulePath>#<exportName> [--out <dir>]
897
+ logix ir validate --runId <id> --in <dir> [--out <dir>]
898
+ logix ir diff --runId <id> --before <dir|file> --after <dir|file> [--out <dir>]
899
+ logix trialrun --runId <id> --entry <modulePath>#<exportName> [--out <dir>] [--diagnosticsLevel off|light|full] [--maxEvents <n>] [--timeout <ms>] [--includeTrace]
900
+ logix contract-suite run --runId <id> --entry <modulePath>#<exportName> [--baseline <dir>] [--out <dir>] [--allowWarn] [--includeContextPack] [--inputs <file|->] [--includeUiKitRegistry] [--packMaxBytes <n>] [--requireRulesManifest] [--includeAnchorAutofill] [--repoRoot <dir>] [--diagnosticsLevel off|light|full] [--maxEvents <n>] [--timeout <ms>] [--includeTrace]
901
+ logix spy evidence --runId <id> --entry <modulePath>#<exportName> [--out <dir>] [--maxUsedServices <n>] [--maxRawMode <n>] [--timeout <ms>]
902
+ logix anchor index --runId <id> [--repoRoot <dir>] [--out <dir>]
903
+ logix anchor autofill --runId <id> [--repoRoot <dir>] [--mode report|write] [--tsconfig <path>] [--out <dir>]
904
+ logix transform module --runId <id> --ops <delta.json|-> [--mode report|write] [--repoRoot <dir>] [--tsconfig <path>] [--out <dir>]
905
+
906
+ \u5168\u5C40\u53C2\u6570:
907
+ --runId <string> \u5FC5\u987B\u663E\u5F0F\u63D0\u4F9B\uFF08\u7528\u4E8E\u786E\u5B9A\u6027\u5DE5\u4EF6\u547D\u540D\u4E0E\u5173\u8054\uFF09
908
+ --out <dir> \u53EF\u9009\uFF1A\u7A33\u5B9A\u843D\u76D8\u76EE\u5F55\uFF08stdout \u4ECD\u8F93\u51FA CommandResult@v1\uFF09
909
+ --outRoot <dir> \u53EF\u9009\uFF1A\u5F53\u672A\u663E\u5F0F --out \u65F6\uFF0C\u81EA\u52A8\u843D\u76D8\u5230 <outRoot>/<command>/<runId>
910
+ --budgetBytes <n> \u53EF\u9009\uFF1Astdout inline artifact \u7684\u9884\u7B97\u4E0A\u9650\uFF08\u8D85\u9650\u4F1A\u622A\u65AD\u5E76\u6807\u8BB0\uFF09
911
+ --mode report|write \u53EF\u9009\uFF1A\u5199\u56DE\u6A21\u5F0F\uFF08\u9ED8\u8BA4 report\uFF1B\u4EC5\u5BF9\u53EF\u5199\u56DE\u547D\u4EE4\u751F\u6548\uFF09
912
+ --tsconfig <path> \u53EF\u9009\uFF1Ats-morph \u89E3\u6790/\u6539\u5199\u6240\u7528 tsconfig\uFF08\u9ED8\u8BA4\u81EA\u52A8\u63A2\u6D4B/\u964D\u7EA7\uFF09
913
+ --host <name> \u53EF\u9009\uFF1A\u6267\u884C\u5BBF\u4E3B\uFF08node|browser-mock\uFF1B\u9ED8\u8BA4 node\uFF1B\u5F71\u54CD\u5165\u53E3\u52A0\u8F7D/\u8BD5\u8DD1\uFF09
914
+ --cliConfig <path> \u53EF\u9009\uFF1A\u663E\u5F0F\u6307\u5B9A logix.cli.json\uFF08\u4E0D\u63D0\u4F9B\u5219\u4ECE cwd \u5411\u4E0A\u67E5\u627E\uFF09
915
+ --profile <name> \u53EF\u9009\uFF1A\u9009\u62E9\u914D\u7F6E\u6587\u4EF6\u4E2D\u7684 profile\uFF08\u5728 defaults \u4E4B\u4E0A\u53E0\u52A0\uFF09
916
+ --config <K=V> \u53EF\u9009\uFF1A\u6CE8\u5165\u8FD0\u884C\u73AF\u5883 config\uFF08\u53EF\u91CD\u590D\uFF1B\u4EC5 trialrun/contract-suite \u6D88\u8D39\uFF09
917
+ -h, --help \u663E\u793A\u5E2E\u52A9
918
+ `;
919
+ var EMPTY_CLI_CONFIG_RESOLUTION = {
920
+ prefix: [],
921
+ layers: [],
922
+ discovery: { found: false }
923
+ };
924
+ var runIrExport = (inv) => Effect3.tryPromise({
925
+ try: () => import("./irExport-EI2VYIMT.js"),
926
+ catch: (cause) => makeCliError({
927
+ code: "CLI_COMMAND_IMPORT_FAILED",
928
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Air.export",
929
+ cause
930
+ })
931
+ }).pipe(Effect3.flatMap((mod) => mod.runIrExport(inv)));
932
+ var runDescribe = (inv, ctx) => Effect3.tryPromise({
933
+ try: () => import("./describe-5MFSLD7R.js"),
934
+ catch: (cause) => makeCliError({
935
+ code: "CLI_COMMAND_IMPORT_FAILED",
936
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Adescribe",
937
+ cause
938
+ })
939
+ }).pipe(
940
+ Effect3.flatMap(
941
+ (mod) => mod.runDescribe(inv, {
942
+ argv: ctx.argv,
943
+ argvWithConfigPrefix: ctx.argvWithConfigPrefix,
944
+ cliConfig: ctx.cliConfig
945
+ })
946
+ )
947
+ );
948
+ var runTrialRun = (inv) => Effect3.tryPromise({
949
+ try: () => import("./trialRun-SWVYG67P.js"),
950
+ catch: (cause) => makeCliError({
951
+ code: "CLI_COMMAND_IMPORT_FAILED",
952
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Atrialrun",
953
+ cause
954
+ })
955
+ }).pipe(Effect3.flatMap((mod) => mod.runTrialRun(inv)));
956
+ var runContractSuiteRun = (inv) => Effect3.tryPromise({
957
+ try: () => import("./contractSuiteRun-5Y7LVI72.js"),
958
+ catch: (cause) => makeCliError({
959
+ code: "CLI_COMMAND_IMPORT_FAILED",
960
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Acontract-suite.run",
961
+ cause
962
+ })
963
+ }).pipe(Effect3.flatMap((mod) => mod.runContractSuiteRun(inv)));
964
+ var runSpyEvidence = (inv) => Effect3.tryPromise({
965
+ try: () => import("./spyEvidence-JTJDS2WN.js"),
966
+ catch: (cause) => makeCliError({
967
+ code: "CLI_COMMAND_IMPORT_FAILED",
968
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Aspy.evidence",
969
+ cause
970
+ })
971
+ }).pipe(Effect3.flatMap((mod) => mod.runSpyEvidence(inv)));
972
+ var runIrValidate = (inv) => Effect3.tryPromise({
973
+ try: () => import("./irValidate-JEQGVRL5.js"),
974
+ catch: (cause) => makeCliError({
975
+ code: "CLI_COMMAND_IMPORT_FAILED",
976
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Air.validate",
977
+ cause
978
+ })
979
+ }).pipe(Effect3.flatMap((mod) => mod.runIrValidate(inv)));
980
+ var runIrDiff = (inv) => Effect3.tryPromise({
981
+ try: () => import("./irDiff-WYXZEVA7.js"),
982
+ catch: (cause) => makeCliError({
983
+ code: "CLI_COMMAND_IMPORT_FAILED",
984
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Air.diff",
985
+ cause
986
+ })
987
+ }).pipe(Effect3.flatMap((mod) => mod.runIrDiff(inv)));
988
+ var runAnchorIndex = (inv) => Effect3.tryPromise({
989
+ try: () => import("./anchorIndex-IEFARUZM.js"),
990
+ catch: (cause) => makeCliError({
991
+ code: "CLI_COMMAND_IMPORT_FAILED",
992
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Aanchor.index",
993
+ cause
994
+ })
995
+ }).pipe(Effect3.flatMap((mod) => mod.runAnchorIndex(inv)));
996
+ var runAnchorAutofill = (inv) => Effect3.tryPromise({
997
+ try: () => import("./anchorAutofill-V6CAXQHT.js"),
998
+ catch: (cause) => makeCliError({
999
+ code: "CLI_COMMAND_IMPORT_FAILED",
1000
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Aanchor.autofill",
1001
+ cause
1002
+ })
1003
+ }).pipe(Effect3.flatMap((mod) => mod.runAnchorAutofill(inv)));
1004
+ var runTransformModule = (inv) => Effect3.tryPromise({
1005
+ try: () => import("./transformModule-D6YE3U5W.js"),
1006
+ catch: (cause) => makeCliError({
1007
+ code: "CLI_COMMAND_IMPORT_FAILED",
1008
+ message: "[Logix][CLI] \u52A0\u8F7D\u547D\u4EE4\u5931\u8D25\uFF1Atransform.module",
1009
+ cause
1010
+ })
1011
+ }).pipe(Effect3.flatMap((mod) => mod.runTransformModule(inv)));
1012
+ var runCommand = (inv, ctx) => {
1013
+ switch (inv.command) {
1014
+ case "describe":
1015
+ return runDescribe(inv, ctx);
1016
+ case "ir.export":
1017
+ return runIrExport(inv);
1018
+ case "ir.validate":
1019
+ return runIrValidate(inv);
1020
+ case "ir.diff":
1021
+ return runIrDiff(inv);
1022
+ case "trialrun":
1023
+ return runTrialRun(inv);
1024
+ case "contract-suite.run":
1025
+ return runContractSuiteRun(inv);
1026
+ case "spy.evidence":
1027
+ return runSpyEvidence(inv);
1028
+ case "anchor.index":
1029
+ return runAnchorIndex(inv);
1030
+ case "anchor.autofill":
1031
+ return runAnchorAutofill(inv);
1032
+ case "transform.module":
1033
+ return runTransformModule(inv);
1034
+ }
1035
+ };
1036
+ var isHelp = (x) => x.kind === "help";
1037
+ var tryGetRunId = (argv) => {
1038
+ const idx = argv.lastIndexOf("--runId");
1039
+ if (idx < 0) return void 0;
1040
+ const next = argv[idx + 1];
1041
+ if (!next || next.startsWith("--")) return void 0;
1042
+ return typeof next === "string" && next.length > 0 ? next : void 0;
1043
+ };
1044
+ var resolveRunIdForFailure = (argv) => {
1045
+ const fromArgv = tryGetRunId(argv);
1046
+ if (fromArgv) return Effect3.succeed(fromArgv);
1047
+ return resolveCliConfigArgvPrefix(argv).pipe(
1048
+ Effect3.map((prefix) => prefix.length > 0 ? [...prefix, ...argv] : argv),
1049
+ Effect3.map((argv2) => tryGetRunId(argv2) ?? "missing-runId"),
1050
+ Effect3.catch(() => Effect3.succeed("missing-runId"))
1051
+ );
1052
+ };
1053
+ var isHostErrorCode = (code) => code === "CLI_HOST_MISSING_BROWSER_GLOBAL" || code === "CLI_HOST_MISMATCH";
1054
+ var stripHostFromArgv = (argv) => {
1055
+ const out = [];
1056
+ for (let i = 0; i < argv.length; i++) {
1057
+ const token = argv[i];
1058
+ if (token === "--host") {
1059
+ i += 1;
1060
+ continue;
1061
+ }
1062
+ if (token.startsWith("--host=")) continue;
1063
+ out.push(token);
1064
+ }
1065
+ return out;
1066
+ };
1067
+ var makeCliDiagnosticsArtifact = (args) => {
1068
+ const argvNoHost = stripHostFromArgv(args.argv);
1069
+ const command = `logix --host browser-mock ${argvNoHost.join(" ")}`.trim();
1070
+ return {
1071
+ outputKey: "cliDiagnostics",
1072
+ kind: "CliDiagnostics",
1073
+ schemaVersion: 1,
1074
+ ok: true,
1075
+ inline: {
1076
+ schemaVersion: 1,
1077
+ kind: "CliDiagnostics",
1078
+ diagnostics: [
1079
+ {
1080
+ severity: "error",
1081
+ code: args.errorCode,
1082
+ message: args.errorCode === "CLI_HOST_MISSING_BROWSER_GLOBAL" ? "\u5165\u53E3\u9700\u8981\u6D4F\u89C8\u5668\u5168\u5C40\uFF08window/document/navigator \u7B49\uFF09\uFF1B\u8BF7\u7528 browser-mock host \u91CD\u8DD1\uFF0C\u6216\u628A\u6D4F\u89C8\u5668\u4EE3\u7801\u79FB\u51FA\u6A21\u5757\u9876\u5C42\u3002" : "host \u53EF\u80FD\u4E0D\u5339\u914D\uFF1B\u8BF7\u5C1D\u8BD5 browser-mock\uFF0C\u6216\u628A\u6D4F\u89C8\u5668\u4EE3\u7801\u79FB\u51FA\u6A21\u5757\u9876\u5C42\u3002",
1083
+ action: { kind: "run.command", command }
1084
+ }
1085
+ ]
1086
+ }
1087
+ };
1088
+ };
1089
+ var withHostDiagnosticsIfNeeded = (result, argv) => {
1090
+ if (result.ok) return result;
1091
+ const code = result.error?.code;
1092
+ if (!isHostErrorCode(code)) return result;
1093
+ if (result.artifacts.some((a) => a.outputKey === "cliDiagnostics")) return result;
1094
+ return {
1095
+ ...result,
1096
+ artifacts: [...result.artifacts, makeCliDiagnosticsArtifact({ errorCode: code, argv })]
1097
+ };
1098
+ };
1099
+ var runCli = (argv) => (argv.includes("-h") || argv.includes("--help") || argv.length === 0 ? Effect3.succeed({
1100
+ argv2: argv,
1101
+ cliConfig: EMPTY_CLI_CONFIG_RESOLUTION
1102
+ }) : resolveCliConfigArgvPrefixResolution(argv).pipe(
1103
+ Effect3.map((resolved) => ({
1104
+ argv2: resolved.prefix.length > 0 ? [...resolved.prefix, ...argv] : argv,
1105
+ cliConfig: resolved
1106
+ }))
1107
+ )).pipe(
1108
+ Effect3.flatMap(
1109
+ ({ argv2, cliConfig }) => parseCliInvocation(argv2, {
1110
+ helpText: printHelp()
1111
+ }).pipe(Effect3.map((parsed) => ({ argv2, parsed, cliConfig })))
1112
+ ),
1113
+ Effect3.matchEffect({
1114
+ onFailure: (cause) => {
1115
+ const error = asSerializableErrorSummary(cause);
1116
+ return resolveRunIdForFailure(argv).pipe(
1117
+ Effect3.map((runId) => ({
1118
+ kind: "result",
1119
+ result: makeErrorCommandResult({ runId, command: "unknown", error }),
1120
+ exitCode: exitCodeFromErrorSummary(error)
1121
+ }))
1122
+ );
1123
+ },
1124
+ onSuccess: ({ argv2, parsed, cliConfig }) => {
1125
+ if (isHelp(parsed)) {
1126
+ return Effect3.succeed({ kind: "help", text: parsed.text, exitCode: 0 });
1127
+ }
1128
+ return runCommand(parsed, {
1129
+ argv,
1130
+ argvWithConfigPrefix: argv2,
1131
+ cliConfig
1132
+ }).pipe(
1133
+ Effect3.map(
1134
+ (result) => {
1135
+ const result2 = withHostDiagnosticsIfNeeded(result, argv2);
1136
+ return {
1137
+ kind: "result",
1138
+ result: {
1139
+ ...result2,
1140
+ artifacts: sortArtifactsByOutputKey(result2.artifacts)
1141
+ },
1142
+ exitCode: result2.ok ? 0 : exitCodeFromErrorSummary(result2.error)
1143
+ };
1144
+ }
1145
+ ),
1146
+ Effect3.catchCause((cause) => {
1147
+ const error = asSerializableErrorSummary(
1148
+ makeCliError({
1149
+ code: "CLI_COMMAND_FAILED",
1150
+ message: `[Logix][CLI] \u547D\u4EE4\u6267\u884C\u5931\u8D25\uFF1A${parsed.command}`,
1151
+ cause
1152
+ })
1153
+ );
1154
+ const result = makeErrorCommandResult({
1155
+ runId: parsed.global.runId,
1156
+ command: parsed.command,
1157
+ error
1158
+ });
1159
+ return Effect3.succeed({ kind: "result", result, exitCode: 1 });
1160
+ })
1161
+ );
1162
+ }
1163
+ }),
1164
+ Effect3.catchCause((cause) => {
1165
+ const error = asSerializableErrorSummary(
1166
+ makeCliError({
1167
+ code: "CLI_INTERNAL",
1168
+ message: "[Logix][CLI] \u5165\u53E3\u6267\u884C\u5931\u8D25",
1169
+ cause
1170
+ })
1171
+ );
1172
+ return resolveRunIdForFailure(argv).pipe(
1173
+ Effect3.map((runId) => ({
1174
+ kind: "result",
1175
+ result: makeErrorCommandResult({ runId, command: "unknown", error }),
1176
+ exitCode: 1
1177
+ }))
1178
+ );
1179
+ }),
1180
+ // CLI stdout is a strict protocol (CommandResult@v1); silence Effect logs to avoid polluting stdout/stderr.
1181
+ Effect3.provide(Logger.layer([Logger.make(() => {
1182
+ })]))
1183
+ );
1184
+ var main = runCli;
1185
+
1186
+ export {
1187
+ formatCommandResult,
1188
+ printHelp,
1189
+ runCli,
1190
+ main,
1191
+ Commands_exports
1192
+ };
1193
+ //# sourceMappingURL=chunk-TDQVD2IA.js.map