pilotswarm 0.5.69 → 0.5.70

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 (74) hide show
  1. package/package.json +2 -2
  2. package/ui/core/src/history.js +3 -1
  3. package/ui/core/src/native-tasks.js +46 -2
  4. package/ui/core/src/selectors.js +40 -15
  5. package/ui/react/src/chat-call-line.js +17 -0
  6. package/ui/react/src/native-task-card.js +53 -23
  7. package/ui/react/src/web-app.js +52 -36
  8. package/web/dist/assets/{abnfDiagram-VRR7QNED-DCEEpIGf.js → abnfDiagram-VRR7QNED-CidJDJrY.js} +1 -1
  9. package/web/dist/assets/{arc-_RJw0dJ3.js → arc-BDO1TDjs.js} +1 -1
  10. package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-Bze_PsYG.js → architectureDiagram-ZJ3FMSHR-BIcgz3Aa.js} +1 -1
  11. package/web/dist/assets/{blockDiagram-677ZJIJ3-CZaMO9H-.js → blockDiagram-677ZJIJ3-CWtdYLva.js} +1 -1
  12. package/web/dist/assets/{c4Diagram-LMCZKHZV-Dzr58V1d.js → c4Diagram-LMCZKHZV-u_IOLAS7.js} +1 -1
  13. package/web/dist/assets/channel-KxoOVq0K.js +1 -0
  14. package/web/dist/assets/{chunk-2Q5K7J3B-1IO7uTFx.js → chunk-2Q5K7J3B-daWW1UxL.js} +1 -1
  15. package/web/dist/assets/{chunk-32BRIVSS-DKdpRP0l.js → chunk-32BRIVSS-DyxnM56K.js} +1 -1
  16. package/web/dist/assets/{chunk-5VM5RSS4-CxyhZOh5.js → chunk-5VM5RSS4-D7taC4Nx.js} +1 -1
  17. package/web/dist/assets/{chunk-EX3LRPZG-DWY7moCs.js → chunk-EX3LRPZG-BWo08pDw.js} +1 -1
  18. package/web/dist/assets/{chunk-JWPE2WC7-By7oiTbd.js → chunk-JWPE2WC7-AhysI3TD.js} +1 -1
  19. package/web/dist/assets/{chunk-MOJQB5TN-CS-m-Pv3.js → chunk-MOJQB5TN-CDyGPb8L.js} +1 -1
  20. package/web/dist/assets/{chunk-RYQCIY6F-Cxykz4-E.js → chunk-RYQCIY6F-RhKa7iem.js} +1 -1
  21. package/web/dist/assets/{chunk-V7JOEXUC-Dwl0aU9m.js → chunk-V7JOEXUC-DLgws19l.js} +1 -1
  22. package/web/dist/assets/{chunk-VR4S4FIN-BERWiLR7.js → chunk-VR4S4FIN-CyLmmpZk.js} +1 -1
  23. package/web/dist/assets/{chunk-XXDRQBXY-CZ0e721z.js → chunk-XXDRQBXY-DYN0KnEU.js} +1 -1
  24. package/web/dist/assets/classDiagram-OUVF2IWQ-B6yEKJ21.js +1 -0
  25. package/web/dist/assets/classDiagram-v2-EOCWNBFH-B6yEKJ21.js +1 -0
  26. package/web/dist/assets/{cose-bilkent-JH36ORCC-RLgoKX1J.js → cose-bilkent-JH36ORCC-62MpINYU.js} +1 -1
  27. package/web/dist/assets/{cynefin-VYW2F7L2-CUvcvCFo.js → cynefin-VYW2F7L2-CHVeQsGv.js} +1 -1
  28. package/web/dist/assets/{cynefinDiagram-TSTJHNR4-D2ML_npa.js → cynefinDiagram-TSTJHNR4-BYgzn_3A.js} +1 -1
  29. package/web/dist/assets/{dagre-VKFMJZFB-BHG6-avE.js → dagre-VKFMJZFB-C3qJqyHj.js} +1 -1
  30. package/web/dist/assets/{diagram-FQU43EPY-ynOb8q0h.js → diagram-FQU43EPY-BBYvv2Hx.js} +1 -1
  31. package/web/dist/assets/{diagram-G47NLZAW-BLHAADd0.js → diagram-G47NLZAW-1Ca1QwqV.js} +1 -1
  32. package/web/dist/assets/{diagram-NH7WQ7WH-DwOMd4DW.js → diagram-NH7WQ7WH-CicNpuah.js} +1 -1
  33. package/web/dist/assets/{diagram-OA4YK3LP-DZWnpqT9.js → diagram-OA4YK3LP-BDGMGAu8.js} +1 -1
  34. package/web/dist/assets/{diagram-WEI45ONY-BMcvO3Pf.js → diagram-WEI45ONY-EgaBHcZC.js} +1 -1
  35. package/web/dist/assets/{ebnfDiagram-CCIWWBDH-CRX9h0gP.js → ebnfDiagram-CCIWWBDH-BEGQ-CpA.js} +1 -1
  36. package/web/dist/assets/{erDiagram-Q63AITRT-Con2S52S.js → erDiagram-Q63AITRT-BifquFiz.js} +1 -1
  37. package/web/dist/assets/{flowDiagram-23GEKE2U-wg4unvdR.js → flowDiagram-23GEKE2U-BOEV0nau.js} +1 -1
  38. package/web/dist/assets/{ganttDiagram-NO4QXBWP-CAg65Xfj.js → ganttDiagram-NO4QXBWP-Die6C1uw.js} +1 -1
  39. package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-5u02gmfN.js → gitGraphDiagram-IHSO6WYX-BS6qOLxN.js} +1 -1
  40. package/web/dist/assets/index-CCniDa-9.css +1 -0
  41. package/web/dist/assets/{index-DzjecAo8.js → index-DpkfY3jc.js} +2 -2
  42. package/web/dist/assets/{infoDiagram-FWYZ7A6U-DW830L4J.js → infoDiagram-FWYZ7A6U-C3dgkkDc.js} +1 -1
  43. package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-6Qr30UBj.js → ishikawaDiagram-FXEZZL3T-BmGRDlL-.js} +1 -1
  44. package/web/dist/assets/{journeyDiagram-5HDEW3XC-BHCjdAv1.js → journeyDiagram-5HDEW3XC-De0y-2Pp.js} +1 -1
  45. package/web/dist/assets/{kanban-definition-HUTT4EX6-PGpXvhY7.js → kanban-definition-HUTT4EX6-CPVl9fbH.js} +1 -1
  46. package/web/dist/assets/{linear-CuN5Qi_I.js → linear-BwcW14FN.js} +1 -1
  47. package/web/dist/assets/{mermaid.core-BEG_GOf7.js → mermaid.core-BPC8y2lr.js} +4 -4
  48. package/web/dist/assets/{mindmap-definition-LN4V7U3C-Bbi2gb0f.js → mindmap-definition-LN4V7U3C-CmTjYZ6-.js} +1 -1
  49. package/web/dist/assets/{papaparse.min-LDhOsJ62.js → papaparse.min-DwUBIiJJ.js} +1 -1
  50. package/web/dist/assets/{pegDiagram-2B236MQR-IZ3AowOt.js → pegDiagram-2B236MQR-DI77hWU9.js} +1 -1
  51. package/web/dist/assets/{pieDiagram-ENE6RG2P-QnG3Rlhe.js → pieDiagram-ENE6RG2P-CQL62GJk.js} +1 -1
  52. package/web/dist/assets/pilotswarm-BnfVgmru.js +109 -0
  53. package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-BIB7xhGf.js → quadrantDiagram-ABIIQ3AL-CQoKIYFZ.js} +1 -1
  54. package/web/dist/assets/{railroadDiagram-RFXS5EU6-CHbggWfd.js → railroadDiagram-RFXS5EU6-B2KkUNRk.js} +1 -1
  55. package/web/dist/assets/{requirementDiagram-TGXJPOKE-CgNGJVBn.js → requirementDiagram-TGXJPOKE-Dgl152x0.js} +1 -1
  56. package/web/dist/assets/{sankeyDiagram-HTMAVEWB-B1GfGCwn.js → sankeyDiagram-HTMAVEWB-B-SjWvvt.js} +1 -1
  57. package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-D-Bfj-RU.js → sequenceDiagram-DBY2YBRQ-CuuRcXdJ.js} +1 -1
  58. package/web/dist/assets/{sizeCapture-X5ZJPWSS-Ca-mVfMN.js → sizeCapture-X5ZJPWSS-TzEpZfA7.js} +1 -1
  59. package/web/dist/assets/{stateDiagram-2N3HPSRC-5gIoJ_8A.js → stateDiagram-2N3HPSRC-XAi55Ttk.js} +1 -1
  60. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CXVciPM_.js +1 -0
  61. package/web/dist/assets/{swimlanes-5IMT3BWC-HxN6_3nA.js → swimlanes-5IMT3BWC-C6ATJwDO.js} +2 -2
  62. package/web/dist/assets/swimlanesDiagram-G3AALYLV-Dk-VTEgD.js +8 -0
  63. package/web/dist/assets/{timeline-definition-FHXFAJF6-CSkNwYwY.js → timeline-definition-FHXFAJF6-DhUjhdEH.js} +1 -1
  64. package/web/dist/assets/{vennDiagram-L72KCM5P-o6qvAiNl.js → vennDiagram-L72KCM5P-CxoeZ7Ri.js} +1 -1
  65. package/web/dist/assets/{wardleyDiagram-EHGQE667-HcUO3YZZ.js → wardleyDiagram-EHGQE667-ChgUaxkB.js} +1 -1
  66. package/web/dist/assets/{xychartDiagram-FW5EYKEG-DmNJJPi3.js → xychartDiagram-FW5EYKEG-iV0ACrP1.js} +1 -1
  67. package/web/dist/index.html +3 -3
  68. package/web/dist/assets/channel-CHAZ3LVB.js +0 -1
  69. package/web/dist/assets/classDiagram-OUVF2IWQ-CXv3ioyD.js +0 -1
  70. package/web/dist/assets/classDiagram-v2-EOCWNBFH-CXv3ioyD.js +0 -1
  71. package/web/dist/assets/index-BT3MiUPE.css +0 -1
  72. package/web/dist/assets/pilotswarm-BNTnbu9f.js +0 -109
  73. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-C_IKdqOV.js +0 -1
  74. package/web/dist/assets/swimlanesDiagram-G3AALYLV-B8jNOz1z.js +0 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pilotswarm",
