pi-studio 0.9.7 → 0.9.8
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 +5 -0
- package/index.ts +4 -19
- package/package.json +1 -1
- package/shared/studio-ssh-hint.js +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,11 @@ All notable changes to `pi-studio` are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.8] — 2026-05-19
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- Restored the full tokenized Studio URL inside SSH tunnel hints so the local browser URL remains visible even when only the latest notification is shown.
|
|
11
|
+
|
|
7
12
|
## [0.9.7] — 2026-05-19
|
|
8
13
|
|
|
9
14
|
### Added
|
package/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
} from "./shared/studio-markdown-latex-literals.js";
|
|
29
29
|
import { escapeStudioPdfLatexTextFragment } from "./shared/studio-pdf-escape.js";
|
|
30
30
|
import { resolveStudioPdfResourceFile } from "./shared/studio-pdf-resource.js";
|
|
31
|
+
import { buildStudioSshTunnelHint, isStudioSshSession as isSshSession } from "./shared/studio-ssh-hint.js";
|
|
31
32
|
|
|
32
33
|
type Lens = "writing" | "code";
|
|
33
34
|
type RequestedLens = Lens | "auto";
|
|
@@ -8270,12 +8271,6 @@ function buildStudioUrl(
|
|
|
8270
8271
|
return `http://127.0.0.1:${port}/?${params.toString()}`;
|
|
8271
8272
|
}
|
|
8272
8273
|
|
|
8273
|
-
function isSshSession(): boolean {
|
|
8274
|
-
return Boolean(
|
|
8275
|
-
String(process.env.SSH_CONNECTION ?? process.env.SSH_CLIENT ?? process.env.SSH_TTY ?? "").trim(),
|
|
8276
|
-
);
|
|
8277
|
-
}
|
|
8278
|
-
|
|
8279
8274
|
function parseStudioLaunchOpenFlags(rawArgs: string): { args: string; openRemoteBrowser: boolean; error?: string } {
|
|
8280
8275
|
const parsed = tokenizeStudioCommandArgs(rawArgs);
|
|
8281
8276
|
if (parsed.error) return { args: rawArgs, openRemoteBrowser: false, error: parsed.error };
|
|
@@ -8295,16 +8290,6 @@ function shouldAutoOpenStudioBrowser(options?: { openRemoteBrowser?: boolean }):
|
|
|
8295
8290
|
return !isSshSession() || Boolean(options?.openRemoteBrowser);
|
|
8296
8291
|
}
|
|
8297
8292
|
|
|
8298
|
-
function buildStudioSshTunnelHint(port: number): string | null {
|
|
8299
|
-
if (!isSshSession()) return null;
|
|
8300
|
-
return [
|
|
8301
|
-
"SSH detected. Studio was not opened in the remote browser.",
|
|
8302
|
-
"To open it locally, run this on your local machine:",
|
|
8303
|
-
` ssh -L ${port}:127.0.0.1:${port} <remote-host>`,
|
|
8304
|
-
"Then open the Studio URL above in your local browser.",
|
|
8305
|
-
].join("\n");
|
|
8306
|
-
}
|
|
8307
|
-
|
|
8308
8293
|
function resolveRequestedStudioDocumentFromUrl(
|
|
8309
8294
|
requestUrl: URL,
|
|
8310
8295
|
fallback: InitialStudioDocument | null,
|
|
@@ -12550,7 +12535,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
12550
12535
|
if (serverState) {
|
|
12551
12536
|
const url = buildStudioUrl(serverState.port, serverState.token, "full");
|
|
12552
12537
|
ctx.ui.notify(`Studio URL: ${url}`, "info");
|
|
12553
|
-
const sshTunnelHint = buildStudioSshTunnelHint(serverState.port);
|
|
12538
|
+
const sshTunnelHint = buildStudioSshTunnelHint(serverState.port, url);
|
|
12554
12539
|
if (sshTunnelHint) ctx.ui.notify(sshTunnelHint, "info");
|
|
12555
12540
|
}
|
|
12556
12541
|
return;
|
|
@@ -12578,7 +12563,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
12578
12563
|
|
|
12579
12564
|
const state = await ensureServer();
|
|
12580
12565
|
const url = buildStudioUrl(state.port, state.token, mode, selected);
|
|
12581
|
-
const sshTunnelHint = buildStudioSshTunnelHint(state.port);
|
|
12566
|
+
const sshTunnelHint = buildStudioSshTunnelHint(state.port, url);
|
|
12582
12567
|
const openedLabel = mode === "editor-only" ? "pi Studio editor-only view" : "pi Studio";
|
|
12583
12568
|
|
|
12584
12569
|
const shouldOpenBrowser = shouldAutoOpenStudioBrowser({
|
|
@@ -12632,7 +12617,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
12632
12617
|
`Studio running at ${url} (busy: ${isStudioBusy() ? "yes" : "no"}; full views: ${counts.full}; editor-only views: ${counts.editorOnly})`,
|
|
12633
12618
|
"info",
|
|
12634
12619
|
);
|
|
12635
|
-
const sshTunnelHint = buildStudioSshTunnelHint(serverState.port);
|
|
12620
|
+
const sshTunnelHint = buildStudioSshTunnelHint(serverState.port, url);
|
|
12636
12621
|
if (sshTunnelHint) ctx.ui.notify(sshTunnelHint, "info");
|
|
12637
12622
|
return;
|
|
12638
12623
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-studio",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"description": "Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, active quiz, prompt/response history, live previews, and tmux-backed REPL/literate REPL workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function isStudioSshSession(env = process.env) {
|
|
2
|
+
return Boolean(
|
|
3
|
+
String(env.SSH_CONNECTION ?? env.SSH_CLIENT ?? env.SSH_TTY ?? "").trim(),
|
|
4
|
+
);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function buildStudioSshTunnelHint(port, studioUrl, env = process.env) {
|
|
8
|
+
if (!isStudioSshSession(env)) return null;
|
|
9
|
+
const normalizedPort = Number(port);
|
|
10
|
+
const remotePort = Number.isInteger(normalizedPort) && normalizedPort > 0 ? normalizedPort : port;
|
|
11
|
+
const url = String(studioUrl || "").trim();
|
|
12
|
+
return [
|
|
13
|
+
"SSH detected. Studio was not opened in the remote browser.",
|
|
14
|
+
"To open it locally, run this on your local machine:",
|
|
15
|
+
` ssh -L ${remotePort}:127.0.0.1:${remotePort} <remote-host>`,
|
|
16
|
+
"Then open this Studio URL in your local browser:",
|
|
17
|
+
` ${url}`,
|
|
18
|
+
].join("\n");
|
|
19
|
+
}
|