@getmarrow/mcp 3.9.102 → 3.9.106
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/README.md +71 -24
- package/dist/approval-reply.d.ts +2 -0
- package/dist/approval-reply.d.ts.map +1 -0
- package/dist/approval-reply.js +18 -0
- package/dist/approval-reply.js.map +1 -0
- package/dist/cli.js +1716 -1644
- package/dist/cli.js.map +1 -1
- package/dist/codex-plugin-pins.d.ts +19 -0
- package/dist/codex-plugin-pins.d.ts.map +1 -0
- package/dist/codex-plugin-pins.js +61 -0
- package/dist/codex-plugin-pins.js.map +1 -0
- package/dist/codex-plugins.d.ts +34 -0
- package/dist/codex-plugins.d.ts.map +1 -0
- package/dist/codex-plugins.js +240 -0
- package/dist/codex-plugins.js.map +1 -0
- package/dist/env.d.ts +8 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +83 -4
- package/dist/env.js.map +1 -1
- package/dist/hook-context.d.ts.map +1 -1
- package/dist/hook-context.js +25 -0
- package/dist/hook-context.js.map +1 -1
- package/dist/hook-contract.d.ts +4 -3
- package/dist/hook-contract.d.ts.map +1 -1
- package/dist/hook-contract.js +43 -5
- package/dist/hook-contract.js.map +1 -1
- package/dist/hook-pre-action.d.ts +80 -3
- package/dist/hook-pre-action.d.ts.map +1 -1
- package/dist/hook-pre-action.js +435 -29
- package/dist/hook-pre-action.js.map +1 -1
- package/dist/hook-tool-policy.d.ts +73 -4
- package/dist/hook-tool-policy.d.ts.map +1 -1
- package/dist/hook-tool-policy.js +287 -18
- package/dist/hook-tool-policy.js.map +1 -1
- package/dist/hook.d.ts +1 -1
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +15 -7
- package/dist/hook.js.map +1 -1
- package/dist/host-approval-state.d.ts +7 -0
- package/dist/host-approval-state.d.ts.map +1 -1
- package/dist/host-approval-state.js +15 -0
- package/dist/host-approval-state.js.map +1 -1
- package/dist/host-approval.d.ts +22 -1
- package/dist/host-approval.d.ts.map +1 -1
- package/dist/host-approval.js +65 -4
- package/dist/host-approval.js.map +1 -1
- package/dist/host-session.d.ts +11 -0
- package/dist/host-session.d.ts.map +1 -1
- package/dist/host-session.js +49 -0
- package/dist/host-session.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -11
- package/dist/index.js.map +1 -1
- package/dist/keyless-server.d.ts +53 -0
- package/dist/keyless-server.d.ts.map +1 -0
- package/dist/keyless-server.js +230 -0
- package/dist/keyless-server.js.map +1 -0
- package/dist/normalized-action.d.ts +31 -6
- package/dist/normalized-action.d.ts.map +1 -1
- package/dist/normalized-action.js +550 -105
- package/dist/normalized-action.js.map +1 -1
- package/dist/own-server-identity.d.ts +142 -0
- package/dist/own-server-identity.d.ts.map +1 -0
- package/dist/own-server-identity.js +1123 -0
- package/dist/own-server-identity.js.map +1 -0
- package/dist/own-tool.d.ts +21 -9
- package/dist/own-tool.d.ts.map +1 -1
- package/dist/own-tool.js +25 -10
- package/dist/own-tool.js.map +1 -1
- package/dist/redact.d.ts +23 -0
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +181 -8
- package/dist/redact.js.map +1 -1
- package/dist/seatbelt/classifier-pin.d.ts +15 -0
- package/dist/seatbelt/classifier-pin.d.ts.map +1 -0
- package/dist/seatbelt/classifier-pin.js +26 -0
- package/dist/seatbelt/classifier-pin.js.map +1 -0
- package/dist/seatbelt/env-dump.d.ts +45 -0
- package/dist/seatbelt/env-dump.d.ts.map +1 -0
- package/dist/seatbelt/env-dump.js +308 -0
- package/dist/seatbelt/env-dump.js.map +1 -0
- package/dist/seatbelt/fallback-copy.d.ts +16 -0
- package/dist/seatbelt/fallback-copy.d.ts.map +1 -0
- package/dist/seatbelt/fallback-copy.js +68 -0
- package/dist/seatbelt/fallback-copy.js.map +1 -0
- package/dist/seatbelt/guards.d.ts +10 -0
- package/dist/seatbelt/guards.d.ts.map +1 -0
- package/dist/seatbelt/guards.js +509 -0
- package/dist/seatbelt/guards.js.map +1 -0
- package/dist/seatbelt/hook.d.ts +91 -0
- package/dist/seatbelt/hook.d.ts.map +1 -0
- package/dist/seatbelt/hook.js +396 -0
- package/dist/seatbelt/hook.js.map +1 -0
- package/dist/seatbelt/longopts.d.ts +68 -0
- package/dist/seatbelt/longopts.d.ts.map +1 -0
- package/dist/seatbelt/longopts.js +377 -0
- package/dist/seatbelt/longopts.js.map +1 -0
- package/dist/seatbelt/mapper.d.ts +83 -0
- package/dist/seatbelt/mapper.d.ts.map +1 -0
- package/dist/seatbelt/mapper.js +10581 -0
- package/dist/seatbelt/mapper.js.map +1 -0
- package/dist/seatbelt/record.d.ts +94 -0
- package/dist/seatbelt/record.d.ts.map +1 -0
- package/dist/seatbelt/record.js +776 -0
- package/dist/seatbelt/record.js.map +1 -0
- package/dist/seatbelt/tables.d.ts +82 -0
- package/dist/seatbelt/tables.d.ts.map +1 -0
- package/dist/seatbelt/tables.js +352 -0
- package/dist/seatbelt/tables.js.map +1 -0
- package/dist/seatbelt-deploy.d.ts +100 -0
- package/dist/seatbelt-deploy.d.ts.map +1 -0
- package/dist/seatbelt-deploy.js +393 -0
- package/dist/seatbelt-deploy.js.map +1 -0
- package/dist/seatbelt-fs.d.ts +30 -0
- package/dist/seatbelt-fs.d.ts.map +1 -0
- package/dist/seatbelt-fs.js +94 -0
- package/dist/seatbelt-fs.js.map +1 -0
- package/dist/seatbelt-git.d.ts +212 -0
- package/dist/seatbelt-git.d.ts.map +1 -0
- package/dist/seatbelt-git.js +844 -0
- package/dist/seatbelt-git.js.map +1 -0
- package/dist/seatbelt-mode.d.ts +77 -0
- package/dist/seatbelt-mode.d.ts.map +1 -0
- package/dist/seatbelt-mode.js +496 -0
- package/dist/seatbelt-mode.js.map +1 -0
- package/dist/seatbelt-path.d.ts +123 -0
- package/dist/seatbelt-path.d.ts.map +1 -0
- package/dist/seatbelt-path.js +482 -0
- package/dist/seatbelt-path.js.map +1 -0
- package/dist/seatbelt-scripts.d.ts +109 -0
- package/dist/seatbelt-scripts.d.ts.map +1 -0
- package/dist/seatbelt-scripts.js +1060 -0
- package/dist/seatbelt-scripts.js.map +1 -0
- package/dist/secret-paths.d.ts +17 -0
- package/dist/secret-paths.d.ts.map +1 -0
- package/dist/secret-paths.js +32 -0
- package/dist/secret-paths.js.map +1 -0
- package/dist/session-loop-guard.d.ts.map +1 -1
- package/dist/session-loop-guard.js +15 -5
- package/dist/session-loop-guard.js.map +1 -1
- package/dist/tool-catalog.js +2 -2
- package/dist/tool-catalog.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/server.json +3 -3
- package/vendor/classifier/MANIFEST.json +25 -0
- package/vendor/classifier/classifier.js +1356 -0
- package/vendor/classifier/policy-baseline.js +187 -0
- package/vendor/classifier/redact.js +59 -0
- package/vendor/classifier/shell-parse.js +455 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyless start of the MCP server. With no Marrow key anywhere the server reads
|
|
3
|
+
* one, the server used to print "MARROW_API_KEY environment variable is
|
|
4
|
+
* required" and exit 1, which hosts show as a broken server. It now answers the
|
|
5
|
+
* MCP protocol with zero tools and an `instructions` string that says how the
|
|
6
|
+
* owner connects a key.
|
|
7
|
+
*
|
|
8
|
+
* Fail closed: keylessStart is true only for a clear "no key". A key, anything
|
|
9
|
+
* key-shaped, a refused owner key file, a base URL the server would refuse, or
|
|
10
|
+
* any doubt runs the real server path exactly as before.
|
|
11
|
+
*
|
|
12
|
+
* The keyless server judges, checks and records nothing. It starts no child
|
|
13
|
+
* process, opens no network and no file, reads no environment, and writes only
|
|
14
|
+
* to stdout and stderr. Hooks are separate entrypoints and are not touched.
|
|
15
|
+
* Protocol handling matches the plugin launcher's keyless stub
|
|
16
|
+
* (marrow-plugins plugins/<plugin>/scripts/marrow-launch.cjs, serveKeyless).
|
|
17
|
+
*
|
|
18
|
+
* Never looser than the exit 1 it replaces: until a valid `initialize` request has
|
|
19
|
+
* been answered, a frame that is not JSON-RPC 2.0 (a Cursor or Claude hook payload
|
|
20
|
+
* piped to the entry, a parse error, an oversize line) or an end of stdin ends the
|
|
21
|
+
* process with the no-key refusal on stderr, nothing on stdout, and exit 1. After
|
|
22
|
+
* an initialize, the end of stdin is exit 0.
|
|
23
|
+
*
|
|
24
|
+
* The key text (URL, activate command, plugin steps, the refusal) is owned by cli.ts
|
|
25
|
+
* and passed in; this file holds no second copy of it.
|
|
26
|
+
*/
|
|
27
|
+
export interface KeylessInstructionParts {
|
|
28
|
+
getKeyUrl: string;
|
|
29
|
+
activateCommand: string;
|
|
30
|
+
/** Set when the server runs under the Claude Code plugin: its key steps replace the activate command. */
|
|
31
|
+
pluginSteps?: string;
|
|
32
|
+
}
|
|
33
|
+
/** The `instructions` string of the initialize answer. */
|
|
34
|
+
export declare function keylessInstructions(parts: KeylessInstructionParts): string;
|
|
35
|
+
export interface KeylessTexts {
|
|
36
|
+
instructions: string;
|
|
37
|
+
/** Written to stderr once, when the first initialize is answered. */
|
|
38
|
+
notice: string;
|
|
39
|
+
/** The server's own no-key refusal, written to stderr before the exit 1 that a non-MCP first frame or an early end of stdin gets. */
|
|
40
|
+
refusal: string;
|
|
41
|
+
}
|
|
42
|
+
export declare const KEYLESS_NOTICE = "Marrow: no Marrow key on this machine, so the Marrow MCP server started with no tools. Marrow hooks, where they are set up, keep their free keyless seatbelt.";
|
|
43
|
+
/**
|
|
44
|
+
* Whether the MCP server starts keyless. `resolved` must be the server's own resolveMarrowEnv() result.
|
|
45
|
+
* True only when it found no key (an empty MARROW_API_KEY or MARROW_KEY counts as none, a whitespace one does
|
|
46
|
+
* not), no owner key file was refused, no `--key` argument is given in any form, no fleet key
|
|
47
|
+
* (MARROW_KEY_<SUFFIX>) is set, and the base URL passes the server's own check.
|
|
48
|
+
*/
|
|
49
|
+
export declare function keylessStart(resolved: unknown, argv: readonly unknown[], env: Record<string, string | undefined>): boolean;
|
|
50
|
+
export declare function keylessProtocolVersion(params: unknown): string;
|
|
51
|
+
/** Newline-delimited JSON-RPC 2.0 on stdio with zero tools. Exits 0 when stdin ends after an initialize, 1 for a non-MCP start. */
|
|
52
|
+
export declare function serveKeylessMcp(serverVersion: string, texts: KeylessTexts): void;
|
|
53
|
+
//# sourceMappingURL=keyless-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyless-server.d.ts","sourceRoot":"","sources":["../src/keyless-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,yGAAyG;IACzG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAS1E;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,qIAAqI;IACrI,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,cAAc,kKAAkK,CAAC;AAQ9L;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAe1H;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAO9D;AAED,mIAAmI;AACnI,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAyHhF"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Keyless start of the MCP server. With no Marrow key anywhere the server reads
|
|
4
|
+
* one, the server used to print "MARROW_API_KEY environment variable is
|
|
5
|
+
* required" and exit 1, which hosts show as a broken server. It now answers the
|
|
6
|
+
* MCP protocol with zero tools and an `instructions` string that says how the
|
|
7
|
+
* owner connects a key.
|
|
8
|
+
*
|
|
9
|
+
* Fail closed: keylessStart is true only for a clear "no key". A key, anything
|
|
10
|
+
* key-shaped, a refused owner key file, a base URL the server would refuse, or
|
|
11
|
+
* any doubt runs the real server path exactly as before.
|
|
12
|
+
*
|
|
13
|
+
* The keyless server judges, checks and records nothing. It starts no child
|
|
14
|
+
* process, opens no network and no file, reads no environment, and writes only
|
|
15
|
+
* to stdout and stderr. Hooks are separate entrypoints and are not touched.
|
|
16
|
+
* Protocol handling matches the plugin launcher's keyless stub
|
|
17
|
+
* (marrow-plugins plugins/<plugin>/scripts/marrow-launch.cjs, serveKeyless).
|
|
18
|
+
*
|
|
19
|
+
* Never looser than the exit 1 it replaces: until a valid `initialize` request has
|
|
20
|
+
* been answered, a frame that is not JSON-RPC 2.0 (a Cursor or Claude hook payload
|
|
21
|
+
* piped to the entry, a parse error, an oversize line) or an end of stdin ends the
|
|
22
|
+
* process with the no-key refusal on stderr, nothing on stdout, and exit 1. After
|
|
23
|
+
* an initialize, the end of stdin is exit 0.
|
|
24
|
+
*
|
|
25
|
+
* The key text (URL, activate command, plugin steps, the refusal) is owned by cli.ts
|
|
26
|
+
* and passed in; this file holds no second copy of it.
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.KEYLESS_NOTICE = void 0;
|
|
30
|
+
exports.keylessInstructions = keylessInstructions;
|
|
31
|
+
exports.keylessStart = keylessStart;
|
|
32
|
+
exports.keylessProtocolVersion = keylessProtocolVersion;
|
|
33
|
+
exports.serveKeylessMcp = serveKeylessMcp;
|
|
34
|
+
const index_1 = require("./index");
|
|
35
|
+
/** The `instructions` string of the initialize answer. */
|
|
36
|
+
function keylessInstructions(parts) {
|
|
37
|
+
const connect = parts.pluginSteps
|
|
38
|
+
? `To connect a Marrow account, the owner follows these steps. ${parts.pluginSteps} `
|
|
39
|
+
: `To connect a Marrow account, the owner creates a key at ${parts.getKeyUrl} and runs ${parts.activateCommand} in their own terminal, then restarts this agent host. `;
|
|
40
|
+
return 'This Marrow server started without a Marrow key on this machine, so it has no tools. '
|
|
41
|
+
+ 'It does not judge, check or record any action. '
|
|
42
|
+
+ (parts.pluginSteps ? '' : 'Marrow hooks, where they are set up on this machine, are separate from this server and keep their free keyless seatbelt; this server does not show whether any are set up. ')
|
|
43
|
+
+ connect
|
|
44
|
+
+ 'A key can not be added from this chat.';
|
|
45
|
+
}
|
|
46
|
+
exports.KEYLESS_NOTICE = 'Marrow: no Marrow key on this machine, so the Marrow MCP server started with no tools. Marrow hooks, where they are set up, keep their free keyless seatbelt.';
|
|
47
|
+
// The real server's protocolVersion rule (cli.ts noteClientCapabilities): the requested version only when it is one
|
|
48
|
+
// of these AND the client's capabilities.elicitation is an object; every other input gets 2024-11-05.
|
|
49
|
+
const ELICITATION_PROTOCOL_VERSIONS = ['2025-06-18', '2025-11-25'];
|
|
50
|
+
const DEFAULT_PROTOCOL_VERSION = '2024-11-05';
|
|
51
|
+
const MAX_LINE_BYTES = 1024 * 1024;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the MCP server starts keyless. `resolved` must be the server's own resolveMarrowEnv() result.
|
|
54
|
+
* True only when it found no key (an empty MARROW_API_KEY or MARROW_KEY counts as none, a whitespace one does
|
|
55
|
+
* not), no owner key file was refused, no `--key` argument is given in any form, no fleet key
|
|
56
|
+
* (MARROW_KEY_<SUFFIX>) is set, and the base URL passes the server's own check.
|
|
57
|
+
*/
|
|
58
|
+
function keylessStart(resolved, argv, env) {
|
|
59
|
+
try {
|
|
60
|
+
if (argv.some((arg) => typeof arg !== 'string' || arg.startsWith('--key')))
|
|
61
|
+
return false;
|
|
62
|
+
if (resolved === null || typeof resolved !== 'object')
|
|
63
|
+
return false;
|
|
64
|
+
const result = resolved;
|
|
65
|
+
if (result.apiKey !== '' || result.missing !== true || result.source !== null || result.ownerFileRefused !== undefined)
|
|
66
|
+
return false;
|
|
67
|
+
// The resolver uses a fleet key only with a direct key and a matching agent identity; one set without them is still a key.
|
|
68
|
+
if (Object.keys(env).some((name) => name.startsWith('MARROW_KEY_') && Boolean(env[name])))
|
|
69
|
+
return false;
|
|
70
|
+
const baseUrl = result.baseUrl || 'https://api.getmarrow.ai';
|
|
71
|
+
if (typeof baseUrl !== 'string')
|
|
72
|
+
return false;
|
|
73
|
+
(0, index_1.validateBaseUrl)(baseUrl);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function keylessProtocolVersion(params) {
|
|
81
|
+
const record = params && typeof params === 'object' ? params : {};
|
|
82
|
+
const capabilities = record.capabilities && typeof record.capabilities === 'object' ? record.capabilities : {};
|
|
83
|
+
const requested = typeof record.protocolVersion === 'string' ? record.protocolVersion : '';
|
|
84
|
+
const elicits = Boolean(capabilities.elicitation && typeof capabilities.elicitation === 'object')
|
|
85
|
+
&& ELICITATION_PROTOCOL_VERSIONS.includes(requested);
|
|
86
|
+
return elicits ? requested : DEFAULT_PROTOCOL_VERSION;
|
|
87
|
+
}
|
|
88
|
+
/** Newline-delimited JSON-RPC 2.0 on stdio with zero tools. Exits 0 when stdin ends after an initialize, 1 for a non-MCP start. */
|
|
89
|
+
function serveKeylessMcp(serverVersion, texts) {
|
|
90
|
+
const has = (object, key) => Object.prototype.hasOwnProperty.call(object, key);
|
|
91
|
+
const send = (id, body) => process.stdout.write(`${JSON.stringify({ jsonrpc: '2.0', id, ...body })}\n`);
|
|
92
|
+
const refuse = (id, code, message) => send(id, { error: { code, message } });
|
|
93
|
+
let initialized = false;
|
|
94
|
+
// Today's no-key exit: the refusal on stderr, nothing on stdout, exit 1.
|
|
95
|
+
function exitAsNoKey() {
|
|
96
|
+
try {
|
|
97
|
+
process.stderr.write(texts.refusal);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// a closed stderr changes nothing
|
|
101
|
+
}
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
// A frame that is not a usable JSON-RPC 2.0 message. Before an initialize it proves the process was not started by an MCP host.
|
|
105
|
+
function badFrame(id, code, message) {
|
|
106
|
+
if (!initialized)
|
|
107
|
+
exitAsNoKey();
|
|
108
|
+
refuse(id, code, message);
|
|
109
|
+
}
|
|
110
|
+
function handle(text) {
|
|
111
|
+
let msg;
|
|
112
|
+
try {
|
|
113
|
+
msg = JSON.parse(text);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
badFrame(null, -32700, 'Parse error.');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (msg === null || typeof msg !== 'object' || Array.isArray(msg)) {
|
|
120
|
+
badFrame(null, -32600, 'Invalid request.');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const request = msg;
|
|
124
|
+
if (request.jsonrpc !== '2.0' || typeof request.method !== 'string') {
|
|
125
|
+
badFrame(null, -32600, 'Invalid request.');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (!has(request, 'id'))
|
|
129
|
+
return; // a notification gets no reply
|
|
130
|
+
const id = request.id;
|
|
131
|
+
if (!(typeof id === 'string' || id === null || (typeof id === 'number' && Number.isFinite(id)))) {
|
|
132
|
+
badFrame(null, -32600, 'Invalid request.');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (request.method === 'initialize') {
|
|
136
|
+
initialized = true;
|
|
137
|
+
try {
|
|
138
|
+
process.stderr.write(texts.notice);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// a closed stderr changes nothing
|
|
142
|
+
}
|
|
143
|
+
send(id, {
|
|
144
|
+
result: {
|
|
145
|
+
protocolVersion: keylessProtocolVersion(request.params),
|
|
146
|
+
capabilities: { tools: { listChanged: false } },
|
|
147
|
+
serverInfo: { name: 'marrow', version: serverVersion },
|
|
148
|
+
instructions: texts.instructions,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (!initialized) {
|
|
154
|
+
refuse(id, -32002, 'Server not initialized. Send initialize first.');
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
switch (request.method) {
|
|
158
|
+
case 'ping':
|
|
159
|
+
send(id, { result: {} });
|
|
160
|
+
return;
|
|
161
|
+
case 'tools/list':
|
|
162
|
+
send(id, { result: { tools: [] } });
|
|
163
|
+
return;
|
|
164
|
+
case 'prompts/list':
|
|
165
|
+
send(id, { result: { prompts: [] } });
|
|
166
|
+
return;
|
|
167
|
+
case 'resources/list':
|
|
168
|
+
send(id, { result: { resources: [] } });
|
|
169
|
+
return;
|
|
170
|
+
case 'resources/templates/list':
|
|
171
|
+
send(id, { result: { resourceTemplates: [] } });
|
|
172
|
+
return;
|
|
173
|
+
case 'tools/call':
|
|
174
|
+
refuse(id, -32602, 'This server has no tools.');
|
|
175
|
+
return;
|
|
176
|
+
default: refuse(id, -32601, 'Method not found.');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function dispatch(chunks) {
|
|
180
|
+
const text = Buffer.concat(chunks).toString('utf8');
|
|
181
|
+
if (!text.trim())
|
|
182
|
+
return;
|
|
183
|
+
try {
|
|
184
|
+
handle(text);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
badFrame(null, -32603, 'Internal error.');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
let chunks = [];
|
|
191
|
+
let size = 0;
|
|
192
|
+
let skipping = false; // inside a line over the limit: dropped up to the next newline, never buffered
|
|
193
|
+
process.stdout.on('error', () => process.exit(initialized ? 0 : 1));
|
|
194
|
+
process.stdin.on('error', () => { process.exitCode = 1; });
|
|
195
|
+
process.stdin.on('data', (data) => {
|
|
196
|
+
const chunk = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;
|
|
197
|
+
let from = 0;
|
|
198
|
+
while (from < chunk.length) {
|
|
199
|
+
const newline = chunk.indexOf(10, from);
|
|
200
|
+
const to = newline === -1 ? chunk.length : newline;
|
|
201
|
+
if (!skipping) {
|
|
202
|
+
size += to - from;
|
|
203
|
+
if (size > MAX_LINE_BYTES) {
|
|
204
|
+
skipping = true;
|
|
205
|
+
chunks = [];
|
|
206
|
+
size = 0;
|
|
207
|
+
badFrame(null, -32600, 'Request too large.');
|
|
208
|
+
}
|
|
209
|
+
else if (to > from) {
|
|
210
|
+
chunks.push(chunk.subarray(from, to));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (newline === -1)
|
|
214
|
+
return;
|
|
215
|
+
if (!skipping)
|
|
216
|
+
dispatch(chunks);
|
|
217
|
+
chunks = [];
|
|
218
|
+
size = 0;
|
|
219
|
+
skipping = false;
|
|
220
|
+
from = newline + 1;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
process.stdin.on('end', () => {
|
|
224
|
+
if (!skipping)
|
|
225
|
+
dispatch(chunks);
|
|
226
|
+
if (!initialized)
|
|
227
|
+
exitAsNoKey(); // empty stdin, or an end before any initialize: no MCP host ever spoke
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=keyless-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyless-server.js","sourceRoot":"","sources":["../src/keyless-server.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAYH,kDASC;AAwBD,oCAeC;AAED,wDAOC;AAGD,0CAyHC;AA/LD,mCAA0C;AAS1C,0DAA0D;AAC1D,SAAgB,mBAAmB,CAAC,KAA8B;IAChE,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW;QAC/B,CAAC,CAAC,+DAA+D,KAAK,CAAC,WAAW,GAAG;QACrF,CAAC,CAAC,2DAA2D,KAAK,CAAC,SAAS,aAAa,KAAK,CAAC,eAAe,yDAAyD,CAAC;IAC1K,OAAO,uFAAuF;UAC1F,iDAAiD;UACjD,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,6KAA6K,CAAC;UACxM,OAAO;UACP,wCAAwC,CAAC;AAC/C,CAAC;AAUY,QAAA,cAAc,GAAG,+JAA+J,CAAC;AAE9L,oHAAoH;AACpH,sGAAsG;AACtG,MAAM,6BAA6B,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AACnE,MAAM,wBAAwB,GAAG,YAAY,CAAC;AAC9C,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnC;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,QAAiB,EAAE,IAAwB,EAAE,GAAuC;IAC/G,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACzF,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACpE,MAAM,MAAM,GAAG,QAAmC,CAAC;QACnD,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACrI,2HAA2H;QAC3H,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACxG,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,0BAA0B,CAAC;QAC7D,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9C,IAAA,uBAAe,EAAC,OAAO,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAgB,sBAAsB,CAAC,MAAe;IACpD,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAiC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7F,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAuC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1I,MAAM,SAAS,GAAG,OAAO,MAAM,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3F,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,IAAI,OAAO,YAAY,CAAC,WAAW,KAAK,QAAQ,CAAC;WAC5F,6BAA6B,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvD,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,wBAAwB,CAAC;AACxD,CAAC;AAED,mIAAmI;AACnI,SAAgB,eAAe,CAAC,aAAqB,EAAE,KAAmB;IACxE,MAAM,GAAG,GAAG,CAAC,MAAc,EAAE,GAAW,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/F,MAAM,IAAI,GAAG,CAAC,EAAW,EAAE,IAA6B,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;IAC1I,MAAM,MAAM,GAAG,CAAC,EAAW,EAAE,IAAY,EAAE,OAAe,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACtG,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,yEAAyE;IACzE,SAAS,WAAW;QAClB,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gIAAgI;IAChI,SAAS,QAAQ,CAAC,EAAW,EAAE,IAAY,EAAE,OAAe;QAC1D,IAAI,CAAC,WAAW;YAAE,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED,SAAS,MAAM,CAAC,IAAY;QAC1B,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,GAA8B,CAAC;QAC/C,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpE,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;YAAE,OAAO,CAAC,+BAA+B;QAChE,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YACpC,WAAW,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,kCAAkC;YACpC,CAAC;YACD,IAAI,CAAC,EAAE,EAAE;gBACP,MAAM,EAAE;oBACN,eAAe,EAAE,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC;oBACvD,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE;oBAC/C,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;oBACtD,YAAY,EAAE,KAAK,CAAC,YAAY;iBACjC;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,gDAAgD,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QACD,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,MAAM;gBAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO;YAC9C,KAAK,YAAY;gBAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO;YAC/D,KAAK,cAAc;gBAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO;YACnE,KAAK,gBAAgB;gBAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO;YACvE,KAAK,0BAA0B;gBAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO;YACzF,KAAK,YAAY;gBAAE,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;gBAAC,OAAO;YAC3E,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,SAAS,QAAQ,CAAC,MAAgB;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO;QACzB,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,MAAM,GAAa,EAAE,CAAC;IAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,QAAQ,GAAG,KAAK,CAAC,CAAC,+EAA+E;IACrG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAqB,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1E,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACxC,MAAM,EAAE,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC;gBAClB,IAAI,IAAI,GAAG,cAAc,EAAE,CAAC;oBAC1B,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM,GAAG,EAAE,CAAC;oBACZ,IAAI,GAAG,CAAC,CAAC;oBACT,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;gBAC/C,CAAC;qBAAM,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;oBACrB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,CAAC;gBAAE,OAAO;YAC3B,IAAI,CAAC,QAAQ;gBAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,GAAG,EAAE,CAAC;YACZ,IAAI,GAAG,CAAC,CAAC;YACT,QAAQ,GAAG,KAAK,CAAC;YACjB,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QAC3B,IAAI,CAAC,QAAQ;YAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,WAAW;YAAE,WAAW,EAAE,CAAC,CAAC,uEAAuE;IAC1G,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -8,8 +8,14 @@
|
|
|
8
8
|
* names of a shell command, the file paths of an edit (the home directory as
|
|
9
9
|
* `~`, another user's home as `/home/[user]`), a SHA-256 of the
|
|
10
10
|
* command or tool input, and `truncated: true` when that hash could not cover
|
|
11
|
-
* everything that decides what the action does. The
|
|
12
|
-
*
|
|
11
|
+
* everything that decides what the action does. The tool input is never sent.
|
|
12
|
+
* The command text is never sent, with one exception: a shell command that is
|
|
13
|
+
* word for word one of the deploy grammars (deployCommandText: one clause of
|
|
14
|
+
* plain ASCII words, an optional launcher, the deploy tool and subcommand, at
|
|
15
|
+
* most one environment flag with a DEPLOY_ENV_VALUE value, nothing else, and
|
|
16
|
+
* no secret replaced) is also sent as `tool_input.command`, exactly as typed
|
|
17
|
+
* (for example `sst deploy --stage production`), so the service can judge the
|
|
18
|
+
* deploy target. Every other command sends only its hash.
|
|
13
19
|
*
|
|
14
20
|
* Before hashing, a normalized form is built (whitespace and quoting
|
|
15
21
|
* normalized) in which:
|
|
@@ -39,9 +45,12 @@
|
|
|
39
45
|
* - Data a command reads (text echoed or printed into a pipe or a file,
|
|
40
46
|
* heredoc bodies, here-strings) and the values of other environment
|
|
41
47
|
* assignments and env-store settings (`env:set`, `config:set`, `variables
|
|
42
|
-
* set`) are replaced by a SHA-256 of the data when the data
|
|
43
|
-
*
|
|
44
|
-
*
|
|
48
|
+
* set`) are replaced by a SHA-256 of the data when the data does not feed
|
|
49
|
+
* a secrets command or a secrets file: different data gives a different
|
|
50
|
+
* hash, the same data the same hash. Data that carries something
|
|
51
|
+
* secret-shaped is hashed with each secret replaced by `[secret]`
|
|
52
|
+
* (`[secret-data:…]`, truncated), so data that differs outside a secret
|
|
53
|
+
* still gives a different hash.
|
|
45
54
|
* - Anything else that may be a secret is replaced by `[secret]` and the
|
|
46
55
|
* action is marked `truncated: true`, so Marrow never binds an approval to
|
|
47
56
|
* it and always asks: data that feeds a secrets command (`… secret put`,
|
|
@@ -74,8 +83,12 @@ export type NormalizedHookAction = {
|
|
|
74
83
|
paths?: string[];
|
|
75
84
|
tool_input: {
|
|
76
85
|
command_sha256: string;
|
|
86
|
+
exact_hmac?: string;
|
|
77
87
|
} | {
|
|
78
88
|
input_sha256: string;
|
|
89
|
+
exact_hmac?: string;
|
|
90
|
+
} | {
|
|
91
|
+
exact_hmac: string;
|
|
79
92
|
} | Record<string, never>;
|
|
80
93
|
/** The hash could not cover everything that decides the action: Marrow never binds an approval to it. */
|
|
81
94
|
truncated?: true;
|
|
@@ -100,7 +113,7 @@ export declare function classifySecretName(name: string): NameClass;
|
|
|
100
113
|
* never sent. `truncated` is true when something that may change what the
|
|
101
114
|
* command does had to be withheld. Exported for tests.
|
|
102
115
|
*/
|
|
103
|
-
export declare function normalizeShellCommand(command: string, deadline?: number): {
|
|
116
|
+
export declare function normalizeShellCommand(command: string, deadline?: number, exact?: boolean): {
|
|
104
117
|
text: string;
|
|
105
118
|
programs: string[];
|
|
106
119
|
truncated: boolean;
|
|
@@ -116,6 +129,8 @@ export declare function normalizeShellCommand(command: string, deadline?: number
|
|
|
116
129
|
* word ever leaves the machine.
|
|
117
130
|
*/
|
|
118
131
|
export declare function deployCommandText(command: string): string | null;
|
|
132
|
+
/** runOptionsKey as a standalone identity (no deadline), for the exact target of a call (hook-contract exactHookTarget). */
|
|
133
|
+
export declare function shellToolRunOptionsKey(event: ToolEvent): string | null;
|
|
119
134
|
/**
|
|
120
135
|
* The normalized action of a hook event. `deadlineAt` bounds the time it may
|
|
121
136
|
* take (default one second from now): past it, or past the size limits, the
|
|
@@ -123,9 +138,19 @@ export declare function deployCommandText(command: string): string | null;
|
|
|
123
138
|
* service never binds, so the hook still answers within its host's budget.
|
|
124
139
|
* An event whose input a host adapter cut or dropped (`input_truncated`) is
|
|
125
140
|
* marked truncated as well.
|
|
141
|
+
*
|
|
142
|
+
* A truncated action also carries `tool_input.exact_hmac`: a keyed hash (the
|
|
143
|
+
* device salt never leaves the machine) of the action with only certain
|
|
144
|
+
* credentials replaced, so two actions that differ anywhere else never share a
|
|
145
|
+
* correlation, hold or key, and a retry that differs only in a certain
|
|
146
|
+
* credential (an OTP) still does. A placeholder keys the raw input (up to
|
|
147
|
+
* 1 MB). Input a host adapter cut or dropped, input over 1 MB and a missing or
|
|
148
|
+
* unsafe salt give a random nonce: the action matches nothing (it is asked
|
|
149
|
+
* again). `salt` is a test seam (undefined: the device salt).
|
|
126
150
|
*/
|
|
127
151
|
export declare function normalizedHookAction(event: ToolEvent, options?: {
|
|
128
152
|
deadlineAt?: number;
|
|
153
|
+
salt?: Buffer | null;
|
|
129
154
|
}): NormalizedHookAction;
|
|
130
155
|
export {};
|
|
131
156
|
//# sourceMappingURL=normalized-action.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalized-action.d.ts","sourceRoot":"","sources":["../src/normalized-action.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"normalized-action.d.ts","sourceRoot":"","sources":["../src/normalized-action.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7J,yGAAyG;IACzG,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB,CAAC;AAMF,yHAAyH;AACzH,eAAO,MAAM,cAAc,QAAS,CAAC;AAWrC,KAAK,SAAS,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA8C/D,4GAA4G;AAC5G,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUnD;AAgDD,KAAK,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAW1D;AAm5BD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAWjJ;AA4HD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyChE;AA2BD,4HAA4H;AAC5H,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAEtE;AAkLD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAAG,oBAAoB,CAgCxI"}
|