@tea-agent/loop-agent 0.43.0-next.10 → 0.43.0-next.11

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 (91) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/build-stamp.json +3 -3
  3. package/dist/executors/dag-pi-executor.js +27 -6
  4. package/dist/executors/shell-executor.js +3 -2
  5. package/dist/worker/console/chat/browser-policy.js +6 -36
  6. package/dist/worker/console/chat/browser-routes.js +3 -11
  7. package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +2 -1
  8. package/dist/worker/console/chat/pi-runtime.js +4 -7
  9. package/dist/worker/console/chat/routes.js +1 -5
  10. package/dist/worker/console/chat/session-mode-view.js +5 -4
  11. package/dist/worker/console/chat/session-mode.js +11 -10
  12. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D_fNbWc_.js → abnfDiagram-N423BO3Z-CTSK0xbU.js} +1 -1
  13. package/dist/worker/console/static/assets/{arc-_HuqLW6m.js → arc-_2MfctFP.js} +1 -1
  14. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-Djy2qY1m.js → architectureDiagram-T3A2C74G-DsDe2wTg.js} +1 -1
  15. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-bB-1TSyY.js → blockDiagram-VBNYF7ZC-Dtz_779U.js} +1 -1
  16. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-C5Hmghrz.js → c4Diagram-5PPSVZJV-LaULi-gw.js} +1 -1
  17. package/dist/worker/console/static/assets/channel-CqS4yBWT.js +1 -0
  18. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-Duyl39oy.js → chunk-2GRJ4B5K-DuHBqqX8.js} +1 -1
  19. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-x6mdnSyf.js → chunk-2Q5K7J3B-BZgZs1dn.js} +1 -1
  20. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-WlBuFj7W.js → chunk-5RXB4S5H-tzwmlIO_.js} +1 -1
  21. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CTF429HX.js → chunk-5VM5RSS4-CeYrLkSn.js} +1 -1
  22. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Dwd6r-SF.js → chunk-6Q2QTUOP-C92cgilm.js} +1 -1
  23. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C-Br82D1.js → chunk-GF5L2VYU-XOXpGC0F.js} +1 -1
  24. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CuGp0DeE.js → chunk-JWPE2WC7-CGHbJyCH.js} +1 -1
  25. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CJhFX6Lh.js → chunk-KBJHAD2P-Bs2-LTzf.js} +1 -1
  26. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DpGOa_jT.js → chunk-RYQCIY6F-rN7up7E4.js} +1 -1
  27. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DXJaTynd.js → chunk-XXDRQBXY-B_fWjKpR.js} +1 -1
  28. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DVOxNOq0.js +1 -0
  29. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DVOxNOq0.js +1 -0
  30. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CRBZWjE4.js → cose-bilkent-JH36ORCC-DE3SdJvB.js} +1 -1
  31. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BdXcxtlb.js → cynefin-VYW2F7L2-B-4yuRAX.js} +1 -1
  32. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-07UKsOts.js → cynefinDiagram-MW4NZA55-TiCPFuO8.js} +1 -1
  33. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-D38p9__S.js → dagre-VZM6K2ZE-7crzLMzA.js} +1 -1
  34. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-nSiBNNjH.js → diagram-7IWD3JNH-Cvr-x6Fd.js} +1 -1
  35. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BFOTot5D.js → diagram-B4RE2ZJO-BzcRHUjH.js} +1 -1
  36. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DypKaZ6k.js → diagram-LBJQPF4R-BjkAXilh.js} +1 -1
  37. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-B6yoOQeW.js → diagram-Q27KOJAE-BkzyATK7.js} +1 -1
  38. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BHYS6viX.js → diagram-UB23O5K3-rZuTarYP.js} +1 -1
  39. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-D2VD5Snj.js → ebnfDiagram-BXEA7PRR-CAYENaN1.js} +1 -1
  40. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-E98mWxN1.js → erDiagram-JOGREHBK-DCEam0Uq.js} +1 -1
  41. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CT1zxhqP.js → flowDiagram-UKHOOZJN-e_dH4wVO.js} +1 -1
  42. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-6GcngNcy.js → ganttDiagram-PKOTCBZU-CvZa2zOK.js} +1 -1
  43. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DCL6NvKe.js → gitGraphDiagram-DS77QQ5N-CbT5TuKp.js} +1 -1
  44. package/dist/worker/console/static/assets/{index-24jp3aBh.js → index-CUPeoE8W.js} +42 -42
  45. package/dist/worker/console/static/assets/{index-CY6y6I8M.css → index-SAANIK8g.css} +1 -1
  46. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-C0627e-9.js → infoDiagram-6WML65LV-BWzHQa_Z.js} +1 -1
  47. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C_u3P6Ik.js → ishikawaDiagram-WSZJBQD7-BTjlovtU.js} +1 -1
  48. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DPDPv9HL.js → journeyDiagram-NVQOT4AX-DkvQoCc1.js} +1 -1
  49. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-D3OHdWiO.js → kanban-definition-27J2QSJJ-CHSzGi3W.js} +1 -1
  50. package/dist/worker/console/static/assets/{linear-DI88zD7n.js → linear-DZMkTCWH.js} +1 -1
  51. package/dist/worker/console/static/assets/{mermaid.core-p2l8IrWY.js → mermaid.core-BIMhty7A.js} +5 -5
  52. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-B1bAX-oS.js → mindmap-definition-FAOFIHXS-Dx-tyMl3.js} +1 -1
  53. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DwOnWxdD.js → pegDiagram-VL7TDLO6-C6G34rbY.js} +1 -1
  54. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-xRkTXnJC.js → pieDiagram-7S7Q4E2Y-CHK9XOfm.js} +1 -1
  55. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-_9UC5Zio.js → quadrantDiagram-CIZ2JOQS-CDARkI0w.js} +1 -1
  56. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CgEUirWJ.js → railroadDiagram-AXF67PYL-DiuUe0ZQ.js} +1 -1
  57. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-Czbpwiyz.js → requirementDiagram-LRYGKXZP-RE61UR56.js} +1 -1
  58. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-_j7_KiqY.js → sankeyDiagram-W5VNT64P-KDNLHMEG.js} +1 -1
  59. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BNJa6Hyi.js → sequenceDiagram-SI44F4Z6-CeVgXnD9.js} +1 -1
  60. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DedpKtOc.js → sizeCapture-X5ZJPWSS-CXwGyjjG.js} +1 -1
  61. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BBvthr7c.js → stateDiagram-OKZ733FA-BjTfozab.js} +1 -1
  62. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BXoYsyr2.js +1 -0
  63. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-Ds7umgEM.js → swimlanes-SLNWSIFB-BaXOB8GT.js} +2 -2
  64. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DfKliS4e.js +8 -0
  65. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKa-p1nF.js → timeline-definition-Z64GVDOM-C3r2hqUU.js} +1 -1
  66. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-LoUNR56o.js → vennDiagram-T6HMQDX7-MWKgl1S9.js} +1 -1
  67. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-Bqbl6ym7.js → wardleyDiagram-T6FBY63Y-C9iFcZPk.js} +1 -1
  68. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-B8dUg4lf.js → xychartDiagram-ELKLHX3M-DqnM24Jp.js} +1 -1
  69. package/dist/worker/console/static/index.html +2 -2
  70. package/dist/workflows/dag/frontend-closeout.js +1 -1
  71. package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
  72. package/dist/workflows/dag/frontend-review-context.js +2 -1
  73. package/dist/workflows/dag/frontend-review-scopes.js +2 -2
  74. package/dist/workflows/dag/frontend-verification-trace.js +1 -1
  75. package/dist/workflows/dag/init-hybrid.js +51 -159
  76. package/docs/templates/frontend-implementation-dag.json +9 -8
  77. package/package.json +1 -1
  78. package/skills/frontend-bounded-implement/SKILL.md +3 -3
  79. package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
  80. package/skills/frontend-contract/references/contract-protocol.md +3 -1
  81. package/skills/frontend-design-review/SKILL.md +12 -7
  82. package/skills/frontend-design-review/references/review-checklist.md +7 -7
  83. package/skills/frontend-plan/SKILL.md +12 -0
  84. package/skills/frontend-plan/references/decision-contract.md +25 -19
  85. package/skills/frontend-review/SKILL.md +12 -18
  86. package/skills/frontend-review/references/review-findings.md +24 -43
  87. package/dist/worker/console/static/assets/channel-C0A6UEIa.js +0 -1
  88. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DzguNppy.js +0 -1
  89. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DzguNppy.js +0 -1
  90. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BABVQnfM.js +0 -1
  91. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D0qsLaxR.js +0 -8
