@workser/cli 0.6.12 → 0.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3583,6 +3583,7 @@ function ownerOnly(opts) {
3583
3583
  }
3584
3584
 
3585
3585
  // src/output.ts
3586
+ var OUT_OF_SCOPE_EXIT = 7;
3586
3587
  var mode = "text";
3587
3588
  var quiet = false;
3588
3589
  function configureOutput(opts) {
@@ -3633,7 +3634,13 @@ function fail(err) {
3633
3634
  } else if (e.status === 401 || e.code === "unauthorized") {
3634
3635
  process.stderr.write(import_picocolors.default.dim(" Run `workser login` to authenticate.\n"));
3635
3636
  } else if (e.code === "no_project") {
3636
- process.stderr.write(import_picocolors.default.dim(" Run `workser project use <id>` or pass --project <id>.\n"));
3637
+ process.stderr.write(import_picocolors.default.dim(" cd into the project's folder, or open it in Workser.\n"));
3638
+ } else if (e.code === "out_of_scope") {
3639
+ process.stderr.write(
3640
+ import_picocolors.default.dim(
3641
+ " You can move between your organization's projects; another organization's are not reachable.\n"
3642
+ )
3643
+ );
3637
3644
  } else if (e.code === "awaiting_approval") {
3638
3645
  process.stderr.write(import_picocolors.default.dim(" Approve the action in Workser Orbit, then retry.\n"));
3639
3646
  } else if (e.code === "owner_only") {
@@ -3647,6 +3654,7 @@ function exitCodeFor(e) {
3647
3654
  if (e.status === 401 || e.code === "unauthorized") return 3;
3648
3655
  if (e.code === "awaiting_approval") return 5;
3649
3656
  if (e.code === "owner_only") return OWNER_ONLY_EXIT;
3657
+ if (e.code === "out_of_scope") return OUT_OF_SCOPE_EXIT;
3650
3658
  return 1;
3651
3659
  }
3652
3660
 
@@ -4063,6 +4071,84 @@ Two things worth knowing:
4063
4071
 
4064
4072
  An app that has never been published has no address, so there is nothing to
4065
4073
  check. That is reported as a note, not as a pass.
4074
+ `
4075
+ },
4076
+ {
4077
+ topic: "cloud-agents",
4078
+ title: "Ship an agent inside the app",
4079
+ summary: "Create an AI agent that runs on Workser and can be called from this project's apps.",
4080
+ commands: ["cloud-agent"],
4081
+ source: "skills/workser/reference/cloud-agents.md",
4082
+ body: `# Ship an agent inside the app
4083
+
4084
+ \`workser cloud-agent\` creates an AI agent that runs on **Workser's**
4085
+ infrastructure, keeps its own memory and tools, and can be called from the web,
4086
+ mobile, API or Python apps in this project.
4087
+
4088
+ **This is not \`workser agent\`.** That one hands a subtask to a coding agent on
4089
+ this machine \u2014 a teammate helping you build. This one is a thing the project
4090
+ *ships*: it works for the user after you are gone.
4091
+
4092
+ \`\`\`
4093
+ workser cloud-agent list
4094
+ workser cloud-agent create "Order desk" --instructions "..."
4095
+ workser cloud-agent show <agentId>
4096
+ workser cloud-agent run <agentId> "<what to do>"
4097
+ workser cloud-agent runs <agentId> # recent runs
4098
+ workser cloud-agent runs <runId> # one run, with what it cost
4099
+ \`\`\`
4100
+
4101
+ Every call is scoped to the project this folder belongs to.
4102
+
4103
+ ## When to reach for this
4104
+
4105
+ When the user describes a job that **keeps happening** and needs judgement:
4106
+ "check every order for stock and email me the problems", "read the LINE
4107
+ messages and file them", "reconcile these invoices". That is an agent.
4108
+
4109
+ A one-off transformation is not an agent \u2014 write the code. A fixed sequence of
4110
+ steps with no judgement in it is not an agent either \u2014 that is \`workser
4111
+ workflow\`.
4112
+
4113
+ ## Calling it from the app you are building
4114
+
4115
+ Do NOT shell out to the CLI from app code. Use the SDK, which streams:
4116
+
4117
+ \`\`\`ts
4118
+ import { workser } from '@workser/app';
4119
+
4120
+ const run = await workser.agents.run(agentId, { message }, {
4121
+ referenceUserId: user.id, // who it is acting for
4122
+ });
4123
+
4124
+ for await (const event of workser.agents.stream(run.id)) {
4125
+ // event.type, event.data \u2014 forward these to the browser
4126
+ }
4127
+ \`\`\`
4128
+
4129
+ \`stream()\` reconnects itself through dropped connections, so the person
4130
+ watching sees the agent think. See the \`workser-sdk\` skill, \`reference/agents.md\`.
4131
+
4132
+ ## Things that will bite you
4133
+
4134
+ 1. **A run costs money by the minute.** It is metered \u2014 runtime, workspace, and
4135
+ a per-run fee \u2014 so a loop that starts agents is a loop that spends. Cancel
4136
+ what you abandon: \`workser cloud-agent runs <runId>\` shows the cost.
4137
+
4138
+ 2. **Instructions are the product.** The agent does what its instructions say,
4139
+ in the user's own words. Write them the way you would brief a new colleague:
4140
+ what to do, what to leave alone, when to ask. Vague instructions are the
4141
+ single biggest cause of an agent that "doesn't work".
4142
+
4143
+ 3. **Free plans cannot run agents at all**, and a trial has a small allowance.
4144
+ A \`402\` with \`spend_limit_reached\` is not a bug \u2014 tell the user what it says
4145
+ and point them at their plan.
4146
+
4147
+ 4. **Say who it is for.** An agent acting for one of the app's customers needs
4148
+ \`referenceUserId\`, or its memory and audit trail belong to nobody.
4149
+
4150
+ 5. **Do not invent an agent the user did not ask for.** Creating one is cheap;
4151
+ an agent nobody wanted, quietly costing money per run, is not.
4066
4152
  `
4067
4153
  },
4068
4154
  {
@@ -5624,6 +5710,9 @@ async function api(ctx, path, opts = {}) {
5624
5710
  if (ctx.mode === "daemon" && ctx.runId) {
5625
5711
  headers["x-workser-run-id"] = ctx.runId;
5626
5712
  }
5713
+ if (ctx.mode === "daemon" && ctx.cwd) {
5714
+ headers["x-workser-cwd"] = encodeURIComponent(ctx.cwd);
5715
+ }
5627
5716
  if (opts.body !== void 0) headers["content-type"] = "application/json";
5628
5717
  const method = opts.method ?? (opts.body !== void 0 ? "POST" : "GET");
5629
5718
  const bodyText = opts.body !== void 0 ? JSON.stringify(opts.body) : void 0;
@@ -5709,6 +5798,12 @@ function registerStatus(program3) {
5709
5798
  ` project: ${data.project?.name ?? "\u2014"}` + (data.project?.id ? import_picocolors3.default.dim(` (${data.project.id})`) : "")
5710
5799
  );
5711
5800
  if (ctx.projectRoot) line(` folder: ${import_picocolors3.default.dim(ctx.projectRoot)}`);
5801
+ if (data.scope) {
5802
+ const why = data.scope.source === "folder" ? "this folder" : data.scope.source === "active" ? "the project open in Workser" : null;
5803
+ line(
5804
+ data.scope.orgId ? ` org: ${data.scope.orgId}` + (why ? import_picocolors3.default.dim(` (from ${why})`) : "") : ` org: ${import_picocolors3.default.yellow("unscoped \u2014 every project is reachable")}`
5805
+ );
5806
+ }
5712
5807
  if (ctx.appId) {
5713
5808
  line(
5714
5809
  ` app: ${ctx.appName ?? "\u2014"}` + import_picocolors3.default.dim(` (${ctx.appId})`)
@@ -5921,7 +6016,7 @@ function registerProject(program3) {
5921
6016
  });
5922
6017
  })
5923
6018
  );
5924
- project.command("list").description("List the workspace's projects").action(
6019
+ project.command("list").description("List the projects in your organization").action(
5925
6020
  action(async ({ ctx }) => {
5926
6021
  const items = await api(ctx, `/v1/projects`);
5927
6022
  ok(items, () => {
@@ -5930,6 +6025,11 @@ function registerProject(program3) {
5930
6025
  const pinned = ctx.projectId && p.id === ctx.projectId ? import_picocolors4.default.green("\u25CF ") : " ";
5931
6026
  line(`${pinned}${p.name ?? "\u2014"}${p.id ? import_picocolors4.default.dim(` (${p.id})`) : ""}`);
5932
6027
  }
6028
+ line(
6029
+ import_picocolors4.default.dim(
6030
+ "\nYour organization's projects. Other organizations are not reachable from here."
6031
+ )
6032
+ );
5933
6033
  });
5934
6034
  })
5935
6035
  );
@@ -7437,8 +7537,154 @@ function formatRole(r) {
7437
7537
  return `${label} ${agent} ${enabled} ${ready}${tail}`;
7438
7538
  }
7439
7539
 
7440
- // src/commands/verify.ts
7540
+ // src/commands/cloud-agent.ts
7441
7541
  var import_picocolors17 = __toESM(require_picocolors(), 1);
7542
+ function registerCloudAgent(program3) {
7543
+ const cloud = program3.command("cloud-agent").description(
7544
+ "Agents that run in the cloud and can be called from this project's apps (not the local coding agents \u2014 that's `workser agent`)"
7545
+ );
7546
+ cloud.command("list").description("List this project's cloud agents").action(
7547
+ action(async ({ ctx }) => {
7548
+ const res = await api(ctx, "/v1/cloud-agents");
7549
+ const agents = res?.agents ?? res ?? [];
7550
+ ok(res, () => {
7551
+ if (!agents.length) {
7552
+ line(import_picocolors17.default.dim("No cloud agents yet."));
7553
+ line(
7554
+ import_picocolors17.default.dim("Create one: ") + import_picocolors17.default.bold('workser cloud-agent create "Order desk" --instructions "..."')
7555
+ );
7556
+ return;
7557
+ }
7558
+ for (const a of agents) {
7559
+ line(
7560
+ `${import_picocolors17.default.bold(a.name ?? a.id)} ${import_picocolors17.default.dim(a.id)}` + (a.status ? ` ${import_picocolors17.default.dim(a.status)}` : "")
7561
+ );
7562
+ if (a.description) line(" " + import_picocolors17.default.dim(a.description));
7563
+ }
7564
+ });
7565
+ })
7566
+ );
7567
+ cloud.command("create <name>").description("Create a cloud agent in this project").option("--description <text>", "What it is for, in the owner's words").option(
7568
+ "--instructions <text>",
7569
+ "The agent's standing instructions \u2014 what it should always do"
7570
+ ).action(
7571
+ action(async ({ ctx, args, opts }) => {
7572
+ const res = await api(ctx, "/v1/cloud-agents", {
7573
+ method: "POST",
7574
+ body: {
7575
+ name: args[0],
7576
+ description: opts.description,
7577
+ instructions: opts.instructions
7578
+ }
7579
+ });
7580
+ ok(res, () => {
7581
+ line(import_picocolors17.default.green("Created ") + import_picocolors17.default.bold(res?.name ?? args[0]));
7582
+ if (res?.id) line(import_picocolors17.default.dim(res.id));
7583
+ line("");
7584
+ line(
7585
+ import_picocolors17.default.dim("Give it work: ") + import_picocolors17.default.bold(`workser cloud-agent run ${res?.id ?? "<id>"} "..."`)
7586
+ );
7587
+ });
7588
+ })
7589
+ );
7590
+ cloud.command("show <agentId>").description("One cloud agent, with its configuration").action(
7591
+ action(async ({ ctx, args }) => {
7592
+ const res = await api(ctx, `/v1/cloud-agents/${encodeURIComponent(args[0])}`);
7593
+ ok(res, () => {
7594
+ line(import_picocolors17.default.bold(res?.name ?? args[0]));
7595
+ if (res?.description) line(import_picocolors17.default.dim(res.description));
7596
+ if (res?.instructions) {
7597
+ line("");
7598
+ line(import_picocolors17.default.bold("instructions:"));
7599
+ line(res.instructions);
7600
+ }
7601
+ });
7602
+ })
7603
+ );
7604
+ cloud.command("run <agentId> <message>").description("Give a cloud agent something to do").action(
7605
+ action(async ({ ctx, args }) => {
7606
+ const res = await api(
7607
+ ctx,
7608
+ `/v1/cloud-agents/${encodeURIComponent(args[0])}/runs`,
7609
+ { method: "POST", body: { input: { message: args[1] } } }
7610
+ );
7611
+ ok(res, () => {
7612
+ line(import_picocolors17.default.green("Started run ") + import_picocolors17.default.bold(res?.id ?? ""));
7613
+ line(
7614
+ import_picocolors17.default.dim("Follow it: ") + import_picocolors17.default.bold(`workser cloud-agent runs ${res?.id ?? "<runId>"}`)
7615
+ );
7616
+ });
7617
+ })
7618
+ );
7619
+ cloud.command("runs [agentIdOrRunId]").description("Recent runs for an agent, or one run in detail").option("--limit <n>", "How many to list", "10").action(
7620
+ action(async ({ ctx, args, opts }) => {
7621
+ const id = args[0];
7622
+ if (!id) {
7623
+ warn("Give an agent id to list its runs, or a run id to inspect one.");
7624
+ return;
7625
+ }
7626
+ try {
7627
+ const run = await api(
7628
+ ctx,
7629
+ `/v1/cloud-agents/runs/${encodeURIComponent(id)}`
7630
+ );
7631
+ ok(run, () => printRun(run));
7632
+ return;
7633
+ } catch {
7634
+ }
7635
+ const res = await api(
7636
+ ctx,
7637
+ `/v1/cloud-agents/${encodeURIComponent(id)}/runs`,
7638
+ { query: { limit: opts.limit } }
7639
+ );
7640
+ const runs = res?.runs ?? res ?? [];
7641
+ ok(res, () => {
7642
+ if (!runs.length) {
7643
+ line(import_picocolors17.default.dim("No runs yet."));
7644
+ return;
7645
+ }
7646
+ for (const r of runs) printRun(r, true);
7647
+ });
7648
+ })
7649
+ );
7650
+ }
7651
+ function printRun(run, compact = false) {
7652
+ const status = String(run?.status ?? "").toLowerCase();
7653
+ const colour2 = status === "completed" ? import_picocolors17.default.green : status === "failed" ? import_picocolors17.default.red : import_picocolors17.default.yellow;
7654
+ line(
7655
+ `${colour2(status || "unknown")} ${import_picocolors17.default.bold(run?.id ?? "")}` + (run?.duration_ms ? ` ${import_picocolors17.default.dim(formatDuration(run.duration_ms))}` : "")
7656
+ );
7657
+ const breakdown = run?.cost_breakdown;
7658
+ if (breakdown) {
7659
+ if (!breakdown.settled) {
7660
+ line(" " + import_picocolors17.default.dim("cost: still being worked out"));
7661
+ } else {
7662
+ line(" " + import_picocolors17.default.dim(`cost: $${Number(breakdown.total_usd).toFixed(4)}`));
7663
+ line(
7664
+ " " + import_picocolors17.default.dim(
7665
+ `model $${Number(breakdown.model_usd).toFixed(4)} \xB7 infrastructure $${Number(breakdown.infrastructure_usd).toFixed(4)}`
7666
+ )
7667
+ );
7668
+ }
7669
+ } else if (run?.cost_usd !== void 0 && run?.cost_usd !== null) {
7670
+ line(" " + import_picocolors17.default.dim(`model cost: $${Number(run.cost_usd).toFixed(4)}`));
7671
+ }
7672
+ if (!compact && run?.output) {
7673
+ line("");
7674
+ line(typeof run.output === "string" ? run.output : JSON.stringify(run.output, null, 2));
7675
+ }
7676
+ if (run?.error?.message) line(" " + import_picocolors17.default.red(run.error.message));
7677
+ }
7678
+ function formatDuration(ms) {
7679
+ if (ms < 1e3) return `${ms}ms`;
7680
+ const seconds = Math.round(ms / 1e3);
7681
+ if (seconds < 60) return `${seconds}s`;
7682
+ const minutes = Math.floor(seconds / 60);
7683
+ return `${minutes}m ${seconds % 60}s`;
7684
+ }
7685
+
7686
+ // src/commands/verify.ts
7687
+ var import_picocolors18 = __toESM(require_picocolors(), 1);
7442
7688
  function registerVerify(program3) {
7443
7689
  program3.command("verify").description(
7444
7690
  "Run the project's checks (typecheck/lint/build) \u2014 use before declaring a task done"
@@ -7460,23 +7706,23 @@ function registerVerify(program3) {
7460
7706
  function printVerify(res) {
7461
7707
  if (!res) return;
7462
7708
  if (!res.checks?.length) {
7463
- line(import_picocolors17.default.dim(res.note ?? "No checks detected."));
7709
+ line(import_picocolors18.default.dim(res.note ?? "No checks detected."));
7464
7710
  return;
7465
7711
  }
7466
7712
  for (const c of res.checks) {
7467
7713
  line(
7468
- ` ${c.ok ? import_picocolors17.default.green("\u2713") : import_picocolors17.default.red("\u2717")} ${c.name}${c.ok ? "" : import_picocolors17.default.dim(` (exit ${c.exitCode})`)}`
7714
+ ` ${c.ok ? import_picocolors18.default.green("\u2713") : import_picocolors18.default.red("\u2717")} ${c.name}${c.ok ? "" : import_picocolors18.default.dim(` (exit ${c.exitCode})`)}`
7469
7715
  );
7470
7716
  }
7471
7717
  if (res.ok) success("All checks passed");
7472
7718
  else
7473
7719
  line(
7474
- import_picocolors17.default.red("Some checks failed \u2014 fix the errors above and re-run ") + import_picocolors17.default.bold("workser verify") + import_picocolors17.default.red(".")
7720
+ import_picocolors18.default.red("Some checks failed \u2014 fix the errors above and re-run ") + import_picocolors18.default.bold("workser verify") + import_picocolors18.default.red(".")
7475
7721
  );
7476
7722
  }
7477
7723
 
7478
7724
  // src/commands/checkpoint.ts
7479
- var import_picocolors18 = __toESM(require_picocolors(), 1);
7725
+ var import_picocolors19 = __toESM(require_picocolors(), 1);
7480
7726
  function registerCheckpoint(program3) {
7481
7727
  program3.command("checkpoint [label]").description(
7482
7728
  "Save the current state of this folder so you can come back to it"
@@ -7493,8 +7739,8 @@ function registerCheckpoint(program3) {
7493
7739
  ok(res, () => {
7494
7740
  const p = res?.point;
7495
7741
  success(`Saved a checkpoint${p?.label ? `: ${p.label}` : ""}`);
7496
- if (p?.ref) line(import_picocolors18.default.dim(` ${p.ref.slice(0, 7)}`));
7497
- line(import_picocolors18.default.dim(" Come back to it with `workser restore`."));
7742
+ if (p?.ref) line(import_picocolors19.default.dim(` ${p.ref.slice(0, 7)}`));
7743
+ line(import_picocolors19.default.dim(" Come back to it with `workser restore`."));
7498
7744
  });
7499
7745
  })
7500
7746
  );
@@ -7520,12 +7766,12 @@ function registerCheckpoint(program3) {
7520
7766
  );
7521
7767
  if (res?.filesChanged) {
7522
7768
  line(
7523
- import_picocolors18.default.dim(
7769
+ import_picocolors19.default.dim(
7524
7770
  ` ${res.filesChanged} file${res.filesChanged === 1 ? "" : "s"} changed`
7525
7771
  )
7526
7772
  );
7527
7773
  }
7528
- line(import_picocolors18.default.dim(" This is reversible: `workser restore` again."));
7774
+ line(import_picocolors19.default.dim(" This is reversible: `workser restore` again."));
7529
7775
  });
7530
7776
  })
7531
7777
  );
@@ -7542,25 +7788,25 @@ function registerCheckpoint(program3) {
7542
7788
  function printPoints(points) {
7543
7789
  if (!points.length) {
7544
7790
  info("No checkpoints yet for this folder.");
7545
- line(import_picocolors18.default.dim(" Take one with `workser checkpoint`."));
7791
+ line(import_picocolors19.default.dim(" Take one with `workser checkpoint`."));
7546
7792
  return;
7547
7793
  }
7548
- line(import_picocolors18.default.bold("Checkpoints"));
7794
+ line(import_picocolors19.default.bold("Checkpoints"));
7549
7795
  for (const p of points) {
7550
7796
  const when = p.at ? new Date(p.at).toLocaleString() : "";
7551
7797
  line(
7552
- ` ${import_picocolors18.default.dim(p.ref.slice(0, 7))} ${p.label}${when ? import_picocolors18.default.dim(` ${when}`) : ""}`
7798
+ ` ${import_picocolors19.default.dim(p.ref.slice(0, 7))} ${p.label}${when ? import_picocolors19.default.dim(` ${when}`) : ""}`
7553
7799
  );
7554
7800
  }
7555
7801
  line(
7556
- import_picocolors18.default.dim(
7802
+ import_picocolors19.default.dim(
7557
7803
  "\nGo back with `workser restore <ref>`, or just `workser restore` for the newest."
7558
7804
  )
7559
7805
  );
7560
7806
  }
7561
7807
 
7562
7808
  // src/commands/sync.ts
7563
- var import_picocolors19 = __toESM(require_picocolors(), 1);
7809
+ var import_picocolors20 = __toESM(require_picocolors(), 1);
7564
7810
  function registerSync(program3) {
7565
7811
  program3.command("sync").description(
7566
7812
  "Reconcile this folder with the copy Workser holds (pull, then push)"
@@ -7587,7 +7833,7 @@ function registerSync(program3) {
7587
7833
  warn(res?.message ?? "Couldn't sync this folder.");
7588
7834
  if (res?.state === "diverged") {
7589
7835
  line(
7590
- import_picocolors19.default.dim(
7836
+ import_picocolors20.default.dim(
7591
7837
  " This folder and Workser's copy have both changed. Open Workser to resolve it."
7592
7838
  )
7593
7839
  );
@@ -7599,7 +7845,7 @@ function registerSync(program3) {
7599
7845
  return;
7600
7846
  }
7601
7847
  success("Synced");
7602
- if (res?.ref) line(import_picocolors19.default.dim(` ${String(res.ref).slice(0, 7)}`));
7848
+ if (res?.ref) line(import_picocolors20.default.dim(` ${String(res.ref).slice(0, 7)}`));
7603
7849
  });
7604
7850
  if (refused) process.exitCode = 1;
7605
7851
  })
@@ -7607,7 +7853,7 @@ function registerSync(program3) {
7607
7853
  }
7608
7854
 
7609
7855
  // src/commands/workflow.ts
7610
- var import_picocolors20 = __toESM(require_picocolors(), 1);
7856
+ var import_picocolors21 = __toESM(require_picocolors(), 1);
7611
7857
  function registerWorkflow(program3) {
7612
7858
  const wf = program3.command("workflow").description("Create, run, and inspect workflow automations for the project");
7613
7859
  wf.command("list").description("List the project's workflows").action(
@@ -7615,10 +7861,10 @@ function registerWorkflow(program3) {
7615
7861
  const projectId = requireProject(ctx);
7616
7862
  const items = await api(ctx, `/v1/projects/${projectId}/workflows`);
7617
7863
  ok(items, () => {
7618
- if (!items?.length) return line(import_picocolors20.default.dim("No workflows yet. `workser workflow create`."));
7864
+ if (!items?.length) return line(import_picocolors21.default.dim("No workflows yet. `workser workflow create`."));
7619
7865
  for (const w of items) {
7620
- const status = w.is_active ? import_picocolors20.default.green("active") : import_picocolors20.default.dim("inactive");
7621
- line(`${w.id} ${import_picocolors20.default.bold(w.name ?? "Untitled")} ${status}`);
7866
+ const status = w.is_active ? import_picocolors21.default.green("active") : import_picocolors21.default.dim("inactive");
7867
+ line(`${w.id} ${import_picocolors21.default.bold(w.name ?? "Untitled")} ${status}`);
7622
7868
  }
7623
7869
  });
7624
7870
  })
@@ -7630,7 +7876,7 @@ function registerWorkflow(program3) {
7630
7876
  const res = await api(ctx, `/v1/projects/${projectId}/workflows`, {
7631
7877
  body: { name: args[0], ...extra }
7632
7878
  });
7633
- ok(res, () => line(`Created workflow ${import_picocolors20.default.bold(res.id)}.`));
7879
+ ok(res, () => line(`Created workflow ${import_picocolors21.default.bold(res.id)}.`));
7634
7880
  })
7635
7881
  );
7636
7882
  wf.command("get <id>").description("Show a workflow's full definition").action(
@@ -7665,8 +7911,8 @@ function registerWorkflow(program3) {
7665
7911
  action(async ({ ctx, args }) => {
7666
7912
  const items = await api(ctx, `/v1/workflows/${args[0]}/executions`);
7667
7913
  ok(items, () => {
7668
- if (!items?.length) return line(import_picocolors20.default.dim("No runs yet."));
7669
- for (const e of items) line(`${e.id} ${e.status ?? ""} ${import_picocolors20.default.dim(e.started_at ?? "")}`);
7914
+ if (!items?.length) return line(import_picocolors21.default.dim("No runs yet."));
7915
+ for (const e of items) line(`${e.id} ${e.status ?? ""} ${import_picocolors21.default.dim(e.started_at ?? "")}`);
7670
7916
  });
7671
7917
  })
7672
7918
  );
@@ -7674,15 +7920,15 @@ function registerWorkflow(program3) {
7674
7920
  action(async ({ ctx, args }) => {
7675
7921
  const items = await api(ctx, `/v1/node-types`, { query: { q: args[0] } });
7676
7922
  ok(items, () => {
7677
- if (!items?.length) return line(import_picocolors20.default.dim("No matching node types."));
7678
- for (const n of items) line(`${n.name ?? n.type} ${import_picocolors20.default.dim(n.category ?? "")}`);
7923
+ if (!items?.length) return line(import_picocolors21.default.dim("No matching node types."));
7924
+ for (const n of items) line(`${n.name ?? n.type} ${import_picocolors21.default.dim(n.category ?? "")}`);
7679
7925
  });
7680
7926
  })
7681
7927
  );
7682
7928
  }
7683
7929
 
7684
7930
  // src/commands/connection.ts
7685
- var import_picocolors21 = __toESM(require_picocolors(), 1);
7931
+ var import_picocolors22 = __toESM(require_picocolors(), 1);
7686
7932
  function registerConnection(program3) {
7687
7933
  const connection = program3.command("connection").description("Connect and use third-party app connections (Gmail, Slack, Stripe, ...)");
7688
7934
  connection.command("list").description("List connectable toolkits and this project's existing connections").option("--toolkit <slug>", "filter connections to one toolkit").action(
@@ -7695,8 +7941,8 @@ function registerConnection(program3) {
7695
7941
  ok({ catalog, connections }, () => {
7696
7942
  const connected = new Set((connections ?? []).map((c) => c.toolkit ?? c.composio_app));
7697
7943
  for (const t of catalog ?? []) {
7698
- const status = connected.has(t.slug) ? import_picocolors21.default.green("connected") : import_picocolors21.default.dim("not connected");
7699
- line(`${t.slug} ${import_picocolors21.default.bold(t.name ?? t.slug)} ${status}`);
7944
+ const status = connected.has(t.slug) ? import_picocolors22.default.green("connected") : import_picocolors22.default.dim("not connected");
7945
+ line(`${t.slug} ${import_picocolors22.default.bold(t.name ?? t.slug)} ${status}`);
7700
7946
  }
7701
7947
  });
7702
7948
  })
@@ -7708,9 +7954,9 @@ function registerConnection(program3) {
7708
7954
  query: { q: args[0], toolkit: opts.toolkit, limit: opts.limit }
7709
7955
  });
7710
7956
  ok(items, () => {
7711
- if (!items?.length) return line(import_picocolors21.default.dim("No matching actions."));
7957
+ if (!items?.length) return line(import_picocolors22.default.dim("No matching actions."));
7712
7958
  for (const t of items) {
7713
- line(`${t.slug} ${import_picocolors21.default.dim(`[${t.toolkit}]`)} ${t.description ?? ""}`);
7959
+ line(`${t.slug} ${import_picocolors22.default.dim(`[${t.toolkit}]`)} ${t.description ?? ""}`);
7714
7960
  }
7715
7961
  });
7716
7962
  })
@@ -7727,7 +7973,7 @@ function registerConnection(program3) {
7727
7973
  });
