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.
- package/package.json +2 -2
- package/ui/core/src/history.js +3 -1
- package/ui/core/src/native-tasks.js +46 -2
- package/ui/core/src/selectors.js +40 -15
- package/ui/react/src/chat-call-line.js +17 -0
- package/ui/react/src/native-task-card.js +53 -23
- package/ui/react/src/web-app.js +52 -36
- package/web/dist/assets/{abnfDiagram-VRR7QNED-DCEEpIGf.js → abnfDiagram-VRR7QNED-CidJDJrY.js} +1 -1
- package/web/dist/assets/{arc-_RJw0dJ3.js → arc-BDO1TDjs.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-Bze_PsYG.js → architectureDiagram-ZJ3FMSHR-BIcgz3Aa.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-CZaMO9H-.js → blockDiagram-677ZJIJ3-CWtdYLva.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-Dzr58V1d.js → c4Diagram-LMCZKHZV-u_IOLAS7.js} +1 -1
- package/web/dist/assets/channel-KxoOVq0K.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-1IO7uTFx.js → chunk-2Q5K7J3B-daWW1UxL.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-DKdpRP0l.js → chunk-32BRIVSS-DyxnM56K.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-CxyhZOh5.js → chunk-5VM5RSS4-D7taC4Nx.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-DWY7moCs.js → chunk-EX3LRPZG-BWo08pDw.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-By7oiTbd.js → chunk-JWPE2WC7-AhysI3TD.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-CS-m-Pv3.js → chunk-MOJQB5TN-CDyGPb8L.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-Cxykz4-E.js → chunk-RYQCIY6F-RhKa7iem.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-Dwl0aU9m.js → chunk-V7JOEXUC-DLgws19l.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-BERWiLR7.js → chunk-VR4S4FIN-CyLmmpZk.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-CZ0e721z.js → chunk-XXDRQBXY-DYN0KnEU.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-B6yEKJ21.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-B6yEKJ21.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-RLgoKX1J.js → cose-bilkent-JH36ORCC-62MpINYU.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-CUvcvCFo.js → cynefin-VYW2F7L2-CHVeQsGv.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-D2ML_npa.js → cynefinDiagram-TSTJHNR4-BYgzn_3A.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-BHG6-avE.js → dagre-VKFMJZFB-C3qJqyHj.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-ynOb8q0h.js → diagram-FQU43EPY-BBYvv2Hx.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-BLHAADd0.js → diagram-G47NLZAW-1Ca1QwqV.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-DwOMd4DW.js → diagram-NH7WQ7WH-CicNpuah.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-DZWnpqT9.js → diagram-OA4YK3LP-BDGMGAu8.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-BMcvO3Pf.js → diagram-WEI45ONY-EgaBHcZC.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-CRX9h0gP.js → ebnfDiagram-CCIWWBDH-BEGQ-CpA.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-Con2S52S.js → erDiagram-Q63AITRT-BifquFiz.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-wg4unvdR.js → flowDiagram-23GEKE2U-BOEV0nau.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-CAg65Xfj.js → ganttDiagram-NO4QXBWP-Die6C1uw.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-5u02gmfN.js → gitGraphDiagram-IHSO6WYX-BS6qOLxN.js} +1 -1
- package/web/dist/assets/index-CCniDa-9.css +1 -0
- package/web/dist/assets/{index-DzjecAo8.js → index-DpkfY3jc.js} +2 -2
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-DW830L4J.js → infoDiagram-FWYZ7A6U-C3dgkkDc.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-6Qr30UBj.js → ishikawaDiagram-FXEZZL3T-BmGRDlL-.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-BHCjdAv1.js → journeyDiagram-5HDEW3XC-De0y-2Pp.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-PGpXvhY7.js → kanban-definition-HUTT4EX6-CPVl9fbH.js} +1 -1
- package/web/dist/assets/{linear-CuN5Qi_I.js → linear-BwcW14FN.js} +1 -1
- package/web/dist/assets/{mermaid.core-BEG_GOf7.js → mermaid.core-BPC8y2lr.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-Bbi2gb0f.js → mindmap-definition-LN4V7U3C-CmTjYZ6-.js} +1 -1
- package/web/dist/assets/{papaparse.min-LDhOsJ62.js → papaparse.min-DwUBIiJJ.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-IZ3AowOt.js → pegDiagram-2B236MQR-DI77hWU9.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-QnG3Rlhe.js → pieDiagram-ENE6RG2P-CQL62GJk.js} +1 -1
- package/web/dist/assets/pilotswarm-BnfVgmru.js +109 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-BIB7xhGf.js → quadrantDiagram-ABIIQ3AL-CQoKIYFZ.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-CHbggWfd.js → railroadDiagram-RFXS5EU6-B2KkUNRk.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-CgNGJVBn.js → requirementDiagram-TGXJPOKE-Dgl152x0.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-B1GfGCwn.js → sankeyDiagram-HTMAVEWB-B-SjWvvt.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-D-Bfj-RU.js → sequenceDiagram-DBY2YBRQ-CuuRcXdJ.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-Ca-mVfMN.js → sizeCapture-X5ZJPWSS-TzEpZfA7.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-5gIoJ_8A.js → stateDiagram-2N3HPSRC-XAi55Ttk.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CXVciPM_.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-HxN6_3nA.js → swimlanes-5IMT3BWC-C6ATJwDO.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-Dk-VTEgD.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-CSkNwYwY.js → timeline-definition-FHXFAJF6-DhUjhdEH.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-o6qvAiNl.js → vennDiagram-L72KCM5P-CxoeZ7Ri.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-HcUO3YZZ.js → wardleyDiagram-EHGQE667-ChgUaxkB.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-DmNJJPi3.js → xychartDiagram-FW5EYKEG-iV0ACrP1.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/dist/assets/channel-CHAZ3LVB.js +0 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-CXv3ioyD.js +0 -1
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-CXv3ioyD.js +0 -1
- package/web/dist/assets/index-BT3MiUPE.css +0 -1
- package/web/dist/assets/pilotswarm-BNTnbu9f.js +0 -109
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-C_IKdqOV.js +0 -1
- 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.
|
|
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.
|
|
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"
|
package/ui/core/src/history.js
CHANGED
|
@@ -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 ||
|
|
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
|
|
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.
|
package/ui/core/src/selectors.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
+
}
|
package/ui/react/src/web-app.js
CHANGED
|
@@ -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)
|
|
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:
|
|
5093
|
-
onChange:
|
|
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
|
-
|
|
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
|
-
(
|
|
5118
|
+
(draft || mobile) ? React.createElement("button", {
|
|
5113
5119
|
type: "button",
|
|
5114
5120
|
className: "ps-session-search-clear",
|
|
5115
|
-
"aria-label":
|
|
5116
|
-
title:
|
|
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
|
|
5153
|
+
const controllerViewState = useControllerSelector(controller, (state) => ({
|
|
5146
5154
|
branding: state.branding,
|
|
5147
|
-
activeSessionId:
|
|
5155
|
+
activeSessionId: state.sessions.activeSessionId,
|
|
5148
5156
|
sessionsById: state.sessions.byId,
|
|
5149
5157
|
sessionsFlat: state.sessions.flat,
|
|
5150
|
-
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:
|
|
5155
|
-
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:
|
|
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:
|
|
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,
|
package/web/dist/assets/{abnfDiagram-VRR7QNED-DCEEpIGf.js → abnfDiagram-VRR7QNED-CidJDJrY.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-
|
|
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-
|
|
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};
|