3
- "version": "0.5.69",
3
+ "version": "0.5.70",
4
4
  "description": "PilotSwarm application package: terminal UI, browser portal + Web API server, and MCP server — one install, three bins.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -81,7 +81,7 @@
81
81
  "ink": "^6.8.0",
82
82
  "jose": "^6.2.2",
83
83
  "mermaid": "^11.16.0",
84
- "pilotswarm-sdk": "0.5.69",
84
+ "pilotswarm-sdk": "0.5.70",
85
85
  "react": "^19.2.4",
86
86
  "react-dom": "^19.2.4",
87
87
  "ws": "^8.18.2"
@@ -3,7 +3,7 @@ import { isCanvasActionContent, parseCanvasActionContent } from "./canvas-action
3
3
  import { formatCompactionActivityRuns } from "./context-usage.js";
4
4
  import { canonicalSystemTitle } from "./system-titles.js";
5
5
  import { matchesSessionError } from "./session-warning.js";
6
- import { appendNativeTaskEvent } from "./native-tasks.js";
6
+ import { appendNativeTaskEvent, appendNativeTaskCall } from "./native-tasks.js";
7
7
  import { buildSessionWarning } from "./session-errors.js";
8
8
  import { appendChatCall, CHAT_CALL_EVENT_TYPES } from "./chat-activity.js";
