agent-web-os 0.2.0 → 0.3.0-beta.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.
@@ -0,0 +1,2102 @@
1
+ import {
2
+ PackageManager,
3
+ Runtime,
4
+ VirtualFS,
5
+ ViteDevServer,
6
+ getServerBridge,
7
+ posixPath
8
+ } from "./chunk-I6U7BPDH.js";
9
+ import "./chunk-PR4QN5HX.js";
10
+
11
+ // src/almostnode-session.ts
12
+ var ALMOSTNODE_INTERNAL_ROOT = "/.almostnode";
13
+ var ALMOSTNODE_NODE_VERSION = "v20.0.0";
14
+ var ALMOSTNODE_NPM_VERSION = "9.6.4";
15
+ var NODE_EXEC_PATH = "/usr/local/bin/node";
16
+ var GLOBAL_NODE_MODULES_ROOT = "/usr/local/lib/node_modules";
17
+ var DEFAULT_PATH = "/usr/local/bin:/usr/bin:/bin:/node_modules/.bin";
18
+ var NPM_USAGE = [
19
+ "Usage: npm <command>",
20
+ "",
21
+ "Commands:",
22
+ " run <script> Run a script from package.json",
23
+ " start Run the start script",
24
+ " test Run the test script",
25
+ " install [pkg] Install packages",
26
+ " ls List installed packages"
27
+ ].join("\n");
28
+ var STATIC_MIME_TYPES = {
29
+ css: "text/css; charset=utf-8",
30
+ cjs: "application/javascript; charset=utf-8",
31
+ gif: "image/gif",
32
+ htm: "text/html; charset=utf-8",
33
+ html: "text/html; charset=utf-8",
34
+ ico: "image/x-icon",
35
+ jpeg: "image/jpeg",
36
+ jpg: "image/jpeg",
37
+ js: "application/javascript; charset=utf-8",
38
+ json: "application/json; charset=utf-8",
39
+ map: "application/json; charset=utf-8",
40
+ md: "text/markdown; charset=utf-8",
41
+ mjs: "application/javascript; charset=utf-8",
42
+ otf: "font/otf",
43
+ pdf: "application/pdf",
44
+ png: "image/png",
45
+ svg: "image/svg+xml",
46
+ txt: "text/plain; charset=utf-8",
47
+ wasm: "application/wasm",
48
+ webp: "image/webp",
49
+ woff: "font/woff",
50
+ woff2: "font/woff2"
51
+ };
52
+ function stripDotSlash(p) {
53
+ return p.startsWith("./") ? p.slice(2) : p;
54
+ }
55
+ function getStaticMimeType(filePath) {
56
+ const extension = filePath.split(".").pop()?.toLowerCase() || "";
57
+ return STATIC_MIME_TYPES[extension] || "application/octet-stream";
58
+ }
59
+ function getRequestPathname(requestUrl) {
60
+ return new URL(requestUrl, "http://localhost").pathname;
61
+ }
62
+ function wrapCjsAsEsm(code, virtualPrefix = "", requestPath = "") {
63
+ const stripped = code.replace(
64
+ /("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*)/g,
65
+ (match2) => " ".repeat(match2.length)
66
+ );
67
+ if (/\b(import\s+|export\s+|export\s*\{|export\s+default\b)/.test(stripped)) {
68
+ return code;
69
+ }
70
+ if (!/\b(require\s*\(|module\.exports|exports\.)/.test(stripped)) {
71
+ return code;
72
+ }
73
+ const requestDir = requestPath ? posixPath.dirname(requestPath) : "";
74
+ const commentFree = code.replace(
75
+ /("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*)/g,
76
+ (m) => {
77
+ if (m.startsWith("/*") || m.startsWith("//")) {
78
+ return " ".repeat(m.length);
79
+ }
80
+ return m;
81
+ }
82
+ );
83
+ const imports = [];
84
+ let counter = 0;
85
+ const requirePattern = /\brequire\s*\(\s*(['"])([^'"]+)\1\s*\)/g;
86
+ let rewritten = "";
87
+ let lastIndex = 0;
88
+ let match;
89
+ while ((match = requirePattern.exec(commentFree)) !== null) {
90
+ const specifier = match[2];
91
+ const varName = `__cjs_req_${counter++}__`;
92
+ let resolvedSpec;
93
+ if (specifier.startsWith(".")) {
94
+ resolvedSpec = `${virtualPrefix}${posixPath.resolve(requestDir, specifier)}`;
95
+ } else {
96
+ resolvedSpec = `${virtualPrefix}/node_modules/${specifier}`;
97
+ }
98
+ imports.push(`import ${varName} from "${resolvedSpec}";`);
99
+ rewritten += code.slice(lastIndex, match.index);
100
+ rewritten += `(${varName} && ${varName}.__esModule ? ${varName}.default : ${varName})`;
101
+ lastIndex = match.index + match[0].length;
102
+ }
103
+ rewritten += code.slice(lastIndex);
104
+ const reExportPattern = /module\.exports\s*=\s*\(__cjs_req_(\d+)__\s*&&\s*__cjs_req_\1__\.__esModule\s*\?\s*__cjs_req_\1__\.default\s*:\s*__cjs_req_\1__\)/g;
105
+ const reExportCandidates = [];
106
+ let reM;
107
+ while ((reM = reExportPattern.exec(rewritten)) !== null) {
108
+ const reExportVar = `__cjs_req_${reM[1]}__`;
109
+ const reExportImport = imports.find((i) => i.includes(reExportVar));
110
+ if (reExportImport) {
111
+ const specMatch = reExportImport.match(/from\s+"([^"]+)"/);
112
+ if (specMatch) reExportCandidates.push(specMatch[1]);
113
+ }
114
+ }
115
+ if (reExportCandidates.length > 0) {
116
+ const picked = reExportCandidates.find((s) => /production|\.prod[\.\b]/.test(s)) ?? reExportCandidates[0];
117
+ return [
118
+ "// [monospace CJS\u2192ESM re-export]",
119
+ ...imports,
120
+ "var module = { exports: {} };",
121
+ "var exports = module.exports;",
122
+ "var process = { env: { NODE_ENV: 'production' } };",
123
+ rewritten,
124
+ "export default module.exports;",
125
+ `export * from "${picked}";`
126
+ ].join("\n");
127
+ }
128
+ const namedExports = /* @__PURE__ */ new Set();
129
+ const exportsPattern = /\bexports\.(\w+)\s*=/g;
130
+ let expMatch;
131
+ while ((expMatch = exportsPattern.exec(rewritten)) !== null) {
132
+ const name = expMatch[1];
133
+ if (name !== "__esModule") namedExports.add(name);
134
+ }
135
+ const namedExportLines = [];
136
+ if (namedExports.size > 0) {
137
+ const names = [...namedExports];
138
+ for (const name of names) {
139
+ namedExportLines.push(`var __cjs_e_${name}__ = module.exports.${name};`);
140
+ }
141
+ namedExportLines.push(
142
+ `export { ${names.map((n) => `__cjs_e_${n}__ as ${n}`).join(", ")} };`
143
+ );
144
+ }
145
+ return [
146
+ "// [monospace CJS\u2192ESM shim]",
147
+ ...imports,
148
+ "var module = { exports: {} };",
149
+ "var exports = module.exports;",
150
+ "var process = { env: { NODE_ENV: 'production' } };",
151
+ rewritten,
152
+ "export default module.exports;",
153
+ ...namedExportLines
154
+ ].join("\n");
155
+ }
156
+ var ESBUILD_WASM_VERSION = "0.20.0";
157
+ async function ensureEsbuildWasm() {
158
+ if (typeof window === "undefined") return;
159
+ if (window.__esbuild) return;
160
+ if (window.__esbuildInitPromise) {
161
+ await window.__esbuildInitPromise;
162
+ return;
163
+ }
164
+ window.__esbuildInitPromise = (async () => {
165
+ const esmUrl = `https://esm.sh/esbuild-wasm@${ESBUILD_WASM_VERSION}`;
166
+ const wasmUrl = `https://unpkg.com/esbuild-wasm@${ESBUILD_WASM_VERSION}/esbuild.wasm`;
167
+ const dynamicImport = new Function("url", "return import(url)");
168
+ const mod = await dynamicImport(esmUrl);
169
+ const esbuildMod = mod.default || mod;
170
+ try {
171
+ await esbuildMod.initialize({ wasmURL: wasmUrl });
172
+ } catch (err) {
173
+ if (err instanceof Error && err.message.includes('Cannot call "initialize" more than once')) {
174
+ } else {
175
+ window.__esbuildInitPromise = void 0;
176
+ throw err;
177
+ }
178
+ }
179
+ window.__esbuild = esbuildMod;
180
+ })();
181
+ await window.__esbuildInitPromise;
182
+ }
183
+ function normalizePath(inputPath) {
184
+ return posixPath.normalize(inputPath.trim() || "/") || "/";
185
+ }
186
+ function isInternalAlmostNodePath(targetPath) {
187
+ const normalizedPath = normalizePath(targetPath);
188
+ return normalizedPath === ALMOSTNODE_INTERNAL_ROOT || normalizedPath.startsWith(`${ALMOSTNODE_INTERNAL_ROOT}/`);
189
+ }
190
+ function appendChunk(chunks, value) {
191
+ if (!value) {
192
+ return;
193
+ }
194
+ chunks.push(value);
195
+ }
196
+ function getPackageJsonDependencyNames(pkgJson) {
197
+ const dependencyNames = [];
198
+ const dependencySections = [
199
+ pkgJson.dependencies,
200
+ pkgJson.devDependencies,
201
+ pkgJson.optionalDependencies,
202
+ pkgJson.peerDependencies
203
+ ];
204
+ for (const section of dependencySections) {
205
+ if (!section || typeof section !== "object") {
206
+ continue;
207
+ }
208
+ for (const packageName of Object.keys(section)) {
209
+ if (!dependencyNames.includes(packageName)) {
210
+ dependencyNames.push(packageName);
211
+ }
212
+ }
213
+ }
214
+ return dependencyNames;
215
+ }
216
+ function getCommandEnvironment(ctx) {
217
+ const environment = {};
218
+ for (const [key, value] of ctx.env.entries()) {
219
+ environment[key] = value;
220
+ }
221
+ return environment;
222
+ }
223
+ async function ensureObservableDirectory(fs, directoryPath) {
224
+ const normalizedPath = normalizePath(directoryPath);
225
+ if (normalizedPath === "/") {
226
+ return;
227
+ }
228
+ if (await fs.exists(normalizedPath)) {
229
+ return;
230
+ }
231
+ await fs.mkdir(normalizedPath, { recursive: true });
232
+ }
233
+ function removeVirtualPath(vfs, targetPath) {
234
+ const normalizedPath = normalizePath(targetPath);
235
+ if (normalizedPath === "/" || isInternalAlmostNodePath(normalizedPath) || !vfs.existsSync(normalizedPath)) {
236
+ return;
237
+ }
238
+ const stat = vfs.statSync(normalizedPath);
239
+ if (!stat.isDirectory()) {
240
+ vfs.unlinkSync(normalizedPath);
241
+ return;
242
+ }
243
+ for (const childName of vfs.readdirSync(normalizedPath)) {
244
+ removeVirtualPath(vfs, posixPath.join(normalizedPath, childName));
245
+ }
246
+ vfs.rmdirSync(normalizedPath);
247
+ }
248
+ var AlmostNodeVirtualFs = class extends VirtualFS {
249
+ constructor(session) {
250
+ super();
251
+ this.session = session;
252
+ }
253
+ session;
254
+ suppressMirrorCount = 0;
255
+ withoutMirror(operation) {
256
+ this.suppressMirrorCount += 1;
257
+ try {
258
+ return operation();
259
+ } finally {
260
+ this.suppressMirrorCount -= 1;
261
+ }
262
+ }
263
+ shouldMirror(targetPath) {
264
+ return this.suppressMirrorCount === 0 && !isInternalAlmostNodePath(targetPath);
265
+ }
266
+ writeFileSync(targetPath, data) {
267
+ super.writeFileSync(targetPath, data);
268
+ if (this.shouldMirror(targetPath)) {
269
+ void this.session.applyVirtualWrite(targetPath, data);
270
+ }
271
+ }
272
+ mkdirSync(targetPath, options) {
273
+ super.mkdirSync(targetPath, options);
274
+ if (this.shouldMirror(targetPath)) {
275
+ void this.session.applyVirtualMkdir(targetPath);
276
+ }
277
+ }
278
+ unlinkSync(targetPath) {
279
+ super.unlinkSync(targetPath);
280
+ if (this.shouldMirror(targetPath)) {
281
+ void this.session.applyVirtualRemove(targetPath, false);
282
+ }
283
+ }
284
+ rmdirSync(targetPath) {
285
+ super.rmdirSync(targetPath);
286
+ if (this.shouldMirror(targetPath)) {
287
+ void this.session.applyVirtualRemove(targetPath, true);
288
+ }
289
+ }
290
+ renameSync(previousPath, nextPath) {
291
+ super.renameSync(previousPath, nextPath);
292
+ if (this.shouldMirror(previousPath) && this.shouldMirror(nextPath)) {
293
+ void this.session.applyVirtualRename(previousPath, nextPath);
294
+ }
295
+ }
296
+ };
297
+ var AlmostNodeSession = class {
298
+ constructor(fs) {
299
+ this.fs = fs;
300
+ this._vfs.mkdirSync(ALMOSTNODE_INTERNAL_ROOT, { recursive: true });
301
+ this._vfs.mkdirSync("/node_modules/constants", { recursive: true });
302
+ this._vfs.writeFileSync("/node_modules/constants/package.json", JSON.stringify({
303
+ name: "constants",
304
+ version: "0.0.1",
305
+ main: "index.js"
306
+ }));
307
+ this._vfs.writeFileSync("/node_modules/constants/index.js", [
308
+ "// Node.js `constants` shim (os.constants + fs.constants)",
309
+ "var os = require('os');",
310
+ "var constants = {};",
311
+ "if (os.constants) {",
312
+ " if (os.constants.signals) Object.assign(constants, os.constants.signals);",
313
+ " if (os.constants.errno) Object.assign(constants, os.constants.errno);",
314
+ " if (os.constants.priority) Object.assign(constants, os.constants.priority);",
315
+ "}",
316
+ "// Common fs.constants used by npm packages",
317
+ "constants.O_RDONLY = 0;",
318
+ "constants.O_WRONLY = 1;",
319
+ "constants.O_RDWR = 2;",
320
+ "constants.O_CREAT = 64;",
321
+ "constants.O_EXCL = 128;",
322
+ "constants.O_TRUNC = 512;",
323
+ "constants.O_APPEND = 1024;",
324
+ "constants.O_DIRECTORY = 65536;",
325
+ "constants.O_NOFOLLOW = 131072;",
326
+ "constants.O_SYNC = 1052672;",
327
+ "constants.O_SYMLINK = 2097152;",
328
+ "constants.O_NONBLOCK = 2048;",
329
+ "constants.S_IFMT = 61440;",
330
+ "constants.S_IFREG = 32768;",
331
+ "constants.S_IFDIR = 16384;",
332
+ "constants.S_IFCHR = 8192;",
333
+ "constants.S_IFBLK = 24576;",
334
+ "constants.S_IFIFO = 4096;",
335
+ "constants.S_IFLNK = 40960;",
336
+ "constants.S_IFSOCK = 49152;",
337
+ "constants.S_IRWXU = 448;",
338
+ "constants.S_IRUSR = 256;",
339
+ "constants.S_IWUSR = 128;",
340
+ "constants.S_IXUSR = 64;",
341
+ "constants.S_IRWXG = 56;",
342
+ "constants.S_IRGRP = 32;",
343
+ "constants.S_IWGRP = 16;",
344
+ "constants.S_IXGRP = 8;",
345
+ "constants.S_IRWXO = 7;",
346
+ "constants.S_IROTH = 4;",
347
+ "constants.S_IWOTH = 2;",
348
+ "constants.S_IXOTH = 1;",
349
+ "constants.F_OK = 0;",
350
+ "constants.R_OK = 4;",
351
+ "constants.W_OK = 2;",
352
+ "constants.X_OK = 1;",
353
+ "constants.COPYFILE_EXCL = 1;",
354
+ "constants.COPYFILE_FICLONE = 2;",
355
+ "constants.COPYFILE_FICLONE_FORCE = 4;",
356
+ "constants.UV_FS_COPYFILE_EXCL = 1;",
357
+ "constants.UV_FS_COPYFILE_FICLONE = 2;",
358
+ "constants.UV_FS_COPYFILE_FICLONE_FORCE = 4;",
359
+ "module.exports = constants;"
360
+ ].join("\n"));
361
+ this._vfs.mkdirSync("/node_modules/stream", { recursive: true });
362
+ this._vfs.writeFileSync("/node_modules/stream/package.json", JSON.stringify({
363
+ name: "stream",
364
+ version: "0.0.1",
365
+ main: "index.js"
366
+ }));
367
+ this._vfs.writeFileSync(
368
+ "/node_modules/stream/index.js",
369
+ "module.exports = require('stream');"
370
+ );
371
+ this._vfs.mkdirSync("/node_modules/stream/promises", { recursive: true });
372
+ this._vfs.writeFileSync("/node_modules/stream/promises/package.json", JSON.stringify({
373
+ name: "stream-promises",
374
+ version: "0.0.1",
375
+ main: "index.js"
376
+ }));
377
+ this._vfs.writeFileSync(
378
+ "/node_modules/stream/promises/index.js",
379
+ "var stream = require('stream');\nmodule.exports = stream.promises || {};"
380
+ );
381
+ this._vfs.mkdirSync("/node_modules/stream/web", { recursive: true });
382
+ this._vfs.writeFileSync("/node_modules/stream/web/package.json", JSON.stringify({
383
+ name: "stream-web",
384
+ version: "0.0.1",
385
+ main: "index.js"
386
+ }));
387
+ this._vfs.writeFileSync("/node_modules/stream/web/index.js", [
388
+ "// Web Streams API shim \u2014 re-exports browser globals",
389
+ "module.exports = {",
390
+ " ReadableStream: typeof ReadableStream !== 'undefined' ? ReadableStream : undefined,",
391
+ " ReadableStreamDefaultReader: typeof ReadableStreamDefaultReader !== 'undefined' ? ReadableStreamDefaultReader : undefined,",
392
+ " ReadableStreamBYOBReader: typeof ReadableStreamBYOBReader !== 'undefined' ? ReadableStreamBYOBReader : undefined,",
393
+ " ReadableStreamDefaultController: typeof ReadableStreamDefaultController !== 'undefined' ? ReadableStreamDefaultController : undefined,",
394
+ " ReadableByteStreamController: typeof ReadableByteStreamController !== 'undefined' ? ReadableByteStreamController : undefined,",
395
+ " WritableStream: typeof WritableStream !== 'undefined' ? WritableStream : undefined,",
396
+ " WritableStreamDefaultWriter: typeof WritableStreamDefaultWriter !== 'undefined' ? WritableStreamDefaultWriter : undefined,",
397
+ " WritableStreamDefaultController: typeof WritableStreamDefaultController !== 'undefined' ? WritableStreamDefaultController : undefined,",
398
+ " TransformStream: typeof TransformStream !== 'undefined' ? TransformStream : undefined,",
399
+ " TransformStreamDefaultController: typeof TransformStreamDefaultController !== 'undefined' ? TransformStreamDefaultController : undefined,",
400
+ " ByteLengthQueuingStrategy: typeof ByteLengthQueuingStrategy !== 'undefined' ? ByteLengthQueuingStrategy : undefined,",
401
+ " CountQueuingStrategy: typeof CountQueuingStrategy !== 'undefined' ? CountQueuingStrategy : undefined,",
402
+ "};"
403
+ ].join("\n"));
404
+ this.disposeObservableSubscription = this.fs.subscribe((event) => {
405
+ void this.trackOperation((async () => {
406
+ if (!this.initialized || this.suppressObservableMirrorCount > 0) {
407
+ return;
408
+ }
409
+ const normalizedPath = normalizePath(event.path);
410
+ if (isInternalAlmostNodePath(normalizedPath)) {
411
+ return;
412
+ }
413
+ if (event.event === "unlink" || event.event === "unlinkDir") {
414
+ this._vfs.withoutMirror(() => {
415
+ removeVirtualPath(this._vfs, normalizedPath);
416
+ });
417
+ return;
418
+ }
419
+ await this.copyObservablePathIntoVirtualFs(normalizedPath);
420
+ })());
421
+ });
422
+ }
423
+ fs;
424
+ _vfs = new AlmostNodeVirtualFs(this);
425
+ get vfs() {
426
+ return this._vfs;
427
+ }
428
+ disposeObservableSubscription;
429
+ initializePromise = null;
430
+ initialized = false;
431
+ pendingOperations = /* @__PURE__ */ new Set();
432
+ suppressObservableMirrorCount = 0;
433
+ registeredBinCommands = /* @__PURE__ */ new Set();
434
+ binCommandRegistrar;
435
+ batchFileLoader;
436
+ stdoutWriter;
437
+ _stdinHandler = null;
438
+ _terminalColumns = 80;
439
+ _terminalRows = 24;
440
+ viteServer;
441
+ vitePort = null;
442
+ vitePreviewUrl = null;
443
+ vitePreviewListener;
444
+ parsedPackageJsonCache = /* @__PURE__ */ new Map();
445
+ transformedTextCache = /* @__PURE__ */ new Map();
446
+ dispose() {
447
+ this.disposeObservableSubscription();
448
+ this.stopViteServer();
449
+ }
450
+ setBinCommandRegistrar(registrar) {
451
+ this.binCommandRegistrar = registrar;
452
+ }
453
+ setBatchFileLoader(loader) {
454
+ this.batchFileLoader = loader;
455
+ }
456
+ setStdoutWriter(writer) {
457
+ this.stdoutWriter = writer;
458
+ }
459
+ /** Send data to the stdin of the currently running interactive process. */
460
+ writeStdin(data) {
461
+ this._stdinHandler?.(data);
462
+ }
463
+ /** Update terminal dimensions (used for process.stdout.columns/rows). */
464
+ setTerminalSize(columns, rows) {
465
+ this._terminalColumns = columns;
466
+ this._terminalRows = rows;
467
+ }
468
+ setVitePreviewListener(listener) {
469
+ this.vitePreviewListener = listener;
470
+ listener?.(this.vitePreviewUrl);
471
+ }
472
+ setViteHmrTarget(target) {
473
+ if (!target || !this.viteServer) {
474
+ return;
475
+ }
476
+ this.viteServer.setHMRTarget(target);
477
+ }
478
+ /**
479
+ * Resolve a bare module specifier (e.g. "@mui/material" or "react") to a
480
+ * `/node_modules/...` URL path that the ViteDevServer can serve.
481
+ *
482
+ * Resolution order mirrors Node/bundler conventions:
483
+ * 1. package.json "exports" (condition "import" → "default")
484
+ * 2. package.json "module"
485
+ * 3. package.json "main"
486
+ * 4. index.js / index.mjs fallback
487
+ *
488
+ * For deep imports like "@mui/material/Button", we resolve from the
489
+ * package directory directly.
490
+ */
491
+ resolveBarePkgEntryCache = /* @__PURE__ */ new Map();
492
+ parseCachedPackageJson(packageJsonPath, raw) {
493
+ const cached = this.parsedPackageJsonCache.get(packageJsonPath);
494
+ if (cached && cached.raw === raw) {
495
+ return cached.value;
496
+ }
497
+ try {
498
+ const parsed = JSON.parse(raw);
499
+ this.parsedPackageJsonCache.set(packageJsonPath, { raw, value: parsed });
500
+ return parsed;
501
+ } catch {
502
+ this.parsedPackageJsonCache.set(packageJsonPath, { raw, value: null });
503
+ return null;
504
+ }
505
+ }
506
+ transformTextWithCache(cacheKey, source, transform) {
507
+ const cached = this.transformedTextCache.get(cacheKey);
508
+ if (cached && cached.source === source) {
509
+ return cached.transformed;
510
+ }
511
+ const transformed = transform(source);
512
+ this.transformedTextCache.set(cacheKey, { source, transformed });
513
+ return transformed;
514
+ }
515
+ resolveBarePkgEntry(specifier, root) {
516
+ const cacheKey = `${root}\0${specifier}`;
517
+ const cached = this.resolveBarePkgEntryCache.get(cacheKey);
518
+ if (cached !== void 0) return cached;
519
+ const result = this._resolveBarePkgEntry(specifier, root);
520
+ this.resolveBarePkgEntryCache.set(cacheKey, result);
521
+ return result;
522
+ }
523
+ _resolveBarePkgEntry(specifier, root) {
524
+ let pkgName;
525
+ let subPath;
526
+ if (specifier.startsWith("@")) {
527
+ const parts = specifier.split("/");
528
+ pkgName = `${parts[0]}/${parts[1]}`;
529
+ subPath = parts.slice(2).join("/");
530
+ } else {
531
+ const slashIdx = specifier.indexOf("/");
532
+ if (slashIdx === -1) {
533
+ pkgName = specifier;
534
+ subPath = "";
535
+ } else {
536
+ pkgName = specifier.slice(0, slashIdx);
537
+ subPath = specifier.slice(slashIdx + 1);
538
+ }
539
+ }
540
+ const nodeModulesPath = `${root}/node_modules/${pkgName}`;
541
+ const pkgJsonPath = `${nodeModulesPath}/package.json`;
542
+ let pkgJson = null;
543
+ try {
544
+ if (this.vfs.existsSync(pkgJsonPath)) {
545
+ pkgJson = this.parseCachedPackageJson(pkgJsonPath, this.vfs.readFileSync(pkgJsonPath, "utf8"));
546
+ }
547
+ } catch {
548
+ }
549
+ if (subPath) {
550
+ if (pkgJson?.exports && typeof pkgJson.exports === "object") {
551
+ const exportsMap = pkgJson.exports;
552
+ const entry = this.resolveExportsEntry(exportsMap, `./${subPath}`) ?? this.resolveWildcardExports(exportsMap, subPath);
553
+ if (entry) return `/node_modules/${pkgName}/${stripDotSlash(entry)}`;
554
+ }
555
+ const candidates = [
556
+ `/node_modules/${pkgName}/${subPath}`,
557
+ `/node_modules/${pkgName}/${subPath}.js`,
558
+ `/node_modules/${pkgName}/${subPath}.mjs`,
559
+ `/node_modules/${pkgName}/${subPath}/index.js`,
560
+ `/node_modules/${pkgName}/${subPath}/index.mjs`
561
+ ];
562
+ for (const candidate of candidates) {
563
+ if (this.vfs.existsSync(`${root}${candidate}`)) return candidate;
564
+ }
565
+ return `/node_modules/${pkgName}/${subPath}`;
566
+ }
567
+ if (pkgJson?.exports && typeof pkgJson.exports === "object") {
568
+ const entry = this.resolveExportsEntry(pkgJson.exports, ".");
569
+ if (entry) return `/node_modules/${pkgName}/${stripDotSlash(entry)}`;
570
+ }
571
+ if (typeof pkgJson?.module === "string") {
572
+ return `/node_modules/${pkgName}/${stripDotSlash(pkgJson.module)}`;
573
+ }
574
+ if (typeof pkgJson?.main === "string") {
575
+ return `/node_modules/${pkgName}/${stripDotSlash(pkgJson.main)}`;
576
+ }
577
+ const fallbacks = [
578
+ `/node_modules/${pkgName}/index.js`,
579
+ `/node_modules/${pkgName}/index.mjs`
580
+ ];
581
+ for (const fb of fallbacks) {
582
+ if (this.vfs.existsSync(`${root}${fb}`)) return fb;
583
+ }
584
+ return `/node_modules/${pkgName}/index.js`;
585
+ }
586
+ resolveExportsEntry(exports, key) {
587
+ const entry = exports[key];
588
+ if (!entry) {
589
+ if (key === "." && typeof exports === "string") return exports;
590
+ return null;
591
+ }
592
+ return this.resolveConditionValue(entry);
593
+ }
594
+ /**
595
+ * Handle wildcard exports like "./*" → { "default": { "default": "./esm/* /index.js" } }
596
+ */
597
+ resolveWildcardExports(exports, subPath) {
598
+ const wildcardKey = "./*";
599
+ const wildcardEntry = exports[wildcardKey];
600
+ if (!wildcardEntry) return null;
601
+ const resolved = this.resolveConditionValue(wildcardEntry);
602
+ if (!resolved) return null;
603
+ return resolved.replace(/\*/g, subPath);
604
+ }
605
+ /**
606
+ * Recursively resolve a condition value from an exports entry.
607
+ * Handles: string, { import, module, default, require }, and nested conditions.
608
+ * Skips "types" conditions since we need JS, not .d.ts files.
609
+ *
610
+ * Priority: browser > module > import > default > require
611
+ * "browser" and "module" are preferred because they point to true ESM bundles.
612
+ * "import" is deprioritised because some packages (e.g. @emotion/*) map it to
613
+ * a CJS-to-ESM wrapper (.cjs.mjs) that uses require()/exports which fails
614
+ * in a browser context.
615
+ */
616
+ resolveConditionValue(value) {
617
+ if (typeof value === "string") return value;
618
+ if (typeof value !== "object" || value === null) return null;
619
+ const conditions = value;
620
+ for (const condition of ["browser", "module", "import", "default", "require"]) {
621
+ const condValue = conditions[condition];
622
+ if (condValue === void 0) continue;
623
+ if (condition === "types") continue;
624
+ const resolved = this.resolveConditionValue(condValue);
625
+ if (resolved && !resolved.endsWith(".d.ts") && !resolved.endsWith(".d.cts") && !resolved.endsWith(".d.mts")) {
626
+ return resolved;
627
+ }
628
+ }
629
+ return null;
630
+ }
631
+ /**
632
+ * Rewrite bare import specifiers in JavaScript source to /node_modules/... paths.
633
+ * When virtualPrefix is provided (e.g. "/__virtual__/5173"), prepends it to
634
+ * resolved paths so the browser stays within the service-worker-routed URL
635
+ * namespace and cascading relative imports keep going through the SW.
636
+ */
637
+ rewriteBareImports(code, root, virtualPrefix = "") {
638
+ const commentFree = code.replace(
639
+ /("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*)/g,
640
+ (m2) => {
641
+ if (m2.startsWith("/*") || m2.startsWith("//")) return " ".repeat(m2.length);
642
+ return m2;
643
+ }
644
+ );
645
+ const importRe = /((?:^|[;\n{])\s*(?:import|export)\s+(?:[\s\S]*?\s+from\s+|)|(?:import\s*\())(['"])([^'".\\/][^'"]*)\2/gm;
646
+ let result = code;
647
+ let offset = 0;
648
+ let m;
649
+ while ((m = importRe.exec(commentFree)) !== null) {
650
+ const [fullMatch, prefix, quote, specifier] = m;
651
+ if (/^https?:\/\//.test(specifier)) continue;
652
+ if (specifier.startsWith("/")) continue;
653
+ const resolved = this.resolveBarePkgEntry(specifier, root);
654
+ if (!resolved) continue;
655
+ const replacement = `${prefix}${quote}${virtualPrefix}${resolved}${quote}`;
656
+ const start = m.index + offset;
657
+ const end = start + fullMatch.length;
658
+ result = result.slice(0, start) + replacement + result.slice(end);
659
+ offset += replacement.length - fullMatch.length;
660
+ }
661
+ return result;
662
+ }
663
+ async serveExistingVirtualStaticFile(root, requestUrl, bufferCtor) {
664
+ const basePath = normalizePath(posixPath.join(root, getRequestPathname(requestUrl)));
665
+ const hasExtension = /\.[a-zA-Z0-9]+$/.test(posixPath.basename(basePath));
666
+ let candidates;
667
+ if (hasExtension) {
668
+ candidates = [basePath];
669
+ } else {
670
+ candidates = [basePath, `${basePath}.js`, `${basePath}.mjs`, `${basePath}.jsx`, `${basePath}/index.js`, `${basePath}/index.mjs`];
671
+ const pkgPath = `${basePath}/package.json`;
672
+ try {
673
+ if (this.vfs.existsSync(pkgPath)) {
674
+ const raw = this.vfs.readFileSync(pkgPath, "utf8");
675
+ const pkg = this.parseCachedPackageJson(pkgPath, raw);
676
+ const entry = pkg ? typeof pkg.module === "string" && pkg.module || typeof pkg.main === "string" && pkg.main : null;
677
+ if (entry) candidates.push(normalizePath(posixPath.join(basePath, entry)));
678
+ }
679
+ } catch {
680
+ }
681
+ try {
682
+ if (await this.fs.exists(pkgPath)) {
683
+ const raw = await this.fs.readFile(pkgPath, "utf-8");
684
+ const pkg = this.parseCachedPackageJson(pkgPath, raw);
685
+ const entry = pkg ? typeof pkg.module === "string" && pkg.module || typeof pkg.main === "string" && pkg.main : null;
686
+ if (entry) candidates.push(normalizePath(posixPath.join(basePath, entry)));
687
+ }
688
+ } catch {
689
+ }
690
+ }
691
+ for (const targetPath of candidates) {
692
+ try {
693
+ const stat = this.vfs.statSync(targetPath);
694
+ if (stat.isDirectory()) {
695
+ continue;
696
+ }
697
+ const content = this.vfs.readFileSync(targetPath);
698
+ const body = typeof content === "string" ? bufferCtor.from(content) : bufferCtor.from(content);
699
+ return {
700
+ statusCode: 200,
701
+ statusMessage: "OK",
702
+ headers: {
703
+ "Content-Type": getStaticMimeType(targetPath),
704
+ "Content-Length": String(body.length),
705
+ "Cache-Control": "no-cache"
706
+ },
707
+ body,
708
+ resolvedPath: targetPath
709
+ };
710
+ } catch {
711
+ }
712
+ }
713
+ for (const targetPath of candidates) {
714
+ try {
715
+ if (!await this.fs.exists(targetPath)) {
716
+ continue;
717
+ }
718
+ const stat = await this.fs.stat(targetPath);
719
+ if (stat.isDirectory) {
720
+ continue;
721
+ }
722
+ const content = await this.fs.readFileBuffer(targetPath);
723
+ this._vfs.withoutMirror(() => {
724
+ this._vfs.mkdirSync(posixPath.dirname(targetPath), { recursive: true });
725
+ this._vfs.writeFileSync(targetPath, content);
726
+ });
727
+ const body = bufferCtor.from(content);
728
+ return {
729
+ statusCode: 200,
730
+ statusMessage: "OK",
731
+ headers: {
732
+ "Content-Type": getStaticMimeType(targetPath),
733
+ "Content-Length": String(body.length),
734
+ "Cache-Control": "no-cache"
735
+ },
736
+ body,
737
+ resolvedPath: targetPath
738
+ };
739
+ } catch {
740
+ }
741
+ }
742
+ return null;
743
+ }
744
+ stopViteServer() {
745
+ if (this.viteServer) {
746
+ this.viteServer.stop();
747
+ this.viteServer = void 0;
748
+ }
749
+ if (this.vitePort !== null) {
750
+ try {
751
+ getServerBridge().unregisterServer(this.vitePort);
752
+ } catch {
753
+ }
754
+ }
755
+ this.vitePort = null;
756
+ this.vitePreviewUrl = null;
757
+ this.vitePreviewListener?.(null);
758
+ }
759
+ resolveBinFromPackageJson(binName, packageName, pkgJson, pkgDir) {
760
+ if (typeof pkgJson.bin === "string") {
761
+ const inferredBinName = typeof pkgJson.name === "string" ? pkgJson.name.split("/").pop() ?? pkgJson.name : packageName.split("/").pop() ?? packageName;
762
+ if (binName === inferredBinName) {
763
+ return normalizePath(posixPath.join(pkgDir, pkgJson.bin));
764
+ }
765
+ }
766
+ if (typeof pkgJson.bin === "object" && pkgJson.bin !== null && binName in pkgJson.bin) {
767
+ const namedBins = pkgJson.bin;
768
+ return normalizePath(posixPath.join(pkgDir, namedBins[binName]));
769
+ }
770
+ return null;
771
+ }
772
+ async resolveNpmBinPath(binName, cwd) {
773
+ const candidatePackageNames = [binName];
774
+ const packageJsonResult = await this.readPackageJson(cwd);
775
+ if ("pkgJson" in packageJsonResult) {
776
+ for (const packageName of getPackageJsonDependencyNames(packageJsonResult.pkgJson)) {
777
+ if (!candidatePackageNames.includes(packageName)) {
778
+ candidatePackageNames.push(packageName);
779
+ }
780
+ }
781
+ }
782
+ for (const packageName of candidatePackageNames) {
783
+ const pkgJsonPath = normalizePath(posixPath.join(cwd, "node_modules", packageName, "package.json"));
784
+ if (!await this.fs.exists(pkgJsonPath)) {
785
+ continue;
786
+ }
787
+ try {
788
+ const content = await this.fs.readFile(pkgJsonPath, "utf-8");
789
+ const pkgJson = this.parseCachedPackageJson(pkgJsonPath, content);
790
+ if (!pkgJson) {
791
+ continue;
792
+ }
793
+ const pkgDir = normalizePath(posixPath.join(cwd, "node_modules", packageName));
794
+ const result = this.resolveBinFromPackageJson(binName, packageName, pkgJson, pkgDir);
795
+ if (result) return result;
796
+ } catch {
797
+ }
798
+ }
799
+ const globalResult = await this.resolveGlobalBinPath(binName);
800
+ if (globalResult) return globalResult;
801
+ return null;
802
+ }
803
+ async resolveGlobalBinPath(binName) {
804
+ try {
805
+ const globalModulesDir = GLOBAL_NODE_MODULES_ROOT;
806
+ if (!this._vfs.existsSync(globalModulesDir)) return null;
807
+ const globalPackages = this._vfs.readdirSync(globalModulesDir);
808
+ for (const entry of globalPackages) {
809
+ const packageName = entry;
810
+ const pkgJsonPath = normalizePath(posixPath.join(globalModulesDir, packageName, "package.json"));
811
+ if (!this._vfs.existsSync(pkgJsonPath)) {
812
+ if (entry.startsWith("@")) {
813
+ try {
814
+ const scopeDir = normalizePath(posixPath.join(globalModulesDir, entry));
815
+ const scopedPackages = this._vfs.readdirSync(scopeDir);
816
+ for (const scopedPkg of scopedPackages) {
817
+ const scopedName = `${entry}/${scopedPkg}`;
818
+ const scopedPkgJsonPath = normalizePath(posixPath.join(globalModulesDir, scopedName, "package.json"));
819
+ if (!this._vfs.existsSync(scopedPkgJsonPath)) continue;
820
+ const raw = this._vfs.readFileSync(scopedPkgJsonPath, "utf8");
821
+ const pkgJson = this.parseCachedPackageJson(scopedPkgJsonPath, raw);
822
+ if (!pkgJson) continue;
823
+ const pkgDir = normalizePath(posixPath.join(globalModulesDir, scopedName));
824
+ const result = this.resolveBinFromPackageJson(binName, scopedName, pkgJson, pkgDir);
825
+ if (result) return result;
826
+ }
827
+ } catch {
828
+ }
829
+ }
830
+ continue;
831
+ }
832
+ try {
833
+ const raw = this._vfs.readFileSync(pkgJsonPath, "utf8");
834
+ const pkgJson = this.parseCachedPackageJson(pkgJsonPath, raw);
835
+ if (!pkgJson) continue;
836
+ const pkgDir = normalizePath(posixPath.join(globalModulesDir, packageName));
837
+ const result = this.resolveBinFromPackageJson(binName, packageName, pkgJson, pkgDir);
838
+ if (result) return result;
839
+ } catch {
840
+ }
841
+ }
842
+ } catch {
843
+ }
844
+ return null;
845
+ }
846
+ /**
847
+ * Replace lru-cache CJS entry points with a browser-safe implementation.
848
+ *
849
+ * lru-cache v11's minified CJS uses `require("node:diagnostics_channel")`
850
+ * and private class fields (`static #t`) which can fail inside the browser
851
+ * WASM runtime's `eval()` context, leaving `exports.LRUCache` undefined
852
+ * ("TypeError: LRUCache is not a constructor").
853
+ *
854
+ * The fix: overwrite the CJS entry with a clean Map-based LRU cache that
855
+ * covers the full API surface used by lru-cache consumers (hosted-git-info,
856
+ * path-scurry, glob, etc.) without any diagnostics_channel dependency or
857
+ * private class fields.
858
+ */
859
+ patchLruCacheInNodeModules(nodeModulesDir) {
860
+ const lruCacheShim = `"use strict";
861
+ Object.defineProperty(exports, "__esModule", { value: true });
862
+ exports.LRUCache = void 0;
863
+ var LRUCache = (function () {
864
+ function LRUCache(options) {
865
+ if (typeof options === "number") options = { max: options };
866
+ if (!options) options = {};
867
+ this._max = options.max || Infinity;
868
+ this._maxSize = options.maxSize || 0;
869
+ this._sizeCalculation = options.sizeCalculation || null;
870
+ this._dispose = options.dispose || null;
871
+ this._allowStale = !!options.allowStale;
872
+ this._ttl = options.ttl || 0;
873
+ this._noUpdateTTL = !!options.noUpdateTTL;
874
+ this._map = new Map();
875
+ this._order = [];
876
+ this._sizes = new Map();
877
+ this._totalSize = 0;
878
+ this._timers = new Map();
879
+ }
880
+ Object.defineProperty(LRUCache.prototype, "size", { get: function () { return this._map.size; } });
881
+ Object.defineProperty(LRUCache.prototype, "max", { get: function () { return this._max; } });
882
+ Object.defineProperty(LRUCache.prototype, "maxSize", { get: function () { return this._maxSize; } });
883
+ Object.defineProperty(LRUCache.prototype, "calculatedSize", { get: function () { return this._totalSize; } });
884
+ LRUCache.prototype._touch = function (key) {
885
+ var idx = this._order.indexOf(key);
886
+ if (idx > -1) this._order.splice(idx, 1);
887
+ this._order.push(key);
888
+ };
889
+ LRUCache.prototype._evict = function () {
890
+ while (this._order.length > 0 && (this._map.size > this._max || (this._maxSize > 0 && this._totalSize > this._maxSize))) {
891
+ var oldest = this._order.shift();
892
+ if (oldest !== undefined && this._map.has(oldest)) {
893
+ var val = this._map.get(oldest);
894
+ this._map.delete(oldest);
895
+ if (this._sizes.has(oldest)) { this._totalSize -= this._sizes.get(oldest); this._sizes.delete(oldest); }
896
+ if (this._timers.has(oldest)) { clearTimeout(this._timers.get(oldest)); this._timers.delete(oldest); }
897
+ if (this._dispose) this._dispose(val, oldest, "evict");
898
+ }
899
+ }
900
+ };
901
+ LRUCache.prototype._isStale = function (key) {
902
+ return false; // TTL timers handle expiry via delete
903
+ };
904
+ LRUCache.prototype.set = function (key, value, options) {
905
+ if (value === undefined) { this.delete(key); return this; }
906
+ var opts = options || {};
907
+ var size = 0;
908
+ if (this._maxSize > 0) {
909
+ size = opts.size || 0;
910
+ if (!size && this._sizeCalculation) size = this._sizeCalculation(value, key);
911
+ if (size > this._maxSize) return this;
912
+ }
913
+ if (this._map.has(key)) {
914
+ var old = this._map.get(key);
915
+ if (this._sizes.has(key)) { this._totalSize -= this._sizes.get(key); }
916
+ if (this._timers.has(key)) { clearTimeout(this._timers.get(key)); this._timers.delete(key); }
917
+ if (this._dispose && !opts.noDisposeOnSet) this._dispose(old, key, "set");
918
+ }
919
+ this._map.set(key, value);
920
+ this._touch(key);
921
+ if (this._maxSize > 0 && size > 0) { this._sizes.set(key, size); this._totalSize += size; }
922
+ var ttl = opts.ttl !== undefined ? opts.ttl : this._ttl;
923
+ if (ttl > 0) {
924
+ var self = this;
925
+ this._timers.set(key, setTimeout(function () { self.delete(key); }, ttl));
926
+ }
927
+ this._evict();
928
+ return this;
929
+ };
930
+ LRUCache.prototype.get = function (key, options) {
931
+ if (!this._map.has(key)) return undefined;
932
+ var value = this._map.get(key);
933
+ this._touch(key);
934
+ return value;
935
+ };
936
+ LRUCache.prototype.peek = function (key) {
937
+ return this._map.get(key);
938
+ };
939
+ LRUCache.prototype.has = function (key) {
940
+ return this._map.has(key);
941
+ };
942
+ LRUCache.prototype.delete = function (key) {
943
+ if (!this._map.has(key)) return false;
944
+ var val = this._map.get(key);
945
+ this._map.delete(key);
946
+ var idx = this._order.indexOf(key);
947
+ if (idx > -1) this._order.splice(idx, 1);
948
+ if (this._sizes.has(key)) { this._totalSize -= this._sizes.get(key); this._sizes.delete(key); }
949
+ if (this._timers.has(key)) { clearTimeout(this._timers.get(key)); this._timers.delete(key); }
950
+ if (this._dispose) this._dispose(val, key, "delete");
951
+ return true;
952
+ };
953
+ LRUCache.prototype.clear = function () {
954
+ var self = this;
955
+ if (this._dispose) {
956
+ this._map.forEach(function (val, key) { self._dispose(val, key, "delete"); });
957
+ }
958
+ this._timers.forEach(function (t) { clearTimeout(t); });
959
+ this._map.clear();
960
+ this._order.length = 0;
961
+ this._sizes.clear();
962
+ this._totalSize = 0;
963
+ this._timers.clear();
964
+ };
965
+ LRUCache.prototype.keys = function () { return this._map.keys(); };
966
+ LRUCache.prototype.values = function () { return this._map.values(); };
967
+ LRUCache.prototype.entries = function () { return this._map.entries(); };
968
+ LRUCache.prototype.find = function (fn, options) {
969
+ for (var it = this._map.entries(), r; !(r = it.next()).done;) {
970
+ if (fn(r.value[1], r.value[0], this)) return this.get(r.value[0], options);
971
+ }
972
+ };
973
+ LRUCache.prototype.forEach = function (fn, thisArg) {
974
+ var self = this;
975
+ this._map.forEach(function (val, key) { fn.call(thisArg || self, val, key, self); });
976
+ };
977
+ LRUCache.prototype.dump = function () { return []; };
978
+ LRUCache.prototype.load = function (arr) {
979
+ this.clear();
980
+ for (var i = 0; i < arr.length; i++) { this.set(arr[i][0], arr[i][1].value, arr[i][1]); }
981
+ };
982
+ LRUCache.prototype.pop = function () {
983
+ if (this._order.length === 0) return undefined;
984
+ var oldest = this._order[0];
985
+ var val = this._map.get(oldest);
986
+ this.delete(oldest);
987
+ return val;
988
+ };
989
+ LRUCache.prototype.purgeStale = function () { return false; };
990
+ LRUCache.prototype.getRemainingTTL = function (key) { return this._map.has(key) ? Infinity : 0; };
991
+ LRUCache.prototype.info = function (key) {
992
+ if (!this._map.has(key)) return undefined;
993
+ return { value: this._map.get(key) };
994
+ };
995
+ LRUCache.prototype[Symbol.iterator] = function () { return this._map.entries(); };
996
+ LRUCache.prototype[Symbol.toStringTag] = "LRUCache";
997
+ return LRUCache;
998
+ })();
999
+ exports.LRUCache = LRUCache;
1000
+ `;
1001
+ const patchDir = (lruDir) => {
1002
+ const cjsPaths = [
1003
+ normalizePath(posixPath.join(lruDir, "dist", "commonjs", "index.min.js")),
1004
+ normalizePath(posixPath.join(lruDir, "dist", "commonjs", "index.js")),
1005
+ // Also try the package root index (lru-cache v7 style)
1006
+ normalizePath(posixPath.join(lruDir, "index.js"))
1007
+ ];
1008
+ let patched = false;
1009
+ for (const p of cjsPaths) {
1010
+ if (this._vfs.existsSync(p)) {
1011
+ this._vfs.writeFileSync(p, lruCacheShim);
1012
+ patched = true;
1013
+ }
1014
+ }
1015
+ if (!patched) {
1016
+ const pkgPath = normalizePath(posixPath.join(lruDir, "package.json"));
1017
+ if (this._vfs.existsSync(pkgPath)) {
1018
+ try {
1019
+ const pkg = JSON.parse(this._vfs.readFileSync(pkgPath, "utf8"));
1020
+ const mainField = pkg.main || pkg.exports?.["."]?.require?.default || pkg.exports?.["."]?.require;
1021
+ if (mainField && typeof mainField === "string") {
1022
+ const mainPath = normalizePath(posixPath.join(lruDir, mainField));
1023
+ if (this._vfs.existsSync(mainPath)) {
1024
+ this._vfs.writeFileSync(mainPath, lruCacheShim);
1025
+ patched = true;
1026
+ }
1027
+ }
1028
+ } catch {
1029
+ }
1030
+ }
1031
+ }
1032
+ return patched;
1033
+ };
1034
+ let patchCount = 0;
1035
+ const walkNodeModules = (nmDir) => {
1036
+ if (!this._vfs.existsSync(nmDir)) return;
1037
+ let entries;
1038
+ try {
1039
+ entries = this._vfs.readdirSync(nmDir);
1040
+ } catch {
1041
+ return;
1042
+ }
1043
+ for (const entry of entries) {
1044
+ if (entry === "lru-cache") {
1045
+ const lruDir = normalizePath(posixPath.join(nmDir, "lru-cache"));
1046
+ if (patchDir(lruDir)) patchCount++;
1047
+ }
1048
+ if (entry.startsWith("@")) {
1049
+ const scopeDir = normalizePath(posixPath.join(nmDir, entry));
1050
+ try {
1051
+ for (const scopedEntry of this._vfs.readdirSync(scopeDir)) {
1052
+ const nestedNm = normalizePath(posixPath.join(scopeDir, scopedEntry, "node_modules"));
1053
+ if (this._vfs.existsSync(nestedNm)) {
1054
+ walkNodeModules(nestedNm);
1055
+ }
1056
+ }
1057
+ } catch {
1058
+ }
1059
+ } else {
1060
+ const nestedNm = normalizePath(posixPath.join(nmDir, entry, "node_modules"));
1061
+ if (this._vfs.existsSync(nestedNm)) {
1062
+ walkNodeModules(nestedNm);
1063
+ }
1064
+ }
1065
+ }
1066
+ };
1067
+ walkNodeModules(nodeModulesDir);
1068
+ if (patchCount === 0) {
1069
+ console.warn(`[agent-web-os] lru-cache patch: no lru-cache found in ${nodeModulesDir}`);
1070
+ } else {
1071
+ console.log(`[agent-web-os] lru-cache patch: patched ${patchCount} installation(s) in ${nodeModulesDir}`);
1072
+ }
1073
+ }
1074
+ async registerGlobalBinCommands(packageName) {
1075
+ if (!this.binCommandRegistrar) return;
1076
+ const pkgJsonPath = normalizePath(posixPath.join(GLOBAL_NODE_MODULES_ROOT, packageName, "package.json"));
1077
+ if (!this._vfs.existsSync(pkgJsonPath)) return;
1078
+ try {
1079
+ const raw = this._vfs.readFileSync(pkgJsonPath, "utf8");
1080
+ const pkgJson = this.parseCachedPackageJson(pkgJsonPath, raw);
1081
+ if (!pkgJson) return;
1082
+ let binNames;
1083
+ if (typeof pkgJson.bin === "string") {
1084
+ const name = typeof pkgJson.name === "string" ? pkgJson.name.split("/").pop() ?? "" : "";
1085
+ binNames = name ? [name] : [];
1086
+ } else if (typeof pkgJson.bin === "object" && pkgJson.bin !== null) {
1087
+ binNames = Object.keys(pkgJson.bin);
1088
+ } else {
1089
+ binNames = [];
1090
+ }
1091
+ for (const binName of binNames) {
1092
+ if (this.registeredBinCommands.has(binName)) continue;
1093
+ this.registeredBinCommands.add(binName);
1094
+ this.binCommandRegistrar(binName, async (args, ctx) => {
1095
+ const resolvedPath = await this.resolveGlobalBinPath(binName) ?? await this.resolveNpmBinPath(binName, normalizePath(ctx.cwd));
1096
+ if (!resolvedPath) {
1097
+ return {
1098
+ stdout: "",
1099
+ stderr: `bash: ${binName}: command not found
1100
+ `,
1101
+ exitCode: 127
1102
+ };
1103
+ }
1104
+ return this.executeNode([resolvedPath, ...args], ctx);
1105
+ });
1106
+ }
1107
+ } catch {
1108
+ }
1109
+ }
1110
+ async resolveAndRegisterBinCommands(command, cwd) {
1111
+ if (!this.binCommandRegistrar) {
1112
+ return;
1113
+ }
1114
+ const potentialBins = command.split(/&&|\|\||;|\|/).flatMap((part) => {
1115
+ const words = part.trim().split(/\s+/);
1116
+ for (const word of words) {
1117
+ if (!word || word.includes("=") || word.startsWith("/") || word.startsWith("./") || word.startsWith("..")) {
1118
+ continue;
1119
+ }
1120
+ return [word];
1121
+ }
1122
+ return [];
1123
+ });
1124
+ for (const binName of potentialBins) {
1125
+ if (this.registeredBinCommands.has(binName)) {
1126
+ continue;
1127
+ }
1128
+ const binPath = await this.resolveNpmBinPath(binName, cwd);
1129
+ if (!binPath) {
1130
+ continue;
1131
+ }
1132
+ this.registeredBinCommands.add(binName);
1133
+ if (binName === "vite") {
1134
+ this.binCommandRegistrar(binName, async (args, ctx) => {
1135
+ return this.executeVite(args, ctx);
1136
+ });
1137
+ continue;
1138
+ }
1139
+ this.binCommandRegistrar(binName, async (args, ctx) => {
1140
+ const resolvedPath = await this.resolveNpmBinPath(binName, normalizePath(ctx.cwd));
1141
+ if (!resolvedPath) {
1142
+ return {
1143
+ stdout: "",
1144
+ stderr: `bash: ${binName}: command not found
1145
+ `,
1146
+ exitCode: 127
1147
+ };
1148
+ }
1149
+ return this.executeNode([resolvedPath, ...args], ctx);
1150
+ });
1151
+ }
1152
+ }
1153
+ trackOperation(operation) {
1154
+ this.pendingOperations.add(operation);
1155
+ return operation.finally(() => {
1156
+ this.pendingOperations.delete(operation);
1157
+ });
1158
+ }
1159
+ async flushPendingOperations() {
1160
+ while (this.pendingOperations.size > 0) {
1161
+ await Promise.all(Array.from(this.pendingOperations));
1162
+ }
1163
+ }
1164
+ async withSuppressedObservableMirroring(operation) {
1165
+ this.suppressObservableMirrorCount += 1;
1166
+ try {
1167
+ return await operation();
1168
+ } finally {
1169
+ this.suppressObservableMirrorCount -= 1;
1170
+ }
1171
+ }
1172
+ async copyObservablePathIntoVirtualFs(targetPath, options) {
1173
+ const normalizedPath = normalizePath(targetPath);
1174
+ if (isInternalAlmostNodePath(normalizedPath)) {
1175
+ return;
1176
+ }
1177
+ if (!options?.force && this.fs.isPathLazy(normalizedPath)) {
1178
+ return;
1179
+ }
1180
+ try {
1181
+ const stat = await this.fs.stat(normalizedPath);
1182
+ if (stat.isDirectory) {
1183
+ this._vfs.withoutMirror(() => {
1184
+ this._vfs.mkdirSync(normalizedPath, { recursive: true });
1185
+ });
1186
+ return;
1187
+ }
1188
+ const content = await this.fs.readFileBuffer(normalizedPath);
1189
+ this._vfs.withoutMirror(() => {
1190
+ this._vfs.mkdirSync(posixPath.dirname(normalizedPath), { recursive: true });
1191
+ this._vfs.writeFileSync(normalizedPath, content);
1192
+ });
1193
+ } catch {
1194
+ this._vfs.withoutMirror(() => {
1195
+ removeVirtualPath(this._vfs, normalizedPath);
1196
+ });
1197
+ }
1198
+ }
1199
+ getNodeModulesPackageRoot(targetPath) {
1200
+ const normalizedPath = normalizePath(targetPath);
1201
+ const nodeModulesMarker = "/node_modules/";
1202
+ const nodeModulesIndex = normalizedPath.indexOf(nodeModulesMarker);
1203
+ if (nodeModulesIndex === -1) {
1204
+ return null;
1205
+ }
1206
+ const packageSegments = normalizedPath.slice(nodeModulesIndex + nodeModulesMarker.length).split("/").filter(Boolean);
1207
+ if (packageSegments.length === 0) {
1208
+ return null;
1209
+ }
1210
+ const packageNameSegments = packageSegments[0]?.startsWith("@") ? packageSegments.slice(0, 2) : packageSegments.slice(0, 1);
1211
+ if (packageNameSegments.length === 0) {
1212
+ return null;
1213
+ }
1214
+ return normalizePath(`${normalizedPath.slice(0, nodeModulesIndex + nodeModulesMarker.length)}${packageNameSegments.join("/")}`);
1215
+ }
1216
+ async hydrateObservablePackageIntoVirtualFs(packageRoot) {
1217
+ const normalizedPackageRoot = normalizePath(packageRoot);
1218
+ const packagePaths = Array.from(new Set(this.fs.getAllPaths().map((targetPath) => normalizePath(targetPath)))).filter((targetPath) => targetPath === normalizedPackageRoot || targetPath.startsWith(`${normalizedPackageRoot}/`)).sort((leftPath, rightPath) => leftPath.split("/").length - rightPath.split("/").length);
1219
+ await this.hydrateObservablePathsIntoVirtualFs(packagePaths);
1220
+ }
1221
+ async hydrateObservablePathsIntoVirtualFs(targetPaths) {
1222
+ const normalizedPaths = Array.from(new Set(targetPaths.map((targetPath) => normalizePath(targetPath)))).sort((leftPath, rightPath) => leftPath.split("/").length - rightPath.split("/").length);
1223
+ const lazyFilePaths = [];
1224
+ for (const targetPath of normalizedPaths) {
1225
+ try {
1226
+ if (this.fs.isPathLazy(targetPath)) {
1227
+ lazyFilePaths.push(targetPath);
1228
+ continue;
1229
+ }
1230
+ const stat = await this.fs.stat(targetPath);
1231
+ if (stat.isDirectory) {
1232
+ this._vfs.withoutMirror(() => {
1233
+ this._vfs.mkdirSync(targetPath, { recursive: true });
1234
+ });
1235
+ continue;
1236
+ }
1237
+ await this.copyObservablePathIntoVirtualFs(targetPath, { force: true });
1238
+ } catch {
1239
+ }
1240
+ }
1241
+ if (lazyFilePaths.length === 0) {
1242
+ return;
1243
+ }
1244
+ if (this.batchFileLoader) {
1245
+ const contents = await this.batchFileLoader(lazyFilePaths);
1246
+ await this.fs.suppressObservability(async () => {
1247
+ for (const [filePath, content] of contents) {
1248
+ this.fs.writeFileSync(filePath, content);
1249
+ }
1250
+ });
1251
+ this._vfs.withoutMirror(() => {
1252
+ for (const [filePath, content] of contents) {
1253
+ this._vfs.mkdirSync(posixPath.dirname(filePath), { recursive: true });
1254
+ this._vfs.writeFileSync(filePath, content);
1255
+ }
1256
+ });
1257
+ const missingPaths = lazyFilePaths.filter((lazyPath) => !contents.has(lazyPath));
1258
+ for (const missingPath of missingPaths) {
1259
+ await this.copyObservablePathIntoVirtualFs(missingPath, { force: true });
1260
+ }
1261
+ return;
1262
+ }
1263
+ for (const lazyPath of lazyFilePaths) {
1264
+ await this.copyObservablePathIntoVirtualFs(lazyPath, { force: true });
1265
+ }
1266
+ }
1267
+ async hydrateObservableDependencyPackagesIntoVirtualFs(cwd) {
1268
+ const packageJsonResult = await this.readPackageJson(cwd);
1269
+ if ("error" in packageJsonResult) {
1270
+ return;
1271
+ }
1272
+ const dependencyPaths = [];
1273
+ for (const packageName of getPackageJsonDependencyNames(packageJsonResult.pkgJson)) {
1274
+ const packageRoot = normalizePath(posixPath.join(cwd, "node_modules", packageName));
1275
+ if (!await this.fs.exists(packageRoot)) {
1276
+ continue;
1277
+ }
1278
+ for (const targetPath of this.fs.getAllPaths()) {
1279
+ const normalizedPath = normalizePath(targetPath);
1280
+ if (normalizedPath === packageRoot || normalizedPath.startsWith(`${packageRoot}/`)) {
1281
+ dependencyPaths.push(normalizedPath);
1282
+ }
1283
+ }
1284
+ }
1285
+ await this.hydrateObservablePathsIntoVirtualFs(dependencyPaths);
1286
+ }
1287
+ async hydrateObservableProjectIntoVirtualFs(cwd) {
1288
+ const normalizedCwd = normalizePath(cwd);
1289
+ const cwdPrefix = normalizedCwd.endsWith("/") ? normalizedCwd : `${normalizedCwd}/`;
1290
+ const projectPaths = Array.from(new Set(this.fs.getAllPaths().map((targetPath) => normalizePath(targetPath)))).filter((targetPath) => {
1291
+ if (isInternalAlmostNodePath(targetPath)) {
1292
+ return false;
1293
+ }
1294
+ if (targetPath !== normalizedCwd && !targetPath.startsWith(cwdPrefix)) {
1295
+ return false;
1296
+ }
1297
+ return !targetPath.startsWith(`${cwdPrefix}node_modules/`);
1298
+ }).sort((leftPath, rightPath) => leftPath.split("/").length - rightPath.split("/").length);
1299
+ await this.hydrateObservablePathsIntoVirtualFs(projectPaths);
1300
+ }
1301
+ async applyVirtualWrite(targetPath, data) {
1302
+ return this.trackOperation((async () => {
1303
+ const normalizedPath = normalizePath(targetPath);
1304
+ if (isInternalAlmostNodePath(normalizedPath)) {
1305
+ return;
1306
+ }
1307
+ await this.withSuppressedObservableMirroring(async () => {
1308
+ await ensureObservableDirectory(this.fs, posixPath.dirname(normalizedPath));
1309
+ await this.fs.writeFile(normalizedPath, data);
1310
+ });
1311
+ })());
1312
+ }
1313
+ async applyVirtualMkdir(targetPath) {
1314
+ return this.trackOperation((async () => {
1315
+ const normalizedPath = normalizePath(targetPath);
1316
+ if (isInternalAlmostNodePath(normalizedPath)) {
1317
+ return;
1318
+ }
1319
+ await this.withSuppressedObservableMirroring(async () => {
1320
+ await this.fs.mkdir(normalizedPath, { recursive: true });
1321
+ });
1322
+ })());
1323
+ }
1324
+ async applyVirtualRemove(targetPath, recursive) {
1325
+ return this.trackOperation((async () => {
1326
+ const normalizedPath = normalizePath(targetPath);
1327
+ if (isInternalAlmostNodePath(normalizedPath)) {
1328
+ return;
1329
+ }
1330
+ await this.withSuppressedObservableMirroring(async () => {
1331
+ await this.fs.rm(normalizedPath, { force: true, recursive });
1332
+ });
1333
+ })());
1334
+ }
1335
+ async applyVirtualRename(previousPath, nextPath) {
1336
+ return this.trackOperation((async () => {
1337
+ const normalizedPreviousPath = normalizePath(previousPath);
1338
+ const normalizedNextPath = normalizePath(nextPath);
1339
+ if (isInternalAlmostNodePath(normalizedPreviousPath) || isInternalAlmostNodePath(normalizedNextPath)) {
1340
+ return;
1341
+ }
1342
+ await this.withSuppressedObservableMirroring(async () => {
1343
+ await ensureObservableDirectory(this.fs, posixPath.dirname(normalizedNextPath));
1344
+ await this.fs.mv(normalizedPreviousPath, normalizedNextPath);
1345
+ });
1346
+ })());
1347
+ }
1348
+ async ensureInitialized() {
1349
+ if (this.initialized) {
1350
+ return;
1351
+ }
1352
+ if (!this.initializePromise) {
1353
+ this.initializePromise = (async () => {
1354
+ const allPaths = Array.from(new Set(this.fs.getAllPaths().map((targetPath) => normalizePath(targetPath)))).filter((targetPath) => !isInternalAlmostNodePath(targetPath)).sort((leftPath, rightPath) => leftPath.split("/").length - rightPath.split("/").length);
1355
+ for (const targetPath of allPaths) {
1356
+ await this.copyObservablePathIntoVirtualFs(targetPath);
1357
+ }
1358
+ this.initialized = true;
1359
+ })();
1360
+ }
1361
+ await this.initializePromise;
1362
+ }
1363
+ async readPackageJson(cwd) {
1364
+ const packageJsonPath = normalizePath(posixPath.join(cwd, "package.json"));
1365
+ if (!this.vfs.existsSync(packageJsonPath)) {
1366
+ await this.copyObservablePathIntoVirtualFs(packageJsonPath, { force: true });
1367
+ }
1368
+ if (!this.vfs.existsSync(packageJsonPath)) {
1369
+ return {
1370
+ error: {
1371
+ stdout: "",
1372
+ stderr: "npm ERR! no package.json found\n",
1373
+ exitCode: 1
1374
+ }
1375
+ };
1376
+ }
1377
+ try {
1378
+ return {
1379
+ pkgJson: this.parseCachedPackageJson(packageJsonPath, this.vfs.readFileSync(packageJsonPath, "utf8")) ?? {}
1380
+ };
1381
+ } catch {
1382
+ return {
1383
+ error: {
1384
+ stdout: "",
1385
+ stderr: "npm ERR! Failed to parse package.json\n",
1386
+ exitCode: 1
1387
+ }
1388
+ };
1389
+ }
1390
+ }
1391
+ async runNpmScript(scriptName, cwd, ctx) {
1392
+ if (!scriptName) {
1393
+ const packageJsonResult2 = await this.readPackageJson(cwd);
1394
+ if ("error" in packageJsonResult2) {
1395
+ return packageJsonResult2.error;
1396
+ }
1397
+ const scripts2 = packageJsonResult2.pkgJson.scripts || {};
1398
+ const scriptNames = Object.keys(scripts2);
1399
+ if (scriptNames.length === 0) {
1400
+ return { stdout: "", stderr: "", exitCode: 0 };
1401
+ }
1402
+ const lifecycleScripts = /* @__PURE__ */ new Set([
1403
+ "prestart",
1404
+ "start",
1405
+ "poststart",
1406
+ "pretest",
1407
+ "test",
1408
+ "posttest",
1409
+ "prestop",
1410
+ "stop",
1411
+ "poststop"
1412
+ ]);
1413
+ const lifecycleNames = scriptNames.filter((name) => lifecycleScripts.has(name));
1414
+ const customNames = scriptNames.filter((name) => !lifecycleScripts.has(name));
1415
+ let stdout2 = `Lifecycle scripts included in ${packageJsonResult2.pkgJson.name || ""}:
1416
+ `;
1417
+ for (const listedScriptName of lifecycleNames) {
1418
+ stdout2 += ` ${listedScriptName}
1419
+ ${scripts2[listedScriptName]}
1420
+ `;
1421
+ }
1422
+ if (customNames.length > 0) {
1423
+ stdout2 += "\navailable via `npm run-script`:\n";
1424
+ for (const listedScriptName of customNames) {
1425
+ stdout2 += ` ${listedScriptName}
1426
+ ${scripts2[listedScriptName]}
1427
+ `;
1428
+ }
1429
+ }
1430
+ return { stdout: stdout2, stderr: "", exitCode: 0 };
1431
+ }
1432
+ const packageJsonResult = await this.readPackageJson(cwd);
1433
+ if ("error" in packageJsonResult) {
1434
+ return packageJsonResult.error;
1435
+ }
1436
+ const { pkgJson } = packageJsonResult;
1437
+ const scripts = pkgJson.scripts || {};
1438
+ const scriptCommand = scripts[scriptName];
1439
+ if (!scriptCommand) {
1440
+ const availableScripts = Object.keys(scripts);
1441
+ let stderr2 = `npm ERR! Missing script: "${scriptName}"
1442
+ `;
1443
+ if (availableScripts.length > 0) {
1444
+ stderr2 += "\nnpm ERR! Available scripts:\n";
1445
+ for (const availableScript of availableScripts) {
1446
+ stderr2 += `npm ERR! ${availableScript}
1447
+ `;
1448
+ stderr2 += `npm ERR! ${scripts[availableScript]}
1449
+ `;
1450
+ }
1451
+ }
1452
+ return { stdout: "", stderr: stderr2, exitCode: 1 };
1453
+ }
1454
+ if (!ctx.exec) {
1455
+ return {
1456
+ stdout: "",
1457
+ stderr: "npm ERR! Script execution not available in this context\n",
1458
+ exitCode: 1
1459
+ };
1460
+ }
1461
+ await this.resolveAndRegisterBinCommands(scriptCommand, cwd);
1462
+ const preScriptCommand = scripts[`pre${scriptName}`];
1463
+ if (preScriptCommand) {
1464
+ await this.resolveAndRegisterBinCommands(preScriptCommand, cwd);
1465
+ }
1466
+ const postScriptCommand = scripts[`post${scriptName}`];
1467
+ if (postScriptCommand) {
1468
+ await this.resolveAndRegisterBinCommands(postScriptCommand, cwd);
1469
+ }
1470
+ const execCommand = ctx.exec;
1471
+ const baseEnv = getCommandEnvironment(ctx);
1472
+ const npmEnv = {
1473
+ ...baseEnv,
1474
+ npm_lifecycle_event: scriptName,
1475
+ PATH: Array.from(/* @__PURE__ */ new Set([
1476
+ normalizePath(posixPath.join(cwd, "node_modules/.bin")),
1477
+ "/node_modules/.bin",
1478
+ `${GLOBAL_NODE_MODULES_ROOT}/.bin`,
1479
+ ...(baseEnv.PATH?.trim() || DEFAULT_PATH).split(":").filter(Boolean)
1480
+ ])).join(":")
1481
+ };
1482
+ if (pkgJson.name) {
1483
+ npmEnv.npm_package_name = pkgJson.name;
1484
+ }
1485
+ if (pkgJson.version) {
1486
+ npmEnv.npm_package_version = pkgJson.version;
1487
+ }
1488
+ let stdout = "";
1489
+ let stderr = "";
1490
+ const label = `${pkgJson.name || ""}@${pkgJson.version || ""}`;
1491
+ const runScript = async (name, command) => {
1492
+ stderr += `
1493
+ > ${label} ${name}
1494
+ > ${command}
1495
+
1496
+ `;
1497
+ const result = await execCommand(command, { cwd, env: npmEnv });
1498
+ stdout += result.stdout;
1499
+ stderr += result.stderr;
1500
+ return result;
1501
+ };
1502
+ if (preScriptCommand) {
1503
+ const preResult = await runScript(`pre${scriptName}`, preScriptCommand);
1504
+ if (preResult.exitCode !== 0) {
1505
+ return { stdout, stderr, exitCode: preResult.exitCode };
1506
+ }
1507
+ }
1508
+ const mainResult = await runScript(scriptName, scriptCommand);
1509
+ if (mainResult.exitCode !== 0) {
1510
+ return { stdout, stderr, exitCode: mainResult.exitCode };
1511
+ }
1512
+ if (postScriptCommand) {
1513
+ const postResult = await runScript(`post${scriptName}`, postScriptCommand);
1514
+ if (postResult.exitCode !== 0) {
1515
+ return { stdout, stderr, exitCode: postResult.exitCode };
1516
+ }
1517
+ }
1518
+ return { stdout, stderr, exitCode: 0 };
1519
+ }
1520
+ async executeNpm(args, ctx) {
1521
+ const cwd = normalizePath(ctx.cwd);
1522
+ await this.ensureInitialized();
1523
+ await this.flushPendingOperations();
1524
+ const subcommand = args[0];
1525
+ let result;
1526
+ switch (subcommand) {
1527
+ case void 0:
1528
+ case "help":
1529
+ case "--help":
1530
+ result = { stdout: `${NPM_USAGE}
1531
+ `, stderr: "", exitCode: 0 };
1532
+ break;
1533
+ case "-v":
1534
+ case "--version":
1535
+ result = { stdout: `${ALMOSTNODE_NPM_VERSION}
1536
+ `, stderr: "", exitCode: 0 };
1537
+ break;
1538
+ case "run":
1539
+ case "run-script":
1540
+ result = await this.runNpmScript(args[1], cwd, ctx);
1541
+ break;
1542
+ case "start":
1543
+ result = await this.runNpmScript("start", cwd, ctx);
1544
+ break;
1545
+ case "test":
1546
+ case "t":
1547
+ case "tst":
1548
+ result = await this.runNpmScript("test", cwd, ctx);
1549
+ break;
1550
+ case "install":
1551
+ case "i":
1552
+ case "add": {
1553
+ const isGlobal = args.includes("-g") || args.includes("--global");
1554
+ const packageSpecs = args.slice(1).filter((arg) => !arg.startsWith("-"));
1555
+ let stdout = "";
1556
+ try {
1557
+ if (isGlobal) {
1558
+ if (packageSpecs.length === 0) {
1559
+ result = { stdout: "", stderr: "npm ERR! npm install -g requires a package name\n", exitCode: 1 };
1560
+ break;
1561
+ }
1562
+ await ensureEsbuildWasm();
1563
+ this._vfs.mkdirSync(GLOBAL_NODE_MODULES_ROOT, { recursive: true });
1564
+ await ensureObservableDirectory(this.fs, GLOBAL_NODE_MODULES_ROOT);
1565
+ const globalPkgJsonPath = normalizePath(posixPath.join(GLOBAL_NODE_MODULES_ROOT, "..", "package.json"));
1566
+ if (!this._vfs.existsSync(globalPkgJsonPath)) {
1567
+ const minimalPkg = JSON.stringify({ name: "global", version: "0.0.0", private: true }, null, 2);
1568
+ this._vfs.mkdirSync(posixPath.dirname(globalPkgJsonPath), { recursive: true });
1569
+ this._vfs.writeFileSync(globalPkgJsonPath, minimalPkg);
1570
+ await this.withSuppressedObservableMirroring(async () => {
1571
+ await ensureObservableDirectory(this.fs, posixPath.dirname(globalPkgJsonPath));
1572
+ await this.fs.writeFile(globalPkgJsonPath, minimalPkg);
1573
+ });
1574
+ }
1575
+ const globalCwd = normalizePath(posixPath.join(GLOBAL_NODE_MODULES_ROOT, ".."));
1576
+ const packageManager = new PackageManager(this.vfs, { cwd: globalCwd });
1577
+ for (const packageSpec of packageSpecs) {
1578
+ const installResult = await packageManager.install(packageSpec, {
1579
+ save: true,
1580
+ onProgress: (message) => {
1581
+ const line = `${message}
1582
+ `;
1583
+ stdout += line;
1584
+ this.stdoutWriter?.(line);
1585
+ }
1586
+ });
1587
+ stdout += `added ${installResult.added.length} packages
1588
+ `;
1589
+ const installedPkgName = packageSpec.replace(/@[^/]*$/, "") || packageSpec;
1590
+ await this.registerGlobalBinCommands(installedPkgName);
1591
+ for (const added of installResult.added) {
1592
+ const addedName = typeof added === "string" ? String(added).replace(/@[^/]*$/, "") : added?.name;
1593
+ if (addedName && addedName !== installedPkgName) {
1594
+ await this.registerGlobalBinCommands(addedName);
1595
+ }
1596
+ }
1597
+ }
1598
+ this.patchLruCacheInNodeModules(GLOBAL_NODE_MODULES_ROOT);
1599
+ result = { stdout, stderr: "", exitCode: 0 };
1600
+ } else {
1601
+ const packageJsonResult = await this.readPackageJson(cwd);
1602
+ if ("error" in packageJsonResult) {
1603
+ result = packageJsonResult.error;
1604
+ break;
1605
+ }
1606
+ await ensureEsbuildWasm();
1607
+ const packageManager = new PackageManager(this.vfs, { cwd });
1608
+ if (packageSpecs.length === 0) {
1609
+ const installResult = await packageManager.installFromPackageJson({
1610
+ onProgress: (message) => {
1611
+ const line = `${message}
1612
+ `;
1613
+ stdout += line;
1614
+ this.stdoutWriter?.(line);
1615
+ }
1616
+ });
1617
+ stdout += `added ${installResult.added.length} packages
1618
+ `;
1619
+ } else {
1620
+ for (const packageSpec of packageSpecs) {
1621
+ const installResult = await packageManager.install(packageSpec, {
1622
+ save: true,
1623
+ onProgress: (message) => {
1624
+ const line = `${message}
1625
+ `;
1626
+ stdout += line;
1627
+ this.stdoutWriter?.(line);
1628
+ }
1629
+ });
1630
+ stdout += `added ${installResult.added.length} packages
1631
+ `;
1632
+ }
1633
+ }
1634
+ const localNodeModules = normalizePath(posixPath.join(cwd, "node_modules"));
1635
+ this.patchLruCacheInNodeModules(localNodeModules);
1636
+ result = { stdout, stderr: "", exitCode: 0 };
1637
+ }
1638
+ } catch (error) {
1639
+ result = {
1640
+ stdout,
1641
+ stderr: `npm ERR! ${error instanceof Error ? error.message : String(error)}
1642
+ `,
1643
+ exitCode: 1
1644
+ };
1645
+ }
1646
+ break;
1647
+ }
1648
+ case "ls":
1649
+ case "list": {
1650
+ const packageManager = new PackageManager(this.vfs, { cwd });
1651
+ const packages = Object.entries(packageManager.list());
1652
+ if (packages.length === 0) {
1653
+ result = { stdout: "(empty)\n", stderr: "", exitCode: 0 };
1654
+ break;
1655
+ }
1656
+ result = {
1657
+ stdout: `${cwd}
1658
+ ${packages.map(([name, version]) => `+-- ${name}@${version}`).join("\n")}
1659
+ `,
1660
+ stderr: "",
1661
+ exitCode: 0
1662
+ };
1663
+ break;
1664
+ }
1665
+ default:
1666
+ result = {
1667
+ stdout: "",
1668
+ stderr: `npm ERR! Unknown command: "${subcommand}"
1669
+ `,
1670
+ exitCode: 1
1671
+ };
1672
+ break;
1673
+ }
1674
+ await this.flushPendingOperations();
1675
+ return result;
1676
+ }
1677
+ async executeNode(args, ctx) {
1678
+ const cwd = normalizePath(ctx.cwd);
1679
+ const invocation = (() => {
1680
+ if (args.length === 0) {
1681
+ return {
1682
+ kind: "error",
1683
+ message: "REPL mode is not supported in just-bash. Use node -e <code> or node <file>."
1684
+ };
1685
+ }
1686
+ const [firstArg, ...restArgs] = args;
1687
+ if (firstArg === "-v" || firstArg === "--version") {
1688
+ return { kind: "version" };
1689
+ }
1690
+ if (firstArg === "-h" || firstArg === "--help") {
1691
+ return {
1692
+ kind: "error",
1693
+ message: "Supported node modes in just-bash: node <file>, node -e <code>, node -p <expression>, node --version."
1694
+ };
1695
+ }
1696
+ if (firstArg === "-e" || firstArg === "--eval") {
1697
+ const code = restArgs[0]?.trim() || "";
1698
+ if (!code) {
1699
+ return { kind: "error", message: "node -e requires inline code" };
1700
+ }
1701
+ return {
1702
+ kind: "eval",
1703
+ code,
1704
+ argv: ["node", ...restArgs.slice(1)],
1705
+ filename: `${ALMOSTNODE_INTERNAL_ROOT}/eval.js`
1706
+ };
1707
+ }
1708
+ if (firstArg === "-p" || firstArg === "--print") {
1709
+ const expression = restArgs[0]?.trim() || "";
1710
+ if (!expression) {
1711
+ return { kind: "error", message: "node -p requires an expression" };
1712
+ }
1713
+ return {
1714
+ kind: "eval",
1715
+ code: [
1716
+ `const __monospace_print_result = ((${expression}));`,
1717
+ "if (typeof __monospace_print_result !== 'undefined') {",
1718
+ " process.stdout.write(String(__monospace_print_result) + '\\n')",
1719
+ "}"
1720
+ ].join("\n"),
1721
+ argv: ["node", ...restArgs.slice(1)],
1722
+ filename: `${ALMOSTNODE_INTERNAL_ROOT}/print.js`
1723
+ };
1724
+ }
1725
+ if (firstArg.startsWith("-")) {
1726
+ return {
1727
+ kind: "error",
1728
+ message: `Unsupported node flag in just-bash: ${firstArg}`
1729
+ };
1730
+ }
1731
+ const scriptPath = posixPath.isAbsolute(firstArg) ? normalizePath(firstArg) : normalizePath(posixPath.resolve(cwd, firstArg));
1732
+ return {
1733
+ kind: "run-file",
1734
+ scriptPath,
1735
+ argv: ["node", scriptPath, ...restArgs]
1736
+ };
1737
+ })();
1738
+ if (invocation.kind === "error") {
1739
+ return {
1740
+ stdout: "",
1741
+ stderr: `${invocation.message}
1742
+ `,
1743
+ exitCode: 1
1744
+ };
1745
+ }
1746
+ if (invocation.kind === "version") {
1747
+ return {
1748
+ stdout: `${ALMOSTNODE_NODE_VERSION}
1749
+ `,
1750
+ stderr: "",
1751
+ exitCode: 0
1752
+ };
1753
+ }
1754
+ await this.ensureInitialized();
1755
+ await this.flushPendingOperations();
1756
+ if (invocation.kind === "run-file") {
1757
+ if (!await this.fs.exists(invocation.scriptPath)) {
1758
+ return {
1759
+ stdout: "",
1760
+ stderr: `Cannot find module '${invocation.scriptPath}'
1761
+ `,
1762
+ exitCode: 1
1763
+ };
1764
+ }
1765
+ const packageRoot = this.getNodeModulesPackageRoot(invocation.scriptPath);
1766
+ if (packageRoot) {
1767
+ await this.hydrateObservablePackageIntoVirtualFs(packageRoot);
1768
+ await this.hydrateObservableProjectIntoVirtualFs(cwd);
1769
+ await this.hydrateObservableDependencyPackagesIntoVirtualFs(cwd);
1770
+ } else {
1771
+ await this.copyObservablePathIntoVirtualFs(invocation.scriptPath, { force: true });
1772
+ }
1773
+ }
1774
+ const stdoutChunks = [];
1775
+ const stderrChunks = [];
1776
+ const runtimeEnv = {
1777
+ ...getCommandEnvironment(ctx),
1778
+ PWD: cwd
1779
+ };
1780
+ const runtime = new Runtime(this.vfs, {
1781
+ cwd,
1782
+ env: runtimeEnv,
1783
+ onStdout: (chunk) => {
1784
+ appendChunk(stdoutChunks, chunk);
1785
+ this.stdoutWriter?.(chunk);
1786
+ },
1787
+ onStderr: (chunk) => appendChunk(stderrChunks, chunk),
1788
+ onConsole: (method, consoleArgs) => {
1789
+ const formatted = consoleArgs.map((value) => {
1790
+ if (typeof value === "string") {
1791
+ return value;
1792
+ }
1793
+ try {
1794
+ return JSON.stringify(value);
1795
+ } catch {
1796
+ return String(value);
1797
+ }
1798
+ }).join(" ");
1799
+ if (!formatted || formatted.startsWith("[process] cwd() called") || formatted.startsWith("[process] chdir called:") || formatted.startsWith("[process] chdir result:")) {
1800
+ return;
1801
+ }
1802
+ const chunk = `${formatted}
1803
+ `;
1804
+ if (method === "error" || method === "warn" || method === "trace") {
1805
+ appendChunk(stderrChunks, chunk);
1806
+ return;
1807
+ }
1808
+ appendChunk(stdoutChunks, chunk);
1809
+ this.stdoutWriter?.(chunk);
1810
+ }
1811
+ });
1812
+ const process = runtime.getProcess();
1813
+ process.stdout.isTTY = true;
1814
+ process.stderr.isTTY = true;
1815
+ if (process.stdin) {
1816
+ process.stdin.isTTY = true;
1817
+ }
1818
+ const stdoutAny = process.stdout;
1819
+ stdoutAny.columns = this._terminalColumns;
1820
+ stdoutAny.rows = this._terminalRows;
1821
+ stdoutAny.getWindowSize = () => [this._terminalColumns, this._terminalRows];
1822
+ let rawModeRequested = false;
1823
+ if (process.stdin) {
1824
+ const originalSetRawMode = process.stdin.setRawMode;
1825
+ process.stdin.setRawMode = (mode) => {
1826
+ rawModeRequested = rawModeRequested || mode;
1827
+ if (typeof originalSetRawMode === "function") {
1828
+ return originalSetRawMode.call(process.stdin, mode);
1829
+ }
1830
+ return process.stdin;
1831
+ };
1832
+ }
1833
+ this._stdinHandler = process.stdin ? (data) => {
1834
+ process.stdin.emit("data", data);
1835
+ } : null;
1836
+ const originalExit = process.exit;
1837
+ let exitCalled = false;
1838
+ let exitCode = 0;
1839
+ let syncExecution = true;
1840
+ let resolveExit = null;
1841
+ const exitPromise = new Promise((resolve) => {
1842
+ resolveExit = resolve;
1843
+ });
1844
+ const previousConsole = {
1845
+ log: console.log,
1846
+ info: console.info,
1847
+ warn: console.warn,
1848
+ error: console.error,
1849
+ debug: console.debug,
1850
+ trace: console.trace,
1851
+ dir: console.dir,
1852
+ table: console.table
1853
+ };
1854
+ console.log = () => void 0;
1855
+ console.info = () => void 0;
1856
+ console.warn = () => void 0;
1857
+ console.error = () => void 0;
1858
+ console.debug = () => void 0;
1859
+ console.trace = () => void 0;
1860
+ console.dir = () => void 0;
1861
+ console.table = () => void 0;
1862
+ process.exit = ((code = 0) => {
1863
+ if (!exitCalled) {
1864
+ exitCalled = true;
1865
+ exitCode = code;
1866
+ resolveExit?.(code);
1867
+ }
1868
+ if (syncExecution) {
1869
+ throw new Error(`Process exited with code ${code}`);
1870
+ }
1871
+ return void 0;
1872
+ });
1873
+ process.argv = invocation.argv;
1874
+ process.argv0 = "node";
1875
+ process.execPath = NODE_EXEC_PATH;
1876
+ if (process.pid == null) {
1877
+ process.pid = 1;
1878
+ }
1879
+ if (typeof process.kill !== "function") {
1880
+ process.kill = () => {
1881
+ };
1882
+ }
1883
+ const rejectionHandler = (event) => {
1884
+ const reason = event.reason;
1885
+ if (reason instanceof Error && reason.message.startsWith("Process exited with code")) {
1886
+ event.preventDefault();
1887
+ }
1888
+ };
1889
+ const canListenForUnhandledRejection = typeof globalThis.addEventListener === "function" && typeof globalThis.removeEventListener === "function";
1890
+ if (canListenForUnhandledRejection) {
1891
+ globalThis.addEventListener("unhandledrejection", rejectionHandler);
1892
+ }
1893
+ try {
1894
+ if (invocation.kind === "eval") {
1895
+ runtime.execute(invocation.code, invocation.filename);
1896
+ } else {
1897
+ runtime.runFile(invocation.scriptPath);
1898
+ }
1899
+ syncExecution = false;
1900
+ await new Promise((resolve) => {
1901
+ setTimeout(resolve, 0);
1902
+ });
1903
+ const hasStdinListeners = process.stdin && (process.stdin.listenerCount("data") > 0 || process.stdin.listenerCount("keypress") > 0);
1904
+ const isInteractive = hasStdinListeners || rawModeRequested;
1905
+ const asyncExitCode = isInteractive ? await exitPromise : await Promise.race([
1906
+ exitPromise,
1907
+ new Promise((resolve) => {
1908
+ setTimeout(() => resolve(null), 0);
1909
+ })
1910
+ ]);
1911
+ await this.flushPendingOperations();
1912
+ if (exitCalled || asyncExitCode !== null) {
1913
+ return {
1914
+ stdout: stdoutChunks.join(""),
1915
+ stderr: stderrChunks.join(""),
1916
+ exitCode: asyncExitCode ?? exitCode
1917
+ };
1918
+ }
1919
+ return {
1920
+ stdout: stdoutChunks.join(""),
1921
+ stderr: stderrChunks.join(""),
1922
+ exitCode: 0
1923
+ };
1924
+ } catch (error) {
1925
+ syncExecution = false;
1926
+ await this.flushPendingOperations();
1927
+ if (error instanceof Error) {
1928
+ const match = /Process exited with code (\d+)/.exec(error.message);
1929
+ if (match) {
1930
+ return {
1931
+ stdout: stdoutChunks.join(""),
1932
+ stderr: stderrChunks.join(""),
1933
+ exitCode: Number.parseInt(match[1] ?? "", 10)
1934
+ };
1935
+ }
1936
+ }
1937
+ appendChunk(stderrChunks, `${error instanceof Error ? error.stack || error.message : String(error)}
1938
+ `);
1939
+ return {
1940
+ stdout: stdoutChunks.join(""),
1941
+ stderr: stderrChunks.join(""),
1942
+ exitCode: 1
1943
+ };
1944
+ } finally {
1945
+ this._stdinHandler = null;
1946
+ if (canListenForUnhandledRejection) {
1947
+ globalThis.removeEventListener("unhandledrejection", rejectionHandler);
1948
+ }
1949
+ process.exit = originalExit;
1950
+ console.log = previousConsole.log;
1951
+ console.info = previousConsole.info;
1952
+ console.warn = previousConsole.warn;
1953
+ console.error = previousConsole.error;
1954
+ console.debug = previousConsole.debug;
1955
+ console.trace = previousConsole.trace;
1956
+ console.dir = previousConsole.dir;
1957
+ console.table = previousConsole.table;
1958
+ }
1959
+ }
1960
+ async executeVite(args, ctx) {
1961
+ const cwd = normalizePath(ctx.cwd);
1962
+ await this.ensureInitialized();
1963
+ await this.flushPendingOperations();
1964
+ const cwdPrefix = cwd.endsWith("/") ? cwd : `${cwd}/`;
1965
+ const allLazyPaths = this.fs.getAllPaths().map((p) => normalizePath(p)).filter((p) => (p === cwd || p.startsWith(cwdPrefix)) && !isInternalAlmostNodePath(p) && this.fs.isPathLazy(p));
1966
+ const pathsToLoad = allLazyPaths.filter((targetPath) => {
1967
+ if (!targetPath.startsWith(`${cwdPrefix}node_modules/`)) {
1968
+ return true;
1969
+ }
1970
+ const baseName = posixPath.basename(targetPath).toLowerCase();
1971
+ if (baseName === "package.json") {
1972
+ return true;
1973
+ }
1974
+ if (baseName.endsWith(".d.ts") || baseName.endsWith(".d.mts") || baseName.endsWith(".d.cts") || baseName.endsWith(".map") || baseName === "readme" || baseName.startsWith("readme.") || baseName === "license" || baseName.startsWith("license.") || baseName === "changelog" || baseName.startsWith("changelog.")) {
1975
+ return false;
1976
+ }
1977
+ return /\.(?:js|mjs|cjs|jsx|ts|tsx|json|css|scss|sass|less|wasm|svg)$/.test(baseName);
1978
+ });
1979
+ if (pathsToLoad.length > 0 && this.batchFileLoader) {
1980
+ const contents = await this.batchFileLoader(pathsToLoad);
1981
+ await this.fs.suppressObservability(async () => {
1982
+ for (const [filePath, content] of contents) {
1983
+ this.fs.writeFileSync(filePath, content);
1984
+ }
1985
+ });
1986
+ this._vfs.withoutMirror(() => {
1987
+ for (const [filePath, content] of contents) {
1988
+ this._vfs.mkdirSync(posixPath.dirname(filePath), { recursive: true });
1989
+ this._vfs.writeFileSync(filePath, content);
1990
+ }
1991
+ });
1992
+ } else {
1993
+ for (const lazyPath of pathsToLoad) {
1994
+ await this.copyObservablePathIntoVirtualFs(lazyPath, { force: true });
1995
+ }
1996
+ }
1997
+ let port = 5173;
1998
+ for (let i = 0; i < args.length; i++) {
1999
+ if (args[i] === "--port" && args[i + 1]) {
2000
+ const parsed = Number.parseInt(args[i + 1], 10);
2001
+ if (!Number.isNaN(parsed) && parsed > 0) {
2002
+ port = parsed;
2003
+ }
2004
+ }
2005
+ }
2006
+ this.stopViteServer();
2007
+ const bridge = getServerBridge();
2008
+ await ensureEsbuildWasm();
2009
+ this.viteServer = new ViteDevServer(this.vfs, { port, root: cwd });
2010
+ this.viteServer.start();
2011
+ await bridge.initServiceWorker();
2012
+ const virtualPrefix = `/__virtual__/${port}`;
2013
+ bridge.registerServer({
2014
+ get listening() {
2015
+ return true;
2016
+ },
2017
+ address: () => ({ port, address: "127.0.0.1", family: "IPv4" }),
2018
+ handleRequest: async (method, url, headers, body) => {
2019
+ let response = await this.viteServer.handleRequest(method, url, headers, typeof body === "string" ? void 0 : body);
2020
+ let resolvedFilePath = "";
2021
+ if (response.statusCode === 404 && response.body) {
2022
+ const BufferCtor = response.body.constructor;
2023
+ const fallbackResponse = await this.serveExistingVirtualStaticFile(cwd, url, BufferCtor);
2024
+ if (fallbackResponse) {
2025
+ resolvedFilePath = fallbackResponse.resolvedPath.replace(cwd, "");
2026
+ response = fallbackResponse;
2027
+ }
2028
+ }
2029
+ const contentType = response.headers["Content-Type"] || response.headers["content-type"] || "";
2030
+ if (contentType.includes("text/html") && response.body) {
2031
+ const rawHtml = response.body.toString("utf8");
2032
+ const html = this.transformTextWithCache(
2033
+ `html:${virtualPrefix}:${url}`,
2034
+ rawHtml,
2035
+ (input) => input.replace(/<script\s+type\s*=\s*["']importmap["'][^>]*>[\s\S]*?<\/script>/gi, "").replace(/(<script\b[^>]*\bsrc\s*=\s*["'])\/((?!\/)[^"']*["'])/gi, `$1${virtualPrefix}/$2`).replace(/(<link\b[^>]*\bhref\s*=\s*["'])\/((?!\/)[^"']*["'])/gi, `$1${virtualPrefix}/$2`)
2036
+ );
2037
+ const BufferCtor = response.body.constructor;
2038
+ const newBody = BufferCtor.from(html);
2039
+ return {
2040
+ ...response,
2041
+ body: newBody,
2042
+ headers: {
2043
+ ...response.headers,
2044
+ "Content-Length": String(newBody.length)
2045
+ }
2046
+ };
2047
+ }
2048
+ if (contentType.includes("javascript") && response.body) {
2049
+ const requestPath = resolvedFilePath || getRequestPathname(url);
2050
+ const rawJs = response.body.toString("utf8");
2051
+ const js = this.transformTextWithCache(
2052
+ `js:${virtualPrefix}:${requestPath}`,
2053
+ rawJs,
2054
+ (input) => {
2055
+ let transformed = this.rewriteBareImports(input, cwd, virtualPrefix);
2056
+ transformed = wrapCjsAsEsm(transformed, virtualPrefix, requestPath);
2057
+ if (/\bprocess\.env\b/.test(transformed) && !/\bvar\s+process\b/.test(transformed)) {
2058
+ transformed = `var process = { env: { NODE_ENV: "production" } };
2059
+ ${transformed}`;
2060
+ }
2061
+ return transformed;
2062
+ }
2063
+ );
2064
+ const BufferCtor = response.body.constructor;
2065
+ const newBody = BufferCtor.from(js);
2066
+ return {
2067
+ ...response,
2068
+ body: newBody,
2069
+ headers: {
2070
+ ...response.headers,
2071
+ "Content-Length": String(newBody.length)
2072
+ }
2073
+ };
2074
+ }
2075
+ return response;
2076
+ }
2077
+ }, port);
2078
+ const serverUrl = bridge.getServerUrl(port);
2079
+ this.vitePort = port;
2080
+ this.vitePreviewUrl = `${serverUrl}/`;
2081
+ this.vitePreviewListener?.(this.vitePreviewUrl);
2082
+ return {
2083
+ stdout: [
2084
+ "",
2085
+ " VITE ready",
2086
+ "",
2087
+ ` \u279C Local: ${this.vitePreviewUrl}`,
2088
+ ""
2089
+ ].join("\n"),
2090
+ stderr: "",
2091
+ exitCode: 0
2092
+ };
2093
+ }
2094
+ };
2095
+ function createAlmostNodeSession(fs) {
2096
+ return new AlmostNodeSession(fs);
2097
+ }
2098
+ export {
2099
+ AlmostNodeSession,
2100
+ createAlmostNodeSession
2101
+ };
2102
+ //# sourceMappingURL=almostnode-session-NGSXCNAV.js.map