humanish 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -31
- package/dist/claude-agent-sdk.js +14 -7
- package/dist/claude-agent-sdk.js.map +1 -1
- package/dist/codex-app-server-ui.d.ts +1 -1
- package/dist/codex-app-server-ui.js +69 -39
- package/dist/codex-app-server-ui.js.map +1 -1
- package/dist/codex-app-server.d.ts +3 -0
- package/dist/codex-app-server.js +15 -8
- package/dist/codex-app-server.js.map +1 -1
- package/dist/concurrent-shared-world-lab.js +18 -16
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/core/git-state.d.ts +2 -0
- package/dist/core/git-state.js +152 -17
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/git-workspace.d.ts +31 -0
- package/dist/core/git-workspace.js +447 -0
- package/dist/core/git-workspace.js.map +1 -0
- package/dist/cua-actor-lab.d.ts +3 -2
- package/dist/cua-actor-lab.js +34 -23
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.js +111 -46
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/feedback.js +139 -101
- package/dist/feedback.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.js +108 -22
- package/dist/init.js.map +1 -1
- package/dist/lab-config.d.ts +5 -0
- package/dist/lab-config.js +38 -0
- package/dist/lab-config.js.map +1 -1
- package/dist/labs.js +258 -52
- package/dist/labs.js.map +1 -1
- package/dist/observer-static.js +131 -17
- package/dist/observer-static.js.map +1 -1
- package/dist/observer.js +263 -66
- package/dist/observer.js.map +1 -1
- package/dist/openai-responses-cu.js +18 -4
- package/dist/openai-responses-cu.js.map +1 -1
- package/dist/oss-lab.js +59 -14
- package/dist/oss-lab.js.map +1 -1
- package/dist/oss-meta-lab.d.ts +2 -4
- package/dist/oss-meta-lab.js +117 -477
- package/dist/oss-meta-lab.js.map +1 -1
- package/dist/program.js +23 -21
- package/dist/program.js.map +1 -1
- package/dist/run-paths.d.ts +56 -0
- package/dist/run-paths.js +340 -0
- package/dist/run-paths.js.map +1 -0
- package/dist/run.d.ts +14 -4
- package/dist/run.js +595 -306
- package/dist/run.js.map +1 -1
- package/dist/scripted-browser-actor.d.ts +7 -4
- package/dist/scripted-browser-actor.js +154 -41
- package/dist/scripted-browser-actor.js.map +1 -1
- package/dist/scripted-browser-lab.js +95 -45
- package/dist/scripted-browser-lab.js.map +1 -1
- package/dist/selected-output-paths.d.ts +49 -0
- package/dist/selected-output-paths.js +354 -0
- package/dist/selected-output-paths.js.map +1 -0
- package/dist/shared-world-lab.js +13 -12
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/source-archive.js +44 -1
- package/dist/source-archive.js.map +1 -1
- package/docs/architecture/oss-lab-poc.md +8 -0
- package/docs/contracts/policy.md +7 -1
- package/docs/goals/current.md +20 -1
- package/docs/product/open-source-install-experience.md +9 -1
- package/docs/ramp/README.md +14 -7
- package/package.json +1 -1
package/dist/labs.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { lstat, open, readdir, realpath } from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { parse } from "yaml";
|
|
4
5
|
import { parseLabConfig } from "./lab-config.js";
|
|
6
|
+
import { assertPreparedSelectedOutputDirectory, assertSafeOutputPathSegment, prepareSelectedOutputDirectory, readContainedRegularFile } from "./selected-output-paths.js";
|
|
5
7
|
export { LAB_CONFIG_SCHEMA } from "./lab-config.js";
|
|
6
8
|
export const LAB_LIST_SCHEMA = "humanish.lab-list.v1";
|
|
7
9
|
export const LAB_INSPECT_SCHEMA = "humanish.lab-inspect.v1";
|
|
@@ -13,68 +15,126 @@ const ignoredLabsDirs = [
|
|
|
13
15
|
export async function resolveLabManifest(cwd, lab) {
|
|
14
16
|
const resolvedCwd = path.resolve(cwd);
|
|
15
17
|
const warnings = [];
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
const projectRoot = await bindProjectRoot(resolvedCwd);
|
|
19
|
+
if (!projectRoot) {
|
|
20
|
+
return invalidLab({ cwd: resolvedCwd, lab, warnings }, "Project root failed containment validation.");
|
|
21
|
+
}
|
|
22
|
+
if (labLooksLikePath(lab)) {
|
|
23
|
+
const requestedPath = path.resolve(resolvedCwd, lab);
|
|
24
|
+
const read = await readExplicitManifest(projectRoot, requestedPath);
|
|
25
|
+
if (read.status === "missing") {
|
|
26
|
+
return labNotFound(resolvedCwd, lab, warnings);
|
|
27
|
+
}
|
|
28
|
+
if (read.status === "unsafe") {
|
|
29
|
+
return invalidLab({ cwd: resolvedCwd, lab, warnings }, read.message);
|
|
30
|
+
}
|
|
31
|
+
return parseResolvedLab({
|
|
32
|
+
cwd: resolvedCwd,
|
|
33
|
+
lab,
|
|
34
|
+
origin: "explicit",
|
|
35
|
+
path: requestedPath,
|
|
36
|
+
warnings,
|
|
37
|
+
contents: read.contents
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const candidates = [
|
|
41
|
+
{ origin: "committed", relativePath: path.join(committedLabsDir, `${lab}.yaml`) },
|
|
42
|
+
{ origin: "committed", relativePath: path.join(committedLabsDir, `${lab}.yml`) },
|
|
43
|
+
...ignoredLabsDirs.flatMap((dir) => [
|
|
44
|
+
{ origin: "ignored", relativePath: path.join(dir, `${lab}.yaml`) },
|
|
45
|
+
{ origin: "ignored", relativePath: path.join(dir, `${lab}.yml`) }
|
|
46
|
+
])
|
|
47
|
+
];
|
|
26
48
|
for (const candidate of candidates) {
|
|
27
|
-
|
|
49
|
+
const requestedPath = path.join(resolvedCwd, candidate.relativePath);
|
|
50
|
+
const read = await readManagedManifest(projectRoot, candidate.relativePath);
|
|
51
|
+
if (read.status === "missing") {
|
|
28
52
|
continue;
|
|
29
53
|
}
|
|
54
|
+
if (read.status === "unsafe") {
|
|
55
|
+
return invalidLab({ cwd: resolvedCwd, lab, warnings }, read.message);
|
|
56
|
+
}
|
|
30
57
|
return parseResolvedLab({
|
|
31
58
|
cwd: resolvedCwd,
|
|
32
59
|
lab,
|
|
33
60
|
origin: candidate.origin,
|
|
34
|
-
path:
|
|
35
|
-
warnings
|
|
61
|
+
path: requestedPath,
|
|
62
|
+
warnings,
|
|
63
|
+
contents: read.contents
|
|
36
64
|
});
|
|
37
65
|
}
|
|
38
|
-
return
|
|
39
|
-
ok: false,
|
|
40
|
-
cwd: resolvedCwd,
|
|
41
|
-
lab,
|
|
42
|
-
error: {
|
|
43
|
-
code: "HUMANISH_LAB_NOT_FOUND",
|
|
44
|
-
message: `Lab not found: ${lab}. Look in humanish/labs/ or pass a .yaml path.`
|
|
45
|
-
},
|
|
46
|
-
warnings
|
|
47
|
-
};
|
|
66
|
+
return labNotFound(resolvedCwd, lab, warnings);
|
|
48
67
|
}
|
|
49
68
|
export async function listLabManifests(cwd) {
|
|
50
69
|
const resolvedCwd = path.resolve(cwd);
|
|
51
70
|
const warnings = [];
|
|
52
71
|
const labs = new Map();
|
|
72
|
+
const projectRoot = await bindProjectRoot(resolvedCwd);
|
|
73
|
+
if (!projectRoot) {
|
|
74
|
+
return {
|
|
75
|
+
schema: LAB_LIST_SCHEMA,
|
|
76
|
+
ok: true,
|
|
77
|
+
cwd: resolvedCwd,
|
|
78
|
+
labs: [],
|
|
79
|
+
warnings: ["Project root failed containment validation; managed lab manifests were skipped."]
|
|
80
|
+
};
|
|
81
|
+
}
|
|
53
82
|
const dirs = [
|
|
54
|
-
{ origin: "committed",
|
|
55
|
-
...ignoredLabsDirs.map((
|
|
83
|
+
{ origin: "committed", relativeDir: committedLabsDir },
|
|
84
|
+
...ignoredLabsDirs.map((relativeDir) => ({ origin: "ignored", relativeDir }))
|
|
56
85
|
];
|
|
57
86
|
for (const entry of dirs) {
|
|
58
|
-
const
|
|
87
|
+
const directory = await bindManagedDirectory(projectRoot, entry.relativeDir);
|
|
88
|
+
if (directory.status === "missing") {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (directory.status === "unsafe") {
|
|
92
|
+
warnings.push(`${entry.relativeDir}: ${directory.message}`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
let names;
|
|
96
|
+
try {
|
|
97
|
+
names = await readdir(directory.binding.physicalPath);
|
|
98
|
+
await assertManagedDirectoryBinding(projectRoot, entry.relativeDir, directory.binding);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
warnings.push(`${entry.relativeDir}: unsafe managed lab directory; skipped.`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
59
104
|
for (const name of names.filter((value) => value.endsWith(".yaml") || value.endsWith(".yml"))) {
|
|
60
|
-
|
|
61
|
-
|
|
105
|
+
let relativePath;
|
|
106
|
+
try {
|
|
107
|
+
assertSafeOutputPathSegment(name, "Lab manifest name");
|
|
108
|
+
relativePath = path.join(entry.relativeDir, name);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
warnings.push(`${entry.relativeDir}: unsafe lab manifest name; skipped.`);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const requestedPath = path.join(resolvedCwd, relativePath);
|
|
115
|
+
const read = await readManagedManifest(projectRoot, relativePath);
|
|
116
|
+
if (read.status !== "ok") {
|
|
117
|
+
warnings.push(`${relativeToCwd(resolvedCwd, requestedPath)}: ${read.status === "unsafe" ? read.message : "manifest changed while it was listed; skipped."}`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const parsed = parseResolvedLab({
|
|
62
121
|
cwd: resolvedCwd,
|
|
63
122
|
lab: name.replace(/\.(?:ya?ml)$/i, ""),
|
|
64
123
|
origin: entry.origin,
|
|
65
|
-
path:
|
|
66
|
-
warnings: []
|
|
124
|
+
path: requestedPath,
|
|
125
|
+
warnings: [],
|
|
126
|
+
contents: read.contents
|
|
67
127
|
});
|
|
68
128
|
if (!parsed.ok) {
|
|
69
|
-
warnings.push(`${relativeToCwd(resolvedCwd,
|
|
129
|
+
warnings.push(`${relativeToCwd(resolvedCwd, requestedPath)}: ${parsed.error.message}`);
|
|
70
130
|
continue;
|
|
71
131
|
}
|
|
72
|
-
const key = `${parsed.config.id}:${entry.origin}:${relativeToCwd(resolvedCwd,
|
|
132
|
+
const key = `${parsed.config.id}:${entry.origin}:${relativeToCwd(resolvedCwd, requestedPath)}`;
|
|
73
133
|
labs.set(key, {
|
|
74
134
|
id: parsed.config.id,
|
|
75
135
|
source: parsed.config.subject.source,
|
|
76
136
|
origin: entry.origin,
|
|
77
|
-
path: relativeToCwd(resolvedCwd,
|
|
137
|
+
path: relativeToCwd(resolvedCwd, requestedPath),
|
|
78
138
|
...(parsed.config.title ? { title: parsed.config.title } : {})
|
|
79
139
|
});
|
|
80
140
|
}
|
|
@@ -110,10 +170,10 @@ export async function inspectLabManifest(cwd, lab) {
|
|
|
110
170
|
warnings: resolved.warnings
|
|
111
171
|
};
|
|
112
172
|
}
|
|
113
|
-
|
|
173
|
+
function parseResolvedLab(args) {
|
|
114
174
|
let raw;
|
|
115
175
|
try {
|
|
116
|
-
raw = parse(
|
|
176
|
+
raw = parse(args.contents);
|
|
117
177
|
}
|
|
118
178
|
catch (error) {
|
|
119
179
|
return invalidLab(args, error instanceof Error ? error.message : "Lab YAML could not be parsed.");
|
|
@@ -134,6 +194,153 @@ async function parseResolvedLab(args) {
|
|
|
134
194
|
warnings
|
|
135
195
|
};
|
|
136
196
|
}
|
|
197
|
+
async function bindProjectRoot(cwd) {
|
|
198
|
+
try {
|
|
199
|
+
const lexical = await lstat(cwd);
|
|
200
|
+
if (!lexical.isDirectory() && !lexical.isSymbolicLink()) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
return await prepareSelectedOutputDirectory(path.dirname(cwd), cwd);
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async function readManagedManifest(projectRoot, relativePath) {
|
|
210
|
+
const inspected = await inspectManagedPath(projectRoot, relativePath, "file");
|
|
211
|
+
if (inspected.status !== "ok") {
|
|
212
|
+
return inspected;
|
|
213
|
+
}
|
|
214
|
+
const contents = await readContainedRegularFile(projectRoot, relativePath.replace(/\\/g, "/"));
|
|
215
|
+
if (!contents) {
|
|
216
|
+
return { status: "unsafe", message: "Managed lab manifest changed or failed containment validation." };
|
|
217
|
+
}
|
|
218
|
+
return { status: "ok", contents: contents.toString("utf8") };
|
|
219
|
+
}
|
|
220
|
+
async function readExplicitManifest(projectRoot, requestedPath) {
|
|
221
|
+
try {
|
|
222
|
+
await assertPreparedSelectedOutputDirectory(projectRoot);
|
|
223
|
+
try {
|
|
224
|
+
await lstat(requestedPath);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
228
|
+
return { status: "missing" };
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
const physicalPath = await realpath(requestedPath);
|
|
233
|
+
const before = await lstat(physicalPath, { bigint: true });
|
|
234
|
+
if (!before.isFile() || before.isSymbolicLink() || before.nlink !== 1n) {
|
|
235
|
+
return { status: "unsafe", message: "Explicit lab manifest must resolve to a single-link regular file." };
|
|
236
|
+
}
|
|
237
|
+
const handle = await open(physicalPath, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
238
|
+
try {
|
|
239
|
+
const opened = await handle.stat({ bigint: true });
|
|
240
|
+
if (!opened.isFile()
|
|
241
|
+
|| opened.nlink !== 1n
|
|
242
|
+
|| opened.dev !== before.dev
|
|
243
|
+
|| opened.ino !== before.ino) {
|
|
244
|
+
return { status: "unsafe", message: "Explicit lab manifest changed before it could be read safely." };
|
|
245
|
+
}
|
|
246
|
+
const contents = await handle.readFile();
|
|
247
|
+
const [currentPhysicalPath, after] = await Promise.all([
|
|
248
|
+
realpath(requestedPath),
|
|
249
|
+
lstat(physicalPath, { bigint: true })
|
|
250
|
+
]);
|
|
251
|
+
await assertPreparedSelectedOutputDirectory(projectRoot);
|
|
252
|
+
if (currentPhysicalPath !== physicalPath
|
|
253
|
+
|| !after.isFile()
|
|
254
|
+
|| after.isSymbolicLink()
|
|
255
|
+
|| after.nlink !== 1n
|
|
256
|
+
|| after.dev !== before.dev
|
|
257
|
+
|| after.ino !== before.ino) {
|
|
258
|
+
return { status: "unsafe", message: "Explicit lab manifest changed while it was being read." };
|
|
259
|
+
}
|
|
260
|
+
return { status: "ok", contents: contents.toString("utf8") };
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
await handle.close();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return { status: "unsafe", message: "Explicit lab manifest failed containment validation." };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async function bindManagedDirectory(projectRoot, relativePath) {
|
|
271
|
+
const inspected = await inspectManagedPath(projectRoot, relativePath, "directory");
|
|
272
|
+
if (inspected.status !== "ok") {
|
|
273
|
+
return inspected;
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
status: "ok",
|
|
277
|
+
binding: {
|
|
278
|
+
birthtimeNs: inspected.birthtimeNs,
|
|
279
|
+
dev: inspected.dev,
|
|
280
|
+
ino: inspected.ino,
|
|
281
|
+
physicalPath: inspected.physicalPath
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
async function inspectManagedPath(projectRoot, relativePath, expectedKind) {
|
|
286
|
+
try {
|
|
287
|
+
await assertPreparedSelectedOutputDirectory(projectRoot);
|
|
288
|
+
const segments = relativePath.replace(/\\/g, "/").split("/");
|
|
289
|
+
let current = projectRoot.physicalPath;
|
|
290
|
+
for (const [index, segment] of segments.entries()) {
|
|
291
|
+
assertSafeOutputPathSegment(segment, "Managed lab path segment");
|
|
292
|
+
current = path.join(current, segment);
|
|
293
|
+
let stats;
|
|
294
|
+
try {
|
|
295
|
+
stats = await lstat(current, { bigint: true });
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
299
|
+
return { status: "missing" };
|
|
300
|
+
}
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
303
|
+
const leaf = index === segments.length - 1;
|
|
304
|
+
if (stats.isSymbolicLink()) {
|
|
305
|
+
return { status: "unsafe", message: "Managed lab paths must not contain symbolic links." };
|
|
306
|
+
}
|
|
307
|
+
if (!leaf && !stats.isDirectory()) {
|
|
308
|
+
return { status: "unsafe", message: "Managed lab path parents must be directories." };
|
|
309
|
+
}
|
|
310
|
+
if (leaf && expectedKind === "directory" && !stats.isDirectory()) {
|
|
311
|
+
return { status: "unsafe", message: "Managed lab directory has an unsafe file type." };
|
|
312
|
+
}
|
|
313
|
+
if (leaf && expectedKind === "file" && (!stats.isFile() || stats.nlink !== 1n)) {
|
|
314
|
+
return { status: "unsafe", message: "Managed lab manifest must be a single-link regular file." };
|
|
315
|
+
}
|
|
316
|
+
if (leaf) {
|
|
317
|
+
await assertPreparedSelectedOutputDirectory(projectRoot);
|
|
318
|
+
return {
|
|
319
|
+
status: "ok",
|
|
320
|
+
birthtimeNs: stats.birthtimeNs,
|
|
321
|
+
dev: stats.dev,
|
|
322
|
+
ino: stats.ino,
|
|
323
|
+
physicalPath: current
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
return { status: "unsafe", message: "Managed lab path failed containment validation." };
|
|
330
|
+
}
|
|
331
|
+
return { status: "missing" };
|
|
332
|
+
}
|
|
333
|
+
async function assertManagedDirectoryBinding(projectRoot, relativePath, binding) {
|
|
334
|
+
await assertPreparedSelectedOutputDirectory(projectRoot);
|
|
335
|
+
const current = await inspectManagedPath(projectRoot, relativePath, "directory");
|
|
336
|
+
if (current.status !== "ok"
|
|
337
|
+
|| current.physicalPath !== binding.physicalPath
|
|
338
|
+
|| current.birthtimeNs !== binding.birthtimeNs
|
|
339
|
+
|| current.dev !== binding.dev
|
|
340
|
+
|| current.ino !== binding.ino) {
|
|
341
|
+
throw new Error("Managed lab directory identity changed after it was bound.");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
137
344
|
function invalidLab(args, message) {
|
|
138
345
|
return {
|
|
139
346
|
ok: false,
|
|
@@ -146,6 +353,18 @@ function invalidLab(args, message) {
|
|
|
146
353
|
warnings: args.warnings
|
|
147
354
|
};
|
|
148
355
|
}
|
|
356
|
+
function labNotFound(cwd, lab, warnings) {
|
|
357
|
+
return {
|
|
358
|
+
ok: false,
|
|
359
|
+
cwd,
|
|
360
|
+
lab,
|
|
361
|
+
error: {
|
|
362
|
+
code: "HUMANISH_LAB_NOT_FOUND",
|
|
363
|
+
message: `Lab not found: ${lab}. Look in humanish/labs/ or pass a .yaml path.`
|
|
364
|
+
},
|
|
365
|
+
warnings
|
|
366
|
+
};
|
|
367
|
+
}
|
|
149
368
|
function labLooksLikePath(lab) {
|
|
150
369
|
return lab.endsWith(".yaml")
|
|
151
370
|
|| lab.endsWith(".yml")
|
|
@@ -153,24 +372,11 @@ function labLooksLikePath(lab) {
|
|
|
153
372
|
|| lab.includes("\\")
|
|
154
373
|
|| lab.startsWith(".");
|
|
155
374
|
}
|
|
156
|
-
async function fileExists(filePath) {
|
|
157
|
-
try {
|
|
158
|
-
return (await stat(filePath)).isFile();
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
async function safeReadDir(dir) {
|
|
165
|
-
try {
|
|
166
|
-
return await readdir(dir);
|
|
167
|
-
}
|
|
168
|
-
catch {
|
|
169
|
-
return [];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
375
|
function relativeToCwd(cwd, filePath) {
|
|
173
376
|
const relative = path.relative(cwd, filePath);
|
|
174
377
|
return relative && !relative.startsWith("..") ? relative : filePath;
|
|
175
378
|
}
|
|
379
|
+
function isNodeError(error) {
|
|
380
|
+
return error instanceof Error && "code" in error;
|
|
381
|
+
}
|
|
176
382
|
//# sourceMappingURL=labs.js.map
|
package/dist/labs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labs.js","sourceRoot":"","sources":["../src/labs.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"labs.js","sourceRoot":"","sources":["../src/labs.ts"],"names":[],"mappings":"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"}
|
package/dist/observer-static.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { constants as fsConstants } from "node:fs";
|
|
1
2
|
import { createServer } from "node:http";
|
|
2
|
-
import {
|
|
3
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
// Loopback-only host for the Observer static server. We never bind 0.0.0.0:
|
|
5
6
|
// the Observer surfaces local run evidence and must stay reachable only from
|
|
@@ -38,9 +39,22 @@ export function observerStaticContentType(filePath) {
|
|
|
38
39
|
* socket.
|
|
39
40
|
*/
|
|
40
41
|
export async function respondToObserverStaticRequest(options, request, response) {
|
|
41
|
-
|
|
42
|
+
try {
|
|
43
|
+
const root = await pinStaticRoot(options.root);
|
|
44
|
+
await respondToPinnedObserverStaticRequest(root, options, request, response);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
if (response.headersSent) {
|
|
48
|
+
response.end();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
writeText(response, 500, "Observer request failed");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function respondToPinnedObserverStaticRequest(root, options, request, response) {
|
|
42
55
|
const indexRelative = options.indexPath ?? "index.html";
|
|
43
56
|
try {
|
|
57
|
+
await assertPinnedStaticRoot(root);
|
|
44
58
|
const method = request.method ?? "GET";
|
|
45
59
|
if (method !== "GET" && method !== "HEAD") {
|
|
46
60
|
writeText(response, 405, "Method Not Allowed");
|
|
@@ -81,32 +95,33 @@ export async function respondToObserverStaticRequest(options, request, response)
|
|
|
81
95
|
if (relative === "" || relative.endsWith("/")) {
|
|
82
96
|
relative = `${relative}${indexRelative}`;
|
|
83
97
|
}
|
|
84
|
-
const target = path.resolve(root, relative);
|
|
85
|
-
if (!isPathInside(root, target)) {
|
|
98
|
+
const target = path.resolve(root.physicalPath, relative);
|
|
99
|
+
if (!isPathInside(root.physicalPath, target)) {
|
|
86
100
|
writeText(response, 403, "Forbidden");
|
|
87
101
|
return;
|
|
88
102
|
}
|
|
89
103
|
let info;
|
|
90
104
|
try {
|
|
91
|
-
info = await
|
|
105
|
+
info = await lstat(target);
|
|
92
106
|
}
|
|
93
107
|
catch {
|
|
94
108
|
writeText(response, 404, "Not Found");
|
|
95
109
|
return;
|
|
96
110
|
}
|
|
111
|
+
if (info.isSymbolicLink()) {
|
|
112
|
+
writeText(response, 403, "Forbidden");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
97
115
|
let filePath = target;
|
|
98
116
|
if (info.isDirectory()) {
|
|
99
117
|
filePath = path.resolve(target, indexRelative);
|
|
100
|
-
if (!isPathInside(root, filePath)) {
|
|
118
|
+
if (!isPathInside(root.physicalPath, filePath)) {
|
|
101
119
|
writeText(response, 403, "Forbidden");
|
|
102
120
|
return;
|
|
103
121
|
}
|
|
104
122
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
body = await readFile(filePath);
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
123
|
+
const body = await readContainedRegularFile(root, filePath);
|
|
124
|
+
if (!body) {
|
|
110
125
|
writeText(response, 404, "Not Found");
|
|
111
126
|
return;
|
|
112
127
|
}
|
|
@@ -121,26 +136,78 @@ export async function respondToObserverStaticRequest(options, request, response)
|
|
|
121
136
|
}
|
|
122
137
|
response.end(body);
|
|
123
138
|
}
|
|
124
|
-
catch
|
|
139
|
+
catch {
|
|
125
140
|
if (response.headersSent) {
|
|
126
141
|
response.end();
|
|
127
142
|
return;
|
|
128
143
|
}
|
|
129
|
-
writeText(response, 500,
|
|
144
|
+
writeText(response, 500, "Observer request failed");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function readContainedRegularFile(root, filePathInput) {
|
|
148
|
+
const filePath = path.resolve(filePathInput);
|
|
149
|
+
if (!isPathInside(root.physicalPath, filePath))
|
|
150
|
+
return null;
|
|
151
|
+
try {
|
|
152
|
+
await assertPinnedStaticRoot(root);
|
|
153
|
+
const expectedStats = await inspectContainedStaticFile(root, filePath);
|
|
154
|
+
if (!expectedStats) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const handle = await open(filePath, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
|
|
158
|
+
try {
|
|
159
|
+
const openedStats = await handle.stat({ bigint: true });
|
|
160
|
+
if (!openedStats.isFile()
|
|
161
|
+
|| openedStats.nlink !== 1n
|
|
162
|
+
|| openedStats.dev !== expectedStats.dev
|
|
163
|
+
|| openedStats.ino !== expectedStats.ino) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const recheckedStats = await inspectContainedStaticFile(root, filePath);
|
|
167
|
+
if (!recheckedStats
|
|
168
|
+
|| recheckedStats.dev !== expectedStats.dev
|
|
169
|
+
|| recheckedStats.ino !== expectedStats.ino) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
await assertPinnedStaticRoot(root);
|
|
173
|
+
const body = await handle.readFile();
|
|
174
|
+
await assertPinnedStaticRoot(root);
|
|
175
|
+
return body;
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
await handle.close();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return null;
|
|
130
183
|
}
|
|
131
184
|
}
|
|
132
185
|
export function createObserverStaticHandler(options) {
|
|
186
|
+
let rootPromise;
|
|
133
187
|
return (request, response) => {
|
|
134
|
-
|
|
188
|
+
rootPromise ??= pinStaticRoot(options.root);
|
|
189
|
+
void rootPromise
|
|
190
|
+
.then((root) => respondToPinnedObserverStaticRequest(root, options, request, response))
|
|
191
|
+
.catch(() => {
|
|
192
|
+
if (response.headersSent) {
|
|
193
|
+
response.end();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
writeText(response, 500, "Observer request failed");
|
|
197
|
+
});
|
|
135
198
|
};
|
|
136
199
|
}
|
|
137
200
|
export async function serveObserverStatic(options) {
|
|
138
201
|
const entryPath = options.entryPath?.replace(/^\/+/, "") ?? "";
|
|
139
|
-
const
|
|
202
|
+
const handlerOptions = {
|
|
140
203
|
root: options.root,
|
|
141
204
|
...(options.indexPath === undefined ? {} : { indexPath: options.indexPath }),
|
|
142
205
|
...(entryPath ? { redirectRootTo: entryPath } : {})
|
|
143
|
-
}
|
|
206
|
+
};
|
|
207
|
+
const root = await pinStaticRoot(options.root);
|
|
208
|
+
const handler = (request, response) => {
|
|
209
|
+
void respondToPinnedObserverStaticRequest(root, handlerOptions, request, response);
|
|
210
|
+
};
|
|
144
211
|
const server = createServer(handler);
|
|
145
212
|
const port = await listen(server, options.port ?? 0);
|
|
146
213
|
return {
|
|
@@ -161,7 +228,54 @@ function writeText(response, status, message) {
|
|
|
161
228
|
}
|
|
162
229
|
function isPathInside(root, candidate) {
|
|
163
230
|
const relative = path.relative(root, candidate);
|
|
164
|
-
return relative === ""
|
|
231
|
+
return relative === ""
|
|
232
|
+
|| (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
|
|
233
|
+
}
|
|
234
|
+
async function inspectContainedStaticFile(root, filePath) {
|
|
235
|
+
const relative = path.relative(root.physicalPath, filePath);
|
|
236
|
+
if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const segments = relative.split(path.sep).filter(Boolean);
|
|
240
|
+
let current = root.physicalPath;
|
|
241
|
+
let fileIdentity = null;
|
|
242
|
+
for (const [index, segment] of segments.entries()) {
|
|
243
|
+
current = path.join(current, segment);
|
|
244
|
+
const stats = await lstat(current, { bigint: true });
|
|
245
|
+
if (stats.isSymbolicLink())
|
|
246
|
+
return null;
|
|
247
|
+
if (index < segments.length - 1) {
|
|
248
|
+
if (!stats.isDirectory())
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
if (!stats.isFile() || stats.nlink !== 1n)
|
|
253
|
+
return null;
|
|
254
|
+
fileIdentity = { dev: stats.dev, ino: stats.ino };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (await realpath(filePath) !== filePath)
|
|
258
|
+
return null;
|
|
259
|
+
return fileIdentity;
|
|
260
|
+
}
|
|
261
|
+
async function pinStaticRoot(rootInput) {
|
|
262
|
+
const physicalPath = await realpath(path.resolve(rootInput));
|
|
263
|
+
const stats = await lstat(physicalPath, { bigint: true });
|
|
264
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
265
|
+
throw new Error("Observer static roots must be physical directories.");
|
|
266
|
+
}
|
|
267
|
+
return Object.freeze({ birthtimeNs: stats.birthtimeNs, dev: stats.dev, ino: stats.ino, physicalPath });
|
|
268
|
+
}
|
|
269
|
+
async function assertPinnedStaticRoot(root) {
|
|
270
|
+
const stats = await lstat(root.physicalPath, { bigint: true });
|
|
271
|
+
if (stats.isSymbolicLink()
|
|
272
|
+
|| !stats.isDirectory()
|
|
273
|
+
|| stats.birthtimeNs !== root.birthtimeNs
|
|
274
|
+
|| stats.dev !== root.dev
|
|
275
|
+
|| stats.ino !== root.ino
|
|
276
|
+
|| await realpath(root.physicalPath) !== root.physicalPath) {
|
|
277
|
+
throw new Error("Observer static root identity changed.");
|
|
278
|
+
}
|
|
165
279
|
}
|
|
166
280
|
function listen(server, port) {
|
|
167
281
|
return new Promise((resolve, reject) => {
|