arcane-os 0.90.0 → 0.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,103 @@
1
+ import Is from 'strong-type';
2
+ import {stat} from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import {throwIfAborted} from './errors.mjs';
5
+
6
+ const is=new Is(false);
7
+ let installedDirectory=null;
8
+
9
+ // Git for Windows records its chosen location for third-party integrations.
10
+ // Read both installation scopes/views in one owned Windows process. No guessed
11
+ // installation paths or changes to the registry/environment are needed.
12
+ const READ_INSTALLATIONS=String.raw`
13
+ $ErrorActionPreference = 'Stop'
14
+ [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
15
+ $installations = [System.Collections.Generic.List[string]]::new()
16
+ $views = @([Microsoft.Win32.RegistryView]::Registry32)
17
+ if ([Environment]::Is64BitOperatingSystem) {
18
+ $views = @([Microsoft.Win32.RegistryView]::Registry64, [Microsoft.Win32.RegistryView]::Registry32)
19
+ }
20
+ foreach ($hive in @([Microsoft.Win32.RegistryHive]::CurrentUser, [Microsoft.Win32.RegistryHive]::LocalMachine)) {
21
+ foreach ($view in $views) {
22
+ $base = [Microsoft.Win32.RegistryKey]::OpenBaseKey($hive, $view)
23
+ try {
24
+ $key = $base.OpenSubKey('Software\GitForWindows')
25
+ if ($null -ne $key) {
26
+ try {
27
+ $location = $key.GetValue('InstallPath')
28
+ if ($location -is [string] -and $location.Length -gt 0 -and -not $installations.Contains($location)) {
29
+ $installations.Add($location)
30
+ }
31
+ } finally { $key.Dispose() }
32
+ }
33
+ } finally { $base.Dispose() }
34
+ }
35
+ }
36
+ ConvertTo-Json -InputObject @($installations.ToArray()) -Compress
37
+ `;
38
+
39
+ function environmentKey(environment,name){
40
+ return Object.keys(environment).sort().find(function matchingKey(key){
41
+ return key.toLowerCase()===name;
42
+ });
43
+ }
44
+
45
+ export function appendWindowsGitDirectory(environment,directory){
46
+ const keys=Object.keys(environment).filter(function pathKey(key){
47
+ return key.toLowerCase()==='path';
48
+ }).sort();
49
+ const selectedKey=keys[0]??'Path';
50
+ // Node chooses the first case-insensitive key before omitting undefined.
51
+ // libuv uses the parent's PATH if the child has none; null becomes 'null'.
52
+ const selected=environment[selectedKey];
53
+ const original=selected===undefined
54
+ ?process.env[environmentKey(process.env,'path')]??'':selected;
55
+ const result={...environment};
56
+ for(const key of keys)delete result[key];
57
+ const originalPath=`${original}`;
58
+ result[selectedKey]=`${originalPath}${originalPath?';':''}"${directory}"`;
59
+ return result;
60
+ }
61
+
62
+ async function installedGitExists(directory){
63
+ try{
64
+ return (await stat(path.win32.join(directory,'git.exe'))).isFile();
65
+ }catch(error){
66
+ if(error.code==='ENOENT'||error.code==='ENOTDIR')return false;
67
+ throw error;
68
+ }
69
+ }
70
+
71
+ export async function windowsGitEnvironment(environment,{run,signal,onEvent}={}){
72
+ throwIfAborted(signal);
73
+ const retained=installedDirectory;
74
+ if(retained){
75
+ const available=await installedGitExists(retained);
76
+ throwIfAborted(signal);
77
+ if(available)return appendWindowsGitDirectory(environment,retained);
78
+ if(installedDirectory===retained)installedDirectory=null;
79
+ }
80
+
81
+ const systemRoot=process.env[environmentKey(process.env,'systemroot')];
82
+ if(!systemRoot)return environment;
83
+ const powershell=path.win32.join(systemRoot,'System32','WindowsPowerShell','v1.0','powershell.exe');
84
+ const result=await run(powershell,['-NoProfile','-NonInteractive','-Command',READ_INSTALLATIONS],{
85
+ signal,onEvent,emitOutputEvents:false
86
+ });
87
+ throwIfAborted(signal);
88
+ const locations=JSON.parse(result.stdout);
89
+ if(!is.array(locations))throw new TypeError('Git installation discovery did not return a location list.');
90
+ for(const location of locations){
91
+ if(!is.string(location)||!path.win32.isAbsolute(location))continue;
92
+ const directory=path.win32.join(location,'cmd');
93
+ const available=await installedGitExists(directory);
94
+ throwIfAborted(signal);
95
+ if(available){
96
+ // Only successful, still-present discovery is retained. Concurrent
97
+ // first callers own separate lookups and cancellation independently.
98
+ installedDirectory=directory;
99
+ return appendWindowsGitDirectory(environment,directory);
100
+ }
101
+ }
102
+ return environment;
103
+ }
@@ -2,6 +2,7 @@ import Is from 'strong-type';
2
2
  import {randomUUID} from 'node:crypto';
