@tea-agent/loop-agent 0.40.0-next.3 → 0.40.0-next.5

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 (139) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/build-stamp.json +3 -3
  3. package/dist/executors/dag-pi-executor.js +46 -5
  4. package/dist/executors/shell-executor.js +28 -0
  5. package/dist/executors/workspace-write-snapshot.js +68 -0
  6. package/dist/infrastructure/harness/atomic-write.js +23 -0
  7. package/dist/task/config-types.js +10 -0
  8. package/dist/worker/console/chat/chat-event-store.js +62 -4
  9. package/dist/worker/console/chat/context-panel.js +7 -0
  10. package/dist/worker/console/chat/deferred-turn.js +12 -0
  11. package/dist/worker/console/chat/pi-runtime.js +264 -16
  12. package/dist/worker/console/chat/provider-error.js +98 -0
  13. package/dist/worker/console/chat/routes.js +292 -29
  14. package/dist/worker/console/chat/session-stats.js +179 -0
  15. package/dist/worker/console/chat/session-store.js +93 -63
  16. package/dist/worker/console/chat/todos.js +115 -0
  17. package/dist/worker/console/chat/tool-preview.js +42 -0
  18. package/dist/worker/console/chat/turn-process.js +20 -55
  19. package/dist/worker/console/chat/user-questions.js +266 -0
  20. package/dist/worker/console/chat/workspace-landing.js +14 -0
  21. package/dist/worker/console/native-directory-picker.js +13 -0
  22. package/dist/worker/console/routes.js +309 -1
  23. package/dist/worker/console/security.js +4 -4
  24. package/dist/worker/console/server.js +529 -186
  25. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-CTx1TrNa.js → abnfDiagram-N423BO3Z-CGZrpj0K.js} +1 -1
  26. package/dist/worker/console/static/assets/{arc-B4i9cVxX.js → arc-CwEyA8iq.js} +1 -1
  27. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-BAXE8_Rl.js → architectureDiagram-T3A2C74G-DLTkrEQ3.js} +1 -1
  28. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-C5Xh59at.js → blockDiagram-VBNYF7ZC-4w12zR3t.js} +1 -1
  29. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-B_asOzAu.js → c4Diagram-5PPSVZJV-BppqLAjk.js} +1 -1
  30. package/dist/worker/console/static/assets/channel-TzuwQha5.js +1 -0
  31. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-wRO_iRNc.js → chunk-2GRJ4B5K-DO6U26Pm.js} +1 -1
  32. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-ByOaSh_G.js → chunk-2Q5K7J3B-DC7YEdOy.js} +1 -1
  33. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DjLzudan.js → chunk-5RXB4S5H-DtMYVQBw.js} +1 -1
  34. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-JCNGkXYT.js → chunk-5VM5RSS4-C5Ed-57N.js} +1 -1
  35. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BhrPXXMZ.js → chunk-6Q2QTUOP-BUY4oIzT.js} +1 -1
  36. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-TJ5JuEBT.js → chunk-GF5L2VYU-VnWHALIV.js} +1 -1
  37. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-VVthn_mD.js → chunk-JWPE2WC7-COV-RQk4.js} +1 -1
  38. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-D60-Mny4.js → chunk-KBJHAD2P-dSnLtUiz.js} +1 -1
  39. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-zXv7aVye.js → chunk-RYQCIY6F-CX6FDzWh.js} +1 -1
  40. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-By9VQoi1.js → chunk-XXDRQBXY-D3mEgb6W.js} +1 -1
  41. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DCu69b3S.js +1 -0
  42. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DCu69b3S.js +1 -0
  43. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-C4zQLe-M.js → cose-bilkent-JH36ORCC-QQBMUnAf.js} +1 -1
  44. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-wh5N2ReN.js → cynefin-VYW2F7L2-BxSD-LVV.js} +1 -1
  45. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Dlu5wIqs.js → cynefinDiagram-MW4NZA55-DxHNiNbk.js} +1 -1
  46. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-CrDgthc6.js → dagre-VZM6K2ZE-C83bYy8E.js} +1 -1
  47. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-zN1clg27.js → diagram-7IWD3JNH-BhtZu2YY.js} +1 -1
  48. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BN-o7J7-.js → diagram-B4RE2ZJO-K0P_ntRE.js} +1 -1
  49. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-C8SuPt0d.js → diagram-LBJQPF4R-CXYy1Nib.js} +1 -1
  50. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BoizuHbZ.js → diagram-Q27KOJAE-D-CtIFkU.js} +1 -1
  51. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BzUzXixG.js → diagram-UB23O5K3-BEK9-_7c.js} +1 -1
  52. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Ev3lA4Cf.js → ebnfDiagram-BXEA7PRR-L0EX-9wn.js} +1 -1
  53. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-GALUzRbs.js → erDiagram-JOGREHBK-9pt0fc_5.js} +1 -1
  54. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CZJN65Sb.js → flowDiagram-UKHOOZJN-CZVeM_n1.js} +1 -1
  55. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-JLB9OESl.js → ganttDiagram-PKOTCBZU-DqUKkAZP.js} +1 -1
  56. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-CcvCr4GD.js → gitGraphDiagram-DS77QQ5N-BYUuXEgp.js} +1 -1
  57. package/dist/worker/console/static/assets/index-B0jGzQj6.js +407 -0
  58. package/dist/worker/console/static/assets/index-BiYbPiTw.css +1 -0
  59. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-HG5z7aVg.js → infoDiagram-6WML65LV-DNzKk7ah.js} +1 -1
  60. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BHEu9chR.js → ishikawaDiagram-WSZJBQD7-Clbyg5IP.js} +1 -1
  61. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-Cp_Up8-a.js → journeyDiagram-NVQOT4AX-zDO_gZNO.js} +1 -1
  62. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-DvVeY-em.js → kanban-definition-27J2QSJJ-x3LpRYek.js} +1 -1
  63. package/dist/worker/console/static/assets/{linear-aGmcjgTn.js → linear-CTpwZqKR.js} +1 -1
  64. package/dist/worker/console/static/assets/{mermaid.core-Biyo-tqA.js → mermaid.core-D_WXK6C7.js} +5 -5
  65. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-DyxY2pIb.js → mindmap-definition-FAOFIHXS-CWK-OYP5.js} +1 -1
  66. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CkdGuc50.js → pegDiagram-VL7TDLO6-B9gtUPsM.js} +1 -1
  67. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-NNQI9xVR.js → pieDiagram-7S7Q4E2Y-Dj2lzceR.js} +1 -1
  68. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-PAJkuz_G.js → quadrantDiagram-CIZ2JOQS-Nwljut7m.js} +1 -1
  69. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-ZwrQod0O.js → railroadDiagram-AXF67PYL-BY-KNt93.js} +1 -1
  70. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D3ZfrzM2.js → requirementDiagram-LRYGKXZP-Vx0wvpPy.js} +1 -1
  71. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DDGFmWk5.js → sankeyDiagram-W5VNT64P-B6grNXUk.js} +1 -1
  72. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DO6mmXTA.js → sequenceDiagram-SI44F4Z6-CteidBvh.js} +1 -1
  73. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DMbCQiJt.js → sizeCapture-X5ZJPWSS-Du4W8mFK.js} +1 -1
  74. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-Di_YUEfC.js → stateDiagram-OKZ733FA-jyI6Yh81.js} +1 -1
  75. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyQblISl.js +1 -0
  76. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-Bn2PphNJ.js → swimlanes-SLNWSIFB-DYWs_fRv.js} +2 -2
  77. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DiygmgYP.js +8 -0
  78. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-DPh8pRsp.js → timeline-definition-Z64GVDOM-DO5LLy47.js} +1 -1
  79. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-GMfl26pW.js → vennDiagram-T6HMQDX7-CLF2p1_L.js} +1 -1
  80. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-DTlmVrmF.js → wardleyDiagram-T6FBY63Y-AwTaYBxA.js} +1 -1
  81. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-YGBjKAS5.js → xychartDiagram-ELKLHX3M-DzbblQRw.js} +1 -1
  82. package/dist/worker/console/static/index.html +2 -2
  83. package/dist/worker/console/static-src/app/console-types.js +29 -4
  84. package/dist/worker/console/static-src/app/useConsoleShell.js +30 -12
  85. package/dist/worker/console/static-src/app/useOperatorActions.js +36 -6
  86. package/dist/worker/console/static-src/app/useRecoveryConsole.js +10 -11
  87. package/dist/worker/console/static-src/app/useRunProgress.js +2 -1
  88. package/dist/worker/console/static-src/app/useTaskWizard.js +2 -2
  89. package/dist/worker/console/static-src/night/useNightBoard.js +8 -5
  90. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +140 -8
  91. package/dist/worker/console/static-src/operator-chat/details-dag-actions.js +122 -0
  92. package/dist/worker/console/static-src/operator-chat/refs.js +3 -0
  93. package/dist/worker/console/static-src/operator-chat/runtime-selection-labels.js +27 -0
  94. package/dist/worker/console/static-src/operator-chat/turn-submission.js +3 -2
  95. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +168 -72
  96. package/dist/worker/console/static-src/operator-chat/useChatStream.js +78 -17
  97. package/dist/worker/console/static-src/operator-chat/useChatThread.js +184 -4
  98. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +63 -9
  99. package/dist/worker/console/static-src/operator-chat/useWorkspaceBrowserGate.js +4 -0
  100. package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +3 -3
  101. package/dist/worker/console/static-src/shell/useWorkspaces.js +299 -0
  102. package/dist/worker/console/static-src/shell/workspace-route.js +337 -0
  103. package/dist/worker/console/workspace-context.js +234 -0
  104. package/dist/worker/console/workspace-registry.js +214 -0
  105. package/dist/worker/observe/server.js +4 -0
  106. package/dist/worker/observe/static/api.js +26 -6
  107. package/dist/worker/observe/static/app.js +18 -70
  108. package/dist/worker/observe/static/index.html +1 -1
  109. package/dist/worker/observe/static/inspect-workspace.js +307 -0
  110. package/dist/worker/observe/static/operator-chrome.css +145 -20
  111. package/dist/worker/observe/static/operator-chrome.d.ts +20 -3
  112. package/dist/worker/observe/static/operator-chrome.js +330 -100
  113. package/dist/worker/observe/static/router.d.ts +46 -0
  114. package/dist/worker/observe/static/router.js +25 -1
  115. package/dist/worker/observe/static/state.d.ts +50 -0
  116. package/dist/worker/observe/static/state.js +172 -0
  117. package/dist/worker/observe/static/styles.css +20 -1
  118. package/dist/worker/observe/static/views/dag-inspector.js +4 -3
  119. package/dist/worker/observe/static/views/dag.js +2 -1
  120. package/dist/worker/observe/static/views/dashboard.js +6 -4
  121. package/dist/worker/observe/static/views/night.js +2 -2
  122. package/dist/worker/observe/static/views/pool.js +1 -0
  123. package/dist/worker/observe/static/views/run.js +3 -1
  124. package/dist/worker/observe/static/views/task.js +1 -1
  125. package/dist/workflows/dag/init-hybrid.js +19 -0
  126. package/dist/workflows/dag/interrupt-request.js +3 -3
  127. package/dist/workflows/dag/lifecycle.js +3 -3
  128. package/dist/workflows/dag/types.js +3 -1
  129. package/docs/README.md +1 -0
  130. package/docs/operations/local-development-environment.md +21 -0
  131. package/harness.json +3 -3
  132. package/package.json +3 -1
  133. package/dist/worker/console/static/assets/channel-Dj_4Moei.js +0 -1
  134. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C0YYAyCa.js +0 -1
  135. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C0YYAyCa.js +0 -1
  136. package/dist/worker/console/static/assets/index-CW88Fjbw.js +0 -406
  137. package/dist/worker/console/static/assets/index-DP0ZJl39.css +0 -1
  138. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DrdDvela.js +0 -1
  139. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DPkEAULl.js +0 -8
