pi-studio 0.6.3 → 0.6.4

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `pi-studio` are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.6.4] — 2026-04-29
8
+
9
+ ### Fixed
10
+ - Fixed `@`-selected quoted file paths such as `@"folder/file.md"` so Studio commands strip the `@` prefix and surrounding quotes before resolving the file.
11
+ - `/studio --status` now prints the full tokenized Studio URL, and SSH tunnel hints explicitly say to preserve the `?token=...` parameter.
12
+
7
13
  ## [0.6.3] — 2026-04-29
8
14
 
9
15
  ### Changed
package/README.md CHANGED
@@ -75,7 +75,7 @@ pi -e https://github.com/omaclaren/pi-studio
75
75
  ## Notes
76
76
 
77
77
  - Local-only server (`127.0.0.1`) with tokenized Studio URLs.
78
- - For remote SSH sessions, keep Studio bound to localhost and use SSH local port forwarding; `/studio` prints the localhost URL and an SSH tunnel hint when SSH is detected.
78
+ - For remote SSH sessions, keep Studio bound to localhost and use SSH local port forwarding; `/studio` and `/studio --status` print the full tokenized localhost URL. Open that URL through the tunnel, preserving the `?token=...` parameter.
79
79
  - Full Studio is a singleton per Pi session: use `/studio` to open it, `/studio-replace` to explicitly replace it, and `/studio-editor-only` for extra editing/preview tabs that do not take over the full Studio session view.
80
80
  - Studio is designed as a complement to terminal pi, not a replacement.
81
81
  - Installing pi-studio makes the optional `pi-studio-dark` and `pi-studio-light` themes available in pi's theme selector; it does not change your active theme.
package/index.ts CHANGED
@@ -1382,20 +1382,27 @@ function isValidRequestId(id: string): boolean {
1382
1382
  return /^[a-zA-Z0-9_-]{1,120}$/.test(id);
1383
1383
  }
1384
1384
 
1385
- function parsePathArgument(args: string): string | null {
1386
- const trimmed = args.trim();
1387
- if (!trimmed) return null;
1388
-
1385
+ function stripMatchingPathQuotes(value: string): string {
1386
+ const trimmed = value.trim();
1389
1387
  if (
1390
1388
  (trimmed.startsWith('"') && trimmed.endsWith('"') && trimmed.length >= 2) ||
1391
1389
  (trimmed.startsWith("'") && trimmed.endsWith("'") && trimmed.length >= 2)
1392
1390
  ) {
1393
1391
  return trimmed.slice(1, -1).trim();
1394
1392
  }
1395
-
1396
1393
  return trimmed;
1397
1394
  }
1398
1395
 
1396
+ function parsePathArgument(args: string): string | null {
1397
+ const trimmed = args.trim();
1398
+ if (!trimmed) return null;
1399
+
1400
+ const hasAtPrefix = trimmed.startsWith("@");
1401
+ const pathPart = hasAtPrefix ? trimmed.slice(1).trim() : trimmed;
1402
+ const unquoted = stripMatchingPathQuotes(pathPart);
1403
+ return hasAtPrefix ? `@${unquoted}` : unquoted;
1404
+ }
1405
+
1399
1406
  function tokenizeStudioCommandArgs(input: string): { tokens: string[]; error?: string } {
1400
1407
  const tokens: string[] = [];
1401
1408
  let current = "";
@@ -1445,8 +1452,8 @@ function tokenizeStudioCommandArgs(input: string): { tokens: string[]; error?: s
1445
1452
 
1446
1453
  function normalizePathInput(pathInput: string): string {
1447
1454
  const trimmed = pathInput.trim();
1448
- if (trimmed.startsWith("@")) return trimmed.slice(1).trim();
1449
- return trimmed;
1455
+ if (trimmed.startsWith("@")) return stripMatchingPathQuotes(trimmed.slice(1).trim());
1456
+ return stripMatchingPathQuotes(trimmed);
1450
1457
  }
1451
1458
 
1452
1459
  function expandHome(pathInput: string): string {
@@ -6083,7 +6090,7 @@ function isSshSession(): boolean {
6083
6090
 
6084
6091
  function buildStudioSshTunnelHint(port: number): string | null {
6085
6092
  if (!isSshSession()) return null;
6086
- return `SSH detected. If Studio is running on a remote machine, forward the port from your local machine, then open the Studio URL locally: ssh -L ${port}:127.0.0.1:${port} <remote-host>`;
6093
+ return `SSH detected. Forward the remote Studio port, then open the full Studio URL above locally, including its ?token=... parameter: ssh -L ${port}:127.0.0.1:${port} <remote-host>. If you choose a different local port, change only the port in the URL; keep the token.`;
6087
6094
  }
6088
6095
 
6089
6096
  function resolveRequestedStudioDocumentFromUrl(
@@ -9481,10 +9488,13 @@ export default function (pi: ExtensionAPI) {
9481
9488
  return;
9482
9489
  }
9483
9490
  const counts = getStudioClientCounts();
9491
+ const url = buildStudioUrl(serverState.port, serverState.token, "full");
9484
9492
  ctx.ui.notify(
9485
- `Studio running at http://127.0.0.1:${serverState.port}/ (busy: ${isStudioBusy() ? "yes" : "no"}; full views: ${counts.full}; editor-only views: ${counts.editorOnly})`,
9493
+ `Studio running at ${url} (busy: ${isStudioBusy() ? "yes" : "no"}; full views: ${counts.full}; editor-only views: ${counts.editorOnly})`,
9486
9494
  "info",
9487
9495
  );
9496
+ const sshTunnelHint = buildStudioSshTunnelHint(serverState.port);
9497
+ if (sshTunnelHint) ctx.ui.notify(sshTunnelHint, "info");
9488
9498
  return;
9489
9499
  }
9490
9500
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-studio",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, prompt/response history, and live Markdown/LaTeX/code preview",
5
5
  "type": "module",
6
6
  "license": "MIT",