frontend-harness 0.7.10 → 0.8.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.
Files changed (68) hide show
  1. package/README.md +17 -10
  2. package/dist/cli/index.js +368 -65
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/runtime/builtin-skills.js +1 -1
  5. package/dist/runtime/clean.js +1 -0
  6. package/dist/runtime/clean.js.map +1 -1
  7. package/dist/runtime/command-taxonomy.js +6 -1
  8. package/dist/runtime/command-taxonomy.js.map +1 -1
  9. package/dist/runtime/context.d.ts +33 -2
  10. package/dist/runtime/context.js +63 -8
  11. package/dist/runtime/context.js.map +1 -1
  12. package/dist/runtime/evidence.d.ts +27 -0
  13. package/dist/runtime/evidence.js +240 -12
  14. package/dist/runtime/evidence.js.map +1 -1
  15. package/dist/runtime/ingest.d.ts +38 -0
  16. package/dist/runtime/ingest.js +157 -0
  17. package/dist/runtime/ingest.js.map +1 -0
  18. package/dist/runtime/knowledge/constants.js +1 -0
  19. package/dist/runtime/knowledge/constants.js.map +1 -1
  20. package/dist/runtime/knowledge/core.d.ts +7 -1
  21. package/dist/runtime/knowledge/core.js +329 -24
  22. package/dist/runtime/knowledge/core.js.map +1 -1
  23. package/dist/runtime/knowledge/types.d.ts +70 -1
  24. package/dist/runtime/knowledge.d.ts +2 -2
  25. package/dist/runtime/knowledge.js +1 -1
  26. package/dist/runtime/knowledge.js.map +1 -1
  27. package/dist/runtime/plan/guidance.d.ts +1 -1
  28. package/dist/runtime/plan/guidance.js +88 -25
  29. package/dist/runtime/plan/guidance.js.map +1 -1
  30. package/dist/runtime/plan/workflow.d.ts +1 -0
  31. package/dist/runtime/plan/workflow.js +32 -1
  32. package/dist/runtime/plan/workflow.js.map +1 -1
  33. package/dist/runtime/plan.d.ts +13 -0
  34. package/dist/runtime/plan.js +132 -79
  35. package/dist/runtime/plan.js.map +1 -1
  36. package/dist/runtime/policy-provenance.d.ts +17 -1
  37. package/dist/runtime/policy-provenance.js +42 -12
  38. package/dist/runtime/policy-provenance.js.map +1 -1
  39. package/dist/runtime/protocol-init.js +12 -7
  40. package/dist/runtime/protocol-init.js.map +1 -1
  41. package/dist/runtime/repair-packet.js +86 -4
  42. package/dist/runtime/repair-packet.js.map +1 -1
  43. package/dist/runtime/skills.d.ts +9 -0
  44. package/dist/runtime/skills.js +13 -0
  45. package/dist/runtime/skills.js.map +1 -1
  46. package/dist/runtime/state-explain.js +39 -7
  47. package/dist/runtime/state-explain.js.map +1 -1
  48. package/dist/runtime/state.js +36 -2
  49. package/dist/runtime/state.js.map +1 -1
  50. package/dist/runtime/task-context.d.ts +122 -0
  51. package/dist/runtime/task-context.js +1322 -0
  52. package/dist/runtime/task-context.js.map +1 -0
  53. package/dist/runtime/task-signals.d.ts +1 -0
  54. package/dist/runtime/task-signals.js +1 -1
  55. package/dist/runtime/task-signals.js.map +1 -1
  56. package/dist/runtime/ui-restoration.d.ts +3 -3
  57. package/dist/runtime/ui-restoration.js +3 -3
  58. package/dist/runtime/ui-restoration.js.map +1 -1
  59. package/dist/runtime/ui-source.d.ts +6 -0
  60. package/dist/runtime/ui-source.js +66 -0
  61. package/dist/runtime/ui-source.js.map +1 -0
  62. package/dist/runtime/verify.js +65 -25
  63. package/dist/runtime/verify.js.map +1 -1
  64. package/dist/schemas/types.d.ts +75 -2
  65. package/dist/schemas/validation.js +42 -7
  66. package/dist/schemas/validation.js.map +1 -1
  67. package/docs/DIRECTION.md +13 -11
  68. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { buildContext } from "../runtime/context.js";
3
3
  import { checkComponentGraph } from "../runtime/graph.js";
4
- import { addKnowledge, checkKnowledge, checkKnowledgeCoverage, createModuleKnowledge, indexKnowledge, listKnowledge, promoteKnowledge, searchKnowledge, showKnowledge, updateKnowledge } from "../runtime/knowledge.js";
4
+ import { addKnowledge, checkKnowledge, checkKnowledgeCoverage, createModuleKnowledge, draftKnowledgeFromIngest, indexKnowledge, listKnowledge, promoteKnowledge, searchKnowledge, showKnowledge, updateKnowledge } from "../runtime/knowledge.js";
5
5
  import { checkAgentPlanningProposal, createPlan } from "../runtime/plan.js";
6
6
  import { publicHelpLines } from "../runtime/command-taxonomy.js";
7
7
  import { cleanRuntimeArtifacts } from "../runtime/clean.js";
@@ -10,12 +10,15 @@ import { createRepairPacket } from "../runtime/repair-packet.js";
10
10
  import { isScaffoldPresetName, scaffoldProject } from "../runtime/scaffold.js";
11
11
  import { explainState } from "../runtime/state-explain.js";
12
12
  import { checkProtocol, initializeProtocol } from "../runtime/protocol-init.js";
13
- import { checkSkills, discoverSkills } from "../runtime/skills.js";
13
+ import { checkSkills, listSkills } from "../runtime/skills.js";
14
14
  import { changedFilesFromGit, checkStateContract, getNextAction, loadState, recordChangedFiles } from "../runtime/state.js";
15
15
  import { checkExecutionUnits } from "../runtime/units.js";
16
+ import { listIngestRecords, recordIngestSource, showIngestRecord } from "../runtime/ingest.js";
17
+ import { buildCompactTaskContext } from "../runtime/task-context.js";
16
18
  import { assertDesignSourceReadyForProjectChanges, createEvidenceTemplate, recordEvidence } from "../runtime/evidence.js";
17
19
  import { runVerification } from "../runtime/verify.js";
18
20
  import { compareVisualArtifacts } from "../runtime/visual-compare.js";
