pilotswarm 0.5.13 → 0.5.15

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 (51) hide show
  1. package/README.md +6 -0
  2. package/mcp/README.md +14 -2
  3. package/mcp/dist/src/context.d.ts +13 -0
  4. package/mcp/dist/src/context.d.ts.map +1 -1
  5. package/mcp/dist/src/context.js +20 -0
  6. package/mcp/dist/src/context.js.map +1 -1
  7. package/mcp/dist/src/server.d.ts.map +1 -1
  8. package/mcp/dist/src/server.js +5 -1
  9. package/mcp/dist/src/server.js.map +1 -1
  10. package/mcp/dist/src/tools/capabilities.d.ts +4 -0
  11. package/mcp/dist/src/tools/capabilities.d.ts.map +1 -1
  12. package/mcp/dist/src/tools/capabilities.js +13 -0
  13. package/mcp/dist/src/tools/capabilities.js.map +1 -1
  14. package/mcp/dist/src/tools/groups.d.ts +5 -4
  15. package/mcp/dist/src/tools/groups.d.ts.map +1 -1
  16. package/mcp/dist/src/tools/groups.js +43 -20
  17. package/mcp/dist/src/tools/groups.js.map +1 -1
  18. package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
  19. package/mcp/dist/src/tools/sessions.js +118 -2
  20. package/mcp/dist/src/tools/sessions.js.map +1 -1
  21. package/package.json +3 -2
  22. package/tui/src/app.js +19 -2
  23. package/tui/src/auth/cli.js +13 -0
  24. package/tui/src/node-sdk-transport.js +99 -13
  25. package/tui/tui-splash-mobile.txt +5 -7
  26. package/tui/tui-splash.txt +13 -9
  27. package/ui/core/src/commands.js +2 -0
  28. package/ui/core/src/controller.js +454 -35
  29. package/ui/core/src/history.js +19 -1
  30. package/ui/core/src/reducer.js +121 -8
  31. package/ui/core/src/selectors.js +204 -14
  32. package/ui/core/src/state.js +3 -0
  33. package/ui/core/src/themes/helpers.js +4 -0
  34. package/ui/react/src/components.js +95 -6
  35. package/ui/react/src/web-app.js +798 -157
  36. package/web/api/router.js +7 -6
  37. package/web/api/ws.js +9 -0
  38. package/web/auth/index.js +5 -0
  39. package/web/auth/providers/dev.js +119 -0
  40. package/web/authz.js +142 -0
  41. package/web/dist/assets/index-CZizkB5Z.js +24 -0
  42. package/web/dist/assets/index-D9e2TGjO.css +1 -0
  43. package/web/dist/assets/pilotswarm-KMqn3ZJs.js +90 -0
  44. package/web/dist/assets/react-l0sNRNKZ.js +1 -0
  45. package/web/dist/index.html +3 -4
  46. package/web/runtime.js +553 -37
  47. package/web/server.js +2 -2
  48. package/web/dist/assets/index-bQ2QInMX.js +0 -24
  49. package/web/dist/assets/index-oldX95Tp.css +0 -1
  50. package/web/dist/assets/pilotswarm-DRs6o-lA.js +0 -90
  51. package/web/dist/assets/react-C9iQPS2h.js +0 -1
@@ -25,6 +25,7 @@ import {
25
25
  selectContextTierPickerModal,
26
26
  selectRenameSessionModal,
27
27
  selectSessionAgentPickerModal,
28
+ selectShareSessionModal,
28
29
  selectSessionGroupNameModal,
29
30
  selectSessionGroupPickerModal,
30
31
  selectSessionOwnerFilterModal,
@@ -138,8 +139,30 @@ function formatProcessRssTitleRuns(rssBytes) {
138
139
  ];
139
140
  }
140
141
 
