pilotswarm-cli 0.1.16 → 0.1.17

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.
@@ -32,7 +32,7 @@ const THEMES = Object.freeze([
32
32
 
33
33
  const THEME_MAP = new Map(THEMES.map((theme) => [theme.id, theme]));
34
34
 
35
- export const DEFAULT_THEME_ID = draculaTheme.id;
35
+ export const DEFAULT_THEME_ID = noctisObscuroTheme.id;
36
36
 
37
37
  export function listThemes() {
38
38
  return THEMES;
@@ -124,6 +124,17 @@ function formatProcessRssTitleRuns(rssBytes) {
124
124
  ];
125
125
  }
126
126
 
127
+ function buildSessionTitleRightRuns(rssRuns, versionLabel = null) {
128
+ const titleRuns = [...(Array.isArray(rssRuns) ? rssRuns : [])];
129
+ const normalizedVersionLabel = typeof versionLabel === "string" ? versionLabel.trim() : "";
130
+ if (!normalizedVersionLabel) return titleRuns.length > 0 ? titleRuns : null;
131
+ if (titleRuns.length > 0) {
132
+ titleRuns.push({ text: " ", color: "gray" });
133
+ }
134
+ titleRuns.push({ text: normalizedVersionLabel, color: "cyan", bold: true });
135
+ return titleRuns;
136
+ }
137
+
127
138
  function useProcessRssTitleRuns(sampleIntervalMs = 2000) {
128
139
  const [rssBytes, setRssBytes] = React.useState(() => readProcessRssBytes());
129
140
 
@@ -236,9 +247,13 @@ function buildWorkspacePaneFrames(layout) {
236
247
  };
237
248
  }
238
249
 
239
- const SessionList = React.memo(function SessionList({ controller, maxRows, width, height, frame }) {
250
+ const SessionList = React.memo(function SessionList({ controller, maxRows, width, height, frame, versionLabel = null }) {
240
251
  const platform = useUiPlatform();
241
252
  const rssTitleRuns = useProcessRssTitleRuns();
253
+ const titleRightRuns = React.useMemo(
254
+ () => buildSessionTitleRightRuns(rssTitleRuns, versionLabel),
255
+ [rssTitleRuns, versionLabel],
256
+ );
242
257
  const sessionView = useControllerSelector(controller, (state) => ({
243
258
  sessions: state.sessions,
244
259
  mode: state.connection?.mode || "local",
@@ -264,7 +279,7 @@ const SessionList = React.memo(function SessionList({ controller, maxRows, width
264
279
 
265
280
  return React.createElement(platform.Panel, {
266
281
  title: "Sessions",
267
- titleRight: rssTitleRuns,
282
+ titleRight: titleRightRuns,
268
283
  color: "yellow",
269
284
  focused: sessionView.focused,
270
285
  width,
@@ -1285,7 +1300,7 @@ function ConfirmModalContainer({ controller }) {
1285
1300
  return React.createElement(ConfirmModal, { state });
1286
1301
  }
1287
1302
 
1288
- export function SharedPilotSwarmApp({ controller }) {
1303
+ export function SharedPilotSwarmApp({ controller, versionLabel = null }) {
1289
1304
  const platform = useUiPlatform();
1290
1305
  const layoutState = useControllerSelector(controller, (state) => ({
1291
1306
  paneAdjust: state.ui.layout?.paneAdjust ?? 0,
@@ -1341,6 +1356,7 @@ export function SharedPilotSwarmApp({ controller }) {
1341
1356
  height: workspaceHeight,
1342
1357
  maxRows: sessionRows,
1343
1358
  frame: frames.fullscreenPane,
1359
+ versionLabel,
1344
1360
  })
1345
1361
  : fullscreenPaneActive === "chat"
1346
1362
  ? React.createElement(ChatPane, {
@@ -1372,6 +1388,7 @@ export function SharedPilotSwarmApp({ controller }) {
1372
1388
  height: layout.sessionPaneHeight,
1373
1389
  maxRows: sessionRows,
1374
1390
  frame: frames.sessions,
1391
+ versionLabel,
1375
1392
  }),
1376
1393
  React.createElement(ChatPane, {
1377
1394
  controller,
@@ -2080,6 +2080,22 @@ function ModalLayer({ controller }) {
2080
2080
  historyFormatState: state.executionHistory?.format || "pretty",
2081
2081
  }), shallowEqualObject);
2082
2082
  const modal = modalState.rawModal;
2083
+ const renameInputRef = React.useRef(null);
2084
+
2085
+ React.useEffect(() => {
2086
+ if (modal?.type !== "renameSession" || !modalState.renameSession) return;
2087
+ const inputNode = renameInputRef.current;
2088
+ if (!inputNode) return;
2089
+ if (document.activeElement !== inputNode) {
2090
+ try {
2091
+ inputNode.focus({ preventScroll: true });
2092
+ } catch {
2093
+ inputNode.focus();
2094
+ }
2095
+ }
2096
+ inputNode.setSelectionRange(modalState.renameSession.cursorIndex, modalState.renameSession.cursorIndex);
2097
+ }, [modal?.type, modalState.renameSession?.cursorIndex, modalState.renameSession?.value]);
2098
+
2083
2099
  if (!modal) return null;
2084
2100
 
2085
2101
  const close = () => controller.handleCommand(UI_COMMANDS.CLOSE_MODAL).catch(() => {});
@@ -2161,10 +2177,11 @@ function ModalLayer({ controller }) {
2161
2177
  React.createElement("button", { type: "button", className: "ps-modal-close", onClick: close }, "Close"),
2162
2178
  ),
2163
2179
  React.createElement("input", {
2180
+ ref: renameInputRef,
2164
2181
  className: "ps-modal-input",
2165
2182
  value: modalState.renameSession.value,
2166
2183
  placeholder: modalState.renameSession.placeholder,
2167
- onChange: (event) => controller.setRenameSessionValue(event.currentTarget.value, event.currentTarget.selectionStart || event.currentTarget.value.length),
2184
+ onChange: (event) => controller.setRenameSessionValue(event.currentTarget.value, event.currentTarget.selectionStart ?? event.currentTarget.value.length),
2168
2185
  onKeyDown: (event) => {
2169
2186
  if (event.key === "Enter") {
2170
2187
  event.preventDefault();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pilotswarm-cli",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Terminal UI for PilotSwarm.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "ink": "^6.8.0",
41
- "pilotswarm-sdk": "^0.1.16",
41
+ "pilotswarm-sdk": "^0.1.17",
42
42
  "pilotswarm-ui-core": "0.1.0",
43
43
  "pilotswarm-ui-react": "0.1.0",
44
44
  "react": "^19.2.4"
package/src/app.js CHANGED
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import { useInput, useStdin } from "ink";
3
3
  import { UiPlatformProvider, SharedPilotSwarmApp } from "pilotswarm-ui-react";
4
4
  import { UI_COMMANDS } from "pilotswarm-ui-core";
5
+ import { PILOTSWARM_CLI_VERSION_LABEL } from "./version.js";
5
6
 
6
7
  const MOUSE_INPUT_PATTERN = /\u001b\[<(\d+);(\d+);(\d+)([mM])/gu;
7
8
  const MOUSE_INPUT_FRAGMENT_PATTERN = /(?:\u001b)?\[<\d+;\d+;\d+[mM]/u;
@@ -657,5 +658,8 @@ export function PilotSwarmTuiApp({ controller, platform, onRequestExit }) {
657
658
  });
658
659
 
659
660
  return React.createElement(UiPlatformProvider, { platform },
660
- React.createElement(SharedPilotSwarmApp, { controller }));
661
+ React.createElement(SharedPilotSwarmApp, {
662
+ controller,
663
+ versionLabel: PILOTSWARM_CLI_VERSION_LABEL,
664
+ }));
661
665
  }
package/src/version.js ADDED
@@ -0,0 +1,7 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ const require = createRequire(import.meta.url);
4
+ const cliPackageJson = require("../package.json");
5
+
6
+ export const PILOTSWARM_CLI_VERSION = String(cliPackageJson?.version || "0.0.0");
7
+ export const PILOTSWARM_CLI_VERSION_LABEL = `v${PILOTSWARM_CLI_VERSION}`;