arcane-os 0.65.0 → 0.67.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 (40) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +1 -1
  3. package/browser-runtime/ai/browser-decisions.mjs +3 -2
  4. package/browser-runtime/ai/core-image.mjs +84 -34
  5. package/browser-runtime/ai/core-local.mjs +195 -43
  6. package/browser-runtime/ai/core-onnx.mjs +71 -12
  7. package/browser-runtime/ai/decision-runtime.mjs +14 -24
  8. package/docs/publishing.md +39 -0
  9. package/docs/reference/README.md +8 -1
  10. package/docs/reference/ai/browser-decisions.md +7 -4
  11. package/docs/reference/core-native-packaging.md +11 -4
  12. package/docs/reference/core-repositories.md +214 -11
  13. package/docs/reference/core-runtime.md +32 -5
  14. package/docs/reference/git-text-snapshot.md +15 -1
  15. package/docs/reference/inventory/package-api.json +41 -13
  16. package/docs/reference/inventory/runtime-modules.json +5 -4
  17. package/docs/reference/local-ai.md +119 -2
  18. package/docs/reference/local-image-generation.md +15 -4
  19. package/docs/reference/local-whisper.md +7 -1
  20. package/docs/reference/mcp-stdio.md +1 -1
  21. package/docs/reference/model-assets.md +50 -3
  22. package/docs/reference/native-decisions.md +181 -0
  23. package/docs/reference/native-speech.md +6 -0
  24. package/docs/reference/sdk-api.md +151 -16
  25. package/package.json +5 -2
  26. package/src/core/repositories.mjs +37 -14
  27. package/src/core/runtime.mjs +11 -0
  28. package/src/core/services/decisions.mjs +144 -0
  29. package/src/core/services/local-ai.mjs +31 -9
  30. package/src/core/services/model-assets.mjs +98 -13
  31. package/src/git-identity.mjs +96 -0
  32. package/src/git-text-snapshot.mjs +5 -3
  33. package/src/local-ai/decision-tokenizer-worker.mjs +31 -0
  34. package/src/local-ai/decision-tokenizer.mjs +109 -0
  35. package/src/local-ai/decisions.mjs +273 -0
  36. package/src/local-ai/dev.mjs +8 -2
  37. package/src/local-ai/onnx-worker.mjs +67 -7
  38. package/src/local-ai/onnx.mjs +23 -12
  39. package/src/native/portable-layout.mjs +8 -3
  40. package/src/repository.mjs +144 -4
@@ -54,18 +54,24 @@ alone does not make bare module names resolve in a browser.
54
54
  | Connect a browser to one Core transport | [Core browser client](core-client.md) |
