@staix/agent-hub 0.12.26 → 0.12.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  Issue and pull request numbers in the entries for 0.7.7 and earlier refer to the previous repository, archived on 2026-09-30 when this repository's history was rewritten; the one exception is the open smoke-check issue, formerly #12, which moved here as #1. Numbers in newer entries refer to this repository.
4
4
 
5
+ ## 0.12.27
6
+
7
+ - Refine the dashboard Office view with an intrinsic 12 px/unit scale, 1 px non-scaling hairlines and padded room cards in flat and isometric themes, and un-nest the desk More control into a separately reconciled sibling button so screen readers can reach it (#394).
8
+ - Shrink the floating pet window to a compact 150x150 panel with the original pixel art in deeper state colors and a configurable base palette (`pet.palette`, or 1/2/3/4 while the window is key: blue, teal, violet, ochre) with a matching rim line so it reads on light backgrounds, reveal the status pill and message composer only while the pointer is over the character, and drop the pill shadow (#391 follow-up).
9
+ - Split the local dashboard into cookie-backed views, compact task cards with shared dialog/column details, and exact-id attention badges; move character presentation to the standalone pet window (#391 Task A).
10
+ - Add an opt-in macOS floating pet window with built-in pixels, counts-only local state, a console message pencil, saved position and signed process ownership; keep terminal pet reads available to agent shells (#391 Task B).
11
+
5
12
  ## 0.12.26
6
13
 
7
14
  - Import claude-mem observations under a checkout-independent identity, so the same observation is one entry on every machine after sync however the checkouts differ; scan the source database project-aware with a persisted machine-local cursor (`--restart` re-scans), so unrelated projects cannot starve the requested one; reconcile legacy duplicate imports with `ahub memory dedupe` through append-only supersede operations (#380).
package/README.md CHANGED
@@ -4,7 +4,7 @@ Native multi-agent hub for one developer's machine: Claude Code, Codex, Kimi Cod
4
4
  hub-owned local-LLM worker, with optional Qwen Code and Jcode support, collaborate as peers in independent project directories, with
5
5
  task-aware model routing (Switchyard) in front of a self-hosted gateway (OmniRoute).
6
6
 
7
- Status: 0.12.26, control protocol 16. Durable delivery records distinguish queued
7
+ Status: 0.12.27, control protocol 16. Durable delivery records distinguish queued
8
8
  work from uncertain execution. The [smoke checklist](docs/smoke.md) records
9
9
  verified paths and remaining prerequisites.
10
10
 
@@ -33,7 +33,7 @@ cd <your project> && ahub init && ahub up
33
33
  Or install the same version from GitHub:
34
34
 
35
35
  ```bash
36
- bun add -g github:STAIxBWLB/agent-hub#v0.12.26 && ahub setup
36
+ bun add -g github:STAIxBWLB/agent-hub#v0.12.27 && ahub setup
37
37
  ```
38
38
 
39
39
  The installed commands remain `ahub` and `agent-hub`.
@@ -1,6 +1,6 @@
1
1
  # Operations guide
2
2
 
3
- This guide describes ahub 0.12.26 and control protocol 16. Live verification
3
+ This guide describes ahub 0.12.27 and control protocol 16. Live verification
4
4
  results and remaining prerequisites are recorded separately in [the smoke ledger](smoke.md).
5
5
 
6
6
  ## Command output
@@ -156,8 +156,8 @@ status read it says loading; later failures preserve the prior count with a noti
156
156
  Panels retain their existing full-board refresh and loading/error handling.
157
157
 
158
158
  The dashboard Task board shows the same shared public-board progress model,
159
- including state counts, waiting, stacked segments and a labeled four-stage track
160
- per row. Filtering rows does not filter overall progress. The existing signature guard
159
+ including overall state counts, waiting and stacked segments; each task detail
160
+ retains its labeled four-stage track. Filtering rows does not filter overall progress. The existing signature guard
161
161
  updates the live region only when progress changes. The stacked SVG fills the
162
162
  section width; its text legend carries every state count. Theme offers System,
163
163
  Light and Dark; it is applied before first paint and stored in a host-scoped loopback cookie
@@ -170,8 +170,8 @@ is tracked in `docs/smoke.md` and remains unverified until performed.
170
170
  The dashboard Office section (#264, phase 1 of 4) draws the same snapshot as a
171
171
  static flat office: one desk per peer in a stable slot (claude, codex, kimi, pi,
172
172
  local, then others by id; a peer going offline dims its desk and never moves
173
- another), rooms for the board columns in a fixed order (To Do, Work floor,
174
- Review, Done shelf as a count only), at most 8 cards per room with "+N more"
173
+ another), rooms for the board columns in a fixed order (To do, Work floor,
174
+ Review, Done as a count only), at most 8 cards per room with "+N more"
175
175
  filtering the task list to that state, and at most 12 desks with "+N peers".
176
176
  Work-floor cards sit at the owner's desk, marked for rework; a busy peer's task
177
177
  bubble names its task only when it has exactly one in progress. Every peer
@@ -1619,21 +1619,21 @@ section is what they run.
1619
1619
 
1620
1620
  Upgrade running projects with the target release's own coordinator. It accepts
1621
1621
  a running source on control protocol 9 (0.6.x), 10 (0.7.0 through 0.12.0),
1622
- 11 (0.12.1 and 0.12.2), 12 (0.12.3), 13 (0.12.4 through 0.12.15), 14 (0.12.16), 15 (0.12.17 through 0.12.19) or 16 (0.12.20 through 0.12.26), and only
1622
+ 11 (0.12.1 and 0.12.2), 12 (0.12.3), 13 (0.12.4 through 0.12.15), 14 (0.12.16), 15 (0.12.17 through 0.12.19) or 16 (0.12.20 through 0.12.27), and only
1623
1623
  a target on its own protocol, so the target's coordinator fits every supported
1624
1624
  source and carries every recovery fix released up to it. Protocol 8 and older
1625
1625
  (0.5.x and earlier) are refused as `manual-bootstrap-required`. Run from the
1626
1626
  project directory, without replacing the global CLI first:
1627
1627
 
1628
1628
  ```bash
1629
- bunx --package @staix/agent-hub@0.12.26 ahub upgrade --to 0.12.26 --dry-run
1630
- bunx --package @staix/agent-hub@0.12.26 ahub upgrade --to 0.12.26 --yes
1629
+ bunx --package @staix/agent-hub@0.12.27 ahub upgrade --to 0.12.27 --dry-run
1630
+ bunx --package @staix/agent-hub@0.12.27 ahub upgrade --to 0.12.27 --yes
1631
1631
  ```
1632
1632
 
1633
1633
  | Running now | Coordinator to use |
1634
1634
  | --- | --- |
1635
1635
  | 0.6.x (protocol 9) | the target's, through `bunx` as above |
1636
- | 0.7.0 through 0.12.0 (protocol 10), 0.12.1 and 0.12.2 (protocol 11), 0.12.3 (protocol 12), 0.12.4 through 0.12.15 (protocol 13), 0.12.16 (protocol 14), 0.12.17 through 0.12.19 (protocol 15), 0.12.20 through 0.12.26 (protocol 16) | the target's, through `bunx` as above |
1636
+ | 0.7.0 through 0.12.0 (protocol 10), 0.12.1 and 0.12.2 (protocol 11), 0.12.3 (protocol 12), 0.12.4 through 0.12.15 (protocol 13), 0.12.16 (protocol 14), 0.12.17 through 0.12.19 (protocol 15), 0.12.20 through 0.12.27 (protocol 16) | the target's, through `bunx` as above |
1637
1637
  | any supported source, with the installed CLI already at the target | `ahub upgrade` below, which is the same coordinator |
1638
1638
  | 0.5.x or earlier (protocol 8 and older) | not supported: bootstrap by hand with the matching CLI |
1639
1639
 
@@ -1665,14 +1665,14 @@ projects first:
1665
1665
 
1666
1666
  ```bash
1667
1667
  ahub restart --dry-run
1668
- ahub upgrade --to 0.12.26 --dry-run
1668
+ ahub upgrade --to 0.12.27 --dry-run
1669
1669
  ```
1670
1670
 
1671
1671
  Apply only after reviewing the plan:
1672
1672
 
1673
1673
  ```bash
1674
1674
  ahub restart --yes
1675
- ahub upgrade --to 0.12.26 --yes
1675
+ ahub upgrade --to 0.12.27 --yes
1676
1676
  ahub recovery status [<operation-id>]
1677
1677
  ahub recovery resume [<operation-id>]
1678
1678
  ahub recovery abort [<operation-id>]
@@ -2879,20 +2879,36 @@ nor drawing a character changes authority, config files, task state or polling.
2879
2879
  Explicit `ahub pet` and text status use the configured line face; prompt tokens
2880
2880
  remain character-independent. Native glyph width and tmux are unverified.
2881
2881
 
2882
- ## Dashboard attention character (#280)
2882
+ ## Dashboard views and attention (#391, replaces the #280 in-page character)
2883
+
2884
+ Top buttons select Board, Office, Stream, Agents, Message, Memory or Settings
2885
+ within the same page. The selected view and board column focus use the shared
2886
+ host-scoped cookie helper; the URL fragment remains reserved for the session
2887
+ ticket. Sections are hidden rather than fetched separately. Projects and
2888
+ Benchmarks live under Agents alongside peers, approvals and usage budgets.
2889
+ Office mode stays an explicit Off/Flat/Isometric preference inside Office.
2890
+
2891
+ Board cards show id/title, priority, owner dot and overdue/check markers.
2892
+ Click or Enter opens a native detail dialog with the full stage/dependency,
2893
+ release/date, SDLC, detail and GitHub content plus existing Pull/Return/Assign
2894
+ controls. Snapshot changes refresh the dialog; project reset or a task leaving
2895
+ the snapshot closes it. Expand on a column shows one wide list of full details;
2896
+ Back returns to compact cards. State/agent/release filters still apply.
2897
+
2898
+ The shared pure needs model now drives the nav attention badge and existing
2899
+ action-count tab title. Agents has a live pending-approval count even when
2900
+ attention metadata is unavailable. Activation switches to the matching view
2901
+ and focuses only the exact visible approval/task id; missing or filtered rows
2902
+ receive fixed structural guidance, with no peer or first-row fallback. No
2903
+ workflow action is issued and no filter is changed by attention navigation.
2904
+ Invalid/legacy attention hides its badge and restores the base title.
2905
+
2906
+ The in-page pet, its SVG and character/pixel payload are removed. The standalone
2907
+ macOS window owns character presentation. Existing snapshot poll, session,
2908
+ request types and CSP hashes remain; no route, request or timer is added.
2909
+ Browser screenshots/CSP-console verification are separate manual evidence on
2910
+ the implementation PR; VM/HTTP fixtures do not establish human visual results.
2883
2911
 
2884
- The dashboard header draws the configured built-in character independently of
2885
- Office. It uses the same structural needs model as status and the console. The
2886
- accessible button names the character, state and action/watch counts; the tab
2887
- title shows the action count. Activating the button scrolls and focuses the exact
2888
- visible approval/task/peer row, or its related section with fixed id-only guidance
2889
- when the row is filtered or unavailable. It performs no action and changes no
2890
- filters. Legacy snapshots without attention keep the widget hidden.
2891
-
2892
- Only a live approval alternates the two waiting poses once per second through
2893
- CSS. `pet.blink:false` and reduced motion retain a static pose. No new timer,
2894
- request, image protocol or character-file load is added. Project reset clears
2895
- the widget and title. Native/browser visual validation remains unverified.
2896
2912
  With mini/full characters, active console notices remain visible away from the
2897
2913
  character: panel body rows show the bounded wrapped notice, and stream mode
2898
2914
  prints each fresh notice once through the existing local stream. Footer prose
@@ -2943,3 +2959,43 @@ A later issue lookup or profile-preparation failure also returns the IDs confirm
2943
2959
  Release cut audits return exact counts with at most 32 example IDs per category; the dashboard states how many IDs are shown when truncated. Scope grouping and indexed approval dates avoid scanning each task history for every release. Full audit pagination remains a future extension.
2944
2960
 
2945
2961
  Release cards include task states in their refresh key, so completion of an outside prerequisite updates blocked counts even when the release and audit preview are unchanged.
2962
+
2963
+ ## Standalone macOS pet window (#391)
2964
+
2965
+ From a person's terminal, `ahub pet --window` starts one floating, transparent
2966
+ JXA panel per project; `ahub pet --window --close` closes it. Other platforms
2967
+ print unsupported and retain `ahub pet` / `ahub pet --short`. An agent-marked
2968
+ shell may read the terminal pet but cannot start or close the window.
2969
+
2970
+ Set `pet.window: true` in `.agenthub/config.json` or `config.local.json` to start
2971
+ it with `ahub up`. A window-only local opt-in preserves inherited `pet:false`
2972
+ for terminal/status/dashboard presentation; explicit local character options
2973
+ retain their existing presentation override behavior. The
2974
+ window uses the configured built-in character, full pixel frame and blink
2975
+ choice. Its body opens `ahub ui`; the pencil opens an inline console message
2976
+ box (Enter sends through `ahub say`, Esc cancels). Drag the body to move it;
2977
+ `pet-window-pos.json` remembers the position, with an on-screen fallback if a
2978
+ saved display has disappeared. The panel joins all Spaces without a Dock icon.
2979
+ The 150x150 panel keeps the status pill and message composer hidden until the
2980
+ pointer is over the character. Deep state colors and a dark rim shadow keep the
2981
+ pixel silhouette readable on light backgrounds. `pet.palette` selects the base
2982
+ color: teal (default, b), blue (a), violet (c) or ochre (d), each with its own
2983
+ rim line; the waiting/blocked/review/offline colors stay fixed. While the
2984
+ window is key, 1/2/3/4 switch blue/teal/violet/ochre and save the choice.
2985
+ From a terminal, `ahub pet --palette <blue|teal|violet|ochre>` writes the
2986
+ choice to `pet.palette` in `.agenthub/config.local.json`.
2987
+ While working, the pixel art bobs in a 0.7-second stepped CSS loop; reduced-motion preferences keep it still.
2988
+
2989
+ A detached Bun host refreshes `pet-view.json` once per second using `readPet`
2990
+ and `loadPetConfig`. The file contains only state/counts/character/blink and
2991
+ built-in pixels. It uses no dashboard session or HTTP listener. An unavailable
2992
+ hub displays Offline for two seconds, then the panel and host exit. Closing
2993
+ JXA exits the host too. `pet-window.pid` holds the host's process signature;
2994
+ an uncertain owner is retained rather than signalled. A stale owner requires
2995
+ an explicit `--close` before restarting; a malformed pidfile requires operator
2996
+ inspection. A send failure is unconfirmed: check the stream before retrying.
2997
+
2998
+ Native transparency/floating and the bridge were verified in the macOS spike.
2999
+ Real keystrokes, dragging and persistence, Spaces, message delivery and body
3000
+ click need the manual PR checklist before merge; automated fixtures do not
3001
+ establish those native results.
@@ -17,7 +17,7 @@ ahub setup # installs the Claude Code channel plu
17
17
  Or use the matching GitHub release:
18
18
 
19
19
  ```bash
20
- bun add -g github:STAIxBWLB/agent-hub#v0.12.26
20
+ bun add -g github:STAIxBWLB/agent-hub#v0.12.27
21
21
  ahub setup
22
22
  ```
23
23
 
package/docs/security.md CHANGED
@@ -109,7 +109,7 @@ Please report vulnerabilities privately through GitHub's "Report a vulnerability
109
109
 
110
110
  - `ahub ui` uses the authenticated console control connection to start an ephemeral HTTP listener on `127.0.0.1`. No UI listener exists before that command. The control and Codex proxy ports continue to refuse every `Origin` header.
111
111
  - The daemon issues a cryptographically random, single-use bootstrap ticket valid for 60 seconds. The CLI opens the dashboard with that ticket in the URL fragment, never a query string or the control token. The static page removes the fragment immediately and exchanges it with a same-origin POST. Tickets are consumed once; expired tickets cannot create sessions.
112
- - The exchange creates a separate random session, valid for one hour without renewal, in an `HttpOnly; SameSite=Strict; Path=/` cookie named for this listener's port. Sessions and tickets live only in memory and die with the daemon. The page itself keeps one more cookie, `agent-hub-theme` (issue #246): script-set, `SameSite=Strict`, kept for a year for the whole `127.0.0.1` host, and read back only as one of `system`, `light` or `dark`. A second script-set cookie, `agent-hub-office` (issue #264), keeps the Office view choice under the same attributes and is read back only as `off`, `flat` or `isometric`. HTTP is loopback-only; the cookie is not a substitute for the origin checks.
112
+ - The exchange creates a separate random session, valid for one hour without renewal, in an `HttpOnly; SameSite=Strict; Path=/` cookie named for this listener's port. Sessions and tickets live only in memory and die with the daemon. The page itself keeps one more cookie, `agent-hub-theme` (issue #246): script-set, `SameSite=Strict`, kept for a year for the whole `127.0.0.1` host, and read back only as one of `system`, `light` or `dark`. A second script-set cookie, `agent-hub-office` (issue #264), keeps the Office view choice under the same attributes and is read back only as `off`, `flat` or `isometric`. The #391 view split adds two more script-set cookies under the same attributes: `agent-hub-view`, read back only as one of the seven view names, and `agent-hub-column-focus`, read back only as one of the five board columns or empty. HTTP is loopback-only; the cookie is not a substitute for the origin checks.
113
113
  - Every request must have the exact listener Host. Every data or action request, including the ticket exchange and snapshot polling, must be POST with the exact listener Origin and JSON content type. Foreign and missing origins, missing or expired sessions, oversized bodies and unknown actions are rejected. There is no CORS support. The only unauthenticated GET is the fixed, data-free HTML shell. No files or paths are served dynamically.
114
114
  - Responses are non-cacheable, cannot be framed, suppress referrers, and use a content security policy restricting scripts/styles to the shipped inline content and connections to this origin. Browser text is rendered with textContent, never interpreted as HTML.
115
115
  - The browser receives a bounded redacted event stream, peer states and queue counts, public task views, budget windows, pending approvals, the settings rows (closed values and ids, the file each comes from) and each startable peer's start plan (issue #269), benchmark run summaries (issue #251): the newest runs in `~/.agenthub/bench/`, whichever project on this machine ran them, by suite name, arm label, state, the task id in progress, counts, tokens and times, never suite text, and the office view's optional fields (issue #264): each peer's open turn (start time, attributed task id, attribution kind), a `checking` flag on tasks whose check is running, and warning `links` of overlapping, conflicting or cohort tasks (task and peer ids only, never paths, symbols or reasons; a PII task never joins a link, and a private or PII-attributed turn exposes no task id). Private envelope bodies and PII task text never cross this endpoint. Local-worker and Pi approval titles can contain PII, so their details remain terminal-only; the dashboard identifies the request and directs the operator to `ahub tail` before allowing it. Budget checkpoint summaries are also omitted.
@@ -226,11 +226,14 @@ owner/reviewer ids, approval ids and numeric times, peer delivery states and
226
226
  budget pause times. It is assembled from the same allowlisted input as status;
227
227
  task text, plans, approval prose, error text and paths are excluded. This input
228
228
  is supplied only inside console-authorized dashboard snapshots, never ordinary
229
- status replies or status.json. The pet creates trusted inline SVG pixel nodes
230
- from built-in literal frames with existing theme colours, without HTML insertion,
231
- inline handlers, style attributes or external assets. Existing CSP hashing,
232
- headers, origin and session authorization remain in force. Clicking scrolls and
233
- focuses only; it cannot grant permissions or invoke a mutation.
229
+ status replies or status.json. The #391 dashboard projects this input into nav
230
+ and tab-title counts; the in-page pet and its character/pixel injection are gone.
231
+ Attention navigation switches a local view and focuses an exact visible row id,
232
+ with structural guidance when missing. It cannot grant permissions or invoke a
233
+ mutation. Compact-card detail/dialog controls retain the existing authenticated
234
+ workflow actions and project/instance fencing. Existing CSP hashing, headers,
235
+ origin and session authorization remain in force; data uses text/DOM nodes,
236
+ without HTML insertion, inline handlers or external assets.
234
237
 
235
238
 
236
239
  ## Hub-owned structured memory (#258)
@@ -251,3 +254,28 @@ refused; unknown visibility proceeds with a warning for the configured remote.
251
254
  Short-term segments, machine identity and the derived index are excluded from
252
255
  sync. Suggested graph edges are off by default and are not evidence until a
253
256
  person confirms them. Operational details and limits: [hub memory](memory.md).
257
+
258
+ ## Standalone pet window (#391)
259
+
260
+ The macOS window reads local files only. Its detached host reuses `readPet`,
261
+ including signed-daemon liveness and recovery-lock handling, and publishes an
262
+ atomic counts-only `pet-view.json` (state, act/watch, known character, blink,
263
+ palette from the closed list, built-in pixel frame). It excludes item ids,
264
+ task titles/text, refs, paths,
265
+ notices and approval prose. Missing or unconfirmed status produces only
266
+ `{offline:true}`. Process and position files are separate from this view.
267
+
268
+ The local WKWebView has a deny-by-default CSP, with only its shipped inline
269
+ script/style allowed and network connections forbidden. Text never becomes
270
+ HTML or executable source. The retained JXA bridge accepts fixed drag/send/
271
+ palette/open/close operations; `NSTask` invokes the host-supplied Bun/CLI/project argv
272
+ and appends `say`, `--` and a single message argument, or `pet`, `--palette`
273
+ and one closed palette name. It does not evaluate a
274
+ shell string. Message text is never logged by the window/host; command stdout
275
+ and stderr go to the null device. `ahub say` keeps its existing console-message
276
+ authority and recording behavior, and `ahub ui` opens its existing session.
277
+ The CLI restricts `pet --window` (including close) to console identity, while
278
+ plain terminal pet reads and `pet --palette` remain available to agent shells;
279
+ the palette write merges only the closed name into `.agenthub/config.local.json`,
280
+ validated and replaced by temp file and rename. Signed pidfiles
281
+ fence instance ownership and close; unknown owners are never signalled.
@@ -710,7 +710,11 @@ fragment ticket for an HttpOnly, SameSite=Strict browser session. The control li
710
710
  retains its blanket Origin refusal. The browser receives no control token.
711
711
 
712
712
  One static HTML file, without a build step or runtime dependency, polls public
713
- snapshots once per second. The latest 200 redacted bus events are retained only
713
+ snapshots once per second. #391 Task A keeps this `/` surface and poll while
714
+ splitting its sections into Board/Office/Stream/Agents/Message/Memory/Settings
715
+ views with a cookie-backed selection. Compact task cards open a native dialog;
716
+ one `taskDetail` function renders both the dialog and expanded-column cards.
717
+ Filters, exact-id attention navigation and existing workflow controls remain. The latest 200 redacted bus events are retained only
714
718
  once the listener starts. The API exposes only permission answers, peer
715
719
  pause/resume, console messages, task proposal and assignment. All task changes
716
720
  use `Tasks`; budget pauses keep the terminal's override requirement.
@@ -731,7 +735,9 @@ project registry and adds explicit project selection, authenticated instance
731
735
  ownership and a separate optional dashboard manager. Runtime data and routing
732
736
  remain per project. Native memory aliases remain compatible and shared.
733
737
  Control protocol 7 adds project/instance identity and console-only dashboard
734
- snapshot/action forwarding. Existing project-local UI security rules still apply.
738
+ snapshot/action forwarding. Existing project-local UI security rules still apply. #391 Task A changes only client view selection;
739
+ project/instance fencing still invalidates open task details and stale controls.
740
+ No additional project route, request or timer is introduced.
735
741
 
736
742
 
737
743
  ## Amendment: externally managed Ollama MLX (issue #51)
@@ -2678,21 +2684,21 @@ C/dumb/linux/unknown locale surfaces use ASCII even when blocks were requested.
2678
2684
  Body foreground is uncoloured; only the Gyul leaf uses an existing accent tone.
2679
2685
  Native terminal/font/tmux proof remains a separate verification leg.
2680
2686
 
2681
- ## Shared dashboard attention (#280, phase 4)
2687
+ ## Shared dashboard attention (#280, replaced by #391 Task A)
2682
2688
 
2683
- The existing authenticated UI snapshot receives an optional allowlisted attention
2684
- input and enabled/character/blink presentation fields. Status wire/file callers
2685
- retain their phase3 summary/items projection and never receive this input. The
2686
- page invokes the same injected needs function on this body-free input, renders
2687
- the selected built-in full block frame as SVG pixels and exposes state/counts
2688
- through an accessible button. Its click only reaches an exact visible list row
2689
- or the relevant heading with fixed structural guidance; no action request occurs.
2689
+ The authenticated snapshot retains optional body-free needs input. The same
2690
+ injected pure needs function drives global nav action/watch counts and the
2691
+ existing tab-title action count; status/file readers retain their summary/items
2692
+ projection. The Agents button separately shows live pending approvals. The
2693
+ in-page character, SVG, character frames and pixel injection are removed; the
2694
+ standalone #391 Task B window owns that presentation.
2690
2695
 
2691
- DOM writes and title counts follow the derived signature, not every poll. A
2692
- waiting pulse uses CSS transform/opacity only, with a static reduced-motion and
2693
- blink-off escape. There is no extra timer, request, route or authority; legacy
2694
- or invalid snapshots make attention unavailable. Project changes clear stale
2695
- attention and restore the title. The existing CSP/header policy is unchanged.
2696
+ Attention activation switches views and selects only the exact visible
2697
+ approval/task id. Default/delivery/budget items without a visible exact target
2698
+ show their related heading and fixed id-only guidance, never a peer or first-row
2699
+ fallback. Filters and workflow state are unchanged. Signature guards suppress
2700
+ unchanged DOM writes, invalid legacy input stays unavailable, and project
2701
+ changes reset attention and close stale dialogs. CSP/header policy remains.
2696
2702
 
2697
2703
  ## Amendment: hub memory, tiers and graph (#258, phase 1)
2698
2704
 
@@ -2710,20 +2716,12 @@ and rebuilds; the dashboard's Memory section is read-only inside the existing CS
2710
2716
  long-term tasks with leases (decision 9's amendment), claude-mem import and model-suggested edges follow in later phases.
2711
2717
 
2712
2718
 
2713
- ## Dashboard attention projection (#280, phase 4 in progress)
2719
+ ## Dashboard attention projection (#280, superseded by #391)
2714
2720
 
2715
- The existing dashboard snapshot supplies optional allowlisted needs input and
2716
- known presentation choices; normal status/file payloads do not gain that input.
2717
- The header independently projects the shared pure needs function into literal
2718
- built-in SVG pixels and an accessible state/count label. Unchanged state and
2719
- choices do not rewrite pet DOM. Clicks navigate only to exact visible rows or
2720
- related headings, never issue actions or alter filters. Missing/invalid legacy
2721
- input hides the widget. Project resets clear retained navigation and title.
2721
+ #391 Task A replaces the in-page pixel widget with nav/title counts as defined
2722
+ in Shared dashboard attention above. Native character presentation is the
2723
+ standalone Task B window; browser attention uses no character data or frames.
2722
2724
 
2723
- The two approved waiting frames alternate in CSS once per second only while
2724
- a live approval exists. Reduced motion and blink-off remain static. Every other
2725
- state stays still. No timer/request or new asset dependency is introduced;
2726
- existing header policy and computed CSP hashes apply.
2727
2725
  ## Amendment: hub memory between machines and long-term tasks (#258, phase 2)
2728
2726
 
2729
2727
  Decision 9 is amended for memory only: the memory directory is a git repository that tracks `log/*.jsonl` and syncs
@@ -2830,3 +2828,54 @@ session instead of assuming that an older extension provides the fence.
2830
2828
  Prompt lineage lasts until logical `agent_settled`: native retry, compaction or
2831
2829
  continuation starts inside that run retain the same command id. A later personal
2832
2830
  run has no hub command lineage.
2831
+
2832
+ ## Amendment: standalone attention window (#391 Task B, supersedes #280 dashboard pet)
2833
+
2834
+ The #280 phase-4 dashboard pet is replaced by an optional standalone macOS JXA
2835
+ window. Task B adds the window first; #391 Task A removes the existing in-page
2836
+ character and retains shared attention counts/navigation. Terminal characters
2837
+ and read-only `ahub pet` behavior remain.
2838
+
2839
+ `ahub pet --window` / `--window --close` are console-identity commands;
2840
+ `pet.window:true` opts into startup from `ahub up`. Non-macOS reports unsupported.
2841
+ One detached Bun host per project holds a signed pidfile in stateDir, reads
2842
+ `readPet` and `loadPetConfig` every second and atomically writes state, act/watch,
2843
+ character, blink and the full built-in `petPixels(CHARACTERS[...])` frame. No
2844
+ item ids/text/titles or external image assets are included. Unavailable status
2845
+ writes exactly `{offline:true}`; JXA displays Offline for two seconds, exits,
2846
+ and the host follows. A closed/crashed JXA also ends the host. A stale owner
2847
+ requires explicit close; an unconfirmed owner is retained.
2848
+
2849
+ `osascript -l JavaScript` creates an accessory, borderless nonactivating
2850
+ NSPanel subclass that can become key, uses NSFloatingWindowLevel and
2851
+ canJoinAllSpaces | stationary, and embeds a transparent local WKWebView. Its
2852
+ one-second NSTimer loads the atomic view and calls `update(json)` with an
2853
+ explicit no-op completion function (a JS null completion block crashes on the
2854
+ verified macOS). The fixed bridge moves/saves position, makes the pencil's
2855
+ inline text box key, sends a console message through NSTask argv to `ahub say`,
2856
+ opens the dashboard through `ahub ui`, or closes. Enter sends; Esc cancels.
2857
+ No shell evaluation, new dependency, compile step, HTTP listener or network
2858
+ request is added. Message contents are not logged by this surface.
2859
+ Working animates only the pixel SVG through a 0.7-second stepped CSS bob, disabled by prefers-reduced-motion; no frame, timer or view-file change is added.
2860
+
2861
+ The repaired Mac spike verified a transparent floating key panel and both
2862
+ bridge directions. Real input/drag/Spaces and end-to-end stream delivery remain
2863
+ manual acceptance evidence on the implementation PR, not inferred from the
2864
+ spike's process metrics or automated fixtures.
2865
+
2866
+ ## Amendment: dashboard views and task detail (#391 Task A)
2867
+
2868
+ The existing page has one nav button per view, with `aria-current`; sections
2869
+ carry `data-view` and selection toggles only `hidden`. A shared cookie helper
2870
+ stores theme, Office mode, selected view and optional board column focus.
2871
+ The one-time ticket keeps exclusive use of the URL fragment. Projects and
2872
+ Benchmarks join peers, approvals and budgets under Agents.
2873
+
2874
+ Compact task cards retain drag/drop, id/title, priority, owner dot and
2875
+ check/overdue markers. Click/Enter opens a native `dialog` via `showModal()`.
2876
+ `taskDetail` supplies full current public content and existing controls to that
2877
+ dialog and to a focused column's one-wide-list cards. Each snapshot updates the
2878
+ open detail; disappearance/project reset closes it. Back restores compact mode,
2879
+ and state/peer/release filters remain active in focus. Attention targets exact
2880
+ visible row ids with heading guidance when absent. No new route, API request,
2881
+ timer, source text/ref/history projection or external asset is introduced.
@@ -29,8 +29,8 @@ asset is copied.
29
29
  No timer, no `requestAnimationFrame`, no request. Colours come from the
30
30
  page's theme tokens through CSS classes; every state also carries a glyph
31
31
  and a text label.
32
- - An always-visible View control in the page header offers Off (the default), Flat, and in
33
- phase 4 Isometric; the choice persists in the host-scoped `agent-hub-office`
32
+ - The Office view section contains a mode control offering Off (the default),
33
+ Flat and Isometric; the choice persists in the host-scoped `agent-hub-office`
34
34
  cookie with the `agent-hub-theme` attributes and try/catch fallback (#246).
35
35
  - Layout: stable desk slots (claude, codex, kimi, pi, local, then others by id;
36
36
  sticky across snapshots via the previous scene, so a peer keeps its slot when
@@ -40,7 +40,8 @@ asset is copied.
40
40
  section width: rooms left to right when wide, stacked when narrow.
41
41
  - Interaction: desks and cards are focusable SVG groups with `role="button"`
42
42
  and accessible names; activation scrolls to and highlights the matching list
43
- row, and a list row highlights its desk or card on focus and hover. The scene
43
+ row; a card also opens the shared task detail dialog (#391). A list row
44
+ highlights its desk or card on focus and hover. The scene
44
45
  performs no action and sends no request; the closed action list is unchanged.
45
46
  - Room counts equal `taskProgress(tasks).counts` for the same snapshot (pinned
46
47
  by a test, including randomized boards).
@@ -64,7 +65,7 @@ Phase 1 decisions within the spec:
64
65
  - The primary condition of a desk is the first of offline, paused, waiting on
65
66
  approval, busy, idle; the raised-hand count, inbox tray, mode badge and break
66
67
  sign are independent marks that combine freely with it.
67
- - Work-floor cards sit at the owner's desk (at most 3, then "+N more" as text);
68
+ - Work-floor cards sit at the owner's desk (at most 3 in Flat, then an owner-filtered "+N more" control);
68
69
  a card whose owner has no visible desk waits in the Work floor room. Tasks in
69
70
  an unknown state are counted (`counts.unknown`) but placed nowhere.
70
71
  - The busy bubble names the task only when the peer has exactly one
@@ -142,11 +143,30 @@ Phase 4 decisions within the spec:
142
143
  parallelogram polygons (the linear image of their rect); cards, text labels,
143
144
  bubbles, marks and arc labels stay upright. No WebGL, no library, no new
144
145
  route, no CSP change.
145
- - The DOM is projection-independent: the same keyed nodes in the same order
146
- with the same accessible names, so focus order is identical (AC7, tested by
147
- comparing serialized tab order between Flat and Isometric). The viewBox is
148
- the projected bounding box with a small margin; the SVG keeps `width: 100%`,
149
- so phone width scales without horizontal page scroll.
146
+ - Keyboard targets follow model order independently of visual paint depth. Each
147
+ visible card has one transparent, focusable hit target with its full accessible
148
+ name; a separate `aria-hidden` paint layer is ordered back to front under
149
+ Isometric. Click, Enter and Space open the same task detail. Shared visible
150
+ cards retain their relative tab order across projections and switching back
151
+ restores Flat's model order. Correctly placed nodes are untouched during
152
+ snapshots; actual reorders use state-preserving DOM movement when available
153
+ and restore active focus without scrolling on the insertBefore fallback.
154
+ #394 allows Isometric to omit cards that do not
155
+ fit and expose the omitted count through the existing "+N more" control, so
156
+ its visible target inventory can be smaller than Flat's.
157
+ - #394 fixed-scale amendment (2026-10-14): the SVG width attribute is its actual
158
+ occupied projected viewBox width times 12 px/unit, with `max-width: 100%` and
159
+ automatic height. It remains centered and shrinks only when the panel is
160
+ narrower than this intrinsic width. Flat uses up to four room columns;
161
+ Isometric uses two on wide screens and bounds the occupied tiles rather than
162
+ blank grid corners, keeping the two-peer scene at the same scale at 1280 and
163
+ 1920 px. The cos-30/sin-30 projection and desk slots remain unchanged.
164
+ Desk trays use 24 px card bodies with 6 px gaps and padding inside a 20-unit
165
+ desk. Isometric fits upright cards wholly inside the tile (two per desk),
166
+ preserving omitted counts in a keyboard-accessible owner-filtered board link.
167
+ Its room band shifts vertically below desk legs and labels, with a one-unit
168
+ gap before the top-layer room headers; header backdrops associate each count
169
+ with its room.
150
170
  - A projection switch repaints every node in place (the projection is part of
151
171
  each reconcile signature) and is treated as a settle: positions jump, no
152
172
  transform transition storms. Card moves under Isometric animate through the
@@ -154,7 +174,9 @@ Phase 4 decisions within the spec:
154
174
  - Size accounting against the issue's 30 KB budget (page base 59,329 bytes at
155
175
  phase 1 branch point): phase 1 +11,040, phase 2 +7,340, phase 3 +2,141,
156
176
  phase 4 +1,704, art polish +3,559; final 89,113 bytes, +25,784 total,
157
- inside the budget. The iso shelf's base skirt was dropped to stay under it.
177
+ inside the original phase-4 budget. These are historical #264 figures; #394
178
+ adds a separately reviewed visual refinement. The iso shelf's base skirt was
179
+ dropped to stay under the original budget.
158
180
  - Art polish (2026-10-12): two reference concept images (a flat view and an
159
181
  isometric view) were generated with Higgsfield (nano_banana_pro) and kept
160
182
  outside the repo (scratchpad); they served as drawing references only. Per
@@ -168,7 +190,24 @@ Phase 4 decisions within the spec:
168
190
  wireframe iso room boxes with small-caps labels at the base, a Done shelf
169
191
  cabinet (flat) and stacked boxes on a slab (iso) with the count kept as
170
192
  text, two-column room cards with thin dividers, and arc arrowheads at the
171
- target end.
193
+ target end. #394 supersedes the wireframe posts, small-caps base labels,
194
+ decorative empty shelf slots and two-column cards:
195
+ - Room names are sentence case, 13 px/600 in `--ink`; count pills are 12 px
196
+ monospace with tabular figures. Desk names are 13 px; card/state/meta text
197
+ is 12 px. Shapes use 1 px non-scaling hairlines; focus is 2 px.
198
+ - Room tiles have a one-unit gap horizontally and vertically. Room cards
199
+ use one 20-unit padded column, 28 px height and 6 px gap, keeping
200
+ the eight-card model cap and public fields. Labels show id plus public
201
+ title. Canvas measures the actual system/monospace fonts before clipping at
202
+ a nearby word boundary; an internal SVG clipPath guarantees the card text
203
+ boundary. The full title remains in SVG title, aria-label and task detail.
204
+ - Room title/count groups paint last above all tiles. Isometric cards remain
205
+ upright, fit wholly inside padded tile bounds and paint by projected depth;
206
+ omitted cards contribute to "+N more". Empty rooms and the empty Done shelf
207
+ show "No tasks"; populated shelf slots correspond to existing done count
208
+ up to the current Flat/Isometric caps.
209
+ - Existing theme tokens, public-view privacy, counts/placement classifications,
210
+ animations, reduced motion, keyboard activation and mode cookie remain.
172
211
 
173
212
  ## Verification
174
213
 
@@ -186,6 +225,11 @@ Phase 4 decisions within the spec:
186
225
  timer/request/colour literal in the scene code, reduced-motion and motion CSS
187
226
  scans, no DOM write on an unchanged snapshot (counting fake document), focus
188
227
  and activation highlighting, "+N more" filtering, `resetView` clearing;
228
+ #394: fixed font/scene scale, 1 px hairlines, top-layer headers, actual shelf
229
+ counts, measured Latin/CJK title clipping and hard SVG bounds, cross-room
230
+ depth order, projection-independent shared-target tab order and Flat restore,
231
+ 0/4/12-task two-peer geometry, count-stable placement changes and light/dark
232
+ text token contrast at least 4.5:1;
189
233
  phase 2: card moves keep their node and animate by transform, arcs/marks/
190
234
  latch draw once with fade timing, departure fade purges on animationend;
191
235
  phase 3: the exact bubble, finishing-a-turn line, check-running mark and
@@ -0,0 +1,31 @@
1
+ # 0.12.27 release verification
2
+
3
+ This record covers release preparation and source verification. It does not certify tagging, package publication, global installation or a live upgrade; those receipts are recorded separately.
4
+
5
+ ## Candidate
6
+
7
+ 0.12.27 carries the console-presentation round for issues #391 and #394: PRs #392, #393, #395 and #396. Control protocol remains 16.
8
+
9
+ - #392 (#391 Task B): an opt-in macOS floating pet window with built-in pixels, counts-only local state, a console message pencil, saved position and signed process ownership; terminal pet reads stay available to agent shells.
10
+ - #393 (#391 Task A): the local dashboard split into cookie-backed views, compact task cards with shared dialog/column details and exact-id attention badges; character presentation moved to the standalone pet window.
11
+ - #395 (#391 follow-up): the pet window shrinks to a compact 150x150 panel with the original pixel art in deeper state colors and a configurable base palette (`pet.palette`, or 1/2/3/4 while the window is key, or `ahub pet --palette`; blue, teal, violet, ochre) with a matching rim line; the status pill and message composer reveal only while the pointer is over the character, driven by a 10 Hz global-mouse-position poll against a page-posted hotspot rect because an inactive accessory panel receives no mouse-moved events; the pill shadow is dropped.
12
+ - #396 (#394): the dashboard Office view renders at an intrinsic 12 px/unit scale with 1 px non-scaling hairlines and padded room cards in both themes, and the desk More control is a separately reconciled sibling button in the non-button marks layer so assistive technology can reach it.
13
+
14
+ Review was adversarial and multi-round on the board: tasks #56 and #58 (owner kimi, reviewer claude) for the compact window and its round-3 fixes, #57 and #59 (owner codex, reviewer claude) for the Office refinement and its round-3 fixes. Owner iterations settled the final pet design (original art, teal default palette) and the hover-reveal interaction, each re-gated after the change.
15
+
16
+ ## Document review
17
+
18
+ Every stale document was rechecked against the source commits of the four PRs. README, Quickstart and the adapters, daemon, tasks and tests area notes were confirmed accurate (version strings landed with the prepare commit; the new pet palette config write is console-local presentation and does not intersect the settings-registry rule). Operations and Security were amended at 59dd4803: Office room labels follow #396 (To do, Done), the pet window section names `ahub pet --palette`, Security enumerates the #391 view and column-focus cookies, the palette field in pet-view.json and the JXA bridge's palette operation with its validated config.local.json write path. All eight documents were restamped at 0f8a7ba4; `node scripts/check-docs.mjs --require-fresh` reports docs: OK.
19
+
20
+ ## Recorded checks
21
+
22
+ - PR #395 head b8498c03: worktree `scripts/check.sh` 2744 pass, 0 fail, `check: OK`; CI Linux and macOS passed, seeded guards pending when the owner merged; the main-branch run of merge commit b2f076fd completed success, seeded guards included.
23
+ - PR #396 head aee84ba1: owner-reported worktree gate 2761 pass, 0 fail, `check: OK`; CI Linux, macOS and seeded guards passed; board review approved (task #59).
24
+ - Release candidate 9d21b1f4: local `scripts/check.sh` in an isolated worktree — 2761 pass, 0 fail, 190249 assertions, `check: OK`, no daemon leaks. The first candidate bundle (e9037e43) embedded `../../node_modules` paths because the worktree had no installed dependencies at build time; the bundle was rebuilt after `bun install` (9d21b1f4) and the freshness check passes. Later commits on this branch change documentation only.
25
+ - Release head: CI, document freshness at the merge commit, and the release workflow are required before tagging is reported complete.
26
+
27
+ Note: `scripts/check.sh` in the main checkout is not a valid signal there because the live hub daemon serving the project interferes (recorded in shared memory #194264); the isolated worktree gate is the valid signal.
28
+
29
+ ## Not verified
30
+
31
+ Native, account and research legs remain open in #273 and #1. Native VoiceOver traversal of the pet window and the Office view was not run; accessibility is covered at DOM ancestry and keyboard level by tests. The installed runtime and live hubs are not upgraded by this release.