@getmarrow/mcp 3.9.103 → 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 +26 -5
- 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 +1677 -1636
- package/dist/cli.js.map +1 -1
- package/dist/codex-plugin-pins.d.ts.map +1 -1
- package/dist/codex-plugin-pins.js +18 -0
- package/dist/codex-plugin-pins.js.map +1 -1
- 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 +36 -3
- package/dist/hook-contract.js.map +1 -1
- package/dist/hook-pre-action.d.ts +38 -7
- package/dist/hook-pre-action.d.ts.map +1 -1
- package/dist/hook-pre-action.js +254 -21
- 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.map +1 -1
- package/dist/hook.js +5 -3
- 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/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- 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 +2 -0
- package/dist/normalized-action.d.ts.map +1 -1
- package/dist/normalized-action.js +65 -10
- package/dist/normalized-action.js.map +1 -1
- package/dist/own-server-identity.d.ts +22 -3
- package/dist/own-server-identity.d.ts.map +1 -1
- package/dist/own-server-identity.js +98 -27
- package/dist/own-server-identity.js.map +1 -1
- package/dist/own-tool.d.ts +14 -6
- package/dist/own-tool.d.ts.map +1 -1
- package/dist/own-tool.js +18 -7
- package/dist/own-tool.js.map +1 -1
- 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/hook.d.ts +21 -2
- package/dist/seatbelt/hook.d.ts.map +1 -1
- package/dist/seatbelt/hook.js +45 -11
- package/dist/seatbelt/hook.js.map +1 -1
- package/dist/seatbelt/mapper.d.ts.map +1 -1
- package/dist/seatbelt/mapper.js +360 -27
- package/dist/seatbelt/mapper.js.map +1 -1
- package/dist/seatbelt/tables.d.ts +1 -1
- package/dist/seatbelt/tables.d.ts.map +1 -1
- package/dist/seatbelt/tables.js +9 -16
- package/dist/seatbelt/tables.js.map +1 -1
- 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/package.json +2 -2
- package/server.json +2 -2
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Env-dump forms: every command an agent can type that prints many or all environment variables.
|
|
3
|
+
// One table for both modes: the keyless seatbelt mapper stops them (S4) and the keyed hook policy
|
|
4
|
+
// holds them (hook-tool-policy.ts asks the mapper and keeps only the reasons named here). Pure
|
|
5
|
+
// word-level predicates over literal arguments; no file contents are read.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ENV_PRINTER_COMMAND = exports.HELPER_ENV_VARS = exports.RECURSIVE_READERS = exports.PROC_PROCESS_DIRECTORY = exports.PROC_ENVIRON = exports.EXEC_WRAPPERS = exports.ENV_DUMP_REASONS = void 0;
|
|
8
|
+
exports.compgenListsVariables = compgenListsVariables;
|
|
9
|
+
exports.tmuxShowsEnvironment = tmuxShowsEnvironment;
|
|
10
|
+
exports.systemctlShowsEnvironment = systemctlShowsEnvironment;
|
|
11
|
+
exports.psPrintsEnvironment = psPrintsEnvironment;
|
|
12
|
+
exports.psLooselyPrintsEnvironment = psLooselyPrintsEnvironment;
|
|
13
|
+
exports.jqFilterReadsEnvironment = jqFilterReadsEnvironment;
|
|
14
|
+
exports.jqFilters = jqFilters;
|
|
15
|
+
exports.packageRunsEnvScript = packageRunsEnvScript;
|
|
16
|
+
exports.procGlobMatchesEnviron = procGlobMatchesEnviron;
|
|
17
|
+
exports.manPagerPrintsEnvironment = manPagerPrintsEnvironment;
|
|
18
|
+
exports.straceShowsEnvironment = straceShowsEnvironment;
|
|
19
|
+
exports.tmuxRunsEnvironmentPrinter = tmuxRunsEnvironmentPrinter;
|
|
20
|
+
/** S4 reasons that mean "prints the environment". The keyed hook keeps only these from a mapper run. */
|
|
21
|
+
exports.ENV_DUMP_REASONS = new Set([
|
|
22
|
+
'env_dump_env', 'env_dump_set', 'env_dump_export', 'env_dump_declare', 'env_dump_declare_secret', 'env_dump_readonly', 'env_dump_printenv',
|
|
23
|
+
'env_dump_printenv_secret', 'interpreter_env_dump', 'ps_environment', 'proc_environ', 'env_dump_compgen', 'env_dump_tmux', 'env_dump_systemctl',
|
|
24
|
+
'env_dump_jq', 'env_dump_strace', 'env_dump_php_info', 'env_dump_npm_run_env', 'tripwire_secret_dumper', 'echo_secret_var',
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Programs that run the command at the end of their argv with a grammar the mapper does not model. A bare `env` or
|
|
28
|
+
* `printenv` as their last word is that command, not a name (`python -m venv env` and `conda activate env` stay fine:
|
|
29
|
+
* those programs are not listed).
|
|
30
|
+
*/
|
|
31
|
+
exports.EXEC_WRAPPERS = new Set([
|
|
32
|
+
'setpriv', 'unshare', 'runuser', 'nsenter', 'chroot', 'fakeroot', 'fakeroot-sysv', 'fakechroot', 'systemd-run', 'firejail', 'bwrap', 'strace', 'ltrace',
|
|
33
|
+
'sg', 'proot', 'torsocks', 'proxychains', 'proxychains4', 'tsocks', 'xvfb-run', 'dbus-run-session', 'cross-env', 'env-cmd', 'dotenv', 'dotenvx', 'direnv',
|
|
34
|
+
'sandbox-exec', 'cgexec', 'sshpass', 'chronic', 'rlwrap',
|
|
35
|
+
]);
|
|
36
|
+
const letters = (text) => /^[a-zA-Z]+$/.test(text);
|
|
37
|
+
/** `compgen -e`, `-v`, `-A export` and `-A variable` list the names of the environment's variables. */
|
|
38
|
+
function compgenListsVariables(args) {
|
|
39
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
40
|
+
const a = args[i];
|
|
41
|
+
if (a === null)
|
|
42
|
+
continue;
|
|
43
|
+
if (a === '--')
|
|
44
|
+
return false;
|
|
45
|
+
if (/^-A./.test(a)) {
|
|
46
|
+
if (/^(?:export|variable)$/.test(a.slice(2)))
|
|
47
|
+
return true;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (a === '-A') {
|
|
51
|
+
const v = args[i + 1];
|
|
52
|
+
if (v === 'export' || v === 'variable')
|
|
53
|
+
return true;
|
|
54
|
+
i += 1;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (/^-[oGWFCXPS]$/.test(a)) {
|
|
58
|
+
i += 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (/^-[a-zA-Z]+$/.test(a) && /[ev]/.test(a.slice(1).replace(/[oGWFCXPS].*$/, '')))
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
/** tmux accepts any unambiguous prefix of a command name or alias: `show-e` and `showe` are show-environment. */
|
|
67
|
+
function tmuxShowEnvironmentWord(word) {
|
|
68
|
+
return (word.length >= 6 && 'show-environment'.startsWith(word)) || (word.length >= 5 && 'showenv'.startsWith(word));
|
|
69
|
+
}
|
|
70
|
+
/** `tmux [options] show-environment` (also `showenv`, a unique prefix, and a command after `\\;`) prints a session's variables. */
|
|
71
|
+
function tmuxShowsEnvironment(args) {
|
|
72
|
+
let i = 0;
|
|
73
|
+
// Global options come before the first command: -S, -L, -f, -c and -T take a value.
|
|
74
|
+
while (i < args.length && args[i] !== null && args[i].startsWith('-') && args[i] !== '-')
|
|
75
|
+
i += /^-[SLfcT]$/.test(args[i]) ? 2 : 1;
|
|
76
|
+
let commandStart = true;
|
|
77
|
+
for (; i < args.length; i += 1) {
|
|
78
|
+
const a = args[i];
|
|
79
|
+
if (a === ';' || a === '\\;') {
|
|
80
|
+
commandStart = true;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (a !== null && commandStart && tmuxShowEnvironmentWord(a))
|
|
84
|
+
return true;
|
|
85
|
+
commandStart = false;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
/** `systemctl [--user] show-environment` prints the manager's environment. */
|
|
90
|
+
function systemctlShowsEnvironment(args) {
|
|
91
|
+
return args.some((a) => a === 'show-environment');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* BSD `ps e`, `ps auxe`, `ps eww` and `ps -E` print every process's environment. A word of letters that holds `e`, or a dash
|
|
95
|
+
* cluster that holds `E`, outside the value of an option (`ps -p 1 -o etime` asks for a column, not the environment).
|
|
96
|
+
*/
|
|
97
|
+
function psPrintsEnvironment(args) {
|
|
98
|
+
const longWithValue = /^--(?:sort|pid|ppid|user|User|group|Group|tty|sid|format|cols|columns|width|lines|rows|quick-pid)$/;
|
|
99
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
100
|
+
const a = args[i];
|
|
101
|
+
if (a === null)
|
|
102
|
+
continue;
|
|
103
|
+
if (a.startsWith('--')) {
|
|
104
|
+
if (longWithValue.test(a))
|
|
105
|
+
i += 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (/^-[a-zA-Z]+$/.test(a)) {
|
|
109
|
+
for (let k = 1; k < a.length; k += 1) {
|
|
110
|
+
if (a[k] === 'E')
|
|
111
|
+
return true;
|
|
112
|
+
if ('oOpquUgGstCnND'.includes(a[k])) {
|
|
113
|
+
if (k === a.length - 1)
|
|
114
|
+
i += 1;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (letters(a)) {
|
|
121
|
+
for (let k = 0; k < a.length; k += 1) {
|
|
122
|
+
if (a[k] === 'e')
|
|
123
|
+
return true;
|
|
124
|
+
if ('oOpqUgGstCnND'.includes(a[k])) {
|
|
125
|
+
if (k === a.length - 1)
|
|
126
|
+
i += 1;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
/** The older, looser reading of `ps`: any word of letters that holds `e`, option values included. The keyless seatbelt keeps stopping it. */
|
|
135
|
+
function psLooselyPrintsEnvironment(args) {
|
|
136
|
+
return args.some((a) => a !== null && letters(a) && a.includes('e'));
|
|
137
|
+
}
|
|
138
|
+
/** The environment object in a jq filter: `env`, `$ENV` (not a `.env` field, a key, or text in a string). */
|
|
139
|
+
function jqFilterReadsEnvironment(filter) {
|
|
140
|
+
const code = filter.replace(/"(?:[^"\\]|\\.)*"/g, '""');
|
|
141
|
+
return /\$ENV\b/.test(code) || /(?<![.$\w])env\b(?!\s*[:,}])/.test(code);
|
|
142
|
+
}
|
|
143
|
+
/** The filter of a jq command line: the first word that is not an option or an option's value. With -f the program is a file: none. */
|
|
144
|
+
function jqFilters(args) {
|
|
145
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
146
|
+
const a = args[i];
|
|
147
|
+
if (a === null)
|
|
148
|
+
continue;
|
|
149
|
+
if (a === '--arg' || a === '--argjson' || a === '--slurpfile' || a === '--rawfile') {
|
|
150
|
+
i += 2;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (a === '--indent') {
|
|
154
|
+
i += 1;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (a === '--from-file' || /^-[a-zA-Z]*f$/.test(a))
|
|
158
|
+
return [];
|
|
159
|
+
if (a.startsWith('-') && a !== '-')
|
|
160
|
+
continue;
|
|
161
|
+
return [a];
|
|
162
|
+
}
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
const RUN_SCRIPT_WORDS = new Set(['run', 'run-script', 'rum', 'urn']);
|
|
166
|
+
/** `npm run env` (also pnpm, yarn and bun) runs npm's built-in `env` script, which prints the environment. */
|
|
167
|
+
function packageRunsEnvScript(args) {
|
|
168
|
+
const at = args.findIndex((a) => a !== null && RUN_SCRIPT_WORDS.has(a));
|
|
169
|
+
if (at < 0)
|
|
170
|
+
return false;
|
|
171
|
+
for (let i = at + 1; i < args.length; i += 1) {
|
|
172
|
+
const a = args[i];
|
|
173
|
+
if (a === null)
|
|
174
|
+
return false;
|
|
175
|
+
if (a.startsWith('-')) {
|
|
176
|
+
if (a === '--prefix' || a === '-C' || a === '--workspace' || a === '-w' || a === '--cwd')
|
|
177
|
+
i += 1;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
return a === 'env';
|
|
181
|
+
}
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
var secret_paths_1 = require("../secret-paths");
|
|
185
|
+
Object.defineProperty(exports, "PROC_ENVIRON", { enumerable: true, get: function () { return secret_paths_1.PROC_ENVIRON; } });
|
|
186
|
+
/** A glob that can name `environ`: `/proc/self/env*`, `/proc/1/*`, `/proc/self/task/1/e[n]viron`. */
|
|
187
|
+
function procGlobMatchesEnviron(path) {
|
|
188
|
+
const m = /^\/proc\/[^/]+\/(?:task\/[^/]+\/)?([^/]*[*?[][^/]*)$/.exec(path);
|
|
189
|
+
if (!m)
|
|
190
|
+
return false;
|
|
191
|
+
let source = '';
|
|
192
|
+
for (let i = 0; i < m[1].length; i += 1) {
|
|
193
|
+
const ch = m[1][i];
|
|
194
|
+
if (ch === '*')
|
|
195
|
+
source += '.*';
|
|
196
|
+
else if (ch === '?')
|
|
197
|
+
source += '.';
|
|
198
|
+
else if (ch === '[') {
|
|
199
|
+
const end = m[1].indexOf(']', i + 2);
|
|
200
|
+
if (end < 0)
|
|
201
|
+
return true;
|
|
202
|
+
const body = m[1].slice(i + 1, end).replace(/^[!^]/, '');
|
|
203
|
+
source += `[${body.replace(/[\\\]^]/g, '\\$&')}]`;
|
|
204
|
+
i = end;
|
|
205
|
+
}
|
|
206
|
+
else
|
|
207
|
+
source += ch.replace(/[.+^${}()|\\]/g, '\\$&');
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
return new RegExp(`^${source}$`).test('environ');
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/** `/proc`, `/proc/<pid>` and `/proc/<pid>/task[/<tid>]`: a folder whose recursive read reaches every `environ` under it. */
|
|
217
|
+
exports.PROC_PROCESS_DIRECTORY = /^\/proc(?:\/[^/]+(?:\/task(?:\/[^/]+)?)?)?\/?$/;
|
|
218
|
+
/** Programs that read or copy every file under a folder named to them. */
|
|
219
|
+
exports.RECURSIVE_READERS = new Set(['grep', 'egrep', 'fgrep', 'rg', 'ag', 'ack', 'tar', 'gtar', 'bsdtar', 'cp', 'rsync', 'zip', 'scp']);
|
|
220
|
+
/** Variables whose value runs as a command: a pager, editor, askpass or diff helper set to `env` prints the environment. */
|
|
221
|
+
exports.HELPER_ENV_VARS = new Set(['PAGER', 'GIT_PAGER', 'MANPAGER', 'EDITOR', 'VISUAL', 'GIT_EDITOR', 'GIT_SEQUENCE_EDITOR', 'GIT_EXTERNAL_DIFF',
|
|
222
|
+
'GIT_SSH_COMMAND', 'GIT_SSH', 'GIT_ASKPASS', 'SSH_ASKPASS', 'BROWSER', 'LESSOPEN', 'GIT_PROXY_COMMAND', 'PROMPT_COMMAND']);
|
|
223
|
+
/** A command word that is the environment printer, alone or followed by arguments. */
|
|
224
|
+
exports.ENV_PRINTER_COMMAND = /^\s*(?:\S*\/)?(?:env|printenv)(?:\s|$)/;
|
|
225
|
+
/** `man -P env`, `man --pager=printenv`: the pager is the command. */
|
|
226
|
+
function manPagerPrintsEnvironment(args) {
|
|
227
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
228
|
+
const a = args[i];
|
|
229
|
+
if (a === null)
|
|
230
|
+
continue;
|
|
231
|
+
if ((a === '-P' || a === '--pager') && args[i + 1] != null && exports.ENV_PRINTER_COMMAND.test(args[i + 1]))
|
|
232
|
+
return true;
|
|
233
|
+
const m = /^(?:--pager=|-P)([\s\S]+)$/.exec(a);
|
|
234
|
+
if (m && exports.ENV_PRINTER_COMMAND.test(m[1]))
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
/** strace shows the whole environment of an exec it traces unless its strings are abbreviated: `-v`, `--no-abbrev`, `-e abbrev=none`, `-e verbose=...`. */
|
|
240
|
+
function straceShowsEnvironment(args) {
|
|
241
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
242
|
+
const a = args[i];
|
|
243
|
+
if (a === null)
|
|
244
|
+
continue;
|
|
245
|
+
if (a === '--')
|
|
246
|
+
return false;
|
|
247
|
+
if (a === '--no-abbrev')
|
|
248
|
+
return true;
|
|
249
|
+
if (a === '-e' || a === '--trace' || a === '--abbrev' || a === '--verbose') {
|
|
250
|
+
if (/(?:abbrev\s*=\s*none|verbose)/.test(String(args[i + 1] ?? '')))
|
|
251
|
+
return true;
|
|
252
|
+
i += a === '-e' || a === '--trace' ? 1 : 0;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (/^-e./.test(a)) {
|
|
256
|
+
if (/(?:abbrev\s*=\s*none|verbose)/.test(a))
|
|
257
|
+
return true;
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (/^-[a-zA-Z]+$/.test(a)) {
|
|
261
|
+
for (let k = 1; k < a.length; k += 1) {
|
|
262
|
+
if (a[k] === 'v')
|
|
263
|
+
return true;
|
|
264
|
+
if ('eopsEuOSabPIUX'.includes(a[k])) {
|
|
265
|
+
if (k === a.length - 1)
|
|
266
|
+
i += 1;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (!a.startsWith('-'))
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
const TMUX_COMMAND_VALUE_FLAGS = {
|
|
278
|
+
'send-keys': 'tNc', send: 'tNc', 'run-shell': 'cdt', run: 'cdt', 'new-session': 'cefFnstxy', new: 'cefFnstxy', 'new-window': 'cenFt', neww: 'cenFt',
|
|
279
|
+
'split-window': 'ceFltp', splitw: 'ceFltp', 'respawn-pane': 'cet', respawnp: 'cet', 'respawn-window': 'cet', respawnw: 'cet', 'pipe-pane': 't', pipep: 't',
|
|
280
|
+
'if-shell': 't', if: 't',
|
|
281
|
+
};
|
|
282
|
+
/** `tmux send-keys env Enter`, `tmux new -d printenv`, `tmux run-shell env`: a command window or pane runs the environment printer. */
|
|
283
|
+
function tmuxRunsEnvironmentPrinter(args) {
|
|
284
|
+
let i = 0;
|
|
285
|
+
while (i < args.length && args[i] !== null && args[i].startsWith('-') && args[i] !== '-')
|
|
286
|
+
i += /^-[SLfcT]$/.test(args[i]) ? 2 : 1;
|
|
287
|
+
const name = args[i];
|
|
288
|
+
if (name === null || name === undefined || !(name in TMUX_COMMAND_VALUE_FLAGS))
|
|
289
|
+
return false;
|
|
290
|
+
const valueFlags = TMUX_COMMAND_VALUE_FLAGS[name];
|
|
291
|
+
for (i += 1; i < args.length; i += 1) {
|
|
292
|
+
const a = args[i];
|
|
293
|
+
if (a === null)
|
|
294
|
+
continue;
|
|
295
|
+
if (a === ';' || a === '\\;')
|
|
296
|
+
return false;
|
|
297
|
+
if (/^-[a-zA-Z]$/.test(a) && valueFlags.includes(a[1])) {
|
|
298
|
+
i += 1;
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
if (a.startsWith('-') && a.length > 1)
|
|
302
|
+
continue;
|
|
303
|
+
if (/^(?:\S*\/)?(?:env|printenv)$/.test(a))
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=env-dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-dump.js","sourceRoot":"","sources":["../../src/seatbelt/env-dump.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** The reason codes of the resolver that can explain a fallback, in the order the text picks one. */
|
|
2
|
+
declare const REASON_ORDER: readonly ["strict", "key_rejected", "home_unknown", "home_unusable", "env_home_unusable", "home_mismatch", "evidence_unknown"];
|
|
3
|
+
export type FallbackReason = typeof REASON_ORDER[number];
|
|
4
|
+
export declare const FALLBACK_OTHER = "setup_unconfirmed";
|
|
5
|
+
/** The one code that explains the fallback: the first of the resolver's reasons in the fixed order, else the generic code. */
|
|
6
|
+
export declare function pickFallbackReason(reasons: unknown): FallbackReason | typeof FALLBACK_OTHER;
|
|
7
|
+
/** The sentence both fallback texts share. Fixed words only: no path, value or user name. */
|
|
8
|
+
export declare function fallbackSentence(code?: string | null): string;
|
|
9
|
+
/** The code printed after "Code:" / "mode:" for a pick. */
|
|
10
|
+
export declare function fallbackCode(code?: string | null): string;
|
|
11
|
+
/** The hold text for a protected action when the fallback is on and the seatbelt did not answer. */
|
|
12
|
+
export declare function setupUnconfirmedText(code?: string | null): string;
|
|
13
|
+
/** Every hold text setupUnconfirmedText can return: one per row of the table, generated from it and from no input. */
|
|
14
|
+
export declare function setupUnconfirmedTexts(): string[];
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=fallback-copy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback-copy.d.ts","sourceRoot":"","sources":["../../src/seatbelt/fallback-copy.ts"],"names":[],"mappings":"AAOA,qGAAqG;AACrG,QAAA,MAAM,YAAY,gIAAiI,CAAC;AACpJ,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,cAAc,sBAAsB,CAAC;AA0BlD,8HAA8H;AAC9H,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,OAAO,cAAc,CAI3F;AAMD,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAG7D;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEzD;AAED,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEjE;AAED,sHAAsH;AACtH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Words for the keyless fallback: why a machine without a key is in the stricter `claimed_no_key`
|
|
3
|
+
// mode with no sign of an account, and what the person at the machine can do about it.
|
|
4
|
+
//
|
|
5
|
+
// Text only. The mode itself is decided by resolveSeatbeltMode() (src/seatbelt-mode.ts); this module
|
|
6
|
+
// reads the reason codes it already computed and never changes a mode or a decision. A resolution
|
|
7
|
+
// without a known reason gets the generic row (code `setup_unconfirmed`).
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FALLBACK_OTHER = void 0;
|
|
10
|
+
exports.pickFallbackReason = pickFallbackReason;
|
|
11
|
+
exports.fallbackSentence = fallbackSentence;
|
|
12
|
+
exports.fallbackCode = fallbackCode;
|
|
13
|
+
exports.setupUnconfirmedText = setupUnconfirmedText;
|
|
14
|
+
exports.setupUnconfirmedTexts = setupUnconfirmedTexts;
|
|
15
|
+
/** The reason codes of the resolver that can explain a fallback, in the order the text picks one. */
|
|
16
|
+
const REASON_ORDER = ['strict', 'key_rejected', 'home_unknown', 'home_unusable', 'env_home_unusable', 'home_mismatch', 'evidence_unknown'];
|
|
17
|
+
exports.FALLBACK_OTHER = 'setup_unconfirmed';
|
|
18
|
+
const DOCTOR = 'npx -y @getmarrow/install@latest doctor';
|
|
19
|
+
const REASON_TEXT = {
|
|
20
|
+
strict: 'MARROW_SEATBELT_STRICT=1 is set',
|
|
21
|
+
key_rejected: 'the Marrow key on this machine was rejected',
|
|
22
|
+
home_unknown: 'it cannot find your login home folder (common in containers that run as a user with no home)',
|
|
23
|
+
home_unusable: 'your login home folder is missing, is not a folder, or is /',
|
|
24
|
+
env_home_unusable: 'HOME points to a folder that is missing, is not a folder, or is /',
|
|
25
|
+
home_mismatch: 'HOME is not your login home folder',
|
|
26
|
+
evidence_unknown: 'a folder or file it checks (your home folder, ~/.marrow, or an agent folder such as ~/.claude) belongs to another user, can be written by other users, or could not be read',
|
|
27
|
+
[exports.FALLBACK_OTHER]: 'it could not confirm this machine\'s setup',
|
|
28
|
+
};
|
|
29
|
+
const FIX_TEXT = {
|
|
30
|
+
strict: 'unset MARROW_SEATBELT_STRICT',
|
|
31
|
+
key_rejected: `run ${DOCTOR}`,
|
|
32
|
+
home_unknown: 'run the agent as a user that has a home folder',
|
|
33
|
+
home_unusable: 'give this user a real home folder',
|
|
34
|
+
env_home_unusable: 'set HOME to your login home folder',
|
|
35
|
+
home_mismatch: 'start the agent with HOME set to your login home folder',
|
|
36
|
+
evidence_unknown: 'make sure your home folder, ~/.marrow and your agent folders (such as ~/.claude) belong to you and can be read, then run chmod go-w on them',
|
|
37
|
+
[exports.FALLBACK_OTHER]: `run ${DOCTOR}`,
|
|
38
|
+
};
|
|
39
|
+
/** The one code that explains the fallback: the first of the resolver's reasons in the fixed order, else the generic code. */
|
|
40
|
+
function pickFallbackReason(reasons) {
|
|
41
|
+
if (!Array.isArray(reasons))
|
|
42
|
+
return exports.FALLBACK_OTHER;
|
|
43
|
+
for (const code of REASON_ORDER)
|
|
44
|
+
if (reasons.includes(code))
|
|
45
|
+
return code;
|
|
46
|
+
return exports.FALLBACK_OTHER;
|
|
47
|
+
}
|
|
48
|
+
function known(code) {
|
|
49
|
+
return typeof code === 'string' && Object.prototype.hasOwnProperty.call(REASON_TEXT, code) ? code : exports.FALLBACK_OTHER;
|
|
50
|
+
}
|
|
51
|
+
/** The sentence both fallback texts share. Fixed words only: no path, value or user name. */
|
|
52
|
+
function fallbackSentence(code) {
|
|
53
|
+
const picked = known(code);
|
|
54
|
+
return `Marrow uses its stricter no-key mode here because ${REASON_TEXT[picked]}. Fix (for the person at this machine, not the agent): ${FIX_TEXT[picked]}, or add a Marrow key (getmarrow.ai/docs#start-here).`;
|
|
55
|
+
}
|
|
56
|
+
/** The code printed after "Code:" / "mode:" for a pick. */
|
|
57
|
+
function fallbackCode(code) {
|
|
58
|
+
return known(code);
|
|
59
|
+
}
|
|
60
|
+
/** The hold text for a protected action when the fallback is on and the seatbelt did not answer. */
|
|
61
|
+
function setupUnconfirmedText(code) {
|
|
62
|
+
return `Marrow stopped this action: there is no Marrow key on this machine, and ${fallbackSentence(code)} Agent: do not retry it another way and do not edit Marrow settings; tell the user why it was stopped. Code: ${fallbackCode(code)}.`;
|
|
63
|
+
}
|
|
64
|
+
/** Every hold text setupUnconfirmedText can return: one per row of the table, generated from it and from no input. */
|
|
65
|
+
function setupUnconfirmedTexts() {
|
|
66
|
+
return Object.keys(REASON_TEXT).map((code) => setupUnconfirmedText(code));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=fallback-copy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback-copy.js","sourceRoot":"","sources":["../../src/seatbelt/fallback-copy.ts"],"names":[],"mappings":";AAAA,kGAAkG;AAClG,uFAAuF;AACvF,EAAE;AACF,qGAAqG;AACrG,kGAAkG;AAClG,0EAA0E;;;AAiC1E,gDAIC;AAOD,4CAGC;AAGD,oCAEC;AAGD,oDAEC;AAGD,sDAEC;AA5DD,qGAAqG;AACrG,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,kBAAkB,CAAU,CAAC;AAGvI,QAAA,cAAc,GAAG,mBAAmB,CAAC;AAElD,MAAM,MAAM,GAAG,yCAAyC,CAAC;AAEzD,MAAM,WAAW,GAA2D;IAC1E,MAAM,EAAE,iCAAiC;IACzC,YAAY,EAAE,6CAA6C;IAC3D,YAAY,EAAE,8FAA8F;IAC5G,aAAa,EAAE,6DAA6D;IAC5E,iBAAiB,EAAE,mEAAmE;IACtF,aAAa,EAAE,oCAAoC;IACnD,gBAAgB,EAAE,6KAA6K;IAC/L,CAAC,sBAAc,CAAC,EAAE,4CAA4C;CAC/D,CAAC;AAEF,MAAM,QAAQ,GAA2D;IACvE,MAAM,EAAE,8BAA8B;IACtC,YAAY,EAAE,OAAO,MAAM,EAAE;IAC7B,YAAY,EAAE,gDAAgD;IAC9D,aAAa,EAAE,mCAAmC;IAClD,iBAAiB,EAAE,oCAAoC;IACvD,aAAa,EAAE,yDAAyD;IACxE,gBAAgB,EAAE,6IAA6I;IAC/J,CAAC,sBAAc,CAAC,EAAE,OAAO,MAAM,EAAE;CAClC,CAAC;AAEF,8HAA8H;AAC9H,SAAgB,kBAAkB,CAAC,OAAgB;IACjD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,sBAAc,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,YAAY;QAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACzE,OAAO,sBAAc,CAAC;AACxB,CAAC;AAED,SAAS,KAAK,CAAC,IAAa;IAC1B,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAsB,CAAC,CAAC,CAAC,sBAAc,CAAC;AACvI,CAAC;AAED,6FAA6F;AAC7F,SAAgB,gBAAgB,CAAC,IAAoB;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,qDAAqD,WAAW,CAAC,MAAM,CAAC,0DAA0D,QAAQ,CAAC,MAAM,CAAC,uDAAuD,CAAC;AACnN,CAAC;AAED,2DAA2D;AAC3D,SAAgB,YAAY,CAAC,IAAoB;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,oGAAoG;AACpG,SAAgB,oBAAoB,CAAC,IAAoB;IACvD,OAAO,2EAA2E,gBAAgB,CAAC,IAAI,CAAC,gHAAgH,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;AAChP,CAAC;AAED,sHAAsH;AACtH,SAAgB,qBAAqB;IACnC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
package/dist/seatbelt/hook.d.ts
CHANGED
|
@@ -16,9 +16,11 @@ export declare const CLAIMED_NO_KEY_TEXT = "Marrow is linked to an account but h
|
|
|
16
16
|
* `claimed_no_key` with no account evidence and no rejected key: a fallback because the machine's
|
|
17
17
|
* setup could not be confirmed (an evidence dir others can write, an unreadable probe, a home
|
|
18
18
|
* mismatch, strict mode). Same holds as CLAIMED_NO_KEY_TEXT, but it never claims an account exists.
|
|
19
|
+
* This constant is the generic wording; a hold names its reason (setupUnconfirmedText, fallback-copy.ts).
|
|
19
20
|
*/
|
|
20
|
-
export declare const SETUP_UNCONFIRMED_TEXT
|
|
21
|
-
|
|
21
|
+
export declare const SETUP_UNCONFIRMED_TEXT: string;
|
|
22
|
+
/** `modeReason`: the fixed code that explains a fallback (pickFallbackReason); only read when the machine is not account-linked. */
|
|
23
|
+
export declare function seatbeltStopText(category: string, rule: string, reason: string, mode: 'seatbelt' | 'claimed_no_key' | 'account', accountLinked?: boolean, modeReason?: string): string;
|
|
22
24
|
/** §4.2: an S0-S5 floor stop is lifted only by an enforced server allow (a verified permit); an advisory allow never lifts it. */
|
|
23
25
|
export declare function accountFloorStops(rollout: 'watch' | 'on', floor: Pick<SeatbeltDecision, 'decision'> | null, server: 'enforced_allow' | 'advisory_allow' | 'deny' | 'none'): boolean;
|
|
24
26
|
/** The mapper's file view over the host. Missing: null. A failure the mapper must not guess about throws (it stops on fs_error). */
|
|
@@ -49,9 +51,26 @@ export interface KeylessOutcome {
|
|
|
49
51
|
* the hook gives master's answer for that host instead of the seatbelt pass.
|
|
50
52
|
*/
|
|
51
53
|
recognized: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Why the machine is in the stricter fallback: one fixed code from the resolver's reasons, or
|
|
56
|
+
* `setup_unconfirmed`. Words only: it never changes the mode or a decision.
|
|
57
|
+
*/
|
|
58
|
+
modeReason: string;
|
|
52
59
|
}
|
|
53
60
|
/** The keyless branch of the hook: mode (U4), then the mapper (U2) with the U3 resolvers. Never throws. */
|
|
54
61
|
export declare function keylessSeatbelt(harness: string, event: SeatbeltHookEvent): KeylessOutcome;
|
|
62
|
+
export interface SeatbeltStatus {
|
|
63
|
+
mode: 'seatbelt' | 'claimed_no_key' | 'account';
|
|
64
|
+
reasons: string[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* What `marrow-mcp seatbelt-status` prints (the installer's doctor reads it): the mode this machine's
|
|
68
|
+
* hook would be in right now, from the same resolution the keyless hook runs (same key lookup, same
|
|
69
|
+
* rollout table), and the resolver's reason codes that are on a closed list. Reads only; writes no file
|
|
70
|
+
* or state, opens no connection, and names no key, path, user or environment value. Throws when the
|
|
71
|
+
* resolution does (the caller prints the unknown line).
|
|
72
|
+
*/
|
|
73
|
+
export declare function seatbeltStatus(): SeatbeltStatus;
|
|
55
74
|
/**
|
|
56
75
|
* The account floor. `watch`: computed after the answer, for the record only; it never throws and
|
|
57
76
|
* never writes output. `on` (not active): run before the server flow; a returned text is a stop.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/seatbelt/hook.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAe,UAAU,IAAI,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/seatbelt/hook.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAe,UAAU,IAAI,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACnG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,KAAK,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAA;CAGrG,CAAC;AAEH,qGAAqG;AACrG,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,eAAO,MAAM,mBAAmB,iHAAiH,CAAC;AAClJ;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAuC,CAAC;AA8B3E,oIAAoI;AACpI,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,EAAE,aAAa,UAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAQnL;AAED,kIAAkI;AAClI,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG,IAAI,EAChD,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAC5D,OAAO,CAGT;AAuBD,oIAAoI;AACpI,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,QAAQ,CA+BtD;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,WAAW,CA6ElG;AAcD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,4GAA4G;IAC5G,GAAG,EAAE,OAAO,CAAC;IACb,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6BD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oHAAoH;IACpH,aAAa,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,2GAA2G;AAC3G,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,cAAc,CAiCzF;AAKD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAM/C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwBzG;AAKD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;CAAE,CAmBlI"}
|
package/dist/seatbelt/hook.js
CHANGED
|
@@ -6,8 +6,10 @@ exports.accountFloorStops = accountFloorStops;
|
|
|
6
6
|
exports.hostMapperFs = hostMapperFs;
|
|
7
7
|
exports.hostSeatbeltGit = hostSeatbeltGit;
|
|
8
8
|
exports.keylessSeatbelt = keylessSeatbelt;
|
|
9
|
+
exports.seatbeltStatus = seatbeltStatus;
|
|
9
10
|
exports.accountFloor = accountFloor;
|
|
10
11
|
exports.outageRisk = outageRisk;
|
|
12
|
+
const fallback_copy_1 = require("./fallback-copy");
|
|
11
13
|
/**
|
|
12
14
|
* Compiled-in rollout table. Not env, not a file: changing a value is a one-line, reviewed code
|
|
13
15
|
* change. `keyless: 'off'` makes every keyless machine `claimed_no_key` (3.9.103 holds plus the
|
|
@@ -24,14 +26,15 @@ exports.CLAIMED_NO_KEY_TEXT = 'Marrow is linked to an account but has no working
|
|
|
24
26
|
* `claimed_no_key` with no account evidence and no rejected key: a fallback because the machine's
|
|
25
27
|
* setup could not be confirmed (an evidence dir others can write, an unreadable probe, a home
|
|
26
28
|
* mismatch, strict mode). Same holds as CLAIMED_NO_KEY_TEXT, but it never claims an account exists.
|
|
29
|
+
* This constant is the generic wording; a hold names its reason (setupUnconfirmedText, fallback-copy.ts).
|
|
27
30
|
*/
|
|
28
|
-
exports.SETUP_UNCONFIRMED_TEXT =
|
|
31
|
+
exports.SETUP_UNCONFIRMED_TEXT = (0, fallback_copy_1.setupUnconfirmedText)(fallback_copy_1.FALLBACK_OTHER);
|
|
29
32
|
const LABELS = {
|
|
30
33
|
S0: 'a change to Marrow seatbelt settings or an owner-only command',
|
|
31
34
|
S1: 'force-push or delete of a protected branch',
|
|
32
35
|
S2: 'production deploy',
|
|
33
36
|
S3: 'package publish',
|
|
34
|
-
S4: '
|
|
37
|
+
S4: 'reading, copying or writing secrets (like .env files or private keys)',
|
|
35
38
|
S5: 'recursive delete outside the workspace',
|
|
36
39
|
Sx: 'obfuscated execution',
|
|
37
40
|
hook: 'a safety check that could not finish',
|
|
@@ -40,14 +43,26 @@ const CODE = /^[A-Za-z0-9_.:-]{1,64}$/;
|
|
|
40
43
|
function codes(list) {
|
|
41
44
|
return Array.isArray(list) ? list.filter((item) => typeof item === 'string' && CODE.test(item)).slice(0, 16) : [];
|
|
42
45
|
}
|
|
43
|
-
|
|
46
|
+
/** What the agent and the person read after the label, in every stop. */
|
|
47
|
+
const STOP_ADVICE = 'If you (the person at this machine) meant it, run it yourself in your own terminal. Agent: do not retry it another way and do not edit Marrow settings; tell the user it was stopped.';
|
|
48
|
+
/** Keyless (no account): the way to approval prompts. The plugin path is the one the plugin's own docs give. */
|
|
49
|
+
const KEYLESS_KEY_ADVICE = 'For approval prompts instead of stops, add a Marrow key: getmarrow.ai/docs#start-here (Claude Code plugin: put MARROW_API_KEY in ~/.marrow/env, chmod 600, then /reload-plugins).';
|
|
50
|
+
/** The label of a stop. A script Marrow could not read is named as such: it is not known to be what its name says. */
|
|
51
|
+
function stopLabel(category, reason) {
|
|
44
52
|
const label = LABELS[category] || LABELS.hook;
|
|
45
|
-
|
|
53
|
+
return reason === 'script_unreadable' ? `a script Marrow could not read (treated as ${label})` : label;
|
|
54
|
+
}
|
|
55
|
+
/** `modeReason`: the fixed code that explains a fallback (pickFallbackReason); only read when the machine is not account-linked. */
|
|
56
|
+
function seatbeltStopText(category, rule, reason, mode, accountLinked = true, modeReason) {
|
|
57
|
+
const head = `MARROW SEATBELT stopped this action: ${stopLabel(category, reason)}. ${STOP_ADVICE}`;
|
|
58
|
+
const code = `Code: ${CODE.test(rule) ? rule : 'unknown'}/${CODE.test(reason) ? reason : 'unknown'}`;
|
|
46
59
|
if (mode === 'account')
|
|
47
|
-
return `${head}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
return `${head} ${code}.`;
|
|
61
|
+
if (mode === 'seatbelt')
|
|
62
|
+
return `${head} ${KEYLESS_KEY_ADVICE} ${code}.`;
|
|
63
|
+
return accountLinked
|
|
64
|
+
? `${head} ${exports.CLAIMED_NO_KEY_TEXT} ${code}.`
|
|
65
|
+
: `${head} ${(0, fallback_copy_1.fallbackSentence)(modeReason)} ${code}; mode: ${(0, fallback_copy_1.fallbackCode)(modeReason)}.`;
|
|
51
66
|
}
|
|
52
67
|
/** §4.2: an S0-S5 floor stop is lifted only by an enforced server allow (a verified permit); an advisory allow never lifts it. */
|
|
53
68
|
function accountFloorStops(rollout, floor, server) {
|
|
@@ -260,16 +275,19 @@ function keylessSeatbelt(harness, event) {
|
|
|
260
275
|
const started = Date.now();
|
|
261
276
|
let mode = 'claimed_no_key';
|
|
262
277
|
let accountLinked = false;
|
|
278
|
+
// A resolution that fails or has no reason keeps the generic code.
|
|
279
|
+
let modeReason = fallback_copy_1.FALLBACK_OTHER;
|
|
263
280
|
let trustedHome;
|
|
264
281
|
const stop = (reason) => {
|
|
265
282
|
record({ v: 1, mode, enforcement: 'enforce', harness, decision: 'stop', category: 'hook', rule: 'U5.fail_closed', reasons: [reason], flags: [], parse: 'unparsed', latency_ms: Date.now() - started }, event, trustedHome);
|
|
266
|
-
return { mode, accountLinked, recognized: true, stopText: seatbeltStopText('hook', 'U5.fail_closed', reason, mode, accountLinked) };
|
|
283
|
+
return { mode, accountLinked, recognized: true, modeReason, stopText: seatbeltStopText('hook', 'U5.fail_closed', reason, mode, accountLinked, modeReason) };
|
|
267
284
|
};
|
|
268
285
|
try {
|
|
269
286
|
const { resolveSeatbeltModeOnHost } = require('../seatbelt-mode');
|
|
270
287
|
const resolution = resolveSeatbeltModeOnHost();
|
|
271
288
|
mode = resolution.mode === 'seatbelt' && exports.SEATBELT_ROLLOUT.keyless === 'on' ? 'seatbelt' : 'claimed_no_key';
|
|
272
289
|
accountLinked = resolution.reasons.includes('account_evidence') || resolution.reasons.includes('key_rejected');
|
|
290
|
+
modeReason = (0, fallback_copy_1.pickFallbackReason)(resolution.reasons);
|
|
273
291
|
if (event.truncated)
|
|
274
292
|
return stop('input_truncated');
|
|
275
293
|
const home = resolution.homes[0] || passwdHome() || '/nonexistent-home';
|
|
@@ -284,13 +302,29 @@ function keylessSeatbelt(harness, event) {
|
|
|
284
302
|
reasons, flags: codes(decision.flags), parse: CODE.test(decision.parse) ? decision.parse : 'unknown', latency_ms: Date.now() - started,
|
|
285
303
|
}, event, home);
|
|
286
304
|
if (decision.decision === 'pass')
|
|
287
|
-
return { mode, accountLinked, recognized: decision.recognized === true, stopText: null };
|
|
288
|
-
return { mode, accountLinked, recognized: true, stopText: seatbeltStopText(decision.category, decision.rule, reasons[0] || 'unspecified', mode, accountLinked) };
|
|
305
|
+
return { mode, accountLinked, recognized: decision.recognized === true, modeReason, stopText: null };
|
|
306
|
+
return { mode, accountLinked, recognized: true, modeReason, stopText: seatbeltStopText(decision.category, decision.rule, reasons[0] || 'unspecified', mode, accountLinked, modeReason) };
|
|
289
307
|
}
|
|
290
308
|
catch {
|
|
291
309
|
return stop('hook_error');
|
|
292
310
|
}
|
|
293
311
|
}
|
|
312
|
+
/** The reason codes mode resolution can emit (src/seatbelt-mode.ts), the only ones the status line may print. */
|
|
313
|
+
const STATUS_REASONS = ['strict', 'key_rejected', 'home_unknown', 'home_unusable', 'env_home_unusable', 'home_mismatch', 'account_evidence', 'evidence_unknown'];
|
|
314
|
+
/**
|
|
315
|
+
* What `marrow-mcp seatbelt-status` prints (the installer's doctor reads it): the mode this machine's
|
|
316
|
+
* hook would be in right now, from the same resolution the keyless hook runs (same key lookup, same
|
|
317
|
+
* rollout table), and the resolver's reason codes that are on a closed list. Reads only; writes no file
|
|
318
|
+
* or state, opens no connection, and names no key, path, user or environment value. Throws when the
|
|
319
|
+
* resolution does (the caller prints the unknown line).
|
|
320
|
+
*/
|
|
321
|
+
function seatbeltStatus() {
|
|
322
|
+
const { resolveSeatbeltModeOnHost } = require('../seatbelt-mode');
|
|
323
|
+
const resolution = resolveSeatbeltModeOnHost({ argv: [] });
|
|
324
|
+
const mode = resolution.mode === 'seatbelt' && exports.SEATBELT_ROLLOUT.keyless !== 'on' ? 'claimed_no_key' : resolution.mode;
|
|
325
|
+
const reasons = STATUS_REASONS.filter((code) => resolution.reasons.includes(code));
|
|
326
|
+
return { mode, reasons };
|
|
327
|
+
}
|
|
294
328
|
/**
|
|
295
329
|
* The account floor. `watch`: computed after the answer, for the record only; it never throws and
|
|
296
330
|
* never writes output. `on` (not active): run before the server flow; a returned text is a stop.
|