arcane-os 0.3.1 → 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 +14 -0
  2. package/README.md +86 -117
  3. package/bin/arcane-test.mjs +170 -46
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +855 -895
  5. package/browser-runtime/ai/browser-speech-providers.mjs +80 -204
  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 -148
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +642 -374
  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 +1042 -427
  37. package/runtime/arcane/modules/AIProviderRuntime.js +618 -359
  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 +27 -67
  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 +109 -1558
  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 -185
  120. package/docs/reference/ai/browser-speech-package-authority.json +0 -835
  121. package/docs/reference/ai/browser-speech.md +0 -1295
  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 -719
  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 -2965
  150. package/docs/reference/sdk-api.md +0 -6698
  151. package/docs/roadmap.md +0 -79
  152. package/docs/work-amplification.md +0 -129
  153. package/runtime/ARCANE_RUNTIME_RELEASE.json +0 -826
package/src/scaffold.mjs CHANGED
@@ -1,9 +1,7 @@
1
1
  import {lstat,mkdir,readFile,readdir,writeFile} from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import {spawn} from 'node:child_process';
4
- import {verifyRuntime} from './runtime.mjs';
5
- import {verifySdkBrowserRuntime} from './sdk-browser-runtime.mjs';
6
- import {materializeWorkspaceRuntime} from './workspace-runtime.mjs';
4
+ import {materializeWorkspaceRuntimeContent} from './workspace-runtime.mjs';
7
5
  import {generateImportMap} from './import-map.mjs';
8
6
  import {withWorkspaceOperationLock} from './workspace-operation-lock.mjs';
9
7
  import {SDK_NAME,SDK_VERSION,workspaceTemplate} from './templates/workspace-template.mjs';
@@ -27,7 +25,7 @@ function throwIfAborted(signal){
27
25
  }
28
26
 
29
27
  async function emit(onEvent,event){
30
- if(typeof onEvent==='function')await onEvent(Object.freeze(event));
28
+ if(typeof onEvent==='function')await onEvent(event);
31
29
  }
32
30
 
