@tablation/crew 0.82.1 → 0.83.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 +42 -0
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1448,6 +1448,7 @@ var HOOK_NAMES = [
1448
1448
  "ports",
1449
1449
  "isolate",
1450
1450
  "handoff",
1451
+ "preview",
1451
1452
  "ci_status",
1452
1453
  "version",
1453
1454
  "bump",
@@ -2316,6 +2317,7 @@ function parseResolved(raw, m, where) {
2316
2317
  areaId: raw.areaId,
2317
2318
  shipsModelId: raw.shipsModelId,
2318
2319
  epicsModelId: raw.epicsModelId,
2320
+ periscopesModelId: raw.periscopesModelId,
2319
2321
  locksModelId: raw.locksModelId,
2320
2322
  recordLinkViewId: raw.recordLinkViewId,
2321
2323
  reposModelId: raw.reposModelId,
@@ -5114,6 +5116,7 @@ var HOOK_PURPOSE = [
5114
5116
  ["isolate", "point this worktree at state of its own; prints KEY=value overrides to export"],
5115
5117
  ["ports", "this worktree's port assignments; prints KEY=value overrides to export"],
5116
5118
  ["handoff", "leave the operator able to open what you built; put its output in your progress comment"],
5119
+ ["preview", "start this worktree's dev server for a viewer, bound to CREW_PREVIEW_HOST, detached; its last stdout line is the URL"],
5117
5120
  ["test", "run the suite"],
5118
5121
  ["build", "build it"],
5119
5122
  ["ci_status", "after you push and before you hand off: exit 0 means CI is green for your branch; on failure fix and push again, and say in your progress comment if it is still pending"]
@@ -5558,6 +5561,19 @@ function validateContract(c) {
5558
5561
  return problems;
5559
5562
  }
5560
5563
  var EVENT_LOG_MISSING = "the Issues table has no event log \u2014 crew writes its audit trail there (CREW-1574). In the app, open the Issues table's Data & lifecycle tab and turn on Event log, then rerun.";
5564
+ var PERISCOPE_COLUMNS = [
5565
+ "ticket_id",
5566
+ "ship_id",
5567
+ "url",
5568
+ "host",
5569
+ "worktree",
5570
+ "branch",
5571
+ "state",
5572
+ "isolated",
5573
+ "started_at",
5574
+ "last_activity_at",
5575
+ "expires_at"
5576
+ ];
5561
5577
 
5562
5578
  // src/agent-log.ts
5563
5579
  import { existsSync as existsSync12, mkdirSync as mkdirSync7, readdirSync as readdirSync5, readFileSync as readFileSync12, rmSync as rmSync7, writeFileSync as writeFileSync8 } from "fs";
@@ -6806,6 +6822,19 @@ var Tracker = class {
6806
6822
  async hasPublicReplyColumn() {
6807
6823
  return (await this.authorshipProbe()).commentPublicReply;
6808
6824
  }
6825
+ /**
6826
+ * Whether this workspace has the optional Periscopes table (EPIC-077), and
6827
+ * which of the columns the crew writes (`PERISCOPE_COLUMNS`) it lacks.
6828
+ * `present: false` is a legitimate shape, never a fault. A table whose
6829
+ * metadata cannot be read reports every column missing, as the authorship
6830
+ * probe reads an unreadable table as "column absent".
6831
+ */
6832
+ async periscopesStatus() {
6833
+ const modelId = this.route.resolved?.periscopesModelId;
6834
+ if (!modelId) return { present: false, missing: [] };
6835
+ const have = await this.columnNames(modelId);
6836
+ return { present: true, modelId, missing: PERISCOPE_COLUMNS.filter((c) => !have.has(c)) };
6837
+ }
6809
6838
  /**
6810
6839
  * The authorship columns this workspace is missing, as `table.column` names
6811
6840
  * for `crew doctor` to report (CREW-1371). Empty on a fully updated install.
@@ -13719,6 +13748,7 @@ function forbiddenDetail(e, route) {
13719
13748
  [r?.shipsModelId, "Ships"],
13720
13749
  [r?.locksModelId, "Locks"],
13721
13750
  [r?.epicsModelId, "Epics"],
13751
+ [r?.periscopesModelId, "Periscopes"],
13722
13752
  [r?.reposModelId, "Repos"]
13723
13753
  ];
13724
13754
  const table2 = modelId ? known.find(([id]) => id && id === modelId)?.[1] ?? `table ${modelId}` : void 0;
@@ -14563,6 +14593,7 @@ async function discover(o) {
14563
14593
  out.reposModelId = find("Repos");
14564
14594
  out.shipsModelId = find("Ships");
14565
14595
  out.epicsModelId = find("Epics");
14596
+ out.periscopesModelId = find("Periscopes");
14566
14597
  out.locksModelId = find("Locks");
14567
14598
  try {
14568
14599
  const views = await get(o, `/views?workspaceId=${ws.id}`);
@@ -14614,6 +14645,7 @@ async function discover(o) {
14614
14645
  shipColumns = new Set((shipsModel.fields ?? []).map((f) => f.columnName));
14615
14646
  } catch {
14616
14647
  }
14648
+ const hostPeriscopes = shipColumns.has("host_periscopes") ? o.ship.hostPeriscopes : void 0;
14617
14649
  let ownerId;
14618
14650
  if (out.meId) {
14619
14651
  if (shipColumns.has("owner_id")) ownerId = out.meId;
@@ -14656,6 +14688,7 @@ async function discover(o) {
14656
14688
  }
14657
14689
  if (writeMachineId) patchBody.machine_id = machineId;
14658
14690
  if ((mine[0].host_passengers ?? false) !== hostPassengers) patchBody.host_passengers = hostPassengers;
14691
+ if (hostPeriscopes !== void 0 && (mine[0].host_periscopes ?? false) !== hostPeriscopes) patchBody.host_periscopes = hostPeriscopes;
14659
14692
  if (sshPublicKey !== void 0 && (mine[0].ssh_public_key ?? "") !== sshPublicKey) {
14660
14693
  patchBody.ssh_public_key = sshPublicKey;
14661
14694
  }
@@ -14663,6 +14696,7 @@ async function discover(o) {
14663
14696
  if (Object.keys(patchBody).length > 0) {
14664
14697
  await patch(o, `/data-models/${out.shipsModelId}/records/${shipRowId}`, patchBody);
14665
14698
  if ("host_passengers" in patchBody) provisioning.push(`synced host_passengers=${hostPassengers} onto Ships row "${o.ship.name}"`);
14699
+ if ("host_periscopes" in patchBody) provisioning.push(`synced host_periscopes=${hostPeriscopes} onto Ships row "${o.ship.name}"`);
14666
14700
  if ("ssh_public_key" in patchBody) provisioning.push(`synced ssh_public_key onto Ships row "${o.ship.name}"`);
14667
14701
  if ("owner_id" in patchBody) provisioning.push(`recorded owner on Ships row "${o.ship.name}"`);
14668
14702
  }
@@ -14671,6 +14705,7 @@ async function discover(o) {
14671
14705
  name: o.ship.name,
14672
14706
  ...o.ship.platform ? { platform: o.ship.platform } : {},
14673
14707
  host_passengers: hostPassengers,
14708
+ ...hostPeriscopes !== void 0 ? { host_periscopes: hostPeriscopes } : {},
14674
14709
  ...sshPublicKey !== void 0 ? { ssh_public_key: sshPublicKey } : {},
14675
14710
  ...ownerId !== void 0 ? { owner_id: ownerId } : {},
14676
14711
  ...writeMachineId ? { machine_id: machineId } : {}
@@ -20561,6 +20596,7 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
20561
20596
  areaId: found.areaId,
20562
20597
  shipsModelId: found.shipsModelId,
20563
20598
  epicsModelId: found.epicsModelId,
20599
+ periscopesModelId: found.periscopesModelId,
20564
20600
  locksModelId: found.locksModelId,
20565
20601
  recordLinkViewId: found.recordLinkViewId,
20566
20602
  reposModelId: found.reposModelId,
@@ -22043,6 +22079,12 @@ routes: ${cfg.routes.map((c) => c.route).join(", ")}
22043
22079
  process.stdout.write(
22044
22080
  await tracker.hasPublicReplyColumn() ? `public replies: Comments.${tracker.contract.comments.publicReply} present \u2014 public reporters are labelled in the digest
22045
22081
  ` : `public replies: Comments.${tracker.contract.comments.publicReply} absent \u2014 no public intake form, nothing to guard
22082
+ `
22083
+ );
22084
+ const periscopes = await tracker.periscopesStatus();
22085
+ process.stdout.write(
22086
+ !periscopes.present ? "periscopes: Periscopes table absent \u2014 this workspace cannot host periscopes\n" : periscopes.missing.length === 0 ? `periscopes: Periscopes table present (${periscopes.modelId})
22087
+ ` : `periscopes: Periscopes table present (${periscopes.modelId}) but missing ${periscopes.missing.join(", ")} \u2014 update the Issues template
22046
22088
  `
22047
22089
  );
22048
22090
  process.stdout.write(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.82.1",
3
+ "version": "0.83.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",