@forge-ts/cli 0.6.6 → 0.7.0

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
@@ -178,7 +178,7 @@ declare const buildCommand: citty.CommandDef<{
178
178
  }>;
179
179
 
180
180
  /**
181
- * A single error entry within a file group, included at standard and full MVI levels.
181
+ * A single error entry within a file group.
182
182
  * @public
183
183
  */
184
184
  interface CheckFileError {
@@ -192,13 +192,13 @@ interface CheckFileError {
192
192
  line: number;
193
193
  /** Human-readable description. */
194
194
  message: string;
195
- /** Exact TSDoc block to add (full MVI level only). */
195
+ /** Exact TSDoc block to add (present at full MVI or with --rule/--file filters). */
196
196
  suggestedFix?: string;
197
- /** Recommended agent action (full MVI level only). */
197
+ /** Recommended agent action. */
198
198
  agentAction?: string;
199
199
  }
200
200
  /**
201
- * A single warning entry within a file group, included at standard and full MVI levels.
201
+ * A single warning entry within a file group.
202
202
  * @public
203
203
  */
204
204
  interface CheckFileWarning {
@@ -214,7 +214,7 @@ interface CheckFileWarning {
214
214
  message: string;
215
215
  }
216
216
  /**
217
- * Errors and warnings grouped by file, included at standard and full MVI levels.
217
+ * Errors and warnings grouped by file.
218
218
  * @public
219
219
  */
220
220
  interface CheckFileGroup {
@@ -225,6 +225,56 @@ interface CheckFileGroup {
225
225
  /** Warnings in this file. */
226
226
  warnings: CheckFileWarning[];
227
227
  }
228
+ /**
229
+ * Error breakdown by rule code, sorted by count descending.
230
+ * @public
231
+ */
232
+ interface CheckRuleCount {
233
+ /** Machine-readable rule code (e.g., "E001"). */
234
+ code: string;
235
+ /** Human-readable rule name (e.g., "require-summary"). */
236
+ rule: string;
237
+ /** Number of violations. */
238
+ count: number;
239
+ /** Number of unique files affected by this rule. */
240
+ files: number;
241
+ }
242
+ /**
243
+ * Triage data for prioritizing fixes.
244
+ * Always present when the check has errors, bounded in size (~9 rules + top 20 files).
245
+ * @public
246
+ */
247
+ interface CheckTriage {
248
+ /** Error counts by rule, sorted descending. */
249
+ byRule: CheckRuleCount[];
250
+ /** Top files by error count (max 20). */
251
+ topFiles: Array<{
252
+ file: string;
253
+ errors: number;
254
+ warnings: number;
255
+ }>;
256
+ /** Suggested fix order: rules sorted by fewest files affected first (quick wins). */
257
+ fixOrder: Array<{
258
+ code: string;
259
+ rule: string;
260
+ count: number;
261
+ files: number;
262
+ }>;
263
+ }
264
+ /**
265
+ * Pagination metadata for byFile results.
266
+ * @public
267
+ */
268
+ interface CheckPage {
269
+ /** Current offset. */
270
+ offset: number;
271
+ /** Page size. */
272
+ limit: number;
273
+ /** Whether more results exist beyond this page. */
274
+ hasMore: boolean;
275
+ /** Total number of file groups (after filters). */
276
+ total: number;
277
+ }
228
278
  /**
229
279
  * Typed result for the `check` command.
230
280
  * @public
@@ -245,8 +295,19 @@ interface CheckResult {
245
295
  /** Wall-clock duration in milliseconds. */
246
296
  duration: number;
247
297
  };
248
- /** Per-file breakdown — present at standard and full MVI levels. */
298
+ /** Triage data for prioritizing fixes — present when errors > 0 (except minimal). */
299
+ triage?: CheckTriage;
300
+ /** Per-file breakdown — present at standard and full MVI levels, paginated. */
249
301
  byFile?: CheckFileGroup[];
302
+ /** Pagination metadata when byFile is paginated. */
303
+ page?: CheckPage;
304
+ /** Active filters applied to this result. */
305
+ filters?: {
306
+ rule?: string;
307
+ file?: string;
308
+ };
309
+ /** CLI command hint for the agent to run next. */
310
+ nextCommand?: string;
250
311
  }
251
312
  /**
252
313
  * Citty command definition for `forge-ts check`.
@@ -267,6 +328,22 @@ declare const checkCommand: citty.CommandDef<{
267
328
  readonly description: "Show detailed output";
268
329
  readonly default: false;
269
330
  };
331
+ readonly rule: {
332
+ readonly type: "string";
333
+ readonly description: "Filter by rule code (e.g., E001, W004)";
334
+ };
335
+ readonly file: {
336
+ readonly type: "string";
337
+ readonly description: "Filter by file path (substring match)";
338
+ };
339
+ readonly limit: {
340
+ readonly type: "string";
341
+ readonly description: "Max file groups in output (default: 20)";
342
+ };
343
+ readonly offset: {
344
+ readonly type: "string";
345
+ readonly description: "Skip N file groups for pagination (default: 0)";
346
+ };
270
347
  readonly json: {
271
348
  readonly type: "boolean";
272
349
  readonly description: "Output as LAFS JSON envelope (agent-friendly)";
@@ -534,4 +611,4 @@ declare function createLogger(options?: {
534
611
  colors?: boolean;
535
612
  }): Logger;
536
613
 
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 };
614
+ export { type BuildResult, type BuildStep, type CheckFileError, type CheckFileGroup, type CheckFileWarning, type CheckPage, type CheckResult, type CheckRuleCount, type CheckTriage, 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
@@ -301,8 +301,66 @@ var buildCommand = defineCommand({
301
301
  import { loadConfig as loadConfig2 } from "@forge-ts/core";
302
302
  import { enforce } from "@forge-ts/enforcer";
303
303
  import { defineCommand as defineCommand2 } from "citty";
304
- function resolveAgentAction(_error) {
305
- return "retry_modified";
304
+ var RULE_NAMES = {
305
+ E001: "require-summary",
306
+ E002: "require-param",
307
+ E003: "require-returns",
308
+ E004: "require-example",
309
+ E005: "require-package-doc",
310
+ E006: "require-class-member-doc",
311
+ E007: "require-interface-member-doc",
312
+ E008: "require-link-target",
313
+ W004: "deprecated-cross-import"
314
+ };
315
+ function computeTriage(errors, warnings) {
316
+ const ruleMap = /* @__PURE__ */ new Map();
317
+ for (const e of errors) {
318
+ const entry = ruleMap.get(e.code) ?? { count: 0, files: /* @__PURE__ */ new Set() };
319
+ entry.count++;
320
+ entry.files.add(e.filePath);
321
+ ruleMap.set(e.code, entry);
322
+ }
323
+ for (const w of warnings) {
324
+ const entry = ruleMap.get(w.code) ?? { count: 0, files: /* @__PURE__ */ new Set() };
325
+ entry.count++;
326
+ entry.files.add(w.filePath);
327
+ ruleMap.set(w.code, entry);
328
+ }
329
+ const byRule = Array.from(ruleMap.entries()).map(([code, { count, files }]) => ({
330
+ code,
331
+ rule: RULE_NAMES[code] ?? code,
332
+ count,
333
+ files: files.size
334
+ })).sort((a, b) => b.count - a.count);
335
+ const fileMap = /* @__PURE__ */ new Map();
336
+ for (const e of errors) {
337
+ const entry = fileMap.get(e.filePath) ?? { errors: 0, warnings: 0 };
338
+ entry.errors++;
339
+ fileMap.set(e.filePath, entry);
340
+ }
341
+ for (const w of warnings) {
342
+ const entry = fileMap.get(w.filePath) ?? { errors: 0, warnings: 0 };
343
+ entry.warnings++;
344
+ fileMap.set(w.filePath, entry);
345
+ }
346
+ const topFiles = Array.from(fileMap.entries()).map(([file, counts]) => ({ file, ...counts })).sort((a, b) => b.errors - a.errors || a.file.localeCompare(b.file)).slice(0, 20);
347
+ const fixOrder = [...byRule].sort((a, b) => a.files - b.files || b.count - a.count);
348
+ return { byRule, topFiles, fixOrder };
349
+ }
350
+ function applyFilters(errors, warnings, filters) {
351
+ let filteredErrors = errors;
352
+ let filteredWarnings = warnings;
353
+ if (filters.rule) {
354
+ const r = filters.rule.toUpperCase();
355
+ filteredErrors = filteredErrors.filter((e) => e.code === r);
356
+ filteredWarnings = filteredWarnings.filter((w) => w.code === r);
357
+ }
358
+ if (filters.file) {
359
+ const f = filters.file;
360
+ filteredErrors = filteredErrors.filter((e) => e.filePath.includes(f));
361
+ filteredWarnings = filteredWarnings.filter((w) => w.filePath.includes(f));
362
+ }
363
+ return { errors: filteredErrors, warnings: filteredWarnings };
306
364
  }
