tend-cli 0.7.0 → 0.8.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/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { ClaudeSession, EFFORT_LEVELS, EventBus, ReportBuilder, ReportSchema, Snapshot, addUsage, applyCliOverrides, assertGitRepo, buildDiff, buildProgram, changedVsHead, createGit, detectBuildCommand, detectPackageManager, filesUnder, filterToChanged, formatClock, gateUnitChanges, loadConfig, makeDeterministicFixUnit, makeTheme, orchestrate, planRepair, planWorkFromRepairs, reasonLabel, renderSummary, resolveRetryTarget, restoreSnapshot, retryCommand, runEslintSonarjs, runScanner, scannerStatus, showCommand, snapshotUnitFiles, snapshotUnitNow, toRepoRelative, unitChanged, zeroUsage } from "./config-DPlVYfKX.js";
2
+ import { ClaudeSession, EFFORT_LEVELS, EventBus, ReportBuilder, ReportSchema, Snapshot, addUsage, applyCliOverrides, assertGitRepo, buildDiff, buildProgram, changedVsHead, createGit, detectBuildCommand, detectPackageManager, filesUnder, filterToChanged, formatClock, gateUnitChanges, loadConfig, makeDeterministicFixUnit, makeTheme, orchestrate, planRepair, planWorkFromRepairs, reasonLabel, renderSummary, resolveRetryTarget, restoreSnapshot, retryCommand, runEslintSonarjs, runScanner, scannerStatus, showCommand, snapshotUnitFiles, snapshotUnitNow, toRepoRelative, unitChanged, zeroUsage } from "./config-BeA71px2.js";
3
3
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
5
5
  import { execa } from "execa";
@@ -957,6 +957,50 @@ function makeFixUnit(deps) {
957
957
  };
958
958
  }
959
959
 
960
+ //#endregion
961
+ //#region src/fixing/thinking-budget.ts
962
+ /** Thinking disabled — mechanical fixes don't need reasoning tokens. */
963
+ const THINKING_OFF = 0;
964
+ /**
965
+ * Upper bound on extended-thinking tokens per fix session. Unbounded thinking
966
+ * measured ~7000 tokens per finding regardless of difficulty; capping it keeps
967
+ * reasoning fixes correct (gate stays green) at a fraction of the latency.
968
+ */
969
+ const THINKING_BUDGET_CAP = 4096;
970
+ function isMechanical(finding) {
971
+ return finding.category === "dead-code" || finding.autofixable === true;
972
+ }
973
+ /**
974
+ * Decide the extended-thinking token budget for one finding's fix session.
975
+ * Mechanical findings (dead-code removal, autofixable rules) get thinking off;
976
+ * everything else — reasoning findings and any unrecognized category — gets the
977
+ * bounded cap (the safe default: never spend more than the cap, never starve a
978
+ * finding that might need reasoning). A configured `thinkingBudget` overrides
979
+ * the policy outright, with 0 meaning thinking off.
980
+ */
981
+ function thinkingBudgetFor(finding, config) {
982
+ if (config?.thinkingBudget !== void 0) return config.thinkingBudget;
983
+ return isMechanical(finding) ? THINKING_OFF : THINKING_BUDGET_CAP;
984
+ }
985
+ /**
986
+ * Budget for a whole work unit (one file's findings). Takes the most-conservative
987
+ * (largest) per-finding budget so a reasoning finding is never starved of thinking
988
+ * just because it shares the file with a mechanical one. An empty unit and any
989
+ * unrecognized category fall back to the cap. A configured budget overrides all.
990
+ */
991
+ function thinkingBudgetForUnit(findings, config) {
992
+ if (config?.thinkingBudget !== void 0) return config.thinkingBudget;
993
+ if (findings.length === 0) return THINKING_BUDGET_CAP;
994
+ return Math.max(...findings.map((finding) => thinkingBudgetFor(finding)));
995
+ }
996
+ /**
997
+ * Delivery to the `claude -p` session boundary: the env overlay that pins the
998
+ * session's extended-thinking budget. Spread onto the child process env.
999
+ */
1000
+ function thinkingEnv(findings, config) {
1001
+ return { MAX_THINKING_TOKENS: String(thinkingBudgetForUnit(findings, config)) };
1002
+ }
1003
+
960
1004
  //#endregion
961
1005
  //#region src/fixing/worker-sandbox.ts
