@timurproko/a1 0.2.7-dev.820 → 0.2.7-dev.831
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/README.md +7 -1
- package/bin/automatic-update.js +7 -0
- package/bin/ui.js +1 -0
- package/dist/app/session-shell/session-shell-root.d.ts +8 -1
- package/dist/app/session-shell/session-shell.js +68 -18
- package/dist/app/session-shell/transcript-document.js +1 -1
- package/dist/composition/owned-ui.d.ts +3 -11
- package/dist/composition/owned-ui.js +93 -42
- package/dist/composition/resident-tab-bridge.d.ts +10 -1
- package/dist/composition/resident-tab-bridge.js +21 -0
- package/dist/composition/settings-route-host.d.ts +12 -2
- package/dist/composition/settings-route-host.js +27 -9
- package/dist/composition/settings-search-input.d.ts +9 -0
- package/dist/composition/settings-search-input.js +58 -0
- package/dist/contracts/owned-ui/session-backend.d.ts +2 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +7 -3
- package/dist/contracts/presentation/index.d.ts +11 -0
- package/dist/contracts/presentation/index.js +12 -0
- package/dist/features/launch/development-launch.js +6 -0
- package/dist/features/launch/profile-paths.js +4 -0
- package/dist/features/owned-ui/plus-menu-dialog.d.ts +22 -0
- package/dist/features/owned-ui/plus-menu-dialog.js +76 -0
- package/dist/features/owned-ui/reference-screen-app.d.ts +2 -0
- package/dist/features/owned-ui/reference-screen-app.js +12 -2
- package/dist/features/owned-ui/settings-app.d.ts +10 -3
- package/dist/features/owned-ui/settings-app.js +98 -45
- package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
- package/dist/features/owned-ui/settings-search-input.js +1 -0
- package/dist/features/prompt-history/index.d.ts +1 -1
- package/dist/features/prompt-history/paths.d.ts +2 -1
- package/dist/features/prompt-history/paths.js +10 -2
- package/dist/features/prompt-history/service.d.ts +5 -0
- package/dist/features/prompt-history/service.js +1 -1
- package/dist/features/resident-tab/shortcut-declarations.d.ts +1 -1
- package/dist/features/resident-tab/shortcut-declarations.js +2 -0
- package/dist/foundation/launch-context/index.d.ts +2 -0
- package/dist/foundation/launch-context/index.js +1 -0
- package/dist/foundation/release/automatic-update.d.ts +37 -0
- package/dist/foundation/release/automatic-update.js +265 -0
- package/dist/foundation/release/bootstrap.d.ts +1 -9
- package/dist/foundation/release/bootstrap.js +7 -3
- package/dist/foundation/release/index.d.ts +1 -1
- package/dist/foundation/release/index.js +1 -1
- package/dist/foundation/release/latest-release.d.ts +3 -2
- package/dist/foundation/release/latest-release.js +1 -1
- package/dist/foundation/release/update-execution-lease.d.ts +36 -0
- package/dist/foundation/release/update-execution-lease.js +145 -0
- package/dist/foundation/release/update.d.ts +8 -6
- package/dist/foundation/release/update.js +232 -167
- package/dist/foundation/resident-tabs/bridge-client.d.ts +8 -2
- package/dist/foundation/resident-tabs/bridge-client.js +13 -6
- package/dist/foundation/resident-tabs/routes.d.ts +5 -0
- package/dist/foundation/resident-tabs/routes.js +5 -0
- package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
- package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
- package/dist/integrations/pi/components/modal-frame.js +48 -9
- package/dist/integrations/pi/components/models-dialog.js +4 -52
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +3 -0
- package/dist/integrations/pi/components/owned-editor-ux.js +75 -4
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +57 -37
- package/dist/integrations/pi/components/shell-footer-status.js +19 -3
- package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +4 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +9 -2
- package/dist/integrations/pi/components/skills-dialog.js +2 -2
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +7 -5
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +15 -8
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +3 -3
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.js +26 -23
- package/dist/integrations/pi/components/upstream/components/session-selector.js +7 -6
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +7 -6
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +9 -8
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +6 -4
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +8 -8
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +10 -10
- package/dist/integrations/pi/components/upstream/history/editor-core.js +2 -0
- package/dist/integrations/pi/engine/adapter.js +7 -2
- package/dist/integrations/pi/engine/ports.d.ts +1 -1
- package/dist/integrations/pi/engine/ports.js +4 -0
- package/dist/integrations/pi/engine/workflow-runner.js +9 -2
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/darwin-arm64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +1 -1
- package/dist/native/darwin-x64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/linux-x64/terminal-host.manifest.json +3 -3
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +3 -3
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/product-identity.d.ts +1 -1
- package/dist/product-identity.js +1 -1
- package/dist/product-identity.json +1 -0
- package/dist/ui/apps/host.d.ts +2 -0
- package/dist/ui/apps/host.js +7 -1
- package/dist/ui/components/dialog-panel.js +35 -30
- package/dist/ui/components/line-input.d.ts +3 -0
- package/dist/ui/components/line-input.js +3 -1
- package/dist/ui/components/prompt-input.d.ts +3 -2
- package/dist/ui/components/prompt-input.js +6 -4
- package/dist/ui/components/surface.js +4 -2
- package/dist/ui/settings/declarations.d.ts +54 -8
- package/dist/ui/settings/declarations.js +36 -7
- package/dist/ui/settings/manager.js +7 -3
- package/dist/ui/settings/migrations.js +15 -0
- package/dist/ui/settings/sections.d.ts +4 -0
- package/dist/ui/settings/sections.js +9 -3
- package/docs/architecture/resident-tabs.md +35 -7
- package/docs/architecture/tool-image-presentation.md +2 -1
- package/docs/features/prompt-history.md +41 -20
- package/package.json +1 -1
|
@@ -167,6 +167,16 @@ Every attach, server, and holder role is `process.execPath` running the release'
|
|
|
167
167
|
Because ConPTY belongs to its creating process, each tab has its own creator. A server crash therefore does not destroy a tab's ConPTY; holder failure affects only that tab. Actual child/tree exit and writer-lease release still require verification, not inference from the pseudoconsole closing. The 2026-10-17 Windows x64 migration measurement put an idle Node-hosted holder at approximately 30–40 MiB of resident memory, versus a few MiB for the former native-executable holder; allocator and shared-page accounting make this a range rather than a per-tab budget. The separate holder process is retained for certified crash isolation, and latency budgets were not raised to absorb Node startup.
|
|
168
168
|
- **Why the server relays surfaces instead of clients connecting to holders directly.** It gives one authenticated endpoint per client, one ordering domain for focus and topology, and simpler multi-client arbitration. Measure the extra local pipe hop in the native hot-path evidence rather than assuming its latency. The server forwards encoded holder surfaces and does not re-render them.
|
|
169
169
|
|
|
170
|
+
### Windows completion-driven transport and wake diagnosis
|
|
171
|
+
|
|
172
|
+
Windows server and client endpoints use overlapped named-pipe I/O. Each operation owns a stable `OVERLAPPED` and non-inherited completion event; read and write workers share handle custody but never serialize a pending read against a write. A worker waits for completion, connection shutdown, or an absolute admission deadline, not `PeekNamedPipe` plus a short sleep. The four-second first-envelope deadline covers fragmented headers and bodies. Cancellation targets one operation and drains its kernel completion before releasing its buffer/event; split-worker guards wake the other direction when the connection owner exits. Owner ACLs, first-instance protection, peer checks, frame limits, control ordering, and latest-surface bounds are unchanged. Unix socket behavior is unchanged.
|
|
173
|
+
|
|
174
|
+
Transport correctness does not rely on `timeBeginPeriod`. The existing per-role timer request remains for non-I/O timers, including ConPTY render-pass settling and animation/maintenance deadlines; removing it requires separate scheduling evidence. A detected attach gap still requests one complete cached repaint, never a process restart or prompt replay.
|
|
175
|
+
|
|
176
|
+
The existing opt-in progress route (`A1_RESIDENT_PROGRESS_OBSERVATION_DIR` plus `A1_RESIDENT_PROGRESS_RUN_ID`) adds `pipe-frame-read`, `pipe-write-complete`, `outer-write-complete`, `wake-gap`, and `wake-repaint-requested` stages. Connection-level records may omit tab identity. `durationUs` is local monotonic completion/assembly time; `idleWaitUs` separately describes waiting for the next frame and is not delivery latency. Native records include `monotonicUs`, `clockEpoch`, and optional `clockDiscontinuity`. Consumers exclude negative, epoch-crossing, and clock-discontinuity-crossing derived samples, while retaining valid local completion durations. The queue remains bounded and asynchronous, with loss accounting and no terminal content or credentials. Outer-write completion is not proof of physical pixels.
|
|
177
|
+
|
|
178
|
+
For recurring post-wake stalls, compare an existing resident client, a new client on the same resident host, and direct `a1 solo` in the same outer terminal. Use matched holder/attach revisions and local I/O durations to distinguish child progress, transport delay, and outer writes. If solo and other terminal applications also stall, do not assign the failure to resident pipes without further evidence. Simulated-gap fixtures do not certify physical sleep/wake recovery; do not automate workstation suspend. Updates retain old resident cohorts, so new endpoint code takes effect only as those roles reach their ordinary lifecycle or the maintainer explicitly chooses to stop them. Installing the update never recycles running tabs.
|
|
179
|
+
|
|
170
180
|
### 3. Host scope, endpoints, writer authority, and credentials
|
|
171
181
|
|
|
172
182
|
- There is **one server per OS user × canonical A1 profile root**, independent of the release cohort. Tabs must outlive release changes, and the supervisor is forbidden from retaining runtime processes.
|
|
@@ -250,7 +260,7 @@ Direct `a1 solo` is the behavioural oracle for every viewed resident child. Only
|
|
|
250
260
|
- **Modes and cursor.** Each surface carries the child's cursor cell and modes. Attach mirrors a cursor shape the child chose and resets it on detach or failure; a default block cursor is left to the outer terminal, as direct A1 leaves it.
|
|
251
261
|
- **Shortcut projection.** The owned child projects the effective A1 keybindings plus `keybindings.json` into one assignment per tab action: a key an A1 action holds never becomes a tab shortcut, and the earlier declaration keeps a duplicated key. It publishes the projection as `bridge.shortcuts`; the server relays it as `tabs.shortcuts`, and attach dispatches and labels exactly that projection. `/hotkeys` renders the same projection. A shared case file is replayed by both resolvers.
|
|
252
262
|
- **Committed presentation.** A requested view commits only with a topology that lists it and a complete target surface. Retained rows, palette/default colors, modes, and cursor are captured atomically; equal captures do not invent a revision. Surfaces of the committed view apply in revision order, and revisions rise across holder incarnations. A retained re-offer is marked stale from the request start and parks for at most 120 ms while the fresh frame arrives. One compositor writes strip, body, overlay, modes, and the viewport-clipped final cursor inside a single synchronized update. It erases suffix cells when a complete replacement row becomes shorter and restores the newest underlying surface when an overlay leaves. Clock, hover, and title-animation damage repaints only the strip and restores the child's cursor.
|
|
253
|
-
- **Evidence.** One interaction matrix drives three layers: an owned-shell oracle that records content-free observations, role fixtures that drive real server, holder, and attach processes with a certified parity child, and exact-artifact harnesses. `verify-interaction-parity.mjs` compares the bytes the same child observes directly and through the built host. `verify-resident-parallel-progress.mjs` configures the real engine against a bounded loopback streaming provider and crosses all six first-response orders with all three initial views while every turn remains unfinished behind a completion barrier. At matching 100×29 child geometry, the same real-A1 prompt also runs through isolated direct-solo and resident profiles; the native Ghostty oracle compares a content-free digest of the intermediate fixture cells and their resolved styles together with normalized cursor and mode state. It advances only at parser-reported synchronized-output boundaries, rejects unbalanced transactions or disappearing intermediate cells, and excludes only the resident strip row rather than normalizing terminal semantics. Opt-in per-process JSONL observations identify engine delivery, completed child writes, PTY ingestion, distinct holder commits, attach receipt, and completed outer paint by run/tab/incarnation/process-instance/sequence without recording terminal or conversation content; queue loss, clock faults, duplicates, stale order, and missing stages fail the report. Named pressure variants keep all turns unfinished while exercising hidden progress, repeated switching, navigation input, rename overlays, tab-local resize, a bounded 35 ms attach-receipt delay, and a 900 ms paused outer sink; every tab must retain partial animation/progress before settlement and then present its final output. A detached/reconnect variant releases all three unfinished turns after terminating the authenticated attach and exact self-reported server identity; child writes, PTY ingestion, and holder commits must continue before a replacement server and attach present every retained final output. Separate isolated exact-artifact control markers stop one target tab at engine delivery, physical child rendering, holder commit, or outer paint; each control requires its upstream stages and the other tabs to advance, then removes the stop and requires final output from all three tabs. A fifth control fragments a real owned-shell synchronized write into at most 64 physical writes without changing its bytes, records the DEC private mode 2026 transaction classification, and requires ordinary complete holder commits without deadline recovery before final output. This characterizes the built PTY/ConPTY coherence path; a passing fragmented run does not by itself assign the historical stall to that path without a failing live reproduction. The marker path is absent in ordinary sessions and is scrubbed before extensions or tools inherit the child environment, while observation callbacks remain passive and cannot select a control. CI runs the vendored Ghostty VT tests and both exact-artifact harnesses on Windows x64, Linux x64, and macOS arm64. Each platform's verdict stands alone.
|
|
263
|
+
- **Evidence.** One interaction matrix drives three layers: an owned-shell oracle that records content-free observations, role fixtures that drive real server, holder, and attach processes with a certified parity child, and exact-artifact harnesses. `verify-interaction-parity.mjs` compares the bytes the same child observes directly and through the built host. `verify-resident-parallel-progress.mjs` configures the real engine against a bounded loopback streaming provider and crosses all six first-response orders with all three initial views while every turn remains unfinished behind a completion barrier. At matching 100×29 child geometry, the same real-A1 prompt also runs through isolated direct-solo and resident profiles; the native Ghostty oracle compares a content-free digest of the intermediate fixture cells and their resolved styles together with normalized cursor and mode state. It advances only at parser-reported synchronized-output boundaries, rejects unbalanced transactions or disappearing intermediate cells, and excludes only the resident strip row rather than normalizing terminal semantics. Opt-in per-process JSONL observations identify engine delivery, completed child writes, PTY ingestion, distinct holder commits, attach receipt, and completed outer paint by run/tab/incarnation/process-instance/sequence without recording terminal or conversation content; queue loss, clock faults, duplicates, stale order, and missing stages fail the report. Named pressure variants keep all turns unfinished while exercising hidden progress, repeated switching, navigation input, rename overlays, tab-local resize, a bounded 35 ms attach-receipt delay, and a 900 ms paused outer sink; every tab must retain partial animation/progress before settlement and then present its final output. A detached/reconnect variant releases all three unfinished turns after terminating the authenticated attach and exact self-reported server identity; child writes, PTY ingestion, and holder commits must continue before a replacement server and attach present every retained final output. Separate isolated exact-artifact control markers stop one target tab at engine delivery, physical child rendering, holder commit, or outer paint; each control requires its upstream stages and the other tabs to advance, then removes the stop and requires final output from all three tabs. The outer-paint control waits for a payload-free `fixture-stop-ack` from the sole writer before starting its scenario; that acknowledgement follows all earlier writes, and same-writer sequence ordering excludes only pre-acknowledgement paints from the zero-progress check. Any later paint still fails. A fifth control fragments a real owned-shell synchronized write into at most 64 physical writes without changing its bytes, records the DEC private mode 2026 transaction classification, and requires ordinary complete holder commits without deadline recovery before final output. This characterizes the built PTY/ConPTY coherence path; a passing fragmented run does not by itself assign the historical stall to that path without a failing live reproduction. The marker path is absent in ordinary sessions and is scrubbed before extensions or tools inherit the child environment, while observation callbacks remain passive and cannot select a control. CI runs the vendored Ghostty VT tests and both exact-artifact harnesses on Windows x64, Linux x64, and macOS arm64. Each platform's verdict stands alone.
|
|
254
264
|
|
|
255
265
|
### 7. Status and attention come from the tab bridge
|
|
256
266
|
|
|
@@ -325,7 +335,7 @@ Tab status is an A1-owned state machine fed by `bridge.status`:
|
|
|
325
335
|
|
|
326
336
|
- **Strip.** Row 0, drawn by the attach client, reproduces the approved v2 default appearance:
|
|
327
337
|
- normal chips use RGB background `38,38,38` with foreground `170,170,170`, hover uses `48,48,48`, and the viewed chip uses `55,55,55` with white text, plus v2's palette fallback;
|
|
328
|
-
- the empty state
|
|
338
|
+
- the empty state keeps the hoverable `+` control and the clock beside the landing, with no cursor;
|
|
329
339
|
- chips are at most 20 columns, clipped with `…` by grapheme width, with no separators or close glyph;
|
|
330
340
|
- a `…` overflow menu holds tabs that do not fit, and `+` is always reserved;
|
|
331
341
|
- these presentation choices are fixed, not settings, while each working spinner uses that tab's reported A1 accent.
|
|
@@ -337,6 +347,8 @@ Tab status is an A1-owned state machine fed by `bridge.status`:
|
|
|
337
347
|
| `Alt+W` | close |
|
|
338
348
|
| `F2` | rename |
|
|
339
349
|
| `Alt+,` | open the global Settings tab, or close it while it is viewed |
|
|
350
|
+
| `Alt+/` | open the command palette, or close it while it is open |
|
|
351
|
+
| unbound (`tabs.changelog`) | open the Changelog tab |
|
|
340
352
|
| `Alt+1`…`Alt+9`, `Alt+0` | jump to a tab |
|
|
341
353
|
| unbound (`tabs.next` / `tabs.previous`) | next / previous, wrapping |
|
|
342
354
|
| unbound (`tabs.moveRight` / `tabs.moveLeft`) | move the tab right / left |
|
|
@@ -347,24 +359,32 @@ Tab status is an A1-owned state machine fed by `bridge.status`:
|
|
|
347
359
|
- **`Ctrl+C` twice leaves, in every tab (user decision).** The client forwards the first `Ctrl+C` to the tab unchanged, so a single press still clears, copies, or interrupts. It consumes the second press within the existing clear/exit interval as the detach request and does not forward it. The tab therefore never receives a second `Ctrl+C` from the chord, which removes v2's bug where `Ctrl+C+C` killed the agent. The trade-off: a future CLI tab cannot receive two quick `Ctrl+C`s. Pressing them more slowly than the interval still reaches the program.
|
|
348
360
|
- **Mouse on row 0:**
|
|
349
361
|
- click activates a tab;
|
|
350
|
-
- right-click opens `Rename`/`Close` (`Close` only for Settings);
|
|
362
|
+
- right-click opens `Rename`/`Close` (`Close` only for Settings and Changelog);
|
|
363
|
+
- right-click on `+` opens a one-row `Configure` menu that opens the `Plus Menu` dialog over the dimmed active tab, without switching tabs;
|
|
351
364
|
- dragging reorders, with a `│` drop marker, after 250 ms or once the pointer moves;
|
|
352
|
-
- `+` opens a persistent dark v2 menu
|
|
365
|
+
- `+` follows the plus menu: with only Agent enabled it adds an Agent at once; with other kinds it opens a persistent dark v2 menu of the enabled kinds, `+ Agent` first and a separator before the `Settings` and `Changelog` toggles, each `✓` while its tab is open; with none the strip hides `+`. Hover and click remain active through the opening release.
|
|
353
366
|
- **Settings.** The strip owns one profile-global `Settings` tab. The grouped launcher creates or activates it; `Alt+,` does the same from another tab and closes it while it is viewed. Esc does not close the Settings tab; closing the tab removes it. Resident Agent autocomplete omits `/settings`, and manually entering it does not open a per-Agent screen. `a1 solo` and `a1 pi` retain their existing Settings routes.
|
|
354
|
-
- **Commands inside A1 tabs:**
|
|
367
|
+
- **Commands inside A1 tabs:** a tab's name and its session's name stay in sync. a strip rename or an automatic name sets the session name through the bridge, and a session name set otherwise publishes the session view at once, so the tab takes it as a user name; and a resumed session's name becomes the tab name. An automatic name never replaces a user name. Resident Agents also omit and refuse `/changelog`, which opens as its own tab, and `/name`, since renaming the tab (`F2`) renames the session; direct A1 keeps both. Milestone 5 adds no tab-management slash commands: `/new-tab`, `/close`, `/tabs`, `/quit-all`, and `/restart-tab` are not exposed.
|
|
355
368
|
- **Naming:**
|
|
356
369
|
- Default names are `agent` or `agent N`.
|
|
357
370
|
- When `tabsAutoName` is on (the default, by user decision), the tab's model proposes a hyphenated lowercase name of at most 16 characters after the first settled turn. It uses a small budget and one retry, with a fallback derived from the first prompt, and it runs inside the child.
|
|
358
371
|
- A user rename sets `nameSource=user`, and auto-naming never overrides it.
|
|
359
372
|
- An automatic rename uses v2's title transition: 600 ms moving rainbow, typing at 45 ms per character, then a 300 ms settle. Manual renames do not animate.
|
|
360
373
|
- Rename is inline in the chip: `Enter` commits, `Esc` or a click elsewhere cancels, and `Ctrl+Left` / `Ctrl+Right` move by word. The name is trimmed, must not be empty, is at most 64 characters, and has control characters stripped.
|
|
361
|
-
- **
|
|
374
|
+
- **Plus menu.** The A1 setting `tabBarPlusMenu`, shown as `Plus menu` in the `Tab Bar` Settings section, holds the kinds `+` offers, Agent and every utility kind, as comma-joined keys in that order and defaults to `agent`. The `Plus Menu` dialog lists every kind with `●` when enabled and `○` when not under `Choose what the + button in the tab bar can add.`, with `Space` to toggle, Up and Down to move, typing to filter, and `Esc` to close. `+`'s `Configure` opens it in the attach client as a modal over the dimmed active tab or landing, built on the command palette's list and renderer, with a reversed white search caret like owned inputs. The Settings `configure` entry opens the same modal: the Settings child sends a `configure-plus` bridge request as the tab's controlling client, which the server forwards to that client as `plus.configure`; only without a bridge does Settings open its own equivalent dialog. Each toggle is written at once: the attach client takes the `settings.json.lock` directory lock the TypeScript writer takes through `proper-lockfile`, rereads the document, replaces only `a1.tabBarPlusMenu` (removed at the default), and renames a temporary file over it. A refused write restores the stored menu. The attach client reads the setting live, and with no kind enabled the strip hides `+`. Because a modal's overlay saves and restores the cursor while faint is active, the strip starts every frame from reset attributes, so no chip stays faint after a modal closes.
|
|
375
|
+
- **Command palette.** `Alt+/` (`tabs.commands`) opens a centered box over the whole frame in the owned list style: an accent `Commands` title, a `> ` search row, `Agent`, `Settings`, and `Changelog` with their effective shortcuts right-aligned, and a key hint. Typing or pasting filters it, Up and Down move, `Enter` runs the selected entry through its shortcut action, and `Esc` or `Alt+/` closes it; another tab shortcut closes it and runs. While it is open no key, paste, or pointer event reaches the strip or a child, the cursor is hidden, and the composer redraws the strip and body with faint re-asserted after every SGR beneath the bright overlay.
|
|
376
|
+
- **Changelog.** The changelog opens as a singleton `changelog-` utility tab titled `Changelog`, from the palette or the unbound `tabs.changelog` action. The tab registry accepts the `agent`, `settings`, and `changelog` kinds. Like Settings it is never renamed, offers only `Close`, is placed last, does not count as an Agent, and is prewarmed and hidden: the attach client starts it with `tab.prewarm-changelog` once Settings is ready, and again after a Changelog tab closes, so opening it shows the running tab at once. Like a hidden Settings tab, a hidden Changelog never takes the view when the viewed tab closes, so closing the last Agent shows the landing. Its screen is the tab: it shows no `Esc close` hint, and neither `Esc` nor one `Ctrl+C` closes it.
|
|
377
|
+
- **Utility tab rules.** Settings and Changelog are kinds in one table, `UtilityKind` in the attach core and `UTILITY_KINDS` on the server, and every rule follows the kind rather than a per-kind path: a kind's toggle shows a tab already in the strip in its slot, reveals a hidden or absent one through `tab.open-<kind>`, which the server answers by starting it or placing the running one last, and hides the viewed one while its process keeps running; the client prewarms each kind with `tab.prewarm-<kind>` once the kind before it runs; and a hidden one never takes the view when another tab closes. In the child, the route matching a resident tab's id is that tab's pinned screen. Adding a kind is a table entry, its prewarm state, and its route.
|
|
378
|
+
- **Reveal.** Opening a tab draws it at once: a created Agent and a revealed Settings or Changelog tab both keep the current content, another tab or the landing, until their first drawn frame commits, a retained blank surface included, and a tab that never draws shows after the bounded first-draw wait. Only a resize fades (`roles/reveal.rs`): once the curtain lifts, the whole frame draws faint for one fade interval with no cursor, then at full intensity. A starting chip shows no spinner. One tab opens at a time: new-Agent input while a tab the client asked for is starting or not yet shown starts nothing.
|
|
379
|
+
- **Rename selection.** The inline rename draws a selection on the prompt editor's selection background (RGB `38,79,120`, palette `24`) and keeps the chip's text color, restoring the chip's background after it; only the caret is a reversed cell.
|
|
380
|
+
- **Close.** `Alt+W` and the right-click menu close a tab directly, including while it is working. Closing removes the chip without a confirmation, stopping/read-only frame, or close glyph, then gracefully stops the child under the existing bounded termination policy. Its session stays resumable. Closing the last tab leaves `+` and the clock beside the landing.
|
|
381
|
+
- **Landing.** While the attach client has no tab to show, the attach role renders the a1 landing as the frame's body. The launch cwd sits where an Agent tab's footer shows it, flush left on the second-to-last body row with the same `~` formatting and `dim` color, so the folder does not move when a tab opens or closes; `v<version>`, read once from the release root's `package.json`, sits below it and the three-row half-block `a1` wordmark in the profile's accent above it (omitted in Apple Terminal). The accent colors are a native table pinned by `landing_accents.json`, which a TypeScript test checks against `derivePiAccentProjection`. The body is painted with the canvas `backgroundStyle` gives Agent tabs. The landing holds no input: tab shortcuts, the launcher, strip mouse, and double-`Ctrl+C` behave as with tabs, and no cursor shows. A hidden Settings tab is prewarmed and kept running beside the landing, as beside Agents, so Settings opens without a start; it closes when the client detaches, and an attach treats a registry holding only Settings as empty, so it starts and views its first Agent. Adding a tab from the landing keeps it until the tab's first drawn frame replaces it at once; the landing has no animation of its own.
|
|
362
382
|
- **Detach.**
|
|
363
383
|
- `Ctrl+C` twice detaches from any tab and is handled by the attach client, so it works even when the bridge is down. Inside an A1 tab, `/quit` and empty-editor `Ctrl+D` send a detach request carrying the immutable command-origin controller identity and revision; stale, ambiguous or unavailable attribution keeps the tab running and directs the user to `Ctrl+C` twice.
|
|
364
384
|
- The client restores the terminal. When agents are still running, it prints `1 agent still running run a1 to return.` or `N agents still running run a1 to return.`; otherwise it prints the resume hint.
|
|
365
385
|
- **Launch and reattach:**
|
|
366
386
|
- Bare `a1` ensures the server and attaches.
|
|
367
|
-
- With zero tabs, it creates one A1 tab in the launch cwd.
|
|
387
|
+
- With zero tabs, it creates one A1 tab in the launch cwd; a registry holding only the hidden Settings tab counts as zero.
|
|
368
388
|
- Otherwise it views the last active tab from its retained surface without byte-history replay. Every holder keeps draining its PTY and updating its retained terminal independently while hidden; selecting a working tab requests its newest complete partial-response surface immediately and then continues live delivery. Measure retained first paint and first input separately from bootstrap; status for the remaining tabs arrives without subscribing to their surfaces.
|
|
369
389
|
- `a1 --session X` opens X in a new tab, or focuses the tab holding it.
|
|
370
390
|
- A new tab's cwd is the client's launch cwd.
|
|
@@ -589,6 +609,14 @@ The user made these decisions on 2026-09-24:
|
|
|
589
609
|
- `Ctrl+C` twice leaves `a1` from any tab while tabs keep running. There is no separate detach key.
|
|
590
610
|
- Reliability is a first-class, release-gating requirement (Decision 16).
|
|
591
611
|
|
|
612
|
+
On 2026-10-24 the user refined the tab bar:
|
|
613
|
+
|
|
614
|
+
- `+` adds an Agent by default; what it offers, Agent, Settings, and Changelog, is configurable from a right-click `Configure` modal over the active tab and from `Tab Bar` › `Plus menu` in Settings, where the `Tabs` section is renamed `Tab Bar`. With nothing enabled, `+` is hidden.
|
|
615
|
+
- `Alt+/` opens a keyboard-only command palette over a dimmed frame: `Agent`, `Settings`, and `Changelog`.
|
|
616
|
+
- The changelog opens at once as its own prewarmed singleton tab that `Esc` does not close, and leaves resident Agents' commands.
|
|
617
|
+
- Opening a tab, a new Agent or a revealed Settings or Changelog tab, draws it at once when its first frame is drawn, with no fade and no starting spinner; the current content, landing included, stays until then. Only a resize fades. The landing's wipe animation is removed.
|
|
618
|
+
- The tab rename selection matches the editor's selection style, and a tab's name and its session's name stay in sync.
|
|
619
|
+
|
|
592
620
|
On 2026-10-16 the `ci-critical-path` change replaced the Intel runner for the release builds:
|
|
593
621
|
|
|
594
622
|
- The macOS x64 process guardian and terminal host are cross-compiled on the `macos-15` arm64 runner (`npm run build:terminal-host -- --target x86_64-apple-darwin`, same for the guardian) and uploaded beside the arm64 artifacts; the Intel runner took 6 to 11 minutes for builds the arm64 runner finishes in about 4, and it gated packing in every publication. The x64 executable's `--version` identity is read by executing it through Rosetta 2 when the runner can; otherwise the manifest records a Mach-O architecture check as `provenance.identityCheck: "mach-o-header"` instead of a report nobody observed. Intel macOS stays certified separately and its physical acceptance record is unchanged; no publication lane ran the x64 bytes beyond that identity check before either, because the published-pair smoke matrix has no Intel lane.
|
|
@@ -16,7 +16,7 @@ The source unit is from MIT-licensed repository <https://github.com/earendil-wor
|
|
|
16
16
|
|
|
17
17
|
One conversion is active per mounted tool. The waiting set is the newest current source set, not an unbounded queue of superseded snapshots. Hidden images and non-Kitty protocols do not start conversions. Work removed before codec entry is skipped. A public codec call already in progress cannot be cancelled; its eventual result is discarded if the source or mount is obsolete. This limitation is explicit, not claimed as cancellable worker execution.
|
|
18
18
|
|
|
19
|
-
Pending Kitty conversion has a visible `[Image converting: ...]` marker. Failure, rejection, or oversized converted bytes produces `[Image unavailable: ...]`, without exposing codec diagnostics or changing the operation outcome. Converted pixels never replace the original payload passed to extension renderers. PNG and iTerm presentation use the actual public `Image` component.
|
|
19
|
+
Pending Kitty conversion has a visible `[Image converting: ...]` marker. Failure, rejection, or oversized converted bytes produces `[Image unavailable: ...]`, without exposing codec diagnostics or changing the operation outcome. Converted pixels never replace the original payload passed to extension renderers. PNG and iTerm presentation use the actual public `Image` component. Explicitly hidden images retain pinned textual indicators. When image display is enabled but the terminal advertises no image protocol, bare A1 omits the non-actionable attachment fallback from user and tool transcript content; attachment bytes, metadata, model delivery, the explicit `a1 pi` route, and extension-owned image components remain unchanged.
|
|
20
20
|
|
|
21
21
|
Rebuild/disposal releases image ownership and invalidates the previous mount. Reentrant renderer invalidation is suppressed during synchronous reconstruction; valid asynchronous callbacks still request the existing scheduler and update presentation revision, not semantic revision.
|
|
22
22
|
|
|
@@ -31,6 +31,7 @@ This correction does not introduce an ANSI parser, change link detection, relax
|
|
|
31
31
|
- `transcript-image-conversion.test.ts`: independent pinned stale-cache baseline, JPEG replacement, PNG replacement, hidden/non-Kitty parity, failed-conversion fallback and real scheduled Kitty publication at unchanged semantic revision.
|
|
32
32
|
- `tool-image-presentation.test.ts`: current-source sharing, one active conversion, superseded bursts, removed/disposed callbacks, hidden/iTerm work avoidance, rejection and size fallback without retry loops.
|
|
33
33
|
- `tool-shell-parity.test.ts`: independent actual pinned read/bash/edit/write/grep/find/ls and generic rendering at widths 40/80/192, partial/final/error states, expansion, binary text, and extension default/self shells with original inputs and stable renderer state.
|
|
34
|
+
- `shell-components.test.ts`: unsupported user and tool transcript images produce no fallback row or spacer, while explicit hiding and capable-terminal unavailable diagnostics remain visible.
|
|
34
35
|
- Existing attachment-ownership, payload-limit, content-retention and shell tests remain non-regression gates. The wrapped-URL counterexample remains explicitly unresolved under issue #353.
|
|
35
36
|
|
|
36
37
|
These are automated content and ownership checks, not Windows Terminal visual acceptance. The broader change stays open until scheduled-producer evidence, required CI, and exact-candidate user review satisfy its remaining tasks.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Persistent prompt history
|
|
2
2
|
|
|
3
|
-
Bare A1 recalls recent prompts
|
|
4
|
-
|
|
3
|
+
Bare A1 recalls recent prompts within each agent session, including when that
|
|
4
|
+
session resumes. The optional Shared scope recalls prompts across agent sessions
|
|
5
|
+
and projects in the same A1 profile. It is input recall, not conversation recovery or agent memory. The Pi
|
|
5
6
|
comparison (`a1 pi`) retains its ordinary current-session history.
|
|
6
7
|
|
|
7
8
|
## Recall
|
|
@@ -36,16 +37,21 @@ imported automatically.
|
|
|
36
37
|
|
|
37
38
|
| Platform | Default durable location |
|
|
38
39
|
|---|---|
|
|
39
|
-
| Windows | `%USERPROFILE%/.a1/data/history/<
|
|
40
|
-
| Linux and macOS | `~/.a1/data/history/<
|
|
41
|
-
| Explicit override | `<A1_DATA_DIR>/history/<
|
|
40
|
+
| Windows | `%USERPROFILE%/.a1/data/history/<history-id>.sqlite3` |
|
|
41
|
+
| Linux and macOS | `~/.a1/data/history/<history-id>.sqlite3` |
|
|
42
|
+
| Explicit override | `<A1_DATA_DIR>/history/<history-id>.sqlite3` |
|
|
42
43
|
|
|
43
44
|
The default uses A1's effective profile home: `A1_PROFILE_HOME` when set, otherwise
|
|
44
45
|
the operating-system home. A custom agent-profile directory changes the history
|
|
45
46
|
identity, not this default root. `A1_DATA_DIR` takes precedence for storage;
|
|
46
47
|
`XDG_DATA_HOME` does not redirect default history. Control metadata, settings,
|
|
47
48
|
agent resources, releases, logs, runtime files, and caches keep their existing
|
|
48
|
-
locations.
|
|
49
|
+
locations. For repository-local `./scripts/dev` launches, history uses a stable
|
|
50
|
+
checkout-wide data root so two independent solo instances share the selected
|
|
51
|
+
Shared database, while control and runtime data remain isolated per launch.
|
|
52
|
+
The development-only `A1_DEV_HISTORY_DATA_DIR` selects that root; an explicit
|
|
53
|
+
`A1_DATA_DIR` still overrides its launcher default. Existing histories in old
|
|
54
|
+
per-instance development roots are not moved or combined.
|
|
49
55
|
|
|
50
56
|
**The home-based default starts fresh.** Previous versions used
|
|
51
57
|
`%LOCALAPPDATA%/a1/history` on Windows, or `$XDG_DATA_HOME/a1/history` /
|
|
@@ -53,12 +59,15 @@ locations.
|
|
|
53
59
|
fall back to those stores. Explicit `A1_DATA_DIR` selections still work normally.
|
|
54
60
|
Old and new releases using different roots do not synchronize history.
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
In Shared mode the filename is the original `a1-` SHA-256 profile identity,
|
|
63
|
+
independent of project, session, checkout, and release. In Unique mode (the
|
|
64
|
+
default), a domain-separated digest also includes the stable conversation session
|
|
65
|
+
ID; two solo launches or resident tabs therefore use different databases and
|
|
66
|
+
image sidecars. Resuming the same session reuses its store; starting or forking a
|
|
67
|
+
session selects a different one. Windows ordinary case and separator variants
|
|
68
|
+
normalize together. Moving a profile, unresolved symlink aliases, or selecting a
|
|
69
|
+
different data root can select a different history; A1 never silently merges or
|
|
70
|
+
imports it.
|
|
62
71
|
|
|
63
72
|
The database is separate from `control.sqlite3`, agent resources, and disposable
|
|
64
73
|
caches. Upgrades, ordinary npm uninstall/reinstall, release rollback, cache cleanup,
|
|
@@ -79,11 +88,19 @@ must not appear in history diagnostics or test evidence.
|
|
|
79
88
|
The History section in `/settings` provides:
|
|
80
89
|
|
|
81
90
|
- **Persistent history:** on by default; applies on the next start. Off disables
|
|
82
|
-
storage and
|
|
91
|
+
storage and durable recall for subsequent launches, not current-session
|
|
83
92
|
recovery. Existing enabled instances keep running until closed.
|
|
93
|
+
- **History scope:** Unique (default) keeps each agent session's durable prompts
|
|
94
|
+
separate across solo launches and resident tabs. Shared restores the former
|
|
95
|
+
profile-wide store. Switching applies to running agents, including other solo
|
|
96
|
+
processes and resident tabs, when their shared settings update arrives. New
|
|
97
|
+
prompts use the newly selected store; already-submitted writes finish in their
|
|
98
|
+
original store. Switching never transfers or deletes records, and it preserves
|
|
99
|
+
unsent drafts. Existing profiles without this setting default to Unique, so
|
|
100
|
+
old Shared entries remain intact but do not appear until Shared is selected.
|
|
84
101
|
- **History limit:** 10-100 in increments of 10, default 100; applies when a new
|
|
85
|
-
enabled instance starts. All writers
|
|
86
|
-
retention limit. Raising the limit cannot restore pruned entries.
|
|
102
|
+
enabled instance starts. All writers using that selected store then use its
|
|
103
|
+
updated retention limit. Raising the limit cannot restore pruned entries.
|
|
87
104
|
|
|
88
105
|
The settings use A1's existing settings document, not Pi's settings or a separate
|
|
89
106
|
history configuration file. Disabling persistence does not delete saved data;
|
|
@@ -134,14 +151,18 @@ placed beside history. For a history-only review, `NODE_DISABLE_COMPILE_CACHE=1`
|
|
|
134
151
|
also avoids creating compile-cache files under that explicitly overridden root.
|
|
135
152
|
The focused path/composition tests cover normal no-override selection. Test:
|
|
136
153
|
|
|
137
|
-
1. Submit two text prompts and one repeated prompt;
|
|
138
|
-
|
|
154
|
+
1. Submit two text prompts and one repeated prompt; resume the same session
|
|
155
|
+
after restart and check those prompts remain recallable. Start `/new` and
|
|
156
|
+
confirm its durable history is separate.
|
|
139
157
|
2. Browse multiline input with a draft present. Check v2 caret placement,
|
|
140
158
|
newest/oldest numbering, and draft restoration.
|
|
141
|
-
3. Submit from a second instance while the first browses.
|
|
142
|
-
|
|
159
|
+
3. Submit from a second instance while the first browses. Under Unique, the
|
|
160
|
+
first sees no cross-agent update. Switch to Shared without restarting; once
|
|
161
|
+
both agents apply the setting, the second instance's new prompt appears in
|
|
162
|
+
the first agent's shared history. Switching back restores each Unique store.
|
|
143
163
|
4. Recall pasted text after restart; image tokens must not promise reattachment.
|
|
144
|
-
5. Save
|
|
164
|
+
5. Save History scope and verify its immediate effective value. Restart only
|
|
165
|
+
for changes to Persistent history or History limit.
|
|
145
166
|
6. Use a second isolated effective profile and verify no sharing. Run
|
|
146
167
|
`./scripts/dev pi` and verify its ordinary history/editor remain unchanged.
|
|
147
168
|
|
package/package.json
CHANGED