@tea-agent/loop-agent 0.39.0-next.29 → 0.39.0-next.30

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 (81) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +2 -0
  3. package/README.md +1 -1
  4. package/dist/build-stamp.json +2 -2
  5. package/dist/commands/dag-rerun.js +55 -1
  6. package/dist/shared/dag-prompt-override.js +28 -0
  7. package/dist/shared/operator/capabilities.js +25 -0
  8. package/dist/worker/console/operator-actions.js +116 -0
  9. package/dist/worker/console/routes.js +40 -2
  10. package/dist/worker/console/security.js +13 -7
  11. package/dist/worker/console/server.js +26 -1
  12. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DGn9iNrd.js → abnfDiagram-N423BO3Z-CiGOV5eG.js} +1 -1
  13. package/dist/worker/console/static/assets/{arc-Dc0C2Nyv.js → arc-Ds9Gyfd8.js} +1 -1
  14. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COnz_Bhe.js → architectureDiagram-T3A2C74G-C6V6uC98.js} +1 -1
  15. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-VhIP6vgf.js → blockDiagram-VBNYF7ZC-DezF7Ol9.js} +1 -1
  16. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-D74lpmlb.js → c4Diagram-5PPSVZJV-BCWk3gCT.js} +1 -1
  17. package/dist/worker/console/static/assets/channel-DMvu1nmi.js +1 -0
  18. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-BxmiogQE.js → chunk-2GRJ4B5K-DbYr-Cxy.js} +1 -1
  19. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-C00Oi-2I.js → chunk-2Q5K7J3B-XSlusW4G.js} +1 -1
  20. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DTrT1Vze.js → chunk-5RXB4S5H-BtcKAj9i.js} +1 -1
  21. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DdKW7-fL.js → chunk-5VM5RSS4-BF57lhXj.js} +1 -1
  22. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-D0q1WN6w.js → chunk-6Q2QTUOP-DJIlR25o.js} +1 -1
  23. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-DBa14MSI.js → chunk-GF5L2VYU-DklNc7dm.js} +1 -1
  24. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DkP-pEox.js → chunk-JWPE2WC7-fZNtEdQZ.js} +1 -1
  25. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-lgPogpcX.js → chunk-KBJHAD2P-BBgLqV4h.js} +1 -1
  26. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-D-apZer0.js → chunk-RYQCIY6F-Dl9e5n_J.js} +1 -1
  27. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-B1T2yAIe.js → chunk-XXDRQBXY-B0JK51NT.js} +1 -1
  28. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DVzM-02m.js +1 -0
  29. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DVzM-02m.js +1 -0
  30. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-0P6hi3jF.js → cose-bilkent-JH36ORCC-Ch-ajv4O.js} +1 -1
  31. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CntzMSR8.js → cynefin-VYW2F7L2-xn_NxcfB.js} +1 -1
  32. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-C9zmXJtG.js → cynefinDiagram-MW4NZA55-DRD0fyga.js} +1 -1
  33. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-DfBCZqZw.js → dagre-VZM6K2ZE-COtnKp4B.js} +1 -1
  34. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-DLp-bhGL.js → diagram-7IWD3JNH-BQp_CAqG.js} +1 -1
  35. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BksDcwZm.js → diagram-B4RE2ZJO-x0y-vNgq.js} +1 -1
  36. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-Bdag7DYP.js → diagram-LBJQPF4R-N2ezwL31.js} +1 -1
  37. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-CoY5uNbk.js → diagram-Q27KOJAE-CSaxRH6Q.js} +1 -1
  38. package/dist/worker/console/static/assets/{diagram-UB23O5K3-KcgrDXHt.js → diagram-UB23O5K3-6Ro7Kpbd.js} +1 -1
  39. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CikErwJb.js → ebnfDiagram-BXEA7PRR-CrIIQEAI.js} +1 -1
  40. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DqmwwzvZ.js → erDiagram-JOGREHBK-DivKcq8g.js} +1 -1
  41. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-35krh9WG.js → flowDiagram-UKHOOZJN-BXrfDo8y.js} +1 -1
  42. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CvTF1gJ4.js → ganttDiagram-PKOTCBZU-LTTQmMRJ.js} +1 -1
  43. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-BiOWWClJ.js → gitGraphDiagram-DS77QQ5N-DP3o_5qd.js} +1 -1
  44. package/dist/worker/console/static/assets/{index-CqWlWE4l.js → index-C2jmYBfu.js} +71 -71
  45. package/dist/worker/console/static/assets/{index-Ya5FE7cD.css → index-C8rOIAJr.css} +1 -1
  46. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Crha5dcA.js → infoDiagram-6WML65LV-wVfSY1WH.js} +1 -1
  47. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-DEtbscOZ.js → ishikawaDiagram-WSZJBQD7-BRKfFL0I.js} +1 -1
  48. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-D2YYzx3z.js → journeyDiagram-NVQOT4AX-DEml3jLb.js} +1 -1
  49. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C7x18ttQ.js → kanban-definition-27J2QSJJ-DTzBmOqN.js} +1 -1
  50. package/dist/worker/console/static/assets/{linear-CCLZkz45.js → linear-Cpy1d873.js} +1 -1
  51. package/dist/worker/console/static/assets/{mermaid.core-Dmy4lSGv.js → mermaid.core-C1cSavOy.js} +5 -5
  52. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CmvIol59.js → mindmap-definition-FAOFIHXS-BEBSKvYM.js} +1 -1
  53. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DVpEdirN.js → pegDiagram-VL7TDLO6-BrLs4Oac.js} +1 -1
  54. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-cKQy456v.js → pieDiagram-7S7Q4E2Y-B47AZcLa.js} +1 -1
  55. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-bx06I38m.js → quadrantDiagram-CIZ2JOQS-s0dVeYR2.js} +1 -1
  56. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BjfIVIJr.js → railroadDiagram-AXF67PYL-lW8aJ7Q6.js} +1 -1
  57. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DcuPGbKM.js → requirementDiagram-LRYGKXZP-BcHJPf6Q.js} +1 -1
  58. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DvgVeDoV.js → sankeyDiagram-W5VNT64P-DdegpUUf.js} +1 -1
  59. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DLBG9nm-.js → sequenceDiagram-SI44F4Z6-BxFWqNv8.js} +1 -1
  60. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-D33L7FBF.js → sizeCapture-X5ZJPWSS-cOdUDPbR.js} +1 -1
  61. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-hvqD9TpS.js → stateDiagram-OKZ733FA-DpxlYl8P.js} +1 -1
  62. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BwecGAkM.js +1 -0
  63. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BtjH81Mz.js → swimlanes-SLNWSIFB-DQOfurE0.js} +2 -2
  64. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D5WW_LbN.js +8 -0
  65. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CJ47Kraf.js → timeline-definition-Z64GVDOM-CIp3tC6V.js} +1 -1
  66. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-COVPl-wh.js → vennDiagram-T6HMQDX7-C-adIPKn.js} +1 -1
  67. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CCoQJLUY.js → wardleyDiagram-T6FBY63Y-CiYrar9M.js} +1 -1
  68. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-DTWJvfAd.js → xychartDiagram-ELKLHX3M-WHrdTV0-.js} +1 -1
  69. package/dist/worker/console/static/index.html +2 -2
  70. package/dist/worker/observe/routes.js +12 -3
  71. package/dist/worker/observe/static/api.js +58 -0
  72. package/dist/worker/observe/static/styles.css +70 -0
  73. package/dist/worker/observe/static/views/dag-inspector.js +315 -2
  74. package/dist/workflows/dag/rerun-plan.js +112 -0
  75. package/dist/workflows/dag/rerun-run.js +58 -6
  76. package/package.json +1 -1
  77. package/dist/worker/console/static/assets/channel-DWcZjWB3.js +0 -1
  78. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-IjoI3dqU.js +0 -1
  79. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-IjoI3dqU.js +0 -1
  80. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-C6MII0D1.js +0 -1
  81. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D_tk0V8D.js +0 -8
