pilotswarm 0.5.63 → 0.5.64

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/mcp/dist/src/server.d.ts.map +1 -1
  2. package/mcp/dist/src/server.js +2 -0
  3. package/mcp/dist/src/server.js.map +1 -1
  4. package/mcp/dist/src/tools/features.d.ts +4 -0
  5. package/mcp/dist/src/tools/features.d.ts.map +1 -0
  6. package/mcp/dist/src/tools/features.js +35 -0
  7. package/mcp/dist/src/tools/features.js.map +1 -0
  8. package/package.json +2 -2
  9. package/tui/src/node-sdk-transport.js +13 -0
  10. package/ui/core/src/controller.js +276 -0
  11. package/ui/core/src/history.js +89 -14
  12. package/ui/core/src/native-tasks.js +197 -0
  13. package/ui/core/src/question-display.js +13 -0
  14. package/ui/core/src/reducer.js +18 -1
  15. package/ui/core/src/selectors.js +46 -13
  16. package/ui/core/src/session-errors.js +13 -6
  17. package/ui/core/src/session-warning.js +14 -0
  18. package/ui/core/src/state.js +1 -0
  19. package/ui/react/src/feature-flags-panel.js +186 -0
  20. package/ui/react/src/native-task-card.js +59 -0
  21. package/ui/react/src/web-app.js +105 -15
  22. package/web/dist/assets/{abnfDiagram-VRR7QNED-C8iAmIqt.js → abnfDiagram-VRR7QNED-gIPHF2gV.js} +1 -1
  23. package/web/dist/assets/{arc-Cg8qs17j.js → arc-DMW_q5Ml.js} +1 -1
  24. package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-fYr0dRm3.js → architectureDiagram-ZJ3FMSHR-DAKsrxcB.js} +1 -1
  25. package/web/dist/assets/{blockDiagram-677ZJIJ3-Bpj79Dzq.js → blockDiagram-677ZJIJ3-BUjSLpP3.js} +1 -1
  26. package/web/dist/assets/{c4Diagram-LMCZKHZV-b26Lsm6m.js → c4Diagram-LMCZKHZV-Dw2nPoes.js} +1 -1
  27. package/web/dist/assets/channel-CcOa1LtY.js +1 -0
  28. package/web/dist/assets/{chunk-2Q5K7J3B-VLYQfjgG.js → chunk-2Q5K7J3B-BAL28Rv0.js} +1 -1
  29. package/web/dist/assets/{chunk-32BRIVSS-mVx--2Hg.js → chunk-32BRIVSS-DDlt9K8s.js} +1 -1
  30. package/web/dist/assets/{chunk-5VM5RSS4-jwnJmked.js → chunk-5VM5RSS4-BLQGJGoP.js} +1 -1
  31. package/web/dist/assets/{chunk-EX3LRPZG-DdfzAT1n.js → chunk-EX3LRPZG-XFMb3HRy.js} +1 -1
  32. package/web/dist/assets/{chunk-JWPE2WC7-BHm6Udd8.js → chunk-JWPE2WC7-DWnKTQ72.js} +1 -1
  33. package/web/dist/assets/{chunk-MOJQB5TN-Dn5qSVAS.js → chunk-MOJQB5TN-MltzhnwP.js} +1 -1
  34. package/web/dist/assets/{chunk-RYQCIY6F-D4IKMROn.js → chunk-RYQCIY6F-Ce3q0-mJ.js} +1 -1
  35. package/web/dist/assets/{chunk-V7JOEXUC-BhME3pRf.js → chunk-V7JOEXUC-ThXLYY88.js} +1 -1
  36. package/web/dist/assets/{chunk-VR4S4FIN-CHG_NBff.js → chunk-VR4S4FIN-DbhAykiW.js} +1 -1
  37. package/web/dist/assets/{chunk-XXDRQBXY-yw4QCgiL.js → chunk-XXDRQBXY-BpkNB0mD.js} +1 -1
  38. package/web/dist/assets/classDiagram-OUVF2IWQ-B2VhHRSV.js +1 -0
  39. package/web/dist/assets/classDiagram-v2-EOCWNBFH-B2VhHRSV.js +1 -0
  40. package/web/dist/assets/{cose-bilkent-JH36ORCC-DqwPj9Kx.js → cose-bilkent-JH36ORCC-rctqAPvj.js} +1 -1
  41. package/web/dist/assets/{cynefin-VYW2F7L2-CVokaaE_.js → cynefin-VYW2F7L2-Dg1cltg6.js} +1 -1
  42. package/web/dist/assets/{cynefinDiagram-TSTJHNR4-Bkhj9fuY.js → cynefinDiagram-TSTJHNR4-Ci23Sv4Z.js} +1 -1
  43. package/web/dist/assets/{dagre-VKFMJZFB-DVv-jnjb.js → dagre-VKFMJZFB-BpWTGhpv.js} +1 -1
  44. package/web/dist/assets/{diagram-FQU43EPY-DDlZjkrF.js → diagram-FQU43EPY-B69JpiAe.js} +1 -1
  45. package/web/dist/assets/{diagram-G47NLZAW-CNDUgqYa.js → diagram-G47NLZAW-BHMk1TOO.js} +1 -1
  46. package/web/dist/assets/{diagram-NH7WQ7WH-DywF8u8i.js → diagram-NH7WQ7WH-CtvZIIsk.js} +1 -1
  47. package/web/dist/assets/{diagram-OA4YK3LP-ZfN8nvLw.js → diagram-OA4YK3LP-BFvKh800.js} +1 -1
  48. package/web/dist/assets/{diagram-WEI45ONY-S94A6Avm.js → diagram-WEI45ONY-CgB8sWPe.js} +1 -1
  49. package/web/dist/assets/{ebnfDiagram-CCIWWBDH-Mpt3QUnw.js → ebnfDiagram-CCIWWBDH-DyqPNydM.js} +1 -1
  50. package/web/dist/assets/{erDiagram-Q63AITRT-Bh-eWbdV.js → erDiagram-Q63AITRT-CwpvZQ3Q.js} +1 -1
  51. package/web/dist/assets/{flowDiagram-23GEKE2U-BwRtDI6V.js → flowDiagram-23GEKE2U-EBKSKxfC.js} +1 -1
  52. package/web/dist/assets/{ganttDiagram-NO4QXBWP-CrZoBmcB.js → ganttDiagram-NO4QXBWP-q5tMPAuC.js} +1 -1
  53. package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-giXv1ynk.js → gitGraphDiagram-IHSO6WYX-DCRbi4KE.js} +1 -1
  54. package/web/dist/assets/{index-Br-gGWmc.js → index-BfF7e08d.js} +6 -6
  55. package/web/dist/assets/index-uhc851H3.css +1 -0
  56. package/web/dist/assets/{infoDiagram-FWYZ7A6U-H_5oc4-7.js → infoDiagram-FWYZ7A6U-Bex5pSIX.js} +1 -1
  57. package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-BydiPDX0.js → ishikawaDiagram-FXEZZL3T-Dj0li_TY.js} +1 -1
  58. package/web/dist/assets/{journeyDiagram-5HDEW3XC-DS1HXms0.js → journeyDiagram-5HDEW3XC-BtEGEeVr.js} +1 -1
  59. package/web/dist/assets/{kanban-definition-HUTT4EX6-BjY5SyYu.js → kanban-definition-HUTT4EX6-BTFfZvYt.js} +1 -1
  60. package/web/dist/assets/{linear-BvOotjKL.js → linear-C3SQCsip.js} +1 -1
  61. package/web/dist/assets/{mermaid.core-0iRu7sp-.js → mermaid.core-DALDJDu8.js} +4 -4
  62. package/web/dist/assets/{mindmap-definition-LN4V7U3C-DB93zsvL.js → mindmap-definition-LN4V7U3C-BZf3uw0u.js} +1 -1
  63. package/web/dist/assets/{papaparse.min-f5Xncedc.js → papaparse.min-Bh9MZ-fk.js} +1 -1
  64. package/web/dist/assets/{pegDiagram-2B236MQR-Dh_U1cFA.js → pegDiagram-2B236MQR-PuOleiMg.js} +1 -1
  65. package/web/dist/assets/{pieDiagram-ENE6RG2P-Csv1qxMm.js → pieDiagram-ENE6RG2P-CcFORUaW.js} +1 -1
  66. package/web/dist/assets/pilotswarm-B9rLtXpI.js +109 -0
  67. package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-Bo0pcrBM.js → quadrantDiagram-ABIIQ3AL-CEm0mp4y.js} +1 -1
  68. package/web/dist/assets/{railroadDiagram-RFXS5EU6-CHPvHNWG.js → railroadDiagram-RFXS5EU6-DeH-uX0_.js} +1 -1
  69. package/web/dist/assets/{requirementDiagram-TGXJPOKE-DgX8l-6H.js → requirementDiagram-TGXJPOKE-CMbJVMc1.js} +1 -1
  70. package/web/dist/assets/{sankeyDiagram-HTMAVEWB-xR6MTs5a.js → sankeyDiagram-HTMAVEWB-C9gL5w_b.js} +1 -1
  71. package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-CD_45diB.js → sequenceDiagram-DBY2YBRQ-BUo8TT74.js} +1 -1
  72. package/web/dist/assets/{sizeCapture-X5ZJPWSS-BJVEXU0K.js → sizeCapture-X5ZJPWSS-C5lqG0ei.js} +1 -1
  73. package/web/dist/assets/{stateDiagram-2N3HPSRC-Bwu6kd23.js → stateDiagram-2N3HPSRC-DyeISrEU.js} +1 -1
  74. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-5FZbaloZ.js +1 -0
  75. package/web/dist/assets/{swimlanes-5IMT3BWC-BmhEzevT.js → swimlanes-5IMT3BWC-DawuBk_a.js} +2 -2
  76. package/web/dist/assets/swimlanesDiagram-G3AALYLV-DL8PgtmM.js +8 -0
  77. package/web/dist/assets/{timeline-definition-FHXFAJF6-DFPI_uTI.js → timeline-definition-FHXFAJF6-BZJ2YJcm.js} +1 -1
  78. package/web/dist/assets/{vennDiagram-L72KCM5P-DDTpTkBC.js → vennDiagram-L72KCM5P-BMXBVCfe.js} +1 -1
  79. package/web/dist/assets/{wardleyDiagram-EHGQE667-bV2_YVIL.js → wardleyDiagram-EHGQE667-DWedKsrQ.js} +1 -1
  80. package/web/dist/assets/{xychartDiagram-FW5EYKEG-C7bDIXAV.js → xychartDiagram-FW5EYKEG--XdfYceC.js} +1 -1
  81. package/web/dist/index.html +3 -3
  82. package/web/runtime.js +19 -0
  83. package/web/server.js +2 -2
  84. package/web/dist/assets/channel-C-ASbcRr.js +0 -1
  85. package/web/dist/assets/classDiagram-OUVF2IWQ-D2vlJIb1.js +0 -1
  86. package/web/dist/assets/classDiagram-v2-EOCWNBFH-D2vlJIb1.js +0 -1
  87. package/web/dist/assets/index-DRFDn87d.css +0 -1
  88. package/web/dist/assets/pilotswarm-DQNSWfNK.js +0 -105
  89. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-aypsN5jW.js +0 -1
  90. package/web/dist/assets/swimlanesDiagram-G3AALYLV-Duf5C4YK.js +0 -8
