@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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/MANAGED-CODEX.md +213 -0
  3. package/README.md +555 -0
  4. package/dist/accounts.d.ts +46 -0
  5. package/dist/broker-descriptors.d.ts +5 -0
  6. package/dist/broker.d.ts +62 -0
  7. package/dist/browser-session.d.ts +161 -0
  8. package/dist/canonical-json.d.ts +2 -0
  9. package/dist/capabilities.d.ts +72 -0
  10. package/dist/claude-api-models.d.ts +24 -0
  11. package/dist/claude-api-transport.d.ts +5 -0
  12. package/dist/claude-api.d.ts +23 -0
  13. package/dist/claude-credentials.d.ts +13 -0
  14. package/dist/claude-options.d.ts +10 -0
  15. package/dist/claude-sdk.d.ts +48 -0
  16. package/dist/claude-task-adapter.d.ts +65 -0
  17. package/dist/cli.js +4190 -0
  18. package/dist/codex-account-process.d.ts +149 -0
  19. package/dist/codex-account-transport.d.ts +39 -0
  20. package/dist/codex-account.d.ts +126 -0
  21. package/dist/codex-config.d.ts +53 -0
  22. package/dist/codex-host.d.ts +40 -0
  23. package/dist/codex-managed-baseline.d.ts +5 -0
  24. package/dist/codex-managed-catalog.d.ts +32 -0
  25. package/dist/codex-managed-config.d.ts +93 -0
  26. package/dist/codex-managed-ledger.d.ts +37 -0
  27. package/dist/codex-managed-session.d.ts +62 -0
  28. package/dist/codex-managed-task-adapter.d.ts +21 -0
  29. package/dist/codex-process.d.ts +67 -0
  30. package/dist/codex-protocol-manifest.d.ts +27 -0
  31. package/dist/codex-relay.d.ts +80 -0
  32. package/dist/codex-scratch.d.ts +36 -0
  33. package/dist/codex-session.d.ts +44 -0
  34. package/dist/codex-task-adapter.d.ts +24 -0
  35. package/dist/codex-task-process.d.ts +21 -0
  36. package/dist/devin-acp.d.ts +105 -0
  37. package/dist/devin-adapter.d.ts +44 -0
  38. package/dist/devin-client.d.ts +36 -0
  39. package/dist/devin-mcp.d.ts +28 -0
  40. package/dist/egress-bridge.d.ts +35 -0
  41. package/dist/egress-client.d.ts +66 -0
  42. package/dist/index-kg2gx694.js +7217 -0
  43. package/dist/index.d.ts +58 -0
  44. package/dist/index.js +3455 -0
  45. package/dist/judge.d.ts +121 -0
  46. package/dist/loopback-server.d.ts +17 -0
  47. package/dist/managed-account.d.ts +176 -0
  48. package/dist/models.d.ts +23 -0
  49. package/dist/os-sandbox.d.ts +168 -0
  50. package/dist/private-file.d.ts +215 -0
  51. package/dist/process-port.d.ts +44 -0
  52. package/dist/process-write.d.ts +13 -0
  53. package/dist/provider-process.d.ts +26 -0
  54. package/dist/public-web.d.ts +21 -0
  55. package/dist/router.d.ts +43 -0
  56. package/dist/runtime.d.ts +90 -0
  57. package/dist/sqlite-port.d.ts +29 -0
  58. package/dist/task-runtime.d.ts +150 -0
  59. package/dist/validation.d.ts +6 -0
  60. package/package.json +70 -0
  61. package/sandbox/loopback-forwarder.cjs +172 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hraness contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,213 @@
