arcane-os 0.54.1 → 0.55.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 +31 -0
- package/README.md +31 -26
- package/browser-runtime/core/client.mjs +491 -0
- package/browser-runtime/core/contracts.mjs +84 -0
- package/docs/architecture.md +31 -23
- package/docs/compatibility.md +10 -1
- package/docs/platform-targets.md +20 -11
- package/docs/reference/README.md +8 -6
- package/docs/reference/availability-and-normalization.md +4 -2
- package/docs/reference/behavioral-testing.md +7 -6
- package/docs/reference/cli.md +12 -4
- package/docs/reference/core-client.md +120 -0
- package/docs/reference/core-native-packaging.md +149 -0
- package/docs/reference/core-runtime.md +175 -0
- package/docs/reference/inventory/package-api.json +257 -5
- package/docs/reference/protocols.md +16 -1
- package/docs/reference/sdk-api.md +772 -15
- package/package.json +10 -3
- package/schemas/native-build-plan.schema.json +8 -0
- package/src/cli/main.mjs +8 -6
- package/src/core/host.mjs +23 -0
- package/src/core/runtime.mjs +333 -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 +47 -18
- package/src/targets/index.mjs +3 -1
- package/src/toolchain.mjs +20 -5
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export const CORE_PROTOCOL='arcane/1';
|
|
2
|
+
export const CORE_READY_EVENTS=['transport.ready','core.ready'];
|
|
3
|
+
|
|
4
|
+
/** Wire descriptions, not method admission or application policy. */
|
|
5
|
+
export const CORE_FRAME_CONTRACTS={
|
|
6
|
+
request:{type:'request',fields:['protocol','type','id','method','parameters','sentAt']},
|
|
7
|
+
response:{type:'response',fields:['protocol','type','id','ok'],success:['result'],failure:['error'],optional:['time']},
|
|
8
|
+
event:{type:'event',fields:['protocol','type','event','data'],optional:['time']},
|
|
9
|
+
cancel:{type:'control',control:'request.cancel',fields:['protocol','type','control','requestId']},
|
|
10
|
+
cancelAll:{type:'control',control:'requests.cancelAll',fields:['protocol','type','control']}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** These names describe existing methods; installed services determine availability. */
|
|
14
|
+
export const CORE_METHOD_CONTRACTS={
|
|
15
|
+
'system.ping':{input:'empty-object-v1',output:'system-ping-result-v1',meaning:'Dispatcher response, not application or model readiness.'},
|
|
16
|
+
'version.current':{input:'empty-object-v1',output:'version-string-v1',meaning:'Active host release version.'},
|
|
17
|
+
'app.current':{input:'empty-object-v1',output:'application-descriptor-v1'},
|
|
18
|
+
'capabilities.list':{input:'empty-object',output:'{app,grants,methods}'},
|
|
19
|
+
'platform.status':{input:'empty-object-v1',output:'platform-status-v1'},
|
|
20
|
+
'network.status':{input:'empty-object-v1',output:'network-status-v1',meaning:'A non-loopback interface is present; this is not proof of Internet reachability.'},
|
|
21
|
+
'apps.list':{input:'empty-object-v1',output:'application-catalog-v1'},
|
|
22
|
+
'apps.launch':{input:'application-launch-v1',output:'application-launch-result-v1',meaning:'Host acceptance, not application readiness.'},
|
|
23
|
+
'external.open':{input:'external-open-v1',output:'external-open-result-v1',meaning:'Host acceptance, not confirmation of a user action.'},
|
|
24
|
+
'filesystem.directory.select':{input:'directory-selection-options',output:'directory-selection-result'},
|
|
25
|
+
'storage.list':{input:'empty-object',output:'{keys}'},
|
|
26
|
+
'storage.get':{input:'{key}',output:'{key,found,value}'},
|
|
27
|
+
'storage.set':{input:'{key,value}',output:'{key,value}'},
|
|
28
|
+
'storage.delete':{input:'{key}',output:'{key,deleted}'},
|
|
29
|
+
'preferences.list':{input:'empty-object',output:'{keys}'},
|
|
30
|
+
'preferences.get':{input:'{key}',output:'{key,found,value}'},
|
|
31
|
+
'preferences.set':{input:'{key,value}',output:'{key,value}'},
|
|
32
|
+
'preferences.setMany':{input:'{entries}',output:'preference-batch-result'},
|
|
33
|
+
'preferences.delete':{input:'{key}',output:'{key,deleted}'},
|
|
34
|
+
'terminal.start':{input:'terminal-start-v1',output:'terminal-session-v1'},
|
|
35
|
+
'terminal.list':{input:'empty-object-v1',output:'terminal-list-v1'},
|
|
36
|
+
'terminal.write':{input:'terminal-write-v1',output:'terminal-write-result-v1'},
|
|
37
|
+
'terminal.resize':{input:'terminal-resize-v1',output:'terminal-resize-result-v1'},
|
|
38
|
+
'terminal.signal':{input:'terminal-signal-v1',output:'terminal-signal-result-v1'},
|
|
39
|
+
'terminal.close':{input:'terminal-session-id-v1',output:'terminal-close-result-v1'},
|
|
40
|
+
'environment.list':{input:'empty-object-v1',output:'environment-list-result-v1'},
|
|
41
|
+
'environment.get':{input:'environment-name-v1',output:'environment-get-result-v1'},
|
|
42
|
+
'environment.set':{input:'environment-set-v1',output:'environment-set-result-v1'},
|
|
43
|
+
'environment.delete':{input:'environment-name-v1',output:'environment-delete-result-v1'},
|
|
44
|
+
'mail.send':{input:'mail-send-v1',output:'mail-send-result-v1'},
|
|
45
|
+
'user.current':{input:'empty-object-v1',output:'user-identity-v1'}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export class CoreError extends Error{
|
|
49
|
+
constructor(value){
|
|
50
|
+
const source=value!==null&&typeof value==='object'
|
|
51
|
+
?value
|
|
52
|
+
:{message:value===undefined?'Arcane operation failed.':String(value)};
|
|
53
|
+
super(source.message??source.userMessage??'Arcane operation failed.');
|
|
54
|
+
for(const key of Object.getOwnPropertyNames(source))this[key]=source[key];
|
|
55
|
+
this.name=source.name??'ArcaneError';
|
|
56
|
+
this.code=source.code??'ARCANE_ERROR';
|
|
57
|
+
this.resolution=source.resolution??null;
|
|
58
|
+
this.diagnosticId=source.diagnosticId??null;
|
|
59
|
+
this.technicalMessage=source.technicalMessage??source.message??null;
|
|
60
|
+
const hresult=String(source.message??'').match(/\b0x[0-9a-f]{8}\b/iu);
|
|
61
|
+
this.hresult=source.hresult??hresult?.[0]?.toUpperCase()??null;
|
|
62
|
+
this.causeName=source.causeName??(source.name&&source.name!=='ArcaneError'?source.name:null);
|
|
63
|
+
if(source.stack!==undefined)this.stack=source.stack;
|
|
64
|
+
if(source.cause!==undefined)this.cause=source.cause;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function serializeCoreError(error){
|
|
69
|
+
if(error===null||typeof error!=='object'){
|
|
70
|
+
return {name:'Error',code:'ARCANE_ERROR',message:String(error)};
|
|
71
|
+
}
|
|
72
|
+
const record=Object.fromEntries(Object.getOwnPropertyNames(error).map(key=>[key,error[key]]));
|
|
73
|
+
for(const key of ['name','message','stack','cause']){
|
|
74
|
+
if(error[key]!==undefined)record[key]=key==='cause'&&error[key] instanceof Error
|
|
75
|
+
?serializeCoreError(error[key]):error[key];
|
|
76
|
+
}
|
|
77
|
+
if(Array.isArray(error.errors)){
|
|
78
|
+
record.errors=error.errors.map(value=>value instanceof Error?serializeCoreError(value):value);
|
|
79
|
+
}
|
|
80
|
+
if(record.name===undefined)record.name='Error';
|
|
81
|
+
if(record.code===undefined)record.code='ARCANE_ERROR';
|
|
82
|
+
if(record.message===undefined)record.message='Arcane operation failed.';
|
|
83
|
+
return record;
|
|
84
|
+
}
|
package/docs/architecture.md
CHANGED
|
@@ -35,11 +35,12 @@ Arcane OS installation, source checkout or private Arcane OS import.
|
|
|
35
35
|
Arcane OS is an SDK consumer like other applications. Its orchestrator,
|
|
36
36
|
launcher, Shell, Provisioner, system AI application and internal tools use the
|
|
37
37
|
same SDK modules and components rather than maintaining private runtime copies.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
The SDK owns reusable Core protocol, browser client, native runtime, service
|
|
39
|
+
lifecycle and portable payload packaging. Privileged execution stays native;
|
|
40
|
+
the browser client imports no native implementation. Arcane OS retains its
|
|
41
|
+
product host composition, app/session policy, launcher, Shell, Provisioner and
|
|
42
|
+
system-AI orchestration. Applications explicitly supply their service modules;
|
|
43
|
+
the SDK does not discover or inherit another application's services or policy.
|
|
43
44
|
|
|
44
45
|
Each application owns its branding, prompts, data, tools, business policy,
|
|
45
46
|
model authorities and app-specific orchestration. Apply this decision order:
|
|
@@ -47,7 +48,8 @@ model authorities and app-specific orchestration. Apply this decision order:
|
|
|
47
48
|
| Responsibility | Canonical owner |
|
|
48
49
|
|---|---|
|
|
49
50
|
| Reusable by any portable application | Arcane SDK |
|
|
50
|
-
|
|
|
51
|
+
| Native execution | Native host using SDK runtime and explicit app services |
|
|
52
|
+
| Arcane OS product composition, launcher, Shell and app/session policy | Arcane OS |
|
|
51
53
|
| Behavior unique to one product | That application |
|
|
52
54
|
|
|
53
55
|
Do not copy a reusable implementation between the SDK, Arcane OS and an app,
|
|
@@ -405,18 +407,25 @@ safety remain in effect.
|
|
|
405
407
|
|
|
406
408
|
The SDK implements protocol `arcane-native-build-plan/1` and the injected
|
|
407
409
|
provider contract `arcane-native-builder/1`. Pairing is process-local; it never
|
|
408
|
-
registers a mutable global provider or searches for a toolchain.
|
|
409
|
-
|
|
410
|
-
explicit
|
|
411
|
-
|
|
412
|
-
|
|
410
|
+
registers a mutable global provider or searches for a toolchain. With no
|
|
411
|
+
`--arcane-root`, the portable CLI target loads the provider from this installed
|
|
412
|
+
SDK package. An explicit root retains the fixed Arcane OS provider selection;
|
|
413
|
+
executable targets still require that override and their platform toolchains.
|
|
414
|
+
Normal Node module resolution owns the loaded module. The pairing reports
|
|
415
|
+
`providerSource` as `sdk-package` or `arcane-checkout`. One paired toolchain can
|
|
416
|
+
perform this lifecycle:
|
|
413
417
|
|
|
414
418
|
```text
|
|
415
419
|
doctor -> prepare -> plan -> build -> run
|
|
416
420
|
```
|
|
417
421
|
|
|
418
|
-
The portable provider
|
|
419
|
-
|
|
422
|
+
The package-owned portable provider copies the complete selected app and
|
|
423
|
+
dependency payloads and generates a Core entry and synchronous classic facade.
|
|
424
|
+
It accepts explicitly selected service modules through
|
|
425
|
+
`createPortableNativeProvider({services:[{module,options}]})`. Its result is a
|
|
426
|
+
directory, so run reports unavailable. It supplies no executable platform host,
|
|
427
|
+
installer, model assets or OS product services. The explicit Arcane OS
|
|
428
|
+
providers for Windows x64, Linux x64,
|
|
420
429
|
Linux ARM64, and Android ARM64 implement same-process launch and owned
|
|
421
430
|
cancellation when their compatible host/device requirements are present.
|
|
422
431
|
Windows uses a retained per-build broker and host readiness. The
|
|
@@ -439,16 +448,15 @@ paths are withheld from the native provider. The provider copies the complete
|
|
|
439
448
|
selected release rather than accepting an unrelated source path. Verification
|
|
440
449
|
is a separate explicit operation for a selected release artifact.
|
|
441
450
|
|
|
442
|
-
The
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
into the Arcane checkout.
|
|
451
|
+
The native plan preserves the selected descriptors, dependency releases and
|
|
452
|
+
minimum Core requirement for the provider. It accepts the CLI's nested
|
|
453
|
+
`signing:{mode,profileId}` request and existing flat `signing`/`signingProfileId`
|
|
454
|
+
inputs, emitting the same flat plan request. Payload assembly alone does not
|
|
455
|
+
establish that a composed host supplies an app's required methods or services.
|
|
456
|
+
See the [portable native packaging guide](reference/core-native-packaging.md)
|
|
457
|
+
for the SDK provider's actual output and composition boundary. Browser-only apps
|
|
458
|
+
may omit `minimumCoreVersion`; ordinary browser operation remains independent
|
|
459
|
+
of Core.
|
|
452
460
|
|
|
453
461
|
See [compatibility.md](compatibility.md) for the complete app and bundled-app
|
|
454
462
|
compatibility rule and the required handling of breaking contract changes.
|
package/docs/compatibility.md
CHANGED
|
@@ -23,7 +23,16 @@ When the selected target actually uses Arcane Core, compatibility requires:
|
|
|
23
23
|
The effective Core floor for a native build is the highest minimum explicitly
|
|
24
24
|
declared by the SDK runtime, the selected app, and its complete bundled-app
|
|
25
25
|
closure. Browser-only targets do not invent a Core floor. The native build plan
|
|
26
|
-
|
|
26
|
+
forwards the complete selected descriptors, release records and minimum to the
|
|
27
|
+
provider. Creating a portable payload does not establish host or service
|
|
28
|
+
compatibility; the composed host must actually supply the required contracts.
|
|
29
|
+
|
|
30
|
+
The portable CLI selects its provider from the installed SDK unless an explicit
|
|
31
|
+
`--arcane-root` chooses the existing checkout provider. Other native target
|
|
32
|
+
selection and the integrated shared-development provider remain unchanged.
|
|
33
|
+
Programmatic native plans accept both nested CLI signing options and the
|
|
34
|
+
existing flat signing/profile fields, retaining the flat plan result. The
|
|
35
|
+
package-owned portable output is a payload, not an executable host or installer.
|
|
27
36
|
|
|
28
37
|
This permits normal non-breaking Arcane upgrades. For example, an app requiring
|
|
29
38
|
Core `0.8.12` can run on `0.8.13` or `0.9.0` when the required protocol,
|
package/docs/platform-targets.md
CHANGED
|
@@ -16,8 +16,10 @@ 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
|
-
|
|
20
|
-
|
|
19
|
+
The portable target pairs with the installed SDK provider by default. An explicit
|
|
20
|
+
`--arcane-root` retains fixed-provider selection from an Arcane OS checkout;
|
|
21
|
+
Windows, Linux and Android executable targets still require that override and
|
|
22
|
+
their platform toolchains. Every native request also requires
|
|
21
23
|
the canonical app descriptor to declare the exact target selected on the
|
|
22
24
|
command line. The SDK package does not silently search for a toolchain, infer a
|
|
23
25
|
descriptor target, embed the Arcane machine bundle, or substitute browser
|
|
@@ -29,8 +31,8 @@ npx arcane-os@latest new my-app --path ./my-app --target portable --git
|
|
|
29
31
|
cd my-app
|
|
30
32
|
npm install
|
|
31
33
|
npm run import-map
|
|
32
|
-
npm exec -- arcane native-doctor --target portable
|
|
33
|
-
npm exec -- arcane build --target portable
|
|
34
|
+
npm exec -- arcane native-doctor --target portable
|
|
35
|
+
npm exec -- arcane build --target portable
|
|
34
36
|
|
|
35
37
|
# In an app scaffolded with --target windows-x64:
|
|
36
38
|
npm exec -- arcane build --target windows-x64 --arcane-root "../Arcane OS"
|
|
@@ -66,11 +68,16 @@ or `android-arm64`) before running the corresponding command.
|
|
|
66
68
|
`native-prepare` remains a standalone diagnostic. The normal build recipe omits
|
|
67
69
|
it and lets `build` prepare the selected toolchain state.
|
|
68
70
|
|
|
69
|
-
The portable output is an app-scoped
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
The portable output is an app-scoped payload directory with complete selected
|
|
72
|
+
app and dependency files, a generated Core entry and classic client source.
|
|
73
|
+
It is not an executable and has no direct run operation. Explicit service
|
|
74
|
+
composition uses `createPortableNativeProvider({services:[{module,options}]})`;
|
|
75
|
+
the default adds no OS or application services. See
|
|
76
|
+
[Core native packaging](reference/core-native-packaging.md).
|
|
77
|
+
The external workspace defaults to `build/portable/`. Integrated Arcane work
|
|
78
|
+
must name an `--output-root` outside that checkout. Explicit checkout providers
|
|
79
|
+
still use the same canonical checkout for `--workspace` and `--arcane-root`;
|
|
80
|
+
the default SDK portable provider instead uses its installed package root.
|
|
74
81
|
|
|
75
82
|
Compatibility uses the highest minimum Core version declared by the SDK runtime,
|
|
76
83
|
selected app, and bundled app dependencies, plus each app's Arcane protocol and
|
|
@@ -81,7 +88,7 @@ for the complete compatibility and breaking-change rule.
|
|
|
81
88
|
| Target | Formats | Development status |
|
|
82
89
|
|---|---|---|
|
|
83
90
|
| `browser` | `directory` | Available |
|
|
84
|
-
| `portable` | `portable` directory |
|
|
91
|
+
| `portable` | `portable` directory | SDK package provider by default; explicit checkout override retained; not executable |
|
|
85
92
|
| `windows-x64` | `exe` bundle | Available with explicit `--arcane-root`; unsigned local development only |
|
|
86
93
|
| `linux-x64` | `deb` | Available with explicit `--arcane-root`; unsigned local development only |
|
|
87
94
|
| `linux-arm64` | `deb` | Available with explicit `--arcane-root` on a compatible native ARM64 toolchain; unsigned local development only |
|
|
@@ -89,7 +96,9 @@ for the complete compatibility and breaking-change rule.
|
|
|
89
96
|
|
|
90
97
|
macOS can consume browser applications and portable JavaScript capabilities
|
|
91
98
|
within their declared runtimes. The current target registry has no macOS native
|
|
92
|
-
package adapter
|
|
99
|
+
package adapter, and the portable CLI request currently selects only Windows
|
|
100
|
+
or Linux. macOS native packaging and Android host adaptation remain incomplete;
|
|
101
|
+
the SDK portable payload does not supply executable hosts. A source-development
|
|
93
102
|
native wrapper is also not an exposed `arcane dev` target. Native `run` uses the
|
|
94
103
|
selected packaged application through its paired provider.
|
|
95
104
|
|
package/docs/reference/README.md
CHANGED
|
@@ -67,12 +67,14 @@ This repository contains explicitly versioned surfaces with different owners:
|
|
|
67
67
|
| Browser SDK runtime | Selected SDK, `browser-runtime/` | Events, logging, Wllama, local/native/cloud speech, TWiN requests and PWA mechanisms. `listSdkBrowserRuntimeFiles()`, `readSdkBrowserRuntimeFile()`, and `loadSdkBrowserRuntimeRelease()` derive its current inventory directly from the selected directory. |
|
|
68
68
|
| Core reference snapshot | Arcane OS commit `567ad110bf57a1c2d4a3daa22ae93716cc5f4d7e`, protocol `arcane/1` | The application-facing Core contract imported into `docs/reference/core/`, with SDK-local links and package-boundary notes added explicitly. |
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
Browser modules and reusable Core client/runtime/lifecycle source belong to the
|
|
71
|
+
SDK. The portable provider uses this installed package by default and assembles
|
|
72
|
+
an app payload with explicitly selected services; it supplies no executable
|
|
73
|
+
platform host. Explicit Arcane OS provider overrides and integrated shared
|
|
74
|
+
checks remain available. Arcane OS retains its product composition and policy.
|
|
75
|
+
The historical Core reference snapshot describes a separate host contract;
|
|
76
|
+
matching a protocol name or assembling a payload alone does not establish that
|
|
77
|
+
a composed host supplies every required method or service.
|
|
76
78
|
|
|
77
79
|
See the [Core reference source notes](core/README.md) for the imported inventory
|
|
78
80
|
and the distinction between a documentation snapshot and the selected runtime.
|
|
@@ -229,8 +229,10 @@ synthesis, and TWiN Cloud/FAL synthesis can be registered through
|
|
|
229
229
|
`ai.configureSpeechProvider(role,provider,{modelId})`; configuration owns only
|
|
230
230
|
the selected role and performs no network request. Saved selections remain
|
|
231
231
|
application-owned, including selections waiting for provider registration.
|
|
232
|
-
The SDK
|
|
233
|
-
|
|
232
|
+
The SDK supplies reusable Core client/runtime/service-lifecycle primitives and
|
|
233
|
+
portable payload composition; privileged execution stays in a native host.
|
|
234
|
+
It supplies no application credential, selected model or product speech-service
|
|
235
|
+
authority. Capability-only built-in adapters report their
|
|
234
236
|
existing routes without probing, downloading, or changing providers. The sticky
|
|
235
237
|
[`AIRuntimeState`](runtime-modules.md#airuntimestatejs) surface keeps
|
|
236
238
|
application UI independent of transport. A selected route remains explicit:
|
|
@@ -43,7 +43,7 @@ development evidence; it is not native artifact or release acceptance.
|
|
|
43
43
|
| Browser-WASM local AI | The exported namespace, canonical ordered `{id, files:[{name?,url},...]}` descriptor, nonempty provider `sources` catalog, default `secure:false`, dormant `secure:true` intent, public AI API module lifecycle, lazy/manual policy, successful Wllama-load requirement, abort normalization, complete output and reasoning, all-choice validation, required structural-call `arguments.message`, exact call identity, and matching tool-result sequencing are represented in deterministic fixture sources. | A real Chrome exercise may load the selected Wllama runtime and model only after explicit user action. It is not an ordinary publication gate or an implicit model download. |
|
|
44
44
|
| Browser speech | Caller-owned Whisper/Kokoro selection, independent STT/TTS routes, ordinary direct upstream runtime/model use, dormant `secure:true` intent, DBOPFS cache, materialized known-route/native-fallback behavior, NPU-to-GPU-to-CPU automatic selection for both roles, fresh Workers after a failed device load, explicit-device failure without fallback, bounded Kokoro Worker/session pools, out-of-order synthesis settlement with FIFO admission, request-targeted TTS cancellation, destructive lifecycle cleanup, Blob/File STT conversion, WAV TTS conversion, complete text/audio, and no cloud fallback are represented with synthetic artifacts and adapters. | A real runtime/model/voice download, WebNN or WebGPU model load, physical accelerator behavior, and actual transcription or synthesis use the application's selected upstream packages/providers, browser media support, and explicit user action. A selected backend is not proof that every operation ran on that physical accelerator; WebNN may execute unsupported operations through WASM. |
|
|
45
45
|
| Persistent chat and document context | Atomic in-memory/history commit, explicit per-turn persistence, streamed/non-stream fallback, session-owned callback fields, complete data callbacks, per-turn request options, exact per-choice streamed/terminal call correlation before publication, terminal-only call acceptance, ordered parallel-call sequencing, atomic all-ID nonblank executed/declined/cancelled/not-executed result batches, readable unmodified malformed pre-existing rows, complete UI transcript metadata, generic visible failure outcomes with complete console diagnostics, BFCache-preserving component lifecycle, complete bootstrap/search/context, caller-source evaluation, cancellation, and partial-read handling are represented with app-scoped adapters. | Live Core/provider inference and durable browser storage remain separate authorities; tests never treat a fake chat function or in-memory adapter as host/storage proof. |
|
|
46
|
-
| Core bridge docs | Canonical namespace/method/event/entity inventories match their one-per-member guides and required sections. |
|
|
46
|
+
| Core bridge docs | Canonical namespace/method/event/entity inventories match their one-per-member guides and required sections. | SDK Core primitives and portable assembly have their own source fixtures. Live composed-host conformance and actual platform behavior remain separate evidence. |
|
|
47
47
|
| Arcane Ollama wrapper | Missing-host error, method forwarding, text/readiness normalization, unload request, and stream-option forwarding run against a deterministic fake `Arcane.ollama`. | Real managed-service, model download/create, GPU/resource admission, and service restart require an admitted Arcane host. |
|
|
48
48
|
| Native providers | Plan/provider protocol, explicit target, complete artifact reading, and unavailable-path honesty are tested with fixtures. | Windows, Linux, or Android artifact verification and launch must run on that actual platform/architecture and only when explicitly selected. |
|
|
49
49
|
|
|
@@ -122,8 +122,9 @@ not prove already-started host, provider, worker, or queue work stopped.
|
|
|
122
122
|
The SDK owns the singleton authority, its per-realm source adapters, package and
|
|
123
123
|
managed-browser projections, focused event/source/DOM contracts, runtime
|
|
124
124
|
compatibility views, package, CLI, synchronized renderer, documentation, and
|
|
125
|
-
injected provider-boundary behavior
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
injected provider-boundary behavior, reusable Core client/runtime/service
|
|
126
|
+
lifecycle and package-owned portable assembly. Arcane OS owns its product host
|
|
127
|
+
composition, Shell, Provisioner, model choices and application policy. Source
|
|
128
|
+
fixtures do not establish execution of the composed host, platform executable,
|
|
129
|
+
installer or model service. Verification stays at the selected owning output
|
|
130
|
+
and follows the active testing authority.
|
package/docs/reference/cli.md
CHANGED
|
@@ -692,11 +692,13 @@ npm exec -- arcane verify-bundle dist/hello-world-1.0.0.arcane-app.tar.gz
|
|
|
692
692
|
|
|
693
693
|
### Overview
|
|
694
694
|
|
|
695
|
-
Loads
|
|
696
|
-
|
|
695
|
+
Loads the SDK package provider for portable by default, or the fixed provider
|
|
696
|
+
from an explicitly selected Arcane OS checkout. It diagnoses the selected
|
|
697
|
+
provider prerequisites without building an app. Executable targets still
|
|
698
|
+
require `--arcane-root` and their platform toolchains.
|
|
697
699
|
|
|
698
700
|
```text
|
|
699
|
-
arcane native-doctor --target <native-target> --arcane-root <directory>
|
|
701
|
+
arcane native-doctor --target <native-target> [--arcane-root <directory>]
|
|
700
702
|
```
|
|
701
703
|
|
|
702
704
|
### Availability
|
|
@@ -722,7 +724,7 @@ It is not a prerequisite command to repeat immediately before `build`; `build`
|
|
|
722
724
|
prepares its own selected toolchain state.
|
|
723
725
|
|
|
724
726
|
```text
|
|
725
|
-
arcane native-prepare --target <native-target> --arcane-root <directory>
|
|
727
|
+
arcane native-prepare --target <native-target> [--arcane-root <directory>]
|
|
726
728
|
```
|
|
727
729
|
|
|
728
730
|
### Example
|
|
@@ -749,6 +751,12 @@ The command selects one workspace, app, target, architecture, format, signing
|
|
|
749
751
|
profile, and output root. Current providers emit a portable directory,
|
|
750
752
|
Windows x64 EXE bundle, Linux x64/ARM64 DEB, or development-signed Android APK.
|
|
751
753
|
The output remains target-specific inside the common plan contract.
|
|
754
|
+
Portable uses the SDK package without an OS checkout, copies complete selected
|
|
755
|
+
app/dependency payloads and generates the Core entry/classic client source.
|
|
756
|
+
It adds no executable platform host or automatically discovered app services.
|
|
757
|
+
An explicit `--arcane-root` continues to select the checkout provider.
|
|
758
|
+
Integrated builds retain an output root outside the OS checkout; only an
|
|
759
|
+
explicit checkout provider must share the workspace root.
|
|
752
760
|
The app's `outputDirectory` selects its packaged browser-content input;
|
|
753
761
|
native `--output-root` independently selects native build output.
|
|
754
762
|
`--dry-run` is implemented for the browser build path. Native builds reject it
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Core browser client
|
|
2
|
+
|
|
3
|
+
`arcane-os/core/client` is the browser-safe `arcane/1` RPC owner. It exports
|
|
4
|
+
`createCoreClient`, `createCoreFacade` and `installCoreClient`.
|
|
5
|
+
`arcane-os/core/contracts` exports `CORE_PROTOCOL`, `CORE_READY_EVENTS`,
|
|
6
|
+
`CORE_FRAME_CONTRACTS`, `CORE_METHOD_CONTRACTS`, `CoreError` and
|
|
7
|
+
`serializeCoreError`. Contracts describe transport and existing method shapes;
|
|
8
|
+
they do not select application policy or decide which services are installed.
|
|
9
|
+
|
|
10
|
+
## Native connection and explicit adapters
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import {installCoreClient} from 'arcane-os/core/client';
|
|
14
|
+
|
|
15
|
+
const client=installCoreClient();
|
|
16
|
+
const stop=client.events.when('core.ready',state=>{
|
|
17
|
+
console.log('The moon-base dispatcher is connected.',state);
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Installation immediately supplies `globalThis.Arcane`, `__arcaneReceive`,
|
|
22
|
+
synchronous `Arcane.runtime.current()` and `Arcane.events.completed(name)`.
|
|
23
|
+
Repeated installation returns the same client. Existing namespace method names
|
|
24
|
+
remain available through this facade; their implementations and availability
|
|
25
|
+
belong to the selected host. No repository, app list, model selection or service
|
|
26
|
+
implementation is installed by importing this client.
|
|
27
|
+
|
|
28
|
+
The native adapters select WebView2, WebKitGTK or Android WebView. Ordinary
|
|
29
|
+
browsers remain `standalone`; they do not probe a local server. Development
|
|
30
|
+
HTTP is selected only by the existing explicit `__ARCANE_DEV_HTTP__` flag.
|
|
31
|
+
Native process startup and shutdown belong to the native host/runtime, not
|
|
32
|
+
this browser module.
|
|
33
|
+
|
|
34
|
+
For a separately owned transport, use `createCoreClient({transport})` with
|
|
35
|
+
`transport.name`, `send(frame)`, and an optional `subscribe(receive)` returning
|
|
36
|
+
an unsubscribe function. Alternatively deliver responses/events through
|
|
37
|
+
`client.receive(frame)`. An adapter may return a promise from `send`; rejection
|
|
38
|
+
rejects the associated pending request. If cancellation, timeout or a response
|
|
39
|
+
has already settled it, `onError` observes the later send failure. A transport
|
|
40
|
+
without callable `send(frame)` remains disconnected and reports
|
|
41
|
+
`ARCANE_TRANSPORT_INVALID`; it does not announce `transport.ready`.
|
|
42
|
+
`autoConnect:false` defers connection until `connect()` or the first invocation.
|
|
43
|
+
|
|
44
|
+
`client.invoke(method, parameters, {signal, timeoutMs})` returns the actual
|
|
45
|
+
response result or rejects with `CoreError`. Parameters, result fields and
|
|
46
|
+
event data retain their complete supplied content. JSON encoding belongs only
|
|
47
|
+
to transports that require it; values crossing those transports must be
|
|
48
|
+
JSON-compatible. There is no client method allowlist or content limit.
|
|
49
|
+
The default request timeout is ten minutes; `timeoutMs:0` disables that timer.
|
|
50
|
+
The compatibility facade retains its operation-specific timeouts and streaming
|
|
51
|
+
callbacks. Streaming IDs and isolated-operation IDs are separate protocol
|
|
52
|
+
correlation fields alongside the supplied request fields.
|
|
53
|
+
|
|
54
|
+
## Events and request lifetime
|
|
55
|
+
|
|
56
|
+
`events.on(name, listener)`, `once(name, listener)` and
|
|
57
|
+
`when(name, listener)` return unsubscribe functions. Named listeners receive
|
|
58
|
+
the original `data`; `on('*', listener)` receives `{event, data}`. The shared
|
|
59
|
+
SDK event owner provides delivery, with one source per client and no competing
|
|
60
|
+
event bus. `when` replays the first authoritative `transport.ready` or
|
|
61
|
+
`core.ready` state once, on a microtask. `completed` is synchronous.
|
|
62
|
+
|
|
63
|
+
Transport connection, Core dispatcher readiness, application-service state,
|
|
64
|
+
repository synchronization and model readiness are different states.
|
|
65
|
+
`core.ready` does not claim that a model is loaded or an app repository synced.
|
|
66
|
+
Other service events pass through normally; this client does not fabricate
|
|
67
|
+
service readiness.
|
|
68
|
+
|
|
69
|
+
Abort/timeout sends `request.cancel`; `cancelAll()` and page hide send
|
|
70
|
+
`requests.cancelAll` for pending renderer requests. Late responses cannot
|
|
71
|
+
resolve a cancelled request. These controls do not promise to roll back an
|
|
72
|
+
accepted mutation. Accepted saves, operation journals and graceful drain belong
|
|
73
|
+
to the service/runtime owner. `client.close()` releases its subscriptions,
|
|
74
|
+
native callbacks, timers and pending renderer requests; it does not kill Core.
|
|
75
|
+
Call `stop()` to remove an individual subscription and `client.close()` when
|
|
76
|
+
the client owner ends its lifetime.
|
|
77
|
+
|
|
78
|
+
Errors retain complete native fields, including diagnostics and stack/cause
|
|
79
|
+
information. WebView2 and Android bridge failures retain native error codes,
|
|
80
|
+
messages and diagnostic fields; the request method and transport are added
|
|
81
|
+
where the native error does not already supply them. Errors without a native
|
|
82
|
+
code receive the adapter's bridge-call failure code. Keep those details in
|
|
83
|
+
developer diagnostics, rather than ordinary
|
|
84
|
+
product status surfaces. The optional `onError(error)` callback observes
|
|
85
|
+
transport/event-owner failures outside individual request promises.
|
|
86
|
+
|
|
87
|
+
## Classic native-host injection
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
import {createCoreClassicSource} from 'arcane-os/core/classic-source';
|
|
91
|
+
|
|
92
|
+
const source=await createCoreClassicSource({
|
|
93
|
+
eventOwnerModuleURL:'/arcane/sdk/event-manager.mjs'
|
|
94
|
+
});
|
|
95
|
+
// Supply source to the native host's existing classic-script injection owner.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This Node-only source generator reads the canonical client and contracts in the
|
|
99
|
+
installed SDK. It emits the same implementation as a classic script, without
|
|
100
|
+
copying another client or adding a bundler. The caller supplies the actual
|
|
101
|
+
served SDK event-manager URL; the example URL must match its selected layout.
|
|
102
|
+
That module and its existing managed import map must be included by packaging.
|
|
103
|
+
|
|
104
|
+
The generated facade, native receive callback and current-state methods install
|
|
105
|
+
synchronously. When the shared event owner already exists, it is reused
|
|
106
|
+
immediately. Document-created injection can precede the page's import map, so
|
|
107
|
+
only its event-owner module import waits until document parsing completes.
|
|
108
|
+
Page rendering and RPC setup continue independently. Complete early event
|
|
109
|
+
frames, subscription operations and response deliveries remain ordered until
|
|
110
|
+
the event owner connects. Work received reentrantly during that handoff joins
|
|
111
|
+
the end of the existing queue, including new subscriptions and response frames.
|
|
112
|
+
Final response completion follows earlier event
|
|
113
|
+
delivery, preserving streaming callbacks before their completion cleanup.
|
|
114
|
+
`client.eventsReady` observes that connection; failures are also reported
|
|
115
|
+
through `onError` and reject pending requests.
|
|
116
|
+
|
|
117
|
+
The SDK's [portable native provider](core-native-packaging.md) assembles the
|
|
118
|
+
Core runtime and selected app services without a native-provider checkout.
|
|
119
|
+
It does not distribute a Core executable or change OS callers. Executable
|
|
120
|
+
platform hosts and their cutover remain separately owned work.
|