@forge-ts/cli 0.5.0 → 0.6.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/dist/index.d.ts CHANGED
@@ -65,9 +65,13 @@ interface OutputFlags {
65
65
  /**
66
66
  * Wraps a command result in a LAFS envelope and emits it.
67
67
  *
68
- * - JSON mode: writes the projected envelope to stdout as JSON.
69
- * - Human mode: calls the provided formatter function.
70
- * - Quiet mode: suppresses all output regardless of format.
68
+ * Output format is determined by LAFS flag resolution:
69
+ * - TTY terminals default to human-readable output.
70
+ * - Non-TTY (piped, CI, agents) defaults to JSON.
71
+ * - Explicit `--json` or `--human` flags always take precedence.
72
+ *
73
+ * On failure, the full result is included alongside the error so agents
74
+ * get actionable data (e.g., suggestedFix) in a single response.
71
75
  *
72
76
  * @param output - Typed result from the command.
73
77
  * @param flags - Output format flags from citty args.
@@ -147,6 +151,11 @@ declare const buildCommand: citty.CommandDef<{
147
151
  readonly description: "Skip doc generation";
148
152
  readonly default: false;
149
153
  };
154
+ readonly "force-stubs": {
155
+ readonly type: "boolean";
156
+ readonly description: "Overwrite stub pages even if they exist (reset to scaffolding)";
157
+ readonly default: false;
158
+ };
150
159
  readonly json: {
151
160
  readonly type: "boolean";
152
161
  readonly description: "Output as LAFS JSON envelope (agent-friendly)";
@@ -279,6 +288,63 @@ declare const checkCommand: citty.CommandDef<{
279
288
  };
280
289
  }>;
281
290
 
291
+ /**
292
+ * The `forge-ts docs dev` command — starts a local doc preview server.
293
+ *
294
+ * Reads the ssgTarget from forge-ts config, looks up the adapter,
295
+ * and spawns the correct dev server automatically.
296
+ *
297
+ * @packageDocumentation
298
+ * @public
299
+ */
300
+ /**
301
+ * Starts the local dev server for the configured SSG target.
302
+ *
303
+ * Reads `gen.ssgTarget` from the forge-ts config, resolves the adapter,
304
+ * and spawns the platform's dev server in the output directory.
305
+ *
306
+ * @param args - Command arguments.
307
+ * @returns A promise that resolves when the server exits.
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * import { runDocsDev } from "@forge-ts/cli";
312
+ * await runDocsDev({ cwd: "./my-project" });
313
+ * ```
314
+ * @public
315
+ */
316
+ declare function runDocsDev(args: {
317
+ /** Project root directory. */
318
+ cwd?: string;
319
+ /** Override the SSG target from config. */
320
+ target?: string;
321
+ /** Port to run the dev server on. */
322
+ port?: string;
323
+ }): Promise<void>;
324
+ /**
325
+ * Citty command definition for `forge-ts docs dev`.
326
+ *
327
+ * @example
328
+ * ```typescript
329
+ * import { docsDevCommand } from "@forge-ts/cli";
330
+ * ```
331
+ * @public
332
+ */
333
+ declare const docsDevCommand: citty.CommandDef<{
334
+ readonly cwd: {
335
+ readonly type: "string";
336
+ readonly description: "Project root directory";
337
+ };
338
+ readonly target: {
339
+ readonly type: "string";
340
+ readonly description: "SSG target override (reads from config by default)";
341
+ };
342
+ readonly port: {
343
+ readonly type: "string";
344
+ readonly description: "Port for the dev server";
345
+ };
346
+ }>;
347
+
282
348
  /**
283
349
  * Result of the `init docs` command.
284
350
  *
@@ -360,19 +426,6 @@ declare const initDocsCommand: citty.CommandDef<{
360
426
  readonly description: "MVI verbosity level: minimal, standard, full";
361
427
  };
362
428
  }>;
363
- /**
364
- * Citty command definition for `forge-ts init`.
365
- *
366
- * Exposes subcommands for scaffolding project artefacts.
367
- *
368
- * @example
369
- * ```typescript
370
- * import { initCommand } from "@forge-ts/cli/commands/init-docs";
371
- * // Registered automatically as a subcommand of `forge-ts`
372
- * ```
373
- * @public
374
- */
375
- declare const initCommand: citty.CommandDef<citty.ArgsDef>;
376
429
 
377
430
  /**
378
431
  * A single test failure entry, included at standard and full MVI levels.
@@ -481,4 +534,4 @@ declare function createLogger(options?: {
481
534
  colors?: boolean;
482
535
  }): Logger;
483
536
 
484
- export { type BuildResult, type BuildStep, type CheckFileError, type CheckFileGroup, type CheckFileWarning, type CheckResult, type CommandOutput, type ForgeCliError, type ForgeCliWarning, type InitDocsResult, type Logger, type OutputFlags, type TestFailure, type TestResult, buildCommand, checkCommand, createLogger, emitResult, initCommand, initDocsCommand, resolveExitCode, testCommand };
537
+ export { type BuildResult, type BuildStep, type CheckFileError, type CheckFileGroup, type CheckFileWarning, type CheckResult, type CommandOutput, type ForgeCliError, type ForgeCliWarning, type InitDocsResult, type Logger, type OutputFlags, type TestFailure, type TestResult, buildCommand, checkCommand, createLogger, docsDevCommand, emitResult, initDocsCommand, resolveExitCode, runDocsDev, testCommand };
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { defineCommand as defineCommand5, runMain } from "citty";
4
+ import { createRequire } from "module";
5
+ import { defineCommand as defineCommand6, runMain } from "citty";
5
6
 
6
7
  // src/commands/build.ts
7
8
  import { join } from "path";
@@ -52,7 +53,6 @@ function createLogger(options) {
52
53
  import { randomUUID } from "crypto";
53
54
  import {
54
55
  createEnvelope,
55
- projectEnvelope,
56
56
  resolveFlags
57
57
  } from "@cleocode/lafs-protocol";
58
58
  function emitResult(output, flags, humanFormatter) {
@@ -60,7 +60,10 @@ function emitResult(output, flags, humanFormatter) {
60
60
  json: flags.json,
61
61
  human: flags.human,
62
62
  quiet: flags.quiet,
63
- mvi: flags.mvi
63
+ mvi: flags.mvi,
64
+ // LAFS 1.8.0: TTY detection drives the default format.
65
+ // Terminals get human output, pipes/agents get JSON.
66
+ tty: process.stdout.isTTY ?? false
64
67
  };
65
68
  const resolved = resolveFlags(flagInput);
66
69
  const format = resolved.format.format;
@@ -68,41 +71,30 @@ function emitResult(output, flags, humanFormatter) {
68
71
  if (quiet) {
69
72
  return;
70
73
  }
71
- const envelope = createEnvelope(
72
- output.success ? {
73
- success: true,
74
- result: output.data,
75
- meta: {
76
- operation: `forge-ts.${output.operation}`,
77
- requestId: randomUUID(),
78
- transport: "cli",
79
- mvi: flags.mvi ?? "standard"
80
- }
81
- } : {
82
- success: false,
83
- error: {
84
- code: output.errors?.[0]?.code ?? "FORGE_ERROR",
85
- message: output.errors?.[0]?.message ?? "Command failed",
86
- category: "VALIDATION",
87
- retryable: false,
88
- retryAfterMs: null,
89
- details: {
90
- errors: output.errors ?? [],
91
- warnings: output.warnings ?? []
92
- }
93
- },
94
- meta: {
95
- operation: `forge-ts.${output.operation}`,
96
- requestId: randomUUID(),
97
- transport: "cli",
98
- mvi: flags.mvi ?? "standard"
99
- }
100
- }
101
- );
74
+ const meta = {
75
+ operation: `forge-ts.${output.operation}`,
76
+ requestId: randomUUID(),
77
+ transport: "cli",
78
+ mvi: flags.mvi ?? "full"
79
+ };
80
+ const envelope = output.success ? createEnvelope({
81
+ success: true,
82
+ result: output.data,
83
+ meta
84
+ }) : createEnvelope({
85
+ success: false,
86
+ result: output.data,
87
+ error: {
88
+ code: output.errors?.[0]?.code ?? "FORGE_CHECK_FAILED",
89
+ message: output.errors?.[0]?.message ?? "Check failed \u2014 see result for actionable fixes",
90
+ category: "VALIDATION",
91
+ retryable: true,
92
+ retryAfterMs: null
93
+ },
94
+ meta
95
+ });
102
96
  if (format === "json") {
103
- const mviLevel = flags.mvi ?? "standard";
104
- const projected = projectEnvelope(envelope, mviLevel);
105
- process.stdout.write(`${JSON.stringify(projected, null, 2)}
97
+ process.stdout.write(`${JSON.stringify(envelope, null, 2)}
106
98
  `);
107
99
  } else {
108
100
  const formatted = humanFormatter(output.data, output);
@@ -157,7 +149,7 @@ async function runBuild(args) {
157
149
  steps.push({ name: "api", status: "skipped" });
158
150
  }
159
151
  if (config.gen.enabled && !args.skipGen) {
160
- const result = await generate(config);
152
+ const result = await generate(config, { forceStubs: args.forceStubs });
161
153
  if (!result.success) {
162
154
  const errors = result.errors.map((e) => ({
163
155
  code: e.code,
@@ -236,6 +228,11 @@ var buildCommand = defineCommand({
236
228
  description: "Skip doc generation",
237
229
  default: false
238
230
  },
231
+ "force-stubs": {
232
+ type: "boolean",
233
+ description: "Overwrite stub pages even if they exist (reset to scaffolding)",
234
+ default: false
235
+ },
239
236
  json: {
240
237
  type: "boolean",
241
238
  description: "Output as LAFS JSON envelope (agent-friendly)",
@@ -261,6 +258,7 @@ var buildCommand = defineCommand({
261
258
  cwd: args.cwd,
262
259
  skipApi: args["skip-api"],
263
260
  skipGen: args["skip-gen"],
261
+ forceStubs: args["force-stubs"],
264
262
  mvi: args.mvi
265
263
  });
266
264
  const flags = {
@@ -349,7 +347,7 @@ function buildCheckResult(rawErrors, rawWarnings, _symbolCount, exportedSymbolCo
349
347
  if (mviLevel === "minimal") {
350
348
  return { success, summary };
351
349
  }
352
- const byFile = groupByFile(rawErrors, rawWarnings, mviLevel === "full");
350
+ const byFile = groupByFile(rawErrors, rawWarnings, mviLevel !== "minimal");
353
351
  return { success, summary, byFile };
354
352
  }
355
353
  async function runCheck(args) {
@@ -358,7 +356,7 @@ async function runCheck(args) {
358
356
  config.enforce.strict = args.strict;
359
357
  }
360
358
  const result = await enforce(config);
361
- const mviLevel = args.mvi ?? "standard";
359
+ const mviLevel = args.mvi ?? "full";
362
360
  const exportedSymbolCount = result.symbols.filter((s) => s.exported).length;
363
361
  const data = buildCheckResult(
364
362
  result.errors,
@@ -369,10 +367,17 @@ async function runCheck(args) {
369
367
  result.success,
370
368
  mviLevel
371
369
  );
370
+ const cliErrors = result.success ? void 0 : [
371
+ {
372
+ code: "FORGE_CHECK_FAILED",
373
+ message: `TSDoc coverage check failed: ${result.errors.length} error(s), ${result.warnings.length} warning(s) across ${data.summary.files} file(s)`
374
+ }
375
+ ];
372
376
  return {
373
377
  operation: "check",
374
378
  success: result.success,
375
379
  data,
380
+ errors: cliErrors,
376
381
  duration: result.duration
377
382
  };
378
383
  }
@@ -396,6 +401,11 @@ function formatCheckHuman(result) {
396
401
  for (const err of group.errors) {
397
402
  const symbolPart = err.symbol ? `${err.symbol} (${err.kind}:${err.line})` : `line ${err.line}`;
398
403
  lines.push(` ${err.code} ${symbolPart} \u2014 ${err.message}`);
404
+ if (err.suggestedFix) {
405
+ for (const fixLine of err.suggestedFix.split("\n")) {
406
+ lines.push(` ${fixLine}`);
407
+ }
408
+ }
399
409
  }
400
410
  }
401
411
  if (group.warnings.length > 0) {
@@ -405,9 +415,7 @@ function formatCheckHuman(result) {
405
415
  }
406
416
  }
407
417
  }
408
- lines.push("");
409
418
  }
410
- lines.push(" Run with --json --mvi full for exact fix suggestions.");
411
419
  return lines.join("\n");
412
420
  }
413
421
  var checkCommand = defineCommand2({
@@ -468,19 +476,81 @@ var checkCommand = defineCommand2({
468
476
  }
469
477
  });
470
478
 
479
+ // src/commands/docs-dev.ts
480
+ import { spawn } from "child_process";
481
+ import { resolve } from "path";
482
+ import { loadConfig as loadConfig3 } from "@forge-ts/core";
483
+ import { DEFAULT_TARGET, getAdapter } from "@forge-ts/gen";
484
+ import { defineCommand as defineCommand3 } from "citty";
485
+ async function runDocsDev(args) {
486
+ const logger = createLogger();
487
+ const config = await loadConfig3(args.cwd);
488
+ const target = args.target ?? config.gen.ssgTarget ?? DEFAULT_TARGET;
489
+ const adapter = getAdapter(target);
490
+ const outDir = resolve(config.outDir);
491
+ const devCmd = adapter.getDevCommand(outDir);
492
+ logger.info(`Starting ${devCmd.label}...`);
493
+ logger.info(` Target: ${target}`);
494
+ logger.info(` Directory: ${outDir}`);
495
+ logger.info(` URL: ${devCmd.url}`);
496
+ logger.info("");
497
+ const spawnArgs = [...devCmd.args];
498
+ if (args.port) {
499
+ spawnArgs.push("--port", args.port);
500
+ }
501
+ const proc = spawn(devCmd.bin, spawnArgs, {
502
+ cwd: devCmd.cwd,
503
+ stdio: "inherit",
504
+ shell: true
505
+ });
506
+ return new Promise((_resolve, reject) => {
507
+ proc.on("close", (code) => {
508
+ if (code === 0) {
509
+ _resolve();
510
+ } else {
511
+ reject(new Error(`${devCmd.label} exited with code ${code}`));
512
+ }
513
+ });
514
+ proc.on("error", reject);
515
+ });
516
+ }
517
+ var docsDevCommand = defineCommand3({
518
+ meta: {
519
+ name: "dev",
520
+ description: "Start a local doc preview server"
521
+ },
522
+ args: {
523
+ cwd: {
524
+ type: "string",
525
+ description: "Project root directory"
526
+ },
527
+ target: {
528
+ type: "string",
529
+ description: "SSG target override (reads from config by default)"
530
+ },
531
+ port: {
532
+ type: "string",
533
+ description: "Port for the dev server"
534
+ }
535
+ },
536
+ async run({ args }) {
537
+ await runDocsDev(args);
538
+ }
539
+ });
540
+
471
541
  // src/commands/init-docs.ts
472
542
  import { mkdir, writeFile } from "fs/promises";
473
- import { join as join2, resolve } from "path";
474
- import { loadConfig as loadConfig3 } from "@forge-ts/core";
543
+ import { join as join2, resolve as resolve2 } from "path";
544
+ import { loadConfig as loadConfig4 } from "@forge-ts/core";
475
545
  import {
476
- DEFAULT_TARGET,
477
- getAdapter,
546
+ DEFAULT_TARGET as DEFAULT_TARGET2,
547
+ getAdapter as getAdapter2,
478
548
  getAvailableTargets
479
549
  } from "@forge-ts/gen";
480
- import { defineCommand as defineCommand3 } from "citty";
550
+ import { defineCommand as defineCommand4 } from "citty";
481
551
  async function runInitDocs(args) {
482
552
  const start = Date.now();
483
- const rawTarget = args.target ?? DEFAULT_TARGET;
553
+ const rawTarget = args.target ?? DEFAULT_TARGET2;
484
554
  const available = getAvailableTargets();
485
555
  if (!available.includes(rawTarget)) {
486
556
  const err = {
@@ -492,7 +562,7 @@ async function runInitDocs(args) {
492
562
  success: false,
493
563
  data: {
494
564
  success: false,
495
- target: DEFAULT_TARGET,
565
+ target: DEFAULT_TARGET2,
496
566
  summary: { filesCreated: 0, dependencies: 0, scripts: 0 },
497
567
  files: [],
498
568
  instructions: []
@@ -502,9 +572,9 @@ async function runInitDocs(args) {
502
572
  };
503
573
  }
504
574
  const target = rawTarget;
505
- const adapter = getAdapter(target);
506
- const config = await loadConfig3(args.cwd);
507
- const outDir = args.outDir ? resolve(args.outDir) : config.outDir;
575
+ const adapter = getAdapter2(target);
576
+ const config = await loadConfig4(args.cwd);
577
+ const outDir = args.outDir ? resolve2(args.outDir) : config.outDir;
508
578
  const alreadyExists = await adapter.detectExisting(outDir);
509
579
  if (alreadyExists && !args.force) {
510
580
  const err = {
@@ -528,7 +598,7 @@ async function runInitDocs(args) {
528
598
  const warnings = [];
529
599
  for (const otherTarget of available) {
530
600
  if (otherTarget === target) continue;
531
- const otherAdapter = getAdapter(otherTarget);
601
+ const otherAdapter = getAdapter2(otherTarget);
532
602
  const otherExists = await otherAdapter.detectExisting(outDir);
533
603
  if (otherExists) {
534
604
  warnings.push({
@@ -611,7 +681,7 @@ function formatInitDocsHuman(result) {
611
681
  );
612
682
  return lines.join("\n");
613
683
  }
614
- var initDocsCommand = defineCommand3({
684
+ var initDocsCommand = defineCommand4({
615
685
  meta: {
616
686
  name: "docs",
617
687
  description: "Scaffold a documentation site"
@@ -619,7 +689,7 @@ var initDocsCommand = defineCommand3({
619
689
  args: {
620
690
  target: {
621
691
  type: "string",
622
- description: `SSG target: ${getAvailableTargets().join(", ")} (default: ${DEFAULT_TARGET})`
692
+ description: `SSG target: ${getAvailableTargets().join(", ")} (default: ${DEFAULT_TARGET2})`
623
693
  },
624
694
  cwd: {
625
695
  type: "string",
@@ -680,7 +750,7 @@ var initDocsCommand = defineCommand3({
680
750
  process.exit(resolveExitCode(output));
681
751
  }
682
752
  });
683
- var initCommand = defineCommand3({
753
+ var initCommand = defineCommand4({
684
754
  meta: {
685
755
  name: "init",
686
756
  description: "Scaffold project artefacts"
@@ -691,11 +761,11 @@ var initCommand = defineCommand3({
691
761
  });
692
762
 
693
763
  // src/commands/test.ts
694
- import { loadConfig as loadConfig4 } from "@forge-ts/core";
764
+ import { loadConfig as loadConfig5 } from "@forge-ts/core";
695
765
  import { doctest } from "@forge-ts/doctest";
696
- import { defineCommand as defineCommand4 } from "citty";
766
+ import { defineCommand as defineCommand5 } from "citty";
697
767
  async function runTest(args) {
698
- const config = await loadConfig4(args.cwd);
768
+ const config = await loadConfig5(args.cwd);
699
769
  const result = await doctest(config);
700
770
  const mviLevel = args.mvi ?? "standard";
701
771
  const failCount = result.errors.length;
@@ -716,14 +786,19 @@ async function runTest(args) {
716
786
  message: e.message
717
787
  }));
718
788
  }
789
+ const cliErrors = result.success ? void 0 : result.errors.map((e) => ({
790
+ code: e.code,
791
+ message: e.message
792
+ }));
719
793
  return {
720
794
  operation: "test",
721
795
  success: result.success,
722
796
  data,
797
+ errors: cliErrors,
723
798
  duration: result.duration
724
799
  };
725
800
  }
726
- var testCommand = defineCommand4({
801
+ var testCommand = defineCommand5({
727
802
  meta: {
728
803
  name: "test",
729
804
  description: "Run @example blocks as doctests"
@@ -777,17 +852,29 @@ var testCommand = defineCommand4({
777
852
  });
778
853
 
779
854
  // src/index.ts
780
- var main = defineCommand5({
855
+ var require2 = createRequire(import.meta.url);
856
+ var pkg = require2("../package.json");
857
+ var docsCommand = defineCommand6({
858
+ meta: {
859
+ name: "docs",
860
+ description: "Documentation site management"
861
+ },
862
+ subCommands: {
863
+ init: initDocsCommand,
864
+ dev: docsDevCommand
865
+ }
866
+ });
867
+ var main = defineCommand6({
781
868
  meta: {
782
869
  name: "forge-ts",
783
- version: "0.1.0",
870
+ version: pkg.version,
784
871
  description: "Universal TypeScript Documentation Compiler"
785
872
  },
786
873
  subCommands: {
787
874
  check: checkCommand,
788
875
  test: testCommand,
789
876
  build: buildCommand,
790
- init: initCommand
877
+ docs: docsCommand
791
878
  }
792
879
  });
793
880
  runMain(main);
@@ -795,10 +882,11 @@ export {
795
882
  buildCommand,
796
883
  checkCommand,
797
884
  createLogger,
885
+ docsDevCommand,
798
886
  emitResult,
799
- initCommand,
800
887
  initDocsCommand,
801
888
  resolveExitCode,
889
+ runDocsDev,
802
890
  testCommand
803
891
  };
804
892
  //# sourceMappingURL=index.js.map
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/init-docs.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 * forge-ts init docs [--target <ssg>] [--out-dir <dir>] [--force]\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 { initCommand } from \"./commands/init-docs.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 {\n\tinitCommand,\n\tinitDocsCommand,\n\ttype InitDocsResult,\n} from \"./commands/init-docs.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\tinit: initCommand,\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 { mkdir, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { loadConfig } from \"@forge-ts/core\";\nimport {\n\ttype AdapterContext,\n\tDEFAULT_TARGET,\n\tgetAdapter,\n\tgetAvailableTargets,\n\ttype SSGTarget,\n} 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// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Result of the `init docs` command.\n *\n * @example\n * ```typescript\n * import { runInitDocs } from \"@forge-ts/cli/commands/init-docs\";\n * const output = await runInitDocs({ target: \"mintlify\" });\n * console.log(output.data.summary.filesCreated); // number of files written\n * ```\n * @public\n */\nexport interface InitDocsResult {\n\t/** Whether the scaffold succeeded. */\n\tsuccess: boolean;\n\t/** The SSG target that was scaffolded. */\n\ttarget: SSGTarget;\n\t/** Summary of what was created. */\n\tsummary: {\n\t\t/** Number of files written to disk. */\n\t\tfilesCreated: number;\n\t\t/** Number of npm dependencies declared by the adapter. */\n\t\tdependencies: number;\n\t\t/** Number of package.json scripts declared by the adapter. */\n\t\tscripts: number;\n\t};\n\t/** Relative paths of all files created. */\n\tfiles: string[];\n\t/** Post-scaffold instructions for the user. */\n\tinstructions: string[];\n}\n\n/**\n * Arguments for the `init docs` command.\n * @internal\n */\nexport interface InitDocsArgs {\n\t/** SSG target to scaffold. Defaults to {@link DEFAULT_TARGET}. */\n\ttarget?: string;\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** Output directory for the doc site (default: outDir from config or ./docs). */\n\toutDir?: string;\n\t/** Overwrite an existing scaffold without prompting. */\n\tforce?: boolean;\n\t/** MVI verbosity level for structured output. */\n\tmvi?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Scaffolds a documentation site for the target SSG platform.\n *\n * Resolves the target from args, validates it, checks for an existing\n * scaffold, calls the adapter's `scaffold()` method, and writes all files\n * produced by the manifest to `outDir`.\n *\n * @param args - CLI arguments for the init docs command.\n * @returns A typed `CommandOutput<InitDocsResult>`.\n * @example\n * ```typescript\n * import { runInitDocs } from \"@forge-ts/cli/commands/init-docs\";\n * const output = await runInitDocs({ target: \"mintlify\", cwd: process.cwd() });\n * console.log(output.data.files); // list of created file paths\n * ```\n * @public\n */\nexport async function runInitDocs(args: InitDocsArgs): Promise<CommandOutput<InitDocsResult>> {\n\tconst start = Date.now();\n\n\t// 1. Resolve target\n\tconst rawTarget = args.target ?? DEFAULT_TARGET;\n\tconst available = getAvailableTargets();\n\tif (!available.includes(rawTarget as SSGTarget)) {\n\t\tconst err: ForgeCliError = {\n\t\t\tcode: \"INIT_UNKNOWN_TARGET\",\n\t\t\tmessage: `Unknown SSG target \"${rawTarget}\". Available targets: ${available.join(\", \")}`,\n\t\t};\n\t\treturn {\n\t\t\toperation: \"init.docs\",\n\t\t\tsuccess: false,\n\t\t\tdata: {\n\t\t\t\tsuccess: false,\n\t\t\t\ttarget: DEFAULT_TARGET,\n\t\t\t\tsummary: { filesCreated: 0, dependencies: 0, scripts: 0 },\n\t\t\t\tfiles: [],\n\t\t\t\tinstructions: [],\n\t\t\t},\n\t\t\terrors: [err],\n\t\t\tduration: Date.now() - start,\n\t\t};\n\t}\n\n\tconst target = rawTarget as SSGTarget;\n\tconst adapter = getAdapter(target);\n\n\t// 2. Load config to resolve outDir\n\tconst config = await loadConfig(args.cwd);\n\tconst outDir = args.outDir ? resolve(args.outDir) : config.outDir;\n\n\t// 3. Safety check: detect existing scaffold\n\tconst alreadyExists = await adapter.detectExisting(outDir);\n\tif (alreadyExists && !args.force) {\n\t\tconst err: ForgeCliError = {\n\t\t\tcode: \"INIT_ALREADY_EXISTS\",\n\t\t\tmessage: `Docs already scaffolded for ${target}. Use --force to overwrite.`,\n\t\t};\n\t\treturn {\n\t\t\toperation: \"init.docs\",\n\t\t\tsuccess: false,\n\t\t\tdata: {\n\t\t\t\tsuccess: false,\n\t\t\t\ttarget,\n\t\t\t\tsummary: { filesCreated: 0, dependencies: 0, scripts: 0 },\n\t\t\t\tfiles: [],\n\t\t\t\tinstructions: [],\n\t\t\t},\n\t\t\terrors: [err],\n\t\t\tduration: Date.now() - start,\n\t\t};\n\t}\n\n\t// 4. Check for cross-target collision (any other adapter already scaffolded)\n\tconst warnings: Array<{ code: string; message: string }> = [];\n\tfor (const otherTarget of available) {\n\t\tif (otherTarget === target) continue;\n\t\tconst otherAdapter = getAdapter(otherTarget as SSGTarget);\n\t\tconst otherExists = await otherAdapter.detectExisting(outDir);\n\t\tif (otherExists) {\n\t\t\twarnings.push({\n\t\t\t\tcode: \"INIT_TARGET_MISMATCH\",\n\t\t\t\tmessage: `Existing scaffold detected for ${otherTarget} but scaffolding for ${target}. Remove conflicting files to avoid issues.`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// 5. Build AdapterContext — use an empty pages/symbols array for init\n\tconst projectName = config.rootDir.split(\"/\").pop() ?? \"Project\";\n\tconst context: AdapterContext = {\n\t\tconfig,\n\t\tprojectName,\n\t\tpages: [],\n\t\tsymbols: [],\n\t\toutDir,\n\t};\n\n\t// 6. Call adapter.scaffold() to get the ScaffoldManifest\n\tconst manifest = adapter.scaffold(context);\n\n\t// 7. Write all files from the manifest\n\tconst writtenFiles: string[] = [];\n\tfor (const file of manifest.files) {\n\t\tconst filePath = join(outDir, file.path);\n\t\tconst fileDir = filePath.substring(0, filePath.lastIndexOf(\"/\"));\n\t\tawait mkdir(fileDir, { recursive: true });\n\t\tawait writeFile(filePath, file.content, \"utf8\");\n\t\twrittenFiles.push(file.path);\n\t}\n\n\tconst depCount =\n\t\tObject.keys(manifest.dependencies).length + Object.keys(manifest.devDependencies).length;\n\tconst scriptCount = Object.keys(manifest.scripts).length;\n\n\tconst data: InitDocsResult = {\n\t\tsuccess: true,\n\t\ttarget,\n\t\tsummary: {\n\t\t\tfilesCreated: writtenFiles.length,\n\t\t\tdependencies: depCount,\n\t\t\tscripts: scriptCount,\n\t\t},\n\t\tfiles: writtenFiles,\n\t\tinstructions: manifest.instructions,\n\t};\n\n\treturn {\n\t\toperation: \"init.docs\",\n\t\tsuccess: true,\n\t\tdata,\n\t\twarnings:\n\t\t\twarnings.length > 0\n\t\t\t\t? warnings.map((w) => ({\n\t\t\t\t\t\tcode: w.code,\n\t\t\t\t\t\tmessage: w.message,\n\t\t\t\t\t\tfilePath: \"\",\n\t\t\t\t\t\tline: 0,\n\t\t\t\t\t\tcolumn: 0,\n\t\t\t\t\t}))\n\t\t\t\t: undefined,\n\t\tduration: Date.now() - start,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Human formatter\n// ---------------------------------------------------------------------------\n\n/**\n * Formats an InitDocsResult as human-readable text.\n * @internal\n */\nfunction formatInitDocsHuman(result: InitDocsResult): string {\n\tconst lines: string[] = [];\n\n\tif (!result.success) {\n\t\treturn \"\";\n\t}\n\n\tconst targetName = result.target.charAt(0).toUpperCase() + result.target.slice(1);\n\tlines.push(`\\n Scaffolding ${targetName} documentation site...\\n`);\n\n\tconst MAX_INLINE = 5;\n\tconst shown = result.files.slice(0, MAX_INLINE);\n\tconst remaining = result.files.length - shown.length;\n\n\tfor (const file of shown) {\n\t\tlines.push(` \\u2713 Created ${file}`);\n\t}\n\n\tif (remaining > 0) {\n\t\tlines.push(` ... (${remaining} more file${remaining !== 1 ? \"s\" : \"\"})`);\n\t}\n\n\tif (result.instructions.length > 0) {\n\t\tlines.push(\"\\n Next steps:\");\n\t\tresult.instructions.forEach((inst, idx) => {\n\t\t\tlines.push(` ${idx + 1}. ${inst}`);\n\t\t});\n\t}\n\n\tlines.push(\n\t\t`\\n ${result.summary.filesCreated} file${result.summary.filesCreated !== 1 ? \"s\" : \"\"} created for ${targetName} doc site.`,\n\t);\n\n\treturn lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Citty command definition\n// ---------------------------------------------------------------------------\n\n/**\n * Citty command definition for `forge-ts init docs`.\n *\n * Scaffolds a complete documentation site for the target SSG platform.\n * Use `--json` for LAFS JSON envelope output (agent/CI-friendly).\n *\n * @example\n * ```typescript\n * import { initDocsCommand } from \"@forge-ts/cli/commands/init-docs\";\n * // Registered automatically as a subcommand of `forge-ts init`\n * ```\n * @public\n */\nexport const initDocsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"docs\",\n\t\tdescription: \"Scaffold a documentation site\",\n\t},\n\targs: {\n\t\ttarget: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: `SSG target: ${getAvailableTargets().join(\", \")} (default: ${DEFAULT_TARGET})`,\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\t\"out-dir\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Output directory for doc site (default: ./docs)\",\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Overwrite existing scaffold\",\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\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text\",\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 runInitDocs({\n\t\t\ttarget: args.target,\n\t\t\tcwd: args.cwd,\n\t\t\toutDir: args[\"out-dir\"],\n\t\t\tforce: args.force,\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, cmd) => {\n\t\t\tif (!cmd.success) {\n\t\t\t\tconst logger = createLogger();\n\t\t\t\tconst msg = cmd.errors?.[0]?.message ?? \"Scaffold failed\";\n\t\t\t\tlogger.error(msg);\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\treturn formatInitDocsHuman(data);\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// Parent \"init\" command that exposes `forge-ts init docs`\n// ---------------------------------------------------------------------------\n\n/**\n * Citty command definition for `forge-ts init`.\n *\n * Exposes subcommands for scaffolding project artefacts.\n *\n * @example\n * ```typescript\n * import { initCommand } from \"@forge-ts/cli/commands/init-docs\";\n * // Registered automatically as a subcommand of `forge-ts`\n * ```\n * @public\n */\nexport const initCommand = defineCommand({\n\tmeta: {\n\t\tname: \"init\",\n\t\tdescription: \"Scaffold project artefacts\",\n\t},\n\tsubCommands: {\n\t\tdocs: initDocsCommand,\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","join","loadConfig","defineCommand","loadConfig","join","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/docs-dev.ts","../src/commands/init-docs.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 * forge-ts docs init [--target <ssg>] [--out-dir <dir>] [--force]\n * forge-ts docs dev [--target <ssg>] [--port <port>]\n *\n * @packageDocumentation\n * @public\n */\n\nimport { createRequire } from \"node:module\";\nimport { defineCommand, runMain } from \"citty\";\nimport { buildCommand } from \"./commands/build.js\";\nimport { checkCommand } from \"./commands/check.js\";\nimport { docsDevCommand } from \"./commands/docs-dev.js\";\nimport { initDocsCommand } from \"./commands/init-docs.js\";\nimport { testCommand } from \"./commands/test.js\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string };\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 { docsDevCommand, runDocsDev } from \"./commands/docs-dev.js\";\nexport {\n\ttype InitDocsResult,\n\tinitDocsCommand,\n} from \"./commands/init-docs.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\n/**\n * The `docs` parent command with `init` and `dev` subcommands.\n *\n * @example\n * ```typescript\n * // forge-ts docs init --target mintlify\n * // forge-ts docs dev\n * ```\n * @public\n */\nconst docsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"docs\",\n\t\tdescription: \"Documentation site management\",\n\t},\n\tsubCommands: {\n\t\tinit: initDocsCommand,\n\t\tdev: docsDevCommand,\n\t},\n});\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"forge-ts\",\n\t\tversion: pkg.version,\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\tdocs: docsCommand,\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/**\n\t * Overwrite stub pages even if they already exist on disk.\n\t * Normally stub pages (concepts, guides, faq, contributing, changelog)\n\t * are only created on the first build to preserve manual edits.\n\t * Use this to reset stubs to their scaffolding state.\n\t */\n\tforceStubs?: 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, { forceStubs: args.forceStubs });\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\t\"force-stubs\": {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Overwrite stub pages even if they exist (reset to scaffolding)\",\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\tforceStubs: args[\"force-stubs\"],\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\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 * Output format is determined by LAFS flag resolution:\n * - TTY terminals default to human-readable output.\n * - Non-TTY (piped, CI, agents) defaults to JSON.\n * - Explicit `--json` or `--human` flags always take precedence.\n *\n * On failure, the full result is included alongside the error so agents\n * get actionable data (e.g., suggestedFix) in a single response.\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\t// LAFS 1.8.0: TTY detection drives the default format.\n\t\t// Terminals get human output, pipes/agents get JSON.\n\t\ttty: process.stdout.isTTY ?? false,\n\t};\n\n\tconst resolved = resolveFlags(flagInput);\n\tconst format = resolved.format.format;\n\tconst quiet = resolved.format.quiet;\n\n\tif (quiet) {\n\t\treturn;\n\t}\n\n\tconst meta = {\n\t\toperation: `forge-ts.${output.operation}`,\n\t\trequestId: randomUUID(),\n\t\ttransport: \"cli\" as const,\n\t\tmvi: (flags.mvi as MVILevel) ?? \"full\",\n\t};\n\n\t// LAFS 1.8.0: result is included on error envelopes so agents get\n\t// actionable data (byFile, suggestedFix) alongside error metadata.\n\tconst envelope = output.success\n\t\t? createEnvelope({\n\t\t\t\tsuccess: true,\n\t\t\t\tresult: output.data as Record<string, unknown>,\n\t\t\t\tmeta,\n\t\t\t})\n\t\t: createEnvelope({\n\t\t\t\tsuccess: false,\n\t\t\t\tresult: output.data as Record<string, unknown>,\n\t\t\t\terror: {\n\t\t\t\t\tcode: output.errors?.[0]?.code ?? \"FORGE_CHECK_FAILED\",\n\t\t\t\t\tmessage: output.errors?.[0]?.message ?? \"Check failed — see result for actionable fixes\",\n\t\t\t\t\tcategory: \"VALIDATION\",\n\t\t\t\t\tretryable: true,\n\t\t\t\t\tretryAfterMs: null,\n\t\t\t\t},\n\t\t\t\tmeta,\n\t\t\t});\n\n\tif (format === \"json\") {\n\t\tprocess.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n\t} else {\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\t// Always include suggestedFix — actionable output shouldn't require extra flags.\n\t// MVI \"minimal\" omits byFile entirely (summary only).\n\t// MVI \"standard\" and \"full\" both include suggestedFix for every error.\n\tconst byFile = groupByFile(rawErrors, rawWarnings, mviLevel !== \"minimal\");\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\t// Default to \"full\" MVI so suggestedFix is always included in JSON output.\n\t// Agents need actionable fixes, not just error descriptions.\n\tconst mviLevel = args.mvi ?? \"full\";\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\t// Populate top-level errors so the LAFS envelope error code is actionable.\n\tconst cliErrors = result.success\n\t\t? undefined\n\t\t: [\n\t\t\t\t{\n\t\t\t\t\tcode: \"FORGE_CHECK_FAILED\",\n\t\t\t\t\tmessage: `TSDoc coverage check failed: ${result.errors.length} error(s), ${result.warnings.length} warning(s) across ${data.summary.files} file(s)`,\n\t\t\t\t},\n\t\t\t];\n\n\treturn {\n\t\toperation: \"check\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: cliErrors,\n\t\tduration: result.duration,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Human formatter\n// ---------------------------------------------------------------------------\n\n/**\n * Formats a CheckResult as human-readable, actionable text.\n *\n * Every error includes the exact TSDoc block to add (suggestedFix).\n * The agent or human can read the output and know exactly what to do\n * without needing additional flags or a second pass.\n *\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\t// Show the exact fix — actionable, not just informational\n\t\t\t\t\tif (err.suggestedFix) {\n\t\t\t\t\t\tfor (const fixLine of err.suggestedFix.split(\"\\n\")) {\n\t\t\t\t\t\t\tlines.push(` ${fixLine}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\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}\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","/**\n * The `forge-ts docs dev` command — starts a local doc preview server.\n *\n * Reads the ssgTarget from forge-ts config, looks up the adapter,\n * and spawns the correct dev server automatically.\n *\n * @packageDocumentation\n * @public\n */\n\nimport { spawn } from \"node:child_process\";\nimport { resolve } from \"node:path\";\nimport { loadConfig } from \"@forge-ts/core\";\nimport { DEFAULT_TARGET, getAdapter, type SSGTarget } from \"@forge-ts/gen\";\nimport { defineCommand } from \"citty\";\nimport { createLogger } from \"../logger.js\";\n\n/**\n * Starts the local dev server for the configured SSG target.\n *\n * Reads `gen.ssgTarget` from the forge-ts config, resolves the adapter,\n * and spawns the platform's dev server in the output directory.\n *\n * @param args - Command arguments.\n * @returns A promise that resolves when the server exits.\n *\n * @example\n * ```typescript\n * import { runDocsDev } from \"@forge-ts/cli\";\n * await runDocsDev({ cwd: \"./my-project\" });\n * ```\n * @public\n */\nexport async function runDocsDev(args: {\n\t/** Project root directory. */\n\tcwd?: string;\n\t/** Override the SSG target from config. */\n\ttarget?: string;\n\t/** Port to run the dev server on. */\n\tport?: string;\n}): Promise<void> {\n\tconst logger = createLogger();\n\tconst config = await loadConfig(args.cwd);\n\tconst target = (args.target ?? config.gen.ssgTarget ?? DEFAULT_TARGET) as SSGTarget;\n\tconst adapter = getAdapter(target);\n\tconst outDir = resolve(config.outDir);\n\tconst devCmd = adapter.getDevCommand(outDir);\n\n\tlogger.info(`Starting ${devCmd.label}...`);\n\tlogger.info(` Target: ${target}`);\n\tlogger.info(` Directory: ${outDir}`);\n\tlogger.info(` URL: ${devCmd.url}`);\n\tlogger.info(\"\");\n\n\tconst spawnArgs = [...devCmd.args];\n\tif (args.port) {\n\t\tspawnArgs.push(\"--port\", args.port);\n\t}\n\n\tconst proc = spawn(devCmd.bin, spawnArgs, {\n\t\tcwd: devCmd.cwd,\n\t\tstdio: \"inherit\",\n\t\tshell: true,\n\t});\n\n\treturn new Promise<void>((_resolve, reject) => {\n\t\tproc.on(\"close\", (code) => {\n\t\t\tif (code === 0) {\n\t\t\t\t_resolve();\n\t\t\t} else {\n\t\t\t\treject(new Error(`${devCmd.label} exited with code ${code}`));\n\t\t\t}\n\t\t});\n\t\tproc.on(\"error\", reject);\n\t});\n}\n\n/**\n * Citty command definition for `forge-ts docs dev`.\n *\n * @example\n * ```typescript\n * import { docsDevCommand } from \"@forge-ts/cli\";\n * ```\n * @public\n */\nexport const docsDevCommand = defineCommand({\n\tmeta: {\n\t\tname: \"dev\",\n\t\tdescription: \"Start a local doc preview server\",\n\t},\n\targs: {\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\ttarget: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"SSG target override (reads from config by default)\",\n\t\t},\n\t\tport: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Port for the dev server\",\n\t\t},\n\t},\n\tasync run({ args }) {\n\t\tawait runDocsDev(args);\n\t},\n});\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { loadConfig } from \"@forge-ts/core\";\nimport {\n\ttype AdapterContext,\n\tDEFAULT_TARGET,\n\tgetAdapter,\n\tgetAvailableTargets,\n\ttype SSGTarget,\n} 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// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Result of the `init docs` command.\n *\n * @example\n * ```typescript\n * import { runInitDocs } from \"@forge-ts/cli/commands/init-docs\";\n * const output = await runInitDocs({ target: \"mintlify\" });\n * console.log(output.data.summary.filesCreated); // number of files written\n * ```\n * @public\n */\nexport interface InitDocsResult {\n\t/** Whether the scaffold succeeded. */\n\tsuccess: boolean;\n\t/** The SSG target that was scaffolded. */\n\ttarget: SSGTarget;\n\t/** Summary of what was created. */\n\tsummary: {\n\t\t/** Number of files written to disk. */\n\t\tfilesCreated: number;\n\t\t/** Number of npm dependencies declared by the adapter. */\n\t\tdependencies: number;\n\t\t/** Number of package.json scripts declared by the adapter. */\n\t\tscripts: number;\n\t};\n\t/** Relative paths of all files created. */\n\tfiles: string[];\n\t/** Post-scaffold instructions for the user. */\n\tinstructions: string[];\n}\n\n/**\n * Arguments for the `init docs` command.\n * @internal\n */\nexport interface InitDocsArgs {\n\t/** SSG target to scaffold. Defaults to {@link DEFAULT_TARGET}. */\n\ttarget?: string;\n\t/** Project root directory (default: cwd). */\n\tcwd?: string;\n\t/** Output directory for the doc site (default: outDir from config or ./docs). */\n\toutDir?: string;\n\t/** Overwrite an existing scaffold without prompting. */\n\tforce?: boolean;\n\t/** MVI verbosity level for structured output. */\n\tmvi?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Scaffolds a documentation site for the target SSG platform.\n *\n * Resolves the target from args, validates it, checks for an existing\n * scaffold, calls the adapter's `scaffold()` method, and writes all files\n * produced by the manifest to `outDir`.\n *\n * @param args - CLI arguments for the init docs command.\n * @returns A typed `CommandOutput<InitDocsResult>`.\n * @example\n * ```typescript\n * import { runInitDocs } from \"@forge-ts/cli/commands/init-docs\";\n * const output = await runInitDocs({ target: \"mintlify\", cwd: process.cwd() });\n * console.log(output.data.files); // list of created file paths\n * ```\n * @public\n */\nexport async function runInitDocs(args: InitDocsArgs): Promise<CommandOutput<InitDocsResult>> {\n\tconst start = Date.now();\n\n\t// 1. Resolve target\n\tconst rawTarget = args.target ?? DEFAULT_TARGET;\n\tconst available = getAvailableTargets();\n\tif (!available.includes(rawTarget as SSGTarget)) {\n\t\tconst err: ForgeCliError = {\n\t\t\tcode: \"INIT_UNKNOWN_TARGET\",\n\t\t\tmessage: `Unknown SSG target \"${rawTarget}\". Available targets: ${available.join(\", \")}`,\n\t\t};\n\t\treturn {\n\t\t\toperation: \"init.docs\",\n\t\t\tsuccess: false,\n\t\t\tdata: {\n\t\t\t\tsuccess: false,\n\t\t\t\ttarget: DEFAULT_TARGET,\n\t\t\t\tsummary: { filesCreated: 0, dependencies: 0, scripts: 0 },\n\t\t\t\tfiles: [],\n\t\t\t\tinstructions: [],\n\t\t\t},\n\t\t\terrors: [err],\n\t\t\tduration: Date.now() - start,\n\t\t};\n\t}\n\n\tconst target = rawTarget as SSGTarget;\n\tconst adapter = getAdapter(target);\n\n\t// 2. Load config to resolve outDir\n\tconst config = await loadConfig(args.cwd);\n\tconst outDir = args.outDir ? resolve(args.outDir) : config.outDir;\n\n\t// 3. Safety check: detect existing scaffold\n\tconst alreadyExists = await adapter.detectExisting(outDir);\n\tif (alreadyExists && !args.force) {\n\t\tconst err: ForgeCliError = {\n\t\t\tcode: \"INIT_ALREADY_EXISTS\",\n\t\t\tmessage: `Docs already scaffolded for ${target}. Use --force to overwrite.`,\n\t\t};\n\t\treturn {\n\t\t\toperation: \"init.docs\",\n\t\t\tsuccess: false,\n\t\t\tdata: {\n\t\t\t\tsuccess: false,\n\t\t\t\ttarget,\n\t\t\t\tsummary: { filesCreated: 0, dependencies: 0, scripts: 0 },\n\t\t\t\tfiles: [],\n\t\t\t\tinstructions: [],\n\t\t\t},\n\t\t\terrors: [err],\n\t\t\tduration: Date.now() - start,\n\t\t};\n\t}\n\n\t// 4. Check for cross-target collision (any other adapter already scaffolded)\n\tconst warnings: Array<{ code: string; message: string }> = [];\n\tfor (const otherTarget of available) {\n\t\tif (otherTarget === target) continue;\n\t\tconst otherAdapter = getAdapter(otherTarget as SSGTarget);\n\t\tconst otherExists = await otherAdapter.detectExisting(outDir);\n\t\tif (otherExists) {\n\t\t\twarnings.push({\n\t\t\t\tcode: \"INIT_TARGET_MISMATCH\",\n\t\t\t\tmessage: `Existing scaffold detected for ${otherTarget} but scaffolding for ${target}. Remove conflicting files to avoid issues.`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// 5. Build AdapterContext — use an empty pages/symbols array for init\n\tconst projectName = config.rootDir.split(\"/\").pop() ?? \"Project\";\n\tconst context: AdapterContext = {\n\t\tconfig,\n\t\tprojectName,\n\t\tpages: [],\n\t\tsymbols: [],\n\t\toutDir,\n\t};\n\n\t// 6. Call adapter.scaffold() to get the ScaffoldManifest\n\tconst manifest = adapter.scaffold(context);\n\n\t// 7. Write all files from the manifest\n\tconst writtenFiles: string[] = [];\n\tfor (const file of manifest.files) {\n\t\tconst filePath = join(outDir, file.path);\n\t\tconst fileDir = filePath.substring(0, filePath.lastIndexOf(\"/\"));\n\t\tawait mkdir(fileDir, { recursive: true });\n\t\tawait writeFile(filePath, file.content, \"utf8\");\n\t\twrittenFiles.push(file.path);\n\t}\n\n\tconst depCount =\n\t\tObject.keys(manifest.dependencies).length + Object.keys(manifest.devDependencies).length;\n\tconst scriptCount = Object.keys(manifest.scripts).length;\n\n\tconst data: InitDocsResult = {\n\t\tsuccess: true,\n\t\ttarget,\n\t\tsummary: {\n\t\t\tfilesCreated: writtenFiles.length,\n\t\t\tdependencies: depCount,\n\t\t\tscripts: scriptCount,\n\t\t},\n\t\tfiles: writtenFiles,\n\t\tinstructions: manifest.instructions,\n\t};\n\n\treturn {\n\t\toperation: \"init.docs\",\n\t\tsuccess: true,\n\t\tdata,\n\t\twarnings:\n\t\t\twarnings.length > 0\n\t\t\t\t? warnings.map((w) => ({\n\t\t\t\t\t\tcode: w.code,\n\t\t\t\t\t\tmessage: w.message,\n\t\t\t\t\t\tfilePath: \"\",\n\t\t\t\t\t\tline: 0,\n\t\t\t\t\t\tcolumn: 0,\n\t\t\t\t\t}))\n\t\t\t\t: undefined,\n\t\tduration: Date.now() - start,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Human formatter\n// ---------------------------------------------------------------------------\n\n/**\n * Formats an InitDocsResult as human-readable text.\n * @internal\n */\nfunction formatInitDocsHuman(result: InitDocsResult): string {\n\tconst lines: string[] = [];\n\n\tif (!result.success) {\n\t\treturn \"\";\n\t}\n\n\tconst targetName = result.target.charAt(0).toUpperCase() + result.target.slice(1);\n\tlines.push(`\\n Scaffolding ${targetName} documentation site...\\n`);\n\n\tconst MAX_INLINE = 5;\n\tconst shown = result.files.slice(0, MAX_INLINE);\n\tconst remaining = result.files.length - shown.length;\n\n\tfor (const file of shown) {\n\t\tlines.push(` \\u2713 Created ${file}`);\n\t}\n\n\tif (remaining > 0) {\n\t\tlines.push(` ... (${remaining} more file${remaining !== 1 ? \"s\" : \"\"})`);\n\t}\n\n\tif (result.instructions.length > 0) {\n\t\tlines.push(\"\\n Next steps:\");\n\t\tresult.instructions.forEach((inst, idx) => {\n\t\t\tlines.push(` ${idx + 1}. ${inst}`);\n\t\t});\n\t}\n\n\tlines.push(\n\t\t`\\n ${result.summary.filesCreated} file${result.summary.filesCreated !== 1 ? \"s\" : \"\"} created for ${targetName} doc site.`,\n\t);\n\n\treturn lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Citty command definition\n// ---------------------------------------------------------------------------\n\n/**\n * Citty command definition for `forge-ts init docs`.\n *\n * Scaffolds a complete documentation site for the target SSG platform.\n * Use `--json` for LAFS JSON envelope output (agent/CI-friendly).\n *\n * @example\n * ```typescript\n * import { initDocsCommand } from \"@forge-ts/cli/commands/init-docs\";\n * // Registered automatically as a subcommand of `forge-ts init`\n * ```\n * @public\n */\nexport const initDocsCommand = defineCommand({\n\tmeta: {\n\t\tname: \"docs\",\n\t\tdescription: \"Scaffold a documentation site\",\n\t},\n\targs: {\n\t\ttarget: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: `SSG target: ${getAvailableTargets().join(\", \")} (default: ${DEFAULT_TARGET})`,\n\t\t},\n\t\tcwd: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Project root directory\",\n\t\t},\n\t\t\"out-dir\": {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Output directory for doc site (default: ./docs)\",\n\t\t},\n\t\tforce: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Overwrite existing scaffold\",\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\",\n\t\t\tdefault: false,\n\t\t},\n\t\thuman: {\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Output as formatted text\",\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 runInitDocs({\n\t\t\ttarget: args.target,\n\t\t\tcwd: args.cwd,\n\t\t\toutDir: args[\"out-dir\"],\n\t\t\tforce: args.force,\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, cmd) => {\n\t\t\tif (!cmd.success) {\n\t\t\t\tconst logger = createLogger();\n\t\t\t\tconst msg = cmd.errors?.[0]?.message ?? \"Scaffold failed\";\n\t\t\t\tlogger.error(msg);\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\treturn formatInitDocsHuman(data);\n\t\t});\n\n\t\tprocess.exit(resolveExitCode(output));\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// Parent \"init\" command that exposes `forge-ts init docs`\n// ---------------------------------------------------------------------------\n\n/**\n * Citty command definition for `forge-ts init`.\n *\n * Exposes subcommands for scaffolding project artefacts.\n *\n * @example\n * ```typescript\n * import { initCommand } from \"@forge-ts/cli/commands/init-docs\";\n * // Registered automatically as a subcommand of `forge-ts`\n * ```\n * @public\n */\nexport const initCommand = defineCommand({\n\tmeta: {\n\t\tname: \"init\",\n\t\tdescription: \"Scaffold project artefacts\",\n\t},\n\tsubCommands: {\n\t\tdocs: initDocsCommand,\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\t// Populate top-level errors so the LAFS envelope error code is actionable.\n\tconst cliErrors = result.success\n\t\t? undefined\n\t\t: result.errors.map((e) => ({\n\t\t\t\tcode: e.code,\n\t\t\t\tmessage: e.message,\n\t\t\t}));\n\n\treturn {\n\t\toperation: \"test\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: cliErrors,\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","join","resolve","loadConfig","DEFAULT_TARGET","getAdapter","defineCommand","DEFAULT_TARGET","getAdapter","loadConfig","resolve","join","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","require","defineCommand"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge-ts/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "description": "CLI entry point for forge-ts",
6
6
  "license": "MIT",
@@ -27,13 +27,13 @@
27
27
  }
28
28
  },
29
29
  "dependencies": {
30
- "@cleocode/lafs-protocol": "^1.7.0",
30
+ "@cleocode/lafs-protocol": "^1.8.0",
31
31
  "citty": "^0.2.1",
32
- "@forge-ts/api": "0.5.0",
33
- "@forge-ts/core": "0.5.0",
34
- "@forge-ts/enforcer": "0.5.0",
35
- "@forge-ts/doctest": "0.5.0",
36
- "@forge-ts/gen": "0.5.0"
32
+ "@forge-ts/core": "0.6.1",
33
+ "@forge-ts/doctest": "0.6.1",
34
+ "@forge-ts/api": "0.6.1",
35
+ "@forge-ts/enforcer": "0.6.1",
36
+ "@forge-ts/gen": "0.6.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "tsup": "^8.3.5",