arcane-os 0.62.0 → 0.64.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/CHANGELOG.md +40 -0
- package/README.md +1 -1
- package/browser-runtime/core/client.mjs +7 -2
- package/docs/reference/README.md +7 -0
- package/docs/reference/cli.md +5 -1
- package/docs/reference/core-client.md +11 -2
- package/docs/reference/core-native-packaging.md +57 -8
- package/docs/reference/core-repositories.md +149 -0
- package/docs/reference/inventory/package-api.json +163 -9
- package/docs/reference/local-ai.md +51 -7
- package/docs/reference/local-image-flux.md +154 -0
- package/docs/reference/local-image-generation.md +12 -0
- package/docs/reference/local-image-sdxl.md +139 -0
- package/docs/reference/local-whisper.md +219 -0
- package/docs/reference/native-speech.md +163 -0
- package/docs/reference/runtime-modules.md +16 -2
- package/docs/reference/sdk-api.md +335 -6
- package/package.json +5 -1
- package/runtime/arcane/components/speech.html +15 -3
- package/runtime/arcane/components/voice-transcription.html +19 -3
- package/runtime/arcane/modules/AI.js +250 -27
- package/runtime/arcane/modules/AIProviderRuntime.js +20 -3
- package/runtime/arcane/modules/AIRuntimeState.js +15 -2
- package/runtime/arcane/modules/ComponentContracts.js +3 -0
- package/schemas/arcane-app.schema.json +53 -2
- package/schemas/arcane-package.schema.json +53 -2
- package/src/core/repositories.mjs +210 -0
- package/src/core/services/speech.mjs +361 -0
- package/src/local-ai/config.mjs +9 -3
- package/src/local-ai/dev.mjs +32 -2
- package/src/local-ai/image-library.mjs +9 -0
- package/src/local-ai/image-models/flux.mjs +31 -0
- package/src/local-ai/image-models/sdxl.mjs +18 -0
- package/src/local-ai/install.mjs +26 -7
- package/src/local-ai/whisper/build.mjs +48 -0
- package/src/local-ai/whisper/config.mjs +61 -0
- package/src/local-ai/whisper/index.mjs +515 -0
- package/src/local-ai/whisper/install.mjs +274 -0
- package/src/local-ai/whisper/native/CMakeLists.txt +98 -0
- package/src/local-ai/whisper/native/NOTICE +18 -0
- package/src/local-ai/whisper/native/README.md +104 -0
- package/src/local-ai/whisper/native/main.cpp +489 -0
- package/src/native/portable-layout.mjs +37 -7
- package/src/native/windows-provider.mjs +39 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.64.0
|
|
4
|
+
|
|
5
|
+
- Add retained native Whisper transcription through the existing Core speech
|
|
6
|
+
service and AI API, with actual model readiness, complete recordings and
|
|
7
|
+
transcripts, native progress, joined cancellation, and one eligible
|
|
8
|
+
accelerated-inference recovery on the prepared CPU runtime.
|
|
9
|
+
- Preserve the same accepted transcription through internal recovery using
|
|
10
|
+
its actual Core request identity. Shared AI and speech controls report
|
|
11
|
+
recovering/error states honestly without discarding the original request
|
|
12
|
+
or turning its terminal native failure into cancellation.
|
|
13
|
+
- Add the SDXL Base 1.0 text-to-image descriptor and correct the shared native
|
|
14
|
+
image binding's asynchronous worker stack allocation while preserving
|
|
15
|
+
existing model selection, complete inputs and native lifecycle.
|
|
16
|
+
- Add `arcane-os/core/repositories` with per-user `ArcaneData/Repos` defaults
|
|
17
|
+
and connected working-repository open/status/pull/push/drain ownership.
|
|
18
|
+
Explicit paths and existing data remain unchanged; applications own
|
|
19
|
+
connection selection, remotes and product records. No data migration.
|
|
20
|
+
- Keep optional NPU, repository file-write orchestration, generic development
|
|
21
|
+
Core composition, Codex/MCP and Ollama lifecycle drafts outside this release.
|
|
22
|
+
The npm dependency tree is unchanged; native resources use their documented
|
|
23
|
+
upstream installation and matching numeric-release helper assets.
|
|
24
|
+
|
|
25
|
+
## 0.63.0
|
|
26
|
+
|
|
27
|
+
- Add the approved FLUX.2 Klein 4B text-to-image model descriptor to the
|
|
28
|
+
existing retained local image runtime, with its separate diffusion, VAE
|
|
29
|
+
and text-encoder resources and four-step Euler defaults. Applications keep
|
|
30
|
+
their model choice, complete prompts and image persistence.
|
|
31
|
+
- Name assembled Windows launchers from the application display name, with a
|
|
32
|
+
matching executable configuration and manifest-selected launch path.
|
|
33
|
+
Preserve supported spaces, case and Unicode, existing generic artifacts,
|
|
34
|
+
icon embedding and the unchanged shared host archive.
|
|
35
|
+
- Add `createSpeechService({stt, tts, signal})` through `arcane-os/core/speech`
|
|
36
|
+
for independently supplied native engines, immediate service registration,
|
|
37
|
+
sticky role state, complete requests/results, cancellation and joined close.
|
|
38
|
+
This service does not install or select a speech engine.
|
|
39
|
+
- Preserve existing image generation/editing and native host behavior. No
|
|
40
|
+
additional GPU setup, SDXL, Whisper engine, Kokoro/Sherpa adoption or browser
|
|
41
|
+
AI native-speech readiness correction is included in this increment.
|
|
42
|
+
|
|
3
43
|
## 0.62.0
|
|
4
44
|
|
|
5
45
|
- Add whole-image PNG editing through the existing local image runtime, Core
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ selected SDK projection or an explicit live SDK source mount. Both profiles
|
|
|
20
20
|
share the theme, packaging, event, cancellation,
|
|
21
21
|
and browser run contracts while retaining their selected application layout.
|
|
22
22
|
|
|
23
|
-
This checkout defines the `0.
|
|
23
|
+
This checkout defines the `0.64.0` SDK contract. Development applications declare
|
|
24
24
|
`arcane-os` as `latest` and retain their lockfile. Exact SDK pins begin when Roshi
|
|
25
25
|
designates a production build. Follow [Consumer updates](docs/consumer-updates.md)
|
|
26
26
|
to refresh and compare the installed SDK and lockfile with the published channel;
|
|
@@ -459,7 +459,10 @@ export function createCoreClient({
|
|
|
459
459
|
if(eventOwnerFailure)return Promise.reject(eventOwnerFailure);
|
|
460
460
|
let selected;
|
|
461
461
|
try{selected=connect();}catch(error){return Promise.reject(error);}
|
|
462
|
-
const {signal,timeoutMs=10*60*1000}=options??{};
|
|
462
|
+
const {signal,timeoutMs=10*60*1000,onRequest}=options??{};
|
|
463
|
+
if(onRequest!==undefined&&typeof onRequest!=='function'){
|
|
464
|
+
return Promise.reject(new TypeError('Arcane request observer must be a function.'));
|
|
465
|
+
}
|
|
463
466
|
if(signal&&(typeof signal.aborted!=='boolean'
|
|
464
467
|
||typeof signal.addEventListener!=='function'
|
|
465
468
|
||typeof signal.removeEventListener!=='function')){
|
|
@@ -483,6 +486,8 @@ export function createCoreClient({
|
|
|
483
486
|
if(!settle(id,failure))report(failure);
|
|
484
487
|
}
|
|
485
488
|
try{
|
|
489
|
+
if(onRequest)Promise.resolve(onRequest({requestId:id})).catch(report);
|
|
490
|
+
if(!pending.has(id))return promise;
|
|
486
491
|
Promise.resolve(selected.send(frame)).catch(sendFailed);
|
|
487
492
|
}catch(error){sendFailed(error);}
|
|
488
493
|
return promise;
|
|
@@ -569,7 +574,7 @@ export function createCoreFacade(client){
|
|
|
569
574
|
mail:{send:request=>invoke('mail.send',request??{},{timeoutMs:450000})},
|
|
570
575
|
speech:{status:()=>invoke('speech.status',{},{timeoutMs:10000}),
|
|
571
576
|
synthesize:(request,options)=>invoke('speech.synthesize',request??{},{timeoutMs:180000,signal:options?.signal}),
|
|
572
|
-
transcribe:(request,options)=>invoke('speech.transcribe',request??{},{timeoutMs:180000,signal:options?.signal})},
|
|
577
|
+
transcribe:(request,options)=>invoke('speech.transcribe',request??{},{timeoutMs:180000,signal:options?.signal,onRequest:options?.onRequest})},
|
|
573
578
|
localAI:{status:()=>invoke('localai.status',{},{timeoutMs:15000}),
|
|
574
579
|
ensurePlatform:()=>invoke('localai.platform.ensure',{},long),recover:request=>invoke('localai.services.recover',request??{},long),
|
|
575
580
|
setParallelRequests:request=>invoke('localai.parallel.requests.set',request??{},long),
|
package/docs/reference/README.md
CHANGED
|
@@ -55,6 +55,11 @@ alone does not make bare module names resolve in a browser.
|
|
|
55
55
|
| Cancel one Core speech synthesis request without changing its payload | [Speech request lifetime](core-client.md#events-and-request-lifetime) and [Core facade](sdk-api.md#createcorefacade) |
|
|
56
56
|
| Compose native Core dispatch, service lifecycle, and stdio hosting | [Native Core runtime](core-runtime.md) |
|
|
57
57
|
| Run application-selected llama.cpp, Ollama or ONNX through Core | [Local AI through Core](local-ai.md) |
|
|
58
|
+
| Generate complete local PNG images with a retained native model | [Local image generation](local-image-generation.md) |
|
|
59
|
+
| Select FLUX.2 Klein 4B and its three complementary model resources | [FLUX.2 Klein 4B through Core](local-image-flux.md) |
|
|
60
|
+
| Compose independently loaded transcription and synthesis engines | [Native speech service](native-speech.md) |
|
|
61
|
+
| Edit an original PNG with a complete prompt and explicit strength | [Local image editing](local-image-editing.md) |
|
|
62
|
+
| Project complete stored model files into native working files | [Model assets through Core](model-assets.md) |
|
|
58
63
|
| Retain a Nemotron model and diarize caller-fed audio streams | [Native speaker diarization](diarization.md) |
|
|
59
64
|
| Persist application-selected preferences through Core | [Core preferences service](core-preferences.md) |
|
|
60
65
|
| Read complete selected Git text without changing a checkout | [Git text snapshots](git-text-snapshot.md) |
|
|
@@ -223,6 +228,8 @@ Ollama, Wllama, Whisper, Kokoro, native, or cloud transport:
|
|
|
223
228
|
| Run a caller-selected GGUF LLM locally | [`arcane-os/ai/browser-wasm`](ai/browser-wasm.md) | Browser secure context with WebAssembly and OPFS/DBOPFS; explicit CPU selection or WebGPU with full offload and no automatic CPU fallback. |
|
|
224
229
|
| Run application-selected native llama.cpp/Ollama chat | [`arcane-os/ai/core-local`, `arcane-os/core/local-ai`](local-ai.md) | Explicit Core connection and selected native runtimes; installation, availability and loaded-model readiness remain distinct. |
|
|
225
230
|
| Run a local ONNX graph with named tensors | [`arcane-os/local-ai/onnx`, `arcane-os/ai/core-onnx`](local-ai.md#native-onnx-sessions) | Retained native workers; browser access requires an available Core ONNX service. |
|
|
231
|
+
| Generate local images from complete prompts and selected model resources | [`arcane-os/local-ai/image`, `arcane-os/ai/core-image`](local-image-generation.md) | Prepared native image runtime; browser access requires its Core service. CPU Windows/Linux and Mac Metal/CPU paths have distinct actual host requirements. |
|
|
232
|
+
| Supply complete stored model members to a native engine | [`arcane-os/ai/core-model-assets`, `arcane-os/core/model-assets`](model-assets.md) | Available Core service; DBOPFS originals stay authoritative while native owners retain working files. |
|
|
226
233
|
| Run caller-selected Whisper/Kokoro locally | [`arcane-os/ai/browser-speech`](ai/browser-speech.md) | Browser with DBOPFS, Web Locks, Workers and selected upstream sources; automatic WebNN NPU, WebGPU, then WASM loading, or an explicit backend. |
|
|
227
234
|
| Use native browser recognition/voices or selected cloud TTS | [Speech provider choices](ai/browser-speech.md) | Native APIs depend on the browser and may use remote services; cloud TTS requires the application key and endpoint access. |
|
|
228
235
|
| Send complete chat, System One or image requests without retained history | [`arcane-os/ai/twin-cloud`](ai/twin-cloud.md) | Node or browser with Fetch and explicit model/credentials; image results contain every returned image as a Blob. |
|
package/docs/reference/cli.md
CHANGED
|
@@ -49,7 +49,7 @@ meaning and cardinality rules:
|
|
|
49
49
|
| `--app` | app id or label | Workspace/app operations except shared scope and `verify-bundle`; optional diagnostic label for `mail serve`. |
|
|
50
50
|
| `--apps-root` | `.` or `apps` | `new`, `init`; standalone setup defaults to the repository root. |
|
|
51
51
|
| `--sdk-runtime-source` | SDK checkout directory | `dev` only; maps live SDK source through the selected browser destinations for that server process. |
|
|
52
|
-
| `--local-ai` | comma-separated runtime IDs | `dev` only; adds `llama.cpp`, `ollama` and/or `
|
|
52
|
+
| `--local-ai` | comma-separated runtime IDs | `dev` only; adds `llama.cpp`, `ollama`, `onnx` and/or `stable-diffusion.cpp` requirements to application configuration and prepares missing runtimes alongside serving. See [local AI through Core](local-ai.md). |
|
|
53
53
|
| `--arcane-root` | directory | `doctor`, native `build`/`run`, `native-doctor`, `native-prepare` |
|
|
54
54
|
| `--host` / `--port` | host / integer 0–65535 | Browser `dev`/`run` default to HTTPS at `127.0.0.1:8000`; `mail serve` defaults to HTTPS with HTTP/2 at `0.0.0.0:4433` and accepts an explicit bind host. |
|
|
55
55
|
| `--http-port` | integer 0–65535 | Browser `dev`/`run` HTTP redirect listener; defaults to `0`, which selects an available port. |
|
|
@@ -375,6 +375,10 @@ arcane dev [--app <id>] [--public] [--http | --https] [--cert <file> --key <file
|
|
|
375
375
|
reuse them. Available services and executables are reused; missing runtimes
|
|
376
376
|
are installed inside the application while serving starts independently.
|
|
377
377
|
Applications choose their model files and optional browser Core connection.
|
|
378
|
+
`--local-ai stable-diffusion.cpp` prepares the selected native image runtime;
|
|
379
|
+
configure its `models` separately in the application's runtime record.
|
|
380
|
+
The [image service](local-image-generation.md) reports installation and model
|
|
381
|
+
readiness independently, with complete PNG results and explicit cancellation.
|
|
378
382
|
See [local AI through Core](local-ai.md) for configuration and native bundling.
|
|
379
383
|
|
|
380
384
|
### Lifecycle
|
|
@@ -67,7 +67,7 @@ current dispatcher and service state for a newly connected document, without
|
|
|
67
67
|
restarting services. Repeated `connect()` calls on the same connection do not
|
|
68
68
|
send another replay. See [runtime replay](core-runtime.md#state-and-frames).
|
|
69
69
|
|
|
70
|
-
`client.invoke(method, parameters, {signal, timeoutMs})` returns the actual
|
|
70
|
+
`client.invoke(method, parameters, {signal, timeoutMs, onRequest})` returns the actual
|
|
71
71
|
response result or rejects with `CoreError`. Parameters, result fields and
|
|
72
72
|
event data retain their complete supplied content. JSON encoding belongs only
|
|
73
73
|
to transports that require it; values crossing those transports must be
|
|
@@ -77,6 +77,14 @@ The compatibility facade retains its operation-specific timeouts and streaming
|
|
|
77
77
|
callbacks. Streaming IDs and isolated-operation IDs are separate protocol
|
|
78
78
|
correlation fields alongside the supplied request fields.
|
|
79
79
|
|
|
80
|
+
The optional `onRequest({requestId})` observer runs synchronously after the
|
|
81
|
+
client owns the request and before transport dispatch. It exposes the actual
|
|
82
|
+
Core correlation ID without adding fields to the supplied payload. A
|
|
83
|
+
pre-aborted request never calls the observer. A synchronous observer failure
|
|
84
|
+
rejects the request before sending; a returned promise is observed for errors
|
|
85
|
+
without delaying dispatch. If the observer cancels or closes the request,
|
|
86
|
+
the client does not subsequently send it.
|
|
87
|
+
|
|
80
88
|
`Arcane.speech.synthesize(request, {signal})` forwards the optional cancellation
|
|
81
89
|
signal through the same request lifetime. Existing one-argument calls retain
|
|
82
90
|
the 180,000 ms timeout and pass the complete request unchanged. A pre-aborted
|
|
@@ -87,12 +95,13 @@ registered speech service and its engine; the facade supplies no speech engine.
|
|
|
87
95
|
call and normalizes cancellation to `AbortError` with
|
|
88
96
|
`ARCANE_AI_REQUEST_ABORTED`, preserving the original error as its cause.
|
|
89
97
|
|
|
90
|
-
`Arcane.speech.transcribe(request, {signal})` forwards cancellation through the
|
|
98
|
+
`Arcane.speech.transcribe(request, {signal, onRequest})` forwards cancellation through the
|
|
91
99
|
same request lifetime and retains its 180,000 ms timeout and complete request.
|
|
92
100
|
`AI.fetchSTT(audio, signal)` carries that signal into the native call. A
|
|
93
101
|
pre-aborted signal sends no transcription request; an in-flight abort sends
|
|
94
102
|
`request.cancel` and suppresses late responses. The registered transcription
|
|
95
103
|
service owns interruption and release of its actual engine operation.
|
|
104
|
+
Its optional request observer uses the same pre-dispatch correlation contract.
|
|
96
105
|
|
|
97
106
|
## Current-window theme
|
|
98
107
|
|
|
@@ -248,8 +248,9 @@ to the artifact root. Only the explicitly configured entry imports
|
|
|
248
248
|
`createLocalAIService` from `arcane-os/core/local-ai`. It resolves those bundled
|
|
249
249
|
locations against the installed artifact and supplies them in the launch
|
|
250
250
|
context's `runtimes` array, alongside `appRoot`, before applying explicit launch
|
|
251
|
-
configuration. It passes
|
|
252
|
-
|
|
251
|
+
configuration. It passes chat/ONNX requirements to that factory and routes
|
|
252
|
+
selected image requirements to their separate service as described below.
|
|
253
|
+
Applications without that selection have no generated local-AI import
|
|
253
254
|
or service. Availability of a particular engine belongs to the selected
|
|
254
255
|
local-AI installer and service; a generic ONNX runtime is not a speech model.
|
|
255
256
|
|
|
@@ -260,6 +261,42 @@ service exposes retained worker sessions through `onnx.load/run/unload/status`;
|
|
|
260
261
|
model files remain caller-selected application resources. See
|
|
261
262
|
[native ONNX sessions](local-ai.md#native-onnx-sessions).
|
|
262
263
|
|
|
264
|
+
Selected `stable-diffusion.cpp` additionally composes
|
|
265
|
+
`createLocalImageService` from `arcane-os/core/image` and one shared
|
|
266
|
+
`createModelAssetService` from `arcane-os/core/model-assets`. The image factory
|
|
267
|
+
receives the full authored selection plus that same model-assets instance.
|
|
268
|
+
Library, Koffi binding and variant paths resolve from the artifact root;
|
|
269
|
+
ordinary browser imports use `arcane-os/ai/core-image` and
|
|
270
|
+
`arcane-os/ai/core-model-assets` through the managed import map.
|
|
271
|
+
|
|
272
|
+
The runtime bundle preserves the complete selected native distribution and
|
|
273
|
+
binding tree. It does not load or download a model. Original model URL
|
|
274
|
+
descriptors remain available for preparation after launch; runtime-contained
|
|
275
|
+
model paths relocate with the artifact. An external native working path
|
|
276
|
+
reports its portability incompatibility. Supply those files through the
|
|
277
|
+
application's native resources or the shared
|
|
278
|
+
[stored-model projection](model-assets.md). Native use retains that projection
|
|
279
|
+
until actual unload or shutdown completes. See
|
|
280
|
+
[local image generation](local-image-generation.md) for selection, complete
|
|
281
|
+
results and CPU/Metal platform boundaries.
|
|
282
|
+
|
|
283
|
+
### Injected native speech engines
|
|
284
|
+
|
|
285
|
+
An application-owned service factory can return
|
|
286
|
+
`createSpeechService({stt,tts,signal})` from `arcane-os/core/speech`, supplying
|
|
287
|
+
either role or both. Include that factory through the existing
|
|
288
|
+
`native.services` and `package.nativeResources` composition above. The host
|
|
289
|
+
constructs its selected engines; this shared service installs no engine,
|
|
290
|
+
downloads no model and selects no browser or native speech default.
|
|
291
|
+
|
|
292
|
+
Core starts both configured role loads independently and remains responsive.
|
|
293
|
+
`speech.status` and replaying service subscriptions report actual loaded-model
|
|
294
|
+
state separately for transcription and synthesis. Complete requests/results
|
|
295
|
+
are forwarded unchanged. Request cancellation reaches its engine independently
|
|
296
|
+
of the service lifetime; `close`/`drain` abort and join both engines and their
|
|
297
|
+
pending work. Engines must settle cancelled inference before Core reaches
|
|
298
|
+
service cleanup. See the [engine interface, progress and shutdown contract](native-speech.md).
|
|
299
|
+
|
|
263
300
|
## Windows executable
|
|
264
301
|
|
|
265
302
|
The ordinary application command is:
|
|
@@ -293,12 +330,24 @@ host output; downstream applications use the published package and matching
|
|
|
293
330
|
release asset. `doctor()` reports the selected prerequisites and missing files;
|
|
294
331
|
it does not download the host or probe the installed WebView runtime.
|
|
295
332
|
|
|
296
|
-
The assembled directory contains
|
|
297
|
-
|
|
298
|
-
|
|
333
|
+
The assembled directory contains the app-named launcher, its matching
|
|
334
|
+
`.exe.config`, the unchanged `app/` payload, Core runtime and semantic
|
|
335
|
+
`arcane-native.json`. `manifest.host.executable` is the authoritative relative
|
|
336
|
+
launcher name for shortcuts and direct launch. Assembly uses
|
|
337
|
+
`appDescriptor.displayName` plus `.exe`, such as `Moon Cheese Hotline.exe`;
|
|
338
|
+
low-level compositions without a nonempty string display name use the app ID.
|
|
339
|
+
Windows-reserved filename characters and controls become underscores, and
|
|
340
|
+
reserved DOS device basenames receive an underscore prefix. Supported Unicode,
|
|
341
|
+
case and spaces remain; the original descriptor and title are unchanged.
|
|
342
|
+
The reusable host archive/cache retains `Arcane.exe` and `Arcane.exe.config`;
|
|
343
|
+
the internal `runtime/ArcaneCore.exe` also keeps its original name.
|
|
344
|
+
|
|
345
|
+
Launch the manifest-selected executable on Windows x64 with the Microsoft
|
|
346
|
+
Edge WebView2 Runtime installed. It opens the selected
|
|
299
347
|
app in WebView2 and owns its framed connection to the bundled Core process.
|
|
300
348
|
`verify()` observes the assembled files and manifest; it does not execute the
|
|
301
|
-
window or prove application behavior. `run()`
|
|
349
|
+
window or prove application behavior. `run()` reads the saved manifest and
|
|
350
|
+
launches that executable, so existing generic-name artifacts remain usable. It
|
|
302
351
|
observes complete diagnostics and exit. Cancelling that operation closes its
|
|
303
352
|
input, allowing the window and accepted Core service work to drain without a
|
|
304
353
|
forced process termination.
|
|
@@ -311,7 +360,7 @@ into a derived `runtime/arcane-app.ico` with 16, 32, 48 and 256-pixel images.
|
|
|
311
360
|
Aspect ratio and transparency are preserved. An ICO selection keeps its
|
|
312
361
|
authored image set. The original application asset remains unchanged.
|
|
313
362
|
|
|
314
|
-
The provider embeds the selected images in the copied
|
|
363
|
+
The provider embeds the selected images in the copied app-named executable and records
|
|
315
364
|
`manifest.host.icon` and `manifest.host.executableIcon:true`. It replaces the
|
|
316
365
|
executable's main icon group while preserving other groups, languages, resources
|
|
317
366
|
and file content. Conversion uses Node standard capabilities on every assembly
|
|
@@ -370,7 +419,7 @@ for the facade and browser behavior.
|
|
|
370
419
|
For explicit user-selected workspace/state locations, launch:
|
|
371
420
|
|
|
372
421
|
```sh
|
|
373
|
-
|
|
422
|
+
"Moon Cheese Hotline.exe" --arcane-launch-config path/to/launch.json
|
|
374
423
|
```
|
|
375
424
|
|
|
376
425
|
The complete JSON object reaches the service factories as their second
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Native repository workspaces
|
|
2
|
+
|
|
3
|
+
`arcane-os/core/repositories` owns a persistent native location for connected
|
|
4
|
+
repositories, separate from application code and application preferences.
|
|
5
|
+
Applications choose their connection names, remotes, branches, files and Core
|
|
6
|
+
methods. Importing the module and constructing an owner perform no I/O.
|
|
7
|
+
|
|
8
|
+
## Persistent locations
|
|
9
|
+
|
|
10
|
+
`resolveArcaneDataPaths({dataRoot}={})` returns absolute
|
|
11
|
+
`{dataRoot,repositoriesRoot}` paths without creating directories:
|
|
12
|
+
|
|
13
|
+
| Host | Default dataRoot | repositoriesRoot |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| Windows | `%LOCALAPPDATA%/ArcaneData`, or `~/AppData/Local/ArcaneData` when that variable is empty | `<dataRoot>/Repos` |
|
|
16
|
+
| Linux | `$XDG_DATA_HOME/ArcaneData` when XDG_DATA_HOME is absolute, otherwise `~/.local/share/ArcaneData` | `<dataRoot>/Repos` |
|
|
17
|
+
| macOS | `~/Library/Application Support/ArcaneData` | `<dataRoot>/Repos` |
|
|
18
|
+
| Android or another adapted host | Explicit `dataRoot` supplied by the host, such as its app files directory followed by `ArcaneData` | `<dataRoot>/Repos` |
|
|
19
|
+
|
|
20
|
+
An explicit `dataRoot` selects that directory directly; the SDK does not append
|
|
21
|
+
another `ArcaneData`. Relative explicit paths resolve from the process working
|
|
22
|
+
directory. Unsupported default platforms report `ARCANE_DATA_ROOT_REQUIRED`.
|
|
23
|
+
The Android host also supplies Git/process execution through the existing
|
|
24
|
+
process-adapter contract; this module does not install Git or choose shared
|
|
25
|
+
Android storage.
|
|
26
|
+
|
|
27
|
+
The factory's first actual operation creates necessary parent directories.
|
|
28
|
+
No existing data is moved, copied, deleted, renamed or migrated. `appRoot`,
|
|
29
|
+
`stateRoot`, preferences, OPFS and the existing CLI/workspace defaults remain
|
|
30
|
+
independent and unchanged.
|
|
31
|
+
|
|
32
|
+
## One connected working checkout
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
import {createRepositoryWorkspace} from 'arcane-os/core/repositories';
|
|
36
|
+
|
|
37
|
+
const repository = createRepositoryWorkspace({
|
|
38
|
+
name: 'moon-cheese-dispatches',
|
|
39
|
+
remote: applicationConnection.remote,
|
|
40
|
+
branch: applicationConnection.branch
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const opened = await repository.open({signal});
|
|
44
|
+
// opened.directory is <ArcaneData>/Repos/moon-cheese-dispatches.
|
|
45
|
+
const status = await repository.status({signal});
|
|
46
|
+
await repository.close();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`createRepositoryWorkspace({name,directory,dataRoot,remote,branch,onEvent,run}={})`
|
|
50
|
+
returns `{directory,open,status,pull,push,close,drain,dispose}`. The `directory`
|
|
51
|
+
property is the absolute selected working path.
|
|
52
|
+
|
|
53
|
+
- Omit `directory` to select `<repositoriesRoot>/<name>`. The application supplies
|
|
54
|
+
one nonempty directory name for each distinct connection; the SDK neither
|
|
55
|
+
derives it from a remote nor maintains a connection registry. Names are one
|
|
56
|
+
component, excluding `.`/`..` and slash/backslash separators. Choose distinct
|
|
57
|
+
names under the host filesystem's ordinary case rules.
|
|
58
|
+
- Supply `directory` to use an existing application-selected path instead.
|
|
59
|
+
This takes precedence over `name` and `dataRoot`; relative paths resolve from
|
|
60
|
+
the process working directory. The path is not relocated or rewritten.
|
|
61
|
+
- `remote` is required only when a missing or empty destination needs cloning.
|
|
62
|
+
`branch`, when supplied, is passed unchanged to Git's `clone --branch` option;
|
|
63
|
+
otherwise Git selects the remote's default branch. Existing checkouts keep
|
|
64
|
+
their own branch, remote, tracked files, untracked files and local changes.
|
|
65
|
+
- `onEvent` and optional `run` use the existing SDK process owner. The default
|
|
66
|
+
adapter is `runProcess`; Git must be available on PATH. Credentials and
|
|
67
|
+
authentication remain with Git and the native host. The SDK adds no download,
|
|
68
|
+
credential store, polling, network retry or process supervisor.
|
|
69
|
+
|
|
70
|
+
All operation methods accept `{signal}={}` and return promises:
|
|
71
|
+
|
|
72
|
+
| Method | Result and side effect |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `open` | For a missing/empty destination, runs one clone and returns `{directory,cloned:true,stdout,stderr}` with complete process output. For an existing working repository root, returns `{directory,cloned:false}` after read-only inspection. Later opens on that owner reuse preparation. |
|
|
75
|
+
| `status` | Prepares the checkout if needed, then returns the existing `repositoryStatus` result unchanged. |
|
|
76
|
+
| `pull` | Prepares the checkout if needed, then runs the existing clean-checkout, fast-forward-only `repositoryPull` operation unchanged. |
|
|
77
|
+
| `push` | Prepares the checkout if needed, then runs the existing `repositoryPush` operation unchanged, preserving its support for unrelated uncommitted working files. |
|
|
78
|
+
| `close`, `drain`, `dispose` | The same idempotent operation: stop accepting new calls and await accepted work and its process/event cleanup. They retain the repository on disk. |
|
|
79
|
+
|
|
80
|
+
Opening an existing repository never pulls, switches branches, resets, changes
|
|
81
|
+
its remote or rewrites files. A nonempty destination that is a bare repository,
|
|
82
|
+
a subdirectory of another checkout, or ordinary non-repository data is left
|
|
83
|
+
untouched and reports its Git error or `ARCANE_REPOSITORY_DIRECTORY_INVALID`.
|
|
84
|
+
A failed or cancelled clone reports the actual failure; any remaining directory
|
|
85
|
+
is retained for application-owned inspection. There is no automatic deletion or
|
|
86
|
+
destructive retry. Filesystem failures and complete Git diagnostics propagate.
|
|
87
|
+
|
|
88
|
+
## Ownership, concurrency and shutdown
|
|
89
|
+
|
|
90
|
+
Calls targeting the same resolved path spelling in one Node process run in
|
|
91
|
+
acceptance order, including separate owners selecting that path. Windows keys
|
|
92
|
+
are case-insensitive. The queue does not resolve symlink aliases or macOS case
|
|
93
|
+
variants; applications use one consistent path for a shared connection.
|
|
94
|
+
This prevents overlapping Git/index writes and duplicate successful cloning.
|
|
95
|
+
Different directories proceed
|
|
96
|
+
independently. Applications coordinate separate processes and their own direct
|
|
97
|
+
file/Git writes; this module does not create a daemon or cross-process lock.
|
|
98
|
+
|
|
99
|
+
A pre-aborted call starts no work. A queued aborted operation does not run when
|
|
100
|
+
its turn arrives. Active cancellation reaches the existing process owner, which
|
|
101
|
+
terminates its owned process tree and joins complete output/event cleanup.
|
|
102
|
+
Shutdown drains accepted operations rather than deleting data or terminating
|
|
103
|
+
the host early. Calls after close reject with `CORE_CLOSING`; a failed operation
|
|
104
|
+
still pending when close begins rejects that drain through an `AggregateError`.
|
|
105
|
+
The caller retains each operation's complete result or failure separately.
|
|
106
|
+
|
|
107
|
+
The cold path is one selected connection, one parent-directory creation and one
|
|
108
|
+
Git clone. Opening an existing checkout uses one read-only Git command. A
|
|
109
|
+
prepared owner's status/pull/push use their existing repository operation graph.
|
|
110
|
+
There is no scan across applications, connections, models or platforms. Git
|
|
111
|
+
progress, process-starting/completion, heartbeat and cancellation events use
|
|
112
|
+
the existing `onEvent` owner with complete output and backpressure.
|
|
113
|
+
An awaited event callback must not await another operation or shutdown for the
|
|
114
|
+
same directory, including calls through another workspace owner: that operation
|
|
115
|
+
needs the observing callback to finish. Schedule such follow-up without awaiting
|
|
116
|
+
it inside that callback, and retain/observe its promise at the application owner.
|
|
117
|
+
|
|
118
|
+
Compose this owner inside an application-selected Core service. Bind only the
|
|
119
|
+
application's chosen methods, pass each request's `context.signal`, and return
|
|
120
|
+
`drain: repository.drain` and `dispose: repository.dispose` from that service.
|
|
121
|
+
Keep initialization at the repository operation that needs it; page rendering
|
|
122
|
+
and unrelated services do not wait for a clone. This module installs no browser
|
|
123
|
+
RPC, chooses no application service and changes no Core launch configuration.
|
|
124
|
+
|
|
125
|
+
## Bare snapshots stay separate
|
|
126
|
+
|
|
127
|
+
[`createGitTextSnapshot`](git-text-snapshot.md) continues to require its explicit
|
|
128
|
+
dedicated bare `cacheDirectory`. It neither becomes a working checkout nor
|
|
129
|
+
changes existing callers' caches. A new native caller can place that distinct
|
|
130
|
+
cache under the shared location without changing the snapshot contract:
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
import path from 'node:path';
|
|
134
|
+
import {createGitTextSnapshot} from 'arcane-os';
|
|
135
|
+
import {resolveArcaneDataPaths} from 'arcane-os/core/repositories';
|
|
136
|
+
|
|
137
|
+
const {repositoriesRoot} = resolveArcaneDataPaths();
|
|
138
|
+
const snapshot = createGitTextSnapshot({
|
|
139
|
+
cacheDirectory: path.join(repositoriesRoot, 'moon-cheese-reader-cache'),
|
|
140
|
+
remote: applicationConnection.remote,
|
|
141
|
+
ref: applicationConnection.ref,
|
|
142
|
+
selectPath: applicationSelectPath
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Never assign the same directory to a bare snapshot and a writable workspace.
|
|
147
|
+
Applications retain remote/ref selection, document parsing, scores, messages,
|
|
148
|
+
saved connection state and refresh policy. Existing explicit repository paths
|
|
149
|
+
continue to operate where they already are.
|