pi-studio 0.9.63 → 0.10.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 (53) hide show
  1. package/BUFFER-DESIGN.md +197 -0
  2. package/CHANGELOG.md +31 -0
  3. package/PRERELEASE-CHECKLIST.md +100 -0
  4. package/README.md +110 -193
  5. package/ROADMAP.md +63 -6
  6. package/WORKFLOW.md +32 -2
  7. package/assets/screenshots/dark-workspace.png +0 -0
  8. package/assets/screenshots/light-workspace.png +0 -0
  9. package/assets/screenshots/theme-zen-code.png +0 -0
  10. package/client/studio-client.js +6694 -942
  11. package/client/studio-editor-draft-helpers.js +162 -0
  12. package/client/studio-navigation-helpers.js +31 -5
  13. package/client/studio.css +460 -12
  14. package/index.ts +1178 -79
  15. package/package.json +5 -3
  16. package/shared/STUDIO_BUFFER_FOUNDATION.md +164 -0
  17. package/shared/studio-buffer-client.js +663 -0
  18. package/shared/studio-buffer-decisions.js +129 -0
  19. package/shared/studio-buffer-lineage.js +48 -0
  20. package/shared/studio-buffer-recovery-panel.js +132 -0
  21. package/shared/studio-buffer-recovery.js +181 -0
  22. package/shared/studio-buffer-server.js +700 -0
  23. package/shared/studio-buffer-store.js +227 -0
  24. package/shared/studio-buffer-switching.js +53 -0
  25. package/shared/studio-disk-revisions.js +15 -0
  26. package/shared/studio-document-entrypoints.js +38 -0
  27. package/shared/studio-document-escrow.js +147 -0
  28. package/shared/studio-document-file-claims.js +215 -0
  29. package/shared/studio-document-host-client.js +268 -0
  30. package/shared/studio-document-hosting.js +319 -0
  31. package/shared/studio-document-launch-client.js +153 -0
  32. package/shared/studio-document-open-client.js +96 -0
  33. package/shared/studio-document-open-storage.js +21 -0
  34. package/shared/studio-document-paths.js +29 -0
  35. package/shared/studio-editor-mode.js +48 -0
  36. package/shared/studio-linked-reader-ui.js +232 -0
  37. package/shared/studio-linked-reader.js +110 -0
  38. package/shared/studio-metadata-write-order.js +35 -0
  39. package/shared/studio-read-only-media.js +24 -0
  40. package/shared/studio-resource-grants.js +3 -0
  41. package/shared/studio-run-lifecycle.js +47 -0
  42. package/shared/studio-system-theme.js +9 -0
  43. package/assets/screenshots/dark-code-mode.png +0 -0
  44. package/assets/screenshots/dark-critique.png +0 -0
  45. package/assets/screenshots/dark-fenced-code.png +0 -0
  46. package/assets/screenshots/dark-focus-mode.png +0 -0
  47. package/assets/screenshots/dark-julia-fenced.png +0 -0
  48. package/assets/screenshots/dark-math.png +0 -0
  49. package/assets/screenshots/dark-mermaid.png +0 -0
  50. package/assets/screenshots/dark-zen.png +0 -0
  51. package/assets/screenshots/light-code-mode.png +0 -0
  52. package/assets/screenshots/light-fenced-code.png +0 -0
  53. package/assets/screenshots/light-math.png +0 -0
