arcane-os 0.5.9 → 0.5.11

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 (55) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +117 -26
  3. package/browser-runtime/ai/browser-speech-providers.mjs +1 -1
  4. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +63 -39
  5. package/docs/architecture.md +303 -0
  6. package/docs/compatibility.md +38 -0
  7. package/docs/event-manager.md +263 -0
  8. package/docs/platform-targets.md +104 -0
  9. package/docs/publishing.md +126 -0
  10. package/docs/reference/README.md +206 -0
  11. package/docs/reference/ai/browser-speech.md +813 -0
  12. package/docs/reference/ai/browser-wasm.md +637 -0
  13. package/docs/reference/ai/twin-cloud.md +156 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +224 -0
  16. package/docs/reference/behavioral-testing.md +129 -0
  17. package/docs/reference/cli.md +820 -0
  18. package/docs/reference/core/README.md +61 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +907 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +59 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +1409 -0
  32. package/docs/reference/inventory/package-api.json +3194 -0
  33. package/docs/reference/inventory/runtime-components.json +1015 -0
  34. package/docs/reference/inventory/runtime-entities.json +25 -0
  35. package/docs/reference/inventory/runtime-modules.json +1367 -0
  36. package/docs/reference/mail.md +309 -0
  37. package/docs/reference/protocols.md +749 -0
  38. package/docs/reference/runtime-components.md +1529 -0
  39. package/docs/reference/runtime-entities.md +305 -0
  40. package/docs/reference/runtime-modules.md +3275 -0
  41. package/docs/reference/sdk-api.md +6733 -0
  42. package/docs/roadmap.md +79 -0
  43. package/docs/work-amplification.md +66 -0
  44. package/examples/wasm-ai-demo/README.md +80 -0
  45. package/examples/wasm-ai-demo/app.js +787 -0
  46. package/examples/wasm-ai-demo/index.html +343 -0
  47. package/examples/wasm-ai-demo/profile-tools.js +217 -0
  48. package/examples/wasm-ai-demo/profiles/BOSS.Modelfile +106 -0
  49. package/examples/wasm-ai-demo/profiles/PreCrisis.Modelfile +693 -0
  50. package/examples/wasm-ai-demo/rag/boss-library.json +3006 -0
  51. package/examples/wasm-ai-demo/rag.js +295 -0
  52. package/examples/wasm-ai-demo/server.mjs +71 -0
  53. package/package.json +11 -2
  54. package/runtime/arcane/modules/AI.js +1 -1
  55. package/runtime/arcane/modules/AIProviderRuntime.js +26 -5
