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.
Files changed (90) hide show
  1. package/README.md +3 -2
  2. package/mcp/dist/src/resources/models.d.ts.map +1 -1
  3. package/mcp/dist/src/resources/models.js +6 -1
  4. package/mcp/dist/src/resources/models.js.map +1 -1
  5. package/mcp/dist/src/tools/models.d.ts.map +1 -1
  6. package/mcp/dist/src/tools/models.js +11 -1
  7. package/mcp/dist/src/tools/models.js.map +1 -1
  8. package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
  9. package/mcp/dist/src/tools/sessions.js +8 -2
  10. package/mcp/dist/src/tools/sessions.js.map +1 -1
  11. package/package.json +2 -2
  12. package/tui/src/node-sdk-transport.js +1 -1
  13. package/ui/core/src/chat-activity.js +94 -0
  14. package/ui/core/src/controller.js +50 -5
  15. package/ui/core/src/history.js +15 -0
  16. package/ui/core/src/moa.js +32 -11
  17. package/ui/core/src/reducer.js +63 -51
  18. package/ui/core/src/selectors.js +25 -5
  19. package/ui/core/src/session-errors.js +10 -2
  20. package/ui/core/src/system-titles.js +2 -0
  21. package/ui/react/src/web-app.js +155 -77
  22. package/web/dist/assets/{abnfDiagram-VRR7QNED-CXEHJkTQ.js → abnfDiagram-VRR7QNED-DAiG41W-.js} +1 -1
  23. package/web/dist/assets/{arc-lInHlEVm.js → arc-CN_GY3DG.js} +1 -1
  24. package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-vrocx6re.js → architectureDiagram-ZJ3FMSHR-DD9qiBOj.js} +1 -1
  25. package/web/dist/assets/{blockDiagram-677ZJIJ3-B1KA5QIB.js → blockDiagram-677ZJIJ3-CZg2R8i6.js} +1 -1
  26. package/web/dist/assets/{c4Diagram-LMCZKHZV-Du9xJMjz.js → c4Diagram-LMCZKHZV-DuZxUZYd.js} +1 -1
  27. package/web/dist/assets/channel-B50-C7oJ.js +1 -0
  28. package/web/dist/assets/{chunk-2Q5K7J3B-BuHucQOQ.js → chunk-2Q5K7J3B-BX7lDvmf.js} +1 -1
  29. package/web/dist/assets/{chunk-32BRIVSS-T-AE5Yz0.js → chunk-32BRIVSS-COupwzAw.js} +1 -1
  30. package/web/dist/assets/{chunk-5VM5RSS4-B_kTsNzt.js → chunk-5VM5RSS4-C_IyERib.js} +1 -1
  31. package/web/dist/assets/{chunk-EX3LRPZG-CtqgceBQ.js → chunk-EX3LRPZG-CyfIuYKn.js} +1 -1
  32. package/web/dist/assets/{chunk-JWPE2WC7-C_Fv9QUd.js → chunk-JWPE2WC7-Cj5lvEfN.js} +1 -1
  33. package/web/dist/assets/{chunk-MOJQB5TN-D5GeF8ZZ.js → chunk-MOJQB5TN-l907LpMA.js} +1 -1
  34. package/web/dist/assets/{chunk-RYQCIY6F-Cg63wDst.js → chunk-RYQCIY6F-PLru1fOZ.js} +1 -1
  35. package/web/dist/assets/{chunk-V7JOEXUC-Bz6G3lev.js → chunk-V7JOEXUC-C6GCxiE5.js} +1 -1
  36. package/web/dist/assets/{chunk-VR4S4FIN-DKs_hvUD.js → chunk-VR4S4FIN-BGelrIxQ.js} +1 -1
  37. package/web/dist/assets/{chunk-XXDRQBXY-B9AtUlbn.js → chunk-XXDRQBXY-BmJstjEv.js} +1 -1
  38. package/web/dist/assets/classDiagram-OUVF2IWQ-CIJlKS0m.js +1 -0
  39. package/web/dist/assets/classDiagram-v2-EOCWNBFH-CIJlKS0m.js +1 -0
  40. package/web/dist/assets/{cose-bilkent-JH36ORCC-rAG6oS0i.js → cose-bilkent-JH36ORCC-CRabxOOK.js} +1 -1
  41. package/web/dist/assets/{cynefin-VYW2F7L2-CUy2C8UT.js → cynefin-VYW2F7L2-CminxBoG.js} +1 -1
  42. package/web/dist/assets/{cynefinDiagram-TSTJHNR4-C1W8blXH.js → cynefinDiagram-TSTJHNR4-yBazsQf4.js} +1 -1
  43. package/web/dist/assets/{dagre-VKFMJZFB-DC0XqwcC.js → dagre-VKFMJZFB-DcZuZV2n.js} +1 -1
  44. package/web/dist/assets/{diagram-FQU43EPY-COAY9zCP.js → diagram-FQU43EPY-CHoFzsw6.js} +1 -1
  45. package/web/dist/assets/{diagram-G47NLZAW-DLPr8eWG.js → diagram-G47NLZAW-B8leqMRl.js} +1 -1
  46. package/web/dist/assets/{diagram-NH7WQ7WH-DoNgwoDz.js → diagram-NH7WQ7WH-DNoVxpa3.js} +1 -1
  47. package/web/dist/assets/{diagram-OA4YK3LP-D3-5TINE.js → diagram-OA4YK3LP-gC3Q2X6-.js} +1 -1
  48. package/web/dist/assets/{diagram-WEI45ONY-DplCkBJC.js → diagram-WEI45ONY-CABqyjDl.js} +1 -1
  49. package/web/dist/assets/{ebnfDiagram-CCIWWBDH-dvcVh7yr.js → ebnfDiagram-CCIWWBDH-cSguXaDC.js} +1 -1
  50. package/web/dist/assets/{erDiagram-Q63AITRT-Cde8cTY6.js → erDiagram-Q63AITRT-CoWX37V3.js} +1 -1
  51. package/web/dist/assets/{flowDiagram-23GEKE2U-MGMNsh2E.js → flowDiagram-23GEKE2U-I9DHYjhG.js} +1 -1
  52. package/web/dist/assets/{ganttDiagram-NO4QXBWP-BiKw7AfS.js → ganttDiagram-NO4QXBWP-DaFnfYTt.js} +1 -1
  53. package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-vC7fsylq.js → gitGraphDiagram-IHSO6WYX-CwiXVM_O.js} +1 -1
  54. package/web/dist/assets/index-CHlrgp0s.css +1 -0
  55. package/web/dist/assets/index-bf7RCrAf.js +24 -0
  56. package/web/dist/assets/{infoDiagram-FWYZ7A6U-Du1uirB0.js → infoDiagram-FWYZ7A6U-DtzIrIpW.js} +1 -1
  57. package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-Dk--Qshr.js → ishikawaDiagram-FXEZZL3T-B9nk829n.js} +1 -1
  58. package/web/dist/assets/{journeyDiagram-5HDEW3XC-iDE4zf_N.js → journeyDiagram-5HDEW3XC-xLaPm-ow.js} +1 -1
  59. package/web/dist/assets/{kanban-definition-HUTT4EX6-D7WI8iRR.js → kanban-definition-HUTT4EX6-BnDqLYLC.js} +1 -1
  60. package/web/dist/assets/{linear-B1_kxCBK.js → linear-Djc7nVo8.js} +1 -1
  61. package/web/dist/assets/{mermaid.core-DNmC5O4Y.js → mermaid.core-B5elhUtV.js} +4 -4
  62. package/web/dist/assets/{mindmap-definition-LN4V7U3C-DIbLKLMA.js → mindmap-definition-LN4V7U3C-N-B7EJGs.js} +1 -1
  63. package/web/dist/assets/{papaparse.min-BdWinjY-.js → papaparse.min-BqM-LJkq.js} +1 -1
  64. package/web/dist/assets/{pegDiagram-2B236MQR-CkxxR07G.js → pegDiagram-2B236MQR-BIollSMB.js} +1 -1
  65. package/web/dist/assets/{pieDiagram-ENE6RG2P-Dxvp1mn7.js → pieDiagram-ENE6RG2P-DkZY6iCd.js} +1 -1
  66. package/web/dist/assets/pilotswarm-Di5s6c69.js +105 -0
  67. package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CrL0hjZW.js → quadrantDiagram-ABIIQ3AL-iUDmQIyL.js} +1 -1
  68. package/web/dist/assets/{railroadDiagram-RFXS5EU6-CmVmFBPa.js → railroadDiagram-RFXS5EU6-BSCGJgV7.js} +1 -1
  69. package/web/dist/assets/{requirementDiagram-TGXJPOKE-DJc3NRXb.js → requirementDiagram-TGXJPOKE-9yqcGRUA.js} +1 -1
  70. package/web/dist/assets/{sankeyDiagram-HTMAVEWB-BJNqWqBb.js → sankeyDiagram-HTMAVEWB-SPh1plT9.js} +1 -1
  71. package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-C0wddECV.js → sequenceDiagram-DBY2YBRQ-C0nv5x71.js} +1 -1
  72. package/web/dist/assets/{sizeCapture-X5ZJPWSS-Cw0dqPWS.js → sizeCapture-X5ZJPWSS-DMXfUt1o.js} +1 -1
  73. package/web/dist/assets/{stateDiagram-2N3HPSRC-C5793RHZ.js → stateDiagram-2N3HPSRC-vjhtquua.js} +1 -1
  74. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CYIeYmPN.js +1 -0
  75. package/web/dist/assets/{swimlanes-5IMT3BWC-Bhpm77Zu.js → swimlanes-5IMT3BWC-Bqewmkt5.js} +2 -2
  76. package/web/dist/assets/swimlanesDiagram-G3AALYLV-BeKhH9C9.js +8 -0
  77. package/web/dist/assets/{timeline-definition-FHXFAJF6-CwbE4NsH.js → timeline-definition-FHXFAJF6-DYHsdXUL.js} +1 -1
  78. package/web/dist/assets/{vennDiagram-L72KCM5P-DZnJEL_w.js → vennDiagram-L72KCM5P-Cb7cOHSa.js} +1 -1
  79. package/web/dist/assets/{wardleyDiagram-EHGQE667-DwTgBDev.js → wardleyDiagram-EHGQE667-BHpO1byL.js} +1 -1
  80. package/web/dist/assets/{xychartDiagram-FW5EYKEG-BiPjN3Qc.js → xychartDiagram-FW5EYKEG-DHDvGPtH.js} +1 -1
  81. package/web/dist/index.html +3 -3
  82. package/web/runtime.js +1 -0
  83. package/web/dist/assets/channel-6wPrR6sC.js +0 -1
  84. package/web/dist/assets/classDiagram-OUVF2IWQ-vvXyIfbC.js +0 -1
  85. package/web/dist/assets/classDiagram-v2-EOCWNBFH-vvXyIfbC.js +0 -1
  86. package/web/dist/assets/index-D9Ab1VTY.css +0 -1
  87. package/web/dist/assets/index-DDAyy127.js +0 -24
  88. package/web/dist/assets/pilotswarm-493nqGmy.js +0 -98
  89. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-qGaRayHj.js +0 -1
  90. package/web/dist/assets/swimlanesDiagram-G3AALYLV-BXjNM_Zw.js +0 -8
