frontend-harness 0.7.10 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +18 -10
  2. package/dist/cli/index.js +399 -65
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/runtime/builtin-skills.js +2 -1
  5. package/dist/runtime/builtin-skills.js.map +1 -1
  6. package/dist/runtime/clean.js +1 -0
  7. package/dist/runtime/clean.js.map +1 -1
  8. package/dist/runtime/command-taxonomy.js +7 -1
  9. package/dist/runtime/command-taxonomy.js.map +1 -1
  10. package/dist/runtime/context.d.ts +33 -2
  11. package/dist/runtime/context.js +63 -8
  12. package/dist/runtime/context.js.map +1 -1
  13. package/dist/runtime/evidence.d.ts +27 -0
  14. package/dist/runtime/evidence.js +240 -12
  15. package/dist/runtime/evidence.js.map +1 -1
  16. package/dist/runtime/ingest.d.ts +38 -0
  17. package/dist/runtime/ingest.js +157 -0
  18. package/dist/runtime/ingest.js.map +1 -0
  19. package/dist/runtime/knowledge/constants.js +1 -0
  20. package/dist/runtime/knowledge/constants.js.map +1 -1
  21. package/dist/runtime/knowledge/core.d.ts +10 -1
  22. package/dist/runtime/knowledge/core.js +582 -24
  23. package/dist/runtime/knowledge/core.js.map +1 -1
  24. package/dist/runtime/knowledge/types.d.ts +125 -1
  25. package/dist/runtime/knowledge.d.ts +2 -2
  26. package/dist/runtime/knowledge.js +1 -1
  27. package/dist/runtime/knowledge.js.map +1 -1
  28. package/dist/runtime/plan/guidance.d.ts +1 -1
  29. package/dist/runtime/plan/guidance.js +88 -25
  30. package/dist/runtime/plan/guidance.js.map +1 -1
  31. package/dist/runtime/plan/workflow.d.ts +1 -0
  32. package/dist/runtime/plan/workflow.js +32 -1
  33. package/dist/runtime/plan/workflow.js.map +1 -1
  34. package/dist/runtime/plan.d.ts +13 -0
  35. package/dist/runtime/plan.js +132 -79
  36. package/dist/runtime/plan.js.map +1 -1
  37. package/dist/runtime/policy-provenance.d.ts +17 -1
  38. package/dist/runtime/policy-provenance.js +42 -12
  39. package/dist/runtime/policy-provenance.js.map +1 -1
  40. package/dist/runtime/protocol-init.js +12 -7
  41. package/dist/runtime/protocol-init.js.map +1 -1
  42. package/dist/runtime/repair-packet.js +86 -4
  43. package/dist/runtime/repair-packet.js.map +1 -1
  44. package/dist/runtime/skills.d.ts +9 -0
  45. package/dist/runtime/skills.js +13 -0
  46. package/dist/runtime/skills.js.map +1 -1
  47. package/dist/runtime/state-explain.js +39 -7
  48. package/dist/runtime/state-explain.js.map +1 -1
  49. package/dist/runtime/state.js +36 -2
  50. package/dist/runtime/state.js.map +1 -1
  51. package/dist/runtime/task-context.d.ts +122 -0
  52. package/dist/runtime/task-context.js +1322 -0
  53. package/dist/runtime/task-context.js.map +1 -0
  54. package/dist/runtime/task-signals.d.ts +1 -0
  55. package/dist/runtime/task-signals.js +1 -1
  56. package/dist/runtime/task-signals.js.map +1 -1
  57. package/dist/runtime/ui-restoration.d.ts +3 -3
  58. package/dist/runtime/ui-restoration.js +3 -3
  59. package/dist/runtime/ui-restoration.js.map +1 -1
  60. package/dist/runtime/ui-source.d.ts +6 -0
  61. package/dist/runtime/ui-source.js +66 -0
  62. package/dist/runtime/ui-source.js.map +1 -0
  63. package/dist/runtime/verify.js +65 -25
  64. package/dist/runtime/verify.js.map +1 -1
  65. package/dist/schemas/types.d.ts +75 -2
  66. package/dist/schemas/validation.js +42 -7
  67. package/dist/schemas/validation.js.map +1 -1
  68. package/docs/DIRECTION.md +13 -11
  69. 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, outlineKnowledgeFromIngest, 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,8 @@ 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 outline --json --ref ingest://<kind>/<source-id>",
131
+ " frontend-harness knowledge draft --json --ref ingest://<kind>/<source-id>",
115
132
  " frontend-harness knowledge module --json --id <id> --title \"<title>\" --summary \"<summary>\" --body \"<body>\"",
116
133
  " frontend-harness knowledge update --json --id <knowledge-id> [metadata flags]",
117
134
  " frontend-harness knowledge index --json",
@@ -147,6 +164,21 @@ const COMMAND_HELP = {
147
164
  " --status active|deprecated",
148
165
  " --stability stable|evolving"
149
166
  ],
