@intutic/shared-types 2.1.0 → 2.3.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.
- package/dist/anomaly.d.ts +6 -10
- package/dist/anomaly.d.ts.map +1 -1
- package/dist/anomaly.js +0 -2
- package/dist/anomaly.js.map +1 -1
- package/dist/api-contracts.d.ts +1 -1
- package/dist/api-contracts.js +1 -1
- package/dist/attenuation.d.ts +1 -1
- package/dist/attenuation.js +1 -1
- package/dist/auth.d.ts +10 -9
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +3 -4
- package/dist/auth.js.map +1 -1
- package/dist/billing.d.ts +1 -1
- package/dist/billing.js +1 -1
- package/dist/destructiveSql.d.ts +48 -0
- package/dist/destructiveSql.d.ts.map +1 -0
- package/dist/destructiveSql.js +43 -0
- package/dist/destructiveSql.js.map +1 -0
- package/dist/devInventory.d.ts +120 -0
- package/dist/devInventory.d.ts.map +1 -0
- package/dist/devInventory.js +80 -0
- package/dist/devInventory.js.map +1 -0
- package/dist/enums.d.ts +18 -21
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +24 -28
- package/dist/enums.js.map +1 -1
- package/dist/errors.js +3 -3
- package/dist/errors.js.map +1 -1
- package/dist/finops.d.ts +14 -2
- package/dist/finops.d.ts.map +1 -1
- package/dist/finops.js +15 -1
- package/dist/finops.js.map +1 -1
- package/dist/gateDecisions.d.ts +18 -0
- package/dist/gateDecisions.d.ts.map +1 -0
- package/dist/gateDecisions.js +20 -0
- package/dist/gateDecisions.js.map +1 -0
- package/dist/gateIdentity.d.ts +23 -0
- package/dist/gateIdentity.d.ts.map +1 -0
- package/dist/gateIdentity.js +32 -0
- package/dist/gateIdentity.js.map +1 -0
- package/dist/gateKind.d.ts +172 -0
- package/dist/gateKind.d.ts.map +1 -0
- package/dist/gateKind.js +160 -0
- package/dist/gateKind.js.map +1 -0
- package/dist/gateLimits.d.ts +170 -0
- package/dist/gateLimits.d.ts.map +1 -0
- package/dist/gateLimits.js +96 -0
- package/dist/gateLimits.js.map +1 -0
- package/dist/gitRemote.d.ts +17 -0
- package/dist/gitRemote.d.ts.map +1 -0
- package/dist/gitRemote.js +71 -0
- package/dist/gitRemote.js.map +1 -0
- package/dist/governanceCoverage.d.ts +3 -3
- package/dist/governanceCoverage.js +3 -3
- package/dist/guardrailIr.d.ts +3 -3
- package/dist/guardrailIr.d.ts.map +1 -1
- package/dist/guardrailIr.js +3 -3
- package/dist/guardrailIr.js.map +1 -1
- package/dist/guardrailRender.d.ts +1 -1
- package/dist/guardrailRender.js +1 -1
- package/dist/harnessRules.d.ts +74 -0
- package/dist/harnessRules.d.ts.map +1 -0
- package/dist/harnessRules.js +142 -0
- package/dist/harnessRules.js.map +1 -0
- package/dist/holdMessages.d.ts +25 -0
- package/dist/holdMessages.d.ts.map +1 -0
- package/dist/holdMessages.js +34 -0
- package/dist/holdMessages.js.map +1 -0
- package/dist/identity.d.ts +1 -1
- package/dist/identity.js +2 -2
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +36 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +141 -10
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +1 -2
- package/dist/intelligence.d.ts.map +1 -1
- package/dist/intelligence.js.map +1 -1
- package/dist/mcpBudgets.d.ts +191 -0
- package/dist/mcpBudgets.d.ts.map +1 -0
- package/dist/mcpBudgets.js +144 -0
- package/dist/mcpBudgets.js.map +1 -0
- package/dist/mcpRegistryRecord.d.ts +143 -0
- package/dist/mcpRegistryRecord.d.ts.map +1 -0
- package/dist/mcpRegistryRecord.js +229 -0
- package/dist/mcpRegistryRecord.js.map +1 -0
- package/dist/mcpToolRisk.d.ts +82 -0
- package/dist/mcpToolRisk.d.ts.map +1 -0
- package/dist/mcpToolRisk.js +334 -0
- package/dist/mcpToolRisk.js.map +1 -0
- package/dist/modelCatalog.d.ts +2 -2
- package/dist/modelCatalog.generated.js +1 -1
- package/dist/modelCatalog.generated.js.map +1 -1
- package/dist/modelCatalog.js +2 -2
- package/dist/notifications.d.ts +20 -130
- package/dist/notifications.d.ts.map +1 -1
- package/dist/notifications.js +241 -1
- package/dist/notifications.js.map +1 -1
- package/dist/phrases.d.ts +87 -0
- package/dist/phrases.d.ts.map +1 -0
- package/dist/phrases.js +241 -0
- package/dist/phrases.js.map +1 -0
- package/dist/piiDetectors.d.ts +97 -0
- package/dist/piiDetectors.d.ts.map +1 -0
- package/dist/piiDetectors.js +96 -0
- package/dist/piiDetectors.js.map +1 -0
- package/dist/piiDetectors.json +71 -0
- package/dist/policy.d.ts +1 -1
- package/dist/policy.js +1 -1
- package/dist/policyGuardrails.d.ts +127 -10
- package/dist/policyGuardrails.d.ts.map +1 -1
- package/dist/policyGuardrails.js +59 -6
- package/dist/policyGuardrails.js.map +1 -1
- package/dist/posturePresets.js +1 -1
- package/dist/posturePresets.js.map +1 -1
- package/dist/providerVerification.d.ts +2 -2
- package/dist/providerVerification.js +2 -2
- package/dist/providers.d.ts +4 -4
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +11 -6
- package/dist/providers.js.map +1 -1
- package/dist/regoBuiltins.d.ts +42 -0
- package/dist/regoBuiltins.d.ts.map +1 -0
- package/dist/regoBuiltins.js +732 -0
- package/dist/regoBuiltins.js.map +1 -0
- package/dist/regoRules.d.ts +105 -0
- package/dist/regoRules.d.ts.map +1 -0
- package/dist/regoRules.js +407 -0
- package/dist/regoRules.js.map +1 -0
- package/dist/ruleLoadFailures.d.ts +15 -0
- package/dist/ruleLoadFailures.d.ts.map +1 -0
- package/dist/ruleLoadFailures.js +26 -0
- package/dist/ruleLoadFailures.js.map +1 -0
- package/dist/scriptScan.d.ts +5 -5
- package/dist/scriptScan.js +3 -3
- package/dist/sequence.d.ts +52 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +127 -0
- package/dist/sequence.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +1 -1
- package/dist/skillScan.d.ts +3 -3
- package/dist/skillScan.d.ts.map +1 -1
- package/dist/skillScan.js +26 -4
- package/dist/skillScan.js.map +1 -1
- package/dist/sop.d.ts +24 -11
- package/dist/sop.d.ts.map +1 -1
- package/dist/sop.js +10 -9
- package/dist/sop.js.map +1 -1
- package/dist/sourceProviders.d.ts +1 -8
- package/dist/sourceProviders.d.ts.map +1 -1
- package/dist/sourceProviders.js +2 -9
- package/dist/sourceProviders.js.map +1 -1
- package/dist/ssoGroupClearance.d.ts +119 -0
- package/dist/ssoGroupClearance.d.ts.map +1 -0
- package/dist/ssoGroupClearance.js +196 -0
- package/dist/ssoGroupClearance.js.map +1 -0
- package/dist/sync.d.ts +42 -14
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +3 -3
- package/dist/sync.js.map +1 -1
- package/dist/taskManagement.d.ts +0 -2
- package/dist/taskManagement.d.ts.map +1 -1
- package/dist/taskManagement.js +0 -2
- package/dist/taskManagement.js.map +1 -1
- package/dist/toolPoison.d.ts +33 -0
- package/dist/toolPoison.d.ts.map +1 -0
- package/dist/toolPoison.js +85 -0
- package/dist/toolPoison.js.map +1 -0
- package/dist/usage.d.ts +186 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/wasmBinary.d.ts +25 -0
- package/dist/wasmBinary.d.ts.map +1 -0
- package/dist/wasmBinary.js +111 -0
- package/dist/wasmBinary.js.map +1 -0
- package/dist/wasmFuel.d.ts +52 -0
- package/dist/wasmFuel.d.ts.map +1 -0
- package/dist/wasmFuel.js +320 -0
- package/dist/wasmFuel.js.map +1 -0
- package/dist/wasmMemoryCap.d.ts +21 -0
- package/dist/wasmMemoryCap.d.ts.map +1 -0
- package/dist/wasmMemoryCap.js +58 -0
- package/dist/wasmMemoryCap.js.map +1 -0
- package/dist/workspaceSettings.d.ts +126 -17
- package/dist/workspaceSettings.d.ts.map +1 -1
- package/dist/workspaceSettings.js +21 -2
- package/dist/workspaceSettings.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which gate an event came from, for the one harness that installs two.
|
|
4
|
+
*
|
|
5
|
+
* A harness is one `HarnessType`: one integration that `intutic connect` sets
|
|
6
|
+
* up, and the unit the harness count counts. Its gate reports under the same
|
|
7
|
+
* id, in hook events (`harnessType`), agent reports, the AI inventory and the
|
|
8
|
+
* SIEM export. `antigravity` is the exception: the integration installs
|
|
9
|
+
* Google Antigravity's `PreToolUse` gate and Gemini CLI's `BeforeTool` gate,
|
|
10
|
+
* for two products a machine may have together or apart. Each reports under
|
|
11
|
+
* its own gate id, `antigravity` and `gemini-cli`, so the silent-gate check
|
|
12
|
+
* expects only the gate of the product that is there, and the inventory and
|
|
13
|
+
* SIEM say which product a call came through. The harness, its rules file and
|
|
14
|
+
* its count stay one.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.GEMINI_CLI_GATE_ID = void 0;
|
|
20
|
+
exports.gateIdentitiesOf = gateIdentitiesOf;
|
|
21
|
+
exports.harnessOfGate = harnessOfGate;
|
|
22
|
+
/** The gate id Gemini CLI's gate reports under. */
|
|
23
|
+
exports.GEMINI_CLI_GATE_ID = 'gemini-cli';
|
|
24
|
+
/** The gate ids a harness's gates report under: its own id, or two for `antigravity`. */
|
|
25
|
+
function gateIdentitiesOf(harness) {
|
|
26
|
+
return harness === 'antigravity' ? ['antigravity', exports.GEMINI_CLI_GATE_ID] : [harness];
|
|
27
|
+
}
|
|
28
|
+
/** The harness a gate id belongs to. */
|
|
29
|
+
function harnessOfGate(gateId) {
|
|
30
|
+
return gateId === exports.GEMINI_CLI_GATE_ID ? 'antigravity' : gateId;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=gateIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateIdentity.js","sourceRoot":"","sources":["../src/gateIdentity.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAMH,4CAEC;AAGD,sCAEC;AAXD,mDAAmD;AACtC,QAAA,kBAAkB,GAAG,YAAY,CAAA;AAE9C,yFAAyF;AACzF,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,0BAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AACpF,CAAC;AAED,wCAAwC;AACxC,SAAgB,aAAa,CAAC,MAAc;IAC1C,OAAO,MAAM,KAAK,0BAAkB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAA;AAC/D,CAAC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gateKind.ts — classifies each harness by HOW its tool calls get governed:
|
|
3
|
+
* for the sync daemon's agent report (`agentReporter.ts`'s `guardrails`
|
|
4
|
+
* facet) and AI inventory, and for the control plane's silent-gate check,
|
|
5
|
+
* which expects a gate only from a harness that has one of its own.
|
|
6
|
+
*
|
|
7
|
+
* # Why this exists
|
|
8
|
+
*
|
|
9
|
+
* `collectAgentReport` used to report `hook_gate: true` unconditionally for
|
|
10
|
+
* every harness, with the comment "the daemon writes the hook gate for every
|
|
11
|
+
* harness it supports." That was already false for `langgraph` — which has
|
|
12
|
+
* no on-disk hook, only the SDK-side `intutic_clawde.gate` — and for `aider`,
|
|
13
|
+
* whose only NO_GATE-registered mechanism is a post-edit, /run-blind
|
|
14
|
+
* pre-commit hook (see `aiderConfigMerger.ts`'s NO_GATE row in
|
|
15
|
+
* `__tests__/harness/gateRegistry.ts`). Wave 1 adds eight more SDK-gated
|
|
16
|
+
* harnesses, which would have made the lie eight times larger without this
|
|
17
|
+
* fix.
|
|
18
|
+
*
|
|
19
|
+
* # What this does NOT do
|
|
20
|
+
*
|
|
21
|
+
* This does not verify that a user actually pip-installed `intutic-clawde`
|
|
22
|
+
* and wired `guard_tools`/`IntuticMiddleware`/etc. into their process — the
|
|
23
|
+
* daemon cannot observe another process's imports, the same way it cannot
|
|
24
|
+
* observe whether a written hook file was left executable. It only reports
|
|
25
|
+
* which MECHANISM this harness's governance model uses (a file the daemon
|
|
26
|
+
* itself writes and can verify existence of, vs. an SDK the harness's own
|
|
27
|
+
* process must import), matching the trust level `hook_gate: true` already
|
|
28
|
+
* carried for file-based harnesses before this fix.
|
|
29
|
+
*
|
|
30
|
+
* # Keeping this in sync with the gate registry
|
|
31
|
+
*
|
|
32
|
+
* `services/sync-daemon/__tests__/harness/gateRegistry.ts` (the GATES/NO_GATE
|
|
33
|
+
* completeness registry exercised by `generatedGateBehaviour.test.ts`) is the
|
|
34
|
+
* authoritative decision per harness, but it is a test-only module (it
|
|
35
|
+
* dynamically imports every writer's compiled `.js` from a temp build dir)
|
|
36
|
+
* and must not be imported from daemon runtime code. `services/sync-daemon/__tests__/harness/gateKind.test.ts`
|
|
37
|
+
* cross-checks the two lists so this file cannot silently drift from that
|
|
38
|
+
* registry's own NO_GATE rows: `file: null` harnesses split between 'sdk'
|
|
39
|
+
* (LangGraph + the Python frameworks — the gate ships in intutic-clawde),
|
|
40
|
+
* 'delegated' (xirp — the gate is whichever wrapped harness's own gate is
|
|
41
|
+
* running), and 'bridge' (trueforge-server — the gate runs in a separate
|
|
42
|
+
* Intutic-operated service, not in any process this repo's writers touch),
|
|
43
|
+
* and 'none' (roo-code, claude-desktop — no hook system); the one non-null
|
|
44
|
+
* row (aiderConfigMerger.ts, "no ... exists") is 'none' too.
|
|
45
|
+
*
|
|
46
|
+
* @module
|
|
47
|
+
*/
|
|
48
|
+
import { type HarnessType as HarnessTypeT } from './enums.js';
|
|
49
|
+
/**
|
|
50
|
+
* `'hook'` — the daemon writes an on-disk hook/config file this harness
|
|
51
|
+
* reads before running a tool call (the 19-harness majority).
|
|
52
|
+
* `'sdk'` — the blocking gate ships in `intutic-clawde`, imported into
|
|
53
|
+
* the harness's own Python process; no file for the daemon
|
|
54
|
+
* to write or verify (LangGraph + the eight Wave/Wave-2
|
|
55
|
+
* frameworks).
|
|
56
|
+
* `'none'` — no tool-call gate exists for this harness (aider: its only
|
|
57
|
+
* native hook is post-edit and /run-blind; Roo Code and
|
|
58
|
+
* Claude Desktop: no hook system).
|
|
59
|
+
* `'delegated'` — this harness has no gate mechanism of its own because it
|
|
60
|
+
* does not run tools itself: it wraps OTHER harnesses that
|
|
61
|
+
* are already `'hook'`- or `'sdk'`-gated, and a tool call
|
|
62
|
+
* made inside it is governed by whichever wrapped harness's
|
|
63
|
+
* own gate is running (Xirp, Agentic Orchestrator, and — a
|
|
64
|
+
* different shape of the same idea — AgentCore Runtime,
|
|
65
|
+
* which HOSTS a customer's already-gated framework code
|
|
66
|
+
* rather than spawning it as a subprocess; see
|
|
67
|
+
* gateRegistry.ts's NO_GATE rows for the reasoning this
|
|
68
|
+
* precedent sets for future orchestrator/host-shaped
|
|
69
|
+
* harnesses).
|
|
70
|
+
* Every wrapped backend of the two orchestrators has a gate of
|
|
71
|
+
* its own (Agentic Orchestrator's `opencode` backend through
|
|
72
|
+
* `openCodeHooks.ts`), so `'delegated'`
|
|
73
|
+
* claims exactly what happens. Distinct from
|
|
74
|
+
* `'none'`: `'none'` means no enforcement point exists
|
|
75
|
+
* ANYWHERE for this harness's tool calls; `'delegated'`
|
|
76
|
+
* means one exists, just not one this harness's own row
|
|
77
|
+
* owns or can be credited for independently — reporting it
|
|
78
|
+
* as `'none'` would undercount real coverage, and reporting
|
|
79
|
+
* it as `'hook'` would overclaim a file this daemon never
|
|
80
|
+
* writes for the wrapping harness itself.
|
|
81
|
+
* `'bridge'` — the gate runs OUT OF PROCESS, in an Intutic-operated
|
|
82
|
+
* service reacting to the harness's own async
|
|
83
|
+
* approval/event API, rather than a file this daemon writes
|
|
84
|
+
* (`'hook'`), an SDK imported into the harness's own process
|
|
85
|
+
* (`'sdk'`), no enforcement point at all (`'none'`), or
|
|
86
|
+
* governance credited to a wrapped harness's own gate
|
|
87
|
+
* (`'delegated'`) — a fifth, genuinely different shape.
|
|
88
|
+
* TRUEFORGE_SERVER is the first and so far only member: a
|
|
89
|
+
* TrueForge standalone/hosted server is a separate process
|
|
90
|
+
* nobody embeds an Intutic gate into (unlike TRUEFORGE,
|
|
91
|
+
* embedded mode, which IS `'sdk'`-gated — see that row's own
|
|
92
|
+
* doc), so `services/trueforge-bridge` watches its turn/event
|
|
93
|
+
* stream externally and answers pending approvals over HTTP.
|
|
94
|
+
* Distinct from `'delegated'`: a delegated harness's tool
|
|
95
|
+
* calls are governed by ANOTHER HARNESS's own gate running
|
|
96
|
+
* in that other harness's process; a bridge-gated harness's
|
|
97
|
+
* tool calls are governed by a service this repo ships and
|
|
98
|
+
* operates, running in neither the harness's process nor any
|
|
99
|
+
* other harness's. Distinct from `'sdk'`: no code from this
|
|
100
|
+
* repo ever runs inside the governed harness's own process
|
|
101
|
+
* at all — the harness's only obligation is to expose the
|
|
102
|
+
* async approval API the bridge polls/subscribes to.
|
|
103
|
+
*/
|
|
104
|
+
export type GateKind = 'hook' | 'sdk' | 'none' | 'delegated' | 'bridge';
|
|
105
|
+
/**
|
|
106
|
+
* Harnesses whose blocking gate ships SDK-side, in the harness's own
|
|
107
|
+
* process — no on-disk hook/config file exists to point a gate at. Mirrors
|
|
108
|
+
* the `file: null` NO_GATE rows in `gateRegistry.ts`.
|
|
109
|
+
*
|
|
110
|
+
* MASTRA, VERCEL_AI_SDK (T2), EVE (A2), and TRUEFORGE (embedded-library mode
|
|
111
|
+
* only — see its own HarnessType doc) are the JS/TS-native members of this
|
|
112
|
+
* family: their blocking gate ships in `@intutic/gate/mastra`/
|
|
113
|
+
* `@intutic/gate/vercel`/`@intutic/gate/eve`/`@intutic/gate/trueforge`
|
|
114
|
+
* (packages/gate-js) rather than `intutic-clawde`, but the shape is
|
|
115
|
+
* identical — no on-disk hook/config file, tools run as plain callables in
|
|
116
|
+
* the harness's own process (for eve, as per-tool/per-connection `approval`
|
|
117
|
+
* policies attached in the agent directory's own TypeScript; for TrueForge,
|
|
118
|
+
* as `intuticApprovalResponder()` answering `tool.approval_required`
|
|
119
|
+
* pauses — see `@intutic/gate/trueforge`'s module doc for why that shape
|
|
120
|
+
* differs from mastra/vercel's single-callback pattern).
|
|
121
|
+
*
|
|
122
|
+
* AI_SDK_HARNESS and AI_SDK_WORKFLOW (A3) are the same `@intutic/gate`
|
|
123
|
+
* family with one nuance worth naming: the VETO still runs SDK-side in the
|
|
124
|
+
* caller's own Node.js process (an approval responder / a `needsApproval`
|
|
125
|
+
* function), which is what `'sdk'` classifies — but for AI_SDK_HARNESS the
|
|
126
|
+
* tool EXECUTION it vetoes happens server-side in a Vercel Sandbox microVM,
|
|
127
|
+
* and its built-in sandbox tools have no veto surface at all beyond
|
|
128
|
+
* `permissionMode` (defaults to 'allow-all'). `'sdk'` describes where the
|
|
129
|
+
* gate mechanism lives, not a claim that every tool the harness can run
|
|
130
|
+
* passes through it — see gateRegistry.ts's NO_GATE rows for the honest
|
|
131
|
+
* scope statement per harness.
|
|
132
|
+
*/
|
|
133
|
+
export declare const SDK_GATED_HARNESSES: ReadonlySet<HarnessTypeT>;
|
|
134
|
+
/**
|
|
135
|
+
* Harnesses with no tool-call gate of their own: the proxy and the MCP
|
|
136
|
+
* governance proxy are their enforcement. Mirrors the NO_GATE rows in
|
|
137
|
+
* `gateRegistry.ts`: aider's only native hook (`--git-commit-verify`) is
|
|
138
|
+
* opt-in, post-edit, and blind to `/run`; Roo Code and Claude Desktop have no
|
|
139
|
+
* hook system at all (Claude Desktop's Code tab is Claude Code, gated by the
|
|
140
|
+
* claude-code gate); Continue's CLI loads PreToolUse hooks but never fires
|
|
141
|
+
* them, and its IDE extension has none (see the continueConfigMerger.ts row).
|
|
142
|
+
*/
|
|
143
|
+
export declare const NO_GATE_HARNESSES: ReadonlySet<HarnessTypeT>;
|
|
144
|
+
/**
|
|
145
|
+
* Harnesses that wrap OTHER already-gated harnesses instead of running tools
|
|
146
|
+
* themselves — no gate of their own, but not ungoverned either. Mirrors the
|
|
147
|
+
* `file: null` NO_GATE rows for `xirp` and `agentic-orchestrator` in
|
|
148
|
+
* `gateRegistry.ts`. Xirp was the first entry of this shape; Agentic
|
|
149
|
+
* Orchestrator (O3) is the second. O2 (QM) is expected to add a third, same
|
|
150
|
+
* "wraps other harnesses" shape, in a concurrent phase not yet merged as of
|
|
151
|
+
* this one.
|
|
152
|
+
*/
|
|
153
|
+
export declare const DELEGATED_GATE_HARNESSES: ReadonlySet<HarnessTypeT>;
|
|
154
|
+
/**
|
|
155
|
+
* Harnesses whose blocking gate runs OUT OF PROCESS, in an Intutic-operated
|
|
156
|
+
* service reacting to the harness's own async approval/event API — not a
|
|
157
|
+
* file this daemon writes, and not an SDK imported into the harness's own
|
|
158
|
+
* process (no process of ours runs inside the harness at all). Mirrors the
|
|
159
|
+
* `file: null` NO_GATE row for `trueforge-server` in `gateRegistry.ts`.
|
|
160
|
+
*
|
|
161
|
+
* TRUEFORGE_SERVER (B3) is the first member: a TrueForge standalone/hosted
|
|
162
|
+
* server has no in-process host to hang an SDK gate off of (contrast
|
|
163
|
+
* TRUEFORGE, embedded mode, in `SDK_GATED_HARNESSES` above) — instead
|
|
164
|
+
* `services/trueforge-bridge` watches its turn/event stream externally and
|
|
165
|
+
* answers pending `tool.approval_required` pauses over HTTP. See the
|
|
166
|
+
* `'bridge'` `GateKind` doc above for the full distinction from `'sdk'` and
|
|
167
|
+
* `'delegated'`.
|
|
168
|
+
*/
|
|
169
|
+
export declare const BRIDGE_GATED_HARNESSES: ReadonlySet<HarnessTypeT>;
|
|
170
|
+
/** How this harness's tool calls get gated. Defaults to `'hook'`. */
|
|
171
|
+
export declare function gateKindForHarness(type: HarnessTypeT): GateKind;
|
|
172
|
+
//# sourceMappingURL=gateKind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateKind.d.ts","sourceRoot":"","sources":["../src/gateKind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EAAe,KAAK,WAAW,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,YAAY,CAkBxD,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAKtD,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,YAAY,CAO7D,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,YAAY,CAA2C,CAAA;AAExG,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,QAAQ,CAM/D"}
|
package/dist/gateKind.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* gateKind.ts — classifies each harness by HOW its tool calls get governed:
|
|
4
|
+
* for the sync daemon's agent report (`agentReporter.ts`'s `guardrails`
|
|
5
|
+
* facet) and AI inventory, and for the control plane's silent-gate check,
|
|
6
|
+
* which expects a gate only from a harness that has one of its own.
|
|
7
|
+
*
|
|
8
|
+
* # Why this exists
|
|
9
|
+
*
|
|
10
|
+
* `collectAgentReport` used to report `hook_gate: true` unconditionally for
|
|
11
|
+
* every harness, with the comment "the daemon writes the hook gate for every
|
|
12
|
+
* harness it supports." That was already false for `langgraph` — which has
|
|
13
|
+
* no on-disk hook, only the SDK-side `intutic_clawde.gate` — and for `aider`,
|
|
14
|
+
* whose only NO_GATE-registered mechanism is a post-edit, /run-blind
|
|
15
|
+
* pre-commit hook (see `aiderConfigMerger.ts`'s NO_GATE row in
|
|
16
|
+
* `__tests__/harness/gateRegistry.ts`). Wave 1 adds eight more SDK-gated
|
|
17
|
+
* harnesses, which would have made the lie eight times larger without this
|
|
18
|
+
* fix.
|
|
19
|
+
*
|
|
20
|
+
* # What this does NOT do
|
|
21
|
+
*
|
|
22
|
+
* This does not verify that a user actually pip-installed `intutic-clawde`
|
|
23
|
+
* and wired `guard_tools`/`IntuticMiddleware`/etc. into their process — the
|
|
24
|
+
* daemon cannot observe another process's imports, the same way it cannot
|
|
25
|
+
* observe whether a written hook file was left executable. It only reports
|
|
26
|
+
* which MECHANISM this harness's governance model uses (a file the daemon
|
|
27
|
+
* itself writes and can verify existence of, vs. an SDK the harness's own
|
|
28
|
+
* process must import), matching the trust level `hook_gate: true` already
|
|
29
|
+
* carried for file-based harnesses before this fix.
|
|
30
|
+
*
|
|
31
|
+
* # Keeping this in sync with the gate registry
|
|
32
|
+
*
|
|
33
|
+
* `services/sync-daemon/__tests__/harness/gateRegistry.ts` (the GATES/NO_GATE
|
|
34
|
+
* completeness registry exercised by `generatedGateBehaviour.test.ts`) is the
|
|
35
|
+
* authoritative decision per harness, but it is a test-only module (it
|
|
36
|
+
* dynamically imports every writer's compiled `.js` from a temp build dir)
|
|
37
|
+
* and must not be imported from daemon runtime code. `services/sync-daemon/__tests__/harness/gateKind.test.ts`
|
|
38
|
+
* cross-checks the two lists so this file cannot silently drift from that
|
|
39
|
+
* registry's own NO_GATE rows: `file: null` harnesses split between 'sdk'
|
|
40
|
+
* (LangGraph + the Python frameworks — the gate ships in intutic-clawde),
|
|
41
|
+
* 'delegated' (xirp — the gate is whichever wrapped harness's own gate is
|
|
42
|
+
* running), and 'bridge' (trueforge-server — the gate runs in a separate
|
|
43
|
+
* Intutic-operated service, not in any process this repo's writers touch),
|
|
44
|
+
* and 'none' (roo-code, claude-desktop — no hook system); the one non-null
|
|
45
|
+
* row (aiderConfigMerger.ts, "no ... exists") is 'none' too.
|
|
46
|
+
*
|
|
47
|
+
* @module
|
|
48
|
+
*/
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.BRIDGE_GATED_HARNESSES = exports.DELEGATED_GATE_HARNESSES = exports.NO_GATE_HARNESSES = exports.SDK_GATED_HARNESSES = void 0;
|
|
51
|
+
exports.gateKindForHarness = gateKindForHarness;
|
|
52
|
+
const enums_js_1 = require("./enums.js");
|
|
53
|
+
/**
|
|
54
|
+
* Harnesses whose blocking gate ships SDK-side, in the harness's own
|
|
55
|
+
* process — no on-disk hook/config file exists to point a gate at. Mirrors
|
|
56
|
+
* the `file: null` NO_GATE rows in `gateRegistry.ts`.
|
|
57
|
+
*
|
|
58
|
+
* MASTRA, VERCEL_AI_SDK (T2), EVE (A2), and TRUEFORGE (embedded-library mode
|
|
59
|
+
* only — see its own HarnessType doc) are the JS/TS-native members of this
|
|
60
|
+
* family: their blocking gate ships in `@intutic/gate/mastra`/
|
|
61
|
+
* `@intutic/gate/vercel`/`@intutic/gate/eve`/`@intutic/gate/trueforge`
|
|
62
|
+
* (packages/gate-js) rather than `intutic-clawde`, but the shape is
|
|
63
|
+
* identical — no on-disk hook/config file, tools run as plain callables in
|
|
64
|
+
* the harness's own process (for eve, as per-tool/per-connection `approval`
|
|
65
|
+
* policies attached in the agent directory's own TypeScript; for TrueForge,
|
|
66
|
+
* as `intuticApprovalResponder()` answering `tool.approval_required`
|
|
67
|
+
* pauses — see `@intutic/gate/trueforge`'s module doc for why that shape
|
|
68
|
+
* differs from mastra/vercel's single-callback pattern).
|
|
69
|
+
*
|
|
70
|
+
* AI_SDK_HARNESS and AI_SDK_WORKFLOW (A3) are the same `@intutic/gate`
|
|
71
|
+
* family with one nuance worth naming: the VETO still runs SDK-side in the
|
|
72
|
+
* caller's own Node.js process (an approval responder / a `needsApproval`
|
|
73
|
+
* function), which is what `'sdk'` classifies — but for AI_SDK_HARNESS the
|
|
74
|
+
* tool EXECUTION it vetoes happens server-side in a Vercel Sandbox microVM,
|
|
75
|
+
* and its built-in sandbox tools have no veto surface at all beyond
|
|
76
|
+
* `permissionMode` (defaults to 'allow-all'). `'sdk'` describes where the
|
|
77
|
+
* gate mechanism lives, not a claim that every tool the harness can run
|
|
78
|
+
* passes through it — see gateRegistry.ts's NO_GATE rows for the honest
|
|
79
|
+
* scope statement per harness.
|
|
80
|
+
*/
|
|
81
|
+
exports.SDK_GATED_HARNESSES = new Set([
|
|
82
|
+
enums_js_1.HarnessType.LANGGRAPH,
|
|
83
|
+
enums_js_1.HarnessType.LANGCHAIN,
|
|
84
|
+
enums_js_1.HarnessType.CREWAI,
|
|
85
|
+
enums_js_1.HarnessType.AUTOGEN,
|
|
86
|
+
enums_js_1.HarnessType.AG2,
|
|
87
|
+
enums_js_1.HarnessType.GOOGLE_ADK,
|
|
88
|
+
enums_js_1.HarnessType.OPENAI_AGENTS,
|
|
89
|
+
enums_js_1.HarnessType.PYDANTIC_AI,
|
|
90
|
+
enums_js_1.HarnessType.SMOLAGENTS,
|
|
91
|
+
enums_js_1.HarnessType.STRANDS,
|
|
92
|
+
enums_js_1.HarnessType.AGENT_FRAMEWORK,
|
|
93
|
+
enums_js_1.HarnessType.MASTRA,
|
|
94
|
+
enums_js_1.HarnessType.VERCEL_AI_SDK,
|
|
95
|
+
enums_js_1.HarnessType.EVE,
|
|
96
|
+
enums_js_1.HarnessType.TRUEFORGE,
|
|
97
|
+
enums_js_1.HarnessType.AI_SDK_HARNESS,
|
|
98
|
+
enums_js_1.HarnessType.AI_SDK_WORKFLOW,
|
|
99
|
+
]);
|
|
100
|
+
/**
|
|
101
|
+
* Harnesses with no tool-call gate of their own: the proxy and the MCP
|
|
102
|
+
* governance proxy are their enforcement. Mirrors the NO_GATE rows in
|
|
103
|
+
* `gateRegistry.ts`: aider's only native hook (`--git-commit-verify`) is
|
|
104
|
+
* opt-in, post-edit, and blind to `/run`; Roo Code and Claude Desktop have no
|
|
105
|
+
* hook system at all (Claude Desktop's Code tab is Claude Code, gated by the
|
|
106
|
+
* claude-code gate); Continue's CLI loads PreToolUse hooks but never fires
|
|
107
|
+
* them, and its IDE extension has none (see the continueConfigMerger.ts row).
|
|
108
|
+
*/
|
|
109
|
+
exports.NO_GATE_HARNESSES = new Set([
|
|
110
|
+
enums_js_1.HarnessType.AIDER,
|
|
111
|
+
enums_js_1.HarnessType.ROO_CODE,
|
|
112
|
+
enums_js_1.HarnessType.CLAUDE_DESKTOP,
|
|
113
|
+
enums_js_1.HarnessType.CONTINUE,
|
|
114
|
+
]);
|
|
115
|
+
/**
|
|
116
|
+
* Harnesses that wrap OTHER already-gated harnesses instead of running tools
|
|
117
|
+
* themselves — no gate of their own, but not ungoverned either. Mirrors the
|
|
118
|
+
* `file: null` NO_GATE rows for `xirp` and `agentic-orchestrator` in
|
|
119
|
+
* `gateRegistry.ts`. Xirp was the first entry of this shape; Agentic
|
|
120
|
+
* Orchestrator (O3) is the second. O2 (QM) is expected to add a third, same
|
|
121
|
+
* "wraps other harnesses" shape, in a concurrent phase not yet merged as of
|
|
122
|
+
* this one.
|
|
123
|
+
*/
|
|
124
|
+
exports.DELEGATED_GATE_HARNESSES = new Set([
|
|
125
|
+
enums_js_1.HarnessType.XIRP,
|
|
126
|
+
enums_js_1.HarnessType.AGENTIC_ORCHESTRATOR,
|
|
127
|
+
// B2: AWS Bedrock AgentCore Runtime — hosts a customer's own framework
|
|
128
|
+
// code unchanged; governed by whichever already-supported framework
|
|
129
|
+
// adapter that code uses. See tools/cli/src/harness/agentcore.ts.
|
|
130
|
+
enums_js_1.HarnessType.AGENTCORE_RUNTIME,
|
|
131
|
+
]);
|
|
132
|
+
/**
|
|
133
|
+
* Harnesses whose blocking gate runs OUT OF PROCESS, in an Intutic-operated
|
|
134
|
+
* service reacting to the harness's own async approval/event API — not a
|
|
135
|
+
* file this daemon writes, and not an SDK imported into the harness's own
|
|
136
|
+
* process (no process of ours runs inside the harness at all). Mirrors the
|
|
137
|
+
* `file: null` NO_GATE row for `trueforge-server` in `gateRegistry.ts`.
|
|
138
|
+
*
|
|
139
|
+
* TRUEFORGE_SERVER (B3) is the first member: a TrueForge standalone/hosted
|
|
140
|
+
* server has no in-process host to hang an SDK gate off of (contrast
|
|
141
|
+
* TRUEFORGE, embedded mode, in `SDK_GATED_HARNESSES` above) — instead
|
|
142
|
+
* `services/trueforge-bridge` watches its turn/event stream externally and
|
|
143
|
+
* answers pending `tool.approval_required` pauses over HTTP. See the
|
|
144
|
+
* `'bridge'` `GateKind` doc above for the full distinction from `'sdk'` and
|
|
145
|
+
* `'delegated'`.
|
|
146
|
+
*/
|
|
147
|
+
exports.BRIDGE_GATED_HARNESSES = new Set([enums_js_1.HarnessType.TRUEFORGE_SERVER]);
|
|
148
|
+
/** How this harness's tool calls get gated. Defaults to `'hook'`. */
|
|
149
|
+
function gateKindForHarness(type) {
|
|
150
|
+
if (exports.SDK_GATED_HARNESSES.has(type))
|
|
151
|
+
return 'sdk';
|
|
152
|
+
if (exports.NO_GATE_HARNESSES.has(type))
|
|
153
|
+
return 'none';
|
|
154
|
+
if (exports.DELEGATED_GATE_HARNESSES.has(type))
|
|
155
|
+
return 'delegated';
|
|
156
|
+
if (exports.BRIDGE_GATED_HARNESSES.has(type))
|
|
157
|
+
return 'bridge';
|
|
158
|
+
return 'hook';
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=gateKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateKind.js","sourceRoot":"","sources":["../src/gateKind.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;;;AAiKH,gDAMC;AArKD,yCAA0E;AA2D1E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACU,QAAA,mBAAmB,GAA8B,IAAI,GAAG,CAAC;IACpE,sBAAW,CAAC,SAAS;IACrB,sBAAW,CAAC,SAAS;IACrB,sBAAW,CAAC,MAAM;IAClB,sBAAW,CAAC,OAAO;IACnB,sBAAW,CAAC,GAAG;IACf,sBAAW,CAAC,UAAU;IACtB,sBAAW,CAAC,aAAa;IACzB,sBAAW,CAAC,WAAW;IACvB,sBAAW,CAAC,UAAU;IACtB,sBAAW,CAAC,OAAO;IACnB,sBAAW,CAAC,eAAe;IAC3B,sBAAW,CAAC,MAAM;IAClB,sBAAW,CAAC,aAAa;IACzB,sBAAW,CAAC,GAAG;IACf,sBAAW,CAAC,SAAS;IACrB,sBAAW,CAAC,cAAc;IAC1B,sBAAW,CAAC,eAAe;CAC5B,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACU,QAAA,iBAAiB,GAA8B,IAAI,GAAG,CAAC;IAClE,sBAAW,CAAC,KAAK;IACjB,sBAAW,CAAC,QAAQ;IACpB,sBAAW,CAAC,cAAc;IAC1B,sBAAW,CAAC,QAAQ;CACrB,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACU,QAAA,wBAAwB,GAA8B,IAAI,GAAG,CAAC;IACzE,sBAAW,CAAC,IAAI;IAChB,sBAAW,CAAC,oBAAoB;IAChC,uEAAuE;IACvE,oEAAoE;IACpE,kEAAkE;IAClE,sBAAW,CAAC,iBAAiB;CAC9B,CAAC,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACU,QAAA,sBAAsB,GAA8B,IAAI,GAAG,CAAC,CAAC,sBAAW,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAExG,qEAAqE;AACrE,SAAgB,kBAAkB,CAAC,IAAkB;IACnD,IAAI,2BAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAC/C,IAAI,yBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAA;IAC9C,IAAI,gCAAwB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAA;IAC1D,IAAI,8BAAsB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAA;IACrD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How much a gate will evaluate, and for how long, before it refuses.
|
|
3
|
+
*
|
|
4
|
+
* Most harnesses treat a hook that runs past its timeout as having allowed
|
|
5
|
+
* the call (see {@link HOOK_GATE_TIMEOUTS}), so a gate that is slow on a
|
|
6
|
+
* crafted call is no gate. Two bounds keep every gate inside its harness's
|
|
7
|
+
* timeout:
|
|
8
|
+
*
|
|
9
|
+
* - **Size.** A command over {@link COMMAND_SIZE_LIMIT} bytes, or tool
|
|
10
|
+
* arguments over {@link ARGUMENTS_SIZE_LIMIT} bytes (serialized as compact
|
|
11
|
+
* JSON), are refused as `COMMAND_TOO_LARGE` before any rule runs. The limits
|
|
12
|
+
* come from 85,314 tool calls in real coding-agent transcripts: the largest
|
|
13
|
+
* shell command was 38.5 KB (99.9th percentile 13 KB), the largest file
|
|
14
|
+
* write 120 KB, the largest arguments of any tool 418 KB (a plan). So the
|
|
15
|
+
* command limit is six times the largest seen and the arguments limit more
|
|
16
|
+
* than twice.
|
|
17
|
+
* - **Time.** Each hook gate stops at {@link gateDeadlineMs} for its harness
|
|
18
|
+
* after it starts and refuses with a `GATE_DEADLINE` reason. Every built-in
|
|
19
|
+
* rule is linear in the text (sequence.ts, the phrase matcher,
|
|
20
|
+
* regexLinearity.ts in the sync daemon), so only a workspace's own WHERE
|
|
21
|
+
* patterns can get there.
|
|
22
|
+
*
|
|
23
|
+
* Sizes are UTF-8 bytes, which every gate can count the same way.
|
|
24
|
+
*
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
/** The largest shell command, in UTF-8 bytes, a gate evaluates. */
|
|
28
|
+
export declare const COMMAND_SIZE_LIMIT: number;
|
|
29
|
+
/** The largest tool arguments, in UTF-8 bytes of compact JSON, a gate evaluates. */
|
|
30
|
+
export declare const ARGUMENTS_SIZE_LIMIT: number;
|
|
31
|
+
/**
|
|
32
|
+
* The timeout `intutic connect` sets on a gate's hook entry, in seconds,
|
|
33
|
+
* wherever the harness has a key for one. Harness defaults run from 30 s to
|
|
34
|
+
* 600 s; 10 s keeps a stalled gate from holding the agent for minutes, and is
|
|
35
|
+
* also the longest any gate runs where the harness sets no limit at all.
|
|
36
|
+
*/
|
|
37
|
+
export declare const HOOK_TIMEOUT_SECONDS = 10;
|
|
38
|
+
/**
|
|
39
|
+
* How far below its harness's hook timeout a gate refuses.
|
|
40
|
+
*
|
|
41
|
+
* The harness starts its clock when it spawns the hook; the gate starts its
|
|
42
|
+
* own once its interpreter is running (Node's `process.uptime()`, the bash
|
|
43
|
+
* gate's watchdog), and once its deadline fires it still has to stop its
|
|
44
|
+
* children, write the refusal and the audit line, and exit, and the harness
|
|
45
|
+
* has to read the exit. On a 14-core machine running every package's test
|
|
46
|
+
* suite beside 100 busy threads (load average near 190), a gate's refusal
|
|
47
|
+
* reached the harness at most 260 ms after its deadline, Node and bash alike.
|
|
48
|
+
* One second is nearly four times that.
|
|
49
|
+
*/
|
|
50
|
+
export declare const GATE_DEADLINE_MARGIN_MS = 1000;
|
|
51
|
+
/** Who decides the timeout a harness applies to its gate. */
|
|
52
|
+
export type HookTimeoutSetBy =
|
|
53
|
+
/** `intutic connect` writes it into the hook entry. */
|
|
54
|
+
'connect'
|
|
55
|
+
/** The harness's own value, which no setting changes. */
|
|
56
|
+
| 'harness'
|
|
57
|
+
/** The harness documents none, so the gate assumes the shortest default of any documented harness that runs a call whose hook timed out: Grok Build's 5 s. */
|
|
58
|
+
| 'undocumented'
|
|
59
|
+
/** The gate runs in the harness's process, which waits for it without a limit. */
|
|
60
|
+
| 'none';
|
|
61
|
+
/** The timeout a harness applies to its hook gate. */
|
|
62
|
+
export interface HookGateTimeout {
|
|
63
|
+
/** In milliseconds; null when the harness waits without a limit. */
|
|
64
|
+
readonly timeoutMs: number | null;
|
|
65
|
+
readonly setBy: HookTimeoutSetBy;
|
|
66
|
+
/** Where the value comes from. */
|
|
67
|
+
readonly source: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The hook timeout each harness applies to its gate, keyed by the harness id
|
|
71
|
+
* the gate is emitted for. The one source every gate's deadline is derived
|
|
72
|
+
* from: the writers set the timeouts marked `connect` from here, and a test
|
|
73
|
+
* reads each written hook entry back against it.
|
|
74
|
+
*/
|
|
75
|
+
export declare const HOOK_GATE_TIMEOUTS: {
|
|
76
|
+
readonly 'claude-code': {
|
|
77
|
+
readonly timeoutMs: number;
|
|
78
|
+
readonly setBy: "connect";
|
|
79
|
+
readonly source: "`timeout` (seconds) on the hook entry in .claude/settings.json; default 600 s, a call whose hook times out runs (code.claude.com/docs/en/hooks)";
|
|
80
|
+
};
|
|
81
|
+
readonly cursor: {
|
|
82
|
+
readonly timeoutMs: number;
|
|
83
|
+
readonly setBy: "connect";
|
|
84
|
+
readonly source: "`timeout` (seconds) on the hooks.json entry, beside `failClosed: true`; default not stated (cursor.com/docs/agent/hooks)";
|
|
85
|
+
};
|
|
86
|
+
readonly windsurf: {
|
|
87
|
+
readonly timeoutMs: 5000;
|
|
88
|
+
readonly setBy: "undocumented";
|
|
89
|
+
readonly source: "hooks.json entries have no timeout key and Windsurf documents no timeout; any exit but 2 runs the call (docs.devin.ai/desktop/cascade/hooks)";
|
|
90
|
+
};
|
|
91
|
+
readonly codex: {
|
|
92
|
+
readonly timeoutMs: number;
|
|
93
|
+
readonly setBy: "connect";
|
|
94
|
+
readonly source: "`timeout` (seconds) on the hooks.json entry; default 600 s (Codex hooks documentation)";
|
|
95
|
+
};
|
|
96
|
+
readonly 'muse-code': {
|
|
97
|
+
readonly timeoutMs: 5000;
|
|
98
|
+
readonly setBy: "undocumented";
|
|
99
|
+
readonly source: "Muse Code documents no hook timeout and no key for one (dev.meta.ai/docs/muse-code)";
|
|
100
|
+
};
|
|
101
|
+
readonly 'github-copilot': {
|
|
102
|
+
readonly timeoutMs: number;
|
|
103
|
+
readonly setBy: "connect";
|
|
104
|
+
readonly source: "`timeout` (seconds) on the hook entry, the Copilot CLI's alias for `timeoutSec` and VS Code's key; default 30 s, a call whose hook times out runs (docs.github.com/en/copilot/reference/hooks-configuration)";
|
|
105
|
+
};
|
|
106
|
+
readonly cline: {
|
|
107
|
+
readonly timeoutMs: 30000;
|
|
108
|
+
readonly setBy: "harness";
|
|
109
|
+
readonly source: "HOOK_EXECUTION_TIMEOUT_MS = 30000 in Cline's hook-factory.ts, not configurable; a call whose hook times out runs";
|
|
110
|
+
};
|
|
111
|
+
readonly grok: {
|
|
112
|
+
readonly timeoutMs: number;
|
|
113
|
+
readonly setBy: "connect";
|
|
114
|
+
readonly source: "`timeout` (seconds) on the hook entry; default 5 s, no stated maximum, a call whose hook times out runs (docs.x.ai/build/features/hooks)";
|
|
115
|
+
};
|
|
116
|
+
readonly antigravity: {
|
|
117
|
+
readonly timeoutMs: number;
|
|
118
|
+
readonly setBy: "connect";
|
|
119
|
+
readonly source: "`timeout` (seconds) on the PreToolUse handler in ~/.gemini/config/hooks.json; default 30 s (antigravity.google/docs/hooks)";
|
|
120
|
+
};
|
|
121
|
+
readonly 'gemini-cli': {
|
|
122
|
+
readonly timeoutMs: number;
|
|
123
|
+
readonly setBy: "connect";
|
|
124
|
+
readonly source: "`timeout` (milliseconds) on the BeforeTool hook in ~/.gemini/settings.json; default 60 000 (geminicli.com/docs/hooks/reference)";
|
|
125
|
+
};
|
|
126
|
+
readonly goose: {
|
|
127
|
+
readonly timeoutMs: number;
|
|
128
|
+
readonly setBy: "connect";
|
|
129
|
+
readonly source: "`timeout` (seconds) beside `on_failure: \"block\"` in the plugin's hooks.json; default 30 s (goose hooks guide)";
|
|
130
|
+
};
|
|
131
|
+
readonly openhands: {
|
|
132
|
+
readonly timeoutMs: number;
|
|
133
|
+
readonly setBy: "connect";
|
|
134
|
+
readonly source: "`timeout` (seconds) in .openhands/hooks.json; default 60 s, a call whose hook times out runs (openhands-sdk hooks/config.py)";
|
|
135
|
+
};
|
|
136
|
+
readonly hermes: {
|
|
137
|
+
readonly timeoutMs: number;
|
|
138
|
+
readonly setBy: "connect";
|
|
139
|
+
readonly source: "`timeout` (seconds) beside `fail_closed: true` in ~/.hermes/config.yaml; default 60 s, at most 300 s (hermes-agent shell_hooks.py)";
|
|
140
|
+
};
|
|
141
|
+
readonly openclaw: {
|
|
142
|
+
readonly timeoutMs: number;
|
|
143
|
+
readonly setBy: "connect";
|
|
144
|
+
readonly source: "`timeoutMs` on the before_tool_call registration; default 15 s, a timeout blocks the call but cannot interrupt the handler (OpenClaw docs/plugins/hooks/reference.md)";
|
|
145
|
+
};
|
|
146
|
+
readonly pi: {
|
|
147
|
+
readonly timeoutMs: null;
|
|
148
|
+
readonly setBy: "none";
|
|
149
|
+
readonly source: "Pi awaits an extension's tool_call handler without a limit (core/extensions/runner.ts)";
|
|
150
|
+
};
|
|
151
|
+
readonly opencode: {
|
|
152
|
+
readonly timeoutMs: null;
|
|
153
|
+
readonly setBy: "none";
|
|
154
|
+
readonly source: "OpenCode awaits a plugin's tool.execute.before without a limit (packages/opencode/src/plugin/index.ts)";
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
/** A harness that runs a hook gate. */
|
|
158
|
+
export type HookGateHarness = keyof typeof HOOK_GATE_TIMEOUTS;
|
|
159
|
+
/**
|
|
160
|
+
* How long a harness's hook gate may decide, from its start, before it
|
|
161
|
+
* refuses with `GATE_DEADLINE`: {@link GATE_DEADLINE_MARGIN_MS} under the
|
|
162
|
+
* harness's timeout, and never longer than {@link HOOK_TIMEOUT_SECONDS} minus
|
|
163
|
+
* that margin, so a gate the harness waits on for 30 s or without limit still
|
|
164
|
+
* answers as promptly as one connect set a timeout for. On the loaded machine
|
|
165
|
+
* above, a call at the size limits took the bash gates at most 4.6 s and the
|
|
166
|
+
* JavaScript gates at most 1.2 s; every 4 s deadline is a JavaScript gate's.
|
|
167
|
+
* Only a workspace's own pathological WHERE pattern runs this long.
|
|
168
|
+
*/
|
|
169
|
+
export declare function gateDeadlineMs(harness: HookGateHarness): number;
|
|
170
|
+
//# sourceMappingURL=gateLimits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateLimits.d.ts","sourceRoot":"","sources":["../src/gateLimits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,QAAa,CAAA;AAE5C,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,QAAc,CAAA;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAE3C,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB;AAC1B,uDAAuD;AACrD,SAAS;AACX,yDAAyD;GACvD,SAAS;AACX,8JAA8J;GAC5J,cAAc;AAChB,kFAAkF;GAChF,MAAM,CAAA;AAEV,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;IAChC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAMD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBqB,CAAA;AAEpD,uCAAuC;AACvC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,kBAAkB,CAAA;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAG/D"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* How much a gate will evaluate, and for how long, before it refuses.
|
|
4
|
+
*
|
|
5
|
+
* Most harnesses treat a hook that runs past its timeout as having allowed
|
|
6
|
+
* the call (see {@link HOOK_GATE_TIMEOUTS}), so a gate that is slow on a
|
|
7
|
+
* crafted call is no gate. Two bounds keep every gate inside its harness's
|
|
8
|
+
* timeout:
|
|
9
|
+
*
|
|
10
|
+
* - **Size.** A command over {@link COMMAND_SIZE_LIMIT} bytes, or tool
|
|
11
|
+
* arguments over {@link ARGUMENTS_SIZE_LIMIT} bytes (serialized as compact
|
|
12
|
+
* JSON), are refused as `COMMAND_TOO_LARGE` before any rule runs. The limits
|
|
13
|
+
* come from 85,314 tool calls in real coding-agent transcripts: the largest
|
|
14
|
+
* shell command was 38.5 KB (99.9th percentile 13 KB), the largest file
|
|
15
|
+
* write 120 KB, the largest arguments of any tool 418 KB (a plan). So the
|
|
16
|
+
* command limit is six times the largest seen and the arguments limit more
|
|
17
|
+
* than twice.
|
|
18
|
+
* - **Time.** Each hook gate stops at {@link gateDeadlineMs} for its harness
|
|
19
|
+
* after it starts and refuses with a `GATE_DEADLINE` reason. Every built-in
|
|
20
|
+
* rule is linear in the text (sequence.ts, the phrase matcher,
|
|
21
|
+
* regexLinearity.ts in the sync daemon), so only a workspace's own WHERE
|
|
22
|
+
* patterns can get there.
|
|
23
|
+
*
|
|
24
|
+
* Sizes are UTF-8 bytes, which every gate can count the same way.
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.HOOK_GATE_TIMEOUTS = exports.GATE_DEADLINE_MARGIN_MS = exports.HOOK_TIMEOUT_SECONDS = exports.ARGUMENTS_SIZE_LIMIT = exports.COMMAND_SIZE_LIMIT = void 0;
|
|
30
|
+
exports.gateDeadlineMs = gateDeadlineMs;
|
|
31
|
+
/** The largest shell command, in UTF-8 bytes, a gate evaluates. */
|
|
32
|
+
exports.COMMAND_SIZE_LIMIT = 256 * 1024;
|
|
33
|
+
/** The largest tool arguments, in UTF-8 bytes of compact JSON, a gate evaluates. */
|
|
34
|
+
exports.ARGUMENTS_SIZE_LIMIT = 1024 * 1024;
|
|
35
|
+
/**
|
|
36
|
+
* The timeout `intutic connect` sets on a gate's hook entry, in seconds,
|
|
37
|
+
* wherever the harness has a key for one. Harness defaults run from 30 s to
|
|
38
|
+
* 600 s; 10 s keeps a stalled gate from holding the agent for minutes, and is
|
|
39
|
+
* also the longest any gate runs where the harness sets no limit at all.
|
|
40
|
+
*/
|
|
41
|
+
exports.HOOK_TIMEOUT_SECONDS = 10;
|
|
42
|
+
/**
|
|
43
|
+
* How far below its harness's hook timeout a gate refuses.
|
|
44
|
+
*
|
|
45
|
+
* The harness starts its clock when it spawns the hook; the gate starts its
|
|
46
|
+
* own once its interpreter is running (Node's `process.uptime()`, the bash
|
|
47
|
+
* gate's watchdog), and once its deadline fires it still has to stop its
|
|
48
|
+
* children, write the refusal and the audit line, and exit, and the harness
|
|
49
|
+
* has to read the exit. On a 14-core machine running every package's test
|
|
50
|
+
* suite beside 100 busy threads (load average near 190), a gate's refusal
|
|
51
|
+
* reached the harness at most 260 ms after its deadline, Node and bash alike.
|
|
52
|
+
* One second is nearly four times that.
|
|
53
|
+
*/
|
|
54
|
+
exports.GATE_DEADLINE_MARGIN_MS = 1000;
|
|
55
|
+
const CONNECT_MS = exports.HOOK_TIMEOUT_SECONDS * 1000;
|
|
56
|
+
/** Grok Build's default hook timeout, the shortest any documented harness uses; assumed where a harness documents none. */
|
|
57
|
+
const UNDOCUMENTED_ASSUMED_MS = 5000;
|
|
58
|
+
/**
|
|
59
|
+
* The hook timeout each harness applies to its gate, keyed by the harness id
|
|
60
|
+
* the gate is emitted for. The one source every gate's deadline is derived
|
|
61
|
+
* from: the writers set the timeouts marked `connect` from here, and a test
|
|
62
|
+
* reads each written hook entry back against it.
|
|
63
|
+
*/
|
|
64
|
+
exports.HOOK_GATE_TIMEOUTS = {
|
|
65
|
+
'claude-code': { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hook entry in .claude/settings.json; default 600 s, a call whose hook times out runs (code.claude.com/docs/en/hooks)' },
|
|
66
|
+
cursor: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hooks.json entry, beside `failClosed: true`; default not stated (cursor.com/docs/agent/hooks)' },
|
|
67
|
+
windsurf: { timeoutMs: UNDOCUMENTED_ASSUMED_MS, setBy: 'undocumented', source: 'hooks.json entries have no timeout key and Windsurf documents no timeout; any exit but 2 runs the call (docs.devin.ai/desktop/cascade/hooks)' },
|
|
68
|
+
codex: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hooks.json entry; default 600 s (Codex hooks documentation)' },
|
|
69
|
+
'muse-code': { timeoutMs: UNDOCUMENTED_ASSUMED_MS, setBy: 'undocumented', source: 'Muse Code documents no hook timeout and no key for one (dev.meta.ai/docs/muse-code)' },
|
|
70
|
+
'github-copilot': { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hook entry, the Copilot CLI\'s alias for `timeoutSec` and VS Code\'s key; default 30 s, a call whose hook times out runs (docs.github.com/en/copilot/reference/hooks-configuration)' },
|
|
71
|
+
cline: { timeoutMs: 30_000, setBy: 'harness', source: 'HOOK_EXECUTION_TIMEOUT_MS = 30000 in Cline\'s hook-factory.ts, not configurable; a call whose hook times out runs' },
|
|
72
|
+
grok: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hook entry; default 5 s, no stated maximum, a call whose hook times out runs (docs.x.ai/build/features/hooks)' },
|
|
73
|
+
antigravity: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the PreToolUse handler in ~/.gemini/config/hooks.json; default 30 s (antigravity.google/docs/hooks)' },
|
|
74
|
+
'gemini-cli': { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (milliseconds) on the BeforeTool hook in ~/.gemini/settings.json; default 60 000 (geminicli.com/docs/hooks/reference)' },
|
|
75
|
+
goose: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) beside `on_failure: "block"` in the plugin\'s hooks.json; default 30 s (goose hooks guide)' },
|
|
76
|
+
openhands: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) in .openhands/hooks.json; default 60 s, a call whose hook times out runs (openhands-sdk hooks/config.py)' },
|
|
77
|
+
hermes: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) beside `fail_closed: true` in ~/.hermes/config.yaml; default 60 s, at most 300 s (hermes-agent shell_hooks.py)' },
|
|
78
|
+
openclaw: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeoutMs` on the before_tool_call registration; default 15 s, a timeout blocks the call but cannot interrupt the handler (OpenClaw docs/plugins/hooks/reference.md)' },
|
|
79
|
+
pi: { timeoutMs: null, setBy: 'none', source: 'Pi awaits an extension\'s tool_call handler without a limit (core/extensions/runner.ts)' },
|
|
80
|
+
opencode: { timeoutMs: null, setBy: 'none', source: 'OpenCode awaits a plugin\'s tool.execute.before without a limit (packages/opencode/src/plugin/index.ts)' },
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* How long a harness's hook gate may decide, from its start, before it
|
|
84
|
+
* refuses with `GATE_DEADLINE`: {@link GATE_DEADLINE_MARGIN_MS} under the
|
|
85
|
+
* harness's timeout, and never longer than {@link HOOK_TIMEOUT_SECONDS} minus
|
|
86
|
+
* that margin, so a gate the harness waits on for 30 s or without limit still
|
|
87
|
+
* answers as promptly as one connect set a timeout for. On the loaded machine
|
|
88
|
+
* above, a call at the size limits took the bash gates at most 4.6 s and the
|
|
89
|
+
* JavaScript gates at most 1.2 s; every 4 s deadline is a JavaScript gate's.
|
|
90
|
+
* Only a workspace's own pathological WHERE pattern runs this long.
|
|
91
|
+
*/
|
|
92
|
+
function gateDeadlineMs(harness) {
|
|
93
|
+
const timeoutMs = exports.HOOK_GATE_TIMEOUTS[harness].timeoutMs;
|
|
94
|
+
return Math.min(timeoutMs ?? CONNECT_MS, CONNECT_MS) - exports.GATE_DEADLINE_MARGIN_MS;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=gateLimits.js.map
|