@agentchatme/cli 0.0.135 → 0.0.136

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/index.js CHANGED
@@ -4709,8 +4709,8 @@ async function runStopHook(platform) {
4709
4709
  }
4710
4710
 
4711
4711
  // src/commands/identity.ts
4712
- import * as fs5 from "fs";
4713
- import * as path6 from "path";
4712
+ import * as fs6 from "fs";
4713
+ import * as path7 from "path";
4714
4714
  import * as readline from "readline/promises";
4715
4715
 
4716
4716
  // ../node_modules/.pnpm/agentchatme@1.0.2_ws@8.21.1/node_modules/agentchatme/dist/index.js
@@ -6306,6 +6306,107 @@ function removeCodex() {
6306
6306
  return removed;
6307
6307
  }
6308
6308
 
6309
+ // src/commands/daemon.ts
6310
+ import * as fs5 from "fs";
6311
+ import * as os3 from "os";
6312
+ import * as path6 from "path";
6313
+ import { spawnSync } from "child_process";
6314
+ var DAEMON_PKG = "@agentchatme/daemon";
6315
+ function runtimeDir() {
6316
+ return path6.join(os3.homedir(), ".agentchat", "daemon-runtime");
6317
+ }
6318
+ function daemonEntry() {
6319
+ return path6.join(runtimeDir(), "node_modules", "@agentchatme", "daemon", "dist", "index.js");
6320
+ }
6321
+ function ensureDaemon() {
6322
+ if (fs5.existsSync(daemonEntry())) return { ok: true };
6323
+ const dir = runtimeDir();
6324
+ try {
6325
+ fs5.mkdirSync(dir, { recursive: true });
6326
+ } catch (err) {
6327
+ return { ok: false, detail: `could not create ${dir}: ${String(err)}` };
6328
+ }
6329
+ const r = spawnSync(
6330
+ "npm",
6331
+ ["install", DAEMON_PKG, "--prefix", dir, "--no-save", "--no-audit", "--no-fund"],
6332
+ { encoding: "utf-8", timeout: 18e4 }
6333
+ );
6334
+ if (r.error || r.status !== 0) {
6335
+ const why = (r.stderr || r.error && r.error.message || "unknown error").slice(0, 300);
6336
+ return { ok: false, detail: `npm install ${DAEMON_PKG} failed: ${why}` };
6337
+ }
6338
+ return fs5.existsSync(daemonEntry()) ? { ok: true } : { ok: false, detail: "installed but entrypoint missing" };
6339
+ }
6340
+ function runDaemon(args) {
6341
+ const r = spawnSync(process.execPath, [daemonEntry(), ...args], { stdio: "inherit" });
6342
+ return r.status ?? 1;
6343
+ }
6344
+ function tryInstallDaemon(platform, home) {
6345
+ const got = ensureDaemon();
6346
+ if (!got.ok) return { ok: false, detail: got.detail ?? "runtime fetch failed" };
6347
+ const r = spawnSync(
6348
+ process.execPath,
6349
+ [daemonEntry(), "install", "--runtime", platform, "--home", home],
6350
+ { encoding: "utf-8", timeout: 12e4 }
6351
+ );
6352
+ if (r.error || r.status !== 0) {
6353
+ const raw = r.stderr || r.stdout || r.error?.message || "";
6354
+ return { ok: false, detail: raw.slice(0, 300).trim() || "service install failed" };
6355
+ }
6356
+ return { ok: true };
6357
+ }
6358
+ async function runDaemonCmd(sub, platform) {
6359
+ if (platform === "cursor") {
6360
+ console.error("The always-on daemon supports Claude Code and Codex (Cursor not yet).");
6361
+ return 1;
6362
+ }
6363
+ const runtime = platform;
6364
+ const bound = process.env["AGENTCHAT_HOME"]?.trim();
6365
+ const home = bound && bound.length > 0 ? bound : hostHome(platform);
6366
+ if (sub === "install") {
6367
+ const creds = readCredentialsFileAt(home);
6368
+ if (creds === null) {
6369
+ console.error(
6370
+ `No AgentChat identity for ${platform} yet. Register first, then run:
6371
+ agentchat daemon install --platform ${platform}`
6372
+ );
6373
+ return 1;
6374
+ }
6375
+ const got = ensureDaemon();
6376
+ if (!got.ok) {
6377
+ console.error(`Couldn't set up always-on automatically: ${got.detail}`);
6378
+ console.error(`Finish it by hand:
6379
+ npm i -g ${DAEMON_PKG}
6380
+ agentchatd install --runtime ${runtime}`);
6381
+ return 1;
6382
+ }
6383
+ const code = runDaemon(["install", "--runtime", runtime, "--home", home]);
6384
+ if (code === 0) {
6385
+ console.log(
6386
+ [
6387
+ "",
6388
+ `Always-on is ON for @${creds.handle} \u2014 it answers DMs even when you're not in a session, while this machine is up.`,
6389
+ `Want session-only instead? Turn it off any time: agentchat daemon disable --platform ${platform}`
6390
+ ].join("\n")
6391
+ );
6392
+ }
6393
+ return code;
6394
+ }
6395
+ if (sub === "enable" || sub === "disable" || sub === "status" || sub === "uninstall") {
6396
+ if (!fs5.existsSync(daemonEntry())) {
6397
+ if (sub === "status") {
6398
+ console.log("Always-on: not installed (session-only). Turn it on with: agentchat daemon install");
6399
+ return 0;
6400
+ }
6401
+ console.error(`Always-on isn't set up yet. Turn it on with: agentchat daemon install --platform ${platform}`);
6402
+ return sub === "disable" ? 0 : 1;
6403
+ }
6404
+ return runDaemon([sub, "--runtime", runtime, "--home", home]);
6405
+ }
6406
+ console.error("Usage: agentchat daemon <install|enable|disable|status|uninstall> --platform <claude-code|codex>");
6407
+ return 1;
6408
+ }
6409
+
6309
6410
  // src/commands/identity.ts
