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.
- package/CHANGELOG.md +60 -0
- package/README.md +35 -28
- package/browser-runtime/core/client.mjs +552 -0
- package/browser-runtime/core/contracts.mjs +85 -0
- package/docs/architecture.md +31 -23
- package/docs/compatibility.md +10 -1
- package/docs/consumer-updates.md +82 -0
- package/docs/platform-targets.md +20 -11
- package/docs/publishing.md +41 -18
- package/docs/reference/README.md +19 -7
- package/docs/reference/availability-and-normalization.md +15 -5
- package/docs/reference/behavioral-testing.md +7 -6
- package/docs/reference/cli.md +12 -4
- package/docs/reference/core-client.md +163 -0
- package/docs/reference/core-native-packaging.md +149 -0
- package/docs/reference/core-runtime.md +185 -0
- package/docs/reference/inventory/package-api.json +271 -5
- package/docs/reference/protocols.md +38 -14
- package/docs/reference/pwa.md +17 -0
- package/docs/reference/sdk-api.md +772 -15
- package/package.json +10 -3
- package/schemas/arcane-app.schema.json +10 -0
- package/schemas/arcane-package.schema.json +10 -0
- package/schemas/native-build-plan.schema.json +8 -0
- package/src/app-descriptor.mjs +18 -1
- package/src/app-layout.mjs +6 -2
- package/src/cli/main.mjs +8 -6
- package/src/core/host.mjs +23 -0
- package/src/core/hosts/arcane-core-loader.cjs +2 -0
- package/src/core/hosts/linux/arcane_core_process.c +568 -0
- package/src/core/hosts/linux/arcane_core_process.h +127 -0
- package/src/core/hosts/sea-launcher.cjs +17 -0
- package/src/core/hosts/windows/ArcaneCoreProcess.cs +416 -0
- package/src/core/runtime.mjs +345 -0
- package/src/core/stdio.mjs +209 -0
- package/src/core-classic-source.mjs +43 -0
- package/src/import-map.mjs +62 -0
- package/src/native/portable-layout.mjs +184 -0
- package/src/native/portable-provider.mjs +211 -0
- package/src/native-plan.mjs +10 -4
- package/src/native-provider-loader.mjs +15 -4
- package/src/packager/core.mjs +131 -32
- package/src/process.mjs +8 -4
- package/src/targets/index.mjs +3 -1
- package/src/toolchain.mjs +23 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.
|
|
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",
|
package/src/app-descriptor.mjs
CHANGED
|
@@ -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
|
},
|
package/src/app-layout.mjs
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
109
|
-
|
|
110
|
-
|
|
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
|
+
}
|