@@ -0,0 +1,186 @@
1
+ import React from "react";
2
+
3
+ const h = React.createElement;
4
+ const onOff = enabled => enabled ? "On" : "Off";
5
+ const validRevision = value => typeof value === "string" && /^[1-9]\d{0,18}$/.test(value)
6
+ && BigInt(value) <= 9223372036854775807n;
7
+ const isRecord = value => value !== null && typeof value === "object" && !Array.isArray(value);
8
+
9
+ /** Missing diagnostics are unknown, including telemetry redacted by older servers. */
10
+ export function featureWorkerStatus(flag, workers = [], now = Date.now()) {
11
+ const reports = workers.map(worker => {
12
+ const age = now - new Date(worker.updatedAt).getTime();
13
+ const state = worker.state?.["feature-flags"];
14
+ const recent = Number.isFinite(age) && age >= -5_000 && age < 90_000;
15
+ const eligible = worker.phase === "ready" && recent;
16
+ const validState = isRecord(state) && state.protocolVersion === 1
17
+ && typeof state.initialized === "boolean" && Array.isArray(state.supportedKeys)
18
+ && state.supportedKeys.every(key => typeof key === "string") && isRecord(state.appliedRevisions);
19
+ let delivery = "unknown";
20
+ if (eligible && validState && validRevision(flag.revision)) {
21
+ if (!state.supportedKeys.includes(flag.featureKey)) delivery = "unsupported";
22
+ else if (!state.initialized) delivery = "loading";
23
+ else if (validRevision(state.appliedRevisions[flag.featureKey])) {
24
+ delivery = BigInt(state.appliedRevisions[flag.featureKey]) >= BigInt(flag.revision) ? "updated" : "pending";
25
+ }
26
+ }
27
+ const capability = eligible && validState && ["sync", "off"].includes(state.nativeCapability)
28
+ ? state.nativeCapability : "unknown";
29
+ return { workerNodeId: worker.workerNodeId, phase: worker.phase, recent, eligible, delivery, capability,
30
+ revision: validState && validRevision(state.appliedRevisions[flag.featureKey]) ? state.appliedRevisions[flag.featureKey] : null,
31
+ refreshError: eligible && validState && (state.hasRefreshError === true || typeof state.lastError === "string" && state.lastError.length > 0) };
32
+ });
33
+ const eligible = reports.filter(report => report.eligible);
34
+ return { reports, eligible: eligible.length,
35
+ updated: eligible.filter(report => report.delivery === "updated").length,
36
+ unknown: eligible.filter(report => report.delivery === "unknown").length,
37
+ unsupported: eligible.filter(report => report.delivery === "unsupported").length,
38
+ capable: eligible.filter(report => report.capability === "sync").length,
39
+ incapable: eligible.filter(report => report.capability === "off").length,
40
+ capabilityUnknown: eligible.filter(report => report.capability === "unknown").length,
41
+ refreshErrors: eligible.filter(report => report.refreshError).length,
42
+ stale: reports.filter(report => !report.recent && report.phase !== "draining").length,
43
+ draining: reports.filter(report => report.phase === "draining").length,
44
+ other: reports.filter(report => report.recent && !report.eligible && report.phase !== "draining").length };
45
+ }
46
+
47
+ function deliveryText(status, workersError) {
48
+ if (workersError || !status.eligible || status.unknown === status.eligible) return "Settings delivery: status unavailable";
49
+ return `Settings delivery: ${status.updated} of ${status.eligible} reporting workers updated.${status.unknown ? ` Status unavailable for ${status.unknown}.` : ""}${status.unsupported ? ` ${status.unsupported} do not support this feature.` : ""}${status.refreshErrors ? ` ${status.refreshErrors} reported a refresh problem.` : ""}`;
50
+ }
51
+
52
+ function clusterSummary(enabled, allowPersonal) {
53
+ return `${onOff(enabled)} ${allowPersonal ? "by default. Users can choose On or Off." : "for everyone. Personal settings do not apply."}`;
54
+ }
55
+
56
+ function RadioChoices({ legend, name, value, options, disabled, onChange }) {
57
+ return h("fieldset", { className: "ps-feature-choice-group", disabled },
58
+ h("legend", null, legend),
59
+ h("div", { className: "ps-feature-choices" }, options.map(option => h("label", {
60
+ className: `ps-feature-choice${value === option.value ? " is-selected" : ""}`, key: option.value,
61
+ }, h("input", { type: "radio", name, value: option.value, checked: value === option.value,
62
+ onChange: () => onChange(option.value) }), h("span", null, option.label)))));
63
+ }
64
+
65
+ function FeatureFlagRow({ flag, mode, busy, saving, controller, workers, workersError, isAdmin, userName }) {
66
+ const id = React.useId();
67
+ const draft = controller.getFeatureDraft?.(flag.featureKey);
68
+ const dirty = draft !== undefined;
69
+ const conflict = dirty && (draft.needsReview || draft.expectedRevision !== flag.revision);
70
+ const conflictNeedsRefresh = conflict && draft.needsReview && draft.expectedRevision === flag.revision;
71
+ const storedEnabled = flag.cluster?.enabled ?? flag.defaultEnabled;
72
+ const storedOverride = flag.cluster?.allowUserOverride ?? flag.defaultAllowUserOverride;
73
+ const locked = mode !== "cluster" && !storedOverride;
74
+ const savedChoice = flag.user ? String(flag.user.enabled) : "inherit";
75
+ const choice = dirty ? draft.values === null ? "inherit" : String(draft.values.enabled) : savedChoice;
76
+ const clusterDraft = dirty ? draft.values ?? { enabled: flag.defaultEnabled, allowUserOverride: flag.defaultAllowUserOverride }
77
+ : { enabled: storedEnabled, allowUserOverride: storedOverride };
78
+ const target = mode === "mine" ? "you" : userName;
79
+ const futureTarget = mode === "mine" ? "Your" : `${userName}’s`;
80
+ const savedValue = mode === "cluster" ? `${onOff(storedEnabled)} ${storedOverride ? "by default" : "for everyone"}`
81
+ : `${onOff(flag.effective)} for ${target}`;
82
+ const reason = mode === "cluster" ? storedOverride ? "Users can choose On or Off." : "Personal settings do not apply."
83
+ : locked ? "Required by the cluster." : flag.user ? mode === "mine" ? "Using your choice." : "Using the saved personal choice." : "Following the cluster setting.";
84
+ const status = featureWorkerStatus(flag, workers);
85
+ const isNative = flag.featureKey === "copilot.native_tasks";
86
+ const savedOn = mode === "cluster" ? storedEnabled : flag.effective;
87
+ const knownBlocked = isAdmin && isNative && savedOn && !workersError && status.eligible > 0 && status.incapable === status.eligible;
88
+ const editDisabled = busy || !flag.supported;
89
+ let preview = null;
90
+ if (dirty) {
91
+ if (mode === "cluster") preview = `${draft.values === null ? "Restore the default policy. " : ""}${clusterSummary(clusterDraft.enabled, clusterDraft.allowUserOverride)}${!storedOverride && clusterDraft.allowUserOverride ? " Previously saved personal choices will apply again." : ""}`;
92
+ else if (locked) preview = `${futureTarget} future preference will ${choice === "inherit" ? "follow the cluster setting" : `be ${onOff(choice === "true")}`}. ${onOff(storedEnabled)} still applies while the cluster requires it.`;
93
+ else preview = `${onOff(choice === "inherit" ? storedEnabled : choice === "true")} for ${target}. ${choice === "inherit" ? "Following the cluster setting." : "Using the personal choice."}`;
94
+ }
95
+ return h("section", { className: "ps-feature-flag", "data-feature-key": flag.featureKey, "aria-labelledby": `${id}-title` },
96
+ h("div", { className: "ps-feature-flag-heading" }, h("h3", { id: `${id}-title` }, flag.displayName),
97
+ dirty ? h("span", { className: "ps-feature-unsaved" }, "Unsaved changes") : null),
98
+ h("p", { className: "ps-feature-description" }, isNative ? "Lets Copilot delegate short tasks in the same session workspace. On permits use; Copilot decides when to use native tasks." : flag.description),
99
+ h("div", { className: "ps-feature-saved" },
100
+ h("span", { className: "ps-feature-label" }, "Saved setting"),
101
+ h("strong", { className: `ps-feature-value${(mode === "cluster" ? storedEnabled : flag.effective) ? " is-on" : ""}` }, savedValue),
102
+ h("p", { className: "ps-feature-explanation" }, reason),
103
+ mode !== "cluster" ? h("p", { className: "ps-feature-context" }, `Cluster setting: ${onOff(storedEnabled)}. Personal settings ${storedOverride ? "allowed" : "not allowed"}.`) : null,
104
+ locked ? h("p", { className: "ps-feature-retained" }, `Saved future preference: ${savedChoice === "inherit" ? "Use cluster setting" : onOff(flag.user.enabled)}. This will apply if personal settings are allowed again.`) : null),
105
+ !flag.supported ? h("p", { role: "status" }, "This server does not support changing this feature.") : null,
106
+ knownBlocked ? h("p", { className: "ps-feature-blocker", role: "status" }, `The saved setting is On, but none of the ${status.eligible} reporting workers is configured for native tasks. Native tasks cannot run on those workers.`) : null,
107
+ h("div", { className: "ps-feature-editor" }, mode === "cluster" ? [
108
+ h(RadioChoices, { key: "enabled", legend: "Cluster setting", name: `${id}-cluster`, value: String(clusterDraft.enabled), disabled: editDisabled,
109
+ options: [{ value: "false", label: "Off" }, { value: "true", label: "On" }],
110
+ onChange: value => controller.setFeatureDraft(flag.featureKey, { ...clusterDraft, enabled: value === "true" }) }),
111
+ h(RadioChoices, { key: "override", legend: "Personal settings", name: `${id}-override`, value: String(clusterDraft.allowUserOverride), disabled: editDisabled,
112
+ options: [{ value: "true", label: "Allowed" }, { value: "false", label: "Not allowed" }],
113
+ onChange: value => controller.setFeatureDraft(flag.featureKey, { ...clusterDraft, allowUserOverride: value === "true" }) }),
114
+ ] : h(RadioChoices, { legend: locked ? "Preference for when personal settings are allowed" : mode === "mine" ? "Your choice" : `${userName}’s choice`,
115
+ name: `${id}-user`, value: choice, disabled: editDisabled,
116
+ options: [{ value: "inherit", label: `Use cluster setting (currently ${onOff(storedEnabled)})` },
117
+ { value: "true", label: mode === "mine" ? "On for me" : "On for this user" },
118
+ { value: "false", label: mode === "mine" ? "Off for me" : "Off for this user" }],
119
+ onChange: value => controller.setFeatureDraft(flag.featureKey, value === "inherit" ? null : { enabled: value === "true" }) })),
120
+ dirty ? h("div", { className: "ps-feature-preview", role: "status" }, h("strong", null, "After saving: "), preview) : null,
121
+ conflict ? h("p", { className: "ps-feature-conflict", role: "status" }, conflictNeedsRefresh
122
+ ? "Settings changed since this edit began. Refresh settings to load the latest saved value."
123
+ : "Settings changed since this edit began. Review the saved setting and your proposed change before saving.") : null,
124
+ h("div", { className: "ps-feature-actions" },
125
+ h("button", { type: "button", className: "ps-mini-button ps-feature-save", disabled: editDisabled || !dirty || conflict,
126
+ onClick: () => controller.saveFeatureDraft(flag.featureKey) }, saving && dirty ? "Saving…" : locked ? "Save future preference" : "Save changes"),
127
+ h("button", { type: "button", className: "ps-mini-button", disabled: busy || !dirty,
128
+ onClick: () => controller.discardFeatureDraft(flag.featureKey) }, "Discard changes"),
129
+ conflict ? h("button", { type: "button", className: "ps-mini-button", disabled: busy || conflictNeedsRefresh,
130
+ onClick: () => controller.reviewFeatureDraft(flag.featureKey) }, "Review latest settings") : null),
131
+ isAdmin ? h("p", { className: "ps-feature-delivery", role: "status" }, deliveryText(status, workersError)) : null,
132
+ h("details", { className: "ps-feature-details" }, h("summary", null, "Technical details"),
133
+ h("p", null, h("code", null, flag.featureKey), ` · Saved revision ${flag.revision}`),
134
+ h("p", null, "Workers normally check for settings changes within 20 seconds. Settings delivery does not confirm that each session has refreshed its tools."),
135
+ isNative ? h("p", null, "After a worker receives On, native tasks become available on the next turn. After it receives Off, new native tasks are blocked. Tasks already running can finish.") : null,
136
+ isAdmin && isNative ? h("p", null, workersError || !status.eligible || status.capabilityUnknown === status.eligible
137
+ ? "Native task support: status unavailable."
138
+ : `Native task support: ${status.capable} of ${status.eligible} reporting workers configured; ${status.incapable} configured Off; ${status.capabilityUnknown} unknown.`) : null,
139
+ isAdmin && (status.stale || status.draining || status.other) ? h("p", null, `Excluded from current delivery counts: ${status.stale} stale or undated reports; ${status.draining} draining workers; ${status.other} other worker reports.`) : null,
140
+ isAdmin ? h("ul", { className: "ps-feature-worker-list" }, status.reports.map(report => h("li", { key: report.workerNodeId },
141
+ `${report.workerNodeId}: ${report.eligible ? ({ updated: "settings received", pending: "waiting for latest settings", loading: "loading settings", unsupported: "feature unsupported", unknown: "status unavailable" })[report.delivery] : report.phase === "draining" ? "draining; excluded" : !report.recent ? "stale or undated report; status unavailable" : "not reporting ready; excluded"}${report.eligible && report.revision ? `; revision ${report.revision}` : ""}${report.eligible && isNative ? `; native task configuration ${report.capability === "sync" ? "On" : report.capability === "off" ? "Off" : "unknown"}` : ""}${report.refreshError ? "; settings refresh problem" : ""}`))) : null,
142
+ mode === "cluster" ? h("div", { className: "ps-feature-defaults" },
143
+ h("p", null, `Default policy: ${clusterSummary(flag.defaultEnabled, flag.defaultAllowUserOverride)}`),
144
+ h("button", { type: "button", className: "ps-mini-button", disabled: editDisabled || !flag.cluster,
145
+ onClick: () => controller.setFeatureDraft(flag.featureKey, null) }, "Preview default policy"),
146
+ h("p", { className: "ps-feature-explanation" }, "Preview stages removal of the cluster override. Save changes to use the code-defined defaults; personal choices are kept.")) : null));
147
+ }
148
+
149
+ export function FeatureFlagsPanel({ controller, features = {}, isAdmin, workers = [], workersError = null }) {
150
+ const mode = features.mode || "mine";
151
+ const [userQuery, setUserQuery] = React.useState(features.userQuery || "");
152
+ const user = features.users?.find(entry => entry.userId === features.userId);
153
+ const userName = user?.displayName || user?.email || user?.subject || (features.userId ? `user ${features.userId}` : "this user");
154
+ const busy = features.saving || features.loading;
155
+ return h("section", { className: "ps-feature-flags-panel", "aria-label": "Feature flags" },
156
+ h("header", { className: "ps-feature-flag-heading" }, h("h2", null, "Feature flags"),
157
+ h("button", { type: "button", className: "ps-mini-button", disabled: busy, onClick: () => controller.refreshFeatureFlags() }, "Refresh settings")),
158
+ h("div", { role: "tablist", "aria-label": "Feature settings scope", className: "ps-feature-tabs" },
159
+ [{ mode: "mine", label: "My settings" }, ...(isAdmin ? [{ mode: "cluster", label: "Cluster settings" }, { mode: "users", label: "User settings" }] : [])].map(tab => {
160
+ const count = controller.getFeatureDraftCount?.(tab.mode) || 0;
161
+ return h("button", { type: "button", key: tab.mode, role: "tab", "aria-selected": mode === tab.mode, disabled: features.saving,
162
+ className: "ps-mini-button", onClick: () => controller.selectFeatureScope(tab.mode) }, tab.label,
163
+ count ? h("span", { className: "ps-feature-unsaved" }, `${count} unsaved`) : null);
164
+ })),
165
+ mode === "users" && isAdmin ? h("div", { className: "ps-feature-user" },
166
+ h("form", { onSubmit: event => { event.preventDefault(); void controller.searchFeatureUsers(userQuery); } },
167
+ h("label", null, "Find user ", h("input", { type: "search", value: userQuery,
168
+ "aria-label": "Find feature settings user", placeholder: "Name, email or identity", onChange: event => setUserQuery(event.target.value) })),
169
+ h("button", { className: "ps-mini-button", disabled: features.usersLoading || features.saving }, "Search")),
170
+ h("label", null, "User ", h("select", { "aria-label": "Feature settings user", value: features.userId ?? "", disabled: features.saving,
171
+ onChange: event => controller.selectFeatureScope("users", event.target.value ? Number(event.target.value) : null) },
172
+ h("option", { value: "" }, "Select a user"),
173
+ (features.users || []).map(entry => h("option", { key: entry.userId, value: entry.userId }, `${entry.displayName || entry.email || entry.subject}${entry.displayName && entry.email ? ` — ${entry.email}` : ""}${features.selectedUserOutsideResults && entry.userId === features.userId ? " (current selection)" : ""}`)))),
174
+ features.selectedUserOutsideResults ? h("p", { className: "ps-feature-explanation" }, "Current selection kept while you search.") : null,
175
+ user ? h("p", { className: "ps-feature-user-identity" }, h("strong", null, userName), user.email ? h("span", null, user.email) : null)
176
+ : features.userId ? h("p", null, `Selected user ID: ${features.userId}`) : null,
177
+ features.users?.length >= 500 ? h("p", null, "Showing the first 500 users. Refine your search to find another user.") : null) : null,
178
+ features.error ? h("p", { role: "alert" }, features.error) : null,
179
+ features.metadataError ? h("p", { role: "status" }, features.metadataError) : null,
180
+ isAdmin && workersError ? h("p", { role: "status" }, "Worker reports could not be refreshed. Settings delivery status is unavailable.") : null,
181
+ features.notice ? h("p", { role: "status" }, features.notice) : null,
182
+ features.loading ? h("p", { role: "status" }, "Loading feature settings…") : null,
183
+ (mode === "mine" || isAdmin ? features.data?.flags || [] : []).map(flag => h(FeatureFlagRow, { key: `${mode}:${features.userId}:${flag.featureKey}`,
184
+ flag, mode, busy, saving: features.saving, controller, workers, workersError, isAdmin, userName })),
185
+ !features.loading && features.data?.flags?.length === 0 ? h("p", null, "No feature definitions are published.") : null);
186
+ }
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ import { NATIVE_TASK_LABELS } from "../../core/src/native-tasks.js";
3
+
4
+ const TERMINAL = new Set(["completed", "failed", "cancelled", "interrupted"]);
5
+ const MARKS = { starting: "◷", running: "◷", waiting: "Ⅱ", completed: "✓", failed: "!", cancelled: "■", interrupted: "↯" };
6
+ function duration(task, now) {
7
+ const ms = task.durationMs ?? (task.startedAt ? (task.completedAt || now) - task.startedAt : null);
8
+ if (!Number.isFinite(ms) || ms < 0) return "";
9
+ const seconds = Math.floor(ms / 1000);
10
+ return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
11
+ }
12
+
13
+ export const NativeTaskCard = React.memo(function NativeTaskCard({ group, colors }) {
14
+ const [showAll, setShowAll] = React.useState(false);
15
+ const [now, setNow] = React.useState(Date.now);
16
+ const active = group.tasks.some(task => !TERMINAL.has(task.status));
17
+ React.useEffect(() => {
18
+ if (!active) return undefined;
19
+ const timer = setInterval(() => setNow(Date.now()), 1000);
20
+ return () => clearInterval(timer);
21
+ }, [active]);
22
+ const counts = group.tasks.reduce((acc, task) => {
23
+ const label = NATIVE_TASK_LABELS[task.status] || "Unknown";
24
+ acc[label] = (acc[label] || 0) + 1;
25
+ return acc;
26
+ }, {});
27
+ const countLabel = Object.entries(counts).map(([label, count]) => `${count} ${label.toLowerCase()}`).join(" · ");
28
+ const tasks = showAll ? group.tasks : group.tasks.slice(0, 3);
29
+ return React.createElement("section", { className: "ps-native-tasks", "aria-label": "Native tasks", "data-task-group": group.id },
30
+ React.createElement("header", { className: "ps-native-tasks-header" },
31
+ React.createElement("span", { className: "ps-native-tasks-title" },
32
+ React.createElement("span", { className: "ps-native-task-branch", "aria-hidden": true }, "⑂"), "Native tasks"),
33
+ React.createElement("span", { className: "ps-native-tasks-count", "aria-live": "polite" }, countLabel)),
34
+ tasks.map(task => {
35
+ const color = colors[task.status] || colors.running;
36
+ const preview = task.error || task.result || task.preview || (task.status === "completed" ? "Task completed." : "");
37
+ const time = duration(task, now);
38
+ return React.createElement("details", { key: task.id, className: "ps-native-task", "data-task-id": task.id, "data-status": task.status,
39
+ style: { "--ps-native-task-accent": color } },
40
+ React.createElement("summary", null,
41
+ React.createElement("span", { className: "ps-native-task-mark", "aria-hidden": true }, MARKS[task.status] || "?"),
42
+ React.createElement("span", { className: "ps-native-task-main" },
43
+ React.createElement("span", { className: "ps-native-task-title" }, task.title),
44
+ preview ? React.createElement("span", { className: "ps-native-task-preview" }, preview.replace(/\s+/g, " ").slice(0, 240)) : null),
45
+ React.createElement("span", { className: "ps-native-task-meta" },
46
+ React.createElement("span", { className: "ps-native-task-status" }, task.telemetryStale ? "Reconnecting" : NATIVE_TASK_LABELS[task.status] || task.status),
47
+ React.createElement("span", null, [time, `${task.toolCalls || 0} calls`].filter(Boolean).join(" · "))),
48
+ React.createElement("span", { className: "ps-native-task-chevron", "aria-hidden": true }, "›")),
49
+ React.createElement("div", { className: "ps-native-task-detail" },
50
+ React.createElement("div", { className: "ps-native-task-scope" }, [task.profile, task.model, task.reasoningEffort, "Same worker"].filter(Boolean).join(" · ")),
51
+ task.result && !task.error ? React.createElement("div", { className: "ps-native-task-scope" }, "Result excerpt") : null,
52
+ React.createElement("p", { className: "ps-native-task-result" }, task.error || task.result || task.preview
53
+ || (task.status === "completed" ? "Task completed. A result excerpt is not available in this recording." : "No result available yet.")),
54
+ task.recentActivity?.length ? React.createElement("ul", { className: "ps-native-task-activity" },
55
+ task.recentActivity.map((activity, i) => React.createElement("li", { key: i }, activity.message))) : null));
56
+ }),
57
+ group.tasks.length > 3 ? React.createElement("button", { type: "button", className: "ps-native-tasks-more", "aria-expanded": showAll,
58
+ onClick: () => setShowAll(value => !value) }, showAll ? "Show fewer tasks" : `Show ${group.tasks.length - 3} more tasks`) : null);
59
+ });
@@ -1,4 +1,6 @@
1
1
  import React from "react";
