arcane-os 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +86 -117
  3. package/bin/arcane-test.mjs +170 -46
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +887 -909
  5. package/browser-runtime/ai/browser-speech-providers.mjs +96 -152
  6. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +627 -819
  7. package/browser-runtime/ai/browser-wasm.mjs +24 -35
  8. package/browser-runtime/ai/browser-wllama-runtime.mjs +64 -316
  9. package/browser-runtime/ai/model-controller.mjs +584 -181
  10. package/browser-runtime/ai/speech-worker-client.mjs +8 -146
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +643 -363
  12. package/browser-runtime/dom-event-instrumentation.mjs +55 -147
  13. package/browser-runtime/event-manager.mjs +239 -624
  14. package/package.json +5 -6
  15. package/runtime/arcane/components/app-bar.html +3 -15
  16. package/runtime/arcane/components/assistant-panel.html +10 -10
  17. package/runtime/arcane/components/calculator.html +1 -1
  18. package/runtime/arcane/components/chat.html +1359 -135
  19. package/runtime/arcane/components/conversation-view.html +2 -2
  20. package/runtime/arcane/components/document-inspector.html +11 -17
  21. package/runtime/arcane/components/file-manager.html +13 -56
  22. package/runtime/arcane/components/markdown-document.html +82 -281
  23. package/runtime/arcane/components/markdown-editor.html +7 -10
  24. package/runtime/arcane/components/media-embed.html +6 -6
  25. package/runtime/arcane/components/screen-capture.html +4 -4
  26. package/runtime/arcane/components/source-explanation.html +2 -2
  27. package/runtime/arcane/components/speech.html +112 -68
  28. package/runtime/arcane/components/terminal-workspace.html +4 -4
  29. package/runtime/arcane/components/theme-editor.html +1 -1
  30. package/runtime/arcane/components/unified-inbox.html +2 -2
  31. package/runtime/arcane/components/voice-transcription.html +31 -21
  32. package/runtime/arcane/entities/Calculation.js +2 -3
  33. package/runtime/arcane/entities/Chat.js +228 -43
  34. package/runtime/arcane/entities/Preference.js +3 -5
  35. package/runtime/arcane/entities/Weather.js +5 -5
  36. package/runtime/arcane/modules/AI.js +1050 -427
  37. package/runtime/arcane/modules/AIProviderRuntime.js +658 -363
  38. package/runtime/arcane/modules/AIResponseLength.js +9 -19
  39. package/runtime/arcane/modules/AIRuntimeState.js +109 -72
  40. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +45 -32
  41. package/runtime/arcane/modules/BrowserTestSuite.js +78 -122
  42. package/runtime/arcane/modules/CalculatorEngine.js +9 -9
  43. package/runtime/arcane/modules/CommunicationAppController.js +3 -7
  44. package/runtime/arcane/modules/ComponentContracts.js +30 -32
  45. package/runtime/arcane/modules/ConfiguredAIChatSession.js +281 -230
  46. package/runtime/arcane/modules/ConversationActionItems.js +26 -59
  47. package/runtime/arcane/modules/ConversationClosingReport.js +34 -61
  48. package/runtime/arcane/modules/ConversationTimebox.js +27 -15
  49. package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +152 -344
  50. package/runtime/arcane/modules/DocumentLexicalSearch.js +25 -91
  51. package/runtime/arcane/modules/HTMLImport.js +54 -1
  52. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +40 -203
  53. package/runtime/arcane/modules/LocalAIReadiness.js +40 -60
  54. package/runtime/arcane/modules/LocalAIReadinessController.js +15 -13
  55. package/runtime/arcane/modules/MD.js +1 -45
  56. package/runtime/arcane/modules/Mail.js +51 -103
  57. package/runtime/arcane/modules/MailOutbox.mjs +95 -193
  58. package/runtime/arcane/modules/MailTransport.mjs +36 -57
  59. package/runtime/arcane/modules/ModelDefinition.js +22 -106
  60. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +39 -101
  61. package/runtime/arcane/modules/PersistentAIChatSession.js +281 -18
  62. package/runtime/arcane/modules/PreferenceStore.js +102 -30
  63. package/runtime/arcane/modules/RiskSignalAnalyzer.js +8 -9
  64. package/runtime/arcane/modules/ScopedOPFSCache.js +7 -42
  65. package/runtime/arcane/modules/ScreenCapture.js +175 -128
  66. package/runtime/arcane/modules/SpeechPlayback.js +46 -149
  67. package/runtime/arcane/modules/StaticDocumentCatalog.js +173 -407
  68. package/runtime/arcane/modules/ToolCallRouter.js +25 -12
  69. package/runtime/arcane/modules/YouTubeMedia.js +6 -5
  70. package/schemas/arcane-app-bundle.schema.json +13 -78
  71. package/schemas/arcane-app.schema.json +9 -25
  72. package/schemas/arcane-lock.schema.json +18 -151
  73. package/schemas/arcane-package.schema.json +2 -16
  74. package/schemas/native-build-plan.schema.json +119 -122
  75. package/src/app-descriptor.mjs +75 -132
  76. package/src/application-tests.mjs +200 -0
  77. package/src/cli/main.mjs +27 -46
  78. package/src/constants.mjs +3 -4
  79. package/src/dev-server.mjs +30 -324
  80. package/src/doctor.mjs +92 -154
  81. package/src/dom-event-instrumentation.mjs +55 -147
  82. package/src/errors.mjs +2 -3
  83. package/src/event-manager.mjs +239 -624
  84. package/src/event-queue.mjs +3 -3
  85. package/src/import-map.mjs +273 -1028
  86. package/src/index.mjs +14 -16
  87. package/src/installed-sdk-runtime.mjs +40 -62
  88. package/src/integrated-provider-loader.mjs +53 -382
  89. package/src/mail-api.mjs +0 -2
  90. package/src/mail-server.mjs +224 -580
  91. package/src/mail.mjs +4 -10
  92. package/src/native-plan.mjs +163 -598
  93. package/src/native-provider-loader.mjs +104 -1063
  94. package/src/packager/core.mjs +485 -3229
  95. package/src/process.mjs +5 -10
  96. package/src/release-bundle.mjs +292 -2405
  97. package/src/runtime.mjs +76 -396
  98. package/src/scaffold.mjs +30 -80
  99. package/src/sdk-browser-runtime.mjs +70 -626
  100. package/src/source-server.mjs +588 -0
  101. package/src/targets/index.mjs +78 -188
  102. package/src/templates/workspace-template.mjs +19 -135
  103. package/src/testing-loader.mjs +164 -0
  104. package/src/testing.mjs +1 -1
  105. package/src/toolchain.mjs +131 -544
  106. package/src/update-check.mjs +26 -64
  107. package/src/workspace-operation-lock.mjs +139 -430
  108. package/src/workspace-runtime.mjs +112 -779
  109. package/src/workspace.mjs +40 -302
  110. package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +0 -218
  111. package/browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json +0 -203
  112. package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +0 -80
  113. package/browser-runtime/ai/internal/sha256.mjs +0 -166
  114. package/docs/architecture.md +0 -344
  115. package/docs/compatibility.md +0 -36
  116. package/docs/event-manager.md +0 -294
  117. package/docs/platform-targets.md +0 -108
  118. package/docs/publishing.md +0 -201
  119. package/docs/reference/README.md +0 -187
  120. package/docs/reference/ai/browser-speech-package-authority.json +0 -835
  121. package/docs/reference/ai/browser-speech.md +0 -1252
  122. package/docs/reference/ai/browser-wasm.md +0 -530
  123. package/docs/reference/arcane-ollama.md +0 -288
  124. package/docs/reference/availability-and-normalization.md +0 -183
  125. package/docs/reference/behavioral-testing.md +0 -133
  126. package/docs/reference/cli.md +0 -779
  127. package/docs/reference/core/README.md +0 -62
  128. package/docs/reference/core/arcane-ai-contracts.md +0 -907
  129. package/docs/reference/core/arcane-api.md +0 -601
  130. package/docs/reference/core/arcane-entities.md +0 -65
  131. package/docs/reference/core/arcane-events.md +0 -134
  132. package/docs/reference/core/ollama-module.md +0 -181
  133. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +0 -1909
  134. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +0 -1057
  135. package/docs/reference/core/reference/arcane-api/core-and-events.md +0 -320
  136. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +0 -610
  137. package/docs/reference/core/reference/arcane-api/namespaces.md +0 -1157
  138. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +0 -1423
  139. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +0 -315
  140. package/docs/reference/event-manager.md +0 -1511
  141. package/docs/reference/inventory/package-api.json +0 -3284
  142. package/docs/reference/inventory/runtime-components.json +0 -1011
  143. package/docs/reference/inventory/runtime-entities.json +0 -26
  144. package/docs/reference/inventory/runtime-modules.json +0 -1431
  145. package/docs/reference/mail.md +0 -316
  146. package/docs/reference/protocols.md +0 -677
  147. package/docs/reference/runtime-components.md +0 -1366
  148. package/docs/reference/runtime-entities.md +0 -303
  149. package/docs/reference/runtime-modules.md +0 -2960
  150. package/docs/reference/sdk-api.md +0 -6694
  151. package/docs/roadmap.md +0 -79
  152. package/docs/work-amplification.md +0 -129
  153. package/runtime/ARCANE_RUNTIME_RELEASE.json +0 -826
