arcane-os 0.57.0 → 0.59.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 (60) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +6 -2
  3. package/browser-runtime/ai/core-onnx.mjs +96 -0
  4. package/browser-runtime/ai/onnx-tensors.mjs +85 -0
  5. package/browser-runtime/core/client.mjs +152 -17
  6. package/docs/architecture.md +5 -2
  7. package/docs/platform-targets.md +30 -13
  8. package/docs/reference/README.md +22 -3
  9. package/docs/reference/availability-and-normalization.md +14 -7
  10. package/docs/reference/cli.md +22 -10
  11. package/docs/reference/core-client.md +87 -0
  12. package/docs/reference/core-native-packaging.md +129 -9
  13. package/docs/reference/core-preferences.md +49 -0
  14. package/docs/reference/diarization.md +206 -0
  15. package/docs/reference/git-text-snapshot.md +104 -0
  16. package/docs/reference/inventory/package-api.json +205 -23
  17. package/docs/reference/local-ai.md +145 -11
  18. package/docs/reference/protocols.md +28 -19
  19. package/docs/reference/pwa.md +74 -4
  20. package/docs/reference/sdk-api.md +589 -39
  21. package/package.json +11 -3
  22. package/schemas/arcane-app.schema.json +3 -3
  23. package/schemas/arcane-package.schema.json +2 -2
  24. package/schemas/native-build-plan.schema.json +27 -1
  25. package/schemas/target-adapter.schema.json +2 -0
  26. package/src/app-descriptor.mjs +1 -1
  27. package/src/cli/main.mjs +14 -4
  28. package/src/constants.mjs +2 -0
  29. package/src/core/host.mjs +14 -5
  30. package/src/core/hosts/macos/ArcaneHost.h +86 -0
  31. package/src/core/hosts/macos/ArcaneHost.m +455 -0
  32. package/src/core/hosts/macos/ArcaneLauncher.m +432 -0
  33. package/src/core/hosts/windows/ArcaneLauncher.cs +4 -1
  34. package/src/core/services/local-ai.mjs +82 -4
  35. package/src/core/services/packaged-web.mjs +89 -0
  36. package/src/core/services/preferences.mjs +201 -0
  37. package/src/core-classic-source.mjs +2 -2
  38. package/src/dev-server.mjs +2 -5
  39. package/src/diarization/build.mjs +35 -0
  40. package/src/diarization/index.mjs +432 -0
  41. package/src/diarization/native/CMakeLists.txt +9 -0
  42. package/src/diarization/native/main.cpp +269 -0
  43. package/src/diarization/service.mjs +129 -0
  44. package/src/git-text-snapshot.mjs +265 -0
  45. package/src/import-map.mjs +9 -4
  46. package/src/index.mjs +1 -0
  47. package/src/local-ai/config.mjs +1 -1
  48. package/src/local-ai/install.mjs +134 -19
  49. package/src/local-ai/onnx-worker.mjs +85 -0
  50. package/src/local-ai/onnx.mjs +368 -0
  51. package/src/native/macos-provider.mjs +291 -0
  52. package/src/native/portable-layout.mjs +10 -2
  53. package/src/native/portable-provider.mjs +10 -5
  54. package/src/native-plan.mjs +9 -1
  55. package/src/native-provider-loader.mjs +3 -1
  56. package/src/process.mjs +123 -17
  57. package/src/scaffold.mjs +1 -1
  58. package/src/targets/index.mjs +11 -1
  59. package/src/templates/workspace-template.mjs +6 -5
  60. package/src/toolchain.mjs +42 -13
@@ -52,7 +52,13 @@ alone does not make bare module names resolve in a browser.
52
52
  | Call `globalThis.Arcane` | [Arcane Core API](core/arcane-api.md) |
53
53
  | Connect a browser to one Core transport | [Core browser client](core-client.md) |
54
54
  | Compose native Core dispatch, service lifecycle, and stdio hosting | [Native Core runtime](core-runtime.md) |
55
+ | Run application-selected llama.cpp, Ollama or ONNX through Core | [Local AI through Core](local-ai.md) |
56
+ | Retain a Nemotron model and diarize caller-fed audio streams | [Native speaker diarization](diarization.md) |
57
+ | Persist application-selected preferences through Core | [Core preferences service](core-preferences.md) |
58
+ | Read complete selected Git text without changing a checkout | [Git text snapshots](git-text-snapshot.md) |
55
59
  | Build an installed-SDK portable Core payload | [Portable Core packaging](core-native-packaging.md) |