package/AGENTS.md CHANGED
@@ -41,7 +41,7 @@
41
41
  4. 涉及测试纪律/验证声明/调试时继续读:`docs/governance/harness-methodology-*.md`。
42
42
  5. 查看最近提交、相关 plan/progress/report;`git status --short --branch`;跑最小基线验证。
43
43
  6. 后端/接口/pytest → `taskKind: "backend-test"`(不是 `--profile`);知识回写 `knowledge-sync`;图谱开荒 `knowledge-graph-bootstrap`。`--profile` 仅 `auto|minimal|standard|reviewed|supervised`。
44
- 7. 看板/observe → `agent-worker console`(默认 repo=当前目录、port=8790;listen 成功后默认打开系统浏览器,`--no-open` 禁止)(`/inspect/` 只读);`observe serve` 已下线(`OBSERVE_SERVE_REMOVED` + exit 2);`observe snapshot` 仍可用。
44
+ 7. 看板/observe → `agent-worker console`(默认 repo=当前目录、port=8790;listen 成功后默认打开系统浏览器,`--no-open` 禁止)(`/inspect/` 只读;唯一实验例外:`HARNESS_DAG_RERUN_PROMPT_OVERRIDE=1` 时节点 inspector 出现「提示词重启」tab 并注入 mutation token,默认关闭时零 token 零 tab);`observe serve` 已下线(`OBSERVE_SERVE_REMOVED` + exit 2);`observe snapshot` 仍可用。
45
45
  8. 分支合并 → 先读 `docs/operations/branch-merge-guideline.md`。
46
46
  9. 涉及版本发布、npm 渠道、release 分支、GitHub Actions 发布链或 dist-tag → 先读 `docs/operations/version-and-release-management.md`。
47
47
 
package/CHANGELOG.md CHANGED
@@ -18,6 +18,8 @@
18
18
 
19
19
  ### 新增
20
20
 