167
+ "knowledge draft": [
168
+ "Usage:",
169
+ " frontend-harness knowledge draft --json --ref ingest://<kind>/<source-id>",
170
+ "",
171
+ "Builds a source outline and knowledge add/update scaffolds from recorded ingest provenance.",
172
+ "For PRD markdown sources, use extractionItems as the checklist: add, update, or explicitly skip each durable source block."
173
+ ],
174
+ "knowledge outline": [
175
+ "",
176
+ "Usage:",
177
+ " frontend-harness knowledge outline --json --ref ingest://<kind>/<source-id>",
178
+ "",
179
+ "Builds a deterministic source heading outline from recorded ingest provenance.",
180
+ "For project-file PRD markdown, headings include suggested knowledge kind and extraction-required hints."
181
+ ],
150
182
  "knowledge module": [
151
183
  "Usage:",
152
184
  " frontend-harness knowledge module --json --id <kebab-id> --title \"<title>\" --summary \"<summary>\" --body \"<body>\" [traceability flags]",
@@ -254,7 +286,10 @@ async function main() {
254
286
  }
255
287
  return;
256
288
  case "context":
257
- output(buildContext(projectRoot), parsed.json);
289
+ handleContext(projectRoot, parsed);
290
+ return;
291
+ case "ingest":
292
+ handleIngest(projectRoot, parsed);
258
293
  return;
259
294
  case "clean":
260
295
  output(cleanRuntimeArtifacts(projectRoot, {
@@ -266,6 +301,7 @@ async function main() {
266
301
  output(createPlan(projectRoot, {
267
302
  taskText: parsed.taskText,
268
303
  ...optionalString("prd", parsed.flags["prd"]),
304
+ ...optionalString("apiSource", parsed.flags["api-source"]),
269
305
  ...optionalString("uiSource", parsed.flags["ui-source"]),
270
306
  ...optionalString("agentProposal", parsed.flags["agent-proposal"])
271
307
  }), parsed.json);
@@ -348,11 +384,27 @@ async function main() {
348
384
  console.log(JSON.stringify({ error: message }, null, 2));
349
385
  }
350
386
  else {
351
- console.error(message);
387
+ console.error(humanField(message));
352
388
  }
353
389
  process.exitCode = 1;
354
390
  }
355
391
  }
392
+ function handleContext(projectRoot, parsed) {
393
+ if (parsed.subcommand === "task") {
394
+ output(buildCompactTaskContext(projectRoot, {
395
+ taskText: parsed.positionals.slice(2).join(" "),
396
+ ...optionalString("prd", parsed.flags["prd"]),
397
+ ...optionalString("apiSource", parsed.flags["api-source"]),
398
+ ...optionalString("uiSource", parsed.flags["ui-source"]),
399
+ ...optionalNumber("limit", parsed.flags["limit"])
400
+ }), parsed.json);
401
+ return;
402
+ }
403
+ if (parsed.subcommand) {
404
+ throw new Error("context requires subcommand: task");
405
+ }
406
+ output(buildContext(projectRoot), parsed.json);
407
+ }
356
408
  function handleEvidence(projectRoot, parsed) {
357
409
  if (parsed.subcommand === "template") {
358
410
  output(createEvidenceTemplate(projectRoot), parsed.json);
@@ -364,6 +416,27 @@ function handleEvidence(projectRoot, parsed) {
364
416
  }
365
417
  throw new Error("evidence requires subcommand: template or record");
366
418
  }
419
+ function handleIngest(projectRoot, parsed) {
420
+ if (parsed.subcommand === "record") {
421
+ output(recordIngestSource(projectRoot, {
422
+ ...optionalString("kind", parsed.flags["kind"]),
423
+ ...optionalString("id", parsed.flags["id"]),
424
+ ...optionalString("source", parsed.flags["source"]),
425
+ ...optionalString("summary", parsed.flags["summary"]),
426
+ ...optionalString("cards", parsed.flags["cards"])
427
+ }), parsed.json);
428
+ return;
429
+ }
430
+ if (parsed.subcommand === "list") {
431
+ output(listIngestRecords(projectRoot, stringFlag(parsed.flags["kind"])), parsed.json);
432
+ return;
433
+ }
434
+ if (parsed.subcommand === "show") {
435
+ output(showIngestRecord(projectRoot, stringFlag(parsed.flags["ref"])), parsed.json);
436
+ return;
437
+ }
438
+ throw new Error("ingest requires subcommand: record, list, or show");
439
+ }
367
440
  function handleVisual(projectRoot, parsed) {
368
441
  if (parsed.subcommand === "compare") {
369
442
  const result = compareVisualArtifacts(projectRoot, {
@@ -424,7 +497,7 @@ function handleRepair(projectRoot, parsed) {
424
497
  }
425
498
  function handleSkills(projectRoot, parsed) {
426
499
  if (parsed.subcommand === "list") {
427
- output({ skills: discoverSkills(projectRoot) }, parsed.json);
500
+ output(listSkills(projectRoot), parsed.json);
428
501
  return;
429
502
  }
430
503
  if (parsed.subcommand === "check") {
@@ -458,6 +531,18 @@ function handleKnowledge(projectRoot, parsed) {
458
531
  }), parsed.json);
459
532
  return;
460
533
  }
534
+ if (parsed.subcommand === "draft") {
535
+ output(draftKnowledgeFromIngest(projectRoot, {
536
+ ...optionalString("ref", parsed.flags["ref"])
537
+ }), parsed.json);
538
+ return;
539
+ }
540
+ if (parsed.subcommand === "outline") {
541
+ output(outlineKnowledgeFromIngest(projectRoot, {
542
+ ...optionalString("ref", parsed.flags["ref"])
543
+ }), parsed.json);
544
+ return;
545
+ }
461
546
  if (parsed.subcommand === "promote") {
462
547
  output(promoteKnowledge(projectRoot, {
463
548
  ...optionalString("title", parsed.flags["title"]),
@@ -546,7 +631,7 @@ function handleKnowledge(projectRoot, parsed) {
546
631
  process.exitCode = result.status === "failed" ? 1 : 0;
547
632
  return;
548
633
  }
549
- throw new Error("knowledge requires subcommand: add, promote, module, update, index, coverage, list, search, show, or check");
634
+ throw new Error("knowledge requires subcommand: add, outline, draft, promote, module, update, index, coverage, list, search, show, or check");
550
635
  }
551
636
  function requireSubcommand(parsed, subcommand, message) {
552
637
  if (parsed.subcommand !== subcommand) {
@@ -617,12 +702,13 @@ function allowedFlags(parsed) {
617
702
  const global = ["json", "help"];
618
703
  const commandFlags = {
619
704
  init: ["dry-run", "check"],
620
- context: [],
705
+ context: parsed.subcommand === "task" ? ["limit", "prd", "api-source", "ui-source"] : [],
621
706
  clean: ["dry-run", "keep-logs"],
622
- plan: ["prd", "ui-source", "agent-proposal"],
707
+ plan: ["prd", "api-source", "ui-source", "agent-proposal"],
623
708
  verify: ["typecheck", "test", "build"],
624
709
  visual: parsed.subcommand === "compare" ? ["design", "actual", "diff", "report", "threshold"] : [],
625
710
  evidence: parsed.subcommand === "record" ? ["file"] : [],
711
+ ingest: ingestFlags(parsed.subcommand),
626
712
  state: parsed.subcommand === "record-change" ? ["from-git"] : [],
627
713
  knowledge: knowledgeFlags(parsed.subcommand),
628
714
  protocol: [],
@@ -648,6 +734,9 @@ function knowledgeFlags(subcommand) {
648
734
  switch (subcommand) {
649
735
  case "add":
650
736
  return ["id", "kind", "subject", "summary", ...atomicContent, ...traceability, ...lifecycle];
737
+ case "outline":
738
+ case "draft":
739
+ return ["ref"];
651
740
  case "promote":
652
741
  return ["title", "body", "type", ...lifecycle];
653
742
  case "module":
@@ -669,6 +758,20 @@ function knowledgeFlags(subcommand) {
669
758
  return [];
670
759
  }
671
760
  }
761
+ function ingestFlags(subcommand) {
762
+ switch (subcommand) {
763
+ case "record":
764
+ return ["kind", "id", "source", "summary", "cards"];
765
+ case "list":
766
+ return ["kind"];
767
+ case "show":
768
+ return ["ref"];
769
+ case undefined:
770
+ return [];
771
+ default:
772
+ return [];
773
+ }
774
+ }
672
775
  function output(value, json) {
673
776
  if (json) {
674
777
  console.log(JSON.stringify(value, null, 2));
@@ -676,63 +779,199 @@ function output(value, json) {
676
779
  }
677
780
  console.log(renderHuman(value));
678
781
  }
782
+ const MAX_HUMAN_FIELD_CHARS = 240;
783
+ const MAX_HUMAN_PROMPT_CHARS = 4_000;
784
+ function humanField(value) {
785
+ const normalized = normalizeHumanField(value);
786
+ return normalized.length > MAX_HUMAN_FIELD_CHARS
787
+ ? `${normalized.slice(0, MAX_HUMAN_FIELD_CHARS - 3)}...`
788
+ : normalized;
789
+ }
790
+ function humanFieldTruncated(value) {
791
+ return normalizeHumanField(value).length > MAX_HUMAN_FIELD_CHARS;
792
+ }
793
+ function normalizeHumanField(value) {
794
+ return String(value ?? "unknown").replace(/\s+/g, " ").trim();
795
+ }
796
+ function humanBlock(value, maxChars) {
797
+ const text = String(value ?? "").trimEnd();
798
+ return text.length > maxChars ? `${text.slice(0, maxChars - 3)}...` : text;
799
+ }
800
+ function humanBlockTruncated(value, maxChars) {
801
+ return String(value ?? "").trimEnd().length > maxChars;
802
+ }
679
803
  function renderHuman(value) {
680
804
  if (!isRecord(value)) {
681
805
  return String(value);
682
806
  }
683
807
  if ("projectRoot" in value && "detectedStack" in value) {
684
808
  const context = value;
809
+ const knowledgeLimit = context.projectStatus?.knowledgeLimits;
810
+ const skillLimit = context.projectStatus?.skillLimits;
811
+ const planningDecision = context.projectStatus?.planningDecision;
812
+ const proposalLimits = planningDecision?.limits;
813
+ const evidence = planningDecision?.planningEvidence;
685
814
  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")}`
815
+ `projectRoot: ${humanField(context.projectRoot ?? "unknown")}`,
816
+ `packageManager: ${humanField(context.detectedStack?.packageManager ?? "unknown")}`,
817
+ `framework: ${humanField(context.detectedStack?.framework ?? "unknown")}`,
818
+ `language: ${humanField(context.detectedStack?.language ?? "unknown")}`,
819
+ `knowledge: ${Array.isArray(context.projectStatus?.knowledge) ? context.projectStatus.knowledge.length : 0}/${String(knowledgeLimit?.total ?? "unknown")}`,
820
+ `omittedKnowledge: ${String(knowledgeLimit?.omitted ?? 0)}`,
821
+ `skills: ${Array.isArray(context.projectStatus?.skills) ? context.projectStatus.skills.length : 0}/${String(skillLimit?.total ?? "unknown")}`,
822
+ `omittedSkills: ${String(skillLimit?.omitted ?? 0)}`,
823
+ ...(planningDecision ? [
824
+ `planningDecision: ${humanField(planningDecision.artifactPath ?? "unknown")}`,
825
+ `planningConstraintHints: ${String(proposalLimits?.constraintHints?.selected ?? (Array.isArray(planningDecision.constraintHints) ? planningDecision.constraintHints.length : 0))}/${String(proposalLimits?.constraintHints?.max ?? "unknown")}`,
826
+ `planningComponentHints: ${String(proposalLimits?.componentHints?.selected ?? (Array.isArray(planningDecision.componentHints) ? planningDecision.componentHints.length : 0))}/${String(proposalLimits?.componentHints?.max ?? "unknown")}`,
827
+ `planningWorkflowCandidates: ${String(proposalLimits?.workflowCandidates?.selected ?? (Array.isArray(evidence?.workflowCandidates) ? evidence.workflowCandidates.length : 0))}/${String(proposalLimits?.workflowCandidates?.max ?? "unknown")}`,
828
+ `planningTargetCandidates: ${String(proposalLimits?.targetCandidates?.selected ?? (Array.isArray(evidence?.targetCandidates) ? evidence.targetCandidates.length : 0))}/${String(proposalLimits?.targetCandidates?.max ?? "unknown")}`,
829
+ `planningVerificationCandidates: ${String(proposalLimits?.verificationCandidates?.selected ?? (Array.isArray(evidence?.verificationCandidates) ? evidence.verificationCandidates.length : 0))}/${String(proposalLimits?.verificationCandidates?.max ?? "unknown")}`,
830
+ `planningAmbiguities: ${String(proposalLimits?.ambiguities?.selected ?? (Array.isArray(evidence?.ambiguities) ? evidence.ambiguities.length : 0))}/${String(proposalLimits?.ambiguities?.max ?? "unknown")}`
831
+ ] : [])
690
832
  ].join("\n");
691
833
  }
692
834
  if ("task" in value && "units" in value && Array.isArray(value["units"])) {
693
835
  const plan = value;
836
+ const guidanceLimits = plan.limits?.guidance;
694
837
  return [
695
- `intent: ${String(plan.task?.intent ?? "unknown")}`,
696
- `scope: ${String(plan.task?.scope ?? "unknown")}`,
697
- `units: ${plan.units.length}`
838
+ `intent: ${humanField(plan.task?.intent)}`,
839
+ `scope: ${humanField(plan.task?.scope)}`,
840
+ `components: ${Array.isArray(plan.components) ? plan.components.length : 0}`,
841
+ `units: ${plan.units.length}`,
842
+ `guidanceComponents: ${String(guidanceLimits?.components?.selected ?? "unknown")}/${String(guidanceLimits?.components?.total ?? "unknown")}`,
843
+ `omittedGuidanceComponents: ${String(guidanceLimits?.components?.omitted ?? 0)}`,
844
+ `guidanceUnits: ${String(guidanceLimits?.units?.selected ?? "unknown")}/${String(guidanceLimits?.units?.total ?? "unknown")}`,
845
+ `omittedGuidanceUnits: ${String(guidanceLimits?.units?.omitted ?? 0)}`,
846
+ `guidancePath: ${humanField(plan.guidancePath ?? "unknown")}`,
847
+ `componentGraphPath: ${humanField(plan.componentGraphPath ?? "unknown")}`,
848
+ `statePath: ${humanField(plan.statePath ?? "unknown")}`
849
+ ].join("\n");
850
+ }
851
+ if ("task" in value && "workflow" in value && "prompt" in value) {
852
+ const taskContext = value;
853
+ const sourceHintCount = [
854
+ taskContext.sourceHints?.endpoints,
855
+ taskContext.sourceHints?.prdCoverage,
856
+ taskContext.sourceHints?.uiArtifacts,
857
+ taskContext.sourceHints?.apiImplementations
858
+ ].reduce((total, group) => total + (Array.isArray(group) ? group.length : 0), 0);
859
+ const prompt = String(taskContext.prompt ?? "");
860
+ return [
861
+ `task: ${humanField(taskContext.task)}`,
862
+ `workflow: ${humanField(taskContext.workflow?.kind)}`,
863
+ `knowledge: ${Array.isArray(taskContext.selectedKnowledge) ? taskContext.selectedKnowledge.length : 0}`,
864
+ `ingestSources: ${Array.isArray(taskContext.selectedIngestSources) ? taskContext.selectedIngestSources.length : 0}`,
865
+ `projectFiles: ${Array.isArray(taskContext.selectedProjectFiles) ? taskContext.selectedProjectFiles.length : 0}`,
866
+ `sourceHints: ${sourceHintCount}`,
867
+ `omittedKnowledge: ${String(taskContext.limits?.omittedSelectedKnowledge ?? 0)}`,
868
+ `omittedKnowledgeSourcePaths: ${String(taskContext.limits?.omittedSelectedKnowledgeSourcePaths ?? 0)}`,
869
+ `omittedKnowledgeCoverage: ${String(taskContext.limits?.omittedSelectedKnowledgeCoverage ?? 0)}`,
870
+ `omittedKnowledgeVerification: ${String(taskContext.limits?.omittedSelectedKnowledgeVerification ?? 0)}`,
871
+ `omittedIngestSources: ${String(taskContext.limits?.omittedSelectedIngestSources ?? 0)}`,
872
+ `omittedIngestProducedKnowledgeCardIds: ${String(taskContext.limits?.omittedSelectedIngestProducedKnowledgeCardIds ?? 0)}`,
873
+ `omittedProjectFiles: ${String(taskContext.limits?.omittedSelectedProjectFiles ?? 0)}`,
874
+ `omittedSourceHints: ${String(taskContext.limits?.omittedSourceHints ?? 0)}`,
875
+ `omittedPrdCoverageHintCoverage: ${String(taskContext.limits?.omittedPrdCoverageHintCoverage ?? 0)}`,
876
+ `omittedPrdCoverageHintAnchors: ${String(taskContext.limits?.omittedPrdCoverageHintAnchors ?? 0)}`,
877
+ `omittedPrdCoverageHintSourcePaths: ${String(taskContext.limits?.omittedPrdCoverageHintSourcePaths ?? 0)}`,
878
+ `projectFilesScanned: ${String(taskContext.limits?.totalScannedProjectFiles ?? 0)}/${String(taskContext.limits?.scannedProjectFiles ?? "unknown")}`,
879
+ `projectFileScanLimitReached: ${String(taskContext.limits?.projectFileScanLimitReached ?? false)}`,
880
+ `skippedPrdSourceHintSources: ${String(taskContext.limits?.skippedPrdSourceHintSources ?? 0)}`,
881
+ `skippedApiSourceHintSources: ${String(taskContext.limits?.skippedApiSourceHintSources ?? 0)}`,
882
+ `artifactPath: ${humanField(taskContext.artifactPath ?? "unknown")}`,
883
+ `promptChars: ${String(prompt.length)}`,
884
+ `promptTruncated: ${String(humanBlockTruncated(prompt, MAX_HUMAN_PROMPT_CHARS))}`,
885
+ "",
886
+ humanBlock(prompt, MAX_HUMAN_PROMPT_CHARS)
698
887
  ].join("\n");
699
888
  }
700
889
  if ("results" in value && Array.isArray(value["results"])) {
701
890
  const verification = value;
891
+ const selectedResults = verification.results.slice(0, MAX_HUMAN_VERIFICATION_RESULTS);
892
+ const omittedResults = Math.max(0, verification.results.length - selectedResults.length);
702
893
  return [
703
- `status: ${String(verification.status ?? "unknown")}`,
894
+ `status: ${humanField(verification.status ?? "unknown")}`,
704
895
  `results: ${verification.results.length}`,
705
- ...verification.results.map((item) => `- ${String(item.name ?? "verification")}: ${String(item.status ?? "unknown")} (${String(item.exitCode ?? "n/a")})`)
896
+ `omittedResults: ${String(omittedResults)}`,
897
+ ...selectedResults.map((item) => `- ${humanField(item.name ?? "verification")}: ${humanField(item.status ?? "unknown")} (${String(item.exitCode ?? "n/a")})`)
898
+ ].join("\n");
899
+ }
900
+ if ("manifestPath" in value && "entries" in value && "instructions" in value) {
901
+ const template = value;
902
+ const entryLimits = template.limits?.entries;
903
+ return [
904
+ `status: ${humanField(template.status ?? "unknown")}`,
905
+ `manifestPath: ${humanField(template.manifestPath ?? "unknown")}`,
906
+ `entries: ${String(entryLimits?.selected ?? (Array.isArray(template.entries) ? template.entries.length : 0))}/${String(entryLimits?.total ?? (Array.isArray(template.entries) ? template.entries.length : 0))}`,
907
+ `omittedEntries: ${String(entryLimits?.omitted ?? 0)}`
908
+ ].join("\n");
909
+ }
910
+ if ("recordedEntries" in value && "entryCount" in value && "provenance" in value) {
911
+ const evidence = value;
912
+ const selectedSourceLimit = evidence.provenance?.limits?.selectedEvidenceSources ?? "unknown";
913
+ return [
914
+ `status: ${humanField(evidence.status ?? "unknown")}`,
915
+ `inputPath: ${humanField(evidence.inputPath ?? "unknown")}`,
916
+ `manifestPath: ${humanField(evidence.manifestPath ?? "unknown")}`,
917
+ `recordedEntries: ${Array.isArray(evidence.recordedEntries) ? evidence.recordedEntries.length : 0}`,
918
+ `entryCount: ${String(evidence.entryCount ?? 0)}`,
919
+ `planArtifactPath: ${humanField(evidence.provenance?.planArtifactPath ?? "none")}`,
920
+ `taskContextArtifactPath: ${humanField(evidence.provenance?.taskContextArtifactPath ?? "none")}`,
921
+ `selectedApiContractSources: ${Array.isArray(evidence.provenance?.selectedApiContractSources) ? evidence.provenance.selectedApiContractSources.length : 0}/${String(selectedSourceLimit)}`,
922
+ `omittedSelectedApiContractSources: ${String(evidence.provenance?.limits?.omittedSelectedApiContractSources ?? 0)}`,
923
+ `selectedUiSources: ${Array.isArray(evidence.provenance?.selectedUiSources) ? evidence.provenance.selectedUiSources.length : 0}/${String(selectedSourceLimit)}`,
924
+ `omittedSelectedUiSources: ${String(evidence.provenance?.limits?.omittedSelectedUiSources ?? 0)}`,
925
+ `selectedIngestSources: ${Array.isArray(evidence.provenance?.selectedIngestSources) ? evidence.provenance.selectedIngestSources.length : 0}/${String(selectedSourceLimit)}`,
926
+ `omittedSelectedIngestSources: ${String(evidence.provenance?.limits?.omittedSelectedIngestSources ?? 0)}`
706
927
  ].join("\n");
707
928
  }
708
929
  if ("comparisonTool" in value && "score" in value) {
709
930
  const comparison = value;
710
931
  return [
711
- `status: ${String(comparison.status ?? "unknown")}`,
932
+ `status: ${humanField(comparison.status ?? "unknown")}`,
712
933
  `score: ${String(comparison.score ?? "unknown")}`,
713
934
  `threshold: ${String(comparison.threshold ?? "unknown")}`,
714
935
  `changedPixels: ${String(comparison.changedPixels ?? "unknown")}`,
715
936
  `changedRatio: ${String(comparison.changedRatio ?? "unknown")}`,
716
- `diffPath: ${String(comparison.diffPath ?? "unknown")}`,
937
+ `diffPath: ${humanField(comparison.diffPath ?? "unknown")}`,
717
938
  ...(Array.isArray(comparison.limitations) && comparison.limitations.length
718
- ? [`limitations: ${comparison.limitations.map((item) => String(item)).join(" ")}`]
939
+ ? [`limitations: ${comparison.limitations.map((item) => humanField(item)).join(" ")}`]
719
940
  : [])
720
941
  ].join("\n");
721
942
  }
722
943
  if ("action" in value && "stateStatus" in value) {
723
944
  const next = value;
945
+ const changedFileLimit = next.limits?.changedFiles;
946
+ return [
947
+ `action: ${humanField(next.action ?? "unknown")}`,
948
+ `reason: ${humanField(next.reason ?? "unknown")}`,
949
+ `command: ${humanField(next.command ?? "none")}`,
950
+ `changedFiles: ${String(changedFileLimit?.selected ?? (Array.isArray(next.changedFiles) ? next.changedFiles.length : 0))}/${String(changedFileLimit?.total ?? (Array.isArray(next.changedFiles) ? next.changedFiles.length : 0))}`,
951
+ `omittedChangedFiles: ${String(changedFileLimit?.omitted ?? 0)}`
952
+ ].join("\n");
953
+ }
954
+ if ("nextAction" in value && "requiredArtifacts" in value && "recommendedCommands" in value) {
955
+ const explain = value;
956
+ const markdownLimits = explain.limits?.markdown;
724
957
  return [
725
- `action: ${String(next.action ?? "unknown")}`,
726
- `reason: ${String(next.reason ?? "unknown")}`,
727
- `command: ${String(next.command ?? "none")}`
958
+ `action: ${humanField(explain.nextAction?.action ?? "unknown")}`,
959
+ `summary: ${humanField(explain.summary ?? "unknown")}`,
960
+ `rationale: ${String(markdownLimits?.rationale?.selected ?? "unknown")}/${String(markdownLimits?.rationale?.total ?? "unknown")}`,
961
+ `omittedRationale: ${String(markdownLimits?.rationale?.omitted ?? 0)}`,
962
+ `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))}`,
963
+ `omittedRequiredArtifacts: ${String(markdownLimits?.requiredArtifacts?.omitted ?? 0)}`,
964
+ `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))}`,
965
+ `omittedRecommendedCommands: ${String(markdownLimits?.recommendedCommands?.omitted ?? 0)}`,
966
+ `stopCondition: ${humanField(explain.stopCondition ?? "unknown")}`
728
967
  ].join("\n");
729
968
  }
730
969
  if ("changedFiles" in value && "verification" in value) {
731
970
  const state = value;
732
971
  return [
733
- `status: ${String(state.status ?? "unknown")}`,
972
+ `status: ${humanField(state.status ?? "unknown")}`,
734
973
  `changedFiles: ${Array.isArray(state.changedFiles) ? state.changedFiles.length : 0}`,
735
- `verification: ${String(state.verification?.status ?? "unknown")}`,
974
+ `verification: ${humanField(state.verification?.status ?? "unknown")}`,
736
975
  `retryCount: ${String(state.retryCount ?? 0)}`
737
976
  ].join("\n");
738
977
  }
@@ -746,50 +985,116 @@ function renderHuman(value) {
746
985
  }
747
986
  if ("skills" in value && Array.isArray(value["skills"])) {
748
987
  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");
988
+ const limits = value["limits"];
989
+ const selected = limits?.selected ?? skills.length;
990
+ const total = limits?.total ?? skills.length;
991
+ return [
992
+ `skills: ${String(selected)}/${String(total)}`,
993
+ `omittedSkills: ${String(limits?.omitted ?? 0)}`,
994
+ ...skills.map((skill) => `- ${humanField(skill.name)}: ${humanField(skill.title)} (${humanField(skill.path)})`)
995
+ ].join("\n");
750
996
  }
751
- if ("cards" in value && Array.isArray(value["cards"])) {
752
- const cards = value["cards"];
997
+ if ("records" in value && Array.isArray(value["records"])) {
998
+ const records = value["records"];
999
+ const limits = value["limits"];
1000
+ const selected = limits?.selected ?? records.length;
1001
+ const total = limits?.total ?? records.length;
753
1002
  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
- })
1003
+ `records: ${String(selected)}/${String(total)}`,
1004
+ `omittedRecords: ${String(limits?.omitted ?? 0)}`,
1005
+ ...records.map((record) => `- ${humanField(record.ingestRef)}: ${humanField(record.summary)} (${humanField(record.artifactPath)})`)
759
1006
  ].join("\n");
760
1007
  }
761
- if ("card" in value && "body" in value) {
762
- const shown = value;
1008
+ if ("ingestRef" in value && "source" in value && "producedKnowledgeCardIds" in value) {
1009
+ const record = value;
763
1010
  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 ?? "")
1011
+ `ingestRef: ${humanField(record.ingestRef)}`,
1012
+ `kind: ${humanField(record.kind)}`,
1013
+ `source: ${humanField(record.source?.value)}`,
1014
+ `sha256: ${humanField(record.source?.sha256 ?? "none")}`,
1015
+ `cards: ${Array.isArray(record.producedKnowledgeCardIds) ? record.producedKnowledgeCardIds.length : 0}`,
1016
+ `artifactPath: ${humanField(record.artifactPath)}`
769
1017
  ].join("\n");
770
1018
  }
771
1019
  if ("artifactPath" in value && "prdSourceCount" in value) {
772
1020
  const index = value;
1021
+ const cardLimits = index.limits?.cards;
773
1022
  return [
774
- `artifactPath: ${String(index.artifactPath ?? "unknown")}`,
1023
+ `artifactPath: ${humanField(index.artifactPath ?? "unknown")}`,
775
1024
  `cardCount: ${String(index.cardCount ?? 0)}`,
1025
+ `cards: ${String(cardLimits?.selected ?? index.cardCount ?? 0)}/${String(cardLimits?.total ?? index.cardCount ?? 0)}`,
1026
+ `omittedCards: ${String(cardLimits?.omitted ?? 0)}`,
776
1027
  `prdSourceCount: ${String(index.prdSourceCount ?? 0)}`,
777
1028
  `uncoveredPrdSourceCount: ${String(index.uncoveredPrdSourceCount ?? 0)}`
778
1029
  ].join("\n");
779
1030
  }
1031
+ if ("cards" in value && Array.isArray(value["cards"])) {
1032
+ const cards = value["cards"];
1033
+ const limits = value["limits"];
1034
+ const selected = limits?.selected ?? cards.length;
1035
+ const total = limits?.total ?? cards.length;
1036
+ return [
1037
+ `cards: ${String(selected)}${limits ? `/${String(total)}` : ""}`,
1038
+ ...(limits ? [`omittedCards: ${String(limits.omitted ?? 0)}`] : []),
1039
+ ...cards.map((card) => {
1040
+ const score = card.score === undefined ? "" : ` score=${String(card.score)}`;
1041
+ return `- ${humanField(card.id)}: ${humanField(card.title)} (${humanField(card.path)})${score}`;
1042
+ })
1043
+ ].join("\n");
1044
+ }
1045
+ if ("card" in value && "body" in value) {
1046
+ const shown = value;
1047
+ const body = String(shown.body ?? "");
1048
+ return [
1049
+ `id: ${humanField(shown.card?.id)}`,
1050
+ `title: ${humanField(shown.card?.title)}`,
1051
+ `path: ${humanField(shown.card?.path)}`,
1052
+ `bodyChars: ${String(body.length)}`,
1053
+ `bodyTruncated: ${String(humanFieldTruncated(body))}`,
1054
+ "",
1055
+ humanField(body)
1056
+ ].join("\n");
1057
+ }
780
1058
  if ("coveredPrdSourceCount" in value && "uncoveredPrdSources" in value) {
781
1059
  const coverage = value;
782
1060
  return [
783
- `status: ${String(coverage.status ?? "unknown")}`,
1061
+ `status: ${humanField(coverage.status ?? "unknown")}`,
784
1062
  `prdSourceCount: ${String(coverage.prdSourceCount ?? 0)}`,
785
1063
  `coveredPrdSourceCount: ${String(coverage.coveredPrdSourceCount ?? 0)}`,
786
1064
  `uncoveredPrdSources: ${Array.isArray(coverage.uncoveredPrdSources) ? coverage.uncoveredPrdSources.length : 0}`,
787
1065
  `cardsWithoutSource: ${Array.isArray(coverage.cardsWithoutSource) ? coverage.cardsWithoutSource.length : 0}`
788
1066
  ].join("\n");
789
1067
  }
1068
+ if ("outline" in value && "sourceType" in value && "ingestRef" in value) {
1069
+ const outline = value;
1070
+ const headingLimits = outline.limits?.headings;
1071
+ const headings = Array.isArray(outline.outline) ? outline.outline : [];
1072
+ return [
1073
+ `ingestRef: ${humanField(outline.ingestRef ?? "unknown")}`,
1074
+ `source: ${humanField(outline.source ?? "unknown")}`,
1075
+ `headings: ${String(headingLimits?.selected ?? headings.length)}/${String(headingLimits?.total ?? headings.length)}`,
1076
+ `omittedHeadings: ${String(headingLimits?.omitted ?? 0)}`,
1077
+ ...headings.slice(0, 12).map((heading) => `- h${String(heading.level ?? "?")} ${humanField(heading.title)} kind=${humanField(heading.suggestedKind)} required=${String(heading.extractionRequired ?? false)} coverage=${humanField(heading.coverage)}`)
1078
+ ].join("\n");
1079
+ }
790
1080
  if ("path" in value && "title" in value) {
791
1081
  const knowledge = value;
792
- return [`path: ${String(knowledge.path ?? "unknown")}`, `title: ${String(knowledge.title ?? "unknown")}`, `createdAt: ${String(knowledge.createdAt ?? "unknown")}`].join("\n");
1082
+ return [`path: ${humanField(knowledge.path)}`, `title: ${humanField(knowledge.title)}`, `createdAt: ${humanField(knowledge.createdAt)}`].join("\n");
1083
+ }
1084
+ if ("ingestRef" in value && "recommendedAction" in value && "updateCandidates" in value) {
1085
+ const draft = value;
1086
+ const candidateLimits = draft.limits?.updateCandidates;
1087
+ const extractionLimits = draft.limits?.extractionItems;
1088
+ return [
1089
+ `ingestRef: ${humanField(draft.ingestRef ?? "unknown")}`,
1090
+ `recommendedAction: ${humanField(draft.recommendedAction ?? "unknown")}`,
1091
+ `recommendedKind: ${humanField(draft.recommendedKind ?? "unknown")}`,
1092
+ `recommendedType: ${humanField(draft.recommendedType ?? "unknown")}`,
1093
+ `updateCandidates: ${String(candidateLimits?.selected ?? (Array.isArray(draft.updateCandidates) ? draft.updateCandidates.length : 0))}/${String(candidateLimits?.total ?? (Array.isArray(draft.updateCandidates) ? draft.updateCandidates.length : 0))}`,
1094
+ `omittedUpdateCandidates: ${String(candidateLimits?.omitted ?? 0)}`,
1095
+ `extractionItems: ${String(extractionLimits?.selected ?? (Array.isArray(draft.extractionItems) ? draft.extractionItems.length : 0))}/${String(extractionLimits?.total ?? (Array.isArray(draft.extractionItems) ? draft.extractionItems.length : 0))}`,
1096
+ `omittedExtractionItems: ${String(extractionLimits?.omitted ?? 0)}`
1097
+ ].join("\n");
793
1098
  }
794
1099
  if ("artifactPath" in value && "unitCount" in value) {
795
1100
  return renderCheck(value, "unitCount");
@@ -797,30 +1102,53 @@ function renderHuman(value) {
797
1102
  if ("artifactPath" in value && "nodeCount" in value) {
798
1103
  return renderCheck(value, "nodeCount");
799
1104
  }
1105
+ if ("artifactPath" in value && "proposal" in value) {
1106
+ const checked = value;
1107
+ const evidence = checked.proposal?.planningEvidence;
1108
+ return [
1109
+ `status: ${humanField(checked.status ?? "unknown")}`,
1110
+ `artifactPath: ${humanField(checked.artifactPath)}`,
1111
+ `constraintHints: ${String(checked.limits?.constraintHints?.selected ?? (Array.isArray(checked.proposal?.constraintHints) ? checked.proposal.constraintHints.length : 0))}/${String(checked.limits?.constraintHints?.max ?? "unknown")}`,
1112
+ `componentHints: ${String(checked.limits?.componentHints?.selected ?? (Array.isArray(checked.proposal?.componentHints) ? checked.proposal.componentHints.length : 0))}/${String(checked.limits?.componentHints?.max ?? "unknown")}`,
1113
+ `workflowCandidates: ${String(checked.limits?.workflowCandidates?.selected ?? (Array.isArray(evidence?.workflowCandidates) ? evidence.workflowCandidates.length : 0))}/${String(checked.limits?.workflowCandidates?.max ?? "unknown")}`,
1114
+ `targetCandidates: ${String(checked.limits?.targetCandidates?.selected ?? (Array.isArray(evidence?.targetCandidates) ? evidence.targetCandidates.length : 0))}/${String(checked.limits?.targetCandidates?.max ?? "unknown")}`,
1115
+ `verificationCandidates: ${String(checked.limits?.verificationCandidates?.selected ?? (Array.isArray(evidence?.verificationCandidates) ? evidence.verificationCandidates.length : 0))}/${String(checked.limits?.verificationCandidates?.max ?? "unknown")}`,
1116
+ `ambiguities: ${String(checked.limits?.ambiguities?.selected ?? (Array.isArray(evidence?.ambiguities) ? evidence.ambiguities.length : 0))}/${String(checked.limits?.ambiguities?.max ?? "unknown")}`,
1117
+ ...(Array.isArray(checked.errors) && checked.errors.length ? checked.errors.map((error) => `error: ${humanField(error)}`) : [])
1118
+ ].join("\n");
1119
+ }
800
1120
  if ("skillsRoot" in value && "skillCount" in value) {
801
1121
  return renderCheck(value, "skillCount");
802
1122
  }
803
1123
  if ("knowledgeRoot" in value && "cardCount" in value) {
804
1124
  return renderCheck(value, "cardCount");
805
1125
  }
806
- if ("artifactPath" in value && ("proposal" in value || "decision" in value)) {
1126
+ if ("artifactPath" in value && "decision" in value) {
807
1127
  return renderCheck(value, null);
808
1128
  }
809
1129
  if ("contractVersion" in value && "failedCommands" in value) {
810
1130
  const packet = value;
811
1131
  return [
812
- `status: ${String(packet.status ?? "unknown")}`,
813
- `verificationStatus: ${String(packet.verificationStatus ?? "unknown")}`,
814
- `failedCommands: ${Array.isArray(packet.failedCommands) ? packet.failedCommands.length : 0}`
1132
+ `status: ${humanField(packet.status ?? "unknown")}`,
1133
+ `verificationStatus: ${humanField(packet.verificationStatus ?? "unknown")}`,
1134
+ `changedFiles: ${Array.isArray(packet.changedFiles) ? packet.changedFiles.length : 0}/${String(packet.limits?.totalChangedFiles ?? "unknown")}`,
1135
+ `omittedChangedFiles: ${String(packet.limits?.omittedChangedFiles ?? 0)}`,
1136
+ `failedCommands: ${Array.isArray(packet.failedCommands) ? packet.failedCommands.length : 0}/${String(packet.limits?.totalFailedCommands ?? "unknown")}`,
1137
+ `omittedFailedCommands: ${String(packet.limits?.omittedFailedCommands ?? 0)}`,
1138
+ `retryGuidanceFailedCommands: ${Array.isArray(packet.retryGuidance?.failedCommands) ? packet.retryGuidance.failedCommands.length : 0}/${String(packet.limits?.totalRetryGuidanceFailedCommands ?? "unknown")}`,
1139
+ `omittedRetryGuidanceFailedCommands: ${String(packet.limits?.omittedRetryGuidanceFailedCommands ?? 0)}`,
1140
+ `retryGuidanceLogs: ${Array.isArray(packet.retryGuidance?.logs) ? packet.retryGuidance.logs.length : 0}/${String(packet.limits?.totalRetryGuidanceLogs ?? "unknown")}`,
1141
+ `omittedRetryGuidanceLogs: ${String(packet.limits?.omittedRetryGuidanceLogs ?? 0)}`,
1142
+ `retryGuidanceInstructionTruncated: ${String(packet.limits?.retryGuidanceInstructionTruncated ?? false)}`
815
1143
  ].join("\n");
816
1144
  }
817
1145
  if ("contractVersion" in value && "files" in value) {
818
1146
  const init = value;
819
1147
  return [
820
1148
  `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")}`) : [])
1149
+ `needsUpdate: ${humanField(init.needsUpdate ?? "unknown")}`,
1150
+ ...(Array.isArray(init.files) ? init.files.map((file) => `${humanField(file.path ?? "unknown")}: ${humanField(file.action ?? "unknown")}`) : []),
1151
+ ...(Array.isArray(init.skills) ? init.skills.map((skill) => `${humanField(skill.path ?? "unknown")}: ${humanField(skill.action ?? "unknown")}`) : [])
824
1152
  ].join("\n");
825
1153
  }
826
1154
  if ("removed" in value && "kept" in value) {
@@ -834,30 +1162,36 @@ function renderHuman(value) {
834
1162
  if ("preset" in value && "files" in value && Array.isArray(value["files"])) {
835
1163
  const scaffold = value;
836
1164
  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")}`,
1165
+ `status: ${humanField(scaffold.status ?? "unknown")}`,
1166
+ `preset: ${humanField(scaffold.preset ?? "unknown")}`,
1167
+ `target: ${humanField(scaffold.target ?? "unknown")}`,
1168
+ `projectName: ${humanField(scaffold.projectName ?? "unknown")}`,
841
1169
  `files: ${scaffold.files.length}`
842
1170
  ].join("\n");
843
1171
  }
844
1172
  if ("status" in value) {
845
- return `status: ${String(value["status"])}`;
1173
+ return `status: ${humanField(value["status"])}`;
846
1174
  }
847
1175
  return JSON.stringify(value, null, 2);
848
1176
  }
849
1177
  function renderCheck(value, countKey) {
1178
+ const errors = Array.isArray(value["errors"]) ? value["errors"] : [];
1179
+ const warnings = Array.isArray(value["warnings"]) ? value["warnings"] : [];
1180
+ const selectedErrors = errors.slice(0, 5);
1181
+ const selectedWarnings = warnings.slice(0, 5);
850
1182
  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)}`] : [])
1183
+ `status: ${humanField(value["status"] ?? "unknown")}`,
1184
+ ...(value["artifactPath"] ? [`artifactPath: ${humanField(value["artifactPath"])}`] : []),
1185
+ ...(value["skillsRoot"] ? [`skillsRoot: ${humanField(value["skillsRoot"])}`] : []),
1186
+ ...(countKey ? [`${countKey}: ${String(value[countKey] ?? 0)}`] : []),
1187
+ `omittedErrors: ${String(Math.max(0, errors.length - selectedErrors.length))}`,
1188
+ `omittedWarnings: ${String(Math.max(0, warnings.length - selectedWarnings.length))}`
855
1189
  ];
856
- for (const error of (Array.isArray(value["errors"]) ? value["errors"] : []).slice(0, 5)) {
857
- lines.push(`error: ${String(error)}`);
1190
+ for (const error of selectedErrors) {
1191
+ lines.push(`error: ${humanField(error)}`);
858
1192
  }
859
- for (const warning of (Array.isArray(value["warnings"]) ? value["warnings"] : []).slice(0, 5)) {
860
- lines.push(`warning: ${String(warning)}`);
1193
+ for (const warning of selectedWarnings) {
1194
+ lines.push(`warning: ${humanField(warning)}`);
861
1195
  }
862
1196
  return lines.join("\n");
863
1197
  }