962
1006
  var SandboxSetupError = class extends Error {
@@ -1695,7 +1739,11 @@ async function makeProductionFixUnit(config, baselineTargets, ownerRoot = cwd, b
1695
1739
  ], {
1696
1740
  cwd: repoRoot,
1697
1741
  reject: false,
1698
- timeout: CLAUDE_TIMEOUT_MS
1742
+ timeout: CLAUDE_TIMEOUT_MS,
1743
+ env: {
1744
+ ...process.env,
1745
+ ...thinkingEnv(req.findings, config)
1746
+ }
1699
1747
  });
1700
1748
  const exitCode = r.exitCode ?? (r.timedOut ? 143 : r.failed ? 1 : 0);
1701
1749
  return {
@@ -3636,6 +3636,7 @@ const ConfigSchema = z.object({
3636
3636
  includeTests: z.boolean().default(false),
3637
3637
  model: z.string().default("sonnet"),
3638
3638
  effort: z.enum(EFFORT_LEVELS).optional(),
3639
+ thinkingBudget: z.number().int().nonnegative().optional(),
3639
3640
  fix: FixScopeConfigSchema,
3640
3641
  tools: z.record(z.string(), ToolConfigSchema).default({})
3641
3642
  });
package/dist/index.d.ts CHANGED
@@ -1863,6 +1863,8 @@ declare const ConfigSchema: z.ZodObject<{
1863
1863
  model: z.ZodDefault<z.ZodString>;
1864
1864
  /** Reasoning effort for fixes; unset → claude's own default. */
1865
1865
  effort: z.ZodOptional<z.ZodEnum<["low", "medium", "high", "xhigh", "max"]>>;
1866
+ /** Extended-thinking token budget per fix session; unset → per-finding policy decides. */
1867
+ thinkingBudget: z.ZodOptional<z.ZodNumber>;
1866
1868
  /** Report/fix scope policy. Reports stay broad; fixes default away from generated/tooling paths. */
1867
1869
  fix: z.ZodDefault<z.ZodObject<{
1868
1870
  include: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -1909,6 +1911,7 @@ declare const ConfigSchema: z.ZodObject<{
1909
1911
  }>;
1910
1912
  test?: string | undefined;
1911
1913
  effort?: "low" | "medium" | "high" | "xhigh" | "max" | undefined;
1914
+ thinkingBudget?: number | undefined;
1912
1915
  }, {
1913
1916
  maxSessions?: number | undefined;
1914
1917
  maxLoops?: number | undefined;
@@ -1918,6 +1921,7 @@ declare const ConfigSchema: z.ZodObject<{
1918
1921
  includeTests?: boolean | undefined;
1919
1922
  model?: string | undefined;
1920
1923
  effort?: "low" | "medium" | "high" | "xhigh" | "max" | undefined;
1924
+ thinkingBudget?: number | undefined;
1921
1925
  fix?: {
1922
1926
  include?: string[] | undefined;
1923
1927
  exclude?: string[] | undefined;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ClaudeSession, ConfigSchema, EventBus, FindingSchema, FindingStore, REPAIR_STRATEGIES, ReportBuilder, ReportSchema, Snapshot, addUsage, applyCliOverrides, applyRepairPlanToFinding, assertGitRepo, buildProgram, changedFiles, changedVsHead, detectPackageManager, dispatch, filterToChanged, fingerprint, groupRemaining, isAiDispatchStrategy, isAvailable, loadConfig, makeDeterministicFixUnit, makeDeterministicFixer, normalize, orchestrate, planRepair, planWork, planWorkFromRepairs, renderSummary, retryCommand, revertFile, route, runScanner, scopeFindings, showCommand, trackForTool, zeroUsage } from "./config-DPlVYfKX.js";
1
+ import { ClaudeSession, ConfigSchema, EventBus, FindingSchema, FindingStore, REPAIR_STRATEGIES, ReportBuilder, ReportSchema, Snapshot, addUsage, applyCliOverrides, applyRepairPlanToFinding, assertGitRepo, buildProgram, changedFiles, changedVsHead, detectPackageManager, dispatch, filterToChanged, fingerprint, groupRemaining, isAiDispatchStrategy, isAvailable, loadConfig, makeDeterministicFixUnit, makeDeterministicFixer, normalize, orchestrate, planRepair, planWork, planWorkFromRepairs, renderSummary, retryCommand, revertFile, route, runScanner, scopeFindings, showCommand, trackForTool, zeroUsage } from "./config-BeA71px2.js";
2
2
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
3
  import { dirname } from "node:path";
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tend-cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Audit a JS/TS repo with established scanners, then fix the findings with parallel AI sessions in a safe scan-fix-rescan loop.",
5
5
  "keywords": [
6
6
  "lint",