@decionis/mcp 0.1.3 → 0.2.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,17 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": ".*",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/AgentHookCli.js\" claude --allow-ungoverned",
10
+ "timeout": 15,
11
+ "statusMessage": "Checking Decionis policy"
12
+ }
13
+ ]
14
+ }
15
+ ]
16
+ }
17
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@decionis/mcp",
3
- "version": "0.1.3",
4
- "description": "Local MCP policy checks and native Codex, Copilot, and Claude execution hooks.",
3
+ "version": "0.2.0",
4
+ "description": "Local MCP policy checks with Decionis policy packs and Presence human verification, plus native Codex, Copilot, and Claude execution hooks.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "mcpName": "com.decionis/mcp",
@@ -17,7 +17,10 @@
17
17
  "hooks",
18
18
  "claude-code",
19
19
  "codex",
20
- "copilot"
20
+ "copilot",
21
+ "presence",
22
+ "human-in-the-loop",
23
+ "policy-packs"
21
24
  ],
22
25
  "homepage": "https://decionis.com/docs/protocol-mcp",
23
26
  "repository": {
@@ -40,6 +43,9 @@
40
43
  "files": [
41
44
  "dist",
42
45
  "templates",
46
+ "hooks",
47
+ "commands",
48
+ ".claude-plugin",
43
49
  "README.md"
44
50
  ],
45
51
  "engines": {
@@ -63,9 +69,9 @@
63
69
  "typescript": "^5.6.3",
64
70
  "vitest": "^2.1.8",
65
71
  "@decionis/protocol": "0.0.0",
66
- "@decionis/sdk": "0.1.0",
72
+ "@decionis/sdk": "0.2.0",
67
73
  "@decionis/shared": "0.0.0",
68
- "@decionis/verify": "0.1.0"
74
+ "@decionis/verify": "0.3.0"
69
75
  },
70
76
  "scripts": {
71
77
  "dev": "tsx src/index.ts",
@@ -2,7 +2,7 @@
2
2
  "hooks": {
3
3
  "PreToolUse": [
4
4
  {
5
- "matcher": "*",
5
+ "matcher": ".*",
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
@@ -0,0 +1,108 @@
1
+ # Decionis execution policy
2
+
3
+ This file is the authority for what an AI agent may do in this repository.
4
+
5
+ Every tool call your agent makes is evaluated against the rules below **before**
6
+ it runs, by a `PreToolUse` hook. The model does not get a vote: a `block` here
7
+ means the tool call does not happen, whatever the model decides it wants.
8
+
9
+ Evaluation is local — the policy is read from this file, compiled, and run
10
+ through the real Decionis protocol evaluator in-process. No network, no
11
+ credentials, nothing recorded.
12
+
13
+ ## How to change it
14
+
15
+ Rules live in the fenced ` ```decionis ` block below. Highest `priority` wins.
16
+
17
+ - `action` is one of `allow`, `block`, `escalate`, `restrain`.
18
+ - Each rule has exactly one of `all` (every predicate must match) or `any`.
19
+ - Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `not_in`, `exists`,
20
+ `contains`, `matches` (case-insensitive regex).
21
+ - Keep `"domain": "*"` so a rule applies to every tool call.
22
+
23
+ **The two mistakes that cost people the most time:**
24
+
25
+ 1. **Field paths are nested.** The agent's own arguments arrive under
26
+ `context.tool_input`, so a Bash command is `context.tool_input.command` —
27
+ not `context.command`. The tool's name is `context.tool_name`.
28
+ 2. **The last rule has to allow.** Anything that is not explicitly allowed is
29
+ held, and the hook treats every non-allow verdict as a refusal. Delete the
30
+ catch-all at the bottom and your agent can do nothing at all.
31
+
32
+ Try it: ask your agent to run `rm -rf /var/lib/postgresql`. It comes back
33
+ refused, by rule name, and it cannot argue with the answer.
34
+
35
+ ```decionis
36
+ {
37
+ "version": 1,
38
+ "rules": [
39
+ {
40
+ "name": "Never recursively delete a system or data path",
41
+ "priority": 300,
42
+ "domain": "*",
43
+ "all": [
44
+ { "field": "context.tool_name", "op": "eq", "value": "Bash" },
45
+ {
46
+ "field": "context.tool_input.command",
47
+ "op": "matches",
48
+ "value": "rm\\s+(-[a-z]*r[a-z]*f|-[a-z]*f[a-z]*r)\\s+(/|~|\\$HOME|/etc|/var|/usr)"
49
+ }
50
+ ],
51
+ "action": "block",
52
+ "rationale": "A recursive force-delete of a system or data path is not recoverable from a chat session."
53
+ },
54
+ {
55
+ "name": "Never read a credential file",
56
+ "priority": 280,
57
+ "domain": "*",
58
+ "all": [
59
+ {
60
+ "field": "context.tool_input.file_path",
61
+ "op": "matches",
62
+ "value": "(^|/)\\.env($|\\.)|\\.pem$|\\.key$|id_rsa|credentials\\.json|\\.p12$"
63
+ }
64
+ ],
65
+ "action": "block",
66
+ "rationale": "Secrets should reach the agent through your secret manager, not by reading the file into the transcript."
67
+ },
68
+ {
69
+ "name": "Never pipe a downloaded script straight into a shell",
70
+ "priority": 260,
71
+ "domain": "*",
72
+ "all": [
73
+ { "field": "context.tool_name", "op": "eq", "value": "Bash" },
74
+ {
75
+ "field": "context.tool_input.command",
76
+ "op": "matches",
77
+ "value": "(curl|wget)[^|]*\\|\\s*(sudo\\s+)?(ba|z|k)?sh"
78
+ }
79
+ ],
80
+ "action": "block",
81
+ "rationale": "Executing an unreviewed remote script is the classic supply-chain foothold."
82
+ },
83
+ {
84
+ "name": "A human approves a force-push to a protected branch",
85
+ "priority": 240,
86
+ "domain": "*",
87
+ "all": [
88
+ { "field": "context.tool_name", "op": "eq", "value": "Bash" },
89
+ {
90
+ "field": "context.tool_input.command",
91
+ "op": "matches",
92
+ "value": "git\\s+push[^\\n]*(--force|-f)\\b[^\\n]*\\b(main|master|prod|production|release)\\b"
93
+ }
94
+ ],
95
+ "action": "escalate",
96
+ "rationale": "Rewriting shared history is recoverable only if someone still has the old commits."
97
+ },
98
+ {
99
+ "name": "Allow everything else",
100
+ "priority": 1,
101
+ "domain": "*",
102
+ "all": [{ "field": "context.tool_name", "op": "exists" }],
103
+ "action": "allow",
104
+ "rationale": "Anything the rules above did not stop is ordinary work. Remove this line and the agent can do nothing."
105
+ }
106
+ ]
107
+ }
108
+ ```
@@ -3,7 +3,7 @@
3
3
  "hooks": {
4
4
  "PreToolUse": [
5
5
  {
6
- "matcher": "*",
6
+ "matcher": ".*",
7
7
  "hooks": [
8
8
  {
9
9
  "type": "command",
@@ -3,7 +3,7 @@
3
3
  "hooks": {
4
4
  "PreToolUse": [
5
5
  {
6
- "matcher": "*",
6
+ "matcher": ".*",
7
7
  "hooks": [
8
8
  {
9
9
  "type": "command",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/agent/AgentContracts.ts","../src/agent/AgentHookValues.ts","../src/agent/AgentDecisionMapper.ts","../src/agent/AgentPolicyPayload.ts","../src/agent/LocalAgentGate.ts","../src/agent/RemoteAgentGate.ts","../src/agent/AgentGateFactory.ts","../src/agent/AgentHookRunner.ts","../src/agent/providers/SnakeCaseHookAdapter.ts","../src/agent/providers/ClaudeHookAdapter.ts","../src/agent/providers/CodexHookAdapter.ts","../src/agent/providers/CopilotHookAdapter.ts","../src/agent/AgentHostRegistry.ts","../src/agent/AgentHookCommand.ts"],"sourcesContent":["export type AgentHost = \"codex\" | \"copilot\" | \"claude\";\n\nexport type AgentGateVerdict = \"allow\" | \"block\" | \"review\" | \"escalate\" | \"error\";\n\nexport type AgentGateSource = \"local\" | \"remote\";\n\nexport interface AgentToolCall {\n host: AgentHost;\n sessionId: string;\n toolUseId: string | null;\n toolName: string;\n toolInput: Record<string, unknown>;\n cwd: string;\n model: string | null;\n permissionMode: string | null;\n}\n\nexport interface AgentGateDecision {\n verdict: AgentGateVerdict;\n reason: string;\n source: AgentGateSource;\n outcome: string | null;\n policyVersion: string | null;\n matchedRule: string | null;\n reasonCodes: string[];\n}\n\nexport interface AgentGateEvaluator {\n readonly source: AgentGateSource;\n evaluate(toolCall: AgentToolCall): Promise<AgentGateDecision>;\n close?(): Promise<void>;\n}\n\nexport interface AgentHostAdapter {\n readonly host: AgentHost;\n parse(input: unknown): AgentToolCall;\n format(decision: AgentGateDecision, input?: unknown): Record<string, unknown>;\n}\n\nexport class AgentHookInputError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentHookInputError\";\n }\n}\n\nexport class AgentGateConfigurationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentGateConfigurationError\";\n }\n}\n","import { AgentHookInputError } from \"./AgentContracts.js\";\n\nexport class AgentHookValues {\n static asRecord(value: unknown): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return {};\n return value as Record<string, unknown>;\n }\n\n static requireRecord(value: unknown): Record<string, unknown> {\n const record = AgentHookValues.asRecord(value);\n if (Object.keys(record).length === 0) {\n throw new AgentHookInputError(\"The hook input must be a non-empty JSON object.\");\n }\n return record;\n }\n\n static optionalString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n }\n\n static requireString(value: unknown, field: string): string {\n const parsed = AgentHookValues.optionalString(value);\n if (!parsed) throw new AgentHookInputError(`The hook input is missing \\`${field}\\`.`);\n return parsed;\n }\n\n static parseToolInput(value: unknown): Record<string, unknown> {\n if (typeof value !== \"string\") return AgentHookValues.asRecord(value);\n try {\n return AgentHookValues.asRecord(JSON.parse(value));\n } catch {\n throw new AgentHookInputError(\"The hook input contains invalid JSON tool arguments.\");\n }\n }\n}\n","import { normalizeVerdict } from \"../Gateway.js\";\nimport { AgentHookValues } from \"./AgentHookValues.js\";\nimport type { AgentGateDecision, AgentGateSource, AgentGateVerdict } from \"./AgentContracts.js\";\n\nexport class AgentDecisionMapper {\n static fromProtocol(\n body: Record<string, unknown>,\n source: AgentGateSource,\n fallbackPolicyVersion: string | null = null,\n ): AgentGateDecision {\n const outcome = AgentHookValues.optionalString(body.outcome);\n const verdict = AgentDecisionMapper.toVerdict(outcome);\n const policyEvaluation = AgentHookValues.asRecord(body.policy_evaluation);\n const selectedRule = AgentHookValues.optionalString(policyEvaluation.selected_rule_name);\n const rationale = AgentHookValues.optionalString(policyEvaluation.selected_rule_rationale);\n const resolution = AgentHookValues.optionalString(policyEvaluation.resolution);\n const policyVersion =\n AgentHookValues.optionalString(body.policy_version) ??\n AgentHookValues.optionalString(policyEvaluation.bundle_version) ??\n fallbackPolicyVersion;\n const reasonCodes = Array.isArray(body.reason_codes)\n ? body.reason_codes.filter((value): value is string => typeof value === \"string\")\n : [];\n\n return {\n verdict,\n reason: AgentDecisionMapper.reason(verdict, {\n selectedRule,\n rationale,\n resolution,\n reasonCodes,\n }),\n source,\n outcome,\n policyVersion,\n matchedRule: selectedRule,\n reasonCodes,\n };\n }\n\n static error(message: string, source: AgentGateSource): AgentGateDecision {\n return {\n verdict: \"error\",\n reason: message,\n source,\n outcome: null,\n policyVersion: null,\n matchedRule: null,\n reasonCodes: [\"AGENT_GATE_ERROR\"],\n };\n }\n\n private static toVerdict(outcome: string | null): AgentGateVerdict {\n const normalized = normalizeVerdict(outcome);\n if (\n normalized === \"allow\" ||\n normalized === \"block\" ||\n normalized === \"review\" ||\n normalized === \"escalate\"\n ) {\n return normalized;\n }\n return \"error\";\n }\n\n private static reason(\n verdict: AgentGateVerdict,\n context: {\n selectedRule: string | null;\n rationale: string | null;\n resolution: string | null;\n reasonCodes: string[];\n },\n ): string {\n if (context.rationale) return context.rationale;\n if (context.selectedRule) {\n return `Policy rule \"${context.selectedRule}\" returned ${verdict}.`;\n }\n if (context.reasonCodes.length > 0) {\n return `Policy returned ${verdict}: ${context.reasonCodes.join(\", \")}.`;\n }\n if (context.resolution) return `Policy returned ${verdict} (${context.resolution}).`;\n return `Policy returned ${verdict}.`;\n }\n}\n","import type { AgentToolCall } from \"./AgentContracts.js\";\n\nexport class AgentPolicyPayload {\n static build(toolCall: AgentToolCall): Record<string, unknown> {\n return {\n action: `agent_tool:${toolCall.toolName}`,\n agent_generated: true,\n agent_provider: toolCall.host,\n agent_session_id: toolCall.sessionId,\n tool_name: toolCall.toolName,\n tool_input: toolCall.toolInput,\n working_directory: toolCall.cwd,\n ...(toolCall.toolUseId ? { tool_use_id: toolCall.toolUseId } : {}),\n ...(toolCall.model ? { model: toolCall.model } : {}),\n ...(toolCall.permissionMode ? { permission_mode: toolCall.permissionMode } : {}),\n };\n }\n}\n","import { LocalDecionisGateway } from \"../Gateway.js\";\nimport type { AgentGateDecision, AgentGateEvaluator, AgentToolCall } from \"./AgentContracts.js\";\nimport { AgentDecisionMapper } from \"./AgentDecisionMapper.js\";\nimport { AgentPolicyPayload } from \"./AgentPolicyPayload.js\";\nimport { PolicyFileRepository } from \"./PolicyFileRepository.js\";\n\nexport interface LocalAgentGateOptions {\n gateway?: LocalDecionisGateway;\n policyFiles?: PolicyFileRepository;\n workflowKey?: string;\n}\n\nexport class LocalAgentGate implements AgentGateEvaluator {\n readonly source = \"local\" as const;\n private readonly gateway: LocalDecionisGateway;\n private readonly policyFiles: PolicyFileRepository;\n private readonly workflowKey: string;\n\n constructor(options: LocalAgentGateOptions = {}) {\n this.gateway = options.gateway ?? new LocalDecionisGateway();\n this.policyFiles = options.policyFiles ?? new PolicyFileRepository();\n this.workflowKey = options.workflowKey ?? \"agent_execution_gate\";\n }\n\n async evaluate(toolCall: AgentToolCall): Promise<AgentGateDecision> {\n const policyFile = await this.policyFiles.read(undefined, toolCall.cwd);\n if (!policyFile.ok) throw new Error(policyFile.message);\n\n const published = await this.gateway.publishPolicy(policyFile.content, {\n workflowKey: this.workflowKey,\n });\n if (!published.ok) {\n throw new Error(\n `The Decionis policy could not be enforced (${published.reason}): ${published.errors.join(\n \"; \",\n )}`,\n );\n }\n\n const evaluated = await this.gateway.evaluate({\n payload: AgentPolicyPayload.build(toolCall),\n workflowKey: this.workflowKey,\n mode: \"enforce\",\n });\n if (evaluated.status !== 200) {\n throw new Error(`The local Decionis evaluator returned HTTP ${evaluated.status}.`);\n }\n return AgentDecisionMapper.fromProtocol(evaluated.body, \"local\", published.version);\n }\n\n close(): Promise<void> {\n return this.gateway.close();\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport type { AgentGateDecision, AgentGateEvaluator, AgentToolCall } from \"./AgentContracts.js\";\nimport { AgentDecisionMapper } from \"./AgentDecisionMapper.js\";\nimport { AgentHookValues } from \"./AgentHookValues.js\";\nimport { AgentPolicyPayload } from \"./AgentPolicyPayload.js\";\n\ntype FetchLike = typeof fetch;\n\nexport interface RemoteAgentGateOptions {\n endpoint: string;\n apiKey: string;\n orgId: string;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n workflowKey?: string;\n}\n\nexport class RemoteAgentGate implements AgentGateEvaluator {\n readonly source = \"remote\" as const;\n private readonly endpoint: string;\n private readonly fetchImpl: FetchLike;\n private readonly timeoutMs: number;\n private readonly workflowKey: string;\n\n constructor(private readonly options: RemoteAgentGateOptions) {\n this.endpoint = options.endpoint.trim();\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.timeoutMs = options.timeoutMs ?? 4000;\n this.workflowKey = options.workflowKey ?? \"agent_execution_gate\";\n }\n\n async evaluate(toolCall: AgentToolCall): Promise<AgentGateDecision> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const idempotencyKey = this.idempotencyKey(toolCall);\n const response = await this.fetchImpl(this.endpoint, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${this.options.apiKey}`,\n \"content-type\": \"application/json\",\n \"idempotency-key\": idempotencyKey,\n },\n body: JSON.stringify({\n org_id: this.options.orgId,\n decision_type: `agent_tool:${toolCall.toolName}`.slice(0, 120),\n channel: toolCall.host,\n mode: \"ENFORCEMENT\",\n workflow_key: this.workflowKey,\n idempotency_key: idempotencyKey,\n context: AgentPolicyPayload.build(toolCall),\n }),\n signal: controller.signal,\n });\n const body = AgentHookValues.asRecord(await response.json().catch(() => null));\n if (!response.ok) {\n const message =\n AgentHookValues.optionalString(body.message) ??\n AgentHookValues.optionalString(body.error) ??\n \"unknown error\";\n throw new Error(\n `The remote Decionis evaluator returned HTTP ${response.status}: ${message}`,\n );\n }\n if (!AgentHookValues.optionalString(body.outcome)) {\n throw new Error(\"The remote Decionis evaluator returned no outcome.\");\n }\n return AgentDecisionMapper.fromProtocol(body, \"remote\");\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private idempotencyKey(toolCall: AgentToolCall): string {\n const source = JSON.stringify({\n host: toolCall.host,\n sessionId: toolCall.sessionId,\n toolUseId: toolCall.toolUseId,\n toolName: toolCall.toolName,\n toolInput: toolCall.toolInput,\n });\n return `agent-hook-${createHash(\"sha256\").update(source).digest(\"hex\")}`;\n }\n}\n","import { AgentGateConfigurationError, type AgentGateEvaluator } from \"./AgentContracts.js\";\nimport { AgentHookValues } from \"./AgentHookValues.js\";\nimport { LocalAgentGate } from \"./LocalAgentGate.js\";\nimport { RemoteAgentGate } from \"./RemoteAgentGate.js\";\n\nexport class AgentGateFactory {\n static create(env: NodeJS.ProcessEnv = process.env): AgentGateEvaluator {\n const mode = (\n AgentHookValues.optionalString(env.DECIONIS_AGENT_GATE_MODE) ?? \"auto\"\n ).toLowerCase();\n const endpoint = AgentHookValues.optionalString(env.DECIONIS_AGENT_GATE_URL);\n const apiKey = AgentHookValues.optionalString(env.DECIONIS_API_KEY);\n const orgId = AgentHookValues.optionalString(env.DECIONIS_ORG_ID);\n const hasRemoteConfiguration = Boolean(endpoint || apiKey || orgId);\n\n if (mode !== \"auto\" && mode !== \"local\" && mode !== \"remote\") {\n throw new AgentGateConfigurationError(\n \"DECIONIS_AGENT_GATE_MODE must be `auto`, `local`, or `remote`.\",\n );\n }\n if (mode === \"local\" || (mode === \"auto\" && !hasRemoteConfiguration)) {\n return new LocalAgentGate();\n }\n if (!endpoint || !apiKey || !orgId) {\n throw new AgentGateConfigurationError(\n \"Remote agent gating requires DECIONIS_AGENT_GATE_URL, DECIONIS_API_KEY, and DECIONIS_ORG_ID.\",\n );\n }\n\n const configuredTimeout = Number.parseInt(env.DECIONIS_AGENT_GATE_TIMEOUT_MS ?? \"\", 10);\n return new RemoteAgentGate({\n endpoint,\n apiKey,\n orgId,\n timeoutMs:\n Number.isFinite(configuredTimeout) && configuredTimeout > 0 ? configuredTimeout : 4000,\n });\n }\n}\n","import type { AgentGateDecision, AgentGateEvaluator, AgentHostAdapter } from \"./AgentContracts.js\";\nimport { AgentDecisionMapper } from \"./AgentDecisionMapper.js\";\n\nexport class AgentHookRunner {\n constructor(\n private readonly adapter: AgentHostAdapter,\n private readonly evaluator: AgentGateEvaluator,\n ) {}\n\n async run(input: unknown): Promise<Record<string, unknown>> {\n try {\n const toolCall = this.adapter.parse(input);\n const decision = await this.evaluator.evaluate(toolCall);\n return this.adapter.format(decision, input);\n } catch (error) {\n return this.adapter.format(\n AgentDecisionMapper.error(\n error instanceof Error ? error.message : String(error),\n this.evaluator.source,\n ),\n input,\n );\n }\n }\n\n close(): Promise<void> {\n return this.evaluator.close?.() ?? Promise.resolve();\n }\n\n static shouldBlock(decision: AgentGateDecision): boolean {\n return decision.verdict !== \"allow\";\n }\n}\n","import type {\n AgentGateDecision,\n AgentHost,\n AgentHostAdapter,\n AgentToolCall,\n} from \"../AgentContracts.js\";\nimport { AgentHookRunner } from \"../AgentHookRunner.js\";\nimport { AgentHookValues } from \"../AgentHookValues.js\";\n\nexport abstract class SnakeCaseHookAdapter implements AgentHostAdapter {\n abstract readonly host: AgentHost;\n\n parse(input: unknown): AgentToolCall {\n const event = AgentHookValues.requireRecord(input);\n return {\n host: this.host,\n sessionId: AgentHookValues.requireString(event.session_id, \"session_id\"),\n toolUseId: AgentHookValues.optionalString(event.tool_use_id),\n toolName: AgentHookValues.requireString(event.tool_name, \"tool_name\"),\n toolInput: AgentHookValues.parseToolInput(event.tool_input),\n cwd: AgentHookValues.requireString(event.cwd, \"cwd\"),\n model: AgentHookValues.optionalString(event.model),\n permissionMode: AgentHookValues.optionalString(event.permission_mode),\n };\n }\n\n format(decision: AgentGateDecision, _input?: unknown): Record<string, unknown> {\n if (!AgentHookRunner.shouldBlock(decision)) return {};\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: this.reason(decision),\n },\n };\n }\n\n protected reason(decision: AgentGateDecision): string {\n const label = decision.verdict === \"error\" ? \"gate error\" : decision.verdict;\n return `Decionis ${label}: ${decision.reason}`;\n }\n}\n","import { SnakeCaseHookAdapter } from \"./SnakeCaseHookAdapter.js\";\n\nexport class ClaudeHookAdapter extends SnakeCaseHookAdapter {\n readonly host = \"claude\" as const;\n}\n","import { SnakeCaseHookAdapter } from \"./SnakeCaseHookAdapter.js\";\n\nexport class CodexHookAdapter extends SnakeCaseHookAdapter {\n readonly host = \"codex\" as const;\n}\n","import type { AgentGateDecision, AgentHostAdapter, AgentToolCall } from \"../AgentContracts.js\";\nimport { AgentHookRunner } from \"../AgentHookRunner.js\";\nimport { AgentHookValues } from \"../AgentHookValues.js\";\n\nexport class CopilotHookAdapter implements AgentHostAdapter {\n readonly host = \"copilot\" as const;\n\n parse(input: unknown): AgentToolCall {\n const event = AgentHookValues.requireRecord(input);\n const usesCompatibleShape = AgentHookValues.optionalString(event.tool_name) !== null;\n const toolInput = usesCompatibleShape ? event.tool_input : event.toolArgs;\n return {\n host: this.host,\n sessionId:\n AgentHookValues.optionalString(usesCompatibleShape ? event.session_id : event.sessionId) ??\n \"unknown-session\",\n toolUseId: AgentHookValues.optionalString(\n usesCompatibleShape ? event.tool_use_id : event.toolUseId,\n ),\n toolName: AgentHookValues.requireString(\n usesCompatibleShape ? event.tool_name : event.toolName,\n usesCompatibleShape ? \"tool_name\" : \"toolName\",\n ),\n toolInput: AgentHookValues.parseToolInput(toolInput),\n cwd: AgentHookValues.optionalString(event.cwd) ?? process.cwd(),\n model: AgentHookValues.optionalString(event.model),\n permissionMode: AgentHookValues.optionalString(\n usesCompatibleShape ? event.permission_mode : event.permissionMode,\n ),\n };\n }\n\n format(decision: AgentGateDecision, input?: unknown): Record<string, unknown> {\n if (!AgentHookRunner.shouldBlock(decision)) return {};\n const label = decision.verdict === \"error\" ? \"gate error\" : decision.verdict;\n const reason = `Decionis ${label}: ${decision.reason}`;\n const event = AgentHookValues.asRecord(input);\n if (\n AgentHookValues.optionalString(event.tool_name) ||\n AgentHookValues.optionalString(event.hook_event_name) === \"PreToolUse\"\n ) {\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: reason,\n },\n };\n }\n return {\n permissionDecision: \"deny\",\n permissionDecisionReason: reason,\n };\n }\n}\n","import {\n AgentGateConfigurationError,\n type AgentHost,\n type AgentHostAdapter,\n} from \"./AgentContracts.js\";\nimport { ClaudeHookAdapter } from \"./providers/ClaudeHookAdapter.js\";\nimport { CodexHookAdapter } from \"./providers/CodexHookAdapter.js\";\nimport { CopilotHookAdapter } from \"./providers/CopilotHookAdapter.js\";\n\nexport class AgentHostRegistry {\n static resolve(host: string): AgentHostAdapter {\n const normalized = host.trim().toLowerCase() as AgentHost;\n switch (normalized) {\n case \"codex\":\n return new CodexHookAdapter();\n case \"copilot\":\n return new CopilotHookAdapter();\n case \"claude\":\n return new ClaudeHookAdapter();\n default:\n throw new AgentGateConfigurationError(\n \"Choose an agent host with `decionis-agent-hook codex|copilot|claude`.\",\n );\n }\n }\n}\n","import type { Readable, Writable } from \"node:stream\";\n\nimport type { AgentGateEvaluator, AgentHostAdapter } from \"./AgentContracts.js\";\nimport { AgentGateFactory } from \"./AgentGateFactory.js\";\nimport { AgentHookRunner } from \"./AgentHookRunner.js\";\nimport { AgentHostRegistry } from \"./AgentHostRegistry.js\";\n\nexport interface AgentHookCommandOptions {\n input?: Readable;\n output?: Writable;\n errorOutput?: Writable;\n env?: NodeJS.ProcessEnv;\n}\n\nexport class AgentHookCommand {\n static async run(args: string[], options: AgentHookCommandOptions = {}): Promise<number> {\n const input = options.input ?? process.stdin;\n const output = options.output ?? process.stdout;\n const errorOutput = options.errorOutput ?? process.stderr;\n const host = AgentHookCommand.hostArgument(args);\n\n let adapter: AgentHostAdapter;\n try {\n adapter = AgentHostRegistry.resolve(host);\n } catch (error) {\n errorOutput.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n return 2;\n }\n\n const raw = await AgentHookCommand.readInput(input);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n parsed = null;\n }\n\n let evaluator: AgentGateEvaluator;\n try {\n evaluator = AgentGateFactory.create(options.env);\n } catch (error) {\n const denial = adapter.format(\n {\n verdict: \"error\",\n reason: error instanceof Error ? error.message : String(error),\n source: \"local\",\n outcome: null,\n policyVersion: null,\n matchedRule: null,\n reasonCodes: [\"AGENT_GATE_CONFIGURATION_ERROR\"],\n },\n parsed,\n );\n output.write(`${JSON.stringify(denial)}\\n`);\n return 0;\n }\n\n const runner = new AgentHookRunner(adapter, evaluator);\n try {\n const result = await runner.run(parsed);\n output.write(`${JSON.stringify(result)}\\n`);\n return 0;\n } finally {\n await runner.close();\n }\n }\n\n private static hostArgument(args: string[]): string {\n const providerIndex = args.indexOf(\"--provider\");\n if (providerIndex >= 0) return args[providerIndex + 1] ?? \"\";\n return args.find((value) => !value.startsWith(\"-\")) ?? \"\";\n }\n\n private static async readInput(input: Readable): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of input) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n }\n return Buffer.concat(chunks).toString(\"utf8\").trim();\n }\n}\n"],"mappings":"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","names":[]}