@tea-agent/loop-agent 0.44.0-next.12 → 0.44.0-next.14

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 (188) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/README.md +12 -12
  3. package/dist/adapters/loop-agent.js +34 -0
  4. package/dist/build-stamp.json +3 -3
  5. package/dist/cli/command-definitions.js +5 -5
  6. package/dist/cli/program.js +1 -4
  7. package/dist/commands/init-legacy-audit.js +330 -0
  8. package/dist/commands/init-upgrade.js +644 -104
  9. package/dist/commands/init.js +686 -330
  10. package/dist/commands/operator-guide.js +99 -0
  11. package/dist/commands/operator.js +16 -3
  12. package/dist/executors/dag-pi-executor.js +11 -6
  13. package/dist/executors/pi-sdk-executor.js +3 -1
  14. package/dist/executors/pi-writer-tool-policy.js +60 -4
  15. package/dist/executors/playwright-cli-launcher.js +31 -45
  16. package/dist/executors/shell-write-guard.js +24 -67
  17. package/dist/governance/exec-plans.js +10 -1
  18. package/dist/governance/harness.js +2 -7
  19. package/dist/governance/manifest-types.js +28 -9
  20. package/dist/governance/project-capability-scanner.js +263 -0
  21. package/dist/governance/project-config.js +96 -0
  22. package/dist/governance/resource-catalog.js +151 -0
  23. package/dist/infrastructure/console/app-data.js +6 -2
  24. package/dist/shared/operator/capabilities.js +2 -2
  25. package/dist/shared/package-metadata.js +23 -7
  26. package/dist/shared/pi-context-pressure/extension.js +23 -0
  27. package/dist/shared/pi-context-pressure/index.js +1 -0
  28. package/dist/shared/pi-context-pressure/telemetry.js +4 -0
  29. package/dist/shared/pi-context-pressure/tool-result-pruner.js +98 -0
  30. package/dist/shared/update/npm-client.js +49 -1
  31. package/dist/task/config-types.js +4 -2
  32. package/dist/task/source-prepare/build-draft.js +1 -0
  33. package/dist/task/source-prepare/path-policy.js +17 -7
  34. package/dist/worker/cli.js +3 -5
  35. package/dist/worker/console/chat/browser-automation.js +455 -41
  36. package/dist/worker/console/chat/browser-content.js +74 -0
  37. package/dist/worker/console/chat/browser-diagnostics.js +250 -0
  38. package/dist/worker/console/chat/browser-evaluation.js +58 -0
  39. package/dist/worker/console/chat/browser-operation-queue.js +19 -0
  40. package/dist/worker/console/chat/browser-pick.js +113 -0
  41. package/dist/worker/console/chat/browser-routes.js +54 -5
  42. package/dist/worker/console/chat/browser-screenshot-result.js +47 -0
  43. package/dist/worker/console/chat/browser-storage.js +89 -0
  44. package/dist/worker/console/chat/chat-event-store.js +7 -6
  45. package/dist/worker/console/chat/context-insights.js +84 -19
  46. package/dist/worker/console/chat/pet/pet-affinity.js +169 -0
  47. package/dist/worker/console/chat/pet/pet-persist.js +109 -0
  48. package/dist/worker/console/chat/pet/pet-registry.js +142 -0
  49. package/dist/worker/console/chat/pet/pet-remarks.js +48 -0
  50. package/dist/worker/console/chat/pet/pet-routes.js +125 -0
  51. package/dist/worker/console/chat/pet/pet-service.js +262 -0
  52. package/dist/worker/console/chat/pet/pet-state.js +99 -0
  53. package/dist/worker/console/chat/pi-mode-loop-isolation.js +17 -2
  54. package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +125 -174
  55. package/dist/worker/console/chat/pi-runtime.js +8 -3
  56. package/dist/worker/console/chat/repo-browser.js +80 -2
  57. package/dist/worker/console/chat/repo-preview-kind.js +155 -0
  58. package/dist/worker/console/chat/routes.js +43 -7
  59. package/dist/worker/console/chat/scheduled-goal-request.js +14 -6
  60. package/dist/worker/console/chat/session-mode.js +1 -1
  61. package/dist/worker/console/chat/session-store.js +24 -5
  62. package/dist/worker/console/chat/tools.js +12 -0
  63. package/dist/worker/console/console-shutdown.js +34 -0
  64. package/dist/worker/console/server.js +2 -1
  65. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-r1NAPU_5.js → abnfDiagram-N423BO3Z-DASc69AM.js} +1 -1
  66. package/dist/worker/console/static/assets/{arc-dT5T4sVL.js → arc-h09p-LAc.js} +1 -1
  67. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP_cOq46.js → architectureDiagram-T3A2C74G-CZ3dtLkh.js} +1 -1
  68. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-sToEZxEf.js → blockDiagram-VBNYF7ZC-DMrRhMXG.js} +1 -1
  69. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DSxwwi2m.js → c4Diagram-5PPSVZJV-DQxisHV6.js} +1 -1
  70. package/dist/worker/console/static/assets/channel-D1zgKZfg.js +1 -0
  71. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-B9fh0IkF.js → chunk-2GRJ4B5K-CefVN9zh.js} +1 -1
  72. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CAUNl-A6.js → chunk-2Q5K7J3B-DmR1Koq2.js} +1 -1
  73. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BomeqbNX.js → chunk-5RXB4S5H-NlzrSW7L.js} +1 -1
  74. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BNAuTOLE.js → chunk-5VM5RSS4-DfelJv-0.js} +1 -1
  75. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DfzjRD5y.js → chunk-6Q2QTUOP-BK6RFy58.js} +1 -1
  76. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C3uE-yc2.js → chunk-GF5L2VYU-BAeh9lz4.js} +1 -1
  77. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-C3sQMMYr.js → chunk-JWPE2WC7-ChPS5WzG.js} +1 -1
  78. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-D_AtEYQL.js → chunk-KBJHAD2P-BoVe5IM6.js} +1 -1
  79. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DW4TwhKv.js → chunk-RYQCIY6F-C4q_0Lw9.js} +1 -1
  80. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CTQDmJcp.js → chunk-XXDRQBXY-Bb9TvjeY.js} +1 -1
  81. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CXNNsY2M.js +1 -0
  82. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CXNNsY2M.js +1 -0
  83. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-iMqPuBsL.js → cose-bilkent-JH36ORCC-DmNnL8Ff.js} +1 -1
  84. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-DktIuDWs.js → cynefin-VYW2F7L2-Contvx58.js} +1 -1
  85. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BgVnjyEs.js → cynefinDiagram-MW4NZA55-Cigq7cjk.js} +1 -1
  86. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-CR25E4bu.js → dagre-VZM6K2ZE-dEbC0nxb.js} +1 -1
  87. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CPM2h5HY.js → diagram-7IWD3JNH-CzIztESV.js} +1 -1
  88. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-DqF0x2g1.js → diagram-B4RE2ZJO-Bo14zbaY.js} +1 -1
  89. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-G8BYp2eb.js → diagram-LBJQPF4R-C4xUyil6.js} +1 -1
  90. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BbC4kT_D.js → diagram-Q27KOJAE-CaBY_uYa.js} +1 -1
  91. package/dist/worker/console/static/assets/{diagram-UB23O5K3-CKZwZ-G5.js → diagram-UB23O5K3-ClUXUeiu.js} +1 -1
  92. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-kJDmheia.js → ebnfDiagram-BXEA7PRR-BbGCgjC6.js} +1 -1
  93. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DFTVHyxB.js → erDiagram-JOGREHBK-Dr-AcwSl.js} +1 -1
  94. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BqdN5_os.js → flowDiagram-UKHOOZJN-BG8Gcfyc.js} +1 -1
  95. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-SYDjVakh.js → ganttDiagram-PKOTCBZU-CFVaPs5r.js} +1 -1
  96. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bf8bNpGA.js → gitGraphDiagram-DS77QQ5N-ChJ8pm-O.js} +1 -1
  97. package/dist/worker/console/static/assets/index-B_5GhVIO.js +488 -0
  98. package/dist/worker/console/static/assets/index-C7YMBluX.css +1 -0
  99. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DIeAmJ45.js → infoDiagram-6WML65LV-C5J9-uCZ.js} +1 -1
  100. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-oikqUAlo.js → ishikawaDiagram-WSZJBQD7-BcfjqzDv.js} +1 -1
  101. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-mKEF_xYT.js → journeyDiagram-NVQOT4AX-BzzCO-rD.js} +1 -1
  102. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BdWJHPnN.js → kanban-definition-27J2QSJJ-NCHUZ46h.js} +1 -1
  103. package/dist/worker/console/static/assets/{linear-DGRlieMH.js → linear-BKZlWCUU.js} +1 -1
  104. package/dist/worker/console/static/assets/{mermaid.core-4P9yPC9c.js → mermaid.core-DbTaQjFE.js} +5 -5
  105. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-5PTSkos6.js → mindmap-definition-FAOFIHXS-CroYl5xQ.js} +1 -1
  106. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DONIFpG5.js → pegDiagram-VL7TDLO6-DgMBx-9k.js} +1 -1
  107. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-D_Z4S70M.js → pieDiagram-7S7Q4E2Y-CyWDmbq1.js} +1 -1
  108. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-CAsjh8iY.js → quadrantDiagram-CIZ2JOQS-BgGEOqSP.js} +1 -1
  109. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Cx4Dd6ac.js → railroadDiagram-AXF67PYL-BMZ7oeeV.js} +1 -1
  110. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-cQb7mwyH.js → requirementDiagram-LRYGKXZP-DxqyGhcc.js} +1 -1
  111. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cd-DhUdf.js → sankeyDiagram-W5VNT64P-DnSvNCG8.js} +1 -1
  112. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-AlKYRgIk.js → sequenceDiagram-SI44F4Z6-BiZh6f-R.js} +1 -1
  113. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-CUy_ET4e.js → sizeCapture-X5ZJPWSS-BKXSI8WB.js} +1 -1
  114. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-CTuVe6Sa.js → stateDiagram-OKZ733FA-CfSgoYFm.js} +1 -1
  115. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DgHi3vjb.js +1 -0
  116. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-ChFLJb-v.js → swimlanes-SLNWSIFB-CyGADcHe.js} +2 -2
  117. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bgvdt1Y0.js +8 -0
  118. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-DZZeiAPr.js → timeline-definition-Z64GVDOM-HmPaSPOK.js} +1 -1
  119. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-t4O91cZU.js → vennDiagram-T6HMQDX7-VA2VBbez.js} +1 -1
  120. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CV5qGHZu.js → wardleyDiagram-T6FBY63Y-BxjiBPZa.js} +1 -1
  121. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-DyXbytUI.js → xychartDiagram-ELKLHX3M--hUY-qFj.js} +1 -1
  122. package/dist/worker/console/static/index.html +2 -2
  123. package/dist/worker/console/static/pets/ember/pet.json +167 -0
  124. package/dist/worker/console/static/pets/ember/spritesheet.png +0 -0
  125. package/dist/worker/console/static-src/operator-chat/details-rail-surfaces.js +4 -3
  126. package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +57 -9
  127. package/dist/worker/console/static-src/operator-chat/use-stat-dialog.js +95 -0
  128. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +6 -0
  129. package/dist/worker/console/workspace-context.js +15 -0
  130. package/dist/worker/console/workspace-initialization.js +25 -16
  131. package/dist/worker/delivery/package.js +4 -1
  132. package/dist/worker/materialize/harness-task-lineage.js +4 -2
  133. package/dist/worker/observe/static/console-theme.css +33 -29
  134. package/dist/worker/observe/static/operator-chrome.js +1 -42
  135. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +3 -1
  136. package/dist/workflows/dag/backend-test-layout.js +27 -7
  137. package/dist/workflows/dag/backend-test-markdown-workflow.js +3 -1
  138. package/dist/workflows/dag/backend-test-pytest-collection.js +4 -1
  139. package/dist/workflows/dag/final-verification.js +45 -10
  140. package/dist/workflows/dag/frontend-test-case-checklist.js +12 -3
  141. package/dist/workflows/dag/frontend-test-environment-probe.js +0 -2
  142. package/dist/workflows/dag/frontend-test-layout.js +41 -12
  143. package/dist/workflows/dag/hybrid/sources.js +35 -16
  144. package/dist/workflows/dag/hybrid/templates/backend-test.js +70 -55
  145. package/dist/workflows/dag/hybrid/templates/frontend-test.js +62 -41
  146. package/dist/workflows/dag/hybrid/templates/kg-bootstrap.js +6 -6
  147. package/dist/workflows/dag/hybrid/templates/knowledge-sync.js +5 -5
  148. package/dist/workflows/dag/skill-instructions.js +102 -32
  149. package/dist/workflows/dag/skill-snapshot.js +3 -0
  150. package/dist/workflows/dag/skills.js +7 -7
  151. package/dist/workflows/dag/test-artifact-namespace.js +73 -0
  152. package/dist/workflows/dag/validate.js +24 -5
  153. package/dist/workflows/dag/workspace-checkpoint.js +13 -1
  154. package/docs/architecture/runtime-boundaries.md +28 -22
  155. package/docs/init-surface.manifest.json +43 -295
  156. package/docs/templates/README.md +4 -4
  157. package/docs/templates/agent-dag.base.json +9 -9
  158. package/docs/templates/agent-dag.final-verification.json +6 -6
  159. package/docs/templates/agent-dag.supervised-implementation.json +12 -12
  160. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +3 -3
  161. package/docs/templates/backend-test-dag.json +708 -708
  162. package/docs/templates/backend-test-dag.review-cases.prompt.md +3 -3
  163. package/docs/templates/frontend-implementation-dag.json +2 -2
  164. package/docs/templates/frontend-test-case-checklist.md +2 -2
  165. package/docs/templates/frontend-test-dag.generate-cases.prompt.md +7 -7
  166. package/docs/templates/frontend-test-dag.json +48 -39
  167. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +2 -2
  168. package/docs/templates/frontend-test-dag.retrospect.prompt.md +1 -1
  169. package/docs/templates/frontend-test-dag.review-cases.prompt.md +1 -1
  170. package/docs/templates/hybrid-dag.json +9 -9
  171. package/docs/templates/knowledge-sync-dag.json +8 -8
  172. package/package.json +12 -3
  173. package/resource-catalog.v1.json +1973 -0
  174. package/resources/agent-bridge/loop-agent/SKILL.md +40 -0
  175. package/resources/init-history/legacy-surface.v1.json +33 -0
  176. package/skills/fe-test-ui-scout/SKILL.md +4 -4
  177. package/skills/fe-test-ui-scout/references/ledger-schema.md +1 -1
  178. package/skills/init-update/SKILL.md +34 -0
  179. package/skills/init-update/agents/openai.yaml +6 -0
  180. package/skills/playwright-cli/SKILL.md +1 -1
  181. package/skills/playwright-cli-case-generator/SKILL.md +4 -4
  182. package/dist/worker/console/static/assets/channel-CyBY_yGk.js +0 -1
  183. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-D5lN4E_E.js +0 -1
  184. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-D5lN4E_E.js +0 -1
  185. package/dist/worker/console/static/assets/index-B28Onmfy.css +0 -1
  186. package/dist/worker/console/static/assets/index-CTMZsDmh.js +0 -486
  187. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BsWhs8O7.js +0 -1
  188. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CJcioYGH.js +0 -8
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Repo preview kind routing — pure extension-name classification shared by
3
+ * `readRepoPreview` (server) so image/binary-container files never enter the
4
+ * UTF-8 text path.
5
+ *
6
+ * Mirrors the DSH `ui-sidebar-documentpreview` builtin split (image/index.ts
7
+ * + document/unviewable.ts) without importing its registry: loop-agent keeps
8
+ * a single JSON snapshot whose `kind` field selects the front-end branch.
9
+ */
10
+ /** Image suffixes rendered by an <img> preview (DSH IMAGE_EXTENSIONS). */
11
+ export const IMAGE_EXTENSIONS = [
12
+ "png",
13
+ "jpg",
14
+ "jpeg",
15
+ "gif",
16
+ "webp",
17
+ "bmp",
18
+ "ico",
19
+ "svg",
20
+ ];
21
+ /** Bitmap suffixes whose bytes are never read as text; SVG keeps its XML
22
+ * source readable (DSH BINARY_IMAGE_EXTENSIONS). */
23
+ export const BINARY_IMAGE_EXTENSIONS = [
24
+ "png",
25
+ "jpg",
26
+ "jpeg",
27
+ "gif",
28
+ "webp",
29
+ "bmp",
30
+ "ico",
31
+ ];
32
+ /** Known binary container suffixes with no renderer: these get the
33
+ * unsupported empty state instead of a text decode or a 415 toast
34
+ * (DSH UNVIEWABLE_BINARY_EXTENSIONS). `pdf` joins this list locally until
35
+ * the M4 PDF renderer lands; remove it there. */
36
+ export const UNVIEWABLE_BINARY_EXTENSIONS = [
37
+ // video
38
+ "mp4",
39
+ "mov",
40
+ "avi",
41
+ "mkv",
42
+ "webm",
43
+ "flv",
44
+ "wmv",
45
+ "m4v",
46
+ // audio
47
+ "mp3",
48
+ "wav",
49
+ "flac",
50
+ "ogg",
51
+ "m4a",
52
+ "aac",
53
+ "wma",
54
+ "opus",
55
+ // archives
56
+ "zip",
57
+ "gz",
58
+ "tgz",
59
+ "bz2",
60
+ "xz",
61
+ "zst",
62
+ "7z",
63
+ "rar",
64
+ "tar",
65
+ "jar",
66
+ // office documents — `key` stays out: it collides with readable key/credential text files
67
+ "doc",
68
+ "docx",
69
+ "xls",
70
+ "xlsx",
71
+ "ppt",
72
+ "pptx",
73
+ "odt",
74
+ "ods",
75
+ "odp",
76
+ "pages",
77
+ "numbers",
78
+ // executables and compiled objects
79
+ "exe",
80
+ "dll",
81
+ "so",
82
+ "dylib",
83
+ "bin",
84
+ "o",
85
+ "class",
86
+ "pyc",
87
+ "wasm",
88
+ // fonts
89
+ "ttf",
90
+ "otf",
91
+ "woff",
92
+ "woff2",
93
+ "eot",
94
+ // disk images and databases
95
+ "dmg",
96
+ "iso",
97
+ "img",
98
+ "sqlite",
99
+ "db",
100
+ // design documents and image formats without a renderer
101
+ "psd",
102
+ "ai",
103
+ "sketch",
104
+ "tiff",
105
+ "tif",
106
+ "heic",
107
+ "heif",
108
+ "avif",
109
+ // local addition: no PDF renderer yet (M4)
110
+ "pdf",
111
+ ];
112
+ const IMAGE_MEDIA_TYPES = {
113
+ png: "image/png",
114
+ jpg: "image/jpeg",
115
+ jpeg: "image/jpeg",
116
+ gif: "image/gif",
117
+ webp: "image/webp",
118
+ bmp: "image/bmp",
119
+ ico: "image/x-icon",
120
+ svg: "image/svg+xml",
121
+ };
122
+ const IMAGE_SUFFIX_SET = new Set(IMAGE_EXTENSIONS);
123
+ const UNVIEWABLE_SUFFIX_SET = new Set(UNVIEWABLE_BINARY_EXTENSIONS);
124
+ /** The lowercased final path segment (DSH documentFileName). */
125
+ export function documentFileName(path) {
126
+ const normalized = path.replaceAll("\\", "/").toLowerCase();
127
+ return normalized.slice(normalized.lastIndexOf("/") + 1);
128
+ }
129
+ /** The final dotted extension of a filename, without the leading dot.
130
+ * Empty for dotfiles like `.env` (no suffix before the dot) and names
131
+ * without any dot. */
132
+ export function fileSuffixOf(path) {
133
+ const name = documentFileName(path);
134
+ const dot = name.lastIndexOf(".");
135
+ if (dot <= 0)
136
+ return "";
137
+ return name.slice(dot + 1);
138
+ }
139
+ /** Classify a repo-relative path by its final extension: image renderers
140
+ * first, then the unviewable binary containers, everything else text. */
141
+ export function classifyRepoPreview(path) {
142
+ const suffix = fileSuffixOf(path);
143
+ if (IMAGE_SUFFIX_SET.has(suffix)) {
144
+ return { kind: "image", mediaType: IMAGE_MEDIA_TYPES[suffix] ?? "application/octet-stream" };
145
+ }
146
+ if (UNVIEWABLE_SUFFIX_SET.has(suffix)) {
147
+ return { kind: "unsupported" };
148
+ }
149
+ return { kind: "text" };
150
+ }
151
+ /** Whether an image path's bytes should never be offered as source text
152
+ * (bitmap). SVG keeps its preview/source dual mode. */
153
+ export function isBinaryImageExtension(path) {
154
+ return BINARY_IMAGE_EXTENSIONS.includes(fileSuffixOf(path));
155
+ }
@@ -47,6 +47,7 @@ import { classifyGoalRoundAdmission, } from "./goal-round-driver.js";
47
47
  import { isTerminalOperationState } from "../../../infrastructure/console/operation-store.js";