@@ -0,0 +1,197 @@
1
+ # Active Prompt and editable document buffers
2
+
3
+ **Hosting follow-up — 2026-09-27:** the uncommitted development checkout now includes separately approved single-owner Document hosting, behind recovery + switching + `PI_STUDIO_DOCUMENT_HOSTING=1`. Prompt stays anchored; move, detached copy, registered blank/text-file opening and existing-owner reuse are distinct operations. Uncertain operations retain their original identities/backups, and Save As metadata attachment requires a prepared receipt. Unsafe legacy entrypoints are explicitly unavailable in this prototype; see [README.md](README.md#additional-opt-in-prototype-single-owner-document-hosting). Source-tree validation does not establish acceptance of an exact alpha package; candidate-scoped artifact and private-install evidence is recorded separately. Finish the [remaining gates](PRERELEASE-CHECKLIST.md#additional-hosting-scope-and-remaining-gates) before packaging/release acceptance; defaults and normal Studio remain unchanged. The earlier status entries below describe their own checkpoints.
4
+
5
+ **Earlier status — 2026-09-22:** the tested fixed-slot workflow is committed through `40d4462`. Bounded local preparation of `0.10.0-alpha.1` is approved; publication, further commits and installation/default changes are not. The latest checkpoint has 240 focused passes and qualified native pane-scroll confirmation; earlier full-suite/browser counts below belong to their historical checkpoints. Whole-document/composed-Prompt hands-on trials and subsequent ownership fixes are recorded in [ROADMAP.md](ROADMAP.md). Blank-looking Working remains unreproduced and is an explicit local-alpha limitation. The alpha's activation/rollback instructions are in [README.md](README.md#local-alpha-one-prompt--one-document).
6
+
7
+ **Toolbar follow-up — 2026-09-23:** Oliver approved a bounded cleanup after trying the exact first alpha. The uncommitted rebuild groups **Add to Prompt → Selection / Whole document** and **Open / load**, labels the replacement destination, and removes permanent help/Run-target rows. Selection ownership is preserved through the Add disclosure, not revived after another field/preview. Capacity and disabled-state explanations remain available in the opened menu and action tooltips. This changes no buffer roles, source-loading semantics, defaults or companion behaviour; new artifact evidence is recorded separately from the first candidate.
8
+
9
+ **Historical status, 2026-09-11:** the foundation and annotation-header compatibility checkpoints are locally committed. A subsequent **one Prompt ↔ one document prototype** is implemented and tested as a local, unreleased checkpoint. It requires both `PI_STUDIO_BUFFER_RECOVERY=1` and `PI_STUDIO_BUFFER_SWITCHING=1`, in a full editable workspace. A separately approved local checkpoint allows switching during an identified direct Run, with 500 passing tests and isolated Brave/Chrome regressions, including the separately approved fixes for stale branch responses and hidden activity-follow state. That checkpoint subsequently passed an isolated live-model hands-on trial. A separately approved **Add selection to Prompt** slice is now a local, unreleased checkpoint: 522 tests and isolated, credential-free Brave/Chrome checks pass after an independent read-only review and separately approved fixes for literal-label boundaries and stale selection presses. No live-provider trial or independent post-fix sign-off is claimed for the selection slice. The earlier Safari evidence covers the foundation, not this switcher. The selection checkpoint subsequently passed a credential-free hands-on trial; Oliver confirmed it worked, and both drafts were backed up before stopping. A separately approved **Add document to Prompt** follow-up is now a local, unreleased checkpoint: 549 tests and twenty isolated Brave/Chrome runs pass after an independent read-only review and separately approved fixes for stale file-open control state and cancelled-press handling. No independent post-fix sign-off or hands-on trial of this follow-up is claimed. Installed Studio, package version and defaults remain unchanged. Updated 2026-09-11.
10
+
11
+ [ROADMAP.md](ROADMAP.md) owns release scope. `0.9.60` is released; implementation of the store/recovery foundation was approved afterward with the visible UI unchanged. Oliver approved a local checkpoint commit on `feature/buffer-recovery-foundation` on 2026-09-09, without release or default-activation authority. This note records the design and acceptance criteria, not a final wire protocol. The initial module/API boundaries and remaining integration work are in [shared/STUDIO_BUFFER_FOUNDATION.md](shared/STUDIO_BUFFER_FOUNDATION.md).
12
+
13
+ ## Purpose
14
+
15
+ Studio is primarily a prompt-writing and response-reading workspace. Editable documents and good previews support that loop; Studio does not need to replace Neovim.
16
+
17
+ The distinction is not whether documents are editable. It is whether selecting a document changes what Run will submit. It must not do so implicitly.
18
+
19
+ Use **one clearly active Prompt, other prompt drafts that can be parked, and independently editable documents**. Multiple drafts share the Pi conversation; they are not independent chats.
20
+
21
+ ## Current prototype — before general tabs
22
+
23
+ Oliver approved continuing from the visual guide with a small switching prototype, not the entire interface below. Its two fixed entries are **Prompt** and **Document**:
24
+
25
+ - A Prompt may be file-backed. Fresh file launches and v1 migration retain the visible editor's file-to-Run intent. Recovering an older v2 file beside a pristine empty Prompt asks **Use file as Prompt / Keep separate Prompt / Cancel**; emptiness alone is not role-change consent.
26
+ - Selecting Document preserves the Prompt. **Open / load → Open file in Document…** and Files' open-here action use the separate document slot. Replacing valuable text requires current consent; reopening its exact canonical path preserves its in-memory edits. **Files → Use as Prompt…** is a separate, explicit file load, not a copy of the other buffer's unsaved text.
27
+ - When idle, Document view offers **Return to Prompt**, with no submission. A separate Run sends the reviewed Prompt, including a file-backed one. Key repeats (including native held Enter with the Prompt editor in Preview) and double-click continuation cannot turn Return into Run. A fresh activation after key release still works; ordinary textarea repeats are unchanged. Existing annotation send/strip behaviour remains.
28
+ - Each buffer retains its text, source, disk baseline/revision, metadata associations, selection, vertical reading positions and preview choices. Response history is still shared. Background history and Follow activity do not steal Document's preview; response-to-editor actions are unavailable there. Returning to a Follow-on Prompt applies a queued response and starts that new response at the top. Follow-off, or returning without a queued update, preserves the earlier response selection and reading position.
29
+ - An identified direct Run on a connected socket permits selecting either existing buffer. The submitted text/source snapshot remains owned by Prompt. **Stop** stays global; the Prompt tab and Run shortcut can return without stopping or steering. Save, file opening/replacement, recovery/reset, unresolved Pi-draft disposition and other local-operation/modal locks remain. Unknown busy states and disconnected/reconnecting sockets do not gain this exception.
30
+ - A response completed in Document waits for Prompt's Follow policy. Explicit Pi tree changes discard the previous branch's queued response; ordinary empty history still permits a current response's payload fallback. History updates do not rebuild Document's live preview or discard interactive iframe state. Returning during the same Run restores its activity-follow ownership or manual opt-out; completing elsewhere retires only the automatically selected Working view. Disabling Follow activity revokes live and saved ownership. Explicitly re-enabling can follow the exact ongoing Prompt request on return without moving Document's view or reviving finished work. Late error/busy results retire their own pending snapshots without unlocking a newer Run.
31
+ - Switching still refuses stale continuations. Whole-pair recovery keeps both buffers; **Reset both buffers** explicitly confirms its scope. Other collections remain retained/exportable rather than being partly adopted.
32
+
33
+ There is no create/close/park manager, automatic context copying, companion transfer, or non-destructive annotation parking yet. Editing Document does **not** add its edits to the Prompt when returning. Ordinary manual copy/paste remains available. The prototype tests the interaction and preservation boundary; its two-entry strip is not a settled design for many documents. Recovery remains temporary, not a durable draft library.
34
+
35
+ ## Local editor-selection slice
36
+
37
+ **Add to Prompt → Selection** is an explicit action in the two-buffer strip, available for selected text in Document's editor. It appends the exact in-memory substring, with a literal source label and editor-line range, to the existing Prompt. It does not reread disk, trim the selection, replace the Prompt, switch buffers, save a file, or submit/steer a Run. Document stays selected. Normal recovery persistence still applies to the pair.
38
+
39
+ The addition is ordinary editable Prompt text; it can be revised or removed there. Each buffer retains its own source, baseline/disk revision, metadata, annotation policy, resources and reading positions. No terminal fingerprint or submission authority comes from Document. During an identified connected Run, an addition prepares the **next** draft; it does not change the already submitted snapshot. Unsafe local work, recovery/modal ownership, unresolved terminal disposition and disconnected/reconnecting states block copying.
40
+
41
+ The action captures pointer/keyboard intent and rechecks the source, selection owner/range, connection and destination revision. A stale press is not recaptured against a new buffer; held Enter/Space and double-click continuation do not duplicate the addition. Observed range/direction changes and new source focus, pointer or key gestures advance a monotonic owner, so selection A→B→A cannot revive a held press. Preview/iframe/other-field interactions retire the old editor selection as a copy source; select in the editor again. Keyboard focus on the action itself and delayed notifications of its unchanged captured range remain valid.
42
+
43
+ Source labels are literal code spans, not links or new file grants. Boundary backticks are separated from the delimiters with paired padding, including names supplied through Import file copy, so filename syntax does not become rendered media or links. Line numbers refer to the selected **editor snapshot**, including unsaved edits. Only text is copied: relative resources still use Prompt's own resource context. Existing per-buffer and aggregate limits include the addition and its label; overflow is rejected without partial insertion or eviction. Recovery errors do not roll back or discard an accepted in-memory addition, and existing recovery warnings remain.
44
+
45
+ Whole-document actions remain separate from selection copying; the local follow-up below does not relax selection ownership. Preview selections, companion transfers, a new undo/history library and general tabs remain deferred.
46
+
47
+ ## Local whole-document append follow-up
48
+
49
+ **Add to Prompt → Whole document** appends the full selected Document's raw-editor text, including unsaved edits, with a literal **whole document, snapshot** source label. No selection or prior editor focus is required; the action never temporarily selects all, rereads disk or extracts rendered content. It requires the same two opt-ins/full editable mode, and is unavailable in Document Preview/Quarto view. Empty text is refused; whitespace-only text is preserved exactly.
50
+
51
+ A description in the Add menu and action tooltip reports the complete addition size, including framing, and remaining capacity in UTF-16 string units. It uses the smaller of Prompt's 900,000-unit text headroom and the workspace's 3,000,000-unit aggregate headroom, including baselines. These are editor/recovery limits, not model-context estimates. Oversized additions are refused without truncation or eviction; execution rechecks the destination and capacity.
52
+
53
+ The append changes only Prompt text/revision and normal workspace/recovery bookkeeping. Both origins, file baselines/revisions, resources, metadata and views remain independent. Document stays selected without a caret/selection/scroll change or preview reconstruction; nothing is saved or sent. The existing identified-Run exception permits next-draft preparation only. Current source/destination revisions, editor/connection consent and a separate interaction generation reject stale held presses, including edit/undo and buffer round trips. Repeats and double-click continuation add once; fresh activations may add again. No selection-owner permission is created for the existing selection action. Local-operation, recovery, modal and terminal-disposition fences remain.
54
+
55
+ Pending file opens refresh both append controls on entry and cleanup, including stale/error outcomes; an older completion cannot enable them over a newer pending owner. Pointer and keyboard continuation leases stay separate: a fresh click-only activation does not consume a cancelled pointer press, and cannot authorize its later continuation. A completed keyboard lease retires after keyup's native activation task, with a generation check so older cleanup cannot clear a newer press.
56
+
57
+ This is a local, unreleased checkpoint, not companion transfer, parked prompts or general tabs.
58
+
59
+ ## Proposed next slice: explicit Prompt role
60
+
61
+ Prompt is an explicit submission role a document can take, independent of file backing, annotations and preview mode. After the fixed-slot alpha, separately scope switching that role between the existing buffers while preserving the previous Prompt. **Annotate** should continue editing the current document; an in-place **Use as Prompt** operation should retain its identity/annotations and send nothing; **Make a prompt copy** should create independent text instead. These are design directions, not implemented alpha controls. The existing Files action loads saved file text, not an in-place promotion of unsaved Document.
62
+
63
+ Retain document annotation/comments and the editor's available space. The bounded control regrouping above is approved; heading changes and general role switching remain separate proposals. Role switching should be tested for ownership and preservation before adding more documents or companion handoff.
64
+
65
+ ## Intended interaction model
66
+
67
+ An illustrative later tab strip:
68
+
69
+ ```text
70
+ [ Prompt ▾ ] [ notes.md • ] [ script.py ]
71
+ ```
72
+
73
+ - **Prompt:** the active prompt text alongside the session's response/Working views. Editor Preview remains available for prompt formatting and annotation.
74
+ - **Document:** editable source alongside that document's preview. Text, selections, scroll positions, dirty state, and preview choices survive switching away and back.
75
+ - **Prompt picker:** create, park, rename, and switch prompt drafts without discarding the previous one. Keep one active submission destination visible; do not add a separate conversation per draft.
76
+ - **Companions:** existing editor-only browser views remain useful and independently recoverable. They can contribute context to the full workspace without becoming additional full Studio views.
77
+
78
+ Opening, selecting, saving, or closing a document does not change the active prompt. A document becomes prompt material only through an explicit copy/handoff or an explicitly chosen Prompt file load. A detached context copy has no write-back link to its source; an explicitly file-backed Prompt retains its normal Save behaviour.
79
+
80
+ Run in Prompt view submits the active prompt, retaining annotation send/strip behaviour. Initially, document views offer **Return to prompt** rather than implicitly submitting the document or sending a hidden prompt. Do not couple this architecture to a global Run-shortcut redesign; preserve the existing REPL and Side question composer bindings.
81
+
82
+ Response history remains session-global. Restore the prompt's response position on return instead of treating a file preview as a new conversation, except when its enabled Follow setting applies a queued response. Follow activity must not switch away from a manually selected document or steal its preview.
83
+
84
+ ## Context transfer
85
+
86
+ Two explicit actions in the wider design:
87
+
88
+ - **Add selection to prompt:** the local slice above implements exact editor-selected text with its source label and editor-line range. Preview extraction is not implemented.
89
+ - **Add document to Prompt:** the local whole-document follow-up implements full raw-editor snapshots with a visible size/capacity check. This is the append-only action previously called **Copy document to prompt** in the wider design; it never replaces an existing Prompt. Preview extraction and companion handoff remain future work.
90
+
91
+ Use ordinary editable text rather than a new opaque attachment format. Capture the displayed in-memory text, including unsaved edits, rather than rereading disk. Detached sources need a useful label but must not invent a file path or line range. Source labels describe provenance; they do not imply that the copy remains synchronized or grant new file access.
92
+
93
+ After the handoff:
94
+
95
+ - prompt annotations affect only the copy;
96
+ - subsequent source edits do not update the staged text;
97
+ - nothing is submitted to Pi;
98
+ - the existing prompt text remains intact, and the insertion can be undone or removed;
99
+ - the source editor and its selection remain available.
100
+
101
+ For editable companion views, send a bounded transfer request to the same Pi process and explicit destination prompt. The destination owner applies the insertion against current state; do not replace its whole prompt with a stale text snapshot supplied by the companion. Acknowledge only after application, and deduplicate retries by transfer ID. If the full workspace is unavailable, the selected destination changed, or acceptance is uncertain, retain source text and report that state rather than silently retargeting or duplicating the insertion.
102
+
103
+ Initially, editable documents/companions are the transfer sources. Keep watched-preview sockets read-only; do not broaden their mutation permissions to reuse the new action. Existing copying from watched/PDF previews remains available separately.
104
+
105
+ ## Buffer model and ownership
106
+
107
+ Introduce `StudioBufferStore` behind the existing editor/preview surfaces before adding the tab UI. The following are design requirements, not fixed serialized field names:
108
+
109
+ | State | Responsibility |
110
+ | --- | --- |
111
+ | Stable buffer ID | Identity independent of tab order, file label, or selected view |
112
+ | Role | Prompt or document; not inferred solely from whether a path exists |
113
+ | Selected buffer ID | Which editor/preview the user is viewing |
114
+ | Active prompt ID | Which draft is the explicit submission/context destination |
115
+ | Text revision | Monotonic in-memory edit identity for async targeting |
116
+ | Text and baseline | Current text, dirty comparison, original source/draft identity |
117
+ | Disk identity | Canonical path and expected disk revision for file-backed saves |
118
+ | View state | Cursor/selection, source and preview scroll, language, preview mode |
119
+ | Local metadata | Annotations/review-note associations and resource context |
120
+
121
+ Keep existing canonical file checks and workspace-level resource grants. Two snapshots referring to a file must not bypass disk-revision conflict detection. Closing dirty documents or discarding prompt drafts must require a deliberate choice; reopen/recovery must not silently substitute the current contents of disk for unsaved text.
122
+
123
+ The full workspace owns its active prompt and draft selection. Companion workspaces retain their own documents; adding context is an explicit operation, not continuous shared-text synchronization. Resource grants and the exact-tmux-lifetime Shared REPL Record do not become buffer-owned.
124
+
125
+ ## Browser-tab continuity
126
+
127
+ Internal tabs complement, rather than replace, browser tabs/windows. Internal tabs will switch Prompt/documents inside a workspace; browser companions and previews remain useful for simultaneous viewing and other screens. Preserve existing browser-opening actions while implementing the new controls.
128
+
129
+ Separate browser editors initially remain independent snapshots, not live-synchronized mirrors. Keep canonical-path/disk-revision conflict checks. Future labels such as **Open in Studio tab** and **Open in browser tab** should make the distinction explicit. A true pop-out of an editable buffer must preserve its unsaved text; merely reopening its disk file is not equivalent. Linked pop-outs and live synchronization are not required for the first batch.
130
+
131
+ With switching off, the transitional single-editor adapter deliberately keeps Run using the visible editor, even when file migration creates a selected document plus an empty active Prompt. The separate switching opt-in changes the controls and submission guard together: Return first, then Run the visible Prompt. A hidden Prompt must never become the accidental submission destination.
132
+
133
+ ## Recovery and asynchronous work
134
+
135
+ ### Recovery schema v2
136
+
137
+ Persist bounded buffer collections, active/selected identities, ordering, and per-buffer state. Define per-buffer and aggregate limits; reject oversize updates visibly rather than truncating or evicting a live dirty buffer to make room.
138
+
139
+ Migrate schema v1 without changing disk or losing text:
140
+
141
+ - a detached editor in full Studio becomes the initial prompt draft;
142
+ - a file-backed editor becomes a document, retaining dirty text and the disk revision it was based on, with a separate empty Prompt;
143
+ - editor-only views retain their document role and cannot become additional full workspaces;
144
+ - preserve the recoverable v1 payload until a complete v2 snapshot has been validated and stored successfully.
145
+
146
+ Those are the low-level migration rules, also retained by foundation-only mode. The switching adapter then preserves fresh/v1 visible-file intent by making that file the Prompt, without changing its text, source or unknown recovered baseline. Older v2 role changes require the explicit choice described above.
147
+
148
+ Exercise all legacy source kinds in migration tests. Malformed or future schemas must fail conservatively with a recovery path, not silently reset dirty work. Keep recovery scoped to the existing browser-tab/workspace identities and resource authorization.
149
+
150
+ Current recovery uses browser session storage plus a bounded in-memory server fallback. Schema v2 must not imply new durable storage or guaranteed Pi-restart recovery unless those are separately designed and tested. Prompt parking must clearly state the recovery lifetime it actually provides.
151
+
152
+ ### Async targeting
153
+
154
+ Capture originating buffer ID, text revision, and request ID when starting a completion, preview, save, annotation replacement, or context transfer. Keep disk revision separate from the in-memory revision. A late result must not write to whichever buffer happens to be selected now, resurrect a closed buffer, or overwrite newer edits.
155
+
156
+ Main Pi responses remain conversation events. Their arrival may update response history, but not overwrite a source document or select a different buffer without an explicit policy. A buffer-mutating result whose origin changed needs an explicit accept/retry path.
157
+
158
+ Preserve the `0.9.59` Pi-terminal-draft handoff: cleanup eligibility stays transient and bound to the originating prompt/submission. Copying document text must not copy terminal cleanup authority. Clear Pi's composer only after an accepted Run and an exact unchanged terminal-text match; never on a context transfer, tab switch, or failed submission.
159
+
160
+ ## Draft replacement and annotation
161
+
162
+ In `0.9.60`, add the separate Annotate shortcut and protect **unsubmitted or unsaved work**, without introducing this buffer model. Do not ask for confirmation merely because the editor contains text:
163
+
164
+ - **No warning:** write a prompt → accepted Run → receive response → Annotate response, while the submitted prompt is still unchanged. Empty editors or an exact copy of the response likewise need no replacement warning when no unsaved file changes would be lost.
165
+ - **Protect before replacing:** post-submission prompt edits, another unsent draft, edited response annotations, and unsaved file changes. Cancel leaves the draft and source/view state unchanged; existing save/copy paths can support keeping it before proceeding.
166
+
167
+ Capture the raw editor text and source identity at submission time, correlate acceptance with that snapshot, and use it as the comparison baseline. A late acknowledgement or response must not mark the then-current editor text as submitted. Failed submissions do not establish the baseline, and a submitted file buffer can still have unsaved edits. This Studio-editor baseline is separate from the Pi-terminal-draft cleanup fingerprint.
168
+
169
+ Test the confirmation-free normal loop as well as the guarded cases, failed submissions, and typing during acknowledgement/confirmation. Do not claim automatic draft parking in this release.
170
+
171
+ In `0.10`, **Annotate response** can prepare a detached prompt draft while parking the unfinished active prompt. Copying a document to a prompt likewise leaves its file buffer independent. Resolve these operations through buffer identities rather than overwriting a global editor string.
172
+
173
+ Neither operation edits the original response in conversation history or the source document. An asynchronous confirmation is not permission to overwrite text typed after it opened.
174
+
175
+ ## Implementation sequence
176
+
177
+ 1. **Store and recovery:** introduce buffer identities/roles behind the single visible editor; test schema migration, bounds, disk identity, and async targeting before exposing tabs.
178
+ 2. **Prompt/document switching:** first prove one Prompt ↔ one document with independent state and an explicit submission boundary (the current local prototype). Review file-open intent and Return/Run ergonomics before expanding to creation/closing, more tabs or a narrow-width picker.
179
+ 3. **Context handoff:** add document/selection snapshots and acknowledged editable-companion-to-prompt transfer, preserving drafts and source text.
180
+ 4. **Parked prompts and annotation:** expose the lightweight draft picker and non-destructive response-to-prompt annotation flow; add MRU/next/previous/close/reopen navigation.
181
+ 5. **Release validation:** run the full suite and fresh-package smoke matrix, including migration and browser reconstruction. Use npm `next` for architectural validation before explicit stable-release approval.
182
+
183
+ Do not require an editor-engine migration, arbitrary pane layout system, or new REPL protocol to complete these steps.
184
+
185
+ ## Acceptance scenarios
186
+
187
+ 1. Start a prompt; edit `notes.md` with preview; append selected context; annotate the detached copy; inspect another file; return and Run. Preserve every draft, document edit, and reading position, and submit only the intended prompt.
188
+ 2. Compare two prompt formulations by parking/switching drafts. Run one without discarding the other or creating another Pi conversation.
189
+ 3. Add text from an editable companion while the main prompt is being edited. Apply once to the acknowledged destination; never lose intervening typing or append to a newly selected draft silently.
190
+ 4. Annotate a response while an unfinished prompt exists. Keep the old draft recoverable and leave the original response unchanged.
191
+ 5. Switch or close buffers during completion, rendering, saving, and confirmation. No late result writes into the wrong buffer or bypasses a stale disk revision.
192
+ 6. Refresh/reconstruct full and companion views, including with dirty files and parked prompts. Verify bounded recovery and non-destructive v1 migration under unavailable or malformed storage.
193
+ 7. Confirm Follow activity respects document navigation; watched previews remain read-only; REPL/Side question workflows and terminal draft cleanup retain their current authority boundaries.
194
+
195
+ ## Out of scope
196
+
197
+ Replacing Neovim; CodeMirror/Monaco migration; arbitrary multi-pane layouts; project trees; per-buffer conversations or parallel main-agent runs; live attachment synchronization; collaborative document editing; Derived REPL Transcript; changes to protocol v1 or `pi-repl` package independence.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,37 @@ All notable changes to `pi-studio` are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.10.1] — 2026-10-14
8
+
9
+ ### Fixed
10
+ - Between clicking **Run Prompt** and Pi starting, the button no longer flashes hollow, and the toolbar no longer drops a row and jumps back. The status beside Run now says "Starting…", with the detail kept in the footer; the button keeps its colour, dimmed, until it becomes Stop.
11
+
12
+ ### Changed
13
+ - A shorter, plainer README with new screenshots. The npm package drops from about 8.4 MB to 1.8 MB.
14
+
15
+ ## [0.10.0] — 2026-10-14
16
+
17
+ ### Added
18
+ - **Dual editor mode**, now the default: a **Prompt** for what you send to Pi, and a **Document** for the file you're working on. Each keeps its own edits, preview and reading position. Switch with the Prompt and Document tabs, or Cmd/Ctrl+Shift+1 and 2. Selecting the Document never changes what Run sends.
19
+ - **Single editor mode** keeps the one-editor Studio. Switch from the footer (**Switch to single editor** / **Switch to dual editor**), or with `/studio --single` and `/studio --dual`. Studio restarts and reopens the tab, and the Prompt's text comes with you. The choice is kept per Pi profile. Studio won't switch while the Document or a closed Document window has unsaved text, other Studio tabs are open, or a run, save or side question is in progress; it says why.
20
+ - **Add to Prompt** adds the Document's selection, or the whole Document, to the Prompt as a labelled copy, with Undo.
21
+ - **Document windows:** open a file in a new Document window, or move or copy the Document to one, and find it again from **File**. Each file has one editor, and saving replaces the file atomically.
22
+ - **Recovery:** unsaved Prompt and Document text survives reloads and dropped connections. After you close the tab, `/studio` reopens the same workspace; `--blank` and `--last` start afresh. A clean exit reopens without asking; otherwise Studio asks before resuming.
23
+ - The **Files** pane lists files to open in the Document or Prompt, read, or show in their folder.
24
+ - Links in rendered pages share one menu: Read, Open in Document, Open in Prompt, Show in folder, Copy path. Web links open in a new tab.
25
+
26
+ ### Changed
27
+ - A two-row header: the file and its actions on the first row; the main action and tools on the second. The toolbars fit a 13-inch laptop.
28
+ - **File** shows recovery items only while they apply.
29
+ - **Follow** moves only between Response, Working and the Prompt preview. Files, Changes, the REPL and Side questions keep their place.
30
+ - Side questions show the model and Thinking beside Ask. The REPL's send mode moves to its **More** menu.
31
+ - Plainer interface text throughout.
32
+ - In dual editor mode, `/studio-replace` moves the open Studio to a new tab here, for when it opened in another browser or a tab you can't find; opening its URL offers **Move it here** too. The old tab hands over its text first. `/studio-current`, editable `/studio-editor-only` and Office-to-Markdown opening aren't available in dual editor mode; use Studio's Document controls, or single editor mode.
33
+ - Development checks typecheck against Pi 1.2.0.
34
+
35
+ ### Fixed
36
+ - A pane's reading position could jump after you changed views, because an earlier scroll restore still ran.
37
+
7
38
  ## [0.9.63] — 2026-10-08
