chivgent 1.0.1 → 1.1.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/README.md +102 -131
- package/README.zh-CN.md +97 -824
- package/dist/agent.d.ts +16 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +95 -43
- package/dist/agent.js.map +1 -1
- package/dist/auth/oauth.d.ts +51 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +444 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/cli-options.d.ts +8 -5
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +36 -3
- package/dist/cli-options.js.map +1 -1
- package/dist/cli-runtime.d.ts +9 -0
- package/dist/cli-runtime.d.ts.map +1 -1
- package/dist/cli-runtime.js +32 -6
- package/dist/cli-runtime.js.map +1 -1
- package/dist/cli.js +57 -10
- package/dist/cli.js.map +1 -1
- package/dist/context/context-manager.d.ts +21 -0
- package/dist/context/context-manager.d.ts.map +1 -1
- package/dist/context/context-manager.js +199 -35
- package/dist/context/context-manager.js.map +1 -1
- package/dist/evals/tools.d.ts.map +1 -1
- package/dist/evals/tools.js +4 -2
- package/dist/evals/tools.js.map +1 -1
- package/dist/events.d.ts +5 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/permissions.d.ts +35 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +89 -0
- package/dist/permissions.js.map +1 -0
- package/dist/prompts.d.ts +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +1 -0
- package/dist/prompts.js.map +1 -1
- package/dist/providers/client.d.ts +1 -1
- package/dist/providers/client.d.ts.map +1 -1
- package/dist/providers/client.js +19 -1
- package/dist/providers/client.js.map +1 -1
- package/dist/providers/definitions.d.ts +2 -0
- package/dist/providers/definitions.d.ts.map +1 -1
- package/dist/providers/definitions.js +3 -1
- package/dist/providers/definitions.js.map +1 -1
- package/dist/providers/interactive.d.ts +4 -0
- package/dist/providers/interactive.d.ts.map +1 -1
- package/dist/providers/interactive.js +86 -2
- package/dist/providers/interactive.js.map +1 -1
- package/dist/providers/oauth-client.d.ts +14 -0
- package/dist/providers/oauth-client.d.ts.map +1 -0
- package/dist/providers/oauth-client.js +52 -0
- package/dist/providers/oauth-client.js.map +1 -0
- package/dist/providers/openai-compatible-chat.d.ts +1 -0
- package/dist/providers/openai-compatible-chat.d.ts.map +1 -1
- package/dist/providers/openai-compatible-chat.js +1 -0
- package/dist/providers/openai-compatible-chat.js.map +1 -1
- package/dist/providers/openai.d.ts +3 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +72 -10
- package/dist/providers/openai.js.map +1 -1
- package/dist/remote/repl.d.ts.map +1 -1
- package/dist/remote/repl.js +9 -0
- package/dist/remote/repl.js.map +1 -1
- package/dist/repl.d.ts +42 -1
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +255 -12
- package/dist/repl.js.map +1 -1
- package/dist/session-store.d.ts +22 -1
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +80 -1
- package/dist/session-store.js.map +1 -1
- package/dist/session.d.ts +19 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +106 -4
- package/dist/session.js.map +1 -1
- package/dist/shell/approval.d.ts +2 -2
- package/dist/shell/approval.d.ts.map +1 -1
- package/dist/shell/approval.js +2 -2
- package/dist/shell/approval.js.map +1 -1
- package/dist/shell/docker.d.ts +2 -0
- package/dist/shell/docker.d.ts.map +1 -1
- package/dist/shell/docker.js +17 -3
- package/dist/shell/docker.js.map +1 -1
- package/dist/shell/factory.d.ts +9 -0
- package/dist/shell/factory.d.ts.map +1 -0
- package/dist/shell/factory.js +13 -0
- package/dist/shell/factory.js.map +1 -0
- package/dist/shell/local.d.ts +4 -0
- package/dist/shell/local.d.ts.map +1 -1
- package/dist/shell/local.js +16 -1
- package/dist/shell/local.js.map +1 -1
- package/dist/shell/native.d.ts +15 -0
- package/dist/shell/native.d.ts.map +1 -0
- package/dist/shell/native.js +99 -0
- package/dist/shell/native.js.map +1 -0
- package/dist/shell/types.d.ts +1 -0
- package/dist/shell/types.d.ts.map +1 -1
- package/dist/tools/bash.d.ts +19 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +30 -11
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +1 -1
- package/dist/tools/edit-file.js.map +1 -1
- package/dist/tools/parallel.d.ts +2 -0
- package/dist/tools/parallel.d.ts.map +1 -1
- package/dist/tools/parallel.js +8 -0
- package/dist/tools/parallel.js.map +1 -1
- package/dist/tools/write-file.d.ts.map +1 -1
- package/dist/tools/write-file.js +1 -1
- package/dist/tools/write-file.js.map +1 -1
- package/dist/transcript-hash.d.ts +4 -0
- package/dist/transcript-hash.d.ts.map +1 -0
- package/dist/transcript-hash.js +6 -0
- package/dist/transcript-hash.js.map +1 -0
- package/dist/tui/activity.d.ts +1 -1
- package/dist/tui/activity.d.ts.map +1 -1
- package/dist/tui/activity.js +2 -2
- package/dist/tui/activity.js.map +1 -1
- package/dist/tui/live.d.ts +2 -0
- package/dist/tui/live.d.ts.map +1 -1
- package/dist/tui/live.js +5 -0
- package/dist/tui/live.js.map +1 -1
- package/dist/workspace/paths.d.ts.map +1 -1
- package/dist/workspace/paths.js +4 -0
- package/dist/workspace/paths.js.map +1 -1
- package/dist/workspace/types.d.ts +2 -2
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/types.js.map +1 -1
- package/dist/workspace.d.ts +2 -2
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +2 -2
- package/dist/workspace.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { randomBytes, createHash, createPublicKey, verify as verifySignature } from "node:crypto";
|
|
3
|
+
import { mkdir, readFile, rename, chmod, writeFile, open, unlink } from "node:fs/promises";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
export function oauthFilePath(home = process.env.CHIVGENT_HOME) {
|
|
7
|
+
return path.join(home || path.join(os.homedir(), ".chivgent"), "oauth.json");
|
|
8
|
+
}
|
|
9
|
+
const fileLocks = new Map();
|
|
10
|
+
async function withFileLock(file, action) {
|
|
11
|
+
const previous = fileLocks.get(file) ?? Promise.resolve();
|
|
12
|
+
let release;
|
|
13
|
+
const next = new Promise((resolve) => { release = resolve; });
|
|
14
|
+
const queued = previous.then(() => next);
|
|
15
|
+
fileLocks.set(file, queued);
|
|
16
|
+
await previous;
|
|
17
|
+
let lockHandle;
|
|
18
|
+
try {
|
|
19
|
+
await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
20
|
+
const lockPath = `${file}.lock`;
|
|
21
|
+
const deadline = Date.now() + 30_000;
|
|
22
|
+
while (!lockHandle && Date.now() < deadline) {
|
|
23
|
+
try {
|
|
24
|
+
lockHandle = await open(lockPath, "wx", 0o600);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error.code !== "EEXIST")
|
|
28
|
+
throw error;
|
|
29
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!lockHandle)
|
|
33
|
+
throw new Error(`OAuth credentials are busy in another chivgent process (lock: ${lockPath}); retry shortly. If no process is using it, remove the stale lock file.`);
|
|
34
|
+
return await action();
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
if (lockHandle) {
|
|
38
|
+
await lockHandle.close();
|
|
39
|
+
await unlink(`${file}.lock`).catch(() => undefined);
|
|
40
|
+
}
|
|
41
|
+
release();
|
|
42
|
+
if (fileLocks.get(file) === queued)
|
|
43
|
+
fileLocks.delete(file);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export async function readOAuthCredentials(file = oauthFilePath()) {
|
|
47
|
+
try {
|
|
48
|
+
const text = await readFile(file, "utf8");
|
|
49
|
+
let parsed;
|
|
50
|
+
try {
|
|
51
|
+
parsed = JSON.parse(text);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
throw new Error(`The OAuth credential file at ${file} is not valid JSON.`);
|
|
55
|
+
}
|
|
56
|
+
if (!Array.isArray(parsed))
|
|
57
|
+
throw new Error("OAuth credential file must be an array.");
|
|
58
|
+
if (parsed.some((item) => !isCredential(item)))
|
|
59
|
+
throw new Error(`The OAuth credential file at ${file} contains an invalid record; refusing to ignore credentials silently.`);
|
|
60
|
+
return parsed;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (error.code === "ENOENT")
|
|
64
|
+
return [];
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export async function writeOAuthCredential(credential, file = oauthFilePath()) {
|
|
69
|
+
return withFileLock(file, async () => writeOAuthCredentialUnlocked(credential, file));
|
|
70
|
+
}
|
|
71
|
+
async function writeOAuthCredentialUnlocked(credential, file) {
|
|
72
|
+
const current = await readOAuthCredentials(file);
|
|
73
|
+
const next = current.filter((item) => item.provider !== credential.provider);
|
|
74
|
+
next.push(credential);
|
|
75
|
+
await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
76
|
+
const temp = `${file}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
77
|
+
await writeFile(temp, `${JSON.stringify(next, null, 2)}\n`, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
78
|
+
await chmod(temp, 0o600);
|
|
79
|
+
await rename(temp, file);
|
|
80
|
+
await chmod(file, 0o600);
|
|
81
|
+
}
|
|
82
|
+
export async function removeOAuthCredential(provider, file = oauthFilePath()) {
|
|
83
|
+
return withFileLock(file, async () => removeOAuthCredentialUnlocked(provider, file));
|
|
84
|
+
}
|
|
85
|
+
async function removeOAuthCredentialUnlocked(provider, file) {
|
|
86
|
+
const current = await readOAuthCredentials(file);
|
|
87
|
+
const next = current.filter((item) => item.provider !== provider);
|
|
88
|
+
await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
89
|
+
const temp = `${file}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
90
|
+
await writeFile(temp, `${JSON.stringify(next, null, 2)}\n`, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
91
|
+
await chmod(temp, 0o600);
|
|
92
|
+
await rename(temp, file);
|
|
93
|
+
await chmod(file, 0o600);
|
|
94
|
+
}
|
|
95
|
+
export async function refreshSavedOAuthCredential(provider, file = oauthFilePath(), fetcher = fetch, signal) {
|
|
96
|
+
signal?.throwIfAborted();
|
|
97
|
+
return withFileLock(file, async () => {
|
|
98
|
+
signal?.throwIfAborted();
|
|
99
|
+
const current = (await readOAuthCredentials(file)).find((item) => item.provider === provider);
|
|
100
|
+
if (!current)
|
|
101
|
+
return undefined;
|
|
102
|
+
if (current.expiresAt >= Date.now() + 60_000)
|
|
103
|
+
return current;
|
|
104
|
+
const refreshed = await refreshOAuthCredential(current, fetcher, signal);
|
|
105
|
+
const latest = (await readOAuthCredentials(file)).find((item) => item.provider === provider);
|
|
106
|
+
if (!latest || latest.refreshToken !== current.refreshToken || latest.clientId !== current.clientId)
|
|
107
|
+
throw new Error("OAuth session changed during refresh; sign in again.");
|
|
108
|
+
await writeOAuthCredentialUnlocked(refreshed, file);
|
|
109
|
+
return refreshed;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
export async function refreshOAuthCredential(credential, fetcher = fetch, signal) {
|
|
113
|
+
if (!credential.refreshToken)
|
|
114
|
+
throw new Error(`No refresh token is available for ${credential.provider}; sign in again.`);
|
|
115
|
+
const endpoint = credential.provider === "openai"
|
|
116
|
+
? "https://auth.openai.com/api/accounts/oauth/token"
|
|
117
|
+
: await getXaiTokenEndpoint(fetcher, signal);
|
|
118
|
+
const body = new URLSearchParams({ grant_type: "refresh_token", client_id: credential.clientId,
|
|
119
|
+
refresh_token: credential.refreshToken, ...(credential.provider === "openai" ? { resource: "https://api.openai.com/v1" } : {}) });
|
|
120
|
+
const response = await secureFetch(fetcher, signal)(endpoint, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" }, body });
|
|
121
|
+
const data = await safeJson(response, "OAuth refresh");
|
|
122
|
+
if (!response.ok || !data.access_token)
|
|
123
|
+
throw new Error(`OAuth refresh failed (${safeError(data.error)}); sign in again if the session was revoked.`);
|
|
124
|
+
validateTokenFields(data, credential.provider, false);
|
|
125
|
+
return { ...credential, accessToken: data.access_token, refreshToken: data.refresh_token ?? credential.refreshToken,
|
|
126
|
+
idToken: data.id_token ?? credential.idToken, expiresAt: Date.now() + (data.expires_in ?? 3600) * 1000,
|
|
127
|
+
scopes: data.scope?.split(" ").filter(Boolean) ?? credential.scopes };
|
|
128
|
+
}
|
|
129
|
+
async function getXaiTokenEndpoint(fetcher, signal) {
|
|
130
|
+
const response = await secureFetch(fetcher, signal)("https://auth.x.ai/.well-known/openid-configuration");
|
|
131
|
+
if (!response.ok)
|
|
132
|
+
throw new Error("Could not load xAI OAuth metadata for token refresh.");
|
|
133
|
+
const metadata = await safeJson(response, "xAI OAuth metadata");
|
|
134
|
+
if (metadata.issuer !== "https://auth.x.ai" || metadata.token_endpoint !== "https://auth.x.ai/oauth2/token")
|
|
135
|
+
throw new Error("xAI OAuth token endpoint failed metadata validation.");
|
|
136
|
+
return metadata.token_endpoint;
|
|
137
|
+
}
|
|
138
|
+
export async function revokeOAuthCredential(credential, fetcher = fetch) {
|
|
139
|
+
if (!credential.refreshToken)
|
|
140
|
+
return false;
|
|
141
|
+
try {
|
|
142
|
+
const safeFetch = secureFetch(fetcher);
|
|
143
|
+
const issuer = credential.provider === "openai" ? "https://auth.openai.com" : "https://auth.x.ai";
|
|
144
|
+
const discovery = await safeFetch(`${issuer}/.well-known/openid-configuration`);
|
|
145
|
+
if (!discovery.ok)
|
|
146
|
+
return false;
|
|
147
|
+
const metadata = await discovery.json();
|
|
148
|
+
if (!metadata.revocation_endpoint || new URL(metadata.revocation_endpoint).origin !== issuer)
|
|
149
|
+
return false;
|
|
150
|
+
const response = await safeFetch(metadata.revocation_endpoint, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ token: credential.refreshToken, token_type_hint: "refresh_token", client_id: credential.clientId }) });
|
|
151
|
+
return response.status === 200;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const SAFE_OAUTH_ERRORS = new Set(["access_denied", "authorization_pending", "slow_down", "expired_token", "invalid_grant", "invalid_client", "invalid_request", "server_error", "temporarily_unavailable"]);
|
|
158
|
+
function safeError(value) { return value && SAFE_OAUTH_ERRORS.has(value) ? value : "oauth_error"; }
|
|
159
|
+
async function safeJson(response, label) {
|
|
160
|
+
try {
|
|
161
|
+
const value = await response.json();
|
|
162
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
163
|
+
throw new Error();
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
throw new Error(`Could not parse ${label} response.`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function validateTokenFields(token, provider, requireOpenAIRenewal) {
|
|
171
|
+
if (typeof token.access_token !== "string" || !token.access_token.trim() ||
|
|
172
|
+
[token.refresh_token, token.id_token, token.scope].some(value => value !== undefined && typeof value !== "string")) {
|
|
173
|
+
throw new Error("OAuth returned invalid credential fields.");
|
|
174
|
+
}
|
|
175
|
+
if (token.token_type !== undefined && (typeof token.token_type !== "string" || token.token_type.toLowerCase() !== "bearer"))
|
|
176
|
+
throw new Error("OAuth returned an unsupported token type.");
|
|
177
|
+
if (token.expires_in !== undefined && (!Number.isFinite(token.expires_in) || token.expires_in <= 0))
|
|
178
|
+
throw new Error("OAuth returned an invalid token lifetime.");
|
|
179
|
+
if (requireOpenAIRenewal && (token.token_type?.toLowerCase() !== "bearer" || !Number.isFinite(token.expires_in) || (token.expires_in ?? 0) <= 0 || !token.refresh_token || !token.scope?.split(" ").includes("offline_access")))
|
|
180
|
+
throw new Error("OpenAI did not grant renewable offline access.");
|
|
181
|
+
}
|
|
182
|
+
function isCredential(value) {
|
|
183
|
+
if (!value || typeof value !== "object")
|
|
184
|
+
return false;
|
|
185
|
+
const v = value;
|
|
186
|
+
return v.type === "oauth" && (v.provider === "openai" || v.provider === "xai") &&
|
|
187
|
+
typeof v.clientId === "string" && v.clientId.length > 0 && typeof v.accessToken === "string" && v.accessToken.length > 0 &&
|
|
188
|
+
typeof v.expiresAt === "number" && Number.isFinite(v.expiresAt) &&
|
|
189
|
+
Array.isArray(v.scopes) && v.scopes.every(scope => typeof scope === "string") &&
|
|
190
|
+
[v.refreshToken, v.idToken, v.subject, v.email].every(value => value === undefined || typeof value === "string");
|
|
191
|
+
}
|
|
192
|
+
function b64url(bytes) { return bytes.toString("base64url"); }
|
|
193
|
+
function randomValue() { return b64url(randomBytes(32)); }
|
|
194
|
+
/** Current OpenAI OSS SIWC registration flow; callback remains loopback-only. */
|
|
195
|
+
export async function signInOpenAI(options) {
|
|
196
|
+
options.signal?.throwIfAborted();
|
|
197
|
+
const fetcher = secureFetch(options.fetch ?? fetch, options.signal);
|
|
198
|
+
const hostId = await getOrCreateHostId(options.file);
|
|
199
|
+
const previous = (await readOAuthCredentials(options.file)).find((item) => item.provider === "openai");
|
|
200
|
+
const state = randomValue(), nonce = randomValue(), verifier = randomValue();
|
|
201
|
+
const challenge = b64url(createHash("sha256").update(verifier).digest());
|
|
202
|
+
const callback = await (options.startCallback?.(state) ?? listenForCallback(state, options.signal));
|
|
203
|
+
const auth = new URL("https://auth.openai.com/api/accounts/authorize");
|
|
204
|
+
const authFields = { client_id: previous?.clientId ?? "dynamic_agent_client",
|
|
205
|
+
ext_agent_host_id: hostId, response_type: "code", redirect_uri: callback.redirectUri,
|
|
206
|
+
scope: "openid profile email offline_access resource.invoke chatgpt.tokens.use.direct",
|
|
207
|
+
resource: "https://api.openai.com/v1", state, nonce, code_challenge_method: "S256", code_challenge: challenge };
|
|
208
|
+
if (previous === undefined)
|
|
209
|
+
authFields.agent_name_hint = options.appName;
|
|
210
|
+
else {
|
|
211
|
+
if (previous.idToken)
|
|
212
|
+
authFields.id_token_hint = previous.idToken;
|
|
213
|
+
if (previous.email)
|
|
214
|
+
authFields.login_hint = previous.email;
|
|
215
|
+
}
|
|
216
|
+
for (const [k, v] of Object.entries(authFields))
|
|
217
|
+
auth.searchParams.set(k, v);
|
|
218
|
+
try {
|
|
219
|
+
if (options.openBrowser)
|
|
220
|
+
await options.openBrowser(auth.toString());
|
|
221
|
+
else
|
|
222
|
+
await openBrowser(auth.toString());
|
|
223
|
+
const result = await callback.result;
|
|
224
|
+
if (result.state !== state)
|
|
225
|
+
throw new Error("OAuth state validation failed.");
|
|
226
|
+
const clientId = result.client_id ?? previous?.clientId;
|
|
227
|
+
if (result.error)
|
|
228
|
+
throw new Error(result.error === "access_denied" ? "Sign-in was declined." : `OpenAI authorization failed (${safeError(result.error)}).`);
|
|
229
|
+
if (previous && result.client_id && result.client_id !== previous.clientId)
|
|
230
|
+
throw new Error("OpenAI returned a different client ID than the selected registration.");
|
|
231
|
+
if (!clientId?.startsWith("oaiapp_") || !result.code)
|
|
232
|
+
throw new Error("OpenAI registration did not return an issued client ID and authorization code.");
|
|
233
|
+
const response = await fetcher("https://auth.openai.com/api/accounts/oauth/token", { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" }, body: new URLSearchParams({ grant_type: "authorization_code", client_id: clientId, code: result.code, code_verifier: verifier, redirect_uri: callback.redirectUri, resource: "https://api.openai.com/v1" }) });
|
|
234
|
+
const token = await safeJson(response, "OpenAI token exchange");
|
|
235
|
+
if (!response.ok || !token.access_token || !token.id_token)
|
|
236
|
+
throw new Error(`OpenAI token exchange failed (${safeError(token.error)}).`);
|
|
237
|
+
validateTokenFields(token, "openai", true);
|
|
238
|
+
if (!token.scope?.split(" ").includes("resource.invoke") || !token.scope.split(" ").includes("chatgpt.tokens.use.direct"))
|
|
239
|
+
throw new Error("Required ChatGPT plan usage permissions were not granted.");
|
|
240
|
+
const identity = await verifyOpenAIIdToken(token.id_token, clientId, nonce, fetcher);
|
|
241
|
+
if (previous?.subject && previous.subject !== identity.sub)
|
|
242
|
+
throw new Error("OpenAI sign-in returned a different account than the selected registration.");
|
|
243
|
+
const credential = { type: "oauth", provider: "openai", clientId, accessToken: token.access_token,
|
|
244
|
+
...(token.refresh_token ? { refreshToken: token.refresh_token } : {}), idToken: token.id_token,
|
|
245
|
+
expiresAt: Date.now() + (token.expires_in ?? 3600) * 1000, scopes: token.scope.split(" "), subject: identity.sub,
|
|
246
|
+
...(typeof identity.email === "string" ? { email: identity.email } : {}) };
|
|
247
|
+
await writeOAuthCredential(credential, options.file);
|
|
248
|
+
return credential;
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
callback.close();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async function openBrowser(url) {
|
|
255
|
+
const { spawn } = await import("node:child_process");
|
|
256
|
+
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
257
|
+
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
258
|
+
await new Promise((resolve, reject) => {
|
|
259
|
+
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
260
|
+
child.once("error", reject);
|
|
261
|
+
child.once("spawn", () => { child.unref(); resolve(); });
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
async function listenForCallback(expectedState, signal) {
|
|
265
|
+
signal?.throwIfAborted();
|
|
266
|
+
let resolve, reject;
|
|
267
|
+
const result = new Promise((res, rej) => { resolve = res; reject = rej; });
|
|
268
|
+
const server = createServer((request, response) => {
|
|
269
|
+
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
270
|
+
if (url.pathname !== "/auth/callback") {
|
|
271
|
+
response.writeHead(404).end();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const state = url.searchParams.get("state") ?? undefined;
|
|
275
|
+
if (state !== expectedState) {
|
|
276
|
+
response.writeHead(400).end("Invalid OAuth state.");
|
|
277
|
+
reject(new Error("OAuth state validation failed."));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const value = { state, code: url.searchParams.get("code") ?? undefined, client_id: url.searchParams.get("client_id") ?? undefined, error: url.searchParams.get("error") ?? undefined };
|
|
281
|
+
response.writeHead(value.error ? 400 : 200, { "content-type": "text/plain" }).end(value.error === "access_denied" ? "Sign-in was declined. You may close this window." : "Sign-in received. You may close this window.");
|
|
282
|
+
if (value.error)
|
|
283
|
+
reject(new Error(value.error === "access_denied" ? "Sign-in was declined." : `OpenAI authorization failed (${safeError(value.error)}).`));
|
|
284
|
+
else
|
|
285
|
+
resolve(value);
|
|
286
|
+
});
|
|
287
|
+
const timer = setTimeout(() => reject(new Error("OpenAI sign-in timed out. Run /login oauth openai to try again.")), 5 * 60_000);
|
|
288
|
+
timer.unref();
|
|
289
|
+
const abort = () => reject(new Error("OpenAI sign-in was cancelled."));
|
|
290
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
291
|
+
await new Promise((resolve, reject) => { server.once("error", reject); server.listen(0, "127.0.0.1", resolve); });
|
|
292
|
+
const address = server.address();
|
|
293
|
+
if (!address || typeof address === "string")
|
|
294
|
+
throw new Error("Could not start the local OAuth callback listener.");
|
|
295
|
+
return { redirectUri: `http://127.0.0.1:${address.port}/auth/callback`, result, close: () => { clearTimeout(timer); signal?.removeEventListener("abort", abort); server.close(); } };
|
|
296
|
+
}
|
|
297
|
+
async function getOrCreateHostId(file) {
|
|
298
|
+
const target = file ?? oauthFilePath();
|
|
299
|
+
const hostFile = path.join(path.dirname(target), "oauth-host-id");
|
|
300
|
+
try {
|
|
301
|
+
return (await readFile(hostFile, "utf8")).trim();
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
if (error.code !== "ENOENT")
|
|
305
|
+
throw error;
|
|
306
|
+
const id = `urn:uuid:${crypto.randomUUID()}`;
|
|
307
|
+
await mkdir(path.dirname(hostFile), { recursive: true, mode: 0o700 });
|
|
308
|
+
await writeFile(hostFile, `${id}\n`, { mode: 0o600, flag: "wx" });
|
|
309
|
+
return id;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async function verifyOpenAIIdToken(token, audience, nonce, fetcher) {
|
|
313
|
+
const [head, payload, signature] = token.split(".");
|
|
314
|
+
if (!head || !payload || !signature || token.split(".").length !== 3)
|
|
315
|
+
throw new Error("OpenAI returned a malformed ID token.");
|
|
316
|
+
let header;
|
|
317
|
+
try {
|
|
318
|
+
header = JSON.parse(Buffer.from(head, "base64url").toString());
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
throw new Error("OpenAI returned a malformed ID token.");
|
|
322
|
+
}
|
|
323
|
+
let claims;
|
|
324
|
+
try {
|
|
325
|
+
claims = JSON.parse(Buffer.from(payload, "base64url").toString());
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
throw new Error("OpenAI returned a malformed ID token.");
|
|
329
|
+
}
|
|
330
|
+
if (header.alg !== "RS256" || typeof header.kid !== "string")
|
|
331
|
+
throw new Error("OpenAI ID token uses an unsupported signing key.");
|
|
332
|
+
const discoveryResponse = await fetcher("https://auth.openai.com/.well-known/openid-configuration");
|
|
333
|
+
if (!discoveryResponse.ok)
|
|
334
|
+
throw new Error("Could not load OpenAI identity metadata.");
|
|
335
|
+
const discovery = await safeJson(discoveryResponse, "OpenAI identity metadata");
|
|
336
|
+
if (discovery.issuer !== "https://auth.openai.com" || !discovery.jwks_uri || new URL(discovery.jwks_uri).origin !== "https://auth.openai.com")
|
|
337
|
+
throw new Error("OpenAI identity metadata failed validation.");
|
|
338
|
+
const jwksResponse = await fetcher(discovery.jwks_uri);
|
|
339
|
+
if (!jwksResponse.ok)
|
|
340
|
+
throw new Error("Could not verify OpenAI ID token signing key.");
|
|
341
|
+
const jwks = await safeJson(jwksResponse, "OpenAI signing keys");
|
|
342
|
+
const jwk = jwks.keys?.find((key) => key.kid === header.kid);
|
|
343
|
+
if (!jwk)
|
|
344
|
+
throw new Error("OpenAI ID token signing key was not found.");
|
|
345
|
+
let valid = false;
|
|
346
|
+
try {
|
|
347
|
+
const key = createPublicKey({ key: jwk, format: "jwk" });
|
|
348
|
+
valid = verifySignature("RSA-SHA256", Buffer.from(`${head}.${payload}`), key, Buffer.from(signature, "base64url"));
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
throw new Error("OpenAI ID token signature validation failed.");
|
|
352
|
+
}
|
|
353
|
+
const aud = claims.aud;
|
|
354
|
+
if (!valid || claims.iss !== discovery.issuer || !(aud === audience || (Array.isArray(aud) && aud.includes(audience) && claims.azp === audience)) || claims.nonce !== nonce || typeof claims.exp !== "number" || claims.exp <= Date.now() / 1000 || (typeof claims.nbf === "number" && claims.nbf > Date.now() / 1000) || typeof claims.sub !== "string")
|
|
355
|
+
throw new Error("OpenAI ID token validation failed.");
|
|
356
|
+
return claims;
|
|
357
|
+
}
|
|
358
|
+
/** xAI RFC 8628 device login; endpoints/scopes currently follow public grok-cli OAuth metadata. */
|
|
359
|
+
export async function signInXAI(options) {
|
|
360
|
+
options.signal?.throwIfAborted();
|
|
361
|
+
const fetcher = secureFetch(options.fetch ?? fetch, options.signal);
|
|
362
|
+
const clientId = "b1a00492-073a-47ea-816f-4c329264a828";
|
|
363
|
+
const discoveryResponse = await fetcher("https://auth.x.ai/.well-known/openid-configuration");
|
|
364
|
+
if (!discoveryResponse.ok)
|
|
365
|
+
throw new Error("Could not load xAI OAuth metadata.");
|
|
366
|
+
const discovery = await safeJson(discoveryResponse, "xAI OAuth metadata");
|
|
367
|
+
const tokenEndpoint = "https://auth.x.ai/oauth2/token";
|
|
368
|
+
const deviceEndpoint = "https://auth.x.ai/oauth2/device/code";
|
|
369
|
+
if (discovery.issuer !== "https://auth.x.ai" || discovery.token_endpoint !== tokenEndpoint || discovery.device_authorization_endpoint !== deviceEndpoint || !discovery.grant_types_supported?.includes("urn:ietf:params:oauth:grant-type:device_code") || !discovery.scopes_supported?.includes("api:access") || !discovery.scopes_supported.includes("offline_access"))
|
|
370
|
+
throw new Error("xAI OAuth metadata does not advertise the expected device-code flow and scopes.");
|
|
371
|
+
const response = await fetcher(discovery.device_authorization_endpoint, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" }, body: new URLSearchParams({ client_id: clientId, scope: "openid profile email offline_access grok-cli:access api:access", referrer: "chivgent" }) });
|
|
372
|
+
const device = await safeJson(response, "xAI device authorization");
|
|
373
|
+
if (!response.ok || !device.device_code || !device.user_code || !device.verification_uri)
|
|
374
|
+
throw new Error(`xAI device authorization failed (${safeError(device.error)}).`);
|
|
375
|
+
const verification = new URL(device.verification_uri);
|
|
376
|
+
if (verification.protocol !== "https:" || !["x.ai", "auth.x.ai"].includes(verification.hostname) || verification.username || verification.password || /[\u0000-\u001f\u007f]/.test(device.verification_uri))
|
|
377
|
+
throw new Error("xAI returned an unexpected device verification URL.");
|
|
378
|
+
options.write(`Open ${device.verification_uri} and enter code ${device.user_code}\n`);
|
|
379
|
+
const expires = Date.now() + (device.expires_in ?? 900) * 1000;
|
|
380
|
+
let interval = device.interval ?? 5;
|
|
381
|
+
const delay = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
382
|
+
while (Date.now() < expires) {
|
|
383
|
+
if (options.signal?.aborted)
|
|
384
|
+
throw new Error("xAI sign-in was cancelled.");
|
|
385
|
+
await abortableDelay(interval * 1000, delay, options.signal);
|
|
386
|
+
const polled = await fetcher(discovery.token_endpoint, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" }, body: new URLSearchParams({ grant_type: "urn:ietf:params:oauth:grant-type:device_code", client_id: clientId, device_code: device.device_code }) });
|
|
387
|
+
const token = await safeJson(polled, "xAI token polling");
|
|
388
|
+
if (polled.ok && token.access_token) {
|
|
389
|
+
validateTokenFields(token, "xai", false);
|
|
390
|
+
const granted = token.scope?.split(" ") ?? [];
|
|
391
|
+
if (!token.refresh_token || (!granted.includes("api:access") && !granted.includes("grok-cli:access")))
|
|
392
|
+
throw new Error("xAI did not grant renewable Grok API access.");
|
|
393
|
+
const credential = { type: "oauth", provider: "xai", clientId, accessToken: token.access_token, ...(token.refresh_token ? { refreshToken: token.refresh_token } : {}), expiresAt: Date.now() + (token.expires_in ?? 3600) * 1000, scopes: token.scope?.split(" ") ?? [] };
|
|
394
|
+
await writeOAuthCredential(credential, options.file);
|
|
395
|
+
return credential;
|
|
396
|
+
}
|
|
397
|
+
if (token.error === "authorization_pending")
|
|
398
|
+
continue;
|
|
399
|
+
if (token.error === "slow_down") {
|
|
400
|
+
interval += 5;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (token.error === "access_denied")
|
|
404
|
+
throw new Error("xAI sign-in was declined.");
|
|
405
|
+
if (token.error === "expired_token")
|
|
406
|
+
throw new Error("xAI device code expired. Run /login xai again.");
|
|
407
|
+
if (!polled.ok)
|
|
408
|
+
throw new Error(`xAI token polling failed (${safeError(token.error)}).`);
|
|
409
|
+
}
|
|
410
|
+
throw new Error("xAI device code expired. Run /login xai again.");
|
|
411
|
+
}
|
|
412
|
+
async function abortableDelay(ms, delay, signal) {
|
|
413
|
+
if (!signal)
|
|
414
|
+
return delay(ms);
|
|
415
|
+
if (signal.aborted)
|
|
416
|
+
throw new Error("xAI sign-in was cancelled.");
|
|
417
|
+
let cancel;
|
|
418
|
+
const aborted = new Promise((_, reject) => { cancel = () => reject(new Error("xAI sign-in was cancelled.")); signal.addEventListener("abort", cancel, { once: true }); });
|
|
419
|
+
try {
|
|
420
|
+
await Promise.race([delay(ms), aborted]);
|
|
421
|
+
}
|
|
422
|
+
finally {
|
|
423
|
+
signal.removeEventListener("abort", cancel);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
function secureFetch(fetcher, outerSignal) {
|
|
427
|
+
return (input, init = {}) => fetcher(input, { ...init, redirect: "error", signal: AbortSignal.any([...(init.signal ? [init.signal] : []), ...(outerSignal ? [outerSignal] : []), AbortSignal.timeout(15_000)]) });
|
|
428
|
+
}
|
|
429
|
+
/** OAuth bearer tokens may only reach their provider API; reject redirects too. */
|
|
430
|
+
export function oauthApiFetch(expectedOrigin) {
|
|
431
|
+
return (input, init = {}) => {
|
|
432
|
+
let url;
|
|
433
|
+
try {
|
|
434
|
+
url = new URL(input instanceof Request ? input.url : input instanceof URL ? input.toString() : String(input));
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
throw new Error("OAuth API request had an invalid URL.");
|
|
438
|
+
}
|
|
439
|
+
if (url.origin !== expectedOrigin)
|
|
440
|
+
throw new Error("OAuth API request target failed origin validation.");
|
|
441
|
+
return fetch(input, { ...init, redirect: "error" });
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/cli-options.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare const VERSION: string;
|
|
2
2
|
import { ProviderRegistry } from "./providers/registry.js";
|
|
3
|
+
import type { ShellBackend } from "./shell/factory.js";
|
|
4
|
+
import { type PermissionMode } from "./permissions.js";
|
|
3
5
|
/** A Provider id known to the registry. */
|
|
4
6
|
export type Provider = string;
|
|
5
7
|
export declare const DEFAULT_MAX_TURNS = 8;
|
|
@@ -34,13 +36,14 @@ export interface CliOptions {
|
|
|
34
36
|
readonly listSessions: boolean;
|
|
35
37
|
/** Allow the agent to create and modify files in the workspace. */
|
|
36
38
|
readonly allowWrites: boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Allow the agent to run shell commands. This implies write access: a shell
|
|
39
|
-
* can do everything the write tools can and is not bound by the workspace.
|
|
40
|
-
*/
|
|
39
|
+
/** Allow the agent to run shell commands inside the selected sandbox. */
|
|
41
40
|
readonly allowShell: boolean;
|
|
42
|
-
/** Explicitly approve every command in this session;
|
|
41
|
+
/** Explicitly approve every command in this session; sandbox isolation still applies. */
|
|
43
42
|
readonly approveAllShell: boolean;
|
|
43
|
+
readonly shellBackend: ShellBackend;
|
|
44
|
+
readonly shellNetwork: boolean;
|
|
45
|
+
/** Explicit policy for tool approval boundaries; absent preserves legacy flags. */
|
|
46
|
+
readonly permissionMode?: PermissionMode;
|
|
44
47
|
/** Draw a live status region above the prompt. Interactive terminals only. */
|
|
45
48
|
readonly tui: boolean;
|
|
46
49
|
/** Load extensions from the user and (once trusted) the project directory. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-options.d.ts","sourceRoot":"","sources":["../src/cli-options.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,QAC6D,CAAC;AAElF,OAAO,EAEL,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-options.d.ts","sourceRoot":"","sources":["../src/cli-options.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,QAC6D,CAAC;AAElF,OAAO,EAEL,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE5E,2CAA2C;AAC3C,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAI1C;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC;AAE/C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,mFAAmF;IACnF,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,EAAE,cAAc,EAC3B,QAAQ,GAAE,gBAA0C,GACnD,UAAU,CAkLZ;AAED,wBAAgB,QAAQ,CACtB,QAAQ,GAAE,gBAA0C,GACnD,MAAM,CA8DR"}
|
package/dist/cli-options.js
CHANGED
|
@@ -4,6 +4,7 @@ const packageMetadata = require("../package.json");
|
|
|
4
4
|
export const VERSION = typeof packageMetadata.version === "string" ? packageMetadata.version : "0.0.0";
|
|
5
5
|
import { defaultProviderRegistry, ProviderRegistry, } from "./providers/registry.js";
|
|
6
6
|
import { DEFAULT_CONTEXT_WINDOW } from "./context/context-manager.js";
|
|
7
|
+
import { parsePermissionMode } from "./permissions.js";
|
|
7
8
|
export const DEFAULT_MAX_TURNS = 8;
|
|
8
9
|
/**
|
|
9
10
|
* Editing costs turns that reading does not: the model reads, edits, then
|
|
@@ -30,6 +31,9 @@ export function parseCliArgs(argv, environment, registry = defaultProviderRegist
|
|
|
30
31
|
let allowWrites = false;
|
|
31
32
|
let allowShell = false;
|
|
32
33
|
let approveAllShell = false;
|
|
34
|
+
let shellBackend = "auto";
|
|
35
|
+
let shellNetwork = false;
|
|
36
|
+
let permissionMode;
|
|
33
37
|
let tui = false;
|
|
34
38
|
let extensions = true;
|
|
35
39
|
let serve = false;
|
|
@@ -107,6 +111,20 @@ export function parseCliArgs(argv, environment, registry = defaultProviderRegist
|
|
|
107
111
|
else if (argument === "--approve-all-shell") {
|
|
108
112
|
approveAllShell = true;
|
|
109
113
|
}
|
|
114
|
+
else if (argument === "--shell-backend") {
|
|
115
|
+
const value = readOptionValue(argv, index, "--shell-backend");
|
|
116
|
+
if (value !== "auto" && value !== "native" && value !== "docker")
|
|
117
|
+
throw new TypeError("--shell-backend must be auto, native, or docker.");
|
|
118
|
+
shellBackend = value;
|
|
119
|
+
index += 1;
|
|
120
|
+
}
|
|
121
|
+
else if (argument === "--shell-network") {
|
|
122
|
+
shellNetwork = true;
|
|
123
|
+
}
|
|
124
|
+
else if (argument === "--permission-mode") {
|
|
125
|
+
permissionMode = parsePermissionMode(readOptionValue(argv, index, "--permission-mode"));
|
|
126
|
+
index += 1;
|
|
127
|
+
}
|
|
110
128
|
else if (argument === "--serve") {
|
|
111
129
|
serve = true;
|
|
112
130
|
}
|
|
@@ -147,6 +165,15 @@ export function parseCliArgs(argv, environment, registry = defaultProviderRegist
|
|
|
147
165
|
if (approveAllShell && !allowShell) {
|
|
148
166
|
throw new TypeError("--approve-all-shell requires --allow-shell.");
|
|
149
167
|
}
|
|
168
|
+
if (permissionMode !== undefined && (allowWrites || allowShell || approveAllShell || shellNetwork)) {
|
|
169
|
+
throw new TypeError("--permission-mode cannot be combined with --allow-writes, --allow-shell, --approve-all-shell, or --shell-network; select the complete policy mode instead.");
|
|
170
|
+
}
|
|
171
|
+
if (permissionMode !== undefined && connect !== undefined) {
|
|
172
|
+
throw new TypeError("--permission-mode applies to local sessions and cannot be used with --connect.");
|
|
173
|
+
}
|
|
174
|
+
if (permissionMode !== undefined && serve) {
|
|
175
|
+
throw new TypeError("--permission-mode cannot be used with --serve because served sessions do not have an interactive approval channel.");
|
|
176
|
+
}
|
|
150
177
|
const definition = registry.get(provider);
|
|
151
178
|
const model = requestedModel ||
|
|
152
179
|
firstEnvironmentValue(environment, definition.modelEnvKeys) ||
|
|
@@ -158,7 +185,7 @@ export function parseCliArgs(argv, environment, registry = defaultProviderRegist
|
|
|
158
185
|
provider,
|
|
159
186
|
...(model === undefined ? {} : { model }),
|
|
160
187
|
...(baseURL === undefined ? {} : { baseURL }),
|
|
161
|
-
maxTurns: (allowWrites || allowShell) && !maxTurnsExplicit
|
|
188
|
+
maxTurns: (allowWrites || allowShell || permissionMode !== undefined) && !maxTurnsExplicit
|
|
162
189
|
? DEFAULT_WRITE_MAX_TURNS
|
|
163
190
|
: maxTurns,
|
|
164
191
|
stream,
|
|
@@ -171,6 +198,9 @@ export function parseCliArgs(argv, environment, registry = defaultProviderRegist
|
|
|
171
198
|
allowWrites,
|
|
172
199
|
allowShell,
|
|
173
200
|
approveAllShell,
|
|
201
|
+
shellBackend,
|
|
202
|
+
shellNetwork,
|
|
203
|
+
...(permissionMode === undefined ? {} : { permissionMode }),
|
|
174
204
|
tui,
|
|
175
205
|
extensions,
|
|
176
206
|
serve,
|
|
@@ -206,9 +236,12 @@ Options:
|
|
|
206
236
|
--resume ID Resume a specific session
|
|
207
237
|
--sessions List recorded sessions and exit
|
|
208
238
|
--allow-writes Let the agent create and change files (default: read-only)
|
|
209
|
-
--allow-shell Expose bash inside
|
|
239
|
+
--allow-shell Expose bash inside a native macOS sandbox or Docker (network denied).
|
|
210
240
|
Interactive commands require individual confirmation.
|
|
211
|
-
--
|
|
241
|
+
--shell-backend MODE auto, native, or docker (default: auto; macOS uses native).
|
|
242
|
+
--shell-network Allow shell network access (explicit opt-in for either backend).
|
|
243
|
+
--permission-mode MODE ask-first, workspace, or unrestricted (network enabled).
|
|
244
|
+
--approve-all-shell Explicitly approve all shell commands this session;
|
|
212
245
|
use only with --allow-shell when individual prompts are unavailable.
|
|
213
246
|
--serve Expose this session on a local socket and keep running
|
|
214
247
|
--connect TARGET Attach to a served session, by id or socket path
|