55
55
  | Cancel one Core speech synthesis request without changing its payload | [Speech request lifetime](core-client.md#events-and-request-lifetime) and [Core facade](sdk-api.md#createcorefacade) |
56
56
  | Compose native Core dispatch, service lifecycle, and stdio hosting | [Native Core runtime](core-runtime.md) |
57
+ | Compose application Core services during source development, independently of local AI | [Development Core services](core-development.md) |
58
+ | Own an explicitly selected native Codex App Server session | [Codex App Server](codex-app-server.md) |
59
+ | Expose application-owned tools and static resources through Node STDIO | [MCP STDIO server](mcp-stdio.md) |
57
60
  | Run application-selected llama.cpp, Ollama or ONNX through Core | [Local AI through Core](local-ai.md) |
58
61
  | Generate complete local PNG images with a retained native model | [Local image generation](local-image-generation.md) |
59
62
  | Select FLUX.2 Klein 4B and its three complementary model resources | [FLUX.2 Klein 4B through Core](local-image-flux.md) |
60
63
  | Select the complete SDXL Base 1.0 checkpoint for text-to-image generation | [SDXL Base 1.0 through Core](local-image-sdxl.md) |
61
64
  | Compose independently loaded transcription and synthesis engines | [Native speech service](native-speech.md) |
62
65
  | Keep a native Whisper model loaded across complete recordings | [Native Whisper transcription](local-whisper.md) |
66
+ | Select the optional Intel NPU encoder with independent CUDA or CPU decoding | [Intel NPU Whisper](../guides/native-whisper-openvino.md) |
63
67
  | Edit an original PNG with a complete prompt and explicit strength | [Local image editing](local-image-editing.md) |
64
68
  | Project complete stored model files into native working files | [Model assets through Core](model-assets.md) |
65
69
  | Retain a Nemotron model and diarize caller-fed audio streams | [Native speaker diarization](diarization.md) |
66
70
  | Persist application-selected preferences through Core | [Core preferences service](core-preferences.md) |
67
71
  | Read complete selected Git text without changing a checkout | [Git text snapshots](git-text-snapshot.md) |
68
72
  | Own a native working checkout under per-user ArcaneData/Repos | [Native repository workspaces](core-repositories.md) |
73
+ | Read Git identity defaults or select child-only author and credential hints | [Git identity configuration](core-repositories.md#git-identity-configuration) |
74
+ | Write, commit and push complete selected repository text | [Selected-text repository writing](core-repositories.md#write-commit-and-push-selected-text) |
69
75
  | Build an installed-SDK portable Core payload | [Portable Core packaging](core-native-packaging.md) |
70
76
  | Pass host-selected state defaults and unchanged explicit launch values to services | [Launch-time locations](core-native-packaging.md#launch-time-locations) |
71
77
  | Build a Windows executable without an OS checkout | [Windows executable packaging](core-native-packaging.md#windows-executable) |
@@ -142,7 +148,8 @@ node tools/build-reference-site.mjs --write --source-ref <documentation-commit>
142
148
 
143
149
  The same option is accepted by `createReferenceSite({sourceRef})` and
144
150
  `writeReferenceSite({sourceRef})`. It reads the selected commit's package
145
- version, complete reference documents and inventories, inventory-selected
151
+ version, complete reference documents and inventories, the canonical
152
+ `docs/guides/native-whisper-openvino.md` guide when present, inventory-selected
146
153
  runtime sources, and authored site inputs directly from Git in memory. It
147
154
  creates no checkout or export and leaves source drafts untouched. Rendering
148
155
  uses the current canonical generator and its authored semantic contracts;
@@ -1,7 +1,8 @@
1
1
  # Browser typed decisions
2
2
 
3
- `arcane-os/ai/browser-decisions` owns browser-local Laya typed-decisions FP16
4
- and Julia-1 FP32 inference. It is separate from chat and speech because these
3
+ `arcane-os/ai/browser-decisions` owns browser-local Laya typed decisions
4
+ and Julia-1 inference. Laya defaults to FP16 and Julia to FP32; an explicit
5
+ `dtype` is forwarded unchanged to the selected upstream loader. It is separate from chat and speech because these
5
6
  models score caller-supplied options instead of generating conversational text.
6
7
  Applications supply the model repository, state, questions, option meanings and
7
8
  policy; the SDK owns the reusable tokenizer, tensors, inference and lifecycle.
@@ -66,6 +67,7 @@ it does not substitute a quantized graph or another model.
66
67
  | `model` | Required upstream repository/base URL accepted by Transformers.js. The application owns its selection. |
67
68
  | `revision` | Upstream revision, default `main`; select a stable revision when repeatable model selection is needed. |
68
69
  | `device` | Transformers.js backend, default `webgpu`; an explicit supported alternative is caller-owned. No automatic backend fallback. |
70
+ | `dtype` | Exact upstream precision selection; defaults to `fp16` for Laya and `fp32` for Julia. For Laya FP32, supply `dtype: 'fp32'`. Unsupported selections fail at the selected upstream loader rather than being replaced. |
69
71
  | `runtime.moduleUrl` | Defaults to the self-contained CDN entry `https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.3.0/dist/transformers.min.js`. The `.web.js` build expects a bundler to resolve its bare ONNX Runtime import and is unsuitable for a native module Worker. An explicit compatible public runtime URL may be supplied. |
70
72
  | `runtime.wasmPaths` | Optional upstream ONNX WASM location passed to the selected runtime's public environment API. |
71
73
 
@@ -75,10 +77,11 @@ network, cross-origin and backend availability still apply. WebGPU needs a
75
77
  compatible browser/device context. Unsupported precision or backend errors
76
78
  are returned, not replaced with a different model, backend or precision.
77
79
 
78
- Laya selects `dtype: 'fp16'`, loading `onnx/model_fp16.onnx` and its
80
+ Laya defaults to `dtype: 'fp16'`, loading `onnx/model_fp16.onnx` and its
79
81
  `model_fp16.onnx_data` companion through Transformers.js. The published mixed
80
82
  precision graph retains selected operations/outputs in FP32; FP16 selection
81
- does not claim every graph operation runs in half precision.
83
+ does not claim every graph operation runs in half precision. Explicit
84
+ `dtype: 'fp32'` selects the repository's FP32 graph through that same loader.
82
85
 
83
86
  Julia selects `dtype: 'fp32'`, loading root `model.onnx` with the exact
84
87
  `model.onnx.data` external-data name. Its custom five-input graph is loaded
@@ -261,10 +261,17 @@ service exposes retained worker sessions through `onnx.load/run/unload/status`;
261
261
  model files remain caller-selected application resources. See
262
262
  [native ONNX sessions](local-ai.md#native-onnx-sessions).
263
263
 
264
- Selected `stable-diffusion.cpp` additionally composes
265
- `createLocalImageService` from `arcane-os/core/image` and one shared
266
- `createModelAssetService` from `arcane-os/core/model-assets`. The image factory
267
- receives the full authored selection plus that same model-assets instance.
264
+ Selecting ONNX, image generation, or both composes one shared
265
+ `createModelAssetService` from `arcane-os/core/model-assets`. Native application
266
+ services obtain that same definition with `await context.getService('model-assets')`.
267
+ They obtain the selected local-AI owner with `await context.getService('local-ai')`
268
+ and its current native ONNX handle with `getONNXRuntime()`. These lookups await
269
+ only their selected service startup, independently of renderer readiness. See
270
+ [native service ownership and cleanup](local-ai.md#native-service-owners).
271
+
272
+ Selected `stable-diffusion.cpp` additionally composes `createLocalImageService`
273
+ from `arcane-os/core/image`. The image factory receives the full authored
274
+ selection plus that same model-assets instance.
268
275
  Library, Koffi binding and variant paths resolve from the artifact root;
269
276
  ordinary browser imports use `arcane-os/ai/core-image` and
270
277
  `arcane-os/ai/core-model-assets` through the managed import map.
@@ -24,7 +24,8 @@ The Android host also supplies Git/process execution through the existing
24
24
  process-adapter contract; this module does not install Git or choose shared
25
25
  Android storage.
26
26
 
27
- The factory's first actual operation creates necessary parent directories.
27
+ The factory's first operation that prepares a checkout creates necessary parent
28
+ directories. The read-only `configuration` operation never prepares one.
28
29
  No existing data is moved, copied, deleted, renamed or migrated. `appRoot`,
29
30
  `stateRoot`, preferences, OPFS and the existing CLI/workspace defaults remain
30
31
  independent and unchanged.
@@ -46,8 +47,8 @@ const status = await repository.status({signal});
46
47
  await repository.close();
47
48
  ```
48
49
 
49
- `createRepositoryWorkspace({name,directory,dataRoot,remote,branch,onEvent,run}={})`
50
- returns `{directory,open,status,pull,push,write,close,drain,dispose}`. The `directory`
50
+ `createRepositoryWorkspace({name,directory,dataRoot,remote,branch,gitIdentity,onEvent,run}={})`
51
+ returns `{directory,open,status,configuration,pull,push,write,close,drain,dispose}`. The `directory`
51
52
  property is the absolute selected working path.
52
53
 
53
54
  - Omit `directory` to select `<repositoriesRoot>/<name>`. The application supplies
@@ -67,15 +68,17 @@ property is the absolute selected working path.
67
68
  authentication remain with Git and the native host. The SDK adds no download,
68
69
  credential store, polling, network retry or process supervisor.
69
70
 
70
- The open/status/pull/push methods accept `{signal}={}` and return promises;
71
+ The open/status/configuration methods accept `{signal}={}` and return promises;
72
+ pull/push accept `{target,signal}={}` with an optional captured destination.
71
73
  `write` accepts the complete file/message request described below:
72
74
 
73
75
  | Method | Result and side effect |
74
76
  |---|---|
75
77
  | `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
78
  | `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
+ | `configuration` | Observes the existing working root, symbolic HEAD, origin and configured upstream. It never clones, initializes or fetches. |
80
+ | `pull` | Prepares the checkout if needed, then runs clean-checkout, fast-forward-only `repositoryPull`, optionally using the operation's selected target. |
81
+ | `push` | Prepares the checkout if needed, then runs `repositoryPush`, optionally using the operation's selected target, preserving support for unrelated uncommitted working files. |
79
82
  | `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
83
  | `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
84
 
@@ -87,6 +90,201 @@ A failed or cancelled clone reports the actual failure; any remaining directory
87
90
  is retained for application-owned inspection. There is no automatic deletion or
88
91
  destructive retry. Filesystem failures and complete Git diagnostics propagate.
89
92
 
93
+ ## Existing checkout configuration and selected targets
94
+
95
+ `configuration({signal}={})` observes an existing checkout without invoking
96
+ `open`, creating directories, cloning, initializing, fetching or changing Git
97
+ configuration. A missing repository reports the actual Git failure. A bare
98
+ cache or nested checkout directory reports `ARCANE_REPOSITORY_DIRECTORY_INVALID`.
99
+ Its result is:
100
+
101
+ ```text
102
+ {
103
+ repositoryRoot,
104
+ headRef: fullSymbolicRef | null,
105
+ origin: {urls: [...], pushUrls: [...]},
106
+ upstream: {remoteNames: [...], mergeRefs: [...], urls: [...], pushUrls: [...]} | null
107
+ }
108
+ ```
109
+
110
+ `repositoryRoot` is this owner's absolute selected working root. `headRef` is
111
+ the complete symbolic HEAD, including an unborn branch, or `null` for detached
112
+ HEAD. `upstream` is `null` when HEAD does not name a local branch. Otherwise its
113
+ arrays contain that branch's configured `remote` and `merge` values; `urls` and
114
+ `pushUrls` observe the effective last configured remote name. A `.` remote
115
+ means the local repository and has no remote URL arrays. Origin is observed
116
+ independently, even when it is not the upstream.
117
+
118
+ Arrays retain configured order, repeated values, complete UTF-8 strings and
119
+ empty strings. `[]` means unset; `['']` means an explicit empty value. The
120
+ reader honors configured includes and ordinary Git configuration precedence.
121
+ Unset push URLs do not imply that Git cannot push: Git retains its normal URL
122
+ fallback and rewrite behavior. These are configuration observations, not
123
+ resolved endpoints, authentication, account identity or ownership proof.
124
+ The SDK neither queries a credential helper nor changes configuration here.
125
+
126
+ Metadata uses the shared raw-Git-text reader. Lifecycle/stderr events remain
127
+ with the process owner, raw stdout remains parser-owned, and undecodable text
128
+ reports `ARCANE_GIT_CONFIGURATION_NOT_TEXT`. Failures retain complete raw
129
+ stdout, process diagnostics and causal errors using the identity reader's
130
+ documented attachment behavior. One observation uses four read-only Git
131
+ commands for an attached local branch, or three otherwise. Results are not a
132
+ transaction with later work or external Git activity. The app owns any decision
133
+ that the current checkout corresponds to its selected repository and branch.
134
+
135
+ The optional `target:{remote,ref}` on `pull`, `push` and `write` selects that
136
+ operation's Git destination. Both fields are nonempty strings representable by
137
+ the native process transport. The SDK captures their exact strings when the
138
+ call is accepted; later edits to the target object or UI selection cannot
139
+ redirect queued or active work. Git owns ref parsing, URL interpretation,
140
+ credentials, hooks and remote outcomes. This target is independent of the
141
+ factory's `remote`/`branch`, which remain initial-clone inputs only.
142
+
143
+ ```javascript
144
+ const observed = await repository.configuration({signal});
145
+ // The app decides whether observed.headRef and configured URLs match its choice.
146
+ const target = {remote: connection.locator, ref: connection.ref};
147
+ await repository.pull({target, signal});
148
+ const result = await repository.write({files: selectedFiles, message, target, signal});
149
+ ```
150
+
151
+ A targeted pull uses `git pull --ff-only -- <remote> <ref>:`. The trailing colon
152
+ is Git's source-only fetch framing; the fetched history is integrated into the
153
+ current branch. It does not switch branches or reset files/history. The existing
154
+ clean-checkout requirement remains. A targeted push uses
155
+ `git push --no-follow-tags -- <remote> HEAD:<ref>`: current HEAD is published to
156
+ the selected ref, without force or implicit configured tag following. Existing
157
+ history is still sent when Git needs it. Ordinary conflicting Git settings or
158
+ remote rejection remain actual failures; no settings are rewritten.
159
+
160
+ Omitting `target` preserves ordinary configured pull/push behavior and its
161
+ existing result shape. Targeted pull/push results add the captured `target` and
162
+ complete `stdout`/`stderr` alongside the existing `action`, `repositoryRoot`,
163
+ `branch` and compatibility `output` field. Writer results and failure outcomes
164
+ add that same captured `target`. There is no hidden pre-write pull, branch
165
+ selection, retry, reset, force, reversal or recommit. The app decides when to
166
+ observe, refresh, write and publish. See Git's [pull](https://git-scm.com/docs/git-pull),
167
+ [push](https://git-scm.com/docs/git-push) and [configuration](https://git-scm.com/docs/git-config)
168
+ contracts.
169
+
170
+ ## Git identity configuration
171
+
172
+ ```javascript
173
+ import {readGitIdentity, createRepositoryWorkspace} from 'arcane-os/core/repositories';
174
+
175
+ const defaults = await readGitIdentity({signal});
176
+ const observations = await readGitIdentity({directory: existingRepositoryDirectory, signal});
177
+ const repository = createRepositoryWorkspace({
178
+ name: 'moon-cheese-dispatches',
179
+ remote: applicationConnection.remote,
180
+ gitIdentity: {name: 'Moon Dispatcher', email: 'moon@example.invalid', username: 'moon-account'}
181
+ });
182
+ ```
183
+
184
+ `readGitIdentity({directory,signal,onEvent,run=runProcess}={})` reads only
185
+ `user.name`, `user.email` and `github.user`. It returns:
186
+
187
+ ```text
188
+ {
189
+ global: {name, email, githubUser},
190
+ local: {name, email, githubUser} | null,
191
+ effective: {name, email, githubUser} | null
192
+ }
193
+ ```
194
+
195
+ Every observed field is the complete UTF-8 Git configuration string, including
196
+ an empty string, leading U+FEFF and embedded newlines, or `null` when unset.
197
+ Git can store values outside UTF-8; those produce
198
+ `ARCANE_GIT_IDENTITY_NOT_TEXT` instead of replacement characters. Global and
199
+ local observations select Git's corresponding file scopes and honor configured
200
+ includes. With an existing
201
+ repository `directory`, `effective` reads ordinary Git configuration in that
202
+ repository context, including system, global, local, worktree and command
203
+ configuration where applicable. Equal local and global values remain separate
204
+ observations; the SDK does not infer who wrote or owns a setting. The last
205
+ configured scalar value wins within each observation.
206
+
207
+ Without `directory`, only global configuration is read and `local`/`effective`
208
+ are `null`. Relative directories resolve from the process working directory.
209
+ Git retains its normal environment and conditional-include context; when no
210
+ directory is supplied, that context is the process working directory. These
211
+ are independent configuration observations, not a transaction or a claim about
212
+ the identity of a prior commit, environment-derived author, or authenticated
213
+ GitHub account. `github.user` is a non-secret configured default, not proof of
214
+ authentication.
215
+
216
+ One targeted Git command reads each requested scope. Independent observations
217
+ start concurrently and all accepted commands finish their process cleanup
218
+ before the reader settles. `signal` uses the existing process owner; the shared
219
+ SDK event queue serializes `onEvent` delivery with its usual backpressure.
220
+ The reader consumes raw stdout through the existing process contract; stdout
221
+ is parsed as configuration rather than emitted as text events. Process
222
+ lifecycle and stderr events retain their ordinary route. A supplied `run`
223
+ adapter must honor that raw-output contract.
224
+ Git's no-match result produces unset fields; other process,
225
+ configuration, observer and cancellation failures remain complete. A single
226
+ failure retains its original object, code, cause and process `details`; the
227
+ reader adds complete captured stdout as the `rawStdout` Buffer on that error.
228
+ If the error already has that property or cannot accept it, a new error retains
229
+ the original as `cause`, preserves its code, process details and exit code, and
230
+ holds this observation's `rawStdout`. Original causal failures stay on that
231
+ original error; an attachment exception is retained as `attachmentError`.
232
+ An existing `rawStdout` property is never overwritten or invoked to read its value.
233
+ The process result's `stdout` remains `null` in raw mode, and its stderr and
234
+ other diagnostics remain intact. A decoding failure likewise carries its
235
+ original decoding `cause`, complete process `details` and `rawStdout`.
236
+ An observer failure already represented by a process error is not added again;
237
+ genuinely separate failures use `AggregateError.errors`, each retaining its
238
+ own diagnostics.
239
+ No configuration file is written and no credential helper is queried by this
240
+ reader. The application owns any saved non-secret defaults and repository
241
+ overrides through its existing preferences.
242
+
243
+ Both this workspace factory and
244
+ [`createGitTextSnapshot`](git-text-snapshot.md) accept optional
245
+ `gitIdentity:{name?,email?,username?}`. They capture supplied strings once during
246
+ I/O-free construction. Later edits to that object or a UI selection do not
247
+ change accepted work. Omitted or `undefined` fields preserve ordinary inherited
248
+ behavior; removing an application override means omitting that field on the
249
+ next owner, not changing unmanaged repository configuration. Empty strings are
250
+ passed explicitly to Git. Non-string values, NUL and text that cannot be
251
+ represented by the native process transport report `TypeError` without silently
252
+ rewriting the input.
253
+
254
+ An application's explicit "global author" choice differs from ordinary Git
255
+ inheritance. Pass the observed global `name` and `email` as selected strings to
256
+ override repository-local author values for those fields. A global `null` means
257
+ that field is unset, not a selected value: passing `null` reports `TypeError`,
258
+ and omitting the field allows normal inheritance, including repository-local
259
+ configuration. The application must describe that partial/inherited choice
260
+ accurately or obtain the missing value before presenting an all-global author
261
+ selection. An empty string is a distinct explicit value that Git may reject.
262
+ Changed application choices apply to future owners; accepted operations retain
263
+ their original selection and may finish without being discarded.
264
+
265
+ Each supplied name/email becomes command-local `-c user.name=...` or
266
+ `-c user.email=...` and the corresponding child-only `GIT_AUTHOR_*` and
267
+ `GIT_COMMITTER_*` fields. Those selected fields take precedence over inherited
268
+ author/committer settings and environment values; omitted fields, dates and
269
+ unrelated environment remain inherited. Git retains its ordinary commit
270
+ identity formatting and may reject an unusable identity. The SDK changes
271
+ neither `process.env` nor global/local Git files.
272
+
273
+ `username` supplies only command-local `credential.username`. Git's existing
274
+ credential helper and remote protocol still own actual authentication. A
275
+ URL-embedded username or helper behavior can affect the selected credential;
276
+ this option neither rewrites the remote nor selects an SSH account or proves a
277
+ GitHub login. No account enumeration, secret storage or `gh` dependency is added.
278
+ See Git's [configuration](https://git-scm.com/docs/git-config),
279
+ [author environment](https://git-scm.com/docs/git#_git_commits) and
280
+ [credential username](https://git-scm.com/docs/gitcredentials) contracts.
281
+
282
+ The selected settings accompany every workspace Git command, including clone,
283
+ pull, commit and push, and every bare-snapshot Git command, including init and
284
+ fetch. Existing arguments, content, output, errors, queue and cancellation
285
+ semantics remain unchanged. Other repository helpers and CLI cwd defaults keep
286
+ their existing behavior.
287
+
90
288
  ## Write, commit and push selected text
91
289
 
92
290
  ```javascript
@@ -97,7 +295,7 @@ const result = await repository.write({
97
295
  });
98
296
  ```
99
297
 
100
- `write({files:[{path,content}],message,signal}={})` requires at least one explicit
298
+ `write({files:[{path,content}],message,target,signal}={})` requires at least one explicit
101
299
  file, a nonempty commit message and string content (including an empty string).
102
300
  Paths name working files relative to this repository, not its root, outside
103
301
  paths or Git-owned `.git` metadata. Strings must be representable as UTF-8;
@@ -121,9 +319,11 @@ native host.
121
319
  One `git --literal-pathspecs add -- <paths>` stages only those exact names.
122
320
  One `git --literal-pathspecs commit --only --cleanup=verbatim --file - -- <paths>`
123
321
  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,
322
+ message is streamed unchanged through standard input. Without `target`, one
323
+ ordinary `git push` then uses that repository's existing remote/ref configuration, the optional
324
+ process-local identity selection above, existing credentials and hooks.
325
+ With `target`, the final push uses the selected current-HEAD mapping above.
326
+ There is no implicit pull, branch switch, forced push,
127
327
  hook bypass, automatic retry, rollback or reset. If Git reports no changes to
128
328
  commit, that actual failure is returned; the SDK creates no empty commit.
129
329
  These are Git's documented [selected-path commit](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---only)
@@ -133,7 +333,8 @@ Existing Git attributes, clean filters, EOL settings and hooks continue to apply
133
333
  when Git stages/commits content. The filesystem write preserves the original
134
334
  text; this API does not claim that repository-configured filters leave Git blob
135
335
  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.
336
+ refs selected by the repository's ordinary push configuration when no explicit
337
+ target is supplied.
137
338
 
138
339
  ### Result and failure outcomes
139
340
 
@@ -156,6 +357,8 @@ Successful completion returns:
156
357
 
157
358
  Each output record retains complete stdout/stderr. `code` and the process
158
359
  termination `signal` are included when a completed process result is available.
360
+ When supplied, `target:{remote,ref}` is included in the result or failure outcome
361
+ with the original accepted strings.
159
362
  An in-progress write also records its current `path` on a failure outcome.
160
363
  `writtenPaths` records successful filesystem writes in input order; `written`
161
364
  becomes true only after every requested write succeeds. The other booleans
@@ -66,11 +66,34 @@ service's startup before invoking its handler. State errors use the shared
66
66
  complete diagnostic serialization; the startup promise retains its original
67
67
  rejection value.
68
68
 
69
- Each lifecycle hook receives `{application, service, emit}`. Each request handler
70
- receives `(parameters, {application, service, emit, requestId, signal})`, with
69
+ Each lifecycle hook receives `{application, service, emit, getService}`. Each request handler
70
+ receives `(parameters, {application, service, emit, getService, requestId, signal})`, with
71
71
  `this` bound to its service definition. A hook or handler may publish a complete
72
72
  service-owned event through `emit(event, data)`.
73
73
 
74
+ ### Native service composition
75
+
76
+ `await runtime.getService(name)` and `await context.getService(name)` return the
77
+ actual registered service definition after that service's shared startup
78
+ promise. A lookup can start its selected dependency before `runtime.start()`;
79
+ it waits for that dependency alone, with no renderer, transport request or
80
+ all-service readiness barrier. Concurrent lookups reuse the same startup and
81
+ return the same object. Applications keep their service dependencies acyclic.
82
+
83
+ Use the returned service's documented native members, such as
84
+ [`getONNXRuntime()`](local-ai.md#native-service-owners), for same-process
85
+ composition. RPC handlers remain owned by the dispatcher; calling entries in
86
+ `service.methods` directly does not supply request tracking or cancellation.
87
+ No service lookup is exposed over the browser protocol.
88
+
89
+ An unregistered name rejects with `CORE_SERVICE_UNAVAILABLE`. Startup failure
90
+ rejects with the original error. New lookups reject with `CORE_CLOSING` once
91
+ shutdown begins; an already accepted lookup still settles with its startup.
92
+ Lookup provides readiness, not a lifetime lease or ownership transfer. Retain
93
+ each acquired native owner according to its own documented cleanup contract,
94
+ and use that retained handle during disposal rather than requesting a new one.
95
+ Independent services still dispose concurrently.
96
+
74
97
  ## State and frames
75
98
 
76
99
  `runtime.current()` returns dispatcher state, application, version, per-service
@@ -133,9 +156,13 @@ the handler runs. A service that does not finish or respond to cancellation is
133
156
  still unfinished; the SDK does not report a forced timeout as successful cleanup.
134
157
 
135
158
  Use `lifetime:'service'` for accepted work, such as a save, that must survive a
136
- renderer cancellation or disconnect. These operations are not aborted by the
137
- request cancellation controls or by normal Core shutdown. The service still
138
- owns its persistence, queueing and failure semantics.
159
+ renderer cancellation or disconnect. The dispatcher does not abort these
160
+ operations through request cancellation controls or its own shutdown. The
161
+ service still owns its persistence, queueing and failure semantics. A composing
162
+ host or native service can abort its own lifetime signal during shutdown;
163
+ in-flight native inference can therefore be cancelled even when the dispatcher
164
+ retains a service-lifetime response. Service lifetime does not promise survival
165
+ of native host shutdown.
139
166
 
140
167
  `runtime.close()` is idempotent and retains the same completion promise. It stops
141
168
  accepting new requests, cancels request-lifetime operations, waits for accepted
@@ -33,12 +33,26 @@ policy stable for the lifetime of its snapshot owner.
33
33
 
34
34
  ## API and lifecycle
35
35
 
36
- `createGitTextSnapshot({cacheDirectory,remote,ref,selectPath,onEvent,run})`
36
+ `createGitTextSnapshot({cacheDirectory,remote,ref,selectPath,gitIdentity,onEvent,run})`
37
37
  returns `{refresh,close,drain,dispose}`. `run` defaults to the SDK's existing
38
38
  `runProcess`; applications normally omit it. It is the same process adapter
39
39
  contract, not a second process supervisor. `onEvent` is the ordinary SDK event
40
40
  callback and follows its asynchronous completion/error contract.
41
41
 
42
+ Optional `gitIdentity:{name?,email?,username?}` uses the shared
43
+ [Git identity configuration contract](core-repositories.md#git-identity-configuration).
44
+ Supplied strings are captured during construction and accompany every Git
45
+ command, including bare initialization and fetch, without changing the remote,
46
+ ref, config files or process environment. Explicit name/email use command-local
47
+ configuration and child-only author/committer fields; omitted fields remain
48
+ inherited. `username` is only Git's credential username hint, not authenticated
49
+ account proof or SSH account selection. Read separate global/local/effective
50
+ configuration through `readGitIdentity` from `arcane-os/core/repositories`;
51
+ the reader also accepts an existing bare cache directory. Applications retain
52
+ saved non-secret choices and per-connection overrides. Identity selection adds
53
+ no process or query to refresh and does not attach a caller's abort to shared
54
+ acquisition.
55
+
42
56
  - `refresh({signal}={})` fetches the selected ref and returns
43
57
  `{revision,files:[{path,content}]}`. `revision` is Git's opaque selected commit
44
58
  name, not an SDK integrity record. Every file comes from that exact revision,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "sdkVersion": "0.64.0",
3
+ "sdkVersion": "0.66.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": 288,
9
+ "memberCount": 290,
10
10
  "runtimeSubpathPatterns": {
11
11
  "arcane-os/modules/*": "./runtime/arcane/modules/*",
12
12
  "arcane-os/entities/*": "./runtime/arcane/entities/*"
@@ -54,6 +54,20 @@
54
54
  "protocol": "Owned configure/build/install process lifecycle",
55
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
56
  },
57
+ {
58
+ "id": "local-ai-whisper-openvino-build:buildWhisperOpenVinoRuntime",
59
+ "name": "buildWhisperOpenVinoRuntime",
60
+ "displayName": "buildWhisperOpenVinoRuntime()",
61
+ "kind": "function",
62
+ "signature": "async buildWhisperOpenVinoRuntime({sourceDirectory,openvinoDirectory,cudaDirectory,outputRoot,cmake='cmake',generator,cmakeArgs=[],env,signal,onEvent}={})",
63
+ "entrypoints": ["arcane-os/local-ai/whisper/openvino-build"],
64
+ "primaryImport": "arcane-os/local-ai/whisper/openvino-build",
65
+ "group": "Core native speech",
66
+ "summary": "Produces the optional Intel NPU encoder runtime from installed matching Whisper/OpenVINO sources and an existing Windows x64 toolchain.",
67
+ "availability": "Windows x64 Node with Whisper 1.9.4 source, OpenVINO 2026.3.1 development tree and compatible CMake/MSVC; other platform distributions require separate native producers",
68
+ "protocol": "Owned configure/build process lifecycle and complete native runtime assembly",
69
+ "normalization": "Returns version/openvinoVersion/platform/architecture/encoder/backend/backends/root/directory/libraryDirectory/copied sourceDirectory and complete configure/compile diagnostics; retains NPU/CPU and optional supplied CUDA libraries plus notices, preserves process failures and cancellation, installs no model, driver or toolchain"
70
+ },
57
71
  {
58
72
  "id": "codex-app-server:createCodexAppServerSession",
59
73
  "name": "createCodexAppServerSession",
@@ -143,14 +157,28 @@
143
157
  "name": "createRepositoryWorkspace",
144
158
  "displayName": "createRepositoryWorkspace()",
145
159
  "kind": "function",
146
- "signature": "createRepositoryWorkspace({name,directory,dataRoot,remote,branch,onEvent,run=runProcess}={})",
160
+ "signature": "createRepositoryWorkspace({name,directory,dataRoot,remote,branch,gitIdentity,onEvent,run=runProcess}={})",
147
161
  "entrypoints": ["arcane-os/core/repositories"],
148
162
  "primaryImport": "arcane-os/core/repositories",
149
163
  "group": "Native repository workspaces",
150
164
  "summary": "Owns one selected native working checkout with ArcaneData/Repos defaults and existing Git/process lifecycle.",
151
165
  "availability": "Node with Git on Windows, Linux and macOS; Android requires host process adaptation",
152
166
  "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."
167
+ "normalization": "Returns directory, open, status, configuration, pull, push, write and identical close/drain/dispose hooks. Only missing or empty destinations clone; existing roots are preserved. configuration observes the existing root, symbolic HEAD, origin URL/pushURL arrays and branch remote/merge/upstream URL arrays without clone/init/fetch, preserving unset, empty and repeated values. Explicit paths remain selected. Same-directory operations serialize within the process; cancellation and shutdown join accepted process work. pull/push/write accept a captured target {remote,ref} for current-branch fast-forward pull or non-force current-HEAD selected-ref push; omission retains ordinary configured behavior. write snapshots exact text and paths, stages/commits only literal owned paths and preserves unrelated staged files and Git filters. Complete outputs and causal failures retain confirmed local/committed/pushed and uncertain outcomes plus the supplied target. Optional gitIdentity captures name/email/username for child Git operations only; omitted fields remain inherited and no config file is written."
168
+ },
169
+ {
170
+ "id": "core-repositories:readGitIdentity",
171
+ "name": "readGitIdentity",
172
+ "displayName": "readGitIdentity()",
173
+ "kind": "function",
174
+ "signature": "readGitIdentity({directory,signal,onEvent,run=runProcess}={})",
175
+ "entrypoints": ["arcane-os/core/repositories"],
176
+ "primaryImport": "arcane-os/core/repositories",
177
+ "group": "Native repository workspaces",
178
+ "summary": "Reads separate global, repository-local and effective non-secret Git identity configuration.",
179
+ "availability": "Node with Git on Windows, Linux and macOS; Android requires host process adaptation",
180
+ "protocol": "Git config NUL-delimited transport through the SDK process adapter",
181
+ "normalization": "Returns {global,local,effective} observations with complete name/email/githubUser strings or null when unset. Empty strings and configured includes are preserved. Without directory only global is observed and local/effective are null. Concurrent scope reads join process cleanup; complete failures propagate singly or through AggregateError. Changes no config files and claims no authenticated account or environment-resolved author."
154
182
  },
155
183
  {
156
184
  "id": "core-speech:createSpeechService",
@@ -311,14 +339,14 @@
311
339
  "name": "createGitTextSnapshot",
312
340
  "displayName": "createGitTextSnapshot()",
313
341
  "kind": "function",
314
- "signature": "createGitTextSnapshot({cacheDirectory,remote,ref,selectPath,onEvent,run=runProcess}={})",
342
+ "signature": "createGitTextSnapshot({cacheDirectory,remote,ref,selectPath,gitIdentity,onEvent,run=runProcess}={})",
315
343
  "entrypoints": ["arcane-os"],
316
344
  "primaryImport": "arcane-os",
317
345
  "group": "Workspace, doctor, repository, and server",
318
346
  "summary": "Reads complete selected text from one fetched revision using a dedicated bare Git object cache and batched retrieval.",
319
347
  "availability": "Node with Git; Android requires a host supplying Git/process capability",
320
348
  "protocol": "Git tree and batched blob transport through the shared process owner",
321
- "normalization": "Returns {refresh,close,drain,dispose}; refresh yields {revision,files:[{path,content}]}, shares concurrent work, reuses unchanged revisions, preserves exact UTF-8 text, isolates caller cancellation and drains accepted work. See git-text-snapshot.md."
349
+ "normalization": "Returns {refresh,close,drain,dispose}; refresh yields {revision,files:[{path,content}]}, shares concurrent work, reuses unchanged revisions, preserves exact UTF-8 text, isolates caller cancellation and drains accepted work. Optional gitIdentity captures name/email/username for child Git commands including bare init and fetch, without changing config files, payloads or shared acquisition lifetime. See git-text-snapshot.md."
322
350
  },
323
351
  {
324
352
  "id": "diarization:createDiarization",
@@ -465,14 +493,14 @@
465
493
  "name": "createBrowserDecisionModel",
466
494
  "displayName": "createBrowserDecisionModel()",
467
495
  "kind": "function",
468
- "signature": "createBrowserDecisionModel({family,model,revision,device,runtime})",
496
+ "signature": "createBrowserDecisionModel({family,model,revision,device,dtype,runtime}={})",
469
497
  "entrypoints": ["arcane-os/ai/browser-decisions"],
470
498
  "primaryImport": "arcane-os/ai/browser-decisions",
471
499
  "group": "Browser typed decisions",
472
- "summary": "Explicit-load Laya FP16 and Julia-1 FP32 decisions with complete inputs and graph results.",
500
+ "summary": "Explicit-load Laya and Julia-1 decisions with caller-selected precision, complete inputs and graph results.",
473
501
  "availability": "Browser module Workers and the selected Transformers.js backend; import/construction starts no model load",
474
502
  "protocol": "Caller-owned state/question/options rows; five-input decision graph; native Worker request/result lifecycle",
475
- "normalization": "Full field tokenization, raw logits and unrounded softmax; no policy thresholds, storage or precision fallback"
503
+ "normalization": "Full field tokenization, raw logits and unrounded softmax; dtype defaults to fp16 for Laya and fp32 for Julia, with explicit values forwarded unchanged to the upstream loader; no policy thresholds, storage or precision fallback"
476
504
  },
477
505
  {
478
506
  "id": "root:acceptWebSocket",
@@ -2078,13 +2106,13 @@
2078
2106
  "name": "repositoryPull",
2079
2107
  "displayName": "repositoryPull()",
2080
2108
  "kind": "function",
2081
- "signature": "async repositoryPull({ workspaceRoot=process.cwd(), signal, onEvent, run=runProcess }={})",
2109
+ "signature": "async repositoryPull({ workspaceRoot=process.cwd(), target, signal, onEvent, run=runProcess }={})",
2082
2110
  "entrypoints": [
2083
2111
  "arcane-os"
2084
2112
  ],
2085
2113
  "primaryImport": "arcane-os",
2086
2114
  "group": "Workspace, doctor, repository, and server",
2087
- "summary": "Runs one fast-forward-only pull after proving the selected repository worktree is clean.",
2115
+ "summary": "Runs one fast-forward-only pull into the selected clean worktree, optionally from a captured remote/ref target.",
2088
2116
  "availability": "Node; network-assisted Git",
2089
2117
  "protocol": "Node ESM",
2090
2118
  "normalization": "SDK-normalized inputs, errors, events, and documented result"
@@ -2094,13 +2122,13 @@
2094
2122
  "name": "repositoryPush",
2095
2123
  "displayName": "repositoryPush()",
2096
2124
  "kind": "function",
2097
- "signature": "async repositoryPush({ workspaceRoot=process.cwd(), signal, onEvent, run=runProcess }={})",
2125
+ "signature": "async repositoryPush({ workspaceRoot=process.cwd(), target, signal, onEvent, run=runProcess }={})",
2098
2126
  "entrypoints": [
2099
2127
  "arcane-os"
2100
2128
  ],
2101
2129
  "primaryImport": "arcane-os",
2102
2130
  "group": "Workspace, doctor, repository, and server",
2103
- "summary": "Pushes the selected attached branch through the repository's configured remote and credentials.",
2131
+ "summary": "Pushes the attached branch through ordinary configured Git or an explicit captured current-HEAD destination without force.",
2104
2132
  "availability": "Node; network-assisted Git",
2105
2133
  "protocol": "Node ESM",
2106
2134
  "normalization": "SDK-normalized inputs, errors, events, and documented result"
@@ -1013,13 +1013,14 @@
1013
1013
  "kind": "esm",
1014
1014
  "exports": [
1015
1015
  "isOllamaModelIdentifier",
1016
- "normalizeOllamaModelIdentifier"
1016
+ "normalizeOllamaModelIdentifier",
1017
+ "sameOllamaModelIdentifier"
1017
1018
  ],
1018
- "summary": "Validates and canonicalizes the syntax of Ollama model identifiers without granting model admission.",
1019
+ "summary": "Recognizes Ollama model identifier syntax and compares ordinary resident-model aliases without changing requests.",
1019
1020
  "availability": "Cross-host",
1020
1021
  "protocol": "In-process only",
1021
- "normalization": "Fully normalized string/boolean result.",
1022
- "surface": "`normalizeOllamaModelIdentifier()`, `isOllamaModelIdentifier()`."
1022
+ "normalization": "Exact identifier/null or boolean results; alias comparison applies Ollama's default registry, namespace and tag without changing either input.",
1023
+ "surface": "`normalizeOllamaModelIdentifier()`, `isOllamaModelIdentifier()`, `sameOllamaModelIdentifier(left, right)`."
1023
1024
  },
1024
1025
  {
1025
1026
  "file": "runtime/arcane/modules/OllamaSettings.js",