opencode-swarm 7.71.0 → 7.71.2

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,48 @@
1
+ /**
2
+ * Worktree Isolation Subsystem
3
+ *
4
+ * Manages standard worktree-backed coder dispatches: provisioning worktrees,
5
+ * tracking dispatches, serializing when capacity is exceeded, and merging
6
+ * results back after coder completion.
7
+ *
8
+ * Extracted from delegation-gate.ts (FR-003) for modularity.
9
+ * The _internals seam allows test injection of worktree operations.
10
+ */
11
+ import type { PluginConfig } from '../../config';
12
+ import type { WorktreeHandle } from '../../worktree';
13
+ import { attemptMergeBackFromDirty, postMergeCleanup, provisionWorktree, removeWorktree } from '../../worktree';
14
+ export declare const MAX_TRACKED_STANDARD_WORKTREE_CALLS = 256;
15
+ export interface StandardWorktreeDispatch {
16
+ callID: string;
17
+ parentSessionID: string;
18
+ taskId: string;
19
+ planTaskId?: string;
20
+ handle: WorktreeHandle;
21
+ mergeStrategy: 'merge' | 'rebase' | 'cherry-pick';
22
+ }
23
+ export declare const standardWorktreeByCallID: Map<string, StandardWorktreeDispatch>;
24
+ export declare const standardWorktreeSerializationSessions: Set<string>;
25
+ export declare function resetStandardWorktreeIsolationState(): void;
26
+ export declare function sanitizeWorktreeTaskId(raw: string): string;
27
+ export declare function precreateStandardWorktreeSession(args: {
28
+ config: PluginConfig;
29
+ directory: string;
30
+ parentSessionID: string;
31
+ callID: string;
32
+ taskId: string;
33
+ planTaskId?: string;
34
+ description?: string;
35
+ outputArgs: Record<string, unknown>;
36
+ }): Promise<void>;
37
+ export declare function finishStandardWorktreeDispatch(directory: string, dispatch: StandardWorktreeDispatch): Promise<void>;
38
+ /**
39
+ * _internals seam for test injection of worktree operations.
40
+ * Tests set these entries on delegation-gate's _internals (which proxies
41
+ * here via getters/setters) to mock worktree provisioning, merge-back, etc.
42
+ */
43
+ export declare const _internals: {
44
+ provisionWorktree: typeof provisionWorktree;
45
+ removeWorktree: typeof removeWorktree;
46
+ attemptMergeBackFromDirty: typeof attemptMergeBackFromDirty;
47
+ postMergeCleanup: typeof postMergeCleanup;
48
+ };
@@ -8,7 +8,9 @@ import type { PluginConfig } from '../config';
8
8
  import { loadPlanJsonOnly } from '../plan/manager';
9
9
  import type { AgentSessionState } from '../state';
10
10
  import type { DelegationEnvelope, EnvelopeValidationResult } from '../types/delegation.js';
11
- import { attemptMergeBackFromDirty, postMergeCleanup, provisionWorktree, removeWorktree } from '../worktree';
11
+ import { resetStandardWorktreeIsolationState } from './delegation-gate/worktree-isolation';
12
+ export { resetStandardWorktreeIsolationState };
13
+ import { _internals as _wtiInternals } from './delegation-gate/worktree-isolation';
12
14
  /**
13
15
  * v6.33.1 CRIT-1: Fallback map for declared coder scope by taskId.
14
16
  * When messagesTransform sets declaredCoderScope on the architect session,
@@ -80,7 +82,6 @@ interface MessageWithParts {
80
82
  info: MessageInfo;
81
83
  parts: MessagePart[];
82
84
  }
83
- export declare function resetStandardWorktreeIsolationState(): void;
84
85
  declare function resolveDelegatedPlanTaskId(args: Record<string, unknown>, knownPlanTaskIds?: ReadonlySet<string>): string | null;
85
86
  declare function buildParallelExecutionGuidance(directory: string | undefined, sessionID: string, session: AgentSessionState): Promise<string | null>;
86
87
  /**
@@ -98,17 +99,21 @@ declare function resolveEvidenceTaskId(args: Record<string, unknown> | undefined
98
99
  * _internals export for testing — do not use in production code.
99
100
  * Exposes resolveEvidenceTaskId, resolveDelegatedPlanTaskId, and
100
101
  * buildParallelExecutionGuidance for unit testing.
102
+ *
103
+ * Worktree operation entries (provisionWorktree, removeWorktree, etc.) proxy
104
+ * to delegation-gate/worktree-isolation._internals via getters/setters so
105
+ * that test mutations on this object propagate to the extracted module.
101
106
  */