@@ -0,0 +1,50 @@
1
+ /** 与 state.js 对应的类型声明(供 vitest/TS 侧导入契约测试)。 */
2
+
3
+ export type ViewStateKind = "loading" | "empty" | "degraded" | "error";
4
+
5
+ export type ViewStateDescriptor = {
6
+ kind: ViewStateKind;
7
+ className: string;
8
+ role: string | null;
9
+ ariaLive: string | null;
10
+ message: string;
11
+ detail: string | null;
12
+ messageClass: string | null;
13
+ };
14
+
15
+ export const uiState: {
16
+ lastSnapshot: unknown;
17
+ specEvidenceDetail: {
18
+ source: string;
19
+ path: string;
20
+ loading: boolean;
21
+ error: string | null;
22
+ data: unknown;
23
+ triggerId: string | null;
24
+ } | null;
25
+ dagNodeExecutionOutputCache: Map<string, unknown> | null;
26
+ [key: string]: unknown;
27
+ };
28
+
29
+ export function setWorkspaceScope(workspaceId: string | null): void;
30
+ export function workspaceScope(): string | null;
31
+ export function scopedApiUrl(url: string): string;
32
+ export function workspaceRequestSignal(): AbortSignal | undefined;
33
+ export function fetchWithWorkspaceScope(
34
+ url: string,
35
+ init?: RequestInit,
36
+ ): Promise<Response>;
37
+ export function abortWorkspaceRequests(): void;
38
+ export function setWorkspaceActive(active: boolean): void;
39
+ export function stopTimers(): void;
40
+ export function pauseForegroundTimers(): void;
41
+
42
+ /** Multi-workspace atomic scope switch (2026-08-26, AC-006). */
43
+ export function applyWorkspaceScopeSwitch(
44
+ nextWorkspaceId: string | null,
45
+ routeValue?: (() => void) | string,
46
+ options?: {
47
+ route?: (hashValue: string) => void;
48
+ onTrace?: (trace: string[]) => void;
49
+ },
50
+ ): string[];
@@ -116,6 +116,8 @@ export const uiState = {
116
116
  /** Last-rendered spec-evidence list, used to restore the list synchronously. */
117
117
  specEvidenceListEvidence: null,
118
118
  pollingGeneration: 0,
119
+ /** Hosted Inspect workspace is foreground. Standalone defaults to active. */
120
+ workspaceActive: true,
119
121
  };
