arcane-os 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,6 +72,7 @@ own asynchronous work, cancellation, and backpressure.
72
72
  | [`CommunicationProviderRegistry.js`](#communicationproviderregistryjs) | esm | Registers and queries validated provider definitions, channels, and required methods. | Cross-host | Strict normalized registry. |
73
73
  | [`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. |
74
74
  | [`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. |
75
+ | [`ContinuousVoiceCapture.js`](#continuousvoicecapturejs) | esm | Owns continuous microphone capture with pre-roll, pause/periodic WAV segments, final flush, and cancellation. | Browser / native WebView with AudioWorklet | Complete ordered clips; audio activity and timing are normalized, microphone availability remains browser-owned. |
75
76
  | [`ConversationActionItems.js`](#conversationactionitemsjs) | esm | Normalizes, creates, updates, remembers, selects, and formats complete conversation action items. | Cross-host | Fully normalized status/base/presentation contract. |
76
77
  | [`ConversationClosingReport.js`](#conversationclosingreportjs) | esm | Defines the closing-report tool, instruction, result normalizer, call classifier, and formatter. | Cross-host | Fully normalized report contract. |
77
78
  | [`ConversationTimebox.js`](#conversationtimeboxjs) | esm | Owns conversation limits, control messages, submission barriers, elapsed formatting, and delivery proof. | Cross-host | Fully normalized state/command/delivery errors. |
@@ -131,6 +132,7 @@ own asynchronous work, cancellation, and backpressure.
131
132
  | [`uPlot.iife.min.js`](#uplotiifeminjs) | classic-script | Vendored uPlot chart constructor and rendering runtime. | Browser vendor script | Vendor-native. |
132
133
  | [`uPlot.LICENSE.txt`](#uplotlicensetxt) | license | License companion for the bundled uPlot vendor runtime. | Documentation asset | Not executable. |
133
134
  | [`uPlot.min.css`](#uplotmincss) | stylesheet | Bundled uPlot presentation stylesheet. | Browser stylesheet | Presentation only. |
135
+ | [`VoiceCaptureWorklet.js`](#voicecaptureworkletjs) | worker | Segments and encodes continuous microphone audio on the audio rendering thread. | AudioWorkletGlobalScope | Rolling pre-roll, activity/quiet/periodic boundaries, complete WAV clips, and final stop acknowledgement. |
134
136
  | [`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. |
135
137
  | [`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. |
136
138
 
@@ -1637,7 +1639,15 @@ behavior for chart, dashboard, Markdown, and voice components.
1637
1639
  ### Public surface
1638
1640
 
1639
1641
  Constant sets plus normalization, formatting, and explicit STT activation
1640
- helpers. `createSTTActivationController({host,button,progress=null,onChange,EventClass=CustomEvent})`
1642
+ helpers. `normalizeVoiceOptions(input,previous)` keeps `capture.mode:'manual'`
1643
+ and `controls:'standard'` as defaults. Continuous capture accepts
1644
+ `{mode:'continuous',preRollMs:1500,quietMs:2000,chunkMs:30000,activityThreshold:0.02}`;
1645
+ `controls:'simple'`, `showComplete`, and the `retry`/`cancel` labels configure
1646
+ the shared voice component. Positive quiet/chunk durations and nonnegative
1647
+ pre-roll/activity values must be finite. Complete callback payloads remain
1648
+ owned by the component and application.
1649
+
1650
+ `createSTTActivationController({host,button,progress=null,onChange,EventClass=CustomEvent})`
1641
1651
  consumes only normalized
1642
1652
  [`AIRuntimeState`](#airuntimestatejs) `stt` role records. Its mutable controller
1643
1653
  exposes `action`, `error`, `label`, `pending`, `selected`, `status`, `title`, and
@@ -1797,6 +1807,76 @@ const session = new ConfiguredAIChatSession({
1797
1807
  console.log(await session.send('Hello'));
1798
1808
  ```
1799
1809
 
1810
+ ## ContinuousVoiceCapture.js
1811
+
1812
+ ### Overview
1813
+
1814
+ Owns a continuous microphone session whose audio worklet keeps rolling
1815
+ pre-roll and produces complete clips at quiet or periodic boundaries. The
1816
+ capture owner has no model, transcription, persistence, or application policy.
1817
+ The shared [`voice-transcription.html`](runtime-components.md#voice-transcriptionhtml)
1818
+ component adds ordered STT, persistence, retry, and presentation.
1819
+
1820
+ ### Public surface
1821
+
1822
+ Default export `ContinuousVoiceCapture` accepts
1823
+ `{preRollMs=1500,quietMs=2000,chunkMs=30000,activityThreshold=0.02,onSegment,onError,onState}`.
1824
+ `start({mediaConstraints={audio:true},signal}={})` acquires microphone input and
1825
+ resolves `true` once capture starts, or `false` after cancellation or a
1826
+ reported start failure. Starting capture is an explicit caller action.
1827
+
1828
+ `onSegment({audio,sequence,reason,durationMs})` receives a complete
1829
+ `audio/wav` Blob containing mono Float32 audio. Sequence starts at one for
1830
+ each capture session; reason is `pause`, `periodic`, or `stop`. The detector
1831
+ uses amplitude to find activity, including noise; it does not determine
1832
+ whether a person is speaking. Inactive windows produce no clips. Pre-roll is
1833
+ used once when activity starts, and periodic segments remain adjacent without
1834
+ repeated samples. Pre-roll longer than `chunkMs` remains complete in the first
1835
+ active clip, so that clip may exceed the periodic duration.
1836
+
1837
+ `stop()` releases microphone tracks immediately and returns a promise that
1838
+ settles after the worklet flushes the final active clip and acknowledges stop.
1839
+ Capture cancellation while microphone permission or worklet loading is
1840
+ pending releases late-acquired resources. `cancel()` and `destroy()` discard
1841
+ pending capture and suppress late segment delivery. They do not cancel
1842
+ application work that already accepted a segment; its owner supplies that
1843
+ cancellation boundary. The optional signal cancels this capture session.
1844
+
1845
+ `onState` reports `starting`, `listening`, `stopped`, or `interrupted`;
1846
+ `onError` receives the original capture error. A naturally ended microphone
1847
+ flushes the active clip before reporting interruption while the worklet remains
1848
+ available. A failed audio context or processor reports interruption directly;
1849
+ audio still inside an unavailable processor cannot be recovered. Callback
1850
+ promises are observed without delaying capture or stop acknowledgement.
1851
+ Capture state is independent
1852
+ of model readiness, STT processing, and application save state.
1853
+
1854
+ ### Availability and normalization
1855
+
1856
+ **Browser / supported native WebView.** Requires browser microphone access,
1857
+ `AudioContext`, and `AudioWorklet`. Browser secure-context and permission rules
1858
+ apply at those platform APIs. The static sibling
1859
+ [`VoiceCaptureWorklet.js`](#voicecaptureworkletjs) owns sample processing and
1860
+ WAV encoding on the audio rendering thread. No audio model or third-party
1861
+ capture runtime is loaded. Native hosts use the same browser APIs where
1862
+ available, with no Core service selected implicitly.
1863
+
1864
+ ### Example
1865
+
1866
+ ```javascript
1867
+ import ContinuousVoiceCapture from '/arcane/modules/ContinuousVoiceCapture.js';
1868
+
1869
+ const capture=new ContinuousVoiceCapture({
1870
+ onSegment:queueTranscription,
1871
+ onError:showCaptureError,
1872
+ onState:showCaptureState
1873
+ });
1874
+ // Call from the application's explicit recording action.
1875
+ await capture.start();
1876
+ // The application's stop action waits for the final clip.
1877
+ await capture.stop();
1878
+ ```
1879
+
1800
1880
  ## ConversationActionItems.js
1801
1881
 
1802
1882
  ### Overview
@@ -3794,6 +3874,34 @@ Load with a stylesheet link before rendering uPlot charts.
3794
3874
  <link rel="stylesheet" href="/arcane/modules/uPlot.min.css">
3795
3875
  ```
3796
3876
 
3877
+ ## VoiceCaptureWorklet.js
3878
+
3879
+ ### Overview
3880
+
3881
+ Internal audio processor for [`ContinuousVoiceCapture.js`](#continuousvoicecapturejs).
3882
+ It keeps rolling pre-roll, detects audio amplitude, preserves complete active
3883
+ audio through quiet and periodic cuts, and encodes mono Float32 WAV clips on
3884
+ the audio rendering thread. It performs no semantic speech detection or STT.
3885
+
3886
+ ### Public surface
3887
+
3888
+ No ESM exports. The capture owner loads this static file with
3889
+ `audioContext.audioWorklet.addModule()` and creates the
3890
+ `arcane-continuous-voice-capture` processor with
3891
+ `{preRollMs,quietMs,chunkMs,activityThreshold}` in `processorOptions`.
3892
+ The owner sends `{type:'stop'}`. The processor transfers each complete
3893
+ `{type:'segment',audio:ArrayBuffer,sampleRate,sequence,reason,durationMs}`
3894
+ and finally `{type:'stopped'}`. Each complete WAV includes its own format,
3895
+ sample-count, and data framing. Quiet-only capture emits no segments, and
3896
+ periodic segments never repeat samples.
3897
+
3898
+ ### Availability and normalization
3899
+
3900
+ **AudioWorkletGlobalScope only.** This is an owner-local native MessagePort
3901
+ protocol, with no separate event bus, model request, or persistence. Applications
3902
+ use `ContinuousVoiceCapture` or the shared voice component rather than importing
3903
+ this processor in a document or Worker.
3904
+
3797
3905
  ## WaitForComponent.js
3798
3906
 
3799
3907
  ### Overview
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
@@ -86,7 +86,7 @@
86
86
  "test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
87
87
  "test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
88
88
  "test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
89
- "test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
89
+ "test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
90
90
  "test:integration": "node ./bin/arcane-test.mjs test/installed-package-runtime.test.mjs test/root-app-layout.test.mjs test/integrated-shared.test.mjs test/integrated-workspace.test.mjs test/mail-browser.test.mjs test/native-plan.test.mjs test/native-provider-loader.test.mjs test/npm-release.test.mjs test/release-bundle.test.mjs test/release-capability-smoke.test.mjs test/shared-payload-batch.test.mjs test/tarball.test.mjs test/browser-wasm-cpu.test.mjs test/wllama-webgpu-runtime.test.mjs",
91
91
  "test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/logging-regression.test.mjs test/markdown-speech.test.mjs test/prepared-speech.test.mjs test/native-provider-generation.test.mjs test/speech-queue-regression.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
92
92
  "check": "node tools/check-source.mjs && npm test",
@@ -85,12 +85,12 @@
85
85
 
86
86
  heading.innerText=host.dataset.title||'Data';
87
87
  fileManager.className='file-manager';
88
- fileManager.previewTransform=host.previewTransform;
88
+ forwardPreviewOptions();
89
89
  fileManager.dataset.dirs=host.dataset.dirs||'';
90
90
  fileManager.dataset.layout=host.dataset.layout||'files';
91
91
  fileManager.setAttribute(
92
92
  'href',
93
- new URL('./file-manager.html?v=18',componentHref).href
93
+ new URL('./file-manager.html?v=19',componentHref).href
94
94
  );
95
95
 
96
96
  content.append(heading,fileManager);
@@ -100,6 +100,10 @@
100
100
  }
101
101
  }
102
102
 
103
+ if(reload){
104
+ forwardPreviewOptions();
105
+ }
106
+
103
107
  const manager=await waitForComponent(
104
108
  fileManager,
105
109
  {
@@ -124,6 +128,18 @@
124
128
  return true;
125
129
  }
126
130
 
131
+ function forwardPreviewOptions(){
132
+ fileManager.previewTransform=host.previewTransform;
133
+ fileManager.previewDescriptor=host.previewDescriptor;
134
+ fileManager.directoryFilter=host.directoryFilter;
135
+ if(host.dataset.hiddenPrefixes===undefined){
136
+ delete fileManager.dataset.hiddenPrefixes;
137
+ }else{
138
+ fileManager.dataset.hiddenPrefixes=host.dataset.hiddenPrefixes;
139
+ }
140
+ fileManager.toggleAttribute('data-show-hidden',host.hasAttribute('data-show-hidden'));
141
+ }
142
+
127
143
  function destroy(){
128
144
  if(destroyed){
129
145
  return false;