21
+ const MAX_HUMAN_VERIFICATION_RESULTS = 10;
19
22
  const COMMAND_HELP = {
20
23
  init: [
21
24
  "Usage:",
@@ -30,7 +33,18 @@ const COMMAND_HELP = {
30
33
  ],
31
34
  context: [
32
35
  "Usage:",
33
- " frontend-harness context --json"
36
+ " frontend-harness context --json",
37
+ " frontend-harness context task --json \"<task>\" [--prd <prd-file>] [--api-source <openapi-file-or-url>] [--ui-source <ui-artifact-or-design-url>] [--limit <count>]",
38
+ "",
39
+ "`context task` builds a compact task packet from workflow policy, knowledge cards, and ingest provenance."
40
+ ],
41
+ ingest: [
42
+ "Usage:",
43
+ " frontend-harness ingest record --json --kind prd|openapi|ui-package --id <source-id> --source <file-or-url> --summary \"<summary>\" [--cards <ids>]",
44
+ " frontend-harness ingest list --json [--kind prd|openapi|ui-package]",
45
+ " frontend-harness ingest show --json --ref ingest://<kind>/<source-id>",
46
+ "",
47
+ "Records lightweight provenance for temporary PRD, OpenAPI, or UI package inputs."
34
48
  ],
35
49
  clean: [
36
50
  "Usage:",
@@ -43,10 +57,11 @@ const COMMAND_HELP = {
43
57
  ],
44
58
  plan: [
45
59
  "Usage:",
46
- " frontend-harness plan --json \"<task>\" [--prd <prd-file>] [--ui-source <ui-artifact-or-design-url>] [--agent-proposal <agent-proposal.json>]",
60
+ " frontend-harness plan --json \"<task>\" [--prd <prd-file>] [--api-source <openapi-file-or-url>] [--ui-source <ui-artifact-or-design-url>] [--agent-proposal <agent-proposal.json>]",
47
61
  "",
48
62
  "Flags:",
49
63
  " --prd <file> Project-relative PRD or requirement source.",
64
+ " --api-source <path-or-url> OpenAPI/Swagger source file or URL.",
50
65
  " --ui-source <path-or-url> UI source artifact or supported design URL.",
51
66
  " --agent-proposal <json-file> Bounded planning proposal envelope.",
52
67
  " --json Print machine-readable output."
@@ -112,6 +127,7 @@ const COMMAND_HELP = {
112
127
  knowledge: [
113
128
  "Usage:",
114
129
  " frontend-harness knowledge add --json --kind <kind> --subject \"<subject>\" <content-flag>",
130
+ " frontend-harness knowledge draft --json --ref ingest://<kind>/<source-id>",
115
131
  " frontend-harness knowledge module --json --id <id> --title \"<title>\" --summary \"<summary>\" --body \"<body>\"",
116
132
  " frontend-harness knowledge update --json --id <knowledge-id> [metadata flags]",
117
133
  " frontend-harness knowledge index --json",
@@ -147,6 +163,13 @@ const COMMAND_HELP = {
147
163
  " --status active|deprecated",
148
164
  " --stability stable|evolving"
149
165
  ],
166
+ "knowledge draft": [
167
+ "Usage:",
168
+ " frontend-harness knowledge draft --json --ref ingest://<kind>/<source-id>",
169
+ "",
170
+ "Builds a knowledge add scaffold from recorded ingest provenance.",
171
+ "Review the summary and replace placeholder content, coverage, verification, scope, and tags before adding durable knowledge."
172
+ ],
150
173
  "knowledge module": [
151
174
  "Usage:",
152
175
  " frontend-harness knowledge module --json --id <kebab-id> --title \"<title>\" --summary \"<summary>\" --body \"<body>\" [traceability flags]",
@@ -254,7 +277,10 @@ async function main() {
254
277
  }
255
278
  return;
256
279
  case "context":
257
- output(buildContext(projectRoot), parsed.json);
280
+ handleContext(projectRoot, parsed);
281
+ return;
282
+ case "ingest":
283
+ handleIngest(projectRoot, parsed);
258
284
  return;
259
285
  case "clean":
260
286
  output(cleanRuntimeArtifacts(projectRoot, {
@@ -266,6 +292,7 @@ async function main() {
266
292
  output(createPlan(projectRoot, {
267
293
  taskText: parsed.taskText,
268
294
  ...optionalString("prd", parsed.flags["prd"]),
295
+ ...optionalString("apiSource", parsed.flags["api-source"]),
269
296
  ...optionalString("uiSource", parsed.flags["ui-source"]),
270
297
  ...optionalString("agentProposal", parsed.flags["agent-proposal"])
271
298
  }), parsed.json);
@@ -348,11 +375,27 @@ async function main() {
348
375
  console.log(JSON.stringify({ error: message }, null, 2));
349
376
  }
350
377
  else {
351
- console.error(message);
378
+ console.error(humanField(message));
352
379
  }
353
380
  process.exitCode = 1;
354
381
  }
355
382
  }
383
+ function handleContext(projectRoot, parsed) {
384
+ if (parsed.subcommand === "task") {
385
+ output(buildCompactTaskContext(projectRoot, {
386
+ taskText: parsed.positionals.slice(2).join(" "),
387
+ ...optionalString("prd", parsed.flags["prd"]),
388
+ ...optionalString("apiSource", parsed.flags["api-source"]),
389
+ ...optionalString("uiSource", parsed.flags["ui-source"]),
390
+ ...optionalNumber("limit", parsed.flags["limit"])
391
+ }), parsed.json);
392
+ return;
393
+ }
394
+ if (parsed.subcommand) {
395
+ throw new Error("context requires subcommand: task");
396
+ }
397
+ output(buildContext(projectRoot), parsed.json);
398
+ }
356
399
  function handleEvidence(projectRoot, parsed) {
357
400
  if (parsed.subcommand === "template") {
358
401
  output(createEvidenceTemplate(projectRoot), parsed.json);
@@ -364,6 +407,27 @@ function handleEvidence(projectRoot, parsed) {
364
407
  }
365
408
  throw new Error("evidence requires subcommand: template or record");
366
409
  }
410
+ function handleIngest(projectRoot, parsed) {
411
+ if (parsed.subcommand === "record") {
412
+ output(recordIngestSource(projectRoot, {
413
+ ...optionalString("kind", parsed.flags["kind"]),
414
+ ...optionalString("id", parsed.flags["id"]),
415
+ ...optionalString("source", parsed.flags["source"]),
416
+ ...optionalString("summary", parsed.flags["summary"]),
417
+ ...optionalString("cards", parsed.flags["cards"])
418
+ }), parsed.json);
419
+ return;
420
+ }
421
+ if (parsed.subcommand === "list") {
422
+ output(listIngestRecords(projectRoot, stringFlag(parsed.flags["kind"])), parsed.json);
423
+ return;
424
+ }
425
+ if (parsed.subcommand === "show") {
426
+ output(showIngestRecord(projectRoot, stringFlag(parsed.flags["ref"])), parsed.json);
427
+ return;
428
+ }
429
+ throw new Error("ingest requires subcommand: record, list, or show");
430
+ }
367
431
  function handleVisual(projectRoot, parsed) {
368
432
  if (parsed.subcommand === "compare") {
369
433
  const result = compareVisualArtifacts(projectRoot, {
@@ -424,7 +488,7 @@ function handleRepair(projectRoot, parsed) {
424
488
  }
425
489
  function handleSkills(projectRoot, parsed) {
426
490
  if (parsed.subcommand === "list") {
427
- output({ skills: discoverSkills(projectRoot) }, parsed.json);
491
+ output(listSkills(projectRoot), parsed.json);
428
492
  return;
429
493
  }
430
494
  if (parsed.subcommand === "check") {
@@ -458,6 +522,12 @@ function handleKnowledge(projectRoot, parsed) {
458
522
  }), parsed.json);
459
523
  return;
460
524
  }
525
+ if (parsed.subcommand === "draft") {
526
+ output(draftKnowledgeFromIngest(projectRoot, {
527
+ ...optionalString("ref", parsed.flags["ref"])
528
+ }), parsed.json);
529
+ return;
530
+ }
461
531
  if (parsed.subcommand === "promote") {
462
532
  output(promoteKnowledge(projectRoot, {
463
533
  ...optionalString("title", parsed.flags["title"]),
@@ -546,7 +616,7 @@ function handleKnowledge(projectRoot, parsed) {
546
616
  process.exitCode = result.status === "failed" ? 1 : 0;
547
617
  return;
548
618
  }
549
- throw new Error("knowledge requires subcommand: add, promote, module, update, index, coverage, list, search, show, or check");
619
+ throw new Error("knowledge requires subcommand: add, draft, promote, module, update, index, coverage, list, search, show, or check");
550
620
  }
551
621
  function requireSubcommand(parsed, subcommand, message) {
552
622
  if (parsed.subcommand !== subcommand) {
@@ -617,12 +687,13 @@ function allowedFlags(parsed) {
617
687
  const global = ["json", "help"];
618
688
  const commandFlags = {
619
689
  init: ["dry-run", "check"],
620
- context: [],
690
+ context: parsed.subcommand === "task" ? ["limit", "prd", "api-source", "ui-source"] : [],
621
691
  clean: ["dry-run", "keep-logs"],
622
- plan: ["prd", "ui-source", "agent-proposal"],
692
+ plan: ["prd", "api-source", "ui-source", "agent-proposal"],
623
693
  verify: ["typecheck", "test", "build"],
624
694
  visual: parsed.subcommand === "compare" ? ["design", "actual", "diff", "report", "threshold"] : [],
625
695
  evidence: parsed.subcommand === "record" ? ["file"] : [],
696
+ ingest: ingestFlags(parsed.subcommand),
626
697
  state: parsed.subcommand === "record-change" ? ["from-git"] : [],
627
698
  knowledge: knowledgeFlags(parsed.subcommand),
628
699
  protocol: [],
@@ -648,6 +719,8 @@ function knowledgeFlags(subcommand) {
648
719
  switch (subcommand) {
649
720
  case "add":
650
721
  return ["id", "kind", "subject", "summary", ...atomicContent, ...traceability, ...lifecycle];
722
+ case "draft":
723
+ return ["ref"];
651
724
  case "promote":
652
725
  return ["title", "body", "type", ...lifecycle];
653
726
  case "module":
@@ -669,6 +742,20 @@ function knowledgeFlags(subcommand) {
669
742
  return [];
670
743
  }
671
744
  }
745
+ function ingestFlags(subcommand) {
746
+ switch (subcommand) {
747
+ case "record":
748
+ return ["kind", "id", "source", "summary", "cards"];
749
+ case "list":
750
+ return ["kind"];
751
+ case "show":
752
+ return ["ref"];
753
+ case undefined:
754
+ return [];
755
+ default:
756
+ return [];
757
+ }
758
+ }
672
759
  function output(value, json) {
673
760
  if (json) {
674
761
  console.log(JSON.stringify(value, null, 2));
@@ -676,63 +763,199 @@ function output(value, json) {
676
763
  }
677
764
  console.log(renderHuman(value));
678
765
  }
766
+ const MAX_HUMAN_FIELD_CHARS = 240;
767
+ const MAX_HUMAN_PROMPT_CHARS = 4_000;
768
+ function humanField(value) {
769
+ const normalized = normalizeHumanField(value);
770
+ return normalized.length > MAX_HUMAN_FIELD_CHARS
771
+ ? `${normalized.slice(0, MAX_HUMAN_FIELD_CHARS - 3)}...`
772
+ : normalized;
773
+ }
774
+ function humanFieldTruncated(value) {
775
+ return normalizeHumanField(value).length > MAX_HUMAN_FIELD_CHARS;
776
+ }
777
+ function normalizeHumanField(value) {
778
+ return String(value ?? "unknown").replace(/\s+/g, " ").trim();
779
+ }
780
+ function humanBlock(value, maxChars) {
781
+ const text = String(value ?? "").trimEnd();
782
+ return text.length > maxChars ? `${text.slice(0, maxChars - 3)}...` : text;
783
+ }
784
+ function humanBlockTruncated(value, maxChars) {
785
+ return String(value ?? "").trimEnd().length > maxChars;
786
+ }
679
787
  function renderHuman(value) {
680
788
  if (!isRecord(value)) {
681
789
  return String(value);
682
790
  }
683
791
  if ("projectRoot" in value && "detectedStack" in value) {
684
792
  const context = value;
793
+ const knowledgeLimit = context.projectStatus?.knowledgeLimits;
794
+ const skillLimit = context.projectStatus?.skillLimits;
795
+ const planningDecision = context.projectStatus?.planningDecision;
796
+ const proposalLimits = planningDecision?.limits;
797
+ const evidence = planningDecision?.planningEvidence;
685
798
  return [
686
- `projectRoot: ${String(context.projectRoot ?? "unknown")}`,
687
- `packageManager: ${String(context.detectedStack?.packageManager ?? "unknown")}`,
688
- `framework: ${String(context.detectedStack?.framework ?? "unknown")}`,
689
- `language: ${String(context.detectedStack?.language ?? "unknown")}`
799
+ `projectRoot: ${humanField(context.projectRoot ?? "unknown")}`,
800
+ `packageManager: ${humanField(context.detectedStack?.packageManager ?? "unknown")}`,
801
+ `framework: ${humanField(context.detectedStack?.framework ?? "unknown")}`,
802
+ `language: ${humanField(context.detectedStack?.language ?? "unknown")}`,
803
+ `knowledge: ${Array.isArray(context.projectStatus?.knowledge) ? context.projectStatus.knowledge.length : 0}/${String(knowledgeLimit?.total ?? "unknown")}`,
804
+ `omittedKnowledge: ${String(knowledgeLimit?.omitted ?? 0)}`,
805
+ `skills: ${Array.isArray(context.projectStatus?.skills) ? context.projectStatus.skills.length : 0}/${String(skillLimit?.total ?? "unknown")}`,
806
+ `omittedSkills: ${String(skillLimit?.omitted ?? 0)}`,
807
+ ...(planningDecision ? [
808
+ `planningDecision: ${humanField(planningDecision.artifactPath ?? "unknown")}`,
809
+ `planningConstraintHints: ${String(proposalLimits?.constraintHints?.selected ?? (Array.isArray(planningDecision.constraintHints) ? planningDecision.constraintHints.length : 0))}/${String(proposalLimits?.constraintHints?.max ?? "unknown")}`,
810
+ `planningComponentHints: ${String(proposalLimits?.componentHints?.selected ?? (Array.isArray(planningDecision.componentHints) ? planningDecision.componentHints.length : 0))}/${String(proposalLimits?.componentHints?.max ?? "unknown")}`,
811
+ `planningWorkflowCandidates: ${String(proposalLimits?.workflowCandidates?.selected ?? (Array.isArray(evidence?.workflowCandidates) ? evidence.workflowCandidates.length : 0))}/${String(proposalLimits?.workflowCandidates?.max ?? "unknown")}`,
812
+ `planningTargetCandidates: ${String(proposalLimits?.targetCandidates?.selected ?? (Array.isArray(evidence?.targetCandidates) ? evidence.targetCandidates.length : 0))}/${String(proposalLimits?.targetCandidates?.max ?? "unknown")}`,
813
+ `planningVerificationCandidates: ${String(proposalLimits?.verificationCandidates?.selected ?? (Array.isArray(evidence?.verificationCandidates) ? evidence.verificationCandidates.length : 0))}/${String(proposalLimits?.verificationCandidates?.max ?? "unknown")}`,
814
+ `planningAmbiguities: ${String(proposalLimits?.ambiguities?.selected ?? (Array.isArray(evidence?.ambiguities) ? evidence.ambiguities.length : 0))}/${String(proposalLimits?.ambiguities?.max ?? "unknown")}`
815
+ ] : [])
690
816
  ].join("\n");
691
817
  }
692
818
  if ("task" in value && "units" in value && Array.isArray(value["units"])) {
693
819
  const plan = value;
820
+ const guidanceLimits = plan.limits?.guidance;
821
+ return [
822
+ `intent: ${humanField(plan.task?.intent)}`,
823
+ `scope: ${humanField(plan.task?.scope)}`,
824
+ `components: ${Array.isArray(plan.components) ? plan.components.length : 0}`,
825
+ `units: ${plan.units.length}`,
826
+ `guidanceComponents: ${String(guidanceLimits?.components?.selected ?? "unknown")}/${String(guidanceLimits?.components?.total ?? "unknown")}`,
827
+ `omittedGuidanceComponents: ${String(guidanceLimits?.components?.omitted ?? 0)}`,
828
+ `guidanceUnits: ${String(guidanceLimits?.units?.selected ?? "unknown")}/${String(guidanceLimits?.units?.total ?? "unknown")}`,
829
+ `omittedGuidanceUnits: ${String(guidanceLimits?.units?.omitted ?? 0)}`,
830
+ `guidancePath: ${humanField(plan.guidancePath ?? "unknown")}`,
831
+ `componentGraphPath: ${humanField(plan.componentGraphPath ?? "unknown")}`,
832
+ `statePath: ${humanField(plan.statePath ?? "unknown")}`
833
+ ].join("\n");
834
+ }
835
+ if ("task" in value && "workflow" in value && "prompt" in value) {
836
+ const taskContext = value;
837
+ const sourceHintCount = [
838
+ taskContext.sourceHints?.endpoints,
839
+ taskContext.sourceHints?.prdCoverage,
840
+ taskContext.sourceHints?.uiArtifacts,
841
+ taskContext.sourceHints?.apiImplementations
842
+ ].reduce((total, group) => total + (Array.isArray(group) ? group.length : 0), 0);
843
+ const prompt = String(taskContext.prompt ?? "");
694
844
  return [
695
- `intent: ${String(plan.task?.intent ?? "unknown")}`,
696
- `scope: ${String(plan.task?.scope ?? "unknown")}`,
697
- `units: ${plan.units.length}`
845
+ `task: ${humanField(taskContext.task)}`,
846
+ `workflow: ${humanField(taskContext.workflow?.kind)}`,
847
+ `knowledge: ${Array.isArray(taskContext.selectedKnowledge) ? taskContext.selectedKnowledge.length : 0}`,
848
+ `ingestSources: ${Array.isArray(taskContext.selectedIngestSources) ? taskContext.selectedIngestSources.length : 0}`,
849
+ `projectFiles: ${Array.isArray(taskContext.selectedProjectFiles) ? taskContext.selectedProjectFiles.length : 0}`,
850
+ `sourceHints: ${sourceHintCount}`,
851
+ `omittedKnowledge: ${String(taskContext.limits?.omittedSelectedKnowledge ?? 0)}`,
852
+ `omittedKnowledgeSourcePaths: ${String(taskContext.limits?.omittedSelectedKnowledgeSourcePaths ?? 0)}`,
853
+ `omittedKnowledgeCoverage: ${String(taskContext.limits?.omittedSelectedKnowledgeCoverage ?? 0)}`,
854
+ `omittedKnowledgeVerification: ${String(taskContext.limits?.omittedSelectedKnowledgeVerification ?? 0)}`,
855
+ `omittedIngestSources: ${String(taskContext.limits?.omittedSelectedIngestSources ?? 0)}`,
856
+ `omittedIngestProducedKnowledgeCardIds: ${String(taskContext.limits?.omittedSelectedIngestProducedKnowledgeCardIds ?? 0)}`,
857
+ `omittedProjectFiles: ${String(taskContext.limits?.omittedSelectedProjectFiles ?? 0)}`,
858
+ `omittedSourceHints: ${String(taskContext.limits?.omittedSourceHints ?? 0)}`,
859
+ `omittedPrdCoverageHintCoverage: ${String(taskContext.limits?.omittedPrdCoverageHintCoverage ?? 0)}`,
860
+ `omittedPrdCoverageHintAnchors: ${String(taskContext.limits?.omittedPrdCoverageHintAnchors ?? 0)}`,
861
+ `omittedPrdCoverageHintSourcePaths: ${String(taskContext.limits?.omittedPrdCoverageHintSourcePaths ?? 0)}`,
862
+ `projectFilesScanned: ${String(taskContext.limits?.totalScannedProjectFiles ?? 0)}/${String(taskContext.limits?.scannedProjectFiles ?? "unknown")}`,
863
+ `projectFileScanLimitReached: ${String(taskContext.limits?.projectFileScanLimitReached ?? false)}`,
864
+ `skippedPrdSourceHintSources: ${String(taskContext.limits?.skippedPrdSourceHintSources ?? 0)}`,
865
+ `skippedApiSourceHintSources: ${String(taskContext.limits?.skippedApiSourceHintSources ?? 0)}`,
866
+ `artifactPath: ${humanField(taskContext.artifactPath ?? "unknown")}`,
867
+ `promptChars: ${String(prompt.length)}`,
868
+ `promptTruncated: ${String(humanBlockTruncated(prompt, MAX_HUMAN_PROMPT_CHARS))}`,
869
+ "",
870
+ humanBlock(prompt, MAX_HUMAN_PROMPT_CHARS)
698
871
  ].join("\n");
699
872
  }
700
873
  if ("results" in value && Array.isArray(value["results"])) {
701
874
  const verification = value;
875
+ const selectedResults = verification.results.slice(0, MAX_HUMAN_VERIFICATION_RESULTS);
876
+ const omittedResults = Math.max(0, verification.results.length - selectedResults.length);
702
877
  return [
703
- `status: ${String(verification.status ?? "unknown")}`,
878
+ `status: ${humanField(verification.status ?? "unknown")}`,
704
879
  `results: ${verification.results.length}`,
705
- ...verification.results.map((item) => `- ${String(item.name ?? "verification")}: ${String(item.status ?? "unknown")} (${String(item.exitCode ?? "n/a")})`)
880
+ `omittedResults: ${String(omittedResults)}`,
881
+ ...selectedResults.map((item) => `- ${humanField(item.name ?? "verification")}: ${humanField(item.status ?? "unknown")} (${String(item.exitCode ?? "n/a")})`)
882
+ ].join("\n");
883
+ }
884
+ if ("manifestPath" in value && "entries" in value && "instructions" in value) {
885
+ const template = value;
886
+ const entryLimits = template.limits?.entries;
887
+ return [
888
+ `status: ${humanField(template.status ?? "unknown")}`,
889
+ `manifestPath: ${humanField(template.manifestPath ?? "unknown")}`,
890
+ `entries: ${String(entryLimits?.selected ?? (Array.isArray(template.entries) ? template.entries.length : 0))}/${String(entryLimits?.total ?? (Array.isArray(template.entries) ? template.entries.length : 0))}`,
891
+ `omittedEntries: ${String(entryLimits?.omitted ?? 0)}`
892
+ ].join("\n");
893
+ }
894
+ if ("recordedEntries" in value && "entryCount" in value && "provenance" in value) {
895
+ const evidence = value;
896
+ const selectedSourceLimit = evidence.provenance?.limits?.selectedEvidenceSources ?? "unknown";
897
+ return [
898
+ `status: ${humanField(evidence.status ?? "unknown")}`,
899
+ `inputPath: ${humanField(evidence.inputPath ?? "unknown")}`,
900
+ `manifestPath: ${humanField(evidence.manifestPath ?? "unknown")}`,
901
+ `recordedEntries: ${Array.isArray(evidence.recordedEntries) ? evidence.recordedEntries.length : 0}`,
902
+ `entryCount: ${String(evidence.entryCount ?? 0)}`,
903
+ `planArtifactPath: ${humanField(evidence.provenance?.planArtifactPath ?? "none")}`,
904
+ `taskContextArtifactPath: ${humanField(evidence.provenance?.taskContextArtifactPath ?? "none")}`,
905
+ `selectedApiContractSources: ${Array.isArray(evidence.provenance?.selectedApiContractSources) ? evidence.provenance.selectedApiContractSources.length : 0}/${String(selectedSourceLimit)}`,
906
+ `omittedSelectedApiContractSources: ${String(evidence.provenance?.limits?.omittedSelectedApiContractSources ?? 0)}`,
907
+ `selectedUiSources: ${Array.isArray(evidence.provenance?.selectedUiSources) ? evidence.provenance.selectedUiSources.length : 0}/${String(selectedSourceLimit)}`,
908
+ `omittedSelectedUiSources: ${String(evidence.provenance?.limits?.omittedSelectedUiSources ?? 0)}`,
909
+ `selectedIngestSources: ${Array.isArray(evidence.provenance?.selectedIngestSources) ? evidence.provenance.selectedIngestSources.length : 0}/${String(selectedSourceLimit)}`,
910
+ `omittedSelectedIngestSources: ${String(evidence.provenance?.limits?.omittedSelectedIngestSources ?? 0)}`
706
911
  ].join("\n");
707
912
  }
708
913
  if ("comparisonTool" in value && "score" in value) {
709
914
  const comparison = value;
710
915
  return [
711
- `status: ${String(comparison.status ?? "unknown")}`,
916
+ `status: ${humanField(comparison.status ?? "unknown")}`,
712
917
  `score: ${String(comparison.score ?? "unknown")}`,
713
918
  `threshold: ${String(comparison.threshold ?? "unknown")}`,
714
919
  `changedPixels: ${String(comparison.changedPixels ?? "unknown")}`,
715
920
  `changedRatio: ${String(comparison.changedRatio ?? "unknown")}`,
716
- `diffPath: ${String(comparison.diffPath ?? "unknown")}`,
921
+ `diffPath: ${humanField(comparison.diffPath ?? "unknown")}`,
717
922
  ...(Array.isArray(comparison.limitations) && comparison.limitations.length
718
- ? [`limitations: ${comparison.limitations.map((item) => String(item)).join(" ")}`]
923
+ ? [`limitations: ${comparison.limitations.map((item) => humanField(item)).join(" ")}`]
719
924
  : [])
720
925
  ].join("\n");
721
926
  }
722
927
  if ("action" in value && "stateStatus" in value) {
723
928
  const next = value;
929
+ const changedFileLimit = next.limits?.changedFiles;
724
930
  return [
725
- `action: ${String(next.action ?? "unknown")}`,
726
- `reason: ${String(next.reason ?? "unknown")}`,
727
- `command: ${String(next.command ?? "none")}`
931
+ `action: ${humanField(next.action ?? "unknown")}`,
932
+ `reason: ${humanField(next.reason ?? "unknown")}`,
933
+ `command: ${humanField(next.command ?? "none")}`,
934
+ `changedFiles: ${String(changedFileLimit?.selected ?? (Array.isArray(next.changedFiles) ? next.changedFiles.length : 0))}/${String(changedFileLimit?.total ?? (Array.isArray(next.changedFiles) ? next.changedFiles.length : 0))}`,
935
+ `omittedChangedFiles: ${String(changedFileLimit?.omitted ?? 0)}`
936
+ ].join("\n");
937
+ }
938
+ if ("nextAction" in value && "requiredArtifacts" in value && "recommendedCommands" in value) {
939
+ const explain = value;
940
+ const markdownLimits = explain.limits?.markdown;
941
+ return [
942
+ `action: ${humanField(explain.nextAction?.action ?? "unknown")}`,
943
+ `summary: ${humanField(explain.summary ?? "unknown")}`,
944
+ `rationale: ${String(markdownLimits?.rationale?.selected ?? "unknown")}/${String(markdownLimits?.rationale?.total ?? "unknown")}`,
945
+ `omittedRationale: ${String(markdownLimits?.rationale?.omitted ?? 0)}`,
946
+ `requiredArtifacts: ${String(markdownLimits?.requiredArtifacts?.selected ?? (Array.isArray(explain.requiredArtifacts) ? explain.requiredArtifacts.length : 0))}/${String(markdownLimits?.requiredArtifacts?.total ?? (Array.isArray(explain.requiredArtifacts) ? explain.requiredArtifacts.length : 0))}`,
947
+ `omittedRequiredArtifacts: ${String(markdownLimits?.requiredArtifacts?.omitted ?? 0)}`,
948
+ `recommendedCommands: ${String(markdownLimits?.recommendedCommands?.selected ?? (Array.isArray(explain.recommendedCommands) ? explain.recommendedCommands.length : 0))}/${String(markdownLimits?.recommendedCommands?.total ?? (Array.isArray(explain.recommendedCommands) ? explain.recommendedCommands.length : 0))}`,
949
+ `omittedRecommendedCommands: ${String(markdownLimits?.recommendedCommands?.omitted ?? 0)}`,
950
+ `stopCondition: ${humanField(explain.stopCondition ?? "unknown")}`
728
951
  ].join("\n");
729
952
  }
730
953
  if ("changedFiles" in value && "verification" in value) {
731
954
  const state = value;
732
955
  return [
733
- `status: ${String(state.status ?? "unknown")}`,
956
+ `status: ${humanField(state.status ?? "unknown")}`,
734
957
  `changedFiles: ${Array.isArray(state.changedFiles) ? state.changedFiles.length : 0}`,
735
- `verification: ${String(state.verification?.status ?? "unknown")}`,
958
+ `verification: ${humanField(state.verification?.status ?? "unknown")}`,
736
959
  `retryCount: ${String(state.retryCount ?? 0)}`
737
960
  ].join("\n");
738
961
  }
@@ -746,41 +969,80 @@ function renderHuman(value) {
746
969
  }
747
970
  if ("skills" in value && Array.isArray(value["skills"])) {
748
971
  const skills = value["skills"];
749
- return [`skills: ${skills.length}`, ...skills.map((skill) => `- ${String(skill.name ?? "unknown")}: ${String(skill.title ?? "unknown")} (${String(skill.path ?? "unknown")})`)].join("\n");
972
+ const limits = value["limits"];
973
+ const selected = limits?.selected ?? skills.length;
974
+ const total = limits?.total ?? skills.length;
975
+ return [
976
+ `skills: ${String(selected)}/${String(total)}`,
977
+ `omittedSkills: ${String(limits?.omitted ?? 0)}`,
978
+ ...skills.map((skill) => `- ${humanField(skill.name)}: ${humanField(skill.title)} (${humanField(skill.path)})`)
979
+ ].join("\n");
750
980
  }
751
- if ("cards" in value && Array.isArray(value["cards"])) {
752
- const cards = value["cards"];
981
+ if ("records" in value && Array.isArray(value["records"])) {
982
+ const records = value["records"];
983
+ const limits = value["limits"];
984
+ const selected = limits?.selected ?? records.length;
985
+ const total = limits?.total ?? records.length;
753
986
  return [
754
- `cards: ${cards.length}`,
755
- ...cards.map((card) => {
756
- const score = card.score === undefined ? "" : ` score=${String(card.score)}`;
757
- return `- ${String(card.id ?? "unknown")}: ${String(card.title ?? "unknown")} (${String(card.path ?? "unknown")})${score}`;
758
- })
987
+ `records: ${String(selected)}/${String(total)}`,
988
+ `omittedRecords: ${String(limits?.omitted ?? 0)}`,
989
+ ...records.map((record) => `- ${humanField(record.ingestRef)}: ${humanField(record.summary)} (${humanField(record.artifactPath)})`)
759
990
  ].join("\n");
760
991
  }
761
- if ("card" in value && "body" in value) {
762
- const shown = value;
992
+ if ("ingestRef" in value && "source" in value && "producedKnowledgeCardIds" in value) {
993
+ const record = value;
763
994
  return [
764
- `id: ${String(shown.card?.id ?? "unknown")}`,
765
- `title: ${String(shown.card?.title ?? "unknown")}`,
766
- `path: ${String(shown.card?.path ?? "unknown")}`,
767
- "",
768
- String(shown.body ?? "")
995
+ `ingestRef: ${humanField(record.ingestRef)}`,
996
+ `kind: ${humanField(record.kind)}`,
997
+ `source: ${humanField(record.source?.value)}`,
998
+ `sha256: ${humanField(record.source?.sha256 ?? "none")}`,
999
+ `cards: ${Array.isArray(record.producedKnowledgeCardIds) ? record.producedKnowledgeCardIds.length : 0}`,
1000
+ `artifactPath: ${humanField(record.artifactPath)}`
769
1001
  ].join("\n");
770
1002
  }
771
1003
  if ("artifactPath" in value && "prdSourceCount" in value) {
772
1004
  const index = value;
1005
+ const cardLimits = index.limits?.cards;
773
1006
  return [
774
- `artifactPath: ${String(index.artifactPath ?? "unknown")}`,
1007
+ `artifactPath: ${humanField(index.artifactPath ?? "unknown")}`,
775
1008
  `cardCount: ${String(index.cardCount ?? 0)}`,
1009
+ `cards: ${String(cardLimits?.selected ?? index.cardCount ?? 0)}/${String(cardLimits?.total ?? index.cardCount ?? 0)}`,
1010
+ `omittedCards: ${String(cardLimits?.omitted ?? 0)}`,
776
1011
  `prdSourceCount: ${String(index.prdSourceCount ?? 0)}`,
777
1012
  `uncoveredPrdSourceCount: ${String(index.uncoveredPrdSourceCount ?? 0)}`
778
1013
  ].join("\n");
779
1014
  }
1015
+ if ("cards" in value && Array.isArray(value["cards"])) {
1016
+ const cards = value["cards"];
1017
+ const limits = value["limits"];
1018
+ const selected = limits?.selected ?? cards.length;
1019
+ const total = limits?.total ?? cards.length;
1020
+ return [
1021
+ `cards: ${String(selected)}${limits ? `/${String(total)}` : ""}`,
1022
+ ...(limits ? [`omittedCards: ${String(limits.omitted ?? 0)}`] : []),
1023
+ ...cards.map((card) => {
1024
+ const score = card.score === undefined ? "" : ` score=${String(card.score)}`;
1025
+ return `- ${humanField(card.id)}: ${humanField(card.title)} (${humanField(card.path)})${score}`;
1026
+ })
1027
+ ].join("\n");
1028
+ }
1029
+ if ("card" in value && "body" in value) {
1030
+ const shown = value;
1031
+ const body = String(shown.body ?? "");
1032
+ return [
1033
+ `id: ${humanField(shown.card?.id)}`,
1034
+ `title: ${humanField(shown.card?.title)}`,
1035
+ `path: ${humanField(shown.card?.path)}`,
1036
+ `bodyChars: ${String(body.length)}`,
1037
+ `bodyTruncated: ${String(humanFieldTruncated(body))}`,
1038
+ "",
1039
+ humanField(body)
1040
+ ].join("\n");
1041
+ }
780
1042
  if ("coveredPrdSourceCount" in value && "uncoveredPrdSources" in value) {
781
1043
  const coverage = value;
782
1044
  return [
783
- `status: ${String(coverage.status ?? "unknown")}`,
1045
+ `status: ${humanField(coverage.status ?? "unknown")}`,
784
1046
  `prdSourceCount: ${String(coverage.prdSourceCount ?? 0)}`,
785
1047
  `coveredPrdSourceCount: ${String(coverage.coveredPrdSourceCount ?? 0)}`,
786
1048
  `uncoveredPrdSources: ${Array.isArray(coverage.uncoveredPrdSources) ? coverage.uncoveredPrdSources.length : 0}`,
@@ -789,7 +1051,19 @@ function renderHuman(value) {
789
1051
  }
790
1052
  if ("path" in value && "title" in value) {
791
1053
  const knowledge = value;
792
- return [`path: ${String(knowledge.path ?? "unknown")}`, `title: ${String(knowledge.title ?? "unknown")}`, `createdAt: ${String(knowledge.createdAt ?? "unknown")}`].join("\n");
1054
+ return [`path: ${humanField(knowledge.path)}`, `title: ${humanField(knowledge.title)}`, `createdAt: ${humanField(knowledge.createdAt)}`].join("\n");
1055
+ }
1056
+ if ("ingestRef" in value && "recommendedAction" in value && "updateCandidates" in value) {
1057
+ const draft = value;
1058
+ const candidateLimits = draft.limits?.updateCandidates;
1059
+ return [
1060
+ `ingestRef: ${humanField(draft.ingestRef ?? "unknown")}`,
1061
+ `recommendedAction: ${humanField(draft.recommendedAction ?? "unknown")}`,
1062
+ `recommendedKind: ${humanField(draft.recommendedKind ?? "unknown")}`,
1063
+ `recommendedType: ${humanField(draft.recommendedType ?? "unknown")}`,
1064
+ `updateCandidates: ${String(candidateLimits?.selected ?? (Array.isArray(draft.updateCandidates) ? draft.updateCandidates.length : 0))}/${String(candidateLimits?.total ?? (Array.isArray(draft.updateCandidates) ? draft.updateCandidates.length : 0))}`,
1065
+ `omittedUpdateCandidates: ${String(candidateLimits?.omitted ?? 0)}`
1066
+ ].join("\n");
793
1067
  }
794
1068
  if ("artifactPath" in value && "unitCount" in value) {
795
1069
  return renderCheck(value, "unitCount");
@@ -797,30 +1071,53 @@ function renderHuman(value) {
797
1071
  if ("artifactPath" in value && "nodeCount" in value) {
798
1072
  return renderCheck(value, "nodeCount");
799
1073
  }
1074
+ if ("artifactPath" in value && "proposal" in value) {
1075
+ const checked = value;
1076
+ const evidence = checked.proposal?.planningEvidence;
1077
+ return [
1078
+ `status: ${humanField(checked.status ?? "unknown")}`,
1079
+ `artifactPath: ${humanField(checked.artifactPath)}`,
1080
+ `constraintHints: ${String(checked.limits?.constraintHints?.selected ?? (Array.isArray(checked.proposal?.constraintHints) ? checked.proposal.constraintHints.length : 0))}/${String(checked.limits?.constraintHints?.max ?? "unknown")}`,
1081
+ `componentHints: ${String(checked.limits?.componentHints?.selected ?? (Array.isArray(checked.proposal?.componentHints) ? checked.proposal.componentHints.length : 0))}/${String(checked.limits?.componentHints?.max ?? "unknown")}`,
1082
+ `workflowCandidates: ${String(checked.limits?.workflowCandidates?.selected ?? (Array.isArray(evidence?.workflowCandidates) ? evidence.workflowCandidates.length : 0))}/${String(checked.limits?.workflowCandidates?.max ?? "unknown")}`,
1083
+ `targetCandidates: ${String(checked.limits?.targetCandidates?.selected ?? (Array.isArray(evidence?.targetCandidates) ? evidence.targetCandidates.length : 0))}/${String(checked.limits?.targetCandidates?.max ?? "unknown")}`,
1084
+ `verificationCandidates: ${String(checked.limits?.verificationCandidates?.selected ?? (Array.isArray(evidence?.verificationCandidates) ? evidence.verificationCandidates.length : 0))}/${String(checked.limits?.verificationCandidates?.max ?? "unknown")}`,
1085
+ `ambiguities: ${String(checked.limits?.ambiguities?.selected ?? (Array.isArray(evidence?.ambiguities) ? evidence.ambiguities.length : 0))}/${String(checked.limits?.ambiguities?.max ?? "unknown")}`,
1086
+ ...(Array.isArray(checked.errors) && checked.errors.length ? checked.errors.map((error) => `error: ${humanField(error)}`) : [])
1087
+ ].join("\n");
1088
+ }
800
1089
  if ("skillsRoot" in value && "skillCount" in value) {
801
1090
  return renderCheck(value, "skillCount");
802
1091
  }
803
1092
  if ("knowledgeRoot" in value && "cardCount" in value) {
804
1093
  return renderCheck(value, "cardCount");
805
1094
  }
806
- if ("artifactPath" in value && ("proposal" in value || "decision" in value)) {
1095
+ if ("artifactPath" in value && "decision" in value) {
807
1096
  return renderCheck(value, null);
808
1097
  }
809
1098
  if ("contractVersion" in value && "failedCommands" in value) {
810
1099
  const packet = value;
811
1100
  return [
812
- `status: ${String(packet.status ?? "unknown")}`,
813
- `verificationStatus: ${String(packet.verificationStatus ?? "unknown")}`,
814
- `failedCommands: ${Array.isArray(packet.failedCommands) ? packet.failedCommands.length : 0}`
1101
+ `status: ${humanField(packet.status ?? "unknown")}`,
1102
+ `verificationStatus: ${humanField(packet.verificationStatus ?? "unknown")}`,
1103
+ `changedFiles: ${Array.isArray(packet.changedFiles) ? packet.changedFiles.length : 0}/${String(packet.limits?.totalChangedFiles ?? "unknown")}`,
1104
+ `omittedChangedFiles: ${String(packet.limits?.omittedChangedFiles ?? 0)}`,
1105
+ `failedCommands: ${Array.isArray(packet.failedCommands) ? packet.failedCommands.length : 0}/${String(packet.limits?.totalFailedCommands ?? "unknown")}`,
1106
+ `omittedFailedCommands: ${String(packet.limits?.omittedFailedCommands ?? 0)}`,
1107
+ `retryGuidanceFailedCommands: ${Array.isArray(packet.retryGuidance?.failedCommands) ? packet.retryGuidance.failedCommands.length : 0}/${String(packet.limits?.totalRetryGuidanceFailedCommands ?? "unknown")}`,
1108
+ `omittedRetryGuidanceFailedCommands: ${String(packet.limits?.omittedRetryGuidanceFailedCommands ?? 0)}`,
1109
+ `retryGuidanceLogs: ${Array.isArray(packet.retryGuidance?.logs) ? packet.retryGuidance.logs.length : 0}/${String(packet.limits?.totalRetryGuidanceLogs ?? "unknown")}`,
1110
+ `omittedRetryGuidanceLogs: ${String(packet.limits?.omittedRetryGuidanceLogs ?? 0)}`,
1111
+ `retryGuidanceInstructionTruncated: ${String(packet.limits?.retryGuidanceInstructionTruncated ?? false)}`
815
1112
  ].join("\n");
816
1113
  }
817
1114
  if ("contractVersion" in value && "files" in value) {
818
1115
  const init = value;
819
1116
  return [
820
1117
  `dryRun: ${String(init.dryRun ?? false)}`,
821
- `needsUpdate: ${String(init.needsUpdate ?? "unknown")}`,
822
- ...(Array.isArray(init.files) ? init.files.map((file) => `${String(file.path ?? "unknown")}: ${String(file.action ?? "unknown")}`) : []),
823
- ...(Array.isArray(init.skills) ? init.skills.map((skill) => `${String(skill.path ?? "unknown")}: ${String(skill.action ?? "unknown")}`) : [])
1118
+ `needsUpdate: ${humanField(init.needsUpdate ?? "unknown")}`,
1119
+ ...(Array.isArray(init.files) ? init.files.map((file) => `${humanField(file.path ?? "unknown")}: ${humanField(file.action ?? "unknown")}`) : []),
1120
+ ...(Array.isArray(init.skills) ? init.skills.map((skill) => `${humanField(skill.path ?? "unknown")}: ${humanField(skill.action ?? "unknown")}`) : [])
824
1121
  ].join("\n");
825
1122
  }
826
1123
  if ("removed" in value && "kept" in value) {
@@ -834,30 +1131,36 @@ function renderHuman(value) {
834
1131
  if ("preset" in value && "files" in value && Array.isArray(value["files"])) {
835
1132
  const scaffold = value;
836
1133
  return [
837
- `status: ${String(scaffold.status ?? "unknown")}`,
838
- `preset: ${String(scaffold.preset ?? "unknown")}`,
839
- `target: ${String(scaffold.target ?? "unknown")}`,
840
- `projectName: ${String(scaffold.projectName ?? "unknown")}`,
1134
+ `status: ${humanField(scaffold.status ?? "unknown")}`,
1135
+ `preset: ${humanField(scaffold.preset ?? "unknown")}`,
1136
+ `target: ${humanField(scaffold.target ?? "unknown")}`,
1137
+ `projectName: ${humanField(scaffold.projectName ?? "unknown")}`,
841
1138
  `files: ${scaffold.files.length}`
842
1139
  ].join("\n");
843
1140
  }
844
1141
  if ("status" in value) {
845
- return `status: ${String(value["status"])}`;
1142
+ return `status: ${humanField(value["status"])}`;
846
1143
  }
847
1144
  return JSON.stringify(value, null, 2);
848
1145
  }
849
1146
  function renderCheck(value, countKey) {
1147
+ const errors = Array.isArray(value["errors"]) ? value["errors"] : [];
1148
+ const warnings = Array.isArray(value["warnings"]) ? value["warnings"] : [];
1149
+ const selectedErrors = errors.slice(0, 5);
1150
+ const selectedWarnings = warnings.slice(0, 5);
850
1151
  const lines = [
851
- `status: ${String(value["status"] ?? "unknown")}`,
852
- ...(value["artifactPath"] ? [`artifactPath: ${String(value["artifactPath"])}`] : []),
853
- ...(value["skillsRoot"] ? [`skillsRoot: ${String(value["skillsRoot"])}`] : []),
854
- ...(countKey ? [`${countKey}: ${String(value[countKey] ?? 0)}`] : [])
1152
+ `status: ${humanField(value["status"] ?? "unknown")}`,
1153
+ ...(value["artifactPath"] ? [`artifactPath: ${humanField(value["artifactPath"])}`] : []),
1154
+ ...(value["skillsRoot"] ? [`skillsRoot: ${humanField(value["skillsRoot"])}`] : []),
1155
+ ...(countKey ? [`${countKey}: ${String(value[countKey] ?? 0)}`] : []),
1156
+ `omittedErrors: ${String(Math.max(0, errors.length - selectedErrors.length))}`,
1157
+ `omittedWarnings: ${String(Math.max(0, warnings.length - selectedWarnings.length))}`
855
1158
  ];
856
- for (const error of (Array.isArray(value["errors"]) ? value["errors"] : []).slice(0, 5)) {
857
- lines.push(`error: ${String(error)}`);
1159
+ for (const error of selectedErrors) {
1160
+ lines.push(`error: ${humanField(error)}`);
858
1161
  }
859
- for (const warning of (Array.isArray(value["warnings"]) ? value["warnings"] : []).slice(0, 5)) {
860
- lines.push(`warning: ${String(warning)}`);
1162
+ for (const warning of selectedWarnings) {
1163
+ lines.push(`warning: ${humanField(warning)}`);
861
1164
  }
862
1165
  return lines.join("\n");
863
1166
  }