@getmarrow/mcp 3.9.103 → 3.9.107
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 +43 -6
- 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 +43 -6
- package/dist/hook-contract.js.map +1 -1
- package/dist/hook-pre-action.d.ts +43 -7
- package/dist/hook-pre-action.d.ts.map +1 -1
- package/dist/hook-pre-action.js +518 -21
- package/dist/hook-pre-action.js.map +1 -1
- package/dist/hook-tool-policy.d.ts +86 -4
- package/dist/hook-tool-policy.d.ts.map +1 -1
- package/dist/hook-tool-policy.js +354 -21
- 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 +24 -0
- package/dist/host-approval-state.d.ts.map +1 -1
- package/dist/host-approval-state.js +68 -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 +11 -3
- package/dist/normalized-action.d.ts.map +1 -1
- package/dist/normalized-action.js +305 -49
- 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 +108 -31
- 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 +66 -0
- package/dist/seatbelt/env-dump.d.ts.map +1 -0
- package/dist/seatbelt/env-dump.js +333 -0
- package/dist/seatbelt/env-dump.js.map +1 -0
- package/dist/seatbelt/env-names.d.ts +22 -0
- package/dist/seatbelt/env-names.d.ts.map +1 -0
- package/dist/seatbelt/env-names.js +298 -0
- package/dist/seatbelt/env-names.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 +1592 -85
- 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 +13 -17
- package/dist/seatbelt/tables.js.map +1 -1
- package/dist/secret-paths.d.ts +40 -0
- package/dist/secret-paths.d.ts.map +1 -0
- package/dist/secret-paths.js +59 -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 +25 -6
- package/dist/session-loop-guard.js.map +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ENV_NAME_CORPUS = void 0;
|
|
4
|
+
exports.lastSegment = lastSegment;
|
|
5
|
+
exports.secretEnvBase = secretEnvBase;
|
|
6
|
+
exports.volumeHost = volumeHost;
|
|
7
|
+
exports.mountSources = mountSources;
|
|
8
|
+
exports.regexMatchesAny = regexMatchesAny;
|
|
9
|
+
// Secret env file names in the forms the mapper reads besides a plain operand: the host side of a container bind mount, the names a find primary matches
|
|
10
|
+
// and the names the stage in front of xargs lists. Pure string work (the mapper turns its words into these strings); no I/O, nothing from the command is
|
|
11
|
+
// ever run, and the one pattern language it reads (find -regex) is matched by a bounded matcher, never by a RegExp built from the command.
|
|
12
|
+
const tables_1 = require("./tables");
|
|
13
|
+
/** The basename of a path as written (the last segment, a trailing slash ignored). */
|
|
14
|
+
function lastSegment(text) {
|
|
15
|
+
const t = text.replace(/\/+$/, '');
|
|
16
|
+
return t.slice(t.lastIndexOf('/') + 1);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A basename the shared secret table reads as an env file: `.env`, `.env.<word>` (a template such as `.env.example` is not) and `.dev.vars`, whatever the case
|
|
20
|
+
* (the same case-blind reading the keyed policy has); `<name>.env` is `present`. The table stays the one source (src/secret-paths.ts): this only repeats
|
|
21
|
+
* its name rules for a word that is not yet a path.
|
|
22
|
+
*/
|
|
23
|
+
function secretEnvBase(base) {
|
|
24
|
+
const b = base.toLowerCase();
|
|
25
|
+
if (/^\.env(?:\.|$)/.test(b))
|
|
26
|
+
return tables_1.ENV_TEMPLATE_SUFFIX.test(b) ? null : 'secret';
|
|
27
|
+
if (b === '.dev.vars')
|
|
28
|
+
return 'secret';
|
|
29
|
+
if (b.length > 4 && b.endsWith('.env'))
|
|
30
|
+
return 'present';
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/** Names a glob that cannot be listed is judged against, besides the mapper's own samples: common secret env names a project holds. */
|
|
34
|
+
exports.ENV_NAME_CORPUS = [
|
|
35
|
+
'.env.staging', '.env.development', '.env.dev', '.env.prod', '.env.test', '.env.ci', '.env.dist', '.env.defaults', '.env.default', '.env.backup', '.env.bak',
|
|
36
|
+
'.env.old', '.env.secret', '.env.secrets', '.env.private', '.env.production.local', '.env.development.local', '.env.test.local', '.env.local.bak',
|
|
37
|
+
'.env.myapp', '.env.docker', '.env.compose', 'config.env', 'prod.env', 'dev.env', 'staging.env', 'local.env', 'secrets.env', 'docker.env',
|
|
38
|
+
];
|
|
39
|
+
/** The host side of a `-v`/`--volume` value `host:container[:options]`: the text before the first colon; null with no colon (an anonymous volume) or an empty host. */
|
|
40
|
+
function volumeHost(value) {
|
|
41
|
+
const at = value.indexOf(':');
|
|
42
|
+
return at > 0 ? value.slice(0, at) : null;
|
|
43
|
+
}
|
|
44
|
+
/** The `source=` / `src=` values of a `--mount` value (comma-separated `key=value` fields): every one, a repeated key included, whatever the mount type. */
|
|
45
|
+
function mountSources(value) {
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const field of value.split(',')) {
|
|
48
|
+
const m = field.trim().replace(/^["']|["']$/g, '').match(/^(?:source|src)\s*=\s*([\s\S]*)$/i);
|
|
49
|
+
if (m)
|
|
50
|
+
out.push(m[1].trim().replace(/^["']|["']$/g, ''));
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
class Unreadable extends Error {
|
|
55
|
+
}
|
|
56
|
+
class OutOfSteps extends Error {
|
|
57
|
+
}
|
|
58
|
+
const MAX_PATTERN = 400;
|
|
59
|
+
const MAX_STEPS = 200_000;
|
|
60
|
+
const MAX_INTERVAL = 32;
|
|
61
|
+
const CLASSES = {
|
|
62
|
+
alpha: [['a', 'z'], ['A', 'Z']], digit: [['0', '9']], alnum: [['a', 'z'], ['A', 'Z'], ['0', '9']], upper: [['A', 'Z']], lower: [['a', 'z']],
|
|
63
|
+
punct: [['!', '/'], [':', '@'], ['[', '`'], ['{', '~']], space: [[' ', ' '], ['\t', '\r']], blank: [[' ', ' '], ['\t', '\t']], xdigit: [['0', '9'], ['a', 'f'], ['A', 'F']],
|
|
64
|
+
word: [['a', 'z'], ['A', 'Z'], ['0', '9'], ['_', '_']], cntrl: [['\u0000', '\u001f']], graph: [['!', '~']], print: [[' ', '~']],
|
|
65
|
+
};
|
|
66
|
+
const ESCAPE_SETS = {
|
|
67
|
+
w: { neg: false, cls: 'word' }, W: { neg: true, cls: 'word' }, s: { neg: false, cls: 'space' }, S: { neg: true, cls: 'space' }, d: { neg: false, cls: 'digit' }, D: { neg: true, cls: 'digit' },
|
|
68
|
+
};
|
|
69
|
+
function parseRegex(p, emacs) {
|
|
70
|
+
if (p.length > MAX_PATTERN)
|
|
71
|
+
throw new Unreadable();
|
|
72
|
+
let i = 0;
|
|
73
|
+
let depth = 0;
|
|
74
|
+
const atAlt = () => (emacs ? p.startsWith('\\|', i) : p[i] === '|');
|
|
75
|
+
const atClose = () => depth > 0 && (emacs ? p.startsWith('\\)', i) : p[i] === ')');
|
|
76
|
+
const parseAlt = () => {
|
|
77
|
+
const branches = [parseCat()];
|
|
78
|
+
while (i < p.length && atAlt()) {
|
|
79
|
+
i += emacs ? 2 : 1;
|
|
80
|
+
branches.push(parseCat());
|
|
81
|
+
}
|
|
82
|
+
return branches.length === 1 ? branches[0] : { t: 'alt', n: branches };
|
|
83
|
+
};
|
|
84
|
+
const parseBracket = () => {
|
|
85
|
+
i += 1;
|
|
86
|
+
let neg = false;
|
|
87
|
+
if (p[i] === '^') {
|
|
88
|
+
neg = true;
|
|
89
|
+
i += 1;
|
|
90
|
+
}
|
|
91
|
+
const items = [];
|
|
92
|
+
let first = true;
|
|
93
|
+
for (;;) {
|
|
94
|
+
if (i >= p.length)
|
|
95
|
+
throw new Unreadable();
|
|
96
|
+
const c = p[i];
|
|
97
|
+
if (c === ']' && !first) {
|
|
98
|
+
i += 1;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
first = false;
|
|
102
|
+
if (c === '[' && p[i + 1] === ':') {
|
|
103
|
+
const end = p.indexOf(':]', i + 2);
|
|
104
|
+
const cls = end < 0 ? undefined : CLASSES[p.slice(i + 2, end)];
|
|
105
|
+
if (!cls)
|
|
106
|
+
throw new Unreadable();
|
|
107
|
+
items.push(...cls);
|
|
108
|
+
i = end + 2;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (c === '[' && (p[i + 1] === '.' || p[i + 1] === '='))
|
|
112
|
+
throw new Unreadable();
|
|
113
|
+
if (c === '\\' && i + 1 < p.length && ESCAPE_SETS[p[i + 1]] && !ESCAPE_SETS[p[i + 1]].neg) {
|
|
114
|
+
items.push(...CLASSES[ESCAPE_SETS[p[i + 1]].cls]);
|
|
115
|
+
i += 2;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (p[i + 1] === '-' && i + 2 < p.length && p[i + 2] !== ']') {
|
|
119
|
+
items.push([c, p[i + 2]]);
|
|
120
|
+
i += 3;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
items.push([c, c]);
|
|
124
|
+
i += 1;
|
|
125
|
+
}
|
|
126
|
+
return { t: 'set', neg, items };
|
|
127
|
+
};
|
|
128
|
+
const interval = () => {
|
|
129
|
+
const m = (emacs ? p.slice(i).match(/^\\\{(\d+)(,(\d*))?\\\}/) : p.slice(i).match(/^\{(\d+)(,(\d*))?\}/));
|
|
130
|
+
if (!m)
|
|
131
|
+
return null;
|
|
132
|
+
const min = Number(m[1]);
|
|
133
|
+
const max = m[2] === undefined ? min : m[3] === '' ? Number.POSITIVE_INFINITY : Number(m[3]);
|
|
134
|
+
if (min > MAX_INTERVAL || (Number.isFinite(max) && max > MAX_INTERVAL) || max < min)
|
|
135
|
+
throw new Unreadable();
|
|
136
|
+
i += m[0].length;
|
|
137
|
+
return { min, max };
|
|
138
|
+
};
|
|
139
|
+
const parseAtom = () => {
|
|
140
|
+
const c = p[i];
|
|
141
|
+
if (c === '.') {
|
|
142
|
+
i += 1;
|
|
143
|
+
return { t: 'any' };
|
|
144
|
+
}
|
|
145
|
+
if (c === '[')
|
|
146
|
+
return parseBracket();
|
|
147
|
+
if (c === '^' || c === '$') {
|
|
148
|
+
i += 1;
|
|
149
|
+
return { t: 'empty' };
|
|
150
|
+
}
|
|
151
|
+
if (!emacs && c === '(') {
|
|
152
|
+
i += 1;
|
|
153
|
+
depth += 1;
|
|
154
|
+
const n = parseAlt();
|
|
155
|
+
if (p[i] !== ')')
|
|
156
|
+
throw new Unreadable();
|
|
157
|
+
i += 1;
|
|
158
|
+
depth -= 1;
|
|
159
|
+
return n;
|
|
160
|
+
}
|
|
161
|
+
if (c === '\\') {
|
|
162
|
+
if (i + 1 >= p.length)
|
|
163
|
+
throw new Unreadable();
|
|
164
|
+
const d = p[i + 1];
|
|
165
|
+
if (emacs && d === '(') {
|
|
166
|
+
i += 2;
|
|
167
|
+
depth += 1;
|
|
168
|
+
const n = parseAlt();
|
|
169
|
+
if (!p.startsWith('\\)', i))
|
|
170
|
+
throw new Unreadable();
|
|
171
|
+
i += 2;
|
|
172
|
+
depth -= 1;
|
|
173
|
+
return n;
|
|
174
|
+
}
|
|
175
|
+
if (/[1-9]/.test(d))
|
|
176
|
+
throw new Unreadable();
|
|
177
|
+
if (ESCAPE_SETS[d]) {
|
|
178
|
+
i += 2;
|
|
179
|
+
return { t: 'set', neg: ESCAPE_SETS[d].neg, items: CLASSES[ESCAPE_SETS[d].cls] };
|
|
180
|
+
}
|
|
181
|
+
if (d === 'b' || d === 'B' || d === '<' || d === '>' || d === '`' || d === "'") {
|
|
182
|
+
i += 2;
|
|
183
|
+
return { t: 'empty' };
|
|
184
|
+
}
|
|
185
|
+
i += 2;
|
|
186
|
+
return { t: 'lit', c: d };
|
|
187
|
+
}
|
|
188
|
+
i += 1;
|
|
189
|
+
return { t: 'lit', c };
|
|
190
|
+
};
|
|
191
|
+
const parseCat = () => {
|
|
192
|
+
const items = [];
|
|
193
|
+
while (i < p.length && !atAlt() && !atClose()) {
|
|
194
|
+
let atom;
|
|
195
|
+
// an operator with nothing in front of it is an ordinary character
|
|
196
|
+
if ((p[i] === '*' || p[i] === '+' || p[i] === '?') && items.length === 0) {
|
|
197
|
+
atom = { t: 'lit', c: p[i] };
|
|
198
|
+
i += 1;
|
|
199
|
+
}
|
|
200
|
+
else
|
|
201
|
+
atom = parseAtom();
|
|
202
|
+
for (;;) {
|
|
203
|
+
const c = p[i];
|
|
204
|
+
if (c === '*') {
|
|
205
|
+
i += 1;
|
|
206
|
+
atom = { t: 'rep', n: atom, min: 0, max: Number.POSITIVE_INFINITY };
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (c === '+') {
|
|
210
|
+
i += 1;
|
|
211
|
+
atom = { t: 'rep', n: atom, min: 1, max: Number.POSITIVE_INFINITY };
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (c === '?') {
|
|
215
|
+
i += 1;
|
|
216
|
+
atom = { t: 'rep', n: atom, min: 0, max: 1 };
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (emacs && (p.startsWith('\\+', i) || p.startsWith('\\?', i))) {
|
|
220
|
+
atom = { t: 'rep', n: atom, min: p[i + 1] === '+' ? 1 : 0, max: p[i + 1] === '+' ? Number.POSITIVE_INFINITY : 1 };
|
|
221
|
+
i += 2;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const iv = c === '{' || c === '\\' ? interval() : null;
|
|
225
|
+
if (iv) {
|
|
226
|
+
atom = { t: 'rep', n: atom, min: iv.min, max: iv.max };
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
items.push(atom);
|
|
232
|
+
}
|
|
233
|
+
return items.length === 1 ? items[0] : { t: 'cat', n: items };
|
|
234
|
+
};
|
|
235
|
+
const node = parseAlt();
|
|
236
|
+
if (i < p.length)
|
|
237
|
+
throw new Unreadable();
|
|
238
|
+
return node;
|
|
239
|
+
}
|
|
240
|
+
function matchNode(node, s, i, k, st) {
|
|
241
|
+
st.steps += 1;
|
|
242
|
+
if (st.steps > MAX_STEPS)
|
|
243
|
+
throw new OutOfSteps();
|
|
244
|
+
switch (node.t) {
|
|
245
|
+
case 'empty': return k(i);
|
|
246
|
+
case 'any': return i < s.length && k(i + 1);
|
|
247
|
+
case 'lit': return i < s.length && (st.ci ? s[i].toLowerCase() === node.c.toLowerCase() : s[i] === node.c) && k(i + 1);
|
|
248
|
+
case 'set': {
|
|
249
|
+
if (i >= s.length)
|
|
250
|
+
return false;
|
|
251
|
+
const ch = s[i];
|
|
252
|
+
const chs = st.ci ? [ch.toLowerCase(), ch.toUpperCase()] : [ch];
|
|
253
|
+
const inSet = chs.some((c) => node.items.some(([lo, hi]) => c >= lo && c <= hi));
|
|
254
|
+
return inSet !== node.neg && k(i + 1);
|
|
255
|
+
}
|
|
256
|
+
case 'cat': {
|
|
257
|
+
const step = (idx, at) => (idx === node.n.length ? k(at) : matchNode(node.n[idx], s, at, (j) => step(idx + 1, j), st));
|
|
258
|
+
return step(0, i);
|
|
259
|
+
}
|
|
260
|
+
case 'alt': return node.n.some((alt) => matchNode(alt, s, i, k, st));
|
|
261
|
+
case 'rep': {
|
|
262
|
+
const again = (count, at) => {
|
|
263
|
+
if (count < node.max && matchNode(node.n, s, at, (j) => (j === at && count >= node.min ? false : again(count + 1, j)), st))
|
|
264
|
+
return true;
|
|
265
|
+
return count >= node.min && k(at);
|
|
266
|
+
};
|
|
267
|
+
return again(0, i);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Whether a find `-regex` pattern matches any of the candidate paths (the whole path, as find matches it), read as emacs and as extended syntax.
|
|
273
|
+
* `unsure`: neither reading could be completed (unreadable syntax, too large, out of steps) and none matched.
|
|
274
|
+
*/
|
|
275
|
+
function regexMatchesAny(pattern, candidates) {
|
|
276
|
+
let unsure = false;
|
|
277
|
+
for (const emacs of [true, false]) {
|
|
278
|
+
let node;
|
|
279
|
+
try {
|
|
280
|
+
node = parseRegex(pattern, emacs);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
unsure = true;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const st = { steps: 0, ci: true };
|
|
287
|
+
try {
|
|
288
|
+
for (const c of candidates)
|
|
289
|
+
if (c.length <= 300 && matchNode(node, c, 0, (j) => j === c.length, st))
|
|
290
|
+
return 'yes';
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
unsure = true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return unsure ? 'unsure' : 'no';
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=env-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-names.js","sourceRoot":"","sources":["../../src/seatbelt/env-names.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.
|