@abelxiaoxing/cadence 2.0.16 → 2.0.17
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 +39 -17
- package/docs/service-management.md +1 -1
- package/package.json +2 -2
- package/src/service-host.mjs +15 -4
- package/web/dist/assets/cadence.css +1 -1
- package/web/dist/assets/cadence.js +10 -10
- package/web/dist/manifest.json +6 -6
package/README.md
CHANGED
|
@@ -141,13 +141,18 @@ The unified browser entry opens on the conversation shell, without an execution
|
|
|
141
141
|
Choose a working folder from the lower-right button; before a folder is selected, New conversation offers the same picker and Send stays disabled.
|
|
142
142
|
Only explicit Open starts or reuses a project owner.
|
|
143
143
|
Within that project, the browser opens on an ordinary conversation with a real message composer, retained multi-turn context and standard read/write/edit/bash tools; no Cadence task is created by Send.
|
|
144
|
-
Use `cadence <goal>` or `/cadence <goal>` at the beginning of the input, or select Cadence task, to
|
|
144
|
+
Use `cadence <goal>` or `/cadence <goal>` at the beginning of the input, or select Cadence task, then Send to create a task in the background and begin readonly analysis.
|
|
145
|
+
New task opens the same composer in task mode; there is no task-kind picker or creation dialog.
|
|
145
146
|
Mentions, quotations and fenced code do not select task mode.
|
|
146
|
-
|
|
147
|
+
Analysis appears in the task transcript.
|
|
148
|
+
Review implementation plan opens the retained proposal for one explicit Confirm plan and execute approval: save those exact bytes, then start only the matching graph under a fresh grant.
|
|
149
|
+
Changed context, failed publication or an uncertain reply stops the sequence without automatic retry.
|
|
150
|
+
Configured checks and human review remain separate.
|
|
147
151
|
A task created from an existing ordinary conversation retains a navigation link back; the old conversation is not converted and its history is not silently injected into the task.
|
|
148
152
|
All of this works without a live Pi terminal.
|
|
149
153
|
A token grants workspace access, not action consent.
|
|
150
|
-
|
|
154
|
+
Task Send authorizes only creation and readonly analysis.
|
|
155
|
+
Editing requires context-bound plan confirmation; the advanced inspector retains independent Save/Start controls.
|
|
151
156
|
Ordinary Send binds its exact text, conversation head, epoch, access and selected model; stale/duplicate/lost replies do not silently replay work.
|
|
152
157
|
The WebUI provides task/run/assignment navigation, long retained messages and tool detail, exact literal search, timeline and complete scoped NDJSON/Markdown downloads.
|
|
153
158
|
Desktop panes and phone drawers retain cancellation and keyboard controls.
|
|
@@ -279,8 +284,9 @@ bun pm pack --destination /absolute/private-temp
|
|
|
279
284
|
|
|
280
285
|
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.
|
|
281
286
|
`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.
|
|
282
|
-
It needs a Node with TypeScript type stripping (official builds; a distro Node built without it fails `build:web:check`)
|
|
283
|
-
|
|
287
|
+
It needs a Node with TypeScript type stripping (official builds; a distro Node built without it fails `build:web:check`).
|
|
288
|
+
`verify` keeps short regressions and loopback browser scenarios; it runs no real PTY workflow, HTTPS-proxy browser lane or multi-MiB cold-history scan.
|
|
289
|
+
Fabricated loopback providers are distinct from physical humans/devices, paid accounts, package-manager installation and native Windows/macOS/ConPTY qualification.
|
|
284
290
|
Those additional lanes remain unqualified unless their own receipts exist.
|
|
285
291
|
No passing gate authorizes commit, push, publication, installation, deployment or cleanup.
|
|
286
292
|
|
|
@@ -510,9 +516,8 @@ Correct: expose bounded continuations/full exports and report the exact executed
|
|
|
510
516
|
Read affected source and adjacent tests, identify the actual owner of a contract, then make the smallest coherent change.
|
|
511
517
|
Use ordinary source editing and directly affected checks while developing; independently review complete capabilities and run full `verify` at stable integration boundaries.
|
|
512
518
|
Do not run the entire suite after every local edit, but do not replace final integration with unit mocks or citation counts.
|
|
513
|
-
`bun run test` runs
|
|
514
|
-
|
|
515
|
-
`test/test-selection.test.ts` compares the runner's actual file discovery across all three configurations, rejecting duplicates, overlap, omissions and moved serial files; new tests belong to integration until explicitly promoted.
|
|
519
|
+
`bun run test` runs every root file in one parallel group; there are no serial groups or separate fast/integration lanes.
|
|
520
|
+
Its workers load `test/no-fsync.mjs`, which makes fsync a no-op inside them (spawned owners and CLIs still flush): crash tests kill processes and no test simulates power loss.
|
|
516
521
|
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.
|
|
517
522
|
Keep that root's absolute path short: Chromium appends fixture and singleton-socket components, and an overly long path makes it abort before browser scenarios begin.
|
|
518
523
|
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.
|
|
@@ -523,18 +528,17 @@ Preserve failed attempts; correct a demonstrated cause before rerunning, and nev
|
|
|
523
528
|
Regression owners:
|
|
524
529
|
|
|
525
530
|
- `service-contract`, `service-current`, `service-model-choice`, `service-auth`: closed DTOs, exact source/choice/current authority, security and compatibility.
|
|
526
|
-
- `service-owner`, `service-accepted-work`, `service-
|
|
527
|
-
- `service-scheduler`, `service-checks`, `service-human-review`, `service-accepting-host`: real SDK overlap/exclusion, native checks, review and publication.
|
|
531
|
+
- `service-owner`, `service-accepted-work`, `service-recovery`, `service-registry-recovery`: original operations, overlap, Stop, unknown fences and informed recovery.
|
|
528
532
|
- `worker-*`, `lightweight-sdk`, `lightweight-process-diff`: genuine SDK/tool capture, split redaction, no-spill bounds and original native facts.
|
|
529
533
|
- `service-history-*`: durable ordering, cold/no-index/restarted proof/search/export, corruption/torn/quota and expected-byte publication.
|
|
530
|
-
- `lightweight-shell`, `native-client`, `native-history`, `terminal-integration`: native consent, shared service, Unicode/paging
|
|
534
|
+
- `lightweight-shell`, `native-client`, `native-history`, `terminal-integration`: native consent, shared service, Unicode/paging and detach/cancel.
|
|
531
535
|
- `agent-panel`, `agent-panel-model`, `agent-panel-cadence`: panel keys/rendering and readonly owner observation that never starts, cancels or replays work.
|
|
532
|
-
- `test/web/`: adapted pure/SSR tests separately from actual built-browser contexts,
|
|
536
|
+
- `test/web/`: adapted pure/SSR tests separately from actual built-browser contexts; `accepting-browser` drives one real SDK Start, check, review and departure-without-cancel workflow with mixed clients, focus/viewports and complete downloads.
|
|
533
537
|
- `package-*`, `distribution`, `service-package`, `independence`: exact tar/member/body/import/notice closure and nonactivating discovery.
|
|
534
538
|
- `service-autostart`, `project-start`, `install-config`: explicit `cadence server` registration on systemd (root system scope without linger, legacy user scope), launchd and the Windows Run key, separate named service definitions and directory owners, definition escaping, restart/disable/mask/foreign handling, orderly Stop before every change, the `.env` port and token lines and a package without install scripts.
|
|
535
539
|
- `service-cli`: real owners started from the `.env` port and token, reselection of a stopped workspace, edits while running and rotation of the token line.
|
|
536
540
|
- `workspace-landing`: no-default-workspace startup, explicit root refusal and noncreating native/readonly entry.
|
|
537
|
-
- `
|
|
541
|
+
- `gateway-browser`: real same-origin project routing, browser-only authority, retirement on token rotation, continuing ordinary work and genuine multi-owner Stop over loopback.
|
|
538
542
|
- `gateway-recovery`: real crashed owners/resolvers, exact gateway-only release, preserved project fences and unfinished openings, retired/reopened associations, live/remote/changed/linked refusals, generated CLI diagnostics and native-TTY host/process/credential/storage acknowledgments.
|
|
539
543
|
|
|
540
544
|
Regenerate operator/service/native/browser outputs only through their canonical builders; `--check` variants compare new private output without overwriting canonical bytes.
|
|
@@ -542,14 +546,21 @@ WebUI text is keyed by its English source: fixed text goes through `useT().t`, w
|
|
|
542
546
|
The timeline client takes the chosen language from its bridge and is remounted on a switch; browser scenarios pin `locale: "en-US"` so English assertions do not follow the host's `LANG`.
|
|
543
547
|
The browser is conversation-first, including before any project is selected: ordinary chat and explicit Cadence task conversations share its sidebar, while a lower-left dock observes actual Cadence child identities.
|
|
544
548
|
The empty entry has no project welcome screen or central Create shortcut; New conversation offers folder selection until a project is explicitly opened.
|
|
545
|
-
The bottom-right folder control is always present, and
|
|
549
|
+
The bottom-right folder control is always present, and its picker lists recent projects.
|
|
550
|
+
Conversation history belongs to each project owner, so the unselected entry's history section says so and lists the recent projects; choosing one only preselects its folder in the picker.
|
|
551
|
+
An unselected first entry returns to the last selected project, remembered only in that browser as its opaque key, after one readonly conversation listing proves that owner still runs in its associated epoch; this is navigation, never Open.
|
|
552
|
+
A stopped, changed or unknown owner stays stopped: the entry remains and names the last project as not running, and any navigation, Open or folder choice during the check wins.
|
|
546
553
|
Browsing or dismissing the picker never opens a project or sends a message.
|
|
547
|
-
|
|
548
|
-
|
|
554
|
+
The picker has no separate Browse step: its location trail, folder list and Enter in the path entry navigate, and the footer names the exact Open target.
|
|
555
|
+
Open of a typed or recent path first makes one fresh readonly observation and opens only that observation's canonical folder; a failed read opens nothing and keeps the typed path and previous listing in view.
|
|
556
|
+
The footer Open is disabled while any observation is pending, including the first one; a recent entry still opens, because its own fresh observation supersedes the pending read.
|
|
557
|
+
Every navigation makes a fresh readonly observation, including retrying the same path after a read failure; it never replays Open.
|
|
558
|
+
Folder browsing (not Open) accepts `~` for the service account's home and reports a missing folder as `invalid`, a file or linked component as `forbidden` and a read failure as `unavailable`; the gateway passes these public codes on so the picker can explain them.
|
|
549
559
|
One service still owns one checkout.
|
|
550
560
|
The recent-project directory records only explicit project openings in the same private namespace; navigation opens that project's independent authenticated entry rather than changing global cwd, importing Pi sessions or adopting another account's state.
|
|
551
561
|
The center shows ordinary streamed messages or retained task text as Markdown.
|
|
552
|
-
Task tools/context/timeline/
|
|
562
|
+
Task tools/context/timeline/runs and export/link actions live under Details, shown only for a task or child scope; an ordinary conversation has no view switch and folds its tool calls into the transcript.
|
|
563
|
+
Runs puts the current snapshot's owner projection above the retained run pages.
|
|
553
564
|
The right panel defaults to files; its Task details inspector remains bound to the task's current plan/check/change/review context even when viewing a child.
|
|
554
565
|
Historical child links bind exact scope and watermark.
|
|
555
566
|
Bounded history and Back never silently rebase; running conversations offer an explicit new-activity update, and source limitations/progress stay visible even when complete-record metadata is folded.
|
|
@@ -560,6 +571,17 @@ Review the independently enumerated package member list and every emitted body,
|
|
|
560
571
|
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.
|
|
561
572
|
Preserve original license bytes through their precise Git attributes; line-ending normalization must not invalidate audited source/notice hashes.
|
|
562
573
|
|
|
574
|
+
### Release 2.0.17 acceptance snapshot
|
|
575
|
+
|
|
576
|
+
Full `verify` passed on the release candidate in about four minutes: 1908 root tests in 71 files (27 platform skips on Linux), 16 task-entry node tests, 136 web tests, 5 real-browser scenarios in 4 files and the 135-member real-pack audit.
|
|
577
|
+
Observed environment: Linux x86_64, official Node 22.22.1, Bun 1.3.14, Pi SDK 0.84.3 and Chrome for Testing 153.0.8010.12, with four root workers and unchanged test deadlines.
|
|
578
|
+
`verify` no longer runs the slow real-process, PTY, HTTPS-proxy browser and multi-MiB cold-scan suites; those behaviors are not regression-gated in this release.
|
|
579
|
+
Task Send creates a task and starts readonly analysis, and one Confirm plan and execute saves and starts the reviewed plan.
|
|
580
|
+
Fixes in that flow: a fenced receipt read is observed again instead of ending the sequence, a transient context gap no longer aborts an in-flight approval, and a failed observation is re-read after 2s rather than leaving actions disabled until the 30s reconcile.
|
|
581
|
+
Ordinary conversations show no recorded-view switch, and Runs includes the current snapshot's owner projection.
|
|
582
|
+
The first merged attempts failed a time-budgeted search page and the new plan-approval browser step, which also failed on its original commit; both causes were fixed, not retried around.
|
|
583
|
+
No consumer service was installed or restarted, no paid provider was used and no native Windows/macOS qualification is claimed; the `ci/windows` matrix still names the removed vitest projects and was not run.
|
|
584
|
+
|
|
563
585
|
### Release 2.0.16 acceptance snapshot
|
|
564
586
|
|
|
565
587
|
The final code candidate passed all 2070 root tests in 86 files (27 platform skips on Linux), 133 web tests, all 9 real-browser scenarios and the 135-member exact real-pack audit.
|
|
@@ -48,7 +48,7 @@ Keep that link private.
|
|
|
48
48
|
Open Pi in the same project and use `/cadence` for the native client; explicit `cadence stop --workspace <path>` stops only that project.
|
|
49
49
|
Opening another project never changes the cwd or cancels work in the former one.
|
|
50
50
|
The default workbench routes all associated projects through one origin, including a configured HTTPS proxy.
|
|
51
|
-
Its project picker browses directory names readonly; only **Open this project
|
|
51
|
+
Its project picker browses directory names readonly (`~` names the service account's home); only **Open this folder**, or one click on a recent project, starts or reuses an owner, without admitting a task or model call.
|
|
52
52
|
Project navigation remounts only the browser client; the original owner's work continues.
|
|
53
53
|
Browser proxy traffic keeps browser authority and the owner's own attachments, CSRF/build checks, grants and history proofs; native management routes and local-capability headers are not forwarded.
|
|
54
54
|
The gateway also refuses the legacy project-level Open command, so every opening is associated through the workbench instead of returning an independent backend token link.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abelxiaoxing/cadence",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.17",
|
|
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",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"build:operator": "bun scripts/build-operator.mjs",
|
|
88
88
|
"build:service": "bun scripts/build-service.mjs",
|
|
89
89
|
"check:web": "tsc -p web/tsconfig.json && tsc -p web/tsconfig.config.json",
|
|
90
|
-
"test:web": "vitest run --config web/vitest.config.ts",
|
|
90
|
+
"test:web": "node --test test/web/task-entry.node.mjs && vitest run --config web/vitest.config.ts",
|
|
91
91
|
"build:web": "node scripts/build-web.mjs",
|
|
92
92
|
"build:web:check": "node scripts/build-web.mjs --check",
|
|
93
93
|
"test:web:assets-browser": "bun run test:browser",
|
package/src/service-host.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
createServer as createServer2,
|
|
10
10
|
request as request2
|
|
11
11
|
} from "node:http";
|
|
12
|
-
import { homedir as
|
|
12
|
+
import { homedir as homedir5 } from "node:os";
|
|
13
13
|
import { WebSocket, WebSocketServer as WebSocketServer2 } from "ws";
|
|
14
14
|
|
|
15
15
|
// src/service-assets.ts
|
|
@@ -9772,6 +9772,7 @@ import {
|
|
|
9772
9772
|
readSync as readSync4,
|
|
9773
9773
|
realpathSync as realpathSync3
|
|
9774
9774
|
} from "node:fs";
|
|
9775
|
+
import { homedir as homedir4 } from "node:os";
|
|
9775
9776
|
import { dirname as dirname10, isAbsolute as isAbsolute6, join as join12, relative as relative5, resolve as resolve6, sep as sep4 } from "node:path";
|
|
9776
9777
|
|
|
9777
9778
|
// src/worker-redaction.mjs
|
|
@@ -10176,8 +10177,18 @@ class WorkbenchFiles {
|
|
|
10176
10177
|
throw new ContractError("forbidden");
|
|
10177
10178
|
return target;
|
|
10178
10179
|
}
|
|
10180
|
+
browsed(path) {
|
|
10181
|
+
const full = /^~(?:[\\/]|$)/.test(path) ? join12(homedir4(), path.slice(1)) : path || this.root;
|
|
10182
|
+
try {
|
|
10183
|
+
return this.directory(full);
|
|
10184
|
+
} catch (error) {
|
|
10185
|
+
if (error instanceof Error && error.message === "Unsafe directory")
|
|
10186
|
+
throw new ContractError("forbidden");
|
|
10187
|
+
throw error;
|
|
10188
|
+
}
|
|
10189
|
+
}
|
|
10179
10190
|
list(path, directories = false) {
|
|
10180
|
-
const selected2 = directories ? this.
|
|
10191
|
+
const selected2 = directories ? this.browsed(path) : this.selected(path);
|
|
10181
10192
|
if (!safeDirectory(selected2) || sanitizeText(selected2, this.secrets()) !== selected2)
|
|
10182
10193
|
throw new ContractError("forbidden");
|
|
10183
10194
|
const entries = [], dir = opendirSync5(selected2);
|
|
@@ -10370,7 +10381,7 @@ Content-Length: 0\r
|
|
|
10370
10381
|
server.close();
|
|
10371
10382
|
throw error;
|
|
10372
10383
|
}
|
|
10373
|
-
const files = new WorkbenchFiles(
|
|
10384
|
+
const files = new WorkbenchFiles(homedir5(), [store.files.namespace, input.agentDir], () => acquired.access.redactionLiterals());
|
|
10374
10385
|
const assert = () => {
|
|
10375
10386
|
store.assert();
|
|
10376
10387
|
if (!accepting)
|
|
@@ -10730,7 +10741,7 @@ Content-Length: 0\r
|
|
|
10730
10741
|
kind: "workbench",
|
|
10731
10742
|
epoch: auth.epoch,
|
|
10732
10743
|
csrf: auth.csrf,
|
|
10733
|
-
home:
|
|
10744
|
+
home: homedir5(),
|
|
10734
10745
|
projects: store.projects(),
|
|
10735
10746
|
build: build2
|
|
10736
10747
|
});
|