arcane-os 0.54.1 → 0.56.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +35 -28
  3. package/browser-runtime/core/client.mjs +552 -0
  4. package/browser-runtime/core/contracts.mjs +85 -0
  5. package/docs/architecture.md +31 -23
  6. package/docs/compatibility.md +10 -1
  7. package/docs/consumer-updates.md +82 -0
  8. package/docs/platform-targets.md +20 -11
  9. package/docs/publishing.md +41 -18
  10. package/docs/reference/README.md +19 -7
  11. package/docs/reference/availability-and-normalization.md +15 -5
  12. package/docs/reference/behavioral-testing.md +7 -6
  13. package/docs/reference/cli.md +12 -4
  14. package/docs/reference/core-client.md +163 -0
  15. package/docs/reference/core-native-packaging.md +149 -0
  16. package/docs/reference/core-runtime.md +185 -0
  17. package/docs/reference/inventory/package-api.json +271 -5
  18. package/docs/reference/protocols.md +38 -14
  19. package/docs/reference/pwa.md +17 -0
  20. package/docs/reference/sdk-api.md +772 -15
  21. package/package.json +10 -3
  22. package/schemas/arcane-app.schema.json +10 -0
  23. package/schemas/arcane-package.schema.json +10 -0
  24. package/schemas/native-build-plan.schema.json +8 -0
  25. package/src/app-descriptor.mjs +18 -1
  26. package/src/app-layout.mjs +6 -2
  27. package/src/cli/main.mjs +8 -6
  28. package/src/core/host.mjs +23 -0
  29. package/src/core/hosts/arcane-core-loader.cjs +2 -0
  30. package/src/core/hosts/linux/arcane_core_process.c +568 -0
  31. package/src/core/hosts/linux/arcane_core_process.h +127 -0
  32. package/src/core/hosts/sea-launcher.cjs +17 -0
  33. package/src/core/hosts/windows/ArcaneCoreProcess.cs +416 -0
  34. package/src/core/runtime.mjs +345 -0
  35. package/src/core/stdio.mjs +209 -0
  36. package/src/core-classic-source.mjs +43 -0
  37. package/src/import-map.mjs +62 -0
  38. package/src/native/portable-layout.mjs +184 -0
  39. package/src/native/portable-provider.mjs +211 -0
  40. package/src/native-plan.mjs +10 -4
  41. package/src/native-provider-loader.mjs +15 -4
  42. package/src/packager/core.mjs +131 -32
  43. package/src/process.mjs +8 -4
  44. package/src/targets/index.mjs +3 -1
  45. package/src/toolchain.mjs +23 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.54.1",
3
+ "version": "0.56.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",
@@ -48,6 +48,13 @@
48
48
  "./targets": "./src/targets/index.mjs",
49
49
  "./native": "./src/native-plan.mjs",
50
50
  "./native-provider": "./src/native-provider-loader.mjs",
51
+ "./native/portable-provider": "./src/native/portable-provider.mjs",
52
+ "./core/client": "./browser-runtime/core/client.mjs",
53
+ "./core/contracts": "./browser-runtime/core/contracts.mjs",
54
+ "./core/classic-source": "./src/core-classic-source.mjs",
55
+ "./core/runtime": "./src/core/runtime.mjs",
56
+ "./core/stdio": "./src/core/stdio.mjs",
57
+ "./core/host": "./src/core/host.mjs",
51
58
  "./integrated-provider": "./src/integrated-provider-loader.mjs",
52
59
  "./packager": "./src/packager/core.mjs",
53
60
  "./release-bundle": "./src/release-bundle.mjs",
@@ -89,8 +96,8 @@
89
96
  "test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
90
97
  "test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
91
98
  "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/conversation-closing-report.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",
92
- "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-decisions.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.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/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.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/rendered-print.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/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
93
- "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",
99
+ "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-decisions.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.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/core-classic-source.test.mjs test/core-client.test.mjs test/core-host.test.mjs test/core-runtime.test.mjs test/core-stdio.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/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.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/rendered-print.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/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
100
+ "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-portable-provider.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",
94
101
  "test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/html-import-packaged-script.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",
95
102
  "check": "node tools/check-source.mjs && npm test",
96
103
  "check:release": "node tools/check-source.mjs --package-only && npm run test:release",
@@ -48,6 +48,16 @@
48
48
  "pwa": { "$ref": "#/$defs/pwa" },
49
49
  "include": { "$ref": "#/$defs/nonemptyPathList" },
50
50
  "exclude": { "$ref": "#/$defs/pathList" },