@@ -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
- // Profiles written before the per-device split carry a single
610
- // `touchScale`, which IS the desktop key — so only a phone needs to
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: "ps-panel-bottom-sticky",
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: false, active: true }));
6422
- }
6423
-
6424
- function ChatPane({ controller, mobile = false, fullWidth = false, showComposer = true }) {
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
- // Keep the tooltip within the viewport horizontally — the leftmost/rightmost
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 || typeof window === "undefined") return;
9101
- const half = tipRef.current.offsetWidth / 2;
9102
- const margin = 6;
9103
- const clampedX = Math.max(half + margin, Math.min(tip.x, window.innerWidth - half - margin));
9104
- tipRef.current.style.left = `${clampedX}px`;
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 (!mobile && moa?.desktop) buttonDefs.push({
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
- * A model reference a session can run: `<provider>:<model>`.
10234
- *
10235
- * The catalog's `providerId` is the TYPE ("azure-openai"); a provider is an
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
- if (!model.providerId || seen.has(model.providerId)) continue;
10255
- seen.set(model.providerId, { id: model.providerId, type: model.providerType || model.providerId });
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 [...seen.values()].sort((a, b) => a.id.localeCompare(b.id));
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) => ({ ...model, providerId: model.providerId || entry.providerId }))
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(":").pop(),
10338
+ modelName: model.modelName || String(model.qualifiedName).split(":").slice(1).join(":"),
10274
10339
  providerId: model.providerId || "",
10275
- providerType: model.providerType || model.providerId || "",
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 are listed for this provider's type")
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
- if (typeof controller.transport.listModels === "function") {
11757
- Promise.resolve(controller.transport.listModels())
11758
- .then((rows) => { if (live) setModels(budgetNormalizeModels(rows)); })
11759
- .catch(() => {});
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 };
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-D5GeF8ZZ.js";import{p as f}from"./chunk-JWPE2WC7-C_Fv9QUd.js";import{_ as n,l as o}from"./mermaid.core-DNmC5O4Y.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CUy2C8UT.js";import"./pilotswarm-493nqGmy.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-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-DNmC5O4Y.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
1
+ import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-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};