agent-yes 1.169.1 → 1.170.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{SUPPORTED_CLIS-Bwg9VqLI.js → SUPPORTED_CLIS-ByppVvWO.js} +2 -2
- package/dist/SUPPORTED_CLIS-C_c097RZ.js +8 -0
- 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-D5jtpCAR.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-DsO0IlNq.js +228 -0
- package/dist/{schedule-CtVvSyaN.js → schedule-ChTPIcXf.js} +7 -7
- package/dist/{serve-CLmk5ujF.js → serve-De1gAWNI.js} +120 -26
- package/dist/{setup-CYbXOcpH.js → setup-nlMqyEPB.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--EUush_X.js → subcommands-BFlpV23b.js} +1049 -44
- package/dist/subcommands-DLDpwrfG.js +9 -0
- package/dist/{tray-CWUpaZF4.js → tray-DXr7iK3E.js} +2 -2
- package/dist/{ts-Bbhf5JbN.js → ts-DsxejviJ.js} +8 -8
- package/dist/{versionChecker-BmWkWhcJ.js → versionChecker-Czk3aHqy.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 +79 -10
- package/lab/ui/index.html +174 -8
- 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 +180 -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-Czk3aHqy.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-DsO0IlNq.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-DsxejviJ.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-Czk3aHqy.js";
|
|
4
|
+
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
+
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-ByppVvWO.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-ChTPIcXf.js.map
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-DsxejviJ.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-Czk3aHqy.js";
|
|
4
|
+
import { t as findSpawnHiddenLauncher } from "./rustBinary-DsO0IlNq.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-ByppVvWO.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-BFlpV23b.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,16 @@ 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;
|
|
784
852
|
return {
|
|
785
853
|
...r,
|
|
854
|
+
last_active_at: lastActiveAt,
|
|
786
855
|
status: status === "exited" ? status : r.unresponsive ? "stuck" : question ? "needs_input" : status,
|
|
787
856
|
question,
|
|
788
857
|
title: await logTitle(r.log_file),
|
|
789
858
|
git: status === "exited" ? null : await gitStatus(r.cwd),
|
|
790
859
|
tasks: status === "exited" ? null : await logTasks(r.log_file),
|
|
791
|
-
badges: status === "exited" ? [] : await logBadges(r.log_file)
|
|
860
|
+
badges: status === "exited" ? [] : await logBadges(r.log_file).then(async (b) => await isUserTyping(r.pid) ? [...b, TYPING_BADGE.id] : b)
|
|
792
861
|
};
|
|
793
862
|
};
|
|
794
863
|
const presence = /* @__PURE__ */ new Map();
|
|
@@ -894,7 +963,10 @@ Options:
|
|
|
894
963
|
return Response.json({ host: user ? `${user}@${host}` : host });
|
|
895
964
|
}
|
|
896
965
|
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({
|
|
966
|
+
if (req.method === "GET" && p === "/api/spawn-config") return Response.json({
|
|
967
|
+
hasSpawnHook: hasSpawnHook(),
|
|
968
|
+
hasProvisionHook: hasProvisionHook()
|
|
969
|
+
});
|
|
898
970
|
if (req.method === "GET" && p === "/api/notes") {
|
|
899
971
|
const notes = await readNotes();
|
|
900
972
|
return Response.json(Object.fromEntries(notes));
|
|
@@ -1104,7 +1176,9 @@ Options:
|
|
|
1104
1176
|
const record = await resolveOne(keyword, defaultOpts({ all: true }));
|
|
1105
1177
|
const args = ["restart", String(record.pid)];
|
|
1106
1178
|
if (body.fresh) args.push("--fresh");
|
|
1107
|
-
Bun.
|
|
1179
|
+
const ayBin = Bun.which("ay") ?? process.argv[1];
|
|
1180
|
+
const ayCmd = process.platform === "win32" && ayBin.toLowerCase().endsWith(".exe") ? [ayBin] : [process.execPath, ayBin];
|
|
1181
|
+
Bun.spawn([...ayCmd, ...args], {
|
|
1108
1182
|
cwd: record.cwd,
|
|
1109
1183
|
detached: true,
|
|
1110
1184
|
stdio: [
|
|
@@ -1206,6 +1280,16 @@ Options:
|
|
|
1206
1280
|
} catch (e) {
|
|
1207
1281
|
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
1282
|
}
|
|
1283
|
+
const forkOrigin = originOwnerRepo(fork.fromCwd);
|
|
1284
|
+
const forkHook = await runProvisionHook(fork.fromCwd, {
|
|
1285
|
+
KOHO_ACTION: "fork",
|
|
1286
|
+
KOHO_FROM_CWD: fork.fromCwd,
|
|
1287
|
+
KOHO_BRANCH: fork.branch,
|
|
1288
|
+
KOHO_OWNER: forkOrigin?.owner ?? "",
|
|
1289
|
+
KOHO_REPO: forkOrigin?.repo ?? "",
|
|
1290
|
+
KOHO_WS_ROOT: getProvisionRoot() ?? ""
|
|
1291
|
+
});
|
|
1292
|
+
if (forkHook.ran && !forkHook.ok) return new Response(`provision hook denied this fork (exit ${forkHook.code})` + (forkHook.detail ? `:\n${forkHook.detail}` : ""), { status: 403 });
|
|
1209
1293
|
let result;
|
|
1210
1294
|
try {
|
|
1211
1295
|
const wsRoot = getProvisionRoot();
|
|
@@ -1218,7 +1302,7 @@ Options:
|
|
|
1218
1302
|
return new Response(`fork failed: ${e.message}`, { status: 502 });
|
|
1219
1303
|
}
|
|
1220
1304
|
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 });
|
|
1305
|
+
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
1306
|
cwd = result.folder;
|
|
1223
1307
|
provisioned = {
|
|
1224
1308
|
action: result.action,
|
|
@@ -1238,7 +1322,17 @@ Options:
|
|
|
1238
1322
|
spec = null;
|
|
1239
1323
|
}
|
|
1240
1324
|
if (!spec) return new Response(`unrecognized spawn source: ${from}`, { status: 400 });
|
|
1241
|
-
|
|
1325
|
+
const fromHook = await runProvisionHook(getProvisionRoot() ?? homedir(), {
|
|
1326
|
+
KOHO_ACTION: "from",
|
|
1327
|
+
KOHO_SOURCE: from,
|
|
1328
|
+
KOHO_OWNER: spec.owner,
|
|
1329
|
+
KOHO_REPO: spec.repo,
|
|
1330
|
+
KOHO_BRANCH: spec.branch,
|
|
1331
|
+
KOHO_WS_ROOT: getProvisionRoot() ?? ""
|
|
1332
|
+
});
|
|
1333
|
+
if (fromHook.ran) {
|
|
1334
|
+
if (!fromHook.ok) return new Response(`provision hook denied '${spec.owner}/${spec.repo}' (exit ${fromHook.code})` + (fromHook.detail ? `:\n${fromHook.detail}` : ""), { status: 403 });
|
|
1335
|
+
} 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
1336
|
let result;
|
|
1243
1337
|
try {
|
|
1244
1338
|
const wsRoot = getProvisionRoot();
|
|
@@ -1405,7 +1499,7 @@ Options:
|
|
|
1405
1499
|
const webrtcVal = argv.webrtc ?? argv.share;
|
|
1406
1500
|
const explicitUrl = typeof webrtcVal === "string" && webrtcVal.startsWith("webrtc://") ? webrtcVal : void 0;
|
|
1407
1501
|
try {
|
|
1408
|
-
const { startShare, loadOrCreateShareRoom } = await import("./share-
|
|
1502
|
+
const { startShare, loadOrCreateShareRoom } = await import("./share-QregR8a_.js");
|
|
1409
1503
|
const linkFile = path.join(process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"), ".share-link");
|
|
1410
1504
|
const announce = async (room, link, rotated) => {
|
|
1411
1505
|
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 +1507,7 @@ Options:
|
|
|
1413
1507
|
const persistNote = explicitUrl ? "\n" : ` (persistent room — same link across restarts; delete ~/.agent-yes/.share-room to rotate)\n\n`;
|
|
1414
1508
|
process.stdout.write(`${wantHttp ? "\n" : ""}${lead}:\n ${link}\n` + persistNote);
|
|
1415
1509
|
if (!rotated) {
|
|
1416
|
-
const { offerOpenInBrowser } = await import("./openBrowser-
|
|
1510
|
+
const { offerOpenInBrowser } = await import("./openBrowser-ChR4llYa.js");
|
|
1417
1511
|
await offerOpenInBrowser(link);
|
|
1418
1512
|
}
|
|
1419
1513
|
} else {
|
|
@@ -1464,4 +1558,4 @@ Options:
|
|
|
1464
1558
|
|
|
1465
1559
|
//#endregion
|
|
1466
1560
|
export { cmdServe };
|
|
1467
|
-
//# sourceMappingURL=serve-
|
|
1561
|
+
//# sourceMappingURL=serve-De1gAWNI.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-De1gAWNI.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-nlMqyEPB.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
|