@abelxiaoxing/cadence 2.0.2 → 2.0.3

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 CHANGED
@@ -40,11 +40,13 @@ See [service management](docs/service-management.md) for configuration, model/au
40
40
 
41
41
  `pi install npm:@abelxiaoxing/cadence` (user scope) writes `~/.local/share/systemd/user/cadence.service`, enables it and starts the owner for `~/cadence` on `http://127.0.0.1:17423`.
42
42
  Set an existing absolute `CADENCE_WORKSPACE` at install to choose another workspace, or `CADENCE_AUTOSTART=0` to skip registration.
43
+ That first registration also enables linger when logind allows it without any authorization prompt, so the service starts at boot instead of at login; `CADENCE_LINGER=0` skips it, and later updates keep `loginctl disable-linger`.
43
44
  Enter the WebUI once with the link from `cadence-service token-link --workspace ~/cadence --reveal`; installation prints that command, not the token.
44
45
  Each `pi update` restarts the unit through orderly Stop, so running work is stopped rather than detached; `systemctl --user disable --now cadence` or `mask` is kept across upgrades.
45
- Run `cadence-service autostart remove` before `pi remove`.
46
+ Run `cadence-service autostart remove` before `pi remove`; after `remove`, a later `pi update` registers the unit again as a first registration, so keep it off with `disable` or `mask` instead.
46
47
  The npm client hides dependency install-script output, and with `strict-allow-scripts` it skips those scripts entirely.
47
- Approve Cadence once with `npm install-scripts approve @abelxiaoxing/cadence` inside `~/.pi/agent/npm` (or `npm config set allow-scripts=@abelxiaoxing/cadence --location=user`), or run `cadence-service autostart install`; `/cadence` names that command while no unit is registered.
48
+ Approve Cadence once with `npm install-scripts approve @abelxiaoxing/cadence` inside `~/.pi/agent/npm` (or `npm config set allow-scripts=@abelxiaoxing/cadence --location=user`), or run `cadence-service autostart install --linger`, which may ask for your password.
49
+ Pi's session-start card names that command (without `--linger` under `CADENCE_LINGER=0`) while Pi's copy has no unit on a systemd machine, and `loginctl enable-linger` while the enabled unit only starts at login.
48
50
  Until the optional SDK and Pi's `auth.json` exist, registration or start waits instead of quarantining an owner.