307
365
  function groupByFile(errors, warnings, includeFix) {
308
366
  const fileMap = /* @__PURE__ */ new Map();
@@ -318,11 +376,9 @@ function groupByFile(errors, warnings, includeFix) {
318
376
  line: e.line,
319
377
  message: e.message
320
378
  };
321
- if (includeFix) {
322
- if (e.suggestedFix !== void 0) {
323
- entry.suggestedFix = e.suggestedFix;
324
- }
325
- entry.agentAction = resolveAgentAction(e);
379
+ if (includeFix && e.suggestedFix !== void 0) {
380
+ entry.suggestedFix = e.suggestedFix;
381
+ entry.agentAction = "retry_modified";
326
382
  }
327
383
  fileMap.get(fp)?.errors.push(entry);
328
384
  }
@@ -339,9 +395,25 @@ function groupByFile(errors, warnings, includeFix) {
339
395
  message: w.message
340
396
  });
341
397
  }
342
- return Array.from(fileMap.values());
398
+ return Array.from(fileMap.values()).sort(
399
+ (a, b) => b.errors.length - a.errors.length || a.file.localeCompare(b.file)
400
+ );
401
+ }
402
+ function computeNextCommand(triage, filters, page, hasFilters) {
403
+ if (page?.hasMore) {
404
+ const parts = ["forge-ts check --mvi full"];
405
+ if (filters.rule) parts.push(`--rule ${filters.rule}`);
406
+ if (filters.file) parts.push(`--file "${filters.file}"`);
407
+ parts.push(`--limit ${page.limit} --offset ${page.offset + page.limit}`);
408
+ return parts.join(" ");
409
+ }
410
+ if (!hasFilters && triage.fixOrder.length > 0) {
411
+ const quickWin = triage.fixOrder[0];
412
+ return `forge-ts check --rule ${quickWin.code} --mvi full`;
413
+ }
414
+ return "forge-ts check --mvi minimal";
343
415
  }
