arcane-os 0.3.1 → 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 +14 -0
- package/README.md +86 -117
- package/bin/arcane-test.mjs +170 -46
- package/browser-runtime/ai/browser-speech-artifacts.mjs +855 -895
- package/browser-runtime/ai/browser-speech-providers.mjs +80 -204
- 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 -148
- package/browser-runtime/ai/speech-worker-runtime.mjs +642 -374
- 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 +1042 -427
- package/runtime/arcane/modules/AIProviderRuntime.js +618 -359
- 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 +27 -67
- 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 +109 -1558
- 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 -185
- package/docs/reference/ai/browser-speech-package-authority.json +0 -835
- package/docs/reference/ai/browser-speech.md +0 -1295
- 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 -719
- package/docs/reference/runtime-components.md +0 -1366
- package/docs/reference/runtime-entities.md +0 -303
- package/docs/reference/runtime-modules.md +0 -2965
- package/docs/reference/sdk-api.md +0 -6698
- 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
|
-
"Strict 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,33 +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
|
-
const strictGraphLoad = graphLoad
|
|
298
|
-
&& payload?.configuration?.security?.secure === true;
|
|
299
|
-
if (strictGraphLoad) {
|
|
300
|
-
initialPrivatePort = this.#establishPrivateTransport();
|
|
301
|
-
} else if (this.#transportMode === null) {
|
|
302
|
-
this.#transportMode = "worker-global-message";
|
|
303
|
-
this.#transport = worker;
|
|
304
|
-
}
|
|
305
|
-
if (op === "load"
|
|
306
|
-
&& !strictGraphLoad
|
|
307
|
-
&& this.#transportMode === "private-message-port") {
|
|
308
|
-
throw clientError(
|
|
309
|
-
"ARCANE_AI_ADAPTER_PROTOCOL_MISMATCH",
|
|
310
|
-
"A private strict artifact graph Worker cannot load an ordinary runtime descriptor.",
|
|
311
|
-
undefined,
|
|
312
|
-
`${this.#role}-worker-runtime-transport-mode-mismatch`,
|
|
313
|
-
);
|
|
314
|
-
}
|
|
191
|
+
this.#transport = worker;
|
|
315
192
|
} catch (error) {
|
|
316
193
|
return Promise.reject(error);
|
|
317
194
|
}
|
|
@@ -332,7 +209,7 @@ class SpeechWorkerClient {
|
|
|
332
209
|
).catch(() => undefined);
|
|
333
210
|
};
|
|
334
211
|
signal?.addEventListener?.("abort", onAbort, { once: true });
|
|
335
|
-
this.#pending.set(id, { resolve, reject,
|
|
212
|
+
this.#pending.set(id, { resolve, reject, cleanup, op });
|
|
336
213
|
const message = {
|
|
337
214
|
protocol: SPEECH_WORKER_PROTOCOL,
|
|
338
215
|
id,
|
|
@@ -340,14 +217,8 @@ class SpeechWorkerClient {
|
|
|
340
217
|
payload,
|
|
341
218
|
};
|
|
342
219
|
const transfers = collectSpeechTransferables(payload);
|
|
343
|
-
let destination = this.#transport;
|
|
344
|
-
if (initialPrivatePort) {
|
|
345
|
-
message.privatePort = initialPrivatePort;
|
|
346
|
-
transfers.push(initialPrivatePort);
|
|
347
|
-
destination = worker;
|
|
348
|
-
}
|
|
349
220
|
try {
|
|
350
|
-
|
|
221
|
+
this.#transport.postMessage(message, transfers);
|
|
351
222
|
} catch (error) {
|
|
352
223
|
this.#pending.delete(id);
|
|
353
224
|
cleanup();
|
|
@@ -390,23 +261,12 @@ class SpeechWorkerClient {
|
|
|
390
261
|
for (const pending of pendingOperations) pending.cleanup();
|
|
391
262
|
this.#pending.clear();
|
|
392
263
|
try {
|
|
393
|
-
for (const port of [
|
|
394
|
-
this.#privatePorts?.clientPort,
|
|
395
|
-
this.#privatePorts?.workerPort,
|
|
396
|
-
]) {
|
|
397
|
-
try {
|
|
398
|
-
port?.close();
|
|
399
|
-
} catch {
|
|
400
|
-
// Worker termination remains the authoritative cancellation boundary.
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
this.#privatePorts = null;
|
|
404
264
|
this.#transport = null;
|
|
405
265
|
const termination = worker?.terminate();
|
|
406
266
|
if (termination && typeof termination.then === "function") await termination;
|
|
407
267
|
} finally {
|
|
408
268
|
for (const pending of pendingOperations) pending.reject(terminationReason);
|
|
409
|
-
this.#onTermination(
|
|
269
|
+
this.#onTermination(completeValue({ reason: terminationReason, intentional }));
|
|
410
270
|
}
|
|
411
271
|
}
|
|
412
272
|
}
|