@camstack/system 1.2.471 → 1.2.473
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 +202 -8
- package/dist/addon-runner.mjs +203 -9
- package/dist/addon-utils.mjs +1 -1
- package/dist/{agent-https-bH6bKDeK.js → agent-https-B9Q3-IKd.js} +2 -5
- package/dist/{agent-https-DHBvFZJS.mjs → agent-https-DOwn4pqL.mjs} +3 -6
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +4 -4
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +5 -5
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +5 -5
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-history/device-history.addon.js +1 -1
- package/dist/builtins/device-history/device-history.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +9 -25
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +240 -39
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +237 -38
- package/dist/builtins/liveness-monitor/liveness-reporter.d.ts +28 -0
- package/dist/builtins/liveness-monitor/storage-root-access.d.ts +53 -0
- package/dist/builtins/local-auth/local-auth.addon.js +16 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +19 -5
- package/dist/builtins/local-auth/person-scopes.d.ts +7 -0
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +10 -10
- package/dist/builtins/platform-probe/accelerator-facts-probe.d.ts +24 -0
- package/dist/builtins/platform-probe/index.js +110 -10
- package/dist/builtins/platform-probe/index.mjs +116 -17
- package/dist/builtins/platform-probe/platform-scorer.d.ts +10 -2
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/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 +20 -20
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
- 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 +3 -3
- package/dist/builtins/system-config/system-config.addon.mjs +115 -115
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-B5uJZXZ1.js → composition-sources-Dj_nInUQ.js} +1 -1
- package/dist/{composition-sources-DRw_vBKH.mjs → composition-sources-cwD35HB0.mjs} +1 -1
- package/dist/{constants-CToE4OFp.js → constants-XkWSVvgY.js} +1 -1
- package/dist/{constants-5lA8Z9d8.mjs → constants-p5mPM1iL.mjs} +1 -1
- package/dist/{coral-accelerators-BW3OcrLD.mjs → coral-accelerators-DBlgWB8k.mjs} +6 -6
- package/dist/{custom-action-registry-BGYDjTqY.mjs → custom-action-registry-DZSCLBuT.mjs} +37 -37
- package/dist/{device-ca-nOCYVFS4.js → device-ca-BXzQ1pYj.js} +1 -1
- package/dist/{device-ca-URrs1lxK.mjs → device-ca-DyUtcpf4.mjs} +1 -1
- package/dist/{dist-BjcWEfRy.js → dist-Bmah6waF.js} +209 -266
- package/dist/{dist-5XUG7iYJ.mjs → dist-C9lbdBL5.mjs} +204 -267
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-zD3JojB_.mjs → hub-mdns-ciao-BemeCNGe.mjs} +2 -2
- package/dist/{hub-mdns-ciao-vEWhJ_SD.js → hub-mdns-ciao-CUr6ewsX.js} +2 -2
- package/dist/index.js +236 -16
- package/dist/index.mjs +455 -235
- package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +24 -4
- package/dist/kernel/hwaccel/vaapi-init-probe.d.ts +29 -0
- package/dist/kernel/moleculer/runner-process-group.d.ts +4 -0
- package/dist/{restore-archive-CN1pJTRn.mjs → restore-archive-C0aohmAK.mjs} +94 -94
- package/dist/{restore-archive-B64m2nAj.js → restore-archive-DbPmyjiM.js} +1 -1
- package/dist/{retired-settings-keys-C_Kjp-Bj.mjs → retired-settings-keys-CWp7ZSeA.mjs} +8 -0
- package/dist/{retired-settings-keys-CGUqX-Oz.js → retired-settings-keys-DorakcxV.js} +8 -0
- package/dist/{wal-maintenance-BNXVX-ot.js → wal-maintenance-BT8Ns0W3.js} +0 -0
- package/dist/{wal-maintenance-Bl2I-ZcR.mjs → wal-maintenance-BuB731DK.mjs} +0 -0
- package/package.json +6 -6
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type StorageLocation } from "@camstack/types";
|
|
2
|
+
import type { LivenessFinding } from "./liveness-checks.js";
|
|
3
|
+
/** Owner and permission bits of a directory, as `stat` reports them. */
|
|
4
|
+
export interface DirStat {
|
|
5
|
+
readonly uid: number;
|
|
6
|
+
readonly gid: number;
|
|
7
|
+
readonly mode: number;
|
|
8
|
+
}
|
|
9
|
+
/** The two filesystem reads the check makes; injected so a test can run without root. */
|
|
10
|
+
export interface StorageRootProbe {
|
|
11
|
+
/** Resolves when the CURRENT process may write (and traverse) `dir`; rejects otherwise. */
|
|
12
|
+
readonly canWrite: (dir: string) => Promise<void>;
|
|
13
|
+
readonly stat: (dir: string) => Promise<DirStat>;
|
|
14
|
+
/** The process uid/gid, or `null` where the platform has none (Windows). */
|
|
15
|
+
readonly processUid: number | null;
|
|
16
|
+
readonly processGid: number | null;
|
|
17
|
+
}
|
|
18
|
+
/** One root this node must be able to write, and every location that writes under it. */
|
|
19
|
+
export interface StorageRootTarget {
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly locationIds: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
export type StorageRootAccess = {
|
|
24
|
+
readonly kind: "writable";
|
|
25
|
+
readonly target: StorageRootTarget;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "unwritable";
|
|
28
|
+
readonly target: StorageRootTarget;
|
|
29
|
+
/** The directory that refused: the root itself, or its nearest existing ancestor. */
|
|
30
|
+
readonly blockedAt: string;
|
|
31
|
+
readonly stat: DirStat;
|
|
32
|
+
readonly reason: string;
|
|
33
|
+
} | {
|
|
34
|
+
readonly kind: "unknown";
|
|
35
|
+
readonly target: StorageRootTarget;
|
|
36
|
+
readonly reason: string;
|
|
37
|
+
};
|
|
38
|
+
/** The hub-local, writable filesystem roots among `locations`, deduplicated by path. */
|
|
39
|
+
export declare function storageRootTargets(locations: readonly StorageLocation[], localNodeId: string): readonly StorageRootTarget[];
|
|
40
|
+
/** Probe one root: the root itself, or the nearest ancestor that exists. */
|
|
41
|
+
export declare function probeStorageRoot(target: StorageRootTarget, probe: StorageRootProbe): Promise<StorageRootAccess>;
|
|
42
|
+
/**
|
|
43
|
+
* One finding per DIRECTORY that refused — several roots under one unwritable
|
|
44
|
+
* mount (`/recordings` holding recordings, event media and artifacts) are one
|
|
45
|
+
* cause and one alert. Stable id = that directory.
|
|
46
|
+
*/
|
|
47
|
+
export declare function storageRootFindings(results: readonly StorageRootAccess[], probe: StorageRootProbe): readonly LivenessFinding[];
|
|
48
|
+
export declare function isStorageRootFindingId(id: string): boolean;
|
|
49
|
+
/** The real probe: `fs.access(W_OK | X_OK)` as THIS process, and `fs.stat`. */
|
|
50
|
+
export declare function nodeStorageRootProbe(fs: {
|
|
51
|
+
readonly access: (p: string, mode: number) => Promise<void>;
|
|
52
|
+
readonly stat: (p: string) => Promise<DirStat>;
|
|
53
|
+
}): StorageRootProbe;
|
|
@@ -3,10 +3,10 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bmah6waF.js");
|
|
7
7
|
const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
|
|
8
8
|
const require_ms$1 = require("../../ms-LB3giGoU.js");
|
|
9
|
-
const require_device_ca = require("../../device-ca-
|
|
9
|
+
const require_device_ca = require("../../device-ca-BXzQ1pYj.js");
|
|
10
10
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
11
11
|
let zod = require("zod");
|
|
12
12
|
let node_crypto = require("node:crypto");
|
|
@@ -8821,6 +8821,19 @@ var UserManager = class {
|
|
|
8821
8821
|
return this.auth.comparePassword(password, user.passwordHash);
|
|
8822
8822
|
}
|
|
8823
8823
|
};
|
|
8824
|
+
//#endregion
|
|
8825
|
+
//#region src/builtins/local-auth/person-scopes.ts
|
|
8826
|
+
/**
|
|
8827
|
+
* What `userManagement.setUserScopes` may store for a person (D921, amended
|
|
8828
|
+
* 2026-10-24): nothing (an admin) or exactly one viewer row. Any other row
|
|
8829
|
+
* is refused. There is no conversion of an older grant set (D900).
|
|
8830
|
+
*/
|
|
8831
|
+
function assertPersonScopes(scopes) {
|
|
8832
|
+
if (scopes.length === 0) return;
|
|
8833
|
+
const only = scopes[0];
|
|
8834
|
+
if (scopes.length === 1 && only !== void 0 && only.type === "viewer") return;
|
|
8835
|
+
throw require_dist.userError("auth.person-scopes-refused", void 0, "A person is an admin, with no scope rows, or holds exactly one viewer grant");
|
|
8836
|
+
}
|
|
8824
8837
|
var JwtSigningKeyKeeper = class {
|
|
8825
8838
|
deps;
|
|
8826
8839
|
retryTimer = null;
|
|
@@ -12179,6 +12192,7 @@ var LocalAuthAddon = class extends require_dist.BaseAddon {
|
|
|
12179
12192
|
},
|
|
12180
12193
|
setUserScopes: async (input) => {
|
|
12181
12194
|
if (!this.userManager) throw new Error("User management not available");
|
|
12195
|
+
assertPersonScopes(input.scopes);
|
|
12182
12196
|
await this.userManager.update(input.userId, { scopes: input.scopes });
|
|
12183
12197
|
return { success: true };
|
|
12184
12198
|
},
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { $ as PreferenceDeviceIdSchema, At as buildDeviceSignatureMessage, E as DEVICE_ENROLLMENT_TTL_MS,
|
|
2
|
+
import { $ as PreferenceDeviceIdSchema, At as buildDeviceSignatureMessage, E as DEVICE_ENROLLMENT_TTL_MS, Ea as userError, Mr as userManagementCapability, O as DEVICE_NONCE_TTL_MS, Q as PREFERENCES_MAX_VALUE_BYTES, Qt as deviceCredentialsCapability, et as PreferenceNamespaceSchema, gt as UserRecordSchema, h as CREDENTIAL_TOKEN_AUDIENCE, hn as formatDeviceRevoker, ia as isSecretMarker, kt as buildDeviceEnrollmentLink, lt as SsoBridgeClaimsSchema, mt as TokenScopeSchema, qi as defineRecordKinds, sa as makeSecretMarker, st as ScopedTokenSchema, ti as BaseAddon, tt as PreferenceValueSchema, wn as isCredentialTokenPayload, wt as authProviderCapability, y as CredentialTokenClaimsSchema } from "../../dist-C9lbdBL5.mjs";
|
|
3
3
|
import { t as require_safe_buffer } from "../../safe-buffer-B1OjL1I9.mjs";
|
|
4
4
|
import { t as require_ms } from "../../ms-CgH2OFlD.mjs";
|
|
5
|
-
import { _ as setProcessJwtSigningKey, a as importDevicePublicKey, c as rebuildDeviceCaCertificate, d as JWT_SIGNING_KEY_REF, g as processJwtSigningKey, h as loadJwtSigningKey, i as generateDeviceCa, l as verifyDeviceLeaf, m as getProcessJwtSigningKeyState, n as DEVICE_CA_KEY_REF, o as issueDeviceLeaf, r as DEVICE_CA_SETTINGS_SECTION, s as loadDeviceCa, t as DEVICE_CA_FIELD, u as verifyDeviceSignature } from "../../device-ca-
|
|
5
|
+
import { _ as setProcessJwtSigningKey, a as importDevicePublicKey, c as rebuildDeviceCaCertificate, d as JWT_SIGNING_KEY_REF, g as processJwtSigningKey, h as loadJwtSigningKey, i as generateDeviceCa, l as verifyDeviceLeaf, m as getProcessJwtSigningKeyState, n as DEVICE_CA_KEY_REF, o as issueDeviceLeaf, r as DEVICE_CA_SETTINGS_SECTION, s as loadDeviceCa, t as DEVICE_CA_FIELD, u as verifyDeviceSignature } from "../../device-ca-DyUtcpf4.mjs";
|
|
6
6
|
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import * as crypto$1 from "node:crypto";
|
|
9
9
|
import { X509Certificate, createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
10
10
|
import nodeCrypto from "crypto";
|
|
11
11
|
import * as path$1 from "node:path";
|
|
12
|
-
import * as fs from "node:fs";
|
|
12
|
+
import * as fs$1 from "node:fs";
|
|
13
13
|
//#region ../../node_modules/bcryptjs/index.js
|
|
14
14
|
/**
|
|
15
15
|
* The random implementation to use as a fallback.
|
|
@@ -8810,6 +8810,19 @@ var UserManager = class {
|
|
|
8810
8810
|
return this.auth.comparePassword(password, user.passwordHash);
|
|
8811
8811
|
}
|
|
8812
8812
|
};
|
|
8813
|
+
//#endregion
|
|
8814
|
+
//#region src/builtins/local-auth/person-scopes.ts
|
|
8815
|
+
/**
|
|
8816
|
+
* What `userManagement.setUserScopes` may store for a person (D921, amended
|
|
8817
|
+
* 2026-10-24): nothing (an admin) or exactly one viewer row. Any other row
|
|
8818
|
+
* is refused. There is no conversion of an older grant set (D900).
|
|
8819
|
+
*/
|
|
8820
|
+
function assertPersonScopes(scopes) {
|
|
8821
|
+
if (scopes.length === 0) return;
|
|
8822
|
+
const only = scopes[0];
|
|
8823
|
+
if (scopes.length === 1 && only !== void 0 && only.type === "viewer") return;
|
|
8824
|
+
throw userError("auth.person-scopes-refused", void 0, "A person is an admin, with no scope rows, or holds exactly one viewer grant");
|
|
8825
|
+
}
|
|
8813
8826
|
var JwtSigningKeyKeeper = class {
|
|
8814
8827
|
deps;
|
|
8815
8828
|
retryTimer = null;
|
|
@@ -12064,8 +12077,8 @@ var LocalAuthAddon = class extends BaseAddon {
|
|
|
12064
12077
|
users: this.userManager,
|
|
12065
12078
|
dataDir: this.ctx.nodeDataDir,
|
|
12066
12079
|
fs: {
|
|
12067
|
-
exists: (filePath) => fs.existsSync(filePath),
|
|
12068
|
-
remove: (filePath) => fs.rmSync(filePath, { force: true })
|
|
12080
|
+
exists: (filePath) => fs$1.existsSync(filePath),
|
|
12081
|
+
remove: (filePath) => fs$1.rmSync(filePath, { force: true })
|
|
12069
12082
|
},
|
|
12070
12083
|
logger: this.ctx.logger
|
|
12071
12084
|
});
|
|
@@ -12168,6 +12181,7 @@ var LocalAuthAddon = class extends BaseAddon {
|
|
|
12168
12181
|
},
|
|
12169
12182
|
setUserScopes: async (input) => {
|
|
12170
12183
|
if (!this.userManager) throw new Error("User management not available");
|
|
12184
|
+
assertPersonScopes(input.scopes);
|
|
12171
12185
|
await this.userManager.update(input.userId, { scopes: input.scopes });
|
|
12172
12186
|
return { success: true };
|
|
12173
12187
|
},
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `userManagement.setUserScopes` may store for a person (D921, amended
|
|
3
|
+
* 2026-10-24): nothing (an admin) or exactly one viewer row. Any other row
|
|
4
|
+
* is refused. There is no conversion of an older grant set (D900).
|
|
5
|
+
*/
|
|
6
|
+
import { type UserScope } from "@camstack/types";
|
|
7
|
+
export declare function assertPersonScopes(scopes: readonly UserScope[]): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
4
|
-
const require_hub_mdns_ciao = require("../../hub-mdns-ciao-
|
|
3
|
+
const require_dist = require("../../dist-Bmah6waF.js");
|
|
4
|
+
const require_hub_mdns_ciao = require("../../hub-mdns-ciao-CUr6ewsX.js");
|
|
5
5
|
let zod = require("zod");
|
|
6
6
|
let node_net = require("node:net");
|
|
7
7
|
let node_os = require("node:os");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { P as readLanHttpState, a as storeUploadedCertificate, d as servedHttpsLeafFingerprint, g as readTlsMode, h as readTlsAccessStatus, i as revertToGeneratedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, m as readExtraSans, n as applyCertificateToListener, o as useStoredUploadedCertificate, r as regenerateCertificate, t as createCiaoPublisher, v as writeExtraSans, w as ensureTlsCert } from "../../hub-mdns-ciao-
|
|
1
|
+
import { Fn as localNetworkCapability, Ft as checkRoleAddress, H as HUB_MDNS_TXT_KEYS, Oa as EventCategory, Pr as validateCustomAddress, Qn as pickAppLinkHub, Tn as isDefaultAppConnectionEndpoint, V as HUB_MDNS_SERVICE_TYPE, Z as NetworkTunnelStartedDataSchema, br as shortHostname, c as CAMSTACK_APP_LINK_ORIGIN, dr as resolveHubAddressRoles, ei as errMsg, mr as resolveNotificationTapAddress, sr as resolveAppConnections, ti as BaseAddon, xn as isAppLinkBase } from "../../dist-C9lbdBL5.mjs";
|
|
2
|
+
import { P as readLanHttpState, a as storeUploadedCertificate, d as servedHttpsLeafFingerprint, g as readTlsMode, h as readTlsAccessStatus, i as revertToGeneratedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, m as readExtraSans, n as applyCertificateToListener, o as useStoredUploadedCertificate, r as regenerateCertificate, t as createCiaoPublisher, v as writeExtraSans, w as ensureTlsCert } from "../../hub-mdns-ciao-BemeCNGe.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { isIP } from "node:net";
|
|
5
5
|
import * as os$1 from "node:os";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bmah6waF.js");
|
|
7
7
|
const require_log_read_filter = require("../../log-read-filter-Bi066jwU.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ln as logDestinationCapability,
|
|
1
|
+
import { Ln as logDestinationCapability, ti as BaseAddon } from "../../dist-C9lbdBL5.mjs";
|
|
2
2
|
import { n as compileLogFilter, o as lineMatches } from "../../log-read-filter-D7Ev3zm-.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bmah6waF.js");
|
|
7
7
|
let node_fs_promises = require("node:fs/promises");
|
|
8
8
|
let node_util = require("node:util");
|
|
9
9
|
let node_os = require("node:os");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Oa as EventCategory, Un as metricsProviderCapability, Wi as createEvent, ar as reducePoints, cr as resolveBucketMs, ei as errMsg, ht as UNATTRIBUTED_BUCKET_KEY, mn as foldSnapshotByFunction, rt as ROOT_BUCKET_KEY, ti as BaseAddon } from "../../dist-C9lbdBL5.mjs";
|
|
2
2
|
import { access, readFile, readdir } from "node:fs/promises";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import * as os$1 from "node:os";
|
|
5
5
|
import { platform } from "node:os";
|
|
6
|
-
import * as fs from "node:fs";
|
|
6
|
+
import * as fs$1 from "node:fs";
|
|
7
7
|
import { constants, readFileSync } from "node:fs";
|
|
8
8
|
import { execFile, execFileSync } from "node:child_process";
|
|
9
9
|
//#region src/builtins/native-metrics/cgroup-memory.ts
|
|
@@ -1642,7 +1642,7 @@ var NativeMetricsProvider = class {
|
|
|
1642
1642
|
let swapUsedBytes = 0;
|
|
1643
1643
|
let swapTotalBytes = 0;
|
|
1644
1644
|
if (IS_LINUX) try {
|
|
1645
|
-
const meminfo = fs.readFileSync("/proc/meminfo", "utf-8");
|
|
1645
|
+
const meminfo = fs$1.readFileSync("/proc/meminfo", "utf-8");
|
|
1646
1646
|
const swapTotal = parseInt(meminfo.match(/SwapTotal:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
|
|
1647
1647
|
const swapFree = parseInt(meminfo.match(/SwapFree:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
|
|
1648
1648
|
swapTotalBytes = swapTotal;
|
|
@@ -1720,7 +1720,7 @@ function sampleMacMemory(provider) {
|
|
|
1720
1720
|
}
|
|
1721
1721
|
function getDiskSpaceInternal(dirPath) {
|
|
1722
1722
|
return new Promise((resolve, reject) => {
|
|
1723
|
-
fs.statfs(dirPath, (err, stats) => {
|
|
1723
|
+
fs$1.statfs(dirPath, (err, stats) => {
|
|
1724
1724
|
if (err) return reject(err);
|
|
1725
1725
|
const totalBytes = stats.blocks * stats.bsize;
|
|
1726
1726
|
const availableBytes = stats.bavail * stats.bsize;
|
|
@@ -1738,7 +1738,7 @@ function getDiskSpaceInternal(dirPath) {
|
|
|
1738
1738
|
async function takeDiskIoSnapshot() {
|
|
1739
1739
|
const now = Date.now();
|
|
1740
1740
|
if (IS_LINUX) try {
|
|
1741
|
-
const data = fs.readFileSync("/proc/diskstats", "utf-8");
|
|
1741
|
+
const data = fs$1.readFileSync("/proc/diskstats", "utf-8");
|
|
1742
1742
|
let readOps = 0, readBytes = 0, writeOps = 0, writeBytes = 0;
|
|
1743
1743
|
for (const line of data.split("\n")) {
|
|
1744
1744
|
const parts = line.trim().split(/\s+/);
|
|
@@ -1769,7 +1769,7 @@ async function takeDiskIoSnapshot() {
|
|
|
1769
1769
|
async function takeNetworkIoSnapshot() {
|
|
1770
1770
|
const now = Date.now();
|
|
1771
1771
|
if (IS_LINUX) try {
|
|
1772
|
-
const data = fs.readFileSync("/proc/net/dev", "utf-8");
|
|
1772
|
+
const data = fs$1.readFileSync("/proc/net/dev", "utf-8");
|
|
1773
1773
|
let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
|
|
1774
1774
|
for (const line of data.split("\n")) {
|
|
1775
1775
|
const match = line.match(/^\s*(\w+):\s+(.+)$/);
|
|
@@ -1830,7 +1830,7 @@ async function takeNetworkIoSnapshot() {
|
|
|
1830
1830
|
}
|
|
1831
1831
|
async function getCpuTemperatureInternal() {
|
|
1832
1832
|
if (IS_LINUX) for (const p of ["/sys/class/thermal/thermal_zone0/temp", "/sys/class/hwmon/hwmon0/temp1_input"]) try {
|
|
1833
|
-
const raw = fs.readFileSync(p, "utf-8").trim();
|
|
1833
|
+
const raw = fs$1.readFileSync(p, "utf-8").trim();
|
|
1834
1834
|
const millideg = parseInt(raw, 10);
|
|
1835
1835
|
if (!isNaN(millideg)) return Math.round(millideg / 100) / 10;
|
|
1836
1836
|
} catch {
|
|
@@ -1881,10 +1881,10 @@ function getProcessResources() {
|
|
|
1881
1881
|
let threadCount = 0;
|
|
1882
1882
|
if (IS_LINUX) {
|
|
1883
1883
|
try {
|
|
1884
|
-
openFds = fs.readdirSync(`/proc/${process.pid}/fd`).length;
|
|
1884
|
+
openFds = fs$1.readdirSync(`/proc/${process.pid}/fd`).length;
|
|
1885
1885
|
} catch {}
|
|
1886
1886
|
try {
|
|
1887
|
-
const match = fs.readFileSync(`/proc/${process.pid}/status`, "utf-8").match(/Threads:\s+(\d+)/);
|
|
1887
|
+
const match = fs$1.readFileSync(`/proc/${process.pid}/status`, "utf-8").match(/Threads:\s+(\d+)/);
|
|
1888
1888
|
if (match) threadCount = parseInt(match[1], 10);
|
|
1889
1889
|
} catch {}
|
|
1890
1890
|
}
|
|
@@ -1899,7 +1899,7 @@ function getProcessResources() {
|
|
|
1899
1899
|
function getPressure(resource) {
|
|
1900
1900
|
if (!IS_LINUX) return null;
|
|
1901
1901
|
try {
|
|
1902
|
-
const data = fs.readFileSync(`/proc/pressure/${resource}`, "utf-8");
|
|
1902
|
+
const data = fs$1.readFileSync(`/proc/pressure/${resource}`, "utf-8");
|
|
1903
1903
|
const parseLine = (prefix) => {
|
|
1904
1904
|
const match = data.match(new RegExp(`${prefix} avg10=(\\d+\\.\\d+) avg60=(\\d+\\.\\d+) avg300=(\\d+\\.\\d+)`));
|
|
1905
1905
|
if (!match) return null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type AcceleratorCompute } from "@camstack/types";
|
|
2
|
+
/** Same name `accelerator_facts.FACTS_FILENAME` writes under the system temp dir. */
|
|
3
|
+
export declare const ACCELERATOR_FACTS_FILENAME = "camstack-accelerator-facts.json";
|
|
4
|
+
/** OpenVINO import is a few seconds; past this the estimate waits for the pool's file. */
|
|
5
|
+
export declare const ACCELERATOR_FACTS_TIMEOUT_MS = 8e3;
|
|
6
|
+
export declare function publishedAcceleratorFactsPath(): string;
|
|
7
|
+
/** `null` when the file is absent, unreadable, or not a facts payload. */
|
|
8
|
+
export declare function readPublishedAcceleratorFacts(filePath: string): readonly AcceleratorCompute[] | null;
|
|
9
|
+
/** Where `accelerator_facts.py` lives, or null when this process cannot see the addon. */
|
|
10
|
+
export declare function findAcceleratorFactsScript(dataDir: string | null | undefined, cwd?: string): string | null;
|
|
11
|
+
export interface AcceleratorFactsExec {
|
|
12
|
+
(command: string, args: readonly string[], timeoutMs: number): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
export interface AcceleratorFactsProbeInput {
|
|
15
|
+
readonly pythonPath: string | null;
|
|
16
|
+
readonly scriptPath: string | null;
|
|
17
|
+
readonly exec?: AcceleratorFactsExec;
|
|
18
|
+
readonly timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run the facts script. `null` when there is no interpreter, no script, or
|
|
22
|
+
* the script could not ask the device (it prints `{"accelerators": null}`).
|
|
23
|
+
*/
|
|
24
|
+
export declare function runAcceleratorFactsProbe(input: AcceleratorFactsProbeInput): Promise<readonly AcceleratorCompute[] | null>;
|
|
@@ -3,8 +3,10 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bmah6waF.js");
|
|
7
7
|
const require_coral_accelerators = require("../../coral-accelerators-BSVsBVzt.js");
|
|
8
|
+
let node_path = require("node:path");
|
|
9
|
+
node_path = require_chunk.__toESM(node_path);
|
|
8
10
|
let node_util = require("node:util");
|
|
9
11
|
let node_os = require("node:os");
|
|
10
12
|
node_os = require_chunk.__toESM(node_os);
|
|
@@ -313,7 +315,7 @@ var WINDOWS_PROBE_TIMEOUT_MS = 15e3;
|
|
|
313
315
|
* entire Node process (WS handshakes, tRPC subscriptions, metrics — all
|
|
314
316
|
* stalled). Keeping it async turns the probe into a true background task.
|
|
315
317
|
*/
|
|
316
|
-
var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
318
|
+
var execFileAsync$1 = (0, node_util.promisify)(node_child_process.execFile);
|
|
317
319
|
/** Minimal no-op logger for default parameter */
|
|
318
320
|
var noopLogger = {
|
|
319
321
|
debug() {},
|
|
@@ -341,7 +343,7 @@ async function getAvailableRAM_MB() {
|
|
|
341
343
|
const platform = node_os.platform();
|
|
342
344
|
try {
|
|
343
345
|
if (platform === "darwin") {
|
|
344
|
-
const { stdout: output } = await execFileAsync("vm_stat", [], {
|
|
346
|
+
const { stdout: output } = await execFileAsync$1("vm_stat", [], {
|
|
345
347
|
encoding: "utf8",
|
|
346
348
|
timeout: 3e3
|
|
347
349
|
});
|
|
@@ -375,10 +377,17 @@ var PlatformScorer = class {
|
|
|
375
377
|
embeddedPythonPath;
|
|
376
378
|
/** Where the Coral scan reads `/sys` and `/dev` (the host's, unless a spec fakes one). */
|
|
377
379
|
coralFs;
|
|
378
|
-
|
|
380
|
+
/**
|
|
381
|
+
* Asks OpenVINO / WebGPU for compute (D930). Null in tests and when this
|
|
382
|
+
* process has no embedded interpreter — the pool's published file is the
|
|
383
|
+
* other way the same facts arrive.
|
|
384
|
+
*/
|
|
385
|
+
readAcceleratorFacts;
|
|
386
|
+
constructor(logger = noopLogger, embeddedPythonPath = null, coralFs = require_coral_accelerators.nodeCoralFs, readAcceleratorFacts = null) {
|
|
379
387
|
this.logger = logger;
|
|
380
388
|
this.embeddedPythonPath = embeddedPythonPath;
|
|
381
389
|
this.coralFs = coralFs;
|
|
390
|
+
this.readAcceleratorFacts = readAcceleratorFacts;
|
|
382
391
|
}
|
|
383
392
|
/**
|
|
384
393
|
* Probe hardware + derive scores from pure rules and score all backend combos.
|
|
@@ -569,7 +578,7 @@ var PlatformScorer = class {
|
|
|
569
578
|
} });
|
|
570
579
|
}
|
|
571
580
|
}
|
|
572
|
-
|
|
581
|
+
const hardware = {
|
|
573
582
|
platform,
|
|
574
583
|
arch,
|
|
575
584
|
cpuModel,
|
|
@@ -580,6 +589,25 @@ var PlatformScorer = class {
|
|
|
580
589
|
npu,
|
|
581
590
|
coral
|
|
582
591
|
};
|
|
592
|
+
const accelerators = await this.readAcceleratorCompute();
|
|
593
|
+
return accelerators === null ? hardware : {
|
|
594
|
+
...hardware,
|
|
595
|
+
accelerators
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
/** Compute facts, or null when the probe did not run or could not ask. */
|
|
599
|
+
async readAcceleratorCompute() {
|
|
600
|
+
const read = this.readAcceleratorFacts;
|
|
601
|
+
if (read === null) return null;
|
|
602
|
+
try {
|
|
603
|
+
const facts = await read();
|
|
604
|
+
if (facts === null) return null;
|
|
605
|
+
this.logger.info("accelerator compute probed", { meta: { devices: facts.map((row) => row.deviceKey) } });
|
|
606
|
+
return facts;
|
|
607
|
+
} catch (err) {
|
|
608
|
+
this.logger.warn("accelerator compute probe failed", { meta: { error: require_dist.errMsg(err) } });
|
|
609
|
+
return null;
|
|
610
|
+
}
|
|
583
611
|
}
|
|
584
612
|
/**
|
|
585
613
|
* The Coral part of the probe, with the evidence that decided it logged —
|
|
@@ -645,7 +673,7 @@ var PlatformScorer = class {
|
|
|
645
673
|
/** NVIDIA's own tool: exact model and VRAM. Null when absent or failing. */
|
|
646
674
|
async probeNvidiaSmi() {
|
|
647
675
|
try {
|
|
648
|
-
const { stdout } = await execFileAsync("nvidia-smi", ["--query-gpu=name,memory.total", "--format=csv,noheader"], {
|
|
676
|
+
const { stdout } = await execFileAsync$1("nvidia-smi", ["--query-gpu=name,memory.total", "--format=csv,noheader"], {
|
|
649
677
|
encoding: "utf8",
|
|
650
678
|
timeout: 5e3,
|
|
651
679
|
windowsHide: true
|
|
@@ -666,7 +694,7 @@ var PlatformScorer = class {
|
|
|
666
694
|
/** Windows WMI probe; bounded, and a failure is a log line, never a boot failure. */
|
|
667
695
|
async probeWindowsHardwareSafely() {
|
|
668
696
|
const run = async (file, args) => {
|
|
669
|
-
const { stdout } = await execFileAsync(file, [...args], {
|
|
697
|
+
const { stdout } = await execFileAsync$1(file, [...args], {
|
|
670
698
|
encoding: "utf8",
|
|
671
699
|
timeout: WINDOWS_PROBE_TIMEOUT_MS,
|
|
672
700
|
windowsHide: true,
|
|
@@ -703,7 +731,7 @@ var PlatformScorer = class {
|
|
|
703
731
|
"python"
|
|
704
732
|
];
|
|
705
733
|
for (const cmd of candidates) try {
|
|
706
|
-
await execFileAsync(cmd, ["--version"], { timeout: 5e3 });
|
|
734
|
+
await execFileAsync$1(cmd, ["--version"], { timeout: 5e3 });
|
|
707
735
|
return cmd;
|
|
708
736
|
} catch (err) {
|
|
709
737
|
this.logger.debug(`Python command "${cmd}" not found`, { meta: { error: require_dist.errMsg(err) } });
|
|
@@ -801,6 +829,68 @@ var InferenceConfigResolver = class {
|
|
|
801
829
|
}
|
|
802
830
|
};
|
|
803
831
|
//#endregion
|
|
832
|
+
//#region src/builtins/platform-probe/accelerator-facts-probe.ts
|
|
833
|
+
/**
|
|
834
|
+
* Read the accelerator compute the inference worker published (D930), or ask
|
|
835
|
+
* the same script once when this process has the embedded interpreter.
|
|
836
|
+
*
|
|
837
|
+
* A missing file and a failed probe are `null` — not an empty list, and not
|
|
838
|
+
* zeros. `getHardware` overlays a published file onto the cached probe so a
|
|
839
|
+
* pool that starts later still reaches Auto tune.
|
|
840
|
+
*/
|
|
841
|
+
/** Same name `accelerator_facts.FACTS_FILENAME` writes under the system temp dir. */
|
|
842
|
+
var ACCELERATOR_FACTS_FILENAME = "camstack-accelerator-facts.json";
|
|
843
|
+
var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
844
|
+
function publishedAcceleratorFactsPath() {
|
|
845
|
+
return node_path.join(node_os.tmpdir(), ACCELERATOR_FACTS_FILENAME);
|
|
846
|
+
}
|
|
847
|
+
function jsonValue(text) {
|
|
848
|
+
return JSON.parse(text);
|
|
849
|
+
}
|
|
850
|
+
/** `null` when the file is absent, unreadable, or not a facts payload. */
|
|
851
|
+
function readPublishedAcceleratorFacts(filePath) {
|
|
852
|
+
let text;
|
|
853
|
+
try {
|
|
854
|
+
text = node_fs.readFileSync(filePath, "utf8");
|
|
855
|
+
} catch {
|
|
856
|
+
return null;
|
|
857
|
+
}
|
|
858
|
+
try {
|
|
859
|
+
return require_dist.parseAcceleratorFactsJson(jsonValue(text));
|
|
860
|
+
} catch {
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
/** Where `accelerator_facts.py` lives, or null when this process cannot see the addon. */
|
|
865
|
+
function findAcceleratorFactsScript(dataDir, cwd = process.cwd()) {
|
|
866
|
+
const candidates = [];
|
|
867
|
+
if (typeof dataDir === "string" && dataDir !== "") candidates.push(node_path.join(dataDir, "addons", "@camstack", "addon-pipeline", "python", "accelerator_facts.py"));
|
|
868
|
+
candidates.push(node_path.join(cwd, "packages", "addon-pipeline", "python", "accelerator_facts.py"));
|
|
869
|
+
for (const candidate of candidates) if (node_fs.existsSync(candidate)) return candidate;
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
async function defaultExec(command, args, timeoutMs) {
|
|
873
|
+
const { stdout } = await execFileAsync(command, [...args], {
|
|
874
|
+
encoding: "utf8",
|
|
875
|
+
timeout: timeoutMs,
|
|
876
|
+
windowsHide: true
|
|
877
|
+
});
|
|
878
|
+
return stdout;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Run the facts script. `null` when there is no interpreter, no script, or
|
|
882
|
+
* the script could not ask the device (it prints `{"accelerators": null}`).
|
|
883
|
+
*/
|
|
884
|
+
async function runAcceleratorFactsProbe(input) {
|
|
885
|
+
if (input.pythonPath === null || input.scriptPath === null) return null;
|
|
886
|
+
const exec = input.exec ?? defaultExec;
|
|
887
|
+
try {
|
|
888
|
+
return require_dist.parseAcceleratorFactsJson(jsonValue(await exec(input.pythonPath, [input.scriptPath], input.timeoutMs ?? 8e3)));
|
|
889
|
+
} catch {
|
|
890
|
+
return null;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
//#endregion
|
|
804
894
|
//#region src/builtins/platform-probe/index.ts
|
|
805
895
|
/**
|
|
806
896
|
* The decode-hwaccel backends `ctx.kernel.hwaccel.resolve` accepts. The cap
|
|
@@ -889,7 +979,11 @@ var PlatformProbeNativeAddon = class extends require_dist.BaseAddon {
|
|
|
889
979
|
this.ctx.logger.debug("ensurePython unavailable for platform probe", { meta: { error: require_dist.errMsg(err) } });
|
|
890
980
|
return null;
|
|
891
981
|
});
|
|
892
|
-
|
|
982
|
+
const factsScript = findAcceleratorFactsScript(this.ctx.dataDir);
|
|
983
|
+
this.scorer = new PlatformScorer(this.ctx.logger.withTags({ nodeId: this.bareLocalNodeId() }), embeddedPython, require_coral_accelerators.nodeCoralFs, embeddedPython === null || factsScript === null ? null : () => runAcceleratorFactsProbe({
|
|
984
|
+
pythonPath: embeddedPython,
|
|
985
|
+
scriptPath: factsScript
|
|
986
|
+
}));
|
|
893
987
|
const emitPhase = (phase, payload) => {
|
|
894
988
|
this.ctx.eventBus?.emit({
|
|
895
989
|
id: `platform-probe-${phase}-${Date.now()}`,
|
|
@@ -935,7 +1029,13 @@ var PlatformProbeNativeAddon = class extends require_dist.BaseAddon {
|
|
|
935
1029
|
return getCaps();
|
|
936
1030
|
},
|
|
937
1031
|
getHardware: async () => {
|
|
938
|
-
|
|
1032
|
+
const caps = await getCaps();
|
|
1033
|
+
const published = readPublishedAcceleratorFacts(publishedAcceleratorFactsPath());
|
|
1034
|
+
if (published === null) return caps.hardware;
|
|
1035
|
+
return {
|
|
1036
|
+
...caps.hardware,
|
|
1037
|
+
accelerators: published
|
|
1038
|
+
};
|
|
939
1039
|
},
|
|
940
1040
|
resolveInferenceConfig: async (input) => {
|
|
941
1041
|
const caps = await getCaps();
|