arcane-os 0.63.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +1 -1
  3. package/browser-runtime/core/client.mjs +7 -2
  4. package/docs/reference/README.md +2 -0
  5. package/docs/reference/core-client.md +11 -2
  6. package/docs/reference/core-native-packaging.md +35 -6
  7. package/docs/reference/core-repositories.md +149 -0
  8. package/docs/reference/inventory/package-api.json +59 -3
  9. package/docs/reference/local-ai.md +5 -2
  10. package/docs/reference/local-image-flux.md +1 -1
  11. package/docs/reference/local-image-generation.md +6 -0
  12. package/docs/reference/local-image-sdxl.md +139 -0
  13. package/docs/reference/local-whisper.md +219 -0
  14. package/docs/reference/native-speech.md +51 -2
  15. package/docs/reference/runtime-modules.md +16 -2
  16. package/docs/reference/sdk-api.md +162 -2
  17. package/package.json +4 -1
  18. package/runtime/arcane/components/speech.html +15 -3
  19. package/runtime/arcane/components/voice-transcription.html +19 -3
  20. package/runtime/arcane/modules/AI.js +250 -27
  21. package/runtime/arcane/modules/AIProviderRuntime.js +20 -3
  22. package/runtime/arcane/modules/AIRuntimeState.js +15 -2
  23. package/runtime/arcane/modules/ComponentContracts.js +3 -0
  24. package/schemas/arcane-app.schema.json +53 -2
  25. package/schemas/arcane-package.schema.json +53 -2
  26. package/src/core/repositories.mjs +210 -0
  27. package/src/core/services/speech.mjs +1 -0
  28. package/src/local-ai/config.mjs +7 -3
  29. package/src/local-ai/dev.mjs +32 -2
  30. package/src/local-ai/image-library.mjs +9 -0
  31. package/src/local-ai/image-models/sdxl.mjs +18 -0
  32. package/src/local-ai/install.mjs +26 -7
  33. package/src/local-ai/whisper/build.mjs +48 -0
  34. package/src/local-ai/whisper/config.mjs +61 -0
  35. package/src/local-ai/whisper/index.mjs +515 -0
  36. package/src/local-ai/whisper/install.mjs +274 -0
  37. package/src/local-ai/whisper/native/CMakeLists.txt +98 -0
  38. package/src/local-ai/whisper/native/NOTICE +18 -0
  39. package/src/local-ai/whisper/native/README.md +104 -0
  40. package/src/local-ai/whisper/native/main.cpp +489 -0
  41. package/src/native/portable-layout.mjs +37 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
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
+
3
25
  ## 0.63.0
4
26
 
5
27
  - Add the approved FLUX.2 Klein 4B text-to-image model descriptor to the
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.63.0` SDK contract. Development applications declare
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),
@@ -56,6 +56,8 @@ alone does not make bare module names resolve in a browser.
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
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) |
59
61
  | Edit an original PNG with a complete prompt and explicit strength | [Local image editing](local-image-editing.md) |
60
62
  | Project complete stored model files into native working files | [Model assets through Core](model-assets.md) |
61
63
  | Retain a Nemotron model and diarize caller-fed audio streams | [Native speaker diarization](diarization.md) |
@@ -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
 
@@ -280,6 +280,23 @@ until actual unload or shutdown completes. See
280
280
  [local image generation](local-image-generation.md) for selection, complete
281
281
  results and CPU/Metal platform boundaries.
282
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
+
283
300
  ## Windows executable
284
301
 
285
302
  The ordinary application command is:
@@ -313,12 +330,24 @@ host output; downstream applications use the published package and matching
313
330
  release asset. `doctor()` reports the selected prerequisites and missing files;
314
331
  it does not download the host or probe the installed WebView runtime.
315
332
 
316
- The assembled directory contains `Arcane.exe`, the unchanged `app/` payload,
317
- Core runtime and semantic `arcane-native.json`. Launch `Arcane.exe` on Windows
318
- x64 with the Microsoft Edge WebView2 Runtime installed. It opens the selected
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
319
347
  app in WebView2 and owns its framed connection to the bundled Core process.
320
348
  `verify()` observes the assembled files and manifest; it does not execute the
321
- window or prove application behavior. `run()` launches the executable and
349
+ window or prove application behavior. `run()` reads the saved manifest and
350
+ launches that executable, so existing generic-name artifacts remain usable. It
322
351
  observes complete diagnostics and exit. Cancelling that operation closes its
323
352
  input, allowing the window and accepted Core service work to drain without a
324
353
  forced process termination.
@@ -331,7 +360,7 @@ into a derived `runtime/arcane-app.ico` with 16, 32, 48 and 256-pixel images.
331
360
  Aspect ratio and transparency are preserved. An ICO selection keeps its
332
361
  authored image set. The original application asset remains unchanged.
333
362
 
334
- The provider embeds the selected images in the copied `Arcane.exe` and records
363
+ The provider embeds the selected images in the copied app-named executable and records
335
364
  `manifest.host.icon` and `manifest.host.executableIcon:true`. It replaces the
336
365
  executable's main icon group while preserving other groups, languages, resources
337
366
  and file content. Conversion uses Node standard capabilities on every assembly
@@ -390,7 +419,7 @@ for the facade and browser behavior.
390
419
  For explicit user-selected workspace/state locations, launch:
391
420
 
392
421
  ```sh
