pilotswarm 0.4.1 → 0.5.1

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 (89) hide show
  1. package/mcp/README.md +88 -4
  2. package/mcp/dist/src/context.d.ts +36 -6
  3. package/mcp/dist/src/context.d.ts.map +1 -1
  4. package/mcp/dist/src/context.js +102 -8
  5. package/mcp/dist/src/context.js.map +1 -1
  6. package/mcp/dist/src/resources/artifacts.d.ts +5 -0
  7. package/mcp/dist/src/resources/artifacts.d.ts.map +1 -0
  8. package/mcp/dist/src/resources/artifacts.js +39 -0
  9. package/mcp/dist/src/resources/artifacts.js.map +1 -0
  10. package/mcp/dist/src/resources/capabilities.d.ts +4 -0
  11. package/mcp/dist/src/resources/capabilities.d.ts.map +1 -0
  12. package/mcp/dist/src/resources/capabilities.js +17 -0
  13. package/mcp/dist/src/resources/capabilities.js.map +1 -0
  14. package/mcp/dist/src/resources/graph.d.ts +5 -0
  15. package/mcp/dist/src/resources/graph.d.ts.map +1 -0
  16. package/mcp/dist/src/resources/graph.js +45 -0
  17. package/mcp/dist/src/resources/graph.js.map +1 -0
  18. package/mcp/dist/src/server.d.ts.map +1 -1
  19. package/mcp/dist/src/server.js +61 -2
  20. package/mcp/dist/src/server.js.map +1 -1
  21. package/mcp/dist/src/tools/agents.d.ts.map +1 -1
  22. package/mcp/dist/src/tools/agents.js +3 -2
  23. package/mcp/dist/src/tools/agents.js.map +1 -1
  24. package/mcp/dist/src/tools/artifacts.d.ts +12 -0
  25. package/mcp/dist/src/tools/artifacts.d.ts.map +1 -0
  26. package/mcp/dist/src/tools/artifacts.js +92 -0
  27. package/mcp/dist/src/tools/artifacts.js.map +1 -0
  28. package/mcp/dist/src/tools/capabilities.d.ts +27 -0
  29. package/mcp/dist/src/tools/capabilities.d.ts.map +1 -0
  30. package/mcp/dist/src/tools/capabilities.js +69 -0
  31. package/mcp/dist/src/tools/capabilities.js.map +1 -0
  32. package/mcp/dist/src/tools/debug.d.ts +4 -0
  33. package/mcp/dist/src/tools/debug.d.ts.map +1 -0
  34. package/mcp/dist/src/tools/debug.js +94 -0
  35. package/mcp/dist/src/tools/debug.js.map +1 -0
  36. package/mcp/dist/src/tools/facts-enhanced.d.ts +13 -0
  37. package/mcp/dist/src/tools/facts-enhanced.d.ts.map +1 -0
  38. package/mcp/dist/src/tools/facts-enhanced.js +80 -0
  39. package/mcp/dist/src/tools/facts-enhanced.js.map +1 -0
  40. package/mcp/dist/src/tools/graph.d.ts +12 -0
  41. package/mcp/dist/src/tools/graph.d.ts.map +1 -0
  42. package/mcp/dist/src/tools/graph.js +237 -0
  43. package/mcp/dist/src/tools/graph.js.map +1 -0
  44. package/mcp/dist/src/tools/groups.d.ts +10 -0
  45. package/mcp/dist/src/tools/groups.d.ts.map +1 -0
  46. package/mcp/dist/src/tools/groups.js +107 -0
  47. package/mcp/dist/src/tools/groups.js.map +1 -0
  48. package/mcp/dist/src/tools/models.d.ts.map +1 -1
  49. package/mcp/dist/src/tools/models.js +16 -4
  50. package/mcp/dist/src/tools/models.js.map +1 -1
  51. package/mcp/dist/src/tools/observability.d.ts +13 -0
  52. package/mcp/dist/src/tools/observability.d.ts.map +1 -0
  53. package/mcp/dist/src/tools/observability.js +174 -0
  54. package/mcp/dist/src/tools/observability.js.map +1 -0
  55. package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
  56. package/mcp/dist/src/tools/sessions.js +120 -94
  57. package/mcp/dist/src/tools/sessions.js.map +1 -1
  58. package/mcp/dist/src/tools/system.d.ts +14 -0
  59. package/mcp/dist/src/tools/system.d.ts.map +1 -0
  60. package/mcp/dist/src/tools/system.js +110 -0
  61. package/mcp/dist/src/tools/system.js.map +1 -0
  62. package/mcp/dist/src/tools/turn-control.d.ts +13 -0
  63. package/mcp/dist/src/tools/turn-control.d.ts.map +1 -0
  64. package/mcp/dist/src/tools/turn-control.js +98 -0
  65. package/mcp/dist/src/tools/turn-control.js.map +1 -0
  66. package/mcp/dist/src/util/respond.d.ts +21 -0
  67. package/mcp/dist/src/util/respond.d.ts.map +1 -0
  68. package/mcp/dist/src/util/respond.js +42 -0
  69. package/mcp/dist/src/util/respond.js.map +1 -0
  70. package/package.json +5 -4
  71. package/tui/bin/tui.js +0 -3
  72. package/tui/src/app.js +36 -5
  73. package/tui/src/node-sdk-transport.js +24 -0
  74. package/ui/core/src/commands.js +6 -0
  75. package/ui/core/src/controller.js +137 -2
  76. package/ui/core/src/reducer.js +31 -1
  77. package/ui/core/src/selectors.js +414 -17
  78. package/ui/core/src/state.js +2 -0
  79. package/ui/react/src/chat-status.js +22 -0
  80. package/ui/react/src/components.js +68 -6
  81. package/ui/react/src/web-app.js +69 -8
  82. package/web/dist/assets/{index-xJ8IzIZY.js → index-BmqU2WsR.js} +4 -4
  83. package/web/dist/assets/index-D2-7fi56.css +1 -0
  84. package/web/dist/assets/pilotswarm-cIaYAE9e.js +90 -0
  85. package/web/dist/assets/{react-CEPDSRB6.js → react-CRYBfNR4.js} +1 -1
  86. package/web/dist/index.html +4 -4
  87. package/web/runtime.js +30 -0
  88. package/web/dist/assets/index-DmGOcKR-.css +0 -1
  89. package/web/dist/assets/pilotswarm-D9pEmenA.js +0 -90
