@whittlelabs/sifter 0.41.2 → 0.42.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 (3) hide show
  1. package/bin.js +281 -14
  2. package/bin.js.map +4 -4
  3. package/package.json +1 -1
package/bin.js CHANGED
@@ -52579,7 +52579,7 @@ var require_ajvProvider_ZaoO9afR = __commonJS({
52579
52579
  };
52580
52580
  exports3.default = formatLimitPlugin;
52581
52581
  }));
52582
- var require_dist8 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports3, module3) => {
52582
+ var require_dist9 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports3, module3) => {
52583
52583
  Object.defineProperty(exports3, "__esModule", { value: true });
52584
52584
  const formats_1 = require_formats();
52585
52585
  const limit_1 = require_limit();
@@ -52614,7 +52614,7 @@ var require_ajvProvider_ZaoO9afR = __commonJS({
52614
52614
  var import_ajv = require_ajv();
52615
52615
  var import__2019 = require__2019();
52616
52616
  var import__2020 = require__2020();
52617
- var import_dist = /* @__PURE__ */ require_chunk.__toESM(require_dist8(), 1);
52617
+ var import_dist = /* @__PURE__ */ require_chunk.__toESM(require_dist9(), 1);
52618
52618
  var addFormats = import_dist.default;
52619
52619
  function createDefaultAjvInstance(engineClass) {
52620
52620
  const ajv = new engineClass({
@@ -68366,6 +68366,28 @@ var require_client2 = __commonJS({
68366
68366
  shift: shift ?? null
68367
68367
  };
68368
68368
  }
68369
+ /**
68370
+ * Open the subscriber's hint stream (`GET /api/my/jobs/stream`, whittlelabs
68371
+ * ADR 0137) and hand back the raw response for @whittlelabs/realtime's
68372
+ * reader. Authenticated as every call, a 401 retried once with a refreshed
68373
+ * token. Naming the shift makes the open stream its check-in.
68374
+ */
68375
+ async openHintStream(options = {}) {
68376
+ const qs = options.shift ? `?shift=${encodeURIComponent(options.shift)}` : "";
68377
+ const url = `${this.baseUrl}/api/my/jobs/stream${qs}`;
68378
+ const headers = async (forceRefresh) => ({
68379
+ ...await this.buildHeaders(forceRefresh),
68380
+ Accept: "text/event-stream",
68381
+ ...options.lastEventId ? { "Last-Event-ID": options.lastEventId } : {}
68382
+ });
68383
+ let response = await fetch(url, { headers: await headers(false), signal: options.signal });
68384
+ if (response.status === 401 && this.getAccessToken) {
68385
+ await response.body?.cancel().catch(() => void 0);
68386
+ response = await fetch(url, { headers: await headers(true), signal: options.signal });
68387
+ }
68388
+ this.onResponse?.(response);
68389
+ return response;
68390
+ }
68369
68391
  // ── HTTP plumbing ────────────────────────────────────────────────
68370
68392
  /**
68371
68393
  * Every call's one reader. `readJsonResponse` refuses to parse a reply that
@@ -68391,12 +68413,181 @@ var require_client2 = __commonJS({
68391
68413
  }
68392
68414
  });
68393
68415
 
68416
+ // ../../packages/realtime-client/dist/reader.js
68417
+ var require_reader = __commonJS({
68418
+ "../../packages/realtime-client/dist/reader.js"(exports2) {
68419
+ "use strict";
68420
+ Object.defineProperty(exports2, "__esModule", { value: true });
68421
+ exports2.StreamSilentError = exports2.RESYNC = void 0;
68422
+ exports2.readEventStream = readEventStream;
68423
+ exports2.connectStream = connectStream;
68424
+ exports2.RESYNC = "resync";
68425
+ async function* readEventStream(body2, options = {}) {
68426
+ const reader = body2.getReader();
68427
+ const decoder = new TextDecoder();
68428
+ let buffer = "";
68429
+ try {
68430
+ for (; ; ) {
68431
+ const { value, done } = await readWithin(reader, options.silenceMs);
68432
+ if (done)
68433
+ return;
68434
+ buffer = (buffer + decoder.decode(value, { stream: true })).replace(/\r\n|\r(?!$)/g, "\n");
68435
+ let boundary;
68436
+ while ((boundary = buffer.indexOf("\n\n")) !== -1) {
68437
+ const block = buffer.slice(0, boundary);
68438
+ buffer = buffer.slice(boundary + 2);
68439
+ const message = parseBlock(block);
68440
+ if (message)
68441
+ yield message;
68442
+ }
68443
+ }
68444
+ } finally {
68445
+ await reader.cancel().catch(() => void 0);
68446
+ }
68447
+ }
68448
+ function parseBlock(block) {
68449
+ let id = null;
68450
+ let event = "message";
68451
+ const data = [];
68452
+ for (const line of block.split("\n")) {
68453
+ if (line === "" || line.startsWith(":"))
68454
+ continue;
68455
+ const colon = line.indexOf(":");
68456
+ const field = colon === -1 ? line : line.slice(0, colon);
68457
+ let value = colon === -1 ? "" : line.slice(colon + 1);
68458
+ if (value.startsWith(" "))
68459
+ value = value.slice(1);
68460
+ if (field === "data")
68461
+ data.push(value);
68462
+ else if (field === "event")
68463
+ event = value;
68464
+ else if (field === "id")
68465
+ id = value;
68466
+ }
68467
+ return data.length === 0 ? null : { id, event, data: data.join("\n") };
68468
+ }
68469
+ async function readWithin(reader, silenceMs) {
68470
+ if (silenceMs === void 0)
68471
+ return reader.read();
68472
+ let timer;
68473
+ try {
68474
+ return await Promise.race([
68475
+ reader.read(),
68476
+ new Promise((_, reject) => {
68477
+ timer = setTimeout(() => reject(new StreamSilentError(silenceMs)), silenceMs);
68478
+ })
68479
+ ]);
68480
+ } finally {
68481
+ clearTimeout(timer);
68482
+ }
68483
+ }
68484
+ var StreamSilentError = class extends Error {
68485
+ constructor(silenceMs) {
68486
+ super(`The stream sent nothing for ${silenceMs}ms`);
68487
+ this.name = "StreamSilentError";
68488
+ }
68489
+ };
68490
+ exports2.StreamSilentError = StreamSilentError;
68491
+ function connectStream(options) {
68492
+ const silenceMs = options.silenceMs ?? 45e3;
68493
+ const minMs = options.retry?.minMs ?? 1e3;
68494
+ const maxMs = options.retry?.maxMs ?? 3e4;
68495
+ const sleep = options.sleep ?? abortableSleep;
68496
+ const random = options.random ?? Math.random;
68497
+ const controller = new AbortController();
68498
+ let lastEventId = null;
68499
+ let failures = 0;
68500
+ let status = null;
68501
+ const report = (next) => {
68502
+ if (next === status)
68503
+ return;
68504
+ status = next;
68505
+ options.onStatus?.(next);
68506
+ };
68507
+ const run2 = async () => {
68508
+ while (!controller.signal.aborted) {
68509
+ try {
68510
+ const res = await options.open({ lastEventId }, controller.signal);
68511
+ if (res.status >= 400 && res.status < 500 && res.status !== 408 && res.status !== 429) {
68512
+ await res.body?.cancel().catch(() => void 0);
68513
+ report("stopped");
68514
+ return;
68515
+ }
68516
+ if (!res.ok || !res.body) {
68517
+ await res.body?.cancel().catch(() => void 0);
68518
+ throw new Error(`stream answered ${res.status}`);
68519
+ }
68520
+ report("live");
68521
+ const openedAt = Date.now();
68522
+ for await (const message of readEventStream(res.body, { silenceMs })) {
68523
+ if (controller.signal.aborted)
68524
+ return;
68525
+ if (message.id !== null)
68526
+ lastEventId = message.id;
68527
+ options.onMessage(message);
68528
+ }
68529
+ if (controller.signal.aborted)
68530
+ return;
68531
+ if (Date.now() - openedAt >= minMs) {
68532
+ failures = 0;
68533
+ continue;
68534
+ }
68535
+ } catch {
68536
+ if (controller.signal.aborted)
68537
+ return;
68538
+ }
68539
+ failures += 1;
68540
+ report("reconnecting");
68541
+ const ceiling = Math.min(maxMs, minMs * 2 ** (failures - 1));
68542
+ await sleep(Math.max(minMs / 2, random() * ceiling), controller.signal).catch(() => void 0);
68543
+ }
68544
+ };
68545
+ void run2();
68546
+ return { close: () => controller.abort() };
68547
+ }
68548
+ function abortableSleep(ms, signal) {
68549
+ return new Promise((resolve, reject) => {
68550
+ if (signal.aborted)
68551
+ return reject(signal.reason);
68552
+ const timer = setTimeout(resolve, ms);
68553
+ signal.addEventListener("abort", () => {
68554
+ clearTimeout(timer);
68555
+ reject(signal.reason);
68556
+ }, { once: true });
68557
+ });
68558
+ }
68559
+ }
68560
+ });
68561
+
68562
+ // ../../packages/realtime-client/dist/index.js
68563
+ var require_dist6 = __commonJS({
68564
+ "../../packages/realtime-client/dist/index.js"(exports2) {
68565
+ "use strict";
68566
+ Object.defineProperty(exports2, "__esModule", { value: true });
68567
+ exports2.StreamSilentError = exports2.RESYNC = exports2.readEventStream = exports2.connectStream = void 0;
68568
+ var reader_1 = require_reader();
68569
+ Object.defineProperty(exports2, "connectStream", { enumerable: true, get: function() {
68570
+ return reader_1.connectStream;
68571
+ } });
68572
+ Object.defineProperty(exports2, "readEventStream", { enumerable: true, get: function() {
68573
+ return reader_1.readEventStream;
68574
+ } });
68575
+ Object.defineProperty(exports2, "RESYNC", { enumerable: true, get: function() {
68576
+ return reader_1.RESYNC;
68577
+ } });
68578
+ Object.defineProperty(exports2, "StreamSilentError", { enumerable: true, get: function() {
68579
+ return reader_1.StreamSilentError;
68580
+ } });
68581
+ }
68582
+ });
68583
+
68394
68584
  // ../../packages/jobs/dist/subscribe.js
68395
68585
  var require_subscribe = __commonJS({
68396
68586
  "../../packages/jobs/dist/subscribe.js"(exports2) {
68397
68587
  "use strict";
68398
68588
  Object.defineProperty(exports2, "__esModule", { value: true });
68399
68589
  exports2.subscribe = subscribe;
68590
+ var realtime_client_1 = require_dist6();
68400
68591
  var response_1 = require_response();
68401
68592
  var NULL_LOGGER = {
68402
68593
  debug: () => {
@@ -68493,6 +68684,8 @@ var require_subscribe = __commonJS({
68493
68684
  return outcome;
68494
68685
  }
68495
68686
  var STOPPED = Symbol("stopped");
68687
+ var STREAMING_POLL_MS = 3e5;
68688
+ var HINT_JITTER_MS = 250;
68496
68689
  var DECLINE_WINDOW = 25;
68497
68690
  var DECLINED_MEMORY = 1e3;
68498
68691
  function subscribe(opts) {
@@ -68503,6 +68696,12 @@ var require_subscribe = __commonJS({
68503
68696
  let stopped = true;
68504
68697
  let session = 0;
68505
68698
  let pollTimer = null;
68699
+ let nextPollAt = Infinity;
68700
+ let polling = false;
68701
+ let pollAgain = false;
68702
+ let hintStream = null;
68703
+ let streamLive = false;
68704
+ let streamSupported = opts.stream ?? true;
68506
68705
  let inflight = 0;
68507
68706
  let resolvedPoolIds = [];
68508
68707
  const controllers = /* @__PURE__ */ new Map();
@@ -68655,13 +68854,50 @@ var require_subscribe = __commonJS({
68655
68854
  maxConcurrency,
68656
68855
  ...shift ? { shiftId: shift.id } : {}
68657
68856
  });
68857
+ openHintStream(mySession);
68658
68858
  schedulePoll(pollIntervalMs);
68659
68859
  }
68860
+ function openHintStream(mySession) {
68861
+ if (!streamSupported || typeof opts.jobsClient.openHintStream !== "function")
68862
+ return;
68863
+ hintStream = (0, realtime_client_1.connectStream)({
68864
+ open: ({ lastEventId }, signal) => opts.jobsClient.openHintStream({ ...shift ? { shift: shift.id } : {}, lastEventId, signal }),
68865
+ onMessage: (message) => {
68866
+ if (stopped || mySession !== session)
68867
+ return;
68868
+ if (message.event === "jobs.available" && (holds.size > 0 || inflight >= maxConcurrency))
68869
+ return;
68870
+ pollSoon(Math.random() * HINT_JITTER_MS);
68871
+ },
68872
+ onStatus: (status) => {
68873
+ if (mySession !== session)
68874
+ return;
68875
+ streamLive = status === "live";
68876
+ if (status === "stopped") {
68877
+ streamSupported = false;
68878
+ hintStream = null;
68879
+ logger.debug?.("Jobs offers no hint stream; polling instead");
68880
+ }
68881
+ if (!streamLive)
68882
+ pollSoon(pollIntervalMs);
68883
+ }
68884
+ });
68885
+ }
68886
+ function closeHintStream() {
68887
+ hintStream?.close();
68888
+ hintStream = null;
68889
+ streamLive = false;
68890
+ }
68660
68891
  async function startShift() {
68661
68892
  if (!shiftsSupported)
68662
68893
  return;
68663
68894
  try {
68895
+ const previous = shift?.id;
68664
68896
  shift = await opts.jobsClient.startShift();
68897
+ if (hintStream && shift.id !== previous) {
68898
+ closeHintStream();
68899
+ openHintStream(session);
68900
+ }
68665
68901
  } catch (err2) {
68666
68902
  if (isFatal(err2) || isUnavailable(err2) || isRateLimited(err2))
68667
68903
  throw err2;
@@ -68717,6 +68953,8 @@ var require_subscribe = __commonJS({
68717
68953
  clearTimeout(pollTimer);
68718
68954
  pollTimer = null;
68719
68955
  }
68956
+ nextPollAt = Infinity;
68957
+ closeHintStream();
68720
68958
  wakeStartup?.();
68721
68959
  }
68722
68960
  async function stop2(options = {}) {
@@ -68751,15 +68989,41 @@ var require_subscribe = __commonJS({
68751
68989
  }
68752
68990
  function schedulePoll(delayMs) {
68753
68991
  const mySession = session;
68754
- const checkInMs = shift ? shift.lapseAfterSeconds * 1e3 / 4 : Infinity;
68992
+ const checkInMs = shift && !streamLive ? shift.lapseAfterSeconds * 1e3 / 4 : Infinity;
68993
+ const ms = Math.min(delayMs, checkInMs);
68994
+ if (pollTimer !== null)
68995
+ clearTimeout(pollTimer);
68996
+ nextPollAt = Date.now() + ms;
68755
68997
  pollTimer = setTimeout(() => {
68998
+ pollTimer = null;
68999
+ nextPollAt = Infinity;
68756
69000
  void poll(mySession);
68757
- }, Math.min(delayMs, checkInMs));
69001
+ }, ms);
69002
+ }
69003
+ function pollSoon(delayMs) {
69004
+ if (stopped)
69005
+ return;
69006
+ if (polling) {
69007
+ pollAgain = true;
69008
+ return;
69009
+ }
69010
+ if (nextPollAt <= Date.now() + delayMs)
69011
+ return;
69012
+ schedulePoll(delayMs);
68758
69013
  }
68759
69014
  async function poll(mySession) {
68760
69015
  if (stopped || mySession !== session)
68761
69016
  return;
68762
- let nextPollMs = pollIntervalMs;
69017
+ polling = true;
69018
+ pollAgain = false;
69019
+ try {
69020
+ await pollOnce(mySession);
69021
+ } finally {
69022
+ polling = false;
69023
+ }
69024
+ }
69025
+ async function pollOnce(mySession) {
69026
+ let nextPollMs = streamLive ? STREAMING_POLL_MS : pollIntervalMs;
68763
69027
  try {
68764
69028
  const paused = holds.size > 0;
68765
69029
  const free = maxConcurrency - inflight;
@@ -68800,6 +69064,8 @@ var require_subscribe = __commonJS({
68800
69064
  inflight++;
68801
69065
  void runOnce(job).finally(() => {
68802
69066
  inflight--;
69067
+ if (streamLive)
69068
+ pollSoon(0);
68803
69069
  });
68804
69070
  }
68805
69071
  }
@@ -68816,8 +69082,9 @@ var require_subscribe = __commonJS({
68816
69082
  logger.error("poll failed", { error: err2 instanceof Error ? err2.message : String(err2) });
68817
69083
  }
68818
69084
  }
68819
- if (!stopped && mySession === session)
68820
- schedulePoll(nextPollMs);
69085
+ if (stopped || mySession !== session)
69086
+ return;
69087
+ schedulePoll(pollAgain ? Math.min(nextPollMs, Math.random() * HINT_JITTER_MS) : nextPollMs);
68821
69088
  }
68822
69089
  async function runOnce(available) {
68823
69090
  let dispatch;
@@ -68944,7 +69211,7 @@ var require_subscribe = __commonJS({
68944
69211
  });
68945
69212
 
68946
69213
  // ../../packages/jobs/dist/index.js
68947
- var require_dist6 = __commonJS({
69214
+ var require_dist7 = __commonJS({
68948
69215
  "../../packages/jobs/dist/index.js"(exports2) {
68949
69216
  "use strict";
68950
69217
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -69300,7 +69567,7 @@ var require_probes = __commonJS({
69300
69567
  var path_1 = __importDefault(require("path"));
69301
69568
  var yaml_1 = require_dist5();
69302
69569
  var keep_1 = require_dist4();
69303
- var jobs_1 = require_dist6();
69570
+ var jobs_1 = require_dist7();
69304
69571
  var scaffold_1 = require_scaffold();
69305
69572
  var loader_1 = require_loader();
69306
69573
  var codex_1 = require_codex();
@@ -74184,7 +74451,7 @@ var require_shuttle = __commonJS({
74184
74451
  exports2.resolveAuth = resolveAuth;
74185
74452
  var os_1 = require("os");
74186
74453
  var path_1 = require("path");
74187
- var jobs_1 = require_dist6();
74454
+ var jobs_1 = require_dist7();
74188
74455
  var self_update_1 = require_self_update();
74189
74456
  var decommission_1 = require_decommission();
74190
74457
  var loom_1 = require_dist();
@@ -75479,7 +75746,7 @@ var require_bundle_assets = __commonJS({
75479
75746
  });
75480
75747
 
75481
75748
  // ../../packages/shuttle/dist/index.js
75482
- var require_dist7 = __commonJS({
75749
+ var require_dist8 = __commonJS({
75483
75750
  "../../packages/shuttle/dist/index.js"(exports2) {
75484
75751
  "use strict";
75485
75752
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -75710,14 +75977,14 @@ var require_dist7 = __commonJS({
75710
75977
  });
75711
75978
 
75712
75979
  // src/bin.ts
75713
- var import_shuttle2 = __toESM(require_dist7());
75980
+ var import_shuttle2 = __toESM(require_dist8());
75714
75981
 
75715
75982
  // src/brand.ts
75716
75983
  var import_path = require("path");
75717
75984
  var import_promises = require("fs/promises");
75718
75985
  var import_yaml = __toESM(require_dist5());
75719
- var import_shuttle = __toESM(require_dist7());
75720
- var buildVersion = true ? "0.41.2" : pkg.version;
75986
+ var import_shuttle = __toESM(require_dist8());
75987
+ var buildVersion = true ? "0.42.0" : pkg.version;
75721
75988
  var AGENT_EXECUTORS = ["claude-code", "codex", "copilot"];
75722
75989
  var sifterBrand = {
75723
75990
  product: {