9
9
 
@@ -21,6 +21,7 @@ export const HISTORY_EVENT_LIMIT_STEPS = [
21
21
  // load transcript pages instead of raw-stream pages.
22
22
  export const CHAT_HISTORY_EVENT_TYPES = [
23
23
  ...CHAT_CALL_EVENT_TYPES,
24
+ ...CHAT_CALL_EVENT_TYPES.filter(type => type !== "session.agent_spawned").map(type => `native.${type}`),
24
25
  "user.message",
25
26
  "assistant.message",
26
27
  // Needed to distinguish interim assistant output from the final answer
@@ -137,6 +138,7 @@ function appendSessionWarning(chat, event) {
137
138
 
138
139
  const parentChatCallTypes = new Set(CHAT_CALL_EVENT_TYPES);
139
140
  function appendParentChatCall(chat, event) {
141
+ if (appendNativeTaskCall(chat, event)) return;
140
142
  if (!parentChatCallTypes.has(event?.eventType)) return;
141
143
  const data = event?.data || {};
142
144
  // Native tasks have their own abridged disclosure. Generic call cards
@@ -1,3 +1,5 @@
1
+ import { appendChatCall, CHAT_CALL_EVENT_TYPES } from "./chat-activity.js";
2
+
1
3
  // Native Copilot work is local to one parent turn. Durable spawn_agent
2
4
  // sessions deliberately do not enter this projection.
3
5
  const TERMINAL = new Set(["completed", "failed", "cancelled", "interrupted"]);
@@ -61,6 +63,7 @@ function updateTask(chat, patch, event, { authoritative = false } = {}) {
61
63
  if (previous?.inferredTerminal) next.error = patch.error || "";
62
64
  }
63
65
  next.title = clip(next.title, 160) || "Native task";
66
+ if (next.title === "Native task" && previous?.title) next.title = previous.title;
64
67
  next.preview = clip(next.preview);
65
68
  next.result = clip(next.result, 4000);
66
69
  next.error = clip(next.error, 1000);
@@ -89,6 +92,47 @@ function updateTask(chat, patch, event, { authoritative = false } = {}) {
89
92
  }
90
93
  }
91
94
 
95
+ // Correlate by runtime identity, never by tool name or arrival time. External
96
+ // callbacks may arrive before the child event; move that existing disclosure
97
+ // under its owner as soon as the explicit relationship becomes available.
98
+ export function appendNativeTaskCall(chat, event) {
99
+ const type = (event?.eventType || "").replace(/^native\./, "");
100
+ if (!CHAT_CALL_EVENT_TYPES.includes(type) || type === "session.agent_spawned") return false;
101
+ const data = event.data || {};
102
+ const explicit = Boolean(data.nativeAgentId || data.parentToolCallId || event.eventType.startsWith("native."));
103
+ const keys = [data.toolCallId && `call:${data.toolCallId}`, data.requestId && `request:${data.requestId}`].filter(Boolean);
104
+ let match = explicit ? findTask(chat, { toolCallId: data.parentToolCallId, agentId: data.nativeAgentId }) : null;
105
+ const namespace = `${event.sessionId}:${data.durableSessionId || ""}`;
106
+ if (!match && !explicit) {
107
+ for (let g = chat.length - 1; g >= 0 && !match; g--) {
108
+ if (chat[g].kind !== "native-task-group") continue;
109
+ const t = chat[g].tasks.findIndex(task => task.calls?.some(call => call.namespace === namespace
110
+ && call.callKeys.some(key => keys.includes(key))));
111
+ if (t >= 0) match = { groupIndex: g, taskIndex: t };
112
+ }
113
+ }
114
+ if (!match && explicit && (data.parentToolCallId || data.nativeAgentId)) {
115
+ updateTask(chat, { toolCallId: data.parentToolCallId, agentId: data.nativeAgentId, status: "running" }, event);
116
+ match = findTask(chat, { toolCallId: data.parentToolCallId, agentId: data.nativeAgentId });
117
+ }
118
+ if (!match) return explicit; // Unknown child activity must not impersonate the parent.
119
+ const group = chat[match.groupIndex];
120
+ const task = group.tasks[match.taskIndex];
121
+ const calls = [...(task.calls || [])];
122
+ for (let i = chat.length - 1; i >= 0; i--) {
123
+ const call = chat[i];
124
+ if (call.kind !== "chat-call" || call.namespace !== namespace || !call.callKeys.some(key => keys.includes(key))) continue;
125
+ if (!calls.some(item => item.callKeys.some(key => call.callKeys.includes(key)))) calls.push(call);
126
+ chat.splice(i, 1);
127
+ }
128
+ appendChatCall(calls, { ...event, eventType: type });
129
+ const tasks = [...group.tasks];
130
+ tasks[match.taskIndex] = { ...task, calls, toolCalls: Math.max(task.toolCalls || 0, calls.length) };
131
+ // Removing a parent disclosure can shift the group's index.
132
+ chat[chat.indexOf(group)] = { ...group, tasks };
133
+ return true;
134
+ }
135
+
92
136
  export function appendNativeTaskEvent(chat, event) {
93
137
  const type = event?.eventType || "";
94
138
  const data = event?.data || {};
@@ -119,7 +163,7 @@ export function appendNativeTaskEvent(chat, event) {
119
163
  const previous = found ? chat[found.groupIndex].tasks[found.taskIndex] : null;
120
164
  if (!previous && !lifecycle && !taskTool) return;
121
165
  if (!previous || taskTool || type === "subagent.started") Object.assign(patch, {
122
- title: args.description || data.agentDisplayName || args.name || data.agentName || "Native task",
166
+ title: args.description || args.name || (previous?.title !== "Native task" ? previous?.title : null) || data.agentDisplayName || "Native task",
123
167
  profile: args.agent_type || data.agentName || data.agentType,
124
168
  model: data.model,
125
169
  });
@@ -145,7 +189,7 @@ export function appendNativeTaskEvent(chat, event) {
145
189
  } else if (type === "native.tool.execution_start") {
146
190
  const ids = previous.toolCallIds || [];
147
191
  patch.toolCallIds = data.toolCallId && !ids.includes(data.toolCallId) ? [...ids, data.toolCallId].slice(-500) : ids;
148
- patch.toolCalls = (previous.toolCalls || 0) + (patch.toolCallIds !== ids ? 1 : 0);
192
+ patch.toolCalls = Math.max(previous.toolCalls || 0, patch.toolCallIds.length);
149
193
  patch.preview = args.description || (data.toolName ? `Using ${data.toolName}` : "Working");
150
194
  } else if (type === "native.assistant.message") {
151
195
  // Do not expose reasoning, tool arguments, or the whole child transcript.
@@ -638,11 +638,20 @@ function distinctHumanOwnerCount(state, stopAt = Infinity) {
638
638
  return owners.size;
639
639
  }
640
640
 
641
+ const sessionOwnerDecorationCache = new WeakMap();
641
642
  function shouldDecorateSessionOwners(state) {
642
643
  // One rule: the chip earns its place when the list holds more than one
643
644
  // distinct human owner. Otherwise it is noise on every row — you are
644
645
  // always "you".
645
- return distinctHumanOwnerCount(state, 2) > 1;
646
+ const byId = state?.sessions?.byId;
647
+ if (!byId) return false;
648
+ const filter = state.sessions.ownerFilter;
649
+ const auth = state.auth;
650
+ const cached = sessionOwnerDecorationCache.get(byId);
651
+ if (cached && cached.filter === filter && cached.auth === auth) return cached.value;
652
+ const value = distinctHumanOwnerCount(state, 2) > 1;
653
+ sessionOwnerDecorationCache.set(byId, { filter, auth, value });
654
+ return value;
646
655
  }
647
656
 
648
657
  function groupMemberSessions(group, byId = {}) {
@@ -1293,6 +1302,7 @@ function matchesSearchQuery(value, query) {
1293
1302
  }
1294
1303
 
1295
1304
  const searchedSessionFlatCache = new WeakMap();
1305
+ const sessionSearchIndexCache = new WeakMap();
1296
1306
 
1297
1307
  function sessionGroupTitle(session, byId) {
1298
1308
  if (session?.isGroup) return session.title || "";
@@ -1320,14 +1330,11 @@ function sessionSearchOwner(session, byId) {
1320
1330
  return null;
1321
1331
  }
1322
1332
 
1323
- function buildSearchedSessionFlat(state, query) {
1324
- const existingFlat = Array.isArray(state.sessions?.flat) ? state.sessions.flat : [];
1325
- if (!query) return existingFlat;
1326
- const cached = searchedSessionFlatCache.get(existingFlat);
1327
- if (cached?.query === query) return cached.result;
1328
-
1333
+ function sessionSearchIndex(state) {
1329
1334
  const byId = state.sessions?.byId || {};
1330
- const parsed = parseSessionSearchQuery(query);
1335
+ const deps = [state.sessions?.orderById, state.sessions?.pinnedIds, state.sessions?.manualOrder];
1336
+ const cached = sessionSearchIndexCache.get(byId);
1337
+ if (cached && sameRowDeps(cached.deps, deps)) return cached;
1331
1338
  const expanded = buildSessionTree(
1332
1339
  Object.values(byId),
1333
1340
  new Set(),
@@ -1348,16 +1355,34 @@ function buildSearchedSessionFlat(state, query) {
1348
1355
  baseIndex.set(entry.sessionId, index);
1349
1356
  }
1350
1357
 
1358
+ const documents = new Map(expanded.map(entry => {
1359
+ const session = byId[entry.sessionId] || entry.standIn;
1360
+ return [entry.sessionId, buildSessionSearchDocument(session, {
1361
+ owner: sessionSearchOwner(session, byId), groupTitle: sessionGroupTitle(session, byId),
1362
+ })];
1363
+ }));
1364
+ const index = { deps, expanded, parentById, entryById, baseIndex, documents };
1365
+ sessionSearchIndexCache.set(byId, index);
1366
+ return index;
1367
+ }
1368
+
1369
+ function buildSearchedSessionFlat(state, query) {
1370
+ const existingFlat = Array.isArray(state.sessions?.flat) ? state.sessions.flat : [];
1371
+ if (!query) return existingFlat;
1372
+ const cached = searchedSessionFlatCache.get(existingFlat);
1373
+ const deps = [state.sessions?.byId, state.sessions?.ownerFilter, state.auth, state.sessions?.orderById,
1374
+ state.sessions?.pinnedIds, state.sessions?.manualOrder, state.sessions?.filterExceptionId];
1375
+ if (cached?.query === query && sameRowDeps(cached.deps, deps)) return cached.result;
1376
+
1377
+ const byId = state.sessions?.byId || {};
1378
+ const parsed = parseSessionSearchQuery(query);
1379
+ const { expanded, parentById, entryById, baseIndex, documents } = sessionSearchIndex(state);
1380
+
1351
1381
  const directScores = new Map();
1352
1382
  for (const entry of expanded) {
1353
1383
  const session = byId[entry.sessionId] || entry.standIn;
1354
1384
  if (!session || !matchesOwnerFilter(session, state.sessions?.ownerFilter, state.auth || {}, byId)) continue;
1355
- const owner = sessionSearchOwner(session, byId);
1356
- const document = buildSessionSearchDocument(session, {
1357
- owner,
1358
- groupTitle: sessionGroupTitle(session, byId),
1359
- });
1360
- const score = scoreSessionSearchDocument(document, parsed);
1385
+ const score = scoreSessionSearchDocument(documents.get(entry.sessionId), parsed);
1361
1386
  if (score > 0) directScores.set(entry.sessionId, score);
1362
1387
  }
1363
1388
  const matchedIds = new Set(directScores.keys());
@@ -1414,7 +1439,7 @@ function buildSearchedSessionFlat(state, query) {
1414
1439
  // A user can type an unbounded number of distinct queries while the
1415
1440
  // catalog array keeps the same identity. Keep only the latest result for
1416
1441
  // that catalog rather than retaining every intermediate keystroke.
1417
- searchedSessionFlatCache.set(existingFlat, { query, result });
1442
+ searchedSessionFlatCache.set(existingFlat, { query, deps, result });
1418
1443
  return result;
1419
1444
  }
1420
1445
 
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+
3
+ export function ChatCallLine({ line }) {
4
+ const [open, setOpen] = React.useState(false);
5
+ return React.createElement("details", {
6
+ className: "ps-system-notice ps-chat-call",
7
+ "data-call-id": line.callKey,
8
+ onToggle: event => setOpen(event.currentTarget.open),
9
+ },
10
+ React.createElement("summary", { className: "ps-system-notice-summary ps-chat-call-summary" },
11
+ React.createElement("span", { className: "ps-chat-call-tag" }, line.category || "Tool"),
12
+ React.createElement("span", { className: "ps-system-notice-summary-text" }, line.text),
13
+ line.status ? React.createElement("span", { className: `ps-chat-call-status${line.status === "Failed" ? " is-failed" : ""}` }, line.status) : null),
14
+ open ? React.createElement("div", { className: "ps-system-notice-body" },
15
+ line.time ? React.createElement("div", { className: "ps-chat-call-time" }, line.time) : null,
16
+ React.createElement("pre", { className: "ps-chat-call-payload" }, line.body)) : null);
17
+ }
@@ -1,4 +1,6 @@
1
1
  import React from "react";
2
+ import { ChatCallLine } from "./chat-call-line.js";
3
+ import { chatCallLine } from "../../core/src/chat-activity.js";
2
4
  import { NATIVE_TASK_LABELS } from "../../core/src/native-tasks.js";
3
5
 
4
6
  const TERMINAL = new Set(["completed", "failed", "cancelled", "interrupted"]);
@@ -31,29 +33,57 @@ export const NativeTaskCard = React.memo(function NativeTaskCard({ group, colors
31
33
  React.createElement("span", { className: "ps-native-tasks-title" },
32
34
  React.createElement("span", { className: "ps-native-task-branch", "aria-hidden": true }, "⑂"), "Native tasks"),
33
35
  React.createElement("span", { className: "ps-native-tasks-count", "aria-live": "polite" }, countLabel)),
34
- tasks.map(task => {
35
- const color = colors[task.status] || colors.running;
36
- const preview = task.error || task.result || task.preview || (task.status === "completed" ? "Task completed." : "");
37
- const time = duration(task, now);
38
- return React.createElement("details", { key: task.id, className: "ps-native-task", "data-task-id": task.id, "data-status": task.status,
39
- style: { "--ps-native-task-accent": color } },
40
- React.createElement("summary", null,
41
- React.createElement("span", { className: "ps-native-task-mark", "aria-hidden": true }, MARKS[task.status] || "?"),
42
- React.createElement("span", { className: "ps-native-task-main" },
43
- React.createElement("span", { className: "ps-native-task-title" }, task.title),
44
- preview ? React.createElement("span", { className: "ps-native-task-preview" }, preview.replace(/\s+/g, " ").slice(0, 240)) : null),
45
- React.createElement("span", { className: "ps-native-task-meta" },
46
- React.createElement("span", { className: "ps-native-task-status" }, task.telemetryStale ? "Reconnecting" : NATIVE_TASK_LABELS[task.status] || task.status),
47
- React.createElement("span", null, [time, `${task.toolCalls || 0} calls`].filter(Boolean).join(" · "))),
48
- React.createElement("span", { className: "ps-native-task-chevron", "aria-hidden": true }, "›")),
49
- React.createElement("div", { className: "ps-native-task-detail" },
50
- React.createElement("div", { className: "ps-native-task-scope" }, [task.profile, task.model, task.reasoningEffort, "Same worker"].filter(Boolean).join(" · ")),
51
- task.result && !task.error ? React.createElement("div", { className: "ps-native-task-scope" }, "Result excerpt") : null,
52
- React.createElement("p", { className: "ps-native-task-result" }, task.error || task.result || task.preview
53
- || (task.status === "completed" ? "Task completed. A result excerpt is not available in this recording." : "No result available yet.")),
54
- task.recentActivity?.length ? React.createElement("ul", { className: "ps-native-task-activity" },
55
- task.recentActivity.map((activity, i) => React.createElement("li", { key: i }, activity.message))) : null));
56
- }),
36
+ tasks.map(task => React.createElement(NativeTask, { key: task.id, task, colors, now })),
57
37
  group.tasks.length > 3 ? React.createElement("button", { type: "button", className: "ps-native-tasks-more", "aria-expanded": showAll,
58
38
  onClick: () => setShowAll(value => !value) }, showAll ? "Show fewer tasks" : `Show ${group.tasks.length - 3} more tasks`) : null);
59
39
  });
40
+
41
+ function NativeTask({ task, colors, now }) {
42
+ const failed = ["failed", "cancelled", "interrupted"].includes(task.status);
43
+ const [open, setOpen] = React.useState(!TERMINAL.has(task.status) || failed);
44
+ const inspected = React.useRef(false);
45
+ const viewport = React.useRef(null);
46
+ const follow = React.useRef(true);
47
+ const calls = React.useMemo(() => (task.calls || []).map(chatCallLine), [task.calls]);
48
+ React.useLayoutEffect(() => {
49
+ if (open && viewport.current && follow.current) viewport.current.scrollTop = viewport.current.scrollHeight;
50
+ }, [open, calls.length]);
51
+ React.useEffect(() => {
52
+ if (failed || !inspected.current) setOpen(!TERMINAL.has(task.status) || failed);
53
+ }, [task.status, failed]);
54
+ const preview = task.error || task.result || task.preview || (task.status === "completed" ? "Task completed." : "");
55
+ const time = duration(task, now);
56
+ const profile = task.profile === "swarm-explore" ? "Explore" : task.profile === "swarm-task" ? "Task" : "Native task";
57
+ return React.createElement("details", {
58
+ className: "ps-native-task", "data-task-id": task.id, "data-status": task.status, open,
59
+ onToggle: event => { if (event.target === event.currentTarget) setOpen(event.currentTarget.open); },
60
+ style: { "--ps-native-task-accent": colors[task.status] || colors.running },
61
+ },
62
+ React.createElement("summary", {
63
+ onClick: () => { inspected.current = true; },
64
+ onKeyDown: event => { if (["Enter", " "].includes(event.key)) inspected.current = true; },
65
+ },
66
+ React.createElement("span", { className: "ps-native-task-mark", "aria-hidden": true }, MARKS[task.status] || "?"),
67
+ React.createElement("span", { className: "ps-native-task-main" },
68
+ React.createElement("span", { className: "ps-native-task-title" },
69
+ React.createElement("span", { className: "ps-native-task-profile" }, profile),
70
+ task.title === "Native task" ? "Working on delegated request" : task.title),
71
+ preview ? React.createElement("span", { className: "ps-native-task-preview" }, preview.replace(/\s+/g, " ").slice(0, 240)) : null),
72
+ React.createElement("span", { className: "ps-native-task-meta" },
73
+ React.createElement("span", { className: "ps-native-task-status" }, task.telemetryStale ? "Reconnecting" : NATIVE_TASK_LABELS[task.status] || task.status),
74
+ React.createElement("span", null, [time, `${task.toolCalls || 0} ${task.toolCalls === 1 ? "call" : "calls"}`].filter(Boolean).join(" · "))),
75
+ React.createElement("span", { className: "ps-native-task-chevron", "aria-hidden": true }, "›")),
76
+ React.createElement("div", { className: "ps-native-task-detail", onClick: () => { inspected.current = true; } },
77
+ React.createElement("div", { className: "ps-native-task-scope" }, [task.model, task.reasoningEffort, "Same worker"].filter(Boolean).join(" · ")),
78
+ calls.length ? React.createElement("div", {
79
+ ref: viewport, className: "ps-native-task-calls", role: "region", "aria-label": `Tool calls for ${task.title}`, tabIndex: 0,
80
+ onScroll: event => { const node = event.currentTarget; follow.current = node.scrollHeight - node.scrollTop - node.clientHeight <= 24; },
81
+ onWheel: event => { inspected.current = true; if (event.deltaY < 0) follow.current = false; },
82
+ onTouchStart: () => { inspected.current = true; follow.current = false; },
83
+ onFocus: () => { inspected.current = true; },
84
+ }, calls.map(line => React.createElement(ChatCallLine, { key: line.callKey, line }))) :
85
+ React.createElement("p", { className: "ps-native-task-scope" }, task.toolCalls ? "Tool details are not available in this recording." : "Waiting for task activity…"),
86
+ task.result || task.error ? React.createElement("p", { className: "ps-native-task-result" }, task.error || task.result) : null,
87
+ task.recentActivity?.length && !task.calls?.length ? React.createElement("ul", { className: "ps-native-task-activity" },
88
+ task.recentActivity.map((activity, i) => React.createElement("li", { key: i }, activity.message))) : null));
89
+ }
@@ -1,3 +1,4 @@
1
+ import { ChatCallLine } from "./chat-call-line.js";
1
2
  import React from "react";
2
3
  import { FeatureFlagsPanel } from "./feature-flags-panel.js";
3
4
  import { NativeTaskCard } from "./native-task-card.js";
@@ -1380,21 +1381,6 @@ function SystemNoticeLine({ line, theme }) {
1380
1381
  : null);
1381
1382
  }
1382
1383
 
1383
- function ChatCallLine({ line }) {
1384
- const [open, setOpen] = React.useState(false);
1385
- return React.createElement("details", {
1386
- className: "ps-system-notice ps-chat-call",
1387
- "data-call-id": line.callKey,
1388
- onToggle: event => setOpen(event.currentTarget.open),
1389
- },
1390
- React.createElement("summary", { className: "ps-system-notice-summary ps-chat-call-summary" },
1391
- React.createElement("span", { className: "ps-chat-call-tag" }, line.category || "Tool"),
1392
- React.createElement("span", { className: "ps-system-notice-summary-text" }, line.text),
1393
- line.status ? React.createElement("span", { className: `ps-chat-call-status${line.status === "Failed" ? " is-failed" : ""}` }, line.status) : null),
1394
- open ? React.createElement("div", { className: "ps-system-notice-body" },
1395
- line.time ? React.createElement("div", { className: "ps-chat-call-time" }, line.time) : null,
1396
- React.createElement("pre", { className: "ps-chat-call-payload" }, line.body)) : null);
1397
- }
1398
1384
 
1399
1385
  function ChatActivityRun({ calls }) {
1400
1386
  const latest = calls[calls.length - 1] || {};
@@ -5053,8 +5039,28 @@ function useAxisLockedPan(ref, enabled = true) {
5053
5039
  }, [ref, enabled]);
5054
5040
  }
5055
5041
 
5056
- function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = false, listRef = null }) {
5042
+ const SessionSearchControl = React.memo(function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = false, listRef = null }) {
5043
+ // Keep typing local: expensive list filtering and external-store updates
5044
+ // must never be part of the input's immediate render path.
5045
+ const [draft, setDraft] = React.useState(query);
5057
5046
  const [mobileOpen, setMobileOpen] = React.useState(Boolean(query));
5047
+ const timer = React.useRef(null);
5048
+ const published = React.useRef(query);
5049
+ const composing = React.useRef(false);
5050
+ const onQueryRef = React.useRef(onQuery);
5051
+ onQueryRef.current = onQuery;
5052
+ const cancel = () => { clearTimeout(timer.current); timer.current = null; };
5053
+ const publish = value => { cancel(); published.current = value; onQueryRef.current?.(value); };
5054
+ const schedule = value => {
5055
+ cancel();
5056
+ if (!composing.current) timer.current = setTimeout(() => publish(value), 150);
5057
+ };
5058
+ React.useEffect(() => () => clearTimeout(timer.current), []);
5059
+ React.useEffect(() => {
5060
+ // An acknowledgement of our prior edit must not erase newer typing.
5061
+ if (query === published.current) return;
5062
+ cancel(); published.current = query; setDraft(query);
5063
+ }, [query]);
5058
5064
  const inputRef = React.useRef(null);
5059
5065
  React.useEffect(() => {
5060
5066
  if (query) setMobileOpen(true);
@@ -5064,12 +5070,11 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
5064
5070
  requestAnimationFrame(() => inputRef.current?.focus({ preventScroll: true }));
5065
5071
  };
5066
5072
  const closeOrClear = () => {
5067
- if (query) onQuery?.("");
5073
+ if (draft || query) { setDraft(""); publish(""); }
5068
5074
  else setMobileOpen(false);
5069
5075
  };
5070
- const resultLabel = query
5071
- ? `${matchCount} ${matchCount === 1 ? "match" : "matches"}`
5072
- : "";
5076
+ const resultLabel = draft !== query ? "Searching…" : draft
5077
+ ? `${matchCount} ${matchCount === 1 ? "match" : "matches"}` : "";
5073
5078
  return React.createElement("div", {
5074
5079
  className: `ps-session-search${mobileOpen ? " is-open" : ""}`,
5075
5080
  "data-session-search": "true",
@@ -5089,8 +5094,10 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
5089
5094
  inputMode: "search",
5090
5095
  "aria-label": "Find a session",
5091
5096
  placeholder: "Find a session…",
5092
- value: query,
5093
- onChange: (event) => onQuery?.(event.target.value),
5097
+ value: draft,
5098
+ onChange: event => { const value = event.target.value; setDraft(value); schedule(value); },
5099
+ onCompositionStart: () => { composing.current = true; cancel(); },
5100
+ onCompositionEnd: event => { composing.current = false; schedule(event.currentTarget.value); },
5094
5101
  onKeyDown: (event) => {
5095
5102
  if (event.key === "Escape") {
5096
5103
  event.preventDefault();
@@ -5098,10 +5105,9 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
5098
5105
  return;
5099
5106
  }
5100
5107
  if (event.key !== "ArrowDown") return;
5101
- const first = listRef?.current?.querySelector?.(".ps-session-list-button");
5102
- if (!first) return;
5103
5108
  event.preventDefault();
5104
- first.focus({ preventScroll: true });
5109
+ if (draft !== query) publish(draft);
5110
+ requestAnimationFrame(() => listRef?.current?.querySelector?.(".ps-session-list-button")?.focus({ preventScroll: true }));
5105
5111
  },
5106
5112
  }),
5107
5113
  resultLabel ? React.createElement("span", {
@@ -5109,14 +5115,16 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
5109
5115
  role: "status",
5110
5116
  "aria-live": "polite",
5111
5117
  }, resultLabel) : null,
5112
- (query || mobile) ? React.createElement("button", {
5118
+ (draft || mobile) ? React.createElement("button", {
5113
5119
  type: "button",
5114
5120
  className: "ps-session-search-clear",
5115
- "aria-label": query ? "Clear session search" : "Close session search",
5116
- title: query ? "Clear" : "Close",
5121
+ "aria-label": draft ? "Clear session search" : "Close session search",
5122
+ title: draft ? "Clear" : "Close",
5117
5123
  onClick: closeOrClear,
5118
5124
  }, "×") : null));
5119
- }
5125
+ });
5126
+
5127
+ const EMPTY_PICKER_SELECTION = Object.freeze([]);
5120
5128
 
5121
5129
  function SessionPane({ controller, actions = null, panelClassName = "", structuredRows = false, showDetailBox = null, selection = null, actionsOnly = false, actionsHost = null, onAction = null, onDialogChange = null }) {
5122
5130
  // Mobile keeps its inline detail line and normally gets no detail box — a
@@ -5142,25 +5150,25 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
5142
5150
  (state) => Boolean(state.ui.sessionDetailCollapsed),
5143
5151
  );
5144
5152
  const sessionButtonRefs = React.useRef(new Map());
5145
- const viewState = useControllerSelector(controller, (state) => ({
5153
+ const controllerViewState = useControllerSelector(controller, (state) => ({
5146
5154
  branding: state.branding,
5147
- activeSessionId: selection ? selection.sessionId : state.sessions.activeSessionId,
5155
+ activeSessionId: state.sessions.activeSessionId,
5148
5156
  sessionsById: state.sessions.byId,
5149
5157
  sessionsFlat: state.sessions.flat,
5150
- filterQuery: selection ? selection.query || "" : state.sessions.filterQuery || "",
5158
+ filterQuery: state.sessions.filterQuery || "",
5151
5159
  ownerFilter: state.sessions.ownerFilter,
5152
5160
  pinnedIds: state.sessions.pinnedIds,
5153
5161
  manualOrder: state.sessions.manualOrder,
5154
- selectedIds: selection ? [] : state.sessions.selectedIds,
5155
- selectMode: selection ? false : state.sessions.selectMode,
5162
+ selectedIds: state.sessions.selectedIds,
5163
+ selectMode: state.sessions.selectMode,
5156
5164
  auth: state.auth,
5157
5165
  connectionMode: state.connection?.mode || "local",
5158
5166
  modalOpen: Boolean(state.ui.modal),
5159
- focused: selection ? true : state.ui.focusRegion === "sessions",
5167
+ focused: state.ui.focusRegion === "sessions",
5160
5168
  // Clicking empty space clears the list highlight; the row VM reads it,
5161
5169
  // so the reconstruction below must carry it or the click does nothing
5162
5170
  // visible (the same omission that blinded the Node Map).
5163
- listDeselected: selection ? !selection.sessionId : Boolean(state.sessions.listDeselected),
5171
+ listDeselected: Boolean(state.sessions.listDeselected),
5164
5172
  // The canvas markers read these. This synthetic state is exactly the
5165
5173
  // trap the branding comment below describes: omit a slice here and
5166
5174
  // every row computes as if it were empty — the markers were null on
@@ -5173,6 +5181,14 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
5173
5181
  // "waiting".
5174
5182
  budgetPaused: state.budget?.paused,
5175
5183
  }), shallowEqualObject);
5184
+ // Picker state is local React state, not controller state. Reading these
5185
+ // props inside the subscription selector delays changes until the next
5186
+ // unrelated store notification (sometimes seconds later).
5187
+ const viewState = selection ? { ...controllerViewState,
5188
+ activeSessionId: selection.sessionId, filterQuery: selection.query || "",
5189
+ selectedIds: EMPTY_PICKER_SELECTION, selectMode: false, focused: true,
5190
+ listDeselected: !selection.sessionId,
5191
+ } : controllerViewState;
5176
5192
  const computedRows = React.useMemo(() => selectSessionRows({
5177
5193
  sessions: {
5178
5194
  activeSessionId: viewState.activeSessionId,
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-CS-m-Pv3.js";import{p as f}from"./chunk-JWPE2WC7-By7oiTbd.js";import{_ as n,l as o}from"./mermaid.core-BEG_GOf7.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CUvcvCFo.js";import"./pilotswarm-BNTnbu9f.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-MOJQB5TN-CDyGPb8L.js";import{p as f}from"./chunk-JWPE2WC7-AhysI3TD.js";import{_ as n,l as o}from"./mermaid.core-BPC8y2lr.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CHVeQsGv.js";import"./pilotswarm-BnfVgmru.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-BEG_GOf7.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-BPC8y2lr.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};