arcane-os 0.51.0 → 0.51.2

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.
@@ -5,12 +5,12 @@
5
5
  "repository": "https://github.com/TheWizardNexus/arcane-os-sdk.git",
6
6
  "branch": "main",
7
7
  "path": "runtime/arcane",
8
- "sdkVersion": "0.6.0",
8
+ "sdkVersion": "0.51.1",
9
9
  "protocol": "arcane/1"
10
10
  },
11
- "artifactCount": 89,
12
- "javascriptArtifactCount": 87,
13
- "esmExportCount": 357,
11
+ "artifactCount": 92,
12
+ "javascriptArtifactCount": 90,
13
+ "esmExportCount": 372,
14
14
  "artifacts": [
15
15
  {
16
16
  "file": "runtime/arcane/modules/AI.js",
@@ -30,7 +30,7 @@
30
30
  "availability": "Browser + native bridge + TWiN Cloud",
31
31
  "protocol": "arcane-ai-browser-speech-configuration/1, AIProviderRuntime arcane-ai-provider/2 routes, globalThis.arcaneEvents, TWiN Cloud HTTPS, Arcane.ollama, Arcane.speech, Android WebView bridge",
32
32
  "normalization": "Complete mutable caller-owned browser speech authority, SDK-owned provider registration/replacement/disposal, explicit STT/TTS activation, normalized Whisper STT and Kokoro TTS execution with default capacities 1 and 4 respectively, explicit provider-neutral execution snapshots through status(role,{execution:true}), sticky readiness, canonical window.user readiness without compatibility-event object-identity admission or polling, exact ordered structural calls with required arguments.message, atomic nonblank all-ID tool-result sequencing, complete all-choice streaming/data validation, native Ollama structural adaptation, complete-response then all validated tool callbacks then completion ordering, observed async callbacks, Blob/File transcription, automatic repeated-formatting-mark removal from cloned outbound TTS input while caller and visible content stays exact, immediate exact-segment synthesis, per-call voice/speed capture, optional final-segment pause on the existing audio clock, optional per-call terminal playback completion, detached preparation with complete semantic DBOPFS audio reuse and same-owner pending request sharing, independent prepared playback without a model load for cached audio, ordered audio-clock scheduling, playable audio, active-generation TTS operation-failure routing, mute, and cancellation are normalized; provider/model/runtime/voice policy remains caller-owned. Both speech roles default execution.device to auto: webnn-npu when navigator.ml.createContext is exposed, then webgpu when navigator.gpu is exposed, then wasm for CPU execution. Failed backend loads clean up the pool before trying fresh Workers with the same prepared model and dtype; explicit devices never fall back. STT capacity only accepts 1; TTS accepts 1 through 4. Execution snapshots expose requestedDevice, selectedDevice, maxConcurrentRequests, and activeRequestCount for both roles; selectedDevice is null while unloaded and names the successful upstream session backend request when loaded. It does not prove every operation used the physical NPU: WebNN unsupported operations may use WASM, and compatibility depends on the browser, driver, hardware, and graph.",
33
- "surface": "Browser-speech protocol/event/error/reason constants; default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and `browserSpeechDescriptor`; explicit `providerRuntime.status(role,{execution:true})` snapshots; `streamTTS(text,end,options={})` with optional voice, speed, pauseAfterMs, and waitForPlayback; automatic speech-input cleanup with SDK-internal preparation metadata; `prepareTTS({parts,storage,identity,signal,onState})` returning ordered segments, state, ready, getAudio(index), and cancel(); `playPreparedTTS(prepared,{signal,onState})` returning state, error, finished, pause(), resume(), and stop() with one playback lane per AI and observational state/error callbacks; configure/dispose speech, route lifecycle, declaration-validated chat/stream requests with exact ordered calls; optional streamRequest toolText:{name,field} and onToolText(text,call,displayId) for decoded selected argument text with actual call identity, distinct from ordinary prose and terminal tool execution; synthesis/transcription and playback controls; initializes from current canonical user readiness, installs `window.ai`, and projects `ai-ready` plus active-generation `ai-tts-failure`."
33
+ "surface": "prepareTTSPlayback(payload,signal) silently returns a real Blob or native-speech descriptor; native controls expose finished/released/state/error/pause/resume/stop, and actual release owns the playback lane. fetchTTS and durable prepareTTS report ARCANE_AI_TTS_AUDIO_EXPORT_UNAVAILABLE for native voices. Request-local model overrides remain exact and never mutate the configured model. Browser-speech protocol/event/error/reason constants; default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and `browserSpeechDescriptor`; explicit `providerRuntime.status(role,{execution:true})` snapshots; `streamTTS(text,end,options={})` with optional voice, speed, pauseAfterMs, and waitForPlayback; automatic speech-input cleanup with SDK-internal preparation metadata; `prepareTTS({parts,storage,identity,signal,onState})` returning ordered segments, state, ready, getAudio(index), and cancel(); `playPreparedTTS(prepared,{signal,onState})` returning state, error, finished, pause(), resume(), and stop() with one playback lane per AI and observational state/error callbacks; configure/dispose speech, route lifecycle, declaration-validated chat/stream requests with exact ordered calls; optional streamRequest toolText:{name,field} and onToolText(text,call,displayId) for decoded selected argument text with actual call identity, distinct from ordinary prose and terminal tool execution; synthesis/transcription and playback controls; initializes from current canonical user readiness, installs `window.ai`, and projects `ai-ready` plus active-generation `ai-tts-failure`."
34
34
  },
35
35
  {
36
36
  "file": "runtime/arcane/modules/AIModelSelectionController.js",
@@ -800,6 +800,31 @@
800
800
  "normalization": "Mail inputs/results normalized; transport failures mixed.",
801
801
  "surface": "default `Mail`, `resolveMailConfig()`; installs `window.mail`; `send()`."
802
802
  },
803
+ {
804
+ "file": "runtime/arcane/modules/MailApi.mjs",
805
+ "name": "MailApi.mjs",
806
+ "kind": "esm",
807
+ "exports": [
808
+ "MAIL_OUTBOX_IDEMPOTENCY_WINDOW_MS",
809
+ "MAIL_OUTBOX_PROTOCOL",
810
+ "MAIL_OUTBOX_STATES",
811
+ "MAIL_OUTBOX_TABLE",
812
+ "Mail",
813
+ "MailOutbox",
814
+ "MailTransportError",
815
+ "createMailOutbox",
816
+ "default",
817
+ "normalizeMailEndpoint",
818
+ "resolveMailConfig",
819
+ "sendMailReport",
820
+ "serializeMailReport"
821
+ ],
822
+ "summary": "Re-exports renderer Mail, durable outbox, and HTTP transport APIs through the public mail entrypoint.",
823
+ "availability": "Browser/native renderer; each re-export retains its owning module's host requirements",
824
+ "protocol": "Mail configuration and Arcane.mail.send or HTTP(S); arcane-mail-outbox/1",
825
+ "normalization": "Preserves the complete contracts of Mail.js, MailOutbox.mjs, and MailTransport.mjs without creating another transport or queue. Import retains Mail.js singleton installation in a browser window.",
826
+ "surface": "Default and named Mail, resolveMailConfig, MailOutbox/createMailOutbox and its four constants, MailTransportError, normalizeMailEndpoint, serializeMailReport, and sendMailReport."
827
+ },
803
828
  {
804
829
  "file": "runtime/arcane/modules/MailOutbox.mjs",
805
830
  "name": "MailOutbox.mjs",
@@ -835,6 +860,23 @@
835
860
  "normalization": "Endpoint, timeout, cancellation, network, HTTP, and response-contract errors are normalized.",
836
861
  "surface": "`MailTransportError`, `normalizeMailEndpoint()`, `serializeMailReport()`, and `sendMailReport()`."
837
862
  },
863
+ {
864
+ "file": "runtime/arcane/modules/MarkdownMedia.js",
865
+ "name": "MarkdownMedia.js",
866
+ "kind": "esm",
867
+ "exports": [
868
+ "decodeMarkdownMediaRecord",
869
+ "hydrateMarkdownMedia",
870
+ "parseMarkdownMediaReference",
871
+ "readMarkdownMedia",
872
+ "saveMarkdownMedia"
873
+ ],
874
+ "summary": "Stores complete local image records separately from Markdown and hydrates their stable references in rendered views.",
875
+ "availability": "Browser/native WebView with Blob, DOM, object URLs, and application-owned DBOPFS for storage operations",
876
+ "protocol": "arcane-media references, complete mediaType/dataUrl records, and DBOPFS",
877
+ "normalization": "Pure record decoding preserves complete content and singleton record layers. Hydration starts independent reads, removes unresolved local image sources before insertion, preserves successful siblings after an image failure, and owns cancellation, display URLs, and retained print resources.",
878
+ "surface": "saveMarkdownMedia({blob,tableName,fileName}), parseMarkdownMediaReference(reference), decodeMarkdownMediaRecord(value), readMarkdownMedia(reference), and hydrateMarkdownMedia(root,{signal}) returning ready/destroy/retain."
879
+ },
838
880
  {
839
881
  "file": "runtime/arcane/modules/MarkdownSpeech.js",
840
882
  "name": "MarkdownSpeech.js",
@@ -1010,7 +1052,7 @@
1010
1052
  "availability": "Browser or native WebView with the projected ChatEntity, DBOPFS, and a configured chat function or normalized Arcane.ai surface",
1011
1053
  "protocol": "Existing ChatEntity/DBOPFS methods plus provider-neutral chat request/result records",
1012
1054
  "normalization": "Preserves complete ordinary visible recurring provider history, one active raw structural continuation, every sanitized timestamped transcript record, and arbitrary nonempty caller-owned chat file names; commits live context atomically; falls back from optional streaming to configured non-stream transport; carries per-turn generation options while owning lifecycle callbacks; exposes complete data callbacks; accepts terminal-only structural calls; correlates every observed per-choice call against the exact validated terminal envelope before callback/persistence; atomically settles every pending ID once; and keeps malformed stored records readable without inventing or rewriting messages.",
1013
- "surface": "Default/named `PersistentAIChatSession`, `createPersistentAIChatSession()`; `create()`, `ai`, `chatEntity`, `fileName`, `ready()`, `history()`, `transcript()`, `settleMemory()`, `open()`, `send()`, and `stream()`. Optional constructor aiName and getter/setter accept a string; open/send/stream capture it before their first await. A nonblank application name is preserved exactly on the copied terminal message and retained assistant transcript, with the actual assistant record timestamp when available. Complete raw providerResponse stays unchanged; configured model context and memory omit the application display name. Existing history is never renamed or rewritten, and persist:false remains operation-only."
1055
+ "surface": "Per-turn persist:false and chatEntity.persist=false retain neither request nor response after the active operation; completed send/stream results expose retained outside provider content. New durable records contain role/content/timestamp and optional application display name or public tool name/status; existing stored records remain untouched. Default/named `PersistentAIChatSession`, `createPersistentAIChatSession()`; `create()`, `ai`, `chatEntity`, `fileName`, `ready()`, `history()`, `transcript()`, `settleMemory()`, `open()`, `send()`, and `stream()`. Optional constructor aiName and getter/setter accept a string; open/send/stream capture it before their first await. A nonblank application name is preserved exactly on the copied terminal message and retained assistant transcript, with the actual assistant record timestamp when available. Complete raw providerResponse stays unchanged; configured model context and memory omit the application display name. Existing history is never renamed or rewritten, and persist:false remains operation-only."
1014
1056
  },
1015
1057
  {
1016
1058
  "file": "runtime/arcane/modules/PreferenceStore.js",
@@ -1042,6 +1084,19 @@
1042
1084
  "normalization": "Preserves complete original parts and JSON-compatible semantic context, shares pending matching work on the same owner/storage group, admits segments in order, stores complete Blobs and MIME metadata, retains successful audio after failure or cancellation, and separates generation readiness from playback.",
1043
1085
  "surface": "Named prepareSpeech({owner,parts,originalParts,selection,segmentation,storage,identity,signal,onState,synthesize}) returns {segments,state,ready,getAudio(index),cancel()}; applications use AI.prepareTTS and AI.playPreparedTTS so the shared AI owner retains segmentation, provider readiness, capacity, and playback."
1044
1086
  },
1087
+ {
1088
+ "file": "runtime/arcane/modules/PrintView.js",
1089
+ "name": "PrintView.js",
1090
+ "kind": "esm",
1091
+ "exports": [
1092
+ "createPrintView"
1093
+ ],
1094
+ "summary": "Prints complete current rendered content through one document-owned print lifecycle and shared print stylesheet.",
1095
+ "availability": "Browser/native WebView with DOM, Fetch, and browser printing",
1096
+ "protocol": "DOM snapshots, beforeprint/afterprint, and shared css/print.css",
1097
+ "normalization": "Explicit requests await view-owned preparation; native Print captures synchronously. Rendered content, fonts, images, and resource retention remain complete. A true print result confirms only a requested browser dialog; snapshots and retained media survive until afterprint.",
1098
+ "surface": "createPrintView({host,content,title,active,priority,signal,onError,retain,prepare}) returns print() and destroy(). Import awaits the required shared print stylesheet."
1099
+ },
1045
1100
  {
1046
1101
  "file": "runtime/arcane/modules/QRCode.min.js",
1047
1102
  "name": "QRCode.min.js",
@@ -1194,9 +1249,9 @@
1194
1249
  ],
1195
1250
  "summary": "Preserves exact nonblank stored segment text; removes repeated formatting marks from only each outbound synthesis copy; eagerly submits complete parts to a capacity-advertising fetchTTS provider while keeping playback indexed; and retains serialized one-segment lookahead for other clients.",
1196
1251
  "availability": "Browser + compatible AI/native bridge",
1197
- "protocol": "AI.fetchTTS plus providerRuntime TTS execution capacity, or compatible serialized Arcane.speech.synthesize; globalThis.arcaneEvents, Blob URLs, audio element",
1252
+ "protocol": "AI.prepareTTSPlayback or AI.fetchTTS plus providerRuntime TTS execution capacity, native provider.prepare, or compatible serialized Arcane.speech.synthesize; globalThis.arcaneEvents, Blob URLs/audio element, and native playback controls",
1198
1253
  "normalization": "Exact nonblank split/part input strings are preserved in mutable records. Each synthesis request clones that part, removes repeated formatting marks from only the outbound input, and carries SDK-internal preparation metadata to prevent a second cleanup pass. A capable provider receives complete segments immediately and owns bounded FIFO admission; URLs and playback stay in exact input order. Native/custom clients remain serialized. Canonical state dispatch precedes the optional synchronous onState callback. Cancellation, Replay recovery, Blob results, and lifecycle state are normalized; provider failures remain external.",
1199
- "surface": "SpeechPlayback class/default, mutable `SPEECH_VOICE_OPTIONS` records, mutable `SPEECH_VOICE_ALIASES` membership, `SPEECH_PLAYBACK_STATE_EVENT`, optional constructor `onState(detail)`, `splitSpeechText()`, canonical playback lifecycle events, cancellation, and destroy APIs."
1254
+ "surface": "prepareTTSPlayback or direct native provider.prepare may return silent native-speech descriptors. autoplay:false stays silent; actual completion advances ordered parts and failed cancellation retains controls until released. Replay preserves completed segments and retries only missing failed generation. SpeechPlayback class/default, mutable `SPEECH_VOICE_OPTIONS` records, mutable `SPEECH_VOICE_ALIASES` membership, `SPEECH_PLAYBACK_STATE_EVENT`, optional constructor `onState(detail)`, `splitSpeechText()`, canonical playback lifecycle events, cancellation, and destroy APIs."
1200
1255
  },
