@poe-platform/safe-bash 0.1.821 → 0.1.823
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/dist/safe-bash/chunks/{chunk-HNT2MR4W.js → chunk-363QOIDR.js} +2 -1
- package/dist/safe-bash/chunks/chunk-AGHV53VF.js +42 -0
- package/dist/safe-bash/chunks/{chunk-VF3Q2V3E.js → chunk-RAFD5ZAH.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-67QE3JLU.js → chunk-TZRVK3NU.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-IRJS54AA.js → chunk-VWLQDZFF.js} +20 -12
- package/dist/safe-bash/chunks/{chunk-NAETSXBW.js → chunk-ZJAXMB5M.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QX3WKBLI.js → chunk-36FV6BAG.js} +5 -3
- package/dist/safe-bash/command-chunks/{chunk-ZSHXZ3XG.js → chunk-3EAZRKI4.js} +7 -7
- package/dist/safe-bash/command-chunks/chunk-64HIOP7Q.js +993 -0
- package/dist/safe-bash/command-chunks/{chunk-WOT2YXBT.js → chunk-7ZQVMPSB.js} +213 -42
- package/dist/safe-bash/command-chunks/{chunk-GRFJKJFN.js → chunk-AVSINNZ6.js} +233 -3
- package/dist/safe-bash/command-chunks/{chunk-BZLLQWRK.js → chunk-E5CDHXFA.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-RHXV2KG5.js → chunk-EO3RYGUZ.js} +1010 -58
- package/dist/safe-bash/command-chunks/{chunk-MCUDSE4H.js → chunk-EWECMOQ5.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-RTUDDAAY.js → chunk-O3KFOFJM.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-SLD5A7IL.js → chunk-OU5UEUZN.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-RKAL5VFP.js → chunk-PLVFJ6FF.js} +255 -616
- package/dist/safe-bash/command-chunks/{chunk-CJIFJ45R.js → chunk-QBCEAYQT.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-4Q3HP33O.js → chunk-RGKHTSUY.js} +146 -123
- package/dist/safe-bash/command-chunks/{chunk-I7MEH76L.js → chunk-UYNJF5QN.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-IAHYG67O.js → chunk-V5ZBRM5R.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-R4NPYXQX.js → chunk-WDTWJFPK.js} +320 -67
- package/dist/safe-bash/command-chunks/{chunk-GQV5RWMN.js → chunk-ZFXHSFTU.js} +1 -1
- package/dist/safe-bash/command-chunks/{prompt-tool-debug-ERJKK3XZ.js → prompt-tool-debug-3POFNRYP.js} +5 -5
- package/dist/safe-bash/commands/bc/index.browser.js +1 -1
- package/dist/safe-bash/commands/llm/index.browser.js +3 -1
- package/dist/safe-bash/commands/llm/index.js +1 -1
- package/dist/safe-bash/commands/python/executor.browser.js +12 -1
- package/dist/safe-bash/commands/python/executor.js +1 -1
- package/dist/safe-bash/commands/python/index.browser.js +23 -1
- package/dist/safe-bash/commands/python/index.js +1 -1
- package/dist/safe-bash/core.browser.js +2 -2
- package/dist/safe-bash/full-core.browser.js +30 -6
- package/dist/safe-bash/plugins/index.browser.js +3 -3
- package/dist/safe-bash/registry-entry.browser.js +2 -2
- package/dist/safe-bash/search.browser.js +1 -1
- package/dist/safe-bash/shell/runtime.d.ts +2 -2
- package/dist/safe-bash/shell/runtime.js +11 -2
- package/dist/safe-bash/shell/sync-extra-evaluators.js +12 -12
- package/dist/safe-bash/shell-entry.browser.js +2 -2
- package/dist/safe-bash-command-llm/collections.js +24 -65
- package/dist/safe-bash-command-llm/command.js +6 -6
- package/dist/safe-bash-command-llm/fragment-loaders.d.ts +3 -2
- package/dist/safe-bash-command-llm/index.d.ts +3 -2
- package/dist/safe-bash-command-llm/index.js +10 -8
- package/dist/safe-bash-command-llm/loader-provider.d.ts +25 -0
- package/dist/safe-bash-command-llm/openai-sse.js +2 -2
- package/dist/safe-bash-command-llm/openai.js +4 -4
- package/dist/safe-bash-command-llm/providers/index.js +4 -4
- package/dist/safe-bash-command-llm/providers/openai.js +4 -4
- package/dist/safe-bash-command-llm/python-unicode.d.ts +2 -0
- package/dist/safe-bash-command-llm/templates.d.ts +7 -2
- package/dist/safe-bash-command-llm/types.d.ts +7 -1
- package/dist/safe-bash-command-mcp/index.browser.js +3 -0
- package/dist/safe-bash-command-mcp/index.js +3 -0
- package/dist/safe-bash-command-patch/index.js +2 -2
- package/dist/safe-bash-command-patch/patch-publication.js +1 -1
- package/dist/safe-bash-command-patch/patch.js +2 -2
- package/dist/safe-bash-command-python/build-backend.d.ts +51 -0
- package/dist/safe-bash-command-python/build-dependencies.d.ts +12 -0
- package/dist/safe-bash-command-python/build-environment.d.ts +3 -0
- package/dist/safe-bash-command-python/build-wheel.d.ts +8 -0
- package/dist/safe-bash-command-python/executor.d.ts +12 -2
- package/dist/safe-bash-command-python/executor.js +26 -4
- package/dist/safe-bash-command-python/index.js +26 -4
- package/dist/safe-bash-command-python/jspi.js +2 -2
- package/dist/safe-bash-command-python/llm-assets-node.js +1 -1
- package/dist/safe-bash-command-python/llm-fragment-loader.d.ts +6 -0
- package/dist/safe-bash-command-python/llm-functions-loader.d.ts +5 -1
- package/dist/safe-bash-command-python/llm-loader-discovery.d.ts +13 -0
- package/dist/safe-bash-command-python/llm-package-manager.d.ts +7 -0
- package/dist/safe-bash-command-python/llm-template-loader.d.ts +6 -0
- package/dist/safe-bash-command-python/manifest.d.ts +13 -0
- package/dist/safe-bash-command-python/provisioning.d.ts +33 -5
- package/dist/safe-bash-command-python/provisioning.js +1 -1
- package/dist/safe-bash-command-python/source-environment.d.ts +9 -0
- package/dist/safe-bash-command-python/source-snapshot.d.ts +8 -0
- package/dist/safe-bash-command-python/worker.js +3 -185
- package/dist/safe-bash-csv-engine/index.js +1 -1
- package/dist/safe-bash-csv-engine/python-iso2022.d.ts +21 -0
- package/dist/safe-bash-csv-engine/python-utf7.d.ts +18 -0
- package/dist/safe-bash-csv-engine/text-decoder.d.ts +2 -0
- package/dist/safe-bash-csv-engine/text-decoder.js +7 -3
- package/dist/safe-bash-zip-engine/index.js +1 -1
- package/dist/safe-bash-zip-engine/zip/repair.js +1 -1
- package/dist/safe-bash-zip-engine/zip/sfx.js +1 -1
- package/dist/safe-bash-zip-engine/zip-format.d.ts +3 -1
- package/dist/safe-bash-zip-engine/zip-format.js +1 -1
- package/dist/safe-playwright-cloudflare/shell-browser-resource.d.ts +1 -1
- package/dist/safe-playwright-cloudflare/shell-browser-resource.js +35 -20
- package/package.json +3 -3
- package/dist/safe-bash/chunks/chunk-PSD2RSOS.js +0 -31
- package/dist/safe-bash/command-chunks/chunk-5EFNQ6FY.js +0 -458
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createPythonJspiExecutor
|
|
3
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
3
|
+
} from "../safe-bash/command-chunks/chunk-RGKHTSUY.js";
|
|
4
4
|
import "../safe-bash/command-chunks/chunk-FXWKMNX2.js";
|
|
5
|
-
import "../safe-bash/command-chunks/chunk-
|
|
5
|
+
import "../safe-bash/command-chunks/chunk-64HIOP7Q.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-P56KGNW7.js";
|
|
7
7
|
import "../safe-bash/command-chunks/chunk-NK3FRG5O.js";
|
|
8
8
|
import "../safe-bash/command-chunks/chunk-XNJGNDFW.js";
|
|
@@ -91,7 +91,7 @@ export async function readPythonLlmAssets(directory) {
|
|
|
91
91
|
maxTotalBytes: distribution.expandedBytes, maxBufferedFileBytes: distribution.expandedBytes * 3,
|
|
92
92
|
maxMembers: 10000, maxPathBytes: 1024, maxDepth: 32, maxPaxBytes: 65536,
|
|
93
93
|
maxTextBytes: distribution.expandedBytes };
|
|
94
|
-
const archive = await readZipArchive(bytes, limits, signal);
|
|
94
|
+
const archive = await readZipArchive(bytes, limits, signal, { allowUnreferencedData: true });
|
|
95
95
|
for (const native of distribution.nativeModules) {
|
|
96
96
|
const entry = archive.entries.find(entry => entry.name === native.path);
|
|
97
97
|
if (!entry || entry.directory || entry.symlink || entry.size !== native.bytes)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type LlmFragmentLoader } from "../safe-bash-command-llm/index.js";
|
|
2
|
+
import type { PythonLlmToolLoaderOptions } from './llm-functions-loader.js';
|
|
3
|
+
/** Each explicitly authorized native loader invocation owns its interpreter.
|
|
4
|
+
* Results are staged one at a time in caller storage and borrowed until next(). */
|
|
5
|
+
export declare function createPythonLlmFragmentLoader(options: PythonLlmToolLoaderOptions, prefix: string): LlmFragmentLoader;
|
|
6
|
+
export declare const pythonLlmFragmentProgram: string;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { type LlmToolLoader } from "../safe-bash-command-llm/index.js";
|
|
2
2
|
import { type PythonCommandsOptions } from './executor.js';
|
|
3
|
+
export interface PythonLlmToolLoaderOptions extends PythonCommandsOptions {
|
|
4
|
+
/** Explicit installed distributions whose tooling hooks the host authorizes. */
|
|
5
|
+
readonly plugins?: readonly string[];
|
|
6
|
+
}
|
|
3
7
|
/** Reuse one configured interpreter per load, retaining only caller-backed tool
|
|
4
8
|
* payloads. The session must outlive consumption of its borrowed results. */
|
|
5
|
-
export declare function createPythonLlmToolLoader(options:
|
|
9
|
+
export declare function createPythonLlmToolLoader(options: PythonLlmToolLoaderOptions): LlmToolLoader;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LlmFragmentLoader, LlmLoaderDiscoveryContext, LlmLoaderProvider, LlmTemplateLoader } from "../safe-bash-command-llm/index.js";
|
|
2
|
+
import type { PythonLlmToolLoaderOptions } from './llm-functions-loader.js';
|
|
3
|
+
export interface PythonLlmDiscoveredLoaders {
|
|
4
|
+
readonly fragmentLoaders: ReadonlyMap<string, LlmFragmentLoader>;
|
|
5
|
+
readonly templateLoaders: ReadonlyMap<string, LlmTemplateLoader>;
|
|
6
|
+
}
|
|
7
|
+
export type PythonLlmLoaderDiscoveryContext = LlmLoaderDiscoveryContext;
|
|
8
|
+
/** Discover at listing time and resolve prefixes without an extra native hook pass. */
|
|
9
|
+
export declare function createPythonLlmLoaderProvider(options: PythonLlmToolLoaderOptions): LlmLoaderProvider;
|
|
10
|
+
/** Discover native prefixes only from explicitly authorized installed plugins.
|
|
11
|
+
* Invoke again after changing the environment; no ambient registry is retained. */
|
|
12
|
+
export declare function createPythonLlmLoaderDiscovery(options: PythonLlmToolLoaderOptions): (context: PythonLlmLoaderDiscoveryContext) => Promise<PythonLlmDiscoveredLoaders>;
|
|
13
|
+
export declare const pythonLlmLoaderDiscoveryProgram: string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LlmPackageManager } from "../safe-bash-command-llm/index.js";
|
|
2
|
+
import { type PythonCommandsOptions, type PythonPackageEnvironment } from './executor.js';
|
|
3
|
+
/** Parse with the pinned LLM CLI, then retire it before mutating the shared
|
|
4
|
+
* caller-owned package environment in a separate interpreter. */
|
|
5
|
+
export declare function createPythonLlmPackageManager(options: PythonCommandsOptions & {
|
|
6
|
+
environment: PythonPackageEnvironment;
|
|
7
|
+
}): LlmPackageManager;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LlmTemplateLoader } from "../safe-bash-command-llm/index.js";
|
|
2
|
+
import type { PythonLlmToolLoaderOptions } from './llm-functions-loader.js';
|
|
3
|
+
/** Execute an explicitly authorized native loader within the caller's remaining
|
|
4
|
+
* template materialization allowance. Native JSON travels in bounded windows. */
|
|
5
|
+
export declare function createPythonLlmTemplateLoader(options: PythonLlmToolLoaderOptions, prefix: string): LlmTemplateLoader;
|
|
6
|
+
export declare const pythonLlmTemplateProgram: string;
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/** Native distribution metadata and pip-compatible removal listings. */
|
|
2
|
+
export type PythonPackageRecord = readonly [name: string, metadata: string, origin: string, remove: readonly string[], skip: readonly string[]];
|
|
3
|
+
/** Exact installed requirements; newer snapshots can uninstall without wheels. */
|
|
4
|
+
export type PythonInstalledSnapshot = {
|
|
5
|
+
readonly version: 1;
|
|
6
|
+
readonly installed: readonly string[];
|
|
7
|
+
} | {
|
|
8
|
+
readonly version: 2;
|
|
9
|
+
readonly installed: readonly string[];
|
|
10
|
+
readonly records: readonly PythonPackageRecord[];
|
|
11
|
+
};
|
|
12
|
+
/** Accept legacy requirements and validated versioned installed snapshots. */
|
|
13
|
+
export declare function readPackageManifest(value: unknown): readonly string[] | undefined;
|
|
1
14
|
export interface PythonPackageManifest {
|
|
2
15
|
readonly revision: string;
|
|
3
16
|
readonly bytes: Uint8Array;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FileSystem } from "../safe-bash-contracts/filesystem.js";
|
|
2
2
|
import type { HttpTransport, NetworkAuthorizer } from "../safe-bash-network-engine/types.js";
|
|
3
|
-
import { type PythonPackageManifestStore } from './manifest.js';
|
|
3
|
+
import { type PythonPackageManifestStore, type PythonPackageRecord } from './manifest.js';
|
|
4
4
|
import { type PythonPackageCache } from './cache.js';
|
|
5
5
|
export type { PythonPackageCache } from './cache.js';
|
|
6
6
|
export interface PythonPackageProgress {
|
|
@@ -9,7 +9,19 @@ export interface PythonPackageProgress {
|
|
|
9
9
|
readonly bytes?: number;
|
|
10
10
|
readonly totalBytes?: number;
|
|
11
11
|
}
|
|
12
|
-
export interface
|
|
12
|
+
export interface PythonPackageInstallOptions {
|
|
13
|
+
/** Include prerelease and development candidates during dependency resolution. */
|
|
14
|
+
readonly pre?: boolean;
|
|
15
|
+
/** Select the newest eligible requested roots, retaining satisfying dependencies. */
|
|
16
|
+
readonly upgrade?: boolean;
|
|
17
|
+
/** Reinstall the requested dependency graph even when installed versions satisfy it. */
|
|
18
|
+
readonly forceReinstall?: boolean;
|
|
19
|
+
/** Bypass artifact cache reads and writes; environment snapshots still persist. */
|
|
20
|
+
readonly noCache?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface PythonPackageOptions extends PythonPackageInstallOptions {
|
|
23
|
+
/** Resolve requested sources before opening an install session; restored pins are unchanged. */
|
|
24
|
+
readonly prepareRequirements?: (requirements: readonly string[], context: PythonPackagePrepareContext) => Promise<readonly string[]>;
|
|
13
25
|
readonly requirements?: readonly string[];
|
|
14
26
|
readonly requirementFiles?: readonly string[];
|
|
15
27
|
readonly profile?: 'documents';
|
|
@@ -29,9 +41,24 @@ export interface PythonPackageOptions {
|
|
|
29
41
|
readonly maxCacheBytes?: number;
|
|
30
42
|
readonly onProgress?: (event: PythonPackageProgress) => void;
|
|
31
43
|
}
|
|
32
|
-
export interface PythonPackageStart {
|
|
44
|
+
export interface PythonPackageStart extends Omit<PythonPackageInstallOptions, 'noCache'> {
|
|
33
45
|
readonly session: string;
|
|
46
|
+
/** Load installer tooling even when no application requirements are installed. */
|
|
47
|
+
readonly bootstrap?: boolean;
|
|
48
|
+
/** Combined requirements for compatibility with custom executors. */
|
|
34
49
|
readonly requirements: readonly string[];
|
|
50
|
+
/** Legacy requirements need one dependency-resolution pass before migration. */
|
|
51
|
+
readonly legacy?: boolean;
|
|
52
|
+
/** Installed metadata used only by uninstall; application startup still restores code. */
|
|
53
|
+
readonly records?: readonly PythonPackageRecord[] | undefined;
|
|
54
|
+
/** Prior installation; only legacy manifests resolve dependencies during restore. */
|
|
55
|
+
readonly restore?: readonly string[];
|
|
56
|
+
/** New or host-configured requirements whose dependency closure is resolved. */
|
|
57
|
+
readonly requested?: readonly string[];
|
|
58
|
+
readonly uninstall?: {
|
|
59
|
+
readonly packages: readonly string[];
|
|
60
|
+
readonly yes: boolean;
|
|
61
|
+
};
|
|
35
62
|
readonly offline: boolean;
|
|
36
63
|
}
|
|
37
64
|
export interface PythonPackageContext {
|
|
@@ -39,7 +66,8 @@ export interface PythonPackageContext {
|
|
|
39
66
|
readonly cwd: string;
|
|
40
67
|
readonly signal: AbortSignal;
|
|
41
68
|
}
|
|
42
|
-
export interface PythonPackagePrepareContext extends PythonPackageContext {
|
|
69
|
+
export interface PythonPackagePrepareContext extends PythonPackageContext, PythonPackageInstallOptions, Partial<Pick<import("../safe-bash-contracts/index.js").CommandContext, 'env' | 'stdout' | 'stderr' | 'registerCleanup'>> {
|
|
70
|
+
readonly uninstall?: PythonPackageStart['uninstall'];
|
|
43
71
|
readonly requirements?: readonly string[];
|
|
44
72
|
readonly requirementFiles?: readonly string[];
|
|
45
73
|
readonly offline?: boolean;
|
|
@@ -47,7 +75,7 @@ export interface PythonPackagePrepareContext extends PythonPackageContext {
|
|
|
47
75
|
export interface PythonPackageEnvironment {
|
|
48
76
|
prepare(context: PythonPackagePrepareContext): Promise<PythonPackageStart>;
|
|
49
77
|
dispatch(operation: string, args: unknown[], context: PythonPackageContext): Promise<unknown>;
|
|
50
|
-
finish(start: PythonPackageStart): void
|
|
78
|
+
finish(start: PythonPackageStart): void | Promise<void>;
|
|
51
79
|
dispose(): Promise<void>;
|
|
52
80
|
}
|
|
53
81
|
export declare const pythonDocumentPackages: readonly string[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createPythonPackageEnvironment,
|
|
3
3
|
pythonDocumentPackages
|
|
4
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
4
|
+
} from "../safe-bash/command-chunks/chunk-WDTWJFPK.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
|
|
6
6
|
export {
|
|
7
7
|
createPythonPackageEnvironment,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type PythonPackageOptions } from './provisioning.js';
|
|
2
|
+
import type { PythonCommandsOptions } from './executor.js';
|
|
3
|
+
export interface PythonSourceBuildOptions {
|
|
4
|
+
/** Existing caller-owned directory for build staging and durable wheels. */
|
|
5
|
+
readonly directory: string;
|
|
6
|
+
readonly python: Omit<PythonCommandsOptions, 'packages' | 'requirements' | 'packageProfile' | 'provisioning' | 'environment'>;
|
|
7
|
+
}
|
|
8
|
+
/** Package environment that builds local PEP 517 projects before normal installation. */
|
|
9
|
+
export declare function createPythonSourcePackageEnvironment(options: PythonPackageOptions, build: PythonSourceBuildOptions): import("./provisioning.js").PythonPackageEnvironment;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CommandContext } from "../safe-bash-contracts/index.js";
|
|
2
|
+
export interface PythonSourceSnapshot {
|
|
3
|
+
readonly path: string;
|
|
4
|
+
/** Retires only the owned tree; substituted identities are never removed. */
|
|
5
|
+
dispose(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
/** Copy a build tree into caller storage using pip 21.2.4's directory policy. */
|
|
8
|
+
export declare function createPythonSourceSnapshot(source: string, directory: string, context: CommandContext): Promise<PythonSourceSnapshot>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
installPythonPackages,
|
|
2
3
|
parsePythonInvocation,
|
|
3
4
|
pythonDirectoryEntries,
|
|
4
5
|
pythonExecution,
|
|
@@ -7,7 +8,7 @@ import {
|
|
|
7
8
|
pythonRuntimeRelocation,
|
|
8
9
|
pythonStatProjection,
|
|
9
10
|
pythonTreeCleanup
|
|
10
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
11
|
+
} from "../safe-bash/command-chunks/chunk-64HIOP7Q.js";
|
|
11
12
|
import {
|
|
12
13
|
PythonFailure
|
|
13
14
|
} from "../safe-bash/command-chunks/chunk-TO6UNFEF.js";
|
|
@@ -15,189 +16,6 @@ import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
|
|
|
15
16
|
|
|
16
17
|
// packages/safe-bash-command-python/src/worker.ts
|
|
17
18
|
import { mountPythonFileSystem } from "@poe-platform/safe-fs/core";
|
|
18
|
-
|
|
19
|
-
// packages/safe-bash-command-python/src/provisioning-runtime.ts
|
|
20
|
-
async function installPythonPackages(supplied, start, request, maxTransferBytes) {
|
|
21
|
-
if (start.requirements.length === 0) return;
|
|
22
|
-
const runtime = supplied;
|
|
23
|
-
if (runtime.version !== "314.0.6" || !runtime._api?.packageManager || !runtime._api.lockfile_packages || typeof runtime.loadPackage !== "function" || typeof runtime.runPythonAsync !== "function") throw new Error("Python package installer ABI requires Pyodide 314.0.6");
|
|
24
|
-
let transportFailure;
|
|
25
|
-
const fetch = (url, expected) => {
|
|
26
|
-
try {
|
|
27
|
-
const opened = request("package-open", start.session, url, expected);
|
|
28
|
-
try {
|
|
29
|
-
const bytes = new Uint8Array(opened.size);
|
|
30
|
-
for (let offset = 0; offset < bytes.length; ) {
|
|
31
|
-
const chunk = request("package-read", start.session, opened.key, offset, Math.min(maxTransferBytes, 65536, bytes.length - offset));
|
|
32
|
-
if (!Array.isArray(chunk) || chunk.length === 0 || offset + chunk.length > bytes.length) throw new Error("Invalid Python package chunk");
|
|
33
|
-
bytes.set(chunk, offset);
|
|
34
|
-
offset += chunk.length;
|
|
35
|
-
}
|
|
36
|
-
return { bytes, headers: opened.headers };
|
|
37
|
-
} finally {
|
|
38
|
-
request("package-close", start.session, opened.key);
|
|
39
|
-
}
|
|
40
|
-
} catch (error) {
|
|
41
|
-
transportFailure ??= { error };
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
runtime._api.packageManager.downloadPackage = async (metadata) => {
|
|
46
|
-
if (metadata.channel === runtime._api.packageManager.defaultChannel) {
|
|
47
|
-
const pkg = runtime._api.lockfile_packages[metadata.normalizedName];
|
|
48
|
-
if (!pkg) throw new Error(`Missing matching Pyodide package: ${metadata.normalizedName}`);
|
|
49
|
-
return fetch(new URL(pkg.file_name, "https://cdn.jsdelivr.net/pyodide/v314.0.6/full/").href, pkg.sha256).bytes;
|
|
50
|
-
}
|
|
51
|
-
return fetch(metadata.channel).bytes;
|
|
52
|
-
};
|
|
53
|
-
const loadPackages = async (names) => {
|
|
54
|
-
const errors = [];
|
|
55
|
-
await runtime.loadPackage(names, { messageCallback() {
|
|
56
|
-
}, errorCallback(message) {
|
|
57
|
-
errors.push(message);
|
|
58
|
-
} });
|
|
59
|
-
if (errors.length) throw new Error(errors.join("\n"));
|
|
60
|
-
};
|
|
61
|
-
const installedGlobals = [];
|
|
62
|
-
try {
|
|
63
|
-
await loadPackages(["micropip"]);
|
|
64
|
-
runtime.globals.set("_safe_package_native", loadPackages);
|
|
65
|
-
installedGlobals.push("_safe_package_native");
|
|
66
|
-
runtime.globals.set("_safe_package_bytes", (url, hash) => fetch(url, hash).bytes);
|
|
67
|
-
installedGlobals.push("_safe_package_bytes");
|
|
68
|
-
runtime.globals.set("_safe_package_metadata", (url) => {
|
|
69
|
-
const result = fetch(url);
|
|
70
|
-
return JSON.stringify({ text: new TextDecoder().decode(result.bytes), headers: Object.fromEntries(result.headers.map(([name, value]) => [name.toLowerCase(), value])) });
|
|
71
|
-
});
|
|
72
|
-
installedGlobals.push("_safe_package_metadata");
|
|
73
|
-
runtime.globals.set("_safe_package_requirements_json", JSON.stringify(start.requirements));
|
|
74
|
-
installedGlobals.push("_safe_package_requirements_json");
|
|
75
|
-
await runtime.runPythonAsync(`
|
|
76
|
-
import json as _safe_json
|
|
77
|
-
import micropip as _safe_micropip
|
|
78
|
-
from micropip._compat import compatibility_layer as _safe_compat
|
|
79
|
-
from micropip.package_manager import PackageManager as _SafePackageManager
|
|
80
|
-
from micropip.wheelinfo import WheelInfo as _SafeWheelInfo
|
|
81
|
-
from micropip._utils import check_compatible as _safe_check_compatible
|
|
82
|
-
from micropip._vendored.packaging.src.packaging.requirements import Requirement as _SafeRequirement, InvalidRequirement as _SafeInvalidRequirement
|
|
83
|
-
from micropip._vendored.packaging.src.packaging.utils import canonicalize_name as _safe_name
|
|
84
|
-
|
|
85
|
-
class _SafePackageCompatibility(_safe_compat):
|
|
86
|
-
@staticmethod
|
|
87
|
-
async def loadPackage(names):
|
|
88
|
-
return await _safe_package_native(names)
|
|
89
|
-
@staticmethod
|
|
90
|
-
async def fetch_bytes(url, kwargs):
|
|
91
|
-
return _safe_package_bytes(url).to_bytes()
|
|
92
|
-
@staticmethod
|
|
93
|
-
async def fetch_string_and_headers(url, kwargs):
|
|
94
|
-
value = _safe_json.loads(_safe_package_metadata(url))
|
|
95
|
-
return value['text'], value['headers']
|
|
96
|
-
|
|
97
|
-
# Require index/URL digests before publishing wheel bytes to the host cache.
|
|
98
|
-
# Local wheels are host-trusted inputs and receive a content digest on first read.
|
|
99
|
-
async def _safe_wheel_fetch(self, url, kwargs, compat):
|
|
100
|
-
expected = self.sha256 if url == self.url else None
|
|
101
|
-
if url == self.metadata_url and isinstance(self.core_metadata, dict):
|
|
102
|
-
expected = self.core_metadata.get('sha256')
|
|
103
|
-
return _safe_package_bytes(url, expected).to_bytes()
|
|
104
|
-
_SafeWheelInfo._fetch_bytes = _safe_wheel_fetch
|
|
105
|
-
_safe_manager = _SafePackageManager(_SafePackageCompatibility)
|
|
106
|
-
_safe_requirements = _safe_json.loads(_safe_package_requirements_json)
|
|
107
|
-
# A persisted base wheel may be visited before a newly requested extra. Micropip
|
|
108
|
-
# skips already locked names, so every occurrence must carry the requested extras.
|
|
109
|
-
_safe_roots = []
|
|
110
|
-
_safe_extras = {}
|
|
111
|
-
for _safe_source in _safe_requirements:
|
|
112
|
-
try:
|
|
113
|
-
_safe_root = _SafeRequirement(_safe_source)
|
|
114
|
-
if _safe_root.name.endswith('.whl'):
|
|
115
|
-
raise _SafeInvalidRequirement(_safe_source)
|
|
116
|
-
except _SafeInvalidRequirement:
|
|
117
|
-
_safe_wheel = _SafeWheelInfo.from_url(_safe_source)
|
|
118
|
-
_safe_root = _SafeRequirement(_safe_wheel.name + ' @ ' + _safe_source)
|
|
119
|
-
_safe_roots.append(_safe_root)
|
|
120
|
-
if not _safe_root.marker or _safe_root.marker.evaluate({'extra': ''}):
|
|
121
|
-
# Named requirements may be skipped when already locked. Validate direct
|
|
122
|
-
# wheels even then, rather than letting an incompatible URL report success.
|
|
123
|
-
if _safe_root.url:
|
|
124
|
-
_safe_direct_wheel = _SafeWheelInfo.from_url(_safe_root.url)
|
|
125
|
-
_safe_check_compatible(_safe_direct_wheel.filename)
|
|
126
|
-
# Validate the actual archive and host-checked digest even if micropip's
|
|
127
|
-
# satisfied-name fast path will skip installing this explicit operand.
|
|
128
|
-
await _safe_direct_wheel.download({}, _SafePackageCompatibility)
|
|
129
|
-
_safe_extras.setdefault(_safe_name(_safe_root.name), set()).update(_safe_root.extras)
|
|
130
|
-
for _safe_root in _safe_roots:
|
|
131
|
-
_safe_root.extras.update(_safe_extras.get(_safe_name(_safe_root.name), set()))
|
|
132
|
-
await _safe_manager.install([str(root) for root in _safe_roots], deps=True)
|
|
133
|
-
# Resolve selected extras from distribution metadata, including extras added to
|
|
134
|
-
# an already satisfied transitive dependency. Micropip skips those names early.
|
|
135
|
-
# Keep its installer and conflict policy; do not infer dependencies from imports.
|
|
136
|
-
import importlib.metadata as _safe_metadata
|
|
137
|
-
_safe_previous_pending = None
|
|
138
|
-
while True:
|
|
139
|
-
_safe_distributions = [d for d in _safe_metadata.distributions() if d.metadata['Name']]
|
|
140
|
-
_safe_versions = {_safe_name(d.metadata['Name']): d.version for d in _safe_distributions}
|
|
141
|
-
while True:
|
|
142
|
-
_safe_changed = False
|
|
143
|
-
_safe_dependencies = []
|
|
144
|
-
for _safe_dist in _safe_distributions:
|
|
145
|
-
_safe_contexts = {''} | _safe_extras.get(_safe_name(_safe_dist.metadata['Name']), set())
|
|
146
|
-
for _safe_dep in _safe_dist.requires or []:
|
|
147
|
-
_safe_requirement = _SafeRequirement(_safe_dep)
|
|
148
|
-
if _safe_requirement.marker and not any(_safe_requirement.marker.evaluate({'extra': extra}) for extra in _safe_contexts):
|
|
149
|
-
continue
|
|
150
|
-
# The marker belongs to the requesting distribution's extra context, already
|
|
151
|
-
# evaluated above; a separate installer transaction must not reinterpret it.
|
|
152
|
-
_safe_requirement.marker = None
|
|
153
|
-
_safe_dependencies.append(_safe_requirement)
|
|
154
|
-
_safe_selected = _safe_extras.setdefault(_safe_name(_safe_requirement.name), set())
|
|
155
|
-
if not _safe_requirement.extras.issubset(_safe_selected):
|
|
156
|
-
_safe_selected.update(_safe_requirement.extras)
|
|
157
|
-
_safe_changed = True
|
|
158
|
-
if not _safe_changed:
|
|
159
|
-
break
|
|
160
|
-
_safe_pending = set()
|
|
161
|
-
for _safe_requirement in _safe_dependencies:
|
|
162
|
-
_safe_version = _safe_versions.get(_safe_name(_safe_requirement.name))
|
|
163
|
-
if _safe_version is None:
|
|
164
|
-
_safe_pending.add(str(_safe_requirement))
|
|
165
|
-
elif not _safe_requirement.specifier.contains(_safe_version, prereleases=True):
|
|
166
|
-
raise ValueError('Python package dependency conflict: ' + str(_safe_requirement))
|
|
167
|
-
if not _safe_pending:
|
|
168
|
-
break
|
|
169
|
-
if _safe_pending == _safe_previous_pending:
|
|
170
|
-
raise ValueError('Python package dependencies remain missing: ' + ', '.join(sorted(_safe_pending)))
|
|
171
|
-
_safe_previous_pending = _safe_pending
|
|
172
|
-
await _safe_manager.install(sorted(_safe_pending), deps=True)
|
|
173
|
-
# Explicit roots also constrain the result: direct URLs can bypass micropip's
|
|
174
|
-
# already-installed version check, including when another root pins that name.
|
|
175
|
-
for _safe_root in _safe_roots:
|
|
176
|
-
if _safe_root.marker and not _safe_root.marker.evaluate({'extra': ''}):
|
|
177
|
-
continue
|
|
178
|
-
_safe_version = _safe_versions.get(_safe_name(_safe_root.name))
|
|
179
|
-
if _safe_version is None or not _safe_root.specifier.contains(_safe_version, prereleases=True):
|
|
180
|
-
raise ValueError('Python package version conflict: ' + str(_safe_root))
|
|
181
|
-
if _safe_root.url:
|
|
182
|
-
_safe_wheel = _SafeWheelInfo.from_url(_safe_root.url)
|
|
183
|
-
_safe_wheel_pin = _SafeRequirement(_safe_wheel.name + '==' + str(_safe_wheel.version))
|
|
184
|
-
if _safe_name(_safe_wheel.name) != _safe_name(_safe_root.name) or not _safe_wheel_pin.specifier.contains(_safe_version, prereleases=True):
|
|
185
|
-
raise ValueError('Python package wheel version conflict: ' + str(_safe_root))
|
|
186
|
-
_safe_installed_json = _safe_json.dumps([name + '==' + version for name, version in sorted(_safe_versions.items())])
|
|
187
|
-
`);
|
|
188
|
-
const pinned = JSON.parse(runtime.runPython("_safe_installed_json"));
|
|
189
|
-
request("package-commit", start.session, pinned);
|
|
190
|
-
} catch (error) {
|
|
191
|
-
throw transportFailure ? transportFailure.error : error;
|
|
192
|
-
} finally {
|
|
193
|
-
runtime._api.packageManager.downloadPackage = async () => {
|
|
194
|
-
throw new Error("Python package transport is only available during installation");
|
|
195
|
-
};
|
|
196
|
-
for (const name of installedGlobals) runtime.globals.delete(name);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// packages/safe-bash-command-python/src/worker.ts
|
|
201
19
|
function createPythonWorkerRequest(shared, postMessage, error) {
|
|
202
20
|
let control;
|
|
203
21
|
let payload;
|
|
@@ -329,7 +147,7 @@ async function runPythonWorker(options) {
|
|
|
329
147
|
if ("loadPackage" in publicRuntime) publicRuntime.loadPackage = unavailablePackage;
|
|
330
148
|
if (publicRuntime._api?.packageManager) publicRuntime._api.packageManager.downloadPackage = unavailablePackage;
|
|
331
149
|
if (start.installOnly) {
|
|
332
|
-
startupWrite("stdout", "Successfully installed requested Python packages");
|
|
150
|
+
if (!start.packages?.uninstall) startupWrite("stdout", "Successfully installed requested Python packages");
|
|
333
151
|
postMessage({ type: "exit", exitCode: 0 });
|
|
334
152
|
return;
|
|
335
153
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PythonTextDecoder
|
|
3
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
3
|
+
} from "../safe-bash/command-chunks/chunk-AVSINNZ6.js";
|
|
4
4
|
import "../safe-bash/command-chunks/chunk-OLXMWQJ5.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-OOYVZAWL.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-ZERCTWUI.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const pythonIso2022Charsets: Readonly<Record<string, readonly number[]>>;
|
|
2
|
+
export declare class PythonIso2022PendingError extends Error {
|
|
3
|
+
constructor();
|
|
4
|
+
}
|
|
5
|
+
/** Bounded ISO-2022 designation and shift state, with existing Python mappings. */
|
|
6
|
+
export declare class PythonIso2022Decoder {
|
|
7
|
+
private readonly encoding;
|
|
8
|
+
private readonly groups;
|
|
9
|
+
private shifted;
|
|
10
|
+
private through;
|
|
11
|
+
private pending;
|
|
12
|
+
private readonly maps;
|
|
13
|
+
constructor(encoding: string);
|
|
14
|
+
private invalid;
|
|
15
|
+
private character;
|
|
16
|
+
private secondary;
|
|
17
|
+
private escape;
|
|
18
|
+
decode(bytes?: Uint8Array, options?: {
|
|
19
|
+
stream?: boolean;
|
|
20
|
+
}): string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class PythonUtf7EncodingError extends TypeError {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
/** File-oriented UTF-7 decoding. Completed units can be staged before the shift
|
|
5
|
+
* ends; callers must discard that staging if decoding or final UTF8 admission fails.
|
|
6
|
+
* Unlike Python's incremental codec, this never retains an entire shifted segment. */
|
|
7
|
+
export declare class PythonUtf7FileDecoder {
|
|
8
|
+
private shifted;
|
|
9
|
+
private haveSextet;
|
|
10
|
+
private bits;
|
|
11
|
+
private value;
|
|
12
|
+
private high;
|
|
13
|
+
private loneSurrogate;
|
|
14
|
+
private unit;
|
|
15
|
+
decode(bytes?: Uint8Array, options?: {
|
|
16
|
+
stream?: boolean;
|
|
17
|
+
}): string;
|
|
18
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
PythonIso2022PendingError,
|
|
3
|
+
PythonTextDecoder,
|
|
4
|
+
PythonUtf7EncodingError
|
|
5
|
+
} from "../safe-bash/command-chunks/chunk-AVSINNZ6.js";
|
|
4
6
|
import "../safe-bash/command-chunks/chunk-OLXMWQJ5.js";
|
|
5
7
|
import {
|
|
6
8
|
PythonTextDecodeError
|
|
@@ -10,6 +12,8 @@ import "../safe-bash/command-chunks/chunk-WIUEM7HP.js";
|
|
|
10
12
|
import "../safe-bash/command-chunks/chunk-HNEWGADJ.js";
|
|
11
13
|
import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
|
|
12
14
|
export {
|
|
15
|
+
PythonIso2022PendingError,
|
|
13
16
|
PythonTextDecodeError,
|
|
14
|
-
PythonTextDecoder
|
|
17
|
+
PythonTextDecoder,
|
|
18
|
+
PythonUtf7EncodingError
|
|
15
19
|
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
streamZipArchive,
|
|
10
10
|
updateZipExtras,
|
|
11
11
|
writeZipArchive
|
|
12
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
12
|
+
} from "../safe-bash/command-chunks/chunk-3EAZRKI4.js";
|
|
13
13
|
import "../safe-bash/command-chunks/chunk-FVQFB7OD.js";
|
|
14
14
|
import "../safe-bash/command-chunks/chunk-3I3PD6VU.js";
|
|
15
15
|
import "../safe-bash/command-chunks/chunk-CFK5CVU7.js";
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
decodeZipEntry,
|
|
3
3
|
readZipArchive,
|
|
4
4
|
readZipIndexedArchive
|
|
5
|
-
} from "../../safe-bash/command-chunks/chunk-
|
|
5
|
+
} from "../../safe-bash/command-chunks/chunk-3EAZRKI4.js";
|
|
6
6
|
import {
|
|
7
7
|
ZipRanges
|
|
8
8
|
} from "../../safe-bash/command-chunks/chunk-FVQFB7OD.js";
|
|
@@ -64,10 +64,12 @@ export interface ZipArchive {
|
|
|
64
64
|
}>) => void;
|
|
65
65
|
}
|
|
66
66
|
export declare function crc32(bytes: Uint8Array, previous?: number): number;
|
|
67
|
-
type ZipReadProfile = Readonly<{
|
|
67
|
+
export type ZipReadProfile = Readonly<{
|
|
68
68
|
grow?: boolean;
|
|
69
69
|
prefix?: boolean;
|
|
70
70
|
disks?: ZipDisks;
|
|
71
|
+
/** Accept unused local records and gaps, as Python wheel readers do; referenced spans still cannot overlap. */
|
|
72
|
+
allowUnreferencedData?: boolean;
|
|
71
73
|
}>;
|
|
72
74
|
/** Explicit buffered compatibility API. Commands use readZipIndexedArchive instead. */
|
|
73
75
|
export declare function readZipArchive(input: Uint8Array | ZipReadSource, limits: ArchiveLimits, signal: AbortSignal, profile?: ZipReadProfile): Promise<ZipArchive>;
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
streamZipArchive,
|
|
10
10
|
updateZipExtras,
|
|
11
11
|
writeZipArchive
|
|
12
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
12
|
+
} from "../safe-bash/command-chunks/chunk-3EAZRKI4.js";
|
|
13
13
|
import "../safe-bash/command-chunks/chunk-FVQFB7OD.js";
|
|
14
14
|
import "../safe-bash/command-chunks/chunk-3I3PD6VU.js";
|
|
15
15
|
import "../safe-bash/command-chunks/chunk-CFK5CVU7.js";
|
|
@@ -21,7 +21,7 @@ export declare function acquireCloudflareBrowser(options: {
|
|
|
21
21
|
interrupt(): Promise<void>;
|
|
22
22
|
release: () => Promise<void>;
|
|
23
23
|
}>;
|
|
24
|
-
/**
|
|
24
|
+
/** Share in-flight deletion and retain success; settled failures permit retry. */
|
|
25
25
|
export declare function createCloudflareBrowserRelease(options: {
|
|
26
26
|
binding: BrowserWorker;
|
|
27
27
|
sessionId: string;
|