arcane-os 0.55.0 → 0.57.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 +51 -0
- package/README.md +5 -3
- package/browser-runtime/ai/core-local.mjs +306 -0
- package/browser-runtime/core/client.mjs +75 -14
- package/browser-runtime/core/contracts.mjs +2 -1
- package/docs/consumer-updates.md +82 -0
- package/docs/publishing.md +41 -18
- package/docs/reference/README.md +31 -1
- package/docs/reference/availability-and-normalization.md +11 -3
- package/docs/reference/cli.md +9 -1
- package/docs/reference/core-client.md +45 -2
- package/docs/reference/core-native-packaging.md +195 -11
- package/docs/reference/core-runtime.md +10 -0
- package/docs/reference/inventory/package-api.json +160 -20
- package/docs/reference/local-ai.md +197 -0
- package/docs/reference/protocols.md +91 -14
- package/docs/reference/pwa.md +17 -0
- package/docs/reference/runtime-modules.md +6 -5
- package/docs/reference/sdk-api.md +165 -26
- package/package.json +5 -1
- package/runtime/arcane/modules/LocalAIReadiness.js +3 -1
- package/schemas/arcane-app.schema.json +64 -0
- package/schemas/arcane-package.schema.json +54 -0
- package/src/app-descriptor.mjs +35 -2
- package/src/app-layout.mjs +6 -2
- package/src/cli/main.mjs +8 -2
- 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/macos/ArcaneCoreProcess.h +85 -0
- package/src/core/hosts/macos/ArcaneCoreProcess.m +357 -0
- package/src/core/hosts/sea-launcher.cjs +17 -0
- package/src/core/hosts/windows/ArcaneCoreProcess.cs +416 -0
- package/src/core/hosts/windows/ArcaneHost.cs +695 -0
- package/src/core/hosts/windows/ArcaneHost.manifest +22 -0
- package/src/core/hosts/windows/ArcaneLauncher.cs +239 -0
- package/src/core/runtime.mjs +15 -3
- package/src/core/services/local-ai.mjs +543 -0
- package/src/core-classic-source.mjs +2 -2
- package/src/dev-server.mjs +7 -0
- package/src/import-map.mjs +1 -0
- package/src/local-ai/archive.mjs +52 -0
- package/src/local-ai/config.mjs +62 -0
- package/src/local-ai/dev.mjs +390 -0
- package/src/local-ai/discover.mjs +71 -0
- package/src/local-ai/http.mjs +106 -0
- package/src/local-ai/install.mjs +344 -0
- package/src/local-ai/server.mjs +262 -0
- package/src/native/portable-layout.mjs +29 -4
- package/src/native/portable-provider.mjs +39 -8
- package/src/native/windows-provider.mjs +262 -0
- package/src/native-provider-loader.mjs +8 -2
- package/src/packager/core.mjs +89 -15
- package/src/process.mjs +74 -12
- package/src/toolchain.mjs +38 -8
|
@@ -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,
|
|
@@ -109,6 +119,19 @@
|
|
|
109
119
|
"oneOf": [{ "$ref": "#/$defs/rasterIcon" }, { "type": "null" }]
|
|
110
120
|
},
|
|
111
121
|
"order": { "type": "integer", "minimum": 0 },
|
|
122
|
+
"services": {
|
|
123
|
+
"description": "Explicit application-owned Core factory modules from the selected native release. Factories receive authored options first and launch context second.",
|
|
124
|
+
"type": "array",
|
|
125
|
+
"items": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"required": ["module"],
|
|
128
|
+
"properties": {
|
|
129
|
+
"module": { "$ref": "#/$defs/relativePath" },
|
|
130
|
+
"options": {}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"localAI": { "$ref": "#/$defs/localAI" },
|
|
112
135
|
"bundledApps": {
|
|
113
136
|
"type": "array",
|
|
114
137
|
"uniqueItems": true,
|
|
@@ -230,6 +253,47 @@
|
|
|
230
253
|
}
|
|
231
254
|
],
|
|
232
255
|
"$defs": {
|
|
256
|
+
"localAI": {
|
|
257
|
+
"type": "object",
|
|
258
|
+
"required": ["runtimes"],
|
|
259
|
+
"description": "Required Core AI runtimes. Development ensures selected runtimes locally; native builds bundle their upstream runtime distributions. Model selection remains application-owned.",
|
|
260
|
+
"properties": {
|
|
261
|
+
"runtimes": {
|
|
262
|
+
"type": "array",
|
|
263
|
+
"items": {
|
|
264
|
+
"oneOf": [
|
|
265
|
+
{ "enum": ["llama.cpp", "ollama"] },
|
|
266
|
+
{
|
|
267
|
+
"type": "object",
|
|
268
|
+
"required": ["id"],
|
|
269
|
+
"properties": {
|
|
270
|
+
"id": { "enum": ["llama.cpp", "ollama"] },
|
|
271
|
+
"version": { "type": "string" },
|
|
272
|
+
"url": { "type": "string" }
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"llamaCpp": {
|
|
279
|
+
"type": "object",
|
|
280
|
+
"properties": {
|
|
281
|
+
"url": { "type": "string" },
|
|
282
|
+
"model": { "type": "string" },
|
|
283
|
+
"modelsDirectory": { "type": "string" },
|
|
284
|
+
"args": { "type": "array", "items": { "type": "string" } }
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
"ollama": {
|
|
288
|
+
"type": "object",
|
|
289
|
+
"properties": {
|
|
290
|
+
"url": { "type": "string" },
|
|
291
|
+
"modelsDirectory": { "type": "string" },
|
|
292
|
+
"args": { "type": "array", "items": { "type": "string" } }
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
},
|
|
233
297
|
"pwa": {
|
|
234
298
|
"type": "object",
|
|
235
299
|
"additionalProperties": false,
|
|
@@ -57,6 +57,9 @@
|
|
|
57
57
|
"localAIModelPolicy": {
|
|
58
58
|
"$ref": "#/$defs/localAIModelPolicy"
|
|
59
59
|
},
|
|
60
|
+
"localAI": {
|
|
61
|
+
"$ref": "#/$defs/localAI"
|
|
62
|
+
},
|
|
60
63
|
"pwa": {
|
|
61
64
|
"$ref": "#/$defs/pwa"
|
|
62
65
|
},
|
|
@@ -88,6 +91,16 @@
|
|
|
88
91
|
"exclude": {
|
|
89
92
|
"$ref": "#/$defs/pathList"
|
|
90
93
|
},
|
|
94
|
+
"nativeResources": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"required": ["include"],
|
|
98
|
+
"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.",
|
|
99
|
+
"properties": {
|
|
100
|
+
"include": { "$ref": "#/$defs/pathList" },
|
|
101
|
+
"exclude": { "$ref": "#/$defs/pathList" }
|
|
102
|
+
}
|
|
103
|
+
},
|
|
91
104
|
"shared": {
|
|
92
105
|
"type": "array",
|
|
93
106
|
"uniqueItems": true,
|
|
@@ -134,6 +147,47 @@
|
|
|
134
147
|
}
|
|
135
148
|
],
|
|
136
149
|
"$defs": {
|
|
150
|
+
"localAI": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"required": ["runtimes"],
|
|
153
|
+
"description": "Required Core AI runtimes. Development ensures selected runtimes locally; native builds bundle their upstream runtime distributions. Model selection remains application-owned.",
|
|
154
|
+
"properties": {
|
|
155
|
+
"runtimes": {
|
|
156
|
+
"type": "array",
|
|
157
|
+
"items": {
|
|
158
|
+
"oneOf": [
|
|
159
|
+
{ "enum": ["llama.cpp", "ollama"] },
|
|
160
|
+
{
|
|
161
|
+
"type": "object",
|
|
162
|
+
"required": ["id"],
|
|
163
|
+
"properties": {
|
|
164
|
+
"id": { "enum": ["llama.cpp", "ollama"] },
|
|
165
|
+
"version": { "type": "string" },
|
|
166
|
+
"url": { "type": "string" }
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"llamaCpp": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"properties": {
|
|
175
|
+
"url": { "type": "string" },
|
|
176
|
+
"model": { "type": "string" },
|
|
177
|
+
"modelsDirectory": { "type": "string" },
|
|
178
|
+
"args": { "type": "array", "items": { "type": "string" } }
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"ollama": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"properties": {
|
|
184
|
+
"url": { "type": "string" },
|
|
185
|
+
"modelsDirectory": { "type": "string" },
|
|
186
|
+
"args": { "type": "array", "items": { "type": "string" } }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
137
191
|
"pwa": {
|
|
138
192
|
"type": "object",
|
|
139
193
|
"additionalProperties": false,
|
package/src/app-descriptor.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import {readFile, writeFile} from 'node:fs/promises';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import {throwIfAborted} from './errors.mjs';
|
|
7
7
|
import {normalizePwaConfig} from './pwa.mjs';
|
|
8
|
+
import {normalizeLocalAIConfig} from './local-ai/config.mjs';
|
|
8
9
|
import {
|
|
9
10
|
ARCANE_MACHINE_BUNDLE_VERSION,
|
|
10
11
|
ARCANE_PROTOCOL,
|
|
@@ -111,13 +112,21 @@ function validateLocalAIModelPolicy(value,label){
|
|
|
111
112
|
|
|
112
113
|
function validatePackage(value,appId){
|
|
113
114
|
assertOnlyKeys(value,new Set([
|
|
114
|
-
'entry','strategy','include','exclude','shared','adapter','localAIModelPolicy','pwa','documents'
|
|
115
|
+
'entry','strategy','include','exclude','shared','adapter','localAIModelPolicy','pwa','documents','nativeResources'
|
|
115
116
|
]),'descriptor.package');
|
|
116
117
|
const entry=normalizeRelativePath(value.entry,'descriptor.package.entry');
|
|
117
118
|
const documents=normalizeAppDocuments(value.documents,'descriptor.package.documents');
|
|
118
119
|
if(!['static','adapter'].includes(value.strategy))fail('descriptor.package.strategy must be static or adapter.');
|
|
119
120
|
const include=relativePaths(value.include,'descriptor.package.include',{required:true});
|
|
120
121
|
const exclude=relativePaths(value.exclude??[],'descriptor.package.exclude');
|
|
122
|
+
let nativeResources;
|
|
123
|
+
if(value.nativeResources!==undefined){
|
|
124
|
+
assertOnlyKeys(value.nativeResources,new Set(['include','exclude']),'descriptor.package.nativeResources');
|
|
125
|
+
nativeResources={
|
|
126
|
+
include:relativePaths(value.nativeResources.include,'descriptor.package.nativeResources.include'),
|
|
127
|
+
exclude:relativePaths(value.nativeResources.exclude??[],'descriptor.package.nativeResources.exclude')
|
|
128
|
+
};
|
|
129
|
+
}
|
|
121
130
|
if(!include.some(candidate=>entry===candidate||entry.startsWith(`${candidate}/`))){
|
|
122
131
|
fail('descriptor.package.entry must be covered by descriptor.package.include.');
|
|
123
132
|
}
|
|
@@ -140,6 +149,7 @@ function validatePackage(value,appId){
|
|
|
140
149
|
strategy:value.strategy,
|
|
141
150
|
include,
|
|
142
151
|
exclude,
|
|
152
|
+
...(nativeResources===undefined?{}:{nativeResources}),
|
|
143
153
|
shared,
|
|
144
154
|
...(value.pwa===undefined?{}:{pwa:normalizePwaConfig(value.pwa)}),
|
|
145
155
|
...(adapter?{adapter}:{}),
|
|
@@ -226,7 +236,7 @@ function validateDocumentCatalog(value){
|
|
|
226
236
|
}
|
|
227
237
|
|
|
228
238
|
function validateNative(value,appId){
|
|
229
|
-
assertOnlyKeys(value,new Set(['type','icon','order','bundledApps','documentCatalog']),'descriptor.native');
|
|
239
|
+
assertOnlyKeys(value,new Set(['type','icon','order','bundledApps','documentCatalog','localAI','services']),'descriptor.native');
|
|
230
240
|
if(!NATIVE_TYPES.has(value.type))fail('descriptor.native.type is unsupported.');
|
|
231
241
|
const icon=value.icon===null?null:normalizeRelativePath(value.icon,'descriptor.native.icon');
|
|
232
242
|
if(!is.integer(value.order)||value.order<0){
|
|
@@ -236,11 +246,21 @@ function validateNative(value,appId){
|
|
|
236
246
|
pattern:APP_ID_PATTERN
|
|
237
247
|
});
|
|
238
248
|
const documentCatalog=validateDocumentCatalog(value.documentCatalog);
|
|
249
|
+
let services;
|
|
250
|
+
if(value.services!==undefined){
|
|
251
|
+
if(!is.array(value.services))fail('descriptor.native.services must be an array.');
|
|
252
|
+
services=value.services.map(function nativeService(service,index){
|
|
253
|
+
if(!isObject(service))fail(`descriptor.native.services[${index}] must be an object.`);
|
|
254
|
+
return {...service,module:normalizeRelativePath(service.module,`descriptor.native.services[${index}].module`)};
|
|
255
|
+
});
|
|
256
|
+
}
|
|
239
257
|
return completeValue({
|
|
240
258
|
type:value.type,
|
|
241
259
|
icon,
|
|
242
260
|
order:value.order,
|
|
243
261
|
bundledApps,
|
|
262
|
+
...(services===undefined?{}:{services}),
|
|
263
|
+
...(value.localAI===undefined?{}:{localAI:normalizeLocalAIConfig(value.localAI)}),
|
|
244
264
|
...(documentCatalog?{documentCatalog}:{})
|
|
245
265
|
});
|
|
246
266
|
}
|
|
@@ -328,9 +348,14 @@ export function projectPackageManifest(descriptor){
|
|
|
328
348
|
mediaOrigins:[...value.security.mediaOrigins]
|
|
329
349
|
}}:{}),
|
|
330
350
|
...(value.package.localAIModelPolicy?{localAIModelPolicy:value.package.localAIModelPolicy}:{}),
|
|
351
|
+
...(value.native.localAI===undefined?{}:{localAI:value.native.localAI}),
|
|
331
352
|
...(value.package.pwa===undefined?{}:{pwa:value.package.pwa}),
|
|
332
353
|
include:[...value.package.include],
|
|
333
354
|
exclude:[...value.package.exclude],
|
|
355
|
+
...(value.package.nativeResources===undefined?{}:{nativeResources:{
|
|
356
|
+
include:[...value.package.nativeResources.include],
|
|
357
|
+
exclude:[...value.package.nativeResources.exclude]
|
|
358
|
+
}}),
|
|
334
359
|
shared:[...value.package.shared],
|
|
335
360
|
...(value.package.adapter?{adapter:value.package.adapter}:{})
|
|
336
361
|
};
|
|
@@ -369,6 +394,8 @@ export function projectNativeDescriptor(descriptor,{source}={}){
|
|
|
369
394
|
}}:{}),
|
|
370
395
|
...(value.native.bundledApps.length?{bundledApps:[...value.native.bundledApps]}:{}),
|
|
371
396
|
...(value.native.documentCatalog?{documentCatalog:value.native.documentCatalog}:{}),
|
|
397
|
+
...(value.native.services===undefined?{}:{services:value.native.services}),
|
|
398
|
+
...(value.native.localAI===undefined?{}:{localAI:value.native.localAI}),
|
|
372
399
|
include:[...value.package.include]
|
|
373
400
|
};
|
|
374
401
|
}
|
|
@@ -391,6 +418,10 @@ function synthesizedDescriptor(packageManifest,nativeDescriptor){
|
|
|
391
418
|
...(packageManifest.pwa===undefined?{}:{pwa:packageManifest.pwa}),
|
|
392
419
|
include:[...packageManifest.include],
|
|
393
420
|
exclude:[...(packageManifest.exclude??[])],
|
|
421
|
+
...(packageManifest.nativeResources===undefined?{}:{nativeResources:{
|
|
422
|
+
include:[...packageManifest.nativeResources.include],
|
|
423
|
+
exclude:[...(packageManifest.nativeResources.exclude??[])]
|
|
424
|
+
}}),
|
|
394
425
|
shared:[...packageManifest.shared],
|
|
395
426
|
...(packageManifest.adapter?{adapter:packageManifest.adapter}:{})
|
|
396
427
|
},
|
|
@@ -408,6 +439,8 @@ function synthesizedDescriptor(packageManifest,nativeDescriptor){
|
|
|
408
439
|
icon:native.icon??null,
|
|
409
440
|
order:is.integer(native.order)?native.order:100,
|
|
410
441
|
bundledApps:[...(native.bundledApps??[])],
|
|
442
|
+
...(native.services===undefined?{}:{services:native.services}),
|
|
443
|
+
...((packageManifest.localAI??native.localAI)===undefined?{}:{localAI:packageManifest.localAI??native.localAI}),
|
|
411
444
|
...(native.documentCatalog?{documentCatalog:native.documentCatalog}:{})
|
|
412
445
|
},
|
|
413
446
|
requirements:{
|
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
|
@@ -16,6 +16,7 @@ const VALUE_OPTIONS=new Set([
|
|
|
16
16
|
'app',
|
|
17
17
|
'apps-root',
|
|
18
18
|
'sdk-runtime-source',
|
|
19
|
+
'local-ai',
|
|
19
20
|
'arcane-root',
|
|
20
21
|
'host',
|
|
21
22
|
'port',
|
|
@@ -66,7 +67,7 @@ Usage:
|
|
|
66
67
|
${CLI_NAME} upgrade [--workspace <directory>] [--app <id>]
|
|
67
68
|
${CLI_NAME} doctor [--workspace <directory>] [--arcane-root <directory>]
|
|
68
69
|
${CLI_NAME} import-map [--workspace <directory>] [--app <id>]
|
|
69
|
-
${CLI_NAME} dev [--app <id>] [--public] [--http | --https] [--cert <pem>] [--key <pem>] [--host <address>] [--port 8000] [--http-port 0] [--sdk-runtime-source <sdk-root>]
|
|
70
|
+
${CLI_NAME} dev [--app <id>] [--public] [--http | --https] [--cert <pem>] [--key <pem>] [--host <address>] [--port 8000] [--http-port 0] [--sdk-runtime-source <sdk-root>] [--local-ai llama.cpp,ollama]
|
|
70
71
|
${CLI_NAME} test [--app <id>] [--scope app]
|
|
71
72
|
${CLI_NAME} test --scope shared --test-file <repo-relative.test.mjs>
|
|
72
73
|
${CLI_NAME} check [--app <id>] [--scope app] [--skip-tests]
|
|
@@ -97,6 +98,7 @@ Development:
|
|
|
97
98
|
--host <address> Override the bind address; takes precedence over --public.
|
|
98
99
|
--http-port <port> Browser dev/run HTTP redirect port; 0 selects an available port (default).
|
|
99
100
|
--sdk-runtime-source <sdk-root> Dev-only live SDK checkout; omitted preserves the workspace runtime mode.
|
|
101
|
+
--local-ai <runtimes> Add required Core runtimes to app config and ensure them for development.
|
|
100
102
|
|
|
101
103
|
Global:
|
|
102
104
|
--workspace <directory> Select an external or integrated Arcane workspace.
|
|
@@ -450,6 +452,9 @@ function operationOptions(command,parsed,cwd){
|
|
|
450
452
|
if(values['sdk-runtime-source']!==undefined&&command!=='dev'){
|
|
451
453
|
usage('--sdk-runtime-source is supported only by dev.');
|
|
452
454
|
}
|
|
455
|
+
if(values['local-ai']!==undefined&&command!=='dev'){
|
|
456
|
+
usage('--local-ai is supported only by dev.');
|
|
457
|
+
}
|
|
453
458
|
if(flags.has('public')&&command!=='dev'){
|
|
454
459
|
usage('--public is supported only by dev.');
|
|
455
460
|
}
|
|
@@ -546,6 +551,7 @@ function operationOptions(command,parsed,cwd){
|
|
|
546
551
|
...browserServerOptions,
|
|
547
552
|
host:values.host??(flags.has('public')?'0.0.0.0':'127.0.0.1'),
|
|
548
553
|
port:readPort(values.port,8000),
|
|
554
|
+
...(values['local-ai']===undefined?{}:{localAI:values['local-ai']}),
|
|
549
555
|
...(values['sdk-runtime-source']===undefined?{}:{
|
|
550
556
|
sdkRuntimeSourceRoot:path.resolve(cwd,values['sdk-runtime-source'])
|
|
551
557
|
})
|
|
@@ -811,7 +817,7 @@ async function pairNativeProvider(command,options,loadProvider,{signal,onEvent}=
|
|
|
811
817
|
usage(`${command} requires one native target.`);
|
|
812
818
|
}
|
|
813
819
|
const targetRequest=createNativeTargetRequest(options);
|
|
814
|
-
if(!options.arcaneRoot
|
|
820
|
+
if(!options.arcaneRoot&&!['portable','windows-x64'].includes(options.target)){
|
|
815
821
|
usage(`${command} for target ${options.target} requires --arcane-root <directory>.`);
|
|
816
822
|
}
|
|
817
823
|
const loaded=await loadProvider({
|
package/src/core/host.mjs
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
|
+
import {readFile} from 'node:fs/promises';
|
|
2
|
+
import Is from 'strong-type';
|
|
1
3
|
import {createCoreRuntime} from './runtime.mjs';
|
|
2
4
|
import {startCoreStdio} from './stdio.mjs';
|
|
3
5
|
|
|
6
|
+
const is = new Is(false);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Read only the explicitly supplied --arcane-launch-config filename.
|
|
10
|
+
* Return the complete JSON object for the service factories' second argument;
|
|
11
|
+
* field meanings belong to the launch owner and individual services.
|
|
12
|
+
*/
|
|
13
|
+
export async function readCoreLaunchContext({argv = process.argv.slice(2)} = {}) {
|
|
14
|
+
const flag = argv.indexOf('--arcane-launch-config');
|
|
15
|
+
if (flag === -1) return {};
|
|
16
|
+
const filename = argv[flag + 1];
|
|
17
|
+
if (filename === undefined || filename === '') {
|
|
18
|
+
throw new TypeError('--arcane-launch-config requires a filename.');
|
|
19
|
+
}
|
|
20
|
+
const context = JSON.parse(await readFile(filename, 'utf8'));
|
|
21
|
+
if (context === null || !is.object(context) || is.array(context)) {
|
|
22
|
+
throw new TypeError('Core launch configuration must be a JSON object.');
|
|
23
|
+
}
|
|
24
|
+
return context;
|
|
25
|
+
}
|
|
26
|
+
|
|
4
27
|
/** Compose app services with the shared dispatcher and draining transport. */
|
|
5
28
|
export function startCoreHost({application, version, services = [], input, output, onError, signal} = {}) {
|
|
6
29
|
const runtime = createCoreRuntime({application, version, services});
|