agent-yes 1.246.5 → 1.247.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/SUPPORTED_CLIS-B1DPQLRV.js +11 -0
- package/dist/{SUPPORTED_CLIS-ia9b-P1k.js → SUPPORTED_CLIS-DUALQTec.js} +2 -2
- package/dist/{agentShare-BazKWNQQ.js → agentShare-Clx5QcyE.js} +2 -2
- package/dist/{callback-Csr8_-FG.js → callback-BPAlieXe.js} +2 -2
- package/dist/{callback-DyyjF-fr.js → callback-DPd9PJQA.js} +3 -3
- package/dist/cli.js +7 -7
- package/dist/index.js +3 -3
- package/dist/{notifyDaemon-DDPfMGlw.js → notifyDaemon-CAML5u0d.js} +2 -2
- package/dist/{pidStore-bCVS2Ldt.js → pidStore-Bg7wdjxY.js} +1 -1
- package/dist/{pidStore-6EZd5DUv.js → pidStore-vnX0bgra.js} +5 -3
- package/dist/{rustBinary-DuwxRidk.js → rustBinary-BU3E3uMi.js} +2 -2
- package/dist/{schedule-CWBHxQxk.js → schedule-C8wzhq0y.js} +6 -6
- package/dist/{serve-DyZpvp4C.js → serve-D_DP0VBy.js} +28 -19
- package/dist/{setup-JqletyDD.js → setup-DIa8Y-lx.js} +3 -3
- package/dist/{spawnGate-BxgS_GlF.js → spawnGate-BFJPdHCQ.js} +2 -2
- package/dist/{spawnGate-Dc3odVqo.js → spawnGate-Djr4KlF5.js} +1 -1
- package/dist/{subcommands-BL_SWFDC.js → subcommands-DeHlaNOY.js} +12 -12
- package/dist/{subcommands-CdWAGc4C.js → subcommands-WJz-UHyC.js} +1 -1
- package/dist/{terminal-BFq0mWdQ.js → terminal-MnictO_E.js} +2 -2
- package/dist/{ts-B51ZLoJC.js → ts-rCPxI3aR.js} +54 -5
- package/dist/{versionChecker-D5ir842c.js → versionChecker-Du1qdZR9.js} +2 -2
- package/dist/{widget-BXlREJHQ.js → widget-U6HkHQcz.js} +3 -3
- package/dist/{workspaceConfig-DOHygA2x.js → workspaceConfig-CpilQzMY.js} +24 -2
- package/dist/{ws-C6gfqPHM.js → ws-1vGWz9c9.js} +3 -3
- package/package.json +1 -1
- package/ts/agentPermissions.spec.ts +117 -0
- package/ts/agentPermissions.ts +80 -0
- package/ts/globalPidIndex.ts +8 -0
- package/ts/index.ts +10 -0
- package/ts/pidStore.ts +7 -0
- package/ts/serve.ts +47 -1
- package/ts/workspaceConfig.ts +30 -0
- package/dist/SUPPORTED_CLIS-D3b_1q8z.js +0 -11
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "./logger-CDIsZ-Pp.js";
|
|
2
|
+
import "./versionChecker-Du1qdZR9.js";
|
|
3
|
+
import "./ts-rCPxI3aR.js";
|
|
4
|
+
import "./todoAutomation-Buo457VO.js";
|
|
5
|
+
import "./JsonlStore-CPGIR0Wy.js";
|
|
6
|
+
import "./globalPidIndex-D9DOSd-c.js";
|
|
7
|
+
import "./pidStore-vnX0bgra.js";
|
|
8
|
+
import "./messageLog-C-YIzhRj.js";
|
|
9
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DUALQTec.js";
|
|
10
|
+
|
|
11
|
+
export { SUPPORTED_CLIS };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-rCPxI3aR.js";
|
|
2
2
|
|
|
3
3
|
//#region ts/SUPPORTED_CLIS.ts
|
|
4
4
|
const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
5
5
|
|
|
6
6
|
//#endregion
|
|
7
7
|
export { SUPPORTED_CLIS as t };
|
|
8
|
-
//# sourceMappingURL=SUPPORTED_CLIS-
|
|
8
|
+
//# sourceMappingURL=SUPPORTED_CLIS-DUALQTec.js.map
|
|
@@ -3,7 +3,7 @@ import "./globalPidIndex-D9DOSd-c.js";
|
|
|
3
3
|
import "./messageLog-C-YIzhRj.js";
|
|
4
4
|
import "./e2e-CEIdJGZ7.js";
|
|
5
5
|
import "./configShared-IBbnn9b8.js";
|
|
6
|
-
import { P as resolveOne } from "./subcommands-
|
|
6
|
+
import { P as resolveOne } from "./subcommands-DeHlaNOY.js";
|
|
7
7
|
import "./webrtcLink-BMYneHbu.js";
|
|
8
8
|
import "./remotes-BxQnNxQv.js";
|
|
9
9
|
import { a as startShare } from "./share-BGl3wutJ.js";
|
|
@@ -229,4 +229,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
|
|
|
229
229
|
|
|
230
230
|
//#endregion
|
|
231
231
|
export { createScopedShare, listShares, revokeAllShares, revokeShare };
|
|
232
|
-
//# sourceMappingURL=agentShare-
|
|
232
|
+
//# sourceMappingURL=agentShare-Clx5QcyE.js.map
|
|
@@ -3,10 +3,10 @@ import "./globalPidIndex-D9DOSd-c.js";
|
|
|
3
3
|
import "./messageLog-C-YIzhRj.js";
|
|
4
4
|
import "./e2e-CEIdJGZ7.js";
|
|
5
5
|
import "./configShared-IBbnn9b8.js";
|
|
6
|
-
import "./subcommands-
|
|
6
|
+
import "./subcommands-DeHlaNOY.js";
|
|
7
7
|
import "./webrtcLink-BMYneHbu.js";
|
|
8
8
|
import "./remotes-BxQnNxQv.js";
|
|
9
9
|
import "./callbackCore-Dd28_cBM.js";
|
|
10
|
-
import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-
|
|
10
|
+
import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-DPd9PJQA.js";
|
|
11
11
|
|
|
12
12
|
export { cmdCallback };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
|
|
2
|
-
import { P as resolveOne } from "./subcommands-
|
|
2
|
+
import { P as resolveOne } from "./subcommands-DeHlaNOY.js";
|
|
3
3
|
import { a as mintCapability, o as parseExpires } from "./callbackCore-Dd28_cBM.js";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { chmodSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
@@ -72,7 +72,7 @@ async function resolveBase(flag) {
|
|
|
72
72
|
if (flag) return flag;
|
|
73
73
|
if (process.env.AGENT_YES_CALLBACK_BASE) return process.env.AGENT_YES_CALLBACK_BASE;
|
|
74
74
|
try {
|
|
75
|
-
const { resolveLocalServeUrl } = await import("./serve-
|
|
75
|
+
const { resolveLocalServeUrl } = await import("./serve-D_DP0VBy.js");
|
|
76
76
|
const url = await resolveLocalServeUrl();
|
|
77
77
|
if (url) return url;
|
|
78
78
|
} catch {}
|
|
@@ -187,4 +187,4 @@ async function cmdCallback(rest) {
|
|
|
187
187
|
|
|
188
188
|
//#endregion
|
|
189
189
|
export { loadOrCreateCallbackSecret as i, isCallbackRevoked as n, loadCallbackSecretReadOnly as r, cmdCallback as t };
|
|
190
|
-
//# sourceMappingURL=callback-
|
|
190
|
+
//# sourceMappingURL=callback-DPd9PJQA.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { t as invokedCliName } from "./invokedCli-uqM2YYA7.js";
|
|
3
3
|
import { n as logger } from "./logger-CDIsZ-Pp.js";
|
|
4
|
-
import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-
|
|
5
|
-
import { n as getRustBinary } from "./rustBinary-
|
|
4
|
+
import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-Du1qdZR9.js";
|
|
5
|
+
import { n as getRustBinary } from "./rustBinary-BU3E3uMi.js";
|
|
6
6
|
import { argv } from "process";
|
|
7
7
|
import { spawn } from "child_process";
|
|
8
8
|
import ms from "ms";
|
|
@@ -285,7 +285,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
285
285
|
const rawArg = process.argv[2];
|
|
286
286
|
const managerCommands = !invokedCliName(process.argv);
|
|
287
287
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
288
|
-
const { isSubcommand, runSubcommand, cmdHelp, isUnknownManagerToken } = await import("./subcommands-
|
|
288
|
+
const { isSubcommand, runSubcommand, cmdHelp, isUnknownManagerToken } = await import("./subcommands-WJz-UHyC.js");
|
|
289
289
|
if (isHelpFlag && process.argv.length === 3) {
|
|
290
290
|
await cmdHelp(managerCommands);
|
|
291
291
|
process.exit(0);
|
|
@@ -295,7 +295,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
295
295
|
process.exit(code ?? 0);
|
|
296
296
|
}
|
|
297
297
|
{
|
|
298
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
298
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-B1DPQLRV.js");
|
|
299
299
|
if (isUnknownManagerToken(rawArg, managerCommands, SUPPORTED_CLIS)) {
|
|
300
300
|
process.stderr.write(`ay: unknown subcommand or CLI '${rawArg}'.\n See 'ay help' for subcommands. To run an agent, name a CLI:\n 'ay <cli> …' (e.g. 'ay claude …') or 'ay --cli <cli> …'.\n`);
|
|
301
301
|
process.exit(1);
|
|
@@ -323,7 +323,7 @@ if (config.tray) {
|
|
|
323
323
|
ensureTray();
|
|
324
324
|
}
|
|
325
325
|
if (!config.showVersion && !config.appendPrompt && !config.tray) {
|
|
326
|
-
const { waitForSpawnCapacity } = await import("./spawnGate-
|
|
326
|
+
const { waitForSpawnCapacity } = await import("./spawnGate-Djr4KlF5.js");
|
|
327
327
|
await waitForSpawnCapacity({
|
|
328
328
|
onWait: (reason, waitedMs) => {
|
|
329
329
|
if (config.verbose || waitedMs === 0) console.error(`[agent-yes] spawn gate: ${reason} — waiting…`);
|
|
@@ -346,7 +346,7 @@ if (config.useRust) {
|
|
|
346
346
|
}
|
|
347
347
|
}
|
|
348
348
|
if (rustBinary) {
|
|
349
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
349
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-B1DPQLRV.js");
|
|
350
350
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
351
351
|
if (config.verbose) {
|
|
352
352
|
console.log(`[rust] Using binary: ${rustBinary}`);
|
|
@@ -411,7 +411,7 @@ if (config.showVersion) {
|
|
|
411
411
|
process.exit(0);
|
|
412
412
|
}
|
|
413
413
|
if (config.appendPrompt) {
|
|
414
|
-
const { PidStore } = await import("./pidStore-
|
|
414
|
+
const { PidStore } = await import("./pidStore-Bg7wdjxY.js");
|
|
415
415
|
const ipcPath = await PidStore.findActiveFifo(process.cwd());
|
|
416
416
|
if (!ipcPath) {
|
|
417
417
|
console.error("No active agent with IPC found in current directory.");
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import "./versionChecker-
|
|
3
|
-
import { a as hasTodoStore,
|
|
2
|
+
import "./versionChecker-Du1qdZR9.js";
|
|
3
|
+
import { a as hasTodoStore, i as answerAsk, l as AgentContext, n as agentYes, o as listAsks, r as config, s as listAsksForProject, t as CLIS_CONFIG } from "./ts-rCPxI3aR.js";
|
|
4
4
|
import { _ as isKnownKind, a as renderTree, b as statesOf, c as monitorHint, d as openStore, f as DONE_STATE, g as initialState, h as canTransition, i as renderDigest, l as CycleError, m as ORPHANED_STATE, o as unblockedTasks, p as LIFECYCLES, r as openBlockers, s as describeBlock, t as reconcileTodos, u as TodoStore, v as nextStates, x as removeControlCharacters, y as requiredGate } from "./todoAutomation-Buo457VO.js";
|
|
5
5
|
import "./JsonlStore-CPGIR0Wy.js";
|
|
6
6
|
import "./globalPidIndex-D9DOSd-c.js";
|
|
7
|
-
import "./pidStore-
|
|
7
|
+
import "./pidStore-vnX0bgra.js";
|
|
8
8
|
import "./messageLog-C-YIzhRj.js";
|
|
9
9
|
|
|
10
10
|
export { AgentContext, CLIS_CONFIG, CycleError, DONE_STATE, LIFECYCLES, ORPHANED_STATE, TodoStore, answerAsk, canTransition, config, agentYes as default, describeBlock, hasTodoStore, initialState, isKnownKind, listAsks, listAsksForProject, monitorHint, nextStates, openBlockers, openStore, reconcileTodos, removeControlCharacters, renderDigest, renderTree, requiredGate, statesOf, unblockedTasks };
|
|
@@ -3,7 +3,7 @@ import "./globalPidIndex-D9DOSd-c.js";
|
|
|
3
3
|
import "./messageLog-C-YIzhRj.js";
|
|
4
4
|
import "./e2e-CEIdJGZ7.js";
|
|
5
5
|
import "./configShared-IBbnn9b8.js";
|
|
6
|
-
import { $ as shouldStealLock, C as listRecords, J as hostId, K as appendEvent, Q as readInbox, X as listInboxParents, Z as liveWatchers, _ as isPidAlive, c as deriveLiveState, et as daemonLockDir, j as renderLogTailLines, nt as notifyDir, q as gcInboxes, tt as daemonLockOwnerPath } from "./subcommands-
|
|
6
|
+
import { $ as shouldStealLock, C as listRecords, J as hostId, K as appendEvent, Q as readInbox, X as listInboxParents, Z as liveWatchers, _ as isPidAlive, c as deriveLiveState, et as daemonLockDir, j as renderLogTailLines, nt as notifyDir, q as gcInboxes, tt as daemonLockOwnerPath } from "./subcommands-DeHlaNOY.js";
|
|
7
7
|
import "./webrtcLink-BMYneHbu.js";
|
|
8
8
|
import "./remotes-BxQnNxQv.js";
|
|
9
9
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "fs/promises";
|
|
@@ -589,4 +589,4 @@ async function ensureDaemon() {
|
|
|
589
589
|
|
|
590
590
|
//#endregion
|
|
591
591
|
export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
|
|
592
|
-
//# sourceMappingURL=notifyDaemon-
|
|
592
|
+
//# sourceMappingURL=notifyDaemon-CAML5u0d.js.map
|
|
@@ -24,7 +24,7 @@ var PidStore = class PidStore {
|
|
|
24
24
|
logger.warn("[pidStore] Failed to initialize:", error);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
async registerProcess({ pid, cli, args, prompt, cwd, wrapperPid, parentPid }) {
|
|
27
|
+
async registerProcess({ pid, cli, args, prompt, cwd, wrapperPid, parentPid, permissions }) {
|
|
28
28
|
const now = Date.now();
|
|
29
29
|
const argsJson = JSON.stringify(args);
|
|
30
30
|
const logFile = this.getRawLogPath(pid);
|
|
@@ -36,6 +36,7 @@ var PidStore = class PidStore {
|
|
|
36
36
|
pid,
|
|
37
37
|
cli,
|
|
38
38
|
args: argsJson,
|
|
39
|
+
permissions,
|
|
39
40
|
prompt,
|
|
40
41
|
cwd,
|
|
41
42
|
logFile,
|
|
@@ -67,7 +68,8 @@ var PidStore = class PidStore {
|
|
|
67
68
|
started_at: now,
|
|
68
69
|
wrapper_pid: wrapperPid ?? null,
|
|
69
70
|
parent_pid: parentPid ?? null,
|
|
70
|
-
agent_id: agentId
|
|
71
|
+
agent_id: agentId,
|
|
72
|
+
permissions: permissions ?? null
|
|
71
73
|
}).then(() => maybeCompactGlobalPids()).catch(() => null);
|
|
72
74
|
return result;
|
|
73
75
|
}
|
|
@@ -188,4 +190,4 @@ pid-db/
|
|
|
188
190
|
|
|
189
191
|
//#endregion
|
|
190
192
|
export { PidStore as t };
|
|
191
|
-
//# sourceMappingURL=pidStore-
|
|
193
|
+
//# sourceMappingURL=pidStore-vnX0bgra.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
1
|
+
import { r as getInstalledPackage } from "./versionChecker-Du1qdZR9.js";
|
|
2
2
|
import { execFileSync } from "child_process";
|
|
3
3
|
import { existsSync, mkdirSync, unlinkSync } from "fs";
|
|
4
4
|
import { chmod, copyFile } from "fs/promises";
|
|
@@ -225,4 +225,4 @@ async function getRustBinary(options = {}) {
|
|
|
225
225
|
|
|
226
226
|
//#endregion
|
|
227
227
|
export { getRustBinary as n, findSpawnHiddenLauncher as t };
|
|
228
|
-
//# sourceMappingURL=rustBinary-
|
|
228
|
+
//# sourceMappingURL=rustBinary-BU3E3uMi.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import "./versionChecker-
|
|
3
|
-
import "./ts-
|
|
2
|
+
import "./versionChecker-Du1qdZR9.js";
|
|
3
|
+
import "./ts-rCPxI3aR.js";
|
|
4
4
|
import "./todoAutomation-Buo457VO.js";
|
|
5
5
|
import "./JsonlStore-CPGIR0Wy.js";
|
|
6
6
|
import "./globalPidIndex-D9DOSd-c.js";
|
|
7
|
-
import "./pidStore-
|
|
7
|
+
import "./pidStore-vnX0bgra.js";
|
|
8
8
|
import "./messageLog-C-YIzhRj.js";
|
|
9
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
10
|
-
import {
|
|
9
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DUALQTec.js";
|
|
10
|
+
import { f as resolveSpawnCwd } from "./workspaceConfig-CpilQzMY.js";
|
|
11
11
|
import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-BtL6Oo1o.js";
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
13
|
|
|
@@ -153,4 +153,4 @@ async function cmdSchedule(rest) {
|
|
|
153
153
|
|
|
154
154
|
//#endregion
|
|
155
155
|
export { cmdSchedule };
|
|
156
|
-
//# sourceMappingURL=schedule-
|
|
156
|
+
//# sourceMappingURL=schedule-C8wzhq0y.js.map
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
-
import { t as findSpawnHiddenLauncher } from "./rustBinary-
|
|
4
|
-
import {
|
|
2
|
+
import { r as getInstalledPackage } from "./versionChecker-Du1qdZR9.js";
|
|
3
|
+
import { t as findSpawnHiddenLauncher } from "./rustBinary-BU3E3uMi.js";
|
|
4
|
+
import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-rCPxI3aR.js";
|
|
5
5
|
import { t as agentYesHome$1 } from "./agentYesHome-CtmsY6I-.js";
|
|
6
6
|
import { x as removeControlCharacters } from "./todoAutomation-Buo457VO.js";
|
|
7
7
|
import "./JsonlStore-CPGIR0Wy.js";
|
|
8
8
|
import { a as updateGlobalPidStatus } from "./globalPidIndex-D9DOSd-c.js";
|
|
9
|
-
import "./pidStore-
|
|
9
|
+
import "./pidStore-vnX0bgra.js";
|
|
10
10
|
import { r as recordInbox } from "./messageLog-C-YIzhRj.js";
|
|
11
11
|
import { t as pgidForWrapper } from "./reaper-DP49VCKx.js";
|
|
12
12
|
import "./e2e-CEIdJGZ7.js";
|
|
13
13
|
import "./configShared-IBbnn9b8.js";
|
|
14
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
15
|
-
import { A as recentReadEdges, C as listRecords, D as readNotes, G as writeToIpc, M as renderRawLog, N as renderRawLogLines, O as readPtysize, P as resolveOne, Y as isTransientLockMkdirError, f as extractNeedsInput, j as renderLogTailLines, k as recentMessageEdges, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, rt as TYPING_BADGE, u as extractBadges, x as isUserTyping, z as snapshotStatus } from "./subcommands-
|
|
14
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DUALQTec.js";
|
|
15
|
+
import { A as recentReadEdges, C as listRecords, D as readNotes, G as writeToIpc, M as renderRawLog, N as renderRawLogLines, O as readPtysize, P as resolveOne, Y as isTransientLockMkdirError, f as extractNeedsInput, j as renderLogTailLines, k as recentMessageEdges, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, rt as TYPING_BADGE, u as extractBadges, x as isUserTyping, z as snapshotStatus } from "./subcommands-DeHlaNOY.js";
|
|
16
16
|
import "./webrtcLink-BMYneHbu.js";
|
|
17
17
|
import "./remotes-BxQnNxQv.js";
|
|
18
18
|
import { i as frameVisitorMessage, s as verifyCapability, t as MAX_CALLBACK_MSG_BYTES } from "./callbackCore-Dd28_cBM.js";
|
|
19
|
-
import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-
|
|
20
|
-
import { a as
|
|
19
|
+
import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-DPd9PJQA.js";
|
|
20
|
+
import { a as getProvisionRoot, d as isProvisionAllowed, f as resolveSpawnCwd, i as getProvisionHook, l as hasProvisionHook, o as getSpawnHook, t as allowsSkipPermissions, u as hasSpawnHook } from "./workspaceConfig-CpilQzMY.js";
|
|
21
21
|
import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-BtL6Oo1o.js";
|
|
22
|
-
import { r as spawnRejectionReason } from "./spawnGate-
|
|
22
|
+
import { r as spawnRejectionReason } from "./spawnGate-BFJPdHCQ.js";
|
|
23
23
|
import yargs from "yargs";
|
|
24
24
|
import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, unlink, writeFile } from "fs/promises";
|
|
25
25
|
import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
|
|
@@ -2151,7 +2151,11 @@ Options:
|
|
|
2151
2151
|
size: await sizeOf(r.pid),
|
|
2152
2152
|
inputs: [textIn, envIn],
|
|
2153
2153
|
outputs: [textOut],
|
|
2154
|
-
renderHints: await hintsOf(r)
|
|
2154
|
+
renderHints: await hintsOf(r),
|
|
2155
|
+
configPublic: {
|
|
2156
|
+
permissions: r.permissions ?? null,
|
|
2157
|
+
permissionBadge: permissionBadge(r.permissions)
|
|
2158
|
+
}
|
|
2155
2159
|
})));
|
|
2156
2160
|
nodes.push({
|
|
2157
2161
|
id: envNodeId,
|
|
@@ -2181,7 +2185,8 @@ Options:
|
|
|
2181
2185
|
kill: true,
|
|
2182
2186
|
spawn: true,
|
|
2183
2187
|
spawnHook: hasSpawnHook(),
|
|
2184
|
-
provision: hasProvisionHook()
|
|
2188
|
+
provision: hasProvisionHook(),
|
|
2189
|
+
skipPermissions: allowsSkipPermissions()
|
|
2185
2190
|
}
|
|
2186
2191
|
}
|
|
2187
2192
|
});
|
|
@@ -2296,11 +2301,12 @@ Options:
|
|
|
2296
2301
|
kill: true,
|
|
2297
2302
|
spawn: true,
|
|
2298
2303
|
spawnHook: hasSpawnHook(),
|
|
2299
|
-
provision: hasProvisionHook()
|
|
2304
|
+
provision: hasProvisionHook(),
|
|
2305
|
+
skipPermissions: allowsSkipPermissions()
|
|
2300
2306
|
}
|
|
2301
2307
|
});
|
|
2302
2308
|
if (req.method === "GET" && p === "/api/ws") {
|
|
2303
|
-
const ws = await import("./ws-
|
|
2309
|
+
const ws = await import("./ws-1vGWz9c9.js");
|
|
2304
2310
|
try {
|
|
2305
2311
|
await ws.loadProvision();
|
|
2306
2312
|
} catch (e) {
|
|
@@ -2320,7 +2326,7 @@ Options:
|
|
|
2320
2326
|
if (req.method === "GET" && p === "/api/ws/status") {
|
|
2321
2327
|
const dirRaw = url.searchParams.get("path");
|
|
2322
2328
|
if (!dirRaw) return new Response("missing ?path=<workspace dir>", { status: 400 });
|
|
2323
|
-
const ws = await import("./ws-
|
|
2329
|
+
const ws = await import("./ws-1vGWz9c9.js");
|
|
2324
2330
|
let prov;
|
|
2325
2331
|
try {
|
|
2326
2332
|
prov = await ws.loadProvision();
|
|
@@ -2888,6 +2894,8 @@ Options:
|
|
|
2888
2894
|
const cli = String(body.cli ?? "claude");
|
|
2889
2895
|
if (!SUPPORTED_CLIS.includes(cli)) return new Response(`unsupported cli: ${cli}`, { status: 400 });
|
|
2890
2896
|
const prompt = String(body.prompt ?? "");
|
|
2897
|
+
const wantsSkipPermissions = body.yes === true;
|
|
2898
|
+
if (wantsSkipPermissions && !allowsSkipPermissions()) return new Response("this environment does not permit skip-permissions agents (caps.skipPermissions=false) — spawn without `yes`, or set \"allowSkipPermissions\": true in ~/.agent-yes/config.json (or AGENT_YES_ALLOW_SKIP_PERMISSIONS=1) on the host", { status: 403 });
|
|
2891
2899
|
const reject = await spawnRejectionReason();
|
|
2892
2900
|
if (reject) return new Response(reject, { status: 429 });
|
|
2893
2901
|
let cwd;
|
|
@@ -2983,6 +2991,7 @@ Options:
|
|
|
2983
2991
|
const ayBin = Bun.which("ay") ?? process.argv[1];
|
|
2984
2992
|
const agentArgv = [
|
|
2985
2993
|
...process.platform === "win32" && ayBin.toLowerCase().endsWith(".exe") ? [ayBin] : [process.execPath, ayBin],
|
|
2994
|
+
...wantsSkipPermissions ? ["-y"] : [],
|
|
2986
2995
|
cli,
|
|
2987
2996
|
...prompt ? ["--", prompt] : []
|
|
2988
2997
|
];
|
|
@@ -3070,7 +3079,7 @@ Options:
|
|
|
3070
3079
|
const perm = body.perm ?? "r";
|
|
3071
3080
|
if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
|
|
3072
3081
|
try {
|
|
3073
|
-
const { createScopedShare } = await import("./agentShare-
|
|
3082
|
+
const { createScopedShare } = await import("./agentShare-Clx5QcyE.js");
|
|
3074
3083
|
const share = await createScopedShare({
|
|
3075
3084
|
agent: body.agent,
|
|
3076
3085
|
perm,
|
|
@@ -3085,12 +3094,12 @@ Options:
|
|
|
3085
3094
|
}
|
|
3086
3095
|
}
|
|
3087
3096
|
if (req.method === "GET" && p === "/api/shares") {
|
|
3088
|
-
const { listShares } = await import("./agentShare-
|
|
3097
|
+
const { listShares } = await import("./agentShare-Clx5QcyE.js");
|
|
3089
3098
|
return Response.json(listShares());
|
|
3090
3099
|
}
|
|
3091
3100
|
const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
|
|
3092
3101
|
if (req.method === "DELETE" && revokeM) {
|
|
3093
|
-
const { revokeShare } = await import("./agentShare-
|
|
3102
|
+
const { revokeShare } = await import("./agentShare-Clx5QcyE.js");
|
|
3094
3103
|
const ok = revokeShare(decodeURIComponent(revokeM[1]));
|
|
3095
3104
|
return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
|
|
3096
3105
|
}
|
|
@@ -3392,7 +3401,7 @@ Options:
|
|
|
3392
3401
|
const shutdown = (resolve) => {
|
|
3393
3402
|
if (heartbeat) clearInterval(heartbeat);
|
|
3394
3403
|
closeShare?.();
|
|
3395
|
-
import("./agentShare-
|
|
3404
|
+
import("./agentShare-Clx5QcyE.js").then((m) => m.revokeAllShares()).catch(() => {});
|
|
3396
3405
|
server?.stop();
|
|
3397
3406
|
Promise.resolve(releaseHostLock?.()).catch(() => {}).then(resolve);
|
|
3398
3407
|
};
|
|
@@ -3405,4 +3414,4 @@ Options:
|
|
|
3405
3414
|
|
|
3406
3415
|
//#endregion
|
|
3407
3416
|
export { cmdServe, loadTokenReadOnly, mintScopedTermToken, resolveDaemonHttpBase, resolveLocalServeUrl };
|
|
3408
|
-
//# sourceMappingURL=serve-
|
|
3417
|
+
//# sourceMappingURL=serve-D_DP0VBy.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as getWorkspaceRoot, p as setWorkspaceRoot } from "./workspaceConfig-CpilQzMY.js";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { stdin, stdout } from "node:process";
|
|
4
4
|
import { createInterface } from "node:readline/promises";
|
|
@@ -32,7 +32,7 @@ async function cmdSetup(rest) {
|
|
|
32
32
|
if (!existsSync(abs)) process.stderr.write(` note: that directory doesn't exist yet — create it, or agents spawned there will fail\n`);
|
|
33
33
|
if (noShare) return 0;
|
|
34
34
|
process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
|
|
35
|
-
const { cmdServe } = await import("./serve-
|
|
35
|
+
const { cmdServe } = await import("./serve-D_DP0VBy.js");
|
|
36
36
|
return cmdServe([
|
|
37
37
|
"install",
|
|
38
38
|
"--share",
|
|
@@ -42,4 +42,4 @@ async function cmdSetup(rest) {
|
|
|
42
42
|
|
|
43
43
|
//#endregion
|
|
44
44
|
export { cmdSetup };
|
|
45
|
-
//# sourceMappingURL=setup-
|
|
45
|
+
//# sourceMappingURL=setup-DIa8Y-lx.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as readGlobalPids } from "./globalPidIndex-D9DOSd-c.js";
|
|
2
|
-
import { n as
|
|
2
|
+
import { n as getMaxAgents, r as getMinFreeMb, s as getSpawnWaitMs } from "./workspaceConfig-CpilQzMY.js";
|
|
3
3
|
import { readFile } from "fs/promises";
|
|
4
4
|
|
|
5
5
|
//#region ts/spawnGate.ts
|
|
@@ -104,4 +104,4 @@ async function waitForSpawnCapacity(opts) {
|
|
|
104
104
|
|
|
105
105
|
//#endregion
|
|
106
106
|
export { waitForSpawnCapacity as i, spawnGateEnabled as n, spawnRejectionReason as r, memAvailableMb as t };
|
|
107
|
-
//# sourceMappingURL=spawnGate-
|
|
107
|
+
//# sourceMappingURL=spawnGate-BFJPdHCQ.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
2
|
import "./globalPidIndex-D9DOSd-c.js";
|
|
3
|
-
import { i as waitForSpawnCapacity, n as spawnGateEnabled, r as spawnRejectionReason, t as memAvailableMb } from "./spawnGate-
|
|
3
|
+
import { i as waitForSpawnCapacity, n as spawnGateEnabled, r as spawnRejectionReason, t as memAvailableMb } from "./spawnGate-BFJPdHCQ.js";
|
|
4
4
|
|
|
5
5
|
export { waitForSpawnCapacity };
|
|
@@ -1267,31 +1267,31 @@ async function runSubcommand(argv) {
|
|
|
1267
1267
|
return cmdCh(rest);
|
|
1268
1268
|
}
|
|
1269
1269
|
case "term": {
|
|
1270
|
-
const { cmdTerm } = await import("./terminal-
|
|
1270
|
+
const { cmdTerm } = await import("./terminal-MnictO_E.js");
|
|
1271
1271
|
return cmdTerm(rest);
|
|
1272
1272
|
}
|
|
1273
1273
|
case "widget": {
|
|
1274
|
-
const { cmdWidget } = await import("./widget-
|
|
1274
|
+
const { cmdWidget } = await import("./widget-U6HkHQcz.js");
|
|
1275
1275
|
return cmdWidget(rest);
|
|
1276
1276
|
}
|
|
1277
1277
|
case "mint": {
|
|
1278
|
-
const { cmdMint } = await import("./widget-
|
|
1278
|
+
const { cmdMint } = await import("./widget-U6HkHQcz.js");
|
|
1279
1279
|
return cmdMint(rest);
|
|
1280
1280
|
}
|
|
1281
1281
|
case "serve": {
|
|
1282
|
-
const { cmdServe } = await import("./serve-
|
|
1282
|
+
const { cmdServe } = await import("./serve-D_DP0VBy.js");
|
|
1283
1283
|
return cmdServe(rest);
|
|
1284
1284
|
}
|
|
1285
1285
|
case "setup": {
|
|
1286
|
-
const { cmdSetup } = await import("./setup-
|
|
1286
|
+
const { cmdSetup } = await import("./setup-DIa8Y-lx.js");
|
|
1287
1287
|
return cmdSetup(rest);
|
|
1288
1288
|
}
|
|
1289
1289
|
case "ws": {
|
|
1290
|
-
const { cmdWs } = await import("./ws-
|
|
1290
|
+
const { cmdWs } = await import("./ws-1vGWz9c9.js");
|
|
1291
1291
|
return cmdWs(rest);
|
|
1292
1292
|
}
|
|
1293
1293
|
case "schedule": {
|
|
1294
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1294
|
+
const { cmdSchedule } = await import("./schedule-C8wzhq0y.js");
|
|
1295
1295
|
return cmdSchedule(rest);
|
|
1296
1296
|
}
|
|
1297
1297
|
case "remote": {
|
|
@@ -1303,7 +1303,7 @@ async function runSubcommand(argv) {
|
|
|
1303
1303
|
return cmdExpose(rest);
|
|
1304
1304
|
}
|
|
1305
1305
|
case "callback": {
|
|
1306
|
-
const { cmdCallback } = await import("./callback-
|
|
1306
|
+
const { cmdCallback } = await import("./callback-BPAlieXe.js");
|
|
1307
1307
|
return cmdCallback(rest);
|
|
1308
1308
|
}
|
|
1309
1309
|
case "reap":
|
|
@@ -3706,7 +3706,7 @@ async function cmdAttach(rest) {
|
|
|
3706
3706
|
const winsizeDir = path.join(ayHome, "winsize");
|
|
3707
3707
|
await mkdir(winsizeDir, { recursive: true });
|
|
3708
3708
|
const winsizePath = path.join(winsizeDir, String(record.pid));
|
|
3709
|
-
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-
|
|
3709
|
+
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-D_DP0VBy.js");
|
|
3710
3710
|
const daemonBase = await resolveDaemonHttpBase().catch(() => null);
|
|
3711
3711
|
const daemonToken = daemonBase ? await loadTokenReadOnly().catch(() => null) ?? "" : "";
|
|
3712
3712
|
const capViewer = `attach:${process.pid}`;
|
|
@@ -4403,7 +4403,7 @@ async function cmdNotify(rest) {
|
|
|
4403
4403
|
}
|
|
4404
4404
|
const ensure = async () => {
|
|
4405
4405
|
if (!argv["ensure-daemon"]) return;
|
|
4406
|
-
const { ensureDaemon } = await import("./notifyDaemon-
|
|
4406
|
+
const { ensureDaemon } = await import("./notifyDaemon-CAML5u0d.js");
|
|
4407
4407
|
await ensureDaemon().catch(() => null);
|
|
4408
4408
|
};
|
|
4409
4409
|
await heartbeatWatcher(parent, selfStartedAt);
|
|
@@ -4477,7 +4477,7 @@ async function cmdNotifyCursor(args) {
|
|
|
4477
4477
|
}
|
|
4478
4478
|
async function cmdNotifyd(rest) {
|
|
4479
4479
|
const sub = rest[0] ?? "status";
|
|
4480
|
-
const daemon = await import("./notifyDaemon-
|
|
4480
|
+
const daemon = await import("./notifyDaemon-CAML5u0d.js");
|
|
4481
4481
|
switch (sub) {
|
|
4482
4482
|
case "run": return daemon.runDaemon();
|
|
4483
4483
|
case "once": return daemon.runDaemon({ once: true });
|
|
@@ -4504,4 +4504,4 @@ async function cmdNotifyd(rest) {
|
|
|
4504
4504
|
|
|
4505
4505
|
//#endregion
|
|
4506
4506
|
export { shouldStealLock as $, recentReadEdges as A, stdinActivityPath as B, listRecords as C, readNotes as D, readAgentPtysize as E, resolveReadWindow as F, writeToIpc as G, submitAndConfirm as H, resolveResumeArgs as I, hostId as J, appendEvent as K, restartHintLines as L, renderRawLog as M, renderRawLogLines as N, readPtysize as O, resolveOne as P, readInbox as Q, runSubcommand as R, lastStdinAt as S, menuSelectKeys as T, waitForLogQuiet as U, stopTipForCli as V, writeKeysPaced as W, listInboxParents as X, isTransientLockMkdirError as Y, liveWatchers as Z, isPidAlive as _, cmdHelp as a, isUnknownManagerToken as b, deriveLiveState as c, extractMenu as d, daemonLockDir as et, extractNeedsInput as f, isExitRequest as g, isAgentStuck as h, backoffWhileTyping as i, renderLogTailLines as j, recentMessageEdges as k, deriveLiveStatus as l, finalizedLines as m, READ_PAGE_DEFAULT as n, notifyDir as nt, controlCodeFromName as o, extractTaskCounts as p, gcInboxes as q, TYPING_WINDOW_MS as r, TYPING_BADGE as rt, cursorAbs as s, GRACEFUL_EXIT_COMMANDS as t, daemonLockOwnerPath as tt, extractBadges as u, isSlashCommand as v, matchKeyword as w, isUserTyping as x, isSubcommand as y, snapshotStatus as z };
|
|
4507
|
-
//# sourceMappingURL=subcommands-
|
|
4507
|
+
//# sourceMappingURL=subcommands-DeHlaNOY.js.map
|
|
@@ -3,7 +3,7 @@ import "./globalPidIndex-D9DOSd-c.js";
|
|
|
3
3
|
import "./messageLog-C-YIzhRj.js";
|
|
4
4
|
import "./e2e-CEIdJGZ7.js";
|
|
5
5
|
import "./configShared-IBbnn9b8.js";
|
|
6
|
-
import { A as recentReadEdges, B as stdinActivityPath, C as listRecords, D as readNotes, E as readAgentPtysize, F as resolveReadWindow, G as writeToIpc, H as submitAndConfirm, I as resolveResumeArgs, L as restartHintLines, M as renderRawLog, N as renderRawLogLines, O as readPtysize, P as resolveOne, R as runSubcommand, S as lastStdinAt, T as menuSelectKeys, U as waitForLogQuiet, V as stopTipForCli, W as writeKeysPaced, _ as isPidAlive, a as cmdHelp, b as isUnknownManagerToken, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as renderLogTailLines, k as recentMessageEdges, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as matchKeyword, x as isUserTyping, y as isSubcommand, z as snapshotStatus } from "./subcommands-
|
|
6
|
+
import { A as recentReadEdges, B as stdinActivityPath, C as listRecords, D as readNotes, E as readAgentPtysize, F as resolveReadWindow, G as writeToIpc, H as submitAndConfirm, I as resolveResumeArgs, L as restartHintLines, M as renderRawLog, N as renderRawLogLines, O as readPtysize, P as resolveOne, R as runSubcommand, S as lastStdinAt, T as menuSelectKeys, U as waitForLogQuiet, V as stopTipForCli, W as writeKeysPaced, _ as isPidAlive, a as cmdHelp, b as isUnknownManagerToken, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as renderLogTailLines, k as recentMessageEdges, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as matchKeyword, x as isUserTyping, y as isSubcommand, z as snapshotStatus } from "./subcommands-DeHlaNOY.js";
|
|
7
7
|
import "./webrtcLink-BMYneHbu.js";
|
|
8
8
|
import "./remotes-BxQnNxQv.js";
|
|
9
9
|
|
|
@@ -98,7 +98,7 @@ async function cmdTermMint(args) {
|
|
|
98
98
|
if (flags.ro && flags.interactive) throw new Error("--ro and --interactive are mutually exclusive");
|
|
99
99
|
const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
|
|
100
100
|
const canSend = flags.interactive === true;
|
|
101
|
-
const { mintScopedTermToken } = await import("./serve-
|
|
101
|
+
const { mintScopedTermToken } = await import("./serve-D_DP0VBy.js");
|
|
102
102
|
const r = await mintScopedTermToken(pid, {
|
|
103
103
|
ttlSec,
|
|
104
104
|
canSend
|
|
@@ -135,4 +135,4 @@ async function cmdTerm(args) {
|
|
|
135
135
|
|
|
136
136
|
//#endregion
|
|
137
137
|
export { cmdTerm };
|
|
138
|
-
//# sourceMappingURL=terminal-
|
|
138
|
+
//# sourceMappingURL=terminal-MnictO_E.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as __esmMin, r as __exportAll } from "./chunk-cZBX9HZv.js";
|
|
2
2
|
import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-Du1qdZR9.js";
|
|
4
4
|
import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
|
|
5
5
|
import { d as openStore, p as LIFECYCLES, x as removeControlCharacters } from "./todoAutomation-Buo457VO.js";
|
|
6
6
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-DBoONoM-.js";
|
|
7
7
|
import { i as readGlobalPids } from "./globalPidIndex-D9DOSd-c.js";
|
|
8
|
-
import { t as PidStore } from "./pidStore-
|
|
8
|
+
import { t as PidStore } from "./pidStore-vnX0bgra.js";
|
|
9
9
|
import { r as recordInbox } from "./messageLog-C-YIzhRj.js";
|
|
10
10
|
import { n as register, r as sweep } from "./reaper-DP49VCKx.js";
|
|
11
11
|
import { arch, platform } from "process";
|
|
@@ -1252,6 +1252,49 @@ async function notifyWebhook(status, details, cwd = process.cwd()) {
|
|
|
1252
1252
|
}
|
|
1253
1253
|
}
|
|
1254
1254
|
|
|
1255
|
+
//#endregion
|
|
1256
|
+
//#region ts/agentPermissions.ts
|
|
1257
|
+
/**
|
|
1258
|
+
* Flags that disable a CLI's confirmation gate, recognised regardless of what
|
|
1259
|
+
* `yesArgs` the config declares.
|
|
1260
|
+
*
|
|
1261
|
+
* The configured `yesArgs` are the flags `-y` APPENDS; a user is free to pass
|
|
1262
|
+
* the same flag directly, and a config that omits `yesArgs` entirely (some CLIs
|
|
1263
|
+
* deliberately have none) must not make a genuinely dangerous flag invisible.
|
|
1264
|
+
* So the check is the union: configured flags OR any of these.
|
|
1265
|
+
*/
|
|
1266
|
+
const DANGEROUS_FLAGS = new Set([
|
|
1267
|
+
"--dangerously-skip-permissions",
|
|
1268
|
+
"--dangerously-bypass-approvals-and-sandbox",
|
|
1269
|
+
"--yolo",
|
|
1270
|
+
"--full-auto"
|
|
1271
|
+
]);
|
|
1272
|
+
/** `--flag=value` and `--flag value` must compare equal — match on the flag part. */
|
|
1273
|
+
function flagName(arg) {
|
|
1274
|
+
const eq = arg.indexOf("=");
|
|
1275
|
+
return eq === -1 ? arg : arg.slice(0, eq);
|
|
1276
|
+
}
|
|
1277
|
+
function derivePermissions(opts) {
|
|
1278
|
+
const configured = new Set((opts.yesArgs ?? []).map(flagName).filter(Boolean));
|
|
1279
|
+
return {
|
|
1280
|
+
skip_permissions: opts.cliArgs.some((a) => {
|
|
1281
|
+
const name = flagName(a);
|
|
1282
|
+
return configured.has(name) || DANGEROUS_FLAGS.has(name);
|
|
1283
|
+
}),
|
|
1284
|
+
robust: Boolean(opts.robust),
|
|
1285
|
+
auto_continue: Boolean(opts.autoContinue)
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* One-word posture for a badge. `skip` is the only one that changes what the
|
|
1290
|
+
* agent is ALLOWED to do; the wrapper flags change only how it recovers, so
|
|
1291
|
+
* they never soften the label.
|
|
1292
|
+
*/
|
|
1293
|
+
function permissionBadge(p) {
|
|
1294
|
+
if (!p) return null;
|
|
1295
|
+
return p.skip_permissions ? "skip" : "prompt";
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1255
1298
|
//#endregion
|
|
1256
1299
|
//#region ts/askApi.ts
|
|
1257
1300
|
/**
|
|
@@ -1548,7 +1591,13 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
|
|
|
1548
1591
|
prompt,
|
|
1549
1592
|
cwd: workingDir,
|
|
1550
1593
|
wrapperPid: process.pid,
|
|
1551
|
-
parentPid
|
|
1594
|
+
parentPid,
|
|
1595
|
+
permissions: derivePermissions({
|
|
1596
|
+
cliArgs,
|
|
1597
|
+
yesArgs: cliConf.yesArgs,
|
|
1598
|
+
robust,
|
|
1599
|
+
autoContinue: Boolean(robust && cliConf.restoreArgs?.length)
|
|
1600
|
+
})
|
|
1552
1601
|
});
|
|
1553
1602
|
} catch (error) {
|
|
1554
1603
|
logger.warn(`[pidStore] Failed to register process ${shell.pid}:`, error);
|
|
@@ -2105,5 +2154,5 @@ function sleep(ms) {
|
|
|
2105
2154
|
}
|
|
2106
2155
|
|
|
2107
2156
|
//#endregion
|
|
2108
|
-
export { hasTodoStore as a,
|
|
2109
|
-
//# sourceMappingURL=ts-
|
|
2157
|
+
export { hasTodoStore as a, permissionBadge as c, answerAsk as i, AgentContext as l, agentYes as n, listAsks as o, config as r, listAsksForProject as s, CLIS_CONFIG as t, CLAUDE_SESSION_PIN_ENV as u };
|
|
2158
|
+
//# sourceMappingURL=ts-rCPxI3aR.js.map
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
|
|
8
8
|
//#region package.json
|
|
9
9
|
var name = "agent-yes";
|
|
10
|
-
var version = "1.
|
|
10
|
+
var version = "1.247.0";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region ts/versionChecker.ts
|
|
@@ -215,4 +215,4 @@ async function displayVersion() {
|
|
|
215
215
|
|
|
216
216
|
//#endregion
|
|
217
217
|
export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
|
|
218
|
-
//# sourceMappingURL=versionChecker-
|
|
218
|
+
//# sourceMappingURL=versionChecker-Du1qdZR9.js.map
|
|
@@ -28,7 +28,7 @@ function parseFlags(args, known) {
|
|
|
28
28
|
}
|
|
29
29
|
/** Resolve the local daemon base URL + token (flags override discovery). */
|
|
30
30
|
async function daemonTarget(flags) {
|
|
31
|
-
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-
|
|
31
|
+
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-D_DP0VBy.js");
|
|
32
32
|
const base = typeof flags.base === "string" ? flags.base : await resolveDaemonHttpBase();
|
|
33
33
|
if (!base) throw new Error("no running ay serve daemon found — start `ay serve` or pass --base <url> (e.g. http://127.0.0.1:PORT)");
|
|
34
34
|
const token = typeof flags.token === "string" ? flags.token : await loadTokenReadOnly() ?? "";
|
|
@@ -186,7 +186,7 @@ async function cmdMint(args) {
|
|
|
186
186
|
const bad = caps.filter((c) => !KNOWN_CAPS.has(c));
|
|
187
187
|
if (bad.length) throw new Error(`unknown cap(s): ${bad.join(", ")} (valid: ${[...KNOWN_CAPS].join(", ")})`);
|
|
188
188
|
const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
|
|
189
|
-
const { mintScopedTermToken } = await import("./serve-
|
|
189
|
+
const { mintScopedTermToken } = await import("./serve-D_DP0VBy.js");
|
|
190
190
|
const r = await mintScopedTermToken(target, {
|
|
191
191
|
ttlSec,
|
|
192
192
|
caps
|
|
@@ -202,4 +202,4 @@ async function cmdMint(args) {
|
|
|
202
202
|
|
|
203
203
|
//#endregion
|
|
204
204
|
export { cmdMint, cmdWidget };
|
|
205
|
-
//# sourceMappingURL=widget-
|
|
205
|
+
//# sourceMappingURL=widget-U6HkHQcz.js.map
|
|
@@ -190,7 +190,29 @@ function resolveSpawnCwd(input) {
|
|
|
190
190
|
if (v.includes("/") || v.includes("\\") || path.isAbsolute(v)) return path.resolve(v);
|
|
191
191
|
return path.join(root, v);
|
|
192
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Whether this environment permits spawning agents that skip the CLI's own
|
|
195
|
+
* permission gate (`-y` / `--dangerously-skip-permissions` and equivalents).
|
|
196
|
+
*
|
|
197
|
+
* This is an ENVIRONMENT capability, not a per-request preference: a restricted
|
|
198
|
+
* host publishes `caps.skipPermissions: false` on its env node and `/api/spawn`
|
|
199
|
+
* refuses such a request, host-enforced the way agentShare's default-deny is.
|
|
200
|
+
* A client can't talk its way past it by asking differently.
|
|
201
|
+
*
|
|
202
|
+
* Defaults to TRUE so nothing changes for an existing host — restricting is an
|
|
203
|
+
* explicit opt-in, via `~/.agent-yes/config.json` (`"allowSkipPermissions": false`)
|
|
204
|
+
* or env `AGENT_YES_ALLOW_SKIP_PERMISSIONS=0`. Only an explicit falsy value
|
|
205
|
+
* restricts; anything unset or unparseable leaves the environment permissive
|
|
206
|
+
* rather than silently locking spawns out.
|
|
207
|
+
*
|
|
208
|
+
* Issue #236.
|
|
209
|
+
*/
|
|
210
|
+
function allowsSkipPermissions() {
|
|
211
|
+
const raw = process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS?.trim();
|
|
212
|
+
if (raw !== void 0 && raw !== "") return !/^(0|false|no|off)$/i.test(raw);
|
|
213
|
+
return readConfig().allowSkipPermissions !== false;
|
|
214
|
+
}
|
|
193
215
|
|
|
194
216
|
//#endregion
|
|
195
|
-
export {
|
|
196
|
-
//# sourceMappingURL=workspaceConfig-
|
|
217
|
+
export { getProvisionRoot as a, getWorkspaceRoot as c, isProvisionAllowed as d, resolveSpawnCwd as f, getProvisionHook as i, hasProvisionHook as l, getMaxAgents as n, getSpawnHook as o, setWorkspaceRoot as p, getMinFreeMb as r, getSpawnWaitMs as s, allowsSkipPermissions as t, hasSpawnHook as u };
|
|
218
|
+
//# sourceMappingURL=workspaceConfig-CpilQzMY.js.map
|
|
@@ -3,10 +3,10 @@ import "./globalPidIndex-D9DOSd-c.js";
|
|
|
3
3
|
import "./messageLog-C-YIzhRj.js";
|
|
4
4
|
import "./e2e-CEIdJGZ7.js";
|
|
5
5
|
import "./configShared-IBbnn9b8.js";
|
|
6
|
-
import { C as listRecords } from "./subcommands-
|
|
6
|
+
import { C as listRecords } from "./subcommands-DeHlaNOY.js";
|
|
7
7
|
import "./webrtcLink-BMYneHbu.js";
|
|
8
8
|
import "./remotes-BxQnNxQv.js";
|
|
9
|
-
import {
|
|
9
|
+
import { a as getProvisionRoot } from "./workspaceConfig-CpilQzMY.js";
|
|
10
10
|
import { existsSync } from "fs";
|
|
11
11
|
import { lstat, opendir } from "fs/promises";
|
|
12
12
|
import path from "path";
|
|
@@ -418,4 +418,4 @@ async function cmdWs(args) {
|
|
|
418
418
|
|
|
419
419
|
//#endregion
|
|
420
420
|
export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, workspaceStatus };
|
|
421
|
-
//# sourceMappingURL=ws-
|
|
421
|
+
//# sourceMappingURL=ws-1vGWz9c9.js.map
|
package/package.json
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { derivePermissions, permissionBadge } from "./agentPermissions.ts";
|
|
3
|
+
import { allowsSkipPermissions } from "./workspaceConfig.ts";
|
|
4
|
+
|
|
5
|
+
// Issue #236. The pid record is the only place the answer to "was this agent
|
|
6
|
+
// allowed to act without confirmation?" survives — the global index carries no
|
|
7
|
+
// argv, and the wrapper's own flags never reach the CLI's args at all.
|
|
8
|
+
|
|
9
|
+
describe("derivePermissions", () => {
|
|
10
|
+
const YES = ["--dangerously-skip-permissions"];
|
|
11
|
+
|
|
12
|
+
it("detects the configured yolo flag", () => {
|
|
13
|
+
expect(
|
|
14
|
+
derivePermissions({ cliArgs: ["--print", ...YES], yesArgs: YES }).skip_permissions,
|
|
15
|
+
).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("detects a dangerous flag the config never declared", () => {
|
|
19
|
+
// A CLI with no yesArgs must still not hide a flag that disables its gate —
|
|
20
|
+
// the check is the union of configured and known-dangerous, not just config.
|
|
21
|
+
expect(derivePermissions({ cliArgs: ["--yolo"] }).skip_permissions).toBe(true);
|
|
22
|
+
expect(
|
|
23
|
+
derivePermissions({ cliArgs: ["--dangerously-bypass-approvals-and-sandbox"] })
|
|
24
|
+
.skip_permissions,
|
|
25
|
+
).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("matches the flag part of an --flag=value form", () => {
|
|
29
|
+
expect(derivePermissions({ cliArgs: ["--full-auto=true"] }).skip_permissions).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("does not flag ordinary args", () => {
|
|
33
|
+
expect(
|
|
34
|
+
derivePermissions({ cliArgs: ["--model", "opus", "--continue"], yesArgs: YES })
|
|
35
|
+
.skip_permissions,
|
|
36
|
+
).toBe(false);
|
|
37
|
+
expect(derivePermissions({ cliArgs: [] }).skip_permissions).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("records the wrapper flags independently of the CLI's", () => {
|
|
41
|
+
const p = derivePermissions({ cliArgs: [], robust: true, autoContinue: true });
|
|
42
|
+
expect(p).toEqual({ skip_permissions: false, robust: true, auto_continue: true });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("defaults every flag to false rather than undefined", () => {
|
|
46
|
+
// The record is serialized to JSON and read by both runtimes; an absent
|
|
47
|
+
// boolean would read as "unknown" where we mean "no".
|
|
48
|
+
expect(derivePermissions({ cliArgs: [] })).toEqual({
|
|
49
|
+
skip_permissions: false,
|
|
50
|
+
robust: false,
|
|
51
|
+
auto_continue: false,
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("ignores an empty yesArgs entry rather than matching everything", () => {
|
|
56
|
+
// A config with a stray "" must not make every arg look like a yolo flag.
|
|
57
|
+
expect(derivePermissions({ cliArgs: ["--model"], yesArgs: [""] }).skip_permissions).toBe(false);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("permissionBadge", () => {
|
|
62
|
+
it("reports skip only when the CLI gate is off", () => {
|
|
63
|
+
expect(permissionBadge({ skip_permissions: true, robust: false, auto_continue: false })).toBe(
|
|
64
|
+
"skip",
|
|
65
|
+
);
|
|
66
|
+
expect(permissionBadge({ skip_permissions: false, robust: false, auto_continue: false })).toBe(
|
|
67
|
+
"prompt",
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("never lets the wrapper flags soften the label", () => {
|
|
72
|
+
// robust/auto_continue change how the agent RECOVERS, not what it may do.
|
|
73
|
+
expect(permissionBadge({ skip_permissions: true, robust: true, auto_continue: true })).toBe(
|
|
74
|
+
"skip",
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("has nothing to show for a record with no stamp (pre-#236 agent)", () => {
|
|
79
|
+
expect(permissionBadge(null)).toBeNull();
|
|
80
|
+
expect(permissionBadge(undefined)).toBeNull();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe("allowsSkipPermissions", () => {
|
|
85
|
+
const original = process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS;
|
|
86
|
+
afterEach(() => {
|
|
87
|
+
if (original === undefined) delete process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS;
|
|
88
|
+
else process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS = original;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("is permissive by default — restricting is an opt-in", () => {
|
|
92
|
+
delete process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS;
|
|
93
|
+
expect(allowsSkipPermissions()).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("is restricted by an explicit falsy env value", () => {
|
|
97
|
+
for (const v of ["0", "false", "no", "off", "FALSE"]) {
|
|
98
|
+
process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS = v;
|
|
99
|
+
expect(allowsSkipPermissions()).toBe(false);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("stays permissive for any other value, including garbage", () => {
|
|
104
|
+
// Failing closed here would lock spawns out of a host over a typo; the
|
|
105
|
+
// enforcement point is an explicit opt-in, so an unparseable value must not
|
|
106
|
+
// silently become a restriction.
|
|
107
|
+
for (const v of ["1", "true", "yes", "on", "banana"]) {
|
|
108
|
+
process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS = v;
|
|
109
|
+
expect(allowsSkipPermissions()).toBe(true);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("treats an empty env value as unset (falls through to config)", () => {
|
|
114
|
+
process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS = " ";
|
|
115
|
+
expect(allowsSkipPermissions()).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The permission posture an agent was actually spawned with — derived once at
|
|
3
|
+
* registration and stamped into the pid record so it can be audited later.
|
|
4
|
+
*
|
|
5
|
+
* Why record it rather than re-derive on read: the global index carries no argv,
|
|
6
|
+
* and the wrapper's own flags (`--robust`, auto-continue) never appear in the
|
|
7
|
+
* CLI's args at all. Without stamping, "was this agent running with permission
|
|
8
|
+
* checks disabled?" is unanswerable after the fact — which is precisely the
|
|
9
|
+
* question an operator looking at a fleet of agents needs answered.
|
|
10
|
+
*
|
|
11
|
+
* Mirrored by `derive_permissions` in rs/src/agentPermissions.rs — keep in sync.
|
|
12
|
+
*
|
|
13
|
+
* Issue #236.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export interface AgentPermissions {
|
|
17
|
+
/**
|
|
18
|
+
* The wrapped CLI got its "yolo" flag — the per-CLI `yesArgs` appended by
|
|
19
|
+
* `-y`/`--yes`, or the same flag passed through directly. This is the one that
|
|
20
|
+
* matters for audit: it disables the CLI's own confirmation gate, so the agent
|
|
21
|
+
* can edit files and run commands with no human in the loop.
|
|
22
|
+
*/
|
|
23
|
+
skip_permissions: boolean;
|
|
24
|
+
/** agent-yes `--robust`: restart the CLI automatically when it crashes. */
|
|
25
|
+
robust: boolean;
|
|
26
|
+
/** agent-yes auto-continue: resume the prior session on restart. */
|
|
27
|
+
auto_continue: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Flags that disable a CLI's confirmation gate, recognised regardless of what
|
|
32
|
+
* `yesArgs` the config declares.
|
|
33
|
+
*
|
|
34
|
+
* The configured `yesArgs` are the flags `-y` APPENDS; a user is free to pass
|
|
35
|
+
* the same flag directly, and a config that omits `yesArgs` entirely (some CLIs
|
|
36
|
+
* deliberately have none) must not make a genuinely dangerous flag invisible.
|
|
37
|
+
* So the check is the union: configured flags OR any of these.
|
|
38
|
+
*/
|
|
39
|
+
const DANGEROUS_FLAGS = new Set([
|
|
40
|
+
"--dangerously-skip-permissions",
|
|
41
|
+
"--dangerously-bypass-approvals-and-sandbox",
|
|
42
|
+
"--yolo",
|
|
43
|
+
"--full-auto",
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
/** `--flag=value` and `--flag value` must compare equal — match on the flag part. */
|
|
47
|
+
function flagName(arg: string): string {
|
|
48
|
+
const eq = arg.indexOf("=");
|
|
49
|
+
return eq === -1 ? arg : arg.slice(0, eq);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function derivePermissions(opts: {
|
|
53
|
+
/** The args handed to the wrapped CLI (after yesArgs were appended). */
|
|
54
|
+
cliArgs: readonly string[];
|
|
55
|
+
/** The CLI's configured "yolo" flags, if it declares any. */
|
|
56
|
+
yesArgs?: readonly string[];
|
|
57
|
+
robust?: boolean;
|
|
58
|
+
autoContinue?: boolean;
|
|
59
|
+
}): AgentPermissions {
|
|
60
|
+
const configured = new Set((opts.yesArgs ?? []).map(flagName).filter(Boolean));
|
|
61
|
+
const skip = opts.cliArgs.some((a) => {
|
|
62
|
+
const name = flagName(a);
|
|
63
|
+
return configured.has(name) || DANGEROUS_FLAGS.has(name);
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
skip_permissions: skip,
|
|
67
|
+
robust: Boolean(opts.robust),
|
|
68
|
+
auto_continue: Boolean(opts.autoContinue),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* One-word posture for a badge. `skip` is the only one that changes what the
|
|
74
|
+
* agent is ALLOWED to do; the wrapper flags change only how it recovers, so
|
|
75
|
+
* they never soften the label.
|
|
76
|
+
*/
|
|
77
|
+
export function permissionBadge(p: AgentPermissions | null | undefined): "skip" | "prompt" | null {
|
|
78
|
+
if (!p) return null;
|
|
79
|
+
return p.skip_permissions ? "skip" : "prompt";
|
|
80
|
+
}
|
package/ts/globalPidIndex.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { appendFile, mkdir, readFile, rename, unlink, writeFile } from "fs/promises";
|
|
2
2
|
import { homedir } from "os";
|
|
3
|
+
import type { AgentPermissions } from "./agentPermissions.ts";
|
|
3
4
|
import path from "path";
|
|
4
5
|
import { lock } from "proper-lockfile";
|
|
5
6
|
import { logger } from "./logger.ts";
|
|
@@ -57,6 +58,13 @@ export interface GlobalPidRecord {
|
|
|
57
58
|
// (snake_case). Currently per-process; cross-restart re-binding is a follow-up
|
|
58
59
|
// (see docs/agent-sharing.md). Preserved verbatim through merges/compaction.
|
|
59
60
|
agent_id?: string | null;
|
|
61
|
+
// The permission posture this agent was SPAWNED with — whether the wrapped CLI
|
|
62
|
+
// got its "yolo" flag, plus the wrapper's own robust/auto-continue flags. The
|
|
63
|
+
// index carries no argv and the wrapper flags never reach the CLI's args at
|
|
64
|
+
// all, so without stamping this at registration "was this agent running with
|
|
65
|
+
// permission checks off?" is unanswerable after the fact. See
|
|
66
|
+
// ts/agentPermissions.ts (mirrored in rs/src/agent_permissions.rs).
|
|
67
|
+
permissions?: AgentPermissions | null;
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
/**
|
package/ts/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ import { globalAgentRegistry } from "./agentRegistry.ts";
|
|
|
44
44
|
import { notifyWebhook } from "./webhookNotifier.ts";
|
|
45
45
|
import { readGlobalPids } from "./globalPidIndex.ts";
|
|
46
46
|
import * as reaper from "./reaper.ts";
|
|
47
|
+
import { derivePermissions } from "./agentPermissions.ts";
|
|
47
48
|
|
|
48
49
|
export { removeControlCharacters };
|
|
49
50
|
export { AgentContext };
|
|
@@ -510,6 +511,15 @@ export default async function agentYes({
|
|
|
510
511
|
wrapperPid: process.pid,
|
|
511
512
|
// The parent agent's wrapper pid (inherited AGENT_YES_PID), for the tree.
|
|
512
513
|
parentPid,
|
|
514
|
+
// Audit trail: what this agent is actually allowed to do. `auto_continue`
|
|
515
|
+
// is robust AND a CLI that declares restoreArgs — robust alone only
|
|
516
|
+
// restarts, it resumes nothing.
|
|
517
|
+
permissions: derivePermissions({
|
|
518
|
+
cliArgs,
|
|
519
|
+
yesArgs: cliConf.yesArgs,
|
|
520
|
+
robust,
|
|
521
|
+
autoContinue: Boolean(robust && cliConf.restoreArgs?.length),
|
|
522
|
+
}),
|
|
513
523
|
});
|
|
514
524
|
} catch (error) {
|
|
515
525
|
logger.warn(`[pidStore] Failed to register process ${shell.pid}:`, error);
|
package/ts/pidStore.ts
CHANGED
|
@@ -4,6 +4,7 @@ import path from "path";
|
|
|
4
4
|
import { logger } from "./logger.ts";
|
|
5
5
|
import { JsonlStore } from "./JsonlStore.ts";
|
|
6
6
|
import { agentYesHome } from "./agentYesHome.ts";
|
|
7
|
+
import type { AgentPermissions } from "./agentPermissions.ts";
|
|
7
8
|
import {
|
|
8
9
|
appendGlobalPid,
|
|
9
10
|
maybeCompactGlobalPids,
|
|
@@ -26,6 +27,8 @@ export interface PidRecord {
|
|
|
26
27
|
startedAt: number;
|
|
27
28
|
// Stable id minted at registration; mirrored to the global index as `agent_id`.
|
|
28
29
|
agentId?: string;
|
|
30
|
+
/** Permission posture at spawn time; mirrored to the global index. */
|
|
31
|
+
permissions?: AgentPermissions;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
export class PidStore {
|
|
@@ -59,6 +62,7 @@ export class PidStore {
|
|
|
59
62
|
cwd,
|
|
60
63
|
wrapperPid,
|
|
61
64
|
parentPid,
|
|
65
|
+
permissions,
|
|
62
66
|
}: {
|
|
63
67
|
pid: number;
|
|
64
68
|
cli: string;
|
|
@@ -67,6 +71,7 @@ export class PidStore {
|
|
|
67
71
|
cwd: string;
|
|
68
72
|
wrapperPid?: number;
|
|
69
73
|
parentPid?: number;
|
|
74
|
+
permissions?: AgentPermissions;
|
|
70
75
|
}): Promise<PidRecord> {
|
|
71
76
|
const now = Date.now();
|
|
72
77
|
const argsJson = JSON.stringify(args);
|
|
@@ -91,6 +96,7 @@ export class PidStore {
|
|
|
91
96
|
pid,
|
|
92
97
|
cli,
|
|
93
98
|
args: argsJson,
|
|
99
|
+
permissions,
|
|
94
100
|
prompt,
|
|
95
101
|
cwd,
|
|
96
102
|
logFile,
|
|
@@ -133,6 +139,7 @@ export class PidStore {
|
|
|
133
139
|
wrapper_pid: wrapperPid ?? null,
|
|
134
140
|
parent_pid: parentPid ?? null,
|
|
135
141
|
agent_id: agentId,
|
|
142
|
+
permissions: permissions ?? null,
|
|
136
143
|
})
|
|
137
144
|
.then(() => maybeCompactGlobalPids())
|
|
138
145
|
.catch(() => null);
|
package/ts/serve.ts
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
type CommonOpts,
|
|
39
39
|
} from "./subcommands.ts";
|
|
40
40
|
import { answerAsk, listAsks } from "./askApi.ts";
|
|
41
|
+
import { permissionBadge } from "./agentPermissions.ts";
|
|
41
42
|
import { TYPING_BADGE } from "./badges.ts";
|
|
42
43
|
import { isTermToken, mintTermToken, verifyTermToken, type TermScope } from "./termToken.ts";
|
|
43
44
|
import { isCallbackRevoked, loadCallbackSecretReadOnly } from "./callback.ts";
|
|
@@ -65,6 +66,7 @@ import {
|
|
|
65
66
|
hasSpawnHook,
|
|
66
67
|
isProvisionAllowed,
|
|
67
68
|
resolveSpawnCwd,
|
|
69
|
+
allowsSkipPermissions,
|
|
68
70
|
} from "./workspaceConfig.ts";
|
|
69
71
|
|
|
70
72
|
const DEFAULT_PORT = 0;
|
|
@@ -2749,6 +2751,16 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
2749
2751
|
inputs: [textIn, envIn],
|
|
2750
2752
|
outputs: [textOut],
|
|
2751
2753
|
renderHints: await hintsOf(r),
|
|
2754
|
+
// What this agent is actually permitted to do, stamped at spawn (see
|
|
2755
|
+
// ts/agentPermissions.ts). Carried on the node so the viewer can badge
|
|
2756
|
+
// the env edge — "skip" means the CLI's confirmation gate is off, i.e.
|
|
2757
|
+
// this agent edits and executes with no human in the loop. Null for
|
|
2758
|
+
// agents registered before the stamp existed, which the viewer renders
|
|
2759
|
+
// as "unknown" rather than as safe.
|
|
2760
|
+
configPublic: {
|
|
2761
|
+
permissions: r.permissions ?? null,
|
|
2762
|
+
permissionBadge: permissionBadge(r.permissions),
|
|
2763
|
+
},
|
|
2752
2764
|
})),
|
|
2753
2765
|
);
|
|
2754
2766
|
// The host environment node: identity + capability flags only (no cwd,
|
|
@@ -2776,6 +2788,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
2776
2788
|
spawn: true,
|
|
2777
2789
|
spawnHook: hasSpawnHook(),
|
|
2778
2790
|
provision: hasProvisionHook(),
|
|
2791
|
+
skipPermissions: allowsSkipPermissions(),
|
|
2779
2792
|
},
|
|
2780
2793
|
},
|
|
2781
2794
|
} as unknown as (typeof nodes)[number]); // configPublic is envelope-legal but absent from the agent-node literal type
|
|
@@ -2919,6 +2932,10 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
2919
2932
|
spawn: true, // /api/spawn is always on; hooks below shape it
|
|
2920
2933
|
spawnHook: hasSpawnHook(),
|
|
2921
2934
|
provision: hasProvisionHook(),
|
|
2935
|
+
// Whether this environment permits spawning agents with the CLI's own
|
|
2936
|
+
// permission gate disabled. Host-enforced in /api/spawn — a client
|
|
2937
|
+
// that asks anyway gets a 403, not a downgrade.
|
|
2938
|
+
skipPermissions: allowsSkipPermissions(),
|
|
2922
2939
|
},
|
|
2923
2940
|
});
|
|
2924
2941
|
}
|
|
@@ -3739,6 +3756,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
3739
3756
|
cwd?: string;
|
|
3740
3757
|
from?: string;
|
|
3741
3758
|
prompt?: string;
|
|
3759
|
+
yes?: boolean;
|
|
3742
3760
|
fork?: { fromCwd?: string; branch?: string };
|
|
3743
3761
|
};
|
|
3744
3762
|
try {
|
|
@@ -3751,6 +3769,26 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
3751
3769
|
return new Response(`unsupported cli: ${cli}`, { status: 400 });
|
|
3752
3770
|
const prompt = String(body.prompt ?? "");
|
|
3753
3771
|
|
|
3772
|
+
// Capability enforcement, BEFORE admission control and any provisioning: a
|
|
3773
|
+
// request that this environment will never honour must fail immediately,
|
|
3774
|
+
// not after cloning a repo. `yes` appends the CLI's own "yolo" flag, which
|
|
3775
|
+
// disables its confirmation gate — so a restricted environment refuses it
|
|
3776
|
+
// outright rather than silently downgrading to a safe spawn (which would
|
|
3777
|
+
// hand back an agent that looks like what was asked for and isn't). The
|
|
3778
|
+
// environment declares the cap on its env node / GET /api/host, and it is
|
|
3779
|
+
// enforced HERE, host-side, the way agentShare's default-deny is: a client
|
|
3780
|
+
// cannot ask its way past it. Issue #236.
|
|
3781
|
+
const wantsSkipPermissions = body.yes === true;
|
|
3782
|
+
if (wantsSkipPermissions && !allowsSkipPermissions()) {
|
|
3783
|
+
return new Response(
|
|
3784
|
+
`this environment does not permit skip-permissions agents ` +
|
|
3785
|
+
`(caps.skipPermissions=false) — spawn without \`yes\`, or set ` +
|
|
3786
|
+
`"allowSkipPermissions": true in ~/.agent-yes/config.json ` +
|
|
3787
|
+
`(or AGENT_YES_ALLOW_SKIP_PERMISSIONS=1) on the host`,
|
|
3788
|
+
{ status: 403 },
|
|
3789
|
+
);
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3754
3792
|
// Admission control BEFORE any provisioning (clone/worktree) so a capped
|
|
3755
3793
|
// request fails fast without doing expensive work. Enforces the optional
|
|
3756
3794
|
// concurrency cap + memory floor that keep a fan-out of agents from
|
|
@@ -3946,7 +3984,15 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
3946
3984
|
process.platform === "win32" && ayBin.toLowerCase().endsWith(".exe")
|
|
3947
3985
|
? [ayBin]
|
|
3948
3986
|
: [process.execPath, ayBin];
|
|
3949
|
-
|
|
3987
|
+
// `-y` goes BEFORE the prompt separator so it is parsed as an agent-yes
|
|
3988
|
+
// flag (global flags precede the CLI's own args), and only after the
|
|
3989
|
+
// capability check above has allowed it.
|
|
3990
|
+
const agentArgv = [
|
|
3991
|
+
...ayCmd,
|
|
3992
|
+
...(wantsSkipPermissions ? ["-y"] : []),
|
|
3993
|
+
cli,
|
|
3994
|
+
...(prompt ? ["--", prompt] : []),
|
|
3995
|
+
];
|
|
3950
3996
|
// don't leak our Claude Code session into the agent
|
|
3951
3997
|
const agentEnv = freshAgentEnv();
|
|
3952
3998
|
// Correlation id: the spawn response returns the `ay` LAUNCHER pid, which is
|
package/ts/workspaceConfig.ts
CHANGED
|
@@ -34,6 +34,13 @@ interface Config {
|
|
|
34
34
|
* so it is intentionally NOT settable over the network.
|
|
35
35
|
*/
|
|
36
36
|
provisionHook?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Whether this environment permits spawning agents with the CLI's permission
|
|
39
|
+
* gate disabled (`-y` / `--dangerously-skip-permissions` and friends).
|
|
40
|
+
* Defaults to TRUE — the historical behaviour — so a host opts IN to being
|
|
41
|
+
* restricted. See {@link allowsSkipPermissions}.
|
|
42
|
+
*/
|
|
43
|
+
allowSkipPermissions?: boolean;
|
|
37
44
|
/**
|
|
38
45
|
* Max number of concurrently-live agents the daemon will admit via
|
|
39
46
|
* `/api/spawn`. `0`/unset = unlimited (current behavior). See {@link getMaxAgents}.
|
|
@@ -263,3 +270,26 @@ export function resolveSpawnCwd(input?: string): string {
|
|
|
263
270
|
if (v.includes("/") || v.includes("\\") || path.isAbsolute(v)) return path.resolve(v);
|
|
264
271
|
return path.join(root, v);
|
|
265
272
|
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Whether this environment permits spawning agents that skip the CLI's own
|
|
276
|
+
* permission gate (`-y` / `--dangerously-skip-permissions` and equivalents).
|
|
277
|
+
*
|
|
278
|
+
* This is an ENVIRONMENT capability, not a per-request preference: a restricted
|
|
279
|
+
* host publishes `caps.skipPermissions: false` on its env node and `/api/spawn`
|
|
280
|
+
* refuses such a request, host-enforced the way agentShare's default-deny is.
|
|
281
|
+
* A client can't talk its way past it by asking differently.
|
|
282
|
+
*
|
|
283
|
+
* Defaults to TRUE so nothing changes for an existing host — restricting is an
|
|
284
|
+
* explicit opt-in, via `~/.agent-yes/config.json` (`"allowSkipPermissions": false`)
|
|
285
|
+
* or env `AGENT_YES_ALLOW_SKIP_PERMISSIONS=0`. Only an explicit falsy value
|
|
286
|
+
* restricts; anything unset or unparseable leaves the environment permissive
|
|
287
|
+
* rather than silently locking spawns out.
|
|
288
|
+
*
|
|
289
|
+
* Issue #236.
|
|
290
|
+
*/
|
|
291
|
+
export function allowsSkipPermissions(): boolean {
|
|
292
|
+
const raw = process.env.AGENT_YES_ALLOW_SKIP_PERMISSIONS?.trim();
|
|
293
|
+
if (raw !== undefined && raw !== "") return !/^(0|false|no|off)$/i.test(raw);
|
|
294
|
+
return readConfig().allowSkipPermissions !== false;
|
|
295
|
+
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import "./versionChecker-D5ir842c.js";
|
|
3
|
-
import "./ts-B51ZLoJC.js";
|
|
4
|
-
import "./todoAutomation-Buo457VO.js";
|
|
5
|
-
import "./JsonlStore-CPGIR0Wy.js";
|
|
6
|
-
import "./globalPidIndex-D9DOSd-c.js";
|
|
7
|
-
import "./pidStore-6EZd5DUv.js";
|
|
8
|
-
import "./messageLog-C-YIzhRj.js";
|
|
9
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-ia9b-P1k.js";
|
|
10
|
-
|
|
11
|
-
export { SUPPORTED_CLIS };
|