@whittlelabs/sifter 0.35.0 → 0.36.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.
Files changed (3) hide show
  1. package/bin.js +123 -63
  2. package/bin.js.map +4 -4
  3. package/package.json +1 -1
package/bin.js CHANGED
@@ -9961,6 +9961,8 @@ var require_progress = __commonJS({
9961
9961
  seq = 0;
9962
9962
  pending = [];
9963
9963
  textBuf = "";
9964
+ /** The last two characters of reasoning emitted since the last tool; null when none. */
9965
+ reasoningTail = null;
9964
9966
  timer = null;
9965
9967
  closed = false;
9966
9968
  flushMs;
@@ -9970,20 +9972,39 @@ var require_progress = __commonJS({
9970
9972
  this.flushMs = options.flushMs ?? 400;
9971
9973
  this.maxChars = options.maxChars ?? 1200;
9972
9974
  }
9975
+ /** A fragment of reasoning, continuing whatever came before it. */
9973
9976
  reasoning(text) {
9974
9977
  if (this.closed || !text)
9975
9978
  return;
9976
9979
  this.textBuf += text;
9980
+ this.reasoningTail = ((this.reasoningTail ?? "") + text).slice(-2);
9977
9981
  if (this.textBuf.length >= this.maxChars) {
9978
9982
  this.flush();
9979
9983
  } else {
9980
9984
  this.arm();
9981
9985
  }
9982
9986
  }
9987
+ /**
9988
+ * A whole block of reasoning (a thinking summary, a message between tool
9989
+ * calls), trimmed and set off from the reasoning before it by one blank
9990
+ * line. A consumer flows consecutive reasoning frames into one passage, so
9991
+ * two blocks reported as fragments run together mid-sentence, and a
9992
+ * block's own trailing blank lines (thinking summaries end in them) would
9993
+ * show as empty lines before the next act.
9994
+ */
9995
+ reasoningBlock(text) {
9996
+ const block = text.trim();
9997
+ if (this.closed || !block)
9998
+ return;
9999
+ const tail = this.reasoningTail;
10000
+ const gap = tail === null || tail.endsWith("\n\n") ? "" : tail.endsWith("\n") ? "\n" : "\n\n";
10001
+ this.reasoning(gap + block);
10002
+ }
9983
10003
  tool(name, target) {
9984
10004
  if (this.closed || !name)
9985
10005
  return;
9986
10006
  this.drainText();
10007
+ this.reasoningTail = null;
9987
10008
  this.push({ kind: "tool", tool: target ? { name, target } : { name } });
9988
10009
  this.flush();
9989
10010
  }
@@ -10611,6 +10632,87 @@ var require_workspace_telemetry = __commonJS({
10611
10632
  }
10612
10633
  });
10613
10634
 
10635
+ // ../../packages/shuttle/dist/executors/cli-version.js
10636
+ var require_cli_version = __commonJS({
10637
+ "../../packages/shuttle/dist/executors/cli-version.js"(exports2) {
10638
+ "use strict";
10639
+ Object.defineProperty(exports2, "__esModule", { value: true });
10640
+ exports2.cliVersion = cliVersion;
10641
+ var child_process_1 = require("child_process");
10642
+ var VERSION_TIMEOUT_MS = 5e3;
10643
+ function cliVersion(bin, env) {
10644
+ return new Promise((resolve) => {
10645
+ try {
10646
+ (0, child_process_1.execFile)(bin, ["--version"], { timeout: VERSION_TIMEOUT_MS, ...env ? { env } : {} }, (err, stdout) => {
10647
+ resolve(err ? null : String(stdout).match(/\d+\.\d+\.\d+/)?.[0] ?? null);
10648
+ });
10649
+ } catch {
10650
+ resolve(null);
10651
+ }
10652
+ });
10653
+ }
10654
+ }
10655
+ });
10656
+
10657
+ // ../../packages/shuttle/dist/version-check.js
10658
+ var require_version_check = __commonJS({
10659
+ "../../packages/shuttle/dist/version-check.js"(exports2) {
10660
+ "use strict";
10661
+ Object.defineProperty(exports2, "__esModule", { value: true });
10662
+ exports2.UpgradeRequiredError = exports2.LATEST_VERSION_HEADER = exports2.MIN_VERSION_HEADER = void 0;
10663
+ exports2.compareSemver = compareSemver;
10664
+ exports2.checkResponseMinVersion = checkResponseMinVersion;
10665
+ exports2.readResponseLatestVersion = readResponseLatestVersion;
10666
+ exports2.MIN_VERSION_HEADER = "x-sifter-min-version";
10667
+ exports2.LATEST_VERSION_HEADER = "x-sifter-latest-version";
10668
+ var UpgradeRequiredError2 = class extends Error {
10669
+ currentVersion;
10670
+ minVersion;
10671
+ packageName;
10672
+ constructor(opts) {
10673
+ super(`The backend requires ${opts.packageName} ${opts.minVersion} or newer. You're running ${opts.currentVersion}. Upgrade: npm install -g ${opts.packageName}@latest`);
10674
+ this.name = "UpgradeRequiredError";
10675
+ this.currentVersion = opts.currentVersion;
10676
+ this.minVersion = opts.minVersion;
10677
+ this.packageName = opts.packageName;
10678
+ }
10679
+ };
10680
+ exports2.UpgradeRequiredError = UpgradeRequiredError2;
10681
+ function compareSemver(a, b) {
10682
+ const parse = (v) => {
10683
+ const core = v.replace(/^v/, "").split(/[-+]/, 1)[0];
10684
+ const parts = core.split(".").map((p) => Number.parseInt(p, 10));
10685
+ return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
10686
+ };
10687
+ const [aMaj, aMin, aPat] = parse(a);
10688
+ const [bMaj, bMin, bPat] = parse(b);
10689
+ if (aMaj !== bMaj)
10690
+ return aMaj < bMaj ? -1 : 1;
10691
+ if (aMin !== bMin)
10692
+ return aMin < bMin ? -1 : 1;
10693
+ if (aPat !== bPat)
10694
+ return aPat < bPat ? -1 : 1;
10695
+ return 0;
10696
+ }
10697
+ function checkResponseMinVersion(opts) {
10698
+ const minVersion = opts.response.headers.get(exports2.MIN_VERSION_HEADER);
10699
+ if (!minVersion)
10700
+ return;
10701
+ if (compareSemver(opts.currentVersion, minVersion) >= 0)
10702
+ return;
10703
+ throw new UpgradeRequiredError2({
10704
+ currentVersion: opts.currentVersion,
10705
+ minVersion,
10706
+ packageName: opts.packageName
10707
+ });
10708
+ }
10709
+ function readResponseLatestVersion(response) {
10710
+ const latest = response.headers.get(exports2.LATEST_VERSION_HEADER);
10711
+ return latest && latest.trim().length > 0 ? latest.trim() : null;
10712
+ }
10713
+ }
10714
+ });
10715
+
10614
10716
  // ../../packages/shuttle/dist/executors/claude-code.js
10615
10717
  var require_claude_code = __commonJS({
10616
10718
  "../../packages/shuttle/dist/executors/claude-code.js"(exports2) {
@@ -10634,9 +10736,12 @@ var require_claude_code = __commonJS({
10634
10736
  var json_answer_1 = require_json_answer();
10635
10737
  var models_1 = require_models();
10636
10738
  var workspace_telemetry_1 = require_workspace_telemetry();
10739
+ var cli_version_1 = require_cli_version();
10637
10740
  var apply_1 = require_apply();
10741
+ var version_check_1 = require_version_check();
10638
10742
  var DEFAULT_TIMEOUT = 6e5;
10639
10743
  var REVIEW_TOOLS = ["Read", "Grep", "Glob"];
10744
+ var THINKING_DISPLAY_FLOOR = "2.1.94";
10640
10745
  function reviewRunArgs(settingSources) {
10641
10746
  return [
10642
10747
  "--setting-sources",
@@ -10891,13 +10996,17 @@ var require_claude_code = __commonJS({
10891
10996
  args.push("--model", model);
10892
10997
  if (effort)
10893
10998
  args.push("--effort", effort);
10999
+ const version = await (0, cli_version_1.cliVersion)("claude", childEnv);
11000
+ if (version !== null && (0, version_check_1.compareSemver)(version, THINKING_DISPLAY_FLOOR) >= 0) {
11001
+ args.push("--thinking-display", "summarized");
11002
+ }
10894
11003
  if (this.config.maxTurns !== void 0)
10895
11004
  args.push("--max-turns", String(this.config.maxTurns));
10896
11005
  if (allowedTools && allowedTools.length > 0) {
10897
11006
  args.push("--allowedTools", allowedTools.join(","));
10898
11007
  }
10899
11008
  const tap = reporter ? new progress_1.StreamJsonTap({
10900
- onReasoning: (t) => reporter.reasoning(t),
11009
+ onReasoning: (t) => reporter.reasoningBlock(t),
10901
11010
  onTool: (name, target) => reporter.tool(name, target),
10902
11011
  onResult: () => reporter.flush()
10903
11012
  }) : null;
@@ -11395,6 +11504,11 @@ var require_codex = __commonJS({
11395
11504
  'approval_policy="never"',
11396
11505
  "-c",
11397
11506
  'web_search="disabled"',
11507
+ // Reasoning summaries are the live view's narration. With the user config
11508
+ // ignored, codex 0.162.1 emits no reasoning items at all; `detailed`
11509
+ // brings them back without touching the answer.
11510
+ "-c",
11511
+ 'model_reasoning_summary="detailed"',
11398
11512
  ...DISABLED_FEATURES.flatMap((f) => ["--disable", f])
11399
11513
  ];
11400
11514
  }
@@ -11649,12 +11763,17 @@ var require_codex = __commonJS({
11649
11763
  if (event.type === "item.started" && kind === "command_execution" && typeof item?.command === "string") {
11650
11764
  reporter.tool("shell", item.command);
11651
11765
  } else if (event.type === "item.completed" && kind === "reasoning" && typeof item?.text === "string") {
11652
- reporter.reasoning(item.text);
11766
+ reporter.reasoningBlock(plainHeadings(item.text));
11767
+ } else if (event.type === "item.completed" && kind === "agent_message" && typeof item?.text === "string" && (0, json_answer_1.extractJsonObject)(item.text) === void 0) {
11768
+ reporter.reasoningBlock(item.text);
11653
11769
  } else if (event.type === "turn.completed") {
11654
11770
  reporter.flush();
11655
11771
  }
11656
11772
  });
11657
11773
  }
11774
+ function plainHeadings(text) {
11775
+ return text.replace(/^\*\*([^*\n]+)\*\*[ \t]*$/gm, "$1");
11776
+ }
11658
11777
  function itemKind(item) {
11659
11778
  const kind = typeof item.type === "string" ? item.type : typeof item.item_type === "string" ? item.item_type : null;
11660
11779
  return kind === "assistant_message" ? "agent_message" : kind;
@@ -12182,7 +12301,7 @@ ${JSON.stringify(spec.outputSchema)}
12182
12301
  const target = [args.path, args.pattern].find((v) => typeof v === "string");
12183
12302
  reporter.tool(data.toolName, target);
12184
12303
  } else if (event.type === "assistant.reasoning" && typeof data.content === "string") {
12185
- reporter.reasoning(data.content);
12304
+ reporter.reasoningBlock(data.content);
12186
12305
  } else if (event.type === "assistant.turn_end") {
12187
12306
  reporter.flush();
12188
12307
  }
@@ -13730,65 +13849,6 @@ var require_custom_script = __commonJS({
13730
13849
  }
13731
13850
  });
13732
13851
 
13733
- // ../../packages/shuttle/dist/version-check.js
13734
- var require_version_check = __commonJS({
13735
- "../../packages/shuttle/dist/version-check.js"(exports2) {
13736
- "use strict";
13737
- Object.defineProperty(exports2, "__esModule", { value: true });
13738
- exports2.UpgradeRequiredError = exports2.LATEST_VERSION_HEADER = exports2.MIN_VERSION_HEADER = void 0;
13739
- exports2.compareSemver = compareSemver;
13740
- exports2.checkResponseMinVersion = checkResponseMinVersion;
13741
- exports2.readResponseLatestVersion = readResponseLatestVersion;
13742
- exports2.MIN_VERSION_HEADER = "x-sifter-min-version";
13743
- exports2.LATEST_VERSION_HEADER = "x-sifter-latest-version";
13744
- var UpgradeRequiredError2 = class extends Error {
13745
- currentVersion;
13746
- minVersion;
13747
- packageName;
13748
- constructor(opts) {
13749
- super(`The backend requires ${opts.packageName} ${opts.minVersion} or newer. You're running ${opts.currentVersion}. Upgrade: npm install -g ${opts.packageName}@latest`);
13750
- this.name = "UpgradeRequiredError";
13751
- this.currentVersion = opts.currentVersion;
13752
- this.minVersion = opts.minVersion;
13753
- this.packageName = opts.packageName;
13754
- }
13755
- };
13756
- exports2.UpgradeRequiredError = UpgradeRequiredError2;
13757
- function compareSemver(a, b) {
13758
- const parse = (v) => {
13759
- const core = v.replace(/^v/, "").split(/[-+]/, 1)[0];
13760
- const parts = core.split(".").map((p) => Number.parseInt(p, 10));
13761
- return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
13762
- };
13763
- const [aMaj, aMin, aPat] = parse(a);
13764
- const [bMaj, bMin, bPat] = parse(b);
13765
- if (aMaj !== bMaj)
13766
- return aMaj < bMaj ? -1 : 1;
13767
- if (aMin !== bMin)
13768
- return aMin < bMin ? -1 : 1;
13769
- if (aPat !== bPat)
13770
- return aPat < bPat ? -1 : 1;
13771
- return 0;
13772
- }
13773
- function checkResponseMinVersion(opts) {
13774
- const minVersion = opts.response.headers.get(exports2.MIN_VERSION_HEADER);
13775
- if (!minVersion)
13776
- return;
13777
- if (compareSemver(opts.currentVersion, minVersion) >= 0)
13778
- return;
13779
- throw new UpgradeRequiredError2({
13780
- currentVersion: opts.currentVersion,
13781
- minVersion,
13782
- packageName: opts.packageName
13783
- });
13784
- }
13785
- function readResponseLatestVersion(response) {
13786
- const latest = response.headers.get(exports2.LATEST_VERSION_HEADER);
13787
- return latest && latest.trim().length > 0 ? latest.trim() : null;
13788
- }
13789
- }
13790
- });
13791
-
13792
13852
  // ../../packages/shuttle/dist/branding/environment.js
13793
13853
  var require_environment = __commonJS({
13794
13854
  "../../packages/shuttle/dist/branding/environment.js"(exports2) {
@@ -29132,7 +29192,7 @@ var import_path = require("path");
29132
29192
  var import_promises = require("fs/promises");
29133
29193
  var import_yaml = __toESM(require_dist3());
29134
29194
  var import_shuttle = __toESM(require_dist5());
29135
- var buildVersion = true ? "0.35.0" : pkg.version;
29195
+ var buildVersion = true ? "0.36.0" : pkg.version;
29136
29196
  var AGENT_EXECUTORS = ["claude-code", "codex", "copilot"];
29137
29197
  var sifterBrand = {
29138
29198
  product: {