@audit-tools/shared 0.1.0 → 0.5.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 (53) hide show
  1. package/dist/git.d.ts +18 -0
  2. package/dist/git.d.ts.map +1 -0
  3. package/dist/git.js +63 -0
  4. package/dist/git.js.map +1 -0
  5. package/dist/index.d.ts +17 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +9 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/observability/runLog.d.ts +31 -0
  10. package/dist/observability/runLog.d.ts.map +1 -0
  11. package/dist/observability/runLog.js +40 -0
  12. package/dist/observability/runLog.js.map +1 -0
  13. package/dist/quota/errorParsing.d.ts.map +1 -1
  14. package/dist/quota/errorParsing.js +13 -1
  15. package/dist/quota/errorParsing.js.map +1 -1
  16. package/dist/quota/limits.d.ts.map +1 -1
  17. package/dist/quota/limits.js +2 -13
  18. package/dist/quota/limits.js.map +1 -1
  19. package/dist/tokens.d.ts +29 -0
  20. package/dist/tokens.d.ts.map +1 -0
  21. package/dist/tokens.js +59 -0
  22. package/dist/tokens.js.map +1 -0
  23. package/dist/tooling/analyzerDeps.d.ts +43 -0
  24. package/dist/tooling/analyzerDeps.d.ts.map +1 -0
  25. package/dist/tooling/analyzerDeps.js +112 -0
  26. package/dist/tooling/analyzerDeps.js.map +1 -0
  27. package/dist/tooling/exec.d.ts +48 -0
  28. package/dist/tooling/exec.d.ts.map +1 -0
  29. package/dist/tooling/exec.js +108 -0
  30. package/dist/tooling/exec.js.map +1 -0
  31. package/dist/tooling/repoConventions.d.ts +21 -0
  32. package/dist/tooling/repoConventions.d.ts.map +1 -0
  33. package/dist/tooling/repoConventions.js +162 -0
  34. package/dist/tooling/repoConventions.js.map +1 -0
  35. package/dist/tooling/testCommand.d.ts +17 -0
  36. package/dist/tooling/testCommand.d.ts.map +1 -0
  37. package/dist/tooling/testCommand.js +78 -0
  38. package/dist/tooling/testCommand.js.map +1 -0
  39. package/dist/types/finding.d.ts +80 -0
  40. package/dist/types/finding.d.ts.map +1 -0
  41. package/dist/types/finding.js +8 -0
  42. package/dist/types/finding.js.map +1 -0
  43. package/dist/types/graph.d.ts +6 -0
  44. package/dist/types/graph.d.ts.map +1 -1
  45. package/dist/types/remediationOutcome.d.ts +21 -0
  46. package/dist/types/remediationOutcome.d.ts.map +1 -0
  47. package/dist/types/remediationOutcome.js +7 -0
  48. package/dist/types/remediationOutcome.js.map +1 -0
  49. package/dist/types/sessionConfig.d.ts +46 -0
  50. package/dist/types/sessionConfig.d.ts.map +1 -1
  51. package/dist/types/sessionConfig.js +22 -0
  52. package/dist/types/sessionConfig.js.map +1 -1
  53. package/package.json +41 -29