@@ -18,6 +18,10 @@ import {
18
18
  getFocusRightTarget,
19
19
  getPromptInputRows,
20
20
  MIN_SESSION_PANE_HEIGHT,
21
+ MIN_CHAT_PANE_HEIGHT,
22
+ MIN_ACTIVITY_PANE_HEIGHT,
23
+ MIN_INSPECTOR_PANE_HEIGHT,
24
+ DEFAULT_ACTIVITY_PANE_RATIO,
21
25
  normalizeFocusRegion,
22
26
  } from "./layout.js";
23
27
  import { parseTerminalMarkupRuns } from "./formatting.js";
@@ -25,6 +29,7 @@ import {
25
29
  selectActiveArtifactLinks,
26
30
  selectActiveHttpLinks,
27
31
  selectActivityPane,
32
+ selectLiveActivityLines,
28
33
  selectChatLines,
29
34
  selectFileBrowserItems,
30
35
  selectFileSessionIdsForScope,
@@ -2883,6 +2888,10 @@ export class PilotSwarmUiController {
2883
2888
  this.exitPendingPromptEdit({ restoreDraft: true });
2884
2889
  }
2885
2890
  this.dispatch({ type: "sessions/selected", sessionId });
2891
+ // Sequence-tab turn selection/expansion is per-session; clear it on
2892
+ // switch so a stale turn index doesn't carry into another session.
2893
+ this.dispatch({ type: "ui/sequenceExpandedTurns", turns: [] });
2894
+ this.dispatch({ type: "ui/sequenceSelectedTurn", turn: null });
2886
2895
  }