7728
7974
  ok(
7729
7975
  res,
7730
- () => res.oauth_url ? line(`Open this URL to finish connecting: ${import_picocolors21.default.underline(res.oauth_url)}`) : line(`Connection ${res.connection_id} is ${res.status}.`)
7976
+ () => res.oauth_url ? line(`Open this URL to finish connecting: ${import_picocolors22.default.underline(res.oauth_url)}`) : line(`Connection ${res.connection_id} is ${res.status}.`)
7731
7977
  );
7732
7978
  })
7733
7979
  );
@@ -7745,8 +7991,8 @@ function registerConnection(program3) {
7745
7991
  const projectId = requireProject(ctx);
7746
7992
  const items = await api(ctx, `/v1/projects/${projectId}/integrations/${args[0]}/tools`);
7747
7993
  ok(items, () => {
7748
- if (!items?.length) return line(import_picocolors21.default.dim("No tools found."));
7749
- for (const t of items) line(`${t.slug} ${import_picocolors21.default.dim(t.description ?? "")}`);
7994
+ if (!items?.length) return line(import_picocolors22.default.dim("No tools found."));
7995
+ for (const t of items) line(`${t.slug} ${import_picocolors22.default.dim(t.description ?? "")}`);
7750
7996
  });
7751
7997
  })
