From 7e42d115c0884b4c26842b891d168df3310b5bc8 Mon Sep 17 00:00:00 2001 From: benstull <1+benstull@noreply.localhost> Date: Fri, 26 Jun 2026 13:50:31 +0000 Subject: [PATCH 1/2] feat(ux): unify Ask-Claude-to-Edit on a split-below multi-line webview (#65) --- package.json | 28 ---- src/editInstructionInput.ts | 147 ++++++++++++++++++ src/extension.ts | 27 ++-- src/inlineAsk.ts | 71 --------- src/trackChangesPreview.ts | 38 ++--- .../suite-no-workspace/noWorkspace.test.ts | 2 - test/e2e/suite/f12Reach.test.ts | 14 +- 7 files changed, 180 insertions(+), 147 deletions(-) create mode 100644 src/editInstructionInput.ts delete mode 100644 src/inlineAsk.ts diff --git a/package.json b/package.json index d020108..e8c2e90 100644 --- a/package.json +++ b/package.json @@ -64,16 +64,6 @@ "title": "Ask Claude to Edit", "category": "Cowriting" }, - { - "command": "cowriting.askClaude.submit", - "title": "Ask Claude to Edit", - "category": "Cowriting" - }, - { - "command": "cowriting.askClaude.cancel", - "title": "Cancel", - "category": "Cowriting" - }, { "command": "cowriting.editSelection", "title": "Ask Claude to Edit Selection", @@ -133,14 +123,6 @@ "command": "cowriting.rejectProposal", "when": "false" }, - { - "command": "cowriting.askClaude.submit", - "when": "false" - }, - { - "command": "cowriting.askClaude.cancel", - "when": "false" - }, { "command": "cowriting.pinDiffBaseline", "when": "editorLangId == markdown" @@ -205,11 +187,6 @@ "command": "cowriting.reply", "group": "inline", "when": "commentController == cowriting.threads" - }, - { - "command": "cowriting.askClaude.submit", - "group": "inline", - "when": "commentController == cowriting.askClaude" } ], "comments/commentThread/title": [ @@ -222,11 +199,6 @@ "command": "cowriting.reopenThread", "group": "inline", "when": "commentController == cowriting.threads && commentThread =~ /^resolved$/" - }, - { - "command": "cowriting.askClaude.cancel", - "group": "inline", - "when": "commentController == cowriting.askClaude" } ] }, diff --git a/src/editInstructionInput.ts b/src/editInstructionInput.ts new file mode 100644 index 0000000..12cb29c --- /dev/null +++ b/src/editInstructionInput.ts @@ -0,0 +1,147 @@ +import * as vscode from "vscode"; +import { randomBytes } from "crypto"; + +/** + * The multi-line instruction input for "Ask Claude to Edit" — BOTH the selection + * and the whole-document case. A small focused webview (a tall, resizable + * textarea + Send) opened in a split pane BELOW the document — not a comment + * thread, and not the top QuickInput (which is single-line only; VS Code has no + * multi-line input at the command-palette location). For a selection edit the + * document stays in the pane above with the selection still highlighted (VS + * Code's inactive-selection style), so the user can see exactly what Claude will + * edit; the caller has already captured the selection, so we never touch it. + * + * The split collapses when the input is submitted or cancelled, and focus is + * handed back to the document so the collapsing split doesn't reveal the bottom + * panel. `header` names the scope ("Ask Claude to Edit This Selection" / + * "…This Document"). + * + * The webview only collects text and posts it to the host — no SDK or secret + * surface lives in it (INV-8/35); the sealed CSP allows no network. Because a + * webview CAN read its own textarea, Cancel / Escape confirms ONLY when there is + * text to lose (closing the tab is an explicit dismiss, no prompt). Resolves with + * the typed instruction, or `undefined` if cancelled / closed / left empty. + */ +export async function promptEditInstruction(header: string): Promise { + // Remember the document editor we came from so we can hand focus back to it + // when the input closes — otherwise, when the empty split group below collapses, + // focus falls into the bottom panel (Output / Debug Console / …) and it pops + // open. Restoring editor focus leaves whatever panel state the user had untouched. + const source = vscode.window.activeTextEditor; + // Open a split editor group BELOW the current one and host the input there, so + // it sits under the document instead of covering it as a tab. The new group is + // empty, so disposing the panel on submit/cancel leaves it empty and VS Code + // collapses the split (the `workbench.editor.closeEmptyGroups` default). Falls + // back to a tab in the active group if the split command is unavailable. + try { + await vscode.commands.executeCommand("workbench.action.newGroupBelow"); + } catch { + /* no split — the panel opens as a tab in the active group instead */ + } + return new Promise((resolve) => { + const panel = vscode.window.createWebviewPanel( + "cowriting.askClaudeInput", + header, + { viewColumn: vscode.ViewColumn.Active, preserveFocus: false }, + { enableScripts: true, retainContextWhenHidden: false }, + ); + + let settled = false; + const done = (value: string | undefined): void => { + if (settled) return; + settled = true; + resolve(value); + panel.dispose(); + // Hand focus back to the originating document so the collapsing split + // doesn't leave focus in (and reveal) the bottom panel. + if (source) { + void vscode.window.showTextDocument(source.document, { + viewColumn: source.viewColumn ?? vscode.ViewColumn.One, + preserveFocus: false, + }); + } + }; + + panel.webview.onDidReceiveMessage((m: { type?: string; text?: string }) => { + const text = (m?.text ?? "").trim(); + if (m?.type === "submit") { + done(text ? text : undefined); + } else if (m?.type === "cancel") { + // Confirm only if there's something to lose (we can read the textarea here). + if (!text) { + done(undefined); + return; + } + void vscode.window + .showWarningMessage("Discard your Ask-Claude instruction?", { modal: true }, "Discard") + .then((pick) => { + if (pick === "Discard") done(undefined); + // else: leave the panel open so the operator can keep editing. + }); + } + }); + // Closing the tab is an explicit dismiss — cancel without a prompt. + panel.onDidDispose(() => done(undefined)); + panel.webview.html = htmlFor(header); + }); +} + +function escapeHtml(s: string): string { + return s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]!); +} + +function htmlFor(header: string): string { + const nonce = randomBytes(16).toString("base64"); + // Sealed CSP: no network; inline style only; the one script is nonce-gated. + const csp = `default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${nonce}';`; + const title = escapeHtml(header); + return ` + + + + + ${title} + + + +

${title}

+ +
+ ⌘↵ / Ctrl+↵ to send · Esc to cancel + +
+ + +`; +} diff --git a/src/extension.ts b/src/extension.ts index 08ec9b1..ec36c22 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,7 +12,6 @@ import { SidecarRouter } from "./sidecarRouter"; import { DiffViewController } from "./diffViewController"; import { TrackChangesPreviewController } from "./trackChangesPreview"; import { LiveProgressUi } from "./liveProgressUi"; -import { InlineAskController } from "./inlineAsk"; import { isAuthorable, routeEdit, selectionRejection } from "./workspacePath"; const CHANNEL_NAME = "Cowriting (Cline SDK)"; @@ -26,7 +25,6 @@ export interface CowritingApi { trackChangesPreviewController: TrackChangesPreviewController; sidecarRouter: SidecarRouter; liveProgressUi: LiveProgressUi; - inlineAsk: InlineAskController; } export function activate(context: vscode.ExtensionContext): CowritingApi | undefined { @@ -38,11 +36,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef // OutputChannel) for both Ask-Claude entry points. const liveProgressUi = new LiveProgressUi(); context.subscriptions.push(liveProgressUi); - - // The inline "Ask Claude to Edit" prompt — rendered at the selection/cursor via - // the Comments API rather than the top-center QuickInput (see inlineAsk.ts). - // Shared by both Ask-Claude entry points (editSelection + the preview's askClaude). - const inlineAsk = new InlineAskController(context.subscriptions); context.subscriptions.push( vscode.commands.registerCommand("cowriting.showClineSdkInfo", async () => { try { @@ -119,7 +112,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef attributionController, proposalController, liveProgressUi, - inlineAsk, ); context.subscriptions.push(trackChangesPreviewController); @@ -227,17 +219,23 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef if (!editor) return; // unreachable once reason is null, but narrows the type const document = editor.document; const selection = editor.selection; // non-empty (selectionRejection guaranteed it) - // The instruction prompt opens INLINE at the selection (inlineAsk), not the - // top-center QuickInput — anchored to the text Claude will edit. - const instruction = await inlineAsk.prompt(document.uri, selection); - if (!instruction) return; + // Capture the selection text + anchor BEFORE prompting — the inline prompt + // moves the cursor to the document top (where its box anchors), which would + // otherwise collapse the selection we act on (spec §6.5 PUC-1: anchor + // captured pre-turn so mid-turn edits can't skew it). const selectedText = document.getText(selection); - // Capture the anchor BEFORE the turn (spec §6.5 PUC-1): mid-turn edits - // can't skew it — the proposal renders wherever the target re-resolves. const fp = buildFingerprint(document.getText(), { start: document.offsetAt(selection.start), end: document.offsetAt(selection.end), }); + // The instruction prompt is the multi-line split-below webview box (shared + // with the document case, via the preview controller); the document above + // keeps the selection highlighted while it's open. selectedText/fp were + // captured above, so moving focus to the box doesn't affect what we edit. + const instruction = await trackChangesPreviewController.askEditInstruction( + "Ask Claude to Edit This Selection", + ); + if (!instruction) return; const turnId = `turn-${Date.now().toString(36)}`; try { await vscode.window.withProgress( @@ -344,7 +342,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef trackChangesPreviewController, sidecarRouter, liveProgressUi, - inlineAsk, }; } diff --git a/src/inlineAsk.ts b/src/inlineAsk.ts deleted file mode 100644 index 40c3953..0000000 --- a/src/inlineAsk.ts +++ /dev/null @@ -1,71 +0,0 @@ -import * as vscode from "vscode"; - -/** Trim the reply text; an empty/whitespace-only instruction is "no instruction". */ -export function normalizeInstruction(text: string | undefined): string | undefined { - const t = text?.trim(); - return t ? t : undefined; -} - -/** - * The "Ask Claude to Edit" prompt, rendered INLINE at the selection (or cursor) - * instead of the top-center QuickInput. VS Code's native pattern for "ask AI to - * edit this" is Inline Chat — an input anchored in the editor at the target. The - * stable-API equivalent for a third-party extension is the Comments API: a - * transient comment thread whose reply box renders right at the range. (The - * coauthoring THREADS feature already uses the Comments API via its own - * controller — this is a SEPARATE, dedicated `cowriting.askClaude` controller so - * the two never collide.) - * - * One prompt is live at a time; opening a new one cancels the previous. The - * thread carries no comments — it is purely the inline input — and is disposed - * as soon as the user submits or cancels. - */ -export class InlineAskController { - private readonly controller: vscode.CommentController; - private pending?: { resolve: (v: string | undefined) => void; thread: vscode.CommentThread }; - - constructor(disposables: vscode.Disposable[]) { - this.controller = vscode.comments.createCommentController("cowriting.askClaude", "Ask Claude to Edit"); - // The reply box's prompt + placeholder (Comments API options). - this.controller.options = { - prompt: "Ask Claude to Edit", - placeHolder: "e.g. tighten this paragraph", - }; - disposables.push( - this.controller, - vscode.commands.registerCommand("cowriting.askClaude.submit", (r: vscode.CommentReply) => - this.finish(normalizeInstruction(r?.text)), - ), - vscode.commands.registerCommand("cowriting.askClaude.cancel", () => this.finish(undefined)), - // The controller itself disposes the live thread on extension teardown. - new vscode.Disposable(() => this.finish(undefined)), - ); - } - - /** - * Open the inline input anchored at `range` in `uri`'s editor and resolve with - * the typed instruction (or `undefined` if cancelled / left empty). Replaces - * any prompt already open. - */ - prompt(uri: vscode.Uri, range: vscode.Range): Promise { - // A fresh prompt supersedes any prior one (resolve it as cancelled). - this.finish(undefined); - return new Promise((resolve) => { - const thread = this.controller.createCommentThread(uri, range, []); - thread.label = "Ask Claude to Edit"; - thread.canReply = true; - thread.collapsibleState = vscode.CommentThreadCollapsibleState.Expanded; - thread.contextValue = "askClaude"; - this.pending = { resolve, thread }; - }); - } - - /** Resolve the live prompt (if any) and tear its thread down. */ - private finish(value: string | undefined): void { - const p = this.pending; - this.pending = undefined; - if (!p) return; - p.thread.dispose(); - p.resolve(value); - } -} diff --git a/src/trackChangesPreview.ts b/src/trackChangesPreview.ts index 9456ec0..45c9244 100644 --- a/src/trackChangesPreview.ts +++ b/src/trackChangesPreview.ts @@ -18,7 +18,7 @@ import { buildFingerprint } from "./anchorer"; import { isAuthorable } from "./workspacePath"; import type { EditTurnResult, RunEditTurnOptions } from "./liveTurn"; import type { LiveProgressUi } from "./liveProgressUi"; -import type { InlineAskController } from "./inlineAsk"; +import { promptEditInstruction } from "./editInstructionInput"; /** * F11: a host edit turn (selection/document text + instruction → rewrite). @@ -63,6 +63,13 @@ export class TrackChangesPreviewController implements vscode.Disposable { const { runEditTurn } = await import("./liveTurn"); return runEditTurn(instruction, text, opts); }; + /** + * The instruction prompt (the multi-line split-below webview box) for BOTH the + * selection and document cases. A field so host E2E can stub it — the webview + * DOM can't run in CI (mirrors `editTurn`). Also used by the editor's + * `cowriting.editSelection` command (via this controller). + */ + askEditInstruction: (header: string) => Promise = promptEditInstruction; /** Monotonic per-session counter minting a stable turnId for each Ask-Claude gesture. */ private turnSeq = 0; private nextTurnSeq(): number { @@ -75,7 +82,6 @@ export class TrackChangesPreviewController implements vscode.Disposable { private readonly attribution: AttributionController, private readonly proposals: ProposalController, private readonly liveProgressUi: LiveProgressUi, - private readonly inlineAsk: InlineAskController, ) { this.disposables.push( // F11 (SLICE-5): the editor/title gateway passes the tab's resource Uri; @@ -222,34 +228,18 @@ export class TrackChangesPreviewController implements vscode.Disposable { ); } - /** - * Where the inline Ask-Claude input anchors: a range edit pins to its selection; - * a whole-document edit pins to the editor's cursor line if this document is the - * active editor, else to the document start. - */ - private editTargetAnchor(document: vscode.TextDocument, target: EditTarget): vscode.Range { - if (target.kind === "range") { - return new vscode.Range(document.positionAt(target.start), document.positionAt(target.end)); - } - const active = vscode.window.activeTextEditor; - if (active && active.document.uri.toString() === document.uri.toString()) { - const line = active.selection.active.line; - return new vscode.Range(line, 0, line, 0); - } - return new vscode.Range(0, 0, 0, 0); - } - /** * F11 (PUC-3/4): prompt host-side for the instruction (keeps the LLM/secret * surface out of the sealed webview, INV-8/35), run the edit turn, and surface * the result as F4 proposal(s). UI wrapper around `runEditAndPropose`. */ private async askClaude(document: vscode.TextDocument, target: EditTarget): Promise { - // The instruction prompt opens INLINE (inlineAsk) at the target: the selected - // range for a range edit, or the editor's cursor line / the document start for - // a whole-document edit — never the top-center QuickInput. - const anchor = this.editTargetAnchor(document, target); - const instruction = await this.inlineAsk.prompt(document.uri, anchor); + // Both scopes use the same multi-line split-below webview box; only the header + // (and the downstream proposal logic) differs. For a selection the document + // above keeps the selection highlighted while the box is open. + const header = + target.kind === "document" ? "Ask Claude to Edit This Document" : "Ask Claude to Edit This Selection"; + const instruction = await this.askEditInstruction(header); if (!instruction) return; try { const ids = await vscode.window.withProgress( diff --git a/test/e2e/suite-no-workspace/noWorkspace.test.ts b/test/e2e/suite-no-workspace/noWorkspace.test.ts index e85682f..7c645e9 100644 --- a/test/e2e/suite-no-workspace/noWorkspace.test.ts +++ b/test/e2e/suite-no-workspace/noWorkspace.test.ts @@ -30,8 +30,6 @@ suite("no-workspace authoring (F8 — real folder-less, #8 lineage)", () => { "cowriting.reopenThread", "cowriting.edit", "cowriting.editSelection", - "cowriting.askClaude.submit", - "cowriting.askClaude.cancel", "cowriting.applyAgentEdit", "cowriting.proposeAgentEdit", ]) { diff --git a/test/e2e/suite/f12Reach.test.ts b/test/e2e/suite/f12Reach.test.ts index f96cda9..7b10bc6 100644 --- a/test/e2e/suite/f12Reach.test.ts +++ b/test/e2e/suite/f12Reach.test.ts @@ -76,9 +76,9 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => { await vscode.window.showTextDocument(a.doc); await settle(); - // Stub the instruction prompt (sealed input box can't run in CI) + the LLM turn. - const origPrompt = api.inlineAsk.prompt; - (api.inlineAsk as any).prompt = async () => "rewrite it"; + // Stub the document instruction prompt (the webview can't run in CI) + the LLM turn. + const origPrompt = ctl.askEditInstruction; + ctl.askEditInstruction = async () => "rewrite it"; ctl.setEditTurnForTest(async () => ({ replacement: "# Tab\n\nThe REWRITTEN tab paragraph.\n", model: "sonnet", @@ -88,7 +88,7 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => { await vscode.commands.executeCommand("cowriting.editDocument", b.doc.uri); await settle(); } finally { - (api.inlineAsk as any).prompt = origPrompt; + ctl.askEditInstruction = origPrompt; } // The proposal(s) landed on the TAB doc (B), and the ACTIVE doc (A) has none. @@ -110,8 +110,8 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => { await vscode.window.showTextDocument(a.doc); await settle(); - const origPrompt = api.inlineAsk.prompt; - (api.inlineAsk as any).prompt = async () => "rewrite it"; + const origPrompt = ctl.askEditInstruction; + ctl.askEditInstruction = async () => "rewrite it"; ctl.setEditTurnForTest(async () => ({ replacement: "# No arg\n\nThe REWRITTEN active doc paragraph.\n", model: "sonnet", @@ -121,7 +121,7 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => { await vscode.commands.executeCommand("cowriting.editDocument"); await settle(); } finally { - (api.inlineAsk as any).prompt = origPrompt; + ctl.askEditInstruction = origPrompt; } assert.ok(api.proposalController.listProposals(a.doc).length >= 1, "active doc received the proposal(s) on no-arg"); }); From d2ef9457c4f6264e0d9e1466037cd5368c39fd74 Mon Sep 17 00:00:00 2001 From: BenStullsBets Date: Fri, 26 Jun 2026 06:56:48 -0700 Subject: [PATCH 2/2] add sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--2026-06-26T06-55.md + replace placeholder/variant SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--INPROGRESS.md --- ...RIPT-2026-06-26T04-35--2026-06-26T06-55.md | 111 ++++++++++++++++++ ...TRANSCRIPT-2026-06-26T04-35--INPROGRESS.md | 22 ---- 2 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--2026-06-26T06-55.md delete mode 100644 sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--INPROGRESS.md diff --git a/sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--2026-06-26T06-55.md b/sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--2026-06-26T06-55.md new file mode 100644 index 0000000..58af542 --- /dev/null +++ b/sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--2026-06-26T06-55.md @@ -0,0 +1,111 @@ +# Session 0057.0 — Transcript + +> App: vscode-cowriting-plugin +> Start: 2026-06-26T04-35 (PST) +> End: 2026-06-26T06-55 (PST) +> Type: executing-plans +> Posture: yolo +> Claude-Session: 3d66a467-8026-472d-9693-52a37939d493 +> Goal: Operator-feedback UX fixes on the Ask-Claude-to-Edit experience (broken +> keybinding, missing/duplicated shortcuts, edit-box placement) — then iterate the +> edit-input UX to its final form. +> Outcome: Shipped two PRs to vscode-cowriting-plugin main (#62, #65); fixed and +> shipped a dev-plugin bug (#134 / PR #135, v0.60.0) surfaced mid-session. + +## Plan + +Operator opened with three asks on the Ask-Claude UX: the live/review-panel +shortcut didn't work, there was no shortcut for "Ask Claude to Edit +Selection/Document" (wanted one combined shortcut), and the edit box appeared in +a disliked spot (near the command palette) — with a request to recommend a +VS-Code-idiomatic placement. Routed as an executing-plans (yolo) session. + +The session became an extended live iterate-and-verify loop on the edit-input UX, +driven by the operator testing each build in an Extension Development Host. + +## Pre-session state + +- On branch `s60-live-progress`; `#60` (live turn progress) work in flight. +- A **concurrent session (0056)** was live in the SAME working checkout, actively + committing/stashing `#60` — which clobbered this session's uncommitted edits + twice before isolation. + +## Turn-by-turn arc + +1. **Phase A (keybindings + command unify).** Added one `cowriting.edit` command + that routes selection-vs-document at runtime via a pure `routeEdit` helper + (unit-tested); hid the two underlying commands from the palette; collapsed the + split menus to one entry. Added `⌘⌥E`/`Ctrl+Alt+E` (edit) and `mac` variants + for `⌘⌥R`/`Ctrl+Alt+R` (review panel) — the missing `mac` variant was why the + panel shortcut "didn't work" (Option-key combos are unreliable on macOS). + +2. **Concurrent-checkout incident + recovery.** Discovered session 0056 was + clobbering the shared tree (git stash/pop/commit out from under this session). + Exported the edits as a durable patch, created an **isolated git worktree**, and + moved all work there. (§5.4 lesson — should have isolated up front.) + +3. **Input-box placement (design Q).** Recommended + implemented an inline input + via the Comments API; then iterated heavily per operator feedback: + inline-at-selection → top-of-document → **finally a multi-line webview in a + split pane below the document for BOTH scopes**. Each iteration was built and + verified live in the EDH. + +4. **Dev-plugin bug #134 (the root cause of the clobber).** Filed plugin feedback + #134 (two sessions can share one working tree — isolation was prose, not a + deterministic guard), then implemented the fix: `claim-session-id.sh` now stamps + `> Checkout:` and **refuses a claim when another live session occupies the same + checkout** (self-session excepted; `WGL_ALLOW_SHARED_CHECKOUT=1` override). + Shipped as PR #135 / v0.60.0 and made live in the running install. + +5. **Final edit-input form (PR #65).** Unified both scopes on the split-below + multi-line webview (`editInstructionInput.ts` / `promptEditInstruction`): + auto-focus, ⌘↵ send, Esc cancel-with-confirm-if-text, split collapses + focus + restored to the doc on close (no Output/Debug panel popping), selection stays + highlighted above. **Deleted the entire inline-comment mechanism** (`inlineAsk.ts`, + `cowriting.askClaude.submit/cancel`, their menus, the Escape keybinding) — net + deletion. Verified interactively, merged. + +## Cut state (end of session) + +| Repo | Change | Ref | +| --- | --- | --- | +| vscode-cowriting-plugin | Phase A: unify `cowriting.edit` + `routeEdit` + mac keybindings + inline Comments-API input | PR #62 → main (squash `9432300`) | +| vscode-cowriting-plugin | Final: split-below multi-line webview for both scopes; remove inline-comment mechanism | PR #65 → main (squash `7e42d11`) | +| wiggleverse-dev-claude-plugin | Deterministic shared-checkout guard in `claim-session-id.sh` + Step 6b docs; v0.60.0 | PR #135 → main (merge `ca383c4`); installed live | +| wiggleverse-dev-claude-plugin (tracker) | Filed + closed feedback #134 (shared-checkout hazard) | issue #134 `resolution:done` | + +- All worktrees (`s60-edit-ux`, `edit-top-anchor`, dev-plugin `issue134`) removed; + branches deleted; all temporary EDH windows closed. +- 242 unit + typecheck (src + e2e) + build green on the final tip. E2E electron + suite not run (known env-broken locally); webview UX verified interactively. +- Local `main` is 3 behind `origin/main` (sessions 0058/0059 + PR #65 merge) — + cosmetic; a future session pulls. +- Untracked strays `docs/superpowers/plans/2026-06-26-live-turn-progress.md` and + `specs/` predate this session (from the `#60` line / a known `specs/` stray); + left untouched — not this session's to land. + +## Deferred decisions + +None logged. No silent low-confidence calls — every judgment call (worktree +recovery, each UX fork, cancel/placement/size trade-offs) was surfaced live and +decided by the operator or flagged as a hard VS Code API limit. + +## What lands on the operator's plate + +- Nothing blocking. The edit-input UX line is complete and shipped. +- The dev-plugin shared-checkout guard (#134/v0.60.0) is **live for new + sessions** (this session's running install was updated; new sessions get it on + start). +- Known VS Code API limits captured in memory ([[ask-claude-edit-input-ux]]): no + multi-line input at the command-palette location; no API to set an editor split + ratio; no API to read bottom-panel visibility. + +## Prompt the operator can paste into the next session + +This session's thread (Ask-Claude edit UX) is **complete** — there is no single +forced next step. Open backlog items the operator may choose from (each its own +session): `#32` scroll-sync (feature, needs design), `#35` repo rename, `#40` undo +provenance (P3), F11 spec graduation (OQ-2), content-repo draft reconciliation. + +No `Next /goal:` is recorded — the next move is an operator pick from the backlog +above. diff --git a/sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--INPROGRESS.md b/sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--INPROGRESS.md deleted file mode 100644 index c2e8246..0000000 --- a/sessions/0057/SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--INPROGRESS.md +++ /dev/null @@ -1,22 +0,0 @@ -# Session 0057.0 — Transcript - -> App: vscode-cowriting-plugin -> Start: 2026-06-26T04-35 (PST) -> Type: executing-plans -> Posture: yolo -> Claude-Session: 3d66a467-8026-472d-9693-52a37939d493 -> Status: **PLACEHOLDER — claimed at session start; finalized at session end.** -> -> This file reserves session ID 0057 for vscode-cowriting-plugin. The driver replaces this -> body with the full transcript and renames the file to its final -> SESSION-0057.0-TRANSCRIPT-2026-06-26T04-35--.md form at session end. - -## Launch prompt - -_(launch prompt not captured at claim time)_ - -## Deferred decisions - -_Autonomous-mode low-confidence calls the driver made and would have -liked operator input on. Appended as the session runs; surfaced at -finalize. Empty if none._