@forge-ts/cli 0.2.1 → 0.3.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.
package/README.md CHANGED
@@ -12,7 +12,7 @@ npm install -D @forge-ts/cli
12
12
 
13
13
  Write your TypeScript. Write your TSDoc comments. Run one command. Get everything:
14
14
 
15
- - **OpenAPI 3.1 specs** from your exported types and interfaces
15
+ - **OpenAPI 3.2 specs** from your exported types and interfaces
16
16
  - **Executable doctests** from your `@example` blocks
17
17
  - **AI context** (`llms.txt` / `llms-full.txt`) for LLM agents
18
18
  - **Markdown/MDX docs** for Docusaurus, Mintlify, Nextra, or VitePress
package/dist/index.d.ts CHANGED
@@ -11,34 +11,54 @@ import * as citty from 'citty';
11
11
  */
12
12
  /** Typed result from a forge-ts command. */
13
13
  interface CommandOutput<T> {
14
+ /** Name of the command that produced this output (e.g., "check", "build"). */
14
15
  operation: string;
16
+ /** Whether the command completed successfully. */
15
17
  success: boolean;
18
+ /** Strongly-typed command-specific result payload. */
16
19
  data: T;
20
+ /** Structured errors produced by the command, if any. */
17
21
  errors?: ForgeCliError[];
22
+ /** Structured warnings produced by the command, if any. */
18
23
  warnings?: ForgeCliWarning[];
24
+ /** Wall-clock duration of the command in milliseconds. */
19
25
  duration?: number;
20
26
  }
21
27
  /** Structured error for CLI commands. */
22
28
  interface ForgeCliError {
29
+ /** Machine-readable error code (e.g., "E004"). */
23
30
  code: string;
31
+ /** Human-readable error description. */
24
32
  message: string;
33
+ /** Absolute path to the source file containing the error, if applicable. */
25
34
  filePath?: string;
35
+ /** 1-based line number of the error, if applicable. */
26
36
  line?: number;
37
+ /** 0-based column number of the error, if applicable. */
27
38
  column?: number;
28
39
  }
29
40
  /** Structured warning for CLI commands. */
30
41
  interface ForgeCliWarning {
42
+ /** Machine-readable warning code. */
31
43
  code: string;
44
+ /** Human-readable warning description. */
32
45
  message: string;
46
+ /** Absolute path to the source file containing the warning, if applicable. */
33
47
  filePath?: string;
48
+ /** 1-based line number of the warning, if applicable. */
34
49
  line?: number;
50
+ /** 0-based column number of the warning, if applicable. */
35
51
  column?: number;
36
52
  }
37
53
  /** Output format flags passed through from citty args. */
38
54
  interface OutputFlags {
55
+ /** Emit output as a LAFS JSON envelope instead of human-readable text. */
39
56
  json?: boolean;
57
+ /** Emit output as formatted human-readable text. */
40
58
  human?: boolean;
59
+ /** Suppress all output regardless of format. */
41
60
  quiet?: boolean;
61
+ /** MVI verbosity level: "minimal", "standard", or "full". */
42
62
  mvi?: string;
43
63
  }
44
64
  /**
@@ -51,6 +71,11 @@ interface OutputFlags {
51
71
  * @param output - Typed result from the command.
52
72
  * @param flags - Output format flags from citty args.
53
73
  * @param humanFormatter - Produces a human-readable string for TTY consumers.
74
+ * @example
75
+ * ```typescript
76
+ * import { emitResult } from "@forge-ts/cli/output";
77
+ * emitResult(output, { human: true }, (data) => `Done: ${data.summary.duration}ms`);
78
+ * ```
54
79
  * @internal
55
80
  */
56
81
  declare function emitResult<T>(output: CommandOutput<T>, flags: OutputFlags, humanFormatter: (data: T, output: CommandOutput<T>) => string): void;
