@tablation/crew 0.23.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +58 -1
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -7684,6 +7684,45 @@ Still failing: ${n.detail ?? n.headline}`, memberId);
7684
7684
  }
7685
7685
  }
7686
7686
 
7687
+ // src/projects-cmd.ts
7688
+ async function buildProjectsReport(routes, open) {
7689
+ return Promise.all(routes.map(async (r) => {
7690
+ const areaId = r.areaId ?? null;
7691
+ try {
7692
+ const rows = await open(r.route).projectRowsWithModes();
7693
+ return {
7694
+ route: r.route,
7695
+ areaId,
7696
+ projects: rows.map((p) => ({
7697
+ id: p.id,
7698
+ name: p.name ?? p.id,
7699
+ issuePrefix: p.issue_prefix ?? null,
7700
+ workMode: p.mode,
7701
+ current: p.id === areaId
7702
+ }))
7703
+ };
7704
+ } catch (e) {
7705
+ return { route: r.route, areaId, error: e.message };
7706
+ }
7707
+ }));
7708
+ }
7709
+ function formatProjectsReport(report) {
7710
+ const lines = [];
7711
+ for (const r of report) {
7712
+ lines.push(`route ${r.route}`);
7713
+ if ("error" in r) {
7714
+ lines.push(` error: ${r.error}`);
7715
+ continue;
7716
+ }
7717
+ if (r.projects.length === 0) lines.push(" (no projects readable)");
7718
+ for (const p of r.projects) {
7719
+ lines.push(` ${p.current ? "*" : " "} ${p.name} ${p.issuePrefix ?? "-"} ${p.workMode} ${p.id}`);
7720
+ }
7721
+ }
7722
+ return `${lines.join("\n")}
7723
+ `;
7724
+ }
7725
+
7687
7726
  // src/cli.ts
7688
7727
  import { StaleWriteError as StaleWriteError8 } from "@tablation/client";
7689
7728
 
@@ -10522,6 +10561,7 @@ function usage() {
10522
10561
  crew deploy [route] release now, even with nothing new to merge
10523
10562
  crew watch [route] live view of what the crew is doing
10524
10563
  crew status [route] [--json] paused/running state; --json for a machine reader
10564
+ crew projects [--route R] [--json] the Projects rows each route can read (id, name, prefix, work mode)
10525
10565
  crew doctor [route] [--fix] preflight; --fix enables clean routes and offers crew install
10526
10566
  crew ports [route] which checkout owns which ports, and what is up
10527
10567
  crew reap [route] kill orphaned servers, drop worktrees for closed tickets
@@ -10685,7 +10725,7 @@ if (command === "passenger-sync-daemon") {
10685
10725
  const releaseFleetWide = ["merge", "deploy", "release"].includes(command) && flag("fleet");
10686
10726
  const DAEMON_SUBCOMMANDS = /* @__PURE__ */ new Set(["start", "stop", "status", "restart"]);
10687
10727
  const named = command === "daemon" && DAEMON_SUBCOMMANDS.has(positional[1] ?? "") ? positional[2] : positional[1];
10688
- const fleetWide = command === "inbox" || command === "connect" || command === "agents" || command === "skills" || command === "logbook" || command === "repos" || releaseFleetWide || command === "pause" || command === "resume" || FLEET_CAPABLE.has(command) && !named && cfg.routes.length > 1;
10728
+ const fleetWide = command === "inbox" || command === "connect" || command === "agents" || command === "skills" || command === "logbook" || command === "repos" || command === "projects" || releaseFleetWide || command === "pause" || command === "resume" || FLEET_CAPABLE.has(command) && !named && cfg.routes.length > 1;
10689
10729
  let route;
10690
10730
  try {
10691
10731
  route = fleetWide ? cfg.routes[0] : findRoute(cfg, named);
@@ -13000,6 +13040,23 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
13000
13040
  }
13001
13041
  break;
13002
13042
  }
13043
+ case "projects": {
13044
+ const only = value("route") ?? positional[1];
13045
+ const wanted = only ? cfg.routes.filter((r) => r.route === only) : cfg.routes;
13046
+ if (only && wanted.length === 0) {
13047
+ process.stderr.write(`crew projects: no route "${only}" (have: ${cfg.routes.map((r) => r.route).join(", ")})
13048
+ `);
13049
+ process.exit(2);
13050
+ }
13051
+ const report = await buildProjectsReport(
13052
+ wanted.map((r) => ({ route: r.route, areaId: r.resolved?.areaId })),
13053
+ (name) => new Tracker(wanted.find((r) => r.route === name), cfg.ship)
13054
+ );
13055
+ process.stdout.write(flag("json") ? `${JSON.stringify({ routes: report }, null, 2)}
13056
+ ` : formatProjectsReport(report));
13057
+ if (report.length > 0 && report.every((r) => "error" in r)) process.exitCode = 1;
13058
+ break;
13059
+ }
13003
13060
  case "status": {
13004
13061
  const fairness = state.fairness(route.route);
13005
13062
  const waiting = fairness.waiting();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.23.1",
3
+ "version": "0.24.0",
4
4
  "description": "A standing team of headless agents that picks work off a Tablation board, does it on a machine you control, and reports back.",
5
5
  "type": "module",
6
6
  "license": "MIT",