@nimbus-sh/worker 0.1.5 → 0.1.6
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 +37 -0
- package/dist/_shared/crypto.d.ts +15 -0
- package/dist/_shared/crypto.d.ts.map +1 -0
- package/dist/_shared/crypto.js +122 -0
- package/dist/facets/manager.d.ts +24 -0
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +279 -70
- package/dist/facets/process.d.ts +11 -2
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +187 -21
- package/dist/facets/vite-dev-server.d.ts +2 -0
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +39 -12
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/loaders/child-process/spawn-facet.d.ts +1 -3
- package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-facet.js +1 -12
- package/dist/loaders/child-process/spawn-pool.d.ts +1 -1
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +1 -6
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +47 -27
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +2 -1
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +41 -13
- package/dist/npm/resolver.d.ts.map +1 -1
- package/dist/npm/resolver.js +70 -35
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +45 -21
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +29 -8
- package/dist/runtime/barrel-synthesizer.d.ts +7 -0
- package/dist/runtime/barrel-synthesizer.d.ts.map +1 -1
- package/dist/runtime/barrel-synthesizer.js +11 -0
- package/dist/runtime/clang-runner.d.ts.map +1 -1
- package/dist/runtime/clang-runner.js +1 -8
- package/dist/runtime/esbuild-service.d.ts +12 -5
- package/dist/runtime/esbuild-service.d.ts.map +1 -1
- package/dist/runtime/esbuild-service.js +28 -14
- package/dist/runtime/node-runner.d.ts +2 -0
- package/dist/runtime/node-runner.d.ts.map +1 -1
- package/dist/runtime/node-shims.d.ts +4 -2
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +404 -55
- package/dist/runtime/os-contracts.d.ts +128 -0
- package/dist/runtime/os-contracts.d.ts.map +1 -0
- package/dist/runtime/os-contracts.js +1 -0
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +32 -7
- package/dist/runtime/port-registry.d.ts +5 -0
- package/dist/runtime/port-registry.d.ts.map +1 -1
- package/dist/runtime/port-registry.js +22 -1
- package/dist/runtime/pyodide-runtime-assets.d.ts +19 -0
- package/dist/runtime/pyodide-runtime-assets.d.ts.map +1 -0
- package/dist/runtime/pyodide-runtime-assets.js +44 -0
- package/dist/runtime/python-repl.d.ts +3 -1
- package/dist/runtime/python-repl.d.ts.map +1 -1
- package/dist/runtime/python-repl.js +11 -29
- package/dist/runtime/python-runner.d.ts +8 -9
- package/dist/runtime/python-runner.d.ts.map +1 -1
- package/dist/runtime/python-runner.js +897 -61
- package/dist/runtime/python-socket-shim.d.ts +11 -0
- package/dist/runtime/python-socket-shim.d.ts.map +1 -0
- package/dist/runtime/python-socket-shim.js +526 -0
- package/dist/runtime/require-resolver.d.ts.map +1 -1
- package/dist/runtime/require-resolver.js +2 -11
- package/dist/runtime/ruby-gems.d.ts +25 -0
- package/dist/runtime/ruby-gems.d.ts.map +1 -0
- package/dist/runtime/ruby-gems.js +582 -0
- package/dist/runtime/ruby-runner.d.ts +2 -4
- package/dist/runtime/ruby-runner.d.ts.map +1 -1
- package/dist/runtime/ruby-runner.js +335 -34
- package/dist/runtime/runtime-catalog.d.ts +16 -4
- package/dist/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/runtime/runtime-catalog.js +21 -10
- package/dist/runtime/runtime-registry.d.ts +3 -0
- package/dist/runtime/runtime-registry.d.ts.map +1 -1
- package/dist/runtime/runtime-registry.js +4 -0
- package/dist/runtime/sqlite-runtime-fs-bridge.d.ts +43 -0
- package/dist/runtime/sqlite-runtime-fs-bridge.d.ts.map +1 -0
- package/dist/runtime/sqlite-runtime-fs-bridge.js +224 -0
- package/dist/runtime/static-server.d.ts +3 -0
- package/dist/runtime/static-server.d.ts.map +1 -0
- package/dist/runtime/static-server.js +121 -0
- package/dist/runtime/vfs-snapshot.d.ts +57 -0
- package/dist/runtime/vfs-snapshot.d.ts.map +1 -0
- package/dist/runtime/vfs-snapshot.js +141 -0
- package/dist/runtime/virtual-socket-kernel.d.ts +16 -0
- package/dist/runtime/virtual-socket-kernel.d.ts.map +1 -0
- package/dist/runtime/virtual-socket-kernel.js +360 -0
- package/dist/runtime/wasi-instance.d.ts +6 -3
- package/dist/runtime/wasi-instance.d.ts.map +1 -1
- package/dist/runtime/wasm-runner.d.ts +1 -25
- package/dist/runtime/wasm-runner.d.ts.map +1 -1
- package/dist/runtime/wasm-runner.js +1 -160
- package/dist/session/agent.d.ts +43 -0
- package/dist/session/agent.d.ts.map +1 -0
- package/dist/session/agent.js +1252 -0
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +15 -16
- package/dist/session/nimbus-session.d.ts +13 -2
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +55 -7
- package/dist/session/programmatic.d.ts +10 -0
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +121 -0
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +19 -1
- package/dist/session/rpc.d.ts +11 -0
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +56 -43
- package/dist/session/supervisor-rpc.d.ts +15 -0
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +32 -0
- package/dist/session/ws.d.ts +4 -3
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +11 -1
- package/dist/shell/unix-commands.js +12 -16
- package/dist/vfs/path.d.ts +8 -4
- package/dist/vfs/path.d.ts.map +1 -1
- package/dist/vfs/path.js +16 -4
- package/dist/vfs/sqlite-vfs.d.ts +2 -0
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
- package/dist/vfs/sqlite-vfs.js +11 -0
- package/dist/vfs/symlink-registry.d.ts +7 -1
- package/dist/vfs/symlink-registry.d.ts.map +1 -1
- package/dist/vfs/symlink-registry.js +16 -11
- package/package.json +4 -1
- package/public/index.html +240 -0
- package/public/s/index.html +1172 -146
- package/runtime-contracts/pyodide-workerd-adapter.json +18 -0
- package/scripts/bundle-runtime.mjs +99 -24
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
* workerd CSP rejects that path.
|
|
50
50
|
*/
|
|
51
51
|
import { WASI_INSTANCE_PREAMBLE_SRC, WASI_IMPLEMENTED_FNS } from './wasi-instance.js';
|
|
52
|
+
import { flushVfsDiff, snapshotVfs } from './vfs-snapshot.js';
|
|
52
53
|
export const WASM_RUNNER_VERSION = '0.3.0';
|
|
53
54
|
export const WASM_RUNNER_HELP = 'Usage: wasm-runner [options] <file.wasm> [exportName] [int args...]\n' +
|
|
54
55
|
' wasm-runner --version\n' +
|
|
@@ -123,166 +124,6 @@ function hasWasiImports(bytes) {
|
|
|
123
124
|
}
|
|
124
125
|
return false;
|
|
125
126
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Convert a Uint8Array to a base64 string. Used to encode VFS file
|
|
128
|
-
* contents into the JSON-serializable `context` field of the loader
|
|
129
|
-
* pool. Workerd's btoa is the standard one; we use it directly rather
|
|
130
|
-
* than depending on Node's Buffer (which works in workerd via the
|
|
131
|
-
* nodejs_compat polyfill but adds an import dependency).
|
|
132
|
-
*/
|
|
133
|
-
function bytesToB64(bytes) {
|
|
134
|
-
let s = '';
|
|
135
|
-
for (let i = 0; i < bytes.length; i++)
|
|
136
|
-
s += String.fromCharCode(bytes[i]);
|
|
137
|
-
return btoa(s);
|
|
138
|
-
}
|
|
139
|
-
function b64ToBytes(b64) {
|
|
140
|
-
const bin = atob(b64);
|
|
141
|
-
const out = new Uint8Array(bin.length);
|
|
142
|
-
for (let i = 0; i < bin.length; i++)
|
|
143
|
-
out[i] = bin.charCodeAt(i);
|
|
144
|
-
return out;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Snapshot a VFS subtree rooted at `vfsRoot` into a JSON-serializable
|
|
148
|
-
* `WasiFsSnapshot`. Used by the WASI runner to ship the user's session
|
|
149
|
-
* filesystem into the facet isolate.
|
|
150
|
-
*
|
|
151
|
-
* Bounded by:
|
|
152
|
-
* - 32 MiB total bytes. Bigger sessions need a streaming or incremental
|
|
153
|
-
* filesystem transport instead of a single snapshot.
|
|
154
|
-
* - 5000 file count.
|
|
155
|
-
*
|
|
156
|
-
* Returns null + a diagnostic if bounds are exceeded so the caller
|
|
157
|
-
* can surface a clear error to the user.
|
|
158
|
-
*/
|
|
159
|
-
function snapshotVfs(vfs, vfsRoot) {
|
|
160
|
-
const MAX_BYTES = 32 * 1024 * 1024;
|
|
161
|
-
const MAX_FILES = 5000;
|
|
162
|
-
const root = vfsRoot.replace(/^\/+/, '').replace(/\/+$/, '');
|
|
163
|
-
const files = {};
|
|
164
|
-
const dirs = [];
|
|
165
|
-
let totalBytes = 0;
|
|
166
|
-
let fileCount = 0;
|
|
167
|
-
const stack = [root];
|
|
168
|
-
if (!vfs.exists(root)) {
|
|
169
|
-
return { snapshot: { root, preopens: [], files: {}, dirs: [root] }, bytes: 0, files: 0 };
|
|
170
|
-
}
|
|
171
|
-
dirs.push(root);
|
|
172
|
-
// Directory prefixes to skip during snapshot. The user's `~/.nimbus`
|
|
173
|
-
// install root holds nimbus-managed runtime bundles (clang.wasm,
|
|
174
|
-
// lld.wasm, sysroot.tar, Pyodide, …) that easily exceed the
|
|
175
|
-
// 32 MiB per-snapshot cap and don't belong in the WASI sandbox
|
|
176
|
-
// anyway. node_modules is similar — large, irrelevant to user
|
|
177
|
-
// wasm execution.
|
|
178
|
-
const skipSubdirs = new Set(['.nimbus', 'node_modules', '.cache', '.npm']);
|
|
179
|
-
while (stack.length > 0) {
|
|
180
|
-
const dir = stack.pop();
|
|
181
|
-
let entries;
|
|
182
|
-
try {
|
|
183
|
-
entries = vfs.readdir(dir);
|
|
184
|
-
}
|
|
185
|
-
catch {
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
for (const e of entries) {
|
|
189
|
-
const childPath = dir + '/' + e.name;
|
|
190
|
-
if (e.type === 'directory') {
|
|
191
|
-
// Skip well-known large/irrelevant subdirs.
|
|
192
|
-
if (skipSubdirs.has(e.name))
|
|
193
|
-
continue;
|
|
194
|
-
dirs.push(childPath);
|
|
195
|
-
stack.push(childPath);
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
let bytes;
|
|
199
|
-
try {
|
|
200
|
-
bytes = vfs.readFile(childPath);
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
totalBytes += bytes.length;
|
|
206
|
-
fileCount++;
|
|
207
|
-
if (totalBytes > MAX_BYTES) {
|
|
208
|
-
return { error: `WASI snapshot exceeded 32 MiB cap (current dir: ${dir})` };
|
|
209
|
-
}
|
|
210
|
-
if (fileCount > MAX_FILES) {
|
|
211
|
-
return { error: `WASI snapshot exceeded 5000 file cap` };
|
|
212
|
-
}
|
|
213
|
-
files[childPath] = bytesToB64(bytes);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
snapshot: { root, preopens: [], files, dirs },
|
|
218
|
-
bytes: totalBytes,
|
|
219
|
-
files: fileCount,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Apply a WasiFsDiff produced by the facet back into the supervisor's
|
|
224
|
-
* SqliteFS. Each operation is independent; failures on one path don't
|
|
225
|
-
* abort the rest (we log to stderr and continue).
|
|
226
|
-
*/
|
|
227
|
-
function flushVfsDiff(vfs, diff) {
|
|
228
|
-
let written = 0, deleted = 0, mkdirs = 0, rmdirs = 0;
|
|
229
|
-
let timesTouched = 0, symlinks = 0;
|
|
230
|
-
for (const path of diff.dirsCreated) {
|
|
231
|
-
try {
|
|
232
|
-
vfs.mkdir(path, { recursive: true });
|
|
233
|
-
mkdirs++;
|
|
234
|
-
}
|
|
235
|
-
catch { }
|
|
236
|
-
}
|
|
237
|
-
for (const [path, b64] of Object.entries(diff.filesWritten)) {
|
|
238
|
-
try {
|
|
239
|
-
const bytes = b64ToBytes(b64);
|
|
240
|
-
// ensure parent dirs exist
|
|
241
|
-
const lastSlash = path.lastIndexOf('/');
|
|
242
|
-
if (lastSlash > 0) {
|
|
243
|
-
const parent = path.substring(0, lastSlash);
|
|
244
|
-
try {
|
|
245
|
-
vfs.mkdir(parent, { recursive: true });
|
|
246
|
-
}
|
|
247
|
-
catch { }
|
|
248
|
-
}
|
|
249
|
-
vfs.writeFile(path, bytes);
|
|
250
|
-
written++;
|
|
251
|
-
}
|
|
252
|
-
catch { }
|
|
253
|
-
}
|
|
254
|
-
for (const path of diff.filesDeleted) {
|
|
255
|
-
try {
|
|
256
|
-
vfs.unlink(path);
|
|
257
|
-
deleted++;
|
|
258
|
-
}
|
|
259
|
-
catch { }
|
|
260
|
-
}
|
|
261
|
-
for (const path of diff.dirsDeleted) {
|
|
262
|
-
try {
|
|
263
|
-
vfs.rmdir(path);
|
|
264
|
-
rmdirs++;
|
|
265
|
-
}
|
|
266
|
-
catch { }
|
|
267
|
-
}
|
|
268
|
-
// WASI socket and polling support B1+B3: count timesChanged / symlinks for diagnostics. The
|
|
269
|
-
// current SqliteVFS doesn't expose utime() or symlink() on its public
|
|
270
|
-
// surface, so we don't persist these across calls — they live only
|
|
271
|
-
// within the call (mtimes are read back correctly via stat→filestat_get
|
|
272
|
-
// before the snapshot returns). This is a documented v1 limitation.
|
|
273
|
-
if (diff.timesChanged) {
|
|
274
|
-
timesTouched = Object.keys(diff.timesChanged).length;
|
|
275
|
-
// Future hook: when SqliteVFS gains a utime() method, call it here:
|
|
276
|
-
// for (const [path, t] of Object.entries(diff.timesChanged)) {
|
|
277
|
-
// try { vfs.utime(path, Number(t.atime) / 1e9, Number(t.mtime) / 1e9); } catch {}
|
|
278
|
-
// }
|
|
279
|
-
}
|
|
280
|
-
if (diff.symlinksCreated) {
|
|
281
|
-
symlinks = Object.keys(diff.symlinksCreated).length;
|
|
282
|
-
// Future hook: when SqliteVFS gains a symlink() method, call it here.
|
|
283
|
-
}
|
|
284
|
-
return { written, deleted, mkdirs, rmdirs, timesTouched, symlinks };
|
|
285
|
-
}
|
|
286
127
|
/**
|
|
287
128
|
* Build a `run` function suitable for RuntimeSpec.run(). Parameterised
|
|
288
129
|
* over the VFS, env (for env.LOADER), ctx (for the pool's doId-scoped
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session/agent.ts - Nimbus session chat agent and Cloudflare OAuth flow.
|
|
3
|
+
*
|
|
4
|
+
* The agent lives in the session Durable Object because that is where the
|
|
5
|
+
* VFS, shell, process table, port registry, and runtime package manager
|
|
6
|
+
* already live. AI calls go through Cloudflare's account REST API so a
|
|
7
|
+
* connected user can spend their own Workers AI quota instead of the
|
|
8
|
+
* Nimbus deployment owner quota.
|
|
9
|
+
*/
|
|
10
|
+
interface AgentStorage {
|
|
11
|
+
get(key: string): Promise<unknown>;
|
|
12
|
+
put(key: string, value: unknown): Promise<void>;
|
|
13
|
+
delete(key: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
interface AgentVfs {
|
|
16
|
+
exists(path: string): boolean;
|
|
17
|
+
mkdir(path: string, options?: {
|
|
18
|
+
recursive?: boolean;
|
|
19
|
+
}): void;
|
|
20
|
+
readFileString(path: string): string;
|
|
21
|
+
readdir(path: string): Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
type: string;
|
|
24
|
+
}>;
|
|
25
|
+
writeFile(path: string, content: string): void;
|
|
26
|
+
}
|
|
27
|
+
interface Host {
|
|
28
|
+
ctx: {
|
|
29
|
+
storage: AgentStorage;
|
|
30
|
+
};
|
|
31
|
+
env: Record<string, unknown>;
|
|
32
|
+
sqliteFs?: AgentVfs | null;
|
|
33
|
+
}
|
|
34
|
+
interface OAuthStatePayload {
|
|
35
|
+
v: 1;
|
|
36
|
+
nonce: string;
|
|
37
|
+
sessionId: string;
|
|
38
|
+
tenantSegment: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function handleAgentRequest(self: Host, request: Request, url: URL): Promise<Response>;
|
|
41
|
+
export declare function parseAgentOAuthStateParam(state: string | null): OAuthStatePayload | null;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/session/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmCH,UAAU,YAAY;IACpB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,UAAU,QAAQ;IAChB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7D,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,UAAU,IAAI;IACZ,GAAG,EAAE;QAAE,OAAO,EAAE,YAAY,CAAA;KAAE,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC5B;AAED,UAAU,iBAAiB;IACzB,CAAC,EAAE,CAAC,CAAC;IACL,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA0FD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwClG;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAQxF"}
|