@whittlelabs/sifter 0.30.14 → 0.30.16
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 +19 -1
- package/bin.js +42 -13
- package/bin.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ It needs three things on the machine first:
|
|
|
12
12
|
|---|---|---|
|
|
13
13
|
| Node.js | 20 or newer | [nodejs.org](https://nodejs.org), or a version manager such as [nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm) |
|
|
14
14
|
| git | 2.20 or newer | macOS: `xcode-select --install` (or Homebrew). Linux and WSL: your package manager, e.g. `sudo apt install git` |
|
|
15
|
-
| Claude Code | 2.0 or newer, signed in | `npm install -g @anthropic-ai/claude-code`, then run `claude` once and sign in |
|
|
15
|
+
| Claude Code | 2.0.45 or newer, signed in | `npm install -g @anthropic-ai/claude-code`, then run `claude` once and sign in |
|
|
16
16
|
|
|
17
17
|
On a Mac without the Command Line Tools, `/usr/bin/git` is only a placeholder that asks for them. The Sifter treats that as git not working, so install them first.
|
|
18
18
|
|
|
@@ -77,6 +77,24 @@ whittle-sifter run
|
|
|
77
77
|
|
|
78
78
|
The Sifter subscribes to your job pool and waits for review jobs. Leave it running in a terminal or wrap it in your favorite process supervisor.
|
|
79
79
|
|
|
80
|
+
### What a review can do
|
|
81
|
+
|
|
82
|
+
A review checks out the pull request and runs Claude Code on it. The pull request is someone else's code, so the review is held to reading:
|
|
83
|
+
|
|
84
|
+
- It is offered three tools, Read, Grep and Glob, and nothing else: no shell, no edits, no network tools, no subagents.
|
|
85
|
+
- It loads no Claude Code settings file, neither the repository's nor yours. Your allow rules, permission mode, hooks and plugins do not apply to reviews, and no MCP server starts.
|
|
86
|
+
|
|
87
|
+
Your login still works: Claude Code keeps it in your keychain or credentials file, or reads `ANTHROPIC_API_KEY`. If instead your login or provider is configured in your Claude Code settings (an `apiKeyHelper`, or an `env` block naming Bedrock, Vertex or a custom base URL), reviews will fail as signed out. Tell the Sifter to load your user settings in its `sifter.yaml` (`~/.sifter/sifter.yaml`, or `~/.sifter/<profile>/sifter.yaml` for a named profile):
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
executors:
|
|
91
|
+
claude-code:
|
|
92
|
+
type: claude-code
|
|
93
|
+
claudeSettings: user
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
With it, your allow rules apply to reviews too, so a review can read whatever they let it read. The three tools, the default permission mode and the hooks staying off still hold.
|
|
97
|
+
|
|
80
98
|
### When something goes away
|
|
81
99
|
|
|
82
100
|
A running Sifter deals with Sift or `claude` going away on its own, and says what it is doing:
|
package/bin.js
CHANGED
|
@@ -10047,8 +10047,21 @@ var require_claude_code = __commonJS({
|
|
|
10047
10047
|
var progress_1 = require_progress();
|
|
10048
10048
|
var apply_1 = require_apply();
|
|
10049
10049
|
var DEFAULT_TIMEOUT = 6e5;
|
|
10050
|
-
var
|
|
10051
|
-
|
|
10050
|
+
var REVIEW_TOOLS = ["Read", "Grep", "Glob"];
|
|
10051
|
+
function reviewRunArgs(settingSources) {
|
|
10052
|
+
return [
|
|
10053
|
+
"--setting-sources",
|
|
10054
|
+
settingSources,
|
|
10055
|
+
"--strict-mcp-config",
|
|
10056
|
+
"--tools",
|
|
10057
|
+
REVIEW_TOOLS.join(","),
|
|
10058
|
+
"--permission-mode",
|
|
10059
|
+
"default",
|
|
10060
|
+
"--settings",
|
|
10061
|
+
JSON.stringify({ disableAllHooks: true })
|
|
10062
|
+
];
|
|
10063
|
+
}
|
|
10064
|
+
var RETIRED_READ_TOOLS = ["LS"];
|
|
10052
10065
|
var HOSTED_ENV_PASSTHROUGH = [
|
|
10053
10066
|
"PATH",
|
|
10054
10067
|
"HOME",
|
|
@@ -10080,7 +10093,7 @@ var require_claude_code = __commonJS({
|
|
|
10080
10093
|
var READINESS_TIMEOUT_MS = 12e4;
|
|
10081
10094
|
var STDERR_LIMIT = 4e3;
|
|
10082
10095
|
var INSTALL_REMEDY = "install Claude Code (npm install -g @anthropic-ai/claude-code) where this process can find it on PATH";
|
|
10083
|
-
var LOGIN_REMEDY = "run `claude` once and sign in (or set a valid ANTHROPIC_API_KEY)";
|
|
10096
|
+
var LOGIN_REMEDY = "run `claude` once and sign in (or set a valid ANTHROPIC_API_KEY); if your login or provider is configured in Claude Code settings (apiKeyHelper, or an env block), set `claudeSettings: user` on the claude-code executor, since a review loads no settings file without it";
|
|
10084
10097
|
var LIMIT_REMEDY = "wait for the plan's usage limit to reset, or raise it";
|
|
10085
10098
|
var SIGNED_OUT = /invalid api key|please run \/login|not (?:logged|signed) in|oauth token (?:has )?expired|authentication_error|invalid x-api-key/i;
|
|
10086
10099
|
var OUT_OF_USAGE = /usage limit|credit balance is too low|out of (?:extra )?usage|hit your (?:\w+ )?(?:usage |spend )?limit|5-hour limit/i;
|
|
@@ -10330,8 +10343,12 @@ var require_claude_code = __commonJS({
|
|
|
10330
10343
|
const outputLabel = spec.outputLabel;
|
|
10331
10344
|
const model = modelOverride ?? this.config.model;
|
|
10332
10345
|
const allowedTools = local ? this.config.allowedTools : checkoutScopedTools(this.config.allowedTools);
|
|
10346
|
+
if (!local && this.config.claudeSettings === "user") {
|
|
10347
|
+
throw new Error("claude-code: `claudeSettings: user` is for an installed Sifter whose login lives in Claude Code settings; a hosted run authenticates with the key it is handed and loads no settings");
|
|
10348
|
+
}
|
|
10349
|
+
const settingSources = local && this.config.claudeSettings === "user" ? "user" : "";
|
|
10333
10350
|
return new Promise((resolve, reject) => {
|
|
10334
|
-
const args = ["--print", "--output-format", "stream-json", "--verbose", ...
|
|
10351
|
+
const args = ["--print", "--output-format", "stream-json", "--verbose", ...reviewRunArgs(settingSources)];
|
|
10335
10352
|
if (resumeSessionId)
|
|
10336
10353
|
args.push("--resume", resumeSessionId);
|
|
10337
10354
|
if (spec.outputSchema && typeof spec.outputSchema === "object" && Object.keys(spec.outputSchema).length > 0) {
|
|
@@ -10531,6 +10548,12 @@ var require_claude_code = __commonJS({
|
|
|
10531
10548
|
}
|
|
10532
10549
|
validated.keepTranscripts = config.keepTranscripts;
|
|
10533
10550
|
}
|
|
10551
|
+
if (config.claudeSettings !== void 0) {
|
|
10552
|
+
if (config.claudeSettings !== "user") {
|
|
10553
|
+
throw new Error('"claudeSettings" may only be "user" (leave it unset to load no settings file)');
|
|
10554
|
+
}
|
|
10555
|
+
validated.claudeSettings = "user";
|
|
10556
|
+
}
|
|
10534
10557
|
if (config.overlayAllowedHosts !== void 0) {
|
|
10535
10558
|
if (!Array.isArray(config.overlayAllowedHosts) || !config.overlayAllowedHosts.every((h) => typeof h === "string")) {
|
|
10536
10559
|
throw new Error('"overlayAllowedHosts" must be an array of strings');
|
|
@@ -10542,13 +10565,17 @@ var require_claude_code = __commonJS({
|
|
|
10542
10565
|
function checkoutScopedTools(tools) {
|
|
10543
10566
|
if (!tools)
|
|
10544
10567
|
return void 0;
|
|
10545
|
-
|
|
10546
|
-
|
|
10568
|
+
const scoped = [];
|
|
10569
|
+
for (const tool of tools) {
|
|
10570
|
+
if (RETIRED_READ_TOOLS.some((t) => tool === t || tool === `${t}(./**)`))
|
|
10571
|
+
continue;
|
|
10572
|
+
const name = REVIEW_TOOLS.find((t) => tool === t || tool === `${t}(./**)`);
|
|
10547
10573
|
if (!name) {
|
|
10548
|
-
throw new Error(`claude-code: a hosted run may use only ${
|
|
10574
|
+
throw new Error(`claude-code: a hosted run may use only ${REVIEW_TOOLS.join(", ")} inside the checkout; "${tool}" is not allowed`);
|
|
10549
10575
|
}
|
|
10550
|
-
|
|
10551
|
-
}
|
|
10576
|
+
scoped.push(`${name}(./**)`);
|
|
10577
|
+
}
|
|
10578
|
+
return scoped;
|
|
10552
10579
|
}
|
|
10553
10580
|
function buildChildEnv(modelKey, configDir) {
|
|
10554
10581
|
if (!modelKey && !configDir)
|
|
@@ -26907,7 +26934,7 @@ var import_path = require("path");
|
|
|
26907
26934
|
var import_promises = require("fs/promises");
|
|
26908
26935
|
var import_yaml = __toESM(require_dist3());
|
|
26909
26936
|
var import_shuttle = __toESM(require_dist5());
|
|
26910
|
-
var buildVersion = true ? "0.30.
|
|
26937
|
+
var buildVersion = true ? "0.30.16" : pkg.version;
|
|
26911
26938
|
var sifterBrand = {
|
|
26912
26939
|
product: {
|
|
26913
26940
|
id: "sifter",
|
|
@@ -26940,11 +26967,13 @@ var sifterBrand = {
|
|
|
26940
26967
|
// number chosen for tidiness rather than necessity would refuse a working
|
|
26941
26968
|
// install. `git` 2.20 (Dec 2018) is older than any supported distro and is
|
|
26942
26969
|
// where the `--no-tags --depth=1` fetch-by-ref path the materializer uses
|
|
26943
|
-
// settled; `claude` 2.0 is
|
|
26944
|
-
// the
|
|
26970
|
+
// settled; `claude` 2.0.45 is the first release with `--json-schema`, the
|
|
26971
|
+
// newest of the flags every review passes (`--tools` arrived in 2.0.31;
|
|
26972
|
+
// the executor's REVIEW_RUN_ARGS names them all), and the hosted image pins
|
|
26973
|
+
// 2.1.x. Below it a review fails on an unknown option.
|
|
26945
26974
|
minimumToolVersions: {
|
|
26946
26975
|
git: "2.20.0",
|
|
26947
|
-
claude: "2.0.
|
|
26976
|
+
claude: "2.0.45"
|
|
26948
26977
|
},
|
|
26949
26978
|
// Overlay-fetch origins for the signed standards-content URLs each Sift
|
|
26950
26979
|
// tier signs (SIFT_PUBLIC_API_URL). Without these, the executor's SSRF
|