@camstack/system 1.2.417 → 1.2.418
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-utils.js +1 -1
- package/dist/addon-utils.mjs +1 -1
- 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/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 +2 -2
- 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-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 +7 -9
- package/dist/builtins/keychain/index.mjs +7 -9
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- 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 +1 -1
- package/dist/builtins/platform-probe/amd-npu.d.ts +6 -0
- package/dist/builtins/platform-probe/index.js +317 -19
- package/dist/builtins/platform-probe/index.mjs +318 -20
- package/dist/builtins/platform-probe/platform-scorer.d.ts +4 -0
- package/dist/builtins/platform-probe/windows-hardware.d.ts +77 -0
- 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 +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- 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 +2 -2
- package/dist/builtins/system-config/system-config.addon.mjs +2 -2
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-CndJVssc.mjs → composition-sources-0cPw9E0M.mjs} +1 -1
- package/dist/{composition-sources-ChAX2Kdo.js → composition-sources-BVjuMvpb.js} +1 -1
- package/dist/{constants-VXvZkGgw.js → constants-Aj0OBqlt.js} +1 -1
- package/dist/{constants-BzxwnfDc.mjs → constants-C8T7u1_Z.mjs} +1 -1
- package/dist/{custom-action-registry-DHv0kYcT.mjs → custom-action-registry-BQnbN0DP.mjs} +1 -2
- package/dist/{custom-action-registry-Bb28ibZV.js → custom-action-registry-Bf_YnagS.js} +3 -4
- package/dist/{dist-BMOD9OyH.js → dist-DVUg8e1T.js} +56 -72
- package/dist/{dist-H_RapIeM.mjs → dist-DlmdESNT.mjs} +57 -55
- package/dist/index.js +38 -10
- package/dist/index.mjs +38 -10
- package/dist/{jwt-signing-key-xQxqpwMC.mjs → jwt-signing-key-CGg61A5v.mjs} +1 -1
- package/dist/{jwt-signing-key-BiKHENST.js → jwt-signing-key-Jyu81jZR.js} +1 -1
- package/dist/{restore-archive-BobsETEp.js → restore-archive-Bq5PpQ-H.js} +1 -1
- package/dist/{restore-archive-CCAQicV-.mjs → restore-archive-DVo5ooBt.mjs} +1 -1
- package/dist/{retired-settings-keys-BMq2u4Wv.js → retired-settings-keys-CihMX6h9.js} +1 -1
- package/dist/{retired-settings-keys-CwL4zHLg.mjs → retired-settings-keys-k_XuC-Mt.mjs} +1 -1
- package/dist/{tls-C0TRPfqc.js → tls-BgImdxCO.js} +4 -11
- package/dist/{tls-D-2dPY-5.mjs → tls-CaOLZ09W.mjs} +5 -12
- package/package.json +1 -1
- package/dist/amd-npu-B-QyyMyF.js +0 -53
- package/dist/amd-npu-Db_SoSuL.mjs +0 -52
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
1
|
+
import { o as __toESM, r as __exportAll } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
+
import { Ct as enumerateInferenceDevices, On as scoreRuntimes, Or as emitReadiness, cr as BaseAddon, ei as EventCategory, fn as platformProbeCapability, sr as errMsg } from "../../dist-DlmdESNT.mjs";
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import { execFile } from "node:child_process";
|
|
@@ -53,7 +53,257 @@ function classifyCoralAccelerator(fsx) {
|
|
|
53
53
|
return null;
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
|
+
//#region src/builtins/platform-probe/amd-npu.ts
|
|
57
|
+
var amd_npu_exports = /* @__PURE__ */ __exportAll({
|
|
58
|
+
classifyAmdNpu: () => classifyAmdNpu,
|
|
59
|
+
xdnaInfoForDevice: () => xdnaInfoForDevice
|
|
60
|
+
});
|
|
61
|
+
var ACCEL_CLASS = "/sys/class/accel";
|
|
62
|
+
var ACCEL_DEV = "/dev/accel";
|
|
63
|
+
var AMD_PCI_VENDOR = "0x1022";
|
|
64
|
+
/** Phoenix / Hawk Point XDNA1. */
|
|
65
|
+
var XDNA1_DEVICES = new Set(["0x1502"]);
|
|
66
|
+
/** Strix / Krackan XDNA2. */
|
|
67
|
+
var XDNA2_DEVICES = new Set(["0x17f0"]);
|
|
68
|
+
function normalizePciId(raw) {
|
|
69
|
+
const t = raw.trim().toLowerCase();
|
|
70
|
+
if (t.startsWith("0x")) return t;
|
|
71
|
+
if (t.length > 0 && [...t].every((c) => "0123456789abcdef".includes(c))) return "0x" + t;
|
|
72
|
+
return t;
|
|
73
|
+
}
|
|
74
|
+
function hasAccelCharDevice(fsx) {
|
|
75
|
+
if (fsx.listDir(ACCEL_DEV).some((n) => n.startsWith("accel"))) return true;
|
|
76
|
+
return fsx.exists("/dev/accel/accel0");
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Detect an AMD XDNA NPU and report it as **present only**.
|
|
80
|
+
*
|
|
81
|
+
* Inference is NOT offered until P2 (Ryzen AI on Linux is Strix-first;
|
|
82
|
+
* Phoenix is not a production path today). The probe still names the
|
|
83
|
+
* generation so the UI and fleet census can show the hardware.
|
|
84
|
+
*/
|
|
85
|
+
function classifyAmdNpu(ctx, fsx) {
|
|
86
|
+
if (ctx.platform !== "linux" || ctx.arch !== "x64" || !ctx.amdPresent) return null;
|
|
87
|
+
if (!hasAccelCharDevice(fsx)) return null;
|
|
88
|
+
for (const name of fsx.listDir(ACCEL_CLASS)) {
|
|
89
|
+
if (!name.startsWith("accel")) continue;
|
|
90
|
+
const vendor = normalizePciId(fsx.readFile("/sys/class/accel/" + name + "/device/vendor"));
|
|
91
|
+
const device = normalizePciId(fsx.readFile("/sys/class/accel/" + name + "/device/device"));
|
|
92
|
+
if (vendor !== AMD_PCI_VENDOR) continue;
|
|
93
|
+
return xdnaInfoForDevice(device);
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The NPU descriptor for an AMD PCI device id (`0x1502` or `1502`). Shared by
|
|
99
|
+
* the Linux sysfs probe and the Windows PnP probe so both name the same
|
|
100
|
+
* silicon the same way.
|
|
101
|
+
*/
|
|
102
|
+
function xdnaInfoForDevice(rawDeviceId) {
|
|
103
|
+
const device = normalizePciId(rawDeviceId);
|
|
104
|
+
if (XDNA1_DEVICES.has(device)) return {
|
|
105
|
+
type: "amd-xdna",
|
|
106
|
+
name: "AMD XDNA1 NPU",
|
|
107
|
+
generation: "xdna1"
|
|
108
|
+
};
|
|
109
|
+
if (XDNA2_DEVICES.has(device)) return {
|
|
110
|
+
type: "amd-xdna",
|
|
111
|
+
name: "AMD XDNA2 NPU",
|
|
112
|
+
generation: "xdna2"
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
type: "amd-xdna",
|
|
116
|
+
name: "AMD XDNA NPU"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/builtins/platform-probe/windows-hardware.ts
|
|
121
|
+
var PCI_VENDOR_NVIDIA = "10DE";
|
|
122
|
+
var PCI_VENDOR_INTEL = "8086";
|
|
123
|
+
/** Radeon graphics are 1002; the XDNA NPU is a 1022 device. */
|
|
124
|
+
var PCI_VENDORS_AMD = new Set(["1002", "1022"]);
|
|
125
|
+
/** Adapters that are not hardware: RDP, hypervisor, capture and spoofing drivers. */
|
|
126
|
+
var VIRTUAL_ADAPTER = /basic display|basic render|remote display|hyper-v|vmware|virtualbox|parallels|citrix|parsec|indirect display|displaylink|mirror driver|virtual/i;
|
|
127
|
+
/** One PowerShell process answers both: video controllers and AMD PCI devices. */
|
|
128
|
+
var POWERSHELL_SCRIPT = [
|
|
129
|
+
"$ErrorActionPreference = 'SilentlyContinue'",
|
|
130
|
+
"$gpu = @(Get-CimInstance Win32_VideoController | Select-Object Name, PNPDeviceID)",
|
|
131
|
+
"$npu = @(Get-CimInstance Win32_PnPEntity | Where-Object { $_.PNPDeviceID -match 'VEN_1022&DEV_(1502|17F0)' } | Select-Object Name, PNPDeviceID)",
|
|
132
|
+
"@{ gpu = $gpu; npu = $npu } | ConvertTo-Json -Compress -Depth 3"
|
|
133
|
+
].join("; ");
|
|
134
|
+
function powershellInvocation(systemRoot) {
|
|
135
|
+
return [`${systemRoot ?? "C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`, [
|
|
136
|
+
"-NoProfile",
|
|
137
|
+
"-NonInteractive",
|
|
138
|
+
"-ExecutionPolicy",
|
|
139
|
+
"Bypass",
|
|
140
|
+
"-Command",
|
|
141
|
+
POWERSHELL_SCRIPT
|
|
142
|
+
]];
|
|
143
|
+
}
|
|
144
|
+
var WMIC_VIDEO_ARGS = [
|
|
145
|
+
"path",
|
|
146
|
+
"Win32_VideoController",
|
|
147
|
+
"get",
|
|
148
|
+
"Name,PNPDeviceID",
|
|
149
|
+
"/format:csv"
|
|
150
|
+
];
|
|
151
|
+
var WMIC_AMD_PNP_ARGS = [
|
|
152
|
+
"path",
|
|
153
|
+
"Win32_PnPEntity",
|
|
154
|
+
"where",
|
|
155
|
+
"PNPDeviceID like 'PCI\\\\VEN_1022&DEV_%'",
|
|
156
|
+
"get",
|
|
157
|
+
"Name,PNPDeviceID",
|
|
158
|
+
"/format:csv"
|
|
159
|
+
];
|
|
160
|
+
function asRecordList(value) {
|
|
161
|
+
if (Array.isArray(value)) return value.filter((v) => v !== null && typeof v === "object" && !Array.isArray(v));
|
|
162
|
+
return value !== null && typeof value === "object" ? [Object.fromEntries(Object.entries(value))] : [];
|
|
163
|
+
}
|
|
164
|
+
function str(value) {
|
|
165
|
+
return typeof value === "string" ? value : "";
|
|
166
|
+
}
|
|
167
|
+
/** PowerShell prepends a BOM on some hosts, which `JSON.parse` rejects. */
|
|
168
|
+
function parseJson(text) {
|
|
169
|
+
return JSON.parse(text.replace(/^\uFEFF/, "").trim());
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* `{"gpu":[...],"npu":[...]}` as the script emits it. A single result comes
|
|
173
|
+
* back as an object rather than a one-element array, and an empty one as
|
|
174
|
+
* `null` — all three are handled.
|
|
175
|
+
*/
|
|
176
|
+
function parsePowershellOutput(text) {
|
|
177
|
+
const root = parseJson(text);
|
|
178
|
+
const gpu = root !== null && typeof root === "object" ? Reflect.get(root, "gpu") : void 0;
|
|
179
|
+
const npu = root !== null && typeof root === "object" ? Reflect.get(root, "npu") : void 0;
|
|
180
|
+
const toDevice = (r) => ({
|
|
181
|
+
name: str(r["Name"]),
|
|
182
|
+
pnpDeviceId: str(r["PNPDeviceID"])
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
controllers: asRecordList(gpu).map(toDevice),
|
|
186
|
+
pnp: asRecordList(npu).map(toDevice)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* `wmic ... /format:csv` — a blank line, then `Node,<cols alphabetical>`, then
|
|
191
|
+
* one row per object. The device name can contain commas, so only the FIRST
|
|
192
|
+
* column boundaries are trusted: columns after `Node` are `Name,PNPDeviceID`
|
|
193
|
+
* and the PNP id (no commas) is taken from the END of the row.
|
|
194
|
+
*/
|
|
195
|
+
function parseWmicCsv(text) {
|
|
196
|
+
const lines = text.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
|
|
197
|
+
const headerIndex = lines.findIndex((l) => /^node,/i.test(l));
|
|
198
|
+
if (headerIndex < 0) return [];
|
|
199
|
+
const out = [];
|
|
200
|
+
for (const line of lines.slice(headerIndex + 1)) {
|
|
201
|
+
const parts = line.split(",");
|
|
202
|
+
if (parts.length < 3) continue;
|
|
203
|
+
const pnpDeviceId = (parts[parts.length - 1] ?? "").trim();
|
|
204
|
+
const name = parts.slice(1, -1).join(",").trim();
|
|
205
|
+
if (pnpDeviceId.length > 0) out.push({
|
|
206
|
+
name,
|
|
207
|
+
pnpDeviceId
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
/** The PCI vendor id (`10DE`) out of a PnP id like `PCI\VEN_10DE&DEV_2504&...`. */
|
|
213
|
+
function pciVendorOf(pnpDeviceId) {
|
|
214
|
+
const m = /VEN_([0-9A-F]{4})/i.exec(pnpDeviceId);
|
|
215
|
+
return m?.[1] ? m[1].toUpperCase() : null;
|
|
216
|
+
}
|
|
217
|
+
function pciDeviceOf(pnpDeviceId) {
|
|
218
|
+
const m = /DEV_([0-9A-F]{4})/i.exec(pnpDeviceId);
|
|
219
|
+
return m?.[1] ? m[1].toLowerCase() : null;
|
|
220
|
+
}
|
|
221
|
+
function gpuVendor(c) {
|
|
222
|
+
const vendor = pciVendorOf(c.pnpDeviceId);
|
|
223
|
+
if (vendor === PCI_VENDOR_NVIDIA) return "nvidia";
|
|
224
|
+
if (vendor === PCI_VENDOR_INTEL) return "intel";
|
|
225
|
+
if (vendor !== null && PCI_VENDORS_AMD.has(vendor)) return "amd";
|
|
226
|
+
if (/nvidia|geforce|quadro|rtx/i.test(c.name)) return "nvidia";
|
|
227
|
+
if (/intel/i.test(c.name)) return "intel";
|
|
228
|
+
if (/amd|radeon/i.test(c.name)) return "amd";
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* The accelerator the node should treat as its GPU. Same preference as the
|
|
233
|
+
* Linux probe — NVIDIA, then Intel, then AMD — so a laptop with an Intel iGPU
|
|
234
|
+
* and a discrete card is described the way the rest of the system already
|
|
235
|
+
* expects. Virtual adapters never count.
|
|
236
|
+
*/
|
|
237
|
+
function classifyWindowsGpu(controllers) {
|
|
238
|
+
const real = controllers.filter((c) => c.name.length > 0 && !VIRTUAL_ADAPTER.test(c.name));
|
|
239
|
+
for (const wanted of [
|
|
240
|
+
"nvidia",
|
|
241
|
+
"intel",
|
|
242
|
+
"amd"
|
|
243
|
+
]) {
|
|
244
|
+
const hit = real.find((c) => gpuVendor(c) === wanted);
|
|
245
|
+
if (hit) return {
|
|
246
|
+
type: wanted,
|
|
247
|
+
name: hit.name
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* An AMD XDNA NPU from PnP ids: `PCI\VEN_1022&DEV_1502` (Phoenix / Hawk Point)
|
|
254
|
+
* or `DEV_17F0` (Strix / Krackan). Present-only, exactly like the Linux probe.
|
|
255
|
+
*/
|
|
256
|
+
function classifyWindowsAmdNpu(devices) {
|
|
257
|
+
for (const d of devices) {
|
|
258
|
+
if (pciVendorOf(d.pnpDeviceId) !== "1022") continue;
|
|
259
|
+
const device = pciDeviceOf(d.pnpDeviceId);
|
|
260
|
+
if (device === "1502" || device === "17f0") return xdnaInfoForDevice(device);
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
async function viaPowershell(run, systemRoot) {
|
|
265
|
+
const [file, args] = powershellInvocation(systemRoot);
|
|
266
|
+
const parsed = parsePowershellOutput(await run(file, args));
|
|
267
|
+
return {
|
|
268
|
+
gpu: classifyWindowsGpu(parsed.controllers),
|
|
269
|
+
npu: classifyWindowsAmdNpu(parsed.pnp),
|
|
270
|
+
source: "powershell"
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
async function viaWmic(run) {
|
|
274
|
+
const [video, amd] = await Promise.all([run("wmic", WMIC_VIDEO_ARGS), run("wmic", WMIC_AMD_PNP_ARGS).catch(() => "")]);
|
|
275
|
+
return {
|
|
276
|
+
gpu: classifyWindowsGpu(parseWmicCsv(video)),
|
|
277
|
+
npu: classifyWindowsAmdNpu(parseWmicCsv(amd)),
|
|
278
|
+
source: "wmic"
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* GPU + AMD NPU on a Windows host. NEVER throws: a probe that cannot run is
|
|
283
|
+
* `{ gpu: null, npu: null, source: 'none' }` and boot goes on — the node then
|
|
284
|
+
* scores as a CPU node, which is correct for hardware we could not see.
|
|
285
|
+
*/
|
|
286
|
+
async function probeWindowsHardware(run, options = {}) {
|
|
287
|
+
try {
|
|
288
|
+
return await viaPowershell(run, options.systemRoot);
|
|
289
|
+
} catch (powershellError) {
|
|
290
|
+
options.onFallback?.(`PowerShell probe failed (${powershellError instanceof Error ? powershellError.message : String(powershellError)}); trying wmic`);
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
return await viaWmic(run);
|
|
294
|
+
} catch (wmicError) {
|
|
295
|
+
options.onFallback?.(`wmic probe failed (${wmicError instanceof Error ? wmicError.message : String(wmicError)}); hardware unknown`);
|
|
296
|
+
return {
|
|
297
|
+
gpu: null,
|
|
298
|
+
npu: null,
|
|
299
|
+
source: "none"
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
//#endregion
|
|
56
304
|
//#region src/builtins/platform-probe/platform-scorer.ts
|
|
305
|
+
/** WMI can be slow on a cold machine, but never worth stalling boot for. */
|
|
306
|
+
var WINDOWS_PROBE_TIMEOUT_MS = 15e3;
|
|
57
307
|
/**
|
|
58
308
|
* Promisified `execFile`. Used across the scorer so every subprocess
|
|
59
309
|
* spawn yields the event loop — critical at boot because a single sync
|
|
@@ -231,24 +481,25 @@ var PlatformScorer = class {
|
|
|
231
481
|
};
|
|
232
482
|
npu = { type: "apple-ane" };
|
|
233
483
|
}
|
|
484
|
+
if (platform === "win32") {
|
|
485
|
+
const nvidia = await this.probeNvidiaSmi();
|
|
486
|
+
const win = await this.probeWindowsHardwareSafely();
|
|
487
|
+
gpu = nvidia ?? win.gpu;
|
|
488
|
+
npu = win.npu;
|
|
489
|
+
if (gpu) this.logger.info("Windows GPU detected", { meta: {
|
|
490
|
+
type: gpu.type,
|
|
491
|
+
name: gpu.name
|
|
492
|
+
} });
|
|
493
|
+
if (npu && win.source !== "none") this.logger.info("AMD XDNA NPU detected (present only)", { meta: {
|
|
494
|
+
type: npu.type,
|
|
495
|
+
name: npu.name,
|
|
496
|
+
generation: npu.generation,
|
|
497
|
+
source: win.source
|
|
498
|
+
} });
|
|
499
|
+
}
|
|
234
500
|
if (platform === "linux") {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
encoding: "utf8",
|
|
238
|
-
timeout: 5e3
|
|
239
|
-
});
|
|
240
|
-
const output = stdout.trim();
|
|
241
|
-
if (output) {
|
|
242
|
-
const [name, mem] = output.split(",").map((s) => s.trim());
|
|
243
|
-
gpu = {
|
|
244
|
-
type: "nvidia",
|
|
245
|
-
name: name ?? "NVIDIA GPU",
|
|
246
|
-
memoryMB: parseInt(mem ?? "0")
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
} catch (err) {
|
|
250
|
-
this.logger.debug("NVIDIA GPU detection failed", { meta: { error: errMsg(err) } });
|
|
251
|
-
}
|
|
501
|
+
const nvidia = await this.probeNvidiaSmi();
|
|
502
|
+
if (nvidia) gpu = nvidia;
|
|
252
503
|
const listRenderNodes = () => {
|
|
253
504
|
try {
|
|
254
505
|
return fs.readdirSync("/dev/dri").filter((n) => n.startsWith("renderD")).map((n) => `/dev/dri/${n}`);
|
|
@@ -307,7 +558,7 @@ var PlatformScorer = class {
|
|
|
307
558
|
} });
|
|
308
559
|
}
|
|
309
560
|
if (!npu) {
|
|
310
|
-
const { classifyAmdNpu } = await
|
|
561
|
+
const { classifyAmdNpu } = await Promise.resolve().then(() => amd_npu_exports);
|
|
311
562
|
npu = classifyAmdNpu({
|
|
312
563
|
platform,
|
|
313
564
|
arch,
|
|
@@ -342,6 +593,53 @@ var PlatformScorer = class {
|
|
|
342
593
|
coral
|
|
343
594
|
};
|
|
344
595
|
}
|
|
596
|
+
/** NVIDIA's own tool: exact model and VRAM. Null when absent or failing. */
|
|
597
|
+
async probeNvidiaSmi() {
|
|
598
|
+
try {
|
|
599
|
+
const { stdout } = await execFileAsync("nvidia-smi", ["--query-gpu=name,memory.total", "--format=csv,noheader"], {
|
|
600
|
+
encoding: "utf8",
|
|
601
|
+
timeout: 5e3,
|
|
602
|
+
windowsHide: true
|
|
603
|
+
});
|
|
604
|
+
const output = stdout.trim();
|
|
605
|
+
if (!output) return null;
|
|
606
|
+
const [name, mem] = output.split(",").map((s) => s.trim());
|
|
607
|
+
return {
|
|
608
|
+
type: "nvidia",
|
|
609
|
+
name: name ?? "NVIDIA GPU",
|
|
610
|
+
memoryMB: parseInt(mem ?? "0")
|
|
611
|
+
};
|
|
612
|
+
} catch (err) {
|
|
613
|
+
this.logger.debug("NVIDIA GPU detection failed", { meta: { error: errMsg(err) } });
|
|
614
|
+
return null;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
/** Windows WMI probe; bounded, and a failure is a log line, never a boot failure. */
|
|
618
|
+
async probeWindowsHardwareSafely() {
|
|
619
|
+
const run = async (file, args) => {
|
|
620
|
+
const { stdout } = await execFileAsync(file, [...args], {
|
|
621
|
+
encoding: "utf8",
|
|
622
|
+
timeout: WINDOWS_PROBE_TIMEOUT_MS,
|
|
623
|
+
windowsHide: true,
|
|
624
|
+
maxBuffer: 4 * 1024 * 1024
|
|
625
|
+
});
|
|
626
|
+
return stdout;
|
|
627
|
+
};
|
|
628
|
+
const systemRoot = process.env["SystemRoot"];
|
|
629
|
+
try {
|
|
630
|
+
return await probeWindowsHardware(run, {
|
|
631
|
+
...systemRoot === void 0 ? {} : { systemRoot },
|
|
632
|
+
onFallback: (reason) => this.logger.warn("Windows hardware probe degraded", { meta: { reason } })
|
|
633
|
+
});
|
|
634
|
+
} catch (err) {
|
|
635
|
+
this.logger.warn("Windows hardware probe failed — scoring as a CPU node", { meta: { error: errMsg(err) } });
|
|
636
|
+
return {
|
|
637
|
+
gpu: null,
|
|
638
|
+
npu: null,
|
|
639
|
+
source: "none"
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
}
|
|
345
643
|
/**
|
|
346
644
|
* Locates a Python interpreter without importing any module.
|
|
347
645
|
*
|
|
@@ -26,6 +26,10 @@ export declare class PlatformScorer {
|
|
|
26
26
|
*/
|
|
27
27
|
probe(onPhase?: (phase: string, payload?: Record<string, unknown>) => void): Promise<PlatformCapabilities>;
|
|
28
28
|
probeHardware(): Promise<HardwareInfo>;
|
|
29
|
+
/** NVIDIA's own tool: exact model and VRAM. Null when absent or failing. */
|
|
30
|
+
private probeNvidiaSmi;
|
|
31
|
+
/** Windows WMI probe; bounded, and a failure is a log line, never a boot failure. */
|
|
32
|
+
private probeWindowsHardwareSafely;
|
|
29
33
|
/**
|
|
30
34
|
* Locates a Python interpreter without importing any module.
|
|
31
35
|
*
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { GpuInfo, NpuInfo } from "@camstack/types";
|
|
2
|
+
/**
|
|
3
|
+
* Windows hardware probe — the same `hw.gpu` / `hw.npu` model the Linux probe
|
|
4
|
+
* fills from `/sys` and `/dev`, read from WMI instead.
|
|
5
|
+
*
|
|
6
|
+
* Two sources, tried in order, neither able to block boot:
|
|
7
|
+
* 1. PowerShell + `Get-CimInstance` (every supported Windows ships it; one
|
|
8
|
+
* process answers both questions).
|
|
9
|
+
* 2. `wmic` — deprecated and absent from newer images, but present on the
|
|
10
|
+
* Windows 10/11 releases that lack nothing else, and the only thing left
|
|
11
|
+
* when PowerShell is locked down by policy.
|
|
12
|
+
*
|
|
13
|
+
* Everything here is PURE over the text a runner returns, so the parsing and
|
|
14
|
+
* the classification are tested on any OS. What this cannot prove — and a
|
|
15
|
+
* Mac cannot — is the shape of the real WMI output on a real Windows host; the
|
|
16
|
+
* parsers are written to accept both the object and the array form PowerShell
|
|
17
|
+
* produces, and the wmic CSV header order wmic actually uses.
|
|
18
|
+
*/
|
|
19
|
+
/** Runs a program and resolves with its stdout; rejects on failure or timeout. */
|
|
20
|
+
export type WindowsProbeRunner = (file: string, args: readonly string[]) => Promise<string>;
|
|
21
|
+
export interface WindowsVideoController {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly pnpDeviceId: string;
|
|
24
|
+
}
|
|
25
|
+
export interface WindowsPnpDevice {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly pnpDeviceId: string;
|
|
28
|
+
}
|
|
29
|
+
export interface WindowsHardware {
|
|
30
|
+
readonly gpu: GpuInfo | null;
|
|
31
|
+
readonly npu: NpuInfo | null;
|
|
32
|
+
/** Which source answered — for the boot log; `none` when neither could. */
|
|
33
|
+
readonly source: "powershell" | "wmic" | "none";
|
|
34
|
+
}
|
|
35
|
+
export declare function powershellInvocation(systemRoot: string | undefined): readonly [string, readonly string[]];
|
|
36
|
+
export declare const WMIC_VIDEO_ARGS: readonly string[];
|
|
37
|
+
export declare const WMIC_AMD_PNP_ARGS: readonly string[];
|
|
38
|
+
export interface ParsedPowershell {
|
|
39
|
+
readonly controllers: readonly WindowsVideoController[];
|
|
40
|
+
readonly pnp: readonly WindowsPnpDevice[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* `{"gpu":[...],"npu":[...]}` as the script emits it. A single result comes
|
|
44
|
+
* back as an object rather than a one-element array, and an empty one as
|
|
45
|
+
* `null` — all three are handled.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parsePowershellOutput(text: string): ParsedPowershell;
|
|
48
|
+
/**
|
|
49
|
+
* `wmic ... /format:csv` — a blank line, then `Node,<cols alphabetical>`, then
|
|
50
|
+
* one row per object. The device name can contain commas, so only the FIRST
|
|
51
|
+
* column boundaries are trusted: columns after `Node` are `Name,PNPDeviceID`
|
|
52
|
+
* and the PNP id (no commas) is taken from the END of the row.
|
|
53
|
+
*/
|
|
54
|
+
export declare function parseWmicCsv(text: string): readonly WindowsPnpDevice[];
|
|
55
|
+
/** The PCI vendor id (`10DE`) out of a PnP id like `PCI\VEN_10DE&DEV_2504&...`. */
|
|
56
|
+
export declare function pciVendorOf(pnpDeviceId: string): string | null;
|
|
57
|
+
/**
|
|
58
|
+
* The accelerator the node should treat as its GPU. Same preference as the
|
|
59
|
+
* Linux probe — NVIDIA, then Intel, then AMD — so a laptop with an Intel iGPU
|
|
60
|
+
* and a discrete card is described the way the rest of the system already
|
|
61
|
+
* expects. Virtual adapters never count.
|
|
62
|
+
*/
|
|
63
|
+
export declare function classifyWindowsGpu(controllers: readonly WindowsVideoController[]): GpuInfo | null;
|
|
64
|
+
/**
|
|
65
|
+
* An AMD XDNA NPU from PnP ids: `PCI\VEN_1022&DEV_1502` (Phoenix / Hawk Point)
|
|
66
|
+
* or `DEV_17F0` (Strix / Krackan). Present-only, exactly like the Linux probe.
|
|
67
|
+
*/
|
|
68
|
+
export declare function classifyWindowsAmdNpu(devices: readonly WindowsPnpDevice[]): NpuInfo | null;
|
|
69
|
+
/**
|
|
70
|
+
* GPU + AMD NPU on a Windows host. NEVER throws: a probe that cannot run is
|
|
71
|
+
* `{ gpu: null, npu: null, source: 'none' }` and boot goes on — the node then
|
|
72
|
+
* scores as a CPU node, which is correct for hardware we could not see.
|
|
73
|
+
*/
|
|
74
|
+
export declare function probeWindowsHardware(run: WindowsProbeRunner, options?: {
|
|
75
|
+
readonly systemRoot?: string;
|
|
76
|
+
readonly onFallback?: (reason: string) => void;
|
|
77
|
+
}): Promise<WindowsHardware>;
|
|
@@ -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-DVUg8e1T.js");
|
|
7
7
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
8
8
|
/**
|
|
9
9
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cr as BaseAddon, ei as EventCategory } from "../../dist-DlmdESNT.mjs";
|
|
2
2
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -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-DVUg8e1T.js");
|
|
7
7
|
const require_snapshot_courtesy = require("../../snapshot-courtesy-D_C5-nC0.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ln as streamQualityLabel, X as bareAddonId, Z as batteryCapability, _t as deriveBatteryPresence, a as BatteryStatusSchema, cr as BaseAddon, ei as EventCategory, ir as DeviceFeature, jn as snapshotCapability, or as DeviceType, sr as errMsg, tn as memoizePinnedFfmpeg, zr as nodePin } from "../../dist-DlmdESNT.mjs";
|
|
2
2
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg } from "../../snapshot-courtesy-CyFs1M3I.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -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-DVUg8e1T.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn as storageProviderCapability, cr as BaseAddon, jt as filesystemBrowseCapability } from "../../dist-DlmdESNT.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
Binary file
|
|
Binary file
|
|
@@ -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-DVUg8e1T.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $r as transformSecretWrite, $t as mayReadLocation, B as StorageLocationModeSchema, Dt as evictionPolicyOfLocation, Gn as withLocationMode, H as StorageMigrationJobSchema, Ir as isSecretMarker, Jr as secretTreeFromPaths, Kr as resolveSecretMarkers, Kt as legacyModeOf, Mn as storageCapability, Nn as storageMigrationCapability, Pt as gbToBytes, Sn as resolveLocationMode, Sr as collectSecretConfigKeys, V as StorageLocationTypeSchema, Vr as parseJsonObject, cr as BaseAddon, ei as EventCategory, en as mayWriteToLocation, fr as REDACTED_SECRET, k as LegacyStorageLocationDefaultSchema, kn as settingsStoreCapability, rn as modeMayWrite, z as StorageCleanupJobSchema, zt as isLocationEnabled } from "../../dist-DlmdESNT.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { containsOrEquals, physicalRootOf } from "@camstack/types/node";
|
|
@@ -3,9 +3,9 @@ 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-DVUg8e1T.js");
|
|
7
7
|
const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
|
|
8
|
-
const require_constants$8 = require("../../constants-
|
|
8
|
+
const require_constants$8 = require("../../constants-Aj0OBqlt.js");
|
|
9
9
|
const require_x509_es = require("../../x509.es-Dzl0BbmG.js");
|
|
10
10
|
const require_src$1 = require("../../src-CnAqG6EF.js");
|
|
11
11
|
let zod = require("zod");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { $r as transformSecretWrite, Er as defineCustomActions, Fr as isSecretClear, Ir as isSecretMarker, Rr as makeSecretMarker, Tr as customAction, Yr as secretTreeFromSchema, cr as BaseAddon, jr as hydrateSchema, sr as errMsg } from "../../dist-DlmdESNT.mjs";
|
|
3
3
|
import { t as require_safe_buffer } from "../../safe-buffer-B1OjL1I9.mjs";
|
|
4
|
-
import { a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, c as MESH_JOIN_TOKEN_MAX_TTL_SEC, d as CLUSTER_SECRET_REF, i as MESH_CA_FIELD, l as SERVER_AUTH_OID, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, r as MESH_CA_COMMON_NAME, s as MESH_CA_VALIDITY_DAYS, t as CLIENT_AUTH_OID, v as hashClusterSecret } from "../../constants-
|
|
4
|
+
import { a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, c as MESH_JOIN_TOKEN_MAX_TTL_SEC, d as CLUSTER_SECRET_REF, i as MESH_CA_FIELD, l as SERVER_AUTH_OID, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, r as MESH_CA_COMMON_NAME, s as MESH_CA_VALIDITY_DAYS, t as CLIENT_AUTH_OID, v as hashClusterSecret } from "../../constants-C8T7u1_Z.mjs";
|
|
5
5
|
import { a as KeyUsagesExtension, c as Pkcs10CertificateRequestGenerator, d as X509Certificate$1, f as X509CertificateGenerator, i as KeyUsageFlags, n as BasicConstraintsExtension, o as PemConverter, p as cryptoProvider, r as ExtendedKeyUsageExtension, s as Pkcs10CertificateRequest, t as AuthorityKeyIdentifierExtension, u as SubjectKeyIdentifierExtension } from "../../x509.es-CAjSsrkk.mjs";
|
|
6
6
|
import { t as require_src } from "../../src-hG4grMU4.mjs";
|
|
7
7
|
import { z } from "zod";
|
|
@@ -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-DVUg8e1T.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Xt as logDestinationCapability, cr as BaseAddon } from "../../dist-DlmdESNT.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { er as compositionSourceKey, sr as errMsg } from "./dist-DlmdESNT.mjs";
|
|
2
2
|
//#region src/builtins/core-blocks/composition-sources.ts
|
|
3
3
|
/**
|
|
4
4
|
* Describe what a composition reads and writes for SAVE-time validation
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { P as MODEL_FORMATS, Rt as hfModelUrl, T as HF_REPO } from "./dist-H_RapIeM.mjs";
|
|
2
1
|
import { createHash } from "node:crypto";
|
|
3
2
|
import * as path$1 from "node:path";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import * as fs from "node:fs";
|
|
6
5
|
import { createReadStream, promises } from "node:fs";
|
|
7
6
|
import { promisify } from "node:util";
|
|
7
|
+
import { HF_REPO, MODEL_FORMATS, describeCustomActions, hfModelUrl } from "@camstack/types/addon";
|
|
8
8
|
import { createServer } from "node:http";
|
|
9
9
|
import { brotliCompress, constants as constants$1, gzip } from "node:zlib";
|
|
10
10
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
11
|
-
import { describeCustomActions } from "@camstack/types/addon";
|
|
12
11
|
//#region src/download/hosted-model-revisions.ts
|
|
13
12
|
/**
|
|
14
13
|
* GENERATED by `scripts/check-hosted-model-revisions.ts --write` — DO NOT EDIT.
|