arcane-os 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +86 -117
- package/bin/arcane-test.mjs +170 -46
- package/browser-runtime/ai/browser-speech-artifacts.mjs +887 -909
- package/browser-runtime/ai/browser-speech-providers.mjs +96 -152
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +627 -819
- package/browser-runtime/ai/browser-wasm.mjs +24 -35
- package/browser-runtime/ai/browser-wllama-runtime.mjs +64 -316
- package/browser-runtime/ai/model-controller.mjs +584 -181
- package/browser-runtime/ai/speech-worker-client.mjs +8 -146
- package/browser-runtime/ai/speech-worker-runtime.mjs +643 -363
- package/browser-runtime/dom-event-instrumentation.mjs +55 -147
- package/browser-runtime/event-manager.mjs +239 -624
- package/package.json +5 -6
- package/runtime/arcane/components/app-bar.html +3 -15
- package/runtime/arcane/components/assistant-panel.html +10 -10
- package/runtime/arcane/components/calculator.html +1 -1
- package/runtime/arcane/components/chat.html +1359 -135
- package/runtime/arcane/components/conversation-view.html +2 -2
- package/runtime/arcane/components/document-inspector.html +11 -17
- package/runtime/arcane/components/file-manager.html +13 -56
- package/runtime/arcane/components/markdown-document.html +82 -281
- package/runtime/arcane/components/markdown-editor.html +7 -10
- package/runtime/arcane/components/media-embed.html +6 -6
- package/runtime/arcane/components/screen-capture.html +4 -4
- package/runtime/arcane/components/source-explanation.html +2 -2
- package/runtime/arcane/components/speech.html +112 -68
- package/runtime/arcane/components/terminal-workspace.html +4 -4
- package/runtime/arcane/components/theme-editor.html +1 -1
- package/runtime/arcane/components/unified-inbox.html +2 -2
- package/runtime/arcane/components/voice-transcription.html +31 -21
- package/runtime/arcane/entities/Calculation.js +2 -3
- package/runtime/arcane/entities/Chat.js +228 -43
- package/runtime/arcane/entities/Preference.js +3 -5
- package/runtime/arcane/entities/Weather.js +5 -5
- package/runtime/arcane/modules/AI.js +1050 -427
- package/runtime/arcane/modules/AIProviderRuntime.js +658 -363
- package/runtime/arcane/modules/AIResponseLength.js +9 -19
- package/runtime/arcane/modules/AIRuntimeState.js +109 -72
- package/runtime/arcane/modules/ArcaneNavigationPolicy.js +45 -32
- package/runtime/arcane/modules/BrowserTestSuite.js +78 -122
- package/runtime/arcane/modules/CalculatorEngine.js +9 -9
- package/runtime/arcane/modules/CommunicationAppController.js +3 -7
- package/runtime/arcane/modules/ComponentContracts.js +30 -32
- package/runtime/arcane/modules/ConfiguredAIChatSession.js +281 -230
- package/runtime/arcane/modules/ConversationActionItems.js +26 -59
- package/runtime/arcane/modules/ConversationClosingReport.js +34 -61
- package/runtime/arcane/modules/ConversationTimebox.js +27 -15
- package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +152 -344
- package/runtime/arcane/modules/DocumentLexicalSearch.js +25 -91
- package/runtime/arcane/modules/HTMLImport.js +54 -1
- package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +40 -203
- package/runtime/arcane/modules/LocalAIReadiness.js +40 -60
- package/runtime/arcane/modules/LocalAIReadinessController.js +15 -13
- package/runtime/arcane/modules/MD.js +1 -45
- package/runtime/arcane/modules/Mail.js +51 -103
- package/runtime/arcane/modules/MailOutbox.mjs +95 -193
- package/runtime/arcane/modules/MailTransport.mjs +36 -57
- package/runtime/arcane/modules/ModelDefinition.js +22 -106
- package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +39 -101
- package/runtime/arcane/modules/PersistentAIChatSession.js +281 -18
- package/runtime/arcane/modules/PreferenceStore.js +102 -30
- package/runtime/arcane/modules/RiskSignalAnalyzer.js +8 -9
- package/runtime/arcane/modules/ScopedOPFSCache.js +7 -42
- package/runtime/arcane/modules/ScreenCapture.js +175 -128
- package/runtime/arcane/modules/SpeechPlayback.js +46 -149
- package/runtime/arcane/modules/StaticDocumentCatalog.js +173 -407
- package/runtime/arcane/modules/ToolCallRouter.js +25 -12
- package/runtime/arcane/modules/YouTubeMedia.js +6 -5
- package/schemas/arcane-app-bundle.schema.json +13 -78
- package/schemas/arcane-app.schema.json +9 -25
- package/schemas/arcane-lock.schema.json +18 -151
- package/schemas/arcane-package.schema.json +2 -16
- package/schemas/native-build-plan.schema.json +119 -122
- package/src/app-descriptor.mjs +75 -132
- package/src/application-tests.mjs +200 -0
- package/src/cli/main.mjs +27 -46
- package/src/constants.mjs +3 -4
- package/src/dev-server.mjs +30 -324
- package/src/doctor.mjs +92 -154
- package/src/dom-event-instrumentation.mjs +55 -147
- package/src/errors.mjs +2 -3
- package/src/event-manager.mjs +239 -624
- package/src/event-queue.mjs +3 -3
- package/src/import-map.mjs +273 -1028
- package/src/index.mjs +14 -16
- package/src/installed-sdk-runtime.mjs +40 -62
- package/src/integrated-provider-loader.mjs +53 -382
- package/src/mail-api.mjs +0 -2
- package/src/mail-server.mjs +224 -580
- package/src/mail.mjs +4 -10
- package/src/native-plan.mjs +163 -598
- package/src/native-provider-loader.mjs +104 -1063
- package/src/packager/core.mjs +485 -3229
- package/src/process.mjs +5 -10
- package/src/release-bundle.mjs +292 -2405
- package/src/runtime.mjs +76 -396
- package/src/scaffold.mjs +30 -80
- package/src/sdk-browser-runtime.mjs +70 -626
- package/src/source-server.mjs +588 -0
- package/src/targets/index.mjs +78 -188
- package/src/templates/workspace-template.mjs +19 -135
- package/src/testing-loader.mjs +164 -0
- package/src/testing.mjs +1 -1
- package/src/toolchain.mjs +131 -544
- package/src/update-check.mjs +26 -64
- package/src/workspace-operation-lock.mjs +139 -430
- package/src/workspace-runtime.mjs +112 -779
- package/src/workspace.mjs +40 -302
- package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +0 -218
- package/browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json +0 -203
- package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +0 -80
- package/browser-runtime/ai/internal/sha256.mjs +0 -166
- package/docs/architecture.md +0 -344
- package/docs/compatibility.md +0 -36
- package/docs/event-manager.md +0 -294
- package/docs/platform-targets.md +0 -108
- package/docs/publishing.md +0 -201
- package/docs/reference/README.md +0 -187
- package/docs/reference/ai/browser-speech-package-authority.json +0 -835
- package/docs/reference/ai/browser-speech.md +0 -1252
- package/docs/reference/ai/browser-wasm.md +0 -530
- package/docs/reference/arcane-ollama.md +0 -288
- package/docs/reference/availability-and-normalization.md +0 -183
- package/docs/reference/behavioral-testing.md +0 -133
- package/docs/reference/cli.md +0 -779
- package/docs/reference/core/README.md +0 -62
- package/docs/reference/core/arcane-ai-contracts.md +0 -907
- package/docs/reference/core/arcane-api.md +0 -601
- package/docs/reference/core/arcane-entities.md +0 -65
- package/docs/reference/core/arcane-events.md +0 -134
- package/docs/reference/core/ollama-module.md +0 -181
- package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +0 -1909
- package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +0 -1057
- package/docs/reference/core/reference/arcane-api/core-and-events.md +0 -320
- package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +0 -610
- package/docs/reference/core/reference/arcane-api/namespaces.md +0 -1157
- package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +0 -1423
- package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +0 -315
- package/docs/reference/event-manager.md +0 -1511
- package/docs/reference/inventory/package-api.json +0 -3284
- package/docs/reference/inventory/runtime-components.json +0 -1011
- package/docs/reference/inventory/runtime-entities.json +0 -26
- package/docs/reference/inventory/runtime-modules.json +0 -1431
- package/docs/reference/mail.md +0 -316
- package/docs/reference/protocols.md +0 -677
- package/docs/reference/runtime-components.md +0 -1366
- package/docs/reference/runtime-entities.md +0 -303
- package/docs/reference/runtime-modules.md +0 -2960
- package/docs/reference/sdk-api.md +0 -6694
- package/docs/roadmap.md +0 -79
- package/docs/work-amplification.md +0 -129
- package/runtime/ARCANE_RUNTIME_RELEASE.json +0 -826
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
SPEECH_WORKER_PROTOCOL,
|
|
5
5
|
} from "./speech-worker-runtime.mjs";
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const completeValue = (value) => value;
|
|
8
|
+
|
|
9
9
|
const PUBLIC_WORKER_OPERATIONS = new Set([
|
|
10
10
|
"load",
|
|
11
11
|
"use",
|
|
@@ -42,24 +42,6 @@ function abortError(signal, role, op) {
|
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function validProgress(role, progress) {
|
|
46
|
-
if (!progress || typeof progress !== "object" || Array.isArray(progress)) return false;
|
|
47
|
-
const keys = Object.keys(progress).sort().join(",");
|
|
48
|
-
if (keys !== "completed,heartbeat,phase,total,unit") return false;
|
|
49
|
-
const phases = new Set([
|
|
50
|
-
`${role}-runtime-import-started`,
|
|
51
|
-
`${role}-model-load-started`,
|
|
52
|
-
`${role}-model-load-progress`,
|
|
53
|
-
`${role}-provider-ready`,
|
|
54
|
-
]);
|
|
55
|
-
return phases.has(progress.phase)
|
|
56
|
-
&& Number.isFinite(progress.completed)
|
|
57
|
-
&& progress.completed >= 0
|
|
58
|
-
&& (progress.total === null || (Number.isFinite(progress.total) && progress.total >= 0))
|
|
59
|
-
&& (progress.unit === "bytes" || progress.unit === "items")
|
|
60
|
-
&& progress.heartbeat === true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
45
|
function validateWorker(worker) {
|
|
64
46
|
if (!worker || typeof worker.postMessage !== "function" || typeof worker.terminate !== "function") {
|
|
65
47
|
throw new TypeError("The packaged speech worker did not create a Worker.");
|
|
@@ -67,23 +49,6 @@ function validateWorker(worker) {
|
|
|
67
49
|
return worker;
|
|
68
50
|
}
|
|
69
51
|
|
|
70
|
-
function validateMessagePort(port) {
|
|
71
|
-
if (
|
|
72
|
-
!port
|
|
73
|
-
|| typeof port.postMessage !== "function"
|
|
74
|
-
|| typeof port.addEventListener !== "function"
|
|
75
|
-
|| typeof port.close !== "function"
|
|
76
|
-
) {
|
|
77
|
-
throw clientError(
|
|
78
|
-
"ARCANE_AI_WORKER_MESSAGE_ERROR",
|
|
79
|
-
"The browser did not create a usable private speech Worker MessagePort.",
|
|
80
|
-
undefined,
|
|
81
|
-
"artifact-graph-private-message-port-unavailable",
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
return port;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
52
|
const WORKER_CLIENTS = new WeakSet();
|
|
88
53
|
|
|
89
54
|
/**
|
|
@@ -95,8 +60,6 @@ class SpeechWorkerClient {
|
|
|
95
60
|
#createWorker;
|
|
96
61
|
#worker = null;
|
|
97
62
|
#transport = null;
|
|
98
|
-
#transportMode = null;
|
|
99
|
-
#privatePorts = null;
|
|
100
63
|
#pending = new Map();
|
|
101
64
|
#nextId = 1;
|
|
102
65
|
#listeners = [];
|
|
@@ -140,7 +103,6 @@ class SpeechWorkerClient {
|
|
|
140
103
|
const worker = validateWorker(this.#createWorker());
|
|
141
104
|
this.#worker = worker;
|
|
142
105
|
this.#listen(worker, "message", (event) => {
|
|
143
|
-
if (this.#transportMode === "private-message-port") return;
|
|
144
106
|
this.#handleMessage(event.data);
|
|
145
107
|
});
|
|
146
108
|
this.#listen(worker, "messageerror", (event) => {
|
|
@@ -162,44 +124,6 @@ class SpeechWorkerClient {
|
|
|
162
124
|
return worker;
|
|
163
125
|
}
|
|
164
126
|
|
|
165
|
-
#establishPrivateTransport() {
|
|
166
|
-
if (this.#transportMode === "private-message-port") return null;
|
|
167
|
-
if (this.#transportMode !== null) {
|
|
168
|
-
throw clientError(
|
|
169
|
-
"ARCANE_AI_ADAPTER_PROTOCOL_MISMATCH",
|
|
170
|
-
"The speech Worker already uses the legacy global message transport.",
|
|
171
|
-
undefined,
|
|
172
|
-
"artifact-graph-private-message-port-established-too-late",
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
const MessageChannelConstructor = globalThis.MessageChannel;
|
|
176
|
-
if (typeof MessageChannelConstructor !== "function") {
|
|
177
|
-
throw clientError(
|
|
178
|
-
"ARCANE_AI_WORKER_MESSAGE_ERROR",
|
|
179
|
-
"Authenticated artifact graph loading requires MessageChannel.",
|
|
180
|
-
undefined,
|
|
181
|
-
"artifact-graph-private-message-channel-unavailable",
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
const channel = new MessageChannelConstructor();
|
|
185
|
-
const clientPort = validateMessagePort(channel.port1);
|
|
186
|
-
const workerPort = validateMessagePort(channel.port2);
|
|
187
|
-
this.#privatePorts = Object.freeze({ clientPort, workerPort });
|
|
188
|
-
this.#transport = clientPort;
|
|
189
|
-
this.#transportMode = "private-message-port";
|
|
190
|
-
this.#listen(clientPort, "message", (event) => this.#handleMessage(event.data));
|
|
191
|
-
this.#listen(clientPort, "messageerror", (event) => {
|
|
192
|
-
void this.terminate(clientError(
|
|
193
|
-
"ARCANE_AI_WORKER_MESSAGE_ERROR",
|
|
194
|
-
"The private speech Worker MessagePort returned an unreadable message.",
|
|
195
|
-
event,
|
|
196
|
-
`${this.#role}-worker-private-message-rejected`,
|
|
197
|
-
), { intentional: false }).catch(() => undefined);
|
|
198
|
-
});
|
|
199
|
-
clientPort.start?.();
|
|
200
|
-
return workerPort;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
127
|
#handleMessage(message) {
|
|
204
128
|
if (message?.protocol !== SPEECH_WORKER_PROTOCOL) {
|
|
205
129
|
void this.terminate(clientError(
|
|
@@ -210,30 +134,6 @@ class SpeechWorkerClient {
|
|
|
210
134
|
), { intentional: false }).catch(() => undefined);
|
|
211
135
|
return;
|
|
212
136
|
}
|
|
213
|
-
if (message.event === "progress") {
|
|
214
|
-
const pending = this.#pending.get(message.requestId);
|
|
215
|
-
if (!pending) return;
|
|
216
|
-
if (!validProgress(this.#role, message.progress)) {
|
|
217
|
-
void this.terminate(clientError(
|
|
218
|
-
"ARCANE_AI_WORKER_MESSAGE_ERROR",
|
|
219
|
-
"The speech Worker progress envelope was rejected.",
|
|
220
|
-
undefined,
|
|
221
|
-
`${this.#role}-worker-progress-envelope-rejected`,
|
|
222
|
-
), { intentional: false }).catch(() => undefined);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
try {
|
|
226
|
-
pending.progress(message.progress);
|
|
227
|
-
} catch (error) {
|
|
228
|
-
void this.terminate(clientError(
|
|
229
|
-
"ARCANE_AI_PROGRESS_CALLBACK_THREW",
|
|
230
|
-
"The speech load progress callback threw an exception.",
|
|
231
|
-
error,
|
|
232
|
-
`${this.#role}-load-progress-callback-threw`,
|
|
233
|
-
), { intentional: false }).catch(() => undefined);
|
|
234
|
-
}
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
137
|
if (!Number.isSafeInteger(message.id) || typeof message.ok !== "boolean") {
|
|
238
138
|
void this.terminate(clientError(
|
|
239
139
|
"ARCANE_AI_WORKER_MESSAGE_ERROR",
|
|
@@ -270,12 +170,12 @@ class SpeechWorkerClient {
|
|
|
270
170
|
pending.reject(clientError(
|
|
271
171
|
admitted.code,
|
|
272
172
|
admitted.message,
|
|
273
|
-
|
|
173
|
+
admitted.cause,
|
|
274
174
|
admitted.reason,
|
|
275
175
|
));
|
|
276
176
|
}
|
|
277
177
|
|
|
278
|
-
request(op, payload, { signal = null
|
|
178
|
+
request(op, payload, { signal = null } = {}) {
|
|
279
179
|
if (!PUBLIC_WORKER_OPERATIONS.has(op)) {
|
|
280
180
|
return Promise.reject(clientError(
|
|
281
181
|
"ARCANE_AI_INVALID_REQUEST",
|
|
@@ -285,31 +185,10 @@ class SpeechWorkerClient {
|
|
|
285
185
|
));
|
|
286
186
|
}
|
|
287
187
|
if (signal?.aborted) return Promise.reject(abortError(signal, this.#role, op));
|
|
288
|
-
if (typeof progress !== "function") {
|
|
289
|
-
return Promise.reject(new TypeError("Speech Worker progress must be a function."));
|
|
290
|
-
}
|
|
291
188
|
let worker;
|
|
292
|
-
let initialPrivatePort = null;
|
|
293
189
|
try {
|
|
294
190
|
worker = this.#start();
|
|
295
|
-
|
|
296
|
-
&& payload?.configuration?.runtime?.moduleGraph === ARTIFACT_GRAPH_MODULE_GRAPH;
|
|
297
|
-
if (graphLoad) {
|
|
298
|
-
initialPrivatePort = this.#establishPrivateTransport();
|
|
299
|
-
} else if (this.#transportMode === null) {
|
|
300
|
-
this.#transportMode = "worker-global-message";
|
|
301
|
-
this.#transport = worker;
|
|
302
|
-
}
|
|
303
|
-
if (op === "load"
|
|
304
|
-
&& !graphLoad
|
|
305
|
-
&& this.#transportMode === "private-message-port") {
|
|
306
|
-
throw clientError(
|
|
307
|
-
"ARCANE_AI_ADAPTER_PROTOCOL_MISMATCH",
|
|
308
|
-
"A private artifact graph Worker cannot load a legacy runtime descriptor.",
|
|
309
|
-
undefined,
|
|
310
|
-
`${this.#role}-worker-runtime-transport-mode-mismatch`,
|
|
311
|
-
);
|
|
312
|
-
}
|
|
191
|
+
this.#transport = worker;
|
|
313
192
|
} catch (error) {
|
|
314
193
|
return Promise.reject(error);
|
|
315
194
|
}
|
|
@@ -330,7 +209,7 @@ class SpeechWorkerClient {
|
|
|
330
209
|
).catch(() => undefined);
|
|
331
210
|
};
|
|
332
211
|
signal?.addEventListener?.("abort", onAbort, { once: true });
|
|
333
|
-
this.#pending.set(id, { resolve, reject,
|
|
212
|
+
this.#pending.set(id, { resolve, reject, cleanup, op });
|
|
334
213
|
const message = {
|
|
335
214
|
protocol: SPEECH_WORKER_PROTOCOL,
|
|
336
215
|
id,
|
|
@@ -338,14 +217,8 @@ class SpeechWorkerClient {
|
|
|
338
217
|
payload,
|
|
339
218
|
};
|
|
340
219
|
const transfers = collectSpeechTransferables(payload);
|
|
341
|
-
let destination = this.#transport;
|
|
342
|
-
if (initialPrivatePort) {
|
|
343
|
-
message.privatePort = initialPrivatePort;
|
|
344
|
-
transfers.push(initialPrivatePort);
|
|
345
|
-
destination = worker;
|
|
346
|
-
}
|
|
347
220
|
try {
|
|
348
|
-
|
|
221
|
+
this.#transport.postMessage(message, transfers);
|
|
349
222
|
} catch (error) {
|
|
350
223
|
this.#pending.delete(id);
|
|
351
224
|
cleanup();
|
|
@@ -388,23 +261,12 @@ class SpeechWorkerClient {
|
|
|
388
261
|
for (const pending of pendingOperations) pending.cleanup();
|
|
389
262
|
this.#pending.clear();
|
|
390
263
|
try {
|
|
391
|
-
for (const port of [
|
|
392
|
-
this.#privatePorts?.clientPort,
|
|
393
|
-
this.#privatePorts?.workerPort,
|
|
394
|
-
]) {
|
|
395
|
-
try {
|
|
396
|
-
port?.close();
|
|
397
|
-
} catch {
|
|
398
|
-
// Worker termination remains the authoritative cancellation boundary.
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
this.#privatePorts = null;
|
|
402
264
|
this.#transport = null;
|
|
403
265
|
const termination = worker?.terminate();
|
|
404
266
|
if (termination && typeof termination.then === "function") await termination;
|
|
405
267
|
} finally {
|
|
406
268
|
for (const pending of pendingOperations) pending.reject(terminationReason);
|
|
407
|
-
this.#onTermination(
|
|
269
|
+
this.#onTermination(completeValue({ reason: terminationReason, intentional }));
|
|
408
270
|
}
|
|
409
271
|
}
|
|
410
272
|
}
|