8
39
 
9
40
  ### Fixed
@@ -0,0 +1,100 @@
1
+ # Opt-in two-buffer prerelease checklist
2
+
3
+ Updated 2026-09-27. **Bounded local alpha preparation, the toolbar cleanup and the opt-in single-owner Document hosting work are approved.** The runtime/test base is `40d4462`; the selected local candidate is `0.10.0-alpha.1`. The follow-up implementation and documentation/package preparation remain uncommitted, and normal Studio remains `0.9.60`. Further commits, a live-model trial, pushing/tagging, publishing and changing the normal installation/default each need separate approval. This is a repository maintainer checklist, not a claim that every gate below has passed; fresh evidence accompanies the exact artifact outside the package.
4
+
5
+ Work in the isolated `pi-studio-buffer-dev` checkout on `feature/buffer-recovery-foundation`. Keep the original `pi-studio` checkout frozen and the normal installation unchanged. Use new candidate-scoped evidence; old dirty-state/HEAD-pinned verifiers are historical, not scripts to repoint at a new build.
6
+
7
+ ## Scope of the earlier two-flag candidates
8
+
9
+ The first local `0.10.0-alpha.1` candidate exposes the existing **one Prompt ↔ one Document** workflow only when both `PI_STUDIO_BUFFER_RECOVERY=1` and `PI_STUDIO_BUFFER_SWITCHING=1` are explicitly set for a full editable workspace. Neither flag becomes a default. The version was unused when npm was queried on 2026-09-22 (`latest: 0.9.60`, `next: 0.9.60-rc.0`). Recheck before any eventual publication to npm `next`, never `latest`.
10
+
11
+ Included: independent editing/previews, switching during an identified Run, explicit selection/full-document snapshot appends, guarded response/critique loading, the leading-only Prompt annotation header, temporary recovery, and the accumulated ownership/reading-state fixes. The separately approved toolbar rebuild groups Add and Open/load actions and moves routine help into their disclosures/tooltips; keep its artifact/results separate from the first alpha.
12
+
13
+ Excluded: role switching between existing buffers, companion-to-Prompt transfer, preview extraction, multiple documents, create/close/park controls, automatic preservation of an unfinished Prompt when annotating a response, durable draft storage, editor-engine migration and new REPL work. The full architecture in [BUFFER-DESIGN.md](BUFFER-DESIGN.md) remains a later target. These exclusions are not feature work to add to this alpha.
14
+
15
+ ## Additional hosting scope and remaining gates
16
+
17
+ The development checkout adds a third opt-in flag, `PI_STUDIO_DOCUMENT_HOSTING=1`, effective only with both recovery and switching enabled. Earlier alpha/toolbar tarballs do not contain this work; their full-suite and fresh-install results are historical, not hosting-package acceptance. [README.md](README.md#additional-opt-in-prototype-single-owner-document-hosting) describes the controls and deliberate entrypoint restrictions.
18
+
19
+ The approved addition is one editing owner per Document: move, detached copy, registered blank/text-file editor creation, existing-owner reuse, atomic text-file replacement and retained save/metadata resolution. Prompt remains anchored. The previous exclusions still apply to simultaneous linked views, Prompt-role migration, durable storage, editor migration and new REPL work. Keep this feature set fixed while closing the gates below.
20
+
21
+ - [ ] Finish entrypoint and permission/resource checks, including trusted commands/tools, direct URLs, exports, watched mode, hosted Refresh and explicitly refused Office conversions. A retained identity or path hint must not grant access.
22
+ - [ ] Cover remaining disconnect, cancellation/decline, reload, quota/storage-change and delayed source/metadata producers. A missing reply, failed focus or popup refusal must never authorize another independent Document.
23
+ - [ ] Verify original Prompt text, metadata and terminal-consumption authority through each Document operation, including edits made while a reply is pending.
24
+ - [ ] Validate default, recovery-only, two-flag and three-flag modes; watched previews stay read-only. Run the complete suite as well as the focused ownership tests and TypeScript.
25
+ - [ ] Build a **new exact artifact**, audit every packaged file/import and test a fresh private installation of that artifact. Source-tree browser trials and the older toolbar package are not substitutes.
26
+ - [ ] Record native fixture limitations separately from human/provider acceptance; preserve failures, backups, source hashes, resource samples and owned-only cleanup evidence.
27
+
28
+ None of these gates authorizes a commit, publication, normal installation change or live-provider trial. The release process below still applies to the new artifact; do not mark it complete using results from an earlier candidate.
29
+
30
+ ## Historical evidence already available
31
+
32
+ The following results belong to `7bdc891` or earlier checkpoints, not the `40d4462` pane-scroll follow-up described in step 1.
33
+
34
+ | Evidence | What it establishes | Qualification |
35
+ | --- | --- | --- |
36
+ | 718 full-suite tests | Recorded pass on the committed runtime/test bytes | Not rerun on 2026-09-20; not an exact prerelease artifact check |
37
+ | 202 focused tests, normal typecheck, syntax/whitespace and runtime-boundary checks | Fresh pass on 2026-09-20 | Supplemental check-JS remains nonpassing with 493 previously recorded, unchanged diagnostics |
38
+ | 41 Brave checks; 29 Chrome-app + 12 Chrome Headless Shell 153 checks | All cases in the latest 41-case browser matrix have passing coverage | Chrome coverage spans two variants; historical Brave use is not the future automation policy |
39
+ | Earlier hands-on/live-model and rendered-preview trials | Useful workflow evidence at their respective checkpoints | Earlier live-model and Safari-foundation results are not current switcher/provider or fresh-package sign-off |
40
+
41
+ The final shell trial used a dedicated test binary, took 39 seconds and recorded 20 normal-pressure samples, peak sampled owned RSS of 863 MiB and no swap growth. Its archive was verified before disposal and its processes/listeners were checked stopped. This does not explain earlier Chrome-app startup failures or guarantee headroom for another run.
42
+
43
+ Local evidence directories (ignored, not package contents): `context/recovery-review-20260920_215659/`, `context/chrome-headless-neighbour-20260920_220551/`, and `context/scroll-ownership-checkpoint-20260920_221223/`. Preserve the earlier settings-drift qualifications; do not claim uninterrupted historical preservation of the whole global settings file.
44
+
45
+ ## 1. Resolve the known release question
46
+
47
+ Bounded triage was approved and performed on 2026-09-20: current production pane-activation/restore and view/trace-render functions reproduce stale scroll in deterministic VM scheduling, both before the first callback and before the second frame. Settled-frame, same-view and interactive-target controls pass. The pane-restore helper block is byte-identical to `0.9.60`. This establishes a separate older callback-ownership gap, not a new buffer regression or a native timing result. No content mutation occurred in these adapters; that is not a general data-preservation audit. Four warning-pressure samples refused a new browser launch. Local evidence: `context/pane-scroll-triage-20260920_230154/`.
48
+
49
+ - [x] Choose and implement the separately approved narrow fix with failing regressions first. Pane snapshots retain DOM/view generations and recovery-mode editor/buffer consent without removing same-view or independent-pane restoration. Of 38 new VM cases, 29 failed before the change and 9 controls passed; all 38 now pass. Evidence: `context/pane-scroll-fix-20260920_232725/`. Product/tests were subsequently committed with approval as `40d4462`.
50
+ - [x] Complete bounded native confirmation on 2026-09-21 after passing resource preflight. In dedicated Chrome Headless Shell 153, both immediate and before-second-frame windows move old Working from 10259px to 0 in default/two-buffer modes; the fix retains 10259px. Settled/same-view controls and unaffected-source offsets pass. Trusted pane input plus deliberately scheduled programmatic view changes isolate the windows without patching application functions/RAF; this is not human timing/frequency evidence. All 25 samples across six attempts stayed normal, peak sampled owned RSS 1026.75 MiB, no per-trial swap growth. Backup-before-disposal and process/port cleanup verified, including two retained harness-calibration failures. Evidence: `context/pane-scroll-native-20260921_225607/`.
51
+ - [x] Rerun 240 focused tests, normal typecheck and syntax/whitespace/runtime-boundary checks after browser cleanup. Full suite/supplemental check-JS were not rerun; prerelease artifact gates below remain outstanding.
52
+ - [x] Explicitly accept the separately reported **Working appears empty until interaction** as a documented limitation for local alpha preparation; final publication remains gated. Native view/buffer returns retained content, geometry and inspected screenshots before content interaction; the symptom remains unreproduced, not claimed fixed. Headless tab switching never made the page hidden, so true background-tab/visible-browser paint behaviour is unverified. No rendering/CSS workaround was added.
53
+ - [x] Obtain separate checkpoint approval and commit only the scroll code/tests as `40d4462`. Local alpha preparation is approved; publication is not. Distinguish scroll movement, empty-looking painting and absent content from wrong submission destination or lost edits; do not infer those more serious outcomes from this bounded test. Data loss, unauthorized mutation or wrong-target submission must be fixed before publishing. Any accepted limitation needs Oliver's decision, not an implicit waiver.
54
+
55
+ Stop this triage once that decision is supported. It is not a new whole-branch review or an invitation to add adjacent features.
56
+
57
+ ## 2. Define the candidate
58
+
59
+ - [x] Approve the smaller alpha scope and choose unused `0.10.0-alpha.1` after checking the registry. Do not reuse or overwrite a published version.
60
+ - [x] Align README, changelog and the status summaries in the design/foundation docs with the chosen scope. Distinguish historical milestones from current validation, including the two Chrome variants and the remaining timing decision.
61
+ - [x] Document activation, expected behaviour with neither flag/only recovery/both flags, and unchanged editor-only/watched modes. No general tabs or parked-prompt promises.
62
+ - [x] Explain recovery lifetime and rollback: session storage plus a bounded process-memory fallback are **not durable backup**. Save/export both drafts before closing a trial or returning to an older build; older UIs may not display experimental v2 copies. Preserve those copies rather than deleting them.
63
+ - [x] Update package/lock versions together under preparation approval. Record base commit `40d4462` plus the exact candidate worktree/package file list and hashes; this is not yet a candidate commit.
64
+ - [ ] Obtain separate approval before committing documentation/package changes. Do not repoint historical verifiers.
65
+
66
+ ## 3. Validate once against that candidate
67
+
68
+ ### Test setup
69
+
70
+ - [ ] Start only with normal sampled memory pressure, stable swap, adequate disk headroom and no competing owned test jobs. Use one trial at a time; do not overlap browsers with full-suite/typecheck jobs. Stop/refuse if the resource budget is exceeded rather than weaken test expectations.
71
+ - [ ] Select an existing, executable **test-only Chromium/Chrome Headless Shell** explicitly. Never use everyday Brave for unattended testing or silently fall back to another browser. Record the executable/version and use independent profiles, temporary files, agent state and ports.
72
+ - [ ] Configure and verify `PUPPETEER_EXECUTABLE_PATH` before the full suite. `npm test` includes `test/studio-tab-launcher-browser.test.js`, whose current discovery falls back to ordinary Brave/Chrome if the supplied path is absent or invalid. Refuse the run unless the dedicated path is verified; an unconfigured full suite is not browser-free.
73
+ - [ ] Prepare candidate-scoped launchers without changing the existing behaviour assertions. Keep model credentials/tools and shared REPL access disabled for synthetic checks. Do not use this coding session's global Studio tools to drive the private instance.
74
+
75
+ ### Automated gates
76
+
77
+ - [ ] Run the full suite serially (`npm test -- --test-concurrency=1`) under the verified browser/resource setup. Record actual counts, failures and skips; do not assume the earlier 718 result covers a newly built artifact.
78
+ - [ ] Run the focused ownership/scroll/append regressions, normal typecheck, client JavaScript syntax and whitespace checks. If supplemental check-JS is used, report its existing baseline separately and investigate new diagnostics; do not label the baseline as a passing check.
79
+ - [ ] Run a production dependency audit. Resolve blockers or record explicit decisions; do not bundle unrelated upgrades into the candidate.
80
+ - [ ] Pack the intended artifact, audit its complete file list and compare packaged runtime/assets to the candidate bytes. Include required modules and usable public documentation links; exclude `context/`, transcripts, recovery archives, private URLs, credentials and test profiles. Record the tarball hash/integrity and version.
81
+ - [ ] Install **that tarball**, not a mutable checkout, in a fresh disposable location. Verify exactly one Studio extension loads from that installation, assets match the package, unauthenticated requests remain rejected, and no normal Pi settings/source entry is changed.
82
+
83
+ ### Fresh-install smoke and short workflow trial
84
+
85
+ - [ ] In the private fresh installation, check the default, recovery-only and two-flag modes, plus editor-only and watched-preview compatibility. A targeted smoke is sufficient; identify any older evidence being reused and its scope.
86
+ - [ ] Exercise: start Prompt → edit a disposable Document → append selection/full document → annotate the detached Prompt copy → return without sending → explicitly Run. Check the source remains independent and the submitted text is the intended Prompt, not Document or scratchpad. Intercepted/synthetic Runs establish client behaviour only.
87
+ - [ ] Check response/Working ownership across a buffer round trip, protected replacement/Cancel, save versus later typing, acknowledged reload of both drafts, and a visible safe outcome when recovery is unavailable. Include the decision from step 1; do not hide it behind an extra frame wait.
88
+ - [ ] Arrange a short hands-on trial if approved. A real model Run/Stop needs separate provider approval and an isolated credential setup; if omitted, state that live-provider acceptance is unverified rather than counting synthetic messages as model success.
89
+ - [ ] Capture and verify the actual live drafts before disposal, unless their owner explicitly chooses to discard disposable test text. Never assume unsaved work is disposable. Close only owned browsers/runtimes, verify their processes and ports are gone, and retain required recovery artifacts. Cleanup must also cover launch/setup failures; inspect ownership before signalling anything.
90
+
91
+ Record each result against the candidate/tarball and browser version. If runtime changes, rerun the affected checks and the release gates on the new artifact; do not overwrite old evidence or launch an unbounded review loop.
92
+
93
+ ## 4. Explicit release decision
94
+
95
+ - [ ] Summarise the exact version/commit/tarball, passed gates, any accepted limitation and unverified environments. Obtain approval to publish **that artifact** to `next`.
96
+ - [ ] Publish the verified tarball with the explicit `next` tag, never the default `latest` tag. Let Oliver handle any npm browser/passkey/OTP authentication; do not create a stored publishing token as a workaround.
97
+ - [ ] Verify the registry version, integrity and dist-tag, confirm `latest` has not moved, and test a disposable installation of the published package against the audited artifact.
98
+ - [ ] Push/tag only with approval. Changing Oliver's normal installation or enabling either flag by default is another decision; publication does not authorize either.
99
+
100
+ **Done for this alpha:** the approved opt-in package is reproducible, the intended workflow has the stated evidence, limitations and rollback are clear, and the stable installation remains untouched. For the new candidate, this includes the separately approved third-flag hosting scope and its exact artifact gates; broader buffer management remains deferred.