arcane-os 0.5.13 → 0.5.15

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 +32 -0
  2. package/README.md +33 -8
  3. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +11 -10
  4. package/browser-runtime/ai/browser-wllama-runtime.mjs +2 -1
  5. package/browser-runtime/ai/model-controller.mjs +6 -5
  6. package/browser-runtime/ai/speech-worker-client.mjs +45 -3
  7. package/browser-runtime/event-manager.mjs +2 -1
  8. package/browser-runtime/logging.mjs +58 -0
  9. package/docs/architecture.md +1 -1
  10. package/docs/reference/README.md +9 -7
  11. package/docs/reference/ai/browser-speech.md +90 -1
  12. package/docs/reference/ai/twin-cloud.md +1 -1
  13. package/docs/reference/cli.md +1 -1
  14. package/docs/reference/core/arcane-ai-contracts.md +1 -1
  15. package/docs/reference/inventory/package-api.json +34 -6
  16. package/docs/reference/inventory/runtime-components.json +1 -1
  17. package/docs/reference/inventory/runtime-modules.json +4 -4
  18. package/docs/reference/protocols.md +5 -5
  19. package/docs/reference/runtime-modules.md +70 -15
  20. package/docs/reference/sdk-api.md +120 -11
  21. package/package.json +4 -3
  22. package/runtime/arcane/components/app-bar.html +3 -1
  23. package/runtime/arcane/components/chat.html +22 -20
  24. package/runtime/arcane/components/dashboard-config.html +3 -1
  25. package/runtime/arcane/components/data-maintenance.html +4 -2
  26. package/runtime/arcane/components/data-view.html +3 -1
  27. package/runtime/arcane/components/directory-picker.html +3 -1
  28. package/runtime/arcane/components/file-manager.html +11 -9
  29. package/runtime/arcane/components/header.html +5 -3
  30. package/runtime/arcane/components/markdown-document.html +3 -1
  31. package/runtime/arcane/components/markdown-editor.html +4 -2
  32. package/runtime/arcane/components/modal.html +3 -1
  33. package/runtime/arcane/components/screen-capture.html +4 -2
  34. package/runtime/arcane/components/speech.html +10 -8
  35. package/runtime/arcane/components/table.html +3 -1
  36. package/runtime/arcane/components/voice-transcription.html +8 -6
  37. package/runtime/arcane/entities/Chat.js +5 -4
  38. package/runtime/arcane/entities/User.js +2 -1
  39. package/runtime/arcane/modules/AI.js +442 -292
  40. package/runtime/arcane/modules/AIProviderRuntime.js +359 -82
  41. package/runtime/arcane/modules/CommunicationAppController.js +2 -1
  42. package/runtime/arcane/modules/ComponentContracts.js +3 -2
  43. package/runtime/arcane/modules/ConversationTimebox.js +2 -1
  44. package/runtime/arcane/modules/DBOPFS.js +5 -4
  45. package/runtime/arcane/modules/Errors.js +3 -14
  46. package/runtime/arcane/modules/HTMLImport.js +4 -3
  47. package/runtime/arcane/modules/LocalAIReadinessController.js +2 -1
  48. package/runtime/arcane/modules/MD.js +3 -2
  49. package/runtime/arcane/modules/MailOutbox.mjs +2 -1
  50. package/runtime/arcane/modules/PersistentAIChatSession.js +2 -1
  51. package/runtime/arcane/modules/ScreenCapture.js +2 -1
  52. package/runtime/arcane/modules/SpeechPlayback.js +206 -40
  53. package/runtime/arcane/modules/ThemeBootstrap.js +3 -2
  54. package/runtime/arcane/modules/ToolCallRouter.js +2 -1
  55. package/src/import-map.mjs +65 -10
@@ -844,8 +844,7 @@ function applyReferenceEdits(source,edits){
844
844
  return result;
845
845
  }
846
846
 