@@ -63,6 +88,45 @@ declare function emitResult<T>(output: CommandOutput<T>, flags: OutputFlags, hum
63
88
  */
64
89
  declare function resolveExitCode(output: CommandOutput<unknown>): number;
65
90
 
91
+ /**
92
+ * A single step in the build pipeline.
93
+ * @public
94
+ */
95
+ interface BuildStep {
96
+ /** Internal step name, e.g. "api" or "gen". */
97
+ name: string;
98
+ /** Outcome of this step. */
99
+ status: "success" | "skipped" | "failed";
100
+ /** Path to the primary output file produced by this step, if applicable. */
101
+ outputPath?: string;
102
+ /** Wall-clock duration of this step in milliseconds. */
103
+ duration?: number;
104
+ /** Errors produced by this step when status is "failed". */
105
+ errors?: ForgeCliError[];
106
+ }
107
+ /**
108
+ * Typed result for the `build` command.
109
+ * @public
110
+ */
111
+ interface BuildResult {
112
+ /** Whether the build succeeded. */
113
+ success: boolean;
114
+ /** Aggregate pipeline counts — always present. */
115
+ summary: {
116
+ /** Total number of pipeline steps. */
117
+ steps: number;
118
+ /** Steps that completed successfully. */
119
+ succeeded: number;
120
+ /** Steps that failed. */
121
+ failed: number;
122
+ /** Wall-clock duration in milliseconds. */
123
+ duration: number;
124
+ };
125
+ /** Per-step details. */
126
+ steps: BuildStep[];
127
+ /** Files written during the build — present at standard and full MVI levels. */
128
+ generatedFiles?: string[];
129
+ }
66
130
  /**
67
131
  * Citty command definition for `forge-ts build`.
68
132
  * @public
@@ -103,6 +167,77 @@ declare const buildCommand: citty.CommandDef<{
103
167
  };
104
168
  }>;
105
169
 
170
+ /**
171
+ * A single error entry within a file group, included at standard and full MVI levels.
172
+ * @public
173
+ */
174
+ interface CheckFileError {
175
+ /** Machine-readable error code. */
176
+ code: string;
177
+ /** Symbol name that needs fixing. */
178
+ symbol: string;
179
+ /** Symbol kind (function, class, interface, etc.). */
180
+ kind: string;
181
+ /** 1-based line number of the error. */
182
+ line: number;
183
+ /** Human-readable description. */
184
+ message: string;
185
+ /** Exact TSDoc block to add (full MVI level only). */
186
+ suggestedFix?: string;
187
+ /** Recommended agent action (full MVI level only). */
188
+ agentAction?: string;
189
+ }
190
+ /**
191
+ * A single warning entry within a file group, included at standard and full MVI levels.
192
+ * @public
193
+ */
194
+ interface CheckFileWarning {
195
+ /** Machine-readable warning code. */
196
+ code: string;
197
+ /** Symbol name that generated the warning. */
198
+ symbol: string;
199
+ /** Symbol kind (function, class, interface, etc.). */
200
+ kind: string;
201
+ /** 1-based line number of the warning. */
202
+ line: number;
203
+ /** Human-readable description. */
204
+ message: string;
205
+ }
206
+ /**
207
+ * Errors and warnings grouped by file, included at standard and full MVI levels.
208
+ * @public
209
+ */
210
+ interface CheckFileGroup {
211
+ /** Absolute path to the source file. */
212
+ file: string;
213
+ /** Errors in this file. */
214
+ errors: CheckFileError[];
215
+ /** Warnings in this file. */
216
+ warnings: CheckFileWarning[];
217
+ }
218
+ /**
219
+ * Typed result for the `check` command.
220
+ * @public
221
+ */
222
+ interface CheckResult {
223
+ /** Whether the check passed without errors. */
224
+ success: boolean;
225
+ /** Aggregate counts — always present regardless of MVI level. */
226
+ summary: {
227
+ /** Total number of errors. */
228
+ errors: number;
229
+ /** Total number of warnings. */
230
+ warnings: number;
231
+ /** Number of unique files with diagnostics. */
232
+ files: number;
233
+ /** Number of exported symbols checked. */
234
+ symbols: number;
235
+ /** Wall-clock duration in milliseconds. */
236
+ duration: number;
237
+ };
238
+ /** Per-file breakdown — present at standard and full MVI levels. */
239
+ byFile?: CheckFileGroup[];
240
+ }
106
241
  /**
107
242
  * Citty command definition for `forge-ts check`.
108
243
  * @public
@@ -143,6 +278,41 @@ declare const checkCommand: citty.CommandDef<{
143
278
  };
144
279
  }>;
145
280
 
281
+ /**
282
+ * A single test failure entry, included at standard and full MVI levels.
283
+ * @public
284
+ */
285
+ interface TestFailure {
286
+ /** Symbol name where the doctest failed. */
287
+ symbol: string;
288
+ /** Absolute path to the source file. */
289
+ file: string;
290
+ /** 1-based line number of the failing example. */
291
+ line: number;
292
+ /** Human-readable failure message. */
293
+ message: string;
294
+ }
295
+ /**
296
+ * Typed result for the `test` command.
297
+ * @public
298
+ */
299
+ interface TestResult {
300
+ /** Whether all doctests passed. */
301
+ success: boolean;
302
+ /** Aggregate counts — always present regardless of MVI level. */
303
+ summary: {
304
+ /** Number of passing doctests. */
305
+ passed: number;
306
+ /** Number of failing doctests. */
307
+ failed: number;
308
+ /** Total doctests run. */
309
+ total: number;
310
+ /** Wall-clock duration in milliseconds. */
311
+ duration: number;
312
+ };
313
+ /** Per-failure details — present at standard and full MVI levels. */
314
+ failures?: TestFailure[];
315
+ }
146
316
  /**
147
317
  * Citty command definition for `forge-ts test`.
148
318
  * @public
@@ -215,4 +385,4 @@ declare function createLogger(options?: {
215
385
  colors?: boolean;
216
386
  }): Logger;
217
387
 
218
- export { type CommandOutput, type ForgeCliError, type ForgeCliWarning, type Logger, type OutputFlags, buildCommand, checkCommand, createLogger, emitResult, resolveExitCode, testCommand };
388
+ export { type BuildResult, type BuildStep, type CheckFileError, type CheckFileGroup, type CheckFileWarning, type CheckResult, type CommandOutput, type ForgeCliError, type ForgeCliWarning, type Logger, type OutputFlags, type TestFailure, type TestResult, buildCommand, checkCommand, createLogger, emitResult, resolveExitCode, testCommand };
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { defineCommand as defineCommand4, runMain } from "citty";
5
5
 
6
6
  // src/commands/build.ts
7
+ import { join } from "path";
7
8
  import { generateApi } from "@forge-ts/api";
8
9
  import { loadConfig } from "@forge-ts/core";
9
10
  import { generate } from "@forge-ts/gen";
@@ -119,8 +120,10 @@ function resolveExitCode(output) {
119
120
  async function runBuild(args) {
120
121
  const config = await loadConfig(args.cwd);
121
122
  const buildStart = Date.now();
123
+ const mviLevel = args.mvi ?? "standard";
122
124
  const steps = [];
123
125
  const allErrors = [];
126
+ const generatedFiles = [];
124
127
  let success = true;
125
128
  if (config.api.enabled && !args.skipApi) {
126
129
  const result = await generateApi(config);
@@ -148,6 +151,7 @@ async function runBuild(args) {
148
151
  outputPath: config.api.openapiPath,
149
152
  duration: result.duration
150
153
  });
154
+ generatedFiles.push(config.api.openapiPath);
151
155
  }
152
156
  } else if (!config.api.enabled || args.skipApi) {
153
157
  steps.push({ name: "api", status: "skipped" });
@@ -176,12 +180,34 @@ async function runBuild(args) {
176
180
  status: "success",
177
181
  duration: result.duration
178
182
  });
183
+ for (const format of config.gen.formats) {
184
+ const ext = format === "mdx" ? "mdx" : "md";
185
+ generatedFiles.push(join(config.outDir, `api-reference.${ext}`));
186
+ }
187
+ if (config.gen.llmsTxt) {
188
+ generatedFiles.push(join(config.outDir, "llms.txt"));
189
+ generatedFiles.push(join(config.outDir, "llms-full.txt"));
190
+ }
179
191
  }
180
192
  } else if (!config.gen.enabled || args.skipGen) {
181
193
  steps.push({ name: "gen", status: "skipped" });
182
194
  }
183
195
  const totalMs = Date.now() - buildStart;
184
- const data = { steps, duration: totalMs };
196
+ const succeededCount = steps.filter((s) => s.status === "success").length;
197
+ const failedCount = steps.filter((s) => s.status === "failed").length;
198
+ const data = {
199
+ success,
200
+ summary: {
201
+ steps: steps.length,
202
+ succeeded: succeededCount,
203
+ failed: failedCount,
204
+ duration: totalMs
205
+ },
206
+ steps
207
+ };
208
+ if (mviLevel !== "minimal") {
209
+ data.generatedFiles = generatedFiles;
210
+ }
185
211
  return {
186
212
  operation: "build",
187
213
  success,
@@ -234,7 +260,8 @@ var buildCommand = defineCommand({
234
260
  const output = await runBuild({
235
261
  cwd: args.cwd,
236
262
  skipApi: args["skip-api"],
237
- skipGen: args["skip-gen"]
263
+ skipGen: args["skip-gen"],
264
+ mvi: args.mvi
238
265
  });
239
266
  const flags = {
240
267
  json: args.json,
@@ -255,7 +282,7 @@ var buildCommand = defineCommand({
255
282
  }
256
283
  }
257
284
  if (output.success) {
258
- return ` Done in ${data.duration}ms`;
285
+ return ` Done in ${data.summary.duration}ms`;
259
286
  }
260
287
  return "";
261
288
  });
@@ -267,43 +294,122 @@ var buildCommand = defineCommand({
267
294
  import { loadConfig as loadConfig2 } from "@forge-ts/core";
268
295
  import { enforce } from "@forge-ts/enforcer";
269
296
  import { defineCommand as defineCommand2 } from "citty";
297
+ function resolveAgentAction(_error) {
298
+ return "retry_modified";
299
+ }
300
+ function groupByFile(errors, warnings, includeFix) {
301
+ const fileMap = /* @__PURE__ */ new Map();
302
+ for (const e of errors) {
303
+ const fp = e.filePath ?? "";
304
+ if (!fileMap.has(fp)) {
305
+ fileMap.set(fp, { file: fp, errors: [], warnings: [] });
306
+ }
307
+ const entry = {
308
+ code: e.code,
309
+ symbol: e.symbolName ?? "",
310
+ kind: e.symbolKind ?? "",
311
+ line: e.line,
312
+ message: e.message
313
+ };
314
+ if (includeFix) {
315
+ if (e.suggestedFix !== void 0) {
316
+ entry.suggestedFix = e.suggestedFix;
317
+ }
318
+ entry.agentAction = resolveAgentAction(e);
319
+ }
320
+ fileMap.get(fp)?.errors.push(entry);
321
+ }
322
+ for (const w of warnings) {
323
+ const fp = w.filePath ?? "";
324
+ if (!fileMap.has(fp)) {
325
+ fileMap.set(fp, { file: fp, errors: [], warnings: [] });
326
+ }
327
+ fileMap.get(fp)?.warnings.push({
328
+ code: w.code,
329
+ symbol: "",
330
+ kind: "",
331
+ line: w.line,
332
+ message: w.message
333
+ });
334
+ }
335
+ return Array.from(fileMap.values());
336
+ }
337
+ function buildCheckResult(rawErrors, rawWarnings, _symbolCount, exportedSymbolCount, duration, success, mviLevel) {
338
+ const uniqueFiles = /* @__PURE__ */ new Set([
339
+ ...rawErrors.map((e) => e.filePath),
340
+ ...rawWarnings.map((w) => w.filePath)
341
+ ]);
342
+ const summary = {
343
+ errors: rawErrors.length,
344
+ warnings: rawWarnings.length,
345
+ files: uniqueFiles.size,
346
+ symbols: exportedSymbolCount,
347
+ duration
348
+ };
349
+ if (mviLevel === "minimal") {
350
+ return { success, summary };
351
+ }
352
+ const byFile = groupByFile(rawErrors, rawWarnings, mviLevel === "full");
353
+ return { success, summary, byFile };
354
+ }
270
355
  async function runCheck(args) {
271
356
  const config = await loadConfig2(args.cwd);
272
357
  if (args.strict !== void 0) {
273
358
  config.enforce.strict = args.strict;
274
359
  }
275
360
  const result = await enforce(config);
276
- const errors = result.errors.map((e) => ({
277
- code: e.code,
278
- message: e.message,
279
- filePath: e.filePath,
280
- line: e.line,
281
- column: e.column
282
- }));
283
- const warnings = result.warnings.map((w) => ({
284
- code: w.code,
285
- message: w.message,
286
- filePath: w.filePath,
287
- line: w.line,
288
- column: w.column
289
- }));
290
- const data = {
291
- symbolCount: result.symbols.length,
292
- errorCount: errors.length,
293
- warningCount: warnings.length,
294
- errors,
295
- warnings,
296
- duration: result.duration
297
- };
361
+ const mviLevel = args.mvi ?? "standard";
362
+ const exportedSymbolCount = result.symbols.filter((s) => s.exported).length;
363
+ const data = buildCheckResult(
364
+ result.errors,
365
+ result.warnings,
366
+ result.symbols.length,
367
+ exportedSymbolCount,
368
+ result.duration,
369
+ result.success,
370
+ mviLevel
371
+ );
298
372
  return {
299
373
  operation: "check",
300
374
  success: result.success,
301
375
  data,
302
- errors,
303
- warnings,
304
376
  duration: result.duration
305
377
  };
306
378
  }
