@whittlelabs/sifter 0.12.0 → 0.14.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 +60 -2
  2. package/bin.js.map +4 -4
  3. package/package.json +1 -1
package/bin.js CHANGED
@@ -15728,6 +15728,28 @@ var require_self_update = __commonJS({
15728
15728
  }
15729
15729
  });
15730
15730
 
15731
+ // ../../packages/shuttle/dist/lifecycle/decommission.js
15732
+ var require_decommission = __commonJS({
15733
+ "../../packages/shuttle/dist/lifecycle/decommission.js"(exports2) {
15734
+ "use strict";
15735
+ Object.defineProperty(exports2, "__esModule", { value: true });
15736
+ exports2.readDecommissionDirective = readDecommissionDirective;
15737
+ exports2.shutdownOnDecommission = shutdownOnDecommission;
15738
+ function readDecommissionDirective(directives) {
15739
+ const raw = directives.decommission;
15740
+ if (!raw || typeof raw !== "object")
15741
+ return null;
15742
+ return raw;
15743
+ }
15744
+ async function shutdownOnDecommission(opts) {
15745
+ const { productTitle, directive, logger, hooks } = opts;
15746
+ logger.info(`${productTitle} was decommissioned from the product settings page; draining and exiting.`, directive.decommissioned_at ? { decommissionedAt: directive.decommissioned_at } : void 0);
15747
+ await hooks.stopLoop();
15748
+ (hooks.exit ?? ((code) => process.exit(code)))(0);
15749
+ }
15750
+ }
15751
+ });
15752
+
15731
15753
  // ../../packages/loom/dist/runtime/prompt-execution.js
15732
15754
  var require_prompt_execution = __commonJS({
15733
15755
  "../../packages/loom/dist/runtime/prompt-execution.js"(exports2) {
@@ -20725,9 +20747,11 @@ var require_shuttle = __commonJS({
20725
20747
  "use strict";
20726
20748
  Object.defineProperty(exports2, "__esModule", { value: true });
20727
20749
  exports2.Shuttle = void 0;
20750
+ exports2.mergeExecutorDefaults = mergeExecutorDefaults;
20728
20751
  var os_1 = require("os");
20729
20752
  var jobs_1 = require_dist2();
20730
20753
  var self_update_1 = require_self_update();
20754
+ var decommission_1 = require_decommission();
20731
20755
  var loom_1 = require_dist3();
20732
20756
  var chain_1 = require_chain();
20733
20757
  var keep_1 = require_dist4();
@@ -20783,7 +20807,7 @@ var require_shuttle = __commonJS({
20783
20807
  });
20784
20808
  const registry = new registry_1.ExecutorRegistry(this.brand.executorAllowlist);
20785
20809
  registerBuiltInExecutors(registry, this.brand.executorAllowlist);
20786
- const executors = registry.build(this.config.executors);
20810
+ const executors = registry.build(mergeExecutorDefaults(this.brand.executorDefaults, this.config.executors));
20787
20811
  const byStrategy = /* @__PURE__ */ new Map();
20788
20812
  for (const executor of executors) {
20789
20813
  for (const strategy of executor.strategies)
@@ -20893,6 +20917,18 @@ var require_shuttle = __commonJS({
20893
20917
  },
20894
20918
  onJob,
20895
20919
  onDirectives: async (directives) => {
20920
+ const decommission = (0, decommission_1.readDecommissionDirective)(directives);
20921
+ if (decommission) {
20922
+ await (0, decommission_1.shutdownOnDecommission)({
20923
+ productTitle: this.brand.product.title,
20924
+ directive: decommission,
20925
+ logger: subscribeLogger,
20926
+ hooks: {
20927
+ stopLoop: () => this.subscription?.stop() ?? Promise.resolve()
20928
+ }
20929
+ });
20930
+ return;
20931
+ }
20896
20932
  const directive = (0, self_update_1.readUpgradeDirective)(directives, this.brand.product.version, attemptedUpgrades);
20897
20933
  if (!directive)
20898
20934
  return;
@@ -20930,6 +20966,15 @@ var require_shuttle = __commonJS({
20930
20966
  }
20931
20967
  };
20932
20968
  exports2.Shuttle = Shuttle;
20969
+ function mergeExecutorDefaults(defaults, userExecutors) {
20970
+ if (!defaults)
20971
+ return userExecutors;
20972
+ const merged = {};
20973
+ for (const [name, userConfig] of Object.entries(userExecutors)) {
20974
+ merged[name] = { ...defaults[name] ?? {}, ...userConfig };
20975
+ }
20976
+ return merged;
20977
+ }
20933
20978
  function registerBuiltInExecutors(registry, allowlist) {
20934
20979
  const all = [
20935
20980
  ["claude-code", claude_code_1.createClaudeCodeExecutor],
@@ -21504,7 +21549,7 @@ var import_shuttle = __toESM(require_dist5());
21504
21549
  // package.json
21505
21550
  var package_default = {
21506
21551
  name: "@whittlelabs/sifter",
21507
- version: "0.12.0",
21552
+ version: "0.14.0",
21508
21553
  description: "Whittle Sifter: paired AI reviewer for Whittle Sift job pools.",
21509
21554
  bin: {
21510
21555
  "whittle-sifter": "./dist/bin.js"
@@ -21563,6 +21608,19 @@ var sifterBrand = {
21563
21608
  configSearchPaths: ["~/.sifter/sifter.yaml"]
21564
21609
  },
21565
21610
  executorAllowlist: ["claude-code", "anthropic-api", "http-api", "webhook", "custom-script"],
21611
+ // Overlay-fetch origins for the signed standards-content URLs each Sift
21612
+ // tier signs (SIFT_PUBLIC_API_URL). Without these, the executor's SSRF
21613
+ // guard silently skips the standards overlay and every review runs
21614
+ // standards-blind (2026-07-13). User config overrides per key.
21615
+ executorDefaults: {
21616
+ "claude-code": {
21617
+ overlayAllowedHosts: [
21618
+ "https://api.sift.whittlelabs.com",
21619
+ "https://api.sift.stage.whittlelabs.com",
21620
+ "http://localhost:3008"
21621
+ ]
21622
+ }
21623
+ },
21566
21624
  keepRegistration: {
21567
21625
  keepApiUrl: process.env.KEEP_API_URL ?? "https://keep.whittlelabs.com",
21568
21626
  jobsApiUrl: process.env.JOBS_API_URL ?? "https://jobs.whittlelabs.com",