claude-yes 1.33.0 → 1.35.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/cli.js +335 -120
- package/dist/index.js +160 -51
- package/package.json +8 -7
- package/ts/index.ts +63 -11
- package/ts/logger.ts +0 -1
- package/ts/pidStore.ts +152 -47
package/dist/index.js
CHANGED
|
@@ -20730,24 +20730,81 @@ var init_fifo = __esm(() => {
|
|
|
20730
20730
|
});
|
|
20731
20731
|
|
|
20732
20732
|
// ts/pidStore.ts
|
|
20733
|
-
import Datastore from "@seald-io/nedb";
|
|
20734
20733
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
20735
20734
|
import path9 from "path";
|
|
20736
20735
|
|
|
20736
|
+
class SqliteAdapter {
|
|
20737
|
+
db;
|
|
20738
|
+
async init(dbPath) {
|
|
20739
|
+
if (typeof globalThis.Bun !== "undefined") {
|
|
20740
|
+
try {
|
|
20741
|
+
const { Database } = await import("bun:sqlite");
|
|
20742
|
+
this.db = new Database(dbPath);
|
|
20743
|
+
} catch (error) {
|
|
20744
|
+
logger.warn("[pidStore] bun:sqlite not available, falling back to better-sqlite3");
|
|
20745
|
+
const Database = (await import("better-sqlite3")).default;
|
|
20746
|
+
this.db = new Database(dbPath);
|
|
20747
|
+
}
|
|
20748
|
+
} else {
|
|
20749
|
+
const Database = (await import("better-sqlite3")).default;
|
|
20750
|
+
this.db = new Database(dbPath);
|
|
20751
|
+
}
|
|
20752
|
+
}
|
|
20753
|
+
query(sql, params = []) {
|
|
20754
|
+
if (typeof this.db.prepare === "function") {
|
|
20755
|
+
return this.db.prepare(sql).all(params);
|
|
20756
|
+
} else {
|
|
20757
|
+
return this.db.query(sql).all(params);
|
|
20758
|
+
}
|
|
20759
|
+
}
|
|
20760
|
+
run(sql, params = []) {
|
|
20761
|
+
if (typeof this.db.prepare === "function") {
|
|
20762
|
+
return this.db.prepare(sql).run(params);
|
|
20763
|
+
} else {
|
|
20764
|
+
this.db.run(sql, params);
|
|
20765
|
+
return {};
|
|
20766
|
+
}
|
|
20767
|
+
}
|
|
20768
|
+
close() {
|
|
20769
|
+
if (this.db.close) {
|
|
20770
|
+
this.db.close();
|
|
20771
|
+
}
|
|
20772
|
+
}
|
|
20773
|
+
}
|
|
20774
|
+
|
|
20737
20775
|
class PidStore {
|
|
20738
20776
|
db;
|
|
20739
20777
|
baseDir;
|
|
20778
|
+
dbPath;
|
|
20740
20779
|
constructor(workingDir) {
|
|
20741
20780
|
this.baseDir = path9.resolve(workingDir, ".agent-yes");
|
|
20781
|
+
this.dbPath = path9.join(this.baseDir, "pid.sqlite");
|
|
20742
20782
|
}
|
|
20743
20783
|
async init() {
|
|
20744
20784
|
await mkdir3(path9.join(this.baseDir, "logs"), { recursive: true });
|
|
20745
20785
|
await mkdir3(path9.join(this.baseDir, "fifo"), { recursive: true });
|
|
20746
|
-
this.db = new
|
|
20747
|
-
|
|
20748
|
-
|
|
20749
|
-
|
|
20750
|
-
|
|
20786
|
+
this.db = new SqliteAdapter;
|
|
20787
|
+
await this.db.init(this.dbPath);
|
|
20788
|
+
this.db.run("PRAGMA journal_mode=WAL");
|
|
20789
|
+
this.db.run("PRAGMA synchronous=NORMAL");
|
|
20790
|
+
this.db.run("PRAGMA cache_size=1000");
|
|
20791
|
+
this.db.run("PRAGMA temp_store=memory");
|
|
20792
|
+
this.db.run(`
|
|
20793
|
+
CREATE TABLE IF NOT EXISTS pid_records (
|
|
20794
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
20795
|
+
pid INTEGER NOT NULL UNIQUE,
|
|
20796
|
+
cli TEXT NOT NULL,
|
|
20797
|
+
args TEXT NOT NULL,
|
|
20798
|
+
prompt TEXT,
|
|
20799
|
+
logFile TEXT NOT NULL,
|
|
20800
|
+
fifoFile TEXT NOT NULL,
|
|
20801
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
20802
|
+
exitReason TEXT NOT NULL DEFAULT '',
|
|
20803
|
+
exitCode INTEGER,
|
|
20804
|
+
startedAt INTEGER NOT NULL,
|
|
20805
|
+
updatedAt INTEGER NOT NULL
|
|
20806
|
+
)
|
|
20807
|
+
`);
|
|
20751
20808
|
await this.cleanStaleRecords();
|
|
20752
20809
|
}
|
|
20753
20810
|
async registerProcess({
|
|
@@ -20757,29 +20814,43 @@ class PidStore {
|
|
|
20757
20814
|
prompt
|
|
20758
20815
|
}) {
|
|
20759
20816
|
const now = Date.now();
|
|
20760
|
-
const
|
|
20761
|
-
|
|
20762
|
-
|
|
20763
|
-
|
|
20764
|
-
|
|
20765
|
-
|
|
20766
|
-
|
|
20767
|
-
|
|
20768
|
-
|
|
20769
|
-
|
|
20770
|
-
|
|
20771
|
-
|
|
20772
|
-
|
|
20817
|
+
const argsJson = JSON.stringify(args);
|
|
20818
|
+
const logFile = this.getLogPath(pid);
|
|
20819
|
+
const fifoFile = this.getFifoPath(pid);
|
|
20820
|
+
try {
|
|
20821
|
+
this.db.run(`
|
|
20822
|
+
INSERT INTO pid_records (pid, cli, args, prompt, logFile, fifoFile, status, exitReason, startedAt, updatedAt)
|
|
20823
|
+
VALUES (?, ?, ?, ?, ?, ?, 'active', '', ?, ?)
|
|
20824
|
+
`, [pid, cli, argsJson, prompt, logFile, fifoFile, now, now]);
|
|
20825
|
+
} catch (error) {
|
|
20826
|
+
if (error.code === "SQLITE_CONSTRAINT_UNIQUE") {
|
|
20827
|
+
this.db.run(`
|
|
20828
|
+
UPDATE pid_records
|
|
20829
|
+
SET cli = ?, args = ?, prompt = ?, logFile = ?, fifoFile = ?, status = 'active', exitReason = '', startedAt = ?, updatedAt = ?
|
|
20830
|
+
WHERE pid = ?
|
|
20831
|
+
`, [cli, argsJson, prompt, logFile, fifoFile, now, now, pid]);
|
|
20832
|
+
} else {
|
|
20833
|
+
throw error;
|
|
20834
|
+
}
|
|
20835
|
+
}
|
|
20836
|
+
const result = this.db.query("SELECT * FROM pid_records WHERE pid = ?", [pid])[0];
|
|
20837
|
+
if (!result) {
|
|
20838
|
+
const allRecords = this.db.query("SELECT * FROM pid_records");
|
|
20839
|
+
logger.error(`[pidStore] Failed to find record for PID ${pid}. All records:`, allRecords);
|
|
20840
|
+
throw new Error(`Failed to register process ${pid}`);
|
|
20841
|
+
}
|
|
20773
20842
|
logger.debug(`[pidStore] Registered process ${pid}`);
|
|
20774
|
-
return
|
|
20843
|
+
return result;
|
|
20775
20844
|
}
|
|
20776
20845
|
async updateStatus(pid, status, extra) {
|
|
20777
|
-
const
|
|
20778
|
-
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
|
|
20846
|
+
const updatedAt = Date.now();
|
|
20847
|
+
const exitReason = extra?.exitReason || "";
|
|
20848
|
+
const exitCode = extra?.exitCode;
|
|
20849
|
+
if (exitCode !== undefined) {
|
|
20850
|
+
this.db.run("UPDATE pid_records SET status = ?, exitReason = ?, exitCode = ?, updatedAt = ? WHERE pid = ?", [status, exitReason, exitCode, updatedAt, pid]);
|
|
20851
|
+
} else {
|
|
20852
|
+
this.db.run("UPDATE pid_records SET status = ?, exitReason = ?, updatedAt = ? WHERE pid = ?", [status, exitReason, updatedAt, pid]);
|
|
20853
|
+
}
|
|
20783
20854
|
logger.debug(`[pidStore] Updated process ${pid} status=${status}`);
|
|
20784
20855
|
}
|
|
20785
20856
|
getLogPath(pid) {
|
|
@@ -20789,25 +20860,23 @@ class PidStore {
|
|
|
20789
20860
|
return path9.resolve(this.baseDir, "fifo", `${pid}.stdin`);
|
|
20790
20861
|
}
|
|
20791
20862
|
async cleanStaleRecords() {
|
|
20792
|
-
const activeRecords =
|
|
20793
|
-
status: { $ne: "exited" }
|
|
20794
|
-
});
|
|
20863
|
+
const activeRecords = this.db.query("SELECT * FROM pid_records WHERE status != 'exited'");
|
|
20795
20864
|
for (const record of activeRecords) {
|
|
20796
20865
|
if (!this.isProcessAlive(record.pid)) {
|
|
20797
|
-
|
|
20798
|
-
$set: {
|
|
20799
|
-
status: "exited",
|
|
20800
|
-
exitReason: "stale-cleanup",
|
|
20801
|
-
updatedAt: Date.now()
|
|
20802
|
-
}
|
|
20803
|
-
}, {});
|
|
20866
|
+
this.db.run("UPDATE pid_records SET status = 'exited', exitReason = 'stale-cleanup', updatedAt = ? WHERE pid = ?", [Date.now(), record.pid]);
|
|
20804
20867
|
logger.debug(`[pidStore] Cleaned stale record for PID ${record.pid}`);
|
|
20805
20868
|
}
|
|
20806
20869
|
}
|
|
20807
20870
|
}
|
|
20808
20871
|
async close() {
|
|
20809
|
-
|
|
20810
|
-
|
|
20872
|
+
try {
|
|
20873
|
+
this.db.run("PRAGMA optimize");
|
|
20874
|
+
this.db.run("VACUUM");
|
|
20875
|
+
} catch (error) {
|
|
20876
|
+
logger.warn("[pidStore] Failed to optimize database:", error);
|
|
20877
|
+
}
|
|
20878
|
+
this.db.close();
|
|
20879
|
+
logger.debug("[pidStore] Database optimized and closed");
|
|
20811
20880
|
}
|
|
20812
20881
|
isProcessAlive(pid) {
|
|
20813
20882
|
try {
|
|
@@ -20820,10 +20889,9 @@ class PidStore {
|
|
|
20820
20889
|
static async findActiveFifo(workingDir) {
|
|
20821
20890
|
const store = new PidStore(workingDir);
|
|
20822
20891
|
await store.init();
|
|
20823
|
-
const records =
|
|
20892
|
+
const records = store.db.query("SELECT * FROM pid_records WHERE status != 'exited' ORDER BY startedAt DESC LIMIT 1");
|
|
20824
20893
|
await store.close();
|
|
20825
|
-
|
|
20826
|
-
return sorted[0]?.fifoFile ?? null;
|
|
20894
|
+
return records[0]?.fifoFile ?? null;
|
|
20827
20895
|
}
|
|
20828
20896
|
}
|
|
20829
20897
|
var init_pidStore = __esm(() => {
|
|
@@ -20879,8 +20947,12 @@ function getDefaultConfig() {
|
|
|
20879
20947
|
},
|
|
20880
20948
|
claude: {
|
|
20881
20949
|
promptArg: "last-arg",
|
|
20882
|
-
install:
|
|
20883
|
-
|
|
20950
|
+
install: {
|
|
20951
|
+
powershell: "irm https://claude.ai/install.ps1 | iex",
|
|
20952
|
+
bash: "curl -fsSL https://claude.ai/install.sh | bash",
|
|
20953
|
+
npm: "npm i -g @anthropic-ai/claude-code@latest"
|
|
20954
|
+
},
|
|
20955
|
+
ready: [/^\? for shortcuts/, /^> /],
|
|
20884
20956
|
typingRespond: {
|
|
20885
20957
|
"1\n": [/│ Do you want to use this API key\?/]
|
|
20886
20958
|
},
|
|
@@ -21295,6 +21367,26 @@ ${prompt}` : prefix;
|
|
|
21295
21367
|
logger.warn(`Unknown promptArg format: ${cliConf.promptArg}`);
|
|
21296
21368
|
}
|
|
21297
21369
|
}
|
|
21370
|
+
const getInstallCommand = (installConfig) => {
|
|
21371
|
+
if (typeof installConfig === "string") {
|
|
21372
|
+
return installConfig;
|
|
21373
|
+
}
|
|
21374
|
+
const isWindows = process.platform === "win32";
|
|
21375
|
+
const platform3 = isWindows ? "windows" : "unix";
|
|
21376
|
+
if (installConfig[platform3]) {
|
|
21377
|
+
return installConfig[platform3];
|
|
21378
|
+
}
|
|
21379
|
+
if (isWindows && installConfig.powershell) {
|
|
21380
|
+
return installConfig.powershell;
|
|
21381
|
+
}
|
|
21382
|
+
if (!isWindows && installConfig.bash) {
|
|
21383
|
+
return installConfig.bash;
|
|
21384
|
+
}
|
|
21385
|
+
if (installConfig.npm) {
|
|
21386
|
+
return installConfig.npm;
|
|
21387
|
+
}
|
|
21388
|
+
return null;
|
|
21389
|
+
};
|
|
21298
21390
|
const spawn2 = () => {
|
|
21299
21391
|
const cliCommand = cliConf?.binary || cli;
|
|
21300
21392
|
let [bin, ...args] = [...parseCommandString(cliCommand), ...cliArgs];
|
|
@@ -21309,14 +21401,19 @@ ${prompt}` : prefix;
|
|
|
21309
21401
|
logger.error(`Fatal: Failed to start ${cli}.`);
|
|
21310
21402
|
const isNotFound = isCommandNotFoundError(error);
|
|
21311
21403
|
if (cliConf?.install && isNotFound) {
|
|
21312
|
-
|
|
21404
|
+
const installCmd = getInstallCommand(cliConf.install);
|
|
21405
|
+
if (!installCmd) {
|
|
21406
|
+
logger.error(`No suitable install command found for ${cli} on this platform`);
|
|
21407
|
+
throw error;
|
|
21408
|
+
}
|
|
21409
|
+
logger.info(`Please install the cli by run ${installCmd}`);
|
|
21313
21410
|
if (install) {
|
|
21314
21411
|
logger.info(`Attempting to install ${cli}...`);
|
|
21315
|
-
execaCommandSync(
|
|
21412
|
+
execaCommandSync(installCmd, { stdio: "inherit" });
|
|
21316
21413
|
logger.info(`${cli} installed successfully. Please rerun the command.`);
|
|
21317
21414
|
return spawn2();
|
|
21318
21415
|
} else {
|
|
21319
|
-
logger.error(`If you did not installed it yet, Please install it first: ${
|
|
21416
|
+
logger.error(`If you did not installed it yet, Please install it first: ${installCmd}`);
|
|
21320
21417
|
throw error;
|
|
21321
21418
|
}
|
|
21322
21419
|
}
|
|
@@ -21351,7 +21448,10 @@ ${prompt}` : prefix;
|
|
|
21351
21448
|
stdinReady.unready();
|
|
21352
21449
|
const agentCrashed = exitCode2 !== 0;
|
|
21353
21450
|
if (shouldRestartWithoutContinue) {
|
|
21354
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21451
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21452
|
+
exitReason: "restarted",
|
|
21453
|
+
exitCode: exitCode2 ?? undefined
|
|
21454
|
+
});
|
|
21355
21455
|
shouldRestartWithoutContinue = false;
|
|
21356
21456
|
isFatal = false;
|
|
21357
21457
|
const cliCommand = cliConf?.binary || cli;
|
|
@@ -21372,10 +21472,16 @@ ${prompt}` : prefix;
|
|
|
21372
21472
|
return;
|
|
21373
21473
|
}
|
|
21374
21474
|
if (isFatal) {
|
|
21375
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21475
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21476
|
+
exitReason: "fatal",
|
|
21477
|
+
exitCode: exitCode2 ?? undefined
|
|
21478
|
+
});
|
|
21376
21479
|
return pendingExitCode.resolve(exitCode2);
|
|
21377
21480
|
}
|
|
21378
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21481
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21482
|
+
exitReason: "restarted",
|
|
21483
|
+
exitCode: exitCode2 ?? undefined
|
|
21484
|
+
});
|
|
21379
21485
|
logger.info(`${cli} crashed, restarting...`);
|
|
21380
21486
|
let restoreArgs = conf.restoreArgs;
|
|
21381
21487
|
if (cli === "codex") {
|
|
@@ -21394,7 +21500,10 @@ ${prompt}` : prefix;
|
|
|
21394
21500
|
return;
|
|
21395
21501
|
}
|
|
21396
21502
|
const exitReason = agentCrashed ? "crash" : "normal";
|
|
21397
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21503
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
21504
|
+
exitReason,
|
|
21505
|
+
exitCode: exitCode2 ?? undefined
|
|
21506
|
+
});
|
|
21398
21507
|
return pendingExitCode.resolve(exitCode2);
|
|
21399
21508
|
});
|
|
21400
21509
|
process.stdout.on("resize", () => {
|
|
@@ -21613,5 +21722,5 @@ export {
|
|
|
21613
21722
|
CLIS_CONFIG
|
|
21614
21723
|
};
|
|
21615
21724
|
|
|
21616
|
-
//# debugId=
|
|
21725
|
+
//# debugId=9A92FE5B1254037264756E2164756E21
|
|
21617
21726
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-yes",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.35.0",
|
|
4
4
|
"description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"url": "git+https://github.com/snomiao/agent-yes.git"
|
|
30
30
|
},
|
|
31
31
|
"bin": {
|
|
32
|
-
"ay": "./dist/agent-yes.js",
|
|
33
32
|
"agent-yes": "./dist/agent-yes.js",
|
|
34
33
|
"amp-yes": "./dist/amp-yes.js",
|
|
35
34
|
"auggie-yes": "./dist/auggie-yes.js",
|
|
35
|
+
"ay": "./dist/agent-yes.js",
|
|
36
36
|
"claude-yes": "./dist/claude-yes.js",
|
|
37
37
|
"codex-yes": "./dist/codex-yes.js",
|
|
38
38
|
"copilot-yes": "./dist/copilot-yes.js",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"doc": "docs"
|
|
46
46
|
},
|
|
47
47
|
"files": [
|
|
48
|
-
"dist/**/*.js",
|
|
49
|
-
"!dist/**/*.map",
|
|
50
48
|
"scripts",
|
|
51
|
-
"ts/*.ts"
|
|
49
|
+
"ts/*.ts",
|
|
50
|
+
"!dist/**/*.map",
|
|
51
|
+
"dist/**/*.js"
|
|
52
52
|
],
|
|
53
53
|
"type": "module",
|
|
54
54
|
"module": "ts/index.ts",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"registry": "https://registry.npmjs.org/"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
|
-
"build": "bun build ./ts/cli.ts ./ts/index.ts --outdir=dist --target=node --sourcemap --external
|
|
65
|
+
"build": "bun build ./ts/cli.ts ./ts/index.ts --outdir=dist --target=node --sourcemap --external=better-sqlite3 --external=@snomiao/bun-pty --external=bun-pty --external=node-pty --external=from-node-stream --external=bun",
|
|
66
66
|
"postbuild": "bun ./ts/postbuild.ts",
|
|
67
67
|
"demo": "bun run build && bun link && claude-yes -- demo",
|
|
68
68
|
"dev": "bun ts/index.ts",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"test": "bun test --coverage"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@seald-io/nedb": "^4.0.4",
|
|
78
77
|
"@snomiao/bun-pty": "^0.3.4",
|
|
78
|
+
"better-sqlite3": "^12.1.0",
|
|
79
79
|
"bun-pty": "^0.4.8",
|
|
80
80
|
"from-node-stream": "^0.1.2"
|
|
81
81
|
},
|
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
"@semantic-release/exec": "^7.1.0",
|
|
86
86
|
"@semantic-release/git": "^10.0.1",
|
|
87
87
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
88
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
88
89
|
"@types/bun": "^1.3.6",
|
|
89
90
|
"@types/jest": "^30.0.0",
|
|
90
91
|
"@types/ms": "^2.1.0",
|
package/ts/index.ts
CHANGED
|
@@ -21,13 +21,14 @@ import { createFifoStream } from "./beta/fifo.ts";
|
|
|
21
21
|
import { PidStore } from "./pidStore.ts";
|
|
22
22
|
import { SUPPORTED_CLIS } from "./SUPPORTED_CLIS.ts";
|
|
23
23
|
import winston from "winston";
|
|
24
|
-
import { mapObject, pipe } from "rambda";
|
|
25
24
|
|
|
26
25
|
export { removeControlCharacters };
|
|
27
26
|
|
|
28
27
|
export type AgentCliConfig = {
|
|
29
28
|
// cli
|
|
30
|
-
install?:
|
|
29
|
+
install?:
|
|
30
|
+
| string
|
|
31
|
+
| { powershell?: string; bash?: string; npm?: string; unix?: string; windows?: string }; // hint user for install command if not installed
|
|
31
32
|
version?: string; // hint user for version command to check if installed
|
|
32
33
|
binary?: string; // actual binary name if different from cli, e.g. cursor -> cursor-agent
|
|
33
34
|
defaultArgs?: string[]; // function to ensure certain args are present
|
|
@@ -328,6 +329,41 @@ export default async function agentYes({
|
|
|
328
329
|
}
|
|
329
330
|
// Determine the actual cli command to run
|
|
330
331
|
|
|
332
|
+
// Helper function to get install command based on platform/availability
|
|
333
|
+
const getInstallCommand = (
|
|
334
|
+
installConfig:
|
|
335
|
+
| string
|
|
336
|
+
| { powershell?: string; bash?: string; npm?: string; unix?: string; windows?: string },
|
|
337
|
+
): string | null => {
|
|
338
|
+
if (typeof installConfig === "string") {
|
|
339
|
+
return installConfig;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const isWindows = process.platform === "win32";
|
|
343
|
+
const platform = isWindows ? "windows" : "unix";
|
|
344
|
+
|
|
345
|
+
// Try platform-specific commands first
|
|
346
|
+
if (installConfig[platform]) {
|
|
347
|
+
return installConfig[platform];
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Try shell-specific commands
|
|
351
|
+
if (isWindows && installConfig.powershell) {
|
|
352
|
+
return installConfig.powershell;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (!isWindows && installConfig.bash) {
|
|
356
|
+
return installConfig.bash;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Fallback to npm if available
|
|
360
|
+
if (installConfig.npm) {
|
|
361
|
+
return installConfig.npm;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return null;
|
|
365
|
+
};
|
|
366
|
+
|
|
331
367
|
const spawn = () => {
|
|
332
368
|
const cliCommand = cliConf?.binary || cli;
|
|
333
369
|
let [bin, ...args] = [...parseCommandString(cliCommand), ...cliArgs];
|
|
@@ -348,17 +384,21 @@ export default async function agentYes({
|
|
|
348
384
|
|
|
349
385
|
const isNotFound = isCommandNotFoundError(error);
|
|
350
386
|
if (cliConf?.install && isNotFound) {
|
|
351
|
-
|
|
387
|
+
const installCmd = getInstallCommand(cliConf.install);
|
|
388
|
+
if (!installCmd) {
|
|
389
|
+
logger.error(`No suitable install command found for ${cli} on this platform`);
|
|
390
|
+
throw error;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
logger.info(`Please install the cli by run ${installCmd}`);
|
|
352
394
|
|
|
353
395
|
if (install) {
|
|
354
396
|
logger.info(`Attempting to install ${cli}...`);
|
|
355
|
-
execaCommandSync(
|
|
397
|
+
execaCommandSync(installCmd, { stdio: "inherit" });
|
|
356
398
|
logger.info(`${cli} installed successfully. Please rerun the command.`);
|
|
357
399
|
return spawn();
|
|
358
400
|
} else {
|
|
359
|
-
logger.error(
|
|
360
|
-
`If you did not installed it yet, Please install it first: ${cliConf.install}`,
|
|
361
|
-
);
|
|
401
|
+
logger.error(`If you did not installed it yet, Please install it first: ${installCmd}`);
|
|
362
402
|
throw error;
|
|
363
403
|
}
|
|
364
404
|
}
|
|
@@ -415,7 +455,10 @@ export default async function agentYes({
|
|
|
415
455
|
// Handle restart without continue args (e.g., "No conversation found to continue")
|
|
416
456
|
// logger.debug(``, { shouldRestartWithoutContinue, robust })
|
|
417
457
|
if (shouldRestartWithoutContinue) {
|
|
418
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
458
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
459
|
+
exitReason: "restarted",
|
|
460
|
+
exitCode: exitCode ?? undefined,
|
|
461
|
+
});
|
|
419
462
|
shouldRestartWithoutContinue = false; // reset flag
|
|
420
463
|
isFatal = false; // reset fatal flag to allow restart
|
|
421
464
|
|
|
@@ -445,11 +488,17 @@ export default async function agentYes({
|
|
|
445
488
|
return;
|
|
446
489
|
}
|
|
447
490
|
if (isFatal) {
|
|
448
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
491
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
492
|
+
exitReason: "fatal",
|
|
493
|
+
exitCode: exitCode ?? undefined,
|
|
494
|
+
});
|
|
449
495
|
return pendingExitCode.resolve(exitCode);
|
|
450
496
|
}
|
|
451
497
|
|
|
452
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
498
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
499
|
+
exitReason: "restarted",
|
|
500
|
+
exitCode: exitCode ?? undefined,
|
|
501
|
+
});
|
|
453
502
|
logger.info(`${cli} crashed, restarting...`);
|
|
454
503
|
|
|
455
504
|
// For codex, try to use stored session ID for this directory
|
|
@@ -472,7 +521,10 @@ export default async function agentYes({
|
|
|
472
521
|
return;
|
|
473
522
|
}
|
|
474
523
|
const exitReason = agentCrashed ? "crash" : "normal";
|
|
475
|
-
await pidStore.updateStatus(shell.pid, "exited", {
|
|
524
|
+
await pidStore.updateStatus(shell.pid, "exited", {
|
|
525
|
+
exitReason,
|
|
526
|
+
exitCode: exitCode ?? undefined,
|
|
527
|
+
});
|
|
476
528
|
return pendingExitCode.resolve(exitCode);
|
|
477
529
|
});
|
|
478
530
|
|
package/ts/logger.ts
CHANGED