@whittlelabs/sifter 0.30.17 → 0.30.18
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 +2 -0
- package/bin.js +49 -5
- package/bin.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -134,6 +134,8 @@ Sixteen checks over everything the Sifter needs before it can review anything: a
|
|
|
134
134
|
|
|
135
135
|
`init` and `run` run the relevant subset themselves, so `doctor` is for when the Sifter looks healthy and nothing is happening.
|
|
136
136
|
|
|
137
|
+
The login check asks the CLI itself (`claude auth status`), so a login kept in the macOS Keychain counts, and it asks with the settings a review loads. A signed-out CLI fails it with the remedy `claude auth login`; a signed-in one passes as, for example, `signed in (claude.ai, max; not verified)`, because only `--deep` proves the login works. It never prints the email or organization the CLI reports. A `claude` too old to have `auth status` is checked the old way, by looking for its credentials file.
|
|
138
|
+
|
|
137
139
|
```bash
|
|
138
140
|
whittle-sifter doctor --deep # also spend one real turn proving the claude login works
|
|
139
141
|
whittle-sifter doctor --json # the verdicts as JSON, and nothing else
|
package/bin.js
CHANGED
|
@@ -12475,6 +12475,12 @@ var require_checks = __commonJS({
|
|
|
12475
12475
|
const defaults = (0, environment_1.executorDefaultsFor)(subject.brand, config.auth.jobsApiUrl)?.[WORKSPACE_EXECUTOR] ?? {};
|
|
12476
12476
|
return { ...defaults, ...user };
|
|
12477
12477
|
}
|
|
12478
|
+
function claudeSettingsOf(config) {
|
|
12479
|
+
return config.executors[WORKSPACE_EXECUTOR]?.claudeSettings;
|
|
12480
|
+
}
|
|
12481
|
+
function describeLogin(status) {
|
|
12482
|
+
return [status.authMethod ?? "unknown method", status.subscriptionType].filter((part) => part !== null).join(", ");
|
|
12483
|
+
}
|
|
12478
12484
|
function runRoot(config, subject, osTmpDir) {
|
|
12479
12485
|
const settings = claudeCodeSettings(config, subject);
|
|
12480
12486
|
const tmpDir = settings?.tmpDir;
|
|
@@ -12769,6 +12775,14 @@ var require_checks = __commonJS({
|
|
|
12769
12775
|
if (probes.ambientAnthropicKey()) {
|
|
12770
12776
|
return warn("claude-auth", "ANTHROPIC_API_KEY is set and will bill that account, shadowing any interactive login", "unset ANTHROPIC_API_KEY if you meant to use your Claude Code login");
|
|
12771
12777
|
}
|
|
12778
|
+
const settingSources = claudeSettingsOf(config) === "user" ? "user" : "";
|
|
12779
|
+
const status = await probes.claudeAuthStatus(settingSources);
|
|
12780
|
+
if (status !== null) {
|
|
12781
|
+
if (!status.loggedIn) {
|
|
12782
|
+
return fail("claude-auth", "the claude CLI is not signed in", settingSources === "" ? "run `claude auth login`; if your login or provider is configured in Claude Code settings (apiKeyHelper, or an env block), set `claudeSettings: user` on the claude-code executor instead" : "run `claude auth login`");
|
|
12783
|
+
}
|
|
12784
|
+
return pass("claude-auth", `signed in (${describeLogin(status)}; not verified)`);
|
|
12785
|
+
}
|
|
12772
12786
|
const store = await probes.claudeCredentialStore();
|
|
12773
12787
|
if (store === null) {
|
|
12774
12788
|
return warn("claude-auth", "no credential store found for the claude CLI (a macOS login may live in the Keychain, which this cannot read)", "run `claude` once and sign in, or run doctor --deep to spend one turn proving it");
|
|
@@ -21382,6 +21396,7 @@ var require_probes = __commonJS({
|
|
|
21382
21396
|
};
|
|
21383
21397
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
21384
21398
|
exports2.createProbes = createProbes;
|
|
21399
|
+
exports2.parseClaudeAuthStatus = parseClaudeAuthStatus;
|
|
21385
21400
|
var child_process_1 = require("child_process");
|
|
21386
21401
|
var fs_1 = require("fs");
|
|
21387
21402
|
var promises_1 = require("fs/promises");
|
|
@@ -21600,6 +21615,10 @@ var require_probes = __commonJS({
|
|
|
21600
21615
|
const candidate = path_1.default.join(configDir, ".credentials.json");
|
|
21601
21616
|
return (0, fs_1.existsSync)(candidate) ? candidate : null;
|
|
21602
21617
|
},
|
|
21618
|
+
async claudeAuthStatus(settingSources) {
|
|
21619
|
+
const outcome = await runForAnyExit("claude", ["--setting-sources", settingSources, "auth", "status", "--json"], VERSION_TIMEOUT_MS);
|
|
21620
|
+
return outcome === null ? null : parseClaudeAuthStatus(outcome);
|
|
21621
|
+
},
|
|
21603
21622
|
ambientAnthropicKey: () => (process.env.ANTHROPIC_API_KEY ?? "").length > 0,
|
|
21604
21623
|
async claudeRoundTrip() {
|
|
21605
21624
|
const output = await runForOutput(
|
|
@@ -21620,13 +21639,37 @@ var require_probes = __commonJS({
|
|
|
21620
21639
|
const outcome = await runCapturing(bin, args, timeoutMs);
|
|
21621
21640
|
return outcome.ok ? outcome.stdout : null;
|
|
21622
21641
|
}
|
|
21642
|
+
async function runForAnyExit(bin, args, timeoutMs) {
|
|
21643
|
+
const outcome = await runCapturing(bin, args, timeoutMs);
|
|
21644
|
+
if (outcome.ok)
|
|
21645
|
+
return outcome.stdout;
|
|
21646
|
+
return outcome.exited ? outcome.stdout : null;
|
|
21647
|
+
}
|
|
21648
|
+
function parseClaudeAuthStatus(stdout) {
|
|
21649
|
+
let parsed;
|
|
21650
|
+
try {
|
|
21651
|
+
parsed = JSON.parse(stdout);
|
|
21652
|
+
} catch {
|
|
21653
|
+
return null;
|
|
21654
|
+
}
|
|
21655
|
+
if (parsed === null || typeof parsed !== "object")
|
|
21656
|
+
return null;
|
|
21657
|
+
const { loggedIn, authMethod, subscriptionType } = parsed;
|
|
21658
|
+
if (typeof loggedIn !== "boolean")
|
|
21659
|
+
return null;
|
|
21660
|
+
return {
|
|
21661
|
+
loggedIn,
|
|
21662
|
+
authMethod: typeof authMethod === "string" && authMethod.length > 0 ? authMethod : null,
|
|
21663
|
+
subscriptionType: typeof subscriptionType === "string" && subscriptionType.length > 0 ? subscriptionType : null
|
|
21664
|
+
};
|
|
21665
|
+
}
|
|
21623
21666
|
function runCapturing(bin, args, timeoutMs) {
|
|
21624
21667
|
return new Promise((resolve) => {
|
|
21625
21668
|
let child;
|
|
21626
21669
|
try {
|
|
21627
21670
|
child = (0, child_process_1.spawn)(bin, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
21628
21671
|
} catch (err) {
|
|
21629
|
-
resolve({ ok: false, reason: describe(err) });
|
|
21672
|
+
resolve({ ok: false, reason: describe(err), exited: false });
|
|
21630
21673
|
return;
|
|
21631
21674
|
}
|
|
21632
21675
|
let stdout = "";
|
|
@@ -21640,7 +21683,7 @@ var require_probes = __commonJS({
|
|
|
21640
21683
|
};
|
|
21641
21684
|
const timer = setTimeout(() => {
|
|
21642
21685
|
child.kill("SIGKILL");
|
|
21643
|
-
settle({ ok: false, reason: `did not finish within ${Math.round(timeoutMs / 1e3)}s
|
|
21686
|
+
settle({ ok: false, reason: `did not finish within ${Math.round(timeoutMs / 1e3)}s`, exited: false });
|
|
21644
21687
|
}, timeoutMs);
|
|
21645
21688
|
child.stdout?.on("data", (chunk) => {
|
|
21646
21689
|
stdout += chunk.toString("utf8");
|
|
@@ -21650,7 +21693,7 @@ var require_probes = __commonJS({
|
|
|
21650
21693
|
});
|
|
21651
21694
|
child.on("error", (err) => {
|
|
21652
21695
|
clearTimeout(timer);
|
|
21653
|
-
settle({ ok: false, reason: describe(err) });
|
|
21696
|
+
settle({ ok: false, reason: describe(err), exited: false });
|
|
21654
21697
|
});
|
|
21655
21698
|
child.on("close", (code, signal) => {
|
|
21656
21699
|
clearTimeout(timer);
|
|
@@ -21660,7 +21703,8 @@ var require_probes = __commonJS({
|
|
|
21660
21703
|
}
|
|
21661
21704
|
const status = code === null ? `was killed by ${signal ?? "a signal"}` : `exited ${code}`;
|
|
21662
21705
|
const said = stderr.split("\n").map((line) => line.trim()).find((line) => line.length > 0);
|
|
21663
|
-
|
|
21706
|
+
const reason = said ? `${status}: ${said}` : status;
|
|
21707
|
+
settle(code === null ? { ok: false, reason, exited: false } : { ok: false, reason, exited: true, stdout: stdout.trim() });
|
|
21664
21708
|
});
|
|
21665
21709
|
});
|
|
21666
21710
|
}
|
|
@@ -26966,7 +27010,7 @@ var import_path = require("path");
|
|
|
26966
27010
|
var import_promises = require("fs/promises");
|
|
26967
27011
|
var import_yaml = __toESM(require_dist3());
|
|
26968
27012
|
var import_shuttle = __toESM(require_dist5());
|
|
26969
|
-
var buildVersion = true ? "0.30.
|
|
27013
|
+
var buildVersion = true ? "0.30.18" : pkg.version;
|
|
26970
27014
|
var sifterBrand = {
|
|
26971
27015
|
product: {
|
|
26972
27016
|
id: "sifter",
|