@tea-agent/loop-agent 0.43.0-next.2 → 0.43.0-next.3

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 (72) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/application/dag/run-dag.js +5 -0
  3. package/dist/build-stamp.json +3 -3
  4. package/dist/executors/dag-pi-executor.js +274 -172
  5. package/dist/shared/frontend-execution-policy.js +1 -0
  6. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-B0Q0nClf.js → abnfDiagram-N423BO3Z-hUmM_GRf.js} +1 -1
  7. package/dist/worker/console/static/assets/{arc-DCPjC19G.js → arc-Bt-xuieW.js} +1 -1
  8. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP5n9jmG.js → architectureDiagram-T3A2C74G-DTqkL4DJ.js} +1 -1
  9. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CmaWi_Wg.js → blockDiagram-VBNYF7ZC-Cy0MNnzV.js} +1 -1
  10. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-Ct5tcMfZ.js → c4Diagram-5PPSVZJV-DDdlT0Pd.js} +1 -1
  11. package/dist/worker/console/static/assets/channel-BpzRnZmU.js +1 -0
  12. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-C0osm1Zf.js → chunk-2GRJ4B5K-3JawwNZ6.js} +1 -1
  13. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CDWviED7.js → chunk-2Q5K7J3B-DoTp7Cri.js} +1 -1
  14. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-mtSk1-j7.js → chunk-5RXB4S5H-CcirhZaS.js} +1 -1
  15. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D5J9PHC7.js → chunk-5VM5RSS4-VrG21gnP.js} +1 -1
  16. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Begg4WAa.js → chunk-6Q2QTUOP-DDOgIS70.js} +1 -1
  17. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-sF1AEy7T.js → chunk-GF5L2VYU-CBjmgvJ_.js} +1 -1
  18. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BqbsWXZb.js → chunk-JWPE2WC7-CCQSht8M.js} +1 -1
  19. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BKJrPcJ6.js → chunk-KBJHAD2P-BpGMkUUV.js} +1 -1
  20. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CcwNMRho.js → chunk-RYQCIY6F-DNDT41QL.js} +1 -1
  21. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BEJi3iIs.js → chunk-XXDRQBXY-euXnDFbn.js} +1 -1
  22. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BhlMVqCc.js +1 -0
  23. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BhlMVqCc.js +1 -0
  24. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-DRLgTvVu.js → cose-bilkent-JH36ORCC-BJ6NAeql.js} +1 -1
  25. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BoAVG3cs.js → cynefin-VYW2F7L2-F5JKIvIq.js} +1 -1
  26. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Bzol06hR.js → cynefinDiagram-MW4NZA55-Cwmkl_Gi.js} +1 -1
  27. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UmliJM77.js → dagre-VZM6K2ZE-BmCZ8815.js} +1 -1
  28. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BWLcJkFo.js → diagram-7IWD3JNH-zWA3hUnX.js} +1 -1
  29. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CgApOm-O.js → diagram-B4RE2ZJO-BzA-888F.js} +1 -1
  30. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-Bh3RgTLs.js → diagram-LBJQPF4R-tPNheoch.js} +1 -1
  31. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Dsh-D5nE.js → diagram-Q27KOJAE-Cdi7Fyqp.js} +1 -1
  32. package/dist/worker/console/static/assets/{diagram-UB23O5K3-Dkbbpcpb.js → diagram-UB23O5K3-DFK9VBf1.js} +1 -1
  33. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-3EBaA3t3.js → ebnfDiagram-BXEA7PRR-xCUr1kpg.js} +1 -1
  34. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bq2Dc5ok.js → erDiagram-JOGREHBK-BANQHY_A.js} +1 -1
  35. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-De7y55ha.js → flowDiagram-UKHOOZJN-VHJYEMkP.js} +1 -1
  36. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-fLiDbQRh.js → ganttDiagram-PKOTCBZU-DiyZQ0C6.js} +1 -1
  37. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Du617mp1.js → gitGraphDiagram-DS77QQ5N-CZtIeBBa.js} +1 -1
  38. package/dist/worker/console/static/assets/index-BlN6ytLr.css +1 -0
  39. package/dist/worker/console/static/assets/{index-C0O48S_P.js → index-CA-jfWlE.js} +1 -1
  40. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BwmlF-XP.js → infoDiagram-6WML65LV-BuSspC0X.js} +1 -1
  41. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-zsGtS59u.js → ishikawaDiagram-WSZJBQD7-DRJZyPFy.js} +1 -1
  42. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DTTPTe3f.js → journeyDiagram-NVQOT4AX-DIfXIVuE.js} +1 -1
  43. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BkXg9aP-.js → kanban-definition-27J2QSJJ-CT10_7Lt.js} +1 -1
  44. package/dist/worker/console/static/assets/{linear-7U2ue5IE.js → linear-ufemj74H.js} +1 -1
  45. package/dist/worker/console/static/assets/{mermaid.core-BUuGHmWO.js → mermaid.core-DEQe8-_m.js} +5 -5
  46. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-7q6fX0Sv.js → mindmap-definition-FAOFIHXS-BRLUrbrC.js} +1 -1
  47. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CkQPJN55.js → pegDiagram-VL7TDLO6-BgibKtiF.js} +1 -1
  48. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CCal_tfX.js → pieDiagram-7S7Q4E2Y-D3eyfdV9.js} +1 -1
  49. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js → quadrantDiagram-CIZ2JOQS-DXeTk5Px.js} +1 -1
  50. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CJmww7D-.js → railroadDiagram-AXF67PYL-BgXdFEe7.js} +1 -1
  51. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D6ldWJEv.js → requirementDiagram-LRYGKXZP-CseC2A7R.js} +1 -1
  52. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-VGh33I9e.js → sankeyDiagram-W5VNT64P-D80PFzfJ.js} +1 -1
  53. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CCkDrIjU.js → sequenceDiagram-SI44F4Z6-BWzHW7LS.js} +1 -1
  54. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-NC8f5Otb.js → sizeCapture-X5ZJPWSS-xWQYTLAn.js} +1 -1
  55. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-_92ezZdF.js → stateDiagram-OKZ733FA-CLxtpZeL.js} +1 -1
  56. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-CiVoq4G-.js +1 -0
  57. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BdUCGtbP.js → swimlanes-SLNWSIFB-DwugtmWV.js} +2 -2
  58. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BkdgdpfR.js +8 -0
  59. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CdD1H8ia.js → timeline-definition-Z64GVDOM-DHEOwHIe.js} +1 -1
  60. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-Dkdk3oFo.js → vennDiagram-T6HMQDX7-pmbZKlBK.js} +1 -1
  61. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CKu2uPPY.js → wardleyDiagram-T6FBY63Y-CivHoM5q.js} +1 -1
  62. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-ClqAnuG8.js → xychartDiagram-ELKLHX3M-BfHIE7o6.js} +1 -1
  63. package/dist/worker/console/static/index.html +2 -2
  64. package/dist/workflows/dag/frontend-shape.js +30 -1
  65. package/dist/workflows/dag/node-execution.js +6 -0
  66. package/package.json +1 -1
  67. package/dist/worker/console/static/assets/channel-DAS07MdS.js +0 -1
  68. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cwk-5jiW.js +0 -1
  69. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cwk-5jiW.js +0 -1
  70. package/dist/worker/console/static/assets/index-CzKf4U8P.css +0 -1
  71. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyJg5gzW.js +0 -1
  72. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B1cw_0Uy.js +0 -8