102
107
  export declare const _internals: {
103
108
  resolveEvidenceTaskId: typeof resolveEvidenceTaskId;
104
109
  resolveDelegatedPlanTaskId: typeof resolveDelegatedPlanTaskId;
105
110
  buildParallelExecutionGuidance: typeof buildParallelExecutionGuidance;
106
111
  loadPlanJsonOnly: typeof loadPlanJsonOnly;
107
- provisionWorktree: typeof provisionWorktree;
108
- removeWorktree: typeof removeWorktree;
109
- attemptMergeBackFromDirty: typeof attemptMergeBackFromDirty;
110
- postMergeCleanup: typeof postMergeCleanup;
111
112
  resetStandardWorktreeIsolationState: typeof resetStandardWorktreeIsolationState;
113
+ provisionWorktree: typeof _wtiInternals.provisionWorktree;
114
+ removeWorktree: typeof _wtiInternals.removeWorktree;
115
+ attemptMergeBackFromDirty: typeof _wtiInternals.attemptMergeBackFromDirty;
116
+ postMergeCleanup: typeof _wtiInternals.postMergeCleanup;
112
117
  };
113
118
  /**
114
119
  * Creates the experimental.chat.messages.transform hook for delegation gating.
@@ -132,4 +137,3 @@ export declare function createDelegationGateHook(config: PluginConfig, directory
132
137
  args?: Record<string, unknown>;
133
138
  }, output: unknown) => Promise<void>;
134
139
  };
135
- export {};
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Destructive Command Protection Subsystem
3
+ *
4
+ * Cross-platform helpers for detecting and blocking destructive shell commands.
5
+ * Extracted from guardrails.ts (FR-002) — pure mechanical extraction, zero
6
+ * behavior change.
7
+ *
8
+ * Provides:
9
+ * - Command normalization (homoglyph collapsing, escape decoding)
10
+ * - Shell wrapper unwrapping (cmd /c, powershell -Command, bash -c, sudo, etc.)
11
+ * - Compound command segmentation (splitting on ;, &&, ||, |)
12
+ * - Target validation (vars, remote paths, filesystem roots, lstat ancestor walk)
13
+ * - Junction/symlink creation detection
14
+ * - Target extraction for Windows cmd.exe and PowerShell destructive commands
15
+ */
16
+ /**
17
+ * Expanded safe-target allowlist for recursive delete operations.
18
+ * These directory names are safe to delete recursively by name alone.
19
+ * NOTE: Subdirectory paths like node_modules/.cache are NOT safe — the
20
+ * check requires the target be exactly one of these bare names.
21
+ */
22
+ export declare const DC_SAFE_TARGETS: Set<string>;
23
+ /**
24
+ * Normalize a command string for pattern matching:
25
+ * 1. Unicode NFKC normalize (collapses homoglyphs)
26
+ * 2. Detect evasion techniques that exist only to defeat scanners
27
+ *
28
+ * When an evasion technique is detected, the decoded form is returned so
29
+ * that pattern matching can still fire on it. Only fails-closed when the
30
+ * evasion wraps a form we cannot safely decode.
31
+ */
32
+ export declare function dcNormalizeCommand(cmd: string): string;
33
+ /**
34
+ * Strip one layer of a shell wrapper from a command string.
35
+ * Returns the inner command if a wrapper was found, null otherwise.
36
+ *
37
+ * Handles:
38
+ * - cmd /c "..." cmd /k "..."
39
+ * - powershell -Command "..." / -c "..." / -EncodedCommand <b64> / -enc <b64>
40
+ * - pwsh -Command / -c / -EncodedCommand / -enc
41
+ * - bash -c "..." / sh -c / zsh -c
42
+ * - sudo <...> / env VAR=val <...> / time <...> / nohup <...>
43
+ * - wsl -e ... / wsl -- ... / wsl.exe -e ...
44
+ * - PowerShell & { ... } script blocks
45
+ * - PowerShell iex / Invoke-Expression <...>
46
+ * - call <...> (batch)
47
+ */
48
+ export declare function dcStripOneWrapper(cmd: string): string | null;
49
+ /**
50
+ * Recursively unwrap all shell wrappers up to DC_MAX_UNWRAP_DEPTH.
51
+ * Returns the innermost unwrapped command.
52
+ */
53
+ export declare function dcUnwrapWrappers(cmd: string): string;
54
+ /**
55
+ * Split a compound command into individual segments, splitting on:
56
+ * ; && || | newlines
57
+ * Respects double-quoted strings (does not split inside quotes).
58
+ * Returns array of trimmed non-empty segments.
59
+ */
60
+ export declare function dcSplitSegments(cmd: string): string[];
61
+ /**
62
+ * Returns true if a path string contains unexpanded environment variable
63
+ * references that we cannot resolve at check time.
64
+ */
65
+ export declare function dcHasUnresolvableVars(p: string): boolean;
66
+ /**
67
+ * Returns true if the path looks like a remote/network filesystem path.
68
+ */
69
+ export declare function dcIsRemotePath(p: string): boolean;
70
+ /**
71
+ * Walk from target path up to (but not beyond) cwd using synchronous lstat,
72
+ * checking each ancestor for symlinks, junctions, or reparse points.
73
+ *
74
+ * Returns a block reason string if a suspicious ancestor is found, null otherwise.
75
+ * Skips silently on ENOENT (target does not exist — nothing to delete).
76
+ * Fails closed on unexpected lstat errors.
77
+ */
78
+ export declare function dcLstatAncestorWalk(targetPath: string, cwd: string): string | null;
79
+ /**
80
+ * Given a set of raw target strings from a destructive command, apply:
81
+ * 1. Unresolvable-var check (fail closed)
82
+ * 2. Safe-target allowlist check (allow through)
83
+ * 3. Remote filesystem check (block)
84
+ * 4. Unconditional system-path block
85
+ * 5. lstat ancestor walk (block on symlink/junction in chain)
86
+ *
87
+ * Returns a block reason string or null if targets are acceptable.
88
+ */
89
+ export declare function dcValidateTargets(targets: string[], cwd: string): string | null;
90
+ /**
91
+ * Detect Windows junction or symlink CREATION commands.
92
+ * Junction creation followed by recursive deletion of the junction is the
93
+ * exact mechanism of the K2.6 data-loss incident.
94
+ * Block junction/symlink creation where the target resolves outside cwd.
95
+ *
96
+ * Patterns covered:
97
+ * mklink /J <link> <target>
98
+ * mklink /D <link> <target>
99
+ * New-Item -ItemType Junction -Path <link> -Target <target>
100
+ * New-Item -ItemType SymbolicLink -Path <link> -Target <target>
101
+ * ln -s <target> <link> (when target is outside cwd)
102
+ */
103
+ export declare function dcCheckJunctionCreation(segment: string, cwd: string): string | null;
104
+ /**
105
+ * Extract candidate target paths from a destructive Windows cmd.exe command.
106
+ * Returns array of path-like arguments.
107
+ */
108
+ export declare function dcExtractWindowsCmdTargets(segment: string): string[];
109
+ /**
110
+ * Extract candidate target paths from a destructive PowerShell command.
111
+ * Handles both `Remove-Item <path> -Recurse` and `Remove-Item -Recurse <path>` orderings.
112
+ */
113
+ export declare function dcExtractPowerShellTargets(segment: string): string[];
@@ -0,0 +1,152 @@
1
+ /**
2
+ * File Authority Subsystem
3
+ *
4
+ * Extracted from guardrails.ts. Provides file-write authority checking,
5
+ * attestation API, path normalization caching, and glob matching for
6
+ * agent file permissions.
7
+ *
8
+ * All exports are re-exported by the barrel guardrails.ts for backward
9
+ * compatibility.
10
+ */
11
+ import * as path from 'node:path';
12
+ import { type AuthorityConfig } from '../../config/schema';
13
+ import { type FileZone } from '../../context/zone-classifier';
14
+ /**
15
+ * Hashes tool arguments for repetition detection
16
+ * @param args Tool arguments to hash
17
+ * @returns Numeric hash (0 if hashing fails)
18
+ */
19
+ export declare function hashArgs(args: unknown): number;
20
+ /** A record of an agent attesting to (resolving/suppressing/deferring) a finding. */
21
+ export interface AttestationRecord {
22
+ findingId: string;
23
+ agent: string;
24
+ attestation: string;
25
+ action: 'resolve' | 'suppress' | 'defer';
26
+ timestamp: string;
27
+ }
28
+ /**
29
+ * Validates that an attestation string meets the minimum length requirement.
30
+ */
31
+ export declare function validateAttestation(attestation: string, _findingId: string, _agent: string, _action: 'resolve' | 'suppress' | 'defer'): {
32
+ valid: true;
33
+ } | {
34
+ valid: false;
35
+ reason: string;
36
+ };
37
+ /**
38
+ * Appends an attestation record to `.swarm/evidence/attestations.jsonl`.
39
+ */
40
+ export declare function recordAttestation(dir: string, record: AttestationRecord): Promise<void>;
41
+ /**
42
+ * Validates an attestation and, on success, records it; on failure, logs a rejection event.
43
+ */
44
+ export declare function validateAndRecordAttestation(dir: string, findingId: string, agent: string, attestation: string, action: 'resolve' | 'suppress' | 'defer'): Promise<{
45
+ valid: true;
46
+ } | {
47
+ valid: false;
48
+ reason: string;
49
+ }>;
50
+ /**
51
+ * Clears all guardrails caches.
52
+ * Use this for test isolation or when guardrails config reloads at runtime.
53
+ */
54
+ export declare function clearGuardrailsCaches(): void;
55
+ /**
56
+ * Normalizes a file path using fs.realpathSync with caching.
57
+ * This resolves symlinks and normalizes the path for cross-platform consistency.
58
+ * @param filePath The file path to normalize (absolute or relative)
59
+ * @param cwd Working directory for relative paths
60
+ * @returns Normalized absolute path or original on error
61
+ */
62
+ export declare function normalizePathWithCache(filePath: string, cwd: string): string;
63
+ /**
64
+ * Gets or creates a cached picomatch matcher for a glob pattern.
65
+ * @param pattern Glob pattern to compile
66
+ * @param caseInsensitive Whether to use case-insensitive matching (default: true on Windows/macOS)
67
+ * @returns Matcher function that returns true if path matches the pattern
68
+ */
69
+ export declare function getGlobMatcher(pattern: string, caseInsensitive?: boolean): (path: string) => boolean;
70
+ export type AgentRule = {
71
+ readOnly?: boolean;
72
+ blockedExact?: string[];
73
+ allowedExact?: string[];
74
+ blockedPrefix?: string[];
75
+ allowedPrefix?: string[];
76
+ blockedZones?: FileZone[];
77
+ blockedGlobs?: string[];
78
+ allowedGlobs?: string[];
79
+ };
80
+ export declare const DEFAULT_AGENT_AUTHORITY_RULES: Record<string, AgentRule>;
81
+ /**
82
+ * Checks whether a write target path (or any ancestor strictly inside cwd)
83
+ * is a symlink. Writing through a symlink can redirect the write to a
84
+ * location outside the working directory, bypassing scope containment.
85
+ *
86
+ * The walk stops at cwd — cwd itself is NOT lstat'd. A user's chosen
87
+ * working directory may legitimately be reached via a symlink (e.g.,
88
+ * macOS's /tmp → /private/tmp), and that symlink does not constitute a
89
+ * redirect *within* the workspace. Only attacker-plantable symlinks
90
+ * BELOW cwd are relevant to this guard.
91
+ *
92
+ * ENOENT on any node in the chain is allowed — the file/dir doesn't exist yet.
93
+ * Any other lstat error (EPERM, EACCES, ENAMETOOLONG, …) fails closed:
94
+ * an unverifiable ancestor must not be written through, even if the OS
95
+ * would eventually reject the write. Defense-in-depth over optimism.
96
+ *
97
+ * @returns A block reason string if a symlink is detected, null if all clear.
98
+ */
99
+ export declare function checkWriteTargetForSymlink(targetPath: string, cwd: string): string | null;
100
+ /**
101
+ * Builds the effective rules map by merging user-configured rules with defaults.
102
+ * User overrides take precedence for each field.
103
+ */
104
+ export declare function buildEffectiveRules(authorityConfig?: AuthorityConfig): Record<string, AgentRule>;
105
+ /**
106
+ * Returns true when `targetAbsolute` and `cwdAbsolute` resolve to different
107
+ * filesystem roots. On POSIX this is always false (single root `/`); on
108
+ * Windows it is true when the two paths sit on different drive letters or
109
+ * different UNC roots — the symptom Codex flagged on PR #501, where
110
+ * `path.relative('C:\\repo', 'D:\\secret.txt')` returns the absolute
111
+ * `'D:\\secret.txt'` and slips past `startsWith('../')` containment.
112
+ *
113
+ * Exposed (and accepts an injectable `pathLib`) so the cross-drive guard
114
+ * is falsifiable on Linux CI without depending on a Windows runner: tests
115
+ * pass `path.win32` / `path.posix` directly.
116
+ */
117
+ export declare function isOnDifferentFilesystemRoot(targetAbsolute: string, cwdAbsolute: string, pathLib?: Pick<typeof path, 'parse'>): boolean;
118
+ /**
119
+ * Checks file path authority against a pre-computed rules map.
120
+ * Implements DENY-first evaluation order:
121
+ * 1. readOnly - blocks all writes
122
+ * 2. blockedExact - exact path matches (fast path)
123
+ * 3. blockedGlobs - glob pattern matches
124
+ * 4. allowedExact - explicit allow for exact paths
125
+ * 5. blockedZones - zone-based blocking (runs before allowedGlobs so that generated
126
+ * output dirs like dist/ and build/ cannot be bypassed by a glob pattern match)
127
+ * 6. allowedGlobs - explicit allow for glob patterns (overrides blockedPrefix/allowedPrefix
128
+ * but NOT blockedZones, which is already decided in Step 5)
129
+ * 7. blockedPrefix - prefix-based blocking (takes priority over allowedPrefix)
130
+ * 8. allowedPrefix - prefix-based allow (whitelist)
131
+ */
132
+ export declare function checkFileAuthorityWithRules(agentName: string, filePath: string, cwd: string, effectiveRules: Record<string, AgentRule>, options?: {
133
+ declaredScope?: string[] | null;
134
+ }): {
135
+ allowed: true;
136
+ } | {
137
+ allowed: false;
138
+ reason: string;
139
+ zone?: FileZone;
140
+ };
141
+ /**
142
+ * Checks whether the given agent is authorised to write to the given file path.
143
+ */
144
+ export declare function checkFileAuthority(agentName: string, filePath: string, cwd: string, authorityConfig?: AuthorityConfig, options?: {
145
+ declaredScope?: string[] | null;
146
+ }): {
147
+ allowed: true;
148
+ } | {
149
+ allowed: false;
150
+ reason: string;
151
+ zone?: FileZone;
152
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Shared Helper Functions — Guardrails
3
+ *
4
+ * Extracted from tool-before.ts (task 1.4 / FR-005).
5
+ * Contains pure utility functions used by the toolBefore handler
6
+ * and potentially other guardrails submodules.
7
+ */
8
+ /**
9
+ * Checks if a file path is a config file either via zone classification
10
+ * or by matching known verifier config glob patterns.
11
+ */
12
+ export declare function isConfigFilePath(filePath: string, cwd: string, extraGlobs?: readonly string[]): boolean;
13
+ /**
14
+ * Detects if a tool is a write-class tool that modifies file contents.
15
+ */
16
+ export declare function isWriteTool(toolName: string): boolean;
17
+ /**
18
+ * Detects if a file path is outside the .swarm/ directory.
19
+ */
20
+ export declare function isOutsideSwarmDir(filePath: string, directory: string): boolean;
21
+ /**
22
+ * Detects if a file path is source code (not docs, config, or metadata).
23
+ */
24
+ export declare function isSourceCodePath(filePath: string): boolean;
25
+ /**
26
+ * Detect obvious traversal segments regardless of destination file type.
27
+ */
28
+ export declare function hasTraversalSegments(filePath: string): boolean;
29
+ /**
30
+ * Check if a file path is within declared scope entries.
31
+ * Handles both exact matches and directory containment.
32
+ */
33
+ export declare function isInDeclaredScope(filePath: string, scopeEntries: string[], cwd?: string): boolean;
34
+ /**
35
+ * Redacts sensitive values from a shell command string before audit logging.
36
+ * Covers env-var assignments, CLI flags, Bearer/Basic auth, and -H header flags.
37
+ */
38
+ export declare function redactShellCommand(cmd: string): string;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Guardrails Hook Module
3
+ *
4
+ * Circuit breaker for runaway LLM agents. Monitors tool usage via OpenCode Plugin API hooks
5
+ * and implements two-layer protection:
6
+ * - Layer 1 (Soft Warning @ warning_threshold): Sets warning flag for messagesTransform to inject warning
7
+ * - Layer 2 (Hard Block @ 100%): Throws error in toolBefore to block further calls, injects STOP message
8
+ */
9
+ import { extractSwarmIdFromAgentName, getSwarmAgents, resolveFallbackModel } from '../../agents/index';
10
+ import { type AuthorityConfig, type GuardrailsConfig } from '../../config/schema';
11
+ import { dcCheckJunctionCreation } from './destructive-command';
12
+ import { getMostRecentAssistantText, getProviderFailureFingerprint, isTransientProviderFailureText } from './messages-transform';
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.
26
+ */
27
+ export declare const SPEC_DRIFT_BLOCKED_TOOLS: Set<string>;
28
+ /**
29
+ * Throw SPEC_DRIFT_BLOCK if the tool is on the block-list and the
30
+ * spec-staleness marker file exists.
31
+ */
32
+ export declare function enforceSpecDriftGate(directory: string | undefined, toolName: string): void;
33
+ /**
34
+ * Extracts bounded provider/error signal from unknown hook error payloads.
35
+ */
36
+ declare function extractErrorSignal(errorContent: unknown): string;
37
+ /**
38
+ * Redacts sensitive values from a shell command string before audit logging.
39
+ */
40
+ export declare function redactShellCommand(cmd: string): string;
41
+ /**
42
+ * Creates guardrails hooks for circuit breaker protection
43
+ * @param directory Working directory from plugin init context (required)
44
+ * @param directoryOrConfig Guardrails configuration object (when passed as second arg, replaces legacy config param)
45
+ * @param config Guardrails configuration (optional)
46
+ * @returns Tool before/after hooks and messages transform hook
47
+ */
48
+ export declare function createGuardrailsHooks(directory: string, directoryOrConfig?: string | GuardrailsConfig, config?: GuardrailsConfig, authorityConfig?: AuthorityConfig): {
49
+ toolBefore: (input: {
50
+ tool: string;
51
+ sessionID: string;
52
+ callID: string;
53
+ }, output: {
54
+ args: unknown;
55
+ }) => Promise<void>;
56
+ toolAfter: (input: {
57
+ tool: string;
58
+ sessionID: string;
59
+ callID: string;
60
+ args?: Record<string, unknown>;
61
+ }, output: {
62
+ title: string;
63
+ output: string;
64
+ metadata: unknown;
65
+ }) => Promise<void>;
66
+ messagesTransform: (input: Record<string, never>, output: {
67
+ messages?: Array<{
68
+ info: {
69
+ role: string;
70
+ agent?: string;
71
+ sessionID?: string;
72
+ };
73
+ parts: Array<{
74
+ type: string;
75
+ text?: string;
76
+ [key: string]: unknown;
77
+ }>;
78
+ }>;
79
+ }) => Promise<void>;
80
+ };
81
+ export {};
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Messages Transform Handler Factory
3
+ *
4
+ * Extracted from guardrails.ts. Creates the messagesTransform handler
5
+ * used by createGuardrailsHooks. The factory receives shared configuration
6
+ * and closures from the guardrails hooks factory, so the handler can
7
+ * inject warnings, detect loops, and enforce QA gate compliance.
8
+ */
9
+ import { type GuardrailsConfig } from '../../config/schema';
10
+ /**
11
+ * Shared context passed from createGuardrailsHooks to the messagesTransform factory.
12
+ */
13
+ export interface MessagesTransformContext {
14
+ /** Resolved working directory for the guardrails hooks */
15
+ effectiveDirectory: string;
16
+ /** Resolved guardrails configuration */
17
+ cfg: GuardrailsConfig;
18
+ /** Required QA gates tool names */
19
+ requiredQaGates: string[];
20
+ /** Whether reviewer/test_engineer delegation is required */
21
+ requireReviewerAndTestEngineer: boolean;
22
+ /** Shared consecutiveNoToolTurns Map (also used by toolBefore) */
23
+ consecutiveNoToolTurns: Map<string, number>;
24
+ }
25
+ type ChatMessageLike = {
26
+ info?: {
27
+ role?: string;
28
+ sessionID?: string;
29
+ };
30
+ parts?: Array<{
31
+ type?: string;
32
+ text?: unknown;
33
+ }>;
34
+ };
35
+ export declare function getMostRecentAssistantText(messages: ChatMessageLike[]): string;
36
+ export declare function isTransientProviderFailureText(text: string): boolean;
37
+ export declare function getProviderFailureFingerprint(text: string): string;
38
+ /**
39
+ * Creates a messagesTransform handler with the given shared context.
40
+ *
41
+ * @param ctx Shared configuration and closures from createGuardrailsHooks
42
+ * @returns The messagesTransform handler function
43
+ */
44
+ export declare function createMessagesTransformHandler(ctx: MessagesTransformContext): (_input: Record<string, never>, output: {
45
+ messages?: Array<{
46
+ info: {
47
+ role: string;
48
+ agent?: string;
49
+ sessionID?: string;
50
+ };
51
+ parts: Array<{
52
+ type: string;
53
+ text?: string;
54
+ [key: string]: unknown;
55
+ }>;
56
+ }>;
57
+ }) => Promise<void>;
58
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Stored Input Args Helpers
3
+ *
4
+ * Extracted from guardrails.ts. Provides module-level storage for tool
5
+ * input args by callID, used by guardrails for delegation detection
6
+ * and exposed via safe accessor helpers.
7
+ */
8
+ /**
9
+ * Retrieves stored input args for a given callID.
10
+ * Used by other hooks (e.g., delegation-gate) to access tool input args.
11
+ * @param callID The callID to look up
12
+ * @returns The stored args or undefined if not found
13
+ */
14
+ export declare function getStoredInputArgs(callID: string): unknown | undefined;
15
+ /**
16
+ * Stores input args for a given callID.
17
+ * Used by guardrails toolBefore hook; may be used by other hooks if needed.
18
+ * @param callID The callID to store args under
19
+ * @param args The tool input args to store
20
+ */
21
+ export declare function setStoredInputArgs(callID: string, args: unknown): void;
22
+ /**
23
+ * Deletes stored input args for a given callID (cleanup after retrieval).
24
+ * @param callID The callID to delete
25
+ */
26
+ export declare function deleteStoredInputArgs(callID: string): void;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Tool Before Handler Factory
3
+ *
4
+ * Extracted from guardrails/index.ts (task 1.4 / FR-005).
5
+ * Creates the toolBefore handler used by createGuardrailsHooks.
6
+ * The factory receives shared configuration and closures from the
7
+ * guardrails hooks factory, so the handler can enforce destructive
8
+ * command blocking, file authority, scope, self-coding gates, write
9
+ * target checks, and circuit breaker limits.
10
+ */
11
+ import { type AuthorityConfig, type GuardrailsConfig } from '../../config/schema';
12
+ import type { AgentRule } from './file-authority';
13
+ /**
14
+ * Shared context passed from createGuardrailsHooks to the toolBefore factory.
15
+ */
16
+ export interface ToolBeforeContext {
17
+ /** Resolved working directory for the guardrails hooks */
18
+ effectiveDirectory: string;
19
+ /** Resolved guardrails configuration */
20
+ cfg: GuardrailsConfig;
21
+ /** Pre-computed per-agent authority rules */
22
+ precomputedAuthorityRules: Record<string, AgentRule>;
23
+ /** Global deny prefixes — apply to all agents regardless of per-agent rules */
24
+ universalDenyPrefixes: string[];
25
+ /** Shell audit log path */
26
+ shellAuditPath: string;
27
+ /** Whether shell audit logging is enabled */
28
+ shellAuditEnabled: boolean;
29
+ /** Agents allowed to use bash/shell interpreter (undefined = all allowed) */
30
+ interpreterAllowedAgents: string[] | undefined;
31
+ /** Authority config (for verifier config paths) */
32
+ authorityConfig: AuthorityConfig | undefined;
33
+ /** Shared consecutiveNoToolTurns Map (also used by messagesTransform) */
34
+ consecutiveNoToolTurns: Map<string, number>;
35
+ }
36
+ /**
37
+ * Creates a toolBefore handler with the given shared context.
38
+ *
39
+ * @param ctx Shared configuration and closures from createGuardrailsHooks
40
+ * @returns The toolBefore handler function
41
+ */
42
+ export declare function createToolBeforeHandler(ctx: ToolBeforeContext): (input: {
43
+ tool: string;
44
+ sessionID: string;
45
+ callID: string;
46
+ }, output: {
47
+ args: unknown;
48
+ }) => Promise<void>;