49
51
  See [the systemd user unit](docs/service-management.md#linux-systemd-user-unit) for exact behavior and limits.
50
52
 
@@ -62,6 +64,27 @@ Return, session departure and Pi quit **detach; admitted work continues** while
62
64
  Reattach to observe the same IDs without replay.
63
65
  Explicit Cancel requests bounded stop; it is not proof that every escaped descendant stopped.
64
66
 
67
+ ### Background agent panel
68
+
69
+ A readonly panel in the Pi TUI follows background agents: the child runs of Cadence's running owner and any agents another extension announces on Pi's shared event bus.
70
+ Every TUI session, not only `/cadence`, looks for the owner already running for its workspace half a second after start and every 15s while none answers; it never starts, recovers or selects one, skips an incompatible owner and only detaches on departure.
71
+ That observation holds one of the owner's viewer attachments, so departure (including Pi quit) waits up to 1.5s for the detach to reach the owner rather than leaving the slot to its idle expiry; `/cadence` departs the same way.
72
+ `CADENCE_AGENT_PANEL=off` turns that observation off.
73
+ It reads the active roster every 5s, and every 2s together with the task's snapshot while it follows an episode, announcing each child of the active episodes: its assignment ID as label, purpose as kind, lifecycle or latest tool as activity, and completed, canceled or any other outcome (with its reason) as done, cancelled or error.
74
+ A child whose outcome the session can no longer observe (no compatible owner a whole retry after losing it, or no settled row five looks after its run left the roster) ends as an error that says so; `/cadence` History keeps the actual outcome.
75
+ Elapsed time counts from when the session first observed a child (`—` for one first seen settled); no tokens are shown because the owner records no usage.
76
+ Opening a child reads its retained messages, tool calls and results through the history readers, up to 64KiB per field; complete fields, search and export stay in `/cadence` History.
77
+ A retained `edit` call shows its call and result without Pi's diff preview, which would compare against the file as it is now.
78
+ Producers emit `subagent:start {id,label,kind,startedAt}`, `subagent:message {id,message,streaming?}`, `subagent:activity {id,activity,tokensIn?,tokensOut?}`, `subagent:stats {id,tokensIn,tokensOut?}` and `subagent:end {id,status,endedAt,error?}` with status `done`, `error` or `cancelled`; `startedAt: null` marks an unobserved start.
79
+ A message has the main session's message shape; `streaming: true` marks a snapshot that the next message replaces.
80
+ The panel emits `subagent:view {id}` (`id: null` when none) so a producer loads only the shown agent's messages.
81
+ Nothing is mounted until the first agent arrives (`CADENCE_AGENT_PANEL=always` keeps `● main` visible).
82
+ Then a launched/finished block sits above the input and one row per agent below it: at most six recently active rows plus `+K more`.
83
+ With an empty input, ↓ moves focus to the rows; ↑/↓ or Ctrl+P/N select, Enter shows that agent's transcript in place of the main view, PgUp/PgDn, Ctrl+U/D and Home/End scroll it, and Esc returns to the main view and then to the input.
84
+ Every other input key, including Enter, Shift+Tab and Ctrl+J, stays Pi's; each agent view remembers its scroll position.
85
+ The panel never starts, cancels or keeps an agent or Pi alive, and keeps nothing across restarts.
86
+ For manual checks, `pi -e ./src/index.ts -e ./scripts/agent-panel-demo.ts` adds `/agents-demo [count]`, which plays fake agents (the second fails) and runs nothing.
87
+
65
88
  ### Browser
66
89
 
67
90
  Open the locally revealed token link.
@@ -71,6 +94,7 @@ A token grants workspace access, not action consent.
71
94
  Every mutation needs its own context-bound preview/confirmation; stale/duplicate/lost replies do not silently replay work.
72
95
  The WebUI provides task/run/assignment navigation, long retained messages and tool detail, exact literal search, timeline and complete scoped NDJSON/Markdown downloads.
73
96
  Desktop panes and phone drawers retain cancellation and keyboard controls.
97
+ Its chrome follows pi-web-ui: a compact topbar with view tabs and icon actions, a sectioned task sidebar, pill inspector tabs, transcript/tool cards and a bottom statusbar; phones wrap the topbar into an action row and an icon tab row.
74
98
 
75
99
  ## Execution, checks and review
76
100
 
@@ -116,7 +140,7 @@ Outbound provider proxy policy is independent of inbound HTTPS and refuses unsup
116
140
  - `skills/git-commit` requires an explicit commit request and deterministic audit; task review never commits.
117
141
  - Three pinned professional profiles in `agents/` provide readonly design/diagnosis and direct-edit implementation instructions, not execution authority.
118
142
  - `config/` contains optional research/check examples.
119
- Missing-only user `.env` template creation is the sole postinstall behavior; no service/build/Git/provider operation runs.
143
+ Missing-only user `.env` template creation and the Linux autostart refresh above are the only postinstall behaviors; no build/Git/provider operation runs.
120
144
  - `node /absolute/cadence/src/operator-cli.mjs doctor|runs [workspace]` remains readonly and independent of service startup.
121
145
 
122
146
  ## Development and evidence
@@ -134,8 +158,9 @@ CADENCE_BROWSER_PATH=/absolute/existing/chromium bun run verify
134
158
  bun pm pack --destination /absolute/private-temp
135
159
  ```
136
160
 
137
- Build/verification use a fresh private directory with `TMPDIR`, `TEMP` and `TMP` set explicitly.
161
+ Build/verification use a fresh private directory with `TMPDIR`, `TEMP` and `TMP` set explicitly, on the checkout's disk filesystem rather than a nearly full tmpfs.
138
162
  `verify` includes native/unit tests, web tests, required real-browser scenarios and exact real-pack auditing; missing required browser is non-green, never an automatic download.
163
+ It needs a Node with TypeScript type stripping (official builds; a distro Node built without it fails `build:web:check`) and NSS `certutil` for the isolated HTTPS browser scenario.
139
164
  Source/extracted PTYs, fabricated loopback providers and isolated HTTPS are distinct from physical humans/devices, paid accounts, package-manager installation and native Windows/macOS/ConPTY qualification.
140
165
  Those additional lanes remain unqualified unless their own receipts exist.
141
166
  No passing gate authorizes commit, push, publication, installation, deployment or cleanup.
@@ -153,6 +178,7 @@ Historical logs are not runtime dependencies, and removing development tooling m
153
178
  | Owner | Responsibility |
154
179
  | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
155
180
  | `src/index.ts`, `src/task-shell.ts`, `src/native-*.ts` | Nonactivating Pi entry, raw native consent, typed service attachment, paging and verified export; no embedded executor |
181
+ | `src/agent-panel.ts`, `src/agent-panel-model.ts`, `src/agent-panel-cadence.ts` | Readonly agent panel over Pi's `subagent:*` bus, fed with a running owner's children; never starts or cancels work |
156
182
  | `src/service/host.ts`, `src/service/cli.ts`, `src/service/autostart.ts` | Real single-owner composition, explicit management and the generated Linux user unit; management entry stays SDK-free |
157
183
  | `src/service/{coordination,private-files,owner,recovery}.ts` | Canonical overlap exclusion, exact locks, original-operation lifetime and informed local recovery |
158
184
  | `src/service/{admission,task-actions,graph,scheduler}.ts` | Context-bound actions, actual current views, finite graph scheduling, check/review barriers |
@@ -305,6 +331,7 @@ Byte values are UTF-8/encoded bounds where specified; they are not targets to si
305
331
  | Host refuses during startup | Fixed code/stage only; unregistered exits `refused`, registered stays `quarantined` |
306
332
  | Workspace containing the private state home | Land on `~/cadence` (only start creates it); never move state into the working copy |
307
333
  | Upgrade changes the unit workspace or Node path | Stop with the loaded unit definition before rewriting, not only SIGTERM |
334
+ | Install hook cannot prompt and npm hides its output | Only a first registration tries passwordless linger; the startup card names the gap |
308
335
 
309
336
  Good: current context → explicit grant → durable acceptance → genuine original native/storage settlement → exact retained dependency → real checks → human review.
310
337
  Base: a client leaves and another reattaches to the same accepted run without launching it again.
@@ -320,7 +347,9 @@ Correct: expose bounded continuations/full exports and report the exact executed
320
347
  Read affected source and adjacent tests, identify the actual owner of a contract, then make the smallest coherent change.
321
348
  Use ordinary source editing and directly affected checks while developing; independently review complete capabilities and run full `verify` at stable integration boundaries.
322
349
  Do not run the entire suite after every local edit, but do not replace final integration with unit mocks or citation counts.
323
- On this development host create fresh0700 disk roots under `/home/mirako/abel` and explicitly set TMPDIR/TEMP/TMP; `/tmp` is inode-exhausted.
350
+ `bun run test` runs unit files in parallel, then `serialProcessFiles` (real PTY/SDK process flows) and `serialScanFiles` (>8MiB cold scans) from `vitest.config.ts` one at a time; a file belongs there only when it measurably exceeds its own waits under shared CPU.
351
+ Create a fresh 0700 root on the checkout's disk filesystem and explicitly set TMPDIR/TEMP/TMP to it; a nearly full tmpfs `/tmp` makes owners refuse at their free-space floor (`receipt-inconclusive`) and `web/dist` publication fail with EXDEV.
352
+ A test waits for the event it needs (both providers contacted, a row settled), not a wall-clock guess at how long process starts take; fixed waits stay only where time is the contract.
324
353
  Use fabricated credentials, isolated browser/profile/state roots and local fixtures; never personal credentials, automatic downloads or unknown process cleanup.
325
354
  Outer command budgets must cover whole suites and preserve original runner waits; existing SDK20s/child15s, PTY90s/interaction15s and browser120s/action15s fixture budgets are not increased to obtain green.
326
355
  Preserve failed attempts; correct a demonstrated cause before rerunning, and never assign old failures a retrospective cause without evidence.
@@ -333,16 +362,27 @@ Regression owners:
333
362
  - `worker-*`, `lightweight-sdk`, `lightweight-process-diff`: genuine SDK/tool capture, split redaction, no-spill bounds and original native facts.
334
363
  - `service-history-*`: durable ordering, cold/no-index/restarted proof/search/export, corruption/torn/quota and expected-byte publication.
335
364
  - `lightweight-shell`, `native-client`, `native-history`, `terminal-integration`: native consent, shared service, Unicode/paging, detach/cancel and actual source/extracted PTYs.
365
+ - `agent-panel`, `agent-panel-model`, `agent-panel-cadence`: panel keys/rendering and readonly owner observation that never starts, cancels or replays work.
336
366
  - `test/web/`: adapted pure/SSR tests separately from actual built-browser contexts, HTTPS, mixed clients, focus/viewports and complete downloads.
337
367
  - `package-*`, `distribution`, `service-package`, `independence`: exact tar/member/body/import/notice closure and nonactivating discovery.
338
368
  - `service-autostart`, `install-config`: Pi user-scope gating, unit escaping, upgrade/disable/mask/foreign handling and orderly removal.
339
369
  - `workspace-landing`: home-directory redirection to `~/cadence` across management, native attach and observation.
340
370
 
341
371
  Regenerate operator/service/native/browser outputs only through their canonical builders; `--check` variants compare new private output without overwriting canonical bytes.
372
+ Publish `web/dist` from Node: Vite run under Bun lays out its preload helper differently, so a Bun build fails a Node `build:web:check`.
342
373
  Review the independently enumerated package member list and every emitted body, not a count or an expected list generated from the tar under test.
343
374
  Keep public Pi peers external for the extension, the exact Undici/ws runtime edges, the exact optional SDK pins for the standalone owner and all upstream/font/vendor notices.
344
375
  Preserve original license bytes through their precise Git attributes; line-ending normalization must not invalidate audited source/notice hashes.
345
376
 
377
+ ### Release 2.0.3 acceptance snapshot
378
+
379
+ Full `verify` passed on `c27b8ca`: 1924 root tests in 78 files (27 Windows-only controls skipped on Linux), 111 web tests in 8 files, 5 real-browser scenarios in 3 files and the 132-member real pack audit.
380
+ Observed environment: Linux x86_64, official Node 22.22.1, Bun 1.3.14, the pinned Pi SDK 0.84.3 and Chrome for Testing 153.0.8010.12; later commits change only tests and this section.
381
+ The GitHub matrix (Windows and Ubuntu × Node 22/24 × `parallel`, `serial-process`, `serial-scan`) runs on the separate CI branch.
382
+ A real Pi 1.4.0 user-scope install of the packed candidate, installed into Pi's own npm layout, registered and enabled the unit, enabled linger without a prompt and, on upgrade, stopped the old owner in order before starting the new one.
383
+ That owner started with the agent directory Pi had created at 0775 and served the built WebUI to Chromium at 1440, 390 and 320px widths.
384
+ No model-backed task ran there (no Pi provider login); macOS, physical phones, paid accounts and every adapter, and a second machine remain unqualified.
385
+
346
386
  ### Prior integrated acceptance snapshot
347
387
 
348
388
  Before removal of development-workflow tooling, the integrated redesign passed full `verify`:1839 root tests/69 files,110 web tests/8 files and5 real-browser scenarios/3 files, with27 existing Windows-only controls skipped on Linux.
@@ -8,7 +8,7 @@ Repository `provenance/webui-reuse.json` records source/destination hashes and e
8
8
 
9
9
  | Source family | Package adaptation |
10
10
  | ------------------------------------ | ------------------------------------------------------------------------ |
11
- | App, panels, layout, drawers | Three-pane task workspace and responsive phone navigation |
11
+ | App, TopBar, panels, layout, drawers | Three-pane workspace, pi topbar/statusbar chrome and phone navigation |
12
12
  | conv-groups, PlanBoard | Task/run/child tree, editable finite graph and separate confirmations |
13
13
  | MessageList, Message, ToolCallBlock | Paged transcript, stable tool associations and retained detail |
14
14
  | Markdown, StreamMarkdown, copy | Sanitized Markdown/math/code, no script/external-image execution |
@@ -31,6 +31,10 @@ On Linux, Pi's user-scope install (`pi install npm:@abelxiaoxing/cadence`, npm i
31
31
  Refresh acts only when the package is exactly Pi's managed user copy; checkouts, project (`-l`), temporary and global installs, other platforms and `CADENCE_AUTOSTART=0` are left alone.
32
32
 
33
33
  The first refresh writes `~/.local/share/systemd/user/cadence.service`, enables it for `default.target` and starts it.
34
+ A user unit runs with the user manager, which starts at login unless logind lingers the user, so that first registration also asks logind to enable linger when it is off; `CADENCE_LINGER=0` at install skips it.
35
+ It never prompts: it calls `SetUserLinger` through `busctl` with `interactive=false` and no interactive authorization (bounded to 15s), because `loginctl enable-linger` always requests an interactive check that a desktop polkit agent can turn into a password dialog even with `--no-ask-password`.
36
+ Where polkit requires authorization for `set-self-linger` (older systemd defaults), the unit stays login-only and the result reports `"linger":"refused"`.
37
+ Later refreshes do not change linger, so `loginctl disable-linger` is kept across upgrades.
34
38
  The workspace is `~/cadence` (created if missing) or an existing absolute `CADENCE_WORKSPACE`, which lands on `~/cadence` with a note when it contains the unit's state home; later refreshes keep the unit's workspace unless that variable is set again.
35
39
  The unit runs `start --foreground --workspace` without `--port`, so a new workspace selects `http://127.0.0.1:17423`.
36
40
  A port saved by an earlier start of that workspace still wins, and an occupied endpoint fails the unit instead of falling back.
@@ -50,17 +54,24 @@ Package files may be hard links into the package manager's store (Bun's default
50
54
  Missing or unusable Pi sources refuse before an owner registers; a new owner without the SDK quarantines.
51
55
  Refresh therefore does not register the unit while the SDK is unresolvable (for example, optional dependencies omitted), and enables without starting it while `auth.json` is missing; the unit carries `ConditionPathExists=` for all three files.
52
56
  After logging in to Pi, start it with `systemctl --user start cadence`.
53
- Without linger, user units start at login and stop at logout through the same Stop; `loginctl enable-linger` keeps the owner running and starts it at boot.
57
+ Without linger, user units start at login and stop at logout through the same Stop.
58
+ Linger starts the user manager, with every enabled user unit, at boot and keeps it running after logout.
59
+ Because npm hides the install guidance, Pi's session-start card names `autostart install --linger` while Pi's managed copy has no unit, and `loginctl enable-linger` while the enabled unit is login-only.
60
+ A machine not booted with systemd (no `/run/systemd/system`), a disabled or masked unit (also `mask --runtime`) and `CADENCE_AUTOSTART=0` keep the card quiet; with `CADENCE_LINGER=0` in Pi's environment it never suggests linger and names `autostart install` without `--linger`.
54
61
 
55
62
  ```sh
56
- cadence-service autostart install [--workspace /absolute/project]
63
+ cadence-service autostart install [--workspace /absolute/project] [--linger]
57
64
  cadence-service autostart status
58
65
  cadence-service autostart remove
59
66
  ```
60
67
 
61
68
  `install` registers, enables and starts the unit from any package location unless it is masked.
69
+ With `--linger` it also runs `loginctl enable-linger`, which may ask for your password; it asks only after the unit has started again, so an interrupted prompt never leaves the owner stopped.
70
+ `status` reports `linger` as `on` or `off`.
62
71
  `remove` disables it through `ExecStop` and deletes only the generated file; workspace, state home, history and Pi sources stay.
63
72
  Because npm runs no uninstall script, run `remove` before `pi remove`; a left-behind unit skips start once its CLI path disappears.
73
+ `remove` is for uninstalling: without the generated file the next `pi update` is a first registration again (unit and linger).
74
+ To keep the service off while Cadence stays installed, use `systemctl --user disable --now cadence` or `mask`.
64
75
 
65
76
  ## Status, departure and Stop
66
77
 
@@ -78,7 +89,8 @@ Because npm runs no uninstall script, run `remove` before `pi remove`; a left-be
78
89
  Stages are `package` (installed web assets or Agent profiles), `pi-agent-directory`, `pi-auth`, `pi-models` and `service`; stderr names the selected Pi source to fix.
79
90
  `quarantined` with stage `pi-runtime` or `service` means the owner registered first; it keeps its fences for informed recovery.
80
91
  Reports carry fixed codes and stages only, never paths, configuration bytes or OS error text.
81
- - The selected Pi agent directory must be a real directory owned by you with mode 0700; `auth.json` and `models.json` must be your own single-link regular files with mode 0600.
92
+ - The selected Pi agent directory must be a real directory (not a symlink) owned by you; `auth.json` and `models.json` must be your own single-link regular files.
93
+ Their mode bits are not checked: Pi creates its agent directory with your umask (0755, or 0775 under umask 002), and Cadence's own state stays 0700 regardless.
82
94
  `models.json` may use only fields the pinned SDK supports.
83
95
  `supportsMidConvoSystemMessages` from newer Pi is accepted because the pinned SDK has no system-role conversation message; other unknown fields refuse rather than being silently ignored.
84
96
  - A foreground owner can be managed from another terminal.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abelxiaoxing/cadence",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Shared Pi task workspace: native terminal and WebUI, persistent service, checks and human review.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,6 +17,9 @@
17
17
  "skills",
18
18
  "config",
19
19
  "agents",
20
+ "src/agent-panel-cadence.ts",
21
+ "src/agent-panel-model.ts",
22
+ "src/agent-panel.ts",
20
23
  "src/index.ts",
21
24
  "src/install-config.mjs",
22
25
  "src/native-build.ts",
@@ -74,7 +77,7 @@
74
77
  "verify": "bun run check && bun run check:web && bun run build:web:check && bun run lint && bun run check:agents && bun run test && bun run test:web && bun run test:browser && bun run pack:check",
75
78
  "check": "node scripts/check-syntax.mjs && bun scripts/build-operator.mjs --check && bun scripts/build-service.mjs --check && tsc --noEmit",
76
79
  "lint": "biome check . && rumdl check .",
77
- "test": "vitest run --no-file-parallelism",
80
+ "test": "vitest run",
78
81
  "test:target": "vitest run",
79
82
  "check:agents": "node scripts/check-agents.mjs",
80
83
  "doctor": "node src/operator-cli.mjs doctor",