@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.
Files changed (35) hide show
  1. package/dist/__tests__/durations.test.d.ts +2 -0
  2. package/dist/__tests__/durations.test.d.ts.map +1 -0
  3. package/dist/__tests__/durations.test.js +24 -0
  4. package/dist/__tests__/durations.test.js.map +1 -0
  5. package/dist/__tests__/scan-cache.test.d.ts +2 -0
  6. package/dist/__tests__/scan-cache.test.d.ts.map +1 -0
  7. package/dist/__tests__/scan-cache.test.js +49 -0
  8. package/dist/__tests__/scan-cache.test.js.map +1 -0
  9. package/dist/__tests__/scan-client.test.d.ts +2 -0
  10. package/dist/__tests__/scan-client.test.d.ts.map +1 -0
  11. package/dist/__tests__/scan-client.test.js +30 -0
  12. package/dist/__tests__/scan-client.test.js.map +1 -0
  13. package/dist/__tests__/scan.test.d.ts +2 -0
  14. package/dist/__tests__/scan.test.d.ts.map +1 -0
  15. package/dist/__tests__/scan.test.js +115 -0
  16. package/dist/__tests__/scan.test.js.map +1 -0
  17. package/dist/cli.js +10 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/scan.d.ts +86 -0
  20. package/dist/commands/scan.d.ts.map +1 -0
  21. package/dist/commands/scan.js +445 -0
  22. package/dist/commands/scan.js.map +1 -0
  23. package/dist/github/client.d.ts +19 -0
  24. package/dist/github/client.d.ts.map +1 -1
  25. package/dist/github/client.js +107 -0
  26. package/dist/github/client.js.map +1 -1
  27. package/dist/lib/durations.d.ts +3 -0
  28. package/dist/lib/durations.d.ts.map +1 -0
  29. package/dist/lib/durations.js +28 -0
  30. package/dist/lib/durations.js.map +1 -0
  31. package/dist/lib/scan-cache.d.ts +21 -0
  32. package/dist/lib/scan-cache.d.ts.map +1 -0
  33. package/dist/lib/scan-cache.js +61 -0
  34. package/dist/lib/scan-cache.js.map +1 -0
  35. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=durations.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scan-cache.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scan-client.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scan.test.d.ts.map
@@ -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":"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"}
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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"}