package/CHANGELOG.md CHANGED
@@ -2,18 +2,33 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ - 修复前端 Plan 无法提交实现步骤的问题:finalize_plan 支持按 AC 绑定实施动作,缺漏在节点内返回修正,避免空计划反复进入设计审查。
6
+
7
+ - 修复前端最终审查反复猜错范围 ID:明确 checkpoint 参数和补交步骤,收尾正确识别 checkpoint 之后的审批结论。
8
+
9
+ - 前端实现流程简化为需求实现覆盖审查和 `npm run build`,不再强制单测或测试方案;行为测试可后补,构建结果不冒充行为验证。
10
+
5
11
  ### 改进
6
12
 
13
+ - Operator Chat 浏览器面板默认以完整权限运行(去掉 iframe 沙箱与「临时解锁」状态条),并放开本机回环地址限制——`localhost` / `127.0.0.1` / `::1` 等本地开发服务器可直接在面板内浏览;地址栏仍仅放行 http/https,`javascript:` / `data:` / `file:` 等危险协议继续拦截,拒绝嵌入站点(X-Frame-Options / frame-ancestors)的解释面板与出口保持不变。
14
+
7
15
  - 前端 Plan 普通分片按本批完整需求材料打包,固定提示词、用户消息和工具定义不再挤占 24 KB 分片目标,也不再触发发送前的机械二分,减少小需求逐 AC 会话;实际模型容量检查与超限恢复继续生效。
8
16
 
9
17
  - 前端 Plan 小任务合并规划不再受固定 48 KB 输入门槛限制,避免提示词、用户消息或工具定义变长导致额外分片;完整输入、其余任务规模条件及容量恢复机制保持不变。
10
18
  - 节点侧栏修复执行分次下拉菜单被执行记录工具栏遮挡的问题,直接展示所选失败尝试的简要原因,并移除重复的左右切换箭头。
