@camstack/addon-pipeline-orchestrator 1.2.638 → 1.2.639
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/assets/viewer/.viewer-current-files.json +2 -2
- package/assets/viewer/.viewer-version +1 -1
- package/assets/viewer/_expo/static/js/web/{__common-6206f99c82ca608b8620797fed9685e4.js → __common-987325b06b59d95030dfaa48ed6559b0.js} +43 -43
- package/assets/viewer/_expo/static/js/web/{index-7e427fd375381d1d43da28a24697dd03.js → index-0134483fbf5fd90d22b3febd6bd0cc64.js} +2 -2
- package/assets/viewer/index.html +1 -1
- package/dist/_stub.js +2 -2
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-Hya6JCSL.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CpDS4Ilu.mjs} +2 -2
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CYNe1S9x.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CMKrpGjd.mjs +26 -0
- package/dist/{hostInit-BWrAZ8UU.mjs → hostInit-DY3NVnRS.mjs} +2 -2
- package/dist/index.js +507 -24
- package/dist/index.mjs +507 -24
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/assets/viewer/_expo/static/js/web/[id]-d3b1d7a725fa2a1af0839ac46985eb3d.js +0 -7
- package/assets/viewer/_expo/static/js/web/[id]-ed4f5ea7c5329aa67a79c94da84ba024.js +0 -5
- package/assets/viewer/_expo/static/js/web/[section]-0eef3af480ef1910eed719cf82530d92.js +0 -31
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BlL4i123.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DW9I9T44.mjs +0 -26
package/dist/index.mjs
CHANGED
|
@@ -5583,7 +5583,7 @@ var ZodIssueCode = {
|
|
|
5583
5583
|
var ZodFirstPartyTypeKind;
|
|
5584
5584
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5585
5585
|
//#endregion
|
|
5586
|
-
//#region ../types/dist/sleep-
|
|
5586
|
+
//#region ../types/dist/sleep-C_u6cEAJ.mjs
|
|
5587
5587
|
/**
|
|
5588
5588
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5589
5589
|
* window to float samples (D455).
|
|
@@ -9531,6 +9531,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9531
9531
|
"network-link",
|
|
9532
9532
|
"network-quality",
|
|
9533
9533
|
"node-certificates",
|
|
9534
|
+
"node-removal-hook",
|
|
9534
9535
|
"nodes",
|
|
9535
9536
|
"notification-output",
|
|
9536
9537
|
"notification-rules",
|
|
@@ -9561,6 +9562,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9561
9562
|
"recording-onboard",
|
|
9562
9563
|
"recording-signal",
|
|
9563
9564
|
"records",
|
|
9565
|
+
"remote",
|
|
9564
9566
|
"running-state",
|
|
9565
9567
|
"scene-monitor",
|
|
9566
9568
|
"script-runner",
|
|
@@ -9584,6 +9586,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9584
9586
|
"system",
|
|
9585
9587
|
"tamper",
|
|
9586
9588
|
"temperature-sensor",
|
|
9589
|
+
"template",
|
|
9587
9590
|
"terminal-session",
|
|
9588
9591
|
"toast",
|
|
9589
9592
|
"training",
|
|
@@ -10524,6 +10527,11 @@ Object.freeze({
|
|
|
10524
10527
|
"standby"
|
|
10525
10528
|
]
|
|
10526
10529
|
},
|
|
10530
|
+
{
|
|
10531
|
+
"path": "stateSource",
|
|
10532
|
+
"valueType": "enum",
|
|
10533
|
+
"enumValues": ["reported", "assumed"]
|
|
10534
|
+
},
|
|
10527
10535
|
{
|
|
10528
10536
|
"path": "volumeLevel",
|
|
10529
10537
|
"valueType": "number"
|
|
@@ -10799,6 +10807,18 @@ Object.freeze({
|
|
|
10799
10807
|
{
|
|
10800
10808
|
"path": "volume",
|
|
10801
10809
|
"valueType": "number"
|
|
10810
|
+
},
|
|
10811
|
+
{
|
|
10812
|
+
"path": "lastFeedGrams",
|
|
10813
|
+
"valueType": "number"
|
|
10814
|
+
},
|
|
10815
|
+
{
|
|
10816
|
+
"path": "lastFeedHopper1",
|
|
10817
|
+
"valueType": "number"
|
|
10818
|
+
},
|
|
10819
|
+
{
|
|
10820
|
+
"path": "lastFeedHopper2",
|
|
10821
|
+
"valueType": "number"
|
|
10802
10822
|
}
|
|
10803
10823
|
],
|
|
10804
10824
|
"power-meter": [
|
|
@@ -11724,7 +11744,7 @@ function errMsg$2(err) {
|
|
|
11724
11744
|
return String(err);
|
|
11725
11745
|
}
|
|
11726
11746
|
//#endregion
|
|
11727
|
-
//#region ../types/dist/composition-
|
|
11747
|
+
//#region ../types/dist/composition-bIBW5_13.mjs
|
|
11728
11748
|
/**
|
|
11729
11749
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11730
11750
|
*
|
|
@@ -43824,6 +43844,14 @@ method(object({
|
|
|
43824
43844
|
kind: "mutation",
|
|
43825
43845
|
auth: "admin"
|
|
43826
43846
|
});
|
|
43847
|
+
method(object({
|
|
43848
|
+
nodeId: string().min(1),
|
|
43849
|
+
/** Epoch ms the node was forgotten (the tombstone's `removedAt`). */
|
|
43850
|
+
removedAt: number()
|
|
43851
|
+
}), object({ counts: record(string(), number().int().nonnegative()) }), {
|
|
43852
|
+
kind: "mutation",
|
|
43853
|
+
auth: "admin"
|
|
43854
|
+
});
|
|
43827
43855
|
/**
|
|
43828
43856
|
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
43829
43857
|
* so it can delete what it keeps for that device (D865).
|
|
@@ -56067,8 +56095,7 @@ var pipelineOrchestratorCapability = {
|
|
|
56067
56095
|
* replaced the four flat orchestrator lists (`enabledNodes`,
|
|
56068
56096
|
* `enabledDecoderNodes`, `enabledAudioNodes`, `remoteSourcingNodes`).
|
|
56069
56097
|
* Each flag is optional in the patch: omit a flag to leave it unchanged,
|
|
56070
|
-
* pass `null` to reset it to the
|
|
56071
|
-
* other node → not). Detection/audio eligibility is derived from these
|
|
56098
|
+
* pass `null` to reset it to the default (ON for every node). Detection/audio eligibility is derived from these
|
|
56072
56099
|
* flags across the cluster; changing them re-derives the enabled sets
|
|
56073
56100
|
* and reconciles dispatch immediately. There is NO separate decode flag:
|
|
56074
56101
|
* decode is always co-located with its frame consumer, so decode
|
|
@@ -60027,6 +60054,318 @@ DeviceType.Light, method(object({
|
|
|
60027
60054
|
level: number().min(0).max(100),
|
|
60028
60055
|
lastChangedAt: number()
|
|
60029
60056
|
});
|
|
60057
|
+
/**
|
|
60058
|
+
* The role vocabulary of a remote (D963): what a button MEANS, independent of
|
|
60059
|
+
* how it is wired. A layout template places buttons by role; a device binds a
|
|
60060
|
+
* role to an action; an exporter asks for a role by name. Roles are shared so
|
|
60061
|
+
* one layout fits every appliance and one voice command fits every binding.
|
|
60062
|
+
*
|
|
60063
|
+
* A role outside this list is `custom:<key>` — the operator's own button (a
|
|
60064
|
+
* SmartIR source, a channel preset). The key is a lowercase slug.
|
|
60065
|
+
*/
|
|
60066
|
+
var REMOTE_KNOWN_ROLES = [
|
|
60067
|
+
"power",
|
|
60068
|
+
"power_on",
|
|
60069
|
+
"power_off",
|
|
60070
|
+
"volume_up",
|
|
60071
|
+
"volume_down",
|
|
60072
|
+
"mute",
|
|
60073
|
+
"channel_up",
|
|
60074
|
+
"channel_down",
|
|
60075
|
+
"up",
|
|
60076
|
+
"down",
|
|
60077
|
+
"left",
|
|
60078
|
+
"right",
|
|
60079
|
+
"ok",
|
|
60080
|
+
"back",
|
|
60081
|
+
"home",
|
|
60082
|
+
"menu",
|
|
60083
|
+
"info",
|
|
60084
|
+
"guide",
|
|
60085
|
+
"exit",
|
|
60086
|
+
"input",
|
|
60087
|
+
"play",
|
|
60088
|
+
"pause",
|
|
60089
|
+
"play_pause",
|
|
60090
|
+
"stop",
|
|
60091
|
+
"next",
|
|
60092
|
+
"previous",
|
|
60093
|
+
"fast_forward",
|
|
60094
|
+
"rewind",
|
|
60095
|
+
"digit_0",
|
|
60096
|
+
"digit_1",
|
|
60097
|
+
"digit_2",
|
|
60098
|
+
"digit_3",
|
|
60099
|
+
"digit_4",
|
|
60100
|
+
"digit_5",
|
|
60101
|
+
"digit_6",
|
|
60102
|
+
"digit_7",
|
|
60103
|
+
"digit_8",
|
|
60104
|
+
"digit_9"
|
|
60105
|
+
];
|
|
60106
|
+
var CUSTOM_KEY_RE = /^[a-z0-9][a-z0-9_]{0,47}$/;
|
|
60107
|
+
var KNOWN_ROLES = new Set(REMOTE_KNOWN_ROLES);
|
|
60108
|
+
function isRemoteKnownRole(value) {
|
|
60109
|
+
return KNOWN_ROLES.has(value);
|
|
60110
|
+
}
|
|
60111
|
+
function isRemoteCustomKey(key) {
|
|
60112
|
+
return CUSTOM_KEY_RE.test(key);
|
|
60113
|
+
}
|
|
60114
|
+
/** The key of a `custom:<key>` role, or null for any other string. */
|
|
60115
|
+
function customKeyOfRole(role) {
|
|
60116
|
+
if (!role.startsWith("custom:")) return null;
|
|
60117
|
+
const key = role.slice(7);
|
|
60118
|
+
return isRemoteCustomKey(key) ? key : null;
|
|
60119
|
+
}
|
|
60120
|
+
function isRemoteRole(value) {
|
|
60121
|
+
return isRemoteKnownRole(value) || customKeyOfRole(value) !== null;
|
|
60122
|
+
}
|
|
60123
|
+
var RemoteRoleSchema = string().refine(isRemoteRole, { message: "a role is one of the known roles or custom:<key> (lowercase letters, digits, _)" });
|
|
60124
|
+
var RemoteBindingSchema = object({ action: AutomationCapStepSchema.extend({ deviceId: number().int().nonnegative() }) });
|
|
60125
|
+
var RemoteCustomButtonSchema = object({
|
|
60126
|
+
/** The slug after `custom:` in the role. */
|
|
60127
|
+
key: string().refine(isRemoteCustomKey, { message: "a lowercase slug" }),
|
|
60128
|
+
/** What the operator calls it, and what a voice command may name. */
|
|
60129
|
+
name: string().min(1).max(60)
|
|
60130
|
+
});
|
|
60131
|
+
var RemotePowerModeSchema = _enum(["toggle", "discrete"]);
|
|
60132
|
+
var RemoteConfigSchema = object({
|
|
60133
|
+
layoutTemplateId: string().min(1).nullable(),
|
|
60134
|
+
/**
|
|
60135
|
+
* The transmitter device new bindings and an import send through. A binding
|
|
60136
|
+
* names its own device, so one command may override it.
|
|
60137
|
+
*/
|
|
60138
|
+
defaultTransmitterId: number().int().nonnegative().nullable().default(null),
|
|
60139
|
+
/** Keyed by role. A role with no entry falls back to the native cap. */
|
|
60140
|
+
bindings: record(string(), RemoteBindingSchema),
|
|
60141
|
+
customButtons: array(RemoteCustomButtonSchema).max(100),
|
|
60142
|
+
power: object({ mode: RemotePowerModeSchema })
|
|
60143
|
+
}).superRefine((config, ctx) => {
|
|
60144
|
+
const roles = Object.keys(config.bindings);
|
|
60145
|
+
if (roles.length > 200) ctx.addIssue({
|
|
60146
|
+
code: "custom",
|
|
60147
|
+
message: "too many bindings",
|
|
60148
|
+
path: ["bindings"]
|
|
60149
|
+
});
|
|
60150
|
+
for (const role of roles) if (!isRemoteRole(role)) ctx.addIssue({
|
|
60151
|
+
code: "custom",
|
|
60152
|
+
message: `"${role}" is not a role`,
|
|
60153
|
+
path: ["bindings", role]
|
|
60154
|
+
});
|
|
60155
|
+
const keys = /* @__PURE__ */ new Set();
|
|
60156
|
+
config.customButtons.forEach((button, index) => {
|
|
60157
|
+
if (keys.has(button.key)) ctx.addIssue({
|
|
60158
|
+
code: "custom",
|
|
60159
|
+
message: `custom button "${button.key}" is listed twice`,
|
|
60160
|
+
path: [
|
|
60161
|
+
"customButtons",
|
|
60162
|
+
index,
|
|
60163
|
+
"key"
|
|
60164
|
+
]
|
|
60165
|
+
});
|
|
60166
|
+
keys.add(button.key);
|
|
60167
|
+
});
|
|
60168
|
+
for (const role of roles) {
|
|
60169
|
+
const key = customKeyOfRole(role);
|
|
60170
|
+
if (key !== null && !keys.has(key)) ctx.addIssue({
|
|
60171
|
+
code: "custom",
|
|
60172
|
+
message: `${role} is bound but has no entry in customButtons`,
|
|
60173
|
+
path: ["bindings", role]
|
|
60174
|
+
});
|
|
60175
|
+
}
|
|
60176
|
+
});
|
|
60177
|
+
object({
|
|
60178
|
+
power: object({
|
|
60179
|
+
state: _enum(["on", "off"]),
|
|
60180
|
+
at: number()
|
|
60181
|
+
}).nullable(),
|
|
60182
|
+
muted: object({
|
|
60183
|
+
value: boolean(),
|
|
60184
|
+
at: number()
|
|
60185
|
+
}).nullable()
|
|
60186
|
+
});
|
|
60187
|
+
var RemoteLayoutButtonSchema = object({
|
|
60188
|
+
id: string().min(1).max(40),
|
|
60189
|
+
/** 0-based grid position. */
|
|
60190
|
+
row: number().int().min(0).max(24),
|
|
60191
|
+
col: number().int().min(0).max(24),
|
|
60192
|
+
rowSpan: number().int().min(1).max(24),
|
|
60193
|
+
colSpan: number().int().min(1).max(24),
|
|
60194
|
+
icon: string().min(1).max(60).optional(),
|
|
60195
|
+
label: string().min(1).max(40).optional(),
|
|
60196
|
+
role: RemoteRoleSchema
|
|
60197
|
+
});
|
|
60198
|
+
object({
|
|
60199
|
+
columns: number().int().min(1).max(24),
|
|
60200
|
+
rows: number().int().min(1).max(24),
|
|
60201
|
+
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
60202
|
+
}).superRefine((grid, ctx) => {
|
|
60203
|
+
const ids = /* @__PURE__ */ new Set();
|
|
60204
|
+
const taken = /* @__PURE__ */ new Map();
|
|
60205
|
+
grid.buttons.forEach((button, index) => {
|
|
60206
|
+
if (ids.has(button.id)) ctx.addIssue({
|
|
60207
|
+
code: "custom",
|
|
60208
|
+
message: `button id "${button.id}" is used twice`,
|
|
60209
|
+
path: [
|
|
60210
|
+
"buttons",
|
|
60211
|
+
index,
|
|
60212
|
+
"id"
|
|
60213
|
+
]
|
|
60214
|
+
});
|
|
60215
|
+
ids.add(button.id);
|
|
60216
|
+
if (button.row + button.rowSpan > grid.rows || button.col + button.colSpan > grid.columns) {
|
|
60217
|
+
ctx.addIssue({
|
|
60218
|
+
code: "custom",
|
|
60219
|
+
message: `button "${button.id}" leaves the grid`,
|
|
60220
|
+
path: ["buttons", index]
|
|
60221
|
+
});
|
|
60222
|
+
return;
|
|
60223
|
+
}
|
|
60224
|
+
for (let r = button.row; r < button.row + button.rowSpan; r += 1) for (let c = button.col; c < button.col + button.colSpan; c += 1) {
|
|
60225
|
+
const cell = `${r}:${c}`;
|
|
60226
|
+
const other = taken.get(cell);
|
|
60227
|
+
if (other !== void 0) {
|
|
60228
|
+
ctx.addIssue({
|
|
60229
|
+
code: "custom",
|
|
60230
|
+
message: `buttons "${other}" and "${button.id}" overlap`,
|
|
60231
|
+
path: ["buttons", index]
|
|
60232
|
+
});
|
|
60233
|
+
return;
|
|
60234
|
+
}
|
|
60235
|
+
taken.set(cell, button.id);
|
|
60236
|
+
}
|
|
60237
|
+
});
|
|
60238
|
+
});
|
|
60239
|
+
var RemoteBoundCommandSchema = object({
|
|
60240
|
+
role: RemoteRoleSchema,
|
|
60241
|
+
/** The operator's name for a custom button; absent for a known role. */
|
|
60242
|
+
label: string().optional(),
|
|
60243
|
+
custom: boolean()
|
|
60244
|
+
});
|
|
60245
|
+
var RemoteCommandListSchema = object({
|
|
60246
|
+
layoutTemplateId: string().nullable(),
|
|
60247
|
+
power: object({ mode: RemotePowerModeSchema }),
|
|
60248
|
+
/** Only the roles that are BOUND — the ones a press can reach. */
|
|
60249
|
+
commands: array(RemoteBoundCommandSchema)
|
|
60250
|
+
});
|
|
60251
|
+
var RemoteRefusalReasonSchema = _enum([
|
|
60252
|
+
"no-remote",
|
|
60253
|
+
"unbound-role",
|
|
60254
|
+
"action-failed"
|
|
60255
|
+
]);
|
|
60256
|
+
var RemoteSendResultSchema = discriminatedUnion("status", [
|
|
60257
|
+
object({
|
|
60258
|
+
status: literal("sent"),
|
|
60259
|
+
/** How many times the action ran. */
|
|
60260
|
+
sends: number().int().min(1)
|
|
60261
|
+
}),
|
|
60262
|
+
object({
|
|
60263
|
+
status: literal("skipped"),
|
|
60264
|
+
reason: literal("already-in-state")
|
|
60265
|
+
}),
|
|
60266
|
+
object({
|
|
60267
|
+
status: literal("refused"),
|
|
60268
|
+
reason: RemoteRefusalReasonSchema,
|
|
60269
|
+
detail: string().optional()
|
|
60270
|
+
})
|
|
60271
|
+
]);
|
|
60272
|
+
var RemoteMediaCommandSchema = _enum([
|
|
60273
|
+
"play",
|
|
60274
|
+
"pause",
|
|
60275
|
+
"stop",
|
|
60276
|
+
"next",
|
|
60277
|
+
"previous",
|
|
60278
|
+
"setMute",
|
|
60279
|
+
"selectSource"
|
|
60280
|
+
]);
|
|
60281
|
+
/** A send result, or `not-routed`: the role is not bound, so the native cap answers. */
|
|
60282
|
+
var RemoteMediaCommandResultSchema = discriminatedUnion("status", [...RemoteSendResultSchema.options, object({ status: literal("not-routed") })]);
|
|
60283
|
+
var RemoteSetConfigResultSchema = discriminatedUnion("status", [object({ status: literal("saved") }), object({
|
|
60284
|
+
status: literal("refused"),
|
|
60285
|
+
reason: _enum(["unknown-template", "not-a-media-player"]),
|
|
60286
|
+
detail: string()
|
|
60287
|
+
})]);
|
|
60288
|
+
var deviceInput = object({ deviceId: number().int().nonnegative() });
|
|
60289
|
+
DeviceType.MediaPlayer;
|
|
60290
|
+
method(deviceInput, RemoteConfigSchema, { auth: "admin" }), method(deviceInput.extend({ config: RemoteConfigSchema }), RemoteSetConfigResultSchema, {
|
|
60291
|
+
kind: "mutation",
|
|
60292
|
+
auth: "admin"
|
|
60293
|
+
}), method(deviceInput, RemoteCommandListSchema, { auth: "protected" }), method(deviceInput.extend({
|
|
60294
|
+
role: RemoteRoleSchema,
|
|
60295
|
+
/** Sends in a row (volume steps). */
|
|
60296
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
60297
|
+
}), RemoteSendResultSchema, {
|
|
60298
|
+
kind: "mutation",
|
|
60299
|
+
auth: "protected"
|
|
60300
|
+
}), method(deviceInput.extend({
|
|
60301
|
+
command: RemoteMediaCommandSchema,
|
|
60302
|
+
muted: boolean().optional(),
|
|
60303
|
+
source: string().optional(),
|
|
60304
|
+
repeat: number().int().min(1).max(50).default(1)
|
|
60305
|
+
}), RemoteMediaCommandResultSchema, {
|
|
60306
|
+
kind: "mutation",
|
|
60307
|
+
auth: "protected"
|
|
60308
|
+
});
|
|
60309
|
+
var TemplateKindSchema = _enum(["remote"]);
|
|
60310
|
+
/**
|
|
60311
|
+
* template — the generic store of reusable, named operator data (D963). A
|
|
60312
|
+
* record is `{ id, kind, name, payload }`; the kinds (today only `remote`, the
|
|
60313
|
+
* button grid of a remote) and the schema each payload must satisfy are
|
|
60314
|
+
* declared by the system in `template-kinds.ts`. Nothing here is specific to a
|
|
60315
|
+
* kind: the engine validates a payload against its kind's schema and, on a
|
|
60316
|
+
* delete, asks the kind's owner whether anything still points at the record.
|
|
60317
|
+
*
|
|
60318
|
+
* Every refusal is a typed result — a UI says "unknown kind" or names the
|
|
60319
|
+
* devices that still use a template, without parsing text.
|
|
60320
|
+
*/
|
|
60321
|
+
var TemplateRecordSchema = object({
|
|
60322
|
+
id: string().min(1),
|
|
60323
|
+
kind: TemplateKindSchema,
|
|
60324
|
+
name: string().min(1).max(120),
|
|
60325
|
+
/** Shaped by the kind; `checkTemplatePayload(kind, payload)` reads it. */
|
|
60326
|
+
payload: unknown(),
|
|
60327
|
+
createdAt: number(),
|
|
60328
|
+
updatedAt: number()
|
|
60329
|
+
});
|
|
60330
|
+
var TemplateWriteResultSchema = discriminatedUnion("status", [object({
|
|
60331
|
+
status: literal("saved"),
|
|
60332
|
+
template: TemplateRecordSchema
|
|
60333
|
+
}), object({
|
|
60334
|
+
status: literal("refused"),
|
|
60335
|
+
reason: _enum(["invalid-payload", "not-found"]),
|
|
60336
|
+
detail: string()
|
|
60337
|
+
})]);
|
|
60338
|
+
/** A device still pointing at a template. */
|
|
60339
|
+
var TemplateUserSchema = object({
|
|
60340
|
+
deviceId: number().int().nonnegative(),
|
|
60341
|
+
name: string()
|
|
60342
|
+
});
|
|
60343
|
+
var TemplateDeleteResultSchema = discriminatedUnion("status", [
|
|
60344
|
+
object({ status: literal("deleted") }),
|
|
60345
|
+
object({ status: literal("not-found") }),
|
|
60346
|
+
object({
|
|
60347
|
+
status: literal("in-use"),
|
|
60348
|
+
devices: array(TemplateUserSchema).min(1)
|
|
60349
|
+
})
|
|
60350
|
+
]);
|
|
60351
|
+
method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSchema), { auth: "protected" }), method(object({ id: string().min(1) }), TemplateRecordSchema.nullable(), { auth: "protected" }), method(object({
|
|
60352
|
+
kind: TemplateKindSchema,
|
|
60353
|
+
name: string().min(1).max(120),
|
|
60354
|
+
payload: unknown()
|
|
60355
|
+
}), TemplateWriteResultSchema, {
|
|
60356
|
+
kind: "mutation",
|
|
60357
|
+
auth: "admin"
|
|
60358
|
+
}), method(object({
|
|
60359
|
+
id: string().min(1),
|
|
60360
|
+
name: string().min(1).max(120).optional(),
|
|
60361
|
+
payload: unknown().optional()
|
|
60362
|
+
}), TemplateWriteResultSchema, {
|
|
60363
|
+
kind: "mutation",
|
|
60364
|
+
auth: "admin"
|
|
60365
|
+
}), method(object({ id: string().min(1) }), TemplateDeleteResultSchema, {
|
|
60366
|
+
kind: "mutation",
|
|
60367
|
+
auth: "admin"
|
|
60368
|
+
});
|
|
60030
60369
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
60031
60370
|
kind: "mutation",
|
|
60032
60371
|
auth: "protected"
|
|
@@ -62785,9 +63124,35 @@ var MediaInfoSchema = object({
|
|
|
62785
63124
|
/** Optional cover-art / thumbnail URL. */
|
|
62786
63125
|
imageUrl: string().optional()
|
|
62787
63126
|
});
|
|
63127
|
+
/**
|
|
63128
|
+
* Where `state`, `volumeLevel`, `isMuted` and `source` come from. `reported`:
|
|
63129
|
+
* the device said so. `assumed`: the driver has no feedback (infrared) and
|
|
63130
|
+
* tracks what it last SENT; it moves only after a send was accepted, and a
|
|
63131
|
+
* human at the real remote makes it wrong. A UI shows an assumed value as a
|
|
63132
|
+
* guess, never as a reading.
|
|
63133
|
+
*/
|
|
63134
|
+
var MediaPlayerStateSourceSchema = _enum(["reported", "assumed"]);
|
|
63135
|
+
/** The fields of a media-player status a driver can only guess. */
|
|
63136
|
+
var MediaPlayerAssumedFieldSchema = _enum([
|
|
63137
|
+
"state",
|
|
63138
|
+
"volumeLevel",
|
|
63139
|
+
"isMuted",
|
|
63140
|
+
"source"
|
|
63141
|
+
]);
|
|
62788
63142
|
object({
|
|
62789
63143
|
/** Playback lifecycle state. */
|
|
62790
63144
|
state: MediaPlayerStateSchema,
|
|
63145
|
+
/**
|
|
63146
|
+
* Whether the state fields are readings or the driver's own bookkeeping.
|
|
63147
|
+
* A slice written before this field existed parses as `reported`.
|
|
63148
|
+
*/
|
|
63149
|
+
stateSource: MediaPlayerStateSourceSchema.default("reported"),
|
|
63150
|
+
/**
|
|
63151
|
+
* Which fields are the driver's own guess. `stateSource` is `assumed` when
|
|
63152
|
+
* this is not empty; a field not listed here is a reading even then (power
|
|
63153
|
+
* from a running-state source, mute guessed from the last send).
|
|
63154
|
+
*/
|
|
63155
|
+
assumedFields: array(MediaPlayerAssumedFieldSchema).default([]),
|
|
62791
63156
|
/** Volume as 0..100 inclusive. Null when the device has no volume
|
|
62792
63157
|
* surface. Pair with `DeviceFeature.MediaPlayerVolume`. */
|
|
62793
63158
|
volumeLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -64253,6 +64618,14 @@ object({
|
|
|
64253
64618
|
feedSound: boolean(),
|
|
64254
64619
|
/** Speaker / prompt volume level (device-scaled integer). */
|
|
64255
64620
|
volume: number().meta(readingMeta("none")),
|
|
64621
|
+
/** Portion (grams) of the last manual feed sent from a single-hopper
|
|
64622
|
+
* stepper — the default the next manual feed starts from. Persisted per
|
|
64623
|
+
* device by the provider; null until a manual feed has been sent. */
|
|
64624
|
+
lastFeedGrams: gramsPortion.nullable(),
|
|
64625
|
+
/** Hopper-1 portion of the last manual feed (dual-hopper); null until sent. */
|
|
64626
|
+
lastFeedHopper1: gramsPortion.nullable(),
|
|
64627
|
+
/** Hopper-2 portion of the last manual feed (dual-hopper); null until sent. */
|
|
64628
|
+
lastFeedHopper2: gramsPortion.nullable(),
|
|
64256
64629
|
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
64257
64630
|
lastFetchedAt: number()
|
|
64258
64631
|
});
|
|
@@ -69704,9 +70077,17 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
69704
70077
|
kind: "mutation",
|
|
69705
70078
|
auth: "admin"
|
|
69706
70079
|
});
|
|
70080
|
+
discriminatedUnion("kind", [object({
|
|
70081
|
+
kind: literal("raw"),
|
|
70082
|
+
timings: array(number().int()),
|
|
70083
|
+
settings: TransmitSettingsSchema.optional()
|
|
70084
|
+
}), object({
|
|
70085
|
+
kind: literal("pronto"),
|
|
70086
|
+
code: string()
|
|
70087
|
+
})]);
|
|
69707
70088
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
69708
70089
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
69709
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
70090
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
69710
70091
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
69711
70092
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
69712
70093
|
new Set(CAP_NAMES);
|
|
@@ -74557,6 +74938,13 @@ Object.freeze({
|
|
|
74557
74938
|
access: "create",
|
|
74558
74939
|
role: "admin"
|
|
74559
74940
|
},
|
|
74941
|
+
"nodeRemovalHook.onNodeRemoved": {
|
|
74942
|
+
capName: "node-removal-hook",
|
|
74943
|
+
capScope: "system",
|
|
74944
|
+
addonId: null,
|
|
74945
|
+
access: "create",
|
|
74946
|
+
role: "admin"
|
|
74947
|
+
},
|
|
74560
74948
|
"nodes.clusterAddonStatus": {
|
|
74561
74949
|
capName: "nodes",
|
|
74562
74950
|
capScope: "system",
|
|
@@ -77448,6 +77836,41 @@ Object.freeze({
|
|
|
77448
77836
|
access: "create",
|
|
77449
77837
|
role: "admin"
|
|
77450
77838
|
},
|
|
77839
|
+
"remote.getConfig": {
|
|
77840
|
+
capName: "remote",
|
|
77841
|
+
capScope: "system",
|
|
77842
|
+
addonId: null,
|
|
77843
|
+
access: "view",
|
|
77844
|
+
role: "admin"
|
|
77845
|
+
},
|
|
77846
|
+
"remote.listCommands": {
|
|
77847
|
+
capName: "remote",
|
|
77848
|
+
capScope: "system",
|
|
77849
|
+
addonId: null,
|
|
77850
|
+
access: "view",
|
|
77851
|
+
role: "admin"
|
|
77852
|
+
},
|
|
77853
|
+
"remote.sendCommand": {
|
|
77854
|
+
capName: "remote",
|
|
77855
|
+
capScope: "system",
|
|
77856
|
+
addonId: null,
|
|
77857
|
+
access: "create",
|
|
77858
|
+
role: "admin"
|
|
77859
|
+
},
|
|
77860
|
+
"remote.sendMediaCommand": {
|
|
77861
|
+
capName: "remote",
|
|
77862
|
+
capScope: "system",
|
|
77863
|
+
addonId: null,
|
|
77864
|
+
access: "create",
|
|
77865
|
+
role: "admin"
|
|
77866
|
+
},
|
|
77867
|
+
"remote.setConfig": {
|
|
77868
|
+
capName: "remote",
|
|
77869
|
+
capScope: "system",
|
|
77870
|
+
addonId: null,
|
|
77871
|
+
access: "create",
|
|
77872
|
+
role: "admin"
|
|
77873
|
+
},
|
|
77451
77874
|
"runningState.getStatus": {
|
|
77452
77875
|
capName: "running-state",
|
|
77453
77876
|
capScope: "device",
|
|
@@ -78638,6 +79061,41 @@ Object.freeze({
|
|
|
78638
79061
|
access: "view",
|
|
78639
79062
|
role: "viewer"
|
|
78640
79063
|
},
|
|
79064
|
+
"template.create": {
|
|
79065
|
+
capName: "template",
|
|
79066
|
+
capScope: "system",
|
|
79067
|
+
addonId: null,
|
|
79068
|
+
access: "create",
|
|
79069
|
+
role: "admin"
|
|
79070
|
+
},
|
|
79071
|
+
"template.delete": {
|
|
79072
|
+
capName: "template",
|
|
79073
|
+
capScope: "system",
|
|
79074
|
+
addonId: null,
|
|
79075
|
+
access: "delete",
|
|
79076
|
+
role: "admin"
|
|
79077
|
+
},
|
|
79078
|
+
"template.get": {
|
|
79079
|
+
capName: "template",
|
|
79080
|
+
capScope: "system",
|
|
79081
|
+
addonId: null,
|
|
79082
|
+
access: "view",
|
|
79083
|
+
role: "admin"
|
|
79084
|
+
},
|
|
79085
|
+
"template.list": {
|
|
79086
|
+
capName: "template",
|
|
79087
|
+
capScope: "system",
|
|
79088
|
+
addonId: null,
|
|
79089
|
+
access: "view",
|
|
79090
|
+
role: "admin"
|
|
79091
|
+
},
|
|
79092
|
+
"template.update": {
|
|
79093
|
+
capName: "template",
|
|
79094
|
+
capScope: "system",
|
|
79095
|
+
addonId: null,
|
|
79096
|
+
access: "create",
|
|
79097
|
+
role: "admin"
|
|
79098
|
+
},
|
|
78641
79099
|
"terminalSession.adoptLegacyMonitor": {
|
|
78642
79100
|
capName: "terminal-session",
|
|
78643
79101
|
capScope: "system",
|
|
@@ -83430,6 +83888,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
83430
83888
|
"device-manager": system("the device registry itself — rename, move and remove are administration"),
|
|
83431
83889
|
"device-provider": system(INTERNAL),
|
|
83432
83890
|
"device-removal-hook": system(INTERNAL),
|
|
83891
|
+
"node-removal-hook": system(INTERNAL),
|
|
83433
83892
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
83434
83893
|
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
83435
83894
|
"embedding-encoder": system(ML),
|
|
@@ -83469,6 +83928,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
83469
83928
|
"recording-archive": system(STORAGE),
|
|
83470
83929
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
83471
83930
|
records: system(INTERNAL),
|
|
83931
|
+
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
83472
83932
|
"server-management": system(CLUSTER),
|
|
83473
83933
|
"settings-store": system(INTERNAL),
|
|
83474
83934
|
"smtp-provider": system(INTERNAL),
|
|
@@ -83481,6 +83941,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
83481
83941
|
"storage-provider": system(STORAGE),
|
|
83482
83942
|
"stream-broker": system(PIPELINE),
|
|
83483
83943
|
system: system(CLUSTER),
|
|
83944
|
+
template: system("operator-authored templates — edited in their own editor, never actuated"),
|
|
83484
83945
|
"terminal-session": system(CLUSTER),
|
|
83485
83946
|
toast: system(UI_PLUMBING),
|
|
83486
83947
|
training: system(ML),
|
|
@@ -85935,6 +86396,31 @@ Object.freeze({
|
|
|
85935
86396
|
form: "single",
|
|
85936
86397
|
optional: true
|
|
85937
86398
|
}],
|
|
86399
|
+
"remote.getConfig": [{
|
|
86400
|
+
name: "deviceId",
|
|
86401
|
+
form: "single",
|
|
86402
|
+
optional: false
|
|
86403
|
+
}],
|
|
86404
|
+
"remote.listCommands": [{
|
|
86405
|
+
name: "deviceId",
|
|
86406
|
+
form: "single",
|
|
86407
|
+
optional: false
|
|
86408
|
+
}],
|
|
86409
|
+
"remote.sendCommand": [{
|
|
86410
|
+
name: "deviceId",
|
|
86411
|
+
form: "single",
|
|
86412
|
+
optional: false
|
|
86413
|
+
}],
|
|
86414
|
+
"remote.sendMediaCommand": [{
|
|
86415
|
+
name: "deviceId",
|
|
86416
|
+
form: "single",
|
|
86417
|
+
optional: false
|
|
86418
|
+
}],
|
|
86419
|
+
"remote.setConfig": [{
|
|
86420
|
+
name: "deviceId",
|
|
86421
|
+
form: "single",
|
|
86422
|
+
optional: false
|
|
86423
|
+
}],
|
|
85938
86424
|
"runningState.getStatus": [{
|
|
85939
86425
|
name: "deviceId",
|
|
85940
86426
|
form: "single",
|
|
@@ -89075,14 +89561,6 @@ var DEVICE_BACKEND_TO_FORMAT = {
|
|
|
89075
89561
|
function deviceBackendToFormat(backend) {
|
|
89076
89562
|
return DEVICE_BACKEND_TO_FORMAT[backend] ?? "onnx";
|
|
89077
89563
|
}
|
|
89078
|
-
discriminatedUnion("kind", [object({
|
|
89079
|
-
kind: literal("raw"),
|
|
89080
|
-
timings: array(number().int()),
|
|
89081
|
-
settings: TransmitSettingsSchema.optional()
|
|
89082
|
-
}), object({
|
|
89083
|
-
kind: literal("pronto"),
|
|
89084
|
-
code: string()
|
|
89085
|
-
})]);
|
|
89086
89564
|
object({
|
|
89087
89565
|
manufacturer: string().optional(),
|
|
89088
89566
|
supportedModels: array(string()).optional(),
|
|
@@ -100768,12 +101246,12 @@ function computeFrameSourceNodes(input) {
|
|
|
100768
101246
|
//#endregion
|
|
100769
101247
|
//#region src/node-topology.ts
|
|
100770
101248
|
/**
|
|
100771
|
-
*
|
|
100772
|
-
*
|
|
100773
|
-
*
|
|
101249
|
+
* A placement flag (detect, audio, ingest) is ON unless the operator stored an
|
|
101250
|
+
* explicit `false`. A newly paired agent has no stored settings and must still
|
|
101251
|
+
* join balancing (D965).
|
|
100774
101252
|
*/
|
|
100775
|
-
function
|
|
100776
|
-
return
|
|
101253
|
+
function isRoleOn(flag) {
|
|
101254
|
+
return flag !== false;
|
|
100777
101255
|
}
|
|
100778
101256
|
var NodeTopologyService = class {
|
|
100779
101257
|
deps;
|
|
@@ -100904,17 +101382,16 @@ var NodeTopologyService = class {
|
|
|
100904
101382
|
this.deps.logger.warn("refreshNodeCapabilities: agent settings read failed", { meta: { error: errMsg$2(err) } });
|
|
100905
101383
|
}
|
|
100906
101384
|
const nodeIds = new Set(["hub"]);
|
|
100907
|
-
for (const nodeId of Object.keys(blob)) if (typeof nodeId === "string" && nodeId.length > 0 && !nodeId.includes("/")) nodeIds.add(nodeId);
|
|
101385
|
+
for (const nodeId of [...Object.keys(blob), ...this.knownRunnerNodes]) if (typeof nodeId === "string" && nodeId.length > 0 && !nodeId.includes("/")) nodeIds.add(nodeId);
|
|
100908
101386
|
const detect = [];
|
|
100909
101387
|
const audio = [];
|
|
100910
101388
|
const ingest = [];
|
|
100911
101389
|
const reachableHosts = /* @__PURE__ */ new Map();
|
|
100912
|
-
const capable = (flag, nodeId) => typeof flag === "boolean" ? flag : nodeCapabilityDefault(nodeId);
|
|
100913
101390
|
for (const nodeId of nodeIds) {
|
|
100914
101391
|
const settings = blob[nodeId];
|
|
100915
|
-
if (
|
|
100916
|
-
if (
|
|
100917
|
-
if (
|
|
101392
|
+
if (isRoleOn(settings?.detect)) detect.push(nodeId);
|
|
101393
|
+
if (isRoleOn(settings?.audio)) audio.push(nodeId);
|
|
101394
|
+
if (isRoleOn(settings?.ingest)) ingest.push(nodeId);
|
|
100918
101395
|
const host = settings?.reachableHost?.trim();
|
|
100919
101396
|
if (host !== void 0 && host.length > 0) reachableHosts.set(nodeId, host);
|
|
100920
101397
|
}
|
|
@@ -102292,7 +102769,7 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
102292
102769
|
const deviceFormat = deviceKey ? parseDeviceKey(deviceKey).format : catalog.selectedEngine.format;
|
|
102293
102770
|
const jumpFormats = [...new Set(jumpDeviceKeys.map((k) => parseDeviceKey(k).format))];
|
|
102294
102771
|
const { config: resolvedBase, skipped, droppedRoots } = resolvePipelineWithSkips(cam, deviceFormat, catalog, jumpFormats);
|
|
102295
|
-
if (skipped.length > 0) this.deps.logger.warn(
|
|
102772
|
+
if (skipped.length > 0) this.deps.logger.warn(`pipeline steps gated on but not provisioned on this node — skipped (node ${agentNodeId}, device ${deviceId})`, {
|
|
102296
102773
|
tags: {
|
|
102297
102774
|
deviceId,
|
|
102298
102775
|
nodeId: agentNodeId
|
|
@@ -106653,6 +107130,12 @@ async function buildOrchestratorControllers(deps) {
|
|
|
106653
107130
|
const unsubAgentOnlineEvent = deps.ctx().eventBus.subscribe({ category: EventCategory.AgentOnline }, (event) => {
|
|
106654
107131
|
const nodeId = event.data.agentId;
|
|
106655
107132
|
if (!nodeId.includes("/")) topology.addKnownRunnerNode(nodeId);
|
|
107133
|
+
if (!nodeId.includes("/")) topology.refreshNodeCapabilities().catch((err) => {
|
|
107134
|
+
deps.ctx().logger.warn("refreshNodeCapabilities after agent online failed", {
|
|
107135
|
+
tags: { nodeId },
|
|
107136
|
+
meta: { error: errMsg$2(err) }
|
|
107137
|
+
});
|
|
107138
|
+
});
|
|
106656
107139
|
sliceGate.forgetNode(nodeId);
|
|
106657
107140
|
sliceGate.refresh("agent-online");
|
|
106658
107141
|
providerGate.forgetProcess(nodeId);
|