arcane-os 0.63.0 → 0.65.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 (58) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +1 -1
  3. package/browser-runtime/core/client.mjs +69 -7
  4. package/docs/guides/native-whisper-openvino.md +334 -0
  5. package/docs/reference/README.md +6 -0
  6. package/docs/reference/arcane-ollama.md +1 -1
  7. package/docs/reference/codex-app-server.md +269 -0
  8. package/docs/reference/core-client.md +71 -4
  9. package/docs/reference/core-development.md +157 -0
  10. package/docs/reference/core-native-packaging.md +48 -6
  11. package/docs/reference/core-repositories.md +258 -0
  12. package/docs/reference/inventory/package-api.json +199 -3
  13. package/docs/reference/inventory/runtime-modules.json +3 -2
  14. package/docs/reference/local-ai.md +77 -4
  15. package/docs/reference/local-image-flux.md +1 -1
  16. package/docs/reference/local-image-generation.md +11 -0
  17. package/docs/reference/local-image-sdxl.md +139 -0
  18. package/docs/reference/local-whisper.md +219 -0
  19. package/docs/reference/mcp-stdio.md +263 -0
  20. package/docs/reference/native-speech.md +51 -2
  21. package/docs/reference/runtime-components.md +18 -1
  22. package/docs/reference/runtime-modules.md +26 -4
  23. package/docs/reference/sdk-api.md +412 -2
  24. package/package.json +9 -2
  25. package/runtime/arcane/components/speech.html +15 -3
  26. package/runtime/arcane/components/voice-transcription.html +19 -3
  27. package/runtime/arcane/modules/AI.js +406 -40
  28. package/runtime/arcane/modules/AIProviderRuntime.js +20 -3
  29. package/runtime/arcane/modules/AIRuntimeState.js +15 -2
  30. package/runtime/arcane/modules/ComponentContracts.js +3 -0
  31. package/runtime/arcane/modules/Ollama.js +1 -1
  32. package/runtime/arcane/modules/OllamaModelIdentifier.js +13 -0
  33. package/schemas/arcane-app.schema.json +60 -2
  34. package/schemas/arcane-package.schema.json +60 -2
  35. package/src/codex/app-server.mjs +845 -0
  36. package/src/core/development.mjs +457 -0
  37. package/src/core/repositories.mjs +375 -0
  38. package/src/core/services/local-ai.mjs +80 -10
  39. package/src/core/services/speech.mjs +1 -0
  40. package/src/dev-server.mjs +3 -2
  41. package/src/index.mjs +1 -0
  42. package/src/local-ai/config.mjs +7 -3
  43. package/src/local-ai/dev.mjs +85 -401
  44. package/src/local-ai/image-library.mjs +9 -0
  45. package/src/local-ai/image-models/sdxl.mjs +18 -0
  46. package/src/local-ai/install.mjs +26 -7
  47. package/src/local-ai/whisper/build.mjs +48 -0
  48. package/src/local-ai/whisper/config.mjs +89 -0
  49. package/src/local-ai/whisper/index.mjs +572 -0
  50. package/src/local-ai/whisper/install.mjs +332 -0
  51. package/src/local-ai/whisper/native/CMakeLists.txt +98 -0
  52. package/src/local-ai/whisper/native/NOTICE +18 -0
  53. package/src/local-ai/whisper/native/README.md +104 -0
  54. package/src/local-ai/whisper/native/main.cpp +520 -0
  55. package/src/local-ai/whisper/openvino-build.mjs +138 -0
  56. package/src/mcp/stdio-server.mjs +579 -0
  57. package/src/native/portable-layout.mjs +39 -7
  58. package/src/toolchain.mjs +19 -8
