claude-yes 1.72.2 → 1.72.4
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-D9eEHdvo.js → SUPPORTED_CLIS-Bqw9gxey.js} +2 -2
- package/dist/cli.js +50 -23
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/ts/JsonlStore.spec.ts +12 -3
- package/ts/cli.ts +3 -5
- package/ts/pidStore.spec.ts +20 -4
- package/ts/versionChecker.spec.ts +25 -2
- package/ts/versionChecker.ts +54 -20
|
@@ -815,7 +815,7 @@ function tryCatch(catchFn, fn) {
|
|
|
815
815
|
//#endregion
|
|
816
816
|
//#region package.json
|
|
817
817
|
var name = "agent-yes";
|
|
818
|
-
var version = "1.72.
|
|
818
|
+
var version = "1.72.4";
|
|
819
819
|
|
|
820
820
|
//#endregion
|
|
821
821
|
//#region ts/pty-fix.ts
|
|
@@ -1895,4 +1895,4 @@ const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
|
1895
1895
|
|
|
1896
1896
|
//#endregion
|
|
1897
1897
|
export { AgentContext as a, PidStore as c, config as i, removeControlCharacters as l, CLIS_CONFIG as n, name as o, agentYes as r, version as s, SUPPORTED_CLIS as t };
|
|
1898
|
-
//# sourceMappingURL=SUPPORTED_CLIS-
|
|
1898
|
+
//# sourceMappingURL=SUPPORTED_CLIS-Bqw9gxey.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
2
|
+
import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Bqw9gxey.js";
|
|
3
3
|
import { t as logger } from "./logger-CX77vJDA.js";
|
|
4
4
|
import { argv } from "process";
|
|
5
|
-
import { spawn } from "child_process";
|
|
5
|
+
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import ms from "ms";
|
|
7
7
|
import yargs from "yargs";
|
|
8
8
|
import { hideBin } from "yargs/helpers";
|
|
@@ -225,44 +225,72 @@ async function writeUpdateCache(data) {
|
|
|
225
225
|
await writeFile(CACHE_FILE, JSON.stringify(data));
|
|
226
226
|
}
|
|
227
227
|
function detectPackageManager() {
|
|
228
|
-
if (process.env.BUN_INSTALL || process.env.npm_execpath?.includes("bun")) return "bun";
|
|
228
|
+
if (process.env.BUN_INSTALL || process.execPath?.includes("bun") || process.env.npm_execpath?.includes("bun")) return "bun";
|
|
229
229
|
return "npm";
|
|
230
230
|
}
|
|
231
231
|
/**
|
|
232
|
-
* Check for updates
|
|
232
|
+
* Check for updates, auto-install if newer version is available, and re-exec
|
|
233
|
+
* so the current invocation always runs the latest code.
|
|
234
|
+
*
|
|
233
235
|
* Uses a 1-hour TTL cache to avoid hitting the registry on every run.
|
|
234
236
|
* All errors are swallowed — network issues must never break the tool.
|
|
235
237
|
* Set AGENT_YES_NO_UPDATE=1 to opt out.
|
|
238
|
+
*
|
|
239
|
+
* The AGENT_YES_UPDATED env var prevents infinite re-exec loops:
|
|
240
|
+
* after updating we re-exec with AGENT_YES_UPDATED=<version> so the
|
|
241
|
+
* new process skips the update check.
|
|
236
242
|
*/
|
|
237
243
|
async function checkAndAutoUpdate() {
|
|
238
244
|
if (process.env.AGENT_YES_NO_UPDATE) return;
|
|
245
|
+
if (process.env.AGENT_YES_UPDATED === version) return;
|
|
239
246
|
try {
|
|
247
|
+
let latestVersion;
|
|
240
248
|
const cache = await readUpdateCache();
|
|
241
|
-
if (cache && Date.now() - cache.checkedAt < TTL_MS)
|
|
242
|
-
|
|
243
|
-
|
|
249
|
+
if (cache && Date.now() - cache.checkedAt < TTL_MS) latestVersion = cache.latestVersion;
|
|
250
|
+
else {
|
|
251
|
+
const fetched = await fetchLatestVersion();
|
|
252
|
+
if (!fetched) return;
|
|
253
|
+
latestVersion = fetched;
|
|
254
|
+
await writeUpdateCache({
|
|
255
|
+
checkedAt: Date.now(),
|
|
256
|
+
latestVersion
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (compareVersions(version, latestVersion) < 0) {
|
|
260
|
+
if (await runInstall(latestVersion)) reExec(latestVersion);
|
|
244
261
|
}
|
|
245
|
-
const latestVersion = await fetchLatestVersion();
|
|
246
|
-
if (!latestVersion) return;
|
|
247
|
-
await writeUpdateCache({
|
|
248
|
-
checkedAt: Date.now(),
|
|
249
|
-
latestVersion
|
|
250
|
-
});
|
|
251
|
-
if (compareVersions(version, latestVersion) < 0) await runInstall(latestVersion);
|
|
252
262
|
} catch {}
|
|
253
263
|
}
|
|
254
264
|
async function runInstall(latestVersion) {
|
|
255
|
-
const
|
|
265
|
+
const installCmd = detectPackageManager() === "bun" ? `bun add -g agent-yes@${latestVersion}` : `npm install -g agent-yes@${latestVersion}`;
|
|
256
266
|
process.stderr.write(`\x1b[33m[agent-yes] Updating ${version} → ${latestVersion}…\x1b[0m\n`);
|
|
257
267
|
try {
|
|
258
|
-
await execaCommand(
|
|
259
|
-
await writeUpdateCache({
|
|
260
|
-
checkedAt: 0,
|
|
261
|
-
latestVersion
|
|
262
|
-
});
|
|
268
|
+
await execaCommand(installCmd, { stdio: "inherit" });
|
|
263
269
|
process.stderr.write(`\x1b[32m[agent-yes] Updated to ${latestVersion}\x1b[0m\n`);
|
|
270
|
+
return true;
|
|
264
271
|
} catch {
|
|
265
|
-
process.stderr.write(`\x1b[31m[agent-yes] Auto-update failed. Run: ${
|
|
272
|
+
process.stderr.write(`\x1b[31m[agent-yes] Auto-update failed. Run: ${installCmd}\x1b[0m\n`);
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Re-exec the current process so the newly installed version runs.
|
|
278
|
+
* Sets AGENT_YES_UPDATED=<version> to prevent an infinite loop.
|
|
279
|
+
*/
|
|
280
|
+
function reExec(version) {
|
|
281
|
+
const [bin, ...args] = process.argv;
|
|
282
|
+
process.stderr.write(`\x1b[36m[agent-yes] Restarting with v${version}…\x1b[0m\n`);
|
|
283
|
+
try {
|
|
284
|
+
execFileSync(bin, args, {
|
|
285
|
+
stdio: "inherit",
|
|
286
|
+
env: {
|
|
287
|
+
...process.env,
|
|
288
|
+
AGENT_YES_UPDATED: version
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
process.exit(0);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
process.exit(err.status ?? 1);
|
|
266
294
|
}
|
|
267
295
|
}
|
|
268
296
|
/**
|
|
@@ -478,7 +506,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
478
506
|
|
|
479
507
|
//#endregion
|
|
480
508
|
//#region ts/cli.ts
|
|
481
|
-
|
|
509
|
+
await checkAndAutoUpdate();
|
|
482
510
|
const config = parseCliArgs(process.argv);
|
|
483
511
|
if (config.tray) {
|
|
484
512
|
const { startTray } = await import("./tray-CPpdxTV-.js");
|
|
@@ -581,7 +609,6 @@ const { exitCode } = await cliYes({
|
|
|
581
609
|
...config,
|
|
582
610
|
autoYes: config.autoYes
|
|
583
611
|
});
|
|
584
|
-
await updateCheckPromise;
|
|
585
612
|
console.log("exiting process");
|
|
586
613
|
process.exit(exitCode ?? 1);
|
|
587
614
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as AgentContext, i as config, l as removeControlCharacters, n as CLIS_CONFIG, r as agentYes } from "./SUPPORTED_CLIS-
|
|
1
|
+
import { a as AgentContext, i as config, l as removeControlCharacters, n as CLIS_CONFIG, r as agentYes } from "./SUPPORTED_CLIS-Bqw9gxey.js";
|
|
2
2
|
import "./logger-CX77vJDA.js";
|
|
3
3
|
|
|
4
4
|
export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
|
package/package.json
CHANGED
package/ts/JsonlStore.spec.ts
CHANGED
|
@@ -2,21 +2,30 @@ import { describe, expect, it, beforeEach, afterEach } from "vitest";
|
|
|
2
2
|
import { JsonlStore } from "./JsonlStore";
|
|
3
3
|
import { rm, readFile, writeFile, mkdir } from "fs/promises";
|
|
4
4
|
import path from "path";
|
|
5
|
+
import os from "os";
|
|
5
6
|
|
|
6
|
-
const TEST_DIR = "
|
|
7
|
+
const TEST_DIR = path.join(os.tmpdir(), "jsonlstore-test-" + process.pid);
|
|
7
8
|
const TEST_FILE = path.join(TEST_DIR, "test.jsonl");
|
|
8
9
|
|
|
9
10
|
describe("JsonlStore", () => {
|
|
10
11
|
let store: JsonlStore;
|
|
11
12
|
|
|
12
13
|
beforeEach(async () => {
|
|
13
|
-
|
|
14
|
+
try {
|
|
15
|
+
await rm(TEST_DIR, { recursive: true, force: true });
|
|
16
|
+
} catch {
|
|
17
|
+
// ignore cleanup failures (e.g. Windows lock files from previous test)
|
|
18
|
+
}
|
|
14
19
|
await mkdir(TEST_DIR, { recursive: true });
|
|
15
20
|
store = new JsonlStore(TEST_FILE);
|
|
16
21
|
});
|
|
17
22
|
|
|
18
23
|
afterEach(async () => {
|
|
19
|
-
|
|
24
|
+
try {
|
|
25
|
+
await rm(TEST_DIR, { recursive: true, force: true });
|
|
26
|
+
} catch {
|
|
27
|
+
// ignore cleanup failures
|
|
28
|
+
}
|
|
20
29
|
});
|
|
21
30
|
|
|
22
31
|
describe("load", () => {
|
package/ts/cli.ts
CHANGED
|
@@ -9,8 +9,9 @@ import { checkAndAutoUpdate, displayVersion } from "./versionChecker.ts";
|
|
|
9
9
|
import { getRustBinary } from "./rustBinary.ts";
|
|
10
10
|
import { buildRustArgs } from "./buildRustArgs.ts";
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
|
|
12
|
+
// Check for updates before starting — installs & re-execs if a newer version exists.
|
|
13
|
+
// Fast path: cached result (no network), so this adds near-zero latency most of the time.
|
|
14
|
+
await checkAndAutoUpdate();
|
|
14
15
|
|
|
15
16
|
// Parse CLI arguments
|
|
16
17
|
const config = parseCliArgs(process.argv);
|
|
@@ -152,8 +153,5 @@ if (config.verbose) {
|
|
|
152
153
|
const { default: cliYes } = await import("./index.ts");
|
|
153
154
|
const { exitCode } = await cliYes({ ...config, autoYes: config.autoYes });
|
|
154
155
|
|
|
155
|
-
// Apply update if one was found during the session
|
|
156
|
-
await updateCheckPromise;
|
|
157
|
-
|
|
158
156
|
console.log("exiting process");
|
|
159
157
|
process.exit(exitCode ?? 1);
|
package/ts/pidStore.spec.ts
CHANGED
|
@@ -12,14 +12,22 @@ describe("PidStore", () => {
|
|
|
12
12
|
let store: PidStore;
|
|
13
13
|
|
|
14
14
|
beforeEach(async () => {
|
|
15
|
-
|
|
15
|
+
try {
|
|
16
|
+
await rm(TEST_DIR, { recursive: true, force: true });
|
|
17
|
+
} catch {
|
|
18
|
+
// ignore cleanup failures (e.g. Windows lock files from previous test)
|
|
19
|
+
}
|
|
16
20
|
store = new PidStore(TEST_DIR);
|
|
17
21
|
await store.init();
|
|
18
22
|
});
|
|
19
23
|
|
|
20
24
|
afterEach(async () => {
|
|
21
25
|
await store.close();
|
|
22
|
-
|
|
26
|
+
try {
|
|
27
|
+
await rm(TEST_DIR, { recursive: true, force: true });
|
|
28
|
+
} catch {
|
|
29
|
+
// ignore cleanup failures
|
|
30
|
+
}
|
|
23
31
|
});
|
|
24
32
|
|
|
25
33
|
describe("registerProcess", () => {
|
|
@@ -170,7 +178,11 @@ describe("PidStore", () => {
|
|
|
170
178
|
|
|
171
179
|
it("should return fifo of most recent non-exited process", async () => {
|
|
172
180
|
const fifoTestDir = TEST_DIR + "-fifo";
|
|
173
|
-
|
|
181
|
+
try {
|
|
182
|
+
await rm(fifoTestDir, { recursive: true, force: true });
|
|
183
|
+
} catch {
|
|
184
|
+
// ignore cleanup failures (e.g. Windows lock files)
|
|
185
|
+
}
|
|
174
186
|
|
|
175
187
|
const fifoStore = new PidStore(fifoTestDir);
|
|
176
188
|
await fifoStore.init();
|
|
@@ -185,7 +197,11 @@ describe("PidStore", () => {
|
|
|
185
197
|
expect(fifo!).toContain(`${process.pid}.stdin`);
|
|
186
198
|
}
|
|
187
199
|
|
|
188
|
-
|
|
200
|
+
try {
|
|
201
|
+
await rm(fifoTestDir, { recursive: true, force: true });
|
|
202
|
+
} catch {
|
|
203
|
+
// ignore cleanup failures
|
|
204
|
+
}
|
|
189
205
|
});
|
|
190
206
|
});
|
|
191
207
|
|
|
@@ -12,6 +12,14 @@ vi.mock("fs/promises", () => ({
|
|
|
12
12
|
readFile: vi.fn(),
|
|
13
13
|
writeFile: vi.fn().mockResolvedValue(undefined),
|
|
14
14
|
}));
|
|
15
|
+
vi.mock("child_process", () => ({
|
|
16
|
+
execFileSync: vi.fn(() => {
|
|
17
|
+
// Simulate successful re-exec by throwing an exit-like error
|
|
18
|
+
const err = new Error("re-exec") as any;
|
|
19
|
+
err.status = 0;
|
|
20
|
+
throw err;
|
|
21
|
+
}),
|
|
22
|
+
}));
|
|
15
23
|
|
|
16
24
|
describe("versionChecker", () => {
|
|
17
25
|
describe("compareVersions", () => {
|
|
@@ -81,7 +89,10 @@ describe("versionChecker", () => {
|
|
|
81
89
|
vi.clearAllMocks();
|
|
82
90
|
vi.stubGlobal("fetch", vi.fn());
|
|
83
91
|
vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
92
|
+
// Use a mock for process.exit to prevent actual exit in tests
|
|
93
|
+
vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
|
|
84
94
|
delete process.env.AGENT_YES_NO_UPDATE;
|
|
95
|
+
delete process.env.AGENT_YES_UPDATED;
|
|
85
96
|
delete process.env.BUN_INSTALL;
|
|
86
97
|
});
|
|
87
98
|
|
|
@@ -95,6 +106,13 @@ describe("versionChecker", () => {
|
|
|
95
106
|
expect(fetch).not.toHaveBeenCalled();
|
|
96
107
|
});
|
|
97
108
|
|
|
109
|
+
it("should skip when AGENT_YES_UPDATED matches current version", async () => {
|
|
110
|
+
const pkg = await import("../package.json");
|
|
111
|
+
process.env.AGENT_YES_UPDATED = pkg.default.version;
|
|
112
|
+
await checkAndAutoUpdate();
|
|
113
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
114
|
+
});
|
|
115
|
+
|
|
98
116
|
it("should use cached result within TTL and not install when up-to-date", async () => {
|
|
99
117
|
const { readFile } = await import("fs/promises");
|
|
100
118
|
vi.mocked(readFile).mockResolvedValueOnce(
|
|
@@ -105,19 +123,23 @@ describe("versionChecker", () => {
|
|
|
105
123
|
expect(process.stderr.write).not.toHaveBeenCalled();
|
|
106
124
|
});
|
|
107
125
|
|
|
108
|
-
it("should install from cache when cached version is newer and within TTL", async () => {
|
|
126
|
+
it("should install and re-exec from cache when cached version is newer and within TTL", async () => {
|
|
109
127
|
const { readFile } = await import("fs/promises");
|
|
110
128
|
const { execaCommand } = await import("execa");
|
|
129
|
+
const { execFileSync } = await import("child_process");
|
|
111
130
|
vi.mocked(readFile).mockResolvedValueOnce(
|
|
112
131
|
JSON.stringify({ checkedAt: Date.now(), latestVersion: "999.0.0" }) as any,
|
|
113
132
|
);
|
|
114
133
|
await checkAndAutoUpdate();
|
|
115
134
|
expect(execaCommand).toHaveBeenCalled();
|
|
135
|
+
expect(execFileSync).toHaveBeenCalled();
|
|
136
|
+
expect(process.exit).toHaveBeenCalled();
|
|
116
137
|
});
|
|
117
138
|
|
|
118
|
-
it("should fetch and write cache when stale, install if behind", async () => {
|
|
139
|
+
it("should fetch and write cache when stale, install and re-exec if behind", async () => {
|
|
119
140
|
const { readFile, writeFile } = await import("fs/promises");
|
|
120
141
|
const { execaCommand } = await import("execa");
|
|
142
|
+
const { execFileSync } = await import("child_process");
|
|
121
143
|
vi.mocked(readFile).mockRejectedValueOnce(new Error("no cache"));
|
|
122
144
|
vi.mocked(fetch).mockResolvedValue({
|
|
123
145
|
ok: true,
|
|
@@ -126,6 +148,7 @@ describe("versionChecker", () => {
|
|
|
126
148
|
await checkAndAutoUpdate();
|
|
127
149
|
expect(writeFile).toHaveBeenCalled();
|
|
128
150
|
expect(execaCommand).toHaveBeenCalled();
|
|
151
|
+
expect(execFileSync).toHaveBeenCalled();
|
|
129
152
|
});
|
|
130
153
|
|
|
131
154
|
it("should fetch and write cache but not install if up-to-date", async () => {
|
package/ts/versionChecker.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execFileSync } from "child_process";
|
|
1
2
|
import { execaCommand } from "execa";
|
|
2
3
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
3
4
|
import { homedir } from "os";
|
|
@@ -25,59 +26,92 @@ async function writeUpdateCache(data: UpdateCache): Promise<void> {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
function detectPackageManager(): string {
|
|
28
|
-
if (
|
|
29
|
+
if (
|
|
30
|
+
process.env.BUN_INSTALL ||
|
|
31
|
+
process.execPath?.includes("bun") ||
|
|
32
|
+
process.env.npm_execpath?.includes("bun")
|
|
33
|
+
)
|
|
34
|
+
return "bun";
|
|
29
35
|
return "npm";
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
/**
|
|
33
|
-
* Check for updates
|
|
39
|
+
* Check for updates, auto-install if newer version is available, and re-exec
|
|
40
|
+
* so the current invocation always runs the latest code.
|
|
41
|
+
*
|
|
34
42
|
* Uses a 1-hour TTL cache to avoid hitting the registry on every run.
|
|
35
43
|
* All errors are swallowed — network issues must never break the tool.
|
|
36
44
|
* Set AGENT_YES_NO_UPDATE=1 to opt out.
|
|
45
|
+
*
|
|
46
|
+
* The AGENT_YES_UPDATED env var prevents infinite re-exec loops:
|
|
47
|
+
* after updating we re-exec with AGENT_YES_UPDATED=<version> so the
|
|
48
|
+
* new process skips the update check.
|
|
37
49
|
*/
|
|
38
50
|
export async function checkAndAutoUpdate(): Promise<void> {
|
|
39
51
|
if (process.env.AGENT_YES_NO_UPDATE) return;
|
|
40
52
|
|
|
53
|
+
// Prevent infinite re-exec: if we just updated to this version, skip
|
|
54
|
+
if (process.env.AGENT_YES_UPDATED === pkg.version) return;
|
|
55
|
+
|
|
41
56
|
try {
|
|
57
|
+
let latestVersion: string | undefined;
|
|
58
|
+
|
|
42
59
|
// Check cache TTL
|
|
43
60
|
const cache = await readUpdateCache();
|
|
44
61
|
if (cache && Date.now() - cache.checkedAt < TTL_MS) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return;
|
|
62
|
+
latestVersion = cache.latestVersion;
|
|
63
|
+
} else {
|
|
64
|
+
// Fetch latest from registry
|
|
65
|
+
const fetched = await fetchLatestVersion();
|
|
66
|
+
if (!fetched) return;
|
|
67
|
+
latestVersion = fetched;
|
|
68
|
+
await writeUpdateCache({ checkedAt: Date.now(), latestVersion });
|
|
50
69
|
}
|
|
51
70
|
|
|
52
|
-
// Fetch latest from registry
|
|
53
|
-
const latestVersion = await fetchLatestVersion();
|
|
54
|
-
if (!latestVersion) return;
|
|
55
|
-
|
|
56
|
-
await writeUpdateCache({ checkedAt: Date.now(), latestVersion });
|
|
57
|
-
|
|
58
71
|
if (compareVersions(pkg.version, latestVersion) < 0) {
|
|
59
|
-
await runInstall(latestVersion);
|
|
72
|
+
const installed = await runInstall(latestVersion);
|
|
73
|
+
if (installed) {
|
|
74
|
+
reExec(latestVersion);
|
|
75
|
+
}
|
|
60
76
|
}
|
|
61
77
|
} catch {
|
|
62
78
|
// Silently ignore all errors
|
|
63
79
|
}
|
|
64
80
|
}
|
|
65
81
|
|
|
66
|
-
async function runInstall(latestVersion: string): Promise<
|
|
82
|
+
async function runInstall(latestVersion: string): Promise<boolean> {
|
|
67
83
|
const pm = detectPackageManager();
|
|
68
|
-
const
|
|
84
|
+
const installCmd =
|
|
69
85
|
pm === "bun"
|
|
70
86
|
? `bun add -g agent-yes@${latestVersion}`
|
|
71
87
|
: `npm install -g agent-yes@${latestVersion}`;
|
|
72
88
|
|
|
73
89
|
process.stderr.write(`\x1b[33m[agent-yes] Updating ${pkg.version} → ${latestVersion}…\x1b[0m\n`);
|
|
74
90
|
try {
|
|
75
|
-
await execaCommand(
|
|
76
|
-
// Clear cache so next run re-checks
|
|
77
|
-
await writeUpdateCache({ checkedAt: 0, latestVersion });
|
|
91
|
+
await execaCommand(installCmd, { stdio: "inherit" });
|
|
78
92
|
process.stderr.write(`\x1b[32m[agent-yes] Updated to ${latestVersion}\x1b[0m\n`);
|
|
93
|
+
return true;
|
|
79
94
|
} catch {
|
|
80
|
-
process.stderr.write(`\x1b[31m[agent-yes] Auto-update failed. Run: ${
|
|
95
|
+
process.stderr.write(`\x1b[31m[agent-yes] Auto-update failed. Run: ${installCmd}\x1b[0m\n`);
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Re-exec the current process so the newly installed version runs.
|
|
102
|
+
* Sets AGENT_YES_UPDATED=<version> to prevent an infinite loop.
|
|
103
|
+
*/
|
|
104
|
+
function reExec(version: string): never {
|
|
105
|
+
const [bin, ...args] = process.argv;
|
|
106
|
+
process.stderr.write(`\x1b[36m[agent-yes] Restarting with v${version}…\x1b[0m\n`);
|
|
107
|
+
try {
|
|
108
|
+
execFileSync(bin, args, {
|
|
109
|
+
stdio: "inherit",
|
|
110
|
+
env: { ...process.env, AGENT_YES_UPDATED: version },
|
|
111
|
+
});
|
|
112
|
+
process.exit(0);
|
|
113
|
+
} catch (err: any) {
|
|
114
|
+
process.exit(err.status ?? 1);
|
|
81
115
|
}
|
|
82
116
|
}
|
|
83
117
|
|