1
+ # Managed Codex accounts
2
+
3
+ This document describes the retained TypeScript host-integration API. Native
4
+ Rust xcb uses a separate supervised device sign-in and explicit `auth.json`
5
+ import; follow the [native Codex setup](README.md#connect-codex-on-macos).
6
+ The compatibility CLI's Codex task route remains unqualified and disabled.
7
+
8
+ The managed account controller connects owner account controls to Codex's
9
+ ChatGPT sign-in flow. It keeps account authentication separate from permission
10
+ to run an agent. A signed-in account never qualifies an execution adapter.
11
+
12
+ The implementation follows the supported
13
+ [Codex app-server account protocol](https://learn.chatgpt.com/docs/app-server#authentication).
14
+ Codex owns credential persistence and refresh in a private host account home.
15
+ The controller accepts browser and device-code sign-in; it has no API-key,
16
+ external-token, credential-export, thread, turn or arbitrary RPC operation.
17
+
18
+ ## Connect a trusted process
19
+
20
+ Create a controller with `createManagedCodexAccountController()` and supply an
21
+ account ID, owner ID, process generation, shared `AccountLeaseStore` and
22
+ `transportFactory`. The factory receives an immutable account/lease/process
23
+ binding plus a notification callback. It must return a custody handle before
24
+ starting asynchronous work so that a failed launch can still be joined.
25
+
26
+ `createCodexAccountStdioTransport()` implements initialization, framed requests,
27
+ account notifications and shutdown over `CodexAccountProcessPort`. The host
28
+ supplies this process port; importing Xcb does not discover or launch
29
+ an installed Codex binary. The protocol exposes only `account/read`, managed
30
+ `account/login/start`, `account/login/cancel`, `account/logout` and `model/list`.
31
+ Unexpected server requests are refused; the transport cannot start a model turn.
32
+ The startup remote-control notification is accepted only when its status is
33
+ `disabled`. Remote identity fields are validated and discarded; another status
34
+ stops the account transport.
35
+
36
+ The host still owns runtime admission, the native launcher, private account
37
+ storage, configuration isolation, process journaling and crash recovery. Keep
38
+ account state outside every contact folder and do not inherit the owner's
39
+ normal CLI configuration or executable plugins. An injected port is trusted
40
+ code, not an owner-JSON setting or an agent tool.
41
+
42
+ ## Offline native process helper
43
+
44
+ `createCodexAccountProcess()` in `src/codex-account-process.ts` supplies a
45
+ process port for offline account-protocol checks on the admitted parent
46
+ platform (`darwin` or `linux`; the launcher selects seatbelt or the admitted
47
+ bwrap artifact accordingly). The caller provides an admitted
48
+ executable, its expected hash and version, a schema digest, a parent-runtime hash,
49
+ and an owner-private state directory. The helper verifies executable and parent
50
+ runtime hashes and records the caller-admitted version and schema digest. These
51
+ inputs do not establish provenance or execution qualification.
52
+
53
+ The helper copies the checked executable into an immutable run snapshot and uses
54
+ fixed app-server arguments, configuration and environment. Network access, process
55
+ forks and remote control are disabled. This mode cannot complete OAuth sign-in.
56
+ An exclusive account lock precedes account-home writes. The persistent account
57
+ home stays outside the run's temporary HOME and working directory and survives
58
+ shutdown; the helper does not inspect or export credentials.
59
+
60
+ The version-one `config.toml` baseline is shared by account helpers and managed
61
+ tasks. Its SHA-256 is
62
+ `9833be747176d26b0915621439e2cbea1bff12aeca6f7854e45265777bb98ae8`.
63
+ `codexManagedAccountConfiguration()` is the pure source of those bytes;
64
+ `codexAccountOfflineConfiguration()` remains a compatibility alias. No migration
65
+ or per-task file rewrite is required. An existing file with different bytes is
66
+ refused and preserved for explicit recovery.
67
+
68
+ A private journal records launch intent before spawning and retains process and
69
+ stream cleanup evidence. Failed cleanup keeps the account lock and recovery state.
70
+ An expired lease or stale lock does not authorize a replacement process. The
71
+ helper is not registered with Textbutler's default host and does not enable replies.
72
+ Filesystem cleanup can finish after the requested wait deadline. The transport
73
+ retains and joins that work before releasing account custody.
74
+
75
+ ## Device-code process candidate
76
+
77
+ The helper also accepts explicit `mode: "device-code"` with a trusted
78
+ `deviceCodeAdmission` bound to the native executable, schema and parent-runtime
79
+ hashes. Its `codex-account-device-code-tcp443-dns-v1` profile adds the system
80
+ resolver socket and outbound TCP port 443 to the offline profile. It adds no
81
+ listener, browser helper, process forks, Keychain access or filesystem roots.
82
+ This is general TCP 443 access; it does not enforce TLS or a hostname allowlist.
83
+ The native client remains responsible for TLS authentication.
84
+
85
+ The separately selected `codex-account-device-code-tcp443-dns-v2` candidate
86
+ preserves every v1 byte and appends only
87
+ `(allow file-read-metadata (literal "/var"))`. This permits metadata access to
88
+ the system resolver's `/var` symlink; it adds no file-content access, socket
89
+ destination, Mach service or executable. V1 admission never upgrades to v2.
90
+ Receipts retain the v1 schema and existing v1 network label; v2 records
91
+ `tcp443-system-resolver-var-metadata-candidate` with its exact profile digest.
92
+ The fixed persistent configuration and offline task profile remain unchanged.
93
+
94
+ A bounded libc DNS-only diagnostic with this exact delta resolved the fixed
95
+ authentication hostname on the tested Mac and proved process cleanup. That
96
+ result may use the resolver cache. It establishes neither native Codex TLS
97
+ compatibility nor device-code sign-in, authentication or model execution.
98
+ Both profile variants remain candidates with `productionQualified: false`.
99
+
100
+ On Linux the same device-code mode plans through the bwrap backend instead:
101
+ the runtime admission carries the pinned `bwrap` artifact and read-only
102
+ library closure, and a `sandbox.egress` admission is additionally required.
103
+ The host seam `startEgressBridge` then starts a unix-socket CONNECT bridge in
104
+ the private run directory; the socket is bind-mounted into the namespace and
105
+ reaches the child as `XCB_EGRESS_SOCKET`. The child's own network
106
+ namespace never has a route — DNS resolution and TCP dialing happen on the
107
+ host side of the bridge, bounded to port 443 and an optional exact-host
108
+ allowlist. Cleanup joins the bridge (listener closed, sockets joined, socket
109
+ removed) before the account lock may release; a failed start or unproven join
110
+ holds custody like any other launch-boundary failure. How a provider runtime
111
+ consumes the socket is its own integration contract — the environment
112
+ variable is admission plumbing, not a native Codex consumption guarantee.
113
+ Two consumption paths now exist: a cooperative runtime links the public
114
+ `egress-client.ts` surface, and a stock binary rides the spec's
115
+ `egressForward` entry — the shipped `sandbox/loopback-forwarder.cjs` becomes
116
+ the namespace entry point under an admitted JS runtime, serves `CONNECT` on
117
+ a fixed loopback port, and launches the child with standard `HTTPS_PROXY`
118
+ variables. `qualification/linux-egress.ts` is the kernel-boundary evidence
119
+ fixture for the bridge path, and `qualification/linux-loopback.ts` exercises
120
+ the shipped forwarder end-to-end with stock `curl`; the `Qualification`
121
+ workflow runs both on `ubuntu-24.04`. Note that Ubuntu's default AppArmor
122
+ user-namespace restriction denies bwrap outright — the host must lift it
123
+ (`kernel.apparmor_restrict_unprivileged_userns=0`) before any plan can run.
124
+
125
+ `createManagedCodexAccountFactory()` in Textbutler's `managed-codex.ts` composes
126
+ the controller, stdio transport and process helper. Its admission inputs come
127
+ from trusted host code, never owner JSON or contact files, and preserve the
128
+ explicitly selected v1 or v2 profile. It accepts device-code
129
+ sign-in only and creates a fresh process generation for each controller.
130
+ Account storage remains under the private host state directory. Importing or
131
+ constructing the factory does not launch Codex or inspect existing credentials.
132
+
133
+ Profile admission and successful sign-in do not qualify model execution. The
134
+ candidate remains absent from the bundled default host until distribution and
135
+ native account-flow evidence are admitted separately.
136
+
137
+ ## Drive owner controls
138
+
139
+ - `snapshot()` returns account state, generations and discovered model metadata.
140
+ It omits email, credentials, sign-in URLs and device codes.
141
+ - `check()` reads account status without requesting token refresh. Only a
142
+ ChatGPT account requiring OpenAI authentication can become `signed-in`.
143
+ Model discovery uses bounded pagination and preserves observed effort and
144
+ service-tier choices. It establishes neither prices nor execution readiness.
145
+ - `startLogin("chatgpt")` returns a browser challenge;
146
+ `startLogin("chatgptDeviceCode")` returns an address and one-time code.
147
+ Show this result only to the owner and keep it in temporary view memory.
148
+ - `cancelLogin(loginId)` is bound to the exact pending attempt. `logout()`
149
+ signs out the selected account; it cannot select another billing route.
150
+ - `close()` stops and joins the transport. Inspect its `released` result.
151
+
152
+ Notifications invalidate cached account/model state synchronously. A late result
153
+ from an earlier account or process generation cannot restore readiness.
154
+ Concurrent operations return busy; aborted work remains under custody until
155
+ it settles. A notification racing with an account mutation can invalidate its
156
+ reply; use a fresh `check()` to reconcile the resulting state.
157
+
158
+ An interrupted or failed dispatched login can leave native polling active even
159
+ when its challenge was never returned. The controller marks that outcome as
160
+ `recovery-required`, ignores later account events and blocks another attempt.
161
+ The host closes and joins that exact controller before making a fresh one
162
+ available. It preserves the original error and never replays the login request.
163
+ Incomplete cleanup retains the old controller and account lease for recovery.
164
+
165
+ The exclusive account lease survives uncertain factory, process and cleanup
166
+ failures. It is released only after the exact bound process, process group,
167
+ streams, writes, requests and notifications are joined. Lease expiry alone
168
+ does not authorize reuse. An account-control process must finish that handoff
169
+ before a separately admitted task process can reuse the account.
170
+
171
+ ## Textbutler integration and current limits
172
+
173
+ Textbutler's `createProviderHost()` and `startDaemon()` accept an optional trusted
174
+ `managedCodex` factory. The factory is called only for an explicit owner account
175
+ operation. When supplied, the local control protocol and Mac account panel expose
176
+ sign-in, cancellation, sign-out and checks. The panel shows authentication state
177
+ and reply availability separately. Challenges are not stored in contact files,
178
+ settings or activity. The bundled default host currently supplies no managed
179
+ native process factory, so these controls are absent from its account rows.
180
+
181
+ Synthetic tests cover the controller, stdio protocol and owner controls. They
182
+ do not establish successful live sign-in or contact-scoped native execution.
183
+ The credential-free Codex task process uses a loopback model relay. The separate
184
+ `createCodexManagedTaskAdapter()` supports managed subscription tasks through
185
+ the built-in provider, but still requires a host launcher and current execution
186
+ qualification. Neither task adapter is enabled by account sign-in. The account
187
+ protocol supplies no inference proxy or token-export bridge between them.
188
+
189
+ Managed task settings are applied in memory to a fresh ephemeral thread. The
190
+ selected model, service tier, base instructions and developer instructions use
191
+ dedicated `thread/start` fields. The pinned protocol has no dedicated thread
192
+ effort field, so `codexManagedThreadConfiguration()` supplies a non-null effort
193
+ as `config.model_reasoning_effort`. This closed host-generated overlay also
194
+ disables the union of account and task feature flags, including remote control,
195
+ and disables the plan and user-input tools. It accepts no arbitrary configuration
196
+ from callers. Explicit effort and tier selections are repeated in `turn/start`;
197
+ null selections leave native defaults intact and the receipt records what the
198
+ thread actually reported.
199
+
200
+ The earlier `config/read` check covers only the public baseline projection. It
201
+ can report defaults that differ from the task, and cannot attest to a thread
202
+ overlay that has not yet been applied. Exact model and non-null effort/tier
203
+ selections are checked against `ThreadStartResponse` before any task turn.
204
+ Configuration and thread readback do not establish the effective tool inventory,
205
+ authenticated execution or OS confinement. This correction keeps the managed
206
+ task route unqualified and requires no native or provider calls.
207
+
208
+ Before a trusted host admits a native process, it must bind the executable and
209
+ generated experimental schema to a `CodexProtocolManifest` using
210
+ `assertCodexProtocolManifest()`. The manifest carries the protocol and source
211
+ versions plus executable, schema and manifest digests. A caller-supplied hash
212
+ alone is not admission evidence; mismatched runtime identity fails before
213
+ initialization.