@tablation/crew 0.49.5 → 0.49.6
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/cli.js +39 -8
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4931,6 +4931,8 @@ var Tracker = class {
|
|
|
4931
4931
|
* writes pass its seat's agent key so the event log and rule context see an
|
|
4932
4932
|
* agent, not the ship's human principal.
|
|
4933
4933
|
*/
|
|
4934
|
+
/** Told once per failed best-effort read (`events`); poll.ts points it at the pass's emitter. */
|
|
4935
|
+
onReadFailure;
|
|
4934
4936
|
constructor(route, ship, opts = {}) {
|
|
4935
4937
|
this.route = route;
|
|
4936
4938
|
if (!route.resolved) {
|
|
@@ -5372,10 +5374,16 @@ var Tracker = class {
|
|
|
5372
5374
|
*/
|
|
5373
5375
|
async events(type, limit = 500) {
|
|
5374
5376
|
const filters = encodeURIComponent(JSON.stringify([{ columnName: "event_type", operator: "EQ", value: type }]));
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5377
|
+
let rows;
|
|
5378
|
+
try {
|
|
5379
|
+
const res = await this.eventsFetch("GET", `/events?limit=${limit}&filters=${filters}`);
|
|
5380
|
+
if (res.status === 404) return [];
|
|
5381
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
5382
|
+
rows = await res.json();
|
|
5383
|
+
} catch (err) {
|
|
5384
|
+
this.onReadFailure?.(`reading ${type} events failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
5385
|
+
return [];
|
|
5386
|
+
}
|
|
5379
5387
|
return rows.filter((e) => e.event_type === type).sort((a, b) => Date.parse(b.occurred_at ?? b.created_at ?? "") - Date.parse(a.occurred_at ?? a.created_at ?? ""));
|
|
5380
5388
|
}
|
|
5381
5389
|
/** The newest event of `type` on a ticket, or undefined — e.g. the `pushed` tip QA verifies against. */
|
|
@@ -6455,14 +6463,23 @@ async function runStalledSweep(o, stalled) {
|
|
|
6455
6463
|
async function decideCycle(o) {
|
|
6456
6464
|
const { route, ship, state, emit } = o;
|
|
6457
6465
|
const tracker = new Tracker(route, ship);
|
|
6466
|
+
tracker.onReadFailure = (m) => emit.warn(m);
|
|
6458
6467
|
emit.enter("poll");
|
|
6468
|
+
const optional = async (what, read, fallback) => {
|
|
6469
|
+
try {
|
|
6470
|
+
return await read;
|
|
6471
|
+
} catch (err) {
|
|
6472
|
+
emit.warn(`reading ${what} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6473
|
+
return fallback;
|
|
6474
|
+
}
|
|
6475
|
+
};
|
|
6459
6476
|
const [tickets, comments, crewRows, epicRows, ships, projectModes, stalledEvents] = await Promise.all([
|
|
6460
6477
|
tracker.openTickets(),
|
|
6461
6478
|
tracker.comments(200),
|
|
6462
6479
|
tracker.crewRows(),
|
|
6463
|
-
tracker.epicRows(),
|
|
6464
|
-
tracker.shipRows(),
|
|
6465
|
-
tracker.projectWorkModes(),
|
|
6480
|
+
optional("epics", tracker.epicRows(), []),
|
|
6481
|
+
optional("ships", tracker.shipRows(), []),
|
|
6482
|
+
optional("project work modes", tracker.projectWorkModes(), /* @__PURE__ */ new Map()),
|
|
6466
6483
|
tracker.events("stalled")
|
|
6467
6484
|
]);
|
|
6468
6485
|
const directionEvents = (await Promise.all([...DIRECTION_EVENT_TYPES, "pushed"].map((t) => tracker.events(t)))).flat();
|
|
@@ -12547,7 +12564,18 @@ async function runDaemonLoop(o) {
|
|
|
12547
12564
|
let passes = 0;
|
|
12548
12565
|
for (; ; ) {
|
|
12549
12566
|
if (o.signal?.aborted) return "aborted";
|
|
12550
|
-
|
|
12567
|
+
let result;
|
|
12568
|
+
try {
|
|
12569
|
+
result = await o.runPass();
|
|
12570
|
+
} catch (err) {
|
|
12571
|
+
passes++;
|
|
12572
|
+
o.onPassError?.(err);
|
|
12573
|
+
if (o.maxPasses !== void 0 && passes >= o.maxPasses) return "maxPasses";
|
|
12574
|
+
if (o.signal?.aborted) return "aborted";
|
|
12575
|
+
await sleep(backoff);
|
|
12576
|
+
backoff = Math.min(backoff * 2, ceiling);
|
|
12577
|
+
continue;
|
|
12578
|
+
}
|
|
12551
12579
|
passes++;
|
|
12552
12580
|
if (result.started.length > 0) {
|
|
12553
12581
|
backoff = floor;
|
|
@@ -14473,6 +14501,9 @@ ${changed2.map((c) => ` - ${c}
|
|
|
14473
14501
|
`)
|
|
14474
14502
|
})
|
|
14475
14503
|
}),
|
|
14504
|
+
onPassError: (err) => emit.error(
|
|
14505
|
+
`daemon pass failed, continuing: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
|
|
14506
|
+
),
|
|
14476
14507
|
checkStale: makeStaleChecker(watchPaths, { reloadSentinel: reloadSentinelFor(cfg.ship.stateDir) }),
|
|
14477
14508
|
onPass: (result) => {
|
|
14478
14509
|
if (result.started.length) emit.emit(`daemon pass started: ${result.started.join(", ")}`);
|
package/package.json
CHANGED