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,348 @@
1
+ import "./chunk-PR4QN5HX.js";
2
+
3
+ // src/pyodide-session.ts
4
+ var PYODIDE_VERSION = "0.27.7";
5
+ var PYODIDE_CDN_URL = `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/`;
6
+ var PYTHON_VERSION = "3.13";
7
+ var PIP_USAGE = [
8
+ "Usage: pip <command> [options]",
9
+ "",
10
+ "Commands:",
11
+ " install <pkg> Install packages",
12
+ " list List installed packages",
13
+ " show <pkg> Show information about a package",
14
+ " uninstall <pkg> Uninstall packages",
15
+ " --version Show pip version"
16
+ ].join("\n");
17
+ async function syncToEmscriptenFS(srcFs, emFs, srcPath, emPath) {
18
+ try {
19
+ emFs.stat(emPath);
20
+ } catch {
21
+ emFs.mkdir(emPath);
22
+ }
23
+ let entries;
24
+ try {
25
+ entries = await srcFs.readdir(srcPath);
26
+ } catch {
27
+ return;
28
+ }
29
+ for (const entry of entries) {
30
+ const srcChild = srcPath === "/" ? `/${entry}` : `${srcPath}/${entry}`;
31
+ const emChild = emPath === "/" ? `/${entry}` : `${emPath}/${entry}`;
32
+ try {
33
+ const stat = await srcFs.stat(srcChild);
34
+ if (stat.isDirectory) {
35
+ await syncToEmscriptenFS(srcFs, emFs, srcChild, emChild);
36
+ } else {
37
+ const content = await srcFs.readFileBuffer(srcChild);
38
+ emFs.writeFile(emChild, content);
39
+ }
40
+ } catch {
41
+ }
42
+ }
43
+ }
44
+ async function syncFromEmscriptenFS(emFs, dstFs, emPath, dstPath) {
45
+ let entries;
46
+ try {
47
+ entries = emFs.readdir(emPath).filter((e) => e !== "." && e !== "..");
48
+ } catch {
49
+ return;
50
+ }
51
+ for (const entry of entries) {
52
+ const emChild = emPath === "/" ? `/${entry}` : `${emPath}/${entry}`;
53
+ const dstChild = dstPath === "/" ? `/${entry}` : `${dstPath}/${entry}`;
54
+ try {
55
+ const stat = emFs.stat(emChild);
56
+ if (emFs.isDir(stat.mode)) {
57
+ dstFs.mkdirSync(dstChild, { recursive: true });
58
+ await syncFromEmscriptenFS(emFs, dstFs, emChild, dstChild);
59
+ } else if (emFs.isFile(stat.mode)) {
60
+ const content = emFs.readFile(emChild);
61
+ dstFs.writeFileSync(dstChild, content);
62
+ }
63
+ } catch {
64
+ }
65
+ }
66
+ }
67
+ var PyodideSession = class {
68
+ constructor(fs) {
69
+ this.fs = fs;
70
+ }
71
+ fs;
72
+ pyodide = null;
73
+ initPromise = null;
74
+ stdoutWriter;
75
+ async ensureInitialized() {
76
+ if (this.pyodide) return;
77
+ if (this.initPromise) {
78
+ await this.initPromise;
79
+ return;
80
+ }
81
+ this.initPromise = (async () => {
82
+ const { loadPyodide } = await import(
83
+ /* webpackIgnore: true */
84
+ `${PYODIDE_CDN_URL}pyodide.mjs`
85
+ );
86
+ this.pyodide = await loadPyodide({
87
+ indexURL: PYODIDE_CDN_URL,
88
+ packages: ["micropip"]
89
+ });
90
+ try {
91
+ this.pyodide.FS.mkdir("/workspace");
92
+ } catch {
93
+ }
94
+ })();
95
+ await this.initPromise;
96
+ }
97
+ async syncWorkspaceToEmscriptenFS(cwd) {
98
+ if (!this.pyodide) return;
99
+ const workspaceRoot = this.getWorkspaceRoot(cwd);
100
+ await syncToEmscriptenFS(this.fs, this.pyodide.FS, workspaceRoot, workspaceRoot);
101
+ }
102
+ async syncWorkspaceFromEmscriptenFS(cwd) {
103
+ if (!this.pyodide) return;
104
+ const workspaceRoot = this.getWorkspaceRoot(cwd);
105
+ await syncFromEmscriptenFS(this.pyodide.FS, this.fs, workspaceRoot, workspaceRoot);
106
+ }
107
+ getWorkspaceRoot(cwd) {
108
+ const parts = cwd.split("/").filter(Boolean);
109
+ return parts.length > 0 ? `/${parts[0]}` : "/workspace";
110
+ }
111
+ setStdoutWriter(writer) {
112
+ this.stdoutWriter = writer;
113
+ }
114
+ async executePython(args, ctx) {
115
+ const cwd = ctx.cwd;
116
+ const invocation = parsePythonArgs(args);
117
+ if (invocation.kind === "version") {
118
+ return { stdout: `Python ${PYTHON_VERSION}
119
+ `, stderr: "", exitCode: 0 };
120
+ }
121
+ if (invocation.kind === "help") {
122
+ return {
123
+ stdout: "usage: python3 [option] ... [-c cmd | -m mod | file | -] [arg] ...\nSupported modes: python3 <file>, python3 -c <code>, python3 --version\n",
124
+ stderr: "",
125
+ exitCode: 0
126
+ };
127
+ }
128
+ if (invocation.kind === "error") {
129
+ return { stdout: "", stderr: invocation.message + "\n", exitCode: 1 };
130
+ }
131
+ await this.ensureInitialized();
132
+ const pyodide = this.pyodide;
133
+ this.syncWorkspaceToEmscriptenFS(cwd);
134
+ let stdout = "";
135
+ let stderr = "";
136
+ pyodide.setStdout({
137
+ batched: (msg) => {
138
+ stdout += msg + "\n";
139
+ this.stdoutWriter?.(msg + "\n");
140
+ }
141
+ });
142
+ pyodide.setStderr({
143
+ batched: (msg) => {
144
+ stderr += msg + "\n";
145
+ this.stdoutWriter?.(msg + "\n");
146
+ }
147
+ });
148
+ pyodide.runPython(`
149
+ import os
150
+ os.chdir(${JSON.stringify(cwd)})
151
+ `);
152
+ let code;
153
+ if (invocation.kind === "eval") {
154
+ code = invocation.code;
155
+ } else {
156
+ const filePath = invocation.filePath.startsWith("/") ? invocation.filePath : `${cwd}/${invocation.filePath}`;
157
+ try {
158
+ const content = pyodide.FS.readFile(filePath, { encoding: "utf8" });
159
+ code = content;
160
+ } catch {
161
+ return {
162
+ stdout: "",
163
+ stderr: `python3: can't open file '${invocation.filePath}': [Errno 2] No such file or directory
164
+ `,
165
+ exitCode: 2
166
+ };
167
+ }
168
+ }
169
+ try {
170
+ await pyodide.loadPackagesFromImports(code, {
171
+ messageCallback: (msg) => {
172
+ this.stdoutWriter?.(msg + "\n");
173
+ }
174
+ });
175
+ await pyodide.runPythonAsync(code);
176
+ this.syncWorkspaceFromEmscriptenFS(cwd);
177
+ return { stdout, stderr, exitCode: 0 };
178
+ } catch (error) {
179
+ const errorMsg = error instanceof Error ? error.message : String(error);
180
+ stderr += errorMsg + "\n";
181
+ return { stdout, stderr, exitCode: 1 };
182
+ }
183
+ }
184
+ async executePip(args, ctx) {
185
+ const subcommand = args[0];
186
+ if (!subcommand || subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
187
+ return { stdout: PIP_USAGE + "\n", stderr: "", exitCode: 0 };
188
+ }
189
+ if (subcommand === "--version" || subcommand === "-V") {
190
+ await this.ensureInitialized();
191
+ return {
192
+ stdout: `pip (micropip) for Python ${PYTHON_VERSION} [Pyodide ${this.pyodide.version}]
193
+ `,
194
+ stderr: "",
195
+ exitCode: 0
196
+ };
197
+ }
198
+ await this.ensureInitialized();
199
+ const pyodide = this.pyodide;
200
+ let stdout = "";
201
+ let stderr = "";
202
+ pyodide.setStdout({
203
+ batched: (msg) => {
204
+ stdout += msg + "\n";
205
+ this.stdoutWriter?.(msg + "\n");
206
+ }
207
+ });
208
+ pyodide.setStderr({
209
+ batched: (msg) => {
210
+ stderr += msg + "\n";
211
+ this.stdoutWriter?.(msg + "\n");
212
+ }
213
+ });
214
+ switch (subcommand) {
215
+ case "install": {
216
+ const packages = args.slice(1).filter((a) => !a.startsWith("-"));
217
+ if (packages.length === 0) {
218
+ return { stdout: "", stderr: "ERROR: You must give at least one requirement to install\n", exitCode: 1 };
219
+ }
220
+ try {
221
+ const packageList = packages.map((p) => JSON.stringify(p)).join(", ");
222
+ await pyodide.runPythonAsync(`
223
+ import micropip
224
+ await micropip.install([${packageList}])
225
+ `);
226
+ const installedMsg = `Successfully installed ${packages.join(" ")}
227
+ `;
228
+ stdout += installedMsg;
229
+ this.stdoutWriter?.(installedMsg);
230
+ return { stdout, stderr, exitCode: 0 };
231
+ } catch (error) {
232
+ const errorMsg = error instanceof Error ? error.message : String(error);
233
+ stderr += errorMsg + "\n";
234
+ return { stdout, stderr, exitCode: 1 };
235
+ }
236
+ }
237
+ case "list": {
238
+ try {
239
+ await pyodide.runPythonAsync(`
240
+ import micropip
241
+ pkgs = micropip.list()
242
+ print(f"{'Package':<30} {'Version':<15}")
243
+ print(f"{'-'*30} {'-'*15}")
244
+ for name, pkg in sorted(pkgs.items()):
245
+ print(f"{name:<30} {pkg.version:<15}")
246
+ `);
247
+ return { stdout, stderr, exitCode: 0 };
248
+ } catch (error) {
249
+ const errorMsg = error instanceof Error ? error.message : String(error);
250
+ stderr += errorMsg + "\n";
251
+ return { stdout, stderr, exitCode: 1 };
252
+ }
253
+ }
254
+ case "show": {
255
+ const packageName = args[1];
256
+ if (!packageName) {
257
+ return { stdout: "", stderr: "ERROR: Please provide a package name\n", exitCode: 1 };
258
+ }
259
+ try {
260
+ await pyodide.runPythonAsync(`
261
+ import micropip
262
+ pkgs = micropip.list()
263
+ pkg_name = ${JSON.stringify(packageName)}
264
+ if pkg_name in pkgs:
265
+ pkg = pkgs[pkg_name]
266
+ print(f"Name: {pkg_name}")
267
+ print(f"Version: {pkg.version}")
268
+ else:
269
+ print(f"WARNING: Package(s) not found: {pkg_name}")
270
+ `);
271
+ return { stdout, stderr, exitCode: 0 };
272
+ } catch (error) {
273
+ const errorMsg = error instanceof Error ? error.message : String(error);
274
+ stderr += errorMsg + "\n";
275
+ return { stdout, stderr, exitCode: 1 };
276
+ }
277
+ }
278
+ case "uninstall": {
279
+ const packages = args.slice(1).filter((a) => !a.startsWith("-"));
280
+ if (packages.length === 0) {
281
+ return { stdout: "", stderr: "ERROR: You must give at least one requirement to uninstall\n", exitCode: 1 };
282
+ }
283
+ try {
284
+ const packageList = packages.map((p) => JSON.stringify(p)).join(", ");
285
+ await pyodide.runPythonAsync(`
286
+ import micropip
287
+ micropip.uninstall([${packageList}])
288
+ `);
289
+ const uninstalledMsg = `Successfully uninstalled ${packages.join(" ")}
290
+ `;
291
+ stdout += uninstalledMsg;
292
+ this.stdoutWriter?.(uninstalledMsg);
293
+ return { stdout, stderr, exitCode: 0 };
294
+ } catch (error) {
295
+ const errorMsg = error instanceof Error ? error.message : String(error);
296
+ stderr += errorMsg + "\n";
297
+ return { stdout, stderr, exitCode: 1 };
298
+ }
299
+ }
300
+ default:
301
+ return { stdout: "", stderr: `ERROR: unknown command "${subcommand}"
302
+ ${PIP_USAGE}
303
+ `, exitCode: 1 };
304
+ }
305
+ }
306
+ dispose() {
307
+ this.pyodide = null;
308
+ this.initPromise = null;
309
+ }
310
+ };
311
+ function parsePythonArgs(args) {
312
+ if (args.length === 0) {
313
+ return { kind: "error", message: "REPL mode is not supported. Use python3 -c <code> or python3 <file>." };
314
+ }
315
+ const [first, ...rest] = args;
316
+ if (first === "-V" || first === "--version") {
317
+ return { kind: "version" };
318
+ }
319
+ if (first === "-h" || first === "--help") {
320
+ return { kind: "help" };
321
+ }
322
+ if (first === "-c") {
323
+ const code = rest[0]?.trim();
324
+ if (!code) {
325
+ return { kind: "error", message: "python3 -c requires inline code" };
326
+ }
327
+ return { kind: "eval", code };
328
+ }
329
+ if (first === "-m") {
330
+ const moduleName = rest[0]?.trim();
331
+ if (!moduleName) {
332
+ return { kind: "error", message: "python3 -m requires a module name" };
333
+ }
334
+ return { kind: "eval", code: `import runpy; runpy.run_module(${JSON.stringify(moduleName)}, run_name='__main__')` };
335
+ }
336
+ if (first.startsWith("-")) {
337
+ return { kind: "error", message: `Unsupported option: ${first}` };
338
+ }
339
+ return { kind: "run-file", filePath: first };
340
+ }
341
+ function createPyodideSession(fs) {
342
+ return new PyodideSession(fs);
343
+ }
344
+ export {
345
+ PyodideSession,
346
+ createPyodideSession
347
+ };
348
+ //# sourceMappingURL=pyodide-session-I7LP2GQO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pyodide-session.ts"],"sourcesContent":["import type { CommandContext, ExecResult } from \"just-bash/browser\"\r\nimport { ObservableInMemoryFs } from \"./observable-in-memory-fs\"\r\n\r\n/**\r\n * Pyodide version loaded from CDN.\r\n * Update this when upgrading to a newer Pyodide release.\r\n */\r\nconst PYODIDE_VERSION = \"0.27.7\"\r\nconst PYODIDE_CDN_URL = `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/`\r\n\r\nconst PYTHON_VERSION = \"3.13\"\r\n\r\nconst PIP_USAGE = [\r\n \"Usage: pip <command> [options]\",\r\n \"\",\r\n \"Commands:\",\r\n \" install <pkg> Install packages\",\r\n \" list List installed packages\",\r\n \" show <pkg> Show information about a package\",\r\n \" uninstall <pkg> Uninstall packages\",\r\n \" --version Show pip version\",\r\n].join(\"\\n\")\r\n\r\n/**\r\n * Minimal type for the Pyodide API surface we use.\r\n * We dynamically import pyodide from CDN so there's no compile-time package.\r\n */\r\ninterface PyodideAPI {\r\n version: string\r\n FS: EmscriptenFS\r\n runPython(code: string, options?: { globals?: unknown }): unknown\r\n runPythonAsync(code: string, options?: { globals?: unknown }): Promise<unknown>\r\n loadPackagesFromImports(code: string, options?: { messageCallback?: (msg: string) => void; errorCallback?: (msg: string) => void }): Promise<unknown>\r\n loadPackage(names: string | string[], options?: { messageCallback?: (msg: string) => void; errorCallback?: (msg: string) => void }): Promise<unknown>\r\n setStdout(options: { batched: (msg: string) => void }): void\r\n setStderr(options: { batched: (msg: string) => void }): void\r\n setStdin(options: { stdin: () => string | null }): void\r\n globals: { get(name: string): unknown }\r\n}\r\n\r\n/** Minimal Emscripten FS type surface */\r\ninterface EmscriptenFS {\r\n mkdir(path: string): void\r\n writeFile(path: string, data: string | Uint8Array, opts?: { encoding?: string }): void\r\n readFile(path: string, opts?: { encoding?: string }): string | Uint8Array\r\n readdir(path: string): string[]\r\n stat(path: string): { mode: number; size: number }\r\n unlink(path: string): void\r\n rmdir(path: string): void\r\n isDir(mode: number): boolean\r\n isFile(mode: number): boolean\r\n}\r\n\r\n/**\r\n * Recursively sync files from ObservableInMemoryFs → Pyodide's Emscripten FS.\r\n * Creates directories as needed and writes all files.\r\n */\r\nasync function syncToEmscriptenFS(\r\n srcFs: ObservableInMemoryFs,\r\n emFs: EmscriptenFS,\r\n srcPath: string,\r\n emPath: string,\r\n): Promise<void> {\r\n // Ensure target directory exists in Emscripten FS\r\n try {\r\n emFs.stat(emPath)\r\n } catch {\r\n emFs.mkdir(emPath)\r\n }\r\n\r\n let entries: string[]\r\n try {\r\n entries = await srcFs.readdir(srcPath)\r\n } catch {\r\n return\r\n }\r\n\r\n for (const entry of entries) {\r\n const srcChild = srcPath === \"/\" ? `/${entry}` : `${srcPath}/${entry}`\r\n const emChild = emPath === \"/\" ? `/${entry}` : `${emPath}/${entry}`\r\n\r\n try {\r\n const stat = await srcFs.stat(srcChild)\r\n if (stat.isDirectory) {\r\n await syncToEmscriptenFS(srcFs, emFs, srcChild, emChild)\r\n } else {\r\n const content = await srcFs.readFileBuffer(srcChild)\r\n emFs.writeFile(emChild, content)\r\n }\r\n } catch {\r\n // Skip files that can't be read\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Recursively sync files from Pyodide's Emscripten FS → ObservableInMemoryFs.\r\n * Only syncs files that differ or are new.\r\n */\r\nasync function syncFromEmscriptenFS(\r\n emFs: EmscriptenFS,\r\n dstFs: ObservableInMemoryFs,\r\n emPath: string,\r\n dstPath: string,\r\n): Promise<void> {\r\n let entries: string[]\r\n try {\r\n entries = emFs.readdir(emPath).filter((e: string) => e !== \".\" && e !== \"..\")\r\n } catch {\r\n return\r\n }\r\n\r\n for (const entry of entries) {\r\n const emChild = emPath === \"/\" ? `/${entry}` : `${emPath}/${entry}`\r\n const dstChild = dstPath === \"/\" ? `/${entry}` : `${dstPath}/${entry}`\r\n\r\n try {\r\n const stat = emFs.stat(emChild)\r\n if (emFs.isDir(stat.mode)) {\r\n dstFs.mkdirSync(dstChild, { recursive: true })\r\n await syncFromEmscriptenFS(emFs, dstFs, emChild, dstChild)\r\n } else if (emFs.isFile(stat.mode)) {\r\n const content = emFs.readFile(emChild) as Uint8Array\r\n dstFs.writeFileSync(dstChild, content)\r\n }\r\n } catch {\r\n // Skip entries we can't read\r\n }\r\n }\r\n}\r\n\r\nexport class PyodideSession {\r\n private pyodide: PyodideAPI | null = null\r\n private initPromise: Promise<void> | null = null\r\n private stdoutWriter?: (data: string) => void\r\n\r\n constructor(private readonly fs: ObservableInMemoryFs) {}\r\n\r\n private async ensureInitialized(): Promise<void> {\r\n if (this.pyodide) return\r\n if (this.initPromise) {\r\n await this.initPromise\r\n return\r\n }\r\n\r\n this.initPromise = (async () => {\r\n const { loadPyodide } = await import(\r\n /* webpackIgnore: true */\r\n `${PYODIDE_CDN_URL}pyodide.mjs`\r\n ) as { loadPyodide: (opts?: Record<string, unknown>) => Promise<PyodideAPI> }\r\n\r\n this.pyodide = await loadPyodide({\r\n indexURL: PYODIDE_CDN_URL,\r\n packages: [\"micropip\"],\r\n })\r\n\r\n // Set up the workspace directory in Pyodide FS\r\n try {\r\n this.pyodide.FS.mkdir(\"/workspace\")\r\n } catch {\r\n // May already exist\r\n }\r\n })()\r\n\r\n await this.initPromise\r\n }\r\n\r\n private async syncWorkspaceToEmscriptenFS(cwd: string): Promise<void> {\r\n if (!this.pyodide) return\r\n\r\n // Determine the workspace root to sync\r\n // Sync the root path that contains cwd\r\n const workspaceRoot = this.getWorkspaceRoot(cwd)\r\n await syncToEmscriptenFS(this.fs, this.pyodide.FS, workspaceRoot, workspaceRoot)\r\n }\r\n\r\n private async syncWorkspaceFromEmscriptenFS(cwd: string): Promise<void> {\r\n if (!this.pyodide) return\r\n\r\n const workspaceRoot = this.getWorkspaceRoot(cwd)\r\n await syncFromEmscriptenFS(this.pyodide.FS, this.fs, workspaceRoot, workspaceRoot)\r\n }\r\n\r\n private getWorkspaceRoot(cwd: string): string {\r\n // Use the first path component under root as workspace root\r\n // e.g. /workspace/project → /workspace\r\n const parts = cwd.split(\"/\").filter(Boolean)\r\n return parts.length > 0 ? `/${parts[0]}` : \"/workspace\"\r\n }\r\n\r\n setStdoutWriter(writer: ((data: string) => void) | undefined): void {\r\n this.stdoutWriter = writer\r\n }\r\n\r\n async executePython(args: string[], ctx: CommandContext): Promise<ExecResult> {\r\n const cwd = ctx.cwd\r\n\r\n const invocation = parsePythonArgs(args)\r\n\r\n if (invocation.kind === \"version\") {\r\n return { stdout: `Python ${PYTHON_VERSION}\\n`, stderr: \"\", exitCode: 0 }\r\n }\r\n\r\n if (invocation.kind === \"help\") {\r\n return {\r\n stdout: \"usage: python3 [option] ... [-c cmd | -m mod | file | -] [arg] ...\\n\" +\r\n \"Supported modes: python3 <file>, python3 -c <code>, python3 --version\\n\",\r\n stderr: \"\",\r\n exitCode: 0,\r\n }\r\n }\r\n\r\n if (invocation.kind === \"error\") {\r\n return { stdout: \"\", stderr: invocation.message + \"\\n\", exitCode: 1 }\r\n }\r\n\r\n await this.ensureInitialized()\r\n const pyodide = this.pyodide!\r\n\r\n // Sync filesystem before execution\r\n this.syncWorkspaceToEmscriptenFS(cwd)\r\n\r\n let stdout = \"\"\r\n let stderr = \"\"\r\n\r\n pyodide.setStdout({\r\n batched: (msg: string) => {\r\n stdout += msg + \"\\n\"\r\n this.stdoutWriter?.(msg + \"\\n\")\r\n },\r\n })\r\n pyodide.setStderr({\r\n batched: (msg: string) => {\r\n stderr += msg + \"\\n\"\r\n this.stdoutWriter?.(msg + \"\\n\")\r\n },\r\n })\r\n\r\n // Set cwd in Python\r\n pyodide.runPython(`\r\nimport os\r\nos.chdir(${JSON.stringify(cwd)})\r\n`)\r\n\r\n let code: string\r\n if (invocation.kind === \"eval\") {\r\n code = invocation.code\r\n } else {\r\n // Run file\r\n const filePath = invocation.filePath.startsWith(\"/\")\r\n ? invocation.filePath\r\n : `${cwd}/${invocation.filePath}`\r\n try {\r\n const content = pyodide.FS.readFile(filePath, { encoding: \"utf8\" }) as string\r\n code = content\r\n } catch {\r\n return {\r\n stdout: \"\",\r\n stderr: `python3: can't open file '${invocation.filePath}': [Errno 2] No such file or directory\\n`,\r\n exitCode: 2,\r\n }\r\n }\r\n }\r\n\r\n try {\r\n // Auto-install any import-able packages\r\n await pyodide.loadPackagesFromImports(code, {\r\n messageCallback: (msg: string) => {\r\n this.stdoutWriter?.(msg + \"\\n\")\r\n },\r\n })\r\n\r\n await pyodide.runPythonAsync(code)\r\n\r\n // Sync filesystem after execution\r\n this.syncWorkspaceFromEmscriptenFS(cwd)\r\n\r\n return { stdout, stderr, exitCode: 0 }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error)\r\n stderr += errorMsg + \"\\n\"\r\n return { stdout, stderr, exitCode: 1 }\r\n }\r\n }\r\n\r\n async executePip(args: string[], ctx: CommandContext): Promise<ExecResult> {\r\n const subcommand = args[0]\r\n\r\n if (!subcommand || subcommand === \"help\" || subcommand === \"--help\" || subcommand === \"-h\") {\r\n return { stdout: PIP_USAGE + \"\\n\", stderr: \"\", exitCode: 0 }\r\n }\r\n\r\n if (subcommand === \"--version\" || subcommand === \"-V\") {\r\n await this.ensureInitialized()\r\n return {\r\n stdout: `pip (micropip) for Python ${PYTHON_VERSION} [Pyodide ${this.pyodide!.version}]\\n`,\r\n stderr: \"\",\r\n exitCode: 0,\r\n }\r\n }\r\n\r\n await this.ensureInitialized()\r\n const pyodide = this.pyodide!\r\n\r\n let stdout = \"\"\r\n let stderr = \"\"\r\n\r\n pyodide.setStdout({\r\n batched: (msg: string) => {\r\n stdout += msg + \"\\n\"\r\n this.stdoutWriter?.(msg + \"\\n\")\r\n },\r\n })\r\n pyodide.setStderr({\r\n batched: (msg: string) => {\r\n stderr += msg + \"\\n\"\r\n this.stdoutWriter?.(msg + \"\\n\")\r\n },\r\n })\r\n\r\n switch (subcommand) {\r\n case \"install\": {\r\n const packages = args.slice(1).filter((a) => !a.startsWith(\"-\"))\r\n if (packages.length === 0) {\r\n return { stdout: \"\", stderr: \"ERROR: You must give at least one requirement to install\\n\", exitCode: 1 }\r\n }\r\n\r\n try {\r\n const packageList = packages.map((p) => JSON.stringify(p)).join(\", \")\r\n await pyodide.runPythonAsync(`\r\nimport micropip\r\nawait micropip.install([${packageList}])\r\n`)\r\n const installedMsg = `Successfully installed ${packages.join(\" \")}\\n`\r\n stdout += installedMsg\r\n this.stdoutWriter?.(installedMsg)\r\n return { stdout, stderr, exitCode: 0 }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error)\r\n stderr += errorMsg + \"\\n\"\r\n return { stdout, stderr, exitCode: 1 }\r\n }\r\n }\r\n\r\n case \"list\": {\r\n try {\r\n await pyodide.runPythonAsync(`\r\nimport micropip\r\npkgs = micropip.list()\r\nprint(f\"{'Package':<30} {'Version':<15}\")\r\nprint(f\"{'-'*30} {'-'*15}\")\r\nfor name, pkg in sorted(pkgs.items()):\r\n print(f\"{name:<30} {pkg.version:<15}\")\r\n`)\r\n return { stdout, stderr, exitCode: 0 }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error)\r\n stderr += errorMsg + \"\\n\"\r\n return { stdout, stderr, exitCode: 1 }\r\n }\r\n }\r\n\r\n case \"show\": {\r\n const packageName = args[1]\r\n if (!packageName) {\r\n return { stdout: \"\", stderr: \"ERROR: Please provide a package name\\n\", exitCode: 1 }\r\n }\r\n\r\n try {\r\n await pyodide.runPythonAsync(`\r\nimport micropip\r\npkgs = micropip.list()\r\npkg_name = ${JSON.stringify(packageName)}\r\nif pkg_name in pkgs:\r\n pkg = pkgs[pkg_name]\r\n print(f\"Name: {pkg_name}\")\r\n print(f\"Version: {pkg.version}\")\r\nelse:\r\n print(f\"WARNING: Package(s) not found: {pkg_name}\")\r\n`)\r\n return { stdout, stderr, exitCode: 0 }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error)\r\n stderr += errorMsg + \"\\n\"\r\n return { stdout, stderr, exitCode: 1 }\r\n }\r\n }\r\n\r\n case \"uninstall\": {\r\n const packages = args.slice(1).filter((a) => !a.startsWith(\"-\"))\r\n if (packages.length === 0) {\r\n return { stdout: \"\", stderr: \"ERROR: You must give at least one requirement to uninstall\\n\", exitCode: 1 }\r\n }\r\n\r\n try {\r\n const packageList = packages.map((p) => JSON.stringify(p)).join(\", \")\r\n await pyodide.runPythonAsync(`\r\nimport micropip\r\nmicropip.uninstall([${packageList}])\r\n`)\r\n const uninstalledMsg = `Successfully uninstalled ${packages.join(\" \")}\\n`\r\n stdout += uninstalledMsg\r\n this.stdoutWriter?.(uninstalledMsg)\r\n return { stdout, stderr, exitCode: 0 }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error)\r\n stderr += errorMsg + \"\\n\"\r\n return { stdout, stderr, exitCode: 1 }\r\n }\r\n }\r\n\r\n default:\r\n return { stdout: \"\", stderr: `ERROR: unknown command \"${subcommand}\"\\n${PIP_USAGE}\\n`, exitCode: 1 }\r\n }\r\n }\r\n\r\n dispose(): void {\r\n this.pyodide = null\r\n this.initPromise = null\r\n }\r\n}\r\n\r\nfunction parsePythonArgs(args: string[]): \r\n | { kind: \"version\" }\r\n | { kind: \"help\" }\r\n | { kind: \"eval\"; code: string }\r\n | { kind: \"run-file\"; filePath: string }\r\n | { kind: \"error\"; message: string } {\r\n if (args.length === 0) {\r\n return { kind: \"error\", message: \"REPL mode is not supported. Use python3 -c <code> or python3 <file>.\" }\r\n }\r\n\r\n const [first, ...rest] = args\r\n\r\n if (first === \"-V\" || first === \"--version\") {\r\n return { kind: \"version\" }\r\n }\r\n\r\n if (first === \"-h\" || first === \"--help\") {\r\n return { kind: \"help\" }\r\n }\r\n\r\n if (first === \"-c\") {\r\n const code = rest[0]?.trim()\r\n if (!code) {\r\n return { kind: \"error\", message: \"python3 -c requires inline code\" }\r\n }\r\n return { kind: \"eval\", code }\r\n }\r\n\r\n if (first === \"-m\") {\r\n const moduleName = rest[0]?.trim()\r\n if (!moduleName) {\r\n return { kind: \"error\", message: \"python3 -m requires a module name\" }\r\n }\r\n // Run as `python -m module`\r\n return { kind: \"eval\", code: `import runpy; runpy.run_module(${JSON.stringify(moduleName)}, run_name='__main__')` }\r\n }\r\n\r\n if (first.startsWith(\"-\")) {\r\n return { kind: \"error\", message: `Unsupported option: ${first}` }\r\n }\r\n\r\n // It's a file path\r\n return { kind: \"run-file\", filePath: first }\r\n}\r\n\r\nexport function createPyodideSession(fs: ObservableInMemoryFs): PyodideSession {\r\n return new PyodideSession(fs)\r\n}\r\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-web-os",
3
- "version": "0.2.0",
3
+ "version": "0.3.0-beta.0",
4
4
  "description": "Browser-based bash + Node.js runtime with an observable in-memory filesystem",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",