@@ -0,0 +1,258 @@
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,write,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
+ The open/status/pull/push methods accept `{signal}={}` and return promises;
71
+ `write` accepts the complete file/message request described below:
72
+
73
+ | Method | Result and side effect |
74
+ |---|---|
75
+ | `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. |
76
+ | `status` | Prepares the checkout if needed, then returns the existing `repositoryStatus` result unchanged. |
77
+ | `pull` | Prepares the checkout if needed, then runs the existing clean-checkout, fast-forward-only `repositoryPull` operation unchanged. |
78
+ | `push` | Prepares the checkout if needed, then runs the existing `repositoryPush` operation unchanged, preserving its support for unrelated uncommitted working files. |
79
+ | `write` | Writes exact caller-selected text files, stages and commits only their literal paths, then performs one ordinary non-force push. Returns confirmed operation outcomes; see below. |
80
+ | `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. |
81
+
82
+ Opening an existing repository never pulls, switches branches, resets, changes
83
+ its remote or rewrites files. A nonempty destination that is a bare repository,
84
+ a subdirectory of another checkout, or ordinary non-repository data is left
85
+ untouched and reports its Git error or `ARCANE_REPOSITORY_DIRECTORY_INVALID`.
86
+ A failed or cancelled clone reports the actual failure; any remaining directory
87
+ is retained for application-owned inspection. There is no automatic deletion or
88
+ destructive retry. Filesystem failures and complete Git diagnostics propagate.
89
+
90
+ ## Write, commit and push selected text
91
+
92
+ ```javascript
93
+ const result = await repository.write({
94
+ files: [{path: 'dispatches/moon-cheese.md', content: completeAuthoredText}],
95
+ message: authoredCommitMessage,
96
+ signal
97
+ });
98
+ ```
99
+
100
+ `write({files:[{path,content}],message,signal}={})` requires at least one explicit
101
+ file, a nonempty commit message and string content (including an empty string).
102
+ Paths name working files relative to this repository, not its root, outside
103
+ paths or Git-owned `.git` metadata. Strings must be representable as UTF-8;
104
+ native filenames cannot contain NUL. Incompatible input reports a `TypeError`
105
+ before any write, rather than replacing text. Content may contain NUL, BOM,
106
+ CRLF, leading/trailing whitespace and every ordinary Unicode character.
107
+
108
+ The method copies the selected records and their original strings synchronously
109
+ when called. Later changes to the caller's array, file records or selected UI
110
+ connection cannot alter accepted work. It does not freeze the caller's objects,
111
+ add document labels, normalize line endings, trim content or wrap documents.
112
+ The workspace's originally selected directory remains the operation owner.
113
+
114
+ After preparing that checkout, it creates needed parent directories and writes
115
+ each complete file using the ordinary native UTF-8 filesystem API. These are
116
+ caller-owned replacements, not an append-only policy or a multi-file atomic
117
+ transaction. Applications choose which paths and content may be replaced.
118
+ Ordinary filesystem behavior, including existing symlinks, remains with the
119
+ native host.
120
+
121
+ One `git --literal-pathspecs add -- <paths>` stages only those exact names.
122
+ One `git --literal-pathspecs commit --only --cleanup=verbatim --file - -- <paths>`
123
+ commits only those paths, leaving unrelated staged paths staged. The original
124
+ message is streamed unchanged through standard input. One ordinary `git push`
125
+ then uses that repository's existing remote/ref configuration, identity,
126
+ credentials and hooks. There is no implicit pull, branch switch, forced push,
127
+ hook bypass, automatic retry, rollback or reset. If Git reports no changes to
128
+ commit, that actual failure is returned; the SDK creates no empty commit.
129
+ These are Git's documented [selected-path commit](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---only)
130
+ and [literal pathspec](https://git-scm.com/docs/git#Documentation/git.txt---literal-pathspecs) semantics.
131
+
132
+ Existing Git attributes, clean filters, EOL settings and hooks continue to apply
133
+ when Git stages/commits content. The filesystem write preserves the original
134
+ text; this API does not claim that repository-configured filters leave Git blob
135
+ text identical. It preserves those settings. A push may also send existing history or other
136
+ refs selected by the repository's ordinary push configuration.
137
+
138
+ ### Result and failure outcomes
139
+
140
+ Successful completion returns:
141
+
142
+ ```text
143
+ {
144
+ directory,
145
+ state: 'pushed',
146
+ stage: 'complete',
147
+ paths: [originalSelectedPath, ...],
148
+ writtenPaths: [confirmedWrittenPath, ...],
149
+ written: true,
150
+ staged: true,
151
+ committed: true,
152
+ pushed: true,
153
+ outputs: [{stage: 'prepare'|'stage'|'commit'|'push', stdout, stderr, code?, signal?}, ...]
154
+ }
155
+ ```
156
+
157
+ Each output record retains complete stdout/stderr. `code` and the process
158
+ termination `signal` are included when a completed process result is available.
159
+ An in-progress write also records its current `path` on a failure outcome.
160
+ `writtenPaths` records successful filesystem writes in input order; `written`
161
+ becomes true only after every requested write succeeds. The other booleans
162
+ record successful Git command completion. **False means success is unconfirmed,
163
+ not that files, the index, HEAD or the remote certainly remained unchanged.**
164
+
165
+ - `local`: no successful commit or push has been confirmed. Inspect
166
+ `writtenPaths`, `written`, `staged` and `stage` for actual local progress.
167
+ - `committed`: Git completed the commit; no successful push has been confirmed.
168
+ Cancellation before push keeps this result rather than claiming delivery.
169
+ - `pushed`: Git reported successful completion of the push. A later observer
170
+ error retains that confirmed result while still reporting the observer error.
171
+ - `uncertain`: an attempted file write, commit or push did not supply successful
172
+ completion evidence. Partial files or index changes can remain, and a remote
173
+ can accept updates before a connection failure hides the acknowledgement.
174
+ Previously confirmed `writtenPaths`, `committed` or `pushed` evidence remains
175
+ present. A known pre-spawn failure does not invent a dispatched side effect.
176
+
177
+ After operation acceptance and execution begins, failures reject with an
178
+ `ArcaneError` whose `cause` is the original complete failure and whose `details`
179
+ is the outcome above. The code/message retain the original failure when
180
+ available, and nested process details remain available through its cause.
181
+ Input errors, a pre-aborted/queued-aborted request or a call after closing reject
182
+ before writer execution and have the existing TypeError/cancellation/closing
183
+ contract. No success is fabricated from an error string or callback.
184
+
185
+ Cancellation is checked before each subsequent filesystem/Git action. Active
186
+ Git cancellation drains through the existing process owner. Completion is
187
+ recorded before checking cancellation for the next action: an accepted commit
188
+ is retained if push has not begun, and an accepted push is retained if an
189
+ observer subsequently fails. Failed operations leave their actual files and
190
+ index state available for inspection; the application chooses recovery.
191
+ Await or retain the write promise and connect the workspace's terminal drain
192
+ to its Core service lifetime. The application still owns any decision to make
193
+ that Core method service-lifetime rather than request-lifetime work.
194
+
195
+ ## Ownership, concurrency and shutdown
196
+
197
+ Calls targeting the same resolved path spelling in one Node process run in
198
+ acceptance order, including separate owners selecting that path. Windows keys
199
+ are case-insensitive. The queue does not resolve symlink aliases or macOS case
200
+ variants; applications use one consistent path for a shared connection.
201
+ This prevents overlapping Git/index writes and duplicate successful cloning.
202
+ Different directories proceed
203
+ independently. Applications coordinate separate processes and their own direct
204
+ file/Git writes; this module does not create a daemon or cross-process lock.
205
+
206
+ A pre-aborted call starts no work. A queued aborted operation does not run when
207
+ its turn arrives. Active cancellation reaches the existing process owner, which
208
+ terminates its owned process tree and joins complete output/event cleanup.
209
+ Shutdown drains accepted operations rather than deleting data or terminating
210
+ the host early. Calls after close reject with `CORE_CLOSING`; a failed operation
211
+ still pending when close begins rejects that drain through an `AggregateError`.
212
+ The caller retains each operation's complete result or failure separately.
213
+
214
+ The cold path is one selected connection, one parent-directory creation and one
215
+ Git clone. Opening an existing checkout uses one read-only Git command. A
216
+ prepared owner's status/pull/push use their existing repository operation graph.
217
+ An accepted writer uses one filesystem write per explicitly selected file,
218
+ then one add, one commit and one push, stopping at the first failure.
219
+ There is no scan across applications, connections, models or platforms. Git
220
+ progress, process-starting/completion, heartbeat and cancellation events use
221
+ the existing `onEvent` owner with complete output and backpressure.
222
+ An awaited event callback must not await another operation or shutdown for the
223
+ same directory, including calls through another workspace owner: that operation
224
+ needs the observing callback to finish. Schedule such follow-up without awaiting
225
+ it inside that callback, and retain/observe its promise at the application owner.
226
+
227
+ Compose this owner inside an application-selected Core service. Bind only the
228
+ application's chosen methods, pass each request's `context.signal`, and return
229
+ `drain: repository.drain` and `dispose: repository.dispose` from that service.
230
+ Keep initialization at the repository operation that needs it; page rendering
231
+ and unrelated services do not wait for a clone. This module installs no browser
232
+ RPC, chooses no application service and changes no Core launch configuration.
233
+
234
+ ## Bare snapshots stay separate
235
+
236
+ [`createGitTextSnapshot`](git-text-snapshot.md) continues to require its explicit
237
+ dedicated bare `cacheDirectory`. It neither becomes a working checkout nor
238
+ changes existing callers' caches. A new native caller can place that distinct
239
+ cache under the shared location without changing the snapshot contract:
240
+
241
+ ```javascript
242
+ import path from 'node:path';
243
+ import {createGitTextSnapshot} from 'arcane-os';
244
+ import {resolveArcaneDataPaths} from 'arcane-os/core/repositories';
245
+
246
+ const {repositoriesRoot} = resolveArcaneDataPaths();
247
+ const snapshot = createGitTextSnapshot({
248
+ cacheDirectory: path.join(repositoriesRoot, 'moon-cheese-reader-cache'),
249
+ remote: applicationConnection.remote,
250
+ ref: applicationConnection.ref,
251
+ selectPath: applicationSelectPath
252
+ });
253
+ ```
254
+
255
+ Never assign the same directory to a bare snapshot and a writable workspace.
256
+ Applications retain remote/ref selection, document parsing, scores, messages,
257
+ saved connection state and refresh policy. Existing explicit repository paths
258
+ continue to operate where they already are.
@@ -1,17 +1,185 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "sdkVersion": "0.62.0",
3
+ "sdkVersion": "0.64.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": 288,
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": "local-ai-whisper:createWhisperRuntime",
17
+ "name": "createWhisperRuntime",
18
+ "displayName": "createWhisperRuntime()",
19
+ "kind": "function",
20
+ "signature": "createWhisperRuntime({runtime,prepare,modelId,temporaryDirectory,onEvent}={})",
21
+ "entrypoints": ["arcane-os/local-ai/whisper"],
22
+ "primaryImport": "arcane-os/local-ai/whisper",
23
+ "group": "Core native speech",
24
+ "summary": "Retains a selected native Whisper helper/model across complete recordings with actual correlated recovery and joined cancellation.",
25
+ "availability": "Node with prepared matching helper, Whisper libraries, decoder and model; Android needs host process adaptation",
26
+ "protocol": "Persistent first-party native helper with replaying whisper.state and complete transcription results",
27
+ "normalization": "Returns current/subscribe/load/transcribe/unload/close; preserves complete original media and text/segment results; one accepted transcription, exact requestId control metadata, eligible auto GPU-to-CPU recovery once, truthful unloaded recovery and terminal errors, joined decoder/helper cleanup"
28
+ },
29
+ {
30
+ "id": "local-ai-whisper:default",
31
+ "name": "default",
32
+ "displayName": "createWhisperRuntime default export",
33
+ "kind": "function",
34
+ "signature": "default as createWhisperRuntime",
35
+ "entrypoints": ["arcane-os/local-ai/whisper"],
36
+ "primaryImport": "arcane-os/local-ai/whisper",
37
+ "group": "Core native speech",
38
+ "summary": "Default binding for the same retained native Whisper engine factory.",
39
+ "availability": "Node with the matching prepared native resources",
40
+ "protocol": "Native Whisper engine lifecycle",
41
+ "normalization": "Binding identity equals the named createWhisperRuntime export"
42
+ },
43
+ {
44
+ "id": "local-ai-whisper-build:buildWhisperHelper",
45
+ "name": "buildWhisperHelper",
46
+ "displayName": "buildWhisperHelper()",
47
+ "kind": "function",
48
+ "signature": "async buildWhisperHelper({runtime,outputRoot,cmake='cmake',generator,cmakeArgs=[],env,signal,onEvent}={})",
49
+ "entrypoints": ["arcane-os/local-ai/whisper/build"],
50
+ "primaryImport": "arcane-os/local-ai/whisper/build",
51
+ "group": "Core native speech",
52
+ "summary": "Builds and installs the first-party persistent helper against matching prepared Whisper headers and runtime libraries.",
53
+ "availability": "Node with installed CMake/C++17 toolchain matching the selected platform and architecture",
54
+ "protocol": "Owned configure/build/install process lifecycle",
55
+ "normalization": "Returns platform/architecture/root/executable/runtimeDirectory and complete configure/compile/install diagnostics; preserves cancellation and process failures, installs no model or toolchain, performs no inference"
56
+ },
57
+ {
58
+ "id": "codex-app-server:createCodexAppServerSession",
59
+ "name": "createCodexAppServerSession",
60
+ "displayName": "createCodexAppServerSession()",
61
+ "kind": "function",
62
+ "signature": "createCodexAppServerSession({executable,args,cwd,env,clientInfo,capabilities}={})",
63
+ "entrypoints": ["arcane-os/codex/app-server"],
64
+ "primaryImport": "arcane-os/codex/app-server",
65
+ "group": "Native Codex sessions",
66
+ "summary": "Creates an explicit native Codex App Server JSONL session without starting its process until connect.",
67
+ "availability": "Node with caller-selected native executable on Windows, Linux and macOS; Android requires host process adaptation",
68
+ "protocol": "Native Codex App Server JSONL",
69
+ "normalization": "Complete request/result/notification objects; ordered live delta/item callbacks, actual terminal turn outcomes and exact stored-turn recovery. Server requests retain real IDs and explicit replies. No automatic thread selection, retry, approval or desktop-task attachment."
70
+ },
71
+ {
72
+ "id": "codex-app-server:openCodexAppServerSession",
73
+ "name": "openCodexAppServerSession",
74
+ "displayName": "openCodexAppServerSession()",
75
+ "kind": "function",
76
+ "signature": "async openCodexAppServerSession(options)",
77
+ "entrypoints": ["arcane-os/codex/app-server"],
78
+ "primaryImport": "arcane-os/codex/app-server",
79
+ "group": "Native Codex sessions",
80
+ "summary": "Creates and connects the same explicit native session, disposing it before rejecting failed initialization.",
81
+ "availability": "Node with caller-selected native Codex executable",
82
+ "protocol": "Native Codex App Server JSONL",
83
+ "normalization": "Returns the connected session; creates or resumes no thread and changes no provider or authentication selection."
84
+ },
85
+ {
86
+ "id": "mcp-stdio:createMcpStdioServer",
87
+ "name": "createMcpStdioServer",
88
+ "displayName": "createMcpStdioServer()",
89
+ "kind": "function",
90
+ "signature": "createMcpStdioServer({serverInfo,instructions,tools=[],resources=[],onDiagnostic}={})",
91
+ "entrypoints": ["arcane-os/mcp/stdio"],
92
+ "primaryImport": "arcane-os/mcp/stdio",
93
+ "group": "MCP STDIO",
94
+ "summary": "Owns one MCP STDIO session for caller-authored tools and static resources.",
95
+ "availability": "Node streams on Windows, Linux and macOS; Android requires host adaptation",
96
+ "protocol": "MCP 2025-11-25 initialize-era JSON-RPC newline transport",
97
+ "normalization": "Explicit CallToolResult/ReadResourceResult preserve complete content. Returns start, cancel, drain, close and closed; concurrent handlers, ordered output, cooperative cancellation and graceful EOF drain. No process launch or application-service ownership."
98
+ },
99
+ {
100
+ "id": "mcp-stdio:MCP_PROTOCOL_VERSION",
101
+ "name": "MCP_PROTOCOL_VERSION",
102
+ "displayName": "MCP_PROTOCOL_VERSION",
103
+ "kind": "constant",
104
+ "signature": "MCP_PROTOCOL_VERSION",
105
+ "entrypoints": ["arcane-os/mcp/stdio"],
106
+ "primaryImport": "arcane-os/mcp/stdio",
107
+ "group": "MCP STDIO",
108
+ "summary": "The explicit supported MCP initialization profile, 2025-11-25.",
109
+ "availability": "Node",
110
+ "protocol": "MCP initialization version negotiation",
111
+ "normalization": "Later profiles and optional unimplemented capabilities are not implied."
112
+ },
113
+ {
114
+ "id": "mcp-stdio:McpProtocolError",
115
+ "name": "McpProtocolError",
116
+ "displayName": "McpProtocolError",
117
+ "kind": "class",
118
+ "signature": "new McpProtocolError(code,message,data)",
119
+ "entrypoints": ["arcane-os/mcp/stdio"],
120
+ "primaryImport": "arcane-os/mcp/stdio",
121
+ "group": "MCP STDIO",
122
+ "summary": "Represents an explicit JSON-RPC failure with complete message and optional data.",
123
+ "availability": "Node",
124
+ "protocol": "JSON-RPC error object",
125
+ "normalization": "Preserves code, message and supplied data; ordinary tool domain failures use CallToolResult.isError."
126
+ },
127
+ {
128
+ "id": "core-repositories:resolveArcaneDataPaths",
129
+ "name": "resolveArcaneDataPaths",
130
+ "displayName": "resolveArcaneDataPaths()",
131
+ "kind": "function",
132
+ "signature": "resolveArcaneDataPaths({dataRoot}={})",
133
+ "entrypoints": ["arcane-os/core/repositories"],
134
+ "primaryImport": "arcane-os/core/repositories",
135
+ "group": "Native repository workspaces",
136
+ "summary": "Resolves persistent per-user ArcaneData and Repos locations without I/O or migration.",
137
+ "availability": "Node on Windows, Linux and macOS; Android supplies its persistent dataRoot",
138
+ "protocol": "Native filesystem paths",
139
+ "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."
140
+ },
141
+ {
142
+ "id": "core-repositories:createRepositoryWorkspace",
143
+ "name": "createRepositoryWorkspace",
144
+ "displayName": "createRepositoryWorkspace()",
145
+ "kind": "function",
146
+ "signature": "createRepositoryWorkspace({name,directory,dataRoot,remote,branch,onEvent,run=runProcess}={})",
147
+ "entrypoints": ["arcane-os/core/repositories"],
148
+ "primaryImport": "arcane-os/core/repositories",
149
+ "group": "Native repository workspaces",
150
+ "summary": "Owns one selected native working checkout with ArcaneData/Repos defaults and existing Git/process lifecycle.",
151
+ "availability": "Node with Git on Windows, Linux and macOS; Android requires host process adaptation",
152
+ "protocol": "Git working repository and SDK process adapter",
153
+ "normalization": "Returns directory, open, status, pull, push, write 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. write snapshots exact selected text and paths, writes files, stages/commits only literal owned paths and non-force pushes, preserving unrelated staged files and ordinary Git filters. Complete outputs and causal failures retain confirmed local/committed/pushed and uncertain outcomes."
154
+ },
155
+ {
156
+ "id": "core-speech:createSpeechService",
157
+ "name": "createSpeechService",
158
+ "displayName": "createSpeechService()",
159
+ "kind": "function",
160
+ "signature": "createSpeechService({stt,tts,signal}={})",
161
+ "entrypoints": ["arcane-os/core/speech"],
162
+ "primaryImport": "arcane-os/core/speech",
163
+ "group": "Core native speech",
164
+ "summary": "Composes host-supplied transcription and synthesis engines with independent loading and role readiness.",
165
+ "availability": "Node Core with explicitly supplied engines; engine platform, model and format support remain engine-owned",
166
+ "protocol": "arcane/1 speech.status/transcribe/synthesize with speech.state/progress",
167
+ "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"
168
+ },
169
+ {
170
+ "id": "core-speech:default",
171
+ "name": "default",
172
+ "displayName": "createSpeechService default export",
173
+ "kind": "function",
174
+ "signature": "default as createSpeechService",
175
+ "entrypoints": ["arcane-os/core/speech"],
176
+ "primaryImport": "arcane-os/core/speech",
177
+ "group": "Core native speech",
178
+ "summary": "Default binding for the same injected-engine native speech service factory.",
179
+ "availability": "Node Core with host-supplied engines",
180
+ "protocol": "arcane/1 service definition",
181
+ "normalization": "Binding identity equals the named createSpeechService export"
182
+ },
15
183
  {
16
184
  "id": "local-ai-image:createImageRuntime",
17
185
  "name": "createImageRuntime",
@@ -4026,6 +4194,34 @@
4026
4194
  "protocol": "arcane/1 renderer client ownership",
4027
4195
  "normalization": "Recognizes ESM and classic SDK installation identity; returns null after close or terminal failure and does not treat a foreign Arcane facade as an SDK client"
4028
4196
  },
