pi-studio 0.9.31 → 0.9.32
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 +8 -0
- package/README.md +1 -1
- package/client/studio-client.js +48 -7
- package/index.ts +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ All notable changes to `pi-studio` are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.32] — 2026-06-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Added `Cmd/Ctrl+Alt+W` to switch the right pane directly to Working, matching the existing direct Preview shortcut.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Preserved expanded Working-view detail sections while live working updates stream in.
|
|
14
|
+
|
|
7
15
|
## [0.9.31] — 2026-06-09
|
|
8
16
|
|
|
9
17
|
### Fixed
|
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Extension for [pi](https://pi.dev) that opens a local two-pane browser workspace
|
|
|
22
22
|
- Supports one canonical full Studio view per Pi session, plus additional editor-only companion views when you want extra editing/preview surfaces; editor-only views can also browse files and use the Studio REPL send controls without taking over the full Studio session view
|
|
23
23
|
- Includes a global **Zen** mode for hiding secondary Studio chrome without changing the current left/right pane layout
|
|
24
24
|
- Runs editor text directly, asks for structured critique (auto/writing/code focus), offers a manual **Suggest completion** action for short cursor-aware continuations (`Option/Alt+Tab` where available or `Cmd/Ctrl+Shift+Space` from the editor, `Tab` to insert a visible suggestion) with an optional editor-plus-latest-response context mode, or opens **Quiz me** for a Studio-native active-recall loop over the current editor text, selection, current file, folder, or repo, with optional focus guidance for shaping question selection
|
|
25
|
-
- Includes a live **Working** view for following current model/tool activity, with `All` / `Thinking` / `Tools` filters, image previews for image-producing tool outputs, plus **Load visible into editor** and **Copy visible** actions; when cycling response history, Working follows saved working details for the selected response when available
|
|
25
|
+
- Includes a live **Working** view for following current model/tool activity, with `All` / `Thinking` / `Tools` filters, image previews for image-producing tool outputs, plus **Load visible into editor** and **Copy visible** actions; when cycling response history, Working follows saved working details for the selected response when available, and `Cmd/Ctrl+Alt+W` switches the right pane directly to Working
|
|
26
26
|
- Includes a right-pane **Changes** view for browsing the current git diff by file, previewing per-file diffs, opening changed files, loading the full diff into the editor, and copying the diff
|
|
27
27
|
- Includes a right-pane **Files** view for browsing the current Pi session/resource directory, opening folders, opening the Files root in Finder/the system file manager, loading text/code/CSV/TSV documents into the editor, previewing PDFs/images, opening PDF/image previews in a new Studio tab, converting DOCX/ODT documents to editable Markdown when Pandoc is available after confirmation, copying paths, setting the current folder as the Studio working directory, and revealing files in the file manager
|
|
28
28
|
- Includes an optional tmux-backed **REPL** view for Shell, Python, IPython, Julia, R, GHCi, and Clojure sessions, with Raw/Literate send modes, `Cmd/Ctrl+Shift+Enter` **Send to REPL**, session start/stop/interrupt controls, a compact refresh-persistent **Studio REPL Record** of user and Pi-sent code, a secondary raw tmux mirror, agent-facing `studio_repl_status` / `studio_repl_send` tools, and Markdown/PDF/HTML export
|
package/client/studio-client.js
CHANGED
|
@@ -270,7 +270,7 @@
|
|
|
270
270
|
});
|
|
271
271
|
rightViewSelect.title = isEditorOnlyMode
|
|
272
272
|
? "Editor-only views: editor preview, Changes, Files, or REPL. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+P switches directly to Preview."
|
|
273
|
-
: "Right pane view mode. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+P switches directly to Preview.";
|
|
273
|
+
: "Right pane view mode. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+P switches directly to Preview; Cmd/Ctrl+Alt+W switches directly to Working.";
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
function getInitialRightView(source) {
|
|
@@ -302,6 +302,7 @@
|
|
|
302
302
|
let traceAutoScroll = true;
|
|
303
303
|
let traceRenderRaf = null;
|
|
304
304
|
const traceExpandedOutputs = new Set();
|
|
305
|
+
const traceOpenDetails = new Set();
|
|
305
306
|
let gitChangesState = {
|
|
306
307
|
status: "idle",
|
|
307
308
|
requestId: null,
|
|
@@ -683,6 +684,7 @@
|
|
|
683
684
|
traceState = normalizeTraceState(nextState);
|
|
684
685
|
if ((traceState.runId || null) !== previousRunId) {
|
|
685
686
|
traceExpandedOutputs.clear();
|
|
687
|
+
traceOpenDetails.clear();
|
|
686
688
|
}
|
|
687
689
|
renderTraceViewIfActive();
|
|
688
690
|
}
|
|
@@ -3804,6 +3806,17 @@
|
|
|
3804
3806
|
setStatus("Right pane view: " + String(label || "Preview") + ".");
|
|
3805
3807
|
}
|
|
3806
3808
|
|
|
3809
|
+
function switchRightPaneToWorking() {
|
|
3810
|
+
if (isEditorOnlyMode) {
|
|
3811
|
+
setStatus("Working view is unavailable in editor-only Studio views.", "warning");
|
|
3812
|
+
return;
|
|
3813
|
+
}
|
|
3814
|
+
const snapshot = snapshotStudioScrollablePositions();
|
|
3815
|
+
setRightView("trace");
|
|
3816
|
+
scheduleStudioScrollablePositionRestore(snapshot);
|
|
3817
|
+
setStatus("Right pane view: Working.");
|
|
3818
|
+
}
|
|
3819
|
+
|
|
3807
3820
|
function cycleActivePaneView(direction) {
|
|
3808
3821
|
if (activePane === "right") {
|
|
3809
3822
|
if (!rightViewSelect || rightViewSelect.disabled) {
|
|
@@ -4112,6 +4125,16 @@
|
|
|
4112
4125
|
return;
|
|
4113
4126
|
}
|
|
4114
4127
|
|
|
4128
|
+
const isWorkingShortcut = (key.toLowerCase() === "w" || code === "KeyW")
|
|
4129
|
+
&& (event.metaKey || event.ctrlKey)
|
|
4130
|
+
&& event.altKey
|
|
4131
|
+
&& !event.shiftKey;
|
|
4132
|
+
if (isWorkingShortcut) {
|
|
4133
|
+
event.preventDefault();
|
|
4134
|
+
switchRightPaneToWorking();
|
|
4135
|
+
return;
|
|
4136
|
+
}
|
|
4137
|
+
|
|
4115
4138
|
const isContentFocusShortcut = key === "F8" && !event.metaKey && !event.ctrlKey && !event.altKey;
|
|
4116
4139
|
if (isContentFocusShortcut) {
|
|
4117
4140
|
event.preventDefault();
|
|
@@ -7757,6 +7780,20 @@
|
|
|
7757
7780
|
}
|
|
7758
7781
|
}
|
|
7759
7782
|
|
|
7783
|
+
function handleTraceDetailsToggle(event) {
|
|
7784
|
+
if (rightView !== "trace") return;
|
|
7785
|
+
const target = event.target;
|
|
7786
|
+
if (!(target instanceof Element) || !target.matches("details[data-trace-details-key]")) return;
|
|
7787
|
+
const key = target.getAttribute("data-trace-details-key") || "";
|
|
7788
|
+
if (!key) return;
|
|
7789
|
+
if (target.open) {
|
|
7790
|
+
traceOpenDetails.add(key);
|
|
7791
|
+
} else {
|
|
7792
|
+
traceOpenDetails.delete(key);
|
|
7793
|
+
}
|
|
7794
|
+
traceAutoScroll = false;
|
|
7795
|
+
}
|
|
7796
|
+
|
|
7760
7797
|
async function handleTracePaneClick(event) {
|
|
7761
7798
|
if (rightView !== "trace") return;
|
|
7762
7799
|
const target = event.target;
|
|
@@ -7951,6 +7988,7 @@
|
|
|
7951
7988
|
function attachResponsePaneInteractionHandlers() {
|
|
7952
7989
|
if (!critiqueViewEl) return;
|
|
7953
7990
|
critiqueViewEl.addEventListener("scroll", handleTracePaneScroll);
|
|
7991
|
+
critiqueViewEl.addEventListener("toggle", handleTraceDetailsToggle, true);
|
|
7954
7992
|
critiqueViewEl.addEventListener("click", handleTracePaneClick);
|
|
7955
7993
|
critiqueViewEl.addEventListener("click", handleReplPaneClick);
|
|
7956
7994
|
critiqueViewEl.addEventListener("click", handleFilesPaneClick);
|
|
@@ -9189,8 +9227,9 @@
|
|
|
9189
9227
|
const value = String(inputText || "").trim();
|
|
9190
9228
|
if (!value) return "";
|
|
9191
9229
|
const rawKey = outputKey + ":raw-input";
|
|
9192
|
-
const
|
|
9193
|
-
|
|
9230
|
+
const detailsKey = rawKey;
|
|
9231
|
+
const openAttr = traceOpenDetails.has(detailsKey) || traceExpandedOutputs.has(rawKey) ? " open" : "";
|
|
9232
|
+
return "<details class='trace-tool-details trace-tool-raw-input' data-trace-details-key='" + escapeHtml(detailsKey) + "'" + openAttr + ">"
|
|
9194
9233
|
+ "<summary>Raw input</summary>"
|
|
9195
9234
|
+ "<div class='trace-tool-details-body'>"
|
|
9196
9235
|
+ renderTraceOutput(value, rawKey, { label: "Raw input" })
|
|
@@ -9201,8 +9240,9 @@
|
|
|
9201
9240
|
function renderTraceToolTextDetails(summary, text, outputKey, label, options) {
|
|
9202
9241
|
const value = String(text || "");
|
|
9203
9242
|
const emptyText = options && typeof options.emptyText === "string" ? options.emptyText : "[empty]";
|
|
9204
|
-
const
|
|
9205
|
-
|
|
9243
|
+
const detailsKey = outputKey;
|
|
9244
|
+
const openAttr = traceOpenDetails.has(detailsKey) || traceExpandedOutputs.has(outputKey) ? " open" : "";
|
|
9245
|
+
return "<details class='trace-tool-details" + (options && options.className ? " " + escapeHtml(options.className) : "") + "' data-trace-details-key='" + escapeHtml(detailsKey) + "'" + openAttr + ">"
|
|
9206
9246
|
+ "<summary>" + escapeHtml(summary) + "</summary>"
|
|
9207
9247
|
+ "<div class='trace-tool-details-body'>"
|
|
9208
9248
|
+ renderTraceOutput(value || emptyText, outputKey, { label })
|
|
@@ -9234,8 +9274,9 @@
|
|
|
9234
9274
|
const newMetrics = formatTraceTextMetrics(edit.newText);
|
|
9235
9275
|
const oldKey = entry.id + ":edit:" + edit.index + ":old";
|
|
9236
9276
|
const newKey = entry.id + ":edit:" + edit.index + ":new";
|
|
9237
|
-
const
|
|
9238
|
-
|
|
9277
|
+
const detailsKey = entry.id + ":edit:" + edit.index;
|
|
9278
|
+
const openAttr = traceOpenDetails.has(detailsKey) || traceExpandedOutputs.has(oldKey) || traceExpandedOutputs.has(newKey) ? " open" : "";
|
|
9279
|
+
return "<details class='trace-tool-details trace-tool-change' data-trace-details-key='" + escapeHtml(detailsKey) + "'" + openAttr + ">"
|
|
9239
9280
|
+ "<summary>Replacement " + escapeHtml(String(displayIndex + 1)) + " · " + escapeHtml(oldMetrics) + " → " + escapeHtml(newMetrics) + "</summary>"
|
|
9240
9281
|
+ "<div class='trace-tool-change-body'>"
|
|
9241
9282
|
+ "<div class='trace-tool-change-grid'>"
|
package/index.ts
CHANGED
|
@@ -10514,7 +10514,7 @@ ${cssVarsBlock}
|
|
|
10514
10514
|
<section id="rightPane">
|
|
10515
10515
|
<div id="rightSectionHeader" class="section-header">
|
|
10516
10516
|
<div class="section-header-main">
|
|
10517
|
-
<select id="rightViewSelect" aria-label="Response view mode" title="Right pane view mode. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+P switches directly to Preview.">
|
|
10517
|
+
<select id="rightViewSelect" aria-label="Response view mode" title="Right pane view mode. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+P switches directly to Preview; Cmd/Ctrl+Alt+W switches directly to Working.">
|
|
10518
10518
|
<option value="markdown">Response (Raw)</option>
|
|
10519
10519
|
<option value="preview" selected>Response (Preview)</option>
|
|
10520
10520
|
<option value="editor-preview">Editor (Preview)</option>
|
|
@@ -10609,6 +10609,7 @@ ${cssVarsBlock}
|
|
|
10609
10609
|
<div><dt>F6</dt><dd>Switch between editor and right pane</dd></div>
|
|
10610
10610
|
<div><dt>F7 / Shift+F7</dt><dd>Cycle the active pane's view</dd></div>
|
|
10611
10611
|
<div><dt>Cmd/Ctrl+Alt+P</dt><dd>Switch the right pane directly to Preview</dd></div>
|
|
10612
|
+
<div><dt>Cmd/Ctrl+Alt+W</dt><dd>Switch the right pane directly to Working</dd></div>
|
|
10612
10613
|
<div><dt>F8</dt><dd>Focus editor text</dd></div>
|
|
10613
10614
|
<div><dt>Shift+F8</dt><dd>Focus right-pane content</dd></div>
|
|
10614
10615
|
<div><dt>F9</dt><dd>Toggle Zen mode</dd></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-studio",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.32",
|
|
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",
|