3
3
  import {copyFile,lstat,mkdir,readFile,readdir,realpath,rename,rm,writeFile} from 'node:fs/promises';
4
4
  import path from 'node:path';
5
+ import {materializeBrowserDecisions} from './browser-decisions-distribution.mjs';
5
6
  import {SDK_VERSION} from './constants.mjs';
6
7
  import {rewriteAssetReferences} from './import-map.mjs';
7
8
  import {getSdkRoot} from './runtime.mjs';
@@ -85,85 +86,6 @@ async function removeTemporaryTree(location){
85
86
  await rm(location,{recursive:true,force:true}).catch(()=>{});
86
87
  }
87
88
 
88
- async function materializeBrowserDecisions(destination, signal, onEvent) {
89
- const transformers = 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.3.0/';
90
- const onnx = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.31.0-dev.20260914-8d85527a0/';
91
- const files = [
92
- {name: 'transformers.min.js', url: `${transformers}dist/transformers.min.js`},
93
- {name: 'ort-wasm-simd-threaded.asyncify.mjs', url: `${onnx}dist/ort-wasm-simd-threaded.asyncify.mjs`},
94
- {name: 'ort-wasm-simd-threaded.asyncify.wasm', url: `${onnx}dist/ort-wasm-simd-threaded.asyncify.wasm`},
95
- {name: 'TRANSFORMERS-LICENSE', url: `${transformers}LICENSE`},
96
- {name: 'ONNX-RUNTIME-LICENSE', url: `${onnx}LICENSE`}
97
- ];
98
- const controller = new AbortController();
99
- function cancelDistribution() {
100
- controller.abort(signal.reason);
101
- }
102
- signal?.addEventListener('abort', cancelDistribution, {once: true});
103
- if (signal?.aborted) cancelDistribution();
104
- let completed = 0;
105
- try {
106
- throwIfAborted(controller.signal);
107
- await emit(
108
- onEvent,
109
- {type: 'workspace.decisions.started', completed, total: files.length}
110
- );
111
- throwIfAborted(controller.signal);
112
- await mkdir(destination, {recursive: true});
113
- async function acquireDistributionFile(file) {
114
- try {
115
- throwIfAborted(controller.signal);
116
- const response = await fetch(file.url, {signal: controller.signal});
117
- const content = new Uint8Array(await response.arrayBuffer());
118
- if (!response.ok) {
119
- const error = new Error(`Browser decision distribution returned HTTP ${response.status} ${response.statusText}.`);
120
- error.code = 'ARCANE_DECISION_DISTRIBUTION_DOWNLOAD_FAILED';
121
- error.response = {
122
- url: response.url,
123
- status: response.status,
124
- statusText: response.statusText,
125
- headers: [...response.headers],
126
- content
127
- };
128
- throw error;
129
- }
130
- throwIfAborted(controller.signal);
131
- // Upstream distribution content is opaque, including its own
132
- // imports and license text. No SDK source rewriting applies.
133
- await writeFile(path.join(destination, file.name), content);
134
- throwIfAborted(controller.signal);
135
- completed += 1;
136
- await emit(
137
- onEvent,
138
- {type: 'workspace.decisions.progress', file: file.name, url: file.url, completed, total: files.length}
139
- );
140
- } catch (error) {
141
- controller.abort(error);
142
- throw error;
143
- }
144
- }
145
- // One fixed distribution, acquired once for the selected projection;
146
- // no model/app/architecture multiplier or installation script.
147
- const outcomes = await Promise.allSettled(files.map(acquireDistributionFile));
148
- const failures = new Set();
149
- for (const outcome of outcomes) {
150
- if (outcome.status === 'rejected') failures.add(outcome.reason);
151
- }
152
- if (failures.size === 1) throw [...failures][0];
153
- if (failures.size > 1) {
154
- throw new AggregateError([...failures], 'Browser decision distribution acquisition failed.');
155
- }
156
- throwIfAborted(controller.signal);
157
- } finally {
158
- signal?.removeEventListener('abort', cancelDistribution);
159
- }
160
- return {
161
- transformersVersion: '4.3.0',
162
- onnxRuntimeVersion: '1.31.0-dev.20260914-8d85527a0',
163
- files: files.map(function distributionFilename(file) { return file.name; })
164
- };
165
- }
166
-
167
89
  export async function materializeWorkspaceRuntimeContent({
168
90
  workspaceRoot,
169
91
  runtimeRoot=path.join(getSdkRoot(),'runtime'),