4197
+ {
4198
+ "id": "core-client:subscribeCoreClient",
4199
+ "name": "subscribeCoreClient",
4200
+ "displayName": "subscribeCoreClient()",
4201
+ "kind": "function",
4202
+ "signature": "subscribeCoreClient(listener,{global=globalThis,emitCurrent=true,signal}={})",
4203
+ "entrypoints": ["arcane-os/core/client"],
4204
+ "primaryImport": "arcane-os/core/client",
4205
+ "group": "Core browser client",
4206
+ "summary": "Observes exact SDK client installation and retirement with current-state replay without creating a transport.",
4207
+ "availability": "Browser and native WebView JavaScript hosts",
4208
+ "protocol": "Core client installation lifecycle",
4209
+ "normalization": "Preserves client and error identities; reports current, installed, closed and transport-failed with previousClient; returns idempotent unsubscribe and supports AbortSignal. Installation does not imply runtime, service or model readiness"
4210
+ },
4211
+ {
4212
+ "id": "core-development:createDevelopmentCore",
4213
+ "name": "createDevelopmentCore",
4214
+ "displayName": "createDevelopmentCore()",
4215
+ "kind": "function",
4216
+ "signature": "createDevelopmentCore({appRoot=process.cwd(),application,version,services=[],serviceModules=[],context={},getReplayEvents,signal,onEvent}={})",
4217
+ "entrypoints": ["arcane-os/core/development", "arcane-os"],
4218
+ "primaryImport": "arcane-os/core/development",
4219
+ "group": "Core source development",
4220
+ "summary": "Composes application Core services and document-owned HTTP/SSE transport independently of local AI.",
4221
+ "availability": "Node on Windows, Linux and macOS; Android requires host adaptation",
4222
+ "protocol": "arcane/1 over source-development HTTP/SSE",
4223
+ "normalization": "Returns ready, handler, current and close synchronously; preserves factory options and explicit context, current lifecycle replay, correlated responses and chunks, document cancellation, accepted service work and owned drain. Explicit bootstrap does not block rendering or start application processes"
4224
+ },
4029
4225
  {
4030
4226
  "id": "core-classic-source:createCoreClassicSource",
4031
4227
  "name": "createCoreClassicSource",
@@ -4150,7 +4346,7 @@
4150
4346
  "summary": "Assembles selected application services and browser content with the SDK-owned Windows x64 WebView2 and SEA host.",
4151
4347
  "availability": "Node for assembly; Windows x64 with WebView2 Runtime for execution",
4152
4348
  "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"
4349
+ "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
4350
  },