33
31
  function validateInputs(appId,displayName){
@@ -157,7 +155,7 @@ async function readExistingPackage(workspaceRoot){
157
155
  try{source=await readFile(packagePath,'utf8');}
158
156
  catch(error){
159
157
  if(error?.code==='ENOENT'){
160
- return Object.freeze({exists:false,packagePath,source:null,document:null});
158
+ return {exists:false,packagePath,source:null,document:null};
161
159
  }
162
160
  throw error;
163
161
  }
@@ -165,7 +163,7 @@ async function readExistingPackage(workspaceRoot){
165
163
  try{existing=JSON.parse(source);}
166
164
  catch(error){fail(`Existing package.json is not valid JSON: ${error.message}.`);}
167
165
  if(!existing||typeof existing!=='object'||Array.isArray(existing))fail('Existing package.json must be a JSON object.');
168
- return Object.freeze({exists:true,packagePath,source,document:existing});
166
+ return {exists:true,packagePath,source,document:existing};
169
167
  }
170
168
 
171
169
  function defaultSdkDeclaration(){
@@ -174,7 +172,7 @@ function defaultSdkDeclaration(){
174
172
 
175
173
  async function prepareExistingPackage(workspaceRoot,files,existingPackage,sdkDeclaration){
176
174
  const packageState=existingPackage??await readExistingPackage(workspaceRoot);
177
- if(!packageState.exists)return Object.freeze({exists:false,updated:false});
175
+ if(!packageState.exists)return {exists:false,updated:false};
178
176
  const {packagePath,source,document:existing}=packageState;
179
177
  const generated=JSON.parse(files.get('package.json'));
180
178
  const conflicts=[];
@@ -207,15 +205,15 @@ async function prepareExistingPackage(workspaceRoot,files,existingPackage,sdkDec
207
205
  if(Object.keys(merged.dependencies).length===0)delete merged.dependencies;
208
206
  }
209
207
  if(JSON.stringify(existing)===JSON.stringify(merged)){
210
- return Object.freeze({exists:true,updated:false});
208
+ return {exists:true,updated:false};
211
209
  }
212
- return Object.freeze({
210
+ return {
213
211
  exists:true,
214
212
  updated:true,
215
213
  packagePath,
216
214
  source,
217
215
  content:`${JSON.stringify(merged,null,2)}\n`
218
- });
216
+ };
219
217
  }
220
218
 
221
219
  async function applyPackageMerge(workspaceRoot,plan,{signal,onEvent}){
@@ -269,29 +267,6 @@ async function writeMissingFiles(workspaceRoot,files,{signal,onEvent}){
269
267
  return {createdFiles,skippedFiles};
270
268
  }
271
269
 
272
- async function assertExistingLockAdmission(workspaceRoot,files){
273
- const expected=files.get('arcane.lock.json');
274
- if(typeof expected!=='string')return;
275
- const lockPath=path.join(workspaceRoot,'arcane.lock.json');
276
- let info;
277
- try{
278
- info=await lstat(lockPath);
279
- }catch(error){
280
- if(error?.code==='ENOENT')return;
281
- throw error;
282
- }
283
- if(info.isSymbolicLink()||!info.isFile()){
284
- fail('Existing arcane.lock.json must be a real file.');
285
- }
286
- if(await readFile(lockPath,'utf8')!==expected){
287
- fail(
288
- 'Existing arcane.lock.json does not match the authenticated SDK runtime '
289
- +'admission. Remove or reconcile it before running arcane init; Arcane never '
290
- +'overwrites a lock implicitly.'
291
- );
292
- }
293
- }
294
-
295
270
  async function runGitInit(workspaceRoot,signal,onEvent){
296
271
  throwIfAborted(signal);
297
272
  await emit(onEvent,{type:'scaffold.git.started',command:'git init -b main'});
@@ -346,29 +321,21 @@ export async function createWorkspace({
346
321
  const workspaceRoot=path.resolve(targetPath);
347
322
  await emit(onEvent,{type:'scaffold.started',mode:'create',workspaceRoot,appId,target});
348
323
  await assertCreateTarget(workspaceRoot);
349
- const receipt=await withWorkspaceOperationLock({
324
+ const operationResult=await withWorkspaceOperationLock({
350
325
  workspaceRoot,
351
326
  operation:'scaffold-create',
352
327
  signal,
353
328
  onEvent
354
329
  },async workspaceOperationLease=>{
355
- const runtimeReceipt=await verifyRuntime({signal,onEvent});
356
- const sdkBrowserRuntimeReceipt=await verifySdkBrowserRuntime({signal,onEvent});
357
330
  const template=workspaceTemplate({
358
331
  appId,
359
332
  displayName,
360
- runtimeRelease:runtimeReceipt,
361
- sdkBrowserRuntimeRelease:sdkBrowserRuntimeReceipt,
362
333
  target,
363
334
  appIcon:await scaffoldIcon(target)
364
335
  });
365
- const result=await writeMissingFiles(workspaceRoot,template.files,{signal,onEvent});
366
- const workspaceRuntimeReceipt=await materializeWorkspaceRuntime({
336
+ const writtenFiles=await writeMissingFiles(workspaceRoot,template.files,{signal,onEvent});
337
+ const workspaceRuntime=await materializeWorkspaceRuntimeContent({
367
338
  workspaceRoot,
368
- runtimeRoot:runtimeReceipt.canonicalLocation,
369
- runtimeReceipt,
370
- browserRuntimeRoot:sdkBrowserRuntimeReceipt.canonicalLocation,
371
- sdkBrowserRuntimeReceipt,
372
339
  signal,
373
340
  onEvent
374
341
  });
@@ -376,26 +343,25 @@ export async function createWorkspace({
376
343
  workspaceRoot,
377
344
  appId,
378
345
  appRoot:path.join(workspaceRoot,'apps',appId),
379
- workspaceRuntimeReceipt,
380
346
  workspaceOperationLease,
381
347
  signal,
382
348
  onEvent
383
349
  });
384
350
  if(initializeGit)await runGitInit(workspaceRoot,signal,onEvent);
385
- const receipt={
351
+ const result={
386
352
  workspaceRoot,
387
353
  appId,
388
354
  displayName:template.name,
389
355
  target,
390
- ...result,
391
- workspaceRuntime:workspaceRuntimeReceipt,
356
+ ...writtenFiles,
357
+ workspaceRuntime,
392
358
  importMap,
393
359
  gitInitialized:Boolean(initializeGit)
394
360
  };
395
- return receipt;
361
+ return result;
396
362
  });
397
- await emit(onEvent,{type:'scaffold.completed',...receipt});
398
- return receipt;
363
+ await emit(onEvent,{type:'scaffold.completed',...operationResult});
364
+ return operationResult;
399
365
  }
400
366
 
401
367
  export async function initWorkspace({
@@ -412,7 +378,7 @@ export async function initWorkspace({
412
378
  const resolvedRoot=path.resolve(workspaceRoot);
413
379
  await emit(onEvent,{type:'scaffold.started',mode:'init',workspaceRoot:resolvedRoot,appId,target});
414
380
  await assertInitTarget(resolvedRoot);
415
- const receipt=await withWorkspaceOperationLock({
381
+ const operationResult=await withWorkspaceOperationLock({
416
382
  workspaceRoot:resolvedRoot,
417
383
  operation:'scaffold-init',
418
384
  signal,
@@ -422,12 +388,6 @@ export async function initWorkspace({
422
388
  const workspaceMode=profile?.workspaceMode??'external';
423
389
  const legacyIntegrated=workspaceMode==='integrated'
424
390
  &&profile.config.browserRuntimeLayout==='integrated-legacy';
425
- const runtimeReceipt=workspaceMode==='external'
426
- ?await verifyRuntime({signal,onEvent})
427
- :null;
428
- const sdkBrowserRuntimeReceipt=workspaceMode==='external'
429
- ?await verifySdkBrowserRuntime({signal,onEvent})
430
- :null;
431
391
  const existingPackage=workspaceMode==='external'
432
392
  ?await readExistingPackage(resolvedRoot)
433
393
  :null;
@@ -455,8 +415,6 @@ export async function initWorkspace({
455
415
  :workspaceTemplate({
456
416
  appId,
457
417
  displayName,
458
- runtimeRelease:runtimeReceipt,
459
- sdkBrowserRuntimeRelease:sdkBrowserRuntimeReceipt,
460
418
  sdkDependencyName:sdkDeclaration.dependencyName,
461
419
  sdkDependencySpecifier:sdkDeclaration.specifier,
462
420
  sdkPackageSource:sdkDeclaration.packageSource,
@@ -464,41 +422,33 @@ export async function initWorkspace({
464
422
  appIcon:await scaffoldIcon(target)
465
423
  });
466
424
  const packagePlan=workspaceMode==='integrated'
467
- ?Object.freeze({exists:true,updated:false})
425
+ ?{exists:true,updated:false}
468
426
  :await prepareExistingPackage(
469
427
  resolvedRoot,
470
428
  template.files,
471
429
  existingPackage,
472
430
  sdkDeclaration
473
431
  );
474
- if(workspaceMode==='external'){
475
- await assertExistingLockAdmission(resolvedRoot,template.files);
476
- }
477
- const result=await writeMissingFiles(resolvedRoot,template.files,{signal,onEvent});
432
+ const writtenFiles=await writeMissingFiles(resolvedRoot,template.files,{signal,onEvent});
478
433
  const packageUpdated=await applyPackageMerge(resolvedRoot,packagePlan,{signal,onEvent});
479
- const workspaceRuntimeReceipt=workspaceMode==='external'
480
- ?await materializeWorkspaceRuntime({
434
+ const workspaceRuntime=workspaceMode==='external'
435
+ ?await materializeWorkspaceRuntimeContent({
481
436
  workspaceRoot:resolvedRoot,
482
- runtimeRoot:runtimeReceipt.canonicalLocation,
483
- runtimeReceipt,
484
- browserRuntimeRoot:sdkBrowserRuntimeReceipt.canonicalLocation,
485
- sdkBrowserRuntimeReceipt,
486
437
  signal,
487
438
  onEvent
488
439
  })
489
440
  :null;
490
441
  const importMap=legacyIntegrated
491
- ?Object.freeze({
442
+ ?{
492
443
  appId,
493
444
  skipped:true,
494
445
  compatibility:'integrated-legacy',
495
446
  reason:'The canonical integrated Arcane OS root retains its physical two-route browser runtime.'
496
- })
447
+ }
497
448
  :await generateImportMap({
498
449
  workspaceRoot:resolvedRoot,
499
450
  appId,
500
451
  appRoot:path.join(resolvedRoot,'apps',appId),
501
- workspaceRuntimeReceipt,
502
452
  workspaceOperationLease,
503
453
  signal,
504
454
  onEvent
@@ -506,20 +456,20 @@ export async function initWorkspace({
506
456
  if(legacyIntegrated){
507
457
  await emit(onEvent,{type:'import-map.compatibility.skipped',...importMap});
508
458
  }
509
- const receipt={
459
+ const result={
510
460
  workspaceRoot:resolvedRoot,
511
461
  workspaceMode,
512
462
  appId,
513
463
  displayName:template.name,
514
464
  target,
515
- ...result,
465
+ ...writtenFiles,
516
466
  packageUpdated,
517
- workspaceRuntime:workspaceRuntimeReceipt,
467
+ workspaceRuntime,
518
468
  importMap,
519
469
  gitInitialized:false
520
470
  };
521
- return receipt;
471
+ return result;
522
472
  });
523
- await emit(onEvent,{type:'scaffold.completed',...receipt});
524
- return receipt;
473
+ await emit(onEvent,{type:'scaffold.completed',...operationResult});
474
+ return operationResult;
525
475
  }