frontend-harness 0.7.9 → 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.
- package/CHANGELOG.md +29 -0
- package/README.md +20 -10
- package/dist/cli/index.js +388 -66
- package/dist/cli/index.js.map +1 -1
- package/dist/runtime/builtin-skills.js +1 -1
- package/dist/runtime/clean.js +25 -3
- package/dist/runtime/clean.js.map +1 -1
- package/dist/runtime/command-taxonomy.js +6 -1
- package/dist/runtime/command-taxonomy.js.map +1 -1
- package/dist/runtime/context.d.ts +33 -2
- package/dist/runtime/context.js +112 -13
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/evidence.d.ts +27 -0
- package/dist/runtime/evidence.js +302 -19
- package/dist/runtime/evidence.js.map +1 -1
- package/dist/runtime/graph.js +11 -4
- package/dist/runtime/graph.js.map +1 -1
- package/dist/runtime/ingest.d.ts +38 -0
- package/dist/runtime/ingest.js +157 -0
- package/dist/runtime/ingest.js.map +1 -0
- package/dist/runtime/knowledge/constants.d.ts +9 -0
- package/dist/runtime/knowledge/constants.js +25 -0
- package/dist/runtime/knowledge/constants.js.map +1 -0
- package/dist/runtime/knowledge/core.d.ts +25 -0
- package/dist/runtime/knowledge/core.js +1569 -0
- package/dist/runtime/knowledge/core.js.map +1 -0
- package/dist/runtime/knowledge/types.d.ts +241 -0
- package/dist/runtime/knowledge/types.js +2 -0
- package/dist/runtime/knowledge/types.js.map +1 -0
- package/dist/runtime/knowledge.d.ts +2 -188
- package/dist/runtime/knowledge.js +1 -1126
- package/dist/runtime/knowledge.js.map +1 -1
- package/dist/runtime/plan/component-resolver.js +17 -6
- package/dist/runtime/plan/component-resolver.js.map +1 -1
- package/dist/runtime/plan/guidance.d.ts +1 -1
- package/dist/runtime/plan/guidance.js +88 -25
- package/dist/runtime/plan/guidance.js.map +1 -1
- package/dist/runtime/plan/proposal.js +9 -0
- package/dist/runtime/plan/proposal.js.map +1 -1
- package/dist/runtime/plan/workflow.d.ts +1 -0
- package/dist/runtime/plan/workflow.js +32 -1
- package/dist/runtime/plan/workflow.js.map +1 -1
- package/dist/runtime/plan.d.ts +13 -0
- package/dist/runtime/plan.js +137 -82
- package/dist/runtime/plan.js.map +1 -1
- package/dist/runtime/policy-provenance.d.ts +17 -1
- package/dist/runtime/policy-provenance.js +84 -16
- package/dist/runtime/policy-provenance.js.map +1 -1
- package/dist/runtime/project-discovery.js +32 -17
- package/dist/runtime/project-discovery.js.map +1 -1
- package/dist/runtime/project-paths.js +7 -1
- package/dist/runtime/project-paths.js.map +1 -1
- package/dist/runtime/protocol-init.js +117 -26
- package/dist/runtime/protocol-init.js.map +1 -1
- package/dist/runtime/repair-decision.js +76 -16
- package/dist/runtime/repair-decision.js.map +1 -1
- package/dist/runtime/repair-packet.js +141 -20
- package/dist/runtime/repair-packet.js.map +1 -1
- package/dist/runtime/scaffold/vue-template.js +1 -1
- package/dist/runtime/scaffold/vue-template.js.map +1 -1
- package/dist/runtime/scaffold.js +44 -8
- package/dist/runtime/scaffold.js.map +1 -1
- package/dist/runtime/skills.d.ts +9 -0
- package/dist/runtime/skills.js +133 -18
- package/dist/runtime/skills.js.map +1 -1
- package/dist/runtime/state-explain.js +39 -7
- package/dist/runtime/state-explain.js.map +1 -1
- package/dist/runtime/state.js +85 -10
- package/dist/runtime/state.js.map +1 -1
- package/dist/runtime/task-context.d.ts +122 -0
- package/dist/runtime/task-context.js +1322 -0
- package/dist/runtime/task-context.js.map +1 -0
- package/dist/runtime/task-signals.d.ts +1 -0
- package/dist/runtime/task-signals.js +1 -1
- package/dist/runtime/task-signals.js.map +1 -1
- package/dist/runtime/ui-restoration.d.ts +3 -3
- package/dist/runtime/ui-restoration.js +3 -3
- package/dist/runtime/ui-restoration.js.map +1 -1
- package/dist/runtime/ui-source.d.ts +6 -0
- package/dist/runtime/ui-source.js +66 -0
- package/dist/runtime/ui-source.js.map +1 -0
- package/dist/runtime/units.js +11 -4
- package/dist/runtime/units.js.map +1 -1
- package/dist/runtime/verification-commands.js +95 -21
- package/dist/runtime/verification-commands.js.map +1 -1
- package/dist/runtime/verify.js +129 -43
- package/dist/runtime/verify.js.map +1 -1
- package/dist/runtime/visual-compare.js +104 -12
- package/dist/runtime/visual-compare.js.map +1 -1
- package/dist/schemas/types.d.ts +75 -2
- package/dist/schemas/validation.js +257 -6
- package/dist/schemas/validation.js.map +1 -1
- package/dist/storage/json.d.ts +9 -1
- package/dist/storage/json.js +106 -8
- package/dist/storage/json.js.map +1 -1
- package/docs/DIRECTION.md +13 -11
- package/docs/RELEASE.md +5 -1
- 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,
|
|
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
|
-
|
|
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, {
|
|
@@ -371,7 +435,7 @@ function handleVisual(projectRoot, parsed) {
|
|
|
371
435
|
...optionalString("actual", parsed.flags["actual"]),
|
|
372
436
|
...optionalString("diff", parsed.flags["diff"]),
|
|
373
437
|
...optionalString("report", parsed.flags["report"]),
|
|
374
|
-
...
|
|
438
|
+
...optionalFiniteNumber("threshold", parsed.flags["threshold"])
|
|
375
439
|
});
|
|
376
440
|
output(result, parsed.json);
|
|
377
441
|
process.exitCode = result.status === "failed" ? 1 : 0;
|
|
@@ -424,7 +488,7 @@ function handleRepair(projectRoot, parsed) {
|
|
|
424
488
|
}
|
|
425
489
|
function handleSkills(projectRoot, parsed) {
|
|
426
490
|
if (parsed.subcommand === "list") {
|
|
427
|
-
output(
|
|
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) {
|
|
@@ -563,6 +633,12 @@ function parseArgs(args) {
|
|
|
563
633
|
}
|
|
564
634
|
if (arg.startsWith("--")) {
|
|
565
635
|
const key = arg.slice(2);
|
|
636
|
+
if (key.includes("=")) {
|
|
637
|
+
throw new Error(`Unsupported flag assignment syntax: --${key}. Use --${key.split("=")[0]} <value>.`);
|
|
638
|
+
}
|
|
639
|
+
if (Object.prototype.hasOwnProperty.call(flags, key)) {
|
|
640
|
+
throw new Error(`Duplicate flag: --${key}`);
|
|
641
|
+
}
|
|
566
642
|
if (["json", "from-git", "dry-run", "check", "help", "force", "include-deprecated"].includes(key)) {
|
|
567
643
|
flags[key] = true;
|
|
568
644
|
}
|
|
@@ -611,12 +687,13 @@ function allowedFlags(parsed) {
|
|
|
611
687
|
const global = ["json", "help"];
|
|
612
688
|
const commandFlags = {
|
|
613
689
|
init: ["dry-run", "check"],
|
|
614
|
-
context: [],
|
|
690
|
+
context: parsed.subcommand === "task" ? ["limit", "prd", "api-source", "ui-source"] : [],
|
|
615
691
|
clean: ["dry-run", "keep-logs"],
|
|
616
|
-
plan: ["prd", "ui-source", "agent-proposal"],
|
|
692
|
+
plan: ["prd", "api-source", "ui-source", "agent-proposal"],
|
|
617
693
|
verify: ["typecheck", "test", "build"],
|
|
618
694
|
visual: parsed.subcommand === "compare" ? ["design", "actual", "diff", "report", "threshold"] : [],
|
|
619
695
|
evidence: parsed.subcommand === "record" ? ["file"] : [],
|
|
696
|
+
ingest: ingestFlags(parsed.subcommand),
|
|
620
697
|
state: parsed.subcommand === "record-change" ? ["from-git"] : [],
|
|
621
698
|
knowledge: knowledgeFlags(parsed.subcommand),
|
|
622
699
|
protocol: [],
|
|
@@ -642,6 +719,8 @@ function knowledgeFlags(subcommand) {
|
|
|
642
719
|
switch (subcommand) {
|
|
643
720
|
case "add":
|
|
644
721
|
return ["id", "kind", "subject", "summary", ...atomicContent, ...traceability, ...lifecycle];
|
|
722
|
+
case "draft":
|
|
723
|
+
return ["ref"];
|
|
645
724
|
case "promote":
|
|
646
725
|
return ["title", "body", "type", ...lifecycle];
|
|
647
726
|
case "module":
|
|
@@ -663,6 +742,20 @@ function knowledgeFlags(subcommand) {
|
|
|
663
742
|
return [];
|
|
664
743
|
}
|
|
665
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
|
+
}
|
|
666
759
|
function output(value, json) {
|
|
667
760
|
if (json) {
|
|
668
761
|
console.log(JSON.stringify(value, null, 2));
|
|
@@ -670,63 +763,199 @@ function output(value, json) {
|
|
|
670
763
|
}
|
|
671
764
|
console.log(renderHuman(value));
|
|
672
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
|
+
}
|
|
673
787
|
function renderHuman(value) {
|
|
674
788
|
if (!isRecord(value)) {
|
|
675
789
|
return String(value);
|
|
676
790
|
}
|
|
677
791
|
if ("projectRoot" in value && "detectedStack" in value) {
|
|
678
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;
|
|
679
798
|
return [
|
|
680
|
-
`projectRoot: ${
|
|
681
|
-
`packageManager: ${
|
|
682
|
-
`framework: ${
|
|
683
|
-
`language: ${
|
|
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
|
+
] : [])
|
|
684
816
|
].join("\n");
|
|
685
817
|
}
|
|
686
818
|
if ("task" in value && "units" in value && Array.isArray(value["units"])) {
|
|
687
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 ?? "");
|
|
688
844
|
return [
|
|
689
|
-
`
|
|
690
|
-
`
|
|
691
|
-
`
|
|
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)
|
|
692
871
|
].join("\n");
|
|
693
872
|
}
|
|
694
873
|
if ("results" in value && Array.isArray(value["results"])) {
|
|
695
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);
|
|
696
877
|
return [
|
|
697
|
-
`status: ${
|
|
878
|
+
`status: ${humanField(verification.status ?? "unknown")}`,
|
|
698
879
|
`results: ${verification.results.length}`,
|
|
699
|
-
|
|
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)}`
|
|
700
911
|
].join("\n");
|
|
701
912
|
}
|
|
702
913
|
if ("comparisonTool" in value && "score" in value) {
|
|
703
914
|
const comparison = value;
|
|
704
915
|
return [
|
|
705
|
-
`status: ${
|
|
916
|
+
`status: ${humanField(comparison.status ?? "unknown")}`,
|
|
706
917
|
`score: ${String(comparison.score ?? "unknown")}`,
|
|
707
918
|
`threshold: ${String(comparison.threshold ?? "unknown")}`,
|
|
708
919
|
`changedPixels: ${String(comparison.changedPixels ?? "unknown")}`,
|
|
709
920
|
`changedRatio: ${String(comparison.changedRatio ?? "unknown")}`,
|
|
710
|
-
`diffPath: ${
|
|
921
|
+
`diffPath: ${humanField(comparison.diffPath ?? "unknown")}`,
|
|
711
922
|
...(Array.isArray(comparison.limitations) && comparison.limitations.length
|
|
712
|
-
? [`limitations: ${comparison.limitations.map((item) =>
|
|
923
|
+
? [`limitations: ${comparison.limitations.map((item) => humanField(item)).join(" ")}`]
|
|
713
924
|
: [])
|
|
714
925
|
].join("\n");
|
|
715
926
|
}
|
|
716
927
|
if ("action" in value && "stateStatus" in value) {
|
|
717
928
|
const next = value;
|
|
929
|
+
const changedFileLimit = next.limits?.changedFiles;
|
|
930
|
+
return [
|
|
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;
|
|
718
941
|
return [
|
|
719
|
-
`action: ${
|
|
720
|
-
`
|
|
721
|
-
`
|
|
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")}`
|
|
722
951
|
].join("\n");
|
|
723
952
|
}
|
|
724
953
|
if ("changedFiles" in value && "verification" in value) {
|
|
725
954
|
const state = value;
|
|
726
955
|
return [
|
|
727
|
-
`status: ${
|
|
956
|
+
`status: ${humanField(state.status ?? "unknown")}`,
|
|
728
957
|
`changedFiles: ${Array.isArray(state.changedFiles) ? state.changedFiles.length : 0}`,
|
|
729
|
-
`verification: ${
|
|
958
|
+
`verification: ${humanField(state.verification?.status ?? "unknown")}`,
|
|
730
959
|
`retryCount: ${String(state.retryCount ?? 0)}`
|
|
731
960
|
].join("\n");
|
|
732
961
|
}
|
|
@@ -740,41 +969,80 @@ function renderHuman(value) {
|
|
|
740
969
|
}
|
|
741
970
|
if ("skills" in value && Array.isArray(value["skills"])) {
|
|
742
971
|
const skills = value["skills"];
|
|
743
|
-
|
|
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");
|
|
744
980
|
}
|
|
745
|
-
if ("
|
|
746
|
-
const
|
|
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;
|
|
747
986
|
return [
|
|
748
|
-
`
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
return `- ${String(card.id ?? "unknown")}: ${String(card.title ?? "unknown")} (${String(card.path ?? "unknown")})${score}`;
|
|
752
|
-
})
|
|
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)})`)
|
|
753
990
|
].join("\n");
|
|
754
991
|
}
|
|
755
|
-
if ("
|
|
756
|
-
const
|
|
992
|
+
if ("ingestRef" in value && "source" in value && "producedKnowledgeCardIds" in value) {
|
|
993
|
+
const record = value;
|
|
757
994
|
return [
|
|
758
|
-
`
|
|
759
|
-
`
|
|
760
|
-
`
|
|
761
|
-
""
|
|
762
|
-
|
|
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)}`
|
|
763
1001
|
].join("\n");
|
|
764
1002
|
}
|
|
765
1003
|
if ("artifactPath" in value && "prdSourceCount" in value) {
|
|
766
1004
|
const index = value;
|
|
1005
|
+
const cardLimits = index.limits?.cards;
|
|
767
1006
|
return [
|
|
768
|
-
`artifactPath: ${
|
|
1007
|
+
`artifactPath: ${humanField(index.artifactPath ?? "unknown")}`,
|
|
769
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)}`,
|
|
770
1011
|
`prdSourceCount: ${String(index.prdSourceCount ?? 0)}`,
|
|
771
1012
|
`uncoveredPrdSourceCount: ${String(index.uncoveredPrdSourceCount ?? 0)}`
|
|
772
1013
|
].join("\n");
|
|
773
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
|
+
}
|
|
774
1042
|
if ("coveredPrdSourceCount" in value && "uncoveredPrdSources" in value) {
|
|
775
1043
|
const coverage = value;
|
|
776
1044
|
return [
|
|
777
|
-
`status: ${
|
|
1045
|
+
`status: ${humanField(coverage.status ?? "unknown")}`,
|
|
778
1046
|
`prdSourceCount: ${String(coverage.prdSourceCount ?? 0)}`,
|
|
779
1047
|
`coveredPrdSourceCount: ${String(coverage.coveredPrdSourceCount ?? 0)}`,
|
|
780
1048
|
`uncoveredPrdSources: ${Array.isArray(coverage.uncoveredPrdSources) ? coverage.uncoveredPrdSources.length : 0}`,
|
|
@@ -783,7 +1051,19 @@ function renderHuman(value) {
|
|
|
783
1051
|
}
|
|
784
1052
|
if ("path" in value && "title" in value) {
|
|
785
1053
|
const knowledge = value;
|
|
786
|
-
return [`path: ${
|
|
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");
|
|
787
1067
|
}
|
|
788
1068
|
if ("artifactPath" in value && "unitCount" in value) {
|
|
789
1069
|
return renderCheck(value, "unitCount");
|
|
@@ -791,30 +1071,53 @@ function renderHuman(value) {
|
|
|
791
1071
|
if ("artifactPath" in value && "nodeCount" in value) {
|
|
792
1072
|
return renderCheck(value, "nodeCount");
|
|
793
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
|
+
}
|
|
794
1089
|
if ("skillsRoot" in value && "skillCount" in value) {
|
|
795
1090
|
return renderCheck(value, "skillCount");
|
|
796
1091
|
}
|
|
797
1092
|
if ("knowledgeRoot" in value && "cardCount" in value) {
|
|
798
1093
|
return renderCheck(value, "cardCount");
|
|
799
1094
|
}
|
|
800
|
-
if ("artifactPath" in value &&
|
|
1095
|
+
if ("artifactPath" in value && "decision" in value) {
|
|
801
1096
|
return renderCheck(value, null);
|
|
802
1097
|
}
|
|
803
1098
|
if ("contractVersion" in value && "failedCommands" in value) {
|
|
804
1099
|
const packet = value;
|
|
805
1100
|
return [
|
|
806
|
-
`status: ${
|
|
807
|
-
`verificationStatus: ${
|
|
808
|
-
`
|
|
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)}`
|
|
809
1112
|
].join("\n");
|
|
810
1113
|
}
|
|
811
1114
|
if ("contractVersion" in value && "files" in value) {
|
|
812
1115
|
const init = value;
|
|
813
1116
|
return [
|
|
814
1117
|
`dryRun: ${String(init.dryRun ?? false)}`,
|
|
815
|
-
`needsUpdate: ${
|
|
816
|
-
...(Array.isArray(init.files) ? init.files.map((file) => `${
|
|
817
|
-
...(Array.isArray(init.skills) ? init.skills.map((skill) => `${
|
|
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")}`) : [])
|
|
818
1121
|
].join("\n");
|
|
819
1122
|
}
|
|
820
1123
|
if ("removed" in value && "kept" in value) {
|
|
@@ -828,30 +1131,36 @@ function renderHuman(value) {
|
|
|
828
1131
|
if ("preset" in value && "files" in value && Array.isArray(value["files"])) {
|
|
829
1132
|
const scaffold = value;
|
|
830
1133
|
return [
|
|
831
|
-
`status: ${
|
|
832
|
-
`preset: ${
|
|
833
|
-
`target: ${
|
|
834
|
-
`projectName: ${
|
|
1134
|
+
`status: ${humanField(scaffold.status ?? "unknown")}`,
|
|
1135
|
+
`preset: ${humanField(scaffold.preset ?? "unknown")}`,
|
|
1136
|
+
`target: ${humanField(scaffold.target ?? "unknown")}`,
|
|
1137
|
+
`projectName: ${humanField(scaffold.projectName ?? "unknown")}`,
|
|
835
1138
|
`files: ${scaffold.files.length}`
|
|
836
1139
|
].join("\n");
|
|
837
1140
|
}
|
|
838
1141
|
if ("status" in value) {
|
|
839
|
-
return `status: ${
|
|
1142
|
+
return `status: ${humanField(value["status"])}`;
|
|
840
1143
|
}
|
|
841
1144
|
return JSON.stringify(value, null, 2);
|
|
842
1145
|
}
|
|
843
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);
|
|
844
1151
|
const lines = [
|
|
845
|
-
`status: ${
|
|
846
|
-
...(value["artifactPath"] ? [`artifactPath: ${
|
|
847
|
-
...(value["skillsRoot"] ? [`skillsRoot: ${
|
|
848
|
-
...(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))}`
|
|
849
1158
|
];
|
|
850
|
-
for (const error of
|
|
851
|
-
lines.push(`error: ${
|
|
1159
|
+
for (const error of selectedErrors) {
|
|
1160
|
+
lines.push(`error: ${humanField(error)}`);
|
|
852
1161
|
}
|
|
853
|
-
for (const warning of
|
|
854
|
-
lines.push(`warning: ${
|
|
1162
|
+
for (const warning of selectedWarnings) {
|
|
1163
|
+
lines.push(`warning: ${humanField(warning)}`);
|
|
855
1164
|
}
|
|
856
1165
|
return lines.join("\n");
|
|
857
1166
|
}
|
|
@@ -892,6 +1201,19 @@ function optionalNumber(key, value) {
|
|
|
892
1201
|
}
|
|
893
1202
|
return { [key]: parsed };
|
|
894
1203
|
}
|
|
1204
|
+
function optionalFiniteNumber(key, value) {
|
|
1205
|
+
if (value === undefined) {
|
|
1206
|
+
return {};
|
|
1207
|
+
}
|
|
1208
|
+
if (typeof value !== "string") {
|
|
1209
|
+
throw new Error("numeric flag requires a value");
|
|
1210
|
+
}
|
|
1211
|
+
const parsed = Number(value);
|
|
1212
|
+
if (!Number.isFinite(parsed)) {
|
|
1213
|
+
throw new Error(`Invalid numeric value: ${value}`);
|
|
1214
|
+
}
|
|
1215
|
+
return { [key]: parsed };
|
|
1216
|
+
}
|
|
895
1217
|
function isRecord(value) {
|
|
896
1218
|
return typeof value === "object" && value !== null;
|
|
897
1219
|
}
|