package/CHANGELOG.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  ### 改进
6
6
 
7
+ - 前端 DAG 修正否定约束导致的小任务误升级;Plan 在分片前统一 compact 判定并保留完整执行组。支持冻结 coverage 并发上限(1–4,默认 4),限流后减少后续并发且不增加重试。自动恢复子进程与 DAG 共用长跑超时,避免继承通用 120 秒上限而中途终止。
7
8
  - 前端 DAG 保留完整需求并按作用域/执行组分批,工具提交改为先校验和耐久保存再回执;支持按组共享覆盖、逐端点/逐 finding 提交和缺项恢复。小任务走短流程,容量耗尽直接缩小剩余工作;模型窗口不再硬编码为 100K/16K。独立 AC、来源保真与 writer/verify 门禁保持有效。
8
9
  - 观测台阅读与口径修补:失败节点的产出页把「错误输出」提到正文之前,未登记文件关系时不再展示空文件卡;检查器 Tab 条放不下时两端渐隐提示并保证选中 Tab 可见,每页顶部说明卡可收起。异常 Task 的分类与建议跟进显示中文业务术语(未知 token 原样透传并可悬停看原始值),资源池「合计」改为口径明确的「已建 Task」并附悬停说明,数据更新文案改为「数据更新于 … · 仅提示」。DAG 详情面包屑使用可读运行标题(缺失回退运行 ID、窄屏截断),「记录保存位置」移入「诊断信息」折叠区,页面刷新按钮与标题同行靠右。
9
10
  - 观测台保留检查器 Tab 导航,日志分类收进下拉框,辅助操作改为带提示的图标;所有执行记录区域(检查器执行记录/产出、运行页最新输出)统一配备对话式「回到底部」悬浮按钮:内容可滚动且视口离开底部即出现,贴底或内容不足一屏时隐藏,点击回到底部;活跃运行同时恢复跟随并提示未读条数,终态运行同样可用。执行分次仅在相关页面固定显示,上翻暂停跟随,并记住分次阅读位置。补充日志搜索、错误过滤、图定位和完整脱敏文本下载。
@@ -15,6 +16,7 @@
15
16
 
16
17
  ### 修复
17
18
 
19
+ - 前端 Plan 重试复用首次冻结的分片归属,避免重试提示词变长导致进度绑定不匹配或重复处理已完成需求;布局缺失、损坏或漂移时保留证据并阻断派发。风险路由仅忽略完整的范围排除声明,条件句和嵌套否定中的真实权限风险在生成期与运行期均保持升级。
18
20
  - 执行记录搜索直接高亮命中文字,标识当前跳转记录;未搜索或无匹配时禁用上下箭头,清空搜索恢复原文。
19
21
 
20
22
  - 恢复运行在导入节点缺少明确读取范围时阻断工作区漂移,避免复用受变更影响的旧结果;读取范围明确且不受影响时仍可按路径复用。
@@ -1,4 +1,5 @@
1
1
  import path from "node:path";
2
+ import { DAG_ABSOLUTE_MAX_WALL_CLOCK_MS } from "../../shared/timeout-policy.js";
2
3
  import { createDagEventObserver } from "../../workflows/dag/event-observer.js";
3
4
  import { composeDagRunObservers } from "../../workflows/dag/observer-compose.js";
4
5
  import { createDagCanvasObserver, resolveCanvasPath, } from "../../workflows/dag/canvas-observer.js";
@@ -47,6 +48,9 @@ export async function buildDefaultFrontendRecoveryDeps(repoRoot) {
47
48
  });
