@motivation-labs/crosscheck 0.3.1-beta.4fbfe4e.0 → 0.3.1-beta.76cee70.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/README.md +0 -2
- package/dist/cli.js +0 -9
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/dist/__tests__/issue.test.d.ts +0 -2
- package/dist/__tests__/issue.test.d.ts.map +0 -1
- package/dist/__tests__/issue.test.js +0 -244
- package/dist/__tests__/issue.test.js.map +0 -1
- package/dist/commands/issue.d.ts +0 -23
- package/dist/commands/issue.d.ts.map +0 -1
- package/dist/commands/issue.js +0 -284
- package/dist/commands/issue.js.map +0 -1
- package/dist/lib/log-analysis.d.ts +0 -17
- package/dist/lib/log-analysis.d.ts.map +0 -1
- package/dist/lib/log-analysis.js +0 -72
- package/dist/lib/log-analysis.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
<img src="./assets/logo.png" alt="crosscheck" width="160" />
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
|
-
<p align="center"><em>Building crosscheck with crosscheck.</em></p>
|
|
10
|
-
|
|
11
9
|
# crosscheck
|
|
12
10
|
|
|
13
11
|
**A lightweight orchestration layer that makes your AI coding agents review each other's work — then fix it.**
|
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,6 @@ import { runStatus } from './commands/status.js';
|
|
|
11
11
|
import { runDiagnose } from './commands/diagnose.js';
|
|
12
12
|
import { runOptimize } from './commands/optimize.js';
|
|
13
13
|
import { runImpact } from './commands/impact.js';
|
|
14
|
-
import { runIssue } from './commands/issue.js';
|
|
15
14
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
15
|
const { version } = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
17
16
|
const program = new Command();
|
|
@@ -68,13 +67,5 @@ program
|
|
|
68
67
|
.option('--money', 'include a rough monetary estimate')
|
|
69
68
|
.option('-c, --config <path>', 'config file path')
|
|
70
69
|
.action((opts) => void runImpact(opts));
|
|
71
|
-
program
|
|
72
|
-
.command('issue')
|
|
73
|
-
.description('Detect errors in recent logs, draft a GitHub issue with AI, and submit after confirmation')
|
|
74
|
-
.option('--since <date>', 'only look at logs from this date onward (YYYY-MM-DD, default: 3 days ago)')
|
|
75
|
-
.option('--dry-run', 'print the draft without submitting')
|
|
76
|
-
.option('-y, --yes', 'skip interactive questions and confirmation')
|
|
77
|
-
.option('-c, --config <path>', 'config file path')
|
|
78
|
-
.action((opts) => void runIssue(opts));
|
|
79
70
|
program.parse();
|
|
80
71
|
//# 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,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AACpC,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;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/issue.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { sanitizeEntry, loadErrorEntriesForPattern, sanitizeDraftContent } from '../lib/log-analysis.js';
|
|
5
|
-
import { parseDraft, buildIssueContent } from '../commands/issue.js';
|
|
6
|
-
const FIXTURES_DIR = join(fileURLToPath(import.meta.url), '..', 'fixtures');
|
|
7
|
-
// ──────────────────────────────────────────────────────
|
|
8
|
-
// sanitizeEntry
|
|
9
|
-
// ──────────────────────────────────────────────────────
|
|
10
|
-
describe('sanitizeEntry', () => {
|
|
11
|
-
it('replaces repo field with [repo]', () => {
|
|
12
|
-
const entry = { ts: '', level: 'error', event: 'error', repo: 'acme/api' };
|
|
13
|
-
expect(sanitizeEntry(entry).repo).toBe('[repo]');
|
|
14
|
-
});
|
|
15
|
-
it('leaves repo undefined when absent', () => {
|
|
16
|
-
const entry = { ts: '', level: 'error', event: 'error' };
|
|
17
|
-
expect(sanitizeEntry(entry).repo).toBeUndefined();
|
|
18
|
-
});
|
|
19
|
-
it('sanitizes owner/repo pattern in message', () => {
|
|
20
|
-
const entry = {
|
|
21
|
-
ts: '', level: 'error', event: 'error',
|
|
22
|
-
message: 'failed cloning motivation-labs/crosscheck',
|
|
23
|
-
};
|
|
24
|
-
expect(sanitizeEntry(entry).message).toContain('[repo]');
|
|
25
|
-
expect(sanitizeEntry(entry).message).not.toContain('motivation-labs/crosscheck');
|
|
26
|
-
});
|
|
27
|
-
it('sanitizes GitHub URLs in message', () => {
|
|
28
|
-
const entry = {
|
|
29
|
-
ts: '', level: 'error', event: 'error',
|
|
30
|
-
message: 'see https://github.com/owner/repo/issues/42',
|
|
31
|
-
};
|
|
32
|
-
expect(sanitizeEntry(entry).message).toContain('[github-url]');
|
|
33
|
-
expect(sanitizeEntry(entry).message).not.toContain('github.com');
|
|
34
|
-
});
|
|
35
|
-
it('sanitizes @username in message', () => {
|
|
36
|
-
const entry = {
|
|
37
|
-
ts: '', level: 'error', event: 'error',
|
|
38
|
-
message: 'PR opened by @johndoe',
|
|
39
|
-
};
|
|
40
|
-
expect(sanitizeEntry(entry).message).toContain('[username]');
|
|
41
|
-
expect(sanitizeEntry(entry).message).not.toContain('@johndoe');
|
|
42
|
-
});
|
|
43
|
-
it('sanitizes absolute file paths in message', () => {
|
|
44
|
-
const entry = {
|
|
45
|
-
ts: '', level: 'error', event: 'error',
|
|
46
|
-
message: 'Error reading /home/user/project/src/index.ts',
|
|
47
|
-
};
|
|
48
|
-
expect(sanitizeEntry(entry).message).toContain('[file-path]');
|
|
49
|
-
});
|
|
50
|
-
it('leaves non-sensitive fields unchanged', () => {
|
|
51
|
-
const entry = { ts: '2026-01-01T00:00:00Z', level: 'error', event: 'error', pr: 42 };
|
|
52
|
-
const out = sanitizeEntry(entry);
|
|
53
|
-
expect(out.ts).toBe('2026-01-01T00:00:00Z');
|
|
54
|
-
expect(out.pr).toBe(42);
|
|
55
|
-
});
|
|
56
|
-
it('sanitizes stack trace with file paths', () => {
|
|
57
|
-
const entry = {
|
|
58
|
-
ts: '', level: 'error', event: 'error',
|
|
59
|
-
stack: 'Error: failed\n at Object.<anonymous> (/Users/user/projects/app/src/index.ts:10:5)',
|
|
60
|
-
};
|
|
61
|
-
expect(sanitizeEntry(entry).stack).not.toContain('/Users/user/projects/app/src/index.ts');
|
|
62
|
-
expect(sanitizeEntry(entry).stack).toContain('[file-path]');
|
|
63
|
-
});
|
|
64
|
-
it('sanitizes stderr field with repo name', () => {
|
|
65
|
-
const entry = {
|
|
66
|
-
ts: '', level: 'error', event: 'error',
|
|
67
|
-
stderr: 'fatal: repository acme/backend not found',
|
|
68
|
-
};
|
|
69
|
-
expect(sanitizeEntry(entry).stderr).not.toContain('acme/backend');
|
|
70
|
-
expect(sanitizeEntry(entry).stderr).toContain('[repo]');
|
|
71
|
-
});
|
|
72
|
-
it('sanitizes command field with file path', () => {
|
|
73
|
-
const entry = {
|
|
74
|
-
ts: '', level: 'error', event: 'error',
|
|
75
|
-
command: 'codex review /tmp/crosscheck-abc123/acme-api/src/main.ts',
|
|
76
|
-
};
|
|
77
|
-
expect(sanitizeEntry(entry).command).not.toContain('/tmp/crosscheck-abc123/acme-api/src/main.ts');
|
|
78
|
-
expect(sanitizeEntry(entry).command).toContain('[file-path]');
|
|
79
|
-
});
|
|
80
|
-
it('does not mutate the original entry', () => {
|
|
81
|
-
const entry = { ts: '', level: 'error', event: 'error', repo: 'acme/api' };
|
|
82
|
-
sanitizeEntry(entry);
|
|
83
|
-
expect(entry.repo).toBe('acme/api');
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
// ──────────────────────────────────────────────────────
|
|
87
|
-
// sanitizeDraftContent
|
|
88
|
-
// ──────────────────────────────────────────────────────
|
|
89
|
-
describe('sanitizeDraftContent', () => {
|
|
90
|
-
it('strips repo name from title', () => {
|
|
91
|
-
const { title } = sanitizeDraftContent('Bug in acme/api causes crash', '');
|
|
92
|
-
expect(title).not.toContain('acme/api');
|
|
93
|
-
expect(title).toContain('[repo]');
|
|
94
|
-
});
|
|
95
|
-
it('strips GitHub URL from body', () => {
|
|
96
|
-
const { body } = sanitizeDraftContent('', 'See https://github.com/acme/api/issues/12 for context.');
|
|
97
|
-
expect(body).not.toContain('github.com');
|
|
98
|
-
expect(body).toContain('[github-url]');
|
|
99
|
-
});
|
|
100
|
-
it('strips file path from body', () => {
|
|
101
|
-
const { body } = sanitizeDraftContent('', 'Error at /home/user/project/src/index.ts:42');
|
|
102
|
-
expect(body).toContain('[file-path]');
|
|
103
|
-
});
|
|
104
|
-
it('leaves clean content unchanged', () => {
|
|
105
|
-
const { title, body } = sanitizeDraftContent('codex reviewer exits with command not found', '## Description\nThe reviewer fails.');
|
|
106
|
-
expect(title).toBe('codex reviewer exits with command not found');
|
|
107
|
-
expect(body).toContain('## Description');
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
// ──────────────────────────────────────────────────────
|
|
111
|
-
// loadErrorEntriesForPattern
|
|
112
|
-
// ──────────────────────────────────────────────────────
|
|
113
|
-
describe('loadErrorEntriesForPattern', () => {
|
|
114
|
-
it('returns empty array when log dir does not exist', () => {
|
|
115
|
-
const result = loadErrorEntriesForPattern('command_not_found', 'tsc', undefined, '/nonexistent');
|
|
116
|
-
expect(result).toHaveLength(0);
|
|
117
|
-
});
|
|
118
|
-
it('returns matching entries for command_not_found tsc from fixtures', () => {
|
|
119
|
-
const result = loadErrorEntriesForPattern('command_not_found', 'tsc', undefined, FIXTURES_DIR);
|
|
120
|
-
expect(result.length).toBeGreaterThan(0);
|
|
121
|
-
expect(result.every(e => e.event === 'error')).toBe(true);
|
|
122
|
-
expect(result.every(e => e.message?.includes('tsc'))).toBe(true);
|
|
123
|
-
});
|
|
124
|
-
it('returns entries for jest command_not_found from fixtures', () => {
|
|
125
|
-
const result = loadErrorEntriesForPattern('command_not_found', 'jest', undefined, FIXTURES_DIR);
|
|
126
|
-
expect(result.length).toBeGreaterThan(0);
|
|
127
|
-
expect(result.every(e => e.message?.includes('jest'))).toBe(true);
|
|
128
|
-
});
|
|
129
|
-
it('returns empty for a pattern not present in fixtures', () => {
|
|
130
|
-
const result = loadErrorEntriesForPattern('auth_failure', undefined, undefined, FIXTURES_DIR);
|
|
131
|
-
expect(result).toHaveLength(0);
|
|
132
|
-
});
|
|
133
|
-
it('caps results at 5 entries', () => {
|
|
134
|
-
// Generate a logDir with many matching entries to verify the cap
|
|
135
|
-
// Use fixtures — has at most a few so won't exceed 5 anyway, but test the cap holds
|
|
136
|
-
const result = loadErrorEntriesForPattern('command_not_found', 'tsc', undefined, FIXTURES_DIR);
|
|
137
|
-
expect(result.length).toBeLessThanOrEqual(5);
|
|
138
|
-
});
|
|
139
|
-
it('respects since filter', () => {
|
|
140
|
-
// Only 2026-01-11 entries
|
|
141
|
-
const result = loadErrorEntriesForPattern('command_not_found', undefined, '2026-01-11', FIXTURES_DIR);
|
|
142
|
-
// 2026-01-10 has tsc and jest errors, 2026-01-11 has base_branch errors
|
|
143
|
-
// so command_not_found from 2026-01-11 only should be empty or fewer
|
|
144
|
-
expect(result.length).toBeLessThanOrEqual(5);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
// ──────────────────────────────────────────────────────
|
|
148
|
-
// parseDraft
|
|
149
|
-
// ──────────────────────────────────────────────────────
|
|
150
|
-
describe('parseDraft', () => {
|
|
151
|
-
it('extracts title and body from well-formed output', () => {
|
|
152
|
-
const output = [
|
|
153
|
-
'TITLE: codex reviewer fails on TypeScript repos',
|
|
154
|
-
'---',
|
|
155
|
-
'## Description',
|
|
156
|
-
'The codex reviewer exits with command not found.',
|
|
157
|
-
].join('\n');
|
|
158
|
-
const result = parseDraft(output);
|
|
159
|
-
expect(result).not.toBeNull();
|
|
160
|
-
expect(result.title).toBe('codex reviewer fails on TypeScript repos');
|
|
161
|
-
expect(result.body).toContain('## Description');
|
|
162
|
-
});
|
|
163
|
-
it('handles leading blank lines before TITLE', () => {
|
|
164
|
-
const output = '\n\nTITLE: my title\n---\nbody here';
|
|
165
|
-
const result = parseDraft(output);
|
|
166
|
-
expect(result?.title).toBe('my title');
|
|
167
|
-
expect(result?.body).toBe('body here');
|
|
168
|
-
});
|
|
169
|
-
it('returns null when TITLE line is missing', () => {
|
|
170
|
-
const output = 'no title line here\n---\nbody';
|
|
171
|
-
expect(parseDraft(output)).toBeNull();
|
|
172
|
-
});
|
|
173
|
-
it('returns null when separator is missing', () => {
|
|
174
|
-
const output = 'TITLE: some title\nbody without separator';
|
|
175
|
-
expect(parseDraft(output)).toBeNull();
|
|
176
|
-
});
|
|
177
|
-
it('returns null when title is empty', () => {
|
|
178
|
-
const output = 'TITLE: \n---\nbody';
|
|
179
|
-
expect(parseDraft(output)).toBeNull();
|
|
180
|
-
});
|
|
181
|
-
it('returns null when body is empty', () => {
|
|
182
|
-
const output = 'TITLE: title\n---\n ';
|
|
183
|
-
expect(parseDraft(output)).toBeNull();
|
|
184
|
-
});
|
|
185
|
-
it('handles multi-line body', () => {
|
|
186
|
-
const body = '## Description\nline one\nline two\n\n## Steps\n1. step one';
|
|
187
|
-
const output = `TITLE: title\n---\n${body}`;
|
|
188
|
-
const result = parseDraft(output);
|
|
189
|
-
expect(result?.body).toBe(body);
|
|
190
|
-
});
|
|
191
|
-
it('uses the first --- separator after the TITLE line', () => {
|
|
192
|
-
const output = 'TITLE: t\n---\n## Section\nsome --- in content\nmore content';
|
|
193
|
-
const result = parseDraft(output);
|
|
194
|
-
expect(result?.body).toContain('some --- in content');
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
// ──────────────────────────────────────────────────────
|
|
198
|
-
// buildIssueContent
|
|
199
|
-
// ──────────────────────────────────────────────────────
|
|
200
|
-
describe('buildIssueContent', () => {
|
|
201
|
-
const draft = {
|
|
202
|
-
title: 'codex fails on tsc',
|
|
203
|
-
body: '## Description\nSomething broke.',
|
|
204
|
-
};
|
|
205
|
-
it('preserves the title unchanged', () => {
|
|
206
|
-
const { title } = buildIssueContent(draft, {
|
|
207
|
-
reproducibility: 'Every time',
|
|
208
|
-
trigger: 'watch',
|
|
209
|
-
impact: 'Blocked',
|
|
210
|
-
});
|
|
211
|
-
expect(title).toBe('codex fails on tsc');
|
|
212
|
-
});
|
|
213
|
-
it('appends User Context section to body', () => {
|
|
214
|
-
const { body } = buildIssueContent(draft, {
|
|
215
|
-
reproducibility: 'Sometimes',
|
|
216
|
-
trigger: 'watch',
|
|
217
|
-
impact: 'Degraded',
|
|
218
|
-
});
|
|
219
|
-
expect(body).toContain('## User Context');
|
|
220
|
-
expect(body).toContain('Sometimes');
|
|
221
|
-
expect(body).toContain('watch');
|
|
222
|
-
expect(body).toContain('Degraded');
|
|
223
|
-
});
|
|
224
|
-
it('original draft body is preserved in output', () => {
|
|
225
|
-
const { body } = buildIssueContent(draft, {
|
|
226
|
-
reproducibility: 'Once',
|
|
227
|
-
trigger: 'review',
|
|
228
|
-
impact: 'Cosmetic',
|
|
229
|
-
});
|
|
230
|
-
expect(body).toContain('## Description');
|
|
231
|
-
expect(body).toContain('Something broke.');
|
|
232
|
-
});
|
|
233
|
-
it('all three answer fields appear in User Context', () => {
|
|
234
|
-
const { body } = buildIssueContent(draft, {
|
|
235
|
-
reproducibility: 'Every time',
|
|
236
|
-
trigger: 'serve',
|
|
237
|
-
impact: 'Blocked',
|
|
238
|
-
});
|
|
239
|
-
expect(body).toContain('Every time');
|
|
240
|
-
expect(body).toContain('serve');
|
|
241
|
-
expect(body).toContain('Blocked');
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
//# sourceMappingURL=issue.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue.test.js","sourceRoot":"","sources":["../../src/__tests__/issue.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,oBAAoB,EAAoB,MAAM,wBAAwB,CAAA;AAC1H,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAEpE,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;AAE3E,yDAAyD;AACzD,gBAAgB;AAChB,yDAAyD;AAEzD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,KAAK,GAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;QACvF,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,KAAK,GAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;QACrE,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,OAAO,EAAE,2CAA2C;SACrD,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QACxD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAA;IAClF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,OAAO,EAAE,6CAA6C;SACvD,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;QAC9D,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,OAAO,EAAE,uBAAuB;SACjC,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;QAC5D,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,OAAO,EAAE,+CAA+C;SACzD,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAgB,EAAE,EAAE,EAAE,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA;QACjG,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QAChC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,KAAK,EAAE,uFAAuF;SAC/F,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAA;QACzF,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,MAAM,EAAE,0CAA0C;SACnD,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;QACjE,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,KAAK,GAAgB;YACzB,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;YACtC,OAAO,EAAE,0DAA0D;SACpE,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,6CAA6C,CAAC,CAAA;QACjG,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,KAAK,GAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;QACvF,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,yDAAyD;AACzD,uBAAuB;AACvB,yDAAyD;AAEzD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,EAAE,KAAK,EAAE,GAAG,oBAAoB,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAA;QAC1E,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,EAAE,EAAE,wDAAwD,CAAC,CAAA;QACnG,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;QACxC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,EAAE,EAAE,6CAA6C,CAAC,CAAA;QACxF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,6CAA6C,EAAE,qCAAqC,CAAC,CAAA;QAClI,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;QACjE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,yDAAyD;AACzD,6BAA6B;AAC7B,yDAAyD;AAEzD,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;QAChG,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,MAAM,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC,CAAA;QAC9F,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,MAAM,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,CAAA;QAC/F,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG,0BAA0B,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,CAAA;QAC7F,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,iEAAiE;QACjE,oFAAoF;QACpF,MAAM,MAAM,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC,CAAA;QAC9F,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,0BAA0B;QAC1B,MAAM,MAAM,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;QACrG,wEAAwE;QACxE,qEAAqE;QACrE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,yDAAyD;AACzD,aAAa;AACb,yDAAyD;AAEzD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG;YACb,iDAAiD;YACjD,KAAK;YACL,gBAAgB;YAChB,kDAAkD;SACnD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;QAC7B,MAAM,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;QACtE,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,qCAAqC,CAAA;QACpD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,+BAA+B,CAAA;QAC9C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG,2CAA2C,CAAA;QAC1D,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAG,sBAAsB,CAAA;QACrC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAG,wBAAwB,CAAA;QACvC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,IAAI,GAAG,6DAA6D,CAAA;QAC1E,MAAM,MAAM,GAAG,sBAAsB,IAAI,EAAE,CAAA;QAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,8DAA8D,CAAA;QAC7E,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,yDAAyD;AACzD,oBAAoB;AACpB,yDAAyD;AAEzD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,KAAK,GAAG;QACZ,KAAK,EAAE,oBAAoB;QAC3B,IAAI,EAAE,kCAAkC;KACzC,CAAA;IAED,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE;YACzC,eAAe,EAAE,YAAY;YAC7B,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,SAAS;SAClB,CAAC,CAAA;QACF,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE;YACxC,eAAe,EAAE,WAAW;YAC5B,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,UAAU;SACnB,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QACzC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;QACnC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE;YACxC,eAAe,EAAE,MAAM;YACvB,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,UAAU;SACnB,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAA;QACxC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE;YACxC,eAAe,EAAE,YAAY;YAC7B,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,SAAS;SAClB,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
package/dist/commands/issue.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface QuestionAnswers {
|
|
2
|
-
reproducibility: string;
|
|
3
|
-
trigger: string;
|
|
4
|
-
impact: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function parseDraft(output: string): {
|
|
7
|
-
title: string;
|
|
8
|
-
body: string;
|
|
9
|
-
} | null;
|
|
10
|
-
export declare function buildIssueContent(draft: {
|
|
11
|
-
title: string;
|
|
12
|
-
body: string;
|
|
13
|
-
}, answers: QuestionAnswers): {
|
|
14
|
-
title: string;
|
|
15
|
-
body: string;
|
|
16
|
-
};
|
|
17
|
-
export declare function runIssue(opts: {
|
|
18
|
-
since?: string;
|
|
19
|
-
dryRun?: boolean;
|
|
20
|
-
yes?: boolean;
|
|
21
|
-
config?: string;
|
|
22
|
-
}): Promise<void>;
|
|
23
|
-
//# sourceMappingURL=issue.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/commands/issue.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkBjF;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACtC,OAAO,EAAE,eAAe,GACvB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUjC;AAqHD,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyKhB"}
|
package/dist/commands/issue.js
DELETED
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdtempSync, writeFileSync, rmSync, readFileSync } from 'fs';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
import { dirname, join, resolve } from 'path';
|
|
4
|
-
import { homedir, platform, tmpdir } from 'os';
|
|
5
|
-
import { createInterface } from 'readline';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
import { execa } from 'execa';
|
|
8
|
-
import { loadConfig } from '../config/loader.js';
|
|
9
|
-
import { buildDiagnoseReport } from './diagnose.js';
|
|
10
|
-
import { selectOptimizeAgent } from './optimize.js';
|
|
11
|
-
import { sanitizeEntry, loadErrorEntriesForPattern, sanitizeDraftContent } from '../lib/log-analysis.js';
|
|
12
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
-
const __dirname = dirname(__filename);
|
|
14
|
-
const PACKAGE_ROOT = resolve(__dirname, '..', '..');
|
|
15
|
-
const LOG_DIR = join(homedir(), '.crosscheck', 'logs');
|
|
16
|
-
const ISSUE_REPO = 'Motivation-Labs/crosscheck';
|
|
17
|
-
const { version: PKG_VERSION } = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'));
|
|
18
|
-
export function parseDraft(output) {
|
|
19
|
-
const lines = output.split('\n');
|
|
20
|
-
const titleIdx = lines.findIndex(l => l.startsWith('TITLE:'));
|
|
21
|
-
if (titleIdx === -1)
|
|
22
|
-
return null;
|
|
23
|
-
const title = lines[titleIdx].replace(/^TITLE:\s*/, '').trim();
|
|
24
|
-
if (!title)
|
|
25
|
-
return null;
|
|
26
|
-
let sepIdx = -1;
|
|
27
|
-
for (let i = titleIdx + 1; i < lines.length; i++) {
|
|
28
|
-
if (lines[i].trim() === '---') {
|
|
29
|
-
sepIdx = i;
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (sepIdx === -1)
|
|
34
|
-
return null;
|
|
35
|
-
const body = lines.slice(sepIdx + 1).join('\n').trim();
|
|
36
|
-
if (!body)
|
|
37
|
-
return null;
|
|
38
|
-
return { title, body };
|
|
39
|
-
}
|
|
40
|
-
export function buildIssueContent(draft, answers) {
|
|
41
|
-
const context = [
|
|
42
|
-
'',
|
|
43
|
-
'## User Context',
|
|
44
|
-
'',
|
|
45
|
-
`- **Reproducibility:** ${answers.reproducibility}`,
|
|
46
|
-
`- **Trigger command:** ${answers.trigger}`,
|
|
47
|
-
`- **Impact:** ${answers.impact}`,
|
|
48
|
-
].join('\n');
|
|
49
|
-
return { title: draft.title, body: draft.body + context };
|
|
50
|
-
}
|
|
51
|
-
function defaultSince() {
|
|
52
|
-
const d = new Date();
|
|
53
|
-
d.setDate(d.getDate() - 3);
|
|
54
|
-
return d.toISOString().split('T')[0];
|
|
55
|
-
}
|
|
56
|
-
function daysBetween(since) {
|
|
57
|
-
return Math.max(1, Math.ceil((Date.now() - new Date(since).getTime()) / 86_400_000));
|
|
58
|
-
}
|
|
59
|
-
async function ask(question) {
|
|
60
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
61
|
-
return new Promise(resolve => {
|
|
62
|
-
rl.question(question, answer => { rl.close(); resolve(answer.trim()); });
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
async function pickOne(label, choices) {
|
|
66
|
-
console.log(`\n ${label}`);
|
|
67
|
-
choices.forEach((c, i) => console.log(` [${i + 1}] ${c}`));
|
|
68
|
-
while (true) {
|
|
69
|
-
const raw = await ask(' > ');
|
|
70
|
-
const n = parseInt(raw, 10);
|
|
71
|
-
if (Number.isInteger(n) && n >= 1 && n <= choices.length)
|
|
72
|
-
return n - 1;
|
|
73
|
-
console.log(chalk.dim(` Enter a number from 1 to ${choices.length}`));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function buildAgentPrompt(errorPattern, errorCount, daysSince, reviewer, entries, mode) {
|
|
77
|
-
const entriesFormatted = entries.map(e => JSON.stringify(sanitizeEntry(e))).join('\n');
|
|
78
|
-
return [
|
|
79
|
-
'You are drafting a GitHub issue for the crosscheck project (a cross-vendor AI code review CLI tool).',
|
|
80
|
-
'',
|
|
81
|
-
`Error pattern: ${errorPattern}`,
|
|
82
|
-
`Frequency: ${errorCount} occurrence${errorCount !== 1 ? 's' : ''} in the last ${daysSince} day${daysSince !== 1 ? 's' : ''}`,
|
|
83
|
-
reviewer ? `Reviewer at time of failure: ${reviewer}` : '',
|
|
84
|
-
'',
|
|
85
|
-
'Sanitized log entries (up to 5 most recent):',
|
|
86
|
-
entriesFormatted || '(none available)',
|
|
87
|
-
'',
|
|
88
|
-
`Environment: crosscheck ${PKG_VERSION} · ${platform()} · mode: ${mode}`,
|
|
89
|
-
'',
|
|
90
|
-
'Write a GitHub issue for this failure. Output exactly:',
|
|
91
|
-
'TITLE: <concise title under 80 characters>',
|
|
92
|
-
'---',
|
|
93
|
-
'<issue body in GitHub-flavored markdown>',
|
|
94
|
-
'',
|
|
95
|
-
'The body must contain: ## Description, ## Steps to Reproduce, ## Log Excerpt, ## Environment',
|
|
96
|
-
'In Log Excerpt, show the sanitized log entries as a json code block.',
|
|
97
|
-
'Do not invent details not present in the provided context.',
|
|
98
|
-
].filter(Boolean).join('\n');
|
|
99
|
-
}
|
|
100
|
-
async function runWithClaude(prompt) {
|
|
101
|
-
let result;
|
|
102
|
-
try {
|
|
103
|
-
result = await execa('claude', ['--print', '--bare'], {
|
|
104
|
-
input: prompt,
|
|
105
|
-
timeout: 120_000,
|
|
106
|
-
env: { ...process.env },
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
catch (err) {
|
|
110
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
111
|
-
if (/not logged in|please run \/login|run \/login/i.test(msg)) {
|
|
112
|
-
throw new Error('claude is not logged in — run: claude /login');
|
|
113
|
-
}
|
|
114
|
-
throw err;
|
|
115
|
-
}
|
|
116
|
-
return (result.stdout ?? result.stderr ?? '').trim();
|
|
117
|
-
}
|
|
118
|
-
async function runWithCodex(prompt) {
|
|
119
|
-
const tmpDir = mkdtempSync(join(tmpdir(), 'crosscheck-issue-'));
|
|
120
|
-
try {
|
|
121
|
-
writeFileSync(join(tmpDir, 'ISSUE_PROMPT.md'), prompt);
|
|
122
|
-
const result = await execa('codex', [
|
|
123
|
-
'-q',
|
|
124
|
-
'Read ISSUE_PROMPT.md and produce a GitHub issue draft. ' +
|
|
125
|
-
'Output exactly: TITLE: line, then ---, then the markdown body.',
|
|
126
|
-
], {
|
|
127
|
-
cwd: tmpDir,
|
|
128
|
-
timeout: 180_000,
|
|
129
|
-
env: { ...process.env },
|
|
130
|
-
});
|
|
131
|
-
return (result.stdout ?? '').trim();
|
|
132
|
-
}
|
|
133
|
-
finally {
|
|
134
|
-
rmSync(tmpDir, { recursive: true, force: true });
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
function printDraft(title, body) {
|
|
138
|
-
const width = Math.min(process.stdout.columns ?? 80, 80);
|
|
139
|
-
const bar = '─'.repeat(width);
|
|
140
|
-
console.log('\n' + chalk.dim(bar));
|
|
141
|
-
console.log(chalk.bold(` TITLE: ${title}`));
|
|
142
|
-
console.log(chalk.dim(bar));
|
|
143
|
-
for (const line of body.split('\n')) {
|
|
144
|
-
console.log(` ${line}`);
|
|
145
|
-
}
|
|
146
|
-
console.log(chalk.dim(bar) + '\n');
|
|
147
|
-
}
|
|
148
|
-
function errorLabel(e) {
|
|
149
|
-
if (e.pattern === 'command_not_found')
|
|
150
|
-
return `command not found: ${e.command}`;
|
|
151
|
-
if (e.pattern === 'base_branch_missing')
|
|
152
|
-
return `base branch missing: ${e.branch}`;
|
|
153
|
-
return e.pattern;
|
|
154
|
-
}
|
|
155
|
-
export async function runIssue(opts) {
|
|
156
|
-
const since = opts.since ?? defaultSince();
|
|
157
|
-
if (!existsSync(LOG_DIR)) {
|
|
158
|
-
console.error(chalk.yellow('No logs found. Run `crosscheck watch` or `crosscheck serve` first.'));
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
// 1. Scan logs for error patterns
|
|
162
|
-
console.log(chalk.dim(' scanning logs...'));
|
|
163
|
-
const report = buildDiagnoseReport(since, LOG_DIR);
|
|
164
|
-
if (report.errors.length === 0) {
|
|
165
|
-
console.log(' No errors found in recent logs — nothing to report');
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
// 2. Select which error to report
|
|
169
|
-
let errorIdx = 0;
|
|
170
|
-
if (report.errors.length > 1 && !opts.yes) {
|
|
171
|
-
const days = daysBetween(since);
|
|
172
|
-
console.log(chalk.bold(`\n Found ${report.errors.length} error patterns in the last ${days} day${days !== 1 ? 's' : ''}:\n`));
|
|
173
|
-
report.errors.forEach((e, i) => {
|
|
174
|
-
const label = errorLabel(e).padEnd(44);
|
|
175
|
-
const rev = e.reviewer ? chalk.dim(` ${e.reviewer}`) : '';
|
|
176
|
-
console.log(` [${i + 1}] ${label} ×${e.count}${rev}`);
|
|
177
|
-
});
|
|
178
|
-
errorIdx = await pickOne('Which issue do you want to report?', report.errors.map((_, i) => String(i + 1)));
|
|
179
|
-
}
|
|
180
|
-
const selected = report.errors[errorIdx];
|
|
181
|
-
if (!selected) {
|
|
182
|
-
console.error(chalk.red('✗ Invalid selection'));
|
|
183
|
-
process.exit(1);
|
|
184
|
-
}
|
|
185
|
-
// 3. Load representative log entries for this pattern
|
|
186
|
-
const rawEntries = loadErrorEntriesForPattern(selected.pattern, selected.command, since);
|
|
187
|
-
// 4. Select agent
|
|
188
|
-
const config = loadConfig(opts.config);
|
|
189
|
-
let agentName = 'claude';
|
|
190
|
-
let agentReason = 'default';
|
|
191
|
-
try {
|
|
192
|
-
const sel = selectOptimizeAgent(config, report);
|
|
193
|
-
agentName = sel.agent;
|
|
194
|
-
agentReason = sel.reason;
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
// No vendors configured — fall back to claude
|
|
198
|
-
}
|
|
199
|
-
// 5. Draft issue via AI agent
|
|
200
|
-
const days = daysBetween(since);
|
|
201
|
-
const prompt = buildAgentPrompt(errorLabel(selected), selected.count, days, selected.reviewer, rawEntries, config.mode);
|
|
202
|
-
console.log(chalk.dim(` drafting issue with ${agentName} (${agentReason})...`));
|
|
203
|
-
let agentOutput;
|
|
204
|
-
try {
|
|
205
|
-
agentOutput = agentName === 'claude'
|
|
206
|
-
? await runWithClaude(prompt)
|
|
207
|
-
: await runWithCodex(prompt);
|
|
208
|
-
}
|
|
209
|
-
catch (err) {
|
|
210
|
-
console.error(chalk.red(`✗ ${agentName} failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
211
|
-
process.exit(1);
|
|
212
|
-
}
|
|
213
|
-
const draftParsed = parseDraft(agentOutput);
|
|
214
|
-
if (!draftParsed) {
|
|
215
|
-
console.error(chalk.red('✗ Agent returned unexpected output format'));
|
|
216
|
-
console.error(chalk.dim(' Expected: TITLE: <title>\\n---\\n<body>'));
|
|
217
|
-
process.exit(1);
|
|
218
|
-
}
|
|
219
|
-
// 6. Ask follow-up questions (skipped when --yes)
|
|
220
|
-
let answers = {
|
|
221
|
-
reproducibility: 'Unknown',
|
|
222
|
-
trigger: 'Unknown',
|
|
223
|
-
impact: 'Degraded',
|
|
224
|
-
};
|
|
225
|
-
if (!opts.yes) {
|
|
226
|
-
const repIdx = await pickOne('Can you reproduce this consistently?', ['Every time', 'Sometimes', 'Happened once']);
|
|
227
|
-
answers.reproducibility = ['Every time', 'Sometimes', 'Happened once'][repIdx];
|
|
228
|
-
const trigIdx = await pickOne('Which command triggered this?', ['watch', 'serve', 'review', 'Unknown']);
|
|
229
|
-
answers.trigger = ['watch', 'serve', 'review', 'Unknown'][trigIdx];
|
|
230
|
-
const impactIdx = await pickOne('Is this blocking you from using crosscheck?', ['Blocked', 'Degraded', 'Cosmetic']);
|
|
231
|
-
answers.impact = ['Blocked', 'Degraded', 'Cosmetic'][impactIdx];
|
|
232
|
-
}
|
|
233
|
-
// 7. Build final content and show draft
|
|
234
|
-
// Sanitize AI output before use — the agent may echo back content it received,
|
|
235
|
-
// even if inputs were sanitized; this is the last gate before posting.
|
|
236
|
-
const cleanDraft = sanitizeDraftContent(draftParsed.title, draftParsed.body);
|
|
237
|
-
const { title, body } = buildIssueContent(cleanDraft, answers);
|
|
238
|
-
printDraft(title, body);
|
|
239
|
-
// 8. Submit
|
|
240
|
-
if (opts.dryRun) {
|
|
241
|
-
console.log(chalk.dim(' (dry run — not submitting)'));
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
if (!opts.yes) {
|
|
245
|
-
const confirmed = (await ask(` Submit to ${ISSUE_REPO}? [y/N]: `));
|
|
246
|
-
if (!/^y(es)?$/i.test(confirmed)) {
|
|
247
|
-
console.log(' Cancelled.');
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
const labels = ['bug'];
|
|
252
|
-
if (answers.impact === 'Blocked')
|
|
253
|
-
labels.push('priority:high');
|
|
254
|
-
const ghArgs = [
|
|
255
|
-
'issue', 'create',
|
|
256
|
-
'--repo', ISSUE_REPO,
|
|
257
|
-
'--title', title,
|
|
258
|
-
'--body', body,
|
|
259
|
-
...labels.flatMap(l => ['--label', l]),
|
|
260
|
-
];
|
|
261
|
-
let issueUrl;
|
|
262
|
-
try {
|
|
263
|
-
const result = await execa('gh', ghArgs, { timeout: 30_000 });
|
|
264
|
-
issueUrl = (result.stdout ?? '').trim();
|
|
265
|
-
}
|
|
266
|
-
catch (err) {
|
|
267
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
268
|
-
if (/not logged in|not authenticated/i.test(msg)) {
|
|
269
|
-
console.error(chalk.yellow(' gh is not authenticated — run: gh auth login'));
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
console.error(chalk.yellow(` gh issue create failed: ${msg}`));
|
|
273
|
-
}
|
|
274
|
-
// Fall back to printing the command the user can run manually
|
|
275
|
-
const escapedTitle = title.replace(/'/g, "'\\''");
|
|
276
|
-
const escapedBody = body.replace(/'/g, "'\\''");
|
|
277
|
-
const labelsStr = labels.map(l => `--label '${l}'`).join(' ');
|
|
278
|
-
console.log('\n Run this manually:');
|
|
279
|
-
console.log(chalk.cyan(` gh issue create --repo ${ISSUE_REPO} --title '${escapedTitle}' --body '${escapedBody}' ${labelsStr}`));
|
|
280
|
-
process.exit(2);
|
|
281
|
-
}
|
|
282
|
-
console.log(chalk.green(`\n ✓ issue created → ${issueUrl}`));
|
|
283
|
-
}
|
|
284
|
-
//# sourceMappingURL=issue.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"issue.js","sourceRoot":"","sources":["../../src/commands/issue.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export interface RawLogEntry {
|
|
2
|
-
ts: string;
|
|
3
|
-
level: string;
|
|
4
|
-
event: string;
|
|
5
|
-
message?: string;
|
|
6
|
-
repo?: string;
|
|
7
|
-
pr?: number;
|
|
8
|
-
reviewer?: string;
|
|
9
|
-
[key: string]: unknown;
|
|
10
|
-
}
|
|
11
|
-
export declare function sanitizeEntry(entry: RawLogEntry): RawLogEntry;
|
|
12
|
-
export declare function sanitizeDraftContent(title: string, body: string): {
|
|
13
|
-
title: string;
|
|
14
|
-
body: string;
|
|
15
|
-
};
|
|
16
|
-
export declare function loadErrorEntriesForPattern(pattern: string, command?: string, since?: string, logDir?: string): RawLogEntry[];
|
|
17
|
-
//# sourceMappingURL=log-analysis.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"log-analysis.d.ts","sourceRoot":"","sources":["../../src/lib/log-analysis.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAW7D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAEjG;AA6BD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,WAAW,EAAE,CAcf"}
|
package/dist/lib/log-analysis.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { readdirSync, readFileSync, existsSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
import { classifyError } from '../commands/diagnose.js';
|
|
5
|
-
const DEFAULT_LOG_DIR = join(homedir(), '.crosscheck', 'logs');
|
|
6
|
-
export function sanitizeEntry(entry) {
|
|
7
|
-
const out = { ...entry };
|
|
8
|
-
// Sanitize repo field first (explicit replacement, not text pattern)
|
|
9
|
-
if (out.repo)
|
|
10
|
-
out.repo = '[repo]';
|
|
11
|
-
// Sanitize every string-valued field — covers message, stack, stderr, command,
|
|
12
|
-
// branch, url, and any future fields added by logError
|
|
13
|
-
for (const key of Object.keys(out)) {
|
|
14
|
-
if (key === 'repo')
|
|
15
|
-
continue;
|
|
16
|
-
if (typeof out[key] === 'string')
|
|
17
|
-
out[key] = sanitizeText(out[key]);
|
|
18
|
-
}
|
|
19
|
-
return out;
|
|
20
|
-
}
|
|
21
|
-
export function sanitizeDraftContent(title, body) {
|
|
22
|
-
return { title: sanitizeText(title), body: sanitizeText(body) };
|
|
23
|
-
}
|
|
24
|
-
function sanitizeText(s) {
|
|
25
|
-
return s
|
|
26
|
-
.replace(/https?:\/\/github\.com\/[^\s"']*/g, '[github-url]')
|
|
27
|
-
// File paths before owner/repo to prevent double-replacement of path segments
|
|
28
|
-
.replace(/(?:\/[a-zA-Z0-9_.-]+){2,}\.[a-zA-Z]{2,5}/g, '[file-path]')
|
|
29
|
-
.replace(/\b[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+\b/g, '[repo]')
|
|
30
|
-
.replace(/@[a-zA-Z0-9][a-zA-Z0-9_-]*/g, '[username]');
|
|
31
|
-
}
|
|
32
|
-
function collectFiles(since, logDir = DEFAULT_LOG_DIR) {
|
|
33
|
-
if (!existsSync(logDir))
|
|
34
|
-
return [];
|
|
35
|
-
return readdirSync(logDir)
|
|
36
|
-
.filter(f => f.endsWith('.ndjson'))
|
|
37
|
-
.filter(f => !since || f.replace('.ndjson', '') >= since)
|
|
38
|
-
.sort()
|
|
39
|
-
.map(f => join(logDir, f));
|
|
40
|
-
}
|
|
41
|
-
function parseFile(filePath) {
|
|
42
|
-
const out = [];
|
|
43
|
-
for (const line of readFileSync(filePath, 'utf8').split('\n')) {
|
|
44
|
-
if (!line.trim())
|
|
45
|
-
continue;
|
|
46
|
-
try {
|
|
47
|
-
out.push(JSON.parse(line));
|
|
48
|
-
}
|
|
49
|
-
catch { /* skip malformed */ }
|
|
50
|
-
}
|
|
51
|
-
return out;
|
|
52
|
-
}
|
|
53
|
-
export function loadErrorEntriesForPattern(pattern, command, since, logDir) {
|
|
54
|
-
const files = collectFiles(since, logDir);
|
|
55
|
-
const matches = [];
|
|
56
|
-
for (const file of files) {
|
|
57
|
-
for (const entry of parseFile(file)) {
|
|
58
|
-
if (entry.event !== 'error' || entry.level !== 'error')
|
|
59
|
-
continue;
|
|
60
|
-
if (!entry.message)
|
|
61
|
-
continue;
|
|
62
|
-
const { pattern: p, command: cmd } = classifyError(entry.message);
|
|
63
|
-
if (p !== pattern)
|
|
64
|
-
continue;
|
|
65
|
-
if (pattern === 'command_not_found' && command && cmd !== command)
|
|
66
|
-
continue;
|
|
67
|
-
matches.push(entry);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return matches.slice(0, 5);
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=log-analysis.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"log-analysis.js","sourceRoot":"","sources":["../../src/lib/log-analysis.ts"],"names":[],"mappings":"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"}
|