344
- function buildCheckResult(rawErrors, rawWarnings, _symbolCount, exportedSymbolCount, duration, success, mviLevel) {
416
+ function buildCheckResult(rawErrors, rawWarnings, exportedSymbolCount, duration, success, mviLevel, filters, limit, offset) {
345
417
  const uniqueFiles = /* @__PURE__ */ new Set([
346
418
  ...rawErrors.map((e) => e.filePath),
347
419
  ...rawWarnings.map((w) => w.filePath)
@@ -356,8 +428,31 @@ function buildCheckResult(rawErrors, rawWarnings, _symbolCount, exportedSymbolCo
356
428
  if (mviLevel === "minimal") {
357
429
  return { success, summary };
358
430
  }
359
- const byFile = groupByFile(rawErrors, rawWarnings, mviLevel !== "minimal");
360
- return { success, summary, byFile };
431
+ const triage = rawErrors.length > 0 || rawWarnings.length > 0 ? computeTriage(rawErrors, rawWarnings) : void 0;
432
+ const hasFilters = !!(filters.rule || filters.file);
433
+ const { errors: filteredErrors, warnings: filteredWarnings } = hasFilters ? applyFilters(rawErrors, rawWarnings, filters) : { errors: rawErrors, warnings: rawWarnings };
434
+ const includeFix = mviLevel === "full" || hasFilters;
435
+ const allGroups = groupByFile(filteredErrors, filteredWarnings, includeFix);
436
+ const total = allGroups.length;
437
+ const pagedGroups = allGroups.slice(offset, offset + limit);
438
+ const hasMore = offset + limit < total;
439
+ const page = { offset, limit, hasMore, total };
440
+ const nextCommand = triage ? computeNextCommand(triage, filters, page, hasFilters) : void 0;
441
+ const result = {
442
+ success,
443
+ summary,
444
+ triage,
445
+ byFile: pagedGroups,
446
+ page,
447
+ nextCommand
448
+ };
449
+ if (hasFilters) {
450
+ result.filters = {
451
+ rule: filters.rule || void 0,
452
+ file: filters.file || void 0
453
+ };
454
+ }
455
+ return result;
361
456
  }
362
457
  async function runCheck(args) {
363
458
  const config = await loadConfig2(args.cwd);
@@ -365,16 +460,21 @@ async function runCheck(args) {
365
460
  config.enforce.strict = args.strict;
366
461
  }
367
462
  const result = await enforce(config);
368
- const mviLevel = args.mvi ?? "full";
463
+ const mviLevel = args.mvi ?? "standard";
464
+ const limit = args.limit ?? 20;
465
+ const offset = args.offset ?? 0;
466
+ const filters = { rule: args.rule, file: args.file };
369
467
  const exportedSymbolCount = result.symbols.filter((s) => s.exported).length;
370
468
  const data = buildCheckResult(
371
469
  result.errors,
372
470
  result.warnings,
373
- result.symbols.length,
374
471
  exportedSymbolCount,
375
472
  result.duration,
376
473
  result.success,
377
- mviLevel
474
+ mviLevel,
475
+ filters,
476
+ limit,
477
+ offset
378
478
  );
379
479
  const cliErrors = result.success ? void 0 : [
380
480
  {
@@ -411,6 +511,27 @@ function formatCheckHuman(result) {
411
511
  ` ${result.summary.errors} error(s), ${result.summary.warnings} warning(s) across ${result.summary.files} file(s) (${result.summary.symbols} symbols checked)
412
512
  `
413
513
  );
514
+ if (result.triage) {
515
+ lines.push(" Rules:");
516
+ for (const r of result.triage.byRule) {
517
+ lines.push(` ${r.code} ${r.rule}: ${r.count} violation(s) in ${r.files} file(s)`);
518
+ }
519
+ lines.push("");
520
+ if (result.triage.fixOrder.length > 0) {
521
+ const qw = result.triage.fixOrder[0];
522
+ lines.push(
523
+ ` Quick win: fix ${qw.code} (${qw.rule}) \u2014 ${qw.count} issue(s) in ${qw.files} file(s)`
524
+ );
525
+ lines.push("");
526
+ }
527
+ }
528
+ if (result.filters) {
529
+ const parts = [];
530
+ if (result.filters.rule) parts.push(`rule=${result.filters.rule}`);
531
+ if (result.filters.file) parts.push(`file=${result.filters.file}`);
532
+ lines.push(` Filtered: ${parts.join(", ")}`);
533
+ lines.push("");
534
+ }
414
535
  if (result.byFile && result.byFile.length > 0) {
415
536
  for (const group of result.byFile) {
416
537
  if (group.errors.length > 0) {
@@ -433,6 +554,16 @@ function formatCheckHuman(result) {
433
554
  }
434
555
  }
435
556
  }
557
+ if (result.page && result.page.hasMore) {
558
+ lines.push(
559
+ `
560
+ Showing ${result.page.offset + 1}-${result.page.offset + (result.byFile?.length ?? 0)} of ${result.page.total} file(s). Use --offset ${result.page.offset + result.page.limit} to see more.`
561
+ );
562
+ }
563
+ if (result.nextCommand) {
564
+ lines.push(`
565
+ Next: ${result.nextCommand}`);
566
+ }
436
567
  return lines.join("\n");
437
568
  }
438
569
  var checkCommand = defineCommand2({
@@ -455,6 +586,22 @@ var checkCommand = defineCommand2({
455
586
  description: "Show detailed output",
456
587
  default: false
457
588
  },
589
+ rule: {
590
+ type: "string",
591
+ description: "Filter by rule code (e.g., E001, W004)"
592
+ },
593
+ file: {
594
+ type: "string",
595
+ description: "Filter by file path (substring match)"
596
+ },
597
+ limit: {
598
+ type: "string",
599
+ description: "Max file groups in output (default: 20)"
600
+ },
601
+ offset: {
602
+ type: "string",
603
+ description: "Skip N file groups for pagination (default: 0)"
604
+ },
458
605
  json: {
459
606
  type: "boolean",
460
607
  description: "Output as LAFS JSON envelope (agent-friendly)",
@@ -480,7 +627,11 @@ var checkCommand = defineCommand2({
480
627
  cwd: args.cwd,
481
628
  strict: args.strict,
482
629
  verbose: args.verbose,
483
- mvi: args.mvi
630
+ mvi: args.mvi,
631
+ rule: args.rule,
632
+ file: args.file,
633
+ limit: args.limit ? parseInt(args.limit, 10) : void 0,
634
+ offset: args.offset ? parseInt(args.offset, 10) : void 0
484
635
  });
485
636
  const flags = {
486
637
  json: args.json,
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/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 { 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\tif (result.writtenFiles) {\n\t\t\t\tgeneratedFiles.push(...result.writtenFiles);\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\tconst cliWarnings = config._configWarnings?.map((msg) => ({\n\t\tcode: \"CONFIG_WARNING\",\n\t\tmessage: msg,\n\t\tfilePath: \"\",\n\t\tline: 0,\n\t\tcolumn: 0,\n\t}));\n\n\treturn {\n\t\toperation: \"build\",\n\t\tsuccess,\n\t\tdata,\n\t\terrors: allErrors,\n\t\twarnings: cliWarnings,\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// Include warnings in the result so agents see them in the JSON envelope.\n\t// Config warnings (unknown keys, invalid rules) go to stderr for TTY\n\t// consumers but agents in non-TTY contexts only see the JSON envelope.\n\tconst resultData = output.data as Record<string, unknown>;\n\tif (output.warnings && output.warnings.length > 0) {\n\t\tresultData._warnings = output.warnings.map((w) => ({\n\t\t\tcode: w.code,\n\t\t\tmessage: w.message,\n\t\t}));\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: resultData,\n\t\t\t\tmeta,\n\t\t\t})\n\t\t: createEnvelope({\n\t\t\t\tsuccess: false,\n\t\t\t\tresult: resultData,\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\t// Surface config warnings so agents see them in the JSON envelope\n\tconst cliWarnings = config._configWarnings?.map((msg) => ({\n\t\tcode: \"CONFIG_WARNING\",\n\t\tmessage: msg,\n\t\tfilePath: \"\",\n\t\tline: 0,\n\t\tcolumn: 0,\n\t}));\n\n\treturn {\n\t\toperation: \"check\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: cliErrors,\n\t\twarnings: cliWarnings,\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: \"init\",\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\tconst cliWarnings = config._configWarnings?.map((msg) => ({\n\t\tcode: \"CONFIG_WARNING\",\n\t\tmessage: msg,\n\t\tfilePath: \"\",\n\t\tline: 0,\n\t\tcolumn: 0,\n\t}));\n\n\treturn {\n\t\toperation: \"test\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: cliErrors,\n\t\twarnings: cliWarnings,\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","resolve","loadConfig","DEFAULT_TARGET","getAdapter","defineCommand","DEFAULT_TARGET","getAdapter","loadConfig","resolve","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand","require","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 CheckPage,\n\ttype CheckResult,\n\ttype CheckRuleCount,\n\ttype CheckTriage,\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 { 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\tif (result.writtenFiles) {\n\t\t\t\tgeneratedFiles.push(...result.writtenFiles);\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\tconst cliWarnings = config._configWarnings?.map((msg) => ({\n\t\tcode: \"CONFIG_WARNING\",\n\t\tmessage: msg,\n\t\tfilePath: \"\",\n\t\tline: 0,\n\t\tcolumn: 0,\n\t}));\n\n\treturn {\n\t\toperation: \"build\",\n\t\tsuccess,\n\t\tdata,\n\t\terrors: allErrors,\n\t\twarnings: cliWarnings,\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// Include warnings in the result so agents see them in the JSON envelope.\n\t// Config warnings (unknown keys, invalid rules) go to stderr for TTY\n\t// consumers but agents in non-TTY contexts only see the JSON envelope.\n\tconst resultData = output.data as Record<string, unknown>;\n\tif (output.warnings && output.warnings.length > 0) {\n\t\tresultData._warnings = output.warnings.map((w) => ({\n\t\t\tcode: w.code,\n\t\t\tmessage: w.message,\n\t\t}));\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: resultData,\n\t\t\t\tmeta,\n\t\t\t})\n\t\t: createEnvelope({\n\t\t\t\tsuccess: false,\n\t\t\t\tresult: resultData,\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\t/** Filter errors to a specific rule code (e.g., \"E001\"). */\n\trule?: string;\n\t/** Filter errors to a specific file path (substring match). */\n\tfile?: string;\n\t/** Maximum number of file groups to return in byFile (default: 20). */\n\tlimit?: number;\n\t/** Offset into the byFile list for pagination (default: 0). */\n\toffset?: number;\n}\n\n/**\n * A single error entry within a file group.\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 (present at full MVI or with --rule/--file filters). */\n\tsuggestedFix?: string;\n\t/** Recommended agent action. */\n\tagentAction?: string;\n}\n\n/**\n * A single warning entry within a file group.\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.\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 * Error breakdown by rule code, sorted by count descending.\n * @public\n */\nexport interface CheckRuleCount {\n\t/** Machine-readable rule code (e.g., \"E001\"). */\n\tcode: string;\n\t/** Human-readable rule name (e.g., \"require-summary\"). */\n\trule: string;\n\t/** Number of violations. */\n\tcount: number;\n\t/** Number of unique files affected by this rule. */\n\tfiles: number;\n}\n\n/**\n * Triage data for prioritizing fixes.\n * Always present when the check has errors, bounded in size (~9 rules + top 20 files).\n * @public\n */\nexport interface CheckTriage {\n\t/** Error counts by rule, sorted descending. */\n\tbyRule: CheckRuleCount[];\n\t/** Top files by error count (max 20). */\n\ttopFiles: Array<{ file: string; errors: number; warnings: number }>;\n\t/** Suggested fix order: rules sorted by fewest files affected first (quick wins). */\n\tfixOrder: Array<{ code: string; rule: string; count: number; files: number }>;\n}\n\n/**\n * Pagination metadata for byFile results.\n * @public\n */\nexport interface CheckPage {\n\t/** Current offset. */\n\toffset: number;\n\t/** Page size. */\n\tlimit: number;\n\t/** Whether more results exist beyond this page. */\n\thasMore: boolean;\n\t/** Total number of file groups (after filters). */\n\ttotal: number;\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/** Triage data for prioritizing fixes — present when errors > 0 (except minimal). */\n\ttriage?: CheckTriage;\n\t/** Per-file breakdown — present at standard and full MVI levels, paginated. */\n\tbyFile?: CheckFileGroup[];\n\t/** Pagination metadata when byFile is paginated. */\n\tpage?: CheckPage;\n\t/** Active filters applied to this result. */\n\tfilters?: { rule?: string; file?: string };\n\t/** CLI command hint for the agent to run next. */\n\tnextCommand?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Rule code → name mapping\n// ---------------------------------------------------------------------------\n\nconst RULE_NAMES: Record<string, string> = {\n\tE001: \"require-summary\",\n\tE002: \"require-param\",\n\tE003: \"require-returns\",\n\tE004: \"require-example\",\n\tE005: \"require-package-doc\",\n\tE006: \"require-class-member-doc\",\n\tE007: \"require-interface-member-doc\",\n\tE008: \"require-link-target\",\n\tW004: \"deprecated-cross-import\",\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Computes triage data from the full (unfiltered) error/warning set.\n * Bounded output: max 9 rules + top 20 files.\n * @internal\n */\nfunction computeTriage(errors: ForgeError[], warnings: ForgeWarning[]): CheckTriage {\n\t// byRule: count per code with file count\n\tconst ruleMap = new Map<string, { count: number; files: Set<string> }>();\n\tfor (const e of errors) {\n\t\tconst entry = ruleMap.get(e.code) ?? { count: 0, files: new Set<string>() };\n\t\tentry.count++;\n\t\tentry.files.add(e.filePath);\n\t\truleMap.set(e.code, entry);\n\t}\n\tfor (const w of warnings) {\n\t\tconst entry = ruleMap.get(w.code) ?? { count: 0, files: new Set<string>() };\n\t\tentry.count++;\n\t\tentry.files.add(w.filePath);\n\t\truleMap.set(w.code, entry);\n\t}\n\n\tconst byRule: CheckRuleCount[] = Array.from(ruleMap.entries())\n\t\t.map(([code, { count, files }]) => ({\n\t\t\tcode,\n\t\t\trule: RULE_NAMES[code] ?? code,\n\t\t\tcount,\n\t\t\tfiles: files.size,\n\t\t}))\n\t\t.sort((a, b) => b.count - a.count);\n\n\t// topFiles: count errors/warnings per file, top 20\n\tconst fileMap = new Map<string, { errors: number; warnings: number }>();\n\tfor (const e of errors) {\n\t\tconst entry = fileMap.get(e.filePath) ?? { errors: 0, warnings: 0 };\n\t\tentry.errors++;\n\t\tfileMap.set(e.filePath, entry);\n\t}\n\tfor (const w of warnings) {\n\t\tconst entry = fileMap.get(w.filePath) ?? { errors: 0, warnings: 0 };\n\t\tentry.warnings++;\n\t\tfileMap.set(w.filePath, entry);\n\t}\n\tconst topFiles = Array.from(fileMap.entries())\n\t\t.map(([file, counts]) => ({ file, ...counts }))\n\t\t.sort((a, b) => b.errors - a.errors || a.file.localeCompare(b.file))\n\t\t.slice(0, 20);\n\n\t// fixOrder: rules sorted by fewest files (quick wins first)\n\tconst fixOrder = [...byRule].sort((a, b) => a.files - b.files || b.count - a.count);\n\n\treturn { byRule, topFiles, fixOrder };\n}\n\n/**\n * Filters errors/warnings by rule code and/or file path substring.\n * @internal\n */\nfunction applyFilters(\n\terrors: ForgeError[],\n\twarnings: ForgeWarning[],\n\tfilters: { rule?: string; file?: string },\n): { errors: ForgeError[]; warnings: ForgeWarning[] } {\n\tlet filteredErrors = errors;\n\tlet filteredWarnings = warnings;\n\n\tif (filters.rule) {\n\t\tconst r = filters.rule.toUpperCase();\n\t\tfilteredErrors = filteredErrors.filter((e) => e.code === r);\n\t\tfilteredWarnings = filteredWarnings.filter((w) => w.code === r);\n\t}\n\tif (filters.file) {\n\t\tconst f = filters.file;\n\t\tfilteredErrors = filteredErrors.filter((e) => e.filePath.includes(f));\n\t\tfilteredWarnings = filteredWarnings.filter((w) => w.filePath.includes(f));\n\t}\n\n\treturn { errors: filteredErrors, warnings: filteredWarnings };\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 && e.suggestedFix !== undefined) {\n\t\t\tentry.suggestedFix = e.suggestedFix;\n\t\t\tentry.agentAction = \"retry_modified\";\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\t// Deterministic sort: most errors first, then lexicographic path\n\treturn Array.from(fileMap.values()).sort(\n\t\t(a, b) => b.errors.length - a.errors.length || a.file.localeCompare(b.file),\n\t);\n}\n\n/**\n * Computes the next CLI command hint for the agent.\n * @internal\n */\nfunction computeNextCommand(\n\ttriage: CheckTriage,\n\tfilters: { rule?: string; file?: string },\n\tpage: CheckPage | undefined,\n\thasFilters: boolean,\n): string {\n\t// If paginated and has more, suggest next page\n\tif (page?.hasMore) {\n\t\tconst parts = [\"forge-ts check --mvi full\"];\n\t\tif (filters.rule) parts.push(`--rule ${filters.rule}`);\n\t\tif (filters.file) parts.push(`--file \"${filters.file}\"`);\n\t\tparts.push(`--limit ${page.limit} --offset ${page.offset + page.limit}`);\n\t\treturn parts.join(\" \");\n\t}\n\n\t// If no filters yet, suggest drilling into the quickest-win rule\n\tif (!hasFilters && triage.fixOrder.length > 0) {\n\t\tconst quickWin = triage.fixOrder[0];\n\t\treturn `forge-ts check --rule ${quickWin.code} --mvi full`;\n\t}\n\n\t// If filtered by rule, suggest re-checking after fixes\n\treturn \"forge-ts check --mvi minimal\";\n}\n\n/**\n * Builds a CheckResult with triage, filtering, pagination, and MVI differentiation.\n * @internal\n */\nfunction buildCheckResult(\n\trawErrors: ForgeError[],\n\trawWarnings: ForgeWarning[],\n\texportedSymbolCount: number,\n\tduration: number,\n\tsuccess: boolean,\n\tmviLevel: string,\n\tfilters: { rule?: string; file?: string },\n\tlimit: number,\n\toffset: number,\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// Triage: always computed from FULL unfiltered data (bounded by rule count + top 20)\n\tconst triage =\n\t\trawErrors.length > 0 || rawWarnings.length > 0\n\t\t\t? computeTriage(rawErrors, rawWarnings)\n\t\t\t: undefined;\n\n\t// Apply filters\n\tconst hasFilters = !!(filters.rule || filters.file);\n\tconst { errors: filteredErrors, warnings: filteredWarnings } = hasFilters\n\t\t? applyFilters(rawErrors, rawWarnings, filters)\n\t\t: { errors: rawErrors, warnings: rawWarnings };\n\n\t// Include suggestedFix at full MVI or when filters are active (targeted drill-down)\n\tconst includeFix = mviLevel === \"full\" || hasFilters;\n\n\t// Group and paginate\n\tconst allGroups = groupByFile(filteredErrors, filteredWarnings, includeFix);\n\tconst total = allGroups.length;\n\tconst pagedGroups = allGroups.slice(offset, offset + limit);\n\tconst hasMore = offset + limit < total;\n\n\tconst page: CheckPage = { offset, limit, hasMore, total };\n\n\tconst nextCommand = triage ? computeNextCommand(triage, filters, page, hasFilters) : undefined;\n\n\tconst result: CheckResult = {\n\t\tsuccess,\n\t\tsummary,\n\t\ttriage,\n\t\tbyFile: pagedGroups,\n\t\tpage,\n\t\tnextCommand,\n\t};\n\n\tif (hasFilters) {\n\t\tresult.filters = {\n\t\t\trule: filters.rule || undefined,\n\t\t\tfile: filters.file || undefined,\n\t\t};\n\t}\n\n\treturn result;\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 \"standard\" MVI — gives triage + paginated overview.\n\t// Agents drill into specific rules/files with --mvi full.\n\tconst mviLevel = args.mvi ?? \"standard\";\n\tconst limit = args.limit ?? 20;\n\tconst offset = args.offset ?? 0;\n\tconst filters = { rule: args.rule, file: args.file };\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\texportedSymbolCount,\n\t\tresult.duration,\n\t\tresult.success,\n\t\tmviLevel,\n\t\tfilters,\n\t\tlimit,\n\t\toffset,\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\t// Surface config warnings so agents see them in the JSON envelope\n\tconst cliWarnings = config._configWarnings?.map((msg) => ({\n\t\tcode: \"CONFIG_WARNING\",\n\t\tmessage: msg,\n\t\tfilePath: \"\",\n\t\tline: 0,\n\t\tcolumn: 0,\n\t}));\n\n\treturn {\n\t\toperation: \"check\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: cliErrors,\n\t\twarnings: cliWarnings,\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 * @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\t// Triage: rule breakdown\n\tif (result.triage) {\n\t\tlines.push(\" Rules:\");\n\t\tfor (const r of result.triage.byRule) {\n\t\t\tlines.push(` ${r.code} ${r.rule}: ${r.count} violation(s) in ${r.files} file(s)`);\n\t\t}\n\t\tlines.push(\"\");\n\n\t\tif (result.triage.fixOrder.length > 0) {\n\t\t\tconst qw = result.triage.fixOrder[0];\n\t\t\tlines.push(\n\t\t\t\t` Quick win: fix ${qw.code} (${qw.rule}) — ${qw.count} issue(s) in ${qw.files} file(s)`,\n\t\t\t);\n\t\t\tlines.push(\"\");\n\t\t}\n\t}\n\n\t// Active filters\n\tif (result.filters) {\n\t\tconst parts = [];\n\t\tif (result.filters.rule) parts.push(`rule=${result.filters.rule}`);\n\t\tif (result.filters.file) parts.push(`file=${result.filters.file}`);\n\t\tlines.push(` Filtered: ${parts.join(\", \")}`);\n\t\tlines.push(\"\");\n\t}\n\n\t// Per-file errors\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\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\t// Pagination footer\n\tif (result.page && result.page.hasMore) {\n\t\tlines.push(\n\t\t\t`\\n Showing ${result.page.offset + 1}-${result.page.offset + (result.byFile?.length ?? 0)} of ${result.page.total} file(s). Use --offset ${result.page.offset + result.page.limit} to see more.`,\n\t\t);\n\t}\n\n\t// Next command hint\n\tif (result.nextCommand) {\n\t\tlines.push(`\\n Next: ${result.nextCommand}`);\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\trule: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Filter by rule code (e.g., E001, W004)\",\n\t\t},\n\t\tfile: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Filter by file path (substring match)\",\n\t\t},\n\t\tlimit: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Max file groups in output (default: 20)\",\n\t\t},\n\t\toffset: {\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Skip N file groups for pagination (default: 0)\",\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\trule: args.rule,\n\t\t\tfile: args.file,\n\t\t\tlimit: args.limit ? parseInt(args.limit, 10) : undefined,\n\t\t\toffset: args.offset ? parseInt(args.offset, 10) : undefined,\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: \"init\",\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\tconst cliWarnings = config._configWarnings?.map((msg) => ({\n\t\tcode: \"CONFIG_WARNING\",\n\t\tmessage: msg,\n\t\tfilePath: \"\",\n\t\tline: 0,\n\t\tcolumn: 0,\n\t}));\n\n\treturn {\n\t\toperation: \"test\",\n\t\tsuccess: result.success,\n\t\tdata,\n\t\terrors: cliErrors,\n\t\twarnings: cliWarnings,\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","resolve","loadConfig","DEFAULT_TARGET","getAdapter","defineCommand","DEFAULT_TARGET","getAdapter","loadConfig","resolve","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.6.6",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "description": "CLI entry point for forge-ts",
6
6
  "license": "MIT",
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@cleocode/lafs-protocol": "^1.8.0",
31
31
  "citty": "^0.2.1",
32
- "@forge-ts/api": "0.6.6",
33
- "@forge-ts/core": "0.6.6",
34
- "@forge-ts/doctest": "0.6.6",
35
- "@forge-ts/gen": "0.6.6",
36
- "@forge-ts/enforcer": "0.6.6"
32
+ "@forge-ts/api": "0.7.0",
33
+ "@forge-ts/core": "0.7.0",
34
+ "@forge-ts/doctest": "0.7.0",
35
+ "@forge-ts/enforcer": "0.7.0",
36
+ "@forge-ts/gen": "0.7.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "tsup": "^8.3.5",