@whittlelabs/sifter 0.3.0 → 0.3.1

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 +33 -16
  2. package/bin.js.map +3 -3
  3. package/package.json +1 -1
package/bin.js CHANGED
@@ -18448,7 +18448,7 @@ var import_shuttle = __toESM(require_dist4());
18448
18448
  // package.json
18449
18449
  var package_default = {
18450
18450
  name: "@whittlelabs/sifter",
18451
- version: "0.3.0",
18451
+ version: "0.3.1",
18452
18452
  description: "Whittle Sifter: paired AI reviewer for Whittle Sift attention pools.",
18453
18453
  bin: {
18454
18454
  "whittle-sifter": "./dist/bin.js"
@@ -18525,12 +18525,19 @@ var sifterBrand = {
18525
18525
  id: "scaffold-run-config",
18526
18526
  phase: "post-pair",
18527
18527
  // The substrate's run command requires a YAML describing pools,
18528
- // executors, and Jobs auth. The web form that minted the pair
18529
- // command bakes the user's product-level choices (executor type,
18530
- // poll interval, caps) into the init flags. This step reads
18531
- // those choices from `ctx.setupOptions` and writes the matching
18532
- // YAML. For `claude-code` we prompt interactively for `cwd` if
18533
- // the user didn't pass `--cwd`; other executors don't need one.
18528
+ // executors, and Jobs auth. The web form that minted the pair command
18529
+ // bakes the user's product-level choices (executor type, poll interval)
18530
+ // into the init flags; this step reads them from `ctx.setupOptions`.
18531
+ //
18532
+ // A re-pair must refresh the pairing-derived fields (Jobs URL, service
18533
+ // identity, pools) even when sifter.yaml already exists otherwise a
18534
+ // stale file silently shadows the new pairing (exactly how a leftover
18535
+ // `localhost:3005` and an old `cwd` once survived a fresh pair). So we
18536
+ // merge rather than skip: rebuild the pairing fields from `pairing`, carry
18537
+ // over the user's executor block (e.g. claude-code `cwd`) and polling
18538
+ // unless a fresh flag overrides them, and log what happened. We only
18539
+ // (re)scaffold an executor block — which may prompt for `cwd` — when there
18540
+ // isn't one to preserve.
18534
18541
  run: async (ctx) => {
18535
18542
  const yamlPath = (0, import_path.join)(ctx.configDir, "sifter.yaml");
18536
18543
  const pairing = new import_shuttle.PairingConfigStore((0, import_path.join)(ctx.configDir, "config.json")).read();
@@ -18539,8 +18546,18 @@ var sifterBrand = {
18539
18546
  "Pairing returned no attention pools. The Sift backend should have provisioned one for this user during pre-pair."
18540
18547
  );
18541
18548
  }
18542
- const executor = ctx.setupOptions.executor ?? "claude-code";
18543
- const executorBlock = await buildExecutorBlock(executor, ctx);
18549
+ let existing = {};
18550
+ try {
18551
+ existing = (0, import_yaml.parse)(await (0, import_promises.readFile)(yamlPath, "utf8")) ?? {};
18552
+ } catch (err) {
18553
+ if (err.code !== "ENOENT") throw err;
18554
+ }
18555
+ const isUpdate = Object.keys(existing).length > 0;
18556
+ const existingExecutors = existing.executors ?? {};
18557
+ const existingPools = Array.isArray(existing.pools) ? existing.pools : [];
18558
+ const priorExecutor = typeof existingPools[0]?.executor === "string" ? existingPools[0].executor : void 0;
18559
+ const executor = ctx.setupOptions.executor ?? priorExecutor ?? "claude-code";
18560
+ const executorBlock = !ctx.setupOptions.executor && existingExecutors[executor] !== void 0 ? existingExecutors[executor] : await buildExecutorBlock(executor, ctx);
18544
18561
  const doc = {
18545
18562
  auth: {
18546
18563
  jobsApiUrl: pairing.jobsApiUrl
@@ -18555,18 +18572,18 @@ var sifterBrand = {
18555
18572
  executor
18556
18573
  })),
18557
18574
  executors: {
18575
+ ...existingExecutors,
18558
18576
  [executor]: executorBlock
18559
18577
  }
18560
18578
  };
18561
- if (ctx.setupOptions.pollIntervalMs !== void 0) {
18562
- doc.polling = { intervalMs: ctx.setupOptions.pollIntervalMs };
18579
+ const pollIntervalMs = ctx.setupOptions.pollIntervalMs ?? existing.polling?.intervalMs;
18580
+ if (pollIntervalMs !== void 0) {
18581
+ doc.polling = { intervalMs: pollIntervalMs };
18563
18582
  }
18564
18583
  await (0, import_promises.mkdir)(ctx.configDir, { recursive: true });
18565
- await (0, import_promises.writeFile)(yamlPath, (0, import_yaml.stringify)(doc), { flag: "wx" }).catch(
18566
- (err) => {
18567
- if (err.code === "EEXIST") return;
18568
- throw err;
18569
- }
18584
+ await (0, import_promises.writeFile)(yamlPath, (0, import_yaml.stringify)(doc));
18585
+ ctx.log(
18586
+ isUpdate ? `Refreshed ${yamlPath} from this pairing (Jobs URL, identity, pools); kept your executor and polling settings.` : `Wrote ${yamlPath}.`
18570
18587
  );
18571
18588
  }
18572
18589
  }