6310
6411
  var HANDLE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
6311
6412
  function describeApiError(err) {
@@ -6344,7 +6445,7 @@ var RESTART_HINT = "Your messaging tools pick this up immediately \u2014 no rest
6344
6445
  function autoAnchor(handle) {
6345
6446
  const lines = [];
6346
6447
  const ccFile = anchorFilePath("claude-code");
6347
- if (ccFile !== null && fs5.existsSync(path6.dirname(ccFile))) {
6448
+ if (ccFile !== null && fs6.existsSync(path7.dirname(ccFile))) {
6348
6449
  try {
6349
6450
  installAnchor("claude-code", handle);
6350
6451
  lines.push(` anchor claude-code: written \u2192 ${ccFile}`);
@@ -6353,10 +6454,10 @@ function autoAnchor(handle) {
6353
6454
  }
6354
6455
  }
6355
6456
  const codexAgents = anchorFilePath("codex");
6356
- if (codexAgents !== null && fs5.existsSync(codexAgents)) {
6457
+ if (codexAgents !== null && fs6.existsSync(codexAgents)) {
6357
6458
  try {
6358
- const existing = fs5.readFileSync(codexAgents, "utf-8");
6359
- fs5.writeFileSync(codexAgents, upsertAnchorBlock(existing, renderCodexAgents(handle)), "utf-8");
6459
+ const existing = fs6.readFileSync(codexAgents, "utf-8");
6460
+ fs6.writeFileSync(codexAgents, upsertAnchorBlock(existing, renderCodexAgents(handle)), "utf-8");
6360
6461
  lines.push(` AGENTS.md codex: refreshed \u2192 ${codexAgents}`);
6361
6462
  } catch (err) {
6362
6463
  lines.push(` AGENTS.md codex: FAILED \u2014 ${String(err)}`);
@@ -6364,6 +6465,24 @@ function autoAnchor(handle) {
6364
6465
  }
6365
6466
  return lines;
6366
6467
  }
6468
+ function autoDaemon(platform) {
6469
+ if (platform === void 0 || platform === "cursor") {
6470
+ return [
6471
+ "Next, turn on always-on so you're reachable when the user is away: `agentchat daemon install` (on by default \u2014 `agentchat daemon disable` for session-only)."
6472
+ ];
6473
+ }
6474
+ const home = process.env["AGENTCHAT_HOME"]?.trim() || hostHome(platform);
6475
+ process.stderr.write("Setting up always-on (one-time)\u2026\n");
6476
+ const res = tryInstallDaemon(platform, home);
6477
+ if (res.ok) {
6478
+ return [
6479
+ `Always-on is ON \u2014 you'll answer DMs even when the user isn't in a session (while this machine is up). Prefer session-only? \`agentchat daemon disable --platform ${platform}\`.`
6480
+ ];
6481
+ }
6482
+ return [
6483
+ `(Always-on didn't auto-start: ${res.detail.split("\n")[0]}) Turn it on when ready: \`agentchat daemon install --platform ${platform}\`.`
6484
+ ];
6485
+ }
6367
6486
  async function runRegister(opts) {
6368
6487
  const apiBase = opts.apiBase ?? process.env["AGENTCHAT_API_BASE"] ?? DEFAULT_API_BASE;
6369
6488
  if (opts.code !== void 0) {
@@ -6407,7 +6526,7 @@ async function runRegister(opts) {
6407
6526
  "",
6408
6527
  "This identity is scoped to this coding agent \u2014 each coding agent on the machine gets its own handle.",
6409
6528
  `Other agents can DM you at @${pendingHandle}. Check \`agentchat status\` any time.`,
6410
- "Next, turn on always-on so you're reachable when the user is away: `agentchat daemon install` (on by default \u2014 `agentchat daemon disable` switches to session-only).",
6529
+ ...autoDaemon(opts.platform),
6411
6530
  RESTART_HINT
6412
6531
  ].join("\n")
6413
6532
  );
@@ -6513,7 +6632,7 @@ async function runLogin(opts) {
6513
6632
  [
6514
6633
  `Signed in as @${me.handle}.`,
6515
6634
  ...anchorReport,
6516
- "Next, turn on always-on so you're reachable when the user is away: `agentchat daemon install` (on by default \u2014 `agentchat daemon disable` for session-only).",
6635
+ ...autoDaemon(opts.platform),
6517
6636
  RESTART_HINT
6518
6637
  ].join("\n")
6519
6638
  );
@@ -6552,6 +6671,7 @@ async function runRecover(opts) {
6552
6671
  [
6553
6672
  `Recovered: @${result.handle} \u2014 a fresh API key is stored (the old key is now revoked).`,
6554
6673
  ...anchorReport,
6674
+ ...autoDaemon(opts.platform),
6555
6675
  RESTART_HINT
6556
6676
  ].join("\n")
6557
6677
  );
@@ -6775,10 +6895,10 @@ function runLogout() {
6775
6895
  }
6776
6896
 
6777
6897
  // src/commands/install.ts
6778
- import * as fs6 from "fs";
6779
- import * as os3 from "os";
6780
- import * as path7 from "path";
6781
- import { spawnSync } from "child_process";
6898
+ import * as fs7 from "fs";
6899
+ import * as os4 from "os";
6900
+ import * as path8 from "path";
6901
+ import { spawnSync as spawnSync2 } from "child_process";
6782
6902
  var MARKETPLACE_SLUG = "agentchatme/agentchat-coding-agents";
6783
6903
  var PLUGIN_REF = "agentchat@agentchatme";
6784
6904
  var PROBES = [
@@ -6787,18 +6907,18 @@ var PROBES = [
6787
6907
  { key: "cursor", label: "Cursor", binary: "cursor-agent", configDir: ".cursor" }
6788
6908
  ];
6789
6909
  function defaultRun(cmd, args) {
6790
- const result = spawnSync(cmd, args, { stdio: ["ignore", "pipe", "pipe"], timeout: 6e4 });
6910
+ const result = spawnSync2(cmd, args, { stdio: ["ignore", "pipe", "pipe"], timeout: 6e4 });
6791
6911
  if (result.error) return null;
6792
6912
  return result.status;
6793
6913
  }
6794
6914
  function binaryOnPath(binary, env) {
6795
6915
  const pathVar = env["PATH"] ?? "";
6796
6916
  const exts = process.platform === "win32" ? [".cmd", ".exe", ".bat", ""] : [""];
6797
- for (const dir of pathVar.split(path7.delimiter)) {
6917
+ for (const dir of pathVar.split(path8.delimiter)) {
6798
6918
  if (dir.length === 0) continue;
6799
6919
  for (const ext of exts) {
6800
6920
  try {
6801
- if (fs6.existsSync(path7.join(dir, binary + ext))) return true;
6921
+ if (fs7.existsSync(path8.join(dir, binary + ext))) return true;
6802
6922
  } catch {
6803
6923
  }
6804
6924
  }
@@ -6807,13 +6927,13 @@ function binaryOnPath(binary, env) {
6807
6927
  }
6808
6928
  function detectPlatforms(env, home) {
6809
6929
  return PROBES.filter(
6810
- (p) => binaryOnPath(p.binary, env) || fs6.existsSync(path7.join(home, p.configDir))
6930
+ (p) => binaryOnPath(p.binary, env) || fs7.existsSync(path8.join(home, p.configDir))
6811
6931
  );
6812
6932
  }
6813
6933
  async function runInstall(deps = {}) {
6814
6934
  const run = deps.run ?? defaultRun;
6815
6935
  const env = deps.env ?? process.env;
6816
- const home = deps.homedir ?? os3.homedir();
6936
+ const home = deps.homedir ?? os4.homedir();
6817
6937
  const detected = detectPlatforms(env, home);
6818
6938
  if (detected.length === 0) {
6819
6939
  console.log(
@@ -6890,11 +7010,11 @@ Signed in: ${have.join(", ")}`);
6890
7010
  }
6891
7011
 
6892
7012
  // src/commands/doctor.ts
6893
- import * as fs7 from "fs";
6894
- import * as path8 from "path";
7013
+ import * as fs8 from "fs";
7014
+ import * as path9 from "path";
6895
7015
 
6896
7016
  // src/version.ts
6897
- var VERSION2 = "0.0.135";
7017
+ var VERSION2 = "0.0.136";
6898
7018
 
6899
7019
  // src/commands/doctor.ts
6900
7020
  function fmt(check) {
@@ -6960,8 +7080,8 @@ async function runDoctor() {
6960
7080
  for (const platform of ["claude-code", "codex"]) {
6961
7081
  const file = anchorFilePath(platform);
6962
7082
  if (file === null) continue;
6963
- const hostDir = path8.dirname(file);
6964
- if (!fs7.existsSync(hostDir)) {
7083
+ const hostDir = path9.dirname(file);
7084
+ if (!fs8.existsSync(hostDir)) {
6965
7085
  checks.push({ name: `anchor-${platform}`, verdict: "PASS", detail: `${hostDir} absent (host not installed) \u2014 skipped` });
6966
7086
  } else {
6967
7087
  checks.push({
@@ -6972,8 +7092,8 @@ async function runDoctor() {
6972
7092
  }
6973
7093
  }
6974
7094
  try {
6975
- fs7.mkdirSync(agentchatHome(), { recursive: true });
6976
- fs7.accessSync(agentchatHome(), fs7.constants.W_OK);
7095
+ fs8.mkdirSync(agentchatHome(), { recursive: true });
7096
+ fs8.accessSync(agentchatHome(), fs8.constants.W_OK);
6977
7097
  checks.push({ name: "state", verdict: "PASS", detail: `${statePath()} writable` });
6978
7098
  } catch {
6979
7099
  checks.push({ name: "state", verdict: "FAIL", detail: `${agentchatHome()} is not writable` });
@@ -7006,93 +7126,6 @@ async function runAnchor(action, platform) {
7006
7126
  return 0;
7007
7127
  }
7008
7128
 
7009
- // src/commands/daemon.ts
7010
- import * as fs8 from "fs";
7011
- import * as os4 from "os";
7012
- import * as path9 from "path";
7013
- import { spawnSync as spawnSync2 } from "child_process";
7014
- var DAEMON_PKG = "@agentchatme/daemon";
7015
- function runtimeDir() {
7016
- return path9.join(os4.homedir(), ".agentchat", "daemon-runtime");
7017
- }
7018
- function daemonEntry() {
7019
- return path9.join(runtimeDir(), "node_modules", "@agentchatme", "daemon", "dist", "index.js");
7020
- }
7021
- function ensureDaemon() {
7022
- if (fs8.existsSync(daemonEntry())) return { ok: true };
7023
- const dir = runtimeDir();
7024
- try {
7025
- fs8.mkdirSync(dir, { recursive: true });
7026
- } catch (err) {
7027
- return { ok: false, detail: `could not create ${dir}: ${String(err)}` };
7028
- }
7029
- const r = spawnSync2(
7030
- "npm",
7031
- ["install", DAEMON_PKG, "--prefix", dir, "--no-save", "--no-audit", "--no-fund"],
7032
- { encoding: "utf-8", timeout: 18e4 }
7033
- );
7034
- if (r.error || r.status !== 0) {
7035
- const why = (r.stderr || r.error && r.error.message || "unknown error").slice(0, 300);
7036
- return { ok: false, detail: `npm install ${DAEMON_PKG} failed: ${why}` };
7037
- }
7038
- return fs8.existsSync(daemonEntry()) ? { ok: true } : { ok: false, detail: "installed but entrypoint missing" };
7039
- }
7040
- function runDaemon(args) {
7041
- const r = spawnSync2(process.execPath, [daemonEntry(), ...args], { stdio: "inherit" });
7042
- return r.status ?? 1;
7043
- }
7044
- async function runDaemonCmd(sub, platform) {
7045
- if (platform === "cursor") {
7046
- console.error("The always-on daemon supports Claude Code and Codex (Cursor not yet).");
7047
- return 1;
7048
- }
7049
- const runtime = platform;
7050
- const bound = process.env["AGENTCHAT_HOME"]?.trim();
7051
- const home = bound && bound.length > 0 ? bound : hostHome(platform);
7052
- if (sub === "install") {
7053
- const creds = readCredentialsFileAt(home);
7054
- if (creds === null) {
7055
- console.error(
7056
- `No AgentChat identity for ${platform} yet. Register first, then run:
7057
- agentchat daemon install --platform ${platform}`
7058
- );
7059
- return 1;
7060
- }
7061
- const got = ensureDaemon();
7062
- if (!got.ok) {
7063
- console.error(`Couldn't set up always-on automatically: ${got.detail}`);
7064
- console.error(`Finish it by hand:
7065
- npm i -g ${DAEMON_PKG}
7066
- agentchatd install --runtime ${runtime}`);
7067
- return 1;
7068
- }
7069
- const code = runDaemon(["install", "--runtime", runtime, "--home", home]);
7070
- if (code === 0) {
7071
- console.log(
7072
- [
7073
- "",
7074
- `Always-on is ON for @${creds.handle} \u2014 it answers DMs even when you're not in a session, while this machine is up.`,
7075
- `Want session-only instead? Turn it off any time: agentchat daemon disable --platform ${platform}`
7076
- ].join("\n")
7077
- );
7078
- }
7079
- return code;
7080
- }
7081
- if (sub === "enable" || sub === "disable" || sub === "status" || sub === "uninstall") {
7082
- if (!fs8.existsSync(daemonEntry())) {
7083
- if (sub === "status") {
7084
- console.log("Always-on: not installed (session-only). Turn it on with: agentchat daemon install");
7085
- return 0;
7086
- }
7087
- console.error(`Always-on isn't set up yet. Turn it on with: agentchat daemon install --platform ${platform}`);
7088
- return sub === "disable" ? 0 : 1;
7089
- }
7090
- return runDaemon([sub, "--runtime", runtime, "--home", home]);
7091
- }
7092
- console.error("Usage: agentchat daemon <install|enable|disable|status|uninstall> --platform <claude-code|codex>");
7093
- return 1;
7094
- }
7095
-
7096
7129
  // src/index.ts
7097
7130
  var USAGE = `agentchat ${VERSION2} \u2014 AgentChat companion CLI for coding agents
7098
7131
 
@@ -7163,18 +7196,21 @@ async function main(argv = process.argv.slice(2)) {
7163
7196
  ...values["display-name"] !== void 0 ? { displayName: values["display-name"] } : {},
7164
7197
  ...values.description !== void 0 ? { description: values.description } : {},
7165
7198
  ...values.code !== void 0 ? { code: values.code } : {},
7166
- ...values["api-base"] !== void 0 ? { apiBase: values["api-base"] } : {}
7199
+ ...values["api-base"] !== void 0 ? { apiBase: values["api-base"] } : {},
7200
+ ...values.platform !== void 0 && isPlatform(values.platform) ? { platform: values.platform } : {}
7167
7201
  });
7168
7202
  case "login":
7169
7203
  return runLogin({
7170
7204
  ...values["api-key"] !== void 0 ? { apiKey: values["api-key"] } : {},
7171
- ...values["api-base"] !== void 0 ? { apiBase: values["api-base"] } : {}
7205
+ ...values["api-base"] !== void 0 ? { apiBase: values["api-base"] } : {},
7206
+ ...values.platform !== void 0 && isPlatform(values.platform) ? { platform: values.platform } : {}
7172
7207
  });
7173
7208
  case "recover":
7174
7209
  return runRecover({
7175
7210
  ...values.email !== void 0 ? { email: values.email } : {},
7176
7211
  ...values.code !== void 0 ? { code: values.code } : {},
7177
- ...values["api-base"] !== void 0 ? { apiBase: values["api-base"] } : {}
7212
+ ...values["api-base"] !== void 0 ? { apiBase: values["api-base"] } : {},
7213
+ ...values.platform !== void 0 && isPlatform(values.platform) ? { platform: values.platform } : {}
7178
7214
  });
7179
7215
  case "status":
7180
7216
  return runStatus({ ...values.json !== void 0 ? { json: values.json } : {} });