@agentskit/code-review 0.1.0 → 0.4.1

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 (76) hide show
  1. package/.doc-bridge/capabilities.json +34 -0
  2. package/.doc-bridge/index.json +94 -0
  3. package/.pre-commit-hooks.yaml +9 -0
  4. package/AGENTS.md +20 -0
  5. package/CHANGELOG.md +85 -0
  6. package/CONTRIBUTING.md +45 -0
  7. package/README.md +238 -33
  8. package/ROADMAP.md +20 -0
  9. package/SECURITY.md +16 -0
  10. package/action.yml +120 -0
  11. package/dist/agents/code-review/agent.js +453 -76
  12. package/dist/agents/code-review/agent.js.map +1 -1
  13. package/dist/agents/code-review/lenses.js +17 -1
  14. package/dist/agents/code-review/lenses.js.map +1 -1
  15. package/dist/agents/code-review/reporters.js +83 -7
  16. package/dist/agents/code-review/reporters.js.map +1 -1
  17. package/dist/agents/code-review/sources.js +324 -73
  18. package/dist/agents/code-review/sources.js.map +1 -1
  19. package/dist/src/acp-cli-adapter.js +127 -0
  20. package/dist/src/acp-cli-adapter.js.map +1 -0
  21. package/dist/src/batch-coverage.js +111 -0
  22. package/dist/src/batch-coverage.js.map +1 -0
  23. package/dist/src/claude-code-adapter.js +44 -60
  24. package/dist/src/claude-code-adapter.js.map +1 -1
  25. package/dist/src/cli.js +347 -50
  26. package/dist/src/cli.js.map +1 -1
  27. package/dist/src/codex-adapter.js +114 -69
  28. package/dist/src/codex-adapter.js.map +1 -1
  29. package/dist/src/github-review-state.js +134 -0
  30. package/dist/src/github-review-state.js.map +1 -0
  31. package/dist/src/grok-cli-adapter.js +27 -0
  32. package/dist/src/grok-cli-adapter.js.map +1 -0
  33. package/dist/src/headless-cli-adapter.js +78 -0
  34. package/dist/src/headless-cli-adapter.js.map +1 -0
  35. package/dist/src/local-cli-process.js +328 -0
  36. package/dist/src/local-cli-process.js.map +1 -0
  37. package/dist/src/local-cli-timeout.js +14 -0
  38. package/dist/src/local-cli-timeout.js.map +1 -0
  39. package/dist/src/ollama-adapter.js +155 -0
  40. package/dist/src/ollama-adapter.js.map +1 -0
  41. package/dist/src/opencode-cli-adapter.js +57 -0
  42. package/dist/src/opencode-cli-adapter.js.map +1 -0
  43. package/dist/src/provider-circuit-breaker.js +52 -0
  44. package/dist/src/provider-circuit-breaker.js.map +1 -0
  45. package/dist/src/provider-registry.js +168 -0
  46. package/dist/src/provider-registry.js.map +1 -0
  47. package/dist/src/review-config.js +145 -0
  48. package/dist/src/review-config.js.map +1 -0
  49. package/doc-bridge.config.json +116 -0
  50. package/docs/OPERATIONS.md +358 -0
  51. package/docs/assets/agentskit-mark.svg +10 -0
  52. package/docs/assets/code-review-terminal.png +0 -0
  53. package/docs/continuous-improvement.md +35 -0
  54. package/docs/for-agents/code-review-cli.md +70 -0
  55. package/docs/for-agents/index.md +5 -0
  56. package/docs/plans/ecosystem-doc-quality-code-review.md +61 -0
  57. package/docs/provider-compatibility.json +35 -0
  58. package/ecosystem-claims.json +187 -0
  59. package/ecosystem.json +277 -0
  60. package/examples/pull-request.yml +29 -0
  61. package/llms-full.txt +1049 -0
  62. package/llms.txt +24 -0
  63. package/package.json +53 -7
  64. package/scripts/generate-llms-full.mjs +68 -0
  65. package/scripts/run-cycle-benchmark.mjs +64 -0
  66. package/test/cli-smoke.test.mjs +507 -0
  67. package/test/continuous-improvement.test.mjs +20 -0
  68. package/test/documentation.test.mjs +238 -0
  69. package/test/release-workflow.test.mjs +31 -0
  70. package/dist/agents/code-review/agent.d.ts +0 -115
  71. package/dist/agents/code-review/lenses.d.ts +0 -10
  72. package/dist/agents/code-review/reporters.d.ts +0 -31
  73. package/dist/agents/code-review/sources.d.ts +0 -27
  74. package/dist/src/claude-code-adapter.d.ts +0 -4
  75. package/dist/src/cli.d.ts +0 -2
  76. package/dist/src/codex-adapter.d.ts +0 -4
