opencode-swarm 7.74.3 → 7.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Auto-review hook (auto-review machinery, piece B) — opt-in.
3
+ *
4
+ * When `auto_review.enabled` is true, completing a task
5
+ * (`update_task_status` → status 'completed') and/or a phase
6
+ * (`phase_complete`) automatically dispatches the registered reviewer agent
7
+ * over a fresh ephemeral session to review the current execution diff —
8
+ * the same "second model reviews the work in a clean context" pattern used
9
+ * by Claude Code's auto-review and Codex's review model. The reviewer agent
10
+ * carries its own configured model (`agents.reviewer.model`), so the review
11
+ * model is independently configurable from the coder/architect models.
12
+ *
13
+ * The pass is ADVISORY and fully fail-open:
14
+ * - fire-and-forget from `tool.execute.after` (never blocks the tool)
15
+ * - verdicts are persisted as durable review receipts
16
+ * (`.swarm/review-receipts/`, scope-fingerprinted over the diff) and an
17
+ * `auto_review` event is appended to `.swarm/events.jsonl`
18
+ * - a REJECTED or unparseable verdict injects a `[AUTO-REVIEW]` advisory
19
+ * into the architect's next prompt; APPROVED stays silent
20
+ *
21
+ * Bounds (AGENTS.md invariants 3 and 8): the diff subprocess uses execFile
22
+ * with cwd/timeout/maxBuffer and ignored stdin; dispatches are guarded by a
23
+ * per-session in-flight set plus a 60s cooldown in a bounded FIFO map.
24
+ */
25
+ import { type AutoReviewConfig } from '../config/schema.js';
26
+ /** Test-only: clear module-level dispatch tracking. */
27
+ export declare function resetAutoReviewTracking(): void;
28
+ export type ExecutionDiffResult = {
29
+ status: 'ok';
30
+ diff: string;
31
+ } | {
32
+ status: 'clean';
33
+ } | {
34
+ status: 'error';
35
+ reason: string;
36
+ };
37
+ /**
38
+ * Collect the execution diff for review: `git diff HEAD` (tracked changes)
39
+ * plus a porcelain summary of untracked files. Distinguishes a clean working
40
+ * tree from collection failures (git missing, timeout, diff exceeding the
41
+ * 2× maxBuffer cap) so events report honestly. Output is truncated to
42
+ * `maxBytes`.
43
+ */
44
+ declare function computeExecutionDiff(directory: string, maxBytes: number): Promise<ExecutionDiffResult>;
45
+ declare function dispatchReviewer(directory: string, prompt: string, agentName: string, timeoutMs: number): Promise<string>;
46
+ export interface AutoReviewRunInput {
47
+ directory: string;
48
+ sessionID: string;
49
+ trigger: 'task_completion' | 'phase_boundary';
50
+ taskId?: string;
51
+ phase?: number;
52
+ config: Required<Pick<AutoReviewConfig, 'timeout_ms' | 'max_diff_kb'>>;
53
+ injectAdvisory: (sessionId: string, message: string) => void;
54
+ }
55
+ /**
56
+ * Execute one auto-review pass: collect diff → dispatch reviewer over an
57
+ * ephemeral session → persist receipt + event → advisory on REJECTED or
58
+ * unparseable output. Fully fail-open; never throws.
59
+ */
60
+ export declare function runAutoReview(input: AutoReviewRunInput): Promise<void>;
61
+ export interface AutoReviewHookOptions {
62
+ config: AutoReviewConfig;
63
+ directory: string;
64
+ injectAdvisory: (sessionId: string, message: string) => void;
65
+ }
66
+ export declare function createAutoReviewHook(options: AutoReviewHookOptions): {
67
+ toolAfter: (input: {
68
+ tool: string;
69
+ sessionID: string;
70
+ callID?: string;
71
+ }, output: {
72
+ args?: unknown;
73
+ output?: unknown;
74
+ }) => Promise<void>;
75
+ };
76
+ export declare const _internals: {
77
+ computeExecutionDiff: typeof computeExecutionDiff;
78
+ dispatchReviewer: typeof dispatchReviewer;
79
+ runAutoReview: typeof runAutoReview;
80
+ now: () => number;
81
+ };
82
+ export {};
@@ -15,7 +15,7 @@
15
15
  * avoid re-reading the JSON on every system prompt construction. The
16
16
  * cache is bypassed if the file's mtime advances.