48
49
  const client = new LoopAgentClient({
49
50
  loopAgentBin: resolveSiblingLoopAgentBin(),
51
+ // rerun-task awaits the entire continuation, not just task preparation.
52
+ // Use the same hard ceiling as the DAG runner and Console entry point.
53
+ defaultTimeoutMs: DAG_ABSOLUTE_MAX_WALL_CLOCK_MS,
50
54
  artifactRoot: path.join(appData.root, "client-artifacts", appData.fingerprint),
51
55
  resolveIdentity: true,
52
56
  });
@@ -54,6 +58,7 @@ export async function buildDefaultFrontendRecoveryDeps(repoRoot) {
54
58
  store,
55
59
  operationRunnerDeps: {
56
60
  store,
61
+ defaultTimeoutMs: DAG_ABSOLUTE_MAX_WALL_CLOCK_MS,
57
62
  events,
58
63
  client,
59
64
  repoRoot,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.43.0-next.2",
4
- "gitSha": "d9e11f1ac55b0bfff4b42fd43616810cf15bb575",
5
- "builtAt": "2026-09-07T07:08:47.369Z"
3
+ "version": "0.43.0-next.3",
4
+ "gitSha": "58353199a043d50d24063322a173d81b4b8f1d2f",
5
+ "builtAt": "2026-09-08T04:08:10.997Z"
6
6
  }
@@ -1,6 +1,8 @@
1
1
  import { collectFrontendExecutionGroups, frontendExecutionSchema } from "../workflows/dag/frontend-execution-groups.js";
2
2
  import { FRONTEND_SCOPE_TARGET_BYTES, packFrontendInputUnits, parseFrontendInputBlock, projectFrontendContractPrompt, projectFrontendInputScope } from "../workflows/dag/frontend-input-projection.js";
3
3
  import { createDurableFrontendTools } from "../workflows/dag/frontend-durable-tools.js";
4
+ import { sha256OfCanonicalJson } from "../task/contract/hash.js";
5
+ import { z } from "zod";
4
6
  import { createFrontendReviewScopeProtocol, loadFrontendReviewScopes } from "../workflows/dag/frontend-review-scopes.js";
5
7
  import { observeFrontendSession } from "../workflows/dag/frontend-session-budget.js";
6
8
  import path from "node:path";
@@ -3908,18 +3910,30 @@ const FRONTEND_PLAN_COVERAGE_MAX_CONCURRENCY = 4;
3908
3910
  const FRONTEND_PLAN_BATCH_MAX_SESSIONS = 128;
3909
3911
  const FRONTEND_PLAN_SMALL_MAX_REQUIREMENTS = 8;
3910
3912
  const FRONTEND_PLAN_SMALL_MAX_ESTIMATED_CALLS = 24;
3911
- async function mapWithConcurrency(items, limit, worker) {
3913
+ async function mapWithConcurrency(items, limit, worker, shouldReduceConcurrency) {
3912
3914
  const results = new Array(items.length);
3913
3915
  let nextIndex = 0;
3914
- const workerCount = Math.min(Math.max(1, limit), items.length);
3915
- await Promise.all(Array.from({ length: workerCount }, async () => {
3916
- while (true) {
3917
- const index = nextIndex++;
3918
- if (index >= items.length)
3919
- return;
3920
- results[index] = await worker(items[index], index);
3916
+ let concurrency = Math.max(1, limit);
3917
+ const running = new Map();
3918
+ try {
3919
+ while (nextIndex < items.length || running.size > 0) {
3920
+ while (nextIndex < items.length && running.size < concurrency) {
3921
+ const index = nextIndex++;
3922
+ running.set(index, worker(items[index], index).then(result => ({ index, result })));
3923
+ }
3924
+ const { index, result } = await Promise.race(running.values());
3925
+ running.delete(index);
3926
+ results[index] = result;
3927
+ // Drain existing work; only pending shards use the reduced cap.
3928
+ // Failed shards remain failed and receive no extra retry allowance.
3929
+ if (shouldReduceConcurrency(result))
3930
+ concurrency = Math.max(1, Math.floor(concurrency / 2));
3921
3931
  }
3922
- }));
3932
+ }
3933
+ catch (error) {
3934
+ await Promise.allSettled(running.values());
3935
+ throw error;
3936
+ }
3923
3937
  return results;
3924
3938
  }
3925
3939
  function compactPromptString(value, _maxChars) {
@@ -4522,6 +4536,110 @@ export async function runFrontendContractSegmentedSessions(input) {
4522
4536
  input.tools.setActiveRequirementScope(null);
4523
4537
  }
4524
4538
  }
4539
+ /** One workload view for both the outer parallel map and inner session queue.
4540
+ * A declared execution group is an indivisible unit during initial packing. */
4541
+ function buildFrontendPlanWorkload(input) {
4542
+ const allRequirementIds = input.requirementIds;
4543
+ const compiledInput = parseFrontendInputBlock(input.basePrompt, "plan")?.payload;
4544
+ const fullUnits = new Map(compiledInput?.requirements.map(r => [r.id, r]) ?? []);
4545
+ const declaredGroups = Array.isArray(compiledInput?.executionGroups)
4546
+ ? compiledInput.executionGroups.filter(isRecordObject) : [];
4547
+ const workGroups = declaredGroups.map(g => ({
4548
+ id: String(g.id), kind: String(g.kind),
4549
+ requirementIds: Array.isArray(g.requirementIds)
4550
+ ? g.requirementIds.filter((id) => typeof id === "string" && allRequirementIds.includes(id)) : [],
4551
+ })).filter(g => g.requirementIds.length);
4552
+ const groupedIds = new Set(workGroups.flatMap(g => g.requirementIds));
4553
+ for (const id of allRequirementIds) {
4554
+ if (!groupedIds.has(id))
4555
+ workGroups.push({ id, kind: "unclassified", requirementIds: [id] });
4556
+ }
4557
+ const workCost = (ids) => 1 + ids.reduce((total, id) => total + Math.max(1, (input.requirementCosts?.get(id) ?? 2) - 1), 0);
4558
+ const policy = input.sessionOptions.frontendExecutionPolicy;
4559
+ const targetBytes = policy?.scopeTargetBytes ?? FRONTEND_SCOPE_TARGET_BYTES;
4560
+ const userMessageBytes = Buffer.byteLength(input.sessionOptions.userMessage ?? "");
4561
+ const buildWorkBatches = (ids) => {
4562
+ const work = workGroups.flatMap((g, index) => {
4563
+ const members = g.requirementIds.filter(id => ids.includes(id));
4564
+ return members.length ? [{ id: `${index}:${g.id}`, requirementIds: members,
4565
+ requirements: members.map(id => fullUnits.get(id) ?? { id }), estimatedCalls: workCost(members) }] : [];
4566
+ });
4567
+ const scaffoldBytes = Buffer.byteLength(input.basePrompt.replace(/<frontend_plan_input>[\s\S]*?<\/frontend_plan_input>/, JSON.stringify({ ...compiledInput, requirements: [] }))) + userMessageBytes + Buffer.byteLength(JSON.stringify(input.coverageTools));
4568
+ return packFrontendInputUnits(work, {
4569
+ targetBytes: Math.max(1, targetBytes - scaffoldBytes),
4570
+ maxUnits: policy?.maxScopeUnits ?? 4,
4571
+ maxCost: FRONTEND_PLAN_COVERAGE_MAX_RECORD_CALLS, cost: g => g.estimatedCalls,
4572
+ }).map(batch => batch.flatMap(g => g.requirementIds));
4573
+ };
4574
+ // This renderer also carries the Plan's evolving UX checkpoint on resume.
4575
+ // Only the Contract/Scout-derived input participates in ownership binding.
4576
+ const { committedUx: _committedUx, ...frozenInput } = compiledInput ?? {};
4577
+ return {
4578
+ frozenInput, workGroups, buildWorkBatches,
4579
+ compactEligible: input.requirementCosts !== undefined &&
4580
+ workGroups.length <= FRONTEND_PLAN_SMALL_MAX_REQUIREMENTS &&
4581
+ Buffer.byteLength(input.basePrompt) + userMessageBytes + Buffer.byteLength(JSON.stringify(input.allTools)) <= targetBytes * 2 &&
4582
+ workGroups.reduce((total, group) => total + workCost(group.requirementIds), 0) <= FRONTEND_PLAN_SMALL_MAX_ESTIMATED_CALLS &&
4583
+ countFrontendPlanTargetSurfaces(input.basePrompt) === 1,
4584
+ };
4585
+ }
4586
+ const frontendPlanCoverageLayoutSchema = z.object({
4587
+ schemaVersion: z.literal(1),
4588
+ bindingSha256: z.string(),
4589
+ coverageBatches: z.array(z.array(z.string().min(1)).min(1)).min(1),
4590
+ layoutSha256: z.string(),
4591
+ }).strict();
4592
+ /** Freeze ledger ownership before any provider call. Session packing remains
4593
+ * adaptive inside each owner, but retry instructions cannot rename its scope. */
4594
+ async function loadOrCreateFrontendPlanCoverageLayout(input) {
4595
+ const fileName = "coverage-layout.json";
4596
+ const file = path.join(input.runDir, input.nodeId, fileName);
4597
+ const bindingSha256 = sha256OfCanonicalJson(input.binding);
4598
+ let raw;
4599
+ try {
4600
+ raw = await readFile(file, "utf8");
4601
+ }
4602
+ catch (error) {
4603
+ if (error.code !== "ENOENT")
4604
+ throw error;
4605
+ }
4606
+ let layout;
4607
+ if (raw !== undefined) {
4608
+ layout = frontendPlanCoverageLayoutSchema.parse(JSON.parse(raw));
4609
+ }
4610
+ else {
4611
+ // Losing the ownership receipt must never repartition acknowledged facts.
4612
+ for (const relative of ["plan-typed-facts.jsonl", "parallel"]) {
4613
+ const existing = await stat(path.join(input.runDir, input.nodeId, relative)).catch(error => {
4614
+ if (error.code !== "ENOENT")
4615
+ throw error;
4616
+ return undefined;
4617
+ });
4618
+ if (existing && (existing.isDirectory() || existing.size > 0)) {
4619
+ throw Error("FRONTEND_PLAN_LAYOUT_MISSING: preserve the existing ledger and restart its owning phase");
4620
+ }
4621
+ }
4622
+ const descriptor = {
4623
+ schemaVersion: 1, bindingSha256,
4624
+ coverageBatches: input.workload.compactEligible ? [input.requirementIds] : input.workload.buildWorkBatches(input.requirementIds),
4625
+ };
4626
+ layout = { ...descriptor, layoutSha256: sha256OfCanonicalJson(descriptor) };
4627
+ }
4628
+ const { layoutSha256, ...descriptor } = layout;
4629
+ if (layout.bindingSha256 !== bindingSha256 || layoutSha256 !== sha256OfCanonicalJson(descriptor)) {
4630
+ throw Error("FRONTEND_PLAN_LAYOUT_MISMATCH: frozen coverage ownership or input binding changed");
4631
+ }
4632
+ const members = layout.coverageBatches.flat();
4633
+ const owners = new Map(layout.coverageBatches.flatMap((batch, index) => batch.map(id => [id, index])));
4634
+ if (members.length !== owners.size || members.length !== input.requirementIds.length ||
4635
+ input.requirementIds.some(id => !owners.has(id)) ||
4636
+ input.workload.workGroups.some(group => new Set(group.requirementIds.map(id => owners.get(id))).size !== 1)) {
4637
+ throw Error("FRONTEND_PLAN_LAYOUT_INVALID: coverage must partition complete execution groups exactly once");
4638
+ }
4639
+ if (raw === undefined)
4640
+ await writeDagNodeJsonArtifact(input.runDir, input.nodeId, fileName, layout);
4641
+ return layout.coverageBatches;
4642
+ }
4525
4643
  export async function runFrontendPlanSegmentedSessions(input) {
4526
4644
  const queue = [];
4527
4645
  const coverageSegment = FRONTEND_PLAN_SEGMENTS.find((segment) => segment.id === "coverage");
@@ -4709,25 +4827,12 @@ export async function runFrontendPlanSegmentedSessions(input) {
4709
4827
  tokensUsed: 0,
4710
4828
  };
4711
4829
  }
4712
- const compiledInput = parseFrontendInputBlock(input.basePrompt, "plan")?.payload;
4713
- const fullUnits = new Map(compiledInput?.requirements.map(r => [r.id, r]) ?? []);
4714
- const declaredGroups = Array.isArray(compiledInput?.executionGroups) ? compiledInput.executionGroups.filter(isRecordObject) : [];
4715
- const workGroups = declaredGroups.length ? declaredGroups.map(g => ({ id: String(g.id), kind: String(g.kind), requirementIds: Array.isArray(g.requirementIds) ? g.requirementIds.filter((id) => typeof id === "string" && allRequirementIds.includes(id)) : [] })).filter(g => g.requirementIds.length) : allRequirementIds.map(id => ({ id, kind: "unclassified", requirementIds: [id] }));
4716
- const groupedIds = new Set(workGroups.flatMap(g => g.requirementIds));
4717
- for (const id of allRequirementIds)
4718
- if (!groupedIds.has(id))
4719
- workGroups.push({ id, kind: "unclassified", requirementIds: [id] });
4720
- const workCost = (ids) => 1 + ids.reduce((total, id) => total + Math.max(1, (input.requirementCosts?.get(id) ?? 2) - 1), 0);
4721
- const buildWorkBatches = (ids) => {
4722
- const work = workGroups.flatMap((g, index) => {
4723
- const members = g.requirementIds.filter(id => ids.includes(id));
4724
- return members.length ? [{ id: `${index}:${g.id}`, requirementIds: members, requirements: members.map(id => fullUnits.get(id) ?? { id }), estimatedCalls: workCost(members) }] : [];
4725
- });
4726
- const scaffoldBytes = Buffer.byteLength(input.basePrompt.replace(/<frontend_plan_input>[\s\S]*?<\/frontend_plan_input>/, JSON.stringify({ ...compiledInput, requirements: [] }))) + Buffer.byteLength(JSON.stringify(input.segmentCustomTools(coverageSegment.toolNames)));
4727
- return packFrontendInputUnits(work, { targetBytes: Math.max(1, (input.sessionOptions.frontendExecutionPolicy?.scopeTargetBytes ?? FRONTEND_SCOPE_TARGET_BYTES) - scaffoldBytes), maxUnits: input.sessionOptions.frontendExecutionPolicy?.maxScopeUnits ?? 4, maxCost: FRONTEND_PLAN_COVERAGE_MAX_RECORD_CALLS, cost: g => g.estimatedCalls }).map(batch => batch.flatMap(g => g.requirementIds));
4728
- };
4729
- const estimatedCalls = workGroups.reduce((total, group) => total + workCost(group.requirementIds), 0);
4730
- const targetSurfaceCount = countFrontendPlanTargetSurfaces(input.basePrompt);
4830
+ const { workGroups, buildWorkBatches, compactEligible } = buildFrontendPlanWorkload({
4831
+ basePrompt: input.basePrompt, requirementIds: allRequirementIds,
4832
+ requirementCosts: input.requirementCosts, sessionOptions: input.sessionOptions,
4833
+ coverageTools: input.segmentCustomTools(coverageSegment.toolNames),
4834
+ allTools: input.segmentCustomTools(null),
4835
+ });
4731
4836
  // Small, single-surface requests do not benefit from six isolated Pi
4732
4837
  // sessions. Keep the typed ledger as the authority, but let one local
4733
4838
  // session establish requirement/UX facts and one final session establish
@@ -4735,11 +4840,7 @@ export async function runFrontendPlanSegmentedSessions(input) {
4735
4840
  // for larger plans and for the unscoped compatibility path.
4736
4841
  const useCompactSmallPlan = requirementIdsProvided &&
4737
4842
  input.compactSmallPlan === true &&
4738
- input.requirementCosts !== undefined &&
4739
- workGroups.length <= FRONTEND_PLAN_SMALL_MAX_REQUIREMENTS &&
4740
- Buffer.byteLength(input.basePrompt) + Buffer.byteLength(JSON.stringify(input.segmentCustomTools(null))) <= (input.sessionOptions.frontendExecutionPolicy?.scopeTargetBytes ?? FRONTEND_SCOPE_TARGET_BYTES) * 2 &&
4741
- estimatedCalls <= FRONTEND_PLAN_SMALL_MAX_ESTIMATED_CALLS &&
4742
- targetSurfaceCount === 1;
4843
+ compactEligible;
4743
4844
  if (useCompactSmallPlan) {
4744
4845
  const compactLocalTools = new Set([
4745
4846
  "record_plan_requirement",
@@ -5954,160 +6055,161 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
5954
6055
  flushLedger: () => options.ledgerTools.flush(),
5955
6056
  });
5956
6057
  if (planRequirementIds.length > 1) {
5957
- const estimatedPlanCalls = planRequirementIds.reduce((total, id) => total + Math.max(1, planRequirementCosts.get(id) ?? 2), 0);
5958
- const compactEligibleBeforeSharding = planRequirementIds.length <= FRONTEND_PLAN_SMALL_MAX_REQUIREMENTS &&
5959
- estimatedPlanCalls > 12 &&
5960
- estimatedPlanCalls <= FRONTEND_PLAN_SMALL_MAX_ESTIMATED_CALLS &&
5961
- countFrontendPlanTargetSurfaces(input.prompt) === 1;
5962
- if (compactEligibleBeforeSharding) {
5963
- // Decide the small-plan topology before creating coverage shards.
5964
- // Sharding first would make the compact two-session path unreachable.
5965
- result = await runPlanSessions({
5966
- ledgerTools: planLedgerTools,
5967
- sessionOptions: piSessionOptions,
5968
- compactSmallPlan: true,
6058
+ const coverageTools = FRONTEND_PLAN_SEGMENTS.find(segment => segment.id === "coverage").toolNames;
6059
+ const workload = buildFrontendPlanWorkload({
6060
+ basePrompt: input.prompt, requirementIds: planRequirementIds,
6061
+ requirementCosts: planRequirementCosts, sessionOptions: piSessionOptions,
6062
+ allTools: planLedgerTools.customTools,
6063
+ coverageTools: planLedgerTools.customTools.filter(tool => isRecordObject(tool) && coverageTools.has(String(tool.name))),
6064
+ });
6065
+ let coverageBatches;
6066
+ try {
6067
+ coverageBatches = await loadOrCreateFrontendPlanCoverageLayout({
6068
+ runDir: meta.runDir, nodeId: input.task.id, workload, requirementIds: planRequirementIds,
6069
+ binding: {
6070
+ runId: meta.runId, nodeId: input.task.id, sourceBinding: meta.spec.sourceBinding,
6071
+ skeleton: input.task.structuredContractOutput?.skeleton, writeSet: input.task.writeSet,
6072
+ policy: meta.spec.frontendExecutionPolicy, requirements: [...planRequirementCosts],
6073
+ compiledInput: workload.frozenInput, workGroups: workload.workGroups,
6074
+ },
5969
6075
  });
5970
6076
  }
5971
- else {
5972
- const coverageBatches = batchFrontendPlanRequirements({
5973
- requirementIds: planRequirementIds,
5974
- maxEstimatedRecordCalls: FRONTEND_PLAN_COVERAGE_MAX_RECORD_CALLS,
5975
- maxRequirements: 4,
5976
- requirementCosts: planRequirementCosts,
5977
- });
5978
- if (coverageBatches.length > 1) {
5979
- const shardResults = await mapWithConcurrency(coverageBatches, FRONTEND_PLAN_COVERAGE_MAX_CONCURRENCY, async (slice, index) => {
5980
- let shardTools;
5981
- let shardResult;
5982
- try {
5983
- const { createTypedEventStore } = await import("../workflows/dag/frontend-typed-event-store.js");
5984
- shardTools = await createFrontendPlanLedgerTools({
5985
- attemptId: `${meta.runId}:${input.task.id}:parallel:${index + 1}`,
5986
- store: createTypedEventStore(),
6077
+ catch (error) {
6078
+ return { ok: false, stdout: "", durationMs: Date.now() - started, failureCategory: "tool-policy",
6079
+ stderr: `frontend plan coverage layout unavailable: ${error instanceof Error ? error.message : String(error)}` };
6080
+ }
6081
+ if (coverageBatches.length > 1) {
6082
+ const shardResults = await mapWithConcurrency(coverageBatches, piSessionOptions.frontendExecutionPolicy?.maxCoverageConcurrency ?? FRONTEND_PLAN_COVERAGE_MAX_CONCURRENCY, async (slice, index) => {
6083
+ let shardTools;
6084
+ let shardResult;
6085
+ try {
6086
+ const { createTypedEventStore } = await import("../workflows/dag/frontend-typed-event-store.js");
6087
+ shardTools = await createFrontendPlanLedgerTools({
6088
+ attemptId: `${meta.runId}:${input.task.id}:parallel:${index + 1}`,
6089
+ store: createTypedEventStore(),
6090
+ runDir: meta.runDir,
6091
+ nodeId: `${input.task.id}/parallel/coverage-${index + 1}`,
6092
+ skeleton: input.task.structuredContractOutput?.skeleton,
6093
+ sourceBinding: meta.spec.sourceBinding,
6094
+ requirementIds: slice,
6095
+ writeSetPatterns: input.task.writeSet,
6096
+ canonicalVerificationTargetIds: await resolveFrontendCanonicalVerificationTargetIds({
5987
6097
  runDir: meta.runDir,
5988
- nodeId: `${input.task.id}/parallel/coverage-${index + 1}`,
5989
- skeleton: input.task.structuredContractOutput?.skeleton,
6098
+ }),
6099
+ componentNewSourceReferences: await resolveFrontendPlanNewComponentSourceReferences({
6100
+ cwd: input.cwd,
5990
6101
  sourceBinding: meta.spec.sourceBinding,
5991
- requirementIds: slice,
5992
- writeSetPatterns: input.task.writeSet,
5993
- canonicalVerificationTargetIds: await resolveFrontendCanonicalVerificationTargetIds({
5994
- runDir: meta.runDir,
5995
- }),
5996
- componentNewSourceReferences: await resolveFrontendPlanNewComponentSourceReferences({
5997
- cwd: input.cwd,
5998
- sourceBinding: meta.spec.sourceBinding,
5999
- }),
6000
- });
6001
- const shardSessionOptions = {
6002
- ...piSessionOptions,
6003
- sessionEventsPath: path.join(meta.runDir, input.task.id, "parallel", `coverage-${index + 1}`, "session-events.jsonl"),
6004
- };
6005
- shardResult = await runPlanSessions({
6006
- ledgerTools: shardTools,
6007
- sessionOptions: shardSessionOptions,
6008
- requirementIds: slice,
6009
- basePrompt: `${input.prompt}\n\nPARALLEL COVERAGE SHARD ${index + 1}: use the frozen canonical behavior verification-target ids listed in the record_plan_verification_target tool description — do not prefix ids with a shard namespace or invent variant ids; identical cross-shard targets are deduped, divergent ones fail the merge.`,
6010
- parallelCoverageOnly: true,
6011
- observation: {
6012
- artifactPath: path.join(meta.runDir, input.task.id, "parallel", `coverage-${index + 1}`, "session-budget", `attempt-${input.attempt ?? 1}`),
6013
- runId: meta.runId,
6014
- nodeId: `${input.task.id}/parallel/coverage-${index + 1}`,
6015
- taskId: meta.spec?.sourceBinding?.taskId,
6016
- attempt: input.attempt ?? 1,
6017
- model: input.model,
6018
- sourceDigest: meta.spec?.sourceBinding?.schemaVersion === 2 ? meta.spec.sourceBinding.inputDigest : undefined,
6019
- contractDigest: meta.spec?.taskContractBinding?.canonicalHash,
6020
- },
6021
- });
6022
- await shardTools.flush();
6023
- return { index, result: shardResult, tools: shardTools };
6024
- }
6025
- catch (error) {
6026
- const crashMessage = `frontend plan coverage shard ${index + 1} crashed: ${error instanceof Error ? error.message : String(error)}`;
6027
- return {
6028
- index,
6029
- tools: shardTools,
6030
- result: shardResult
6031
- ? {
6032
- ...shardResult,
6033
- ok: false,
6034
- failureCategory: shardResult.ok
6035
- ? "invalid-output"
6036
- : shardResult.failureCategory,
6037
- stderr: [shardResult.stderr, crashMessage]
6038
- .filter(Boolean)
6039
- .join("\n"),
6040
- }
6041
- : {
6042
- ok: false,
6043
- assistantText: "",
6044
- command: [],
6045
- durationMs: 0,
6046
- exitCode: null,
6047
- failureCategory: "tool-policy",
6048
- modelDisplay: "unknown",
6049
- parsedEvents: 0,
6050
- stderr: crashMessage,
6051
- stdout: "",
6052
- timedOut: false,
6053
- attemptedModels: [],
6054
- fallbackUsed: false,
6055
- tokensUsed: 0,
6056
- },
6057
- };
6058
- }
6059
- });
6060
- const coverageResult = aggregateParallelPiResults(shardResults.map((shard) => shard.result));
6061
- let mergeFailure;
6062
- try {
6063
- // Flatten every shard's facts FIRST, then pre-reduce: shards
6064
- // partition requirements but a frozen verification target can
6065
- // span shards, so same-id targets must merge across shards
6066
- // before adoption, not per shard.
6067
- await planLedgerTools.adoptCommittedFacts(reduceParallelCoverageShardRecords(shardResults
6068
- .filter((item) => item.result.ok && item.tools)
6069
- .flatMap((shard) => normalizeParallelCoverageShardRecords(shard.tools.committedFacts(), shard.index + 1))));
6070
- }
6071
- catch (error) {
6072
- mergeFailure = error;
6073
- }
6074
- const failedShard = shardResults.find((shard) => !shard.result.ok);
6075
- if (mergeFailure) {
6076
- result = {
6077
- ...coverageResult,
6078
- ok: false,
6079
- failureCategory: "invalid-output",
6080
- stderr: [
6081
- coverageResult.stderr,
6082
- `frontend plan coverage shard merge failed: ${mergeFailure instanceof Error ? mergeFailure.message : String(mergeFailure)}`,
6083
- ]
6084
- .filter(Boolean)
6085
- .join("\n"),
6102
+ }),
6103
+ });
6104
+ const shardSessionOptions = {
6105
+ ...piSessionOptions,
6106
+ sessionEventsPath: path.join(meta.runDir, input.task.id, "parallel", `coverage-${index + 1}`, "session-events.jsonl"),
6086
6107
  };
6108
+ shardResult = await runPlanSessions({
6109
+ ledgerTools: shardTools,
6110
+ sessionOptions: shardSessionOptions,
6111
+ requirementIds: slice,
6112
+ basePrompt: `${input.prompt}\n\nPARALLEL COVERAGE SHARD ${index + 1}: use the frozen canonical behavior verification-target ids listed in the record_plan_verification_target tool description — do not prefix ids with a shard namespace or invent variant ids; identical cross-shard targets are deduped, divergent ones fail the merge.`,
6113
+ parallelCoverageOnly: true,
6114
+ observation: {
6115
+ artifactPath: path.join(meta.runDir, input.task.id, "parallel", `coverage-${index + 1}`, "session-budget", `attempt-${input.attempt ?? 1}`),
6116
+ runId: meta.runId,
6117
+ nodeId: `${input.task.id}/parallel/coverage-${index + 1}`,
6118
+ taskId: meta.spec?.sourceBinding?.taskId,
6119
+ attempt: input.attempt ?? 1,
6120
+ model: input.model,
6121
+ sourceDigest: meta.spec?.sourceBinding?.schemaVersion === 2 ? meta.spec.sourceBinding.inputDigest : undefined,
6122
+ contractDigest: meta.spec?.taskContractBinding?.canonicalHash,
6123
+ },
6124
+ });
6125
+ await shardTools.flush();
6126
+ return { index, result: shardResult, tools: shardTools };
6087
6127
  }
6088
- else if (failedShard) {
6089
- result = {
6090
- ...coverageResult,
6091
- ok: false,
6092
- stderr: `${coverageResult.stderr}\nfrontend plan coverage shard ${failedShard.index + 1} failed before reduce`.trim(),
6128
+ catch (error) {
6129
+ const crashMessage = `frontend plan coverage shard ${index + 1} crashed: ${error instanceof Error ? error.message : String(error)}`;
6130
+ return {
6131
+ index,
6132
+ tools: shardTools,
6133
+ result: shardResult
6134
+ ? {
6135
+ ...shardResult,
6136
+ ok: false,
6137
+ failureCategory: shardResult.ok
6138
+ ? "invalid-output"
6139
+ : shardResult.failureCategory,
6140
+ stderr: [shardResult.stderr, crashMessage]
6141
+ .filter(Boolean)
6142
+ .join("\n"),
6143
+ }
6144
+ : {
6145
+ ok: false,
6146
+ assistantText: "",
6147
+ command: [],
6148
+ durationMs: 0,
6149
+ exitCode: null,
6150
+ failureCategory: "tool-policy",
6151
+ modelDisplay: "unknown",
6152
+ parsedEvents: 0,
6153
+ stderr: crashMessage,
6154
+ stdout: "",
6155
+ timedOut: false,
6156
+ attemptedModels: [],
6157
+ fallbackUsed: false,
6158
+ tokensUsed: 0,
6159
+ },
6093
6160
  };
6094
6161
  }
6095
- else {
6096
- const reducerResult = await runPlanSessions({
6097
- ledgerTools: planLedgerTools,
6098
- sessionOptions: piSessionOptions,
6099
- });
6100
- result = combineSequentialPiResults(coverageResult, reducerResult);
6101
- }
6162
+ }, shard => shard.result.failureCategory === "rate-limit");
6163
+ const coverageResult = aggregateParallelPiResults(shardResults.map((shard) => shard.result));
6164
+ let mergeFailure;
6165
+ try {
6166
+ // Flatten every shard's facts FIRST, then pre-reduce: shards
6167
+ // partition requirements but a frozen verification target can
6168
+ // span shards, so same-id targets must merge across shards
6169
+ // before adoption, not per shard.
6170
+ await planLedgerTools.adoptCommittedFacts(reduceParallelCoverageShardRecords(shardResults
6171
+ .filter((item) => item.result.ok && item.tools)
6172
+ .flatMap((shard) => normalizeParallelCoverageShardRecords(shard.tools.committedFacts(), shard.index + 1))));
6173
+ }
6174
+ catch (error) {
6175
+ mergeFailure = error;
6176
+ }
6177
+ const failedShard = shardResults.find((shard) => !shard.result.ok);
6178
+ if (mergeFailure) {
6179
+ result = {
6180
+ ...coverageResult,
6181
+ ok: false,
6182
+ failureCategory: "invalid-output",
6183
+ stderr: [
6184
+ coverageResult.stderr,
6185
+ `frontend plan coverage shard merge failed: ${mergeFailure instanceof Error ? mergeFailure.message : String(mergeFailure)}`,
6186
+ ]
6187
+ .filter(Boolean)
6188
+ .join("\n"),
6189
+ };
6190
+ }
6191
+ else if (failedShard) {
6192
+ result = {
6193
+ ...coverageResult,
6194
+ ok: false,
6195
+ stderr: `${coverageResult.stderr}\nfrontend plan coverage shard ${failedShard.index + 1} failed before reduce`.trim(),
6196
+ };
6102
6197
  }
6103
6198
  else {
6104
- result = await runPlanSessions({
6199
+ const reducerResult = await runPlanSessions({
6105
6200
  ledgerTools: planLedgerTools,
6106
6201
  sessionOptions: piSessionOptions,
6107
- compactSmallPlan: true,
6108
6202
  });
6203
+ result = combineSequentialPiResults(coverageResult, reducerResult);
6109
6204
  }
6110
6205
  }
6206
+ else {
6207
+ result = await runPlanSessions({
6208
+ ledgerTools: planLedgerTools,
6209
+ sessionOptions: piSessionOptions,
6210
+ compactSmallPlan: true,
6211
+ });
6212
+ }
6111
6213
  }
6112
6214
  else {
6113
6215
  result = await runPlanSessions({
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  export const frontendExecutionPolicySchema = z.object({
4
4
  scopeTargetBytes: z.number().int().positive().default(24_000),
5
5
  maxScopeUnits: z.number().int().positive().default(4),
6
+ maxCoverageConcurrency: z.number().int().min(1).max(4).default(4),
6
7
  outputReserveTokens: z.number().int().positive().default(4096),
7
8
  readGrowthReserveTokens: z.number().int().nonnegative().default(2048),
8
9
  safetyRatio: z.number().min(0).max(0.5).default(0.15),
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-Begg4WAa.js";import{p as f}from"./chunk-JWPE2WC7-BqbsWXZb.js";import{_ as n,l as o}from"./mermaid.core-BUuGHmWO.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-BoAVG3cs.js";import"./index-C0O48S_P.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
+ import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-DDOgIS70.js";import{p as f}from"./chunk-JWPE2WC7-CCQSht8M.js";import{_ as n,l as o}from"./mermaid.core-DEQe8-_m.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-F5JKIvIq.js";import"./index-CA-jfWlE.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-BUuGHmWO.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};
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-DEQe8-_m.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};