21
+ - Operator Chat 时间线左缘新增「用户消息锚点栏」:每个用户输入一枚横向小条(12×3px 微圆角),紧凑等距排列并在时间线高度内垂直居中;条数超出栏高时相邻锚点自动聚合为稍宽的聚合条(悬停展开「N 条聚合输入」逐条列表,时间 + 单行预览,逐条点击定位)。悬停时小条向对话一侧平滑伸长(12→18px)并变橙,浮窗右侧弹出(白底圆角,正文最多 3 行、超出省略号,附序号与时间);单击平滑滚动定位到对应消息(精确停靠在视口顶部偏移 8px);覆盖视口顶部的锚点保持高亮。空会话自动隐藏;历史分页/流式更新/窗口缩放时自动重算(rAF 节流)。
22
+ - 实验能力「编辑失败节点提示词后从节点重跑」(默认关闭):内部开关 `HARNESS_DAG_RERUN_PROMPT_OVERRIDE=1` 启用后,`dag rerun` 支持 `--prompt-override <nodeId>@<file>`(全文替换)与 `--prompt-override-append <nodeId>@<file>`(追加指令:保留冻结原提示词,末尾追加 `<operator_addendum>` 块)。仅限 ERROR 且位于 reset closure 内的节点;mode + base/最终 prompt sha256 计入 planHash(execute 漂移即 `PLAN_DRIFT`),父 run spec 冻结、provenance(含 mode)落 `continuation.promptOverrides`。Console 新增 `dagPromptOverrideConfig` 开关探测 action,`dagRerunPlan`/`dagRerun` 接受 `promptOverrides`(`{nodeId, prompt, mode?}`);Inspect DAG 节点 inspector 新增「提示词重启」tab——默认「追加指令」模式(只读底稿 + 追加编辑器),可切换「全文替换(高级)」,预检通过展示执行估算,提交后续跑并跳转新 run,全程不离开图页;开关开启时 `/inspect` 只注入 **scoped** 变体凭据(独立 cookie + `__INSPECT_MUTATION_TOKEN__`,与 Console 通用 token 互不可重放),mutations 路由对 inspect 凭据仅放行 `dagRerunPlan`/`dagRerun`(其余 action 403 `ACTION_NOT_IN_INSPECT_SCOPE`),Inspect 不获得通用写能力;开关关闭时不注入任何 token、tab 不出现,检视面保持严格只读。
21
23
  - 观察面 DAG Inspector 节点详情适配 Pi 扩展:执行器输入摘要展示节点声明的 `piExtensions` 短 id;新增「Pi 扩展运行事实」展示 `pi-extensions.json` 的 resolved(包名@版本)与 missing 降级原因(缺包降级不再静默);产物未生成/损坏时降级提示不阻断接口,绝对路径不外泄。
22
24
  - 后端实现 DAG(standard / review-gated / supervised)的 Pi 节点支持按桶显式加载本机 Pi 导航扩展:读侧节点(除 closeout)加载 `pi-codegraph` + `pi-lens`,写侧节点只加载 `pi-codegraph`(pi-lens 的 `ast_grep_replace` 可绕过 writeSet,不加载);前端/测试模板与省略字段节点保持扩展全关。扩展发现始终关闭,只经白名单解析 `~/.pi/agent` 与项目 `.pi` settings 的已装包(缺包降级不失败,产物 `pi-extensions.json` 记录 requested/resolved/missing);session 后 pin 工具面剔 builtin 同名、deny 面与写工具,writer 的 `edit`/`write` 仍为 policy-wrapped;`.codegraph/**` index 同步不再计入 write-guard 越界。
23
25
  - Pi SDK 终态 session-events JSONL 顶层增加可选 `finish_reason`:仅当 `message_end` / `turn_end` / `assistant_message` 明确携带非空终止原因时由序列化层提升,不伪造默认值,也不回流 `stopReason` 诊断。
package/README.md CHANGED
@@ -116,7 +116,7 @@ loop-agent dag report --run-id <run-id>
116
116
  | --- | --- | --- |
117
117
  | 受治理 CLI | `loop-agent …` / `agent-worker …` | 权威写入与诊断 |
118
118
  | Loop Operator Console | `agent-worker console` | Official 本地控制面(默认 repo=当前目录、`127.0.0.1:8790`,含 Operate 与 Inspect) |
119
- | Inspect(只读) | `agent-worker console` → `/inspect/`;`observe snapshot` | 统一 Console 内只读检视;`observe serve` 已下线(REMOVED / exit 2) |
119
+ | Inspect(只读) | `agent-worker console` → `/inspect/`;`observe snapshot` | 统一 Console 内只读检视;`observe serve` 已下线(REMOVED / exit 2)。实验例外:`HARNESS_DAG_RERUN_PROMPT_OVERRIDE=1` 时节点 inspector 增加失败节点「提示词重启」tab(默认关闭,不注入任何 mutation token) |
120
120
 