379
+ function formatCheckHuman(result) {
380
+ const lines = [];
381
+ if (result.success) {
382
+ lines.push(
383
+ `forge-ts check: OK (${result.summary.symbols} symbol(s) checked, ${result.summary.duration}ms)`
384
+ );
385
+ return lines.join("\n");
386
+ }
387
+ lines.push("forge-ts check: FAILED\n");
388
+ lines.push(
389
+ ` ${result.summary.errors} error(s), ${result.summary.warnings} warning(s) across ${result.summary.files} file(s) (${result.summary.symbols} symbols checked)
390
+ `
391
+ );
392
+ if (result.byFile && result.byFile.length > 0) {
393
+ for (const group of result.byFile) {
394
+ if (group.errors.length > 0) {
395
+ lines.push(` ${group.file} (${group.errors.length} error(s)):`);
396
+ for (const err of group.errors) {
397
+ const symbolPart = err.symbol ? `${err.symbol} (${err.kind}:${err.line})` : `line ${err.line}`;
398
+ lines.push(` ${err.code} ${symbolPart} \u2014 ${err.message}`);
399
+ }
400
+ }
401
+ if (group.warnings.length > 0) {
402
+ lines.push(` ${group.file} (${group.warnings.length} warning(s)):`);
403
+ for (const w of group.warnings) {
404
+ lines.push(` ${w.code} line ${w.line} \u2014 ${w.message}`);
405
+ }
406
+ }
407
+ }
408
+ lines.push("");
409
+ }
410
+ lines.push(" Run with --json --mvi full for exact fix suggestions.");
411
+ return lines.join("\n");
412
+ }
307
413
  var checkCommand = defineCommand2({
308
414
  meta: {
309
415
  name: "check",
@@ -348,7 +454,8 @@ var checkCommand = defineCommand2({
348
454
  const output = await runCheck({
349
455
  cwd: args.cwd,
350
456
  strict: args.strict,
351
- verbose: args.verbose
457
+ verbose: args.verbose,
458
+ mvi: args.mvi
352
459
  });
353
460
  const flags = {
354
461
  json: args.json,
@@ -356,24 +463,7 @@ var checkCommand = defineCommand2({
356
463
  quiet: args.quiet,
357
464
  mvi: args.mvi
358
465
  };
359
- emitResult(output, flags, (_data, cmd) => {
360
- const lines = [];
361
- for (const err of cmd.errors ?? []) {
362
- const loc = err.filePath != null ? `${err.filePath}:${err.line ?? 0}:${err.column ?? 0}` : "";
363
- lines.push(loc ? `${loc} \u2014 ${err.message}` : err.message);
364
- }
365
- if (lines.length > 0) {
366
- lines.push(
367
- `
368
- ${cmd.data.errorCount} error(s), ${cmd.data.warningCount} warning(s) in ${cmd.data.duration}ms`
369
- );
370
- } else {
371
- lines.push(
372
- `forge-ts check: ${cmd.data.symbolCount} symbol(s) checked. (${cmd.data.duration}ms)`
373
- );
374
- }
375
- return lines.join("\n");
376
- });
466
+ emitResult(output, flags, (data) => formatCheckHuman(data));
377
467
  process.exit(resolveExitCode(output));
378
468
  }
379
469
  });
@@ -385,28 +475,29 @@ import { defineCommand as defineCommand3 } from "citty";
385
475
  async function runTest(args) {
386
476
  const config = await loadConfig3(args.cwd);
387
477
  const result = await doctest(config);
388
- const failures = result.errors.map((e) => ({
389
- code: e.code,
390
- message: e.message,
391
- filePath: e.filePath,
392
- line: e.line,
393
- column: e.column
394
- }));
395
- const failCount = failures.length;
478
+ const mviLevel = args.mvi ?? "standard";
479
+ const failCount = result.errors.length;
396
480
  const totalSymbols = result.symbols.length;
397
481
  const passCount = totalSymbols - failCount > 0 ? totalSymbols - failCount : 0;
398
- const data = {
482
+ const summary = {
399
483
  passed: passCount,
400
484
  failed: failCount,
401
485
  total: totalSymbols,
402
- duration: result.duration,
403
- failures
486
+ duration: result.duration
404
487
  };
488
+ const data = { success: result.success, summary };
489
+ if (mviLevel !== "minimal") {
490
+ data.failures = result.errors.map((e) => ({
491
+ symbol: e.symbolName ?? "",
492
+ file: e.filePath ?? "",
493
+ line: e.line,
494
+ message: e.message
495
+ }));
496
+ }
405
497
  return {
406
498
  operation: "test",
407
499
  success: result.success,
408
500
  data,
409
- errors: failures,
410
501
  duration: result.duration
411
502
  };
412
503
  }
@@ -441,7 +532,7 @@ var testCommand = defineCommand3({
441
532
  }
442
533
  },
443
534
  async run({ args }) {
444
- const output = await runTest({ cwd: args.cwd });
535
+ const output = await runTest({ cwd: args.cwd, mvi: args.mvi });
445
536
  const flags = {
446
537
  json: args.json,
447
538
  human: args.human,
@@ -450,13 +541,13 @@ var testCommand = defineCommand3({
450
541
  };
451
542
  emitResult(output, flags, (data) => {
452
543
  if (output.success) {
453
- return `forge-ts test: all doctests passed. (${data.duration}ms)`;
544
+ return `forge-ts test: all doctests passed. (${data.summary.duration}ms)`;
454
545
  }
455
546
  const lines = [];
456
- for (const err of data.failures) {
457
- lines.push(err.message);
547
+ for (const f of data.failures ?? []) {
548
+ lines.push(f.message);
458
549
  }
459
- lines.push(`forge-ts test: ${data.failed} failure(s). (${data.duration}ms)`);
550
+ lines.push(`forge-ts test: ${data.summary.failed} failure(s). (${data.summary.duration}ms)`);
460
551
  return lines.join("\n");
461
552
  });
462
553
  process.exit(resolveExitCode(output));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/build.ts","../src/logger.ts","../src/output.ts","../src/commands/check.ts","../src/commands/test.ts"],"sourcesContent":["/**\n * @forge-ts/cli — Command-line interface for the forge-ts toolchain.\n *\n * Usage:\n * forge-ts check [--cwd <dir>] [--strict] [--verbose]\n * forge-ts test [--cwd <dir>]\n * forge-ts build [--cwd <dir>] [--skip-api] [--skip-gen]\n *\n * @packageDocumentation\n * @public\n */\n\nimport { defineCommand, runMain } from \"citty\";\nimport { buildCommand } from \"./commands/build.js\";\nimport { checkCommand } from \"./commands/check.js\";\nimport { testCommand } from \"./commands/test.js\";\n\nexport { buildCommand } from \"./commands/build.js\";\nexport { checkCommand } from \"./commands/check.js\";\nexport { testCommand } from \"./commands/test.js\";\nexport { createLogger, type Logger } from \"./logger.js\";\nexport {\n\ttype CommandOutput,\n\temitResult,\n\ttype ForgeCliError,\n\ttype ForgeCliWarning,\n\ttype OutputFlags,\n\tresolveExitCode,\n} from \"./output.js\";\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"forge-ts\",\n\t\tversion: \"0.1.0\",\n\t\tdescription: \"Universal TypeScript Documentation Compiler\",\n\t},\n\tsubCommands: {\n\t\tcheck: checkCommand,\n\t\ttest: testCommand,\n\t\tbuild: buildCommand,\n\t},\n});\n\nrunMain(main);\n","import { generateApi } from \"@forge-ts/api\";\nimport { loadConfig } from \"@forge-ts/core\";\nimport { generate } from \"@forge-ts/gen\";\nimport { defineCommand } from \"citty\";\nimport { createLogger } from \"../logger.js\";\nimport {\n\ttype CommandOutput,\n\temitResult,\n\ttype ForgeCliError,\n\ttype OutputFlags,\n\tresolveExitCode,\n} from \"../output.js\";\n\n/**\n * Arguments for the `build` command.\n * @internal\n */\nexport interface BuildArgs {\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** Skip API generation even if enabled in config. */\n\tskipApi?: boolean;\n\t/** Skip doc generation even if enabled in config. */\n\tskipGen?: boolean;\n}\n\n/**\n * A single step in the build pipeline.\n * @public\n */\nexport interface BuildStep {\n\tname: string;\n\tstatus: \"success\" | \"skipped\" | \"failed\";\n\toutputPath?: string;\n\tduration?: number;\n\terrors?: ForgeCliError[];\n}\n\n/**\n * Typed result for the `build` command.\n * @public\n */\nexport interface BuildResult {\n\tsteps: BuildStep[];\n\tduration: number;\n}\n\n/**\n * Runs the full build pipeline and returns a typed command output.\n *\n * @param args - CLI arguments for the build command.\n * @returns A typed `CommandOutput<BuildResult>`.\n * @public\n */\nexport async function runBuild(args: BuildArgs): Promise<CommandOutput<BuildResult>> {\n\tconst config = await loadConfig(args.cwd);\n\tconst buildStart = Date.now();\n\n\tconst steps: BuildStep[] = [];\n\tconst allErrors: ForgeCliError[] = [];\n\tlet success = true;\n\n\tif (config.api.enabled && !args.skipApi) {\n\t\tconst result = await generateApi(config);\n\t\tif (!result.success) {\n\t\t\tconst errors: ForgeCliError[] = result.errors.map((e) => ({\n\t\t\t\tcode: e.code,\n\t\t\t\tmessage: e.message,\n\t\t\t\tfilePath: e.filePath,\n\t\t\t\tline: e.line,\n\t\t\t\tcolumn: e.column,\n\t\t\t}));\n\t\t\tallErrors.push(...errors);\n\t\t\tsuccess = false;\n\t\t\tsteps.push({\n\t\t\t\tname: \"api\",\n\t\t\t\tstatus: \"failed\",\n\t\t\t\toutputPath: config.api.openapiPath,\n\t\t\t\tduration: result.duration,\n\t\t\t\terrors,\n\t\t\t});\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tname: \"api\",\n\t\t\t\tstatus: \"success\",\n\t\t\t\toutputPath: config.api.openapiPath,\n\t\t\t\tduration: result.duration,\n\t\t\t});\n\t\t}\n\t} else if (!config.api.enabled || args.skipApi) {\n\t\tsteps.push({ name: \"api\", status: \"skipped\" });\n\t}\n\n\tif (config.gen.enabled && !args.skipGen) {\n\t\tconst result = await generate(config);\n\t\tif (!result.success) {\n\t\t\tconst errors: ForgeCliError[] = result.errors.map((e) => ({\n\t\t\t\tcode: e.code,\n\t\t\t\tmessage: e.message,\n\t\t\t\tfilePath: e.filePath,\n\t\t\t\tline: e.line,\n\t\t\t\tcolumn: e.column,\n\t\t\t}));\n\t\t\tallErrors.push(...errors);\n\t\t\tsuccess = false;\n\t\t\tsteps.push({\n\t\t\t\tname: \"gen\",\n\t\t\t\tstatus: \"failed\",\n\t\t\t\tduration: result.duration,\n\t\t\t\terrors,\n\t\t\t});\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tname: \"gen\",\n\t\t\t\tstatus: \"success\",\n\t\t\t\tduration: result.duration,\n\t\t\t});\n\t\t}\n\t} else if (!config.gen.enabled || args.skipGen) {\n\t\tsteps.push({ name: \"gen\", status: \"skipped\" });\n\t}\n\n\tconst totalMs = Date.now() - buildStart;\n\tconst data: BuildResult = { steps, duration: totalMs };\n\n\treturn {\n\t\toperation: \"build\",\n\t\tsuccess,\n\t\tdata,\n\t\terrors: allErrors,\n\t\tduration: totalMs,\n\t};\n}\n\n/**\n * Citty command definition for `forge-ts build`.\n * @public\n */\nexport const buildCommand = defineCommand({\n\tmeta: {\n\t\tname: \"build\",\n\t\tdescription: \"Generate API reference and documentation\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\t\"skip-api\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip OpenAPI generation\",\n\t\t\tdefault: false,\n\t\t},\n\t\t\"skip-gen\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip doc generation\",\n\t\t\tdefault: false,\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as LAFS JSON envelope (agent-friendly)\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text (default for TTY)\",\n\t\t\tdefault: false,\n\t\t},\n\t\tquiet: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Suppress non-essential output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tmvi: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"MVI verbosity level: minimal, standard, full\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst output = await runBuild({\n\t\t\tcwd: args.cwd,\n\t\t\tskipApi: args[\"skip-api\"],\n\t\t\tskipGen: args[\"skip-gen\"],\n\t\t});\n\n\t\tconst flags: OutputFlags = {\n\t\t\tjson: args.json,\n\t\t\thuman: args.human,\n\t\t\tquiet: args.quiet,\n\t\t\tmvi: args.mvi,\n\t\t};\n\n\t\temitResult(output, flags, (data) => {\n\t\t\tconst logger = createLogger();\n\t\t\tfor (const step of data.steps) {\n\t\t\t\tif (step.status === \"failed\") {\n\t\t\t\t\tfor (const err of step.errors ?? []) {\n\t\t\t\t\t\tlogger.error(`[${step.name}] ${err.message}`);\n\t\t\t\t\t}\n\t\t\t\t} else if (step.status === \"success\") {\n\t\t\t\t\tconst detail =\n\t\t\t\t\t\tstep.name === \"api\" && step.outputPath != null\n\t\t\t\t\t\t\t? `Generated OpenAPI spec \\u2192 ${step.outputPath}`\n\t\t\t\t\t\t\t: `Step complete`;\n\t\t\t\t\tlogger.step(step.name.toUpperCase(), detail, step.duration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (output.success) {\n\t\t\t\treturn ` Done in ${data.duration}ms`;\n\t\t\t}\n\t\t\treturn \"\";\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n","/**\n * Simple TTY-aware logger for forge-ts CLI output.\n *\n * Uses ANSI escape codes directly — no external colour library.\n *\n * @packageDocumentation\n * @internal\n */\n\n// ---------------------------------------------------------------------------\n// ANSI constants\n// ---------------------------------------------------------------------------\n\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\nconst RED = \"\\x1b[31m\";\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A minimal structured logger used throughout the CLI commands.\n * @internal\n */\nexport interface Logger {\n\t/** Print an informational message. */\n\tinfo(msg: string): void;\n\t/** Print a success message (green ✓ prefix when colours are on). */\n\tsuccess(msg: string): void;\n\t/** Print a warning message (yellow prefix when colours are on). */\n\twarn(msg: string): void;\n\t/** Print an error message (red ✗ prefix when colours are on). */\n\terror(msg: string): void;\n\t/**\n\t * Print a build-step line.\n\t *\n\t * @param label - Short category label (e.g. \"API\", \"Gen\").\n\t * @param detail - Description of what was produced.\n\t * @param duration - Optional wall-clock time in milliseconds.\n\t */\n\tstep(label: string, detail: string, duration?: number): void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a {@link Logger} instance.\n *\n * @param options - Optional configuration.\n * @param options.colors - Emit ANSI colour codes. Defaults to `process.stdout.isTTY`.\n * @returns A configured logger.\n * @internal\n */\nexport function createLogger(options?: { colors?: boolean }): Logger {\n\tconst useColors = options?.colors ?? process.stdout.isTTY ?? false;\n\n\tfunction colorize(text: string, code: string): string {\n\t\treturn useColors ? `${code}${text}${RESET}` : text;\n\t}\n\n\tfunction bold(text: string): string {\n\t\treturn useColors ? `${BOLD}${text}${RESET}` : text;\n\t}\n\n\treturn {\n\t\tinfo(msg: string): void {\n\t\t\tconsole.log(msg);\n\t\t},\n\n\t\tsuccess(msg: string): void {\n\t\t\tconst prefix = colorize(\"✓\", GREEN);\n\t\t\tconsole.log(`${prefix} ${msg}`);\n\t\t},\n\n\t\twarn(msg: string): void {\n\t\t\tconst prefix = colorize(\"warn\", YELLOW);\n\t\t\tconsole.warn(`${bold(prefix)} ${msg}`);\n\t\t},\n\n\t\terror(msg: string): void {\n\t\t\tconst prefix = colorize(\"error\", RED);\n\t\t\tconsole.error(`${bold(prefix)} ${msg}`);\n\t\t},\n\n\t\tstep(label: string, detail: string, duration?: number): void {\n\t\t\tconst check = colorize(\"✓\", GREEN);\n\t\t\tconst durationStr = duration !== undefined ? ` (${duration}ms)` : \"\";\n\t\t\tconsole.log(` ${check} ${bold(label)}: ${detail}${durationStr}`);\n\t\t},\n\t};\n}\n","/**\n * Central output layer for forge-ts CLI.\n *\n * Wraps all command results in LAFS envelopes for agent-first output, while\n * preserving human-readable formatting for TTY consumers.\n *\n * @packageDocumentation\n * @internal\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport {\n\tcreateEnvelope,\n\ttype MVILevel,\n\tprojectEnvelope,\n\tresolveFlags,\n\ttype UnifiedFlagInput,\n} from \"@cleocode/lafs-protocol\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Typed result from a forge-ts command. */\nexport interface CommandOutput<T> {\n\toperation: string;\n\tsuccess: boolean;\n\tdata: T;\n\terrors?: ForgeCliError[];\n\twarnings?: ForgeCliWarning[];\n\tduration?: number;\n}\n\n/** Structured error for CLI commands. */\nexport interface ForgeCliError {\n\tcode: string;\n\tmessage: string;\n\tfilePath?: string;\n\tline?: number;\n\tcolumn?: number;\n}\n\n/** Structured warning for CLI commands. */\nexport interface ForgeCliWarning {\n\tcode: string;\n\tmessage: string;\n\tfilePath?: string;\n\tline?: number;\n\tcolumn?: number;\n}\n\n/** Output format flags passed through from citty args. */\nexport interface OutputFlags {\n\tjson?: boolean;\n\thuman?: boolean;\n\tquiet?: boolean;\n\tmvi?: string;\n}\n\n// ---------------------------------------------------------------------------\n// emitResult\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps a command result in a LAFS envelope and emits it.\n *\n * - JSON mode: writes the projected envelope to stdout as JSON.\n * - Human mode: calls the provided formatter function.\n * - Quiet mode: suppresses all output regardless of format.\n *\n * @param output - Typed result from the command.\n * @param flags - Output format flags from citty args.\n * @param humanFormatter - Produces a human-readable string for TTY consumers.\n * @internal\n */\nexport function emitResult<T>(\n\toutput: CommandOutput<T>,\n\tflags: OutputFlags,\n\thumanFormatter: (data: T, output: CommandOutput<T>) => string,\n): void {\n\tconst flagInput: UnifiedFlagInput = {\n\t\tjson: flags.json,\n\t\thuman: flags.human,\n\t\tquiet: flags.quiet,\n\t\tmvi: flags.mvi,\n\t};\n\n\tconst resolved = resolveFlags(flagInput);\n\tconst format = resolved.format.format;\n\tconst quiet = resolved.format.quiet;\n\n\t// Quiet mode: suppress all output, just let exit code speak.\n\tif (quiet) {\n\t\treturn;\n\t}\n\n\t// Build the LAFS envelope\n\tconst envelope = createEnvelope(\n\t\toutput.success\n\t\t\t? {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tresult: output.data as Record<string, unknown>,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\toperation: `forge-ts.${output.operation}`,\n\t\t\t\t\t\trequestId: randomUUID(),\n\t\t\t\t\t\ttransport: \"cli\",\n\t\t\t\t\t\tmvi: (flags.mvi as MVILevel) ?? \"standard\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: output.errors?.[0]?.code ?? \"FORGE_ERROR\",\n\t\t\t\t\t\tmessage: output.errors?.[0]?.message ?? \"Command failed\",\n\t\t\t\t\t\tcategory: \"VALIDATION\",\n\t\t\t\t\t\tretryable: false,\n\t\t\t\t\t\tretryAfterMs: null,\n\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\terrors: output.errors ?? [],\n\t\t\t\t\t\t\twarnings: output.warnings ?? [],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\toperation: `forge-ts.${output.operation}`,\n\t\t\t\t\t\trequestId: randomUUID(),\n\t\t\t\t\t\ttransport: \"cli\",\n\t\t\t\t\t\tmvi: (flags.mvi as MVILevel) ?? \"standard\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t);\n\n\tif (format === \"json\") {\n\t\t// MVI projection reduces token cost for agents\n\t\tconst mviLevel: MVILevel = (flags.mvi as MVILevel) ?? \"standard\";\n\t\tconst projected = projectEnvelope(envelope, mviLevel);\n\t\tprocess.stdout.write(`${JSON.stringify(projected, null, 2)}\\n`);\n\t} else {\n\t\t// Human-readable output\n\t\tconst formatted = humanFormatter(output.data, output);\n\t\tif (formatted) {\n\t\t\tconsole.log(formatted);\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// resolveExitCode\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the LAFS-compliant exit code for a command output.\n *\n * @param output - Typed result from the command.\n * @returns `0` on success, `1` on validation/check failure.\n * @internal\n */\nexport function resolveExitCode(output: CommandOutput<unknown>): number {\n\tif (output.success) return 0;\n\treturn 1;\n}\n","import { loadConfig } from \"@forge-ts/core\";\nimport { enforce } from \"@forge-ts/enforcer\";\nimport { defineCommand } from \"citty\";\nimport {\n\ttype CommandOutput,\n\temitResult,\n\ttype ForgeCliError,\n\ttype ForgeCliWarning,\n\ttype OutputFlags,\n\tresolveExitCode,\n} from \"../output.js\";\n\n/**\n * Arguments for the `check` command.\n * @internal\n */\nexport interface CheckArgs {\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** Exit with non-zero code on warnings as well as errors. */\n\tstrict?: boolean;\n\t/** Include symbol signatures alongside diagnostics. */\n\tverbose?: boolean;\n}\n\n/**\n * Typed result for the `check` command.\n * @public\n */\nexport interface CheckResult {\n\tsymbolCount: number;\n\terrorCount: number;\n\twarningCount: number;\n\terrors: ForgeCliError[];\n\twarnings: ForgeCliWarning[];\n\tduration: number;\n}\n\n/**\n * Runs the TSDoc enforcement pass and returns a typed command output.\n *\n * @param args - CLI arguments for the check command.\n * @returns A typed `CommandOutput<CheckResult>`.\n * @public\n */\nexport async function runCheck(args: CheckArgs): Promise<CommandOutput<CheckResult>> {\n\tconst config = await loadConfig(args.cwd);\n\tif (args.strict !== undefined) {\n\t\tconfig.enforce.strict = args.strict;\n\t}\n\n\tconst result = await enforce(config);\n\n\tconst errors: ForgeCliError[] = result.errors.map((e) => ({\n\t\tcode: e.code,\n\t\tmessage: e.message,\n\t\tfilePath: e.filePath,\n\t\tline: e.line,\n\t\tcolumn: e.column,\n\t}));\n\n\tconst warnings: ForgeCliWarning[] = result.warnings.map((w) => ({\n\t\tcode: w.code,\n\t\tmessage: w.message,\n\t\tfilePath: w.filePath,\n\t\tline: w.line,\n\t\tcolumn: w.column,\n\t}));\n\n\tconst data: CheckResult = {\n\t\tsymbolCount: result.symbols.length,\n\t\terrorCount: errors.length,\n\t\twarningCount: warnings.length,\n\t\terrors,\n\t\twarnings,\n\t\tduration: result.duration,\n\t};\n\n\treturn {\n\t\toperation: \"check\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors,\n\t\twarnings,\n\t\tduration: result.duration,\n\t};\n}\n\n/**\n * Citty command definition for `forge-ts check`.\n * @public\n */\nexport const checkCommand = defineCommand({\n\tmeta: {\n\t\tname: \"check\",\n\t\tdescription: \"Lint TSDoc coverage on exported symbols\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\tstrict: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Treat warnings as errors\",\n\t\t\tdefault: false,\n\t\t},\n\t\tverbose: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show detailed output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as LAFS JSON envelope (agent-friendly)\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text (default for TTY)\",\n\t\t\tdefault: false,\n\t\t},\n\t\tquiet: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Suppress non-essential output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tmvi: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"MVI verbosity level: minimal, standard, full\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst output = await runCheck({\n\t\t\tcwd: args.cwd,\n\t\t\tstrict: args.strict,\n\t\t\tverbose: args.verbose,\n\t\t});\n\n\t\tconst flags: OutputFlags = {\n\t\t\tjson: args.json,\n\t\t\thuman: args.human,\n\t\t\tquiet: args.quiet,\n\t\t\tmvi: args.mvi,\n\t\t};\n\n\t\temitResult(output, flags, (_data, cmd) => {\n\t\t\t// Delegate to enforcer's own formatter for human output.\n\t\t\t// Re-run enforce is not needed — we have the raw result embedded.\n\t\t\t// However formatResults needs the ForgeResult shape; we reconstruct\n\t\t\t// just enough to call it by printing the errors inline.\n\t\t\tconst lines: string[] = [];\n\t\t\tfor (const err of cmd.errors ?? []) {\n\t\t\t\tconst loc =\n\t\t\t\t\terr.filePath != null ? `${err.filePath}:${err.line ?? 0}:${err.column ?? 0}` : \"\";\n\t\t\t\tlines.push(loc ? `${loc} — ${err.message}` : err.message);\n\t\t\t}\n\t\t\tif (lines.length > 0) {\n\t\t\t\tlines.push(\n\t\t\t\t\t`\\n${cmd.data.errorCount} error(s), ${cmd.data.warningCount} warning(s) in ${cmd.data.duration}ms`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tlines.push(\n\t\t\t\t\t`forge-ts check: ${cmd.data.symbolCount} symbol(s) checked. (${cmd.data.duration}ms)`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn lines.join(\"\\n\");\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n","import { loadConfig } from \"@forge-ts/core\";\nimport { doctest } from \"@forge-ts/doctest\";\nimport { defineCommand } from \"citty\";\nimport {\n\ttype CommandOutput,\n\temitResult,\n\ttype ForgeCliError,\n\ttype OutputFlags,\n\tresolveExitCode,\n} from \"../output.js\";\n\n/**\n * Arguments for the `test` command.\n * @internal\n */\nexport interface TestArgs {\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n}\n\n/**\n * Typed result for the `test` command.\n * @public\n */\nexport interface TestResult {\n\tpassed: number;\n\tfailed: number;\n\ttotal: number;\n\tduration: number;\n\tfailures: ForgeCliError[];\n}\n\n/**\n * Runs the doctest pipeline and returns a typed command output.\n *\n * @param args - CLI arguments for the test command.\n * @returns A typed `CommandOutput<TestResult>`.\n * @public\n */\nexport async function runTest(args: TestArgs): Promise<CommandOutput<TestResult>> {\n\tconst config = await loadConfig(args.cwd);\n\tconst result = await doctest(config);\n\n\tconst failures: ForgeCliError[] = result.errors.map((e) => ({\n\t\tcode: e.code,\n\t\tmessage: e.message,\n\t\tfilePath: e.filePath,\n\t\tline: e.line,\n\t\tcolumn: e.column,\n\t}));\n\n\tconst failCount = failures.length;\n\tconst totalSymbols = result.symbols.length;\n\tconst passCount = totalSymbols - failCount > 0 ? totalSymbols - failCount : 0;\n\n\tconst data: TestResult = {\n\t\tpassed: passCount,\n\t\tfailed: failCount,\n\t\ttotal: totalSymbols,\n\t\tduration: result.duration,\n\t\tfailures,\n\t};\n\n\treturn {\n\t\toperation: \"test\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: failures,\n\t\tduration: result.duration,\n\t};\n}\n\n/**\n * Citty command definition for `forge-ts test`.\n * @public\n */\nexport const testCommand = defineCommand({\n\tmeta: {\n\t\tname: \"test\",\n\t\tdescription: \"Run @example blocks as doctests\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as LAFS JSON envelope (agent-friendly)\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text (default for TTY)\",\n\t\t\tdefault: false,\n\t\t},\n\t\tquiet: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Suppress non-essential output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tmvi: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"MVI verbosity level: minimal, standard, full\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst output = await runTest({ cwd: args.cwd });\n\n\t\tconst flags: OutputFlags = {\n\t\t\tjson: args.json,\n\t\t\thuman: args.human,\n\t\t\tquiet: args.quiet,\n\t\t\tmvi: args.mvi,\n\t\t};\n\n\t\temitResult(output, flags, (data) => {\n\t\t\tif (output.success) {\n\t\t\t\treturn `forge-ts test: all doctests passed. (${data.duration}ms)`;\n\t\t\t}\n\t\t\tconst lines: string[] = [];\n\t\t\tfor (const err of data.failures) {\n\t\t\t\tlines.push(err.message);\n\t\t\t}\n\t\t\tlines.push(`forge-ts test: ${data.failed} failure(s). (${data.duration}ms)`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n"],"mappings":"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","names":["defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","defineCommand"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/build.ts","../src/logger.ts","../src/output.ts","../src/commands/check.ts","../src/commands/test.ts"],"sourcesContent":["/**\n * @forge-ts/cli — Command-line interface for the forge-ts toolchain.\n *\n * Usage:\n * forge-ts check [--cwd <dir>] [--strict] [--verbose]\n * forge-ts test [--cwd <dir>]\n * forge-ts build [--cwd <dir>] [--skip-api] [--skip-gen]\n *\n * @packageDocumentation\n * @public\n */\n\nimport { defineCommand, runMain } from \"citty\";\nimport { buildCommand } from \"./commands/build.js\";\nimport { checkCommand } from \"./commands/check.js\";\nimport { testCommand } from \"./commands/test.js\";\n\nexport { type BuildResult, type BuildStep, buildCommand } from \"./commands/build.js\";\nexport {\n\ttype CheckFileError,\n\ttype CheckFileGroup,\n\ttype CheckFileWarning,\n\ttype CheckResult,\n\tcheckCommand,\n} from \"./commands/check.js\";\nexport { type TestFailure, type TestResult, testCommand } from \"./commands/test.js\";\nexport { createLogger, type Logger } from \"./logger.js\";\nexport {\n\ttype CommandOutput,\n\temitResult,\n\ttype ForgeCliError,\n\ttype ForgeCliWarning,\n\ttype OutputFlags,\n\tresolveExitCode,\n} from \"./output.js\";\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"forge-ts\",\n\t\tversion: \"0.1.0\",\n\t\tdescription: \"Universal TypeScript Documentation Compiler\",\n\t},\n\tsubCommands: {\n\t\tcheck: checkCommand,\n\t\ttest: testCommand,\n\t\tbuild: buildCommand,\n\t},\n});\n\nrunMain(main);\n","import { join } from \"node:path\";\nimport { generateApi } from \"@forge-ts/api\";\nimport { loadConfig } from \"@forge-ts/core\";\nimport { generate } from \"@forge-ts/gen\";\nimport { defineCommand } from \"citty\";\nimport { createLogger } from \"../logger.js\";\nimport {\n\ttype CommandOutput,\n\temitResult,\n\ttype ForgeCliError,\n\ttype OutputFlags,\n\tresolveExitCode,\n} from \"../output.js\";\n\n/**\n * Arguments for the `build` command.\n * @internal\n */\nexport interface BuildArgs {\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** Skip API generation even if enabled in config. */\n\tskipApi?: boolean;\n\t/** Skip doc generation even if enabled in config. */\n\tskipGen?: boolean;\n\t/** MVI verbosity level for structured output. */\n\tmvi?: string;\n}\n\n/**\n * A single step in the build pipeline.\n * @public\n */\nexport interface BuildStep {\n\t/** Internal step name, e.g. \"api\" or \"gen\". */\n\tname: string;\n\t/** Outcome of this step. */\n\tstatus: \"success\" | \"skipped\" | \"failed\";\n\t/** Path to the primary output file produced by this step, if applicable. */\n\toutputPath?: string;\n\t/** Wall-clock duration of this step in milliseconds. */\n\tduration?: number;\n\t/** Errors produced by this step when status is \"failed\". */\n\terrors?: ForgeCliError[];\n}\n\n/**\n * Typed result for the `build` command.\n * @public\n */\nexport interface BuildResult {\n\t/** Whether the build succeeded. */\n\tsuccess: boolean;\n\t/** Aggregate pipeline counts — always present. */\n\tsummary: {\n\t\t/** Total number of pipeline steps. */\n\t\tsteps: number;\n\t\t/** Steps that completed successfully. */\n\t\tsucceeded: number;\n\t\t/** Steps that failed. */\n\t\tfailed: number;\n\t\t/** Wall-clock duration in milliseconds. */\n\t\tduration: number;\n\t};\n\t/** Per-step details. */\n\tsteps: BuildStep[];\n\t/** Files written during the build — present at standard and full MVI levels. */\n\tgeneratedFiles?: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Runs the full build pipeline and returns a typed command output.\n *\n * @param args - CLI arguments for the build command.\n * @returns A typed `CommandOutput<BuildResult>`.\n * @example\n * ```typescript\n * import { runBuild } from \"@forge-ts/cli/commands/build\";\n * const output = await runBuild({ cwd: process.cwd() });\n * console.log(output.success); // true if all steps succeeded\n * ```\n * @public\n */\nexport async function runBuild(args: BuildArgs): Promise<CommandOutput<BuildResult>> {\n\tconst config = await loadConfig(args.cwd);\n\tconst buildStart = Date.now();\n\tconst mviLevel = args.mvi ?? \"standard\";\n\n\tconst steps: BuildStep[] = [];\n\tconst allErrors: ForgeCliError[] = [];\n\tconst generatedFiles: string[] = [];\n\tlet success = true;\n\n\tif (config.api.enabled && !args.skipApi) {\n\t\tconst result = await generateApi(config);\n\t\tif (!result.success) {\n\t\t\tconst errors: ForgeCliError[] = result.errors.map((e) => ({\n\t\t\t\tcode: e.code,\n\t\t\t\tmessage: e.message,\n\t\t\t\tfilePath: e.filePath,\n\t\t\t\tline: e.line,\n\t\t\t\tcolumn: e.column,\n\t\t\t}));\n\t\t\tallErrors.push(...errors);\n\t\t\tsuccess = false;\n\t\t\tsteps.push({\n\t\t\t\tname: \"api\",\n\t\t\t\tstatus: \"failed\",\n\t\t\t\toutputPath: config.api.openapiPath,\n\t\t\t\tduration: result.duration,\n\t\t\t\terrors,\n\t\t\t});\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tname: \"api\",\n\t\t\t\tstatus: \"success\",\n\t\t\t\toutputPath: config.api.openapiPath,\n\t\t\t\tduration: result.duration,\n\t\t\t});\n\t\t\tgeneratedFiles.push(config.api.openapiPath);\n\t\t}\n\t} else if (!config.api.enabled || args.skipApi) {\n\t\tsteps.push({ name: \"api\", status: \"skipped\" });\n\t}\n\n\tif (config.gen.enabled && !args.skipGen) {\n\t\tconst result = await generate(config);\n\t\tif (!result.success) {\n\t\t\tconst errors: ForgeCliError[] = result.errors.map((e) => ({\n\t\t\t\tcode: e.code,\n\t\t\t\tmessage: e.message,\n\t\t\t\tfilePath: e.filePath,\n\t\t\t\tline: e.line,\n\t\t\t\tcolumn: e.column,\n\t\t\t}));\n\t\t\tallErrors.push(...errors);\n\t\t\tsuccess = false;\n\t\t\tsteps.push({\n\t\t\t\tname: \"gen\",\n\t\t\t\tstatus: \"failed\",\n\t\t\t\tduration: result.duration,\n\t\t\t\terrors,\n\t\t\t});\n\t\t} else {\n\t\t\tsteps.push({\n\t\t\t\tname: \"gen\",\n\t\t\t\tstatus: \"success\",\n\t\t\t\tduration: result.duration,\n\t\t\t});\n\t\t\t// Track the generated output directory and standard files\n\t\t\tfor (const format of config.gen.formats) {\n\t\t\t\tconst ext = format === \"mdx\" ? \"mdx\" : \"md\";\n\t\t\t\tgeneratedFiles.push(join(config.outDir, `api-reference.${ext}`));\n\t\t\t}\n\t\t\tif (config.gen.llmsTxt) {\n\t\t\t\tgeneratedFiles.push(join(config.outDir, \"llms.txt\"));\n\t\t\t\tgeneratedFiles.push(join(config.outDir, \"llms-full.txt\"));\n\t\t\t}\n\t\t}\n\t} else if (!config.gen.enabled || args.skipGen) {\n\t\tsteps.push({ name: \"gen\", status: \"skipped\" });\n\t}\n\n\tconst totalMs = Date.now() - buildStart;\n\n\tconst succeededCount = steps.filter((s) => s.status === \"success\").length;\n\tconst failedCount = steps.filter((s) => s.status === \"failed\").length;\n\n\tconst data: BuildResult = {\n\t\tsuccess,\n\t\tsummary: {\n\t\t\tsteps: steps.length,\n\t\t\tsucceeded: succeededCount,\n\t\t\tfailed: failedCount,\n\t\t\tduration: totalMs,\n\t\t},\n\t\tsteps,\n\t};\n\n\tif (mviLevel !== \"minimal\") {\n\t\tdata.generatedFiles = generatedFiles;\n\t}\n\n\treturn {\n\t\toperation: \"build\",\n\t\tsuccess,\n\t\tdata,\n\t\terrors: allErrors,\n\t\tduration: totalMs,\n\t};\n}\n\n/**\n * Citty command definition for `forge-ts build`.\n * @public\n */\nexport const buildCommand = defineCommand({\n\tmeta: {\n\t\tname: \"build\",\n\t\tdescription: \"Generate API reference and documentation\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\t\"skip-api\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip OpenAPI generation\",\n\t\t\tdefault: false,\n\t\t},\n\t\t\"skip-gen\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip doc generation\",\n\t\t\tdefault: false,\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as LAFS JSON envelope (agent-friendly)\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text (default for TTY)\",\n\t\t\tdefault: false,\n\t\t},\n\t\tquiet: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Suppress non-essential output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tmvi: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"MVI verbosity level: minimal, standard, full\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst output = await runBuild({\n\t\t\tcwd: args.cwd,\n\t\t\tskipApi: args[\"skip-api\"],\n\t\t\tskipGen: args[\"skip-gen\"],\n\t\t\tmvi: args.mvi,\n\t\t});\n\n\t\tconst flags: OutputFlags = {\n\t\t\tjson: args.json,\n\t\t\thuman: args.human,\n\t\t\tquiet: args.quiet,\n\t\t\tmvi: args.mvi,\n\t\t};\n\n\t\temitResult(output, flags, (data) => {\n\t\t\tconst logger = createLogger();\n\t\t\tfor (const step of data.steps) {\n\t\t\t\tif (step.status === \"failed\") {\n\t\t\t\t\tfor (const err of step.errors ?? []) {\n\t\t\t\t\t\tlogger.error(`[${step.name}] ${err.message}`);\n\t\t\t\t\t}\n\t\t\t\t} else if (step.status === \"success\") {\n\t\t\t\t\tconst detail =\n\t\t\t\t\t\tstep.name === \"api\" && step.outputPath != null\n\t\t\t\t\t\t\t? `Generated OpenAPI spec \\u2192 ${step.outputPath}`\n\t\t\t\t\t\t\t: `Step complete`;\n\t\t\t\t\tlogger.step(step.name.toUpperCase(), detail, step.duration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (output.success) {\n\t\t\t\treturn ` Done in ${data.summary.duration}ms`;\n\t\t\t}\n\t\t\treturn \"\";\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n","/**\n * Simple TTY-aware logger for forge-ts CLI output.\n *\n * Uses ANSI escape codes directly — no external colour library.\n *\n * @packageDocumentation\n * @internal\n */\n\n// ---------------------------------------------------------------------------\n// ANSI constants\n// ---------------------------------------------------------------------------\n\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\nconst RED = \"\\x1b[31m\";\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A minimal structured logger used throughout the CLI commands.\n * @internal\n */\nexport interface Logger {\n\t/** Print an informational message. */\n\tinfo(msg: string): void;\n\t/** Print a success message (green ✓ prefix when colours are on). */\n\tsuccess(msg: string): void;\n\t/** Print a warning message (yellow prefix when colours are on). */\n\twarn(msg: string): void;\n\t/** Print an error message (red ✗ prefix when colours are on). */\n\terror(msg: string): void;\n\t/**\n\t * Print a build-step line.\n\t *\n\t * @param label - Short category label (e.g. \"API\", \"Gen\").\n\t * @param detail - Description of what was produced.\n\t * @param duration - Optional wall-clock time in milliseconds.\n\t */\n\tstep(label: string, detail: string, duration?: number): void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a {@link Logger} instance.\n *\n * @param options - Optional configuration.\n * @param options.colors - Emit ANSI colour codes. Defaults to `process.stdout.isTTY`.\n * @returns A configured logger.\n * @internal\n */\nexport function createLogger(options?: { colors?: boolean }): Logger {\n\tconst useColors = options?.colors ?? process.stdout.isTTY ?? false;\n\n\tfunction colorize(text: string, code: string): string {\n\t\treturn useColors ? `${code}${text}${RESET}` : text;\n\t}\n\n\tfunction bold(text: string): string {\n\t\treturn useColors ? `${BOLD}${text}${RESET}` : text;\n\t}\n\n\treturn {\n\t\tinfo(msg: string): void {\n\t\t\tconsole.log(msg);\n\t\t},\n\n\t\tsuccess(msg: string): void {\n\t\t\tconst prefix = colorize(\"✓\", GREEN);\n\t\t\tconsole.log(`${prefix} ${msg}`);\n\t\t},\n\n\t\twarn(msg: string): void {\n\t\t\tconst prefix = colorize(\"warn\", YELLOW);\n\t\t\tconsole.warn(`${bold(prefix)} ${msg}`);\n\t\t},\n\n\t\terror(msg: string): void {\n\t\t\tconst prefix = colorize(\"error\", RED);\n\t\t\tconsole.error(`${bold(prefix)} ${msg}`);\n\t\t},\n\n\t\tstep(label: string, detail: string, duration?: number): void {\n\t\t\tconst check = colorize(\"✓\", GREEN);\n\t\t\tconst durationStr = duration !== undefined ? ` (${duration}ms)` : \"\";\n\t\t\tconsole.log(` ${check} ${bold(label)}: ${detail}${durationStr}`);\n\t\t},\n\t};\n}\n","/**\n * Central output layer for forge-ts CLI.\n *\n * Wraps all command results in LAFS envelopes for agent-first output, while\n * preserving human-readable formatting for TTY consumers.\n *\n * @packageDocumentation\n * @internal\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport {\n\tcreateEnvelope,\n\ttype MVILevel,\n\tprojectEnvelope,\n\tresolveFlags,\n\ttype UnifiedFlagInput,\n} from \"@cleocode/lafs-protocol\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Typed result from a forge-ts command. */\nexport interface CommandOutput<T> {\n\t/** Name of the command that produced this output (e.g., \"check\", \"build\"). */\n\toperation: string;\n\t/** Whether the command completed successfully. */\n\tsuccess: boolean;\n\t/** Strongly-typed command-specific result payload. */\n\tdata: T;\n\t/** Structured errors produced by the command, if any. */\n\terrors?: ForgeCliError[];\n\t/** Structured warnings produced by the command, if any. */\n\twarnings?: ForgeCliWarning[];\n\t/** Wall-clock duration of the command in milliseconds. */\n\tduration?: number;\n}\n\n/** Structured error for CLI commands. */\nexport interface ForgeCliError {\n\t/** Machine-readable error code (e.g., \"E004\"). */\n\tcode: string;\n\t/** Human-readable error description. */\n\tmessage: string;\n\t/** Absolute path to the source file containing the error, if applicable. */\n\tfilePath?: string;\n\t/** 1-based line number of the error, if applicable. */\n\tline?: number;\n\t/** 0-based column number of the error, if applicable. */\n\tcolumn?: number;\n}\n\n/** Structured warning for CLI commands. */\nexport interface ForgeCliWarning {\n\t/** Machine-readable warning code. */\n\tcode: string;\n\t/** Human-readable warning description. */\n\tmessage: string;\n\t/** Absolute path to the source file containing the warning, if applicable. */\n\tfilePath?: string;\n\t/** 1-based line number of the warning, if applicable. */\n\tline?: number;\n\t/** 0-based column number of the warning, if applicable. */\n\tcolumn?: number;\n}\n\n/** Output format flags passed through from citty args. */\nexport interface OutputFlags {\n\t/** Emit output as a LAFS JSON envelope instead of human-readable text. */\n\tjson?: boolean;\n\t/** Emit output as formatted human-readable text. */\n\thuman?: boolean;\n\t/** Suppress all output regardless of format. */\n\tquiet?: boolean;\n\t/** MVI verbosity level: \"minimal\", \"standard\", or \"full\". */\n\tmvi?: string;\n}\n\n// ---------------------------------------------------------------------------\n// emitResult\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps a command result in a LAFS envelope and emits it.\n *\n * - JSON mode: writes the projected envelope to stdout as JSON.\n * - Human mode: calls the provided formatter function.\n * - Quiet mode: suppresses all output regardless of format.\n *\n * @param output - Typed result from the command.\n * @param flags - Output format flags from citty args.\n * @param humanFormatter - Produces a human-readable string for TTY consumers.\n * @example\n * ```typescript\n * import { emitResult } from \"@forge-ts/cli/output\";\n * emitResult(output, { human: true }, (data) => `Done: ${data.summary.duration}ms`);\n * ```\n * @internal\n */\nexport function emitResult<T>(\n\toutput: CommandOutput<T>,\n\tflags: OutputFlags,\n\thumanFormatter: (data: T, output: CommandOutput<T>) => string,\n): void {\n\tconst flagInput: UnifiedFlagInput = {\n\t\tjson: flags.json,\n\t\thuman: flags.human,\n\t\tquiet: flags.quiet,\n\t\tmvi: flags.mvi,\n\t};\n\n\tconst resolved = resolveFlags(flagInput);\n\tconst format = resolved.format.format;\n\tconst quiet = resolved.format.quiet;\n\n\t// Quiet mode: suppress all output, just let exit code speak.\n\tif (quiet) {\n\t\treturn;\n\t}\n\n\t// Build the LAFS envelope\n\tconst envelope = createEnvelope(\n\t\toutput.success\n\t\t\t? {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tresult: output.data as Record<string, unknown>,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\toperation: `forge-ts.${output.operation}`,\n\t\t\t\t\t\trequestId: randomUUID(),\n\t\t\t\t\t\ttransport: \"cli\",\n\t\t\t\t\t\tmvi: (flags.mvi as MVILevel) ?? \"standard\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: output.errors?.[0]?.code ?? \"FORGE_ERROR\",\n\t\t\t\t\t\tmessage: output.errors?.[0]?.message ?? \"Command failed\",\n\t\t\t\t\t\tcategory: \"VALIDATION\",\n\t\t\t\t\t\tretryable: false,\n\t\t\t\t\t\tretryAfterMs: null,\n\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\terrors: output.errors ?? [],\n\t\t\t\t\t\t\twarnings: output.warnings ?? [],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\toperation: `forge-ts.${output.operation}`,\n\t\t\t\t\t\trequestId: randomUUID(),\n\t\t\t\t\t\ttransport: \"cli\",\n\t\t\t\t\t\tmvi: (flags.mvi as MVILevel) ?? \"standard\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t);\n\n\tif (format === \"json\") {\n\t\t// MVI projection reduces token cost for agents\n\t\tconst mviLevel: MVILevel = (flags.mvi as MVILevel) ?? \"standard\";\n\t\tconst projected = projectEnvelope(envelope, mviLevel);\n\t\tprocess.stdout.write(`${JSON.stringify(projected, null, 2)}\\n`);\n\t} else {\n\t\t// Human-readable output\n\t\tconst formatted = humanFormatter(output.data, output);\n\t\tif (formatted) {\n\t\t\tconsole.log(formatted);\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// resolveExitCode\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the LAFS-compliant exit code for a command output.\n *\n * @param output - Typed result from the command.\n * @returns `0` on success, `1` on validation/check failure.\n * @internal\n */\nexport function resolveExitCode(output: CommandOutput<unknown>): number {\n\tif (output.success) return 0;\n\treturn 1;\n}\n","import { type ForgeError, type ForgeWarning, loadConfig } from \"@forge-ts/core\";\nimport { enforce } from \"@forge-ts/enforcer\";\nimport { defineCommand } from \"citty\";\nimport { type CommandOutput, emitResult, type OutputFlags, resolveExitCode } from \"../output.js\";\n\n/**\n * Arguments for the `check` command.\n * @internal\n */\nexport interface CheckArgs {\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** Exit with non-zero code on warnings as well as errors. */\n\tstrict?: boolean;\n\t/** Include symbol signatures alongside diagnostics. */\n\tverbose?: boolean;\n\t/** MVI verbosity level for structured output. */\n\tmvi?: string;\n}\n\n/**\n * A single error entry within a file group, included at standard and full MVI levels.\n * @public\n */\nexport interface CheckFileError {\n\t/** Machine-readable error code. */\n\tcode: string;\n\t/** Symbol name that needs fixing. */\n\tsymbol: string;\n\t/** Symbol kind (function, class, interface, etc.). */\n\tkind: string;\n\t/** 1-based line number of the error. */\n\tline: number;\n\t/** Human-readable description. */\n\tmessage: string;\n\t/** Exact TSDoc block to add (full MVI level only). */\n\tsuggestedFix?: string;\n\t/** Recommended agent action (full MVI level only). */\n\tagentAction?: string;\n}\n\n/**\n * A single warning entry within a file group, included at standard and full MVI levels.\n * @public\n */\nexport interface CheckFileWarning {\n\t/** Machine-readable warning code. */\n\tcode: string;\n\t/** Symbol name that generated the warning. */\n\tsymbol: string;\n\t/** Symbol kind (function, class, interface, etc.). */\n\tkind: string;\n\t/** 1-based line number of the warning. */\n\tline: number;\n\t/** Human-readable description. */\n\tmessage: string;\n}\n\n/**\n * Errors and warnings grouped by file, included at standard and full MVI levels.\n * @public\n */\nexport interface CheckFileGroup {\n\t/** Absolute path to the source file. */\n\tfile: string;\n\t/** Errors in this file. */\n\terrors: CheckFileError[];\n\t/** Warnings in this file. */\n\twarnings: CheckFileWarning[];\n}\n\n/**\n * Typed result for the `check` command.\n * @public\n */\nexport interface CheckResult {\n\t/** Whether the check passed without errors. */\n\tsuccess: boolean;\n\t/** Aggregate counts — always present regardless of MVI level. */\n\tsummary: {\n\t\t/** Total number of errors. */\n\t\terrors: number;\n\t\t/** Total number of warnings. */\n\t\twarnings: number;\n\t\t/** Number of unique files with diagnostics. */\n\t\tfiles: number;\n\t\t/** Number of exported symbols checked. */\n\t\tsymbols: number;\n\t\t/** Wall-clock duration in milliseconds. */\n\t\tduration: number;\n\t};\n\t/** Per-file breakdown — present at standard and full MVI levels. */\n\tbyFile?: CheckFileGroup[];\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Determines the recommended agent action given a ForgeError.\n * @internal\n */\nfunction resolveAgentAction(_error: ForgeError): string {\n\treturn \"retry_modified\";\n}\n\n/**\n * Groups errors and warnings by file path.\n * @internal\n */\nfunction groupByFile(\n\terrors: ForgeError[],\n\twarnings: ForgeWarning[],\n\tincludeFix: boolean,\n): CheckFileGroup[] {\n\tconst fileMap = new Map<string, CheckFileGroup>();\n\n\tfor (const e of errors) {\n\t\tconst fp = e.filePath ?? \"\";\n\t\tif (!fileMap.has(fp)) {\n\t\t\tfileMap.set(fp, { file: fp, errors: [], warnings: [] });\n\t\t}\n\t\tconst entry: CheckFileError = {\n\t\t\tcode: e.code,\n\t\t\tsymbol: e.symbolName ?? \"\",\n\t\t\tkind: e.symbolKind ?? \"\",\n\t\t\tline: e.line,\n\t\t\tmessage: e.message,\n\t\t};\n\t\tif (includeFix) {\n\t\t\tif (e.suggestedFix !== undefined) {\n\t\t\t\tentry.suggestedFix = e.suggestedFix;\n\t\t\t}\n\t\t\tentry.agentAction = resolveAgentAction(e);\n\t\t}\n\t\tfileMap.get(fp)?.errors.push(entry);\n\t}\n\n\tfor (const w of warnings) {\n\t\tconst fp = w.filePath ?? \"\";\n\t\tif (!fileMap.has(fp)) {\n\t\t\tfileMap.set(fp, { file: fp, errors: [], warnings: [] });\n\t\t}\n\t\tfileMap.get(fp)?.warnings.push({\n\t\t\tcode: w.code,\n\t\t\tsymbol: \"\",\n\t\t\tkind: \"\",\n\t\t\tline: w.line,\n\t\t\tmessage: w.message,\n\t\t});\n\t}\n\n\treturn Array.from(fileMap.values());\n}\n\n/**\n * Builds an MVI-projected CheckResult from raw enforcer output.\n * @internal\n */\nfunction buildCheckResult(\n\trawErrors: ForgeError[],\n\trawWarnings: ForgeWarning[],\n\t_symbolCount: number,\n\texportedSymbolCount: number,\n\tduration: number,\n\tsuccess: boolean,\n\tmviLevel: string,\n): CheckResult {\n\tconst uniqueFiles = new Set([\n\t\t...rawErrors.map((e) => e.filePath),\n\t\t...rawWarnings.map((w) => w.filePath),\n\t]);\n\n\tconst summary = {\n\t\terrors: rawErrors.length,\n\t\twarnings: rawWarnings.length,\n\t\tfiles: uniqueFiles.size,\n\t\tsymbols: exportedSymbolCount,\n\t\tduration,\n\t};\n\n\tif (mviLevel === \"minimal\") {\n\t\treturn { success, summary };\n\t}\n\n\tconst byFile = groupByFile(rawErrors, rawWarnings, mviLevel === \"full\");\n\treturn { success, summary, byFile };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Runs the TSDoc enforcement pass and returns a typed command output.\n *\n * @param args - CLI arguments for the check command.\n * @returns A typed `CommandOutput<CheckResult>`.\n * @example\n * ```typescript\n * import { runCheck } from \"@forge-ts/cli/commands/check\";\n * const output = await runCheck({ cwd: process.cwd() });\n * console.log(output.data.summary.errors); // number of TSDoc errors found\n * ```\n * @public\n */\nexport async function runCheck(args: CheckArgs): Promise<CommandOutput<CheckResult>> {\n\tconst config = await loadConfig(args.cwd);\n\tif (args.strict !== undefined) {\n\t\tconfig.enforce.strict = args.strict;\n\t}\n\n\tconst result = await enforce(config);\n\tconst mviLevel = args.mvi ?? \"standard\";\n\n\tconst exportedSymbolCount = result.symbols.filter((s) => s.exported).length;\n\n\tconst data = buildCheckResult(\n\t\tresult.errors,\n\t\tresult.warnings,\n\t\tresult.symbols.length,\n\t\texportedSymbolCount,\n\t\tresult.duration,\n\t\tresult.success,\n\t\tmviLevel,\n\t);\n\n\treturn {\n\t\toperation: \"check\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\tduration: result.duration,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Human formatter\n// ---------------------------------------------------------------------------\n\n/**\n * Formats a CheckResult as human-readable text.\n * @internal\n */\nfunction formatCheckHuman(result: CheckResult): string {\n\tconst lines: string[] = [];\n\n\tif (result.success) {\n\t\tlines.push(\n\t\t\t`forge-ts check: OK (${result.summary.symbols} symbol(s) checked, ${result.summary.duration}ms)`,\n\t\t);\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tlines.push(\"forge-ts check: FAILED\\n\");\n\tlines.push(\n\t\t` ${result.summary.errors} error(s), ${result.summary.warnings} warning(s) across ${result.summary.files} file(s) (${result.summary.symbols} symbols checked)\\n`,\n\t);\n\n\tif (result.byFile && result.byFile.length > 0) {\n\t\tfor (const group of result.byFile) {\n\t\t\tif (group.errors.length > 0) {\n\t\t\t\tlines.push(` ${group.file} (${group.errors.length} error(s)):`);\n\t\t\t\tfor (const err of group.errors) {\n\t\t\t\t\tconst symbolPart = err.symbol\n\t\t\t\t\t\t? `${err.symbol} (${err.kind}:${err.line})`\n\t\t\t\t\t\t: `line ${err.line}`;\n\t\t\t\t\tlines.push(` ${err.code} ${symbolPart} — ${err.message}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (group.warnings.length > 0) {\n\t\t\t\tlines.push(` ${group.file} (${group.warnings.length} warning(s)):`);\n\t\t\t\tfor (const w of group.warnings) {\n\t\t\t\t\tlines.push(` ${w.code} line ${w.line} — ${w.message}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\tlines.push(\" Run with --json --mvi full for exact fix suggestions.\");\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Citty command definition for `forge-ts check`.\n * @public\n */\nexport const checkCommand = defineCommand({\n\tmeta: {\n\t\tname: \"check\",\n\t\tdescription: \"Lint TSDoc coverage on exported symbols\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\tstrict: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Treat warnings as errors\",\n\t\t\tdefault: false,\n\t\t},\n\t\tverbose: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Show detailed output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as LAFS JSON envelope (agent-friendly)\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text (default for TTY)\",\n\t\t\tdefault: false,\n\t\t},\n\t\tquiet: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Suppress non-essential output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tmvi: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"MVI verbosity level: minimal, standard, full\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst output = await runCheck({\n\t\t\tcwd: args.cwd,\n\t\t\tstrict: args.strict,\n\t\t\tverbose: args.verbose,\n\t\t\tmvi: args.mvi,\n\t\t});\n\n\t\tconst flags: OutputFlags = {\n\t\t\tjson: args.json,\n\t\t\thuman: args.human,\n\t\t\tquiet: args.quiet,\n\t\t\tmvi: args.mvi,\n\t\t};\n\n\t\temitResult(output, flags, (data) => formatCheckHuman(data));\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n","import { loadConfig } from \"@forge-ts/core\";\nimport { doctest } from \"@forge-ts/doctest\";\nimport { defineCommand } from \"citty\";\nimport { type CommandOutput, emitResult, type OutputFlags, resolveExitCode } from \"../output.js\";\n\n/**\n * Arguments for the `test` command.\n * @internal\n */\nexport interface TestArgs {\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** MVI verbosity level for structured output. */\n\tmvi?: string;\n}\n\n/**\n * A single test failure entry, included at standard and full MVI levels.\n * @public\n */\nexport interface TestFailure {\n\t/** Symbol name where the doctest failed. */\n\tsymbol: string;\n\t/** Absolute path to the source file. */\n\tfile: string;\n\t/** 1-based line number of the failing example. */\n\tline: number;\n\t/** Human-readable failure message. */\n\tmessage: string;\n}\n\n/**\n * Typed result for the `test` command.\n * @public\n */\nexport interface TestResult {\n\t/** Whether all doctests passed. */\n\tsuccess: boolean;\n\t/** Aggregate counts — always present regardless of MVI level. */\n\tsummary: {\n\t\t/** Number of passing doctests. */\n\t\tpassed: number;\n\t\t/** Number of failing doctests. */\n\t\tfailed: number;\n\t\t/** Total doctests run. */\n\t\ttotal: number;\n\t\t/** Wall-clock duration in milliseconds. */\n\t\tduration: number;\n\t};\n\t/** Per-failure details — present at standard and full MVI levels. */\n\tfailures?: TestFailure[];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Runs the doctest pipeline and returns a typed command output.\n *\n * @param args - CLI arguments for the test command.\n * @returns A typed `CommandOutput<TestResult>`.\n * @example\n * ```typescript\n * import { runTest } from \"@forge-ts/cli/commands/test\";\n * const output = await runTest({ cwd: process.cwd() });\n * console.log(output.data.summary.passed); // number of passing doctests\n * ```\n * @public\n */\nexport async function runTest(args: TestArgs): Promise<CommandOutput<TestResult>> {\n\tconst config = await loadConfig(args.cwd);\n\tconst result = await doctest(config);\n\tconst mviLevel = args.mvi ?? \"standard\";\n\n\tconst failCount = result.errors.length;\n\tconst totalSymbols = result.symbols.length;\n\tconst passCount = totalSymbols - failCount > 0 ? totalSymbols - failCount : 0;\n\n\tconst summary = {\n\t\tpassed: passCount,\n\t\tfailed: failCount,\n\t\ttotal: totalSymbols,\n\t\tduration: result.duration,\n\t};\n\n\tconst data: TestResult = { success: result.success, summary };\n\n\tif (mviLevel !== \"minimal\") {\n\t\tdata.failures = result.errors.map((e) => ({\n\t\t\tsymbol: e.symbolName ?? \"\",\n\t\t\tfile: e.filePath ?? \"\",\n\t\t\tline: e.line,\n\t\t\tmessage: e.message,\n\t\t}));\n\t}\n\n\treturn {\n\t\toperation: \"test\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\tduration: result.duration,\n\t};\n}\n\n/**\n * Citty command definition for `forge-ts test`.\n * @public\n */\nexport const testCommand = defineCommand({\n\tmeta: {\n\t\tname: \"test\",\n\t\tdescription: \"Run @example blocks as doctests\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\tjson: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as LAFS JSON envelope (agent-friendly)\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text (default for TTY)\",\n\t\t\tdefault: false,\n\t\t},\n\t\tquiet: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Suppress non-essential output\",\n\t\t\tdefault: false,\n\t\t},\n\t\tmvi: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"MVI verbosity level: minimal, standard, full\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tconst output = await runTest({ cwd: args.cwd, mvi: args.mvi });\n\n\t\tconst flags: OutputFlags = {\n\t\t\tjson: args.json,\n\t\t\thuman: args.human,\n\t\t\tquiet: args.quiet,\n\t\t\tmvi: args.mvi,\n\t\t};\n\n\t\temitResult(output, flags, (data) => {\n\t\t\tif (output.success) {\n\t\t\t\treturn `forge-ts test: all doctests passed. (${data.summary.duration}ms)`;\n\t\t\t}\n\t\t\tconst lines: string[] = [];\n\t\t\tfor (const f of data.failures ?? []) {\n\t\t\t\tlines.push(f.message);\n\t\t\t}\n\t\t\tlines.push(`forge-ts test: ${data.summary.failed} failure(s). (${data.summary.duration}ms)`);\n\t\t\treturn lines.join(\"\\n\");\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n"],"mappings":"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","names":["defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","defineCommand"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge-ts/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "CLI entry point for forge-ts",
6
6
  "license": "MIT",
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@cleocode/lafs-protocol": "^1.7.0",
31
31
  "citty": "^0.2.1",
32
- "@forge-ts/core": "0.2.1",
33
- "@forge-ts/api": "0.2.1",
34
- "@forge-ts/enforcer": "0.2.1",
35
- "@forge-ts/doctest": "0.2.1",
36
- "@forge-ts/gen": "0.2.1"
32
+ "@forge-ts/api": "0.3.1",
33
+ "@forge-ts/core": "0.3.1",
34
+ "@forge-ts/enforcer": "0.3.1",
35
+ "@forge-ts/doctest": "0.3.1",
36
+ "@forge-ts/gen": "0.3.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "tsup": "^8.3.5",