agent-yes 1.169.1 → 1.171.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-BMExykB1.js +8 -0
- package/dist/{SUPPORTED_CLIS-Bwg9VqLI.js → SUPPORTED_CLIS-D6MArV7A.js} +2 -2
- package/dist/{agent-yes.config-Bl08kMpl.js → agent-yes.config-ugPYTPOd.js} +2 -2
- package/dist/{agentYesHome-_eJa3DaX.js → agentYesHome-CtHb5b71.js} +1 -1
- package/dist/cli.js +10 -212
- package/dist/{configShared-CEyhl0WH.js → configShared-0MnIQ652.js} +1 -1
- package/dist/{e2e-BeKjLhmO.js → e2e-jb0Hp43q.js} +1 -1
- package/dist/{forkNested-UCKPEgSI.js → forkNested-DhJxa4q4.js} +2 -2
- package/dist/{globalPidIndex-DlmmJlO8.js → globalPidIndex-CoNr7tS8.js} +1 -1
- package/dist/index.js +4 -4
- package/dist/notifyDaemon-BlGV0y4j.js +591 -0
- package/dist/{openBrowser-CCF1iuQK.js → openBrowser-ChR4llYa.js} +1 -1
- package/dist/{pidStore-BfoBWUjc.js → pidStore-BIvsBQ8X.js} +3 -3
- package/dist/pidStore-CLxwp0qI.js +5 -0
- package/dist/{reaper-C-eWAxIj.js → reaper-CWF2_ATd.js} +27 -3
- package/dist/{reaper-BQgDb85W.js → reaper-jfSmog15.js} +1 -1
- package/dist/{remotes-cx_GDFPj.js → remotes-BQMr4_En.js} +3 -3
- package/dist/{remotes-BmAPylU_.js → remotes-CC-4GuJb.js} +3 -3
- package/dist/{runningLock-BobVW1_A.js → runningLock-CNMl13dC.js} +1 -1
- package/dist/rustBinary-mYbyV0SD.js +228 -0
- package/dist/{schedule-CtVvSyaN.js → schedule-C5nUV0GO.js} +7 -7
- package/dist/{serve-CLmk5ujF.js → serve-ChcayCC3.js} +122 -26
- package/dist/{setup-CYbXOcpH.js → setup-CCQZ9tPB.js} +3 -3
- package/dist/{share-D_e2Fwiy.js → share-QregR8a_.js} +2 -2
- package/dist/spawnGate-BFhva-2F.js +5 -0
- package/dist/{spawnGate-DzPfa1PZ.js → spawnGate-IJDByl2U.js} +3 -3
- package/dist/subcommands-CIk1SSdW.js +9 -0
- package/dist/{subcommands--EUush_X.js → subcommands-CtWxwydR.js} +1049 -44
- package/dist/{tray-CWUpaZF4.js → tray-DXr7iK3E.js} +2 -2
- package/dist/{ts-Bbhf5JbN.js → ts-WHYKp13w.js} +8 -8
- package/dist/{versionChecker-BmWkWhcJ.js → versionChecker-BoPKPL9B.js} +2 -2
- package/dist/{webrtcLink-BG0Xc4-W.js → webrtcLink-B7REGtK2.js} +2 -2
- package/dist/{webrtcRemote-SybKurg9.js → webrtcRemote-Bx-eD_0I.js} +3 -3
- package/dist/{workspaceConfig-BC03X4Y1.js → workspaceConfig-BgqK-31W.js} +37 -6
- package/lab/ui/console-logic.js +125 -10
- package/lab/ui/index.html +340 -11
- package/lab/ui/landing.html +11 -1
- package/package.json +1 -1
- package/scripts/build-rs.ts +9 -5
- package/ts/badges.spec.ts +51 -1
- package/ts/badges.ts +35 -1
- package/ts/notifyDaemon.spec.ts +276 -0
- package/ts/notifyDaemon.ts +698 -0
- package/ts/notifyInbox.spec.ts +192 -0
- package/ts/notifyInbox.ts +294 -0
- package/ts/notifyRouter.spec.ts +355 -0
- package/ts/notifyRouter.ts +288 -0
- package/ts/notifyStore.spec.ts +308 -0
- package/ts/notifyStore.ts +439 -0
- package/ts/reaper.spec.ts +18 -1
- package/ts/reaper.ts +33 -1
- package/ts/rustBinary.ts +30 -0
- package/ts/serve.ts +194 -14
- package/ts/subcommands.spec.ts +341 -0
- package/ts/subcommands.ts +764 -29
- package/ts/workspaceConfig.spec.ts +48 -0
- package/ts/workspaceConfig.ts +46 -3
- package/dist/SUPPORTED_CLIS-DiL99G3j.js +0 -8
- package/dist/pidStore-5qyLX3Fh.js +0 -5
- package/dist/spawnGate-CQ1Il3Xk.js +0 -5
- package/dist/subcommands-1ZcaHYkb.js +0 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as isWebrtcSpec } from "./webrtcLink-
|
|
1
|
+
import { n as isWebrtcSpec } from "./webrtcLink-B7REGtK2.js";
|
|
2
2
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import path from "path";
|
|
@@ -86,7 +86,7 @@ async function resolveRemoteSpec(spec) {
|
|
|
86
86
|
* The bridge lives for the rest of the process (torn down on `process.exit`).
|
|
87
87
|
*/
|
|
88
88
|
async function resolveWebrtc(link, keyword) {
|
|
89
|
-
const { startWebrtcBridge } = await import("./webrtcRemote-
|
|
89
|
+
const { startWebrtcBridge } = await import("./webrtcRemote-Bx-eD_0I.js");
|
|
90
90
|
const bridge = await startWebrtcBridge(link);
|
|
91
91
|
return {
|
|
92
92
|
url: bridge.baseUrl,
|
|
@@ -173,4 +173,4 @@ async function cmdRemote(rest) {
|
|
|
173
173
|
|
|
174
174
|
//#endregion
|
|
175
175
|
export { resolveRemoteSpec as a, readRemotes as i, deleteRemoteAlias as n, writeRemoteAlias as o, parseDirectRemoteSpec as r, cmdRemote as t };
|
|
176
|
-
//# sourceMappingURL=remotes-
|
|
176
|
+
//# sourceMappingURL=remotes-CC-4GuJb.js.map
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { r as getInstalledPackage } from "./versionChecker-BoPKPL9B.js";
|
|
2
|
+
import { execFileSync } from "child_process";
|
|
3
|
+
import { existsSync, mkdirSync, unlinkSync } from "fs";
|
|
4
|
+
import { chmod, copyFile } from "fs/promises";
|
|
5
|
+
import path from "path";
|
|
6
|
+
|
|
7
|
+
//#region ts/rustBinary.ts
|
|
8
|
+
/**
|
|
9
|
+
* Rust binary helper - finds or downloads the appropriate prebuilt binary
|
|
10
|
+
*/
|
|
11
|
+
const PLATFORM_MAP = {
|
|
12
|
+
"linux-x64": "agent-yes-linux-x64-musl",
|
|
13
|
+
"linux-arm64": "agent-yes-linux-arm64-musl",
|
|
14
|
+
"darwin-x64": "agent-yes-darwin-x64",
|
|
15
|
+
"darwin-arm64": "agent-yes-darwin-arm64",
|
|
16
|
+
"win32-x64": "agent-yes-win32-x64"
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Get the binary name for the current platform
|
|
20
|
+
*/
|
|
21
|
+
function getBinaryName() {
|
|
22
|
+
const platform = process.platform;
|
|
23
|
+
const arch = process.arch;
|
|
24
|
+
const binaryName = PLATFORM_MAP[`${platform}-${arch}`];
|
|
25
|
+
if (!binaryName) throw new Error(`Unsupported platform: ${platform}-${arch}. Supported: ${Object.keys(PLATFORM_MAP).join(", ")}`);
|
|
26
|
+
return binaryName + (platform === "win32" ? ".exe" : "");
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the directory where binaries are stored
|
|
30
|
+
*/
|
|
31
|
+
function getBinDir() {
|
|
32
|
+
const packageBinDir = path.resolve(import.meta.dirname ?? import.meta.dir, "../bin");
|
|
33
|
+
if (existsSync(packageBinDir)) return packageBinDir;
|
|
34
|
+
const cacheDir = process.env.AGENT_YES_CACHE_DIR || path.join(process.env.XDG_CACHE_HOME || path.join(process.env.HOME || "/tmp", ".cache"), "agent-yes");
|
|
35
|
+
return path.join(cacheDir, "bin", getInstalledPackage().version);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Find the Rust binary, checking multiple locations
|
|
39
|
+
*/
|
|
40
|
+
function findRustBinary(verbose = false) {
|
|
41
|
+
const binaryName = getBinaryName();
|
|
42
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
43
|
+
const searchPaths = [
|
|
44
|
+
path.resolve(import.meta.dirname ?? import.meta.dir, `../rs/target/release/agent-yes${ext}`),
|
|
45
|
+
path.resolve(import.meta.dirname ?? import.meta.dir, `../rs/target/debug/agent-yes${ext}`),
|
|
46
|
+
path.join(getBinDir(), binaryName),
|
|
47
|
+
path.join(getBinDir(), binaryName)
|
|
48
|
+
];
|
|
49
|
+
if (verbose) {
|
|
50
|
+
console.log(`[rust] Looking for binary: ${binaryName}`);
|
|
51
|
+
console.log(`[rust] Search paths:`);
|
|
52
|
+
}
|
|
53
|
+
for (const p of searchPaths) {
|
|
54
|
+
if (verbose) console.log(`[rust] - ${p}: ${existsSync(p) ? "FOUND" : "not found"}`);
|
|
55
|
+
if (existsSync(p)) return p;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Locate the `ay-spawn-hidden` launcher (Windows-only). Returns undefined off
|
|
60
|
+
* Windows, or when the launcher isn't present — older installs, or a release
|
|
61
|
+
* that predates it. Callers MUST fall back to spawning the program directly.
|
|
62
|
+
*
|
|
63
|
+
* The launcher is a second `[[bin]]` built alongside `agent-yes`, so it sits
|
|
64
|
+
* next to the Rust binary in every install shape: the cargo `target/` build
|
|
65
|
+
* dir, the downloaded release bin dir (getBinDir), and `~/.cargo/bin` on PATH.
|
|
66
|
+
*/
|
|
67
|
+
function findSpawnHiddenLauncher() {
|
|
68
|
+
if (process.platform !== "win32") return void 0;
|
|
69
|
+
const dir = import.meta.dirname ?? import.meta.dir;
|
|
70
|
+
const searchPaths = [
|
|
71
|
+
path.resolve(dir, "../rs/target/release/ay-spawn-hidden.exe"),
|
|
72
|
+
path.resolve(dir, "../rs/target/debug/ay-spawn-hidden.exe"),
|
|
73
|
+
path.join(getBinDir(), "ay-spawn-hidden.exe"),
|
|
74
|
+
Bun.which("ay-spawn-hidden") ?? ""
|
|
75
|
+
];
|
|
76
|
+
for (const p of searchPaths) if (p && existsSync(p)) return p;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get GitHub release download URL for the binary
|
|
80
|
+
*/
|
|
81
|
+
function getDownloadUrl(version = "latest") {
|
|
82
|
+
const binaryName = getBinaryName().replace(/\.exe$/, "");
|
|
83
|
+
const ext = process.platform === "win32" ? ".zip" : ".tar.gz";
|
|
84
|
+
if (version === "latest") return `https://github.com/snomiao/agent-yes/releases/latest/download/${binaryName}${ext}`;
|
|
85
|
+
return `https://github.com/snomiao/agent-yes/releases/download/v${version}/${binaryName}${ext}`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Download and extract the binary
|
|
89
|
+
*/
|
|
90
|
+
async function downloadBinary(verbose = false) {
|
|
91
|
+
const binDir = getBinDir();
|
|
92
|
+
const binaryName = getBinaryName();
|
|
93
|
+
const binaryPath = path.join(binDir, binaryName);
|
|
94
|
+
mkdirSync(binDir, { recursive: true });
|
|
95
|
+
const url = getDownloadUrl(getInstalledPackage().version);
|
|
96
|
+
if (verbose) console.log(`[rust] Downloading binary from: ${url}`);
|
|
97
|
+
const response = await fetch(url);
|
|
98
|
+
if (!response.ok) throw new Error(`Failed to download binary: ${response.status} ${response.statusText}`);
|
|
99
|
+
if (process.platform === "win32") {
|
|
100
|
+
const tempZipPath = path.join(binDir, "temp.zip");
|
|
101
|
+
await Bun.write(tempZipPath, await response.arrayBuffer());
|
|
102
|
+
await Bun.spawn([
|
|
103
|
+
"powershell",
|
|
104
|
+
"-Command",
|
|
105
|
+
`Expand-Archive -Path '${tempZipPath}' -DestinationPath '${binDir}' -Force`
|
|
106
|
+
], {
|
|
107
|
+
cwd: binDir,
|
|
108
|
+
stdio: [
|
|
109
|
+
"ignore",
|
|
110
|
+
"pipe",
|
|
111
|
+
"pipe"
|
|
112
|
+
]
|
|
113
|
+
}).exited;
|
|
114
|
+
try {
|
|
115
|
+
unlinkSync(tempZipPath);
|
|
116
|
+
} catch {}
|
|
117
|
+
} else {
|
|
118
|
+
const tarPath = path.join(binDir, "temp.tar.gz");
|
|
119
|
+
await Bun.write(tarPath, await response.arrayBuffer());
|
|
120
|
+
await Bun.spawn([
|
|
121
|
+
"tar",
|
|
122
|
+
"-xzf",
|
|
123
|
+
tarPath,
|
|
124
|
+
"-C",
|
|
125
|
+
binDir
|
|
126
|
+
], {
|
|
127
|
+
cwd: binDir,
|
|
128
|
+
stdio: [
|
|
129
|
+
"ignore",
|
|
130
|
+
"pipe",
|
|
131
|
+
"pipe"
|
|
132
|
+
]
|
|
133
|
+
}).exited;
|
|
134
|
+
const possibleNames = [
|
|
135
|
+
"agent-yes",
|
|
136
|
+
binaryName.replace(/-musl$/, "").replace(/-gnu$/, ""),
|
|
137
|
+
binaryName
|
|
138
|
+
];
|
|
139
|
+
for (const name of possibleNames) {
|
|
140
|
+
const extractedPath = path.join(binDir, name);
|
|
141
|
+
if (existsSync(extractedPath) && extractedPath !== binaryPath) {
|
|
142
|
+
try {
|
|
143
|
+
await copyFile(extractedPath, binaryPath);
|
|
144
|
+
unlinkSync(extractedPath);
|
|
145
|
+
} catch {}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
unlinkSync(tarPath);
|
|
151
|
+
} catch {}
|
|
152
|
+
await chmod(binaryPath, 493);
|
|
153
|
+
}
|
|
154
|
+
if (verbose) console.log(`[rust] Binary downloaded to: ${binaryPath}`);
|
|
155
|
+
return binaryPath;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get the version of a Rust binary by running it with --version
|
|
159
|
+
*/
|
|
160
|
+
function getRustBinaryVersion(binaryPath) {
|
|
161
|
+
try {
|
|
162
|
+
const match = execFileSync(binaryPath, ["--version"], {
|
|
163
|
+
timeout: 5e3,
|
|
164
|
+
encoding: "utf8",
|
|
165
|
+
stdio: [
|
|
166
|
+
"ignore",
|
|
167
|
+
"pipe",
|
|
168
|
+
"ignore"
|
|
169
|
+
]
|
|
170
|
+
}).match(/(\d+\.\d+\.\d+)/);
|
|
171
|
+
return match ? match[1] ?? null : null;
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if a binary path is inside a git repo (dev build), and rebuild if outdated.
|
|
178
|
+
* Returns the same path if up-to-date or rebuilt, undefined if rebuild failed.
|
|
179
|
+
*/
|
|
180
|
+
function autoRebuildIfOutdated(binaryPath, verbose) {
|
|
181
|
+
if (!binaryPath.includes("/target/release") && !binaryPath.includes("/target/debug")) return true;
|
|
182
|
+
const binaryVersion = getRustBinaryVersion(binaryPath);
|
|
183
|
+
const pkgVersion = getInstalledPackage().version;
|
|
184
|
+
if (verbose) console.log(`[rust] Binary version: ${binaryVersion}, package version: ${pkgVersion}`);
|
|
185
|
+
if (binaryVersion === pkgVersion) return true;
|
|
186
|
+
const rsDir = binaryPath.replace(/\/target\/(release|debug)\/agent-yes.*$/, "");
|
|
187
|
+
if (!existsSync(path.join(rsDir, "Cargo.toml"))) {
|
|
188
|
+
if (verbose) console.log(`[rust] Cannot find Cargo.toml at ${rsDir}, skipping rebuild`);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
process.stderr.write(`\x1b[33m[rust] Binary outdated (${binaryVersion ?? "unknown"} → ${pkgVersion}), rebuilding…\x1b[0m\n`);
|
|
192
|
+
try {
|
|
193
|
+
execFileSync("cargo", ["build", ...binaryPath.includes("/target/release") ? ["--release"] : []], {
|
|
194
|
+
cwd: rsDir,
|
|
195
|
+
stdio: "inherit",
|
|
196
|
+
timeout: 3e5
|
|
197
|
+
});
|
|
198
|
+
process.stderr.write(`\x1b[32m[rust] Rebuild complete\x1b[0m\n`);
|
|
199
|
+
return true;
|
|
200
|
+
} catch {
|
|
201
|
+
process.stderr.write(`\x1b[31m[rust] Auto-rebuild failed, using outdated binary\x1b[0m\n`);
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get or download the Rust binary
|
|
207
|
+
*/
|
|
208
|
+
async function getRustBinary(options = {}) {
|
|
209
|
+
const { verbose = false, forceDownload = false } = options;
|
|
210
|
+
if (!forceDownload) {
|
|
211
|
+
const existing = findRustBinary(verbose);
|
|
212
|
+
if (existing) {
|
|
213
|
+
if (verbose) console.log(`[rust] Using existing binary: ${existing}`);
|
|
214
|
+
autoRebuildIfOutdated(existing, verbose);
|
|
215
|
+
return existing;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (verbose) console.log(`[rust] Binary not found, downloading...`);
|
|
219
|
+
try {
|
|
220
|
+
return await downloadBinary(verbose);
|
|
221
|
+
} catch (err) {
|
|
222
|
+
throw new Error(`Failed to get Rust binary: ${err instanceof Error ? err.message : err}\nYou can build manually with: cd rs && cargo build --release`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
//#endregion
|
|
227
|
+
export { getRustBinary as n, findSpawnHiddenLauncher as t };
|
|
228
|
+
//# sourceMappingURL=rustBinary-mYbyV0SD.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-WHYKp13w.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
4
|
-
import "./pidStore-
|
|
5
|
-
import "./globalPidIndex-
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
7
|
-
import {
|
|
3
|
+
import "./versionChecker-BoPKPL9B.js";
|
|
4
|
+
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
+
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D6MArV7A.js";
|
|
7
|
+
import { d as resolveSpawnCwd } from "./workspaceConfig-BgqK-31W.js";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
|
|
10
10
|
//#region ts/oxmgrService.ts
|
|
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
|
|
|
141
141
|
|
|
142
142
|
//#endregion
|
|
143
143
|
export { cmdSchedule };
|
|
144
|
-
//# sourceMappingURL=schedule-
|
|
144
|
+
//# sourceMappingURL=schedule-C5nUV0GO.js.map
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-WHYKp13w.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
4
|
-
import "./
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import "./
|
|
8
|
-
import
|
|
9
|
-
import "./
|
|
10
|
-
import "./
|
|
11
|
-
import "./
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import { r as
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-BoPKPL9B.js";
|
|
4
|
+
import { t as findSpawnHiddenLauncher } from "./rustBinary-mYbyV0SD.js";
|
|
5
|
+
import "./pidStore-BIvsBQ8X.js";
|
|
6
|
+
import { a as updateGlobalPidStatus } from "./globalPidIndex-CoNr7tS8.js";
|
|
7
|
+
import { t as pgidForWrapper } from "./reaper-CWF2_ATd.js";
|
|
8
|
+
import "./configShared-0MnIQ652.js";
|
|
9
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D6MArV7A.js";
|
|
10
|
+
import { A as resolveOne, E as readPtysize, F as snapshotStatus, H as TYPING_BADGE, O as renderRawLog, S as listRecords, T as readNotes, V as writeToIpc, b as isUserTyping, f as extractNeedsInput, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, u as extractBadges } from "./subcommands-CtWxwydR.js";
|
|
11
|
+
import "./e2e-jb0Hp43q.js";
|
|
12
|
+
import "./webrtcLink-B7REGtK2.js";
|
|
13
|
+
import "./remotes-CC-4GuJb.js";
|
|
14
|
+
import { a as getSpawnHook, c as hasProvisionHook, d as resolveSpawnCwd, i as getProvisionRoot, l as hasSpawnHook, r as getProvisionHook, u as isProvisionAllowed } from "./workspaceConfig-BgqK-31W.js";
|
|
15
|
+
import { r as spawnRejectionReason } from "./spawnGate-IJDByl2U.js";
|
|
15
16
|
import yargs from "yargs";
|
|
16
17
|
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
17
18
|
import { homedir, hostname, userInfo } from "os";
|
|
@@ -148,6 +149,70 @@ function freshAgentEnv() {
|
|
|
148
149
|
}
|
|
149
150
|
return env;
|
|
150
151
|
}
|
|
152
|
+
function originOwnerRepo(cwd) {
|
|
153
|
+
try {
|
|
154
|
+
const r = Bun.spawnSync([
|
|
155
|
+
"git",
|
|
156
|
+
"-C",
|
|
157
|
+
cwd,
|
|
158
|
+
"remote",
|
|
159
|
+
"get-url",
|
|
160
|
+
"origin"
|
|
161
|
+
]);
|
|
162
|
+
if (r.exitCode !== 0) return null;
|
|
163
|
+
const m = new TextDecoder().decode(r.stdout).trim().match(/github\.com[:/]([^/]+)\/(.+?)(?:\.git)?\/?$/i);
|
|
164
|
+
return m && m[1] && m[2] ? {
|
|
165
|
+
owner: m[1],
|
|
166
|
+
repo: m[2]
|
|
167
|
+
} : null;
|
|
168
|
+
} catch {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function runProvisionHook(cwd, koho) {
|
|
173
|
+
const hook = getProvisionHook();
|
|
174
|
+
if (!hook) return { ran: false };
|
|
175
|
+
const shell = process.env.AGENT_YES_PROVISION_SHELL?.trim() || process.env.AGENT_YES_SPAWN_SHELL?.trim() || "/bin/sh";
|
|
176
|
+
const outPath = path.join(agentYesHome(), `provision-hook-${process.pid}-${performance.now().toString(36).replace(".", "")}.log`);
|
|
177
|
+
const timeoutMs = Number(process.env.AGENT_YES_PROVISION_HOOK_TIMEOUT_MS) || 6e4;
|
|
178
|
+
let code = null;
|
|
179
|
+
try {
|
|
180
|
+
const child = Bun.spawn([
|
|
181
|
+
shell,
|
|
182
|
+
"-c",
|
|
183
|
+
`set -e\n${hook}`
|
|
184
|
+
], {
|
|
185
|
+
cwd,
|
|
186
|
+
env: {
|
|
187
|
+
...freshAgentEnv(),
|
|
188
|
+
...koho
|
|
189
|
+
},
|
|
190
|
+
stdin: "ignore",
|
|
191
|
+
stdout: Bun.file(outPath),
|
|
192
|
+
stderr: Bun.file(outPath)
|
|
193
|
+
});
|
|
194
|
+
code = await Promise.race([child.exited, new Promise((r) => setTimeout(() => r(124), timeoutMs))]);
|
|
195
|
+
if (code === 124) child.kill();
|
|
196
|
+
} catch (e) {
|
|
197
|
+
return {
|
|
198
|
+
ran: true,
|
|
199
|
+
ok: false,
|
|
200
|
+
code: null,
|
|
201
|
+
detail: e.message
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
let detail = "";
|
|
205
|
+
try {
|
|
206
|
+
detail = (await Bun.file(outPath).text()).slice(0, 4096).trimEnd();
|
|
207
|
+
} catch {}
|
|
208
|
+
await unlink(outPath).catch(() => {});
|
|
209
|
+
return {
|
|
210
|
+
ran: true,
|
|
211
|
+
ok: code === 0,
|
|
212
|
+
code,
|
|
213
|
+
detail
|
|
214
|
+
};
|
|
215
|
+
}
|
|
151
216
|
const DAEMON_NAME = "agent-yes";
|
|
152
217
|
function resolveDaemonManager() {
|
|
153
218
|
const oxmgr = Bun.which("oxmgr");
|
|
@@ -308,7 +373,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
308
373
|
let shareLink = null;
|
|
309
374
|
let shareLinkMinted = false;
|
|
310
375
|
if (webrtcDaemon) try {
|
|
311
|
-
const { loadOrCreateShareRoom, shareLinkFromRoomUrl } = await import("./share-
|
|
376
|
+
const { loadOrCreateShareRoom, shareLinkFromRoomUrl } = await import("./share-QregR8a_.js");
|
|
312
377
|
const explicit = explicitWebrtcUrl(effArgs);
|
|
313
378
|
shareLink = shareLinkFromRoomUrl(explicit ?? await loadOrCreateShareRoom());
|
|
314
379
|
shareLinkMinted = !explicit;
|
|
@@ -317,7 +382,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
317
382
|
if (!webrtcDaemon) return;
|
|
318
383
|
if (shareLink) {
|
|
319
384
|
process.stdout.write(`\nshared over WebRTC — open this link (the token is eaten from the URL on open):\n ${shareLink}\n` + (shareLinkMinted ? ` (persistent room — same link across restarts; delete ~/.agent-yes/.share-room to rotate)\n` : ``));
|
|
320
|
-
const { offerOpenInBrowser } = await import("./openBrowser-
|
|
385
|
+
const { offerOpenInBrowser } = await import("./openBrowser-ChR4llYa.js");
|
|
321
386
|
await offerOpenInBrowser(shareLink);
|
|
322
387
|
} else process.stdout.write("\nthe WebRTC share link carries a secret, so the daemon does NOT log it —\nread it from ~/.agent-yes/.share-link (mode 0600). The room persists in\n~/.agent-yes/.share-room, so the link survives restarts.\n");
|
|
323
388
|
};
|
|
@@ -343,6 +408,8 @@ async function cmdServeDaemon(sub, args) {
|
|
|
343
408
|
]);
|
|
344
409
|
}
|
|
345
410
|
const serveArgv = ayServeArgv(effArgs);
|
|
411
|
+
const spawnHidden = findSpawnHiddenLauncher();
|
|
412
|
+
const managedArgv = spawnHidden ? [spawnHidden, ...serveArgv] : serveArgv;
|
|
346
413
|
const oxmgrHealth = webrtcDaemon && mgr.id === "oxmgr" ? [
|
|
347
414
|
"--health-cmd",
|
|
348
415
|
ayServeArgv(["healthcheck"]).join(" "),
|
|
@@ -356,7 +423,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
356
423
|
const startArgv = mgr.id === "oxmgr" ? [
|
|
357
424
|
mgr.bin,
|
|
358
425
|
"start",
|
|
359
|
-
|
|
426
|
+
managedArgv.join(" "),
|
|
360
427
|
"--name",
|
|
361
428
|
DAEMON_NAME,
|
|
362
429
|
"--restart",
|
|
@@ -367,7 +434,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
367
434
|
] : [
|
|
368
435
|
mgr.bin,
|
|
369
436
|
"start",
|
|
370
|
-
|
|
437
|
+
managedArgv[0],
|
|
371
438
|
"--name",
|
|
372
439
|
DAEMON_NAME,
|
|
373
440
|
"--interpreter",
|
|
@@ -375,7 +442,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
375
442
|
"--exp-backoff-restart-delay",
|
|
376
443
|
"200",
|
|
377
444
|
"--",
|
|
378
|
-
...
|
|
445
|
+
...managedArgv.slice(1)
|
|
379
446
|
];
|
|
380
447
|
const code = await Bun.spawn(startArgv, { stdio: [
|
|
381
448
|
"ignore",
|
|
@@ -781,14 +848,18 @@ Options:
|
|
|
781
848
|
const withMeta = async (r) => {
|
|
782
849
|
const status = await deriveLiveStatus(r);
|
|
783
850
|
const question = status !== "exited" && !r.unresponsive ? await logNeedsInput(r.log_file, r.cli) : null;
|
|
851
|
+
const lastActiveAt = r.log_file ? await stat(r.log_file).then((s) => s.mtimeMs).catch(() => r.started_at) : r.started_at;
|
|
852
|
+
const lastStdinAt = status !== "exited" && r.fifo_file ? await stat(r.fifo_file).then((s) => s.mtimeMs).catch(() => null) : null;
|
|
784
853
|
return {
|
|
785
854
|
...r,
|
|
855
|
+
last_active_at: lastActiveAt,
|
|
856
|
+
last_stdin_at: lastStdinAt,
|
|
786
857
|
status: status === "exited" ? status : r.unresponsive ? "stuck" : question ? "needs_input" : status,
|
|
787
858
|
question,
|
|
788
859
|
title: await logTitle(r.log_file),
|
|
789
860
|
git: status === "exited" ? null : await gitStatus(r.cwd),
|
|
790
861
|
tasks: status === "exited" ? null : await logTasks(r.log_file),
|
|
791
|
-
badges: status === "exited" ? [] : await logBadges(r.log_file)
|
|
862
|
+
badges: status === "exited" ? [] : await logBadges(r.log_file).then(async (b) => await isUserTyping(r.pid) ? [...b, TYPING_BADGE.id] : b)
|
|
792
863
|
};
|
|
793
864
|
};
|
|
794
865
|
const presence = /* @__PURE__ */ new Map();
|
|
@@ -894,7 +965,10 @@ Options:
|
|
|
894
965
|
return Response.json({ host: user ? `${user}@${host}` : host });
|
|
895
966
|
}
|
|
896
967
|
if (req.method === "GET" && p === "/api/version") return Response.json({ version: getInstalledPackage().version });
|
|
897
|
-
if (req.method === "GET" && p === "/api/spawn-config") return Response.json({
|
|
968
|
+
if (req.method === "GET" && p === "/api/spawn-config") return Response.json({
|
|
969
|
+
hasSpawnHook: hasSpawnHook(),
|
|
970
|
+
hasProvisionHook: hasProvisionHook()
|
|
971
|
+
});
|
|
898
972
|
if (req.method === "GET" && p === "/api/notes") {
|
|
899
973
|
const notes = await readNotes();
|
|
900
974
|
return Response.json(Object.fromEntries(notes));
|
|
@@ -1104,7 +1178,9 @@ Options:
|
|
|
1104
1178
|
const record = await resolveOne(keyword, defaultOpts({ all: true }));
|
|
1105
1179
|
const args = ["restart", String(record.pid)];
|
|
1106
1180
|
if (body.fresh) args.push("--fresh");
|
|
1107
|
-
Bun.
|
|
1181
|
+
const ayBin = Bun.which("ay") ?? process.argv[1];
|
|
1182
|
+
const ayCmd = process.platform === "win32" && ayBin.toLowerCase().endsWith(".exe") ? [ayBin] : [process.execPath, ayBin];
|
|
1183
|
+
Bun.spawn([...ayCmd, ...args], {
|
|
1108
1184
|
cwd: record.cwd,
|
|
1109
1185
|
detached: true,
|
|
1110
1186
|
stdio: [
|
|
@@ -1206,6 +1282,16 @@ Options:
|
|
|
1206
1282
|
} catch (e) {
|
|
1207
1283
|
return new Response(`fork needs the 'codehost' package (codehost/provision) — install it (npm i -g codehost) or 'bun link' it for local dev: ${e.message}`, { status: 501 });
|
|
1208
1284
|
}
|
|
1285
|
+
const forkOrigin = originOwnerRepo(fork.fromCwd);
|
|
1286
|
+
const forkHook = await runProvisionHook(fork.fromCwd, {
|
|
1287
|
+
KOHO_ACTION: "fork",
|
|
1288
|
+
KOHO_FROM_CWD: fork.fromCwd,
|
|
1289
|
+
KOHO_BRANCH: fork.branch,
|
|
1290
|
+
KOHO_OWNER: forkOrigin?.owner ?? "",
|
|
1291
|
+
KOHO_REPO: forkOrigin?.repo ?? "",
|
|
1292
|
+
KOHO_WS_ROOT: getProvisionRoot() ?? ""
|
|
1293
|
+
});
|
|
1294
|
+
if (forkHook.ran && !forkHook.ok) return new Response(`provision hook denied this fork (exit ${forkHook.code})` + (forkHook.detail ? `:\n${forkHook.detail}` : ""), { status: 403 });
|
|
1209
1295
|
let result;
|
|
1210
1296
|
try {
|
|
1211
1297
|
const wsRoot = getProvisionRoot();
|
|
@@ -1218,7 +1304,7 @@ Options:
|
|
|
1218
1304
|
return new Response(`fork failed: ${e.message}`, { status: 502 });
|
|
1219
1305
|
}
|
|
1220
1306
|
if (!result?.ok) return new Response(result?.error ?? "fork failed", { status: 502 });
|
|
1221
|
-
if (result.spec && !isProvisionAllowed(result.spec.owner, result.spec.repo)) return new Response(`forking '${result.spec.owner}/${result.spec.repo}' is not allowed — add the owner to provisionAllowlist in ~/.agent-yes/config.json (or "*" to allow all)`, { status: 403 });
|
|
1307
|
+
if (!forkHook.ran && result.spec && !isProvisionAllowed(result.spec.owner, result.spec.repo)) return new Response(`forking '${result.spec.owner}/${result.spec.repo}' is not allowed — add the owner to provisionAllowlist in ~/.agent-yes/config.json (or "*" to allow all), or set a provisionHook to gate it yourself`, { status: 403 });
|
|
1222
1308
|
cwd = result.folder;
|
|
1223
1309
|
provisioned = {
|
|
1224
1310
|
action: result.action,
|
|
@@ -1238,7 +1324,17 @@ Options:
|
|
|
1238
1324
|
spec = null;
|
|
1239
1325
|
}
|
|
1240
1326
|
if (!spec) return new Response(`unrecognized spawn source: ${from}`, { status: 400 });
|
|
1241
|
-
|
|
1327
|
+
const fromHook = await runProvisionHook(getProvisionRoot() ?? homedir(), {
|
|
1328
|
+
KOHO_ACTION: "from",
|
|
1329
|
+
KOHO_SOURCE: from,
|
|
1330
|
+
KOHO_OWNER: spec.owner,
|
|
1331
|
+
KOHO_REPO: spec.repo,
|
|
1332
|
+
KOHO_BRANCH: spec.branch,
|
|
1333
|
+
KOHO_WS_ROOT: getProvisionRoot() ?? ""
|
|
1334
|
+
});
|
|
1335
|
+
if (fromHook.ran) {
|
|
1336
|
+
if (!fromHook.ok) return new Response(`provision hook denied '${spec.owner}/${spec.repo}' (exit ${fromHook.code})` + (fromHook.detail ? `:\n${fromHook.detail}` : ""), { status: 403 });
|
|
1337
|
+
} else if (!isProvisionAllowed(spec.owner, spec.repo)) return new Response(`provisioning '${spec.owner}/${spec.repo}' is not allowed — add the owner to provisionAllowlist in ~/.agent-yes/config.json (or "*" to allow all), or set a provisionHook to gate it yourself`, { status: 403 });
|
|
1242
1338
|
let result;
|
|
1243
1339
|
try {
|
|
1244
1340
|
const wsRoot = getProvisionRoot();
|
|
@@ -1405,7 +1501,7 @@ Options:
|
|
|
1405
1501
|
const webrtcVal = argv.webrtc ?? argv.share;
|
|
1406
1502
|
const explicitUrl = typeof webrtcVal === "string" && webrtcVal.startsWith("webrtc://") ? webrtcVal : void 0;
|
|
1407
1503
|
try {
|
|
1408
|
-
const { startShare, loadOrCreateShareRoom } = await import("./share-
|
|
1504
|
+
const { startShare, loadOrCreateShareRoom } = await import("./share-QregR8a_.js");
|
|
1409
1505
|
const linkFile = path.join(process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"), ".share-link");
|
|
1410
1506
|
const announce = async (room, link, rotated) => {
|
|
1411
1507
|
const lead = rotated ? "the room was rejected by signaling (stale generation) — rotated to a fresh link" : "shared over WebRTC — open this link (the token is eaten from the URL on open)";
|
|
@@ -1413,7 +1509,7 @@ Options:
|
|
|
1413
1509
|
const persistNote = explicitUrl ? "\n" : ` (persistent room — same link across restarts; delete ~/.agent-yes/.share-room to rotate)\n\n`;
|
|
1414
1510
|
process.stdout.write(`${wantHttp ? "\n" : ""}${lead}:\n ${link}\n` + persistNote);
|
|
1415
1511
|
if (!rotated) {
|
|
1416
|
-
const { offerOpenInBrowser } = await import("./openBrowser-
|
|
1512
|
+
const { offerOpenInBrowser } = await import("./openBrowser-ChR4llYa.js");
|
|
1417
1513
|
await offerOpenInBrowser(link);
|
|
1418
1514
|
}
|
|
1419
1515
|
} else {
|
|
@@ -1464,4 +1560,4 @@ Options:
|
|
|
1464
1560
|
|
|
1465
1561
|
//#endregion
|
|
1466
1562
|
export { cmdServe };
|
|
1467
|
-
//# sourceMappingURL=serve-
|
|
1563
|
+
//# sourceMappingURL=serve-ChcayCC3.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as setWorkspaceRoot, s as getWorkspaceRoot } from "./workspaceConfig-BgqK-31W.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-ChcayCC3.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-CCQZ9tPB.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as computeTranscriptHash, c as open$1, d as randomHex, f as seal, i as MAX_CHUNK, l as packEnvelope, n as FLAG_CONFIRM, o as deriveAuthToken, p as unpackEnvelope, r as MARKER, s as deriveDirKeys, t as CONFIRM_TIMEOUT_MS, u as parseSecret } from "./e2e-
|
|
1
|
+
import { a as computeTranscriptHash, c as open$1, d as randomHex, f as seal, i as MAX_CHUNK, l as packEnvelope, n as FLAG_CONFIRM, o as deriveAuthToken, p as unpackEnvelope, r as MARKER, s as deriveDirKeys, t as CONFIRM_TIMEOUT_MS, u as parseSecret } from "./e2e-jb0Hp43q.js";
|
|
2
2
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import path from "path";
|
|
@@ -534,4 +534,4 @@ async function startShare(opts) {
|
|
|
534
534
|
|
|
535
535
|
//#endregion
|
|
536
536
|
export { loadOrCreateShareRoom, shareLinkFromRoomUrl, startShare };
|
|
537
|
-
//# sourceMappingURL=share-
|
|
537
|
+
//# sourceMappingURL=share-QregR8a_.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as readGlobalPids } from "./globalPidIndex-
|
|
2
|
-
import {
|
|
1
|
+
import { i as readGlobalPids } from "./globalPidIndex-CoNr7tS8.js";
|
|
2
|
+
import { n as getMinFreeMb, o as getSpawnWaitMs, t as getMaxAgents } from "./workspaceConfig-BgqK-31W.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-IJDByl2U.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "./logger-CDIsZ-Pp.js";
|
|
2
|
+
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
|
+
import "./configShared-0MnIQ652.js";
|
|
4
|
+
import { A as resolveOne, B as writeKeysPaced, C as matchKeyword, D as renderLogTailLines, E as readPtysize, F as snapshotStatus, I as stdinActivityPath, L as stopTipForCli, M as resolveResumeArgs, N as restartHintLines, O as renderRawLog, P as runSubcommand, R as submitAndConfirm, S as listRecords, T as readNotes, V as writeToIpc, _ as isPidAlive, a as cmdHelp, b as isUserTyping, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as resolveReadWindow, k as renderRawLogLines, 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 menuSelectKeys, x as lastStdinAt, y as isSubcommand, z as waitForLogQuiet } from "./subcommands-CtWxwydR.js";
|
|
5
|
+
import "./e2e-jb0Hp43q.js";
|
|
6
|
+
import "./webrtcLink-B7REGtK2.js";
|
|
7
|
+
import "./remotes-CC-4GuJb.js";
|
|
8
|
+
|
|
9
|
+
export { cmdHelp, isSubcommand, runSubcommand };
|