51
+ "nativeResources": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": ["include"],
55
+ "description": "Additional literal application-relative paths for a selected nonbrowser target. Exclude applies only to this additional selection. Native-only files retain their complete original content and do not enter browser document or PWA processing. Omission or an empty include preserves existing selection and output behavior.",
56
+ "properties": {
57
+ "include": { "$ref": "#/$defs/pathList" },
58
+ "exclude": { "$ref": "#/$defs/pathList" }
59
+ }
60
+ },
51
61
  "shared": {
52
62
  "type": "array",
53
63
  "minItems": 1,
@@ -88,6 +88,16 @@
88
88
  "exclude": {
89
89
  "$ref": "#/$defs/pathList"
90
90
  },
91
+ "nativeResources": {
92
+ "type": "object",
93
+ "additionalProperties": false,
94
+ "required": ["include"],
95
+ "description": "Additional literal application-relative paths for a selected nonbrowser target. Exclude applies only to this additional selection. Native-only files retain their complete original content and do not enter browser document or PWA processing. Omission or an empty include preserves existing selection and output behavior.",
96
+ "properties": {
97
+ "include": { "$ref": "#/$defs/pathList" },
98
+ "exclude": { "$ref": "#/$defs/pathList" }
99
+ }
100
+ },
91
101
  "shared": {
92
102
  "type": "array",
93
103
  "uniqueItems": true,
@@ -23,6 +23,14 @@
23
23
  "toolchainRoot": { "type": "string", "minLength": 1 },
24
24
  "toolchain": { "type": "object" },
25
25
  "appDescriptor": { "type": "object" },
26
+ "selectedSdk": {
27
+ "description": "Actual selected app SDK installation used to complete a partial native package projection without replacing selected files.",
28
+ "type": "object",
29
+ "properties": {
30
+ "packageRoot": { "type": "string" },
31
+ "packageSource": { "type": "string" }
32
+ }
33
+ },
26
34
  "application": { "$ref": "#/$defs/releaseSelection" },
27
35
  "dependencies": {
28
36
  "type": "array",
@@ -111,13 +111,21 @@ function validateLocalAIModelPolicy(value,label){
111
111
 
112
112
  function validatePackage(value,appId){
113
113
  assertOnlyKeys(value,new Set([
114
- 'entry','strategy','include','exclude','shared','adapter','localAIModelPolicy','pwa','documents'
114
+ 'entry','strategy','include','exclude','shared','adapter','localAIModelPolicy','pwa','documents','nativeResources'
115
115
  ]),'descriptor.package');
116
116
  const entry=normalizeRelativePath(value.entry,'descriptor.package.entry');
117
117
  const documents=normalizeAppDocuments(value.documents,'descriptor.package.documents');
118
118
  if(!['static','adapter'].includes(value.strategy))fail('descriptor.package.strategy must be static or adapter.');
119
119
  const include=relativePaths(value.include,'descriptor.package.include',{required:true});
120
120
  const exclude=relativePaths(value.exclude??[],'descriptor.package.exclude');
121
+ let nativeResources;
122
+ if(value.nativeResources!==undefined){
123
+ assertOnlyKeys(value.nativeResources,new Set(['include','exclude']),'descriptor.package.nativeResources');
124
+ nativeResources={
125
+ include:relativePaths(value.nativeResources.include,'descriptor.package.nativeResources.include'),
126
+ exclude:relativePaths(value.nativeResources.exclude??[],'descriptor.package.nativeResources.exclude')
127
+ };
128
+ }
121
129
  if(!include.some(candidate=>entry===candidate||entry.startsWith(`${candidate}/`))){
122
130
  fail('descriptor.package.entry must be covered by descriptor.package.include.');
123
131
  }
@@ -140,6 +148,7 @@ function validatePackage(value,appId){
140
148
  strategy:value.strategy,
141
149
  include,
142
150
  exclude,
151
+ ...(nativeResources===undefined?{}:{nativeResources}),
143
152
  shared,
144
153
  ...(value.pwa===undefined?{}:{pwa:normalizePwaConfig(value.pwa)}),
145
154
  ...(adapter?{adapter}:{}),
@@ -331,6 +340,10 @@ export function projectPackageManifest(descriptor){
331
340
  ...(value.package.pwa===undefined?{}:{pwa:value.package.pwa}),
332
341
  include:[...value.package.include],
333
342
  exclude:[...value.package.exclude],
343
+ ...(value.package.nativeResources===undefined?{}:{nativeResources:{
344
+ include:[...value.package.nativeResources.include],
345
+ exclude:[...value.package.nativeResources.exclude]
346
+ }}),
334
347
  shared:[...value.package.shared],
335
348
  ...(value.package.adapter?{adapter:value.package.adapter}:{})
336
349
  };
@@ -391,6 +404,10 @@ function synthesizedDescriptor(packageManifest,nativeDescriptor){
391
404
  ...(packageManifest.pwa===undefined?{}:{pwa:packageManifest.pwa}),
392
405
  include:[...packageManifest.include],
393
406
  exclude:[...(packageManifest.exclude??[])],
407
+ ...(packageManifest.nativeResources===undefined?{}:{nativeResources:{
408
+ include:[...packageManifest.nativeResources.include],
409
+ exclude:[...(packageManifest.nativeResources.exclude??[])]
410
+ }}),
394
411
  shared:[...packageManifest.shared],
395
412
  ...(packageManifest.adapter?{adapter:packageManifest.adapter}:{})
396
413
  },
@@ -9,8 +9,12 @@ export function resolveAppRoot(workspaceRoot, config, appId) {
9
9
  return path.resolve(workspaceRoot, appRelativeRoot(config, appId));
10
10
  }
11
11
 
12
- export function resolvePackageOutputRoot(workspaceRoot, config, app) {
13
- return path.resolve(workspaceRoot, app.outputDirectory ?? `${config.distRoot}/${app.id}`);
12
+ export function resolvePackageOutputRoot(workspaceRoot, config, app, {target='browser', outputDirectory}={}) {
13
+ const nativeSelection=target!=='browser'&&app.nativeResources?.include.length>0;
14
+ const selectedDirectory=outputDirectory??(nativeSelection
15
+ ?`${config.distRoot}/.native/${target}/${app.id}`
16
+ :app.outputDirectory??`${config.distRoot}/${app.id}`);
17
+ return path.resolve(workspaceRoot,selectedDirectory);
14
18
  }
15
19
 
16
20
  export function appBaseHref(workspaceRoot, appRoot, document = 'index.html') {
package/src/cli/main.mjs CHANGED
@@ -75,8 +75,8 @@ Usage:
75
75
  ${CLI_NAME} verify [--app <id>]
76
76
  ${CLI_NAME} bundle [--app <id>] [--artifact <file>${APP_BUNDLE_EXTENSION}] [--overwrite]
77
77
  ${CLI_NAME} verify-bundle <file${APP_BUNDLE_EXTENSION}>
78
- ${CLI_NAME} native-doctor --target <native-target> --arcane-root <directory>
79
- ${CLI_NAME} native-prepare --target <native-target> --arcane-root <directory>
78
+ ${CLI_NAME} native-doctor --target <native-target> [--arcane-root <directory>]
79
+ ${CLI_NAME} native-prepare --target <native-target> [--arcane-root <directory>]
80
80
  ${CLI_NAME} build --target <target> [--arcane-root <directory>] [--output-root <directory>] [--format <format>] [--signing <mode>]
81
81
  ${CLI_NAME} run [--target <target>] [--app <id>] [--cert <pem>] [--key <pem>] [--port 8000] [--http-port 0] [--arcane-root <directory>] [--output-root <directory>] [--format <format>] [--signing <mode>]
82
82
  ${CLI_NAME} update-check
@@ -105,9 +105,10 @@ Global:
105
105
  --version Show the SDK version.
106
106
 
107
107
  The npm package is ${SDK_NAME}. Both the ${CLI_NAME} and arcane-os executables
108
- invoke this same headless toolchain. Every native operation requires one explicit
109
- --arcane-root. Available providers build portable directories, Windows x64 EXE
110
- bundles, Linux x64 or ARM64 DEBs, and development-signed Android APKs.`;
108
+ invoke this same headless toolchain. Portable uses the installed SDK provider
109
+ by default and produces a non-executable app payload. An explicit --arcane-root
110
+ selects the Arcane OS provider instead. Windows EXE, Linux DEB, and Android APK
111
+ targets still require an explicit --arcane-root and their platform toolchains.`;
111
112
 
112
113
  function usage(message){
113
114
  throw new ArcaneError(ERROR_CODES.usage,message);
@@ -810,7 +811,7 @@ async function pairNativeProvider(command,options,loadProvider,{signal,onEvent}=
810
811
  usage(`${command} requires one native target.`);
811
812
  }
812
813
  const targetRequest=createNativeTargetRequest(options);
813
- if(!options.arcaneRoot){
814
+ if(!options.arcaneRoot&&options.target!=='portable'){
814
815
  usage(`${command} for target ${options.target} requires --arcane-root <directory>.`);
815
816
  }
816
817
  const loaded=await loadProvider({
@@ -823,6 +824,7 @@ async function pairNativeProvider(command,options,loadProvider,{signal,onEvent}=
823
824
  ...options,
824
825
  nativeBuilder:loaded.nativeBuilder,
825
826
  toolchainRoot:loaded.toolchainRoot,
827
+ providerSource:loaded.providerSource,
826
828
  targetRequest
827
829
  };
828
830
  }
@@ -0,0 +1,23 @@
1
+ import {createCoreRuntime} from './runtime.mjs';
2
+ import {startCoreStdio} from './stdio.mjs';
3
+
4
+ /** Compose app services with the shared dispatcher and draining transport. */
5
+ export function startCoreHost({application, version, services = [], input, output, onError, signal} = {}) {
6
+ const runtime = createCoreRuntime({application, version, services});
7
+ const host = startCoreStdio({runtime, input, output, onError});
8
+ if (!signal) return host;
9
+
10
+ function closeHostOnAbort() {
11
+ // The transport owns cancellation, accepted-service work and final output.
12
+ host.close();
13
+ }
14
+
15
+ function releaseAbortListener() {
16
+ signal.removeEventListener('abort', closeHostOnAbort);
17
+ }
18
+
19
+ signal.addEventListener('abort', closeHostOnAbort, {once: true});
20
+ host.closed.then(releaseAbortListener, releaseAbortListener);
21
+ if (signal.aborted) closeHostOnAbort();
22
+ return host;
23
+ }
@@ -0,0 +1,2 @@
1
+ // This ordinary filesystem module retains Node's asynchronous ESM loader.
2
+ module.exports = import('./arcane-core.mjs');