@@ -0,0 +1,111 @@
1
+ export function partitionReviewableFiles(files, batchSize) {
2
+ if (!Number.isInteger(batchSize) || batchSize < 1)
3
+ throw new Error('batch size must be a positive integer');
4
+ const unique = [...new Set(files)].sort();
5
+ return Array.from({ length: Math.ceil(unique.length / batchSize) }, (_, index) => ({ index, files: unique.slice(index * batchSize, (index + 1) * batchSize) }));
6
+ }
7
+ export function createBatchCoverage(input) {
8
+ const indices = new Set();
9
+ for (const batch of input.batches) {
10
+ if (!Number.isInteger(batch.index) || batch.index < 0 || indices.has(batch.index) || !batch.files.length)
11
+ throw new Error('invalid batch coverage manifest');
12
+ indices.add(batch.index);
13
+ }
14
+ return { version: 1, repository: input.repository, pullNumber: input.pullNumber, headSha: input.headSha, policyFingerprint: input.policyFingerprint, batches: input.batches.map((batch) => ({ ...batch, files: [...batch.files], completed: false, findings: 0 })) };
15
+ }
16
+ export function recordBatch(state, input) {
17
+ if (input.headSha !== state.headSha || input.policyFingerprint !== state.policyFingerprint)
18
+ throw new Error('stale batch coverage state');
19
+ const batch = state.batches.find((item) => item.index === input.index);
20
+ if (!batch || batch.completed || !Number.isInteger(input.findings) || input.findings < 0)
21
+ throw new Error('invalid batch result');
22
+ return { ...state, batches: state.batches.map((item) => item.index === input.index ? { ...item, completed: true, findings: input.findings } : item) };
23
+ }
24
+ export function finalCoverage(state) {
25
+ const pending = state.batches.filter((batch) => !batch.completed).map((batch) => batch.index);
26
+ return { complete: pending.length === 0, findings: state.batches.reduce((sum, batch) => sum + batch.findings, 0), pending };
27
+ }
28
+ export function publicationDecision(state) {
29
+ const coverage = finalCoverage(state);
30
+ if (!coverage.complete)
31
+ return { publish: false, reason: `coverage incomplete; pending batches: ${coverage.pending.join(', ')}` };
32
+ if (coverage.findings)
33
+ return { publish: true, reason: `${coverage.findings} verified finding(s)` };
34
+ return { publish: true, reason: 'complete coverage with zero findings' };
35
+ }
36
+ function assertUsableArtifact(state, artifact) {
37
+ if (artifact.version !== 1 || artifact.repository !== state.repository || artifact.pullNumber !== state.pullNumber)
38
+ throw new Error('batch result does not belong to this PR');
39
+ if (artifact.headSha !== state.headSha || artifact.policyFingerprint !== state.policyFingerprint)
40
+ throw new Error('stale batch result');
41
+ const expected = state.batches.find((batch) => batch.index === artifact.batch.index);
42
+ if (!expected || expected.files.join('\0') !== artifact.batch.files.join('\0'))
43
+ throw new Error('batch result does not match the planned file manifest');
44
+ if (artifact.review.unreviewed?.length || artifact.review.missingRequiredLenses?.length || artifact.review.execution.failed || artifact.review.execution.succeeded !== artifact.review.execution.attempted || artifact.review.evidence.deadlineExceeded) {
45
+ throw new Error(`batch ${artifact.batch.index} has incomplete review evidence`);
46
+ }
47
+ }
48
+ /**
49
+ * Validates every private artifact against the immutable manifest and returns the
50
+ * only result that may be published. A partial, stale, failed, or duplicate batch
51
+ * is rejected rather than silently becoming a clean review.
52
+ */
53
+ export function consolidateBatchArtifacts(state, artifacts) {
54
+ let recorded = state;
55
+ const seen = new Set();
56
+ for (const artifact of artifacts) {
57
+ assertUsableArtifact(state, artifact);
58
+ if (seen.has(artifact.batch.index))
59
+ throw new Error(`duplicate batch result: ${artifact.batch.index}`);
60
+ seen.add(artifact.batch.index);
61
+ recorded = recordBatch(recorded, {
62
+ headSha: artifact.headSha,
63
+ policyFingerprint: artifact.policyFingerprint,
64
+ index: artifact.batch.index,
65
+ findings: artifact.review.findings.length,
66
+ });
67
+ }
68
+ const decision = publicationDecision(recorded);
69
+ if (!decision.publish)
70
+ throw new Error(decision.reason);
71
+ const reviews = [...artifacts].sort((a, b) => a.batch.index - b.batch.index).map((artifact) => artifact.review);
72
+ const findings = reviews.flatMap((review) => review.findings);
73
+ const dropped = reviews.flatMap((review) => review.dropped);
74
+ const execution = reviews.reduce((total, review) => ({
75
+ attempted: total.attempted + review.execution.attempted,
76
+ succeeded: total.succeeded + review.execution.succeeded,
77
+ failed: total.failed + review.execution.failed,
78
+ }), { attempted: 0, succeeded: 0, failed: 0 });
79
+ const evidence = reviews.reduce((total, review) => ({
80
+ profile: total.profile,
81
+ providerCalls: total.providerCalls + review.evidence.providerCalls,
82
+ failedProviderCalls: total.failedProviderCalls + review.evidence.failedProviderCalls,
83
+ skippedProviderCalls: total.skippedProviderCalls + review.evidence.skippedProviderCalls,
84
+ elapsedMs: total.elapsedMs + review.evidence.elapsedMs,
85
+ deadlineMs: total.deadlineMs + review.evidence.deadlineMs,
86
+ deadlineExceeded: total.deadlineExceeded || review.evidence.deadlineExceeded,
87
+ circuitState: total.circuitState === 'open' || review.evidence.circuitState === 'open' ? 'open' : total.circuitState,
88
+ }), { profile: reviews[0].evidence.profile, providerCalls: 0, failedProviderCalls: 0, skippedProviderCalls: 0, elapsedMs: 0, deadlineMs: 0, deadlineExceeded: false, circuitState: 'closed' });
89
+ const severe = findings.some((finding) => finding.severity === 'blocker' || finding.severity === 'high');
90
+ return {
91
+ verdict: !findings.length ? 'APPROVE' : severe ? 'REQUEST CHANGES' : 'COMMENT',
92
+ blocking: reviews.some((review) => review.blocking),
93
+ incomplete: false,
94
+ findings,
95
+ dropped,
96
+ execution,
97
+ evidence,
98
+ summary: `Complete batch review: ${reviews.length} batch(es), ${state.batches.reduce((total, batch) => total + batch.files.length, 0)} file(s), ${findings.length} verified finding(s).`,
99
+ };
100
+ }
101
+ export function consolidateToArtifact(state, artifacts) {
102
+ return {
103
+ version: 1,
104
+ repository: state.repository,
105
+ pullNumber: state.pullNumber,
106
+ headSha: state.headSha,
107
+ policyFingerprint: state.policyFingerprint,
108
+ review: consolidateBatchArtifacts(state, artifacts),
109
+ };
110
+ }
111
+ //# sourceMappingURL=batch-coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-coverage.js","sourceRoot":"","sources":["../../src/batch-coverage.ts"],"names":[],"mappings":"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"}
@@ -1,35 +1,16 @@
1
- /**
2
- * AgentsKit adapter backed by the local `claude -p` (Claude Code headless) — no
3
- * ANTHROPIC_API_KEY needed; uses your logged-in CLI. `claude -p` is an agent, not a
4
- * raw model API, so this adapter is tuned for the promote pipeline's pattern: each
5
- * stage offers exactly ONE tool, so we tell Claude to emit only that tool's JSON
6
- * args and synthesize the `tool_call` stream chunk the runtime expects.
7
- */
8
- import { execFile } from "node:child_process";
1
+ import { runLocalCli } from "./local-cli-process.js";
9
2
  /**
10
3
  * Run `claude` and capture stdout. Crucially we CLOSE the child's stdin: in a
11
4
  * non-TTY env (CI / self-hosted runner) `claude -p` otherwise blocks waiting for
12
5
  * stdin ("no stdin data received in 3s …") and fails. Locally stdin is a TTY so it
13
6
  * never showed. stderr is attached to the error for diagnosis.
14
7
  */