@@ -0,0 +1,3275 @@
1
+ # Arcane runtime module catalog
2
+
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
+
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.
6
+
7
+ ## Availability shorthand
8
+
9
+ - **Cross-host** means in-process logic built from standard JavaScript/Web APIs.
10
+ - **Browser / native WebView** means DOM, storage, media, or component behavior available in a browser renderer and in supported native WebViews.
11
+ - **Native bridge** means the module requires an available `globalThis.Arcane` method.
12
+ - **Hybrid** means one public helper deliberately selects a documented native or browser/provider path.
13
+ - **Cloud** means the module can call an explicitly configured remote provider; it never implies automatic local-to-cloud fallback.
14
+ - **Node**, **worker**, and **vendor** identify specialized runtimes.
15
+
16
+ ## Runtime semantic events and teardown
17
+
18
+ SDK runtime modules publish semantic state and lifecycle occurrences through the
19
+ one branded, versioned `globalThis.arcaneEvents` authority in each JavaScript
20
+ realm. A class can retain its existing `EventTarget` or `on()` listener surface,
21
+ but that surface delegates to a `createArcaneEventSource()` view scoped
22
+ by the module's source and instance identifiers; it does not own a second event
23
+ bus, listener `Map`, or listener `Set`. Every canonical occurrence and every
24
+ one-way DOM projection carries an occurrence ID. DOM input events
25
+ remain local UI/platform input, and projected DOM `CustomEvent`s must not be
26
+ mirrored back into the canonical source.
27
+
28
+ `arcaneEvents.subscribe(type,handler,{once,signal})` and source-scoped
29
+ `subscribe()`/`on()` registrations return one idempotent unsubscribe function
30
+ (also exposed as `.dispose`). The singleton's convenience `on()`/`once()` methods are
31
+ chainable listener APIs that return the manager; lifecycle-owned consumers
32
+ use `subscribe()`. Instance `dispose()`/`destroy()` methods remove owned
33
+ listeners, abort owned work, suppress stale settlement, and dispose the instance
34
+ source. Module-lifetime singleton sources instead expose a focused module
35
+ teardown function where teardown is supported. Event publication is synchronous
36
+ and observational; promises, `AbortSignal`, and `createEventQueue` continue to
37
+ own asynchronous work, cancellation, and backpressure.
38
+
39
+ ## Canonical inventory
40
+
41
+ | Module | Kind | Capability | Availability | Normalization |
42
+ | --- | --- | --- | --- | --- |
43
+ | [`AI.js`](#aijs) | esm | Provider-selectable chat, speech-to-text, text-to-speech, tool calling, structured output, streaming, bounded synthesis, and ordered audio-clock playback. | Browser + native bridge + cloud | High-level chat/speech behavior and active TTS operation failures are normalized; provider diagnostics remain mixed. |
44
+ | [`AIPreferenceRuntime.js`](#aipreferenceruntimejs) | esm | Applies and reads non-persistent per-user AI preference overrides. | Cross-host | Normalized six-slot preference state. |
45
+ | [`AIPreferenceTuple.js`](#aipreferencetuplejs) | esm | Normalizes and compares the six provider/model preference slots. | Cross-host | Fully normalized frozen tuple. |
46
+ | [`AIProviderRuntime.js`](#aiproviderruntimejs) | esm | Owns provider-neutral selection, lifecycle, routing, startup, requests, streaming, cancellation, and independent LLM/STT/TTS state. | Cross-host runtime; provider-specific availability | Normalized required provider members plus route/status contracts, with explicit local-only selection and no implicit fallback. |
47
+ | [`AIResponseLength.js`](#airesponselengthjs) | esm | Normalizes current low/medium/high response-preference selectors while preserving complete prompts. | Cross-host | Current selector normalization; prompt content remains unchanged. |
48
+ | [`AIResponseURLPolicy.js`](#airesponseurlpolicyjs) | esm | Extracts and audits links from AI Markdown, rendered HTML, CSS, srcset, bare URLs, and email text. | Cross-host | Normalized frozen allowlist audit. |
49
+ | [`AIRuntimeState.js`](#airuntimestatejs) | esm | Publishes sticky mutable role snapshots, lifecycle intents, and startup-settlement barriers. | Cross-host state contract | Closed monotonic state records; events report state but grant no authority. |
50
+ | [`AnsiText.js`](#ansitextjs) | esm | Parses terminal ANSI sequences into display spans or strips them to plain text. | Cross-host | Normalized text/span output. |
51
+ | [`ApiModelDatabase.js`](#apimodeldatabasejs) | esm | Fetches an injectable HTTP JSON model with parser, cache, redacted public endpoint records, and request lifecycle events. | Browser / native WebView / server with fetch | Request records are normalized; fetch/provider failures remain mixed. |
52
+ | [`AppDataScope.js`](#appdatascopejs) | esm | Reconciles declared and native application identity and scopes OPFS/localStorage ownership fail-closed. | Browser / native WebView hybrid | Strict normalized identifiers and coded mismatch failures. |
53
+ | [`AppearancePreferences.js`](#appearancepreferencesjs) | esm | Defines, stores, and applies color scheme, density, reduced motion, and large-text preferences. | Browser / native WebView hybrid | Normalized values; storage/host failures remain mixed. |
54
+ | [`ArcaneCommunicationBridge.js`](#arcanecommunicationbridgejs) | esm | Maps provider HTTP threads/messages/connect/disconnect endpoints to normalized communication entities. | Browser / native WebView / server with fetch | Entity results are normalized; provider/transport failures remain mixed. |
55
+ | [`ArcaneNavigationPolicy.js`](#arcanenavigationpolicyjs) | esm | Creates an HTTP(S) navigation guard with explicit secure-mode domain and CIDR policy decisions. | Cross-host | Complete mutable decisions; ordinary mode warns and continues, while explicitly selected `secure: true` fails closed. |
56
+ | [`ArcaneNetworkPolicy.js`](#arcanenetworkpolicyjs) | esm | Validates the Arcane domain/network deny policy and matches domain, IPv4/IPv6 CIDR, protocol, and port rules. | Cross-host | Strict coded normalization. |
57
+ | [`AsyncBoundary.js`](#asyncboundaryjs) | esm | Runs one asynchronous operation with timeout, abort, result validation, and stable boundary errors. | Cross-host | Fully normalized timeout/abort errors. |
58
+ | [`BrowserTestSuite.js`](#browsertestsuitejs) | esm | Runs a complete sequential browser test list with explicit cancellation and full-detail lifecycle events. | Browser / standard Web APIs | Mutable results and skip/assertion errors normalized without suite-created caps or timers. |
59
+ | [`CalculatorEngine.js`](#calculatorenginejs) | esm | Evaluates arithmetic, powers, constants, and common functions without `eval`. | Cross-host | Normalized `Calculation` result and parser errors. |
60
+ | [`ChartLibrary.js`](#chartlibraryjs) | esm | Loads the bundled uPlot classic script once and returns its global constructor. | Browser / native WebView | Load state/errors normalized; uPlot result is vendor-native. |
61
+ | [`ChatRecords.js`](#chatrecordsjs) | esm | Detects conversation entries and projects retained state into recurring provider context. | Cross-host | Boolean entry results and recurring context are normalized. |
62
+ | [`CommunicationAppController.js`](#communicationappcontrollerjs) | esm | Binds shared inbox, conversation, settings, theme, and provider workflows into one UI controller. | Browser / native WebView hybrid | Controller state normalized; provider/DOM failures mixed. |
63
+ | [`CommunicationHub.js`](#communicationhubjs) | esm | Fans out provider refresh/send operations and aggregates normalized threads/messages. | Cross-host with injected providers | Normalized aggregates; refresh contains per-provider failures. |
64
+ | [`CommunicationPreferences.js`](#communicationpreferencesjs) | esm | Stores app-scoped, non-secret communication provider preferences. | Browser / native WebView hybrid | Normalized preference record; storage failures mixed. |
65
+ | [`CommunicationProviderRegistry.js`](#communicationproviderregistryjs) | esm | Registers and queries validated provider definitions, channels, and required methods. | Cross-host | Strict normalized registry. |
66
+ | [`ComponentContracts.js`](#componentcontractsjs) | esm | Owns normalized configuration/value contracts and shared explicit STT activation behavior for chart, dashboard, Markdown, and voice components. | Cross-host | Fully normalized labels, rows, definitions, visibility, formats, editor and voice options, plus capability-neutral STT activation intent and presentation state. Complete finite progress measures remain visible, including fractional and over-total values. |
67
+ | [`ConfiguredAIChatSession.js`](#configuredaichatsessionjs) | esm | Owns ordinary visible recurring AI turns, one active structural continuation, context construction, provider-response preservation, and atomic history commit. | Native bridge by default; cross-host with injected chat | Normalized session/result; provider rejection preserved. |
68
+ | [`ConversationActionItems.js`](#conversationactionitemsjs) | esm | Normalizes, creates, updates, remembers, selects, and formats complete conversation action items. | Cross-host | Fully normalized status/base/presentation contract. |
69
+ | [`ConversationClosingReport.js`](#conversationclosingreportjs) | esm | Defines the closing-report tool, instruction, result normalizer, call classifier, and formatter. | Cross-host | Fully normalized report contract. |
70
+ | [`ConversationTimebox.js`](#conversationtimeboxjs) | esm | Owns conversation limits, control messages, submission barriers, elapsed formatting, and delivery proof. | Cross-host | Fully normalized state/command/delivery errors. |
71
+ | [`CoreLocalModelCatalog.js`](#corelocalmodelcatalogjs) | esm | Projects Core local-AI status into UI-safe model and speech availability catalogs. | Cross-host | Fully normalized descriptors and stable availability labels. |
72
+ | [`DataMaintenance.js`](#datamaintenancejs) | esm | Deletes empty chats and associated/empty memory records inside the current app data scope. | Browser / native WebView | Normalized counts; destructive storage failures preserved. |
73
+ | [`DBLS.js`](#dblsjs) | esm | Provides app-scoped localStorage tables, batch reads/writes, filtering, deletion, and counts. | Browser / native WebView | Scoped keys and values normalized; storage failures mixed. |
74
+ | [`DBOPFS.js`](#dbopfsjs) | esm | Provides app-scoped OPFS tables, worker I/O, backup/restore, compression, and CRUD/batch APIs. | Browser / native WebView | App scope and recognized file parsing normalized; nonblank unreadable JSONL rows and DOM/storage errors are preserved. |
75
+ | [`DBOPFSDocumentLibrary.js`](#dbopfsdocumentlibraryjs) | esm | Bootstraps and searches an app-defined DBOPFS corpus and builds complete chat context. | Browser or compatible DBOPFS host | Existing DBOPFS semantics; generation completion and complete search only after the app calls it or wires its context builder. |
76
+ | [`DBOPFSWorker.js`](#dbopfsworkerjs) | worker | Serializes OPFS sync-handle read/write requests from a MessagePort. | Dedicated worker | Responses normalize to `{success,fileData?}` or `{error:{name,message}}`. |
77
+ | [`DevelopmentWorkspace.js`](#developmentworkspacejs) | esm | Provides complete workspace inspection, context, setup task, and Node installer clients without arbitrary command execution. | Native bridge | Complete plain-text inputs and provider result/error preserved. |
78
+ | [`DirectoryPicker.js`](#directorypickerjs) | esm | Wraps the provider-owned native directory chooser and normalizes selected/cancelled/error results. | Native bridge | Complete mutable caller options and provider result fields; coded cancellation and malformed-result errors. |
79
+ | [`DocumentLexicalSearch.js`](#documentlexicalsearchjs) | esm | Provides dependency-free deterministic metadata/body ranking and complete excerpts. | Cross-host | Mutable complete results with no storage, provider, or network side effects. |
80
+ | [`DocumentNavigation.js`](#documentnavigationjs) | esm | Binds document navigation, filtering, history, current-item reveal, and load initialization. | Browser / native WebView | Normalized filter/navigation state; DOM effects preserved. |
81
+ | [`Errors.js`](#errorsjs) | esm | Normalizes global errors/rejections, fingerprints and deduplicates incidents, persists a complete ledger, and performs complete delivery. | Browser / native WebView hybrid | Incident records normalized; storage/mail failures isolated. |
82
+ | [`GifEncoder.js`](#gifencoderjs) | esm | Encodes indexed frames into a complete animated GIF using palette mapping and LZW. | Cross-host | Normalized complete binary output. |
83
+ | [`HTMLImport.js`](#htmlimportjs) | esm | Defines the same-origin `<html-import>` loader with open shadow root, inline script execution, and readiness/error events. | Browser / native WebView | Public error detail normalized; fetch/DOM failure preserved. |
84
+ | [`InMemoryCommunicationProvider.js`](#inmemorycommunicationproviderjs) | esm | Implements deterministic in-memory thread/message/send behavior for demos and tests. | Cross-host | Normalized communication entities. |
85
+ | [`IsolatedModelQuestionRunner.js`](#isolatedmodelquestionrunnerjs) | esm | Inspects one selected model and runs one isolated question while preserving the complete answer. | Native bridge or injected provider | Normalized model/result and coded errors. |
86
+ | [`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. |
87
+ | [`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. |
88
+ | [`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. |
89
+ | [`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. |
90
+ | [`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. |
91
+ | [`Marked.min.js`](#markedminjs) | esm | Vendored Marked 18.0.5 Markdown lexer, parser, renderer, extension, and walk-token API. | Cross-host vendor module | Vendor-native Marked contract. |
92
+ | [`MD.js`](#mdjs) | esm | Renders complete Markdown with Marked and exposes the complete rendered markup. | Browser / native WebView | Complete raw and rendered Marked values; parse errors vendor-native. |
93
+ | [`MemoryRecords.js`](#memoryrecordsjs) | esm | Normalizes memory content and detects meaningful stored memory. | Cross-host | Fully normalized string/boolean results. |
94
+ | [`MessageAdvisory.js`](#messageadvisoryjs) | esm | Normalizes message content advisories and contains per-message inspection failures. | Cross-host | Normalized advisory records; inspector failures converted to unavailable results. |
95
+ | [`ModelDefinition.js`](#modeldefinitionjs) | esm | Parses the deterministic packaged Modelfile subset and extracts the SYSTEM prompt. | Cross-host | Complete mutable definition with coded malformed-input errors. |
96
+ | [`Ollama.js`](#ollamajs) | esm | Provides the first-class Arcane Ollama client without direct access to localhost:11434. | Native bridge | Principal methods preserve provider-native envelopes; readiness/text/unload helpers normalize. |
97
+ | [`OllamaModelIdentifier.js`](#ollamamodelidentifierjs) | esm | Validates and canonicalizes the syntax of Ollama model identifiers without granting model admission. | Cross-host | Fully normalized string/boolean result. |
98
+ | [`OllamaSettings.js`](#ollamasettingsjs) | esm | Defines complete runtime/service preference schemas and deterministic Arcane brain alias names. | Cross-host | Fully normalized settings/name contract. |
99
+ | [`OpenMeteoWeatherProvider.js`](#openmeteoweatherproviderjs) | esm | Searches and loads Open-Meteo data into complete mutable Arcane weather entities. | Browser / native WebView / server with fetch + cloud | Provider data normalized to mutable entities; transport errors mixed. |
100
+ | [`PersistentAIChatSession.js`](#persistentaichatsessionjs) | esm | Adds explicit retained-history/memory policy to complete configured chat without changing DBOPFS or ChatEntity semantics. | Browser / native WebView with DBOPFS and configured chat | Retained context commits atomically; `persist:false` turns are one-operation-only. |
101
+ | [`PreferenceStore.js`](#preferencestorejs) | esm | Loads and updates schema-defined app preferences through native storage with a narrow browser fallback. | Browser/native hybrid | Complete ordinary values remain mutable; setAll uses one optional atomic adapter batch for every selected value when advertised, otherwise performs complete ordered serial writes, and only exact unsupported native capability changes future operations to the browser fallback. |
102
+ | [`QRCode.min.js`](#qrcodeminjs) | classic-script | Vendored QRCode generator for DOM, canvas, SVG, and image output. | Browser vendor script | Vendor-native. |
103
+ | [`Questionnaire.js`](#questionnairejs) | esm | Evaluates whether a one-time questionnaire prompt is due without performing the prompt. | Cross-host | Normalized conservative boolean. |
104
+ | [`RecordLinkIndex.js`](#recordlinkindexjs) | esm | Parses record links and builds their normalized index. | Cross-host | Fully normalized. |
105
+ | [`RecordPassageIndex.js`](#recordpassageindexjs) | esm | Indexes text lines, page markers, dates, rules, and excerpts for record review. | Cross-host | Fully normalized. |
106
+ | [`RecordReviewStore.js`](#recordreviewstorejs) | esm | Stores normalized record-review decisions through native storage or app-scoped local fallback. | Browser/native hybrid | Complete records preserved; unreadable stored content fails observably. |
107
+ | [`RiskSignalAnalyzer.js`](#risksignalanalyzerjs) | esm | Matches configured risk signals and levels against complete text. | Cross-host | Fully normalized. |
108
+ | [`ScamRiskPolicy.js`](#scamriskpolicyjs) | esm | Combines deterministic scam signals with optional Arcane blocked-domain evidence and safety guidance. | Cross-host | Complete mutable results; blocked-domain policy requires `secure:true`. |
109
+ | [`ScopedOPFSCache.js`](#scopedopfscachejs) | esm | Provides a narrow exact-key JSON cache inside one app-owned OPFS namespace. | Browser / native WebView | Filename-safe keys, complete JSON values, and malformed-cache cleanup normalized; storage errors mixed. |
110
+ | [`ScreenCapture.js`](#screencapturejs) | esm | Captures a display surface as image, video, or GIF with explicit lifecycle events. | Browser / native WebView | State/events normalized; permission and codec errors mixed. |
111
+ | [`SpeechPlayback.js`](#speechplaybackjs) | esm | Preserves exact nonblank text as one speech segment, queues latest-request synthesis, and controls lookahead HTML audio playback. | Browser + native bridge | Exact input text and state normalized; provider/media failures mixed. |
112
+ | [`StaticDocumentCatalog.js`](#staticdocumentcatalogjs) | esm | Loads a positive static document inventory with cache, search, and complete context. | Browser / native WebView / server with fetch | Mutable complete catalog/content normalization; malformed data and transport failures remain visible. |
113
+ | [`SystemAppearance.js`](#systemappearancejs) | esm | Reads or applies native appearance, returning an explicit unsupported browser state when no bridge exists. | Browser/native hybrid | Absent bridge normalized; native result/error preserved. |
114
+ | [`SystemPlatformPresentation.js`](#systemplatformpresentationjs) | classic-script | Maps kernel names to presentation labels/classes without granting platform authority. | Browser / native WebView classic script | Fully normalized presentation only. |
115
+ | [`SystemToolRegistry.js`](#systemtoolregistryjs) | esm | Registers validated command builders and constructs command strings without executing them. | Cross-host | Fully normalized definitions/quoting. |
116
+ | [`TerminalClient.js`](#terminalclientjs) | esm | Maps native terminal sessions and Arcane events into an EventTarget client. | Native bridge | Client events/state normalized; native result/error mixed. |
117
+ | [`TerminalCommandRegistry.js`](#terminalcommandregistryjs) | esm | Routes parsed command lines to injected handlers and provides definitions/completions. | Cross-host | Parsing/routing normalized; handler result/error preserved. |
118
+ | [`ThemeBootstrap.js`](#themebootstrapjs) | esm | Performs import-time Arcane theme loading and subscribes to native appearance changes. | Browser/native hybrid | Theme state normalized; storage/native errors mixed. |
119
+ | [`ThemeManager.js`](#thememanagerjs) | esm | Loads, applies, previews, saves, resets, and synchronizes semantic Arcane themes. | Browser/native hybrid | Theme values/events normalized; storage/native failures mixed. |
120
+ | [`TimeGuard.js`](#timeguardjs) | esm | Persists and evaluates clock rollback and grace-period state. | Browser / native WebView | Time decisions normalized; storage lifecycle mixed. |
121
+ | [`ToolCallRouter.js`](#toolcallrouterjs) | esm | Parses OpenAI-style tool calls and dispatches complete or streamed calls to injected handlers. | Cross-host | Argument records validated; handler results returned or all-settled. |
122
+ | [`uPlot.iife.min.js`](#uplotiifeminjs) | classic-script | Vendored uPlot chart constructor and rendering runtime. | Browser vendor script | Vendor-native. |
123
+ | [`uPlot.LICENSE.txt`](#uplotlicensetxt) | license | License companion for the bundled uPlot vendor runtime. | Documentation asset | Not executable. |
124
+ | [`uPlot.min.css`](#uplotmincss) | stylesheet | Bundled uPlot presentation stylesheet. | Browser stylesheet | Presentation only. |
125
+ | [`WaitForComponent.js`](#waitforcomponentjs) | esm | Waits for a component property, method, or readiness event with optional error event and bounded timeout. | Cross-host EventTarget / browser component | Normalized coded readiness, error, and timeout results. |
126
+ | [`YouTubeMedia.js`](#youtubemediajs) | esm | Parses YouTube video/playlist locators and constructs ordinary embed URLs with opt-in privacy enhancement. | Cross-host | Fully normalized mutable locators. |
127
+
128
+ ## AI.js
129
+
130
+ ### Overview
131
+
132
+ Provider-selectable chat, speech-to-text, text-to-speech, tool calling,
133
+ structured output, streaming, bounded synthesis, and ordered audio-clock
134
+ playback.
135
+
136
+ ### Public surface
137
+
138
+ default `AI`; read-only `providerRuntime`, `browserSpeechConfiguration`, and
139
+ `browserSpeechDescriptor`; `configureBrowserSpeech(configuration,{signal})`,
140
+ `disposeBrowserSpeech({signal})`, `setAI()`, `configureProviders()`,
141
+ `configureSpeechProviders()`, `transitionAI()`, `transitionProviders()`,
142
+ `transitionSpeechProviders()`, `startProviders()`, `setSpeechMuted()`,
143
+ `streamRequest()`, `streamMessage()`, `fetchRequest()`, `fetch()`,
144
+ read-only `ttsSegmentation`, `configureTTSSegmentation()`, `streamTTS()`,
145
+ `finishTTS()`, `fetchTTS()`, `fetchSTT()`, `stopAudio()`, `resumeAudio()`,
146
+ `playAudio()`; consumes `user-entity-loaded` and `arcane-ollama-ready`,
147
+ installs `window.ai`, and emits `ai-ready` and `ai-tts-failure`.
148
+
149
+ Initialization uses the canonical realm user's actual readiness state. If
150
+ `window.user?.ready` is already true, AI initializes immediately. Otherwise one
151
+ shared registration observes `user-entity-loaded`, then rechecks readiness
152
+ after registration so an event that occurred between the initial check and the
153
+ subscription cannot strand initialization. Source event projections do
154
+ not need to preserve object identity with `window.user`; the event only prompts
155
+ the readiness recheck. This boundary uses no timer or polling fallback.
156
+
157
+ The provider-runtime methods keep LLM, STT, and TTS selection explicit. They do
158
+ not reinterpret one provider's failure as permission to select another
159
+ provider. `transitionAI()` and `transitionProviders()` are deliberate
160
+ cross-role transitions: each stops queued audio, unloads the current LLM, STT,
161
+ and TTS roles, then applies the replacement configuration. `transitionAI()`
162
+ returns aggregate runtime status; `transitionProviders()` returns the configured
163
+ three-role route configuration. Selected TWiN Cloud `TWIN` LLM, `OLLAMA` LLM,
164
+ and Core `LOCAL_SPEACH` STT/TTS built-in routes expose truthful capability-only
165
+ readiness through internal provider/2 adapters without probing, downloading, or
166
+ hiding a load. Configured `OPENAI` speech preferences migrate to on-device
167
+ `LOCAL_SPEACH`, with Whisper for STT and Kokoro for TTS. TWiN Cloud availability
168
+ requires the selected LLM route, its model, a credential, and `fetch`; Core speech
169
+ availability requires the exact selected `Arcane.speech.transcribe` or
170
+ `synthesize` method. `fetchRequest()`
171
+ keeps the selected provider's public response shape. Browser speech routes
172
+ translate the existing AI.js STT `{audio:Blob|File,mimeType,model}` and TTS
173
+ `{model,input,responseFormat,voice?,speed?}` requests at the provider boundary;
174
+ only WAV is accepted for the shared TTS result. TTS voice selection comes from
175
+ the exact selected local provider/model catalog `defaultVoice`; a saved
176
+ OpenAI-route voice is never forwarded to another provider route.
177
+
178
+ The TWiN Cloud built-in provider and default-model preference sentinel are
179
+ `TWIN`. Applications upgrading saved `OPENAI` LLM selections must explicitly
180
+ replace only the exact uppercase `OPENAI` value in tuple slot 0 (LLM provider)
181
+ and slot 3 (default-model sentinel) with `TWIN`, before importing `AI.js` or any module that imports it,
182
+ hydrating a ready `window.user`, applying saved preferences, or starting
183
+ providers. Importing `AI.js` can immediately consume a ready user's saved tuple.
184
+ Keep every other tuple value unchanged.
185
+ The SDK supplies no built-in alias and does not rewrite persisted preferences.
186
+ Preserve `openai-gpt-oss-120b`, `openai-gpt-oss-20b`, OpenAI-compatible wire
187
+ terminology, and the separate Core `provider:'openai'` contract. See the
188
+ [complete migration example](ai/twin-cloud.md).
189
+
190
+ `fetchRequest()` and `streamRequest()` accept `reasoningEffort` as a
191
+ provider-neutral request option. Its exact values are `none`, `low`, `medium`,
192
+ `high`, and `max`; an omitted value leaves the provider default unchanged.
193
+ TWiN Cloud translates the selected value to the DigitalOcean Serverless
194
+ Inference `reasoning_effort` field. Its default model remains
195
+ `openai-gpt-oss-120b`, while an explicitly selected `openai-gpt-oss-20b` is
196
+ preserved. Reasoning effort does not alter complete streaming data, structural
197
+ tool declarations, emitted tool calls, or callback ordering.
198
+
199
+ `configureSpeechProviders({stt,tts})` commits only the two speech routes and
200
+ leaves the current LLM route and sticky lifecycle record unchanged. Both speech
201
+ roles must be unloaded, use local-only selections, and own no request, load,
202
+ unload, or dispose operation. Non-local STT and TTS selections reject with
203
+ `AI_STT_DEVICE_ONLY` and `AI_TTS_DEVICE_ONLY`, respectively.
204
+ `transitionSpeechProviders({stt,tts})` stops queued audio, explicitly unloads
205
+ only STT and TTS, then commits that same closed speech route record. Neither
206
+ method loads a model, selects a fallback, or changes caller-owned model or voice
207
+ policy.
208
+
209
+ `startProviders({startLanguageModel=true,startMuted=true,startTranscription=false,signal=null}={})`
210
+ starts provider-owned text chat without requesting an STT load by default.
211
+ Callers selecting a browser-WASM LLM pass `startLanguageModel:false` so it
212
+ remains selected and unloaded until the user uses the shared chat activation
213
+ control or the application publishes an equivalent explicit user load intent.
214
+ The default preserves startup behavior for existing Cloud/Core routes. Startup
215
+ does not undo an already ready or independently loading LLM or STT role. Its default
216
+ `startMuted:true` path cancels active TTS work and unloads TTS. Callers must opt
217
+ into eager STT startup with `startTranscription:true` or publish the explicit
218
+ user activation intent exposed by the shared speech component.
219
+ `setSpeechMuted(false)` records the public unmuted state only after the selected
220
+ TTS route reaches ready; a failed load leaves the public state muted. In contrast,
221
+ `setSpeechMuted(true)` cancels active TTS work and unloads that role.
222
+ The optional browser-speech `tts.execution` record selects
223
+ `device:'auto'|'webgpu'|'wasm'` and a `maxConcurrentRequests` integer from 1
224
+ through 4. Omission uses GPU-first automatic selection with four bounded Kokoro
225
+ Worker/session slots; STT remains one WASM Worker.
226
+ Capacity 4 means up to four segments synthesize at once. Segment 5 and later
227
+ wait in the SDK's FIFO queue; they are not dropped. Synthesis may finish out
228
+ of order, but playback waits for earlier segments and plays exact input order.
229
+ Each slot owns a Worker/model session, so raising capacity trades memory for
230
+ latency. This capacity does not establish physical GPU kernel overlap.
231
+
232
+ After configuration, explicitly inspect execution through
233
+ `ai.providerRuntime.status('tts', {execution:true}).execution`. When supplied
234
+ by the selected provider, this read returns its execution snapshot. Kokoro
235
+ reports `requestedDevice`, `selectedDevice`, `maxConcurrentRequests`, and
236
+ `activeRequestCount`. `selectedDevice` is `null` before load and after unload.
237
+ `requestedDevice === 'auto' && selectedDevice === 'wasm'` identifies automatic
238
+ WASM fallback after a successful load. Calling `status()` without options keeps
239
+ the existing sticky lifecycle snapshot and does not inspect provider execution.
240
+ Provider inspection failures are surfaced to the caller.
241
+ `fetchTTS({model,voice,input,responseFormat,speed},signal)` accepts the public
242
+ provider-neutral synthesis shape, requires any explicit model to match the
243
+ selected route, and fills an omitted voice only from the selected model
244
+ catalog's `defaultVoice`. An omitted response format preserves the instance's
245
+ existing `audioFormat` when the catalog does not declare response formats. When
246
+ the selected model declares `speech.responseFormats`, that setting is used only when supported; if
247
+ the setting is the instance's `opus` default and the model rejects it, the catalog's
248
+ `speech.defaultResponseFormat` is used, while any other unsupported setting is
249
+ rejected. It propagates the caller-owned signal and returns a playable `Blob`;
250
+ it does not independently choose a provider, cloud fallback, model, runtime, or
251
+ voice policy for the application. Existing `streamTTS()` and `finishTTS()` use
252
+ this same request boundary. Streaming speech retains sentence
253
+ segmentation by default. `configureTTSSegmentation({punctuation,wordCadence})`
254
+ accepts `punctuation:'sentence'|'any'|'none'` and a `wordCadence` that is either
255
+ `null` or a positive integer. `punctuation:'any'` completes a segment at a
256
+ Unicode punctuation run without requiring following whitespace. Apostrophes,
257
+ commas, and hyphens remain inside a segment when they join Unicode letters or
258
+ numbers. A potentially joining mark at the current end of an incremental stream
259
+ waits for the next character or terminal flush before the boundary is decided;
260
+ `wordCadence` completes one after that many whole words. The earliest available
261
+ boundary wins. Segmentation preserves every character, including punctuation
262
+ and whitespace. Every completed segment enters synthesis immediately; provider
263
+ capacity supplies FIFO backpressure while allowing bounded TTS work to overlap.
264
+ A later segment may finish synthesis first, but playback schedules only the
265
+ contiguous ready prefix in original order. Decoded buffers with known duration
266
+ are placed consecutively on the `AudioContext` clock, so callback latency does
267
+ not add a seam between ready chunks. A genuine synthesis underrun begins the
268
+ next buffer at the current audio time. Mute, stop, provider transition, and
269
+ cancellation retain authority over the complete queue and already scheduled
270
+ sources.
271
+ Every active-generation, non-abort synthesis, decode, playback-start, or
272
+ playback-resume failure emits `ai-tts-failure` with the complete `Error`, exact
273
+ operation boundary, generation, and stable reason. Muting, explicit
274
+ cancellation, permission waiting, and superseded generations do not emit a
275
+ failure. The operation event does not rewrite provider readiness; the consuming
276
+ Chat/Speech surface owns its visible mute and recovery state.
277
+ `fetchSTT(audioFile,signal)` propagates the caller-owned signal;
278
+ provider routes accept a `Blob` or `File` directly and leave media decoding,
279
+ PCM normalization, and WAV construction to the selected shared provider;
280
+ delivery suppression is guaranteed after abort, while underlying provider-stop
281
+ claims remain limited to that provider's cancellation contract.
282
+
283
+ Every function declaration accepted by the chat and streaming APIs must define
284
+ `function.parameters.properties.message` as a string with `minLength:1` and
285
+ include `message` in the declaration's `required` list. Every emitted structural
286
+ call must preserve its exact nonempty `id`, function name, and JSON argument
287
+ string; that JSON must encode an object with a nonempty user-facing `message`.
288
+ The message is ordinary progress or next-step text. Complete argument envelopes
289
+ remain available to an explicitly opened inspection surface or developer
290
+ console, but are not substituted for conversational text. A visible call is
291
+ still pending until a matching `role:'tool'` message records an executed,
292
+ declined, cancelled, or not-executed result.
293
+ That tool-result content must be a nonblank string and is preserved exactly.
294
+
295
+ `streamRequest()` owns the complete terminal callback sequence. `onDataChunk`
296
+ receives each complete provider chunk before ordinary projection, while
297
+ `onChunk` receives every nonstructural content or reasoning value from every
298
+ choice in provider order. After the stream settles, `onDataResult` receives the
299
+ complete terminal completion, `onResponse` receives that same unprojected
300
+ provider response, `onToolCall` runs exactly once for each complete normalized
301
+ structural call, and `onComplete` receives the application-facing output. That
302
+ output is the ordered structural-call array when the selected result contains
303
+ tools, the complete completion object when it contains multiple choices, or
304
+ the ordinary single-result text/completion otherwise; later choices are never
305
+ discarded.
306
+ Partial structural deltas remain private until the matching terminal envelope
307
+ validates. Request observers receive
308
+ `onRequest(request,id,metadata)` and any transport metadata supplied by the
309
+ selected route is forwarded unchanged. Every async native, HTTP, provider, and
310
+ built-in callback is observed before the next callback or terminal settlement.
311
+
312
+ Native Ollama responses are adapted before the shared structural validator:
313
+ provider-native calls may omit `id` and `type` or provide object arguments, so
314
+ the adapter assigns a deterministic request-local call ID when needed, sets
315
+ `type:'function'`, and JSON-encodes complete object arguments. This adaptation
316
+ never invents the required user-facing `arguments.message`. Every response
317
+ choice is scanned; a structural call outside the selected result or a streamed
318
+ call that changes or disappears at terminal settlement is rejected with
319
+ `AI_CHAT_STREAM_TOOL_CALL_MISMATCH` before public tool-call delivery.
320
+
321
+ #### Browser speech configuration
322
+
323
+ The caller constructs a mutable authority record for one or both roles and
324
+ retains ownership of it. Start with the [complete beginner speech example](ai/browser-speech.md)
325
+ to define your DBOPFS, runtime, model, and voice selections. In this advanced
326
+ example, `applicationSpeech` is the application-supplied object containing its
327
+ `dbopfs`, `sttGraph`, and `ttsGraph`; every other variable is defined below.
328
+
329
+ ```javascript
330
+ import AI, {
331
+ AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL
332
+ } from '/arcane/modules/AI.js';
333
+
334
+ const {dbopfs, sttGraph, ttsGraph} = applicationSpeech;
335
+ const controller = new AbortController();
336
+ const signal = controller.signal;
337
+ const speechConfiguration = {
338
+ protocol: AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL,
339
+ id: 'app-speech-authority',
340
+ dbopfs,
341
+ tableName: 'browser-speech-artifacts', // optional
342
+ stt: {
343
+ providerId: 'app-whisper',
344
+ graph: sttGraph,
345
+ offline: false
346
+ },
347
+ tts: {
348
+ providerId: 'app-kokoro',
349
+ graph: ttsGraph,
350
+ offline: false,
351
+ execution: {
352
+ device: 'auto',
353
+ maxConcurrentRequests: 4
354
+ }
355
+ }
356
+ };
357
+
358
+ const ai = new AI();
359
+ const descriptor = await ai.configureBrowserSpeech(
360
+ speechConfiguration,
361
+ {signal}
362
+ );
363
+
364
+ // Configuration does not load either role. Activate only from an explicit UI.
365
+ await ai.providerRuntime.load('stt', {signal});
366
+ await ai.setSpeechMuted(false); // loads the selected TTS role, then unmutes
367
+
368
+ // Teardown unloads, unregisters, and disposes only this SDK-owned configuration.
369
+ await ai.disposeBrowserSpeech({signal});
370
+ ```
371
+
372
+ The record is a mutable plain data record with exactly
373
+ `{protocol,id,dbopfs,tableName?,stt?,tts?}` and at least one role. Each supplied
374
+ mutable STT role is exactly `{providerId,graph,security?,offline}` or
375
+ `{providerId,model,runtime,security?,offline}`. TTS accepts the corresponding
376
+ shape plus optional `execution:{device,maxConcurrentRequests}`. The graph and
377
+ direct authority forms are mutually exclusive; `providerId` and `id` are nonblank exact strings,
378
+ `graph` is the role-matching graph returned by the SDK browser
379
+ speech artifact API, and `offline` is boolean. The direct form forwards its
380
+ caller-selected model and runtime descriptors to the shared
381
+ provider. In ordinary mode it may use an empty `model.files` inventory and a
382
+ caller-selected upstream `runtime.wasmPaths`. The application
383
+ chooses every artifact, graph or direct model/runtime authority, provider ID, offline policy,
384
+ sample rate, and TTS default voice. `configureBrowserSpeech()` imports the shared
385
+ browser-speech module, creates one DBOPFS store, constructs and registers the
386
+ supplied Whisper and/or Kokoro provider/2 instances, atomically replaces only
387
+ the supplied STT/TTS routes, and returns a mutable descriptor. An initial or
388
+ later call may supply only `stt` or only `tts`; the omitted unmanaged or Core
389
+ role remains unchanged and is not claimed as SDK browser-provider ownership.
390
+ A partial replacement of an existing browser-managed record retains the same
391
+ `dbopfs` and `tableName`, carries every omitted managed browser provider and
392
+ route unchanged, and unregisters and disposes only the replaced provider after
393
+ commit. Supplying both roles remains one atomic replacement. Applications do not register those
394
+ providers, decode `Blob`/`File` data into PCM, construct WAV, select Worker URLs,
395
+ or reproduce DBOPFS cache logic.
396
+
397
+ The returned descriptor is exactly `{protocol,configurationId,stt,tts}`; an
398
+ external, unmanaged role is `null`. A managed STT descriptor is
399
+ `{role:'stt',providerId,modelId,artifactGraphId?,offline}`; TTS adds
400
+ `defaultVoice` and the normalized `execution` record. `artifactGraphId` is present only for the graph form.
401
+ `browserSpeechConfiguration` returns the exact caller-owned record when no
402
+ managed role is carried. After a partial replacement that carries another
403
+ managed role, it returns a mutable merged record with the replacement call's
404
+ `id` and the carried role's unchanged authority. It is non-null only while the
405
+ SDK still owns every represented browser provider and route;
406
+ `browserSpeechDescriptor` returns that descriptor on the same condition.
407
+ Configuration never loads a role, auto-downloads, selects an alternative
408
+ provider/model/runtime/voice, or falls back to an unmanaged or alternative
409
+ browser-speech route.
410
+
411
+ Calling `configureBrowserSpeech()` again with the same active record for every
412
+ supplied role is an idempotent descriptor read. A different call is serialized,
413
+ aborts the prior owned operation, unloads only the replaced speech roles, atomically
414
+ replaces provider ownership/routes, and suppresses stale settlement. A
415
+ single-role replacement does not reconstruct, unregister, dispose, or reroute
416
+ the omitted role or change its ready/selected state, provider identity,
417
+ operation generation, or lifecycle. STT-only replacement also preserves TTS
418
+ mute and playback state; TTS replacement invalidates current TTS speech control
419
+ before replacing that role. The caller's signal is
420
+ forwarded and detached on settlement. Cancellation proves delivery suppression,
421
+ not that provider work stopped beyond the provider's own cancellation contract.
422
+ Once SDK-owned browser speech is active, synchronous route mutation fails with
423
+ `ARCANE_AI_BROWSER_SPEECH_ASYNC_TRANSITION_REQUIRED`; use an asynchronous
424
+ transition method or await `disposeBrowserSpeech()`.
425
+
426
+ Browser speech publishes these exact event values through the AI instance's
427
+ canonical event source. Public consumers use
428
+ `arcaneEvents.subscribe(type,handler,{signal})`; `handler(occurrence)` receives
429
+ the mutable complete canonical occurrence and can correlate `source:'ai'`, `instanceId`,
430
+ and `operationId`:
431
+
432
+ | Constant member | Stable value |
433
+ | --- | --- |
434
+ | `configurationStarted` | `ai-browser-speech-configuration-started` |
435
+ | `configured` | `ai-browser-speech-configured` |
436
+ | `configurationCancelled` | `ai-browser-speech-configuration-cancelled` |
437
+ | `configurationError` | `ai-browser-speech-configuration-error` |
438
+ | `disposed` | `ai-browser-speech-disposed` |
439
+
440
+ Canonical public details are mutable and contain `configurationId`, optional
441
+ `descriptor`, optional exact `code`, and `reason`. The private source-local
442
+ view also carries the caller-owned configuration and optional
443
+ error, but `AI` does not expose that source handle and the global occurrence
444
+ does not publish those private values. Reasons are exactly `speech-configuration-added`,
445
+ `speech-configuration-replaced`, `speech-configuration-cancelled`,
446
+ `speech-configuration-disposed`, `speech-configuration-contract-mismatch`,
447
+ `speech-configuration-async-transition-required`,
448
+ `speech-operation-options-contract-mismatch`,
449
+ `speech-operation-sequence-exhausted`, `speech-module-import-rejected`,
450
+ `speech-artifact-store-construction-rejected`,
451
+ `speech-provider-construction-rejected`, `speech-provider-disposal-rejected`,
452
+ `speech-provider-route-ownership-mismatch`,
453
+ `speech-provider-unregistration-rejected`, `speech-route-commit-rejected`,
454
+ `speech-route-rollback-rejected`, and `speech-route-view-update-rejected`.
455
+ Their corresponding exact public codes are the values of
456
+ `AI_BROWSER_SPEECH_ERROR_CODES`: `ARCANE_AI_BROWSER_SPEECH_CONFIGURATION_CANCELLED`,
457
+ `ARCANE_AI_BROWSER_SPEECH_CONFIGURATION_SUPERSEDED`,
458
+ `ARCANE_AI_BROWSER_SPEECH_CONFIGURATION_CONTRACT_MISMATCH`,
459
+ `ARCANE_AI_BROWSER_SPEECH_ASYNC_TRANSITION_REQUIRED`,
460
+ `ARCANE_AI_BROWSER_SPEECH_OPERATION_OPTIONS_CONTRACT_MISMATCH`,
461
+ `ARCANE_AI_BROWSER_SPEECH_OPERATION_SEQUENCE_EXHAUSTED`,
462
+ `ARCANE_AI_BROWSER_SPEECH_MODULE_IMPORT_REJECTED`,
463
+ `ARCANE_AI_BROWSER_SPEECH_ARTIFACT_STORE_CONSTRUCTION_REJECTED`,
464
+ `ARCANE_AI_BROWSER_SPEECH_PROVIDER_CONSTRUCTION_REJECTED`,
465
+ `ARCANE_AI_BROWSER_SPEECH_PROVIDER_DISPOSAL_REJECTED`,
466
+ `ARCANE_AI_BROWSER_SPEECH_PROVIDER_ROUTE_OWNERSHIP_MISMATCH`,
467
+ `ARCANE_AI_BROWSER_SPEECH_PROVIDER_UNREGISTRATION_REJECTED`,
468
+ `ARCANE_AI_BROWSER_SPEECH_ROUTE_COMMIT_REJECTED`,
469
+ `ARCANE_AI_BROWSER_SPEECH_ROUTE_ROLLBACK_REJECTED`, and
470
+ `ARCANE_AI_BROWSER_SPEECH_ROUTE_VIEW_UPDATE_REJECTED`.
471
+
472
+ `fetchTTS()` rejects malformed request/signal/input/model/voice/format/speed
473
+ boundaries with `ARCANE_AI_TTS_REQUEST_INVALID`,
474
+ `ARCANE_AI_TTS_SIGNAL_INVALID`, `ARCANE_AI_TTS_INPUT_INVALID`,
475
+ `ARCANE_AI_TTS_MODEL_INVALID`, `ARCANE_AI_TTS_MODEL_REQUIRED`,
476
+ `ARCANE_AI_TTS_MODEL_SELECTION_MISMATCH`, `ARCANE_AI_TTS_VOICE_INVALID`,
477
+ `ARCANE_AI_TTS_VOICE_REQUIRED`, `ARCANE_AI_TTS_RESPONSE_FORMAT_INVALID`, or
478
+ `ARCANE_AI_TTS_SPEED_INVALID`; a non-playable provider result is
479
+ `ARCANE_AI_TTS_PROVIDER_AUDIO_INVALID`. `fetchSTT()` uses
480
+ `ARCANE_AI_STT_SIGNAL_INVALID` and `ARCANE_AI_STT_PROVIDER_TRANSCRIPT_INVALID`
481
+ at those exact boundaries. Owned
482
+ request abortion is `ARCANE_AI_REQUEST_ABORTED`.
483
+
484
+ Exact exports: `AI_BROWSER_SPEECH_CONFIGURATION_PROTOCOL`,
485
+ `AI_BROWSER_SPEECH_ERROR_CODES`, `AI_BROWSER_SPEECH_EVENT_TYPES`,
486
+ `AI_BROWSER_SPEECH_REASONS`, `AI_INITIALIZATION_ERROR_CODES`,
487
+ `AI_INITIALIZATION_REASONS`, `AI_READY_EVENT`, and `default`.
488
+
489
+ ### Availability and normalization
490
+
491
+ **Browser + native bridge + TWiN Cloud.** High-level chat/speech behavior is
492
+ normalized; provider diagnostics and media errors remain mixed. Transport:
493
+ AIProviderRuntime `arcane-ai-provider/2` routes, TWiN Cloud HTTPS, Arcane.ollama,
494
+ Arcane.speech, and the Android WebView bridge. [Deep protocol details](protocols.md).
495
+
496
+ ### Example
497
+
498
+ This function sends one TWiN request. `applicationRuntime` is the one
499
+ application-supplied argument: it provides a runtime `twinKey`. Call the
500
+ function from your application's send action; do not commit a key in source.
501
+
502
+ ```javascript
503
+ import AI from '/arcane/modules/AI.js';
504
+
505
+ async function sayHello(applicationRuntime) {
506
+ const ai = new AI();
507
+ ai.twinKey = applicationRuntime.twinKey;
508
+ try {
509
+ const response = await ai.fetchRequest(
510
+ {
511
+ messages: [{role: 'user', content: 'Hello!'}]
512
+ }
513
+ );
514
+ console.log(JSON.stringify(response, null, 2));
515
+ } catch (error) {
516
+ console.error(error.code, error.message);
517
+ }
518
+ }
519
+ ```
520
+
521
+ For on-device TTS, use the [browser speech quick start](ai/browser-speech.md).
522
+
523
+ ## AIPreferenceRuntime.js
524
+
525
+ ### Overview
526
+
527
+ Applies and reads non-persistent per-user AI preference overrides.
528
+
529
+ ### Public surface
530
+
531
+ `setAIPreferenceRuntimeOverride()`, `getAIPreferencesForRuntime()`.
532
+
533
+ Exact exports: `getAIPreferencesForRuntime`, `setAIPreferenceRuntimeOverride`.
534
+
535
+ ### Availability and normalization
536
+
537
+ **Cross-host.** Normalized six-slot preference state. Transport: In-process only. [Deep protocol details](protocols.md).
538
+
539
+ ### Example
540
+
541
+ ```javascript
542
+ import * as module from '/arcane/modules/AIPreferenceRuntime.js';
543
+
544
+ console.log(Object.keys(module));
545
+ ```
546
+
547
+ ## AIPreferenceTuple.js
548
+
549
+ ### Overview
550
+
551
+ Normalizes and compares the six provider/model preference slots.
552
+
553
+ ### Public surface
554
+
555
+ `AI_PREFERENCE_SLOT_KEYS`, `normalizeAIPreferenceTuple()`, `aiPreferenceTuplesEqual()`.
556
+
557
+ Exact exports: `AI_PREFERENCE_SLOT_KEYS`, `aiPreferenceTuplesEqual`, `normalizeAIPreferenceTuple`.
558
+
559
+ ### Availability and normalization
560
+
561
+ **Cross-host.** Fully normalized frozen tuple. Transport: In-process only. [Deep protocol details](protocols.md).
562
+
563
+ ### Example
564
+
565
+ ```javascript
566
+ import * as module from '/arcane/modules/AIPreferenceTuple.js';
567
+
568
+ console.log(Object.keys(module));
569
+ ```
570
+
571
+ ## AIProviderRuntime.js
572
+
573
+ ### Overview
574
+
575
+ Owns the portable provider-neutral runtime for independently selected LLM,
576
+ speech-to-text, and text-to-speech providers. The exported class documents the
577
+ shape, but application code uses the exported singleton returned by
578
+ `getAIProviderRuntime()`; direct construction fails with
579
+ `ARCANE_AI_RUNTIME_SINGLETON_REQUIRED`.
580
+
581
+ ### Public surface
582
+
583
+ Exact exports: `AI_MODEL_AUTHORITY_PROTOCOL`, `AI_PROVIDER_PROTOCOL`,
584
+ `AI_PROVIDER_RUNTIME_PROTOCOL`, `AIProviderRuntime`, `aiProviderRuntime`, and
585
+ `getAIProviderRuntime`.
586
+
587
+ The singleton exposes read-only `protocol`, `configured`, and `speechMuted`;
588
+ `register(provider)`; `unregister(role,providerId,expectedProvider=null)`;
589
+ `hasProvider(role,providerId)`; `ownsProvider(role,expectedProvider)`;
590
+ `providerIdentity(role,providerId)`; `selection(role,options={})`;
591
+ `ownsSelection(role,providerId,options={})`;
592
+ `validateConfiguration(value)`; `validateSpeechConfiguration(value)`;
593
+ `configure(value)`; `configureSpeech(value)`;
594
+ `replaceSpeechProvider(role,value)`; `replaceSpeechProviders(value)`;
595
+ `configureFromTuple(tuple)`;
596
+ `status(role=null,options={})`; `catalog(role)`;
597
+ `inspect(role,options={})`; `start(options)`; `load(role,options={})`;
598
+ `unload(role,options={})`; `dispose(role,options={})`;
599
+ `disposeAll(options={})`; `cancel(role)`; `request(role,options={})`;
600
+ `chat(payload,options={})`; `stream(payload,options={})`;
601
+ `transcribe(payload,options={})`; `synthesize(payload,options={})`; and
602
+ `setSpeechMuted(muted)`. Provider payloads must be data-only; callbacks,
603
+ accessors, symbols, and cycles are rejected at the provider boundary.
604
+
605
+ Selection options admit `localOnly=false`; inspection admits
606
+ `{localOnly=false,signal=null}`; startup admits
607
+ `{startLanguageModel=true,startMuted=true,startTranscription=false,signal=null}` (including an omitted
608
+ `options` value); load admits `{signal=null,localOnly=false}`; unload, dispose,
609
+ and dispose-all admit `{signal=null}`. Request requires the exact
610
+ `{operation,payload,localOnly,signal}` options record; the four role-specific
611
+ request helpers admit `{localOnly=false,signal=null}`. Configuration `value`
612
+ records are the closed `{llm,stt,tts}`, `{stt,tts}`, or
613
+ `{provider,routes,expectedProvider}` and
614
+ `{providers,routes,expectedProviders}` shapes described below.
615
+ `configureFromTuple()` accepts exactly six provider/model preference entries.
616
+
617
+ `register()` returns the provider's single unregister closure; caller-
618
+ registered providers remain caller-owned. The high-level
619
+ `AI.configureBrowserSpeech()` boundary is different: AI constructs, registers,
620
+ atomically replaces, unregisters, and disposes those two SDK-owned providers.
621
+ `status()` is the sticky mutable AIRuntimeState snapshot (or one role record),
622
+ while `catalog()` synchronously returns mutable provider/model entries and
623
+ never loads or downloads a model. `load()` forwards provider progress into the
624
+ sticky role record; `unload()` and `dispose()` abort owned work, await exposed
625
+ settlement, and verify provider status before publishing terminal state.
626
+
627
+ `status('tts', {execution:true})` explicitly reads the selected provider and
628
+ adds its optional `execution` snapshot to a copy of the role record.
629
+ `status(null, {execution:true})` provides the equivalent projection under
630
+ `roles.llm`, `roles.stt`, and `roles.tts`. Providers that do not supply execution
631
+ omit that field. No provider load or sticky-state event is triggered; default
632
+ `status()` keeps its existing identity and behavior. A provider inspection
633
+ error propagates. Kokoro's execution contains `requestedDevice`,
634
+ `selectedDevice` (`null` while unloaded), `maxConcurrentRequests`, and
635
+ `activeRequestCount`; these describe provider execution, not physical GPU
636
+ kernel overlap.
637
+
638
+ `validateSpeechConfiguration(value)` returns one mutable two-role selection
639
+ record without committing it, where `value` is the closed `{stt,tts}` record.
640
+ `configureSpeech(value)` accepts the same record, requires both speech roles to
641
+ own no ready/load/unload/dispose or request work, commits only STT/TTS, restores
642
+ muted speech selection, and returns the mutable selection record. The current LLM
643
+ routes, selection, readiness, operation generation, and sticky state remain
644
+ unchanged. A malformed top-level, route, or selection record preserves the
645
+ current error code
646
+ `ARCANE_AI_PROVIDER_RUNTIME_INVALID` and adds exact reason
647
+ `speech-configuration-contract-mismatch`; runtime-disposed, reentrant,
648
+ role-busy, and provider-locality failures retain their existing exact codes.
649
+
650
+ `replaceSpeechProvider(role,value)` accepts only `stt` or `tts` and atomically
651
+ replaces exactly that unloaded role using the closed
652
+ `{provider,routes,expectedProvider}` record. A null `provider` with empty routes
653
+ removes that role and requires its exact non-null expected provider. The method preserves the omitted role's
654
+ provider registration, routes, selection, readiness, generation, sticky state,
655
+ owned lifecycle work, and TTS mute state. `replaceSpeechProviders(value)` keeps
656
+ the existing atomic two-role boundary for a coordinated STT/TTS replacement.
657
+ Either replacement may replace a selected-but-unregistered pending speech
658
+ placeholder whose saved locality is still `null`. Every existing pending route
659
+ must agree with that saved placeholder; the replacement provider and routes
660
+ then define the actual selected provider and model. Registration and route
661
+ publication remain one commit without loading either provider; an already
662
+ registered, local-only, busy, or partially divergent selection rejects without
663
+ changing either role.
664
+
665
+ `start(options)` waits for prior speech-state and role unload work, applies the
666
+ requested initial mute state, and returns the `startAIRuntime()` control handle
667
+ `{barrier,settled,cancel}`. With `startLanguageModel:false`, startup does not
668
+ request the selected LLM and its barrier may therefore resolve with `chatReady:false` and
669
+ `roles.llm.requested:false` while the explicit activation UI remains available.
670
+ Startup does not request selected STT unless the caller explicitly opts in; it
671
+ does not force an independently active STT role back to unloaded. The barrier
672
+ and settled promises describe only requested provider-startup work;
673
+ cancellation remains cooperative through the supplied signal and returned
674
+ control.
675
+
676
+ Interactive requests enter a FIFO lane per role. Providers omit
677
+ `maxConcurrentRequests` to retain capacity 1. A TTS provider may declare a
678
+ positive safe-integer capacity; the runtime starts that many oldest requests
679
+ and retains later work in FIFO order. LLM and STT remain capacity 1. A newer
680
+ request does not abort or discard earlier work. A caller `AbortSignal` cancels
681
+ only its own queued or active request, while `cancel(role)` targets the oldest
682
+ active request. Explicit unload and dispose reject queued work, cancel every
683
+ active request, await settlement, and then clean the provider. Load and
684
+ configuration remain unavailable while that role owns active or queued request
685
+ work. Promise settlement proves only that the provider's exposed request promise
686
+ completed; provider-specific cancellation acknowledgement remains the selected
687
+ provider's boundary.
688
+
689
+ Direct LLM `request()`, `chat()`, and `stream()` use the same message history,
690
+ tool-declaration, emitted-call, all-choice, and ordered parallel-call contracts
691
+ as the high-level AI API module, including one nonblank matching result for
692
+ every pending tool-call ID. A complete text-only terminal string remains
693
+ compatible; structured terminals must use exactly one message or choices
694
+ envelope. An ordinary stream iterator exposes complete nonstructural content
695
+ and reasoning projections from every choice in FIFO order; provider-native
696
+ tool deltas remain private until the complete terminal result validates. The
697
+ runtime drains private provider streams even when `result` is awaited before
698
+ iteration, buffers projected chunks for later consumption, and retains the
699
+ complete validated terminal provider response on `result`. A terminal-only
700
+ tool call is valid; any tool call observed during streaming must retain the
701
+ same choice, ID, type, function name, argument string, and extension fields at
702
+ terminal settlement. Consumer `return()` starts observed cancellation
703
+ immediately and returns promptly; provider cleanup and any failure remain
704
+ observable through the terminal result or complete developer-console
705
+ diagnostics rather than blocking iterator return.
706
+
707
+ ### Availability and normalization
708
+
709
+ **Cross-host runtime with provider-specific execution.** The SDK source ships
710
+ the browser-WASM LLM and browser Whisper/Kokoro adapters and supplies the
711
+ narrow AI.js TWiN Cloud LLM, Ollama, and local Core-speech adapters; other
712
+ native, Core, or cloud adapters may be supplied externally only when they implement the same
713
+ `arcane-ai-provider/2` boundary. A
714
+ provider must prove a matching `arcane-ai-model-authority/1` inspection before load.
715
+ `localOnly` routing fails closed; it never selects a cloud or non-local route as
716
+ a fallback. A missing or mismatched explicit local-only route rejects load or
717
+ request selection with `AI_LOCAL_MODEL_REQUIRED`. Role lifecycle and stream
718
+ cleanup are normalized, while the
719
+ selected provider retains its own capability, permission, download, and model
720
+ requirements. [Deep protocol details](protocols.md#portable-ai-provider-runtime).
721
+
722
+ ### Example
723
+
724
+ ```javascript
725
+ import {getAIProviderRuntime} from '/arcane/modules/AIProviderRuntime.js';
726
+
727
+ const runtime = getAIProviderRuntime();
728
+ console.log(runtime.protocol, runtime.status());
729
+ ```
730
+
731
+ ## AIResponseLength.js
732
+
733
+ ### Overview
734
+
735
+ Normalizes current low/medium/high response-preference selectors while
736
+ preserving complete prompts unchanged.
737
+
738
+ ### Public surface
739
+
740
+ Response-preference constants plus `normalizeAIResponseLength()`,
741
+ `aiResponseLengthInstruction()`, and `applyAIResponseLength()`. Every option is
742
+ labeled `Complete`, the instruction helper returns an empty string, and the
743
+ application helper returns its complete `systemPrompt` unchanged.
744
+
745
+ Exact exports: `AI_RESPONSE_LENGTH_DEFAULT`, `AI_RESPONSE_LENGTH_OPTIONS`, `aiResponseLengthInstruction`, `applyAIResponseLength`, `normalizeAIResponseLength`.
746
+
747
+ ### Availability and normalization
748
+
749
+ **Cross-host.** Current selector normalization with no prompt transformation.
750
+ Transport: In-process only. [Deep protocol details](protocols.md).
751
+
752
+ ### Example
753
+
754
+ ```javascript
755
+ import * as module from '/arcane/modules/AIResponseLength.js';
756
+
757
+ console.log(Object.keys(module));
758
+ ```
759
+
760
+ ## AIResponseURLPolicy.js
761
+
762
+ ### Overview
763
+
764
+ Extracts and audits links from AI Markdown, rendered HTML, CSS, srcset, bare URLs, and email text.
765
+
766
+ ### Public surface
767
+
768
+ `auditAIResponseLinks()`, `extractAIResponseLinks()`, `normalizeAIResponseLink()`, `decodeHTMLCharacterReferences()`.
769
+
770
+ Exact exports: `auditAIResponseLinks`, `decodeHTMLCharacterReferences`, `extractAIResponseLinks`, `normalizeAIResponseLink`.
771
+
772
+ ### Availability and normalization
773
+
774
+ **Cross-host.** Normalized frozen allowlist audit. Transport: In-process; bundled Marked parser. [Deep protocol details](protocols.md).
775
+
776
+ ### Example
777
+
778
+ ```javascript
779
+ import * as module from '/arcane/modules/AIResponseURLPolicy.js';
780
+
781
+ console.log(Object.keys(module));
782
+ ```
783
+
784
+ ## AIRuntimeState.js
785
+
786
+ ### Overview
787
+
788
+ Publishes one sticky mutable state tree for `llm`, `stt`, and `tts`, transient
789
+ load/unload/dispose intents, and a startup-settlement report. It makes lifecycle
790
+ observable without exposing provider transports in application code.
791
+
792
+ ### Public surface
793
+
794
+ Exact exports: `AI_RUNTIME_INTENT_EVENT`, `AI_RUNTIME_PROTOCOL`,
795
+ `AI_RUNTIME_ROLES`, `AI_RUNTIME_STARTUP_EVENT`, `AI_RUNTIME_STATES`,
796
+ `AI_RUNTIME_STATE_EVENT`, `getAIRuntimeState`,
797
+ `publishAIRuntimeRoleState`, `publishAIRuntimeRolesState`,
798
+ `requestAIRuntimeIntent`, `startAIRuntime`, `subscribeAIRuntimeIntents`, and
799
+ `subscribeAIRuntimeState`.
800
+
801
+ Each role record is exactly `{role,state,providerId,modelId,localOnly,loaded,
802
+ busy,operationId,progress,error}`.
803
+ `subscribeAIRuntimeState(listener,{signal=null,emitCurrent=true})` installs its
804
+ subscription and synchronously replays the current mutable snapshot by default;
805
+ `subscribeAIRuntimeIntents(listener,{signal=null})` is future-only. Both return
806
+ one idempotent unsubscribe/dispose closure.
807
+ `startAIRuntime({startLanguageModel=true,startMuted=true,startTranscription=false,signal})` returns
808
+ `{barrier,settled,cancel}`: `barrier` settles for requested text-chat startup,
809
+ while `settled` covers every requested role. With `startLanguageModel:false`, a
810
+ selected LLM remains unloaded for explicit user activation, so the barrier can settle honestly with
811
+ `chatReady:false` and `roles.llm.requested:false`. Muted startup does not request
812
+ TTS, and STT startup is opt-in so selection and state observation do not begin a
813
+ transcription-model load.
814
+
815
+ ### Availability and normalization
816
+
817
+ **Cross-host state contract.** States are `unavailable`, `unloaded`, `loading`,
818
+ `ready`, `unloading`, `error`, and `disposed`. Revisions increase monotonically.
819
+ The events `arcane-ai-runtime-state`, `arcane-ai-runtime-intent`, and
820
+ `arcane-ai-runtime-startup-settled` normalize observation only: receiving one
821
+ does not grant a native capability, prove browser support, or load a provider.
822
+ `arcane-ai-runtime-startup-settled` reports the LLM/text-chat `barrier`.
823
+ Await the returned `handle.settled` promise for every role requested by that
824
+ startup; the all-role settlement has no separate public event.
825
+ Intent records are exactly `{role,action,reason}` where roles are `llm`, `stt`,
826
+ or `tts`; actions are `load`, `unload`, or `dispose`; and reasons are `startup`,
827
+ `user`, or `teardown`. Invalid closed records fail with the stable prefix
828
+ `ARCANE_AI_RUNTIME_STATE_INVALID`; startup cancellation is an `AbortError` with
829
+ code `ARCANE_AI_REQUEST_ABORTED`.
830
+
831
+ ### Example
832
+
833
+ ```javascript
834
+ import {
835
+ getAIRuntimeState,
836
+ subscribeAIRuntimeState
837
+ } from '/arcane/modules/AIRuntimeState.js';
838
+
839
+ const unsubscribe = subscribeAIRuntimeState(snapshot => {
840
+ console.log(snapshot.roles.llm.state);
841
+ });
842
+ console.log(getAIRuntimeState().protocol);
843
+ unsubscribe();
844
+ ```
845
+
846
+ ## AnsiText.js
847
+
848
+ ### Overview
849
+
850
+ Parses terminal ANSI sequences into display spans or strips them to plain text.
851
+
852
+ ### Public surface
853
+
854
+ `parseAnsi()`, `stripAnsi()`.
855
+
856
+ Exact exports: `parseAnsi`, `stripAnsi`.
857
+
858
+ ### Availability and normalization
859
+
860
+ **Cross-host.** Normalized text/span output. Transport: In-process only. [Deep protocol details](protocols.md).
861
+
862
+ ### Example
863
+
864
+ ```javascript
865
+ import * as module from '/arcane/modules/AnsiText.js';
866
+
867
+ console.log(Object.keys(module));
868
+ ```
869
+
870
+ ## ApiModelDatabase.js
871
+
872
+ ### Overview
873
+
874
+ Fetches an injectable HTTP JSON model with parser, cache, redacted public endpoint records, and request lifecycle events.
875
+
876
+ ### Public surface
877
+
878
+ default `ApiModelDatabase`; `setEndpoint()`, `fetch()`, `cached()`; emits `api-model-request`, `api-model-success`, and `api-model-error`.
879
+
880
+ Exact exports: `API_MODEL_ERRORS`, `API_MODEL_EVENTS`, `appendParameters`,
881
+ `default`, `publicEndpoint`.
882
+
883
+ ### Availability and normalization
884
+
885
+ **Browser / native WebView / server with fetch.** Request records are normalized; fetch/provider failures remain mixed. Transport: HTTP(S) fetch. [Deep protocol details](protocols.md).
886
+
887
+ ### Example
888
+
889
+ ```javascript
890
+ import * as module from '/arcane/modules/ApiModelDatabase.js';
891
+
892
+ console.log(Object.keys(module));
893
+ ```
894
+
895
+ ## AppDataScope.js
896
+
897
+ ### Overview
898
+
899
+ Reconciles declared and native application identity and scopes OPFS/localStorage ownership fail-closed.
900
+
901
+ ### Public surface
902
+
903
+ Identity constants and `canonicalApplicationId()`, `resolveApplicationId()`, `resolveApplicationLocalStorageKey()`, `openApplicationDataDirectory()`.
904
+
905
+ Exact exports: `APPLICATION_ID_MAX_LENGTH`, `APPLICATION_ID_PATTERN`, `APP_DATA_DIRECTORY`, `APP_LOCAL_STORAGE_PREFIX`, `canonicalApplicationId`, `declaredApplicationId`, `openApplicationDataDirectory`, `resolveApplicationId`, `resolveApplicationLocalStorageKey`, `resolveBrowserApplicationId`.
906
+
907
+ ### Availability and normalization
908
+
909
+ **Browser / native WebView hybrid.** Strict normalized identifiers and coded mismatch failures. Transport: Arcane.app.current, DOM declaration, OPFS. [Deep protocol details](protocols.md).
910
+
911
+ ### Example
912
+
913
+ ```javascript
914
+ import * as module from '/arcane/modules/AppDataScope.js';
915
+
916
+ console.log(Object.keys(module));
917
+ ```
918
+
919
+ ## AppearancePreferences.js
920
+
921
+ ### Overview
922
+
923
+ Defines, stores, and applies color scheme, density, reduced motion, and large-text preferences.
924
+
925
+ ### Public surface
926
+
927
+ `appearancePreferenceSchema`, `createAppearancePreferenceStore()`, `applyAppearancePreferences()`, `loadAndApplyAppearancePreferences()`.
928
+
929
+ Exact exports: `appearancePreferenceSchema`, `applyAppearancePreferences`, `createAppearancePreferenceStore`, `loadAndApplyAppearancePreferences`.
930
+
931
+ ### Availability and normalization
932
+
933
+ **Browser / native WebView hybrid.** Normalized values; storage/host failures remain mixed. Transport: PreferenceStore, DOM, optional Arcane preferences. [Deep protocol details](protocols.md).
934
+
935
+ ### Example
936
+
937
+ ```javascript
938
+ import * as module from '/arcane/modules/AppearancePreferences.js';
939
+
940
+ console.log(Object.keys(module));
941
+ ```
942
+
943
+ ## ArcaneCommunicationBridge.js
944
+
945
+ ### Overview
946
+
947
+ Maps provider HTTP threads/messages/connect/disconnect endpoints to normalized communication entities.
948
+
949
+ ### Public surface
950
+
951
+ default `ArcaneCommunicationBridge`; `request()`, `listThreads()`, `getMessages()`, `send()`, `connect()`, `disconnect()`.
952
+
953
+ Exact exports: `default`.
954
+
955
+ ### Availability and normalization
956
+
957
+ **Browser / native WebView / server with fetch.** Entity results are normalized; provider/transport failures remain mixed. Transport: JSON HTTP(S), default loopback 127.0.0.1:8020. [Deep protocol details](protocols.md).
958
+
959
+ ### Example
960
+
961
+ ```javascript
962
+ import * as module from '/arcane/modules/ArcaneCommunicationBridge.js';
963
+
964
+ console.log(Object.keys(module));
965
+ ```
966
+
967
+ ## ArcaneNavigationPolicy.js
968
+
969
+ ### Overview
970
+
971
+ Creates an HTTP(S) navigation guard whose optional domain and CIDR hardening runs only when the caller explicitly selects `secure: true`. The ordinary default returns a complete allow decision with a warning and does not load policy.
972
+
973
+ ### Public surface
974
+
975
+ `createArcaneNavigationGuard({ secure })`.
976
+
977
+ Exact exports: `createArcaneNavigationGuard`.
978
+
979
+ ### Availability and normalization
980
+
981
+ **Cross-host.** Complete mutable allow/block decision. Ordinary mode warns and
982
+ continues; explicitly selected `secure: true` loads the Arcane network-policy
983
+ document and fails closed when that selected policy cannot be evaluated. [Deep protocol details](protocols.md).
984
+
985
+ ### Example
986
+
987
+ ```javascript
988
+ import {createArcaneNavigationGuard} from '/arcane/modules/ArcaneNavigationPolicy.js';
989
+
990
+ const guard=createArcaneNavigationGuard();
991
+ console.log(await guard('https://example.com/docs',{intent:'external'}));
992
+ ```
993
+
994
+ ## ArcaneNetworkPolicy.js
995
+
996
+ ### Overview
997
+
998
+ Validates the Arcane domain/network deny policy and matches domain, IPv4/IPv6 CIDR, protocol, and port rules.
999
+
1000
+ ### Public surface
1001
+
1002
+ Policy constants plus validate/load/cache/match helpers.
1003
+
1004
+ Exact exports: `ARCANE_NETWORK_POLICY_SCHEMA_VERSION`, `ARCANE_NETWORK_POLICY_URL`, `canonicalNetworkHostname`, `emptyArcaneNetworkPolicy`, `findDeniedDomainRule`, `findDeniedNetworkRule`, `invalidateArcaneNetworkPolicyCache`, `loadArcaneNetworkPolicy`, `validateArcaneNetworkPolicy`.
1005
+
1006
+ ### Availability and normalization
1007
+
1008
+ **Cross-host.** Strict coded normalization. Transport: Same-origin policy fetch. [Deep protocol details](protocols.md).
1009
+
1010
+ ### Example
1011
+
1012
+ ```javascript
1013
+ import * as module from '/arcane/modules/ArcaneNetworkPolicy.js';
1014
+
1015
+ console.log(Object.keys(module));
1016
+ ```
1017
+
1018
+ ## AsyncBoundary.js
1019
+
1020
+ ### Overview
1021
+
1022
+ Runs one asynchronous operation with timeout, abort, result validation, and stable boundary errors.
1023
+
1024
+ ### Public surface
1025
+
1026
+ `AsyncBoundaryTimeoutError`, `AsyncBoundaryAbortError`, defaults, `runAsyncBoundary()`, and default alias.
1027
+
1028
+ Exact exports: `AsyncBoundaryAbortError`, `AsyncBoundaryTimeoutError`, `asyncBoundaryDefaults`, `default`, `runAsyncBoundary`.
1029
+
1030
+ ### Availability and normalization
1031
+
1032
+ **Cross-host.** Fully normalized timeout/abort errors. Transport: AbortController and timers. [Deep protocol details](protocols.md).
1033
+
1034
+ ### Example
1035
+
1036
+ ```javascript
1037
+ import * as module from '/arcane/modules/AsyncBoundary.js';
1038
+
1039
+ console.log(Object.keys(module));
1040
+ ```
1041
+
1042
+ ## BrowserTestSuite.js
1043
+
1044
+ ### Overview
1045
+
1046
+ Runs a complete sequential browser test list with explicit cancellation and full-detail lifecycle events.
1047
+
1048
+ ### Public surface
1049
+
1050
+ default `BrowserTestSuite`; `list()`, `run()`, `dispose()`/`destroy()`; emits
1051
+ complete suite/test start/result/complete events. Caller metadata does not limit
1052
+ execution or create a timer. Caller `AbortSignal` or disposal is the only
1053
+ suite-owned stop.
1054
+
1055
+ Exact exports: `BROWSER_TEST_SUITE_ERROR_CODES`,
1056
+ `BROWSER_TEST_SUITE_EVENT_TYPES`, `BROWSER_TEST_SUITE_REASONS`,
1057
+ `assertionError`, `default`, `skipError`.
1058
+
1059
+ ### Availability and normalization
1060
+
1061
+ **Browser / standard Web APIs.** Mutable full-detail results and events with
1062
+ normalized malformed-result and skip/assertion errors. Transport: EventTarget
1063
+ and explicit AbortSignal cancellation. [Deep protocol details](protocols.md).
1064
+
1065
+ ### Example
1066
+
1067
+ ```javascript
1068
+ import * as module from '/arcane/modules/BrowserTestSuite.js';
1069
+
1070
+ console.log(Object.keys(module));
1071
+ ```
1072
+
1073
+ ## CalculatorEngine.js
1074
+
1075
+ ### Overview
1076
+
1077
+ Evaluates complete arithmetic expressions, powers, constants, and common functions without `eval`.
1078
+
1079
+ ### Public surface
1080
+
1081
+ `new CalculatorEngine()` exposes synchronous
1082
+ `calculate(expression): Calculation` and idempotent
1083
+ `dispose(): boolean` / `destroy(): boolean`. `evaluateExpression(input): number`
1084
+ remains the parser-only helper. `CALCULATOR_ENGINE_ERROR_CODES` is one mutable
1085
+ record containing the stable `disposed`, `input`, `syntax`, `domain`, and
1086
+ `evaluation` codes.
1087
+
1088
+ Exact exports: `CALCULATOR_ENGINE_ERROR_CODES`, `default`,
1089
+ `evaluateExpression`.
1090
+
1091
+ ### Availability and normalization
1092
+
1093
+ **Cross-host.** Each engine owns one `calculator-engine` source on the realm's
1094
+ branded `globalThis.arcaneEvents`. `calculator-result` publishes mutable public
1095
+ detail `{result}`. `calculator-error` publishes mutable public detail
1096
+ `{code,error,expression}` while `calculate()` rethrows that same complete
1097
+ `Error`. Both occurrences carry one
1098
+ source-instance `operationId`. Canonical listener callbacks are synchronous
1099
+ observations; their failures are reported by the central event authority and do
1100
+ not rewrite calculation settlement. Disposal rejects later calculations with
1101
+ `ARCANE_CALCULATOR_ENGINE_DISPOSED`. Invalid expression input, syntax, numeric
1102
+ domain, and unexpected evaluation boundaries use
1103
+ `ARCANE_CALCULATOR_EXPRESSION_INPUT_INVALID`,
1104
+ `ARCANE_CALCULATOR_EXPRESSION_SYNTAX_INVALID`,
1105
+ `ARCANE_CALCULATOR_EXPRESSION_DOMAIN_INVALID`, and
1106
+ `ARCANE_CALCULATOR_EXPRESSION_EVALUATION_FAILED`. Transport: in-process only.
1107
+ [Deep protocol details](protocols.md).
1108
+
1109
+ ### Example
1110
+
1111
+ ```javascript
1112
+ import * as module from '/arcane/modules/CalculatorEngine.js';
1113
+
1114
+ console.log(Object.keys(module));
1115
+ ```
1116
+
1117
+ ## ChartLibrary.js
1118
+
1119
+ ### Overview
1120
+
1121
+ Loads the bundled uPlot classic script once and returns its global constructor.
1122
+
1123
+ ### Public surface
1124
+
1125
+ default `loadChartLibrary()`.
1126
+
1127
+ Exact exports: `default`.
1128
+
1129
+ ### Availability and normalization
1130
+
1131
+ **Browser / native WebView.** Load state/errors normalized; uPlot result is vendor-native. Transport: DOM script injection. [Deep protocol details](protocols.md).
1132
+
1133
+ ### Example
1134
+
1135
+ ```javascript
1136
+ import * as module from '/arcane/modules/ChartLibrary.js';
1137
+
1138
+ console.log(Object.keys(module));
1139
+ ```
1140
+
1141
+ ## ChatRecords.js
1142
+
1143
+ ### Overview
1144
+
1145
+ Detects whether a chat record contains a user entry or durable conversation
1146
+ entry, and projects retained chat state into recurring provider context. That
1147
+ projection preserves an unresolved structural-call tail for its one active
1148
+ continuation, then replaces the settled protocol with complete ordinary visible
1149
+ messages.
1150
+
1151
+ ### Public surface
1152
+
1153
+ `hasUserEntry()`, `hasConversationEntry()`, and
1154
+ `recurringChatMessages(chat,{settleCompleteToolTail=false}={})`. The optional
1155
+ settlement flag is for restoring a configured session that has no active
1156
+ provider continuation; unresolved calls remain raw regardless.
1157
+
1158
+ Exact exports: `hasConversationEntry`, `hasUserEntry`,
1159
+ `recurringChatMessages`.
1160
+
1161
+ ### Availability and normalization
1162
+
1163
+ **Cross-host.** Boolean conversation-entry results and recurring provider
1164
+ context are normalized. Transport: In-process only. [Deep protocol details](protocols.md).
1165
+
1166
+ ### Example
1167
+
1168
+ ```javascript
1169
+ import * as module from '/arcane/modules/ChatRecords.js';
1170
+
1171
+ console.log(Object.keys(module));
1172
+ ```
1173
+
1174
+ ## CommunicationAppController.js
1175
+
1176
+ ### Overview
1177
+
1178
+ Binds shared inbox, conversation, settings, theme, and provider workflows into one UI controller.
1179
+
1180
+ ### Public surface
1181
+
1182
+ default controller with `start()`, `bind()`, `configure()`, `refresh()`, `select()`, `send()`, and settings actions.
1183
+
1184
+ Exact exports: `COMMUNICATION_APP_CONTROLLER_ERROR_CODES`, `default`.
1185
+
1186
+ ### Availability and normalization
1187
+
1188
+ **Browser / native WebView hybrid.** Controller state normalized; provider/DOM failures mixed. Transport: DOM plus communication providers. [Deep protocol details](protocols.md).
1189
+
1190
+ ### Example
1191
+
1192
+ ```javascript
1193
+ import * as module from '/arcane/modules/CommunicationAppController.js';
1194
+
1195
+ console.log(Object.keys(module));
1196
+ ```
1197
+
1198
+ ## CommunicationHub.js
1199
+
1200
+ ### Overview
1201
+
1202
+ Fans out provider refresh/send operations and aggregates normalized threads/messages.
1203
+
1204
+ ### Public surface
1205
+
1206
+ default `CommunicationHub`; provider enablement, `refresh()`, `messages()`, and `send()`.
1207
+
1208
+ Exact exports: `COMMUNICATION_HUB_ERROR_CODES`, `COMMUNICATION_HUB_EVENTS`,
1209
+ `COMMUNICATION_HUB_REFRESH_REASONS`, `COMMUNICATION_HUB_REFRESH_STATES`, and
1210
+ `default`.
1211
+
1212
+ ### Availability and normalization
1213
+
1214
+ **Cross-host with injected providers.** Normalized aggregates; refresh contains per-provider failures. Transport: Injected provider contract. [Deep protocol details](protocols.md).
1215
+
1216
+ ### Example
1217
+
1218
+ ```javascript
1219
+ import * as module from '/arcane/modules/CommunicationHub.js';
1220
+
1221
+ console.log(Object.keys(module));
1222
+ ```
1223
+
1224
+ ## CommunicationPreferences.js
1225
+
1226
+ ### Overview
1227
+
1228
+ Stores app-scoped, non-secret communication provider preferences.
1229
+
1230
+ ### Public surface
1231
+
1232
+ default `CommunicationPreferences`; `load()`, `save()`.
1233
+
1234
+ Exact exports: `default`.
1235
+
1236
+ ### Availability and normalization
1237
+
1238
+ **Browser / native WebView hybrid.** Normalized preference record; storage failures mixed. Transport: Arcane.preferences or localStorage. [Deep protocol details](protocols.md).
1239
+
1240
+ ### Example
1241
+
1242
+ ```javascript
1243
+ import * as module from '/arcane/modules/CommunicationPreferences.js';
1244
+
1245
+ console.log(Object.keys(module));
1246
+ ```
1247
+
1248
+ ## CommunicationProviderRegistry.js
1249
+
1250
+ ### Overview
1251
+
1252
+ Registers and queries validated provider definitions, channels, and required methods.
1253
+
1254
+ ### Public surface
1255
+
1256
+ default registry with `register()`, `get()`, `has()`, `list()`.
1257
+
1258
+ Exact exports: `default`.
1259
+
1260
+ ### Availability and normalization
1261
+
1262
+ **Cross-host.** Strict normalized registry. Transport: In-process only. [Deep protocol details](protocols.md).
1263
+
1264
+ ### Example
1265
+
1266
+ ```javascript
1267
+ import * as module from '/arcane/modules/CommunicationProviderRegistry.js';
1268
+
1269
+ console.log(Object.keys(module));
1270
+ ```
1271
+
1272
+ ## ComponentContracts.js
1273
+
1274
+ ### Overview
1275
+
1276
+ Owns normalized configuration/value contracts and shared explicit STT activation
1277
+ behavior for chart, dashboard, Markdown, and voice components.
1278
+
1279
+ ### Public surface
1280
+
1281
+ Constant sets plus normalization, formatting, and explicit STT activation
1282
+ helpers. `createSTTActivationController({host,button,onChange,EventClass=CustomEvent})`
1283
+ consumes only normalized
1284
+ [`AIRuntimeState`](#airuntimestatejs) `stt` role records. Its mutable controller
1285
+ exposes `action`, `error`, `label`, `pending`, `selected`, `status`, `title`, and
1286
+ `visible` getters plus `request(action)`, `synchronize(role)`, and `destroy()`.
1287
+ `host` supplies `dispatchEvent(event)` and `requestSTTActivation(intent)`;
1288
+ `button` supplies `addEventListener()` and `removeEventListener()`; and
1289
+ `onChange()` is called whenever presentation should be rendered again. Browser
1290
+ callers use the default `CustomEvent`; non-DOM callers must inject a compatible
1291
+ `EventClass` constructor.
1292
+
1293
+ `request('load'|'unload')` emits the cancelable
1294
+ `speech-stt-activation-request` event with mutable `{intent,state}` before it
1295
+ invokes `host.requestSTTActivation(intent)`. Callback failure emits
1296
+ `speech-stt-activation-error` with mutable `{request,error,message}`. Syncing
1297
+ sticky state only changes the controller's observation and presentation; it
1298
+ never emits a lifecycle intent, chooses a provider, or starts a download.
1299
+ `destroy()` removes its button listener and suppresses late callback effects.
1300
+
1301
+ Exact exports: `CHART_LABELS`, `DASHBOARD_LABELS`, `MARKDOWN_FORMATS`,
1302
+ `MARKDOWN_LABELS`, `STT_ACTIVATION_ERROR_CODES`,
1303
+ `STT_ACTIVATION_EVENT_TYPES`, `STT_ACTIVATION_REASONS`, `VOICE_LABELS`,
1304
+ `VOICE_MESSAGES`, `appendTranscription`, `applyMarkdownFormat`,
1305
+ `createSTTActivationController`, `effectiveDashboardVisibility`,
1306
+ `formatAIRuntimeProgress`,
1307
+ `normalizeChartOptions`, `normalizeChartRows`, `normalizeDashboardDefinitions`,
1308
+ `normalizeDashboardOptions`, `normalizeDashboardVisibility`,
1309
+ `normalizeMarkdownFormats`, `normalizeMarkdownOptions`, and
1310
+ `normalizeVoiceOptions`.
1311
+
1312
+ ### Availability and normalization
1313
+
1314
+ **Cross-host with an injected event constructor outside DOM hosts.** Fully
1315
+ normalized labels, rows, definitions, visibility, formats, editor and voice
1316
+ options, capability-neutral STT activation intent and presentation state, and
1317
+ complete informational provider progress whenever a finite measure is present.
1318
+ Fractional and over-total measures remain visible rather than being replaced by
1319
+ their phase label.
1320
+ Provider authority and lifecycle execution remain with the configured runtime
1321
+ owner. Transport: In-process only. [Deep protocol details](protocols.md).
1322
+
1323
+ ### Example
1324
+
1325
+ ```javascript
1326
+ import * as module from '/arcane/modules/ComponentContracts.js';
1327
+
1328
+ console.log(Object.keys(module));
1329
+ ```
1330
+
1331
+ ## ConfiguredAIChatSession.js
1332
+
1333
+ ### Overview
1334
+
1335
+ Owns complete ordinary visible recurring AI turns, one active structural
1336
+ continuation, context construction, provider-response preservation, and atomic
1337
+ history commit.
1338
+
1339
+ ### Public surface
1340
+
1341
+ Default `ConfiguredAIChatSession`; named
1342
+ `normalizeStructuralToolCall(call,label)`; instance methods `history()`,
1343
+ `clear()`, `prepareOpening()`, `prepare()`, and `send()`.
1344
+
1345
+ `new ConfiguredAIChatSession(options={})` uses `chat`, `contextBuilder`,
1346
+ `initialMessages`, `request`, `responseLength`, and `systemPrompt`.
1347
+ `responseLength` is caller preference metadata and does not alter or limit content.
1348
+ `initialMessages` is an array of complete `user`, `assistant`, or `tool`
1349
+ messages. It excludes `system`, accepts one unresolved structural assistant
1350
+ tool-call tail, and requires its tracked result before another user turn or
1351
+ tool-call sequence; `systemPrompt` owns the separate system message. Settled
1352
+ structural protocol is projected immediately into ordinary visible recurring
1353
+ messages.
1354
+
1355
+ Each assistant structural tool call is one complete function call with an exact
1356
+ nonempty string `id`, `type:'function'`, a nonempty `function.name`, and
1357
+ `function.arguments` as a JSON string encoding an object containing a nonempty
1358
+ user-facing `message`. One assistant message may contain an ordered array of
1359
+ calls with unique IDs; every call and every extension field is preserved in the
1360
+ returned response and its active matching continuation, but not settled
1361
+ recurring history.
1362
+ Validation does not trim or reserialize an accepted ID, name, or argument
1363
+ string. A pending call set is settled atomically only by one request batch that
1364
+ contains exactly one `role:'tool'` message with nonempty content for every
1365
+ pending ID. A user turn, duplicate or mismatched result, partial result batch,
1366
+ or overlapping structural call is rejected until the complete set settles.
1367
+
1368
+ `prepare(input,{request,signal})` performs the complete request but does not
1369
+ commit history immediately. It returns mutable `{response,commit,rollback}`;
1370
+ exactly one terminal settlement is permitted. Plain-object per-turn `request`
1371
+ options merge over constructor defaults, while session-owned `messages` and
1372
+ `signal` are applied last. `messages`, `signal`, `stream`, `onChunk`,
1373
+ `onToolCall`, and `onResponse` cannot be supplied through either request layer.
1374
+ A matching tool result may include a complete public `message`, `name`, and
1375
+ `status`; those fields are excluded from the raw provider continuation. The
1376
+ public `message` becomes ordinary visible recurring content after settlement,
1377
+ while `name` and `status` remain optional durable transcript metadata. Raw
1378
+ call/result protocol is retained only until that one continuation commits.
1379
+ `send()` is the convenience path that prepares and then commits the turn.
1380
+
1381
+ `prepareOpening(input,{request,signal})` is the dedicated transaction for an
1382
+ automatic model-authored opening. It sends one application-authored user
1383
+ bootstrap only when retained history contains no conversation turn, requires a
1384
+ complete nonblank assistant response without structural calls, and prepares
1385
+ only that assistant content for commit. The bootstrap never enters history.
1386
+ An existing retained turn rejects as `AI_CHAT_OPENING_EXISTS`; an empty or
1387
+ structural response rejects as `AI_CHAT_INVALID_OPENING_RESPONSE`.
1388
+
1389
+ An optional async `contextBuilder({input,history,signal})` receives a mutable,
1390
+ complete request snapshot and the same cancellation signal. Its complete
1391
+ returned context applies only to the current request and is never committed to
1392
+ history.
1393
+
1394
+ An injected `chat(request)` may return the prior normalized session result or a
1395
+ non-stream OpenAI-compatible response whose first choice supplies the assistant
1396
+ message. The prior form preserves its explicit `done` boolean;
1397
+ OpenAI-compatible choice normalization sets `done:true`. Both return mutable
1398
+ `{provider,model,message:{role:'assistant',content,tool_calls?},providerResponse,
1399
+ done,doneReason,promptEvalCount,evalCount}` and preserve the complete provider
1400
+ response in `providerResponse`. Tool calls remain structural data and are never
1401
+ executed. General malformed responses fail `AI_CHAT_INVALID_RESPONSE`;
1402
+ malformed structural envelopes or argument JSON fail
1403
+ `AI_CHAT_INVALID_TOOL_CALL`, and a missing or blank argument `message` fails
1404
+ `AI_CHAT_TOOL_MESSAGE_REQUIRED`. Caller cancellation is `AbortError` with code
1405
+ `AI_CHAT_ABORTED`. A new user
1406
+ turn cannot bypass a pending structural tool call
1407
+ (`AI_CHAT_TOOL_RESULT_REQUIRED`), a mismatched tool result fails
1408
+ `AI_CHAT_INVALID_TOOL_MESSAGE`, and a second terminal settlement of one
1409
+ prepared transaction fails `AI_CHAT_TRANSACTION_SETTLED`. Incoherent initial or
1410
+ persisted sequencing fails `AI_CHAT_INCOHERENT_PERSISTENCE`.
1411
+
1412
+ Exact exports: `normalizeStructuralToolCall`, `default`.
1413
+
1414
+ ### Availability and normalization
1415
+
1416
+ **Native bridge by default; cross-host with injected chat.** Normalized session/result; provider rejection preserved. Transport: Arcane.ai.chat or injected provider. [Deep protocol details](protocols.md).
1417
+
1418
+ ### Example
1419
+
1420
+ ```javascript
1421
+ import ConfiguredAIChatSession from '/arcane/modules/ConfiguredAIChatSession.js';
1422
+
1423
+ const session = new ConfiguredAIChatSession({
1424
+ chat: async request => ({
1425
+ provider: 'demo',
1426
+ model: 'echo',
1427
+ message: {
1428
+ role: 'assistant',
1429
+ content: `Received ${request.messages.length} messages.`
1430
+ }
1431
+ })
1432
+ });
1433
+ console.log(await session.send('Hello'));
1434
+ ```
1435
+
1436
+ ## ConversationActionItems.js
1437
+
1438
+ ### Overview
1439
+
1440
+ Normalizes, creates, updates, remembers, selects, and formats complete conversation action items.
1441
+
1442
+ ### Public surface
1443
+
1444
+ Action-item constants and lifecycle/formatting helpers.
1445
+
1446
+ Exact exports: `CONVERSATION_ACTION_ITEM_BASES`, `CONVERSATION_ACTION_ITEM_PRESENTATION_COOLDOWN_MS`, `CONVERSATION_ACTION_ITEM_STATUSES`, `conversationActionItemsInstruction`, `createConversationActionItem`, `formatConversationActionItemCheckIn`, `markConversationActionItemsPresented`, `normalizeConversationActionItem`, `normalizeConversationActionItems`, `normalizeRememberedConversationActions`, `outstandingConversationActionItems`, `rememberConversationActionItems`, `removeConversationActionItem`, `selectConversationActionItemsForPresentation`, `updateConversationActionItem`.
1447
+
1448
+ ### Availability and normalization
1449
+
1450
+ **Cross-host.** Fully normalized status/base/presentation contract. Transport: In-process only. [Deep protocol details](protocols.md).
1451
+
1452
+ ### Example
1453
+
1454
+ ```javascript
1455
+ import * as module from '/arcane/modules/ConversationActionItems.js';
1456
+
1457
+ console.log(Object.keys(module));
1458
+ ```
1459
+
1460
+ ## ConversationClosingReport.js
1461
+
1462
+ ### Overview
1463
+
1464
+ Defines the closing-report tool, instruction, result normalizer, call classifier, and formatter.
1465
+
1466
+ ### Public surface
1467
+
1468
+ Six constants/helpers for closing reports.
1469
+
1470
+ The generated sole-call schema requires both `message` and `final_message`.
1471
+ `message` is brief user-facing progress shown while the application accepts and
1472
+ renders the call. `final_message` remains the complete terminal closeout and is
1473
+ never replaced by or duplicated into `message`; `remembered_actions` remains
1474
+ optional. `normalizeConversationClosingReport()` returns
1475
+ `{message,finalMessage,rememberedActions}`, while
1476
+ `formatConversationClosingReport()` escapes and renders only `finalMessage`.
1477
+
1478
+ Exact exports: `CONVERSATION_CLOSING_REPORT_TOOL_NAME`, `classifyConversationClosingReportCalls`, `conversationClosingReportInstruction`, `createConversationClosingReportTool`, `formatConversationClosingReport`, `normalizeConversationClosingReport`.
1479
+
1480
+ ### Availability and normalization
1481
+
1482
+ **Cross-host.** Fully normalized report contract. Transport: In-process only. [Deep protocol details](protocols.md).
1483
+
1484
+ ### Example
1485
+
1486
+ ```javascript
1487
+ import * as module from '/arcane/modules/ConversationClosingReport.js';
1488
+
1489
+ console.log(Object.keys(module));
1490
+ ```
1491
+
1492
+ ## ConversationTimebox.js
1493
+
1494
+ ### Overview
1495
+
1496
+ Owns conversation limits, control messages, submission barriers, elapsed formatting, and delivery proof.
1497
+
1498
+ ### Public surface
1499
+
1500
+ default `ConversationTimebox`, `ConversationSubmissionBarrier`, constants and control helpers.
1501
+
1502
+ Exact exports: `CONVERSATION_TIMEBOX_ERROR_CODES`,
1503
+ `CONVERSATION_TIMEBOX_EVENT_TYPES`, `CONVERSATION_TIMEBOX_LIMIT_MESSAGE`,
1504
+ `CONVERSATION_TIMEBOX_OPENING_INSTRUCTION`, `CONVERSATION_TIMEBOX_REASONS`,
1505
+ `CONVERSATION_TIMEBOX_TOOL_NAME`, `ConversationSubmissionBarrier`,
1506
+ `appendConversationTimeboxOpeningInstruction`, `consumeConversationTimeboxCall`,
1507
+ `conversationTimeboxSubmissionKey`, `conversationTimeboxTool`,
1508
+ `createConversationTimeboxControlMessage`, `default`,
1509
+ `formatConversationElapsed`, `normalizeConversationTimeboxCommand`, and
1510
+ `requireConversationTimeboxDelivery`.
1511
+
1512
+ `conversationTimeboxTool` is a sole-call function schema with
1513
+ `additionalProperties:false`. Every call requires `action` and a nonempty
1514
+ user-facing `message`; `set` and `adjust` also require an explicit positive
1515
+ `duration_milliseconds`, while `clear` ignores duration.
1516
+ `normalizeConversationTimeboxCommand()` preserves the exact message, and
1517
+ `ConversationTimebox.applyCommand()` returns the resulting state snapshot plus
1518
+ that message after applying the command. `consumeConversationTimeboxCall()`
1519
+ retains this producer result inside its fulfilled result record.
1520
+
1521
+ ### Availability and normalization
1522
+
1523
+ **Cross-host.** Fully normalized state/command/delivery errors. Transport: Clock/timers and callbacks. [Deep protocol details](protocols.md).
1524
+
1525
+ ### Example
1526
+
1527
+ ```javascript
1528
+ import * as module from '/arcane/modules/ConversationTimebox.js';
1529
+
1530
+ console.log(Object.keys(module));
1531
+ ```
1532
+
1533
+ ## CoreLocalModelCatalog.js
1534
+
1535
+ ### Overview
1536
+
1537
+ Projects Core local-AI status into UI-safe admitted model and speech availability catalogs.
1538
+
1539
+ ### Public surface
1540
+
1541
+ Provider-mode constant and four catalog/availability helpers.
1542
+
1543
+ Exact exports: `USER_MANAGED_LOOPBACK_PROVIDER_MODE`, `getCoreLocalModelCatalog`, `getCoreLocalModelCatalogWithAdmissionFailures`, `getCoreLocalSpeechAvailability`, `isUserManagedLoopbackLocalAIStatus`.
1544
+
1545
+ ### Availability and normalization
1546
+
1547
+ **Cross-host.** Fully normalized descriptors and stable availability labels. Transport: In-process projection of Core status. [Deep protocol details](protocols.md).
1548
+
1549
+ ### Example
1550
+
1551
+ ```javascript
1552
+ import * as module from '/arcane/modules/CoreLocalModelCatalog.js';
1553
+
1554
+ console.log(Object.keys(module));
1555
+ ```
1556
+
1557
+ ## DataMaintenance.js
1558
+
1559
+ ### Overview
1560
+
1561
+ Deletes empty chats and associated/empty memory records inside the current app data scope.
1562
+
1563
+ ### Public surface
1564
+
1565
+ `clearEmptyChatsAndMemories()` plus content predicates.
1566
+
1567
+ Exact exports: `clearEmptyChatsAndMemories`, `hasConversationEntry`,
1568
+ `hasMemoryContent`, `hasUserEntry`.
1569
+
1570
+ ### Availability and normalization
1571
+
1572
+ **Browser / native WebView.** Normalized counts; destructive storage failures preserved. Transport: Global DBOPFS. [Deep protocol details](protocols.md).
1573
+
1574
+ ### Example
1575
+
1576
+ ```javascript
1577
+ import * as module from '/arcane/modules/DataMaintenance.js';
1578
+
1579
+ console.log(Object.keys(module));
1580
+ ```
1581
+
1582
+ ## DBLS.js
1583
+
1584
+ ### Overview
1585
+
1586
+ Provides app-scoped localStorage tables, batch reads/writes, filtering, deletion, and counts.
1587
+
1588
+ ### Public surface
1589
+
1590
+ default `DBLS`; installs `window.dbls`, emits `dbls-ready`; CRUD/batch/key APIs.
1591
+
1592
+ Exact exports: `DBLS_EVENT_TYPES`, `DBLS_REASONS`, `default`.
1593
+
1594
+ ### Availability and normalization
1595
+
1596
+ **Browser / native WebView.** Scoped keys and values normalized; storage failures mixed. Transport: localStorage + AppDataScope. [Deep protocol details](protocols.md).
1597
+
1598
+ ### Example
1599
+
1600
+ ```javascript
1601
+ import * as module from '/arcane/modules/DBLS.js';
1602
+
1603
+ console.log(Object.keys(module));
1604
+ ```
1605
+
1606
+ ## DBOPFS.js
1607
+
1608
+ ### Overview
1609
+
1610
+ Provides app-scoped OPFS tables, worker I/O, backup/restore, compression, and CRUD/batch APIs.
1611
+
1612
+ ### Public surface
1613
+
1614
+ default `DBOPFS`; installs `window.dbopfs`, emits `dbopfs-ready`; table/file/backup APIs.
1615
+
1616
+ Exact exports: `DBOPFS_EVENT_TYPES`, `DBOPFS_REASONS`, `default`.
1617
+
1618
+ ### Availability and normalization
1619
+
1620
+ **Browser / native WebView.** App scope and recognized JSON/JSONL file parsing
1621
+ are normalized. Each readable JSONL row becomes its parsed value; a nonblank
1622
+ unreadable row remains in its original string form so the owning application
1623
+ can display, diagnose, or recover it without silent data loss. DOM and storage
1624
+ errors remain observable. Transport: OPFS, DBOPFSWorker, Compression Streams.
1625
+ [Deep protocol details](protocols.md).
1626
+
1627
+ ### Example
1628
+
1629
+ ```javascript
1630
+ import * as module from '/arcane/modules/DBOPFS.js';
1631
+
1632
+ console.log(Object.keys(module));
1633
+ ```
1634
+
1635
+ ## DBOPFSDocumentLibrary.js
1636
+
1637
+ ### Overview
1638
+
1639
+ Stores one application-defined document corpus through an existing DBOPFS-style
1640
+ adapter, searches only a completed generation, and builds complete context.
1641
+ Construction performs no read, write, fetch, or search; applications call
1642
+ `bootstrap()` deliberately.
1643
+
1644
+ ### Public surface
1645
+
1646
+ Exact exports: `DBOPFSDocumentLibrary`, `createDBOPFSDocumentLibrary`,
1647
+ `default`, and `normalizeDBOPFSDocumentSchema`.
1648
+
1649
+ `new DBOPFSDocumentLibrary({concurrency,db,schema})` exposes `schema`,
1650
+ `bootstrap({files,onProgress,read,readFailurePolicy,signal})`,
1651
+ `search(query,{kinds,signal,tags})`,
1652
+ `evaluate(query,{sources,read,kinds?,tags?,readFailurePolicy?,onProgress?,signal?})`,
1653
+ `buildContext(query,{signal})`, and `createContextBuilder()`.
1654
+
1655
+ `evaluate()` requires `sources`
1656
+ and `read`, filters source metadata before calling
1657
+ `read(source,{ordinal,signal})`, and never persists a caller-owned body.
1658
+
1659
+ ### Availability and normalization
1660
+
1661
+ **Browser or compatible host with an injected DBOPFS adapter.** The adapter
1662
+ keeps the existing `get`, `set`, `getAllKeys`, and `delete` method names; Node
1663
+ can use the same class only through an explicitly imported runtime module and a
1664
+ compatible storage adapter; SDK `0.5.11` publishes no Node package subpath or
1665
+ Node storage implementation for it. Bootstrap uses a concurrent
1666
+ generation, commits its manifest last, cleans partial data on failure, and
1667
+ rejects case-colliding IDs. Search
1668
+ returns `{failures,matches,total}` so one malformed record remains visible
1669
+ without hiding readable results. `bootstrap()` and `evaluate()` default to
1670
+ `readFailurePolicy:'preserve-readable'`; explicit `reject` stops on a read
1671
+ failure. Preserve-readable mode returns the readable records plus the complete
1672
+ failure and coverage details (`readCoverage` for bootstrap, `coverage` for
1673
+ evaluation). Evaluation reads a caller-owned source list without persisting its
1674
+ bodies and returns complete documents and text.
1675
+ Read failure remains `DBOPFS_DOCUMENT_READ_FAILED`; invalid public input uses
1676
+ `DBOPFS_DOCUMENT_INVALID`, invalid concurrency uses
1677
+ `DBOPFS_DOCUMENT_INVALID_LIMIT`, and a preserved read failure without a usable
1678
+ source code is reported as `failures[].code:'DBOPFS_DOCUMENT_ERROR'`.
1679
+ Cancellation is `AbortError` with code `DBOPFS_DOCUMENT_ABORTED`. Construction
1680
+ does not search.
1681
+ When an application explicitly supplies the library's context builder, each
1682
+ prepared chat send performs that complete retrieval.
1683
+
1684
+ ### Example
1685
+
1686
+ ```javascript
1687
+ import {
1688
+ createDBOPFSDocumentLibrary
1689
+ } from '/arcane/modules/DBOPFSDocumentLibrary.js';
1690
+
1691
+ const documents = createDBOPFSDocumentLibrary({
1692
+ db: globalThis.dbopfs,
1693
+ schema: {id: 'help', version: '1', table: 'help_documents'}
1694
+ });
1695
+ async function replaceHelpCorpusAfterUserChoice() {
1696
+ await documents.bootstrap({files: [{
1697
+ id: 'welcome',
1698
+ path: 'welcome.md',
1699
+ title: 'Welcome',
1700
+ body: 'Arcane applications are portable.'
1701
+ }]});
1702
+ console.log(await documents.search('portable'));
1703
+
1704
+ const preview = await documents.evaluate('portable', {
1705
+ sources: [{id:'draft', path:'draft.md', title:'Draft'}],
1706
+ read: async source => source.id === 'draft' ? 'Portable app notes.' : ''
1707
+ });
1708
+ console.log(preview.coverage, preview.text);
1709
+ }
1710
+ ```
1711
+
1712
+ ## DBOPFSWorker.js
1713
+
1714
+ ### Overview
1715
+
1716
+ Serializes OPFS sync-handle read/write requests from a MessagePort.
1717
+
1718
+ ### Public surface
1719
+
1720
+ No ESM exports; accepts `read` and `write` port requests.
1721
+
1722
+ This is a dedicated worker protocol and has no ESM exports.
1723
+
1724
+ ### Availability and normalization
1725
+
1726
+ **Dedicated worker.** Responses normalize to `{success,fileData?}` or `{error:{name,message}}`. Transport: MessageChannel + OPFS sync access handle. [Deep protocol details](protocols.md).
1727
+
1728
+ ### Example
1729
+
1730
+ ```javascript
1731
+ const worker = new Worker('/arcane/modules/DBOPFSWorker.js', {type: 'module'});
1732
+ ```
1733
+
1734
+ ## DevelopmentWorkspace.js
1735
+
1736
+ ### Overview
1737
+
1738
+ Provides complete workspace inspection, context, setup task, and Node installer clients without arbitrary command execution.
1739
+
1740
+ ### Public surface
1741
+
1742
+ default `DevelopmentWorkspace` and input validators; `inspect()`, `context()`, `setup()`, `installNode()`.
1743
+
1744
+ Exact exports: `contextQuery`, `default`, `setupTaskId`, `workspaceRoot`.
1745
+
1746
+ ### Availability and normalization
1747
+
1748
+ **Native bridge.** Complete plain-text roots, queries, and application-owned task identifiers reach the provider without application length or task allowlist gates; provider result/error content is preserved. Transport: Arcane.development. [Deep protocol details](protocols.md).
1749
+
1750
+ ### Example
1751
+
1752
+ ```javascript
1753
+ import * as module from '/arcane/modules/DevelopmentWorkspace.js';
1754
+
1755
+ console.log(Object.keys(module));
1756
+ ```
1757
+
1758
+ ## DirectoryPicker.js
1759
+
1760
+ ### Overview
1761
+
1762
+ Wraps the provider-owned native directory chooser and normalizes selected/cancelled/error results.
1763
+
1764
+ ### Public surface
1765
+
1766
+ default `DirectoryPicker`, `normalizeDirectoryPickerOptions()`, `normalizeDirectorySelection()`.
1767
+
1768
+ Exact exports: `default`, `normalizeDirectoryPickerOptions`, `normalizeDirectorySelection`.
1769
+
1770
+ ### Availability and normalization
1771
+
1772
+ **Native bridge.** Every caller option and provider result field is preserved.
1773
+ `title`, `initialPath`, and a selected `path` remain complete strings without
1774
+ trimming or application character gates, and returned records remain mutable.
1775
+ The provider or operating system owns any platform-specific path failure.
1776
+ Cancellation and malformed provider results retain coded errors. Transport:
1777
+ Arcane.filesystem.selectDirectory. [Deep protocol details](protocols.md).
1778
+
1779
+ ### Example
1780
+
1781
+ ```javascript
1782
+ import * as module from '/arcane/modules/DirectoryPicker.js';
1783
+
1784
+ console.log(Object.keys(module));
1785
+ ```
1786
+
1787
+ ## DocumentLexicalSearch.js
1788
+
1789
+ ### Overview
1790
+
1791
+ Provides deterministic, dependency-free metadata/body ranking and complete
1792
+ context excerpts for caller-owned document records.
1793
+
1794
+ ### Public surface
1795
+
1796
+ Exact exports: `DOCUMENT_SEARCH_FIELD_ORDER`, `DocumentLexicalSearch`,
1797
+ `createDocumentLexicalIndex`, `default`, `documentContextExcerpt`,
1798
+ `documentSearchTokens`, `normalizedDocumentSearchText`, `scoreDocumentBody`,
1799
+ and `scoreDocumentLexicalIndex`.
1800
+
1801
+ `new DocumentLexicalSearch(records)` exposes
1802
+ `rank(query,{kinds,tags})` and `search(query,{kinds,tags})`.
1803
+
1804
+ ### Availability and normalization
1805
+
1806
+ **Cross-host.** Indexing and search are in-process only. Text, tags, kinds,
1807
+ scores, field ordering, complete excerpts, and tie-breaking are normalized into
1808
+ mutable records. This module performs no storage, network, model, Core, or DOM
1809
+ action. The caller decides how a result is used.
1810
+
1811
+ ### Example
1812
+
1813
+ ```javascript
1814
+ import DocumentLexicalSearch from '/arcane/modules/DocumentLexicalSearch.js';
1815
+
1816
+ const search = new DocumentLexicalSearch([{
1817
+ id: 'welcome',
1818
+ path: 'welcome.md',
1819
+ title: 'Welcome',
1820
+ body: 'Arcane applications are portable.',
1821
+ kind: 'guide',
1822
+ tags: ['intro']
1823
+ }]);
1824
+ console.log(search.search('portable', {limit: 5}));
1825
+ ```
1826
+
1827
+ ## DocumentNavigation.js
1828
+
1829
+ ### Overview
1830
+
1831
+ Binds document navigation, filtering, history, current-item reveal, and load initialization.
1832
+
1833
+ ### Public surface
1834
+
1835
+ Five binding/filter/reveal helpers.
1836
+
1837
+ Exact exports: `applyDocumentNavigationFilter`, `bindDocumentNavigation`, `clearDocumentNavigationFilter`, `initializeDocumentNavigation`, `revealCurrentDocumentNavigationItem`.
1838
+
1839
+ ### Availability and normalization
1840
+
1841
+ **Browser / native WebView.** Normalized filter/navigation state; DOM effects preserved. Transport: DOM and history. [Deep protocol details](protocols.md).
1842
+
1843
+ ### Example
1844
+
1845
+ ```javascript
1846
+ import * as module from '/arcane/modules/DocumentNavigation.js';
1847
+
1848
+ console.log(Object.keys(module));
1849
+ ```
1850
+
1851
+ ## Errors.js
1852
+
1853
+ ### Overview
1854
+
1855
+ Normalizes global errors/rejections, assigns occurrence identifiers, persists a complete ledger, and performs complete delivery.
1856
+
1857
+ ### Public surface
1858
+
1859
+ default `Errors`; event normalizers plus lifecycle, capture, delivery and teardown methods.
1860
+
1861
+ Exact exports: `GLOBAL_ERROR_EVENT_CODES`, `GLOBAL_ERROR_EVENT_TYPES`,
1862
+ `GLOBAL_ERROR_REASONS`, `default`, `normalizeErrorEvent`, and
1863
+ `normalizeRejectionEvent`.
1864
+
1865
+ ### Availability and normalization
1866
+
1867
+ **Browser / native WebView hybrid.** Incident records normalized; storage/mail failures isolated. Transport: Window events, DBOPFS, Mail. [Deep protocol details](protocols.md).
1868
+
1869
+ ### Example
1870
+
1871
+ ```javascript
1872
+ import * as module from '/arcane/modules/Errors.js';
1873
+
1874
+ console.log(Object.keys(module));
1875
+ ```
1876
+
1877
+ ## GifEncoder.js
1878
+
1879
+ ### Overview
1880
+
1881
+ Encodes indexed frames into a complete animated GIF using palette mapping and LZW.
1882
+
1883
+ ### Public surface
1884
+
1885
+ default `GifEncoder`, `indexPixels()`, `lzw()`.
1886
+
1887
+ Exact exports: `default`, `indexPixels`, `lzw`.
1888
+
1889
+ ### Availability and normalization
1890
+
1891
+ **Cross-host.** Normalized complete binary output. Transport: In-process only. [Deep protocol details](protocols.md).
1892
+
1893
+ ### Example
1894
+
1895
+ ```javascript
1896
+ import * as module from '/arcane/modules/GifEncoder.js';
1897
+
1898
+ console.log(Object.keys(module));
1899
+ ```
1900
+
1901
+ ## HTMLImport.js
1902
+
1903
+ ### Overview
1904
+
1905
+ Defines the same-origin `<html-import>` loader with open shadow root, inline script execution, and readiness/error events.
1906
+
1907
+ ### Public surface
1908
+
1909
+ default `HTMLImport`; registers `html-import`; `connectedCallback()` and `ready`.
1910
+
1911
+ Exact exports: `default`.
1912
+
1913
+ ### Availability and normalization
1914
+
1915
+ **Browser / native WebView.** Public error detail normalized; fetch/DOM failure preserved. Transport: Same-origin fetch + DOM. [Deep protocol details](protocols.md).
1916
+
1917
+ ### Example
1918
+
1919
+ ```javascript
1920
+ import * as module from '/arcane/modules/HTMLImport.js';
1921
+
1922
+ console.log(Object.keys(module));
1923
+ ```
1924
+
1925
+ ## InMemoryCommunicationProvider.js
1926
+
1927
+ ### Overview
1928
+
1929
+ Implements deterministic in-memory thread/message/send behavior for demos and tests.
1930
+
1931
+ ### Public surface
1932
+
1933
+ default provider with `listThreads()`, `getMessages()`, `send()`.
1934
+
1935
+ Exact exports: `default`.
1936
+
1937
+ ### Availability and normalization
1938
+
1939
+ **Cross-host.** Normalized communication entities. Transport: In-process only. [Deep protocol details](protocols.md).
1940
+
1941
+ ### Example
1942
+
1943
+ ```javascript
1944
+ import * as module from '/arcane/modules/InMemoryCommunicationProvider.js';
1945
+
1946
+ console.log(Object.keys(module));
1947
+ ```
1948
+
1949
+ ## IsolatedModelQuestionRunner.js
1950
+
1951
+ ### Overview
1952
+
1953
+ Inspects one selected model and runs one isolated question while preserving the
1954
+ complete answer.
1955
+
1956
+ ### Public surface
1957
+
1958
+ default/named runner, `countSentences()`, `inspectModel()`, `runQuestion()`.
1959
+ `inspectModel(model,expectedModel,contextTokens)` accepts any positive safe
1960
+ integer context-token value and forwards the complete selected request.
1961
+ `runQuestion()` returns the provider's full result plus informative
1962
+ `sentenceCount`; it has no `maxSentences` input or `sentenceLimitExceeded`
1963
+ output.
1964
+
1965
+ Exact exports: `IsolatedModelQuestionRunner`, `countSentences`, `default`.
1966
+
1967
+ ### Availability and normalization
1968
+
1969
+ **Native bridge or injected provider.** Normalized model/result and coded errors. Transport: localAI isolated-model methods. [Deep protocol details](protocols.md).
1970
+
1971
+ ### Example
1972
+
1973
+ ```javascript
1974
+ import * as module from '/arcane/modules/IsolatedModelQuestionRunner.js';
1975
+
1976
+ console.log(Object.keys(module));
1977
+ ```
1978
+
1979
+ ## LocalAIReadiness.js
1980
+
1981
+ ### Overview
1982
+
1983
+ Derives selected AI requirements and returns a complete readiness/recovery report across browser, desktop, and Android modes.
1984
+
1985
+ ### Public surface
1986
+
1987
+ Endpoint constant plus requirements, speech-health, and readiness helpers.
1988
+
1989
+ Exact exports: `LOCAL_AI_BROWSER_ENDPOINTS`, `checkLocalAIReadiness`, `deriveLocalAIRequirements`, `evaluateLocalSpeechHealth`.
1990
+
1991
+ ### Availability and normalization
1992
+
1993
+ **Browser/native hybrid.** Fully normalized report and stable error codes; browsers never probe Ollama. Transport: Arcane.localAI, Arcane.speech, complete browser speech health. [Deep protocol details](protocols.md).
1994
+
1995
+ ### Example
1996
+
1997
+ ```javascript
1998
+ import * as module from '/arcane/modules/LocalAIReadiness.js';
1999
+
2000
+ console.log(Object.keys(module));
2001
+ ```
2002
+
2003
+ ## LocalAIReadinessController.js
2004
+
2005
+ ### Overview
2006
+
2007
+ Coordinates local-AI status component checks, ensured recovery, availability projection, and teardown.
2008
+
2009
+ ### Public surface
2010
+
2011
+ `createLocalAIReadinessController()`, `availabilityFromReport()`.
2012
+
2013
+ Exact exports: `LOCAL_AI_READINESS_CONTROLLER_ERROR_CODES`,
2014
+ `LOCAL_AI_READINESS_CONTROLLER_EVENT_TYPES`,
2015
+ `LOCAL_AI_READINESS_CONTROLLER_REASONS`, `availabilityFromReport`, and
2016
+ `createLocalAIReadinessController`.
2017
+
2018
+ ### Availability and normalization
2019
+
2020
+ `availabilityFromReport()` returns `true` only for a slot whose local
2021
+ requirement is explicitly `required:true` and whose report is explicitly
2022
+ `ready:true`. Missing and non-local-required slots remain false: this projection
2023
+ does not attest provider registration, selection, credentials, browser speech
2024
+ authority, or model load state. Components must preserve selected sticky
2025
+ `AIRuntimeState` roles as the readiness authority.
2026
+
2027
+ **Browser/native hybrid.** Normalized controller state and change events.
2028
+ Transport: LocalAIReadiness + component events. [Deep protocol details](protocols.md).
2029
+
2030
+ ### Example
2031
+
2032
+ ```javascript
2033
+ import * as module from '/arcane/modules/LocalAIReadinessController.js';
2034
+
2035
+ console.log(Object.keys(module));
2036
+ ```
2037
+
2038
+ ## Mail.js
2039
+
2040
+ ### Overview
2041
+
2042
+ Builds complete reports and prefers the native mail capability with an explicit HTTP transport fallback. Report text, HTML, and serialized content are preserved exactly and delivered complete.
2043
+
2044
+ ### Public surface
2045
+
2046
+ default `Mail`, `resolveMailConfig()`; installs `window.mail`; `send()`.
2047
+
2048
+ Exact exports: `default`, `resolveMailConfig`.
2049
+
2050
+ ### Availability and normalization
2051
+
2052
+ **Browser/native hybrid + cloud.** Mail inputs/results normalized; transport failures mixed. Transport: Arcane.mail.send or MailTransport HTTP(S). [Deep protocol details](protocols.md).
2053
+
2054
+ ### Example
2055
+
2056
+ ```javascript
2057
+ import * as module from '/arcane/modules/Mail.js';
2058
+
2059
+ console.log(Object.keys(module));
2060
+ ```
2061
+
2062
+ ## MailOutbox.mjs
2063
+
2064
+ ### Overview
2065
+
2066
+ Persists each complete provider-neutral mail report before delivery and owns its
2067
+ idempotent enqueue, FIFO drain, retry-window, terminal-state, reconciliation,
2068
+ and explicit invalid-record maintenance lifecycle. It selects no mail provider,
2069
+ recipient, retention policy, retry timer, or transport fallback.
2070
+
2071
+ ### Public surface
2072
+
2073
+ Exact exports: `MAIL_OUTBOX_IDEMPOTENCY_WINDOW_MS`, `MAIL_OUTBOX_PROTOCOL`,
2074
+ `MAIL_OUTBOX_STATES`, `MAIL_OUTBOX_TABLE`, `MailOutbox`, `createMailOutbox`, and
2075
+ `default`.
2076
+
2077
+ ```text
2078
+ new MailOutbox({
2079
+ storage,
2080
+ deliver,
2081
+ clock=Date.now,
2082
+ isOnline=()=>globalThis.navigator?.onLine!==false,
2083
+ lockManager=undefined,
2084
+ onlineTarget=typeof globalThis.addEventListener==='function'?globalThis:null,
2085
+ onRecordCommitted=null,
2086
+ quarantineTable='mail_outbox_quarantine',
2087
+ table=MAIL_OUTBOX_TABLE
2088
+ }={})
2089
+ ```
2090
+
2091
+ `storage` must expose `get()`, `set()`, and `getAllKeys()`; explicit deletion or
2092
+ quarantine additionally requires `delete()`. `lockManager` must expose the Web
2093
+ Locks-compatible `request()` contract. The injected
2094
+ `deliver({report,reportKey,serializedReport,signal})` callback receives the
2095
+ complete parsed report, its stable idempotency key, the exact stored JSON string,
2096
+ and the caller-owned signal. Omitted `lockManager` resolves first from storage
2097
+ and then from `navigator.locks`. A delivery result must identify a valid
2098
+ `requestId` and one of `accepted`, `delivery_uncertain`,
2099
+ `retryable`, `permanently_rejected`, or `partially_accepted`;
2100
+ `providerId` and `acceptanceAuthority` are optional transport-owned metadata,
2101
+ and an acceptance authority is valid only on an `accepted` result.
2102
+
2103
+ Read-only getters are `started`, `invalidRecords`, and `lastBackgroundError`.
2104
+ Methods are `get(key)`, `list()`, `audit()`, `deleteInvalid(fileName)`,
2105
+ `repairInvalid(fileName,replacement)`,
2106
+ `quarantineInvalid()`,
2107
+ `enqueue({report,reportKey}={}, {attempt=true,signal=null}={})`,
2108
+ `drain({reason='manual',signal=null}={})`, `start({signal=null}={})`, and
2109
+ `stop()`. `createMailOutbox(options)` returns `new MailOutbox(options)`.
2110
+
2111
+ Every returned durable record contains exactly
2112
+ `{protocol,reportKey,serializedReport,state,createdAt,updatedAt,firstAttemptAt,
2113
+ lastAttemptAt,nextAttemptAt,attempts,result,failure}`. Protocol is
2114
+ `arcane-mail-outbox/1`; the default table is `mail_outbox`; the idempotency
2115
+ window is 86,400,000 milliseconds. States are exactly `queued`, `sending`,
2116
+ `retry_wait`, `accepted`, `failed`, and `reconciliation_required`. Accepted
2117
+ means the selected transport returned `accepted` with a valid request ID, not
2118
+ that the message reached an inbox.
2119
+
2120
+ `enqueue()` serializes same-instance persistence and binds one report key to one
2121
+ complete serialized body. It preserves the complete queued content without
2122
+ truncation, clipping, tailing, or elision.
2123
+ `drain()` runs or joins one instance drain under an exclusive shared lock. Startup,
2124
+ an owned `online` listener, or an explicit call may trigger work; there is no
2125
+ polling or retry timer. Abort before the delivery call prevents that call, and a
2126
+ caller joining an existing drain may stop waiting without cancelling the shared
2127
+ drain. Once an accepted result is committed, it outranks a racing cancellation;
2128
+ cancellation never claims an admitted provider attempt stopped. An interrupted
2129
+ or ambiguous attempt remains a same-key retry inside the 24-hour window and
2130
+ becomes `reconciliation_required` when automatic retry would risk a duplicate.
2131
+ `stop()` aborts only the owned online drain, removes its listener, preserves
2132
+ durable records, and returns the instance.
2133
+
2134
+ `audit()` reports valid records plus complete invalid-file metadata. Repair,
2135
+ deletion, and quarantine are explicit, revalidate the selected file under the
2136
+ table lock, and never infer destructive authority from a storage read failure.
2137
+ `onRecordCommitted(record)` is an observational callback after each durable
2138
+ write; callback failure cannot change the committed operation result.
2139
+
2140
+ ### Availability and normalization
2141
+
2142
+ **Browser/native WebView or compatible injected host.** The default application
2143
+ integration uses DBOPFS-compatible durable storage and `navigator.locks`; an
2144
+ alternate adapter owns its own durability claim and must provide equivalent
2145
+ storage and shared-lock semantics. Complete records, state transitions,
2146
+ retry/reconciliation classification, invalid-record maintenance, and
2147
+ AbortSignal admission/join cancellation are normalized. Storage, lock,
2148
+ online-check, and injected-delivery failures remain visible through concrete
2149
+ `MAIL_OUTBOX_*` codes. Transport: injected durable storage, Web Locks,
2150
+ AbortSignal, optional online EventTarget, and an injected delivery callback.
2151
+ [Deep protocol details](mail.md#durable-send-semantics).
2152
+
2153
+ ### Example
2154
+
2155
+ ```javascript
2156
+ import {createMailOutbox} from '/arcane/modules/MailOutbox.mjs';
2157
+
2158
+ const outbox = createMailOutbox({storage, deliver});
2159
+ await outbox.start({signal});
2160
+ const record = await outbox.enqueue(
2161
+ {report, reportKey: 'report-20260827-001'},
2162
+ {attempt: true, signal}
2163
+ );
2164
+ console.log(record.state);
2165
+ outbox.stop();
2166
+ ```
2167
+
2168
+ ## MailTransport.mjs
2169
+
2170
+ ### Overview
2171
+
2172
+ Sends one complete mail report to a normalized HTTP(S) endpoint.
2173
+
2174
+ ### Public surface
2175
+
2176
+ `MailTransportError`, `normalizeMailEndpoint()`, `serializeMailReport()`, and
2177
+ `sendMailReport()`.
2178
+
2179
+ Exact exports: `MailTransportError`, `normalizeMailEndpoint`,
2180
+ `serializeMailReport`, `sendMailReport`.
2181
+
2182
+ ### Availability and normalization
2183
+
2184
+ **Browser/server with fetch + cloud.** Normalized endpoint/transport errors; complete remote detail is preserved subject only to unavoidable HTTP framing. Transport: HTTP(S) fetch + AbortController. [Deep protocol details](protocols.md).
2185
+
2186
+ ### Example
2187
+
2188
+ ```javascript
2189
+ import * as module from '/arcane/modules/MailTransport.mjs';
2190
+
2191
+ console.log(Object.keys(module));
2192
+ ```
2193
+
2194
+ ## Marked.min.js
2195
+
2196
+ ### Overview
2197
+
2198
+ Vendored Marked 18.0.5 Markdown lexer, parser, renderer, extension, and walk-token API.
2199
+
2200
+ ### Public surface
2201
+
2202
+ Twenty named/default-style Marked exports; see bundled license notice.
2203
+
2204
+ Exact exports: `Hooks`, `Lexer`, `Marked`, `Parser`, `Renderer`, `TextRenderer`, `Tokenizer`, `defaults`, `getDefaults`, `lexer`, `marked`, `options`, `parse`, `parseInline`, `parser`, `setOptions`, `use`, `walkTokens`.
2205
+
2206
+ ### Availability and normalization
2207
+
2208
+ **Cross-host vendor module.** Vendor-native Marked contract. Transport: In-process only. [Deep protocol details](protocols.md).
2209
+
2210
+ ### Example
2211
+
2212
+ ```javascript
2213
+ import * as module from '/arcane/modules/Marked.min.js';
2214
+
2215
+ console.log(Object.keys(module));
2216
+ ```
2217
+
2218
+ ## MD.js
2219
+
2220
+ ### Overview
2221
+
2222
+ Renders complete Markdown with Marked and exposes the same complete rendered
2223
+ markup through `rendered` and `safeRendered`.
2224
+
2225
+ ### Public surface
2226
+
2227
+ default `MD`; `raw`, `rendered`, `safeRendered`, `append()`.
2228
+
2229
+ Exact exports: `default`.
2230
+
2231
+ ### Availability and normalization
2232
+
2233
+ **Browser / native WebView.** Raw Marked behavior is preserved; parse errors are
2234
+ vendor-native. Transport: Marked. [Deep protocol details](protocols.md).
2235
+
2236
+ ### Example
2237
+
2238
+ ```javascript
2239
+ import * as module from '/arcane/modules/MD.js';
2240
+
2241
+ console.log(Object.keys(module));
2242
+ ```
2243
+
2244
+ ## MemoryRecords.js
2245
+
2246
+ ### Overview
2247
+
2248
+ Normalizes memory content and detects meaningful stored memory.
2249
+
2250
+ ### Public surface
2251
+
2252
+ `normalizeMemoryContent()`, `hasMemoryContent()`.
2253
+
2254
+ Exact exports: `hasMemoryContent`, `normalizeMemoryContent`.
2255
+
2256
+ ### Availability and normalization
2257
+
2258
+ **Cross-host.** Fully normalized string/boolean results. Transport: In-process only. [Deep protocol details](protocols.md).
2259
+
2260
+ ### Example
2261
+
2262
+ ```javascript
2263
+ import * as module from '/arcane/modules/MemoryRecords.js';
2264
+
2265
+ console.log(Object.keys(module));
2266
+ ```
2267
+
2268
+ ## MessageAdvisory.js
2269
+
2270
+ ### Overview
2271
+
2272
+ Normalizes message content advisories and contains per-message inspection failures.
2273
+
2274
+ ### Public surface
2275
+
2276
+ Three advisory/inspection helpers.
2277
+
2278
+ Exact exports: `inspectMessageRecords`, `normalizeContentAdvisory`, `unavailableMessageInspection`.
2279
+
2280
+ ### Availability and normalization
2281
+
2282
+ **Cross-host.** Complete mutable advisory records preserve all supplied text and signals; inspector failures are converted to unavailable results. Transport: Injected inspector. [Deep protocol details](protocols.md).
2283
+
2284
+ ### Example
2285
+
2286
+ ```javascript
2287
+ import * as module from '/arcane/modules/MessageAdvisory.js';
2288
+
2289
+ console.log(Object.keys(module));
2290
+ ```
2291
+
2292
+ ## ModelDefinition.js
2293
+
2294
+ ### Overview
2295
+
2296
+ Parses the deterministic packaged Modelfile subset and extracts the SYSTEM prompt.
2297
+
2298
+ ### Public surface
2299
+
2300
+ `parseModelDefinition()`, `loadModelDefinitionSystemPrompt()`.
2301
+
2302
+ Exact exports: `loadModelDefinitionSystemPrompt`, `parseModelDefinition`.
2303
+
2304
+ ### Availability and normalization
2305
+
2306
+ **Cross-host.** Complete mutable definition data with coded syntax errors for malformed input. Transport: Optional ordinary read-only fetch using the fetch implementation's redirect, credentials, and cache behavior. [Deep protocol details](protocols.md).
2307
+
2308
+ ### Example
2309
+
2310
+ ```javascript
2311
+ import * as module from '/arcane/modules/ModelDefinition.js';
2312
+
2313
+ console.log(Object.keys(module));
2314
+ ```
2315
+
2316
+ ## Ollama.js
2317
+
2318
+ ### Overview
2319
+
2320
+ Provides the first-class Arcane Ollama client without direct access to localhost:11434.
2321
+
2322
+ ### Public surface
2323
+
2324
+ `Ollama`, singleton/default `ollama`; 24 methods; installs `globalThis.arcaneOllama`, emits `arcane-ollama-ready`.
2325
+
2326
+ Exact exports: `OLLAMA_EVENT_TYPES`, `OLLAMA_REASONS`, `Ollama`, `default`,
2327
+ and `ollama`.
2328
+
2329
+ ### Availability and normalization
2330
+
2331
+ **Native bridge.** Principal methods preserve provider-native envelopes; readiness/text/unload helpers normalize. Transport: Arcane.ollama through Core. [Deep protocol details](protocols.md).
2332
+
2333
+ ### Example
2334
+
2335
+ ```javascript
2336
+ import * as module from '/arcane/modules/Ollama.js';
2337
+
2338
+ console.log(Object.keys(module));
2339
+ ```
2340
+
2341
+ ## OllamaModelIdentifier.js
2342
+
2343
+ ### Overview
2344
+
2345
+ Validates and canonicalizes the syntax of Ollama model identifiers without granting model admission.
2346
+
2347
+ ### Public surface
2348
+
2349
+ `normalizeOllamaModelIdentifier()`, `isOllamaModelIdentifier()`.
2350
+
2351
+ Exact exports: `isOllamaModelIdentifier`, `normalizeOllamaModelIdentifier`.
2352
+
2353
+ ### Availability and normalization
2354
+
2355
+ **Cross-host.** Fully normalized string/boolean result. Transport: In-process only. [Deep protocol details](protocols.md).
2356
+
2357
+ ### Example
2358
+
2359
+ ```javascript
2360
+ import * as module from '/arcane/modules/OllamaModelIdentifier.js';
2361
+
2362
+ console.log(Object.keys(module));
2363
+ ```
2364
+
2365
+ ## OllamaSettings.js
2366
+
2367
+ ### Overview
2368
+
2369
+ Defines complete runtime/service preference schemas and deterministic Arcane brain alias names.
2370
+
2371
+ ### Public surface
2372
+
2373
+ `ollamaRuntimeSchema`, `ollamaServiceSchema`, `arcaneBrainModelName()`.
2374
+
2375
+ Exact exports: `arcaneBrainModelName`, `ollamaRuntimeSchema`, `ollamaServiceSchema`.
2376
+
2377
+ ### Availability and normalization
2378
+
2379
+ **Cross-host.** Fully normalized settings/name contract. Transport: In-process only. [Deep protocol details](protocols.md).
2380
+
2381
+ ### Example
2382
+
2383
+ ```javascript
2384
+ import * as module from '/arcane/modules/OllamaSettings.js';
2385
+
2386
+ console.log(Object.keys(module));
2387
+ ```
2388
+
2389
+ ## OpenMeteoWeatherProvider.js
2390
+
2391
+ ### Overview
2392
+
2393
+ Searches and loads Open-Meteo data into mutable Arcane weather entities.
2394
+
2395
+ ### Public surface
2396
+
2397
+ Endpoint constants, default provider, `mapForecast()`; search/load methods and lifecycle events.
2398
+
2399
+ Exact exports: `OPEN_METEO_ENDPOINTS`, `OPEN_METEO_WEATHER_ERRORS`,
2400
+ `OPEN_METEO_WEATHER_EVENTS`, `default`, and `mapForecast`.
2401
+
2402
+ ### Availability and normalization
2403
+
2404
+ **Browser / native WebView / server with fetch + cloud.** Provider data normalized to entities; transport errors mixed. Transport: Open-Meteo HTTPS. [Deep protocol details](protocols.md).
2405
+
2406
+ ### Example
2407
+
2408
+ ```javascript
2409
+ import * as module from '/arcane/modules/OpenMeteoWeatherProvider.js';
2410
+
2411
+ console.log(Object.keys(module));
2412
+ ```
2413
+
2414
+ ## PersistentAIChatSession.js
2415
+
2416
+ ### Overview
2417
+
2418
+ Composes `ConfiguredAIChatSession` with one `ChatEntity` so every user,
2419
+ assistant, and structural tool-result turn has an explicit durable-persistence
2420
+ choice. It preserves the existing DBOPFS method names and ChatEntity memory
2421
+ semantics; it does not define a new storage protocol.
2422
+
2423
+ ### Public surface
2424
+
2425
+ Exact exports: `PersistentAIChatSession`, `createPersistentAIChatSession`, and
2426
+ `default`.
2427
+
2428
+ Constructor and factory options are `{ai,chat,chatEntity,chatFileName,
2429
+ contextBuilder,loadExisting,memory,request,responseLength,systemPrompt}`. Public members are
2430
+ static `create()`, getters `ai`, `chatEntity`, and `fileName`, and `ready()`,
2431
+ `history()`, `transcript()`, `settleMemory()`, `open(input)`, `send(input)`, and
2432
+ `stream(input,handlers)`.
2433
+ `ready()` waits for initialization and resolves the same session instance.
2434
+
2435
+ `open({message:{content,persist:false?},request?,signal?})` performs one
2436
+ application-authored bootstrap request only when the retained conversation is
2437
+ otherwise empty. The bootstrap is never committed. After a complete nonblank
2438
+ model response succeeds, the operation atomically retains only the sanitized
2439
+ assistant content in configured model context and ChatEntity/DBOPFS history.
2440
+ That assistant-only opening survives reload and empty-chat maintenance without
2441
+ a fabricated user turn. A second opening rejects as `AI_CHAT_OPENING_EXISTS`;
2442
+ an unavailable durable ChatEntity rejects as `AI_CHAT_PERSISTENCE_UNAVAILABLE`.
2443
+
2444
+ `send()` accepts either
2445
+ `{message:{content,role:'user'|'tool',tool_call_id?,message?,name?,status?,persist},...}`
2446
+ or an atomic tool-result batch with the same fields,
2447
+ plus `request?`, `response:{persist}`, and `signal?`. Every message and the
2448
+ response must use the same persistence choice. Plain-object `request` supplies
2449
+ per-turn generation options such as
2450
+ `toolChoice:'none'`; it cannot replace session-owned `messages`, `signal`, or
2451
+ streaming/lifecycle callback state.
2452
+ `persist:false` makes the input and response available only to that one request.
2453
+ After the response is returned, neither remains in subsequent model context,
2454
+ the retained transcript, memory extraction, or DBOPFS. A nonpersistent response
2455
+ therefore does not open a retained structural-tool continuation. A retained
2456
+ structural tool result must use the persistence choice captured by its matching
2457
+ assistant tool call.
2458
+
2459
+ `history()` returns provider-safe configured model context, including the
2460
+ system prompt and every complete ordinary visible committed turn. Only a
2461
+ currently unresolved structural-call tail remains raw for its matching active
2462
+ continuation. `transcript()` returns the sanitized human-readable ChatEntity
2463
+ projection.
2464
+ User and assistant records retain only role, complete visible content, and the
2465
+ real timestamp. Tool records retain only role, the required user-facing
2466
+ `message` as content, and optional public `name` and result `status`.
2467
+
2468
+ `stream()` accepts the same input as `send()` and optional
2469
+ `{onChunk,onDataChunk,onDataResult,onToolCall}` handlers. When
2470
+ `ai.streamRequest()` is available, it forwards complete provider data through
2471
+ the data callbacks and ordinary live text/reasoning through `onChunk`. It
2472
+ buffers every observed structural call until the ordered call array exactly
2473
+ matches the terminal response and the complete response passes
2474
+ configured-session validation, and only then publishes each call and uses the
2475
+ same atomic ChatEntity append/configured session commit as `send()`. A
2476
+ terminal-only call is valid; omission or divergence of any observed call
2477
+ rejects with
2478
+ `AI_CHAT_STREAM_TOOL_CALL_MISMATCH` before persistence or commit. When streaming
2479
+ is unavailable, `stream()` uses the
2480
+ configured non-stream chat request and still returns, validates, persists, and
2481
+ renders the complete terminal response and tool calls; optional streaming is
2482
+ not a session failure. The same caller signal and transaction rollback govern
2483
+ both paths.
2484
+
2485
+ When an assistant response opens structural calls, the response persistence
2486
+ choice is retained under every exact call ID only in the active session. One
2487
+ ordered `role:'tool'` request batch must settle all pending IDs with that same
2488
+ persistence choice before a new user or provider turn. That one provider
2489
+ continuation receives the raw calls, IDs, arguments, and results. Once it
2490
+ commits, recurring context replaces them with complete ordinary visible call,
2491
+ assistant, and any supplied public result messages. Raw protocol is never
2492
+ included in new durable records. Existing stored records are not rewritten on
2493
+ load.
2494
+
2495
+ ### Availability and normalization
2496
+
2497
+ **Browser or native WebView with ChatEntity/DBOPFS and a configured chat
2498
+ function.** The default chat calls normalized `Arcane.ai.chat()`; callers can
2499
+ inject the browser-WASM controller, another provider-neutral adapter, or a
2500
+ cloud chat function. There is no automatic provider or storage fallback.
2501
+ Context builders are request-only, and document context remains explicitly
2502
+ untrusted. Errors include `AI_CHAT_BUSY`, `AI_CHAT_TOOL_RESULT_REQUIRED`,
2503
+ `AI_CHAT_INVALID_TOOL_MESSAGE`, `AI_CHAT_TOOL_MESSAGE_REQUIRED`, and
2504
+ `AI_CHAT_INCOHERENT_PERSISTENCE`, plus
2505
+ `AI_CHAT_STREAM_TOOL_CALL_MISMATCH` for a streamed/terminal envelope mismatch,
2506
+ and `AI_CHAT_INVALID_OPENING_RESPONSE`, `AI_CHAT_OPENING_EXISTS`, or
2507
+ `AI_CHAT_PERSISTENCE_UNAVAILABLE` for the dedicated opening lifecycle.
2508
+
2509
+ ### Example
2510
+
2511
+ ```javascript
2512
+ import {
2513
+ createPersistentAIChatSession
2514
+ } from '/arcane/modules/PersistentAIChatSession.js';
2515
+
2516
+ async function sendPersistentSupportTurnAfterUserChoice(documents) {
2517
+ const session = await createPersistentAIChatSession({
2518
+ chatFileName: 'support.jsonl',
2519
+ loadExisting: true,
2520
+ contextBuilder: documents.createContextBuilder()
2521
+ });
2522
+ const response = await session.send({
2523
+ message: {role: 'user', content: 'Summarize the documents.', persist: true},
2524
+ response: {persist: true}
2525
+ });
2526
+ console.log(response.message.content);
2527
+ }
2528
+ ```
2529
+
2530
+ ## PreferenceStore.js
2531
+
2532
+ ### Overview
2533
+
2534
+ Loads and updates schema-defined app preferences through native storage with a narrow browser fallback.
2535
+
2536
+ ### Public surface
2537
+
2538
+ default `PreferenceStore`, re-exported `Preference`/schema; load/set/setAll/reset APIs and events.
2539
+
2540
+ Adapters provide `get(key, context)`, `set(key, value, context)`, and
2541
+ `delete(key, context)`. An adapter may also provide
2542
+ `setMany(entries, context)`, where `entries` is one mutable plain object keyed by
2543
+ the store's namespaced storage keys. `setAll(values, {signal})` normalizes every
2544
+ selected schema value before storage work. For every selected value it calls an
2545
+ advertised `setMany()` once and publishes the existing per-key change events
2546
+ only after that batch succeeds. A dispatched batch rejection propagates without
2547
+ a serial retry, in-memory state change, or change event. Adapters without
2548
+ `setMany()` retain ordered complete serial storage behavior inside
2549
+ one queued operation, including state and events for each successful write before
2550
+ a later write fails.
2551
+
2552
+ Exact exports: `PREFERENCE_STORE_ERROR_CODES`,
2553
+ `PREFERENCE_STORE_EVENT_TYPES`, `Preference`, `default`, and
2554
+ `preferenceSchema`.
2555
+
2556
+ ### Availability and normalization
2557
+
2558
+ **Browser/native hybrid.** Complete ordinary values and returned snapshots remain
2559
+ mutable after schema normalization. Non-Android
2560
+ `Arcane.preferences.setMany()` supplies the optional atomic batch. Only exact
2561
+ unsupported native capability changes future operations to app-scoped
2562
+ localStorage; an in-flight advertised batch is never downgraded after rejection.
2563
+ If cancellation settles after a native batch was dispatched, reload the store to
2564
+ reconcile any atomic host commit that completed before cancellation. Transport:
2565
+ Arcane.preferences or app-scoped localStorage. [Deep protocol details](protocols.md).
2566
+
2567
+ ### Example
2568
+
2569
+ ```javascript
2570
+ import * as module from '/arcane/modules/PreferenceStore.js';
2571
+
2572
+ console.log(Object.keys(module));
2573
+ ```
2574
+
2575
+ ## QRCode.min.js
2576
+
2577
+ ### Overview
2578
+
2579
+ Vendored QRCode generator for DOM, canvas, SVG, and image output.
2580
+
2581
+ ### Public surface
2582
+
2583
+ No ESM exports; global `QRCode`, `makeCode()`, `makeImage()`, `clear()`, `CorrectLevel`.
2584
+
2585
+ This is a classic global script and has no ESM exports.
2586
+
2587
+ ### Availability and normalization
2588
+
2589
+ **Browser vendor script.** Vendor-native. Transport: Classic script global + DOM/canvas/SVG. [Deep protocol details](protocols.md).
2590
+
2591
+ ### Example
2592
+
2593
+ ```html
2594
+ <script src="/arcane/modules/QRCode.min.js"></script>
2595
+ ```
2596
+
2597
+ ## Questionnaire.js
2598
+
2599
+ ### Overview
2600
+
2601
+ Evaluates whether a one-time questionnaire prompt is due without performing the prompt.
2602
+
2603
+ ### Public surface
2604
+
2605
+ Notification default and `Questionnaire` with timing/check methods.
2606
+
2607
+ Exact exports: `DEFAULT_QUESTIONNAIRE_NOTIFICATION_TIME_MS`, `Questionnaire`.
2608
+
2609
+ ### Availability and normalization
2610
+
2611
+ **Cross-host.** Normalized conservative boolean. Transport: In-process clock only. [Deep protocol details](protocols.md).
2612
+
2613
+ ### Example
2614
+
2615
+ ```javascript
2616
+ import * as module from '/arcane/modules/Questionnaire.js';
2617
+
2618
+ console.log(Object.keys(module));
2619
+ ```
2620
+
2621
+ ## RecordLinkIndex.js
2622
+
2623
+ ### Overview
2624
+
2625
+ Parses record links and builds their normalized index.
2626
+
2627
+ ### Public surface
2628
+
2629
+ `parseRecordLinks()`, `buildRecordLinkIndex()`.
2630
+
2631
+ Exact exports: `buildRecordLinkIndex`, `parseRecordLinks`.
2632
+
2633
+ ### Availability and normalization
2634
+
2635
+ **Cross-host.** Fully normalized. Transport: In-process only. [Deep protocol details](protocols.md).
2636
+
2637
+ ### Example
2638
+
2639
+ ```javascript
2640
+ import * as module from '/arcane/modules/RecordLinkIndex.js';
2641
+
2642
+ console.log(Object.keys(module));
2643
+ ```
2644
+
2645
+ ## RecordPassageIndex.js
2646
+
2647
+ ### Overview
2648
+
2649
+ Indexes text lines, page markers, dates, rules, and excerpts for record review.
2650
+
2651
+ ### Public surface
2652
+
2653
+ Eight text/page/date/rule helper exports.
2654
+
2655
+ Exact exports: `cleanExcerpt`, `extractDateMentions`, `findRulePassages`, `pageAtLine`, `pageMarkers`, `parseDateMention`, `textLines`, `validIsoDate`.
2656
+
2657
+ ### Availability and normalization
2658
+
2659
+ **Cross-host.** Complete selected excerpts and every unique date/rule finding are preserved without character or result-count caps. Transport: In-process only. [Deep protocol details](protocols.md).
2660
+
2661
+ ### Example
2662
+
2663
+ ```javascript
2664
+ import * as module from '/arcane/modules/RecordPassageIndex.js';
2665
+
2666
+ console.log(Object.keys(module));
2667
+ ```
2668
+
2669
+ ## RecordReviewStore.js
2670
+
2671
+ ### Overview
2672
+
2673
+ Stores normalized record-review decisions through native storage or app-scoped local fallback.
2674
+
2675
+ ### Public surface
2676
+
2677
+ default store, record/review normalizers; `load()`, `get()`, `set()`, `snapshot()`, change event.
2678
+
2679
+ Exact exports: `RECORD_REVIEW_STORE_ERROR_CODES`,
2680
+ `RECORD_REVIEW_STORE_EVENT_TYPES`, `default`, `normalizeRecordId`, and
2681
+ `normalizeReview`.
2682
+
2683
+ ### Availability and normalization
2684
+
2685
+ **Browser/native hybrid.** Complete normalized ids, reviews, and snapshots are preserved; unreadable stored records fail with `ARCANE_RECORD_REVIEW_STORED_RECORDS_INVALID` rather than silently becoming an empty store. Transport: Arcane.storage or localStorage. [Deep protocol details](protocols.md).
2686
+
2687
+ ### Example
2688
+
2689
+ ```javascript
2690
+ import * as module from '/arcane/modules/RecordReviewStore.js';
2691
+
2692
+ console.log(Object.keys(module));
2693
+ ```
2694
+
2695
+ ## RiskSignalAnalyzer.js
2696
+
2697
+ ### Overview
2698
+
2699
+ Matches configured risk signals and levels against complete text.
2700
+
2701
+ ### Public surface
2702
+
2703
+ `DEFAULT_LEVELS`, `analyzeRiskSignals()`.
2704
+
2705
+ Exact exports: `DEFAULT_LEVELS`, `analyzeRiskSignals`.
2706
+
2707
+ ### Availability and normalization
2708
+
2709
+ **Cross-host.** Fully normalized. Transport: In-process only. [Deep protocol details](protocols.md).
2710
+
2711
+ ### Example
2712
+
2713
+ ```javascript
2714
+ import * as module from '/arcane/modules/RiskSignalAnalyzer.js';
2715
+
2716
+ console.log(Object.keys(module));
2717
+ ```
2718
+
2719
+ ## ScamRiskPolicy.js
2720
+
2721
+ ### Overview
2722
+
2723
+ Combines deterministic scam signals with optional Arcane blocked-domain evidence and safety guidance.
2724
+
2725
+ ### Public surface
2726
+
2727
+ Signals plus load, assess, and guidance helpers.
2728
+
2729
+ Exact exports: `assessScamRisk`, `loadScamNetworkPolicy`, `scamRiskSignals`, `scamSafetyGuidance`.
2730
+
2731
+ ### Availability and normalization
2732
+
2733
+ **Cross-host.** Complete mutable signal results are returned. Blocked-domain policy inspection is inactive by default and runs only when the caller explicitly selects `secure:true`. Transport: In-process + optional caller-selected Arcane network policy fetch. [Deep protocol details](protocols.md).
2734
+
2735
+ ### Example
2736
+
2737
+ ```javascript
2738
+ import * as module from '/arcane/modules/ScamRiskPolicy.js';
2739
+
2740
+ console.log(Object.keys(module));
2741
+ ```
2742
+
2743
+ ## ScopedOPFSCache.js
2744
+
2745
+ ### Overview
2746
+
2747
+ Provides a narrow exact-key JSON cache inside one app-owned OPFS namespace.
2748
+
2749
+ ### Public surface
2750
+
2751
+ default `ScopedOPFSCache`; support check and get/set/delete APIs.
2752
+
2753
+ Exact exports: `default`.
2754
+
2755
+ ### Availability and normalization
2756
+
2757
+ **Browser / native WebView.** Exact-key options and malformed-JSON handling are
2758
+ normalized; complete JSON values are preserved and storage errors remain
2759
+ visible. Transport: OPFS + AppDataScope. [Deep protocol details](protocols.md).
2760
+
2761
+ ### Example
2762
+
2763
+ ```javascript
2764
+ import * as module from '/arcane/modules/ScopedOPFSCache.js';
2765
+
2766
+ console.log(Object.keys(module));
2767
+ ```
2768
+
2769
+ ## ScreenCapture.js
2770
+
2771
+ ### Overview
2772
+
2773
+ Captures a display surface as image, video, or GIF with explicit lifecycle events.
2774
+
2775
+ ### Public surface
2776
+
2777
+ default `ScreenCapture`; acquire/capture/start/stop/reset methods.
2778
+
2779
+ Exact exports: `SCREEN_CAPTURE_ERROR_CODES`, `SCREEN_CAPTURE_ERRORS`,
2780
+ `SCREEN_CAPTURE_EVENT_TYPES`, `SCREEN_CAPTURE_IMAGE_TYPE_FALLBACK`,
2781
+ `SCREEN_CAPTURE_REASONS`, `SCREEN_CAPTURE_STATUSES`, and `default`.
2782
+
2783
+ ### Availability and normalization
2784
+
2785
+ **Browser / native WebView.** State/events normalized; permission and codec errors mixed. Transport: getDisplayMedia, MediaRecorder, canvas, GifEncoder. [Deep protocol details](protocols.md).
2786
+
2787
+ ### Example
2788
+
2789
+ ```javascript
2790
+ import * as module from '/arcane/modules/ScreenCapture.js';
2791
+
2792
+ console.log(Object.keys(module));
2793
+ ```
2794
+
2795
+ ## SpeechPlayback.js
2796
+
2797
+ ### Overview
2798
+
2799
+ Preserves exact nonblank text as one segment, queues latest-request speech
2800
+ synthesis, and controls lookahead HTML audio playback.
2801
+
2802
+ ### Public surface
2803
+
2804
+ `SpeechPlayback` class/default, `SPEECH_PLAYBACK_STATE_EVENT`,
2805
+ `splitSpeechText()`, and playback lifecycle APIs.
2806
+
2807
+ Exact exports: `SPEECH_PLAYBACK_STATE_EVENT`, `SpeechPlayback`, `default`, and
2808
+ `splitSpeechText`.
2809
+
2810
+ ```text
2811
+ new SpeechPlayback({
2812
+ audio,
2813
+ speech=globalThis.Arcane?.speech,
2814
+ model=null,
2815
+ voice=null,
2816
+ responseFormat=null,
2817
+ speed=1,
2818
+ createObjectURL,
2819
+ revokeObjectURL,
2820
+ delay,
2821
+ messages={}
2822
+ })
2823
+ ```
2824
+
2825
+ `speech` must expose either `fetchTTS(payload, signal)` or
2826
+ `synthesize(payload, {signal})`. `prepare({key,parts,model,voice,responseFormat,
2827
+ speed,autoplay=true})` uses only caller-supplied model, voice, and response-format
2828
+ values; those three omitted values remain omitted so the selected AI/model
2829
+ catalog may provide its documented defaults. Speed defaults to `1`, is normalized
2830
+ as a positive number, and is always sent. There is no
2831
+ hard-coded model, response format, voice, or cloud/browser fallback.
2832
+ `splitSpeechText(value)` uses trimming only to detect blank input, then returns
2833
+ the caller's exact string in one mutable array without trimming, splitting, or
2834
+ freezing it. `prepare()` likewise preserves each nonblank part's exact `input`
2835
+ string while normalizing its other playback fields into a new mutable record.
2836
+ The class applies no part-count, character-count, pause, or input upper cap.
2837
+
2838
+ Every preparation owns an operation ID and one AbortController for each active
2839
+ synthesis segment or playback delay. Replacement,
2840
+ `stop()`, `cancel()`, and `destroy()` abort their owned signals, suppress stale
2841
+ settlement, release Blob URLs, and publish synchronous
2842
+ `speech-playback-state` occurrences through `globalThis.arcaneEvents`.
2843
+ Subscribers receive mutable public state detail. The detail contains
2844
+ `state`, `message`, `key`, `index`, `total`, `producing`, `buffered`, `hasAudio`,
2845
+ `operationId`, `code`, and `reason`; provider rejection remains preserved to the
2846
+ `prepare()` caller. `destroy()` also removes every audio listener and disposes
2847
+ its per-instance canonical source handle; repeated destroy returns
2848
+ `false`. Signal abortion proves delivery suppression; whether provider work
2849
+ actually stops remains the selected provider's cancellation boundary.
2850
+
2851
+ Stable error codes are `ARCANE_SPEECH_PLAYBACK_DESTROYED`,
2852
+ `ARCANE_SPEECH_PLAYBACK_OPERATION_SEQUENCE_EXHAUSTED`,
2853
+ `ARCANE_SPEECH_PLAYBACK_SYNTHESIZER_UNAVAILABLE`,
2854
+ `ARCANE_SPEECH_PLAYBACK_SYNTHESIZED_AUDIO_CONTRACT_MISMATCH`,
2855
+ `ARCANE_SPEECH_PLAYBACK_AUDIO_PLAYBACK_REJECTED`,
2856
+ `ARCANE_SPEECH_PLAYBACK_REQUEST_CONTRACT_MISMATCH`, and
2857
+ `ARCANE_SPEECH_PLAYBACK_SYNTHESIS_REQUEST_REJECTED`, plus propagated
2858
+ `ARCANE_AI_OPERATION_SUPERSEDED` and `ARCANE_AI_REQUEST_ABORTED`.
2859
+ Exact lifecycle reasons are `playback-replaced`, `playback-stopped`,
2860
+ `playback-destroyed`, `speech-playback-cancelled`,
2861
+ `speech-synthesis-superseded`, `speech-synthesis-cancelled`,
2862
+ `speech-synthesizer-unavailable`, `synthesized-audio-contract-mismatch`,
2863
+ `audio-playback-rejected`, `audio-autoplay-rejected`,
2864
+ `speech-playback-request-contract-mismatch`, and
2865
+ `speech-synthesis-rejected`, as applicable to the emitted state.
2866
+
2867
+ ### Availability and normalization
2868
+
2869
+ **Browser + compatible AI/native bridge.** State, cancellation, lifecycle, and
2870
+ playable Blob normalization are shared. Provider/model/runtime/voice selection
2871
+ remains caller- and catalog-owned. Transport: `AI.fetchTTS`, compatible
2872
+ `Arcane.speech.synthesize`, Blob URLs, audio element, and the singleton event
2873
+ authority. [Deep protocol details](protocols.md).
2874
+
2875
+ ### Example
2876
+
2877
+ ```javascript
2878
+ import SpeechPlayback from '/arcane/modules/SpeechPlayback.js';
2879
+
2880
+ const audio = document.body.appendChild(document.createElement('audio'));
2881
+ audio.controls = true;
2882
+ const speech = new SpeechPlayback({
2883
+ audio,
2884
+ speech: globalThis.ai,
2885
+ model: 'caller-selected-model',
2886
+ voice: 'caller-selected-voice',
2887
+ responseFormat: 'wav'
2888
+ });
2889
+ const speakButton = document.body.appendChild(document.createElement('button'));
2890
+ speakButton.type = 'button';
2891
+ speakButton.textContent = 'Speak';
2892
+ speakButton.addEventListener('click', async () => {
2893
+ await speech.prepare({
2894
+ key: 'ready',
2895
+ parts: ['Arcane is ready.'],
2896
+ autoplay: true
2897
+ });
2898
+ });
2899
+ ```
2900
+
2901
+ ## StaticDocumentCatalog.js
2902
+
2903
+ ### Overview
2904
+
2905
+ Loads a positive static document inventory with cache, search, and complete context.
2906
+
2907
+ ### Public surface
2908
+
2909
+ default catalog, schema constant, catalog normalizer/cache-key; list/get/search/hydrate/context APIs.
2910
+
2911
+ Exact exports: `CATALOG_SCHEMA_VERSION`, `default`, `normalizeStaticDocumentCatalog`, `staticDocumentCacheKey`.
2912
+
2913
+ ### Availability and normalization
2914
+
2915
+ **Browser / native WebView / server with fetch.** Catalog/content normalization
2916
+ preserves complete mutable documents; malformed catalog/content and transport
2917
+ failures remain visible. Transport: HTTP(S) and optional cache. [Deep protocol details](protocols.md).
2918
+
2919
+ ### Example
2920
+
2921
+ ```javascript
2922
+ import * as module from '/arcane/modules/StaticDocumentCatalog.js';
2923
+
2924
+ console.log(Object.keys(module));
2925
+ ```
2926
+
2927
+ ## SystemAppearance.js
2928
+
2929
+ ### Overview
2930
+
2931
+ Reads or applies native appearance, returning an explicit unsupported browser state when no bridge exists.
2932
+
2933
+ ### Public surface
2934
+
2935
+ default `SystemAppearance`; `available()`, `current()`, `apply()`.
2936
+
2937
+ Exact exports: `default`.
2938
+
2939
+ ### Availability and normalization
2940
+
2941
+ **Browser/native hybrid.** Absent bridge normalized; native result/error preserved. Transport: Arcane.appearance. [Deep protocol details](protocols.md).
2942
+
2943
+ ### Example
2944
+
2945
+ ```javascript
2946
+ import * as module from '/arcane/modules/SystemAppearance.js';
2947
+
2948
+ console.log(Object.keys(module));
2949
+ ```
2950
+
2951
+ ## SystemPlatformPresentation.js
2952
+
2953
+ ### Overview
2954
+
2955
+ Maps kernel names to presentation labels/classes without granting platform authority.
2956
+
2957
+ ### Public surface
2958
+
2959
+ No ESM exports; global `ArcaneSystemPlatformPresentation` with `kernelType()`, `displayName()`, `apply()`.
2960
+
2961
+ This is a classic global script and has no ESM exports.
2962
+
2963
+ ### Availability and normalization
2964
+
2965
+ **Browser / native WebView classic script.** Fully normalized presentation only. Transport: DOM. [Deep protocol details](protocols.md).
2966
+
2967
+ ### Example
2968
+
2969
+ ```html
2970
+ <script src="/arcane/modules/SystemPlatformPresentation.js"></script>
2971
+ ```
2972
+
2973
+ ## SystemToolRegistry.js
2974
+
2975
+ ### Overview
2976
+
2977
+ Registers validated command builders and constructs command strings without executing them.
2978
+
2979
+ ### Public surface
2980
+
2981
+ default registry, `quoteArgument()`, register/list/get/build APIs.
2982
+
2983
+ Exact exports: `default`, `quoteArgument`.
2984
+
2985
+ ### Availability and normalization
2986
+
2987
+ **Cross-host.** Fully normalized definitions/quoting. Transport: In-process only. [Deep protocol details](protocols.md).
2988
+
2989
+ ### Example
2990
+
2991
+ ```javascript
2992
+ import * as module from '/arcane/modules/SystemToolRegistry.js';
2993
+
2994
+ console.log(Object.keys(module));
2995
+ ```
2996
+
2997
+ ## TerminalClient.js
2998
+
2999
+ ### Overview
3000
+
3001
+ Maps native terminal sessions and Arcane events into an EventTarget client.
3002
+
3003
+ ### Public surface
3004
+
3005
+ default `TerminalClient`; start/write/resize/signal/close/receive/destroy APIs and terminal events.
3006
+
3007
+ Exact exports: `TERMINAL_CLIENT_ERROR_CODES`, `TERMINAL_CLIENT_EVENT_TYPES`,
3008
+ `TERMINAL_CLIENT_REASONS`, and `default`.
3009
+
3010
+ ### Availability and normalization
3011
+
3012
+ **Native bridge.** Client events/state normalized; native result/error mixed. Transport: Arcane.terminal + Arcane.events. [Deep protocol details](protocols.md).
3013
+
3014
+ ### Example
3015
+
3016
+ ```javascript
3017
+ import * as module from '/arcane/modules/TerminalClient.js';
3018
+
3019
+ console.log(Object.keys(module));
3020
+ ```
3021
+
3022
+ ## TerminalCommandRegistry.js
3023
+
3024
+ ### Overview
3025
+
3026
+ Routes parsed command lines to injected handlers and provides definitions/completions.
3027
+
3028
+ ### Public surface
3029
+
3030
+ default registry, `splitCommandLine()`, register/resolve/definitions/completions/execute APIs.
3031
+
3032
+ Exact exports: `default`, `splitCommandLine`.
3033
+
3034
+ ### Availability and normalization
3035
+
3036
+ **Cross-host.** Parsing/routing normalized; handler result/error preserved. Transport: Injected handlers. [Deep protocol details](protocols.md).
3037
+
3038
+ ### Example
3039
+
3040
+ ```javascript
3041
+ import * as module from '/arcane/modules/TerminalCommandRegistry.js';
3042
+
3043
+ console.log(Object.keys(module));
3044
+ ```
3045
+
3046
+ ## ThemeBootstrap.js
3047
+
3048
+ ### Overview
3049
+
3050
+ Performs import-time Arcane theme loading and subscribes to native appearance changes.
3051
+
3052
+ ### Public surface
3053
+
3054
+ `bootstrapArcaneTheme()`, `arcaneThemeReady`, default ready promise.
3055
+
3056
+ Exact exports: `arcaneThemeReady`, `bootstrapArcaneTheme`, `default`, and
3057
+ `disposeArcaneThemeBootstrap`.
3058
+
3059
+ ### Availability and normalization
3060
+
3061
+ **Browser/native hybrid.** Theme state normalized; storage/native errors mixed. Transport: ThemeManager + Arcane.events. [Deep protocol details](protocols.md).
3062
+
3063
+ ### Example
3064
+
3065
+ ```javascript
3066
+ import * as module from '/arcane/modules/ThemeBootstrap.js';
3067
+
3068
+ console.log(Object.keys(module));
3069
+ ```
3070
+
3071
+ ## ThemeManager.js
3072
+
3073
+ ### Overview
3074
+
3075
+ Loads, applies, previews, saves, resets, and synchronizes semantic Arcane themes.
3076
+
3077
+ ### Public surface
3078
+
3079
+ default `ThemeManager`, `loadAndApplyTheme()`; scheme/custom/system APIs and `arcane-theme-change`.
3080
+
3081
+ Exact exports: `default`, `loadAndApplyTheme`.
3082
+
3083
+ ### Availability and normalization
3084
+
3085
+ **Browser/native hybrid.** Theme values/events normalized; storage/native failures mixed. Transport: PreferenceStore, DOM, Arcane.appearance. [Deep protocol details](protocols.md).
3086
+
3087
+ ### Example
3088
+
3089
+ ```javascript
3090
+ import * as module from '/arcane/modules/ThemeManager.js';
3091
+
3092
+ console.log(Object.keys(module));
3093
+ ```
3094
+
3095
+ ## TimeGuard.js
3096
+
3097
+ ### Overview
3098
+
3099
+ Persists and evaluates clock rollback and grace-period state.
3100
+
3101
+ ### Public surface
3102
+
3103
+ default `TimeGuard`; installs `window.timeguard`, emits `time-guard-ready`; clock methods.
3104
+
3105
+ Exact exports: `default`.
3106
+
3107
+ ### Availability and normalization
3108
+
3109
+ **Browser / native WebView.** Time decisions normalized; storage lifecycle mixed. Transport: User + DBOPFS. [Deep protocol details](protocols.md).
3110
+
3111
+ ### Example
3112
+
3113
+ ```javascript
3114
+ import * as module from '/arcane/modules/TimeGuard.js';
3115
+
3116
+ console.log(Object.keys(module));
3117
+ ```
3118
+
3119
+ ## ToolCallRouter.js
3120
+
3121
+ ### Overview
3122
+
3123
+ Parses OpenAI-style complete responses or streamed name-keyed call records,
3124
+ validates each argument record, and dispatches it to an injected handler.
3125
+
3126
+ ### Public surface
3127
+
3128
+ `parseArguments()`, `handleResponse()`, `handleStreamedCalls()`.
3129
+
3130
+ `parseArguments()` accepts JSON text or a plain argument object whose prototype
3131
+ is `Object.prototype` or `null`, requires a nonempty user-facing `message`, and
3132
+ returns the parsed object without cloning, freezing, or reserialization.
3133
+ Missing, blank, null, array, custom-prototype, or otherwise invalid argument
3134
+ records fail with `AI_TOOL_MESSAGE_REQUIRED`. Complete-response handlers run
3135
+ sequentially and return one result or an array; streamed handlers return
3136
+ `Promise.allSettled()` results. A routed call is not settled merely because it
3137
+ was displayed: the conversation owner must still append the exact matching
3138
+ executed, declined, cancelled, or not-executed `role:'tool'` result before the
3139
+ next user turn.
3140
+
3141
+ Exact exports: `handleResponse`, `handleStreamedCalls`, `parseArguments`.
3142
+
3143
+ ### Availability and normalization
3144
+
3145
+ **Cross-host.** Argument records validated; handler results returned or
3146
+ all-settled. Transport: Injected handlers. [Deep protocol details](protocols.md).
3147
+
3148
+ ### Example
3149
+
3150
+ ```javascript
3151
+ import * as module from '/arcane/modules/ToolCallRouter.js';
3152
+
3153
+ console.log(Object.keys(module));
3154
+ ```
3155
+
3156
+ ## uPlot.iife.min.js
3157
+
3158
+ ### Overview
3159
+
3160
+ Vendored uPlot chart constructor and rendering runtime.
3161
+
3162
+ ### Public surface
3163
+
3164
+ No ESM exports; global `uPlot` with data/series/scale/cursor/hook/selection/destroy APIs.
3165
+
3166
+ This is a classic global script and has no ESM exports.
3167
+
3168
+ ### Availability and normalization
3169
+
3170
+ **Browser vendor script.** Vendor-native. Transport: Classic script + canvas/DOM. [Deep protocol details](protocols.md).
3171
+
3172
+ ### Example
3173
+
3174
+ ```html
3175
+ <script src="/arcane/modules/uPlot.iife.min.js"></script>
3176
+ ```
3177
+
3178
+ ## uPlot.LICENSE.txt
3179
+
3180
+ ### Overview
3181
+
3182
+ License companion for the bundled uPlot vendor runtime.
3183
+
3184
+ ### Public surface
3185
+
3186
+ MIT license text.
3187
+
3188
+ ### Availability and normalization
3189
+
3190
+ **Documentation asset.** Not executable. Transport: None. [Deep protocol details](protocols.md).
3191
+
3192
+ ### Example
3193
+
3194
+ ```text
3195
+ /arcane/modules/uPlot.LICENSE.txt
3196
+ ```
3197
+
3198
+ ## uPlot.min.css
3199
+
3200
+ ### Overview
3201
+
3202
+ Bundled uPlot presentation stylesheet.
3203
+
3204
+ ### Public surface
3205
+
3206
+ Load with a stylesheet link before rendering uPlot charts.
3207
+
3208
+ ### Availability and normalization
3209
+
3210
+ **Browser stylesheet.** Presentation only. Transport: CSS. [Deep protocol details](protocols.md).
3211
+
3212
+ ### Example
3213
+
3214
+ ```html
3215
+ <link rel="stylesheet" href="/arcane/modules/uPlot.min.css">
3216
+ ```
3217
+
3218
+ ## WaitForComponent.js
3219
+
3220
+ ### Overview
3221
+
3222
+ Waits for a component property, method, or readiness event with optional error event and bounded timeout.
3223
+
3224
+ ### Public surface
3225
+
3226
+ default `waitForComponent()`.
3227
+
3228
+ Exact exports: `COMPONENT_WAIT_ERROR_CODES`, `COMPONENT_WAIT_REASONS`, and
3229
+ `default`.
3230
+
3231
+ ### Availability and normalization
3232
+
3233
+ **Cross-host EventTarget / browser component.** Normalized coded readiness, error, and timeout results. Transport: EventTarget + timers. [Deep protocol details](protocols.md).
3234
+
3235
+ ### Example
3236
+
3237
+ ```javascript
3238
+ import * as module from '/arcane/modules/WaitForComponent.js';
3239
+
3240
+ console.log(Object.keys(module));
3241
+ ```
3242
+
3243
+ ## YouTubeMedia.js
3244
+
3245
+ ### Overview
3246
+
3247
+ Parses YouTube video/playlist locators and constructs ordinary embed URLs by
3248
+ default, with privacy enhancement only when the caller selects it.
3249
+
3250
+ ### Public surface
3251
+
3252
+ `parseYouTubeMedia()`, `youtubeEmbedUrl()`.
3253
+
3254
+ Exact exports: `parseYouTubeMedia`, `youtubeEmbedUrl`.
3255
+
3256
+ ### Availability and normalization
3257
+
3258
+ **Cross-host.** Bare video IDs and supported URLs normalize to mutable locators;
3259
+ `youtubeEmbedUrl(locator,{privacyEnhanced:false})` is the default and
3260
+ `privacyEnhanced:true` explicitly selects the privacy-enhanced host. Transport:
3261
+ URL construction only. [Deep protocol details](protocols.md).
3262
+
3263
+ ### Example
3264
+
3265
+ ```javascript
3266
+ import * as module from '/arcane/modules/YouTubeMedia.js';
3267
+
3268
+ console.log(Object.keys(module));
3269
+ ```
3270
+
3271
+ ## Entity and component continuations
3272
+
3273
+ - [Runtime entity modules](runtime-entities.md) explains all 14 modules, and [shared entity contracts](core/arcane-entities.md) owns all 29 exports.
3274
+ - [Runtime components](runtime-components.md) owns all 39 HTML-import fragments, methods, slots, and events.
3275
+ - [Arcane Ollama](arcane-ollama.md) expands the raw-versus-normalized behavior of `Ollama.js`.