@intutic/gate 1.10.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.
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/actions.d.ts +86 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +239 -0
- package/dist/actions.js.map +1 -0
- package/dist/client.d.ts +94 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +207 -0
- package/dist/client.js.map +1 -0
- package/dist/dsh.d.ts +162 -0
- package/dist/dsh.d.ts.map +1 -0
- package/dist/dsh.js +189 -0
- package/dist/dsh.js.map +1 -0
- package/dist/errors.d.ts +41 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/eve.d.ts +425 -0
- package/dist/eve.d.ts.map +1 -0
- package/dist/eve.js +378 -0
- package/dist/eve.js.map +1 -0
- package/dist/gate.d.ts +113 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +274 -0
- package/dist/gate.js.map +1 -0
- package/dist/harness.d.ts +482 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +504 -0
- package/dist/harness.js.map +1 -0
- package/dist/headers.d.ts +26 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +30 -0
- package/dist/headers.js.map +1 -0
- package/dist/imagecheck.d.ts +93 -0
- package/dist/imagecheck.d.ts.map +1 -0
- package/dist/imagecheck.js +286 -0
- package/dist/imagecheck.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/managedAgents.d.ts +375 -0
- package/dist/managedAgents.d.ts.map +1 -0
- package/dist/managedAgents.js +446 -0
- package/dist/managedAgents.js.map +1 -0
- package/dist/mastra.d.ts +175 -0
- package/dist/mastra.d.ts.map +1 -0
- package/dist/mastra.js +161 -0
- package/dist/mastra.js.map +1 -0
- package/dist/openai.d.ts +392 -0
- package/dist/openai.d.ts.map +1 -0
- package/dist/openai.js +658 -0
- package/dist/openai.js.map +1 -0
- package/dist/shlex.d.ts +16 -0
- package/dist/shlex.d.ts.map +1 -0
- package/dist/shlex.js +78 -0
- package/dist/shlex.js.map +1 -0
- package/dist/snapshot.d.ts +111 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +243 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/soprules.d.ts +88 -0
- package/dist/soprules.d.ts.map +1 -0
- package/dist/soprules.js +176 -0
- package/dist/soprules.js.map +1 -0
- package/dist/trueforge.d.ts +191 -0
- package/dist/trueforge.d.ts.map +1 -0
- package/dist/trueforge.js +184 -0
- package/dist/trueforge.js.map +1 -0
- package/dist/vercel.d.ts +174 -0
- package/dist/vercel.d.ts.map +1 -0
- package/dist/vercel.js +157 -0
- package/dist/vercel.js.map +1 -0
- package/dist/workflow.d.ts +209 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +254 -0
- package/dist/workflow.js.map +1 -0
- package/dist/wrapTools.d.ts +68 -0
- package/dist/wrapTools.d.ts.map +1 -0
- package/dist/wrapTools.js +95 -0
- package/dist/wrapTools.js.map +1 -0
- package/package.json +123 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Intutic Community
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# @intutic/gate
|
|
2
|
+
|
|
3
|
+
Pre-execution tool gate for JS/TS agent frameworks without a shipped Intutic
|
|
4
|
+
harness. Port of the Python SDK's gate subpackage
|
|
5
|
+
(`packages/intutic-clawde/intutic_clawde/gate/`) — see that package for the
|
|
6
|
+
canonical description of the enforcement contract this one mirrors.
|
|
7
|
+
|
|
8
|
+
This package is the **core** library plus framework-specific adapters built
|
|
9
|
+
on top of it: `@intutic/gate/dsh` (a Cordis plugin for DeepSeek's "dsh"
|
|
10
|
+
harness), `@intutic/gate/mastra` (`intuticHooks()` on Mastra's
|
|
11
|
+
`beforeToolCall`), `@intutic/gate/vercel` (`intuticToolApproval()` on the
|
|
12
|
+
`ai` package's `toolApproval`), `@intutic/gate/openai` (the OpenAI Agents SDK
|
|
13
|
+
for TypeScript — see below), `@intutic/gate/eve` (`intuticApproval()` on
|
|
14
|
+
eve's per-tool/per-connection `approval` policy surface — Vercel's
|
|
15
|
+
filesystem-first durable-agent framework, a pre-1.0 **Preview** product),
|
|
16
|
+
`@intutic/gate/harness` (Vercel's `@ai-sdk/harness` sandboxed coding-agent
|
|
17
|
+
runtime), `@intutic/gate/workflow` (Vercel's `@ai-sdk/workflow` durable
|
|
18
|
+
workflow agents), and `@intutic/gate/managed-agents` (Anthropic's Managed
|
|
19
|
+
Agents — a session-confirmation responder, not a hook, since Anthropic hosts
|
|
20
|
+
the tool-call loop; see below). LangChain.js has no dedicated adapter planned
|
|
21
|
+
and instead uses the generic `wrapTool`/`wrapTools` helper directly.
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { Gate, GateClient, install, wrapTools } from '@intutic/gate'
|
|
27
|
+
|
|
28
|
+
const gate = new Gate(
|
|
29
|
+
{ workspaceId: process.env.INTUTIC_WORKSPACE_ID },
|
|
30
|
+
GateClient.fromEnv({ harness: 'my-framework' }),
|
|
31
|
+
)
|
|
32
|
+
install(gate) // process-wide default; wrapTool()/wrapTools() pick it up
|
|
33
|
+
|
|
34
|
+
const guardedTools = wrapTools(myTools) // array or {name: tool} record
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
On a refused call, the wrapped tool throws `IntuticGateRefusal` (message
|
|
38
|
+
prefixed `[Intutic Governance] BLOCKED:`) BEFORE the real implementation
|
|
39
|
+
runs — this package's throw-based refusal contract, the same one
|
|
40
|
+
`services/sync-daemon/src/harness/gateBody.ts`'s emitted gates and
|
|
41
|
+
`packages/mcp-proxy/src/policy.ts` use elsewhere in this repo's gate
|
|
42
|
+
vocabulary.
|
|
43
|
+
|
|
44
|
+
## Public API surface
|
|
45
|
+
|
|
46
|
+
| Export | From | What it is |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `Gate`, `GateConfig` | `gate.ts` | The four-tier evaluator. `new Gate(cfg, client?)`, `await gate.guard(toolName, toolInput)`. |
|
|
49
|
+
| `install(gate)`, `active()` | `gate.ts` | Process-wide default gate, so wrapped tools don't need the instance threaded through every call site. |
|
|
50
|
+
| `IntuticGateRefusal`, `GateError`, `GateConnectionError` | `errors.ts` | Thrown on refusal. `.reason`, `.code`, `.incidentId` carry the structured verdict; `.message` carries the `[Intutic Governance] BLOCKED: ...` text. |
|
|
51
|
+
| `GateClient` | `client.ts` | Control-plane client (`hookGate`, `emit`, `GateClient.fromEnv(...)`). |
|
|
52
|
+
| `wrapTool(fn \| tool, opts?)`, `wrapTools(list \| record, gate?)` | `wrapTools.ts` | Generic wrapping for a plain async function or an `{ execute, ... }`-shaped tool object. **This is the integration point for any JS framework without a dedicated adapter — LangChain.js included.** |
|
|
53
|
+
| `intuticHeaders(opts?)` | `headers.ts` | Headers for a proxy-pointed HTTP/OpenAI-compatible client (`x-session-id`, `x-workspace-id`, `x-intutic-harness`). |
|
|
54
|
+
| `loadSnapshot`, `evaluate`, `Snapshot`, `guardDisabledFromEnv` | `snapshot.ts` | Tier A1: reads `~/.intutic/hooks/policy-snapshot.rules`. |
|
|
55
|
+
| `parseRules`, `firstMatch`, `fetchRules`, `SopRule` | `soprules.ts` | Tier A3: SOP-authored `WHERE`-clause rules. |
|
|
56
|
+
| `checkCommand`, `checkImages`, `checkWrittenManifest`, `ImageVerdict` | `imagecheck.ts` | Tier A2: container-image provenance on deploy commands. |
|
|
57
|
+
| `classify`, `isDeploy`, `isTest`, `touchesInfra` | `actions.ts` | Command classifier shared by A2's deploy trigger. |
|
|
58
|
+
|
|
59
|
+
### A note for sibling adapter phases
|
|
60
|
+
|
|
61
|
+
`Gate.guard()` is **async** (`Promise<void>`), unlike the Python SDK's
|
|
62
|
+
synchronous `Gate.guard()` — the network-backed tiers (SOP-rule fetch,
|
|
63
|
+
`POST /hook-gate`) use `fetch` here rather than Python's blocking
|
|
64
|
+
`urllib.request`. Every adapter built on this package must `await` it.
|
|
65
|
+
|
|
66
|
+
### What Tier A1 does and does not cover
|
|
67
|
+
|
|
68
|
+
Like the Python SDK it ports, this package's snapshot reader (Tier A1) reads
|
|
69
|
+
**only** `~/.intutic/hooks/policy-snapshot.rules`. It does **not** separately
|
|
70
|
+
compile in the "static floor" patterns
|
|
71
|
+
(`services/sync-daemon/src/harness/protectedPaths.ts`'s
|
|
72
|
+
`staticFloorPatterns()` — the bypass/secret-content/skill-surface pattern
|
|
73
|
+
tables) the way the shipped shell/JS gate emitters do (`INTUTIC_FLOOR`,
|
|
74
|
+
concatenated ahead of the snapshot's own rules in `gateBody.ts`'s
|
|
75
|
+
`intuticGate()`). Only what actually flows through the `.rules` file —
|
|
76
|
+
SOP-authored rules, the destructive-command tier, and the tier-promoted
|
|
77
|
+
skill-surface rules — is enforced by Tier A1 here. This gap already exists in
|
|
78
|
+
`intutic_clawde`; it is preserved, not introduced, by this port. See
|
|
79
|
+
`src/__tests__/fidelity.test.ts` for exactly which parts of the shipped
|
|
80
|
+
contract Tier A1 DOES reproduce, verified against the real pattern tables.
|
|
81
|
+
|
|
82
|
+
## `@intutic/gate/openai` — OpenAI Agents SDK (TypeScript)
|
|
83
|
+
|
|
84
|
+
The adapter for `@openai/agents` (the TypeScript twin of the Python SDK's
|
|
85
|
+
`intutic_clawde.gate.adapters.openai_agents`). The SDK's documented per-tool
|
|
86
|
+
veto point is a **tool input guardrail** (`@openai/agents-core` >= 0.3.8):
|
|
87
|
+
the runner executes guardrails before the tool body, and a
|
|
88
|
+
`rejectContent` result skips the tool and hands the message to the model.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { Agent, run } from '@openai/agents'
|
|
92
|
+
import { installOpenAiGate, wrapAgent } from '@intutic/gate/openai'
|
|
93
|
+
|
|
94
|
+
installOpenAiGate({ workspaceId: process.env.INTUTIC_WORKSPACE_ID })
|
|
95
|
+
|
|
96
|
+
const agent = wrapAgent(new Agent({ name: 'ops', tools, mcpServers }))
|
|
97
|
+
const result = await run(agent, prompt)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
* `intuticToolGuardrail()` — the raw guardrail, attachable via
|
|
101
|
+
`tool({ inputGuardrails: [...] })`. Refusal → `rejectContent` with the
|
|
102
|
+
`[Intutic Governance] BLOCKED: ...` message; unexpected gate crash →
|
|
103
|
+
`rejectContent` too (fail closed).
|
|
104
|
+
* `wrapTools(tools)` / `wrapAgent(agent)` — inject the guardrail into every
|
|
105
|
+
`FunctionTool`, **including `mcpServers`-derived tools** (`wrapAgent`
|
|
106
|
+
patches `getAllTools`, the only place those ever appear — mapping over
|
|
107
|
+
`agent.tools` misses them); rewrite `hostedMcpTool` entries to
|
|
108
|
+
`require_approval: 'always'` plus an Intutic `on_approval`; install a
|
|
109
|
+
composed gate-driven `onApproval` on local `shellTool`/`applyPatchTool`;
|
|
110
|
+
and gate `computerTool` through its `needsApproval` predicate (refusal →
|
|
111
|
+
pending interruption your code must reject — the SDK has no auto-reject
|
|
112
|
+
hook for computer actions).
|
|
113
|
+
* `installOpenAiGate()` — builds + `install()`s a `Gate` and, by default,
|
|
114
|
+
sets `OPENAI_AGENTS_DISABLE_TRACING=1`: the SDK's tracing exporter posts
|
|
115
|
+
tool inputs/outputs to a **hardcoded** `api.openai.com/v1/traces/ingest`
|
|
116
|
+
that ignores `OPENAI_BASE_URL` (a DLP leak around the proxy). Pass
|
|
117
|
+
`{ tracingExport: 'keep' }` only once the exporter endpoint is re-pointed.
|
|
118
|
+
* Truly hosted tools (`webSearchTool`, `fileSearchTool`,
|
|
119
|
+
`codeInterpreterTool`, image generation, hosted-environment `shellTool`)
|
|
120
|
+
execute server-side at OpenAI — **no client-side hook exists**; they pass
|
|
121
|
+
through unwrapped, stated plainly rather than pretended otherwise.
|
|
122
|
+
|
|
123
|
+
LLM egress: the underlying `openai` client honours `OPENAI_BASE_URL`, so a
|
|
124
|
+
sourced `.env.intutic` routes chat traffic through the Intutic proxy with
|
|
125
|
+
zero code. See `apps/docs/integrations/openai-agents.md` for the full
|
|
126
|
+
operator-facing version (guardrail-vs-approval ordering, realtime coverage,
|
|
127
|
+
minimum versions).
|
|
128
|
+
|
|
129
|
+
## `@intutic/gate/harness` — Vercel `@ai-sdk/harness` (sandboxed coding agents)
|
|
130
|
+
|
|
131
|
+
`HarnessAgent` runs coding-agent runtimes (Claude Code, Grok Build, ...)
|
|
132
|
+
**server-side, in Vercel Sandbox microVMs** — a materially different execution
|
|
133
|
+
model from every other adapter in this package, and its veto surface differs
|
|
134
|
+
to match. Confirmed against `@ai-sdk/harness@1.0.75` (a devDependency,
|
|
135
|
+
type-checked and exercised in `src/__tests__/harness.test.ts`):
|
|
136
|
+
|
|
137
|
+
- The `toolApproval` setting is a **static** `Readonly<Record<string,
|
|
138
|
+
ToolApprovalStatus>>` — "without callback support" (the shipped doc's own
|
|
139
|
+
words). Per-call gating therefore routes through the tool-approval **flow**:
|
|
140
|
+
`intuticStaticApprovals(tools)` marks every custom tool `'user-approval'`
|
|
141
|
+
(pausing each call), and `intuticApprovalResponder()` answers each pause
|
|
142
|
+
with a real `Gate.guard()` verdict, producing the
|
|
143
|
+
`toolApprovalContinuations` array for `continueGenerate`/`continueStream`.
|
|
144
|
+
`intuticSubmitApprovals(session, ...)` uses the optional
|
|
145
|
+
`session.submitToolApproval` instead when the adapter implements it
|
|
146
|
+
(harness-claude-code does; harness-grok-build does not).
|
|
147
|
+
- **Built-in sandbox tools (read/write/edit/bash/...) never consult
|
|
148
|
+
`toolApproval`.** They are governed only by `permissionMode`, which
|
|
149
|
+
**defaults to `'allow-all'`**. `recommendedHarnessSettings()` returns the
|
|
150
|
+
posture this integration recommends instead (`'allow-edits'`, plus a
|
|
151
|
+
sandbox `networkPolicy` — deny-all, or a host allow-list — plus
|
|
152
|
+
`inactiveTools: ['bash']` by default, dropping `bash` from the tool set
|
|
153
|
+
entirely rather than merely gating it; opt out with `filterBash: false`)
|
|
154
|
+
— because the laptop Intutic proxy never sees sandbox egress, host-level
|
|
155
|
+
network policy is the only egress control available there, and it is
|
|
156
|
+
coarse (no DLP).
|
|
157
|
+
- **`intuticSandboxBootstrap()`** injects a Tier A1 (policy-snapshot)
|
|
158
|
+
`PreToolUse` hook + `.claude/settings.json` directly into the sandbox
|
|
159
|
+
filesystem via `HarnessAgentSettings.sandboxConfig.onBootstrap` — the only
|
|
160
|
+
way to put anything resembling the native Intutic gate inside the
|
|
161
|
+
microVM. Claude Code only; a strict subset of a laptop gate (no SOP tier,
|
|
162
|
+
review-hold, or event draining — those need a live control-plane
|
|
163
|
+
connection a bootstrap function can't have). Spread its output into
|
|
164
|
+
`sandboxConfig` alongside `recommendedHarnessSettings()`. See TD-417 and
|
|
165
|
+
`apps/docs/integrations/ai-sdk-harness.md` for what has and hasn't been
|
|
166
|
+
live-verified.
|
|
167
|
+
|
|
168
|
+
## `@intutic/gate/workflow` — Vercel `@ai-sdk/workflow` (durable workflow agents)
|
|
169
|
+
|
|
170
|
+
`WorkflowAgent` has **zero approval fields** (confirmed against
|
|
171
|
+
`@ai-sdk/workflow@1.0.69`); its veto surface is per-tool `needsApproval`,
|
|
172
|
+
which pauses a call **durably** (a human can approve hours later).
|
|
173
|
+
`intuticNeedsApproval(toolName)` builds that function from `Gate.guard()`;
|
|
174
|
+
`withIntuticApproval(tools)` attaches it to a whole record, composing with any
|
|
175
|
+
`needsApproval` a tool already declares.
|
|
176
|
+
|
|
177
|
+
The durable runtime **retries** thrown errors — and its retry/abort decision
|
|
178
|
+
duck-types on `error.name === 'FatalError'` (`FatalError.is()`, confirmed
|
|
179
|
+
against `workflow@4.8.3`'s real machinery, because workflows run in a separate
|
|
180
|
+
`vm` realm where `instanceof` fails). A plain `IntuticGateRefusal` thrown from
|
|
181
|
+
`needsApproval` would be retried toward max attempts — a governance denial
|
|
182
|
+
replayed on a timer. This adapter therefore throws `IntuticWorkflowRefusal`:
|
|
183
|
+
still an `IntuticGateRefusal` (message, `.reason`/`.code`/`.incidentId`
|
|
184
|
+
intact) but with `name = 'FatalError'`, so a denial **aborts** instead of
|
|
185
|
+
retry-looping. On allow it resolves `false` (no human pause) or `true` (with
|
|
186
|
+
`{ onAllow: 'human' }` — gate allows AND a human still approves).
|
|
187
|
+
`wrapWorkflowTools()` is the execute-level variant: `wrapTools` semantics with
|
|
188
|
+
the throw contract converted to the fatal shape.
|
|
189
|
+
|
|
190
|
+
## `@intutic/gate/managed-agents` — Anthropic Managed Agents (session responder)
|
|
191
|
+
|
|
192
|
+
Anthropic hosts the tool-call loop for a Managed Agents session — your process
|
|
193
|
+
never executes a call directly, so there is no hook to attach. Instead your
|
|
194
|
+
backend answers session events. `evaluated_permission: "ask"` on an
|
|
195
|
+
`agent.tool_use`/`agent.mcp_tool_use` event (e.g. a tool configured
|
|
196
|
+
`always_ask`) **pauses the session** until a `user.tool_confirmation` event
|
|
197
|
+
arrives — a real, documented pre-execution veto ("Denied tools do not run.").
|
|
198
|
+
`IntuticSessionConfirmer` answers those pauses with a `Gate.guard()` verdict,
|
|
199
|
+
via polling, a webhook (`session.requires_action`), or a live stream. A tool
|
|
200
|
+
configured `always_allow` never pauses and is therefore never seen by
|
|
201
|
+
Intutic at all — see TD-425.
|
|
202
|
+
|
|
203
|
+
`agent.custom_tool_use` (your own tools) has no pause concept — it is gated
|
|
204
|
+
at the point YOUR code executes it instead, via
|
|
205
|
+
`wrapManagedAgentsCustomTool`/`wrapManagedAgentsCustomTools` (the
|
|
206
|
+
`BetaRunnableTool.run()` shape, not `.execute` — the generic `wrapTools()`
|
|
207
|
+
does not apply here). See `apps/docs/integrations/anthropic-managed-agents.md`
|
|
208
|
+
for the full operator-facing version, including the self-hosted
|
|
209
|
+
`EnvironmentWorker` coverage story and the Python-side custom-tool decorator
|
|
210
|
+
ordering gotcha (TD-427).
|
|
211
|
+
|
|
212
|
+
## Subpath convention
|
|
213
|
+
|
|
214
|
+
Eight adapters exist today, one source file each: `@intutic/gate/dsh`
|
|
215
|
+
(`src/dsh.ts` — a Cordis plugin; see its module doc for the veto contract and
|
|
216
|
+
`services/sync-daemon/src/harness/dshHooks.ts` for profile registration),
|
|
217
|
+
`@intutic/gate/mastra` (`src/mastra.ts`), `@intutic/gate/vercel`
|
|
218
|
+
(`src/vercel.ts`), `@intutic/gate/openai` (`src/openai.ts` — see above),
|
|
219
|
+
`@intutic/gate/eve` (`src/eve.ts` — approval policies for eve's
|
|
220
|
+
per-tool/per-connection `approval` surface, plus the observe-only
|
|
221
|
+
`intuticAuditHooks()`; verified against a pinned `eve@0.39.1` install — a
|
|
222
|
+
pre-1.0 Preview product, see its module doc and TD-410), `@intutic/gate/harness`
|
|
223
|
+
(`src/harness.ts` — see above), `@intutic/gate/workflow` (`src/workflow.ts`
|
|
224
|
+
— see above), and `@intutic/gate/managed-agents` (`src/managedAgents.ts` — see
|
|
225
|
+
above). Later adapter phases follow the SAME convention (also
|
|
226
|
+
`services/sync-daemon`'s existing subpath convention — see that package's
|
|
227
|
+
`package.json`):
|
|
228
|
+
|
|
229
|
+
1. One source file per adapter: `src/vercel.ts`, `src/mastra.ts`,
|
|
230
|
+
`src/dsh.ts`, `src/harness.ts`, `src/workflow.ts`, `src/managedAgents.ts`.
|
|
231
|
+
2. An `exports` entry per adapter in `package.json`:
|
|
232
|
+
```json
|
|
233
|
+
"./vercel": { "import": "./dist/vercel.js", "types": "./dist/vercel.d.ts" }
|
|
234
|
+
```
|
|
235
|
+
3. A matching `typesVersions` entry so editors resolve types from source
|
|
236
|
+
pre-build:
|
|
237
|
+
```json
|
|
238
|
+
"typesVersions": { "*": { "vercel": ["src/vercel.ts"] } }
|
|
239
|
+
```
|
|
240
|
+
4. Each adapter file imports from `./gate.js`, `./errors.js`, etc. (this
|
|
241
|
+
package's core, already built) rather than re-implementing any tier —
|
|
242
|
+
the whole point of splitting core from adapters is that the four-tier
|
|
243
|
+
evaluation logic lives in exactly one place.
|
|
244
|
+
|
|
245
|
+
No stub files are checked in for future adapters; the `exports` map above
|
|
246
|
+
documents the shape they should take rather than pre-committing to file
|
|
247
|
+
names a later phase might want to change.
|
|
248
|
+
|
|
249
|
+
## Fidelity suite
|
|
250
|
+
|
|
251
|
+
`src/__tests__/fidelity.test.ts` builds a synthetic `.rules` snapshot from a
|
|
252
|
+
point-in-time copy of the REAL pattern tables in
|
|
253
|
+
`services/sync-daemon/src/harness/protectedPaths.ts`
|
|
254
|
+
(`src/__tests__/fixtures/protectedPathsFixtures.ts` — see that file's header
|
|
255
|
+
for why it is a copy rather than a live cross-package import, and how to
|
|
256
|
+
re-sync it) and asserts `evaluate()` reproduces the same block/warn/shadow
|
|
257
|
+
verdict as each pattern's own `matches`/`notMatches` fixtures, for every
|
|
258
|
+
pattern whose `subject` a `.rules` file can actually carry (`command`,
|
|
259
|
+
`target`, `tool`, `any` — `content`-subject patterns, i.e.
|
|
260
|
+
`SECRET_CONTENT_PATTERNS`, are out of scope: they never reach the snapshot
|
|
261
|
+
channel in the first place, matching the Python SDK's own limitation).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of the proxy's command classifier.
|
|
3
|
+
*
|
|
4
|
+
* Source of truth: `packages/proxy/src/plugins/anomaly/actions.rs`, by way of
|
|
5
|
+
* `packages/intutic-clawde/intutic_clawde/gate/actions.py` (the Python SDK's
|
|
6
|
+
* own transliteration, which this file mirrors line for line rather than
|
|
7
|
+
* re-deriving from the Rust — see that module's docstring for why: two
|
|
8
|
+
* independent readings of the Rust drift, one faithful copy of the Python
|
|
9
|
+
* reading does not).
|
|
10
|
+
*
|
|
11
|
+
* The proxy synthesises abstract `action:` tokens from tool calls and
|
|
12
|
+
* evaluates ordering rules over them. A pre-execution gate has to reach the
|
|
13
|
+
* SAME verdict the proxy would, one turn earlier — if the two disagree, the
|
|
14
|
+
* gate either blocks something the proxy would allow, or waves through
|
|
15
|
+
* something the proxy then refuses.
|
|
16
|
+
*
|
|
17
|
+
* Note the trailing spaces in `'update '`, `'truncate '` and `'curl -d '` —
|
|
18
|
+
* they are load-bearing and must survive editing.
|
|
19
|
+
*/
|
|
20
|
+
export declare const ACTION_PREFIX = "action:";
|
|
21
|
+
/** Commands that put code or artefacts somewhere real. */
|
|
22
|
+
export declare const DEPLOY_PATTERNS: readonly string[];
|
|
23
|
+
/** Commands that publish a package or a release to the outside world. */
|
|
24
|
+
export declare const PUBLISH_PATTERNS: readonly string[];
|
|
25
|
+
/** Commands that cut a release. */
|
|
26
|
+
export declare const RELEASE_PATTERNS: readonly string[];
|
|
27
|
+
/** Commands that run a test suite. */
|
|
28
|
+
export declare const TEST_PATTERNS: readonly string[];
|
|
29
|
+
/** Commands that send data somewhere over the network. */
|
|
30
|
+
export declare const HTTP_POST_PATTERNS: readonly string[];
|
|
31
|
+
/** Commands that write to a database. */
|
|
32
|
+
export declare const DB_WRITE_PATTERNS: readonly string[];
|
|
33
|
+
/**
|
|
34
|
+
* Path fragments that indicate credential material.
|
|
35
|
+
*
|
|
36
|
+
* `kubeconfig` and `service-account` are in here, so any command mentioning
|
|
37
|
+
* either synthesises `action:secret_read`.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SECRET_PATH_FRAGMENTS: readonly string[];
|
|
40
|
+
/** Path fragments that indicate personal data leaving the system. */
|
|
41
|
+
export declare const PII_PATH_FRAGMENTS: readonly string[];
|
|
42
|
+
/** Tool names harnesses use for "run a shell command". */
|
|
43
|
+
export declare const SHELL_TOOLS: readonly string[];
|
|
44
|
+
/** Tool names harnesses use for "read a file". */
|
|
45
|
+
export declare const READ_TOOLS: readonly string[];
|
|
46
|
+
/** Tool names harnesses use for "fetch a URL". */
|
|
47
|
+
export declare const FETCH_TOOLS: readonly string[];
|
|
48
|
+
/**
|
|
49
|
+
* Path fragments that indicate infrastructure-as-code.
|
|
50
|
+
* Source: `packages/proxy/src/manifest.rs:280` (`INFRA_PATH_FRAGMENTS`).
|
|
51
|
+
* Used to decide when a WRITE deserves an image-integrity check.
|
|
52
|
+
*/
|
|
53
|
+
export declare const INFRA_PATH_FRAGMENTS: readonly string[];
|
|
54
|
+
/**
|
|
55
|
+
* Concatenate the string-ish values of a tool's arguments, lowercased.
|
|
56
|
+
*
|
|
57
|
+
* Which key holds the command varies by harness (`command`, `cmd`, `script`,
|
|
58
|
+
* `file_path`, `path`, `url`), and a new harness will invent another. Reading
|
|
59
|
+
* every string value means an unknown key still classifies correctly.
|
|
60
|
+
*
|
|
61
|
+
* Mirrors the Python/Rust exactly, including the leading space before each
|
|
62
|
+
* nested value — spacing changes which patterns can straddle a value
|
|
63
|
+
* boundary.
|
|
64
|
+
*/
|
|
65
|
+
export declare function flattenInput(value: unknown): string;
|
|
66
|
+
export declare function matchesAny(haystack: string, patterns: readonly string[]): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Match a tool name against a group.
|
|
69
|
+
*
|
|
70
|
+
* `endsWith` is what lets namespaced names like `mcp__sh__bash` classify.
|
|
71
|
+
*/
|
|
72
|
+
export declare function toolIs(name: string, group: readonly string[]): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Classify one tool call into the abstract actions it performs.
|
|
75
|
+
*
|
|
76
|
+
* Returns prefixed tokens (`action:deploy`, ...) in the order the Rust/Python
|
|
77
|
+
* emit them. Order matters: the ordering detectors read position in the
|
|
78
|
+
* sequence.
|
|
79
|
+
*/
|
|
80
|
+
export declare function classify(toolName: string, toolInput: unknown): string[];
|
|
81
|
+
/** True when this call would deploy — the trigger for the image check. */
|
|
82
|
+
export declare function isDeploy(toolName: string, toolInput: unknown): boolean;
|
|
83
|
+
export declare function isTest(toolName: string, toolInput: unknown): boolean;
|
|
84
|
+
/** True when a written path is infrastructure-as-code. */
|
|
85
|
+
export declare function touchesInfra(path: string | null | undefined): boolean;
|
|
86
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,aAAa,YAAY,CAAA;AAEtC,0DAA0D;AAC1D,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAe5C,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAS7C,CAAA;AAED,mCAAmC;AACnC,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAO7C,CAAA;AAED,sCAAsC;AACtC,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAqB1C,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAO/C,CAAA;AAED,yCAAyC;AACzC,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAO9C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAclD,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAO/C,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAQxC,CAAA;AAED,kDAAkD;AAClD,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAAqD,CAAA;AAE7F,kDAAkD;AAClD,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAAmE,CAAA;AAE5G;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EASjD,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUnD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEjF;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAGtE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,CAoBvE;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAEtE;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAEpE;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAErE"}
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of the proxy's command classifier.
|
|
3
|
+
*
|
|
4
|
+
* Source of truth: `packages/proxy/src/plugins/anomaly/actions.rs`, by way of
|
|
5
|
+
* `packages/intutic-clawde/intutic_clawde/gate/actions.py` (the Python SDK's
|
|
6
|
+
* own transliteration, which this file mirrors line for line rather than
|
|
7
|
+
* re-deriving from the Rust — see that module's docstring for why: two
|
|
8
|
+
* independent readings of the Rust drift, one faithful copy of the Python
|
|
9
|
+
* reading does not).
|
|
10
|
+
*
|
|
11
|
+
* The proxy synthesises abstract `action:` tokens from tool calls and
|
|
12
|
+
* evaluates ordering rules over them. A pre-execution gate has to reach the
|
|
13
|
+
* SAME verdict the proxy would, one turn earlier — if the two disagree, the
|
|
14
|
+
* gate either blocks something the proxy would allow, or waves through
|
|
15
|
+
* something the proxy then refuses.
|
|
16
|
+
*
|
|
17
|
+
* Note the trailing spaces in `'update '`, `'truncate '` and `'curl -d '` —
|
|
18
|
+
* they are load-bearing and must survive editing.
|
|
19
|
+
*/
|
|
20
|
+
export const ACTION_PREFIX = 'action:';
|
|
21
|
+
/** Commands that put code or artefacts somewhere real. */
|
|
22
|
+
export const DEPLOY_PATTERNS = [
|
|
23
|
+
'git push',
|
|
24
|
+
'kubectl apply',
|
|
25
|
+
'kubectl rollout',
|
|
26
|
+
'helm upgrade',
|
|
27
|
+
'helm install',
|
|
28
|
+
'terraform apply',
|
|
29
|
+
'docker push',
|
|
30
|
+
'serverless deploy',
|
|
31
|
+
'fly deploy',
|
|
32
|
+
'vercel deploy',
|
|
33
|
+
'gcloud run deploy',
|
|
34
|
+
'aws deploy',
|
|
35
|
+
'aws s3 sync',
|
|
36
|
+
'eb deploy',
|
|
37
|
+
];
|
|
38
|
+
/** Commands that publish a package or a release to the outside world. */
|
|
39
|
+
export const PUBLISH_PATTERNS = [
|
|
40
|
+
'npm publish',
|
|
41
|
+
'pnpm publish',
|
|
42
|
+
'yarn publish',
|
|
43
|
+
'cargo publish',
|
|
44
|
+
'twine upload',
|
|
45
|
+
'poetry publish',
|
|
46
|
+
'gem push',
|
|
47
|
+
'docker manifest push',
|
|
48
|
+
];
|
|
49
|
+
/** Commands that cut a release. */
|
|
50
|
+
export const RELEASE_PATTERNS = [
|
|
51
|
+
'gh release create',
|
|
52
|
+
'git tag',
|
|
53
|
+
'npm version',
|
|
54
|
+
'cargo release',
|
|
55
|
+
'goreleaser release',
|
|
56
|
+
'semantic-release',
|
|
57
|
+
];
|
|
58
|
+
/** Commands that run a test suite. */
|
|
59
|
+
export const TEST_PATTERNS = [
|
|
60
|
+
'npm test',
|
|
61
|
+
'npm run test',
|
|
62
|
+
'pnpm test',
|
|
63
|
+
'pnpm run test',
|
|
64
|
+
'yarn test',
|
|
65
|
+
'cargo test',
|
|
66
|
+
'go test',
|
|
67
|
+
'pytest',
|
|
68
|
+
'python -m pytest',
|
|
69
|
+
'vitest',
|
|
70
|
+
'jest',
|
|
71
|
+
'mocha',
|
|
72
|
+
'rspec',
|
|
73
|
+
'phpunit',
|
|
74
|
+
'make test',
|
|
75
|
+
'gradle test',
|
|
76
|
+
'mvn test',
|
|
77
|
+
'dotnet test',
|
|
78
|
+
'bazel test',
|
|
79
|
+
'tox',
|
|
80
|
+
];
|
|
81
|
+
/** Commands that send data somewhere over the network. */
|
|
82
|
+
export const HTTP_POST_PATTERNS = [
|
|
83
|
+
'curl -x post',
|
|
84
|
+
'curl --request post',
|
|
85
|
+
'curl -d ',
|
|
86
|
+
'curl --data',
|
|
87
|
+
'wget --post',
|
|
88
|
+
'http post',
|
|
89
|
+
];
|
|
90
|
+
/** Commands that write to a database. */
|
|
91
|
+
export const DB_WRITE_PATTERNS = [
|
|
92
|
+
'insert into',
|
|
93
|
+
'update ',
|
|
94
|
+
'delete from',
|
|
95
|
+
'drop table',
|
|
96
|
+
'truncate ',
|
|
97
|
+
'alter table',
|
|
98
|
+
];
|
|
99
|
+
/**
|
|
100
|
+
* Path fragments that indicate credential material.
|
|
101
|
+
*
|
|
102
|
+
* `kubeconfig` and `service-account` are in here, so any command mentioning
|
|
103
|
+
* either synthesises `action:secret_read`.
|
|
104
|
+
*/
|
|
105
|
+
export const SECRET_PATH_FRAGMENTS = [
|
|
106
|
+
'.env',
|
|
107
|
+
'credentials',
|
|
108
|
+
'id_rsa',
|
|
109
|
+
'id_ed25519',
|
|
110
|
+
'.pem',
|
|
111
|
+
'.p12',
|
|
112
|
+
'.pfx',
|
|
113
|
+
'secrets.',
|
|
114
|
+
'.netrc',
|
|
115
|
+
'.aws/',
|
|
116
|
+
'.ssh/',
|
|
117
|
+
'kubeconfig',
|
|
118
|
+
'service-account',
|
|
119
|
+
];
|
|
120
|
+
/** Path fragments that indicate personal data leaving the system. */
|
|
121
|
+
export const PII_PATH_FRAGMENTS = [
|
|
122
|
+
'customer',
|
|
123
|
+
'users.csv',
|
|
124
|
+
'pii',
|
|
125
|
+
'personal',
|
|
126
|
+
'gdpr',
|
|
127
|
+
'payroll',
|
|
128
|
+
];
|
|
129
|
+
/** Tool names harnesses use for "run a shell command". */
|
|
130
|
+
export const SHELL_TOOLS = [
|
|
131
|
+
'bash',
|
|
132
|
+
'shell',
|
|
133
|
+
'run_command',
|
|
134
|
+
'runcommand',
|
|
135
|
+
'terminal',
|
|
136
|
+
'execute',
|
|
137
|
+
'exec',
|
|
138
|
+
];
|
|
139
|
+
/** Tool names harnesses use for "read a file". */
|
|
140
|
+
export const READ_TOOLS = ['read', 'readfile', 'view', 'cat', 'open_file'];
|
|
141
|
+
/** Tool names harnesses use for "fetch a URL". */
|
|
142
|
+
export const FETCH_TOOLS = ['webfetch', 'fetch', 'http_request', 'browser', 'web_search'];
|
|
143
|
+
/**
|
|
144
|
+
* Path fragments that indicate infrastructure-as-code.
|
|
145
|
+
* Source: `packages/proxy/src/manifest.rs:280` (`INFRA_PATH_FRAGMENTS`).
|
|
146
|
+
* Used to decide when a WRITE deserves an image-integrity check.
|
|
147
|
+
*/
|
|
148
|
+
export const INFRA_PATH_FRAGMENTS = [
|
|
149
|
+
'terraform',
|
|
150
|
+
'.tf',
|
|
151
|
+
'k8s/',
|
|
152
|
+
'kubernetes/',
|
|
153
|
+
'helm/',
|
|
154
|
+
'dockerfile',
|
|
155
|
+
'docker-compose',
|
|
156
|
+
'.tfstate',
|
|
157
|
+
];
|
|
158
|
+
/**
|
|
159
|
+
* Concatenate the string-ish values of a tool's arguments, lowercased.
|
|
160
|
+
*
|
|
161
|
+
* Which key holds the command varies by harness (`command`, `cmd`, `script`,
|
|
162
|
+
* `file_path`, `path`, `url`), and a new harness will invent another. Reading
|
|
163
|
+
* every string value means an unknown key still classifies correctly.
|
|
164
|
+
*
|
|
165
|
+
* Mirrors the Python/Rust exactly, including the leading space before each
|
|
166
|
+
* nested value — spacing changes which patterns can straddle a value
|
|
167
|
+
* boundary.
|
|
168
|
+
*/
|
|
169
|
+
export function flattenInput(value) {
|
|
170
|
+
if (typeof value === 'string')
|
|
171
|
+
return value.toLowerCase();
|
|
172
|
+
if (Array.isArray(value))
|
|
173
|
+
return value.map((v) => ' ' + flattenInput(v)).join('');
|
|
174
|
+
if (value !== null && typeof value === 'object') {
|
|
175
|
+
return Object.values(value)
|
|
176
|
+
.map((v) => ' ' + flattenInput(v))
|
|
177
|
+
.join('');
|
|
178
|
+
}
|
|
179
|
+
// Numbers, booleans and null/undefined contribute nothing.
|
|
180
|
+
return '';
|
|
181
|
+
}
|
|
182
|
+
export function matchesAny(haystack, patterns) {
|
|
183
|
+
return patterns.some((p) => haystack.includes(p));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Match a tool name against a group.
|
|
187
|
+
*
|
|
188
|
+
* `endsWith` is what lets namespaced names like `mcp__sh__bash` classify.
|
|
189
|
+
*/
|
|
190
|
+
export function toolIs(name, group) {
|
|
191
|
+
const lower = name.toLowerCase();
|
|
192
|
+
return group.some((t) => lower === t || lower.endsWith(t));
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Classify one tool call into the abstract actions it performs.
|
|
196
|
+
*
|
|
197
|
+
* Returns prefixed tokens (`action:deploy`, ...) in the order the Rust/Python
|
|
198
|
+
* emit them. Order matters: the ordering detectors read position in the
|
|
199
|
+
* sequence.
|
|
200
|
+
*/
|
|
201
|
+
export function classify(toolName, toolInput) {
|
|
202
|
+
const args = flattenInput(toolInput);
|
|
203
|
+
const actions = [];
|
|
204
|
+
if (toolIs(toolName, SHELL_TOOLS)) {
|
|
205
|
+
// Tests first: `make test && git push` is both, and the ordering rule
|
|
206
|
+
// needs the test to be seen as having happened before the deploy.
|
|
207
|
+
if (matchesAny(args, TEST_PATTERNS))
|
|
208
|
+
actions.push('run_tests');
|
|
209
|
+
if (matchesAny(args, DEPLOY_PATTERNS))
|
|
210
|
+
actions.push('deploy');
|
|
211
|
+
if (matchesAny(args, PUBLISH_PATTERNS))
|
|
212
|
+
actions.push('publish');
|
|
213
|
+
if (matchesAny(args, RELEASE_PATTERNS))
|
|
214
|
+
actions.push('release');
|
|
215
|
+
// Source before sink, so that (secret_read -> http_post) can still fire
|
|
216
|
+
// on a single command that does both.
|
|
217
|
+
if (matchesAny(args, SECRET_PATH_FRAGMENTS))
|
|
218
|
+
actions.push('secret_read');
|
|
219
|
+
if (matchesAny(args, PII_PATH_FRAGMENTS))
|
|
220
|
+
actions.push('pii_export');
|
|
221
|
+
if (matchesAny(args, HTTP_POST_PATTERNS))
|
|
222
|
+
actions.push('http_post');
|
|
223
|
+
if (matchesAny(args, DB_WRITE_PATTERNS))
|
|
224
|
+
actions.push('db_write');
|
|
225
|
+
}
|
|
226
|
+
return actions.map((a) => ACTION_PREFIX + a);
|
|
227
|
+
}
|
|
228
|
+
/** True when this call would deploy — the trigger for the image check. */
|
|
229
|
+
export function isDeploy(toolName, toolInput) {
|
|
230
|
+
return classify(toolName, toolInput).includes(ACTION_PREFIX + 'deploy');
|
|
231
|
+
}
|
|
232
|
+
export function isTest(toolName, toolInput) {
|
|
233
|
+
return classify(toolName, toolInput).includes(ACTION_PREFIX + 'run_tests');
|
|
234
|
+
}
|
|
235
|
+
/** True when a written path is infrastructure-as-code. */
|
|
236
|
+
export function touchesInfra(path) {
|
|
237
|
+
return matchesAny((path ?? '').toLowerCase(), INFRA_PATH_FRAGMENTS);
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|