pyfig 0.1.0 → 0.3.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.
Files changed (66) hide show
  1. package/README.md +154 -17
  2. package/SECURITY.md +5 -3
  3. package/dist/cjs/index.js +1504 -0
  4. package/dist/cjs/index.js.map +21 -0
  5. package/dist/cjs/package.json +3 -0
  6. package/dist/cjs/sync-resolver.js +1242 -0
  7. package/dist/cjs/sync-resolver.js.map +18 -0
  8. package/dist/cli.js +17 -6
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client.d.ts +20 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +23 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/config.d.ts +45 -2
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/config.js +130 -9
  17. package/dist/config.js.map +1 -1
  18. package/dist/coordination.d.ts +25 -0
  19. package/dist/coordination.d.ts.map +1 -0
  20. package/dist/coordination.js +187 -0
  21. package/dist/coordination.js.map +1 -0
  22. package/dist/index.d.ts +9 -5
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +6 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/package-target.d.ts +12 -0
  27. package/dist/package-target.d.ts.map +1 -0
  28. package/dist/package-target.js +97 -0
  29. package/dist/package-target.js.map +1 -0
  30. package/dist/probes.d.ts +27 -0
  31. package/dist/probes.d.ts.map +1 -1
  32. package/dist/probes.js +140 -33
  33. package/dist/probes.js.map +1 -1
  34. package/dist/process.d.ts +2 -0
  35. package/dist/process.d.ts.map +1 -1
  36. package/dist/process.js +63 -1
  37. package/dist/process.js.map +1 -1
  38. package/dist/project-root.d.ts +3 -0
  39. package/dist/project-root.d.ts.map +1 -0
  40. package/dist/project-root.js +83 -0
  41. package/dist/project-root.js.map +1 -0
  42. package/dist/provision.d.ts +3 -1
  43. package/dist/provision.d.ts.map +1 -1
  44. package/dist/provision.js +375 -97
  45. package/dist/provision.js.map +1 -1
  46. package/dist/runners.d.ts +18 -0
  47. package/dist/runners.d.ts.map +1 -0
  48. package/dist/runners.js +151 -0
  49. package/dist/runners.js.map +1 -0
  50. package/dist/runtime-files.d.ts +3 -0
  51. package/dist/runtime-files.d.ts.map +1 -0
  52. package/dist/runtime-files.js +12 -0
  53. package/dist/runtime-files.js.map +1 -0
  54. package/dist/state.d.ts +10 -0
  55. package/dist/state.d.ts.map +1 -0
  56. package/dist/state.js +62 -0
  57. package/dist/state.js.map +1 -0
  58. package/dist/sync-resolver.d.ts +2 -0
  59. package/dist/sync-resolver.d.ts.map +1 -0
  60. package/dist/sync-resolver.js +24 -0
  61. package/dist/sync-resolver.js.map +1 -0
  62. package/dist/virtual-environment.d.ts +9 -0
  63. package/dist/virtual-environment.d.ts.map +1 -0
  64. package/dist/virtual-environment.js +42 -0
  65. package/dist/virtual-environment.js.map +1 -0
  66. package/package.json +26 -7