2887
2896
  if (this.getState().sessions.byId[sessionId]?.isGroup) {
2888
2897
  this.detachActiveSession();
@@ -3534,6 +3543,19 @@ export class PilotSwarmUiController {
3534
3543
  await this.refreshSessions();
3535
3544
  }
3536
3545
 
3546
+ openHelpModal() {
3547
+ this.dispatch({
3548
+ type: "ui/modal",
3549
+ modal: {
3550
+ type: "help",
3551
+ title: "Keybindings",
3552
+ selectedIndex: 0,
3553
+ previousFocus: this.getState().ui.focusRegion,
3554
+ },
3555
+ });
3556
+ this.dispatch({ type: "ui/status", text: "Keybindings — ? or Esc to close" });
3557
+ }
3558
+
3537
3559
  openThemePicker() {
3538
3560
  const themes = listThemes().map((theme) => ({
3539
3561
  id: theme.id,
@@ -4160,7 +4182,13 @@ export class PilotSwarmUiController {
4160
4182
 
4161
4183
  moveModalSelection(delta) {
4162
4184
  const modal = this.getState().ui.modal;
4163
- if (!modal || !Array.isArray(modal.items) || modal.items.length === 0) return;
4185
+ if (!modal) return;
4186
+ if (modal.type === "help") {
4187
+ const current = Math.max(0, Number(modal.selectedIndex) || 0);
4188
+ this.dispatch({ type: "ui/modalSelection", index: Math.max(0, current + delta) });
4189
+ return;
4190
+ }
4191
+ if (!Array.isArray(modal.items) || modal.items.length === 0) return;
4164
4192
  if (modal.type === "logFilter" || modal.type === "filesFilter" || modal.type === "historyFormat") {
4165
4193
  const currentPaneIndex = Math.max(0, Math.min(Number(modal.selectedIndex) || 0, modal.items.length - 1));
4166
4194
  const selected = modal.items[currentPaneIndex];
@@ -4216,6 +4244,10 @@ export class PilotSwarmUiController {
4216
4244
  async confirmModal() {
4217
4245
  const modal = this.getState().ui.modal;
4218
4246
  if (!modal) return;
4247
+ if (modal.type === "help") {
4248
+ this.closeModal();
4249
+ return;
4250
+ }
4219
4251
  if (modal.type === "confirm") {
4220
4252
  const previousFocus = modal.previousFocus;
4221
4253
  this.dispatch({ type: "ui/modal", modal: null });
@@ -4782,6 +4814,88 @@ export class PilotSwarmUiController {
4782
4814
  }
4783
4815
  }
4784
4816
 
4817
+ // Focus-aware vertical resize: [ / ] grow or shrink whichever pane is
4818
+ // focused. Sessions and chat share the left-column vertical split;
4819
+ // inspector and activity share the right-column vertical split. A positive
4820
+ // delta always grows the focused pane at the expense of its sibling.
4821
+ resizeFocusedPane(delta) {
4822
+ const focus = this.getState().ui.focusRegion;
4823
+ const layoutState = this.getState().ui.layout || {};
4824
+ const bodyHeight = this.getCurrentLayout().bodyHeight ?? (layoutState.viewportHeight ?? 40);
4825
+ const totalHeight = layoutState.viewportHeight ?? 40;
4826
+ // Bound the adjust so BOTH panes stay strictly ABOVE their collapse
4827
+ // thresholds (the collapse check is `<=`, hence the +1). A keyboard
4828
+ // resize then never hides a pane — which would drop it from the Tab
4829
+ // cycle — and never lands on a dead plateau. A positive delta grows the
4830
+ // focused pane.
4831
+ const clamp = (current, signed, min, max) => {
4832
+ const hi = Math.max(min, max);
4833
+ return Math.max(min, Math.min(hi, (current || 0) + signed));
4834
+ };
4835
+ if (focus === FOCUS_REGIONS.SESSIONS || focus === FOCUS_REGIONS.CHAT) {
4836
+ const base = getBaseSessionPaneHeight(bodyHeight);
4837
+ const minH = MIN_SESSION_PANE_HEIGHT + 1;
4838
+ const maxH = Math.min(getMaxSessionPaneHeight(totalHeight, bodyHeight), bodyHeight - MIN_CHAT_PANE_HEIGHT - 1);
4839
+ const signed = focus === FOCUS_REGIONS.CHAT ? -delta : delta;
4840
+ const next = clamp(layoutState.sessionPaneAdjust, signed, minH - base, maxH - base);
4841
+ this.dispatch({ type: "ui/sessionPaneAdjust", sessionPaneAdjust: next });
4842
+ } else if (focus === FOCUS_REGIONS.INSPECTOR || focus === FOCUS_REGIONS.ACTIVITY) {
4843
+ const base = Math.max(MIN_ACTIVITY_PANE_HEIGHT, Math.floor(bodyHeight * DEFAULT_ACTIVITY_PANE_RATIO));
4844
+ const minH = MIN_ACTIVITY_PANE_HEIGHT + 1;
4845
+ const maxH = bodyHeight - MIN_INSPECTOR_PANE_HEIGHT - 1;
4846
+ const signed = focus === FOCUS_REGIONS.INSPECTOR ? -delta : delta;
4847
+ const next = clamp(layoutState.activityPaneAdjust, signed, minH - base, maxH - base);
4848
+ this.dispatch({ type: "ui/activityPaneAdjust", activityPaneAdjust: next });
4849
+ }
4850
+ }
4851
+
4852
+ getActiveSequenceCompletedTurns() {
4853
+ const state = this.getState();
4854
+ const sid = state.sessions.activeSessionId;
4855
+ if (!sid) return [];
4856
+ const history = state.history.bySessionId?.get?.(sid);
4857
+ const turns = [];
4858
+ const seen = new Set();
4859
+ for (const event of history?.events || []) {
4860
+ if (event?.eventType !== "session.turn_completed") continue;
4861
+ const turn = Number(event?.data?.turnIndex ?? event?.data?.iteration);
4862
+ if (!Number.isFinite(turn) || seen.has(turn)) continue;
4863
+ seen.add(turn);
4864
+ turns.push(turn);
4865
+ }
4866
+ turns.sort((a, b) => a - b);
4867
+ return turns;
4868
+ }
4869
+
4870
+ // Move the sequence-tab turn cursor among completed turns. First press with
4871
+ // no selection lands on the latest turn; subsequent presses step.
4872
+ moveSequenceSelection(delta) {
4873
+ const turns = this.getActiveSequenceCompletedTurns();
4874
+ if (turns.length === 0) return;
4875
+ const at = turns.indexOf(Number(this.getState().ui.sequenceSelectedTurn));
4876
+ const index = at === -1
4877
+ ? turns.length - 1
4878
+ : Math.max(0, Math.min(turns.length - 1, at + delta));
4879
+ this.dispatch({ type: "ui/sequenceSelectedTurn", turn: turns[index] });
4880
+ }
4881
+
4882
+ toggleSequenceTurnExpanded() {
4883
+ const turns = this.getActiveSequenceCompletedTurns();
4884
+ if (turns.length === 0) return;
4885
+ let selected = Number(this.getState().ui.sequenceSelectedTurn);
4886
+ if (!turns.includes(selected)) {
4887
+ selected = turns[turns.length - 1];
4888
+ this.dispatch({ type: "ui/sequenceSelectedTurn", turn: selected });
4889
+ }
4890
+ const expanded = Array.isArray(this.getState().ui.sequenceExpandedTurns)
4891
+ ? this.getState().ui.sequenceExpandedTurns.map(Number)
4892
+ : [];
4893
+ const next = expanded.includes(selected)
4894
+ ? expanded.filter((turn) => turn !== selected)
4895
+ : [...expanded, selected];
4896
+ this.dispatch({ type: "ui/sequenceExpandedTurns", turns: next });
4897
+ }
4898
+
4785
4899
  nextInspectorTab() {
4786
4900
  const current = this.getState().ui.inspectorTab;
4787
4901
  const inspectorTab = cycleValue(INSPECTOR_TABS, current, 1);
@@ -5058,7 +5172,10 @@ export class PilotSwarmUiController {
5058
5172
 
5059
5173
  const contentWidth = Math.max(20, layout.leftWidth - 4);
5060
5174
  const contentHeight = Math.max(1, layout.chatPaneHeight - 2);
5061
- const lines = selectChatLines(state, contentWidth);
5175
+ const lines = [
5176
+ ...selectChatLines(state, contentWidth),
5177
+ ...selectLiveActivityLines(state),
5178
+ ];
5062
5179
  const bottomStickyLines = selectOutboxOverlayLines(state, contentWidth);
5063
5180
  const bottomStickyHeight = Math.min(
5064
5181
  Math.max(0, Math.floor(contentHeight * 0.34)),
@@ -6030,9 +6147,27 @@ export class PilotSwarmUiController {
6030
6147
  case UI_COMMANDS.SHRINK_SESSION_PANE:
6031
6148
  this.adjustSessionPaneSplit(-2);
6032
6149
  return;
6150
+ case UI_COMMANDS.GROW_FOCUSED_PANE:
6151
+ this.resizeFocusedPane(2);
6152
+ return;
6153
+ case UI_COMMANDS.SHRINK_FOCUSED_PANE:
6154
+ this.resizeFocusedPane(-2);
6155
+ return;
6033
6156
  case UI_COMMANDS.OPEN_ARTIFACT_PICKER:
6034
6157
  await this.openArtifactPicker();
6035
6158
  return;
6159
+ case UI_COMMANDS.OPEN_HELP:
6160
+ this.openHelpModal();
6161
+ return;
6162
+ case UI_COMMANDS.SEQUENCE_SELECT_PREV:
6163
+ this.moveSequenceSelection(-1);
6164
+ return;
6165
+ case UI_COMMANDS.SEQUENCE_SELECT_NEXT:
6166
+ this.moveSequenceSelection(1);
6167
+ return;
6168
+ case UI_COMMANDS.TOGGLE_SEQUENCE_TURN:
6169
+ this.toggleSequenceTurnExpanded();
6170
+ return;
6036
6171
  case UI_COMMANDS.TOGGLE_LOG_TAIL:
6037
6172
  this.toggleLogTail();
6038
6173
  return;
@@ -670,6 +670,24 @@ export function appReducer(state, action) {
670
670
  },
671
671
  };
672
672
 
673
+ case "ui/sequenceExpandedTurns":
674
+ return {
675
+ ...state,
676
+ ui: {
677
+ ...state.ui,
678
+ sequenceExpandedTurns: Array.isArray(action.turns) ? action.turns : [],
679
+ },
680
+ };
681
+
682
+ case "ui/sequenceSelectedTurn":
683
+ return {
684
+ ...state,
685
+ ui: {
686
+ ...state.ui,
687
+ sequenceSelectedTurn: action.turn == null ? null : Number(action.turn),
688
+ },
689
+ };
690
+
673
691
  case "sessions/filterQuery":
674
692
  {
675
693
  const nextSessions = {
@@ -701,7 +719,19 @@ export function appReducer(state, action) {
701
719
 
702
720
  case "ui/modalSelection": {
703
721
  const modal = state.ui.modal;
704
- if (!modal || !Array.isArray(modal.items) || modal.items.length === 0) {
722
+ if (!modal) return state;
723
+ if (modal.type === "help") {
724
+ // The help overlay has no `items`; the row-count upper bound is
725
+ // clamped by selectHelpModal, so just track the scroll anchor.
726
+ return {
727
+ ...state,
728
+ ui: {
729
+ ...state.ui,
730
+ modal: { ...modal, selectedIndex: Math.max(0, Number(action.index) || 0) },
731
+ },
732
+ };
733
+ }
734
+ if (!Array.isArray(modal.items) || modal.items.length === 0) {
705
735
  return state;
706
736
  }
707
737
  const nextIndex = Math.max(0, Math.min(action.index ?? 0, modal.items.length - 1));