package/dist/git.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /** True when `root` is inside a git working tree. */
2
+ export declare function isGitRepo(root: string): boolean;
3
+ /**
4
+ * True when `ref` resolves to a commit in `root`. Lets callers distinguish a
5
+ * mistyped/unknown `--since` ref (fall back to a full audit) from a valid ref
6
+ * with no changes (`changedFiles` returns `[]` in both cases otherwise).
7
+ */
8
+ export declare function gitRefExists(root: string, ref: string): boolean;
9
+ /**
10
+ * Files differing between `since` (a ref/SHA) and the current working tree —
11
+ * committed, staged, and unstaged. Backs the auditor's `--since` delta mode.
12
+ */
13
+ export declare function changedFiles(root: string, since: string): string[];
14
+ /** The set of commit SHAs that have touched `path`, newest first. */
15
+ export declare function fileCommits(root: string, path: string): Set<string>;
16
+ /** Working-tree changes vs HEAD plus untracked (non-ignored) files. */
17
+ export declare function stagedAndUntracked(root: string): string[];
18
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAmBA,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAM/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAElE;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAEnE;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAazD"}
package/dist/git.js ADDED
@@ -0,0 +1,63 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { runTracked } from "./tooling/exec.js";
4
+ // Git helpers shared by both orchestrators. The remediator previously issued
5
+ // `git` calls inline in close.ts and plan.ts; the auditor's Phase 3 delta mode
6
+ // needs the same primitives. All run through the shared `runTracked` so the
7
+ // one Windows-wrapping implementation applies, and all degrade to empty/false
8
+ // when git is unavailable or the command fails (never throw).
9
+ function gitLines(root, args) {
10
+ const result = runTracked(["git", ...args], { cwd: root, encoding: "utf8" });
11
+ if (result.status !== 0)
12
+ return [];
13
+ return result.stdout
14
+ .split(/\r?\n/)
15
+ .map((line) => line.trim())
16
+ .filter((line) => line.length > 0);
17
+ }
18
+ /** True when `root` is inside a git working tree. */
19
+ export function isGitRepo(root) {
20
+ if (existsSync(join(root, ".git")))
21
+ return true;
22
+ const result = runTracked(["git", "rev-parse", "--is-inside-work-tree"], {
23
+ cwd: root,
24
+ encoding: "utf8",
25
+ });
26
+ return result.status === 0 && result.stdout.trim() === "true";
27
+ }
28
+ /**
29
+ * True when `ref` resolves to a commit in `root`. Lets callers distinguish a
30
+ * mistyped/unknown `--since` ref (fall back to a full audit) from a valid ref
31
+ * with no changes (`changedFiles` returns `[]` in both cases otherwise).
32
+ */
33
+ export function gitRefExists(root, ref) {
34
+ const result = runTracked(["git", "rev-parse", "--verify", "--quiet", `${ref}^{commit}`], { cwd: root, encoding: "utf8" });
35
+ return result.status === 0 && result.stdout.trim().length > 0;
36
+ }
37
+ /**
38
+ * Files differing between `since` (a ref/SHA) and the current working tree —
39
+ * committed, staged, and unstaged. Backs the auditor's `--since` delta mode.
40
+ */
41
+ export function changedFiles(root, since) {
42
+ return gitLines(root, ["diff", "--name-only", since]);
43
+ }
44
+ /** The set of commit SHAs that have touched `path`, newest first. */
45
+ export function fileCommits(root, path) {
46
+ return new Set(gitLines(root, ["log", "--format=%H", "--", path]));
47
+ }
48
+ /** Working-tree changes vs HEAD plus untracked (non-ignored) files. */
49
+ export function stagedAndUntracked(root) {
50
+ const files = new Set();
51
+ for (const file of gitLines(root, ["diff", "--name-only", "HEAD"])) {
52
+ files.add(file);
53
+ }
54
+ for (const file of gitLines(root, [
55
+ "ls-files",
56
+ "--others",
57
+ "--exclude-standard",
58
+ ])) {
59
+ files.add(file);
60
+ }
61
+ return [...files];
62
+ }
63
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,10 +8,25 @@ export type { RunLedgerStatus, RunLedgerEntry, RunLedger, } from "./types/runLed
8
8
  export { RUN_LEDGER_STATUSES } from "./types/runLedger.js";
9
9
  export type { GraphEdge, RouteEdge, GraphBundle, } from "./types/graph.js";
10
10
  export type { AccessDeclaration } from "./types/accessDeclaration.js";
11
+ export type { FindingSeverity, FindingConfidence, FindingLocation, Finding, WorkBlock, FindingTheme, SynthesisNarrative, AuditFindingsSummary, AuditFindingsReport, } from "./types/finding.js";
12
+ export type { RemediationOutcomeStatus, RemediationOutcome, RemediationOutcomesReport, } from "./types/remediationOutcome.js";
13
+ export type { RepoConventions } from "./tooling/repoConventions.js";
14
+ export { detectRepoConventions, formatRepoConventions, } from "./tooling/repoConventions.js";
11
15
  export type { StepStatus, DispatchModelTier, DispatchModelHint, } from "./types/stepContract.js";
12
- export type { ProviderName, ResolvedProviderName, SessionUiMode, SubprocessTemplateConfig, ClaudeCodeConfig, OpenCodeConfig, VSCodeTaskConfig, BlockQuotaConfig, QuotaModelLimits, QuotaConfig, OpenTokenConfig, SessionConfig, } from "./types/sessionConfig.js";
13
- export { PROVIDER_NAMES, SESSION_UI_MODES, PROVIDER_SECTION_KEYS, } from "./types/sessionConfig.js";
16
+ export type { ProviderName, ResolvedProviderName, SessionUiMode, SubprocessTemplateConfig, ClaudeCodeConfig, OpenCodeConfig, VSCodeTaskConfig, BlockQuotaConfig, QuotaModelLimits, QuotaConfig, OpenTokenConfig, ObservabilityConfig, SynthesisConfig, GraphConfig, AnalyzerSetting, SessionConfig, } from "./types/sessionConfig.js";
17
+ export { PROVIDER_NAMES, SESSION_UI_MODES, PROVIDER_SECTION_KEYS, ANALYZER_SETTINGS, } from "./types/sessionConfig.js";
14
18
  export { AUDITOR_REPORT_MARKER } from "./contracts.js";
