@lesscap/baton-cli 0.9.6 → 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.
Files changed (3) hide show
  1. package/README.md +2 -2
  2. package/dist/baton.mjs +128 -339
  3. 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/requirements/tasks/sessions against a baton server.
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 | requirement | task | session` — run
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 configured`);
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");
@@ -7674,12 +7724,17 @@ var installProvisionerAgent = async (config, configPath) => startAgent(config, {
7674
7724
  // src/provisioner/worker-template.ts
7675
7725
  import { mkdir as mkdir2, writeFile } from "node:fs/promises";
7676
7726
  import { join as join4 } from "node:path";
7677
- var workerTemplateEnvironment = async (config, creation, state) => {
7727
+ var requireWorkerTemplate = (config, creation) => {
7678
7728
  if (!workerTemplateAgentKinds(creation.templateId).includes(creation.agentKind))
7679
7729
  throw new Error("agentKind is not supported by this template");
7680
- if (creation.templateId === "mini-local") return config.workerEnv;
7730
+ if (creation.templateId === "mini-local") return null;
7681
7731
  const profile = config.templates[creation.templateId];
7682
- 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;
7683
7738
  if (creation.agentKind !== "pi") return profile.workerEnv;
7684
7739
  if (!profile.pi) throw new Error("Pi provider and model are not configured");
7685
7740
  const agentDir = join4(state, "pi");
@@ -7765,6 +7820,7 @@ var adoptRepository = async (config, creation, repoPath, progress, signal) => {
7765
7820
  throw new Error(`not the root of a Git work tree: ${repoPath}`);
7766
7821
  };
7767
7822
  var provisionWorker = async (config, creation, client, signal) => {
7823
+ requireWorkerTemplate(config, creation);
7768
7824
  const shared = creation.repoPath !== null;
7769
7825
  const repoPath = creation.repoPath ?? join5(config.projectsRoot, `project-${creation.projectId}`, `creation-${creation.id}`);
7770
7826
  const progress = (step) => client.report(creation.id, { status: "running", step, repoPath }, signal);
@@ -8148,118 +8204,6 @@ var relay = defineCommand({
8148
8204
  subCommands: { host: hostCommand, listen: listenCommand2, send: sendCommand2 }
8149
8205
  });
8150
8206
 
8151
- // src/commands/requirement.ts
8152
- var createRequirement = (c, input, json) => c.requirements.create(input).then((r) => renderOne(r, fmtRequirement, json));
8153
- var updateRequirement = (c, id, patch, json) => c.requirements.update(id, patch).then((r) => renderOne(r, fmtRequirement, json));
8154
- var listRequirements = (c, projectId, json) => c.requirements.listByProject(projectId).then((rs) => renderList(rs, fmtRequirement, json));
8155
- var getRequirement = (c, id, json) => c.requirements.get(id).then((r) => renderOne(r, fmtRequirement, json));
8156
- var setRequirementStatus = (c, id, status, json) => c.requirements.setStatus(id, status).then((r) => renderOne(r, fmtRequirement, json));
8157
- var removeRequirement = (c, id, label, json) => c.requirements.remove(id).then(() => removed("requirement", label, json));
8158
- var resolveByCode = async (c, projectId, code) => (await c.requirements.getByCode(projectId, code)).id;
8159
- var requirement = defineCommand({
8160
- meta: { name: "requirement", description: "manage requirements" },
8161
- subCommands: {
8162
- create: defineCommand({
8163
- meta: { name: "create", description: "create a requirement" },
8164
- args: {
8165
- title: { type: "positional", required: true },
8166
- project: { type: "string", description: "project id (overrides .baton.json)" },
8167
- desc: { type: "string", description: "description" },
8168
- body: { type: "string", description: "requirement body (markdown)" },
8169
- ...common
8170
- },
8171
- run: async ({ args }) => {
8172
- console.log(
8173
- await createRequirement(
8174
- clientFor(args),
8175
- {
8176
- projectId: resolveProjectId(args),
8177
- title: args.title,
8178
- description: args.desc,
8179
- body: args.body
8180
- },
8181
- Boolean(args.json)
8182
- )
8183
- );
8184
- }
8185
- }),
8186
- update: defineCommand({
8187
- meta: { name: "update", description: "update a requirement title / body" },
8188
- args: {
8189
- code: { type: "positional", required: true, description: "requirement code (R-N)" },
8190
- title: { type: "string", description: "new title" },
8191
- body: { type: "string", description: "new body (markdown)" },
8192
- project: { type: "string", description: "project id (overrides .baton.json)" },
8193
- ...common
8194
- },
8195
- run: async ({ args }) => {
8196
- const patch = {
8197
- ...args.title !== void 0 ? { title: args.title } : {},
8198
- ...args.body !== void 0 ? { body: args.body } : {}
8199
- };
8200
- if (Object.keys(patch).length === 0) throw new Error("pass --title and/or --body");
8201
- const c = clientFor(args);
8202
- const id = await resolveByCode(c, resolveProjectId(args), args.code);
8203
- console.log(await updateRequirement(c, id, patch, Boolean(args.json)));
8204
- }
8205
- }),
8206
- ls: defineCommand({
8207
- meta: { name: "ls", description: "list requirements in a project" },
8208
- args: {
8209
- project: { type: "string", description: "project id (overrides .baton.json)" },
8210
- ...common
8211
- },
8212
- run: async ({ args }) => {
8213
- console.log(
8214
- await listRequirements(clientFor(args), resolveProjectId(args), Boolean(args.json))
8215
- );
8216
- }
8217
- }),
8218
- get: defineCommand({
8219
- meta: { name: "get", description: "get a requirement by code (R-N)" },
8220
- args: {
8221
- code: { type: "positional", required: true, description: "requirement code, e.g. R-1" },
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 getRequirement(c, id, Boolean(args.json)));
8229
- }
8230
- }),
8231
- "set-status": defineCommand({
8232
- meta: { name: "set-status", description: "set requirement status (active|done|cancelled)" },
8233
- args: {
8234
- code: { type: "positional", required: true, description: "requirement code (R-N)" },
8235
- status: { type: "positional", required: true },
8236
- project: { type: "string", description: "project id (overrides .baton.json)" },
8237
- ...common
8238
- },
8239
- run: async ({ args }) => {
8240
- const c = clientFor(args);
8241
- const id = await resolveByCode(c, resolveProjectId(args), args.code);
8242
- console.log(
8243
- await setRequirementStatus(c, id, args.status, Boolean(args.json))
8244
- );
8245
- }
8246
- }),
8247
- rm: defineCommand({
8248
- meta: { name: "rm", description: "delete a requirement by code" },
8249
- args: {
8250
- code: { type: "positional", required: true },
8251
- project: { type: "string", description: "project id (overrides .baton.json)" },
8252
- ...common
8253
- },
8254
- run: async ({ args }) => {
8255
- const c = clientFor(args);
8256
- const id = await resolveByCode(c, resolveProjectId(args), args.code);
8257
- console.log(await removeRequirement(c, id, args.code, Boolean(args.json)));
8258
- }
8259
- })
8260
- }
8261
- });
8262
-
8263
8207
  // src/commands/service.ts
8264
8208
  import { resolve as resolve2 } from "node:path";
8265
8209
 
@@ -9877,165 +9821,6 @@ var session = defineCommand({
9877
9821
  }
9878
9822
  });
9879
9823
 
9880
- // src/commands/task.ts
9881
- var createTask = (c, input, json) => c.tasks.create(input).then((t) => renderOne(t, fmtTask, json));
9882
- var updateTask = (c, id, patch, json) => c.tasks.update(id, patch).then((t) => renderOne(t, fmtTask, json));
9883
- var listTasks = (c, requirementId, json) => c.tasks.listByRequirement(requirementId).then((ts) => renderList(ts, fmtTask, json));
9884
- var getTask = (c, id, json) => c.tasks.get(id).then((t) => renderOne(t, fmtTask, json));
9885
- var setTaskStatus = (c, id, status, json) => c.tasks.setStatus(id, status).then((t) => renderOne(t, fmtTask, json));
9886
- var removeTask = (c, id, label, json) => c.tasks.remove(id).then(() => removed("task", label, json));
9887
- var addTaskComment = (c, taskId, body, workerId, json) => c.tasks.addComment(taskId, body, workerId).then((x) => renderOne(x, fmtComment, json));
9888
- var listTaskComments = (c, taskId, json) => c.tasks.listComments(taskId).then((xs) => renderList(xs, fmtComment, json));
9889
- var resolveReqByCode = async (c, projectId, code) => (await c.requirements.getByCode(projectId, code)).id;
9890
- var resolveTaskByCode = async (c, projectId, code) => (await c.tasks.getByCode(projectId, code)).id;
9891
- var task = defineCommand({
9892
- meta: { name: "task", description: "manage tasks" },
9893
- subCommands: {
9894
- create: defineCommand({
9895
- meta: { name: "create", description: "create a task" },
9896
- args: {
9897
- title: { type: "positional", required: true },
9898
- requirement: { type: "string", required: true, description: "requirement code (R-N)" },
9899
- project: { type: "string", description: "project id (overrides .baton.json)" },
9900
- body: { type: "string", description: "task body (markdown)" },
9901
- deps: { type: "string", description: "comma-separated dependency task codes (T-N,T-N)" },
9902
- ...common
9903
- },
9904
- run: async ({ args }) => {
9905
- const c = clientFor(args);
9906
- const projectId = resolveProjectId(args);
9907
- const requirementId = await resolveReqByCode(c, projectId, args.requirement);
9908
- const depCodes = splitCsv(args.deps) ?? [];
9909
- const dependsOn = await Promise.all(
9910
- depCodes.map((code) => resolveTaskByCode(c, projectId, code))
9911
- );
9912
- console.log(
9913
- await createTask(
9914
- c,
9915
- {
9916
- requirementId,
9917
- title: args.title,
9918
- body: args.body,
9919
- dependsOn: dependsOn.length ? dependsOn : void 0
9920
- },
9921
- Boolean(args.json)
9922
- )
9923
- );
9924
- }
9925
- }),
9926
- update: defineCommand({
9927
- meta: { name: "update", description: "update a task title / body" },
9928
- args: {
9929
- code: { type: "positional", required: true, description: "task code (T-N)" },
9930
- title: { type: "string", description: "new title" },
9931
- body: { type: "string", description: "new body (markdown)" },
9932
- project: { type: "string", description: "project id (overrides .baton.json)" },
9933
- ...common
9934
- },
9935
- run: async ({ args }) => {
9936
- const patch = {
9937
- ...args.title !== void 0 ? { title: args.title } : {},
9938
- ...args.body !== void 0 ? { body: args.body } : {}
9939
- };
9940
- if (Object.keys(patch).length === 0) throw new Error("pass --title and/or --body");
9941
- const c = clientFor(args);
9942
- const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
9943
- console.log(await updateTask(c, id, patch, Boolean(args.json)));
9944
- }
9945
- }),
9946
- ls: defineCommand({
9947
- meta: { name: "ls", description: "list tasks in a requirement" },
9948
- args: {
9949
- requirement: { type: "string", required: true, description: "requirement code (R-N)" },
9950
- project: { type: "string", description: "project id (overrides .baton.json)" },
9951
- ...common
9952
- },
9953
- run: async ({ args }) => {
9954
- const c = clientFor(args);
9955
- const reqId = await resolveReqByCode(c, resolveProjectId(args), args.requirement);
9956
- console.log(await listTasks(c, reqId, Boolean(args.json)));
9957
- }
9958
- }),
9959
- get: defineCommand({
9960
- meta: { name: "get", description: "get a task by code (T-N)" },
9961
- args: {
9962
- code: { type: "positional", required: true },
9963
- project: { type: "string", description: "project id (overrides .baton.json)" },
9964
- ...common
9965
- },
9966
- run: async ({ args }) => {
9967
- const c = clientFor(args);
9968
- const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
9969
- console.log(await getTask(c, id, Boolean(args.json)));
9970
- }
9971
- }),
9972
- "set-status": defineCommand({
9973
- meta: {
9974
- name: "set-status",
9975
- description: "set task status (todo|in_progress|blocked|done|failed|cancelled)"
9976
- },
9977
- args: {
9978
- code: { type: "positional", required: true, description: "task code (T-N)" },
9979
- status: { type: "positional", required: true },
9980
- project: { type: "string", description: "project id (overrides .baton.json)" },
9981
- ...common
9982
- },
9983
- run: async ({ args }) => {
9984
- const c = clientFor(args);
9985
- const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
9986
- console.log(await setTaskStatus(c, id, args.status, Boolean(args.json)));
9987
- }
9988
- }),
9989
- rm: defineCommand({
9990
- meta: { name: "rm", description: "delete a task by code" },
9991
- args: {
9992
- code: { type: "positional", required: true },
9993
- project: { type: "string", description: "project id (overrides .baton.json)" },
9994
- ...common
9995
- },
9996
- run: async ({ args }) => {
9997
- const c = clientFor(args);
9998
- const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
9999
- console.log(await removeTask(c, id, args.code, Boolean(args.json)));
10000
- }
10001
- }),
10002
- comment: defineCommand({
10003
- meta: { name: "comment", description: "append-only task comments" },
10004
- subCommands: {
10005
- add: defineCommand({
10006
- meta: { name: "add", description: "add a comment to a task" },
10007
- args: {
10008
- code: { type: "positional", required: true, description: "task code (T-N)" },
10009
- body: { type: "positional", required: true, description: "comment text (markdown)" },
10010
- worker: { type: "string", description: "attribute to a worker id (omit = human)" },
10011
- project: { type: "string", description: "project id (overrides .baton.json)" },
10012
- ...common
10013
- },
10014
- run: async ({ args }) => {
10015
- const c = clientFor(args);
10016
- const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
10017
- const workerId = args.worker ? Number(args.worker) : void 0;
10018
- console.log(await addTaskComment(c, id, args.body, workerId, Boolean(args.json)));
10019
- }
10020
- }),
10021
- ls: defineCommand({
10022
- meta: { name: "ls", description: "list a task\u2019s comments in order" },
10023
- args: {
10024
- code: { type: "positional", required: true, description: "task code (T-N)" },
10025
- project: { type: "string", description: "project id (overrides .baton.json)" },
10026
- ...common
10027
- },
10028
- run: async ({ args }) => {
10029
- const c = clientFor(args);
10030
- const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
10031
- console.log(await listTaskComments(c, id, Boolean(args.json)));
10032
- }
10033
- })
10034
- }
10035
- })
10036
- }
10037
- });
10038
-
10039
9824
  // src/commands/worker/index.ts
10040
9825
  import { hostname as osHostname } from "node:os";
10041
9826
 
@@ -11605,7 +11390,7 @@ var readOrCreateMachineId = (path = machineIdPath()) => {
11605
11390
  var projectArg = {
11606
11391
  project: { type: "string", description: "project id (overrides .baton.json)" }
11607
11392
  };
11608
- var positiveId = (raw) => {
11393
+ var positiveId2 = (raw) => {
11609
11394
  const id = Number(raw);
11610
11395
  if (!Number.isSafeInteger(id) || id <= 0) throw new Error("positive id required");
11611
11396
  return id;
@@ -11614,12 +11399,12 @@ var workerTemplatesCommand = defineCommand({
11614
11399
  meta: { name: "templates", description: "list worker creation templates for a project" },
11615
11400
  args: { ...projectArg, ...common },
11616
11401
  run: async ({ args }) => {
11617
- const list = await clientFor(args).workerCreations.templates(positiveId(resolveProjectId(args)));
11402
+ const list = await clientFor(args).workerCreations.templates(positiveId2(resolveProjectId(args)));
11618
11403
  console.log(renderList(list, fmtWorkerTemplate, Boolean(args.json)));
11619
11404
  }
11620
11405
  });
11621
11406
  var workerCreateCommand = defineCommand({
11622
- meta: { name: "create", description: "request a worker from the mini template (asynchronous)" },
11407
+ meta: { name: "create", description: "request a worker from a template (asynchronous)" },
11623
11408
  args: {
11624
11409
  ...projectArg,
11625
11410
  ...common,
@@ -11633,6 +11418,10 @@ var workerCreateCommand = defineCommand({
11633
11418
  repoPath: {
11634
11419
  type: "string",
11635
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)"
11636
11425
  }
11637
11426
  },
11638
11427
  run: async ({ args }) => {
@@ -11643,15 +11432,16 @@ var workerCreateCommand = defineCommand({
11643
11432
  throw new Error("agentKind is not supported by this template");
11644
11433
  const name = args.name.trim();
11645
11434
  if (!name) throw new Error("worker name required");
11646
- const creation = await clientFor(args).workerCreations.create(
11647
- positiveId(resolveProjectId(args)),
11648
- {
11649
- templateId: args.template,
11650
- name,
11651
- agentKind,
11652
- ...args.repoPath ? { repoPath: args.repoPath } : {}
11653
- }
11654
- );
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
+ });
11655
11445
  console.log(renderOne(creation, fmtWorkerCreation, Boolean(args.json)));
11656
11446
  }
11657
11447
  });
@@ -11662,7 +11452,7 @@ var workerCreationCommand = defineCommand({
11662
11452
  args: { ...projectArg, ...common },
11663
11453
  run: async ({ args }) => {
11664
11454
  const list = await clientFor(args).workerCreations.listByProject(
11665
- positiveId(resolveProjectId(args))
11455
+ positiveId2(resolveProjectId(args))
11666
11456
  );
11667
11457
  console.log(renderList(list, fmtWorkerCreation, Boolean(args.json)));
11668
11458
  }
@@ -11670,7 +11460,7 @@ var workerCreationCommand = defineCommand({
11670
11460
  get: defineCommand({
11671
11461
  args: { ...common, id: { type: "positional", required: true } },
11672
11462
  run: async ({ args }) => {
11673
- const creation = await clientFor(args).workerCreations.get(positiveId(args.id));
11463
+ const creation = await clientFor(args).workerCreations.get(positiveId2(args.id));
11674
11464
  console.log(renderOne(creation, fmtWorkerCreation, Boolean(args.json)));
11675
11465
  }
11676
11466
  })
@@ -11962,13 +11752,14 @@ var workspace = defineCommand({
11962
11752
  var main = defineCommand({
11963
11753
  meta: {
11964
11754
  name: "baton",
11965
- description: "baton \u2014 run a worker daemon; manage projects / requirements / tasks / sessions"
11755
+ description: "baton \u2014 run a worker daemon; manage projects / sessions"
11966
11756
  },
11967
11757
  // Order matters: high-level verbs first so --help shows them on top.
11968
11758
  subCommands: {
11969
11759
  init,
11970
11760
  worker,
11971
11761
  provisioner,
11762
+ host,
11972
11763
  session,
11973
11764
  service,
11974
11765
  artifact,
@@ -11977,9 +11768,7 @@ var main = defineCommand({
11977
11768
  relay,
11978
11769
  channel,
11979
11770
  workspace,
11980
- project,
11981
- requirement,
11982
- task
11771
+ project
11983
11772
  }
11984
11773
  });
11985
11774
  runMain(main);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lesscap/baton-cli",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"