@motivation-labs/crosscheck 0.14.0-beta.68 → 0.14.0-beta.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/durations.test.d.ts +2 -0
- package/dist/__tests__/durations.test.d.ts.map +1 -0
- package/dist/__tests__/durations.test.js +24 -0
- package/dist/__tests__/durations.test.js.map +1 -0
- package/dist/__tests__/scan-cache.test.d.ts +2 -0
- package/dist/__tests__/scan-cache.test.d.ts.map +1 -0
- package/dist/__tests__/scan-cache.test.js +49 -0
- package/dist/__tests__/scan-cache.test.js.map +1 -0
- package/dist/__tests__/scan-client.test.d.ts +2 -0
- package/dist/__tests__/scan-client.test.d.ts.map +1 -0
- package/dist/__tests__/scan-client.test.js +30 -0
- package/dist/__tests__/scan-client.test.js.map +1 -0
- package/dist/__tests__/scan.test.d.ts +2 -0
- package/dist/__tests__/scan.test.d.ts.map +1 -0
- package/dist/__tests__/scan.test.js +115 -0
- package/dist/__tests__/scan.test.js.map +1 -0
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/scan.d.ts +86 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +445 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/github/client.d.ts +19 -0
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +107 -0
- package/dist/github/client.js.map +1 -1
- package/dist/lib/durations.d.ts +3 -0
- package/dist/lib/durations.d.ts.map +1 -0
- package/dist/lib/durations.js +28 -0
- package/dist/lib/durations.js.map +1 -0
- package/dist/lib/scan-cache.d.ts +21 -0
- package/dist/lib/scan-cache.d.ts.map +1 -0
- package/dist/lib/scan-cache.js +61 -0
- package/dist/lib/scan-cache.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durations.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/durations.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { formatElapsed, parseDurationMs } from '../lib/durations.js';
|
|
3
|
+
describe('parseDurationMs', () => {
|
|
4
|
+
it('parses supported minute, hour, and day durations', () => {
|
|
5
|
+
expect(parseDurationMs('30m')).toBe(30 * 60 * 1000);
|
|
6
|
+
expect(parseDurationMs('2h')).toBe(2 * 60 * 60 * 1000);
|
|
7
|
+
expect(parseDurationMs('1d')).toBe(24 * 60 * 60 * 1000);
|
|
8
|
+
});
|
|
9
|
+
it('rejects invalid duration strings', () => {
|
|
10
|
+
expect(() => parseDurationMs('30')).toThrow(/Invalid duration/);
|
|
11
|
+
expect(() => parseDurationMs('2w')).toThrow(/Invalid duration/);
|
|
12
|
+
expect(() => parseDurationMs('abc')).toThrow(/Invalid duration/);
|
|
13
|
+
expect(() => parseDurationMs('0m')).toThrow(/Invalid duration/);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('formatElapsed', () => {
|
|
17
|
+
const now = Date.parse('2026-05-29T12:00:00Z');
|
|
18
|
+
it('formats elapsed times consistently', () => {
|
|
19
|
+
expect(formatElapsed('2026-05-29T11:40:00Z', now)).toBe('20m ago');
|
|
20
|
+
expect(formatElapsed('2026-05-28T09:00:00Z', now)).toBe('27h ago');
|
|
21
|
+
expect(formatElapsed('2026-05-26T12:00:00Z', now)).toBe('3d ago');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=durations.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durations.test.js","sourceRoot":"","sources":["../../src/__tests__/durations.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAEpE,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;QACnD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;QACtD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;QAC/D,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;QAC/D,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;QAChE,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;IAE9C,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,aAAa,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAClE,MAAM,CAAC,aAAa,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAClE,MAAM,CAAC,aAAa,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-cache.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scan-cache.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { mkdtempSync, readFileSync, rmSync, statSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { buildScanCacheKey, readScanCache, writeScanCache } from '../lib/scan-cache.js';
|
|
6
|
+
let tmpDir;
|
|
7
|
+
let cachePath;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
tmpDir = mkdtempSync(join(tmpdir(), 'crosscheck-scan-cache-'));
|
|
10
|
+
cachePath = join(tmpDir, 'scan.json');
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
14
|
+
});
|
|
15
|
+
describe('scan cache', () => {
|
|
16
|
+
const key = buildScanCacheKey({
|
|
17
|
+
configPath: '/repo/crosscheck.config.yml',
|
|
18
|
+
monitorScopeHash: 'scope',
|
|
19
|
+
githubLogin: 'alice',
|
|
20
|
+
staleAfterMs: 24 * 60 * 60 * 1000,
|
|
21
|
+
packageVersion: '0.9.0',
|
|
22
|
+
});
|
|
23
|
+
it('hits within the 60 second TTL', () => {
|
|
24
|
+
writeScanCache(key, { rows: [1] }, { cachePath, now: 1_000 });
|
|
25
|
+
expect(readScanCache(key, { cachePath, now: 60_000 })).toEqual({ rows: [1] });
|
|
26
|
+
});
|
|
27
|
+
it('misses after the TTL', () => {
|
|
28
|
+
writeScanCache(key, { rows: [1] }, { cachePath, now: 1_000 });
|
|
29
|
+
expect(readScanCache(key, { cachePath, now: 62_000 })).toBeNull();
|
|
30
|
+
});
|
|
31
|
+
it('misses when force bypass is requested', () => {
|
|
32
|
+
writeScanCache(key, { rows: [1] }, { cachePath, now: 1_000 });
|
|
33
|
+
expect(readScanCache(key, { cachePath, now: 2_000, force: true })).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
it('does not overwrite a prior successful cache on partial failure', () => {
|
|
36
|
+
writeScanCache(key, { rows: ['old'] }, { cachePath, now: 1_000 });
|
|
37
|
+
const before = readFileSync(cachePath, 'utf8');
|
|
38
|
+
const wrote = writeScanCache(key, { rows: ['new'] }, { cachePath, now: 2_000, partialFailure: true });
|
|
39
|
+
expect(wrote).toBe(false);
|
|
40
|
+
expect(readFileSync(cachePath, 'utf8')).toBe(before);
|
|
41
|
+
expect(readScanCache(key, { cachePath, now: 3_000 })).toEqual({ rows: ['old'] });
|
|
42
|
+
});
|
|
43
|
+
it('creates cache directories with owner-only permissions', () => {
|
|
44
|
+
const nestedCachePath = join(tmpDir, 'nested', 'cache', 'scan.json');
|
|
45
|
+
writeScanCache(key, { rows: [1] }, { cachePath: nestedCachePath, now: 1_000 });
|
|
46
|
+
expect(statSync(join(tmpDir, 'nested', 'cache')).mode & 0o777).toBe(0o700);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=scan-cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-cache.test.js","sourceRoot":"","sources":["../../src/__tests__/scan-cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scan-client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { listIssueCommentsForScan } from '../github/client.js';
|
|
3
|
+
function jsonResponse(data, init = {}) {
|
|
4
|
+
return new Response(JSON.stringify(data), {
|
|
5
|
+
status: init.status ?? 200,
|
|
6
|
+
statusText: init.statusText,
|
|
7
|
+
headers: { 'Content-Type': 'application/json' },
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
vi.unstubAllGlobals();
|
|
12
|
+
});
|
|
13
|
+
describe('scan GitHub client helpers', () => {
|
|
14
|
+
it('requests issue comments in explicit created-at order with encoded path segments', async () => {
|
|
15
|
+
const fetchMock = vi.fn().mockResolvedValueOnce(jsonResponse([]));
|
|
16
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
17
|
+
await listIssueCommentsForScan('acme org', 'api/repo', 12, 'token');
|
|
18
|
+
const url = String(fetchMock.mock.calls[0]?.[0]);
|
|
19
|
+
expect(url).toContain('/repos/acme%20org/api%2Frepo/issues/12/comments');
|
|
20
|
+
expect(url).toContain('sort=created');
|
|
21
|
+
expect(url).toContain('direction=asc');
|
|
22
|
+
});
|
|
23
|
+
it('surfaces GitHub rate limit responses distinctly', async () => {
|
|
24
|
+
const fetchMock = vi.fn().mockResolvedValueOnce(jsonResponse({ message: 'API rate limit exceeded' }, { status: 403, statusText: 'Forbidden' }));
|
|
25
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
26
|
+
await expect(listIssueCommentsForScan('acme', 'api', 12, 'token'))
|
|
27
|
+
.rejects.toThrow('GitHub rate limit or secondary rate limit');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=scan-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-client.test.js","sourceRoot":"","sources":["../../src/__tests__/scan-client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAE9D,SAAS,YAAY,CAAC,IAAa,EAAE,OAAqB,EAAE;IAC1D,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG;QAC1B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,gBAAgB,EAAE,CAAA;AACvB,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAA;QACjE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QAEjC,MAAM,wBAAwB,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;QAEnE,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAChD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,iDAAiD,CAAC,CAAA;QACxE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,YAAY,CAC1D,EAAE,OAAO,EAAE,yBAAyB,EAAE,EACtC,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,CACzC,CAAC,CAAA;QACF,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QAEjC,MAAM,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;aAC/D,OAAO,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scan.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { applyLogEntry, buildProgressSummary, chooseLatestVerdict, emptyLogSummary, filterScanRowsForOutput, findLatestAnnotation, selectNextAction, } from '../commands/scan.js';
|
|
3
|
+
function row(overrides) {
|
|
4
|
+
return {
|
|
5
|
+
repo: 'acme/api',
|
|
6
|
+
pr: 1,
|
|
7
|
+
title: 'test PR',
|
|
8
|
+
author: 'alice',
|
|
9
|
+
branch: 'feat/test',
|
|
10
|
+
headSha: 'abcdef123456',
|
|
11
|
+
headShaShort: 'abcdef1',
|
|
12
|
+
url: 'https://github.com/acme/api/pull/1',
|
|
13
|
+
createdAt: '2026-05-29T10:00:00Z',
|
|
14
|
+
lastActiveAt: '2026-05-29T10:00:00Z',
|
|
15
|
+
isStale: false,
|
|
16
|
+
reviewState: 'PR',
|
|
17
|
+
latestVerdict: null,
|
|
18
|
+
progressSummary: 'PR',
|
|
19
|
+
tokens: { review: 0, fix: 0, recheck: 0, total: 0 },
|
|
20
|
+
latestAnnotation: null,
|
|
21
|
+
nextAction: 'next CR',
|
|
22
|
+
...overrides,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
describe('filterScanRowsForOutput', () => {
|
|
26
|
+
it('keeps all rows by default', () => {
|
|
27
|
+
const rows = [
|
|
28
|
+
row({ pr: 1, isStale: true, nextAction: 'next fix' }),
|
|
29
|
+
row({ pr: 2, isStale: false, nextAction: 'next CR' }),
|
|
30
|
+
row({ pr: 3, isStale: true, nextAction: null }),
|
|
31
|
+
];
|
|
32
|
+
expect(filterScanRowsForOutput(rows, false).map(r => r.pr)).toEqual([1, 2, 3]);
|
|
33
|
+
});
|
|
34
|
+
it('tidy mode hides non-stale rows and rows without a next action', () => {
|
|
35
|
+
const rows = [
|
|
36
|
+
row({ pr: 1, isStale: true, nextAction: 'next fix' }),
|
|
37
|
+
row({ pr: 2, isStale: false, nextAction: 'next CR' }),
|
|
38
|
+
row({ pr: 3, isStale: true, nextAction: null }),
|
|
39
|
+
];
|
|
40
|
+
expect(filterScanRowsForOutput(rows, true).map(r => r.pr)).toEqual([1]);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('scan state helpers', () => {
|
|
44
|
+
it('uses conflict resolve counts in progress summaries', () => {
|
|
45
|
+
const summary = emptyLogSummary();
|
|
46
|
+
applyLogEntry(summary, {
|
|
47
|
+
ts: '2026-05-30T08:00:00Z',
|
|
48
|
+
event: 'conflict_resolve_complete',
|
|
49
|
+
conflicts_resolved: 3,
|
|
50
|
+
tokens_used: 1200,
|
|
51
|
+
});
|
|
52
|
+
expect(summary.fixAppliedCount).toBe(3);
|
|
53
|
+
expect(summary.tokens.fix).toBe(1200);
|
|
54
|
+
expect(buildProgressSummary(null, summary)).toBe('PR -> fix(3)');
|
|
55
|
+
});
|
|
56
|
+
it('does not invent fix(0) for conflict resolve logs without a count', () => {
|
|
57
|
+
const summary = emptyLogSummary();
|
|
58
|
+
applyLogEntry(summary, {
|
|
59
|
+
ts: '2026-05-30T08:00:00Z',
|
|
60
|
+
event: 'conflict_resolve_complete',
|
|
61
|
+
});
|
|
62
|
+
expect(summary.fixAppliedCount).toBeNull();
|
|
63
|
+
expect(buildProgressSummary(null, summary)).toBe('PR');
|
|
64
|
+
});
|
|
65
|
+
it('keeps recheck annotations labeled as rechecks in progress summaries', () => {
|
|
66
|
+
const annotation = {
|
|
67
|
+
commentId: 1,
|
|
68
|
+
commentCreatedAt: '2026-05-30T08:00:00Z',
|
|
69
|
+
raw: 'origin=codex reviewer=claude verdict=APPROVE type=recheck',
|
|
70
|
+
origin: 'codex',
|
|
71
|
+
reviewer: 'claude',
|
|
72
|
+
verdict: 'APPROVE',
|
|
73
|
+
type: 'recheck',
|
|
74
|
+
isRecheck: true,
|
|
75
|
+
};
|
|
76
|
+
expect(buildProgressSummary(annotation, emptyLogSummary())).toBe('PR -> recheck(APPROVE)');
|
|
77
|
+
});
|
|
78
|
+
it('chooses the newer verdict source', () => {
|
|
79
|
+
const summary = emptyLogSummary();
|
|
80
|
+
summary.latestVerdict = 'BLOCK';
|
|
81
|
+
summary.latestVerdictAt = '2026-05-30T08:00:00Z';
|
|
82
|
+
expect(chooseLatestVerdict('NEEDS_WORK', '2026-05-30T09:00:00Z', summary)).toBe('NEEDS_WORK');
|
|
83
|
+
expect(chooseLatestVerdict('APPROVE', '2026-05-30T07:00:00Z', summary)).toBe('BLOCK');
|
|
84
|
+
});
|
|
85
|
+
it('selects the expected next action for each review state', () => {
|
|
86
|
+
const summary = emptyLogSummary();
|
|
87
|
+
expect(selectNextAction(null, summary)).toBe('next CR');
|
|
88
|
+
expect(selectNextAction('APPROVE', summary)).toBe('next merge');
|
|
89
|
+
expect(selectNextAction('NEEDS_WORK', summary)).toBe('next fix');
|
|
90
|
+
summary.latestStep = 'fix';
|
|
91
|
+
expect(selectNextAction('BLOCK', summary)).toBe('next recheck');
|
|
92
|
+
});
|
|
93
|
+
it('tracks latest annotation separately from latest verdict annotation', () => {
|
|
94
|
+
const annotations = findLatestAnnotation([
|
|
95
|
+
{
|
|
96
|
+
id: 1,
|
|
97
|
+
author: 'bot',
|
|
98
|
+
body: '<!-- crosscheck: origin=codex reviewer=claude verdict=NEEDS_WORK type=review -->',
|
|
99
|
+
createdAt: '2026-05-30T08:00:00Z',
|
|
100
|
+
updatedAt: '2026-05-30T08:00:00Z',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: 2,
|
|
104
|
+
author: 'bot',
|
|
105
|
+
body: '<!-- crosscheck: fix_applied -->',
|
|
106
|
+
createdAt: '2026-05-30T09:00:00Z',
|
|
107
|
+
updatedAt: '2026-05-30T09:00:00Z',
|
|
108
|
+
},
|
|
109
|
+
]);
|
|
110
|
+
expect(annotations.latestAnnotation?.commentId).toBe(2);
|
|
111
|
+
expect(annotations.latestVerdictAnnotation?.commentId).toBe(1);
|
|
112
|
+
expect(annotations.latestVerdictAnnotation?.verdict).toBe('NEEDS_WORK');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=scan.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.test.js","sourceRoot":"","sources":["../../src/__tests__/scan.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -14,6 +14,7 @@ import { runOptimize } from './commands/optimize.js';
|
|
|
14
14
|
import { runImpact } from './commands/impact.js';
|
|
15
15
|
import { runIssue } from './commands/issue.js';
|
|
16
16
|
import { runRun } from './commands/run.js';
|
|
17
|
+
import { runScan } from './commands/scan.js';
|
|
17
18
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
19
|
const { version } = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
19
20
|
const invokedAs = basename(process.argv[1] ?? 'crosscheck').replace(/\.js$/, '');
|
|
@@ -78,6 +79,15 @@ program
|
|
|
78
79
|
.description('Show auth state, config summary, and CLI versions')
|
|
79
80
|
.option('-c, --config <path>', 'config file path')
|
|
80
81
|
.action((opts) => void runStatus(opts.config));
|
|
82
|
+
program
|
|
83
|
+
.command('scan')
|
|
84
|
+
.description('Scan open PRs and show review freshness, state, and next action')
|
|
85
|
+
.option('-c, --config <path>', 'config file path')
|
|
86
|
+
.option('--stale-after <duration>', 'mark PRs stale after inactivity, e.g. 30m, 2h, 1d')
|
|
87
|
+
.option('--tidy', 'only print stale rows with a next action')
|
|
88
|
+
.option('--json', 'output full scan data as JSON')
|
|
89
|
+
.option('--force', 'bypass the 60 second scan cache')
|
|
90
|
+
.action((opts) => void runScan(opts));
|
|
81
91
|
program
|
|
82
92
|
.command('diagnose')
|
|
83
93
|
.description('Analyze review logs — surface failure patterns, error trends, and improvement suggestions')
|
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,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,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;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type ScanIssueComment } from '../github/client.js';
|
|
2
|
+
type ReviewState = 'PR' | 'APPROVE' | 'NEEDS_WORK' | 'BLOCK';
|
|
3
|
+
type StepType = 'review' | 'fix' | 'recheck';
|
|
4
|
+
export interface ScanTokens {
|
|
5
|
+
review: number;
|
|
6
|
+
fix: number;
|
|
7
|
+
recheck: number;
|
|
8
|
+
total: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ScanAnnotationMetadata {
|
|
11
|
+
commentId: number;
|
|
12
|
+
commentCreatedAt: string;
|
|
13
|
+
raw: string;
|
|
14
|
+
origin?: string;
|
|
15
|
+
reviewer?: string;
|
|
16
|
+
verdict?: ReviewState;
|
|
17
|
+
type?: string;
|
|
18
|
+
isRecheck?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ScanRow {
|
|
21
|
+
repo: string;
|
|
22
|
+
pr: number;
|
|
23
|
+
title: string;
|
|
24
|
+
author: string;
|
|
25
|
+
branch: string;
|
|
26
|
+
headSha: string;
|
|
27
|
+
headShaShort: string;
|
|
28
|
+
url: string;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
lastActiveAt: string;
|
|
31
|
+
isStale: boolean;
|
|
32
|
+
reviewState: ReviewState;
|
|
33
|
+
latestVerdict: ReviewState | null;
|
|
34
|
+
progressSummary: string;
|
|
35
|
+
tokens: ScanTokens;
|
|
36
|
+
latestAnnotation: ScanAnnotationMetadata | null;
|
|
37
|
+
nextAction: string | null;
|
|
38
|
+
}
|
|
39
|
+
export interface SkippedRepo {
|
|
40
|
+
repo: string;
|
|
41
|
+
reason: string;
|
|
42
|
+
}
|
|
43
|
+
interface ScanOptions {
|
|
44
|
+
config?: string;
|
|
45
|
+
staleAfter?: string;
|
|
46
|
+
tidy?: boolean;
|
|
47
|
+
json?: boolean;
|
|
48
|
+
force?: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface LogEntry {
|
|
51
|
+
ts: string;
|
|
52
|
+
event: string;
|
|
53
|
+
repo?: string;
|
|
54
|
+
pr?: number;
|
|
55
|
+
step_type?: string;
|
|
56
|
+
verdict?: string | null;
|
|
57
|
+
tokens_used?: number;
|
|
58
|
+
applied_count?: number;
|
|
59
|
+
conflicts_resolved?: number;
|
|
60
|
+
reason?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface PRLogSummary {
|
|
63
|
+
reviewVerdict: ReviewState | null;
|
|
64
|
+
recheckVerdict: ReviewState | null;
|
|
65
|
+
latestVerdict: ReviewState | null;
|
|
66
|
+
latestVerdictAt: string | null;
|
|
67
|
+
latestStep: StepType | null;
|
|
68
|
+
latestLogAt: string | null;
|
|
69
|
+
fixAppliedCount: number | null;
|
|
70
|
+
fixCompletedAt: string | null;
|
|
71
|
+
tokens: ScanTokens;
|
|
72
|
+
}
|
|
73
|
+
export declare function runScan(opts: ScanOptions): Promise<void>;
|
|
74
|
+
export declare function filterScanRowsForOutput(rows: ScanRow[], tidy: boolean): ScanRow[];
|
|
75
|
+
export declare function chooseLatestVerdict(annotationVerdict: ReviewState, annotationAt: string, logSummary: PRLogSummary): ReviewState | null;
|
|
76
|
+
export declare function selectNextAction(latestVerdict: ReviewState | null, logSummary: PRLogSummary): string | null;
|
|
77
|
+
export declare function buildProgressSummary(annotation: ScanAnnotationMetadata | null, logSummary: PRLogSummary): string;
|
|
78
|
+
interface ScanAnnotations {
|
|
79
|
+
latestAnnotation: ScanAnnotationMetadata | null;
|
|
80
|
+
latestVerdictAnnotation: ScanAnnotationMetadata | null;
|
|
81
|
+
}
|
|
82
|
+
export declare function findLatestAnnotation(comments: ScanIssueComment[]): ScanAnnotations;
|
|
83
|
+
export declare function applyLogEntry(summary: PRLogSummary, entry: LogEntry): void;
|
|
84
|
+
export declare function emptyLogSummary(): PRLogSummary;
|
|
85
|
+
export {};
|
|
86
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|