1201
1256
  {
1202
1257
  "file": "runtime/arcane/modules/StaticDocumentCatalog.js",
@@ -69,8 +69,10 @@ include `arcane-os/preference-store`, `arcane-os/speech-playback`,
69
69
  `arcane-os/model-definition`, `arcane-os/conversation-timebox`,
70
70
  `arcane-os/conversation-action-items`, `arcane-os/conversation-closing-report`,
71
71
  and `arcane-os/chat-records`.
72
- `arcane/PreferenceStore` and `arcane/SpeechPlayback` remain their established
73
- browser import-map names. The additional portable `arcane-os/speech-text`
72
+ Physical, nested and virtual layouts also retain the established
73
+ `arcane/PreferenceStore` and `arcane/SpeechPlayback` browser names. Direct
74
+ installed-package root apps use the package-namespaced imports. The additional
75
+ portable `arcane-os/speech-text`
74
76
  subpath owns shared speech-input cleanup and has the same
75
77
  managed browser key. `arcane-os/mail` remains the existing Mail aggregation.
76
78
  There is
@@ -324,19 +326,20 @@ map-artifact lifecycle below remains separate.
324
326
 
325
327
  ## Browser runtime delivery
326
328
 
327
- External and modern integrated workspaces keep the same application URLs and a
328
- browser-standard import map. Each selected app owns
329
- `apps/<id>/modules/arcane.importmap.json`; the exact canonical JSON is also
329
+ External and modern integrated workspaces use a browser-standard import map.
330
+ Each selected app owns `modules/arcane.importmap.json` relative to its app root:
331
+ the repository root for a standalone app, or `apps/<id>/` for an explicitly
332
+ nested app. The exact canonical JSON is also
330
333
  embedded in its HTML entry as a managed `<script type="importmap"
331
334
  data-arcane-import-map>`. The map follows `<base>` and precedes module scripts,
332
335
  classic scripts, and module preloads, so application code can use stable named
333
336
  imports such as:
334
337
 
335
338
  ```javascript
336
- import ollama from 'arcane/Ollama';
339
+ import ollama from 'arcane-os/modules/Ollama.js';
337
340
  ```
338
341
 
339
- The physical-v1 tree lives entirely beneath `arcane/`. SDK `0.5.17` projects the
342
+ The supported physical-v1 tree lives entirely beneath `arcane/`. It projects the
340
343
  complete canonical runtime and browser runtime selected by the installed SDK
341
344
  package. Runtime dependencies stay under
342
345
  `arcane/dependencies/`; the SDK event and browser-AI closure stays under
@@ -351,9 +354,9 @@ integrated physical route uses the same ordered include list in its one route.
351
354
  Omitting only that final optional entry is compatible. Removing, reordering, or
352
355
  renaming any preceding entry changes the physical contract.
353
356
 
354
- The `0.5.17` map derives its complete entries from the selected runtime graph;
357
+ The map derives its complete entries from the selected runtime graph;
355
358
  application source imports do not select a fixed entry count. The operation
356
- result reports `imports`, `entryCount`, and `excludedModules`; reached-file
359
+ result reports `imports`, `documentCount`, and `excludedModules`; reached-file
357
360
  traversal remains internal. The
358
361
  managed graph exposes `arcane-os/event-manager`, `arcane-os/ai/browser-wasm`,
359
362
  `arcane-os/ai/browser-speech`, `arcane-os/preference-store`, and
@@ -371,16 +374,19 @@ The focused physical targets remain stable when their bindings are reached:
371
374
  | `arcane-os/preference-store` | `./arcane/modules/PreferenceStore.js` |
372
375
  | `arcane-os/speech-playback` | `./arcane/modules/SpeechPlayback.js` |
373
376
  | `event-pubsub` | `./arcane/sdk/dependencies/event-pubsub/index.js` |
377
+ | `strong-type` | `./arcane/dependencies/strong-type/index.js` |
374
378
  | `./node_modules/strong-type/index.js` | `./arcane/dependencies/strong-type/index.js` |
375
379
 
376
- There is no `arcane-os` package-root mapping, bare `strong-type` mapping, or
377
- catch-all `arcane/` prefix. Classic scripts, workers, stylesheets, and other
380
+ Direct installed routes translate these targets to their actual npm destinations,
381
+ including aliases. There is no `arcane-os` package-root mapping or catch-all
382
+ `arcane/` prefix. Classic scripts, workers, stylesheets, and other
378
383
  non-ESM assets use their documented URL or host loading contract rather than
379
384
  invented package bindings. Development serves the selected app plus the
380
385
  complete selected tree.
381
386
  Packaging copies the same map, app entry, and physical content into the
382
387
  [selected package output](#app-selected-package-output), defaulting to `dist/<id>`;
383
- targets never resolve through the consumer workspace's root `node_modules/`.
388
+ physical targets stay beneath the selected `arcane/` routes, while direct
389
+ installed targets retain `node_modules/<dependency>/...` inside the output.
384
390
  The two lowercase static runtime package specifiers above and the shared
385
391
  speech-text helper are exact npm package exports, so Node and managed-browser
386
392
  source can share those specifiers
@@ -390,42 +396,34 @@ without data URLs, copied modules, or a consumer-owned loader.
390
396
  The shared app-document owner derives the configured entry plus the
391
397
  deterministic admitted `.html`/`.htm` inventory from the descriptor's package
392
398
  include/exclude rules. `import-map`, development, and packaging all reuse that
393
- discovery. One transaction writes the artifact and the same managed
394
- JSON into every selected document. The result reports
395
- `documentPaths`, `documentCount`, and `files`: artifact first, configured entry
396
- second, then additional documents as `role:"document"`. The public CLI keeps
399
+ discovery. Import-map generation prepares the complete selection, then writes
400
+ the artifact and the same managed JSON into each selected document in order.
401
+ The result reports
402
+ `artifactPath`, `entryPath`, `documentPaths`, `documentCount`, the complete
403
+ `imports` record, and `committed`. `documentPaths` lists the configured entry
404
+ first, followed by the other selected documents. The public CLI keeps
397
405
  its existing two-option command; callers never maintain a separate page list.
398
406
 
399
- An external package and development server expose the runtime
400
- inventory at `/ARCANE_RUNTIME_PROJECTION.json`:
401
-
402
- ```javascript
403
- {
404
- schemaVersion: 1,
405
- kind: 'arcane-app-runtime-projection',
406
- sdkVersion,
407
- pathPrefix: 'arcane/',
408
- files: [{path}]
409
- }
410
- ```
411
-
412
- The projection contains the complete public paths relative to its declared
413
- `pathPrefix:'arcane/'` (for example, `modules/...` and `sdk/...`). It does not
414
- expose the private `/ARCANE_APP_RELEASE.json`. Genuinely malformed projection
415
- data fails `ARCANE_RUNTIME_PROJECTION_INVALID`.
407
+ The managed import map derives its complete bindings from the selected runtime
408
+ files. Enabled PWA delivery publishes its resource inventory in
409
+ `arcane-offline.json`; packaging records its complete file inventory in
410
+ `ARCANE_APP_RELEASE.json`. There is no generated
411
+ `ARCANE_RUNTIME_PROJECTION.json` endpoint in the current serving or packaging
412
+ contract.
416
413
 
417
414
  External `validateWorkspace()` results also expose `sdkInstallation` with
418
415
  exactly `dependencyName`, `packageSource`,
419
416
  `canonicalPackageRoot`, `packageName`, `packageVersion`, `runtimeRoot`,
420
417
  and `browserRuntimeRoot`. A
421
- workspace may use the canonical dependency name or one exact npm alias such as
422
- `npm:arcane-os@0.5.17`; the physical package manifest must still identify
423
- exactly as `arcane-os@0.5.17`. Canonical-plus-alias duplicates, multiple aliases,
424
- links/junctions, indirect package roots, or version drift are reported.
425
-
426
- For external workspaces, `arcane dev` serves the projected `arcane/` root,
427
- including `arcane/sdk` and `arcane/dependencies`, alongside the selected
428
- application. Integrated workspaces retain their configured physical routes.
418
+ workspace may use the canonical dependency name or one npm alias such as
419
+ `npm:arcane-os@0.51.1`; the installed package manifest identifies `arcane-os`
420
+ and supplies its actual version. The resolver requires one declaration and a
421
+ direct physical installation with runtime and browser-runtime directories.
422
+ The application's normal npm declaration and lockfile own version selection.
423
+
424
+ For external workspaces, `arcane dev` serves the selected direct npm, virtual
425
+ installed or physical routes alongside the selected application. Integrated
426
+ workspaces retain their configured physical routes.
429
427
  The explicit live-source development mapping remains a separate development
430
428
  path and does not rewrite the installed projection.
431
429
 
@@ -437,21 +435,24 @@ transport and host RPC remain separate layers.
437
435
  <details>
438
436
  <summary>Refresh lifecycle and managed-file commit behavior</summary>
439
437
 
440
- Scaffolding (`new` and `init`) creates the map. `dev` refreshes once before
441
- binding. `import-map` refreshes every admitted document explicitly.
442
- Non-dry-run `package`, browser `build`, and paired native packaging refresh
443
- before collecting source. Packaging does not run tests or checks automatically.
438
+ Root scaffolding reports the map as pending until its SDK dependency is installed;
439
+ root `init` with an installed SDK and explicit nested scaffolds generate it.
440
+ `dev` refreshes once before binding. `import-map` refreshes every admitted
441
+ document explicitly. `package`, browser `build`, and paired native packaging
442
+ consume the saved source and managed maps. Refresh maps through `import-map` or
443
+ ordinary `dev` startup when needed. Packaging does not run tests or checks
444
+ automatically.
444
445
  Explicit `test` and `check` operations read the existing map without rewriting it;
445
446
  `verify`, `bundle`, and browser `run` do not refresh. Dry-run packaging/build
446
447
  validates an existing map without rewriting it, and `import-map` itself has no
447
448
  supported dry-run.
448
449
 
449
- Generation stages the artifact and every selected HTML document beside their
450
- destinations and uses backups to restore the prior managed files after a
451
- handled pre-commit failure. Success reports `committed: true` and the complete
452
- managed path inventory. Cleanup failures after commit remain warnings. This is
453
- a handled-error transaction, not a claim of one filesystem-atomic rename for
454
- all files and not a durable crash journal.
450
+ Generation prepares the artifact and every selected HTML document, checks their
451
+ destinations, then writes the artifact followed by the documents. Cancellation
452
+ or a write failure can leave completed writes in place. Success reports
453
+ `committed: true` and the selected document paths. Event-delivery failure after
454
+ successful writes is returned as degraded delivery; it does not undo those
455
+ writes. There is no all-file rollback or durable crash journal.
455
456
 
456
457
  When tests are explicitly selected, external app tests receive an
457
458
  `arcane-test-import-map/1` context for that app's managed map. Each isolated
@@ -478,9 +479,13 @@ comes from the selected runtime and owns independent `llm`, `stt`, and
478
479
  `tts` selections. This SDK release ships browser-WASM LLM and browser
479
480
  speech provider/2 adapters and also adapts selected TWiN Cloud LLM,
480
481
  Core-backed Ollama LLM, on-device Whisper STT, and on-device Kokoro TTS routes
481
- into provider/2. There is no cloud speech route;
482
- other native, Core, or cloud routes require an externally supplied compatible
483
- adapter. The singleton itself is not an authentication or capability token. It
482
+ into provider/2. Built-in speech selections use `LOCAL_SPEACH` with
483
+ `whisper-small` for STT and `kokoro` for TTS; these local routes need no TWiN key.
484
+ Applications may explicitly configure `createTwinCloudTTSProvider()` with their
485
+ TWiN key for cloud TTS. Native browser recognition and synthesis providers are
486
+ also available through `arcane-os/ai/browser-speech`; their browser-owned engines
487
+ may use remote services. Other routes require a compatible provider adapter.
488
+ The singleton itself is not an authentication or capability token. It
484
489
  normalizes inspection, model authority,
485
490
  load/unload/dispose, cancellation, stream cleanup, status, and startup
486
491
  barriers. Each selected provider retains its real execution requirements.
@@ -491,8 +496,9 @@ For a browser-only LLM,
491
496
  [`arcane-os/ai/browser-wasm`](ai/browser-wasm.md) exposes `createArcaneAI()`
492
497
  and an adapter into the same provider-neutral lifecycle. For browser speech,
493
498
  [`arcane-os/ai/browser-speech`](ai/browser-speech.md) creates independent
494
- Whisper STT and Kokoro TTS providers that register directly with the normalized
495
- runtime. The SDK supplies mechanism; applications retain model/runtime choice,
499
+ Whisper STT, Kokoro TTS, native browser recognition/synthesis and explicit cloud
500
+ TTS providers. These providers register directly with the normalized runtime.
501
+ The SDK supplies mechanism; applications retain model/runtime choice,
496
502
  licenses, prompts, tools, voices, and disclosure policy.
497
503
 
498
504
  ### Browser-WASM LLM lifecycle
@@ -86,9 +86,11 @@ establish any particular installed application's browser lifecycle.
86
86
  `offline.include` and `offline.exclude` select literal paths or directory
87
87
  prefixes from the selected emitted inventory. An omitted or empty include list
88
88
  selects that inventory; exclusions subtract from it. App files use app-relative
89
- paths and shared runtime files use paths such as `arcane/sdk/pwa.mjs`.
90
- For example, selecting `modules` matches packaged
91
- `apps/<id>/modules/...`; emitted offline URLs keep the `apps/<id>/` prefix.
89
+ paths. Shared runtime selections follow the configured destinations: for example,
90
+ `node_modules/arcane-os/browser-runtime/pwa.mjs` for a direct installed route,
91
+ or `arcane/sdk/pwa.mjs` for a physical or virtual route.
92
+ For example, selecting `modules` matches a root app's `modules/...` or a nested
93
+ app's `apps/<id>/modules/...`; emitted offline URLs retain that selected layout.
92
94
  The application entry and generated PWA shell records are retained. Select the
93
95
  resources needed by every offline page, including its shared modules and styles.
94
96
  The worker script itself is never an application cache entry.
@@ -120,9 +122,10 @@ Browser packaging emits these files at the selected deployment root:
120
122
  | `arcane-sw.js` | Stable worker URL with the selected offline manifest embedded in its source. |
121
123
  | `arcane-pwa.mjs` | Independent registration and installation-component bootstrap importing the SDK client. |
122
124
 
123
- The selected app files remain under `apps/<id>/`, with shared runtime routes
124
- alongside them. The SDK supplies a root `index.html` launcher when selected
125
- shared content has no root page. The generated PWA files stay at the deployment
125
+ Standalone app files stay at the output root. Explicit multi-app workspaces
126
+ retain their selected app under `apps/<id>/`, with shared runtime routes alongside
127
+ it. The SDK supplies a root `index.html` launcher when selected content has no
128
+ root page. The generated PWA files stay at the deployment
126
129
  root so their worker can serve the selected app and shared resources. The
127
130
  worker is registered for the deployment root independently of any app-authored
128
131
  manifest scope.
@@ -140,12 +143,13 @@ The same bootstrap starts one initially hidden `pwa-install.html` component with
140
143
  the generated manifest's app name. Component loading and worker registration
141
144
  proceed independently.
142
145
 
143
- The selected PWA browser delivery removes only SDK-owned `arcaneVersion` fields
146
+ All SDK browser-resource delivery removes only SDK-owned `arcaneVersion` fields
144
147
  from actual local resource references, including the managed import map. Authored
145
148
  fields such as `v`, encoded and repeated fields, empty query segments, fragments,
146
149
  source spelling and unrelated payloads are preserved. The offline
147
- manifest now carries release information. Non-PWA and native delivery retain
148
- the [existing asset version contract](asset-versioning.md).
150
+ manifest carries release information. Non-PWA and native packaging use the same
151
+ [clean local resource URLs](asset-versioning.md). Native packaging does not
152
+ generate the browser PWA worker, installation manifest or registration bootstrap.
149
153
 
150
154
  ## Development and hosting
151
155
 
@@ -157,9 +161,11 @@ Package-only applications retain their existing descriptor workflow.
157
161
 
158
162
  With the external [`installed-v1` routes](protocols.md#installed-package-browser-routes),
159
163
  the server inventories the selected SDK directly in `node_modules`. Runtime
160
- resources retain their public `arcane/`, `arcane/sdk/`, and
161
- `arcane/dependencies/strong-type/` URLs, so offline selections use those logical
162
- paths rather than package filesystem paths. No workspace `arcane/` tree or
164
+ resources follow the configured destinations. Direct routes use real
165
+ `node_modules/<dependency>/...` URLs, including an npm alias when selected.
166
+ Earlier virtual routes retain their `arcane/`, `arcane/sdk/`, and
167
+ `arcane/dependencies/strong-type/` destinations. Offline selections use those
168
+ same emitted paths. No workspace `arcane/` tree or
163
169
  `arcane.lock.json` is needed. Packaging uses the same route selection and copies
164
170
  the selected resources into the portable output; existing physical projections
165
171
  remain supported.
@@ -179,7 +185,8 @@ write is needed. Edits to selected source files are picked up by the next due
179
185
  page-load check while the server remains running.
180
186
 
181
187
  For an enabled application, `arcane dev` serves the generated PWA files at the
182
- origin root and starts at the selected app page under `/apps/<id>/`. Use one
188
+ origin root and starts at the selected app entry: `/index.html` for a standalone
189
+ root app with that entry, or `/apps/<id>/<entry>` for a nested app. Use one
183
190
  selected app per development origin. The SDK uses `node-http-server` for source
184
191
  and packaged-preview serving, including conditional resource responses.
185
192
  Arcane development servers default to HTTPS, including localhost, and packaged
@@ -4,14 +4,21 @@ Arcane components are reusable HTML fragments loaded through the shared `<html-i
4
4
 
5
5
  A component file does not register its own custom element. The `<html-import>` host fetches the fragment from the same origin, attaches an open shadow root, runs its inline scripts with `this` bound to the host, and publishes `html-import-ready` or `html-import-error`. Component methods and properties are attached to that host.
6
6
 
7
+ Import the loader through `arcane-os/modules/HTMLImport.js` and the SDK-managed
8
+ import map. Component `href` values are asset URLs, so use the application's
9
+ configured runtime route. The default root npm layout serves components from
10
+ `/node_modules/arcane-os/runtime/arcane/components/`. Other `/arcane/...`
11
+ examples on this page describe an explicitly configured physical or virtual
12
+ route; direct npm applications use their corresponding installed-package URLs.
13
+
7
14
  ## Basic loading pattern
8
15
 
9
16
  ```html
10
17
  <script type="module">
11
- import '/arcane/modules/HTMLImport.js';
18
+ import 'arcane-os/modules/HTMLImport.js';
12
19
  </script>
13
20
 
14
- <html-import id="widget" href="/arcane/components/weather-widget.html"></html-import>
21
+ <html-import id="widget" href="/node_modules/arcane-os/runtime/arcane/components/weather-widget.html"></html-import>
15
22
 
16
23
  <script type="module">
17
24
  const widget = document.querySelector('#widget');
@@ -11,6 +11,13 @@ Entity creation and serialization are usually cross-host. Methods that touch
11
11
  DOM, DBOPFS, local storage, AI, or object URLs require the corresponding browser
12
12
  or native-WebView dependency.
13
13
 
14
+ Apps import entities with `arcane-os/entities/<file>.js`; the SDK-managed
15
+ import map resolves these names through the selected runtime routes. Default
16
+ root applications use their installed npm package directly. Absolute
17
+ `/arcane/entities/...` examples below assume an explicitly configured physical
18
+ or virtual `/arcane` route. Use the corresponding package specifier in direct
19
+ npm applications; entity inputs and behavior are the same.
20
+
14
21
  ## Canonical inventory
15
22
 
16
23
  | Module | Exports | Capability | Availability / normalization |
@@ -86,12 +93,17 @@ with complete ordinary visible call, public result, and assistant content.
86
93
  storage boundary. User and assistant records contain role, complete
87
94
  visible content, and their real timestamp. An assistant record may also carry
88
95
  its application-owned display `name`. A visible tool record may
89
- additionally carry its public name and plain result status, while its `content`
90
- comes only from the tool call's required user-facing `message`. System prompts,
96
+ additionally carry its public name and plain result status. A requested-call
97
+ record uses the call's required user-facing `message`; a settled tool result
98
+ uses its supplied public message. System prompts,
91
99
  reasoning, provider-extension fields, memory flags, raw tool calls, call IDs,
92
100
  argument objects, and raw tool returns never enter new DBOPFS writes.
93
101
  Messages added with `persist:false` participate only in their current operation;
94
102
  they are not retained in `messages`, `transcript`, memory extraction, or DBOPFS.
103
+ Setting `chat.persist=false` applies the same rule to new additions: the append
104
+ returns `false` before adding records to retained state or starting a write.
105
+ Existing retained messages and saved history remain unchanged. An already
106
+ accepted persistence write keeps its operation ownership and may finish.
95
107
  One complete nonblank assistant record is also a durable conversation entry, so
96
108
  a model-authored opening can be stored and survive maintenance before the first
97
109
  ordinary user turn. No synthetic user record is required or written.
@@ -2,7 +2,17 @@
2
2
 
3
3
  Every file shipped under `runtime/arcane/modules/` appears here. Start with the capability and example; expand into [protocol and host architecture](protocols.md) only when transport detail matters.
4
4
 
5
- Apps import renderer ESM from `/arcane/modules/<file>`. Classic scripts, the OPFS worker, uPlot stylesheet, and vendor license are called out explicitly. Importing a module does not grant a native capability.
5
+ Apps import renderer ESM with `arcane-os/modules/<file>`, including the `.js`
6
+ or `.mjs` extension. The SDK-managed import map resolves that name through the
7
+ application's selected runtime routes. Root applications use the installed
8
+ npm package directly by default. Absolute `/arcane/modules/<file>` examples
9
+ below describe an explicitly configured physical or virtual `/arcane` route;
10
+ that directory is not required by a direct npm layout.
11
+
12
+ Classic scripts, the OPFS worker, uPlot stylesheet, and vendor license use
13
+ their actual configured asset URLs and are called out separately. Importing a
14
+ module does not grant a native capability. See [installed-package browser
15
+ routes](protocols.md#installed-package-browser-routes) for route selection.
6
16
 
7
17
  Applications own response-detail preferences, their saved values, and any
8
18
  verbosity instruction appended to the system prompt. The former
@@ -94,6 +104,7 @@ own asynchronous work, cancellation, and backpressure.
94
104
  | [`LocalAIReadiness.js`](#localaireadinessjs) | esm | Derives selected AI requirements and returns a complete readiness/recovery report across browser, desktop, and Android modes. | Browser/native hybrid | Fully normalized report and stable error codes; browsers never probe Ollama. |
95
105
  | [`LocalAIReadinessController.js`](#localaireadinesscontrollerjs) | esm | Coordinates local-AI status component checks, ensured recovery, availability projection, and teardown. | Browser/native hybrid | Normalized controller state and change events. |
96
106
  | [`Mail.js`](#mailjs) | esm | Builds complete reports and prefers the native mail capability with an explicit HTTP transport fallback. | Browser/native hybrid + cloud | Mail inputs/results normalized; transport failures mixed. |
107
+ | [`MailApi.mjs`](#mailapimjs) | esm | Public renderer entrypoint for Mail, durable outbox, and HTTP transport APIs. | Browser/native renderer | Re-exports preserve their owning module's contracts. |
97
108
  | [`MailOutbox.mjs`](#mailoutboxmjs) | esm | Persists complete mail reports before delivery and normalizes idempotent enqueue, retry, reconciliation, and invalid-record maintenance. | Browser/native WebView or compatible injected host | Complete records, full work, cancellation, and lifecycle states normalized; storage, lock, and delivery failures coded. |
98
109
  | [`MailTransport.mjs`](#mailtransportmjs) | esm | Sends one complete mail report to a normalized HTTP(S) endpoint. | Browser/server with fetch + cloud | Normalized endpoint and transport errors; remote detail preserved. |
99
110
  | [`MarkdownMedia.js`](#markdownmediajs) | esm | Saves local Markdown images separately, decodes complete stored records, and resolves stable references in rendered views. | Browser / supported native WebView | Complete image records, concurrent display reads, cancellation, and print-owned URL lifetime. |
@@ -184,6 +195,14 @@ payload; an omitted value remains absent. The provider owns interpretation.
184
195
  This option does not switch a loaded browser-WASM model or its lifecycle:
185
196
  explicit provider/model selection and activation remain necessary there.
186
197
 
198
+ Both object-form methods also forward an optional request-local `temperature`
199
+ unchanged to built-in TWiN Cloud, including through its provider-runtime
200
+ adapter. Explicit `0` is preserved; omission or `undefined` leaves the outbound
201
+ field absent and preserves the provider default. The value is not clamped or
202
+ saved as a preference, concurrent calls remain independent, and retries reuse
203
+ the same value. This adds no output limit or native Ollama option mapping;
204
+ other registered providers retain their existing interpretation of the option.
205
+
187
206
  Built-in cloud chat decodes an HTTP error body once as JSON or text and rejects
188
207
  with that complete value unchanged. It does not reconstruct an Error, replace
189
208
  the message, or add `providerMessage`, `status`, or an SDK failure code to the
@@ -2485,7 +2504,11 @@ Defines the same-origin `<html-import>` loader with open shadow root, inline scr
2485
2504
 
2486
2505
  ### Public surface
2487
2506
 
2488
- default `HTMLImport`; registers `html-import`; `connectedCallback()` and `ready`.
2507
+ Default export: the constructor registered for `html-import`. When no
2508
+ constructor is registered, the module registers its SDK loader, whose
2509
+ `connectedCallback()` owns fragment loading and whose `ready` property reports
2510
+ completion. The browser invokes the connection callback when the host enters
2511
+ the document.
2489
2512
 
2490
2513
  Registration occurs once per custom-element registry. Imports through different
2491
2514
  module URLs reuse and export the registered constructor, including overlapping
@@ -2648,6 +2671,40 @@ import * as module from '/arcane/modules/Mail.js';
2648
2671
  console.log(Object.keys(module));
2649
2672
  ```
2650
2673
 
2674
+ ## MailApi.mjs
2675
+
2676
+ ### Overview
2677
+
2678
+ The managed-browser `arcane-os/mail` entrypoint re-exports the existing
2679
+ [`Mail.js`](#mailjs), [`MailOutbox.mjs`](#mailoutboxmjs), and
2680
+ [`MailTransport.mjs`](#mailtransportmjs) APIs. Their configuration, storage,
2681
+ delivery, errors, and lifecycle remain owned by those modules.
2682
+
2683
+ ### Public surface
2684
+
2685
+ Exact exports: `default`, `Mail`, `resolveMailConfig`,
2686
+ `MAIL_OUTBOX_IDEMPOTENCY_WINDOW_MS`, `MAIL_OUTBOX_PROTOCOL`,
2687
+ `MAIL_OUTBOX_STATES`, `MAIL_OUTBOX_TABLE`, `MailOutbox`, `createMailOutbox`,
2688
+ `MailTransportError`, `normalizeMailEndpoint`, `sendMailReport`, and
2689
+ `serializeMailReport`.
2690
+
2691
+ `default` and `Mail` refer to the same renderer Mail class. Import retains
2692
+ `Mail.js`'s browser singleton installation; it creates no additional queue or
2693
+ transport. Node resolves `arcane-os/mail` through the separate
2694
+ [Node mail entrypoint](mail.md).
2695
+
2696
+ ### Example
2697
+
2698
+ ```javascript
2699
+ import {resolveMailConfig} from 'arcane-os/mail';
2700
+
2701
+ const mailConfig = resolveMailConfig(
2702
+ {appName:'dragon-dispatch', endpoint:'https://mail.example.com/v1/mail'},
2703
+ {document:null, location:new URL('https://dispatch.example.com/')}
2704
+ );
2705
+ console.log(mailConfig.endpoint);
2706
+ ```
2707
+
2651
2708
  ## MailOutbox.mjs
2652
2709
 
2653
2710
  ### Overview