121
121
  ```bash
122
122
  # 终端 A:Console(任务/运行操作面;canonical mutation 只经 sibling loop-agent)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "version": "0.38.3",
4
- "gitSha": "a757f2e56597122ab0be09e7524038ad14a576bb",
5
- "builtAt": "2026-08-22T10:37:15.456Z"
4
+ "gitSha": "07a0a9bcee0b9aa29cafc085485f3aed7ae03cec",
5
+ "builtAt": "2026-08-22T12:04:10.935Z"
6
6
  }
@@ -1,3 +1,5 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { isDagRerunPromptOverrideEnabled } from "../shared/dag-prompt-override.js";
1
3
  import { executeDagRerun, planDagRerun, } from "../workflows/dag/rerun-run.js";
2
4
  export function parseDagRerunArgs(args) {
3
5
  if (args.length === 0) {
@@ -9,6 +11,8 @@ export function parseDagRerunArgs(args) {
9
11
  let planHash;
10
12
  let requestId;
11
13
  let reason;
14
+ const promptOverrideSpecs = [];
15
+ const promptOverrideAppendSpecs = [];
12
16
  for (let index = 0; index < args.length; index += 1) {
13
17
  const arg = args[index];
14
18
  if (arg === "--run-id")
@@ -33,6 +37,14 @@ export function parseDagRerunArgs(args) {
33
37
  reason = args[++index];
34
38
  else if (arg.startsWith("--reason="))
35
39
  reason = arg.slice("--reason=".length);
40
+ else if (arg === "--prompt-override")
41
+ promptOverrideSpecs.push(args[++index] ?? "");
42
+ else if (arg.startsWith("--prompt-override="))
43
+ promptOverrideSpecs.push(arg.slice("--prompt-override=".length));
44
+ else if (arg === "--prompt-override-append")
45
+ promptOverrideAppendSpecs.push(args[++index] ?? "");
46
+ else if (arg.startsWith("--prompt-override-append="))
47
+ promptOverrideAppendSpecs.push(arg.slice("--prompt-override-append=".length));
36
48
  else if (arg === "--json")
37
49
  continue;
38
50
  else if (arg.startsWith("-"))
@@ -50,7 +62,13 @@ export function parseDagRerunArgs(args) {
50
62
  if (planHash || requestId || reason) {
51
63
  throw new Error("dag rerun --plan cannot be combined with execute flags");
52
64
  }
53
- return { parentRunId, selectedNodeId, planOnly: true };
65
+ return {
66
+ parentRunId,
67
+ selectedNodeId,
68
+ planOnly: true,
69
+ promptOverrideSpecs,
70
+ promptOverrideAppendSpecs,
71
+ };
54
72
  }
55
73
  if (!planHash?.trim()) {
56
74
  throw new Error("dag rerun execute requires --plan-hash <hash>");
@@ -68,15 +86,50 @@ export function parseDagRerunArgs(args) {
68
86
  planHash: planHash.trim(),
69
87
  requestId: requestId.trim(),
70
88
  reason: reason.trim(),
89
+ promptOverrideSpecs,
90
+ promptOverrideAppendSpecs,
71
91
  };
72
92
  }
93
+ async function loadPromptOverrides(specs, mode) {
94
+ const overrides = [];
95
+ for (const spec of specs) {
96
+ const separator = spec.indexOf("@");
97
+ if (separator <= 0 || separator >= spec.length - 1) {
98
+ throw new Error(`dag rerun --prompt-override${mode === "append" ? "-append" : ""} expects <nodeId>@<filePath>, got: ${spec}`);
99
+ }
100
+ const nodeId = spec.slice(0, separator);
101
+ const filePath = spec.slice(separator + 1);
102
+ let prompt;
103
+ try {
104
+ prompt = await readFile(filePath, "utf-8");
105
+ }
106
+ catch (error) {
107
+ throw new Error(`cannot read prompt override file for node ${nodeId} (${filePath}): ${error instanceof Error ? error.message : String(error)}`);
108
+ }
109
+ overrides.push(mode === "append" ? { nodeId, prompt, mode } : { nodeId, prompt });
110
+ }
111
+ return overrides;
112
+ }
73
113
  export async function runDagRerun(repoRoot, rawArgs) {
74
114
  const parsed = parseDagRerunArgs(rawArgs);
115
+ let promptOverrides;
116
+ const hasOverrides = parsed.promptOverrideSpecs.length > 0 ||
117
+ parsed.promptOverrideAppendSpecs.length > 0;
118
+ if (hasOverrides) {
119
+ if (!isDagRerunPromptOverrideEnabled()) {
120
+ throw new Error("prompt override rerun is disabled; set HARNESS_DAG_RERUN_PROMPT_OVERRIDE=1 to enable this experimental capability");
121
+ }
122
+ promptOverrides = [
123
+ ...(await loadPromptOverrides(parsed.promptOverrideSpecs, "replace")),
124
+ ...(await loadPromptOverrides(parsed.promptOverrideAppendSpecs, "append")),
125
+ ];
126
+ }
75
127
  if (parsed.planOnly) {
76
128
  const plan = await planDagRerun({
77
129
  cwd: repoRoot,
78
130
  parentRunId: parsed.parentRunId,
79
131
  selectedNodeId: parsed.selectedNodeId,
132
+ promptOverrides,
80
133
  });
81
134
  const result = {
82
135
  ok: plan.eligible,
@@ -95,6 +148,7 @@ export async function runDagRerun(repoRoot, rawArgs) {
95
148
  planHash: parsed.planHash,
96
149
  requestId: parsed.requestId,
97
150
  reason: parsed.reason,
151
+ promptOverrides,
98
152
  });
99
153
  console.log(JSON.stringify(result, null, 2));
100
154
  if (!result.ok) {
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Internal switch for the experimental "rerun failed node with an edited
3
+ * prompt" capability. Default is OFF; nothing may depend on it being enabled.
4
+ * The switch is deliberately env-based (no harness.json surface) while the
5
+ * feature is internal.
6
+ */
7
+ export const DAG_RERUN_PROMPT_OVERRIDE_ENV = "HARNESS_DAG_RERUN_PROMPT_OVERRIDE";
8
+ /** Upper bound for an override input body (characters). */
9
+ export const MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS = 65_536;
10
+ export function isDagRerunPromptOverrideEnabled(env = process.env) {
11
+ const value = env[DAG_RERUN_PROMPT_OVERRIDE_ENV];
12
+ return value === "1" || value === "true";
13
+ }
14
+ export const DAG_RERUN_PROMPT_ADDENDUM_TAG = "operator_addendum";
15
+ /**
16
+ * Compose the final subtask_prompt for a rerun override.
17
+ * - "replace": the operator text becomes the whole prompt (advanced mode).
18
+ * - "append" (recommended): the frozen base prompt is kept verbatim and the
19
+ * operator addendum is appended in a clearly marked block, mirroring the
20
+ * rerunFeedback / retry_instruction augmentation semantics — small diffs,
21
+ * no risk of dropping template scaffolding.
22
+ */
23
+ export function composeDagPromptOverridePrompt(input) {
24
+ if (input.mode === "replace") {
25
+ return input.text;
26
+ }
27
+ return `${input.basePrompt}\n\n<${DAG_RERUN_PROMPT_ADDENDUM_TAG}>\n${input.text.trim()}\n</${DAG_RERUN_PROMPT_ADDENDUM_TAG}>\n`;
28
+ }
@@ -1155,6 +1155,19 @@ export function buildOperatorCapabilitiesDocument() {
1155
1155
  modelCallable: "always",
1156
1156
  humanConfirmation: "none",
1157
1157
  },
1158
+ {
1159
+ action: "dagPromptOverrideConfig",
1160
+ cli: "console dag-prompt-override-config",
1161
+ kind: "read",
1162
+ inputSchemaVersion: 1,
1163
+ resultSchemaVersion: 1,
1164
+ envelopeSchemaVersion: 1,
1165
+ requiredErrorCodes: [],
1166
+ description: "Read-only probe of the experimental prompt-override rerun switch (env-gated, default off). The browser Recovery UI hides the failed-node prompt editor unless this returns enabled=true. Never mutates.",
1167
+ inputParams: [],
1168
+ modelCallable: "always",
1169
+ humanConfirmation: "none",
1170
+ },
1158
1171
  {
1159
1172
  action: "dagRerunPlan",
1160
1173
  cli: "loop-agent dag rerun --run-id <id> --from-node <node> --plan --json",
@@ -1177,6 +1190,12 @@ export function buildOperatorCapabilitiesDocument() {
1177
1190
  required: true,
1178
1191
  description: "node id to rerun from (prefer failed/attention node from dagReport primaryFailure.nodeId)",
1179
1192
  },
1193
+ {
1194
+ name: "promptOverrides",
1195
+ type: "array",
1196
+ required: false,
1197
+ description: "experimental (switch off by default): [{nodeId, prompt, mode?}] — mode append (recommended) keeps the frozen base prompt and appends the text as a marked addendum block, replace swaps the whole subtask_prompt; only FAILED nodes inside the reset closure are admitted and the planHash binds the composed change",
1198
+ },
1180
1199
  ],
1181
1200
  modelCallable: "always",
1182
1201
  humanConfirmation: "none",
@@ -1219,6 +1238,12 @@ export function buildOperatorCapabilitiesDocument() {
1219
1238
  required: true,
1220
1239
  description: "why continue from this node (e.g. provider flake; resume from review-pi)",
1221
1240
  },
1241
+ {
1242
+ name: "promptOverrides",
1243
+ type: "array",
1244
+ required: false,
1245
+ description: "experimental (switch off by default): must match the dagRerunPlan promptOverrides exactly (same mode/text); the planHash already binds them, any drift is rejected",
1246
+ },
1222
1247
  ],
1223
1248
  // always: fresh eligible dagRerun plans are model-callable (2026-08-11).
1224
1249
  // The CLI keeps enforcing parent lifecycle, fromNode, planHash,
@@ -1,5 +1,6 @@
1
1
  import { access, readFile } from "node:fs/promises";
2
2
  import { buildOperatorCapabilitiesDocument, OFFICIAL_TAIL_ACTION_IDS, } from "../../shared/operator/capabilities.js";
3
+ import { DAG_RERUN_PROMPT_OVERRIDE_ENV, isDagRerunPromptOverrideEnabled, MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS, } from "../../shared/dag-prompt-override.js";
3
4
  import { buildOperatorResult, operatorFailed, operatorSucceeded, } from "../../shared/operator/envelope.js";
4
5
  import { CANONICAL_TASK_ID_PATTERN, formatLocalBusinessDate, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
5
6
  import { diffTaskContract, validateDraftForTask, } from "../../task/contract/index.js";
@@ -401,6 +402,85 @@ async function runReadCli(ctx, args, command) {
401
402
  });
402
403
  }
403
404
  }
405
+ /**
406
+ * Parse and bound the experimental promptOverrides action param. The env
407
+ * switch is checked separately so disabled deployments fail closed before any
408
+ * staging happens. `mode` defaults to "replace"; "append" keeps the frozen
409
+ * base prompt and only appends the operator text as a marked addendum.
410
+ */
411
+ function parsePromptOverrideParams(raw) {
412
+ if (raw === undefined || raw === null)
413
+ return { kind: "ok", overrides: [] };
414
+ if (!Array.isArray(raw)) {
415
+ return {
416
+ kind: "error",
417
+ message: "promptOverrides must be an array of {nodeId, prompt, mode?}",
418
+ };
419
+ }
420
+ if (raw.length === 0)
421
+ return { kind: "ok", overrides: [] };
422
+ if (raw.length > 8) {
423
+ return { kind: "error", message: "promptOverrides supports at most 8 nodes" };
424
+ }
425
+ const overrides = [];
426
+ const seen = new Set();
427
+ for (const item of raw) {
428
+ if (!item || typeof item !== "object") {
429
+ return {
430
+ kind: "error",
431
+ message: "promptOverrides entries must be objects {nodeId, prompt, mode?}",
432
+ };
433
+ }
434
+ const record = item;
435
+ const nodeId = typeof record.nodeId === "string" ? record.nodeId.trim() : "";
436
+ const prompt = typeof record.prompt === "string" ? record.prompt : "";
437
+ const mode = record.mode === undefined || record.mode === null
438
+ ? undefined
439
+ : typeof record.mode === "string"
440
+ ? record.mode
441
+ : "invalid";
442
+ if (!nodeId) {
443
+ return { kind: "error", message: "promptOverrides nodeId is required" };
444
+ }
445
+ if (seen.has(nodeId)) {
446
+ return {
447
+ kind: "error",
448
+ message: `promptOverrides contains duplicate nodeId: ${nodeId}`,
449
+ };
450
+ }
451
+ seen.add(nodeId);
452
+ if (mode !== undefined && mode !== "append" && mode !== "replace") {
453
+ return {
454
+ kind: "error",
455
+ message: `promptOverrides mode for ${nodeId} must be append or replace`,
456
+ };
457
+ }
458
+ if (!prompt.trim() || prompt.length > MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS) {
459
+ return {
460
+ kind: "error",
461
+ message: `promptOverrides prompt for ${nodeId} must be 1-${MAX_DAG_RERUN_PROMPT_OVERRIDE_CHARS} characters`,
462
+ };
463
+ }
464
+ overrides.push(mode === undefined ? { nodeId, prompt } : { nodeId, prompt, mode });
465
+ }
466
+ return { kind: "ok", overrides };
467
+ }
468
+ /** Stage override bodies under app-data and build `--prompt-override` CLI
469
+ * args. The flag carries the mode: `--prompt-override-append` for append. */
470
+ async function buildPromptOverrideCliArgs(ctx, overrides) {
471
+ const args = [];
472
+ for (const override of overrides) {
473
+ const staged = await stageUtf8Text(ctx.appData, override.prompt, {
474
+ extension: ".md",
475
+ label: `prompt-override-${override.nodeId}`,
476
+ });
477
+ const flag = override.mode === "append"
478
+ ? "--prompt-override-append"
479
+ : "--prompt-override";
480
+ args.push(flag, `${override.nodeId}@${staged.path}`);
481
+ }
482
+ return args;
483
+ }
404
484
  async function acceptOperation(ctx, input) {
405
485
  const created = await ctx.operations.create({
406
486
  clientRequestId: input.clientRequestId,
@@ -2078,12 +2158,35 @@ export async function dispatchOperatorAction(ctx, req) {
2078
2158
  }
2079
2159
  return accepted;
2080
2160
  }
2161
+ case "dagPromptOverrideConfig": {
2162
+ // Experimental internal switch; the browser UI hides the prompt-edit
2163
+ // entry unless this reports enabled=true.
2164
+ return {
2165
+ kind: "sync",
2166
+ status: 200,
2167
+ body: operatorSucceeded(action, {
2168
+ enabled: isDagRerunPromptOverrideEnabled(),
2169
+ envVar: DAG_RERUN_PROMPT_OVERRIDE_ENV,
2170
+ }),
2171
+ };
2172
+ }
2081
2173
  case "dagRerunPlan": {
2082
2174
  const runId = str(p.runId);
2083
2175
  const fromNode = str(p.fromNode);
2084
2176
  if (!runId || !fromNode) {
2085
2177
  return invalid(action, "runId and fromNode are required");
2086
2178
  }
2179
+ const parsedOverrides = parsePromptOverrideParams(p.promptOverrides);
2180
+ if (parsedOverrides.kind === "error") {
2181
+ return invalid(action, parsedOverrides.message);
2182
+ }
2183
+ if (parsedOverrides.overrides.length > 0 &&
2184
+ !isDagRerunPromptOverrideEnabled()) {
2185
+ return invalid(action, `prompt override rerun is disabled; set ${DAG_RERUN_PROMPT_OVERRIDE_ENV}=1 to enable this experimental capability`);
2186
+ }
2187
+ const overrideArgs = parsedOverrides.overrides.length > 0
2188
+ ? await buildPromptOverrideCliArgs(ctx, parsedOverrides.overrides)
2189
+ : [];
2087
2190
  const body = await runReadCli(ctx, [
2088
2191
  "dag",
2089
2192
  "rerun",
@@ -2092,6 +2195,7 @@ export async function dispatchOperatorAction(ctx, req) {
2092
2195
  "--from-node",
2093
2196
  fromNode,
2094
2197
  "--plan",
2198
+ ...overrideArgs,
2095
2199
  "--json",
2096
2200
  ], "dag rerun plan");
2097
2201
  return { kind: "sync", status: body.ok ? 200 : 400, body };
@@ -2105,6 +2209,17 @@ export async function dispatchOperatorAction(ctx, req) {
2105
2209
  if (!runId || !fromNode || !planHash || !reason || !clientRequestId) {
2106
2210
  return invalid(action, "runId, fromNode, planHash, reason, and clientRequestId are required");
2107
2211
  }
2212
+ const parsedOverrides = parsePromptOverrideParams(p.promptOverrides);
2213
+ if (parsedOverrides.kind === "error") {
2214
+ return invalid(action, parsedOverrides.message);
2215
+ }
2216
+ if (parsedOverrides.overrides.length > 0 &&
2217
+ !isDagRerunPromptOverrideEnabled()) {
2218
+ return invalid(action, `prompt override rerun is disabled; set ${DAG_RERUN_PROMPT_OVERRIDE_ENV}=1 to enable this experimental capability`);
2219
+ }
2220
+ const overrideArgs = parsedOverrides.overrides.length > 0
2221
+ ? await buildPromptOverrideCliArgs(ctx, parsedOverrides.overrides)
2222
+ : [];
2108
2223
  return acceptOperation(ctx, {
2109
2224
  action,
2110
2225
  actionParams: p,
@@ -2122,6 +2237,7 @@ export async function dispatchOperatorAction(ctx, req) {
2122
2237
  clientRequestId,
2123
2238
  "--reason",
2124
2239
  reason,
2240
+ ...overrideArgs,
2125
2241
  "--json",
2126
2242
  ],
2127
2243
  });
@@ -131,6 +131,16 @@ async function handleSessionPing(req, res, ctx) {
131
131
  }
132
132
  sendJson(res, 200, { ok: true, pong: true });
133
133
  }
134
+ /**
135
+ * Actions the inspect-scoped mutation token may dispatch. Deliberately
136
+ * minimal: the experimental prompt-override rerun tab needs plan preflight +
137
+ * execution only. Everything else (task creation, runDag, reconcile, chat,
138
+ * worker actions…) requires the general Console token.
139
+ */
140
+ export const INSPECT_MUTATION_ALLOWED_ACTIONS = new Set([
141
+ "dagRerunPlan",
142
+ "dagRerun",
143
+ ]);
134
144
  async function handleCreateOperation(req, res, ctx) {
135
145
  if (!ctx.operator) {
136
146
  sendJson(res, 503, {
@@ -142,13 +152,31 @@ async function handleCreateOperation(req, res, ctx) {
142
152
  });
143
153
  return;
144
154
  }
145
- const failure = evaluateMutationGate(req, {
155
+ const generalGateContext = {
146
156
  cookieName: ctx.bootToken.cookieName,
147
157
  bootToken: ctx.bootToken.value,
148
158
  confirmationToken: ctx.bootToken.confirmationToken,
149
159
  consoleOrigin: ctx.getConsoleOrigin(),
150
160
  allowNonLoopbackAccess: ctx.allowNonLoopbackAccess === true,
151
- });
161
+ };
162
+ let failure = evaluateMutationGate(req, generalGateContext);
163
+ let inspectScoped = false;
164
+ if (failure && ctx.inspectBootToken) {
165
+ // Scoped /inspect credentials: try the inspect gate before failing. The
166
+ // general gate already rejected, so passing here only ever yields the
167
+ // allowlisted actions below — never general write capability.
168
+ const scopedFailure = evaluateMutationGate(req, {
169
+ cookieName: ctx.inspectBootToken.cookieName,
170
+ bootToken: ctx.inspectBootToken.value,
171
+ confirmationToken: ctx.inspectBootToken.confirmationToken,
172
+ consoleOrigin: ctx.getConsoleOrigin(),
173
+ allowNonLoopbackAccess: ctx.allowNonLoopbackAccess === true,
174
+ });
175
+ if (!scopedFailure) {
176
+ inspectScoped = true;
177
+ failure = undefined;
178
+ }
179
+ }
152
180
  if (failure) {
153
181
  sendJson(res, failure.status, {
154
182
  ok: false,
@@ -175,6 +203,16 @@ async function handleCreateOperation(req, res, ctx) {
175
203
  ? body.actionParams
176
204
  : {};
177
205
  const clientRequestId = typeof body.clientRequestId === "string" ? body.clientRequestId : undefined;
206
+ if (inspectScoped && !INSPECT_MUTATION_ALLOWED_ACTIONS.has(action)) {
207
+ sendJson(res, 403, {
208
+ ok: false,
209
+ error: {
210
+ code: "ACTION_NOT_IN_INSPECT_SCOPE",
211
+ message: `inspect-scoped token only allows: ${[...INSPECT_MUTATION_ALLOWED_ACTIONS].join(", ")}`,
212
+ },
213
+ });
214
+ return;
215
+ }
178
216
  const result = await dispatchOperatorAction(ctx.operator.actionContext, {
179
217
  action,
180
218
  actionParams,
@@ -35,7 +35,7 @@ function normalizeInstanceScope(scope) {
35
35
  };
36
36
  }
37
37
  /** Deterministic Cookie name for one Console instance; never includes repo path or token. */
38
- export function deriveBootCapabilityCookieName(scope) {
38
+ export function deriveBootCapabilityCookieName(scope, variant) {
39
39
  const normalized = normalizeInstanceScope(scope);
40
40
  const digest = createHash("sha256")
41
41
  .update("loop-console-capability-v1\0", "utf8")
@@ -46,13 +46,17 @@ export function deriveBootCapabilityCookieName(scope) {
46
46
  .update(String(normalized.configuredPort), "utf8")
47
47
  .update("\0", "utf8")
48
48
  .update(normalized.instanceNonce ?? "", "utf8")
49
+ .update("\0", "utf8")
50
+ .update(variant ?? "", "utf8")
49
51
  .digest("hex")
50
52
  .slice(0, 32);
51
53
  return `${BOOT_CAPABILITY_COOKIE}_${digest}`;
52
54
  }
53
- /** Issue per-process unguessable boot capability + confirmation tokens. */
54
- export function issueBootCapabilityToken(scope) {
55
- const cookieName = deriveBootCapabilityCookieName(scope);
55
+ /** Issue per-process unguessable boot capability + confirmation tokens.
56
+ * `variant` (e.g. "inspect") derives a separate cookie name so scoped
57
+ * credentials cannot be replayed against the general mutation surface. */
58
+ export function issueBootCapabilityToken(scope, options = {}) {
59
+ const cookieName = deriveBootCapabilityCookieName(scope, options.variant);
56
60
  const value = randomBytes(32).toString("base64url");
57
61
  const confirmationToken = randomBytes(32).toString("base64url");
58
62
  const setCookieHeader = [
@@ -63,10 +67,12 @@ export function issueBootCapabilityToken(scope) {
63
67
  ].join("; ");
64
68
  return { cookieName, value, setCookieHeader, confirmationToken };
65
69
  }
66
- /** Inject confirmation token into HTML so the SPA can send the mutation header. */
67
- export function injectConfirmationTokenScript(html, confirmationToken) {
70
+ /** Inject confirmation token into HTML so the SPA can send the mutation
71
+ * header. `varName` separates the general Console token from the scoped
72
+ * inspect token on the read-only /inspect surface. */
73
+ export function injectConfirmationTokenScript(html, confirmationToken, varName = "__CONSOLE_CONFIRMATION_TOKEN__") {
68
74
  const source = typeof html === "string" ? html : html.toString("utf8");
69
- const script = `<script>window.__CONSOLE_CONFIRMATION_TOKEN__=${JSON.stringify(confirmationToken)};</script>`;
75
+ const script = `<script>window.${varName}=${JSON.stringify(confirmationToken)};</script>`;
70
76
  if (source.includes("</head>")) {
71
77
  return Buffer.from(source.replace("</head>", `${script}</head>`), "utf8");
72
78
  }
@@ -21,8 +21,9 @@ import { createOperationEventStore, } from "./operation-sse.js";
21
21
  import { OperationStore } from "./operation-store.js";
22
22
  import { probePiReadiness, } from "./pi-readiness.js";
23
23
  import { handleConsoleHealthRequest, handleConsoleOperatorRequest, sendJson, serveConsoleStatic, } from "./routes.js";
24
- import { issueBootCapabilityToken } from "./security.js";
24
+ import { issueBootCapabilityToken, injectConfirmationTokenScript, } from "./security.js";
25
25
  import { resolveSiblingLoopAgentBin } from "./sibling-controller.js";
26
+ import { isDagRerunPromptOverrideEnabled } from "../../shared/dag-prompt-override.js";
26
27
  import { NightAuxTicker } from "./night-aux-ticker.js";
27
28
  import { deriveObserveRouteCapabilities } from "../observe/health.js";
28
29
  import { createObserveRouteContext, defaultObserveStaticDir, handleMatchedObserveRoute, matchObserveGetRoute, ROUTES, serveObserveStatic, } from "../observe/routes.js";
@@ -86,6 +87,15 @@ export async function createConsoleServer(options) {
86
87
  configuredPort,
87
88
  ...(instanceNonce ? { instanceNonce } : {}),
88
89
  });
90
+ // Scoped credentials for the experimental /inspect prompt-override rerun:
91
+ // separate cookie name + confirmation token so the read-only inspect page
92
+ // can never replay them against the general Console mutation surface.
93
+ const inspectBootToken = issueBootCapabilityToken({
94
+ repoFingerprint: appData.fingerprint,
95
+ bindHost: host,
96
+ configuredPort,
97
+ ...(instanceNonce ? { instanceNonce } : {}),
98
+ }, { variant: "inspect" });
89
99
  const operations = new OperationStore(appData);
90
100
  const events = createOperationEventStore({
91
101
  persistenceDir: path.join(appData.operations, "events"),
@@ -194,6 +204,7 @@ export async function createConsoleServer(options) {
194
204
  repoRoot,
195
205
  staticDir,
196
206
  bootToken,
207
+ inspectBootToken,
197
208
  getConsoleOrigin,
198
209
  allowNonLoopbackAccess: !loopbackBind,
199
210
  inspect: {
@@ -283,8 +294,22 @@ export async function createConsoleServer(options) {
283
294
  }
284
295
  }
285
296
  if (pathname.startsWith("/inspect")) {
297
+ // Experimental prompt-override rerun: only while the internal switch
298
+ // is enabled do we hand the inspect page SCOPED mutation
299
+ // credentials (separate cookie + token, only strong enough for
300
+ // INSPECT_MUTATION_ALLOWED_ACTIONS — see routes.ts). Default stays
301
+ // strictly read-only: no token, no cookie, no tab.
302
+ const htmlEnhancer = isDagRerunPromptOverrideEnabled()
303
+ ? (html) => ({
304
+ content: injectConfirmationTokenScript(html, routeContext.inspectBootToken?.confirmationToken ??
305
+ routeContext.bootToken.confirmationToken, "__INSPECT_MUTATION_TOKEN__"),
306
+ setCookie: routeContext.inspectBootToken?.setCookieHeader ??
307
+ routeContext.bootToken.setCookieHeader,
308
+ })
309
+ : undefined;
286
310
  await serveObserveStatic(req, res, inspectStaticDir, {
287
311
  urlPrefix: "/inspect",
312
+ ...(htmlEnhancer ? { htmlEnhancer } : {}),
288
313
  });
289
314
  return;
290
315
  }
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-D0q1WN6w.js";import{p as f}from"./chunk-JWPE2WC7-DkP-pEox.js";import{_ as n,l as o}from"./mermaid.core-Dmy4lSGv.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CntzMSR8.js";import"./index-CqWlWE4l.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-DJIlR25o.js";import{p as f}from"./chunk-JWPE2WC7-fZNtEdQZ.js";import{_ as n,l as o}from"./mermaid.core-C1cSavOy.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-xn_NxcfB.js";import"./index-C2jmYBfu.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-Dmy4lSGv.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-C1cSavOy.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};