@whittlelabs/sifter 0.8.0 → 0.10.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 +126 -12
  2. package/bin.js.map +4 -4
  3. package/package.json +1 -1
package/bin.js CHANGED
@@ -3226,7 +3226,9 @@ var require_device_code = __commonJS({
3226
3226
  body: JSON.stringify({
3227
3227
  client_id: opts.oauthClientId,
3228
3228
  device_code: opts.deviceCode,
3229
- display_name: opts.displayName
3229
+ display_name: opts.displayName,
3230
+ hostname: (0, os_1.hostname)(),
3231
+ os_user: (0, os_1.userInfo)().username
3230
3232
  })
3231
3233
  });
3232
3234
  if (response.status === 202) {
@@ -3254,7 +3256,9 @@ var require_device_code = __commonJS({
3254
3256
  body: JSON.stringify({
3255
3257
  client_id: opts.oauthClientId,
3256
3258
  user_code: opts.userCode,
3257
- display_name: opts.displayName
3259
+ display_name: opts.displayName,
3260
+ hostname: (0, os_1.hostname)(),
3261
+ os_user: (0, os_1.userInfo)().username
3258
3262
  })
3259
3263
  });
3260
3264
  (0, version_check_1.checkResponseMinVersion)({
@@ -15446,10 +15450,11 @@ var require_client = __commonJS({
15446
15450
  if (options?.sort)
15447
15451
  params.set("sort", options.sort);
15448
15452
  const qs = params.toString();
15449
- const { jobs, total } = await this.request("GET", `/api/my/jobs${qs ? `?${qs}` : ""}`);
15453
+ const { jobs, total, directives } = await this.request("GET", `/api/my/jobs${qs ? `?${qs}` : ""}`);
15450
15454
  return {
15451
15455
  data: jobs,
15452
- pagination: { total, limit: options?.limit ?? 25, offset: options?.offset ?? 0 }
15456
+ pagination: { total, limit: options?.limit ?? 25, offset: options?.offset ?? 0 },
15457
+ directives: directives ?? null
15453
15458
  };
15454
15459
  }
15455
15460
  // ── HTTP plumbing ────────────────────────────────────────────────
@@ -15543,11 +15548,22 @@ var require_subscribe = __commonJS({
15543
15548
  return;
15544
15549
  }
15545
15550
  try {
15546
- const { data } = await opts.jobsClient.listDispatchableJobs({
15551
+ const { data, directives } = await opts.jobsClient.listDispatchableJobs({
15547
15552
  pools: resolvedPoolIds,
15548
15553
  limit: maxConcurrency - inflight,
15549
15554
  sort: "priority:desc,queued_at:asc"
15550
15555
  });
15556
+ if (directives && Object.keys(directives).length > 0 && opts.onDirectives) {
15557
+ try {
15558
+ await opts.onDirectives(directives);
15559
+ } catch (err) {
15560
+ logger.error("onDirectives handler failed", {
15561
+ error: err instanceof Error ? err.message : String(err)
15562
+ });
15563
+ }
15564
+ }
15565
+ if (stopped)
15566
+ return;
15551
15567
  for (const job of data) {
15552
15568
  if (inflight >= maxConcurrency)
15553
15569
  break;
@@ -15640,6 +15656,78 @@ var require_dist2 = __commonJS({
15640
15656
  }
15641
15657
  });
15642
15658
 
15659
+ // ../../packages/shuttle/dist/lifecycle/self-update.js
15660
+ var require_self_update = __commonJS({
15661
+ "../../packages/shuttle/dist/lifecycle/self-update.js"(exports2) {
15662
+ "use strict";
15663
+ Object.defineProperty(exports2, "__esModule", { value: true });
15664
+ exports2.readUpgradeDirective = readUpgradeDirective;
15665
+ exports2.performSelfUpdate = performSelfUpdate;
15666
+ var child_process_1 = require("child_process");
15667
+ var version_check_1 = require_version_check();
15668
+ function readUpgradeDirective(directives, currentVersion, attemptedVersions) {
15669
+ const raw = directives.upgrade;
15670
+ if (!raw || typeof raw !== "object")
15671
+ return null;
15672
+ const requested = raw.requested_version;
15673
+ if (typeof requested !== "string" || requested.length === 0)
15674
+ return null;
15675
+ if (attemptedVersions.has(requested))
15676
+ return null;
15677
+ if ((0, version_check_1.compareSemver)(currentVersion, requested) >= 0)
15678
+ return null;
15679
+ return {
15680
+ requested_version: requested,
15681
+ requested_at: raw.requested_at
15682
+ };
15683
+ }
15684
+ async function performSelfUpdate(opts) {
15685
+ const { packageName, directive, logger, hooks } = opts;
15686
+ const spec = `${packageName}@${directive.requested_version}`;
15687
+ const install = hooks.install ?? defaultInstall;
15688
+ const respawn = hooks.respawn ?? defaultRespawn;
15689
+ logger.info("upgrade directive received; draining claim loop", {
15690
+ requestedVersion: directive.requested_version
15691
+ });
15692
+ await hooks.stopLoop();
15693
+ try {
15694
+ await install(spec);
15695
+ } catch (err) {
15696
+ logger.error("self-update install failed; resuming on the current version", {
15697
+ packageSpec: spec,
15698
+ error: err instanceof Error ? err.message : String(err)
15699
+ });
15700
+ await hooks.restartLoop();
15701
+ return false;
15702
+ }
15703
+ logger.info("self-update installed; restarting", { packageSpec: spec });
15704
+ respawn();
15705
+ return true;
15706
+ }
15707
+ function defaultInstall(packageSpec) {
15708
+ return new Promise((resolve, reject) => {
15709
+ const child = (0, child_process_1.spawn)("npm", ["install", "-g", packageSpec], {
15710
+ stdio: ["ignore", "pipe", "pipe"]
15711
+ });
15712
+ let output = "";
15713
+ child.stdout.on("data", (chunk) => output += chunk.toString());
15714
+ child.stderr.on("data", (chunk) => output += chunk.toString());
15715
+ child.on("error", reject);
15716
+ child.on("exit", (code) => {
15717
+ if (code === 0)
15718
+ resolve();
15719
+ else
15720
+ reject(new Error(`npm install -g exited ${code}: ${output.trim().slice(-500)}`));
15721
+ });
15722
+ });
15723
+ }
15724
+ function defaultRespawn() {
15725
+ const child = (0, child_process_1.spawn)(process.execPath, process.argv.slice(1), { stdio: "inherit" });
15726
+ child.on("exit", (code) => process.exit(code ?? 0));
15727
+ }
15728
+ }
15729
+ });
15730
+
15643
15731
  // ../../packages/loom/dist/runtime/prompt-execution.js
15644
15732
  var require_prompt_execution = __commonJS({
15645
15733
  "../../packages/loom/dist/runtime/prompt-execution.js"(exports2) {
@@ -20547,7 +20635,9 @@ var require_shuttle = __commonJS({
20547
20635
  "use strict";
20548
20636
  Object.defineProperty(exports2, "__esModule", { value: true });
20549
20637
  exports2.Shuttle = void 0;
20638
+ var os_1 = require("os");
20550
20639
  var jobs_1 = require_dist2();
20640
+ var self_update_1 = require_self_update();
20551
20641
  var loom_1 = require_dist3();
20552
20642
  var chain_1 = require_chain();
20553
20643
  var keep_1 = require_dist4();
@@ -20687,6 +20777,13 @@ var require_shuttle = __commonJS({
20687
20777
  return { status: "completed", outputs };
20688
20778
  };
20689
20779
  const pools = this.config.pools.map((p) => p.id ? { id: p.id } : { name: p.name });
20780
+ const subscribeLogger = {
20781
+ debug: (msg, meta) => logger.debug(msg, meta),
20782
+ info: (msg, meta) => logger.info(msg, meta),
20783
+ warn: (msg, meta) => logger.warn(msg, meta),
20784
+ error: (msg, meta) => logger.error(msg, meta)
20785
+ };
20786
+ const attemptedUpgrades = /* @__PURE__ */ new Set();
20690
20787
  this.subscription = (0, jobs_1.subscribe)({
20691
20788
  jobsClient,
20692
20789
  pools,
@@ -20695,15 +20792,32 @@ var require_shuttle = __commonJS({
20695
20792
  identityId: this.config.agent.identityId,
20696
20793
  intelligence: "digital",
20697
20794
  displayName: this.config.agent.displayName,
20698
- metadata: this.config.agent.metadata
20795
+ // Self-reported build facts, refreshed on every registration.
20796
+ // Products read these off the pool-member row (Sift's settings
20797
+ // page shows the version and offers the upgrade action).
20798
+ metadata: {
20799
+ ...this.config.agent.metadata,
20800
+ client_version: this.brand.product.version,
20801
+ hostname: (0, os_1.hostname)()
20802
+ }
20699
20803
  },
20700
20804
  onJob,
20701
- logger: {
20702
- debug: (msg, meta) => logger.debug(msg, meta),
20703
- info: (msg, meta) => logger.info(msg, meta),
20704
- warn: (msg, meta) => logger.warn(msg, meta),
20705
- error: (msg, meta) => logger.error(msg, meta)
20805
+ onDirectives: async (directives) => {
20806
+ const directive = (0, self_update_1.readUpgradeDirective)(directives, this.brand.product.version, attemptedUpgrades);
20807
+ if (!directive)
20808
+ return;
20809
+ attemptedUpgrades.add(directive.requested_version);
20810
+ await (0, self_update_1.performSelfUpdate)({
20811
+ packageName: this.brand.product.packageName,
20812
+ directive,
20813
+ logger: subscribeLogger,
20814
+ hooks: {
20815
+ stopLoop: () => this.subscription?.stop() ?? Promise.resolve(),
20816
+ restartLoop: () => this.subscription?.start() ?? Promise.resolve()
20817
+ }
20818
+ });
20706
20819
  },
20820
+ logger: subscribeLogger,
20707
20821
  pollIntervalMs: this.config.polling.intervalMs,
20708
20822
  maxConcurrency: this.config.concurrency.maxJobs
20709
20823
  });
@@ -21300,7 +21414,7 @@ var import_shuttle = __toESM(require_dist5());
21300
21414
  // package.json
21301
21415
  var package_default = {
21302
21416
  name: "@whittlelabs/sifter",
21303
- version: "0.8.0",
21417
+ version: "0.10.0",
21304
21418
  description: "Whittle Sifter: paired AI reviewer for Whittle Sift job pools.",
21305
21419
  bin: {
21306
21420
  "whittle-sifter": "./dist/bin.js"