60
+ | Build a Windows executable without an OS checkout | [Windows executable packaging](core-native-packaging.md#windows-executable) |
61
+ | Compose a Mac application with an architecture-matched host | [macOS application composition](core-native-packaging.md#macos-application-composition) |
56
62
  | Subscribe to native events | [Arcane event reference](core/arcane-events.md) |
57
63
  | Use provider-neutral AI lifecycle, chat, speech, persistence, or document context | [Normalized AI](#normalized-ai) |
58
64
  | Choose a normalized typed browser decision surface | [Browser typed decisions](ai/browser-decisions.md) |
@@ -79,9 +85,11 @@ This repository contains explicitly versioned surfaces with different owners:
79
85
 
80
86
  Browser modules and reusable Core client/runtime/lifecycle source belong to the
81
87
  SDK. The portable provider uses this installed package by default and assembles
82
- an app payload with explicitly selected services; it supplies no executable
83
- platform host. Explicit Arcane OS provider overrides and integrated shared
84
- checks remain available. Arcane OS retains its product composition and policy.
88
+ an app payload with explicitly selected services; portable itself supplies no
89
+ executable host. The Windows provider pairs that payload with the installed
90
+ SDK version's precompiled WebView2/SEA release asset. Explicit Arcane OS provider
91
+ overrides and integrated shared checks remain available. Arcane OS retains its
92
+ product composition and policy.
85
93
  The historical Core reference snapshot describes a separate host contract;
86
94
  matching a protocol name or assembling a payload alone does not establish that
87
95
  a composed host supplies every required method or service.
@@ -131,6 +139,15 @@ select a documentation commit whose contracts match the published package.
131
139
  Generated output still belongs to the canonical `site/` tree and requires its
132
140
  usual coordinated output ownership. Generation does not publish hosted Pages.
133
141
 
142
+ For a selected release whose documentation correction lands after unrelated
143
+ source, `createReferenceSite({inputs})` and `writeReferenceSite({inputs})` accept
144
+ one explicit input owner with `readText(relativePath)` and
145
+ `listFiles(relativeDirectory)`. It is shared with the contract extractor. Keep
146
+ package/runtime reads and document discovery on the release commit, and overlay
147
+ only reviewed documentation records from the correction commit. In particular,
148
+ preserve the selected inventory's member set instead of importing later public
149
+ APIs. Omitted `inputs` preserves the live or `sourceRef` behavior above.
150
+
134
151
  ### Historical 0.3.4 publication record
135
152
 
136
153
  The following records describe that earlier release only. They do not identify
@@ -201,6 +218,8 @@ Ollama, Wllama, Whisper, Kokoro, native, or cloud transport:
201
218
  | Offer explicit selected-model start/cancel UI | [`chat.html`](runtime-components.md#chathtml), [`speech.html`](runtime-components.md#speechhtml), and [`voice-transcription.html`](runtime-components.md#voice-transcriptionhtml) | Browser/native WebView components; user activation emits a cancelable request before any LLM or STT load intent, and recording stays disabled without sticky ready STT. |
202
219
  | Use Core-normalized chat | [`globalThis.Arcane.ai`](core/arcane-ai-contracts.md) | Native/Core only when separately admitted. |
203
220
  | 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. |
221
+ | 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. |
222
+ | 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. |
204
223
  | 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. |
205
224
  | 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. |
206
225
  | 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. |
@@ -58,12 +58,12 @@ false when a probe throws; SDK branching continues through its owning error path
58
58
  policy, package-owned model policy, platform support, and dependency readiness
59
59
  are independent checks.
60
60
 
61
- The current executable host/target matrix covers Microsoft NT, Linux, and
62
- Android where listed. This SDK exposes no macOS executable target, native
63
- bridge, artifact, or run contract; WebKitGTK availability must not be
64
- generalized to macOS. The reusable Node Core runtime, framed stdio transport,
65
- host composition, and portable payload can be used by a separately composed
66
- macOS host, but they do not supply that native platform host or bridge.
61
+ Windows x64 and macOS ARM64/x64 have SDK-owned provider and host composition
62
+ source. Their assembly paths require the matching numeric release's native
63
+ host archive; npm publication alone does not supply that archive or establish
64
+ platform execution. The macOS provider composes AppKit, WebKit and the shared
65
+ Node Core payload. Linux and Android retain their explicit checkout providers
66
+ where listed. See [native output and host requirements](core-native-packaging.md).
67
67
 
68
68
  ## Capability-first matrix
69
69
 
@@ -88,7 +88,14 @@ macOS host, but they do not supply that native platform host or bridge.
88
88
  | Read host identity, capabilities, storage, preferences, appearance, or platform state | `globalThis.Arcane` | **Cross-host** where the method is implemented and admitted | Promise behavior and `Arcane.Error` are normalized. Result fields are normalized unless the method explicitly documents a platform-dependent snapshot. |
89
89
  | Connect browser code to an existing Core transport | `arcane-os/core/client` and `arcane-os/core/contracts` | **Browser / native WebView** with an admitted transport; explicit development HTTP remains opt-in | The reusable client owns `arcane/1` correlation, readiness, cancellation, events, facades, and complete native error fidelity. It supplies no service, policy, or host process. |
90
90
  | Compose native Core services and framed stdio hosting | `arcane-os/core/runtime`, `arcane-os/core/stdio`, and `arcane-os/core/host` | **Node** on Windows, Linux, or macOS; the composing native host supplies its process and bridge | The SDK owns reusable dispatch, per-service lifecycle, request/service work ownership, cooperative cancellation, drain, and stdio framing. Product identity, policy, privileges, models, storage, and services remain host-owned. |
91
- | Assemble a portable Core payload from the installed SDK | `arcane-os/native/portable-provider` | **Node**; portable platform selection is currently Windows or Linux, while separately composed hosts may use the payload | The provider copies the selected app, dependencies, installed SDK runtime, Core client/runtime, and explicit service composition into a non-executable directory. It uses no `arcaneRoot` by default and does not prove host behavior or supply a platform bridge. |
91
+ | Assemble a portable Core payload from the installed SDK | `arcane-os/native/portable-provider` | **Node**; explicit Windows, Linux or macOS platform selection | The provider copies the selected app, dependencies, installed SDK runtime, Core client/runtime, and explicit service composition into a non-executable directory. It uses no `arcaneRoot` by default and does not prove host behavior or supply a platform bridge. |
92
+ | Assemble and run a Windows executable | [`arcane-os/native/windows-provider`](core-native-packaging.md#windows-executable) | **Node** for assembly; Windows x64, .NET Framework 4.6.2+ and WebView2 for execution | Uses the installed SDK version's precompiled release asset and explicit app services. Complete diagnostics and accepted service work drain on run cancellation; no OS checkout or application-side native compiler is required. |
93
+ | Compose a macOS application bundle | [`arcane-os/native/macos-provider`](core-native-packaging.md#macos-application-composition) | **Node** assembly with matching host archive; matching Darwin ARM64/x64 for execution | Complete portable content stays in Resources. AppKit/WebKit launch, stable packaged origin, document activation and graceful Core drain remain host-owned. Source implementation is separate from a built/published host archive or actual Mac execution. |
94
+ | Persist application-owned Core preferences | [`arcane-os/core/preferences`](core-preferences.md) | **Node** Core service; renderer uses existing `Arcane.preferences` methods | Application-selected file and exact keys/JSON values, ordered in-process writes and service-lifetime drain. Unreadable storage remains untouched; saved values do not set operating-system preferences. |
95
+ | Read complete selected text from Git | [`createGitTextSnapshot`](git-text-snapshot.md) from `arcane-os` | **Node** with Git on Windows, Linux or macOS; Android requires host adaptation | One selected revision, complete UTF-8 content and independent result copies. A dedicated bare object cache leaves working checkouts untouched; shared refresh and drain own actual completion. |
96
+ | Use application-selected llama.cpp/Ollama through Core | [`arcane-os/core/local-ai`, `arcane-os/ai/core-local`](local-ai.md) | **Node** native service; **Browser / native WebView** provider through an explicit Core connection | Independent runtime/model lifecycle, complete streaming and cancellation. Official runtime preparation follows explicit app requirements; model selection and business policy stay app-owned. |
97
+ | Run native ONNX tensors | [`arcane-os/local-ai/onnx`, `arcane-os/ai/core-onnx`](local-ai.md#native-onnx-sessions) | **Node** Windows/Linux/macOS x64/arm64; **Browser / native WebView** through available Core | Explicit graph loading, retained workers and complete tensor outputs. Android requires host adaptation. Native calls can delay worker termination; cleanup observes actual exit. |
98
+ | Label speakers in caller-fed mono audio | [`arcane-os/diarization`, `arcane-os/core/diarization`](diarization.md) | **Node** with built helper, selected official NeMo libraries and Nemotron model; official CPU archives cover Windows x64 and Linux/macOS x64/arm64 | Independent retained streams, complete timed segments and optional probability frames. Generic labels are not personal identities or speech transcripts; cancellation and close observe native cleanup. Android needs host adaptation. |
92
99
  | Use local AI without coupling app code to Ollama HTTP | `Arcane.localAI`, `Arcane.ai`, or `/arcane/modules/Ollama.js` | Primarily **Native**; Android exposes a narrower admitted inference projection | Admission, errors, and managed-operation events are normalized. Direct Ollama response envelopes remain **Provider-native**. |
93
100
  | Use TWiN Cloud from the renderer profile | `/arcane/modules/AI.js` | **Cloud** from an allowed browser/native renderer | High-level chat behavior is normalized by the module. The TWiN access key authenticates remote LLM chat; raw provider diagnostics remain provider-specific. No automatic cloud fallback is inferred from local failure. |
94
101
  | Send one TWiN Cloud request with an explicit key and model | `fetchRequest` from `arcane-os/ai/twin-cloud` | **Node** and **Browser**, using standard Fetch and a remote HTTPS provider | Keeps complete messages and returns the full parsed provider JSON. Rejected Fetch and HTTP 529 share three retries after 3000 ms; HTTP 429 overload retains unlimited three-second retries. Optional `onRetry` reports waiting/requesting phases without blocking recovery. Shared structured-output mapping and cancellation match browser TWiN transport. No browser profile, AI/user singleton, DBOPFS, or retained request history is created. |
@@ -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` and/or `ollama` requirements to application configuration and prepares missing runtimes alongside serving. See [local AI through Core](local-ai.md). |
52
+ | `--local-ai` | comma-separated runtime IDs | `dev` only; adds `llama.cpp`, `ollama` and/or `onnx` 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. |
@@ -367,7 +367,7 @@ An explicit live-source SDK mapping follows the selected browser destinations
367
367
  while reading canonical SDK source; it never replaces installed files.
368
368
 
369
369
  ```text
370
- arcane dev [--app <id>] [--public] [--http | --https] [--cert <file> --key <file>] [--host <address>] [--port 8000] [--http-port 0] [--sdk-runtime-source <sdk-root>] [--local-ai llama.cpp,ollama]
370
+ arcane dev [--app <id>] [--public] [--http | --https] [--cert <file> --key <file>] [--host <address>] [--port 8000] [--http-port 0] [--sdk-runtime-source <sdk-root>] [--local-ai llama.cpp,ollama,onnx]
371
371
  ```
372
372
 
373
373
  `--local-ai` saves the selected requirements in `native.localAI`, or in
@@ -406,7 +406,7 @@ device, since `localhost` refers to that device and `0.0.0.0` is a bind address.
406
406
  Network URLs come from one interface snapshot at startup and do not establish
407
407
  remote reachability through the machine's firewall or network.
408
408
 
409
- HTTPS is the default for development and required for packaged browser previews.
409
+ HTTPS is the default for development and packaged browser previews.
410
410
  The published `node-http-server` 10.0.0 integration negotiates HTTP/2 or HTTP/1.1
411
411
  on the same HTTPS port using the configured PEM pair. Source routes, generated
412
412
  PWA resources, and conditional responses use the same serving pipeline.
@@ -448,6 +448,10 @@ close the owned HTTP listener and settle the same lifecycle.
448
448
  `--key`, or `--http-port` is a usage error. Omitting it preserves HTTPS;
449
449
  certificate errors never select HTTP automatically.
450
450
 
451
+ The public `startDevServer()` API also accepts `http:true` in packaged mode;
452
+ this does not add a CLI preview command or change `dev` into packaged serving.
453
+ See [the API contract](sdk-api.md#startdevserver).
454
+
451
455
  A LAN HTTP origin does not receive the browser's localhost secure-context
452
456
  exception. For Chrome development, Chromium documents
453
457
  `chrome://flags/#unsafely-treat-insecure-origin-as-secure` with the exact HTTP
@@ -700,10 +704,10 @@ npm exec -- arcane verify-bundle dist/hello-world-1.0.0.arcane-app.tar.gz
700
704
 
701
705
  ### Overview
702
706
 
703
- Loads the SDK package provider for portable by default, or the fixed provider
704
- from an explicitly selected Arcane OS checkout. It diagnoses the selected
705
- provider prerequisites without building an app. Executable targets still
706
- require `--arcane-root` and their platform toolchains.
707
+ Loads the SDK package provider for `portable` or `windows-x64` by default, or
708
+ the fixed provider from an explicitly selected Arcane OS checkout. It diagnoses
709
+ selected prerequisites without building an app. Windows uses the matching
710
+ precompiled SDK host; Linux and Android retain their checkout/toolchain routes.
707
711
 
708
712
  ```text
709
713
  arcane native-doctor --target <native-target> [--arcane-root <directory>]
@@ -719,8 +723,7 @@ is unavailable; it never returns a browser package as a substitute.
719
723
 
720
724
  ```bash
721
725
  npm exec -- arcane native-doctor \
722
- --target windows-x64 \
723
- --arcane-root "../Arcane OS"
726
+ --target windows-x64
724
727
  ```
725
728
 
726
729
  ## `arcane native-prepare`
@@ -762,6 +765,9 @@ The output remains target-specific inside the common plan contract.
762
765
  Portable uses the SDK package without an OS checkout, copies complete selected
763
766
  app/dependency payloads and generates the Core entry/classic client source.
764
767
  It adds no executable platform host or automatically discovered app services.
768
+ Windows x64 uses the SDK package provider and its matching precompiled release
769
+ asset without an OS checkout or application-side native compilation. See
770
+ [Windows requirements and artifact layout](core-native-packaging.md#windows-executable).
765
771
  An explicit `--arcane-root` continues to select the checkout provider.
766
772
  Integrated builds retain an output root outside the OS checkout; only an
767
773
  explicit checkout provider must share the workspace root.
@@ -775,7 +781,6 @@ rather than returning a fictional native artifact plan.
775
781
  ```bash
776
782
  npm exec -- arcane build \
777
783
  --target windows-x64 \
778
- --arcane-root "../Arcane OS" \
779
784
  --output-root "../arcane-native-output"
780
785
  ```
781
786
 
@@ -816,6 +821,13 @@ Android providers expose supported paired native run paths. Portable output is
816
821
  a directory and intentionally cannot run. Android run requires one
817
822
  connected physical/native ARM64 device for the current target.
818
823
 
824
+ `windows-x64` uses the package provider by default, launches `Arcane.exe`, and
825
+ streams complete diagnostics. Its cancellation closes input and waits for the
826
+ window/Core's accepted work to drain; it does not force-kill that host after a
827
+ timer. WebView2 Runtime and .NET Framework 4.6.2 or later must be available on
828
+ the Windows execution machine. Linux/Android retain their explicit provider
829
+ requirements. Build/launch completion does not prove application domain behavior.
830
+
819
831
  ### Example
820
832
 
821
833
  ```bash
@@ -77,6 +77,13 @@ 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
+ `Arcane.speech.synthesize(request, {signal})` forwards the optional cancellation
81
+ signal through the same request lifetime. Existing one-argument calls retain
82
+ the 180,000 ms timeout and pass the complete request unchanged. A pre-aborted
83
+ signal sends no synthesis request; an in-flight abort sends `request.cancel`
84
+ and suppresses late responses. Actual synthesis interruption depends on the
85
+ registered speech service and its engine; the facade supplies no speech engine.
86
+
80
87
  ## Events and request lifetime
81
88
 
82
89
  `events.on(name, listener)`, `once(name, listener)` and
@@ -124,6 +131,86 @@ developer diagnostics, rather than ordinary
124
131
  product status surfaces. The optional `onError(error)` callback observes
125
132
  transport/event-owner failures outside individual request promises.
126
133
 
134
+ ## Optional WebKit document lifetime
135
+
136
+ `webKitDocumentLifecycle:true` on `createCoreClient`, `installCoreClient` or
137
+ `createCoreClassicSource` selects document lifetime handling for the native
138
+ WebKit `arcane` handler with replies. It defaults to `false`; existing WebKit
139
+ plain-JSON and alternate acknowledgement transports, WebView2, Android,
140
+ development HTTP and supplied transports keep their existing behavior. The
141
+ selected host must implement this contract and the existing `runtime.replay`
142
+ control. Install the classic source at document start in the page's world.
143
+
144
+ The client owns a fresh activation for the current JavaScript realm and each
145
+ restoration from the browser's page cache. WithReply receives these transport
146
+ records; the Core JSON string remains unchanged in its separate `json` field:
147
+
148
+ | Record | Meaning |
149
+ | --- | --- |
150
+ | `{type:'activate', activation}` | Attach this activation before sending its Core frames. |
151
+ | `{type:'frame', activation, json}` | Send the complete serialized Core request or control. |
152
+ | `{type:'retire', activation, json}` | Retire this activation; `json` is the existing `requests.cancelAll` control. |
153
+
154
+ Reply with `{accepted:true}` or `{accepted:false,error}` on the initiating
155
+ WithReply promise. Frame and retirement acceptance follows the actual complete
156
+ process write. Queue admission alone is insufficient. Activation acceptance
157
+ follows the host's current-realm probe and any required prior-owner cancellation.
158
+ Only this activation's outgoing frames wait for attachment; page rendering,
159
+ facade installation and independent Core startup remain concurrent.
160
+ An aborted, timed-out or otherwise cancelled request awaiting attachment is
161
+ never submitted afterward; its existing cancellation control remains observable.
162
+
163
+ The host calls `__arcaneWebKitDocumentCurrent(activation)` in the current main
164
+ document's page world to probe a candidate. A token or native frame descriptor
165
+ alone does not identify the active document. Serialize candidate probes and
166
+ Core ingress ownership changes: finish each candidate's probe before processing
167
+ the next announcement, and leave the current owner unchanged when a probe is
168
+ false. Announcement arrival order cannot establish document order. A true
169
+ probe establishes the realm at that execution instant; every later delivery
170
+ still checks its target at execution time.
171
+
172
+ Before accepting a replacement activation, write the existing
173
+ `requests.cancelAll` control for the prior ingress owner. Do not wait for a
174
+ retirement announcement that a destroyed document may never send. Write a
175
+ retirement record's JSON only while that activation still owns ingress;
176
+ reject a late retirement without cancelling the replacement's requests.
177
+ Record request-ID-to-origin-activation correlation before submitting each
178
+ request to Core. Responses retain that origin. Existing generic service events
179
+ remain broadcasts to the current activation; no request association is added.
180
+ Complete native diagnostics retain frames received while no document is active;
181
+ restoration uses current-state replay rather than historical event delivery.
182
+
183
+ Deliver through `__arcaneReceive(json, activation)` and
184
+ `__arcaneTransportFailed(error, activation)`, passing payloads as native
185
+ JavaScript call arguments. Both return `false` for a retired or different
186
+ activation. Receive also returns `false` for an unrecognized frame or a
187
+ response with no pending request; `true` means the client accepted delivery,
188
+ which may still await its shared event owner. Failure returns `true` when it
189
+ ends that active installation. Preserve actual evaluation failures through the
190
+ native diagnostic owner; a `false` result is not a JavaScript exception.
191
+ `client.acceptsNativeDelivery(activation)` exposes the same synchronous lifetime
192
+ predicate. It accepts any activation while a client using an ordinary transport
193
+ is live. Direct owner calls to `client.failTransport(error)` retain their
194
+ existing terminal-failure semantics.
195
+
196
+ Page hide synchronously retires the activation even with no pending requests.
197
+ It clears completed ready state and rejects every pending renderer promise with
198
+ the existing `ARCANE_REQUEST_ABORTED`/`AbortError`. This ends the page's wait;
199
+ the runtime's cancellation skips service-lifetime work, so an accepted save
200
+ continues and participates in graceful drain. Its eventual response stays with
201
+ the retired activation and cannot settle a restored page's request. The client
202
+ does not claim that cancellation rolled back persistence.
203
+
204
+ Persisted page restoration creates a fresh activation and sends exactly one
205
+ `runtime.replay` after native attachment. Initial attachment sends that replay
206
+ only when `replayRuntimeState:true`. Application subscriptions survive page
207
+ hide and restoration, including registrations awaiting the shared event owner
208
+ and ready listeners awaiting their replay microtask. Queued deliveries from a
209
+ retired activation are no longer applicable to those subscriptions. Replay
210
+ supplies current Core/service state, not prior responses or request promises.
211
+ Closing the client retires once, removes lifecycle listeners and restores its
212
+ owned callbacks. It does not close the process or control application shutdown.
213
+
127
214
  ## Classic native-host injection
128
215
 
129
216
  ```js
@@ -6,7 +6,7 @@ executable. An application's explicit `native.localAI` selection can include
6
6
  its selected upstream runtimes through the SDK local-AI installer. Without that
7
7
  selection, assembly does no local-AI runtime preparation. Windows, Linux and macOS hosts may compose this
8
8
  Node-based payload; Android needs its separate native host adaptation. The
9
- current CLI's portable platform selections remain Windows and Linux. A portable
9
+ current CLI's portable platform selections include Windows, Linux and macOS. A portable
10
10
  artifact is not a Windows executable, Linux package or Android application.
11
11
 
12
12
  `loadArcaneNativeProvider({target:'portable'})` selects the installed SDK provider
@@ -18,10 +18,14 @@ providers; the loader does not substitute this payload for an unavailable host.
18
18
  ## Provider and selected input
19
19
 
20
20
  The default export and `arcaneNativeBuilderProvider` are the same provider.
21
- `createPortableNativeProvider({services})` creates one with application-owned
21
+ `createPortableNativeProvider({services,packagedWeb=false,webKitDocumentLifecycle=false})` creates one with application-owned
22
22
  service configuration. Without that override, the provider uses the selected
23
23
  app descriptor's `native.services`, or an empty selection when omitted. An
24
24
  explicit `services:[]` overrides the descriptor with no app services.
25
+ The Mac provider selects `packagedWeb:true` to compose the SDK's packaged-web
26
+ Core service and `webKitDocumentLifecycle:true` for the canonical classic-client
27
+ activation/replay contract. Both default to false, preserving ordinary portable
28
+ and Windows composition.
25
29
  All implement `arcane-native-builder/1`:
26
30
 
27
31
  - `describe()` identifies the portable target and `executable:false`.
@@ -208,10 +212,14 @@ details and [the client contract](core-client.md) for native bridge integration.
208
212
 
209
213
  The generated Core entry accepts `--arcane-launch-config <path>`. The public
210
214
  `readCoreLaunchContext({argv=process.argv.slice(2)}={})` function in
211
- `arcane-os/core/host` reads that explicitly selected JSON object. Without the
212
- flag it returns `{}`. Missing files, missing flag values and malformed JSON
213
- report their actual errors; the reader does not search for configuration,
214
- rewrite it or change the process environment.
215
+ `arcane-os/core/host` reads that explicitly selected JSON object. A native host
216
+ can separately supply `--arcane-host-state-root <directory>` for the reader's
217
+ `stateRoot` default. Every field in the explicit JSON object takes precedence
218
+ unchanged, including an explicitly present `stateRoot` with a relative, null or
219
+ other application-owned value. With neither argument the reader returns `{}`.
220
+ Missing files, missing argument values and malformed JSON report their actual
221
+ errors; the reader does not search for configuration, resolve or validate the
222
+ state directory, rewrite the file or change the process environment.
215
223
 
216
224
  The generated entry supplies an artifact-derived `appRoot` and then applies the
217
225
  complete explicit launch context. Every service factory receives that same
@@ -220,7 +228,10 @@ launcher can supply the user's selected `workspaceRoot` and writable
220
228
  `stateRoot` at launch instead of embedding this machine's paths in an app
221
229
  package. The host owns those selections; the SDK does not choose a product's
222
230
  workspace, namespace, saved preferences or models. JSON values and additional
223
- application-owned fields remain unchanged.
231
+ application-owned fields remain unchanged, including an app-selected
232
+ `preferencesFile`. The state directory supplies no preference filename and
233
+ triggers no stored-data discovery or migration. Linux and other composing hosts
234
+ may pass the same separate argument; the reader chooses no platform directory.
224
235
 
225
236
  ## Selected local-AI runtimes
226
237
 
@@ -242,6 +253,13 @@ factory. Applications without that selection have no generated local-AI import
242
253
  or service. Availability of a particular engine belongs to the selected
243
254
  local-AI installer and service; a generic ONNX runtime is not a speech model.
244
255
 
256
+ Selected `onnx` bundles its complete managed `onnxruntime-node` dependency tree.
257
+ Its `modulePath` resolves against the artifact root just as a server runtime's
258
+ `executable` does. Library/module records need no executable. The generated Core
259
+ service exposes retained worker sessions through `onnx.load/run/unload/status`;
260
+ model files remain caller-selected application resources. See
261
+ [native ONNX sessions](local-ai.md#native-onnx-sessions).
262
+
245
263
  ## Windows executable
246
264
 
247
265
  The ordinary application command is:
@@ -294,8 +312,11 @@ Arcane.exe --arcane-launch-config path/to/launch.json
294
312
  The complete JSON object reaches the service factories as their second
295
313
  argument. A supplied `stateRoot` also owns the WebView2 profile and diagnostic
296
314
  directory. Otherwise the launcher uses the current user's local application
297
- data under `Arcane/<app-id>`. The launcher does not invent an application
298
- workspace. Relative launch-file paths resolve from the invocation's working
315
+ data under `Arcane/<app-id>`. It forwards that actual host selection through
316
+ `--arcane-host-state-root`, so ordinary double-click startup supplies `stateRoot`
317
+ to every Core service factory. The complete explicit launch context still takes
318
+ precedence without rewriting its fields. The launcher does not invent an
319
+ application workspace. Relative launch-file paths resolve from the invocation's working
299
320
  directory. `--close-on-stdin-eof` is an explicit process-owner option used by the
300
321
  SDK runner; an ordinary double-clicked window closes through its own UI.
301
322
 
@@ -331,3 +352,102 @@ Linux, macOS, Android dispatch and each platform's output verification retain
331
352
  their separate delivery boundaries. Published
332
353
  consumers must adopt the numeric package that includes this increment; a source
333
354
  checkout or a successful source push is not that public package authority.
355
+
356
+ ## macOS process source
357
+
358
+ `src/core/hosts/macos/ArcaneCoreProcess.h` and `.m` provide a Foundation-only
359
+ adapter for macOS 11 or later, compiled with Objective-C ARC and blocks. A
360
+ composing host explicitly supplies the executable URL, arguments, working
361
+ directory and delegate; startup is asynchronous. Delegate callbacks deliver
362
+ every raw stdout/stderr chunk and complete opaque framed JSON bodies, plus
363
+ launch, error, exit and final completion observations. Each stream and accepted
364
+ write retains its own order; UI dispatch belongs to the host. Callbacks must
365
+ return normally and must not wait for another callback or completion.
366
+
367
+ `sendJSONData:completion:error:` accepts an ordered write or reports a
368
+ synchronous rejection. Write completion means the frame reached stdin, not that
369
+ the RPC succeeded. `closeInput` rejects new sends, finishes accepted writes and
370
+ closes stdin, then keeps observing output and child exit without a forced
371
+ termination deadline. The delegate is retained through final completion.
372
+ The AppKit `ArcaneHost` and launcher compose that source as described below.
373
+ Compilation and execution on macOS remain separate evidence from the selected
374
+ Windows output.
375
+
376
+ ## macOS application composition
377
+
378
+ `arcane-os/native/macos-provider` exports
379
+ `createMacOSNativeProvider({services,hostDirectory}={})`, its named
380
+ `arcaneNativeBuilderProvider`, and the same provider as default. The six-method
381
+ contract accepts `macos-arm64` or `macos-x64`, `platform:'macos'`, `format:'app'`
382
+ and the existing unsigned local development selection. Ordinary CLI routing
383
+ uses the SDK package, not an Arcane OS checkout:
384
+
385
+ ```sh
386
+ npm exec -- arcane build --target macos-arm64
387
+ npm exec -- arcane run --target macos-arm64
388
+ ```
389
+
390
+ Select `macos-x64` for Intel. The descriptor must declare the selected target.
391
+ Source implementation does not establish that an architecture's host artifact
392
+ has been built, executed or published. Consumer assembly needs the exact numeric
393
+ SDK release asset `arcane-native-macos-<architecture>.tar.gz`; unavailable assets
394
+ produce their actual download error. SDK collaborators may select an existing
395
+ `hostDirectory` explicitly. There is no fallback to source checkout, another
396
+ version, another architecture or a browser-only artifact.
397
+
398
+ The complete unchanged portable payload lives at
399
+ `<app-id>.app/Contents/Resources/`. That directory remains `target.rootDir` and
400
+ contains `arcane-native.json`, `app/`, dependency releases, installed SDK files,
401
+ Core entry/client and `runtime/node`. The additive `bundleRoot` identifies the
402
+ `.app` directory. `Contents/MacOS/Arcane` and `Contents/Info.plist` belong to the
403
+ bundle rather than the web root; the Mac owner checks these separately from the
404
+ Resources file inventory. Application identity supplies the stable bundle ID
405
+ `org.arcane.<app-id>`. Executable permissions are preserved for the launcher and
406
+ selected Node runtime.
407
+
408
+ The launcher opens its window immediately and starts one Core child. The
409
+ generated Core entry starts the `packaged-web` service alongside application
410
+ services, without waiting for models. Only `core.web.ready`, emitted after the
411
+ actual listener is ready and the initial port is saved, supplies the application
412
+ URL to WebKit. It serves the complete `manifest.webRoot` at `/` and resolves the
413
+ complete `manifest.start`, including query and fragment, against that origin.
414
+ The classic client selects current-document activation and sticky state replay;
415
+ navigation does not restart the Core service or replay retired requests.
416
+ The host's main-thread readonly `isClosing` accessor exposes its existing close
417
+ intent; an unsolicited Core exit is therefore reported separately from an
418
+ ordinary user-requested drain, even when the process exits successfully.
419
+
420
+ `createPackagedWebService({artifactRoot}, context={})` is available from
421
+ `arcane-os/core/packaged-web`. It uses the existing
422
+ `startDevServer({mode:'packaged',http:true,host:'127.0.0.1',port,releaseRoot})`
423
+ owner and published `node-http-server`, not a second HTTP implementation.
424
+ `context.stateRoot` takes precedence over the launcher's separate
425
+ `--arcane-host-state-root` argument. The launcher defaults to
426
+ `~/Library/Application Support/Arcane/<app-id>`; an explicitly supplied launch
427
+ file remains unchanged and is forwarded to Core. The shared launch reader also
428
+ supplies that host default to every application service factory, with explicit
429
+ launch fields taking precedence. The first successful listener
430
+ stores its selected port in `packaged-web-origin.json`. Later launches reuse it;
431
+ a port conflict or unreadable saved record is reported without changing origins
432
+ or discarding stored state.
433
+
434
+ The app's persistent default `WKWebsiteDataStore` uses its bundle identity.
435
+ `stateRoot` selects Core state and diagnostics, not a custom WebKit profile
436
+ directory. Browser API availability, OPFS and secure-context behavior remain
437
+ WebKit-owned and require actual Mac verification; the SDK bypasses no browser
438
+ policy. Startup failures use `core.service.state` for `name:'packaged-web'`;
439
+ unexpected listener closure or failure uses `core.web.failed` with the complete
440
+ serialized error. Native alerts show a concise outcome, with full diagnostics
441
+ outside the conversation. Core drains accepted work and the listener before
442
+ the native close completes. The optional runner stdin-EOF signal uses that same
443
+ path; ordinary double-click startup does not wait on stdin.
444
+
445
+ `tools/build-core-macos-host.mjs` is SDK host-release tooling, not an application
446
+ compiler requirement. It accepts an explicit Darwin Node executable and its
447
+ license, compiler path, `arm64` or `x64`, and output directory. It uses Objective-C
448
+ ARC/blocks and Apple's Foundation, AppKit and WebKit frameworks. The host source
449
+ targets macOS 11; the selected Node runtime may require a newer macOS version.
450
+ Its actual runtime/platform/architecture and the SDK Node engine requirement
451
+ must agree. Compiler/runtime execution and redistribution belong to the
452
+ separately authorized selected host output. This source increment runs none of
453
+ them and claims no Mac build or execution result.
@@ -0,0 +1,49 @@
1
+ # Core preferences service
2
+
3
+ `createPreferencesService({file})` from `arcane-os/core/preferences` supplies the
4
+ existing `Arcane.preferences` RPC methods to a native Core host. The default
5
+ export is the same factory. Construction performs no filesystem work. The
6
+ application selects its writable file and owns preference names, defaults and
7
+ schemas; this service does not invent them or alter operating-system settings.
8
+
9
+ ```js
10
+ import path from 'node:path';
11
+ import {createPreferencesService} from 'arcane-os/core/preferences';
12
+
13
+ export default function createMoonPreferences(options, context) {
14
+ return createPreferencesService({
15
+ file: path.join(context.stateRoot, 'moon-preferences.json')
16
+ });
17
+ }
18
+ ```
19
+
20
+ Select this application-owned factory through `native.services`, and include it
21
+ in `package.nativeResources`. Supply the application's selected `stateRoot`
22
+ through the explicit launch configuration. See [native packaging](core-native-packaging.md#launch-time-locations).
23
+
24
+ | Method | Input | Result |
25
+ | --- | --- | --- |
26
+ | `preferences.list` | `{}` | `{keys}` in sorted order |
27
+ | `preferences.get` | `{key}` | `{key,found,value}`; missing value is `null` |
28
+ | `preferences.set` | `{key,value}` | `{key,value}` after file replacement |
29
+ | `preferences.setMany` | `{entries}` | `{keys,count}` after file replacement |
30
+ | `preferences.delete` | `{key}` | `{key,deleted}` |
31
+
32
+ Storage remains `{schemaVersion:1,entries}`. Exact keys, complete JSON values and
33
+ additional existing document metadata are retained. A missing file starts with
34
+ empty entries; reading it does not create a file. Unreadable or malformed files
35
+ report their real errors and are not replaced with an empty record. Values that
36
+ JSON cannot represent completely fail before replacement. There is no migration,
37
+ truncation, namespace rewrite, default injection or frozen result.
38
+
39
+ Operations selecting the same resolved filename share one ordered queue within
40
+ the Core process. This is not a cross-process file lock. Writes flush their new
41
+ content and replace the selected file before acknowledgment. Filesystem failures
42
+ remain observable, including cleanup errors; this is not a claim of survival
43
+ across every hardware or operating-system failure.
44
+
45
+ `set`, `setMany` and `delete` use `lifetime:'service'`: renderer cancellation does
46
+ not discard accepted writes. `drain()` and `dispose()` stop acceptance and wait
47
+ for accepted operations; later calls reject with `CORE_CLOSING`. Read operations
48
+ observe their request cancellation. Use the existing Core host shutdown owner
49
+ so saved preferences finish before the native process exits.