141
- function buildSessionTitleRightRuns(rssRuns, versionLabel = null) {
142
- const titleRuns = [...(Array.isArray(rssRuns) ? rssRuns : [])];
142
+ // The signed-in identity shown in the sessions header. Admins are marked with
143
+ // a leading "(*)" so an operator can tell at a glance they hold elevated rights.
144
+ function formatSignedInIdentityLabel(auth) {
145
+ const principal = auth?.principal;
146
+ if (!principal) return null;
147
+ const base = principal.displayName || principal.email || principal.subject || null;
148
+ if (!base) return null;
149
+ const isAdmin = auth?.authorization?.role === "admin"
150
+ || (Array.isArray(principal.roles) && principal.roles.includes("admin"));
151
+ return isAdmin ? `(*) ${base}` : base;
152
+ }
153
+
154
+ function buildSessionTitleRightRuns(rssRuns, versionLabel = null, identityLabel = null) {
155
+ const titleRuns = [];
156
+ // Signed-in identity (multi-user deployments) sits left of the rss gauge
157
+ // so it's always visible without giving up a whole line.
158
+ const normalizedIdentityLabel = typeof identityLabel === "string" ? identityLabel.trim() : "";
159
+ if (normalizedIdentityLabel) {
160
+ titleRuns.push({ text: normalizedIdentityLabel, color: "yellow", bold: true });
161
+ }
162
+ if (Array.isArray(rssRuns) && rssRuns.length > 0) {
163
+ if (titleRuns.length > 0) titleRuns.push({ text: " ", color: "gray" });
164
+ titleRuns.push(...rssRuns);
165
+ }
143
166
  const normalizedVersionLabel = typeof versionLabel === "string" ? versionLabel.trim() : "";
144
167
  if (!normalizedVersionLabel) return titleRuns.length > 0 ? titleRuns : null;
145
168
  if (titleRuns.length > 0) {
@@ -269,16 +292,19 @@ function buildWorkspacePaneFrames(layout) {
269
292
  const SessionList = React.memo(function SessionList({ controller, maxRows, width, height, frame, versionLabel = null }) {
270
293
  const platform = useUiPlatform();
271
294
  const rssTitleRuns = useProcessRssTitleRuns();
272
- const titleRightRuns = React.useMemo(
273
- () => buildSessionTitleRightRuns(rssTitleRuns, versionLabel),
274
- [rssTitleRuns, versionLabel],
275
- );
276
295
  const sessionView = useControllerSelector(controller, (state) => ({
277
296
  sessions: state.sessions,
278
297
  mode: state.connection?.mode || "local",
279
298
  brandingTitle: state.branding?.title || "PilotSwarm",
280
299
  focused: state.ui.focusRegion === "sessions",
300
+ // Who am I signed in as (null on identity-less/local deployments);
301
+ // admins are prefixed with "(*)".
302
+ identityLabel: formatSignedInIdentityLabel(state.auth),
281
303
  }), shallowEqualObject);
304
+ const titleRightRuns = React.useMemo(
305
+ () => buildSessionTitleRightRuns(rssTitleRuns, versionLabel, sessionView.identityLabel),
306
+ [rssTitleRuns, versionLabel, sessionView.identityLabel],
307
+ );
282
308
  const selectorState = React.useMemo(() => ({
283
309
  sessions: sessionView.sessions,
284
310
  connection: { mode: sessionView.mode },
@@ -320,6 +346,9 @@ const ChatPane = React.memo(function ChatPane({ controller, width, height, frame
320
346
  activeSession: activeSessionId ? state.sessions.byId[activeSessionId] || null : null,
321
347
  activeHistory: activeSessionId ? state.history.bySessionId.get(activeSessionId) || null : null,
322
348
  activeOutbox: activeSessionId ? state.outbox?.bySessionId?.[activeSessionId] || null : null,
349
+ // Viewer identity — so the transcript can say "You" for the viewer's
350
+ // own messages (and tag the owner) in shared sessions.
351
+ authPrincipal: state.auth?.principal || null,
323
352
  branding: state.branding,
324
353
  connectionError: state.connection.error,
325
354
  connectionMode: state.connection.mode,
@@ -336,6 +365,7 @@ const ChatPane = React.memo(function ChatPane({ controller, width, height, frame
336
365
  }
337
366
  return {
338
367
  branding: chatView.branding,
368
+ auth: { principal: chatView.authPrincipal },
339
369
  connection: {
340
370
  error: chatView.connectionError,
341
371
  mode: chatView.connectionMode,
@@ -365,6 +395,7 @@ const ChatPane = React.memo(function ChatPane({ controller, width, height, frame
365
395
  chatView.activeSessionId,
366
396
  chatView.activeSession,
367
397
  chatView.activeOutbox,
398
+ chatView.authPrincipal,
368
399
  chatView.branding,
369
400
  chatView.chatViewMode,
370
401
  chatView.connectionError,
@@ -1420,6 +1451,63 @@ function RenameSessionModalContainer({ controller }) {
1420
1451
  return React.createElement(RenameSessionModal, { state });
1421
1452
  }
1422
1453
 
1454
+ function ShareSessionModal({ state }) {
1455
+ const platform = useUiPlatform();
1456
+ const modal = selectShareSessionModal(state);
1457
+ if (!modal) return null;
1458
+
1459
+ const viewport = typeof platform.getViewport === "function"
1460
+ ? platform.getViewport()
1461
+ : { width: 120, height: 40 };
1462
+ const width = Math.max(56, Math.min(modal.idealWidth || 72, (viewport.width || 120) - 12));
1463
+ const detailsHeight = Math.max(6, Math.min((modal.detailsLines?.length || 0) + 2, 14, (viewport.height || 40) - 14));
1464
+ const helpHeight = Math.max(4, Math.min(5, (viewport.height || 40) - detailsHeight - 8));
1465
+
1466
+ return React.createElement(platform.Overlay, null,
1467
+ React.createElement(platform.Column, { width },
1468
+ React.createElement(platform.Panel, {
1469
+ title: modal.title,
1470
+ color: "cyan",
1471
+ focused: false,
1472
+ width,
1473
+ height: detailsHeight,
1474
+ lines: modal.detailsLines,
1475
+ scrollOffset: 0,
1476
+ scrollMode: "top",
1477
+ marginBottom: 1,
1478
+ fillColor: "surface",
1479
+ }),
1480
+ React.createElement(platform.Input, {
1481
+ label: "grant",
1482
+ value: modal.value,
1483
+ cursorIndex: modal.cursorIndex,
1484
+ focused: true,
1485
+ placeholder: modal.placeholder,
1486
+ rows: 1,
1487
+ }),
1488
+ React.createElement(platform.Panel, {
1489
+ title: modal.helpTitle || "Share Rules",
1490
+ color: "cyan",
1491
+ focused: false,
1492
+ width,
1493
+ height: helpHeight,
1494
+ lines: modal.helpLines,
1495
+ scrollOffset: 0,
1496
+ scrollMode: "top",
1497
+ fillColor: "surface",
1498
+ }),
1499
+ ));
1500
+ }
1501
+
1502
+ function ShareSessionModalContainer({ controller }) {
1503
+ const state = useControllerSelector(controller, (rootState) => ({
1504
+ ui: {
1505
+ modal: rootState.ui.modal,
1506
+ },
1507
+ }), shallowEqualObject);
1508
+ return React.createElement(ShareSessionModal, { state });
1509
+ }
1510
+
1423
1511
  function ArtifactUploadModal({ state }) {
1424
1512
  const platform = useUiPlatform();
1425
1513
  const modal = selectArtifactUploadModal(state);
@@ -2106,6 +2194,7 @@ export function SharedPilotSwarmApp({ controller, versionLabel = null }) {
2106
2194
  React.createElement(StatusBar, { controller }),
2107
2195
  React.createElement(PromptBar, { controller, rows: layoutState.promptRows }),
2108
2196
  React.createElement(RenameSessionModalContainer, { controller }),
2197
+ React.createElement(ShareSessionModalContainer, { controller }),
2109
2198
  React.createElement(ArtifactUploadModalContainer, { controller }),
2110
2199
  React.createElement(ArtifactPickerModalContainer, { controller }),
2111
2200
  React.createElement(HelpModalContainer, { controller }),