@whittlelabs/sifter 0.3.0 → 0.3.2
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/bin.js +49 -26
- package/bin.js.map +3 -3
- package/package.json +1 -1
package/bin.js
CHANGED
|
@@ -15370,15 +15370,17 @@ var require_client = __commonJS({
|
|
|
15370
15370
|
throw new Error(`Attention pool not found by name: "${ref.name}"`);
|
|
15371
15371
|
return pool.id;
|
|
15372
15372
|
}
|
|
15373
|
-
// ──
|
|
15374
|
-
|
|
15375
|
-
|
|
15373
|
+
// ── Members ──────────────────────────────────────────────────────
|
|
15374
|
+
// A subscriber joins a pool by registering as a member of it. These
|
|
15375
|
+
// map to the server's `/api/attention-pools/:poolId/members` routes.
|
|
15376
|
+
async listMembers(poolId) {
|
|
15377
|
+
return this.request("GET", `/api/attention-pools/${poolId}/members`);
|
|
15376
15378
|
}
|
|
15377
|
-
async
|
|
15378
|
-
return this.request("POST", `/api/attention-pools/${poolId}/
|
|
15379
|
+
async registerMember(poolId, options) {
|
|
15380
|
+
return this.request("POST", `/api/attention-pools/${poolId}/members`, options);
|
|
15379
15381
|
}
|
|
15380
|
-
async
|
|
15381
|
-
return this.request("PUT", `/api/attention-pools/${poolId}/
|
|
15382
|
+
async updateMember(poolId, memberId, options) {
|
|
15383
|
+
return this.request("PUT", `/api/attention-pools/${poolId}/members/${memberId}`, options);
|
|
15382
15384
|
}
|
|
15383
15385
|
// ── Jobs (producer) ──────────────────────────────────────────────
|
|
15384
15386
|
/**
|
|
@@ -15801,13 +15803,17 @@ var require_subscribe = __commonJS({
|
|
|
15801
15803
|
for (const ref of opts.pools) {
|
|
15802
15804
|
const id = await opts.jobsClient.resolvePoolRef(ref);
|
|
15803
15805
|
resolvedPoolIds.push(id);
|
|
15804
|
-
await opts.jobsClient.
|
|
15806
|
+
await opts.jobsClient.registerMember(id, {
|
|
15805
15807
|
identityType: opts.subscriber.identityType,
|
|
15806
15808
|
identityId: opts.subscriber.identityId,
|
|
15807
15809
|
intelligence: opts.subscriber.intelligence,
|
|
15808
|
-
capabilities: opts.subscriber.capabilities,
|
|
15809
15810
|
...opts.subscriber.displayName !== void 0 ? { displayName: opts.subscriber.displayName } : {},
|
|
15810
|
-
|
|
15811
|
+
// The server has no first-class capabilities column; carry the
|
|
15812
|
+
// advertised set in metadata so it persists on the member row.
|
|
15813
|
+
metadata: {
|
|
15814
|
+
...opts.subscriber.metadata,
|
|
15815
|
+
capabilities: opts.subscriber.capabilities
|
|
15816
|
+
}
|
|
15811
15817
|
});
|
|
15812
15818
|
}
|
|
15813
15819
|
logger.info("subscribe loop started", {
|
|
@@ -18448,7 +18454,7 @@ var import_shuttle = __toESM(require_dist4());
|
|
|
18448
18454
|
// package.json
|
|
18449
18455
|
var package_default = {
|
|
18450
18456
|
name: "@whittlelabs/sifter",
|
|
18451
|
-
version: "0.3.
|
|
18457
|
+
version: "0.3.2",
|
|
18452
18458
|
description: "Whittle Sifter: paired AI reviewer for Whittle Sift attention pools.",
|
|
18453
18459
|
bin: {
|
|
18454
18460
|
"whittle-sifter": "./dist/bin.js"
|
|
@@ -18525,12 +18531,19 @@ var sifterBrand = {
|
|
|
18525
18531
|
id: "scaffold-run-config",
|
|
18526
18532
|
phase: "post-pair",
|
|
18527
18533
|
// The substrate's run command requires a YAML describing pools,
|
|
18528
|
-
// executors, and Jobs auth. The web form that minted the pair
|
|
18529
|
-
//
|
|
18530
|
-
//
|
|
18531
|
-
//
|
|
18532
|
-
//
|
|
18533
|
-
//
|
|
18534
|
+
// executors, and Jobs auth. The web form that minted the pair command
|
|
18535
|
+
// bakes the user's product-level choices (executor type, poll interval)
|
|
18536
|
+
// into the init flags; this step reads them from `ctx.setupOptions`.
|
|
18537
|
+
//
|
|
18538
|
+
// A re-pair must refresh the pairing-derived fields (Jobs URL, service
|
|
18539
|
+
// identity, pools) even when sifter.yaml already exists — otherwise a
|
|
18540
|
+
// stale file silently shadows the new pairing (exactly how a leftover
|
|
18541
|
+
// `localhost:3005` and an old `cwd` once survived a fresh pair). So we
|
|
18542
|
+
// merge rather than skip: rebuild the pairing fields from `pairing`, carry
|
|
18543
|
+
// over the user's executor block (e.g. claude-code `cwd`) and polling
|
|
18544
|
+
// unless a fresh flag overrides them, and log what happened. We only
|
|
18545
|
+
// (re)scaffold an executor block — which may prompt for `cwd` — when there
|
|
18546
|
+
// isn't one to preserve.
|
|
18534
18547
|
run: async (ctx) => {
|
|
18535
18548
|
const yamlPath = (0, import_path.join)(ctx.configDir, "sifter.yaml");
|
|
18536
18549
|
const pairing = new import_shuttle.PairingConfigStore((0, import_path.join)(ctx.configDir, "config.json")).read();
|
|
@@ -18539,8 +18552,18 @@ var sifterBrand = {
|
|
|
18539
18552
|
"Pairing returned no attention pools. The Sift backend should have provisioned one for this user during pre-pair."
|
|
18540
18553
|
);
|
|
18541
18554
|
}
|
|
18542
|
-
|
|
18543
|
-
|
|
18555
|
+
let existing = {};
|
|
18556
|
+
try {
|
|
18557
|
+
existing = (0, import_yaml.parse)(await (0, import_promises.readFile)(yamlPath, "utf8")) ?? {};
|
|
18558
|
+
} catch (err) {
|
|
18559
|
+
if (err.code !== "ENOENT") throw err;
|
|
18560
|
+
}
|
|
18561
|
+
const isUpdate = Object.keys(existing).length > 0;
|
|
18562
|
+
const existingExecutors = existing.executors ?? {};
|
|
18563
|
+
const existingPools = Array.isArray(existing.pools) ? existing.pools : [];
|
|
18564
|
+
const priorExecutor = typeof existingPools[0]?.executor === "string" ? existingPools[0].executor : void 0;
|
|
18565
|
+
const executor = ctx.setupOptions.executor ?? priorExecutor ?? "claude-code";
|
|
18566
|
+
const executorBlock = !ctx.setupOptions.executor && existingExecutors[executor] !== void 0 ? existingExecutors[executor] : await buildExecutorBlock(executor, ctx);
|
|
18544
18567
|
const doc = {
|
|
18545
18568
|
auth: {
|
|
18546
18569
|
jobsApiUrl: pairing.jobsApiUrl
|
|
@@ -18555,18 +18578,18 @@ var sifterBrand = {
|
|
|
18555
18578
|
executor
|
|
18556
18579
|
})),
|
|
18557
18580
|
executors: {
|
|
18581
|
+
...existingExecutors,
|
|
18558
18582
|
[executor]: executorBlock
|
|
18559
18583
|
}
|
|
18560
18584
|
};
|
|
18561
|
-
|
|
18562
|
-
|
|
18585
|
+
const pollIntervalMs = ctx.setupOptions.pollIntervalMs ?? existing.polling?.intervalMs;
|
|
18586
|
+
if (pollIntervalMs !== void 0) {
|
|
18587
|
+
doc.polling = { intervalMs: pollIntervalMs };
|
|
18563
18588
|
}
|
|
18564
18589
|
await (0, import_promises.mkdir)(ctx.configDir, { recursive: true });
|
|
18565
|
-
await (0, import_promises.writeFile)(yamlPath, (0, import_yaml.stringify)(doc)
|
|
18566
|
-
|
|
18567
|
-
|
|
18568
|
-
throw err;
|
|
18569
|
-
}
|
|
18590
|
+
await (0, import_promises.writeFile)(yamlPath, (0, import_yaml.stringify)(doc));
|
|
18591
|
+
ctx.log(
|
|
18592
|
+
isUpdate ? `Refreshed ${yamlPath} from this pairing (Jobs URL, identity, pools); kept your executor and polling settings.` : `Wrote ${yamlPath}.`
|
|
18570
18593
|
);
|
|
18571
18594
|
}
|
|
18572
18595
|
}
|