@lesscap/baton-cli 0.9.5 → 0.9.7
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/README.md +2 -2
- package/dist/baton.mjs +213 -390
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @lesscap/baton-cli
|
|
2
2
|
|
|
3
3
|
The baton CLI: register/run a **worker** on a machine and manage
|
|
4
|
-
workspaces/projects/
|
|
4
|
+
workspaces/projects/sessions against a baton server.
|
|
5
5
|
|
|
6
6
|
A worker is the thing that actually runs agent sessions: it listens to the
|
|
7
7
|
server's command stream and, per session, runs Claude or Codex in the worker’s working directory.
|
|
@@ -69,7 +69,7 @@ runtime `services/` directory; the run result prints their path.
|
|
|
69
69
|
|
|
70
70
|
## Other commands
|
|
71
71
|
|
|
72
|
-
`baton init | workspace | project |
|
|
72
|
+
`baton init | workspace | project | host | session` — run
|
|
73
73
|
`baton <command> --help` for details. The back-office management commands hit
|
|
74
74
|
gated routes; set `BATON_USER` / `BATON_PASS` to log in transparently (the
|
|
75
75
|
worker commands above don't need this).
|
package/dist/baton.mjs
CHANGED
|
@@ -5376,10 +5376,10 @@ var toJson = (data) => JSON.stringify(data, null, 2);
|
|
|
5376
5376
|
var fmtWorkspace = (w) => `${w.id} ${w.name}`;
|
|
5377
5377
|
var fmtWorkerTemplate = (t) => `${t.id} ${t.name} [${t.available ? "available" : "unavailable"}] ${t.agentKinds.join(", ")}`;
|
|
5378
5378
|
var fmtWorkerCreation = (c) => `${c.id} [${c.status}/${c.step ?? "pending"}] ${c.name} ${c.agentKind}${c.workerId === null ? "" : ` W-${c.workerId}`}${c.error ? ` ${c.error}` : ""}`;
|
|
5379
|
+
var fmtHost = (h) => `${h.id} ${h.name} [${h.online ? "online" : "offline"}] workspaces: ${h.workspaceIds.join(",") || "-"}`;
|
|
5380
|
+
var fmtHostCredential = ({ host: host2, token }) => `${host2.id} ${host2.name}
|
|
5381
|
+
token: ${token}`;
|
|
5379
5382
|
var fmtProject = (p) => `${p.id} ${p.name}`;
|
|
5380
|
-
var fmtRequirement = (r) => `${r.code} [${r.status}] ${r.title}`;
|
|
5381
|
-
var fmtTask = (t) => `${t.code} [${t.status}] ${t.title}`;
|
|
5382
|
-
var fmtComment = (c) => `${c.workerId !== void 0 ? `worker#${c.workerId}` : "you"} ${c.body}`;
|
|
5383
5383
|
var fmtSession = (s) => `${s.id} ${s.name} ${s.attached ? "[active]" : "[inactive]"} ${s.cwd ?? "(pending)"}`;
|
|
5384
5384
|
var fmtWorker = (w) => {
|
|
5385
5385
|
const offline = w.connected === false ? " [offline]" : "";
|
|
@@ -5509,6 +5509,15 @@ var filesClient = (baseUrl) => {
|
|
|
5509
5509
|
};
|
|
5510
5510
|
};
|
|
5511
5511
|
|
|
5512
|
+
// src/client/hosts.ts
|
|
5513
|
+
var hostsClient = (baseUrl) => ({
|
|
5514
|
+
create: (name) => request(`${baseUrl}/hosts`, { method: "POST", body: { name } }),
|
|
5515
|
+
list: () => request(`${baseUrl}/hosts`, { method: "GET" }),
|
|
5516
|
+
rotate: (id) => request(`${baseUrl}/hosts/${id}/token`, { method: "POST", body: {} }),
|
|
5517
|
+
assign: (id, workspaceId) => request(`${baseUrl}/hosts/${id}/workspaces/${workspaceId}`, { method: "PUT" }),
|
|
5518
|
+
unassign: (id, workspaceId) => request(`${baseUrl}/hosts/${id}/workspaces/${workspaceId}`, { method: "DELETE" })
|
|
5519
|
+
});
|
|
5520
|
+
|
|
5512
5521
|
// src/client/loops.ts
|
|
5513
5522
|
var loopsClient = (baseUrl) => {
|
|
5514
5523
|
const u = (p) => `${baseUrl}${p}`;
|
|
@@ -5535,30 +5544,6 @@ var projectClient = (baseUrl) => {
|
|
|
5535
5544
|
};
|
|
5536
5545
|
};
|
|
5537
5546
|
|
|
5538
|
-
// src/client/items.ts
|
|
5539
|
-
var fetchItemByCode = async (baseUrl, projectId, code, expectKind) => {
|
|
5540
|
-
const r = await request(
|
|
5541
|
-
`${baseUrl}/projects/${projectId}/items/${encodeURIComponent(code)}`,
|
|
5542
|
-
{ method: "GET" }
|
|
5543
|
-
);
|
|
5544
|
-
if (r.kind !== expectKind) throw new Error(`expected ${expectKind} but got ${r.kind} for ${code}`);
|
|
5545
|
-
return r.item;
|
|
5546
|
-
};
|
|
5547
|
-
|
|
5548
|
-
// src/client/requirements.ts
|
|
5549
|
-
var requirementClient = (baseUrl) => {
|
|
5550
|
-
const u = (p) => `${baseUrl}${p}`;
|
|
5551
|
-
return {
|
|
5552
|
-
create: (input) => request(u("/requirements"), { method: "POST", body: input }),
|
|
5553
|
-
listByProject: (projectId) => request(u(`/projects/${projectId}/requirements`), { method: "GET" }),
|
|
5554
|
-
get: (id) => request(u(`/requirements/${id}`), { method: "GET" }),
|
|
5555
|
-
getByCode: (projectId, code) => fetchItemByCode(baseUrl, projectId, code, "requirement"),
|
|
5556
|
-
update: (id, patch) => request(u(`/requirements/${id}`), { method: "PATCH", body: patch }),
|
|
5557
|
-
setStatus: (id, status) => request(u(`/requirements/${id}`), { method: "PATCH", body: { status } }),
|
|
5558
|
-
remove: (id) => request(u(`/requirements/${id}`), { method: "DELETE" })
|
|
5559
|
-
};
|
|
5560
|
-
};
|
|
5561
|
-
|
|
5562
5547
|
// src/client/services.ts
|
|
5563
5548
|
var servicesClient = (baseUrl) => {
|
|
5564
5549
|
const u = (path) => `${baseUrl}${path}`;
|
|
@@ -5693,24 +5678,9 @@ var sessionsClient = (baseUrl) => {
|
|
|
5693
5678
|
};
|
|
5694
5679
|
};
|
|
5695
5680
|
|
|
5696
|
-
// src/client/tasks.ts
|
|
5697
|
-
var taskClient = (baseUrl) => {
|
|
5698
|
-
const u = (p) => `${baseUrl}${p}`;
|
|
5699
|
-
return {
|
|
5700
|
-
create: (input) => request(u("/tasks"), { method: "POST", body: input }),
|
|
5701
|
-
listByRequirement: (requirementId) => request(u(`/requirements/${requirementId}/tasks`), { method: "GET" }),
|
|
5702
|
-
get: (id) => request(u(`/tasks/${id}`), { method: "GET" }),
|
|
5703
|
-
getByCode: (projectId, code) => fetchItemByCode(baseUrl, projectId, code, "task"),
|
|
5704
|
-
update: (id, patch) => request(u(`/tasks/${id}`), { method: "PATCH", body: patch }),
|
|
5705
|
-
setStatus: (id, status) => request(u(`/tasks/${id}`), { method: "PATCH", body: { status } }),
|
|
5706
|
-
remove: (id) => request(u(`/tasks/${id}`), { method: "DELETE" }),
|
|
5707
|
-
listComments: (id) => request(u(`/tasks/${id}/comments`), { method: "GET" }),
|
|
5708
|
-
addComment: (id, body, workerId) => request(u(`/tasks/${id}/comments`), { method: "POST", body: { body, workerId } })
|
|
5709
|
-
};
|
|
5710
|
-
};
|
|
5711
|
-
|
|
5712
5681
|
// src/client/worker-creations.ts
|
|
5713
5682
|
var workerCreationsClient = (baseUrl) => ({
|
|
5683
|
+
hosts: (projectId) => request(`${baseUrl}/projects/${projectId}/hosts`, { method: "GET" }),
|
|
5714
5684
|
templates: (projectId) => request(`${baseUrl}/projects/${projectId}/worker-templates`, { method: "GET" }),
|
|
5715
5685
|
create: (projectId, input) => request(`${baseUrl}/projects/${projectId}/worker-creations`, { method: "POST", body: input }),
|
|
5716
5686
|
listByProject: (projectId) => request(`${baseUrl}/projects/${projectId}/worker-creations`, { method: "GET" }),
|
|
@@ -5758,11 +5728,10 @@ var createClient = (baseUrl, opts) => {
|
|
|
5758
5728
|
};
|
|
5759
5729
|
var clientFromBase = (baseUrl) => ({
|
|
5760
5730
|
workerCreations: workerCreationsClient(baseUrl),
|
|
5731
|
+
hosts: hostsClient(baseUrl),
|
|
5761
5732
|
artifacts: artifactsClient(baseUrl),
|
|
5762
5733
|
workspaces: workspaceClient(baseUrl),
|
|
5763
5734
|
projects: projectClient(baseUrl),
|
|
5764
|
-
requirements: requirementClient(baseUrl),
|
|
5765
|
-
tasks: taskClient(baseUrl),
|
|
5766
5735
|
sessions: sessionsClient(baseUrl),
|
|
5767
5736
|
services: servicesClient(baseUrl),
|
|
5768
5737
|
files: filesClient(baseUrl),
|
|
@@ -7114,6 +7083,87 @@ var channel = defineCommand({
|
|
|
7114
7083
|
}
|
|
7115
7084
|
});
|
|
7116
7085
|
|
|
7086
|
+
// src/commands/host.ts
|
|
7087
|
+
var findHost = (hosts, handle) => {
|
|
7088
|
+
const host2 = hosts.find((item) => item.name === handle || String(item.id) === handle);
|
|
7089
|
+
if (!host2) throw new Error(`host not found: ${handle}`);
|
|
7090
|
+
return host2;
|
|
7091
|
+
};
|
|
7092
|
+
var adminHost = async (c, handle) => findHost(await c.hosts.list(), handle);
|
|
7093
|
+
var positiveId = (raw) => {
|
|
7094
|
+
const id = Number(raw);
|
|
7095
|
+
if (!Number.isSafeInteger(id) || id <= 0) throw new Error("workspace must be a positive id");
|
|
7096
|
+
return id;
|
|
7097
|
+
};
|
|
7098
|
+
var hostArg = {
|
|
7099
|
+
host: { type: "positional", required: true, description: "host name or id" }
|
|
7100
|
+
};
|
|
7101
|
+
var workspaceArg = {
|
|
7102
|
+
workspace: { type: "string", required: true, description: "workspace id" }
|
|
7103
|
+
};
|
|
7104
|
+
var host = defineCommand({
|
|
7105
|
+
meta: { name: "host", description: "manage machines and which workspaces can use them (admin)" },
|
|
7106
|
+
subCommands: {
|
|
7107
|
+
add: defineCommand({
|
|
7108
|
+
meta: { name: "add", description: "add a host; prints its Provisioner token once" },
|
|
7109
|
+
args: {
|
|
7110
|
+
name: { type: "positional", required: true, description: "host name" },
|
|
7111
|
+
workspace: { type: "string", description: "also assign it to this workspace id" },
|
|
7112
|
+
...common
|
|
7113
|
+
},
|
|
7114
|
+
run: async ({ args }) => {
|
|
7115
|
+
const c = clientFor(args);
|
|
7116
|
+
const workspaceId = args.workspace === void 0 ? null : positiveId(args.workspace);
|
|
7117
|
+
const credential = await c.hosts.create(args.name);
|
|
7118
|
+
console.log(renderOne(credential, fmtHostCredential, Boolean(args.json)));
|
|
7119
|
+
if (workspaceId !== null) await c.hosts.assign(credential.host.id, workspaceId);
|
|
7120
|
+
}
|
|
7121
|
+
}),
|
|
7122
|
+
ls: defineCommand({
|
|
7123
|
+
meta: {
|
|
7124
|
+
name: "ls",
|
|
7125
|
+
description: "list hosts, whether they are online, and their workspaces"
|
|
7126
|
+
},
|
|
7127
|
+
args: { ...common },
|
|
7128
|
+
run: async ({ args }) => {
|
|
7129
|
+
console.log(renderList(await clientFor(args).hosts.list(), fmtHost, Boolean(args.json)));
|
|
7130
|
+
}
|
|
7131
|
+
}),
|
|
7132
|
+
assign: defineCommand({
|
|
7133
|
+
meta: { name: "assign", description: "let a workspace create Workers on this host" },
|
|
7134
|
+
args: { ...hostArg, ...workspaceArg, ...common },
|
|
7135
|
+
run: async ({ args }) => {
|
|
7136
|
+
const c = clientFor(args);
|
|
7137
|
+
const { id, name } = await adminHost(c, args.host);
|
|
7138
|
+
await c.hosts.assign(id, positiveId(args.workspace));
|
|
7139
|
+
console.log(`assigned ${name} to workspace ${args.workspace}`);
|
|
7140
|
+
}
|
|
7141
|
+
}),
|
|
7142
|
+
unassign: defineCommand({
|
|
7143
|
+
meta: {
|
|
7144
|
+
name: "unassign",
|
|
7145
|
+
description: "stop new Workers on this host for a workspace; existing ones keep running"
|
|
7146
|
+
},
|
|
7147
|
+
args: { ...hostArg, ...workspaceArg, ...common },
|
|
7148
|
+
run: async ({ args }) => {
|
|
7149
|
+
const c = clientFor(args);
|
|
7150
|
+
const { id, name } = await adminHost(c, args.host);
|
|
7151
|
+
await c.hosts.unassign(id, positiveId(args.workspace));
|
|
7152
|
+
console.log(`unassigned ${name} from workspace ${args.workspace}`);
|
|
7153
|
+
}
|
|
7154
|
+
}),
|
|
7155
|
+
rotate: defineCommand({
|
|
7156
|
+
meta: { name: "rotate", description: "replace a host token; the old one stops working" },
|
|
7157
|
+
args: { ...hostArg, ...common },
|
|
7158
|
+
run: async ({ args }) => {
|
|
7159
|
+
const c = clientFor(args);
|
|
7160
|
+
const { id } = await adminHost(c, args.host);
|
|
7161
|
+
console.log(renderOne(await c.hosts.rotate(id), fmtHostCredential, Boolean(args.json)));
|
|
7162
|
+
}
|
|
7163
|
+
})
|
|
7164
|
+
}
|
|
7165
|
+
});
|
|
7166
|
+
|
|
7117
7167
|
// src/commands/init.ts
|
|
7118
7168
|
import { existsSync as existsSync2 } from "node:fs";
|
|
7119
7169
|
import * as readline from "node:readline/promises";
|
|
@@ -7467,9 +7517,9 @@ var environment = (value) => {
|
|
|
7467
7517
|
var templates = (value) => {
|
|
7468
7518
|
if (!object(value)) throw new Error("templates must be an object");
|
|
7469
7519
|
return Object.fromEntries(
|
|
7470
|
-
WORKER_TEMPLATES.map((template) => {
|
|
7520
|
+
WORKER_TEMPLATES.filter((template) => value[template.id] !== void 0).map((template) => {
|
|
7471
7521
|
const raw = value[template.id];
|
|
7472
|
-
if (!object(raw)) throw new Error(`template ${template.id} must be
|
|
7522
|
+
if (!object(raw)) throw new Error(`template ${template.id} must be an object`);
|
|
7473
7523
|
const workerEnv2 = environment(raw.workerEnv);
|
|
7474
7524
|
if (template.id === "mini-codex") {
|
|
7475
7525
|
if (raw.pi !== void 0) throw new Error("mini-codex does not support pi");
|
|
@@ -7563,7 +7613,7 @@ var createProvisionerClient = (config) => {
|
|
|
7563
7613
|
import { execFile as execFile3 } from "node:child_process";
|
|
7564
7614
|
import { lstat, mkdir as mkdir3, realpath, writeFile as writeFile2 } from "node:fs/promises";
|
|
7565
7615
|
import { hostname } from "node:os";
|
|
7566
|
-
import { join as join5 } from "node:path";
|
|
7616
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
7567
7617
|
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
7568
7618
|
import { promisify as promisify3 } from "node:util";
|
|
7569
7619
|
|
|
@@ -7634,11 +7684,17 @@ var startAgent = async (config, agent, signal) => {
|
|
|
7634
7684
|
throw new Error(`launchd start failed; inspect ${plist} and ${agent.log}`);
|
|
7635
7685
|
}
|
|
7636
7686
|
};
|
|
7637
|
-
var launchWorkerAgent = async (config, creation, repoPath, workerEnv2, signal) => startAgent(
|
|
7687
|
+
var launchWorkerAgent = async (config, creation, repoPath, configPath, workerEnv2, signal) => startAgent(
|
|
7638
7688
|
config,
|
|
7639
7689
|
{
|
|
7640
7690
|
label: `dev.fmap.baton-worker-creation-${creation.id}`,
|
|
7641
|
-
args: [
|
|
7691
|
+
args: [
|
|
7692
|
+
config.nodePath ?? process.execPath,
|
|
7693
|
+
config.cliPath,
|
|
7694
|
+
"worker",
|
|
7695
|
+
"run",
|
|
7696
|
+
...configPath === null ? [] : ["--config", configPath]
|
|
7697
|
+
],
|
|
7642
7698
|
cwd: repoPath,
|
|
7643
7699
|
env: {
|
|
7644
7700
|
PATH: workerEnv2.PATH ?? process.env.PATH ?? "/usr/bin:/bin",
|
|
@@ -7668,12 +7724,17 @@ var installProvisionerAgent = async (config, configPath) => startAgent(config, {
|
|
|
7668
7724
|
// src/provisioner/worker-template.ts
|
|
7669
7725
|
import { mkdir as mkdir2, writeFile } from "node:fs/promises";
|
|
7670
7726
|
import { join as join4 } from "node:path";
|
|
7671
|
-
var
|
|
7727
|
+
var requireWorkerTemplate = (config, creation) => {
|
|
7672
7728
|
if (!workerTemplateAgentKinds(creation.templateId).includes(creation.agentKind))
|
|
7673
7729
|
throw new Error("agentKind is not supported by this template");
|
|
7674
|
-
if (creation.templateId === "mini-local") return
|
|
7730
|
+
if (creation.templateId === "mini-local") return null;
|
|
7675
7731
|
const profile = config.templates[creation.templateId];
|
|
7676
|
-
if (!profile) throw new Error(`template ${creation.templateId} is not configured`);
|
|
7732
|
+
if (!profile) throw new Error(`template ${creation.templateId} is not configured on this host`);
|
|
7733
|
+
return profile;
|
|
7734
|
+
};
|
|
7735
|
+
var workerTemplateEnvironment = async (config, creation, state) => {
|
|
7736
|
+
const profile = requireWorkerTemplate(config, creation);
|
|
7737
|
+
if (!profile) return config.workerEnv;
|
|
7677
7738
|
if (creation.agentKind !== "pi") return profile.workerEnv;
|
|
7678
7739
|
if (!profile.pi) throw new Error("Pi provider and model are not configured");
|
|
7679
7740
|
const agentDir = join4(state, "pi");
|
|
@@ -7699,13 +7760,20 @@ var directory = async (path) => {
|
|
|
7699
7760
|
const info = await lstat(path);
|
|
7700
7761
|
if (!info.isDirectory() || info.isSymbolicLink()) throw new Error(`unsafe directory: ${path}`);
|
|
7701
7762
|
};
|
|
7702
|
-
var
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7763
|
+
var gitIn = async (config, repoPath, args, signal, failure = "Git repository initialization failed") => {
|
|
7764
|
+
try {
|
|
7765
|
+
const { stdout } = await promisify3(execFile3)("git", ["-C", repoPath, ...args], {
|
|
7766
|
+
env: commandEnvironment(config),
|
|
7767
|
+
signal,
|
|
7768
|
+
timeout: 1e4
|
|
7769
|
+
});
|
|
7770
|
+
return stdout;
|
|
7771
|
+
} catch (error) {
|
|
7772
|
+
signal.throwIfAborted();
|
|
7773
|
+
throw new Error(failure, { cause: error });
|
|
7774
|
+
}
|
|
7775
|
+
};
|
|
7776
|
+
var initRepository = async (config, creation, repoPath, progress, signal) => {
|
|
7709
7777
|
await progress("directory");
|
|
7710
7778
|
signal.throwIfAborted();
|
|
7711
7779
|
await mkdir3(config.projectsRoot, { recursive: true, mode: 448 });
|
|
@@ -7715,33 +7783,52 @@ var provisionWorker = async (config, creation, client, signal) => {
|
|
|
7715
7783
|
mode: 448
|
|
7716
7784
|
});
|
|
7717
7785
|
await progress("git");
|
|
7718
|
-
|
|
7719
|
-
try {
|
|
7720
|
-
await promisify3(execFile3)("git", ["-C", repoPath, ...args], {
|
|
7721
|
-
env: commandEnvironment(config),
|
|
7722
|
-
signal,
|
|
7723
|
-
timeout: 1e4
|
|
7724
|
-
});
|
|
7725
|
-
} catch (error) {
|
|
7726
|
-
signal.throwIfAborted();
|
|
7727
|
-
throw new Error("Git repository initialization failed", { cause: error });
|
|
7728
|
-
}
|
|
7729
|
-
};
|
|
7730
|
-
await git2(["init", "-b", "main"]);
|
|
7786
|
+
await gitIn(config, repoPath, ["init", "-b", "main"], signal);
|
|
7731
7787
|
await writeFile2(join5(repoPath, ".git/info/exclude"), "\n.baton.json\n", { flag: "a" });
|
|
7732
|
-
await
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7788
|
+
await gitIn(
|
|
7789
|
+
config,
|
|
7790
|
+
repoPath,
|
|
7791
|
+
[
|
|
7792
|
+
"-c",
|
|
7793
|
+
"user.name=Baton",
|
|
7794
|
+
"-c",
|
|
7795
|
+
"user.email=baton@localhost",
|
|
7796
|
+
"commit",
|
|
7797
|
+
"--allow-empty",
|
|
7798
|
+
"-m",
|
|
7799
|
+
"chore: initialize repository"
|
|
7800
|
+
],
|
|
7801
|
+
signal
|
|
7802
|
+
);
|
|
7803
|
+
};
|
|
7804
|
+
var adoptRepository = async (config, creation, repoPath, progress, signal) => {
|
|
7805
|
+
await progress("directory");
|
|
7806
|
+
signal.throwIfAborted();
|
|
7807
|
+
const real = await realpath(repoPath);
|
|
7808
|
+
const project2 = join5(await realpath(config.projectsRoot), `project-${creation.projectId}`);
|
|
7809
|
+
if (dirname2(real) !== project2 || !(await lstat(real)).isDirectory())
|
|
7810
|
+
throw new Error(`unsafe directory: ${repoPath}`);
|
|
7811
|
+
await progress("git");
|
|
7812
|
+
const top = await gitIn(
|
|
7813
|
+
config,
|
|
7814
|
+
real,
|
|
7815
|
+
["rev-parse", "--show-toplevel"],
|
|
7816
|
+
signal,
|
|
7817
|
+
`not a Git repository: ${repoPath}`
|
|
7818
|
+
);
|
|
7819
|
+
if (await realpath(top.trim()) !== real)
|
|
7820
|
+
throw new Error(`not the root of a Git work tree: ${repoPath}`);
|
|
7821
|
+
};
|
|
7822
|
+
var provisionWorker = async (config, creation, client, signal) => {
|
|
7823
|
+
requireWorkerTemplate(config, creation);
|
|
7824
|
+
const shared = creation.repoPath !== null;
|
|
7825
|
+
const repoPath = creation.repoPath ?? join5(config.projectsRoot, `project-${creation.projectId}`, `creation-${creation.id}`);
|
|
7826
|
+
const progress = (step) => client.report(creation.id, { status: "running", step, repoPath }, signal);
|
|
7827
|
+
await (shared ? adoptRepository : initRepository)(config, creation, repoPath, progress, signal);
|
|
7742
7828
|
await progress("register");
|
|
7743
7829
|
const result = await client.register(creation.id, hostname(), signal);
|
|
7744
7830
|
const state = workerStatePath(config, creation);
|
|
7831
|
+
const root = await realpath(config.projectsRoot);
|
|
7745
7832
|
await directory(join5(root, ".worker-state"));
|
|
7746
7833
|
await directory(join5(root, ".worker-state", `project-${creation.projectId}`));
|
|
7747
7834
|
await mkdir3(state, { mode: 448 });
|
|
@@ -7760,15 +7847,13 @@ var provisionWorker = async (config, creation, client, signal) => {
|
|
|
7760
7847
|
machineId: result.worker.machineId,
|
|
7761
7848
|
apiToken: result.apiToken
|
|
7762
7849
|
});
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
mode: 384
|
|
7767
|
-
});
|
|
7850
|
+
const configPath = shared ? join5(state, "worker.json") : join5(repoPath, ".baton.json");
|
|
7851
|
+
await writeFile2(configPath, `${JSON.stringify(cfg, null, 2)}
|
|
7852
|
+
`, { flag: "wx", mode: 384 });
|
|
7768
7853
|
await progress("start");
|
|
7769
7854
|
signal.throwIfAborted();
|
|
7770
7855
|
const workerEnv2 = await workerTemplateEnvironment(config, creation, state);
|
|
7771
|
-
await launchWorkerAgent(config, creation, repoPath, workerEnv2, signal);
|
|
7856
|
+
await launchWorkerAgent(config, creation, repoPath, shared ? configPath : null, workerEnv2, signal);
|
|
7772
7857
|
await progress("connect");
|
|
7773
7858
|
const deadline = Date.now() + 6e4;
|
|
7774
7859
|
while (Date.now() < deadline) {
|
|
@@ -8119,118 +8204,6 @@ var relay = defineCommand({
|
|
|
8119
8204
|
subCommands: { host: hostCommand, listen: listenCommand2, send: sendCommand2 }
|
|
8120
8205
|
});
|
|
8121
8206
|
|
|
8122
|
-
// src/commands/requirement.ts
|
|
8123
|
-
var createRequirement = (c, input, json) => c.requirements.create(input).then((r) => renderOne(r, fmtRequirement, json));
|
|
8124
|
-
var updateRequirement = (c, id, patch, json) => c.requirements.update(id, patch).then((r) => renderOne(r, fmtRequirement, json));
|
|
8125
|
-
var listRequirements = (c, projectId, json) => c.requirements.listByProject(projectId).then((rs) => renderList(rs, fmtRequirement, json));
|
|
8126
|
-
var getRequirement = (c, id, json) => c.requirements.get(id).then((r) => renderOne(r, fmtRequirement, json));
|
|
8127
|
-
var setRequirementStatus = (c, id, status, json) => c.requirements.setStatus(id, status).then((r) => renderOne(r, fmtRequirement, json));
|
|
8128
|
-
var removeRequirement = (c, id, label, json) => c.requirements.remove(id).then(() => removed("requirement", label, json));
|
|
8129
|
-
var resolveByCode = async (c, projectId, code) => (await c.requirements.getByCode(projectId, code)).id;
|
|
8130
|
-
var requirement = defineCommand({
|
|
8131
|
-
meta: { name: "requirement", description: "manage requirements" },
|
|
8132
|
-
subCommands: {
|
|
8133
|
-
create: defineCommand({
|
|
8134
|
-
meta: { name: "create", description: "create a requirement" },
|
|
8135
|
-
args: {
|
|
8136
|
-
title: { type: "positional", required: true },
|
|
8137
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
8138
|
-
desc: { type: "string", description: "description" },
|
|
8139
|
-
body: { type: "string", description: "requirement body (markdown)" },
|
|
8140
|
-
...common
|
|
8141
|
-
},
|
|
8142
|
-
run: async ({ args }) => {
|
|
8143
|
-
console.log(
|
|
8144
|
-
await createRequirement(
|
|
8145
|
-
clientFor(args),
|
|
8146
|
-
{
|
|
8147
|
-
projectId: resolveProjectId(args),
|
|
8148
|
-
title: args.title,
|
|
8149
|
-
description: args.desc,
|
|
8150
|
-
body: args.body
|
|
8151
|
-
},
|
|
8152
|
-
Boolean(args.json)
|
|
8153
|
-
)
|
|
8154
|
-
);
|
|
8155
|
-
}
|
|
8156
|
-
}),
|
|
8157
|
-
update: defineCommand({
|
|
8158
|
-
meta: { name: "update", description: "update a requirement title / body" },
|
|
8159
|
-
args: {
|
|
8160
|
-
code: { type: "positional", required: true, description: "requirement code (R-N)" },
|
|
8161
|
-
title: { type: "string", description: "new title" },
|
|
8162
|
-
body: { type: "string", description: "new body (markdown)" },
|
|
8163
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
8164
|
-
...common
|
|
8165
|
-
},
|
|
8166
|
-
run: async ({ args }) => {
|
|
8167
|
-
const patch = {
|
|
8168
|
-
...args.title !== void 0 ? { title: args.title } : {},
|
|
8169
|
-
...args.body !== void 0 ? { body: args.body } : {}
|
|
8170
|
-
};
|
|
8171
|
-
if (Object.keys(patch).length === 0) throw new Error("pass --title and/or --body");
|
|
8172
|
-
const c = clientFor(args);
|
|
8173
|
-
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
8174
|
-
console.log(await updateRequirement(c, id, patch, Boolean(args.json)));
|
|
8175
|
-
}
|
|
8176
|
-
}),
|
|
8177
|
-
ls: defineCommand({
|
|
8178
|
-
meta: { name: "ls", description: "list requirements in a project" },
|
|
8179
|
-
args: {
|
|
8180
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
8181
|
-
...common
|
|
8182
|
-
},
|
|
8183
|
-
run: async ({ args }) => {
|
|
8184
|
-
console.log(
|
|
8185
|
-
await listRequirements(clientFor(args), resolveProjectId(args), Boolean(args.json))
|
|
8186
|
-
);
|
|
8187
|
-
}
|
|
8188
|
-
}),
|
|
8189
|
-
get: defineCommand({
|
|
8190
|
-
meta: { name: "get", description: "get a requirement by code (R-N)" },
|
|
8191
|
-
args: {
|
|
8192
|
-
code: { type: "positional", required: true, description: "requirement code, e.g. R-1" },
|
|
8193
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
8194
|
-
...common
|
|
8195
|
-
},
|
|
8196
|
-
run: async ({ args }) => {
|
|
8197
|
-
const c = clientFor(args);
|
|
8198
|
-
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
8199
|
-
console.log(await getRequirement(c, id, Boolean(args.json)));
|
|
8200
|
-
}
|
|
8201
|
-
}),
|
|
8202
|
-
"set-status": defineCommand({
|
|
8203
|
-
meta: { name: "set-status", description: "set requirement status (active|done|cancelled)" },
|
|
8204
|
-
args: {
|
|
8205
|
-
code: { type: "positional", required: true, description: "requirement code (R-N)" },
|
|
8206
|
-
status: { type: "positional", required: true },
|
|
8207
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
8208
|
-
...common
|
|
8209
|
-
},
|
|
8210
|
-
run: async ({ args }) => {
|
|
8211
|
-
const c = clientFor(args);
|
|
8212
|
-
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
8213
|
-
console.log(
|
|
8214
|
-
await setRequirementStatus(c, id, args.status, Boolean(args.json))
|
|
8215
|
-
);
|
|
8216
|
-
}
|
|
8217
|
-
}),
|
|
8218
|
-
rm: defineCommand({
|
|
8219
|
-
meta: { name: "rm", description: "delete a requirement by code" },
|
|
8220
|
-
args: {
|
|
8221
|
-
code: { type: "positional", required: true },
|
|
8222
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
8223
|
-
...common
|
|
8224
|
-
},
|
|
8225
|
-
run: async ({ args }) => {
|
|
8226
|
-
const c = clientFor(args);
|
|
8227
|
-
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
8228
|
-
console.log(await removeRequirement(c, id, args.code, Boolean(args.json)));
|
|
8229
|
-
}
|
|
8230
|
-
})
|
|
8231
|
-
}
|
|
8232
|
-
});
|
|
8233
|
-
|
|
8234
8207
|
// src/commands/service.ts
|
|
8235
8208
|
import { resolve as resolve2 } from "node:path";
|
|
8236
8209
|
|
|
@@ -9848,178 +9821,19 @@ var session = defineCommand({
|
|
|
9848
9821
|
}
|
|
9849
9822
|
});
|
|
9850
9823
|
|
|
9851
|
-
// src/commands/task.ts
|
|
9852
|
-
var createTask = (c, input, json) => c.tasks.create(input).then((t) => renderOne(t, fmtTask, json));
|
|
9853
|
-
var updateTask = (c, id, patch, json) => c.tasks.update(id, patch).then((t) => renderOne(t, fmtTask, json));
|
|
9854
|
-
var listTasks = (c, requirementId, json) => c.tasks.listByRequirement(requirementId).then((ts) => renderList(ts, fmtTask, json));
|
|
9855
|
-
var getTask = (c, id, json) => c.tasks.get(id).then((t) => renderOne(t, fmtTask, json));
|
|
9856
|
-
var setTaskStatus = (c, id, status, json) => c.tasks.setStatus(id, status).then((t) => renderOne(t, fmtTask, json));
|
|
9857
|
-
var removeTask = (c, id, label, json) => c.tasks.remove(id).then(() => removed("task", label, json));
|
|
9858
|
-
var addTaskComment = (c, taskId, body, workerId, json) => c.tasks.addComment(taskId, body, workerId).then((x) => renderOne(x, fmtComment, json));
|
|
9859
|
-
var listTaskComments = (c, taskId, json) => c.tasks.listComments(taskId).then((xs) => renderList(xs, fmtComment, json));
|
|
9860
|
-
var resolveReqByCode = async (c, projectId, code) => (await c.requirements.getByCode(projectId, code)).id;
|
|
9861
|
-
var resolveTaskByCode = async (c, projectId, code) => (await c.tasks.getByCode(projectId, code)).id;
|
|
9862
|
-
var task = defineCommand({
|
|
9863
|
-
meta: { name: "task", description: "manage tasks" },
|
|
9864
|
-
subCommands: {
|
|
9865
|
-
create: defineCommand({
|
|
9866
|
-
meta: { name: "create", description: "create a task" },
|
|
9867
|
-
args: {
|
|
9868
|
-
title: { type: "positional", required: true },
|
|
9869
|
-
requirement: { type: "string", required: true, description: "requirement code (R-N)" },
|
|
9870
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9871
|
-
body: { type: "string", description: "task body (markdown)" },
|
|
9872
|
-
deps: { type: "string", description: "comma-separated dependency task codes (T-N,T-N)" },
|
|
9873
|
-
...common
|
|
9874
|
-
},
|
|
9875
|
-
run: async ({ args }) => {
|
|
9876
|
-
const c = clientFor(args);
|
|
9877
|
-
const projectId = resolveProjectId(args);
|
|
9878
|
-
const requirementId = await resolveReqByCode(c, projectId, args.requirement);
|
|
9879
|
-
const depCodes = splitCsv(args.deps) ?? [];
|
|
9880
|
-
const dependsOn = await Promise.all(
|
|
9881
|
-
depCodes.map((code) => resolveTaskByCode(c, projectId, code))
|
|
9882
|
-
);
|
|
9883
|
-
console.log(
|
|
9884
|
-
await createTask(
|
|
9885
|
-
c,
|
|
9886
|
-
{
|
|
9887
|
-
requirementId,
|
|
9888
|
-
title: args.title,
|
|
9889
|
-
body: args.body,
|
|
9890
|
-
dependsOn: dependsOn.length ? dependsOn : void 0
|
|
9891
|
-
},
|
|
9892
|
-
Boolean(args.json)
|
|
9893
|
-
)
|
|
9894
|
-
);
|
|
9895
|
-
}
|
|
9896
|
-
}),
|
|
9897
|
-
update: defineCommand({
|
|
9898
|
-
meta: { name: "update", description: "update a task title / body" },
|
|
9899
|
-
args: {
|
|
9900
|
-
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
9901
|
-
title: { type: "string", description: "new title" },
|
|
9902
|
-
body: { type: "string", description: "new body (markdown)" },
|
|
9903
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9904
|
-
...common
|
|
9905
|
-
},
|
|
9906
|
-
run: async ({ args }) => {
|
|
9907
|
-
const patch = {
|
|
9908
|
-
...args.title !== void 0 ? { title: args.title } : {},
|
|
9909
|
-
...args.body !== void 0 ? { body: args.body } : {}
|
|
9910
|
-
};
|
|
9911
|
-
if (Object.keys(patch).length === 0) throw new Error("pass --title and/or --body");
|
|
9912
|
-
const c = clientFor(args);
|
|
9913
|
-
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
9914
|
-
console.log(await updateTask(c, id, patch, Boolean(args.json)));
|
|
9915
|
-
}
|
|
9916
|
-
}),
|
|
9917
|
-
ls: defineCommand({
|
|
9918
|
-
meta: { name: "ls", description: "list tasks in a requirement" },
|
|
9919
|
-
args: {
|
|
9920
|
-
requirement: { type: "string", required: true, description: "requirement code (R-N)" },
|
|
9921
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9922
|
-
...common
|
|
9923
|
-
},
|
|
9924
|
-
run: async ({ args }) => {
|
|
9925
|
-
const c = clientFor(args);
|
|
9926
|
-
const reqId = await resolveReqByCode(c, resolveProjectId(args), args.requirement);
|
|
9927
|
-
console.log(await listTasks(c, reqId, Boolean(args.json)));
|
|
9928
|
-
}
|
|
9929
|
-
}),
|
|
9930
|
-
get: defineCommand({
|
|
9931
|
-
meta: { name: "get", description: "get a task by code (T-N)" },
|
|
9932
|
-
args: {
|
|
9933
|
-
code: { type: "positional", required: true },
|
|
9934
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9935
|
-
...common
|
|
9936
|
-
},
|
|
9937
|
-
run: async ({ args }) => {
|
|
9938
|
-
const c = clientFor(args);
|
|
9939
|
-
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
9940
|
-
console.log(await getTask(c, id, Boolean(args.json)));
|
|
9941
|
-
}
|
|
9942
|
-
}),
|
|
9943
|
-
"set-status": defineCommand({
|
|
9944
|
-
meta: {
|
|
9945
|
-
name: "set-status",
|
|
9946
|
-
description: "set task status (todo|in_progress|blocked|done|failed|cancelled)"
|
|
9947
|
-
},
|
|
9948
|
-
args: {
|
|
9949
|
-
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
9950
|
-
status: { type: "positional", required: true },
|
|
9951
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9952
|
-
...common
|
|
9953
|
-
},
|
|
9954
|
-
run: async ({ args }) => {
|
|
9955
|
-
const c = clientFor(args);
|
|
9956
|
-
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
9957
|
-
console.log(await setTaskStatus(c, id, args.status, Boolean(args.json)));
|
|
9958
|
-
}
|
|
9959
|
-
}),
|
|
9960
|
-
rm: defineCommand({
|
|
9961
|
-
meta: { name: "rm", description: "delete a task by code" },
|
|
9962
|
-
args: {
|
|
9963
|
-
code: { type: "positional", required: true },
|
|
9964
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9965
|
-
...common
|
|
9966
|
-
},
|
|
9967
|
-
run: async ({ args }) => {
|
|
9968
|
-
const c = clientFor(args);
|
|
9969
|
-
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
9970
|
-
console.log(await removeTask(c, id, args.code, Boolean(args.json)));
|
|
9971
|
-
}
|
|
9972
|
-
}),
|
|
9973
|
-
comment: defineCommand({
|
|
9974
|
-
meta: { name: "comment", description: "append-only task comments" },
|
|
9975
|
-
subCommands: {
|
|
9976
|
-
add: defineCommand({
|
|
9977
|
-
meta: { name: "add", description: "add a comment to a task" },
|
|
9978
|
-
args: {
|
|
9979
|
-
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
9980
|
-
body: { type: "positional", required: true, description: "comment text (markdown)" },
|
|
9981
|
-
worker: { type: "string", description: "attribute to a worker id (omit = human)" },
|
|
9982
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9983
|
-
...common
|
|
9984
|
-
},
|
|
9985
|
-
run: async ({ args }) => {
|
|
9986
|
-
const c = clientFor(args);
|
|
9987
|
-
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
9988
|
-
const workerId = args.worker ? Number(args.worker) : void 0;
|
|
9989
|
-
console.log(await addTaskComment(c, id, args.body, workerId, Boolean(args.json)));
|
|
9990
|
-
}
|
|
9991
|
-
}),
|
|
9992
|
-
ls: defineCommand({
|
|
9993
|
-
meta: { name: "ls", description: "list a task\u2019s comments in order" },
|
|
9994
|
-
args: {
|
|
9995
|
-
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
9996
|
-
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
9997
|
-
...common
|
|
9998
|
-
},
|
|
9999
|
-
run: async ({ args }) => {
|
|
10000
|
-
const c = clientFor(args);
|
|
10001
|
-
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
10002
|
-
console.log(await listTaskComments(c, id, Boolean(args.json)));
|
|
10003
|
-
}
|
|
10004
|
-
})
|
|
10005
|
-
}
|
|
10006
|
-
})
|
|
10007
|
-
}
|
|
10008
|
-
});
|
|
10009
|
-
|
|
10010
9824
|
// src/commands/worker/index.ts
|
|
10011
9825
|
import { hostname as osHostname } from "node:os";
|
|
10012
9826
|
|
|
10013
9827
|
// src/worker/bundled-skills.ts
|
|
10014
9828
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
10015
9829
|
import { cpSync, existsSync as existsSync5 } from "node:fs";
|
|
10016
|
-
import { dirname as
|
|
9830
|
+
import { dirname as dirname4, join as join14 } from "node:path";
|
|
10017
9831
|
import { fileURLToPath } from "node:url";
|
|
10018
9832
|
|
|
10019
9833
|
// src/worker/git-exclude.ts
|
|
10020
9834
|
import { spawnSync } from "node:child_process";
|
|
10021
9835
|
import { appendFileSync, existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
10022
|
-
import { dirname as
|
|
9836
|
+
import { dirname as dirname3, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
|
|
10023
9837
|
var ensureExcluded = (cwd, pattern) => {
|
|
10024
9838
|
const result = spawnSync("git", ["-C", cwd, "rev-parse", "--git-path", "info/exclude"], {
|
|
10025
9839
|
encoding: "utf8",
|
|
@@ -10034,7 +9848,7 @@ var ensureExcluded = (cwd, pattern) => {
|
|
|
10034
9848
|
const path = isAbsolute3(location) ? location : resolve3(cwd, location);
|
|
10035
9849
|
const current = existsSync4(path) ? readFileSync5(path, "utf8") : "";
|
|
10036
9850
|
if (current.split("\n").includes(pattern)) return;
|
|
10037
|
-
mkdirSync3(
|
|
9851
|
+
mkdirSync3(dirname3(path), { recursive: true });
|
|
10038
9852
|
appendFileSync(path, `${current && !current.endsWith("\n") ? "\n" : ""}${pattern}
|
|
10039
9853
|
`);
|
|
10040
9854
|
};
|
|
@@ -10043,7 +9857,7 @@ var ensureExcluded = (cwd, pattern) => {
|
|
|
10043
9857
|
var SKILL_NAME = "baton-publish-artifact";
|
|
10044
9858
|
var TARGETS = [`.claude/skills/${SKILL_NAME}`, `.agents/skills/${SKILL_NAME}`];
|
|
10045
9859
|
var bundledSkillPath = () => {
|
|
10046
|
-
const here =
|
|
9860
|
+
const here = dirname4(fileURLToPath(import.meta.url));
|
|
10047
9861
|
const candidates = [
|
|
10048
9862
|
join14(here, "..", "skills", SKILL_NAME),
|
|
10049
9863
|
join14(here, "..", "..", "skills", SKILL_NAME)
|
|
@@ -10651,7 +10465,7 @@ import { join as join17 } from "node:path";
|
|
|
10651
10465
|
// src/worker/service-process.ts
|
|
10652
10466
|
import { spawn as spawn3 } from "node:child_process";
|
|
10653
10467
|
import { closeSync, existsSync as existsSync6, openSync } from "node:fs";
|
|
10654
|
-
import { dirname as
|
|
10468
|
+
import { dirname as dirname5, join as join16 } from "node:path";
|
|
10655
10469
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
10656
10470
|
var START_TIMEOUT_MS = 1e4;
|
|
10657
10471
|
var isWrapperMessage = (message) => {
|
|
@@ -10661,7 +10475,7 @@ var isWrapperMessage = (message) => {
|
|
|
10661
10475
|
return value.type === "error" && typeof value.error === "string";
|
|
10662
10476
|
};
|
|
10663
10477
|
var binPath = () => {
|
|
10664
|
-
const here =
|
|
10478
|
+
const here = dirname5(fileURLToPath2(import.meta.url));
|
|
10665
10479
|
const devShim = join16(here, "..", "..", "bin", "baton.mjs");
|
|
10666
10480
|
return existsSync6(devShim) ? devShim : fileURLToPath2(import.meta.url);
|
|
10667
10481
|
};
|
|
@@ -10823,7 +10637,7 @@ import { spawn as spawn4 } from "node:child_process";
|
|
|
10823
10637
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
10824
10638
|
import { existsSync as existsSync7 } from "node:fs";
|
|
10825
10639
|
import { mkdir as mkdir6, rm as rm3, stat as stat5 } from "node:fs/promises";
|
|
10826
|
-
import { dirname as
|
|
10640
|
+
import { dirname as dirname6, join as join21 } from "node:path";
|
|
10827
10641
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
10828
10642
|
import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
|
|
10829
10643
|
|
|
@@ -11086,7 +10900,7 @@ var stopRecordedRunner = async (record, expected, graceMs = 5e3) => {
|
|
|
11086
10900
|
|
|
11087
10901
|
// src/worker/session-supervisor.ts
|
|
11088
10902
|
var binPath2 = () => {
|
|
11089
|
-
const here =
|
|
10903
|
+
const here = dirname6(fileURLToPath3(import.meta.url));
|
|
11090
10904
|
const devShim = join21(here, "..", "..", "bin", "baton.mjs");
|
|
11091
10905
|
return existsSync7(devShim) ? devShim : fileURLToPath3(import.meta.url);
|
|
11092
10906
|
};
|
|
@@ -11332,7 +11146,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
11332
11146
|
import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
|
|
11333
11147
|
import { createRequire as createModuleRequire } from "node:module";
|
|
11334
11148
|
import { homedir as homedir5 } from "node:os";
|
|
11335
|
-
import { dirname as
|
|
11149
|
+
import { dirname as dirname7, join as join22 } from "node:path";
|
|
11336
11150
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
11337
11151
|
var MAX_TERMINALS = 10;
|
|
11338
11152
|
var claudePtyCommand = (agentSessionId, hasJsonl, env = process.env) => ({
|
|
@@ -11353,7 +11167,7 @@ var piPtyCommand = (agentSessionId, env = process.env) => {
|
|
|
11353
11167
|
const override = env.BATON_PI_BIN?.trim();
|
|
11354
11168
|
if (override) return { file: override, args };
|
|
11355
11169
|
const entry = fileURLToPath4(import.meta.resolve("@earendil-works/pi-coding-agent"));
|
|
11356
|
-
return { file: process.execPath, args: [join22(
|
|
11170
|
+
return { file: process.execPath, args: [join22(dirname7(entry), "bundle", "cli.js"), ...args] };
|
|
11357
11171
|
};
|
|
11358
11172
|
var hasSessionJsonl = (agentSessionId) => {
|
|
11359
11173
|
const root = join22(homedir5(), ".claude", "projects");
|
|
@@ -11558,7 +11372,7 @@ var runWorkerDaemon = async (cfg, client, signal) => {
|
|
|
11558
11372
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
11559
11373
|
import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
11560
11374
|
import { homedir as homedir6 } from "node:os";
|
|
11561
|
-
import { dirname as
|
|
11375
|
+
import { dirname as dirname8, join as join23 } from "node:path";
|
|
11562
11376
|
var machineIdPath = (env = process.env) => join23(env.XDG_DATA_HOME ?? join23(env.HOME ?? homedir6(), ".local/share"), "baton", "machine-id");
|
|
11563
11377
|
var readOrCreateMachineId = (path = machineIdPath()) => {
|
|
11564
11378
|
if (existsSync9(path)) {
|
|
@@ -11566,7 +11380,7 @@ var readOrCreateMachineId = (path = machineIdPath()) => {
|
|
|
11566
11380
|
if (s) return s;
|
|
11567
11381
|
}
|
|
11568
11382
|
const id = randomUUID3();
|
|
11569
|
-
mkdirSync5(
|
|
11383
|
+
mkdirSync5(dirname8(path), { recursive: true });
|
|
11570
11384
|
writeFileSync5(path, `${id}
|
|
11571
11385
|
`, "utf8");
|
|
11572
11386
|
return id;
|
|
@@ -11576,7 +11390,7 @@ var readOrCreateMachineId = (path = machineIdPath()) => {
|
|
|
11576
11390
|
var projectArg = {
|
|
11577
11391
|
project: { type: "string", description: "project id (overrides .baton.json)" }
|
|
11578
11392
|
};
|
|
11579
|
-
var
|
|
11393
|
+
var positiveId2 = (raw) => {
|
|
11580
11394
|
const id = Number(raw);
|
|
11581
11395
|
if (!Number.isSafeInteger(id) || id <= 0) throw new Error("positive id required");
|
|
11582
11396
|
return id;
|
|
@@ -11585,12 +11399,12 @@ var workerTemplatesCommand = defineCommand({
|
|
|
11585
11399
|
meta: { name: "templates", description: "list worker creation templates for a project" },
|
|
11586
11400
|
args: { ...projectArg, ...common },
|
|
11587
11401
|
run: async ({ args }) => {
|
|
11588
|
-
const list = await clientFor(args).workerCreations.templates(
|
|
11402
|
+
const list = await clientFor(args).workerCreations.templates(positiveId2(resolveProjectId(args)));
|
|
11589
11403
|
console.log(renderList(list, fmtWorkerTemplate, Boolean(args.json)));
|
|
11590
11404
|
}
|
|
11591
11405
|
});
|
|
11592
11406
|
var workerCreateCommand = defineCommand({
|
|
11593
|
-
meta: { name: "create", description: "request a worker from
|
|
11407
|
+
meta: { name: "create", description: "request a worker from a template (asynchronous)" },
|
|
11594
11408
|
args: {
|
|
11595
11409
|
...projectArg,
|
|
11596
11410
|
...common,
|
|
@@ -11600,7 +11414,15 @@ var workerCreateCommand = defineCommand({
|
|
|
11600
11414
|
description: "mini-glm-codeplan | mini-dashscope-codeplan | mini-codex"
|
|
11601
11415
|
},
|
|
11602
11416
|
name: { type: "string", required: true, description: "worker name" },
|
|
11603
|
-
agentKind: { type: "string", description: AGENT_KINDS.join(", ") }
|
|
11417
|
+
agentKind: { type: "string", description: AGENT_KINDS.join(", ") },
|
|
11418
|
+
repoPath: {
|
|
11419
|
+
type: "string",
|
|
11420
|
+
description: "share an existing worker's directory in this project (default: a new one)"
|
|
11421
|
+
},
|
|
11422
|
+
host: {
|
|
11423
|
+
type: "string",
|
|
11424
|
+
description: "host name or id (default: the workspace's only host)"
|
|
11425
|
+
}
|
|
11604
11426
|
},
|
|
11605
11427
|
run: async ({ args }) => {
|
|
11606
11428
|
if (!isWorkerTemplateId(args.template)) throw new Error("invalid worker template");
|
|
@@ -11610,14 +11432,16 @@ var workerCreateCommand = defineCommand({
|
|
|
11610
11432
|
throw new Error("agentKind is not supported by this template");
|
|
11611
11433
|
const name = args.name.trim();
|
|
11612
11434
|
if (!name) throw new Error("worker name required");
|
|
11613
|
-
const
|
|
11614
|
-
|
|
11615
|
-
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11435
|
+
const client = clientFor(args);
|
|
11436
|
+
const projectId = positiveId2(resolveProjectId(args));
|
|
11437
|
+
const host2 = args.host ? findHost(await client.workerCreations.hosts(projectId), args.host) : null;
|
|
11438
|
+
const creation = await client.workerCreations.create(projectId, {
|
|
11439
|
+
templateId: args.template,
|
|
11440
|
+
name,
|
|
11441
|
+
agentKind,
|
|
11442
|
+
...args.repoPath ? { repoPath: args.repoPath } : {},
|
|
11443
|
+
...host2 ? { hostId: host2.id } : {}
|
|
11444
|
+
});
|
|
11621
11445
|
console.log(renderOne(creation, fmtWorkerCreation, Boolean(args.json)));
|
|
11622
11446
|
}
|
|
11623
11447
|
});
|
|
@@ -11628,7 +11452,7 @@ var workerCreationCommand = defineCommand({
|
|
|
11628
11452
|
args: { ...projectArg, ...common },
|
|
11629
11453
|
run: async ({ args }) => {
|
|
11630
11454
|
const list = await clientFor(args).workerCreations.listByProject(
|
|
11631
|
-
|
|
11455
|
+
positiveId2(resolveProjectId(args))
|
|
11632
11456
|
);
|
|
11633
11457
|
console.log(renderList(list, fmtWorkerCreation, Boolean(args.json)));
|
|
11634
11458
|
}
|
|
@@ -11636,7 +11460,7 @@ var workerCreationCommand = defineCommand({
|
|
|
11636
11460
|
get: defineCommand({
|
|
11637
11461
|
args: { ...common, id: { type: "positional", required: true } },
|
|
11638
11462
|
run: async ({ args }) => {
|
|
11639
|
-
const creation = await clientFor(args).workerCreations.get(
|
|
11463
|
+
const creation = await clientFor(args).workerCreations.get(positiveId2(args.id));
|
|
11640
11464
|
console.log(renderOne(creation, fmtWorkerCreation, Boolean(args.json)));
|
|
11641
11465
|
}
|
|
11642
11466
|
})
|
|
@@ -11928,13 +11752,14 @@ var workspace = defineCommand({
|
|
|
11928
11752
|
var main = defineCommand({
|
|
11929
11753
|
meta: {
|
|
11930
11754
|
name: "baton",
|
|
11931
|
-
description: "baton \u2014 run a worker daemon; manage projects /
|
|
11755
|
+
description: "baton \u2014 run a worker daemon; manage projects / sessions"
|
|
11932
11756
|
},
|
|
11933
11757
|
// Order matters: high-level verbs first so --help shows them on top.
|
|
11934
11758
|
subCommands: {
|
|
11935
11759
|
init,
|
|
11936
11760
|
worker,
|
|
11937
11761
|
provisioner,
|
|
11762
|
+
host,
|
|
11938
11763
|
session,
|
|
11939
11764
|
service,
|
|
11940
11765
|
artifact,
|
|
@@ -11943,9 +11768,7 @@ var main = defineCommand({
|
|
|
11943
11768
|
relay,
|
|
11944
11769
|
channel,
|
|
11945
11770
|
workspace,
|
|
11946
|
-
project
|
|
11947
|
-
requirement,
|
|
11948
|
-
task
|
|
11771
|
+
project
|
|
11949
11772
|
}
|
|
11950
11773
|
});
|
|
11951
11774
|
runMain(main);
|