mandala-computer-mcp 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +558 -29
- package/dist/api.d.ts +59 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +404 -33
- package/dist/api.js.map +1 -1
- package/dist/artifacts.d.ts +63 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +81 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -21
- package/dist/cli.js.map +1 -1
- package/dist/credentials.d.ts +33 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +395 -0
- package/dist/credentials.js.map +1 -0
- package/dist/errors.d.ts +122 -11
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +237 -41
- package/dist/errors.js.map +1 -1
- package/dist/executions.d.ts +43 -0
- package/dist/executions.d.ts.map +1 -0
- package/dist/executions.js +162 -0
- package/dist/executions.js.map +1 -0
- package/dist/format.d.ts +33 -8
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +107 -12
- package/dist/format.js.map +1 -1
- package/dist/http.d.ts +42 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +383 -3
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/paths.d.ts +50 -2
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +65 -5
- package/dist/paths.js.map +1 -1
- package/dist/results.d.ts +97 -0
- package/dist/results.d.ts.map +1 -0
- package/dist/results.js +263 -0
- package/dist/results.js.map +1 -0
- package/dist/secret-errors.d.ts +59 -0
- package/dist/secret-errors.d.ts.map +1 -0
- package/dist/secret-errors.js +199 -0
- package/dist/secret-errors.js.map +1 -0
- package/dist/secret-store.d.ts +115 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/secret-store.js +105 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/server.d.ts +3 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +60 -9
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +6 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +1 -1
- package/dist/session.js.map +1 -1
- package/dist/stdio.d.ts +5 -1
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +10 -4
- package/dist/stdio.js.map +1 -1
- package/dist/tool-filters.d.ts +38 -0
- package/dist/tool-filters.d.ts.map +1 -0
- package/dist/tool-filters.js +137 -0
- package/dist/tool-filters.js.map +1 -0
- package/dist/tools/account.d.ts +3 -0
- package/dist/tools/account.d.ts.map +1 -0
- package/dist/tools/account.js +122 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/activities.d.ts +3 -0
- package/dist/tools/activities.d.ts.map +1 -0
- package/dist/tools/activities.js +140 -0
- package/dist/tools/activities.js.map +1 -0
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +21 -9
- package/dist/tools/agent.js.map +1 -1
- package/dist/tools/artifacts.d.ts +3 -0
- package/dist/tools/artifacts.d.ts.map +1 -0
- package/dist/tools/artifacts.js +97 -0
- package/dist/tools/artifacts.js.map +1 -0
- package/dist/tools/chat.d.ts +6 -0
- package/dist/tools/chat.d.ts.map +1 -0
- package/dist/tools/chat.js +192 -0
- package/dist/tools/chat.js.map +1 -0
- package/dist/tools/computers.d.ts.map +1 -1
- package/dist/tools/computers.js +28 -16
- package/dist/tools/computers.js.map +1 -1
- package/dist/tools/directory.d.ts +13 -0
- package/dist/tools/directory.d.ts.map +1 -0
- package/dist/tools/directory.js +88 -0
- package/dist/tools/directory.js.map +1 -0
- package/dist/tools/executions.d.ts +3 -0
- package/dist/tools/executions.d.ts.map +1 -0
- package/dist/tools/executions.js +87 -0
- package/dist/tools/executions.js.map +1 -0
- package/dist/tools/guest.d.ts.map +1 -1
- package/dist/tools/guest.js +184 -35
- package/dist/tools/guest.js.map +1 -1
- package/dist/tools/input.d.ts +2 -0
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +31 -5
- package/dist/tools/input.js.map +1 -1
- package/dist/tools/results.d.ts +30 -0
- package/dist/tools/results.d.ts.map +1 -0
- package/dist/tools/results.js +106 -0
- package/dist/tools/results.js.map +1 -0
- package/dist/tools/secrets.d.ts +78 -0
- package/dist/tools/secrets.d.ts.map +1 -0
- package/dist/tools/secrets.js +448 -0
- package/dist/tools/secrets.js.map +1 -0
- package/dist/tools/signals.d.ts +3 -0
- package/dist/tools/signals.d.ts.map +1 -0
- package/dist/tools/signals.js +116 -0
- package/dist/tools/signals.js.map +1 -0
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +52 -10
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/ssh.d.ts +3 -0
- package/dist/tools/ssh.d.ts.map +1 -0
- package/dist/tools/ssh.js +186 -0
- package/dist/tools/ssh.js.map +1 -0
- package/dist/tools/webhooks.js +1 -1
- package/dist/tools/webhooks.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { isIP } from 'node:net';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { DEFAULT_BASE_URL } from './api.js';
|
|
6
|
+
const MAX_BYTES = 65_536;
|
|
7
|
+
const RESERVED = new Set([
|
|
8
|
+
'__proto__',
|
|
9
|
+
'prototype',
|
|
10
|
+
'constructor',
|
|
11
|
+
'__defineGetter__',
|
|
12
|
+
'__defineSetter__',
|
|
13
|
+
'hasOwnProperty',
|
|
14
|
+
'__lookupGetter__',
|
|
15
|
+
'__lookupSetter__',
|
|
16
|
+
'isPrototypeOf',
|
|
17
|
+
'propertyIsEnumerable',
|
|
18
|
+
'toLocaleString',
|
|
19
|
+
'toString',
|
|
20
|
+
'valueOf',
|
|
21
|
+
]);
|
|
22
|
+
function credentialWhitespace(code) {
|
|
23
|
+
return ((code >= 9 && code <= 13) ||
|
|
24
|
+
code === 32 ||
|
|
25
|
+
code === 133 ||
|
|
26
|
+
code === 160 ||
|
|
27
|
+
code === 5760 ||
|
|
28
|
+
(code >= 8192 && code <= 8202) ||
|
|
29
|
+
code === 8232 ||
|
|
30
|
+
code === 8233 ||
|
|
31
|
+
code === 8239 ||
|
|
32
|
+
code === 8287 ||
|
|
33
|
+
code === 12288 ||
|
|
34
|
+
code === 65279);
|
|
35
|
+
}
|
|
36
|
+
/** Fixed credential whitespace, shared with the other local clients. */
|
|
37
|
+
export function trimCredentialWhitespace(value) {
|
|
38
|
+
let start = 0;
|
|
39
|
+
let end = value.length;
|
|
40
|
+
while (start < end && credentialWhitespace(value.charCodeAt(start)))
|
|
41
|
+
start++;
|
|
42
|
+
while (end > start && credentialWhitespace(value.charCodeAt(end - 1)))
|
|
43
|
+
end--;
|
|
44
|
+
return value.slice(start, end);
|
|
45
|
+
}
|
|
46
|
+
/** Local diagnostics never include file contents, keys, paths or supplied values. */
|
|
47
|
+
export class CredentialsError extends Error {
|
|
48
|
+
code;
|
|
49
|
+
constructor(code, detail) {
|
|
50
|
+
super(`${detail} Run mandala login with the TypeScript CLI, or set MANDALA_API_KEY.`);
|
|
51
|
+
this.code = code;
|
|
52
|
+
this.name = 'CredentialsError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function fail(code, detail = 'Invalid saved credentials.') {
|
|
56
|
+
throw new CredentialsError(code, detail);
|
|
57
|
+
}
|
|
58
|
+
function profileName(value) {
|
|
59
|
+
if (typeof value !== 'string' ||
|
|
60
|
+
value.length < 1 ||
|
|
61
|
+
value.length > 64 ||
|
|
62
|
+
!/[A-Za-z0-9]/.test(value[0]) ||
|
|
63
|
+
/[^A-Za-z0-9._-]/.test(value) ||
|
|
64
|
+
RESERVED.has(value)) {
|
|
65
|
+
fail('invalid_profile', 'Invalid profile name; use 1–64 ASCII letters, digits, dots, underscores or hyphens.');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Strict file-bound URL syntax; explicit-key transport behavior is separate. */
|
|
69
|
+
export function canonicalizeBaseUrl(value) {
|
|
70
|
+
const bad = () => fail('invalid_base_url', 'Invalid saved-credential base URL.');
|
|
71
|
+
if (typeof value !== 'string')
|
|
72
|
+
return bad();
|
|
73
|
+
const raw = trimCredentialWhitespace(value);
|
|
74
|
+
if (!raw || raw.length > 2048 || /[^\x21-\x7e]|[\\%?#]/.test(raw))
|
|
75
|
+
return bad();
|
|
76
|
+
const schemeMatch = /^(https?):\/\//i.exec(raw);
|
|
77
|
+
if (!schemeMatch)
|
|
78
|
+
return bad();
|
|
79
|
+
const scheme = schemeMatch[1].toLowerCase();
|
|
80
|
+
const rest = raw.slice(schemeMatch[0].length);
|
|
81
|
+
const slash = rest.indexOf('/');
|
|
82
|
+
const authority = slash < 0 ? rest : rest.slice(0, slash);
|
|
83
|
+
const pathname = slash < 0 ? '' : rest.slice(slash);
|
|
84
|
+
if (!authority || authority.includes('@'))
|
|
85
|
+
return bad();
|
|
86
|
+
let host;
|
|
87
|
+
let port;
|
|
88
|
+
if (authority.startsWith('[')) {
|
|
89
|
+
const close = authority.indexOf(']');
|
|
90
|
+
if (close < 0)
|
|
91
|
+
return bad();
|
|
92
|
+
const address = authority.slice(1, close);
|
|
93
|
+
if (isIP(address) !== 6)
|
|
94
|
+
return bad();
|
|
95
|
+
const suffix = authority.slice(close + 1);
|
|
96
|
+
if (suffix && !suffix.startsWith(':'))
|
|
97
|
+
return bad();
|
|
98
|
+
port = suffix ? suffix.slice(1) : undefined;
|
|
99
|
+
// Only IPv6 reaches the URL parser, after strict address validation. It
|
|
100
|
+
// serializes the first longest zero run and any dotted IPv4 tail.
|
|
101
|
+
host = new URL(`https://[${address}]`).hostname;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const parts = authority.split(':');
|
|
105
|
+
if (parts.length > 2)
|
|
106
|
+
return bad();
|
|
107
|
+
host = parts[0].toLowerCase();
|
|
108
|
+
port = parts[1];
|
|
109
|
+
if (!host || host.length > 253)
|
|
110
|
+
return bad();
|
|
111
|
+
const labels = host.split('.');
|
|
112
|
+
if (labels.some((label) => !label ||
|
|
113
|
+
label.length > 63 ||
|
|
114
|
+
/[^a-z0-9-]/.test(label) ||
|
|
115
|
+
!/[a-z0-9]/.test(label[0]) ||
|
|
116
|
+
!/[a-z0-9]/.test(label[label.length - 1])))
|
|
117
|
+
return bad();
|
|
118
|
+
const last = labels[labels.length - 1];
|
|
119
|
+
if (/^(?:[0-9]+|0x[0-9a-f]*)$/.test(last) && isIP(host) !== 4)
|
|
120
|
+
return bad();
|
|
121
|
+
}
|
|
122
|
+
let portSuffix = '';
|
|
123
|
+
if (port !== undefined) {
|
|
124
|
+
if (!port || /[^0-9]/.test(port))
|
|
125
|
+
return bad();
|
|
126
|
+
const n = Number(port);
|
|
127
|
+
if (!Number.isInteger(n) || n < 1 || n > 65535)
|
|
128
|
+
return bad();
|
|
129
|
+
if (!(scheme === 'https' && n === 443) && !(scheme === 'http' && n === 80))
|
|
130
|
+
portSuffix = `:${n}`;
|
|
131
|
+
}
|
|
132
|
+
if (scheme === 'http' &&
|
|
133
|
+
host !== 'localhost' &&
|
|
134
|
+
host !== '[::1]' &&
|
|
135
|
+
!(isIP(host) === 4 && host.startsWith('127.')))
|
|
136
|
+
return bad();
|
|
137
|
+
if (/[^A-Za-z0-9\-._~!$&'()*+,;=:@/]/.test(pathname) ||
|
|
138
|
+
pathname.split('/').some((part) => part === '.' || part === '..'))
|
|
139
|
+
return bad();
|
|
140
|
+
return `${scheme}://${host}${portSuffix}${pathname.replace(/\/+$/, '')}`;
|
|
141
|
+
}
|
|
142
|
+
function object(value) {
|
|
143
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
144
|
+
fail('invalid_schema');
|
|
145
|
+
}
|
|
146
|
+
function closed(value, keys) {
|
|
147
|
+
object(value);
|
|
148
|
+
if (Object.keys(value).length !== keys.length || keys.some((key) => !Object.hasOwn(value, key)))
|
|
149
|
+
fail('invalid_schema');
|
|
150
|
+
}
|
|
151
|
+
function nonempty(value) {
|
|
152
|
+
if (typeof value !== 'string' || !value.length)
|
|
153
|
+
fail('invalid_schema');
|
|
154
|
+
}
|
|
155
|
+
function stringsWellFormed(value) {
|
|
156
|
+
const pending = [value];
|
|
157
|
+
while (pending.length) {
|
|
158
|
+
const current = pending.pop();
|
|
159
|
+
if (typeof current === 'string') {
|
|
160
|
+
for (let i = 0; i < current.length; i++) {
|
|
161
|
+
const code = current.charCodeAt(i);
|
|
162
|
+
if (code >= 0xd800 && code <= 0xdbff) {
|
|
163
|
+
const next = current.charCodeAt(++i);
|
|
164
|
+
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
165
|
+
fail('invalid_schema');
|
|
166
|
+
}
|
|
167
|
+
else if (code >= 0xdc00 && code <= 0xdfff)
|
|
168
|
+
fail('invalid_schema');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (current && typeof current === 'object') {
|
|
172
|
+
for (const [key, child] of Object.entries(current))
|
|
173
|
+
pending.push(key, child);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export function parseCredentials(bytes) {
|
|
178
|
+
if (bytes.byteLength > MAX_BYTES)
|
|
179
|
+
fail('file_too_large', 'Saved credentials exceed 65,536 bytes.');
|
|
180
|
+
let text;
|
|
181
|
+
try {
|
|
182
|
+
text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return fail('invalid_utf8', 'Saved credentials must be valid UTF-8.');
|
|
186
|
+
}
|
|
187
|
+
let doc;
|
|
188
|
+
try {
|
|
189
|
+
doc = JSON.parse(text);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return fail('invalid_json', 'Saved credentials are not valid JSON.');
|
|
193
|
+
}
|
|
194
|
+
stringsWellFormed(doc);
|
|
195
|
+
object(doc);
|
|
196
|
+
if (typeof doc.version !== 'number' ||
|
|
197
|
+
!Number.isFinite(doc.version) ||
|
|
198
|
+
!Number.isInteger(doc.version))
|
|
199
|
+
fail('invalid_schema');
|
|
200
|
+
if (doc.version !== 1)
|
|
201
|
+
fail('unsupported_version', 'Unsupported saved-credentials version.');
|
|
202
|
+
if (!Object.hasOwn(doc, 'default_profile'))
|
|
203
|
+
fail('missing_default_profile', 'Saved credentials have no default profile.');
|
|
204
|
+
closed(doc, ['version', 'default_profile', 'profiles']);
|
|
205
|
+
if (typeof doc.default_profile !== 'string')
|
|
206
|
+
fail('invalid_schema');
|
|
207
|
+
profileName(doc.default_profile);
|
|
208
|
+
object(doc.profiles);
|
|
209
|
+
const names = Object.keys(doc.profiles);
|
|
210
|
+
if (!names.length)
|
|
211
|
+
fail('invalid_schema');
|
|
212
|
+
if (names.length > 100)
|
|
213
|
+
fail('too_many_profiles', 'Saved credentials contain more than 100 profiles.');
|
|
214
|
+
for (const name of names) {
|
|
215
|
+
profileName(name);
|
|
216
|
+
const entry = doc.profiles[name];
|
|
217
|
+
closed(entry, ['api_key', 'base_url', 'key_id', 'account', 'scope']);
|
|
218
|
+
nonempty(entry.api_key);
|
|
219
|
+
if (!trimCredentialWhitespace(entry.api_key))
|
|
220
|
+
fail('invalid_schema');
|
|
221
|
+
if (canonicalizeBaseUrl(entry.base_url) !== entry.base_url)
|
|
222
|
+
fail('invalid_base_url', 'Stored base URLs must be canonical.');
|
|
223
|
+
nonempty(entry.key_id);
|
|
224
|
+
closed(entry.account, ['id', 'name']);
|
|
225
|
+
nonempty(entry.account.id);
|
|
226
|
+
if (entry.account.name !== null && typeof entry.account.name !== 'string')
|
|
227
|
+
fail('invalid_schema');
|
|
228
|
+
object(entry.scope);
|
|
229
|
+
if (entry.scope.type === 'account')
|
|
230
|
+
closed(entry.scope, ['type']);
|
|
231
|
+
else if (entry.scope.type === 'workspace') {
|
|
232
|
+
closed(entry.scope, ['type', 'workspace_id', 'workspace_name']);
|
|
233
|
+
nonempty(entry.scope.workspace_id);
|
|
234
|
+
nonempty(entry.scope.workspace_name);
|
|
235
|
+
}
|
|
236
|
+
else
|
|
237
|
+
fail('invalid_schema');
|
|
238
|
+
}
|
|
239
|
+
if (!Object.hasOwn(doc.profiles, doc.default_profile))
|
|
240
|
+
fail('missing_default_profile', 'The saved default profile is missing.');
|
|
241
|
+
return doc;
|
|
242
|
+
}
|
|
243
|
+
const sameObject = (a, b) => a.dev === b.dev && a.ino === b.ino;
|
|
244
|
+
const sameDirectory = (initial, current) => sameObject(initial, current) &&
|
|
245
|
+
initial.ctimeNs === current.ctimeNs &&
|
|
246
|
+
initial.mtimeNs === current.mtimeNs;
|
|
247
|
+
/**
|
|
248
|
+
* Opened descriptors are checked against pre/post named directory AND file
|
|
249
|
+
* identities and the initial directory's change timestamps. Renaming a
|
|
250
|
+
* directory away and back preserves dev/ino and can preserve mtime, so ctime
|
|
251
|
+
* is essential. Bigint stats retain the filesystem's timestamp precision.
|
|
252
|
+
* Node has no portable openat: these checks reject observed substitutions
|
|
253
|
+
* rather than claiming an atomic directory-relative open.
|
|
254
|
+
*/
|
|
255
|
+
function readStore() {
|
|
256
|
+
if (process.platform === 'win32' ||
|
|
257
|
+
typeof process.getuid !== 'function' ||
|
|
258
|
+
!fs.constants.O_NOFOLLOW ||
|
|
259
|
+
!fs.constants.O_DIRECTORY) {
|
|
260
|
+
fail('unsupported_file_protection', 'Saved credentials require verified POSIX file protection.');
|
|
261
|
+
}
|
|
262
|
+
const deadline = performance.now() + 5000;
|
|
263
|
+
const checkTime = () => {
|
|
264
|
+
if (performance.now() >= deadline)
|
|
265
|
+
fail('credential_read_timeout', 'Reading saved credentials timed out.');
|
|
266
|
+
};
|
|
267
|
+
const uid = process.getuid();
|
|
268
|
+
const directoryUid = BigInt(uid);
|
|
269
|
+
const checkDir = (st) => {
|
|
270
|
+
if (!st.isDirectory() || st.uid !== directoryUid || (st.mode & 4095n) !== 448n)
|
|
271
|
+
fail('unsafe_directory', 'The credentials directory must be owned by you with mode 0700.');
|
|
272
|
+
};
|
|
273
|
+
const checkFile = (st) => {
|
|
274
|
+
if (!st.isFile() || st.uid !== uid || (st.mode & 0o7777) !== 0o600 || st.nlink !== 1)
|
|
275
|
+
fail('unsafe_file', 'The credentials file must be a private, owned regular file with mode 0600 and one link.');
|
|
276
|
+
if (st.size > MAX_BYTES)
|
|
277
|
+
fail('file_too_large', 'Saved credentials exceed 65,536 bytes.');
|
|
278
|
+
};
|
|
279
|
+
let dirFd;
|
|
280
|
+
let fileFd;
|
|
281
|
+
try {
|
|
282
|
+
const home = os.homedir();
|
|
283
|
+
if (!home || !path.isAbsolute(home))
|
|
284
|
+
fail('missing_credentials', 'Cannot discover your home directory.');
|
|
285
|
+
const directory = path.join(home, '.mandala');
|
|
286
|
+
const filename = path.join(directory, 'credentials.json');
|
|
287
|
+
const namedDir = fs.lstatSync(directory, { bigint: true });
|
|
288
|
+
checkDir(namedDir);
|
|
289
|
+
dirFd = fs.openSync(directory, fs.constants.O_RDONLY |
|
|
290
|
+
fs.constants.O_DIRECTORY |
|
|
291
|
+
fs.constants.O_NOFOLLOW |
|
|
292
|
+
fs.constants.O_NONBLOCK);
|
|
293
|
+
const openedDir = fs.fstatSync(dirFd, { bigint: true });
|
|
294
|
+
checkDir(openedDir);
|
|
295
|
+
if (!sameDirectory(namedDir, openedDir))
|
|
296
|
+
fail('unsafe_directory');
|
|
297
|
+
const namedFile = fs.lstatSync(filename);
|
|
298
|
+
checkFile(namedFile);
|
|
299
|
+
const beforeDir = fs.lstatSync(directory, { bigint: true });
|
|
300
|
+
checkDir(beforeDir);
|
|
301
|
+
if (!sameDirectory(namedDir, beforeDir))
|
|
302
|
+
fail('unsafe_directory');
|
|
303
|
+
checkTime();
|
|
304
|
+
fileFd = fs.openSync(filename, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
|
305
|
+
const openedFile = fs.fstatSync(fileFd);
|
|
306
|
+
checkFile(openedFile);
|
|
307
|
+
if (!sameObject(namedFile, openedFile))
|
|
308
|
+
fail('unsafe_file');
|
|
309
|
+
const buffer = Buffer.alloc(MAX_BYTES + 1);
|
|
310
|
+
let size = 0;
|
|
311
|
+
for (;;) {
|
|
312
|
+
checkTime();
|
|
313
|
+
const n = fs.readSync(fileFd, buffer, size, Math.min(8192, buffer.length - size), null);
|
|
314
|
+
size += n;
|
|
315
|
+
if (size > MAX_BYTES)
|
|
316
|
+
fail('file_too_large', 'Saved credentials exceed 65,536 bytes.');
|
|
317
|
+
if (!n)
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
const finalFile = fs.fstatSync(fileFd);
|
|
321
|
+
checkFile(finalFile);
|
|
322
|
+
if (!sameObject(openedFile, finalFile) ||
|
|
323
|
+
size !== finalFile.size ||
|
|
324
|
+
openedFile.size !== finalFile.size ||
|
|
325
|
+
openedFile.mtimeMs !== finalFile.mtimeMs ||
|
|
326
|
+
openedFile.ctimeMs !== finalFile.ctimeMs)
|
|
327
|
+
fail('unsafe_file');
|
|
328
|
+
const finalNamedFile = fs.lstatSync(filename);
|
|
329
|
+
checkFile(finalNamedFile);
|
|
330
|
+
if (!sameObject(openedFile, finalNamedFile))
|
|
331
|
+
fail('unsafe_file');
|
|
332
|
+
const finalDir = fs.fstatSync(dirFd, { bigint: true });
|
|
333
|
+
const finalNamedDir = fs.lstatSync(directory, { bigint: true });
|
|
334
|
+
checkDir(finalDir);
|
|
335
|
+
checkDir(finalNamedDir);
|
|
336
|
+
if (!sameDirectory(namedDir, finalDir) || !sameDirectory(namedDir, finalNamedDir))
|
|
337
|
+
fail('unsafe_directory');
|
|
338
|
+
checkTime();
|
|
339
|
+
return buffer.subarray(0, size);
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
if (error instanceof CredentialsError)
|
|
343
|
+
throw error;
|
|
344
|
+
const code = error?.code;
|
|
345
|
+
if (code === 'ENOENT')
|
|
346
|
+
fail('missing_credentials', 'No API key or saved credentials found.');
|
|
347
|
+
return fail('unsafe_file', 'Cannot safely read saved credentials; check the directory and file protection.');
|
|
348
|
+
}
|
|
349
|
+
finally {
|
|
350
|
+
if (fileFd !== undefined)
|
|
351
|
+
fs.closeSync(fileFd);
|
|
352
|
+
if (dirFd !== undefined)
|
|
353
|
+
fs.closeSync(dirFd);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/** Resolve once at local startup, before constructing an explicit ServerConfig. */
|
|
357
|
+
export function resolveCredentials(options = {}) {
|
|
358
|
+
const explicit = options.apiKey;
|
|
359
|
+
const legacyBase = () => (options.baseUrl ?? process.env.MANDALA_BASE_URL?.trim()) || DEFAULT_BASE_URL;
|
|
360
|
+
if (explicit !== undefined) {
|
|
361
|
+
if (typeof explicit !== 'string' || !trimCredentialWhitespace(explicit))
|
|
362
|
+
fail('invalid_explicit_key', 'The supplied API key must be a nonempty string.');
|
|
363
|
+
return {
|
|
364
|
+
apiKey: trimCredentialWhitespace(explicit),
|
|
365
|
+
baseUrl: legacyBase(),
|
|
366
|
+
source: 'explicit',
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
const environment = trimCredentialWhitespace(process.env.MANDALA_API_KEY ?? '');
|
|
370
|
+
if (environment)
|
|
371
|
+
return { apiKey: environment, baseUrl: legacyBase(), source: 'environment' };
|
|
372
|
+
// null is supplied in JavaScript, and must not fall through to the environment.
|
|
373
|
+
const profile = options.profile !== undefined
|
|
374
|
+
? options.profile
|
|
375
|
+
: trimCredentialWhitespace(process.env.MANDALA_PROFILE ?? '') || undefined;
|
|
376
|
+
if (profile !== undefined)
|
|
377
|
+
profileName(profile);
|
|
378
|
+
const doc = parseCredentials(readStore());
|
|
379
|
+
const name = profile ?? doc.default_profile;
|
|
380
|
+
if (!Object.hasOwn(doc.profiles, name))
|
|
381
|
+
fail('missing_selected_profile', 'The selected credential profile is missing.');
|
|
382
|
+
const entry = doc.profiles[name];
|
|
383
|
+
const override = options.baseUrl !== undefined
|
|
384
|
+
? options.baseUrl
|
|
385
|
+
: trimCredentialWhitespace(process.env.MANDALA_BASE_URL ?? '') || undefined;
|
|
386
|
+
if (override !== undefined && canonicalizeBaseUrl(override) !== entry.base_url)
|
|
387
|
+
fail('base_binding_mismatch', 'The base URL does not match the selected credential profile.');
|
|
388
|
+
return {
|
|
389
|
+
apiKey: trimCredentialWhitespace(entry.api_key),
|
|
390
|
+
baseUrl: entry.base_url,
|
|
391
|
+
source: 'file',
|
|
392
|
+
profile: name,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -16,6 +16,19 @@
|
|
|
16
16
|
export declare class MandalaError extends Error {
|
|
17
17
|
name: string;
|
|
18
18
|
}
|
|
19
|
+
/** Optional diagnostics supplied by an HTTP response; never permission to replay a request. */
|
|
20
|
+
export interface APIErrorMetadata {
|
|
21
|
+
requestId?: string;
|
|
22
|
+
allow?: string;
|
|
23
|
+
wwwAuthenticate?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The HTTP method of the request that was refused, when known. Read by
|
|
26
|
+
* {@link isTransient} for one status: a `503` answered to a change may or may
|
|
27
|
+
* not have been acted on, so only a request that is safe to repeat is
|
|
28
|
+
* transient on it.
|
|
29
|
+
*/
|
|
30
|
+
method?: string;
|
|
31
|
+
}
|
|
19
32
|
export declare class APIError extends MandalaError {
|
|
20
33
|
readonly status: number;
|
|
21
34
|
readonly body?: unknown | undefined;
|
|
@@ -36,9 +49,17 @@ export declare class APIError extends MandalaError {
|
|
|
36
49
|
* the caller who arrived a moment earlier heard.
|
|
37
50
|
*/
|
|
38
51
|
readonly reason?: string;
|
|
52
|
+
/** Response header first, then the top-level body ID; never an idempotency key. */
|
|
53
|
+
readonly requestId?: string;
|
|
54
|
+
/** The received Allow header, when supplied. */
|
|
55
|
+
readonly allow?: string;
|
|
56
|
+
/** The received WWW-Authenticate header, when supplied. */
|
|
57
|
+
readonly wwwAuthenticate?: string;
|
|
58
|
+
/** The method of the refused request, upper case, when known. */
|
|
59
|
+
readonly method?: string;
|
|
39
60
|
constructor(message: string, status: number, body?: unknown | undefined,
|
|
40
61
|
/** Parsed Retry-After delay in milliseconds; absent when missing or invalid. */
|
|
41
|
-
retryAfterMs?: number | undefined);
|
|
62
|
+
retryAfterMs?: number | undefined, metadata?: APIErrorMetadata);
|
|
42
63
|
}
|
|
43
64
|
/** Whether waiting can change a classified refusal's answer. */
|
|
44
65
|
export type ReasonKind = 'clears' | 'permanent';
|
|
@@ -102,12 +123,14 @@ export declare function reasonAdvice(reason: string | undefined): string | undef
|
|
|
102
123
|
* the work may already stand. None of the three is a fault on the computer, and
|
|
103
124
|
* a model told only "unauthorized (HTTP 401)" reads it as one.
|
|
104
125
|
*
|
|
105
|
-
*
|
|
126
|
+
* A 404 is deliberately not classified here: it does not separate deleted
|
|
106
127
|
* from out of this key's reach, so a single clause would have to be wrong about
|
|
107
128
|
* one of them — that judgement belongs to the tools that know which id they were
|
|
108
129
|
* given. Silence is the same discipline {@link reasonAdvice} keeps.
|
|
109
130
|
*/
|
|
110
|
-
export declare function
|
|
131
|
+
export declare function authenticationAdvice(reason: string | undefined): string;
|
|
132
|
+
/** Status-specific guidance, with authentication provenance supplied by the refusal reason. */
|
|
133
|
+
export declare function statusAdvice(status: number | undefined, reason?: string): string | undefined;
|
|
111
134
|
/** 401 — the key is missing, malformed, or revoked. */
|
|
112
135
|
export declare class AuthenticationError extends APIError {
|
|
113
136
|
name: string;
|
|
@@ -120,10 +143,14 @@ export declare class PlanLimitError extends APIError {
|
|
|
120
143
|
export declare class PermissionDeniedError extends APIError {
|
|
121
144
|
name: string;
|
|
122
145
|
}
|
|
123
|
-
/** 404 — no such computer, snapshot, or route. */
|
|
146
|
+
/** 404 — no such computer, snapshot, guest path, or route. */
|
|
124
147
|
export declare class NotFoundError extends APIError {
|
|
125
148
|
name: string;
|
|
126
149
|
}
|
|
150
|
+
/** 405 — the path does not support the requested method; inspect the received Allow. */
|
|
151
|
+
export declare class MethodNotAllowedError extends APIError {
|
|
152
|
+
name: string;
|
|
153
|
+
}
|
|
127
154
|
/**
|
|
128
155
|
* 409 — the thing exists but is in the wrong state for this right now.
|
|
129
156
|
*
|
|
@@ -180,8 +207,73 @@ export declare class MoveRequiredError extends ConflictError {
|
|
|
180
207
|
name: string;
|
|
181
208
|
constructor(message: string, status: number, body: unknown,
|
|
182
209
|
/** Whether a host in this region could run the size that was asked for. */
|
|
183
|
-
movePossible: boolean, retryAfterMs?: number);
|
|
210
|
+
movePossible: boolean, retryAfterMs?: number, metadata?: APIErrorMetadata);
|
|
184
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* The 409 a create-only upload gets when the path is already taken.
|
|
214
|
+
*
|
|
215
|
+
* `PUT /computers/{id}/files?overwrite=false` creates the file only if nothing
|
|
216
|
+
* is at `path`. When something is, the answer is 409 with `reason: "exists"` and
|
|
217
|
+
* THIS request wrote nothing — an earlier attempt whose answer was lost may have
|
|
218
|
+
* written the file itself. Its own class for the reason {@link MoveRequiredError}
|
|
219
|
+
* has one: it is a {@link ConflictError} by status and the opposite of one by
|
|
220
|
+
* nature — it clears only when the caller decides, never by waiting — so
|
|
221
|
+
* {@link isTransient} says no to it. A subclass, so `instanceof ConflictError`
|
|
222
|
+
* written before this existed still catches it.
|
|
223
|
+
*
|
|
224
|
+
* Raised only for the platform's explicit `reason: "exists"`, so the class is
|
|
225
|
+
* the claim: something is at the path. A create-only 409 whose reason could
|
|
226
|
+
* not be read is {@link CreateOnlyConflictError} instead, which claims nothing
|
|
227
|
+
* about the path.
|
|
228
|
+
*/
|
|
229
|
+
export declare class FileExistsError extends ConflictError {
|
|
230
|
+
name: string;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* A create-only upload refused with 409 whose reason could not be read.
|
|
234
|
+
*
|
|
235
|
+
* `PUT /computers/{id}/files?overwrite=false` is answered 409 `exists`
|
|
236
|
+
* ({@link FileExistsError}) or 409 `unsupported` when it is refused. A 409 can
|
|
237
|
+
* also arrive with no usable reason: the body interrupted, empty, a proxy's
|
|
238
|
+
* page instead of the platform's JSON, or JSON whose `reason` is missing, not a
|
|
239
|
+
* string, or blank. {@link Api} raises that refusal as this class (see
|
|
240
|
+
* {@link createOnlyRefusal}), with {@link APIError.reason} `undefined` and a
|
|
241
|
+
* message saying the reason is unknown. It does NOT say the path is taken, and
|
|
242
|
+
* it does not say whether the write landed.
|
|
243
|
+
*
|
|
244
|
+
* Final, not transient: {@link isTransient} says no to it. Sending the same
|
|
245
|
+
* create-only write again repeats a refusal that was not said to clear, and a
|
|
246
|
+
* delayed retry after the path is cleared could create the file when no one
|
|
247
|
+
* expected it. Read the path to find out what is there before deciding. The
|
|
248
|
+
* raw body stays on {@link APIError.body} for diagnostics. A subclass of
|
|
249
|
+
* {@link ConflictError}, so `instanceof ConflictError` still catches it.
|
|
250
|
+
*/
|
|
251
|
+
export declare class CreateOnlyConflictError extends ConflictError {
|
|
252
|
+
name: string;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* A create-only upload's 409, never left looking like a passing conflict.
|
|
256
|
+
*
|
|
257
|
+
* Applied by {@link Api} to every `PUT computers/:id/files` sent with
|
|
258
|
+
* `overwrite=false`, so an embedder's {@link isTransient} and this server's
|
|
259
|
+
* tools give one answer. The platform's taken path is 409 `exists`, which
|
|
260
|
+
* {@link errorForStatus} already maps to {@link FileExistsError}. A 409 without
|
|
261
|
+
* a usable word — the body lost, empty, a proxy's page, or JSON whose `reason`
|
|
262
|
+
* is missing, not a string, or blank — would otherwise be a bare
|
|
263
|
+
* {@link ConflictError} that {@link isTransient} calls worth sending again: a
|
|
264
|
+
* retry of a refusal that does not clear, and one that could create the file
|
|
265
|
+
* later if the path were cleared in between. So it is a
|
|
266
|
+
* {@link CreateOnlyConflictError} here, final, with a neutral message: not the
|
|
267
|
+
* body's own text, which could say "already exists" without the `exists`
|
|
268
|
+
* reason. The body stays on the error for diagnostics. A 409 that DID carry a
|
|
269
|
+
* string reason keeps the platform's classification, whatever the word.
|
|
270
|
+
*/
|
|
271
|
+
export declare function createOnlyRefusal(err: APIError): APIError;
|
|
272
|
+
/**
|
|
273
|
+
* Whether this request is a create-only upload: `PUT computers/:id/files` with
|
|
274
|
+
* `overwrite=false`. The only request {@link createOnlyRefusal} applies to.
|
|
275
|
+
*/
|
|
276
|
+
export declare function isCreateOnlyUpload(method: string, path: string, query: Record<string, string | number | boolean | undefined> | undefined): boolean;
|
|
185
277
|
/**
|
|
186
278
|
* 416 — the `Range` named no byte the file has.
|
|
187
279
|
*
|
|
@@ -200,7 +292,7 @@ export declare class RangeNotSatisfiableError extends APIError {
|
|
|
200
292
|
name: string;
|
|
201
293
|
constructor(message: string, status: number, body?: unknown,
|
|
202
294
|
/** The file's real length, off `Content-Range`, when the response sent one. */
|
|
203
|
-
size?: number | undefined, retryAfterMs?: number);
|
|
295
|
+
size?: number | undefined, retryAfterMs?: number, metadata?: APIErrorMetadata);
|
|
204
296
|
}
|
|
205
297
|
/**
|
|
206
298
|
* 429 — the request is valid; the caller has spent a temporary rate budget.
|
|
@@ -219,12 +311,27 @@ export declare class RateLimitError extends APIError {
|
|
|
219
311
|
name: string;
|
|
220
312
|
constructor(message: string, status: number, body?: unknown,
|
|
221
313
|
/** From `Retry-After`, in milliseconds from now, when the response sent one. */
|
|
222
|
-
retryAfterMs?: number);
|
|
314
|
+
retryAfterMs?: number, metadata?: APIErrorMetadata);
|
|
223
315
|
}
|
|
224
|
-
/**
|
|
316
|
+
/**
|
|
317
|
+
* 503 — something the request depends on (a hypervisor, a store, a host's
|
|
318
|
+
* capacity) could not answer or take it right now.
|
|
319
|
+
*
|
|
320
|
+
* A READ answered 503 can be asked again shortly. A CHANGE answered 503 may or
|
|
321
|
+
* may not have happened: the platform answers a failure after the request was
|
|
322
|
+
* sent the same way, with or without a warning in the message. So
|
|
323
|
+
* {@link isTransient} calls a 503 worth repeating only for a request that is
|
|
324
|
+
* safe to repeat — a GET or HEAD, see {@link REPEATABLE_METHODS} — and any
|
|
325
|
+
* change has its current state read before it is sent again.
|
|
326
|
+
*/
|
|
225
327
|
export declare class UnavailableError extends APIError {
|
|
226
328
|
name: string;
|
|
227
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Whether a `503` leaves the request's outcome unknown: it was a change, or its
|
|
332
|
+
* method was not recorded.
|
|
333
|
+
*/
|
|
334
|
+
export declare function outcomeUnknownOn503(err: unknown): boolean;
|
|
228
335
|
/**
|
|
229
336
|
* The request was given up on before the platform answered.
|
|
230
337
|
*
|
|
@@ -464,7 +571,7 @@ export declare class OriginTLSError extends APIError {
|
|
|
464
571
|
*/
|
|
465
572
|
export declare function platformSaid(body: unknown): string | undefined;
|
|
466
573
|
/** Build the error for a status, with the platform's own message when it sent one. */
|
|
467
|
-
export declare function errorForStatus(status: number, message: string, body?: unknown, retryAfterMs?: number): APIError;
|
|
574
|
+
export declare function errorForStatus(status: number, message: string, body?: unknown, retryAfterMs?: number, metadata?: APIErrorMetadata): APIError;
|
|
468
575
|
/**
|
|
469
576
|
* Whether an error is worth trying again without changing the request.
|
|
470
577
|
*
|
|
@@ -474,7 +581,9 @@ export declare function errorForStatus(status: number, message: string, body?: u
|
|
|
474
581
|
* including one that creates something — so it names only failures that both
|
|
475
582
|
* clear on their own AND are safe to replay blind.
|
|
476
583
|
*
|
|
477
|
-
*
|
|
584
|
+
* Terminal authentication, authority, payment, missing-resource and method
|
|
585
|
+
* refusals stay terminal even with a contradictory reason. Other cases are
|
|
586
|
+
* answered by TYPE, which is the OPL-3724
|
|
478
587
|
* decision written down. Three clients had drifted into three mechanisms for
|
|
479
588
|
* one question: this file matched classes plus a list of numbers, the
|
|
480
589
|
* TypeScript SDK matched classes alone, and the Python SDK named the fatal
|
|
@@ -485,7 +594,9 @@ export declare function errorForStatus(status: number, message: string, body?: u
|
|
|
485
594
|
* - {@link ConflictError} — something is in flight that this cannot run
|
|
486
595
|
* alongside, minus the one that is a decision
|
|
487
596
|
* - {@link RateLimitError} — a cadence, and the response usually says how long
|
|
488
|
-
* - {@link UnavailableError} —
|
|
597
|
+
* - {@link UnavailableError} — something briefly out of reach, for a GET or
|
|
598
|
+
* HEAD only. Any change answered 503 may have happened, so it is not
|
|
599
|
+
* transient, whatever `reason` it carries
|
|
489
600
|
* - {@link ConnectivityError} — the request never left
|
|
490
601
|
*
|
|
491
602
|
* That last line is now literally true, and it was not always. The class used
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAC5B,IAAI,SAAkB;CAChC;AAED,qBAAa,QAAS,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|