From 049d889075ba3a5c729f2cc621cfe468e519fd09 Mon Sep 17 00:00:00 2001 From: Vinh Le Date: Wed, 9 Sep 2026 17:44:20 +1000 Subject: [PATCH 1/4] fix: keep the working spinner in the editor border --- index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.ts b/index.ts index d855803..16845d4 100644 --- a/index.ts +++ b/index.ts @@ -625,7 +625,9 @@ export default function queueSteerExtension(pi: ExtensionAPI) { if (features.has(QUEUE_STEER_FEATURE)) return; const factory = ((tui, theme, keybindings) => { - const editor = previousFactory?.(tui, theme, keybindings) ?? new CustomEditor(tui, theme, keybindings); + const editor = previousFactory?.(tui, theme, keybindings) ?? new CustomEditor(tui, theme, keybindings, { + embedWorkingStatus: true, + }); installSubmitGuard(editor, ctx); const handleInput = editor.handleInput.bind(editor); const renderEditor = editor.render.bind(editor); From fc71aae2a38e4575373eeb3e7d6649bfc7f78b9d Mon Sep 17 00:00:00 2001 From: Thomas Mustier <6326440+tmustier@users.noreply.github.com> Date: Thu, 1 Oct 2026 23:51:57 +0100 Subject: [PATCH 2/4] fix: keep the embedded working status visible while editing a queued row --- editor-render.ts | 10 ++++++++++ index.ts | 7 +++++-- test/editor-render.test.ts | 17 ++++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/editor-render.ts b/editor-render.ts index c78f844..b925f35 100644 --- a/editor-render.ts +++ b/editor-render.ts @@ -128,6 +128,16 @@ function stripOuterFrameAndPadding(line: string, paddingX: number): string { * add side borders and padding. The queue already provides that frame, so an * active row should inherit only the live editor content and cursor. */ +/** + * Keep an editor's top border only when it carries an embedded status such as + * Pi's working spinner, so the status stays visible while a queued row is edited inline. + */ +export function extractEmbeddedStatusBorder(lines: readonly string[]): string[] { + const top = lines[0] ?? ""; + const label = stripAnsi(top).replace(/↑ \d+ more/, "").replace(/─/g, "").trim(); + return label ? [top] : []; +} + export function extractInlineEditorLines(lines: readonly string[], paddingX = 0): string[] { if (lines.length === 0) return [""]; if (!isEditorFrame(lines[0] ?? "")) return [...lines]; diff --git a/index.ts b/index.ts index 13b6457..252c66c 100644 --- a/index.ts +++ b/index.ts @@ -10,7 +10,7 @@ import { type ThemeColor, } from "@earendil-works/pi-coding-agent"; import { matchesKey, truncateToWidth, visibleWidth, type Component, type EditorComponent } from "@earendil-works/pi-tui"; -import { extractInlineEditorLines } from "./editor-render.ts"; +import { extractEmbeddedStatusBorder, extractInlineEditorLines } from "./editor-render.ts"; import { expandQueuedInput, queuesDuringCompaction } from "./queued-input.ts"; import { DeliveryQueue, @@ -604,8 +604,11 @@ export default function queueSteerExtension(pi: ExtensionAPI) { } }; + const embedsWorkingStatus = "embedWorkingStatus" in editor && editor.embedWorkingStatus === true; editor.render = (width: number): string[] => { - if (editSession && !renderingInline) return []; + if (editSession && !renderingInline) { + return embedsWorkingStatus ? extractEmbeddedStatusBorder(renderEditor(width)) : []; + } return renderEditor(width); }; diff --git a/test/editor-render.test.ts b/test/editor-render.test.ts index 080fb79..b01d234 100644 --- a/test/editor-render.test.ts +++ b/test/editor-render.test.ts @@ -1,6 +1,6 @@ import assert from "node:assert/strict"; import test from "node:test"; -import { extractInlineEditorLines, stripAnsi } from "../editor-render.ts"; +import { extractEmbeddedStatusBorder, extractInlineEditorLines, stripAnsi } from "../editor-render.ts"; test("removes the stock editor frame without disturbing its cursor", () => { const cursorMarker = "\x1b_pi:c\x07"; @@ -65,3 +65,18 @@ test("does not mistake short horizontal user text for the bottom frame", () => { test("leaves frameless custom editor output intact", () => { assert.deepEqual(extractInlineEditorLines(["custom editor"]), ["custom editor"]); }); + +test("keeps an embedded working status border while a row is edited inline", () => { + const lines = [ + "\x1b[33m── \x1b[36m⠸ Working\x1b[33m ──────\x1b[39m", + "draft ", + "\x1b[33m────────────\x1b[39m", + ]; + + assert.deepEqual(extractEmbeddedStatusBorder(lines), [lines[0]]); +}); + +test("drops plain and overflow-only editor borders while a row is edited inline", () => { + assert.deepEqual(extractEmbeddedStatusBorder(["────────────", "draft", "────────────"]), []); + assert.deepEqual(extractEmbeddedStatusBorder(["─── ↑ 3 more ───", "draft", "────────────"]), []); +}); From 3cbd2b57ac4d78efbeb60c6b579c9a8efc7a95c9 Mon Sep 17 00:00:00 2001 From: Thomas Mustier <6326440+tmustier@users.noreply.github.com> Date: Thu, 1 Oct 2026 23:52:13 +0100 Subject: [PATCH 3/4] chore(release): prepare v0.2.2 --- CHANGELOG.md | 7 +++++++ README.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d5c0ce..bda9967 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 0.2.2 - 2026-10-01 + +### Fixed + +- Keep Pi's working, compaction and retry spinners in the editor border instead of above the input when queue-steer installs the editor ([#11](https://github.com/tmustier/pi-queue-steer/pull/11) by [@VinhLe1410](https://github.com/VinhLe1410)). +- Keep the embedded spinner visible below the queue while a queued row is edited inline. + ## 0.2.1 - 2026-10-01 ### Fixed diff --git a/README.md b/README.md index a2d960a..ef29dc5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ pi install git:github.com/tmustier/pi-queue-steer Pin the current release: ```bash -pi install git:github.com/tmustier/pi-queue-steer@v0.2.1 +pi install git:github.com/tmustier/pi-queue-steer@v0.2.2 ``` Then start a new Pi session or run `/reload`. diff --git a/package-lock.json b/package-lock.json index 10ae141..1203101 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tmustier/pi-queue-steer", - "version": "0.2.1", + "version": "0.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tmustier/pi-queue-steer", - "version": "0.2.1", + "version": "0.2.2", "license": "MIT", "devDependencies": { "@earendil-works/pi-ai": "*", diff --git a/package.json b/package.json index f210dfd..98559c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tmustier/pi-queue-steer", - "version": "0.2.1", + "version": "0.2.2", "description": "Visible steering and follow-up queues with inline editing for Pi.", "type": "module", "license": "MIT", From d82c0589cdf7ba1d61d93a17cfca7c047a53c236 Mon Sep 17 00:00:00 2001 From: Thomas Mustier <6326440+tmustier@users.noreply.github.com> Date: Thu, 1 Oct 2026 23:53:16 +0100 Subject: [PATCH 4/4] docs: record v0.2.2 validation --- docs/validation.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/validation.md b/docs/validation.md index 4961129..dc3405d 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -25,7 +25,19 @@ npm run ci The suite covers queue/edit invariants, command classification, images, one-at-a-time and all-mode delivery, synchronous partial handoff restoration, non-TUI pass-through, prompt and Skill expansion, manual compaction success/failure, automatic overflow compaction, retry ordering, settled-handler launch ordering, repeated reload restoration, and compaction/native-input ordering. -Release 0.2.1: 84 tests passed on both Pi 0.87.0 (the lockfile) and Pi 0.99.2 (the current installed release). +Release 0.2.2: 86 tests passed on both Pi 0.87.0 (the lockfile) and Pi 1.0.0 (the current installed release). + +Release 0.2.1: 84 tests passed on both Pi 0.87.0 and Pi 0.99.2. + +## Embedded working status + +Validated on 1 October 2026 at `3cbd2b57ac4d78efbeb60c6b579c9a8efc7a95c9` for release 0.2.2. + +A scratch Pi 1.0.0 TUI used `openai/gpt-6-astra` at low thinking with only this extension loaded. The prompt asked the model to run `sleep 20 && echo done` with bash. While the tool ran, the TUI queued a follow-up. Terminal captures showed: + +- `── ⠸ Working ───` in the editor's top border below the queue, where 0.2.1 showed `⠸ Working` above the queue +- the same border line below the queue while the queued row was edited inline, with no stray border when editing a paused queue at idle +- the follow-up delivered once after the run ## Automatic-compaction steering regression @@ -67,7 +79,7 @@ Run: The output directory contains plain terminal captures, provider-call logs, lifecycle-event logs, and runtime-initialization logs. Run it immediately before review so `summary.txt` records the exact Pi version, commit and working-tree state under test. A release evidence run should report `working tree: clean`. -The full harness passed against Pi 0.87.0 and 0.99.2 for release 0.2.1. The historical 0.2.0 release-evidence run reported: +The full harness passed against Pi 0.87.0 and 1.0.0 for release 0.2.2, and against Pi 0.87.0 and 0.99.2 for release 0.2.1. The historical 0.2.0 release-evidence run reported: ```text pi: 0.84.1