11
19
  - Operator Chat 的 Pi Runtime 按职责拆出工具构造、运行态检视和 SDK 适配,并共用创建/恢复/分叉的会话准备流程;对外入口、错误类型和会话行为保持不变。
12
20
 
21
+ ### 修复
22
+
23
+
24
+ - 前端设计审查的写入门禁只统计已提交的审批终态,避免审查范围、发现记录导致合法审批被误判为缺失或歧义;要求修改时保留具体审查意见,缺失、重复及冲突终态仍阻断写入。
25
+
13
26
  ## [0.42.1] - 2026-09-09
14
27
 
15
28
  ### 新增
16
29
 
30
+ - Console Chat 的 `/goal` 持续目标能力对 Pi 模式开放(与工作流模式同语义):斜杠面板两模式均可见 `/goal`;Pi 会话注册 `get_goal` / `create_goal` / `update_goal` 工具并纳入激活集;Goal HTTP 接口(创建/暂停/恢复/清除)在 Pi 会话不再返回模式拒绝;GoalBar 与目标编辑面板在 Pi 会话渲染;压缩恢复、每轮 Goal 上下文与有界自主续跑(仅显式 `/goal` 才 arm,maxRounds 上限,reload/重启/出错/暂停即 disarm)在 Pi 会话可用。
31
+
17
32
  - Operator Chat 浏览器面板(DSH 风格):Console 右侧辅助栏新增「浏览器」tab——地址栏(自动补 https、仅 http/https、禁止 javascript/data/file 等危险协议与本机回环地址)、后退/前进/刷新导航栈、系统浏览器跳转;页面运行在无 same-origin、无 top-navigation 的沙箱 iframe 中(访问的页面拿不到 Console 的存储与 API),沙箱状态条支持单页面临时解锁(红色警示 + 一键恢复);对拒绝被嵌入的站点(X-Frame-Options / frame-ancestors)给出明确解释面板与「在系统浏览器打开 / 仍要加载」出口,探测端点仅返回响应头、仅限 http(s) 非回环、8 秒硬超时。
18
33
  - Operator Chat 源代码管理(DSH 风格):模型获得 `scm` 工具(status/diff/stage/unstage/discard/commit/log/branch/push/pull,固定参数 git 无 shell、限时限量输出);Console 右侧辅助栏新增「源码」面板(DSH GitView 布局——分支下拉切换、已暂存/更改分组与全部暂存/取消暂存、单行提交框 Ctrl+Enter、内联分页历史带 refs 徽标与相对时间、点击文件看 diff、右键菜单放弃更改/复制路径);模型与面板共用同一工作区级 ScmService。
19
34
  - Operator Chat 在具备 Aimax 凭据资格时,向对话进程注入 `$AIMAX_AUTH_TOKEN`(明文或 `sm4:v1:` 解密后的 ticket),供 skills 读取;文件缺失、无法解析或解密失败时不注入该变量。
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.43.0-next.10",
4
- "gitSha": "a57ccda19e1372045d03071a01e7e6df1be2e942",
5
- "builtAt": "2026-09-10T04:37:15.842Z"
3
+ "version": "0.43.0-next.11",
4
+ "gitSha": "e64b429d8ed2b8c87afe9f2a1d167ae29e3fb0d9",
5
+ "builtAt": "2026-09-10T11:05:38.558Z"
6
6
  }
