From e9c0ff4d84a69773ae16950e6d8cb0ef224e538f Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 2 Nov 2026 22:36:54 +0000 Subject: [PATCH] feat(chord): Chord v2 is the package's root src/next is src (the main export), src/next-node is src/node with short subpaths (/http, /workers, /plugins, /plugins/runtime, /app, /surfaces, /web, /react, /tui, /tui/launcher); the foundations get /json and /watch; Chord v1 moves to src/old (/old, /old/node) until p2 runs on v2; tests and docs move likewise (test/, docs/, test/old, docs/old). Durable and env import the foundations from their subpaths. --- AGENTS.md | 10 +- README.md | 2 +- packages/chord/CHANGELOG.md | 11 +- packages/chord/README.md | 140 ++++++----------- packages/chord/docs/{next => }/benchmarks.md | 46 +++--- packages/chord/docs/{next => }/decisions.md | 85 ++++++----- .../docs/{next => }/dependencies/book.md | 2 +- .../docs/{next => }/dependencies/index.html | 2 +- .../docs/{next => }/dependencies/model.md | 0 packages/chord/docs/{next => }/design.md | 57 +++---- .../docs/{next => }/durable-observers/book.md | 4 +- .../{next => }/durable-observers/index.html | 4 +- .../docs/{next => }/flow-control/book.md | 0 .../{next => }/flow-control/fold/index.html | 0 .../docs/{next => }/flow-control/index.html | 0 .../{next => }/flow-control/window/index.html | 0 .../{next => }/guide-plugins-hosts/book.md | 16 +- .../{next => }/guide-plugins-hosts/index.html | 15 +- .../docs/{next => }/http-workers/book.md | 10 +- .../docs/{next => }/http-workers/index.html | 10 +- packages/chord/docs/{next => }/i18n/book.md | 0 .../chord/docs/{next => }/i18n/index.html | 0 packages/chord/docs/{next => }/layer-1.md | 6 +- packages/chord/docs/{next => }/layer-2.md | 4 +- packages/chord/docs/old/README.md | 116 ++++++++++++++ packages/chord/docs/{ => old}/guide.md | 4 +- packages/chord/docs/{ => old}/spec.md | 0 packages/chord/docs/{ => old}/tutorial.md | 10 +- .../docs/{next => }/p3-features/README.md | 0 .../chord/docs/{next => }/p3-features/book.md | 4 +- .../chord/docs/{next => }/plugin-authoring.md | 8 +- .../docs/{next => }/plugin-model/book.md | 6 +- .../docs/{next => }/plugin-model/index.html | 6 +- .../docs/{next => }/plugin-primer/book.md | 14 +- .../docs/{next => }/plugin-primer/index.html | 14 +- packages/chord/docs/{next => }/slice-1.md | 4 +- packages/chord/docs/{next => }/slice-10.md | 20 +-- packages/chord/docs/{next => }/slice-11.md | 12 +- packages/chord/docs/{next => }/slice-12.md | 12 +- packages/chord/docs/{next => }/slice-13.md | 8 +- packages/chord/docs/{next => }/slice-2.md | 2 +- packages/chord/docs/{next => }/slice-3a.md | 4 +- packages/chord/docs/{next => }/slice-3b.md | 2 +- packages/chord/docs/{next => }/slice-4.md | 0 packages/chord/docs/{next => }/slice-4a.md | 4 +- packages/chord/docs/{next => }/slice-4b.md | 4 +- packages/chord/docs/{next => }/slice-5.md | 0 packages/chord/docs/{next => }/slice-6a.md | 8 +- packages/chord/docs/{next => }/slice-6b.md | 4 +- packages/chord/docs/{next => }/slice-7a.md | 0 packages/chord/docs/{next => }/slice-7b.md | 2 +- .../chord/docs/{next => }/slice-7b/book.md | 50 +++--- .../chord/docs/{next => }/slice-7b/index.html | 50 +++--- packages/chord/docs/{next => }/slice-7c.md | 12 +- packages/chord/docs/{next => }/slice-8.md | 0 packages/chord/docs/{next => }/slices.md | 43 +++--- packages/chord/docs/{next => }/store/book.md | 4 +- .../chord/docs/{next => }/store/index.html | 4 +- .../docs/{next => }/store/walkthrough.md | 6 +- .../chord/docs/{next => }/theming/book.md | 0 .../chord/docs/{next => }/theming/index.html | 0 packages/chord/package.json | 96 +++++++++--- .../chord/src/{next => }/contracts/README.md | 0 .../chord/src/{next => }/contracts/accepts.ts | 2 +- .../src/{next => }/contracts/contract.ts | 4 +- .../chord/src/{next => }/contracts/declare.ts | 0 .../chord/src/{next => }/contracts/evolve.ts | 0 .../src/{next => }/contracts/fingerprint.ts | 2 +- .../chord/src/{next => }/contracts/history.ts | 0 .../src/{next => }/contracts/host-kind.ts | 0 .../chord/src/{next => }/contracts/index.ts | 0 .../src/{next => }/contracts/internal.ts | 0 .../chord/src/{next => }/contracts/names.ts | 0 .../chord/src/{next => }/contracts/params.ts | 2 +- .../chord/src/{next => }/contracts/schema.ts | 0 .../src/{next => }/contracts/snapshot.ts | 2 +- packages/chord/src/{next => }/data/README.md | 0 packages/chord/src/{next => }/data/args.ts | 2 +- packages/chord/src/{next => }/data/errors.ts | 2 +- packages/chord/src/{next => }/data/failure.ts | 0 packages/chord/src/{next => }/data/index.ts | 0 .../chord/src/{next => }/data/internal.ts | 0 packages/chord/src/{next => }/data/params.ts | 2 +- .../chord/src/{next => }/data/principal.ts | 4 +- .../chord/src/{next => }/data/validator.ts | 2 +- .../chord/src/{next => }/documents/README.md | 2 +- .../{next => }/documents/address-source.ts | 4 +- .../src/{next => }/documents/definition.ts | 6 +- .../src/{next => }/documents/documents.ts | 2 +- .../chord/src/{next => }/documents/fence.ts | 0 .../chord/src/{next => }/documents/handles.ts | 6 +- .../chord/src/{next => }/documents/index.ts | 0 .../src/{next => }/documents/internal.ts | 0 .../src/{next => }/documents/keyed-slot.ts | 6 +- .../chord/src/{next => }/documents/line.ts | 0 .../src/{next => }/documents/persistence.ts | 4 +- .../src/{next => }/documents/residency.ts | 2 +- .../chord/src/{next => }/documents/slot.ts | 4 +- .../src/{next => }/documents/transaction.ts | 4 +- packages/chord/src/{next => }/host/README.md | 6 +- .../chord/src/{next => }/host/activity.ts | 4 +- packages/chord/src/{next => }/host/adapted.ts | 2 +- packages/chord/src/{next => }/host/attempt.ts | 6 +- packages/chord/src/{next => }/host/backoff.ts | 0 packages/chord/src/{next => }/host/ctx.ts | 2 +- .../chord/src/{next => }/host/deadline.ts | 0 .../chord/src/{next => }/host/dependencies.ts | 0 .../chord/src/{next => }/host/destination.ts | 2 +- packages/chord/src/{next => }/host/facet.ts | 2 +- packages/chord/src/{next => }/host/follow.ts | 8 +- packages/chord/src/{next => }/host/host.ts | 6 +- packages/chord/src/{next => }/host/index.ts | 0 .../chord/src/{next => }/host/internal.ts | 0 packages/chord/src/{next => }/host/members.ts | 2 +- packages/chord/src/{next => }/host/native.ts | 2 +- packages/chord/src/{next => }/host/object.ts | 4 +- packages/chord/src/{next => }/host/parked.ts | 2 +- .../chord/src/{next => }/host/presence.ts | 6 +- .../chord/src/{next => }/host/ref-state.ts | 4 +- .../src/{next => }/host/reference-keys.ts | 2 +- .../src/{next => }/host/reference-source.ts | 8 +- .../chord/src/{next => }/host/reference.ts | 6 +- .../chord/src/{next => }/host/retry-on.ts | 0 .../chord/src/{next => }/host/revocation.ts | 4 +- packages/chord/src/{next => }/host/root.ts | 2 +- packages/chord/src/{next => }/host/route.ts | 2 +- .../chord/src/{next => }/host/routines.ts | 12 +- packages/chord/src/{next => }/host/sleep.ts | 2 +- packages/chord/src/{next => }/host/staging.ts | 4 +- packages/chord/src/{next => }/host/unbound.ts | 0 packages/chord/src/{next => }/host/uuid.ts | 0 packages/chord/src/index.ts | 144 +++++++----------- packages/chord/src/{next => }/jobs/README.md | 0 .../chord/src/{next => }/jobs/definition.ts | 0 packages/chord/src/{next => }/jobs/index.ts | 0 .../chord/src/{next => }/jobs/internal.ts | 0 packages/chord/src/{next => }/jobs/job.ts | 8 +- .../chord/src/{next => }/jobs/persisted.ts | 2 +- packages/chord/src/{next => }/jobs/records.ts | 6 +- .../chord/src/{next => }/jobs/run-states.ts | 4 +- packages/chord/src/{next => }/jobs/run.ts | 4 +- packages/chord/src/{next => }/jobs/running.ts | 6 +- packages/chord/src/{next => }/jobs/stored.ts | 2 +- packages/chord/src/{next => }/link/README.md | 2 +- packages/chord/src/{next => }/link/binary.ts | 0 packages/chord/src/{next => }/link/channel.ts | 2 +- packages/chord/src/{next => }/link/errors.ts | 2 +- packages/chord/src/{next => }/link/index.ts | 0 .../chord/src/{next => }/link/internal.ts | 0 packages/chord/src/{next => }/link/ipc.ts | 0 packages/chord/src/{next => }/link/link.ts | 0 packages/chord/src/{next => }/link/message.ts | 2 +- packages/chord/src/{next => }/link/part.ts | 2 +- packages/chord/src/{next => }/link/text.ts | 0 packages/chord/src/{next => }/link/values.ts | 0 .../chord/src/{next => }/link/websocket.ts | 0 packages/chord/src/next/index.ts | 52 ------- .../src/{next-node => node}/app/README.md | 6 +- .../chord/src/{next-node => node}/app/app.ts | 12 +- .../src/{next-node => node}/app/archive.ts | 2 +- .../chord/src/{next-node => node}/app/data.ts | 10 +- .../app/ephemeral-sessions.ts | 2 +- .../src/{next-node => node}/app/ephemeral.ts | 4 +- .../src/{next-node => node}/app/files.ts | 10 +- .../src/{next-node => node}/app/index.ts | 6 +- .../chord/src/{next-node => node}/app/info.ts | 8 +- .../src/{next-node => node}/app/invite.ts | 4 +- .../src/{next-node => node}/app/layout.ts | 2 +- .../src/{next-node => node}/app/owner.ts | 4 +- .../src/{next-node => node}/app/pairing.ts | 4 +- .../src/{next-node => node}/app/secrets.ts | 0 .../src/{next-node => node}/app/sessions.ts | 8 +- .../chord/src/{next-node => node}/app/tar.ts | 0 .../src/{next-node => node}/app/uploads.ts | 4 +- .../src/{next-node => node}/app/users.ts | 10 +- .../src/{next-node => node}/app/worker.ts | 6 +- .../src/{next-node => node}/compression.ts | 5 +- .../src/{next-node => node}/http/README.md | 13 +- .../src/{next-node => node}/http/admission.ts | 0 .../{next-node => node}/http/authenticate.ts | 4 +- .../src/{next-node => node}/http/cookies.ts | 0 .../src/{next-node => node}/http/file.ts | 0 .../src/{next-node => node}/http/headers.ts | 0 .../src/{next-node => node}/http/http.ts | 8 +- .../src/{next-node => node}/http/incoming.ts | 0 .../src/{next-node => node}/http/index.ts | 2 +- .../src/{next-node => node}/http/node.ts | 0 .../src/{next-node => node}/http/request.ts | 0 .../src/{next-node => node}/http/response.ts | 2 +- .../src/{next-node => node}/http/router.ts | 4 +- .../src/{next-node => node}/http/upgrades.ts | 6 +- .../src/{next-node => node}/plugins/README.md | 25 ++- .../src/{next-node => node}/plugins/build.ts | 2 +- .../plugins/css-modules.ts | 0 .../{next-node => node}/plugins/discover.ts | 2 +- .../{next-node => node}/plugins/evaluate.ts | 8 +- .../src/{next-node => node}/plugins/index.ts | 8 +- .../{next-node => node}/plugins/install.ts | 2 +- .../{next-node => node}/plugins/plugins.ts | 8 +- .../{next-node => node}/plugins/runtime.ts | 6 +- .../src/{next-node => node}/plugins/stack.ts | 0 .../{next-node => node}/plugins/testing.ts | 12 +- .../{next-node => node}/plugins/watcher.ts | 2 +- .../{next-node => node}/surfaces/README.md | 5 +- .../{next-node => node}/surfaces/bundle.ts | 0 .../{next-node => node}/surfaces/current.ts | 8 +- .../src/{next-node => node}/surfaces/index.ts | 4 +- .../{next-node => node}/surfaces/published.ts | 6 +- .../{next-node => node}/surfaces/served.ts | 0 .../src/{next-node => node}/surfaces/tui.ts | 4 +- .../src/{next-node => node}/surfaces/web.ts | 6 +- .../src/{next-node => node}/tui/README.md | 8 +- .../src/{next-node => node}/tui/actions.ts | 2 +- .../{next-node => node}/tui/credentials.ts | 0 .../src/{next-node => node}/tui/filter.ts | 0 .../src/{next-node => node}/tui/index.ts | 4 +- .../src/{next-node => node}/tui/launcher.ts | 4 +- .../chord/src/{next-node => node}/tui/pipe.ts | 2 +- .../src/{next-node => node}/tui/sandbox.ts | 2 +- .../src/{next-node => node}/workers/README.md | 6 +- .../{next-node => node}/workers/control.ts | 8 +- .../src/{next-node => node}/workers/index.ts | 2 +- .../src/{next-node => node}/workers/lock.ts | 0 .../src/{next-node => node}/workers/main.ts | 8 +- .../{next-node => node}/workers/process.ts | 4 +- .../{next-node => node}/workers/workers.ts | 10 +- packages/chord/src/{ => old}/cell.ts | 2 +- packages/chord/src/{ => old}/cluster.ts | 0 packages/chord/src/{ => old}/connection.ts | 2 +- packages/chord/src/{ => old}/contract.ts | 0 packages/chord/src/{ => old}/declare.ts | 0 packages/chord/src/{ => old}/errors.ts | 0 packages/chord/src/{ => old}/host.ts | 2 +- packages/chord/src/old/index.ts | 96 ++++++++++++ packages/chord/src/{ => old}/link.ts | 0 packages/chord/src/{ => old}/loader.ts | 0 packages/chord/src/{ => old}/manager.ts | 0 packages/chord/src/{ => old}/node.ts | 2 +- packages/chord/src/{ => old}/object.ts | 0 packages/chord/src/{ => old}/publish.ts | 0 packages/chord/src/{ => old}/registry.ts | 0 packages/chord/src/{ => old}/reload.ts | 0 packages/chord/src/{ => old}/remote.ts | 2 +- packages/chord/src/{ => old}/schema.ts | 0 packages/chord/src/{ => old}/state.ts | 4 +- packages/chord/src/{ => old}/types.ts | 2 +- packages/chord/src/{ => old}/websocket.ts | 0 packages/chord/src/{ => old}/wire.ts | 0 .../chord/src/{next-react => react}/README.md | 6 +- .../chord/src/{next-react => react}/hooks.ts | 10 +- .../chord/src/{next-react => react}/index.ts | 3 +- .../chord/src/{next-react => react}/stores.ts | 0 .../chord/src/{next => }/registries/README.md | 0 .../src/{next => }/registries/contribution.ts | 0 .../src/{next => }/registries/entries.ts | 0 .../chord/src/{next => }/registries/index.ts | 0 .../src/{next => }/registries/internal.ts | 0 .../chord/src/{next => }/registries/record.ts | 0 .../src/{next => }/registries/registry.ts | 4 +- .../chord/src/{next => }/registries/value.ts | 0 .../chord/src/{next => }/remote/README.md | 0 packages/chord/src/{next => }/remote/calls.ts | 0 .../chord/src/{next => }/remote/consumer.ts | 2 +- packages/chord/src/{next => }/remote/hold.ts | 6 +- .../chord/src/{next => }/remote/host-link.ts | 4 +- .../chord/src/{next => }/remote/internal.ts | 0 packages/chord/src/{next => }/remote/path.ts | 0 .../chord/src/{next => }/remote/provider.ts | 2 +- packages/chord/src/{next => }/remote/relay.ts | 0 .../src/{next => }/remote/remote-object.ts | 4 +- .../chord/src/{next => }/remote/replica.ts | 6 +- packages/chord/src/{next => }/state/README.md | 0 packages/chord/src/{next => }/state/batch.ts | 2 +- packages/chord/src/{next => }/state/derive.ts | 6 +- packages/chord/src/{next => }/state/index.ts | 2 +- .../chord/src/{next => }/state/internal.ts | 0 .../src/{next => }/state/native-source.ts | 4 +- .../chord/src/{next => }/state/watchable.ts | 8 +- .../chord/src/{next => }/state/writable.ts | 4 +- packages/chord/src/{next => }/store/README.md | 4 +- .../chord/src/{next => }/store/adapter.ts | 4 +- .../chord/src/{next => }/store/allocator.ts | 0 .../chord/src/{next => }/store/applier.ts | 2 +- .../chord/src/{next => }/store/apply-batch.ts | 4 +- .../chord/src/{next => }/store/archive.ts | 2 +- .../chord/src/{next => }/store/backend.ts | 2 +- .../chord/src/{next => }/store/catalog.ts | 2 +- packages/chord/src/{next => }/store/claims.ts | 0 .../chord/src/{next => }/store/columns.ts | 0 packages/chord/src/{next => }/store/engine.ts | 6 +- .../chord/src/{next => }/store/evaluate.ts | 2 +- packages/chord/src/{next => }/store/export.ts | 6 +- .../chord/src/{next => }/store/expression.ts | 2 +- packages/chord/src/{next => }/store/import.ts | 4 +- packages/chord/src/{next => }/store/index.ts | 0 .../chord/src/{next => }/store/json-column.ts | 4 +- packages/chord/src/{next => }/store/jsonl.ts | 0 packages/chord/src/{next => }/store/outbox.ts | 2 +- packages/chord/src/{next => }/store/query.ts | 2 +- .../chord/src/{next => }/store/refusal.ts | 0 packages/chord/src/{next => }/store/rows.ts | 6 +- packages/chord/src/{next => }/store/schema.ts | 2 +- packages/chord/src/{next => }/store/sql.ts | 2 +- packages/chord/src/{next => }/store/step.ts | 2 +- packages/chord/src/{next => }/store/store.ts | 4 +- .../src/{next => }/store/table-changes.ts | 2 +- .../src/{next => }/store/table-evolve.ts | 0 .../src/{next => }/store/table-handle.ts | 4 +- .../src/{next => }/store/table-history.ts | 0 .../src/{next => }/store/table-migration.ts | 4 +- .../src/{next => }/store/table-writes.ts | 0 packages/chord/src/{next => }/store/table.ts | 0 packages/chord/src/{next => }/store/text.ts | 0 packages/chord/src/{next => }/store/writes.ts | 0 .../chord/src/{next => }/surfaces/README.md | 4 +- .../src/{next => }/surfaces/active-theme.ts | 2 +- .../chord/src/{next => }/surfaces/client.ts | 2 +- .../src/{next => }/surfaces/connection.ts | 0 .../chord/src/{next => }/surfaces/index.ts | 0 .../chord/src/{next => }/surfaces/loaded.ts | 2 +- .../src/{next => }/surfaces/registered.ts | 0 .../chord/src/{next => }/surfaces/scripts.ts | 0 .../src/{next => }/surfaces/theme-choice.ts | 2 +- .../chord/src/{next => }/surfaces/themes.ts | 2 +- .../chord/src/{next-tui => tui}/README.md | 6 +- .../chord/src/{next-tui => tui}/bridge.ts | 2 +- .../chord/src/{next-tui => tui}/channel.ts | 2 +- .../chord/src/{next-tui => tui}/frames.ts | 0 packages/chord/src/{next-tui => tui}/index.ts | 6 +- .../chord/src/{next-tui => tui}/runtime.ts | 6 +- packages/chord/src/{next-tui => tui}/scope.ts | 8 +- .../chord/src/{next-tui => tui}/terminal.ts | 0 packages/chord/src/{next-tui => tui}/theme.ts | 2 +- .../chord/src/{next-web => web}/README.md | 6 +- .../src/{next-web => web}/environment.ts | 2 +- packages/chord/src/{next-web => web}/index.ts | 4 +- packages/chord/src/{next-web => web}/page.ts | 8 +- .../chord/src/{next-web => web}/scripts.ts | 4 +- .../chord/src/{next-web => web}/themes.ts | 6 +- packages/chord/test/{next => }/bench/calls.ts | 10 +- .../test/{next => }/bench/compression.ts | 16 +- .../chord/test/{next => }/bench/derives.ts | 12 +- packages/chord/test/{next => }/bench/http.ts | 8 +- packages/chord/test/{next => }/bench/jobs.ts | 16 +- packages/chord/test/{next => }/bench/links.ts | 16 +- .../chord/test/{next => }/bench/plugins.ts | 12 +- .../chord/test/{next => }/bench/registries.ts | 12 +- packages/chord/test/{next => }/bench/relay.ts | 12 +- .../chord/test/{next => }/bench/reload.ts | 12 +- packages/chord/test/{next => }/bench/store.ts | 46 +++--- .../chord/test/{next => }/bench/workers.ts | 26 ++-- .../test/{next => }/contracts/accepts.test.ts | 4 +- .../{next => }/contracts/contract.test.ts | 12 +- .../test/{next => }/contracts/declare.test.ts | 15 +- .../test/{next => }/contracts/evolve.test.ts | 8 +- .../{next => }/contracts/fingerprint.test.ts | 6 +- .../test/{next => }/contracts/history.test.ts | 8 +- .../{next => }/contracts/host-kind.test.ts | 10 +- .../test/{next => }/contracts/params.test.ts | 14 +- .../test/{next => }/contracts/schema.test.ts | 4 +- .../{next => }/contracts/snapshot.test.ts | 4 +- .../chord/test/{next => }/data/args.test.ts | 8 +- .../chord/test/{next => }/data/errors.test.ts | 4 +- .../test/{next => }/data/failure.test.ts | 4 +- .../chord/test/{next => }/data/params.test.ts | 12 +- .../test/{next => }/data/principal.test.ts | 4 +- .../test/{next => }/data/validator.test.ts | 10 +- .../documents/address-source.test.ts | 10 +- .../{next => }/documents/definition.test.ts | 6 +- .../{next => }/documents/documents.test.ts | 6 +- .../test/{next => }/documents/fence.test.ts | 2 +- .../test/{next => }/documents/handles.test.ts | 8 +- .../{next => }/documents/keyed-slot.test.ts | 18 +-- .../test/{next => }/documents/line.test.ts | 2 +- .../{next => }/documents/persistence.test.ts | 16 +- .../{next => }/documents/residency.test.ts | 4 +- .../test/{next => }/documents/slot.test.ts | 19 +-- .../{next => }/documents/transaction.test.ts | 24 +-- .../test/{next => }/examples/01-objects.ts | 12 +- .../test/{next => }/examples/02-documents.ts | 10 +- .../test/{next => }/examples/03-derives.ts | 12 +- .../test/{next => }/examples/04-watches.ts | 10 +- .../test/{next => }/examples/05-errors.ts | 12 +- .../test/{next => }/examples/06-natives.ts | 12 +- .../test/{next => }/examples/07-failures.ts | 12 +- .../test/{next => }/examples/08-remote.ts | 14 +- .../test/{next => }/examples/09-calls.ts | 12 +- .../test/{next => }/examples/10-drops.ts | 12 +- .../examples/11-linger-and-retry.ts | 14 +- .../test/{next => }/examples/12-routes.ts | 14 +- .../test/{next => }/examples/13-relay.ts | 14 +- .../{next => }/examples/14-flow-control.ts | 12 +- .../test/{next => }/examples/15-revocation.ts | 14 +- .../examples/16-presence-and-activity.ts | 10 +- .../examples/17-limits-and-compression.ts | 16 +- .../test/{next => }/examples/18-routines.ts | 10 +- .../chord/test/{next => }/examples/19-jobs.ts | 18 +-- .../test/{next => }/examples/20-tables.ts | 12 +- .../examples/21-persisted-documents.ts | 14 +- .../test/{next => }/examples/22-migrations.ts | 12 +- .../{next => }/examples/23-keyed-watches.ts | 10 +- .../{next => }/examples/24-keyed-members.ts | 10 +- .../{next => }/examples/25-export-import.ts | 14 +- .../{next => }/examples/28-persisted-jobs.ts | 16 +- .../test/{next => }/examples/29-registries.ts | 10 +- .../test/{next => }/examples/30-host-root.ts | 10 +- .../examples/31-parked-dependencies.ts | 16 +- .../test/{next => }/examples/32-startup.ts | 12 +- .../test/{next => }/examples/33-reload.ts | 12 +- .../test/{next => }/examples/34-versions.ts | 25 +-- .../{next => }/examples/35-plugins/main.ts | 16 +- .../35-plugins/plugins/clock/package.json | 0 .../35-plugins/plugins/clock/server.ts | 2 +- .../35-plugins/plugins/contracts/contract.ts | 2 +- .../35-plugins/plugins/contracts/package.json | 0 .../35-plugins/plugins/notes/label.ts | 0 .../35-plugins/plugins/notes/package.json | 0 .../35-plugins/plugins/notes/server.ts | 2 +- .../35-plugins/plugins/notes/worker.ts | 2 +- .../examples/36-plugin-failures/main.ts | 16 +- .../plugins/boot/package.json | 0 .../36-plugin-failures/plugins/boot/server.ts | 2 +- .../plugins/cache/package.json | 0 .../plugins/cache/server.ts | 2 +- .../plugins/counter/package.json | 0 .../plugins/counter/server.ts | 2 +- .../plugins/forecast/package.json | 0 .../plugins/forecast/server.ts | 2 +- .../plugins/greeter/label.ts | 0 .../plugins/greeter/package.json | 0 .../plugins/greeter/server.ts | 2 +- .../plugins/prices/contract.ts | 2 +- .../plugins/prices/package.json | 0 .../plugins/prices/server.ts | 2 +- .../plugins/summary/package.json | 0 .../plugins/summary/server.ts | 2 +- .../plugins/weather/contract.ts | 2 +- .../plugins/weather/package.json | 0 .../plugins/weather/server.ts | 2 +- .../examples/37-plugin-imports/app/index.ts | 0 .../examples/37-plugin-imports/app/legacy.cjs | 0 .../deps/example-greeting/index.js | 0 .../deps/example-greeting/package.json | 0 .../deps/example-native/index.js | 0 .../deps/example-native/package.json | 0 .../examples/37-plugin-imports/fake-npm.mjs | 0 .../examples/37-plugin-imports/main.ts | 12 +- .../plugins/paths/package.json | 0 .../37-plugin-imports/plugins/paths/server.ts | 2 +- .../plugins/refused/other.ts | 0 .../plugins/refused/package.json | 0 .../plugins/refused/server.ts | 2 +- .../plugins/report/data/rates.json | 0 .../37-plugin-imports/plugins/report/env.d.ts | 0 .../plugins/report/package.json | 0 .../plugins/report/server.ts | 4 +- .../plugins/ruler/package.json | 0 .../37-plugin-imports/plugins/ruler/server.ts | 2 +- .../plugins/shapes/contract.ts | 2 +- .../plugins/shapes/package.json | 0 .../37-plugin-imports/plugins/shapes/units.ts | 0 .../38-watch-and-rollout/app/config.ts | 0 .../incoming/extra/package.json | 0 .../incoming/extra/server.ts | 2 +- .../examples/38-watch-and-rollout/main.ts | 12 +- .../plugins/contracts/contract.ts | 2 +- .../plugins/contracts/package.json | 0 .../plugins/notes/label.ts | 0 .../plugins/notes/package.json | 0 .../plugins/notes/server.ts | 2 +- .../plugins/notes/worker.ts | 2 +- .../plugins/old/package.json | 0 .../plugins/old/server.ts | 2 +- .../plugins/tags/package.json | 0 .../plugins/tags/server.ts | 2 +- .../plugins/tags/worker.ts | 2 +- .../examples/39-browser-build/main.ts | 14 +- .../plugins/bad-web/package.json | 0 .../39-browser-build/plugins/bad-web/web.ts | 2 +- .../plugins/gallery/assets.d.ts | 0 .../plugins/gallery/assets/logo.svg | 0 .../plugins/gallery/gallery.css | 0 .../plugins/gallery/package.json | 0 .../39-browser-build/plugins/gallery/web.ts | 2 +- .../test/{next => }/examples/40-http/main.ts | 14 +- .../40-http/plugins/notes/files/hello.md | 0 .../40-http/plugins/notes/package.json | 0 .../examples/40-http/plugins/notes/server.ts | 6 +- .../{next => }/examples/41-workers/main.ts | 14 +- .../41-workers/plugins/sessions/contract.ts | 2 +- .../41-workers/plugins/sessions/package.json | 0 .../41-workers/plugins/sessions/worker.ts | 2 +- .../41-workers}/worker.ts | 10 +- .../examples/42-worker-crash/main.ts | 14 +- .../plugins/sessions/contract.ts | 2 +- .../plugins/sessions/package.json | 0 .../plugins/sessions/worker.ts | 2 +- .../42-worker-crash}/worker.ts | 10 +- .../{next => }/examples/43-rollout/main.ts | 18 +-- .../43-rollout/plugins/notes/contract.ts | 2 +- .../43-rollout/plugins/notes/label.ts | 0 .../43-rollout/plugins/notes/package.json | 0 .../43-rollout/plugins/notes/server.ts | 2 +- .../43-rollout/plugins/notes/worker.ts | 2 +- .../43-rollout}/worker.ts | 10 +- .../{next => }/examples/44-http-wraps/main.ts | 14 +- .../44-http-wraps/plugins/audit/package.json | 0 .../44-http-wraps/plugins/audit/server.ts | 4 +- .../44-http-wraps/plugins/notes/package.json | 0 .../44-http-wraps/plugins/notes/server.ts | 4 +- .../examples/45-plugin-socket/main.ts | 14 +- .../plugins/echo/package.json | 0 .../45-plugin-socket/plugins/echo/server.ts | 4 +- .../examples/46-allowed-hosts/main.ts | 16 +- .../plugins/tunnel/package.json | 0 .../46-allowed-hosts/plugins/tunnel/server.ts | 4 +- .../examples/47-http-own-server/main.ts | 14 +- .../plugins/notes/package.json | 0 .../plugins/notes/server.ts | 4 +- .../examples/48-http-baseline/main.ts | 14 +- .../plugins/notes/package.json | 0 .../48-http-baseline/plugins/notes/server.ts | 4 +- .../examples/49-plugin-api/app/v2.ts | 0 .../examples/49-plugin-api/app/v3.ts | 4 +- .../examples/49-plugin-api/app/v3/server.ts | 0 .../examples/49-plugin-api/app/v3/web.ts | 2 +- .../examples/49-plugin-api/app/v3/worker.ts | 2 +- .../{next => }/examples/49-plugin-api/main.ts | 8 +- .../49-plugin-api/plugins/ancient/env.d.ts | 0 .../plugins/ancient/package.json | 0 .../49-plugin-api/plugins/ancient/server.ts | 0 .../49-plugin-api/plugins/direct/package.json | 0 .../49-plugin-api/plugins/direct/server.ts | 2 +- .../49-plugin-api/plugins/hello/package.json | 0 .../49-plugin-api/plugins/hello/server.ts | 0 .../49-plugin-api/plugins/legacy/package.json | 0 .../49-plugin-api/plugins/legacy/server.ts | 0 .../49-plugin-api/plugins/mixed/package.json | 0 .../49-plugin-api/plugins/mixed/server.ts | 0 .../49-plugin-api/plugins/panel/package.json | 0 .../49-plugin-api/plugins/panel/server.ts | 0 .../49-plugin-api/plugins/panel/web.ts | 0 .../examples/50-plugin-imports/main.ts | 10 +- .../plugins/notes/contract.ts | 0 .../plugins/notes/contract.web.ts | 0 .../plugins/notes/package.json | 0 .../50-plugin-imports/plugins/notes/server.ts | 0 .../plugins/peek/package.json | 0 .../50-plugin-imports/plugins/peek/server.ts | 0 .../50-plugin-imports/plugins/peek/view.ts | 0 .../plugins/search/package.json | 0 .../plugins/search/server.ts | 0 .../50-plugin-imports/plugins/search/web.ts | 0 .../50-plugin-imports/user/reach/package.json | 0 .../50-plugin-imports/user/reach/server.ts | 0 .../50-plugin-imports/user/stats/env.d.ts | 0 .../50-plugin-imports/user/stats/package.json | 0 .../50-plugin-imports/user/stats/server.ts | 0 .../50-plugin-imports/words/package.json | 0 .../examples/50-plugin-imports/words/words.ts | 0 .../examples/51-single-file-plugin/main.ts | 10 +- .../plugins/bad.server.ts | 0 .../plugins/clock.server.ts | 0 .../plugins/hello.server.ts | 0 .../plugins/hello.web.ts | 0 .../51-single-file-plugin/plugins/helper.ts | 0 .../examples/52-test-plugin/main.ts | 6 +- .../52-test-plugin/plugins/notes/contract.ts | 0 .../52-test-plugin/plugins/notes/package.json | 0 .../52-test-plugin/plugins/stats/package.json | 0 .../52-test-plugin/plugins/stats/worker.ts | 0 .../examples/53-app/app/principals.ts | 0 .../test/{next => }/examples/53-app/app/v1.ts | 6 +- .../examples/53-app/app/v1/server.ts | 4 +- .../test/{next => }/examples/53-app/client.ts | 0 .../test/{next => }/examples/53-app/main.ts | 4 +- .../examples/53-app/plugins/home/package.json | 0 .../examples/53-app/plugins/home/server.ts | 0 .../examples/53-app/plugins/notes/contract.ts | 0 .../53-app/plugins/notes/package.json | 0 .../examples/53-app/plugins/notes/server.ts | 0 .../examples/53-app/plugins/notes/worker.ts | 0 .../test/{next => }/examples/53-app/start.ts | 4 +- .../test/{next => }/examples/53-app/worker.ts | 2 +- .../examples/54-app-sessions/main.ts | 6 +- .../{next => }/examples/55-app-export/main.ts | 4 +- .../examples/56-web/app/principals.ts | 0 .../test/{next => }/examples/56-web/app/v1.ts | 2 +- .../{next => }/examples/56-web/app/v1/tui.ts | 2 +- .../{next => }/examples/56-web/app/v1/web.ts | 2 +- .../{next => }/examples/56-web/headless.ts | 2 +- .../test/{next => }/examples/56-web/main.ts | 8 +- .../56-web/plugins/clock/package.json | 0 .../examples/56-web/plugins/clock/web.ts | 0 .../56-web/plugins/notes/package.json | 0 .../examples/56-web/plugins/notes/tui.ts | 0 .../examples/56-web/plugins/notes/web.ts | 0 .../test/{next => }/examples/56-web/start.ts | 6 +- .../{next => }/examples/56-web/tui/main.ts | 6 +- .../{next => }/examples/56-web/web/main.ts | 8 +- .../test/{next => }/examples/57-tui/main.ts | 10 +- .../{next => }/examples/57-tui/terminal.ts | 4 +- .../{next => }/examples/58-themes/main.ts | 14 +- .../58-themes/plugins/midnight.web.ts | 0 .../58-themes/plugins/solarized/package.json | 0 .../58-themes/plugins/solarized/theme.ts | 0 .../58-themes/plugins/solarized/tui.ts | 0 .../58-themes/plugins/solarized/web.ts | 0 .../examples/59-chat/app/principals.ts | 0 .../{next => }/examples/59-chat/app/v1.ts | 18 +-- .../examples/59-chat/app/v1/server.ts | 4 +- .../examples/59-chat/app/v1/worker.ts | 2 +- .../test/{next => }/examples/59-chat/main.ts | 8 +- .../59-chat/plugins/chat/package.json | 0 .../examples/59-chat/plugins/chat/server.ts | 0 .../examples/59-chat/plugins/chat/worker.ts | 0 .../examples/59-chat/plugins/login.server.ts | 0 .../test/{next => }/examples/59-chat/start.ts | 6 +- .../{next => }/examples/59-chat/tui/main.ts | 4 +- .../{next => }/examples/59-chat/web/main.ts | 6 +- .../{next => }/examples/59-chat/web/style.css | 0 .../{next => }/examples/59-chat/worker.ts | 2 +- .../examples/60-session-sync/main.ts | 10 +- .../examples/60-session-sync/radius.ts | 14 +- .../examples/60-session-sync/session.ts | 10 +- .../examples/60-session-sync/sync.ts | 8 +- .../test/{next => }/host/activity.test.ts | 8 +- .../test/{next => }/host/adapted.test.ts | 12 +- .../test/{next => }/host/attempt.test.ts | 30 ++-- .../test/{next => }/host/backoff.test.ts | 2 +- .../chord/test/{next => }/host/ctx.test.ts | 12 +- .../test/{next => }/host/deadline.test.ts | 2 +- .../test/{next => }/host/dependencies.test.ts | 12 +- .../chord/test/{next => }/host/facet.test.ts | 10 +- .../chord/test/{next => }/host/follow.test.ts | 18 +-- .../chord/test/{next => }/host/host.test.ts | 33 ++-- .../test/{next => }/host/members.test.ts | 4 +- .../chord/test/{next => }/host/native.test.ts | 10 +- .../chord/test/{next => }/host/object.test.ts | 22 +-- .../chord/test/{next => }/host/parked.test.ts | 6 +- .../test/{next => }/host/presence.test.ts | 14 +- .../test/{next => }/host/ref-state.test.ts | 8 +- .../{next => }/host/reference-keys.test.ts | 12 +- .../{next => }/host/reference-source.test.ts | 18 +-- .../test/{next => }/host/reference.test.ts | 24 +-- .../test/{next => }/host/retry-on.test.ts | 14 +- .../test/{next => }/host/revocation.test.ts | 14 +- .../chord/test/{next => }/host/root.test.ts | 8 +- .../chord/test/{next => }/host/route.test.ts | 8 +- .../test/{next => }/host/routines.test.ts | 16 +- .../chord/test/{next => }/host/sleep.test.ts | 4 +- .../test/{next => }/host/staging.test.ts | 18 +-- .../test/{next => }/host/unbound.test.ts | 22 +-- .../test/{next => }/jobs/definition.test.ts | 6 +- .../chord/test/{next => }/jobs/job.test.ts | 23 ++- .../test/{next => }/jobs/persisted.test.ts | 26 ++-- .../test/{next => }/jobs/records.test.ts | 16 +- .../chord/test/{next => }/jobs/run.test.ts | 6 +- .../test/{next => }/jobs/running.test.ts | 10 +- packages/chord/test/json.test.ts | 2 +- .../test/{next => }/link/channel.test.ts | 12 +- .../chord/test/{next => }/link/errors.test.ts | 4 +- .../test/{next => }/link/fixtures/ipc-echo.ts | 2 +- .../chord/test/{next => }/link/ipc.test.ts | 2 +- .../chord/test/{next => }/link/link.test.ts | 6 +- .../test/{next => }/link/message.test.ts | 6 +- .../chord/test/{next => }/link/part.test.ts | 4 +- .../chord/test/{next => }/link/values.test.ts | 4 +- .../test/{next => }/link/websocket.test.ts | 6 +- .../test/{next-node => node}/app/app.test.ts | 8 +- .../{next-node => node}/app/archive.test.ts | 6 +- .../app/ephemeral-sessions.test.ts | 2 +- .../{next-node => node}/app/ephemeral.test.ts | 4 +- .../{next-node => node}/app/files.test.ts | 4 +- .../test/{next-node => node}/app/info.test.ts | 4 +- .../{next-node => node}/app/invite.test.ts | 4 +- .../{next-node => node}/app/layout.test.ts | 4 +- .../{next-node => node}/app/owner.test.ts | 4 +- .../{next-node => node}/app/pairing.test.ts | 4 +- .../{next-node => node}/app/secrets.test.ts | 2 +- .../{next-node => node}/app/sessions.test.ts | 4 +- .../test/{next-node => node}/app/support.ts | 10 +- .../test/{next-node => node}/app/tar.test.ts | 2 +- .../{next-node => node}/app/uploads.test.ts | 2 +- .../{next-node => node}/app/users.test.ts | 8 +- .../{next-node => node}/app/worker.test.ts | 0 .../{next-node => node}/compression.test.ts | 4 +- .../fixtures/app/worker.ts | 6 +- .../{next-node => node}/fixtures/esm-host.ts | 0 .../fixtures/plugins/contracts/contract.ts | 2 +- .../fixtures/plugins/contracts/package.json | 0 .../fixtures/plugins/files/assets/data.txt | 0 .../fixtures/plugins/files/package.json | 0 .../fixtures/plugins/files/worker.ts | 4 +- .../fixtures/plugins/notes/label.ts | 0 .../fixtures/plugins/notes/package.json | 0 .../fixtures/plugins/notes/server.ts | 2 +- .../fixtures/plugins/notes/worker.ts | 2 +- .../{next-node => node}/fixtures/tui/api.ts | 2 +- .../{next-node => node}/fixtures/tui/drive.ts | 2 +- .../fixtures/tui/escapes.ts | 0 .../{next-node => node}/fixtures/tui/main.ts | 10 +- .../fixtures/tui/os-layer.ts | 2 +- .../fixtures/tui/sandbox-run.ts | 2 +- .../{next-node => node}/fixtures/web/api.ts | 2 +- .../{next-node => node}/fixtures/web/main.ts | 10 +- .../fixtures/workers/child.ts | 2 +- .../fixtures/workers/control.ts | 2 +- .../fixtures/workers/plugins/notes/label.ts | 0 .../workers/plugins/notes/package.json | 0 .../fixtures/workers/plugins/notes/worker.ts | 2 +- .../fixtures/workers/worker.ts | 12 +- .../http/admission.test.ts | 12 +- .../http/authenticate.test.ts | 6 +- .../{next-node => node}/http/cookies.test.ts | 4 +- .../{next-node => node}/http/file.test.ts | 2 +- .../{next-node => node}/http/headers.test.ts | 10 +- .../{next-node => node}/http/http.test.ts | 10 +- .../{next-node => node}/http/node.test.ts | 2 +- .../{next-node => node}/http/request.test.ts | 2 +- .../{next-node => node}/http/response.test.ts | 4 +- .../{next-node => node}/http/router.test.ts | 4 +- .../test/{next-node => node}/http/support.ts | 6 +- .../{next-node => node}/http/upgrades.test.ts | 12 +- .../{next-node => node}/plugins/build.test.ts | 22 +-- .../plugins/discover.test.ts | 2 +- .../plugins/evaluate.test.ts | 20 +-- .../plugins/install.test.ts | 11 +- .../plugins/plugins.test.ts | 41 ++--- .../plugins/runtime.test.ts | 12 +- .../{next-node => node}/plugins/stack.test.ts | 4 +- .../{next-node => node}/plugins/support.ts | 6 +- .../plugins/testing.test.ts | 22 +-- .../plugins/watcher.test.ts | 8 +- .../{next-node => node}/react/hooks.test.ts | 0 .../{next-node => node}/react/stores.test.ts | 4 +- .../{next-node => node}/surfaces/tui.test.ts | 4 +- .../{next-node => node}/surfaces/web.test.ts | 6 +- .../{next-node => node}/tui/actions.test.ts | 2 +- .../tui/credentials.test.ts | 2 +- .../{next-node => node}/tui/filter.test.ts | 2 +- .../{next-node => node}/tui/launcher.test.ts | 4 +- .../test/{next-node => node}/tui/pipe.test.ts | 2 +- .../{next-node => node}/tui/sandbox.test.ts | 2 +- .../test/{next-node => node}/tui/support.ts | 0 .../test/{next-node => node}/web/browser.ts | 0 .../test/{next-node => node}/web/page.test.ts | 0 .../test/{next-node => node}/web/support.ts | 2 +- .../workers/control.test.ts | 4 +- .../{next-node => node}/workers/lock.test.ts | 4 +- .../{next-node => node}/workers/main.test.ts | 6 +- .../workers/process.test.ts | 4 +- .../{next-node => node}/workers/support.ts | 12 +- .../workers/workers.test.ts | 8 +- .../chord/test/{ => old}/awaiting.test.ts | 10 +- .../chord/test/{ => old}/bindings.test.ts | 4 +- packages/chord/test/{ => old}/cluster.test.ts | 2 +- .../chord/test/{ => old}/contract.test.ts | 14 +- .../chord/test/{ => old}/fixtures/counting.ts | 2 +- .../chord/test/{ => old}/fixtures/echo.ts | 2 +- .../chord/test/{ => old}/fixtures/loader.ts | 6 +- .../chord/test/{ => old}/fixtures/schemas.ts | 0 .../chord/test/{ => old}/fixtures/worker.ts | 4 +- .../chord/test/{ => old}/flow-units.test.ts | 4 +- packages/chord/test/{ => old}/flow.test.ts | 2 +- .../chord/test/{ => old}/generations.test.ts | 2 +- .../{ => old}/host-objects-reload.test.ts | 4 +- packages/chord/test/{ => old}/host.test.ts | 2 +- .../chord/test/{ => old}/hydration.test.ts | 2 +- packages/chord/test/{ => old}/link.test.ts | 4 +- .../chord/test/{ => old}/links-review.test.ts | 2 +- packages/chord/test/{ => old}/loader.test.ts | 2 +- packages/chord/test/{ => old}/manager.test.ts | 4 +- .../chord/test/{ => old}/placement.test.ts | 2 +- .../chord/test/{ => old}/principals.test.ts | 2 +- .../test/{ => old}/provider-cost.test.ts | 6 +- .../chord/test/{ => old}/readiness.test.ts | 2 +- packages/chord/test/{ => old}/reload.test.ts | 2 +- .../replicated-state-delivery.test.ts | 4 +- .../test/{ => old}/replicated-state.test.ts | 6 +- .../chord/test/{ => old}/requests.test.ts | 4 +- packages/chord/test/{ => old}/review.test.ts | 4 +- .../chord/test/{ => old}/state-init.test.ts | 2 +- packages/chord/test/{ => old}/state.test.ts | 4 +- .../chord/test/{ => old}/tutorial.test.ts | 4 +- packages/chord/test/{ => old}/types.test.ts | 2 +- .../chord/test/{ => old}/variants.test.ts | 2 +- .../chord/test/{ => old}/websocket.test.ts | 2 +- .../{next => }/registries/entries.test.ts | 7 +- .../test/{next => }/registries/record.test.ts | 18 +-- .../{next => }/registries/registry.test.ts | 6 +- .../test/{next => }/registries/value.test.ts | 14 +- .../test/{next => }/remote/calls.test.ts | 2 +- .../test/{next => }/remote/consumer.test.ts | 18 +-- .../chord/test/{next => }/remote/hold.test.ts | 28 ++-- .../test/{next => }/remote/host-link.test.ts | 14 +- .../chord/test/{next => }/remote/path.test.ts | 6 +- .../test/{next => }/remote/provider.test.ts | 18 +-- .../test/{next => }/remote/relay.test.ts | 18 +-- .../{next => }/remote/remote-object.test.ts | 20 +-- .../test/{next => }/remote/replica.test.ts | 8 +- .../test/{next => }/schema/declarations.ts | 8 +- .../chord/test/{next => }/schema/owner.ts | 10 +- .../chord/test/{next => }/schema/proofs.ts | 14 +- .../test/{next => }/schema/recorded.json | 0 .../{next => }/schema/schema-switch.test.ts | 2 +- .../{next => }/schema/stored/archive.jsonl | 0 .../test/{next => }/schema/stored/store.db | Bin .../test/{next => }/schema/write-stored.ts | 6 +- packages/chord/test/sqlite/cloudflare.test.ts | 8 +- .../chord/test/{next => }/state/batch.test.ts | 12 +- .../test/{next => }/state/derive.test.ts | 16 +- .../{next => }/state/native-source.test.ts | 16 +- .../test/{next => }/state/watchable.test.ts | 12 +- .../test/{next => }/state/writable.test.ts | 18 +-- .../test/{next => }/store/allocator.test.ts | 2 +- .../test/{next => }/store/applier.test.ts | 10 +- .../test/{next => }/store/apply-batch.test.ts | 24 +-- .../test/{next => }/store/archive.test.ts | 4 +- .../test/{next => }/store/catalog.test.ts | 16 +- .../test/{next => }/store/claims.test.ts | 10 +- .../test/{next => }/store/columns.test.ts | 12 +- .../test/{next => }/store/engine.test.ts | 20 +-- .../test/{next => }/store/evaluate.test.ts | 20 +-- .../test/{next => }/store/export.test.ts | 20 +-- .../test/{next => }/store/expression.test.ts | 10 +- .../test/{next => }/store/import.test.ts | 32 ++-- .../test/{next => }/store/json-column.test.ts | 4 +- .../chord/test/{next => }/store/jsonl.test.ts | 4 +- .../test/{next => }/store/outbox.test.ts | 14 +- .../chord/test/{next => }/store/query.test.ts | 8 +- .../test/{next => }/store/refusal.test.ts | 12 +- .../chord/test/{next => }/store/rows.test.ts | 8 +- .../chord/test/{next => }/store/sql.test.ts | 17 +-- .../chord/test/{next => }/store/store.test.ts | 24 +-- .../{next => }/store/table-changes.test.ts | 14 +- .../{next => }/store/table-evolve.test.ts | 12 +- .../{next => }/store/table-handle.test.ts | 22 +-- .../{next => }/store/table-history.test.ts | 12 +- .../{next => }/store/table-migration.test.ts | 26 ++-- .../{next => }/store/table-writes.test.ts | 22 +-- .../chord/test/{next => }/store/table.test.ts | 6 +- .../chord/test/{next => }/store/text.test.ts | 2 +- packages/chord/test/{next => }/support.ts | 54 +++---- .../{next => }/surfaces/active-theme.test.ts | 6 +- .../test/{next => }/surfaces/client.test.ts | 8 +- .../{next => }/surfaces/connection.test.ts | 2 +- .../{next => }/surfaces/registered.test.ts | 4 +- .../test/{next => }/surfaces/themes.test.ts | 8 +- .../chord/test/{next => }/tui/frames.test.ts | 4 +- .../chord/test/{next => }/tui/scope.test.ts | 6 +- packages/chord/vitest.config.ts | 8 + packages/coding-agent/examples/tsconfig.json | 98 +++++++----- packages/durable/README.md | 2 +- packages/durable/docs/spec.md | 16 +- packages/durable/src/codemode/codemode.ts | 3 +- packages/durable/src/codemode/models.ts | 3 +- packages/durable/src/documents.ts | 2 +- packages/durable/src/entries.ts | 2 +- packages/durable/src/env/index.ts | 2 +- packages/durable/src/env/node-watch.ts | 2 +- packages/durable/src/env/node.ts | 2 +- packages/durable/src/harness/agent.ts | 3 +- packages/durable/src/harness/compaction.ts | 3 +- packages/durable/src/harness/context.ts | 2 +- packages/durable/src/harness/define.ts | 2 +- packages/durable/src/harness/generation.ts | 4 +- packages/durable/src/harness/harness.ts | 3 +- packages/durable/src/harness/inbox.ts | 3 +- packages/durable/src/harness/json.ts | 2 +- packages/durable/src/harness/live.ts | 3 +- .../durable/src/harness/partial-changes.ts | 3 +- packages/durable/src/harness/prompt.ts | 2 +- packages/durable/src/harness/provider.ts | 2 +- .../durable/src/harness/registry-reader.ts | 2 +- packages/durable/src/harness/scheduler.ts | 10 +- packages/durable/src/harness/submissions.ts | 4 +- packages/durable/src/harness/task-graph.ts | 5 +- packages/durable/src/harness/tool.ts | 6 +- packages/durable/src/harness/transcript.ts | 2 +- packages/durable/src/harness/types.ts | 4 +- packages/durable/src/harness/usage.ts | 3 +- packages/durable/src/harness/util.ts | 2 +- packages/durable/src/harness/view.ts | 12 +- packages/durable/src/index.ts | 2 +- .../durable/src/session/cached-storage.ts | 3 +- packages/durable/src/session/forks.ts | 2 +- packages/durable/src/session/keys.ts | 3 +- packages/durable/src/session/session.ts | 5 +- packages/durable/src/session/transaction.ts | 14 +- packages/durable/src/session/writer.ts | 2 +- packages/durable/src/storage/indexeddb.ts | 3 +- packages/durable/src/storage/jsonl/node.ts | 2 +- packages/durable/src/storage/jsonl/storage.ts | 3 +- packages/durable/src/storage/memory.ts | 3 +- .../durable/src/storage/sqlite/storage.ts | 3 +- packages/durable/src/storage/store/commit.ts | 5 +- .../durable/src/storage/store/documents.ts | 2 +- packages/durable/src/storage/store/queries.ts | 4 +- packages/durable/src/storage/store/storage.ts | 5 +- packages/durable/src/storage/store/tables.ts | 4 +- packages/durable/src/testing/commit-writes.ts | 2 +- .../durable/src/testing/env-conformance.ts | 2 +- .../durable/src/testing/storage-benchmark.ts | 2 +- .../src/testing/storage-conformance.ts | 2 +- packages/durable/src/tools/bash.ts | 2 +- .../durable/src/tools/file-mutation-queue.ts | 2 +- packages/durable/src/tools/path-utils.ts | 2 +- packages/durable/src/tools/read.ts | 2 +- packages/durable/src/types.ts | 6 +- packages/durable/test/chat-support.ts | 2 +- packages/durable/test/codemode-models.test.ts | 2 +- packages/durable/test/codemode.test.ts | 2 +- .../durable/test/conversation-view-bench.ts | 2 +- .../test/examples/21-subagent-foreground.ts | 2 +- .../test/examples/35-durable-on-the-store.ts | 4 +- .../durable/test/examples/36-durable-views.ts | 4 +- .../test/examples/37-harness-registry.ts | 4 +- .../durable/test/harness-after-run.test.ts | 3 +- .../test/harness-cancellation-barrier.test.ts | 2 +- packages/durable/test/harness-context.test.ts | 2 +- .../durable/test/harness-group-commit.test.ts | 2 +- .../durable/test/harness-lifecycle.test.ts | 3 +- .../test/harness-nested-tools-restart.test.ts | 2 +- .../durable/test/harness-nested-tools.test.ts | 2 +- .../durable/test/harness-observers.test.ts | 2 +- .../test/harness-partial-changes.test.ts | 2 +- .../test/harness-registry-reader.test.ts | 4 +- .../test/harness-storage-failure.test.ts | 2 +- .../test/harness-structured-output.test.ts | 2 +- .../durable/test/harness-structured.test.ts | 3 +- .../durable/test/harness-task-graph.test.ts | 2 +- .../test/harness-tasks-recovery.test.ts | 3 +- packages/durable/test/harness-tasks.test.ts | 2 +- .../durable/test/harness-tool-hooks.test.ts | 2 +- .../test/harness-tools-recovery.test.ts | 2 +- packages/durable/test/harness-tools.test.ts | 2 +- .../durable/test/harness-view-run.test.ts | 2 +- .../durable/test/indexeddb-storage.test.ts | 3 +- packages/durable/test/jsonl-storage.test.ts | 3 +- .../durable/test/session-adoption.test.ts | 2 +- .../test/session-cached-storage.test.ts | 2 +- .../test/session-deferred-commits.test.ts | 2 +- .../durable/test/session-definitions.test.ts | 2 +- .../durable/test/session-documents.test.ts | 3 +- .../durable/test/session-group-commit.test.ts | 2 +- .../durable/test/session-observers.test.ts | 2 +- packages/durable/test/session-support.ts | 2 +- packages/durable/test/session-tables.test.ts | 2 +- packages/durable/test/session-watches.test.ts | 3 +- packages/durable/test/spec-usage.test.ts | 3 +- packages/durable/test/sqlite-storage.test.ts | 3 +- .../durable/test/store-storage-commit.test.ts | 2 +- .../durable/test/store-storage-support.ts | 2 +- packages/durable/test/store-storage.test.ts | 6 +- packages/durable/test/tools.test.ts | 3 +- packages/durable/test/types.test.ts | 2 +- packages/durable/tsconfig.build.json | 8 + packages/env/src/list-files.ts | 2 +- packages/env/src/remote-env.ts | 2 +- packages/env/src/watch.ts | 2 +- packages/env/test/differential.test.ts | 2 +- packages/env/tsconfig.build.json | 1 - scripts/browser-smoke-entry.ts | 4 +- tsconfig.json | 36 ++--- vitest.base.ts | 40 ++++- 966 files changed, 2968 insertions(+), 2804 deletions(-) rename packages/chord/docs/{next => }/benchmarks.md (97%) rename packages/chord/docs/{next => }/decisions.md (99%) rename packages/chord/docs/{next => }/dependencies/book.md (99%) rename packages/chord/docs/{next => }/dependencies/index.html (99%) rename packages/chord/docs/{next => }/dependencies/model.md (100%) rename packages/chord/docs/{next => }/design.md (98%) rename packages/chord/docs/{next => }/durable-observers/book.md (99%) rename packages/chord/docs/{next => }/durable-observers/index.html (99%) rename packages/chord/docs/{next => }/flow-control/book.md (100%) rename packages/chord/docs/{next => }/flow-control/fold/index.html (100%) rename packages/chord/docs/{next => }/flow-control/index.html (100%) rename packages/chord/docs/{next => }/flow-control/window/index.html (100%) rename packages/chord/docs/{next => }/guide-plugins-hosts/book.md (98%) rename packages/chord/docs/{next => }/guide-plugins-hosts/index.html (99%) rename packages/chord/docs/{next => }/http-workers/book.md (98%) rename packages/chord/docs/{next => }/http-workers/index.html (98%) rename packages/chord/docs/{next => }/i18n/book.md (100%) rename packages/chord/docs/{next => }/i18n/index.html (100%) rename packages/chord/docs/{next => }/layer-1.md (98%) rename packages/chord/docs/{next => }/layer-2.md (98%) create mode 100644 packages/chord/docs/old/README.md rename packages/chord/docs/{ => old}/guide.md (99%) rename packages/chord/docs/{ => old}/spec.md (100%) rename packages/chord/docs/{ => old}/tutorial.md (99%) rename packages/chord/docs/{next => }/p3-features/README.md (100%) rename packages/chord/docs/{next => }/p3-features/book.md (99%) rename packages/chord/docs/{next => }/plugin-authoring.md (97%) rename packages/chord/docs/{next => }/plugin-model/book.md (97%) rename packages/chord/docs/{next => }/plugin-model/index.html (99%) rename packages/chord/docs/{next => }/plugin-primer/book.md (96%) rename packages/chord/docs/{next => }/plugin-primer/index.html (98%) rename packages/chord/docs/{next => }/slice-1.md (98%) rename packages/chord/docs/{next => }/slice-10.md (96%) rename packages/chord/docs/{next => }/slice-11.md (96%) rename packages/chord/docs/{next => }/slice-12.md (93%) rename packages/chord/docs/{next => }/slice-13.md (96%) rename packages/chord/docs/{next => }/slice-2.md (99%) rename packages/chord/docs/{next => }/slice-3a.md (99%) rename packages/chord/docs/{next => }/slice-3b.md (99%) rename packages/chord/docs/{next => }/slice-4.md (100%) rename packages/chord/docs/{next => }/slice-4a.md (99%) rename packages/chord/docs/{next => }/slice-4b.md (98%) rename packages/chord/docs/{next => }/slice-5.md (100%) rename packages/chord/docs/{next => }/slice-6a.md (99%) rename packages/chord/docs/{next => }/slice-6b.md (99%) rename packages/chord/docs/{next => }/slice-7a.md (100%) rename packages/chord/docs/{next => }/slice-7b.md (99%) rename packages/chord/docs/{next => }/slice-7b/book.md (92%) rename packages/chord/docs/{next => }/slice-7b/index.html (97%) rename packages/chord/docs/{next => }/slice-7c.md (95%) rename packages/chord/docs/{next => }/slice-8.md (100%) rename packages/chord/docs/{next => }/slices.md (87%) rename packages/chord/docs/{next => }/store/book.md (99%) rename packages/chord/docs/{next => }/store/index.html (99%) rename packages/chord/docs/{next => }/store/walkthrough.md (99%) rename packages/chord/docs/{next => }/theming/book.md (100%) rename packages/chord/docs/{next => }/theming/index.html (100%) rename packages/chord/src/{next => }/contracts/README.md (100%) rename packages/chord/src/{next => }/contracts/accepts.ts (99%) rename packages/chord/src/{next => }/contracts/contract.ts (98%) rename packages/chord/src/{next => }/contracts/declare.ts (100%) rename packages/chord/src/{next => }/contracts/evolve.ts (100%) rename packages/chord/src/{next => }/contracts/fingerprint.ts (98%) rename packages/chord/src/{next => }/contracts/history.ts (100%) rename packages/chord/src/{next => }/contracts/host-kind.ts (100%) rename packages/chord/src/{next => }/contracts/index.ts (100%) rename packages/chord/src/{next => }/contracts/internal.ts (100%) rename packages/chord/src/{next => }/contracts/names.ts (100%) rename packages/chord/src/{next => }/contracts/params.ts (98%) rename packages/chord/src/{next => }/contracts/schema.ts (100%) rename packages/chord/src/{next => }/contracts/snapshot.ts (99%) rename packages/chord/src/{next => }/data/README.md (100%) rename packages/chord/src/{next => }/data/args.ts (99%) rename packages/chord/src/{next => }/data/errors.ts (99%) rename packages/chord/src/{next => }/data/failure.ts (100%) rename packages/chord/src/{next => }/data/index.ts (100%) rename packages/chord/src/{next => }/data/internal.ts (100%) rename packages/chord/src/{next => }/data/params.ts (97%) rename packages/chord/src/{next => }/data/principal.ts (95%) rename packages/chord/src/{next => }/data/validator.ts (97%) rename packages/chord/src/{next => }/documents/README.md (98%) rename packages/chord/src/{next => }/documents/address-source.ts (94%) rename packages/chord/src/{next => }/documents/definition.ts (97%) rename packages/chord/src/{next => }/documents/documents.ts (99%) rename packages/chord/src/{next => }/documents/fence.ts (100%) rename packages/chord/src/{next => }/documents/handles.ts (96%) rename packages/chord/src/{next => }/documents/index.ts (100%) rename packages/chord/src/{next => }/documents/internal.ts (100%) rename packages/chord/src/{next => }/documents/keyed-slot.ts (98%) rename packages/chord/src/{next => }/documents/line.ts (100%) rename packages/chord/src/{next => }/documents/persistence.ts (98%) rename packages/chord/src/{next => }/documents/residency.ts (98%) rename packages/chord/src/{next => }/documents/slot.ts (98%) rename packages/chord/src/{next => }/documents/transaction.ts (99%) rename packages/chord/src/{next => }/host/README.md (99%) rename packages/chord/src/{next => }/host/activity.ts (94%) rename packages/chord/src/{next => }/host/adapted.ts (99%) rename packages/chord/src/{next => }/host/attempt.ts (99%) rename packages/chord/src/{next => }/host/backoff.ts (100%) rename packages/chord/src/{next => }/host/ctx.ts (99%) rename packages/chord/src/{next => }/host/deadline.ts (100%) rename packages/chord/src/{next => }/host/dependencies.ts (100%) rename packages/chord/src/{next => }/host/destination.ts (99%) rename packages/chord/src/{next => }/host/facet.ts (99%) rename packages/chord/src/{next => }/host/follow.ts (97%) rename packages/chord/src/{next => }/host/host.ts (99%) rename packages/chord/src/{next => }/host/index.ts (100%) rename packages/chord/src/{next => }/host/internal.ts (100%) rename packages/chord/src/{next => }/host/members.ts (99%) rename packages/chord/src/{next => }/host/native.ts (98%) rename packages/chord/src/{next => }/host/object.ts (99%) rename packages/chord/src/{next => }/host/parked.ts (98%) rename packages/chord/src/{next => }/host/presence.ts (96%) rename packages/chord/src/{next => }/host/ref-state.ts (97%) rename packages/chord/src/{next => }/host/reference-keys.ts (99%) rename packages/chord/src/{next => }/host/reference-source.ts (98%) rename packages/chord/src/{next => }/host/reference.ts (99%) rename packages/chord/src/{next => }/host/retry-on.ts (100%) rename packages/chord/src/{next => }/host/revocation.ts (93%) rename packages/chord/src/{next => }/host/root.ts (98%) rename packages/chord/src/{next => }/host/route.ts (99%) rename packages/chord/src/{next => }/host/routines.ts (98%) rename packages/chord/src/{next => }/host/sleep.ts (96%) rename packages/chord/src/{next => }/host/staging.ts (99%) rename packages/chord/src/{next => }/host/unbound.ts (100%) rename packages/chord/src/{next => }/host/uuid.ts (100%) rename packages/chord/src/{next => }/jobs/README.md (100%) rename packages/chord/src/{next => }/jobs/definition.ts (100%) rename packages/chord/src/{next => }/jobs/index.ts (100%) rename packages/chord/src/{next => }/jobs/internal.ts (100%) rename packages/chord/src/{next => }/jobs/job.ts (99%) rename packages/chord/src/{next => }/jobs/persisted.ts (98%) rename packages/chord/src/{next => }/jobs/records.ts (99%) rename packages/chord/src/{next => }/jobs/run-states.ts (99%) rename packages/chord/src/{next => }/jobs/run.ts (98%) rename packages/chord/src/{next => }/jobs/running.ts (96%) rename packages/chord/src/{next => }/jobs/stored.ts (98%) rename packages/chord/src/{next => }/link/README.md (99%) rename packages/chord/src/{next => }/link/binary.ts (100%) rename packages/chord/src/{next => }/link/channel.ts (99%) rename packages/chord/src/{next => }/link/errors.ts (96%) rename packages/chord/src/{next => }/link/index.ts (100%) rename packages/chord/src/{next => }/link/internal.ts (100%) rename packages/chord/src/{next => }/link/ipc.ts (100%) rename packages/chord/src/{next => }/link/link.ts (100%) rename packages/chord/src/{next => }/link/message.ts (99%) rename packages/chord/src/{next => }/link/part.ts (99%) rename packages/chord/src/{next => }/link/text.ts (100%) rename packages/chord/src/{next => }/link/values.ts (100%) rename packages/chord/src/{next => }/link/websocket.ts (100%) delete mode 100644 packages/chord/src/next/index.ts rename packages/chord/src/{next-node => node}/app/README.md (98%) rename packages/chord/src/{next-node => node}/app/app.ts (98%) rename packages/chord/src/{next-node => node}/app/archive.ts (99%) rename packages/chord/src/{next-node => node}/app/data.ts (86%) rename packages/chord/src/{next-node => node}/app/ephemeral-sessions.ts (97%) rename packages/chord/src/{next-node => node}/app/ephemeral.ts (94%) rename packages/chord/src/{next-node => node}/app/files.ts (96%) rename packages/chord/src/{next-node => node}/app/index.ts (66%) rename packages/chord/src/{next-node => node}/app/info.ts (87%) rename packages/chord/src/{next-node => node}/app/invite.ts (96%) rename packages/chord/src/{next-node => node}/app/layout.ts (98%) rename packages/chord/src/{next-node => node}/app/owner.ts (97%) rename packages/chord/src/{next-node => node}/app/pairing.ts (98%) rename packages/chord/src/{next-node => node}/app/secrets.ts (100%) rename packages/chord/src/{next-node => node}/app/sessions.ts (97%) rename packages/chord/src/{next-node => node}/app/tar.ts (100%) rename packages/chord/src/{next-node => node}/app/uploads.ts (98%) rename packages/chord/src/{next-node => node}/app/users.ts (90%) rename packages/chord/src/{next-node => node}/app/worker.ts (95%) rename packages/chord/src/{next-node => node}/compression.ts (85%) rename packages/chord/src/{next-node => node}/http/README.md (95%) rename packages/chord/src/{next-node => node}/http/admission.ts (100%) rename packages/chord/src/{next-node => node}/http/authenticate.ts (93%) rename packages/chord/src/{next-node => node}/http/cookies.ts (100%) rename packages/chord/src/{next-node => node}/http/file.ts (100%) rename packages/chord/src/{next-node => node}/http/headers.ts (100%) rename packages/chord/src/{next-node => node}/http/http.ts (99%) rename packages/chord/src/{next-node => node}/http/incoming.ts (100%) rename packages/chord/src/{next-node => node}/http/index.ts (91%) rename packages/chord/src/{next-node => node}/http/node.ts (100%) rename packages/chord/src/{next-node => node}/http/request.ts (100%) rename packages/chord/src/{next-node => node}/http/response.ts (99%) rename packages/chord/src/{next-node => node}/http/router.ts (99%) rename packages/chord/src/{next-node => node}/http/upgrades.ts (98%) rename packages/chord/src/{next-node => node}/plugins/README.md (93%) rename packages/chord/src/{next-node => node}/plugins/build.ts (99%) rename packages/chord/src/{next-node => node}/plugins/css-modules.ts (100%) rename packages/chord/src/{next-node => node}/plugins/discover.ts (99%) rename packages/chord/src/{next-node => node}/plugins/evaluate.ts (96%) rename packages/chord/src/{next-node => node}/plugins/index.ts (70%) rename packages/chord/src/{next-node => node}/plugins/install.ts (99%) rename packages/chord/src/{next-node => node}/plugins/plugins.ts (98%) rename packages/chord/src/{next-node => node}/plugins/runtime.ts (98%) rename packages/chord/src/{next-node => node}/plugins/stack.ts (100%) rename packages/chord/src/{next-node => node}/plugins/testing.ts (97%) rename packages/chord/src/{next-node => node}/plugins/watcher.ts (99%) rename packages/chord/src/{next-node => node}/surfaces/README.md (94%) rename packages/chord/src/{next-node => node}/surfaces/bundle.ts (100%) rename packages/chord/src/{next-node => node}/surfaces/current.ts (91%) rename packages/chord/src/{next-node => node}/surfaces/index.ts (69%) rename packages/chord/src/{next-node => node}/surfaces/published.ts (97%) rename packages/chord/src/{next-node => node}/surfaces/served.ts (100%) rename packages/chord/src/{next-node => node}/surfaces/tui.ts (95%) rename packages/chord/src/{next-node => node}/surfaces/web.ts (96%) rename packages/chord/src/{next-node => node}/tui/README.md (94%) rename packages/chord/src/{next-node => node}/tui/actions.ts (99%) rename packages/chord/src/{next-node => node}/tui/credentials.ts (100%) rename packages/chord/src/{next-node => node}/tui/filter.ts (100%) rename packages/chord/src/{next-node => node}/tui/index.ts (59%) rename packages/chord/src/{next-node => node}/tui/launcher.ts (99%) rename packages/chord/src/{next-node => node}/tui/pipe.ts (99%) rename packages/chord/src/{next-node => node}/tui/sandbox.ts (99%) rename packages/chord/src/{next-node => node}/workers/README.md (96%) rename packages/chord/src/{next-node => node}/workers/control.ts (95%) rename packages/chord/src/{next-node => node}/workers/index.ts (81%) rename packages/chord/src/{next-node => node}/workers/lock.ts (100%) rename packages/chord/src/{next-node => node}/workers/main.ts (97%) rename packages/chord/src/{next-node => node}/workers/process.ts (97%) rename packages/chord/src/{next-node => node}/workers/workers.ts (98%) rename packages/chord/src/{ => old}/cell.ts (99%) rename packages/chord/src/{ => old}/cluster.ts (100%) rename packages/chord/src/{ => old}/connection.ts (99%) rename packages/chord/src/{ => old}/contract.ts (100%) rename packages/chord/src/{ => old}/declare.ts (100%) rename packages/chord/src/{ => old}/errors.ts (100%) rename packages/chord/src/{ => old}/host.ts (99%) create mode 100644 packages/chord/src/old/index.ts rename packages/chord/src/{ => old}/link.ts (100%) rename packages/chord/src/{ => old}/loader.ts (100%) rename packages/chord/src/{ => old}/manager.ts (100%) rename packages/chord/src/{ => old}/node.ts (67%) rename packages/chord/src/{ => old}/object.ts (100%) rename packages/chord/src/{ => old}/publish.ts (100%) rename packages/chord/src/{ => old}/registry.ts (100%) rename packages/chord/src/{ => old}/reload.ts (100%) rename packages/chord/src/{ => old}/remote.ts (99%) rename packages/chord/src/{ => old}/schema.ts (100%) rename packages/chord/src/{ => old}/state.ts (99%) rename packages/chord/src/{ => old}/types.ts (98%) rename packages/chord/src/{ => old}/websocket.ts (100%) rename packages/chord/src/{ => old}/wire.ts (100%) rename packages/chord/src/{next-react => react}/README.md (72%) rename packages/chord/src/{next-react => react}/hooks.ts (91%) rename packages/chord/src/{next-react => react}/index.ts (50%) rename packages/chord/src/{next-react => react}/stores.ts (100%) rename packages/chord/src/{next => }/registries/README.md (100%) rename packages/chord/src/{next => }/registries/contribution.ts (100%) rename packages/chord/src/{next => }/registries/entries.ts (100%) rename packages/chord/src/{next => }/registries/index.ts (100%) rename packages/chord/src/{next => }/registries/internal.ts (100%) rename packages/chord/src/{next => }/registries/record.ts (100%) rename packages/chord/src/{next => }/registries/registry.ts (97%) rename packages/chord/src/{next => }/registries/value.ts (100%) rename packages/chord/src/{next => }/remote/README.md (100%) rename packages/chord/src/{next => }/remote/calls.ts (100%) rename packages/chord/src/{next => }/remote/consumer.ts (99%) rename packages/chord/src/{next => }/remote/hold.ts (99%) rename packages/chord/src/{next => }/remote/host-link.ts (98%) rename packages/chord/src/{next => }/remote/internal.ts (100%) rename packages/chord/src/{next => }/remote/path.ts (100%) rename packages/chord/src/{next => }/remote/provider.ts (99%) rename packages/chord/src/{next => }/remote/relay.ts (100%) rename packages/chord/src/{next => }/remote/remote-object.ts (99%) rename packages/chord/src/{next => }/remote/replica.ts (97%) rename packages/chord/src/{next => }/state/README.md (100%) rename packages/chord/src/{next => }/state/batch.ts (99%) rename packages/chord/src/{next => }/state/derive.ts (97%) rename packages/chord/src/{next => }/state/index.ts (86%) rename packages/chord/src/{next => }/state/internal.ts (100%) rename packages/chord/src/{next => }/state/native-source.ts (99%) rename packages/chord/src/{next => }/state/watchable.ts (98%) rename packages/chord/src/{next => }/state/writable.ts (96%) rename packages/chord/src/{next => }/store/README.md (96%) rename packages/chord/src/{next => }/store/adapter.ts (98%) rename packages/chord/src/{next => }/store/allocator.ts (100%) rename packages/chord/src/{next => }/store/applier.ts (99%) rename packages/chord/src/{next => }/store/apply-batch.ts (97%) rename packages/chord/src/{next => }/store/archive.ts (99%) rename packages/chord/src/{next => }/store/backend.ts (91%) rename packages/chord/src/{next => }/store/catalog.ts (96%) rename packages/chord/src/{next => }/store/claims.ts (100%) rename packages/chord/src/{next => }/store/columns.ts (100%) rename packages/chord/src/{next => }/store/engine.ts (99%) rename packages/chord/src/{next => }/store/evaluate.ts (99%) rename packages/chord/src/{next => }/store/export.ts (98%) rename packages/chord/src/{next => }/store/expression.ts (99%) rename packages/chord/src/{next => }/store/import.ts (98%) rename packages/chord/src/{next => }/store/index.ts (100%) rename packages/chord/src/{next => }/store/json-column.ts (97%) rename packages/chord/src/{next => }/store/jsonl.ts (100%) rename packages/chord/src/{next => }/store/outbox.ts (98%) rename packages/chord/src/{next => }/store/query.ts (98%) rename packages/chord/src/{next => }/store/refusal.ts (100%) rename packages/chord/src/{next => }/store/rows.ts (98%) rename packages/chord/src/{next => }/store/schema.ts (99%) rename packages/chord/src/{next => }/store/sql.ts (99%) rename packages/chord/src/{next => }/store/step.ts (97%) rename packages/chord/src/{next => }/store/store.ts (99%) rename packages/chord/src/{next => }/store/table-changes.ts (98%) rename packages/chord/src/{next => }/store/table-evolve.ts (100%) rename packages/chord/src/{next => }/store/table-handle.ts (98%) rename packages/chord/src/{next => }/store/table-history.ts (100%) rename packages/chord/src/{next => }/store/table-migration.ts (98%) rename packages/chord/src/{next => }/store/table-writes.ts (100%) rename packages/chord/src/{next => }/store/table.ts (100%) rename packages/chord/src/{next => }/store/text.ts (100%) rename packages/chord/src/{next => }/store/writes.ts (100%) rename packages/chord/src/{next => }/surfaces/README.md (98%) rename packages/chord/src/{next => }/surfaces/active-theme.ts (96%) rename packages/chord/src/{next => }/surfaces/client.ts (99%) rename packages/chord/src/{next => }/surfaces/connection.ts (100%) rename packages/chord/src/{next => }/surfaces/index.ts (100%) rename packages/chord/src/{next => }/surfaces/loaded.ts (99%) rename packages/chord/src/{next => }/surfaces/registered.ts (100%) rename packages/chord/src/{next => }/surfaces/scripts.ts (100%) rename packages/chord/src/{next => }/surfaces/theme-choice.ts (98%) rename packages/chord/src/{next => }/surfaces/themes.ts (99%) rename packages/chord/src/{next-tui => tui}/README.md (86%) rename packages/chord/src/{next-tui => tui}/bridge.ts (97%) rename packages/chord/src/{next-tui => tui}/channel.ts (99%) rename packages/chord/src/{next-tui => tui}/frames.ts (100%) rename packages/chord/src/{next-tui => tui}/index.ts (61%) rename packages/chord/src/{next-tui => tui}/runtime.ts (97%) rename packages/chord/src/{next-tui => tui}/scope.ts (92%) rename packages/chord/src/{next-tui => tui}/terminal.ts (100%) rename packages/chord/src/{next-tui => tui}/theme.ts (94%) rename packages/chord/src/{next-web => web}/README.md (84%) rename packages/chord/src/{next-web => web}/environment.ts (95%) rename packages/chord/src/{next-web => web}/index.ts (57%) rename packages/chord/src/{next-web => web}/page.ts (94%) rename packages/chord/src/{next-web => web}/scripts.ts (97%) rename packages/chord/src/{next-web => web}/themes.ts (89%) rename packages/chord/test/{next => }/bench/calls.ts (90%) rename packages/chord/test/{next => }/bench/compression.ts (93%) rename packages/chord/test/{next => }/bench/derives.ts (87%) rename packages/chord/test/{next => }/bench/http.ts (94%) rename packages/chord/test/{next => }/bench/jobs.ts (92%) rename packages/chord/test/{next => }/bench/links.ts (97%) rename packages/chord/test/{next => }/bench/plugins.ts (95%) rename packages/chord/test/{next => }/bench/registries.ts (91%) rename packages/chord/test/{next => }/bench/relay.ts (98%) rename packages/chord/test/{next => }/bench/reload.ts (93%) rename packages/chord/test/{next => }/bench/store.ts (90%) rename packages/chord/test/{next => }/bench/workers.ts (77%) rename packages/chord/test/{next => }/contracts/accepts.test.ts (99%) rename packages/chord/test/{next => }/contracts/contract.test.ts (91%) rename packages/chord/test/{next => }/contracts/declare.test.ts (97%) rename packages/chord/test/{next => }/contracts/evolve.test.ts (98%) rename packages/chord/test/{next => }/contracts/fingerprint.test.ts (94%) rename packages/chord/test/{next => }/contracts/history.test.ts (91%) rename packages/chord/test/{next => }/contracts/host-kind.test.ts (90%) rename packages/chord/test/{next => }/contracts/params.test.ts (90%) rename packages/chord/test/{next => }/contracts/schema.test.ts (97%) rename packages/chord/test/{next => }/contracts/snapshot.test.ts (98%) rename packages/chord/test/{next => }/data/args.test.ts (97%) rename packages/chord/test/{next => }/data/errors.test.ts (98%) rename packages/chord/test/{next => }/data/failure.test.ts (97%) rename packages/chord/test/{next => }/data/params.test.ts (91%) rename packages/chord/test/{next => }/data/principal.test.ts (94%) rename packages/chord/test/{next => }/data/validator.test.ts (91%) rename packages/chord/test/{next => }/documents/address-source.test.ts (91%) rename packages/chord/test/{next => }/documents/definition.test.ts (94%) rename packages/chord/test/{next => }/documents/documents.test.ts (94%) rename packages/chord/test/{next => }/documents/fence.test.ts (84%) rename packages/chord/test/{next => }/documents/handles.test.ts (91%) rename packages/chord/test/{next => }/documents/keyed-slot.test.ts (97%) rename packages/chord/test/{next => }/documents/line.test.ts (95%) rename packages/chord/test/{next => }/documents/persistence.test.ts (93%) rename packages/chord/test/{next => }/documents/residency.test.ts (94%) rename packages/chord/test/{next => }/documents/slot.test.ts (96%) rename packages/chord/test/{next => }/documents/transaction.test.ts (97%) rename packages/chord/test/{next => }/examples/01-objects.ts (85%) rename packages/chord/test/{next => }/examples/02-documents.ts (86%) rename packages/chord/test/{next => }/examples/03-derives.ts (83%) rename packages/chord/test/{next => }/examples/04-watches.ts (90%) rename packages/chord/test/{next => }/examples/05-errors.ts (90%) rename packages/chord/test/{next => }/examples/06-natives.ts (87%) rename packages/chord/test/{next => }/examples/07-failures.ts (89%) rename packages/chord/test/{next => }/examples/08-remote.ts (91%) rename packages/chord/test/{next => }/examples/09-calls.ts (91%) rename packages/chord/test/{next => }/examples/10-drops.ts (91%) rename packages/chord/test/{next => }/examples/11-linger-and-retry.ts (87%) rename packages/chord/test/{next => }/examples/12-routes.ts (93%) rename packages/chord/test/{next => }/examples/13-relay.ts (92%) rename packages/chord/test/{next => }/examples/14-flow-control.ts (94%) rename packages/chord/test/{next => }/examples/15-revocation.ts (91%) rename packages/chord/test/{next => }/examples/16-presence-and-activity.ts (90%) rename packages/chord/test/{next => }/examples/17-limits-and-compression.ts (93%) rename packages/chord/test/{next => }/examples/18-routines.ts (91%) rename packages/chord/test/{next => }/examples/19-jobs.ts (93%) rename packages/chord/test/{next => }/examples/20-tables.ts (90%) rename packages/chord/test/{next => }/examples/21-persisted-documents.ts (85%) rename packages/chord/test/{next => }/examples/22-migrations.ts (89%) rename packages/chord/test/{next => }/examples/23-keyed-watches.ts (87%) rename packages/chord/test/{next => }/examples/24-keyed-members.ts (85%) rename packages/chord/test/{next => }/examples/25-export-import.ts (86%) rename packages/chord/test/{next => }/examples/28-persisted-jobs.ts (87%) rename packages/chord/test/{next => }/examples/29-registries.ts (93%) rename packages/chord/test/{next => }/examples/30-host-root.ts (90%) rename packages/chord/test/{next => }/examples/31-parked-dependencies.ts (91%) rename packages/chord/test/{next => }/examples/32-startup.ts (90%) rename packages/chord/test/{next => }/examples/33-reload.ts (93%) rename packages/chord/test/{next => }/examples/34-versions.ts (92%) rename packages/chord/test/{next => }/examples/35-plugins/main.ts (89%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/clock/package.json (100%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/clock/server.ts (85%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/contracts/contract.ts (97%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/contracts/package.json (100%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/notes/label.ts (100%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/notes/server.ts (78%) rename packages/chord/test/{next => }/examples/35-plugins/plugins/notes/worker.ts (96%) rename packages/chord/test/{next => }/examples/36-plugin-failures/main.ts (93%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/boot/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/boot/server.ts (95%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/cache/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/cache/server.ts (98%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/counter/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/counter/server.ts (95%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/forecast/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/forecast/server.ts (86%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/greeter/label.ts (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/greeter/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/greeter/server.ts (96%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/prices/contract.ts (80%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/prices/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/prices/server.ts (73%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/summary/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/summary/server.ts (87%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/weather/contract.ts (78%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/weather/package.json (100%) rename packages/chord/test/{next => }/examples/36-plugin-failures/plugins/weather/server.ts (85%) rename packages/chord/test/{next => }/examples/37-plugin-imports/app/index.ts (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/app/legacy.cjs (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/deps/example-greeting/index.js (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/deps/example-greeting/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/deps/example-native/index.js (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/deps/example-native/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/fake-npm.mjs (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/main.ts (90%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/paths/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/paths/server.ts (85%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/refused/other.ts (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/refused/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/refused/server.ts (89%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/report/data/rates.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/report/env.d.ts (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/report/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/report/server.ts (89%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/ruler/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/ruler/server.ts (84%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/shapes/contract.ts (85%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/shapes/package.json (100%) rename packages/chord/test/{next => }/examples/37-plugin-imports/plugins/shapes/units.ts (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/app/config.ts (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/incoming/extra/package.json (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/incoming/extra/server.ts (96%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/main.ts (95%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/contracts/contract.ts (86%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/contracts/package.json (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/notes/label.ts (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/notes/server.ts (79%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/notes/worker.ts (79%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/old/package.json (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/old/server.ts (78%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/tags/package.json (100%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/tags/server.ts (75%) rename packages/chord/test/{next => }/examples/38-watch-and-rollout/plugins/tags/worker.ts (75%) rename packages/chord/test/{next => }/examples/39-browser-build/main.ts (85%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/bad-web/package.json (100%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/bad-web/web.ts (78%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/gallery/assets.d.ts (100%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/gallery/assets/logo.svg (100%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/gallery/gallery.css (100%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/gallery/package.json (100%) rename packages/chord/test/{next => }/examples/39-browser-build/plugins/gallery/web.ts (96%) rename packages/chord/test/{next => }/examples/40-http/main.ts (82%) rename packages/chord/test/{next => }/examples/40-http/plugins/notes/files/hello.md (100%) rename packages/chord/test/{next => }/examples/40-http/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/40-http/plugins/notes/server.ts (84%) rename packages/chord/test/{next => }/examples/41-workers/main.ts (83%) rename packages/chord/test/{next => }/examples/41-workers/plugins/sessions/contract.ts (98%) rename packages/chord/test/{next => }/examples/41-workers/plugins/sessions/package.json (100%) rename packages/chord/test/{next => }/examples/41-workers/plugins/sessions/worker.ts (82%) rename packages/chord/test/{next/examples/42-worker-crash => examples/41-workers}/worker.ts (66%) rename packages/chord/test/{next => }/examples/42-worker-crash/main.ts (83%) rename packages/chord/test/{next => }/examples/42-worker-crash/plugins/sessions/contract.ts (96%) rename packages/chord/test/{next => }/examples/42-worker-crash/plugins/sessions/package.json (100%) rename packages/chord/test/{next => }/examples/42-worker-crash/plugins/sessions/worker.ts (85%) rename packages/chord/test/{next/examples/43-rollout => examples/42-worker-crash}/worker.ts (66%) rename packages/chord/test/{next => }/examples/43-rollout/main.ts (84%) rename packages/chord/test/{next => }/examples/43-rollout/plugins/notes/contract.ts (98%) rename packages/chord/test/{next => }/examples/43-rollout/plugins/notes/label.ts (100%) rename packages/chord/test/{next => }/examples/43-rollout/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/43-rollout/plugins/notes/server.ts (76%) rename packages/chord/test/{next => }/examples/43-rollout/plugins/notes/worker.ts (79%) rename packages/chord/test/{next/examples/41-workers => examples/43-rollout}/worker.ts (66%) rename packages/chord/test/{next => }/examples/44-http-wraps/main.ts (72%) rename packages/chord/test/{next => }/examples/44-http-wraps/plugins/audit/package.json (100%) rename packages/chord/test/{next => }/examples/44-http-wraps/plugins/audit/server.ts (84%) rename packages/chord/test/{next => }/examples/44-http-wraps/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/44-http-wraps/plugins/notes/server.ts (82%) rename packages/chord/test/{next => }/examples/45-plugin-socket/main.ts (81%) rename packages/chord/test/{next => }/examples/45-plugin-socket/plugins/echo/package.json (100%) rename packages/chord/test/{next => }/examples/45-plugin-socket/plugins/echo/server.ts (79%) rename packages/chord/test/{next => }/examples/46-allowed-hosts/main.ts (77%) rename packages/chord/test/{next => }/examples/46-allowed-hosts/plugins/tunnel/package.json (100%) rename packages/chord/test/{next => }/examples/46-allowed-hosts/plugins/tunnel/server.ts (97%) rename packages/chord/test/{next => }/examples/47-http-own-server/main.ts (85%) rename packages/chord/test/{next => }/examples/47-http-own-server/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/47-http-own-server/plugins/notes/server.ts (74%) rename packages/chord/test/{next => }/examples/48-http-baseline/main.ts (87%) rename packages/chord/test/{next => }/examples/48-http-baseline/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/48-http-baseline/plugins/notes/server.ts (90%) rename packages/chord/test/{next => }/examples/49-plugin-api/app/v2.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/app/v3.ts (87%) rename packages/chord/test/{next => }/examples/49-plugin-api/app/v3/server.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/app/v3/web.ts (78%) rename packages/chord/test/{next => }/examples/49-plugin-api/app/v3/worker.ts (82%) rename packages/chord/test/{next => }/examples/49-plugin-api/main.ts (91%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/ancient/env.d.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/ancient/package.json (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/ancient/server.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/direct/package.json (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/direct/server.ts (72%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/hello/package.json (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/hello/server.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/legacy/package.json (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/legacy/server.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/mixed/package.json (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/mixed/server.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/panel/package.json (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/panel/server.ts (100%) rename packages/chord/test/{next => }/examples/49-plugin-api/plugins/panel/web.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/main.ts (92%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/notes/contract.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/notes/contract.web.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/notes/server.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/peek/package.json (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/peek/server.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/peek/view.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/search/package.json (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/search/server.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/plugins/search/web.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/user/reach/package.json (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/user/reach/server.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/user/stats/env.d.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/user/stats/package.json (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/user/stats/server.ts (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/words/package.json (100%) rename packages/chord/test/{next => }/examples/50-plugin-imports/words/words.ts (100%) rename packages/chord/test/{next => }/examples/51-single-file-plugin/main.ts (92%) rename packages/chord/test/{next => }/examples/51-single-file-plugin/plugins/bad.server.ts (100%) rename packages/chord/test/{next => }/examples/51-single-file-plugin/plugins/clock.server.ts (100%) rename packages/chord/test/{next => }/examples/51-single-file-plugin/plugins/hello.server.ts (100%) rename packages/chord/test/{next => }/examples/51-single-file-plugin/plugins/hello.web.ts (100%) rename packages/chord/test/{next => }/examples/51-single-file-plugin/plugins/helper.ts (100%) rename packages/chord/test/{next => }/examples/52-test-plugin/main.ts (93%) rename packages/chord/test/{next => }/examples/52-test-plugin/plugins/notes/contract.ts (100%) rename packages/chord/test/{next => }/examples/52-test-plugin/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/52-test-plugin/plugins/stats/package.json (100%) rename packages/chord/test/{next => }/examples/52-test-plugin/plugins/stats/worker.ts (100%) rename packages/chord/test/{next => }/examples/53-app/app/principals.ts (100%) rename packages/chord/test/{next => }/examples/53-app/app/v1.ts (82%) rename packages/chord/test/{next => }/examples/53-app/app/v1/server.ts (51%) rename packages/chord/test/{next => }/examples/53-app/client.ts (100%) rename packages/chord/test/{next => }/examples/53-app/main.ts (94%) rename packages/chord/test/{next => }/examples/53-app/plugins/home/package.json (100%) rename packages/chord/test/{next => }/examples/53-app/plugins/home/server.ts (100%) rename packages/chord/test/{next => }/examples/53-app/plugins/notes/contract.ts (100%) rename packages/chord/test/{next => }/examples/53-app/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/53-app/plugins/notes/server.ts (100%) rename packages/chord/test/{next => }/examples/53-app/plugins/notes/worker.ts (100%) rename packages/chord/test/{next => }/examples/53-app/start.ts (93%) rename packages/chord/test/{next => }/examples/53-app/worker.ts (81%) rename packages/chord/test/{next => }/examples/54-app-sessions/main.ts (92%) rename packages/chord/test/{next => }/examples/55-app-export/main.ts (94%) rename packages/chord/test/{next => }/examples/56-web/app/principals.ts (100%) rename packages/chord/test/{next => }/examples/56-web/app/v1.ts (85%) rename packages/chord/test/{next => }/examples/56-web/app/v1/tui.ts (79%) rename packages/chord/test/{next => }/examples/56-web/app/v1/web.ts (85%) rename packages/chord/test/{next => }/examples/56-web/headless.ts (98%) rename packages/chord/test/{next => }/examples/56-web/main.ts (91%) rename packages/chord/test/{next => }/examples/56-web/plugins/clock/package.json (100%) rename packages/chord/test/{next => }/examples/56-web/plugins/clock/web.ts (100%) rename packages/chord/test/{next => }/examples/56-web/plugins/notes/package.json (100%) rename packages/chord/test/{next => }/examples/56-web/plugins/notes/tui.ts (100%) rename packages/chord/test/{next => }/examples/56-web/plugins/notes/web.ts (100%) rename packages/chord/test/{next => }/examples/56-web/start.ts (90%) rename packages/chord/test/{next => }/examples/56-web/tui/main.ts (83%) rename packages/chord/test/{next => }/examples/56-web/web/main.ts (82%) rename packages/chord/test/{next => }/examples/57-tui/main.ts (85%) rename packages/chord/test/{next => }/examples/57-tui/terminal.ts (76%) rename packages/chord/test/{next => }/examples/58-themes/main.ts (91%) rename packages/chord/test/{next => }/examples/58-themes/plugins/midnight.web.ts (100%) rename packages/chord/test/{next => }/examples/58-themes/plugins/solarized/package.json (100%) rename packages/chord/test/{next => }/examples/58-themes/plugins/solarized/theme.ts (100%) rename packages/chord/test/{next => }/examples/58-themes/plugins/solarized/tui.ts (100%) rename packages/chord/test/{next => }/examples/58-themes/plugins/solarized/web.ts (100%) rename packages/chord/test/{next => }/examples/59-chat/app/principals.ts (100%) rename packages/chord/test/{next => }/examples/59-chat/app/v1.ts (88%) rename packages/chord/test/{next => }/examples/59-chat/app/v1/server.ts (71%) rename packages/chord/test/{next => }/examples/59-chat/app/v1/worker.ts (60%) rename packages/chord/test/{next => }/examples/59-chat/main.ts (94%) rename packages/chord/test/{next => }/examples/59-chat/plugins/chat/package.json (100%) rename packages/chord/test/{next => }/examples/59-chat/plugins/chat/server.ts (100%) rename packages/chord/test/{next => }/examples/59-chat/plugins/chat/worker.ts (100%) rename packages/chord/test/{next => }/examples/59-chat/plugins/login.server.ts (100%) rename packages/chord/test/{next => }/examples/59-chat/start.ts (92%) rename packages/chord/test/{next => }/examples/59-chat/tui/main.ts (97%) rename packages/chord/test/{next => }/examples/59-chat/web/main.ts (93%) rename packages/chord/test/{next => }/examples/59-chat/web/style.css (100%) rename packages/chord/test/{next => }/examples/59-chat/worker.ts (74%) rename packages/chord/test/{next => }/examples/60-session-sync/main.ts (95%) rename packages/chord/test/{next => }/examples/60-session-sync/radius.ts (92%) rename packages/chord/test/{next => }/examples/60-session-sync/session.ts (87%) rename packages/chord/test/{next => }/examples/60-session-sync/sync.ts (95%) rename packages/chord/test/{next => }/host/activity.test.ts (95%) rename packages/chord/test/{next => }/host/adapted.test.ts (99%) rename packages/chord/test/{next => }/host/attempt.test.ts (97%) rename packages/chord/test/{next => }/host/backoff.test.ts (98%) rename packages/chord/test/{next => }/host/ctx.test.ts (94%) rename packages/chord/test/{next => }/host/deadline.test.ts (95%) rename packages/chord/test/{next => }/host/dependencies.test.ts (97%) rename packages/chord/test/{next => }/host/facet.test.ts (88%) rename packages/chord/test/{next => }/host/follow.test.ts (95%) rename packages/chord/test/{next => }/host/host.test.ts (98%) rename packages/chord/test/{next => }/host/members.test.ts (89%) rename packages/chord/test/{next => }/host/native.test.ts (96%) rename packages/chord/test/{next => }/host/object.test.ts (99%) rename packages/chord/test/{next => }/host/parked.test.ts (97%) rename packages/chord/test/{next => }/host/presence.test.ts (96%) rename packages/chord/test/{next => }/host/ref-state.test.ts (97%) rename packages/chord/test/{next => }/host/reference-keys.test.ts (98%) rename packages/chord/test/{next => }/host/reference-source.test.ts (97%) rename packages/chord/test/{next => }/host/reference.test.ts (97%) rename packages/chord/test/{next => }/host/retry-on.test.ts (93%) rename packages/chord/test/{next => }/host/revocation.test.ts (97%) rename packages/chord/test/{next => }/host/root.test.ts (98%) rename packages/chord/test/{next => }/host/route.test.ts (98%) rename packages/chord/test/{next => }/host/routines.test.ts (98%) rename packages/chord/test/{next => }/host/sleep.test.ts (93%) rename packages/chord/test/{next => }/host/staging.test.ts (97%) rename packages/chord/test/{next => }/host/unbound.test.ts (90%) rename packages/chord/test/{next => }/jobs/definition.test.ts (96%) rename packages/chord/test/{next => }/jobs/job.test.ts (98%) rename packages/chord/test/{next => }/jobs/persisted.test.ts (97%) rename packages/chord/test/{next => }/jobs/records.test.ts (97%) rename packages/chord/test/{next => }/jobs/run.test.ts (94%) rename packages/chord/test/{next => }/jobs/running.test.ts (92%) rename packages/chord/test/{next => }/link/channel.test.ts (97%) rename packages/chord/test/{next => }/link/errors.test.ts (91%) rename packages/chord/test/{next => }/link/fixtures/ipc-echo.ts (85%) rename packages/chord/test/{next => }/link/ipc.test.ts (98%) rename packages/chord/test/{next => }/link/link.test.ts (93%) rename packages/chord/test/{next => }/link/message.test.ts (99%) rename packages/chord/test/{next => }/link/part.test.ts (98%) rename packages/chord/test/{next => }/link/values.test.ts (96%) rename packages/chord/test/{next => }/link/websocket.test.ts (96%) rename packages/chord/test/{next-node => node}/app/app.test.ts (98%) rename packages/chord/test/{next-node => node}/app/archive.test.ts (98%) rename packages/chord/test/{next-node => node}/app/ephemeral-sessions.test.ts (95%) rename packages/chord/test/{next-node => node}/app/ephemeral.test.ts (95%) rename packages/chord/test/{next-node => node}/app/files.test.ts (98%) rename packages/chord/test/{next-node => node}/app/info.test.ts (94%) rename packages/chord/test/{next-node => node}/app/invite.test.ts (95%) rename packages/chord/test/{next-node => node}/app/layout.test.ts (95%) rename packages/chord/test/{next-node => node}/app/owner.test.ts (97%) rename packages/chord/test/{next-node => node}/app/pairing.test.ts (98%) rename packages/chord/test/{next-node => node}/app/secrets.test.ts (98%) rename packages/chord/test/{next-node => node}/app/sessions.test.ts (98%) rename packages/chord/test/{next-node => node}/app/support.ts (96%) rename packages/chord/test/{next-node => node}/app/tar.test.ts (99%) rename packages/chord/test/{next-node => node}/app/uploads.test.ts (95%) rename packages/chord/test/{next-node => node}/app/users.test.ts (89%) rename packages/chord/test/{next-node => node}/app/worker.test.ts (100%) rename packages/chord/test/{next-node => node}/compression.test.ts (93%) rename packages/chord/test/{next-node => node}/fixtures/app/worker.ts (73%) rename packages/chord/test/{next-node => node}/fixtures/esm-host.ts (100%) rename packages/chord/test/{next-node => node}/fixtures/plugins/contracts/contract.ts (97%) rename packages/chord/test/{next-node => node}/fixtures/plugins/contracts/package.json (100%) rename packages/chord/test/{next-node => node}/fixtures/plugins/files/assets/data.txt (100%) rename packages/chord/test/{next-node => node}/fixtures/plugins/files/package.json (100%) rename packages/chord/test/{next-node => node}/fixtures/plugins/files/worker.ts (71%) rename packages/chord/test/{next-node => node}/fixtures/plugins/notes/label.ts (100%) rename packages/chord/test/{next-node => node}/fixtures/plugins/notes/package.json (100%) rename packages/chord/test/{next-node => node}/fixtures/plugins/notes/server.ts (79%) rename packages/chord/test/{next-node => node}/fixtures/plugins/notes/worker.ts (96%) rename packages/chord/test/{next-node => node}/fixtures/tui/api.ts (82%) rename packages/chord/test/{next-node => node}/fixtures/tui/drive.ts (89%) rename packages/chord/test/{next-node => node}/fixtures/tui/escapes.ts (100%) rename packages/chord/test/{next-node => node}/fixtures/tui/main.ts (95%) rename packages/chord/test/{next-node => node}/fixtures/tui/os-layer.ts (98%) rename packages/chord/test/{next-node => node}/fixtures/tui/sandbox-run.ts (90%) rename packages/chord/test/{next-node => node}/fixtures/web/api.ts (96%) rename packages/chord/test/{next-node => node}/fixtures/web/main.ts (89%) rename packages/chord/test/{next-node => node}/fixtures/workers/child.ts (87%) rename packages/chord/test/{next-node => node}/fixtures/workers/control.ts (98%) rename packages/chord/test/{next-node => node}/fixtures/workers/plugins/notes/label.ts (100%) rename packages/chord/test/{next-node => node}/fixtures/workers/plugins/notes/package.json (100%) rename packages/chord/test/{next-node => node}/fixtures/workers/plugins/notes/worker.ts (95%) rename packages/chord/test/{next-node => node}/fixtures/workers/worker.ts (92%) rename packages/chord/test/{next-node => node}/http/admission.test.ts (95%) rename packages/chord/test/{next-node => node}/http/authenticate.test.ts (91%) rename packages/chord/test/{next-node => node}/http/cookies.test.ts (96%) rename packages/chord/test/{next-node => node}/http/file.test.ts (98%) rename packages/chord/test/{next-node => node}/http/headers.test.ts (94%) rename packages/chord/test/{next-node => node}/http/http.test.ts (99%) rename packages/chord/test/{next-node => node}/http/node.test.ts (99%) rename packages/chord/test/{next-node => node}/http/request.test.ts (98%) rename packages/chord/test/{next-node => node}/http/response.test.ts (98%) rename packages/chord/test/{next-node => node}/http/router.test.ts (99%) rename packages/chord/test/{next-node => node}/http/support.ts (97%) rename packages/chord/test/{next-node => node}/http/upgrades.test.ts (98%) rename packages/chord/test/{next-node => node}/plugins/build.test.ts (98%) rename packages/chord/test/{next-node => node}/plugins/discover.test.ts (99%) rename packages/chord/test/{next-node => node}/plugins/evaluate.test.ts (94%) rename packages/chord/test/{next-node => node}/plugins/install.test.ts (97%) rename packages/chord/test/{next-node => node}/plugins/plugins.test.ts (97%) rename packages/chord/test/{next-node => node}/plugins/runtime.test.ts (95%) rename packages/chord/test/{next-node => node}/plugins/stack.test.ts (97%) rename packages/chord/test/{next-node => node}/plugins/support.ts (97%) rename packages/chord/test/{next-node => node}/plugins/testing.test.ts (92%) rename packages/chord/test/{next-node => node}/plugins/watcher.test.ts (97%) rename packages/chord/test/{next-node => node}/react/hooks.test.ts (100%) rename packages/chord/test/{next-node => node}/react/stores.test.ts (97%) rename packages/chord/test/{next-node => node}/surfaces/tui.test.ts (95%) rename packages/chord/test/{next-node => node}/surfaces/web.test.ts (98%) rename packages/chord/test/{next-node => node}/tui/actions.test.ts (99%) rename packages/chord/test/{next-node => node}/tui/credentials.test.ts (95%) rename packages/chord/test/{next-node => node}/tui/filter.test.ts (95%) rename packages/chord/test/{next-node => node}/tui/launcher.test.ts (99%) rename packages/chord/test/{next-node => node}/tui/pipe.test.ts (98%) rename packages/chord/test/{next-node => node}/tui/sandbox.test.ts (98%) rename packages/chord/test/{next-node => node}/tui/support.ts (100%) rename packages/chord/test/{next-node => node}/web/browser.ts (100%) rename packages/chord/test/{next-node => node}/web/page.test.ts (100%) rename packages/chord/test/{next-node => node}/web/support.ts (97%) rename packages/chord/test/{next-node => node}/workers/control.test.ts (94%) rename packages/chord/test/{next-node => node}/workers/lock.test.ts (95%) rename packages/chord/test/{next-node => node}/workers/main.test.ts (93%) rename packages/chord/test/{next-node => node}/workers/process.test.ts (91%) rename packages/chord/test/{next-node => node}/workers/support.ts (93%) rename packages/chord/test/{next-node => node}/workers/workers.test.ts (99%) rename packages/chord/test/{ => old}/awaiting.test.ts (96%) rename packages/chord/test/{ => old}/bindings.test.ts (99%) rename packages/chord/test/{ => old}/cluster.test.ts (99%) rename packages/chord/test/{ => old}/contract.test.ts (96%) rename packages/chord/test/{ => old}/fixtures/counting.ts (97%) rename packages/chord/test/{ => old}/fixtures/echo.ts (79%) rename packages/chord/test/{ => old}/fixtures/loader.ts (94%) rename packages/chord/test/{ => old}/fixtures/schemas.ts (100%) rename packages/chord/test/{ => old}/fixtures/worker.ts (90%) rename packages/chord/test/{ => old}/flow-units.test.ts (99%) rename packages/chord/test/{ => old}/flow.test.ts (99%) rename packages/chord/test/{ => old}/generations.test.ts (99%) rename packages/chord/test/{ => old}/host-objects-reload.test.ts (99%) rename packages/chord/test/{ => old}/host.test.ts (99%) rename packages/chord/test/{ => old}/hydration.test.ts (99%) rename packages/chord/test/{ => old}/link.test.ts (99%) rename packages/chord/test/{ => old}/links-review.test.ts (99%) rename packages/chord/test/{ => old}/loader.test.ts (93%) rename packages/chord/test/{ => old}/manager.test.ts (98%) rename packages/chord/test/{ => old}/placement.test.ts (99%) rename packages/chord/test/{ => old}/principals.test.ts (99%) rename packages/chord/test/{ => old}/provider-cost.test.ts (94%) rename packages/chord/test/{ => old}/readiness.test.ts (99%) rename packages/chord/test/{ => old}/reload.test.ts (99%) rename packages/chord/test/{ => old}/replicated-state-delivery.test.ts (98%) rename packages/chord/test/{ => old}/replicated-state.test.ts (98%) rename packages/chord/test/{ => old}/requests.test.ts (99%) rename packages/chord/test/{ => old}/review.test.ts (99%) rename packages/chord/test/{ => old}/state-init.test.ts (99%) rename packages/chord/test/{ => old}/state.test.ts (98%) rename packages/chord/test/{ => old}/tutorial.test.ts (99%) rename packages/chord/test/{ => old}/types.test.ts (96%) rename packages/chord/test/{ => old}/variants.test.ts (99%) rename packages/chord/test/{ => old}/websocket.test.ts (99%) rename packages/chord/test/{next => }/registries/entries.test.ts (92%) rename packages/chord/test/{next => }/registries/record.test.ts (97%) rename packages/chord/test/{next => }/registries/registry.test.ts (93%) rename packages/chord/test/{next => }/registries/value.test.ts (97%) rename packages/chord/test/{next => }/remote/calls.test.ts (96%) rename packages/chord/test/{next => }/remote/consumer.test.ts (98%) rename packages/chord/test/{next => }/remote/hold.test.ts (98%) rename packages/chord/test/{next => }/remote/host-link.test.ts (97%) rename packages/chord/test/{next => }/remote/path.test.ts (93%) rename packages/chord/test/{next => }/remote/provider.test.ts (98%) rename packages/chord/test/{next => }/remote/relay.test.ts (98%) rename packages/chord/test/{next => }/remote/remote-object.test.ts (98%) rename packages/chord/test/{next => }/remote/replica.test.ts (93%) rename packages/chord/test/{next => }/schema/declarations.ts (94%) rename packages/chord/test/{next => }/schema/owner.ts (90%) rename packages/chord/test/{next => }/schema/proofs.ts (88%) rename packages/chord/test/{next => }/schema/recorded.json (100%) rename packages/chord/test/{next => }/schema/schema-switch.test.ts (92%) rename packages/chord/test/{next => }/schema/stored/archive.jsonl (100%) rename packages/chord/test/{next => }/schema/stored/store.db (100%) rename packages/chord/test/{next => }/schema/write-stored.ts (87%) rename packages/chord/test/{next => }/state/batch.test.ts (92%) rename packages/chord/test/{next => }/state/derive.test.ts (96%) rename packages/chord/test/{next => }/state/native-source.test.ts (90%) rename packages/chord/test/{next => }/state/watchable.test.ts (91%) rename packages/chord/test/{next => }/state/writable.test.ts (92%) rename packages/chord/test/{next => }/store/allocator.test.ts (92%) rename packages/chord/test/{next => }/store/applier.test.ts (91%) rename packages/chord/test/{next => }/store/apply-batch.test.ts (93%) rename packages/chord/test/{next => }/store/archive.test.ts (90%) rename packages/chord/test/{next => }/store/catalog.test.ts (78%) rename packages/chord/test/{next => }/store/claims.test.ts (88%) rename packages/chord/test/{next => }/store/columns.test.ts (90%) rename packages/chord/test/{next => }/store/engine.test.ts (94%) rename packages/chord/test/{next => }/store/evaluate.test.ts (91%) rename packages/chord/test/{next => }/store/export.test.ts (93%) rename packages/chord/test/{next => }/store/expression.test.ts (94%) rename packages/chord/test/{next => }/store/import.test.ts (93%) rename packages/chord/test/{next => }/store/json-column.test.ts (94%) rename packages/chord/test/{next => }/store/jsonl.test.ts (93%) rename packages/chord/test/{next => }/store/outbox.test.ts (92%) rename packages/chord/test/{next => }/store/query.test.ts (91%) rename packages/chord/test/{next => }/store/refusal.test.ts (85%) rename packages/chord/test/{next => }/store/rows.test.ts (91%) rename packages/chord/test/{next => }/store/sql.test.ts (90%) rename packages/chord/test/{next => }/store/store.test.ts (96%) rename packages/chord/test/{next => }/store/table-changes.test.ts (87%) rename packages/chord/test/{next => }/store/table-evolve.test.ts (95%) rename packages/chord/test/{next => }/store/table-handle.test.ts (88%) rename packages/chord/test/{next => }/store/table-history.test.ts (85%) rename packages/chord/test/{next => }/store/table-migration.test.ts (93%) rename packages/chord/test/{next => }/store/table-writes.test.ts (91%) rename packages/chord/test/{next => }/store/table.test.ts (94%) rename packages/chord/test/{next => }/store/text.test.ts (98%) rename packages/chord/test/{next => }/support.ts (96%) rename packages/chord/test/{next => }/surfaces/active-theme.test.ts (95%) rename packages/chord/test/{next => }/surfaces/client.test.ts (96%) rename packages/chord/test/{next => }/surfaces/connection.test.ts (99%) rename packages/chord/test/{next => }/surfaces/registered.test.ts (95%) rename packages/chord/test/{next => }/surfaces/themes.test.ts (95%) rename packages/chord/test/{next => }/tui/frames.test.ts (86%) rename packages/chord/test/{next => }/tui/scope.test.ts (93%) create mode 100644 packages/chord/vitest.config.ts diff --git a/AGENTS.md b/AGENTS.md index 43a9cf8c9..977199212 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,22 +29,22 @@ ## Chord v2 Code Style -Binding for `packages/chord/src/next/` and its tests, when writing and when reviewing. The model is pi-durable's source. +Binding for Chord v2 (`packages/chord/src/`, except Chord v1 in `src/old/`) and its tests, when writing and when reviewing. The model is pi-durable's source. - Files: one concept per file, named after it; no one-helper files, no grab-bag files. First line: a comment saying what the file is for. Order: imports, exported types, then the public entry point first and its helpers below it in the order they are used; constants right above their first user. A blank line between top-level declarations. Split files by concept, never by size: one concept may take a long file (up to about 1,000 lines is fine); a second concept in a file is the reason to split. - Functions: every export has a one-line doc comment saying what it does or guarantees. Inline comments explain a non-obvious why (cost, race, decided rule), never what the next line does. Short functions with one job (about 40 lines needs a reason; one `switch` over a tagged union is fine). No boolean flag parameters that switch behaviour: two functions or a tagged value. Never write the same lines twice. Context last: required args, then `context`/`ctx` (always required, as in Durable; optional only on error-reporting paths), then optional args. - Types and checks: tagged unions for every state and result. Casts only where TypeScript cannot express a decided invariant, each with a short why. Every remaining runtime check names the trust boundary it serves (wire input, schema-checked params and arguments, declaration policy the types cannot express). Same-host values are plain data, immutable by convention: never copied, frozen or walked to enforce it; freeze only Chord-owned metadata when a decision says so. No defensive code against broken adapters, callers or our own modules. - Cost and memory: no hot-path work a decision did not ask for (walks, copies, compilations, per-call allocations). The function doing counted work counts it through its context; call sites never count for others. Caches are `WeakMap`s keyed by their owner, each with a GC test; no module-level strong caches. - Names and API: the design's vocabulary (`params`, `binding`, `principal key`), no invented synonyms; decided `ChordError` codes and reasons. Export only what a later layer or app needs. No dev or test modes, no unrequested options. -- Tests: one test file per source file, one `describe` per mechanism, the layer spec's test list case by case; cost guards through the in-memory telemetry adapter; GC tests for every cache and binding. Every slice also adds one or more runnable examples in `packages/chord/test/next/examples/NN-topic.ts`, one topic each, numbered across slices, written as references for Chord's users (Durable's `test/examples/` format: header with what it shows and how to run it, commented steps, printed results). -- Slices: Chord v2 is built in vertical slices (`packages/chord/docs/next/slices.md`). Implementers and reviewers read the slice spec, the feature map in `slices.md` and the whole of `packages/chord/docs/next/design.md` in full, and check the work against all three; slice specs cite design sections for orientation, not as a reading limit. -- Deferred work: anything left to a later slice goes into the section "Carry-over" of `packages/chord/docs/next/slices.md` under that slice, in the same change; a slice's spec and build include every entry of its section. +- Tests: one test file per source file, one `describe` per mechanism, the layer spec's test list case by case; cost guards through the in-memory telemetry adapter; GC tests for every cache and binding. Every slice also adds one or more runnable examples in `packages/chord/test/examples/NN-topic.ts`, one topic each, numbered across slices, written as references for Chord's users (Durable's `test/examples/` format: header with what it shows and how to run it, commented steps, printed results). +- Slices: Chord v2 is built in vertical slices (`packages/chord/docs/slices.md`). Implementers and reviewers read the slice spec, the feature map in `slices.md` and the whole of `packages/chord/docs/design.md` in full, and check the work against all three; slice specs cite design sections for orientation, not as a reading limit. +- Deferred work: anything left to a later slice goes into the section "Carry-over" of `packages/chord/docs/slices.md` under that slice, in the same change; a slice's spec and build include every entry of its section. - Before reporting: re-read every changed file top to bottom as a stranger would; each file must be understandable without jumping around. Then `npm run check` and the layer's tests. ## Commands - After code changes (not docs): `npm run check` (full output, no tail). Fix all errors, warnings, and infos before committing. Does not run tests. -- Run `npm run build` whenever something needs built output (`dist/`): tests or benchmarks that import built packages, Durable's workerd suite. Never use it to type check or lint: that is `npm run check`, the preferred check. +- Run `npm run build` whenever something needs built output (`dist/`): tests or benchmarks that import built packages, Durable's workerd suite. The full suites of Chord and Durable need it: Chord's tests that start Node processes or bundle with esbuild load workspace packages from `dist/` (the rest run from source by its vitest config), and Durable imports pi-ai's `utils/*`, which have no source export. Never use it to type check or lint: that is `npm run check`, the preferred check. - Never run `npm test` unless requested by the user. - Never run the full vitest suite directly: it includes e2e tests that activate when endpoint/auth env vars are present. For all non-e2e tests, run `./test.sh` from the repo root. Otherwise run specific tests from the package root: - Vitest: `node "$(git rev-parse --show-toplevel)/node_modules/vitest/dist/cli.js" --run test/specific.test.ts` diff --git a/README.md b/README.md index 93184c10f..b4c0d8daa 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ This monorepo contains the Pi CLI and its supporting libraries. | Package | Description | |---------|-------------| -| **[@earendil-works/chord](packages/chord)** | Typed host runtime for hot-reloadable plugins, contracts, replicated state, and RPC over JSON links | +| **[@earendil-works/chord](packages/chord)** | Object runtime for apps across processes: contracts, documents, a store, links, plugins with hot reload, HTTP, workers, web and terminal clients | | **[@earendil-works/pi-telemetry](packages/telemetry)** | Vendor-neutral telemetry contracts, reference adapter, conformance tests, and typed schemas | | **[@earendil-works/pi-ai](packages/ai)** | Unified multi-provider LLM API (OpenAI, Anthropic, Google, etc.) | | **[@earendil-works/pi-durable](packages/durable)** | Durable conversation, task, and document runtime | diff --git a/packages/chord/CHANGELOG.md b/packages/chord/CHANGELOG.md index 8ea8cb930..910aec018 100644 --- a/packages/chord/CHANGELOG.md +++ b/packages/chord/CHANGELOG.md @@ -2,11 +2,16 @@ ## [Unreleased] +### Breaking Changes + +- Chord v2 is the package's root: `@earendil-works/chord` exports v2 (was `@earendil-works/chord/next`). Chord v1 moved unchanged to `@earendil-works/chord/old` (was the root) and `@earendil-works/chord/old/node` (was `/node`); it stays until p2 runs on v2. The foundations v1's root re-exported have their own subpaths: `@earendil-works/chord/json` (`JsonValue`, `JsonRepresentation`, `copyJson`, `isJsonValue`) and `@earendil-works/chord/watch` (`Watch`, `NativeWatch` and the watch types), beside `/context` and `/delta`. Migration: imports of `@earendil-works/chord/next` drop `/next`; v1's imports of `@earendil-works/chord` become `@earendil-works/chord/old`, and `/node` becomes `/old/node`; imports of `Context`, `Draft`, `JsonValue`, `copyJson` or the watch types from the root move to `/context`, `/delta`, `/json` and `/watch`. In the repository, v2's `src/next` is now `src`, `src/next-node` is `src/node`, `src/next-web`, `src/next-react` and `src/next-tui` are `src/web`, `src/react` and `src/tui`, v1 is in `src/old`, and tests and docs moved likewise (`test/next` to `test`, `docs/next` to `docs`, v1's to `test/old` and `docs/old`). + ### Added -- Chord v2's plugins component gains the plugin model (slice 12): `createPlugins({ api: { name, versions } })` checks every import of the app's versioned API (`@acme/app/v3`, per-kind modules such as `@acme/app/v3/web`): an unlisted version, another kind's module, two versions in one facet and a direct import of Chord are build errors naming the file and line. Roots may be `{ path, required }`: a required root's plugin failing at `load` rejects it with a `PluginError` after the load settled. Files named `..` (`contract.web.tsx`) are of that kind, refused in facets of another kind with the chain of imports named. Single-file plugins (`hello.server.ts` at a root's top, grouped by name, host packages only). `installPlugin({ git, ref } | { npm, version }, root, ctx)` installs plugins from git (a shallow clone of a branch, tag or commit; a repository of several plugins too) or npm; a package lists the plugin folders it provides in its `package.json` (`"chord": { "plugins": ["./notes", "plugins/*", "!plugins/draft"] }`), used by discovery and `installPlugin` (without it: one plugin when the package's top has facet files, else its subfolders with a `package.json`). `testPlugin(dir, { kind, modules, stubs, principal }, ctx)` builds a plugin as production does and loads it on an in-memory host beside stub facets, collecting its contributions to registries nobody serves and listing the contracts it waits for. Agents' guide: `docs/next/plugin-authoring.md`. -- Chord v2 gains the app kit (slice 13, `src/next-node/app`, to be exported as `@earendil-works/chord/next/app`): `startServer

({ name, dataDir?, root?, listen?, api, kinds, principal, workers?, files?, install?, onError }, ctx)` lays out the data directory (`server/store.sqlite`, `workers//

/`, `plugins/`, `logs/`, `owner-token`; one server per data directory), creates the server's store and host, HTTP, one workers component per worker kind and the plugins component over the app's required root and the user's root, and loads the server's plugins with the kit's objects; `startWorker({ api, kinds, busy?, onError })` is a worker's entry (its directory and store, the link to the server first, its plugins). The start-data objects `AppInfo` and `WorkerInfo` serve process values to plugins. Sessions (`Sessions`: `issue`, `verify`, `revoke`, `list`; tokens kept as SHA-256 hashes, compared in constant time; persisted ones end after 400 days unused and their browser cookie is renewed daily while used, ephemeral ones live in memory, at most `limits.ephemeralSessions`) authenticate a signed `HttpOnly`, `SameSite=Strict` cookie or `Authorization: Bearer`; a one-time owner link per start (`app.ownerLink()`, the token in the URL's fragment, single use, 10 minutes), an owner token file (mode 0600, written atomically) and device pairing (`POST /_chord/pair`, owner approval, a poll returning the token once; bounded in all and per client address) sign the owner in. The data directory, its stores and secret files are made private (0700, 0600) at every start; the home directory, a file system's root and another user's directory are refused. `Files` per host: small and chunked writes at a stored offset, ranged reads, a watchable index, caps, at most `limits.uploads` uploads under way. `app.exportData(address, path, ctx)` and `app.importData(archive, address, ctx)` move the data a worker created (its store and files) as a tar without stopping anything: a running worker writes its own store at one consistent point, else the server reads it under the worker's process lock (import refusing an existing address, another app's archive, every path leaving the target, and archives past `limits.importBytes` or `limits.importEntries`). `app.applyChanges(ctx)` and `app.plugins.install(source, ctx)`. Optional plugins as exported facets: `defineUsers(profile)`, `inviteFacet()`, `ephemeralLoginFacet()`. -- Chord v2 gains web and terminal surfaces (slice 11): `webSurface` and `tuiSurface` (`src/next-node/surfaces`) build a client kind's base bundle from the app's entry at start (content-hashed, served forever) and publish its plugins' facets as scripts that register themselves (`chordFacet("", "", function (require, module, exports) {โ€ฆ})`) and one combined file, with `WebScripts` and `TuiScripts` showing the current set (a rollout step publishes without waiting for clients) and the page served through the app's own template (`PageAssets`, `pageScripts`). `startPage` (`src/next-web`) runs a page's client host: the connection loop (`keepConnected`: 250 ms doubling to 5 s, wakes, silent sockets, `canRetry`), plugins applied in place on a new set (a failed one keeps its old facet), a reload when the server's base bundle changed, and the active theme as CSS variables. React bindings (`src/next-react`): `HostProvider`, `useHold`, `useWatch`, `useRegistry`, `useRefState` (React is an optional peer dependency). The terminal: `startTerminal` (`src/next-node/tui`) signs in with a token, a token file or device pairing and runs the app's terminal code always in a sandbox (a child process on pipes with Node's permission model: no file system, terminal, processes, workers, network or SQLite; Node 26.5.1 or later), filtering its output, relaying its link and confirming its actions (copy, open a URL, attach a file the user names); `startTerminalRuntime` and `TuiScope` (`src/next-tui`) inside it. Themes: the `Themes` registry, `ThemeChoice` (one dark and one light pick per principal), `followActiveTheme`, `themeVariables`, `terminalColor`. `startServer` gains `web` and `tui`. Plugin builds scope `*.module.css` files per plugin and file. Ephemeral sessions end with their client's last link (after a minute). The HTTP component's links endpoint gains an `opened` hook. +- Chord v2's Node components and client surfaces are exported: `@earendil-works/chord/http`, `/workers`, `/plugins`, `/plugins/runtime` and `/app`; `/surfaces` (the web and terminal surfaces' server side), `/web`, `/react`, `/tui` and `/tui/launcher`. +- Chord v2's plugins component gains the plugin model (slice 12): `createPlugins({ api: { name, versions } })` checks every import of the app's versioned API (`@acme/app/v3`, per-kind modules such as `@acme/app/v3/web`): an unlisted version, another kind's module, two versions in one facet and a direct import of Chord are build errors naming the file and line. Roots may be `{ path, required }`: a required root's plugin failing at `load` rejects it with a `PluginError` after the load settled. Files named `..` (`contract.web.tsx`) are of that kind, refused in facets of another kind with the chain of imports named. Single-file plugins (`hello.server.ts` at a root's top, grouped by name, host packages only). `installPlugin({ git, ref } | { npm, version }, root, ctx)` installs plugins from git (a shallow clone of a branch, tag or commit; a repository of several plugins too) or npm; a package lists the plugin folders it provides in its `package.json` (`"chord": { "plugins": ["./notes", "plugins/*", "!plugins/draft"] }`), used by discovery and `installPlugin` (without it: one plugin when the package's top has facet files, else its subfolders with a `package.json`). `testPlugin(dir, { kind, modules, stubs, principal }, ctx)` builds a plugin as production does and loads it on an in-memory host beside stub facets, collecting its contributions to registries nobody serves and listing the contracts it waits for. Agents' guide: `docs/plugin-authoring.md`. +- Chord v2 gains the app kit (slice 13, `@earendil-works/chord/app`): `startServer

({ name, dataDir?, root?, listen?, api, kinds, principal, workers?, files?, install?, onError }, ctx)` lays out the data directory (`server/store.sqlite`, `workers//

/`, `plugins/`, `logs/`, `owner-token`; one server per data directory), creates the server's store and host, HTTP, one workers component per worker kind and the plugins component over the app's required root and the user's root, and loads the server's plugins with the kit's objects; `startWorker({ api, kinds, busy?, onError })` is a worker's entry (its directory and store, the link to the server first, its plugins). The start-data objects `AppInfo` and `WorkerInfo` serve process values to plugins. Sessions (`Sessions`: `issue`, `verify`, `revoke`, `list`; tokens kept as SHA-256 hashes, compared in constant time; persisted ones end after 400 days unused and their browser cookie is renewed daily while used, ephemeral ones live in memory, at most `limits.ephemeralSessions`) authenticate a signed `HttpOnly`, `SameSite=Strict` cookie or `Authorization: Bearer`; a one-time owner link per start (`app.ownerLink()`, the token in the URL's fragment, single use, 10 minutes), an owner token file (mode 0600, written atomically) and device pairing (`POST /_chord/pair`, owner approval, a poll returning the token once; bounded in all and per client address) sign the owner in. The data directory, its stores and secret files are made private (0700, 0600) at every start; the home directory, a file system's root and another user's directory are refused. `Files` per host: small and chunked writes at a stored offset, ranged reads, a watchable index, caps, at most `limits.uploads` uploads under way. `app.exportData(address, path, ctx)` and `app.importData(archive, address, ctx)` move the data a worker created (its store and files) as a tar without stopping anything: a running worker writes its own store at one consistent point, else the server reads it under the worker's process lock (import refusing an existing address, another app's archive, every path leaving the target, and archives past `limits.importBytes` or `limits.importEntries`). `app.applyChanges(ctx)` and `app.plugins.install(source, ctx)`. Optional plugins as exported facets: `defineUsers(profile)`, `inviteFacet()`, `ephemeralLoginFacet()`. +- Chord v2 gains web and terminal surfaces (slice 11): `webSurface` and `tuiSurface` (`@earendil-works/chord/surfaces`) build a client kind's base bundle from the app's entry at start (content-hashed, served forever) and publish its plugins' facets as scripts that register themselves (`chordFacet("", "", function (require, module, exports) {โ€ฆ})`) and one combined file, with `WebScripts` and `TuiScripts` showing the current set (a rollout step publishes without waiting for clients) and the page served through the app's own template (`PageAssets`, `pageScripts`). `startPage` (`@earendil-works/chord/web`) runs a page's client host: the connection loop (`keepConnected`: 250 ms doubling to 5 s, wakes, silent sockets, `canRetry`), plugins applied in place on a new set (a failed one keeps its old facet), a reload when the server's base bundle changed, and the active theme as CSS variables. React bindings (`@earendil-works/chord/react`): `HostProvider`, `useHold`, `useWatch`, `useRegistry`, `useRefState` (React is an optional peer dependency). The terminal: `startTerminal` (`@earendil-works/chord/tui/launcher`) signs in with a token, a token file or device pairing and runs the app's terminal code always in a sandbox (a child process on pipes with Node's permission model: no file system, terminal, processes, workers, network or SQLite; Node 26.5.1 or later), filtering its output, relaying its link and confirming its actions (copy, open a URL, attach a file the user names); `startTerminalRuntime` and `TuiScope` (`@earendil-works/chord/tui`) inside it. Themes: the `Themes` registry, `ThemeChoice` (one dark and one light pick per principal), `followActiveTheme`, `themeVariables`, `terminalColor`. `startServer` gains `web` and `tui`. Plugin builds scope `*.module.css` files per plugin and file. Ephemeral sessions end with their client's last link (after a minute). The HTTP component's links endpoint gains an `opened` hook. - Chord v2's `HttpRequest` gains `remoteAddress`, the peer's address as the listener knows it (for limits per client). - Chord v2's HTTP component gains `readSignedCookie(request, name, secret)`: `readCookie`'s value with its signed expiry, for renewing a cookie before it expires. diff --git a/packages/chord/README.md b/packages/chord/README.md index 081e3fe21..2d4b1f7f9 100644 --- a/packages/chord/README.md +++ b/packages/chord/README.md @@ -1,74 +1,83 @@ # @earendil-works/chord -Chord builds applications out of **objects** that live in several processes (a server, workers, browser tabs) and can be **hot reloaded** while they run. +Chord builds applications out of **objects** that live in several processes (a server, workers, browser tabs) and keep running while their plugins are **reloaded**. -- An **object** is state plus code at an address. It is created on demand and lives while someone references it. -- Everyone gets a **reference**, never the object. References work the same locally and across processes, and survive reloads. -- Every object knows its **principal**: an owner and a guest get different objects, with different methods. -- **State** is observable JSON. Remote viewers get a snapshot followed by deltas. -- **Hot reload** swaps code while it runs. Work in flight finishes on the code it started with, state is kept, and incompatible changes migrate at a safe point. +- An **object type** is a contract: a name, params that select the instance, the host it lives on, its members (state and methods) and a version. Contracts are runtime values described with JSON Schema, written with the builders of `@earendil-works/pi-schema`. +- A **facet** is a plugin's declarations for one host: the types it serves and its contributions to registries. A factory only declares; Chord activates. +- Everyone gets a **reference**, never the object. A reference is live and hydrated once its `get` resolves, works the same locally and across links, and keeps its object alive. +- **Documents** are named JSON values an object owns, written in transactions and persisted in Chord's store; **derives** compute values from watchables; **jobs** are owned work that outlives the call that started it. +- Every call has a **principal**: links stamp it, the app types it, and objects are kept per principal key. +- A **reload** swaps a plugin's code inside the running app, rolled out host by host: hosts keep running, data, connections and running work survive where they can. -Contracts are runtime values described with JSON Schema, written with the builders of `@earendil-works/pi-schema` (any JSON Schema object works; `format` is an annotation, never checked). Hosts exchange JSON frames over links: in memory, a Node IPC channel, or a WebSocket. +The design, the rule book for all of this, is [docs/design.md](docs/design.md). Chord v1, which p2 still runs on, stays available as `@earendil-works/chord/old` until p2 moves to v2 ([docs/old](docs/old/README.md)). ## Entry points | Import | Contents | Runs in | |--------|----------|---------| -| `@earendil-works/chord` | Contracts (`local`, `remote`, `method`, `opaque`), declarations (through the factory's `self`: `state`, `derive`, `resource`, `on`, `task`), hosts (`createHost`, `defineFacet`, `defineRegistry`), links (`memoryLinkPair`, `ipcLink`, `webSocketLink`, `acceptWebSockets`), errors (`ChordError`, `isChordError`, `forbidden`, `invalid`). Also the shared base: `Context`, `JsonValue`, `JsonRepresentation`, `Draft`, `copyJson`, `isJsonValue`, `replicatedState` with its types, and the watch types `WatchHandle`, `NativeWatchHandle`, `WatchCall`, `NativeWatchCall`, and `WatchEnd` with their implementations `Watch` and `NativeWatch`. | Node and browsers | -| `@earendil-works/chord/node` | Child host processes: `createHostManager`, `forkDriver`, `childControl`, `processLock`; the facet module loader `nodeLoader`. | Node | +| `@earendil-works/chord` | Contracts (`local`, `remote`, `method`, the schema builders), errors (`ChordError`, `isChordError`), hosts and facets (`createHost`, `defineFacet`), documents (`defineState`), derives and natives (`constant`, `mapShared`), routines and jobs (`defineJob`), links (`memoryLinkPair`, `ipcLink`, `webSocketLink`), registries (`defineRegistry`), the store (`openStore`, `defineTable`, queries, export and import), and the client surfaces' shared part (`Themes`, `ThemeChoice`, `WebScripts`, `TuiScripts`). | Node and browsers | +| `@earendil-works/chord/http` | HTTP: a Web-standard `fetch` handler (`createHttp`) built from the routes, wraps and sockets plugins contribute to the registry `Http`, authenticators (`Authenticators`), responses as descriptions, a security baseline on by default, Chord's Node listener and `nodeRequest`, the links endpoint. | Node | +| `@earendil-works/chord/workers` | Workers: `createWorkers` runs a forked worker per address of a host kind, started on demand and stopped when idle; `workerMain` is a worker's entry; `processLock`. | Node | +| `@earendil-works/chord/plugins` | Plugins: discovery, builds with esbuild (`buildFacet`), evaluation, the watcher, rollouts, `createPlugins`, `installPlugin`, `testPlugin`, `pluginFile`. | Node | +| `@earendil-works/chord/plugins/runtime` | `createPluginRuntime`: loads built plugins without esbuild (a worker's side). | Node | +| `@earendil-works/chord/app` | The app kit: `startServer`, `startWorker`, the start-data objects, sessions and the owner's sign-in, device pairing, files, export and import per address, optional plugins (users, invites, ephemeral login). | Node | +| `@earendil-works/chord/surfaces` | The client surfaces' server side: `webSurface` (base bundle, plugin scripts, the page) and `tuiSurface` (the terminal surface). | Node | +| `@earendil-works/chord/web` | The web surface's browser side: `startPage` in the app's web entry, `followThemes`. | Browsers | +| `@earendil-works/chord/react` | Optional React bindings: `HostProvider`, `useHold`, `useWatch`, `useRefState`, `useRegistry`, `watchStore`. | Browsers | +| `@earendil-works/chord/tui` | The terminal surface's sandbox side: `startTerminalRuntime` in the app's terminal entry, `BridgeTerminal`, `TerminalTheme`, `TuiScope`. | Node (sandboxed) | +| `@earendil-works/chord/tui/launcher` | The terminal launcher, the trusted side of a terminal client: `startTerminal`, `requireSandboxNode`. | Node | | `@earendil-works/chord/context` | Explicit cancellation, telemetry, and invocation values: `BACKGROUND_CONTEXT`, `withCancel`, `withAbortSignal`, `withoutAbortSignal`, `withTelemetry`, `traceIn`, `withContextValue`, `awaitWithContext`. | Node and browsers | | `@earendil-works/chord/delta` | The transactional JSON tracker, structural diff, immutable apply, and the wire encoder/decoder for operation batches. | Node and browsers | +| `@earendil-works/chord/json` | `JsonValue`, `JsonRepresentation`, `copyJson`, `isJsonValue`. | Node and browsers | +| `@earendil-works/chord/watch` | The watch types `Watchable`, `WatchHandle`, `NativeWatchable`, `NativeWatchHandle`, `WatchCall`, `NativeWatchCall`, and `WatchEnd`, with their implementations `Watch` and `NativeWatch`. | Node and browsers | | `@earendil-works/chord/output` | Bounded output streams and paced progress: `OutputBuffer` (head or tail window of a stream, `OutputLimits`, `OutputSkip`), `boundOutput`, `sanitizeOutput`, `utf8ByteLength`, and `Progress` (adaptive commits of a changing value). | Node and browsers | | `@earendil-works/chord/telemetry-sqlite` | `createSqliteTelemetry(db, { retentionMs?, maxQueuedSpans? })`: buffered recording and backend-independent `TelemetryStore` queries. | Any SQLite adapter | | `@earendil-works/chord/sqlite` | Portable `SqliteDatabase`, `SqliteExecutor`, and `SqliteValue`, atomic `applySqliteMigrations(database, migrations, { table })`, and `validateSqliteSchemaPrefix`. The metadata table must be a valid, non-reserved SQLite identifier; migration versions start at 1 and are contiguous. | Any SQLite adapter | | `@earendil-works/chord/sqlite/node` | `NodeSqliteDatabase`, `openNodeSqliteDatabase`, and `NodeSqliteDatabaseOptions`. | Node | | `@earendil-works/chord/sqlite/cloudflare` | `DurableObjectSqliteDatabase` and the structural `DurableObjectSqliteStorage` binding type. | Cloudflare Durable Objects | +| `@earendil-works/chord/old`, `@earendil-works/chord/old/node` | Chord v1, unchanged, kept for p2 until it runs on v2 ([docs/old](docs/old/README.md)). | Node and browsers; `/old/node` Node | + +`esbuild` (for `/plugins` and `/surfaces`), `ws` (for `/http` and `/tui/launcher`) and `react` (for `/react`) are optional peer dependencies, imported only there; `/app` uses all but `react`. ## Quick start ```ts -import { num, obj, str } from "@earendil-works/pi-schema"; -import { createHost, hostNamed, method, remote } from "@earendil-works/chord"; +import { createHost, defineFacet, local, method, obj, str, constant } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; -// contract.ts: shared by provider and consumers -export const Counter = remote("demo.counter", { +const context = BACKGROUND_CONTEXT; // every call takes a context, used for cancellation + +// A contract: params select the instance (one object per language), members are state and methods. +const Greeter = local("example.greeter", { version: 1, - input: obj({ name: str() }), - host: hostNamed("server"), // where its objects live; callers never name a host - variants: { - default: { - state: { count: num() }, - methods: { increment: method(obj({ by: num() })) }, - }, - }, + params: { language: str() }, + members: { language: str(), greet: method(obj({ name: str() }), str()) }, }); -const host = createHost({ name: "server", self: { kind: "server" } }); - -host.serve(Counter, ({ name }, _principal, self) => { - const count = self.state("count", num(), 0); - return { - variant: "default", - count, - increment: async ({ by }, ctx) => { - count.change(ctx, (n) => n + by); - }, - }; +// A facet serves types with factories; a factory only declares and returns the implementation. +const facet = defineFacet((host) => { + host.serve(Greeter, ({ language }) => ({ + language: constant(language), + greet: async ({ name }) => (language === "de" ? `Hallo ${name}` : `Hello ${name}`), + })); }); -await host.root(async (ctx) => { - const clicks = await ctx.get(Counter, { name: "clicks" }); // ready, with its state; released when this root ends - clicks.count.subscribe((n) => console.log("count", n)); - await clicks.increment({ by: 2 }, ctx); // logs 0, then 2 -}); +const host = createHost({ onError: (error) => console.error(error) }); +await host.load([{ name: "@example/greeter", facet }], context); + +const german = await host.get(Greeter, { language: "de" }, context); // live: state has values, methods can be called +console.log(german.language.value, await german.greet({ name: "Mario" }, context)); // de Hallo Mario +german.release(); // the last reference released ends the object +await host.close(context); ``` ## Documentation -- [Tutorial](docs/tutorial.md): a shared todo list, built up section by section. Every example runs as `test/tutorial.test.ts`. -- [Usage guide](docs/guide.md): API reference for contracts, objects, state, roots, lifetime, plugins, hot reload, hosts, and links. -- [Specification](docs/spec.md): compatibility, lifetime, and reload semantics, plus known limitations and implementation decisions. -- [Delta guide](src/delta/README.md): ownership, lifecycle, operation, and replica contracts of `@earendil-works/chord/delta`. +- [Design](docs/design.md): the target design, the one current statement of every rule; [decisions](docs/decisions.md): the decision log; [slices](docs/slices.md): the build plan and its carry-over. +- [Plugins and hosts](docs/guide-plugins-hosts/book.md): a tutorial building a notes app with plugins, HTTP and workers; [plugin authoring](docs/plugin-authoring.md): the guide for agents writing plugins. +- [Examples](test/examples/): runnable references, one topic each. Run from `packages/chord`: `node --conditions=source --experimental-strip-types test/examples/01-objects.ts`. +- Each layer's README in `src/*/README.md` and `src/node/*/README.md`; the [delta guide](src/delta/README.md): ownership, lifecycle, operation, and replica contracts of `@earendil-works/chord/delta`. +- [Chord v1](docs/old/README.md) (`@earendil-works/chord/old`): its tutorial, usage guide and specification. ## Explicit Context telemetry @@ -155,55 +164,6 @@ the draft changes. Published values are not frozen. In-process consumers may sha their containers with the provider; mutating a consumed value violates the contract and can corrupt authority. Clone or serialize at any mutable trust boundary. -Replicated state provides the same model through a callback. `replicatedState` is a -standalone observable value, independent of hosts: - -```ts -import { replicatedState } from "@earendil-works/chord"; - -const initial = { output: "", count: 0 }; -const status = replicatedState(initial); // transfers ownership of initial -status.change(context, (draft) => { - draft.output += "done\n"; - draft.count += 1; -}); -``` - -A successful `change()` publishes exactly one atomic revision. If its callback -throws, the original value and sequence remain unchanged. Draft references become -unusable when the callback returns. The tracker emits string append and -front-truncate operations, array splices and permutations, sets, and deletes; large -edit sets may fold into a complete replacement. - -`replicatedState(source, { onError })` instead attaches a publication-only state to -an authoritative revision source (`ReplicatedStateSource`): it captures a snapshot, -then publishes every committed frame in cursor order. - -### Public state subscriptions - -`state.subscribe(async (value, context, delivery) => { ... })` serializes callbacks -independently for each subscription. Hydration starts immediately when a value is -available, and its returned promise must settle before updates start. Synchronous -callbacks still run synchronously. Read the captured `value` inside an asynchronous -callback: `state.value` may already refer to a later revision. - -Each subscription retains at most 100 pending complete-value deliveries, excluding -the running callback. On overflow, only the newest pending value, context, and -delivery metadata are retained; a not-yet-started initial hydration is preserved. -Thus public delivery sequences may skip. This is a frame-count policy, not a byte -limit. - -The returned unsubscribe function immediately discards pending work and prevents -new callbacks. It neither aborts nor waits for the running callback. Synchronous -throws and promise rejections are observed, reported, and do not stop other -subscriptions or subsequent callbacks. Attached sources use their `onError` -handler; mutable states (and attached sources without a handler) report failures -by throwing in a microtask. Unsubscribing does not hide a later rejection from the -running callback. - -Cells of Chord objects and their remote readables have their own subscription -model; see [State](docs/guide.md#state) in the usage guide. - ### Watches `WatchHandle` is the one watch interface, implemented by watch sources such as diff --git a/packages/chord/docs/next/benchmarks.md b/packages/chord/docs/benchmarks.md similarity index 97% rename from packages/chord/docs/next/benchmarks.md rename to packages/chord/docs/benchmarks.md index 801a30c66..1a18a3bb2 100644 --- a/packages/chord/docs/next/benchmarks.md +++ b/packages/chord/docs/benchmarks.md @@ -5,8 +5,8 @@ Light benchmarks of hot paths, run by hand (not in CI), recorded per slice for l ## Slice 3a: remote objects over one link -Script: `test/next/bench/links.ts`, run from `packages/chord` with -`node --conditions=source --experimental-strip-types --expose-gc test/next/bench/links.ts` (about 15 s). Node 24.4.1, +Script: `test/bench/links.ts`, run from `packages/chord` with +`node --conditions=source --experimental-strip-types --expose-gc test/bench/links.ts` (about 15 s). Node 24.4.1, Intel Core i9-13900, one process: server and client host on one memory link (`queueMicrotask`), every case once per codec, side by side. @@ -125,7 +125,7 @@ Observations: ## Slice 3b: surviving drops -Script and machine as for slice 3a (`test/next/bench/links.ts` now runs the 3b cases after the 3a ones, about 37 s). +Script and machine as for slice 3a (`test/bench/links.ts` now runs the 3b cases after the 3a ones, about 37 s). New cases, both on the 1,000-item notes list view (133.7 KiB snapshot): @@ -174,8 +174,8 @@ Observations: ## Slice 4a: links and relays -Script: `test/next/bench/relay.ts`, run from `packages/chord` with -`node --conditions=source --experimental-strip-types --expose-gc --no-flush-bytecode test/next/bench/relay.ts` (about +Script: `test/bench/relay.ts`, run from `packages/chord` with +`node --conditions=source --experimental-strip-types --expose-gc --no-flush-bytecode test/bench/relay.ts` (about 5 s; the forked workers are the same file run with the argument `worker`). Machine as for slice 3a. Binary codec throughout. The topology is the one of slice 4a's example: a tab (a client host), a server with an address and a route for `Session`, and per session a worker host whose `Store` (a local document) backs a remote `View` placed on @@ -268,8 +268,8 @@ Observations: ## Slice 4b: authority and housekeeping -Script: `test/next/bench/compression.ts`, run from `packages/chord` with -`node --conditions=source --experimental-strip-types --expose-gc test/next/bench/compression.ts` (about 5 s). Node +Script: `test/bench/compression.ts`, run from `packages/chord` with +`node --conditions=source --experimental-strip-types --expose-gc test/bench/compression.ts` (about 5 s). Node 24.4.1, Intel Core i9-13900, one process. Payloads: the 500 KB document of slice 3a (500 entries `{ id, text, author, at }` of 960 characters), but with @@ -317,8 +317,8 @@ Observations: ## Slice 6a: the store -`test/next/bench/store.ts` (run by hand: `node --conditions=source --experimental-strip-types --expose-gc -test/next/bench/store.ts` from `packages/chord`): Node 24.4.1, `chord/sqlite/node` on a fresh SQLite file per burst +`test/bench/store.ts` (run by hand: `node --conditions=source --experimental-strip-types --expose-gc +test/bench/store.ts` from `packages/chord`): Node 24.4.1, `chord/sqlite/node` on a fresh SQLite file per burst for both sides (the same pragmas and file system), 7 bursts of 1,000 commits after a warm-up burst; per commit, the median and p95 of single commits and the burst's mean. @@ -456,12 +456,12 @@ The forwarded-link gap is not work or retention in 6a's code. It is a V8 decisio - pi a92283056 ("Delta's tracker holds its one open change without a WeakRef") removed the cause: the numbers above it show the forwarded link at HEAD's level with 6-7 MB promoted and 2 mark-compacts on both. -A retirement under a diamond of derives (`test/next/bench/derives.ts`: 40 derives in 13 layers of two derives joined +A retirement under a diamond of derives (`test/bench/derives.ts`: 40 derives in 13 layers of two derives joined by a third, 2^13 paths from top to bottom, the bottom watched; one step retires and recreates the document in one transaction): 9.8 ยตs median, 17.7 ยตs p95 per step with one visit per derive per batch; 349 ยตs without the visited set (one visit per path). -Binary `state` messages (`test/next/bench/links.ts`, against HEAD, alternating, pinned): an entry without retirements +Binary `state` messages (`test/bench/links.ts`, against HEAD, alternating, pinned): an entry without retirements costs no extra byte (165 / 27 / 23 B for one appended item, one changed field, one removed item, as at HEAD); encode and decode are at HEAD's level (one changed field, 200,000 runs, best of 9: encode 1,167-1,203 ns against 1,172-1,275 ns, decode 692 against 685-705 ns); heap per encode and decode 1,592 / 1,631 / 1,363 B against 1,684 / @@ -547,7 +547,7 @@ delta take 4 each (`SqliteStorage`: 5 and about 7). a fixed cost of the store (catalog, compiled statements, claims, the store's code), the same at both scales; heap after reads 0.13 โ†’ 0.16-0.18 MiB. Disk 0.61 โ†’ 0.58 MiB (1k), 4.34 โ†’ 4.38 MiB (10k). -**Chord's commit gate** (`test/next/bench/store.ts`), HEAD โ†’ build, two alternating runs each, medians: +**Chord's commit gate** (`test/bench/store.ts`), HEAD โ†’ build, two alternating runs each, medians: | Case | HEAD | build | | --- | --- | --- | @@ -579,7 +579,7 @@ each; the head lookup and scans under it are at parity or faster in the micro-be (one invocation per call of `run`, held state folded in a `PendingOps`): start 55.5 โ†’ 55.2 ยตs, immediate state change 21.3 โ†’ 21.2 ยตs, deferred 3.2 โ†’ 3.5 ยตs (the fold), in memory unchanged. -**Persisted jobs** (`test/next/bench/jobs.ts`, 7 bursts of 500, medians): a start (resolved after its commit) 8.4 ยตs in +**Persisted jobs** (`test/bench/jobs.ts`, 7 bursts of 500, medians): a start (resolved after its commit) 8.4 ยตs in memory, 55.5 ยตs persisted (two commits: the record and state created, then the reservation); a state change inside `run` 2.7 ยตs in memory, 21.3 ยตs persisted (one delta commit, as the gate's (c)), 3.2 ยตs deferred (stored with the outcome). @@ -590,7 +590,7 @@ Node 24.4.1, one CPU (`taskset -c 6`), runs alternating. HEAD is `391e83fb1`, ex (`/home/badlogic/pi-h8`); the build was measured in the worktree and, where the worktree itself skewed a result (below), in an extract of the same sources at `/home/badlogic/pi-x8`. -**Paths under every object** (`test/next/bench/calls.ts`, new: runs on HEAD as it is), median per operation over nine +**Paths under every object** (`test/bench/calls.ts`, new: runs on HEAD as it is), median per operation over nine bursts, heap allocated per operation, three alternating runs each, HEAD โ†’ build: | Case | HEAD | build | @@ -617,7 +617,7 @@ unchanged; its round trips are one cold burst each and vary as much between HEAD ยตs, text 7.66-7.72 โ†’ 7.70-7.83 ยตs in the extracts; the worktree itself runs the same sources at 7.8-7.9 ยตs (binary), an effect of the tree, not the code. -**Registries and writables** (`test/next/bench/registries.ts`, new), median over nine bursts: `writable.set` delivered +**Registries and writables** (`test/bench/registries.ts`, new), median over nine bursts: `writable.set` delivered to one watch 0.81-0.91 ยตs (2.9 KB allocated: the batch and the watch's call); a set of the same value 0.008 ยตs, 0 B (one comparison: its batch work is a method of its own, so `set` allocates no closure context); one of 10 contributions changed while the registry is watched 0.74-0.77 ยตs, of 100 1.52-1.59 ยตs (the table built again over every entry, one @@ -639,7 +639,7 @@ in six 3.4 ยตs on either variant tried: JIT). Node 24.4.1, one CPU (`taskset -c 6`), runs alternating. HEAD is `babe30a7e`, extracted at a path of the same length (`/home/badlogic/pi-h7`); the build in the worktree (`/home/badlogic/pi-7a`). -**Paths under every object** (`test/next/bench/calls.ts`), median per operation over nine bursts, heap allocated per +**Paths under every object** (`test/bench/calls.ts`), median per operation over nine bursts, heap allocated per operation, three alternating runs each, HEAD โ†’ build: | Case | HEAD | build | @@ -679,7 +679,7 @@ retry's operation id is made per `ref.retry()`, and an object keeps its handled Node 24.4.1, one CPU (`taskset -c 6`), runs alternating. HEAD is `0c3675e64`, extracted at a path of the same length (`/home/badlogic/pi-hb`); the build in the worktree (`/home/badlogic/pi-7b`). -**Paths under every object** (`test/next/bench/calls.ts`), median per operation over nine bursts, heap allocated per +**Paths under every object** (`test/bench/calls.ts`), median per operation over nine bursts, heap allocated per operation, alternating runs (the last two after the fixes below), HEAD โ†’ build: | Case | HEAD | build | @@ -710,7 +710,7 @@ contributions set 0.77-1.05 โ†’ 0.69-0.72 ยตs; of 100 1.57-1.58 โ†’ 1.54-3.30 ยต ยตs. The store (`store.ts`): every median within 0.3 ยตs. The relay (`relay.ts`, three runs): tab B alone 0.014 ms both; 10,000 calls at once 530-723 โ†’ 491-785 ms (the spread of either side). -**Reload** (`test/next/bench/reload.ts`, new): 20 plugins, 1,000 live objects (with params, a document, a derive and a +**Reload** (`test/bench/reload.ts`, new): 20 plugins, 1,000 live objects (with params, a document, a derive and a method each), one plugin reloaded 20 times; medians after two warm-up reloads, two runs: | Case | reload resolves | all live again | heap after 20 reloads, above after the first | @@ -799,7 +799,7 @@ The binary append differs unpinned (median +11%, p90 +31%) and is equal pinned: section, not per-append work. To compare commit-to-frame across two copies, run both at paths of equal length, pinned to one CPU, alternating, with the young generation pinned: - taskset -c 22 node --min-semi-space-size=16 --max-semi-space-size=16 --conditions=source --expose-gc test/next/bench/links.ts + taskset -c 22 node --min-semi-space-size=16 --max-semi-space-size=16 --conditions=source --expose-gc test/bench/links.ts Fix round 3 hot paths, `/tmp/s7b-hd-astra` โ†’ a build copy at a path of equal length, CPU 22, three alternating runs (`calls.ts`): local call 3.69-3.71 โ†’ 3.56-3.63 ยตs (6,894 โ†’ 6,660 B), watched derive commit 17.39-17.50 โ†’ 17.41-17.53 @@ -883,7 +883,7 @@ not. With text measured first the gap is 22.4-22.5 โ†’ 23.0-23.3 ยตs (+2-3%). V8 ## Slice 7c: plugins (2026-10-30) -**The plugins component** (`test/next/bench/plugins.ts`, new): 20 plugins, one worker facet each (a store object over a +**The plugins component** (`test/bench/plugins.ts`, new): 20 plugins, one worker facet each (a store object over a document, a derive, a method, a helper module and a copied contract; 80.9 KiB of scripts in all), Node 24.4.1. Medians of seven runs; three runs pinned to CPU 8, one unpinned: @@ -917,7 +917,7 @@ derive commit 10.34-10.36 โ†’ 10.43-10.49 ยตs (14,899 โ†’ 14,901 B), activation ## Slice 10: HTTP and workers (2026-10-31) -`test/next/bench/http.ts` and `test/next/bench/workers.ts`, Node 24.4.1, CPU 6 (the forked workers inherit the pin). +`test/bench/http.ts` and `test/bench/workers.ts`, Node 24.4.1, CPU 6 (the forked workers inherit the pin). | Measurement | Result | | --- | --- | @@ -939,7 +939,7 @@ it. the standard run grew from +4.5 ยตs to +20-21 ยตs (+41 ยตs before the Node fast path: the listener reads Node's parsed headers and makes a Web `Request` only when something reads `request.headers` or the body or a relay verifies; whole bodies are written as strings, in one write with the head). Warmed, +12-13 ยตs; a CPU profile of the warmed route path -(per request, `test/next/bench/http.ts`'s route): the listener's request function 13.6 ยตs inclusive against the plain +(per request, `test/bench/http.ts`'s route): the listener's request function 13.6 ยตs inclusive against the plain handler's 8.9 ยตs, of which writing the answer 8.3 ยตs (the plain handler's `writeHead` and `end`: 9.1 ยตs); `serve` 4.2 ยตs (the root scope 2.1, the URL parse 0.9, default headers 0.6, admission and routing 1.1, the answer 0.7); the root scope's seal in a later microtask 0.9 ยตs. The baseline's extra headers cost 0.4 ยตs (a plain handler sending them). @@ -960,7 +960,7 @@ to frame and encode/decode alike; reconnect of 1 / 100 references 0.94-1.15 / 80 ## Slice 12: the plugin model (2026-11-01) -**The build's checks** (`test/next/bench/plugins.ts`, the 7c set: 20 plugins, one worker facet each, a copied contract +**The build's checks** (`test/bench/plugins.ts`, the 7c set: 20 plugins, one worker facet each, a copied contract by relative path), Node 24.4.1, CPU 8, medians of seven runs, three alternating runs. HEAD `ebce9debd` (its bench importing the contract by plugin name, which HEAD resolves) โ†’ this build: cold build of the 20 facets 257.6-257.8 โ†’ 257.2-258.8 ms, rebuild of one facet 13.2-13.5 โ†’ 13.3-13.9 ms. With the app's API set and the kinds named (every diff --git a/packages/chord/docs/next/decisions.md b/packages/chord/docs/decisions.md similarity index 99% rename from packages/chord/docs/next/decisions.md rename to packages/chord/docs/decisions.md index a9647718a..57579953d 100644 --- a/packages/chord/docs/next/decisions.md +++ b/packages/chord/docs/decisions.md @@ -1,7 +1,7 @@ # Redesign decisions (input for target design v2) Decisions made with the owner after the plugin review round on `target-design.md` (6559589bd), in the order they were -made. Later entries supersede earlier ones; superseded entries are marked inline and point to their replacement. The target design v2 is `packages/chord/docs/next/design.md`, written from this log; new decisions land here +made. Later entries supersede earlier ones; superseded entries are marked inline and point to their replacement. The target design v2 is `packages/chord/docs/design.md`, written from this log; new decisions land here first and win until the design is updated. ## Plan @@ -13,7 +13,7 @@ first and win until the design is updated. (owner override of the "pi first" rule for this directory) and upstreamed to pi once stable; then `next/` replaces today's Chord and p2 is deleted. `next/` imports `../context`, `../delta`, `../json`, `../output` directly, so Durable's `Context`, `Draft` and `JsonValue` are the same modules and types in v2 (no copies, no type conflicts). - (Replaces "Chord v2 lives inside p3".) + (Replaces "Chord v2 lives inside p3". Now `src` and the package's root: "Chord v2 becomes the package's root".) - **Build a playground before p3:** a small system with p3's shape (server, worker processes over IPC, clients over WebSockets) and toy plugins, one per concept; it proves the concepts and reload and is the e2e test ground. Location `apps/chord-playground` (private). Client: a web page first (a CLI client possibly later). Order: kernel @@ -444,7 +444,7 @@ validation and copies the v2 kernel added around Delta. no view algebra, no `memo` API. - **Diffing and derived values come from Delta and today's Chord, not new code:** Delta's `diffRevisions` (tested, identity short-circuit) gets bytes as atomic leaves (compared by identity, replaced when different), and v2 calls - it directly; `next/diff.ts` is removed. Derives reuse today's derived cells (`chord/src/cell.ts`) on top of the + it directly; v2's `diff.ts` is removed. Derives reuse today's derived cells (`chord/src/cell.ts`) on top of the readable. Delta gets a small, pure, tested helper `mapShared(f)` (an identity cache per source element: a new object per changed element, the previous result for unchanged ones), used by derives that build a new object per source element; the cookbook documents it alongside the patterns. @@ -461,7 +461,7 @@ validation and copies the v2 kernel added around Delta. encodes, schema validations and materializations; per hop a test asserts the counts, e.g. one appended note to a 500 KB document with 10 viewers: no walks, no copies, one encode per link, no validations) and a `vitest bench` suite outside CI (500 KB and 1 MB values, 0/1/10 viewers, memory/SQLite, 1 MiB bytes) with results recorded - in `packages/chord/docs/next/benchmarks.md`. + in `packages/chord/docs/benchmarks.md`. - **Naming:** the pattern of a `local` object holding shared data behind per-principal views is the **shared store** (not "core"); base code and plugins use exactly the same primitives. @@ -659,7 +659,7 @@ validation and copies the v2 kernel added around Delta. schema-aware data-only normal form (`NORMAL_FORM_VERSION`; union and intersection order kept; `required`/`enum` sorted; TypeBox keyword whitelist; bytes as a `{ type: "bytes" }` data marker); history private, deep-copied and frozen (**superseded in part** by "L1 rewrite review": nothing is frozen). Schema helpers `str num int bool nul lit oneOf union obj arr map opt bytes unknown` + `type Static`. - Implemented and reviewed (Fable, Astra: thumbs up) in `packages/chord/src/next/contracts/` (`7d2bb8ea8`). + Implemented and reviewed (Fable, Astra: thumbs up) in `packages/chord/src/contracts/` (`7d2bb8ea8`). - **Q11, absent singletons (owner, 2026-10-21):** a singleton always has a value: `handle.value` is the written value or `initial()`, never `undefined` (an exposed singleton is typed `T`); `undefined` only for absent keyed documents (`handle.get(key)`); singleton existence has no API. A deliberate difference from Durable's `snapshot()`. @@ -1076,7 +1076,7 @@ validation and copies the v2 kernel added around Delta. step) is a later pi change, with L3d. - **L2 spec decisions (owner, 2026-10-22):** watchable state is JSON only (no bytes in documents, derives, reference members or any watchable; bytes only in method arguments and results and chunked transfers; Delta stays JSON-only; - supersedes W4's "JSON plus bytes" for watchables). `mapShared` lives in `next/watch/` until v2 goes upstream. C10 is + supersedes W4's "JSON plus bytes" for watchables). `mapShared` lives in v2's `watch/` until v2 goes upstream. C10 is rejected (`constant` and `writable` stay two kinds, Q14). One publication object per host, passed to its sources; no module-level singleton. No CBOR: the wire stays JSON plus raw byte segments (R1, Q4), revisited only if L6 benchmarks show encoding as a bottleneck. @@ -1087,7 +1087,7 @@ validation and copies the v2 kernel added around Delta. publication resets its phase and queues in a `finally`, so a throwing sink cannot leave it stuck; L2's size (about 680 lines) is accepted. - **Carry-over ledger (owner, 2026-10-22):** obligations deferred to later layers are recorded in - `packages/chord/docs/next/carry-over.md`, under the layer that must do them, by whoever defers them, in the same + `packages/chord/docs/next/carry-over.md` (later folded into `slices.md`), under the layer that must do them, by whoever defers them, in the same change; a layer's spec includes its section; done entries are deleted. The AGENTS.md style section states the rule. - **Vertical slices instead of layers (owner, 2026-10-22):** building strictly bottom-up made L2 grow generic machinery for callers that did not exist yet (nodes, sinks, deliveries, "publications"), hard to follow; its code was deleted, @@ -1098,7 +1098,7 @@ validation and copies the v2 kernel added around Delta. contexts and an `index.ts`/`internal.ts` split, `ff4f4456d`). Kept from L2: Chord's shared watch handle (`src/watch.ts`) and the decisions (JSON-only state, one batch per host, no CBOR, C10 rejected). Plain names from the design's vocabulary or common usage (a signals library's `batch`), never invented internal jargon in APIs. - Plan: `packages/chord/docs/next/slices.md`. + Plan: `packages/chord/docs/slices.md`. - **`Implementation` maps state members to watchables (owner, 2026-10-22; slice 1):** L1's `Implementation` types a state member as `Watchable>` (the document handle, derive or reference member the factory returns), not a getter `() => value`: a getter cannot tell Chord when a value changed (design ยง11). @@ -1187,7 +1187,7 @@ validation and copies the v2 kernel added around Delta. (option a, end-to-end acks, rejected for that). About 40 more lines than (a). - Open for the slice-4 spec: Astra's circuit breaker (a hard transport-buffer cap plus a stall or heartbeat deadline that closes the link). - Explainer: `packages/chord/docs/next/flow-control/` (Radius artifact 01m5n82vsbe5rtn4nm6wzaq0mp). + Explainer: `packages/chord/docs/flow-control/` (Radius artifact 01m5n82vsbe5rtn4nm6wzaq0mp). - **One pending queue for slow consumers of state (owner, 2026-10-23):** refines the snapshot fallback of "Flow control: an ack-clocked window" and supersedes "Watchable and one watch API"'s "after 100 pending frames the backlog becomes one root replacement" for state watches. Measured by Astra and Fable (`/tmp/fc2-*.md`, `/tmp/fc3-*.md`; real p2 entries plus synthetic stress @@ -1212,11 +1212,11 @@ validation and copies the v2 kernel added around Delta. Chord's shared `src/watch.ts` (pi first); tests and `examples/04-watches` change with the contract. - Unchanged: Durable's event stream (`watchEvents` batches are events: they keep their own queue until removed), `NativeWatch` (newest value), relays (drop + `reset { hold }`: parts are opaque). - Animation: `packages/chord/docs/next/flow-control/fold/` (Radius 01m5nc9s24e9kscppen2fxgwye). + Animation: `packages/chord/docs/flow-control/fold/` (Radius 01m5nc9s24e9kscppen2fxgwye). - **Slice 4 split and first decisions (owner, 2026-10-23):** slice 4 is split into 4a (links and relays: IPC and WebSocket links, trusted links, parts as opaque bytes, flow control, host kinds and placement, routes, relayed holds and calls) and 4b (revocation, cycles across hosts, `host.references`, `host.activity`, size limits, compression); - draft with structural changes and races: `packages/chord/docs/next/slice-4.md`. Decided: trusted links are an + draft with structural changes and races: `packages/chord/docs/slice-4.md`. Decided: trusted links are an explicit option (`trusted: true` on `accept` and in `resolve`'s result; default untrusted; stamping only from the parent link). ~~Resets and queue overflow travel as `[["r", value]]` ops in an ordinary `state` message~~ (**superseded** by "Slice 4a review decisions": resets are a list-`bound`; overflow stays an `r` op): a relay's @@ -1252,7 +1252,7 @@ validation and copies the v2 kernel added around Delta. `(value, reason, context)`; a local object's handlers act as the host's principal. Still open, listed in design ยง26 (#24-#29): the timeouts of later mechanisms, `host.root`'s signature, how a migration commit reaches consumers, compression on browser links, the circuit breaker, cuts C3/C4/C11. -- **Simplification pass after 4a (owner, 2026-10-24):** two cutters (Opus 5.5, GPT-6.1 Sol) read all of `src/next` +- **Simplification pass after 4a (owner, 2026-10-24):** two cutters (Opus 5.5, GPT-6.1 Sol) read all of v2 (`src/next`) without a line target (a target is not meaningful); the merged small cuts, two bug fixes (relays strip a client's principal fields on every path; a closed link delivers no queued message) and D1-D4 are applied by a fresh builder. D1: the unreachable "binding back to pending" branch of a served hold is cut from 4a; slice 7 builds it with reload @@ -1335,7 +1335,7 @@ validation and copies the v2 kernel added around Delta. queued). **No Durable special cases in Chord's store** (owner): the store never knows or waits for Durable's continuation. **Decided (owner, 2026-10-26), after four checks of the proposal (`/tmp/observers-proposal-*.md`, explainer - `packages/chord/docs/next/durable-observers/`):** publication at adoption in Opus's variant. Inside `adopt`, in + `packages/chord/docs/durable-observers/`):** publication at adoption in Opus's variant. Inside `adopt`, in HEAD's order: the trackers, the telemetry events, the queueing of one microtask that dispatches the host `subscribeCommits` listeners (the listener list read inside that microtask), the internal observers. Microtasks run in order, so host listeners still run before every wait continuation, abort and `onWake` of the commit (before @@ -1625,13 +1625,13 @@ validation and copies the v2 kernel added around Delta. - **Chord v2 and its docs live in pi upstream (owner, 2026-10-27: "we can put chord v2 in upstream", "the docs can all be public, and in upstream"):** `packages/chord/src/next`, `src/next-node`, `test/next`, `test/next-node` and `docs/next` moved to pi `main` (`93029a0f1`), not exported until v2 has an entry point (experimental, noted in the - changelog); the decision log moved from `apps/p2/docs/redesign-decisions.md` to `packages/chord/docs/next/decisions.md`; + changelog); the decision log moved from `apps/p2/docs/redesign-decisions.md` to `packages/chord/docs/decisions.md`; the root `AGENTS.md` carries the "Chord v2 Code Style" section. From now on every slice and every design doc change goes to pi first (worktree of `upstream/main`, check, tests, push, CI, merge into `private`); only `apps/` stays private. - **Slice 6b D1: `StoreStorage` and `durableView` live in Durable (owner, 2026-10-27: "they are only used if durable is used"):** in Durable's own `src` (an ordinary pi module, now that Chord v2 is upstream), importing - `@earendil-works/chord/next` (Chord's `./next` export comes with them). No package cycle: Durable already depends on + `@earendil-works/chord/next` (Chord's `./next` export comes with them; now the root export). No package cycle: Durable already depends on Chord, Chord imports nothing of Durable (S13). Durable's conformance suite runs in Durable's tests and CI. - **Slice 6b D2: Durable's records are ordinary declared tables of the store (owner, 2026-10-27: "a, that's the whole purpose of this slice"):** `StoreStorage` declares conversations, entries, tasks, submissions and `record_ids` as @@ -1861,8 +1861,8 @@ validation and copies the v2 kernel added around Delta. - **Slice 7c's points (owner, 2026-10-30; `slice-7c.md` ยง5):** (1) esbuild is an optional peer dependency of Chord, imported only by the plugins component. (2) **No dev/prod split** (owner: "chord apps are supposed to not have a prod/dev split. they are supposed to be self modifying applications"): watching, rebuilding and rolling out are core - machinery; one component `chord/next/plugins` (discovery, build, evaluation, `pluginFile`, the watcher, `rollout`) in - `src/next-node/plugins/`, exported with v2's entry point; it turns V8's compilation cache off when created; reloads + machinery; one component `chord/plugins` (discovery, build, evaluation, `pluginFile`, the watcher, `rollout`) in + `src/node/plugins/`, exported with v2's entry point; it turns V8's compilation cache off when created; reloads stay explicit (the watcher marks, never applies). Supersedes the separate `loader` and `dev` subpaths of "Slice 7b's open points" (5), (6). (3) `installDependencies(plugin, ctx)` as coding-agent installs package dependencies (`npm install --omit=dev --legacy-peer-deps --ignore-scripts --no-audit --no-fund` in the plugin's real directory, the @@ -1901,7 +1901,7 @@ validation and copies the v2 kernel added around Delta. and hands the plugin a `ws` WebSocket for its own protocol; patterns as routes; wraps do not apply; the links path is the component's (`host.accept`). The design's channel component (acknowledged byte channels) waits for a second user and would be built on top of it. - (D7, "a") `ws` is an optional peer dependency of Chord (pinned exactly), imported only by `next-node/http`, as + (D7, "a") `ws` is an optional peer dependency of Chord (pinned exactly), imported only by `node/http`, as esbuild for plugins. (D8, "a") Route patterns: exact segments, `:name` (one non-empty segment, percent-decoded, `params.name`) and a trailing `/*` (the rest, possibly empty, `params["*"]`); the most specific match wins, segment by segment from the @@ -1990,10 +1990,10 @@ validation and copies the v2 kernel added around Delta. `/chord` link or socket whose `Host` is no longer allowed closes (1008) when the allowed hosts change. - **Slice 11's points (owner, 2026-10-30; `slice-11.md`):** the surfaces are generic plumbing; the app keeps everything visible (owner: "this one needs to be generic, so apps can do whatever they want, css, tui components, - themes"). (P1, "a") `chord/next/web` ships serving the surface (the base bundle, the plugins' web scripts, - stylesheets and assets, the page through the app's template, all as `Http` contributions), the browser's client host - with its connection loop, and loading and applying the plugins' web facets; not HTML, CSS, components, themes, - navigation, slots or layout. + themes"). (P1, "a") `chord/web` (its server side now `/surfaces`) ships serving the surface (the base bundle, the + plugins' web scripts, stylesheets and assets, the page through the app's template, all as `Http` contributions), the + browser's client host with its connection loop, and loading and applying the plugins' web facets; not HTML, CSS, + components, themes, navigation, slots or layout. (P2, "script tag") A plugin's web script is served as a file that registers itself (`chordFacet("", "", function (require, module, exports) { โ€ฆ })`) and is loaded with `