opencode-swarm 7.71.0 → 7.71.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.
@@ -1,239 +1,14 @@
1
1
  /**
2
- * Guardrails Hook Module
2
+ * Guardrails Hook Module — Barrel
3
+ *
4
+ * Re-exports from submodules for backward compatibility.
5
+ * All implementation lives in the submodules under guardrails/.
3
6
  *
4
7
  * Circuit breaker for runaway LLM agents. Monitors tool usage via OpenCode Plugin API hooks
5
8
  * and implements two-layer protection:
6
9
  * - Layer 1 (Soft Warning @ warning_threshold): Sets warning flag for messagesTransform to inject warning
7
10
  * - Layer 2 (Hard Block @ 100%): Throws error in toolBefore to block further calls, injects STOP message
8
11
  */
9
- import * as path from 'node:path';
10
- import { extractSwarmIdFromAgentName, getSwarmAgents, resolveFallbackModel } from '../agents/index';
11
- import { type AuthorityConfig, type GuardrailsConfig } from '../config/schema';
12
- import { type FileZone } from '../context/zone-classifier';
13
- export declare const _internals: {
14
- extractSwarmIdFromAgentName: typeof extractSwarmIdFromAgentName;
15
- getSwarmAgents: typeof getSwarmAgents;
16
- getMostRecentAssistantText: typeof getMostRecentAssistantText;
17
- getProviderFailureFingerprint: typeof getProviderFailureFingerprint;
18
- isTransientProviderFailureText: typeof isTransientProviderFailureText;
19
- resolveFallbackModel: typeof resolveFallbackModel;
20
- dcCheckJunctionCreation: typeof dcCheckJunctionCreation;
21
- extractErrorSignal: typeof extractErrorSignal;
22
- };
23
- /**
24
- * Issue #853 Layer B: tools that are structurally blocked while
25
- * `.swarm/spec-staleness.json` exists. Every blocked tool mutates plan
26
- * state (save_plan, update_task_status, phase_complete) or proceeds with
27
- * lean-turbo execution (lean_turbo_run_phase, lean_turbo_acquire_locks).
28
- * The architect must run /swarm clarify or /swarm acknowledge-spec-drift
29
- * before any of these will succeed.
30
- *
31
- * Read tools (get_approved_plan, lint_spec, set_qa_gates, convene_*,
32
- * lean_turbo_plan_lanes, lean_turbo_runner_status, lean_turbo_review) are
33
- * intentionally NOT blocked — drift surfacing should not block exploration.
34
- */
35
- export declare const SPEC_DRIFT_BLOCKED_TOOLS: Set<string>;
36
- /**
37
- * Throw SPEC_DRIFT_BLOCK if the tool is on the block-list and the
38
- * spec-staleness marker file exists. Layer B is structural (not a
39
- * retryable error) — deterministic disk read every call, no cache, so
40
- * /swarm acknowledge-spec-drift (which removes the marker) is reflected
41
- * immediately on the next tool call.
42
- */
43
- export declare function enforceSpecDriftGate(directory: string | undefined, toolName: string): void;
44
- /**
45
- * Extracts bounded provider/error signal from unknown hook error payloads.
46
- * Do not stringify arbitrary objects here: unrelated fields like `phase: 502`
47
- * must not accidentally become transient provider errors.
48
- */
49
- declare function extractErrorSignal(errorContent: unknown): string;
50
- type ChatMessageLike = {
51
- info?: {
52
- role?: string;
53
- sessionID?: string;
54
- };
55
- parts?: Array<{
56
- type?: string;
57
- text?: unknown;
58
- }>;
59
- };
60
- declare function getMostRecentAssistantText(messages: ChatMessageLike[]): string;
61
- declare function isTransientProviderFailureText(text: string): boolean;
62
- declare function getProviderFailureFingerprint(text: string): string;
63
- /**
64
- * Retrieves stored input args for a given callID.
65
- * Used by other hooks (e.g., delegation-gate) to access tool input args.
66
- * @param callID The callID to look up
67
- * @returns The stored args or undefined if not found
68
- */
69
- export declare function getStoredInputArgs(callID: string): unknown | undefined;
70
- /**
71
- * Stores input args for a given callID.
72
- * Used by guardrails toolBefore hook; may be used by other hooks if needed.
73
- * @param callID The callID to store args under
74
- * @param args The tool input args to store
75
- */
76
- export declare function setStoredInputArgs(callID: string, args: unknown): void;
77
- /**
78
- * Deletes stored input args for a given callID (cleanup after retrieval).
79
- * @param callID The callID to delete
80
- */
81
- export declare function deleteStoredInputArgs(callID: string): void;
82
- /**
83
- * Detect Windows junction or symlink CREATION commands.
84
- * Junction creation followed by recursive deletion of the junction is the
85
- * exact mechanism of the K2.6 data-loss incident.
86
- * Block junction/symlink creation where the target resolves outside cwd.
87
- *
88
- * Patterns covered:
89
- * mklink /J <link> <target>
90
- * mklink /D <link> <target>
91
- * New-Item -ItemType Junction -Path <link> -Target <target>
92
- * New-Item -ItemType SymbolicLink -Path <link> -Target <target>
93
- * ln -s <target> <link> (when target is outside cwd)
94
- */
95
- declare function dcCheckJunctionCreation(segment: string, cwd: string): string | null;
96
- /**
97
- * Redacts sensitive values from a shell command string before audit logging.
98
- * Covers env-var assignments, CLI flags, Bearer/Basic auth, and -H header flags.
99
- * Conservative: only redacts patterns with well-known secret-bearing names.
100
- * Export allows unit testing without spinning up a full hooks factory.
101
- */
102
- export declare function redactShellCommand(cmd: string): string;
103
- /**
104
- * Creates guardrails hooks for circuit breaker protection
105
- * @param directory Working directory from plugin init context (required)
106
- * @param directoryOrConfig Guardrails configuration object (when passed as second arg, replaces legacy config param)
107
- * @param config Guardrails configuration (optional)
108
- * @returns Tool before/after hooks and messages transform hook
109
- */
110
- export declare function createGuardrailsHooks(directory: string, directoryOrConfig?: string | GuardrailsConfig, config?: GuardrailsConfig, authorityConfig?: AuthorityConfig): {
111
- toolBefore: (input: {
112
- tool: string;
113
- sessionID: string;
114
- callID: string;
115
- }, output: {
116
- args: unknown;
117
- }) => Promise<void>;
118
- toolAfter: (input: {
119
- tool: string;
120
- sessionID: string;
121
- callID: string;
122
- args?: Record<string, unknown>;
123
- }, output: {
124
- title: string;
125
- output: string;
126
- metadata: unknown;
127
- }) => Promise<void>;
128
- messagesTransform: (input: Record<string, never>, output: {
129
- messages?: Array<{
130
- info: {
131
- role: string;
132
- agent?: string;
133
- sessionID?: string;
134
- };
135
- parts: Array<{
136
- type: string;
137
- text?: string;
138
- [key: string]: unknown;
139
- }>;
140
- }>;
141
- }) => Promise<void>;
142
- };
143
- /**
144
- * Hashes tool arguments for repetition detection
145
- * @param args Tool arguments to hash
146
- * @returns Numeric hash (0 if hashing fails)
147
- */
148
- export declare function hashArgs(args: unknown): number;
149
- /** A record of an agent attesting to (resolving/suppressing/deferring) a finding. */
150
- export interface AttestationRecord {
151
- findingId: string;
152
- agent: string;
153
- attestation: string;
154
- action: 'resolve' | 'suppress' | 'defer';
155
- timestamp: string;
156
- }
157
- /**
158
- * Validates that an attestation string meets the minimum length requirement.
159
- */
160
- export declare function validateAttestation(attestation: string, _findingId: string, _agent: string, _action: 'resolve' | 'suppress' | 'defer'): {
161
- valid: true;
162
- } | {
163
- valid: false;
164
- reason: string;
165
- };
166
- /**
167
- * Appends an attestation record to `.swarm/evidence/attestations.jsonl`.
168
- */
169
- export declare function recordAttestation(dir: string, record: AttestationRecord): Promise<void>;
170
- /**
171
- * Validates an attestation and, on success, records it; on failure, logs a rejection event.
172
- */
173
- export declare function validateAndRecordAttestation(dir: string, findingId: string, agent: string, attestation: string, action: 'resolve' | 'suppress' | 'defer'): Promise<{
174
- valid: true;
175
- } | {
176
- valid: false;
177
- reason: string;
178
- }>;
179
- /**
180
- * Clears all guardrails caches.
181
- * Use this for test isolation or when guardrails config reloads at runtime.
182
- */
183
- export declare function clearGuardrailsCaches(): void;
184
- type AgentRule = {
185
- readOnly?: boolean;
186
- blockedExact?: string[];
187
- allowedExact?: string[];
188
- blockedPrefix?: string[];
189
- allowedPrefix?: string[];
190
- blockedZones?: FileZone[];
191
- blockedGlobs?: string[];
192
- allowedGlobs?: string[];
193
- };
194
- export declare const DEFAULT_AGENT_AUTHORITY_RULES: Record<string, AgentRule>;
195
- /**
196
- * Checks whether a write target path (or any ancestor strictly inside cwd)
197
- * is a symlink. Writing through a symlink can redirect the write to a
198
- * location outside the working directory, bypassing scope containment.
199
- *
200
- * The walk stops at cwd — cwd itself is NOT lstat'd. A user's chosen
201
- * working directory may legitimately be reached via a symlink (e.g.,
202
- * macOS's /tmp → /private/tmp), and that symlink does not constitute a
203
- * redirect *within* the workspace. Only attacker-plantable symlinks
204
- * BELOW cwd are relevant to this guard.
205
- *
206
- * ENOENT on any node in the chain is allowed — the file/dir doesn't exist yet.
207
- * Any other lstat error (EPERM, EACCES, ENAMETOOLONG, …) fails closed:
208
- * an unverifiable ancestor must not be written through, even if the OS
209
- * would eventually reject the write. Defense-in-depth over optimism.
210
- *
211
- * @returns A block reason string if a symlink is detected, null if all clear.
212
- */
213
- export declare function checkWriteTargetForSymlink(targetPath: string, cwd: string): string | null;
214
- /**
215
- * Returns true when `targetAbsolute` and `cwdAbsolute` resolve to different
216
- * filesystem roots. On POSIX this is always false (single root `/`); on
217
- * Windows it is true when the two paths sit on different drive letters or
218
- * different UNC roots — the symptom Codex flagged on PR #501, where
219
- * `path.relative('C:\\repo', 'D:\\secret.txt')` returns the absolute
220
- * `'D:\\secret.txt'` and slips past `startsWith('../')` containment.
221
- *
222
- * Exposed (and accepts an injectable `pathLib`) so the cross-drive guard
223
- * is falsifiable on Linux CI without depending on a Windows runner: tests
224
- * pass `path.win32` / `path.posix` directly.
225
- */
226
- export declare function isOnDifferentFilesystemRoot(targetAbsolute: string, cwdAbsolute: string, pathLib?: Pick<typeof path, 'parse'>): boolean;
227
- /**
228
- * Checks whether the given agent is authorised to write to the given file path.
229
- */
230
- export declare function checkFileAuthority(agentName: string, filePath: string, cwd: string, authorityConfig?: AuthorityConfig, options?: {
231
- declaredScope?: string[] | null;
232
- }): {
233
- allowed: true;
234
- } | {
235
- allowed: false;
236
- reason: string;
237
- zone?: FileZone;
238
- };
239
- export {};
12
+ export { type AgentRule, type AttestationRecord, buildEffectiveRules, checkFileAuthority, checkFileAuthorityWithRules, checkWriteTargetForSymlink, clearGuardrailsCaches, DEFAULT_AGENT_AUTHORITY_RULES, getGlobMatcher, hashArgs, isOnDifferentFilesystemRoot, normalizePathWithCache, recordAttestation, validateAndRecordAttestation, validateAttestation, } from './guardrails/file-authority';
13
+ export { _internals, createGuardrailsHooks, enforceSpecDriftGate, redactShellCommand, SPEC_DRIFT_BLOCKED_TOOLS, } from './guardrails/index';
14
+ export { deleteStoredInputArgs, getStoredInputArgs, setStoredInputArgs, } from './guardrails/stored-input-args';