393
- Arcane.exe --arcane-launch-config path/to/launch.json
422
+ "Moon Cheese Hotline.exe" --arcane-launch-config path/to/launch.json
394
423
  ```
395
424
 
396
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.
@@ -1,17 +1,73 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "sdkVersion": "0.62.0",
3
+ "sdkVersion": "0.63.0",
4
4
  "environment": {
5
5
  "runtime": "Node.js for Node entrypoints; browser for browser-only entrypoints",
6
6
  "minimumVersion": "22.23.2 for Node entrypoints",
7
7
  "moduleSystem": "ESM"
8
8
  },
9
- "memberCount": 274,
9
+ "memberCount": 278,
10
10
  "runtimeSubpathPatterns": {
11
11
  "arcane-os/modules/*": "./runtime/arcane/modules/*",
12
12
  "arcane-os/entities/*": "./runtime/arcane/entities/*"
13
13
  },
14
14
  "members": [
15
+ {
16
+ "id": "core-repositories:resolveArcaneDataPaths",
17
+ "name": "resolveArcaneDataPaths",
18
+ "displayName": "resolveArcaneDataPaths()",
19
+ "kind": "function",
20
+ "signature": "resolveArcaneDataPaths({dataRoot}={})",
21
+ "entrypoints": ["arcane-os/core/repositories"],
22
+ "primaryImport": "arcane-os/core/repositories",
23
+ "group": "Native repository workspaces",
24
+ "summary": "Resolves persistent per-user ArcaneData and Repos locations without I/O or migration.",
25
+ "availability": "Node on Windows, Linux and macOS; Android supplies its persistent dataRoot",
26
+ "protocol": "Native filesystem paths",
27
+ "normalization": "Returns absolute dataRoot and repositoriesRoot; explicit dataRoot takes precedence, otherwise uses LocalAppData, XDG data home or user Application Support. Changes no launch, preference, workspace or user data."
28
+ },
29
+ {
30
+ "id": "core-repositories:createRepositoryWorkspace",
31
+ "name": "createRepositoryWorkspace",
32
+ "displayName": "createRepositoryWorkspace()",
33
+ "kind": "function",
34
+ "signature": "createRepositoryWorkspace({name,directory,dataRoot,remote,branch,onEvent,run=runProcess}={})",
35
+ "entrypoints": ["arcane-os/core/repositories"],
36
+ "primaryImport": "arcane-os/core/repositories",
37
+ "group": "Native repository workspaces",
38
+ "summary": "Owns one selected native working checkout with ArcaneData/Repos defaults and existing Git/process lifecycle.",
39
+ "availability": "Node with Git on Windows, Linux and macOS; Android requires host process adaptation",
40
+ "protocol": "Git working repository and SDK process adapter",
41
+ "normalization": "Returns directory, open, status, pull, push and identical close/drain/dispose hooks. Only missing or empty destinations clone; existing roots are inspected without rewriting, resetting or pulling. Explicit paths remain selected. Same-directory operations serialize within the process; cancellation and shutdown join accepted process work."
42
+ },
43
+ {
44
+ "id": "core-speech:createSpeechService",
45
+ "name": "createSpeechService",
46
+ "displayName": "createSpeechService()",
47
+ "kind": "function",
48
+ "signature": "createSpeechService({stt,tts,signal}={})",
49
+ "entrypoints": ["arcane-os/core/speech"],
50
+ "primaryImport": "arcane-os/core/speech",
51
+ "group": "Core native speech",
52
+ "summary": "Composes host-supplied transcription and synthesis engines with independent loading and role readiness.",
53
+ "availability": "Node Core with explicitly supplied engines; engine platform, model and format support remain engine-owned",
54
+ "protocol": "arcane/1 speech.status/transcribe/synthesize with speech.state/progress",
55
+ "normalization": "Returns current/subscribe/close/start/methods/drain/dispose; forwards complete requests and results unchanged; replaying service state, synchronous accepted Thinking, combined request/lifetime cancellation and concurrent joined engine shutdown; no engine installation or automatic provider selection"
56
+ },
57
+ {
58
+ "id": "core-speech:default",
59
+ "name": "default",
60
+ "displayName": "createSpeechService default export",
61
+ "kind": "function",
62
+ "signature": "default as createSpeechService",
63
+ "entrypoints": ["arcane-os/core/speech"],
64
+ "primaryImport": "arcane-os/core/speech",
65
+ "group": "Core native speech",
66
+ "summary": "Default binding for the same injected-engine native speech service factory.",
67
+ "availability": "Node Core with host-supplied engines",
68
+ "protocol": "arcane/1 service definition",
69
+ "normalization": "Binding identity equals the named createSpeechService export"
70
+ },
15
71
  {
16
72
  "id": "local-ai-image:createImageRuntime",
17
73
  "name": "createImageRuntime",
@@ -4150,7 +4206,7 @@
4150
4206
  "summary": "Assembles selected application services and browser content with the SDK-owned Windows x64 WebView2 and SEA host.",
4151
4207
  "availability": "Node for assembly; Windows x64 with WebView2 Runtime for execution",
4152
4208
  "protocol": "arcane-native-builder/1 windows-x64 provider",
4153
- "normalization": "Uses a selected hostDirectory or the exact installed SDK version's numeric release asset; preserves complete payloads; native.icon PNG/ICO derives the copied executable and host.icon without an app compiler, while other formats retain assembly with native.icon.unsupported and executableIcon:false; the matching host loads the selected window/taskbar icon and handles window.setTheme with per-field applied/unsupported results; run cancellation closes stdin and waits for host-owned graceful shutdown"
4209
+ "normalization": "Uses a selected hostDirectory or the exact installed SDK version's numeric release asset; preserves complete payloads; app displayName plus .exe (app ID fallback) and matching .exe.config use Windows filename substitutions only; manifest.host.executable owns inventory, icon, verify and run while generic cache/Core names remain unchanged; native.icon PNG/ICO derives the copied executable and host.icon without an app compiler, while other formats retain assembly with native.icon.unsupported and executableIcon:false; the matching host loads the selected window/taskbar icon and handles window.setTheme with per-field applied/unsupported results; run cancellation closes stdin and waits for host-owned graceful shutdown"
4154
4210
  },
4155
4211
  {
4156
4212
  "id": "native-windows-provider:arcaneNativeBuilderProvider",
@@ -43,14 +43,17 @@ preserved when its version cannot be established.
43
43
 
44
44
  Both public application/package schemas accept `stable-diffusion.cpp` as a
45
45
  string or runtime-record ID. Its record additionally accepts `backend`
46
- (`auto`, `cpu` or `metal`) and `models`, an array of `sd14` or complete model
47
- descriptors. Omitted image version selects `master-929-3f8527a`; omitted backend
46
+ (`auto`, `cpu` or `metal`) and `models`, an array of `sd14`, `flux2-klein-4b` or
47
+ complete model descriptors. Omitted image version selects `master-929-3f8527a`; omitted backend
48
48
  selects `auto`; omitted models leaves model selection empty. Windows/Linux
49
49
  distribution defaults use CPU; the selected universal Mac archive supports
50
50
  Metal with CPU fallback. Installation obtains the upstream library and its
51
51
  managed `koffi@3.3.2` binding, without installing a model. Complete model
52
52
  descriptors keep their resources, context, defaults and operations separate.
53
53
  See [image selection and model preparation](local-image-generation.md#selection-and-model-assets).
54
+ The [FLUX.2 Klein 4B guide](local-image-flux.md) describes its diffusion model,
55
+ VAE and Qwen text-conditioning resources, four-step defaults and `txt2img`
56
+ operation. Each model retains its own supported operation set.
54
57
 
55
58
  `llamaCpp` accepts `url`, `model`, `modelsDirectory`, and an `args` string array.
56
59
  `model` selects a single GGUF file; `modelsDirectory` selects llama.cpp router
@@ -45,7 +45,7 @@ model pipeline, rather than three independent image generators.
45
45
  | Native role | Resource | Purpose |
46
46
  | --- | --- | --- |
47
47
  | `diffusion_model` | [flux-2-klein-4b.safetensors](https://huggingface.co/black-forest-labs/FLUX.2-klein-4B/resolve/e7b7dc27f91deacad38e78976d1f2b499d76a294/flux-2-klein-4b.safetensors) | Distilled image generation model. |
48
- | `vae` | [full_encoder_small_decoder.safetensors](https://huggingface.co/black-forest-labs/FLUX.2-small-decoder/resolve/a3efc24f613ef42d9428af62fdbd6f5fd8856c4a/full_encoder_small_decoder.safetensors) | Complete image encoder and the smaller FLUX.2 decoder. |
48
+ | `vae` | [`full_encoder_small_decoder.safetensors`](https://huggingface.co/black-forest-labs/FLUX.2-small-decoder/resolve/a3efc24f613ef42d9428af62fdbd6f5fd8856c4a/full_encoder_small_decoder.safetensors) | Complete image encoder and the smaller FLUX.2 decoder. |
49
49
  | `llm` | [Qwen3-4B-Q8_0.gguf](https://huggingface.co/Qwen/Qwen3-4B-GGUF/resolve/bc640142c66e1fdd12af0bd68f40445458f3869b/Qwen3-4B-Q8_0.gguf) | Qwen3-4B text conditioning inside the image engine. |
50
50
 
51
51
  The selected upstream records identify these resources as Apache-2.0. The
@@ -41,6 +41,12 @@ model's resource metadata; runtime installation does not independently download
41
41
  or bundle model files. The shared model asset owner prepares selected browser
42
42
  assets and supplies a Core working projection for native path-based loading.
43
43
 
44
+ `flux2-klein-4b` selects the three-resource distilled FLUX.2 Klein definition.
45
+ Its [family guide](local-image-flux.md) covers diffusion/VAE/Qwen preparation,
46
+ four-step defaults and the advertised `txt2img` operation. Keep each model's
47
+ supported operations distinct: selecting FLUX does not enable reference-image
48
+ editing or imply the same input path as SD1.4 img2img.
49
+
44
50
  The first published distribution path selects CPU on Windows and Linux.
45
51
  On macOS, `auto` selects the same upstream universal runtime's built-in Metal
46
52
  backend, with CPU fallback; explicit `cpu` remains available. A caller-supplied
@@ -0,0 +1,139 @@
1
+ # SDXL Base 1.0 through Core
2
+
3
+ The `sdxl-base-1.0` model definition selects Stability AI's complete SDXL Base
4
+ 1.0 checkpoint for text-to-image generation through the shared
5
+ [local image runtime](local-image-generation.md). Applications supply their
6
+ own complete prompts and own the resulting images and saved associations.
7
+ The model uses the shared retained native context, progress, cancellation
8
+ and complete PNG result contract.
9
+
10
+ ## Model selection
11
+
12
+ Select this runtime record under `native.localAI` in `arcane-app.json`, or
13
+ the corresponding package projection's `localAI` record:
14
+
15
+ ```json
16
+ {
17
+ "runtimes": [
18
+ {
19
+ "id": "stable-diffusion.cpp",
20
+ "version": "master-929-3f8527a",
21
+ "backend": "auto",
22
+ "models": ["sdxl-base-1.0"]
23
+ }
24
+ ]
25
+ }
26
+ ```
27
+
28
+ The built-in ID supplies the cohesive `SDXL_BASE_1_0_MODEL` definition from
29
+ `src/local-ai/image-models/sdxl.mjs`. The shared service exposes its resource
30
+ metadata through `image.status` and `images.inspect()`.
31
+
32
+ Backend discovery, accelerated-device selection and CPU fallback belong to
33
+ the shared runtime. This model definition leaves `context` empty and adds no
34
+ device or precision override. Available acceleration depends on the selected
35
+ runtime distribution; see the shared guide's platform availability. Model
36
+ selection alone does not establish actual execution on any device.
37
+
38
+ ## Prepare the checkpoint and generate an image
39
+
40
+ The single `model` resource is the official
41
+ [sd_xl_base_1.0.safetensors checkpoint](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/462165984030d82259a11f4367a4eed129e94a7b/sd_xl_base_1.0.safetensors)
42
+ at revision `462165984030d82259a11f4367a4eed129e94a7b`. It includes the text
43
+ encoders, denoiser and original VAE. Standalone base generation uses this one
44
+ resource; a refiner, separate VAE, LoRA or Python converter is unnecessary for
45
+ this selection. The upstream model carries the
46
+ [CreativeML Open RAIL++-M license](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/462165984030d82259a11f4367a4eed129e94a7b/LICENSE.md).
47
+
48
+ The existing DBOPFS model store owns the authoritative download. The shared
49
+ [model-assets service](model-assets.md) prepares complete native working files
50
+ when the application loads the model. Installing the native runtime does not
51
+ download a second model copy.
52
+
53
+ This example extends the shared generation guide. It uses an existing `images`
54
+ accessor, DBOPFS-backed `modelStore`, application-selected `workingDirectory`
55
+ and request `signal`:
56
+
57
+ ```javascript
58
+ import {createBrowserModelSource} from 'arcane-os/ai/browser-wasm';
59
+ import {prepareCoreModelAssets} from 'arcane-os/ai/core-model-assets';
60
+
61
+ const selected = (await images.inspect({signal})).models.find(
62
+ function selectedSDXL(model) {
63
+ return model.id === 'sdxl-base-1.0';
64
+ }
65
+ );
66
+ const resource = selected.resources.model;
67
+ const source = createBrowserModelSource({
68
+ id: selected.id,
69
+ files: [{name: resource.filename, url: resource.url}]
70
+ });
71
+ const stored = await modelStore.ensure(source, {signal});
72
+ const projection = await prepareCoreModelAssets({
73
+ workingDirectory,
74
+ members: source.files.map(function workingMember(member, index) {
75
+ return {path: member.name, file: stored.files[index]};
76
+ }),
77
+ signal
78
+ });
79
+
80
+ try {
81
+ await images.load({
82
+ model: selected.id,
83
+ assetProjectionId: projection.id,
84
+ resourcePaths: {model: resource.filename},
85
+ signal
86
+ });
87
+ } finally {
88
+ await projection.release();
89
+ }
90
+
91
+ const result = await images.generate({
92
+ model: selected.id,
93
+ prompt: 'An octopus librarian shelving tiny books inside a glass submarine.',
94
+ signal
95
+ });
96
+ // Display result.images using the shared guide's Blob preview example.
97
+ ```
98
+
99
+ Change the prompt to request another scene. The model defaults to a
100
+ 1024-by-1024 canvas; pass `parameters: {width, height}` to select other native
101
+ dimensions. Display or save every returned image using its actual width and
102
+ height. Each result contains the complete PNG Blob.
103
+
104
+ Successful loading retains the working projection in the native model owner.
105
+ Releasing the caller's preparation handle preserves that native retain.
106
+ Repeated generation reuses the loaded context; unload it when the application
107
+ no longer needs it. Follow the shared lifecycle contract for request
108
+ cancellation, state subscriptions, unloading and accessor closure.
109
+
110
+ ## Defaults and operation scope
111
+
112
+ Only canvas dimensions are model-specific defaults here. Sampling parameters
113
+ remain owned by the selected native engine and can be supplied through
114
+ `parameters.sample_params`. At `master-929-3f8527a`, SDXL resolves the native
115
+ default sampler to Euler A and scheduler to discrete, with 20 steps and CFG 7.
116
+ These are native defaults; Stability AI's separate base-plus-refiner example
117
+ and Python pipeline have their own sampling configuration.
118
+
119
+ The selected engine has an explicit path for SDXL's embedded original VAE,
120
+ including its native convolution scaling. The model definition leaves that
121
+ treatment with the engine and supplies no guessed weight-type override or
122
+ separate VAE checkpoint. Output quality, speed and device behavior depend on
123
+ the actual selected runtime and generation parameters.
124
+
125
+ The SDK forwards the complete caller prompt to the native API. The engine
126
+ applies its own text conditioning and prompt-weighting syntax; see the shared
127
+ guide for native string-boundary limitations. The SDK adds no avatar wording,
128
+ style instructions or application-specific content.
129
+
130
+ This definition advertises `txt2img`. Whole-image editing, masked editing and
131
+ reference-image editing are separate operations with their own model and
132
+ runtime requirements. This base selection does not advertise those operations.
133
+
134
+ The model resource and standalone use follow the
135
+ [official model card](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/462165984030d82259a11f4367a4eed129e94a7b/README.md).
136
+ Native defaults and embedded-VAE behavior follow the selected engine's
137
+ [request implementation](https://github.com/leejet/stable-diffusion.cpp/blob/master-929-3f8527a/src/pipeline/request.cpp),
138
+ [parameter initialization](https://github.com/leejet/stable-diffusion.cpp/blob/master-929-3f8527a/src/stable-diffusion.cpp)
139
+ and [model construction](https://github.com/leejet/stable-diffusion.cpp/blob/master-929-3f8527a/src/pipeline/model_builders.cpp).