@@ -2286,9 +2286,13 @@ export async function createFrontendPlanLedgerTools(input) {
2286
2286
  const finalizePlanTool = defineTool({
2287
2287
  name: "finalize_plan",
2288
2288
  label: "finalize_plan",
2289
- description: "Commit the finalize_plan terminal. Requirements, verification targets, and evidence gaps (optional) were already committed incrementally through record_plan_requirement / record_plan_verification_target / record_plan_evidence_gap; finalize_plan assembles them from the ledger together with these optional remaining fields, publishes the canonical editable patch on a target-surface fact, and commits the terminal. A successful terminal commit occurs exactly once. If validation fails, correct only the reported facts and retry finalize.",
2290
- promptSnippet: "Commit the finalize_plan terminal (ledger fields + optional residualRisks / realIntegrationGap).",
2289
+ description: "Commit the finalize_plan terminal. Requirements, verification targets, and evidence gaps (optional) were already committed incrementally through record_plan_requirement / record_plan_verification_target / record_plan_evidence_gap; finalize_plan requires implementationSteps: [{requirementIds, action}] covering every frozen requirement (shared steps allowed), and assembles them with the ledger and optional remaining fields, publishes the canonical editable patch on a target-surface fact, and commits the terminal. A successful terminal commit occurs exactly once. If validation fails, correct only the reported facts and retry finalize.",
2290
+ promptSnippet: "Commit finalize_plan with implementationSteps: [{requirementIds, action}] covering every frozen requirement; optional residualRisks / realIntegrationGap.",
2291
2291
  parameters: Type.Object({
2292
+ implementationSteps: Type.Optional(Type.Array(Type.Object({
2293
+ requirementIds: Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),
2294
+ action: Type.String({ minLength: 1 }),
2295
+ }, { additionalProperties: false }))),
2292
2296
  residualRisks: optionalStringArray,
2293
2297
  realIntegrationGap: optionalString,
2294
2298
  }, { additionalProperties: false }),
@@ -2305,8 +2309,23 @@ export async function createFrontendPlanLedgerTools(input) {
2305
2309
  if (missingData.length)
2306
2310
  return planToolReceipt({ ok: false, kind: "finalize_plan", code: "PLAN_DATA_FLOW_INCOMPLETE", error: missingData.map(f => f.reason).join("; ") });
2307
2311
  const fragment = assemblePlanPatchFromCommittedFacts(committed, contractInheritance) ?? {};
2312
+ const requiredIds = new Set([
2313
+ ...(input.requirementIds ?? []),
2314
+ ...contractInheritance.keys(),
2315
+ ...(Array.isArray(fragment.requirements) ? fragment.requirements.flatMap((entry) => isRecordObject(entry) && typeof entry.id === "string" ? [entry.id] : []) : []),
2316
+ ]);
2317
+ const steps = params?.implementationSteps ?? [];
2318
+ const coveredIds = new Set(steps.flatMap(step => step.requirementIds));
2319
+ const missingRequirementIds = [...requiredIds].filter(id => !coveredIds.has(id));
2320
+ const unknownRequirementIds = [...coveredIds].filter(id => !requiredIds.has(id));
2321
+ if (missingRequirementIds.length || unknownRequirementIds.length || steps.some(step => !step.action.trim())) {
2322
+ return planToolReceipt({ ok: false, kind: "finalize_plan", code: "PLAN_IMPLEMENTATION_STEPS_INCOMPLETE",
2323
+ error: `Submit finalize_plan with non-empty implementationSteps: [{requirementIds: [exact frozen IDs], action: "what to change and where"}]. Cover every requirement; shared steps may cover several IDs. Missing: ${missingRequirementIds.join(", ") || "none"}; unknown: ${unknownRequirementIds.join(", ") || "none"}. Actions must not be blank. Do not add a test plan.`,
2324
+ });
2325
+ }
2308
2326
  const patch = {
2309
2327
  ...fragment,
2328
+ ...(steps.length ? { implementationSteps: steps.map(step => `[${[...new Set(step.requirementIds)].join(", ")}] ${step.action.trim()}`) } : {}),
2310
2329
  ...(params?.residualRisks
2311
2330
  ? { residualRisks: params.residualRisks }
2312
2331
  : {}),
@@ -3802,7 +3821,7 @@ const FRONTEND_PLAN_SEGMENTS = [
3802
3821
  toolNames: null,
3803
3822
  instruction: [
3804
3823
  "PLAN PHASE — finalize.",
3805
- "All record_* tools are available only for a narrowly named correction if the finalize receipt reports missing or invalid facts. Otherwise call finalize_plan exactly once with no extra fields.",
3824
+ "All record_* tools are available only for a narrowly named correction if the finalize receipt reports missing or invalid facts. Otherwise call finalize_plan with implementationSteps: [{requirementIds, action}] covering every frozen requirement. Describe concrete changes within approved paths, including what constraints preserve; shared steps may cover related IDs. Do not add tests or a test plan.",
3806
3825
  ].join(" "),
3807
3826
  },
3808
3827
  ];
@@ -4318,12 +4337,14 @@ export async function runFrontendReviewSegmentedSessions(input) {
4318
4337
  index--;
4319
4338
  continue;
4320
4339
  }
4340
+ const completionInstruction = `${item.repairs ? "REPAIR: the prior session did not commit all required checkpoints/verdict. Do not repeat the review narrative. " : ""}Complete these exact runtime scope IDs using complete_review_scope: ${JSON.stringify(scopes.map(scope => scope.id))}. These are scope IDs, not node IDs. ${finalScope ? `After those checkpoints succeed, call exactly one terminal tool: ${terminalKinds.join(" or ")}. A prose conclusion is not a committed verdict.` : "More scopes remain; do not submit an overall verdict yet."}`;
4341
+ const userMessage = `${input.sessionOptions.userMessage}\n\n${completionInstruction}`;
4321
4342
  if (++calls > 128)
4322
4343
  return { ...last, ok: false, failureCategory: "frontend-input-exhausted", stderr: "FRONTEND_REVIEW_RECOVERY_EXHAUSTED: session quota reached" };
4323
- last = await observeFrontendSession({ ...input.observation, phase: `${input.phase}/scope`, scopeIds: scopes.map(s => s.id), prompt, userMessage: input.sessionOptions.userMessage, customTools,
4344
+ last = await observeFrontendSession({ ...input.observation, phase: `${input.phase}/scope`, scopeIds: scopes.map(s => s.id), prompt, userMessage, customTools,
4324
4345
  artifactPath: input.observation?.artifactPath ? `${input.observation.artifactPath}-${calls}.json` : undefined,
4325
4346
  committedCount: () => protocol.committedFacts().length, durableCommittedCount: () => protocol.committedFacts().length,
4326
- }, observer => input.piStepFn({ ...input.sessionOptions, prompt, onAttemptObservation: observer, writerToolPolicy: { requireSdk: true, customTools } }));
4347
+ }, observer => input.piStepFn({ ...input.sessionOptions, prompt, userMessage, onAttemptObservation: observer, writerToolPolicy: { requireSdk: true, customTools } }));
4327
4348
  await input.tools.flush();
4328
4349
  await input.inventory.validate();
4329
4350
  if (last.timedOut || /interrupt|termination-unconfirmed|budget_breach/.test(last.failureCategory))
@@ -4607,7 +4628,7 @@ export async function runFrontendPlanSegmentedSessions(input) {
4607
4628
  const buildPhasePrompt = (segment, missing = [], scopeIds = allRequirementIds) => {
4608
4629
  const compact = allRequirementIds.length > 0
4609
4630
  ? compactFrontendPlanPromptForRequirementSlice(input.basePrompt, scopeIds, {
4610
- includeRequirementText: segment.id === "global-mock-data",
4631
+ includeRequirementText: segment.id === "global-mock-data" || segment.id === "finalize",
4611
4632
  includeVerificationTargets: false,
4612
4633
  includeDesignEvidence: segment.id === "global-dependency-deviation" || segment.id === "finalize",
4613
4634
  includeChecklist: false,
@@ -2329,7 +2329,7 @@ async function collectReviewTerminalKinds(runDir, reviewNodeId) {
2329
2329
  const kind = record.fact.kind;
2330
2330
  return typeof kind === "string" ? kind : "";
2331
2331
  })
2332
- .filter(Boolean);
2332
+ .filter((kind) => kind === "approve_review" || kind === "request_review_changes");
2333
2333
  }
2334
2334
  catch {
2335
2335
  return [];
@@ -2348,7 +2348,7 @@ async function collectDesignTerminalKinds(runDir, designNodeId) {
2348
2348
  const kind = record.fact.kind;
2349
2349
  return typeof kind === "string" ? kind : "";
2350
2350
  })
2351
- .filter(Boolean);
2351
+ .filter((kind) => kind === "approve_design" || kind === "request_design_changes");
2352
2352
  }
2353
2353
  catch {
2354
2354
  return [];
@@ -2974,6 +2974,7 @@ async function executeFrontendCloseout(input, meta) {
2974
2974
  const contract = frontendImplementationContractSchema.parse(JSON.parse(contractRaw));
2975
2975
  const trace = context.verificationTrace;
2976
2976
  const verificationTargets = (trace?.targets ?? []).map((target) => ({
2977
+ mode: contract.verificationTargets.find((entry) => entry.id === target.id)?.mode ?? "static",
2977
2978
  status: target.status === "ok" ? "ok" : "failed",
2978
2979
  }));
2979
2980
  const mockEvidenceBound = contract.mockApi.strategy !== "not-needed" &&
@@ -1,15 +1,11 @@
1
1
  /**
2
2
  * Pure URL policy for the Operator Chat browser panel: normalize user input
3
- * into an http(s) URL and refuse destinations that would be dangerous to
4
- * embed in the panel iframe. Dependency-free so it is unit-testable.
3
+ * into an http(s) URL. Dependency-free so it is unit-testable.
5
4
  *
6
- * The iframe sandbox (opaque origin no allow-same-origin, no top
7
- * navigation) is the primary security boundary; this module is the
8
- * address-bar gate on top of it: only http/https may be navigated, and
9
- * loopback addresses are refused so a browsed page cannot probe local
10
- * services by user action. The Console's OWN origin is explicitly allowed —
11
- * the sandbox still renders it in an opaque origin with no same-origin
12
- * privileges, exactly like any other site.
5
+ * Only the scheme is gated: javascript:, data:, file: and friends must never
6
+ * reach the iframe. Local addresses (localhost / 127.0.0.1 / ::1 / LAN
7
+ * hosts) are deliberately allowed the panel is a development console and
8
+ * its users routinely browse local dev servers.
13
9
  */
14
10
  /**
15
11
  * Extract the `frame-ancestors` source list of a Content-Security-Policy
@@ -47,16 +43,6 @@ export function embeddabilityOf(probe) {
47
43
  }
48
44
  return "embeddable";
49
45
  }
50
- /** A loopback hostname (localhost, IPv6 ::1, 127.0.0.0/8, 0.0.0.0). */
51
- export function isLoopbackHostname(hostname) {
52
- const host = hostname.replace(/^\[|\]$/g, "").toLowerCase();
53
- if (host === "localhost" || host === "::1" || host === "0.0.0.0")
54
- return true;
55
- const parts = host.split(".");
56
- return (parts.length === 4 &&
57
- parts[0] === "127" &&
58
- parts.every((part) => /^\d{1,3}$/.test(part) && Number(part) <= 255));
59
- }
60
46
  /**
61
47
  * Schemes that must never reach the iframe even without `//` (javascript:,
62
48
  * data:, file:, ...). Host:port lookalikes (example.com:8080) are NOT here —
@@ -88,12 +74,8 @@ const FORBIDDEN_SCHEMES = new Set([
88
74
  /**
89
75
  * Normalize one address-bar input against the navigation policy.
90
76
  * @param input raw user text.
91
- * @param selfOrigin the Console's own origin (window.location.origin). The
92
- * Console itself may be browsed in the panel (the sandbox keeps it opaque),
93
- * so it is let through BEFORE the loopback check — its host is normally
94
- * loopback.
95
77
  */
96
- export function normalizeBrowserUrl(input, selfOrigin) {
78
+ export function normalizeBrowserUrl(input) {
97
79
  const trimmed = input.trim();
98
80
  if (trimmed === "")
99
81
  return { kind: "invalid" };
@@ -127,17 +109,5 @@ export function normalizeBrowserUrl(input, selfOrigin) {
127
109
  if (url.protocol !== "http:" && url.protocol !== "https:") {
128
110
  return { kind: "blocked", reason: "scheme" };
129
111
  }
130
- // The Console's own origin is allowed (browsed in an opaque origin like
131
- // any other site); checked before the loopback gate because its host is
132
- // normally loopback.
133
- try {
134
- if (url.origin === new URL(selfOrigin).origin)
135
- return { kind: "ok", url: url.href };
136
- }
137
- catch {
138
- // Unparsable selfOrigin (never in practice): fall through to the gate.
139
- }
140
- if (isLoopbackHostname(url.hostname))
141
- return { kind: "blocked", reason: "loopback" };
142
112
  return { kind: "ok", url: url.href };
143
113
  }
@@ -3,9 +3,10 @@
3
3
  * endpoint the panel uses to explain an iframe refusal (X-Frame-Options /
4
4
  * CSP frame-ancestors are exactly the signals the browser enforces when it
5
5
  * refuses to embed a site). The probe is display-only (headers back to the
6
- * caller), restricted to http(s) non-loopback URLs, with a hard timeout.
6
+ * caller), restricted to http(s) URLs, with a hard timeout. Local addresses
7
+ * are allowed — the panel routinely browses local dev servers.
7
8
  */
8
- import { embeddabilityOf, extractFrameAncestors, isLoopbackHostname, } from "./browser-policy.js";
9
+ import { embeddabilityOf, extractFrameAncestors, } from "./browser-policy.js";
9
10
  function workspaceIdOf(req) {
10
11
  try {
11
12
  return new URL(req.url ?? "/", "http://localhost").searchParams.get("workspaceId") ?? undefined;
@@ -69,15 +70,6 @@ export async function handleBrowserRequest(req, res, deps, pathname) {
69
70
  });
70
71
  return true;
71
72
  }
72
- // Mirror the address-bar policy: loopback stays unreachable from
73
- // the panel, so probing it would leak nothing the panel could use.
74
- if (isLoopbackHostname(parsed.hostname)) {
75
- sendJson(res, 400, {
76
- ok: false,
77
- error: { code: "LOOPBACK_REFUSED", message: "local addresses are not probed" },
78
- });
79
- return true;
80
- }
81
73
  const controller = new AbortController();
82
74
  const timer = setTimeout(() => controller.abort(), 8000);
83
75
  try {
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Session-bound Goal tools (workflow-mode only).
2
+ * Session-bound Goal tools (shared by workflow and Pi modes since
3
+ * 2026-09-10; see exec-plan 2026-09-10-console-chat-goal-for-pi-mode).
3
4
  * create_goal still requires a consumed model-create grant from the registry.
4
5
  */
5
6
  const GET_GOAL_DESCRIPTION = "Read the current session's durable cross-turn Goal, including revision, status, round limit, and whether this Console process is authorized to continue it.";
@@ -33,7 +33,7 @@ import { parseProviderError, } from "./provider-error.js";
33
33
  import { projectCompactSnapshot, } from "./chat-event-store.js";
34
34
  import { extractUsageSample } from "./usage.js";
35
35
  import { OPERATOR_CHAT_ALLOWED_TOOLS, authorizeOperatorChatTool, assertNoWriteToolInList, } from "./tools.js";
36
- import { authorizeChatSessionTool, DEFAULT_CONSOLE_CHAT_SESSION_MODE, chatActiveToolBaseline, composeChatSystemPrompt, composeChatSystemPromptParts, computeChatActiveToolNames, shouldInjectGoalContinuation, shouldLoadWorkflowBusinessTools, } from "./session-mode.js";
36
+ import { authorizeChatSessionTool, DEFAULT_CONSOLE_CHAT_SESSION_MODE, chatActiveToolBaseline, composeChatSystemPrompt, composeChatSystemPromptParts, computeChatActiveToolNames, shouldLoadWorkflowBusinessTools, } from "./session-mode.js";
37
37
  import { buildAgentCustomTool, ExploreOrchestrator, } from "./subagents/index.js";
38
38
  import { createOperatorChatResourceLoader, } from "./resource-loader.js";
39
39
  import { applySkillAutoInvocationPreferences, loadResourcePreferences, } from "./resource-preferences-store.js";
@@ -492,9 +492,7 @@ export class ConsolePiRuntime {
492
492
  const pressureExtension = sessionId
493
493
  ? this.createContextPressureInlineExtension(sessionId)
494
494
  : undefined;
495
- const goalContextExtension = sessionId &&
496
- this.options.goalRegistry &&
497
- shouldInjectGoalContinuation(sessionMode)
495
+ const goalContextExtension = sessionId && this.options.goalRegistry
498
496
  ? createGoalCompactionContextExtension({
499
497
  sessionId,
500
498
  registry: this.options.goalRegistry,
@@ -985,7 +983,7 @@ export class ConsolePiRuntime {
985
983
  sessionMode,
986
984
  })
987
985
  : undefined;
988
- const goalTools = loadWorkflowTools && this.options.goalRegistry
986
+ const goalTools = this.options.goalRegistry
989
987
  ? await buildGoalTools({ sessionId, registry: this.options.goalRegistry })
990
988
  : [];
991
989
  const terminalTools = this.options.terminalRegistry
@@ -1819,8 +1817,7 @@ export class ConsolePiRuntime {
1819
1817
  if (options?.turnId && this.options.todoRegistry) {
1820
1818
  this.options.todoRegistry.startTurn(sessionId, options.turnId);
1821
1819
  }
1822
- if (this.options.goalRegistry &&
1823
- shouldInjectGoalContinuation(this.sessionModeOf(sessionId))) {
1820
+ if (this.options.goalRegistry) {
1824
1821
  this.options.goalRegistry.startTurn(sessionId, text);
1825
1822
  }
1826
1823
  // AC-FIX-002: if Stop already fired before readiness, never start model work.
@@ -1327,7 +1327,7 @@ export async function handleChatGoal(req, res, deps, sessionId) {
1327
1327
  });
1328
1328
  return;
1329
1329
  }
1330
- if (!(await requireWorkflowSession(res, deps, sessionId)))
1330
+ if (!(await requireChatSession(res, deps, sessionId)))
1331
1331
  return;
1332
1332
  if (req.method === "GET") {
1333
1333
  sendJson(res, 200, { ok: true, goal: registry.get(sessionId) });
@@ -2256,10 +2256,6 @@ export async function driveGoalRound(deps, sessionId) {
2256
2256
  registry.disarm(sessionId);
2257
2257
  return "idle";
2258
2258
  }
2259
- if (!isWorkflowSessionMode(readStoredSessionMode(record.sessionMode))) {
2260
- registry.disarm(sessionId);
2261
- return "idle";
2262
- }
2263
2259
  const runtimeFacts = deps.runtime.getSessionBusyFacts(sessionId);
2264
2260
  const operationStore = deps.runtime.actionContext?.operations;
2265
2261
  const linkedOperationIds = linkedOperationIdsForGoal(deps.events.snapshot(sessionId));
@@ -27,21 +27,22 @@ export const SESSION_MODE_COPY = {
27
27
  description: "保留压缩与 Explore,直接协作编码",
28
28
  createLabel: "新建 Pi 会话",
29
29
  bannerTitle: "Pi",
30
- bannerBody: "保留 Console 压缩与 Explore,直接协作编码。不注入工作流业务指令、业务工具或 Goal 驱动。",
30
+ bannerBody: "保留 Console 压缩、Explore 与持续目标,直接协作编码。不注入工作流业务指令与业务工具。",
31
31
  landingTitle: "开始一段 Pi 协作",
32
- landingBody: "Pi 模式保留压缩、Explore、认证与 SDD 接入,取消工作流业务注入。适合有人监督的直接编码与调试。",
32
+ landingBody: "Pi 模式保留压缩、Explore、持续目标、认证与 SDD 接入,取消工作流业务注入。适合有人监督的直接编码与调试。",
33
33
  emptyTitle: "直接协作编码",
34
34
  emptyBody: "会话已就绪。输入框上方可切换工作区或模式。使用 Pi 工具读写仓库;Explore 负责只读深挖。本会话不加载任务 / DAG 工作流工具。",
35
35
  },
36
36
  };
37
37
  /** Slash actions that only exist in workflow sessions. Browser-safe: pure
38
- * string constants, no runtime/tool policy imports. */
38
+ * string constants, no runtime/tool policy imports. `/goal` was moved to
39
+ * shared on 2026-09-10 (exec-plan 2026-09-10-console-chat-goal-for-pi-mode);
40
+ * interview/panel navigation remain workflow-only. */
39
41
  export const WORKFLOW_EXCLUSIVE_SLASH_ACTIONS = Object.freeze([
40
42
  "focus-panel:task",
41
43
  "focus-panel:contract",
42
44
  "focus-panel:dag",
43
45
  "focus:interview",
44
- "goal",
45
46
  ]);
46
47
  export function isWorkflowExclusiveSlashAction(action) {
47
48
  return WORKFLOW_EXCLUSIVE_SLASH_ACTIONS.includes(action);
@@ -74,7 +74,8 @@ export const PI_CHAT_SYSTEM_PROMPT_BASE = [
74
74
  "Use read/write/edit/bash/grep/find/ls to inspect and change the workspace. apply_patch, full-tools, shell and coding-chat are denied.",
75
75
  "Agent (Explore) is a built-in read-only subagent for path-uncertain codebase search. Do not use it for a known single-file read. Prefer safe-read/safe-grep for secret-safe probes.",
76
76
  "ask_user_question pauses for a real user answer. todo_write tracks the current work and is restored after compression; it is not a workflow auto-continue signal. The persistent terminal tool is available.",
77
- "This session keeps Console compression (L0/L1/L2, sift, strict checkpoint) and existing Aimax / SDD access. Do not create tasks, run DAGs, drive Goals, or start requirement interviews from this session.",
77
+ "Goal tools (get_goal / create_goal / update_goal) track the session's durable cross-turn objective. Create a Goal only when the user explicitly asks to start one; iterate in bounded rounds until complete or blocked.",
78
+ "This session keeps Console compression (L0/L1/L2, sift, strict checkpoint) and existing Aimax / SDD access. Do not create tasks, run DAGs, or start requirement interviews from this session.",
78
79
  "Obey repository AGENTS.md, skills and extensions when they apply. Choosing Pi mode is not extra write authorization and does not bypass Console access control or output scrubbing.",
79
80
  ].join("\n");
80
81
  export const CHAT_SAFE_EXPLORE_TOOL_IDS = Object.freeze([
@@ -87,7 +88,11 @@ export const PI_CHAT_GENERIC_HELPER_TOOLS = Object.freeze([
87
88
  "ask_user_question",
88
89
  "todo_write",
89
90
  ]);
90
- export const PI_CHAT_WORKFLOW_TOOL_IDS = Object.freeze([
91
+ /** Durable cross-turn Goal tools. Shared by both session modes since
92
+ * 2026-09-10 (exec-plan 2026-09-10-console-chat-goal-for-pi-mode); they are
93
+ * NOT workflow business tools and are registered whenever a GoalRegistry
94
+ * is present. */
95
+ export const GOAL_TOOL_IDS = Object.freeze([
91
96
  "get_goal",
92
97
  "create_goal",
93
98
  "update_goal",
@@ -102,7 +107,6 @@ const CHAT_EXTENSION_DENIED_TOOL_IDS = new Set([
102
107
  "shell",
103
108
  ].map((name) => name.toLowerCase()));
104
109
  const WORKFLOW_OPERATOR_TOOL_IDS = new Set(OPERATOR_CHAT_ALLOWED_TOOLS.map((name) => name.toLowerCase()));
105
- const PI_GOAL_TOOL_IDS = new Set(PI_CHAT_WORKFLOW_TOOL_IDS.map((name) => name.toLowerCase()));
106
110
  export function workflowActiveToolBaseline() {
107
111
  return [
108
112
  ...OPERATOR_CHAT_ALLOWED_TOOLS,
@@ -117,6 +121,7 @@ export function piActiveToolBaseline() {
117
121
  ...CHAT_SAFE_EXPLORE_TOOL_IDS,
118
122
  ...OPERATOR_CHAT_BUILTIN_CUSTOM_TOOLS,
119
123
  ...PI_CHAT_GENERIC_HELPER_TOOLS,
124
+ ...GOAL_TOOL_IDS,
120
125
  ];
121
126
  }
122
127
  export function chatActiveToolBaseline(sessionMode) {
@@ -126,7 +131,8 @@ export function chatActiveToolBaseline(sessionMode) {
126
131
  }
127
132
  /**
128
133
  * Gate 2 pin: mode baseline plus user/project extension tools. Pi mode must
129
- * not re-add operator actions or Goal tools via the extras pass.
134
+ * not re-add operator actions via the extras pass (Goal tools are shared and
135
+ * part of the Pi baseline since 2026-09-10).
130
136
  */
131
137
  export function computeChatActiveToolNames(session, sessionMode) {
132
138
  const baseline = chatActiveToolBaseline(sessionMode);
@@ -145,8 +151,6 @@ export function computeChatActiveToolNames(session, sessionMode) {
145
151
  continue;
146
152
  if (sessionMode === "pi" && WORKFLOW_OPERATOR_TOOL_IDS.has(lower))
147
153
  continue;
148
- if (sessionMode === "pi" && PI_GOAL_TOOL_IDS.has(lower))
149
- continue;
150
154
  extras.push(name);
151
155
  }
152
156
  return extras.length > 0 ? [...baseline, ...extras] : baseline;
@@ -172,7 +176,7 @@ export function authorizeChatSessionTool(toolId, sessionMode) {
172
176
  };
173
177
  }
174
178
  const lower = id.toLowerCase();
175
- if (WORKFLOW_OPERATOR_TOOL_IDS.has(lower) || PI_GOAL_TOOL_IDS.has(lower)) {
179
+ if (WORKFLOW_OPERATOR_TOOL_IDS.has(lower)) {
176
180
  return {
177
181
  ok: false,
178
182
  code: "tool-denied",
@@ -207,9 +211,6 @@ export { WORKFLOW_EXCLUSIVE_SLASH_ACTIONS, isWorkflowExclusiveSlashAction, } fro
207
211
  export function shouldLoadWorkflowBusinessTools(sessionMode) {
208
212
  return sessionMode === "workflow";
209
213
  }
210
- export function shouldInjectGoalContinuation(sessionMode) {
211
- return sessionMode === "workflow";
212
- }
213
214
  export function shouldAcceptOperatorSnapshot(sessionMode) {
214
215
  return sessionMode === "workflow";
215
216
  }
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-Dwd6r-SF.js";import{p as f}from"./chunk-JWPE2WC7-CuGp0DeE.js";import{_ as n,l as o}from"./mermaid.core-p2l8IrWY.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-BdXcxtlb.js";import"./index-24jp3aBh.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-C92cgilm.js";import{p as f}from"./chunk-JWPE2WC7-CGHbJyCH.js";import{_ as n,l as o}from"./mermaid.core-BIMhty7A.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-B-4yuRAX.js";import"./index-CUPeoE8W.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-p2l8IrWY.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-BIMhty7A.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};