camstack 1.1.32 → 1.2.1
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.
|
@@ -14522,7 +14522,7 @@ function date4(params) {
|
|
|
14522
14522
|
// ../../node_modules/zod/v4/classic/external.js
|
|
14523
14523
|
config(en_default());
|
|
14524
14524
|
|
|
14525
|
-
// ../types/dist/sleep-
|
|
14525
|
+
// ../types/dist/sleep-BQ60XlE9.mjs
|
|
14526
14526
|
var WELL_KNOWN_TABS = [
|
|
14527
14527
|
{
|
|
14528
14528
|
id: "overview",
|
|
@@ -15389,6 +15389,17 @@ var ModelCatalogEntrySchema = external_exports.object({
|
|
|
15389
15389
|
"imagenet",
|
|
15390
15390
|
"none"
|
|
15391
15391
|
]).optional(),
|
|
15392
|
+
/**
|
|
15393
|
+
* The model already applies softmax IN-GRAPH — its raw output is a
|
|
15394
|
+
* probability distribution, not logits. When set, the `softmax`
|
|
15395
|
+
* postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
|
|
15396
|
+
* probability vector collapses it toward uniform (top-1 score craters far
|
|
15397
|
+
* below its true value, making every confidence gate meaningless). Absent ⇒
|
|
15398
|
+
* the output is raw logits and the postprocessor applies softmax (the normal
|
|
15399
|
+
* case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
|
|
15400
|
+
* TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
|
|
15401
|
+
*/
|
|
15402
|
+
outputProbabilities: external_exports.boolean().optional(),
|
|
15392
15403
|
preprocessMode: external_exports.enum(["letterbox", "resize"]).optional(),
|
|
15393
15404
|
/**
|
|
15394
15405
|
* Per-MODEL postprocessor override. Absent ⇒ the step's own
|
|
@@ -19694,20 +19705,6 @@ var pipelineExecutorCapability = {
|
|
|
19694
19705
|
getSelectedEngine: method(external_exports.void(), PipelineEngineChoiceSchema),
|
|
19695
19706
|
getDefaultSteps: method(PipelineEngineChoiceSchema, external_exports.array(PipelineDefaultStepSchema)),
|
|
19696
19707
|
/**
|
|
19697
|
-
* Re-run the platform probe for the inference engine and write the
|
|
19698
|
-
* detected runtime / backend / device back into the addon's own
|
|
19699
|
-
* global settings store. Returns the engine that was picked so the
|
|
19700
|
-
* UI can confirm without a second round-trip. Triggers the standard
|
|
19701
|
-
* `requiresRestart` auto-restart flow because all three fields are
|
|
19702
|
-
* marked restart-required. Replaces the legacy per-agent
|
|
19703
|
-
* `pipeline-orchestrator.reprobeAgentHwAccel` surface for the
|
|
19704
|
-
* engine dimension — each addon now owns its own probe.
|
|
19705
|
-
*/
|
|
19706
|
-
reprobeEngine: method(external_exports.void(), PipelineEngineChoiceSchema, {
|
|
19707
|
-
kind: "mutation",
|
|
19708
|
-
auth: "admin"
|
|
19709
|
-
}),
|
|
19710
|
-
/**
|
|
19711
19708
|
* Per-node detection-engine provisioning snapshot. Returns the live
|
|
19712
19709
|
* state of the lazy runtime-provisioning machine on `nodeId`
|
|
19713
19710
|
* (idle / installing / verifying / ready / failed). The UI pairs this
|
|
@@ -19845,7 +19842,14 @@ var pipelineExecutorCapability = {
|
|
|
19845
19842
|
* (inputClasses ≠ null) are skipped and served per-track via
|
|
19846
19843
|
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
19847
19844
|
*/
|
|
19848
|
-
plane: external_exports.enum(["full", "frame"]).optional()
|
|
19845
|
+
plane: external_exports.enum(["full", "frame"]).optional(),
|
|
19846
|
+
/**
|
|
19847
|
+
* Inference-device selector (Phase 2 multi-device). Format
|
|
19848
|
+
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
19849
|
+
* Omitted ⇒ the runner's default device (current single-engine
|
|
19850
|
+
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
19851
|
+
*/
|
|
19852
|
+
deviceKey: external_exports.string().optional()
|
|
19849
19853
|
}), PipelineRunResultBridge, { kind: "mutation" }),
|
|
19850
19854
|
/**
|
|
19851
19855
|
* Batched run — N raw frames packed into one cap call. The provider
|
|
@@ -19863,7 +19867,20 @@ var pipelineExecutorCapability = {
|
|
|
19863
19867
|
steps: external_exports.array(PipelineStepInputSchema).min(1),
|
|
19864
19868
|
frames: external_exports.array(FrameInputSchema).min(1).max(255),
|
|
19865
19869
|
deviceId: external_exports.number().optional(),
|
|
19866
|
-
sessionId: external_exports.string().optional()
|
|
19870
|
+
sessionId: external_exports.string().optional(),
|
|
19871
|
+
/**
|
|
19872
|
+
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
19873
|
+
* the batch to the Python pool's bench preprocess cache
|
|
19874
|
+
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
19875
|
+
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
19876
|
+
* hit — the sustained-throughput run measures inference, not
|
|
19877
|
+
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
19878
|
+
* full preprocess every call, correct). Fresh per sustained run;
|
|
19879
|
+
* released via `uncacheFrame`.
|
|
19880
|
+
*/
|
|
19881
|
+
frameId: external_exports.number().int().nonnegative().optional(),
|
|
19882
|
+
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
19883
|
+
deviceKey: external_exports.string().optional()
|
|
19867
19884
|
}), external_exports.object({ results: external_exports.array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }),
|
|
19868
19885
|
/**
|
|
19869
19886
|
* Cache a raw frame inside the Python inference pool's memory.
|
|
@@ -19920,8 +19937,18 @@ var pipelineExecutorCapability = {
|
|
|
19920
19937
|
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
19921
19938
|
* - `warm-override` — benchmark/test override held in the warm
|
|
19922
19939
|
* cache; auto-disposed after the idle TTL.
|
|
19940
|
+
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
19941
|
+
* multi-device, keyed by `deviceKey`) resolved
|
|
19942
|
+
* via `resolveDeviceFactory`. Runs alongside the
|
|
19943
|
+
* `runtime` engine on a DIFFERENT accelerator
|
|
19944
|
+
* (NPU / iGPU / Coral) — this is how the
|
|
19945
|
+
* Engines tab shows all pools running at once.
|
|
19923
19946
|
*/
|
|
19924
|
-
kind: external_exports.enum([
|
|
19947
|
+
kind: external_exports.enum([
|
|
19948
|
+
"runtime",
|
|
19949
|
+
"warm-override",
|
|
19950
|
+
"device-pool"
|
|
19951
|
+
]),
|
|
19925
19952
|
/** Native pid of the underlying Python pool (null when no pool). */
|
|
19926
19953
|
poolPid: external_exports.number().nullable(),
|
|
19927
19954
|
/** ms since this factory was last used (null when not warm-tracked). */
|
|
@@ -20026,7 +20053,21 @@ var NativeCropResultSchema = external_exports.object({
|
|
|
20026
20053
|
/** Packed rgb (24-bit) pixels of the crop. */
|
|
20027
20054
|
bytes: external_exports.instanceof(Uint8Array),
|
|
20028
20055
|
width: external_exports.number().int().positive(),
|
|
20029
|
-
height: external_exports.number().int().positive()
|
|
20056
|
+
height: external_exports.number().int().positive(),
|
|
20057
|
+
/**
|
|
20058
|
+
* Which source served this crop, so a quality-sensitive consumer (the native
|
|
20059
|
+
* `keyFrame`) can reject a degraded fallback:
|
|
20060
|
+
* - `native` — cut from the decode worker's retained NATIVE surface (the
|
|
20061
|
+
* quality path).
|
|
20062
|
+
* - `ram-fullframe` — the native surface MISSED but the request was full-frame,
|
|
20063
|
+
* so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
|
|
20064
|
+
* the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
|
|
20065
|
+
*
|
|
20066
|
+
* OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
|
|
20067
|
+
* treated as `native` (accepted) by every consumer so mixed-version clusters
|
|
20068
|
+
* keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
|
|
20069
|
+
*/
|
|
20070
|
+
tier: external_exports.enum(["native", "ram-fullframe"]).optional()
|
|
20030
20071
|
});
|
|
20031
20072
|
var DetailParentSchema = external_exports.object({
|
|
20032
20073
|
bbox: NativeCropBboxSchema,
|
|
@@ -20194,7 +20235,14 @@ var RunnerCameraConfigSchema = external_exports.object({
|
|
|
20194
20235
|
* camera's detect node differs from its source-owner (P2d, gated by the
|
|
20195
20236
|
* `remoteSourcingNodes` rollout setting).
|
|
20196
20237
|
*/
|
|
20197
|
-
frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
|
|
20238
|
+
frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
|
|
20239
|
+
/**
|
|
20240
|
+
* Inference-device selector for this camera's sessions (Phase 2 multi-device).
|
|
20241
|
+
* Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
|
|
20242
|
+
* omitted ⇒ the runner's default device. The engine itself stays node-local —
|
|
20243
|
+
* this only selects WHICH device pool of that node runs the session.
|
|
20244
|
+
*/
|
|
20245
|
+
deviceKey: external_exports.string().optional()
|
|
20198
20246
|
});
|
|
20199
20247
|
var RunnerCameraDeviceUIFields = [
|
|
20200
20248
|
{
|
|
@@ -20319,6 +20367,19 @@ var RunnerLocalLoadSchema = external_exports.object({
|
|
|
20319
20367
|
avgInferenceTimeMs: external_exports.number(),
|
|
20320
20368
|
/** Total queue depth across motion + detection queues. */
|
|
20321
20369
|
queueDepthTotal: external_exports.number(),
|
|
20370
|
+
/**
|
|
20371
|
+
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
20372
|
+
* this runner currently has attached cameras on, so the orchestrator's second
|
|
20373
|
+
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
20374
|
+
* counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
|
|
20375
|
+
* per device is 0 until the pool backlog gets a public accessor (follow-up).
|
|
20376
|
+
*/
|
|
20377
|
+
devices: external_exports.array(external_exports.object({
|
|
20378
|
+
deviceKey: external_exports.string(),
|
|
20379
|
+
backend: external_exports.string(),
|
|
20380
|
+
attachedCameras: external_exports.number(),
|
|
20381
|
+
queueDepthTotal: external_exports.number()
|
|
20382
|
+
})).default([]),
|
|
20322
20383
|
/** Hardware capability flags reported by this node. */
|
|
20323
20384
|
hardware: external_exports.object({
|
|
20324
20385
|
hasGpu: external_exports.boolean(),
|
|
@@ -20373,10 +20434,15 @@ var pipelineRunnerCapability = {
|
|
|
20373
20434
|
* `FrameHandle` that rode an inference-result event and a normalized `bbox`,
|
|
20374
20435
|
* the runner asks the decode worker still holding that frame's NATIVE
|
|
20375
20436
|
* surface to GPU/CPU-crop ONLY the ROI at native res and download just the
|
|
20376
|
-
* crop.
|
|
20377
|
-
*
|
|
20378
|
-
*
|
|
20379
|
-
*
|
|
20437
|
+
* crop. Routed to the frame's owning node by `handle.nodeId`; NEVER ships a
|
|
20438
|
+
* full native frame.
|
|
20439
|
+
*
|
|
20440
|
+
* Miss behaviour differs by request shape (see `NativeCropResultSchema.tier`):
|
|
20441
|
+
* - an ROI (subject-crop) miss returns `null` — the caller reports the miss
|
|
20442
|
+
* and retries; it is NEVER handed a ≤640 crop masquerading as native.
|
|
20443
|
+
* - a FULL-FRAME miss falls back to the ≤640 RAM `RetainedFrameStore`, tagged
|
|
20444
|
+
* `tier: 'ram-fullframe'` (honest lower-res for the blank-frame guard /
|
|
20445
|
+
* 640-snapshot resolve). A native hit is tagged `tier: 'native'`.
|
|
20380
20446
|
*/
|
|
20381
20447
|
getNativeCrop: method(external_exports.object({
|
|
20382
20448
|
handle: FrameHandleSchema,
|
|
@@ -22501,6 +22567,40 @@ var deviceProviderCapability = {
|
|
|
22501
22567
|
})
|
|
22502
22568
|
}
|
|
22503
22569
|
};
|
|
22570
|
+
var DEVICE_TYPE_CONTROL_KIND = {
|
|
22571
|
+
[DeviceType.Cover]: "cover",
|
|
22572
|
+
[DeviceType.Valve]: "valve",
|
|
22573
|
+
[DeviceType.Humidifier]: "humidifier",
|
|
22574
|
+
[DeviceType.WaterHeater]: "water-heater",
|
|
22575
|
+
[DeviceType.Camera]: "dummy",
|
|
22576
|
+
[DeviceType.Hub]: "dummy",
|
|
22577
|
+
[DeviceType.Switch]: "switch",
|
|
22578
|
+
[DeviceType.Siren]: "switch",
|
|
22579
|
+
[DeviceType.Light]: "light",
|
|
22580
|
+
[DeviceType.Fan]: "fan",
|
|
22581
|
+
[DeviceType.Sensor]: "sensor",
|
|
22582
|
+
[DeviceType.Thermostat]: "thermostat",
|
|
22583
|
+
[DeviceType.Climate]: "climate",
|
|
22584
|
+
[DeviceType.Button]: "button",
|
|
22585
|
+
[DeviceType.EventEmitter]: "dummy",
|
|
22586
|
+
[DeviceType.Update]: "update",
|
|
22587
|
+
[DeviceType.Generic]: "dummy",
|
|
22588
|
+
[DeviceType.Notifier]: "dummy",
|
|
22589
|
+
[DeviceType.Script]: "dummy",
|
|
22590
|
+
[DeviceType.Automation]: "dummy",
|
|
22591
|
+
[DeviceType.Lock]: "lock",
|
|
22592
|
+
[DeviceType.MediaPlayer]: "media-player",
|
|
22593
|
+
[DeviceType.AlarmPanel]: "alarm",
|
|
22594
|
+
[DeviceType.Control]: "control",
|
|
22595
|
+
[DeviceType.Presence]: "sensor",
|
|
22596
|
+
[DeviceType.Weather]: "weather",
|
|
22597
|
+
[DeviceType.Vacuum]: "vacuum",
|
|
22598
|
+
[DeviceType.LawnMower]: "lawn-mower",
|
|
22599
|
+
[DeviceType.Container]: "dummy",
|
|
22600
|
+
[DeviceType.Image]: "image",
|
|
22601
|
+
[DeviceType.PetFeeder]: "pet-feeder"
|
|
22602
|
+
};
|
|
22603
|
+
var DEVICE_TYPE_VALUES = new Set(Object.values(DeviceType));
|
|
22504
22604
|
var AddonPageDeclarationSchema$1 = external_exports.object({
|
|
22505
22605
|
id: external_exports.string(),
|
|
22506
22606
|
label: external_exports.string(),
|
|
@@ -24065,7 +24165,8 @@ var LinkedDeviceSchema = external_exports.object({
|
|
|
24065
24165
|
deviceId: external_exports.number(),
|
|
24066
24166
|
name: external_exports.string(),
|
|
24067
24167
|
location: external_exports.string().nullable(),
|
|
24068
|
-
features: external_exports.array(external_exports.string())
|
|
24168
|
+
features: external_exports.array(external_exports.string()),
|
|
24169
|
+
producesTrackedEvents: external_exports.boolean().optional()
|
|
24069
24170
|
});
|
|
24070
24171
|
var SavedDeviceRowSchema = external_exports.object({
|
|
24071
24172
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
@@ -25982,6 +26083,7 @@ var TrackSchema = external_exports.object({
|
|
|
25982
26083
|
deviceId: external_exports.number(),
|
|
25983
26084
|
className: external_exports.string(),
|
|
25984
26085
|
label: external_exports.string().optional(),
|
|
26086
|
+
producingDeviceName: external_exports.string().optional(),
|
|
25985
26087
|
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
25986
26088
|
source: TrackSourceSchema.optional(),
|
|
25987
26089
|
firstSeen: external_exports.number(),
|
|
@@ -26111,7 +26213,8 @@ var MediaFileKindEnum = external_exports.enum([
|
|
|
26111
26213
|
"fullFrameBoxed",
|
|
26112
26214
|
"faceCrop",
|
|
26113
26215
|
"plateCrop",
|
|
26114
|
-
"keyFrame"
|
|
26216
|
+
"keyFrame",
|
|
26217
|
+
"keyFrameSmall"
|
|
26115
26218
|
]);
|
|
26116
26219
|
var MediaFileSchema = external_exports.object({
|
|
26117
26220
|
key: external_exports.string(),
|
|
@@ -26570,13 +26673,11 @@ var PipelineTemplateSchema = external_exports.object({
|
|
|
26570
26673
|
createdAt: external_exports.string(),
|
|
26571
26674
|
updatedAt: external_exports.string()
|
|
26572
26675
|
});
|
|
26573
|
-
var
|
|
26574
|
-
enabled: external_exports.boolean(),
|
|
26676
|
+
var DeviceStepConfigSchema = external_exports.object({
|
|
26575
26677
|
modelId: external_exports.string().optional(),
|
|
26576
|
-
settings: external_exports.record(external_exports.string(), external_exports.unknown()).
|
|
26678
|
+
settings: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
26577
26679
|
});
|
|
26578
26680
|
var AgentPipelineSettingsSchema = external_exports.object({
|
|
26579
|
-
addonDefaults: external_exports.record(external_exports.string(), AgentAddonConfigSchema).readonly(),
|
|
26580
26681
|
maxCameras: external_exports.number().int().nonnegative().nullable().default(null),
|
|
26581
26682
|
/** Per-node detection weight (relative share for the quota balancer). */
|
|
26582
26683
|
detectWeight: external_exports.number().positive().optional(),
|
|
@@ -26600,7 +26701,22 @@ var AgentPipelineSettingsSchema = external_exports.object({
|
|
|
26600
26701
|
* it already uses to reach the hub). Set this only when the auto-detected
|
|
26601
26702
|
* address is wrong (multi-homed host, NAT, custom interface).
|
|
26602
26703
|
*/
|
|
26603
|
-
reachableHost: external_exports.string().optional()
|
|
26704
|
+
reachableHost: external_exports.string().optional(),
|
|
26705
|
+
/**
|
|
26706
|
+
* Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
|
|
26707
|
+
* weight, steps}. Absent / all-disabled ⇒ the node's single default
|
|
26708
|
+
* accelerator (safe default); two+ enabled ⇒ the dispatcher balances
|
|
26709
|
+
* detection sessions across them so they run CONCURRENTLY. `steps` is the
|
|
26710
|
+
* per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
|
|
26711
|
+
* the default model/settings for every camera landing on that accelerator;
|
|
26712
|
+
* a stepId absent ⇒ the step uses that device's format default.
|
|
26713
|
+
*/
|
|
26714
|
+
inferenceDevices: external_exports.record(external_exports.string(), external_exports.object({
|
|
26715
|
+
enabled: external_exports.boolean(),
|
|
26716
|
+
weight: external_exports.number().positive().optional(),
|
|
26717
|
+
maxSessions: external_exports.number().int().positive().optional(),
|
|
26718
|
+
steps: external_exports.record(external_exports.string(), DeviceStepConfigSchema).optional()
|
|
26719
|
+
})).optional()
|
|
26604
26720
|
});
|
|
26605
26721
|
var CameraPipelineForAgentSchema = external_exports.object({
|
|
26606
26722
|
steps: external_exports.array(PipelineStepInputSchema).readonly(),
|
|
@@ -26610,14 +26726,13 @@ var CameraPipelineForAgentSchema = external_exports.object({
|
|
|
26610
26726
|
}).nullable()
|
|
26611
26727
|
});
|
|
26612
26728
|
var CameraStepOverridePatchSchema = external_exports.object({
|
|
26613
|
-
enabled: external_exports.boolean().optional(),
|
|
26614
26729
|
modelId: external_exports.string().optional(),
|
|
26615
26730
|
settings: external_exports.record(external_exports.string(), external_exports.unknown()).readonly().optional()
|
|
26616
26731
|
});
|
|
26617
26732
|
var CameraPipelineSettingsSchema = external_exports.object({
|
|
26618
26733
|
pinnedAgentNodeId: external_exports.string().optional(),
|
|
26619
26734
|
stepToggles: external_exports.record(external_exports.string(), external_exports.boolean()).optional(),
|
|
26620
|
-
|
|
26735
|
+
stepOverridesByDevice: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema))).optional(),
|
|
26621
26736
|
pipelineByAgent: external_exports.record(external_exports.string(), CameraPipelineForAgentSchema).optional()
|
|
26622
26737
|
});
|
|
26623
26738
|
var PipelineAssignmentSchema = external_exports.object({
|
|
@@ -26783,6 +26898,44 @@ var CameraStatusSchema = external_exports.object({
|
|
|
26783
26898
|
/** Unix timestamp (ms) when this snapshot was composed server-side. */
|
|
26784
26899
|
fetchedAt: external_exports.number()
|
|
26785
26900
|
});
|
|
26901
|
+
var NodeInferenceDeviceSchema = external_exports.object({
|
|
26902
|
+
/** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
|
|
26903
|
+
key: external_exports.string(),
|
|
26904
|
+
backend: external_exports.string(),
|
|
26905
|
+
device: external_exports.string(),
|
|
26906
|
+
format: external_exports.enum(MODEL_FORMATS),
|
|
26907
|
+
/** Whether the node's live probe reports the device as usable right now. */
|
|
26908
|
+
available: external_exports.boolean(),
|
|
26909
|
+
/**
|
|
26910
|
+
* Whether this device participates in dispatch. AUTO default (spec C2):
|
|
26911
|
+
* accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
|
|
26912
|
+
* entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
|
|
26913
|
+
* not a balanced target). An explicit stored value always wins; a stored-only
|
|
26914
|
+
* (unavailable) key keeps its stored value.
|
|
26915
|
+
*/
|
|
26916
|
+
enabled: external_exports.boolean(),
|
|
26917
|
+
/** Relative balancer weight for the enabled device (default 1). */
|
|
26918
|
+
weight: external_exports.number(),
|
|
26919
|
+
/** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
|
|
26920
|
+
maxSessions: external_exports.number().nullable(),
|
|
26921
|
+
/** Object-detection model the executor defaults to for this deviceKey. */
|
|
26922
|
+
defaultModelId: external_exports.string(),
|
|
26923
|
+
/**
|
|
26924
|
+
* Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
|
|
26925
|
+
* `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
|
|
26926
|
+
* Absent/empty ⇒ no base (every step uses its device format default). The
|
|
26927
|
+
* UI cross-references `pipelineExecutor.getSchema` for the models actually
|
|
26928
|
+
* available per format; this is the stored selection that becomes the
|
|
26929
|
+
* default for EVERY camera landing on this accelerator.
|
|
26930
|
+
*/
|
|
26931
|
+
steps: external_exports.record(external_exports.string(), DeviceStepConfigSchema).optional()
|
|
26932
|
+
});
|
|
26933
|
+
var NodeInferenceDevicesSchema = external_exports.object({
|
|
26934
|
+
nodeId: external_exports.string(),
|
|
26935
|
+
/** False when the node's platform-probe was unreachable (no live device set). */
|
|
26936
|
+
reachable: external_exports.boolean(),
|
|
26937
|
+
devices: external_exports.array(NodeInferenceDeviceSchema).readonly()
|
|
26938
|
+
});
|
|
26786
26939
|
var pipelineOrchestratorCapability = {
|
|
26787
26940
|
name: "pipeline-orchestrator",
|
|
26788
26941
|
scope: "system",
|
|
@@ -26820,6 +26973,34 @@ var pipelineOrchestratorCapability = {
|
|
|
26820
26973
|
auth: "admin"
|
|
26821
26974
|
}),
|
|
26822
26975
|
/**
|
|
26976
|
+
* Pin a camera's detection to a specific INFERENCE DEVICE (accelerator)
|
|
26977
|
+
* within its node — a SOFT L1 device affinity honoured by the per-session
|
|
26978
|
+
* device `balance()` pass (sibling of the node-level `pipelineNodeId` pin;
|
|
26979
|
+
* persisted as `pipelineDeviceKey` in the device store, read by
|
|
26980
|
+
* `readPipelineDevicePin`). `deviceKey` is a concrete key
|
|
26981
|
+
* (`openvino:npu` / `edgetpu:usb` / `cpu`), or the `'auto'` sentinel /
|
|
26982
|
+
* empty string to CLEAR the pin and let the balancer pick the device.
|
|
26983
|
+
*
|
|
26984
|
+
* Applies promptly: the device is chosen per-session at dispatch, so any
|
|
26985
|
+
* running detection session is closed and re-dispatched onto the new pin
|
|
26986
|
+
* (the camera stays on the SAME node — a device pin never moves the camera).
|
|
26987
|
+
* Cameras with no active session pick it up on their next dispatch.
|
|
26988
|
+
*/
|
|
26989
|
+
setPipelineDevicePin: method(external_exports.object({
|
|
26990
|
+
deviceId: external_exports.number(),
|
|
26991
|
+
deviceKey: external_exports.string()
|
|
26992
|
+
}), external_exports.object({ success: external_exports.literal(true) }), {
|
|
26993
|
+
kind: "mutation",
|
|
26994
|
+
auth: "admin"
|
|
26995
|
+
}),
|
|
26996
|
+
/**
|
|
26997
|
+
* Read a camera's persisted inference-device pin (`pipelineDeviceKey`).
|
|
26998
|
+
* Returns the concrete device key, or `null` when unpinned (auto). Lets the
|
|
26999
|
+
* UI show the current pin alongside the node pin (parity with the node-pin
|
|
27000
|
+
* value carried on the assignment record).
|
|
27001
|
+
*/
|
|
27002
|
+
getPipelineDevicePin: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.object({ deviceKey: external_exports.string().nullable() })),
|
|
27003
|
+
/**
|
|
26823
27004
|
* Trigger a full rebalance pass. Iterates over all assigned cameras,
|
|
26824
27005
|
* recomputes the optimal agent for each one based on current load +
|
|
26825
27006
|
* hardware affinity, and migrates cameras whose current agent is no
|
|
@@ -26904,14 +27085,6 @@ var pipelineOrchestratorCapability = {
|
|
|
26904
27085
|
nodeId: external_exports.string(),
|
|
26905
27086
|
settings: AgentPipelineSettingsSchema
|
|
26906
27087
|
})).readonly()),
|
|
26907
|
-
/** Bulk-replace ALL addon configs on one agent. Used by the agent-level PipelineEditor which emits the full map per edit. Merges on top of existing entries — omitted addonIds are left alone. */
|
|
26908
|
-
setAgentAddonDefaults: method(external_exports.object({
|
|
26909
|
-
agentNodeId: external_exports.string(),
|
|
26910
|
-
defaults: external_exports.record(external_exports.string(), AgentAddonConfigSchema)
|
|
26911
|
-
}), external_exports.object({ success: external_exports.literal(true) }), {
|
|
26912
|
-
kind: "mutation",
|
|
26913
|
-
auth: "admin"
|
|
26914
|
-
}),
|
|
26915
27088
|
/**
|
|
26916
27089
|
* Drop a single agent's persisted settings. Used by the cluster
|
|
26917
27090
|
* "Offline agents" panel to evict stale entries left behind when an
|
|
@@ -26998,6 +27171,46 @@ var pipelineOrchestratorCapability = {
|
|
|
26998
27171
|
auth: "admin"
|
|
26999
27172
|
}),
|
|
27000
27173
|
/**
|
|
27174
|
+
* Set one node's multi-device inference opt-in (Phase 4 multi-device) — the
|
|
27175
|
+
* per-node `deviceKey → { enabled, weight }` map that decides which
|
|
27176
|
+
* accelerators the dispatcher may balance detection sessions across.
|
|
27177
|
+
* The map REPLACES the node's stored `inferenceDevices` wholesale (pass the
|
|
27178
|
+
* complete desired set; an empty map clears the opt-in → the node reverts to
|
|
27179
|
+
* its single DEFAULT accelerator). `weight` is optional and defaults to 1.
|
|
27180
|
+
* `models` is the optional per-device model override (`stepId → modelId`,
|
|
27181
|
+
* C7.2/C7.4) — a stepId absent ⇒ the step uses that device's default model.
|
|
27182
|
+
* Creates the node's settings entry if absent. Changes take effect on the
|
|
27183
|
+
* next dispatch/rebalance cycle — the dispatcher reads the enabled set via
|
|
27184
|
+
* `PipelineSettingsStore.buildNodeInferenceDevices` when placing sessions
|
|
27185
|
+
* and the per-(node,device) base provisioning via
|
|
27186
|
+
* `buildNodeInferenceDeviceSteps`.
|
|
27187
|
+
*/
|
|
27188
|
+
setAgentInferenceDevices: method(external_exports.object({
|
|
27189
|
+
agentNodeId: external_exports.string(),
|
|
27190
|
+
inferenceDevices: external_exports.record(external_exports.string(), external_exports.object({
|
|
27191
|
+
enabled: external_exports.boolean(),
|
|
27192
|
+
weight: external_exports.number().positive().optional(),
|
|
27193
|
+
maxSessions: external_exports.number().int().positive().optional(),
|
|
27194
|
+
steps: external_exports.record(external_exports.string(), DeviceStepConfigSchema).optional()
|
|
27195
|
+
}))
|
|
27196
|
+
}), external_exports.object({ success: external_exports.literal(true) }), {
|
|
27197
|
+
kind: "mutation",
|
|
27198
|
+
auth: "admin"
|
|
27199
|
+
}),
|
|
27200
|
+
/**
|
|
27201
|
+
* DEVICE-AWARE merged view of ONE node's inference accelerators. Joins each
|
|
27202
|
+
* physical device the node HAS — probed live via a node-pinned
|
|
27203
|
+
* `platformProbe.getCapabilities` (the platform-probe singleton is targeted
|
|
27204
|
+
* by the `nodeId` cap INPUT, since a `nodePin` context is ignored by a
|
|
27205
|
+
* singleton mount) — with its stored opt-in (`enabled`/`weight`) and the
|
|
27206
|
+
* object-detection `defaultModelId` the executor would run for that
|
|
27207
|
+
* deviceKey. Disabled-but-configured keys still appear. An unreachable node
|
|
27208
|
+
* returns `reachable:false` + best-effort stored-only devices (never
|
|
27209
|
+
* throws). Read surface for the cluster/agent multi-device UI — hence a
|
|
27210
|
+
* default (read-level) auth, matching the other `getAgent*` reads.
|
|
27211
|
+
*/
|
|
27212
|
+
getNodeInferenceDevices: method(external_exports.object({ nodeId: external_exports.string() }), NodeInferenceDevicesSchema),
|
|
27213
|
+
/**
|
|
27001
27214
|
* Reset one node's pipeline to its hardware-aware defaults — the HONEST
|
|
27002
27215
|
* reset (replaces the executor's legacy `resetToDefault`, which cleared a
|
|
27003
27216
|
* dead persisted step-tree seed nothing in the live path read):
|
|
@@ -27036,15 +27249,18 @@ var pipelineOrchestratorCapability = {
|
|
|
27036
27249
|
kind: "mutation",
|
|
27037
27250
|
auth: "admin"
|
|
27038
27251
|
}),
|
|
27039
|
-
/** Read every
|
|
27040
|
-
getCameraStepOverrides: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema)).nullable()),
|
|
27252
|
+
/** Read every per-(node,device) override map for a device. Null when device has no overrides. */
|
|
27253
|
+
getCameraStepOverrides: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema))).nullable()),
|
|
27041
27254
|
/**
|
|
27042
|
-
* Write or clear the
|
|
27043
|
-
* `patch: null` clears the entry entirely for that (
|
|
27255
|
+
* Write or clear the per-(camera,node,device) override for one addonId.
|
|
27256
|
+
* `patch: null` clears the entry entirely for that (node, deviceKey, addon)
|
|
27257
|
+
* triple (empty parents are pruned). Model/settings only — enablement is
|
|
27258
|
+
* the per-camera `stepToggles` authority.
|
|
27044
27259
|
*/
|
|
27045
27260
|
setCameraStepOverride: method(external_exports.object({
|
|
27046
27261
|
deviceId: external_exports.number(),
|
|
27047
27262
|
agentNodeId: external_exports.string(),
|
|
27263
|
+
deviceKey: external_exports.string(),
|
|
27048
27264
|
addonId: external_exports.string(),
|
|
27049
27265
|
patch: CameraStepOverridePatchSchema.nullable()
|
|
27050
27266
|
}), external_exports.object({ success: external_exports.literal(true) }), {
|
|
@@ -27197,7 +27413,8 @@ var serverManagementCapability = {
|
|
|
27197
27413
|
version: external_exports.string().optional()
|
|
27198
27414
|
}), ServerUpdateActionResultSchema, {
|
|
27199
27415
|
kind: "mutation",
|
|
27200
|
-
auth: "admin"
|
|
27416
|
+
auth: "admin",
|
|
27417
|
+
timeoutMs: 16 * 6e4
|
|
27201
27418
|
}),
|
|
27202
27419
|
rollbackServerUpdate: method(external_exports.void(), ServerUpdateActionResultSchema, {
|
|
27203
27420
|
kind: "mutation",
|
|
@@ -28389,13 +28606,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
28389
28606
|
var RestartAddonResultSchema = external_exports.unknown();
|
|
28390
28607
|
var InstallPackageResultSchema = external_exports.unknown();
|
|
28391
28608
|
var ReloadPackagesResultSchema = external_exports.unknown();
|
|
28392
|
-
var UpdateFrameworkPackageResultSchema = external_exports.object({
|
|
28393
|
-
packageName: external_exports.string(),
|
|
28394
|
-
fromVersion: external_exports.string(),
|
|
28395
|
-
toVersion: external_exports.string(),
|
|
28396
|
-
/** Ms-epoch the server scheduled its self-restart. */
|
|
28397
|
-
restartingAt: external_exports.number()
|
|
28398
|
-
});
|
|
28399
28609
|
var BulkUpdateItemStatusSchema = external_exports.enum([
|
|
28400
28610
|
"queued",
|
|
28401
28611
|
"updating",
|
|
@@ -28623,28 +28833,6 @@ var addonsCapability = {
|
|
|
28623
28833
|
kind: "mutation",
|
|
28624
28834
|
auth: "admin"
|
|
28625
28835
|
}),
|
|
28626
|
-
/**
|
|
28627
|
-
* Live-update one of the framework packages marked
|
|
28628
|
-
* `camstack.system: true` (`@camstack/types|kernel|core|sdk|ui-library`).
|
|
28629
|
-
* Runs `npm install --prefix <appRoot> <name>@<version> --no-save`,
|
|
28630
|
-
* writes a `.restart-pending` marker, emits `system.restarting`
|
|
28631
|
-
* and schedules a graceful process exit. The supervisor (Docker /
|
|
28632
|
-
* Electron / systemd) brings the hub back up; on first boot after
|
|
28633
|
-
* the restart the marker fires `system.restart-completed`.
|
|
28634
|
-
*
|
|
28635
|
-
* `version` defaults to `'latest'`. The allow-list of valid
|
|
28636
|
-
* `packageName` values is enforced server-side.
|
|
28637
|
-
*
|
|
28638
|
-
* Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
|
|
28639
|
-
*/
|
|
28640
|
-
updateFrameworkPackage: method(external_exports.object({
|
|
28641
|
-
packageName: external_exports.string().min(1),
|
|
28642
|
-
version: external_exports.string().optional(),
|
|
28643
|
-
deferRestart: external_exports.boolean().optional()
|
|
28644
|
-
}), UpdateFrameworkPackageResultSchema, {
|
|
28645
|
-
kind: "mutation",
|
|
28646
|
-
auth: "admin"
|
|
28647
|
-
}),
|
|
28648
28836
|
getVersions: method(external_exports.object({ name: external_exports.string() }), external_exports.array(PackageVersionInfoSchema).readonly()),
|
|
28649
28837
|
restartAddon: method(external_exports.object({ addonId: external_exports.string() }), RestartAddonResultSchema, {
|
|
28650
28838
|
kind: "mutation",
|
|
@@ -30140,17 +30328,28 @@ var PlatformScoreSchema = external_exports.object({
|
|
|
30140
30328
|
format: external_exports.enum([
|
|
30141
30329
|
"onnx",
|
|
30142
30330
|
"coreml",
|
|
30143
|
-
"openvino"
|
|
30331
|
+
"openvino",
|
|
30332
|
+
"tflite"
|
|
30144
30333
|
]),
|
|
30145
30334
|
score: external_exports.number(),
|
|
30146
30335
|
reason: external_exports.string(),
|
|
30147
30336
|
available: external_exports.boolean()
|
|
30148
30337
|
});
|
|
30338
|
+
var InferenceDeviceDescriptorSchema = external_exports.object({
|
|
30339
|
+
key: external_exports.string(),
|
|
30340
|
+
backend: external_exports.string(),
|
|
30341
|
+
device: external_exports.string(),
|
|
30342
|
+
format: ModelFormatSchema,
|
|
30343
|
+
runtime: external_exports.literal("python"),
|
|
30344
|
+
score: external_exports.number(),
|
|
30345
|
+
available: external_exports.boolean()
|
|
30346
|
+
});
|
|
30149
30347
|
var PlatformCapabilitiesSchema = external_exports.object({
|
|
30150
30348
|
hardware: HardwareInfoSchema,
|
|
30151
30349
|
scores: external_exports.array(PlatformScoreSchema).readonly(),
|
|
30152
30350
|
bestScore: PlatformScoreSchema,
|
|
30153
|
-
pythonPath: external_exports.string().nullable()
|
|
30351
|
+
pythonPath: external_exports.string().nullable(),
|
|
30352
|
+
devices: external_exports.array(InferenceDeviceDescriptorSchema).readonly()
|
|
30154
30353
|
});
|
|
30155
30354
|
var ModelRequirementSchema = external_exports.object({
|
|
30156
30355
|
modelId: external_exports.string(),
|
|
@@ -31122,12 +31321,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31122
31321
|
addonId: null,
|
|
31123
31322
|
access: "delete"
|
|
31124
31323
|
},
|
|
31125
|
-
"addons.updateFrameworkPackage": {
|
|
31126
|
-
capName: "addons",
|
|
31127
|
-
capScope: "system",
|
|
31128
|
-
addonId: null,
|
|
31129
|
-
access: "create"
|
|
31130
|
-
},
|
|
31131
31324
|
"addons.updatePackage": {
|
|
31132
31325
|
capName: "addons",
|
|
31133
31326
|
capScope: "system",
|
|
@@ -33900,12 +34093,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
33900
34093
|
addonId: null,
|
|
33901
34094
|
access: "view"
|
|
33902
34095
|
},
|
|
33903
|
-
"pipelineExecutor.reprobeEngine": {
|
|
33904
|
-
capName: "pipeline-executor",
|
|
33905
|
-
capScope: "system",
|
|
33906
|
-
addonId: null,
|
|
33907
|
-
access: "create"
|
|
33908
|
-
},
|
|
33909
34096
|
"pipelineExecutor.runAudioTest": {
|
|
33910
34097
|
capName: "pipeline-executor",
|
|
33911
34098
|
capScope: "system",
|
|
@@ -34056,6 +34243,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34056
34243
|
addonId: null,
|
|
34057
34244
|
access: "view"
|
|
34058
34245
|
},
|
|
34246
|
+
"pipelineOrchestrator.getNodeInferenceDevices": {
|
|
34247
|
+
capName: "pipeline-orchestrator",
|
|
34248
|
+
capScope: "system",
|
|
34249
|
+
addonId: null,
|
|
34250
|
+
access: "view"
|
|
34251
|
+
},
|
|
34059
34252
|
"pipelineOrchestrator.getPipelineAssignment": {
|
|
34060
34253
|
capName: "pipeline-orchestrator",
|
|
34061
34254
|
capScope: "system",
|
|
@@ -34068,6 +34261,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34068
34261
|
addonId: null,
|
|
34069
34262
|
access: "view"
|
|
34070
34263
|
},
|
|
34264
|
+
"pipelineOrchestrator.getPipelineDevicePin": {
|
|
34265
|
+
capName: "pipeline-orchestrator",
|
|
34266
|
+
capScope: "system",
|
|
34267
|
+
addonId: null,
|
|
34268
|
+
access: "view"
|
|
34269
|
+
},
|
|
34071
34270
|
"pipelineOrchestrator.listAgentSettings": {
|
|
34072
34271
|
capName: "pipeline-orchestrator",
|
|
34073
34272
|
capScope: "system",
|
|
@@ -34110,19 +34309,19 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34110
34309
|
addonId: null,
|
|
34111
34310
|
access: "create"
|
|
34112
34311
|
},
|
|
34113
|
-
"pipelineOrchestrator.
|
|
34312
|
+
"pipelineOrchestrator.setAgentCapabilities": {
|
|
34114
34313
|
capName: "pipeline-orchestrator",
|
|
34115
34314
|
capScope: "system",
|
|
34116
34315
|
addonId: null,
|
|
34117
34316
|
access: "create"
|
|
34118
34317
|
},
|
|
34119
|
-
"pipelineOrchestrator.
|
|
34318
|
+
"pipelineOrchestrator.setAgentDetectWeight": {
|
|
34120
34319
|
capName: "pipeline-orchestrator",
|
|
34121
34320
|
capScope: "system",
|
|
34122
34321
|
addonId: null,
|
|
34123
34322
|
access: "create"
|
|
34124
34323
|
},
|
|
34125
|
-
"pipelineOrchestrator.
|
|
34324
|
+
"pipelineOrchestrator.setAgentInferenceDevices": {
|
|
34126
34325
|
capName: "pipeline-orchestrator",
|
|
34127
34326
|
capScope: "system",
|
|
34128
34327
|
addonId: null,
|
|
@@ -34164,6 +34363,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34164
34363
|
addonId: null,
|
|
34165
34364
|
access: "create"
|
|
34166
34365
|
},
|
|
34366
|
+
"pipelineOrchestrator.setPipelineDevicePin": {
|
|
34367
|
+
capName: "pipeline-orchestrator",
|
|
34368
|
+
capScope: "system",
|
|
34369
|
+
addonId: null,
|
|
34370
|
+
access: "create"
|
|
34371
|
+
},
|
|
34167
34372
|
"pipelineOrchestrator.unassignAudio": {
|
|
34168
34373
|
capName: "pipeline-orchestrator",
|
|
34169
34374
|
capScope: "system",
|
|
@@ -35716,32 +35921,6 @@ var CAP_PROVIDER_KIND_MAP = Object.freeze({
|
|
|
35716
35921
|
"network-access": "ingress",
|
|
35717
35922
|
"smtp-provider": "email"
|
|
35718
35923
|
});
|
|
35719
|
-
var frameworkSwapPackageSchema = external_exports.object({
|
|
35720
|
-
name: external_exports.string(),
|
|
35721
|
-
stagedPath: external_exports.string(),
|
|
35722
|
-
backupPath: external_exports.string(),
|
|
35723
|
-
toVersion: external_exports.string(),
|
|
35724
|
-
fromVersion: external_exports.string().nullable()
|
|
35725
|
-
});
|
|
35726
|
-
var pendingFrameworkSwapSchema = external_exports.object({
|
|
35727
|
-
jobId: external_exports.string(),
|
|
35728
|
-
taskId: external_exports.string(),
|
|
35729
|
-
packages: external_exports.array(frameworkSwapPackageSchema),
|
|
35730
|
-
requestedAtMs: external_exports.number(),
|
|
35731
|
-
schemaVersion: external_exports.literal(1)
|
|
35732
|
-
});
|
|
35733
|
-
var frameworkSwapConfirmSchema = external_exports.object({
|
|
35734
|
-
jobId: external_exports.string(),
|
|
35735
|
-
taskId: external_exports.string(),
|
|
35736
|
-
backups: external_exports.array(external_exports.object({
|
|
35737
|
-
name: external_exports.string(),
|
|
35738
|
-
backupPath: external_exports.string(),
|
|
35739
|
-
livePath: external_exports.string()
|
|
35740
|
-
})),
|
|
35741
|
-
appliedAtMs: external_exports.number(),
|
|
35742
|
-
bootAttempts: external_exports.number(),
|
|
35743
|
-
schemaVersion: external_exports.literal(1)
|
|
35744
|
-
});
|
|
35745
35924
|
|
|
35746
35925
|
// src/commands/discover.ts
|
|
35747
35926
|
var DEFAULT_MULTICAST_GROUP = "239.0.0.0";
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runDiscover
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UW26FXNH.js";
|
|
5
5
|
import "./chunk-K3NQKI34.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
@@ -1079,7 +1079,7 @@ function isUnknown(_value) {
|
|
|
1079
1079
|
return true;
|
|
1080
1080
|
}
|
|
1081
1081
|
async function resolveServerInteractive(presetNamespace) {
|
|
1082
|
-
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-
|
|
1082
|
+
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-YZCMQEZ5.js");
|
|
1083
1083
|
if (presetNamespace) {
|
|
1084
1084
|
const spinner4 = clack.spinner();
|
|
1085
1085
|
spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
|