4155
4351
  {
4156
4352
  "id": "native-windows-provider:arcaneNativeBuilderProvider",
@@ -120,6 +120,7 @@
120
120
  "AI_RUNTIME_STARTUP_EVENT",
121
121
  "AI_RUNTIME_STATES",
122
122
  "AI_RUNTIME_STATE_EVENT",
123
+ "continuesAIRuntimeOperation",
123
124
  "getAIRuntimeState",
124
125
  "publishAIRuntimeRoleState",
125
126
  "publishAIRuntimeRolesState",
@@ -131,8 +132,8 @@
131
132
  "summary": "Sticky mutable LLM, speech-to-text, and text-to-speech lifecycle snapshots, intents, subscriptions, and startup-settlement barriers.",
132
133
  "availability": "Cross-host in-process state contract; actual role readiness remains provider specific",
133
134
  "protocol": "arcane-ai-runtime-state/1 over the per-realm globalThis.arcaneEvents authority",
134
- "normalization": "Closed monotonic sticky role snapshots, transient lifecycle intents, synchronous current-state replay, AbortSignal cleanup, and startup settlement are normalized; events report state but grant no authority.",
135
- "surface": "Protocol/event/role/state constants; snapshot, state subscribe/publish, intent request/subscribe, and `startAIRuntime({startMuted,startTranscription,signal})` returning `{barrier,settled,cancel}`."
135
+ "normalization": "Closed monotonic sticky role snapshots, transient lifecycle intents, synchronous current-state replay, AbortSignal cleanup, and startup settlement are normalized; unloaded recovery/error may retain the exact busy operation until settlement, without readiness for new inference.",
136
+ "surface": "Protocol/event/role/state constants; snapshot, state subscribe/publish, intent request/subscribe, continuesAIRuntimeOperation(previous,current,operationId) for the real continuing runtime operation, and `startAIRuntime({startMuted,startTranscription,signal})` returning `{barrier,settled,cancel}`."
136
137
  },