48
48
  import { SddDataAlignmentError, } from "./sdd-data-alignment.js";
49
49
  import { TerminalSessionRegistry } from "./terminal-sessions.js";
50
+ import { handlePetRequest } from "./pet/pet-routes.js";
50
51
  import { handleTerminalRequest } from "./terminal-routes.js";
51
52
  import { handleScmRequest } from "./scm-routes.js";
52
53
  import { handleBrowserRequest } from "./browser-routes.js";
@@ -983,14 +984,33 @@ export async function handleForkChatSession(req, res, deps, sourceSessionId) {
983
984
  const throughMessageId = typeof body.throughMessageId === "string" && body.throughMessageId.trim()
984
985
  ? body.throughMessageId.trim()
985
986
  : undefined;
986
- const throughUserMessageIndex = throughMessageId
987
- ? source.messages
988
- .filter((message) => message.role === "user")
989
- .findIndex((message) => message.id === throughMessageId)
990
- : undefined;
991
- if (throughMessageId && throughUserMessageIndex === -1) {
987
+ // Accept a user or assistant message as the fork anchor. An assistant
988
+ // anchor resolves to the user message of its own turn so the runtime
989
+ // branch and the persisted copy both truncate at the same Q&A pair.
990
+ const anchorIndex = throughMessageId
991
+ ? source.messages.findIndex((message) => message.id === throughMessageId)
992
+ : -1;
993
+ if (throughMessageId && anchorIndex < 0) {
992
994
  throw new Error("FORK_MESSAGE_NOT_FOUND");
993
995
  }
996
+ const throughUserMessageIndex = throughMessageId
997
+ ? (() => {
998
+ const boundary = anchorIndex >= 0 && source.messages[anchorIndex]?.role === "assistant"
999
+ ? (() => {
1000
+ let index = anchorIndex;
1001
+ while (index >= 0 && source.messages[index]?.role !== "user") {
1002
+ index -= 1;
1003
+ }
1004
+ return index;
1005
+ })()
1006
+ : anchorIndex;
1007
+ if (boundary < 0)
1008
+ throw new Error("FORK_MESSAGE_TURN_USER_NOT_FOUND");
1009
+ return source.messages
1010
+ .slice(0, boundary + 1)
1011
+ .filter((message) => message.role === "user").length - 1;
1012
+ })()
1013
+ : undefined;
994
1014
  const handle = await deps.runtime.forkSession({
995
1015
  sourceSessionFile: source.sessionFile ?? "",
996
1016
  sessionMode: source.sessionMode,
@@ -4692,8 +4712,24 @@ async function dispatchChatRequest(req, res, deps, pathname, workspaceScope) {
4692
4712
  }, pathname)) {
4693
4713
  return true;
4694
4714
  }
4715
+ // Operator pet (dsh-pet port): state/interact API + atlas media.
4716
+ if (pathname.startsWith("/api/operator/v1/pet/") &&
4717
+ (req.method ?? "GET").toUpperCase() !== "GET") {
4718
+ const gate = gateMutation(req, deps);
4719
+ if (!gate.ok) {
4720
+ sendJson(res, gate.status, {
4721
+ ok: false,
4722
+ error: { code: gate.code, message: gate.message },
4723
+ });
4724
+ return true;
4725
+ }
4726
+ }
4727
+ if (await handlePetRequest(req, res, pathname, deps.pet)) {
4728
+ return true;
4729
+ }
4695
4730
  if (!pathname.startsWith("/api/operator/v1/chat/") &&
4696
- !pathname.startsWith("/api/operator/v1/pi/"))
4731
+ !pathname.startsWith("/api/operator/v1/pi/") &&
4732
+ !pathname.startsWith("/api/operator/v1/pet/"))
4697
4733
  return false;
4698
4734
  const method = (req.method ?? "GET").toUpperCase();
4699
4735
  const url = new URL(req.url ?? "/", "http://localhost");
@@ -12,6 +12,14 @@ import { captureScheduledGoalTree } from "../../scheduler/scheduled-goal-evidenc
12
12
  import { getScheduledGoalBooking, prepareScheduledGoalBooking } from "./scheduled-goal-booking.js";
13
13
  const execFileAsync = promisify(execFile);
14
14
  const protectedPaths = [".harness/**", "node_modules/**", ".git/**"];
15
+ /** Omit-default for natural-language bookings: five DAG attempts with four supervisor continues. */
16
+ export const SCHEDULED_TASK_DEFAULT_BUDGET = {
17
+ maxTurns: 5,
18
+ maxDagRuns: 5,
19
+ maxSupervisorCalls: 4,
20
+ };
21
+ export const SCHEDULED_TASK_DEFAULT_START_GRACE_MINUTES = 15;
22
+ export const SCHEDULED_TASK_DEFAULT_MAX_DURATION_MINUTES = 240;
15
23
  const relativePath = z.string().trim().min(1).max(500).refine((value) => !path.isAbsolute(value) && !/^[A-Za-z]:/.test(value) && !value.includes("\\") &&
16
24
  !value.split("/").some((part) => part === ".." || part === "." || part === "") && !value.startsWith("-"), "use a relative repository path without traversal");
17
25
  const scheduleSchema = z.object({
@@ -20,8 +28,8 @@ const scheduleSchema = z.object({
20
28
  timezone: z.string().min(1).optional().describe("IANA timezone, e.g. Asia/Shanghai for Beijing. Defaults to the Console host timezone."),
21
29
  fold: z.enum(["earlier", "later"]).optional(),
22
30
  allowedHours: z.array(z.string()).optional().describe("Local allowed windows; default [] means all day."),
23
- startGraceMinutes: z.number().positive().max(1440).optional(),
24
- maxDurationMinutes: z.number().positive().max(1440).optional(),
31
+ startGraceMinutes: z.number().positive().max(1440).optional().describe(`Latest-start grace after executeAt; omit for ${SCHEDULED_TASK_DEFAULT_START_GRACE_MINUTES} minutes.`),
32
+ maxDurationMinutes: z.number().positive().max(1440).optional().describe(`Authorized execution window after latestStart; omit for ${SCHEDULED_TASK_DEFAULT_MAX_DURATION_MINUTES} minutes so later DAG attempts can finish.`),
25
33
  }).strict().refine((value) => (value.delayMinutes !== undefined) !== (value.localAt !== undefined), "choose exactly one of delayMinutes or localAt");
26
34
  /** The model supplies business meaning, never runtime identity or authorization. */
27
35
  export const scheduledTaskRequestSchema = z.object({
@@ -30,7 +38,7 @@ export const scheduledTaskRequestSchema = z.object({
30
38
  allowedPaths: z.array(relativePath).min(1).max(100).describe("Business outputs in the CURRENT project directory. For a read-only inspection, allow only a report such as scheduled-report.md, never .harness/."),
31
39
  forbiddenPaths: z.array(relativePath).max(100).optional(),
32
40
  acceptance: scheduledGoalDraftSchema.shape.acceptance.describe("Use minimal independent executable checks with AC-1, AC-2 IDs. Each command must exit nonzero on failure. For backend-test, acceptance must only inspect the finished run and must never invoke pytest. Prefer an existing read-only verification command or test -s report.md. Do not invent extra requirements, language-specific grep checks, shell pipelines, command substitution, redirects or compound shell statements. The host already enforces write scope."),
33
- budget: scheduledGoalDraftSchema.shape.budget.optional().describe("Omit for ordinary tasks: defaults to one DAG run, one goal attempt and one supervisor call. maxTurns counts goal attempts, NOT model tool calls; maxSupervisorCalls does NOT count polling. Always displayed before confirmation."),
41
+ budget: scheduledGoalDraftSchema.shape.budget.optional().describe(`Omit for ordinary tasks: defaults to ${SCHEDULED_TASK_DEFAULT_BUDGET.maxTurns} goal attempts, ${SCHEDULED_TASK_DEFAULT_BUDGET.maxDagRuns} DAG runs and ${SCHEDULED_TASK_DEFAULT_BUDGET.maxSupervisorCalls} supervisor calls. maxTurns counts goal attempts, NOT model tool calls; maxSupervisorCalls does NOT count polling. Explicit values are never raised. Always displayed before confirmation.`),
34
42
  schedule: scheduleSchema,
35
43
  }).strict();
36
44
  export function resolveScheduledTaskTime(input, now) {
@@ -41,8 +49,8 @@ export function resolveScheduledTaskTime(input, now) {
41
49
  : new Date(now.getTime() + schedule.delayMinutes * 60000).toISOString();
42
50
  if (Date.parse(executeAtUtc) <= now.getTime())
43
51
  throw new Error("requested time is in the past; provide a new future time (不会自动顺延)");
44
- const latestStart = Date.parse(executeAtUtc) + (schedule.startGraceMinutes ?? 15) * 60000;
45
- const stop = latestStart + (schedule.maxDurationMinutes ?? 60) * 60000;
52
+ const latestStart = Date.parse(executeAtUtc) + (schedule.startGraceMinutes ?? SCHEDULED_TASK_DEFAULT_START_GRACE_MINUTES) * 60000;
53
+ const stop = latestStart + (schedule.maxDurationMinutes ?? SCHEDULED_TASK_DEFAULT_MAX_DURATION_MINUTES) * 60000;
46
54
  return scheduledGoalTimeSchema.parse({ executeAtUtc, latestStartUtc: new Date(latestStart).toISOString(),
47
55
  stopAtUtc: new Date(stop).toISOString(), expiresAt: new Date(stop).toISOString(), timezone,
48
56
  allowedHours: schedule.allowedHours ?? [], misfirePolicy: "run-immediately" });
@@ -170,7 +178,7 @@ export async function prepareScheduledTask(input, deps) {
170
178
  const booking = await prepareScheduledGoalBooking({ managedTaskId: record.taskId, originalGoal: request.originalGoal,
171
179
  chatSessionRef: deps.sessionId, workflow: request.workflow, worktreeRef: record.worktree, frozenBase: base,
172
180
  allowedPaths: config.allowedPaths, forbiddenPaths: config.forbiddenPaths, acceptance: request.acceptance,
173
- budget: request.budget ?? { maxTurns: 1, maxDagRuns: 1, maxSupervisorCalls: 1 }, time: resolveScheduledTaskTime(request.schedule, now()),
181
+ budget: request.budget ?? { ...SCHEDULED_TASK_DEFAULT_BUDGET }, time: resolveScheduledTaskTime(request.schedule, now()),
174
182
  }, { goals, client: deps.client, sessions: deps.sessions }, () => resolveScheduledTaskTime(request.schedule, now()));
175
183
  record.goalId = booking.goalId;
176
184
  record.stage = "planned";
@@ -74,7 +74,7 @@ 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
- "Browser tools (navigate/search/snapshot/act/tabs/scroll/press/dialog/wait/screenshot) drive the workspace-controlled real browser shown in the Browser panel. Use refs from the latest page inspection for element actions; they never edit workspace files or execute page scripts. browser_snapshot means browser page inspection, not workspace snapshots.",
77
+ "Browser tools control the workspace-controlled real browser in an external window; the sidebar iframe is independent. Use tabId/snapshotId from the latest snapshot/find/pick for ref actions, condition waits and screenshots to verify results. browser_eval executes page JavaScript; cookies/storage tools exchange login state through app-data files. browser_snapshot inspects the page, not workspace files.",
78
78
  "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.",
79
79
  "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.",
80
80
  "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.",
@@ -10,6 +10,7 @@
10
10
  * The dispatcher is the SINGLE place where a Chat tool invocation becomes an
11
11
  * operator action call. Every invocation is re-authorized here.
12
12
  */
13
+ import { omitBrowserImageData } from "./browser-screenshot-result.js";
13
14
  import path from "node:path";
14
15
  import { randomUUID } from "node:crypto";
15
16
  import { copyFile, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
@@ -214,12 +215,29 @@ export class ChatSessionStore {
214
215
  const source = await this.get(input.sourceSessionId);
215
216
  if (!source)
216
217
  throw new Error(`chat session not found: ${input.sourceSessionId}`);
217
- const throughIndex = input.throughMessageId
218
- ? source.messages.findIndex((message) => message.id === input.throughMessageId && message.role === "user")
218
+ // The fork anchor may be a user message or an assistant message. A user
219
+ // anchor truncates at itself; an assistant anchor resolves to the user
220
+ // message of its own turn so the complete Q&A pair carries into the fork.
221
+ const anchorIndex = input.throughMessageId
222
+ ? source.messages.findIndex((message) => message.id === input.throughMessageId)
219
223
  : -1;
220
- if (input.throughMessageId && throughIndex < 0) {
224
+ if (input.throughMessageId && anchorIndex < 0) {
221
225
  throw new Error("FORK_MESSAGE_NOT_FOUND");
222
226
  }
227
+ let throughIndex = anchorIndex;
228
+ if (anchorIndex >= 0 && source.messages[anchorIndex]?.role === "assistant") {
229
+ // Keep the complete Q&A pair: truncate at the assistant answer
230
+ // itself. The turn's user message must exist directly before the
231
+ // answer chain (same rule the route uses for the runtime branch),
232
+ // otherwise the persisted copy and the runtime branch would
233
+ // truncate at different turns.
234
+ for (let index = anchorIndex; index >= 0; index -= 1) {
235
+ if (source.messages[index]?.role === "user")
236
+ break;
237
+ if (index === 0)
238
+ throw new Error("FORK_MESSAGE_TURN_USER_NOT_FOUND");
239
+ }
240
+ }
223
241
  return this.serialize(input.targetSessionId, async () => {
224
242
  const now = new Date().toISOString();
225
243
  const record = {
@@ -830,7 +848,8 @@ export async function runChatTurn(options) {
830
848
  operationId: acceptedOperationId,
831
849
  })));
832
850
  }
833
- const resultText = safeStringifyResult(event.result);
851
+ const resultRecord = event.result && typeof event.result === "object" ? event.result : undefined;
852
+ const resultText = safeStringifyResult(event.toolName === "browser_screenshot" && resultRecord?.details ? resultRecord.details : event.result);
834
853
  pending.push(store.appendMessage(sessionId, {
835
854
  role: "tool",
836
855
  text: resultText,
@@ -926,7 +945,7 @@ export function acceptedOperationIdFromResult(toolName, result) {
926
945
  }
927
946
  function safeStringifyResult(result) {
928
947
  try {
929
- const raw = JSON.stringify(result ?? {});
948
+ const raw = JSON.stringify(result ?? {}, omitBrowserImageData);
930
949
  const { scrubbed } = scrubSecrets(raw);
931
950
  return scrubbed.length > 4000 ? `${scrubbed.slice(0, 4000)}…[truncated]` : scrubbed;
932
951
  }
@@ -68,6 +68,18 @@ export const OPERATOR_CHAT_BUILTIN_CUSTOM_TOOLS = Object.freeze([
68
68
  "browser_dialog",
69
69
  "browser_wait",
70
70
  "browser_screenshot",
71
+ "browser_reload",
72
+ "browser_back",
73
+ "browser_forward",
74
+ "browser_eval",
75
+ "browser_cookies",
76
+ "browser_storage_export",
77
+ "browser_storage_import",
78
+ "browser_find",
79
+ "browser_content",
80
+ "browser_pick",
81
+ "browser_console",
82
+ "browser_network",
71
83
  ...OPERATOR_CHAT_SQL_TOOL_CAPABILITIES.map((tool) => tool.toolId),
72
84
  ]);
73
85
  /**
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Console process lifetime: first SIGINT/SIGTERM starts graceful close;
3
+ * a second signal or a close timeout force-exits so a blocked event loop
4
+ * (e.g. a giant synchronous JSON.stringify) cannot swallow Ctrl+C forever.
5
+ */
6
+ export const CONSOLE_CLOSE_TIMEOUT_MS = 2_000;
7
+ /**
8
+ * Block until the first interrupt, then close. A second SIGINT/SIGTERM (or
9
+ * close hanging past `timeoutMs`) calls `exit` with 130/143.
10
+ */
11
+ export async function holdConsoleUntilSignal(hooks) {
12
+ const proc = hooks.proc ?? process;
13
+ const timeoutMs = hooks.timeoutMs ?? CONSOLE_CLOSE_TIMEOUT_MS;
14
+ const exit = hooks.exit ?? ((code) => process.exit(code));
15
+ let closing = false;
16
+ await new Promise((resolve) => {
17
+ const onSignal = (signal) => {
18
+ const code = signal === "SIGINT" ? 130 : 143;
19
+ if (closing) {
20
+ exit(code);
21
+ return;
22
+ }
23
+ closing = true;
24
+ const timer = setTimeout(() => exit(code), timeoutMs);
25
+ timer.unref?.();
26
+ void hooks.close().finally(() => {
27
+ clearTimeout(timer);
28
+ resolve();
29
+ });
30
+ };
31
+ proc.on("SIGINT", () => onSignal("SIGINT"));
32
+ proc.on("SIGTERM", () => onSignal("SIGTERM"));
33
+ });
34
+ }
@@ -360,7 +360,8 @@ export async function createConsoleServer(options) {
360
360
  return;
361
361
  }
362
362
  if (pathname.startsWith("/api/operator/v1/chat/") ||
363
- pathname.startsWith("/api/operator/v1/pi/")) {
363
+ pathname.startsWith("/api/operator/v1/pi/") ||
364
+ pathname.startsWith("/api/operator/v1/pet/")) {
364
365
  await handleChatDispatch(req, res, pathname, url, method);
365
366
  return;
366
367
  }
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-DfzjRD5y.js";import{p as f}from"./chunk-JWPE2WC7-C3sQMMYr.js";import{_ as n,l as o}from"./mermaid.core-4P9yPC9c.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-DktIuDWs.js";import"./index-CTMZsDmh.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-BK6RFy58.js";import{p as f}from"./chunk-JWPE2WC7-ChPS5WzG.js";import{_ as n,l as o}from"./mermaid.core-DbTaQjFE.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-Contvx58.js";import"./index-B_5GhVIO.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-4P9yPC9c.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-DbTaQjFE.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};