@lesscap/baton-cli 0.2.2 → 0.2.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.
Files changed (2) hide show
  1. package/dist/baton.mjs +184 -28
  2. package/package.json +1 -1
package/dist/baton.mjs CHANGED
@@ -550,6 +550,7 @@ var requirementClient = (baseUrl) => {
550
550
  listByProject: (projectId) => request(u(`/projects/${projectId}/requirements`), { method: "GET" }),
551
551
  get: (id) => request(u(`/requirements/${id}`), { method: "GET" }),
552
552
  getByCode: (projectId, code) => fetchItemByCode(baseUrl, projectId, code, "requirement"),
553
+ update: (id, patch2) => request(u(`/requirements/${id}`), { method: "PATCH", body: patch2 }),
553
554
  setStatus: (id, status) => request(u(`/requirements/${id}`), { method: "PATCH", body: { status } }),
554
555
  remove: (id) => request(u(`/requirements/${id}`), { method: "DELETE" })
555
556
  };
@@ -587,9 +588,13 @@ var sessionsClient = (baseUrl) => {
587
588
  const matches = all.filter((s) => s.name === name);
588
589
  return matches.length === 0 ? null : matches[matches.length - 1] ?? null;
589
590
  },
590
- sendMessage: (id, text, attachments) => request(u(`/sessions/${id}/messages`), {
591
+ sendMessage: (id, text, attachments, planMode) => request(u(`/sessions/${id}/messages`), {
591
592
  method: "POST",
592
- body: attachments && attachments.length > 0 ? { text, attachments } : { text }
593
+ body: {
594
+ text,
595
+ ...attachments && attachments.length > 0 ? { attachments } : {},
596
+ ...planMode ? { planMode: true } : {}
597
+ }
593
598
  }),
594
599
  // Raw-body upload: the file streams as the request body (no multipart), so
595
600
  // a Blob backed by a file on disk uploads without buffering. filename rides
@@ -618,6 +623,7 @@ var taskClient = (baseUrl) => {
618
623
  listByRequirement: (requirementId) => request(u(`/requirements/${requirementId}/tasks`), { method: "GET" }),
619
624
  get: (id) => request(u(`/tasks/${id}`), { method: "GET" }),
620
625
  getByCode: (projectId, code) => fetchItemByCode(baseUrl, projectId, code, "task"),
626
+ update: (id, patch2) => request(u(`/tasks/${id}`), { method: "PATCH", body: patch2 }),
621
627
  setStatus: (id, status) => request(u(`/tasks/${id}`), { method: "PATCH", body: { status } }),
622
628
  remove: (id) => request(u(`/tasks/${id}`), { method: "DELETE" }),
623
629
  listComments: (id) => request(u(`/tasks/${id}/comments`), { method: "GET" }),
@@ -734,6 +740,11 @@ var viewWorker = (cfg) => {
734
740
  apiToken: worker2.apiToken
735
741
  };
736
742
  };
743
+ var worktreeConfig = (cfg) => ({
744
+ server: cfg.server,
745
+ project: cfg.projectId,
746
+ worker: { id: cfg.workerId, name: cfg.name, machineId: cfg.machineId, apiToken: cfg.apiToken }
747
+ });
737
748
 
738
749
  // src/config.ts
739
750
  var resolveBaseUrl = (urlArg, env = process.env) => {
@@ -772,6 +783,12 @@ var resolveWorkspaceId = (args) => {
772
783
  "no workspace in scope. pass --workspace <id> or run `baton init` in this directory."
773
784
  );
774
785
  };
786
+ var parseIssueUrl = (url) => {
787
+ const m = url.match(/^https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/);
788
+ if (!m)
789
+ throw new Error(`expected a GitHub issue url (https://github.com/o/r/issues/N), got "${url}"`);
790
+ return { source: "github", number: Number(m[1]), url: url.split(/[?#]/)[0] };
791
+ };
775
792
  var splitCsv = (s) => s ? s.split(",").map((x) => x.trim()).filter(Boolean) : void 0;
776
793
 
777
794
  // src/commands/init.ts
@@ -931,6 +948,7 @@ var project = defineCommand({
931
948
 
932
949
  // src/commands/requirement.ts
933
950
  var createRequirement = (c, input, json) => c.requirements.create(input).then((r) => renderOne(r, fmtRequirement, json));
951
+ var updateRequirement = (c, id, patch2, json) => c.requirements.update(id, patch2).then((r) => renderOne(r, fmtRequirement, json));
934
952
  var listRequirements = (c, projectId, json) => c.requirements.listByProject(projectId).then((rs) => renderList(rs, fmtRequirement, json));
935
953
  var getRequirement = (c, id, json) => c.requirements.get(id).then((r) => renderOne(r, fmtRequirement, json));
936
954
  var setRequirementStatus = (c, id, status, json) => c.requirements.setStatus(id, status).then((r) => renderOne(r, fmtRequirement, json));
@@ -946,6 +964,7 @@ var requirement = defineCommand({
946
964
  project: { type: "string", description: "project id (overrides .baton.json)" },
947
965
  desc: { type: "string", description: "description" },
948
966
  body: { type: "string", description: "requirement body (markdown)" },
967
+ github: { type: "string", description: "link a GitHub issue url (light association)" },
949
968
  ...common
950
969
  },
951
970
  run: async ({ args }) => {
@@ -956,13 +975,69 @@ var requirement = defineCommand({
956
975
  projectId: resolveProjectId(args),
957
976
  title: args.title,
958
977
  description: args.desc,
959
- body: args.body
978
+ body: args.body,
979
+ external: args.github ? parseIssueUrl(args.github) : void 0
960
980
  },
961
981
  Boolean(args.json)
962
982
  )
963
983
  );
964
984
  }
965
985
  }),
986
+ update: defineCommand({
987
+ meta: { name: "update", description: "update a requirement title / body" },
988
+ args: {
989
+ code: { type: "positional", required: true, description: "requirement code (R-N)" },
990
+ title: { type: "string", description: "new title" },
991
+ body: { type: "string", description: "new body (markdown)" },
992
+ project: { type: "string", description: "project id (overrides .baton.json)" },
993
+ ...common
994
+ },
995
+ run: async ({ args }) => {
996
+ const patch2 = {
997
+ ...args.title !== void 0 ? { title: args.title } : {},
998
+ ...args.body !== void 0 ? { body: args.body } : {}
999
+ };
1000
+ if (Object.keys(patch2).length === 0) throw new Error("pass --title and/or --body");
1001
+ const c = clientFor(args);
1002
+ const id = await resolveByCode(c, resolveProjectId(args), args.code);
1003
+ console.log(await updateRequirement(c, id, patch2, Boolean(args.json)));
1004
+ }
1005
+ }),
1006
+ link: defineCommand({
1007
+ meta: { name: "link", description: "link a requirement to a GitHub issue url" },
1008
+ args: {
1009
+ code: { type: "positional", required: true, description: "requirement code (R-N)" },
1010
+ // Named `issue` (not `url`) — `url` would collide with the common --url flag.
1011
+ issue: { type: "positional", required: true, description: "GitHub issue url" },
1012
+ project: { type: "string", description: "project id (overrides .baton.json)" },
1013
+ ...common
1014
+ },
1015
+ run: async ({ args }) => {
1016
+ const c = clientFor(args);
1017
+ const id = await resolveByCode(c, resolveProjectId(args), args.code);
1018
+ console.log(
1019
+ await updateRequirement(
1020
+ c,
1021
+ id,
1022
+ { external: parseIssueUrl(args.issue) },
1023
+ Boolean(args.json)
1024
+ )
1025
+ );
1026
+ }
1027
+ }),
1028
+ unlink: defineCommand({
1029
+ meta: { name: "unlink", description: "clear a requirement\u2019s GitHub issue association" },
1030
+ args: {
1031
+ code: { type: "positional", required: true, description: "requirement code (R-N)" },
1032
+ project: { type: "string", description: "project id (overrides .baton.json)" },
1033
+ ...common
1034
+ },
1035
+ run: async ({ args }) => {
1036
+ const c = clientFor(args);
1037
+ const id = await resolveByCode(c, resolveProjectId(args), args.code);
1038
+ console.log(await updateRequirement(c, id, { external: null }, Boolean(args.json)));
1039
+ }
1040
+ }),
966
1041
  ls: defineCommand({
967
1042
  meta: { name: "ls", description: "list requirements in a project" },
968
1043
  args: {
@@ -1795,14 +1870,15 @@ ${text}` : header;
1795
1870
  };
1796
1871
 
1797
1872
  // src/session/runner/query.ts
1798
- var startQuery = (config, text, resuming, queryFn, abortController, log, envOverlay) => {
1873
+ var startQuery = (config, text, resuming, queryFn, abortController, log, envOverlay, planMode = false) => {
1799
1874
  const env = buildSdkEnv(envOverlay);
1800
1875
  const exe = claudeExecutable();
1801
1876
  const addDirs = additionalDirs();
1802
1877
  if (addDirs) log(`[add-dir] ${addDirs.join(", ")}`);
1878
+ if (planMode) log("[plan] read-only planning turn");
1803
1879
  const options = {
1804
1880
  cwd: config.worktreePath,
1805
- permissionMode: "bypassPermissions",
1881
+ permissionMode: planMode ? "plan" : "bypassPermissions",
1806
1882
  includePartialMessages: false,
1807
1883
  abortController,
1808
1884
  stderr: (line) => log(`[claude] ${line.trimEnd()}`),
@@ -1868,6 +1944,7 @@ var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => conso
1868
1944
  const payload = msg.payload;
1869
1945
  const rawText = typeof payload?.text === "string" ? payload.text : "";
1870
1946
  const attachments = Array.isArray(payload?.attachments) ? payload.attachments : [];
1947
+ const planMode = payload?.planMode === true;
1871
1948
  if (rawText.length === 0 && attachments.length === 0) {
1872
1949
  await worker2.emitEvent("turn_error", { message: "user_message missing text and attachments" });
1873
1950
  return -1;
@@ -1883,15 +1960,15 @@ var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => conso
1883
1960
  const abort = new AbortController();
1884
1961
  const ceiling = turnTimeoutMs();
1885
1962
  let timer;
1886
- const timeout = new Promise((resolve) => {
1887
- timer = setTimeout(() => resolve(TIMEOUT), ceiling);
1963
+ const timeout = new Promise((resolve2) => {
1964
+ timer = setTimeout(() => resolve2(TIMEOUT), ceiling);
1888
1965
  });
1889
- const interrupted = new Promise((resolve) => {
1890
- if (externalSignal?.aborted) resolve(ABORTED);
1891
- else externalSignal?.addEventListener("abort", () => resolve(ABORTED), { once: true });
1966
+ const interrupted = new Promise((resolve2) => {
1967
+ if (externalSignal?.aborted) resolve2(ABORTED);
1968
+ else externalSignal?.addEventListener("abort", () => resolve2(ABORTED), { once: true });
1892
1969
  });
1893
1970
  try {
1894
- const messages = startQuery(config, text, resuming, queryFn, abort, log, envOverlay);
1971
+ const messages = startQuery(config, text, resuming, queryFn, abort, log, envOverlay, planMode);
1895
1972
  const consume = streamSdkEvents(messages, worker2);
1896
1973
  void consume.catch(() => {
1897
1974
  });
@@ -1906,7 +1983,9 @@ var runTurn = async (config, worker2, msg, resuming, queryFn, log = (m) => conso
1906
1983
  if (outcome === TIMEOUT) {
1907
1984
  log(`[watchdog] turn exceeded ${ceiling}ms \u2014 aborting claude`);
1908
1985
  abort.abort();
1909
- await worker2.emitEvent("turn_error", { message: `turn exceeded ${ceiling}ms \u2014 claude aborted` });
1986
+ await worker2.emitEvent("turn_error", {
1987
+ message: `turn exceeded ${ceiling}ms \u2014 claude aborted`
1988
+ });
1910
1989
  await worker2.emitEvent("turn_complete", {});
1911
1990
  return -1;
1912
1991
  }
@@ -1940,9 +2019,9 @@ var subscribeStream = (url, ESCtor, seen, log, onUserMessage, onInterrupt, onRea
1940
2019
  es.onerror = () => log("sse error (eventsource will retry)");
1941
2020
  return es;
1942
2021
  };
1943
- var waitForAbort = (signal) => new Promise((resolve) => {
1944
- if (signal.aborted) return resolve();
1945
- signal.addEventListener("abort", () => resolve(), { once: true });
2022
+ var waitForAbort = (signal) => new Promise((resolve2) => {
2023
+ if (signal.aborted) return resolve2();
2024
+ signal.addEventListener("abort", () => resolve2(), { once: true });
1946
2025
  });
1947
2026
  var shouldReap = (lastActivity, now, busy, queueLen, idleMs) => !busy && queueLen === 0 && now - lastActivity >= idleMs;
1948
2027
  var idleMsFromEnv = () => Number(process.env.BATON_SESSION_IDLE_MS) || 30 * 6e4;
@@ -2025,12 +2104,12 @@ var runDaemon = async (config, deps, signal) => {
2025
2104
  );
2026
2105
  const idleMs = idleMsFromEnv();
2027
2106
  let idleTimer;
2028
- const reaped = new Promise((resolve) => {
2107
+ const reaped = new Promise((resolve2) => {
2029
2108
  idleTimer = setInterval(
2030
2109
  () => {
2031
2110
  if (shouldReap(lastActivity, Date.now(), busy, pendingQueue.length, idleMs)) {
2032
2111
  log("idle \u2014 shutting down (resumes on next message)");
2033
- resolve();
2112
+ resolve2();
2034
2113
  }
2035
2114
  },
2036
2115
  Math.min(idleMs, 3e4)
@@ -2209,6 +2288,7 @@ var session = defineCommand({
2209
2288
 
2210
2289
  // src/commands/task.ts
2211
2290
  var createTask = (c, input, json) => c.tasks.create(input).then((t) => renderOne(t, fmtTask, json));
2291
+ var updateTask = (c, id, patch2, json) => c.tasks.update(id, patch2).then((t) => renderOne(t, fmtTask, json));
2212
2292
  var listTasks = (c, requirementId, json) => c.tasks.listByRequirement(requirementId).then((ts) => renderList(ts, fmtTask, json));
2213
2293
  var getTask = (c, id, json) => c.tasks.get(id).then((t) => renderOne(t, fmtTask, json));
2214
2294
  var setTaskStatus = (c, id, status, json) => c.tasks.setStatus(id, status).then((t) => renderOne(t, fmtTask, json));
@@ -2228,6 +2308,7 @@ var task = defineCommand({
2228
2308
  project: { type: "string", description: "project id (overrides .baton.json)" },
2229
2309
  body: { type: "string", description: "task body (markdown)" },
2230
2310
  deps: { type: "string", description: "comma-separated dependency task codes (T-N,T-N)" },
2311
+ github: { type: "string", description: "link a GitHub issue url (light association)" },
2231
2312
  ...common
2232
2313
  },
2233
2314
  run: async ({ args }) => {
@@ -2245,13 +2326,64 @@ var task = defineCommand({
2245
2326
  requirementId,
2246
2327
  title: args.title,
2247
2328
  body: args.body,
2248
- dependsOn: dependsOn.length ? dependsOn : void 0
2329
+ dependsOn: dependsOn.length ? dependsOn : void 0,
2330
+ external: args.github ? parseIssueUrl(args.github) : void 0
2249
2331
  },
2250
2332
  Boolean(args.json)
2251
2333
  )
2252
2334
  );
2253
2335
  }
2254
2336
  }),
2337
+ update: defineCommand({
2338
+ meta: { name: "update", description: "update a task title / body" },
2339
+ args: {
2340
+ code: { type: "positional", required: true, description: "task code (T-N)" },
2341
+ title: { type: "string", description: "new title" },
2342
+ body: { type: "string", description: "new body (markdown)" },
2343
+ project: { type: "string", description: "project id (overrides .baton.json)" },
2344
+ ...common
2345
+ },
2346
+ run: async ({ args }) => {
2347
+ const patch2 = {
2348
+ ...args.title !== void 0 ? { title: args.title } : {},
2349
+ ...args.body !== void 0 ? { body: args.body } : {}
2350
+ };
2351
+ if (Object.keys(patch2).length === 0) throw new Error("pass --title and/or --body");
2352
+ const c = clientFor(args);
2353
+ const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
2354
+ console.log(await updateTask(c, id, patch2, Boolean(args.json)));
2355
+ }
2356
+ }),
2357
+ link: defineCommand({
2358
+ meta: { name: "link", description: "link a task to a GitHub issue url" },
2359
+ args: {
2360
+ code: { type: "positional", required: true, description: "task code (T-N)" },
2361
+ // Named `issue` (not `url`) — `url` would collide with the common --url flag.
2362
+ issue: { type: "positional", required: true, description: "GitHub issue url" },
2363
+ project: { type: "string", description: "project id (overrides .baton.json)" },
2364
+ ...common
2365
+ },
2366
+ run: async ({ args }) => {
2367
+ const c = clientFor(args);
2368
+ const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
2369
+ console.log(
2370
+ await updateTask(c, id, { external: parseIssueUrl(args.issue) }, Boolean(args.json))
2371
+ );
2372
+ }
2373
+ }),
2374
+ unlink: defineCommand({
2375
+ meta: { name: "unlink", description: "clear a task\u2019s GitHub issue association" },
2376
+ args: {
2377
+ code: { type: "positional", required: true, description: "task code (T-N)" },
2378
+ project: { type: "string", description: "project id (overrides .baton.json)" },
2379
+ ...common
2380
+ },
2381
+ run: async ({ args }) => {
2382
+ const c = clientFor(args);
2383
+ const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
2384
+ console.log(await updateTask(c, id, { external: null }, Boolean(args.json)));
2385
+ }
2386
+ }),
2255
2387
  ls: defineCommand({
2256
2388
  meta: { name: "ls", description: "list tasks in a requirement" },
2257
2389
  args: {
@@ -2281,7 +2413,7 @@ var task = defineCommand({
2281
2413
  "set-status": defineCommand({
2282
2414
  meta: {
2283
2415
  name: "set-status",
2284
- description: "set task status (todo|in_progress|done|failed|cancelled)"
2416
+ description: "set task status (todo|in_progress|blocked|done|failed|cancelled)"
2285
2417
  },
2286
2418
  args: {
2287
2419
  code: { type: "positional", required: true, description: "task code (T-N)" },
@@ -2359,7 +2491,7 @@ import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
2359
2491
  // src/session/runner/title.ts
2360
2492
  var clip = (s, max) => s.length > max ? s.slice(0, max) : s;
2361
2493
  var isDeclined = (title) => title.replace(/[^a-z]/gi, "").toUpperCase() === "NONE";
2362
- var sanitizeTitle = (raw) => raw.replace(/[\r\n]+/g, " ").replace(/["'`]/g, "").replace(/^\s*(title|session)\s*[:-]\s*/i, "").replace(/\s+/g, " ").trim().slice(0, 40).trim();
2494
+ var sanitizeTitle = (raw) => raw.replace(/[\r\n]+/g, " ").replace(/[*_`~#>]/g, "").replace(/["']/g, "").replace(/^\s*(?:title|session|标题)\s*[::-]\s*/i, "").replace(/^\s*(?:[-*•]|\d+[.)、])\s+/, "").replace(/\s+/g, " ").trim().slice(0, 30).replace(/[\s。.,,、;;::!!??.]+$/, "").trim();
2363
2495
  var TITLE_TIMEOUT_MS = 3e4;
2364
2496
  var generateTitle = async (input) => {
2365
2497
  const { worktreePath, userText, assistantText, queryFn } = input;
@@ -2368,7 +2500,8 @@ var generateTitle = async (input) => {
2368
2500
  `User: ${clip(userText, 800)}`,
2369
2501
  assistantText ? `Assistant: ${clip(assistantText, 800)}` : ""
2370
2502
  ].filter(Boolean).join("\n");
2371
- const prompt = `Reply with ONLY a 2-5 word title (no quotes, no punctuation) summarizing this coding session. If it is too short or generic to title meaningfully, reply with exactly NONE:
2503
+ const prompt = `Reply with ONLY a short title for this session: a noun phrase like a filename \u2014 at most 6 words or ~12 Chinese characters. It must NOT be a sentence, no punctuation, no markdown, no quotes, and never an opener like "\u597D\u7684"/"\u6536\u5230"/"I'll". If it is too thin or generic to title meaningfully, reply with exactly NONE.
2504
+
2372
2505
  ${exchange}`;
2373
2506
  const exe = claudeExecutable();
2374
2507
  const abort = new AbortController();
@@ -2379,6 +2512,9 @@ ${exchange}`;
2379
2512
  prompt,
2380
2513
  options: {
2381
2514
  cwd: worktreePath,
2515
+ // Don't load the worktree's CLAUDE.md / project settings — they steer the
2516
+ // model into verbose summaries instead of a terse title.
2517
+ settingSources: [],
2382
2518
  permissionMode: "bypassPermissions",
2383
2519
  allowedTools: [],
2384
2520
  includePartialMessages: false,
@@ -2401,8 +2537,8 @@ ${exchange}`;
2401
2537
 
2402
2538
  // src/session/worktree.ts
2403
2539
  import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
2404
- import { existsSync as existsSync4, mkdirSync } from "node:fs";
2405
- import { dirname } from "node:path";
2540
+ import { appendFileSync, existsSync as existsSync4, mkdirSync, readFileSync as readFileSync3 } from "node:fs";
2541
+ import { dirname, isAbsolute as isAbsolute2, resolve } from "node:path";
2406
2542
  var createWorktree = (input) => {
2407
2543
  if (existsSync4(input.worktreePath))
2408
2544
  throw new Error(`worktree path already exists: ${input.worktreePath}`);
@@ -2425,6 +2561,24 @@ var repoHeadBranch = (repo) => {
2425
2561
  const branch = r.status === 0 ? r.stdout.trim() : "";
2426
2562
  return branch || "main";
2427
2563
  };
2564
+ var ensureExcluded = (repo, pattern) => {
2565
+ try {
2566
+ const r = spawnSync2("git", ["-C", repo, "rev-parse", "--git-path", "info/exclude"], {
2567
+ stdio: "pipe",
2568
+ encoding: "utf8"
2569
+ });
2570
+ if (r.status !== 0) return;
2571
+ const rel = r.stdout.trim();
2572
+ const path = isAbsolute2(rel) ? rel : resolve(repo, rel);
2573
+ const current = existsSync4(path) ? readFileSync3(path, "utf8") : "";
2574
+ if (current.split("\n").includes(pattern)) return;
2575
+ mkdirSync(dirname(path), { recursive: true });
2576
+ const sep = current === "" || current.endsWith("\n") ? "" : "\n";
2577
+ appendFileSync(path, `${sep}${pattern}
2578
+ `, "utf8");
2579
+ } catch {
2580
+ }
2581
+ };
2428
2582
  var removeWorktree = (repo, worktreePath) => {
2429
2583
  if (!existsSync4(worktreePath)) return;
2430
2584
  try {
@@ -2494,6 +2648,8 @@ var runWorkerDaemon = async (cfg, client, signal) => {
2494
2648
  await client.sessions.materialize(sessionId, { agentSessionId, worktreePath }, cfg.apiToken);
2495
2649
  log(`materialized session #${sessionId} \u2192 ${worktreePath}`);
2496
2650
  }
2651
+ ensureExcluded(repo, PROJECT_CONFIG_NAME);
2652
+ saveProjectConfig(join5(worktreePath, PROJECT_CONFIG_NAME), worktreeConfig(cfg));
2497
2653
  spawnChild(sessionId, worktreePath);
2498
2654
  };
2499
2655
  const onStop = (sessionId) => {
@@ -2565,9 +2721,9 @@ var runWorkerDaemon = async (cfg, client, signal) => {
2565
2721
  };
2566
2722
  es.onerror = () => log("command stream error (eventsource will retry)");
2567
2723
  log(`listening for commands (server ${cfg.server}, repo ${repo})`);
2568
- await new Promise((resolve) => {
2569
- if (signal.aborted) return resolve();
2570
- signal.addEventListener("abort", () => resolve(), { once: true });
2724
+ await new Promise((resolve2) => {
2725
+ if (signal.aborted) return resolve2();
2726
+ signal.addEventListener("abort", () => resolve2(), { once: true });
2571
2727
  });
2572
2728
  es.close();
2573
2729
  clearInterval(hb);
@@ -2576,13 +2732,13 @@ var runWorkerDaemon = async (cfg, client, signal) => {
2576
2732
 
2577
2733
  // src/worker/machine-id.ts
2578
2734
  import { randomUUID as randomUUID2 } from "node:crypto";
2579
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
2735
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
2580
2736
  import { homedir as homedir3 } from "node:os";
2581
2737
  import { dirname as dirname3, join as join6 } from "node:path";
2582
2738
  var machineIdPath = (env = process.env) => join6(env.XDG_DATA_HOME ?? join6(env.HOME ?? homedir3(), ".local/share"), "baton", "machine-id");
2583
2739
  var readOrCreateMachineId = (path = machineIdPath()) => {
2584
2740
  if (existsSync6(path)) {
2585
- const s = readFileSync3(path, "utf8").trim();
2741
+ const s = readFileSync4(path, "utf8").trim();
2586
2742
  if (s) return s;
2587
2743
  }
2588
2744
  const id = randomUUID2();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lesscap/baton-cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "description": "baton CLI — register/run a worker, manage projects/requirements/tasks/sessions",
6
6
  "bin": {