arcane-os 0.1.0 → 0.1.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.
- package/NOTICE +10 -0
- package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +80 -4
- package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +69 -0
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +1151 -0
- package/browser-runtime/ai/browser-wasm.mjs +44 -0
- package/browser-runtime/ai/browser-wllama-runtime.mjs +390 -0
- package/browser-runtime/ai/internal/sha256.mjs +166 -0
- package/browser-runtime/ai/model-controller.mjs +581 -0
- package/browser-runtime/ai/wllama/LICENCE +21 -0
- package/browser-runtime/ai/wllama/index.mjs +3494 -0
- package/browser-runtime/ai/wllama/llama.cpp-LICENSE +21 -0
- package/browser-runtime/ai/wllama/wllama.wasm +0 -0
- package/docs/publishing.md +23 -18
- package/docs/reference/README.md +9 -5
- package/docs/reference/ai/browser-wasm.md +335 -0
- package/docs/reference/availability-and-normalization.md +17 -0
- package/docs/reference/behavioral-testing.md +8 -0
- package/docs/reference/cli.md +86 -3
- package/docs/reference/event-manager.md +15 -6
- package/docs/reference/inventory/package-api.json +84 -4
- package/docs/reference/protocols.md +113 -14
- package/docs/reference/sdk-api.md +244 -11
- package/package.json +8 -5
- package/runtime/ARCANE_RUNTIME_RELEASE.json +1 -1
- package/schemas/arcane-lock.schema.json +17 -6
- package/src/dev-server.mjs +2 -1
- package/src/doctor.mjs +1 -1
- package/src/import-map.mjs +25 -1
- package/src/sdk-browser-runtime.mjs +134 -17
- package/src/templates/workspace-template.mjs +6 -0
- package/src/workspace.mjs +7 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"./toolchain": "./src/toolchain.mjs",
|
|
14
14
|
"./events": "./src/events.mjs",
|
|
15
15
|
"./event-manager": "./src/event-manager.mjs",
|
|
16
|
+
"./ai/browser-wasm": "./browser-runtime/ai/browser-wasm.mjs",
|
|
16
17
|
"./testing": "./src/testing.mjs",
|
|
17
18
|
"./targets": "./src/targets/index.mjs",
|
|
18
19
|
"./native": "./src/native-plan.mjs",
|
|
@@ -46,14 +47,13 @@
|
|
|
46
47
|
],
|
|
47
48
|
"scripts": {
|
|
48
49
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
49
|
-
"test:release": "
|
|
50
|
+
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
50
51
|
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/contracts.test.mjs test/doctor.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
|
|
51
52
|
"test:functional": "node ./bin/arcane-test.mjs test/cli.test.mjs test/dev-server.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/import-map.test.mjs test/packaging.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime-sync.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/site.test.mjs test/update-check.test.mjs",
|
|
52
|
-
"test:functional:release": "node ./bin/arcane-test.mjs test/cli.test.mjs test/dev-server.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/import-map.test.mjs test/packaging.test.mjs test/runtime-api-behavior.test.mjs test/runtime-sync.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/update-check.test.mjs",
|
|
53
53
|
"test:integration": "node ./bin/arcane-test.mjs test/integrated-shared.test.mjs test/integrated-workspace.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",
|
|
54
54
|
"test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/native-provider-generation.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
|
|
55
55
|
"check": "node tools/check-source.mjs && node tools/runtime-manifest.mjs --verify && node tools/sdk-browser-runtime-manifest.mjs --verify && npm test",
|
|
56
|
-
"check:release": "node tools/check-source.mjs && node tools/runtime-manifest.mjs --verify && node tools/sdk-browser-runtime-manifest.mjs --verify && npm run test:release",
|
|
56
|
+
"check:release": "node tools/check-source.mjs --package-only && node tools/runtime-manifest.mjs --verify && node tools/sdk-browser-runtime-manifest.mjs --verify && npm run test:release",
|
|
57
57
|
"runtime:verify": "node tools/runtime-manifest.mjs --verify",
|
|
58
58
|
"runtime:sync": "node tools/sync-runtime.mjs",
|
|
59
59
|
"pack:local": "npm pack --ignore-scripts",
|
|
@@ -95,5 +95,8 @@
|
|
|
95
95
|
"bundleDependencies": [
|
|
96
96
|
"event-pubsub",
|
|
97
97
|
"strong-type"
|
|
98
|
-
]
|
|
98
|
+
],
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"@wllama/wllama": "3.6.0"
|
|
101
|
+
}
|
|
99
102
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"const": "arcane-os"
|
|
29
29
|
},
|
|
30
30
|
"version": {
|
|
31
|
-
"const": "0.1.
|
|
31
|
+
"const": "0.1.2"
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
},
|
|
@@ -69,16 +69,16 @@
|
|
|
69
69
|
"const": "node_modules/arcane-os/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json"
|
|
70
70
|
},
|
|
71
71
|
"manifestSha256": {
|
|
72
|
-
"const": "
|
|
72
|
+
"const": "88395493b411fd5461fbb2bb065ae2b745f6d1672f796583fd248ec97f71f4f7"
|
|
73
73
|
},
|
|
74
74
|
"contentSha256": {
|
|
75
|
-
"const": "
|
|
75
|
+
"const": "5e03f45a732db51cb5a2b2193cc79ecda34501d07a9b2e82e794e5fa37d55d00"
|
|
76
76
|
},
|
|
77
77
|
"builder": {
|
|
78
78
|
"const": "arcane-sdk-browser-runtime-v1"
|
|
79
79
|
},
|
|
80
80
|
"sdkVersion": {
|
|
81
|
-
"const": "0.1.
|
|
81
|
+
"const": "0.1.2"
|
|
82
82
|
},
|
|
83
83
|
"source": {
|
|
84
84
|
"type": "object",
|
|
@@ -105,8 +105,8 @@
|
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
107
|
"type": "array",
|
|
108
|
-
"minItems":
|
|
109
|
-
"maxItems":
|
|
108
|
+
"minItems": 3,
|
|
109
|
+
"maxItems": 3,
|
|
110
110
|
"prefixItems": [
|
|
111
111
|
{
|
|
112
112
|
"type": "object",
|
|
@@ -129,6 +129,17 @@
|
|
|
129
129
|
"resolved": {"const": "https://registry.npmjs.org/strong-type/-/strong-type-2.0.0.tgz"},
|
|
130
130
|
"integrity": {"const": "sha512-HHrY9qYC7yn+5mlewiI3k9RQM9gZqGQsqbomZcd10Ks0h4RlX01nnkWbCe4AsVPCI6KaFvpkWm1nHMD+Ykup6g=="}
|
|
131
131
|
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"type": "object",
|
|
135
|
+
"additionalProperties": false,
|
|
136
|
+
"required": ["name", "version", "resolved", "integrity"],
|
|
137
|
+
"properties": {
|
|
138
|
+
"name": {"const": "@wllama/wllama"},
|
|
139
|
+
"version": {"const": "3.6.0"},
|
|
140
|
+
"resolved": {"const": "https://registry.npmjs.org/@wllama/wllama/-/wllama-3.6.0.tgz"},
|
|
141
|
+
"integrity": {"const": "sha512-NN3ZBXqaaUwGXTQubkNvsCaLPjN2XVa0bVS40OYCE8zquYmRc2W3oHYEgwvuSWWDB8aUqTLyMioySCXNkcnD1w=="}
|
|
142
|
+
}
|
|
132
143
|
}
|
|
133
144
|
],
|
|
134
145
|
"items": false
|
package/src/dev-server.mjs
CHANGED
|
@@ -31,6 +31,7 @@ const MIME_TYPES=new Map([
|
|
|
31
31
|
['.png','image/png'],
|
|
32
32
|
['.svg','image/svg+xml; charset=utf-8'],
|
|
33
33
|
['.txt','text/plain; charset=utf-8'],
|
|
34
|
+
['.wasm','application/wasm'],
|
|
34
35
|
['.webp','image/webp'],
|
|
35
36
|
['.woff','font/woff'],
|
|
36
37
|
['.woff2','font/woff2']
|
|
@@ -51,7 +52,7 @@ const PRIVATE_SOURCE_SEGMENTS=new Set([
|
|
|
51
52
|
// development CSP from being exposed as a general network service.
|
|
52
53
|
const DEVELOPMENT_CSP=[
|
|
53
54
|
"default-src 'self'",
|
|
54
|
-
"script-src 'self' 'unsafe-inline'",
|
|
55
|
+
"script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'",
|
|
55
56
|
"style-src 'self' 'unsafe-inline'",
|
|
56
57
|
"img-src 'self' data: blob: http: https:",
|
|
57
58
|
"font-src 'self' data:",
|
package/src/doctor.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import {runProcess} from './process.mjs';
|
|
|
8
8
|
import {ARCANE_PROTOCOL,SDK_VERSION} from './constants.mjs';
|
|
9
9
|
import {ERROR_CODES,ArcaneError,throwIfAborted} from './errors.mjs';
|
|
10
10
|
|
|
11
|
-
const MINIMUM_NODE=[22,
|
|
11
|
+
const MINIMUM_NODE=[22,23,2];
|
|
12
12
|
const WINDOWS_SERVICE_NAME='ArcaneOllama';
|
|
13
13
|
const WINDOWS_SERVICE_HOST='C:\\Program Files\\Ollama\\ArcaneOllamaService.exe';
|
|
14
14
|
const WINDOWS_SERVICE_COMMAND=`"${WINDOWS_SERVICE_HOST}"`;
|
package/src/import-map.mjs
CHANGED
|
@@ -15,7 +15,18 @@ const JAVASCRIPT_EXTENSION=/\.(?:js|mjs)$/u;
|
|
|
15
15
|
const NODE_ONLY_MODULE='modules/CaseEvidenceIndexer.js';
|
|
16
16
|
const RUNTIME_STRONG_TYPE_IMPORT='../../node_modules/strong-type/index.js';
|
|
17
17
|
const SDK_BROWSER_ENTRY='sdk/event-manager.mjs';
|
|
18
|
+
const SDK_BROWSER_AI_ENTRY='sdk/ai/browser-wasm.mjs';
|
|
18
19
|
const SDK_BROWSER_FILES=Object.freeze([
|
|
20
|
+
'sdk/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json',
|
|
21
|
+
'sdk/ai/browser-wasm-llm-provider.mjs',
|
|
22
|
+
SDK_BROWSER_AI_ENTRY,
|
|
23
|
+
'sdk/ai/browser-wllama-runtime.mjs',
|
|
24
|
+
'sdk/ai/internal/sha256.mjs',
|
|
25
|
+
'sdk/ai/model-controller.mjs',
|
|
26
|
+
'sdk/ai/wllama/LICENCE',
|
|
27
|
+
'sdk/ai/wllama/index.mjs',
|
|
28
|
+
'sdk/ai/wllama/llama.cpp-LICENSE',
|
|
29
|
+
'sdk/ai/wllama/wllama.wasm',
|
|
19
30
|
SDK_BROWSER_ENTRY,
|
|
20
31
|
'sdk/dom-event-instrumentation.mjs',
|
|
21
32
|
'sdk/dependencies/event-pubsub/index.js',
|
|
@@ -954,6 +965,10 @@ export async function buildImportMap({files,readFile,signal}={}){
|
|
|
954
965
|
roots.push(relative);
|
|
955
966
|
}
|
|
956
967
|
const hasSdkBrowserGraph=inventory.has(SDK_BROWSER_ENTRY);
|
|
968
|
+
const hasSdkAiGraph=inventory.has(SDK_BROWSER_AI_ENTRY);
|
|
969
|
+
if(hasSdkAiGraph&&!hasSdkBrowserGraph){
|
|
970
|
+
unresolved(SDK_BROWSER_AI_ENTRY,'<authenticated SDK browser closure>',SDK_BROWSER_ENTRY);
|
|
971
|
+
}
|
|
957
972
|
if(hasSdkBrowserGraph){
|
|
958
973
|
for(const required of SDK_BROWSER_FILES){
|
|
959
974
|
if(!inventory.has(required)){
|
|
@@ -995,9 +1010,18 @@ export async function buildImportMap({files,readFile,signal}={}){
|
|
|
995
1010
|
'arcane-os/event-manager',
|
|
996
1011
|
'./arcane/sdk/event-manager.mjs'
|
|
997
1012
|
);
|
|
1013
|
+
if(hasSdkAiGraph){
|
|
1014
|
+
registerSpecifier(
|
|
1015
|
+
namedRegistry,
|
|
1016
|
+
'arcane-os/ai/browser-wasm',
|
|
1017
|
+
'./arcane/sdk/ai/browser-wasm.mjs'
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
998
1020
|
}
|
|
999
1021
|
|
|
1000
|
-
const
|
|
1022
|
+
const sdkRoots=hasSdkBrowserGraph
|
|
1023
|
+
?[SDK_BROWSER_ENTRY,...(hasSdkAiGraph?[SDK_BROWSER_AI_ENTRY]:[])]:[];
|
|
1024
|
+
const queue=[...roots,...sdkRoots];
|
|
1001
1025
|
const reached=new Set();
|
|
1002
1026
|
const entities=new Set();
|
|
1003
1027
|
let usesRuntimeStrongType=false;
|
|
@@ -9,9 +9,9 @@ const MANIFEST_NAME='ARCANE_SDK_BROWSER_RELEASE.json';
|
|
|
9
9
|
const BUILDER='arcane-sdk-browser-runtime-v1';
|
|
10
10
|
const PROTOCOL='arcane-sdk-browser-runtime/1';
|
|
11
11
|
export const SDK_BROWSER_RUNTIME_MANIFEST_SHA256=
|
|
12
|
-
'
|
|
12
|
+
'88395493b411fd5461fbb2bb065ae2b745f6d1672f796583fd248ec97f71f4f7';
|
|
13
13
|
export const SDK_BROWSER_RUNTIME_CONTENT_SHA256=
|
|
14
|
-
'
|
|
14
|
+
'5e03f45a732db51cb5a2b2193cc79ecda34501d07a9b2e82e794e5fa37d55d00';
|
|
15
15
|
const REPOSITORY='https://github.com/TheWizardNexus/arcane-os-sdk.git';
|
|
16
16
|
const SHA256_PATTERN=/^[a-f0-9]{64}$/u;
|
|
17
17
|
const READ_ONLY_NO_FOLLOW=FS_CONSTANTS.O_RDONLY|(FS_CONSTANTS.O_NOFOLLOW??0);
|
|
@@ -19,8 +19,87 @@ const MAX_VERIFIED_FILE_BYTES=64*1024*1024;
|
|
|
19
19
|
const packageRoot=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
|
|
20
20
|
const defaultRoot=path.join(packageRoot,'browser-runtime');
|
|
21
21
|
const issuedReceipts=new WeakSet();
|
|
22
|
+
const expectedAiComponents=Object.freeze({
|
|
23
|
+
schemaVersion:1,
|
|
24
|
+
kind:'arcane-ai-browser-wasm-components',
|
|
25
|
+
protocol:'arcane-ai-browser-wasm/1',
|
|
26
|
+
packageExport:'arcane-os/ai/browser-wasm',
|
|
27
|
+
browserEntry:'ai/browser-wasm.mjs',
|
|
28
|
+
runtimePolicy:{
|
|
29
|
+
modelAuthorities:'caller-supplied-exact-bytes-and-sha256',
|
|
30
|
+
modelWeightsPacked:false,
|
|
31
|
+
remoteModelHelpers:false,
|
|
32
|
+
compatibilityRuntime:false,
|
|
33
|
+
toolCalls:'structural-only-never-executed'
|
|
34
|
+
},
|
|
35
|
+
components:[
|
|
36
|
+
{
|
|
37
|
+
name:'@wllama/wllama',
|
|
38
|
+
version:'3.6.0',
|
|
39
|
+
licenseSpdx:'MIT',
|
|
40
|
+
sourceRepository:'https://github.com/ngxson/wllama.git',
|
|
41
|
+
sourceRevision:'f16050d8d51a00602c6a2a6b8ac9c09f490eea7f',
|
|
42
|
+
npm:{
|
|
43
|
+
resolved:'https://registry.npmjs.org/@wllama/wllama/-/wllama-3.6.0.tgz',
|
|
44
|
+
integrity:'sha512-NN3ZBXqaaUwGXTQubkNvsCaLPjN2XVa0bVS40OYCE8zquYmRc2W3oHYEgwvuSWWDB8aUqTLyMioySCXNkcnD1w==',
|
|
45
|
+
tarballBytes:5671369,
|
|
46
|
+
tarballSha256:'137c35ceccb4911a9b0ce9b427889f75991654ec6a6d1dd8fabd879b14b07a1b'
|
|
47
|
+
},
|
|
48
|
+
files:[
|
|
49
|
+
{
|
|
50
|
+
role:'runtime-module',
|
|
51
|
+
path:'ai/wllama/index.mjs',
|
|
52
|
+
sourcePath:'node_modules/@wllama/wllama/esm/index.js',
|
|
53
|
+
bytes:373519,
|
|
54
|
+
sha256:'4637e42d636010493a9b274fbbe70bfd8120365da726b1d9e589d85ca84a00d6'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
role:'runtime-wasm',
|
|
58
|
+
path:'ai/wllama/wllama.wasm',
|
|
59
|
+
sourcePath:'node_modules/@wllama/wllama/esm/wasm/wllama.wasm',
|
|
60
|
+
bytes:8524865,
|
|
61
|
+
sha256:'95c6ff9ef2a03ff2c63bc91db132f0126a0bd0456b272cd8ae2e0f592fb059f6'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
role:'license',
|
|
65
|
+
path:'ai/wllama/LICENCE',
|
|
66
|
+
sourcePath:'node_modules/@wllama/wllama/LICENCE',
|
|
67
|
+
bytes:1071,
|
|
68
|
+
sha256:'5866e3bd7e3cbd3f7c8bea6efd8a1e7fa7cc8de68c30f428aff7c6584a0fb720'
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name:'llama.cpp',
|
|
74
|
+
version:'b10454',
|
|
75
|
+
licenseSpdx:'MIT',
|
|
76
|
+
sourceRepository:'https://github.com/ggerganov/llama.cpp.git',
|
|
77
|
+
sourceRevision:'4df29be4f4c3673f428170fda944a5b19f743bb8',
|
|
78
|
+
embeddedBy:'@wllama/wllama@3.6.0',
|
|
79
|
+
files:[
|
|
80
|
+
{
|
|
81
|
+
role:'license',
|
|
82
|
+
path:'ai/wllama/llama.cpp-LICENSE',
|
|
83
|
+
sourceUrl:'https://raw.githubusercontent.com/ggerganov/llama.cpp/4df29be4f4c3673f428170fda944a5b19f743bb8/LICENSE',
|
|
84
|
+
bytes:1078,
|
|
85
|
+
sha256:'94f29bbed6a22c35b992c5c6ebf0e7c92f13b836b90f36f461c9cf2f0f1d010d'
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
});
|
|
22
91
|
|
|
23
92
|
const expectedFiles=Object.freeze([
|
|
93
|
+
['ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json','browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json','sdk-source-identity'],
|
|
94
|
+
['ai/browser-wasm-llm-provider.mjs','browser-runtime/ai/browser-wasm-llm-provider.mjs','sdk-source-identity'],
|
|
95
|
+
['ai/browser-wasm.mjs','browser-runtime/ai/browser-wasm.mjs','sdk-source-identity'],
|
|
96
|
+
['ai/browser-wllama-runtime.mjs','browser-runtime/ai/browser-wllama-runtime.mjs','sdk-source-identity'],
|
|
97
|
+
['ai/internal/sha256.mjs','browser-runtime/ai/internal/sha256.mjs','sdk-source-identity'],
|
|
98
|
+
['ai/model-controller.mjs','browser-runtime/ai/model-controller.mjs','sdk-source-identity'],
|
|
99
|
+
['ai/wllama/LICENCE','node_modules/@wllama/wllama/LICENCE','vendor-package-identity'],
|
|
100
|
+
['ai/wllama/index.mjs','node_modules/@wllama/wllama/esm/index.js','vendor-package-identity'],
|
|
101
|
+
['ai/wllama/llama.cpp-LICENSE','browser-runtime/ai/wllama/llama.cpp-LICENSE','vendor-source-identity'],
|
|
102
|
+
['ai/wllama/wllama.wasm','node_modules/@wllama/wllama/esm/wasm/wllama.wasm','vendor-package-identity'],
|
|
24
103
|
['dependencies/event-pubsub/index.js','node_modules/event-pubsub/index.js','vendor-package-identity'],
|
|
25
104
|
['dependencies/event-pubsub/licence','node_modules/event-pubsub/licence','vendor-package-identity'],
|
|
26
105
|
['dependencies/event-pubsub/package.json','node_modules/event-pubsub/package.json','vendor-package-identity'],
|
|
@@ -83,13 +162,35 @@ function immutableInventory(files){
|
|
|
83
162
|
return Object.freeze(files.map(file=>Object.freeze({...file})));
|
|
84
163
|
}
|
|
85
164
|
|
|
165
|
+
function validateAiComponents(bytes,releaseFiles){
|
|
166
|
+
let receipt;
|
|
167
|
+
try{receipt=JSON.parse(bytes.toString('utf8'));}
|
|
168
|
+
catch(error){fail(`Arcane AI browser WASM component receipt is invalid JSON: ${error.message}`);}
|
|
169
|
+
if(JSON.stringify(receipt)!==JSON.stringify(expectedAiComponents)){
|
|
170
|
+
fail('Arcane AI browser WASM component authority is invalid.');
|
|
171
|
+
}
|
|
172
|
+
for(const component of receipt.components){
|
|
173
|
+
for(const file of component.files){
|
|
174
|
+
const declared=releaseFiles.find(candidate=>candidate.path===file.path);
|
|
175
|
+
if(!declared||declared.bytes!==file.bytes||declared.sha256!==file.sha256
|
|
176
|
+
||('sourcePath' in file&&declared.sourcePath!==file.sourcePath)){
|
|
177
|
+
fail(`Arcane AI browser WASM component projection drifted for ${file.path}.`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function requiresInstalledPackageSource(file){
|
|
184
|
+
return !file.sourcePath.startsWith('node_modules/@wllama/wllama/');
|
|
185
|
+
}
|
|
186
|
+
|
|
86
187
|
function validateSource(source){
|
|
87
188
|
if(!source||typeof source!=='object'||Array.isArray(source)
|
|
88
189
|
||!exactKeys(source,['authority','browserEntry','dependencies','protocol','repository'])
|
|
89
190
|
||source.authority!=='arcane-os-sdk'||source.browserEntry!=='arcane-os/event-manager'
|
|
90
191
|
||source.protocol!==PROTOCOL
|
|
91
192
|
||source.repository!==REPOSITORY||!Array.isArray(source.dependencies)
|
|
92
|
-
||source.dependencies.length!==
|
|
193
|
+
||source.dependencies.length!==3){
|
|
93
194
|
fail('SDK browser runtime manifest source authority is invalid.');
|
|
94
195
|
}
|
|
95
196
|
const expectedDependencies=[
|
|
@@ -104,6 +205,12 @@ function validateSource(source){
|
|
|
104
205
|
version:'2.0.0',
|
|
105
206
|
resolved:'https://registry.npmjs.org/strong-type/-/strong-type-2.0.0.tgz',
|
|
106
207
|
integrity:'sha512-HHrY9qYC7yn+5mlewiI3k9RQM9gZqGQsqbomZcd10Ks0h4RlX01nnkWbCe4AsVPCI6KaFvpkWm1nHMD+Ykup6g=='
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name:'@wllama/wllama',
|
|
211
|
+
version:'3.6.0',
|
|
212
|
+
resolved:'https://registry.npmjs.org/@wllama/wllama/-/wllama-3.6.0.tgz',
|
|
213
|
+
integrity:'sha512-NN3ZBXqaaUwGXTQubkNvsCaLPjN2XVa0bVS40OYCE8zquYmRc2W3oHYEgwvuSWWDB8aUqTLyMioySCXNkcnD1w=='
|
|
107
214
|
}
|
|
108
215
|
];
|
|
109
216
|
for(const [index,expected] of expectedDependencies.entries()){
|
|
@@ -514,6 +621,7 @@ export async function verifySdkBrowserRuntime({
|
|
|
514
621
|
const identities=[];
|
|
515
622
|
const sourceIdentities=[];
|
|
516
623
|
const sourceRoot=path.dirname(canonical);
|
|
624
|
+
let aiComponentsBytes;
|
|
517
625
|
let verifiedBytes=0;
|
|
518
626
|
for(const [index,file] of release.files.entries()){
|
|
519
627
|
throwIfAborted(signal);
|
|
@@ -527,23 +635,28 @@ export async function verifySdkBrowserRuntime({
|
|
|
527
635
|
if(createHash('sha256').update(result.bytes).digest('hex')!==file.sha256){
|
|
528
636
|
fail(`SDK browser runtime integrity check failed for ${file.path}.`);
|
|
529
637
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
+`${file.path} (${file.sourcePath}).`
|
|
638
|
+
if(file.path==='ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json'){
|
|
639
|
+
aiComponentsBytes=result.bytes;
|
|
640
|
+
}
|
|
641
|
+
if(requiresInstalledPackageSource(file)){
|
|
642
|
+
const sourceResult=await openVerified(
|
|
643
|
+
containedPath(sourceRoot,file.sourcePath,'source file'),
|
|
644
|
+
{
|
|
645
|
+
expectedBytes:file.bytes,
|
|
646
|
+
root:sourceRoot,
|
|
647
|
+
relative:file.sourcePath,
|
|
648
|
+
signal
|
|
649
|
+
}
|
|
543
650
|
);
|
|
651
|
+
if(!result.bytes.equals(sourceResult.bytes)){
|
|
652
|
+
fail(
|
|
653
|
+
`SDK browser runtime file does not match its declared package source: `
|
|
654
|
+
+`${file.path} (${file.sourcePath}).`
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
sourceIdentities.push(Object.freeze({path:file.sourcePath,...sourceResult.identity}));
|
|
544
658
|
}
|
|
545
659
|
identities.push(Object.freeze({path:file.path,...result.identity}));
|
|
546
|
-
sourceIdentities.push(Object.freeze({path:file.sourcePath,...sourceResult.identity}));
|
|
547
660
|
verifiedBytes+=file.bytes;
|
|
548
661
|
await emit(onEvent,{
|
|
549
662
|
type:'sdk-browser-runtime.verify.progress',
|
|
@@ -554,6 +667,10 @@ export async function verifySdkBrowserRuntime({
|
|
|
554
667
|
path:file.path
|
|
555
668
|
});
|
|
556
669
|
}
|
|
670
|
+
if(!aiComponentsBytes){
|
|
671
|
+
fail('Arcane AI browser WASM component receipt is missing.');
|
|
672
|
+
}
|
|
673
|
+
validateAiComponents(aiComponentsBytes,release.files);
|
|
557
674
|
const receipt=Object.freeze({
|
|
558
675
|
schemaVersion:1,
|
|
559
676
|
kind:'arcane-sdk-browser-runtime-verification',
|
|
@@ -63,6 +63,12 @@ export function workspaceTemplate({
|
|
|
63
63
|
version:'2.0.0',
|
|
64
64
|
resolved:'https://registry.npmjs.org/strong-type/-/strong-type-2.0.0.tgz',
|
|
65
65
|
integrity:'sha512-HHrY9qYC7yn+5mlewiI3k9RQM9gZqGQsqbomZcd10Ks0h4RlX01nnkWbCe4AsVPCI6KaFvpkWm1nHMD+Ykup6g=='
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name:'@wllama/wllama',
|
|
69
|
+
version:'3.6.0',
|
|
70
|
+
resolved:'https://registry.npmjs.org/@wllama/wllama/-/wllama-3.6.0.tgz',
|
|
71
|
+
integrity:'sha512-NN3ZBXqaaUwGXTQubkNvsCaLPjN2XVa0bVS40OYCE8zquYmRc2W3oHYEgwvuSWWDB8aUqTLyMioySCXNkcnD1w=='
|
|
66
72
|
}
|
|
67
73
|
];
|
|
68
74
|
const packageInclude=[`${appId}.css`,'index.html'];
|
package/src/workspace.mjs
CHANGED
|
@@ -325,9 +325,15 @@ function validateLock(lock){
|
|
|
325
325
|
version:'2.0.0',
|
|
326
326
|
resolved:'https://registry.npmjs.org/strong-type/-/strong-type-2.0.0.tgz',
|
|
327
327
|
integrity:'sha512-HHrY9qYC7yn+5mlewiI3k9RQM9gZqGQsqbomZcd10Ks0h4RlX01nnkWbCe4AsVPCI6KaFvpkWm1nHMD+Ykup6g=='
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name:'@wllama/wllama',
|
|
331
|
+
version:'3.6.0',
|
|
332
|
+
resolved:'https://registry.npmjs.org/@wllama/wllama/-/wllama-3.6.0.tgz',
|
|
333
|
+
integrity:'sha512-NN3ZBXqaaUwGXTQubkNvsCaLPjN2XVa0bVS40OYCE8zquYmRc2W3oHYEgwvuSWWDB8aUqTLyMioySCXNkcnD1w=='
|
|
328
334
|
}
|
|
329
335
|
];
|
|
330
|
-
const dependenciesMatch=Array.isArray(dependencies)&&dependencies.length===
|
|
336
|
+
const dependenciesMatch=Array.isArray(dependencies)&&dependencies.length===expectedDependencies.length
|
|
331
337
|
&&dependencies.every((actual,index)=>{
|
|
332
338
|
const expected=expectedDependencies[index];
|
|
333
339
|
return exactKeys(actual,['name','version','resolved','integrity'])
|