15
- function runClaude(args) {
16
- return new Promise((resolve, reject) => {
17
- // Run from HOME (a trusted dir): the runner's checkout dir is untrusted and can
18
- // make claude exit without output (folder-trust). The file under review is in the
19
- // prompt, not read from cwd, so cwd is irrelevant to the result.
20
- const child = execFile("claude", args, { maxBuffer: 20 * 1024 * 1024, cwd: process.env.HOME }, (err, stdout, stderr) => {
21
- if (err) {
22
- const e = err;
23
- e.stderr = stderr;
24
- e.stdout = stdout;
25
- reject(err);
26
- }
27
- else {
28
- resolve(stdout);
29
- }
30
- });
31
- child.stdin?.end();
32
- });
8
+ async function runClaude(args, signal, mode, worker, oauthToken) {
9
+ // Run from HOME (a trusted dir): the runner's checkout dir is untrusted and can
10
+ // make claude exit without output (folder-trust). The file under review is in the
11
+ // prompt, not read from cwd, so cwd is irrelevant to the result.
12
+ const { stdout } = await runLocalCli("claude", args, { signal, mode, providerCredential: oauthToken ? { name: "CLAUDE_CODE_OAUTH_TOKEN", value: oauthToken } : undefined, ...worker });
13
+ return stdout;
33
14
  }
34
15
  /**
35
16
  * Pull the JSON object out of a model reply: first `{` to last `}` over the whole
@@ -47,42 +28,45 @@ function extractJson(text) {
47
28
  export function claudeCode(opts = {}) {
48
29
  return {
49
30
  capabilities: { streaming: false, tools: true, structuredOutput: true },
50
- createSource: (request) => ({
51
- stream: async function* () {
52
- try {
53
- const system = request.messages.find((m) => m.role === "system")?.content ?? "";
54
- const convo = request.messages
55
- .filter((m) => m.role !== "system")
56
- .map((m) => `${m.role.toUpperCase()}: ${m.content}`)
57
- .join("\n\n");
58
- const tools = request.context?.tools ?? [];
59
- let prompt = `${system}\n\n${convo}`;
60
- if (tools.length === 1) {
61
- const t = tools[0];
62
- prompt += `\n\nReturn ONLY a JSON object that is the argument to the "${t.name}" tool, matching this JSON Schema exactly. No prose, no code fences:\n${JSON.stringify(t.schema)}`;
63
- }
64
- const args = ["-p", prompt];
65
- if (opts.model)
66
- args.push("--model", opts.model);
67
- const out = (await runClaude(args)).trim();
68
- if (tools.length === 1) {
69
- yield { type: "tool_call", toolCall: { id: `tc-${Date.now()}`, name: tools[0].name, args: extractJson(out) } };
31
+ createSource: (request) => {
32
+ const controller = new AbortController();
33
+ return {
34
+ stream: async function* () {
35
+ try {
36
+ const system = request.messages.find((m) => m.role === "system")?.content ?? "";
37
+ const convo = request.messages
38
+ .filter((m) => m.role !== "system")
39
+ .map((m) => `${m.role.toUpperCase()}: ${m.content}`)
40
+ .join("\n\n");
41
+ const tools = request.context?.tools ?? [];
42
+ let prompt = `${system}\n\n${convo}`;
43
+ if (tools.length === 1) {
44
+ const t = tools[0];
45
+ prompt += `\n\nReturn ONLY a JSON object that is the argument to the "${t.name}" tool, matching this JSON Schema exactly. No prose, no code fences:\n${JSON.stringify(t.schema)}`;
46
+ }
47
+ const args = ["-p", prompt];
48
+ if (opts.model)
49
+ args.push("--model", opts.model);
50
+ const out = (await runClaude(args, controller.signal, opts.mode, opts.worker, opts.oauthToken)).trim();
51
+ if (tools.length === 1) {
52
+ yield { type: "tool_call", toolCall: { id: `tc-${Date.now()}`, name: tools[0].name, args: extractJson(out) } };
53
+ }
54
+ else {
55
+ yield { type: "text", content: out };
56
+ }
57
+ yield { type: "done" };
70
58
  }
71
- else {
72
- yield { type: "text", content: out };
59
+ catch (err) {
60
+ // Surface claude's own stderr/stdout (e.g. "Not logged in · Please run
61
+ // /login"). The default execFile message embeds the whole prompt — drop it.
62
+ const e = err;
63
+ const detail = e.code === "ETIMEDOUT" ? e.message : [e.stderr, e.stdout].filter(Boolean).join(" ").trim();
64
+ yield { type: "error", content: `claude -p failed${detail ? `: ${detail.slice(0, 400)}` : ` (no output): ${(e.message ?? "").split("\n")[0]}`}` };
73
65
  }
74
- yield { type: "done" };
75
- }
76
- catch (err) {
77
- // Surface claude's own stderr/stdout (e.g. "Not logged in · Please run
78
- // /login"). The default execFile message embeds the whole prompt — drop it.
79
- const e = err;
80
- const detail = [e.stderr, e.stdout].filter(Boolean).join(" ").trim();
81
- yield { type: "error", content: `claude -p failed${detail ? `: ${detail.slice(0, 400)}` : ` (no output): ${(e.message ?? "").split("\n")[0]}`}` };
82
- }
83
- },
84
- abort: () => { },
85
- }),
66
+ },
67
+ abort: () => controller.abort(),
68
+ };
69
+ },
86
70
  };
87
71
  }
88
72
  //# sourceMappingURL=claude-code-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code-adapter.js","sourceRoot":"","sources":["../../src/claude-code-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-code-adapter.js","sourceRoot":"","sources":["../../src/claude-code-adapter.ts"],"names":[],"mappings":"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"}