19
+ export type { ModelTokenLimits } from "./tokens.js";
20
+ export { KNOWN_MODEL_LIMITS, lookupModelLimits, DEFAULT_CONTEXT_TOKENS, DEFAULT_OUTPUT_TOKENS, BLOCK_SAFETY_MARGIN, BYTES_PER_TOKEN, ESTIMATED_TOKENS_PER_LINE, estimateTokensFromBytes, resolveContextBudget, } from "./tokens.js";
21
+ export type { RunTrackedOptions, RunTrackedResult } from "./tooling/exec.js";
22
+ export { runTracked, resolveExecArgv, quoteForCmd, platformCommand, } from "./tooling/exec.js";
23
+ export type { ProjectCommands } from "./tooling/testCommand.js";
24
+ export { discoverProjectCommands } from "./tooling/testCommand.js";
25
+ export type { AnalyzerDepVia, ResolvedAnalyzerDep, ResolveAnalyzerDepOptions, InstallToCacheOptions, InstallToCacheResult, } from "./tooling/analyzerDeps.js";
26
+ export { analyzerCacheRoot, parseAnalyzerSpec, resolveAnalyzerDep, installToCache, } from "./tooling/analyzerDeps.js";
27
+ export { isGitRepo, gitRefExists, changedFiles, fileCommits, stagedAndUntracked, } from "./git.js";
28
+ export type { RunLogEvent, RunLoggerOptions } from "./observability/runLog.js";
29
+ export { RunLogger } from "./observability/runLog.js";
15
30
  export { isFileMissingError, readJsonFile, writeJsonFile, appendNdjsonFile, readNdjsonFile, readOptionalJsonFile, readOptionalNdjsonFile, writeNdjsonFile, readOptionalTextFile, writeTextFile, } from "./io/json.js";
16
31
  export type { ValidationSeverity, ValidationIssue } from "./validation/basic.js";
17
32
  export { describeValue, isRecord, createValidationIssue, pushValidationIssue, prefixValidationIssues, formatValidationIssues, requireKeys, } from "./validation/basic.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,9 +1,17 @@
1
1
  export { FLOW_CONFIDENCE_LEVELS } from "./types/flows.js";
2
2
  export { SURFACE_KINDS } from "./types/surfaces.js";
3
3
  export { RUN_LEDGER_STATUSES } from "./types/runLedger.js";
4
- export { PROVIDER_NAMES, SESSION_UI_MODES, PROVIDER_SECTION_KEYS, } from "./types/sessionConfig.js";
4
+ export { detectRepoConventions, formatRepoConventions, } from "./tooling/repoConventions.js";
5
+ export { PROVIDER_NAMES, SESSION_UI_MODES, PROVIDER_SECTION_KEYS, ANALYZER_SETTINGS, } from "./types/sessionConfig.js";
5
6
  // Contracts
6
7
  export { AUDITOR_REPORT_MARKER } from "./contracts.js";
8
+ export { KNOWN_MODEL_LIMITS, lookupModelLimits, DEFAULT_CONTEXT_TOKENS, DEFAULT_OUTPUT_TOKENS, BLOCK_SAFETY_MARGIN, BYTES_PER_TOKEN, ESTIMATED_TOKENS_PER_LINE, estimateTokensFromBytes, resolveContextBudget, } from "./tokens.js";
9
+ export { runTracked, resolveExecArgv, quoteForCmd, platformCommand, } from "./tooling/exec.js";
10
+ export { discoverProjectCommands } from "./tooling/testCommand.js";
11
+ export { analyzerCacheRoot, parseAnalyzerSpec, resolveAnalyzerDep, installToCache, } from "./tooling/analyzerDeps.js";
12
+ // Git helpers
13
+ export { isGitRepo, gitRefExists, changedFiles, fileCommits, stagedAndUntracked, } from "./git.js";
14
+ export { RunLogger } from "./observability/runLog.js";
7
15
  // IO
8
16
  export { isFileMissingError, readJsonFile, writeJsonFile, appendNdjsonFile, readNdjsonFile, readOptionalJsonFile, readOptionalNdjsonFile, writeNdjsonFile, readOptionalTextFile, writeTextFile, } from "./io/json.js";
9
17
  export { describeValue, isRecord, createValidationIssue, pushValidationIssue, prefixValidationIssues, formatValidationIssues, requireKeys, } from "./validation/basic.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AA0B3D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,YAAY;AACZ,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,KAAK;AACL,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,aAAa,GACd,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAW/B,qBAAqB;AACrB,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAiB1E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAwB3D,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AAwBtC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAElC,YAAY;AACZ,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAIrB,OAAO,EACL,UAAU,EACV,eAAe,EACf,WAAW,EACX,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAUnE,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,GACf,MAAM,2BAA2B,CAAC;AAEnC,cAAc;AACd,OAAO,EACL,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAIlB,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,KAAK;AACL,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,aAAa,GACd,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAW/B,qBAAqB;AACrB,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAiB1E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,31 @@