120
122
 
121
123
  /** Per-dagRunId graph viewport restore map (stable Map instance). */
@@ -279,16 +281,186 @@ export function isPageVisible() {
279
281
  );
280
282
  }
281
283
 
284
+ export function isWorkspaceActive() {
285
+ return uiState.workspaceActive !== false;
286
+ }
287
+
288
+ export function setWorkspaceActive(active) {
289
+ uiState.workspaceActive = Boolean(active);
290
+ }
291
+
292
+ /**
293
+ * Multi-workspace scope (2026-08-23): every Observe GET must carry the
294
+ * current workspaceId (AC-002/AC-003). The scope is synced from the parent
295
+ * Console shell hash (`?workspaceId=`) or via postMessage for hosted mode;
296
+ * standalone pages default to null and all workspace-scoped routes fail closed
297
+ * until the host or hash publishes an explicit workspace id.
298
+ */
299
+ let currentWorkspaceScope = null;
300
+ let currentWorkspaceRequestController =
301
+ typeof AbortController === "undefined" ? null : new AbortController();
302
+
303
+ export function setWorkspaceScope(workspaceId) {
304
+ currentWorkspaceScope =
305
+ typeof workspaceId === "string" && workspaceId.trim()
306
+ ? workspaceId.trim()
307
+ : null;
308
+ }
309
+
310
+ export function workspaceScope() {
311
+ return currentWorkspaceScope;
312
+ }
313
+
314
+ /** Signal shared by every workspace-scoped Observe request in the active scope. */
315
+ export function workspaceRequestSignal() {
316
+ if (
317
+ typeof AbortController !== "undefined" &&
318
+ (!currentWorkspaceRequestController ||
319
+ currentWorkspaceRequestController.signal.aborted)
320
+ ) {
321
+ currentWorkspaceRequestController = new AbortController();
322
+ }
323
+ return currentWorkspaceRequestController?.signal;
324
+ }
325
+
326
+ function combinedRequestSignal(scopeSignal, requestSignal) {
327
+ const signals = [scopeSignal, requestSignal].filter(Boolean);
328
+ if (signals.length <= 1) return { signal: signals[0], cleanup: () => {} };
329
+ const controller = new AbortController();
330
+ const abort = () => controller.abort();
331
+ for (const signal of signals) {
332
+ if (signal.aborted) abort();
333
+ else signal.addEventListener("abort", abort, { once: true });
334
+ }
335
+ return {
336
+ signal: controller.signal,
337
+ cleanup: () => {
338
+ for (const signal of signals) signal.removeEventListener("abort", abort);
339
+ },
340
+ };
341
+ }
342
+
343
+ /** Fetch through the current workspace boundary and abort on any scope swap. */
344
+ export async function fetchWithWorkspaceScope(url, init = {}) {
345
+ const { signal: requestSignal, ...rest } = init;
346
+ const combined = combinedRequestSignal(
347
+ workspaceRequestSignal(),
348
+ requestSignal,
349
+ );
350
+ try {
351
+ return await fetch(scopedApiUrl(url), {
352
+ ...rest,
353
+ ...(combined.signal ? { signal: combined.signal } : {}),
354
+ });
355
+ } finally {
356
+ combined.cleanup();
357
+ }
358
+ }
359
+
360
+ /** Abort every old-scope request and invalidate request identity guards. */
361
+ export function abortWorkspaceRequests() {
362
+ currentWorkspaceRequestController?.abort();
363
+ currentWorkspaceRequestController =
364
+ typeof AbortController === "undefined" ? null : new AbortController();
365
+ uiState.dagHistoryAbortController?.abort?.();
366
+ uiState.dagHistoryAbortController = null;
367
+ uiState.dagHistoryRequestSeq += 1;
368
+ uiState.dagHistoryPrefetchGeneration += 1;
369
+ uiState.dagNodeInputRequestSeq += 1;
370
+ uiState.dagNodeProcessRequestSeq += 1;
371
+ uiState.dagNodeExecutionOutputRequestSeq += 1;
372
+ }
373
+
374
+ /** Multi-workspace atomic scope switch (2026-08-26, AC-006).
375
+ *
376
+ * Contract order — strictly sequential, no interleaving:
377
+ * 1. abort old — stop every poll/SSE so no late request can race the swap;
378
+ * 2. clear old — drop cached run/task/selection state of the old scope;
379
+ * 3. set scope — publish the new workspaceId for scopedApiUrl;
380
+ * 4. reload new — re-route/re-render with the new scope active.
381
+ *
382
+ * Observability: each stage appends to the returned trace so tests (and
383
+ * diagnostics) can assert the exact ordering; there is no window in which a
384
+ * new route is requested with the old scope or vice versa.
385
+ */
386
+ export function applyWorkspaceScopeSwitch(
387
+ nextWorkspaceId,
388
+ routeValue,
389
+ options = {},
390
+ ) {
391
+ const trace = [];
392
+ // 1. abort old
393
+ abortWorkspaceRequests();
394
+ stopTimers();
395
+ pauseForegroundTimers();
396
+ trace.push("abort-old");
397
+ // 2. clear old
398
+ uiState.lastSnapshot = null;
399
+ uiState.specEvidenceDetail = null;
400
+ uiState.specEvidenceListEvidence = null;
401
+ clearDagNodeExecutionOutputCache();
402
+ trace.push("clear-old");
403
+ // 3. set scope
404
+ setWorkspaceScope(nextWorkspaceId);
405
+ trace.push(`set-scope:${workspaceScope() ?? ""}`);
406
+ // 4. route/reload new
407
+ if (typeof routeValue === "function") routeValue();
408
+ else if (typeof routeValue === "string") options.route?.(routeValue);
409
+ trace.push("route-new");
410
+ if (options.onTrace) options.onTrace(trace);
411
+ return trace;
412
+ }
413
+
414
+ /** Append ?workspaceId= to an observe API URL (real request path kept). */
415
+ export function scopedApiUrl(url) {
416
+ const raw = String(url ?? "");
417
+ if (!currentWorkspaceScope || !raw.startsWith("/api/")) return raw;
418
+ const qIndex = raw.indexOf("?");
419
+ if (qIndex >= 0) {
420
+ const params = new URLSearchParams(raw.slice(qIndex + 1));
421
+ if (params.has("workspaceId")) return raw;
422
+ params.set("workspaceId", currentWorkspaceScope);
423
+ return `${raw.slice(0, qIndex)}?${params.toString()}`;
424
+ }
425
+ return `${raw}?workspaceId=${encodeURIComponent(currentWorkspaceScope)}`;
426
+ }
427
+
282
428
  export function detailPollDelay(status, isVisible) {
283
429
  const normalizedStatus = (status ?? "").toLowerCase().replace(/-/g, "_");
284
430
  if (TERMINAL_RUN_STATUSES.has(normalizedStatus)) return null;
431
+ if (!isWorkspaceActive()) return null;
285
432
  return isVisible ? ACTIVE_DETAIL_POLL_MS : HIDDEN_POLL_MS;
286
433
  }
