@tea-agent/loop-agent 0.39.0-beta.5 → 0.39.0-beta.7
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 +13 -1
- package/dist/build-stamp.json +3 -3
- package/dist/commands/client-recovery.js +3 -0
- package/dist/commands/task-advance.js +19 -0
- package/dist/executors/dag-pi-executor.js +138 -36
- package/dist/executors/pi-executor.js +7 -0
- package/dist/executors/pi-playwright-cli-tool.js +23 -16
- package/dist/executors/shell-executor.js +26 -9
- package/dist/shared/dag-failure-category.js +150 -0
- package/dist/task/config-types.js +6 -0
- package/dist/task/frontend-project-capability.js +19 -0
- package/dist/task/source-references.js +22 -1
- package/dist/worker/console/chat/operation-card.js +8 -1
- package/dist/worker/console/chat/routes.js +5 -3
- package/dist/worker/console/inspect-split.js +18 -0
- package/dist/worker/console/operation-run-facts.js +19 -3
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-zsNyvGaH.js → abnfDiagram-N423BO3Z-bPer1waP.js} +1 -1
- package/dist/worker/console/static/assets/{arc-BDjZ5kE1.js → arc-BLdkwucW.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-BkgaujnN.js → architectureDiagram-T3A2C74G-Bw4wo4I1.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CqxOJi0j.js → blockDiagram-VBNYF7ZC-DUUkc0gr.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-C2JHLdRi.js → c4Diagram-5PPSVZJV-BC3O0nob.js} +1 -1
- package/dist/worker/console/static/assets/channel-AbFtVnFm.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DF_YSvOS.js → chunk-2GRJ4B5K-Dd4g2nti.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-D3Ort5Vo.js → chunk-2Q5K7J3B-s2EDm7-n.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-XfAfZeUC.js → chunk-5RXB4S5H-GqtHM2yQ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-SLBibhf5.js → chunk-5VM5RSS4-BzRFrN8j.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Dz29Ye_f.js → chunk-6Q2QTUOP-Bw9nFjCJ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-DB2G4H8V.js → chunk-GF5L2VYU-B4n-03Qm.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CIoGkxdu.js → chunk-JWPE2WC7-Dt75ZdBD.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CG78FGkn.js → chunk-KBJHAD2P-B_afMhHB.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-ZDHAvXPd.js → chunk-RYQCIY6F-Bd8Rqqg9.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BKkkC4VA.js → chunk-XXDRQBXY-9boOMji4.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-n1yf2Jcv.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-n1yf2Jcv.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-SposUZsO.js → cose-bilkent-JH36ORCC-BtCycfCc.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BSCtQpD7.js → cynefin-VYW2F7L2-eTOts9L1.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-DgFHrw9l.js → cynefinDiagram-MW4NZA55-Cibd2mjg.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BVBasYbj.js → dagre-VZM6K2ZE-CDjDZtDV.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-6r_4rN_c.js → diagram-7IWD3JNH-Btexn-JJ.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-JmuaB41P.js → diagram-B4RE2ZJO-Cyl8sdpM.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-xXvAY3sk.js → diagram-LBJQPF4R-Ev-83E1t.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-D2B3lY2o.js → diagram-Q27KOJAE-41LqE0Mc.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-tK54tMEX.js → diagram-UB23O5K3-BC39T5R3.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CNtELzV-.js → ebnfDiagram-BXEA7PRR-DzcNRuri.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-C1xKMKcW.js → erDiagram-JOGREHBK-B5Frvvnz.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CZ7dlPMz.js → flowDiagram-UKHOOZJN-BapxROIM.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-BqGb42Xe.js → ganttDiagram-PKOTCBZU-Cd4d4wQ0.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-D_BlXEtt.js → gitGraphDiagram-DS77QQ5N-CrL6buFW.js} +1 -1
- package/dist/worker/console/static/assets/index-DBh_x_Ek.js +406 -0
- package/dist/worker/console/static/assets/index-DwOGauxU.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Vce2vmIe.js → infoDiagram-6WML65LV-BrSiNxyd.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-DDwVBAvI.js → ishikawaDiagram-WSZJBQD7-gvlvY-n9.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-y_Ew-wv4.js → journeyDiagram-NVQOT4AX-D-YaPzRQ.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-CjXJFp1K.js → kanban-definition-27J2QSJJ-BsmDv9E_.js} +1 -1
- package/dist/worker/console/static/assets/{linear-1itMst1Q.js → linear-UWaoDN3h.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-C-D3ZRUa.js → mermaid.core-BlvpGVG8.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BiYywmZc.js → mindmap-definition-FAOFIHXS-CUCIP5CP.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-l2fydNWA.js → pegDiagram-VL7TDLO6-CB1aQUAK.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-Dz0hNbYW.js → pieDiagram-7S7Q4E2Y-BwehHxhf.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-BujI_mLZ.js → quadrantDiagram-CIZ2JOQS-CFz30APB.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-pWe84beb.js → railroadDiagram-AXF67PYL-BwNmw1i6.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-ByYu2frg.js → requirementDiagram-LRYGKXZP-jg-tPXlI.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-CoPnilFP.js → sankeyDiagram-W5VNT64P-BlyReDKl.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-1Md2LnS0.js → sequenceDiagram-SI44F4Z6-DBUzW1f3.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DqqqAoSH.js → sizeCapture-X5ZJPWSS-BYcI2RAr.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-C4sGkf--.js → stateDiagram-OKZ733FA-D7AiyJdo.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BBSH5c8m.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-ByxJrUzW.js → swimlanes-SLNWSIFB-BHGt7Kkv.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D2F7-U4H.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-D8MLgM0O.js → timeline-definition-Z64GVDOM-OPjooWcX.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DnBis-wZ.js → vennDiagram-T6HMQDX7-ggsWDvrO.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-uuyYT7UO.js → wardleyDiagram-T6FBY63Y-DjNe-BjZ.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-BjgabhwK.js → xychartDiagram-ELKLHX3M-Byp63Hei.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +38 -2
- package/dist/worker/console/static-src/app/useRunProgress.js +46 -0
- package/dist/worker/console/static-src/operator-chat/cards/failure-category-advice.js +25 -0
- package/dist/worker/console/static-src/operator-chat/input-history.js +76 -0
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +13 -1
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +29 -9
- package/dist/worker/console/static-src/operator-chat/useComposer.js +32 -0
- package/dist/worker/console/static-src/pages/tasks/run-id-resolution.js +79 -0
- package/dist/worker/console/static-src/pages/tasks/run-ownership-verify.js +23 -0
- package/dist/worker/console/static-src/pages/tasks/run-panel-progress.js +110 -0
- package/dist/worker/materialize/harness-task-lineage.js +5 -2
- package/dist/worker/observability/read-model.js +22 -0
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +29 -1
- package/dist/workflows/dag/backend-test-markdown-workflow.js +176 -1
- package/dist/workflows/dag/backend-test-pytest-collection.js +87 -4
- package/dist/workflows/dag/backend-test-writer-completeness.js +10 -5
- package/dist/workflows/dag/dynamic-runtime/loop-until.js +1 -1
- package/dist/workflows/dag/dynamic-runtime/map.js +1 -1
- package/dist/workflows/dag/failure-category.js +7 -128
- package/dist/workflows/dag/frontend-design-policy.js +31 -7
- package/dist/workflows/dag/frontend-implementation-contract.js +78 -3
- package/dist/workflows/dag/frontend-review-findings.js +238 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +24 -10
- package/dist/workflows/dag/frontend-shape.js +5 -3
- package/dist/workflows/dag/frontend-test-case-checklist.js +4 -2
- package/dist/workflows/dag/frontend-test-case-manifest.js +6 -4
- package/dist/workflows/dag/frontend-test-case-quality.js +6 -3
- package/dist/workflows/dag/frontend-test-environment-probe.js +10 -7
- package/dist/workflows/dag/frontend-test-html-report.js +3 -1
- package/dist/workflows/dag/frontend-test-l5-report.js +3 -1
- package/dist/workflows/dag/frontend-test-layout.js +159 -0
- package/dist/workflows/dag/frontend-test-result-contract.js +28 -14
- package/dist/workflows/dag/frontend-test-standard-scenarios.js +3 -1
- package/dist/workflows/dag/init-hybrid.js +149 -15
- package/dist/workflows/dag/node-execution.js +18 -1
- package/dist/workflows/dag/report.js +37 -1
- package/dist/workflows/dag/rerun-feedback.js +101 -1
- package/dist/workflows/dag/retry-policy.js +31 -3
- package/dist/workflows/dag/runner.js +46 -1
- package/dist/workflows/dag/types.js +12 -0
- package/dist/workflows/dag/validate.js +32 -22
- package/docs/templates/agent-dag-report.schema.json +8 -2
- package/docs/templates/agent-dag.schema.json +1 -1
- package/docs/templates/frontend-test-case-checklist.md +2 -2
- package/package.json +1 -1
- package/skills/fe-test-ui-scout/SKILL.md +4 -4
- package/skills/fe-test-ui-scout/references/ledger-schema.md +1 -1
- package/skills/playwright-cli/SKILL.md +1 -1
- package/skills/playwright-cli-case-generator/SKILL.md +10 -8
- package/dist/worker/console/static/assets/channel-BuqaGKAT.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DNdSHjH9.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DNdSHjH9.js +0 -1
- package/dist/worker/console/static/assets/index-D5zGX6fG.js +0 -404
- package/dist/worker/console/static/assets/index-DBbhESQ_.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-B8rmop_9.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B0ky-kBM.js +0 -8
|
@@ -39,6 +39,7 @@ import { materializeFrontendLintAssessment, materializeFrontendLintBaseline, } f
|
|
|
39
39
|
import { formatTraceabilityGateStdout, materializeBackendTestCaseManifest, runBackendTestTraceabilityGate, } from "../workflows/dag/backend-test-case-manifest.js";
|
|
40
40
|
import { materializeBackendTestExecutionContract } from "../workflows/dag/backend-test-execution-contract.js";
|
|
41
41
|
import { resolveBackendTestLayout } from "../workflows/dag/backend-test-layout.js";
|
|
42
|
+
import { frontendTestLayoutFromSpec, } from "../workflows/dag/frontend-test-layout.js";
|
|
42
43
|
import { backendTestGapDocSchema, ingestBackendTestGap, } from "../workflows/dag/backend-test-gap-fill.js";
|
|
43
44
|
import { analyzeBackendTestCaseCoverage, analyzeBackendTestMarkdownPytestCorrespondence, materializeBackendTestCaseManifestFromFacts, } from "../workflows/dag/backend-test-case-coverage-analysis.js";
|
|
44
45
|
import { materializeBackendTestResultFromPytestHtml, materializeBackendTestResultFromRunDir, parsePytestHtmlReport, } from "../workflows/dag/backend-test-result-contract.js";
|
|
@@ -1067,7 +1068,7 @@ async function executeBackendTestPipeline(input, meta) {
|
|
|
1067
1068
|
else if (pipeline === "markdown-traceability") {
|
|
1068
1069
|
let report;
|
|
1069
1070
|
try {
|
|
1070
|
-
report = await validateBackendMarkdownTraceability(input.cwd);
|
|
1071
|
+
report = await validateBackendMarkdownTraceability(input.cwd, backendLayout);
|
|
1071
1072
|
}
|
|
1072
1073
|
catch (error) {
|
|
1073
1074
|
report = `# Backend Test Traceability\n\n## Status\n\nFAIL\n\n## Findings\n\n- Traceability validation could not complete: ${error instanceof Error ? error.message : String(error)}\n`;
|
|
@@ -2800,10 +2801,12 @@ async function executeFrontendCloseout(input, meta) {
|
|
|
2800
2801
|
async function executeFrontendTestCaseChecklist(input, meta) {
|
|
2801
2802
|
const started = Date.now();
|
|
2802
2803
|
try {
|
|
2804
|
+
const layout = frontendTestLayoutFromSpec(meta.spec);
|
|
2803
2805
|
const declaredAcIds = (meta.spec.sourceBinding?.requirementIds ?? []).filter((id) => /^AC(?:-[A-Z0-9]+)+$/i.test(id));
|
|
2804
2806
|
const result = await validateFrontendCaseChecklist({
|
|
2805
2807
|
workspaceRoot: input.cwd,
|
|
2806
2808
|
declaredAcIds,
|
|
2809
|
+
layout,
|
|
2807
2810
|
});
|
|
2808
2811
|
if (result.issues.length) {
|
|
2809
2812
|
return {
|
|
@@ -2838,6 +2841,7 @@ async function executeFrontendTestL5Report(input, meta) {
|
|
|
2838
2841
|
const output = await renderFrontendTestL5Report({
|
|
2839
2842
|
workspaceRoot: input.cwd,
|
|
2840
2843
|
runDir: meta.runDir,
|
|
2844
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2841
2845
|
});
|
|
2842
2846
|
return {
|
|
2843
2847
|
ok: true,
|
|
@@ -2863,6 +2867,7 @@ async function executeFrontendTestHtmlReport(input, meta) {
|
|
|
2863
2867
|
const output = await renderFrontendTestHtmlReport({
|
|
2864
2868
|
workspaceRoot: input.cwd,
|
|
2865
2869
|
runDir: meta.runDir,
|
|
2870
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2866
2871
|
});
|
|
2867
2872
|
return {
|
|
2868
2873
|
ok: true,
|
|
@@ -2882,11 +2887,12 @@ async function executeFrontendTestHtmlReport(input, meta) {
|
|
|
2882
2887
|
};
|
|
2883
2888
|
}
|
|
2884
2889
|
}
|
|
2885
|
-
async function executeFrontendTestStandardScenarios(input) {
|
|
2890
|
+
async function executeFrontendTestStandardScenarios(input, meta) {
|
|
2886
2891
|
const started = Date.now();
|
|
2887
2892
|
try {
|
|
2888
2893
|
const result = await copyFrontendTestStandardScenarios({
|
|
2889
2894
|
workspaceRoot: input.cwd,
|
|
2895
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2890
2896
|
});
|
|
2891
2897
|
return {
|
|
2892
2898
|
ok: true,
|
|
@@ -2906,10 +2912,11 @@ async function executeFrontendTestStandardScenarios(input) {
|
|
|
2906
2912
|
};
|
|
2907
2913
|
}
|
|
2908
2914
|
}
|
|
2909
|
-
async function executeFrontendTestEnvironmentProbe(input) {
|
|
2915
|
+
async function executeFrontendTestEnvironmentProbe(input, meta) {
|
|
2910
2916
|
const started = Date.now();
|
|
2911
2917
|
const result = await probeFrontendTestEnvironment({
|
|
2912
2918
|
workspaceRoot: input.cwd,
|
|
2919
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2913
2920
|
});
|
|
2914
2921
|
if (result.ok) {
|
|
2915
2922
|
return {
|
|
@@ -2928,11 +2935,12 @@ async function executeFrontendTestEnvironmentProbe(input) {
|
|
|
2928
2935
|
durationMs: Date.now() - started,
|
|
2929
2936
|
};
|
|
2930
2937
|
}
|
|
2931
|
-
async function executeFrontendTestEvidenceValidation(input) {
|
|
2938
|
+
async function executeFrontendTestEvidenceValidation(input, meta) {
|
|
2932
2939
|
const started = Date.now();
|
|
2933
2940
|
try {
|
|
2934
2941
|
const result = await validateFrontendCaseEvidence({
|
|
2935
2942
|
workspaceRoot: input.cwd,
|
|
2943
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2936
2944
|
});
|
|
2937
2945
|
const output = `frontend case evidence validation cases=${result.cases} findings=${result.issues.length}${result.issues.length ? ` issues=${JSON.stringify(result.issues)}` : ""}`;
|
|
2938
2946
|
if (result.hardFail) {
|
|
@@ -2971,6 +2979,7 @@ async function executeFrontendTestCaseManifest(input, meta) {
|
|
|
2971
2979
|
const checklist = await validateFrontendCaseChecklist({
|
|
2972
2980
|
workspaceRoot: input.cwd,
|
|
2973
2981
|
declaredAcIds,
|
|
2982
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2974
2983
|
});
|
|
2975
2984
|
if (checklist.issues.length) {
|
|
2976
2985
|
return {
|
|
@@ -2985,6 +2994,7 @@ async function executeFrontendTestCaseManifest(input, meta) {
|
|
|
2985
2994
|
workspaceRoot: input.cwd,
|
|
2986
2995
|
maxCases: gate.maxCases,
|
|
2987
2996
|
declaredAcIds,
|
|
2997
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
2988
2998
|
});
|
|
2989
2999
|
return {
|
|
2990
3000
|
ok: true,
|
|
@@ -3023,6 +3033,7 @@ async function executeFrontendTestResultFinalize(input, meta) {
|
|
|
3023
3033
|
try {
|
|
3024
3034
|
const evidence = await validateFrontendCaseEvidence({
|
|
3025
3035
|
workspaceRoot: input.cwd,
|
|
3036
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
3026
3037
|
});
|
|
3027
3038
|
advisoryStdout = `frontend case evidence validation cases=${evidence.cases} findings=${evidence.issues.length}${evidence.issues.length ? ` issues=${JSON.stringify(evidence.issues)}` : ""}`;
|
|
3028
3039
|
// Advisory findings must not block materialize; only hardFail (path escape) does.
|
|
@@ -3041,6 +3052,7 @@ async function executeFrontendTestResultFinalize(input, meta) {
|
|
|
3041
3052
|
artifactName: "frontend-test-result.json",
|
|
3042
3053
|
outputDir: "contracts",
|
|
3043
3054
|
sourceBinding: meta.spec.sourceBinding,
|
|
3055
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
3044
3056
|
});
|
|
3045
3057
|
return {
|
|
3046
3058
|
ok: true,
|
|
@@ -3079,12 +3091,14 @@ async function executeFrontendTestReports(input, meta) {
|
|
|
3079
3091
|
const l5 = await renderFrontendTestL5Report({
|
|
3080
3092
|
workspaceRoot: input.cwd,
|
|
3081
3093
|
runDir: meta.runDir,
|
|
3094
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
3082
3095
|
});
|
|
3083
3096
|
lines.push(`Frontend L-5 report: ${l5.htmlPath}\nMarkdown: ${l5.markdownPath}\nStatus: ${l5.metrics.status}`);
|
|
3084
3097
|
}
|
|
3085
3098
|
const report = await renderFrontendTestHtmlReport({
|
|
3086
3099
|
workspaceRoot: input.cwd,
|
|
3087
3100
|
runDir: meta.runDir,
|
|
3101
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
3088
3102
|
});
|
|
3089
3103
|
lines.push(`Frontend test report: ${report.htmlPath}\nMarkdown: ${report.markdownPath}\nOutcome: ${report.outcome}\nCases: ${report.caseCount}`);
|
|
3090
3104
|
return {
|
|
@@ -3214,10 +3228,10 @@ async function executeDagShellNodeInner(input, meta) {
|
|
|
3214
3228
|
}
|
|
3215
3229
|
}
|
|
3216
3230
|
if (shell?.frontendTestStandardScenarios) {
|
|
3217
|
-
return executeFrontendTestStandardScenarios(input);
|
|
3231
|
+
return executeFrontendTestStandardScenarios(input, meta);
|
|
3218
3232
|
}
|
|
3219
3233
|
if (shell?.frontendTestEnvironmentProbe) {
|
|
3220
|
-
return executeFrontendTestEnvironmentProbe(input);
|
|
3234
|
+
return executeFrontendTestEnvironmentProbe(input, meta);
|
|
3221
3235
|
}
|
|
3222
3236
|
if (shell?.frontendBrowserToolPreflight) {
|
|
3223
3237
|
const started = Date.now();
|
|
@@ -3273,14 +3287,16 @@ async function executeDagShellNodeInner(input, meta) {
|
|
|
3273
3287
|
label: "Pi SDK custom-tool 能力",
|
|
3274
3288
|
ok: true,
|
|
3275
3289
|
});
|
|
3290
|
+
const layout = frontendTestLayoutFromSpec(meta.spec);
|
|
3276
3291
|
const toolProbe = await createPlaywrightCliTool({
|
|
3277
3292
|
repoRoot: input.cwd,
|
|
3278
3293
|
runDir: meta.runDir,
|
|
3279
3294
|
nodeId: input.task.id,
|
|
3280
3295
|
caseId: "frontend-browser-preflight",
|
|
3281
|
-
evidenceDir:
|
|
3296
|
+
evidenceDir: `${layout.evidenceDir}/frontend-browser-preflight`,
|
|
3282
3297
|
baseUrl: "http://localhost:5173/",
|
|
3283
|
-
inputRoot:
|
|
3298
|
+
inputRoot: layout.fixturesDir,
|
|
3299
|
+
layout,
|
|
3284
3300
|
});
|
|
3285
3301
|
if (toolProbe.name !== "playwright_cli") {
|
|
3286
3302
|
steps.push({
|
|
@@ -3431,7 +3447,7 @@ async function executeDagShellNodeInner(input, meta) {
|
|
|
3431
3447
|
return executeFrontendTestCaseManifest(input, meta);
|
|
3432
3448
|
}
|
|
3433
3449
|
if (shell?.frontendTestEvidenceValidation) {
|
|
3434
|
-
return executeFrontendTestEvidenceValidation(input);
|
|
3450
|
+
return executeFrontendTestEvidenceValidation(input, meta);
|
|
3435
3451
|
}
|
|
3436
3452
|
if (shell?.frontendTestResultFinalize) {
|
|
3437
3453
|
return executeFrontendTestResultFinalize(input, meta);
|
|
@@ -3538,6 +3554,7 @@ async function executeDagShellNodeInner(input, meta) {
|
|
|
3538
3554
|
artifactName: gate.artifactName,
|
|
3539
3555
|
outputDir: gate.outputDir,
|
|
3540
3556
|
sourceBinding: meta.spec.sourceBinding,
|
|
3557
|
+
layout: frontendTestLayoutFromSpec(meta.spec),
|
|
3541
3558
|
});
|
|
3542
3559
|
break;
|
|
3543
3560
|
default:
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure DAG failure-category classification shared by the workflows kernel and
|
|
3
|
+
* the Operator Console projection (console sources may not import
|
|
4
|
+
* src/workflows — security-and-tools boundary test).
|
|
5
|
+
*
|
|
6
|
+
* No runtime imports: this module is a leaf safe for both the CLI kernel and
|
|
7
|
+
* the browser bundle.
|
|
8
|
+
*/
|
|
9
|
+
export const DAG_NORMALIZED_FAILURE_CATEGORY_VALUES = [
|
|
10
|
+
"success",
|
|
11
|
+
"validation",
|
|
12
|
+
"executor",
|
|
13
|
+
"write-guard",
|
|
14
|
+
"timeout",
|
|
15
|
+
"auth",
|
|
16
|
+
"human-required",
|
|
17
|
+
"human-rejected",
|
|
18
|
+
"shell-command",
|
|
19
|
+
"static-error",
|
|
20
|
+
"decision-envelope",
|
|
21
|
+
"skipped",
|
|
22
|
+
"unknown",
|
|
23
|
+
];
|
|
24
|
+
const RAW_TO_NORMALIZED = {
|
|
25
|
+
success: "success",
|
|
26
|
+
"write-guard": "write-guard",
|
|
27
|
+
timeout: "timeout",
|
|
28
|
+
// Clean implementer stall with zero writes — still a timeout class for report,
|
|
29
|
+
// but retryable under WRITER_TRANSPORT_RETRY_POLICY.
|
|
30
|
+
"writer-clean-timeout": "timeout",
|
|
31
|
+
"missing-api-key": "auth",
|
|
32
|
+
auth: "auth",
|
|
33
|
+
"human-rejected": "human-rejected",
|
|
34
|
+
"human-required": "human-required",
|
|
35
|
+
"decision-envelope-invalid": "decision-envelope",
|
|
36
|
+
"nonzero-exit": "shell-command",
|
|
37
|
+
"spawn-error": "shell-command",
|
|
38
|
+
"test-timeout": "timeout",
|
|
39
|
+
"static-error": "static-error",
|
|
40
|
+
"invalid-output": "validation",
|
|
41
|
+
"structured-output-truncated": "validation",
|
|
42
|
+
"output-too-large": "validation",
|
|
43
|
+
"structured-repair-exhausted": "validation",
|
|
44
|
+
"governance-blocked": "validation",
|
|
45
|
+
"path-violation": "validation",
|
|
46
|
+
"empty-output": "validation",
|
|
47
|
+
"verify-failure": "validation",
|
|
48
|
+
"test-failure": "validation",
|
|
49
|
+
"verification-plan-stale": "validation",
|
|
50
|
+
"read-burst": "validation",
|
|
51
|
+
// Writer persisted real file changes but the final provider call hit a
|
|
52
|
+
// context overflow; verification never ran. Distinct from empty-output so
|
|
53
|
+
// the report shows partial success instead of a spec issue.
|
|
54
|
+
"partial-success-with-context-overflow": "validation",
|
|
55
|
+
// Writer burned an excessive token budget (unconverged read-edit-test loop)
|
|
56
|
+
// and still failed; distinct from empty-output for accurate reporting.
|
|
57
|
+
"writer-budget-exhausted": "validation",
|
|
58
|
+
network: "executor",
|
|
59
|
+
quota: "executor",
|
|
60
|
+
"rate-limit": "executor",
|
|
61
|
+
unavailable: "executor",
|
|
62
|
+
// Context window overflow (400 request-too-large): the session needs
|
|
63
|
+
// compaction / fresh context before retrying — an executor-side
|
|
64
|
+
// environment condition, not a plan-quality defect.
|
|
65
|
+
"context-overflow": "executor",
|
|
66
|
+
// Deterministic capability/policy refusal: missing verified launcher JS
|
|
67
|
+
// entry, capability allowlist rejection, or missing bounded write tool
|
|
68
|
+
// profile. These are environment/config defects the operator repairs
|
|
69
|
+
// before rerunning; classify as executor so recovery recommends
|
|
70
|
+
// rerun-after-fix WITHOUT forcing a human-decision gate on
|
|
71
|
+
// standaloneTaskRerun (run-failed same-task rerun).
|
|
72
|
+
"tool-policy": "executor",
|
|
73
|
+
unknown: "unknown",
|
|
74
|
+
};
|
|
75
|
+
/** Status inputs are deliberately `string`: projection layers pass bounded
|
|
76
|
+
* text from CLI JSON; unmatched values simply fall through to unknown. */
|
|
77
|
+
function isFinishedStatus(status) {
|
|
78
|
+
return status === "FINISHED" || status === "finished";
|
|
79
|
+
}
|
|
80
|
+
function isInProgressStatus(status) {
|
|
81
|
+
return (status === "PENDING" ||
|
|
82
|
+
status === "RUNNING" ||
|
|
83
|
+
status === "pending" ||
|
|
84
|
+
status === "running");
|
|
85
|
+
}
|
|
86
|
+
function isFailureStatus(status) {
|
|
87
|
+
return (status === "ERROR" ||
|
|
88
|
+
status === "failed" ||
|
|
89
|
+
status === "partial_failed");
|
|
90
|
+
}
|
|
91
|
+
function mapRawCategory(raw) {
|
|
92
|
+
const direct = RAW_TO_NORMALIZED[raw];
|
|
93
|
+
if (direct)
|
|
94
|
+
return direct;
|
|
95
|
+
const lower = raw.toLowerCase();
|
|
96
|
+
if (lower.includes("timeout"))
|
|
97
|
+
return "timeout";
|
|
98
|
+
if (lower.includes("validation") ||
|
|
99
|
+
lower.includes("invalid") ||
|
|
100
|
+
lower.includes("verification-plan-stale") ||
|
|
101
|
+
lower.includes("plan-stale"))
|
|
102
|
+
return "validation";
|
|
103
|
+
if (lower.includes("auth") || lower.includes("api-key"))
|
|
104
|
+
return "auth";
|
|
105
|
+
if (lower.includes("write-guard") || lower.includes("write_guard"))
|
|
106
|
+
return "write-guard";
|
|
107
|
+
if (lower.includes("decision-envelope") || lower.includes("decision_envelope"))
|
|
108
|
+
return "decision-envelope";
|
|
109
|
+
if (lower.includes("human-rejected"))
|
|
110
|
+
return "human-rejected";
|
|
111
|
+
if (lower.includes("human-required"))
|
|
112
|
+
return "human-required";
|
|
113
|
+
if (lower.includes("static-error"))
|
|
114
|
+
return "static-error";
|
|
115
|
+
if (lower.includes("nonzero-exit") ||
|
|
116
|
+
lower.includes("spawn-error") ||
|
|
117
|
+
lower.includes("shell"))
|
|
118
|
+
return "shell-command";
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
export function isDagFailureCategory(value) {
|
|
122
|
+
return DAG_NORMALIZED_FAILURE_CATEGORY_VALUES.includes(value);
|
|
123
|
+
}
|
|
124
|
+
export function normalizeDagFailureCategory(raw, status) {
|
|
125
|
+
if (status === "SKIPPED") {
|
|
126
|
+
return "skipped";
|
|
127
|
+
}
|
|
128
|
+
if (raw !== undefined) {
|
|
129
|
+
const mapped = mapRawCategory(raw);
|
|
130
|
+
if (mapped) {
|
|
131
|
+
if (mapped === "success") {
|
|
132
|
+
return isFinishedStatus(status) ? "success" : "unknown";
|
|
133
|
+
}
|
|
134
|
+
return mapped;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (raw === undefined && isFinishedStatus(status)) {
|
|
138
|
+
return "success";
|
|
139
|
+
}
|
|
140
|
+
if (isInProgressStatus(status)) {
|
|
141
|
+
return "unknown";
|
|
142
|
+
}
|
|
143
|
+
if (isFailureStatus(status)) {
|
|
144
|
+
return "unknown";
|
|
145
|
+
}
|
|
146
|
+
if (raw === "success" && isFinishedStatus(status)) {
|
|
147
|
+
return "success";
|
|
148
|
+
}
|
|
149
|
+
return "unknown";
|
|
150
|
+
}
|
|
@@ -101,6 +101,12 @@ export const frontendOpenspecConfigSchema = z.object({
|
|
|
101
101
|
/** Batch limits and gate profile for the browser-driven frontend test DAG.
|
|
102
102
|
* Token fields are post-case stop thresholds, not model-provider hard caps. */
|
|
103
103
|
export const frontendTestConfigSchema = z.object({
|
|
104
|
+
/**
|
|
105
|
+
* Repository-relative frontend-test artifact root.
|
|
106
|
+
* Default "testcase/frontend". Semantic validation lives in
|
|
107
|
+
* resolveFrontendTestLayout (fail-closed), not in this schema.
|
|
108
|
+
*/
|
|
109
|
+
testRoot: z.string().min(1).optional(),
|
|
104
110
|
maxCasesPerBatch: z.number().int().min(1).max(50).optional(),
|
|
105
111
|
maxTokensPerCase: z.number().int().positive().optional(),
|
|
106
112
|
maxTotalTokens: z.number().int().positive().optional(),
|
|
@@ -133,9 +133,28 @@ export async function listOpenspecDiscovery(repoRoot, options = {}) {
|
|
|
133
133
|
.filter(Boolean);
|
|
134
134
|
const collected = [];
|
|
135
135
|
let excludedGovernanceCount = 0;
|
|
136
|
+
// Metadata / bookkeeping directories that are not normative design specs:
|
|
137
|
+
// changelogs, ADR/history archives, proposals under review, and scratch
|
|
138
|
+
// state. Reading them inflates the candidate list (and the plan prompt)
|
|
139
|
+
// with files no component selection should cite. A task that genuinely
|
|
140
|
+
// needs one can still reference it explicitly — the prewrite gate
|
|
141
|
+
// candidates come from this discovery, but explicit task-source citations
|
|
142
|
+
// flow through openspecMandatoryPaths independently.
|
|
143
|
+
const DEFAULT_EXCLUDED_SPEC_PREFIXES = [
|
|
144
|
+
"openspec/changes",
|
|
145
|
+
"openspec/project-specs/changes",
|
|
146
|
+
"openspec/project-specs/changelog",
|
|
147
|
+
"openspec/project-specs/history",
|
|
148
|
+
"openspec/project-specs/archive",
|
|
149
|
+
"openspec/project-specs/decisions",
|
|
150
|
+
"openspec/project-specs/proposals",
|
|
151
|
+
];
|
|
136
152
|
const isExcluded = (rel) => {
|
|
137
153
|
if (isGovernanceSubtreePath(rel, governanceRoot))
|
|
138
154
|
return true;
|
|
155
|
+
if (DEFAULT_EXCLUDED_SPEC_PREFIXES.some((prefix) => rel === prefix || rel.startsWith(prefix + "/"))) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
139
158
|
return extraExcludedPrefixes.some((prefix) => rel === prefix || rel.startsWith(prefix + "/"));
|
|
140
159
|
};
|
|
141
160
|
for (const specDir of options.specRoots ?? [...OPENSPEC_SPEC_DIRS]) {
|
|
@@ -22,6 +22,18 @@ function slugifyName(value) {
|
|
|
22
22
|
.replace(/-{2,}/g, "-");
|
|
23
23
|
return slug || "requirement";
|
|
24
24
|
}
|
|
25
|
+
/** Stable identity of a manifest document for change detection. Timestamps and
|
|
26
|
+
* byte sizes are excluded: identical content re-imported later must not appear
|
|
27
|
+
* "changed" (the canonical hash includes manifest bytes). */
|
|
28
|
+
function documentIdentity(doc) {
|
|
29
|
+
return `${doc.role}|${doc.name}|${doc.materializedPath}|${doc.sha256}`;
|
|
30
|
+
}
|
|
31
|
+
function sameDocumentSet(left, right) {
|
|
32
|
+
if (left.length !== right.length)
|
|
33
|
+
return false;
|
|
34
|
+
const rightIds = new Set(right.map(documentIdentity));
|
|
35
|
+
return left.every((doc) => rightIds.has(documentIdentity(doc)));
|
|
36
|
+
}
|
|
25
37
|
function ensureUniqueReferenceName(existing, baseName, extension) {
|
|
26
38
|
const used = new Set(existing);
|
|
27
39
|
const candidate = `${baseName}${extension}`;
|
|
@@ -149,10 +161,19 @@ export async function importPrdDocument(input) {
|
|
|
149
161
|
const documents = [...(existingManifest?.documents ?? [])].filter((entry) => entry.materializedPath !== materializedRelativePath);
|
|
150
162
|
documents.push(document);
|
|
151
163
|
documents.sort((left, right) => left.materializedPath.localeCompare(right.materializedPath));
|
|
164
|
+
// Keep `updatedAt` stable across re-imports of the same content: the
|
|
165
|
+
// canonical contract hash includes the manifest bytes, so a fresh
|
|
166
|
+
// timestamp on every identical re-import would make the observed
|
|
167
|
+
// canonical hash drift and fail task verification. Only bump it when the
|
|
168
|
+
// document set actually changed (a new/changed materialized file).
|
|
169
|
+
const documentSetChanged = !existingManifest ||
|
|
170
|
+
!sameDocumentSet(existingManifest.documents, documents);
|
|
152
171
|
const manifest = {
|
|
153
172
|
schemaVersion: 1,
|
|
154
173
|
taskId: input.taskId,
|
|
155
|
-
updatedAt:
|
|
174
|
+
updatedAt: documentSetChanged
|
|
175
|
+
? importedAt
|
|
176
|
+
: (existingManifest?.updatedAt ?? importedAt),
|
|
156
177
|
documents,
|
|
157
178
|
};
|
|
158
179
|
await writeSourceManifest(paths.sourceDir, manifest);
|
|
@@ -64,7 +64,14 @@ function safeRunSummary(value) {
|
|
|
64
64
|
const status = String(node.status ?? "");
|
|
65
65
|
if (!id || !status)
|
|
66
66
|
return [];
|
|
67
|
-
|
|
67
|
+
const failureCategory = String(node.failureCategory ?? "");
|
|
68
|
+
return [
|
|
69
|
+
{
|
|
70
|
+
id,
|
|
71
|
+
status,
|
|
72
|
+
...(failureCategory ? { failureCategory } : {}),
|
|
73
|
+
},
|
|
74
|
+
];
|
|
68
75
|
})
|
|
69
76
|
.slice(0, 20);
|
|
70
77
|
}
|
|
@@ -728,13 +728,15 @@ export async function handlePutDeferredTurn(req, res, deps, sessionId) {
|
|
|
728
728
|
return;
|
|
729
729
|
}
|
|
730
730
|
const active = deps.events.getActiveTurn(sessionId);
|
|
731
|
-
|
|
731
|
+
// Queueing binds to the active Turn (running OR stopping); the durable
|
|
732
|
+
// follow-up auto-dispatches when that Turn reaches a terminal state.
|
|
733
|
+
if (!active || active.turnId !== blockedByTurnId) {
|
|
732
734
|
sendJson(res, 409, {
|
|
733
735
|
ok: false,
|
|
734
736
|
accepted: false,
|
|
735
737
|
error: {
|
|
736
|
-
code: "
|
|
737
|
-
message: "
|
|
738
|
+
code: "TURN_NOT_ACTIVE",
|
|
739
|
+
message: "没有匹配的运行中 Turn,无法保存待发送消息",
|
|
738
740
|
},
|
|
739
741
|
activeTurn: active ? turnSummary(active) : null,
|
|
740
742
|
});
|
|
@@ -80,3 +80,21 @@ export function pickInspectNode(nodes, preferredNodeId) {
|
|
|
80
80
|
});
|
|
81
81
|
return running ?? nodes[0];
|
|
82
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Terminal DagRun effective/status values (mirrors observe read-model
|
|
85
|
+
* TERMINAL_RUN_STATUSES). A run that reached one of these states no longer
|
|
86
|
+
* needs live polling in the console split panel.
|
|
87
|
+
*/
|
|
88
|
+
export const TERMINAL_DAG_RUN_STATUSES = new Set([
|
|
89
|
+
"finished",
|
|
90
|
+
"failed",
|
|
91
|
+
"partial_failed",
|
|
92
|
+
"superseded",
|
|
93
|
+
"abandoned",
|
|
94
|
+
]);
|
|
95
|
+
export function isTerminalDagRun(dag) {
|
|
96
|
+
if (!dag)
|
|
97
|
+
return false;
|
|
98
|
+
const status = String(dag.effectiveStatus ?? dag.status ?? "").toLowerCase();
|
|
99
|
+
return TERMINAL_DAG_RUN_STATUSES.has(status);
|
|
100
|
+
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* - A run summary is a projection only: it can never change the terminal
|
|
14
14
|
* operation state decided by the command envelope/exit facts.
|
|
15
15
|
*/
|
|
16
|
+
import { normalizeDagFailureCategory } from "../../shared/dag-failure-category.js";
|
|
16
17
|
import { scrubSecrets } from "./chat/explore-tools.js";
|
|
17
18
|
const RUN_SUMMARY_MAX_NODES = 20;
|
|
18
19
|
const RUN_SUMMARY_MAX_TEXT_CHARS = 600;
|
|
@@ -72,7 +73,13 @@ function safeNode(value) {
|
|
|
72
73
|
const status = boundedRedactedText(rec.status, 100);
|
|
73
74
|
if (!id || !status)
|
|
74
75
|
return undefined;
|
|
75
|
-
|
|
76
|
+
const rawCategory = boundedRedactedText(rec.failureCategory, 200);
|
|
77
|
+
if (!rawCategory)
|
|
78
|
+
return { id, status };
|
|
79
|
+
const category = normalizeDagFailureCategory(rawCategory, status);
|
|
80
|
+
if (category === "success" || category === "skipped")
|
|
81
|
+
return { id, status };
|
|
82
|
+
return { id, status, failureCategory: category };
|
|
76
83
|
}
|
|
77
84
|
/** Independent allowlist projection of a structured run summary. */
|
|
78
85
|
export function safeRunSummaryForProjection(value) {
|
|
@@ -117,13 +124,22 @@ export function safeRunSummaryForProjection(value) {
|
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
126
|
const verdict = boundedRedactedText(rec.verdict);
|
|
120
|
-
const
|
|
127
|
+
const rawFailureCategory = boundedRedactedText(rec.failureCategory, 200);
|
|
128
|
+
// Normalize the run-level category too (2026-08-23): raw codes like
|
|
129
|
+
// missing-api-key / nonzero-exit never matched the browser advice table.
|
|
130
|
+
const failureCategory = rawFailureCategory !== undefined
|
|
131
|
+
? normalizeDagFailureCategory(rawFailureCategory, status)
|
|
132
|
+
: undefined;
|
|
121
133
|
return {
|
|
122
134
|
runId,
|
|
123
135
|
status,
|
|
124
136
|
nodes,
|
|
125
137
|
...(verdict !== undefined ? { verdict } : {}),
|
|
126
|
-
...(failureCategory !== undefined
|
|
138
|
+
...(failureCategory !== undefined &&
|
|
139
|
+
failureCategory !== "success" &&
|
|
140
|
+
failureCategory !== "skipped"
|
|
141
|
+
? { failureCategory }
|
|
142
|
+
: {}),
|
|
127
143
|
...(outOfBounds.length > 0 ? { outOfBounds } : {}),
|
|
128
144
|
...(next ? { next } : {}),
|
|
129
145
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-Bw9nFjCJ.js";import{p as f}from"./chunk-JWPE2WC7-Dt75ZdBD.js";import{_ as n,l as o}from"./mermaid.core-BlvpGVG8.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-eTOts9L1.js";import"./index-DBh_x_Ek.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-BlvpGVG8.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|