@@ -0,0 +1,151 @@
1
+ import { spawn, spawnSync, } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import { configurationFingerprint, resolveOptions, uvEnvironment, } from './config.js';
4
+ import { assertMutationUsesUv, assertSafePackageArguments, isUvPipCommand, packageManagerEnvironment, uvPipEnvironment, } from './package-target.js';
5
+ import { ensureEnvironment, ensureUv, ensureVirtualEnvironment, } from './provision.js';
6
+ import { runtimeFile } from './runtime-files.js';
7
+ import { memoizeSync } from './state.js';
8
+ import { activateVirtualEnvironment } from './virtual-environment.js';
9
+ export async function pythonSpawn(args = [], spawnOptions = {}, pyfigOptions = {}) {
10
+ const options = optionsForInvocation(pyfigOptions, spawnOptions.env);
11
+ const python = await ensureVirtualEnvironment(options);
12
+ const command = buildPythonCommand(python, args, resolveOptions(options).env);
13
+ return spawn(command.executable, command.args, {
14
+ ...spawnOptions,
15
+ env: command.env,
16
+ });
17
+ }
18
+ export function pythonSpawnSync(args = [], spawnOptions = {}, pyfigOptions = {}) {
19
+ const options = optionsForInvocation(pyfigOptions, spawnOptions.env);
20
+ const python = resolveSynchronously('venv', options);
21
+ const command = buildPythonCommand(python, args, resolveOptions(options).env);
22
+ return spawnSync(command.executable, command.args, {
23
+ ...spawnOptions,
24
+ env: command.env,
25
+ });
26
+ }
27
+ export async function pipSpawn(args = [], spawnOptions = {}, pyfigOptions = {}) {
28
+ const options = optionsForInvocation(pyfigOptions, spawnOptions.env);
29
+ const environment = await ensureEnvironment(options);
30
+ const command = buildPipCommand(environment.packageManager, args, resolveOptions(options).env);
31
+ return spawn(command.executable, command.args, {
32
+ ...spawnOptions,
33
+ env: command.env,
34
+ });
35
+ }
36
+ export function pipSpawnSync(args = [], spawnOptions = {}, pyfigOptions = {}) {
37
+ const options = optionsForInvocation(pyfigOptions, spawnOptions.env);
38
+ const environment = resolveSynchronously('environment', options);
39
+ const command = buildPipCommand(environment.packageManager, args, resolveOptions(options).env);
40
+ return spawnSync(command.executable, command.args, {
41
+ ...spawnOptions,
42
+ env: command.env,
43
+ });
44
+ }
45
+ export async function uvSpawn(args = [], spawnOptions = {}, pyfigOptions = {}) {
46
+ const options = optionsForInvocation(pyfigOptions, spawnOptions.env);
47
+ const resolved = resolveOptions(options);
48
+ const uv = await ensureUv(resolved);
49
+ const python = isUvPipCommand(args)
50
+ ? await ensureVirtualEnvironment(resolved)
51
+ : undefined;
52
+ const command = buildUvCommand(uv, args, resolved, python);
53
+ return spawn(command.executable, command.args, {
54
+ ...spawnOptions,
55
+ env: command.env,
56
+ });
57
+ }
58
+ export function uvSpawnSync(args = [], spawnOptions = {}, pyfigOptions = {}) {
59
+ const options = optionsForInvocation(pyfigOptions, spawnOptions.env);
60
+ const resolved = resolveOptions(options);
61
+ const resolution = isUvPipCommand(args)
62
+ ? resolveSynchronously('uv-pip', resolved)
63
+ : { uv: resolveSynchronously('uv', resolved), python: undefined };
64
+ const command = buildUvCommand(resolution.uv, args, resolved, resolution.python);
65
+ return spawnSync(command.executable, command.args, {
66
+ ...spawnOptions,
67
+ env: command.env,
68
+ });
69
+ }
70
+ export function buildPythonCommand(python, args, env) {
71
+ const commandEnv = python.virtualEnvironment
72
+ ? activateVirtualEnvironment(env, python.virtualEnvironment, python.executable)
73
+ : env;
74
+ return {
75
+ executable: python.executable,
76
+ args: [...args],
77
+ env: commandEnv,
78
+ };
79
+ }
80
+ export function buildPipCommand(packageManager, args, env) {
81
+ if (!packageManager.virtualEnvironment) {
82
+ throw new Error('pip commands require an active virtual environment.');
83
+ }
84
+ assertSafePackageArguments(args);
85
+ assertMutationUsesUv(packageManager, args);
86
+ return {
87
+ executable: packageManager.executable,
88
+ args: [...packageManager.prefixArgs, ...args],
89
+ env: packageManagerEnvironment(env, packageManager),
90
+ };
91
+ }
92
+ export function buildUvCommand(uv, args, options, python) {
93
+ const isPip = isUvPipCommand(args);
94
+ if (isPip && !python?.virtualEnvironment) {
95
+ throw new Error('uv pip commands require the repo virtual-environment Python interpreter.');
96
+ }
97
+ if (isPip)
98
+ assertSafePackageArguments(args);
99
+ const env = isPip && python
100
+ ? uvPipEnvironment(uvEnvironment(options), python)
101
+ : uvEnvironment(options);
102
+ return {
103
+ executable: uv.executable,
104
+ args: [...args],
105
+ env,
106
+ };
107
+ }
108
+ function optionsForInvocation(pyfigOptions, spawnEnv) {
109
+ return spawnEnv === undefined ? pyfigOptions : { ...pyfigOptions, env: spawnEnv };
110
+ }
111
+ function resolveSynchronously(target, options) {
112
+ const resolved = resolveOptions(options);
113
+ const cacheKey = `${target}:${configurationFingerprint(resolved)}`;
114
+ return memoizeSync('sync-resolution', cacheKey, resolved.cacheTtlMs, synchronousResolutionIsPresent, () => {
115
+ const request = { target, options: resolved };
116
+ const result = spawnSync(process.execPath, [runtimeFile('sync-resolver')], {
117
+ input: JSON.stringify(request),
118
+ encoding: 'utf8',
119
+ env: resolved.env,
120
+ timeout: synchronousResolutionTimeout(resolved),
121
+ maxBuffer: 4 * 1024 * 1024,
122
+ windowsHide: true,
123
+ });
124
+ if (result.status !== 0 || result.error) {
125
+ const detail = result.stderr.trim() || result.error?.message || `exit ${result.status}`;
126
+ throw new Error(`Could not resolve ${target} synchronously: ${detail}`);
127
+ }
128
+ try {
129
+ return JSON.parse(result.stdout);
130
+ }
131
+ catch (error) {
132
+ const detail = error instanceof Error ? error.message : String(error);
133
+ throw new Error(`Could not parse synchronous ${target} resolution: ${detail}`);
134
+ }
135
+ });
136
+ }
137
+ function synchronousResolutionTimeout(options) {
138
+ return options.coordinationTimeoutMs + options.downloadTimeoutMs +
139
+ (2 * options.installTimeoutMs) + (4 * options.probeTimeoutMs) + 60_000;
140
+ }
141
+ function synchronousResolutionIsPresent(resolution) {
142
+ if ('packageManager' in resolution) {
143
+ return fs.existsSync(resolution.python.executable) &&
144
+ fs.existsSync(resolution.packageManager.executable);
145
+ }
146
+ if ('uv' in resolution) {
147
+ return fs.existsSync(resolution.uv.executable) && fs.existsSync(resolution.python.executable);
148
+ }
149
+ return fs.existsSync(resolution.executable);
150
+ }
151
+ //# sourceMappingURL=runners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runners.js","sourceRoot":"","sources":["../src/runners.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Resolve a compiled runtime helper beside either the ESM files or the CJS bundle. */
2
+ export declare function runtimeFile(name: string): string;
3
+ //# sourceMappingURL=runtime-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-files.d.ts","sourceRoot":"","sources":["../src/runtime-files.ts"],"names":[],"mappings":"AAMA,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhD"}
@@ -0,0 +1,12 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /** Resolve a compiled runtime helper beside either the ESM files or the CJS bundle. */
5
+ export function runtimeFile(name) {
6
+ const moduleDirectory = typeof PYFIG_CJS_DIRECTORY === 'string'
7
+ ? PYFIG_CJS_DIRECTORY
8
+ : path.dirname(fileURLToPath(import.meta.url));
9
+ const compiled = path.join(moduleDirectory, `${name}.js`);
10
+ return fs.existsSync(compiled) ? compiled : path.join(moduleDirectory, `${name}.ts`);
11
+ }
12
+ //# sourceMappingURL=runtime-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-files.js","sourceRoot":"","sources":["../src/runtime-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,uFAAuF;AACvF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,eAAe,GAAG,OAAO,mBAAmB,KAAK,QAAQ;QAC7D,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAC1D,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;AACvF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Share expensive resolution work within one JavaScript realm without treating
3
+ * cached filesystem state as permanent truth.
4
+ */
5
+ export declare function memoizeAsync<T>(namespace: string, key: string, ttlMs: number, validate: (value: T) => boolean | Promise<boolean>, load: () => Promise<T>): Promise<T>;
6
+ /** Synchronous counterpart used by spawnSync bridges in the caller realm. */
7
+ export declare function memoizeSync<T>(namespace: string, key: string, ttlMs: number, validate: (value: T) => boolean, load: () => T): T;
8
+ /** Clear completed and in-flight lookup references after external toolchain changes. */
9
+ export declare function clearPyfigCaches(): void;
10
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAClD,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,CAAC,CA0BZ;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,CAAC,EAC3B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,EAC/B,IAAI,EAAE,MAAM,CAAC,GACZ,CAAC,CAcH;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC"}
package/dist/state.js ADDED
@@ -0,0 +1,62 @@
1
+ const completed = new Map();
2
+ const inFlight = new Map();
3
+ let cacheGeneration = 0;
4
+ /**
5
+ * Share expensive resolution work within one JavaScript realm without treating
6
+ * cached filesystem state as permanent truth.
7
+ */
8
+ export async function memoizeAsync(namespace, key, ttlMs, validate, load) {
9
+ const cacheKey = `${namespace}\0${key}`;
10
+ const cached = completed.get(cacheKey);
11
+ if (cached && cached.expiresAt >= Date.now()) {
12
+ try {
13
+ if (await validate(cached.value))
14
+ return cached.value;
15
+ }
16
+ catch {
17
+ // Invalid or inaccessible external state is refreshed below.
18
+ }
19
+ completed.delete(cacheKey);
20
+ }
21
+ const pending = inFlight.get(cacheKey);
22
+ if (pending)
23
+ return pending;
24
+ const generation = cacheGeneration;
25
+ const loading = load().then((value) => {
26
+ if (ttlMs > 0 && generation === cacheGeneration) {
27
+ completed.set(cacheKey, { expiresAt: Date.now() + ttlMs, value });
28
+ }
29
+ return value;
30
+ }).finally(() => {
31
+ if (inFlight.get(cacheKey) === loading)
32
+ inFlight.delete(cacheKey);
33
+ });
34
+ inFlight.set(cacheKey, loading);
35
+ return loading;
36
+ }
37
+ /** Synchronous counterpart used by spawnSync bridges in the caller realm. */
38
+ export function memoizeSync(namespace, key, ttlMs, validate, load) {
39
+ const cacheKey = `${namespace}\0${key}`;
40
+ const cached = completed.get(cacheKey);
41
+ if (cached && cached.expiresAt >= Date.now()) {
42
+ try {
43
+ if (validate(cached.value))
44
+ return cached.value;
45
+ }
46
+ catch {
47
+ // Refresh invalid external state below.
48
+ }
49
+ completed.delete(cacheKey);
50
+ }
51
+ const value = load();
52
+ if (ttlMs > 0)
53
+ completed.set(cacheKey, { expiresAt: Date.now() + ttlMs, value });
54
+ return value;
55
+ }
56
+ /** Clear completed and in-flight lookup references after external toolchain changes. */
57
+ export function clearPyfigCaches() {
58
+ cacheGeneration += 1;
59
+ completed.clear();
60
+ inFlight.clear();
61
+ }
62
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAKA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAC;AAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;AACrD,IAAI,eAAe,GAAG,CAAC,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,SAAiB,EACjB,GAAW,EACX,KAAa,EACb,QAAkD,EAClD,IAAsB;IAEtB,MAAM,QAAQ,GAAG,GAAG,SAAS,KAAK,GAAG,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,IAAI,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAU,CAAC;gBAAE,OAAO,MAAM,CAAC,KAAU,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;QAC/D,CAAC;QACD,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,OAAO;QAAE,OAAO,OAAqB,CAAC;IAE1C,MAAM,UAAU,GAAG,eAAe,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACpC,IAAI,KAAK,GAAG,CAAC,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;YAChD,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;QACd,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,OAAO;YAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CACzB,SAAiB,EACjB,GAAW,EACX,KAAa,EACb,QAA+B,EAC/B,IAAa;IAEb,MAAM,QAAQ,GAAG,GAAG,SAAS,KAAK,GAAG,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAU,CAAC;gBAAE,OAAO,MAAM,CAAC,KAAU,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;QACD,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;IACrB,IAAI,KAAK,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,gBAAgB;IAC9B,eAAe,IAAI,CAAC,CAAC;IACrB,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-resolver.d.ts","sourceRoot":"","sources":["../src/sync-resolver.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { ensureEnvironment, ensurePython, ensureUv, ensureVirtualEnvironment, } from './provision.js';
3
+ async function main() {
4
+ const request = JSON.parse(readFileSync(0, 'utf8'));
5
+ const result = request.target === 'python'
6
+ ? await ensurePython(request.options)
7
+ : request.target === 'venv'
8
+ ? await ensureVirtualEnvironment(request.options)
9
+ : request.target === 'uv'
10
+ ? await ensureUv(request.options)
11
+ : request.target === 'uv-pip'
12
+ ? {
13
+ uv: await ensureUv(request.options),
14
+ python: await ensureVirtualEnvironment(request.options),
15
+ }
16
+ : await ensureEnvironment(request.options);
17
+ process.stdout.write(JSON.stringify(result));
18
+ }
19
+ main().catch((error) => {
20
+ const message = error instanceof Error ? error.message : String(error);
21
+ process.stderr.write(message);
22
+ process.exitCode = 1;
23
+ });
24
+ //# sourceMappingURL=sync-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-resolver.js","sourceRoot":"","sources":["../src/sync-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAOxB,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAA0B,CAAC;IAC7E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,QAAQ;QACxC,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC;QACrC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM;YACzB,CAAC,CAAC,MAAM,wBAAwB,CAAC,OAAO,CAAC,OAAO,CAAC;YACnD,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI;gBACvB,CAAC,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;gBACjC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ;oBAC3B,CAAC,CAAC;wBACE,EAAE,EAAE,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;wBACnC,MAAM,EAAE,MAAM,wBAAwB,CAAC,OAAO,CAAC,OAAO,CAAC;qBACxD;oBACH,CAAC,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const VIRTUAL_ENV_DIRECTORY_NAME = ".venv";
2
+ export declare function virtualEnvironmentDirectory(projectRoot: string): string;
3
+ export declare function virtualEnvironmentPythonExecutable(virtualEnvironment: string): string;
4
+ /** Apply the environment changes that shell activation scripts make for child processes. */
5
+ export declare function activateVirtualEnvironment(env: NodeJS.ProcessEnv, virtualEnvironment: string, pythonExecutable: string): NodeJS.ProcessEnv;
6
+ export declare function pathsEqual(left: string, right: string): boolean;
7
+ /** Canonicalize existing paths so symlink, junction, and filesystem casing aliases compare equally. */
8
+ export declare function canonicalPath(value: string): string;
9
+ //# sourceMappingURL=virtual-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-environment.d.ts","sourceRoot":"","sources":["../src/virtual-environment.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,0BAA0B,UAAU,CAAC;AAElD,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,kCAAkC,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAMrF;AAED,4FAA4F;AAC5F,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,kBAAkB,EAAE,MAAM,EAC1B,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAAC,UAAU,CAenB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,uGAAuG;AACvG,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASnD"}
@@ -0,0 +1,42 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export const VIRTUAL_ENV_DIRECTORY_NAME = '.venv';
4
+ export function virtualEnvironmentDirectory(projectRoot) {
5
+ return path.join(projectRoot, VIRTUAL_ENV_DIRECTORY_NAME);
6
+ }
7
+ export function virtualEnvironmentPythonExecutable(virtualEnvironment) {
8
+ return path.join(virtualEnvironment, process.platform === 'win32' ? 'Scripts' : 'bin', process.platform === 'win32' ? 'python.exe' : 'python');
9
+ }
10
+ /** Apply the environment changes that shell activation scripts make for child processes. */
11
+ export function activateVirtualEnvironment(env, virtualEnvironment, pythonExecutable) {
12
+ const activated = { ...env };
13
+ const pathEntry = Object.keys(activated).find((key) => key.toUpperCase() === 'PATH');
14
+ const existingPath = pathEntry ? activated[pathEntry] : undefined;
15
+ for (const key of Object.keys(activated)) {
16
+ const normalized = key.toUpperCase();
17
+ if (normalized === 'PATH' || normalized === 'PYTHONHOME' || normalized === 'VIRTUAL_ENV') {
18
+ delete activated[key];
19
+ }
20
+ }
21
+ activated['PATH'] = [path.dirname(pythonExecutable), existingPath]
22
+ .filter((value) => Boolean(value))
23
+ .join(path.delimiter);
24
+ activated['VIRTUAL_ENV'] = virtualEnvironment;
25
+ return activated;
26
+ }
27
+ export function pathsEqual(left, right) {
28
+ return canonicalPath(left) === canonicalPath(right);
29
+ }
30
+ /** Canonicalize existing paths so symlink, junction, and filesystem casing aliases compare equally. */
31
+ export function canonicalPath(value) {
32
+ const resolved = path.resolve(value);
33
+ let canonical = resolved;
34
+ try {
35
+ canonical = fs.realpathSync.native(resolved);
36
+ }
37
+ catch {
38
+ // Paths being provisioned do not exist yet; the absolute spelling is the best stable key.
39
+ }
40
+ return process.platform === 'win32' ? canonical.toLowerCase() : canonical;
41
+ }
42
+ //# sourceMappingURL=virtual-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-environment.js","sourceRoot":"","sources":["../src/virtual-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAC;AAElD,MAAM,UAAU,2BAA2B,CAAC,WAAmB;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,kBAA0B;IAC3E,OAAO,IAAI,CAAC,IAAI,CACd,kBAAkB,EAClB,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAChD,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CACvD,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,0BAA0B,CACxC,GAAsB,EACtB,kBAA0B,EAC1B,gBAAwB;IAExB,MAAM,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;IACrF,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,YAAY,IAAI,UAAU,KAAK,aAAa,EAAE,CAAC;YACzF,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC;SAC/D,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;SAClD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,SAAS,CAAC,aAAa,CAAC,GAAG,kBAAkB,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAa;IACpD,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,SAAS,GAAG,QAAQ,CAAC;IACzB,IAAI,CAAC;QACH,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,0FAA0F;IAC5F,CAAC;IACD,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5E,CAAC"}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "pyfig",
3
- "version": "0.1.0",
4
- "description": "Find compatible Python and pip executables, with a locked uv fallback.",
3
+ "version": "0.3.0",
4
+ "description": "Provision a repo-local Python venv with uv-first tooling and locked fallbacks.",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
6
+ "main": "./dist/cjs/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/cjs/index.js"
12
13
  }