287
434
 
288
435
  export function dashboardPollDelay() {
436
+ if (!isWorkspaceActive()) return null;
289
437
  return isPageVisible() ? DASHBOARD_POLL_MS : HIDDEN_POLL_MS;
290
438
  }
291
439
 
440
+ /** Stop pausable timers without destroying route/selection/scroll. */
441
+ export function pauseForegroundTimers() {
442
+ if (uiState.dashboardTimer) {
443
+ clearTimeout(uiState.dashboardTimer);
444
+ uiState.dashboardTimer = null;
445
+ }
446
+ if (uiState.runPollTimer) {
447
+ clearTimeout(uiState.runPollTimer);
448
+ uiState.runPollTimer = null;
449
+ }
450
+ if (uiState.dagPollTimer) {
451
+ clearTimeout(uiState.dagPollTimer);
452
+ uiState.dagPollTimer = null;
453
+ }
454
+ if (uiState.poolTimer) {
455
+ clearTimeout(uiState.poolTimer);
456
+ uiState.poolTimer = null;
457
+ }
458
+ if (uiState.taskPollTimer) {
459
+ clearTimeout(uiState.taskPollTimer);
460
+ uiState.taskPollTimer = null;
461
+ }
462
+ }
463
+
292
464
  export function updateDagGraphViewportState(
293
465
  _previous,
294
466
  dagRunId,
@@ -3580,6 +3580,10 @@ button.copy-command:focus-visible {
3580
3580
  #dag-inspector-panel-prompt-restart {
3581
3581
  display: flex;
3582
3582
  flex-direction: column;
3583
+ min-height: 0;
3584
+ }
3585
+ #dag-inspector-panel-prompt-restart:has(.prompt-restart-panel.is-readonly) {
3586
+ overflow: hidden;
3583
3587
  }