@@ -5,9 +5,7 @@ import {SDK_NAME,SDK_VERSION} from './constants.mjs';
5
5
  export const SDK_UPDATE_REGISTRY='https://registry.npmjs.org/';
6
6
  export const SDK_UPDATE_TIMEOUT_MS=2500;
7
7
 
8
- const MAX_RESPONSE_BYTES=32*1024;
9
- const MAX_DIST_TAGS=64;
10
- const DIST_TAG_PATTERN=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
8
+ const DIST_TAG_PATTERN=/^[A-Za-z0-9][A-Za-z0-9._-]*$/u;
11
9
  const FORBIDDEN_DIST_TAG_KEYS=new Set(['__proto__','constructor','prototype']);
12
10
 
13
11
  function updateFailure(message,{cause,details}={}){
@@ -25,25 +23,15 @@ function canonicalPackageName(value){
25
23
  return value;
26
24
  }
27
25
 
28
- export function validateUpdateRegistry(value,{
29
- allowedHosts=new Set(['registry.npmjs.org'])
30
- }={}){
26
+ export function validateUpdateRegistry(value){
31
27
  let registry;
32
28
  try{
33
29
  registry=new URL(value);
34
30
  }catch(error){
35
31
  throw updateFailure('The SDK update registry URL is invalid.',{cause:error});
36
32
  }
37
- if(registry.protocol!=='https:'
38
- ||registry.username||registry.password
39
- ||registry.search||registry.hash
40
- ||registry.pathname!=='/'
41
- ||(registry.port&&registry.port!=='443')
42
- ||!allowedHosts.has(registry.hostname.toLowerCase())){
43
- throw updateFailure(
44
- 'The SDK update registry must be an approved credential-free HTTPS origin.',
45
- {details:{registryOrigin:registry.origin}}
46
- );
33
+ if(!['http:','https:'].includes(registry.protocol)){
34
+ throw updateFailure('The SDK update registry must use HTTP or HTTPS.');
47
35
  }
48
36
  return registry;
49
37
  }
@@ -53,8 +41,8 @@ function registryEndpoint(registry,packageName){
53
41
  }
54
42
 
55
43
  function validateTimeout(value){
56
- if(!Number.isSafeInteger(value)||value<100||value>10_000){
57
- throw updateFailure('The SDK update timeout must be between 100 and 10000 milliseconds.');
44
+ if(!Number.isSafeInteger(value)||value<1){
45
+ throw updateFailure('The SDK update timeout must be a positive integer of milliseconds.');
58
46
  }
59
47
  return value;
60
48
  }
@@ -83,51 +71,34 @@ function linkedAbortSignal(signal,timeoutMs,{schedule=setTimeout,cancel=clearTim
83
71
  };
84
72
  }
85
73
 
86
- async function boundedResponseBytes(response){
74
+ async function responseText(response){
87
75
  const contentType=response.headers?.get?.('content-type')??'';
88
76
  if(!/^(?:application\/json|application\/[A-Za-z0-9.+-]+\+json)(?:\s*;|$)/iu.test(contentType)){
89
77
  throw updateFailure('The npm registry returned a non-JSON update response.');
90
78
  }
91
- const declared=response.headers?.get?.('content-length');
92
- if(declared!==null&&declared!==undefined&&declared!==''){
93
- if(!/^\d+$/u.test(declared)||Number(declared)>MAX_RESPONSE_BYTES){
94
- throw updateFailure('The npm registry update response exceeded the byte limit.');
95
- }
96
- }
97
79
  if(!response.body||typeof response.body.getReader!=='function'){
98
80
  throw updateFailure('The npm registry returned no readable update response.');
99
81
  }
100
82
  const reader=response.body.getReader();
101
- const chunks=[];
102
- let total=0;
83
+ const decoder=new TextDecoder('utf-8',{fatal:true});
84
+ let text='';
103
85
  try{
104
86
  while(true){
105
87
  const {done,value}=await reader.read();
106
88
  if(done)break;
107
89
  if(!(value instanceof Uint8Array)){
108
90
  await reader.cancel();
109
- throw updateFailure('The npm registry update response was not a byte stream.');
91
+ throw updateFailure('The npm registry update response was not a readable stream.');
110
92
  }
111
- total+=value.byteLength;
112
- if(total>MAX_RESPONSE_BYTES){
113
- await reader.cancel();
114
- throw updateFailure('The npm registry update response exceeded the byte limit.');
115
- }
116
- chunks.push(value);
93
+ text+=decoder.decode(value,{stream:true});
117
94
  }
118
- }finally{
119
- reader.releaseLock?.();
120
- }
121
- const bytes=new Uint8Array(total);
122
- let offset=0;
123
- for(const chunk of chunks){
124
- bytes.set(chunk,offset);
125
- offset+=chunk.byteLength;
126
- }
127
- try{
128
- return new TextDecoder('utf-8',{fatal:true}).decode(bytes);
95
+ text+=decoder.decode();
96
+ return text;
129
97
  }catch(error){
98
+ if(error instanceof ArcaneError)throw error;
130
99
  throw updateFailure('The npm registry update response was not valid UTF-8.',{cause:error});
100
+ }finally{
101
+ reader.releaseLock?.();
131
102
  }
132
103
  }
133
104
 
@@ -136,13 +107,13 @@ function canonicalDistTags(value){
136
107
  throw updateFailure('The npm registry update response was not a dist-tag object.');
137
108
  }
138
109
  const entries=Object.entries(value);
139
- if(entries.length<1||entries.length>MAX_DIST_TAGS){
110
+ if(entries.length<1){
140
111
  throw updateFailure('The npm registry update response contained an invalid dist-tag count.');
141
112
  }
142
113
  const tags=Object.create(null);
143
114
  for(const [tag,version] of entries){
144
115
  if(!DIST_TAG_PATTERN.test(tag)||FORBIDDEN_DIST_TAG_KEYS.has(tag)
145
- ||typeof version!=='string'||version.length>128){
116
+ ||typeof version!=='string'){
146
117
  throw updateFailure('The npm registry update response contained an invalid dist-tag.');
147
118
  }
148
119
  try{
@@ -152,7 +123,7 @@ function canonicalDistTags(value){
152
123
  }
153
124
  tags[tag]=version;
154
125
  }
155
- return Object.freeze(tags);
126
+ return tags;
156
127
  }
157
128
 
158
129
  function comparePrerelease(left,right){
@@ -199,7 +170,6 @@ export async function checkForSdkUpdate({
199
170
  packageName=SDK_NAME,
200
171
  currentVersion=SDK_VERSION,
201
172
  registry=SDK_UPDATE_REGISTRY,
202
- allowedRegistryHosts,
203
173
  timeoutMs=SDK_UPDATE_TIMEOUT_MS,
204
174
  fetchImpl=globalThis.fetch,
205
175
  signal,
@@ -208,9 +178,7 @@ export async function checkForSdkUpdate({
208
178
  }={}){
209
179
  throwIfAborted(signal);
210
180
  const selectedPackage=canonicalPackageName(packageName);
211
- const selectedRegistry=validateUpdateRegistry(registry,{
212
- ...(allowedRegistryHosts===undefined?{}:{allowedHosts:allowedRegistryHosts})
213
- });
181
+ const selectedRegistry=validateUpdateRegistry(registry);
214
182
  const selectedTimeout=validateTimeout(timeoutMs);
215
183
  if(typeof fetchImpl!=='function'){
216
184
  throw updateFailure('The SDK update HTTP client is unavailable.');
@@ -226,18 +194,12 @@ export async function checkForSdkUpdate({
226
194
  try{
227
195
  const response=await fetchImpl(endpoint,{
228
196
  method:'GET',
229
- headers:Object.freeze({accept:'application/json'}),
230
- redirect:'error',
231
- cache:'no-store',
232
- credentials:'omit',
233
- referrerPolicy:'no-referrer',
197
+ headers:{accept:'application/json'},
234
198
  signal:linked.signal
235
199
  });
236
200
  throwIfAborted(signal);
237
- if(!response||typeof response.status!=='number'
238
- ||response.redirected===true
239
- ||(response.url&&response.url!==endpoint.href)){
240
- throw updateFailure('The npm registry update response changed origin or request identity.');
201
+ if(!response||typeof response.status!=='number'){
202
+ throw updateFailure('The npm registry update response is unavailable.');
241
203
  }
242
204
  if(response.status!==200){
243
205
  throw updateFailure(
@@ -245,7 +207,7 @@ export async function checkForSdkUpdate({
245
207
  {details:{status:response.status}}
246
208
  );
247
209
  }
248
- const body=await boundedResponseBytes(response);
210
+ const body=await responseText(response);
249
211
  let document;
250
212
  try{
251
213
  document=JSON.parse(body);
@@ -265,7 +227,7 @@ export async function checkForSdkUpdate({
265
227
  throw updateFailure('The installed or registry SDK version is invalid.',{cause:error});
266
228
  }
267
229
  const status=comparison<0?'update-available':comparison===0?'current':'ahead';
268
- const result=Object.freeze({
230
+ const result={
269
231
  packageName:selectedPackage,
270
232
  currentVersion,
271
233
  registryVersion,
@@ -274,7 +236,7 @@ export async function checkForSdkUpdate({
274
236
  updateAvailable:status==='update-available',
275
237
  registry:selectedRegistry.origin,
276
238
  checkedAt:clock().toISOString()
277
- });
239
+ };
278
240
  await onEvent?.({
279
241
  type:'update.check.completed',
280
242
  message:status==='update-available'