arcane-os 0.88.1 → 0.90.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 (44) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/browser-runtime/ai/browser-decisions.mjs +31 -4
  3. package/browser-runtime/ai/core-local.mjs +105 -25
  4. package/browser-runtime/ai/decision-runtime.mjs +7 -0
  5. package/browser-runtime/ai/decision-worker.mjs +9 -1
  6. package/browser-runtime/core/client.mjs +6 -0
  7. package/browser-runtime/core/contracts.mjs +10 -0
  8. package/docs/reference/ai/browser-decisions.md +89 -7
  9. package/docs/reference/core-client.md +59 -0
  10. package/docs/reference/core-native-packaging.md +62 -10
  11. package/docs/reference/core-repositories.md +104 -8
  12. package/docs/reference/git-text-snapshot.md +16 -1
  13. package/docs/reference/inventory/package-api.json +25 -25
  14. package/docs/reference/inventory/runtime-components.json +1 -1
  15. package/docs/reference/inventory/runtime-modules.json +4 -4
  16. package/docs/reference/local-ai.md +108 -9
  17. package/docs/reference/mcp-stdio.md +76 -1
  18. package/docs/reference/native-app-control.md +17 -5
  19. package/docs/reference/protocols.md +14 -0
  20. package/docs/reference/runtime-modules.md +9 -3
  21. package/docs/reference/sdk-api.md +202 -35
  22. package/package.json +2 -2
  23. package/runtime/arcane/modules/RiskSignalAnalyzer.js +1 -5
  24. package/schemas/arcane-app.schema.json +13 -3
  25. package/schemas/arcane-package.schema.json +10 -1
  26. package/src/app-descriptor.mjs +6 -2
  27. package/src/cli/app-control.mjs +1 -1
  28. package/src/core/hosts/windows/ArcaneHost.cs +273 -5
  29. package/src/core/hosts/windows/ArcaneLauncher.cs +9 -0
  30. package/src/core/hosts/windows/ArcaneWindowControl.cs +7 -7
  31. package/src/core/repositories.mjs +17 -6
  32. package/src/core/services/local-ai.mjs +183 -22
  33. package/src/git-text-snapshot.mjs +4 -2
  34. package/src/installed-sdk-runtime.mjs +2 -0
  35. package/src/local-ai/config.mjs +16 -0
  36. package/src/local-ai/dev.mjs +2 -2
  37. package/src/local-ai/discover.mjs +3 -0
  38. package/src/local-ai/install.mjs +130 -20
  39. package/src/local-ai/llama-execution-windows.ps1 +158 -0
  40. package/src/local-ai/llama-execution.mjs +169 -0
  41. package/src/local-ai/server.mjs +38 -8
  42. package/src/native/portable-layout.mjs +13 -3
  43. package/src/repository.mjs +33 -8
  44. package/src/workspace-runtime.mjs +97 -1
@@ -1857,7 +1857,7 @@ create `arcane.lock.json` before serving, refreshing app import maps, or packagi
1857
1857
  ### Signature and result
1858
1858
 
1859
1859
  ```text
1860
- async materializeInstalledSdkRuntime({workspaceRoot,sdkPackageSource,workspaceOperationLease,signal,onEvent}={})
1860
+ async materializeInstalledSdkRuntime({workspaceRoot,sdkPackageSource,browserDecisions=false,workspaceOperationLease,signal,onEvent}={})
1861
1861
  ```
1862
1862
 
1863
1863
  Import it through the exact dependency key declared by the workspace: normally
@@ -1868,6 +1868,16 @@ whole-tree replacement. The mutable result includes the installed-package
1868
1868
  location, materialized workspace runtime paths, and `workspaceLock` path and
1869
1869
  document. It does not install dependencies or merge application source.
1870
1870
 