7752
7998
  );
@@ -7762,7 +8008,7 @@ function registerConnection(program3) {
7762
8008
  }
7763
8009
 
7764
8010
  // src/commands/tool.ts
7765
- var import_picocolors22 = __toESM(require_picocolors(), 1);
8011
+ var import_picocolors23 = __toESM(require_picocolors(), 1);
7766
8012
  function registerTool(program3) {
7767
8013
  const tool = program3.command("tool").description(
7768
8014
  "Computer-use tools: filesystem, shell, screenshot, input control, clipboard, notifications, basic browser"
@@ -7771,7 +8017,7 @@ function registerTool(program3) {
7771
8017
  action(async ({ ctx }) => {
7772
8018
  const tools = await api(ctx, "/v1/tool/list");
7773
8019
  ok(tools, () => {
7774
- if (!tools?.length) return line(import_picocolors22.default.dim("No tools available."));
8020
+ if (!tools?.length) return line(import_picocolors23.default.dim("No tools available."));
7775
8021
  const byCategory = /* @__PURE__ */ new Map();
7776
8022
  for (const t of tools) {
7777
8023
  const list = byCategory.get(t.category) ?? [];
@@ -7779,9 +8025,9 @@ function registerTool(program3) {
7779
8025
  byCategory.set(t.category, list);
7780
8026
  }
7781
8027
  for (const [category, items] of byCategory) {
7782
- line(import_picocolors22.default.bold(category) + ":");
8028
+ line(import_picocolors23.default.bold(category) + ":");
7783
8029
  for (const t of items) {
7784
- line(` ${t.name} ${import_picocolors22.default.dim(t.description ?? "")}`);
8030
+ line(` ${t.name} ${import_picocolors23.default.dim(t.description ?? "")}`);
7785
8031
  }
7786
8032
  }
7787
8033
  });
@@ -7799,7 +8045,7 @@ function registerTool(program3) {
7799
8045
  }
7800
8046
 
7801
8047
  // src/commands/memory.ts
7802
- var import_picocolors23 = __toESM(require_picocolors(), 1);
8048
+ var import_picocolors24 = __toESM(require_picocolors(), 1);
7803
8049
  function registerMemory(program3) {
7804
8050
  const memory = program3.command("memory").description("Durable, cross-conversation project memory (shared with cloud agents on the same project)");
7805
8051
  memory.command("add <content>").description("Store something worth remembering across future conversations").option("--metadata <json>", "extra metadata for filtering, as a JSON string").option("--id <customId>", "custom id for dedup/updates").action(
@@ -7823,9 +8069,9 @@ function registerMemory(program3) {
7823
8069
  });
7824
8070
  ok(res, () => {
7825
8071
  const results = res?.results ?? res ?? [];
7826
- if (!results?.length) return line(import_picocolors23.default.dim("No matching memories."));
8072
+ if (!results?.length) return line(import_picocolors24.default.dim("No matching memories."));
7827
8073
  for (const r of results) {
7828
- line(`${import_picocolors23.default.dim(r.id ?? "?")} ${r.memory ?? r.content ?? ""}`);
8074
+ line(`${import_picocolors24.default.dim(r.id ?? "?")} ${r.memory ?? r.content ?? ""}`);
7829
8075
  }
7830
8076
  });
7831
8077
  })
@@ -7841,8 +8087,52 @@ function registerMemory(program3) {
7841
8087
  );
7842
8088
  }
7843
8089
 
8090
+ // src/commands/note.ts
8091
+ var import_picocolors25 = __toESM(require_picocolors(), 1);
8092
+ function registerNote(program3) {
8093
+ program3.command("note <text>").description("Leave a fact the rest of the team will need").addHelpText(
8094
+ "after",
8095
+ '\nFor things that are true about the WORK, not about your step:\n workser note "the API base path is /api/v2, not /api"\n workser note "added STRIPE_KEY to local, preview and production"\n\nWhat your own step did goes in `workser task done --summary` instead.\n'
8096
+ ).option(
8097
+ "--task <id>",
8098
+ "the plan to leave it on (default: the plan this step belongs to)"
8099
+ ).action(
8100
+ action(async ({ ctx, args, opts }) => {
8101
+ const text = typeof args[0] === "string" ? args[0].trim() : "";
8102
+ if (!text) {
8103
+ info("Nothing to note \u2014 give it a sentence.");
8104
+ return;
8105
+ }
8106
+ const taskId = opts.task || ctx.parentTaskId || ctx.projectTaskId;
8107
+ if (!taskId) {
8108
+ info(
8109
+ "No plan to leave this on. Run it from inside a step, or pass --task <id>."
8110
+ );
8111
+ return;
8112
+ }
8113
+ const res = await api(ctx, "/v1/team-notes", {
8114
+ body: {
8115
+ cwd: ctx.cwd,
8116
+ taskId,
8117
+ text,
8118
+ role: ctx.agentRole,
8119
+ agent: ctx.agentType
8120
+ }
8121
+ }).catch(() => null);
8122
+ if (!res) {
8123
+ info("Couldn't save that note \u2014 carrying on.");
8124
+ return;
8125
+ }
8126
+ ok(res, () => {
8127
+ success("Noted for the team.");
8128
+ line(import_picocolors25.default.dim(` ${text}`));
8129
+ });
8130
+ })
8131
+ );
8132
+ }
8133
+
7844
8134
  // src/commands/business.ts
7845
- var import_picocolors24 = __toESM(require_picocolors(), 1);
8135
+ var import_picocolors26 = __toESM(require_picocolors(), 1);
7846
8136
  var RESOURCE_PATHS = {
7847
8137
  "business-config": "business-config",
7848
8138
  "business-settings": "business-settings",
@@ -7902,7 +8192,7 @@ function registerBusiness(program3) {
7902
8192
  const projectId = requireProject(ctx);
7903
8193
  const [resource] = args;
7904
8194
  const res = await api(ctx, businessPath(projectId, resource), { body: JSON.parse(opts.body) });
7905
- ok(res, () => line(`Created ${resource} ${import_picocolors24.default.bold(res?.id ?? "")}.`));
8195
+ ok(res, () => line(`Created ${resource} ${import_picocolors26.default.bold(res?.id ?? "")}.`));
7906
8196
  })
7907
8197
  );
7908
8198
  biz.command("update <resource> <id>").description("Update a record by id (PATCH/PUT \u2014 matches the underlying route)").option("--body <json>", "changed fields as a JSON object string", "{}").action(
@@ -7944,7 +8234,7 @@ function businessPath(projectId, resource, subpath) {
7944
8234
  }
7945
8235
 
7946
8236
  // src/commands/artifact.ts
7947
- var import_picocolors25 = __toESM(require_picocolors(), 1);
8237
+ var import_picocolors27 = __toESM(require_picocolors(), 1);
7948
8238
  import { existsSync as existsSync2, statSync } from "fs";
7949
8239
  import { resolve as resolve3, basename as basename3 } from "path";
7950
8240
  var KINDS = [
@@ -8041,7 +8331,7 @@ function registerArtifact(program3) {
8041
8331
  ok(
8042
8332
  res,
8043
8333
  () => success(
8044
- `Recorded ${import_picocolors25.default.bold(res?.title ?? "artifact")}${res?.kind ? import_picocolors25.default.dim(` (${res.kind})`) : ""}`
8334
+ `Recorded ${import_picocolors27.default.bold(res?.title ?? "artifact")}${res?.kind ? import_picocolors27.default.dim(` (${res.kind})`) : ""}`
8045
8335
  )
8046
8336
  );
8047
8337
  })
@@ -8073,13 +8363,13 @@ function registerArtifact(program3) {
8073
8363
  artifact.command("run").description("Show the task/conversation this agent run is attached to").action(
8074
8364
  action(async ({ ctx }) => {
8075
8365
  const res = await api(ctx, `/v1/runs/${runTarget(ctx)}`);
8076
- ok(res, () => printRun(res));
8366
+ ok(res, () => printRun2(res));
8077
8367
  })
8078
8368
  );
8079
8369
  }
8080
8370
  function printArtifacts(rows) {
8081
8371
  if (!rows.length) {
8082
- line(import_picocolors25.default.dim("Nothing produced yet."));
8372
+ line(import_picocolors27.default.dim("Nothing produced yet."));
8083
8373
  return;
8084
8374
  }
8085
8375
  const byStep = /* @__PURE__ */ new Map();
@@ -8089,26 +8379,26 @@ function printArtifacts(rows) {
8089
8379
  byStep.set(r.subtask_id, list);
8090
8380
  }
8091
8381
  for (const [stepId, items] of byStep) {
8092
- line(import_picocolors25.default.bold(`step ${stepId}`));
8382
+ line(import_picocolors27.default.bold(`step ${stepId}`));
8093
8383
  for (const a of items) {
8094
- const flag = a.promoted_at ? import_picocolors25.default.green(" *") : " ";
8384
+ const flag = a.promoted_at ? import_picocolors27.default.green(" *") : " ";
8095
8385
  const where = a.local_path || a.cloud_url || "";
8096
8386
  line(
8097
- `${flag} ${import_picocolors25.default.dim(`[${a.kind}]`)} ${a.title ?? "(untitled)"}` + (where ? import_picocolors25.default.dim(` ${where}`) : "")
8387
+ `${flag} ${import_picocolors27.default.dim(`[${a.kind}]`)} ${a.title ?? "(untitled)"}` + (where ? import_picocolors27.default.dim(` ${where}`) : "")
8098
8388
  );
8099
- if (a.description) line(import_picocolors25.default.dim(` ${a.description}`));
8389
+ if (a.description) line(import_picocolors27.default.dim(` ${a.description}`));
8100
8390
  }
8101
8391
  line("");
8102
8392
  }
8103
- line(import_picocolors25.default.dim("* = handed over as a deliverable; the rest is working material."));
8393
+ line(import_picocolors27.default.dim("* = handed over as a deliverable; the rest is working material."));
8104
8394
  }
8105
- function printRun(run) {
8395
+ function printRun2(run) {
8106
8396
  if (!run) return;
8107
- line(` run ${import_picocolors25.default.bold(run.runId)}`);
8397
+ line(` run ${import_picocolors27.default.bold(run.runId)}`);
8108
8398
  if (run.taskId) line(` task ${run.taskId}`);
8109
8399
  if (run.conversationId) line(` chat ${run.conversationId}`);
8110
8400
  if (run.projectId) line(` project ${run.projectId}`);
8111
- if (run.cwd) line(` folder ${import_picocolors25.default.dim(run.cwd)}`);
8401
+ if (run.cwd) line(` folder ${import_picocolors27.default.dim(run.cwd)}`);
8112
8402
  }
8113
8403
 
8114
8404
  // src/commands/image.ts
@@ -8289,7 +8579,7 @@ function registerAudio(program3) {
8289
8579
  }
8290
8580
 
8291
8581
  // src/commands/ask.ts
8292
- var import_picocolors26 = __toESM(require_picocolors(), 1);
8582
+ var import_picocolors28 = __toESM(require_picocolors(), 1);
8293
8583
  var TYPES = [
8294
8584
  "input",
8295
8585
  "choice",
@@ -8367,7 +8657,7 @@ function registerAsk(program3) {
8367
8657
  code: "bad_request"
8368
8658
  });
8369
8659
  }
8370
- info(import_picocolors26.default.dim("Waiting for the user to answer\u2026"));
8660
+ info(import_picocolors28.default.dim("Waiting for the user to answer\u2026"));
8371
8661
  const res = await api(ctx, `/v1/runs/${runTarget(ctx)}/ask`, {
8372
8662
  body: {
8373
8663
  type,
@@ -8395,12 +8685,12 @@ function deriveTitle(message) {
8395
8685
  function printAnswer(res) {
8396
8686
  if (!res) return;
8397
8687
  if (res.status === "answered") {
8398
- line(` ${import_picocolors26.default.green("answered")}`);
8688
+ line(` ${import_picocolors28.default.green("answered")}`);
8399
8689
  const value = extract(res.response);
8400
8690
  if (value) line(` ${value}`);
8401
8691
  return;
8402
8692
  }
8403
- line(` ${import_picocolors26.default.yellow(res.status)} ${import_picocolors26.default.dim(res.reason ?? "")}`);
8693
+ line(` ${import_picocolors28.default.yellow(res.status)} ${import_picocolors28.default.dim(res.reason ?? "")}`);
8404
8694
  }
8405
8695
  function extract(response) {
8406
8696
  if (response == null) return "";
@@ -8419,7 +8709,7 @@ function extract(response) {
8419
8709
  }
8420
8710
 
8421
8711
  // src/commands/search.ts
8422
- var import_picocolors27 = __toESM(require_picocolors(), 1);
8712
+ var import_picocolors29 = __toESM(require_picocolors(), 1);
8423
8713
  function registerSearch(program3) {
8424
8714
  program3.command("search <query>").description("Search the web (Google-grounded, server-side)").option("-n, --max-results <n>", "max results", "5").action(
8425
8715
  action(async ({ ctx, args, opts }) => {
@@ -8432,9 +8722,9 @@ function registerSearch(program3) {
8432
8722
  line("");
8433
8723
  }
8434
8724
  const results = res?.results ?? [];
8435
- if (!results.length) return line(import_picocolors27.default.dim("No results."));
8725
+ if (!results.length) return line(import_picocolors29.default.dim("No results."));
8436
8726
  for (const r of results) {
8437
- line(`${r.title || import_picocolors27.default.dim("(untitled)")} ${import_picocolors27.default.dim(r.url)}`);
8727
+ line(`${r.title || import_picocolors29.default.dim("(untitled)")} ${import_picocolors29.default.dim(r.url)}`);
8438
8728
  }
8439
8729
  });
8440
8730
  })
@@ -8442,7 +8732,7 @@ function registerSearch(program3) {
8442
8732
  }
8443
8733
 
8444
8734
  // src/commands/board.ts
8445
- var import_picocolors28 = __toESM(require_picocolors(), 1);
8735
+ var import_picocolors30 = __toESM(require_picocolors(), 1);
8446
8736
 
8447
8737
  // src/commands/record-step.ts
8448
8738
  async function recordEntityStep(ctx, opts) {
@@ -8481,7 +8771,7 @@ function registerBoard(program3) {
8481
8771
  }
8482
8772
  ok(rows, () => {
8483
8773
  if (!rows.length) {
8484
- line(import_picocolors28.default.dim("No cards on the Board yet."));
8774
+ line(import_picocolors30.default.dim("No cards on the Board yet."));
8485
8775
  return;
8486
8776
  }
8487
8777
  for (const r of rows) line(formatRow(r));
@@ -8496,7 +8786,7 @@ function registerBoard(program3) {
8496
8786
  `/v1/projects/${projectId}/work-items/${args[0]}`
8497
8787
  );
8498
8788
  ok(row, () => {
8499
- line(`${import_picocolors28.default.bold(row.title)} ${import_picocolors28.default.dim(row.id)}`);
8789
+ line(`${import_picocolors30.default.bold(row.title)} ${import_picocolors30.default.dim(row.id)}`);
8500
8790
  line(`${statusTag(row.status)} priority ${row.priority}`);
8501
8791
  if (row.ownerHuman) line(`owner: ${row.ownerHuman}`);
8502
8792
  if (row.labels?.length) line(`labels: ${row.labels.join(", ")}`);
@@ -8537,7 +8827,7 @@ ${row.description}`);
8537
8827
  refId: row?.id,
8538
8828
  output: { workItem: row }
8539
8829
  });
8540
- ok(row, () => line(`Created work item ${import_picocolors28.default.bold(row?.id ?? "")} \u2014 ${title}`));
8830
+ ok(row, () => line(`Created work item ${import_picocolors30.default.bold(row?.id ?? "")} \u2014 ${title}`));
8541
8831
  })
8542
8832
  );
8543
8833
  board.command("update <id>").description("Change fields on a card \u2014 pass only what changes").option("--title <text>", "new title").option("--description <text>", "new description").option("--status <value>", STATUSES.join(" | ")).option("--priority <value>", PRIORITIES.join(" | ")).option(
@@ -8571,7 +8861,7 @@ ${row.description}`);
8571
8861
  );
8572
8862
  }
8573
8863
  const row = await patchItem(ctx, projectId, String(args[0]), body);
8574
- ok(row, () => line(`Updated ${import_picocolors28.default.bold(row.id)} \u2014 ${row.title} ${statusTag(row.status)}`));
8864
+ ok(row, () => line(`Updated ${import_picocolors30.default.bold(row.id)} \u2014 ${row.title} ${statusTag(row.status)}`));
8575
8865
  })
8576
8866
  );
8577
8867
  board.command("move <id> <status>").description(
@@ -8582,14 +8872,14 @@ ${row.description}`);
8582
8872
  const status = String(args[1]);
8583
8873
  assertStatus(status);
8584
8874
  const row = await patchItem(ctx, projectId, String(args[0]), { status });
8585
- ok(row, () => line(`Moved ${import_picocolors28.default.bold(row.title)} \u2192 ${statusTag(row.status)}`));
8875
+ ok(row, () => line(`Moved ${import_picocolors30.default.bold(row.title)} \u2192 ${statusTag(row.status)}`));
8586
8876
  })
8587
8877
  );
8588
8878
  board.command("close <id>").description("Shorthand for `board move <id> done`").action(
8589
8879
  action(async ({ ctx, args }) => {
8590
8880
  const projectId = requireProject(ctx);
8591
8881
  const row = await patchItem(ctx, projectId, String(args[0]), { status: "done" });
8592
- ok(row, () => line(`Closed ${import_picocolors28.default.bold(row.title)} ${statusTag(row.status)}`));
8882
+ ok(row, () => line(`Closed ${import_picocolors30.default.bold(row.title)} ${statusTag(row.status)}`));
8593
8883
  })
8594
8884
  );
8595
8885
  }
@@ -8622,23 +8912,23 @@ function assertPriority(value) {
8622
8912
  }
8623
8913
  }
8624
8914
  function formatRow(r) {
8625
- const labels = r.labels?.length ? import_picocolors28.default.dim(` [${r.labels.join(", ")}]`) : "";
8626
- const owner = r.ownerHuman ? import_picocolors28.default.dim(` @${r.ownerHuman}`) : "";
8627
- return `${import_picocolors28.default.dim(r.id)} ${statusTag(r.status)} ${r.title}${labels}${owner}`;
8915
+ const labels = r.labels?.length ? import_picocolors30.default.dim(` [${r.labels.join(", ")}]`) : "";
8916
+ const owner = r.ownerHuman ? import_picocolors30.default.dim(` @${r.ownerHuman}`) : "";
8917
+ return `${import_picocolors30.default.dim(r.id)} ${statusTag(r.status)} ${r.title}${labels}${owner}`;
8628
8918
  }
8629
8919
  function statusTag(status) {
8630
8920
  const label = status.padEnd(11);
8631
- if (status === "done") return import_picocolors28.default.green(label);
8632
- if (status === "in-progress") return import_picocolors28.default.yellow(label);
8633
- if (status === "in-review") return import_picocolors28.default.cyan(label);
8634
- return import_picocolors28.default.dim(label);
8921
+ if (status === "done") return import_picocolors30.default.green(label);
8922
+ if (status === "in-progress") return import_picocolors30.default.yellow(label);
8923
+ if (status === "in-review") return import_picocolors30.default.cyan(label);
8924
+ return import_picocolors30.default.dim(label);
8635
8925
  }
8636
8926
  function collect2(value, previous) {
8637
8927
  return [...previous, value];
8638
8928
  }
8639
8929
 
8640
8930
  // src/commands/task.ts
8641
- var import_picocolors29 = __toESM(require_picocolors(), 1);
8931
+ var import_picocolors31 = __toESM(require_picocolors(), 1);
8642
8932
 
8643
8933
  // src/subtask-attachments.ts
8644
8934
  var MAX_REF_NOTE = 500;
@@ -8752,7 +9042,7 @@ function registerTask(program3) {
8752
9042
  }) ?? [];
8753
9043
  ok(rows, () => {
8754
9044
  if (!rows.length) {
8755
- line(import_picocolors29.default.dim("No tasks on the board yet."));
9045
+ line(import_picocolors31.default.dim("No tasks on the board yet."));
8756
9046
  return;
8757
9047
  }
8758
9048
  for (const r of rows) line(formatRow2(r));
@@ -8861,10 +9151,10 @@ function registerTask(program3) {
8861
9151
  };
8862
9152
  ok(result, () => {
8863
9153
  line(
8864
- `${import_picocolors29.default.green("opened")} ${import_picocolors29.default.bold(row.title)} ${import_picocolors29.default.dim(row.key ?? row.id)}`
9154
+ `${import_picocolors31.default.green("opened")} ${import_picocolors31.default.bold(row.title)} ${import_picocolors31.default.dim(row.key ?? row.id)}`
8865
9155
  );
8866
9156
  if (channelMessage)
8867
- line(import_picocolors29.default.dim("posted to the channel as Project Manager"));
9157
+ line(import_picocolors31.default.dim("posted to the channel as Project Manager"));
8868
9158
  if (channelMessageError) {
8869
9159
  warn(
8870
9160
  `Task opened, but its Project Manager card could not be posted: ${channelMessageError.message}`
@@ -8943,12 +9233,12 @@ function registerTask(program3) {
8943
9233
  ) : null;
8944
9234
  ok(runner ?? row, () => {
8945
9235
  line(
8946
- `${import_picocolors29.default.green("added")} ${import_picocolors29.default.bold(row.title)} ${import_picocolors29.default.dim(row.key ?? row.id)}`
9236
+ `${import_picocolors31.default.green("added")} ${import_picocolors31.default.bold(row.title)} ${import_picocolors31.default.dim(row.key ?? row.id)}`
8947
9237
  );
8948
- if (row.role) line(import_picocolors29.default.dim(`role: ${row.role}`));
9238
+ if (row.role) line(import_picocolors31.default.dim(`role: ${row.role}`));
8949
9239
  if (runner) {
8950
9240
  line(
8951
- import_picocolors29.default.dim(
9241
+ import_picocolors31.default.dim(
8952
9242
  `runs on: ${[opts.agent, opts.model, opts.effort].filter(Boolean).join(" \xB7 ")}`
8953
9243
  )
8954
9244
  );
@@ -8966,7 +9256,7 @@ function registerTask(program3) {
8966
9256
  const rows = row.subtasks ?? [];
8967
9257
  ok(rows, () => {
8968
9258
  if (!rows.length) {
8969
- line(import_picocolors29.default.dim("No subtasks yet."));
9259
+ line(import_picocolors31.default.dim("No subtasks yet."));
8970
9260
  return;
8971
9261
  }
8972
9262
  rows.forEach((r, i) => line(formatSubtask(r, i + 1)));
@@ -9014,7 +9304,7 @@ function registerTask(program3) {
9014
9304
  }
9015
9305
  }
9016
9306
  );
9017
- ok(row, () => line(`${import_picocolors29.default.green("updated")} ${import_picocolors29.default.bold(row.title)}`));
9307
+ ok(row, () => line(`${import_picocolors31.default.green("updated")} ${import_picocolors31.default.bold(row.title)}`));
9018
9308
  })
9019
9309
  );
9020
9310
  subtask.command("remove <id>").description("Remove a subtask (only before the work starts)").action(
@@ -9022,7 +9312,7 @@ function registerTask(program3) {
9022
9312
  await api(ctx, `/v1/project-tasks/${encodeURIComponent(args[0])}`, {
9023
9313
  method: "DELETE"
9024
9314
  });
9025
- ok({ removed: args[0] }, () => line(import_picocolors29.default.green("removed")));
9315
+ ok({ removed: args[0] }, () => line(import_picocolors31.default.green("removed")));
9026
9316
  })
9027
9317
  );
9028
9318
  task.command("move <id> <status>").description(
@@ -9037,7 +9327,7 @@ function registerTask(program3) {
9037
9327
  );
9038
9328
  ok(
9039
9329
  row,
9040
- () => line(`${import_picocolors29.default.green("moved")} ${import_picocolors29.default.bold(row.title)} \u2192 ${args[1]}`)
9330
+ () => line(`${import_picocolors31.default.green("moved")} ${import_picocolors31.default.bold(row.title)} \u2192 ${args[1]}`)
9041
9331
  );
9042
9332
  })
9043
9333
  );
@@ -9053,18 +9343,18 @@ function registerTask(program3) {
9053
9343
  );
9054
9344
  ok(row, () => {
9055
9345
  if (!row?.queued) {
9056
- line(import_picocolors29.default.yellow("could not resume it \u2014 check the step id"));
9346
+ line(import_picocolors31.default.yellow("could not resume it \u2014 check the step id"));
9057
9347
  return;
9058
9348
  }
9059
9349
  const started = row.started ?? 0;
9060
9350
  if (started > 0) {
9061
9351
  line(
9062
- `${import_picocolors29.default.green("resumed")} \u2014 ${started} step${started === 1 ? "" : "s"} started`
9352
+ `${import_picocolors31.default.green("resumed")} \u2014 ${started} step${started === 1 ? "" : "s"} started`
9063
9353
  );
9064
9354
  return;
9065
9355
  }
9066
9356
  line(
9067
- `${import_picocolors29.default.green("resumed")} \u2014 it is queued, but nothing started yet. Check the plan is approved and that no step is blocking the rest.`
9357
+ `${import_picocolors31.default.green("resumed")} \u2014 it is queued, but nothing started yet. Check the plan is approved and that no step is blocking the rest.`
9068
9358
  );
9069
9359
  });
9070
9360
  })
@@ -9078,11 +9368,11 @@ function registerTask(program3) {
9078
9368
  );
9079
9369
  ok(row, () => {
9080
9370
  if (row?.reopened) {
9081
- line(`${import_picocolors29.default.green("sent back")} \u2014 it will be picked up again`);
9371
+ line(`${import_picocolors31.default.green("sent back")} \u2014 it will be picked up again`);
9082
9372
  return;
9083
9373
  }
9084
9374
  line(
9085
- import_picocolors29.default.yellow(
9375
+ import_picocolors31.default.yellow(
9086
9376
  row?.reason === "already_open" ? "already waiting to be picked up \u2014 nothing to send back" : row?.reason === "still_working" ? "still working \u2014 let it finish before sending it back" : "could not send that step back"
9087
9377
  )
9088
9378
  );
@@ -9099,7 +9389,7 @@ function registerTask(program3) {
9099
9389
  `/v1/project-tasks/${encodeURIComponent(id)}/dispatch-check`,
9100
9390
  { method: "POST" }
9101
9391
  );
9102
- ok(row, () => line(import_picocolors29.default.green("approved \u2014 you may start")));
9392
+ ok(row, () => line(import_picocolors31.default.green("approved \u2014 you may start")));
9103
9393
  })
9104
9394
  );
9105
9395
  task.command("start [id]").description(
@@ -9114,13 +9404,13 @@ function registerTask(program3) {
9114
9404
  const started = row?.started ?? null;
9115
9405
  if (started && started > 0) {
9116
9406
  line(
9117
- import_picocolors29.default.green(
9407
+ import_picocolors31.default.green(
9118
9408
  `started ${started} step${started === 1 ? "" : "s"} \u2014 they are running now`
9119
9409
  )
9120
9410
  );
9121
9411
  return;
9122
9412
  }
9123
- line(import_picocolors29.default.yellow(row?.note ?? "Nothing started."));
9413
+ line(import_picocolors31.default.yellow(row?.note ?? "Nothing started."));
9124
9414
  });
9125
9415
  })
9126
9416
  );
@@ -9135,7 +9425,7 @@ function registerTask(program3) {
9135
9425
  );
9136
9426
  ok({ awaiting: row2.approval_state === "awaiting", task: row2 }, () => {
9137
9427
  line(
9138
- row2.approval_state === "awaiting" ? import_picocolors29.default.yellow(
9428
+ row2.approval_state === "awaiting" ? import_picocolors31.default.yellow(
9139
9429
  "The plan is waiting on the owner. They see it in the task."
9140
9430
  ) : `Already ${row2.approval_state}.`
9141
9431
  );
@@ -9160,7 +9450,7 @@ function registerTask(program3) {
9160
9450
  );
9161
9451
  ok(
9162
9452
  row,
9163
- () => line(`${import_picocolors29.default.green(row.approval_state)} ${import_picocolors29.default.bold(row.title)}`)
9453
+ () => line(`${import_picocolors31.default.green(row.approval_state)} ${import_picocolors31.default.bold(row.title)}`)
9164
9454
  );
9165
9455
  })
9166
9456
  );
@@ -9176,7 +9466,7 @@ function registerTask(program3) {
9176
9466
  `/v1/project-tasks/${encodeURIComponent(id)}/move`,
9177
9467
  { body: { status: "ready" } }
9178
9468
  );
9179
- ok(row, () => line(`${import_picocolors29.default.green("ready")} ${import_picocolors29.default.bold(row.title)}`));
9469
+ ok(row, () => line(`${import_picocolors31.default.green("ready")} ${import_picocolors31.default.bold(row.title)}`));
9180
9470
  })
9181
9471
  );
9182
9472
  }
@@ -9221,24 +9511,24 @@ function assertOneOf(flag, value, allowed) {
9221
9511
  }
9222
9512
  }
9223
9513
  function formatRow2(r) {
9224
- const key = import_picocolors29.default.dim((r.key ?? r.id.slice(0, 8)).padEnd(10));
9225
- const steps = r.subtaskTotal ? import_picocolors29.default.dim(` ${r.subtaskDone}/${r.subtaskTotal}`) : "";
9226
- const gate = r.approval_state === "awaiting" ? import_picocolors29.default.yellow(" awaiting approval") : "";
9514
+ const key = import_picocolors31.default.dim((r.key ?? r.id.slice(0, 8)).padEnd(10));
9515
+ const steps = r.subtaskTotal ? import_picocolors31.default.dim(` ${r.subtaskDone}/${r.subtaskTotal}`) : "";
9516
+ const gate = r.approval_state === "awaiting" ? import_picocolors31.default.yellow(" awaiting approval") : "";
9227
9517
  return `${key} ${statusTag2(r.status)} ${r.title}${steps}${gate}`;
9228
9518
  }
9229
9519
  function formatSubtask(r, index) {
9230
- const n = import_picocolors29.default.dim(String(index).padStart(2, "0"));
9231
- const role = r.role ? import_picocolors29.default.dim(` [${r.role}]`) : "";
9232
- const scope = r.scope_paths?.length ? import_picocolors29.default.dim(` owns: ${r.scope_paths.join(", ")}`) : "";
9520
+ const n = import_picocolors31.default.dim(String(index).padStart(2, "0"));
9521
+ const role = r.role ? import_picocolors31.default.dim(` [${r.role}]`) : "";
9522
+ const scope = r.scope_paths?.length ? import_picocolors31.default.dim(` owns: ${r.scope_paths.join(", ")}`) : "";
9233
9523
  const head = `${n} ${statusTag2(r.status)} ${r.title}${role}${scope}`;
9234
9524
  const summary = (r.result_summary ?? "").trim();
9235
9525
  if (!summary) return head;
9236
9526
  const wrapped = summary.split("\n").map((l) => ` ${l}`).join("\n");
9237
9527
  return `${head}
9238
- ${import_picocolors29.default.dim(wrapped)}`;
9528
+ ${import_picocolors31.default.dim(wrapped)}`;
9239
9529
  }
9240
9530
  function printTask(row, goal) {
9241
- line(`${import_picocolors29.default.bold(row.title)} ${import_picocolors29.default.dim(row.key ?? row.id)}`);
9531
+ line(`${import_picocolors31.default.bold(row.title)} ${import_picocolors31.default.dim(row.key ?? row.id)}`);
9242
9532
  line(`${statusTag2(row.status)} approval: ${row.approval_state}`);
9243
9533
  if (row.summary) line(`
9244
9534
  ${row.summary}`);
@@ -9251,53 +9541,53 @@ touches: ${row.targets.map((t) => t.appName ?? t.ref ?? t.kind).join(", ")}`
9251
9541
  }
9252
9542
  if (row.subtasks?.length) {
9253
9543
  line(`
9254
- ${import_picocolors29.default.bold("subtasks")}`);
9544
+ ${import_picocolors31.default.bold("subtasks")}`);
9255
9545
  row.subtasks.forEach((s, i) => line(formatSubtask(s, i + 1)));
9256
9546
  line(
9257
- import_picocolors29.default.dim(
9547
+ import_picocolors31.default.dim(
9258
9548
  `
9259
9549
  Run \`workser artifact list\` to see what these subtasks produced,`
9260
9550
  )
9261
9551
  );
9262
9552
  line(
9263
- import_picocolors29.default.dim(
9553
+ import_picocolors31.default.dim(
9264
9554
  `or \`workser artifact list --step <id>\` for one subtask's output alone.`
9265
9555
  )
9266
9556
  );
9267
9557
  } else {
9268
- line(import_picocolors29.default.dim("\nNo subtasks yet."));
9558
+ line(import_picocolors31.default.dim("\nNo subtasks yet."));
9269
9559
  }
9270
9560
  }
9271
9561
  function printGoalContext(row, goal) {
9272
9562
  const mine = row.phase ?? null;
9273
9563
  line(`
9274
- ${import_picocolors29.default.bold("part of")}: ${goal.title}`);
9275
- if (goal.outcome) line(import_picocolors29.default.dim(`done means: ${goal.outcome}`));
9564
+ ${import_picocolors31.default.bold("part of")}: ${goal.title}`);
9565
+ if (goal.outcome) line(import_picocolors31.default.dim(`done means: ${goal.outcome}`));
9276
9566
  const progress = goal.progress ?? [];
9277
9567
  for (const p of progress) {
9278
9568
  const where = p.total === 0 ? "not started" : `${p.done} of ${p.total} done`;
9279
- const here = mine && p.name === mine ? import_picocolors29.default.cyan(" <- this task") : "";
9280
- const mark = p.state === "done" ? import_picocolors29.default.green("*") : import_picocolors29.default.dim("-");
9569
+ const here = mine && p.name === mine ? import_picocolors31.default.cyan(" <- this task") : "";
9570
+ const mark = p.state === "done" ? import_picocolors31.default.green("*") : import_picocolors31.default.dim("-");
9281
9571
  line(` ${mark} ${p.name} \u2014 ${where}${here}`);
9282
9572
  }
9283
9573
  const next = progress.find((p) => p.state !== "done");
9284
9574
  const running = progress.some((p) => p.state === "working");
9285
9575
  if (next && !running) {
9286
9576
  line(
9287
- import_picocolors29.default.dim(
9577
+ import_picocolors31.default.dim(
9288
9578
  `
9289
9579
  Nothing is running. The next part waiting is "${next.name}" \u2014 offer it to them in a sentence rather than starting it unasked.`
9290
9580
  )
9291
9581
  );
9292
9582
  } else if (!next) {
9293
9583
  line(
9294
- import_picocolors29.default.dim(
9584
+ import_picocolors31.default.dim(
9295
9585
  "\nEvery part of this plan is done. Say so, and offer to wrap it up."
9296
9586
  )
9297
9587
  );
9298
9588
  }
9299
9589
  line(
9300
- import_picocolors29.default.dim(
9590
+ import_picocolors31.default.dim(
9301
9591
  "The plan is a reference for what was agreed, not a rule about what may run. Work can start on any part at any time if they ask for it."
9302
9592
  )
9303
9593
  );
@@ -9305,22 +9595,22 @@ Nothing is running. The next part waiting is "${next.name}" \u2014 offer it to t
9305
9595
  function statusTag2(status) {
9306
9596
  switch (status) {
9307
9597
  case "ready":
9308
- return import_picocolors29.default.green("[ready]");
9598
+ return import_picocolors31.default.green("[ready]");
9309
9599
  case "working":
9310
- return import_picocolors29.default.blue("[working]");
9600
+ return import_picocolors31.default.blue("[working]");
9311
9601
  case "checking":
9312
- return import_picocolors29.default.cyan("[checking]");
9602
+ return import_picocolors31.default.cyan("[checking]");
9313
9603
  case "accepted":
9314
- return import_picocolors29.default.green("[accepted]");
9604
+ return import_picocolors31.default.green("[accepted]");
9315
9605
  case "archived":
9316
- return import_picocolors29.default.dim("[archived]");
9606
+ return import_picocolors31.default.dim("[archived]");
9317
9607
  default:
9318
- return import_picocolors29.default.dim("[todo]");
9608
+ return import_picocolors31.default.dim("[todo]");
9319
9609
  }
9320
9610
  }
9321
9611
 
9322
9612
  // src/commands/goal.ts
9323
- var import_picocolors30 = __toESM(require_picocolors(), 1);
9613
+ var import_picocolors32 = __toESM(require_picocolors(), 1);
9324
9614
  var STATUSES3 = ["proposed", "agreed", "working", "delivered", "abandoned"];
9325
9615
  function registerGoal(program3) {
9326
9616
  const goal = program3.command("goal").description("Business goals and the phases that deliver them");
@@ -9332,7 +9622,7 @@ function registerGoal(program3) {
9332
9622
  }) ?? [];
9333
9623
  ok(rows, () => {
9334
9624
  if (!rows.length) {
9335
- line(import_picocolors30.default.dim("No goals yet \u2014 every task here stands on its own."));
9625
+ line(import_picocolors32.default.dim("No goals yet \u2014 every task here stands on its own."));
9336
9626
  return;
9337
9627
  }
9338
9628
  for (const g of rows) line(formatGoal(g));
@@ -9409,10 +9699,10 @@ function registerGoal(program3) {
9409
9699
  }
9410
9700
  });
9411
9701
  ok(row, () => {
9412
- success(`Proposed ${import_picocolors30.default.bold(row?.title ?? "goal")}`);
9702
+ success(`Proposed ${import_picocolors32.default.bold(row?.title ?? "goal")}`);
9413
9703
  printGoal(row);
9414
9704
  line(
9415
- import_picocolors30.default.dim(
9705
+ import_picocolors32.default.dim(
9416
9706
  "\nNothing has been created yet. The owner agrees the shape first."
9417
9707
  )
9418
9708
  );
@@ -9441,7 +9731,7 @@ function registerGoal(program3) {
9441
9731
  ok(
9442
9732
  row,
9443
9733
  () => line(
9444
- row?.recorded ? met === true ? import_picocolors30.default.green("recorded \u2014 met") : met === false ? import_picocolors30.default.yellow("recorded \u2014 not met") : import_picocolors30.default.dim("recorded \u2014 back to unchecked") : import_picocolors30.default.yellow(
9734
+ row?.recorded ? met === true ? import_picocolors32.default.green("recorded \u2014 met") : met === false ? import_picocolors32.default.yellow("recorded \u2014 not met") : import_picocolors32.default.dim("recorded \u2014 back to unchecked") : import_picocolors32.default.yellow(
9445
9735
  "couldn't record it \u2014 check the goal id, the phase name and the criterion id"
9446
9736
  )
9447
9737
  )
@@ -9484,7 +9774,7 @@ function registerGoal(program3) {
9484
9774
  }
9485
9775
  ok({ goalId, phase, filed }, () => {
9486
9776
  success(
9487
- `Filed ${filed.length} ${filed.length === 1 ? "task" : "tasks"} under ${import_picocolors30.default.bold(phase)}`
9777
+ `Filed ${filed.length} ${filed.length === 1 ? "task" : "tasks"} under ${import_picocolors32.default.bold(phase)}`
9488
9778
  );
9489
9779
  });
9490
9780
  })
@@ -9516,42 +9806,42 @@ function registerGoal(program3) {
9516
9806
  function appScope(g) {
9517
9807
  const n = g.appIds?.length ?? 0;
9518
9808
  if (!n) return "";
9519
- return import_picocolors30.default.dim(` ${n} part${n === 1 ? "" : "s"} of the system`);
9809
+ return import_picocolors32.default.dim(` ${n} part${n === 1 ? "" : "s"} of the system`);
9520
9810
  }
9521
9811
  function formatGoal(g) {
9522
- const where = g.currentPhase && g.status !== "delivered" ? import_picocolors30.default.dim(` now: ${g.currentPhase}`) : "";
9523
- const count = g.taskTotal != null ? import_picocolors30.default.dim(` ${g.taskDone}/${g.taskTotal} done`) : "";
9524
- return `${statusTag3(g.status)} ${g.title}${appScope(g)}${where}${count} ${import_picocolors30.default.dim(g.id)}`;
9812
+ const where = g.currentPhase && g.status !== "delivered" ? import_picocolors32.default.dim(` now: ${g.currentPhase}`) : "";
9813
+ const count = g.taskTotal != null ? import_picocolors32.default.dim(` ${g.taskDone}/${g.taskTotal} done`) : "";
9814
+ return `${statusTag3(g.status)} ${g.title}${appScope(g)}${where}${count} ${import_picocolors32.default.dim(g.id)}`;
9525
9815
  }
9526
9816
  function printGoal(g) {
9527
9817
  if (!g) return;
9528
- line(`${import_picocolors30.default.bold(g.title)} ${import_picocolors30.default.dim(g.id)}`);
9818
+ line(`${import_picocolors32.default.bold(g.title)} ${import_picocolors32.default.dim(g.id)}`);
9529
9819
  line(statusTag3(g.status));
9530
9820
  if (g.outcome) line(`
9531
9821
  done means: ${g.outcome}`);
9532
9822
  const progress = g.progress ?? [];
9533
9823
  if (!progress.length) {
9534
- line(import_picocolors30.default.dim("\nNo phases agreed yet."));
9824
+ line(import_picocolors32.default.dim("\nNo phases agreed yet."));
9535
9825
  return;
9536
9826
  }
9537
9827
  line(`
9538
- ${import_picocolors30.default.bold("phases")}`);
9828
+ ${import_picocolors32.default.bold("phases")}`);
9539
9829
  for (const p of progress) {
9540
- const bar2 = p.total > 0 ? `${p.done}/${p.total} done` : import_picocolors30.default.dim("nothing filed yet");
9541
- const mark = p.state === "done" ? import_picocolors30.default.green("done") : p.state === "working" ? import_picocolors30.default.blue("working") : import_picocolors30.default.dim("waiting");
9830
+ const bar2 = p.total > 0 ? `${p.done}/${p.total} done` : import_picocolors32.default.dim("nothing filed yet");
9831
+ const mark = p.state === "done" ? import_picocolors32.default.green("done") : p.state === "working" ? import_picocolors32.default.blue("working") : import_picocolors32.default.dim("waiting");
9542
9832
  line(
9543
- ` ${import_picocolors30.default.dim(String(p.index).padStart(2, "0"))} ${p.name} ${mark} ${import_picocolors30.default.dim(bar2)}`
9833
+ ` ${import_picocolors32.default.dim(String(p.index).padStart(2, "0"))} ${p.name} ${mark} ${import_picocolors32.default.dim(bar2)}`
9544
9834
  );
9545
9835
  for (const c of p.criteria ?? []) {
9546
- const tick = c.met === true ? import_picocolors30.default.green("\u2713") : c.met === false ? import_picocolors30.default.red("\u2717") : import_picocolors30.default.dim("\xB7");
9547
- line(` ${tick} ${c.text} ${import_picocolors30.default.dim(c.id)}`);
9548
- if (c.note) line(import_picocolors30.default.dim(` ${c.note}`));
9836
+ const tick = c.met === true ? import_picocolors32.default.green("\u2713") : c.met === false ? import_picocolors32.default.red("\u2717") : import_picocolors32.default.dim("\xB7");
9837
+ line(` ${tick} ${c.text} ${import_picocolors32.default.dim(c.id)}`);
9838
+ if (c.note) line(import_picocolors32.default.dim(` ${c.note}`));
9549
9839
  }
9550
9840
  }
9551
9841
  const current = progress.find((p) => p.name === g.currentPhase);
9552
9842
  if (current) {
9553
9843
  line(
9554
- import_picocolors30.default.dim(
9844
+ import_picocolors32.default.dim(
9555
9845
  `
9556
9846
  ${current.name} \u2014 ${current.done} of ${current.total} done (phase ${current.index} of ${progress.length}).`
9557
9847
  )
@@ -9561,15 +9851,15 @@ ${current.name} \u2014 ${current.done} of ${current.total} done (phase ${current
9561
9851
  function statusTag3(status) {
9562
9852
  switch (status) {
9563
9853
  case "agreed":
9564
- return import_picocolors30.default.cyan("[agreed]");
9854
+ return import_picocolors32.default.cyan("[agreed]");
9565
9855
  case "working":
9566
- return import_picocolors30.default.blue("[working]");
9856
+ return import_picocolors32.default.blue("[working]");
9567
9857
  case "delivered":
9568
- return import_picocolors30.default.green("[delivered]");
9858
+ return import_picocolors32.default.green("[delivered]");
9569
9859
  case "abandoned":
9570
- return import_picocolors30.default.dim("[abandoned]");
9860
+ return import_picocolors32.default.dim("[abandoned]");
9571
9861
  default:
9572
- return import_picocolors30.default.yellow("[proposed]");
9862
+ return import_picocolors32.default.yellow("[proposed]");
9573
9863
  }
9574
9864
  }
9575
9865
 
@@ -9622,7 +9912,15 @@ var READS = [
9622
9912
  // have `create` subcommands — these write the project's RECORD, not the
9623
9913
  // project. What stops a reviewer editing code is its filesystem mode, and
9624
9914
  // that is untouched.
9625
- "artifact"
9915
+ "artifact",
9916
+ // LEAVING A FACT FOR THE TEAM IS NOT CHANGING THE PROJECT — the same
9917
+ // argument as `artifact` directly above, and it belongs in READS rather than
9918
+ // BUILDS on purpose. The roles that DISCOVER things are the reading ones: a
9919
+ // tester that found the real cause, an analyst that found the actual column
9920
+ // name, a security engineer that found where a key is read from. A shared
9921
+ // memory only builders could write to would be missing most of what is worth
9922
+ // sharing. See the daemon's `team-memory.ts`.
9923
+ "note"
9626
9924
  ];
9627
9925
  var BUILDS = [
9628
9926
  ...READS,
@@ -9642,6 +9940,7 @@ var BUILDS = [
9642
9940
  ];
9643
9941
  var ROLE_VERBS = {
9644
9942
  pm: [...READS, "ask", "app"],
9943
+ // `note` reaches this via READS.
9645
9944
  architect: [...BUILDS, "versions"],
9646
9945
  web: BUILDS,
9647
9946
  api: BUILDS,
@@ -9744,7 +10043,7 @@ function stripLeadingGlobalOptions(argv) {
9744
10043
  }
9745
10044
 
9746
10045
  // src/commands/decision.ts
9747
- var import_picocolors31 = __toESM(require_picocolors(), 1);
10046
+ var import_picocolors33 = __toESM(require_picocolors(), 1);
9748
10047
  function registerDecision(program3) {
9749
10048
  const decision = program3.command("decision").description("Read and record the project's architecture decisions");
9750
10049
  decision.command("list").description("Every decision on record \u2014 read this before changing how something works").option("--limit <n>", "cap the number returned (newest first)").action(
@@ -9757,11 +10056,11 @@ function registerDecision(program3) {
9757
10056
  rows = applyLimit(rows, opts.limit);
9758
10057
  ok(rows, () => {
9759
10058
  if (!rows.length) {
9760
- line(import_picocolors31.default.dim("No decisions recorded yet."));
10059
+ line(import_picocolors33.default.dim("No decisions recorded yet."));
9761
10060
  return;
9762
10061
  }
9763
10062
  for (const r of rows) {
9764
- line(`${import_picocolors31.default.dim(r.id)} ${import_picocolors31.default.dim(shortDate(r.createdAt))} ${r.title}`);
10063
+ line(`${import_picocolors33.default.dim(r.id)} ${import_picocolors33.default.dim(shortDate(r.createdAt))} ${r.title}`);
9765
10064
  line(` ${truncate(r.decision, 100)}`);
9766
10065
  }
9767
10066
  });
@@ -9775,16 +10074,16 @@ function registerDecision(program3) {
9775
10074
  `/v1/projects/${projectId}/architecture-decisions/${args[0]}`
9776
10075
  );
9777
10076
  ok(row, () => {
9778
- line(`${import_picocolors31.default.bold(row.title)} ${import_picocolors31.default.dim(row.id)}`);
9779
- line(import_picocolors31.default.dim(`${row.status} \xB7 ${shortDate(row.createdAt)}`));
10077
+ line(`${import_picocolors33.default.bold(row.title)} ${import_picocolors33.default.dim(row.id)}`);
10078
+ line(import_picocolors33.default.dim(`${row.status} \xB7 ${shortDate(row.createdAt)}`));
9780
10079
  line(`
9781
- ${import_picocolors31.default.bold("Context")}
10080
+ ${import_picocolors33.default.bold("Context")}
9782
10081
  ${row.context}`);
9783
10082
  line(`
9784
- ${import_picocolors31.default.bold("Decision")}
10083
+ ${import_picocolors33.default.bold("Decision")}
9785
10084
  ${row.decision}`);
9786
10085
  if (row.consequences) line(`
9787
- ${import_picocolors31.default.bold("Consequences")}
10086
+ ${import_picocolors33.default.bold("Consequences")}
9788
10087
  ${row.consequences}`);
9789
10088
  });
9790
10089
  })
@@ -9813,7 +10112,7 @@ ${row.consequences}`);
9813
10112
  refId: row?.id,
9814
10113
  output: { decision: row }
9815
10114
  });
9816
- ok(row, () => line(`Recorded decision ${import_picocolors31.default.bold(row?.id ?? "")} \u2014 ${title}`));
10115
+ ok(row, () => line(`Recorded decision ${import_picocolors33.default.bold(row?.id ?? "")} \u2014 ${title}`));
9817
10116
  })
9818
10117
  );
9819
10118
  const requirement = program3.command("requirement").description("Read and record the project's requirements");
@@ -9825,11 +10124,11 @@ ${row.consequences}`);
9825
10124
  rows = applyLimit(rows, opts.limit);
9826
10125
  ok(rows, () => {
9827
10126
  if (!rows.length) {
9828
- line(import_picocolors31.default.dim("No requirements recorded yet."));
10127
+ line(import_picocolors33.default.dim("No requirements recorded yet."));
9829
10128
  return;
9830
10129
  }
9831
10130
  for (const r of rows) {
9832
- line(`${import_picocolors31.default.dim(r.id)} ${r.status.padEnd(9)} ${r.title}`);
10131
+ line(`${import_picocolors33.default.dim(r.id)} ${r.status.padEnd(9)} ${r.title}`);
9833
10132
  }
9834
10133
  });
9835
10134
  })
@@ -9842,8 +10141,8 @@ ${row.consequences}`);
9842
10141
  `/v1/projects/${projectId}/requirements/${args[0]}`
9843
10142
  );
9844
10143
  ok(row, () => {
9845
- line(`${import_picocolors31.default.bold(row.title)} ${import_picocolors31.default.dim(row.id)}`);
9846
- line(import_picocolors31.default.dim(`${row.status} \xB7 ${shortDate(row.createdAt)}`));
10144
+ line(`${import_picocolors33.default.bold(row.title)} ${import_picocolors33.default.dim(row.id)}`);
10145
+ line(import_picocolors33.default.dim(`${row.status} \xB7 ${shortDate(row.createdAt)}`));
9847
10146
  line(`
9848
10147
  ${row.body}`);
9849
10148
  });
@@ -9869,7 +10168,7 @@ ${row.body}`);
9869
10168
  refId: row?.id,
9870
10169
  output: { requirement: row }
9871
10170
  });
9872
- ok(row, () => line(`Recorded requirement ${import_picocolors31.default.bold(row?.id ?? "")} \u2014 ${title}`));
10171
+ ok(row, () => line(`Recorded requirement ${import_picocolors33.default.bold(row?.id ?? "")} \u2014 ${title}`));
9873
10172
  })
9874
10173
  );
9875
10174
  requirement.command("update <id>").description(
@@ -9898,7 +10197,7 @@ ${row.body}`);
9898
10197
  code: "bad_request"
9899
10198
  });
9900
10199
  }
9901
- ok(row, () => line(`Updated requirement ${import_picocolors31.default.bold(row.id)} \u2014 ${row.title} (${row.status})`));
10200
+ ok(row, () => line(`Updated requirement ${import_picocolors33.default.bold(row.id)} \u2014 ${row.title} (${row.status})`));
9902
10201
  })
9903
10202
  );
9904
10203
  }
@@ -9921,7 +10220,7 @@ function shortDate(iso) {
9921
10220
  }
9922
10221
 
9923
10222
  // src/commands/doc.ts
9924
- var import_picocolors32 = __toESM(require_picocolors(), 1);
10223
+ var import_picocolors34 = __toESM(require_picocolors(), 1);
9925
10224
 
9926
10225
  // src/mermaid-fences.ts
9927
10226
  function hasDiagram(code) {
@@ -9966,13 +10265,13 @@ function registerDoc(program3) {
9966
10265
  }) ?? [];
9967
10266
  ok(rows, () => {
9968
10267
  if (!rows.length) {
9969
- line(import_picocolors32.default.dim("No documents yet."));
10268
+ line(import_picocolors34.default.dim("No documents yet."));
9970
10269
  return;
9971
10270
  }
9972
10271
  for (const r of rows) {
9973
- const link = r.workItemId ? import_picocolors32.default.dim(` \u21B3 ${r.workItemId}`) : "";
9974
- const file = r.filePath ? import_picocolors32.default.dim(` ${r.filePath}`) : "";
9975
- line(`${import_picocolors32.default.dim(r.id)} ${r.title}${link}${file}`);
10272
+ const link = r.workItemId ? import_picocolors34.default.dim(` \u21B3 ${r.workItemId}`) : "";
10273
+ const file = r.filePath ? import_picocolors34.default.dim(` ${r.filePath}`) : "";
10274
+ line(`${import_picocolors34.default.dim(r.id)} ${r.title}${link}${file}`);
9976
10275
  }
9977
10276
  });
9978
10277
  })
@@ -9986,17 +10285,17 @@ function registerDoc(program3) {
9986
10285
  );
9987
10286
  if (opts.markdown) {
9988
10287
  ok({ id: row.id, title: row.title, filePath: row.filePath }, () => {
9989
- line(`${import_picocolors32.default.bold(row.title)} ${import_picocolors32.default.dim(row.id)}`);
10288
+ line(`${import_picocolors34.default.bold(row.title)} ${import_picocolors34.default.dim(row.id)}`);
9990
10289
  line(
9991
- row.filePath ? `Read it at ${import_picocolors32.default.bold(row.filePath)} (relative to the project folder).` : import_picocolors32.default.dim("This document has no markdown mirror on disk yet.")
10290
+ row.filePath ? `Read it at ${import_picocolors34.default.bold(row.filePath)} (relative to the project folder).` : import_picocolors34.default.dim("This document has no markdown mirror on disk yet.")
9992
10291
  );
9993
10292
  });
9994
10293
  return;
9995
10294
  }
9996
10295
  ok(row, () => {
9997
- line(`${import_picocolors32.default.bold(row.title)} ${import_picocolors32.default.dim(row.id)}`);
9998
- if (row.workItemId) line(import_picocolors32.default.dim(`linked to work item ${row.workItemId}`));
9999
- if (row.filePath) line(import_picocolors32.default.dim(`markdown mirror: ${row.filePath}`));
10296
+ line(`${import_picocolors34.default.bold(row.title)} ${import_picocolors34.default.dim(row.id)}`);
10297
+ if (row.workItemId) line(import_picocolors34.default.dim(`linked to work item ${row.workItemId}`));
10298
+ if (row.filePath) line(import_picocolors34.default.dim(`markdown mirror: ${row.filePath}`));
10000
10299
  line("");
10001
10300
  line(row.contentJson);
10002
10301
  });
@@ -10025,7 +10324,7 @@ function registerDoc(program3) {
10025
10324
  refId: row?.id,
10026
10325
  output: { document: row }
10027
10326
  });
10028
- ok(row, () => line(`Created document ${import_picocolors32.default.bold(row?.id ?? "")} \u2014 ${title}`));
10327
+ ok(row, () => line(`Created document ${import_picocolors34.default.bold(row?.id ?? "")} \u2014 ${title}`));
10029
10328
  })
10030
10329
  );
10031
10330
  doc.command("diagram <id>").description(
@@ -10051,19 +10350,19 @@ function registerDoc(program3) {
10051
10350
  diagrams: diagrams.map((code) => ({ kind: diagramKind(code), code }))
10052
10351
  };
10053
10352
  ok(payload, () => {
10054
- line(`${import_picocolors32.default.bold(row.title)} ${import_picocolors32.default.dim(row.id)}`);
10353
+ line(`${import_picocolors34.default.bold(row.title)} ${import_picocolors34.default.dim(row.id)}`);
10055
10354
  if (markdown === null) {
10056
10355
  line(
10057
- import_picocolors32.default.dim(
10356
+ import_picocolors34.default.dim(
10058
10357
  row.filePath ? `Could not read ${row.filePath} from this folder.` : "This document has no markdown mirror on disk yet."
10059
10358
  )
10060
10359
  );
10061
10360
  } else if (!diagrams.length) {
10062
- line(import_picocolors32.default.dim("No diagrams in this document."));
10361
+ line(import_picocolors34.default.dim("No diagrams in this document."));
10063
10362
  } else {
10064
10363
  for (const [i, code] of diagrams.entries()) {
10065
10364
  const kind = diagramKind(code) ?? "diagram";
10066
- line(`${import_picocolors32.default.dim(String(i + 1))} ${kind} ${import_picocolors32.default.dim(`${code.split("\n").length} lines`)}`);
10365
+ line(`${import_picocolors34.default.dim(String(i + 1))} ${kind} ${import_picocolors34.default.dim(`${code.split("\n").length} lines`)}`);
10067
10366
  }
10068
10367
  }
10069
10368
  });
@@ -10099,7 +10398,7 @@ function registerDoc(program3) {
10099
10398
  code: "bad_request"
10100
10399
  });
10101
10400
  }
10102
- ok(row, () => line(`Updated document ${import_picocolors32.default.bold(row.id)} \u2014 ${row.title}`));
10401
+ ok(row, () => line(`Updated document ${import_picocolors34.default.bold(row.id)} \u2014 ${row.title}`));
10103
10402
  })
10104
10403
  );
10105
10404
  }
@@ -10113,7 +10412,7 @@ function readMirror(cwd, filePath) {
10113
10412
  }
10114
10413
 
10115
10414
  // src/commands/design.ts
10116
- var import_picocolors33 = __toESM(require_picocolors(), 1);
10415
+ var import_picocolors35 = __toESM(require_picocolors(), 1);
10117
10416
  function registerDesign(program3) {
10118
10417
  const design = program3.command("design").description("Read the project's brand (colours, fonts, logo)");
10119
10418
  design.command("show").description("Show this project's brand \u2014 read it before writing any UI").option("--raw", "print the generated token files verbatim instead of a summary").action(
@@ -10127,11 +10426,11 @@ function registerDesign(program3) {
10127
10426
  if (opts.raw) {
10128
10427
  ok(files, () => {
10129
10428
  if (!files.length) {
10130
- line(import_picocolors33.default.dim("No brand set for this project."));
10429
+ line(import_picocolors35.default.dim("No brand set for this project."));
10131
10430
  return;
10132
10431
  }
10133
10432
  for (const f of files) {
10134
- line(import_picocolors33.default.bold(f.path));
10433
+ line(import_picocolors35.default.bold(f.path));
10135
10434
  line(f.contents);
10136
10435
  line("");
10137
10436
  }
@@ -10148,21 +10447,21 @@ function registerDesign(program3) {
10148
10447
  } : { hasBrand: false, colors: {}, fonts: {}, brand: {}, files: [] };
10149
10448
  ok(summary, () => {
10150
10449
  if (!tokens) {
10151
- line(import_picocolors33.default.dim("No brand set for this project \u2014 choose sensible styling yourself."));
10450
+ line(import_picocolors35.default.dim("No brand set for this project \u2014 choose sensible styling yourself."));
10152
10451
  return;
10153
10452
  }
10154
10453
  for (const [name, value] of Object.entries(tokens.brand)) {
10155
- line(`${import_picocolors33.default.dim(name.padEnd(12))} ${value}`);
10454
+ line(`${import_picocolors35.default.dim(name.padEnd(12))} ${value}`);
10156
10455
  }
10157
10456
  for (const [name, value] of Object.entries(tokens.color)) {
10158
- line(`${import_picocolors33.default.dim(`color.${name}`.padEnd(12))} ${value}`);
10457
+ line(`${import_picocolors35.default.dim(`color.${name}`.padEnd(12))} ${value}`);
10159
10458
  }
10160
10459
  for (const [name, value] of Object.entries(tokens.font)) {
10161
- line(`${import_picocolors33.default.dim(`font.${name}`.padEnd(12))} ${value}`);
10460
+ line(`${import_picocolors35.default.dim(`font.${name}`.padEnd(12))} ${value}`);
10162
10461
  }
10163
10462
  line("");
10164
10463
  line(
10165
- import_picocolors33.default.dim(
10464
+ import_picocolors35.default.dim(
10166
10465
  `Generated into the working tree as ${files.map((f) => f.path).join(", ")} \u2014 wire those in, never edit them.`
10167
10466
  )
10168
10467
  );
@@ -10193,7 +10492,7 @@ function unwrap(group) {
10193
10492
  }
10194
10493
 
10195
10494
  // src/commands/api.ts
10196
- var import_picocolors34 = __toESM(require_picocolors(), 1);
10495
+ var import_picocolors36 = __toESM(require_picocolors(), 1);
10197
10496
  import { readdirSync, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
10198
10497
  import { join as join3, relative, sep } from "path";
10199
10498
 
@@ -10307,10 +10606,10 @@ function registerApi(program3) {
10307
10606
  const appId = requireApp2(opts.app);
10308
10607
  const res = await api(ctx, `/v1/apps/${encodeURIComponent(appId)}/api/requests`);
10309
10608
  ok(res, () => {
10310
- for (const note of res?.notes ?? []) line(import_picocolors34.default.dim(note));
10609
+ for (const note of res?.notes ?? []) line(import_picocolors36.default.dim(note));
10311
10610
  for (const r of res?.requests ?? []) {
10312
10611
  line(
10313
- `${import_picocolors34.default.dim(r.method.padEnd(6))}${r.path}${r.note ? import_picocolors34.default.dim(` ${r.note}`) : ""}`
10612
+ `${import_picocolors36.default.dim(r.method.padEnd(6))}${r.path}${r.note ? import_picocolors36.default.dim(` ${r.note}`) : ""}`
10314
10613
  );
10315
10614
  }
10316
10615
  });
@@ -10344,14 +10643,14 @@ function registerApi(program3) {
10344
10643
  );
10345
10644
  ok(res, () => {
10346
10645
  if (!res?.ok) {
10347
- line(import_picocolors34.default.red(res?.error ?? "The service did not answer."));
10646
+ line(import_picocolors36.default.red(res?.error ?? "The service did not answer."));
10348
10647
  return;
10349
10648
  }
10350
10649
  const code = `${res.status}${res.statusText ? ` ${res.statusText}` : ""}`;
10351
- const colour2 = res.status && res.status < 300 ? import_picocolors34.default.green : res.status && res.status < 500 ? import_picocolors34.default.yellow : import_picocolors34.default.red;
10352
- line(`${colour2(code)} ${import_picocolors34.default.dim(`${res.durationMs}ms ${res.url}`)}`);
10650
+ const colour2 = res.status && res.status < 300 ? import_picocolors36.default.green : res.status && res.status < 500 ? import_picocolors36.default.yellow : import_picocolors36.default.red;
10651
+ line(`${colour2(code)} ${import_picocolors36.default.dim(`${res.durationMs}ms ${res.url}`)}`);
10353
10652
  if (res.body) line(res.body);
10354
- if (res.truncated) line(import_picocolors34.default.dim("(answer truncated)"));
10653
+ if (res.truncated) line(import_picocolors36.default.dim("(answer truncated)"));
10355
10654
  });
10356
10655
  if (!res?.ok) process.exitCode = 1;
10357
10656
  })
@@ -10371,15 +10670,15 @@ function registerApi(program3) {
10371
10670
  for (const r of report.routes) {
10372
10671
  const known = report.missing.some((m) => m.path === r.path);
10373
10672
  line(
10374
- `${known ? import_picocolors34.default.yellow("undocumented") : import_picocolors34.default.green("documented ")} ${r.path}${import_picocolors34.default.dim(` ${r.file}`)}`
10673
+ `${known ? import_picocolors36.default.yellow("undocumented") : import_picocolors36.default.green("documented ")} ${r.path}${import_picocolors36.default.dim(` ${r.file}`)}`
10375
10674
  );
10376
10675
  }
10377
10676
  for (const p of report.stale) {
10378
- line(`${import_picocolors34.default.dim("in spec only ")} ${p}`);
10677
+ line(`${import_picocolors36.default.dim("in spec only ")} ${p}`);
10379
10678
  }
10380
10679
  line("");
10381
10680
  if (report.ok && specFile) success(summary);
10382
- else line(import_picocolors34.default.yellow(summary));
10681
+ else line(import_picocolors36.default.yellow(summary));
10383
10682
  });
10384
10683
  if (opts.check && !report.ok) {
10385
10684
  throw new WorkserError(summary, { code: "bad_request" });
@@ -10450,7 +10749,7 @@ function listRepoFiles(root, maxDepth = 8) {
10450
10749
  }
10451
10750
 
10452
10751
  // src/commands/analysis.ts
10453
- var import_picocolors35 = __toESM(require_picocolors(), 1);
10752
+ var import_picocolors37 = __toESM(require_picocolors(), 1);
10454
10753
  import { readFileSync as readFileSync4 } from "fs";
10455
10754
  function registerAnalysis(program3) {
10456
10755
  const cmd = program3.command("analysis").description("Run Python analysis locally, recorded in the task");
@@ -10460,14 +10759,14 @@ function registerAnalysis(program3) {
10460
10759
  const res = await api(ctx, path);
10461
10760
  ok(res, () => {
10462
10761
  line(
10463
- `${res?.available ? import_picocolors35.default.green("python") : import_picocolors35.default.red("python")} ${res?.version ?? "not found"} ${import_picocolors35.default.dim(res?.python ?? "")}`
10762
+ `${res?.available ? import_picocolors37.default.green("python") : import_picocolors37.default.red("python")} ${res?.version ?? "not found"} ${import_picocolors37.default.dim(res?.python ?? "")}`
10464
10763
  );
10465
10764
  for (const lib of res?.libraries ?? []) {
10466
10765
  line(
10467
- `${lib.present ? import_picocolors35.default.green(lib.name) : import_picocolors35.default.yellow(lib.name)}${import_picocolors35.default.dim(lib.present ? "" : " missing")}`
10766
+ `${lib.present ? import_picocolors37.default.green(lib.name) : import_picocolors37.default.yellow(lib.name)}${import_picocolors37.default.dim(lib.present ? "" : " missing")}`
10468
10767
  );
10469
10768
  }
10470
- for (const note of res?.notes ?? []) line(import_picocolors35.default.dim(note));
10769
+ for (const note of res?.notes ?? []) line(import_picocolors37.default.dim(note));
10471
10770
  });
10472
10771
  if (!res?.available) process.exitCode = 1;
10473
10772
  })
@@ -10489,15 +10788,15 @@ function registerAnalysis(program3) {
10489
10788
  );
10490
10789
  ok(res, () => {
10491
10790
  if (res?.stdout) line(res.stdout.replace(/\n$/, ""));
10492
- if (res?.stderr) line(import_picocolors35.default.dim(res.stderr.replace(/\n$/, "")));
10493
- if (res?.truncated) line(import_picocolors35.default.dim("(output truncated)"));
10791
+ if (res?.stderr) line(import_picocolors37.default.dim(res.stderr.replace(/\n$/, "")));
10792
+ if (res?.truncated) line(import_picocolors37.default.dim("(output truncated)"));
10494
10793
  const took = `${Math.round((res?.durationMs ?? 0) / 100) / 10}s`;
10495
10794
  line(
10496
- res?.ok ? import_picocolors35.default.green(`\u2713 ${res.summary ?? "It finished."}`) + import_picocolors35.default.dim(` ${took}`) : import_picocolors35.default.yellow(res?.summary ?? "It did not finish.") + import_picocolors35.default.dim(` ${took}`)
10795
+ res?.ok ? import_picocolors37.default.green(`\u2713 ${res.summary ?? "It finished."}`) + import_picocolors37.default.dim(` ${took}`) : import_picocolors37.default.yellow(res?.summary ?? "It did not finish.") + import_picocolors37.default.dim(` ${took}`)
10497
10796
  );
10498
10797
  if (res && !res.sandboxed) {
10499
10798
  line(
10500
- import_picocolors35.default.dim(
10799
+ import_picocolors37.default.dim(
10501
10800
  "This platform has no OS sandbox, so the script ran with your own file access."
10502
10801
  )
10503
10802
  );
@@ -10525,7 +10824,7 @@ function readCode(file, inline) {
10525
10824
  }
10526
10825
 
10527
10826
  // src/commands/scan.ts
10528
- var import_picocolors36 = __toESM(require_picocolors(), 1);
10827
+ var import_picocolors38 = __toESM(require_picocolors(), 1);
10529
10828
  import { spawnSync as spawnSync2 } from "child_process";
10530
10829
  import { existsSync as existsSync3, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
10531
10830
  import { join as join4, relative as relative2, sep as sep2 } from "path";
@@ -10809,22 +11108,22 @@ function runPermissions(cwd, findings, checked, skipped) {
10809
11108
  }
10810
11109
  function print2(report, summary) {
10811
11110
  for (const s of report.skipped) {
10812
- line(`${import_picocolors36.default.yellow("not checked")} ${s.check}${import_picocolors36.default.dim(` \u2014 ${s.reason}`)}`);
11111
+ line(`${import_picocolors38.default.yellow("not checked")} ${s.check}${import_picocolors38.default.dim(` \u2014 ${s.reason}`)}`);
10813
11112
  }
10814
11113
  for (const f of report.findings) {
10815
- const where = f.file ? import_picocolors36.default.dim(` ${f.file}${f.line ? `:${f.line}` : ""}`) : "";
11114
+ const where = f.file ? import_picocolors38.default.dim(` ${f.file}${f.line ? `:${f.line}` : ""}`) : "";
10816
11115
  line(`${severityTag(f.severity)} ${f.title}${where}`);
10817
- line(` ${import_picocolors36.default.dim(f.fix)}`);
11116
+ line(` ${import_picocolors38.default.dim(f.fix)}`);
10818
11117
  }
10819
11118
  if (report.findings.length || report.skipped.length) line("");
10820
11119
  if (report.ok && !report.skipped.length) success(summary);
10821
- else if (report.ok) line(import_picocolors36.default.yellow(summary));
10822
- else line(import_picocolors36.default.red(summary));
11120
+ else if (report.ok) line(import_picocolors38.default.yellow(summary));
11121
+ else line(import_picocolors38.default.red(summary));
10823
11122
  }
10824
11123
  function severityTag(severity) {
10825
- if (severity === "high") return import_picocolors36.default.red("serious ");
10826
- if (severity === "medium") return import_picocolors36.default.yellow("worth fixing");
10827
- return import_picocolors36.default.dim("minor ");
11124
+ if (severity === "high") return import_picocolors38.default.red("serious ");
11125
+ if (severity === "medium") return import_picocolors38.default.yellow("worth fixing");
11126
+ return import_picocolors38.default.dim("minor ");
10828
11127
  }
10829
11128
  function git(cwd, args) {
10830
11129
  try {
@@ -10885,7 +11184,7 @@ function listRepoFiles2(root, maxDepth = 8) {
10885
11184
  }
10886
11185
 
10887
11186
  // src/commands/health.ts
10888
- var import_picocolors37 = __toESM(require_picocolors(), 1);
11187
+ var import_picocolors39 = __toESM(require_picocolors(), 1);
10889
11188
  function registerHealth(program3) {
10890
11189
  program3.command("health").description("Check that the published apps in this project are still answering").option("--app <webAppId>", "check one app rather than all of them").action(
10891
11190
  action(async ({ ctx, opts }) => {
@@ -10899,16 +11198,16 @@ function registerHealth(program3) {
10899
11198
  }
10900
11199
  function print3(res) {
10901
11200
  if (!res?.checks?.length) {
10902
- line(import_picocolors37.default.dim(res?.note ?? "Nothing to check."));
11201
+ line(import_picocolors39.default.dim(res?.note ?? "Nothing to check."));
10903
11202
  return;
10904
11203
  }
10905
11204
  for (const c of res.checks) {
10906
- const mark = c.ok ? import_picocolors37.default.green("up ") : import_picocolors37.default.red("down");
10907
- const timing = import_picocolors37.default.dim(`${c.ms}ms`);
10908
- const detail = c.ok ? timing : import_picocolors37.default.dim(`${c.error ?? "no answer"}${c.failures > 1 ? ` \xB7 ${c.failures} in a row` : ""}`);
10909
- line(` ${mark} ${c.appName} ${import_picocolors37.default.dim(`(${c.environment})`)} ${c.url} ${detail}`);
11205
+ const mark = c.ok ? import_picocolors39.default.green("up ") : import_picocolors39.default.red("down");
11206
+ const timing = import_picocolors39.default.dim(`${c.ms}ms`);
11207
+ const detail = c.ok ? timing : import_picocolors39.default.dim(`${c.error ?? "no answer"}${c.failures > 1 ? ` \xB7 ${c.failures} in a row` : ""}`);
11208
+ line(` ${mark} ${c.appName} ${import_picocolors39.default.dim(`(${c.environment})`)} ${c.url} ${detail}`);
10910
11209
  if (c.incidentOpened) {
10911
- line(import_picocolors37.default.yellow(` An incident has been opened on the board for this.`));
11210
+ line(import_picocolors39.default.yellow(` An incident has been opened on the board for this.`));
10912
11211
  }
10913
11212
  }
10914
11213
  const down = res.checks.filter((c) => !c.ok);
@@ -10921,14 +11220,14 @@ function print3(res) {
10921
11220
  }
10922
11221
  const production = down.filter((c) => c.environment === "production").length;
10923
11222
  line(
10924
- import_picocolors37.default.red(
11223
+ import_picocolors39.default.red(
10925
11224
  `${down.length} of ${res.checks.length} not answering` + (production ? ` \u2014 ${production} customer-facing.` : " (preview only).")
10926
11225
  )
10927
11226
  );
10928
11227
  }
10929
11228
 
10930
11229
  // src/commands/urls.ts
10931
- var import_picocolors38 = __toESM(require_picocolors(), 1);
11230
+ var import_picocolors40 = __toESM(require_picocolors(), 1);
10932
11231
  function registerUrls(program3) {
10933
11232
  program3.command("urls").description("The stable preview and production addresses of every app in this project").option("--app <webAppId>", "just one app").action(
10934
11233
  action(async ({ ctx, opts }) => {
@@ -10942,20 +11241,20 @@ function registerUrls(program3) {
10942
11241
  const summary = urlsSummary(rows);
10943
11242
  ok({ rows, summary }, () => {
10944
11243
  for (const row of rows) {
10945
- const label = import_picocolors38.default.dim(row.environment.padEnd(10));
10946
- const value = row.url ? import_picocolors38.default.cyan(row.url) : import_picocolors38.default.dim(row.note ?? "not published");
11244
+ const label = import_picocolors40.default.dim(row.environment.padEnd(10));
11245
+ const value = row.url ? import_picocolors40.default.cyan(row.url) : import_picocolors40.default.dim(row.note ?? "not published");
10947
11246
  line(` ${row.appName.padEnd(22)} ${label} ${value}`);
10948
11247
  }
10949
11248
  line("");
10950
11249
  if (rows.some((r) => r.url)) success(summary);
10951
- else line(import_picocolors38.default.yellow(summary));
11250
+ else line(import_picocolors40.default.yellow(summary));
10952
11251
  });
10953
11252
  })
10954
11253
  );
10955
11254
  }
10956
11255
 
10957
11256
  // src/commands/deployments.ts
10958
- var import_picocolors39 = __toESM(require_picocolors(), 1);
11257
+ var import_picocolors41 = __toESM(require_picocolors(), 1);
10959
11258
  function registerDeployments(program3) {
10960
11259
  const cmd = program3.command("deployments").description("Deployment history, and putting a build in front of customers");
10961
11260
  cmd.command("list").description("What has been built, newest first").option("--app <webAppId>", "just one app (default: every app in the project)").option("--env <environment>", "preview or production").option("--limit <n>", "how many to show", "20").action(
@@ -10973,7 +11272,7 @@ function registerDeployments(program3) {
10973
11272
  ok(res, () => {
10974
11273
  if (!items.length) {
10975
11274
  return line(
10976
- import_picocolors39.default.dim(
11275
+ import_picocolors41.default.dim(
10977
11276
  environment ? `Nothing has been deployed to ${environment} yet.` : "Nothing has been deployed yet. `workser deploy` builds the first one."
10978
11277
  )
10979
11278
  );
@@ -10993,13 +11292,13 @@ function registerDeployments(program3) {
10993
11292
  ).catch(() => null) : null;
10994
11293
  ok({ ...dep, logs }, () => {
10995
11294
  line(formatDeployment(dep));
10996
- if (dep?.error_message) line(import_picocolors39.default.red(` ${dep.error_message}`));
11295
+ if (dep?.error_message) line(import_picocolors41.default.red(` ${dep.error_message}`));
10997
11296
  const events = logs?.events ?? [];
10998
11297
  for (const e of events) {
10999
- line(` ${import_picocolors39.default.dim(String(e.type ?? "log"))} ${e.text ?? ""}`);
11298
+ line(` ${import_picocolors41.default.dim(String(e.type ?? "log"))} ${e.text ?? ""}`);
11000
11299
  }
11001
11300
  if (opts.logs && !events.length) {
11002
- line(import_picocolors39.default.dim(" That build produced no output."));
11301
+ line(import_picocolors41.default.dim(" That build produced no output."));
11003
11302
  }
11004
11303
  });
11005
11304
  })
@@ -11043,16 +11342,16 @@ function printPromoted(res, version) {
11043
11342
  const what = version === null ? "the latest build" : `version ${version}`;
11044
11343
  const url = res.url ?? res.vercel_url;
11045
11344
  success(`Production is being rebuilt from ${what}.`);
11046
- if (url) line(import_picocolors39.default.dim(`It will be at ${url}`));
11047
- line(import_picocolors39.default.dim("`workser deploy status` follows it."));
11345
+ if (url) line(import_picocolors41.default.dim(`It will be at ${url}`));
11346
+ line(import_picocolors41.default.dim("`workser deploy status` follows it."));
11048
11347
  }
11049
11348
  function formatDeployment(d) {
11050
11349
  if (!d) return "";
11051
- const version = d.version !== void 0 ? import_picocolors39.default.yellow(`v${d.version}`) : import_picocolors39.default.dim("v?");
11052
- const env = import_picocolors39.default.dim((d.environment ?? "?").padEnd(10));
11350
+ const version = d.version !== void 0 ? import_picocolors41.default.yellow(`v${d.version}`) : import_picocolors41.default.dim("v?");
11351
+ const env = import_picocolors41.default.dim((d.environment ?? "?").padEnd(10));
11053
11352
  const app = d.webAppName ? `${d.webAppName} ` : "";
11054
- const when = import_picocolors39.default.dim(formatTime2(d.created_at));
11055
- const url = d.url ? " " + import_picocolors39.default.cyan(d.url) : "";
11353
+ const when = import_picocolors41.default.dim(formatTime2(d.created_at));
11354
+ const url = d.url ? " " + import_picocolors41.default.cyan(d.url) : "";
11056
11355
  return `${version} ${env} ${colorStatus(d.status ?? "")} ${app}${when}${url}`;
11057
11356
  }
11058
11357
  function formatTime2(t) {
@@ -11062,7 +11361,7 @@ function formatTime2(t) {
11062
11361
  }
11063
11362
 
11064
11363
  // src/commands/usage.ts
11065
- var import_picocolors40 = __toESM(require_picocolors(), 1);
11364
+ var import_picocolors42 = __toESM(require_picocolors(), 1);
11066
11365
 
11067
11366
  // src/usage.ts
11068
11367
  var NEAR_LIMIT_FRACTION = 0.8;
@@ -11157,7 +11456,7 @@ function registerUsage(program3) {
11157
11456
  function print4(report) {
11158
11457
  const dims = report.dimensions ?? [];
11159
11458
  if (!dims.length) {
11160
- return line(import_picocolors40.default.dim("Nothing to measure for this project yet."));
11459
+ return line(import_picocolors42.default.dim("Nothing to measure for this project yet."));
11161
11460
  }
11162
11461
  const width = Math.max(...dims.map((d) => d.label.length));
11163
11462
  for (const d of dims) {
@@ -11166,23 +11465,23 @@ function print4(report) {
11166
11465
  line("");
11167
11466
  const summary = usageSummary(report);
11168
11467
  const worst = dims.map(usageState);
11169
- if (worst.includes("over")) line(import_picocolors40.default.red(summary));
11468
+ if (worst.includes("over")) line(import_picocolors42.default.red(summary));
11170
11469
  else if (worst.includes("near") || worst.includes("unknown"))
11171
- line(import_picocolors40.default.yellow(summary));
11470
+ line(import_picocolors42.default.yellow(summary));
11172
11471
  else success(summary);
11173
11472
  }
11174
11473
  function gauge(d, _labelWidth) {
11175
11474
  const drawn = bar(d);
11176
- return drawn ? ` ${import_picocolors40.default.dim(drawn)}` : "";
11475
+ return drawn ? ` ${import_picocolors42.default.dim(drawn)}` : "";
11177
11476
  }
11178
11477
  function colour(d) {
11179
11478
  switch (usageState(d)) {
11180
11479
  case "over":
11181
- return d.kind === "hard" ? import_picocolors40.default.red : import_picocolors40.default.yellow;
11480
+ return d.kind === "hard" ? import_picocolors42.default.red : import_picocolors42.default.yellow;
11182
11481
  case "near":
11183
- return import_picocolors40.default.yellow;
11482
+ return import_picocolors42.default.yellow;
11184
11483
  case "unknown":
11185
- return import_picocolors40.default.dim;
11484
+ return import_picocolors42.default.dim;
11186
11485
  default:
11187
11486
  return (s) => s;
11188
11487
  }
@@ -11190,7 +11489,7 @@ function colour(d) {
11190
11489
 
11191
11490
  // src/index.ts
11192
11491
  var pkg = {
11193
- version: true ? "0.6.12" : "0.0.0-dev"
11492
+ version: true ? "0.6.14" : "0.0.0-dev"
11194
11493
  };
11195
11494
  var program2 = new Command();
11196
11495
  program2.name("workser").description(
@@ -11223,6 +11522,7 @@ registerDomain(program2);
11223
11522
  registerOpen(program2);
11224
11523
  registerDoctor(program2);
11225
11524
  registerAgent(program2);
11525
+ registerCloudAgent(program2);
11226
11526
  registerVerify(program2);
11227
11527
  registerApi(program2);
11228
11528
  registerAnalysis(program2);
@@ -11237,6 +11537,7 @@ registerWorkflow(program2);
11237
11537
  registerConnection(program2);
11238
11538
  registerTool(program2);
11239
11539
  registerMemory(program2);
11540
+ registerNote(program2);
11240
11541
  registerBusiness(program2);
11241
11542
  registerArtifact(program2);
11242
11543
  registerImage(program2);