@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
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { type BigIntStats, type Stats } from "node:fs";
|
|
2
|
+
import { type FileHandle } from "node:fs/promises";
|
|
3
|
+
/** Canonical path ceiling shared by the private-state modules. */
|
|
4
|
+
export declare const PRIVATE_PATH_MAX_LENGTH = 4096;
|
|
5
|
+
/** Path byte rejection for custody paths: C0 controls, DEL, `"` and `\`. */
|
|
6
|
+
export declare const PRIVATE_PATH_REJECT: RegExp;
|
|
7
|
+
/** Control-byte-only rejection (C0 + DEL) for paths that permit `"` and `\`. */
|
|
8
|
+
export declare const PRIVATE_CONTROL_REJECT: RegExp;
|
|
9
|
+
/** C0-only rejection for sites that historically allowed DEL as well. */
|
|
10
|
+
export declare const PRIVATE_C0_REJECT: RegExp;
|
|
11
|
+
/** Canonical path grammar: absolute, lexically resolved, length-capped and
|
|
12
|
+
* control-clean. `resolved: false` keeps only the absolute check for sites
|
|
13
|
+
* that canonicalize through `realpath` instead of the lexical form; `reject:
|
|
14
|
+
* null` drops the character check; `maxLength: Infinity` drops the cap;
|
|
15
|
+
* `measureBytes` counts UTF-8 bytes instead of UTF-16 units (codex-host). */
|
|
16
|
+
export declare function canonicalizePrivatePath(value: unknown, rule: Readonly<{
|
|
17
|
+
code: string;
|
|
18
|
+
resolved?: boolean;
|
|
19
|
+
reject?: RegExp | null;
|
|
20
|
+
maxLength?: number;
|
|
21
|
+
measureBytes?: boolean;
|
|
22
|
+
}>): string;
|
|
23
|
+
/** The absolute-path half of a split-code site: grammar failures and physical
|
|
24
|
+
* custody failures report different codes, so they stay two calls. */
|
|
25
|
+
export declare function assertAbsolutePrivatePath(value: unknown, code: string): asserts value is string;
|
|
26
|
+
/** Ownership expectation for a private file or directory. `"self"` requires
|
|
27
|
+
* the current uid and fails the site code when `getuid` is unavailable;
|
|
28
|
+
* `"selfOrThrow"` calls `getuid!()` so an absent uid check throws exactly as
|
|
29
|
+
* the replaced site did; the `OrRoot` variants additionally admit uid 0 (a
|
|
30
|
+
* root-owned system artifact is at least as tamper-evident as a user file);
|
|
31
|
+
* a number, bigint, or list is an exact uid set resolved by the caller. */
|
|
32
|
+
export type PrivateOwner = "self" | "selfOrThrow" | "selfOrRoot" | "selfOrRootOrThrow" | number | bigint | readonly (number | bigint)[];
|
|
33
|
+
/** One mode-predicate rule: `(mode & mask)` must equal `equals` and/or differ
|
|
34
|
+
* from `notEquals`. Examples: exact-0600 is `{ mask: 0o7777, equals: 0o600 }`;
|
|
35
|
+
* "some execute bit" is `{ mask: 0o111, notEquals: 0 }`. */
|
|
36
|
+
export type PrivateModeRule = Readonly<{
|
|
37
|
+
mask: number | bigint;
|
|
38
|
+
equals?: number | bigint;
|
|
39
|
+
notEquals?: number | bigint;
|
|
40
|
+
}>;
|
|
41
|
+
/** The shape a private file or directory must have. `links: "single"` is the
|
|
42
|
+
* nlink===1 no-hardlink rule; `noSymlink` rejects an lstat symlink result (an
|
|
43
|
+
* O_NOFOLLOW open can never produce one, so it applies to lstat snapshots);
|
|
44
|
+
* `size.min` is an inclusive floor (`min: 1` is the nonempty check). */
|
|
45
|
+
export type PrivateStatShape = Readonly<{
|
|
46
|
+
kind?: "file" | "directory";
|
|
47
|
+
owner?: PrivateOwner;
|
|
48
|
+
links?: "single";
|
|
49
|
+
mode?: readonly PrivateModeRule[];
|
|
50
|
+
size?: Readonly<{
|
|
51
|
+
min?: number | bigint;
|
|
52
|
+
max?: number | bigint;
|
|
53
|
+
equals?: number | bigint;
|
|
54
|
+
}>;
|
|
55
|
+
noSymlink?: boolean;
|
|
56
|
+
}>;
|
|
57
|
+
/** Boolean form of the private-stat predicate, for sites whose contract is a
|
|
58
|
+
* yes/no answer (mode repair, best-effort probes) rather than a thrown code. */
|
|
59
|
+
export declare function matchesPrivateStat(metadata: Stats | BigIntStats, shape: PrivateStatShape): boolean;
|
|
60
|
+
/** Throwing form of the shape predicate; `code` is the site's own error. */
|
|
61
|
+
export declare function assertPrivateStat(metadata: Stats | BigIntStats, shape: PrivateStatShape, code: string): void;
|
|
62
|
+
/** Comparable stat fields. `mtime`/`ctime` map to `mtimeNs`/`ctimeNs` on
|
|
63
|
+
* BigIntStats and `mtimeMs`/`ctimeMs` on Stats, preserving each site's
|
|
64
|
+
* original precision. The default set is the nine-field identity every
|
|
65
|
+
* custody module compared; sites with a narrower drift set pass a subset. */
|
|
66
|
+
export type PrivateIdentityField = "dev" | "ino" | "uid" | "gid" | "mode" | "nlink" | "size" | "mtime" | "ctime";
|
|
67
|
+
export declare const PRIVATE_IDENTITY_FIELDS: readonly PrivateIdentityField[];
|
|
68
|
+
/** Exact field equality between two stat snapshots of the same type. Mixed
|
|
69
|
+
* Stats/BigIntStats pairs compare only the type-shared fields; a mismatched
|
|
70
|
+
* timestamp precision reports unequal (fails closed as drift). */
|
|
71
|
+
export declare function sameFileIdentity(a: Stats | BigIntStats, b: Stats | BigIntStats, fields?: readonly PrivateIdentityField[]): boolean;
|
|
72
|
+
/** The held-fd before/after revalidation: every `observed` snapshot must keep
|
|
73
|
+
* `before`'s identity fields. `requirePlainFile` additionally demands each
|
|
74
|
+
* observed value stay a plain non-symlink file (the codex-host rule). All
|
|
75
|
+
* snapshots come from callers that hold the descriptor open — this predicate
|
|
76
|
+
* never opens, closes, or reopens anything. */
|
|
77
|
+
export declare function assertFileStable(before: Stats | BigIntStats, observed: readonly (Stats | BigIntStats)[], rule: Readonly<{
|
|
78
|
+
code: string;
|
|
79
|
+
fields?: readonly PrivateIdentityField[];
|
|
80
|
+
requirePlainFile?: boolean;
|
|
81
|
+
}>): void;
|
|
82
|
+
/** Assert an existing directory is canonical, physical, owner-only and
|
|
83
|
+
* private. `canonical: "self"` (default) requires `realpath(path) === path`;
|
|
84
|
+
* `"resolved"` accepts a noncanonical input whose physical form equals
|
|
85
|
+
* `resolve(path)` (codex-process). `mode: "exact"` is `(mode & 0o7777) ===
|
|
86
|
+
* 0o700` including suid/sgid/sticky rejection; `"perms"` masks only 0o777;
|
|
87
|
+
* `"ownerOnly"` accepts any mode with no group/other bits. `statOrder` keeps
|
|
88
|
+
* the site's lstat-vs-realpath call order so a missing path reports from the
|
|
89
|
+
* same syscall it used to. `metadataFirst` preserves the one short-circuiting
|
|
90
|
+
* site that rejected unsafe metadata before calling realpath. `stats: "number"`
|
|
91
|
+
* preserves the ordinary-Stats precision of its caller; bigint is the default.
|
|
92
|
+
* Returns the metadata and realpath. */
|
|
93
|
+
type PrivateDirectoryRule = Readonly<{
|
|
94
|
+
code: string;
|
|
95
|
+
owner?: PrivateOwner;
|
|
96
|
+
mode?: "exact" | "perms" | "ownerOnly";
|
|
97
|
+
canonical?: "self" | "resolved";
|
|
98
|
+
statOrder?: "lstatFirst" | "realpathFirst";
|
|
99
|
+
metadataFirst?: boolean;
|
|
100
|
+
stats?: "number";
|
|
101
|
+
}>;
|
|
102
|
+
export declare function assertPrivateDirectory(path: string, rule: PrivateDirectoryRule & {
|
|
103
|
+
stats: "number";
|
|
104
|
+
}): Promise<Readonly<{
|
|
105
|
+
metadata: Stats;
|
|
106
|
+
physical: string;
|
|
107
|
+
}>>;
|
|
108
|
+
export declare function assertPrivateDirectory(path: string, rule: PrivateDirectoryRule): Promise<Readonly<{
|
|
109
|
+
metadata: BigIntStats;
|
|
110
|
+
physical: string;
|
|
111
|
+
}>>;
|
|
112
|
+
/** Open a directory read-only+no-follow and fsync it — the durability proof
|
|
113
|
+
* for a create/unlink/rename inside it. */
|
|
114
|
+
export declare function fsyncDirectory(path: string): Promise<void>;
|
|
115
|
+
/** Create `path` mode 0700 if missing, fsync the parent on creation, then
|
|
116
|
+
* apply `assertPrivateDirectory` — a preexisting directory is re-verified,
|
|
117
|
+
* never trusted. */
|
|
118
|
+
export declare function ensurePrivateDirectory(path: string, rule: Omit<PrivateDirectoryRule, "stats">): Promise<BigIntStats>;
|
|
119
|
+
type PrivateReadOptions = Readonly<{
|
|
120
|
+
directory?: boolean;
|
|
121
|
+
nonblock?: boolean;
|
|
122
|
+
missingOk?: boolean;
|
|
123
|
+
openErrorCode?: string;
|
|
124
|
+
}>;
|
|
125
|
+
/** Open `path` `O_RDONLY | O_NOFOLLOW` — the stable-read descriptor every
|
|
126
|
+
* held-fd check starts from. `nonblock` defaults on (every custody site);
|
|
127
|
+
* `directory` adds O_DIRECTORY; `missingOk` maps ENOENT to null; an
|
|
128
|
+
* `openErrorCode` collapses any open failure (including ELOOP) to the site's
|
|
129
|
+
* invalid-shape code. The caller owns and must close the handle. */
|
|
130
|
+
export declare function openPrivateRead(path: string, options: PrivateReadOptions & {
|
|
131
|
+
missingOk: true;
|
|
132
|
+
}): Promise<FileHandle | null>;
|
|
133
|
+
export declare function openPrivateRead(path: string, options?: PrivateReadOptions): Promise<FileHandle>;
|
|
134
|
+
type PrivateWriteOptions = Readonly<{
|
|
135
|
+
mode?: number;
|
|
136
|
+
exclusive?: boolean;
|
|
137
|
+
nofollow?: boolean;
|
|
138
|
+
append?: boolean;
|
|
139
|
+
truncate?: boolean;
|
|
140
|
+
create?: boolean;
|
|
141
|
+
}>;
|
|
142
|
+
/** Open `path` `O_WRONLY | O_CREAT` for a private write. `exclusive` (default)
|
|
143
|
+
* adds O_EXCL — atomic create-once; `nofollow` (default) adds O_NOFOLLOW;
|
|
144
|
+
* `append` adds O_APPEND (append-only journals); `truncate` adds O_TRUNC for
|
|
145
|
+
* the staged-temp rewrite pattern; `create: false` drops O_CREAT so reopening
|
|
146
|
+
* an already-durable journal still asserts the inode exists. The caller owns
|
|
147
|
+
* and must close the handle. */
|
|
148
|
+
export declare function openPrivateWrite(path: string, options?: PrivateWriteOptions): Promise<FileHandle>;
|
|
149
|
+
/** Synchronous `openPrivateWrite` for the journal descriptors held across a
|
|
150
|
+
* launch: custody must be provable inside synchronous state machines. */
|
|
151
|
+
export declare function openPrivateWriteSync(path: string, options?: PrivateWriteOptions): number;
|
|
152
|
+
/** Atomic create-once durable write: O_EXCL no-follow create at `mode`
|
|
153
|
+
* (default 0600), the contents, an optional file fsync, close, and an
|
|
154
|
+
* optional parent-directory fsync. `nofollow`/`truncate`/`append` forward to
|
|
155
|
+
* the same flag grammar as `openPrivateWrite` (Node's `"wx"` flag is
|
|
156
|
+
* `nofollow: false, truncate: true`). Callers whose ownership flag must flip
|
|
157
|
+
* between open and write use `openPrivateWrite` directly. */
|
|
158
|
+
export declare function writeFileOnce(path: string, contents: string | Uint8Array, options?: PrivateWriteOptions & Readonly<{
|
|
159
|
+
syncFile?: boolean;
|
|
160
|
+
syncParent?: boolean;
|
|
161
|
+
}>): Promise<void>;
|
|
162
|
+
/** Bounded position-zero read through a held descriptor. `growth` sizes the
|
|
163
|
+
* allocation one byte larger; `loop` retries short reads to EOF/capacity;
|
|
164
|
+
* `into` preserves a caller-owned buffer and its zeroization semantics. No
|
|
165
|
+
* exact-size verdict is made here because several sites collect post-read
|
|
166
|
+
* stats before that verdict. */
|
|
167
|
+
export declare function readFdBounded(fd: FileHandle, size: number | bigint, options?: Readonly<{
|
|
168
|
+
growth?: boolean;
|
|
169
|
+
loop?: boolean;
|
|
170
|
+
into?: Buffer;
|
|
171
|
+
}>): Promise<Readonly<{
|
|
172
|
+
buffer: Buffer;
|
|
173
|
+
bytesRead: number;
|
|
174
|
+
}>>;
|
|
175
|
+
/** `readFdBounded` plus an immediate exact-size and optional byte-equality
|
|
176
|
+
* verdict. Returns exactly `size` verified bytes. */
|
|
177
|
+
export declare function readFdExact(fd: FileHandle, size: number | bigint, options: Readonly<{
|
|
178
|
+
code: string;
|
|
179
|
+
contents?: Uint8Array;
|
|
180
|
+
growth?: boolean;
|
|
181
|
+
loop?: boolean;
|
|
182
|
+
into?: Buffer;
|
|
183
|
+
}>): Promise<Buffer>;
|
|
184
|
+
/** Stream at most `size`+1 bytes from position 0 through `onChunk`. Reads are
|
|
185
|
+
* bounded by `size`+1 so growth is always detectable; the return value is the
|
|
186
|
+
* consumed count and the caller compares it at its own verdict position —
|
|
187
|
+
* sites disagree on where that verdict lands relative to their post-read
|
|
188
|
+
* stats, so it is deliberately not asserted here. `earlyGrowth` fails `code`
|
|
189
|
+
* inside the loop (sites whose replaced loop asserted `read <= size`
|
|
190
|
+
* mid-loop); out-of-range reads always fail `code`. The descriptor stays
|
|
191
|
+
* open and owned by the caller. */
|
|
192
|
+
export declare function streamFdContent(fd: FileHandle, size: number | bigint, options: Readonly<{
|
|
193
|
+
code: string;
|
|
194
|
+
onChunk: (chunk: Buffer) => void | Promise<void>;
|
|
195
|
+
chunkBytes?: number;
|
|
196
|
+
earlyGrowth?: boolean;
|
|
197
|
+
}>): Promise<number>;
|
|
198
|
+
/** The exact-content private file: optionally durable-create when absent
|
|
199
|
+
* (EEXIST tolerated — a prior run may have left it), then open no-follow,
|
|
200
|
+
* require a 0600 single-link self-owned file of exactly `contents`' length,
|
|
201
|
+
* read and byte-compare it through the held descriptor, and revalidate the
|
|
202
|
+
* identity against a post-read fstat and fresh lstat. `statsEarly` collects
|
|
203
|
+
* those two snapshots before the content check (the browser/account order);
|
|
204
|
+
* `stableCode`/`stablePlainFile` model the codex-host stability predicate
|
|
205
|
+
* where identity drift reports a different code than content drift. */
|
|
206
|
+
export declare function readExactPrivateFile(path: string, contents: string, options: Readonly<{
|
|
207
|
+
invalidCode: string;
|
|
208
|
+
changedCode: string;
|
|
209
|
+
create?: boolean;
|
|
210
|
+
loop?: boolean;
|
|
211
|
+
statsEarly?: boolean;
|
|
212
|
+
stableCode?: string;
|
|
213
|
+
stablePlainFile?: boolean;
|
|
214
|
+
}>): Promise<void>;
|
|
215
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Trusted host process boundary. This is an in-memory adapter contract, not a
|
|
2
|
+
* wire protocol, launch API, runtime qualification or authority to signal PIDs.
|
|
3
|
+
* The host owns artifact admission, launch policy and durable account custody. */
|
|
4
|
+
export type ProviderProcessBinding = Readonly<{
|
|
5
|
+
version: 1;
|
|
6
|
+
nonce: string;
|
|
7
|
+
scope: "posix-process-group" | "windows-job";
|
|
8
|
+
}>;
|
|
9
|
+
export type ProviderProcessWriteResult = Readonly<{
|
|
10
|
+
outcome: "accepted-full" | "refused-before-write" | "partial-known" | "indeterminate";
|
|
11
|
+
acceptedBytes: number;
|
|
12
|
+
}>;
|
|
13
|
+
export type ProviderProcessSettlement = Readonly<{
|
|
14
|
+
kind: "joined" | "not-started";
|
|
15
|
+
binding: ProviderProcessBinding;
|
|
16
|
+
}>;
|
|
17
|
+
export interface ProviderProcessPort {
|
|
18
|
+
/** Resolves only after runtime readiness and the host's durable Ready commit. */
|
|
19
|
+
readonly ready: Promise<unknown>;
|
|
20
|
+
/** Root observation only. Neither root exit nor a rejected launch proves join. */
|
|
21
|
+
readonly rootExited: Promise<unknown>;
|
|
22
|
+
/** The trusted owner resolves this only after exact scope, native stream EOF,
|
|
23
|
+
* supervisor and control work join, or exact proof that launch never started.
|
|
24
|
+
* Operation or JavaScript delivery failure does not invalidate that proof. */
|
|
25
|
+
readonly joined: Promise<ProviderProcessSettlement>;
|
|
26
|
+
/** Operation result, separate from custody. Success includes consumer drain;
|
|
27
|
+
* rejection may precede physical join and must never be reinterpreted as it. */
|
|
28
|
+
readonly transportCompleted: Promise<void>;
|
|
29
|
+
readonly stdout: AsyncIterable<Uint8Array>;
|
|
30
|
+
readonly stderr: AsyncIterable<Uint8Array>;
|
|
31
|
+
/** Makes its admission decision synchronously when called, with no queue
|
|
32
|
+
* behind an outstanding provider write. It never retries uncertain bytes. */
|
|
33
|
+
write(bytes: Uint8Array): Promise<ProviderProcessWriteResult>;
|
|
34
|
+
closeInput(): Promise<void>;
|
|
35
|
+
/** Both calls revoke new writes synchronously and retain observation. Stop
|
|
36
|
+
* uses the exact owned handle, including a launch that is not ready yet. */
|
|
37
|
+
requestStop(): void;
|
|
38
|
+
forceStop(): void;
|
|
39
|
+
}
|
|
40
|
+
export declare function snapshotProviderProcessBinding(value: unknown): ProviderProcessBinding;
|
|
41
|
+
export declare function sameProviderProcessBinding(a: ProviderProcessBinding, b: ProviderProcessBinding): boolean;
|
|
42
|
+
/** Validate byte acceptance without treating a successful write as a successful
|
|
43
|
+
* RPC. Extra host receipt fields stay outside this product adapter. */
|
|
44
|
+
export declare function providerProcessWriteResult(value: unknown, byteLength: number): ProviderProcessWriteResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ProviderProcessWriteResult } from "./process-port.ts";
|
|
2
|
+
/** Product-owned serialization. A deadline revokes queued writes immediately;
|
|
3
|
+
* the original admitted write remains owned until its receipt settles. */
|
|
4
|
+
export declare function createProcessWriteQueue(options: Readonly<{
|
|
5
|
+
write(bytes: Uint8Array): Promise<ProviderProcessWriteResult>;
|
|
6
|
+
assertActive(): void;
|
|
7
|
+
failed(): void;
|
|
8
|
+
timeoutMs: number;
|
|
9
|
+
}>): Readonly<{
|
|
10
|
+
write(bytes: Uint8Array): Promise<void>;
|
|
11
|
+
stop(): void;
|
|
12
|
+
settled(): Promise<void>;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SpawnedProcess } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
export type BoundedProviderProcessInput = Readonly<{
|
|
3
|
+
executable: string;
|
|
4
|
+
args: readonly string[];
|
|
5
|
+
cwd: string;
|
|
6
|
+
env: Readonly<Record<string, string>>;
|
|
7
|
+
onViolation: () => void;
|
|
8
|
+
}>;
|
|
9
|
+
export type BoundedProviderProcess = Readonly<{
|
|
10
|
+
process: SpawnedProcess;
|
|
11
|
+
stopAndJoin(): Promise<void>;
|
|
12
|
+
isStopped(): boolean;
|
|
13
|
+
}>;
|
|
14
|
+
/** Trusted application factory. Return an owned handle synchronously, including
|
|
15
|
+
* failed readiness; never reject after a possible launch without retaining it.
|
|
16
|
+
* Exact shared-artifact admission, durable launch/Ready fences and native join
|
|
17
|
+
* belong to the application. This signature creates no runtime qualification. */
|
|
18
|
+
export type BoundedProviderProcessFactory = (input: BoundedProviderProcessInput & Readonly<{
|
|
19
|
+
binding: Readonly<{
|
|
20
|
+
runId: string;
|
|
21
|
+
accountId: string;
|
|
22
|
+
workspaceId: string;
|
|
23
|
+
}>;
|
|
24
|
+
}>) => BoundedProviderProcess;
|
|
25
|
+
/** Host-owned subprocess custody. Model-controlled tools cannot call this module. */
|
|
26
|
+
export declare function spawnBoundedProvider(input: BoundedProviderProcessInput): BoundedProviderProcess;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type PublicWeb } from "./broker.ts";
|
|
2
|
+
/** Conservative public-unicast policy. Mapped IPv4, transition and special-use ranges fail closed. */
|
|
3
|
+
export declare function isPublicAddress(address: string): boolean;
|
|
4
|
+
type Address = Readonly<{
|
|
5
|
+
address: string;
|
|
6
|
+
family: number;
|
|
7
|
+
}>;
|
|
8
|
+
type WebResponse = Readonly<{
|
|
9
|
+
status: number;
|
|
10
|
+
location?: string;
|
|
11
|
+
text?: string;
|
|
12
|
+
}>;
|
|
13
|
+
/** Trusted host IO seam, useful for deterministic DNS/redirect qualification. Never a model tool. */
|
|
14
|
+
export interface PublicWebIO {
|
|
15
|
+
resolve(hostname: string): Promise<readonly Address[]>;
|
|
16
|
+
get(url: URL, address: Address, maxBytes: number, signal: AbortSignal): Promise<WebResponse>;
|
|
17
|
+
}
|
|
18
|
+
export declare const nodePublicWebIO: PublicWebIO;
|
|
19
|
+
/** Bounded public HTTPS GETs. Every redirect repeats DNS admission and pins one approved address. */
|
|
20
|
+
export declare function createPublicWeb(io?: PublicWebIO): PublicWeb;
|
|
21
|
+
export {};
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AccountLeaseStore } from "./accounts.ts";
|
|
2
|
+
import type { CapabilityBroker } from "./capabilities.ts";
|
|
3
|
+
import { type AgentTaskAdapter, type AgentTaskRequest, type AgentTaskResult, type AgentTaskRoute } from "./task-runtime.ts";
|
|
4
|
+
import { type AgentProvider } from "./validation.ts";
|
|
5
|
+
/**
|
|
6
|
+
* The caller-facing request: `route` resolves by `provider` + `authentication`
|
|
7
|
+
* against the registered adapters when it is not given exactly, and `runId` /
|
|
8
|
+
* `workspaceId` default to the broker's own binding. Every other field keeps
|
|
9
|
+
* the task-runtime contract — the router validates nothing the runtime would
|
|
10
|
+
* not recheck.
|
|
11
|
+
*/
|
|
12
|
+
export type RouterTaskRequest = Omit<AgentTaskRequest, "route" | "runId" | "workspaceId" | "signal"> & Readonly<{
|
|
13
|
+
/** Exact route object; required when one provider registers several. */
|
|
14
|
+
route?: AgentTaskRoute;
|
|
15
|
+
/** Resolve the registered route for this provider. */
|
|
16
|
+
provider?: AgentProvider;
|
|
17
|
+
/** With `provider`, selects the route's authentication kind. */
|
|
18
|
+
authentication?: AgentTaskRoute["authentication"];
|
|
19
|
+
runId?: string;
|
|
20
|
+
workspaceId?: string;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
}>;
|
|
23
|
+
export type SubscriptionRouter = Readonly<{
|
|
24
|
+
/**
|
|
25
|
+
* The adapter-registered routes this router can dispatch to. Registration is
|
|
26
|
+
* not eligibility: account custody, credentials and qualification evidence
|
|
27
|
+
* are proven when a task runs, never by listing.
|
|
28
|
+
*/
|
|
29
|
+
routes(): readonly AgentTaskRoute[];
|
|
30
|
+
run(request: RouterTaskRequest, broker: CapabilityBroker): Promise<AgentTaskResult>;
|
|
31
|
+
}>;
|
|
32
|
+
export type SubscriptionRouterOptions = Readonly<{
|
|
33
|
+
/** Host-owned custody store, e.g. `new SqliteAccountLeases(db)`. */
|
|
34
|
+
leases: AccountLeaseStore;
|
|
35
|
+
adapters: readonly AgentTaskAdapter[];
|
|
36
|
+
now?: () => number;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* One construction call for the embeddable subscription router: an account
|
|
40
|
+
* lease store plus qualified task adapters. There is no bundled live adapter
|
|
41
|
+
* and no credential discovery — the host still supplies both.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createSubscriptionRouter(options: SubscriptionRouterOptions): SubscriptionRouter;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { AccountLeaseStore } from "./accounts.ts";
|
|
2
|
+
import type { ToolBroker } from "./broker.ts";
|
|
3
|
+
import type { CapabilityBroker } from "./capabilities.ts";
|
|
4
|
+
import { type AgentTaskAdapter, type AgentTaskRequest, type AgentTaskResult } from "./task-runtime.ts";
|
|
5
|
+
import { type AgentProvider } from "./validation.ts";
|
|
6
|
+
export declare const CONTACT_TOOL_PROFILE: "xcb.scoped-tools.v1";
|
|
7
|
+
export type RuntimeQualification = Readonly<{
|
|
8
|
+
status: "unqualified";
|
|
9
|
+
reason: string;
|
|
10
|
+
}> | Readonly<{
|
|
11
|
+
status: "qualified";
|
|
12
|
+
profile: typeof CONTACT_TOOL_PROFILE;
|
|
13
|
+
runtimeVersion: string;
|
|
14
|
+
runtimeDigest: string;
|
|
15
|
+
evidenceDigest: string;
|
|
16
|
+
expiresAt: number;
|
|
17
|
+
controls: Readonly<{
|
|
18
|
+
noCommandTools: true;
|
|
19
|
+
exactToolInventory: true;
|
|
20
|
+
contactReadIsolation: true;
|
|
21
|
+
contactWriteIsolation: true;
|
|
22
|
+
isolatedConfiguration: true;
|
|
23
|
+
authOutsideWorkspace: true;
|
|
24
|
+
hostBrokerOnly: true;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
export type AgentRunRequest = Readonly<{
|
|
28
|
+
runId: string;
|
|
29
|
+
provider: AgentProvider;
|
|
30
|
+
accountId: string;
|
|
31
|
+
workspaceId: string;
|
|
32
|
+
prompt: string;
|
|
33
|
+
model: string;
|
|
34
|
+
purpose: "classify" | "respond";
|
|
35
|
+
signal: AbortSignal;
|
|
36
|
+
}>;
|
|
37
|
+
export type AgentRunResult = Readonly<{
|
|
38
|
+
output: unknown;
|
|
39
|
+
/** Must prove provider process exit or fenced controller release, even after errors. */
|
|
40
|
+
processStopped: true;
|
|
41
|
+
}>;
|
|
42
|
+
/** An adapter may use this only after independently joining every process it started. */
|
|
43
|
+
export declare class AgentStoppedError extends Error {
|
|
44
|
+
readonly processStopped = true;
|
|
45
|
+
}
|
|
46
|
+
export interface AgentAdapter {
|
|
47
|
+
readonly provider: AgentProvider;
|
|
48
|
+
readonly qualification: RuntimeQualification;
|
|
49
|
+
run(request: AgentRunRequest, broker: ToolBroker): Promise<AgentRunResult>;
|
|
50
|
+
}
|
|
51
|
+
export declare const UNQUALIFIED_PROVIDER_REASONS: Readonly<{
|
|
52
|
+
codex: "Codex 0.153.4 has a restricted experimental driver; native confinement, adversarial custody and account transport qualification remain incomplete.";
|
|
53
|
+
claude: "Claude tool selection is documented; isolated configuration and contact-only read confinement require exact-runtime adversarial qualification.";
|
|
54
|
+
devin: "Devin ACP exposes session and usage facts; exact-runtime custody, tool-inventory and read/write confinement qualification remain incomplete.";
|
|
55
|
+
}>;
|
|
56
|
+
/** Installed adapters explicitly advertise blocked status until their host evidence exists. */
|
|
57
|
+
export declare function unqualifiedAdapter(selected: AgentProvider): AgentAdapter;
|
|
58
|
+
export type AccountBinding = Readonly<{
|
|
59
|
+
provider: AgentProvider;
|
|
60
|
+
accountId: string;
|
|
61
|
+
authBindingId: string;
|
|
62
|
+
}>;
|
|
63
|
+
/** The trusted adapter resolves this opaque handle; the broker/model never receives credentials. */
|
|
64
|
+
export interface AccountResolver {
|
|
65
|
+
resolve(provider: AgentProvider, accountId: string): Promise<AccountBinding>;
|
|
66
|
+
}
|
|
67
|
+
export declare class Xcb {
|
|
68
|
+
private readonly options;
|
|
69
|
+
private readonly taskAdapters;
|
|
70
|
+
constructor(options: {
|
|
71
|
+
adapters: readonly AgentAdapter[];
|
|
72
|
+
taskAdapters?: readonly AgentTaskAdapter[];
|
|
73
|
+
leases: AccountLeaseStore;
|
|
74
|
+
now: () => number;
|
|
75
|
+
});
|
|
76
|
+
/** Additive execution path for an application's exact capability profile. */
|
|
77
|
+
runTask(request: AgentTaskRequest, broker: CapabilityBroker): Promise<AgentTaskResult>;
|
|
78
|
+
run(request: AgentRunRequest, broker: ToolBroker): Promise<AgentRunResult>;
|
|
79
|
+
private runAdmitted;
|
|
80
|
+
}
|
|
81
|
+
export declare function assertQualified(value: RuntimeQualification, now: number): void;
|
|
82
|
+
export type ProviderLaunchPlan = Readonly<{
|
|
83
|
+
provider: AgentProvider;
|
|
84
|
+
status: "unqualified";
|
|
85
|
+
authBindingId: string;
|
|
86
|
+
workspaceId: string;
|
|
87
|
+
/** Configuration intent, not an executable security claim. Host adapter must qualify it. */
|
|
88
|
+
configuration: Readonly<Record<string, unknown>>;
|
|
89
|
+
}>;
|
|
90
|
+
export declare function createProviderLaunchPlan(binding: AccountBinding, workspaceId: string): ProviderLaunchPlan;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type SqliteBinding = string | number | bigint | boolean | null | Uint8Array;
|
|
2
|
+
export interface SqliteStatement<Row, _Params extends SqliteBinding[] = SqliteBinding[]> {
|
|
3
|
+
get(...params: unknown[]): Row | null;
|
|
4
|
+
all(...params: unknown[]): Row[];
|
|
5
|
+
run(...params: unknown[]): {
|
|
6
|
+
changes: number;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface SqliteDatabase {
|
|
10
|
+
exec(sql: string): void;
|
|
11
|
+
query<Row = unknown, Params extends SqliteBinding[] = SqliteBinding[]>(sql: string): SqliteStatement<Row, Params>;
|
|
12
|
+
close(): void;
|
|
13
|
+
}
|
|
14
|
+
type NativeStatement = {
|
|
15
|
+
get(...params: never[]): unknown;
|
|
16
|
+
all(...params: never[]): unknown[];
|
|
17
|
+
run(...params: never[]): {
|
|
18
|
+
changes: number | bigint;
|
|
19
|
+
};
|
|
20
|
+
finalize?(): void;
|
|
21
|
+
};
|
|
22
|
+
type NativeDatabase = {
|
|
23
|
+
exec(sql: string): unknown;
|
|
24
|
+
prepare(sql: string): NativeStatement;
|
|
25
|
+
close(): void;
|
|
26
|
+
};
|
|
27
|
+
export declare function wrapSqliteDatabase(database: NativeDatabase, journal?: "WAL" | "DELETE"): SqliteDatabase;
|
|
28
|
+
export declare function openAccountDatabase(path: string, journal?: "WAL" | "DELETE"): Promise<SqliteDatabase>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { AccountLease, AccountLeaseStore } from "./accounts.ts";
|
|
2
|
+
import { type CapabilityBroker, type CapabilityProfileIdentity } from "./capabilities.ts";
|
|
3
|
+
import { type AgentProvider } from "./validation.ts";
|
|
4
|
+
export type AgentTaskRoute = Readonly<{
|
|
5
|
+
id: string;
|
|
6
|
+
provider: AgentProvider;
|
|
7
|
+
authentication: "subscription" | "api";
|
|
8
|
+
}>;
|
|
9
|
+
export type AgentTaskModel = Readonly<{
|
|
10
|
+
id: string;
|
|
11
|
+
reasoningEffort: string | null;
|
|
12
|
+
serviceTier: string | null;
|
|
13
|
+
}>;
|
|
14
|
+
/** Freshness proof supplied only by a trusted managed-account handoff. It is
|
|
15
|
+
* provenance, not permission: the runtime still requires its normal lease and
|
|
16
|
+
* qualification checks. */
|
|
17
|
+
export type AgentTaskAuthority = Readonly<{
|
|
18
|
+
kind: "codex-managed";
|
|
19
|
+
accountGeneration: number;
|
|
20
|
+
modelCatalogDigest: string;
|
|
21
|
+
}>;
|
|
22
|
+
export type AgentTaskLimits = Readonly<{
|
|
23
|
+
maxRunMs: number;
|
|
24
|
+
maxCleanupMs: number;
|
|
25
|
+
maxOutputBytes: number;
|
|
26
|
+
}>;
|
|
27
|
+
export type TaskRuntimeQualification = Readonly<{
|
|
28
|
+
status: "unqualified";
|
|
29
|
+
reason: string;
|
|
30
|
+
}> | Readonly<{
|
|
31
|
+
status: "qualified";
|
|
32
|
+
route: AgentTaskRoute;
|
|
33
|
+
profile: CapabilityProfileIdentity;
|
|
34
|
+
runtimeVersion: string;
|
|
35
|
+
runtimeDigest: string;
|
|
36
|
+
evidenceDigest: string;
|
|
37
|
+
expiresAt: number;
|
|
38
|
+
controls: Readonly<{
|
|
39
|
+
noCommandTools: true;
|
|
40
|
+
exactToolInventory: true;
|
|
41
|
+
workspaceReadIsolation: true;
|
|
42
|
+
workspaceWriteIsolation: true;
|
|
43
|
+
isolatedConfiguration: true;
|
|
44
|
+
authOutsideWorkspace: true;
|
|
45
|
+
hostBrokerOnly: true;
|
|
46
|
+
}>;
|
|
47
|
+
}>;
|
|
48
|
+
export type AgentTaskRequest = Readonly<{
|
|
49
|
+
route: AgentTaskRoute;
|
|
50
|
+
accountId: string;
|
|
51
|
+
workspaceId: string;
|
|
52
|
+
runId: string;
|
|
53
|
+
profile: CapabilityProfileIdentity;
|
|
54
|
+
model: AgentTaskModel;
|
|
55
|
+
purpose: string;
|
|
56
|
+
prompt: string;
|
|
57
|
+
limits: AgentTaskLimits;
|
|
58
|
+
signal: AbortSignal;
|
|
59
|
+
authority?: AgentTaskAuthority;
|
|
60
|
+
}>;
|
|
61
|
+
export type AgentTaskRuntimeProof = Readonly<{
|
|
62
|
+
runtimeVersion: string;
|
|
63
|
+
runtimeDigest: string;
|
|
64
|
+
evidenceDigest: string;
|
|
65
|
+
qualificationExpiresAt: number;
|
|
66
|
+
}>;
|
|
67
|
+
/** Runtime-owned snapshot of the one acquired lease. Its values may be retained
|
|
68
|
+
* as evidence; a reconstructed object never grants execution authority. */
|
|
69
|
+
export type AgentTaskAccountLease = AccountLease;
|
|
70
|
+
export type AgentTaskBinding = Readonly<{
|
|
71
|
+
route: AgentTaskRoute;
|
|
72
|
+
accountId: string;
|
|
73
|
+
workspaceId: string;
|
|
74
|
+
runId: string;
|
|
75
|
+
profile: CapabilityProfileIdentity;
|
|
76
|
+
model: AgentTaskModel;
|
|
77
|
+
runtime: AgentTaskRuntimeProof;
|
|
78
|
+
accountLease: AgentTaskAccountLease;
|
|
79
|
+
authority?: AgentTaskAuthority;
|
|
80
|
+
}>;
|
|
81
|
+
export type AgentTaskExecutionRequest = AgentTaskRequest & Readonly<{
|
|
82
|
+
runtime: AgentTaskRuntimeProof;
|
|
83
|
+
accountLease: AgentTaskAccountLease;
|
|
84
|
+
admittedAtUnixMs: number;
|
|
85
|
+
executionDeadlineUnixMs: number;
|
|
86
|
+
cleanupDeadlineUnixMs: number;
|
|
87
|
+
}>;
|
|
88
|
+
export type AgentTaskUsage = Readonly<{
|
|
89
|
+
inputTokens: number | null;
|
|
90
|
+
outputTokens: number | null;
|
|
91
|
+
totalTokens: number | null;
|
|
92
|
+
costUsd: number | null;
|
|
93
|
+
}>;
|
|
94
|
+
export type AgentTaskOutcome = Readonly<{
|
|
95
|
+
status: "completed" | "failed" | "cancelled" | "deadline-exceeded";
|
|
96
|
+
code: string | null;
|
|
97
|
+
}>;
|
|
98
|
+
export type AgentTaskCompletion = AgentTaskBinding & Readonly<{
|
|
99
|
+
output: string | null;
|
|
100
|
+
usage: AgentTaskUsage;
|
|
101
|
+
outcome: AgentTaskOutcome;
|
|
102
|
+
}>;
|
|
103
|
+
export type AgentTaskStopReason = "completed" | "failed" | "cancelled" | "deadline-exceeded";
|
|
104
|
+
/** Trusted adapter evidence, never inferred from a signal, timeout or lease expiry. */
|
|
105
|
+
export type AgentTaskStopEvidence = AgentTaskBinding & Readonly<{
|
|
106
|
+
processStopped: true;
|
|
107
|
+
controllersStopped: true;
|
|
108
|
+
joined: true;
|
|
109
|
+
stoppedAtUnixMs: number;
|
|
110
|
+
proofDigest: string;
|
|
111
|
+
}>;
|
|
112
|
+
export type AgentTaskResult = AgentTaskCompletion & Readonly<{
|
|
113
|
+
stop: AgentTaskStopEvidence;
|
|
114
|
+
timing: Readonly<{
|
|
115
|
+
admittedAtUnixMs: number;
|
|
116
|
+
executionDeadlineUnixMs: number;
|
|
117
|
+
cleanupDeadlineUnixMs: number;
|
|
118
|
+
outerDeadlineUnixMs: number;
|
|
119
|
+
joinedAtUnixMs: number;
|
|
120
|
+
cleanupDeadlineExceeded: boolean;
|
|
121
|
+
}>;
|
|
122
|
+
brokerJoined: true;
|
|
123
|
+
custody: "released";
|
|
124
|
+
}>;
|
|
125
|
+
export interface AgentTaskAdapter {
|
|
126
|
+
readonly route: AgentTaskRoute;
|
|
127
|
+
readonly runtime: Readonly<{
|
|
128
|
+
version: string;
|
|
129
|
+
digest: string;
|
|
130
|
+
}>;
|
|
131
|
+
readonly qualification: TaskRuntimeQualification;
|
|
132
|
+
run(request: AgentTaskExecutionRequest, broker: CapabilityBroker): Promise<AgentTaskCompletion>;
|
|
133
|
+
/** Must work while run is pending; settle only after every owned controller/process joins.
|
|
134
|
+
* This request copy carries the actual cleanup deadline, capped by the original outer deadline. */
|
|
135
|
+
stop(request: AgentTaskExecutionRequest, reason: AgentTaskStopReason): Promise<AgentTaskStopEvidence>;
|
|
136
|
+
}
|
|
137
|
+
export type AgentTaskOptions = Readonly<{
|
|
138
|
+
adapters: readonly AgentTaskAdapter[];
|
|
139
|
+
leases: AccountLeaseStore;
|
|
140
|
+
now(): number;
|
|
141
|
+
}>;
|
|
142
|
+
/** Check runtime provenance without minting authority. Adapters must retain the
|
|
143
|
+
* original lease reference and signal when copying a request. Cancellation can
|
|
144
|
+
* narrow stop's cleanup deadline; it cannot authorize another run or lease. */
|
|
145
|
+
export declare function assertAgentTaskAccountLease(request: AgentTaskExecutionRequest, phase?: "run" | "stop"): AgentTaskAccountLease;
|
|
146
|
+
/** Admission only: no bundled live adapter, credential discovery or route fallback.
|
|
147
|
+
* Native adapters must enforce supplied deadlines outside this JS event loop. This
|
|
148
|
+
* owner never races past unresolved run/stop/handler promises or claims force-stop.
|
|
149
|
+
*/
|
|
150
|
+
export declare function runAgentTask(options: AgentTaskOptions, input: AgentTaskRequest, broker: CapabilityBroker): Promise<AgentTaskResult>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function object(value: unknown, keys: readonly string[]): Record<string, unknown>;
|
|
2
|
+
export declare function boundedText(value: unknown, maxBytes: number, empty?: boolean): string;
|
|
3
|
+
export declare function identifier(value: unknown): string;
|
|
4
|
+
export declare function safeInteger(value: unknown, min: number, max: number): number;
|
|
5
|
+
export type AgentProvider = "codex" | "claude" | "devin";
|
|
6
|
+
export declare function provider(value: unknown): AgentProvider;
|