1871
+ Explicit `browserDecisions: true` also acquires the bundled Transformers.js
1872
+ 4.3.0 entry and matching ONNX Runtime 1.31.0-dev.20260914-8d85527a0 asyncify
1873
+ module/WASM and license files from their upstream distributions into
1874
+ `arcane/sdk/ai/decisions-runtime/`. It returns their `directory`,
1875
+ `transformersVersion`, `onnxRuntimeVersion` and `files` under
1876
+ `workspaceRuntime.browserDecisions`. The default `false` performs no optional
1877
+ acquisition. Select this option on each refresh that should retain those files.
1878
+ The [extension-local decision guide](ai/browser-decisions.md#extension-local-executables-manifest-v3)
1879
+ describes `runtime.local: true`, complete resource ownership and MV3 usage.
1880
+
1871
1881
  Ordinary acquisition automatically recovers a workspace-operation lock when
1872
1882
  the recorded owner process is confirmed absent, without waiting solely for its
1873
1883
  six-hour expiry. Retry this public operation normally; `workspaceOperationLease`
@@ -1910,13 +1920,24 @@ the installed-package lock document owned by `materializeInstalledSdkRuntime()`.
1910
1920
  ### Signature and result
1911
1921
 
1912
1922
  ```text
1913
- async materializeWorkspaceRuntimeContent({workspaceRoot,runtimeRoot=path.join(getSdkRoot(), 'runtime'),browserRuntimeRoot=getSdkBrowserRuntimeRoot(),signal,onEvent}={})
1923
+ async materializeWorkspaceRuntimeContent({workspaceRoot,runtimeRoot=path.join(getSdkRoot(), 'runtime'),browserRuntimeRoot=getSdkBrowserRuntimeRoot(),sdkVersion=SDK_VERSION,browserDecisions=false,signal,onEvent}={})
1914
1924
  ```
1915
1925
 
1916
1926
  The operation stages the complete projection, replaces the prior tree at the
1917
1927
  commit boundary, restores it if commit fails, and removes paths absent from the
1918
1928
  selected sources.
1919
1929
 
1930
+ `browserDecisions: true` acquires the same upstream executable closure described
1931
+ by `materializeInstalledSdkRuntime()` before replacement. Its result is at
1932
+ `result.browserDecisions` because this lower-level operation returns the
1933
+ workspace runtime directly. Full downloaded content remains unchanged; model
1934
+ and tokenizer data are not materialized. `workspace.decisions.started` and
1935
+ `workspace.decisions.progress` report completed files and the fixed total.
1936
+ Cancellation, HTTP failures and throwing/rejecting observers abort and join
1937
+ pending acquisitions before returning; the prior runtime remains in place.
1938
+ An HTTP failure retains its complete response in `error.response`, or in the
1939
+ corresponding member of `AggregateError.errors` when several operations fail.
1940
+
1920
1941
  ### Availability and normalization
1921
1942
 
1922
1943
  **Node.** Complete workspace runtime content and a mutable materialization result. Deep protocol: [Installed SDK runtime materialization](protocols.md#installed-sdk-runtime-materialization).
@@ -3810,12 +3831,21 @@ async repositoryPull({ workspaceRoot=process.cwd(), target, signal, onEvent, run
3810
3831
 
3811
3832
  Import it from `arcane-os`. The signature above states whether settlement is synchronous or promise-based. The overview and owning group define result authority, side effects, callbacks, events, cancellation, and lifecycle.
3812
3833
 
3813
- Optional `target:{remote,ref}` captures exact nonempty native-representable
3814
- strings before any wait and selects `git pull --ff-only -- <remote> <ref>:`.
3834
+ Optional `target:{remote,ref,remoteBase?}` captures the exact nonempty
3835
+ native-representable `remote` and `ref` strings before any wait and selects
3836
+ `git pull --ff-only -- <remote> <ref>:`.
3815
3837
  The current clean branch receives a fast-forward-only integration; the SDK
3816
3838
  never switches branches, resets or changes configuration. Without a target,
3817
3839
  the existing configured pull and result remain unchanged. Targeted results
3818
3840
  add `target`, complete `stdout` and `stderr` to the existing pull result.
3841
+
3842
+ Supplying `target.remoteBase` explicitly selects a local filesystem locator:
3843
+ only the Git remote argument becomes `path.resolve(remoteBase, remote)`, captured
3844
+ once at acceptance before status work. Relative bases, including `''`, use the
3845
+ working directory at that moment. The returned target retains the original
3846
+ `remote`, `ref` and supplied base text. Omission preserves Git remote names,
3847
+ URLs, SCP-like addresses and remote-helper strings without guessed parsing.
3848
+ Unrepresentable base text reports `TypeError` without transformation.
3819
3849
  See [checkout configuration and selected targets](core-repositories.md#existing-checkout-configuration-and-selected-targets).
3820
3850
 
3821
3851
  ### Availability and normalization
@@ -3856,20 +3886,29 @@ detached HEAD, then, without `target`, runs plain `git push`; the repository's c
3856
3886
  configured upstream/remote, Git credentials, hooks, and server policy remain
3857
3887
  authoritative. Unlike `repositoryPull()`, this function does **not** require a
3858
3888
  clean worktree. It does not create a commit or choose an application destination.
3859
- Optional `target:{remote,ref}` captures the original nonempty
3860
- native-representable strings before any wait and runs
3889
+ Optional `target:{remote,ref,remoteBase?}` captures the original nonempty
3890
+ native-representable `remote` and `ref` strings before any wait and runs
3861
3891
  `git push --no-follow-tags -- <remote> HEAD:<ref>`. This publishes current HEAD
3862
3892
  to the caller-selected ref without force or implicit configured tag following.
3863
3893
  It changes no branch or Git configuration; credentials, URL interpretation,
3864
3894
  hooks and remote rejection remain Git-owned.
3865
3895
 
3896
+ Supplying `target.remoteBase` explicitly selects a local filesystem locator:
3897
+ only the Git remote argument becomes `path.resolve(remoteBase, remote)`, captured
3898
+ once at acceptance before status work. Relative bases, including `''`, use the
3899
+ working directory at that moment. Later directory or target-object changes do
3900
+ not redirect accepted work. Omission preserves Git remote names, URLs, SCP-like
3901
+ addresses and remote-helper strings without guessed parsing. Unrepresentable
3902
+ base text reports `TypeError` without transformation.
3903
+
3866
3904
  The promise resolves to
3867
3905
  `{action:'push', repositoryRoot, branch, output}`. `output` is trimmed stdout,
3868
3906
  or trimmed stderr when stdout is empty. A missing Git executable, failed status
3869
3907
  probe, rejected/nonzero push, cancellation, or event-callback failure rejects
3870
3908
  with the normalized process error. Cancellation stops the local process tree;
3871
3909
  it cannot prove that a remote accepted no objects before the interruption.
3872
- Targeted results also contain the captured `target` and complete
3910
+ Targeted results also contain the captured `target`, retaining original
3911
+ `remote`, `ref` and any supplied `remoteBase`, and complete
3873
3912
  `stdout`/`stderr`; omitting the target preserves the existing result shape.
3874
3913
  See [checkout configuration and selected targets](core-repositories.md#existing-checkout-configuration-and-selected-targets).
3875
3914
 
@@ -5346,7 +5385,7 @@ a dedicated bare Git cache. It does not create or alter a working checkout.
5346
5385
  ### Signature, lifecycle, and result
5347
5386
 
5348
5387
  ```text
5349
- createGitTextSnapshot({cacheDirectory,remote,ref,selectPath,gitIdentity,onEvent,run=runProcess}={})
5388
+ createGitTextSnapshot({cacheDirectory,remote,remoteBase,ref,selectPath,gitIdentity,onEvent,run=runProcess}={})
5350
5389
  ```
5351
5390
 
5352
5391
  Import from `arcane-os`. The application owns the cache location, remote, ref,
@@ -5358,6 +5397,16 @@ await accepted refresh/process cleanup. Errors remain observable instead of
5358
5397
  returning stale or partial success. See [Git text snapshots](git-text-snapshot.md)
5359
5398
  for complete inputs, text semantics, errors, events and Core service composition.
5360
5399
 
5400
+ Optional `remoteBase` explicitly selects `remote` as a local filesystem locator.
5401
+ Only its Git fetch argument is derived using `path.resolve(remoteBase, remote)`,
5402
+ once at construction, independently of the cache location and later changes to
5403
+ the working directory. Relative bases, including `''`, use the construction-time
5404
+ working directory. Original locator/options remain unchanged. Omission preserves
5405
+ Git remote names, URLs, SCP-like addresses and remote-helper strings without
5406
+ guessed parsing. Unrepresentable base text reports `TypeError` without
5407
+ transformation; actual Git failures retain their existing error behavior.
5408
+ See [relative local repository locators](core-repositories.md#relative-local-repository-locators).
5409
+
5361
5410
  Optional `gitIdentity:{name?,email?,username?}` captures a child-process-only
5362
5411
  selection for init/fetch and subsequent Git commands, preserving shared refresh
5363
5412
  cancellation and complete content. See [Git identity configuration](core-repositories.md#git-identity-configuration)
@@ -7122,6 +7171,21 @@ no engine. The native routes of `AI.fetchTTS(payload, signal)` and
7122
7171
  `AI.fetchSTT(audio, signal)` forward their signals through these calls and
7123
7172
  normalize cancellation to `AbortError` with `ARCANE_AI_REQUEST_ABORTED`.
7124
7173
 
7174
+ `facade.window.state({signal}?)` reads the calling document's native window;
7175
+ `facade.window.setState({state}, {signal}?)` selects `normal`, `maximized` or
7176
+ `fullscreen` for that same window. The matching Windows host returns
7177
+ `{platform:'windows', supported:true, state}`, with observed `state` also able
7178
+ to be `minimized`. Fullscreen removes the frame and fills the selected monitor;
7179
+ leaving it restores the preceding normal bounds and frame controls before any
7180
+ requested maximization. Visible state transitions prevent activation/focus
7181
+ assignment to the requesting window without changing TopMost, Core, origin or
7182
+ profile. Optional `native.window.state` selects startup state after initial
7183
+ sizing; omission preserves host behavior. Saved Settings remain application-owned.
7184
+ Cancellation does not undo an already-applied change. Other hosts retain their
7185
+ actual unavailable-method/transport errors; the facade provides no fallback.
7186
+ See [current-window state](core-client.md#current-window-state) for complete
7187
+ native errors, partial-state evidence, navigation and cleanup ownership.
7188
+
7125
7189
  `facade.window.setTheme(presentation, {signal}?)` forwards the complete
7126
7190
  presentation to the current native window, independently of OS-user appearance.
7127
7191
  Optional `backgroundColor` and `textColor` accept `{red,green,blue,alpha}` or
@@ -7777,6 +7841,17 @@ published SDK/runtime dependencies and the canonical Core entry/client into a
7777
7841
  fresh output directory. Service factories are imported only when a real native
7778
7842
  host later launches the generated Core entry, never during packaging.
7779
7843
 
7844
+ The generated `runtime/arcane-core.mjs` also accepts
7845
+ `--arcane-app-entry <app-relative-module>` through the host's supported Node
7846
+ executable; the portable provider supplies no executable. Include that module
7847
+ and its complete source closure through `package.nativeResources`. The flag
7848
+ imports it from the packaged `app/` directory, preserves complete `process.argv`,
7849
+ and runs its top-level work rather than invoking an export or making it
7850
+ `import.meta.main`. The entry owns explicit launch-context reads, services,
7851
+ signals and shutdown; ordinary Core startup is skipped only in this mode.
7852
+ See [app-owned runtime entry](core-native-packaging.md#app-owned-runtime-entry)
7853
+ and [packaged MCP commands and lifetime](mcp-stdio.md#launch-from-a-native-package).
7854
+
7780
7855
  Explicit `native.launchContext.coreListener:{endpoint}` also composes one passive
7781
7856
  model observation service after `startCoreHost()` and before listener binding,
7782
7857
  using that runtime and existing services exposing `localai.status`, `image.status`
@@ -7784,11 +7859,13 @@ and `decisions.status`. Missing owners remain `null`; renderer attachment stays
7784
7859
  application-owned. Ordinary stdio and shared/headless branches gain no model
7785
7860
  startup or readiness barrier. See [native observation composition](core-native-packaging.md#launch-time-locations).
7786
7861
 
7787
- An optional `appDescriptor.native.window` record carries `width`, `height` and
7788
- `resizable` into `manifest.window`. Dimensions are positive integral logical
7789
- client units; `resizable` is an optional boolean. Omitted fields remain omitted.
7790
- The portable payload records the selection; the selected platform host owns
7791
- its window behavior. See [initial native window size](core-native-packaging.md#initial-native-window-size).
7862
+ An optional `appDescriptor.native.window` record carries `width`, `height`,
7863
+ `resizable` and `state` into `manifest.window`. Dimensions are positive integral
7864
+ logical client units; `resizable` is an optional boolean, and `state` selects
7865
+ `normal`, `maximized` or `fullscreen`. Omitted fields remain omitted. The portable
7866
+ payload records the selection; the matching Windows host applies it, while
7867
+ current other-platform hosts retain their existing window behavior. See
7868
+ [initial native window size and state](core-native-packaging.md#initial-native-window-size).
7792
7869
 
7793
7870
  ### Availability and normalization
7794
7871
 
@@ -7905,11 +7982,25 @@ The matching Windows host consumes `appDescriptor.native.window` through
7905
7982
  `manifest.window`. Optional `width` and `height` select initial client dimensions
7906
7983
  in 96-DPI logical units; the host scales them for its actual DPI and fits the
7907
7984
  outer window within the current screen's usable area. Optional `resizable:false`
7908
- selects a fixed-size border and disables maximizing. Omitted fields preserve
7909
- the existing host defaults. Initial sizing preserves a window already restored
7910
- to a non-normal state and does not add saved-bounds storage. The initial-fit
7911
- logic is not reapplied during later user resizing. See [initial native window size](core-native-packaging.md#initial-native-window-size)
7912
- for a complete descriptor example and the other-platform boundary.
7985
+ selects a fixed-size border and disables the maximize control. Optional `state`
7986
+ selects `normal`, `maximized` or `fullscreen`; the host applies an explicit state
7987
+ after its initial sizing pass and before the composing launcher's `Load` handler.
7988
+ Initial sizing runs only for a Normal window. Omitted fields preserve existing
7989
+ host choices, including the current state when `state` is omitted. Fullscreen
7990
+ retains normal bounds and frame controls for restoration. No saved-bounds store
7991
+ is added, and initial-fit logic is not reapplied during later user resizing.
7992
+ See [initial native window size and state](core-native-packaging.md#initial-native-window-size)
7993
+ for the complete descriptor and unchanged other-platform behavior.
7994
+
7995
+ The packaged `runtime/ArcaneCore.exe` also accepts
7996
+ `--arcane-app-entry <app-relative-module>` directly, without a script argument
7997
+ or the GUI launcher. Include the entry and complete source closure through
7998
+ `package.nativeResources`. It imports the selected packaged `app/` module with
7999
+ complete `process.argv` unchanged, running top-level work without invoking an
8000
+ export or making it `import.meta.main`. The entry owns explicit launch-context
8001
+ reads, services, signals and shutdown; this mode skips ordinary Core startup,
8002
+ while omission retains it. See [app-owned runtime entry](core-native-packaging.md#app-owned-runtime-entry)
8003
+ and [packaged MCP commands and lifetime](mcp-stdio.md#launch-from-a-native-package).
7913
8004
 
7914
8005
  The returned `arcane-native-builder/1` provider exposes `describe`, `doctor`,
7915
8006
  `prepare`, `build`, `verify` and `run`. Build returns `{app,target,manifest}`
@@ -8285,7 +8376,7 @@ explicit existing path. The application owns the remote, branch and Core API.
8285
8376
  ### Signature and result
8286
8377
 
8287
8378
  ```text
8288
- createRepositoryWorkspace({name,directory,dataRoot,remote,branch,longPaths,gitIdentity,onEvent,run=runProcess}={})
8379
+ createRepositoryWorkspace({name,directory,dataRoot,remote,remoteBase,branch,longPaths,cloneIdentity,gitIdentity,onEvent,run=runProcess}={})
8289
8380
  ```
8290
8381
 
8291
8382
  Returns `{directory,open,status,configuration,pull,push,write,close,drain,dispose}`. Construction does
@@ -8296,6 +8387,16 @@ work and preserves the checkout. No CLI cwd, launch state, preference, snapshot
8296
8387
  cache or existing user-data location changes. See the [complete inputs, results,
8297
8388
  errors and lifecycle](core-repositories.md#one-connected-working-checkout).
8298
8389
 
8390
+ Optional factory `remoteBase` explicitly selects the initial-clone `remote` as
8391
+ a local filesystem locator. Only its Git argument is derived through the host's
8392
+ native `path.resolve(remoteBase, remote)`, once at construction. Relative bases,
8393
+ including `''`, use the construction-time working directory. The caller's
8394
+ original locator remains unchanged; Git clone may save the derived argument as
8395
+ its ordinary origin setting. Omission preserves Git remote names, URLs, SCP-like
8396
+ addresses and remote-helper strings without guessed parsing. Unrepresentable
8397
+ base text reports `TypeError` without transformation.
8398
+ See [relative local repository locators](core-repositories.md#relative-local-repository-locators).
8399
+
8299
8400
  Optional `longPaths` captures a boolean for new Windows clones. Explicit true
8300
8401
  or false supplies clone-local `core.longpaths` before the first checkout and
8301
8402
  persists it only in the new repository. Omission preserves inherited/template
@@ -8304,6 +8405,16 @@ unchanged; no global setting or data migration is performed. Git's ordinary
8304
8405
  configuration precedence, hooks and single-clone lifecycle remain in effect.
8305
8406
  See [Windows long paths](core-repositories.md#windows-long-paths-for-a-new-checkout).
8306
8407
 
8408
+ Optional `cloneIdentity:{name?,email?}` captures exact author strings and saves
8409
+ only supplied fields in a newly created checkout through Git's `clone --config`
8410
+ before its first checkout, on every supported platform. Empty strings are
8411
+ explicit values; omitted or `undefined` fields preserve inherited and template
8412
+ configuration. Existing repositories are never reconfigured. Unrepresentable
8413
+ process arguments fail without changing the supplied text. This option changes
8414
+ no global configuration, credentials, remote or branch, and does not identify
8415
+ the authenticated account. Command-local `gitIdentity` remains independent.
8416
+ See [clone-local author selection](core-repositories.md#clone-local-author-selection).
8417
+
8307
8418
  Optional `gitIdentity:{name?,email?,username?}` captures explicit non-secret
8308
8419
  settings for child Git operations without writing global/local configuration.
8309
8420
  Selected author fields override inherited child author/committer fields;
@@ -8321,11 +8432,15 @@ reports `ARCANE_GIT_CONFIGURATION_NOT_TEXT` with full diagnostics.
8321
8432
 
8322
8433
  `pull({target,signal})`, `push({target,signal})` and
8323
8434
  `write({files:[{path,content}],message,target,signal})` accept optional
8324
- `target:{remote,ref}`, captured as original strings at acceptance. The target
8435
+ `target:{remote,ref,remoteBase?}`, captured as original strings at acceptance. The target
8325
8436
  selects a fast-forward-only pull into the current branch or a non-force push
8326
8437
  of current HEAD to the selected ref, without switching branches or changing
8327
- configuration. It is independent of initial-clone `remote`/`branch`; omission
8328
- preserves ordinary configured behavior. See the [complete configuration and
8438
+ configuration. An operation's own `remoteBase` declares local-path intent and
8439
+ captures the native absolute Git argument once at acceptance, before queueing.
8440
+ It is independent of initial-clone `remote`/`remoteBase`/`branch`; omission of
8441
+ `target` preserves ordinary configured behavior. Targeted pull/push results and
8442
+ writer results/failure outcomes retain original `remote`, `ref` and any supplied
8443
+ `remoteBase`, including relative or empty base text. See the [complete configuration and
8329
8444
  target contract](core-repositories.md#existing-checkout-configuration-and-selected-targets).
8330
8445
 
8331
8446
  `write` snapshots the exact selected
@@ -8396,15 +8511,16 @@ Construction selects no model and installs no runtime or transport.
8396
8511
  ### Signature and result
8397
8512
 
8398
8513
  ```text
8399
- createCoreLocalAIProvider({client,id='llama.cpp'}={})
8514
+ createCoreLocalAIProvider({client,id='llama.cpp',prepareModel}={})
8400
8515
  ```
8401
8516
 
8402
8517
  Import it from `arcane-os/ai/core-local`. The provider implements
8403
8518
  `arcane-ai-provider/2` and exposes `catalog`, `status`, `inspect`, `load`,
8404
8519
  `request`, `unload` and `dispose`. Register it with the shared AI provider runtime,
8405
8520
  select the exact provider/model with `localOnly:true`, and load that selection.
8406
- Requests wait for the requested model's actual readiness, preserve complete
8407
- payloads and parsed streaming chunks, and cancel on observed readiness loss.
8521
+ `load()` waits for the selected model's actual readiness; inference requests
8522
+ require that load to have completed successfully. Requests preserve complete
8523
+ payloads and parsed streaming chunks and cancel on observed readiness loss.
8408
8524
  Missing Core reports unavailability; it does not choose a browser or cloud route.
8409
8525
  Dispose/unregister at the caller's owning lifecycle boundary.
8410
8526
 
@@ -8418,6 +8534,17 @@ client, so never-loaded and already-unloaded providers send no native unload.
8418
8534
  The provider/2 runtime reconciles status at its operation boundaries; this
8419
8535
  does not add an idle role-state subscription.
8420
8536
 
8537
+ Optional `prepareModel({selection,signal,progress})` runs at actual load and
8538
+ returns `{assetProjectionId,resourcePaths,executionTarget,release?}`. Direct
8539
+ `load` fields with those names override preparation when defined; an explicit
8540
+ `executionTarget:null` requests the runtime default. Preparation release is
8541
+ awaited after native load settles, including failure, cancellation and late
8542
+ preparation results. The current successfully completed load owns readiness
8543
+ and inference; a failed replacement cannot reuse an older model's ready state.
8544
+ Native cleanup owns the last dispatched selection, while preparation alone
8545
+ creates no native unload obligation. `status().execution` forwards native
8546
+ execution diagnostics, including configured and observed targets separately.
8547
+
8421
8548
  ```javascript
8422
8549
  import {createCoreLocalAIProvider} from 'arcane-os/ai/core-local';
8423
8550
  import {getAIProviderRuntime} from 'arcane-os/ai-provider-runtime';
@@ -8440,7 +8567,7 @@ separate states; prompts, models and application policy remain caller-owned.
8440
8567
  ### Signature and result
8441
8568
 
8442
8569
  ```text
8443
- createLocalAIService(configuration,{appRoot,runtimes=[],signal,onEvent,prepare}={})
8570
+ createLocalAIService(configuration,{appRoot,runtimes=[],signal,onEvent,prepare,executionDevices}={})
8444
8571
  ```
8445
8572
 
8446
8573
  Import it from `arcane-os/core/local-ai`. `configuration` is the authored local-AI
@@ -8473,6 +8600,19 @@ Explicit load retains startup and exact catalog-membership checks.
8473
8600
  carry original parsed chunks with `streamId`; terminal responses remain complete.
8474
8601
  There is no background health polling or implicit model choice.
8475
8602
 
8603
+ For managed llama.cpp loading, `llama.load` also accepts `assetProjectionId`,
8604
+ `resourcePaths:{model}` and `executionTarget`. The existing model-assets owner
8605
+ retains the exact projected GGUF through actual server exit. An omitted target
8606
+ retains the same model's selection or configured default; `null` requests the
8607
+ runtime default. `{deviceId}` uses this computer's execution-device catalog.
8608
+ Windows NVIDIA selection resolves that physical device to its CUDA identity;
8609
+ unsupported or unavailable targets report their actual failure. Runtime
8610
+ `execution` reports requested, resolved and configured targets with
8611
+ `observedTarget:null`; configuration does not establish physical execution.
8612
+ An optional `executionDevices` catalog is borrowed by ONNX and llama.cpp; its
8613
+ supplying owner retains disposal responsibility. Existing external listeners
8614
+ retain their own model/device selection and reject managed reconfiguration.
8615
+
8476
8616
  ```javascript
8477
8617
  import {createLocalAIService} from 'arcane-os/core/local-ai';
8478
8618
 
@@ -8905,7 +9045,7 @@ import createLocalAIService from 'arcane-os/core/local-ai';
8905
9045
 
8906
9046
  ### Overview
8907
9047
 
8908
- Reuses matching managed runtimes or installs complete selected official
9048
+ Reuses matching managed runtimes or installs complete selected
8909
9049
  llama.cpp/Ollama/ONNX/image distributions or NeMo libraries in an explicitly supplied directory.
8910
9050
 
8911
9051
  ### Signature and result
@@ -8918,14 +9058,22 @@ Import it from `arcane-os/local-ai`. Runtime requirements accept IDs or
8918
9058
  `{id,version?,url?}` records. The result is an array of absolute
8919
9059
  `{id,version,platform,architecture,root}` records, with `executable` for servers,
8920
9060
  `modulePath` for ONNX, image `libraryPath`/`bindingModulePath`/`variants`/`models`,
8921
- or NeMo library directories. Image requirements also accept `backend` and
9061
+ or NeMo library directories. The SDK-selected Windows x64 ONNX `1.30.0`
9062
+ distribution also returns `nativeDistributionRevision: '1.30.0-directml-reshape-1'`.
9063
+ With no explicit `url`, an omitted ONNX version or explicit `1.30.0` selects
9064
+ the corrected native archive from the installed SDK's numeric release.
9065
+ Other ONNX versions, platforms/architectures and explicit URLs retain their
9066
+ upstream package path. Reuse requires the selected revision; older installation
9067
+ trees remain intact while a fresh installation is prepared. See
9068
+ [ONNX runtime preparation](local-ai.md#development).
9069
+ Image requirements also accept `backend` and
8922
9070
  `models`; their pinned default runtime, CPU/Metal selection and separate model
8923
9071
  preparation are described in [local image generation](local-image-generation.md).
8924
9072
  Matching concurrent
8925
9073
  installs share their work. Downloads retain runtime libraries and surface
8926
9074
  network/archive failures; cancellation and operation events remain observable.
8927
9075
  Installation changes no global PATH or system service and loads no model.
8928
- Supported assets belong to the selected upstream distribution; see
9076
+ Supported assets belong to the selected distribution; see
8929
9077
  [platform and archive requirements](local-ai.md#native-bundling).
8930
9078
 
8931
9079
  ```javascript
@@ -8959,6 +9107,11 @@ contains the complete emitted inventory. Existing runtime destinations are
8959
9107
  preserved and reported as a conflict. Copying settles all started work and
8960
9108
  reports failures/cancellation without executing app services or models.
8961
9109
 
9110
+ The corrected Windows x64 ONNX selection retains its
9111
+ `nativeDistributionRevision` and complete native libraries. Its `modulePath`
9112
+ is relocated with the other runtime paths; bundling introduces no separate
9113
+ runtime selection. See [ONNX runtime preparation](local-ai.md#development).
9114
+
8962
9115
  Image records relocate the complete library, binding and variant paths. Model
8963
9116
  URL descriptors retain their original acquisition metadata for preparation
8964
9117
  after launch. Runtime-contained native model paths become artifact-relative;
@@ -9156,7 +9309,8 @@ portable Node local IPC; other native host adapters do not yet implement these
9156
9309
  document operations. No application is launched, no desktop window is activated,
9157
9310
  and no automatic reconnect or action retry occurs.
9158
9311
 
9159
- `status(options)` reports current app/window/document readiness.
9312
+ `status(options)` reports current app/window/document readiness, including
9313
+ observed window state `Normal`, `Maximized`, `Minimized` or `Fullscreen`.
9160
9314
  `inspect(parameters={},options)` returns complete selected DOM HTML/text
9161
9315
  and live control state. Inspection and actions accept optional `shadowPath`, an
9162
9316
  ordered array of unique CSS host selectors through open shadow roots; their
@@ -9171,7 +9325,8 @@ of the rendered viewport. `act(parameters,options)` requires a returned
9171
9325
  fields.
9172
9326
 
9173
9327
  `key(parameters,options)` requires the observed `documentGeneration` and
9174
- `key:'Tab'`, `'Enter'` or `'Space'`; `shiftKey:true` is supported only for Tab.
9328
+ `key:'Tab'`, `'Enter'`, `'Space'` or `'Escape'`; `shiftKey:true` is supported only
9329
+ for Tab.
9175
9330
  It sends a fixed ordered press/release pair to the selected WebView's current
9176
9331
  focus, without selecting an element or activating the desktop window. Accepted
9177
9332
  pairs share one keyboard owner. Once a press is attempted, its matching release
@@ -9183,9 +9338,9 @@ or navigation can change between phases.
9183
9338
 
9184
9339
  `resize(parameters,options)` accepts positive integral native client `width`
9185
9340
  and `height` supported by WinForms, plus optional `documentGeneration`. It changes
9186
- only `ClientSize` while the actual window is `Normal`; maximized or minimized
9187
- windows fail before size mutation. Results retain immediate `previous`/`actual`
9188
- native dimensions, requested dimensions, attempted/completed flags and a later
9341
+ only `ClientSize` while the actual window is `Normal`; maximized, minimized or
9342
+ fullscreen windows fail before size mutation. Results retain immediate
9343
+ `previous`/`actual` native dimensions, requested dimensions, attempted/completed flags and a later
9189
9344
  observed CSS `viewport`. Platform constraints can change actual dimensions;
9190
9345
  native and CSS observations are not an atomic snapshot. Restore explicitly with
9191
9346
  the same operation's `previous.width` and `previous.height`, not CSS dimensions
@@ -9990,9 +10145,21 @@ selections report its failure without precision fallback. For Laya FP32, pass
9990
10145
  Cancellation terminates that client's Worker and rejects its in-flight work.
9991
10146
  No decisions are inserted into chat history or durable storage.
9992
10147
 
10148
+ For explicitly selected extension-local execution, supply `runtime: {local:
10149
+ true}` after materializing with `browserDecisions: true`. The SDK directly
10150
+ imports its deployment-local `decisions-runtime/transformers.min.js` and
10151
+ matched asyncify module/WASM. Explicit `runtime.moduleUrl` and
10152
+ `runtime.wasmPaths: {mjs, wasm}` may select other compatible files in that same
10153
+ deployment; a directory string is also accepted for `wasmPaths`. This mode
10154
+ disables executable Blob preparation and upstream WASM cache/proxy creation,
10155
+ selects one WASM thread, and preserves the caller's model, precision and
10156
+ inference backend. With `store`, only the exact selected executable URLs bypass
10157
+ it; model, tokenizer, configuration and external-data resources retain that
10158
+ store. Local mode is opt-in; default browser behavior remains unchanged.
10159
+
9993
10160
  Optional `store` is an existing SDK DBOPFS model or speech store exposing
9994
10161
  `fetchResource(input, options)`. It remains outside cloned Worker configuration.
9995
- Explicit activation first stores the complete selected `runtime.moduleUrl`
10162
+ Without `runtime.local`, explicit activation first stores the complete selected `runtime.moduleUrl`
9996
10163
  entry and materializes it as a JavaScript object URL without rewriting source.
9997
10164
  The configured original URL remains the resource selection for later loads.
9998
10165
  The selected loader also routes its actual model/configuration/tokenizer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.88.1",
3
+ "version": "0.90.0",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
@@ -129,7 +129,7 @@
129
129
  "scripts": {
130
130
  "test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
131
131
  "test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
132
- "test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/conversation-closing-report.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/native-windows-icon.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
132
+ "test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/conversation-closing-report.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/native-windows-icon.test.mjs test/risk-signal-analyzer.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
133
133
  "test:functional": "node ./bin/arcane-test.mjs test/ai-ollama-readiness.test.mjs test/core-ollama-lifecycle.test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-decisions.test.mjs test/browser-kokoro-complete-input.test.mjs test/browser-speech-providers.test.mjs test/browser-speech-artifacts.test.mjs test/browser-speech-resource-bridge.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/codex-app-server.test.mjs test/mcp-stdio-server.test.mjs test/core-classic-source.test.mjs test/core-client.test.mjs test/core-client-installation.test.mjs test/core-ai-installation.test.mjs test/core-llama-lifecycle.test.mjs test/core-development.test.mjs test/core-host.test.mjs test/core-shared-host.test.mjs test/core-model-assets.test.mjs test/core-native-services.test.mjs test/core-packaged-web.test.mjs test/core-runtime.test.mjs test/core-stdio.test.mjs test/dbopfs-committed-events.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-model-resources.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/document-acquisition.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/execution-devices.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/local-image-editing.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/model-resource-bridge.test.mjs test/native-decisions.test.mjs test/native-onnx.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/rendered-print.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
134
134
  "test:integration": "node ./bin/arcane-test.mjs test/installed-package-runtime.test.mjs test/root-app-layout.test.mjs test/integrated-shared.test.mjs test/integrated-workspace.test.mjs test/mail-browser.test.mjs test/native-macos-provider.test.mjs test/native-plan.test.mjs test/native-portable-provider.test.mjs test/native-provider-loader.test.mjs test/npm-release.test.mjs test/release-bundle.test.mjs test/release-capability-smoke.test.mjs test/shared-payload-batch.test.mjs test/tarball.test.mjs test/browser-wasm-cpu.test.mjs test/wllama-webgpu-runtime.test.mjs",
135
135
  "test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/html-import-packaged-script.test.mjs test/logging-regression.test.mjs test/markdown-speech.test.mjs test/prepared-speech.test.mjs test/ai-audio-output.test.mjs test/native-provider-generation.test.mjs test/speech-queue-regression.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
@@ -8,12 +8,8 @@ const DEFAULT_LEVELS=[
8
8
  {minimum:0,id:'low'},
9
9
  ];
10
10
 
11
- function normalizeText(value){
12
- return String(value??'').normalize('NFKC');
13
- }
14
-
15
11
  export function analyzeRiskSignals(input,{signals=[],levels=DEFAULT_LEVELS}={}){
16
- const text=normalizeText(input);
12
+ const text=String(input??'');
17
13
  const matches=[];
18
14
  let score=0;
19
15
 
@@ -139,11 +139,12 @@
139
139
  "window": {
140
140
  "type": "object",
141
141
  "additionalProperties": false,
142
- "description": "Initial native client dimensions in logical pixels at 96 DPI, and whether the user can resize the window. Omitted fields retain the host defaults.",
142
+ "description": "Initial normal client dimensions in logical pixels at 96 DPI, resizing behavior, and optional native window state. Omitted fields retain the host defaults.",
143
143
  "properties": {
144
144
  "width": { "type": "integer", "minimum": 1 },
145
145
  "height": { "type": "integer", "minimum": 1 },
146
- "resizable": { "type": "boolean" }
146
+ "resizable": { "type": "boolean" },
147
+ "state": { "enum": ["normal", "maximized", "fullscreen"] }
147
148
  }
148
149
  },
149
150
  "bundledApps": {
@@ -283,7 +284,9 @@
283
284
  "properties": {
284
285
  "id": { "enum": ["llama.cpp", "ollama", "onnx", "stable-diffusion.cpp"] },
285
286
  "version": { "type": "string" },
286
- "url": { "type": "string" }
287
+ "url": { "type": "string" },
288
+ "backend": { "type": "string", "description": "llama.cpp: auto, cpu or cuda. Image runtimes: auto, metal or cpu." },
289
+ "companionUrl": { "type": "string", "description": "Explicit CUDA runtime companion archive for a custom llama.cpp CUDA URL." }
287
290
  }
288
291
  },
289
292
  { "$ref": "#/$defs/whisperRuntime" }
@@ -295,6 +298,13 @@
295
298
  "properties": {
296
299
  "url": { "type": "string" },
297
300
  "model": { "type": "string" },
301
+ "alias": { "type": "string" },
302
+ "executionTarget": {
303
+ "oneOf": [
304
+ { "type": "null" },
305
+ { "type": "object", "required": ["deviceId"], "properties": { "deviceId": { "type": "string" } } }
306
+ ]
307
+ },
298
308
  "modelsDirectory": { "type": "string" },
299
309
  "args": { "type": "array", "items": { "type": "string" } }
300
310
  }
@@ -163,7 +163,9 @@
163
163
  "properties": {
164
164
  "id": { "enum": ["llama.cpp", "ollama", "onnx", "stable-diffusion.cpp"] },
165
165
  "version": { "type": "string" },
166
- "url": { "type": "string" }
166
+ "url": { "type": "string" },
167
+ "backend": { "type": "string", "description": "llama.cpp: auto, cpu or cuda. Image runtimes: auto, metal or cpu." },
168
+ "companionUrl": { "type": "string", "description": "Explicit CUDA runtime companion archive for a custom llama.cpp CUDA URL." }
167
169
  }
168
170
  },
169
171
  { "$ref": "#/$defs/whisperRuntime" }
@@ -175,6 +177,13 @@
175
177
  "properties": {
176
178
  "url": { "type": "string" },
177
179
  "model": { "type": "string" },
180
+ "alias": { "type": "string" },
181
+ "executionTarget": {
182
+ "oneOf": [
183
+ { "type": "null" },
184
+ { "type": "object", "required": ["deviceId"], "properties": { "deviceId": { "type": "string" } } }
185
+ ]
186
+ },
178
187
  "modelsDirectory": { "type": "string" },
179
188
  "args": { "type": "array", "items": { "type": "string" } }
180
189
  }
@@ -237,7 +237,7 @@ function validateDocumentCatalog(value){
237
237
 
238
238
  function validateNativeWindow(value){
239
239
  if(value===undefined)return undefined;
240
- assertOnlyKeys(value,new Set(['width','height','resizable']),'descriptor.native.window');
240
+ assertOnlyKeys(value,new Set(['width','height','resizable','state']),'descriptor.native.window');
241
241
  for(const dimension of ['width','height']){
242
242
  if(value[dimension]!==undefined&&(!is.integer(value[dimension])||value[dimension]<=0)){
243
243
  fail(`descriptor.native.window.${dimension} must be a positive integer.`);
@@ -246,10 +246,14 @@ function validateNativeWindow(value){
246
246
  if(value.resizable!==undefined&&!is.boolean(value.resizable)){
247
247
  fail('descriptor.native.window.resizable must be a boolean.');
248
248
  }
249
+ if(value.state!==undefined&&!['normal','maximized','fullscreen'].includes(value.state)){
250
+ fail('descriptor.native.window.state must be normal, maximized, or fullscreen.');
251
+ }
249
252
  return completeValue({
250
253
  ...(value.width===undefined?{}:{width:value.width}),
251
254
  ...(value.height===undefined?{}:{height:value.height}),
252
- ...(value.resizable===undefined?{}:{resizable:value.resizable})
255
+ ...(value.resizable===undefined?{}:{resizable:value.resizable}),
256
+ ...(value.state===undefined?{}:{state:value.state})
253
257
  });
254
258
  }
255
259
 
@@ -18,7 +18,7 @@ an application or change its profile. --output selects the capture filename;
18
18
  the other Arcane commands retain their existing output-format option.
19
19
  Inspect --request reads the complete parameter object, including shadowPath and
20
20
  optional documentGeneration. It cannot be combined with --selector.
21
- Key --request selects Tab (optionally shiftKey:true), Enter, or Space and the
21
+ Key --request selects Tab (optionally shiftKey:true), Enter, Space, or Escape and the
22
22
  observed documentGeneration. Resize --request supplies native client width and
23
23
  height for a Normal window; its result includes the previous dimensions.
24
24
  `;