2
+ import { FeatureFlagsPanel } from "./feature-flags-panel.js";
3
+ import { NativeTaskCard } from "./native-task-card.js";
2
4
  // createPortal is only invoked by browser-only surfaces (tooltips, toolbar
3
5
  // slots, and viewport-level dialogs); the import itself is side-effect-free
4
6
  // and react-dom is a dependency wherever this file loads, so it is safe in the
@@ -838,7 +840,14 @@ function normalizeLines(lines) {
838
840
  };
839
841
 
840
842
  for (const line of lines || []) {
841
- if (line?.kind === "assistantPreview") {
843
+ if (line?.kind === "chatCall" || line?.callPreview !== undefined) {
844
+ // A disclosure is one keyed record, even when its preview contains
845
+ // escaped newlines. Splitting it duplicates callKey and leaves
846
+ // orphaned React nodes behind when the session is replaced.
847
+ normalized.push(line);
848
+ continue;
849
+ }
850
+ if (line?.kind === "assistantPreview" || line?.kind === "nativeTasks") {
842
851
  // Preserve selector-cache identity so another stream's ticks don't
843
852
  // rerender every completed response or recreate its scroll observer.
844
853
  normalized.push(line);
@@ -1387,6 +1396,65 @@ function ChatCallLine({ line }) {
1387
1396
  React.createElement("pre", { className: "ps-chat-call-payload" }, line.body)) : null);
1388
1397
  }
1389
1398
 
1399
+ function ChatActivityRun({ calls }) {
1400
+ const latest = calls[calls.length - 1] || {};
1401
+ const active = latest.status === "Called" || latest.status === "Started";
1402
+ const failed = calls.some((call) => call.status === "Failed");
1403
+ const [open, setOpen] = React.useState(active);
1404
+ const viewportRef = React.useRef(null);
1405
+ const followRef = React.useRef(true);
1406
+ const categories = new Set(calls.map((call) => call.category || "Tool"));
1407
+ const countLabel = categories.size === 1 && categories.has("Tool")
1408
+ ? `${calls.length} tool ${calls.length === 1 ? "call" : "calls"}`
1409
+ : categories.size === 1 && categories.has("Agent")
1410
+ ? `${calls.length} agent ${calls.length === 1 ? "activity" : "activities"}`
1411
+ : `${calls.length} activities`;
1412
+ const latestName = String(latest.text || latest.category || "activity").split(" — ")[0];
1413
+ const status = active ? "Working" : failed ? "Failed" : "Done";
1414
+ const updateKey = `${latest.callKey || ""}:${latest.status || ""}:${String(latest.body || "").length}`;
1415
+
1416
+ React.useLayoutEffect(() => {
1417
+ const viewport = viewportRef.current;
1418
+ if (open && viewport && followRef.current) viewport.scrollTop = viewport.scrollHeight;
1419
+ }, [open, calls.length, updateKey]);
1420
+
1421
+ return React.createElement("details", {
1422
+ className: "ps-native-tasks ps-activity-run",
1423
+ open,
1424
+ onToggle: (event) => setOpen(event.currentTarget.open),
1425
+ },
1426
+ React.createElement("summary", { className: "ps-native-tasks-header ps-activity-run-summary" },
1427
+ React.createElement("span", { className: "ps-native-tasks-title" },
1428
+ React.createElement("span", { className: "ps-native-task-branch", "aria-hidden": true }, "⌘"),
1429
+ countLabel),
1430
+ React.createElement("span", { className: "ps-activity-run-latest", title: latest.text || "" }, `latest: ${latestName}`),
1431
+ React.createElement("span", { className: `ps-activity-run-status${failed ? " is-failed" : ""}` }, status),
1432
+ React.createElement("span", { className: "ps-activity-run-chevron", "aria-hidden": true }, "›")),
1433
+ React.createElement("div", {
1434
+ ref: viewportRef,
1435
+ className: "ps-activity-run-viewport",
1436
+ role: "region",
1437
+ "aria-label": `${countLabel} activity log`,
1438
+ tabIndex: 0,
1439
+ onScroll: (event) => {
1440
+ event.stopPropagation();
1441
+ followRef.current = getScrollDistanceToBottom(event.currentTarget) <= 24;
1442
+ },
1443
+ onWheel: (event) => {
1444
+ event.stopPropagation();
1445
+ if (event.deltaY < 0) followRef.current = false;
1446
+ },
1447
+ onTouchStart: (event) => {
1448
+ event.stopPropagation();
1449
+ followRef.current = false;
1450
+ },
1451
+ onTouchMove: (event) => event.stopPropagation(),
1452
+ onTouchEnd: (event) => event.stopPropagation(),
1453
+ }, calls.map((call) => React.createElement(ChatCallLine, { key: call.callKey, line: call }))),
1454
+ React.createElement("div", { className: "ps-activity-run-footer" },
1455
+ `Showing ${calls.length} ${calls.length === 1 ? "entry" : "entries"} · Scroll for earlier activity`));
1456
+ }
1457
+
1390
1458
  /**
1391
1459
  * A canvas action is a button press inside the drawn page, not something the
1392
1460
  * viewer typed. Printing the raw `[canvas-action] {…}` JSON as a chat message
@@ -3286,12 +3354,24 @@ function parseStructuredChatBlocks(lines = []) {
3286
3354
  for (let index = 0; index < lines.length;) {
3287
3355
  const currentLine = lines[index];
3288
3356
 
3289
- if (currentLine?.kind === "chatCall" || currentLine?.callPreview !== undefined) {
3290
- blocks.push({ type: "chatCall", line: currentLine.callPreview !== undefined
3291
- ? { ...currentLine, text: currentLine.callPreview, category: "Agent" } : currentLine });
3357
+ if (currentLine?.kind === "nativeTasks") {
3358
+ blocks.push({ type: "nativeTasks", group: currentLine.group });
3292
3359
  index += 1;
3293
3360
  continue;
3294
3361
  }
3362
+ if (currentLine?.kind === "chatCall" || currentLine?.callPreview !== undefined) {
3363
+ const calls = [];
3364
+ while (index < lines.length) {
3365
+ const line = lines[index];
3366
+ if (line?.kind !== "chatCall" && line?.callPreview === undefined) break;
3367
+ calls.push(line.callPreview !== undefined
3368
+ ? { ...line, text: line.callPreview, category: "Agent" }
3369
+ : line);
3370
+ index += 1;
3371
+ }
3372
+ blocks.push({ type: "chatCallGroup", groupKey: calls[0]?.callKey, calls });
3373
+ continue;
3374
+ }
3295
3375
 
3296
3376
  if (currentLine?.kind === "assistantPreview") {
3297
3377
  blocks.push({ type: "assistantPreview", line: currentLine });
@@ -3718,8 +3798,14 @@ const AssistantPreviewCard = React.memo(function AssistantPreviewCard({ line, th
3718
3798
  function StructuredBlockList({ blocks, theme, controller = null }) {
3719
3799
  return React.createElement(React.Fragment, null,
3720
3800
  (blocks || []).map((block, index) => {
3721
- if (block.type === "chatCall") {
3722
- return React.createElement(ChatCallLine, { key: block.line.callKey, line: block.line });
3801
+ if (block.type === "nativeTasks") {
3802
+ return React.createElement(NativeTaskCard, { key: block.group.id, group: block.group,
3803
+ colors: { starting: resolveColor(theme, "cyan"), running: resolveColor(theme, "cyan"),
3804
+ waiting: resolveColor(theme, "yellow"), completed: resolveColor(theme, "green"),
3805
+ failed: resolveColor(theme, "red"), cancelled: resolveColor(theme, "gray"), interrupted: resolveColor(theme, "yellow") } });
3806
+ }
3807
+ if (block.type === "chatCallGroup") {
3808
+ return React.createElement(ChatActivityRun, { key: block.groupKey, calls: block.calls });
3723
3809
  }
3724
3810
  if (block.type === "assistantPreview") {
3725
3811
  return React.createElement(AssistantPreviewCard, {
@@ -5599,8 +5685,8 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
5599
5685
  // shortcut handler decides "am I editable?" from the event target, the
5600
5686
  // rest of what the user typed ran as commands (d = complete,
5601
5687
  // D = delete). Scrolling on every refresh has a milder failure but the
5602
- // same shape: the list yanks back to the active row while the user is
5603
- // deliberately scrolled away browsing older sessions.
5688
+ // same shape. Selection must never alter the list's scroll position;
5689
+ // only the user's own scroll gestures move it.
5604
5690
  if (revealedRowKeyRef.current === activeRowRevealKey) return;
5605
5691
  revealedRowKeyRef.current = activeRowRevealKey;
5606
5692
 
@@ -5617,11 +5703,6 @@ function SessionPane({ controller, actions = null, panelClassName = "", structur
5617
5703
  if (viewState.focused && focused !== activeButton && !isTypingTarget) {
5618
5704
  activeButton.focus({ preventScroll: true });
5619
5705
  }
5620
- // Selection can change from outside this pane (deep links, newly
5621
- // created sessions, MoA focus and other navigation surfaces). Center
5622
- // the row once for that selection so its surrounding sessions remain
5623
- // visible, without re-centering on routine status/catalog refreshes.
5624
- activeButton.scrollIntoView({ block: "center" });
5625
5706
  }, [activeRowRevealKey, viewState.activeSessionId, viewState.focused, viewState.modalOpen, viewState.sessionsFlat]);
5626
5707
 
5627
5708
  const panelActions = React.createElement(React.Fragment, null,
@@ -13193,9 +13274,16 @@ function formatAdminPrincipalLabel(principal) {
13193
13274
 
13194
13275
  function AdminConsolePanel({ controller, mobile = false }) {
13195
13276
  const view = useControllerSelector(controller, selectAdminConsole, shallowEqualObject);
13277
+ const features = useControllerSelector(controller, state => state.admin.features);
13278
+ const featureWorkers = useControllerSelector(controller, state => state.admin.workers);
13279
+ const featureRole = useControllerSelector(controller, state => state.auth?.authorization?.role);
13196
13280
  const packages = view.packages || {};
13197
13281
  const showPackages = view.section === "packages";
13198
13282
  const showWorkers = view.section === "workers";
13283
+ const showFeatures = view.section === "features";
13284
+ const featureSection = React.createElement(FeatureFlagsPanel, { controller, features,
13285
+ workers: featureWorkers?.list || [], workersError: featureWorkers?.error,
13286
+ isAdmin: view.isAdmin && (!featureRole || featureRole === "admin" || featureRole === "anonymous") });
13199
13287
  const [providerSheet, setProviderSheet] = React.useState(null);
13200
13288
  const [providerSheetBusy, setProviderSheetBusy] = React.useState(false);
13201
13289
  const [providerSheetError, setProviderSheetError] = React.useState(null);
@@ -13344,7 +13432,7 @@ function AdminConsolePanel({ controller, mobile = false }) {
13344
13432
  body = React.createElement("div", { className: "ps-admin-mobile-stack" }, tree,
13345
13433
  React.createElement(AdminWorkersPane, { controller, view }));
13346
13434
  } else {
13347
- body = React.createElement("div", { className: "ps-admin-mobile-stack" }, tree, providerSection);
13435
+ body = React.createElement("div", { className: "ps-admin-mobile-stack" }, tree, showFeatures ? featureSection : providerSection);
13348
13436
  }
13349
13437
  return React.createElement("div", { className: "ps-admin-console is-mobile" },
13350
13438
  header,
@@ -13373,7 +13461,7 @@ function AdminConsolePanel({ controller, mobile = false }) {
13373
13461
  "aria-label": "Resize settings column",
13374
13462
  })),
13375
13463
  React.createElement("div", { className: "ps-admin-main" },
13376
- showPackages ? detail : showWorkers ? React.createElement(AdminWorkersPane, { controller, view }) : providerSection),
13464
+ showPackages ? detail : showWorkers ? React.createElement(AdminWorkersPane, { controller, view }) : showFeatures ? featureSection : providerSection),
13377
13465
  workspacePane),
13378
13466
  dialog,
13379
13467
  createProviderDialog);
@@ -13467,6 +13555,8 @@ function AdminSettingsTree({ controller, view }) {
13467
13555
  } else if (row.id === "sharedProviders") {
13468
13556
  controller.setAdminSection("providers");
13469
13557
  controller.setAdminModelProviderPage("shared");
13558
+ } else if (row.id === "features") {
13559
+ controller.setAdminSection("features");
13470
13560
  } else {
13471
13561
  controller.setAdminSection(row.id === "agents" ? "packages" : "workers");
13472
13562
  }
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-Dn5qSVAS.js";import{p as f}from"./chunk-JWPE2WC7-BHm6Udd8.js";import{_ as n,l as o}from"./mermaid.core-0iRu7sp-.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CVokaaE_.js";import"./pilotswarm-DQNSWfNK.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-MltzhnwP.js";import{p as f}from"./chunk-JWPE2WC7-DWnKTQ72.js";import{_ as n,l as o}from"./mermaid.core-DALDJDu8.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-Dg1cltg6.js";import"./pilotswarm-B9rLtXpI.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-0iRu7sp-.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-DALDJDu8.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};