@whittlelabs/sifter 0.5.0 → 0.6.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.
- package/README.md +5 -8
- package/bin.js +29 -22
- package/bin.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
# @whittlelabs/sifter
|
|
2
2
|
|
|
3
|
-
The Whittle Sifter is a paired AI reviewer for [Whittle Sift](https://sift.
|
|
3
|
+
The Whittle Sifter is a paired AI reviewer for [Whittle Sift](https://sift.stage.whittlelabs.com). It runs on your machine, executes review prompts against your own AI credentials (Claude Code, Anthropic API key, etc.), and submits the results back to Sift. Token spend stays on your account.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
`@whittlelabs/sifter` is published to
|
|
7
|
+
`@whittlelabs/sifter` is published publicly to npmjs.com (released by
|
|
8
|
+
`sifter-release.yml` on a version bump):
|
|
8
9
|
|
|
9
10
|
```bash
|
|
10
|
-
# One-time: tell npm where to find @whittlelabs packages
|
|
11
|
-
echo "@whittlelabs:registry=https://npm.pkg.github.com" >> ~/.npmrc
|
|
12
|
-
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> ~/.npmrc
|
|
13
|
-
|
|
14
11
|
npm install -g @whittlelabs/sifter
|
|
15
12
|
```
|
|
16
13
|
|
|
@@ -24,11 +21,11 @@ Visit Sift's **Settings → Pair a Sifter**. Sift will display a pairing code an
|
|
|
24
21
|
whittle-sifter init --pairing-code=ABCD-1234
|
|
25
22
|
```
|
|
26
23
|
|
|
27
|
-
The Sifter defaults to the
|
|
24
|
+
The Sifter defaults to the stage Keep instance (`https://keep.stage.whittlelabs.com`). To pair against a different environment, pass `--keep-url`:
|
|
28
25
|
|
|
29
26
|
```bash
|
|
30
27
|
whittle-sifter init \
|
|
31
|
-
--keep-url=https://keep.
|
|
28
|
+
--keep-url=https://keep.test.whittlelabs.com \
|
|
32
29
|
--pairing-code=ABCD-1234
|
|
33
30
|
```
|
|
34
31
|
|
package/bin.js
CHANGED
|
@@ -15340,7 +15340,8 @@ var require_client = __commonJS({
|
|
|
15340
15340
|
if (filters?.name)
|
|
15341
15341
|
params.set("name", filters.name);
|
|
15342
15342
|
const qs = params.toString();
|
|
15343
|
-
|
|
15343
|
+
const { pools } = await this.request("GET", `/api/job-pools${qs ? `?${qs}` : ""}`);
|
|
15344
|
+
return pools;
|
|
15344
15345
|
}
|
|
15345
15346
|
async getJobPool(poolId) {
|
|
15346
15347
|
return this.request("GET", `/api/job-pools/${poolId}`);
|
|
@@ -15362,7 +15363,8 @@ var require_client = __commonJS({
|
|
|
15362
15363
|
// A subscriber joins a pool by registering as a member of it. These
|
|
15363
15364
|
// map to the server's `/api/job-pools/:poolId/members` routes.
|
|
15364
15365
|
async listMembers(poolId) {
|
|
15365
|
-
|
|
15366
|
+
const { members } = await this.request("GET", `/api/job-pools/${poolId}/members`);
|
|
15367
|
+
return members;
|
|
15366
15368
|
}
|
|
15367
15369
|
async registerMember(poolId, options) {
|
|
15368
15370
|
return this.request("POST", `/api/job-pools/${poolId}/members`, options);
|
|
@@ -15401,7 +15403,15 @@ var require_client = __commonJS({
|
|
|
15401
15403
|
}
|
|
15402
15404
|
// ── Outputs ──────────────────────────────────────────────────────
|
|
15403
15405
|
async listOutputs(jobId) {
|
|
15404
|
-
|
|
15406
|
+
const all = [];
|
|
15407
|
+
const pageSize = 100;
|
|
15408
|
+
for (let offset = 0; ; offset += pageSize) {
|
|
15409
|
+
const { outputs, total } = await this.request("GET", `/api/jobs/${jobId}/output?limit=${pageSize}&offset=${offset}`);
|
|
15410
|
+
all.push(...outputs);
|
|
15411
|
+
if (outputs.length === 0 || all.length >= total)
|
|
15412
|
+
break;
|
|
15413
|
+
}
|
|
15414
|
+
return all;
|
|
15405
15415
|
}
|
|
15406
15416
|
async createOutput(jobId, options) {
|
|
15407
15417
|
return this.request("POST", `/api/jobs/${jobId}/output`, options);
|
|
@@ -15436,7 +15446,11 @@ var require_client = __commonJS({
|
|
|
15436
15446
|
if (options?.sort)
|
|
15437
15447
|
params.set("sort", options.sort);
|
|
15438
15448
|
const qs = params.toString();
|
|
15439
|
-
|
|
15449
|
+
const { jobs, total } = await this.request("GET", `/api/my/jobs${qs ? `?${qs}` : ""}`);
|
|
15450
|
+
return {
|
|
15451
|
+
data: jobs,
|
|
15452
|
+
pagination: { total, limit: options?.limit ?? 25, offset: options?.offset ?? 0 }
|
|
15453
|
+
};
|
|
15440
15454
|
}
|
|
15441
15455
|
// ── HTTP plumbing ────────────────────────────────────────────────
|
|
15442
15456
|
async request(method, path, body) {
|
|
@@ -15452,19 +15466,6 @@ var require_client = __commonJS({
|
|
|
15452
15466
|
}
|
|
15453
15467
|
return json.data;
|
|
15454
15468
|
}
|
|
15455
|
-
async requestPaginated(method, path) {
|
|
15456
|
-
const url = `${this.baseUrl}${path}`;
|
|
15457
|
-
const response = await this.fetchWithAuthRetry(method, url);
|
|
15458
|
-
const json = await response.json();
|
|
15459
|
-
if (!response.ok || !json.success) {
|
|
15460
|
-
const errorMessage = json.error?.message ?? `Request failed with status ${response.status}`;
|
|
15461
|
-
const error = new Error(errorMessage);
|
|
15462
|
-
error.code = json.error?.code;
|
|
15463
|
-
error.statusCode = response.status;
|
|
15464
|
-
throw error;
|
|
15465
|
-
}
|
|
15466
|
-
return { data: json.data, pagination: json.pagination };
|
|
15467
|
-
}
|
|
15468
15469
|
};
|
|
15469
15470
|
exports2.JobsClient = JobsClient;
|
|
15470
15471
|
}
|
|
@@ -17985,7 +17986,10 @@ var require_canonicalise = __commonJS({
|
|
|
17985
17986
|
transitionResolver: options.transition.resolver,
|
|
17986
17987
|
transitionContext: extractTransitionContext(options.transition)
|
|
17987
17988
|
} : {},
|
|
17988
|
-
...options.qualityGates !== void 0 ? { qualityGates: serialiseQualityGates(options.qualityGates) } : {}
|
|
17989
|
+
...options.qualityGates !== void 0 ? { qualityGates: serialiseQualityGates(options.qualityGates) } : {},
|
|
17990
|
+
// Normalise the emit spec: `true` → emit-all (`{}`); object → as-is;
|
|
17991
|
+
// `false`/omitted → not emitted (field absent).
|
|
17992
|
+
...options.emitOutput === true ? { emitOutput: {} } : options.emitOutput && typeof options.emitOutput === "object" ? { emitOutput: options.emitOutput } : {}
|
|
17989
17993
|
};
|
|
17990
17994
|
}
|
|
17991
17995
|
function interpolate(value, env) {
|
|
@@ -18310,7 +18314,8 @@ var require_client2 = __commonJS({
|
|
|
18310
18314
|
}
|
|
18311
18315
|
// ── Organizations ───────────────────────────────────────────────
|
|
18312
18316
|
async listOrganizations() {
|
|
18313
|
-
|
|
18317
|
+
const { organizations } = await this.request("GET", "/api/organizations");
|
|
18318
|
+
return organizations;
|
|
18314
18319
|
}
|
|
18315
18320
|
async getOrganization(orgId) {
|
|
18316
18321
|
return this.request("GET", `/api/organizations/${orgId}`);
|
|
@@ -18732,6 +18737,7 @@ var require_claude_code = __commonJS({
|
|
|
18732
18737
|
var child_process_1 = require("child_process");
|
|
18733
18738
|
var loom_1 = require_dist3();
|
|
18734
18739
|
var validate_output_1 = require_validate_output();
|
|
18740
|
+
var apply_1 = require_apply();
|
|
18735
18741
|
var DEFAULT_TIMEOUT = 6e5;
|
|
18736
18742
|
var ClaudeCodeExecutor = class {
|
|
18737
18743
|
capability;
|
|
@@ -18823,10 +18829,11 @@ var require_claude_code = __commonJS({
|
|
|
18823
18829
|
}
|
|
18824
18830
|
};
|
|
18825
18831
|
function createClaudeCodeExecutor(config, capabilityId = "claude-code") {
|
|
18826
|
-
const
|
|
18827
|
-
if (typeof
|
|
18832
|
+
const cwdRaw = config.cwd;
|
|
18833
|
+
if (typeof cwdRaw !== "string" || cwdRaw.length === 0) {
|
|
18828
18834
|
throw new Error('ClaudeCodeExecutor requires a non-empty "cwd" string in config');
|
|
18829
18835
|
}
|
|
18836
|
+
const cwd = (0, apply_1.expandHome)(cwdRaw);
|
|
18830
18837
|
const validated = { cwd, capabilityId };
|
|
18831
18838
|
if (config.model !== void 0) {
|
|
18832
18839
|
if (typeof config.model !== "string")
|
|
@@ -20710,7 +20717,7 @@ var import_shuttle = __toESM(require_dist5());
|
|
|
20710
20717
|
// package.json
|
|
20711
20718
|
var package_default = {
|
|
20712
20719
|
name: "@whittlelabs/sifter",
|
|
20713
|
-
version: "0.
|
|
20720
|
+
version: "0.6.0",
|
|
20714
20721
|
description: "Whittle Sifter: paired AI reviewer for Whittle Sift job pools.",
|
|
20715
20722
|
bin: {
|
|
20716
20723
|
"whittle-sifter": "./dist/bin.js"
|