137
138
  {
138
139
  "file": "runtime/arcane/modules/AnsiText.js",
@@ -1,7 +1,7 @@
1
1
  # Local AI through Core
2
2
 
3
- Core owns native llama.cpp and Ollama processes, ONNX worker sessions and
4
- selected local image generation. The browser retains its own
3
+ Core owns native llama.cpp and Ollama processes, ONNX worker sessions,
4
+ selected local image generation and retained Whisper transcription. The browser retains its own
5
5
  Wllama and ONNX implementations, and can also use an explicitly connected Core
6
6
  when that system service is available. Runtime installation, model loading and
7
7
  inference are separate operations.
@@ -43,14 +43,41 @@ 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`, `sdxl-base-1.0` 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.
57
+
58
+ The [SDXL Base 1.0 guide](local-image-sdxl.md) describes its complete checkpoint,
59
+ embedded text encoders and original VAE, 1024-by-1024 default canvas and
60
+ `txt2img` operation. Selecting a family retains the shared native context,
61
+ progress, cancellation and complete PNG result contract.
62
+
63
+ For native transcription, select a `whisper.cpp` runtime record with a `models`
64
+ array and an explicit `modelId` when selecting more than one model. For example,
65
+ `{id: 'whisper.cpp', backend: 'auto', models: ['whisper-small'], modelId: 'whisper-small'}`
66
+ selects the multilingual small model. Installation prepares its native
67
+ libraries, persistent SDK helper, FFmpeg decoder and selected model files;
68
+ loading and transcription remain separate operations. Development and native
69
+ assembly compose it through the shared speech service without changing the
70
+ browser's selected STT route. See [native Whisper](local-whisper.md) for the
71
+ complete configuration, platform, media and shutdown contracts.
72
+
73
+ The selected model stays loaded across recordings. An eligible native
74
+ accelerated failure may drain that helper and retry the same complete recording
75
+ once on the prepared CPU backend. That accepted request retains its actual
76
+ request identity while `recovering` is unloaded and busy; new inference remains
77
+ blocked until actual readiness. Cancellation, unload, close, replacement and
78
+ transport loss retain their owning cancellation behavior. A terminal engine
79
+ failure reaches the original request as its actual error rather than a
80
+ fabricated readiness success. See [native speech reconciliation](native-speech.md).
54
81
 
55
82
  `llamaCpp` accepts `url`, `model`, `modelsDirectory`, and an `args` string array.
56
83
  `model` selects a single GGUF file; `modelsDirectory` selects llama.cpp router
@@ -190,6 +217,52 @@ Those methods use Ollama's native API. Streaming uses the existing
190
217
  such as selection, settings and brain creation remain with their existing
191
218
  owners; they are separate from this runtime service.
192
219
 
220
+ ### Selected Ollama model readiness
221
+
222
+ The built-in `OLLAMA` LLM provider loads its selected model through Ollama's
223
+ empty `generate` request and separately confirms that selected model in
224
+ `running()` (`/api/ps`). A model catalog entry, a connected bridge, and a
225
+ successful preload response alone do not establish a ready model. Ollama's
226
+ empty preload response echoes the requested name; resident snapshots use its
227
+ shortest tagged name. Comparison applies Ollama's default `registry.ollama.ai`
228
+ host, `library` namespace and `latest` tag, so `moon-raccoon` and
229
+ `registry.ollama.ai/library/moon-raccoon:latest` identify the same resident
230
+ model. This comparison leaves outbound model names and payloads unchanged.
231
+ The provider preserves Ollama's configured/default retention duration.
232
+
233
+ Core refreshes and emits `localai.state` after its Ollama generation, chat,
234
+ embedding and catalog-changing operations, including a failed or cancelled
235
+ operation while the service remains available. Explicit `running()` inspection
236
+ also publishes the actual resident-model snapshot. An SDK-owned process exit
237
+ publishes its unavailable state through the existing process owner.
238
+ Successes and failures belong to their observation order and engine lifetime;
239
+ an older observation cannot replace newer state or a recovered engine's state.
240
+ The complete current failure remains available through the owning state surface.
241
+
242
+ The LLM provider subscribes before loading and retains that observation while
243
+ loaded. An observed selected-model unload, replacement, unavailable service or
244
+ service error revokes readiness and cancels the active request through the shared
245
+ AI runtime. Each inference checks current residency before dispatch and again
246
+ before accepting its terminal result. These `running({signal})` calls carry the
247
+ owning request's cancellation through Core to `/api/ps`. Streaming chunks still
248
+ arrive immediately through their existing path. Explicit provider unloading sends Ollama's
249
+ `keep_alive: 0` release request; another client can independently reload a model.
250
+
251
+ Ollama's documented public API exposes resident snapshots, not an ongoing
252
+ resident-model event subscription. Core adds no timer polling. External changes
253
+ between observations, including idle eviction or another client's model load,
254
+ remain unobserved until a subsequent owned operation or explicit inspection.
255
+ There is also an upstream race between a snapshot and the following request;
256
+ these checks do not claim an atomic reservation of the daemon's model state.
257
+ Applications consume the shared provider lifecycle rather than treating a stale
258
+ idle snapshot as proof for their next inference. `Ollama.readiness()` remains a
259
+ service-connectivity result and does not establish selected-model readiness.
260
+
261
+ Upstream references: [resident models](https://docs.ollama.com/api/ps),
262
+ [model-name defaults and comparison](https://github.com/ollama/ollama/blob/main/types/model/name.go),
263
+ [preload response and resident-name handling](https://github.com/ollama/ollama/blob/main/server/routes.go),
264
+ [preload and retention](https://docs.ollama.com/faq#how-can-i-preload-a-model-into-ollama-to-get-faster-response-times).
265
+
193
266
  ## Browser llama.cpp provider
194
267
 
195
268
  ```js
@@ -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