@hraness/xcb 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/MANAGED-CODEX.md +213 -0
- package/README.md +555 -0
- package/dist/accounts.d.ts +46 -0
- package/dist/broker-descriptors.d.ts +5 -0
- package/dist/broker.d.ts +62 -0
- package/dist/browser-session.d.ts +161 -0
- package/dist/canonical-json.d.ts +2 -0
- package/dist/capabilities.d.ts +72 -0
- package/dist/claude-api-models.d.ts +24 -0
- package/dist/claude-api-transport.d.ts +5 -0
- package/dist/claude-api.d.ts +23 -0
- package/dist/claude-credentials.d.ts +13 -0
- package/dist/claude-options.d.ts +10 -0
- package/dist/claude-sdk.d.ts +48 -0
- package/dist/claude-task-adapter.d.ts +65 -0
- package/dist/cli.js +4190 -0
- package/dist/codex-account-process.d.ts +149 -0
- package/dist/codex-account-transport.d.ts +39 -0
- package/dist/codex-account.d.ts +126 -0
- package/dist/codex-config.d.ts +53 -0
- package/dist/codex-host.d.ts +40 -0
- package/dist/codex-managed-baseline.d.ts +5 -0
- package/dist/codex-managed-catalog.d.ts +32 -0
- package/dist/codex-managed-config.d.ts +93 -0
- package/dist/codex-managed-ledger.d.ts +37 -0
- package/dist/codex-managed-session.d.ts +62 -0
- package/dist/codex-managed-task-adapter.d.ts +21 -0
- package/dist/codex-process.d.ts +67 -0
- package/dist/codex-protocol-manifest.d.ts +27 -0
- package/dist/codex-relay.d.ts +80 -0
- package/dist/codex-scratch.d.ts +36 -0
- package/dist/codex-session.d.ts +44 -0
- package/dist/codex-task-adapter.d.ts +24 -0
- package/dist/codex-task-process.d.ts +21 -0
- package/dist/devin-acp.d.ts +105 -0
- package/dist/devin-adapter.d.ts +44 -0
- package/dist/devin-client.d.ts +36 -0
- package/dist/devin-mcp.d.ts +28 -0
- package/dist/egress-bridge.d.ts +35 -0
- package/dist/egress-client.d.ts +66 -0
- package/dist/index-kg2gx694.js +7217 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +3455 -0
- package/dist/judge.d.ts +121 -0
- package/dist/loopback-server.d.ts +17 -0
- package/dist/managed-account.d.ts +176 -0
- package/dist/models.d.ts +23 -0
- package/dist/os-sandbox.d.ts +168 -0
- package/dist/private-file.d.ts +215 -0
- package/dist/process-port.d.ts +44 -0
- package/dist/process-write.d.ts +13 -0
- package/dist/provider-process.d.ts +26 -0
- package/dist/public-web.d.ts +21 -0
- package/dist/router.d.ts +43 -0
- package/dist/runtime.d.ts +90 -0
- package/dist/sqlite-port.d.ts +29 -0
- package/dist/task-runtime.d.ts +150 -0
- package/dist/validation.d.ts +6 -0
- package/package.json +70 -0
- package/sandbox/loopback-forwarder.cjs +172 -0
package/README.md
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
<!-- hraness:xcb-landing:start -->
|
|
2
|
+
# xcb
|
|
3
|
+
|
|
4
|
+
xcb, short for Excalibur, routes coding tasks across the Claude, Codex, and
|
|
5
|
+
Devin subscriptions you already pay for. Each task runs on an account that is
|
|
6
|
+
signed in, idle, and not at a known usage limit, on a model that fits the
|
|
7
|
+
work, and xcb holds that account until the provider process has exited.
|
|
8
|
+
|
|
9
|
+
It is for developers who pay for more than one coding agent and want one
|
|
10
|
+
workflow around them: another agent can hand it work with one JSON command,
|
|
11
|
+
`xcb --json route`, an application can embed the TypeScript SDK, and the
|
|
12
|
+
terminal workspace is built on the same router. The native Rust app is a
|
|
13
|
+
source preview for supported Claude, Codex, and Devin runtimes. It includes
|
|
14
|
+
workspace file tools, an isolated Linux command runner, customizable panes,
|
|
15
|
+
and a separate application API. The managed harness, which is being rebuilt as
|
|
16
|
+
a self-evolving ALGAL harness, is in development and does not run
|
|
17
|
+
self-modifying routing policies. It does not replace every feature of the
|
|
18
|
+
providers' own tools; provider support and limits are listed below.
|
|
19
|
+
<!-- hraness:xcb-landing:end -->
|
|
20
|
+
|
|
21
|
+
[Project site](https://xcb.sh) · [Getting started](https://xcb.sh/docs/getting-started) ·
|
|
22
|
+
[Compare tools](https://xcb.sh/compare) · [Source](https://github.com/hraness/xcb) ·
|
|
23
|
+
[Route contract](docs/route.md) · [Application API](docs/application-api.md) · [Compatibility reference](docs/compatibility.md) · [Contributing](CONTRIBUTING.md)
|
|
24
|
+
|
|
25
|
+
xcb picks one signed-in, idle account for each task and keeps it locked until
|
|
26
|
+
the provider process has exited, so permission stays explicit: the design every
|
|
27
|
+
Hraness project shares.
|
|
28
|
+
[The thread through hraness](https://hraness.com/writing/the-thread-through-hraness)
|
|
29
|
+
follows that design across the projects, and the
|
|
30
|
+
[ALGAL vision](https://algal.computer/docs/vision/) states the bet behind it.
|
|
31
|
+
|
|
32
|
+
## Readiness
|
|
33
|
+
|
|
34
|
+
**xcb is not yet a daily-driver replacement for Codex, Claude Code, and Devin.**
|
|
35
|
+
The native broker lists, reads, searches, and writes workspace files, creates
|
|
36
|
+
directories, and removes or renames regular files with revision checks. The
|
|
37
|
+
source also includes an isolated Linux command runner for tests and builds on
|
|
38
|
+
macOS ARM64. The current backend passed its 12-case VM boundary suite, including
|
|
39
|
+
filtered Git inspection, public dependency fetching, and offline Cargo/Bun use
|
|
40
|
+
from immutable caches. Installed Claude and Codex coding workflows passed on
|
|
41
|
+
macOS ARM64: an expected test failure, exact repair, passing test, and filtered
|
|
42
|
+
Git status, with joined processes and settled effects. This evidence covers the
|
|
43
|
+
tested accounts and admitted builds. Devin's credential-free boundary checks
|
|
44
|
+
are separate from authenticated coding acceptance. See the [command runner contract](docs/command-runner.md)
|
|
45
|
+
for setup, supported boundaries, and current limits.
|
|
46
|
+
|
|
47
|
+
| Provider | Native Rust CLI | TypeScript compatibility CLI |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| Claude | Installed coding workflow verified on macOS ARM64 with the tested account; Linux remains an execution candidate after sign-in, binary admission, and confinement checks | Execution candidate, subject to its own admission and confinement checks |
|
|
50
|
+
| Codex | Native app-server on macOS for exact build **0.156.1**; credential-free boundary and tool-manifest checks passed; authenticated coding acceptance was recorded on the previous admitted build and has not been rerun on this one | Discovery only; managed task execution gated on host qualification |
|
|
51
|
+
| Devin | Native ACP candidate on macOS for exact builds **3000.11.3**, **3000.11.1** and **3000.10.31**; all passed credential-free boundary checks; model availability is checked against the connected account's fresh catalog at launch | ACP implementation exists; task execution disabled pending exact-runtime qualification |
|
|
52
|
+
|
|
53
|
+
A successful `doctor` or a visible model does not prove a working coding session.
|
|
54
|
+
The current Devin CLI can be authenticated and can return its model catalog, but
|
|
55
|
+
that provider login is separate from xcb's explicit credential import and from
|
|
56
|
+
an admitted coding turn. Devin validates the selected model against the
|
|
57
|
+
connected account's fresh catalog before each turn. The September 20, 2026
|
|
58
|
+
quota result is historical evidence, not a statement of current availability.
|
|
59
|
+
`xcb doctor` marks an unqualified provider build with ⚠ ("found, but xcb
|
|
60
|
+
can't run this build yet"). Codex and
|
|
61
|
+
Devin candidates require the checked executable digest as well as the version;
|
|
62
|
+
other builds and their Linux execution paths remain unavailable. Automated
|
|
63
|
+
fixtures check boundaries; they do not establish authentication, service
|
|
64
|
+
reliability, or real-model task quality. The TypeScript compatibility CLI's
|
|
65
|
+
Codex and Devin task routes remain unqualified and disabled.
|
|
66
|
+
|
|
67
|
+
## Native xcb
|
|
68
|
+
|
|
69
|
+
Native release binaries are built for macOS ARM64 (`darwin-aarch64`) and
|
|
70
|
+
Linux x86_64 (`linux-x86_64`) as `xcb-<version>-<platform>.tar.gz` with an
|
|
71
|
+
adjacent `.sha256` checksum; other hosts build from source. The
|
|
72
|
+
[release assets](https://github.com/hraness/xcb/releases) show the latest
|
|
73
|
+
verified version and the [project site](https://xcb.sh/download) reflects the
|
|
74
|
+
same datum. The source version number is a build identity, not a published
|
|
75
|
+
release. Releases tagged v0.3.0 and earlier are AgentMixer package archives,
|
|
76
|
+
not native xcb binaries.
|
|
77
|
+
|
|
78
|
+
### Install a verified release
|
|
79
|
+
|
|
80
|
+
On a supported platform, download the archive and checksum for your host from
|
|
81
|
+
the release assets, or let the installer fetch and verify one exact version
|
|
82
|
+
from a source checkout:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
XCB_VERSION=<version> ./scripts/install-native.sh
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The installer refuses a missing archive, a checksum mismatch, or an archive
|
|
89
|
+
that contains anything other than the `xcb` binary. When no verified native
|
|
90
|
+
release exists yet, install from source instead.
|
|
91
|
+
|
|
92
|
+
### Install from source
|
|
93
|
+
|
|
94
|
+
Requires Git, the pinned Rust **1.97.1** toolchain, and platform build tools.
|
|
95
|
+
Claude's supported execution boundary is macOS Seatbelt or Linux with a working,
|
|
96
|
+
admitted `bwrap` configuration. The native Codex and Devin candidates currently
|
|
97
|
+
require macOS Seatbelt; unsupported confinement fails closed.
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
git clone https://github.com/hraness/xcb.git
|
|
101
|
+
cd xcb
|
|
102
|
+
rustup toolchain install 1.97.1 --profile minimal
|
|
103
|
+
./scripts/install-native.sh
|
|
104
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
105
|
+
xcb --version
|
|
106
|
+
xcb --help
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The installer builds with the lockfile and installs `~/.local/bin/xcb`.
|
|
110
|
+
`XCB_INSTALL_PREFIX` changes the prefix; `XCB_ADD_PATH=yes` appends the bin
|
|
111
|
+
directory to your shell profile when it is not already on `PATH`. The
|
|
112
|
+
TypeScript compatibility CLI installs as `xcb-compat`, so it does not shadow
|
|
113
|
+
the native `xcb`; an older compatibility install that still used the `xcb`
|
|
114
|
+
name should be removed, and `command -v xcb` shows which binary answers.
|
|
115
|
+
The installer also records a private install manifest under the prefix and
|
|
116
|
+
keeps the exact installer beside the binary, so later upgrades use the same
|
|
117
|
+
verified path.
|
|
118
|
+
|
|
119
|
+
### Updates and global operation
|
|
120
|
+
|
|
121
|
+
The native binary is a user-global install when it lives in `~/.local/bin` and
|
|
122
|
+
that directory is on `PATH`. xcb follows an OpenCode-style policy: `notify` is
|
|
123
|
+
the default, `auto` installs only an exact stable release with its checksum,
|
|
124
|
+
and `disable` turns checks off. Scheduled checks are macOS-only: a LaunchAgent
|
|
125
|
+
runs the check once a day when you enable it, and it never reads project
|
|
126
|
+
settings or updates from `main`. On Linux, run `xcb update check` from your
|
|
127
|
+
own user timer; `xcb update enable` reports that scheduling is unavailable.
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
xcb update check
|
|
131
|
+
xcb update enable --policy notify # macOS only: check daily and tell you when a release exists
|
|
132
|
+
xcb update enable --policy auto # macOS only: check daily and install verified releases
|
|
133
|
+
xcb update status
|
|
134
|
+
xcb upgrade # install the latest verified native release
|
|
135
|
+
xcb update disable
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Native release binaries are built for macOS ARM64 (`darwin-aarch64`) and
|
|
139
|
+
Linux x86_64 (`linux-x86_64`). The updater installs only a verified
|
|
140
|
+
`xcb-<version>-<platform>.tar.gz` asset with its matching checksum for the
|
|
141
|
+
running host; on any other host, or when no such release exists yet, it fails
|
|
142
|
+
closed and leaves the installed binary alone. After any replacement, restart
|
|
143
|
+
open terminals; provider pins rebind to the new host build automatically while
|
|
144
|
+
their pinned provider bytes are unchanged.
|
|
145
|
+
|
|
146
|
+
Managed supervisors record their exact executable identity. When that binary
|
|
147
|
+
is replaced, a current supervisor stops starting new turns, retains custody of
|
|
148
|
+
its active workers until they settle, then exits. Queued tasks and tasks waiting
|
|
149
|
+
for input remain saved. Wait for that exit, restart the terminal, and reopen
|
|
150
|
+
the thread or project view to continue; provider pins rebind automatically.
|
|
151
|
+
A different running build produces an explicit supervisor-version error.
|
|
152
|
+
Legacy supervisors without an identity record need their exact process verified
|
|
153
|
+
and stopped after active workers settle; a saved PID or a deleted lock file is
|
|
154
|
+
not a safe replacement for that verification.
|
|
155
|
+
|
|
156
|
+
Managed records can gain fields that older source builds reject. Restart old
|
|
157
|
+
clients and supervisors before using updated managed state, and retain that state
|
|
158
|
+
during an installation rollback. Replacing the binary does not migrate provider
|
|
159
|
+
sessions or establish fresh live acceptance across all three providers.
|
|
160
|
+
|
|
161
|
+
### First managed conversation
|
|
162
|
+
|
|
163
|
+
Install an admitted Claude Code binary (major 2, version 2.1.268 or newer).
|
|
164
|
+
xcb performs its own account sign-in below; it does
|
|
165
|
+
not silently import your existing provider login. Replace `<account-id>` below
|
|
166
|
+
with the generated ID printed by `accounts add` or `accounts import-*` (the
|
|
167
|
+
`xcb accounts` ID column is shortened; `xcb accounts --json` lists full IDs).
|
|
168
|
+
Account names come from observed provider identities;
|
|
169
|
+
custom labels are not accepted.
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
xcb setup claude --plan Max
|
|
173
|
+
xcb --cwd /absolute/path/to/your/project
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`xcb setup` adds the account (or reuses the one you have), checks Claude Code
|
|
177
|
+
the way `xcb doctor` does, opens the browser sign-in, and loads the account's
|
|
178
|
+
models. Each step is also its own command:
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
xcb accounts add claude --plan Max
|
|
182
|
+
xcb doctor --provider claude
|
|
183
|
+
xcb accounts login <account-id>
|
|
184
|
+
xcb accounts refresh <account-id>
|
|
185
|
+
xcb models
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Plain `xcb` opens your thread from any directory. The thread is one managed
|
|
189
|
+
conversation per machine that spans your projects: xcb picks the project
|
|
190
|
+
directory each task runs in and says why in its reply, for example
|
|
191
|
+
“Started Fix the parser in `xcb` · named `xcb` · /workspace to move”.
|
|
192
|
+
It uses a path or project name in the prompt, the project you focused with
|
|
193
|
+
`/workspace`, the task you are continuing, and only then the directory you
|
|
194
|
+
launched from, so `--cwd` is a hint. When none of these settles it, xcb asks
|
|
195
|
+
which project, keeps your draft, and saves nothing. A less certain choice, or
|
|
196
|
+
a prompt that names a project other than the focused one, waits 8 seconds
|
|
197
|
+
before it starts so you can move it with `/workspace <name|path>`. xcb only
|
|
198
|
+
picks directories you have used or registered: `/workspace add <dir>` or
|
|
199
|
+
`xcb workspaces add <dir>` registers one, and xcb refuses your home directory,
|
|
200
|
+
its hidden directories, `~/Library`, xcb's own state and system directories.
|
|
201
|
+
`xcb chat --new` starts a separate project view whose tasks all run in the
|
|
202
|
+
current directory.
|
|
203
|
+
|
|
204
|
+
Prompts become durable managed tasks routed through admitted Codex, Claude, or
|
|
205
|
+
Devin sessions; closing the terminal detaches without cancelling them. Open
|
|
206
|
+
another terminal for another view of the same task swarm, use `/tasks` to
|
|
207
|
+
inspect work, or `/sessions` to switch between the thread and project views.
|
|
208
|
+
Ordinary prompts create new work.
|
|
209
|
+
In the v0.7 terminal, select a task in `/agents` and press `s` to guide it or `a`
|
|
210
|
+
to answer its current question; the prompt displays the target. `/task` returns
|
|
211
|
+
to new work and Tab queues it. Independent workspaces can run concurrently;
|
|
212
|
+
tasks in the same workspace, or in a directory inside it, run one at a time. Use
|
|
213
|
+
`/cancel <task-id>` to request cancellation and inspect `/tasks` for settlement.
|
|
214
|
+
|
|
215
|
+
A project is a directory. Its backlog, work history, autonomy grant, working
|
|
216
|
+
memory and Wordcell binding belong to that directory and are shared by the
|
|
217
|
+
thread and every project view over it. A grant authorizes automatic work only
|
|
218
|
+
in its own directory, even though the thread holds tasks for several.
|
|
219
|
+
Use `/backlog` for this conversation's backlog (in the thread, narrowed to the
|
|
220
|
+
focused project) and `/backlog all` to browse all
|
|
221
|
+
projects. `/attention` collects questions, approvals and actions across agents.
|
|
222
|
+
Use `/steer <task-id> <guidance>` to queue guidance for a task's next safe turn,
|
|
223
|
+
and `/inbox` to inspect acceptance and delivery. `/watch <target-id> <source-id>`
|
|
224
|
+
requests a completion report in the target's inbox. Available reports and messages
|
|
225
|
+
share a bounded batch; they do not renew budgets or reopen closed work. The CLI
|
|
226
|
+
offers the same `steer`, `watch` and `inbox` controls, including stable IDs for
|
|
227
|
+
retries and paginated JSON inspection.
|
|
228
|
+
Deferred work can be edited, released, or completed with a summary. `/project
|
|
229
|
+
grant [project] <tasks> <hours> <goal>` delegates a bounded follow-up budget;
|
|
230
|
+
`/project pause` holds future automatic work. In the thread, `/project` and
|
|
231
|
+
`/memory` use the project you name, then the focused project, then the selected
|
|
232
|
+
task's directory; `/schedule` and `/backlog add` use the focused project or the
|
|
233
|
+
selected task's directory. None of them guesses: without a project they ask and
|
|
234
|
+
save nothing. `/schedule` manages recurring prompts, and
|
|
235
|
+
`xcb schedules program` pins bounded ALGAL planners. Starting in v0.6.0, add
|
|
236
|
+
`--managed-calls 2`
|
|
237
|
+
to run a controller that can suspend for up to two ordinary worker tasks, or use
|
|
238
|
+
`xcb backlog program` to run one immediately. `/program` and
|
|
239
|
+
`xcb backlog program-status <task-id>` show its linked child, progress and
|
|
240
|
+
receipt. Every occurrence retains its normal task history and
|
|
241
|
+
attention states. Workers can propose follow-ups,
|
|
242
|
+
read recent summaries, and search an explicitly bound Wordcell vault. Explicit
|
|
243
|
+
note promotion keeps long-term knowledge separate from working memory. See
|
|
244
|
+
[persistent project agents](docs/project-agents.md) and [opt-in login
|
|
245
|
+
startup](docs/habitat-service.md) for controls and limits.
|
|
246
|
+
|
|
247
|
+
The Rust supervisor owns scheduling and deterministic safety decisions. ALGAL
|
|
248
|
+
records bounded transition receipts; it does not infer permissions, establish
|
|
249
|
+
provider qualification, or replace the supervisor’s execution policy.
|
|
250
|
+
`xcb tasks verify <task-id>` replays that task’s local receipt chain and checks
|
|
251
|
+
it against the current record; it does not attest provider claims or real-world
|
|
252
|
+
outcomes.
|
|
253
|
+
|
|
254
|
+
Managed routing and unpinned `xcb run` first filter for qualified, credentialed,
|
|
255
|
+
idle, quota-usable accounts. ALGAL's fitted classifier can select a capability
|
|
256
|
+
tier through one bounded typed judgment; routing works deterministically when
|
|
257
|
+
that optional service is absent. Substantial prompts use the highest known
|
|
258
|
+
quality among eligible models. Quota-driven downgrades are visible. Explicit
|
|
259
|
+
provider/model requests remain constraints; routine work still considers
|
|
260
|
+
relative cost, latency and workspace preferences. Official temporary
|
|
261
|
+
offers are cached as expiring observations. They do not prove account entitlement
|
|
262
|
+
or reduce a route’s estimated cost without that evidence. They never activate an
|
|
263
|
+
unqualified provider or survive stale terms. Managed Claude, Codex and Devin workers share
|
|
264
|
+
`xcb_swarm_status`, `xcb_message_list` and `xcb_message_send` for durable,
|
|
265
|
+
workspace-scoped cross-provider coordination.
|
|
266
|
+
|
|
267
|
+
A settled authentication failure marks that account as requiring reconnection
|
|
268
|
+
and excludes it from new task routes, including after restart. Other eligible
|
|
269
|
+
accounts still respect the requested provider. Successful sign-in or an explicit
|
|
270
|
+
import with changed credential material clears the block; catalog refresh and
|
|
271
|
+
reimporting the same credentials do not. Older failure records have no credential
|
|
272
|
+
generation binding, so an upgraded account may need one new bounded attempt to
|
|
273
|
+
establish this block.
|
|
274
|
+
|
|
275
|
+
`--plan` is a display label; it does not verify your subscription. Complete the
|
|
276
|
+
browser sign-in when prompted. `accounts refresh` probes supported model and
|
|
277
|
+
usage metadata. Unknown or stale usage percentages remain unknown. A proven
|
|
278
|
+
Claude account-wide quota exhaustion stays blocked until its reported reset,
|
|
279
|
+
even when its percentage has gone stale. The account list shows a retry estimate;
|
|
280
|
+
see [quota routing](docs/quota-routing.md) for the scope and credential binding.
|
|
281
|
+
You do not need to select a model for managed chat or `xcb run`. To pin a model
|
|
282
|
+
for a direct run, pass its full observed key with `--model`; stored direct
|
|
283
|
+
sessions keep their existing binding. Begin a managed task with `Use Claude`,
|
|
284
|
+
`Use Codex`, or `Use Devin` when you want to require that provider.
|
|
285
|
+
|
|
286
|
+
If discovery finds the wrong binary, use
|
|
287
|
+
`xcb doctor --provider claude --executable /absolute/path/to/claude`.
|
|
288
|
+
The pin binds a private copy of the executable bytes plus version, so a
|
|
289
|
+
provider auto-update cannot move the pinned install: xcb adopts an updated
|
|
290
|
+
build automatically only when it is an admitted version and keeps routing the
|
|
291
|
+
pinned build otherwise. For exact-artifact providers, admission also accepts
|
|
292
|
+
reviewed (version, digest) pairs published in the repository's
|
|
293
|
+
`qualified-builds.json`: a discovered build nothing yet admits is parked as
|
|
294
|
+
awaiting catalog admission (`xcb doctor` reports it), and a published entry
|
|
295
|
+
adopts it on the next hourly refresh without an xcb upgrade. The catalog is
|
|
296
|
+
admission-only — a denied digest is rejected outright, and the stored copy
|
|
297
|
+
is reused when the network is unavailable. After upgrading xcb, restart open
|
|
298
|
+
xcb terminals; the
|
|
299
|
+
pins rebind to the new host build on next use. A process started from the old
|
|
300
|
+
binary cannot adopt the replacement binary's pin, and older clients refuse
|
|
301
|
+
new run records whose credential-custody format they do not understand.
|
|
302
|
+
An account, metadata pin, or model listing cannot activate an unqualified adapter.
|
|
303
|
+
|
|
304
|
+
### Connect Codex on macOS
|
|
305
|
+
|
|
306
|
+
Use the exact admitted **0.156.1** build. Its credential-free boundary and
|
|
307
|
+
tool-manifest checks passed on macOS ARM64. Authenticated broker read/write/read
|
|
308
|
+
and installed coding-workflow acceptance were recorded on the previous admitted
|
|
309
|
+
build (0.155.0-alpha.2.6) and have not been rerun on this one. None of this
|
|
310
|
+
qualifies arbitrary provider versions or the separate application API. xcb supervises the official
|
|
311
|
+
CLI's ChatGPT device sign-in in a private profile:
|
|
312
|
+
|
|
313
|
+
```sh
|
|
314
|
+
xcb doctor --provider codex
|
|
315
|
+
xcb accounts add codex --plan ChatGPT
|
|
316
|
+
xcb accounts login <account-id>
|
|
317
|
+
xcb accounts refresh <account-id>
|
|
318
|
+
xcb models
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Follow the device sign-in instructions shown in the terminal. Alternatively,
|
|
322
|
+
copy one existing ChatGPT credential into a new xcb account by selecting its
|
|
323
|
+
private `auth.json` explicitly:
|
|
324
|
+
|
|
325
|
+
```sh
|
|
326
|
+
xcb accounts import-codex --source /absolute/path/to/auth.json
|
|
327
|
+
xcb accounts refresh <account-id>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The source file is preserved. Import does not copy provider configuration,
|
|
331
|
+
plugins, sessions, or transcripts. API-key credentials are not accepted by this
|
|
332
|
+
route. Refreshed ChatGPT credentials are persisted only after the owned provider
|
|
333
|
+
process has joined.
|
|
334
|
+
|
|
335
|
+
### Connect Devin on macOS
|
|
336
|
+
|
|
337
|
+
Use the exact admitted **3000.11.3** build; **3000.11.1** and **3000.10.31**
|
|
338
|
+
remain admitted. All passed credential-free native boundary checks; authenticated coding
|
|
339
|
+
acceptance requires separate evidence for the account, model, and build.
|
|
340
|
+
Model availability is checked against the connected account's fresh catalog at
|
|
341
|
+
launch. xcb preserves an unknown quota reset as unknown. Sign in through the
|
|
342
|
+
provider CLI, then explicitly select its
|
|
343
|
+
`credentials.toml` to create a private xcb account:
|
|
344
|
+
|
|
345
|
+
```sh
|
|
346
|
+
devin auth login
|
|
347
|
+
xcb doctor --provider devin
|
|
348
|
+
xcb accounts import-devin --source /absolute/path/to/credentials.toml
|
|
349
|
+
xcb accounts refresh <account-id>
|
|
350
|
+
xcb models
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
The source file and provider sessions are preserved. xcb copies only the
|
|
354
|
+
credential for the supported provider endpoints. To update just the catalog,
|
|
355
|
+
use `xcb models refresh devin --account <account-id>`; Devin discovery requires
|
|
356
|
+
an explicitly connected account. Native Devin currently uses fixed ACP model
|
|
357
|
+
choices. Adaptive and Fusion catalog representations in the compatibility
|
|
358
|
+
package do not establish native support.
|
|
359
|
+
|
|
360
|
+
For either provider, `xcb run` automatically selects an eligible model. An
|
|
361
|
+
optional explicit default for direct interactive sessions can be set with a
|
|
362
|
+
full matching key from `xcb models` using `xcb models default <key>`. Select the account with
|
|
363
|
+
`xcb accounts default <account>` for new direct sessions, or pass
|
|
364
|
+
`--account <account> --model <key>` to `xcb run`. A provider upgrade is not
|
|
365
|
+
automatically admitted; xcb keeps routing the pinned qualified build until an
|
|
366
|
+
xcb release qualifies the new artifact.
|
|
367
|
+
|
|
368
|
+
### Isolated tests, builds, and Git
|
|
369
|
+
|
|
370
|
+
Project commands use an explicitly provisioned Linux VM through `workspace_exec`.
|
|
371
|
+
Follow the [command runner setup](docs/command-runner.md#setup-and-admission)
|
|
372
|
+
from the same source checkout as the installed native CLI. Commands run offline
|
|
373
|
+
against a staged workspace; host dependencies, credentials, and build products
|
|
374
|
+
are excluded. Native macOS and Xcode builds are unavailable. The explicit
|
|
375
|
+
[public dependency preparation frontend](docs/command-runner.md#dependencies-and-git)
|
|
376
|
+
passed the current VM boundary suite, including rejection of a cache after its
|
|
377
|
+
manifest changed. Installed Claude and Codex coding workflows passed on macOS
|
|
378
|
+
ARM64 with the tested accounts; other repositories and toolchains still need
|
|
379
|
+
their own checks.
|
|
380
|
+
|
|
381
|
+
The Git projection is limited to filtered, read-only HEAD and index data for
|
|
382
|
+
status and diffs. Original history, remotes, and hooks are omitted; commit and
|
|
383
|
+
push workflows are unavailable. Publication checks file revisions and replaces
|
|
384
|
+
each file atomically; it is not a transaction across every changed file. Failed,
|
|
385
|
+
cancelled, or uncertain command state is retained. Successfully published and
|
|
386
|
+
durably settled commands remove their verified input snapshot.
|
|
387
|
+
|
|
388
|
+
### Application integration
|
|
389
|
+
|
|
390
|
+
The [application API](docs/application-api.md) provides bounded, ephemeral
|
|
391
|
+
inference with no tools or hooks. It requires evidence for the exact xcb binary,
|
|
392
|
+
provider, account and model before accepting application traffic.
|
|
393
|
+
[Textbutler](https://github.com/hraness/textbutler), an MIT-licensed reference
|
|
394
|
+
application, keeps its contact access and messaging approval in its own host.
|
|
395
|
+
Sign-in and a successful `doctor` alone do not qualify the application route.
|
|
396
|
+
|
|
397
|
+
### Everyday commands
|
|
398
|
+
|
|
399
|
+
```sh
|
|
400
|
+
xcb # your thread, from any directory
|
|
401
|
+
xcb --cwd /absolute/path/to/your/project # the thread, hinting this project
|
|
402
|
+
xcb chat --new # a new project view for this directory
|
|
403
|
+
xcb conversations # the thread and project views
|
|
404
|
+
xcb chat --resume <conversation-id>
|
|
405
|
+
xcb workspaces # project directories the thread picks from
|
|
406
|
+
xcb tasks # global managed task swarm
|
|
407
|
+
xcb backlog # backlog and work history across projects
|
|
408
|
+
xcb attention # questions, approvals and actions
|
|
409
|
+
xcb schedules # durable recurring prompts
|
|
410
|
+
xcb projects # project goals and remaining autonomy grants
|
|
411
|
+
xcb memory status <dir> # explicit Wordcell binding
|
|
412
|
+
xcb service status # opt-in macOS login startup
|
|
413
|
+
xcb tasks verify <task-id> # verify local transition receipts
|
|
414
|
+
xcb tasks messages <task-id> # durable cross-provider mailbox
|
|
415
|
+
xcb offers --refresh # refresh official expiring offers
|
|
416
|
+
xcb models tiers --task "fix a race" # inspect Pareto layers
|
|
417
|
+
xcb models route --task "fix a race" # preview the eligible smart route
|
|
418
|
+
xcb --cwd /absolute/path/to/your/project run --account <account-id> -p "Explain this repository"
|
|
419
|
+
xcb sessions # direct provider sessions
|
|
420
|
+
xcb resume # latest direct provider session
|
|
421
|
+
xcb resume <session-id>
|
|
422
|
+
xcb accounts
|
|
423
|
+
xcb config
|
|
424
|
+
xcb plugins
|
|
425
|
+
xcb panes
|
|
426
|
+
xcb doctor
|
|
427
|
+
xcb completions zsh > /path/to/completions/_xcb
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
For another program — typically a coding agent — `xcb --json route` is the
|
|
431
|
+
closed machine contract: one JSON task document on stdin selects an eligible
|
|
432
|
+
account/model route and runs exactly one bounded turn, returning the selected
|
|
433
|
+
route, saved session id, and settled outcome facts as bounded JSON. See
|
|
434
|
+
[the route contract](docs/route.md).
|
|
435
|
+
|
|
436
|
+
`xcb chat --resume` reopens the thread or a project view; `xcb resume` opens a saved
|
|
437
|
+
direct provider session and its workspace. Neither is a headless continuation
|
|
438
|
+
command. `/help` lists terminal commands. The [terminal guide](docs/terminal.md)
|
|
439
|
+
covers editing keys, optional Vim editing, transcript search, agent guidance,
|
|
440
|
+
and draft recovery.
|
|
441
|
+
Conversations, tasks, provider
|
|
442
|
+
sessions, and credentials live in the private native state root
|
|
443
|
+
`~/.local/share/xcb`; `--state /absolute/path` or `XCB_STATE` overrides it.
|
|
444
|
+
The `xcb-compat` compatibility CLI uses `~/.xcb` instead. Do not point both
|
|
445
|
+
implementations at the same state directory. `xcb --json run` includes the native session ID
|
|
446
|
+
in its result so it can be reopened with `xcb resume <session-id>`.
|
|
447
|
+
|
|
448
|
+
One provider turn has a 30-minute default deadline, including initialization.
|
|
449
|
+
The `turn_timeout_ms` setting in the private state root's `config.json` accepts
|
|
450
|
+
1,000–3,600,000 milliseconds (one second to 60 minutes); `xcb config` displays the
|
|
451
|
+
effective configuration. Older configurations that omit it use the default.
|
|
452
|
+
Cancellation remains available before the deadline, and automatic continuation
|
|
453
|
+
has its own separate limits.
|
|
454
|
+
|
|
455
|
+
Control conversations are concurrent and share one durable task supervisor.
|
|
456
|
+
Each account still owns at most one active provider turn, and one workspace can
|
|
457
|
+
have only one admitted writer even when different accounts or terminals are
|
|
458
|
+
available. Independent workspaces and accounts can run concurrently; a
|
|
459
|
+
workspace and a directory inside it take turns. Managed
|
|
460
|
+
cancellation may be requested from the task’s originating conversation or by an
|
|
461
|
+
explicit task ID/title elsewhere. In the thread, a bare `/cancel` cancels the
|
|
462
|
+
selected task or the only cancellable one; when several could be cancelled it
|
|
463
|
+
asks which, listing each task's project. Direct provider-session cancellation is
|
|
464
|
+
owned by its terminal. Ctrl-C and SIGTERM request bounded cleanup for a headless
|
|
465
|
+
run. `xcb run` reports success only for a completed, joined, settled idle result.
|
|
466
|
+
|
|
467
|
+
Cancellation joins the owned process before releasing custody. If `doctor`
|
|
468
|
+
reports an unsettled run, inspect `xcb recover` and the process state; an expired
|
|
469
|
+
lease or a quiet terminal is not proof that the provider stopped. Recovery is
|
|
470
|
+
an explicit operation, not a reason to delete state or lock files.
|
|
471
|
+
|
|
472
|
+
### Fleet and remote devices
|
|
473
|
+
|
|
474
|
+
Each machine can enroll as a device on a shared relay fleet. Linked machines
|
|
475
|
+
publish an encrypted presence and task projection and accept fenced commands;
|
|
476
|
+
a controller device or another enrolled machine drives them through the same
|
|
477
|
+
CLI. Remote task content stays encrypted at the device boundary.
|
|
478
|
+
|
|
479
|
+
```sh
|
|
480
|
+
xcb link --relay <relay-url> --email <owner email> # enroll this machine (email one-time code)
|
|
481
|
+
xcb remote admit <device> # admit a newly linked device
|
|
482
|
+
xcb fleet # devices, presence, projection staleness
|
|
483
|
+
xcb dispatch <device> <workspace> -p "<task>" # run a managed task on a remote machine
|
|
484
|
+
xcb remote status <command-id> --wait # wait for a posted command to settle
|
|
485
|
+
xcb remote steer|cancel|answer <device> <task> # drive a remote task
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
Ids may be typed as unambiguous prefixes (`xcb remote cancel 513c t_a65b`).
|
|
489
|
+
Every remote verb is `--json`-scriptable with closed exit codes, which is the
|
|
490
|
+
contract a driving agent (for example a bot) should use. See
|
|
491
|
+
[remote operations](docs/remote-operations.md) for enrollment, controller
|
|
492
|
+
semantics and recovery.
|
|
493
|
+
|
|
494
|
+
### Optional behavior
|
|
495
|
+
|
|
496
|
+
Auto-continue and Gobstopper context management default on with bounded
|
|
497
|
+
continuation and settled-boundary checks. Disable either with
|
|
498
|
+
`xcb plugins disable auto-continue` or `xcb plugins disable gobstopper`.
|
|
499
|
+
Local usage measurement stays local. aiCharts upload is unavailable; local
|
|
500
|
+
exports, external judgment, and executable hooks require separate opt-in.
|
|
501
|
+
Panes are presentation data and cannot grant execution authority.
|
|
502
|
+
|
|
503
|
+
The optional judge uses TypeSafe System One (`jev-latest`) to advise routing,
|
|
504
|
+
continuation, and context retention. It sends bounded task/response context to
|
|
505
|
+
that service; old tool-result bodies are excluded from compaction advice.
|
|
506
|
+
A judge cannot qualify a provider or bypass deterministic safety gates.
|
|
507
|
+
Store a key through stdin on macOS or Linux, then explicitly enable it:
|
|
508
|
+
|
|
509
|
+
```sh
|
|
510
|
+
xcb judge token < /secure/path/to/judge-key
|
|
511
|
+
xcb judge status
|
|
512
|
+
xcb judge enable
|
|
513
|
+
xcb judge test
|
|
514
|
+
# Later:
|
|
515
|
+
xcb judge disable
|
|
516
|
+
xcb judge logout
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
The input file is an existing private credential file, not a command-line key.
|
|
520
|
+
Keys are vaulted mode-0600 outside the workspace. `XCB_JEV_API_KEY` or
|
|
521
|
+
`TYPESAFE_API_KEY` may supply a key via the environment. Custom endpoints require
|
|
522
|
+
an explicit environment key; the vaulted key remains bound to System One.
|
|
523
|
+
|
|
524
|
+
## Migrating from AgentMixer
|
|
525
|
+
|
|
526
|
+
The native command imports **one Claude credential**, preserving the source:
|
|
527
|
+
|
|
528
|
+
```sh
|
|
529
|
+
xcb accounts import-agentmixer --source /absolute/path/to/.agentmixer
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
The account name comes from the observed provider identity. It does not
|
|
533
|
+
migrate transcripts or sessions. The `xcb-compat` compatibility CLI has its
|
|
534
|
+
own `migrate` command and identifier changes; see the
|
|
535
|
+
[compatibility migration reference](docs/compatibility.md#migrating-from-agentmixer).
|
|
536
|
+
Do not run compatibility migration commands against the native state root.
|
|
537
|
+
|
|
538
|
+
## Standalone package
|
|
539
|
+
|
|
540
|
+
The retained TypeScript source provides host-owned routing, account custody,
|
|
541
|
+
bounded tools, and provider adapters. It is separate from the native Rust app.
|
|
542
|
+
For building it locally, library examples, qualification requirements, and its
|
|
543
|
+
CLI commands, see the [compatibility reference](docs/compatibility.md) and
|
|
544
|
+
[managed Codex contract](MANAGED-CODEX.md). The
|
|
545
|
+
[publishing contract](docs/publishing.md) describes future verified artifacts;
|
|
546
|
+
it is not evidence of a published package.
|
|
547
|
+
|
|
548
|
+
## Development
|
|
549
|
+
|
|
550
|
+
See [Contributing](CONTRIBUTING.md) for setup and the native, compatibility, and
|
|
551
|
+
site checks. The credential-free [native Codex boundary fixtures](qualification/codex-native.md)
|
|
552
|
+
and [native Devin boundary fixture](qualification/devin-native.md) document
|
|
553
|
+
repeatable checks separately from authenticated live acceptance.
|
|
554
|
+
Release notes live in [CHANGELOG.md](CHANGELOG.md).
|
|
555
|
+
Report vulnerabilities through [Security](SECURITY.md). Licensed under [MIT](LICENSE).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SqliteDatabase } from "./sqlite-port.ts";
|
|
2
|
+
import { type AgentProvider } from "./validation.ts";
|
|
3
|
+
export type AccountLease = Readonly<{
|
|
4
|
+
provider: AgentProvider;
|
|
5
|
+
accountId: string;
|
|
6
|
+
owner: string;
|
|
7
|
+
generation: number;
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
}>;
|
|
10
|
+
export interface AccountLeaseStore {
|
|
11
|
+
acquire(input: {
|
|
12
|
+
provider: AgentProvider;
|
|
13
|
+
accountId: string;
|
|
14
|
+
owner: string;
|
|
15
|
+
now: number;
|
|
16
|
+
ttlMs: number;
|
|
17
|
+
}): AccountLease;
|
|
18
|
+
renew(lease: AccountLease, now: number, ttlMs: number): AccountLease;
|
|
19
|
+
release(lease: AccountLease): boolean;
|
|
20
|
+
/** Optional read of a currently held lease, for host recovery flows. */
|
|
21
|
+
inspect?(provider: AgentProvider, accountId: string): AccountLease | null;
|
|
22
|
+
/** Optional host recovery; proveStopped must supply independent
|
|
23
|
+
* process-exit evidence — a TTL or heartbeat is never sufficient. */
|
|
24
|
+
recover?(lease: AccountLease, proveStopped: (lease: AccountLease) => Promise<boolean>): Promise<boolean>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Shared host database, outside every agent workspace. A heartbeat deadline is
|
|
28
|
+
* diagnostic, never permission to steal custody from a possibly live process.
|
|
29
|
+
*/
|
|
30
|
+
export declare class SqliteAccountLeases implements AccountLeaseStore {
|
|
31
|
+
private readonly db;
|
|
32
|
+
constructor(db: SqliteDatabase);
|
|
33
|
+
acquire(input: {
|
|
34
|
+
provider: AgentProvider;
|
|
35
|
+
accountId: string;
|
|
36
|
+
owner: string;
|
|
37
|
+
now: number;
|
|
38
|
+
ttlMs: number;
|
|
39
|
+
}): AccountLease;
|
|
40
|
+
renew(lease: AccountLease, now: number, ttlMs: number): AccountLease;
|
|
41
|
+
/** Call only after the adapter proves its provider process/controller stopped. */
|
|
42
|
+
release(lease: AccountLease): boolean;
|
|
43
|
+
inspect(providerValue: AgentProvider, accountId: string): AccountLease | null;
|
|
44
|
+
/** Host recovery supplies independent process custody evidence; no automatic TTL recovery. */
|
|
45
|
+
recover(lease: AccountLease, proveStopped: (lease: AccountLease) => Promise<boolean>): Promise<boolean>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type BrokerToolName } from "./broker.ts";
|
|
2
|
+
import type { CapabilityDescriptor } from "./capabilities.ts";
|
|
3
|
+
/** Descriptions shared by native tool inventories and application profiles.
|
|
4
|
+
* createToolBroker remains the semantic parser and effect authority. */
|
|
5
|
+
export declare function brokerDescriptors(names: readonly BrokerToolName[]): readonly CapabilityDescriptor[];
|
package/dist/broker.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface WorkspaceFiles {
|
|
2
|
+
/** Host must confine resolution by directory handle, reject links, and bound IO. */
|
|
3
|
+
read(workspaceId: string, path: string, signal: AbortSignal): Promise<{
|
|
4
|
+
text: string;
|
|
5
|
+
revision: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Conditional writes prevent an agent from overwriting a concurrent human edit. */
|
|
8
|
+
write(workspaceId: string, path: string, text: string, expectedRevision: string | null, signal: AbortSignal): Promise<{
|
|
9
|
+
revision: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export interface PublicWeb {
|
|
13
|
+
/** Host validates DNS addresses and every redirect; refuses private IPs, credentials and local services. */
|
|
14
|
+
fetchPublic(url: string, maxBytes: number, signal: AbortSignal): Promise<{
|
|
15
|
+
text: string;
|
|
16
|
+
url: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export interface ScopedMessaging {
|
|
20
|
+
/** Stages an intent only. The host owns later disclosure, enrollment, journaling and dispatch. */
|
|
21
|
+
stage(workspaceId: string, runId: string, operation: MessageOperation, signal: AbortSignal): Promise<{
|
|
22
|
+
intentId: string;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export type MessageOperation = Readonly<{
|
|
26
|
+
kind: "text";
|
|
27
|
+
text: string;
|
|
28
|
+
idempotencyKey: string;
|
|
29
|
+
}> | Readonly<{
|
|
30
|
+
kind: "reaction";
|
|
31
|
+
messageId: string;
|
|
32
|
+
reaction: "love" | "like" | "dislike" | "laugh" | "emphasize" | "question";
|
|
33
|
+
idempotencyKey: string;
|
|
34
|
+
}> | Readonly<{
|
|
35
|
+
kind: "attachment";
|
|
36
|
+
path: string;
|
|
37
|
+
caption: string;
|
|
38
|
+
idempotencyKey: string;
|
|
39
|
+
}>;
|
|
40
|
+
export declare const BROKER_TOOL_NAMES: readonly ["files.read", "files.write", "web.fetch", "messages.propose_text", "messages.propose_reaction", "messages.propose_attachment"];
|
|
41
|
+
export type BrokerToolName = typeof BROKER_TOOL_NAMES[number];
|
|
42
|
+
export interface ToolBroker {
|
|
43
|
+
readonly workspaceId: string;
|
|
44
|
+
readonly runId: string;
|
|
45
|
+
readonly tools: readonly BrokerToolName[];
|
|
46
|
+
invoke(name: unknown, input: unknown): Promise<unknown>;
|
|
47
|
+
revoke(): void;
|
|
48
|
+
}
|
|
49
|
+
/** One capability-bound broker per run. Input never selects another workspace or recipient. */
|
|
50
|
+
export declare function createToolBroker(options: {
|
|
51
|
+
workspaceId: string;
|
|
52
|
+
runId: string;
|
|
53
|
+
files: WorkspaceFiles;
|
|
54
|
+
web: PublicWeb;
|
|
55
|
+
messaging: ScopedMessaging;
|
|
56
|
+
isActive: () => boolean;
|
|
57
|
+
signal?: AbortSignal;
|
|
58
|
+
allowedTools?: readonly BrokerToolName[];
|
|
59
|
+
}): ToolBroker;
|
|
60
|
+
export declare function relativeFile(value: unknown): string;
|
|
61
|
+
/** First-pass URL syntax guard; the host transport must also enforce DNS and redirects. */
|
|
62
|
+
export declare function publicHttpsUrl(value: unknown): string;
|