17
17
  */
18
- import { type RepoGraph } from '../graph';
18
+ import { type RepoGraph } from '../tools/repo-graph';
19
19
  /**
20
20
  * Load the repo graph for `directory`, using a per-directory cache that
21
21
  * invalidates on file mtime change. Returns null if no graph exists.
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Reviewer receipt collector (auto-review machinery, piece A).
3
+ *
4
+ * Parses the mandated reviewer OUTPUT FORMAT (`VERDICT:` / `RISK:` /
5
+ * `ISSUES:` / `FIXES:`) from a returning reviewer Task delegation and
6
+ * persists it as a durable review receipt under `.swarm/review-receipts/`
7
+ * via the existing receipt store (scope-fingerprinted over the delegation
8
+ * prompt, which defines the reviewed scope).
9
+ *
10
+ * Before this collector, reviewer verdicts existed only as free text inside
11
+ * the architect's context — re-reviews and drift verification had no durable
12
+ * machine-readable record of what the reviewer decided. Knowledge-directive
13
+ * lines (`DIRECTIVE_COMPLIANCE`) are handled separately by
14
+ * `reviewer-verdict-parser.ts`; this module covers the main verdict block.
15
+ *
16
+ * Fail-open: parsing or persistence failures never block tool execution.
17
+ */
18
+ export type ParsedReviewSeverity = 'critical' | 'high' | 'medium';
19
+ export interface ParsedReviewIssue {
20
+ /** Raw issue line (trimmed, bullet stripped) */
21
+ text: string;
22
+ /** Severity inferred from a CRITICAL/HIGH/MEDIUM/LOW/INFO tag, default medium */
23
+ severity: ParsedReviewSeverity;
24
+ /** `path:line` reference when one appears in the line */
25
+ location?: string;
26
+ }
27
+ export interface ParsedReviewerOutput {
28
+ verdict: 'approved' | 'rejected';
29
+ /** RISK: LOW | MEDIUM | HIGH | CRITICAL (uppercased), when present */
30
+ risk?: string;
31
+ /** Blocking/non-blocking issue lines from the ISSUES section */
32
+ issues: ParsedReviewIssue[];
33
+ /** Required-change lines from the FIXES section */
34
+ fixes: string[];
35
+ }
36
+ /**
37
+ * Parse the reviewer agent's mandated output block. Returns null when no
38
+ * unambiguous line-anchored `VERDICT: APPROVED|REJECTED` is present —
39
+ * including when multiple anchored verdict lines DISAGREE (ambiguous output
40
+ * fails toward "no machine-readable verdict", never toward approval).
41
+ */
42
+ export declare function parseReviewerOutput(text: string): ParsedReviewerOutput | null;
43
+ export interface ReviewerReceiptInput {
44
+ tool: unknown;
45
+ args?: unknown;
46
+ sessionID?: unknown;
47
+ }
48
+ export interface ReviewerReceiptOutput {
49
+ output?: unknown;
50
+ }
51
+ /**
52
+ * `tool.execute.after` collector. When a reviewer Task returns, parse its
53
+ * verdict block and persist a durable review receipt. No-op for non-reviewer
54
+ * delegations, missing prompts/outputs, or unparseable verdicts. Never throws.
55
+ *
56
+ * Returns the persisted receipt path (for tests/telemetry) or null.
57
+ */
58
+ export declare function collectReviewerReceiptAfter(directory: string, input: ReviewerReceiptInput, output: ReviewerReceiptOutput): Promise<string | null>;
@@ -20,6 +20,13 @@
20
20
  *
21
21
  * Critic drift verification can consume prior receipts as supporting context
22
22
  * but MUST NOT blindly trust them — staleness check is mandatory.
23
+ *
24
+ * Scope-description heterogeneity: receipts in one index may be fingerprinted
25
+ * over different canonical contents (e.g. 'reviewer-task-prompt' hashes the
26
+ * delegation prompt; 'auto-review-*-diff' hashes the reviewed diff). A prompt
27
+ * fingerprint does NOT change when the worktree changes, so consumers MUST
28
+ * filter by `scope_fingerprint.scope_description` (or compare like-for-like
29
+ * content) before treating an approved receipt as fresh via isScopeStale().
23
30
  */
24
31
  export type ReceiptVerdict = 'rejected' | 'approved';
25
32
  /** Identity of the reviewer/curator that produced the receipt. */