@automatalabs/acp-agents 0.21.2 → 0.22.0
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/dist/acp-client.d.ts +51 -0
- package/dist/acp-client.d.ts.map +1 -1
- package/dist/acp-client.js +127 -2
- package/dist/auth/auth-profiles.d.ts +63 -0
- package/dist/auth/auth-profiles.d.ts.map +1 -0
- package/dist/auth/auth-profiles.js +45 -0
- package/dist/auth/auth-store.d.ts +112 -0
- package/dist/auth/auth-store.d.ts.map +1 -0
- package/dist/auth/auth-store.js +186 -0
- package/dist/auth/auth-types.d.ts +93 -0
- package/dist/auth/auth-types.d.ts.map +1 -0
- package/dist/auth/auth-types.js +108 -0
- package/dist/backend.d.ts +7 -0
- package/dist/backend.d.ts.map +1 -1
- package/dist/backends/claude.d.ts +2 -0
- package/dist/backends/claude.d.ts.map +1 -1
- package/dist/backends/claude.js +3 -0
- package/dist/backends/codex.d.ts +3 -0
- package/dist/backends/codex.d.ts.map +1 -1
- package/dist/backends/codex.js +4 -0
- package/dist/backends/opencode.d.ts +2 -0
- package/dist/backends/opencode.d.ts.map +1 -1
- package/dist/backends/opencode.js +3 -0
- package/dist/capabilities.d.ts +7 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +17 -0
- package/dist/client-handlers.d.ts +9 -0
- package/dist/client-handlers.d.ts.map +1 -1
- package/dist/client-handlers.js +17 -0
- package/dist/errors-map.d.ts.map +1 -1
- package/dist/errors-map.js +26 -2
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/permissions.d.ts +27 -0
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +23 -1
- package/dist/pool.d.ts +20 -0
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +58 -16
- package/dist/protocol-coverage.d.ts +75 -0
- package/dist/protocol-coverage.d.ts.map +1 -1
- package/dist/protocol-coverage.js +58 -0
- package/dist/runner.d.ts +120 -3
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +307 -20
- package/package.json +2 -2
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { isGatewayShapedMeta } from "./auth-types.js";
|
|
2
|
+
/** Type-driven, agent-agnostic classification (§2.1). Keys ONLY on the method type + whether the
|
|
3
|
+
* advertised `_meta` is gateway-shaped — never on an agent id. */
|
|
4
|
+
export function classifyCredential(methodType, advertisedMeta) {
|
|
5
|
+
switch (methodType) {
|
|
6
|
+
case "env_var":
|
|
7
|
+
return { klass: "spawn-env", diskBacked: false };
|
|
8
|
+
case "terminal":
|
|
9
|
+
return { klass: "disk", diskBacked: true };
|
|
10
|
+
case "agent":
|
|
11
|
+
return isGatewayShapedMeta(advertisedMeta)
|
|
12
|
+
? { klass: "in-process", diskBacked: false }
|
|
13
|
+
: { klass: "disk", diskBacked: true };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Best-effort in-place zeroization of an intent's secret payload before it is dropped (§2.14). The
|
|
17
|
+
* intent's `readonly` typing is a compile-time contract, not a runtime freeze, so we overwrite. */
|
|
18
|
+
function zeroizeIntent(intent) {
|
|
19
|
+
const meta = intent.authenticateMeta;
|
|
20
|
+
if (meta)
|
|
21
|
+
for (const key of Object.keys(meta))
|
|
22
|
+
delete meta[key];
|
|
23
|
+
const env = intent.envValues;
|
|
24
|
+
if (env)
|
|
25
|
+
for (const key of Object.keys(env))
|
|
26
|
+
env[key] = "";
|
|
27
|
+
}
|
|
28
|
+
/** One state machine per `poolKey`, owned by the `AuthStore`. The single source of auth truth. */
|
|
29
|
+
export class BackendAuthMachine {
|
|
30
|
+
_state = "unauthenticated";
|
|
31
|
+
_generation = 0;
|
|
32
|
+
_intent;
|
|
33
|
+
_advertised = [];
|
|
34
|
+
get state() {
|
|
35
|
+
return this._state;
|
|
36
|
+
}
|
|
37
|
+
get generation() {
|
|
38
|
+
return this._generation;
|
|
39
|
+
}
|
|
40
|
+
/** The advertised methods most recently observed at `initialize` (redaction source for status). */
|
|
41
|
+
get advertised() {
|
|
42
|
+
return this._advertised;
|
|
43
|
+
}
|
|
44
|
+
get authenticated() {
|
|
45
|
+
return this._state === "authenticated";
|
|
46
|
+
}
|
|
47
|
+
/** Redacted view — ids/types/klass only, NEVER authenticateMeta/envValues. */
|
|
48
|
+
intentView() {
|
|
49
|
+
if (!this._intent)
|
|
50
|
+
return undefined;
|
|
51
|
+
const { authenticateMeta: _m, envValues: _e, ...rest } = this._intent;
|
|
52
|
+
return rest;
|
|
53
|
+
}
|
|
54
|
+
/** SECRET accessor — connection-internal only (used by applyAuthIntent, §2.5). */
|
|
55
|
+
applyMeta() {
|
|
56
|
+
return this._intent?.authenticateMeta;
|
|
57
|
+
}
|
|
58
|
+
/** SECRET accessor — pool/connection-internal only (used by spawnEnvFor, §2.8). */
|
|
59
|
+
spawnEnv() {
|
|
60
|
+
return this._intent?.envValues;
|
|
61
|
+
}
|
|
62
|
+
/** SECRET accessor — module-internal only (AuthStore.spawnEnvFor passes it to a profile). */
|
|
63
|
+
rawIntent() {
|
|
64
|
+
return this._intent;
|
|
65
|
+
}
|
|
66
|
+
/** Cold-resume re-arm predicate (§2.13): resumable iff creds are held/applied OR disk-backed. */
|
|
67
|
+
canResume() {
|
|
68
|
+
if (this._state === "authenticated" || this._state === "credentials_held")
|
|
69
|
+
return true;
|
|
70
|
+
return this._intent?.diskBacked === true;
|
|
71
|
+
}
|
|
72
|
+
isStale(stamp) {
|
|
73
|
+
return stamp.appliedGeneration < this._generation;
|
|
74
|
+
}
|
|
75
|
+
/** true iff the current intent is an in-process (gateway) cred that can be live-re-applied on an
|
|
76
|
+
* idle connection via an authenticate RPC replay, rather than requiring a process recycle. */
|
|
77
|
+
currentKlassIsInProcess() {
|
|
78
|
+
return this._intent?.klass === "in-process";
|
|
79
|
+
}
|
|
80
|
+
send(ev) {
|
|
81
|
+
switch (ev.t) {
|
|
82
|
+
case "initialize_ok":
|
|
83
|
+
this._advertised = ev.advertised;
|
|
84
|
+
return;
|
|
85
|
+
case "host_authenticate":
|
|
86
|
+
// The only events that bump `generation` are host_authenticate and logout, so one completed
|
|
87
|
+
// auth atomically invalidates every existing connection's stamp (§2.3).
|
|
88
|
+
this._intent = ev.intent;
|
|
89
|
+
this._generation += 1;
|
|
90
|
+
this._state = "credentials_held";
|
|
91
|
+
return;
|
|
92
|
+
case "apply_ok":
|
|
93
|
+
if (this._state === "credentials_held")
|
|
94
|
+
this._state = "authenticated";
|
|
95
|
+
return;
|
|
96
|
+
case "apply_failed":
|
|
97
|
+
if (this._state === "credentials_held" || this._state === "authenticated") {
|
|
98
|
+
this._state = "auth_required";
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
case "auth_required_tripped":
|
|
102
|
+
// unauthenticated / auth_required / authenticated -> auth_required (mid-run expiry included).
|
|
103
|
+
this._state = "auth_required";
|
|
104
|
+
return;
|
|
105
|
+
case "logout":
|
|
106
|
+
if (this._intent)
|
|
107
|
+
zeroizeIntent(this._intent);
|
|
108
|
+
this._intent = undefined;
|
|
109
|
+
this._generation += 1;
|
|
110
|
+
this._state = "unauthenticated";
|
|
111
|
+
return;
|
|
112
|
+
case "process_death":
|
|
113
|
+
// The dying connection's stamp is dropped with it; machine state is unchanged (§2.3).
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** The single per-runner auth store. Owns one `BackendAuthMachine` per `poolKey` and records the
|
|
119
|
+
* (optional) per-backend `AuthProfile` so `spawnEnvFor` can consult it. */
|
|
120
|
+
export class AuthStore {
|
|
121
|
+
machines = new Map();
|
|
122
|
+
profiles = new Map();
|
|
123
|
+
/** Get/create the machine for a `poolKey`, recording the backend's profile the first time. */
|
|
124
|
+
machineFor(poolKey, profile) {
|
|
125
|
+
let machine = this.machines.get(poolKey);
|
|
126
|
+
if (!machine) {
|
|
127
|
+
machine = new BackendAuthMachine();
|
|
128
|
+
this.machines.set(poolKey, machine);
|
|
129
|
+
}
|
|
130
|
+
if (profile && !this.profiles.has(poolKey))
|
|
131
|
+
this.profiles.set(poolKey, profile);
|
|
132
|
+
return machine;
|
|
133
|
+
}
|
|
134
|
+
/** The machine for a `poolKey`, or undefined if none has been created yet (read-only lookup). */
|
|
135
|
+
existing(poolKey) {
|
|
136
|
+
return this.machines.get(poolKey);
|
|
137
|
+
}
|
|
138
|
+
/** Every `poolKey` that has a machine (the touched backends). */
|
|
139
|
+
poolKeys() {
|
|
140
|
+
return [...this.machines.keys()];
|
|
141
|
+
}
|
|
142
|
+
/** The spawn-env overlay (§2.8): the machine's `env_var` collected values merged with the backend
|
|
143
|
+
* profile's `spawnAuthEnv(intent)` contribution. Undefined when neither applies. Secret — passed
|
|
144
|
+
* straight to `spawn`, never logged. */
|
|
145
|
+
spawnEnvFor(poolKey) {
|
|
146
|
+
const machine = this.machines.get(poolKey);
|
|
147
|
+
if (!machine)
|
|
148
|
+
return undefined;
|
|
149
|
+
const envValues = machine.spawnEnv();
|
|
150
|
+
const profile = this.profiles.get(poolKey);
|
|
151
|
+
const intent = machine.rawIntent();
|
|
152
|
+
const profileEnv = profile?.spawnAuthEnv && intent ? profile.spawnAuthEnv(intent) : undefined;
|
|
153
|
+
if (!envValues && !profileEnv)
|
|
154
|
+
return undefined;
|
|
155
|
+
return { ...(envValues ?? {}), ...(profileEnv ?? {}) };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Strip credential-shaped substrings from best-effort diagnostic text (stderr tails, §2.14). Never
|
|
159
|
+
* the machine-readable channel — a defensive scrub so a spawned agent that echoes an injected env
|
|
160
|
+
* var to stderr cannot leak it into an error suffix. */
|
|
161
|
+
const SECRET_LINE_PATTERNS = [
|
|
162
|
+
/^(\s*(?:export\s+)?)([A-Za-z_][A-Za-z0-9_]*_API_KEY|ANTHROPIC_AUTH_TOKEN|CLAUDE_CODE_OAUTH_TOKEN|AWS_[A-Za-z0-9_]+|CODEX_API_KEY|CODEX_ACCESS_TOKEN|CODEX_AUTH|OPENCODE_AUTH_CONTENT|DEFAULT_AUTH_REQUEST)(\s*[:=]\s*)(\S.*)$/,
|
|
163
|
+
];
|
|
164
|
+
const SECRET_INLINE_PATTERNS = [
|
|
165
|
+
{ re: /\b([A-Za-z_][A-Za-z0-9_]*_API_KEY|ANTHROPIC_AUTH_TOKEN|CLAUDE_CODE_OAUTH_TOKEN|CODEX_API_KEY|CODEX_ACCESS_TOKEN|OPENCODE_AUTH_CONTENT)(=)(\S+)/g, replace: "$1=[redacted]" },
|
|
166
|
+
// Bearer tokens / Authorization header values.
|
|
167
|
+
{ re: /\b(Bearer|Authorization:?\s*Bearer)\s+[A-Za-z0-9._~+/=-]+/gi, replace: "$1 [redacted]" },
|
|
168
|
+
];
|
|
169
|
+
export function redactSecrets(text) {
|
|
170
|
+
if (!text)
|
|
171
|
+
return text;
|
|
172
|
+
return text
|
|
173
|
+
.split("\n")
|
|
174
|
+
.map((line) => {
|
|
175
|
+
for (const re of SECRET_LINE_PATTERNS) {
|
|
176
|
+
const m = line.match(re);
|
|
177
|
+
if (m)
|
|
178
|
+
return `${m[1]}${m[2]}${m[3]}[redacted]`;
|
|
179
|
+
}
|
|
180
|
+
let out = line;
|
|
181
|
+
for (const { re, replace } of SECRET_INLINE_PATTERNS)
|
|
182
|
+
out = out.replace(re, replace);
|
|
183
|
+
return out;
|
|
184
|
+
})
|
|
185
|
+
.join("\n");
|
|
186
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AuthMethod } from "@agentclientprotocol/sdk";
|
|
2
|
+
import type { SpawnConfig } from "../backend.js";
|
|
3
|
+
/** Host-agnostic, fully type-dispatched view of one advertised `AuthMethod`. ZERO backend branching. */
|
|
4
|
+
export type AuthMethodDescriptor = {
|
|
5
|
+
type: "agent";
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
/** true iff the advertised `authMethods[]._meta` block is present (a `_meta` object exists —
|
|
10
|
+
* gateway OR api-key convention). Whether it is *gateway-shaped* is a SEPARATE test that
|
|
11
|
+
* drives `klass` (§2.1), not `expectsMeta`. */
|
|
12
|
+
expectsMeta: boolean;
|
|
13
|
+
meta?: Record<string, unknown>;
|
|
14
|
+
/** true iff this is a bare `agent` method (no `_meta`) that runs its OWN login via the
|
|
15
|
+
* authenticate RPC — which may open a browser or need a TTY (e.g. codex `chat-gpt`).
|
|
16
|
+
* Derived as `!expectsMeta`. Headless hosts (MCP/SDK) use this to SKIP a method they cannot
|
|
17
|
+
* complete instead of mapping it to a no-op (§4.3). */
|
|
18
|
+
interactive: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
type: "terminal";
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
/** How the host spawns the interactive login. Base fills from EITHER the conventional
|
|
25
|
+
* `_meta["terminal-auth"] {command,args,label}` (preferred; not an SDK schema field), OR the
|
|
26
|
+
* agent binary + `AuthMethodTerminal.args`/`env` (spec baseline). */
|
|
27
|
+
launch: {
|
|
28
|
+
command: string;
|
|
29
|
+
args: string[];
|
|
30
|
+
env?: Record<string, string>;
|
|
31
|
+
label?: string;
|
|
32
|
+
};
|
|
33
|
+
meta?: Record<string, unknown>;
|
|
34
|
+
} | {
|
|
35
|
+
type: "env_var";
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
link?: string;
|
|
40
|
+
/** Per-var `meta` carries the SDK-first-class `AuthEnvVar._meta` through unchanged, so no
|
|
41
|
+
* env_var surface is silently dropped (Principle 3, §3.6). */
|
|
42
|
+
vars: Array<{
|
|
43
|
+
name: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
secret: boolean;
|
|
46
|
+
optional: boolean;
|
|
47
|
+
meta?: Record<string, unknown>;
|
|
48
|
+
}>;
|
|
49
|
+
meta?: Record<string, unknown>;
|
|
50
|
+
};
|
|
51
|
+
/** The host-collected outcome of one auth step. `env`/`meta` payloads are SECRET (Principle 9). */
|
|
52
|
+
export type AuthResolution = {
|
|
53
|
+
outcome: "completed";
|
|
54
|
+
methodId?: string;
|
|
55
|
+
} | {
|
|
56
|
+
outcome: "agent-login";
|
|
57
|
+
methodId: string;
|
|
58
|
+
} | {
|
|
59
|
+
outcome: "env";
|
|
60
|
+
values: Record<string, string>;
|
|
61
|
+
methodId?: string;
|
|
62
|
+
} | {
|
|
63
|
+
outcome: "meta";
|
|
64
|
+
methodId: string;
|
|
65
|
+
meta: Record<string, unknown>;
|
|
66
|
+
} | {
|
|
67
|
+
outcome: "cancelled";
|
|
68
|
+
};
|
|
69
|
+
export interface AuthContext {
|
|
70
|
+
readonly backendId: string;
|
|
71
|
+
readonly label?: string;
|
|
72
|
+
/** All advertised methods, already dispatched by `buildAuthDescriptors`. */
|
|
73
|
+
readonly methods: readonly AuthMethodDescriptor[];
|
|
74
|
+
/** `required` = we hit -32000; `proactive` = pre-run enumeration. */
|
|
75
|
+
readonly cause: "required" | "proactive";
|
|
76
|
+
readonly signal?: AbortSignal;
|
|
77
|
+
}
|
|
78
|
+
/** The host-facing inline auth resolver hook. Mirrors PermissionResolver / ElicitationResolver. */
|
|
79
|
+
export type AuthResolver = (ctx: AuthContext) => Promise<AuthResolution> | AuthResolution;
|
|
80
|
+
/** The conventional in-process gateway key (`_meta.gateway`) claude+codex attach to a gateway
|
|
81
|
+
* method. Its PRESENCE (a gateway-shaped `_meta`) is what makes us classify a method `in-process`
|
|
82
|
+
* (§2.1). Recognized by literal name; NOT an SDK schema field. */
|
|
83
|
+
export declare const GATEWAY_META_KEY = "gateway";
|
|
84
|
+
/** A `_meta` object counts as gateway-shaped iff it carries the literal `gateway` key with a
|
|
85
|
+
* non-null value. This is the single discriminant behind `in-process` classification (§2.1);
|
|
86
|
+
* codex `api-key` carries a `_meta["api-key"]` block and is therefore NOT gateway-shaped. */
|
|
87
|
+
export declare function isGatewayShapedMeta(meta: Record<string, unknown> | null | undefined): boolean;
|
|
88
|
+
/** Pure, agent-agnostic per-method dispatcher (§1.3): maps each advertised `AuthMethod` to an
|
|
89
|
+
* `AuthMethodDescriptor` with NO agent identity. `spawn` supplies the terminal-launch fallback
|
|
90
|
+
* (the agent binary + `AuthMethodTerminal.args`). */
|
|
91
|
+
export declare function buildAuthDescriptors(methods: readonly AuthMethod[], spawn: SpawnConfig): AuthMethodDescriptor[];
|
|
92
|
+
export declare function buildAuthDescriptor(method: AuthMethod, spawn: SpawnConfig): AuthMethodDescriptor;
|
|
93
|
+
//# sourceMappingURL=auth-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-types.d.ts","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/** The conventional launch-hint key (`_meta["terminal-auth"] = {command,args,label}`) both claude
|
|
2
|
+
* 0.57.0 and opencode 1.17.14 attach to a terminal login method. Recognized by literal name; it is
|
|
3
|
+
* NOT an SDK schema field. */
|
|
4
|
+
const TERMINAL_AUTH_META_KEY = "terminal-auth";
|
|
5
|
+
/** The conventional in-process gateway key (`_meta.gateway`) claude+codex attach to a gateway
|
|
6
|
+
* method. Its PRESENCE (a gateway-shaped `_meta`) is what makes us classify a method `in-process`
|
|
7
|
+
* (§2.1). Recognized by literal name; NOT an SDK schema field. */
|
|
8
|
+
export const GATEWAY_META_KEY = "gateway";
|
|
9
|
+
/** A `_meta` object counts as gateway-shaped iff it carries the literal `gateway` key with a
|
|
10
|
+
* non-null value. This is the single discriminant behind `in-process` classification (§2.1);
|
|
11
|
+
* codex `api-key` carries a `_meta["api-key"]` block and is therefore NOT gateway-shaped. */
|
|
12
|
+
export function isGatewayShapedMeta(meta) {
|
|
13
|
+
return meta != null && meta[GATEWAY_META_KEY] != null;
|
|
14
|
+
}
|
|
15
|
+
function metaOf(method) {
|
|
16
|
+
const meta = method._meta;
|
|
17
|
+
return meta ?? undefined;
|
|
18
|
+
}
|
|
19
|
+
/** The SDK types a missing `type` discriminant as `agent` (AuthMethodAgent carries no `type`). */
|
|
20
|
+
function typeOf(method) {
|
|
21
|
+
return (("type" in method ? method.type : undefined) ?? "agent");
|
|
22
|
+
}
|
|
23
|
+
function terminalAuthHint(meta) {
|
|
24
|
+
const hint = meta?.[TERMINAL_AUTH_META_KEY];
|
|
25
|
+
if (!hint || typeof hint !== "object")
|
|
26
|
+
return undefined;
|
|
27
|
+
const record = hint;
|
|
28
|
+
if (typeof record.command !== "string")
|
|
29
|
+
return undefined;
|
|
30
|
+
const args = Array.isArray(record.args) ? record.args.filter((a) => typeof a === "string") : [];
|
|
31
|
+
return { command: record.command, args, ...(typeof record.label === "string" ? { label: record.label } : {}) };
|
|
32
|
+
}
|
|
33
|
+
/** true iff a bare `agent` method (`type` absent OR "agent") is semantically a TERMINAL login —
|
|
34
|
+
* i.e. it carries a `_meta["terminal-auth"]` launch hint. This is why OpenCode's bare-`agent`
|
|
35
|
+
* `opencode-login` becomes a `terminal` descriptor for us, while codex's `gateway` (which carries
|
|
36
|
+
* `_meta.gateway`, not `terminal-auth`) does not (§3.1 decision). */
|
|
37
|
+
function isTerminalShaped(method) {
|
|
38
|
+
const type = typeOf(method);
|
|
39
|
+
if (type === "terminal")
|
|
40
|
+
return true;
|
|
41
|
+
if (type === "env_var")
|
|
42
|
+
return false;
|
|
43
|
+
return terminalAuthHint(metaOf(method)) !== undefined;
|
|
44
|
+
}
|
|
45
|
+
/** Pure, agent-agnostic per-method dispatcher (§1.3): maps each advertised `AuthMethod` to an
|
|
46
|
+
* `AuthMethodDescriptor` with NO agent identity. `spawn` supplies the terminal-launch fallback
|
|
47
|
+
* (the agent binary + `AuthMethodTerminal.args`). */
|
|
48
|
+
export function buildAuthDescriptors(methods, spawn) {
|
|
49
|
+
return methods.map((method) => buildAuthDescriptor(method, spawn));
|
|
50
|
+
}
|
|
51
|
+
export function buildAuthDescriptor(method, spawn) {
|
|
52
|
+
const meta = metaOf(method);
|
|
53
|
+
const description = method.description ?? undefined;
|
|
54
|
+
const type = typeOf(method);
|
|
55
|
+
if (isTerminalShaped(method)) {
|
|
56
|
+
// Launch resolution, both branches agent-id-free:
|
|
57
|
+
// 1. Method carries `_meta["terminal-auth"] = {command,args,label}` → use verbatim.
|
|
58
|
+
// 2. Pure-spec fallback → agent binary + AuthMethodTerminal.args/env.
|
|
59
|
+
const hint = terminalAuthHint(meta);
|
|
60
|
+
const terminalMethod = type === "terminal" ? method : undefined;
|
|
61
|
+
const launch = hint
|
|
62
|
+
? { command: hint.command, args: hint.args, ...(hint.label ? { label: hint.label } : {}) }
|
|
63
|
+
: {
|
|
64
|
+
command: spawn.command,
|
|
65
|
+
args: [...spawn.args, ...(terminalMethod?.args ?? [])],
|
|
66
|
+
...(terminalMethod?.env ? { env: { ...terminalMethod.env } } : {}),
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
type: "terminal",
|
|
70
|
+
id: method.id,
|
|
71
|
+
name: method.name,
|
|
72
|
+
...(description ? { description } : {}),
|
|
73
|
+
launch,
|
|
74
|
+
...(meta ? { meta } : {}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (type === "env_var") {
|
|
78
|
+
const envMethod = method;
|
|
79
|
+
const vars = (envMethod.vars ?? []).map((v) => ({
|
|
80
|
+
name: v.name,
|
|
81
|
+
...(v.label != null ? { label: v.label } : {}),
|
|
82
|
+
// SDK defaults: `secret` defaults TRUE, `optional` defaults FALSE.
|
|
83
|
+
secret: v.secret ?? true,
|
|
84
|
+
optional: v.optional ?? false,
|
|
85
|
+
...(v._meta ? { meta: v._meta } : {}),
|
|
86
|
+
}));
|
|
87
|
+
return {
|
|
88
|
+
type: "env_var",
|
|
89
|
+
id: method.id,
|
|
90
|
+
name: method.name,
|
|
91
|
+
...(description ? { description } : {}),
|
|
92
|
+
...(envMethod.link != null ? { link: envMethod.link } : {}),
|
|
93
|
+
vars,
|
|
94
|
+
...(meta ? { meta } : {}),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// agent (AuthMethodAgent, or the default when `type` is absent):
|
|
98
|
+
const expectsMeta = meta != null;
|
|
99
|
+
return {
|
|
100
|
+
type: "agent",
|
|
101
|
+
id: method.id,
|
|
102
|
+
name: method.name,
|
|
103
|
+
...(description ? { description } : {}),
|
|
104
|
+
expectsMeta,
|
|
105
|
+
interactive: !expectsMeta,
|
|
106
|
+
...(meta ? { meta } : {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
package/dist/backend.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TSchema } from "typebox";
|
|
2
|
+
import type { AuthProfile } from "./auth/auth-profiles.js";
|
|
2
3
|
/** The built-in backends. Custom registry backends extend the id space beyond these. */
|
|
3
4
|
export type BuiltinBackendId = "claude" | "codex" | "opencode";
|
|
4
5
|
/** A backend id: one of the built-ins, or the registered name of a custom ACP backend
|
|
@@ -52,6 +53,12 @@ export interface Backend {
|
|
|
52
53
|
readonly namespace: string;
|
|
53
54
|
readonly gatedKeys: readonly string[];
|
|
54
55
|
};
|
|
56
|
+
/** Per-agent auth adapter (§3.1). UNDEFINED for custom backends → the type-driven base auth flow
|
|
57
|
+
* runs verbatim (conformance-by-absence, §1.4). The three built-in backends wire their pure-data
|
|
58
|
+
* profile (§3.2–§3.4); the lifecycle spine (§2) reads it when computing `spawnEnvFor` (§2.8), the
|
|
59
|
+
* runner consults `profile.describe`/`buildMeta` (§1.3/§2.9), and the connection refines client
|
|
60
|
+
* auth capabilities through `profile.clientAuthCapabilities` (§1.2). */
|
|
61
|
+
readonly authProfile?: AuthProfile;
|
|
55
62
|
/** How to launch this backend's ACP server over stdio. */
|
|
56
63
|
spawnConfig(): SpawnConfig;
|
|
57
64
|
/** OPTIONAL backend-level `_meta` DEFAULTS for session/new (e.g. a custom registry entry's
|
package/dist/backend.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,wFAAwF;AACxF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAC/D;sFACsF;AACtF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,8FAA8F;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,eAAe,IAAI,MAAM,CAAC;IAC1B,uGAAuG;IACvG,mBAAmB,IAAI,OAAO,CAAC;CAChC;AAED;+EAC+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB;;;0EAGsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;oCAEgC;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC;;;;kGAI8F;IAC9F,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC;;qFAEiF;IACjF,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAC9C;;sFAEkF;IAClF,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IACpG;;;;6EAIyE;IACzE,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,0DAA0D;IAC1D,WAAW,IAAI,WAAW,CAAC;IAC3B;;sEAEkE;IAClE,mBAAmB,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC5D;;;mGAG+F;IAC/F,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC1G,kGAAkG;IAClG,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7E,oGAAoG;IACpG,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC;CACrD;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAE7D"}
|
|
@@ -2,6 +2,8 @@ import type { TSchema } from "typebox";
|
|
|
2
2
|
import type { Backend, SpawnConfig, StructuredSource } from "../backend.js";
|
|
3
3
|
export declare class ClaudeBackend implements Backend {
|
|
4
4
|
readonly id: "claude";
|
|
5
|
+
/** Pure-data claude auth profile (§3.2): terminal follows the host TTY, gateway follows `onAuth`. */
|
|
6
|
+
readonly authProfile: import("../auth/auth-profiles.js").AuthProfile;
|
|
5
7
|
spawnConfig(): SpawnConfig;
|
|
6
8
|
sessionMeta(schema: TSchema | undefined): Record<string, unknown> | undefined;
|
|
7
9
|
promptMeta(): Record<string, unknown> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/backends/claude.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/backends/claude.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAO5E,qBAAa,aAAc,YAAW,OAAO;IAC3C,QAAQ,CAAC,EAAE,EAAG,QAAQ,CAAU;IAChC,qGAAqG;IACrG,QAAQ,CAAC,WAAW,iDAAqB;IAEzC,WAAW,IAAI,WAAW;IAgB1B,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAmB7E,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAKjD,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO;CAGpD"}
|
package/dist/backends/claude.js
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
// `_claude/sdkMessage` extension notification (the runner's ACP client captures it).
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { splitArgs } from "../backend.js";
|
|
9
|
+
import { claudeAuthProfile } from "../auth/auth-profiles.js";
|
|
9
10
|
import { toAnthropicJsonSchema } from "../schema-strict.js";
|
|
10
11
|
const require = createRequire(import.meta.url);
|
|
11
12
|
export class ClaudeBackend {
|
|
12
13
|
id = "claude";
|
|
14
|
+
/** Pure-data claude auth profile (§3.2): terminal follows the host TTY, gateway follows `onAuth`. */
|
|
15
|
+
authProfile = claudeAuthProfile;
|
|
13
16
|
spawnConfig() {
|
|
14
17
|
const env = process.env;
|
|
15
18
|
const override = env.AGENTPRISM_CLAUDE_ACP_CMD;
|
package/dist/backends/codex.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type { TSchema } from "typebox";
|
|
|
2
2
|
import type { Backend, SessionMetaInputs, SpawnConfig, StructuredSource } from "../backend.js";
|
|
3
3
|
export declare class CodexBackend implements Backend {
|
|
4
4
|
readonly id: "codex";
|
|
5
|
+
/** Pure-data codex auth profile (§3.3): no terminal, gateway follows `onAuth`, and the
|
|
6
|
+
* `DEFAULT_AUTH_REQUEST` spawn-env lever for api-key/gateway intents. */
|
|
7
|
+
readonly authProfile: import("../auth/auth-profiles.js").AuthProfile;
|
|
5
8
|
readonly customCapabilities: {
|
|
6
9
|
readonly namespace: "@automatalabs/codex-acp";
|
|
7
10
|
readonly gatedKeys: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/backends/codex.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/backends/codex.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAS/F,qBAAa,YAAa,YAAW,OAAO;IAC1C,QAAQ,CAAC,EAAE,EAAG,OAAO,CAAU;IAC/B;8EAC0E;IAC1E,QAAQ,CAAC,WAAW,iDAAoB;IACxC,QAAQ,CAAC,kBAAkB;;;MAGhB;IAEX,WAAW,IAAI,WAAW;IAe1B,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAY1G,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAK5E,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO;CAKpD"}
|
package/dist/backends/codex.js
CHANGED
|
@@ -9,12 +9,16 @@
|
|
|
9
9
|
import { createRequire } from "node:module";
|
|
10
10
|
import { CODEX_CUSTOM_CAPABILITY_NAMESPACE, CODEX_META_KEYS, META_KEYS } from "@automatalabs/shared-types";
|
|
11
11
|
import { splitArgs } from "../backend.js";
|
|
12
|
+
import { codexAuthProfile } from "../auth/auth-profiles.js";
|
|
12
13
|
import { GATED_CUSTOM_META_KEYS } from "../capabilities.js";
|
|
13
14
|
import { toStrictJsonSchema } from "../schema-strict.js";
|
|
14
15
|
import { parseFinalJson } from "../structured-output.js";
|
|
15
16
|
const require = createRequire(import.meta.url);
|
|
16
17
|
export class CodexBackend {
|
|
17
18
|
id = "codex";
|
|
19
|
+
/** Pure-data codex auth profile (§3.3): no terminal, gateway follows `onAuth`, and the
|
|
20
|
+
* `DEFAULT_AUTH_REQUEST` spawn-env lever for api-key/gateway intents. */
|
|
21
|
+
authProfile = codexAuthProfile;
|
|
18
22
|
customCapabilities = {
|
|
19
23
|
namespace: CODEX_CUSTOM_CAPABILITY_NAMESPACE,
|
|
20
24
|
gatedKeys: GATED_CUSTOM_META_KEYS,
|
|
@@ -2,6 +2,8 @@ import type { TSchema } from "typebox";
|
|
|
2
2
|
import type { Backend, SpawnConfig, StructuredSource } from "../backend.js";
|
|
3
3
|
export declare class OpenCodeBackend implements Backend {
|
|
4
4
|
readonly id: "opencode";
|
|
5
|
+
/** Pure-data opencode auth profile (§3.4): terminal follows the host TTY; no gateway/logout. */
|
|
6
|
+
readonly authProfile: import("../auth/auth-profiles.js").AuthProfile;
|
|
5
7
|
readonly stripsRoutingPrefix = true;
|
|
6
8
|
readonly embedSchemaInPrompt = true;
|
|
7
9
|
readonly injectStructuredOutputTool = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/backends/opencode.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/backends/opencode.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAQ5E,qBAAa,eAAgB,YAAW,OAAO;IAC7C,QAAQ,CAAC,EAAE,EAAG,UAAU,CAAU;IAClC,gGAAgG;IAChG,QAAQ,CAAC,WAAW,iDAAuB;IAC3C,QAAQ,CAAC,mBAAmB,QAAQ;IACpC,QAAQ,CAAC,mBAAmB,QAAQ;IACpC,QAAQ,CAAC,0BAA0B,QAAQ;IAE3C,WAAW,IAAI,WAAW;IAW1B,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAKlD,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAO5E,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO;CAGpD"}
|
|
@@ -6,11 +6,14 @@ import { dirname, join } from "node:path";
|
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { META_KEYS } from "@automatalabs/shared-types";
|
|
8
8
|
import { splitArgs } from "../backend.js";
|
|
9
|
+
import { opencodeAuthProfile } from "../auth/auth-profiles.js";
|
|
9
10
|
import { toJsonSchema } from "../schema-strict.js";
|
|
10
11
|
import { parseFinalJson } from "../structured-output.js";
|
|
11
12
|
const require = createRequire(import.meta.url);
|
|
12
13
|
export class OpenCodeBackend {
|
|
13
14
|
id = "opencode";
|
|
15
|
+
/** Pure-data opencode auth profile (§3.4): terminal follows the host TTY; no gateway/logout. */
|
|
16
|
+
authProfile = opencodeAuthProfile;
|
|
14
17
|
stripsRoutingPrefix = true;
|
|
15
18
|
embedSchemaInPrompt = true;
|
|
16
19
|
injectStructuredOutputTool = true;
|
package/dist/capabilities.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentCapabilities, type AuthMethod, type ContentBlock, type Implementation, type InitializeResponse } from "@agentclientprotocol/sdk";
|
|
1
|
+
import { type AgentCapabilities, type AuthMethod, type ClientCapabilities, type ContentBlock, type Implementation, type InitializeResponse } from "@agentclientprotocol/sdk";
|
|
2
2
|
import { type McpServerConfig } from "@automatalabs/shared-types";
|
|
3
3
|
import type { Backend } from "./backend.js";
|
|
4
4
|
/** The bare `_meta` keys whose emission is gated by Codex's custom-capability advertisement.
|
|
@@ -48,6 +48,12 @@ export declare function negotiateCapabilities(response: InitializeResponse, cust
|
|
|
48
48
|
export declare function describeLifecycleAdvertisement(agent: AgentCapabilities): string;
|
|
49
49
|
/** Human-readable auth/provider advertisement summary for strict wrapper gate errors. */
|
|
50
50
|
export declare function describeAuthProviderAdvertisement(agent: AgentCapabilities, authMethods?: readonly AuthMethod[]): string;
|
|
51
|
+
/** Human-readable summary of the CLIENT-side auth advertisement this runner sends at initialize —
|
|
52
|
+
* the symmetric counterpart to describeAuthProviderAdvertisement (the agent side). Used for
|
|
53
|
+
* error/diagnostic text (§1.2); reads only the pinned boolean gates, never any secret. Renders
|
|
54
|
+
* e.g. `auth.terminal=true; auth._meta.gateway=true; _meta["terminal-auth"]=true`, or `auth=none`
|
|
55
|
+
* when nothing is advertised. */
|
|
56
|
+
export declare function describeClientAuthAdvertisement(auth: ClientCapabilities["auth"], meta: ClientCapabilities["_meta"]): string;
|
|
51
57
|
/** True only when the agent selected EXACTLY PROTOCOL_VERSION. This client implements that one wire
|
|
52
58
|
* version and adapts its behavior to no other, so any other selected version — older or newer —
|
|
53
59
|
* means close the connection per the ACP spec's SHOULD-close rule. Per the spec the agent echoes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAQ5C;;;iGAGiG;AACjG,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAInD,CAAC;AAEF,qFAAqF;AACrF,MAAM,WAAW,sBAAsB;IACrC;0FACsF;IACtF,eAAe,EAAE,MAAM,CAAC;IACxB;4DACwD;IACxD,KAAK,EAAE,iBAAiB,CAAC;IACzB,+DAA+D;IAC/D,SAAS,EAAE,cAAc,GAAG,SAAS,CAAC;IACtC,kGAAkG;IAClG,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,2DAA2D;IAC3D,cAAc,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,sFAAsF;IACtF,aAAa,EAAE,OAAO,CAAC;IACvB;mGAC+F;IAC/F,mBAAmB,EAAE,OAAO,CAAC;IAC7B,0CAA0C;IAC1C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,4CAA4C;IAC5C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4CAA4C;IAC5C,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wEAAwE;IACxE,cAAc,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,iBAAiB,EAAE,OAAO,CAAC;IAC3B;oGACgG;IAChG,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACvD;+EAC2E;IAC3E,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC1C;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,kBAAkB,EAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACjD,sBAAsB,CAsBxB;AAMD,qFAAqF;AACrF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAiB/E;AAED,yFAAyF;AACzF,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,iBAAiB,EACxB,WAAW,GAAE,SAAS,UAAU,EAAO,GACtC,MAAM,CAOR;AAaD;;;;+DAI+D;AAC/D,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;gEAGgE;AAChE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,SAAS,GAAE,SAAS,MAAM,EAA2B,GACpD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAWrC;AAED;;;;;2EAK2E;AAC3E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EAAE,EACtB,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,MAAM,GAChB,YAAY,EAAE,CAchB;AAkCD;;;;kEAIkE;AAClE,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,eAAe,EAAE,GAAG,SAAS,EACtC,KAAK,EAAE,iBAAiB,EACxB,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAA;CAAE,GAAG,SAAS,CAkBpF"}
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
|
package/dist/capabilities.js
CHANGED
|
@@ -86,6 +86,23 @@ export function describeAuthProviderAdvertisement(agent, authMethods = []) {
|
|
|
86
86
|
`providers=${advertised(agent.providers) ? "true" : "false"}`,
|
|
87
87
|
].join("; ");
|
|
88
88
|
}
|
|
89
|
+
/** Human-readable summary of the CLIENT-side auth advertisement this runner sends at initialize —
|
|
90
|
+
* the symmetric counterpart to describeAuthProviderAdvertisement (the agent side). Used for
|
|
91
|
+
* error/diagnostic text (§1.2); reads only the pinned boolean gates, never any secret. Renders
|
|
92
|
+
* e.g. `auth.terminal=true; auth._meta.gateway=true; _meta["terminal-auth"]=true`, or `auth=none`
|
|
93
|
+
* when nothing is advertised. */
|
|
94
|
+
export function describeClientAuthAdvertisement(auth, meta) {
|
|
95
|
+
const parts = [];
|
|
96
|
+
if (auth?.terminal === true)
|
|
97
|
+
parts.push("auth.terminal=true");
|
|
98
|
+
const gateway = auth?._meta?.gateway;
|
|
99
|
+
if (gateway === true)
|
|
100
|
+
parts.push("auth._meta.gateway=true");
|
|
101
|
+
const terminalAuth = meta?.["terminal-auth"];
|
|
102
|
+
if (terminalAuth === true)
|
|
103
|
+
parts.push('_meta["terminal-auth"]=true');
|
|
104
|
+
return parts.length > 0 ? parts.join("; ") : "auth=none";
|
|
105
|
+
}
|
|
89
106
|
function readCustomNamespace(meta, namespace) {
|
|
90
107
|
if (!meta || typeof meta !== "object")
|
|
91
108
|
return undefined;
|
|
@@ -31,6 +31,15 @@ export interface ClientCapabilityOptions {
|
|
|
31
31
|
* responder. Initialize capabilities are fixed for the connection lifetime, so a later
|
|
32
32
|
* session-scoped responder alone cannot truthfully light this up. */
|
|
33
33
|
elicitation?: boolean;
|
|
34
|
+
/** Which auth method TYPES this client can actually complete. Advertising a gate the host
|
|
35
|
+
* cannot service would invite the agent to offer a method the host can't finish. FIXED for
|
|
36
|
+
* the connection lifetime (same discipline as `elicitation`); derived once at runner
|
|
37
|
+
* construction, never per-session. Unset (or all-false) => the `auth` key is omitted entirely,
|
|
38
|
+
* which the ACP spec treats as "unsupported" — the default-OFF, zero-behavior-change baseline. */
|
|
39
|
+
auth?: {
|
|
40
|
+
terminal?: boolean;
|
|
41
|
+
gateway?: boolean;
|
|
42
|
+
};
|
|
34
43
|
}
|
|
35
44
|
/** The client capability advertisement: fs/terminal derived solely from registered consumer
|
|
36
45
|
* handlers, plus the capabilities this client supports natively regardless of handlers —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-handlers.d.ts","sourceRoot":"","sources":["../src/client-handlers.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,CACX,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,CAAC;IACxD,aAAa,CAAC,CACZ,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;CACzE;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;IAC5D,cAAc,CACZ,MAAM,EAAE,qBAAqB,EAC7B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,sBAAsB,CAAC,GAAG,sBAAsB,CAAC;IAC5D,mBAAmB,CACjB,MAAM,EAAE,0BAA0B,EAClC,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC;IACtE,YAAY,CACV,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAAC;IACtE,eAAe,CACb,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAAG,uBAAuB,GAAG,IAAI,CAAC;CAC7E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CACL,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;IACpD,OAAO,CACL,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;IACpD,UAAU,CACR,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;CACzE;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,GAAG,CAAC,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC;;0EAEsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"client-handlers.d.ts","sourceRoot":"","sources":["../src/client-handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/client-handlers.js
CHANGED
|
@@ -16,6 +16,23 @@ export function clientCapabilitiesFor(handlers, options = {}) {
|
|
|
16
16
|
const capabilities = { session: { configOptions: { boolean: {} } } };
|
|
17
17
|
if (options.elicitation)
|
|
18
18
|
capabilities.elicitation = { form: {}, url: {} };
|
|
19
|
+
// Auth advertisement is host-declared, not handler-derived (like `elicitation`), so it is applied
|
|
20
|
+
// before the no-handlers early return. `auth` is OMITTED entirely unless a gate is requested —
|
|
21
|
+
// any capability absent from `initialize` MUST be treated as unsupported by the agent (§1.2).
|
|
22
|
+
if (options.auth?.terminal || options.auth?.gateway) {
|
|
23
|
+
const auth = {};
|
|
24
|
+
if (options.auth.terminal)
|
|
25
|
+
auth.terminal = true; // typed SDK field (schema/types.gen.d.ts AuthCapabilities.terminal)
|
|
26
|
+
if (options.auth.gateway)
|
|
27
|
+
auth._meta = { gateway: true }; // claude+codex gateway gate
|
|
28
|
+
capabilities.auth = auth;
|
|
29
|
+
if (options.auth.terminal) {
|
|
30
|
+
// claude 0.57.0 (acp-agent.js:339) and opencode 1.17.14 (service.ts:100-101) ALSO read the
|
|
31
|
+
// top-level `_meta["terminal-auth"]` channel, which additionally carries the spawnable
|
|
32
|
+
// {command,args,label} launch hint. Light both so all three agents reveal terminal methods.
|
|
33
|
+
capabilities._meta = { ...(capabilities._meta ?? {}), "terminal-auth": true };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
19
36
|
if (!handlers)
|
|
20
37
|
return capabilities;
|
|
21
38
|
const fs = handlers.fs;
|