@humanbased/crosscheck 1.2.0 → 1.3.0-beta.81
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/LICENSE +1 -1
- package/README.md +182 -375
- package/README.zh.md +1 -1
- package/assets/icon-256.png +0 -0
- package/assets/linear-comment.svg +18 -0
- package/assets/linear-onboard.svg +30 -0
- package/assets/linear-status.svg +23 -0
- package/assets/linear-test.svg +34 -0
- package/assets/skills/code-review/.crosscheck-skill.json +9 -0
- package/assets/skills/code-review/LICENSE +21 -0
- package/assets/skills/code-review/SKILL.md +89 -0
- package/assets/skills/code-review/agents/openai.yaml +3 -0
- package/assets/skills/code-review-skill/.crosscheck-skill.json +9 -0
- package/assets/skills/code-review-skill/LICENSE +21 -0
- package/assets/skills/code-review-skill/SKILL.md +231 -0
- package/assets/skills/code-review-skill/assets/pr-review-template.md +137 -0
- package/assets/skills/code-review-skill/assets/review-checklist.md +123 -0
- package/assets/skills/code-review-skill/reference/angular.md +768 -0
- package/assets/skills/code-review-skill/reference/architecture-review-guide.md +472 -0
- package/assets/skills/code-review-skill/reference/c.md +890 -0
- package/assets/skills/code-review-skill/reference/code-quality-universal.md +488 -0
- package/assets/skills/code-review-skill/reference/code-review-best-practices.md +136 -0
- package/assets/skills/code-review-skill/reference/common-bugs-checklist.md +286 -0
- package/assets/skills/code-review-skill/reference/cpp.md +893 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/async-concurrency-patterns.md +515 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/error-handling-principles.md +492 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/n-plus-one-queries.md +309 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/sql-injection-prevention.md +308 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/xss-prevention.md +264 -0
- package/assets/skills/code-review-skill/reference/csharp.md +525 -0
- package/assets/skills/code-review-skill/reference/css-less-sass.md +661 -0
- package/assets/skills/code-review-skill/reference/django.md +985 -0
- package/assets/skills/code-review-skill/reference/fastapi.md +580 -0
- package/assets/skills/code-review-skill/reference/go.md +993 -0
- package/assets/skills/code-review-skill/reference/java.md +409 -0
- package/assets/skills/code-review-skill/reference/java8.md +586 -0
- package/assets/skills/code-review-skill/reference/kotlin.md +1018 -0
- package/assets/skills/code-review-skill/reference/nestjs.md +593 -0
- package/assets/skills/code-review-skill/reference/performance-review-guide.md +816 -0
- package/assets/skills/code-review-skill/reference/php.md +684 -0
- package/assets/skills/code-review-skill/reference/python.md +1073 -0
- package/assets/skills/code-review-skill/reference/qt.md +757 -0
- package/assets/skills/code-review-skill/reference/react.md +871 -0
- package/assets/skills/code-review-skill/reference/ruby.md +964 -0
- package/assets/skills/code-review-skill/reference/rust.md +846 -0
- package/assets/skills/code-review-skill/reference/security-review-guide.md +494 -0
- package/assets/skills/code-review-skill/reference/svelte.md +1064 -0
- package/assets/skills/code-review-skill/reference/swift.md +936 -0
- package/assets/skills/code-review-skill/reference/typescript.md +1016 -0
- package/assets/skills/code-review-skill/reference/vue.md +924 -0
- package/assets/skills/code-review-skill/reference/zig.md +440 -0
- package/assets/skills/code-review-skill/scripts/pr-analyzer.py +435 -0
- package/assets/skills/code-review-skill/scripts/test_pr_analyzer.py +380 -0
- package/assets/skills/codebase-design/.crosscheck-skill.json +9 -0
- package/assets/skills/codebase-design/DEEPENING.md +37 -0
- package/assets/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/assets/skills/codebase-design/LICENSE +21 -0
- package/assets/skills/codebase-design/SKILL.md +114 -0
- package/assets/skills/codebase-design/agents/openai.yaml +3 -0
- package/assets/skills/diagnosing-bugs/.crosscheck-skill.json +9 -0
- package/assets/skills/diagnosing-bugs/LICENSE +21 -0
- package/assets/skills/diagnosing-bugs/SKILL.md +134 -0
- package/assets/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/assets/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/crosscheck.config.example.yml +101 -9
- package/dist/__tests__/board.test.js +11 -0
- package/dist/__tests__/board.test.js.map +1 -1
- package/dist/__tests__/can-write-verdict.test.d.ts +2 -0
- package/dist/__tests__/can-write-verdict.test.d.ts.map +1 -0
- package/dist/__tests__/can-write-verdict.test.js +31 -0
- package/dist/__tests__/can-write-verdict.test.js.map +1 -0
- package/dist/__tests__/codex.test.js +14 -27
- package/dist/__tests__/codex.test.js.map +1 -1
- package/dist/__tests__/comment-bodies.test.js +49 -1
- package/dist/__tests__/comment-bodies.test.js.map +1 -1
- package/dist/__tests__/conflict-resolve.test.js +44 -1
- package/dist/__tests__/conflict-resolve.test.js.map +1 -1
- package/dist/__tests__/fix.test.js +33 -0
- package/dist/__tests__/fix.test.js.map +1 -1
- package/dist/__tests__/linear-branding.test.d.ts +2 -0
- package/dist/__tests__/linear-branding.test.d.ts.map +1 -0
- package/dist/__tests__/linear-branding.test.js +156 -0
- package/dist/__tests__/linear-branding.test.js.map +1 -0
- package/dist/__tests__/linear-client.test.d.ts +2 -0
- package/dist/__tests__/linear-client.test.d.ts.map +1 -0
- package/dist/__tests__/linear-client.test.js +120 -0
- package/dist/__tests__/linear-client.test.js.map +1 -0
- package/dist/__tests__/linear-comment.test.d.ts +2 -0
- package/dist/__tests__/linear-comment.test.d.ts.map +1 -0
- package/dist/__tests__/linear-comment.test.js +151 -0
- package/dist/__tests__/linear-comment.test.js.map +1 -0
- package/dist/__tests__/linear-identity.test.d.ts +2 -0
- package/dist/__tests__/linear-identity.test.d.ts.map +1 -0
- package/dist/__tests__/linear-identity.test.js +253 -0
- package/dist/__tests__/linear-identity.test.js.map +1 -0
- package/dist/__tests__/linear-notify.test.d.ts +2 -0
- package/dist/__tests__/linear-notify.test.d.ts.map +1 -0
- package/dist/__tests__/linear-notify.test.js +144 -0
- package/dist/__tests__/linear-notify.test.js.map +1 -0
- package/dist/__tests__/linear-ref.test.d.ts +2 -0
- package/dist/__tests__/linear-ref.test.d.ts.map +1 -0
- package/dist/__tests__/linear-ref.test.js +261 -0
- package/dist/__tests__/linear-ref.test.js.map +1 -0
- package/dist/__tests__/linear-test-ref.test.d.ts +2 -0
- package/dist/__tests__/linear-test-ref.test.d.ts.map +1 -0
- package/dist/__tests__/linear-test-ref.test.js +81 -0
- package/dist/__tests__/linear-test-ref.test.js.map +1 -0
- package/dist/__tests__/linear-verify.test.d.ts +2 -0
- package/dist/__tests__/linear-verify.test.d.ts.map +1 -0
- package/dist/__tests__/linear-verify.test.js +132 -0
- package/dist/__tests__/linear-verify.test.js.map +1 -0
- package/dist/__tests__/linear-worker.test.d.ts +2 -0
- package/dist/__tests__/linear-worker.test.d.ts.map +1 -0
- package/dist/__tests__/linear-worker.test.js +83 -0
- package/dist/__tests__/linear-worker.test.js.map +1 -0
- package/dist/__tests__/linear-write-possible.test.d.ts +2 -0
- package/dist/__tests__/linear-write-possible.test.d.ts.map +1 -0
- package/dist/__tests__/linear-write-possible.test.js +30 -0
- package/dist/__tests__/linear-write-possible.test.js.map +1 -0
- package/dist/__tests__/onboard-preservation.test.js +59 -3
- package/dist/__tests__/onboard-preservation.test.js.map +1 -1
- package/dist/__tests__/optimize.test.js +2 -0
- package/dist/__tests__/optimize.test.js.map +1 -1
- package/dist/__tests__/repo-picker.test.js +7 -1
- package/dist/__tests__/repo-picker.test.js.map +1 -1
- package/dist/__tests__/repository-guidance.test.d.ts +2 -0
- package/dist/__tests__/repository-guidance.test.d.ts.map +1 -0
- package/dist/__tests__/repository-guidance.test.js +107 -0
- package/dist/__tests__/repository-guidance.test.js.map +1 -0
- package/dist/__tests__/review-comment-body.test.js +35 -0
- package/dist/__tests__/review-comment-body.test.js.map +1 -1
- package/dist/__tests__/review-models.test.js +19 -3
- package/dist/__tests__/review-models.test.js.map +1 -1
- package/dist/__tests__/review-strategy.test.d.ts +2 -0
- package/dist/__tests__/review-strategy.test.d.ts.map +1 -0
- package/dist/__tests__/review-strategy.test.js +397 -0
- package/dist/__tests__/review-strategy.test.js.map +1 -0
- package/dist/__tests__/runner.test.js +29 -1
- package/dist/__tests__/runner.test.js.map +1 -1
- package/dist/__tests__/skill-attribution.test.d.ts +2 -0
- package/dist/__tests__/skill-attribution.test.d.ts.map +1 -0
- package/dist/__tests__/skill-attribution.test.js +53 -0
- package/dist/__tests__/skill-attribution.test.js.map +1 -0
- package/dist/__tests__/skill-broker.test.d.ts +2 -0
- package/dist/__tests__/skill-broker.test.d.ts.map +1 -0
- package/dist/__tests__/skill-broker.test.js +144 -0
- package/dist/__tests__/skill-broker.test.js.map +1 -0
- package/dist/__tests__/skill-catalog.test.d.ts +2 -0
- package/dist/__tests__/skill-catalog.test.d.ts.map +1 -0
- package/dist/__tests__/skill-catalog.test.js +40 -0
- package/dist/__tests__/skill-catalog.test.js.map +1 -0
- package/dist/__tests__/skill-installer.test.d.ts +2 -0
- package/dist/__tests__/skill-installer.test.d.ts.map +1 -0
- package/dist/__tests__/skill-installer.test.js +96 -0
- package/dist/__tests__/skill-installer.test.js.map +1 -0
- package/dist/__tests__/skills-config.test.d.ts +2 -0
- package/dist/__tests__/skills-config.test.d.ts.map +1 -0
- package/dist/__tests__/skills-config.test.js +12 -0
- package/dist/__tests__/skills-config.test.js.map +1 -0
- package/dist/cli.js +29 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/linear-test.d.ts +18 -0
- package/dist/commands/linear-test.d.ts.map +1 -0
- package/dist/commands/linear-test.js +130 -0
- package/dist/commands/linear-test.js.map +1 -0
- package/dist/commands/onboard.d.ts +36 -3
- package/dist/commands/onboard.d.ts.map +1 -1
- package/dist/commands/onboard.js +233 -42
- package/dist/commands/onboard.js.map +1 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +65 -6
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +45 -7
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/skill.d.ts +2 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +16 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +53 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +90 -12
- package/dist/commands/watch.js.map +1 -1
- package/dist/config/loader.d.ts +3 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +13 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/review-model-tiers.json +3 -3
- package/dist/config/review-strategy.json +204 -0
- package/dist/config/schema.d.ts +261 -15
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +90 -8
- package/dist/config/schema.js.map +1 -1
- package/dist/github/client.d.ts +21 -1
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +46 -7
- package/dist/github/client.js.map +1 -1
- package/dist/github/webhook.d.ts +4 -0
- package/dist/github/webhook.d.ts.map +1 -1
- package/dist/github/webhook.js.map +1 -1
- package/dist/issues/ticket-ref.d.ts.map +1 -1
- package/dist/issues/ticket-ref.js +6 -5
- package/dist/issues/ticket-ref.js.map +1 -1
- package/dist/lib/annotation.d.ts +7 -0
- package/dist/lib/annotation.d.ts.map +1 -1
- package/dist/lib/annotation.js +11 -1
- package/dist/lib/annotation.js.map +1 -1
- package/dist/lib/board.d.ts +3 -0
- package/dist/lib/board.d.ts.map +1 -1
- package/dist/lib/board.js +4 -2
- package/dist/lib/board.js.map +1 -1
- package/dist/lib/clone.d.ts +1 -0
- package/dist/lib/clone.d.ts.map +1 -1
- package/dist/lib/clone.js +32 -10
- package/dist/lib/clone.js.map +1 -1
- package/dist/lib/comment-bodies.d.ts +37 -0
- package/dist/lib/comment-bodies.d.ts.map +1 -1
- package/dist/lib/comment-bodies.js +47 -9
- package/dist/lib/comment-bodies.js.map +1 -1
- package/dist/lib/repo-picker.d.ts +3 -0
- package/dist/lib/repo-picker.d.ts.map +1 -1
- package/dist/lib/repo-picker.js +45 -9
- package/dist/lib/repo-picker.js.map +1 -1
- package/dist/lib/repository-guidance.d.ts +2 -0
- package/dist/lib/repository-guidance.d.ts.map +1 -0
- package/dist/lib/repository-guidance.js +55 -0
- package/dist/lib/repository-guidance.js.map +1 -0
- package/dist/lib/review-models.d.ts +15 -2
- package/dist/lib/review-models.d.ts.map +1 -1
- package/dist/lib/review-models.js +26 -6
- package/dist/lib/review-models.js.map +1 -1
- package/dist/lib/review-strategy.d.ts +92 -0
- package/dist/lib/review-strategy.d.ts.map +1 -0
- package/dist/lib/review-strategy.js +282 -0
- package/dist/lib/review-strategy.js.map +1 -0
- package/dist/lib/runner.d.ts +92 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +470 -54
- package/dist/lib/runner.js.map +1 -1
- package/dist/lib/workflow.d.ts +9 -0
- package/dist/lib/workflow.d.ts.map +1 -1
- package/dist/lib/workflow.js +20 -0
- package/dist/lib/workflow.js.map +1 -1
- package/dist/linear/client.d.ts +18 -0
- package/dist/linear/client.d.ts.map +1 -0
- package/dist/linear/client.js +67 -0
- package/dist/linear/client.js.map +1 -0
- package/dist/linear/comment.d.ts +20 -0
- package/dist/linear/comment.d.ts.map +1 -0
- package/dist/linear/comment.js +57 -0
- package/dist/linear/comment.js.map +1 -0
- package/dist/linear/identity.d.ts +59 -0
- package/dist/linear/identity.d.ts.map +1 -0
- package/dist/linear/identity.js +187 -0
- package/dist/linear/identity.js.map +1 -0
- package/dist/linear/notify.d.ts +35 -0
- package/dist/linear/notify.d.ts.map +1 -0
- package/dist/linear/notify.js +76 -0
- package/dist/linear/notify.js.map +1 -0
- package/dist/linear/ref.d.ts +13 -0
- package/dist/linear/ref.d.ts.map +1 -0
- package/dist/linear/ref.js +90 -0
- package/dist/linear/ref.js.map +1 -0
- package/dist/linear/verify.d.ts +26 -0
- package/dist/linear/verify.d.ts.map +1 -0
- package/dist/linear/verify.js +67 -0
- package/dist/linear/verify.js.map +1 -0
- package/dist/reviewers/claude.d.ts +4 -1
- package/dist/reviewers/claude.d.ts.map +1 -1
- package/dist/reviewers/claude.js +39 -7
- package/dist/reviewers/claude.js.map +1 -1
- package/dist/reviewers/codex.d.ts +3 -1
- package/dist/reviewers/codex.d.ts.map +1 -1
- package/dist/reviewers/codex.js +76 -70
- package/dist/reviewers/codex.js.map +1 -1
- package/dist/reviewers/conflict-resolve.d.ts +3 -1
- package/dist/reviewers/conflict-resolve.d.ts.map +1 -1
- package/dist/reviewers/conflict-resolve.js +21 -6
- package/dist/reviewers/conflict-resolve.js.map +1 -1
- package/dist/reviewers/fix.d.ts +5 -2
- package/dist/reviewers/fix.d.ts.map +1 -1
- package/dist/reviewers/fix.js +26 -10
- package/dist/reviewers/fix.js.map +1 -1
- package/dist/skills/attribution.d.ts +4 -0
- package/dist/skills/attribution.d.ts.map +1 -0
- package/dist/skills/attribution.js +14 -0
- package/dist/skills/attribution.js.map +1 -0
- package/dist/skills/broker-server.d.ts +2 -0
- package/dist/skills/broker-server.d.ts.map +1 -0
- package/dist/skills/broker-server.js +17 -0
- package/dist/skills/broker-server.js.map +1 -0
- package/dist/skills/broker.d.ts +42 -0
- package/dist/skills/broker.d.ts.map +1 -0
- package/dist/skills/broker.js +285 -0
- package/dist/skills/broker.js.map +1 -0
- package/dist/skills/catalog.d.ts +28 -0
- package/dist/skills/catalog.d.ts.map +1 -0
- package/dist/skills/catalog.js +104 -0
- package/dist/skills/catalog.js.map +1 -0
- package/dist/skills/installer.d.ts +10 -0
- package/dist/skills/installer.d.ts.map +1 -0
- package/dist/skills/installer.js +138 -0
- package/dist/skills/installer.js.map +1 -0
- package/dist/skills/integrity.d.ts +4 -0
- package/dist/skills/integrity.d.ts.map +1 -0
- package/dist/skills/integrity.js +36 -0
- package/dist/skills/integrity.js.map +1 -0
- package/docs/dynamic-thoroughness.md +738 -0
- package/docs/linear-identity-contract.md +139 -0
- package/docs/linear-identity.md +293 -0
- package/get-started.md +207 -11
- package/package.json +4 -3
package/dist/commands/status.js
CHANGED
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import { existsSync, statSync } from 'fs';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import { loadConfig, getGithubTokenSource, getWebhookSecretPath, resolveConfigPath } from '../config/loader.js';
|
|
4
|
+
import { loadConfig, getGithubTokenSource, getWebhookSecretPath, resolveConfigPath, getLinearCredentials } from '../config/loader.js';
|
|
5
|
+
import { verifyLinearIdentity } from '../linear/verify.js';
|
|
5
6
|
import { checkCodexAuth } from '../reviewers/codex.js';
|
|
6
7
|
import { checkClaudeAuth } from '../reviewers/claude.js';
|
|
7
8
|
import { getLogDir, getTodayLogPath } from '../lib/logger.js';
|
|
8
9
|
import { buildImpactReport } from './impact.js';
|
|
10
|
+
import { formatSkillIdentity, loadSkillCatalog } from '../skills/catalog.js';
|
|
9
11
|
function row(label, value, ok) {
|
|
10
12
|
const indicator = ok === undefined ? ' ' : ok ? chalk.green('✓') : chalk.red('✗');
|
|
11
13
|
console.log(` ${indicator} ${chalk.bold(label.padEnd(22))} ${value}`);
|
|
12
14
|
}
|
|
15
|
+
const LINEAR_PROBE_TIMEOUT_MS = 10_000;
|
|
13
16
|
export async function runStatus(configPath) {
|
|
14
17
|
const config = loadConfig(configPath);
|
|
15
18
|
const activeConfigPath = resolveConfigPath(configPath);
|
|
19
|
+
// Start the Linear probe before the CLI auth checks so the two network round
|
|
20
|
+
// trips overlap, and bound it — status must stay responsive even if Linear is
|
|
21
|
+
// slow or unreachable. verifyLinearIdentity never throws; the timeout is the
|
|
22
|
+
// only way this can reject, so it resolves to a report either way.
|
|
23
|
+
const linearProbe = config.linear.enabled
|
|
24
|
+
? Promise.race([
|
|
25
|
+
verifyLinearIdentity(config.linear, getLinearCredentials(config.linear.auth)),
|
|
26
|
+
new Promise(resolve => setTimeout(() => resolve({
|
|
27
|
+
ok: false,
|
|
28
|
+
mode: config.linear.auth.mode,
|
|
29
|
+
actor: config.linear.identity.actor,
|
|
30
|
+
attribution: config.linear.auth.mode === 'client_credentials' ? 'app' : 'user',
|
|
31
|
+
error: `timed out after ${LINEAR_PROBE_TIMEOUT_MS / 1000}s`,
|
|
32
|
+
}), LINEAR_PROBE_TIMEOUT_MS).unref?.()),
|
|
33
|
+
])
|
|
34
|
+
: null;
|
|
16
35
|
console.log(chalk.bold('\ncrosscheck status\n'));
|
|
17
36
|
// Auth
|
|
18
37
|
console.log(chalk.dim(' Auth'));
|
|
@@ -38,6 +57,15 @@ export async function runStatus(configPath) {
|
|
|
38
57
|
row('config path', activeConfigPath ?? 'defaults only');
|
|
39
58
|
row('mode', config.mode);
|
|
40
59
|
row('quality tier', config.quality.tier);
|
|
60
|
+
const skillCatalog = loadSkillCatalog();
|
|
61
|
+
const bundledSkills = new Map(skillCatalog.map(skill => [skill.name, skill]));
|
|
62
|
+
row('installed skills', skillCatalog.map(formatSkillIdentity).join(', '));
|
|
63
|
+
row('enabled skills', config.skills.enabled.length > 0
|
|
64
|
+
? config.skills.enabled.map(name => {
|
|
65
|
+
const skill = bundledSkills.get(name);
|
|
66
|
+
return skill ? formatSkillIdentity(skill) : `${name} (not installed or failed integrity check)`;
|
|
67
|
+
}).join(', ')
|
|
68
|
+
: 'none');
|
|
41
69
|
row('codex auth', config.vendors.codex.auth);
|
|
42
70
|
row('codex model', config.vendors.codex.model ?? 'auto (by tier)');
|
|
43
71
|
row('claude model', config.vendors.claude.model ?? 'default');
|
|
@@ -50,6 +78,30 @@ export async function runStatus(configPath) {
|
|
|
50
78
|
if (config.quality.focus.length > 0) {
|
|
51
79
|
row('focus', config.quality.focus.join(', '));
|
|
52
80
|
}
|
|
81
|
+
// Linear identity — only when the operator has opted in.
|
|
82
|
+
if (linearProbe) {
|
|
83
|
+
console.log();
|
|
84
|
+
console.log(chalk.dim(' Linear'));
|
|
85
|
+
const report = await linearProbe;
|
|
86
|
+
row('auth mode', report.mode, report.ok);
|
|
87
|
+
if (!report.ok) {
|
|
88
|
+
row('identity', report.error ?? 'verification failed', false);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
row('organization', report.organization ?? 'unknown');
|
|
92
|
+
if (report.attribution === 'app') {
|
|
93
|
+
const actor = config.linear.identity.per_step_actor ? `${report.actor}/<step>` : report.actor;
|
|
94
|
+
row('writes as', `${actor} ${chalk.dim('(crosscheck itself)')}`, true);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Deliberately not a failed check. Attributing to a person is the wrong
|
|
98
|
+
// state for a shared workspace, but it is a perfectly reasonable choice for
|
|
99
|
+
// a solo user with no attribution problem — so this informs, it does not nag.
|
|
100
|
+
row('writes as', `${report.attributesTo ?? 'your Linear account'} ${chalk.dim('(api key)')}`);
|
|
101
|
+
console.log(chalk.dim(' to post as crosscheck itself, see docs/linear-identity.md'));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
53
105
|
// Logs
|
|
54
106
|
console.log();
|
|
55
107
|
console.log(chalk.dim(' Logs'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AACzC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AA2KA,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,SAAc,iBAs0ClD"}
|
package/dist/commands/watch.js
CHANGED
|
@@ -3,18 +3,19 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { createWebhookServer } from '../github/webhook.js';
|
|
4
4
|
import { createGithubClient, getCommitMessage, registerOrgWebhook, deleteOrgWebhook, registerRepoWebhook, deleteRepoWebhook, patchOrgWebhookEvents, patchRepoWebhookEvents, findOrgWebhook, findRepoWebhook, listUserRepos, checkRepoAccessible, } from '../github/client.js';
|
|
5
5
|
import { detectOriginFull, assignReviewer } from '../github/detector.js';
|
|
6
|
-
import { loadConfig, getGithubToken, getWebhookSecret, resolveConfigPath, promptDeploymentMode, detectScopesForDeployment, patchDeploymentConfig, detectGitHubLogin, } from '../config/loader.js';
|
|
6
|
+
import { loadConfig, getGithubToken, getWebhookSecret, resolveConfigPath, promptDeploymentMode, detectScopesForDeployment, patchDeploymentConfig, detectGitHubLogin, getLinearCredentials, } from '../config/loader.js';
|
|
7
7
|
import { randomFortune } from '../lib/fortune.js';
|
|
8
8
|
import { scanUnreviewedPRs } from '../lib/backtrace.js';
|
|
9
9
|
import { initLogger, log as fileLog, logError, logUncaught } from '../lib/logger.js';
|
|
10
10
|
import { isAuthorAllowed } from '../lib/filter.js';
|
|
11
11
|
import { runWorkflow } from '../lib/runner.js';
|
|
12
|
-
import { loadWorkflow, DEFAULT_RECHECK_INSTRUCTIONS } from '../lib/workflow.js';
|
|
12
|
+
import { loadWorkflow, linearWritePossible, DEFAULT_RECHECK_INSTRUCTIONS } from '../lib/workflow.js';
|
|
13
13
|
import { filterStepsByTypes, formatRepoWorkflowSteps, isRecheckWithoutFix, isReviewOnlyWorkflow, readRepoWorkflowStepTypes, resolveRepoWorkflowSteps, workflowHasStep } from '../lib/repo-workflow.js';
|
|
14
14
|
import { fetchStepHistory, identifyNextWorkflowStep, decideReviewOnly } from '../lib/pr-workflow-state.js';
|
|
15
15
|
import { parseAnnotation } from '../lib/annotation.js';
|
|
16
16
|
import { PRBoard, fmtTime, FMT_TIME_WIDTH } from '../lib/board.js';
|
|
17
17
|
import { clonePRForReview } from '../lib/clone.js';
|
|
18
|
+
import { resolveLinearAuth, isLinearConfigError } from '../linear/identity.js';
|
|
18
19
|
import { getSmartSwitch, isSubscriptionLimitError, detectFailedVendor, triggerSwitch, notifyReviewSuccess, stopSmartSwitch, } from '../lib/smart-switch.js';
|
|
19
20
|
import { buildReviewFailedCommentBody } from '../lib/comment-bodies.js';
|
|
20
21
|
import { classifyReviewerError } from '../lib/reviewer-error.js';
|
|
@@ -156,6 +157,25 @@ export async function runWatch(opts = {}) {
|
|
|
156
157
|
console.error(chalk.red(`✗ ${err instanceof Error ? err.message : String(err)}`));
|
|
157
158
|
process.exit(1);
|
|
158
159
|
}
|
|
160
|
+
// Preflight Linear identity at startup. watch is a long-running daemon: a bad
|
|
161
|
+
// credential discovered per-event would either drop events silently or spam the
|
|
162
|
+
// board. Fail loudly at boot instead, the way the run path fails before its
|
|
163
|
+
// clone. The token is discarded — per-event resolution mints a fresh one, since
|
|
164
|
+
// app tokens outlive neither a long daemon run nor a rotation.
|
|
165
|
+
// Same gate as the run and per-event paths: a daemon whose configured workflow
|
|
166
|
+
// is fix/conflict-resolve only can never call notifyLinear, so a missing
|
|
167
|
+
// credential must not stop it booting.
|
|
168
|
+
if (linearWritePossible(config.linear, loadWorkflow(process.cwd()))) {
|
|
169
|
+
try {
|
|
170
|
+
const preflight = await resolveLinearAuth(config.linear, getLinearCredentials(config.linear.auth));
|
|
171
|
+
console.log(chalk.dim(` linear: ${preflight.mode} — writes as ${preflight.actor}`));
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
logError({ command: 'watch', phase: 'linear-auth' }, err);
|
|
175
|
+
console.error(chalk.red(`✗ ${err instanceof Error ? err.message : String(err)}`));
|
|
176
|
+
process.exit(isLinearConfigError(err) ? 1 : 2);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
159
179
|
fileLog({ level: 'info', event: 'session_start', command: 'watch' });
|
|
160
180
|
// Fetch the authenticated user so the onComment handler can reject annotation
|
|
161
181
|
// injection from non-token accounts. If this fails, the handler is disabled
|
|
@@ -235,9 +255,16 @@ export async function runWatch(opts = {}) {
|
|
|
235
255
|
title: params.title,
|
|
236
256
|
body: params.body ?? '',
|
|
237
257
|
head: { ref: params.headRef, sha: params.headSha, repo: params.headRepo ? { full_name: params.headRepo } : null },
|
|
238
|
-
base: {
|
|
258
|
+
base: {
|
|
259
|
+
ref: params.baseRef,
|
|
260
|
+
repo: {
|
|
261
|
+
full_name: `${owner}/${repoName}`,
|
|
262
|
+
...(params.defaultBranch !== undefined && { default_branch: params.defaultBranch }),
|
|
263
|
+
},
|
|
264
|
+
},
|
|
239
265
|
html_url: `https://github.com/${owner}/${repoName}/pull/${prNumber}`,
|
|
240
266
|
user: { login: params.author },
|
|
267
|
+
...(params.labels !== undefined && { labels: params.labels.map(name => ({ name })) }),
|
|
241
268
|
};
|
|
242
269
|
if (!acquirePRLock(owner, repoName, prNumber, params.headSha)) {
|
|
243
270
|
fileLog({ level: 'info', event: 'pr_skipped', repo: `${owner}/${repoName}`, pr: prNumber, reason: 'in_progress_local' });
|
|
@@ -407,6 +434,32 @@ export async function runWatch(opts = {}) {
|
|
|
407
434
|
let stopHeartbeat = () => { };
|
|
408
435
|
let boardAdded = false;
|
|
409
436
|
try {
|
|
437
|
+
// Board first, so any failure below is visible rather than swallowed by the
|
|
438
|
+
// enclosing catch (which only calls logError — a no-op when file logging is
|
|
439
|
+
// off). Then auth, then the clone: during an outage a long-running watcher
|
|
440
|
+
// would otherwise pay for a full clone on every event before rejecting it.
|
|
441
|
+
// Computed here rather than at the runWorkflow call so the auth gate below
|
|
442
|
+
// sees the workflow that will actually run. resolvedSteps alone is
|
|
443
|
+
// undefined for a plain event, and canWriteVerdict fails open on undefined
|
|
444
|
+
// — which let a fix-only daemon resolve credentials on every event.
|
|
445
|
+
const workflowStepsForRun = resolvedSteps
|
|
446
|
+
?? (repoStepOverride ? filterStepsByTypes(loadWorkflow(process.cwd()), repoStepOverride) : loadWorkflow(process.cwd()));
|
|
447
|
+
board.addPR(key, prNumber, `${owner}/${repoName}`, params.headRef, round);
|
|
448
|
+
boardAdded = true;
|
|
449
|
+
// Only workflows that can write a verdict need an identity — the fix and
|
|
450
|
+
// resolve paths never call notifyLinear.
|
|
451
|
+
let linearAuth = null;
|
|
452
|
+
if (linearWritePossible(effectiveConfig.linear, workflowStepsForRun)) {
|
|
453
|
+
try {
|
|
454
|
+
linearAuth = await resolveLinearAuth(effectiveConfig.linear, getLinearCredentials(effectiveConfig.linear.auth));
|
|
455
|
+
}
|
|
456
|
+
catch (err) {
|
|
457
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
458
|
+
board.failPR(key, `linear identity unavailable: ${message}`);
|
|
459
|
+
fileLog({ level: 'error', event: 'linear_auth_failed', repo: `${owner}/${repoName}`, pr: prNumber, reason: message });
|
|
460
|
+
throw err;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
410
463
|
await clonePRForReview({
|
|
411
464
|
owner, repo: repoName, prNumber, baseRef: params.baseRef,
|
|
412
465
|
tmpDir, token, protocol: config.clone_protocol,
|
|
@@ -442,18 +495,18 @@ export async function runWatch(opts = {}) {
|
|
|
442
495
|
logError({ repo: `${owner}/${repoName}`, pr: prNumber, phase: 'no_diff_comment' }, err);
|
|
443
496
|
}
|
|
444
497
|
await releaseRemoteLock(lockOctokit, owner, repoName, params.headSha, 'success');
|
|
498
|
+
// The PR is on the board from before the clone, so close its slot rather
|
|
499
|
+
// than leaving a row that never resolves.
|
|
500
|
+
board.completePR(key, { elapsedMs: Date.now() - reviewStart, url: `https://github.com/${owner}/${repoName}/pull/${prNumber}` });
|
|
445
501
|
return;
|
|
446
502
|
}
|
|
447
|
-
board.addPR(key, prNumber, `${owner}/${repoName}`, params.headRef, round);
|
|
448
|
-
boardAdded = true;
|
|
449
503
|
const prLoc = computePRLoc(tmpDir, params.baseRef);
|
|
450
504
|
board.updatePR(key, { prLoc });
|
|
451
505
|
stopHeartbeat = startRemoteLockHeartbeat(lockOctokit, owner, repoName, params.headSha);
|
|
452
|
-
const
|
|
453
|
-
?? (repoStepOverride ? filterStepsByTypes(loadWorkflow(process.cwd()), repoStepOverride) : undefined);
|
|
454
|
-
const { verdict, fixAppliedCount } = await runWorkflow({
|
|
506
|
+
const { verdict, fixAppliedCount, strategySkipped } = await runWorkflow({
|
|
455
507
|
owner, repoName, prNumber, pr,
|
|
456
508
|
tmpDir, token, config: effectiveConfig, origin,
|
|
509
|
+
linearAuth,
|
|
457
510
|
reviewStart,
|
|
458
511
|
log: (msg) => bLog(`${chalk.dim(fmtTime())} ${msg}`),
|
|
459
512
|
onPhaseChange: (label, data) => board.updatePR(key, { label, ...data }),
|
|
@@ -471,9 +524,16 @@ export async function runWatch(opts = {}) {
|
|
|
471
524
|
trigger: params.action === 'backtrace' ? 'backtrace' : params.action === 'comment' ? 'comment' : 'watch',
|
|
472
525
|
});
|
|
473
526
|
void verdict;
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
527
|
+
// A strategy-skipped PR never ran a review, so it must stay out of the
|
|
528
|
+
// session caches. reviewedPRKeys is what makes the next event on this PR
|
|
529
|
+
// an `isRecheckRun`, and a review coerced to a recheck is deliberately
|
|
530
|
+
// never gated by max_rounds — so a lockfile-only PR that later gains
|
|
531
|
+
// source files would be "rechecked" against findings never posted.
|
|
532
|
+
if (strategySkipped === undefined) {
|
|
533
|
+
reviewedPRKeys.add(prKey);
|
|
534
|
+
reviewedPRShaKeys.add(key); // key = "owner/repo#pr@sha"
|
|
535
|
+
prRoundCounts.set(prKey, round);
|
|
536
|
+
}
|
|
477
537
|
// Recompute the diff hash AFTER runWorkflow — workflow steps such as
|
|
478
538
|
// `conflict-resolve` or `fix` followed by `recheck` can mutate the checkout,
|
|
479
539
|
// so the pre-workflow hash may not represent the content that was actually
|
|
@@ -493,7 +553,10 @@ export async function runWatch(opts = {}) {
|
|
|
493
553
|
}
|
|
494
554
|
catch { /* fall back — skip auto-loop this cycle */ }
|
|
495
555
|
}
|
|
496
|
-
|
|
556
|
+
// Same gate as the session caches above: caching the diff of a PR that was
|
|
557
|
+
// never reviewed would make the first event that *should* review it get
|
|
558
|
+
// skipped as `no_diff_change`.
|
|
559
|
+
if (newDiffHash && strategySkipped === undefined) {
|
|
497
560
|
// For non-commit delivery with an applied fix the checkout may be on a fix
|
|
498
561
|
// branch; computeDiffHash would return the post-fix diff, not the original PR
|
|
499
562
|
// diff. Caching that under prKey corrupts future no_diff_change checks for the
|
|
@@ -514,9 +577,15 @@ export async function runWatch(opts = {}) {
|
|
|
514
577
|
}
|
|
515
578
|
}
|
|
516
579
|
}
|
|
580
|
+
// A class-skipped PR (e.g. lockfile-only) never ran a review, so say so
|
|
581
|
+
// rather than reporting it as a completed one.
|
|
582
|
+
if (strategySkipped) {
|
|
583
|
+
bLog(`${chalk.dim(fmtTime())} ${chalk.dim(`PR #${prNumber} skipped — ${strategySkipped} class, nothing to review`)}`);
|
|
584
|
+
}
|
|
517
585
|
board.completePR(key, {
|
|
518
586
|
elapsedMs: Date.now() - reviewStart,
|
|
519
587
|
url: `github.com/${owner}/${repoName}/pull/${prNumber}`,
|
|
588
|
+
...(strategySkipped !== undefined && { label: `skipped · ${strategySkipped}` }),
|
|
520
589
|
});
|
|
521
590
|
// Smart-switch recovery confirmation: if a restore attempt is pending and
|
|
522
591
|
// this reviewer matches the previously-degraded vendor, announce full restoration.
|
|
@@ -649,6 +718,8 @@ export async function runWatch(opts = {}) {
|
|
|
649
718
|
title: pr.title, body: pr.body, author: pr.user.login,
|
|
650
719
|
headSha: pr.head.sha, headRef: pr.head.ref, headRepo: pr.head.repo?.full_name ?? null,
|
|
651
720
|
baseRef: pr.base.ref, action: event.action,
|
|
721
|
+
...(pr.labels !== undefined && { labels: pr.labels.map(l => l.name) }),
|
|
722
|
+
...(pr.base.repo.default_branch !== undefined && { defaultBranch: pr.base.repo.default_branch }),
|
|
652
723
|
});
|
|
653
724
|
}, (msg) => bLog(chalk.dim(fmtTime()) + ' ' + msg), fileLog, async (event) => {
|
|
654
725
|
const owner = event.repository.owner.login;
|
|
@@ -743,6 +814,11 @@ export async function runWatch(opts = {}) {
|
|
|
743
814
|
headRepo: prData.head.repo?.full_name ?? null,
|
|
744
815
|
baseRef: prData.base.ref,
|
|
745
816
|
action: 'comment',
|
|
817
|
+
// Same fields the webhook path forwards: without them the risky
|
|
818
|
+
// class's label and hotfix rules classify this PR differently
|
|
819
|
+
// depending on which trigger ran it.
|
|
820
|
+
...(prData.labels !== undefined && { labels: prData.labels.map((l) => l.name) }),
|
|
821
|
+
...(prData.base.repo?.default_branch !== undefined && { defaultBranch: prData.base.repo.default_branch }),
|
|
746
822
|
});
|
|
747
823
|
break;
|
|
748
824
|
}
|
|
@@ -1029,6 +1105,8 @@ export async function runWatch(opts = {}) {
|
|
|
1029
1105
|
title: pr.title, body: pr.body, author: pr.author,
|
|
1030
1106
|
headSha: pr.headSha, headRef: pr.headRef, headRepo: pr.headRepo,
|
|
1031
1107
|
baseRef: pr.baseRef, action: 'backtrace',
|
|
1108
|
+
...(pr.labels !== undefined && { labels: pr.labels }),
|
|
1109
|
+
...(pr.defaultBranch !== undefined && { defaultBranch: pr.defaultBranch }),
|
|
1032
1110
|
})));
|
|
1033
1111
|
}
|
|
1034
1112
|
catch (err) {
|