13
14
  },
14
15
  "bin": {
@@ -21,10 +22,13 @@
21
22
  "SECURITY.md"
22
23
  ],
23
24
  "scripts": {
24
- "build": "tsc -p tsconfig.json",
25
+ "build": "tsc -p tsconfig.json && bun run scripts/build-cjs.ts",
25
26
  "test": "bun test",
27
+ "test:zero-python": "bun run scripts/smoke-zero-python.ts",
26
28
  "typecheck": "tsc --noEmit -p tsconfig.json",
27
29
  "verify": "bun run typecheck && bun test",
30
+ "release:check": "bun run scripts/check-release.ts",
31
+ "release:audit": "bun run scripts/audit-package.ts",
28
32
  "prepack": "bun run verify && bun run build"
29
33
  },
30
34
  "keywords": [
@@ -37,19 +41,34 @@
37
41
  ],
38
42
  "author": "Reggie Bowser",
39
43
  "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/regbo/pyfig.git"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/regbo/pyfig/issues"
50
+ },
51
+ "homepage": "https://github.com/regbo/pyfig#readme",
40
52
  "publishConfig": {
41
- "access": "public"
53
+ "access": "public",
54
+ "provenance": true,
55
+ "registry": "https://registry.npmjs.org"
42
56
  },
57
+ "packageManager": "bun@1.4.4",
43
58
  "sideEffects": false,
44
59
  "engines": {
45
- "node": ">=20.17.0",
60
+ "node": ">=22.0.0 <=26.x",
46
61
  "bun": ">=1.2.0"
47
62
  },
48
63
  "dependencies": {
49
64
  "commander": "^14.0.3",
50
65
  "env-paths": "^4.0.0",
66
+ "extract-zip": "^2.0.1",
67
+ "pacwich": "^0.7.3",
51
68
  "proper-lockfile": "^4.1.2",
52
69
  "semver": "^7.8.5",
70
+ "tar": "^7.4.3",
71
+ "undici": "^7.30.1",
53
72
  "which": "^6.0.1"
54
73
  },
55
74
  "devDependencies": {