@lamplitisles/dsh-nanocodex 0.1.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.
- package/LICENSE +65 -0
- package/NOTICE +2 -0
- package/README.md +182 -0
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/cordis.patch.yml +52 -0
- package/dist/index.d.ts +435 -0
- package/dist/index.js +3405 -0
- package/dist/standard-preset.d.ts +7 -0
- package/dist/standard-preset.js +25 -0
- package/engine-release.json +14 -0
- package/package.json +119 -0
- package/presets/standard/agent.cordis.yml +6 -0
- package/presets/standard/preset.yml +2 -0
- package/vendor/nanocodex/README.md +1344 -0
- package/vendor/nanocodex/actions/events.d.mts +10 -0
- package/vendor/nanocodex/actions/events.mjs +163 -0
- package/vendor/nanocodex/actions/index.d.mts +13 -0
- package/vendor/nanocodex/actions/index.mjs +35 -0
- package/vendor/nanocodex/actions/session.d.mts +66 -0
- package/vendor/nanocodex/actions/session.mjs +59 -0
- package/vendor/nanocodex/actions/turn.d.mts +59 -0
- package/vendor/nanocodex/actions/turn.mjs +37 -0
- package/vendor/nanocodex/actions/voice.d.mts +22 -0
- package/vendor/nanocodex/actions/voice.mjs +50 -0
- package/vendor/nanocodex/browser/Agent.d.mts +55 -0
- package/vendor/nanocodex/browser/Agent.mjs +11 -0
- package/vendor/nanocodex/browser/ChatGptSubscription.d.mts +7 -0
- package/vendor/nanocodex/browser/ChatGptSubscription.mjs +19 -0
- package/vendor/nanocodex/browser/InlineAgent.mjs +266 -0
- package/vendor/nanocodex/browser/Transport.d.mts +74 -0
- package/vendor/nanocodex/browser/Transport.mjs +61 -0
- package/vendor/nanocodex/browser/Voice.d.mts +71 -0
- package/vendor/nanocodex/browser/Voice.mjs +291 -0
- package/vendor/nanocodex/browser/VoiceSession.mjs +688 -0
- package/vendor/nanocodex/browser/WorkerAgent.d.mts +65 -0
- package/vendor/nanocodex/browser/WorkerAgent.mjs +1472 -0
- package/vendor/nanocodex/browser/agent.worker.mjs +3 -0
- package/vendor/nanocodex/browser/config.d.mts +36 -0
- package/vendor/nanocodex/browser/config.mjs +439 -0
- package/vendor/nanocodex/browser/engine.mjs +13 -0
- package/vendor/nanocodex/browser/harness.mjs +55 -0
- package/vendor/nanocodex/browser/host.d.mts +83 -0
- package/vendor/nanocodex/browser/host.mjs +555 -0
- package/vendor/nanocodex/browser/hostManagedWebSocket.d.mts +14 -0
- package/vendor/nanocodex/browser/hostManagedWebSocket.mjs +110 -0
- package/vendor/nanocodex/browser/index.d.mts +92 -0
- package/vendor/nanocodex/browser/index.mjs +23 -0
- package/vendor/nanocodex/browser/indexeddb-durability-store.mjs +197 -0
- package/vendor/nanocodex/browser/workspace.d.mts +16 -0
- package/vendor/nanocodex/browser/workspace.mjs +107 -0
- package/vendor/nanocodex/cloud/Client.d.mts +83 -0
- package/vendor/nanocodex/cloud/Client.mjs +231 -0
- package/vendor/nanocodex/cloud/Decorator.d.mts +31 -0
- package/vendor/nanocodex/cloud/Decorator.mjs +37 -0
- package/vendor/nanocodex/cloud/Dialog.d.mts +113 -0
- package/vendor/nanocodex/cloud/Dialog.mjs +366 -0
- package/vendor/nanocodex/cloud/Errors.d.mts +22 -0
- package/vendor/nanocodex/cloud/Errors.mjs +39 -0
- package/vendor/nanocodex/cloud/Principal.d.mts +26 -0
- package/vendor/nanocodex/cloud/Principal.mjs +88 -0
- package/vendor/nanocodex/cloud/RemoteProvider.mjs +88 -0
- package/vendor/nanocodex/cloud/Transport.d.mts +47 -0
- package/vendor/nanocodex/cloud/Transport.mjs +454 -0
- package/vendor/nanocodex/cloud/actions/account.d.mts +9 -0
- package/vendor/nanocodex/cloud/actions/account.mjs +19 -0
- package/vendor/nanocodex/cloud/actions/agent.d.mts +18 -0
- package/vendor/nanocodex/cloud/actions/agent.mjs +428 -0
- package/vendor/nanocodex/cloud/actions/connection.d.mts +133 -0
- package/vendor/nanocodex/cloud/actions/connection.mjs +580 -0
- package/vendor/nanocodex/cloud/actions/grant.d.mts +10 -0
- package/vendor/nanocodex/cloud/actions/grant.mjs +12 -0
- package/vendor/nanocodex/cloud/actions/index.d.mts +7 -0
- package/vendor/nanocodex/cloud/actions/index.mjs +7 -0
- package/vendor/nanocodex/cloud/actions/machineUsd.d.mts +23 -0
- package/vendor/nanocodex/cloud/actions/machineUsd.mjs +37 -0
- package/vendor/nanocodex/cloud/actions/model.d.mts +12 -0
- package/vendor/nanocodex/cloud/actions/model.mjs +50 -0
- package/vendor/nanocodex/cloud/actions/mpp.d.mts +28 -0
- package/vendor/nanocodex/cloud/actions/mpp.mjs +39 -0
- package/vendor/nanocodex/cloud/index.d.mts +30 -0
- package/vendor/nanocodex/cloud/index.mjs +9 -0
- package/vendor/nanocodex/cloud/internal.mjs +533 -0
- package/vendor/nanocodex/cloud/mercator.mjs +108 -0
- package/vendor/nanocodex/cloud/server/HostPrincipal.d.mts +34 -0
- package/vendor/nanocodex/cloud/server/HostPrincipal.mjs +202 -0
- package/vendor/nanocodex/cloud/server/index.d.mts +1 -0
- package/vendor/nanocodex/cloud/server/index.mjs +1 -0
- package/vendor/nanocodex/cloud/types.d.mts +211 -0
- package/vendor/nanocodex/cloudflare/Agent.d.mts +133 -0
- package/vendor/nanocodex/cloudflare/Agent.mjs +811 -0
- package/vendor/nanocodex/cloudflare/egress-subject.mjs +19 -0
- package/vendor/nanocodex/cloudflare/egress.d.mts +41 -0
- package/vendor/nanocodex/cloudflare/egress.mjs +119 -0
- package/vendor/nanocodex/cloudflare/event-socket.mjs +316 -0
- package/vendor/nanocodex/cloudflare/index.d.mts +7 -0
- package/vendor/nanocodex/cloudflare/index.mjs +6 -0
- package/vendor/nanocodex/host/Agent.d.mts +55 -0
- package/vendor/nanocodex/host/Agent.mjs +1 -0
- package/vendor/nanocodex/host/index.d.mts +82 -0
- package/vendor/nanocodex/host/index.mjs +10 -0
- package/vendor/nanocodex/index.d.mts +81 -0
- package/vendor/nanocodex/index.mjs +12 -0
- package/vendor/nanocodex/internal.mjs +1275 -0
- package/vendor/nanocodex/managed/Agent.d.mts +380 -0
- package/vendor/nanocodex/managed/Agent.mjs +1694 -0
- package/vendor/nanocodex/managed/ManagedError.d.mts +9 -0
- package/vendor/nanocodex/managed/ManagedError.mjs +8 -0
- package/vendor/nanocodex/managed/README.md +241 -0
- package/vendor/nanocodex/managed/Voice.mjs +202 -0
- package/vendor/nanocodex/managed/index.d.mts +20 -0
- package/vendor/nanocodex/managed/index.mjs +2 -0
- package/vendor/nanocodex/managed/internal.mjs +119 -0
- package/vendor/nanocodex/node/Agent.d.mts +50 -0
- package/vendor/nanocodex/node/Agent.mjs +203 -0
- package/vendor/nanocodex/node/ChatGptSubscription.d.mts +9 -0
- package/vendor/nanocodex/node/ChatGptSubscription.mjs +17 -0
- package/vendor/nanocodex/node/Transport.d.mts +44 -0
- package/vendor/nanocodex/node/Transport.mjs +46 -0
- package/vendor/nanocodex/node/host.mjs +731 -0
- package/vendor/nanocodex/node/index.d.mts +73 -0
- package/vendor/nanocodex/node/index.mjs +17 -0
- package/vendor/nanocodex/node/workspace.d.mts +10 -0
- package/vendor/nanocodex/node/workspace.mjs +198 -0
- package/vendor/nanocodex/package.json +200 -0
- package/vendor/nanocodex/pkg-node/nanocodex.d.ts +675 -0
- package/vendor/nanocodex/pkg-node/nanocodex.js +2628 -0
- package/vendor/nanocodex/pkg-node/nanocodex_bg.wasm.d.ts +105 -0
- package/vendor/nanocodex/pkg-node/package.json +1 -0
- package/vendor/nanocodex/pkg-web/.nanocodex-bindgen-stamp +6 -0
- package/vendor/nanocodex/pkg-web/nanocodex-build.json +1 -0
- package/vendor/nanocodex/pkg-web/nanocodex.d.ts +805 -0
- package/vendor/nanocodex/pkg-web/nanocodex.js +2714 -0
- package/vendor/nanocodex/pkg-web/nanocodex_bg.js +2615 -0
- package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm +0 -0
- package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm.d.ts +105 -0
- package/vendor/nanocodex/pkg-web/nanocodex_worker.js +9 -0
- package/vendor/nanocodex/pkg-web/package.json +1 -0
- package/vendor/nanocodex/runtime/chatgpt-subscription.mjs +212 -0
- package/vendor/nanocodex/runtime/cloudflare-durability-store.d.mts +26 -0
- package/vendor/nanocodex/runtime/cloudflare-durability-store.mjs +168 -0
- package/vendor/nanocodex/runtime/code-evaluator.worker.mjs +137 -0
- package/vendor/nanocodex/runtime/code-runtime.mjs +1 -0
- package/vendor/nanocodex/runtime/durability-store.d.mts +85 -0
- package/vendor/nanocodex/runtime/durability-store.mjs +631 -0
- package/vendor/nanocodex/runtime/durability.mjs +153 -0
- package/vendor/nanocodex/runtime/managed-transport.mjs +460 -0
- package/vendor/nanocodex/runtime/mcp-runtime.mjs +534 -0
- package/vendor/nanocodex/runtime/postgres-durability-store.d.mts +64 -0
- package/vendor/nanocodex/runtime/postgres-durability-store.mjs +532 -0
- package/vendor/nanocodex/runtime/quickjs-evaluator.d.mts +17 -0
- package/vendor/nanocodex/runtime/quickjs-evaluator.mjs +236 -0
- package/vendor/nanocodex/runtime/responses-transport.mjs +22 -0
- package/vendor/nanocodex/runtime/subagents.d.mts +107 -0
- package/vendor/nanocodex/runtime/subagents.mjs +54 -0
- package/vendor/nanocodex/runtime/subscription-store.d.mts +8 -0
- package/vendor/nanocodex/runtime/subscription-store.mjs +42 -0
- package/vendor/nanocodex/runtime/tempo-provider.d.mts +125 -0
- package/vendor/nanocodex/runtime/tempo-provider.mjs +264 -0
- package/vendor/nanocodex/runtime/tool-configuration.mjs +1 -0
- package/vendor/nanocodex/runtime/tool-router.mjs +1 -0
- package/vendor/nanocodex/runtime/utf8.mjs +1 -0
- package/vendor/nanocodex/runtime/worker-evaluator.mjs +162 -0
- package/vendor/nanocodex/runtime/workspace.d.mts +1 -0
- package/vendor/nanocodex/runtime/workspace.mjs +1 -0
- package/vendor/nanocodex/tools/Tools.d.mts +56 -0
- package/vendor/nanocodex/tools/Tools.mjs +136 -0
- package/vendor/nanocodex/tools/artifact.d.mts +1 -0
- package/vendor/nanocodex/tools/artifact.mjs +1 -0
- package/vendor/nanocodex/tools/attachment.mjs +1 -0
- package/vendor/nanocodex/tools/bash.d.mts +1 -0
- package/vendor/nanocodex/tools/bash.mjs +1 -0
- package/vendor/nanocodex/tools/browser/accountInfo.mjs +795 -0
- package/vendor/nanocodex/tools/browser/browserBuffer.mjs +18 -0
- package/vendor/nanocodex/tools/browser/browserCompiler.mjs +155 -0
- package/vendor/nanocodex/tools/browser/browserEgress.mjs +161 -0
- package/vendor/nanocodex/tools/browser/browserPython.mjs +133 -0
- package/vendor/nanocodex/tools/browser/browserShell.mjs +1075 -0
- package/vendor/nanocodex/tools/browser/browserSprintf.mjs +4 -0
- package/vendor/nanocodex/tools/browser/browserSsh.mjs +201 -0
- package/vendor/nanocodex/tools/browser/browserZlib.mjs +136 -0
- package/vendor/nanocodex/tools/browser/compiler.worker.mjs +160 -0
- package/vendor/nanocodex/tools/browser/devTunnelsSshBrowser.mjs +13 -0
- package/vendor/nanocodex/tools/browser/index.d.mts +209 -0
- package/vendor/nanocodex/tools/browser/index.mjs +174 -0
- package/vendor/nanocodex/tools/browser/opfsGit.mjs +248 -0
- package/vendor/nanocodex/tools/browser/python.worker.mjs +114 -0
- package/vendor/nanocodex/tools/browser/threadGit.mjs +197 -0
- package/vendor/nanocodex/tools/browser/unsupportedNodeRsa.mjs +5 -0
- package/vendor/nanocodex/tools/browser/workspace.mjs +83 -0
- package/vendor/nanocodex/tools/dataset.d.mts +1 -0
- package/vendor/nanocodex/tools/dataset.mjs +1 -0
- package/vendor/nanocodex/tools/datasetContract.mjs +1 -0
- package/vendor/nanocodex/tools/datasetEngine.mjs +1 -0
- package/vendor/nanocodex/tools/hostedCatalog.d.mts +1 -0
- package/vendor/nanocodex/tools/hostedCatalog.mjs +1 -0
- package/vendor/nanocodex/tools/index.d.mts +49 -0
- package/vendor/nanocodex/tools/index.mjs +19 -0
- package/vendor/nanocodex/tools/namedTool.mjs +1 -0
- package/vendor/nanocodex/tools/repository-workspace.d.mts +1 -0
- package/vendor/nanocodex/tools/repository-workspace.mjs +1 -0
- package/vendor/nanocodex/tools/ssh.d.mts +1 -0
- package/vendor/nanocodex/tools/ssh.mjs +1 -0
- package/vendor/nanocodex/tools/standard.mjs +1 -0
- package/vendor/nanocodex/tools/standardDescriptions.mjs +1 -0
- package/vendor/nanocodex/types.d.mts +663 -0
- package/vendor/nanocodex/wasm.d.mts +4 -0
- package/vendor/nanocodex/worker/ChatGptSubscription.d.mts +9 -0
- package/vendor/nanocodex/worker/ChatGptSubscription.mjs +29 -0
- package/vendor/nanocodex/worker/index.d.mts +18 -0
- package/vendor/nanocodex/worker/index.mjs +5 -0
- package/vendor/nanocodex-tools/README.md +65 -0
- package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.d.ts +7 -0
- package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.js +14 -0
- package/vendor/nanocodex-tools/dist/hosted/broker-core.d.ts +172 -0
- package/vendor/nanocodex-tools/dist/hosted/broker-core.js +1278 -0
- package/vendor/nanocodex-tools/dist/hosted/index.d.ts +3 -0
- package/vendor/nanocodex-tools/dist/hosted/index.js +3 -0
- package/vendor/nanocodex-tools/dist/hosted/protocol.d.ts +120 -0
- package/vendor/nanocodex-tools/dist/hosted/protocol.js +415 -0
- package/vendor/nanocodex-tools/dist/index.d.ts +19 -0
- package/vendor/nanocodex-tools/dist/index.js +14 -0
- package/vendor/nanocodex-tools/dist/memory.d.ts +204 -0
- package/vendor/nanocodex-tools/dist/memory.js +411 -0
- package/vendor/nanocodex-tools/dist/namespace.d.ts +87 -0
- package/vendor/nanocodex-tools/dist/namespace.js +338 -0
- package/vendor/nanocodex-tools/dist/repository-archive.d.ts +4 -0
- package/vendor/nanocodex-tools/dist/repository-archive.js +104 -0
- package/vendor/nanocodex-tools/dist/runtime.d.ts +30 -0
- package/vendor/nanocodex-tools/dist/runtime.js +37 -0
- package/vendor/nanocodex-tools/dist/session.d.ts +167 -0
- package/vendor/nanocodex-tools/dist/session.js +286 -0
- package/vendor/nanocodex-tools/dist/shell.d.ts +51 -0
- package/vendor/nanocodex-tools/dist/shell.js +553 -0
- package/vendor/nanocodex-tools/dist/ssh.d.ts +29 -0
- package/vendor/nanocodex-tools/dist/ssh.js +66 -0
- package/vendor/nanocodex-tools/dist/workspace.d.ts +45 -0
- package/vendor/nanocodex-tools/dist/workspace.js +237 -0
- package/vendor/nanocodex-tools/package.json +122 -0
- package/vendor/nanocodex-tools/runtime/code-runtime.mjs +817 -0
- package/vendor/nanocodex-tools/runtime/tool-configuration.mjs +50 -0
- package/vendor/nanocodex-tools/runtime/tool-router.mjs +730 -0
- package/vendor/nanocodex-tools/runtime/utf8.d.mts +2 -0
- package/vendor/nanocodex-tools/runtime/utf8.mjs +25 -0
- package/vendor/nanocodex-tools/tools/artifact.d.mts +69 -0
- package/vendor/nanocodex-tools/tools/artifact.mjs +270 -0
- package/vendor/nanocodex-tools/tools/attachment.mjs +603 -0
- package/vendor/nanocodex-tools/tools/bash.d.mts +90 -0
- package/vendor/nanocodex-tools/tools/bash.mjs +742 -0
- package/vendor/nanocodex-tools/tools/dataset.d.mts +9 -0
- package/vendor/nanocodex-tools/tools/dataset.mjs +47 -0
- package/vendor/nanocodex-tools/tools/datasetContract.mjs +54 -0
- package/vendor/nanocodex-tools/tools/datasetEngine.mjs +1167 -0
- package/vendor/nanocodex-tools/tools/execution-contract.d.mts +5 -0
- package/vendor/nanocodex-tools/tools/execution-contract.mjs +63 -0
- package/vendor/nanocodex-tools/tools/hostedCatalog.d.mts +20 -0
- package/vendor/nanocodex-tools/tools/hostedCatalog.mjs +67 -0
- package/vendor/nanocodex-tools/tools/hostedMachine.d.mts +10 -0
- package/vendor/nanocodex-tools/tools/hostedMachine.mjs +56 -0
- package/vendor/nanocodex-tools/tools/just-bash-browser.d.mts +1 -0
- package/vendor/nanocodex-tools/tools/just-bash-browser.mjs +1 -0
- package/vendor/nanocodex-tools/tools/namedTool.d.mts +3 -0
- package/vendor/nanocodex-tools/tools/namedTool.mjs +3 -0
- package/vendor/nanocodex-tools/tools/nodeProcess.d.mts +10 -0
- package/vendor/nanocodex-tools/tools/nodeProcess.mjs +314 -0
- package/vendor/nanocodex-tools/tools/processOutput.mjs +56 -0
- package/vendor/nanocodex-tools/tools/repository-workspace.d.mts +55 -0
- package/vendor/nanocodex-tools/tools/repository-workspace.mjs +397 -0
- package/vendor/nanocodex-tools/tools/ssh.d.mts +56 -0
- package/vendor/nanocodex-tools/tools/ssh.mjs +503 -0
- package/vendor/nanocodex-tools/tools/standard.mjs +458 -0
- package/vendor/nanocodex-tools/tools/standardDescriptions.mjs +3 -0
- package/vendor/nanocodex-tools/tools/types.d.mts +83 -0
- package/vendor/nanocodex-tools/tools/workspace.d.mts +25 -0
- package/vendor/nanocodex-tools/tools/workspace.mjs +282 -0
- package/vendor/nanocodex-tools/tools/x.d.mts +30 -0
- package/vendor/nanocodex-tools/tools/x.mjs +91 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as bufferModule from "buffer";
|
|
2
|
+
|
|
3
|
+
// CommonJS interop differs between Vite's page optimizer, Worker graph, and
|
|
4
|
+
// production bundler. A namespace import requests no synthetic binding; read
|
|
5
|
+
// the constructor from whichever CJS namespace shape that graph provides.
|
|
6
|
+
const buffer = bufferModule.Buffer === undefined ? bufferModule.default : bufferModule;
|
|
7
|
+
export const { Buffer } = buffer;
|
|
8
|
+
if (typeof Buffer !== "function") {
|
|
9
|
+
throw new Error("the browser Buffer compatibility module did not expose Buffer");
|
|
10
|
+
}
|
|
11
|
+
// isomorphic-git still reads Buffer from the global scope in its browser build.
|
|
12
|
+
// Install it in every browser/Worker realm before a Git operation can run.
|
|
13
|
+
globalThis.Buffer ??= Buffer;
|
|
14
|
+
// A few CommonJS browser libraries (notably the SSH stream dependencies) use
|
|
15
|
+
// Node's `global` spelling even when their implementation selects Web Crypto.
|
|
16
|
+
const commonJsGlobal = globalThis;
|
|
17
|
+
commonJsGlobal.global ??= globalThis;
|
|
18
|
+
commonJsGlobal.process ??= { versions: {} };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { defineCommand } from "../../../nanocodex-tools/tools/just-bash-browser.mjs";
|
|
2
|
+
const runtimes = new WeakMap();
|
|
3
|
+
export function createCompilerCommand(name, filesystem, egress) {
|
|
4
|
+
const runtime = runtimes.get(filesystem) ?? new BrowserCompilerRuntime(egress);
|
|
5
|
+
runtimes.set(filesystem, runtime);
|
|
6
|
+
return defineCommand(name, async (args, context) => {
|
|
7
|
+
const parsed = parseArguments(name, args, context);
|
|
8
|
+
if ("result" in parsed)
|
|
9
|
+
return parsed.result;
|
|
10
|
+
try {
|
|
11
|
+
const files = await collectCompilerFiles(filesystem, context.cwd, parsed.sources);
|
|
12
|
+
const result = await runtime.execute({ ...parsed, files }, context.signal);
|
|
13
|
+
if (result.exitCode === 0 && result.output) {
|
|
14
|
+
await filesystem.writeFile(parsed.output, result.output);
|
|
15
|
+
}
|
|
16
|
+
return { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode };
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
return fail(`${name}: ${error instanceof Error ? error.message : String(error)}\n`, context.signal?.aborted ? 124 : 1);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
class BrowserCompilerRuntime {
|
|
24
|
+
#egress;
|
|
25
|
+
#worker;
|
|
26
|
+
#nextId = 1;
|
|
27
|
+
#queue = Promise.resolve();
|
|
28
|
+
constructor(egress) {
|
|
29
|
+
this.#egress = egress;
|
|
30
|
+
}
|
|
31
|
+
execute(input, signal) {
|
|
32
|
+
const run = this.#queue.then(() => this.#run(input, signal));
|
|
33
|
+
this.#queue = run.then(() => undefined, () => undefined);
|
|
34
|
+
return run;
|
|
35
|
+
}
|
|
36
|
+
#run(input, signal) {
|
|
37
|
+
const worker = this.#worker ?? this.#createWorker();
|
|
38
|
+
const id = this.#nextId++;
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const cleanup = () => {
|
|
41
|
+
worker.removeEventListener("message", onMessage);
|
|
42
|
+
worker.removeEventListener("error", onError);
|
|
43
|
+
signal?.removeEventListener("abort", onAbort);
|
|
44
|
+
};
|
|
45
|
+
const onMessage = (event) => {
|
|
46
|
+
if (event.data.id !== id)
|
|
47
|
+
return;
|
|
48
|
+
cleanup();
|
|
49
|
+
if (event.data.result)
|
|
50
|
+
resolve(event.data.result);
|
|
51
|
+
else
|
|
52
|
+
reject(new Error(event.data.error ?? "compiler worker failed"));
|
|
53
|
+
};
|
|
54
|
+
const onError = (event) => {
|
|
55
|
+
cleanup();
|
|
56
|
+
this.#discard(worker);
|
|
57
|
+
reject(new Error(event.message || "compiler worker crashed"));
|
|
58
|
+
};
|
|
59
|
+
const onAbort = () => {
|
|
60
|
+
cleanup();
|
|
61
|
+
this.#discard(worker);
|
|
62
|
+
reject(signal?.reason instanceof Error ? signal.reason : new Error("compilation aborted"));
|
|
63
|
+
};
|
|
64
|
+
worker.addEventListener("message", onMessage);
|
|
65
|
+
worker.addEventListener("error", onError);
|
|
66
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
67
|
+
if (signal?.aborted)
|
|
68
|
+
return onAbort();
|
|
69
|
+
worker.postMessage({ type: "compile", id, input });
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
#createWorker() {
|
|
73
|
+
const worker = new Worker(new URL("./compiler.worker.mjs", import.meta.url), { type: "module" });
|
|
74
|
+
worker.postMessage({ type: "initialize", egress: this.#egress });
|
|
75
|
+
this.#worker = worker;
|
|
76
|
+
return worker;
|
|
77
|
+
}
|
|
78
|
+
#discard(worker) {
|
|
79
|
+
worker.terminate();
|
|
80
|
+
if (this.#worker === worker)
|
|
81
|
+
this.#worker = undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function parseArguments(name, args, context) {
|
|
85
|
+
if (args.includes("--help")) {
|
|
86
|
+
return { result: ok(`usage: ${name} [-c] [-O0|-O1|-O2|-O3] [-o OUTPUT] SOURCE...\n`) };
|
|
87
|
+
}
|
|
88
|
+
let output = "a.wasm";
|
|
89
|
+
let outputWasSet = false;
|
|
90
|
+
let optimize = "2";
|
|
91
|
+
let compileOnly = false;
|
|
92
|
+
const sources = [];
|
|
93
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
94
|
+
const arg = args[index];
|
|
95
|
+
if (arg === "-c")
|
|
96
|
+
compileOnly = true;
|
|
97
|
+
else if (/^-O[0-3]$/.test(arg))
|
|
98
|
+
optimize = arg.slice(2);
|
|
99
|
+
else if (arg === "-o") {
|
|
100
|
+
const value = args[++index];
|
|
101
|
+
if (!value)
|
|
102
|
+
return { result: fail(`${name}: -o requires a filename\n`, 1) };
|
|
103
|
+
output = context.fs.resolvePath(context.cwd, value);
|
|
104
|
+
outputWasSet = true;
|
|
105
|
+
}
|
|
106
|
+
else if (arg.startsWith("-")) {
|
|
107
|
+
return { result: fail(`${name}: unsupported browser compiler option '${arg}'\n`, 1) };
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
sources.push(context.fs.resolvePath(context.cwd, arg));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!sources.length)
|
|
114
|
+
return { result: fail(`${name}: no input files\n`, 1) };
|
|
115
|
+
if (compileOnly && sources.length > 1) {
|
|
116
|
+
return { result: fail(`${name}: browser compilation does not support -c with multiple source files; compile one source at a time\n`, 1) };
|
|
117
|
+
}
|
|
118
|
+
if (!output.startsWith("/"))
|
|
119
|
+
output = context.fs.resolvePath(context.cwd, output);
|
|
120
|
+
if (compileOnly && !outputWasSet)
|
|
121
|
+
output = sources[0].replace(/\.[^.]+$/, ".o");
|
|
122
|
+
return { sources, output, optimize, compileOnly };
|
|
123
|
+
}
|
|
124
|
+
async function collectCompilerFiles(filesystem, cwd, sources) {
|
|
125
|
+
const indexed = filesystem;
|
|
126
|
+
const paths = indexed.getAllPaths?.() ?? sources;
|
|
127
|
+
const sourceSet = new Set(sources);
|
|
128
|
+
const relevant = paths.filter((path) => sourceSet.has(path) || /\.(?:h|hh|hpp|hxx|inc)$/.test(path));
|
|
129
|
+
const files = [];
|
|
130
|
+
for (const path of relevant) {
|
|
131
|
+
if (!await filesystem.exists(path))
|
|
132
|
+
continue;
|
|
133
|
+
const stat = await filesystem.stat(path);
|
|
134
|
+
if (!stat.isFile)
|
|
135
|
+
continue;
|
|
136
|
+
const relative = relativeWorkspacePath(path, cwd);
|
|
137
|
+
files.push({ path: relative, contents: await filesystem.readFileBuffer(path) });
|
|
138
|
+
}
|
|
139
|
+
for (const source of sources) {
|
|
140
|
+
if (!files.some((file) => file.path === relativeWorkspacePath(source, cwd))) {
|
|
141
|
+
throw new Error(`input file not found: ${source}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return files;
|
|
145
|
+
}
|
|
146
|
+
function relativeWorkspacePath(path, cwd) {
|
|
147
|
+
const root = cwd.split("/").slice(0, 2).join("/") || "/workspace";
|
|
148
|
+
return path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path.replace(/^\/+/, "");
|
|
149
|
+
}
|
|
150
|
+
function ok(stdout) {
|
|
151
|
+
return { stdout, stderr: "", exitCode: 0 };
|
|
152
|
+
}
|
|
153
|
+
function fail(stderr, exitCode) {
|
|
154
|
+
return { stdout: "", stderr, exitCode };
|
|
155
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const THREAD_ID = /^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/;
|
|
2
|
+
const VAULT_ID = /^[A-Za-z0-9_-]{22,64}$/;
|
|
3
|
+
const VAULT_ID_HEADER = "x-nanocodex-vault-id";
|
|
4
|
+
const VAULT_PLACEHOLDER = /\{\{NANOCODEX_VAULT_(?:USERNAME|PASSWORD|API_KEY|BASIC|CARD_NUMBER|EXPIRY_MONTH|EXPIRY_YEAR|CVV|BILLING_ZIP)\}\}/;
|
|
5
|
+
const PRIVATE_HEADER = /(?:^|[-_])(?:auth(?:orization)?|cookie|credential|password|proxy|secret|token|api[-_]?key)(?:$|[-_])/i;
|
|
6
|
+
const FORBIDDEN_HEADERS = new Set([
|
|
7
|
+
"connection", "host", "origin", "proxy-connection", "referer", "te", "trailer",
|
|
8
|
+
"transfer-encoding", "upgrade", "x-nanocodex-subject", "x-nanocodex-target-url",
|
|
9
|
+
]);
|
|
10
|
+
let installed;
|
|
11
|
+
|
|
12
|
+
/** Installs one thread-owned external fetch route for the current browser Worker isolate. */
|
|
13
|
+
export function installBrowserEgressFetch(options) {
|
|
14
|
+
const origin = new URL(options?.origin).origin;
|
|
15
|
+
if (installed) {
|
|
16
|
+
if (installed.origin !== origin || installed.threadId !== options.threadId) {
|
|
17
|
+
throw new Error("browser egress is already bound to a different thread");
|
|
18
|
+
}
|
|
19
|
+
return installed.fetch;
|
|
20
|
+
}
|
|
21
|
+
const routedFetch = createBrowserRuntimeFetch(options);
|
|
22
|
+
globalThis.fetch = routedFetch;
|
|
23
|
+
installed = Object.freeze({ fetch: routedFetch, origin, threadId: options.threadId });
|
|
24
|
+
return routedFetch;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Creates the browser harness fetch boundary without mutating the caller's global fetch. */
|
|
28
|
+
export function createBrowserRuntimeFetch(options) {
|
|
29
|
+
const origin = new URL(options?.origin).origin;
|
|
30
|
+
const nativeFetch = (options.fetch ?? globalThis.fetch).bind(globalThis);
|
|
31
|
+
const externalFetch = standardFetchFromEgress(createBrowserEgressFetch({
|
|
32
|
+
fetch: nativeFetch,
|
|
33
|
+
headers: options.headers,
|
|
34
|
+
origin,
|
|
35
|
+
threadId: options.threadId,
|
|
36
|
+
}));
|
|
37
|
+
return async (input, init) => {
|
|
38
|
+
const request = input instanceof Request
|
|
39
|
+
? new Request(input, init)
|
|
40
|
+
: new Request(new URL(String(input), origin), init);
|
|
41
|
+
return new URL(request.url).origin === origin
|
|
42
|
+
? nativeFetch(request)
|
|
43
|
+
: externalFetch(request);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Creates the only workload-network capability installed in browser-side runtimes. */
|
|
48
|
+
export function createBrowserEgressFetch(options) {
|
|
49
|
+
if (typeof options?.fetch !== "function") {
|
|
50
|
+
throw new TypeError("browser egress requires a fetch implementation");
|
|
51
|
+
}
|
|
52
|
+
if (typeof options.origin !== "string" || !options.origin) {
|
|
53
|
+
throw new TypeError("browser egress requires the application origin");
|
|
54
|
+
}
|
|
55
|
+
if (!THREAD_ID.test(options.threadId)) {
|
|
56
|
+
throw new TypeError("browser egress requires a valid thread id");
|
|
57
|
+
}
|
|
58
|
+
const endpoint = new URL("/v1/egress", options.origin);
|
|
59
|
+
const responseFetch = async (target, request = {}) => {
|
|
60
|
+
const url = new URL(target);
|
|
61
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password) {
|
|
62
|
+
throw new Error("browser egress supports only credential-free http:// and https:// URLs");
|
|
63
|
+
}
|
|
64
|
+
const headers = new Headers(request.headers);
|
|
65
|
+
const vaultId = headers.get(VAULT_ID_HEADER);
|
|
66
|
+
if (vaultId !== null && !VAULT_ID.test(vaultId)) {
|
|
67
|
+
throw new Error("browser egress requires a valid Vault item id");
|
|
68
|
+
}
|
|
69
|
+
for (const [name, value] of headers) {
|
|
70
|
+
const lower = name.toLowerCase();
|
|
71
|
+
const privateVaultPlaceholder = vaultId !== null
|
|
72
|
+
&& PRIVATE_HEADER.test(name)
|
|
73
|
+
&& safeVaultHeaderValue(lower, value);
|
|
74
|
+
if ((!privateVaultPlaceholder && PRIVATE_HEADER.test(name)) || FORBIDDEN_HEADERS.has(lower)
|
|
75
|
+
|| lower.startsWith("cf-") || lower.startsWith("forwarded")
|
|
76
|
+
|| lower.startsWith("sec-") || lower.startsWith("x-forwarded-")) {
|
|
77
|
+
throw new Error(`browser egress does not accept credential or routing header '${name}'`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const templateBody = request.body instanceof Uint8Array ? new TextDecoder().decode(request.body) : request.body;
|
|
81
|
+
if (vaultId !== null && ![...headers.values()].some((value) => VAULT_PLACEHOLDER.test(value))
|
|
82
|
+
&& (typeof templateBody !== "string" || !VAULT_PLACEHOLDER.test(templateBody))) {
|
|
83
|
+
throw new Error("browser egress Vault requests require a supported placeholder");
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const gatewayHeaders = new Headers(options.headers);
|
|
87
|
+
gatewayHeaders.set("content-type", "application/json");
|
|
88
|
+
const response = await options.fetch(endpoint, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers: gatewayHeaders,
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
thread_id: options.threadId,
|
|
93
|
+
url: url.href,
|
|
94
|
+
method: request.method ?? "GET",
|
|
95
|
+
headers: Object.fromEntries(headers.entries()),
|
|
96
|
+
...encodeRequestBody(vaultId === null ? request.body : templateBody),
|
|
97
|
+
}),
|
|
98
|
+
credentials: "same-origin",
|
|
99
|
+
redirect: "manual",
|
|
100
|
+
signal: request.signal,
|
|
101
|
+
});
|
|
102
|
+
return response;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
105
|
+
throw new Error(`browser egress failed (${detail})`);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
return Object.assign(async (target, request = {}) => {
|
|
109
|
+
const response = await responseFetch(target, request);
|
|
110
|
+
return {
|
|
111
|
+
status: response.status,
|
|
112
|
+
statusText: response.statusText,
|
|
113
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
114
|
+
body: new Uint8Array(await response.arrayBuffer()),
|
|
115
|
+
url: new URL(target).href,
|
|
116
|
+
};
|
|
117
|
+
}, { response: responseFetch });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function encodeRequestBody(body) {
|
|
121
|
+
if (body === undefined) return {};
|
|
122
|
+
if (typeof body === "string") return { body };
|
|
123
|
+
if (!(body instanceof Uint8Array)) throw new TypeError("browser egress body must be text or bytes");
|
|
124
|
+
let encoded = "";
|
|
125
|
+
for (let offset = 0; offset < body.length; offset += 32_768) {
|
|
126
|
+
encoded += String.fromCharCode(...body.subarray(offset, offset + 32_768));
|
|
127
|
+
}
|
|
128
|
+
return { body_base64: btoa(encoded) };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function safeVaultHeaderValue(name, value) {
|
|
132
|
+
if (name === "cookie" || name === "proxy-authorization") return false;
|
|
133
|
+
if (name === "authorization") {
|
|
134
|
+
return value === "Basic {{NANOCODEX_VAULT_BASIC}}"
|
|
135
|
+
|| value === "Bearer {{NANOCODEX_VAULT_API_KEY}}"
|
|
136
|
+
|| value === "Bearer {{NANOCODEX_VAULT_PASSWORD}}";
|
|
137
|
+
}
|
|
138
|
+
return /^\{\{NANOCODEX_VAULT_(?:PASSWORD|API_KEY|BASIC|CARD_NUMBER|EXPIRY_MONTH|EXPIRY_YEAR|CVV|BILLING_ZIP)\}\}$/.test(value);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Adapts the shell result to the standard Fetch API used inside browser Workers. */
|
|
142
|
+
export function standardFetchFromEgress(secureFetch) {
|
|
143
|
+
return async (input, init = {}) => {
|
|
144
|
+
const request = new Request(input, init);
|
|
145
|
+
const method = request.method.toUpperCase();
|
|
146
|
+
const send = secureFetch.response ?? secureFetch;
|
|
147
|
+
const textBody = /^(?:text\/|application\/(?:[a-z.+-]*json|x-www-form-urlencoded)(?:;|$))/.test(request.headers.get("content-type") ?? "");
|
|
148
|
+
const result = await send(request.url, {
|
|
149
|
+
method,
|
|
150
|
+
headers: request.headers,
|
|
151
|
+
...(method === "GET" || method === "HEAD" ? {} : { body: textBody ? await request.text() : new Uint8Array(await request.arrayBuffer()) }),
|
|
152
|
+
signal: request.signal,
|
|
153
|
+
});
|
|
154
|
+
if (result instanceof Response) return result;
|
|
155
|
+
return new Response(result.body, {
|
|
156
|
+
status: result.status,
|
|
157
|
+
statusText: result.statusText,
|
|
158
|
+
headers: result.headers,
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { defineCommand } from "../../../nanocodex-tools/tools/just-bash-browser.mjs";
|
|
2
|
+
export class BrowserPythonRuntime {
|
|
3
|
+
#workspaceRoot;
|
|
4
|
+
#egress;
|
|
5
|
+
#worker;
|
|
6
|
+
#nextId = 1;
|
|
7
|
+
#queue = Promise.resolve();
|
|
8
|
+
constructor(workspaceRoot, egress) {
|
|
9
|
+
this.#workspaceRoot = workspaceRoot;
|
|
10
|
+
this.#egress = egress;
|
|
11
|
+
}
|
|
12
|
+
execute(input, signal) {
|
|
13
|
+
const run = this.#queue.then(() => this.#run(input, signal));
|
|
14
|
+
this.#queue = run.then(() => undefined, () => undefined);
|
|
15
|
+
return run;
|
|
16
|
+
}
|
|
17
|
+
async #run(input, signal) {
|
|
18
|
+
const worker = this.#worker ?? this.#createWorker();
|
|
19
|
+
const id = this.#nextId++;
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const cleanup = () => {
|
|
22
|
+
worker.removeEventListener("message", onMessage);
|
|
23
|
+
worker.removeEventListener("error", onError);
|
|
24
|
+
signal?.removeEventListener("abort", onAbort);
|
|
25
|
+
};
|
|
26
|
+
const onMessage = (event) => {
|
|
27
|
+
if (event.data.id !== id)
|
|
28
|
+
return;
|
|
29
|
+
cleanup();
|
|
30
|
+
// NativeFS can push changes back to OPFS but cannot refresh an existing
|
|
31
|
+
// mount after bash edits. A process-like fresh worker per invocation
|
|
32
|
+
// guarantees each Python command begins from the latest workspace.
|
|
33
|
+
this.#discardWorker(worker);
|
|
34
|
+
if (event.data.result)
|
|
35
|
+
resolve(event.data.result);
|
|
36
|
+
else
|
|
37
|
+
reject(new Error(event.data.error ?? "Python worker failed"));
|
|
38
|
+
};
|
|
39
|
+
const onError = (event) => {
|
|
40
|
+
cleanup();
|
|
41
|
+
this.#discardWorker(worker);
|
|
42
|
+
reject(new Error(event.message || "Python worker crashed"));
|
|
43
|
+
};
|
|
44
|
+
const onAbort = () => {
|
|
45
|
+
cleanup();
|
|
46
|
+
this.#discardWorker(worker);
|
|
47
|
+
reject(signal?.reason instanceof Error ? signal.reason : new Error("Python execution aborted"));
|
|
48
|
+
};
|
|
49
|
+
worker.addEventListener("message", onMessage);
|
|
50
|
+
worker.addEventListener("error", onError);
|
|
51
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
52
|
+
if (signal?.aborted)
|
|
53
|
+
return onAbort();
|
|
54
|
+
worker.postMessage({ type: "execute", id, input });
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
#createWorker() {
|
|
58
|
+
const worker = new Worker(new URL("./python.worker.mjs", import.meta.url), { type: "module" });
|
|
59
|
+
worker.postMessage({
|
|
60
|
+
type: "initialize",
|
|
61
|
+
workspaceRoot: this.#workspaceRoot,
|
|
62
|
+
egress: this.#egress,
|
|
63
|
+
});
|
|
64
|
+
this.#worker = worker;
|
|
65
|
+
return worker;
|
|
66
|
+
}
|
|
67
|
+
#discardWorker(worker) {
|
|
68
|
+
worker.terminate();
|
|
69
|
+
if (this.#worker === worker)
|
|
70
|
+
this.#worker = undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function createPythonCommand(name, runtime, filesystem) {
|
|
74
|
+
const execute = async (args, context) => {
|
|
75
|
+
const parsed = parsePythonArguments(name, args, String(context.stdin));
|
|
76
|
+
if ("result" in parsed)
|
|
77
|
+
return parsed.result;
|
|
78
|
+
if (!runtime) {
|
|
79
|
+
return {
|
|
80
|
+
stdout: "",
|
|
81
|
+
stderr: `${name}: browser Python is unavailable without an OPFS workspace\n`,
|
|
82
|
+
exitCode: 1,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const result = await runtime.execute({
|
|
87
|
+
...parsed,
|
|
88
|
+
cwd: context.cwd,
|
|
89
|
+
stdin: String(context.stdin),
|
|
90
|
+
}, context.signal);
|
|
91
|
+
await filesystem.refreshPaths?.();
|
|
92
|
+
filesystem.recordRepositoryMutation?.();
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return {
|
|
97
|
+
stdout: "",
|
|
98
|
+
stderr: `${name}: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
99
|
+
exitCode: context.signal?.aborted ? 124 : 1,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return defineCommand(name, execute);
|
|
104
|
+
}
|
|
105
|
+
export function parsePythonArguments(name, args, stdin) {
|
|
106
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
107
|
+
return { result: { stdout: `usage: ${name} [-c code | -m module | script | -] [args...]\n`, stderr: "", exitCode: 0 } };
|
|
108
|
+
}
|
|
109
|
+
if (args[0] === "--version" || args[0] === "-V") {
|
|
110
|
+
return { result: { stdout: "Python 3 (Pyodide)\n", stderr: "", exitCode: 0 } };
|
|
111
|
+
}
|
|
112
|
+
if (args[0] === "-c") {
|
|
113
|
+
if (args[1] === undefined)
|
|
114
|
+
return pythonArgumentError(name, "argument expected for -c");
|
|
115
|
+
return { source: args[1], moduleName: null, filename: "<string>", argv: ["-c", ...args.slice(2)] };
|
|
116
|
+
}
|
|
117
|
+
if (args[0] === "-m") {
|
|
118
|
+
if (args[1] === undefined)
|
|
119
|
+
return pythonArgumentError(name, "argument expected for -m");
|
|
120
|
+
return { source: null, moduleName: args[1], filename: args[1], argv: [args[1], ...args.slice(2)] };
|
|
121
|
+
}
|
|
122
|
+
if (!args.length || args[0] === "-") {
|
|
123
|
+
if (!stdin)
|
|
124
|
+
return pythonArgumentError(name, "no input provided (use -c, -m, a script, or stdin)");
|
|
125
|
+
return { source: stdin, moduleName: null, filename: "<stdin>", argv: ["-", ...args.slice(1)] };
|
|
126
|
+
}
|
|
127
|
+
if (args[0].startsWith("-"))
|
|
128
|
+
return pythonArgumentError(name, `unrecognized option '${args[0]}'`);
|
|
129
|
+
return { source: null, moduleName: null, filename: args[0], argv: [args[0], ...args.slice(1)] };
|
|
130
|
+
}
|
|
131
|
+
function pythonArgumentError(name, message) {
|
|
132
|
+
return { result: { stdout: "", stderr: `${name}: ${message}\n`, exitCode: 2 } };
|
|
133
|
+
}
|