claude-yes 1.32.3 → 1.34.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 CHANGED
@@ -20633,16 +20633,20 @@ import { fromReadable } from "from-node-stream";
20633
20633
  import { createReadStream as createReadStream2, mkdirSync } from "fs";
20634
20634
  import { unlink } from "fs/promises";
20635
20635
  import { dirname } from "path";
20636
- function createFifoStream(cli) {
20636
+ function createFifoStream(cli, customPath) {
20637
20637
  if (process.platform !== "linux") {
20638
20638
  return null;
20639
20639
  }
20640
20640
  let fifoPath = null;
20641
20641
  let fifoStream = null;
20642
20642
  try {
20643
- const timestamp = new Date().toISOString().replace(/\D/g, "").slice(0, 17);
20644
- const randomSuffix = Math.random().toString(36).substring(2, 5);
20645
- fifoPath = `/tmp/agent-yes-${timestamp}${randomSuffix}.stdin`;
20643
+ if (customPath) {
20644
+ fifoPath = customPath;
20645
+ } else {
20646
+ const timestamp = new Date().toISOString().replace(/\D/g, "").slice(0, 17);
20647
+ const randomSuffix = Math.random().toString(36).substring(2, 5);
20648
+ fifoPath = `/tmp/agent-yes-${timestamp}${randomSuffix}.stdin`;
20649
+ }
20646
20650
  mkdirSync(dirname(fifoPath), { recursive: true });
20647
20651
  const mkfifoResult = execaCommandSync(`mkfifo ${fifoPath}`, {
20648
20652
  reject: false
@@ -20727,6 +20731,107 @@ var init_fifo = __esm(() => {
20727
20731
  init_logger();
20728
20732
  });
20729
20733
 
20734
+ // ts/pidStore.ts
20735
+ import Datastore from "@seald-io/nedb";
20736
+ import { mkdir as mkdir3 } from "fs/promises";
20737
+ import path9 from "path";
20738
+
20739
+ class PidStore {
20740
+ db;
20741
+ baseDir;
20742
+ constructor(workingDir) {
20743
+ this.baseDir = path9.resolve(workingDir, ".agent-yes");
20744
+ }
20745
+ async init() {
20746
+ await mkdir3(path9.join(this.baseDir, "logs"), { recursive: true });
20747
+ await mkdir3(path9.join(this.baseDir, "fifo"), { recursive: true });
20748
+ this.db = new Datastore({
20749
+ filename: path9.join(this.baseDir, "pid.jsonl"),
20750
+ autoload: true
20751
+ });
20752
+ await this.db.loadDatabaseAsync();
20753
+ await this.cleanStaleRecords();
20754
+ }
20755
+ async registerProcess({
20756
+ pid,
20757
+ cli,
20758
+ args,
20759
+ prompt
20760
+ }) {
20761
+ const now = Date.now();
20762
+ const record = {
20763
+ pid,
20764
+ cli,
20765
+ args,
20766
+ prompt,
20767
+ logFile: this.getLogPath(pid),
20768
+ fifoFile: this.getFifoPath(pid),
20769
+ status: "active",
20770
+ exitReason: "",
20771
+ startedAt: now,
20772
+ updatedAt: now
20773
+ };
20774
+ await this.db.insertAsync(record);
20775
+ logger.debug(`[pidStore] Registered process ${pid}`);
20776
+ return record;
20777
+ }
20778
+ async updateStatus(pid, status, extra) {
20779
+ const update2 = {
20780
+ status,
20781
+ updatedAt: Date.now(),
20782
+ ...extra
20783
+ };
20784
+ await this.db.updateAsync({ pid }, { $set: update2 }, {});
20785
+ logger.debug(`[pidStore] Updated process ${pid} status=${status}`);
20786
+ }
20787
+ getLogPath(pid) {
20788
+ return path9.resolve(this.baseDir, "logs", `${pid}.log`);
20789
+ }
20790
+ getFifoPath(pid) {
20791
+ return path9.resolve(this.baseDir, "fifo", `${pid}.stdin`);
20792
+ }
20793
+ async cleanStaleRecords() {
20794
+ const activeRecords = await this.db.findAsync({
20795
+ status: { $ne: "exited" }
20796
+ });
20797
+ for (const record of activeRecords) {
20798
+ if (!this.isProcessAlive(record.pid)) {
20799
+ await this.db.updateAsync({ pid: record.pid }, {
20800
+ $set: {
20801
+ status: "exited",
20802
+ exitReason: "stale-cleanup",
20803
+ updatedAt: Date.now()
20804
+ }
20805
+ }, {});
20806
+ logger.debug(`[pidStore] Cleaned stale record for PID ${record.pid}`);
20807
+ }
20808
+ }
20809
+ }
20810
+ async close() {
20811
+ await this.db.compactDatafileAsync();
20812
+ logger.debug("[pidStore] Database compacted and closed");
20813
+ }
20814
+ isProcessAlive(pid) {
20815
+ try {
20816
+ process.kill(pid, 0);
20817
+ return true;
20818
+ } catch {
20819
+ return false;
20820
+ }
20821
+ }
20822
+ static async findActiveFifo(workingDir) {
20823
+ const store = new PidStore(workingDir);
20824
+ await store.init();
20825
+ const records = await store.db.findAsync({ status: { $ne: "exited" } });
20826
+ await store.close();
20827
+ const sorted = records.sort((a2, b) => b.startedAt - a2.startedAt);
20828
+ return sorted[0]?.fifoFile ?? null;
20829
+ }
20830
+ }
20831
+ var init_pidStore = __esm(() => {
20832
+ init_logger();
20833
+ });
20834
+
20730
20835
  // ts/defineConfig.ts
20731
20836
  async function defineCliYesConfig(cfg) {
20732
20837
  if (typeof cfg === "function")
@@ -20757,13 +20862,13 @@ var exports_agent_yes_config = {};
20757
20862
  __export(exports_agent_yes_config, {
20758
20863
  default: () => agent_yes_config_default
20759
20864
  });
20760
- import { mkdir as mkdir3 } from "node:fs/promises";
20865
+ import { mkdir as mkdir4 } from "node:fs/promises";
20761
20866
  import os from "node:os";
20762
- import path9 from "node:path";
20867
+ import path10 from "node:path";
20763
20868
  function getDefaultConfig() {
20764
20869
  return defineCliYesConfig({
20765
20870
  configDir,
20766
- logsDir: configDir && path9.resolve(configDir, "logs"),
20871
+ logsDir: configDir && path10.resolve(configDir, "logs"),
20767
20872
  clis: {
20768
20873
  qwen: {
20769
20874
  install: "npm install -g @qwen-code/qwen-code@latest",
@@ -20776,8 +20881,12 @@ function getDefaultConfig() {
20776
20881
  },
20777
20882
  claude: {
20778
20883
  promptArg: "last-arg",
20779
- install: "npm install -g @anthropic-ai/claude-code@latest",
20780
- ready: [/\? for shortcuts/],
20884
+ install: {
20885
+ powershell: "irm https://claude.ai/install.ps1 | iex",
20886
+ bash: "curl -fsSL https://claude.ai/install.sh | bash",
20887
+ npm: "npm i -g @anthropic-ai/claude-code@latest"
20888
+ },
20889
+ ready: [/^\? for shortcuts/, /^> /],
20781
20890
  typingRespond: {
20782
20891
  "1\n": [/│ Do you want to use this API key\?/]
20783
20892
  },
@@ -20860,21 +20969,21 @@ var init_agent_yes_config = __esm(async () => {
20860
20969
  init_logger();
20861
20970
  logger.debug("loading cli-yes.config.ts from " + import.meta.url);
20862
20971
  configDir = await (async () => {
20863
- const homeConfigDir = path9.resolve(os.homedir(), ".agent-yes");
20864
- const isHomeWritable = await mkdir3(homeConfigDir, { recursive: true }).then(() => true).catch(() => false);
20972
+ const homeConfigDir = path10.resolve(os.homedir(), ".agent-yes");
20973
+ const isHomeWritable = await mkdir4(homeConfigDir, { recursive: true }).then(() => true).catch(() => false);
20865
20974
  if (isHomeWritable) {
20866
20975
  logger.debug("[config] Using home directory:", homeConfigDir);
20867
20976
  return homeConfigDir;
20868
20977
  }
20869
- const tmpConfigDir = path9.resolve("/tmp/.agent-yes");
20870
- const isWritable = await mkdir3(tmpConfigDir, { recursive: true });
20978
+ const tmpConfigDir = path10.resolve("/tmp/.agent-yes");
20979
+ const isWritable = await mkdir4(tmpConfigDir, { recursive: true });
20871
20980
  if (isWritable) {
20872
20981
  logger.debug("[config] Using workspace directory:", tmpConfigDir);
20873
20982
  return tmpConfigDir;
20874
20983
  }
20875
20984
  return;
20876
20985
  })();
20877
- agent_yes_config_default = deepMixin(await getDefaultConfig(), await import(path9.resolve(os.homedir(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path9.resolve(process.cwd(), "node_modules/.agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path9.resolve(process.cwd(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default));
20986
+ agent_yes_config_default = deepMixin(await getDefaultConfig(), await import(path10.resolve(os.homedir(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path10.resolve(process.cwd(), "node_modules/.agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path10.resolve(process.cwd(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default));
20878
20987
  });
20879
20988
 
20880
20989
  // ts/pty-fix.ts
@@ -21041,8 +21150,8 @@ __export(exports_ts, {
21041
21150
  CLIS_CONFIG: () => CLIS_CONFIG2
21042
21151
  });
21043
21152
  import { fromReadable as fromReadable3, fromWritable as fromWritable2 } from "from-node-stream";
21044
- import { mkdir as mkdir6, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
21045
- import path12 from "path";
21153
+ import { mkdir as mkdir7, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
21154
+ import path13 from "path";
21046
21155
  async function agentYes2({
21047
21156
  cli,
21048
21157
  cliArgs = [],
@@ -21086,6 +21195,8 @@ async function agentYes2({
21086
21195
  process.exit(code);
21087
21196
  });
21088
21197
  }
21198
+ const pidStore = new PidStore(workingDir);
21199
+ await pidStore.init();
21089
21200
  process.stdin.setRawMode?.(true);
21090
21201
  let isFatal = false;
21091
21202
  let shouldRestartWithoutContinue = false;
@@ -21101,16 +21212,10 @@ async function agentYes2({
21101
21212
  const shellOutputStream = new TransformStream;
21102
21213
  const outputWriter = shellOutputStream.writable.getWriter();
21103
21214
  logger.debug(`Using ${ptyPackage} for pseudo terminal management.`);
21104
- const datetime = new Date().toISOString().replace(/\D/g, "").slice(0, 17);
21105
- const logPath = config2.logsDir && path12.resolve(config2.logsDir, `${cli}-yes-${datetime}.log`);
21106
- const rawLogPath = config2.logsDir && path12.resolve(config2.logsDir, `${cli}-yes-${datetime}.raw.log`);
21107
- const rawLinesLogPath = config2.logsDir && path12.resolve(config2.logsDir, `${cli}-yes-${datetime}.lines.log`);
21108
- const debuggingLogsPath = config2.logsDir && path12.resolve(config2.logsDir, `${cli}-yes-${datetime}.debug.log`);
21109
- if (debuggingLogsPath)
21110
- logger.add(new import_winston4.default.transports.File({
21111
- filename: debuggingLogsPath,
21112
- level: "debug"
21113
- }));
21215
+ let logPath = false;
21216
+ let rawLogPath = false;
21217
+ let rawLinesLogPath = false;
21218
+ let debuggingLogsPath = false;
21114
21219
  const isSubAgent = !!process.env.CLAUDE_PPID;
21115
21220
  if (isSubAgent)
21116
21221
  logger.info(`[${cli}-yes] Running as sub-agent (CLAUDE_PPID=${process.env.CLAUDE_PPID})`);
@@ -21140,9 +21245,9 @@ async function agentYes2({
21140
21245
  } catch {}
21141
21246
  const skillHeaders = [];
21142
21247
  let currentDir = workingDir2;
21143
- const searchLimit = gitRoot || path12.parse(currentDir).root;
21248
+ const searchLimit = gitRoot || path13.parse(currentDir).root;
21144
21249
  while (true) {
21145
- const skillPath = path12.resolve(currentDir, "SKILL.md");
21250
+ const skillPath = path13.resolve(currentDir, "SKILL.md");
21146
21251
  const md = await readFile4(skillPath, "utf8").catch(() => null);
21147
21252
  if (md) {
21148
21253
  const headerMatch = md.match(/^[\s\S]*?(?=\n##\s)/);
@@ -21155,7 +21260,7 @@ async function agentYes2({
21155
21260
  }
21156
21261
  if (currentDir === searchLimit)
21157
21262
  break;
21158
- const parentDir = path12.dirname(currentDir);
21263
+ const parentDir = path13.dirname(currentDir);
21159
21264
  if (parentDir === currentDir)
21160
21265
  break;
21161
21266
  currentDir = parentDir;
@@ -21218,6 +21323,26 @@ ${prompt}` : prefix;
21218
21323
  logger.warn(`Unknown promptArg format: ${cliConf.promptArg}`);
21219
21324
  }
21220
21325
  }
21326
+ const getInstallCommand = (installConfig) => {
21327
+ if (typeof installConfig === "string") {
21328
+ return installConfig;
21329
+ }
21330
+ const isWindows = process.platform === "win32";
21331
+ const platform3 = isWindows ? "windows" : "unix";
21332
+ if (installConfig[platform3]) {
21333
+ return installConfig[platform3];
21334
+ }
21335
+ if (isWindows && installConfig.powershell) {
21336
+ return installConfig.powershell;
21337
+ }
21338
+ if (!isWindows && installConfig.bash) {
21339
+ return installConfig.bash;
21340
+ }
21341
+ if (installConfig.npm) {
21342
+ return installConfig.npm;
21343
+ }
21344
+ return null;
21345
+ };
21221
21346
  const spawn2 = () => {
21222
21347
  const cliCommand = cliConf?.binary || cli;
21223
21348
  let [bin, ...args] = [...parseCommandString(cliCommand), ...cliArgs];
@@ -21232,14 +21357,19 @@ ${prompt}` : prefix;
21232
21357
  logger.error(`Fatal: Failed to start ${cli}.`);
21233
21358
  const isNotFound = isCommandNotFoundError(error);
21234
21359
  if (cliConf?.install && isNotFound) {
21235
- logger.info(`Please install the cli by run ${cliConf.install}`);
21360
+ const installCmd = getInstallCommand(cliConf.install);
21361
+ if (!installCmd) {
21362
+ logger.error(`No suitable install command found for ${cli} on this platform`);
21363
+ throw error;
21364
+ }
21365
+ logger.info(`Please install the cli by run ${installCmd}`);
21236
21366
  if (install) {
21237
21367
  logger.info(`Attempting to install ${cli}...`);
21238
- execaCommandSync(cliConf.install, { stdio: "inherit" });
21368
+ execaCommandSync(installCmd, { stdio: "inherit" });
21239
21369
  logger.info(`${cli} installed successfully. Please rerun the command.`);
21240
21370
  return spawn2();
21241
21371
  } else {
21242
- logger.error(`If you did not installed it yet, Please install it first: ${cliConf.install}`);
21372
+ logger.error(`If you did not installed it yet, Please install it first: ${installCmd}`);
21243
21373
  throw error;
21244
21374
  }
21245
21375
  }
@@ -21255,6 +21385,16 @@ ${prompt}` : prefix;
21255
21385
  return false;
21256
21386
  }
21257
21387
  }, spawn2)();
21388
+ await pidStore.registerProcess({ pid: shell.pid, cli, args: cliArgs, prompt });
21389
+ logPath = pidStore.getLogPath(shell.pid);
21390
+ rawLogPath = path13.resolve(path13.dirname(logPath), `${shell.pid}.raw.log`);
21391
+ rawLinesLogPath = path13.resolve(path13.dirname(logPath), `${shell.pid}.lines.log`);
21392
+ debuggingLogsPath = path13.resolve(path13.dirname(logPath), `${shell.pid}.debug.log`);
21393
+ if (debuggingLogsPath)
21394
+ logger.add(new import_winston4.default.transports.File({
21395
+ filename: debuggingLogsPath,
21396
+ level: "debug"
21397
+ }));
21258
21398
  const pendingExitCode = Promise.withResolvers();
21259
21399
  async function onData(data) {
21260
21400
  await outputWriter.write(data);
@@ -21264,6 +21404,10 @@ ${prompt}` : prefix;
21264
21404
  stdinReady.unready();
21265
21405
  const agentCrashed = exitCode2 !== 0;
21266
21406
  if (shouldRestartWithoutContinue) {
21407
+ await pidStore.updateStatus(shell.pid, "exited", {
21408
+ exitReason: "restarted",
21409
+ exitCode: exitCode2 ?? undefined
21410
+ });
21267
21411
  shouldRestartWithoutContinue = false;
21268
21412
  isFatal = false;
21269
21413
  const cliCommand = cliConf?.binary || cli;
@@ -21273,6 +21417,7 @@ ${prompt}` : prefix;
21273
21417
  ];
21274
21418
  logger.info(`Restarting ${cli} ${JSON.stringify([bin, ...args])}`);
21275
21419
  shell = pty_default.spawn(bin, args, getPtyOptions());
21420
+ await pidStore.registerProcess({ pid: shell.pid, cli, args, prompt });
21276
21421
  shell.onData(onData);
21277
21422
  shell.onExit(onExit);
21278
21423
  return;
@@ -21282,8 +21427,17 @@ ${prompt}` : prefix;
21282
21427
  logger.warn(`robust is only supported for ${Object.entries(CLIS_CONFIG2).filter(([_, v]) => v.restoreArgs).map(([k]) => k).join(", ")} currently, not ${cli}`);
21283
21428
  return;
21284
21429
  }
21285
- if (isFatal)
21430
+ if (isFatal) {
21431
+ await pidStore.updateStatus(shell.pid, "exited", {
21432
+ exitReason: "fatal",
21433
+ exitCode: exitCode2 ?? undefined
21434
+ });
21286
21435
  return pendingExitCode.resolve(exitCode2);
21436
+ }
21437
+ await pidStore.updateStatus(shell.pid, "exited", {
21438
+ exitReason: "restarted",
21439
+ exitCode: exitCode2 ?? undefined
21440
+ });
21287
21441
  logger.info(`${cli} crashed, restarting...`);
21288
21442
  let restoreArgs = conf.restoreArgs;
21289
21443
  if (cli === "codex") {
@@ -21296,10 +21450,16 @@ ${prompt}` : prefix;
21296
21450
  }
21297
21451
  }
21298
21452
  shell = pty_default.spawn(cli, restoreArgs, getPtyOptions());
21453
+ await pidStore.registerProcess({ pid: shell.pid, cli, args: restoreArgs, prompt });
21299
21454
  shell.onData(onData);
21300
21455
  shell.onExit(onExit);
21301
21456
  return;
21302
21457
  }
21458
+ const exitReason = agentCrashed ? "crash" : "normal";
21459
+ await pidStore.updateStatus(shell.pid, "exited", {
21460
+ exitReason,
21461
+ exitCode: exitCode2 ?? undefined
21462
+ });
21303
21463
  return pendingExitCode.resolve(exitCode2);
21304
21464
  });
21305
21465
  process.stdout.on("resize", () => {
@@ -21311,6 +21471,7 @@ ${prompt}` : prefix;
21311
21471
  const idleWaiter = new IdleWaiter;
21312
21472
  if (exitOnIdle)
21313
21473
  idleWaiter.wait(exitOnIdle).then(async () => {
21474
+ await pidStore.updateStatus(shell.pid, "idle").catch(() => null);
21314
21475
  if (isStillWorkingQ()) {
21315
21476
  logger.warn("[${cli}-yes] ${cli} is idle, but seems still working, not exiting yet");
21316
21477
  return;
@@ -21336,10 +21497,14 @@ ${prompt}` : prefix;
21336
21497
  }).by((s) => {
21337
21498
  if (!useFifo)
21338
21499
  return s;
21339
- const fifoResult = createFifoStream(cli);
21500
+ const fifoResult = createFifoStream(cli, pidStore.getFifoPath(shell.pid));
21340
21501
  if (!fifoResult)
21341
21502
  return s;
21342
21503
  pendingExitCode.promise.finally(() => fifoResult.cleanup());
21504
+ process.stderr.write(`
21505
+ Append prompts: ${cli}-yes --append-prompt '...'
21506
+
21507
+ `);
21343
21508
  return s.merge(fifoResult.stream);
21344
21509
  }).onStart(async function promptOnStart() {
21345
21510
  logger.debug("Sending prompt message: " + JSON.stringify(prompt));
@@ -21353,10 +21518,13 @@ ${prompt}` : prefix;
21353
21518
  }
21354
21519
  }),
21355
21520
  readable: shellOutputStream.readable
21356
- }).forEach(() => idleWaiter.ping()).forEach(() => nextStdout.ready()).forkTo(async function rawLogger(f) {
21521
+ }).forEach(() => {
21522
+ idleWaiter.ping();
21523
+ pidStore.updateStatus(shell.pid, "active").catch(() => null);
21524
+ }).forEach(() => nextStdout.ready()).forkTo(async function rawLogger(f) {
21357
21525
  if (!rawLogPath)
21358
21526
  return f.run();
21359
- return await mkdir6(path12.dirname(rawLogPath), { recursive: true }).then(() => {
21527
+ return await mkdir7(path13.dirname(rawLogPath), { recursive: true }).then(() => {
21360
21528
  logger.debug(`[${cli}-yes] raw logs streaming to ${rawLogPath}`);
21361
21529
  return f.forEach(async (chars) => {
21362
21530
  await writeFile5(rawLogPath, chars, { flag: "a" }).catch(() => null);
@@ -21430,18 +21598,19 @@ ${prompt}` : prefix;
21430
21598
  flush: (ctrl) => ctrl.terminate()
21431
21599
  })).to(fromWritable2(process.stdout));
21432
21600
  if (logPath) {
21433
- await mkdir6(path12.dirname(logPath), { recursive: true }).catch(() => null);
21601
+ await mkdir7(path13.dirname(logPath), { recursive: true }).catch(() => null);
21434
21602
  await writeFile5(logPath, terminalRender.render()).catch(() => null);
21435
21603
  logger.info(`[${cli}-yes] Full logs saved to ${logPath}`);
21436
21604
  }
21437
21605
  const exitCode = await pendingExitCode.promise;
21438
21606
  logger.info(`[${cli}-yes] ${cli} exited with code ${exitCode}`);
21607
+ await pidStore.close();
21439
21608
  await outputWriter.close();
21440
21609
  if (logFile) {
21441
21610
  if (verbose)
21442
21611
  logger.info(`[${cli}-yes] Writing rendered logs to ${logFile}`);
21443
- const logFilePath = path12.resolve(logFile);
21444
- await mkdir6(path12.dirname(logFilePath), { recursive: true }).catch(() => null);
21612
+ const logFilePath = path13.resolve(logFile);
21613
+ await mkdir7(path13.dirname(logFilePath), { recursive: true }).catch(() => null);
21445
21614
  await writeFile5(logFilePath, terminalRender.render());
21446
21615
  }
21447
21616
  return { exitCode, logs: terminalRender.render() };
@@ -21512,6 +21681,7 @@ var init_ts = __esm(async () => {
21512
21681
  init_runningLock();
21513
21682
  init_logger();
21514
21683
  init_fifo();
21684
+ init_pidStore();
21515
21685
  await init_pty();
21516
21686
  import_winston4 = __toESM(require_winston(), 1);
21517
21687
  config2 = await init_agent_yes_config().then(() => exports_agent_yes_config).then((mod) => mod.default || mod);
@@ -21527,11 +21697,12 @@ init_codexSessionManager();
21527
21697
  init_runningLock();
21528
21698
  init_logger();
21529
21699
  init_fifo();
21700
+ init_pidStore();
21530
21701
  await init_pty();
21531
21702
  var import_winston2 = __toESM(require_winston(), 1);
21532
21703
  import { fromReadable as fromReadable2, fromWritable } from "from-node-stream";
21533
- import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
21534
- import path10 from "path";
21704
+ import { mkdir as mkdir5, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
21705
+ import path11 from "path";
21535
21706
  var config = await init_agent_yes_config().then(() => exports_agent_yes_config).then((mod) => mod.default || mod);
21536
21707
  var CLIS_CONFIG = config.clis;
21537
21708
  async function agentYes({
@@ -21577,6 +21748,8 @@ async function agentYes({
21577
21748
  process.exit(code);
21578
21749
  });
21579
21750
  }
21751
+ const pidStore = new PidStore(workingDir);
21752
+ await pidStore.init();
21580
21753
  process.stdin.setRawMode?.(true);
21581
21754
  let isFatal = false;
21582
21755
  let shouldRestartWithoutContinue = false;
@@ -21592,16 +21765,10 @@ async function agentYes({
21592
21765
  const shellOutputStream = new TransformStream;
21593
21766
  const outputWriter = shellOutputStream.writable.getWriter();
21594
21767
  logger.debug(`Using ${ptyPackage} for pseudo terminal management.`);
21595
- const datetime = new Date().toISOString().replace(/\D/g, "").slice(0, 17);
21596
- const logPath = config.logsDir && path10.resolve(config.logsDir, `${cli}-yes-${datetime}.log`);
21597
- const rawLogPath = config.logsDir && path10.resolve(config.logsDir, `${cli}-yes-${datetime}.raw.log`);
21598
- const rawLinesLogPath = config.logsDir && path10.resolve(config.logsDir, `${cli}-yes-${datetime}.lines.log`);
21599
- const debuggingLogsPath = config.logsDir && path10.resolve(config.logsDir, `${cli}-yes-${datetime}.debug.log`);
21600
- if (debuggingLogsPath)
21601
- logger.add(new import_winston2.default.transports.File({
21602
- filename: debuggingLogsPath,
21603
- level: "debug"
21604
- }));
21768
+ let logPath = false;
21769
+ let rawLogPath = false;
21770
+ let rawLinesLogPath = false;
21771
+ let debuggingLogsPath = false;
21605
21772
  const isSubAgent = !!process.env.CLAUDE_PPID;
21606
21773
  if (isSubAgent)
21607
21774
  logger.info(`[${cli}-yes] Running as sub-agent (CLAUDE_PPID=${process.env.CLAUDE_PPID})`);
@@ -21631,9 +21798,9 @@ async function agentYes({
21631
21798
  } catch {}
21632
21799
  const skillHeaders = [];
21633
21800
  let currentDir = workingDir2;
21634
- const searchLimit = gitRoot || path10.parse(currentDir).root;
21801
+ const searchLimit = gitRoot || path11.parse(currentDir).root;
21635
21802
  while (true) {
21636
- const skillPath = path10.resolve(currentDir, "SKILL.md");
21803
+ const skillPath = path11.resolve(currentDir, "SKILL.md");
21637
21804
  const md = await readFile3(skillPath, "utf8").catch(() => null);
21638
21805
  if (md) {
21639
21806
  const headerMatch = md.match(/^[\s\S]*?(?=\n##\s)/);
@@ -21646,7 +21813,7 @@ async function agentYes({
21646
21813
  }
21647
21814
  if (currentDir === searchLimit)
21648
21815
  break;
21649
- const parentDir = path10.dirname(currentDir);
21816
+ const parentDir = path11.dirname(currentDir);
21650
21817
  if (parentDir === currentDir)
21651
21818
  break;
21652
21819
  currentDir = parentDir;
@@ -21709,6 +21876,26 @@ ${prompt}` : prefix;
21709
21876
  logger.warn(`Unknown promptArg format: ${cliConf.promptArg}`);
21710
21877
  }
21711
21878
  }
21879
+ const getInstallCommand = (installConfig) => {
21880
+ if (typeof installConfig === "string") {
21881
+ return installConfig;
21882
+ }
21883
+ const isWindows = process.platform === "win32";
21884
+ const platform3 = isWindows ? "windows" : "unix";
21885
+ if (installConfig[platform3]) {
21886
+ return installConfig[platform3];
21887
+ }
21888
+ if (isWindows && installConfig.powershell) {
21889
+ return installConfig.powershell;
21890
+ }
21891
+ if (!isWindows && installConfig.bash) {
21892
+ return installConfig.bash;
21893
+ }
21894
+ if (installConfig.npm) {
21895
+ return installConfig.npm;
21896
+ }
21897
+ return null;
21898
+ };
21712
21899
  const spawn2 = () => {
21713
21900
  const cliCommand = cliConf?.binary || cli;
21714
21901
  let [bin, ...args] = [...parseCommandString(cliCommand), ...cliArgs];
@@ -21723,14 +21910,19 @@ ${prompt}` : prefix;
21723
21910
  logger.error(`Fatal: Failed to start ${cli}.`);
21724
21911
  const isNotFound = isCommandNotFoundError(error);
21725
21912
  if (cliConf?.install && isNotFound) {
21726
- logger.info(`Please install the cli by run ${cliConf.install}`);
21913
+ const installCmd = getInstallCommand(cliConf.install);
21914
+ if (!installCmd) {
21915
+ logger.error(`No suitable install command found for ${cli} on this platform`);
21916
+ throw error;
21917
+ }
21918
+ logger.info(`Please install the cli by run ${installCmd}`);
21727
21919
  if (install) {
21728
21920
  logger.info(`Attempting to install ${cli}...`);
21729
- execaCommandSync(cliConf.install, { stdio: "inherit" });
21921
+ execaCommandSync(installCmd, { stdio: "inherit" });
21730
21922
  logger.info(`${cli} installed successfully. Please rerun the command.`);
21731
21923
  return spawn2();
21732
21924
  } else {
21733
- logger.error(`If you did not installed it yet, Please install it first: ${cliConf.install}`);
21925
+ logger.error(`If you did not installed it yet, Please install it first: ${installCmd}`);
21734
21926
  throw error;
21735
21927
  }
21736
21928
  }
@@ -21746,6 +21938,16 @@ ${prompt}` : prefix;
21746
21938
  return false;
21747
21939
  }
21748
21940
  }, spawn2)();
21941
+ await pidStore.registerProcess({ pid: shell.pid, cli, args: cliArgs, prompt });
21942
+ logPath = pidStore.getLogPath(shell.pid);
21943
+ rawLogPath = path11.resolve(path11.dirname(logPath), `${shell.pid}.raw.log`);
21944
+ rawLinesLogPath = path11.resolve(path11.dirname(logPath), `${shell.pid}.lines.log`);
21945
+ debuggingLogsPath = path11.resolve(path11.dirname(logPath), `${shell.pid}.debug.log`);
21946
+ if (debuggingLogsPath)
21947
+ logger.add(new import_winston2.default.transports.File({
21948
+ filename: debuggingLogsPath,
21949
+ level: "debug"
21950
+ }));
21749
21951
  const pendingExitCode = Promise.withResolvers();
21750
21952
  async function onData(data) {
21751
21953
  await outputWriter.write(data);
@@ -21755,6 +21957,10 @@ ${prompt}` : prefix;
21755
21957
  stdinReady.unready();
21756
21958
  const agentCrashed = exitCode2 !== 0;
21757
21959
  if (shouldRestartWithoutContinue) {
21960
+ await pidStore.updateStatus(shell.pid, "exited", {
21961
+ exitReason: "restarted",
21962
+ exitCode: exitCode2 ?? undefined
21963
+ });
21758
21964
  shouldRestartWithoutContinue = false;
21759
21965
  isFatal = false;
21760
21966
  const cliCommand = cliConf?.binary || cli;
@@ -21764,6 +21970,7 @@ ${prompt}` : prefix;
21764
21970
  ];
21765
21971
  logger.info(`Restarting ${cli} ${JSON.stringify([bin, ...args])}`);
21766
21972
  shell = pty_default.spawn(bin, args, getPtyOptions());
21973
+ await pidStore.registerProcess({ pid: shell.pid, cli, args, prompt });
21767
21974
  shell.onData(onData);
21768
21975
  shell.onExit(onExit);
21769
21976
  return;
@@ -21773,8 +21980,17 @@ ${prompt}` : prefix;
21773
21980
  logger.warn(`robust is only supported for ${Object.entries(CLIS_CONFIG).filter(([_, v]) => v.restoreArgs).map(([k]) => k).join(", ")} currently, not ${cli}`);
21774
21981
  return;
21775
21982
  }
21776
- if (isFatal)
21983
+ if (isFatal) {
21984
+ await pidStore.updateStatus(shell.pid, "exited", {
21985
+ exitReason: "fatal",
21986
+ exitCode: exitCode2 ?? undefined
21987
+ });
21777
21988
  return pendingExitCode.resolve(exitCode2);
21989
+ }
21990
+ await pidStore.updateStatus(shell.pid, "exited", {
21991
+ exitReason: "restarted",
21992
+ exitCode: exitCode2 ?? undefined
21993
+ });
21778
21994
  logger.info(`${cli} crashed, restarting...`);
21779
21995
  let restoreArgs = conf.restoreArgs;
21780
21996
  if (cli === "codex") {
@@ -21787,10 +22003,16 @@ ${prompt}` : prefix;
21787
22003
  }
21788
22004
  }
21789
22005
  shell = pty_default.spawn(cli, restoreArgs, getPtyOptions());
22006
+ await pidStore.registerProcess({ pid: shell.pid, cli, args: restoreArgs, prompt });
21790
22007
  shell.onData(onData);
21791
22008
  shell.onExit(onExit);
21792
22009
  return;
21793
22010
  }
22011
+ const exitReason = agentCrashed ? "crash" : "normal";
22012
+ await pidStore.updateStatus(shell.pid, "exited", {
22013
+ exitReason,
22014
+ exitCode: exitCode2 ?? undefined
22015
+ });
21794
22016
  return pendingExitCode.resolve(exitCode2);
21795
22017
  });
21796
22018
  process.stdout.on("resize", () => {
@@ -21802,6 +22024,7 @@ ${prompt}` : prefix;
21802
22024
  const idleWaiter = new IdleWaiter;
21803
22025
  if (exitOnIdle)
21804
22026
  idleWaiter.wait(exitOnIdle).then(async () => {
22027
+ await pidStore.updateStatus(shell.pid, "idle").catch(() => null);
21805
22028
  if (isStillWorkingQ()) {
21806
22029
  logger.warn("[${cli}-yes] ${cli} is idle, but seems still working, not exiting yet");
21807
22030
  return;
@@ -21827,10 +22050,14 @@ ${prompt}` : prefix;
21827
22050
  }).by((s) => {
21828
22051
  if (!useFifo)
21829
22052
  return s;
21830
- const fifoResult = createFifoStream(cli);
22053
+ const fifoResult = createFifoStream(cli, pidStore.getFifoPath(shell.pid));
21831
22054
  if (!fifoResult)
21832
22055
  return s;
21833
22056
  pendingExitCode.promise.finally(() => fifoResult.cleanup());
22057
+ process.stderr.write(`
22058
+ Append prompts: ${cli}-yes --append-prompt '...'
22059
+
22060
+ `);
21834
22061
  return s.merge(fifoResult.stream);
21835
22062
  }).onStart(async function promptOnStart() {
21836
22063
  logger.debug("Sending prompt message: " + JSON.stringify(prompt));
@@ -21844,10 +22071,13 @@ ${prompt}` : prefix;
21844
22071
  }
21845
22072
  }),
21846
22073
  readable: shellOutputStream.readable
21847
- }).forEach(() => idleWaiter.ping()).forEach(() => nextStdout.ready()).forkTo(async function rawLogger(f) {
22074
+ }).forEach(() => {
22075
+ idleWaiter.ping();
22076
+ pidStore.updateStatus(shell.pid, "active").catch(() => null);
22077
+ }).forEach(() => nextStdout.ready()).forkTo(async function rawLogger(f) {
21848
22078
  if (!rawLogPath)
21849
22079
  return f.run();
21850
- return await mkdir4(path10.dirname(rawLogPath), { recursive: true }).then(() => {
22080
+ return await mkdir5(path11.dirname(rawLogPath), { recursive: true }).then(() => {
21851
22081
  logger.debug(`[${cli}-yes] raw logs streaming to ${rawLogPath}`);
21852
22082
  return f.forEach(async (chars) => {
21853
22083
  await writeFile3(rawLogPath, chars, { flag: "a" }).catch(() => null);
@@ -21921,18 +22151,19 @@ ${prompt}` : prefix;
21921
22151
  flush: (ctrl) => ctrl.terminate()
21922
22152
  })).to(fromWritable(process.stdout));
21923
22153
  if (logPath) {
21924
- await mkdir4(path10.dirname(logPath), { recursive: true }).catch(() => null);
22154
+ await mkdir5(path11.dirname(logPath), { recursive: true }).catch(() => null);
21925
22155
  await writeFile3(logPath, terminalRender.render()).catch(() => null);
21926
22156
  logger.info(`[${cli}-yes] Full logs saved to ${logPath}`);
21927
22157
  }
21928
22158
  const exitCode = await pendingExitCode.promise;
21929
22159
  logger.info(`[${cli}-yes] ${cli} exited with code ${exitCode}`);
22160
+ await pidStore.close();
21930
22161
  await outputWriter.close();
21931
22162
  if (logFile) {
21932
22163
  if (verbose)
21933
22164
  logger.info(`[${cli}-yes] Writing rendered logs to ${logFile}`);
21934
- const logFilePath = path10.resolve(logFile);
21935
- await mkdir4(path10.dirname(logFilePath), { recursive: true }).catch(() => null);
22165
+ const logFilePath = path11.resolve(logFile);
22166
+ await mkdir5(path11.dirname(logFilePath), { recursive: true }).catch(() => null);
21936
22167
  await writeFile3(logFilePath, terminalRender.render());
21937
22168
  }
21938
22169
  return { exitCode, logs: terminalRender.render() };
@@ -21997,124 +22228,6 @@ function sleep2(ms) {
21997
22228
  // ts/cli.ts
21998
22229
  import { argv } from "process";
21999
22230
 
22000
- // agent-yes.config.ts
22001
- init_logger();
22002
- import { mkdir as mkdir5 } from "node:fs/promises";
22003
- import os2 from "node:os";
22004
- import path11 from "node:path";
22005
- logger.debug("loading cli-yes.config.ts from " + import.meta.url);
22006
- var configDir2 = await (async () => {
22007
- const homeConfigDir = path11.resolve(os2.homedir(), ".agent-yes");
22008
- const isHomeWritable = await mkdir5(homeConfigDir, { recursive: true }).then(() => true).catch(() => false);
22009
- if (isHomeWritable) {
22010
- logger.debug("[config] Using home directory:", homeConfigDir);
22011
- return homeConfigDir;
22012
- }
22013
- const tmpConfigDir = path11.resolve("/tmp/.agent-yes");
22014
- const isWritable = await mkdir5(tmpConfigDir, { recursive: true });
22015
- if (isWritable) {
22016
- logger.debug("[config] Using workspace directory:", tmpConfigDir);
22017
- return tmpConfigDir;
22018
- }
22019
- return;
22020
- })();
22021
- var agent_yes_config_default2 = deepMixin(await getDefaultConfig2(), await import(path11.resolve(os2.homedir(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path11.resolve(process.cwd(), "node_modules/.agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path11.resolve(process.cwd(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default));
22022
- function getDefaultConfig2() {
22023
- return defineCliYesConfig({
22024
- configDir: configDir2,
22025
- logsDir: configDir2 && path11.resolve(configDir2, "logs"),
22026
- clis: {
22027
- qwen: {
22028
- install: "npm install -g @qwen-code/qwen-code@latest",
22029
- version: "qwen --version"
22030
- },
22031
- grok: {
22032
- install: "npm install -g @vibe-kit/grok-cli@latest",
22033
- ready: [/^ │ ❯ +/],
22034
- enter: [/^ 1. Yes/]
22035
- },
22036
- claude: {
22037
- promptArg: "last-arg",
22038
- install: "npm install -g @anthropic-ai/claude-code@latest",
22039
- ready: [/\? for shortcuts/],
22040
- typingRespond: {
22041
- "1\n": [/│ Do you want to use this API key\?/]
22042
- },
22043
- enter: [
22044
- /^.{0,4} 1\. Yes/m,
22045
- /^.{0,4} 1\. Yes, continue/m,
22046
- /^.{0,4} 1\. Dark mode ?✔/m,
22047
- /❯ 1\. Yes/m,
22048
- /❯ 1\. Yes, continue/m,
22049
- /❯ 1\. Dark mode ?✔/m,
22050
- /Press Enter to continue…/m
22051
- ],
22052
- fatal: [/⎿ Claude usage limit reached\./, /^error: unknown option/],
22053
- restoreArgs: ["--continue"],
22054
- restartWithoutContinueArg: [/No conversation found to continue/],
22055
- exitCommand: ["/exit"],
22056
- bunx: true,
22057
- defaultArgs: ["--model=sonnet"]
22058
- },
22059
- gemini: {
22060
- install: "npm install -g @google/gemini-cli@latest",
22061
- ready: [/Type your message/],
22062
- enter: [/│ ● 1. Yes, allow once/, /│ ● 1. Allow once/],
22063
- fatal: [/Error resuming session/, /No previous sessions found for this project./],
22064
- restoreArgs: ["--resume"],
22065
- restartWithoutContinueArg: [
22066
- /No previous sessions found for this project\./,
22067
- /Error resuming session/
22068
- ],
22069
- exitCommand: ["/chat save ${PWD}", "/quit"]
22070
- },
22071
- codex: {
22072
- promptArg: "first-arg",
22073
- install: "npm install -g @openai/codex@latest",
22074
- updateAvailable: [/^✨⬆️ Update available!/],
22075
- ready: [
22076
- /⏎ send/,
22077
- /\? for shortcuts/
22078
- ],
22079
- enter: [
22080
- /> 1. Yes,/,
22081
- /> 1. Yes, allow Codex to work in this folder/,
22082
- /> 1. Approve and run now/
22083
- ],
22084
- fatal: [/Error: The cursor position could not be read within/],
22085
- defaultArgs: ["--search"],
22086
- noEOL: true
22087
- },
22088
- copilot: {
22089
- install: "npm install -g @github/copilot",
22090
- ready: [/^ +> /, /Ctrl\+c Exit/],
22091
- enter: [/ │ ❯ +1. Yes, proceed/, /❯ +1. Yes/],
22092
- fatal: []
22093
- },
22094
- cursor: {
22095
- install: "open https://cursor.com/ja/docs/cli/installation",
22096
- binary: "cursor-agent",
22097
- bunx: true,
22098
- ready: [/\/ commands/],
22099
- enter: [/→ Run \(once\) \(y\) \(enter\)/, /▶ \[a\] Trust this workspace/],
22100
- fatal: [/^ Error: You've hit your usage limit/]
22101
- },
22102
- auggie: {
22103
- help: "https://docs.augmentcode.com/cli/overview",
22104
- install: "npm install -g @augmentcode/auggie",
22105
- promptArg: "first-arg",
22106
- ready: [/ > /, /\? to show shortcuts/],
22107
- enter: [],
22108
- fatal: []
22109
- },
22110
- amp: {
22111
- help: "",
22112
- install: "npm i -g @sourcegraph/amp"
22113
- }
22114
- }
22115
- });
22116
- }
22117
-
22118
22231
  // ts/parseCliArgs.ts
22119
22232
  var import_ms = __toESM(require_ms(), 1);
22120
22233
 
@@ -27545,6 +27658,7 @@ var package_default = {
27545
27658
  "agent-yes": "./dist/agent-yes.js",
27546
27659
  "amp-yes": "./dist/amp-yes.js",
27547
27660
  "auggie-yes": "./dist/auggie-yes.js",
27661
+ ay: "./dist/agent-yes.js",
27548
27662
  "claude-yes": "./dist/claude-yes.js",
27549
27663
  "codex-yes": "./dist/codex-yes.js",
27550
27664
  "copilot-yes": "./dist/copilot-yes.js",
@@ -27557,10 +27671,10 @@ var package_default = {
27557
27671
  doc: "docs"
27558
27672
  },
27559
27673
  files: [
27560
- "dist/**/*.js",
27561
- "!dist/**/*.map",
27562
27674
  "scripts",
27563
- "ts/*.ts"
27675
+ "ts/*.ts",
27676
+ "!dist/**/*.map",
27677
+ "dist/**/*.js"
27564
27678
  ],
27565
27679
  type: "module",
27566
27680
  module: "ts/index.ts",
@@ -27574,7 +27688,7 @@ var package_default = {
27574
27688
  registry: "https://registry.npmjs.org/"
27575
27689
  },
27576
27690
  scripts: {
27577
- build: "bun build ./ts/cli.ts ./ts/index.ts --outdir=dist --target=node --sourcemap --external=@snomiao/bun-pty --external=bun-pty --external=node-pty --external=from-node-stream --external=bun",
27691
+ build: "bun build ./ts/cli.ts ./ts/index.ts --outdir=dist --target=node --sourcemap --external=@seald-io/nedb --external=@snomiao/bun-pty --external=bun-pty --external=node-pty --external=from-node-stream --external=bun",
27578
27692
  postbuild: "bun ./ts/postbuild.ts",
27579
27693
  demo: "bun run build && bun link && claude-yes -- demo",
27580
27694
  dev: "bun ts/index.ts",
@@ -27586,26 +27700,13 @@ var package_default = {
27586
27700
  test: "bun test --coverage"
27587
27701
  },
27588
27702
  dependencies: {
27703
+ "@seald-io/nedb": "^4.0.4",
27589
27704
  "@snomiao/bun-pty": "^0.3.4",
27590
27705
  "bun-pty": "^0.4.8",
27591
27706
  "from-node-stream": "^0.1.2"
27592
27707
  },
27593
27708
  devDependencies: {
27594
27709
  "@anthropic-ai/sdk": "^0.71.2",
27595
- "cpu-wait": "^0.0.10",
27596
- execa: "^9.6.1",
27597
- ink: "^6.6.0",
27598
- ms: "^2.1.3",
27599
- openai: "^6.16.0",
27600
- "p-map": "^7.0.4",
27601
- phpdie: "^1.7.0",
27602
- rambda: "^11.0.1",
27603
- sflow: "^1.27.0",
27604
- "strip-ansi-control-characters": "^2.0.0",
27605
- "terminal-render": "^1.2.2",
27606
- "tsa-composer": "^3.0.3",
27607
- winston: "^3.19.0",
27608
- yargs: "^18.0.0",
27609
27710
  "@semantic-release/changelog": "^6.0.3",
27610
27711
  "@semantic-release/exec": "^7.1.0",
27611
27712
  "@semantic-release/git": "^10.0.1",
@@ -27615,14 +27716,28 @@ var package_default = {
27615
27716
  "@types/ms": "^2.1.0",
27616
27717
  "@types/node": "^25.0.10",
27617
27718
  "@types/yargs": "^17.0.35",
27719
+ "cpu-wait": "^0.0.10",
27720
+ execa: "^9.6.1",
27618
27721
  husky: "^9.1.7",
27722
+ ink: "^6.6.0",
27619
27723
  "lint-staged": "^16.2.7",
27724
+ ms: "^2.1.3",
27620
27725
  "node-pty": "^1.1.0",
27726
+ openai: "^6.16.0",
27621
27727
  oxfmt: "^0.26.0",
27622
27728
  oxlint: "^1.41.0",
27729
+ "p-map": "^7.0.4",
27730
+ phpdie: "^1.7.0",
27731
+ rambda: "^11.0.1",
27623
27732
  "semantic-release": "^25.0.2",
27733
+ sflow: "^1.27.0",
27624
27734
  "standard-version": "^9.5.0",
27625
- vitest: "^4.0.17"
27735
+ "strip-ansi-control-characters": "^2.0.0",
27736
+ "terminal-render": "^1.2.2",
27737
+ "tsa-composer": "^3.0.3",
27738
+ vitest: "^4.0.17",
27739
+ winston: "^3.19.0",
27740
+ yargs: "^18.0.0"
27626
27741
  },
27627
27742
  peerDependencies: {
27628
27743
  "node-pty": "latest",
@@ -27707,6 +27822,13 @@ function parseCliArgs(argv) {
27707
27822
  description: "Resume previous session in current cwd if any, note: will exit if no previous session found",
27708
27823
  default: false,
27709
27824
  alias: "c"
27825
+ }).option("append-prompt", {
27826
+ type: "string",
27827
+ description: "Send a prompt to the active agent's FIFO stdin in current directory"
27828
+ }).option("fifo", {
27829
+ type: "boolean",
27830
+ description: "Enable FIFO input stream for additional stdin input (Linux only)",
27831
+ default: false
27710
27832
  }).positional("cli", {
27711
27833
  describe: "The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini",
27712
27834
  type: "string",
@@ -27777,7 +27899,9 @@ function parseCliArgs(argv) {
27777
27899
  logFile: parsedArgv.logFile,
27778
27900
  verbose: parsedArgv.verbose,
27779
27901
  resume: parsedArgv.continue,
27780
- useSkills: parsedArgv.useSkills
27902
+ useSkills: parsedArgv.useSkills,
27903
+ appendPrompt: parsedArgv.appendPrompt,
27904
+ useFifo: parsedArgv.fifo
27781
27905
  };
27782
27906
  }
27783
27907
 
@@ -27798,12 +27922,123 @@ var logger2 = import_winston3.default.createLogger({
27798
27922
  silent: false
27799
27923
  });
27800
27924
 
27925
+ // ts/pidStore.ts
27926
+ init_logger();
27927
+ import Datastore2 from "@seald-io/nedb";
27928
+ import { mkdir as mkdir6 } from "fs/promises";
27929
+ import path12 from "path";
27930
+
27931
+ class PidStore2 {
27932
+ db;
27933
+ baseDir;
27934
+ constructor(workingDir) {
27935
+ this.baseDir = path12.resolve(workingDir, ".agent-yes");
27936
+ }
27937
+ async init() {
27938
+ await mkdir6(path12.join(this.baseDir, "logs"), { recursive: true });
27939
+ await mkdir6(path12.join(this.baseDir, "fifo"), { recursive: true });
27940
+ this.db = new Datastore2({
27941
+ filename: path12.join(this.baseDir, "pid.jsonl"),
27942
+ autoload: true
27943
+ });
27944
+ await this.db.loadDatabaseAsync();
27945
+ await this.cleanStaleRecords();
27946
+ }
27947
+ async registerProcess({
27948
+ pid,
27949
+ cli,
27950
+ args,
27951
+ prompt
27952
+ }) {
27953
+ const now = Date.now();
27954
+ const record = {
27955
+ pid,
27956
+ cli,
27957
+ args,
27958
+ prompt,
27959
+ logFile: this.getLogPath(pid),
27960
+ fifoFile: this.getFifoPath(pid),
27961
+ status: "active",
27962
+ exitReason: "",
27963
+ startedAt: now,
27964
+ updatedAt: now
27965
+ };
27966
+ await this.db.insertAsync(record);
27967
+ logger.debug(`[pidStore] Registered process ${pid}`);
27968
+ return record;
27969
+ }
27970
+ async updateStatus(pid, status, extra) {
27971
+ const update2 = {
27972
+ status,
27973
+ updatedAt: Date.now(),
27974
+ ...extra
27975
+ };
27976
+ await this.db.updateAsync({ pid }, { $set: update2 }, {});
27977
+ logger.debug(`[pidStore] Updated process ${pid} status=${status}`);
27978
+ }
27979
+ getLogPath(pid) {
27980
+ return path12.resolve(this.baseDir, "logs", `${pid}.log`);
27981
+ }
27982
+ getFifoPath(pid) {
27983
+ return path12.resolve(this.baseDir, "fifo", `${pid}.stdin`);
27984
+ }
27985
+ async cleanStaleRecords() {
27986
+ const activeRecords = await this.db.findAsync({
27987
+ status: { $ne: "exited" }
27988
+ });
27989
+ for (const record of activeRecords) {
27990
+ if (!this.isProcessAlive(record.pid)) {
27991
+ await this.db.updateAsync({ pid: record.pid }, {
27992
+ $set: {
27993
+ status: "exited",
27994
+ exitReason: "stale-cleanup",
27995
+ updatedAt: Date.now()
27996
+ }
27997
+ }, {});
27998
+ logger.debug(`[pidStore] Cleaned stale record for PID ${record.pid}`);
27999
+ }
28000
+ }
28001
+ }
28002
+ async close() {
28003
+ await this.db.compactDatafileAsync();
28004
+ logger.debug("[pidStore] Database compacted and closed");
28005
+ }
28006
+ isProcessAlive(pid) {
28007
+ try {
28008
+ process.kill(pid, 0);
28009
+ return true;
28010
+ } catch {
28011
+ return false;
28012
+ }
28013
+ }
28014
+ static async findActiveFifo(workingDir) {
28015
+ const store = new PidStore2(workingDir);
28016
+ await store.init();
28017
+ const records = await store.db.findAsync({ status: { $ne: "exited" } });
28018
+ await store.close();
28019
+ const sorted = records.sort((a2, b) => b.startedAt - a2.startedAt);
28020
+ return sorted[0]?.fifoFile ?? null;
28021
+ }
28022
+ }
28023
+
27801
28024
  // ts/cli.ts
27802
28025
  var config3 = parseCliArgs(process.argv);
28026
+ if (config3.appendPrompt) {
28027
+ const fifoPath = await PidStore2.findActiveFifo(process.cwd());
28028
+ if (!fifoPath) {
28029
+ console.error("No active agent with FIFO found in current directory.");
28030
+ process.exit(1);
28031
+ }
28032
+ const { writeFileSync: writeFileSync2, openSync, closeSync } = await import("fs");
28033
+ const fd = openSync(fifoPath, "w");
28034
+ writeFileSync2(fd, config3.appendPrompt + "\r");
28035
+ closeSync(fd);
28036
+ console.log(`Sent prompt to ${fifoPath}`);
28037
+ process.exit(0);
28038
+ }
27803
28039
  if (!config3.cli) {
27804
- logger2.error(process.argv);
27805
- logger2.error("Error: No CLI name provided.");
27806
- throw new Error(`missing cli def, available clis: ${Object.keys((await agent_yes_config_default2).clis).join(", ")}`);
28040
+ config3.cli = "claude";
28041
+ logger2.warn("Warning: No CLI name provided. Using default 'claude'.");
27807
28042
  }
27808
28043
  if (config3.verbose) {
27809
28044
  process.env.VERBOSE = "true";
@@ -27815,5 +28050,5 @@ var { exitCode } = await cliYes(config3);
27815
28050
  console.log("exiting process");
27816
28051
  process.exit(exitCode ?? 1);
27817
28052
 
27818
- //# debugId=88F92B41CE5B430064756E2164756E21
28053
+ //# debugId=12710EC867DEB2CA64756E2164756E21
27819
28054
  //# sourceMappingURL=cli.js.map