@camstack/system 1.1.56 → 1.1.58
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/dist/addon-runner.js +2 -2
- package/dist/addon-runner.mjs +2 -2
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-JAF9YR1q.mjs → dist-BNevCEAo.mjs} +0 -70
- package/dist/{dist-Bg795EQF.js → dist-BY6NWf-c.js} +0 -70
- package/dist/index.js +44 -107
- package/dist/index.mjs +45 -106
- package/dist/kernel/addon-loader.d.ts +7 -2
- package/dist/kernel/index.d.ts +1 -3
- package/dist/kernel/lifecycle/lifecycle-job-engine.d.ts +21 -26
- package/dist/{manifest-python-deps-eI3-3FeW.js → manifest-python-deps-D2G0DFWp.js} +1 -1
- package/dist/{manifest-python-deps-9wuRyL-k.mjs → manifest-python-deps-DtCMZhuR.mjs} +1 -1
- package/package.json +1 -1
- package/dist/kernel/lifecycle/framework-staging.d.ts +0 -15
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("./dist-
|
|
3
|
+
const require_dist = require("./dist-BY6NWf-c.js");
|
|
4
4
|
const require_model_download_service = require("./model-download-service-hf0ookyy.js");
|
|
5
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
5
|
+
const require_manifest_python_deps = require("./manifest-python-deps-D2G0DFWp.js");
|
|
6
6
|
const require_resource_monitor = require("./resource-monitor-DNNomR-i.js");
|
|
7
7
|
const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
|
|
8
8
|
const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
|
|
@@ -2308,9 +2308,15 @@ var AddonLoader = class {
|
|
|
2308
2308
|
else i++;
|
|
2309
2309
|
}
|
|
2310
2310
|
/** Scan addons directory and load all addon packages.
|
|
2311
|
-
* Supports scoped layout: addons/@scope/package-name/
|
|
2312
|
-
|
|
2311
|
+
* Supports scoped layout: addons/@scope/package-name/
|
|
2312
|
+
*
|
|
2313
|
+
* `skipPackages` names scoped packages (e.g. `@camstack/system`) that the
|
|
2314
|
+
* caller loads from elsewhere — the single-copy model loads the framework
|
|
2315
|
+
* BUILTINS from the active closure, not the (now-inert) addons-dir copy, so
|
|
2316
|
+
* the addons-dir `@camstack/system` must NOT be double-loaded here. */
|
|
2317
|
+
async loadFromDirectory(addonsDir, skipPackages = []) {
|
|
2313
2318
|
if (!node_fs.existsSync(addonsDir)) return;
|
|
2319
|
+
const skip = new Set(skipPackages);
|
|
2314
2320
|
const entries = node_fs.readdirSync(addonsDir, { withFileTypes: true });
|
|
2315
2321
|
for (const entry of entries) {
|
|
2316
2322
|
if (!isDirectoryEntry(entry, addonsDir)) continue;
|
|
@@ -2319,10 +2325,12 @@ var AddonLoader = class {
|
|
|
2319
2325
|
const scopeEntries = node_fs.readdirSync(scopeDir, { withFileTypes: true });
|
|
2320
2326
|
for (const scopeEntry of scopeEntries) {
|
|
2321
2327
|
if (!isDirectoryEntry(scopeEntry, scopeDir)) continue;
|
|
2328
|
+
if (skip.has(`${entry.name}/${scopeEntry.name}`)) continue;
|
|
2322
2329
|
await this.tryLoadAddon(node_path.join(scopeDir, scopeEntry.name));
|
|
2323
2330
|
}
|
|
2324
2331
|
continue;
|
|
2325
2332
|
}
|
|
2333
|
+
if (skip.has(entry.name)) continue;
|
|
2326
2334
|
await this.tryLoadAddon(node_path.join(addonsDir, entry.name));
|
|
2327
2335
|
}
|
|
2328
2336
|
}
|
|
@@ -93071,7 +93079,7 @@ var JobJournal = class {
|
|
|
93071
93079
|
};
|
|
93072
93080
|
//#endregion
|
|
93073
93081
|
//#region src/kernel/lifecycle/staging-area.ts
|
|
93074
|
-
function safeSegment
|
|
93082
|
+
function safeSegment(name) {
|
|
93075
93083
|
return name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
93076
93084
|
}
|
|
93077
93085
|
var StagingArea = class {
|
|
@@ -93082,7 +93090,7 @@ var StagingArea = class {
|
|
|
93082
93090
|
this.deps = deps;
|
|
93083
93091
|
}
|
|
93084
93092
|
async fetchAndStage(input) {
|
|
93085
|
-
const destDir = node_path.join(this.stagingDir, input.jobId, safeSegment
|
|
93093
|
+
const destDir = node_path.join(this.stagingDir, input.jobId, safeSegment(input.name));
|
|
93086
93094
|
node_fs.rmSync(destDir, {
|
|
93087
93095
|
recursive: true,
|
|
93088
93096
|
force: true
|
|
@@ -93218,50 +93226,22 @@ var LifecycleJobEngine = class {
|
|
|
93218
93226
|
}
|
|
93219
93227
|
}
|
|
93220
93228
|
/**
|
|
93221
|
-
*
|
|
93222
|
-
*
|
|
93223
|
-
*
|
|
93224
|
-
*
|
|
93225
|
-
*
|
|
93226
|
-
|
|
93227
|
-
|
|
93228
|
-
|
|
93229
|
-
|
|
93230
|
-
|
|
93231
|
-
|
|
93232
|
-
|
|
93233
|
-
|
|
93234
|
-
|
|
93235
|
-
|
|
93236
|
-
|
|
93237
|
-
this.advance(job.jobId, task, "fetching", {
|
|
93238
|
-
startedAtMs: this.deps.now(),
|
|
93239
|
-
attempts: task.attempts + 1
|
|
93240
|
-
});
|
|
93241
|
-
const ac = new AbortController();
|
|
93242
|
-
const timer = setTimeout(() => ac.abort(), this.deps.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS);
|
|
93243
|
-
let packages;
|
|
93244
|
-
try {
|
|
93245
|
-
packages = await stageFramework(task, ac.signal);
|
|
93246
|
-
} finally {
|
|
93247
|
-
clearTimeout(timer);
|
|
93248
|
-
}
|
|
93249
|
-
const [firstPackage] = packages;
|
|
93250
|
-
if (!firstPackage) throw new Error("stageFramework returned no packages");
|
|
93251
|
-
this.advance(job.jobId, task, "staged", { stagedPath: firstPackage.stagedPath });
|
|
93252
|
-
requestFrameworkSwap({
|
|
93253
|
-
jobId: job.jobId,
|
|
93254
|
-
taskId: task.taskId,
|
|
93255
|
-
packages
|
|
93256
|
-
});
|
|
93257
|
-
return this.deps.journal.getJob(job.jobId) ?? job;
|
|
93258
|
-
} catch (err) {
|
|
93259
|
-
this.advance(job.jobId, task, "failed", {
|
|
93260
|
-
error: err instanceof Error ? err.message : String(err),
|
|
93261
|
-
finishedAtMs: this.deps.now()
|
|
93262
|
-
});
|
|
93263
|
-
return null;
|
|
93264
|
-
}
|
|
93229
|
+
* Mark a framework task `skipped`.
|
|
93230
|
+
*
|
|
93231
|
+
* Framework packages (`@camstack/system` + its lockstep companions) are NO
|
|
93232
|
+
* LONGER updated through this engine. The legacy `/data/framework` per-package
|
|
93233
|
+
* swap was removed in the single-copy framework collapse (2026-07-18) — the
|
|
93234
|
+
* running framework is loaded from the active server-root single copy, and
|
|
93235
|
+
* framework/cap updates now ship EXCLUSIVELY via `applyServerUpdate` (the
|
|
93236
|
+
* node-root ServerUpdateService). Any framework task that still reaches this
|
|
93237
|
+
* engine (e.g. an "Update all" bulk job that swept `@camstack/system`) is
|
|
93238
|
+
* skipped, never applied — applying it would swap a dead dir.
|
|
93239
|
+
*/
|
|
93240
|
+
skipFrameworkTask(job, task) {
|
|
93241
|
+
this.advance(job.jobId, task, "skipped", {
|
|
93242
|
+
startedAtMs: task.startedAtMs ?? this.deps.now(),
|
|
93243
|
+
finishedAtMs: this.deps.now()
|
|
93244
|
+
});
|
|
93265
93245
|
}
|
|
93266
93246
|
/**
|
|
93267
93247
|
* Run the addon fetch phase with a bounded-concurrency worker pool. At most
|
|
@@ -93289,24 +93269,24 @@ var LifecycleJobEngine = class {
|
|
|
93289
93269
|
* §10 boot reconcile: re-drive every NON-TERMINAL addon task of a job that
|
|
93290
93270
|
* was interrupted mid-flight (e.g. a crash) from its on-disk checkpoint.
|
|
93291
93271
|
*
|
|
93292
|
-
* Framework tasks are
|
|
93293
|
-
*
|
|
93294
|
-
*
|
|
93272
|
+
* Framework tasks are NOT applied by this engine (single-copy collapse —
|
|
93273
|
+
* framework updates ship via `applyServerUpdate`). Any stray non-terminal
|
|
93274
|
+
* framework task is marked `skipped` so the interrupted job can finalize
|
|
93275
|
+
* instead of hanging `running` forever. Terminal addon tasks
|
|
93276
|
+
* (`done`/`failed`/`skipped`) are left as-is.
|
|
93295
93277
|
*
|
|
93296
93278
|
* Apply is idempotent (`applyAddonUpdate` backs up the live dir + restores on
|
|
93297
93279
|
* failure), so every non-terminal addon phase collapses to:
|
|
93298
93280
|
* ensure staged (reuse a still-valid `stagedPath` or re-fetch) → apply → done;
|
|
93299
93281
|
* on failure → `failed`.
|
|
93300
|
-
*
|
|
93301
|
-
* The job is finalized (`completed`/`partially-failed`/`failed` + staging
|
|
93302
|
-
* cleanup) ONLY when ALL tasks — including any framework task — are terminal.
|
|
93303
|
-
* If a framework task is still non-terminal the job is LEFT `running` (the
|
|
93304
|
-
* reboot/F2 path finalizes it).
|
|
93305
93282
|
*/
|
|
93306
93283
|
async reconcileJob(job) {
|
|
93307
93284
|
const exists = this.deps.stagedPathExists ?? ((p) => node_fs.existsSync(p));
|
|
93308
93285
|
for (const task of job.tasks) {
|
|
93309
|
-
if (task.target === "framework")
|
|
93286
|
+
if (task.target === "framework") {
|
|
93287
|
+
if (!this.isTerminal(task.phase)) this.skipFrameworkTask(job, task);
|
|
93288
|
+
continue;
|
|
93289
|
+
}
|
|
93310
93290
|
if (this.isTerminal(task.phase)) continue;
|
|
93311
93291
|
await this.reconcileAddonTask(job, task, exists);
|
|
93312
93292
|
}
|
|
@@ -93328,9 +93308,10 @@ var LifecycleJobEngine = class {
|
|
|
93328
93308
|
}
|
|
93329
93309
|
/**
|
|
93330
93310
|
* Finalize a reconciled job: `completed` if all addon tasks succeeded,
|
|
93331
|
-
* `failed` if all failed, `partially-failed` if mixed
|
|
93332
|
-
* task
|
|
93333
|
-
* (
|
|
93311
|
+
* `failed` if all failed, `partially-failed` if mixed. A skipped framework
|
|
93312
|
+
* task counts as neither success nor failure. Defensive: if a task is still
|
|
93313
|
+
* non-terminal (should not happen — reconcile drives every task terminal),
|
|
93314
|
+
* leave the job `running` and do not clean staging.
|
|
93334
93315
|
*/
|
|
93335
93316
|
finalizeReconciledJob(jobId) {
|
|
93336
93317
|
const current = this.deps.journal.getJob(jobId);
|
|
@@ -93346,6 +93327,7 @@ var LifecycleJobEngine = class {
|
|
|
93346
93327
|
async runJob(job) {
|
|
93347
93328
|
const addonTasks = job.tasks.filter((t) => t.target !== "framework");
|
|
93348
93329
|
const frameworkTasks = job.tasks.filter((t) => t.target === "framework");
|
|
93330
|
+
for (const task of frameworkTasks) this.skipFrameworkTask(job, task);
|
|
93349
93331
|
let failures = 0;
|
|
93350
93332
|
let successes = 0;
|
|
93351
93333
|
const fetchOutcomes = await this.fetchAddonsBounded(job, addonTasks);
|
|
@@ -93355,11 +93337,6 @@ var LifecycleJobEngine = class {
|
|
|
93355
93337
|
if (await this.applyAddonTask(job, outcome.task, outcome.stagedPath)) successes += 1;
|
|
93356
93338
|
else failures += 1;
|
|
93357
93339
|
}
|
|
93358
|
-
for (const task of frameworkTasks) {
|
|
93359
|
-
const result = await this.runFrameworkTask(job, task);
|
|
93360
|
-
if (result !== null) return result;
|
|
93361
|
-
failures += 1;
|
|
93362
|
-
}
|
|
93363
93340
|
const state = failures === 0 ? "completed" : successes === 0 ? "failed" : "partially-failed";
|
|
93364
93341
|
const finalJob = this.deps.journal.setJobState(job.jobId, state);
|
|
93365
93342
|
this.deps.staging.cleanup(job.jobId);
|
|
@@ -93367,44 +93344,6 @@ var LifecycleJobEngine = class {
|
|
|
93367
93344
|
}
|
|
93368
93345
|
};
|
|
93369
93346
|
//#endregion
|
|
93370
|
-
//#region src/kernel/lifecycle/framework-staging.ts
|
|
93371
|
-
var FRAMEWORK_LOCKSTEP = [
|
|
93372
|
-
"@camstack/system",
|
|
93373
|
-
"@camstack/types",
|
|
93374
|
-
"@camstack/sdk",
|
|
93375
|
-
"@camstack/shm-ring"
|
|
93376
|
-
];
|
|
93377
|
-
function safeSegment(name) {
|
|
93378
|
-
return name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
93379
|
-
}
|
|
93380
|
-
async function stageFrameworkLockstep(input) {
|
|
93381
|
-
const stagingArea = new StagingArea(input.stagingDir, {
|
|
93382
|
-
fetchTarball: input.fetchTarball,
|
|
93383
|
-
extract: input.extract
|
|
93384
|
-
});
|
|
93385
|
-
const results = [];
|
|
93386
|
-
const primary = FRAMEWORK_LOCKSTEP[0];
|
|
93387
|
-
for (const pkg of FRAMEWORK_LOCKSTEP) {
|
|
93388
|
-
const version = pkg === primary ? input.toVersion : await input.resolveVersion(pkg);
|
|
93389
|
-
const { stagedPath } = await stagingArea.fetchAndStage({
|
|
93390
|
-
jobId: input.jobId,
|
|
93391
|
-
name: pkg,
|
|
93392
|
-
version,
|
|
93393
|
-
signal: input.signal
|
|
93394
|
-
});
|
|
93395
|
-
const backupPath = node_path.join(input.stagingDir, input.jobId, ".bak-fw", safeSegment(pkg));
|
|
93396
|
-
const fromVersion = input.currentVersionOf(pkg);
|
|
93397
|
-
results.push({
|
|
93398
|
-
name: pkg,
|
|
93399
|
-
stagedPath,
|
|
93400
|
-
backupPath,
|
|
93401
|
-
toVersion: version,
|
|
93402
|
-
fromVersion
|
|
93403
|
-
});
|
|
93404
|
-
}
|
|
93405
|
-
return results;
|
|
93406
|
-
}
|
|
93407
|
-
//#endregion
|
|
93408
93347
|
exports.AGENT_CAP_FWD_ACTION = require_manifest_python_deps.AGENT_CAP_FWD_ACTION;
|
|
93409
93348
|
exports.AGENT_CAP_FWD_SERVICE = require_manifest_python_deps.AGENT_CAP_FWD_SERVICE;
|
|
93410
93349
|
exports.AGENT_READINESS_SERVICE_NAME = AGENT_READINESS_SERVICE_NAME;
|
|
@@ -93444,7 +93383,6 @@ exports.DeviceStore = require_builtins_sqlite_storage_index.DeviceStore$1;
|
|
|
93444
93383
|
exports.EVENT_TOPIC_PREFIX = require_manifest_python_deps.EVENT_TOPIC_PREFIX;
|
|
93445
93384
|
exports.EngineManagerResolver = EngineManagerResolver;
|
|
93446
93385
|
exports.EventBus = EventBus;
|
|
93447
|
-
exports.FRAMEWORK_LOCKSTEP = FRAMEWORK_LOCKSTEP;
|
|
93448
93386
|
exports.FeatureManager = FeatureManager;
|
|
93449
93387
|
exports.FilesystemStorageAddon = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageAddon;
|
|
93450
93388
|
exports.FilesystemStorageProvider = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageProvider;
|
|
@@ -93682,7 +93620,6 @@ exports.scopesAllowDeviceCap = scopesAllowDeviceCap;
|
|
|
93682
93620
|
exports.serializeTypedArrays = require_manifest_python_deps.serializeTypedArrays;
|
|
93683
93621
|
exports.setHubConnected = require_manifest_python_deps.setHubConnected;
|
|
93684
93622
|
exports.setNodeEventInterest = require_manifest_python_deps.setNodeEventInterest;
|
|
93685
|
-
exports.stageFrameworkLockstep = stageFrameworkLockstep;
|
|
93686
93623
|
exports.stripCamstackDeps = stripCamstackDeps;
|
|
93687
93624
|
exports.subscribePassthrough = require_manifest_python_deps.subscribePassthrough;
|
|
93688
93625
|
exports.udsChildLogToWorkerEntry = require_manifest_python_deps.udsChildLogToWorkerEntry;
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as isArrayOutputSchema, Ct as parseJsonObject, D as extractNestedAddonId, Dt as scopeKey, Et as resolveCapMount, F as lifecycleJobSchema, G as procedureAuthKey, H as objectInputDeclaresAddonId, M as isObjectInput, N as isVoidInput, P as kebabToCamel, R as looseSchema, Tt as readinessKey, _t as createEvent, at as DATAPLANE_SECRET_HEADER$1, bt as expandCapMethods, dt as ReadinessRegistry, ft as ReadinessTimeoutError, gt as asString$1, ht as asNumber, j as isCollectionArrayMethod, kt as EventCategory$1, mt as asJsonObject$1, o as METHOD_ACCESS_MAP, ot as DEVICE_SETTINGS_CONTRIBUTION_METHODS, p as addonSettingsCapability, rt as errMsg$1, s as RUNTIME_DEFAULTS, st as DEVICE_STATUS_METHOD, t as ALL_CAPABILITY_DEFINITIONS, vt as emitDownForOwnedCaps, wt as parseJsonUnknown$1 } from "./dist-
|
|
1
|
+
import { A as isArrayOutputSchema, Ct as parseJsonObject, D as extractNestedAddonId, Dt as scopeKey, Et as resolveCapMount, F as lifecycleJobSchema, G as procedureAuthKey, H as objectInputDeclaresAddonId, M as isObjectInput, N as isVoidInput, P as kebabToCamel, R as looseSchema, Tt as readinessKey, _t as createEvent, at as DATAPLANE_SECRET_HEADER$1, bt as expandCapMethods, dt as ReadinessRegistry, ft as ReadinessTimeoutError, gt as asString$1, ht as asNumber, j as isCollectionArrayMethod, kt as EventCategory$1, mt as asJsonObject$1, o as METHOD_ACCESS_MAP, ot as DEVICE_SETTINGS_CONTRIBUTION_METHODS, p as addonSettingsCapability, rt as errMsg$1, s as RUNTIME_DEFAULTS, st as DEVICE_STATUS_METHOD, t as ALL_CAPABILITY_DEFINITIONS, vt as emitDownForOwnedCaps, wt as parseJsonUnknown$1 } from "./dist-BNevCEAo.mjs";
|
|
2
2
|
import { a as downloadModel, c as getModelFilePath, d as contentTypeFor, f as createAuthenticatedFileServer, h as resolveFilePath, i as downloadFile, l as isModelDownloaded, m as parseTokenizedUrl, n as collectModelFiles, o as ensureModel, p as parseRangeHeader, r as deleteModelFromDisk, s as fetchJson, t as ModelDownloadService, u as createFileDataPlaneHandler } from "./model-download-service-Cp9f4dk6.mjs";
|
|
3
|
-
import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, B as AGENT_CAP_FWD_SERVICE, C as buildLinkChain, D as HUB_CAP_FWD_ACTION, E as localProviderLink, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, N as udsChildLogToWorkerEntry, O as HUB_CAP_FWD_SERVICE, P as createUdsLogger, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerTransportLink, T as ipcParentLink, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as resolveHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as getCapUsageRegistry, bt as resolveAddonClass, c as setHubConnected, ct as capActionName, d as getMoleculerEventStats, dt as capServiceName, et as createBrokerDeviceManagerApi, f as registerEventBusService, ft as parseCapAction, g as createKernelHwAccel, gt as CapabilityHandle, h as AddonDepsManager, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, k as createHubCapForwardService, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as subscribePassthrough, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as setNodeEventInterest, pt as deserializeTypedArrays, q as UdsLocalTransportServer, r as createAddonContext, rt as mountNativeCapService, s as getOrInitReadinessRegistryForClient, st as NATIVE_PROVIDER_SERVICE_INFIX, t as installManifestPythonDeps, u as getBrokerEventBus, ut as capBareAction, v as CapUsageRegistry, vt as installManifestNativeDeps, w as ipcChildLink, x as brokerCallForCap, xt as createAddonDataPlaneFacility, y as __resetCapUsageRegistryForTests, yt as runNpm, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-
|
|
3
|
+
import { $ as buildUdsNativeCapProxy, A as createParentUnownedCallHandler, B as AGENT_CAP_FWD_SERVICE, C as buildLinkChain, D as HUB_CAP_FWD_ACTION, E as localProviderLink, F as createUdsLoggerWithControl, G as createLocalTransport, H as CapRouteError, I as LocalChildClient, J as SocketChannel, K as UdsLocalTransportClient, L as LocalChildRegistry, M as createUdsEventBus, N as udsChildLogToWorkerEntry, O as HUB_CAP_FWD_SERVICE, P as createUdsLogger, Q as buildNativeCapProxy, R as UDS_NO_ROUTE_PREFIX, S as brokerTransportLink, T as ipcParentLink, U as classifyCapRoute, V as CapRouteResolver, W as callWithServiceDiscovery, X as FrameDecoder, Y as localEndpointPath, Z as encodeFrame, _ as resolveHwAccel, _t as CapabilityUnavailableError, a as getWorkerDeviceRegistry, at as createAddonService, b as getCapUsageRegistry, bt as resolveAddonClass, c as setHubConnected, ct as capActionName, d as getMoleculerEventStats, dt as capServiceName, et as createBrokerDeviceManagerApi, f as registerEventBusService, ft as parseCapAction, g as createKernelHwAccel, gt as CapabilityHandle, h as AddonDepsManager, ht as DeviceRegistry, i as createUdsAddonContext, j as createUdsEventBridge, k as createHubCapForwardService, l as EVENT_TOPIC_PREFIX, lt as capActionSuffix, m as subscribePassthrough, mt as serializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as validateProviderRegistrations, p as setNodeEventInterest, pt as deserializeTypedArrays, q as UdsLocalTransportServer, r as createAddonContext, rt as mountNativeCapService, s as getOrInitReadinessRegistryForClient, st as NATIVE_PROVIDER_SERVICE_INFIX, t as installManifestPythonDeps, u as getBrokerEventBus, ut as capBareAction, v as CapUsageRegistry, vt as installManifestNativeDeps, w as ipcChildLink, x as brokerCallForCap, xt as createAddonDataPlaneFacility, y as __resetCapUsageRegistryForTests, yt as runNpm, z as AGENT_CAP_FWD_ACTION } from "./manifest-python-deps-DtCMZhuR.mjs";
|
|
4
4
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Le3l0qS2.mjs";
|
|
5
5
|
import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
|
|
6
6
|
import { SqliteSettingsAddon, t as SqliteSettingsBackend } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
|
|
@@ -2300,9 +2300,15 @@ var AddonLoader = class {
|
|
|
2300
2300
|
else i++;
|
|
2301
2301
|
}
|
|
2302
2302
|
/** Scan addons directory and load all addon packages.
|
|
2303
|
-
* Supports scoped layout: addons/@scope/package-name/
|
|
2304
|
-
|
|
2303
|
+
* Supports scoped layout: addons/@scope/package-name/
|
|
2304
|
+
*
|
|
2305
|
+
* `skipPackages` names scoped packages (e.g. `@camstack/system`) that the
|
|
2306
|
+
* caller loads from elsewhere — the single-copy model loads the framework
|
|
2307
|
+
* BUILTINS from the active closure, not the (now-inert) addons-dir copy, so
|
|
2308
|
+
* the addons-dir `@camstack/system` must NOT be double-loaded here. */
|
|
2309
|
+
async loadFromDirectory(addonsDir, skipPackages = []) {
|
|
2305
2310
|
if (!fs$17.existsSync(addonsDir)) return;
|
|
2311
|
+
const skip = new Set(skipPackages);
|
|
2306
2312
|
const entries = fs$17.readdirSync(addonsDir, { withFileTypes: true });
|
|
2307
2313
|
for (const entry of entries) {
|
|
2308
2314
|
if (!isDirectoryEntry(entry, addonsDir)) continue;
|
|
@@ -2311,10 +2317,12 @@ var AddonLoader = class {
|
|
|
2311
2317
|
const scopeEntries = fs$17.readdirSync(scopeDir, { withFileTypes: true });
|
|
2312
2318
|
for (const scopeEntry of scopeEntries) {
|
|
2313
2319
|
if (!isDirectoryEntry(scopeEntry, scopeDir)) continue;
|
|
2320
|
+
if (skip.has(`${entry.name}/${scopeEntry.name}`)) continue;
|
|
2314
2321
|
await this.tryLoadAddon(path$39.join(scopeDir, scopeEntry.name));
|
|
2315
2322
|
}
|
|
2316
2323
|
continue;
|
|
2317
2324
|
}
|
|
2325
|
+
if (skip.has(entry.name)) continue;
|
|
2318
2326
|
await this.tryLoadAddon(path$39.join(addonsDir, entry.name));
|
|
2319
2327
|
}
|
|
2320
2328
|
}
|
|
@@ -93063,7 +93071,7 @@ var JobJournal = class {
|
|
|
93063
93071
|
};
|
|
93064
93072
|
//#endregion
|
|
93065
93073
|
//#region src/kernel/lifecycle/staging-area.ts
|
|
93066
|
-
function safeSegment
|
|
93074
|
+
function safeSegment(name) {
|
|
93067
93075
|
return name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
93068
93076
|
}
|
|
93069
93077
|
var StagingArea = class {
|
|
@@ -93074,7 +93082,7 @@ var StagingArea = class {
|
|
|
93074
93082
|
this.deps = deps;
|
|
93075
93083
|
}
|
|
93076
93084
|
async fetchAndStage(input) {
|
|
93077
|
-
const destDir = path$39.join(this.stagingDir, input.jobId, safeSegment
|
|
93085
|
+
const destDir = path$39.join(this.stagingDir, input.jobId, safeSegment(input.name));
|
|
93078
93086
|
fs$17.rmSync(destDir, {
|
|
93079
93087
|
recursive: true,
|
|
93080
93088
|
force: true
|
|
@@ -93210,50 +93218,22 @@ var LifecycleJobEngine = class {
|
|
|
93210
93218
|
}
|
|
93211
93219
|
}
|
|
93212
93220
|
/**
|
|
93213
|
-
*
|
|
93214
|
-
*
|
|
93215
|
-
*
|
|
93216
|
-
*
|
|
93217
|
-
*
|
|
93218
|
-
|
|
93219
|
-
|
|
93220
|
-
|
|
93221
|
-
|
|
93222
|
-
|
|
93223
|
-
|
|
93224
|
-
|
|
93225
|
-
|
|
93226
|
-
|
|
93227
|
-
|
|
93228
|
-
|
|
93229
|
-
this.advance(job.jobId, task, "fetching", {
|
|
93230
|
-
startedAtMs: this.deps.now(),
|
|
93231
|
-
attempts: task.attempts + 1
|
|
93232
|
-
});
|
|
93233
|
-
const ac = new AbortController();
|
|
93234
|
-
const timer = setTimeout(() => ac.abort(), this.deps.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS);
|
|
93235
|
-
let packages;
|
|
93236
|
-
try {
|
|
93237
|
-
packages = await stageFramework(task, ac.signal);
|
|
93238
|
-
} finally {
|
|
93239
|
-
clearTimeout(timer);
|
|
93240
|
-
}
|
|
93241
|
-
const [firstPackage] = packages;
|
|
93242
|
-
if (!firstPackage) throw new Error("stageFramework returned no packages");
|
|
93243
|
-
this.advance(job.jobId, task, "staged", { stagedPath: firstPackage.stagedPath });
|
|
93244
|
-
requestFrameworkSwap({
|
|
93245
|
-
jobId: job.jobId,
|
|
93246
|
-
taskId: task.taskId,
|
|
93247
|
-
packages
|
|
93248
|
-
});
|
|
93249
|
-
return this.deps.journal.getJob(job.jobId) ?? job;
|
|
93250
|
-
} catch (err) {
|
|
93251
|
-
this.advance(job.jobId, task, "failed", {
|
|
93252
|
-
error: err instanceof Error ? err.message : String(err),
|
|
93253
|
-
finishedAtMs: this.deps.now()
|
|
93254
|
-
});
|
|
93255
|
-
return null;
|
|
93256
|
-
}
|
|
93221
|
+
* Mark a framework task `skipped`.
|
|
93222
|
+
*
|
|
93223
|
+
* Framework packages (`@camstack/system` + its lockstep companions) are NO
|
|
93224
|
+
* LONGER updated through this engine. The legacy `/data/framework` per-package
|
|
93225
|
+
* swap was removed in the single-copy framework collapse (2026-07-18) — the
|
|
93226
|
+
* running framework is loaded from the active server-root single copy, and
|
|
93227
|
+
* framework/cap updates now ship EXCLUSIVELY via `applyServerUpdate` (the
|
|
93228
|
+
* node-root ServerUpdateService). Any framework task that still reaches this
|
|
93229
|
+
* engine (e.g. an "Update all" bulk job that swept `@camstack/system`) is
|
|
93230
|
+
* skipped, never applied — applying it would swap a dead dir.
|
|
93231
|
+
*/
|
|
93232
|
+
skipFrameworkTask(job, task) {
|
|
93233
|
+
this.advance(job.jobId, task, "skipped", {
|
|
93234
|
+
startedAtMs: task.startedAtMs ?? this.deps.now(),
|
|
93235
|
+
finishedAtMs: this.deps.now()
|
|
93236
|
+
});
|
|
93257
93237
|
}
|
|
93258
93238
|
/**
|
|
93259
93239
|
* Run the addon fetch phase with a bounded-concurrency worker pool. At most
|
|
@@ -93281,24 +93261,24 @@ var LifecycleJobEngine = class {
|
|
|
93281
93261
|
* §10 boot reconcile: re-drive every NON-TERMINAL addon task of a job that
|
|
93282
93262
|
* was interrupted mid-flight (e.g. a crash) from its on-disk checkpoint.
|
|
93283
93263
|
*
|
|
93284
|
-
* Framework tasks are
|
|
93285
|
-
*
|
|
93286
|
-
*
|
|
93264
|
+
* Framework tasks are NOT applied by this engine (single-copy collapse —
|
|
93265
|
+
* framework updates ship via `applyServerUpdate`). Any stray non-terminal
|
|
93266
|
+
* framework task is marked `skipped` so the interrupted job can finalize
|
|
93267
|
+
* instead of hanging `running` forever. Terminal addon tasks
|
|
93268
|
+
* (`done`/`failed`/`skipped`) are left as-is.
|
|
93287
93269
|
*
|
|
93288
93270
|
* Apply is idempotent (`applyAddonUpdate` backs up the live dir + restores on
|
|
93289
93271
|
* failure), so every non-terminal addon phase collapses to:
|
|
93290
93272
|
* ensure staged (reuse a still-valid `stagedPath` or re-fetch) → apply → done;
|
|
93291
93273
|
* on failure → `failed`.
|
|
93292
|
-
*
|
|
93293
|
-
* The job is finalized (`completed`/`partially-failed`/`failed` + staging
|
|
93294
|
-
* cleanup) ONLY when ALL tasks — including any framework task — are terminal.
|
|
93295
|
-
* If a framework task is still non-terminal the job is LEFT `running` (the
|
|
93296
|
-
* reboot/F2 path finalizes it).
|
|
93297
93274
|
*/
|
|
93298
93275
|
async reconcileJob(job) {
|
|
93299
93276
|
const exists = this.deps.stagedPathExists ?? ((p) => fs$17.existsSync(p));
|
|
93300
93277
|
for (const task of job.tasks) {
|
|
93301
|
-
if (task.target === "framework")
|
|
93278
|
+
if (task.target === "framework") {
|
|
93279
|
+
if (!this.isTerminal(task.phase)) this.skipFrameworkTask(job, task);
|
|
93280
|
+
continue;
|
|
93281
|
+
}
|
|
93302
93282
|
if (this.isTerminal(task.phase)) continue;
|
|
93303
93283
|
await this.reconcileAddonTask(job, task, exists);
|
|
93304
93284
|
}
|
|
@@ -93320,9 +93300,10 @@ var LifecycleJobEngine = class {
|
|
|
93320
93300
|
}
|
|
93321
93301
|
/**
|
|
93322
93302
|
* Finalize a reconciled job: `completed` if all addon tasks succeeded,
|
|
93323
|
-
* `failed` if all failed, `partially-failed` if mixed
|
|
93324
|
-
* task
|
|
93325
|
-
* (
|
|
93303
|
+
* `failed` if all failed, `partially-failed` if mixed. A skipped framework
|
|
93304
|
+
* task counts as neither success nor failure. Defensive: if a task is still
|
|
93305
|
+
* non-terminal (should not happen — reconcile drives every task terminal),
|
|
93306
|
+
* leave the job `running` and do not clean staging.
|
|
93326
93307
|
*/
|
|
93327
93308
|
finalizeReconciledJob(jobId) {
|
|
93328
93309
|
const current = this.deps.journal.getJob(jobId);
|
|
@@ -93338,6 +93319,7 @@ var LifecycleJobEngine = class {
|
|
|
93338
93319
|
async runJob(job) {
|
|
93339
93320
|
const addonTasks = job.tasks.filter((t) => t.target !== "framework");
|
|
93340
93321
|
const frameworkTasks = job.tasks.filter((t) => t.target === "framework");
|
|
93322
|
+
for (const task of frameworkTasks) this.skipFrameworkTask(job, task);
|
|
93341
93323
|
let failures = 0;
|
|
93342
93324
|
let successes = 0;
|
|
93343
93325
|
const fetchOutcomes = await this.fetchAddonsBounded(job, addonTasks);
|
|
@@ -93347,11 +93329,6 @@ var LifecycleJobEngine = class {
|
|
|
93347
93329
|
if (await this.applyAddonTask(job, outcome.task, outcome.stagedPath)) successes += 1;
|
|
93348
93330
|
else failures += 1;
|
|
93349
93331
|
}
|
|
93350
|
-
for (const task of frameworkTasks) {
|
|
93351
|
-
const result = await this.runFrameworkTask(job, task);
|
|
93352
|
-
if (result !== null) return result;
|
|
93353
|
-
failures += 1;
|
|
93354
|
-
}
|
|
93355
93332
|
const state = failures === 0 ? "completed" : successes === 0 ? "failed" : "partially-failed";
|
|
93356
93333
|
const finalJob = this.deps.journal.setJobState(job.jobId, state);
|
|
93357
93334
|
this.deps.staging.cleanup(job.jobId);
|
|
@@ -93359,42 +93336,4 @@ var LifecycleJobEngine = class {
|
|
|
93359
93336
|
}
|
|
93360
93337
|
};
|
|
93361
93338
|
//#endregion
|
|
93362
|
-
|
|
93363
|
-
var FRAMEWORK_LOCKSTEP = [
|
|
93364
|
-
"@camstack/system",
|
|
93365
|
-
"@camstack/types",
|
|
93366
|
-
"@camstack/sdk",
|
|
93367
|
-
"@camstack/shm-ring"
|
|
93368
|
-
];
|
|
93369
|
-
function safeSegment(name) {
|
|
93370
|
-
return name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
93371
|
-
}
|
|
93372
|
-
async function stageFrameworkLockstep(input) {
|
|
93373
|
-
const stagingArea = new StagingArea(input.stagingDir, {
|
|
93374
|
-
fetchTarball: input.fetchTarball,
|
|
93375
|
-
extract: input.extract
|
|
93376
|
-
});
|
|
93377
|
-
const results = [];
|
|
93378
|
-
const primary = FRAMEWORK_LOCKSTEP[0];
|
|
93379
|
-
for (const pkg of FRAMEWORK_LOCKSTEP) {
|
|
93380
|
-
const version = pkg === primary ? input.toVersion : await input.resolveVersion(pkg);
|
|
93381
|
-
const { stagedPath } = await stagingArea.fetchAndStage({
|
|
93382
|
-
jobId: input.jobId,
|
|
93383
|
-
name: pkg,
|
|
93384
|
-
version,
|
|
93385
|
-
signal: input.signal
|
|
93386
|
-
});
|
|
93387
|
-
const backupPath = path$39.join(input.stagingDir, input.jobId, ".bak-fw", safeSegment(pkg));
|
|
93388
|
-
const fromVersion = input.currentVersionOf(pkg);
|
|
93389
|
-
results.push({
|
|
93390
|
-
name: pkg,
|
|
93391
|
-
stagedPath,
|
|
93392
|
-
backupPath,
|
|
93393
|
-
toVersion: version,
|
|
93394
|
-
fromVersion
|
|
93395
|
-
});
|
|
93396
|
-
}
|
|
93397
|
-
return results;
|
|
93398
|
-
}
|
|
93399
|
-
//#endregion
|
|
93400
|
-
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CustomActionRegistry, DEFAULT_DATA_PATH, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FRAMEWORK_LOCKSTEP, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LifecycleJobEngine, LifecycleStateMachine, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, RESTART_MARKER_FILE, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, __resetCapUsageRegistryForTests, adaptBrokerToCluster, addonSettingsCapability, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, capActionName, capActionSuffix, capBareAction, capServiceName, classifyCapRoute, clearPendingRestart, clusterSecretMatches, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensurePython, ensureTlsCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, proxyToUpstream, readPendingRestart, readinessKey, registerEventBusService, resolveFilePath, resolveHwAccel, scheduleSelfRestart, scopeKey, scopesAllowDeviceCap, serializeTypedArrays, setHubConnected, setNodeEventInterest, stageFrameworkLockstep, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, writePendingRestart };
|
|
93339
|
+
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CustomActionRegistry, DEFAULT_DATA_PATH, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LifecycleJobEngine, LifecycleStateMachine, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, RESTART_MARKER_FILE, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, __resetCapUsageRegistryForTests, adaptBrokerToCluster, addonSettingsCapability, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, capActionName, capActionSuffix, capBareAction, capServiceName, classifyCapRoute, clearPendingRestart, clusterSecretMatches, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensurePython, ensureTlsCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, proxyToUpstream, readPendingRestart, readinessKey, registerEventBusService, resolveFilePath, resolveHwAccel, scheduleSelfRestart, scopeKey, scopesAllowDeviceCap, serializeTypedArrays, setHubConnected, setNodeEventInterest, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, writePendingRestart };
|
|
@@ -72,8 +72,13 @@ export declare class AddonLoader {
|
|
|
72
72
|
/** Forget any tracked failures for a given package — uninstall path. */
|
|
73
73
|
clearLoadFailures(packageName: string): void;
|
|
74
74
|
/** Scan addons directory and load all addon packages.
|
|
75
|
-
* Supports scoped layout: addons/@scope/package-name/
|
|
76
|
-
|
|
75
|
+
* Supports scoped layout: addons/@scope/package-name/
|
|
76
|
+
*
|
|
77
|
+
* `skipPackages` names scoped packages (e.g. `@camstack/system`) that the
|
|
78
|
+
* caller loads from elsewhere — the single-copy model loads the framework
|
|
79
|
+
* BUILTINS from the active closure, not the (now-inert) addons-dir copy, so
|
|
80
|
+
* the addons-dir `@camstack/system` must NOT be double-loaded here. */
|
|
81
|
+
loadFromDirectory(addonsDir: string, skipPackages?: readonly string[]): Promise<void>;
|
|
77
82
|
private tryLoadAddon;
|
|
78
83
|
/** Load addon from a specific directory (package.json + dist/) */
|
|
79
84
|
loadFromAddonDir(addonDir: string): Promise<void>;
|
package/dist/kernel/index.d.ts
CHANGED
|
@@ -77,7 +77,5 @@ export type { ReadinessHandler, ReadinessTransition, AwaitReadyOptions, Readines
|
|
|
77
77
|
export { JobJournal } from './lifecycle/job-journal.js';
|
|
78
78
|
export { StagingArea } from './lifecycle/staging-area.js';
|
|
79
79
|
export { LifecycleJobEngine } from './lifecycle/lifecycle-job-engine.js';
|
|
80
|
-
export type { ApplyAddonUpdateFn, EmitFn
|
|
80
|
+
export type { ApplyAddonUpdateFn, EmitFn } from './lifecycle/lifecycle-job-engine.js';
|
|
81
81
|
export type { TarballFetcher, ExtractFn } from './lifecycle/staging-area.js';
|
|
82
|
-
export { stageFrameworkLockstep, FRAMEWORK_LOCKSTEP } from './lifecycle/framework-staging.js';
|
|
83
|
-
export type { StageFrameworkInput } from './lifecycle/framework-staging.js';
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { JobJournal } from './job-journal.js';
|
|
2
2
|
import { StagingArea } from './staging-area.js';
|
|
3
|
-
import { LifecycleJob,
|
|
3
|
+
import { LifecycleJob, TaskLogEntry } from '@camstack/types';
|
|
4
4
|
export type ApplyAddonUpdateFn = (input: {
|
|
5
5
|
name: string;
|
|
6
6
|
version: string;
|
|
7
7
|
stagedPath: string;
|
|
8
8
|
}) => Promise<void>;
|
|
9
9
|
export type EmitFn = (kind: 'progress' | 'log', job: LifecycleJob, entry?: TaskLogEntry) => void;
|
|
10
|
-
export type StageFrameworkFn = (task: LifecycleTask, signal: AbortSignal) => Promise<FrameworkSwapPackage[]>;
|
|
11
|
-
export type RequestFrameworkSwapFn = (input: {
|
|
12
|
-
jobId: string;
|
|
13
|
-
taskId: string;
|
|
14
|
-
packages: FrameworkSwapPackage[];
|
|
15
|
-
}) => void;
|
|
16
10
|
interface Deps {
|
|
17
11
|
readonly journal: JobJournal;
|
|
18
12
|
readonly staging: StagingArea;
|
|
@@ -21,8 +15,6 @@ interface Deps {
|
|
|
21
15
|
readonly now: () => number;
|
|
22
16
|
readonly fetchTimeoutMs?: number;
|
|
23
17
|
readonly fetchConcurrency?: number;
|
|
24
|
-
readonly stageFramework?: StageFrameworkFn;
|
|
25
|
-
readonly requestFrameworkSwap?: RequestFrameworkSwapFn;
|
|
26
18
|
/**
|
|
27
19
|
* Predicate used by `reconcileJob` to decide whether a task's recorded
|
|
28
20
|
* `stagedPath` directory still exists on disk (so apply can reuse it instead
|
|
@@ -48,13 +40,18 @@ export declare class LifecycleJobEngine {
|
|
|
48
40
|
*/
|
|
49
41
|
private applyAddonTask;
|
|
50
42
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
43
|
+
* Mark a framework task `skipped`.
|
|
44
|
+
*
|
|
45
|
+
* Framework packages (`@camstack/system` + its lockstep companions) are NO
|
|
46
|
+
* LONGER updated through this engine. The legacy `/data/framework` per-package
|
|
47
|
+
* swap was removed in the single-copy framework collapse (2026-07-18) — the
|
|
48
|
+
* running framework is loaded from the active server-root single copy, and
|
|
49
|
+
* framework/cap updates now ship EXCLUSIVELY via `applyServerUpdate` (the
|
|
50
|
+
* node-root ServerUpdateService). Any framework task that still reaches this
|
|
51
|
+
* engine (e.g. an "Update all" bulk job that swept `@camstack/system`) is
|
|
52
|
+
* skipped, never applied — applying it would swap a dead dir.
|
|
56
53
|
*/
|
|
57
|
-
private
|
|
54
|
+
private skipFrameworkTask;
|
|
58
55
|
/**
|
|
59
56
|
* Run the addon fetch phase with a bounded-concurrency worker pool. At most
|
|
60
57
|
* `fetchConcurrency` fetches are in flight at once; completion order may vary
|
|
@@ -65,19 +62,16 @@ export declare class LifecycleJobEngine {
|
|
|
65
62
|
* §10 boot reconcile: re-drive every NON-TERMINAL addon task of a job that
|
|
66
63
|
* was interrupted mid-flight (e.g. a crash) from its on-disk checkpoint.
|
|
67
64
|
*
|
|
68
|
-
* Framework tasks are
|
|
69
|
-
*
|
|
70
|
-
*
|
|
65
|
+
* Framework tasks are NOT applied by this engine (single-copy collapse —
|
|
66
|
+
* framework updates ship via `applyServerUpdate`). Any stray non-terminal
|
|
67
|
+
* framework task is marked `skipped` so the interrupted job can finalize
|
|
68
|
+
* instead of hanging `running` forever. Terminal addon tasks
|
|
69
|
+
* (`done`/`failed`/`skipped`) are left as-is.
|
|
71
70
|
*
|
|
72
71
|
* Apply is idempotent (`applyAddonUpdate` backs up the live dir + restores on
|
|
73
72
|
* failure), so every non-terminal addon phase collapses to:
|
|
74
73
|
* ensure staged (reuse a still-valid `stagedPath` or re-fetch) → apply → done;
|
|
75
74
|
* on failure → `failed`.
|
|
76
|
-
*
|
|
77
|
-
* The job is finalized (`completed`/`partially-failed`/`failed` + staging
|
|
78
|
-
* cleanup) ONLY when ALL tasks — including any framework task — are terminal.
|
|
79
|
-
* If a framework task is still non-terminal the job is LEFT `running` (the
|
|
80
|
-
* reboot/F2 path finalizes it).
|
|
81
75
|
*/
|
|
82
76
|
reconcileJob(job: LifecycleJob): Promise<LifecycleJob>;
|
|
83
77
|
private isTerminal;
|
|
@@ -88,9 +82,10 @@ export declare class LifecycleJobEngine {
|
|
|
88
82
|
private reconcileAddonTask;
|
|
89
83
|
/**
|
|
90
84
|
* Finalize a reconciled job: `completed` if all addon tasks succeeded,
|
|
91
|
-
* `failed` if all failed, `partially-failed` if mixed
|
|
92
|
-
* task
|
|
93
|
-
* (
|
|
85
|
+
* `failed` if all failed, `partially-failed` if mixed. A skipped framework
|
|
86
|
+
* task counts as neither success nor failure. Defensive: if a task is still
|
|
87
|
+
* non-terminal (should not happen — reconcile drives every task terminal),
|
|
88
|
+
* leave the job `running` and do not clean staging.
|
|
94
89
|
*/
|
|
95
90
|
private finalizeReconciledJob;
|
|
96
91
|
runJob(job: LifecycleJob): Promise<LifecycleJob>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-BY6NWf-c.js");
|
|
3
3
|
let _camstack_types_node = require("@camstack/types/node");
|
|
4
4
|
let node_http = require("node:http");
|
|
5
5
|
let node_fs = require("node:fs");
|