@motivation-labs/crosscheck 0.2.0 → 0.2.1-beta.3838f2a.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/AGENT.md ADDED
@@ -0,0 +1,207 @@
1
+ # AGENT.md — crosscheck optimize harness
2
+
3
+ You are improving crosscheck's AI code review instructions. crosscheck runs `codex` and
4
+ `claude` CLIs to review pull requests automatically. Both reviewers read
5
+ `~/.crosscheck/instructions.md` before every review. Your job is to read the diagnostic
6
+ report below and produce an improved `instructions.md` that increases review quality and
7
+ reduces failures.
8
+
9
+ > **Note:** `crosscheck optimize` selects which agent runs you based on your local config
10
+ > and log history — whichever reviewer has the highest success rate, or `claude` if there
11
+ > is no data. The instructions you produce are reviewer-agnostic: they are read by both
12
+ > `claude` and `codex`, so write in plain language that both understand.
13
+
14
+ ---
15
+
16
+ ## Input you will receive
17
+
18
+ 1. **Diagnostic JSON** from `crosscheck diagnose --json` — error patterns, review outcomes,
19
+ repos seen, language signals, and suggestions.
20
+ 2. **Current `instructions.md`** — may be empty on first run.
21
+
22
+ ## Output you must produce
23
+
24
+ Respond with only the new content of `instructions.md`. No explanation, no preamble, no
25
+ markdown fences — just the file content. The file uses plain Markdown.
26
+
27
+ ---
28
+
29
+ ## Required sections (always present)
30
+
31
+ ### `## Constraints`
32
+ What reviewers must NOT do. Each constraint is one bullet:
33
+ ```
34
+ - Do not run [specific command].
35
+ ```
36
+
37
+ ### `## Focus`
38
+ What reviewers should prioritize. Free-form prose or bullets.
39
+
40
+ ### `## Verdict format` (never modify this section)
41
+ This section must always be preserved exactly as written in the current file. If it is
42
+ missing from the current file, add it verbatim:
43
+
44
+ ```markdown
45
+ ## Verdict format
46
+
47
+ On the very last line of your response, write exactly one of:
48
+
49
+ VERDICT: APPROVE
50
+ VERDICT: NEEDS WORK
51
+ VERDICT: BLOCK
52
+
53
+ Use APPROVE for no issues or trivial nits only.
54
+ Use NEEDS WORK for addressable issues that are not blocking.
55
+ Use BLOCK for security risks, data loss, broken API contracts, or correctness bugs.
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Rules for the `## Constraints` section
61
+
62
+ ### Add a constraint when
63
+ - `diagnostic.errors` contains a `command_not_found` pattern with `count >= 1` for a
64
+ specific command.
65
+ - `diagnostic.errors` contains a `timeout` pattern with `count >= 2` for a reviewer that
66
+ is also producing `command_not_found` entries (likely spinning on a failed tool call).
67
+
68
+ ### Remove a constraint when
69
+ - It was previously added for a specific command but that command no longer appears in
70
+ `diagnostic.errors` and has not appeared for the full log period analyzed.
71
+
72
+ ### Phrasing rules
73
+ - Use the exact command name, not a category. Write `Do not run tsc.` not `Do not run
74
+ TypeScript build tools.`
75
+ - One command per bullet. Do not combine: `Do not run tsc or npm.` → split into two.
76
+ - Do not restrict reading. `Do not open package.json` is wrong. Constraints are for
77
+ execution only.
78
+ - Do not restrict security analysis. Never add a constraint that would prevent a reviewer
79
+ from flagging a vulnerability.
80
+
81
+ ---
82
+
83
+ ## Language detection → constraint mapping
84
+
85
+ Use `diagnostic.languages_detected` (list of detected language/tool identifiers) to seed
86
+ the initial constraints. Add the corresponding constraint only if the language is detected
87
+ AND a related `command_not_found` error is present OR this is the first run with no
88
+ existing constraints.
89
+
90
+ | Detected signal | Constraint to add |
91
+ |---|---|
92
+ | `typescript` / `tsconfig.json` / `package.json` | `Do not run tsc.` |
93
+ | `nodejs` / `package.json` | `Do not run npm, npx, yarn, or pnpm.` |
94
+ | `jest` / `vitest` in devDependencies | `Do not run jest or vitest.` |
95
+ | `python` / `requirements.txt` / `pyproject.toml` | `Do not run pytest, pip, or python scripts.` |
96
+ | `rust` / `Cargo.toml` | `Do not run cargo build or cargo test.` |
97
+ | `go` / `go.mod` | `Do not run go build or go test.` |
98
+ | `java` / `pom.xml` | `Do not run mvn.` |
99
+ | `kotlin` / `gradle` / `build.gradle` | `Do not run gradle.` |
100
+ | `ruby` / `Gemfile` | `Do not run bundle exec or rspec.` |
101
+
102
+ Do not add constraints for languages not detected. Do not add all of the above blindly.
103
+
104
+ ---
105
+
106
+ ## Rules for the `## Focus` section
107
+
108
+ ### Update focus when
109
+ - `diagnostic.verdict_distribution.APPROVE` percentage > 80% across >= 10 reviews → reviews
110
+ may be too lenient → add: "Apply strict scrutiny to error handling and edge cases."
111
+ - `diagnostic.verdict_distribution.BLOCK` percentage > 30% across >= 10 reviews → reviews
112
+ may be too strict → add: "Prefer NEEDS WORK over BLOCK unless the issue causes data loss
113
+ or a security vulnerability."
114
+ - `diagnostic.repos_seen` consistently includes infrastructure repos (name contains
115
+ `-infra`, `-deploy`, `-k8s`) → add: "Pay extra attention to secrets, env vars, and IAM
116
+ permissions in infrastructure changes."
117
+
118
+ ### Default focus (use when no signals override it)
119
+ ```markdown
120
+ ## Focus
121
+
122
+ Review for correctness, security, and maintainability. Flag issues that would cause bugs
123
+ in production, expose sensitive data, or make the code significantly harder to maintain.
124
+ Nits and style preferences should be NEEDS WORK, not BLOCK.
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Quality principles
130
+
131
+ 1. **Minimal** — fewer instructions produce better reviews. Each line must earn its place.
132
+ 2. **Specific** — exact command names, concrete criteria, not vague categories.
133
+ 3. **Evidence-based** — add only what the diagnostic shows is needed or what language
134
+ detection justifies.
135
+ 4. **Reversible** — stale constraints (no matching errors in the log period) should be
136
+ removed, not accumulated.
137
+ 5. **Reviewer-agnostic** — these instructions are read by both `codex` and `claude`. Write
138
+ them in plain language that both understand.
139
+
140
+ ---
141
+
142
+ ## What must never change
143
+
144
+ - The `## Verdict format` section content and label.
145
+ - Instructions that the user has manually annotated with `<!-- keep -->`.
146
+ - The overall Markdown structure (## headings, bullet lists).
147
+
148
+ ---
149
+
150
+ ## Worked example
151
+
152
+ ### Input diagnostic (excerpt)
153
+ ```json
154
+ {
155
+ "summary": { "total_reviews": 6, "successful": 3, "failed": 3, "failure_rate": 0.5 },
156
+ "errors": [
157
+ { "pattern": "command_not_found", "command": "tsc", "count": 2, "reviewer": "codex" },
158
+ { "pattern": "command_not_found", "command": "jest", "count": 1, "reviewer": "codex" },
159
+ { "pattern": "base_branch_missing", "branch": "staging", "count": 2 }
160
+ ],
161
+ "verdict_distribution": { "APPROVE": 2, "NEEDS_WORK": 1, "BLOCK": 0 },
162
+ "languages_detected": ["typescript", "nodejs"],
163
+ "suggestions": [
164
+ { "type": "add_constraint", "instruction": "Do not run tsc.", "reason": "tsc not found ×2" },
165
+ { "type": "add_constraint", "instruction": "Do not run jest.", "reason": "jest not found ×1" }
166
+ ]
167
+ }
168
+ ```
169
+
170
+ ### Input current instructions.md
171
+ ```markdown
172
+ ## Verdict format
173
+
174
+ On the very last line of your response, write exactly one of:
175
+ ...
176
+ ```
177
+
178
+ ### Correct output
179
+ ```markdown
180
+ ## Constraints
181
+
182
+ - Do not run tsc.
183
+ - Do not run jest.
184
+ - Do not run npm, npx, yarn, or pnpm.
185
+
186
+ ## Focus
187
+
188
+ Review for correctness, security, and maintainability. Flag issues that would cause bugs
189
+ in production, expose sensitive data, or make the code significantly harder to maintain.
190
+ Nits and style preferences should be NEEDS WORK, not BLOCK.
191
+
192
+ ## Verdict format
193
+
194
+ On the very last line of your response, write exactly one of:
195
+
196
+ VERDICT: APPROVE
197
+ VERDICT: NEEDS WORK
198
+ VERDICT: BLOCK
199
+
200
+ Use APPROVE for no issues or trivial nits only.
201
+ Use NEEDS WORK for addressable issues that are not blocking.
202
+ Use BLOCK for security risks, data loss, broken API contracts, or correctness bugs.
203
+ ```
204
+
205
+ Note: `Do not run npm, npx, yarn, or pnpm.` was added because `nodejs` was detected, even
206
+ though no npm error appeared yet — this is the language-detection pre-emptive path for
207
+ first-run seeding.
package/dist/cli.js CHANGED
@@ -5,6 +5,8 @@ import { runServe } from './commands/serve.js';
5
5
  import { runWatch } from './commands/watch.js';
6
6
  import { runReview } from './commands/review.js';
7
7
  import { runStatus } from './commands/status.js';
8
+ import { runDiagnose } from './commands/diagnose.js';
9
+ import { runOptimize } from './commands/optimize.js';
8
10
  const program = new Command();
9
11
  program
10
12
  .name('crosscheck')
@@ -36,5 +38,20 @@ program
36
38
  .description('Show auth state, config summary, and CLI versions')
37
39
  .option('-c, --config <path>', 'config file path')
38
40
  .action((opts) => void runStatus(opts.config));
41
+ program
42
+ .command('diagnose')
43
+ .description('Analyze review logs — surface failure patterns, error trends, and improvement suggestions')
44
+ .option('--json', 'output full report as JSON')
45
+ .option('--since <date>', 'only analyze logs from this date onward (YYYY-MM-DD)')
46
+ .action((opts) => void runDiagnose(opts));
47
+ program
48
+ .command('optimize')
49
+ .description('Use AI to improve review instructions based on diagnose output')
50
+ .option('--apply', 'write the improved instructions to ~/.crosscheck/instructions.md')
51
+ .option('--dry-run', 'show diff without writing (default behavior)')
52
+ .option('--agent <vendor>', 'force a specific agent: claude | codex')
53
+ .option('--since <date>', 'limit the diagnose window (YYYY-MM-DD)')
54
+ .option('-c, --config <path>', 'config file path')
55
+ .action((opts) => void runOptimize(opts));
39
56
  program.parse();
40
57
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEhD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;KAC1D,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAE9D,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,+DAA+D,CAAC;KAC5E,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;KACjD,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAE/D,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;KACjD,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAEpE,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;KACjD,MAAM,CAAC,yBAAyB,EAAE,qEAAqE,CAAC;KACxG,MAAM,CAAC,CAAC,KAAa,EAAE,IAA4C,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;AAE7H,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;KACjD,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAErE,OAAO,CAAC,KAAK,EAAE,CAAA"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ type ErrorPattern = 'command_not_found' | 'base_branch_missing' | 'timeout' | 'auth_failure' | 'other';
2
+ interface ErrorEntry {
3
+ pattern: ErrorPattern;
4
+ command?: string;
5
+ branch?: string;
6
+ count: number;
7
+ reviewer?: string;
8
+ }
9
+ interface ReviewerPerf {
10
+ attempts: number;
11
+ successes: number;
12
+ failure_rate: number;
13
+ }
14
+ interface Suggestion {
15
+ type: 'add_constraint' | 'investigate' | 'config_change';
16
+ instruction?: string;
17
+ reason: string;
18
+ }
19
+ export interface DiagnoseReport {
20
+ period: {
21
+ from: string;
22
+ to: string;
23
+ log_files: number;
24
+ };
25
+ summary: {
26
+ total_reviews: number;
27
+ successful: number;
28
+ failed: number;
29
+ failure_rate: number;
30
+ };
31
+ errors: ErrorEntry[];
32
+ verdict_distribution: {
33
+ APPROVE: number;
34
+ NEEDS_WORK: number;
35
+ BLOCK: number;
36
+ };
37
+ repos_seen: string[];
38
+ languages_detected: string[];
39
+ reviewer_performance: Record<string, ReviewerPerf>;
40
+ suggestions: Suggestion[];
41
+ }
42
+ export declare function buildDiagnoseReport(since?: string): DiagnoseReport;
43
+ export declare function runDiagnose(opts: {
44
+ json?: boolean;
45
+ since?: string;
46
+ }): Promise<void>;
47
+ export {};
48
+ //# sourceMappingURL=diagnose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../../src/commands/diagnose.ts"],"names":[],"mappings":"AAOA,KAAK,YAAY,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,SAAS,GAAG,cAAc,GAAG,OAAO,CAAA;AAEtG,UAAU,UAAU;IAClB,OAAO,EAAE,YAAY,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,gBAAgB,GAAG,aAAa,GAAG,eAAe,CAAA;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IACvD,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5F,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,oBAAoB,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAA;IAC5B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAClD,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AA0HD,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,CAoGlE;AAuED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzF"}
@@ -0,0 +1,278 @@
1
+ import { readdirSync, readFileSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import chalk from 'chalk';
5
+ const LOG_DIR = join(homedir(), '.crosscheck', 'logs');
6
+ // Maps command names to language identifiers
7
+ const COMMAND_LANGUAGE_MAP = {
8
+ tsc: ['typescript'], 'ts-node': ['typescript'], tsx: ['typescript'],
9
+ npm: ['nodejs'], npx: ['nodejs'], yarn: ['nodejs'], pnpm: ['nodejs'],
10
+ jest: ['nodejs'], vitest: ['nodejs'], mocha: ['nodejs'],
11
+ pytest: ['python'], pip: ['python'], python: ['python'], python3: ['python'],
12
+ cargo: ['rust'],
13
+ go: ['golang'],
14
+ mvn: ['java'], gradle: ['java'],
15
+ rspec: ['ruby'], bundle: ['ruby'],
16
+ };
17
+ // Language → constraint instruction
18
+ const LANGUAGE_CONSTRAINT_MAP = {
19
+ typescript: 'Do not run tsc, ts-node, or tsx.',
20
+ nodejs: 'Do not run npm, npx, yarn, or pnpm.',
21
+ jest: 'Do not run jest, vitest, or mocha.',
22
+ python: 'Do not run pytest, pip, or python scripts.',
23
+ rust: 'Do not run cargo build or cargo test.',
24
+ golang: 'Do not run go build or go test.',
25
+ java: 'Do not run mvn or gradle.',
26
+ ruby: 'Do not run bundle exec or rspec.',
27
+ };
28
+ function parseLogFile(path) {
29
+ const entries = [];
30
+ const lines = readFileSync(path, 'utf8').split('\n');
31
+ for (const line of lines) {
32
+ if (!line.trim())
33
+ continue;
34
+ try {
35
+ entries.push(JSON.parse(line));
36
+ }
37
+ catch { /* skip malformed */ }
38
+ }
39
+ return entries;
40
+ }
41
+ function classifyError(message, reviewer) {
42
+ const cmdMatch = message.match(/(?:sh:|bash:|zsh:)?\s*([a-zA-Z0-9_-]+):\s*(?:command not found|not found)/i);
43
+ if (cmdMatch)
44
+ return { pattern: 'command_not_found', command: cmdMatch[1].toLowerCase() };
45
+ const branchMatch = message.match(/fatal: no such branch:?\s*'?([^\s'"]+)'?/i);
46
+ if (branchMatch)
47
+ return { pattern: 'base_branch_missing', branch: branchMatch[1] };
48
+ if (/timed? ?out|etimedout/i.test(message))
49
+ return { pattern: 'timeout' };
50
+ if (/bad credentials|401|unauthorized/i.test(message))
51
+ return { pattern: 'auth_failure' };
52
+ return { pattern: 'other' };
53
+ }
54
+ function detectLanguagesFromCommands(errors) {
55
+ const detected = new Set();
56
+ for (const e of errors) {
57
+ if (e.pattern === 'command_not_found' && e.command) {
58
+ const langs = COMMAND_LANGUAGE_MAP[e.command] ?? [];
59
+ for (const l of langs)
60
+ detected.add(l);
61
+ }
62
+ }
63
+ return [...detected];
64
+ }
65
+ function buildSuggestions(errors, languages) {
66
+ const suggestions = [];
67
+ const seen = new Set();
68
+ for (const e of errors) {
69
+ if (e.pattern === 'command_not_found' && e.command) {
70
+ const langs = COMMAND_LANGUAGE_MAP[e.command] ?? [];
71
+ for (const lang of langs) {
72
+ const instruction = LANGUAGE_CONSTRAINT_MAP[lang];
73
+ if (instruction && !seen.has(instruction)) {
74
+ seen.add(instruction);
75
+ suggestions.push({
76
+ type: 'add_constraint',
77
+ instruction,
78
+ reason: `${e.command}: command not found ×${e.count}${e.reviewer ? ` (${e.reviewer})` : ''}`,
79
+ });
80
+ }
81
+ }
82
+ }
83
+ if (e.pattern === 'base_branch_missing' && !seen.has('base_branch_missing')) {
84
+ seen.add('base_branch_missing');
85
+ suggestions.push({
86
+ type: 'investigate',
87
+ reason: `base branch '${e.branch}' not found ×${e.count} — verify the branch is fetched before review`,
88
+ });
89
+ }
90
+ if (e.pattern === 'timeout' && e.count >= 2 && !seen.has('timeout')) {
91
+ seen.add('timeout');
92
+ suggestions.push({
93
+ type: 'config_change',
94
+ reason: `review timed out ×${e.count} — consider lowering quality.tier to "fast" or "balanced"`,
95
+ });
96
+ }
97
+ }
98
+ return suggestions;
99
+ }
100
+ function collectLogFiles(since) {
101
+ if (!existsSync(LOG_DIR))
102
+ return [];
103
+ return readdirSync(LOG_DIR)
104
+ .filter(f => f.endsWith('.ndjson'))
105
+ .filter(f => !since || f.replace('.ndjson', '') >= since)
106
+ .sort()
107
+ .map(f => join(LOG_DIR, f));
108
+ }
109
+ export function buildDiagnoseReport(since) {
110
+ const files = collectLogFiles(since);
111
+ const allEntries = files.flatMap(parseLogFile);
112
+ // Track review lifecycle: review_started → review_complete or error
113
+ const started = new Map(); // key: `${repo}#${pr}`
114
+ const completed = new Set();
115
+ const failed = new Set();
116
+ const errorPatterns = new Map();
117
+ const verdicts = { APPROVE: 0, NEEDS_WORK: 0, BLOCK: 0 };
118
+ const reposSeen = new Set();
119
+ const reviewerStats = new Map();
120
+ for (const e of allEntries) {
121
+ if (e.repo)
122
+ reposSeen.add(e.repo);
123
+ if (e.event === 'review_started') {
124
+ const key = `${e.repo}#${e.pr}`;
125
+ started.set(key, e);
126
+ const r = e.reviewer ?? 'unknown';
127
+ if (!reviewerStats.has(r))
128
+ reviewerStats.set(r, { attempts: 0, successes: 0 });
129
+ reviewerStats.get(r).attempts++;
130
+ }
131
+ if (e.event === 'review_complete') {
132
+ const key = `${e.repo}#${e.pr}`;
133
+ completed.add(key);
134
+ const r = e.reviewer ?? 'unknown';
135
+ reviewerStats.get(r).successes = (reviewerStats.get(r)?.successes ?? 0) + 1;
136
+ if (e.verdict) {
137
+ const v = e.verdict;
138
+ if (v in verdicts)
139
+ verdicts[v]++;
140
+ }
141
+ }
142
+ if (e.event === 'error' && e.level === 'error') {
143
+ const msg = e.message ?? '';
144
+ const { pattern, command, branch } = classifyError(msg);
145
+ // Determine reviewer from message or surrounding context
146
+ const reviewerMatch = msg.match(/^(codex|claude):/i);
147
+ const reviewer = reviewerMatch ? reviewerMatch[1].toLowerCase() : undefined;
148
+ const mapKey = pattern === 'command_not_found' ? `cmd:${command}` : pattern;
149
+ if (errorPatterns.has(mapKey)) {
150
+ errorPatterns.get(mapKey).count++;
151
+ }
152
+ else {
153
+ errorPatterns.set(mapKey, { pattern, command, branch, count: 1, reviewer });
154
+ }
155
+ // Mark the most recent started review as failed
156
+ for (const [key, startEntry] of started.entries()) {
157
+ if (!completed.has(key) && !failed.has(key)) {
158
+ failed.add(key);
159
+ const r = startEntry.reviewer ?? reviewer ?? 'unknown';
160
+ if (reviewerStats.has(r)) {
161
+ // Don't double-count: subtract the attempted that didn't complete
162
+ }
163
+ break;
164
+ }
165
+ }
166
+ }
167
+ }
168
+ const errors = [...errorPatterns.values()].sort((a, b) => b.count - a.count);
169
+ const languages = detectLanguagesFromCommands(errors);
170
+ const suggestions = buildSuggestions(errors, languages);
171
+ const fromDate = files[0]?.split('/').at(-1)?.replace('.ndjson', '') ?? 'N/A';
172
+ const toDate = files.at(-1)?.split('/').at(-1)?.replace('.ndjson', '') ?? 'N/A';
173
+ const totalReviews = started.size;
174
+ const successfulReviews = completed.size;
175
+ const failedReviews = failed.size;
176
+ const reviewer_performance = {};
177
+ for (const [name, stats] of reviewerStats.entries()) {
178
+ reviewer_performance[name] = {
179
+ attempts: stats.attempts,
180
+ successes: stats.successes,
181
+ failure_rate: stats.attempts > 0 ? (stats.attempts - stats.successes) / stats.attempts : 0,
182
+ };
183
+ }
184
+ return {
185
+ period: { from: fromDate, to: toDate, log_files: files.length },
186
+ summary: {
187
+ total_reviews: totalReviews,
188
+ successful: successfulReviews,
189
+ failed: failedReviews,
190
+ failure_rate: totalReviews > 0 ? failedReviews / totalReviews : 0,
191
+ },
192
+ errors,
193
+ verdict_distribution: verdicts,
194
+ repos_seen: [...reposSeen],
195
+ languages_detected: languages,
196
+ reviewer_performance,
197
+ suggestions,
198
+ };
199
+ }
200
+ function pct(n, total) {
201
+ return total === 0 ? '—' : `${Math.round((n / total) * 100)}%`;
202
+ }
203
+ function printReport(report) {
204
+ const { period, summary, errors, verdict_distribution: vd, reviewer_performance: rp, suggestions } = report;
205
+ const total = vd.APPROVE + vd.NEEDS_WORK + vd.BLOCK;
206
+ console.log(chalk.bold('\ncrosscheck diagnose\n'));
207
+ console.log(chalk.dim(` Period ${period.from} → ${period.to} (${period.log_files} log file${period.log_files !== 1 ? 's' : ''})`));
208
+ console.log();
209
+ console.log(chalk.dim(' Reviews'));
210
+ console.log(` total ${summary.total_reviews}`);
211
+ console.log(` successful ${chalk.green(summary.successful)}`);
212
+ console.log(` failed ${summary.failed > 0 ? chalk.red(summary.failed) : chalk.green(summary.failed)} ${summary.failed > 0 ? chalk.dim(`(${pct(summary.failed, summary.total_reviews)} failure rate)`) : ''}`);
213
+ console.log();
214
+ if (Object.keys(rp).length > 0) {
215
+ console.log(chalk.dim(' Reviewer performance'));
216
+ for (const [name, perf] of Object.entries(rp)) {
217
+ const rate = perf.attempts > 0 ? Math.round((perf.successes / perf.attempts) * 100) : 0;
218
+ const indicator = rate >= 80 ? chalk.green(`${rate}%`) : rate >= 50 ? chalk.yellow(`${rate}%`) : chalk.red(`${rate}%`);
219
+ console.log(` ${name.padEnd(8)} ${perf.successes}/${perf.attempts} success ${indicator}`);
220
+ }
221
+ console.log();
222
+ }
223
+ if (total > 0) {
224
+ console.log(chalk.dim(' Verdict distribution'));
225
+ console.log(` APPROVE ${vd.APPROVE} ${chalk.dim(pct(vd.APPROVE, total))}`);
226
+ console.log(` NEEDS WORK ${vd.NEEDS_WORK} ${chalk.dim(pct(vd.NEEDS_WORK, total))}`);
227
+ console.log(` BLOCK ${vd.BLOCK} ${chalk.dim(pct(vd.BLOCK, total))}`);
228
+ console.log();
229
+ }
230
+ if (errors.length > 0) {
231
+ console.log(chalk.dim(' Error patterns'));
232
+ for (const e of errors) {
233
+ const label = e.pattern === 'command_not_found' ? `command not found: ${e.command}`
234
+ : e.pattern === 'base_branch_missing' ? `base branch missing: ${e.branch}`
235
+ : e.pattern;
236
+ console.log(` ${chalk.red('✗')} ${label.padEnd(40)} ×${e.count}${e.reviewer ? chalk.dim(` (${e.reviewer})`) : ''}`);
237
+ }
238
+ console.log();
239
+ }
240
+ if (report.languages_detected.length > 0) {
241
+ console.log(chalk.dim(' Languages detected'));
242
+ console.log(` ${report.languages_detected.join(', ')}`);
243
+ console.log();
244
+ }
245
+ if (suggestions.length > 0) {
246
+ console.log(chalk.dim(' Suggestions'));
247
+ for (const s of suggestions) {
248
+ const icon = s.type === 'add_constraint' ? chalk.yellow('→') : chalk.dim('→');
249
+ console.log(` ${icon} ${s.reason}`);
250
+ if (s.instruction)
251
+ console.log(` ${chalk.cyan(`add to instructions.md: "${s.instruction}"`)}`);
252
+ }
253
+ console.log();
254
+ console.log(chalk.dim(' Run `crosscheck optimize` to apply suggestions automatically.'));
255
+ }
256
+ else if (summary.total_reviews > 0) {
257
+ console.log(chalk.green(' ✓ No actionable issues found.'));
258
+ }
259
+ console.log();
260
+ }
261
+ export async function runDiagnose(opts) {
262
+ if (!existsSync(LOG_DIR)) {
263
+ if (opts.json) {
264
+ console.log(JSON.stringify({ error: 'No log directory found. Run crosscheck watch or serve first.' }));
265
+ }
266
+ else {
267
+ console.error(chalk.yellow('No logs found. Run `crosscheck watch` or `crosscheck serve` first.'));
268
+ }
269
+ return;
270
+ }
271
+ const report = buildDiagnoseReport(opts.since);
272
+ if (opts.json) {
273
+ console.log(JSON.stringify(report, null, 2));
274
+ return;
275
+ }
276
+ printReport(report);
277
+ }
278
+ //# sourceMappingURL=diagnose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../../src/commands/diagnose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Config } from '../config/schema.js';
2
+ import { type DiagnoseReport } from './diagnose.js';
3
+ type Agent = 'claude' | 'codex';
4
+ export declare function selectOptimizeAgent(config: Config, report: DiagnoseReport): {
5
+ agent: Agent;
6
+ reason: string;
7
+ };
8
+ export declare function runOptimize(opts: {
9
+ apply?: boolean;
10
+ dryRun?: boolean;
11
+ since?: string;
12
+ agent?: string;
13
+ config?: string;
14
+ }): Promise<void>;
15
+ export {};
16
+ //# sourceMappingURL=optimize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimize.d.ts","sourceRoot":"","sources":["../../src/commands/optimize.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAOxE,KAAK,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE/B,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,GACrB;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoBlC;AAkED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+FhB"}
@@ -0,0 +1,189 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join, resolve } from 'path';
4
+ import chalk from 'chalk';
5
+ import { execa } from 'execa';
6
+ import { loadConfig } from '../config/loader.js';
7
+ import { readInstructions, writeInstructions, getInstructionsPath } from '../lib/instructions.js';
8
+ import { buildDiagnoseReport } from './diagnose.js';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ // dist/commands/ → ../../ = package root
12
+ const PACKAGE_ROOT = resolve(__dirname, '..', '..');
13
+ export function selectOptimizeAgent(config, report) {
14
+ const enabled = [];
15
+ if (config.vendors.claude.enabled)
16
+ enabled.push('claude');
17
+ if (config.vendors.codex.enabled)
18
+ enabled.push('codex');
19
+ if (enabled.length === 0)
20
+ throw new Error('No vendors enabled in config — enable claude or codex under vendors.');
21
+ if (enabled.length === 1)
22
+ return { agent: enabled[0], reason: `only enabled vendor in config` };
23
+ // Both enabled — pick by success rate from log data
24
+ const cp = report.reviewer_performance['claude'];
25
+ const xp = report.reviewer_performance['codex'];
26
+ if (cp?.attempts > 0 && xp?.attempts > 0) {
27
+ const cr = cp.successes / cp.attempts;
28
+ const xr = xp.successes / xp.attempts;
29
+ if (xr > cr)
30
+ return { agent: 'codex', reason: `codex success rate ${Math.round(xr * 100)}% > claude ${Math.round(cr * 100)}%` };
31
+ if (cr > xr)
32
+ return { agent: 'claude', reason: `claude success rate ${Math.round(cr * 100)}% > codex ${Math.round(xr * 100)}%` };
33
+ }
34
+ return { agent: 'claude', reason: 'default (both enabled, no data or equal rates)' };
35
+ }
36
+ function findAgentMd(cwd) {
37
+ const candidates = [
38
+ join(cwd, 'AGENT.md'),
39
+ join(cwd, '.crosscheck', 'AGENT.md'),
40
+ join(PACKAGE_ROOT, 'AGENT.md'),
41
+ ];
42
+ for (const p of candidates) {
43
+ if (existsSync(p))
44
+ return readFileSync(p, 'utf8');
45
+ }
46
+ throw new Error(`AGENT.md not found. Expected at ${candidates[2]}`);
47
+ }
48
+ // Minimal LCS-based unified diff for display
49
+ function unifiedDiff(oldText, newText) {
50
+ if (oldText === newText)
51
+ return '';
52
+ const a = oldText.split('\n');
53
+ const b = newText.split('\n');
54
+ const m = a.length, n = b.length;
55
+ // LCS via DP
56
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
57
+ for (let i = m - 1; i >= 0; i--)
58
+ for (let j = n - 1; j >= 0; j--)
59
+ dp[i][j] = a[i] === b[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
60
+ const lines = [];
61
+ let i = 0, j = 0;
62
+ while (i < m || j < n) {
63
+ if (i < m && j < n && a[i] === b[j]) {
64
+ lines.push(` ${a[i]}`);
65
+ i++;
66
+ j++;
67
+ }
68
+ else if (j < n && (i >= m || dp[i + 1][j] >= dp[i][j + 1])) {
69
+ lines.push(chalk.green(`+${b[j]}`));
70
+ j++;
71
+ }
72
+ else {
73
+ lines.push(chalk.red(`-${a[i]}`));
74
+ i++;
75
+ }
76
+ }
77
+ return lines.filter(l => !l.startsWith(' ')).length > 0
78
+ ? lines.join('\n')
79
+ : '';
80
+ }
81
+ async function runWithClaude(prompt) {
82
+ const result = await execa('claude', ['--print', '--bare', prompt], {
83
+ timeout: 120_000,
84
+ env: { ...process.env },
85
+ });
86
+ return (result.stdout ?? result.stderr ?? '').trim();
87
+ }
88
+ async function runWithCodex(prompt) {
89
+ // codex supports non-interactive mode via -q (quiet) flag
90
+ try {
91
+ const result = await execa('codex', ['-q', prompt], {
92
+ timeout: 120_000,
93
+ env: { ...process.env },
94
+ });
95
+ return (result.stdout ?? '').trim();
96
+ }
97
+ catch {
98
+ throw new Error('codex does not support non-interactive mode for optimize — use --agent claude or enable claude in config');
99
+ }
100
+ }
101
+ export async function runOptimize(opts) {
102
+ const config = loadConfig(opts.config);
103
+ const cwd = process.cwd();
104
+ // 1. Diagnose
105
+ console.log(chalk.dim(' Running diagnose...'));
106
+ const report = buildDiagnoseReport(opts.since);
107
+ // 2. Select agent
108
+ let selectedAgent;
109
+ let agentReason;
110
+ if (opts.agent === 'claude' || opts.agent === 'codex') {
111
+ selectedAgent = opts.agent;
112
+ agentReason = '--agent flag';
113
+ }
114
+ else {
115
+ try {
116
+ const sel = selectOptimizeAgent(config, report);
117
+ selectedAgent = sel.agent;
118
+ agentReason = sel.reason;
119
+ }
120
+ catch (err) {
121
+ console.error(chalk.red(`✗ ${err instanceof Error ? err.message : String(err)}`));
122
+ process.exit(1);
123
+ }
124
+ }
125
+ console.log(` agent ${chalk.cyan(selectedAgent)} ${chalk.dim(`(${agentReason})`)}`);
126
+ // 3. Load AGENT.md and current instructions
127
+ let agentMd;
128
+ try {
129
+ agentMd = findAgentMd(cwd);
130
+ }
131
+ catch (err) {
132
+ console.error(chalk.red(`✗ ${err instanceof Error ? err.message : String(err)}`));
133
+ process.exit(1);
134
+ }
135
+ const currentInstructions = readInstructions();
136
+ const instructionsPath = getInstructionsPath();
137
+ // 4. Build prompt
138
+ const prompt = [
139
+ agentMd,
140
+ '',
141
+ '---',
142
+ '',
143
+ '## Diagnostic report',
144
+ '',
145
+ '```json',
146
+ JSON.stringify(report, null, 2),
147
+ '```',
148
+ '',
149
+ `## Current ${instructionsPath}`,
150
+ '',
151
+ currentInstructions || '(empty)',
152
+ ].join('\n');
153
+ // 5. Run agent
154
+ console.log(chalk.dim(` Asking ${selectedAgent} to optimize instructions...`));
155
+ let newInstructions;
156
+ try {
157
+ newInstructions = selectedAgent === 'claude'
158
+ ? await runWithClaude(prompt)
159
+ : await runWithCodex(prompt);
160
+ }
161
+ catch (err) {
162
+ console.error(chalk.red(`✗ ${selectedAgent} failed: ${err instanceof Error ? err.message : String(err)}`));
163
+ process.exit(1);
164
+ }
165
+ if (!newInstructions || newInstructions.length < 20) {
166
+ console.error(chalk.red('✗ Agent returned empty or unusable output'));
167
+ process.exit(1);
168
+ }
169
+ // 6. Diff
170
+ const diff = unifiedDiff(currentInstructions, newInstructions);
171
+ if (!diff) {
172
+ console.log(chalk.green('\n ✓ Instructions are already optimal — no changes needed.'));
173
+ return;
174
+ }
175
+ console.log(chalk.bold(`\n diff ${instructionsPath}\n`));
176
+ console.log(diff);
177
+ console.log();
178
+ // 7. Apply or exit
179
+ const apply = opts.apply && !opts.dryRun;
180
+ if (apply) {
181
+ writeInstructions(newInstructions);
182
+ console.log(chalk.green(` ✓ Written to ${instructionsPath}`));
183
+ console.log(chalk.dim(' Next reviews will use the updated instructions.'));
184
+ }
185
+ else {
186
+ console.log(chalk.dim(` Run with --apply to write changes to ${instructionsPath}`));
187
+ }
188
+ }
189
+ //# sourceMappingURL=optimize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimize.js","sourceRoot":"","sources":["../../src/commands/optimize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACjG,OAAO,EAAE,mBAAmB,EAAuB,MAAM,eAAe,CAAA;AAExE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACrC,yCAAyC;AACzC,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAInD,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,MAAsB;IAEtB,MAAM,OAAO,GAAY,EAAE,CAAA;IAC3B,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACzD,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAEvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAA;IACjH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;IAE/F,oDAAoD;IACpD,MAAM,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAA;IAChD,MAAM,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAE/C,IAAI,EAAE,EAAE,QAAQ,GAAG,CAAC,IAAI,EAAE,EAAE,QAAQ,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAA;QACrC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAA;QACrC,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAA;QAC/H,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAA;IAClI,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,gDAAgD,EAAE,CAAA;AACtF,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC;QACrB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,UAAU,CAAC;QACpC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC;KAC/B,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mCAAmC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACrE,CAAC;AAED,6CAA6C;AAC7C,SAAS,WAAW,CAAC,OAAe,EAAE,OAAe;IACnD,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,CAAA;IAElC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;IAEhC,aAAa;IACb,MAAM,EAAE,GAAe,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACpF,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;YAC7B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAE1F,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,CAAC,EAAE,CAAA;QAClC,CAAC;aAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAAC,CAAC,EAAE,CAAA;QAC1C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAAC,CAAC,EAAE,CAAA;QACxC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;QACrD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAClB,CAAC,CAAC,EAAE,CAAA;AACR,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAAc;IACzC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE;QAClE,OAAO,EAAE,OAAO;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;KACxB,CAAC,CAAA;IACF,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;AACtD,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,MAAc;IACxC,0DAA0D;IAC1D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;YAClD,OAAO,EAAE,OAAO;YAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;SACxB,CAAC,CAAA;QACF,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0GAA0G,CAAC,CAAA;IAC7H,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAMjC;IACC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEzB,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAE9C,kBAAkB;IAClB,IAAI,aAAoB,CAAA;IACxB,IAAI,WAAmB,CAAA;IAEvB,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;QACtD,aAAa,GAAG,IAAI,CAAC,KAAK,CAAA;QAC1B,WAAW,GAAG,cAAc,CAAA;IAC9B,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YAC/C,aAAa,GAAG,GAAG,CAAC,KAAK,CAAA;YACzB,WAAW,GAAG,GAAG,CAAC,MAAM,CAAA;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC,CAAA;IAEvF,4CAA4C;IAC5C,IAAI,OAAe,CAAA;IACnB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,mBAAmB,GAAG,gBAAgB,EAAE,CAAA;IAC9C,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAA;IAE9C,kBAAkB;IAClB,MAAM,MAAM,GAAG;QACb,OAAO;QACP,EAAE;QACF,KAAK;QACL,EAAE;QACF,sBAAsB;QACtB,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,KAAK;QACL,EAAE;QACF,cAAc,gBAAgB,EAAE;QAChC,EAAE;QACF,mBAAmB,IAAI,SAAS;KACjC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEZ,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,aAAa,8BAA8B,CAAC,CAAC,CAAA;IAC/E,IAAI,eAAuB,CAAA;IAC3B,IAAI,CAAC;QACH,eAAe,GAAG,aAAa,KAAK,QAAQ;YAC1C,CAAC,CAAC,MAAM,aAAa,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,aAAa,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAA;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,UAAU;IACV,MAAM,IAAI,GAAG,WAAW,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAA;IAE9D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAA;QACvF,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,gBAAgB,IAAI,CAAC,CAAC,CAAA;IAC1D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjB,OAAO,CAAC,GAAG,EAAE,CAAA;IAEb,mBAAmB;IACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;IACxC,IAAI,KAAK,EAAE,CAAC;QACV,iBAAiB,CAAC,eAAe,CAAC,CAAA;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,gBAAgB,EAAE,CAAC,CAAC,CAAA;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC,CAAA;IAC7E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0CAA0C,gBAAgB,EAAE,CAAC,CAAC,CAAA;IACtF,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function readInstructions(repoDir?: string): string;
2
+ export declare function writeInstructions(content: string): void;
3
+ export declare function getInstructionsPath(): string;
4
+ export declare function instructionsExist(): boolean;
5
+ //# sourceMappingURL=instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/lib/instructions.ts"],"names":[],"mappings":"AAqCA,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBzD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGvD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
@@ -0,0 +1,61 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ const CROSSCHECK_DIR = join(homedir(), '.crosscheck');
5
+ const USER_INSTRUCTIONS_PATH = join(CROSSCHECK_DIR, 'instructions.md');
6
+ // Shipped default — conservative constraints that apply to almost every repo.
7
+ // `crosscheck optimize` will refine this over time based on observed failures.
8
+ const DEFAULT_INSTRUCTIONS = `\
9
+ ## Constraints
10
+
11
+ - Do not run tsc, ts-node, or tsx.
12
+ - Do not run npm, npx, yarn, or pnpm.
13
+ - Do not run jest, vitest, mocha, or other test runners.
14
+ - Do not run any build, compile, or install commands.
15
+ - Base your review solely on reading source files and the diff.
16
+
17
+ ## Focus
18
+
19
+ Review for correctness, security, and maintainability. Flag issues that would cause
20
+ bugs in production, expose sensitive data, or make the code significantly harder to
21
+ maintain. Nits and style preferences should be NEEDS WORK, not BLOCK.
22
+
23
+ ## Verdict format
24
+
25
+ On the very last line of your response, write exactly one of:
26
+
27
+ VERDICT: APPROVE
28
+ VERDICT: NEEDS WORK
29
+ VERDICT: BLOCK
30
+
31
+ Use APPROVE for no issues or trivial nits only.
32
+ Use NEEDS WORK for addressable issues that are not blocking.
33
+ Use BLOCK for security risks, data loss, broken API contracts, or correctness bugs.
34
+ `;
35
+ export function readInstructions(repoDir) {
36
+ // Project-level override takes precedence
37
+ if (repoDir) {
38
+ const projectLevel = join(repoDir, '.crosscheck', 'instructions.md');
39
+ if (existsSync(projectLevel)) {
40
+ return readFileSync(projectLevel, 'utf8').trim();
41
+ }
42
+ }
43
+ if (existsSync(USER_INSTRUCTIONS_PATH)) {
44
+ return readFileSync(USER_INSTRUCTIONS_PATH, 'utf8').trim();
45
+ }
46
+ // Seed default on first use so the user can inspect and edit it
47
+ mkdirSync(CROSSCHECK_DIR, { recursive: true });
48
+ writeFileSync(USER_INSTRUCTIONS_PATH, DEFAULT_INSTRUCTIONS, { mode: 0o644 });
49
+ return DEFAULT_INSTRUCTIONS.trim();
50
+ }
51
+ export function writeInstructions(content) {
52
+ mkdirSync(CROSSCHECK_DIR, { recursive: true });
53
+ writeFileSync(USER_INSTRUCTIONS_PATH, content, { mode: 0o644 });
54
+ }
55
+ export function getInstructionsPath() {
56
+ return USER_INSTRUCTIONS_PATH;
57
+ }
58
+ export function instructionsExist() {
59
+ return existsSync(USER_INSTRUCTIONS_PATH);
60
+ }
61
+ //# sourceMappingURL=instructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/lib/instructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAA;AAE5B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAA;AACrD,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAA;AAEtE,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0B5B,CAAA;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,0CAA0C;IAC1C,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAA;QACpE,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,OAAO,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;QAClD,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;QACvC,OAAO,YAAY,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IAC5D,CAAC;IAED,gEAAgE;IAChE,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9C,aAAa,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC5E,OAAO,oBAAoB,CAAC,IAAI,EAAE,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,SAAS,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9C,aAAa,CAAC,sBAAsB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,sBAAsB,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,sBAAsB,CAAC,CAAA;AAC3C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/reviewers/claude.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAetE,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,YAAY,EACpB,eAAe,EAAE,MAAM,EACvB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQhF"}
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/reviewers/claude.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAgBtE,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,YAAY,EACpB,eAAe,EAAE,MAAM,EACvB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAsDjB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQhF"}
@@ -2,6 +2,7 @@ import { execa } from 'execa';
2
2
  import { readFileSync, mkdtempSync } from 'fs';
3
3
  import { tmpdir } from 'os';
4
4
  import { join } from 'path';
5
+ import { readInstructions } from '../lib/instructions.js';
5
6
  const TIER_MODELS = {
6
7
  fast: 'claude-haiku-4-5-20251001',
7
8
  balanced: 'claude-sonnet-4-6',
@@ -20,18 +21,16 @@ export async function runClaudeReview(repoDir, baseBranch, prTitle, quality, ven
20
21
  ? `Focus areas: ${quality.focus.join(', ')}.`
21
22
  : '';
22
23
  const customLine = quality.custom_prompt ?? '';
24
+ // Adaptive instructions from ~/.crosscheck/instructions.md (managed by `crosscheck optimize`)
25
+ const adaptiveInstructions = readInstructions(repoDir);
23
26
  const prompt = [
24
27
  `You are reviewing a pull request titled: "${prTitle}".`,
25
28
  `The branch \`${baseBranch}\` is the base. Review only the changes introduced in this PR.`,
26
29
  focusLine,
27
30
  customLine,
31
+ adaptiveInstructions,
28
32
  'Structure your output as: ## Summary, ## Critical Issues, ## Warnings, ## Suggestions.',
29
33
  'Be concise. Skip praise.',
30
- 'On the very last line of your response, write exactly one of:',
31
- 'VERDICT: APPROVE',
32
- 'VERDICT: NEEDS WORK',
33
- 'VERDICT: BLOCK',
34
- 'Use APPROVE for no issues or trivial nits. Use NEEDS WORK for addressable issues that are not blocking. Use BLOCK for security risks, data loss, broken API contracts, or correctness bugs.',
35
34
  ].filter(Boolean).join('\n');
36
35
  const outputFile = join(mkdtempSync(join(tmpdir(), 'crosscheck-')), 'review.md');
37
36
  const args = [
@@ -1 +1 @@
1
- {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/reviewers/claude.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/reviewers/claude.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAwBxD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,GAAE,cAAc,GAAG,SAA0B,EACrD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CA2DjB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ/E"}
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAyBxD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,GAAE,cAAc,GAAG,SAA0B,EACrD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAmDjB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ/E"}
@@ -2,6 +2,7 @@ import { execa } from 'execa';
2
2
  import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs';
3
3
  import { tmpdir } from 'os';
4
4
  import { join } from 'path';
5
+ import { readInstructions } from '../lib/instructions.js';
5
6
  // Scans stderr bottom-up for the first fatal/error line, skipping Codex header boilerplate.
6
7
  function extractErrorSummary(stderr) {
7
8
  const lines = stderr.split('\n').map(l => l.trim()).filter(Boolean);
@@ -33,17 +34,9 @@ export async function runCodexReview(repoDir, baseBranch, prTitle, quality, over
33
34
  ? `Focus areas: ${quality.focus.join(', ')}. `
34
35
  : '';
35
36
  const customNote = quality.custom_prompt ?? '';
36
- const verdictNote = [
37
- 'On the very last line of your response, write exactly one of:',
38
- 'VERDICT: APPROVE',
39
- 'VERDICT: NEEDS WORK',
40
- 'VERDICT: BLOCK',
41
- 'Use APPROVE for no issues or trivial nits. Use NEEDS WORK for addressable issues that are not blocking. Use BLOCK for security risks, data loss, broken API contracts, or correctness bugs.',
42
- ].join('\n');
43
- // Prevent codex from running build/compile tools that are not installed in the
44
- // temporary clone (no node_modules, no global tsc/jest/etc).
45
- const noBuildToolsNote = 'Do not run tsc, npm, yarn, pnpm, jest, pytest, or any build, compile, or test commands. Base your review solely on reading source files and the diff.';
46
- const instructionsNote = [focusNote, customNote, noBuildToolsNote, verdictNote].filter(Boolean).join('\n\n');
37
+ // Adaptive instructions from ~/.crosscheck/instructions.md (managed by `crosscheck optimize`)
38
+ const adaptiveInstructions = readInstructions(repoDir);
39
+ const instructionsNote = [focusNote, customNote, adaptiveInstructions].filter(Boolean).join('\n\n');
47
40
  mkdirSync(`${repoDir}/.codex`, { recursive: true });
48
41
  writeFileSync(`${repoDir}/.codex/instructions`, instructionsNote);
49
42
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,IAAI,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,4FAA4F;AAC5F,SAAS,mBAAmB,CAAC,MAAc;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACnE,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAClB,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IAC1C,CAAC;IACD,yCAAyC;IACzC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACtB,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QACpB,CAAC,qEAAqE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9E,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAC1B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AACV,CAAC;AAED,sFAAsF;AACtF,MAAM,eAAe,GAA2B;IAC9C,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,IAAI;CACf,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAe,EACf,UAAkB,EAClB,OAAe,EACf,OAAsB,EACtB,aAAsB,EACtB,WAAuC,cAAc,EACrD,KAA6B;IAE7B,qFAAqF;IACrF,MAAM,KAAK,GAAG,QAAQ,KAAK,SAAS;QAClC,CAAC,CAAC,CAAC,aAAa,IAAI,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC/D,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,CAAA;IAE7E,8DAA8D;IAC9D,mEAAmE;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QACxC,CAAC,CAAC,gBAAgB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QAC9C,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAA;IAC9C,MAAM,WAAW,GAAG;QAClB,+DAA+D;QAC/D,kBAAkB;QAClB,qBAAqB;QACrB,gBAAgB;QAChB,6LAA6L;KAC9L,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,+EAA+E;IAC/E,6DAA6D;IAC7D,MAAM,gBAAgB,GAAG,uJAAuJ,CAAA;IAChL,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC5G,SAAS,CAAC,GAAG,OAAO,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,aAAa,CAAC,GAAG,OAAO,sBAAsB,EAAE,gBAAgB,CAAC,CAAA;IAEjE,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACzD,KAAK,EAAE,CAAC,kCAAkC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,cAAc,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAE7F,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,OAAO,EACP,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,EAClE;YACE,GAAG,EAAE,OAAO;YACZ,OAAO,EAAE,OAAO;YAChB,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,yEAAyE;gBACzE,IAAI,EAAE,GAAG,OAAO,sBAAsB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE;aAC/D;SACF,CACF,CAAA;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;IACrD,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,GAAoG,CAAA;QAClH,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;QACpC,MAAM,OAAO,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,eAAe,CAAA;QAClF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,EAAE;YAC3D,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,SAAS;SAClB,CAAC,CAAA;QACF,MAAM,MAAM,CAAA;IACd,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;QACjF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAA;IAC5C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,GAA4C,CAAA;QAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,mBAAmB,EAAE,CAAA;IACpF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motivation-labs/crosscheck",
3
- "version": "0.2.0",
3
+ "version": "0.2.1-beta.3838f2a.0",
4
4
  "description": "Cross-vendor AI code review orchestrator — Claude Code ↔ Codex",
5
5
  "bin": {
6
6
  "crosscheck": "dist/cli.js"
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "dist",
11
11
  "crosscheck.config.example.yml",
12
+ "AGENT.md",
12
13
  "README.md"
13
14
  ],
14
15
  "engines": {