3584
3588
  .prompt-restart-panel,
3585
3589
  .prompt-restart-box {
@@ -3589,6 +3593,14 @@ button.copy-command:focus-visible {
3589
3593
  min-width: 0;
3590
3594
  flex: 1;
3591
3595
  }
3596
+ .prompt-restart-panel.is-readonly {
3597
+ min-height: 0;
3598
+ overflow: hidden;
3599
+ }
3600
+ .prompt-restart-panel.is-readonly .prompt-restart-prompt-card {
3601
+ flex: 1 1 auto;
3602
+ min-height: 12rem;
3603
+ }
3592
3604
  .prompt-restart-toolbar {
3593
3605
  display: grid;
3594
3606
  grid-template-columns: minmax(0, 1fr) auto;
@@ -3814,7 +3826,6 @@ button.copy-command:focus-visible {
3814
3826
  .prompt-restart-readonly {
3815
3827
  margin: 0;
3816
3828
  padding: 14px 16px;
3817
- max-height: min(36vh, 18rem);
3818
3829
  overflow: auto;
3819
3830
  background: var(--canvas-soft);
3820
3831
  color: var(--ink);
@@ -3825,6 +3836,14 @@ button.copy-command:focus-visible {
3825
3836
  overflow-wrap: anywhere;
3826
3837
  tab-size: 2;
3827
3838
  }
3839
+ .prompt-restart-panel.is-readonly .prompt-restart-readonly {
3840
+ flex: 1 1 auto;
3841
+ min-height: 0;
3842
+ max-height: none;
3843
+ }
3844
+ .prompt-restart-panel.is-edit .prompt-restart-readonly {
3845
+ max-height: min(36vh, 18rem);
3846
+ }
3828
3847
  .prompt-restart-textarea {
3829
3848
  width: 100%;
3830
3849
  min-height: 8rem;
@@ -25,6 +25,7 @@ import { describeDagNodePurpose } from "../dag-node-purpose.js";
25
25
  import { buildPromptRestartCandidateOptions } from "../prompt-restart-candidates.js";
26
26
  import { copyText } from "../copy.js";
27
27
  import {
28
+ fetchWithWorkspaceScope,
28
29
  uiState,
29
30
  makeSessionEventIdentity,
30
31
  makeDagNodeInputIdentity,
@@ -1286,7 +1287,7 @@ export function frontendGateLedgerLines(input) {
1286
1287
  /** DAG run 专属 prewrite-result 只读拉取(内联 fetch,不新增 api.js 依赖)。 */
1287
1288
  async function fetchPrewriteResultJson(dagRunId) {
1288
1289
  try {
1289
- const res = await fetch(
1290
+ const res = await fetchWithWorkspaceScope(
1290
1291
  `/api/dag-runs/${encodeURIComponent(dagRunId)}/prewrite-result`,
1291
1292
  { credentials: "same-origin" },
1292
1293
  );
@@ -1404,7 +1405,7 @@ async function renderPromptRestart(content, dagRunId, node) {
1404
1405
 
1405
1406
  if (node.status !== "ERROR") {
1406
1407
  // Non-failed nodes still show their frozen prompt — read-only.
1407
- const panel = el("div", "prompt-restart-panel");
1408
+ const panel = el("div", "prompt-restart-panel is-readonly");
1408
1409
  panel.appendChild(
1409
1410
  createPromptRestartBanner({
1410
1411
  tone: "readonly",
@@ -2012,7 +2013,7 @@ function effectiveExecutionKey(dagRunId, node) {
2012
2013
  async function fetchExecutionOutput(dagRunId, nodeId, key) {
2013
2014
  const url = `/api/dag-runs/${encodeURIComponent(dagRunId)}/nodes/${encodeURIComponent(nodeId)}/execution-output?key=${encodeURIComponent(key)}`;
2014
2015
  try {
2015
- const res = await fetch(url);
2016
+ const res = await fetchWithWorkspaceScope(url);
2016
2017
  let body = null;
2017
2018
  try {
2018
2019
  body = await res.json();
@@ -364,7 +364,7 @@ export async function renderDagDetail(dagRunId, initial = true) {
364
364
  "page-action-btn",
365
365
  "在操作台中止此运行 →",
366
366
  );
367
- interruptLink.href = `/#/recovery?dagRunId=${encodeURIComponent(dag.dagRunId)}&intent=interrupt`;
367
+ interruptLink.href = `/#/operate/recovery?dagRunId=${encodeURIComponent(dag.dagRunId)}&intent=interrupt`;
368
368
  interruptLink.setAttribute("data-testid", "inspect-dag-interrupt-link");
369
369
  interruptLink.title = "只跳转到操作台 Recovery,不会在观测页执行中止";
370
370
  primaryEntries.push(["协作中止", interruptLink]);
@@ -482,6 +482,7 @@ export function startDagPolling(dagRunId, initial = true) {
482
482
  const active = await renderDagDetail(dagRunId, isInitial);
483
483
  if (generation !== uiState.pollingGeneration || !active) return;
484
484
  const delay = detailPollDelay("running", isPageVisible());
485
+ if (delay == null) return;
485
486
  uiState.dagPollTimer = setTimeout(() => {
486
487
  uiState.dagPollTimer = null;
487
488
  void poll(false);
@@ -84,7 +84,7 @@ let dashboardLoadingNode = null;
84
84
 
85
85
  /**
86
86
  * 「昨夜班次」条带:夜间结果在观测侧的唯一一级呈现(替代旧「夜间任务」tab)。
87
- * 管理动作(晨审处置)始终落在操作侧 /#/night,保持 Inspect 只读不变式。
87
+ * 管理动作(晨审处置)始终落在操作侧 /#/operate/night,保持 Inspect 只读不变式。
88
88
  */
89
89
  async function renderNightStrip() {
90
90
  const strip = document.getElementById("dashboard-night");
@@ -118,14 +118,14 @@ async function renderNightStrip() {
118
118
 
119
119
  const actions = el("div", "night-strip-actions");
120
120
  const detail = el("a", "page-action-btn", "夜间详情");
121
- detail.href = "#/night";
121
+ detail.href = "/#/inspect/night";
122
122
  detail.addEventListener("click", (e) => {
123
123
  e.preventDefault();
124
124
  navigate("/night");
125
125
  });
126
126
  actions.appendChild(detail);
127
127
  const manage = el("a", "page-action-btn night-strip-manage", "晨审处置 →");
128
- manage.href = "/#/night";
128
+ manage.href = "/#/operate/night";
129
129
  manage.title = "夜间计划的管理与晨审处置在操作台完成(Inspect 保持只读)";
130
130
  actions.appendChild(manage);
131
131
  strip.appendChild(actions);
@@ -738,10 +738,12 @@ export function startDashboardPolling(scrollTo) {
738
738
  const poll = async (initialScrollTo) => {
739
739
  await renderDashboard(initialScrollTo);
740
740
  if (generation !== uiState.pollingGeneration) return;
741
+ const delay = dashboardPollDelay();
742
+ if (delay == null) return;
741
743
  uiState.dashboardTimer = setTimeout(() => {
742
744
  uiState.dashboardTimer = null;
743
745
  void poll();
744
- }, dashboardPollDelay());
746
+ }, delay);
745
747
  };
746
748
  void poll(scrollTo);
747
749
  }
@@ -46,8 +46,8 @@ export async function renderNightJobs(scheduleId) {
46
46
  showView("night");
47
47
  bindNightToolbar();
48
48
  const crumbs = [
49
- { label: UI_TEXT.dashboard, href: "#/" },
50
- { label: UI_TEXT.nightJobs, href: "#/night" },
49
+ { label: UI_TEXT.dashboard, href: "/#/inspect" },
50
+ { label: UI_TEXT.nightJobs, href: "/#/inspect/night" },
51
51
  ];
52
52
  if (scheduleId) crumbs.push({ label: scheduleId });
53
53
  setBreadcrumb(crumbs);
@@ -93,6 +93,7 @@ function startPoolAutoPolling() {
93
93
  if (generation !== uiState.pollingGeneration) return;
94
94
  if (!poolAutoRefreshEnabled()) return;
95
95
  const delay = isPageVisible() ? POOL_POLL_MS : dashboardPollDelay();
96
+ if (delay == null) return;
96
97
  uiState.poolTimer = setTimeout(() => {
97
98
  uiState.poolTimer = null;
98
99
  void poll();
@@ -50,6 +50,7 @@ import {
50
50
  } from "../relations.js";
51
51
  import { copyText, renderRecommendedCommand } from "../copy.js";
52
52
  import {
53
+ fetchWithWorkspaceScope,
53
54
  isPageVisible,
54
55
  detailPollDelay,
55
56
  dashboardPollDelay,
@@ -126,7 +127,7 @@ export function renderInlineArtifactList(container, artifacts) {
126
127
  list.appendChild(li);
127
128
  void (async () => {
128
129
  try {
129
- const res = await fetch(artifactUrl(artifactPath));
130
+ const res = await fetchWithWorkspaceScope(artifactUrl(artifactPath));
130
131
  const text = await res.text();
131
132
  if (!res.ok) {
132
133
  let message = text;
@@ -444,6 +445,7 @@ export function startRunPolling(workerRunId, initial = true) {
444
445
  const active = await renderRun(workerRunId, isInitial);
445
446
  if (generation !== uiState.pollingGeneration || !active) return;
446
447
  const delay = detailPollDelay("running", isPageVisible());
448
+ if (delay == null) return;
447
449
  uiState.runPollTimer = setTimeout(() => {
448
450
  uiState.runPollTimer = null;
449
451
  void poll(false);
@@ -86,7 +86,7 @@ export async function renderTaskDetail(featureId, taskId) {
86
86
  showView("task");
87
87
  setBreadcrumb([
88
88
  { label: UI_TEXT.dashboard, href: "#/" },
89
- { label: "资源池", href: "#/pool" },
89
+ { label: "资源池", href: "/#/inspect/pool" },
90
90
  { label: displayLabel },
91
91
  ]);
92
92
 
@@ -4412,6 +4412,7 @@ async function buildBackendTestGapFillDag(sources) {
4412
4412
  ],
4413
4413
  };
4414
4414
  spec.backendTestLayout = layout;
4415
+ applyBackendTestWorkspaceControl(spec, taskConfig.backendTest?.workspaceControl ?? "git");
4415
4416
  if (sharedSetup) {
4416
4417
  spec.backendTestSharedSetup = { ...sharedSetup };
4417
4418
  }
@@ -4868,6 +4869,7 @@ async function buildBackendTestHybridDag(sources) {
4868
4869
  // against the resolved layout. The default layout is identity, so the
4869
4870
  // packaged template stays byte-identical with the historical contract.
4870
4871
  applyBackendTestLayoutToDagSpec(spec, layout);
4872
+ applyBackendTestWorkspaceControl(spec, taskConfig.backendTest?.workspaceControl ?? "git");
4871
4873
  // Plan B: carry the bound shared-setup document on the spec so runtime
4872
4874
  // validators (N6 markdown case validation) see the same binding as prompts.
4873
4875
  if (intake.sharedSetup) {
@@ -4878,6 +4880,23 @@ async function buildBackendTestHybridDag(sources) {
4878
4880
  assertValidDagSpec(spec);
4879
4881
  return spec;
4880
4882
  }
4883
+ function applyBackendTestWorkspaceControl(spec, control) {
4884
+ if (control !== "filesystem-only") {
4885
+ delete spec.backendTestWorkspaceControl;
4886
+ return;
4887
+ }
4888
+ spec.backendTestWorkspaceControl = control;
4889
+ for (const task of spec.tasks) {
4890
+ if ((task.executor === "pi" && task.toolProfile === "write") ||
4891
+ task.shell?.backendTestPipeline) {
4892
+ task.writeGuardPolicy = "filesystem-only";
4893
+ }
4894
+ const child = task.dynamicExpansion?.childTask;
4895
+ if (child?.executor === "pi" && child.toolProfile === "write") {
4896
+ child.writeGuardPolicy = "filesystem-only";
4897
+ }
4898
+ }
4899
+ }
4881
4900
  /** Rewrite layout-dependent strings across a compiled backend-test DAG spec (plan A). */
4882
4901
  function applyBackendTestLayoutToDagSpec(spec, layout) {
4883
4902
  if (layout.isDefault) {
@@ -1,8 +1,8 @@
1
1
  import { watch } from "node:fs";
2
- import { mkdir, readFile } from "node:fs/promises";
2
+ import { mkdir } from "node:fs/promises";
3
3
  import { hostname as localHostname } from "node:os";
4
4
  import path from "node:path";
5
- import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
5
+ import { readJsonWithTransientRetry, writeJsonAtomic, } from "../../infrastructure/harness/atomic-write.js";
6
6
  import { assessDagRunLiveness, getDagRunDir, locateDagRun, readDagRunState, } from "./lifecycle.js";
7
7
  export const INTERRUPT_ARTIFACT_REL = path.posix.join(".runtime", "interrupt.json");
8
8
  export const INTERRUPT_REASON_CODES = [
@@ -140,7 +140,7 @@ export function parseInterruptRequest(raw) {
140
140
  }
141
141
  export async function readInterruptRequest(runDir) {
142
142
  try {
143
- const raw = JSON.parse(await readFile(interruptArtifactPath(runDir), "utf-8"));
143
+ const raw = await readJsonWithTransientRetry(interruptArtifactPath(runDir));
144
144
  return parseInterruptRequest(raw);
145
145
  }
146
146
  catch (error) {
@@ -1,7 +1,7 @@
1
1
  import { access, mkdir, readFile, readdir, rename } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { hostname as localHostname } from "node:os";
4
- import { writeJsonAtomic, } from "../../infrastructure/harness/atomic-write.js";
4
+ import { readJsonWithTransientRetry, writeJsonAtomic, } from "../../infrastructure/harness/atomic-write.js";
5
5
  import { parseDagSpec } from "./types.js";
6
6
  import { normalizeDagFailureCategory, } from "./failure-category.js";
7
7
  import { dagProductLineFailureCategoryValues, routeDagFailure, } from "./failure-routing.js";
@@ -43,14 +43,14 @@ export async function dagRunDirExists(runDir) {
43
43
  }
44
44
  }
45
45
  export async function readDagRunState(runDir) {
46
- const raw = JSON.parse(await readFile(path.join(runDir, "state.json"), "utf-8"));
46
+ const raw = await readJsonWithTransientRetry(path.join(runDir, "state.json"));
47
47
  return raw;
48
48
  }
49
49
  export async function writeDagRunState(runDir, state, options) {
50
50
  await writeJsonAtomic(path.join(runDir, "state.json"), state, options);
51
51
  }
52
52
  export async function readDagRunSpec(runDir) {
53
- const raw = JSON.parse(await readFile(path.join(runDir, "run.json"), "utf-8"));
53
+ const raw = await readJsonWithTransientRetry(path.join(runDir, "run.json"));
54
54
  return parseDagSpec(raw);
55
55
  }
56
56
  export async function locateDagRun(cwd, runId) {
@@ -382,7 +382,7 @@ export const dagWritePolicySchema = z.enum([
382
382
  "none",
383
383
  ]);
384
384
  /** Git/post-diff write guard intensity for exclusive Pi writers. */
385
- export const dagWriteGuardPolicySchema = z.enum(["full", "tools-only"]);
385
+ export const dagWriteGuardPolicySchema = z.enum(["full", "tools-only", "filesystem-only"]);
386
386
  /**
387
387
  * Fail-closed outcome/diff consistency contract for bounded Pi writers.
388
388
  * The writer must begin with IMPLEMENTATION_OUTCOME: changed,
@@ -997,6 +997,8 @@ export const dagSpecSchema = z
997
997
  taskContractBinding: dagTaskContractBindingSchema.optional(),
998
998
  /** Optional unresolved parent-run feedback for a full task rerun. */
999
999
  rerunFeedback: dagRerunFeedbackSchema.optional(),
1000
+ /** Backend-test-only workspace mutation control; absent means Git. */
1001
+ backendTestWorkspaceControl: z.enum(["git", "filesystem-only"]).optional(),
1000
1002
  /** Frozen backend-test artifact layout (plan A); absent = historical default testcase/ layout. */
1001
1003
  backendTestLayout: z
1002
1004
  .object({
package/docs/README.md CHANGED
@@ -73,6 +73,7 @@
73
73
  | `design/active/` | 仍会影响后续决策的设计输入、路线与契约 |
74
74
  | `design/visual-references/` | 长期视觉参考,不表达实现状态 |
75
75
  | `design/archive/` | 历史设计和已被实现/替代的阶段性设计 |
76
+ | `superpowers/specs/` | Superpowers 工作流产出的阶段性实现设计输入 |
76
77
  | `exec-plans/active/` | 仍需推进或明确保持 open 的任务合同 |
77
78
  | `exec-plans/completed/` | 已完成任务合同归档 |
78
79
  | `progress/` | 仍需下一次会话接手的当前 handoff 入口 |
@@ -2,6 +2,27 @@
2
2
 
3
3
  本文记录仅与特定开发环境有关、但可能反复影响验证结果的问题。它不是通用工程规则;标准验证命令仍以 [`verification-matrix.md`](../governance/verification-matrix.md) 为准。
4
4
 
5
+ ## Operator Console 前端快速迭代
6
+
7
+ 对 `src/worker/console/static-src/` 内的对话样式和前端交互做高频调整时,使用固定 8790 的开发入口:
8
+
9
+ ```bash
10
+ npm run console:dev
11
+ ```
12
+
13
+ 它从当前源码启动真实 Console 后端,并在内部 `8791` 常驻 Vite dev server。浏览器始终访问 `http://127.0.0.1:8790/`:API、HttpOnly Cookie、确认令牌和 Origin 校验仍由真实 Console 处理,前端 HTML/模块请求才由 8790 转发给 Vite。CSS 保存后原地热替换,TSX 保存后自动整页刷新;不生成 `static-dev` bundle,也不重复运行生产 build。
14
+
15
+ 常用参数:
16
+
17
+ ```bash
18
+ npm run console:dev -- --no-open
19
+ npm run console:dev -- --port 8792 --reload-port 8793 --no-open
20
+ ```
21
+
22
+ 默认端口是 Console `8790`、内部 Vite/HMR `8791`;两者都只允许 loopback。端口已占用时命令会失败并报告端口,不会停止或接管已有进程。前端类型检查在后台持续输出诊断,但不阻塞 HMR;后端源码变化时只重启 Console 子进程,Vite 保持常驻。
23
+
24
+ 该命令只优化编辑反馈,不构成验收。独立交互修复完成后仍需运行定向 Vitest;交付前按验证矩阵运行 typecheck、正式 `npm run console:build` / `npm run build`。正式构建继续写入 `dist/worker/console/static/`,不会包含 `/@vite/client`、8791 或开发代理代码。
25
+
5
26
  ## Git hooks(本仓库)
6
27
 
7
28
  每个 clone 安装一次:
package/harness.json CHANGED
@@ -82,9 +82,9 @@
82
82
  "executors": {
83
83
  "pi": {
84
84
  "description": "Pi 负责规划、评审、诊断;当 DAG toolProfile=write 时也可做有界写入。模型按复杂度三档配置,支持 provider/model 字符串或带 thinking 的对象;斜杠前为 Pi provider,后为 modelId,勿只写裸 modelId。",
85
- "LOW": "deepseek/deepseek-v4-flash",
86
- "MED": "deepseek/deepseek-v4-flash",
87
- "HIGH": "deepseek/deepseek-v4-flash"
85
+ "LOW": "wizard-local/minimax-m3",
86
+ "MED": "wizard-local/glm-5.3",
87
+ "HIGH": "wizard-local/gpt-5.6-sol"
88
88
  }
89
89
  }
90
90
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.40.0-next.3",
3
+ "version": "0.40.0-next.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -54,6 +54,7 @@
54
54
  "build": "npm run brand:sync && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build && node scripts/write-build-stamp.mjs",
55
55
  "console:typecheck": "tsc -p src/worker/console/tsconfig.json",
56
56
  "console:build": "npm run console:typecheck && vite build --config src/worker/console/vite.config.ts",
57
+ "console:dev": "node --import tsx/esm scripts/console-dev.mjs",
57
58
  "prepack": "npm run build",
58
59
  "prepublishOnly": "node scripts/check-npm-publish-policy.mjs && npm run typecheck && npm test && npm run build",
59
60
  "lint": "npm run typecheck",
@@ -71,6 +72,7 @@
71
72
  "verify:tree": "node scripts/pre-push-verify.mjs --verify-current-tree"
72
73
  },
73
74
  "dependencies": {
75
+ "@deepseek-ai/dsh-host-directory-picker-native": "0.1.1-rc.2",
74
76
  "@earendil-works/pi-ai": "0.83.0",
75
77
  "@earendil-works/pi-coding-agent": "0.83.0",
76
78
  "commander": "^12.1.0",
@@ -1 +0,0 @@
1
- import{ag as o,ah as n}from"./mermaid.core-Biyo-tqA.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-TJ5JuEBT.js";import{_ as i}from"./mermaid.core-Biyo-tqA.js";import"./chunk-5VM5RSS4-JCNGkXYT.js";import"./chunk-XXDRQBXY-By9VQoi1.js";import"./chunk-KBJHAD2P-D60-Mny4.js";import"./chunk-2GRJ4B5K-wRO_iRNc.js";import"./index-CW88Fjbw.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-TJ5JuEBT.js";import{_ as i}from"./mermaid.core-Biyo-tqA.js";import"./chunk-5VM5RSS4-JCNGkXYT.js";import"./chunk-XXDRQBXY-By9VQoi1.js";import"./chunk-KBJHAD2P-D60-Mny4.js";import"./chunk-2GRJ4B5K-wRO_iRNc.js";import"./index-CW88Fjbw.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};