@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/dist/client.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the Intutic control plane's gate endpoints.
|
|
3
|
+
*
|
|
4
|
+
* Port of `packages/intutic-clawde/intutic_clawde/gate/client.py`.
|
|
5
|
+
*
|
|
6
|
+
* Endpoints used:
|
|
7
|
+
*
|
|
8
|
+
* POST /api/v1/hook-gate synchronous allow/deny -> {allowed, reason, incidentId?}
|
|
9
|
+
* POST /api/v1/hook-events batched telemetry -> creates governance_incidents rows
|
|
10
|
+
*
|
|
11
|
+
* Two behaviours that must not be "improved":
|
|
12
|
+
*
|
|
13
|
+
* * The hook-gate SERVER fails OPEN on its own error paths — it returns
|
|
14
|
+
* `{allowed:true}` on malformed input, schema mismatch, or DB error,
|
|
15
|
+
* because blocking a developer over a bad payload teaches people to
|
|
16
|
+
* disable the hook. This CLIENT, by contrast, defaults to FAIL-CLOSED
|
|
17
|
+
* (`failClosed=true`) for blocking decisions: a transport error or
|
|
18
|
+
* non-2xx response means we have no verdict at all to defer to, so
|
|
19
|
+
* `hookGate` reports `allowed=false`. Set `failClosed=false` to treat the
|
|
20
|
+
* tier as advisory, mirroring the server's own posture.
|
|
21
|
+
* * `emit` NEVER throws. Telemetry that can break a run is worse than no
|
|
22
|
+
* telemetry.
|
|
23
|
+
*/
|
|
24
|
+
export interface GateResponse {
|
|
25
|
+
allowed: boolean;
|
|
26
|
+
reason: string;
|
|
27
|
+
incidentId?: string | undefined;
|
|
28
|
+
/** False when the call failed and `failClosed` decided the verdict. */
|
|
29
|
+
reached: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface GateClientOptions {
|
|
32
|
+
baseUrl?: string;
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
workspaceId?: string;
|
|
35
|
+
sessionId?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Attributes incidents to the right adapter. Sent as `harnessType` on every
|
|
38
|
+
* gate call and event.
|
|
39
|
+
*/
|
|
40
|
+
harness?: string;
|
|
41
|
+
failClosed?: boolean;
|
|
42
|
+
timeoutMs?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Control-plane client for the pre-execution gate.
|
|
46
|
+
*
|
|
47
|
+
* `harness` defaults to `"generic"` and is sent as `harnessType` on every
|
|
48
|
+
* gate call and event, so incidents attribute to the right adapter. Override
|
|
49
|
+
* it when wrapping a specific framework (`mastra`, `vercel-ai`,
|
|
50
|
+
* `langchainjs`, `dsh`, ...).
|
|
51
|
+
*/
|
|
52
|
+
export declare class GateClient {
|
|
53
|
+
readonly baseUrl: string;
|
|
54
|
+
readonly apiKey: string;
|
|
55
|
+
readonly workspaceId: string;
|
|
56
|
+
readonly sessionId: string;
|
|
57
|
+
readonly harness: string;
|
|
58
|
+
readonly failClosed: boolean;
|
|
59
|
+
readonly timeoutMs: number;
|
|
60
|
+
constructor(opts?: GateClientOptions);
|
|
61
|
+
private post;
|
|
62
|
+
/**
|
|
63
|
+
* Synchronous allow/deny for one tool call.
|
|
64
|
+
*
|
|
65
|
+
* The endpoint matches ~19 DLP regexes against the serialised toolInput,
|
|
66
|
+
* plus SOP rules. It is defence in depth on top of the local tiers, not a
|
|
67
|
+
* replacement for them.
|
|
68
|
+
*
|
|
69
|
+
* When the call itself fails (transport error, non-2xx), the verdict is
|
|
70
|
+
* decided by `failClosed`: true (the default) reports BLOCK, because a
|
|
71
|
+
* client with no verdict has nothing to defer to; false reports allow,
|
|
72
|
+
* mirroring the server's own fail-open error paths.
|
|
73
|
+
*/
|
|
74
|
+
hookGate(toolName: string, toolInput: unknown): Promise<GateResponse>;
|
|
75
|
+
/**
|
|
76
|
+
* Fire-and-forget telemetry. Never throws.
|
|
77
|
+
*
|
|
78
|
+
* A `tool_blocked` event creates a `governance_incidents` row whose
|
|
79
|
+
* description embeds the reason verbatim.
|
|
80
|
+
*/
|
|
81
|
+
emit(event: string, toolName: string, reason?: string, toolInput?: unknown, incidentId?: string, filePath?: string): Promise<boolean>;
|
|
82
|
+
/**
|
|
83
|
+
* Build a client from the environment, falling back to CLI credentials.
|
|
84
|
+
*
|
|
85
|
+
* Reading `~/.intutic/credentials.json` means the gate works with whatever
|
|
86
|
+
* workspace `intutic login` already bound, instead of duplicating the key.
|
|
87
|
+
*/
|
|
88
|
+
static fromEnv(opts?: {
|
|
89
|
+
sessionId?: string;
|
|
90
|
+
harness?: string;
|
|
91
|
+
failClosed?: boolean;
|
|
92
|
+
}): GateClient;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAyBH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;gBAEd,IAAI,GAAE,iBAAsB;YAa1B,IAAI;IAsBlB;;;;;;;;;;;OAWG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;IAoC3E;;;;;OAKG;IACG,IAAI,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,SAAK,EACX,SAAS,CAAC,EAAE,OAAO,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAsBnB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,UAAU;CAoCtG"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the Intutic control plane's gate endpoints.
|
|
3
|
+
*
|
|
4
|
+
* Port of `packages/intutic-clawde/intutic_clawde/gate/client.py`.
|
|
5
|
+
*
|
|
6
|
+
* Endpoints used:
|
|
7
|
+
*
|
|
8
|
+
* POST /api/v1/hook-gate synchronous allow/deny -> {allowed, reason, incidentId?}
|
|
9
|
+
* POST /api/v1/hook-events batched telemetry -> creates governance_incidents rows
|
|
10
|
+
*
|
|
11
|
+
* Two behaviours that must not be "improved":
|
|
12
|
+
*
|
|
13
|
+
* * The hook-gate SERVER fails OPEN on its own error paths — it returns
|
|
14
|
+
* `{allowed:true}` on malformed input, schema mismatch, or DB error,
|
|
15
|
+
* because blocking a developer over a bad payload teaches people to
|
|
16
|
+
* disable the hook. This CLIENT, by contrast, defaults to FAIL-CLOSED
|
|
17
|
+
* (`failClosed=true`) for blocking decisions: a transport error or
|
|
18
|
+
* non-2xx response means we have no verdict at all to defer to, so
|
|
19
|
+
* `hookGate` reports `allowed=false`. Set `failClosed=false` to treat the
|
|
20
|
+
* tier as advisory, mirroring the server's own posture.
|
|
21
|
+
* * `emit` NEVER throws. Telemetry that can break a run is worse than no
|
|
22
|
+
* telemetry.
|
|
23
|
+
*/
|
|
24
|
+
import { readFileSync } from 'node:fs';
|
|
25
|
+
import { homedir } from 'node:os';
|
|
26
|
+
import { join } from 'node:path';
|
|
27
|
+
const DEFAULT_TIMEOUT_MS = 2_000;
|
|
28
|
+
const EVENT_TIMEOUT_MS = 2_000;
|
|
29
|
+
const REASON_MAX = 512; // control plane truncates at 512; do it here so logs match
|
|
30
|
+
// Mirrors HookEventSchema in services/control-plane/src/routes/hookEvents.ts.
|
|
31
|
+
const VALID_EVENTS = new Set([
|
|
32
|
+
'tool_blocked',
|
|
33
|
+
'tool_allowed',
|
|
34
|
+
'tool_flagged',
|
|
35
|
+
'tool_would_block',
|
|
36
|
+
'config_tamper',
|
|
37
|
+
'network_bypass',
|
|
38
|
+
'guards_disabled',
|
|
39
|
+
'snapshot_absent',
|
|
40
|
+
'snapshot_stale',
|
|
41
|
+
'snapshot_invalid',
|
|
42
|
+
'snapshot_empty',
|
|
43
|
+
]);
|
|
44
|
+
/**
|
|
45
|
+
* Control-plane client for the pre-execution gate.
|
|
46
|
+
*
|
|
47
|
+
* `harness` defaults to `"generic"` and is sent as `harnessType` on every
|
|
48
|
+
* gate call and event, so incidents attribute to the right adapter. Override
|
|
49
|
+
* it when wrapping a specific framework (`mastra`, `vercel-ai`,
|
|
50
|
+
* `langchainjs`, `dsh`, ...).
|
|
51
|
+
*/
|
|
52
|
+
export class GateClient {
|
|
53
|
+
baseUrl;
|
|
54
|
+
apiKey;
|
|
55
|
+
workspaceId;
|
|
56
|
+
sessionId;
|
|
57
|
+
harness;
|
|
58
|
+
failClosed;
|
|
59
|
+
timeoutMs;
|
|
60
|
+
constructor(opts = {}) {
|
|
61
|
+
this.baseUrl = (opts.baseUrl || process.env.INTUTIC_CONTROL_PLANE_URL || 'https://api.intutic.ai').replace(/\/$/, '');
|
|
62
|
+
this.apiKey = opts.apiKey ?? '';
|
|
63
|
+
this.workspaceId = opts.workspaceId ?? '';
|
|
64
|
+
this.sessionId = opts.sessionId ?? '';
|
|
65
|
+
this.harness = opts.harness ?? 'generic';
|
|
66
|
+
this.failClosed = opts.failClosed ?? true;
|
|
67
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
68
|
+
}
|
|
69
|
+
async post(path, body, timeoutMs) {
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
72
|
+
try {
|
|
73
|
+
const res = await fetch(this.baseUrl + path, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'application/json',
|
|
77
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
78
|
+
'X-Workspace-Id': this.workspaceId,
|
|
79
|
+
},
|
|
80
|
+
body: JSON.stringify(body),
|
|
81
|
+
signal: controller.signal,
|
|
82
|
+
});
|
|
83
|
+
if (!res.ok)
|
|
84
|
+
throw new Error(`HTTP ${res.status} from ${path}`);
|
|
85
|
+
const text = await res.text();
|
|
86
|
+
return text ? JSON.parse(text) : {};
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Synchronous allow/deny for one tool call.
|
|
94
|
+
*
|
|
95
|
+
* The endpoint matches ~19 DLP regexes against the serialised toolInput,
|
|
96
|
+
* plus SOP rules. It is defence in depth on top of the local tiers, not a
|
|
97
|
+
* replacement for them.
|
|
98
|
+
*
|
|
99
|
+
* When the call itself fails (transport error, non-2xx), the verdict is
|
|
100
|
+
* decided by `failClosed`: true (the default) reports BLOCK, because a
|
|
101
|
+
* client with no verdict has nothing to defer to; false reports allow,
|
|
102
|
+
* mirroring the server's own fail-open error paths.
|
|
103
|
+
*/
|
|
104
|
+
async hookGate(toolName, toolInput) {
|
|
105
|
+
try {
|
|
106
|
+
const d = await this.post('/api/v1/hook-gate', {
|
|
107
|
+
toolName,
|
|
108
|
+
toolInput,
|
|
109
|
+
workspaceId: this.workspaceId,
|
|
110
|
+
sessionId: this.sessionId,
|
|
111
|
+
harnessType: this.harness,
|
|
112
|
+
}, this.timeoutMs);
|
|
113
|
+
return {
|
|
114
|
+
allowed: Boolean(d.allowed ?? true),
|
|
115
|
+
reason: String(d.reason ?? ''),
|
|
116
|
+
incidentId: typeof d.incidentId === 'string' ? d.incidentId : undefined,
|
|
117
|
+
reached: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch (exc) {
|
|
121
|
+
const name = exc instanceof Error ? exc.constructor.name : 'Error';
|
|
122
|
+
if (this.failClosed) {
|
|
123
|
+
return {
|
|
124
|
+
allowed: false,
|
|
125
|
+
reason: `hook-gate unreachable (${name}) — failing closed (failClosed=true)`,
|
|
126
|
+
reached: false,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
allowed: true,
|
|
131
|
+
reason: `hook-gate unreachable (${name}) — failing open (failClosed=false)`,
|
|
132
|
+
reached: false,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Fire-and-forget telemetry. Never throws.
|
|
138
|
+
*
|
|
139
|
+
* A `tool_blocked` event creates a `governance_incidents` row whose
|
|
140
|
+
* description embeds the reason verbatim.
|
|
141
|
+
*/
|
|
142
|
+
async emit(event, toolName, reason = '', toolInput, incidentId, filePath) {
|
|
143
|
+
if (!VALID_EVENTS.has(event))
|
|
144
|
+
return false;
|
|
145
|
+
const ev = {
|
|
146
|
+
event,
|
|
147
|
+
toolName,
|
|
148
|
+
reason: (reason || '').slice(0, REASON_MAX),
|
|
149
|
+
workspaceId: this.workspaceId,
|
|
150
|
+
sessionId: this.sessionId,
|
|
151
|
+
harnessType: this.harness,
|
|
152
|
+
timestamp: new Date().toISOString(),
|
|
153
|
+
};
|
|
154
|
+
if (toolInput !== undefined)
|
|
155
|
+
ev.toolInput = toolInput;
|
|
156
|
+
if (incidentId)
|
|
157
|
+
ev.incidentId = incidentId;
|
|
158
|
+
if (filePath)
|
|
159
|
+
ev.filePath = filePath.slice(0, 512);
|
|
160
|
+
try {
|
|
161
|
+
await this.post('/api/v1/hook-events', { events: [ev] }, EVENT_TIMEOUT_MS);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Build a client from the environment, falling back to CLI credentials.
|
|
170
|
+
*
|
|
171
|
+
* Reading `~/.intutic/credentials.json` means the gate works with whatever
|
|
172
|
+
* workspace `intutic login` already bound, instead of duplicating the key.
|
|
173
|
+
*/
|
|
174
|
+
static fromEnv(opts = {}) {
|
|
175
|
+
const base = process.env.INTUTIC_CONTROL_PLANE_URL || 'https://api.intutic.ai';
|
|
176
|
+
let key = process.env.INTUTIC_API_KEY || '';
|
|
177
|
+
let ws = process.env.INTUTIC_WORKSPACE_ID || '';
|
|
178
|
+
if (!key || !ws) {
|
|
179
|
+
try {
|
|
180
|
+
const credPath = join(homedir(), '.intutic', 'credentials.json');
|
|
181
|
+
const c = JSON.parse(readFileSync(credPath, 'utf-8'));
|
|
182
|
+
key = key || String(c.apiKey ?? '');
|
|
183
|
+
ws = ws || String(c.workspaceId ?? '');
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// No credentials file — fall through with whatever env supplied.
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const sess = opts.sessionId || process.env.INTUTIC_SESSION_ID || '';
|
|
190
|
+
if (!sess) {
|
|
191
|
+
// The proxy defaults an unset x-session-id to the literal "unknown",
|
|
192
|
+
// which collapses every run onto one dashboard row. Refuse instead.
|
|
193
|
+
throw new Error('No session id. Set INTUTIC_SESSION_ID or pass sessionId — an unset x-session-id ' +
|
|
194
|
+
"becomes the literal 'unknown' in the proxy and merges every run into a single " +
|
|
195
|
+
'dashboard session.');
|
|
196
|
+
}
|
|
197
|
+
return new GateClient({
|
|
198
|
+
baseUrl: base,
|
|
199
|
+
apiKey: key,
|
|
200
|
+
workspaceId: ws,
|
|
201
|
+
sessionId: sess,
|
|
202
|
+
harness: opts.harness ?? 'generic',
|
|
203
|
+
failClosed: opts.failClosed ?? true,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/dsh.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh.ts — Cordis plugin adapter for DeepSeek's "dsh" harness.
|
|
3
|
+
*
|
|
4
|
+
* Published as the `@intutic/gate/dsh` subpath (see README.md's "Subpath
|
|
5
|
+
* convention for later phases"). `services/sync-daemon/src/harness/dshHooks.ts`
|
|
6
|
+
* merge-writes a row naming this module (`name: '@intutic/gate/dsh'`) into a
|
|
7
|
+
* dsh profile's `cordis.patch.yml`; dsh's own Cordis loader resolves that name
|
|
8
|
+
* with a plain dynamic `import()` and mounts the exported plugin
|
|
9
|
+
* (`{ name, inject, apply }`) the same way it mounts every other bundle row.
|
|
10
|
+
*
|
|
11
|
+
* ## The veto mechanism — CONFIRMED against a real install, not assumed
|
|
12
|
+
*
|
|
13
|
+
* dsh is a developer preview (`@deepseek-ai/dsh`, first published 2026-08-13)
|
|
14
|
+
* built on DeepSeek's own "Cordis" plugin framework (`@deepseek-ai/cordis`,
|
|
15
|
+
* `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-app-boot`, ...). Both are public
|
|
16
|
+
* on the npm registry, and this module was authored against a real
|
|
17
|
+
* `npm pack`/inspection of them (see the TD entry this phase filed for exactly
|
|
18
|
+
* what was checked and what still had to be assumed) — NOT solely from the
|
|
19
|
+
* phase brief's prior guess, which named a different event (`agent/pre-step`)
|
|
20
|
+
* and a different decision shape (`{kind:'reject',...}`). Both turned out to
|
|
21
|
+
* be close but not exact:
|
|
22
|
+
*
|
|
23
|
+
* - The real per-tool veto point is `tools/pre-execute` (declared by
|
|
24
|
+
* `@deepseek-ai/dsh-tools`), not `agent/pre-step` (`@deepseek-ai/dsh-agent`'s
|
|
25
|
+
* per-turn/step event — a coarser boundary that batches a driver step
|
|
26
|
+
* rather than one tool call, and the wrong extension point for a
|
|
27
|
+
* per-tool-call gate).
|
|
28
|
+
* - It is a genuine Cordis `waterfall`: `(exec: ToolExecution, next: () =>
|
|
29
|
+
* Promise<PreToolDecision>) => Promise<PreToolDecision>`. Cordis's own
|
|
30
|
+
* waterfall contract (confirmed by reading `@deepseek-ai/cordis`'s
|
|
31
|
+
* `events.d.ts`) composes listeners around a `next()` continuation —
|
|
32
|
+
* "a listener that does not call next() vetoes the rest of the chain,
|
|
33
|
+
* including the built-in behavior" — so this listener calls `next()` on
|
|
34
|
+
* ALLOW (to preserve whatever later listener or built-in behaviour — e.g.
|
|
35
|
+
* dsh's own `ask`/approval flow — would otherwise run) and returns its own
|
|
36
|
+
* `{kind:'deny',...}` WITHOUT calling `next()` to veto.
|
|
37
|
+
* - The decision shape is `PreToolDecision = {kind:'allow'} | {kind:'deny',
|
|
38
|
+
* reason} | {kind:'ask', reason?}` (confirmed from
|
|
39
|
+
* `@deepseek-ai/dsh-tools`'s shipped `.d.ts`) — `'deny'`, not the phase
|
|
40
|
+
* brief's guessed `'reject'`.
|
|
41
|
+
*
|
|
42
|
+
* `ctx.tools.guard()` (a separate, monotonic, explicitly SYNCHRONOUS
|
|
43
|
+
* mechanism dsh also exposes) was considered and rejected: `@intutic/gate`'s
|
|
44
|
+
* `Gate.guard()` is async (network-backed SOP-rule fetch and `/hook-gate`
|
|
45
|
+
* POST — see gate.ts's module doc), and a synchronous `ToolGuard` cannot
|
|
46
|
+
* `await` it. `tools/pre-execute` is the only one of dsh's two extension
|
|
47
|
+
* points this package's async contract fits.
|
|
48
|
+
*
|
|
49
|
+
* ## What this module does NOT import
|
|
50
|
+
*
|
|
51
|
+
* Deliberately no dependency on `@deepseek-ai/cordis` or `@deepseek-ai/dsh-tools`
|
|
52
|
+
* at runtime — `CordisLikeContext`/`DshToolExecution`/`DshPreToolDecision`
|
|
53
|
+
* below are narrow structural types capturing only the shape this plugin
|
|
54
|
+
* actually touches, matching Cordis's own duck-typed plugin contract (a
|
|
55
|
+
* plain `{ name?, inject?, apply(ctx, config) }` object — confirmed against
|
|
56
|
+
* both `@deepseek-ai/cordis`'s README quick-start and dsh's own in-product
|
|
57
|
+
* "cordis-plugin-development" skill doc, which returns `{ apply(ctx) {...} }`
|
|
58
|
+
* with no import of anything). Adding a hard dependency on a fast-moving
|
|
59
|
+
* preview product's framework package to `@intutic/gate`'s dsh subpath would
|
|
60
|
+
* make every OTHER subpath's install pull it in too (or need a peerDependency
|
|
61
|
+
* carve-out) for a shape simple enough to describe locally. The real
|
|
62
|
+
* `@deepseek-ai/cordis` package is used only as a devDependency, in this
|
|
63
|
+
* module's own test file, to exercise the real waterfall dispatch mechanics
|
|
64
|
+
* against the genuine `Context` class rather than a hand-rolled stand-in.
|
|
65
|
+
*
|
|
66
|
+
* @module
|
|
67
|
+
*/
|
|
68
|
+
import { Gate } from './gate.js';
|
|
69
|
+
import type { GateConfig } from './gate.js';
|
|
70
|
+
/** The Cordis Plugin id this module registers as. Shown in dsh's own plugin
|
|
71
|
+
* diagnostics/`--dump-config` output. */
|
|
72
|
+
export declare const PLUGIN_NAME = "intutic-governance";
|
|
73
|
+
/**
|
|
74
|
+
* The slice of dsh's real `tools/pre-execute` payload (`ToolExecution`, from
|
|
75
|
+
* `@deepseek-ai/dsh-tools`) this plugin reads. `arguments` is documented as
|
|
76
|
+
* "losslessly JSON-serializable parsed arguments (tools validate their own
|
|
77
|
+
* schema)" — an `unknown`, not necessarily an object, hence
|
|
78
|
+
* {@link renderDshToolInput} below.
|
|
79
|
+
*/
|
|
80
|
+
export interface DshToolExecution {
|
|
81
|
+
readonly name: string;
|
|
82
|
+
readonly arguments: unknown;
|
|
83
|
+
}
|
|
84
|
+
/** The confirmed real `PreToolDecision` union from `@deepseek-ai/dsh-tools`. */
|
|
85
|
+
export type DshPreToolDecision = {
|
|
86
|
+
kind: 'allow';
|
|
87
|
+
} | {
|
|
88
|
+
kind: 'deny';
|
|
89
|
+
reason: string;
|
|
90
|
+
} | {
|
|
91
|
+
kind: 'ask';
|
|
92
|
+
reason?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Structural stand-in for the Cordis `Context` this plugin needs — see the
|
|
96
|
+
* module doc for why the real `@deepseek-ai/cordis` package is not imported.
|
|
97
|
+
*/
|
|
98
|
+
export interface CordisLikeContext {
|
|
99
|
+
on(event: 'tools/pre-execute', listener: (exec: DshToolExecution, next: () => Promise<DshPreToolDecision>) => Promise<DshPreToolDecision>): () => boolean;
|
|
100
|
+
}
|
|
101
|
+
/** `cordis.patch.yml` row config for this plugin. Extends the core
|
|
102
|
+
* {@link GateConfig} with the one dsh-specific knob: an explicit session id,
|
|
103
|
+
* since dsh has no single "the session" this plugin can read off `exec` (a
|
|
104
|
+
* `ToolExecution` carries an `agent?`, not a raw session/conversation id) —
|
|
105
|
+
* see {@link resolveSessionId}. */
|
|
106
|
+
export interface DshGateConfig extends GateConfig {
|
|
107
|
+
/** Overrides the generated-per-process session id. Mirrors
|
|
108
|
+
* `INTUTIC_SESSION_ID` for callers that already have one to hand. */
|
|
109
|
+
sessionId?: string;
|
|
110
|
+
}
|
|
111
|
+
/** Cordis Plugins declare their hard dependencies here; the loader defers
|
|
112
|
+
* activation until every named service exists and reactivates on restart.
|
|
113
|
+
* `tools` is `@deepseek-ai/dsh-tools`'s `ToolRegistry` service — the thing
|
|
114
|
+
* that actually dispatches `tools/pre-execute`. */
|
|
115
|
+
export declare const inject: string[];
|
|
116
|
+
/**
|
|
117
|
+
* Build the `tools/pre-execute` listener for a given {@link Gate}.
|
|
118
|
+
*
|
|
119
|
+
* Factored out of {@link apply} so a test can exercise the exact listener
|
|
120
|
+
* `apply()` registers — event extraction, the refusal-to-decision mapping,
|
|
121
|
+
* the fail-closed default, and the waterfall `next()`-calling on allow —
|
|
122
|
+
* against a controllable fake `Gate`, without needing a real dsh install or
|
|
123
|
+
* network access to construct a `GateClient`.
|
|
124
|
+
*
|
|
125
|
+
* Never throws: every path returns a {@link DshPreToolDecision}. A crash
|
|
126
|
+
* inside `gate.guard()` that is not an {@link IntuticGateRefusal} — a bug in
|
|
127
|
+
* this gate, or an unexpected throw from a tier it calls into — is treated
|
|
128
|
+
* as "cannot evaluate" and denied rather than allowed to escape the
|
|
129
|
+
* waterfall or fall through to an allow; see gate.ts's own module doc for why
|
|
130
|
+
* every tier in this package takes that direction on failure.
|
|
131
|
+
*/
|
|
132
|
+
export declare function createPreExecuteListener(gate: Gate): (exec: DshToolExecution, next: () => Promise<DshPreToolDecision>) => Promise<DshPreToolDecision>;
|
|
133
|
+
/**
|
|
134
|
+
* Mount the Intutic governance gate on a dsh profile.
|
|
135
|
+
*
|
|
136
|
+
* Builds one {@link Gate} for the lifetime of this plugin instance (not per
|
|
137
|
+
* call — Tier A1/A2/A3 all cache within a `Gate`, see gate.ts) and installs it
|
|
138
|
+
* as the process-wide default too (`install()`), so a hand-authored
|
|
139
|
+
* `wrapTool`/`wrapTools` call elsewhere in the same dsh process picks up the
|
|
140
|
+
* identical instance rather than constructing a second one with independent
|
|
141
|
+
* caches.
|
|
142
|
+
*
|
|
143
|
+
* Never throws out of `apply()` itself: a `GateClient.fromEnv` failure (e.g.
|
|
144
|
+
* credentials genuinely unreadable) degrades to a client-less `Gate` — Tier B
|
|
145
|
+
* and Tier A3 inactive, Tier A1/A2 (local, load-bearing) unaffected — rather
|
|
146
|
+
* than taking down the whole dsh profile boot over a governance layer that is
|
|
147
|
+
* additive by design.
|
|
148
|
+
*/
|
|
149
|
+
export declare function apply(ctx: CordisLikeContext, config?: DshGateConfig): void;
|
|
150
|
+
/** Default export — the whole Plugin object, for `name: '@intutic/gate/dsh'`
|
|
151
|
+
* cordis.patch.yml rows that resolve this module and pass it directly to
|
|
152
|
+
* `ctx.plugin()` (dsh's loader unwraps a default export the same way it
|
|
153
|
+
* unwraps a named one — see `dsh-app-boot`'s `unwrapExports`). Named exports
|
|
154
|
+
* (`apply`, `inject`, `PLUGIN_NAME`) are also available for a caller that
|
|
155
|
+
* imports this subpath directly rather than through the loader. */
|
|
156
|
+
declare const _default: {
|
|
157
|
+
name: string;
|
|
158
|
+
inject: string[];
|
|
159
|
+
apply: typeof apply;
|
|
160
|
+
};
|
|
161
|
+
export default _default;
|
|
162
|
+
//# sourceMappingURL=dsh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsh.d.ts","sourceRoot":"","sources":["../src/dsh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAGH,OAAO,EAAE,IAAI,EAAW,MAAM,WAAW,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,WAAW,CAAA;AAItD;0CAC0C;AAC1C,eAAO,MAAM,WAAW,uBAAuB,CAAA;AAE/C;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED,gFAAgF;AAChF,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAExH;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,CACA,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,KAAK,OAAO,CAAC,kBAAkB,CAAC,GACzG,MAAM,OAAO,CAAA;CACjB;AAED;;;;oCAIoC;AACpC,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C;0EACsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;oDAGoD;AACpD,eAAO,MAAM,MAAM,UAAY,CAAA;AAwC/B;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,IAAI,GACT,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAoBlG;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,GAAE,aAAkB,GAAG,IAAI,CAY9E;AAED;;;;;oEAKoE;;;;;;AACpE,wBAAmD"}
|