pilotswarm 0.5.60 → 0.5.62
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/README.md +3 -2
- package/mcp/dist/src/resources/models.d.ts.map +1 -1
- package/mcp/dist/src/resources/models.js +6 -1
- package/mcp/dist/src/resources/models.js.map +1 -1
- package/mcp/dist/src/tools/models.d.ts.map +1 -1
- package/mcp/dist/src/tools/models.js +11 -1
- package/mcp/dist/src/tools/models.js.map +1 -1
- package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
- package/mcp/dist/src/tools/sessions.js +8 -2
- package/mcp/dist/src/tools/sessions.js.map +1 -1
- package/package.json +2 -2
- package/tui/src/node-sdk-transport.js +1 -1
- package/ui/core/src/chat-activity.js +94 -0
- package/ui/core/src/controller.js +50 -5
- package/ui/core/src/history.js +15 -0
- package/ui/core/src/moa.js +32 -11
- package/ui/core/src/reducer.js +63 -51
- package/ui/core/src/selectors.js +25 -5
- package/ui/core/src/session-errors.js +10 -2
- package/ui/core/src/system-titles.js +2 -0
- package/ui/react/src/web-app.js +155 -77
- package/web/dist/assets/{abnfDiagram-VRR7QNED-CXEHJkTQ.js → abnfDiagram-VRR7QNED-DAiG41W-.js} +1 -1
- package/web/dist/assets/{arc-lInHlEVm.js → arc-CN_GY3DG.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-vrocx6re.js → architectureDiagram-ZJ3FMSHR-DD9qiBOj.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-B1KA5QIB.js → blockDiagram-677ZJIJ3-CZg2R8i6.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-Du9xJMjz.js → c4Diagram-LMCZKHZV-DuZxUZYd.js} +1 -1
- package/web/dist/assets/channel-B50-C7oJ.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-BuHucQOQ.js → chunk-2Q5K7J3B-BX7lDvmf.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-T-AE5Yz0.js → chunk-32BRIVSS-COupwzAw.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-B_kTsNzt.js → chunk-5VM5RSS4-C_IyERib.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-CtqgceBQ.js → chunk-EX3LRPZG-CyfIuYKn.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-C_Fv9QUd.js → chunk-JWPE2WC7-Cj5lvEfN.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-D5GeF8ZZ.js → chunk-MOJQB5TN-l907LpMA.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-Cg63wDst.js → chunk-RYQCIY6F-PLru1fOZ.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-Bz6G3lev.js → chunk-V7JOEXUC-C6GCxiE5.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-DKs_hvUD.js → chunk-VR4S4FIN-BGelrIxQ.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-B9AtUlbn.js → chunk-XXDRQBXY-BmJstjEv.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-CIJlKS0m.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-CIJlKS0m.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-rAG6oS0i.js → cose-bilkent-JH36ORCC-CRabxOOK.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-CUy2C8UT.js → cynefin-VYW2F7L2-CminxBoG.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-C1W8blXH.js → cynefinDiagram-TSTJHNR4-yBazsQf4.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-DC0XqwcC.js → dagre-VKFMJZFB-DcZuZV2n.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-COAY9zCP.js → diagram-FQU43EPY-CHoFzsw6.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-DLPr8eWG.js → diagram-G47NLZAW-B8leqMRl.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-DoNgwoDz.js → diagram-NH7WQ7WH-DNoVxpa3.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-D3-5TINE.js → diagram-OA4YK3LP-gC3Q2X6-.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-DplCkBJC.js → diagram-WEI45ONY-CABqyjDl.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-dvcVh7yr.js → ebnfDiagram-CCIWWBDH-cSguXaDC.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-Cde8cTY6.js → erDiagram-Q63AITRT-CoWX37V3.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-MGMNsh2E.js → flowDiagram-23GEKE2U-I9DHYjhG.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-BiKw7AfS.js → ganttDiagram-NO4QXBWP-DaFnfYTt.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-vC7fsylq.js → gitGraphDiagram-IHSO6WYX-CwiXVM_O.js} +1 -1
- package/web/dist/assets/index-CHlrgp0s.css +1 -0
- package/web/dist/assets/index-bf7RCrAf.js +24 -0
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-Du1uirB0.js → infoDiagram-FWYZ7A6U-DtzIrIpW.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-Dk--Qshr.js → ishikawaDiagram-FXEZZL3T-B9nk829n.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-iDE4zf_N.js → journeyDiagram-5HDEW3XC-xLaPm-ow.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-D7WI8iRR.js → kanban-definition-HUTT4EX6-BnDqLYLC.js} +1 -1
- package/web/dist/assets/{linear-B1_kxCBK.js → linear-Djc7nVo8.js} +1 -1
- package/web/dist/assets/{mermaid.core-DNmC5O4Y.js → mermaid.core-B5elhUtV.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-DIbLKLMA.js → mindmap-definition-LN4V7U3C-N-B7EJGs.js} +1 -1
- package/web/dist/assets/{papaparse.min-BdWinjY-.js → papaparse.min-BqM-LJkq.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-CkxxR07G.js → pegDiagram-2B236MQR-BIollSMB.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-Dxvp1mn7.js → pieDiagram-ENE6RG2P-DkZY6iCd.js} +1 -1
- package/web/dist/assets/pilotswarm-Di5s6c69.js +105 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CrL0hjZW.js → quadrantDiagram-ABIIQ3AL-iUDmQIyL.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-CmVmFBPa.js → railroadDiagram-RFXS5EU6-BSCGJgV7.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-DJc3NRXb.js → requirementDiagram-TGXJPOKE-9yqcGRUA.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-BJNqWqBb.js → sankeyDiagram-HTMAVEWB-SPh1plT9.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-C0wddECV.js → sequenceDiagram-DBY2YBRQ-C0nv5x71.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-Cw0dqPWS.js → sizeCapture-X5ZJPWSS-DMXfUt1o.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-C5793RHZ.js → stateDiagram-2N3HPSRC-vjhtquua.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CYIeYmPN.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-Bhpm77Zu.js → swimlanes-5IMT3BWC-Bqewmkt5.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-BeKhH9C9.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-CwbE4NsH.js → timeline-definition-FHXFAJF6-DYHsdXUL.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-DZnJEL_w.js → vennDiagram-L72KCM5P-Cb7cOHSa.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-DwTgBDev.js → wardleyDiagram-EHGQE667-BHpO1byL.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-BiPjN3Qc.js → xychartDiagram-FW5EYKEG-DHDvGPtH.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/runtime.js +1 -0
- package/web/dist/assets/channel-6wPrR6sC.js +0 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-vvXyIfbC.js +0 -1
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-vvXyIfbC.js +0 -1
- package/web/dist/assets/index-D9Ab1VTY.css +0 -1
- package/web/dist/assets/index-DDAyy127.js +0 -24
- package/web/dist/assets/pilotswarm-493nqGmy.js +0 -98
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-qGaRayHj.js +0 -1
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-BXjNM_Zw.js +0 -8
package/ui/react/src/web-app.js
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
selectArtifactPickerModal,
|
|
37
37
|
selectArtifactUploadModal,
|
|
38
38
|
selectLiveActivityLines,
|
|
39
|
+
selectActiveOutboxMessages,
|
|
39
40
|
selectChatLines,
|
|
40
41
|
selectChatPaneChrome,
|
|
41
42
|
selectOutboxOverlayLines,
|
|
@@ -606,12 +607,8 @@ function materializeProfileSettings(remoteSettings, defaults) {
|
|
|
606
607
|
// synthesizing one here would let a poll clobber a fresh local toggle.
|
|
607
608
|
...(hasOwn(normalizedRemote, touchScaleKey())
|
|
608
609
|
? { touchScale: normalizedRemote[touchScaleKey()] }
|
|
609
|
-
//
|
|
610
|
-
|
|
611
|
-
// inherit it, and only until it saves a slot of its own.
|
|
612
|
-
: (isNarrowViewport() && hasOwn(normalizedRemote, "touchScale")
|
|
613
|
-
? { touchScale: normalizedRemote.touchScale }
|
|
614
|
-
: {})),
|
|
610
|
+
// Never inherit the other device class's preference.
|
|
611
|
+
: {}),
|
|
615
612
|
// Read back for the same reason as touchScale above: written but never
|
|
616
613
|
// merged means the fold state resets on every reload. No default here
|
|
617
614
|
// either — absent must stay absent so a poll cannot overwrite a toggle
|
|
@@ -1330,6 +1327,22 @@ function SystemNoticeLine({ line, theme }) {
|
|
|
1330
1327
|
: null);
|
|
1331
1328
|
}
|
|
1332
1329
|
|
|
1330
|
+
function ChatCallLine({ line }) {
|
|
1331
|
+
const [open, setOpen] = React.useState(false);
|
|
1332
|
+
return React.createElement("details", {
|
|
1333
|
+
className: "ps-system-notice ps-chat-call",
|
|
1334
|
+
"data-call-id": line.callKey,
|
|
1335
|
+
onToggle: event => setOpen(event.currentTarget.open),
|
|
1336
|
+
},
|
|
1337
|
+
React.createElement("summary", { className: "ps-system-notice-summary ps-chat-call-summary" },
|
|
1338
|
+
React.createElement("span", { className: "ps-chat-call-tag" }, line.category || "Tool"),
|
|
1339
|
+
React.createElement("span", { className: "ps-system-notice-summary-text" }, line.text),
|
|
1340
|
+
line.status ? React.createElement("span", { className: `ps-chat-call-status${line.status === "Failed" ? " is-failed" : ""}` }, line.status) : null),
|
|
1341
|
+
open ? React.createElement("div", { className: "ps-system-notice-body" },
|
|
1342
|
+
line.time ? React.createElement("div", { className: "ps-chat-call-time" }, line.time) : null,
|
|
1343
|
+
React.createElement("pre", { className: "ps-chat-call-payload" }, line.body)) : null);
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1333
1346
|
/**
|
|
1334
1347
|
* A canvas action is a button press inside the drawn page, not something the
|
|
1335
1348
|
* viewer typed. Printing the raw `[canvas-action] {…}` JSON as a chat message
|
|
@@ -3229,6 +3242,13 @@ function parseStructuredChatBlocks(lines = []) {
|
|
|
3229
3242
|
for (let index = 0; index < lines.length;) {
|
|
3230
3243
|
const currentLine = lines[index];
|
|
3231
3244
|
|
|
3245
|
+
if (currentLine?.kind === "chatCall" || currentLine?.callPreview !== undefined) {
|
|
3246
|
+
blocks.push({ type: "chatCall", line: currentLine.callPreview !== undefined
|
|
3247
|
+
? { ...currentLine, text: currentLine.callPreview, category: "Agent" } : currentLine });
|
|
3248
|
+
index += 1;
|
|
3249
|
+
continue;
|
|
3250
|
+
}
|
|
3251
|
+
|
|
3232
3252
|
if (currentLine?.kind === "assistantPreview") {
|
|
3233
3253
|
blocks.push({ type: "assistantPreview", line: currentLine });
|
|
3234
3254
|
index += 1;
|
|
@@ -3654,6 +3674,9 @@ const AssistantPreviewCard = React.memo(function AssistantPreviewCard({ line, th
|
|
|
3654
3674
|
function StructuredBlockList({ blocks, theme, controller = null }) {
|
|
3655
3675
|
return React.createElement(React.Fragment, null,
|
|
3656
3676
|
(blocks || []).map((block, index) => {
|
|
3677
|
+
if (block.type === "chatCall") {
|
|
3678
|
+
return React.createElement(ChatCallLine, { key: block.line.callKey, line: block.line });
|
|
3679
|
+
}
|
|
3657
3680
|
if (block.type === "assistantPreview") {
|
|
3658
3681
|
return React.createElement(AssistantPreviewCard, {
|
|
3659
3682
|
key: block.line.previewKey,
|
|
@@ -3979,7 +4002,7 @@ function focusRegionForPaneKey(paneKey, override = null) {
|
|
|
3979
4002
|
return PANE_KEY_FOCUS_REGIONS[String(paneKey || "")] || null;
|
|
3980
4003
|
}
|
|
3981
4004
|
|
|
3982
|
-
function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, lines, stickyLines = [], bottomStickyLines = [], scrollOffset = 0, scrollMode = "top", paneKey, controller, className = "", panelClassName = "", topContent = null, bottomContent = null, structuredBlocks = false, stickyBottom = false, renderBody = null, focusRegion = null, panelRef = null, ariaLive = null }) {
|
|
4005
|
+
function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, lines, stickyLines = [], bottomStickyLines = [], reserveBottomSticky = false, scrollOffset = 0, scrollMode = "top", paneKey, controller, className = "", panelClassName = "", topContent = null, bottomContent = null, structuredBlocks = false, stickyBottom = false, renderBody = null, focusRegion = null, panelRef = null, ariaLive = null }) {
|
|
3983
4006
|
const themeId = useControllerSelector(controller, (state) => state.ui.themeId);
|
|
3984
4007
|
const theme = getTheme(themeId);
|
|
3985
4008
|
const ref = React.useRef(null);
|
|
@@ -4098,9 +4121,9 @@ function ScrollLinesPanel({ title, titleRight = null, color, focused, actions, l
|
|
|
4098
4121
|
? React.createElement(StructuredChatBlocks, { lines: normalizedLines, theme, controller })
|
|
4099
4122
|
: normalizedLines.map((line, index) => React.createElement(Line, { key: `line:${index}`, line, theme })),
|
|
4100
4123
|
),
|
|
4101
|
-
normalizedBottomSticky.length > 0
|
|
4124
|
+
(normalizedBottomSticky.length > 0 || reserveBottomSticky)
|
|
4102
4125
|
? React.createElement("div", {
|
|
4103
|
-
className:
|
|
4126
|
+
className: `ps-panel-bottom-sticky${reserveBottomSticky ? " is-reserved" : ""}`,
|
|
4104
4127
|
},
|
|
4105
4128
|
normalizedBottomSticky.map((line, index) => React.createElement(Line, { key: `bottom-sticky:${index}`, line, theme })),
|
|
4106
4129
|
)
|
|
@@ -4215,7 +4238,7 @@ export function waitReasonLabel(session) {
|
|
|
4215
4238
|
return session?.cronActive === true ? "On wake" : "Waiting";
|
|
4216
4239
|
}
|
|
4217
4240
|
|
|
4218
|
-
function SessionDetailBox({ session, childCount = 0, pause = null, controller = null, collapsed = false, onToggle = null }) {
|
|
4241
|
+
function SessionDetailBox({ session, childCount = 0, pause = null, controller = null, collapsed = false, onToggle = null, onOpenBudget = null }) {
|
|
4219
4242
|
// EVERY field renders on EVERY selection, empty ones as an em dash. The box
|
|
4220
4243
|
// is a fixed grid of rows, so moving through the list cannot change its
|
|
4221
4244
|
// height — a box that grew and shrank would shove the list under the
|
|
@@ -4312,12 +4335,12 @@ function SessionDetailBox({ session, childCount = 0, pause = null, controller =
|
|
|
4312
4335
|
pause && pause.clears
|
|
4313
4336
|
? React.createElement("span", { className: "ps-session-detail-clears" }, pause.clears)
|
|
4314
4337
|
: null,
|
|
4315
|
-
pause && controller ? React.createElement("button", {
|
|
4338
|
+
pause && (controller || onOpenBudget) ? React.createElement("button", {
|
|
4316
4339
|
type: "button", className: "ps-budget-link",
|
|
4317
4340
|
title: pause.provider
|
|
4318
4341
|
? `Open ${pause.provider} in Providers & Budgets`
|
|
4319
4342
|
: "Open providers and budgets",
|
|
4320
|
-
onClick: () => controller.openBudget(
|
|
4343
|
+
onClick: () => (onOpenBudget || (options => controller.openBudget(options)))(
|
|
4321
4344
|
pause.provider ? { provider: pause.provider } : {},
|
|
4322
4345
|
).catch(() => {}),
|
|
4323
4346
|
}, pause.provider ? `Open ${pause.provider}` : "Open providers and budgets") : null));
|
|
@@ -6407,7 +6430,7 @@ function SessionModifyModal({ controller, sessionId, initialTitle, currentModel,
|
|
|
6407
6430
|
error ? React.createElement("div", { className: "ps-share-error" }, error) : null));
|
|
6408
6431
|
}
|
|
6409
6432
|
|
|
6410
|
-
function SessionComposer({ controller, onReadOnlyFocus = null }) {
|
|
6433
|
+
function SessionComposer({ controller, onReadOnlyFocus = null, mobile = false, compact = false, autoFocus = !mobile }) {
|
|
6411
6434
|
const modal = useControllerSelector(controller, state => state.ui.modal);
|
|
6412
6435
|
const session = useControllerSelector(controller, state => state.sessions.byId[state.sessions.activeSessionId]);
|
|
6413
6436
|
const { access } = useActiveSessionAccess(controller, session?.sessionId, session?.isGroup);
|
|
@@ -6418,10 +6441,30 @@ function SessionComposer({ controller, onReadOnlyFocus = null }) {
|
|
|
6418
6441
|
? React.createElement("div", { className: "ps-composer-readonly" }, session.serviceKind
|
|
6419
6442
|
? "⚗ Service session — runtime machinery. Its transcript is a read-only trace; it does not accept messages."
|
|
6420
6443
|
: `You have view access to this session. Ask ${access.owner?.displayName || access.owner?.email || "the owner"} for write access to participate.`)
|
|
6421
|
-
: React.createElement(PromptComposer, { controller, mobile
|
|
6422
|
-
}
|
|
6423
|
-
|
|
6424
|
-
|
|
6444
|
+
: React.createElement(PromptComposer, { controller, mobile, compact, autoFocus, active: true }));
|
|
6445
|
+
}
|
|
6446
|
+
|
|
6447
|
+
// The compact focus views use their existing header for activity. The same
|
|
6448
|
+
// selector powers the desktop footer, so stale-status and elapsed-time rules
|
|
6449
|
+
// remain identical; queued prompt bodies stay readable in the transcript.
|
|
6450
|
+
function SessionHeaderStatus({ controller }) {
|
|
6451
|
+
const state = useControllerSelector(controller, s => s);
|
|
6452
|
+
const session = state.sessions.byId[state.sessions.activeSessionId];
|
|
6453
|
+
const spinnerFrame = useSpinnerFrame(session?.status === "running");
|
|
6454
|
+
const activity = selectLiveActivityLines(state, { spinnerFrame, maxWidth: 120 });
|
|
6455
|
+
const status = activity[0]?.map(run => run.text || "").join("")
|
|
6456
|
+
|| (session ? String(session.status || "idle").replace(/^./, c => c.toUpperCase()) : "");
|
|
6457
|
+
const messages = selectActiveOutboxMessages(state);
|
|
6458
|
+
const queue = ["pending", "queued", "cancelling", "rejected"].map(phase => {
|
|
6459
|
+
const count = messages.filter(message => message.pendingPhase === phase).length;
|
|
6460
|
+
return count ? `${count} ${phase}` : "";
|
|
6461
|
+
}).filter(Boolean).join(" · ");
|
|
6462
|
+
return React.createElement("div", { className: "ps-mobile-session-status", "aria-label": "Session status" },
|
|
6463
|
+
React.createElement("span", { className: "ps-mobile-activity", title: status }, status),
|
|
6464
|
+
queue ? React.createElement("span", { className: "ps-mobile-queue", title: queue }, queue) : null);
|
|
6465
|
+
}
|
|
6466
|
+
|
|
6467
|
+
function ChatPane({ controller, mobile = false, fullWidth = false, showComposer = true, onEnterZen = null, activityInHeader = false }) {
|
|
6425
6468
|
const themeId = useControllerSelector(controller, (state) => state.ui.themeId);
|
|
6426
6469
|
const theme = getTheme(themeId);
|
|
6427
6470
|
const viewState = useControllerSelector(controller, (state) => {
|
|
@@ -6532,6 +6575,10 @@ function ChatPane({ controller, mobile = false, fullWidth = false, showComposer
|
|
|
6532
6575
|
() => (pinnedActivityLines.length > 0 ? [...outboxLines, ...pinnedActivityLines] : outboxLines),
|
|
6533
6576
|
[outboxLines, pinnedActivityLines],
|
|
6534
6577
|
);
|
|
6578
|
+
const transcriptLines = React.useMemo(
|
|
6579
|
+
() => activityInHeader && outboxLines.length ? [...lines, ...outboxLines] : lines,
|
|
6580
|
+
[activityInHeader, lines, outboxLines],
|
|
6581
|
+
);
|
|
6535
6582
|
// Read-only gating: a view-only viewer (shared_read / read grant, no write)
|
|
6536
6583
|
// gets an explanatory notice instead of the composer. The visibility chip
|
|
6537
6584
|
// and Share affordance now live in the session list "Modify" modal and the
|
|
@@ -6587,11 +6634,12 @@ function ChatPane({ controller, mobile = false, fullWidth = false, showComposer
|
|
|
6587
6634
|
titleRight: mobile && titleRight ? compactTitleRuns(titleRight, 18) : titleRight,
|
|
6588
6635
|
// Chat/Summary toggling lives on the top toolbar so the pane chrome
|
|
6589
6636
|
// stays clean. The toolbar button is disabled for group sessions.
|
|
6590
|
-
actions: null,
|
|
6637
|
+
actions: mobile && onEnterZen ? React.createElement(IconButton, { className: "ps-mini-button", icon: React.createElement(ExpandGlyph), label: "Enter mobile zen", onClick: onEnterZen }) : null,
|
|
6591
6638
|
color: chrome.color,
|
|
6592
6639
|
focused: viewState.focused,
|
|
6593
|
-
lines,
|
|
6594
|
-
bottomStickyLines: stickyBottom,
|
|
6640
|
+
lines: transcriptLines,
|
|
6641
|
+
bottomStickyLines: activityInHeader ? EMPTY_ARRAY : stickyBottom,
|
|
6642
|
+
reserveBottomSticky: !activityInHeader,
|
|
6595
6643
|
scrollOffset: viewState.scroll,
|
|
6596
6644
|
scrollMode: "bottom",
|
|
6597
6645
|
paneKey: "chat",
|
|
@@ -6941,7 +6989,7 @@ function useKeyboardTakeover(enabled) {
|
|
|
6941
6989
|
* detail sub-panel). This replaced chat-focus mode, which was a second way to
|
|
6942
6990
|
* say "chat only" with its own chrome and its own exit.
|
|
6943
6991
|
*/
|
|
6944
|
-
function MobileWorkspace({ controller, layout = "split" }) {
|
|
6992
|
+
function MobileWorkspace({ controller, layout = "split", onEnterZen }) {
|
|
6945
6993
|
const sessionPane = React.createElement(SessionPane, {
|
|
6946
6994
|
controller,
|
|
6947
6995
|
panelClassName: "ps-mobile-session-pane",
|
|
@@ -6949,7 +6997,7 @@ function MobileWorkspace({ controller, layout = "split" }) {
|
|
|
6949
6997
|
if (layout === "chat") {
|
|
6950
6998
|
return React.createElement("div", { className: "ps-mobile-workspace is-chat-only" },
|
|
6951
6999
|
React.createElement("div", { className: "ps-mobile-chat-pane" },
|
|
6952
|
-
React.createElement(ChatPane, { controller, mobile: true, fullWidth: true })));
|
|
7000
|
+
React.createElement(ChatPane, { controller, mobile: true, fullWidth: true, onEnterZen })));
|
|
6953
7001
|
}
|
|
6954
7002
|
if (layout === "sessions") {
|
|
6955
7003
|
return React.createElement("div", { className: "ps-mobile-workspace is-sessions-only" },
|
|
@@ -6962,7 +7010,7 @@ function MobileWorkspace({ controller, layout = "split" }) {
|
|
|
6962
7010
|
return React.createElement("div", { className: "ps-mobile-workspace" },
|
|
6963
7011
|
sessionPane,
|
|
6964
7012
|
React.createElement("div", { className: "ps-mobile-chat-pane" },
|
|
6965
|
-
React.createElement(ChatPane, { controller, mobile: true, fullWidth: true })));
|
|
7013
|
+
React.createElement(ChatPane, { controller, mobile: true, fullWidth: true, onEnterZen })));
|
|
6966
7014
|
}
|
|
6967
7015
|
|
|
6968
7016
|
/** Frame-and-easel glyph for the Canvas toggle. */
|
|
@@ -8688,7 +8736,7 @@ function formatAttachmentSize(sizeBytes) {
|
|
|
8688
8736
|
return `${bytes} B`;
|
|
8689
8737
|
}
|
|
8690
8738
|
|
|
8691
|
-
function PromptComposer({ controller, mobile, active = true, onAfterSend = null, autoFocus = true }) {
|
|
8739
|
+
function PromptComposer({ controller, mobile, compact = false, active = true, onAfterSend = null, autoFocus = true }) {
|
|
8692
8740
|
const promptState = useControllerSelector(controller, (state) => {
|
|
8693
8741
|
const activeSessionId = state.sessions.activeSessionId;
|
|
8694
8742
|
const activeSession = activeSessionId ? state.sessions.byId[activeSessionId] || null : null;
|
|
@@ -8720,7 +8768,7 @@ function PromptComposer({ controller, mobile, active = true, onAfterSend = null,
|
|
|
8720
8768
|
const selectedQueued = promptState.selectedOutboxPhase === "queued";
|
|
8721
8769
|
const selectedCancelling = promptState.selectedOutboxPhase === "cancelling";
|
|
8722
8770
|
const selectedReadOnly = selectedQueued || selectedCancelling;
|
|
8723
|
-
const placeholder = promptState.answerMode
|
|
8771
|
+
const placeholder = mobile && !promptState.editingPending ? (promptState.answerMode ? "Answer…" : "Message…") : promptState.answerMode
|
|
8724
8772
|
? "Type an answer and press Enter"
|
|
8725
8773
|
: promptState.editingPending
|
|
8726
8774
|
? selectedCancelling
|
|
@@ -8824,7 +8872,7 @@ function PromptComposer({ controller, mobile, active = true, onAfterSend = null,
|
|
|
8824
8872
|
const inputNode = inputRef.current;
|
|
8825
8873
|
if (!active || promptState.modalOpen || !promptState.focused || !inputNode) return;
|
|
8826
8874
|
if (document.activeElement !== inputNode) {
|
|
8827
|
-
if (!autoFocus) return;
|
|
8875
|
+
if (!autoFocus || (typeof autoFocus === "function" && !autoFocus())) return;
|
|
8828
8876
|
// Programmatic focus pops the on-screen keyboard on touch devices;
|
|
8829
8877
|
// there, focus only ever comes from the user's own tap.
|
|
8830
8878
|
if (mobile) return;
|
|
@@ -8883,7 +8931,7 @@ function PromptComposer({ controller, mobile, active = true, onAfterSend = null,
|
|
|
8883
8931
|
: "❯";
|
|
8884
8932
|
|
|
8885
8933
|
return React.createElement("div", {
|
|
8886
|
-
className: `ps-prompt-shell${mobile ? " is-mobile" : ""}${dragOver ? " is-drag-over" : ""}`,
|
|
8934
|
+
className: `ps-prompt-shell${compact ? " is-compact" : ""}${mobile ? " is-mobile" : ""}${dragOver ? " is-drag-over" : ""}`,
|
|
8887
8935
|
...(canAttachImages ? {
|
|
8888
8936
|
onDragOver: (event) => {
|
|
8889
8937
|
if (event.dataTransfer?.types?.includes?.("Files")) {
|
|
@@ -9001,7 +9049,7 @@ function PromptComposer({ controller, mobile, active = true, onAfterSend = null,
|
|
|
9001
9049
|
// pointerdown preventDefault on every action keeps focus in the
|
|
9002
9050
|
// textarea — on a phone, tapping Send must not collapse the
|
|
9003
9051
|
// keyboard between messages.
|
|
9004
|
-
canAttachImages
|
|
9052
|
+
canAttachImages && !compact
|
|
9005
9053
|
? React.createElement(React.Fragment, null,
|
|
9006
9054
|
React.createElement("input", {
|
|
9007
9055
|
ref: attachInputRef,
|
|
@@ -9038,7 +9086,7 @@ function PromptComposer({ controller, mobile, active = true, onAfterSend = null,
|
|
|
9038
9086
|
onClick: cancelPending,
|
|
9039
9087
|
}, selectedQueued ? "Delete" : "Cancel")
|
|
9040
9088
|
: null,
|
|
9041
|
-
promptState.canStopTurn || stoppingTurn
|
|
9089
|
+
!compact && (promptState.canStopTurn || stoppingTurn)
|
|
9042
9090
|
? React.createElement("button", {
|
|
9043
9091
|
type: "button",
|
|
9044
9092
|
className: `ps-stop-button${stoppingTurn ? " is-stopping" : ""}`,
|
|
@@ -9094,14 +9142,29 @@ function IconButton({ icon, label, onClick, disabled = false, active = false, cl
|
|
|
9094
9142
|
const timerRef = React.useRef(null);
|
|
9095
9143
|
const longPressRef = React.useRef(false);
|
|
9096
9144
|
|
|
9097
|
-
//
|
|
9098
|
-
// buttons would otherwise clip off the edge (the tooltip is center-anchored).
|
|
9145
|
+
// Measure wrapped text against the visual viewport, including the keyboard.
|
|
9099
9146
|
React.useLayoutEffect(() => {
|
|
9100
|
-
if (!tip || !tipRef.current ||
|
|
9101
|
-
const
|
|
9102
|
-
const
|
|
9103
|
-
const
|
|
9104
|
-
|
|
9147
|
+
if (!tip || !tipRef.current || !btnRef.current) return;
|
|
9148
|
+
const el = tipRef.current, viewport = window.visualViewport;
|
|
9149
|
+
const update = () => {
|
|
9150
|
+
const left = viewport?.offsetLeft || 0, top = viewport?.offsetTop || 0;
|
|
9151
|
+
const width = viewport?.width || window.innerWidth, height = viewport?.height || window.innerHeight;
|
|
9152
|
+
const margin = 6, r = btnRef.current.getBoundingClientRect();
|
|
9153
|
+
el.style.width = "max-content";
|
|
9154
|
+
el.style.maxWidth = `${Math.min(220, width - 2 * margin)}px`;
|
|
9155
|
+
el.style.maxHeight = `${height - 2 * margin}px`;
|
|
9156
|
+
const box = el.getBoundingClientRect();
|
|
9157
|
+
let below = tip.placement === "below";
|
|
9158
|
+
if (!below && r.top - box.height - margin < top) below = true;
|
|
9159
|
+
if (below && r.bottom + box.height + margin > top + height && r.top - box.height - margin >= top) below = false;
|
|
9160
|
+
const x = Math.max(left + margin, Math.min(r.left + r.width / 2 - box.width / 2, left + width - box.width - margin));
|
|
9161
|
+
const y = Math.max(top + margin, Math.min(below ? r.bottom + margin : r.top - box.height - margin, top + height - box.height - margin));
|
|
9162
|
+
el.style.transform = "none";
|
|
9163
|
+
el.style.left = `${x}px`; el.style.top = `${y}px`;
|
|
9164
|
+
};
|
|
9165
|
+
update(); viewport?.addEventListener("resize", update); viewport?.addEventListener("scroll", update);
|
|
9166
|
+
window.addEventListener("resize", update);
|
|
9167
|
+
return () => { viewport?.removeEventListener("resize", update); viewport?.removeEventListener("scroll", update); window.removeEventListener("resize", update); };
|
|
9105
9168
|
}, [tip]);
|
|
9106
9169
|
|
|
9107
9170
|
const reveal = (preferAbove = false) => {
|
|
@@ -9366,7 +9429,7 @@ function Toolbar({ controller, mobile, moa = null, canvasPaneOpen = false, onTog
|
|
|
9366
9429
|
}]),
|
|
9367
9430
|
];
|
|
9368
9431
|
|
|
9369
|
-
if (
|
|
9432
|
+
if (moa) buttonDefs.push({
|
|
9370
9433
|
key: "moa", icon: React.createElement(MoaGlyph),
|
|
9371
9434
|
label: moa.returnTo ? "Back to MoA — Master of Agents" : "Master of Agents",
|
|
9372
9435
|
active: moa.active, disabled: !moa.loaded,
|
|
@@ -9430,8 +9493,9 @@ function Toolbar({ controller, mobile, moa = null, canvasPaneOpen = false, onTog
|
|
|
9430
9493
|
];
|
|
9431
9494
|
return React.createElement("div", { className: "ps-toolbar is-mobile" },
|
|
9432
9495
|
React.createElement("div", { className: "ps-toolbar-row ps-toolbar-row-primary" },
|
|
9433
|
-
React.createElement("div", { className: "ps-toolbar-row-actions" }, buttonDefs.map(renderButton)),
|
|
9496
|
+
React.createElement("div", { className: "ps-toolbar-row-actions" }, buttonDefs.filter(def => def.key !== "moa").map(renderButton)),
|
|
9434
9497
|
React.createElement("div", { className: "ps-toolbar-row-actions is-panes" },
|
|
9498
|
+
...buttonDefs.filter(def => def.key === "moa").map(renderButton),
|
|
9435
9499
|
paneDefs.map((def) => React.createElement(IconButton, {
|
|
9436
9500
|
key: def.id === "workspace" ? "workspace" : "diagnostics",
|
|
9437
9501
|
icon: React.createElement(def.icon),
|
|
@@ -10229,32 +10293,30 @@ function budgetPlural(n, one, many) {
|
|
|
10229
10293
|
return `${n} ${n === 1 ? one : many}`;
|
|
10230
10294
|
}
|
|
10231
10295
|
|
|
10232
|
-
/**
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
* instance of that type with a name of its own, and both a model-scoped limit
|
|
10237
|
-
* and a default tuple are refused by the database unless the model half names
|
|
10238
|
-
* the provider it belongs to.
|
|
10239
|
-
*/
|
|
10240
|
-
function budgetModelsForProvider(models, provider) {
|
|
10241
|
-
if (!provider?.typeId) return [];
|
|
10242
|
-
return models
|
|
10243
|
-
.filter((model) => model.providerId === provider.typeId)
|
|
10244
|
-
.map((model) => ({
|
|
10245
|
-
qualifiedName: `${provider.name}:${model.modelName}`,
|
|
10246
|
-
modelName: model.modelName,
|
|
10247
|
-
}));
|
|
10248
|
-
}
|
|
10249
|
-
|
|
10250
|
-
/** The provider TYPES this deployment can instantiate, from its model catalog. */
|
|
10251
|
-
function budgetProviderTypes(models) {
|
|
10252
|
-
const seen = new Map();
|
|
10296
|
+
/** Runtime catalogs name a pool; type catalogs name a provider template. */
|
|
10297
|
+
function budgetModelsForProvider(models, provider, rawRows = []) {
|
|
10298
|
+
if (!provider?.name) return [];
|
|
10299
|
+
const choices = new Map();
|
|
10253
10300
|
for (const model of models) {
|
|
10254
|
-
|
|
10255
|
-
|
|
10301
|
+
const matches = model.catalogKind === "runtime_provider"
|
|
10302
|
+
? model.providerId === provider.name
|
|
10303
|
+
: model.catalogKind === "provider_type"
|
|
10304
|
+
? model.providerId === provider.typeId
|
|
10305
|
+
: model.providerId === provider.name || model.providerId === provider.typeId;
|
|
10306
|
+
if (!matches) continue;
|
|
10307
|
+
const qualifiedName = `${provider.name}:${model.modelName}`;
|
|
10308
|
+
choices.set(qualifiedName, { qualifiedName, modelName: model.modelName });
|
|
10309
|
+
}
|
|
10310
|
+
// Existing caps remain editable even when the catalog is unavailable or a
|
|
10311
|
+
// model was retired. Never borrow a model reference from another pool.
|
|
10312
|
+
for (const row of rawRows) {
|
|
10313
|
+
if (row.providerName !== provider.name || row.rowKind !== "model"
|
|
10314
|
+
|| !String(row.scope || "").startsWith(`${provider.name}:`)) continue;
|
|
10315
|
+
choices.set(row.scope, {
|
|
10316
|
+
qualifiedName: row.scope, modelName: row.scope.slice(provider.name.length + 1),
|
|
10317
|
+
});
|
|
10256
10318
|
}
|
|
10257
|
-
return [...
|
|
10319
|
+
return [...choices.values()];
|
|
10258
10320
|
}
|
|
10259
10321
|
|
|
10260
10322
|
/** listModels() is flat on the web transport and grouped on the direct one. */
|
|
@@ -10264,15 +10326,18 @@ function budgetNormalizeModels(raw) {
|
|
|
10264
10326
|
: (Array.isArray(raw?.providers) ? raw.providers : (Array.isArray(raw?.models) ? raw.models : []));
|
|
10265
10327
|
const flat = top.flatMap((entry) => (
|
|
10266
10328
|
Array.isArray(entry?.models)
|
|
10267
|
-
? entry.models.map((model) => ({
|
|
10329
|
+
? entry.models.map((model) => ({
|
|
10330
|
+
...model, providerId: model.providerId || entry.providerId,
|
|
10331
|
+
catalogKind: model.catalogKind || entry.catalogKind,
|
|
10332
|
+
}))
|
|
10268
10333
|
: [entry]
|
|
10269
10334
|
));
|
|
10270
10335
|
return flat
|
|
10271
10336
|
.filter((model) => model && (model.modelName || model.qualifiedName))
|
|
10272
10337
|
.map((model) => ({
|
|
10273
|
-
modelName: model.modelName || String(model.qualifiedName).split(":").
|
|
10338
|
+
modelName: model.modelName || String(model.qualifiedName).split(":").slice(1).join(":"),
|
|
10274
10339
|
providerId: model.providerId || "",
|
|
10275
|
-
|
|
10340
|
+
catalogKind: model.catalogKind || null,
|
|
10276
10341
|
}));
|
|
10277
10342
|
}
|
|
10278
10343
|
|
|
@@ -10810,7 +10875,7 @@ function ProviderSystemSpend({ view }) {
|
|
|
10810
10875
|
* reachable.
|
|
10811
10876
|
*/
|
|
10812
10877
|
function EditProviderSheet({
|
|
10813
|
-
row, rawRows, models, isAdmin, busy, error, onCancel, onRun,
|
|
10878
|
+
row, rawRows, models, modelsLoading, modelsError, onRetryModels, isAdmin, busy, error, onCancel, onRun,
|
|
10814
10879
|
initialPeriod = "day", initialScope = "*",
|
|
10815
10880
|
}) {
|
|
10816
10881
|
const shared = row.class === "shared";
|
|
@@ -10954,10 +11019,13 @@ function EditProviderSheet({
|
|
|
10954
11019
|
className: "ps-budget-input", "aria-label": "Model this limit applies to",
|
|
10955
11020
|
value: model, onChange: (event) => setModel(event.target.value),
|
|
10956
11021
|
}, models.length === 0
|
|
10957
|
-
? React.createElement("option", { value: "" }, "No models
|
|
11022
|
+
? React.createElement("option", { value: "" }, modelsLoading ? "Loading models…" : modelsError ? "Model catalog unavailable" : "No models listed for this provider")
|
|
10958
11023
|
: models.map((option) => React.createElement("option", {
|
|
10959
11024
|
key: option.qualifiedName, value: option.qualifiedName,
|
|
10960
|
-
}, option.qualifiedName))) : null
|
|
11025
|
+
}, option.qualifiedName))) : null,
|
|
11026
|
+
modelsError ? React.createElement("div", { className: "ps-budget-note is-warn", role: "status" },
|
|
11027
|
+
"Could not load the model catalog. Existing model limits remain editable. ",
|
|
11028
|
+
React.createElement("button", { type: "button", onClick: onRetryModels, disabled: modelsLoading }, "Retry")) : null),
|
|
10961
11029
|
React.createElement(SheetField, {
|
|
10962
11030
|
label: "Tokens",
|
|
10963
11031
|
hint: parsed
|
|
@@ -11743,6 +11811,9 @@ function ProviderBudgetView({ controller }) {
|
|
|
11743
11811
|
// a failure is not fatal — the controls that need it say they have nothing
|
|
11744
11812
|
// to offer.
|
|
11745
11813
|
const [models, setModels] = React.useState([]);
|
|
11814
|
+
const [modelsLoading, setModelsLoading] = React.useState(true);
|
|
11815
|
+
const [modelsError, setModelsError] = React.useState(false);
|
|
11816
|
+
const [modelsRequest, setModelsRequest] = React.useState(0);
|
|
11746
11817
|
const [providerTypes, setProviderTypes] = React.useState(new Map());
|
|
11747
11818
|
const [defaults, setDefaults] = React.useState(null);
|
|
11748
11819
|
const readDefaults = React.useCallback(() => {
|
|
@@ -11753,11 +11824,14 @@ function ProviderBudgetView({ controller }) {
|
|
|
11753
11824
|
}, [controller]);
|
|
11754
11825
|
React.useEffect(() => {
|
|
11755
11826
|
let live = true;
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
}
|
|
11827
|
+
setModelsLoading(true);
|
|
11828
|
+
Promise.resolve().then(() => {
|
|
11829
|
+
if (typeof controller.transport.listModels !== "function") throw new Error("Model catalog unavailable");
|
|
11830
|
+
return controller.transport.listModels();
|
|
11831
|
+
}).then((rows) => {
|
|
11832
|
+
if (live) { setModels(budgetNormalizeModels(rows)); setModelsError(false); }
|
|
11833
|
+
}).catch(() => { if (live) setModelsError(true); })
|
|
11834
|
+
.finally(() => { if (live) setModelsLoading(false); });
|
|
11761
11835
|
if (typeof controller.transport.listProviders === "function") {
|
|
11762
11836
|
Promise.resolve(controller.transport.listProviders())
|
|
11763
11837
|
.then((rows) => {
|
|
@@ -11770,7 +11844,7 @@ function ProviderBudgetView({ controller }) {
|
|
|
11770
11844
|
}
|
|
11771
11845
|
readDefaults();
|
|
11772
11846
|
return () => { live = false; };
|
|
11773
|
-
}, [controller, readDefaults]);
|
|
11847
|
+
}, [controller, readDefaults, modelsRequest]);
|
|
11774
11848
|
|
|
11775
11849
|
// Opened by the toolbar, which loads it. Mounting with nothing behind it —
|
|
11776
11850
|
// a restored state, a second mount — reads once rather than showing zeros.
|
|
@@ -11855,13 +11929,14 @@ function ProviderBudgetView({ controller }) {
|
|
|
11855
11929
|
const modelsForSelected = selected
|
|
11856
11930
|
? budgetModelsForProvider(models, {
|
|
11857
11931
|
name: selected.providerName, typeId: providerTypes.get(selected.providerName) || "",
|
|
11858
|
-
})
|
|
11932
|
+
}, rawRows)
|
|
11859
11933
|
: [];
|
|
11860
11934
|
|
|
11861
11935
|
let sheetEl = null;
|
|
11862
11936
|
if (sheet?.kind === "edit" && selectedProvider) {
|
|
11863
11937
|
sheetEl = React.createElement(EditProviderSheet, {
|
|
11864
11938
|
row: selectedProvider, rawRows, models: modelsForSelected, isAdmin: view.isAdmin,
|
|
11939
|
+
modelsLoading, modelsError, onRetryModels: () => setModelsRequest((value) => value + 1),
|
|
11865
11940
|
// MAJOR 17: the sheet opens on the limit the reader was standing
|
|
11866
11941
|
// on, rather than always on Daily / all models.
|
|
11867
11942
|
initialPeriod: sheet.period || "day",
|
|
@@ -14249,6 +14324,9 @@ export function createWebPilotSwarmController({ transport, mode = "remote", bran
|
|
|
14249
14324
|
branding,
|
|
14250
14325
|
docs,
|
|
14251
14326
|
}));
|
|
14327
|
+
// Only the initial device default. A saved value for this device wins
|
|
14328
|
+
// when the profile loads, including an explicit mobile opt-out.
|
|
14329
|
+
store.dispatch({ type: "ui/touchScale", enabled: isNarrowViewport });
|
|
14252
14330
|
return new PilotSwarmUiController({ store, transport });
|
|
14253
14331
|
}
|
|
14254
14332
|
|
|
@@ -14994,7 +15072,7 @@ export function PilotSwarmWebApp({ controller, suspended = false, moa = null })
|
|
|
14994
15072
|
// it — the layer below is a SIBLING of this content and covers it. Drawing
|
|
14995
15073
|
// a pane here would only be invisible work.
|
|
14996
15074
|
else if (mobilePane === "canvas") mobileContent = null;
|
|
14997
|
-
else mobileContent = React.createElement(MobileWorkspace, { controller, layout: mobileMainLayout });
|
|
15075
|
+
else mobileContent = React.createElement(MobileWorkspace, { controller, layout: mobileMainLayout, onEnterZen: moa?.openMobileZen });
|
|
14998
15076
|
|
|
14999
15077
|
// The phone's canvas layer: a sibling of the content region's pane, NOT a
|
|
15000
15078
|
// child of any pane. That is deliberate — panes mount and unmount as the
|
|
@@ -15058,4 +15136,4 @@ export function PilotSwarmWebApp({ controller, suspended = false, moa = null })
|
|
|
15058
15136
|
}
|
|
15059
15137
|
|
|
15060
15138
|
// Browser hosts may compose these existing surfaces with isolated controllers.
|
|
15061
|
-
export { ChatPane, CanvasFrame, SessionPane, SessionRowContent, SessionDetailBox, SessionComposer, ScopedModalLayer, ControllerContext };
|
|
15139
|
+
export { SessionHeaderStatus, ChatPane, CanvasFrame, SessionPane, SessionRowContent, SessionDetailBox, SessionComposer, ScopedModalLayer, ControllerContext };
|
package/web/dist/assets/{abnfDiagram-VRR7QNED-CXEHJkTQ.js → abnfDiagram-VRR7QNED-DAiG41W-.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-l907LpMA.js";import{p as f}from"./chunk-JWPE2WC7-Cj5lvEfN.js";import{_ as n,l as o}from"./mermaid.core-B5elhUtV.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CminxBoG.js";import"./pilotswarm-Di5s6c69.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-B5elhUtV.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};
|