847
- function stringReferenceEdit(source,token,version){
848
- const urlEdits=assetUrlVersionEdits(token.value,version);
847
+ function stringReferenceEdit(source,token,version,urlEdits=assetUrlVersionEdits(token.value,version)){
849
848
  if(urlEdits.length===0)return null;
850
849
  const quote=source[token.start];
851
850
  const positions=[];
@@ -1091,31 +1090,67 @@ function importMapReferenceEdits(source,version,onReference){
1091
1090
  const valueIndex=cursor+2;
1092
1091
  const value=tokens[valueIndex];
1093
1092
  if(!value)return [];
1094
- properties.push({key:key.value,valueIndex,value});
1095
1093
  let end=valueIndex;
1096
1094
  if(value.type==='punctuator'&&(value.value==='{'||value.value==='[')){
1097
1095
  end=matchingToken(tokens,valueIndex,value.value,value.value==='{'?'}':']');
1098
1096
  if(end<0)return [];
1099
1097
  }
1098
+ properties.push({key:key.value,keyToken:key,valueIndex,value,end:tokens[end].end});
1100
1099
  cursor=end+1;
1101
1100
  if(tokens[cursor]?.value===',')cursor+=1;
1102
1101
  else if(tokens[cursor]?.value!=='}')return [];
1103
1102
  }
1104
1103
  return properties;
1105
1104
  }
1105
+ function addAlias(property,keys,value,aliases,alias=versionImportMapSpecifier(property.key,version)){
1106
+ if(alias===property.key||keys.has(alias))return;
1107
+ const keyEdit=stringReferenceEdit(source,property.keyToken,version,importMapUrlVersionEdits(property.key,version));
1108
+ if(!keyEdit)return;
1109
+ keys.add(alias);
1110
+ aliases.push(`${keyEdit.value}: ${value}`);
1111
+ }
1112
+ function prependAliases(start,aliases,selectedEdits){
1113
+ if(aliases.length===0)return;
1114
+ // Authored keys retain priority even when different spellings normalize to one URL.
1115
+ const offset=tokens[start].end;
1116
+ selectedEdits.push({start:offset,end:offset,value:`${aliases.join(', ')}, `});
1117
+ }
1106
1118
  function addImports(start){
1107
- for(const property of objectProperties(start)){
1119
+ const selectedEdits=[];
1120
+ const aliases=[];
1121
+ const properties=objectProperties(start);
1122
+ const keys=new Set(properties.map(function importKey(property){return property.key;}));
1123
+ for(const property of properties){
1124
+ if(property.value.value==='null'&&property.value.type==='identifier'){
1125
+ addAlias(property,keys,'null',aliases);
1126
+ continue;
1127
+ }
1108
1128
  if(property.value.type!=='string')continue;
1109
- if(property.key.endsWith('/')||property.value.value.split(/[?#]/u)[0].endsWith('/'))continue;
1129
+ if(property.key.endsWith('/'))continue;
1110
1130
  reportAssetReference(onReference,property.value.value,'import');
1111
- const edit=stringReferenceEdit(source,property.value,version);
1112
- if(edit)edits.push(edit);
1131
+ const edit=property.value.value.split(/[?#]/u)[0].endsWith('/')
1132
+ ?null:stringReferenceEdit(source,property.value,version);
1133
+ if(edit)selectedEdits.push(edit);
1134
+ addAlias(property,keys,edit?.value??source.slice(property.value.start,property.value.end),aliases);
1113
1135
  }
1136
+ prependAliases(start,aliases,selectedEdits);
1137
+ return selectedEdits;
1114
1138
  }
1115
1139
  for(const property of objectProperties(0)){
1116
- if(property.key==='imports')addImports(property.valueIndex);
1140
+ if(property.key==='imports')edits.push(...addImports(property.valueIndex));
1117
1141
  if(property.key==='scopes'){
1118
- for(const scope of objectProperties(property.valueIndex))addImports(scope.valueIndex);
1142
+ const scopes=objectProperties(property.valueIndex);
1143
+ const aliases=[];
1144
+ const keys=new Set(scopes.map(function scopeKey(scope){return scope.key;}));
1145
+ for(const scope of scopes){
1146
+ const scopeEdits=addImports(scope.valueIndex);
1147
+ edits.push(...scopeEdits);
1148
+ const value=applyReferenceEdits(source.slice(scope.value.start,scope.end),scopeEdits.map(function scopeRelativeEdit(edit){
1149
+ return {...edit,start:edit.start-scope.value.start,end:edit.end-scope.value.start};
1150
+ }));
1151
+ if(!scope.key.endsWith('/'))addAlias(scope,keys,value,aliases,versionImportMapUrl(scope.key,version));
1152
+ }
1153
+ prependAliases(property.valueIndex,aliases,edits);
1119
1154
  }
1120
1155
  }
1121
1156
  return edits;
@@ -1138,6 +1173,24 @@ function registerSpecifier(registry,specifier,target){
1138
1173
  registry.set(specifier,{specifier,target});
1139
1174
  }
1140
1175
 
1176
+ function versionImportMapSpecifier(specifier,version){
1177
+ if(specifier.endsWith('/')||!/^(?:\.{1,2}\/|\/|[A-Za-z][A-Za-z0-9+.-]*:\/\/)/u.test(specifier))return specifier;
1178
+ return versionImportMapUrl(specifier,version);
1179
+ }
1180
+
1181
+ function versionImportMapUrl(value,version){
1182
+ return applyReferenceEdits(value,importMapUrlVersionEdits(value,version));
1183
+ }
1184
+
1185
+ function importMapUrlVersionEdits(value,version){
1186
+ // Absolute map keys can match a relative import resolved against the document.
1187
+ const authority=/^(?:[A-Za-z][A-Za-z0-9+.-]*:)?\/\/[^/?#]*/u.exec(value)?.[0];
1188
+ const offset=authority?.length??0;
1189
+ return assetUrlVersionEdits(value.slice(offset),version).map(function absoluteKeyEdit(edit){
1190
+ return {...edit,start:edit.start+offset,end:edit.end+offset};
1191
+ });
1192
+ }
1193
+
1141
1194
  function validateInventory(files){
1142
1195
  if(!Array.isArray(files))throw new TypeError('buildImportMap files must be an array.');
1143
1196
  const exact=new Set();
@@ -1215,7 +1268,9 @@ export async function buildImportMap({files,signal,version=SDK_VERSION}={}){
1215
1268
  }
1216
1269
  const imports={};
1217
1270
  for(const entry of [...namedRegistry.values()].sort((left,right)=>compareText(left.specifier,right.specifier))){
1218
- imports[entry.specifier]=versionAssetUrl(entry.target,version);
1271
+ const target=versionAssetUrl(entry.target,version);
1272
+ imports[entry.specifier]=target;
1273
+ imports[versionImportMapSpecifier(entry.specifier,version)]=target;
1219
1274
  }
1220
1275
  return {
1221
1276
  imports,