@oddessentials/odd-ai-reviewers 1.7.4 → 1.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.
Files changed (70) hide show
  1. package/dist/agents/ai_semantic_review.d.ts.map +1 -1
  2. package/dist/agents/ai_semantic_review.js +4 -1
  3. package/dist/agents/ai_semantic_review.js.map +1 -1
  4. package/dist/agents/control_flow/safe-source-detector.d.ts +48 -0
  5. package/dist/agents/control_flow/safe-source-detector.d.ts.map +1 -0
  6. package/dist/agents/control_flow/safe-source-detector.js +424 -0
  7. package/dist/agents/control_flow/safe-source-detector.js.map +1 -0
  8. package/dist/agents/control_flow/safe-source-patterns.d.ts +61 -0
  9. package/dist/agents/control_flow/safe-source-patterns.d.ts.map +1 -0
  10. package/dist/agents/control_flow/safe-source-patterns.js +137 -0
  11. package/dist/agents/control_flow/safe-source-patterns.js.map +1 -0
  12. package/dist/agents/control_flow/scope-stack.d.ts +113 -0
  13. package/dist/agents/control_flow/scope-stack.d.ts.map +1 -0
  14. package/dist/agents/control_flow/scope-stack.js +320 -0
  15. package/dist/agents/control_flow/scope-stack.js.map +1 -0
  16. package/dist/agents/control_flow/vulnerability-detector.d.ts +13 -0
  17. package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -1
  18. package/dist/agents/control_flow/vulnerability-detector.js +252 -35
  19. package/dist/agents/control_flow/vulnerability-detector.js.map +1 -1
  20. package/dist/agents/opencode.d.ts.map +1 -1
  21. package/dist/agents/opencode.js +4 -1
  22. package/dist/agents/opencode.js.map +1 -1
  23. package/dist/agents/pr_agent.d.ts.map +1 -1
  24. package/dist/agents/pr_agent.js +5 -2
  25. package/dist/agents/pr_agent.js.map +1 -1
  26. package/dist/agents/security.d.ts.map +1 -1
  27. package/dist/agents/security.js +1 -0
  28. package/dist/agents/security.js.map +1 -1
  29. package/dist/agents/types.d.ts +6 -0
  30. package/dist/agents/types.d.ts.map +1 -1
  31. package/dist/benchmark/adapter.d.ts +39 -0
  32. package/dist/benchmark/adapter.d.ts.map +1 -0
  33. package/dist/benchmark/adapter.js +217 -0
  34. package/dist/benchmark/adapter.js.map +1 -0
  35. package/dist/benchmark/scoring.d.ts +100 -0
  36. package/dist/benchmark/scoring.d.ts.map +1 -0
  37. package/dist/benchmark/scoring.js +195 -0
  38. package/dist/benchmark/scoring.js.map +1 -0
  39. package/dist/context-loader.d.ts +80 -0
  40. package/dist/context-loader.d.ts.map +1 -0
  41. package/dist/context-loader.js +202 -0
  42. package/dist/context-loader.js.map +1 -0
  43. package/dist/main.d.ts.map +1 -1
  44. package/dist/main.js +131 -4
  45. package/dist/main.js.map +1 -1
  46. package/dist/phases/index.d.ts +1 -1
  47. package/dist/phases/index.d.ts.map +1 -1
  48. package/dist/phases/index.js +1 -1
  49. package/dist/phases/index.js.map +1 -1
  50. package/dist/phases/report.d.ts +8 -1
  51. package/dist/phases/report.d.ts.map +1 -1
  52. package/dist/phases/report.js +27 -5
  53. package/dist/phases/report.js.map +1 -1
  54. package/dist/report/ado.d.ts +2 -0
  55. package/dist/report/ado.d.ts.map +1 -1
  56. package/dist/report/ado.js +9 -23
  57. package/dist/report/ado.js.map +1 -1
  58. package/dist/report/finding-validator.d.ts +104 -0
  59. package/dist/report/finding-validator.d.ts.map +1 -0
  60. package/dist/report/finding-validator.js +273 -0
  61. package/dist/report/finding-validator.js.map +1 -0
  62. package/dist/report/github.d.ts +2 -0
  63. package/dist/report/github.d.ts.map +1 -1
  64. package/dist/report/github.js +9 -23
  65. package/dist/report/github.js.map +1 -1
  66. package/dist/trust.d.ts +6 -0
  67. package/dist/trust.d.ts.map +1 -1
  68. package/dist/trust.js +2 -0
  69. package/dist/trust.js.map +1 -1
  70. package/package.json +5 -5
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Benchmark Scoring Module
3
+ *
4
+ * Types and scoring functions for the false-positive regression benchmark.
5
+ * Implements dual-pool scoring (FP suppression rate + TP recall/precision)
6
+ * per benchmark-scenario.md contract.
7
+ */
8
+ // =============================================================================
9
+ // Severity Ranking
10
+ // =============================================================================
11
+ const SEVERITY_RANK = {
12
+ info: 1,
13
+ low: 2,
14
+ medium: 3,
15
+ high: 4,
16
+ critical: 5,
17
+ error: 5,
18
+ warning: 3,
19
+ };
20
+ // =============================================================================
21
+ // Matching Functions
22
+ // =============================================================================
23
+ /**
24
+ * Check if an actual finding matches an expected finding.
25
+ * File match is required; severity, message, and ruleId are optional constraints.
26
+ */
27
+ export function matchFinding(expected, actual) {
28
+ // File match required
29
+ if (actual.file !== expected.file)
30
+ return false;
31
+ // Line match (if specified)
32
+ if (expected.line !== undefined && actual.line !== expected.line)
33
+ return false;
34
+ // Severity match (if specified): actual severity must be >= expected minimum
35
+ if (expected.severityAtLeast !== undefined) {
36
+ const actualRank = SEVERITY_RANK[actual.severity] ?? 0;
37
+ const expectedRank = SEVERITY_RANK[expected.severityAtLeast] ?? 0;
38
+ if (actualRank < expectedRank)
39
+ return false;
40
+ }
41
+ // Message match (if specified): actual message must contain expected substring
42
+ if (expected.messageContains !== undefined) {
43
+ if (!actual.message.toLowerCase().includes(expected.messageContains.toLowerCase()))
44
+ return false;
45
+ }
46
+ // Rule match (if specified)
47
+ if (expected.ruleId !== undefined && actual.ruleId !== expected.ruleId)
48
+ return false;
49
+ return true;
50
+ }
51
+ /**
52
+ * Count the number of defined optional fields on an ExpectedFinding.
53
+ * Used to sort by specificity (most fields first).
54
+ */
55
+ function specificityScore(ef) {
56
+ let score = 0;
57
+ if (ef.line !== undefined)
58
+ score++;
59
+ if (ef.severityAtLeast !== undefined)
60
+ score++;
61
+ if (ef.messageContains !== undefined)
62
+ score++;
63
+ if (ef.ruleId !== undefined)
64
+ score++;
65
+ return score;
66
+ }
67
+ /**
68
+ * 1:1 strict matching of expected findings against actual findings.
69
+ * Sort expected by specificity (most fields first), then consume matched actuals.
70
+ */
71
+ export function matchFindings(expected, actual) {
72
+ // Sort expected by specificity descending (most specific matched first)
73
+ const sortedExpected = [...expected].sort((a, b) => specificityScore(b) - specificityScore(a));
74
+ const consumed = new Set();
75
+ const unmatchedExpected = [];
76
+ let matched = 0;
77
+ for (const exp of sortedExpected) {
78
+ let found = false;
79
+ for (let i = 0; i < actual.length; i++) {
80
+ if (consumed.has(i))
81
+ continue;
82
+ const actualFinding = actual[i];
83
+ if (actualFinding && matchFinding(exp, actualFinding)) {
84
+ consumed.add(i);
85
+ matched++;
86
+ found = true;
87
+ break;
88
+ }
89
+ }
90
+ if (!found) {
91
+ unmatchedExpected.push(exp);
92
+ }
93
+ }
94
+ const extraneous = actual.filter((_, i) => !consumed.has(i));
95
+ return { matched, unmatchedExpected, extraneous };
96
+ }
97
+ // =============================================================================
98
+ // Scoring Functions
99
+ // =============================================================================
100
+ /**
101
+ * Score a single benchmark scenario.
102
+ *
103
+ * - FP scenario (truePositive: false): passed = actualFindings.length === 0
104
+ * - TP scenario (truePositive: true): passed = all expectedFindings matched
105
+ */
106
+ export function scoreScenario(scenario, actualFindings, timedOut = false) {
107
+ if (!scenario.truePositive) {
108
+ // FP scenario: no findings expected
109
+ return {
110
+ id: scenario.id,
111
+ passed: actualFindings.length === 0,
112
+ category: scenario.category,
113
+ pattern: scenario.pattern,
114
+ truePositive: false,
115
+ actualFindings,
116
+ expectedFindings: scenario.expectedFindings,
117
+ matchedCount: 0,
118
+ unmatchedExpected: [],
119
+ extraneousFindings: actualFindings,
120
+ timedOut,
121
+ };
122
+ }
123
+ // TP scenario: all expected findings must match
124
+ const { matched, unmatchedExpected, extraneous } = matchFindings(scenario.expectedFindings, actualFindings);
125
+ return {
126
+ id: scenario.id,
127
+ passed: unmatchedExpected.length === 0,
128
+ category: scenario.category,
129
+ pattern: scenario.pattern,
130
+ truePositive: true,
131
+ actualFindings,
132
+ expectedFindings: scenario.expectedFindings,
133
+ matchedCount: matched,
134
+ unmatchedExpected,
135
+ extraneousFindings: extraneous,
136
+ timedOut,
137
+ };
138
+ }
139
+ /**
140
+ * Compute the aggregate benchmark report from individual scenario results.
141
+ * Pool 1 (FP) and Pool 2 (TP) are scored independently.
142
+ */
143
+ export function computeReport(results) {
144
+ const fpResults = results.filter((r) => !r.truePositive);
145
+ const tpResults = results.filter((r) => r.truePositive);
146
+ // Pool 1: FP Regression
147
+ const trueNegatives = fpResults.filter((r) => r.passed).length;
148
+ const falsePositives = fpResults.length - trueNegatives;
149
+ const suppressionRate = fpResults.length > 0 ? trueNegatives / fpResults.length : 1;
150
+ // Pool 2: TP Preservation
151
+ const totalTpExpected = tpResults.reduce((sum, r) => sum + r.expectedFindings.length, 0);
152
+ const totalTpMatched = tpResults.reduce((sum, r) => sum + r.matchedCount, 0);
153
+ const totalTpFN = totalTpExpected - totalTpMatched;
154
+ const totalExtraneous = tpResults.reduce((sum, r) => sum + r.extraneousFindings.length, 0);
155
+ const recall = totalTpExpected > 0 ? totalTpMatched / totalTpExpected : 1;
156
+ const precision = totalTpMatched + totalExtraneous > 0 ? totalTpMatched / (totalTpMatched + totalExtraneous) : 1;
157
+ // By category
158
+ const byCategory = {};
159
+ for (const r of results) {
160
+ const key = r.category;
161
+ if (!byCategory[key]) {
162
+ byCategory[key] = { total: 0, passed: 0, failed: 0 };
163
+ }
164
+ byCategory[key].total++;
165
+ if (r.passed) {
166
+ byCategory[key].passed++;
167
+ }
168
+ else {
169
+ byCategory[key].failed++;
170
+ }
171
+ }
172
+ return {
173
+ schemaVersion: '1.0.0',
174
+ timestamp: new Date().toISOString(),
175
+ totalScenarios: results.length,
176
+ pool1: {
177
+ total: fpResults.length,
178
+ trueNegatives,
179
+ falsePositives,
180
+ suppressionRate,
181
+ fpRate: 1 - suppressionRate,
182
+ },
183
+ pool2: {
184
+ total: tpResults.length,
185
+ truePositives: totalTpMatched,
186
+ falseNegatives: totalTpFN,
187
+ extraneous: totalExtraneous,
188
+ recall,
189
+ precision,
190
+ },
191
+ byCategory,
192
+ scenarios: results,
193
+ };
194
+ }
195
+ //# sourceMappingURL=scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/benchmark/scoring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Context Loader Module
3
+ *
4
+ * Loads and sanitizes contextual information (project rules, PR description)
5
+ * for injection into agent prompts. Implements FR-006, FR-007, FR-008.
6
+ *
7
+ * Security: All fields are sanitized to prevent prompt injection via
8
+ * null bytes, control characters, and oversized content.
9
+ */
10
+ /**
11
+ * Sanitize a context field by stripping dangerous characters and truncating.
12
+ *
13
+ * @param input - Raw input string
14
+ * @param maxLength - Maximum allowed length (default 2000)
15
+ * @returns Sanitized string
16
+ */
17
+ export declare function sanitizeContextField(input: string, maxLength?: number): string;
18
+ /**
19
+ * Load project rules from CLAUDE.md in the repository root.
20
+ *
21
+ * @param repoPath - Path to the repository root
22
+ * @returns Sanitized CLAUDE.md content, or undefined if not found
23
+ */
24
+ export declare function loadProjectRules(repoPath: string): Promise<string | undefined>;
25
+ /**
26
+ * Load PR description from title and body fields.
27
+ *
28
+ * @param title - PR title
29
+ * @param body - PR body/description
30
+ * @returns Sanitized combined description, or undefined if both empty
31
+ */
32
+ export declare function loadPRDescription(title?: string, body?: string): Promise<string | undefined>;
33
+ /**
34
+ * Extract PR title and body from the GitHub Actions event payload.
35
+ *
36
+ * GitHub Actions sets GITHUB_EVENT_PATH to a JSON file containing the
37
+ * full webhook event. For pull_request events, this includes title and body.
38
+ * Returns undefined fields for non-PR events, missing files, or parse errors.
39
+ *
40
+ * @param eventPath - Path to the event JSON file (from GITHUB_EVENT_PATH)
41
+ * @returns Object with optional title and body, or undefined fields on failure
42
+ */
43
+ export declare function loadGitHubEventPR(eventPath: string | undefined): Promise<{
44
+ title?: string;
45
+ body?: string;
46
+ }>;
47
+ /**
48
+ * Fetch PR title and body from the GitHub API using Octokit.
49
+ *
50
+ * This is the fallback path when GITHUB_EVENT_PATH doesn't contain PR data
51
+ * (e.g., workflow_dispatch triggers, external CI without a pull_request event).
52
+ * Requires owner, repo, PR number, and a valid GITHUB_TOKEN.
53
+ *
54
+ * @param owner - Repository owner
55
+ * @param repo - Repository name
56
+ * @param prNumber - Pull request number
57
+ * @param token - GitHub API token
58
+ * @returns Object with optional title and body, or empty object on failure
59
+ */
60
+ export declare function fetchGitHubPRDetails(owner: string, repo: string, prNumber: number, token: string): Promise<{
61
+ title?: string;
62
+ body?: string;
63
+ }>;
64
+ /**
65
+ * Truncate context fields to fit within a token budget while preserving diff content.
66
+ *
67
+ * Strategy: diff is always preserved; projectRules is truncated first, then prDescription.
68
+ *
69
+ * @param projectRules - Project rules content (may be truncated)
70
+ * @param prDescription - PR description content (may be truncated)
71
+ * @param diffContent - Diff content (always preserved)
72
+ * @param maxTokens - Maximum token budget
73
+ * @returns Truncated fields and whether truncation occurred
74
+ */
75
+ export declare function truncateContext(projectRules: string | undefined, prDescription: string | undefined, diffContent: string, maxTokens: number): {
76
+ projectRules: string | undefined;
77
+ prDescription: string | undefined;
78
+ truncated: boolean;
79
+ };
80
+ //# sourceMappingURL=context-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-loader.d.ts","sourceRoot":"","sources":["../src/context-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAc9E;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQpF;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,CAAC,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW7B;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB5C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB;IACD,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;CACpB,CA4EA"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Context Loader Module
3
+ *
4
+ * Loads and sanitizes contextual information (project rules, PR description)
5
+ * for injection into agent prompts. Implements FR-006, FR-007, FR-008.
6
+ *
7
+ * Security: All fields are sanitized to prevent prompt injection via
8
+ * null bytes, control characters, and oversized content.
9
+ */
10
+ import { readFile } from 'fs/promises';
11
+ import { join } from 'path';
12
+ import { Octokit } from '@octokit/rest';
13
+ /**
14
+ * Sanitize a context field by stripping dangerous characters and truncating.
15
+ *
16
+ * @param input - Raw input string
17
+ * @param maxLength - Maximum allowed length (default 2000)
18
+ * @returns Sanitized string
19
+ */
20
+ export function sanitizeContextField(input, maxLength) {
21
+ // Strip null bytes
22
+ let sanitized = input.replace(/\0/g, '');
23
+ // Remove control characters except \t (0x09), \n (0x0A), \r (0x0D)
24
+ // eslint-disable-next-line no-control-regex
25
+ sanitized = sanitized.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '');
26
+ // Truncate to maxLength
27
+ if (typeof maxLength === 'number' && sanitized.length > maxLength) {
28
+ sanitized = sanitized.slice(0, maxLength);
29
+ }
30
+ return sanitized;
31
+ }
32
+ /**
33
+ * Load project rules from CLAUDE.md in the repository root.
34
+ *
35
+ * @param repoPath - Path to the repository root
36
+ * @returns Sanitized CLAUDE.md content, or undefined if not found
37
+ */
38
+ export async function loadProjectRules(repoPath) {
39
+ try {
40
+ const content = await readFile(join(repoPath, 'CLAUDE.md'), 'utf-8');
41
+ return sanitizeContextField(content);
42
+ }
43
+ catch {
44
+ // File doesn't exist or can't be read - graceful degradation
45
+ return undefined;
46
+ }
47
+ }
48
+ /**
49
+ * Load PR description from title and body fields.
50
+ *
51
+ * @param title - PR title
52
+ * @param body - PR body/description
53
+ * @returns Sanitized combined description, or undefined if both empty
54
+ */
55
+ export async function loadPRDescription(title, body) {
56
+ if (!title && !body) {
57
+ return undefined;
58
+ }
59
+ const parts = [];
60
+ if (title)
61
+ parts.push(title);
62
+ if (body)
63
+ parts.push(body);
64
+ const combined = parts.join('\n\n');
65
+ return sanitizeContextField(combined, 2000);
66
+ }
67
+ /**
68
+ * Extract PR title and body from the GitHub Actions event payload.
69
+ *
70
+ * GitHub Actions sets GITHUB_EVENT_PATH to a JSON file containing the
71
+ * full webhook event. For pull_request events, this includes title and body.
72
+ * Returns undefined fields for non-PR events, missing files, or parse errors.
73
+ *
74
+ * @param eventPath - Path to the event JSON file (from GITHUB_EVENT_PATH)
75
+ * @returns Object with optional title and body, or undefined fields on failure
76
+ */
77
+ export async function loadGitHubEventPR(eventPath) {
78
+ if (!eventPath) {
79
+ return {};
80
+ }
81
+ try {
82
+ const content = await readFile(eventPath, 'utf-8');
83
+ const event = JSON.parse(content);
84
+ // pull_request events have the PR data directly
85
+ const pr = event['pull_request'];
86
+ if (!pr) {
87
+ // Not a pull_request event (e.g., push, schedule) — degrade cleanly
88
+ return {};
89
+ }
90
+ return {
91
+ title: typeof pr['title'] === 'string' ? pr['title'] : undefined,
92
+ body: typeof pr['body'] === 'string' ? pr['body'] : undefined,
93
+ };
94
+ }
95
+ catch {
96
+ // File doesn't exist, can't be read, or JSON is malformed — graceful degradation
97
+ return {};
98
+ }
99
+ }
100
+ /**
101
+ * Fetch PR title and body from the GitHub API using Octokit.
102
+ *
103
+ * This is the fallback path when GITHUB_EVENT_PATH doesn't contain PR data
104
+ * (e.g., workflow_dispatch triggers, external CI without a pull_request event).
105
+ * Requires owner, repo, PR number, and a valid GITHUB_TOKEN.
106
+ *
107
+ * @param owner - Repository owner
108
+ * @param repo - Repository name
109
+ * @param prNumber - Pull request number
110
+ * @param token - GitHub API token
111
+ * @returns Object with optional title and body, or empty object on failure
112
+ */
113
+ export async function fetchGitHubPRDetails(owner, repo, prNumber, token) {
114
+ try {
115
+ const octokit = new Octokit({ auth: token });
116
+ const { data } = await octokit.pulls.get({
117
+ owner,
118
+ repo,
119
+ pull_number: prNumber,
120
+ });
121
+ return {
122
+ title: typeof data.title === 'string' ? data.title : undefined,
123
+ body: typeof data.body === 'string' ? data.body : undefined,
124
+ };
125
+ }
126
+ catch (error) {
127
+ console.warn('[router] [context-loader] Failed to fetch PR details from GitHub API:', error instanceof Error ? error.message : String(error));
128
+ return {};
129
+ }
130
+ }
131
+ /**
132
+ * Truncate context fields to fit within a token budget while preserving diff content.
133
+ *
134
+ * Strategy: diff is always preserved; projectRules is truncated first, then prDescription.
135
+ *
136
+ * @param projectRules - Project rules content (may be truncated)
137
+ * @param prDescription - PR description content (may be truncated)
138
+ * @param diffContent - Diff content (always preserved)
139
+ * @param maxTokens - Maximum token budget
140
+ * @returns Truncated fields and whether truncation occurred
141
+ */
142
+ export function truncateContext(projectRules, prDescription, diffContent, maxTokens) {
143
+ // Estimate: 1 token ~ 4 characters
144
+ const budget = maxTokens * 4;
145
+ const total = (projectRules?.length ?? 0) + (prDescription?.length ?? 0) + diffContent.length;
146
+ // If total fits within 90% of budget, no truncation needed
147
+ if (total <= budget * 0.9) {
148
+ return { projectRules, prDescription, truncated: false };
149
+ }
150
+ // Context budget = 90% of total budget minus diff (diff is always preserved)
151
+ const contextBudget = budget * 0.9 - diffContent.length;
152
+ if (contextBudget <= 0) {
153
+ // No room for context at all
154
+ if (projectRules || prDescription) {
155
+ console.log('[router] [context-loader] No budget remaining for context fields after diff allocation');
156
+ }
157
+ return { projectRules: undefined, prDescription: undefined, truncated: true };
158
+ }
159
+ let truncatedRules = projectRules;
160
+ let truncatedDesc = prDescription;
161
+ let truncated = false;
162
+ // Truncate projectRules first
163
+ const TRUNCATION_MARKER = ' [truncated]';
164
+ if (truncatedRules && truncatedRules.length > contextBudget) {
165
+ const originalSize = truncatedRules.length;
166
+ if (contextBudget < TRUNCATION_MARKER.length) {
167
+ // Budget too small for even the marker — drop the field entirely
168
+ truncatedRules = undefined;
169
+ console.log(`[router] [context-loader] Truncated projectRules: ${originalSize} -> 0 chars (budget too small for marker)`);
170
+ }
171
+ else {
172
+ const sliceLimit = contextBudget - TRUNCATION_MARKER.length;
173
+ truncatedRules = truncatedRules.slice(0, sliceLimit) + TRUNCATION_MARKER;
174
+ console.log(`[router] [context-loader] Truncated projectRules: ${originalSize} -> ${truncatedRules.length} chars`);
175
+ }
176
+ truncated = true;
177
+ }
178
+ // Calculate remaining budget after projectRules
179
+ const rulesSize = truncatedRules?.length ?? 0;
180
+ const remainingBudget = contextBudget - rulesSize;
181
+ // Truncate prDescription if needed
182
+ if (truncatedDesc && truncatedDesc.length > remainingBudget) {
183
+ if (remainingBudget <= 0) {
184
+ console.log(`[router] [context-loader] Truncated prDescription: ${truncatedDesc.length} -> 0 chars (no budget)`);
185
+ truncatedDesc = undefined;
186
+ }
187
+ else if (remainingBudget < TRUNCATION_MARKER.length) {
188
+ // Budget too small for even the marker — drop the field entirely
189
+ console.log(`[router] [context-loader] Truncated prDescription: ${truncatedDesc.length} -> 0 chars (budget too small for marker)`);
190
+ truncatedDesc = undefined;
191
+ }
192
+ else {
193
+ const originalSize = truncatedDesc.length;
194
+ const descSliceLimit = remainingBudget - TRUNCATION_MARKER.length;
195
+ truncatedDesc = truncatedDesc.slice(0, descSliceLimit) + TRUNCATION_MARKER;
196
+ console.log(`[router] [context-loader] Truncated prDescription: ${originalSize} -> ${truncatedDesc.length} chars`);
197
+ }
198
+ truncated = true;
199
+ }
200
+ return { projectRules: truncatedRules, prDescription: truncatedDesc, truncated };
201
+ }
202
+ //# sourceMappingURL=context-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-loader.js","sourceRoot":"","sources":["../src/context-loader.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AA8BH,OAAO,EAOL,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAC;AAO3B;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAEhC,CAAC;AAshBF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,QAAQ,CAIhF;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,oEAAoE;IACpE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,aAAa,EACtB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Rf"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAsCH,OAAO,EAQL,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAC;AAO3B;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAEhC,CAAC;AAuoBF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,QAAQ,CAIhF;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,oEAAoE;IACpE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,aAAa,EACtB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA0Uf"}