arcane-os 0.56.0 → 0.58.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 +43 -0
- package/README.md +6 -2
- package/browser-runtime/ai/core-local.mjs +306 -0
- package/browser-runtime/ai/core-onnx.mjs +96 -0
- package/browser-runtime/ai/onnx-tensors.mjs +85 -0
- package/browser-runtime/core/client.mjs +151 -16
- package/docs/architecture.md +5 -2
- package/docs/platform-targets.md +30 -13
- package/docs/reference/README.md +38 -3
- package/docs/reference/availability-and-normalization.md +9 -6
- package/docs/reference/cli.md +29 -9
- package/docs/reference/core-client.md +80 -0
- package/docs/reference/core-native-packaging.md +304 -12
- package/docs/reference/core-preferences.md +49 -0
- package/docs/reference/diarization.md +206 -0
- package/docs/reference/git-text-snapshot.md +104 -0
- package/docs/reference/inventory/package-api.json +330 -22
- package/docs/reference/local-ai.md +331 -0
- package/docs/reference/protocols.md +97 -20
- package/docs/reference/pwa.md +5 -2
- package/docs/reference/runtime-modules.md +6 -5
- package/docs/reference/sdk-api.md +611 -63
- package/package.json +15 -3
- package/runtime/arcane/modules/LocalAIReadiness.js +3 -1
- package/schemas/arcane-app.schema.json +55 -1
- package/schemas/arcane-package.schema.json +44 -0
- package/schemas/native-build-plan.schema.json +27 -1
- package/schemas/target-adapter.schema.json +2 -0
- package/src/app-descriptor.mjs +18 -2
- package/src/cli/main.mjs +20 -4
- package/src/constants.mjs +2 -0
- package/src/core/host.mjs +23 -0
- package/src/core/hosts/macos/ArcaneCoreProcess.h +85 -0
- package/src/core/hosts/macos/ArcaneCoreProcess.m +357 -0
- package/src/core/hosts/macos/ArcaneHost.h +86 -0
- package/src/core/hosts/macos/ArcaneHost.m +455 -0
- package/src/core/hosts/macos/ArcaneLauncher.m +432 -0
- package/src/core/hosts/windows/ArcaneCoreProcess.cs +3 -3
- 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/services/local-ai.mjs +621 -0
- package/src/core/services/packaged-web.mjs +89 -0
- package/src/core/services/preferences.mjs +201 -0
- package/src/core-classic-source.mjs +2 -2
- package/src/dev-server.mjs +9 -5
- package/src/diarization/build.mjs +35 -0
- package/src/diarization/index.mjs +432 -0
- package/src/diarization/native/CMakeLists.txt +9 -0
- package/src/diarization/native/main.cpp +269 -0
- package/src/diarization/service.mjs +129 -0
- package/src/git-text-snapshot.mjs +265 -0
- package/src/import-map.mjs +2 -0
- package/src/index.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 +459 -0
- package/src/local-ai/onnx-worker.mjs +85 -0
- package/src/local-ai/onnx.mjs +368 -0
- package/src/local-ai/server.mjs +262 -0
- package/src/native/macos-provider.mjs +291 -0
- package/src/native/portable-layout.mjs +37 -4
- package/src/native/portable-provider.mjs +44 -8
- package/src/native/windows-provider.mjs +262 -0
- package/src/native-plan.mjs +9 -1
- package/src/native-provider-loader.mjs +10 -2
- package/src/packager/core.mjs +6 -2
- package/src/process.mjs +184 -20
- package/src/scaffold.mjs +1 -1
- package/src/targets/index.mjs +11 -1
- package/src/templates/workspace-template.mjs +6 -5
- package/src/toolchain.mjs +33 -5
|
@@ -14,6 +14,7 @@ export function createCoreClient({
|
|
|
14
14
|
eventOwnerReady,
|
|
15
15
|
autoConnect=true,
|
|
16
16
|
replayRuntimeState=false,
|
|
17
|
+
webKitDocumentLifecycle=false,
|
|
17
18
|
onError=error=>global.console?.error('Arcane Core client failed.',error)
|
|
18
19
|
}={}){
|
|
19
20
|
const pending=new Map();
|
|
@@ -29,6 +30,7 @@ export function createCoreClient({
|
|
|
29
30
|
let eventOwnerFailure=null;
|
|
30
31
|
let transportFailure=null;
|
|
31
32
|
let transportFailureReported=false;
|
|
33
|
+
let webKitDocument=null;
|
|
32
34
|
|
|
33
35
|
function report(error){
|
|
34
36
|
if(error===transportFailure){
|
|
@@ -67,8 +69,13 @@ export function createCoreClient({
|
|
|
67
69
|
report(eventOwnerFailure);
|
|
68
70
|
});
|
|
69
71
|
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
+
function acceptsNativeDelivery(activation){
|
|
73
|
+
return !closed&&(!webKitDocument||webKitDocument.current(activation));
|
|
74
|
+
}
|
|
75
|
+
function emit(event,data,activation=webKitDocument?.activation){
|
|
76
|
+
withEvents(function deliverEvent(){
|
|
77
|
+
if(acceptsNativeDelivery(activation))source.dispatch(CORE_EVENT,{event,data});
|
|
78
|
+
});
|
|
72
79
|
}
|
|
73
80
|
function complete(event,data){
|
|
74
81
|
if(completedEvents.has(event))return false;
|
|
@@ -110,13 +117,23 @@ export function createCoreClient({
|
|
|
110
117
|
if(typeof listener!=='function')throw new TypeError('Arcane event listener must be a function.');
|
|
111
118
|
if(!completedEvents.has(event))return events.once(event,listener);
|
|
112
119
|
const value=completedEvents.get(event);
|
|
120
|
+
const activation=webKitDocument?.activation;
|
|
113
121
|
let active=!closed;
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
let dispose=null;
|
|
123
|
+
function deliverReadyEvent(ready){
|
|
124
|
+
if(!active)return;
|
|
116
125
|
active=false;
|
|
117
|
-
|
|
126
|
+
dispose?.();
|
|
127
|
+
try{listener(ready);}catch(error){report(error);}
|
|
128
|
+
}
|
|
129
|
+
// A ready-state subscription survives a retirement that happens
|
|
130
|
+
// before its queued replay, just like an ordinary registration.
|
|
131
|
+
if(webKitDocument)dispose=events.once(event,deliverReadyEvent);
|
|
132
|
+
Promise.resolve().then(function replayReadyEvent(){
|
|
133
|
+
if(!active||!acceptsNativeDelivery(activation))return;
|
|
134
|
+
deliverReadyEvent(value);
|
|
118
135
|
});
|
|
119
|
-
return function unsubscribe(){active=false;};
|
|
136
|
+
return function unsubscribe(){active=false;dispose?.();};
|
|
120
137
|
},
|
|
121
138
|
completed(event){return CORE_READY_EVENTS.includes(event)&&completedEvents.has(event);}
|
|
122
139
|
};
|
|
@@ -131,8 +148,8 @@ export function createCoreClient({
|
|
|
131
148
|
else request.resolve(result);
|
|
132
149
|
return true;
|
|
133
150
|
}
|
|
134
|
-
function receive(input){
|
|
135
|
-
if(
|
|
151
|
+
function receive(input,activation){
|
|
152
|
+
if(!acceptsNativeDelivery(activation))return false;
|
|
136
153
|
let message=input;
|
|
137
154
|
if(typeof message==='string'){
|
|
138
155
|
try{message=JSON.parse(message);}
|
|
@@ -149,7 +166,9 @@ export function createCoreClient({
|
|
|
149
166
|
// Final responses follow earlier event deliveries, including while a
|
|
150
167
|
// classic host is connecting the shared SDK event owner. A stream's
|
|
151
168
|
// completion must not remove its subscription before its chunks arrive.
|
|
152
|
-
withEvents(
|
|
169
|
+
withEvents(function deliverResponse(){
|
|
170
|
+
if(acceptsNativeDelivery(activation))settle(message.id,message.ok?null:new CoreError(message.error),message.result);
|
|
171
|
+
});
|
|
153
172
|
return true;
|
|
154
173
|
}
|
|
155
174
|
function installCallback(name,value){
|
|
@@ -182,6 +201,107 @@ export function createCoreClient({
|
|
|
182
201
|
catch(error){record.reject(error);}
|
|
183
202
|
return true;
|
|
184
203
|
}
|
|
204
|
+
function createWebKitDocumentTransport(webkit) {
|
|
205
|
+
let activation = null;
|
|
206
|
+
let active = false;
|
|
207
|
+
let registration = null;
|
|
208
|
+
function current(candidate) {
|
|
209
|
+
return !closed && active && candidate === activation;
|
|
210
|
+
}
|
|
211
|
+
function inactive() {
|
|
212
|
+
return new CoreError(
|
|
213
|
+
{code: 'ARCANE_WEBKIT_DOCUMENT_INACTIVE', message: 'This document activation no longer owns the native connection.'}
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
async function post(record) {
|
|
217
|
+
parseAcknowledgement(
|
|
218
|
+
await webkit.postMessage(record), {required: true}
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
function activate(restored = false) {
|
|
222
|
+
if (closed || active) return;
|
|
223
|
+
activation = uuid();
|
|
224
|
+
active = true;
|
|
225
|
+
const candidate = activation;
|
|
226
|
+
// Only transport ingress waits for native attachment. Rendering and
|
|
227
|
+
// the synchronous facade remain independent of this acknowledgement.
|
|
228
|
+
registration = Promise.resolve().then(
|
|
229
|
+
function announceDocument() {
|
|
230
|
+
if (!current(candidate)) throw inactive();
|
|
231
|
+
return post(
|
|
232
|
+
{type: 'activate', activation: candidate}
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
complete(
|
|
237
|
+
'transport.ready', {protocol: CORE_PROTOCOL, transport: 'webkitgtk'}
|
|
238
|
+
);
|
|
239
|
+
registration.then(
|
|
240
|
+
function replayDocumentState() {
|
|
241
|
+
if (current(candidate) && (restored || replayRuntimeState)) {
|
|
242
|
+
sendControl(
|
|
243
|
+
{protocol: CORE_PROTOCOL, type: 'control', control: 'runtime.replay'}
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
).catch(report);
|
|
248
|
+
}
|
|
249
|
+
function retire() {
|
|
250
|
+
if (!active) return false;
|
|
251
|
+
const candidate = activation;
|
|
252
|
+
// Invalidate delivery synchronously, including callbacks queued in
|
|
253
|
+
// WebKit or waiting for the shared event owner. Subscriptions live
|
|
254
|
+
// with this document and remain registered across restoration.
|
|
255
|
+
active = false;
|
|
256
|
+
completedEvents.clear();
|
|
257
|
+
for (const [id, request] of pending) settle(id, aborted(request.method));
|
|
258
|
+
const json = JSON.stringify(
|
|
259
|
+
{protocol: CORE_PROTOCOL, type: 'control', control: 'requests.cancelAll'}
|
|
260
|
+
);
|
|
261
|
+
post(
|
|
262
|
+
{type: 'retire', activation: candidate, json}
|
|
263
|
+
).catch(report);
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
function restoredDocument(event) {
|
|
267
|
+
if (event.persisted) activate(true);
|
|
268
|
+
}
|
|
269
|
+
if (typeof global.addEventListener === 'function') {
|
|
270
|
+
global.addEventListener(
|
|
271
|
+
'pageshow', restoredDocument, {capture: true}
|
|
272
|
+
);
|
|
273
|
+
cleanups.push(
|
|
274
|
+
function removeDocumentRestoration() {
|
|
275
|
+
global.removeEventListener(
|
|
276
|
+
'pageshow', restoredDocument, {capture: true}
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
cleanups.push(
|
|
282
|
+
function releaseDocument() { active = false; }
|
|
283
|
+
);
|
|
284
|
+
installCallback('__arcaneWebKitDocumentCurrent', current);
|
|
285
|
+
webKitDocument = {current, activate, retire, get activation() { return active ? activation : null; }};
|
|
286
|
+
return {
|
|
287
|
+
name: 'webkitgtk',
|
|
288
|
+
async send(frame) {
|
|
289
|
+
const candidate = activation;
|
|
290
|
+
if (!current(candidate)) throw inactive();
|
|
291
|
+
const json = JSON.stringify(frame);
|
|
292
|
+
await registration;
|
|
293
|
+
// A page may retire while native attachment is pending. It
|
|
294
|
+
// must never submit its queued request after that retirement.
|
|
295
|
+
if (!current(candidate)) throw inactive();
|
|
296
|
+
// Abort, timeout or cancelAll may also end a request while
|
|
297
|
+
// this activation remains live. Unsent work stays cancelled.
|
|
298
|
+
if (frame.type === 'request' && !pending.has(frame.id)) return;
|
|
299
|
+
await post(
|
|
300
|
+
{type: 'frame', activation: candidate, json}
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
185
305
|
function chooseTransport(){
|
|
186
306
|
const webview=global.chrome?.webview;
|
|
187
307
|
if(webview?.hostObjects){
|
|
@@ -204,6 +324,12 @@ export function createCoreClient({
|
|
|
204
324
|
const webkit=global.webkit?.messageHandlers?.arcane;
|
|
205
325
|
if(typeof global.__arcaneWebKitPostMessage==='function'||webkit){
|
|
206
326
|
installCallback('__arcaneReceive',receive);
|
|
327
|
+
if(webKitDocumentLifecycle){
|
|
328
|
+
if(typeof webkit?.postMessage!=='function'){
|
|
329
|
+
throw new CoreError({code:'ARCANE_TRANSPORT_INVALID',message:'WebKit document lifecycle requires the arcane message handler with replies.'});
|
|
330
|
+
}
|
|
331
|
+
return createWebKitDocumentTransport(webkit);
|
|
332
|
+
}
|
|
207
333
|
installCallback('__arcaneWebKitAcknowledge',acknowledge);
|
|
208
334
|
return {name:'webkitgtk',async send(frame){
|
|
209
335
|
const serialized=JSON.stringify(frame);
|
|
@@ -293,8 +419,9 @@ export function createCoreClient({
|
|
|
293
419
|
throw error;
|
|
294
420
|
}
|
|
295
421
|
if(closed)throw transportFailure??new CoreError({code:'ARCANE_CLIENT_CLOSED',message:'The Core client is closed.'});
|
|
422
|
+
if(webKitDocument)webKitDocument.activate();
|
|
296
423
|
complete('transport.ready',{protocol:CORE_PROTOCOL,transport:transport.name});
|
|
297
|
-
if(replayRuntimeState&&!closed)sendControl({protocol:CORE_PROTOCOL,type:'control',control:'runtime.replay'});
|
|
424
|
+
if(replayRuntimeState&&!closed&&!webKitDocument)sendControl({protocol:CORE_PROTOCOL,type:'control',control:'runtime.replay'});
|
|
298
425
|
// A native callback may close the client synchronously during replay.
|
|
299
426
|
if(closed)throw transportFailure??new CoreError({code:'ARCANE_CLIENT_CLOSED',message:'The Core client is closed.'});
|
|
300
427
|
return transport;
|
|
@@ -305,7 +432,7 @@ export function createCoreClient({
|
|
|
305
432
|
:typeof global.__arcaneWebKitPostMessage==='function'||global.webkit?.messageHandlers?.arcane?'webkitgtk'
|
|
306
433
|
:typeof global.arcaneAndroid?.postMessage==='function'?'android-webview'
|
|
307
434
|
:global.__ARCANE_DEV_HTTP__?'development-http':'standalone');
|
|
308
|
-
return {connected:transport!==null&&!closed,transport:name,
|
|
435
|
+
return {connected:transport!==null&&!closed&&(!webKitDocument||webKitDocument.activation!==null),transport:name,
|
|
309
436
|
native:['webview2','webkitgtk','android-webview'].includes(name),
|
|
310
437
|
managedLocalAI:['webview2','webkitgtk'].includes(name)};
|
|
311
438
|
}
|
|
@@ -389,18 +516,23 @@ export function createCoreClient({
|
|
|
389
516
|
function close(){
|
|
390
517
|
if(closed)return false;
|
|
391
518
|
closed=true;
|
|
392
|
-
|
|
519
|
+
if(webKitDocument)webKitDocument.retire();
|
|
520
|
+
else cancelAll();
|
|
393
521
|
disposeTransport(new CoreError({code:'ARCANE_CLIENT_CLOSED',message:'The Core client is closed.'}));
|
|
394
522
|
return true;
|
|
395
523
|
}
|
|
524
|
+
function documentHidden(){
|
|
525
|
+
if(webKitDocument)webKitDocument.retire();
|
|
526
|
+
else cancelAll();
|
|
527
|
+
}
|
|
396
528
|
if(typeof global.addEventListener==='function'){
|
|
397
|
-
global.addEventListener('pagehide',
|
|
398
|
-
cleanups.push(()=>global.removeEventListener('pagehide',
|
|
529
|
+
global.addEventListener('pagehide',documentHidden,{capture:true});
|
|
530
|
+
cleanups.push(()=>global.removeEventListener('pagehide',documentHidden,{capture:true}));
|
|
399
531
|
}
|
|
400
532
|
if(autoConnect){
|
|
401
533
|
try{connect();}catch(error){if(error.code!=='ARCANE_TRANSPORT_UNAVAILABLE')report(error);}
|
|
402
534
|
}
|
|
403
|
-
return {protocol:CORE_PROTOCOL,Error:CoreError,invoke,receive,connect,close,failTransport,cancelAll,events,eventsReady,runtime:{current:runtimeSnapshot},uuid};
|
|
535
|
+
return {protocol:CORE_PROTOCOL,Error:CoreError,invoke,receive,connect,close,failTransport,cancelAll,acceptsNativeDelivery,events,eventsReady,runtime:{current:runtimeSnapshot},uuid};
|
|
404
536
|
}
|
|
405
537
|
|
|
406
538
|
/** Existing namespace call shapes; method implementations remain host-owned. */
|
|
@@ -512,7 +644,10 @@ export function installCoreClient(global=globalThis,options={}){
|
|
|
512
644
|
const previous=global.__arcaneReceive;
|
|
513
645
|
global.__arcaneReceive=client.receive;
|
|
514
646
|
const previousFailure=global.__arcaneTransportFailed;
|
|
515
|
-
function nativeTransportFailed(error){
|
|
647
|
+
function nativeTransportFailed(error,activation){
|
|
648
|
+
if(!client.acceptsNativeDelivery(activation))return false;
|
|
649
|
+
return client.failTransport(error);
|
|
650
|
+
}
|
|
516
651
|
global.__arcaneTransportFailed=nativeTransportFailed;
|
|
517
652
|
const close=client.close;
|
|
518
653
|
const failTransport=client.failTransport;
|
package/docs/architecture.md
CHANGED
|
@@ -191,13 +191,16 @@ redirect listener, defaulting to an OS-assigned port. Existing raw `tls` inputs
|
|
|
191
191
|
retain their native HTTPS transport under the SDK, as described by the module's
|
|
192
192
|
advanced TLS extension guidance; all content uses its public serving methods.
|
|
193
193
|
|
|
194
|
-
Explicit `arcane dev --http` or
|
|
194
|
+
Explicit `arcane dev --http` or API `http:true` selects the module's
|
|
195
195
|
single HTTP listener on `port`. It skips certificate resolution and serves the
|
|
196
196
|
same selected source mappings, generated PWA routes, and conditional responses.
|
|
197
|
+
In API packaged mode, it serves the complete selected packaged web root and
|
|
198
|
+
its declared application start URL instead of source mappings.
|
|
197
199
|
No HTTPS listener or redirect is started in this mode. Listener readiness,
|
|
198
200
|
failure, cancellation and shutdown retain the same operation owner; reported
|
|
199
201
|
URLs use the actual HTTP protocol and bound port. Browser secure-context
|
|
200
|
-
requirements remain browser-owned.
|
|
202
|
+
requirements remain browser-owned. Source and packaged modes retain HTTPS
|
|
203
|
+
when `http:true` is not selected; a certificate error never switches transport.
|
|
201
204
|
|
|
202
205
|
Development is an intentionally fast feedback loop. Keep each increment small
|
|
203
206
|
and independently understandable so its effect has one clear cause and a
|
package/docs/platform-targets.md
CHANGED
|
@@ -16,10 +16,15 @@ toolchain, platform, architecture, format, signing mode, declared dependency
|
|
|
16
16
|
releases, and destination. Verification is a separate operation only when the
|
|
17
17
|
user explicitly selects it for the release artifact.
|
|
18
18
|
|
|
19
|
-
The portable
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
The portable, Windows x64 and macOS targets pair with installed SDK providers by
|
|
20
|
+
default. Windows uses the numeric SDK release's precompiled WebView2/SEA host.
|
|
21
|
+
macOS source composition selects that version's architecture-specific AppKit,
|
|
22
|
+
WebKit and bundled Node host asset; actual asset publication and Mac execution
|
|
23
|
+
are separate release evidence, not implied by the target registry.
|
|
24
|
+
An explicit `--arcane-root` retains fixed-provider selection for the registered
|
|
25
|
+
portable, Windows, Linux and Android checkout targets. macOS uses the installed
|
|
26
|
+
SDK provider and has no checkout override. Linux and Android still require that
|
|
27
|
+
override and their platform toolchains. Every native request also requires
|
|
23
28
|
the canonical app descriptor to declare the exact target selected on the
|
|
24
29
|
command line. The SDK package does not silently search for a toolchain, infer a
|
|
25
30
|
descriptor target, embed the Arcane machine bundle, or substitute browser
|
|
@@ -35,8 +40,8 @@ npm exec -- arcane native-doctor --target portable
|
|
|
35
40
|
npm exec -- arcane build --target portable
|
|
36
41
|
|
|
37
42
|
# In an app scaffolded with --target windows-x64:
|
|
38
|
-
npm exec -- arcane build --target windows-x64
|
|
39
|
-
npm exec -- arcane run --target windows-x64
|
|
43
|
+
npm exec -- arcane build --target windows-x64
|
|
44
|
+
npm exec -- arcane run --target windows-x64
|
|
40
45
|
|
|
41
46
|
# In an app scaffolded with --target linux-x64:
|
|
42
47
|
npm exec -- arcane build --target linux-x64 --arcane-root "../Arcane OS"
|
|
@@ -62,7 +67,7 @@ from its installed npm dependency. After `npm install`, run
|
|
|
62
67
|
browser maps are present. The initial scaffold reports that map as pending while
|
|
63
68
|
the SDK dependency is absent. The scaffold includes the raster icon required
|
|
64
69
|
by the current native platform. Use the
|
|
65
|
-
matching scaffold target (`portable`, `windows-x64`, `linux-x64`, `linux-arm64`,
|
|
70
|
+
matching scaffold target (`portable`, `windows-x64`, `macos-arm64`, `macos-x64`, `linux-x64`, `linux-arm64`,
|
|
66
71
|
or `android-arm64`) before running the corresponding command.
|
|
67
72
|
|
|
68
73
|
`native-prepare` remains a standalone diagnostic. The normal build recipe omits
|
|
@@ -72,7 +77,8 @@ The portable output is an app-scoped payload directory with complete selected
|
|
|
72
77
|
app and dependency files, a generated Core entry and classic client source.
|
|
73
78
|
It is not an executable and has no direct run operation. Explicit service
|
|
74
79
|
composition uses `createPortableNativeProvider({services:[{module,options}]})`;
|
|
75
|
-
the default
|
|
80
|
+
the default uses an explicit descriptor service selection when supplied and
|
|
81
|
+
does not discover or copy OS product services. See
|
|
76
82
|
[Core native packaging](reference/core-native-packaging.md).
|
|
77
83
|
The external workspace defaults to `build/portable/`. Integrated Arcane work
|
|
78
84
|
must name an `--output-root` outside that checkout. Explicit checkout providers
|
|
@@ -89,19 +95,30 @@ for the complete compatibility and breaking-change rule.
|
|
|
89
95
|
|---|---|---|
|
|
90
96
|
| `browser` | `directory` | Available |
|
|
91
97
|
| `portable` | `portable` directory | SDK package provider by default; explicit checkout override retained; not executable |
|
|
92
|
-
| `windows-x64` | `exe` bundle |
|
|
98
|
+
| `windows-x64` | `exe` bundle | SDK package provider and matching precompiled release host by default; explicit checkout override retained |
|
|
99
|
+
| `macos-arm64` | `.app` bundle | SDK provider source; needs a matching selected or published Apple silicon host asset |
|
|
100
|
+
| `macos-x64` | `.app` bundle | SDK provider source; needs a matching selected or published Intel host asset |
|
|
93
101
|
| `linux-x64` | `deb` | Available with explicit `--arcane-root`; unsigned local development only |
|
|
94
102
|
| `linux-arm64` | `deb` | Available with explicit `--arcane-root` on a compatible native ARM64 toolchain; unsigned local development only |
|
|
95
103
|
| `android-arm64` | `apk` | Available with explicit `--arcane-root`; development-signed, architecture-neutral, and physical/native ARM64 for run |
|
|
96
104
|
|
|
97
105
|
macOS can consume browser applications and portable JavaScript capabilities
|
|
98
|
-
within their declared runtimes. The
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
within their declared runtimes. The native target registry includes separate
|
|
107
|
+
Apple silicon and Intel `.app` compositions; portable CLI requests also accept
|
|
108
|
+
macOS. A Mac provider preserves the complete portable payload under its bundle's
|
|
109
|
+
Resources directory and composes the SDK host separately. A source-development
|
|
102
110
|
native wrapper is also not an exposed `arcane dev` target. Native `run` uses the
|
|
103
111
|
selected packaged application through its paired provider.
|
|
104
112
|
|
|
113
|
+
The package includes macOS `ArcaneCoreProcess`, `ArcaneHost` and launcher source
|
|
114
|
+
for explicit child launch, framed pipes, document lifecycle and graceful drain.
|
|
115
|
+
The SDK provider composes them with an explicitly selected Darwin Node runtime.
|
|
116
|
+
Source availability is not evidence of Mac compilation or execution. See the
|
|
117
|
+
[macOS composition boundary](reference/core-native-packaging.md#macos-application-composition).
|
|
118
|
+
Windows app assembly needs the normal Node/npm toolchain and `tar`, not a C#
|
|
119
|
+
compiler. Its generated executable uses bundled Node and requires .NET Framework
|
|
120
|
+
4.6.2 or later plus WebView2 Runtime on the destination Windows x64 machine.
|
|
121
|
+
|
|
105
122
|
Every native target accepts one selected app release and its complete bundled
|
|
106
123
|
dependency closure through the provider boundary. The providers retain the
|
|
107
124
|
toolchain state required for build and, where supported, launch; app source and
|
package/docs/reference/README.md
CHANGED
|
@@ -52,7 +52,9 @@ alone does not make bare module names resolve in a browser.
|
|
|
52
52
|
| Call `globalThis.Arcane` | [Arcane Core API](core/arcane-api.md) |
|
|
53
53
|
| Connect a browser to one Core transport | [Core browser client](core-client.md) |
|
|
54
54
|
| Compose native Core dispatch, service lifecycle, and stdio hosting | [Native Core runtime](core-runtime.md) |
|
|
55
|
+
| Run application-selected llama.cpp, Ollama or ONNX through Core | [Local AI through Core](local-ai.md) |
|
|
55
56
|
| Build an installed-SDK portable Core payload | [Portable Core packaging](core-native-packaging.md) |
|
|
57
|
+
| Build a Windows executable without an OS checkout | [Windows executable packaging](core-native-packaging.md#windows-executable) |
|
|
56
58
|
| Subscribe to native events | [Arcane event reference](core/arcane-events.md) |
|
|
57
59
|
| Use provider-neutral AI lifecycle, chat, speech, persistence, or document context | [Normalized AI](#normalized-ai) |
|
|
58
60
|
| Choose a normalized typed browser decision surface | [Browser typed decisions](ai/browser-decisions.md) |
|
|
@@ -79,9 +81,11 @@ This repository contains explicitly versioned surfaces with different owners:
|
|
|
79
81
|
|
|
80
82
|
Browser modules and reusable Core client/runtime/lifecycle source belong to the
|
|
81
83
|
SDK. The portable provider uses this installed package by default and assembles
|
|
82
|
-
an app payload with explicitly selected services;
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
an app payload with explicitly selected services; portable itself supplies no
|
|
85
|
+
executable host. The Windows provider pairs that payload with the installed
|
|
86
|
+
SDK version's precompiled WebView2/SEA release asset. Explicit Arcane OS provider
|
|
87
|
+
overrides and integrated shared checks remain available. Arcane OS retains its
|
|
88
|
+
product composition and policy.
|
|
85
89
|
The historical Core reference snapshot describes a separate host contract;
|
|
86
90
|
matching a protocol name or assembling a payload alone does not establish that
|
|
87
91
|
a composed host supplies every required method or service.
|
|
@@ -111,6 +115,35 @@ The [changelog](../../CHANGELOG.md) records changes by version; the
|
|
|
111
115
|
identify the corresponding published package source. A newer website does not
|
|
112
116
|
change the version installed in your application.
|
|
113
117
|
|
|
118
|
+
### Generate the selected reference site
|
|
119
|
+
|
|
120
|
+
The existing `node tools/build-reference-site.mjs --write` command reads the
|
|
121
|
+
live checkout. For release documentation while disjoint source work continues,
|
|
122
|
+
select the reviewed documentation commit explicitly:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
node tools/build-reference-site.mjs --write --source-ref <documentation-commit>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The same option is accepted by `createReferenceSite({sourceRef})` and
|
|
129
|
+
`writeReferenceSite({sourceRef})`. It reads the selected commit's package
|
|
130
|
+
version, complete reference documents and inventories, inventory-selected
|
|
131
|
+
runtime sources, and authored site inputs directly from Git in memory. It
|
|
132
|
+
creates no checkout or export and leaves source drafts untouched. Rendering
|
|
133
|
+
uses the current canonical generator and its authored semantic contracts;
|
|
134
|
+
select a documentation commit whose contracts match the published package.
|
|
135
|
+
Generated output still belongs to the canonical `site/` tree and requires its
|
|
136
|
+
usual coordinated output ownership. Generation does not publish hosted Pages.
|
|
137
|
+
|
|
138
|
+
For a selected release whose documentation correction lands after unrelated
|
|
139
|
+
source, `createReferenceSite({inputs})` and `writeReferenceSite({inputs})` accept
|
|
140
|
+
one explicit input owner with `readText(relativePath)` and
|
|
141
|
+
`listFiles(relativeDirectory)`. It is shared with the contract extractor. Keep
|
|
142
|
+
package/runtime reads and document discovery on the release commit, and overlay
|
|
143
|
+
only reviewed documentation records from the correction commit. In particular,
|
|
144
|
+
preserve the selected inventory's member set instead of importing later public
|
|
145
|
+
APIs. Omitted `inputs` preserves the live or `sourceRef` behavior above.
|
|
146
|
+
|
|
114
147
|
### Historical 0.3.4 publication record
|
|
115
148
|
|
|
116
149
|
The following records describe that earlier release only. They do not identify
|
|
@@ -181,6 +214,8 @@ Ollama, Wllama, Whisper, Kokoro, native, or cloud transport:
|
|
|
181
214
|
| Offer explicit selected-model start/cancel UI | [`chat.html`](runtime-components.md#chathtml), [`speech.html`](runtime-components.md#speechhtml), and [`voice-transcription.html`](runtime-components.md#voice-transcriptionhtml) | Browser/native WebView components; user activation emits a cancelable request before any LLM or STT load intent, and recording stays disabled without sticky ready STT. |
|
|
182
215
|
| Use Core-normalized chat | [`globalThis.Arcane.ai`](core/arcane-ai-contracts.md) | Native/Core only when separately admitted. |
|
|
183
216
|
| Run a caller-selected GGUF LLM locally | [`arcane-os/ai/browser-wasm`](ai/browser-wasm.md) | Browser secure context with WebAssembly and OPFS/DBOPFS; explicit CPU selection or WebGPU with full offload and no automatic CPU fallback. |
|
|
217
|
+
| Run application-selected native llama.cpp/Ollama chat | [`arcane-os/ai/core-local`, `arcane-os/core/local-ai`](local-ai.md) | Explicit Core connection and selected native runtimes; installation, availability and loaded-model readiness remain distinct. |
|
|
218
|
+
| Run a local ONNX graph with named tensors | [`arcane-os/local-ai/onnx`, `arcane-os/ai/core-onnx`](local-ai.md#native-onnx-sessions) | Retained native workers; browser access requires an available Core ONNX service. |
|
|
184
219
|
| Run caller-selected Whisper/Kokoro locally | [`arcane-os/ai/browser-speech`](ai/browser-speech.md) | Browser with DBOPFS, Web Locks, Workers and selected upstream sources; automatic WebNN NPU, WebGPU, then WASM loading, or an explicit backend. |
|
|
185
220
|
| Use native browser recognition/voices or selected cloud TTS | [Speech provider choices](ai/browser-speech.md) | Native APIs depend on the browser and may use remote services; cloud TTS requires the application key and endpoint access. |
|
|
186
221
|
| Send complete chat, System One or image requests without retained history | [`arcane-os/ai/twin-cloud`](ai/twin-cloud.md) | Node or browser with Fetch and explicit model/credentials; image results contain every returned image as a Blob. |
|
|
@@ -58,12 +58,12 @@ false when a probe throws; SDK branching continues through its owning error path
|
|
|
58
58
|
policy, package-owned model policy, platform support, and dependency readiness
|
|
59
59
|
are independent checks.
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
Windows x64 has an SDK-owned precompiled WebView2/SEA host; Linux and Android
|
|
62
|
+
retain their explicit checkout providers where listed. The SDK also includes
|
|
63
|
+
macOS Foundation process-adapter source, separately from an executable target,
|
|
64
|
+
renderer bridge, artifact or run command. A composed macOS host may combine that
|
|
65
|
+
source with the reusable Node Core runtime, stdio transport and portable payload.
|
|
66
|
+
Source availability does not establish macOS compilation or execution.
|
|
67
67
|
|
|
68
68
|
## Capability-first matrix
|
|
69
69
|
|
|
@@ -89,6 +89,9 @@ macOS host, but they do not supply that native platform host or bridge.
|
|
|
89
89
|
| Connect browser code to an existing Core transport | `arcane-os/core/client` and `arcane-os/core/contracts` | **Browser / native WebView** with an admitted transport; explicit development HTTP remains opt-in | The reusable client owns `arcane/1` correlation, readiness, cancellation, events, facades, and complete native error fidelity. It supplies no service, policy, or host process. |
|
|
90
90
|
| Compose native Core services and framed stdio hosting | `arcane-os/core/runtime`, `arcane-os/core/stdio`, and `arcane-os/core/host` | **Node** on Windows, Linux, or macOS; the composing native host supplies its process and bridge | The SDK owns reusable dispatch, per-service lifecycle, request/service work ownership, cooperative cancellation, drain, and stdio framing. Product identity, policy, privileges, models, storage, and services remain host-owned. |
|
|
91
91
|
| Assemble a portable Core payload from the installed SDK | `arcane-os/native/portable-provider` | **Node**; portable platform selection is currently Windows or Linux, while separately composed hosts may use the payload | The provider copies the selected app, dependencies, installed SDK runtime, Core client/runtime, and explicit service composition into a non-executable directory. It uses no `arcaneRoot` by default and does not prove host behavior or supply a platform bridge. |
|
|
92
|
+
| Assemble and run a Windows executable | [`arcane-os/native/windows-provider`](core-native-packaging.md#windows-executable) | **Node** for assembly; Windows x64, .NET Framework 4.6.2+ and WebView2 for execution | Uses the installed SDK version's precompiled release asset and explicit app services. Complete diagnostics and accepted service work drain on run cancellation; no OS checkout or application-side native compiler is required. |
|
|
93
|
+
| Use application-selected llama.cpp/Ollama through Core | [`arcane-os/core/local-ai`, `arcane-os/ai/core-local`](local-ai.md) | **Node** native service; **Browser / native WebView** provider through an explicit Core connection | Independent runtime/model lifecycle, complete streaming and cancellation. Official runtime preparation follows explicit app requirements; model selection and business policy stay app-owned. |
|
|
94
|
+
| Run native ONNX tensors | [`arcane-os/local-ai/onnx`, `arcane-os/ai/core-onnx`](local-ai.md#native-onnx-sessions) | **Node** Windows/Linux/macOS x64/arm64; **Browser / native WebView** through available Core | Explicit graph loading, retained workers and complete tensor outputs. Android requires host adaptation. Native calls can delay worker termination; cleanup observes actual exit. |
|
|
92
95
|
| Use local AI without coupling app code to Ollama HTTP | `Arcane.localAI`, `Arcane.ai`, or `/arcane/modules/Ollama.js` | Primarily **Native**; Android exposes a narrower admitted inference projection | Admission, errors, and managed-operation events are normalized. Direct Ollama response envelopes remain **Provider-native**. |
|
|
93
96
|
| Use TWiN Cloud from the renderer profile | `/arcane/modules/AI.js` | **Cloud** from an allowed browser/native renderer | High-level chat behavior is normalized by the module. The TWiN access key authenticates remote LLM chat; raw provider diagnostics remain provider-specific. No automatic cloud fallback is inferred from local failure. |
|
|
94
97
|
| Send one TWiN Cloud request with an explicit key and model | `fetchRequest` from `arcane-os/ai/twin-cloud` | **Node** and **Browser**, using standard Fetch and a remote HTTPS provider | Keeps complete messages and returns the full parsed provider JSON. Rejected Fetch and HTTP 529 share three retries after 3000 ms; HTTP 429 overload retains unlimited three-second retries. Optional `onRetry` reports waiting/requesting phases without blocking recovery. Shared structured-output mapping and cancellation match browser TWiN transport. No browser profile, AI/user singleton, DBOPFS, or retained request history is created. |
|
package/docs/reference/cli.md
CHANGED
|
@@ -49,6 +49,7 @@ meaning and cardinality rules:
|
|
|
49
49
|
| `--app` | app id or label | Workspace/app operations except shared scope and `verify-bundle`; optional diagnostic label for `mail serve`. |
|
|
50
50
|
| `--apps-root` | `.` or `apps` | `new`, `init`; standalone setup defaults to the repository root. |
|
|
51
51
|
| `--sdk-runtime-source` | SDK checkout directory | `dev` only; maps live SDK source through the selected browser destinations for that server process. |
|
|
52
|
+
| `--local-ai` | comma-separated runtime IDs | `dev` only; adds `llama.cpp`, `ollama` and/or `onnx` requirements to application configuration and prepares missing runtimes alongside serving. See [local AI through Core](local-ai.md). |
|
|
52
53
|
| `--arcane-root` | directory | `doctor`, native `build`/`run`, `native-doctor`, `native-prepare` |
|
|
53
54
|
| `--host` / `--port` | host / integer 0–65535 | Browser `dev`/`run` default to HTTPS at `127.0.0.1:8000`; `mail serve` defaults to HTTPS with HTTP/2 at `0.0.0.0:4433` and accepts an explicit bind host. |
|
|
54
55
|
| `--http-port` | integer 0–65535 | Browser `dev`/`run` HTTP redirect listener; defaults to `0`, which selects an available port. |
|
|
@@ -366,9 +367,16 @@ An explicit live-source SDK mapping follows the selected browser destinations
|
|
|
366
367
|
while reading canonical SDK source; it never replaces installed files.
|
|
367
368
|
|
|
368
369
|
```text
|
|
369
|
-
arcane dev [--app <id>] [--public] [--http | --https] [--cert <file> --key <file>] [--host <address>] [--port 8000] [--http-port 0] [--sdk-runtime-source <sdk-root>]
|
|
370
|
+
arcane dev [--app <id>] [--public] [--http | --https] [--cert <file> --key <file>] [--host <address>] [--port 8000] [--http-port 0] [--sdk-runtime-source <sdk-root>] [--local-ai llama.cpp,ollama,onnx]
|
|
370
371
|
```
|
|
371
372
|
|
|
373
|
+
`--local-ai` saves the selected requirements in `native.localAI`, or in
|
|
374
|
+
`arcane-package.json.localAI` for a package-only app. Later development runs
|
|
375
|
+
reuse them. Available services and executables are reused; missing runtimes
|
|
376
|
+
are installed inside the application while serving starts independently.
|
|
377
|
+
Applications choose their model files and optional browser Core connection.
|
|
378
|
+
See [local AI through Core](local-ai.md) for configuration and native bundling.
|
|
379
|
+
|
|
372
380
|
### Lifecycle
|
|
373
381
|
|
|
374
382
|
Startup refreshes the selected authored `arcane-app.json` projection into
|
|
@@ -398,7 +406,7 @@ device, since `localhost` refers to that device and `0.0.0.0` is a bind address.
|
|
|
398
406
|
Network URLs come from one interface snapshot at startup and do not establish
|
|
399
407
|
remote reachability through the machine's firewall or network.
|
|
400
408
|
|
|
401
|
-
HTTPS is the default for development and
|
|
409
|
+
HTTPS is the default for development and packaged browser previews.
|
|
402
410
|
The published `node-http-server` 10.0.0 integration negotiates HTTP/2 or HTTP/1.1
|
|
403
411
|
on the same HTTPS port using the configured PEM pair. Source routes, generated
|
|
404
412
|
PWA resources, and conditional responses use the same serving pipeline.
|
|
@@ -440,6 +448,10 @@ close the owned HTTP listener and settle the same lifecycle.
|
|
|
440
448
|
`--key`, or `--http-port` is a usage error. Omitting it preserves HTTPS;
|
|
441
449
|
certificate errors never select HTTP automatically.
|
|
442
450
|
|
|
451
|
+
The public `startDevServer()` API also accepts `http:true` in packaged mode;
|
|
452
|
+
this does not add a CLI preview command or change `dev` into packaged serving.
|
|
453
|
+
See [the API contract](sdk-api.md#startdevserver).
|
|
454
|
+
|
|
443
455
|
A LAN HTTP origin does not receive the browser's localhost secure-context
|
|
444
456
|
exception. For Chrome development, Chromium documents
|
|
445
457
|
`chrome://flags/#unsafely-treat-insecure-origin-as-secure` with the exact HTTP
|
|
@@ -692,10 +704,10 @@ npm exec -- arcane verify-bundle dist/hello-world-1.0.0.arcane-app.tar.gz
|
|
|
692
704
|
|
|
693
705
|
### Overview
|
|
694
706
|
|
|
695
|
-
Loads the SDK package provider for portable by default, or
|
|
696
|
-
from an explicitly selected Arcane OS checkout. It diagnoses
|
|
697
|
-
|
|
698
|
-
|
|
707
|
+
Loads the SDK package provider for `portable` or `windows-x64` by default, or
|
|
708
|
+
the fixed provider from an explicitly selected Arcane OS checkout. It diagnoses
|
|
709
|
+
selected prerequisites without building an app. Windows uses the matching
|
|
710
|
+
precompiled SDK host; Linux and Android retain their checkout/toolchain routes.
|
|
699
711
|
|
|
700
712
|
```text
|
|
701
713
|
arcane native-doctor --target <native-target> [--arcane-root <directory>]
|
|
@@ -711,8 +723,7 @@ is unavailable; it never returns a browser package as a substitute.
|
|
|
711
723
|
|
|
712
724
|
```bash
|
|
713
725
|
npm exec -- arcane native-doctor \
|
|
714
|
-
--target windows-x64
|
|
715
|
-
--arcane-root "../Arcane OS"
|
|
726
|
+
--target windows-x64
|
|
716
727
|
```
|
|
717
728
|
|
|
718
729
|
## `arcane native-prepare`
|
|
@@ -754,6 +765,9 @@ The output remains target-specific inside the common plan contract.
|
|
|
754
765
|
Portable uses the SDK package without an OS checkout, copies complete selected
|
|
755
766
|
app/dependency payloads and generates the Core entry/classic client source.
|
|
756
767
|
It adds no executable platform host or automatically discovered app services.
|
|
768
|
+
Windows x64 uses the SDK package provider and its matching precompiled release
|
|
769
|
+
asset without an OS checkout or application-side native compilation. See
|
|
770
|
+
[Windows requirements and artifact layout](core-native-packaging.md#windows-executable).
|
|
757
771
|
An explicit `--arcane-root` continues to select the checkout provider.
|
|
758
772
|
Integrated builds retain an output root outside the OS checkout; only an
|
|
759
773
|
explicit checkout provider must share the workspace root.
|
|
@@ -767,7 +781,6 @@ rather than returning a fictional native artifact plan.
|
|
|
767
781
|
```bash
|
|
768
782
|
npm exec -- arcane build \
|
|
769
783
|
--target windows-x64 \
|
|
770
|
-
--arcane-root "../Arcane OS" \
|
|
771
784
|
--output-root "../arcane-native-output"
|
|
772
785
|
```
|
|
773
786
|
|
|
@@ -808,6 +821,13 @@ Android providers expose supported paired native run paths. Portable output is
|
|
|
808
821
|
a directory and intentionally cannot run. Android run requires one
|
|
809
822
|
connected physical/native ARM64 device for the current target.
|
|
810
823
|
|
|
824
|
+
`windows-x64` uses the package provider by default, launches `Arcane.exe`, and
|
|
825
|
+
streams complete diagnostics. Its cancellation closes input and waits for the
|
|
826
|
+
window/Core's accepted work to drain; it does not force-kill that host after a
|
|
827
|
+
timer. WebView2 Runtime and .NET Framework 4.6.2 or later must be available on
|
|
828
|
+
the Windows execution machine. Linux/Android retain their explicit provider
|
|
829
|
+
requirements. Build/launch completion does not prove application domain behavior.
|
|
830
|
+
|
|
811
831
|
### Example
|
|
812
832
|
|
|
813
833
|
```bash
|