pilotswarm 0.5.69 → 0.5.71
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/controller.js +3 -1
- package/ui/core/src/history.js +3 -1
- package/ui/core/src/moa.js +2 -2
- package/ui/core/src/native-tasks.js +46 -2
- package/ui/core/src/reducer.js +14 -2
- package/ui/core/src/selectors.js +41 -16
- package/ui/core/src/session-sort.js +45 -0
- package/ui/core/src/state.js +3 -0
- 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 +100 -48
- package/web/dist/assets/{abnfDiagram-VRR7QNED-DCEEpIGf.js → abnfDiagram-VRR7QNED-C1caNr4U.js} +1 -1
- package/web/dist/assets/{arc-_RJw0dJ3.js → arc-BufdFJYK.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-Bze_PsYG.js → architectureDiagram-ZJ3FMSHR-C0vQblUK.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-CZaMO9H-.js → blockDiagram-677ZJIJ3-B6PYWI9u.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-Dzr58V1d.js → c4Diagram-LMCZKHZV-DFoaVeMm.js} +1 -1
- package/web/dist/assets/channel-CDzPwSI9.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-1IO7uTFx.js → chunk-2Q5K7J3B-CxFBb-8y.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-DKdpRP0l.js → chunk-32BRIVSS-DO1G8AVc.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-CxyhZOh5.js → chunk-5VM5RSS4-spE4bKSd.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-DWY7moCs.js → chunk-EX3LRPZG-Bc_eUP5F.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-By7oiTbd.js → chunk-JWPE2WC7-CGM2GAMX.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-CS-m-Pv3.js → chunk-MOJQB5TN-CHdrVT1z.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-Cxykz4-E.js → chunk-RYQCIY6F-BWJK7-AW.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-Dwl0aU9m.js → chunk-V7JOEXUC-D8tgpQwK.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-BERWiLR7.js → chunk-VR4S4FIN-BP86JfVu.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-CZ0e721z.js → chunk-XXDRQBXY-Ctq_LUrs.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-DdcABn-U.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-DdcABn-U.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-RLgoKX1J.js → cose-bilkent-JH36ORCC-DNvC4thT.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-CUvcvCFo.js → cynefin-VYW2F7L2-3zVj2GvI.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-D2ML_npa.js → cynefinDiagram-TSTJHNR4-DQbITfsJ.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-BHG6-avE.js → dagre-VKFMJZFB-BkGAcDyj.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-ynOb8q0h.js → diagram-FQU43EPY-D3lsgelm.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-BLHAADd0.js → diagram-G47NLZAW-C2rO9e3d.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-DwOMd4DW.js → diagram-NH7WQ7WH-DJBwtT8q.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-DZWnpqT9.js → diagram-OA4YK3LP-C-SAwEHZ.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-BMcvO3Pf.js → diagram-WEI45ONY-BpXMlmKz.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-CRX9h0gP.js → ebnfDiagram-CCIWWBDH-DwxUgEmE.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-Con2S52S.js → erDiagram-Q63AITRT-DNZMCmYz.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-wg4unvdR.js → flowDiagram-23GEKE2U-CUlGtnWV.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-CAg65Xfj.js → ganttDiagram-NO4QXBWP-DCj6zkyt.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-5u02gmfN.js → gitGraphDiagram-IHSO6WYX-Q6UP_dgi.js} +1 -1
- package/web/dist/assets/index-23y0f1it.js +24 -0
- package/web/dist/assets/index-BXR-II2L.css +1 -0
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-DW830L4J.js → infoDiagram-FWYZ7A6U-Cwn8XNQT.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-6Qr30UBj.js → ishikawaDiagram-FXEZZL3T-BaMvGBAo.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-BHCjdAv1.js → journeyDiagram-5HDEW3XC-DK95FJ0t.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-PGpXvhY7.js → kanban-definition-HUTT4EX6-C6W6RJLm.js} +1 -1
- package/web/dist/assets/{linear-CuN5Qi_I.js → linear-Un37Oyxr.js} +1 -1
- package/web/dist/assets/{mermaid.core-BEG_GOf7.js → mermaid.core-i8uqvLPa.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-Bbi2gb0f.js → mindmap-definition-LN4V7U3C-d_cgq1KW.js} +1 -1
- package/web/dist/assets/{papaparse.min-LDhOsJ62.js → papaparse.min-BiJEkQ8f.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-IZ3AowOt.js → pegDiagram-2B236MQR-5QRWM5AP.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-QnG3Rlhe.js → pieDiagram-ENE6RG2P-VIZXsjFV.js} +1 -1
- package/web/dist/assets/pilotswarm-D7Q48waO.js +109 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-BIB7xhGf.js → quadrantDiagram-ABIIQ3AL-DMOx841b.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-CHbggWfd.js → railroadDiagram-RFXS5EU6-lTWzjdcd.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-CgNGJVBn.js → requirementDiagram-TGXJPOKE-BE5SpiNy.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-B1GfGCwn.js → sankeyDiagram-HTMAVEWB-C3LYWQTA.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-D-Bfj-RU.js → sequenceDiagram-DBY2YBRQ-BTCp88tQ.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-Ca-mVfMN.js → sizeCapture-X5ZJPWSS-Ppzj8n5l.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-5gIoJ_8A.js → stateDiagram-2N3HPSRC-Ch_iZ_cQ.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-BbJN7t8_.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-HxN6_3nA.js → swimlanes-5IMT3BWC-BX4-Oeby.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-0UA1VebA.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-CSkNwYwY.js → timeline-definition-FHXFAJF6-B1l-6l6u.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-o6qvAiNl.js → vennDiagram-L72KCM5P-Grpa6wFZ.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-HcUO3YZZ.js → wardleyDiagram-EHGQE667-B5bXnFlL.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-DmNJJPi3.js → xychartDiagram-FW5EYKEG-BkELQtgc.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/index-DzjecAo8.js +0 -24
- 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/ui/react/src/web-app.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { normalizeSessionSortMode, normalizeSessionUsage } from "../../core/src/session-sort.js";
|
|
2
|
+
import { ChatCallLine } from "./chat-call-line.js";
|
|
1
3
|
import React from "react";
|
|
2
4
|
import { FeatureFlagsPanel } from "./feature-flags-panel.js";
|
|
3
5
|
import { NativeTaskCard } from "./native-task-card.js";
|
|
@@ -290,6 +292,8 @@ function clearBrowserPreferenceCache() {
|
|
|
290
292
|
function normalizeProfileSettings(settings) {
|
|
291
293
|
const candidate = settings && typeof settings === "object" && !Array.isArray(settings) ? settings : {};
|
|
292
294
|
const normalized = {};
|
|
295
|
+
if (hasOwn(candidate, "sessionSortMode")) normalized.sessionSortMode = normalizeSessionSortMode(candidate.sessionSortMode);
|
|
296
|
+
if (hasOwn(candidate, "sessionUsedAt")) normalized.sessionUsedAt = normalizeSessionUsage(candidate.sessionUsedAt);
|
|
293
297
|
if (hasOwn(candidate, "moa")) normalized.moa = normalizeMoa(candidate.moa);
|
|
294
298
|
if (typeof candidate.themeId === "string" && candidate.themeId.trim()) {
|
|
295
299
|
normalized.themeId = candidate.themeId.trim();
|
|
@@ -440,7 +444,7 @@ function profileViewState(root) {
|
|
|
440
444
|
return {
|
|
441
445
|
...root.ui, ...root.ui.layout,
|
|
442
446
|
ownerFilter: root.sessions.ownerFilter, pinnedIds: root.sessions.pinnedIds,
|
|
443
|
-
manualOrder: root.sessions.manualOrder, collapsedSessionIds: root.sessions.collapsedIds,
|
|
447
|
+
manualOrder: root.sessions.manualOrder, sessionSortMode: root.sessions.sortMode, sessionUsedAt: root.sessions.usedAt, collapsedSessionIds: root.sessions.collapsedIds,
|
|
444
448
|
activeSessionId: root.sessions.activeSessionId, canvasPrefs: root.canvas?.prefs,
|
|
445
449
|
};
|
|
446
450
|
}
|
|
@@ -463,6 +467,8 @@ function profileSettingsFromViewState(state, preservedOtherTouchScale = null, pr
|
|
|
463
467
|
},
|
|
464
468
|
pinnedSessionIds: state.pinnedIds,
|
|
465
469
|
sessionOrder: state.manualOrder,
|
|
470
|
+
sessionSortMode: state.sessionSortMode,
|
|
471
|
+
sessionUsedAt: state.sessionUsedAt,
|
|
466
472
|
collapsedSessionIds: state.collapsedSessionIds,
|
|
467
473
|
activeSessionId: state.activeSessionId,
|
|
468
474
|
// rightPaneMode describes the DESKTOP right column; a phone has no
|
|
@@ -527,6 +533,8 @@ function buildDefaultProfileSettingsFromState(state, preservedOtherTouchScale =
|
|
|
527
533
|
layoutAdjustments: state?.ui?.layout,
|
|
528
534
|
pinnedSessionIds: state?.sessions?.pinnedIds,
|
|
529
535
|
sessionOrder: state?.sessions?.manualOrder,
|
|
536
|
+
sessionSortMode: state?.sessions?.sortMode,
|
|
537
|
+
sessionUsedAt: state?.sessions?.usedAt,
|
|
530
538
|
collapsedSessionIds: state?.sessions?.collapsedIds,
|
|
531
539
|
activeSessionId: state?.sessions?.activeSessionId,
|
|
532
540
|
...(isNarrowViewport()
|
|
@@ -574,6 +582,8 @@ function materializeProfileSettings(remoteSettings, defaults) {
|
|
|
574
582
|
// here is DROPPED at startup — and the save effect then writes the
|
|
575
583
|
// empty value straight back over the stored one. Leaving sessionOrder
|
|
576
584
|
// out made every placement survive exactly until the next reload.
|
|
585
|
+
sessionSortMode: normalizedRemote.sessionSortMode ?? normalizedDefaults.sessionSortMode,
|
|
586
|
+
sessionUsedAt: normalizedRemote.sessionUsedAt ?? normalizedDefaults.sessionUsedAt,
|
|
577
587
|
sessionOrder: hasOwn(normalizedRemote, "sessionOrder")
|
|
578
588
|
? normalizedRemote.sessionOrder
|
|
579
589
|
: normalizedDefaults.sessionOrder,
|
|
@@ -1380,21 +1390,6 @@ function SystemNoticeLine({ line, theme }) {
|
|
|
1380
1390
|
: null);
|
|
1381
1391
|
}
|
|
1382
1392
|
|
|
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
1393
|
|
|
1399
1394
|
function ChatActivityRun({ calls }) {
|
|
1400
1395
|
const latest = calls[calls.length - 1] || {};
|
|
@@ -2044,6 +2039,10 @@ function ArtifactLink({ artifactRef }) {
|
|
|
2044
2039
|
*/
|
|
2045
2040
|
function openArtifactFromChat(controller, sessionId, filename) {
|
|
2046
2041
|
if (!controller?.revealArtifact) return;
|
|
2042
|
+
if (controller.openChatArtifact) {
|
|
2043
|
+
Promise.resolve(controller.openChatArtifact(sessionId, filename)).catch(() => {});
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2047
2046
|
const isPhone = typeof window !== "undefined"
|
|
2048
2047
|
&& typeof window.matchMedia === "function"
|
|
2049
2048
|
&& window.matchMedia("(max-width: 920px)").matches;
|
|
@@ -5053,8 +5052,28 @@ function useAxisLockedPan(ref, enabled = true) {
|
|
|
5053
5052
|
}, [ref, enabled]);
|
|
5054
5053
|
}
|
|
5055
5054
|
|
|
5056
|
-
function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = false, listRef = null }) {
|
|
5055
|
+
const SessionSearchControl = React.memo(function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = false, listRef = null }) {
|
|
5056
|
+
// Keep typing local: expensive list filtering and external-store updates
|
|
5057
|
+
// must never be part of the input's immediate render path.
|
|
5058
|
+
const [draft, setDraft] = React.useState(query);
|
|
5057
5059
|
const [mobileOpen, setMobileOpen] = React.useState(Boolean(query));
|
|
5060
|
+
const timer = React.useRef(null);
|
|
5061
|
+
const published = React.useRef(query);
|
|
5062
|
+
const composing = React.useRef(false);
|
|
5063
|
+
const onQueryRef = React.useRef(onQuery);
|
|
5064
|
+
onQueryRef.current = onQuery;
|
|
5065
|
+
const cancel = () => { clearTimeout(timer.current); timer.current = null; };
|
|
5066
|
+
const publish = value => { cancel(); published.current = value; onQueryRef.current?.(value); };
|
|
5067
|
+
const schedule = value => {
|
|
5068
|
+
cancel();
|
|
5069
|
+
if (!composing.current) timer.current = setTimeout(() => publish(value), 150);
|
|
5070
|
+
};
|
|
5071
|
+
React.useEffect(() => () => clearTimeout(timer.current), []);
|
|
5072
|
+
React.useEffect(() => {
|
|
5073
|
+
// An acknowledgement of our prior edit must not erase newer typing.
|
|
5074
|
+
if (query === published.current) return;
|
|
5075
|
+
cancel(); published.current = query; setDraft(query);
|
|
5076
|
+
}, [query]);
|
|
5058
5077
|
const inputRef = React.useRef(null);
|
|
5059
5078
|
React.useEffect(() => {
|
|
5060
5079
|
if (query) setMobileOpen(true);
|
|
@@ -5064,12 +5083,11 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
|
|
|
5064
5083
|
requestAnimationFrame(() => inputRef.current?.focus({ preventScroll: true }));
|
|
5065
5084
|
};
|
|
5066
5085
|
const closeOrClear = () => {
|
|
5067
|
-
if (query)
|
|
5086
|
+
if (draft || query) { setDraft(""); publish(""); }
|
|
5068
5087
|
else setMobileOpen(false);
|
|
5069
5088
|
};
|
|
5070
|
-
const resultLabel = query
|
|
5071
|
-
? `${matchCount} ${matchCount === 1 ? "match" : "matches"}`
|
|
5072
|
-
: "";
|
|
5089
|
+
const resultLabel = draft !== query ? "Searching…" : draft
|
|
5090
|
+
? `${matchCount} ${matchCount === 1 ? "match" : "matches"}` : "";
|
|
5073
5091
|
return React.createElement("div", {
|
|
5074
5092
|
className: `ps-session-search${mobileOpen ? " is-open" : ""}`,
|
|
5075
5093
|
"data-session-search": "true",
|
|
@@ -5089,8 +5107,10 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
|
|
|
5089
5107
|
inputMode: "search",
|
|
5090
5108
|
"aria-label": "Find a session",
|
|
5091
5109
|
placeholder: "Find a session…",
|
|
5092
|
-
value:
|
|
5093
|
-
onChange:
|
|
5110
|
+
value: draft,
|
|
5111
|
+
onChange: event => { const value = event.target.value; setDraft(value); schedule(value); },
|
|
5112
|
+
onCompositionStart: () => { composing.current = true; cancel(); },
|
|
5113
|
+
onCompositionEnd: event => { composing.current = false; schedule(event.currentTarget.value); },
|
|
5094
5114
|
onKeyDown: (event) => {
|
|
5095
5115
|
if (event.key === "Escape") {
|
|
5096
5116
|
event.preventDefault();
|
|
@@ -5098,10 +5118,9 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
|
|
|
5098
5118
|
return;
|
|
5099
5119
|
}
|
|
5100
5120
|
if (event.key !== "ArrowDown") return;
|
|
5101
|
-
const first = listRef?.current?.querySelector?.(".ps-session-list-button");
|
|
5102
|
-
if (!first) return;
|
|
5103
5121
|
event.preventDefault();
|
|
5104
|
-
|
|
5122
|
+
if (draft !== query) publish(draft);
|
|
5123
|
+
requestAnimationFrame(() => listRef?.current?.querySelector?.(".ps-session-list-button")?.focus({ preventScroll: true }));
|
|
5105
5124
|
},
|
|
5106
5125
|
}),
|
|
5107
5126
|
resultLabel ? React.createElement("span", {
|
|
@@ -5109,14 +5128,16 @@ function SessionSearchControl({ query = "", onQuery, matchCount = 0, mobile = fa
|
|
|
5109
5128
|
role: "status",
|
|
5110
5129
|
"aria-live": "polite",
|
|
5111
5130
|
}, resultLabel) : null,
|
|
5112
|
-
(
|
|
5131
|
+
(draft || mobile) ? React.createElement("button", {
|
|
5113
5132
|
type: "button",
|
|
5114
5133
|
className: "ps-session-search-clear",
|
|
5115
|
-
"aria-label":
|
|
5116
|
-
title:
|
|
5134
|
+
"aria-label": draft ? "Clear session search" : "Close session search",
|
|
5135
|
+
title: draft ? "Clear" : "Close",
|
|
5117
5136
|
onClick: closeOrClear,
|
|
5118
5137
|
}, "×") : null));
|
|
5119
|
-
}
|
|
5138
|
+
});
|
|
5139
|
+
|
|
5140
|
+
const EMPTY_PICKER_SELECTION = Object.freeze([]);
|
|
5120
5141
|
|
|
5121
5142
|
function SessionPane({ controller, actions = null, panelClassName = "", structuredRows = false, showDetailBox = null, selection = null, actionsOnly = false, actionsHost = null, onAction = null, onDialogChange = null }) {
|
|
5122
5143
|
// Mobile keeps its inline detail line and normally gets no detail box — a
|
|
@@ -5142,25 +5163,27 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
|
|
|
5142
5163
|
(state) => Boolean(state.ui.sessionDetailCollapsed),
|
|
5143
5164
|
);
|
|
5144
5165
|
const sessionButtonRefs = React.useRef(new Map());
|
|
5145
|
-
const
|
|
5166
|
+
const controllerViewState = useControllerSelector(controller, (state) => ({
|
|
5146
5167
|
branding: state.branding,
|
|
5147
|
-
activeSessionId:
|
|
5168
|
+
activeSessionId: state.sessions.activeSessionId,
|
|
5148
5169
|
sessionsById: state.sessions.byId,
|
|
5149
5170
|
sessionsFlat: state.sessions.flat,
|
|
5150
|
-
filterQuery:
|
|
5171
|
+
filterQuery: state.sessions.filterQuery || "",
|
|
5151
5172
|
ownerFilter: state.sessions.ownerFilter,
|
|
5152
5173
|
pinnedIds: state.sessions.pinnedIds,
|
|
5153
5174
|
manualOrder: state.sessions.manualOrder,
|
|
5154
|
-
|
|
5155
|
-
|
|
5175
|
+
sortMode: state.sessions.sortMode,
|
|
5176
|
+
sortSnapshot: state.sessions.sortSnapshot,
|
|
5177
|
+
selectedIds: state.sessions.selectedIds,
|
|
5178
|
+
selectMode: state.sessions.selectMode,
|
|
5156
5179
|
auth: state.auth,
|
|
5157
5180
|
connectionMode: state.connection?.mode || "local",
|
|
5158
5181
|
modalOpen: Boolean(state.ui.modal),
|
|
5159
|
-
focused:
|
|
5182
|
+
focused: state.ui.focusRegion === "sessions",
|
|
5160
5183
|
// Clicking empty space clears the list highlight; the row VM reads it,
|
|
5161
5184
|
// so the reconstruction below must carry it or the click does nothing
|
|
5162
5185
|
// visible (the same omission that blinded the Node Map).
|
|
5163
|
-
listDeselected:
|
|
5186
|
+
listDeselected: Boolean(state.sessions.listDeselected),
|
|
5164
5187
|
// The canvas markers read these. This synthetic state is exactly the
|
|
5165
5188
|
// trap the branding comment below describes: omit a slice here and
|
|
5166
5189
|
// every row computes as if it were empty — the markers were null on
|
|
@@ -5173,6 +5196,14 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
|
|
|
5173
5196
|
// "waiting".
|
|
5174
5197
|
budgetPaused: state.budget?.paused,
|
|
5175
5198
|
}), shallowEqualObject);
|
|
5199
|
+
// Picker state is local React state, not controller state. Reading these
|
|
5200
|
+
// props inside the subscription selector delays changes until the next
|
|
5201
|
+
// unrelated store notification (sometimes seconds later).
|
|
5202
|
+
const viewState = selection ? { ...controllerViewState,
|
|
5203
|
+
activeSessionId: selection.sessionId, filterQuery: selection.query || "",
|
|
5204
|
+
selectedIds: EMPTY_PICKER_SELECTION, selectMode: false, focused: true,
|
|
5205
|
+
listDeselected: !selection.sessionId,
|
|
5206
|
+
} : controllerViewState;
|
|
5176
5207
|
const computedRows = React.useMemo(() => selectSessionRows({
|
|
5177
5208
|
sessions: {
|
|
5178
5209
|
activeSessionId: viewState.activeSessionId,
|
|
@@ -5182,6 +5213,8 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
|
|
|
5182
5213
|
ownerFilter: viewState.ownerFilter,
|
|
5183
5214
|
pinnedIds: viewState.pinnedIds,
|
|
5184
5215
|
manualOrder: viewState.manualOrder,
|
|
5216
|
+
sortMode: viewState.sortMode,
|
|
5217
|
+
sortSnapshot: viewState.sortSnapshot,
|
|
5185
5218
|
selectedIds: viewState.selectedIds,
|
|
5186
5219
|
selectMode: viewState.selectMode,
|
|
5187
5220
|
listDeselected: viewState.listDeselected,
|
|
@@ -5200,7 +5233,7 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
|
|
|
5200
5233
|
prefs: viewState.canvasPrefs,
|
|
5201
5234
|
},
|
|
5202
5235
|
budget: { paused: viewState.budgetPaused },
|
|
5203
|
-
}), [viewState.activeSessionId, viewState.auth, viewState.branding, viewState.budgetPaused, viewState.canvasBySessionId, viewState.canvasPrefs, viewState.connectionMode, viewState.filterQuery, viewState.listDeselected, viewState.ownerFilter, viewState.pinnedIds, viewState.manualOrder, viewState.selectedIds, viewState.selectMode, viewState.sessionsById, viewState.sessionsFlat]);
|
|
5236
|
+
}), [viewState.activeSessionId, viewState.auth, viewState.branding, viewState.budgetPaused, viewState.canvasBySessionId, viewState.canvasPrefs, viewState.connectionMode, viewState.filterQuery, viewState.listDeselected, viewState.ownerFilter, viewState.pinnedIds, viewState.manualOrder, viewState.sortMode, viewState.sortSnapshot, viewState.selectedIds, viewState.selectMode, viewState.sessionsById, viewState.sessionsFlat]);
|
|
5204
5237
|
// Hold the previous rows when a poll produced identical output.
|
|
5205
5238
|
const rows = useStableValue(computedRows);
|
|
5206
5239
|
const searchScrollRef = React.useRef({ top: 0, left: 0, restore: false });
|
|
@@ -5975,15 +6008,31 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
|
|
|
5975
6008
|
setRef: setSessionButtonRef,
|
|
5976
6009
|
// Drag-to-folder is a fine-pointer gesture: arming it on
|
|
5977
6010
|
// touch hijacks the finger that should be scrolling the list.
|
|
5978
|
-
drag: selection || touchInput ? null : dragHandlers,
|
|
6011
|
+
drag: selection || touchInput || viewState.sortMode !== "saved" ? null : dragHandlers,
|
|
5979
6012
|
}))),
|
|
5980
|
-
React.createElement(
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
6013
|
+
React.createElement("div", { className: "ps-session-find-controls" },
|
|
6014
|
+
React.createElement("div", { className: "ps-session-sort-controls" },
|
|
6015
|
+
React.createElement("div", { className: "ps-session-sort-modes", role: "group", "aria-label": "Session sort order" },
|
|
6016
|
+
...[["used", "Recently used", "M12 8v4l3 2", true], ["updated", "Recently updated", "M3 12h4l3-7 4 14 3-7h4"], ["saved", "Saved order", "M6 3h12v18l-6-4-6 4Z"]].map(([mode, label, path, clock]) => React.createElement(IconButton, {
|
|
6017
|
+
key: mode, label, className: "ps-session-sort-button", active: (viewState.sortMode || "saved") === mode, pressed: (viewState.sortMode || "saved") === mode,
|
|
6018
|
+
icon: React.createElement("svg", { viewBox: "0 0 24 24", width: 18, height: 18, fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true }, clock ? React.createElement("circle", { cx: 12, cy: 12, r: 9 }) : null, React.createElement("path", { d: path })),
|
|
6019
|
+
onClick: () => controller.dispatch({ type: "sessions/sortMode", mode }),
|
|
6020
|
+
}))),
|
|
6021
|
+
React.createElement(IconButton, {
|
|
6022
|
+
label: "Refresh session order", className: "ps-session-sort-refresh",
|
|
6023
|
+
icon: React.createElement("svg", { viewBox: "0 0 24 24", width: 18, height: 18, fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true }, React.createElement("path", { d: "M20 7v5h-5M20 12a8 8 0 1 0-2 5M20 7v5" })),
|
|
6024
|
+
onClick: async () => {
|
|
6025
|
+
try { await controller.refreshSessions(); controller.dispatch({ type: "sessions/refreshSort" }); }
|
|
6026
|
+
catch { controller.dispatch({ type: "ui/status", text: "Could not refresh sessions. Try again." }); }
|
|
6027
|
+
},
|
|
6028
|
+
})),
|
|
6029
|
+
React.createElement(SessionSearchControl, {
|
|
6030
|
+
query: viewState.filterQuery,
|
|
6031
|
+
onQuery: setSearchQuery,
|
|
6032
|
+
matchCount: searchMatchCount,
|
|
6033
|
+
mobile: isMobilePane,
|
|
6034
|
+
listRef: sessionListRef,
|
|
6035
|
+
})),
|
|
5987
6036
|
(showDetailBox === null ? !isMobilePane : showDetailBox)
|
|
5988
6037
|
? React.createElement(SessionDetailBox, {
|
|
5989
6038
|
session: activeSession,
|
|
@@ -9365,7 +9414,7 @@ function StatusStrip({ controller }) {
|
|
|
9365
9414
|
// (hold ~450ms to see the label, release to dismiss — the long-press does not
|
|
9366
9415
|
// fire onClick). aria-label carries the meaning for assistive tech.
|
|
9367
9416
|
const ICON_HOVER_TOOLTIP_MS = 1000;
|
|
9368
|
-
function IconButton({ icon, label, onClick, disabled = false, active = false, className = "ps-toolbar-button" }) {
|
|
9417
|
+
function IconButton({ icon, label, onClick, disabled = false, active = false, pressed = undefined, className = "ps-toolbar-button" }) {
|
|
9369
9418
|
// The tooltip is portaled to <body> so it escapes the toolbar/pane
|
|
9370
9419
|
// overflow-clipping and stacking contexts (nested tooltips were hidden
|
|
9371
9420
|
// behind, or bled through by, the panes). Coordinates are computed from
|
|
@@ -9508,6 +9557,7 @@ function IconButton({ icon, label, onClick, disabled = false, active = false, cl
|
|
|
9508
9557
|
onClick: handleClick,
|
|
9509
9558
|
disabled,
|
|
9510
9559
|
"aria-label": label,
|
|
9560
|
+
"aria-pressed": pressed,
|
|
9511
9561
|
onPointerEnter: startHover,
|
|
9512
9562
|
onPointerLeave: endHover,
|
|
9513
9563
|
onPointerDown: startPress,
|
|
@@ -14650,6 +14700,8 @@ export function PilotSwarmWebApp({ controller, suspended = false, moa = null })
|
|
|
14650
14700
|
// never persists — the reducer would reorder the list correctly and
|
|
14651
14701
|
// the placement would vanish on reload.
|
|
14652
14702
|
manualOrder: rootState.sessions.manualOrder,
|
|
14703
|
+
sessionSortMode: rootState.sessions.sortMode,
|
|
14704
|
+
sessionUsedAt: rootState.sessions.usedAt,
|
|
14653
14705
|
// Pass the live Set reference here so shallow-equal sees the same
|
|
14654
14706
|
// identity across renders (a fresh array would break memoization).
|
|
14655
14707
|
// Conversion to a sorted array happens inside `normalizeProfileSettings`.
|
|
@@ -14991,7 +15043,7 @@ export function PilotSwarmWebApp({ controller, suspended = false, moa = null })
|
|
|
14991
15043
|
});
|
|
14992
15044
|
}, 400);
|
|
14993
15045
|
return undefined;
|
|
14994
|
-
}, [controller, state.moa, state.activeSessionId, state.activityPaneAdjust, state.agentPickerUsage, state.canvasOpen, state.canvasPaneAdjust, state.canvasPrefs, state.canvasZen, state.collapsedSessionIds, state.diagnosticsOpen, state.diagnosticsPaneAdjust, state.diagnosticsSplitAdjust, state.ownerFilter, state.paneAdjust, state.manualOrder, state.pinnedIds, state.portalSessionColumnAdjust, state.rightPaneMode, state.sessionDetailCollapsed, state.sessionPaneAdjust, state.sessionViews, state.themeId, state.touchScale]);
|
|
15046
|
+
}, [controller, state.moa, state.activeSessionId, state.activityPaneAdjust, state.agentPickerUsage, state.canvasOpen, state.canvasPaneAdjust, state.canvasPrefs, state.canvasZen, state.collapsedSessionIds, state.diagnosticsOpen, state.diagnosticsPaneAdjust, state.diagnosticsSplitAdjust, state.ownerFilter, state.paneAdjust, state.manualOrder, state.sessionSortMode, state.sessionUsedAt, state.pinnedIds, state.portalSessionColumnAdjust, state.rightPaneMode, state.sessionDetailCollapsed, state.sessionPaneAdjust, state.sessionViews, state.themeId, state.touchScale]);
|
|
14995
15047
|
|
|
14996
15048
|
React.useEffect(() => {
|
|
14997
15049
|
applyDocumentTheme(state.themeId);
|
package/web/dist/assets/{abnfDiagram-VRR7QNED-DCEEpIGf.js → abnfDiagram-VRR7QNED-C1caNr4U.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-CHdrVT1z.js";import{p as f}from"./chunk-JWPE2WC7-CGM2GAMX.js";import{_ as n,l as o}from"./mermaid.core-i8uqvLPa.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-3zVj2GvI.js";import"./pilotswarm-D7Q48waO.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-i8uqvLPa.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};
|