1
+ export interface RunLogEvent {
2
+ /** Coarse phase/state, e.g. "advance" or "implementing". */
3
+ phase?: string;
4
+ /** The obligation/decision this event relates to. */
5
+ obligation?: string;
6
+ /** Event kind: "obligation" | "executor_start" | "executor_end" | "artifact_write" | "provider_launch" | ... */
7
+ kind: string;
8
+ artifact?: string;
9
+ provider?: string;
10
+ tokens_est?: number;
11
+ duration_ms?: number;
12
+ note?: string;
13
+ [key: string]: unknown;
14
+ }
15
+ export interface RunLoggerOptions {
16
+ enabled?: boolean;
17
+ /** Injectable clock (epoch ms) for deterministic tests. */
18
+ now?: () => number;
19
+ }
20
+ export declare class RunLogger {
21
+ private readonly path;
22
+ private readonly enabled;
23
+ private readonly now;
24
+ constructor(path: string, options?: RunLoggerOptions);
25
+ /** A logger that drops every event. Use when observability is disabled. */
26
+ static disabled(): RunLogger;
27
+ get isEnabled(): boolean;
28
+ /** Append one event line. Atomic per line (O_APPEND); swallows all errors. */
29
+ event(event: RunLogEvent): void;
30
+ }
31
+ //# sourceMappingURL=runLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runLog.d.ts","sourceRoot":"","sources":["../../src/observability/runLog.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gHAAgH;IAChH,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAMxD,2EAA2E;IAC3E,MAAM,CAAC,QAAQ,IAAI,SAAS;IAI5B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,8EAA8E;IAC9E,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;CAgBhC"}
@@ -0,0 +1,40 @@
1
+ import { appendFileSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ export class RunLogger {
4
+ path;
5
+ enabled;
6
+ now;
7
+ constructor(path, options = {}) {
8
+ this.path = path;
9
+ this.enabled = options.enabled ?? true;
10
+ this.now = options.now ?? (() => Date.now());
11
+ }
12
+ /** A logger that drops every event. Use when observability is disabled. */
13
+ static disabled() {
14
+ return new RunLogger("", { enabled: false });
15
+ }
16
+ get isEnabled() {
17
+ return this.enabled;
18
+ }
19
+ /** Append one event line. Atomic per line (O_APPEND); swallows all errors. */
20
+ event(event) {
21
+ if (!this.enabled || this.path.length === 0)
22
+ return;
23
+ let line;
24
+ try {
25
+ line = JSON.stringify({ ts: new Date(this.now()).toISOString(), ...event }) + "\n";
26
+ }
27
+ catch {
28
+ // Non-serializable payload: log a minimal marker instead of throwing.
29
+ line = JSON.stringify({ ts: new Date(this.now()).toISOString(), kind: event.kind, note: "unserializable_event" }) + "\n";
30
+ }
31
+ try {
32
+ mkdirSync(dirname(this.path), { recursive: true });
33
+ appendFileSync(this.path, line, "utf8");
34
+ }
35
+ catch {
36
+ // Observability must never break a run.
37
+ }
38
+ }
39
+ }
40
+ //# sourceMappingURL=runLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runLog.js","sourceRoot":"","sources":["../../src/observability/runLog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,MAAM,OAAO,SAAS;IACH,IAAI,CAAS;IACb,OAAO,CAAU;IACjB,GAAG,CAAe;IAEnC,YAAY,IAAY,EAAE,UAA4B,EAAE;QACtD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;QACvC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,2EAA2E;IAC3E,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,SAAS,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,KAAkB;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpD,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;QACrF,CAAC;QAAC,MAAM,CAAC;YACP,sEAAsE;YACtE,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC,GAAG,IAAI,CAAC;QAC3H,CAAC;QACD,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACnD,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;IACH,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"errorParsing.d.ts","sourceRoot":"","sources":["../../src/quota/errorParsing.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AA0DD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAY3E;AAID,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,GAAE,MAA4B,GACtC,MAAM,CAGR"}
1
+ {"version":3,"file":"errorParsing.d.ts","sourceRoot":"","sources":["../../src/quota/errorParsing.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAqED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAY3E;AAID,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,GAAE,MAA4B,GACtC,MAAM,CAGR"}
@@ -50,6 +50,18 @@ function detectFromJson(text) {
50
50
  rawMatch: `json:${status === 429 ? "status=429" : `type=${type ?? errorType}`}`,
51
51
  };
52
52
  }
53
+ function extractResetsInMs(text) {
54
+ const match = /Resets in (?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/i.exec(text);
55
+ if (!match)
56
+ return null;
57
+ const hours = match[1] ? parseInt(match[1], 10) : 0;
58
+ const minutes = match[2] ? parseInt(match[2], 10) : 0;
59
+ const seconds = match[3] ? parseInt(match[3], 10) : 0;
60
+ if (hours === 0 && minutes === 0 && seconds === 0)
61
+ return null;
62
+ // Add 5 seconds of buffer
63
+ return (hours * 3600 + minutes * 60 + seconds + 5) * 1000;
64
+ }
53
65
  export function detectRateLimitError(text) {
54
66
  const jsonResult = detectFromJson(text);
55
67
  if (jsonResult)
@@ -57,7 +69,7 @@ export function detectRateLimitError(text) {
57
69
  for (const pattern of RATE_LIMIT_PATTERNS) {
58
70
  const match = pattern.exec(text);
59
71
  if (match) {
60
- return { isRateLimited: true, retryAfterMs: null, rawMatch: match[0] };
72
+ return { isRateLimited: true, retryAfterMs: extractResetsInMs(text), rawMatch: match[0] };
61
73
  }
62
74
  }
63
75
  return { isRateLimited: false, retryAfterMs: null, rawMatch: null };
@@ -1 +1 @@
1
- {"version":3,"file":"errorParsing.js","sourceRoot":"","sources":["../../src/quota/errorParsing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errorParsing.js","sourceRoot":"","sources":["../../src/quota/errorParsing.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/quota/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAe/E,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,oBAAoB,GAAG,YAAY,CAYjF;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,GACf,IAAI,CAAC,cAAc,EAAE,gBAAgB,GAAG,eAAe,CAAC,GAAG,SAAS,CAEtE;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,oBAAoB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAaD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,CAyClF"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/quota/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG/E,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,oBAAoB,GAAG,YAAY,CAYjF;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,GACf,IAAI,CAAC,cAAc,EAAE,gBAAgB,GAAG,eAAe,CAAC,GAAG,SAAS,CAEtE;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,oBAAoB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAaD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,CAyClF"}
@@ -1,15 +1,4 @@
1
- // RPM/TPM are omitted here — they are tier-dependent and must come from learning.
2
- const KNOWN_MODEL_LIMITS = {
3
- "anthropic/claude-opus-4-7": { context_tokens: 200_000, output_tokens: 32_000 },
4
- "anthropic/claude-sonnet-4-6": { context_tokens: 200_000, output_tokens: 8_192 },
5
- "anthropic/claude-haiku-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
6
- "anthropic/claude-opus-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
7
- "anthropic/claude-sonnet-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
8
- "openai/gpt-4o": { context_tokens: 128_000, output_tokens: 16_384 },
9
- "openai/gpt-4o-mini": { context_tokens: 128_000, output_tokens: 16_384 },
10
- "google/gemini-2.0-flash": { context_tokens: 1_048_576, output_tokens: 8_192 },
11
- "google/gemini-1.5-pro": { context_tokens: 2_097_152, output_tokens: 8_192 },
12
- };
1
+ import { lookupModelLimits } from "../tokens.js";
13
2
  export function classifyProvider(providerName) {
14
3
  switch (providerName) {
15
4
  case "claude-code":
@@ -24,7 +13,7 @@ export function classifyProvider(providerName) {
24
13
  }
25
14
  }
26
15
  export function lookupKnownModel(modelKey) {
27
- return KNOWN_MODEL_LIMITS[modelKey.toLowerCase().trim()];
16
+ return lookupModelLimits(modelKey);
28
17
  }
29
18
  function defaultLimits(sessionConfig) {
30
19
  const quota = sessionConfig.quota ?? {};
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/quota/limits.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/quota/limits.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAIjD,MAAM,UAAU,gBAAgB,CAAC,YAAkC;IACjE,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,aAAa;YAChB,OAAO,QAAQ,CAAC;QAClB,KAAK,UAAU,CAAC;QAChB,KAAK,kBAAkB;YACrB,OAAO,OAAO,CAAC;QACjB,KAAK,qBAAqB,CAAC;QAC3B,KAAK,aAAa,CAAC;QACnB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAAgB;IAEhB,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAcD,SAAS,aAAa,CAAC,aAA4B;IACjD,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC;IACxC,OAAO;QACL,cAAc,EAAE,KAAK,CAAC,sBAAsB,IAAI,MAAM;QACtD,aAAa,EAAE,KAAK,CAAC,sBAAsB,IAAI,KAAK;QACpD,mBAAmB,EAAE,IAAI;QACzB,uBAAuB,EAAE,IAAI;QAC7B,wBAAwB,EAAE,IAAI;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC1E,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;IAE9C,yCAAyC;IACzC,IAAI,SAAS,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO;YACL,MAAM,EAAE;gBACN,cAAc,EAAE,QAAQ,CAAC,cAAc,IAAI,QAAQ,CAAC,cAAc;gBAClE,aAAa,EAAE,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,aAAa;gBAC/D,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,IAAI,IAAI;gBACzD,uBAAuB,EAAE,QAAQ,CAAC,uBAAuB,IAAI,IAAI;gBACjE,wBAAwB,EAAE,QAAQ,CAAC,wBAAwB,IAAI,IAAI;aACpE;YACD,MAAM,EAAE,iBAAiB;YACzB,UAAU,EAAE,MAAM;SACnB,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,KAAK,EAAE,CAAC;YACV,OAAO;gBACL,MAAM,EAAE;oBACN,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,mBAAmB,EAAE,IAAI;oBACzB,uBAAuB,EAAE,IAAI;oBAC7B,wBAAwB,EAAE,IAAI;iBAC/B;gBACD,MAAM,EAAE,gBAAgB;gBACxB,UAAU,EAAE,QAAQ;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACpE,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface ModelTokenLimits {
2
+ context_tokens: number;
3
+ output_tokens: number;
4
+ }
5
+ export declare const KNOWN_MODEL_LIMITS: Record<string, ModelTokenLimits>;
6
+ /** Case-insensitive lookup of a known model's context/output limits. */
7
+ export declare function lookupModelLimits(modelKey: string): ModelTokenLimits | undefined;
8
+ export declare const DEFAULT_CONTEXT_TOKENS = 200000;
9
+ export declare const DEFAULT_OUTPUT_TOKENS = 8192;
10
+ export declare const BLOCK_SAFETY_MARGIN = 0.7;
11
+ export declare const BYTES_PER_TOKEN = 4;
12
+ export declare const ESTIMATED_TOKENS_PER_LINE = 4;
13
+ /**
14
+ * Estimate tokens from a raw byte count. Non-finite or non-positive inputs
15
+ * estimate to zero so missing `size_bytes` never inflates a budget.
16
+ */
17
+ export declare function estimateTokensFromBytes(bytes: number): number;
18
+ /**
19
+ * Usable context budget for a single work block: (context − reserved output)
20
+ * scaled by the safety margin. Falls back to a known model's limits, then to
21
+ * the conservative defaults.
22
+ */
23
+ export declare function resolveContextBudget(input: {
24
+ contextTokens?: number | null;
25
+ reservedOutputTokens?: number | null;
26
+ hostModel?: string | null;
27
+ safetyMargin?: number;
28
+ }): number;
29
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAID,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAU/D,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEhF;AAGD,eAAO,MAAM,sBAAsB,SAAU,CAAC;AAC9C,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAI3C,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAIvC,eAAO,MAAM,eAAe,IAAI,CAAC;AAIjC,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAQT"}
package/dist/tokens.js ADDED
@@ -0,0 +1,59 @@
1
+ // Canonical token-budget arithmetic shared by both orchestrators.
2
+ //
3
+ // Before Phase 0 each package carried its own copy of the model-limits table
4
+ // and a per-line token estimator (auditor `reviewPackets.ts`, remediator
5
+ // `plan.ts`). This module is the single source of truth for:
6
+ // - the known-model context/output limits,
7
+ // - the byte- and line-based token estimators,
8
+ // - the default budgets and safety margin used when sizing work blocks.
9
+ // Known-model context/output limits. RPM/TPM are tier-dependent and must come
10
+ // from learning, so they are intentionally omitted here (see quota/limits.ts).
11
+ export const KNOWN_MODEL_LIMITS = {
12
+ "anthropic/claude-opus-4-7": { context_tokens: 200_000, output_tokens: 32_000 },
13
+ "anthropic/claude-sonnet-4-6": { context_tokens: 200_000, output_tokens: 8_192 },
14
+ "anthropic/claude-haiku-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
15
+ "anthropic/claude-opus-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
16
+ "anthropic/claude-sonnet-4-5": { context_tokens: 200_000, output_tokens: 8_192 },
17
+ "openai/gpt-4o": { context_tokens: 128_000, output_tokens: 16_384 },
18
+ "openai/gpt-4o-mini": { context_tokens: 128_000, output_tokens: 16_384 },
19
+ "google/gemini-2.0-flash": { context_tokens: 1_048_576, output_tokens: 8_192 },
20
+ "google/gemini-1.5-pro": { context_tokens: 2_097_152, output_tokens: 8_192 },
21
+ };
22
+ /** Case-insensitive lookup of a known model's context/output limits. */
23
+ export function lookupModelLimits(modelKey) {
24
+ return KNOWN_MODEL_LIMITS[modelKey.toLowerCase().trim()];
25
+ }
26
+ // Conservative default budgets when no model is configured or recognized.
27
+ export const DEFAULT_CONTEXT_TOKENS = 200_000;
28
+ export const DEFAULT_OUTPUT_TOKENS = 8_192;
29
+ // Fraction of the usable window (context − reserved output) a single work block
30
+ // or review packet is allowed to occupy. Leaves headroom for the host prompt.
31
+ export const BLOCK_SAFETY_MARGIN = 0.7;
32
+ // Heuristic byte→token ratio for source code and English prose. Roughly four
33
+ // bytes per token; deliberately coarse — callers size budgets, not bills.
34
+ export const BYTES_PER_TOKEN = 4;
35
+ // Legacy line-based estimate. Retained for callers that size by line count
36
+ // before Phase 2 switches them to byte-based sizing.
37
+ export const ESTIMATED_TOKENS_PER_LINE = 4;
38
+ /**
39
+ * Estimate tokens from a raw byte count. Non-finite or non-positive inputs
40
+ * estimate to zero so missing `size_bytes` never inflates a budget.
41
+ */
42
+ export function estimateTokensFromBytes(bytes) {
43
+ if (!Number.isFinite(bytes) || bytes <= 0)
44
+ return 0;
45
+ return Math.ceil(bytes / BYTES_PER_TOKEN);
46
+ }
47
+ /**
48
+ * Usable context budget for a single work block: (context − reserved output)
49
+ * scaled by the safety margin. Falls back to a known model's limits, then to
50
+ * the conservative defaults.
51
+ */
52
+ export function resolveContextBudget(input) {
53
+ const known = input.hostModel ? lookupModelLimits(input.hostModel) : undefined;
54
+ const contextTokens = input.contextTokens ?? known?.context_tokens ?? DEFAULT_CONTEXT_TOKENS;
55
+ const outputTokens = input.reservedOutputTokens ?? known?.output_tokens ?? DEFAULT_OUTPUT_TOKENS;
56
+ const margin = input.safetyMargin ?? BLOCK_SAFETY_MARGIN;
57
+ return Math.floor((contextTokens - outputTokens) * margin);
58
+ }
59
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,6DAA6D;AAC7D,6CAA6C;AAC7C,iDAAiD;AACjD,0EAA0E;AAO1E,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAClE,2BAA2B,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE;IAC/E,6BAA6B,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE;IAChF,4BAA4B,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE;IAC/E,2BAA2B,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE;IAC9E,6BAA6B,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE;IAChF,eAAe,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE;IACnE,oBAAoB,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE;IACxE,yBAAyB,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE;IAC9E,uBAAuB,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE;CAC7E,CAAC;AAEF,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,kBAAkB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE3C,gFAAgF;AAChF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,6EAA6E;AAC7E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,2EAA2E;AAC3E,qDAAqD;AACrD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACpD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAKpC;IACC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,aAAa,GACjB,KAAK,CAAC,aAAa,IAAI,KAAK,EAAE,cAAc,IAAI,sBAAsB,CAAC;IACzE,MAAM,YAAY,GAChB,KAAK,CAAC,oBAAoB,IAAI,KAAK,EAAE,aAAa,IAAI,qBAAqB,CAAC;IAC9E,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,IAAI,mBAAmB,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type RunTrackedResult } from "./exec.js";
2
+ export type AnalyzerDepVia = "repo" | "cache" | "absent";
3
+ export interface ResolvedAnalyzerDep {
4
+ via: AnalyzerDepVia;
5
+ /** Absolute path to the resolved package directory (when via != "absent"). */
6
+ path?: string;
7
+ }
8
+ export interface ResolveAnalyzerDepOptions {
9
+ /** Override the cache root; defaults to ~/.audit-tools/analyzer-cache. */
10
+ cacheRoot?: string;
11
+ }
12
+ /** Default shared analyzer cache root. */
13
+ export declare function analyzerCacheRoot(): string;
14
+ interface ParsedSpec {
15
+ name: string;
16
+ version?: string;
17
+ }
18
+ /** Parse "name", "name@version", or "@scope/name@version". */
19
+ export declare function parseAnalyzerSpec(spec: string): ParsedSpec;
20
+ /**
21
+ * Resolve an analyzer dependency: repo node_modules → version-keyed cache →
22
+ * absent. `pkg` may be a bare name or "name@version"; a version narrows the
23
+ * cache lookup, otherwise the newest cached version is chosen.
24
+ */
25
+ export declare function resolveAnalyzerDep(pkg: string, repoRoot: string, options?: ResolveAnalyzerDepOptions): ResolvedAnalyzerDep;
26
+ export interface InstallToCacheOptions {
27
+ cacheRoot?: string;
28
+ /** Injectable command runner; defaults to the shared runTracked. */
29
+ run?: (argv: string[], cwd: string) => RunTrackedResult;
30
+ }
31
+ export interface InstallToCacheResult {
32
+ ok: boolean;
33
+ path?: string;
34
+ error?: string;
35
+ }
36
+ /**
37
+ * Install `pkg@version` into the version-keyed shared cache and return the
38
+ * installed package directory. Requires an explicit version so the cache stays
39
+ * reproducible. Never writes into any audited project.
40
+ */
41
+ export declare function installToCache(pkgAtVersion: string, options?: InstallToCacheOptions): InstallToCacheResult;
42
+ export {};
43
+ //# sourceMappingURL=analyzerDeps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzerDeps.d.ts","sourceRoot":"","sources":["../../src/tooling/analyzerDeps.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAS9D,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,cAAc,CAAC;IACpB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAO1D;AAiDD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,yBAA8B,GACtC,mBAAmB,CAerB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,gBAAgB,CAAC;CACzD;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CAqCtB"}
@@ -0,0 +1,112 @@
1
+ import { existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { runTracked } from "./exec.js";
5
+ /** Default shared analyzer cache root. */
6
+ export function analyzerCacheRoot() {
7
+ return join(homedir(), ".audit-tools", "analyzer-cache");
8
+ }
9
+ /** Parse "name", "name@version", or "@scope/name@version". */
10
+ export function parseAnalyzerSpec(spec) {
11
+ const at = spec.lastIndexOf("@");
12
+ // at === 0 means a bare scoped name like "@scope/name" (no version).
13
+ if (at > 0) {
14
+ return { name: spec.slice(0, at), version: spec.slice(at + 1) };
15
+ }
16
+ return { name: spec };
17
+ }
18
+ // Cache directory key. Scoped package separators are escaped so the key is a
19
+ // single valid directory name (e.g. "@scope/pkg@1.0.0" -> "@scope+pkg@1.0.0").
20
+ function cacheKey(name, version) {
21
+ return `${name.replace(/\//g, "+")}@${version}`;
22
+ }
23
+ function packageDirIn(installDir, name) {
24
+ return join(installDir, "node_modules", ...name.split("/"));
25
+ }
26
+ function isInstalledPackage(packageDir) {
27
+ return existsSync(join(packageDir, "package.json"));
28
+ }
29
+ function findInCache(name, version, cacheRoot) {
30
+ if (!existsSync(cacheRoot))
31
+ return undefined;
32
+ if (version) {
33
+ const installDir = join(cacheRoot, cacheKey(name, version));
34
+ const packageDir = packageDirIn(installDir, name);
35
+ return isInstalledPackage(packageDir) ? packageDir : undefined;
36
+ }
37
+ // No version pinned: pick the highest-sorting matching cache entry that
38
+ // actually contains an installed package. Deterministic via reverse sort.
39
+ const prefix = `${name.replace(/\//g, "+")}@`;
40
+ let entries;
41
+ try {
42
+ entries = readdirSync(cacheRoot);
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ const matches = entries
48
+ .filter((entry) => entry.startsWith(prefix))
49
+ .sort()
50
+ .reverse();
51
+ for (const entry of matches) {
52
+ const packageDir = packageDirIn(join(cacheRoot, entry), name);
53
+ if (isInstalledPackage(packageDir))
54
+ return packageDir;
55
+ }
56
+ return undefined;
57
+ }
58
+ /**
59
+ * Resolve an analyzer dependency: repo node_modules → version-keyed cache →
60
+ * absent. `pkg` may be a bare name or "name@version"; a version narrows the
61
+ * cache lookup, otherwise the newest cached version is chosen.
62
+ */
63
+ export function resolveAnalyzerDep(pkg, repoRoot, options = {}) {
64
+ const { name, version } = parseAnalyzerSpec(pkg);
65
+ const repoPackageDir = join(repoRoot, "node_modules", ...name.split("/"));
66
+ if (isInstalledPackage(repoPackageDir)) {
67
+ return { via: "repo", path: repoPackageDir };
68
+ }
69
+ const cacheRoot = options.cacheRoot ?? analyzerCacheRoot();
70
+ const cached = findInCache(name, version, cacheRoot);
71
+ if (cached) {
72
+ return { via: "cache", path: cached };
73
+ }
74
+ return { via: "absent" };
75
+ }
76
+ /**
77
+ * Install `pkg@version` into the version-keyed shared cache and return the
78
+ * installed package directory. Requires an explicit version so the cache stays
79
+ * reproducible. Never writes into any audited project.
80
+ */
81
+ export function installToCache(pkgAtVersion, options = {}) {
82
+ const { name, version } = parseAnalyzerSpec(pkgAtVersion);
83
+ if (!version) {
84
+ return { ok: false, error: "installToCache requires an explicit version (name@version)" };
85
+ }
86
+ const cacheRoot = options.cacheRoot ?? analyzerCacheRoot();
87
+ const installDir = join(cacheRoot, cacheKey(name, version));
88
+ const run = options.run ?? ((argv, cwd) => runTracked(argv, { cwd }));
89
+ try {
90
+ mkdirSync(installDir, { recursive: true });
91
+ const manifestPath = join(installDir, "package.json");
92
+ if (!existsSync(manifestPath)) {
93
+ writeFileSync(manifestPath, JSON.stringify({ name: "audit-tools-analyzer-cache", private: true }) + "\n", "utf8");
94
+ }
95
+ const result = run(["npm", "install", pkgAtVersion, "--no-audit", "--no-fund", "--save-exact"], installDir);
96
+ if (result.status !== 0) {
97
+ return {
98
+ ok: false,
99
+ error: result.stderr.trim() || `npm install exited with ${result.status}`,
100
+ };
101
+ }
102
+ const packageDir = packageDirIn(installDir, name);
103
+ if (!isInstalledPackage(packageDir)) {
104
+ return { ok: false, error: "package not present after install" };
105
+ }
106
+ return { ok: true, path: packageDir };
107
+ }
108
+ catch (error) {
109
+ return { ok: false, error: error instanceof Error ? error.message : String(error) };
110
+ }
111
+ }
112
+ //# sourceMappingURL=analyzerDeps.js.map