@tablation/crew 0.54.1 → 0.54.2

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 +21 -4
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6229,7 +6229,16 @@ function operatorTodo(tickets, contract, operatorId) {
6229
6229
  }
6230
6230
 
6231
6231
  // src/digest.ts
6232
- var DIRECTION_EVENT_TYPES = ["conflict_handed_back", "requeued", "bounced", "conflict_escalated", "interrupted"];
6232
+ var DIRECTION_EVENT_TYPES = [
6233
+ "conflict_handed_back",
6234
+ "requeued",
6235
+ "bounced",
6236
+ "conflict_escalated",
6237
+ "interrupted",
6238
+ // The release gate's isolation path hands a ticket back as `build_failed`: it builds alone but not merged with the base.
6239
+ "build_failed"
6240
+ ];
6241
+ var STATUS_EVENT_TYPES = ["gate_red"];
6233
6242
  function displayKey2(t) {
6234
6243
  return t.issue_tag ?? t.issue_id ?? "?";
6235
6244
  }
@@ -6278,10 +6287,18 @@ function pendingDirection(i, ticketId) {
6278
6287
  }
6279
6288
  function directionCell(i, ticketId) {
6280
6289
  const d = pendingDirection(i, ticketId);
6281
- if (!d) return "\u2014";
6290
+ if (!d) return statusCell(i, ticketId);
6282
6291
  const msg = (d.message ?? "").replace(/\s+/g, " ").trim().slice(0, 160);
6283
6292
  return `${d.event_type} ${eventAt(d).slice(0, 16)}Z${msg ? ` \u2014 ${msg}` : ""}`.replace(/\|/g, "/");
6284
6293
  }
6294
+ function statusCell(i, ticketId) {
6295
+ const mine = (i.events ?? []).filter((e) => e.record_id === ticketId);
6296
+ const pushed = mine.filter((e) => e.event_type === "pushed").map(eventAt).sort().pop() ?? "";
6297
+ const s = mine.filter((e) => STATUS_EVENT_TYPES.includes(e.event_type) && eventAt(e) > pushed).sort((a, b) => eventAt(a) < eventAt(b) ? 1 : -1)[0];
6298
+ if (!s) return "\u2014";
6299
+ const msg = (s.message ?? "").replace(/\s+/g, " ").trim().slice(0, 160);
6300
+ return `${s.event_type} ${eventAt(s).slice(0, 16)}Z (status only, nothing to build)${msg ? ` \u2014 ${msg}` : ""}`.replace(/\|/g, "/");
6301
+ }
6285
6302
  function newFromOthers(i, ticketId) {
6286
6303
  const comments = i.comments.filter(
6287
6304
  (c) => c.ticket_id === ticketId && c.team_member_id !== i.me && c.created_at > i.watermark
@@ -6364,7 +6381,7 @@ ${sorted(held).map((t) => `| ${displayKey2(t)} | ${stopOf(t)} |`).join("\n")}
6364
6381
  "## Current queue \u2014 built for you by the poll\n",
6365
6382
  "\nAlready filtered to your lane, and already ordered by the Step 2 rule.\nTicket bodies are deliberately omitted: fetch the full record of only the\nticket you actually pick up. **Do not re-fetch the whole tracker.** This\ndigest comes from the same API call the poll just made, moments ago.\n",
6366
6383
  '\n"new since last poll" counts comments from someone other than you since\nthe poll watermark \u2014 the same signal that woke this run.\n',
6367
- '\n"runner direction" is the newest instruction the crew itself posted to the\nevent log (not Comments) that no push has answered yet: `conflict_handed_back`\n(merge the base into the branch and resolve), `requeued`, `bounced`,\n`conflict_escalated`, `interrupted` (an earlier run on this seat was cut short; its\nuncommitted worktree is yours, resume it). It is direction, same as a comment from a hold: act on it.\n',
6384
+ '\n"runner direction" is the newest instruction the crew itself posted to the\nevent log (not Comments) that no push has answered yet: `conflict_handed_back`\n(merge the base into the branch and resolve), `requeued`, `bounced`,\n`conflict_escalated`, `interrupted` (an earlier run on this seat was cut short; its\nuncommitted worktree is yours, resume it), `build_failed` (the release gate found the branch builds alone but\nnot merged with the current base: merge the base in, fix, push, hand back to QA; the output is quoted). It is\ndirection, same as a comment from a hold: act on it. `gate_red` is status only: the ticket is merged and the\ngate is red, so there is nothing to build on the branch.\n',
6368
6385
  "\n**`repo` is the checkout a ticket's work happens in** \u2014 an area spans\nseveral repositories, so cut the worktree beside THAT directory, not beside\nwhichever one you started in. A ticket marked **NO CHECKOUT** is not yours:\nthis ship has no clone of its repository, and another ship may serve it.\n\n**Use the `branch` and `worktree` columns verbatim.** They are that\nrepository's own naming convention, rendered for THIS ticket \u2014 cut the\nworktree at `<repo>/../<worktree>`, on branch `<branch>`. Do not derive\neither yourself, and prefer these over the Environment section's own worked\nexample if the two ever disagree \u2014 that example is illustrative only,\nrendered before any ticket is picked.\n",
6369
6386
  ...i.workModes && [...i.workModes.modes.values()].some((m) => m !== "automatic") ? ["\n**Manual / hybrid projects.** Some projects on this board are not fully automatic. In a `manual` project no lane touches any ticket, and a ticket with no project is treated the same way, so none appear below. In a `hybrid` project a ticket appears below only when it is assigned to an agent. An `accepted` ticket that is absent for either reason is not yours to claim \u2014 do not go looking for it.\n"] : [],
6370
6387
  "\n### Step 1 \u2014 open tickets that may be yours to act on\n",
@@ -6603,7 +6620,7 @@ async function decideCycle(o) {
6603
6620
  optional("project work modes", tracker.projectWorkModes(), /* @__PURE__ */ new Map()),
6604
6621
  tracker.events("stalled")
6605
6622
  ]);
6606
- const directionEvents = (await Promise.all([...DIRECTION_EVENT_TYPES, "pushed"].map((t) => tracker.events(t)))).flat();
6623
+ const directionEvents = (await Promise.all([...DIRECTION_EVENT_TYPES, ...STATUS_EVENT_TYPES, "pushed"].map((t) => tracker.events(t)))).flat();
6607
6624
  emit.emit(`${tickets.length} open ticket(s), ${comments.length} comment(s)`, {
6608
6625
  data: { tickets: tickets.length, comments: comments.length }
6609
6626
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablation/crew",
3
- "version": "0.54.1",
3
+ "version": "0.54.2",
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",