@camstack/addon-import-alexa 0.2.193 → 0.2.195
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 +13 -0
- package/dist/addon.js +163 -416
- package/dist/addon.mjs +163 -416
- package/package.json +2 -2
package/dist/addon.js
CHANGED
|
@@ -48,7 +48,7 @@ node_fs = __toESM(node_fs, 1);
|
|
|
48
48
|
let node_child_process = require("node:child_process");
|
|
49
49
|
require("node:zlib");
|
|
50
50
|
let node_url = require("node:url");
|
|
51
|
-
//#region ../types/dist/event-category-
|
|
51
|
+
//#region ../types/dist/event-category-78tcBemo.mjs
|
|
52
52
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
53
53
|
EventCategory["SystemBoot"] = "system.boot";
|
|
54
54
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -169,6 +169,23 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
169
169
|
*/
|
|
170
170
|
EventCategory["AddonLoadRecovered"] = "addon.load-recovered";
|
|
171
171
|
/**
|
|
172
|
+
* An addon is RUNNING although its installed package is below what the
|
|
173
|
+
* running server requires (`camstack.requires.addons` of the server, or the
|
|
174
|
+
* addon's own `requires.server`). Raised once per streak by the unsupported-
|
|
175
|
+
* addon tracker, on the hub and on agents; AlertCenter turns it into one
|
|
176
|
+
* operator alert per node and package. The addon is never held back for it.
|
|
177
|
+
*
|
|
178
|
+
* Payload: `{ packageName, addonId, nodeId, installedVersion, requiredMinimum, serverVersion, unmet }`.
|
|
179
|
+
*/
|
|
180
|
+
EventCategory["AddonUnsupportedVersion"] = "addon.unsupported-version";
|
|
181
|
+
/**
|
|
182
|
+
* The package of an {@link AddonUnsupportedVersion} alert reached a supported
|
|
183
|
+
* version, or is no longer installed on the node. AlertCenter dismisses the matching alert.
|
|
184
|
+
*
|
|
185
|
+
* Payload: `{ packageName, addonId, nodeId }`.
|
|
186
|
+
*/
|
|
187
|
+
EventCategory["AddonUnsupportedResolved"] = "addon.unsupported-resolved";
|
|
188
|
+
/**
|
|
172
189
|
* Monitor scheduled the next retry for a failed addon. Transient —
|
|
173
190
|
* surfaced to the UI for live-updating the "next retry in Ns"
|
|
174
191
|
* countdown on the Addons page row, NOT persisted as an alert.
|
|
@@ -279,7 +296,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
279
296
|
EventCategory["ProcessRestarted"] = "process.restarted";
|
|
280
297
|
/**
|
|
281
298
|
* The SET of storage locations changed — one was created, edited, enabled,
|
|
282
|
-
* disabled or deleted through
|
|
299
|
+
* disabled or deleted through the location instances or the forced-delete action.
|
|
283
300
|
*
|
|
284
301
|
* Telemetry, not a transaction (D8/D11): every consumer that re-resolves on
|
|
285
302
|
* it must also converge on its own periodic path, because a dropped event
|
|
@@ -6044,7 +6061,7 @@ function number(params) {
|
|
|
6044
6061
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
6045
6062
|
}
|
|
6046
6063
|
//#endregion
|
|
6047
|
-
//#region ../types/dist/sleep-
|
|
6064
|
+
//#region ../types/dist/sleep-AEnTN3b4.mjs
|
|
6048
6065
|
/**
|
|
6049
6066
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6050
6067
|
* window to float samples (D455).
|
|
@@ -6753,10 +6770,33 @@ function integrationRowsApiOver(api) {
|
|
|
6753
6770
|
};
|
|
6754
6771
|
}
|
|
6755
6772
|
var PREFIX = "records/";
|
|
6773
|
+
/**
|
|
6774
|
+
* Cross-realm brand. An addon bundles its own copy of this module (D15) while
|
|
6775
|
+
* `ctx.records` is the HOST's door, so an error thrown by the host is an
|
|
6776
|
+
* instance of the host's classes, not of the addon's. The brand plus the code
|
|
6777
|
+
* make `instanceof` answer by identity of the failure, not of the copy.
|
|
6778
|
+
*/
|
|
6779
|
+
var RECORDS_ERROR_BRAND = Symbol.for("camstack.records-error");
|
|
6780
|
+
function carriesBrand(value) {
|
|
6781
|
+
return typeof value === "object" && value !== null && Reflect.get(value, RECORDS_ERROR_BRAND) === true;
|
|
6782
|
+
}
|
|
6756
6783
|
/** The base of every records failure. `detail` is the human part of the message. */
|
|
6757
6784
|
var RecordsError = class extends Error {
|
|
6785
|
+
/** The code a subclass stands for; the base stands for every code. */
|
|
6786
|
+
static code = void 0;
|
|
6787
|
+
/**
|
|
6788
|
+
* `instanceof` across copies of this module: any branded error is a
|
|
6789
|
+
* `RecordsError`, and is an instance of a subclass only when its code is the
|
|
6790
|
+
* subclass's code. Same-copy answers are unchanged.
|
|
6791
|
+
*/
|
|
6792
|
+
static [Symbol.hasInstance](value) {
|
|
6793
|
+
if (Function.prototype[Symbol.hasInstance].call(this, value)) return true;
|
|
6794
|
+
if (!carriesBrand(value)) return false;
|
|
6795
|
+
return this.code === void 0 || value.code === this.code;
|
|
6796
|
+
}
|
|
6758
6797
|
code;
|
|
6759
6798
|
detail;
|
|
6799
|
+
[RECORDS_ERROR_BRAND] = true;
|
|
6760
6800
|
constructor(code, detail) {
|
|
6761
6801
|
super(`${PREFIX}${code}: ${detail}`);
|
|
6762
6802
|
this.name = "RecordsError";
|
|
@@ -6765,29 +6805,33 @@ var RecordsError = class extends Error {
|
|
|
6765
6805
|
}
|
|
6766
6806
|
};
|
|
6767
6807
|
/** A write guarded by `ifRev` found another revision (or an existing row for `ifRev: 0`). */
|
|
6768
|
-
var RevConflictError = class extends RecordsError {
|
|
6808
|
+
var RevConflictError = class RevConflictError extends RecordsError {
|
|
6809
|
+
static code = "rev-conflict";
|
|
6769
6810
|
constructor(detail) {
|
|
6770
|
-
super(
|
|
6811
|
+
super(RevConflictError.code, detail);
|
|
6771
6812
|
this.name = "RevConflictError";
|
|
6772
6813
|
}
|
|
6773
6814
|
};
|
|
6774
6815
|
/** The keychain could not store or serve a value: explicit, never an empty string. */
|
|
6775
|
-
var RecordSecretUnavailableError = class extends RecordsError {
|
|
6816
|
+
var RecordSecretUnavailableError = class RecordSecretUnavailableError extends RecordsError {
|
|
6817
|
+
static code = "secret-unavailable";
|
|
6776
6818
|
constructor(detail) {
|
|
6777
|
-
super(
|
|
6819
|
+
super(RecordSecretUnavailableError.code, detail);
|
|
6778
6820
|
this.name = "RecordSecretUnavailableError";
|
|
6779
6821
|
}
|
|
6780
6822
|
};
|
|
6781
|
-
var InvalidRecordError = class extends RecordsError {
|
|
6823
|
+
var InvalidRecordError = class InvalidRecordError extends RecordsError {
|
|
6824
|
+
static code = "invalid-record";
|
|
6782
6825
|
constructor(detail) {
|
|
6783
|
-
super(
|
|
6826
|
+
super(InvalidRecordError.code, detail);
|
|
6784
6827
|
this.name = "InvalidRecordError";
|
|
6785
6828
|
}
|
|
6786
6829
|
};
|
|
6787
6830
|
/** A kind declaration the engine refuses (non-additive change, bad shape, wrong file). */
|
|
6788
|
-
var DeclarationRefusedError = class extends RecordsError {
|
|
6831
|
+
var DeclarationRefusedError = class DeclarationRefusedError extends RecordsError {
|
|
6832
|
+
static code = "declaration-refused";
|
|
6789
6833
|
constructor(detail) {
|
|
6790
|
-
super(
|
|
6834
|
+
super(DeclarationRefusedError.code, detail);
|
|
6791
6835
|
this.name = "DeclarationRefusedError";
|
|
6792
6836
|
}
|
|
6793
6837
|
};
|
|
@@ -7281,17 +7325,35 @@ var RecordIntegrationInstances = class {
|
|
|
7281
7325
|
...kind !== void 0 ? { kind } : {}
|
|
7282
7326
|
});
|
|
7283
7327
|
if (minted === void 0) throw new Error("createInstance needs an id: this provider does not mint one");
|
|
7328
|
+
const initial = this.hooks.initialBody(name, kind);
|
|
7329
|
+
const patch = this.patchOf(values ?? {});
|
|
7330
|
+
if (Object.keys(patch).length > 0) Object.assign(patch, await this.hooks.validateWrite?.({
|
|
7331
|
+
kind,
|
|
7332
|
+
body: {
|
|
7333
|
+
...initial,
|
|
7334
|
+
...patch
|
|
7335
|
+
}
|
|
7336
|
+
}));
|
|
7284
7337
|
await this.handle.put({
|
|
7285
7338
|
id: minted,
|
|
7286
|
-
data:
|
|
7339
|
+
data: initial
|
|
7287
7340
|
}, { ifRev: 0 });
|
|
7288
|
-
const patch = this.patchOf(values ?? {});
|
|
7289
7341
|
if (Object.keys(patch).length > 0) await this.handle.patch(minted, patch);
|
|
7290
7342
|
await this.hooks.onChanged?.(minted, "created");
|
|
7291
7343
|
return { id: minted };
|
|
7292
7344
|
};
|
|
7293
7345
|
updateInstance = async ({ id, name, values }) => {
|
|
7294
7346
|
const patch = this.patchOf(values);
|
|
7347
|
+
if (this.hooks.validateWrite !== void 0 && Object.keys(patch).length > 0) {
|
|
7348
|
+
const stored = await this.handle.get(id);
|
|
7349
|
+
if (stored !== null) Object.assign(patch, await this.hooks.validateWrite({
|
|
7350
|
+
kind: void 0,
|
|
7351
|
+
body: {
|
|
7352
|
+
...stored.data,
|
|
7353
|
+
...patch
|
|
7354
|
+
}
|
|
7355
|
+
}));
|
|
7356
|
+
}
|
|
7295
7357
|
if (name !== void 0) patch[this.nameField] = name;
|
|
7296
7358
|
await this.handle.patch(id, patch);
|
|
7297
7359
|
await this.hooks.onChanged?.(id, "updated");
|
|
@@ -10637,7 +10699,6 @@ var CAP_NAMES = Object.freeze([
|
|
|
10637
10699
|
"notifier",
|
|
10638
10700
|
"numeric-sensor",
|
|
10639
10701
|
"oauth-integration",
|
|
10640
|
-
"oidc-connections",
|
|
10641
10702
|
"osd",
|
|
10642
10703
|
"osd-manager",
|
|
10643
10704
|
"pet-feeder",
|
|
@@ -12529,8 +12590,7 @@ Object.freeze({
|
|
|
12529
12590
|
"device-provider": { "reloadDevice": 18e4 },
|
|
12530
12591
|
"llm": {
|
|
12531
12592
|
"generate": 6e5,
|
|
12532
|
-
"generateVision": 6e5
|
|
12533
|
-
"testProfile": 6e5
|
|
12593
|
+
"generateVision": 6e5
|
|
12534
12594
|
},
|
|
12535
12595
|
"llm-runtime": {
|
|
12536
12596
|
"complete": 6e5,
|
|
@@ -14141,17 +14201,18 @@ function composeInstanceKinds(parts, base) {
|
|
|
14141
14201
|
* message to what the kind supports — callers never special-case a service.
|
|
14142
14202
|
*
|
|
14143
14203
|
* DESIGN DECISIONS (locked):
|
|
14144
|
-
* -
|
|
14145
|
-
*
|
|
14146
|
-
*
|
|
14147
|
-
*
|
|
14148
|
-
*
|
|
14149
|
-
*
|
|
14150
|
-
*
|
|
14151
|
-
*
|
|
14152
|
-
*
|
|
14153
|
-
* routable. `send` / `testTarget` /
|
|
14154
|
-
* `
|
|
14204
|
+
* - A target is an INSTANCE of this function cap (epic #440, step 6): the
|
|
14205
|
+
* providers serve their targets as `integration-instances` records, one
|
|
14206
|
+
* record kind per target kind, and the admin lists, adds, edits, switches
|
|
14207
|
+
* and deletes them through that cap. This cap keeps what an instance cannot
|
|
14208
|
+
* say: the kind catalogue (`listTargetKinds`: capabilities, delivery
|
|
14209
|
+
* parameters, brand icon), dispatch (`send`, `testTarget`) and the form
|
|
14210
|
+
* helpers (`discoverTargets`, `probeTargetConfig`).
|
|
14211
|
+
* - `listTargetKinds` / `discoverTargets` return arrays → the generated
|
|
14212
|
+
* cap-mount auto-`concatCollection`-fans them across every registered
|
|
14213
|
+
* provider so one catalog is routable. `send` / `testTarget` /
|
|
14214
|
+
* `probeTargetConfig` route to ONE provider by the `addonId` the generated
|
|
14215
|
+
* collection router extracts from the call input.
|
|
14155
14216
|
* - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
|
|
14156
14217
|
* transformer) + UDS MsgPack both round-trip typed arrays — already used by
|
|
14157
14218
|
* `storage` / `storage-provider` / `recording` caps over the same path. No
|
|
@@ -14396,7 +14457,7 @@ var TargetKindCapsSchema = object({
|
|
|
14396
14457
|
* the union is large and not meant for runtime validation here; the exported
|
|
14397
14458
|
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
14398
14459
|
*/
|
|
14399
|
-
var ConfigSchemaPassthrough$
|
|
14460
|
+
var ConfigSchemaPassthrough$3 = unknown();
|
|
14400
14461
|
var TargetKindSchema = object({
|
|
14401
14462
|
kind: string(),
|
|
14402
14463
|
label: string(),
|
|
@@ -14433,7 +14494,7 @@ var TargetKindSchema = object({
|
|
|
14433
14494
|
* its raster path, which is the safe default for an unknown image.
|
|
14434
14495
|
*/
|
|
14435
14496
|
iconMediaType: string().optional(),
|
|
14436
|
-
configSchema: ConfigSchemaPassthrough$
|
|
14497
|
+
configSchema: ConfigSchemaPassthrough$3,
|
|
14437
14498
|
/**
|
|
14438
14499
|
* The config keys that decide WHERE this kind's secrets are sent (server,
|
|
14439
14500
|
* base URL, instance, chat, recipient). A save that changes any of them
|
|
@@ -14455,9 +14516,11 @@ var TargetKindSchema = object({
|
|
|
14455
14516
|
caps: TargetKindCapsSchema
|
|
14456
14517
|
});
|
|
14457
14518
|
/**
|
|
14458
|
-
* A
|
|
14459
|
-
*
|
|
14460
|
-
*
|
|
14519
|
+
* A target as a provider's own code sees it (the notification-center bridge, the
|
|
14520
|
+
* send path): the flat record body split into the name, the switch and the
|
|
14521
|
+
* kind's fields. `config` holds secrets; a reader that serves it to a client
|
|
14522
|
+
* REDACTS secret fields (a presence marker only) — never round-trip a stored
|
|
14523
|
+
* secret to the UI.
|
|
14461
14524
|
*/
|
|
14462
14525
|
var TargetSchema = object({
|
|
14463
14526
|
id: string(),
|
|
@@ -14506,21 +14569,13 @@ var notificationOutputCapability = {
|
|
|
14506
14569
|
mode: "collection",
|
|
14507
14570
|
methods: {
|
|
14508
14571
|
listTargetKinds: method(object({}), array(TargetKindSchema)),
|
|
14509
|
-
listTargets: method(object({}), array(TargetSchema), { auth: "admin" }),
|
|
14510
|
-
/**
|
|
14511
|
-
* One target WITH secrets — admin edit / duplicate hydration only.
|
|
14512
|
-
* `listTargets` stays redacted; the editor loads this so password fields
|
|
14513
|
-
* are filled (masked in the input) and a save can round-trip the token
|
|
14514
|
-
* when a destination changes (Duplicate with a new chatId, etc.).
|
|
14515
|
-
*/
|
|
14516
|
-
getTarget: method(object({ targetId: string() }), TargetSchema, { auth: "admin" }),
|
|
14517
14572
|
discoverTargets: method(object({
|
|
14518
14573
|
kind: string(),
|
|
14519
14574
|
config: record(string(), unknown()).optional(),
|
|
14520
14575
|
/**
|
|
14521
14576
|
* When editing / duplicating, the blank password field never round-trips
|
|
14522
14577
|
* the stored token. Pass the source target id so the provider can restore
|
|
14523
|
-
* secrets server-side before dialling
|
|
14578
|
+
* secrets server-side before dialling.
|
|
14524
14579
|
*/
|
|
14525
14580
|
targetId: string().optional()
|
|
14526
14581
|
}), array(DiscoveredTargetSchema), { auth: "admin" }),
|
|
@@ -14546,30 +14601,6 @@ var notificationOutputCapability = {
|
|
|
14546
14601
|
}), TestResultSchema, {
|
|
14547
14602
|
kind: "mutation",
|
|
14548
14603
|
auth: "admin"
|
|
14549
|
-
}),
|
|
14550
|
-
upsertTarget: method(object({
|
|
14551
|
-
target: TargetSchema,
|
|
14552
|
-
/**
|
|
14553
|
-
* Duplicate flow: create a NEW target id while copying secrets from an
|
|
14554
|
-
* existing row. The UI never holds the stored token; blank / redacted
|
|
14555
|
-
* password fields are restored from this source (D634 still applies if
|
|
14556
|
-
* destinations diverge without a re-typed secret).
|
|
14557
|
-
*/
|
|
14558
|
-
cloneSecretsFrom: string().optional()
|
|
14559
|
-
}), TargetSchema, {
|
|
14560
|
-
kind: "mutation",
|
|
14561
|
-
auth: "admin"
|
|
14562
|
-
}),
|
|
14563
|
-
deleteTarget: method(object({ targetId: string() }), _void(), {
|
|
14564
|
-
kind: "mutation",
|
|
14565
|
-
auth: "admin"
|
|
14566
|
-
}),
|
|
14567
|
-
setTargetEnabled: method(object({
|
|
14568
|
-
targetId: string(),
|
|
14569
|
-
enabled: boolean()
|
|
14570
|
-
}), _void(), {
|
|
14571
|
-
kind: "mutation",
|
|
14572
|
-
auth: "admin"
|
|
14573
14604
|
})
|
|
14574
14605
|
}
|
|
14575
14606
|
};
|
|
@@ -14585,8 +14616,9 @@ var notificationOutputCapability = {
|
|
|
14585
14616
|
*
|
|
14586
14617
|
* Three providers (notifiers, Home Assistant, Alexa) serve the same shape, so the pieces are shared:
|
|
14587
14618
|
* - {@link defineNotificationTargetKind}: the record kind of one `TargetKind` descriptor;
|
|
14588
|
-
* - {@link NotificationTargetStore}: the `Target`-shaped facade the
|
|
14589
|
-
* using, over one handle per kind
|
|
14619
|
+
* - {@link NotificationTargetStore}: the `Target`-shaped facade the provider's own code keeps
|
|
14620
|
+
* using (send, the notification-center bridge), over one handle per kind;
|
|
14621
|
+
* - {@link listNotificationTargets}: the targets as an addon on `ctx.api` reads them;
|
|
14590
14622
|
* - {@link buildNotificationTargetInstances}: the `integration-instances` provider, one kind each;
|
|
14591
14623
|
* - {@link moveTargetRows}: the D987 procedure that flattens the old `config` blobs into the bodies.
|
|
14592
14624
|
*/
|
|
@@ -14843,6 +14875,10 @@ function notificationTargetParts(records, spec) {
|
|
|
14843
14875
|
initialBody: (name) => ({ name }),
|
|
14844
14876
|
mintId: () => spec.mintId(),
|
|
14845
14877
|
configured: () => true,
|
|
14878
|
+
validateWrite: ({ body }) => spec.validate?.({
|
|
14879
|
+
kind: descriptor.kind,
|
|
14880
|
+
config: body
|
|
14881
|
+
}),
|
|
14846
14882
|
test: async ({ id, values }) => {
|
|
14847
14883
|
if (spec.probe === void 0 || !canTest) return {
|
|
14848
14884
|
success: false,
|
|
@@ -23238,7 +23274,6 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
23238
23274
|
"notification-output": system("notification delivery — reached through notifier devices and rules"),
|
|
23239
23275
|
"notification-rules": system("notification rules — authored on their own page"),
|
|
23240
23276
|
"oauth-integration": system(IDENTITY),
|
|
23241
|
-
"oidc-connections": system(IDENTITY),
|
|
23242
23277
|
"osd-manager": system(PIPELINE),
|
|
23243
23278
|
"pipeline-executor": system(PIPELINE),
|
|
23244
23279
|
"pipeline-orchestrator": system(PIPELINE),
|
|
@@ -57030,7 +57065,7 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57030
57065
|
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
57031
57066
|
* clears it.
|
|
57032
57067
|
*/
|
|
57033
|
-
var ConfigSchemaPassthrough$
|
|
57068
|
+
var ConfigSchemaPassthrough$2 = custom();
|
|
57034
57069
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
57035
57070
|
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
57036
57071
|
/**
|
|
@@ -57076,7 +57111,16 @@ var IntegrationInstanceKindSchema = object({
|
|
|
57076
57111
|
/** Relative hub path to start an interactive account link of an instance of this kind. */
|
|
57077
57112
|
connectPath: string().min(1).optional(),
|
|
57078
57113
|
/** Relative hub path to disconnect that account. */
|
|
57079
|
-
disconnectPath: string().min(1).optional()
|
|
57114
|
+
disconnectPath: string().min(1).optional(),
|
|
57115
|
+
/**
|
|
57116
|
+
* Parts of the edit dialog the flat form cannot draw (a node picker, a model source), named by a
|
|
57117
|
+
* GENERIC widget id the client maps to a component; a client that knows none of them shows none.
|
|
57118
|
+
* `connection` widgets write connection values, `model` widgets own the model choice.
|
|
57119
|
+
*/
|
|
57120
|
+
widgets: array(object({
|
|
57121
|
+
id: string().min(1),
|
|
57122
|
+
placement: _enum(["connection", "model"])
|
|
57123
|
+
})).optional()
|
|
57080
57124
|
});
|
|
57081
57125
|
/**
|
|
57082
57126
|
* How devices of an instance are found. `none`: the operator adds them by hand; `lan`: the addon
|
|
@@ -57181,7 +57225,7 @@ var integrationInstancesCapability = {
|
|
|
57181
57225
|
id: IntegrationInstanceIdSchema.nullable(),
|
|
57182
57226
|
/** The kind of the create form (`id: null`) of a provider with several. */
|
|
57183
57227
|
kind: string().min(1).optional()
|
|
57184
|
-
}), ConfigSchemaPassthrough$
|
|
57228
|
+
}), ConfigSchemaPassthrough$2, { auth: "admin" }),
|
|
57185
57229
|
listInstances: method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }),
|
|
57186
57230
|
getInstance: method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }),
|
|
57187
57231
|
/**
|
|
@@ -58283,12 +58327,12 @@ var LlmModelInfoSchema = object({
|
|
|
58283
58327
|
});
|
|
58284
58328
|
/**
|
|
58285
58329
|
* The provider-specific part of a profile, validated by the provider that owns
|
|
58286
|
-
* the kind (
|
|
58330
|
+
* the kind (saving an instance refuses what it does not accept). A field its
|
|
58287
58331
|
* `connectionSchema` declares `type: 'password'` is a secret: it is held in the
|
|
58288
58332
|
* keychain, never in the row, and reads back as the redaction marker.
|
|
58289
58333
|
*/
|
|
58290
58334
|
var LlmProviderConfigSchema = record(string(), unknown());
|
|
58291
|
-
|
|
58335
|
+
object({
|
|
58292
58336
|
id: string(),
|
|
58293
58337
|
name: string(),
|
|
58294
58338
|
/** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
|
|
@@ -58382,8 +58426,8 @@ var LlmProviderWidgetSchema = object({
|
|
|
58382
58426
|
/** ConfigUISchema tree passed through untyped on the wire (the
|
|
58383
58427
|
* notification-output `ConfigSchemaPassthrough` precedent at
|
|
58384
58428
|
* notification-output.cap.ts:151); the exported TS type re-tightens it. */
|
|
58385
|
-
var ConfigSchemaPassthrough$
|
|
58386
|
-
|
|
58429
|
+
var ConfigSchemaPassthrough$1 = unknown();
|
|
58430
|
+
object({
|
|
58387
58431
|
kind: LlmProfileKindSchema,
|
|
58388
58432
|
label: string(),
|
|
58389
58433
|
/** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
|
|
@@ -58391,9 +58435,9 @@ var LlmProfileKindDescriptorSchema = object({
|
|
|
58391
58435
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
58392
58436
|
addonId: string(),
|
|
58393
58437
|
/** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
|
|
58394
|
-
connectionSchema: ConfigSchemaPassthrough$
|
|
58438
|
+
connectionSchema: ConfigSchemaPassthrough$1,
|
|
58395
58439
|
/** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
|
|
58396
|
-
advancedSchema: ConfigSchemaPassthrough$
|
|
58440
|
+
advancedSchema: ConfigSchemaPassthrough$1.optional(),
|
|
58397
58441
|
/** The kind's defaults; a model from `listModels` may override any of them. */
|
|
58398
58442
|
features: LlmModelFeaturesSchema,
|
|
58399
58443
|
/** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
|
|
@@ -58522,20 +58566,7 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
|
|
|
58522
58566
|
}), method(object({
|
|
58523
58567
|
addonId: string().optional(),
|
|
58524
58568
|
requestId: string()
|
|
58525
|
-
}), _void(), { kind: "mutation" }), method(
|
|
58526
|
-
kind: "mutation",
|
|
58527
|
-
auth: "admin"
|
|
58528
|
-
}), method(RawSecretMigrationInputSchema, RawSecretMigrationReportSchema, {
|
|
58529
|
-
kind: "mutation",
|
|
58530
|
-
auth: "admin"
|
|
58531
|
-
}), method(ProfileRefInputSchema, _void(), {
|
|
58532
|
-
kind: "mutation",
|
|
58533
|
-
auth: "admin"
|
|
58534
|
-
}), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
|
|
58535
|
-
kind: "mutation",
|
|
58536
|
-
auth: "admin",
|
|
58537
|
-
timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
|
|
58538
|
-
}), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
58569
|
+
}), _void(), { kind: "mutation" }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
58539
58570
|
kind: "mutation",
|
|
58540
58571
|
auth: "admin"
|
|
58541
58572
|
}), method(object({}), array(LlmDefaultSchema)), method(object({
|
|
@@ -59598,20 +59629,7 @@ method(_void(), MeshStatusSchema), method(object({
|
|
|
59598
59629
|
/** Optional hostname override the host should advertise once joined. */
|
|
59599
59630
|
hostname: string().optional() }), object({
|
|
59600
59631
|
/** Authentication URL the operator should open in a browser. */
|
|
59601
|
-
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }))
|
|
59602
|
-
/** Optional auth key — when provided, probes the key validity
|
|
59603
|
-
* against the provider's API. Omit when already joined to
|
|
59604
|
-
* just ping the daemon. */
|
|
59605
|
-
authKey: string().optional() }), object({
|
|
59606
|
-
ok: boolean(),
|
|
59607
|
-
/** Provider-side identifier resolved by the probe (tailnet
|
|
59608
|
-
* name for Tailscale, network id for ZeroTier, etc.). */
|
|
59609
|
-
tenant: string().optional(),
|
|
59610
|
-
/** Daemon binary version, when reachable. */
|
|
59611
|
-
daemonVersion: string().optional(),
|
|
59612
|
-
/** Human-readable error when `ok: false`. */
|
|
59613
|
-
error: string().optional()
|
|
59614
|
-
}), { kind: "mutation" });
|
|
59632
|
+
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }));
|
|
59615
59633
|
/**
|
|
59616
59634
|
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
59617
59635
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
@@ -69818,61 +69836,6 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
69818
69836
|
});
|
|
69819
69837
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
69820
69838
|
/**
|
|
69821
|
-
* `oidc-connections` — CRUD for IdP rows under `auth-oidc` (D828 sibling).
|
|
69822
|
-
*
|
|
69823
|
-
* One hub-only singleton (`auth-oidc`). The Settings UI is a DataTable +
|
|
69824
|
-
* ItemFormDialog; there is no `editable-array` in `globalSettingsSchema`.
|
|
69825
|
-
* Operator-chosen `id` is the URL slug (`/addon/auth-oidc/<id>/…`) and is
|
|
69826
|
-
* immutable after create.
|
|
69827
|
-
*/
|
|
69828
|
-
var ConfigSchemaPassthrough$1 = unknown();
|
|
69829
|
-
var OidcConnectionSchema = object({
|
|
69830
|
-
id: string().min(1),
|
|
69831
|
-
displayName: string(),
|
|
69832
|
-
icon: string(),
|
|
69833
|
-
issuerUrl: string(),
|
|
69834
|
-
clientId: string(),
|
|
69835
|
-
/** Client id + secret present — never the secret value. */
|
|
69836
|
-
configured: boolean(),
|
|
69837
|
-
/**
|
|
69838
|
-
* Values for the connection form schema. `clientSecret` is a keychain
|
|
69839
|
-
* {@link SecretFieldView} or `null` / `''`, never plaintext (D789).
|
|
69840
|
-
*/
|
|
69841
|
-
formValues: record(string(), unknown()).optional()
|
|
69842
|
-
});
|
|
69843
|
-
/**
|
|
69844
|
-
* Patch one connection. Omitted or empty `clientSecret` keeps the stored
|
|
69845
|
-
* secret (D787). `{ $secretClear: true }` clears it. `id` is never renamed.
|
|
69846
|
-
*/
|
|
69847
|
-
var OidcConnectionUpdateInputSchema = object({
|
|
69848
|
-
id: string().min(1),
|
|
69849
|
-
displayName: string().min(1),
|
|
69850
|
-
icon: string().optional(),
|
|
69851
|
-
issuerUrl: string().optional(),
|
|
69852
|
-
clientId: string().optional(),
|
|
69853
|
-
clientSecret: union([string(), object({ $secretClear: literal(true) })]).optional(),
|
|
69854
|
-
redirectUri: string().optional(),
|
|
69855
|
-
scopes: string().optional(),
|
|
69856
|
-
usernameClaim: _enum([
|
|
69857
|
-
"preferred_username",
|
|
69858
|
-
"email",
|
|
69859
|
-
"sub"
|
|
69860
|
-
]).optional()
|
|
69861
|
-
});
|
|
69862
|
-
method(object({}), ConfigSchemaPassthrough$1, { auth: "admin" }), method(object({}), array(OidcConnectionSchema).readonly(), { auth: "admin" }), method(object({
|
|
69863
|
-
id: string().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug"),
|
|
69864
|
-
displayName: string().min(1)
|
|
69865
|
-
}), object({ id: string() }), {
|
|
69866
|
-
kind: "mutation",
|
|
69867
|
-
auth: "admin"
|
|
69868
|
-
}), method(OidcConnectionUpdateInputSchema, object({ ok: literal(true) }), {
|
|
69869
|
-
kind: "mutation",
|
|
69870
|
-
auth: "admin"
|
|
69871
|
-
}), method(object({ id: string().min(1) }), object({ ok: literal(true) }), {
|
|
69872
|
-
kind: "mutation",
|
|
69873
|
-
auth: "admin"
|
|
69874
|
-
});
|
|
69875
|
-
/**
|
|
69876
69839
|
* Generic on-screen-display (video overlay) cap. Each camera exposes
|
|
69877
69840
|
* a firmware-defined list of overlays (channel name, timestamp,
|
|
69878
69841
|
* watermark, logo, …); the cap models them as a homogeneous array of
|
|
@@ -76954,21 +76917,6 @@ method(object({
|
|
|
76954
76917
|
*/
|
|
76955
76918
|
ttlSec: union([number$1().int().positive(), literal("never")]).optional()
|
|
76956
76919
|
}), object({ token: string() }), { auth: "admin" }), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable(), { auth: "admin" });
|
|
76957
|
-
var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
|
|
76958
|
-
providerId: string().min(1),
|
|
76959
|
-
displayName: string().min(1),
|
|
76960
|
-
configSchema: unknown(),
|
|
76961
|
-
nodeLocal: boolean(),
|
|
76962
|
-
shouldSaveDiskSpace: literal(true),
|
|
76963
|
-
minFreePercent: number$1().min(0).max(100)
|
|
76964
|
-
}), object({
|
|
76965
|
-
providerId: string().min(1),
|
|
76966
|
-
displayName: string().min(1),
|
|
76967
|
-
configSchema: unknown(),
|
|
76968
|
-
nodeLocal: boolean(),
|
|
76969
|
-
shouldSaveDiskSpace: literal(false),
|
|
76970
|
-
minFreePercent: literal(null)
|
|
76971
|
-
})]);
|
|
76972
76920
|
method(object({
|
|
76973
76921
|
location: StorageLocationRefSchema,
|
|
76974
76922
|
relativePath: string()
|
|
@@ -77030,42 +76978,7 @@ method(object({
|
|
|
77030
76978
|
}), _instanceof(Uint8Array), { auth: "admin" }), method(object({ downloadId: string() }), _void(), {
|
|
77031
76979
|
kind: "mutation",
|
|
77032
76980
|
auth: "admin"
|
|
77033
|
-
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(
|
|
77034
|
-
createdAt: true,
|
|
77035
|
-
updatedAt: true
|
|
77036
|
-
}), StorageLocationSchema, {
|
|
77037
|
-
kind: "mutation",
|
|
77038
|
-
auth: "admin"
|
|
77039
|
-
}), method(object({
|
|
77040
|
-
id: string(),
|
|
77041
|
-
force: boolean().optional()
|
|
77042
|
-
}), _void(), {
|
|
77043
|
-
kind: "mutation",
|
|
77044
|
-
auth: "admin"
|
|
77045
|
-
}), method(_void(), array(StorageDrainProgressSchema).readonly()), method(object({ id: string() }), object({
|
|
77046
|
-
ok: boolean(),
|
|
77047
|
-
error: string().optional()
|
|
77048
|
-
}), { auth: "admin" }), method(_void(), array(ProviderListEntrySchema).readonly()), method(object({
|
|
77049
|
-
providerId: string(),
|
|
77050
|
-
/**
|
|
77051
|
-
* The location this config is an UNSAVED edit of, when there is one.
|
|
77052
|
-
*
|
|
77053
|
-
* `listLocations` replaces every declared secret with the redaction
|
|
77054
|
-
* sentinel, so the edit modal's form state holds the sentinel for any
|
|
77055
|
-
* credential the operator did not retype — and posting that here
|
|
77056
|
-
* without a way to resolve it makes the provider try to authenticate
|
|
77057
|
-
* as `__camstack_redacted__` and report the operator's own working
|
|
77058
|
-
* password as wrong. Given this id, the orchestrator restores each
|
|
77059
|
-
* sentinel from the stored config (same rule as `upsertLocation`)
|
|
77060
|
-
* before dispatching. Omitted by the "Add location" wizard, where
|
|
77061
|
-
* every value was typed just now and nothing is stored yet.
|
|
77062
|
-
*/
|
|
77063
|
-
locationId: string().optional(),
|
|
77064
|
-
config: record(string(), unknown())
|
|
77065
|
-
}), object({
|
|
77066
|
-
ok: boolean(),
|
|
77067
|
-
error: string().optional()
|
|
77068
|
-
}), { auth: "admin" });
|
|
76981
|
+
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(_void(), array(StorageDrainProgressSchema).readonly());
|
|
77069
76982
|
/** One table of the settings database. */
|
|
77070
76983
|
var StorageTableSchema = object({
|
|
77071
76984
|
/** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
|
|
@@ -86951,13 +86864,6 @@ Object.freeze({
|
|
|
86951
86864
|
access: "delete",
|
|
86952
86865
|
role: "admin"
|
|
86953
86866
|
},
|
|
86954
|
-
"llm.deleteProfile": {
|
|
86955
|
-
capName: "llm",
|
|
86956
|
-
capScope: "system",
|
|
86957
|
-
addonId: null,
|
|
86958
|
-
access: "delete",
|
|
86959
|
-
role: "admin"
|
|
86960
|
-
},
|
|
86961
86867
|
"llm.generate": {
|
|
86962
86868
|
capName: "llm",
|
|
86963
86869
|
capScope: "system",
|
|
@@ -87021,20 +86927,6 @@ Object.freeze({
|
|
|
87021
86927
|
access: "view",
|
|
87022
86928
|
role: "admin"
|
|
87023
86929
|
},
|
|
87024
|
-
"llm.listProfileKinds": {
|
|
87025
|
-
capName: "llm",
|
|
87026
|
-
capScope: "system",
|
|
87027
|
-
addonId: null,
|
|
87028
|
-
access: "view",
|
|
87029
|
-
role: "admin"
|
|
87030
|
-
},
|
|
87031
|
-
"llm.listProfiles": {
|
|
87032
|
-
capName: "llm",
|
|
87033
|
-
capScope: "system",
|
|
87034
|
-
addonId: null,
|
|
87035
|
-
access: "view",
|
|
87036
|
-
role: "admin"
|
|
87037
|
-
},
|
|
87038
86930
|
"llm.listRuntimeNodes": {
|
|
87039
86931
|
capName: "llm",
|
|
87040
86932
|
capScope: "system",
|
|
@@ -87042,13 +86934,6 @@ Object.freeze({
|
|
|
87042
86934
|
access: "view",
|
|
87043
86935
|
role: "admin"
|
|
87044
86936
|
},
|
|
87045
|
-
"llm.migrateRawSecrets": {
|
|
87046
|
-
capName: "llm",
|
|
87047
|
-
capScope: "system",
|
|
87048
|
-
addonId: null,
|
|
87049
|
-
access: "create",
|
|
87050
|
-
role: "admin"
|
|
87051
|
-
},
|
|
87052
86937
|
"llm.resolveModelRef": {
|
|
87053
86938
|
capName: "llm",
|
|
87054
86939
|
capScope: "system",
|
|
@@ -87077,20 +86962,6 @@ Object.freeze({
|
|
|
87077
86962
|
access: "create",
|
|
87078
86963
|
role: "admin"
|
|
87079
86964
|
},
|
|
87080
|
-
"llm.testProfile": {
|
|
87081
|
-
capName: "llm",
|
|
87082
|
-
capScope: "system",
|
|
87083
|
-
addonId: null,
|
|
87084
|
-
access: "create",
|
|
87085
|
-
role: "admin"
|
|
87086
|
-
},
|
|
87087
|
-
"llm.upsertProfile": {
|
|
87088
|
-
capName: "llm",
|
|
87089
|
-
capScope: "system",
|
|
87090
|
-
addonId: null,
|
|
87091
|
-
access: "create",
|
|
87092
|
-
role: "admin"
|
|
87093
|
-
},
|
|
87094
86965
|
"llmRuntime.appleAvailability": {
|
|
87095
86966
|
capName: "llm-runtime",
|
|
87096
86967
|
capScope: "system",
|
|
@@ -87595,13 +87466,6 @@ Object.freeze({
|
|
|
87595
87466
|
access: "create",
|
|
87596
87467
|
role: "admin"
|
|
87597
87468
|
},
|
|
87598
|
-
"meshNetwork.testConnection": {
|
|
87599
|
-
capName: "mesh-network",
|
|
87600
|
-
capScope: "system",
|
|
87601
|
-
addonId: null,
|
|
87602
|
-
access: "create",
|
|
87603
|
-
role: "admin"
|
|
87604
|
-
},
|
|
87605
87469
|
"meter.getStatus": {
|
|
87606
87470
|
capName: "meter",
|
|
87607
87471
|
capScope: "device",
|
|
@@ -88260,13 +88124,6 @@ Object.freeze({
|
|
|
88260
88124
|
access: "create",
|
|
88261
88125
|
role: "admin"
|
|
88262
88126
|
},
|
|
88263
|
-
"notificationOutput.deleteTarget": {
|
|
88264
|
-
capName: "notification-output",
|
|
88265
|
-
capScope: "system",
|
|
88266
|
-
addonId: null,
|
|
88267
|
-
access: "delete",
|
|
88268
|
-
role: "admin"
|
|
88269
|
-
},
|
|
88270
88127
|
"notificationOutput.discoverTargets": {
|
|
88271
88128
|
capName: "notification-output",
|
|
88272
88129
|
capScope: "system",
|
|
@@ -88274,13 +88131,6 @@ Object.freeze({
|
|
|
88274
88131
|
access: "view",
|
|
88275
88132
|
role: "admin"
|
|
88276
88133
|
},
|
|
88277
|
-
"notificationOutput.getTarget": {
|
|
88278
|
-
capName: "notification-output",
|
|
88279
|
-
capScope: "system",
|
|
88280
|
-
addonId: null,
|
|
88281
|
-
access: "view",
|
|
88282
|
-
role: "admin"
|
|
88283
|
-
},
|
|
88284
88134
|
"notificationOutput.listTargetKinds": {
|
|
88285
88135
|
capName: "notification-output",
|
|
88286
88136
|
capScope: "system",
|
|
@@ -88288,13 +88138,6 @@ Object.freeze({
|
|
|
88288
88138
|
access: "view",
|
|
88289
88139
|
role: "admin"
|
|
88290
88140
|
},
|
|
88291
|
-
"notificationOutput.listTargets": {
|
|
88292
|
-
capName: "notification-output",
|
|
88293
|
-
capScope: "system",
|
|
88294
|
-
addonId: null,
|
|
88295
|
-
access: "view",
|
|
88296
|
-
role: "admin"
|
|
88297
|
-
},
|
|
88298
88141
|
"notificationOutput.probeTargetConfig": {
|
|
88299
88142
|
capName: "notification-output",
|
|
88300
88143
|
capScope: "system",
|
|
@@ -88309,13 +88152,6 @@ Object.freeze({
|
|
|
88309
88152
|
access: "create",
|
|
88310
88153
|
role: "admin"
|
|
88311
88154
|
},
|
|
88312
|
-
"notificationOutput.setTargetEnabled": {
|
|
88313
|
-
capName: "notification-output",
|
|
88314
|
-
capScope: "system",
|
|
88315
|
-
addonId: null,
|
|
88316
|
-
access: "create",
|
|
88317
|
-
role: "admin"
|
|
88318
|
-
},
|
|
88319
88155
|
"notificationOutput.testTarget": {
|
|
88320
88156
|
capName: "notification-output",
|
|
88321
88157
|
capScope: "system",
|
|
@@ -88323,13 +88159,6 @@ Object.freeze({
|
|
|
88323
88159
|
access: "create",
|
|
88324
88160
|
role: "admin"
|
|
88325
88161
|
},
|
|
88326
|
-
"notificationOutput.upsertTarget": {
|
|
88327
|
-
capName: "notification-output",
|
|
88328
|
-
capScope: "system",
|
|
88329
|
-
addonId: null,
|
|
88330
|
-
access: "create",
|
|
88331
|
-
role: "admin"
|
|
88332
|
-
},
|
|
88333
88162
|
"notificationRules.activateAlarmProfile": {
|
|
88334
88163
|
capName: "notification-rules",
|
|
88335
88164
|
capScope: "system",
|
|
@@ -88589,41 +88418,6 @@ Object.freeze({
|
|
|
88589
88418
|
access: "view",
|
|
88590
88419
|
role: "admin"
|
|
88591
88420
|
},
|
|
88592
|
-
"oidcConnections.connectionFormSchema": {
|
|
88593
|
-
capName: "oidc-connections",
|
|
88594
|
-
capScope: "system",
|
|
88595
|
-
addonId: null,
|
|
88596
|
-
access: "view",
|
|
88597
|
-
role: "admin"
|
|
88598
|
-
},
|
|
88599
|
-
"oidcConnections.createConnection": {
|
|
88600
|
-
capName: "oidc-connections",
|
|
88601
|
-
capScope: "system",
|
|
88602
|
-
addonId: null,
|
|
88603
|
-
access: "create",
|
|
88604
|
-
role: "admin"
|
|
88605
|
-
},
|
|
88606
|
-
"oidcConnections.deleteConnection": {
|
|
88607
|
-
capName: "oidc-connections",
|
|
88608
|
-
capScope: "system",
|
|
88609
|
-
addonId: null,
|
|
88610
|
-
access: "delete",
|
|
88611
|
-
role: "admin"
|
|
88612
|
-
},
|
|
88613
|
-
"oidcConnections.listConnections": {
|
|
88614
|
-
capName: "oidc-connections",
|
|
88615
|
-
capScope: "system",
|
|
88616
|
-
addonId: null,
|
|
88617
|
-
access: "view",
|
|
88618
|
-
role: "admin"
|
|
88619
|
-
},
|
|
88620
|
-
"oidcConnections.updateConnection": {
|
|
88621
|
-
capName: "oidc-connections",
|
|
88622
|
-
capScope: "system",
|
|
88623
|
-
addonId: null,
|
|
88624
|
-
access: "create",
|
|
88625
|
-
role: "admin"
|
|
88626
|
-
},
|
|
88627
88421
|
"osd.getStatus": {
|
|
88628
88422
|
capName: "osd",
|
|
88629
88423
|
capScope: "device",
|
|
@@ -91655,13 +91449,6 @@ Object.freeze({
|
|
|
91655
91449
|
access: "delete",
|
|
91656
91450
|
role: "admin"
|
|
91657
91451
|
},
|
|
91658
|
-
"storage.deleteLocation": {
|
|
91659
|
-
capName: "storage",
|
|
91660
|
-
capScope: "system",
|
|
91661
|
-
addonId: null,
|
|
91662
|
-
access: "delete",
|
|
91663
|
-
role: "admin"
|
|
91664
|
-
},
|
|
91665
91452
|
"storage.endDownload": {
|
|
91666
91453
|
capName: "storage",
|
|
91667
91454
|
capScope: "system",
|
|
@@ -91718,13 +91505,6 @@ Object.freeze({
|
|
|
91718
91505
|
access: "view",
|
|
91719
91506
|
role: "admin"
|
|
91720
91507
|
},
|
|
91721
|
-
"storage.listProviders": {
|
|
91722
|
-
capName: "storage",
|
|
91723
|
-
capScope: "system",
|
|
91724
|
-
addonId: null,
|
|
91725
|
-
access: "view",
|
|
91726
|
-
role: "admin"
|
|
91727
|
-
},
|
|
91728
91508
|
"storage.read": {
|
|
91729
91509
|
capName: "storage",
|
|
91730
91510
|
capScope: "system",
|
|
@@ -91746,27 +91526,6 @@ Object.freeze({
|
|
|
91746
91526
|
access: "view",
|
|
91747
91527
|
role: "admin"
|
|
91748
91528
|
},
|
|
91749
|
-
"storage.testConfig": {
|
|
91750
|
-
capName: "storage",
|
|
91751
|
-
capScope: "system",
|
|
91752
|
-
addonId: null,
|
|
91753
|
-
access: "view",
|
|
91754
|
-
role: "admin"
|
|
91755
|
-
},
|
|
91756
|
-
"storage.testLocation": {
|
|
91757
|
-
capName: "storage",
|
|
91758
|
-
capScope: "system",
|
|
91759
|
-
addonId: null,
|
|
91760
|
-
access: "view",
|
|
91761
|
-
role: "admin"
|
|
91762
|
-
},
|
|
91763
|
-
"storage.upsertLocation": {
|
|
91764
|
-
capName: "storage",
|
|
91765
|
-
capScope: "system",
|
|
91766
|
-
addonId: null,
|
|
91767
|
-
access: "create",
|
|
91768
|
-
role: "admin"
|
|
91769
|
-
},
|
|
91770
91529
|
"storage.write": {
|
|
91771
91530
|
capName: "storage",
|
|
91772
91531
|
capScope: "system",
|
|
@@ -145494,6 +145253,33 @@ function quietLogger$1() {
|
|
|
145494
145253
|
};
|
|
145495
145254
|
return logger;
|
|
145496
145255
|
}
|
|
145256
|
+
/**
|
|
145257
|
+
* The account a target speaks through: the one it names; else the only one there is; else the one
|
|
145258
|
+
* whose Echoes include the target's Echo.
|
|
145259
|
+
*/
|
|
145260
|
+
function pickBroker(brokers, config) {
|
|
145261
|
+
const named = readString(config, "brokerId");
|
|
145262
|
+
if (named.length > 0) return brokers.find((broker) => broker.id === named);
|
|
145263
|
+
if (brokers.length === 1) return brokers[0];
|
|
145264
|
+
const echoId = readString(config, "echoId");
|
|
145265
|
+
const owners = brokers.filter((broker) => broker.devices.some((device) => device.id === echoId));
|
|
145266
|
+
return owners.length === 1 ? owners[0] : void 0;
|
|
145267
|
+
}
|
|
145268
|
+
/**
|
|
145269
|
+
* The save-time rule of an Echo target: an Echo and an account must be picked, and the account is
|
|
145270
|
+
* pinned the moment it is known, so a second account added later cannot silently change where an
|
|
145271
|
+
* existing target speaks. Throws the reason; returns the keys to keep with the write.
|
|
145272
|
+
*/
|
|
145273
|
+
function validateEchoTarget(brokers, config) {
|
|
145274
|
+
if (readString(config, "echoId").length === 0) throw new Error("Pick the Echo that should speak");
|
|
145275
|
+
const owner = pickBroker(brokers, config);
|
|
145276
|
+
if (owner === void 0) {
|
|
145277
|
+
const named = readString(config, "brokerId");
|
|
145278
|
+
if (named.length > 0) throw new Error(`The Amazon account ${named} is not available`);
|
|
145279
|
+
throw new Error(brokers.length === 0 ? "Add an Amazon account first: an Echo speaks through one" : "Pick the Amazon account this Echo belongs to");
|
|
145280
|
+
}
|
|
145281
|
+
return readString(config, "brokerId").length === 0 ? { brokerId: owner.id } : {};
|
|
145282
|
+
}
|
|
145497
145283
|
function readString(config, key) {
|
|
145498
145284
|
const value = config[key];
|
|
145499
145285
|
return typeof value === "string" ? value : "";
|
|
@@ -145523,7 +145309,7 @@ function echoOptionLabel(device) {
|
|
|
145523
145309
|
/**
|
|
145524
145310
|
* The two pickers are not `required`: a required select shows its first option
|
|
145525
145311
|
* while the form still holds no value, so a save would drop the choice. Left
|
|
145526
|
-
* optional they open on "Select", and `
|
|
145312
|
+
* optional they open on "Select", and `validateEchoTarget` refuses an empty pick on save.
|
|
145527
145313
|
*
|
|
145528
145314
|
* The account is a broker pick (existing, or created in place); the Echo list
|
|
145529
145315
|
* is fetched from that account, so a new Echo shows up without a deploy.
|
|
@@ -145615,18 +145401,8 @@ function createAlexaNotificationProvider(ports) {
|
|
|
145615
145401
|
function record(row) {
|
|
145616
145402
|
deliveries = [...deliveries, row];
|
|
145617
145403
|
}
|
|
145618
|
-
/**
|
|
145619
|
-
* The account a target speaks through: the one it names; else the only one
|
|
145620
|
-
* there is; else the one whose Echoes include the target's Echo.
|
|
145621
|
-
*/
|
|
145622
145404
|
function brokerFor(config) {
|
|
145623
|
-
|
|
145624
|
-
const named = readString(config, "brokerId");
|
|
145625
|
-
if (named.length > 0) return all.find((broker) => broker.id === named);
|
|
145626
|
-
if (all.length === 1) return all[0];
|
|
145627
|
-
const echoId = readString(config, "echoId");
|
|
145628
|
-
const owners = all.filter((broker) => broker.devices.some((device) => device.id === echoId));
|
|
145629
|
-
return owners.length === 1 ? owners[0] : void 0;
|
|
145405
|
+
return pickBroker(ports.brokers(), config);
|
|
145630
145406
|
}
|
|
145631
145407
|
async function deliver(target, notification) {
|
|
145632
145408
|
const speech = speechFromNotification(notification);
|
|
@@ -145828,14 +145604,6 @@ function createAlexaNotificationProvider(ports) {
|
|
|
145828
145604
|
async listTargetKinds() {
|
|
145829
145605
|
return [alexaTargetKind()];
|
|
145830
145606
|
},
|
|
145831
|
-
async listTargets() {
|
|
145832
|
-
return [...await ports.loadTargets()];
|
|
145833
|
-
},
|
|
145834
|
-
async getTarget(input) {
|
|
145835
|
-
const found = (await ports.loadTargets()).find((target) => target.id === input.targetId);
|
|
145836
|
-
if (found === void 0) throw new Error(`target not found: ${input.targetId}`);
|
|
145837
|
-
return found;
|
|
145838
|
-
},
|
|
145839
145607
|
async discoverTargets(input) {
|
|
145840
145608
|
for (const broker of ports.brokers()) if (!broker.ready) ports.logger.warn(`alexa echo discovery: no Echo listed for '${broker.name}', the Amazon account is not signed in for this broker`, { tags: { brokerId: broker.id } });
|
|
145841
145609
|
const named = readString(input.config ?? {}, "brokerId");
|
|
@@ -145896,33 +145664,6 @@ function createAlexaNotificationProvider(ports) {
|
|
|
145896
145664
|
format: "text",
|
|
145897
145665
|
priority: 3
|
|
145898
145666
|
});
|
|
145899
|
-
},
|
|
145900
|
-
async upsertTarget(input) {
|
|
145901
|
-
const owner = brokerFor(input.target.config);
|
|
145902
|
-
if (readString(input.target.config, "echoId").length === 0) throw new Error("Pick the Echo that should speak");
|
|
145903
|
-
if (owner === void 0) throw new Error("Pick the Amazon account this Echo belongs to");
|
|
145904
|
-
const pinned = readString(input.target.config, "brokerId").length === 0 ? {
|
|
145905
|
-
...input.target.config,
|
|
145906
|
-
brokerId: owner.id
|
|
145907
|
-
} : input.target.config;
|
|
145908
|
-
const target = {
|
|
145909
|
-
...input.target,
|
|
145910
|
-
config: pinned,
|
|
145911
|
-
addonId: ALEXA_SPEAK_ADDON_ID,
|
|
145912
|
-
kind: ALEXA_SPEAK_KIND
|
|
145913
|
-
};
|
|
145914
|
-
await ports.putTarget(target);
|
|
145915
|
-
return target;
|
|
145916
|
-
},
|
|
145917
|
-
async deleteTarget(input) {
|
|
145918
|
-
await ports.removeTarget(input.targetId);
|
|
145919
|
-
},
|
|
145920
|
-
async setTargetEnabled(input) {
|
|
145921
|
-
const found = (await ports.loadTargets()).find((row) => row.id === input.targetId);
|
|
145922
|
-
if (found !== void 0) await ports.putTarget({
|
|
145923
|
-
...found,
|
|
145924
|
-
enabled: input.enabled
|
|
145925
|
-
});
|
|
145926
145667
|
}
|
|
145927
145668
|
};
|
|
145928
145669
|
}
|
|
@@ -146013,6 +145754,14 @@ function echoTargetProbe(speak) {
|
|
|
146013
145754
|
});
|
|
146014
145755
|
};
|
|
146015
145756
|
}
|
|
145757
|
+
/**
|
|
145758
|
+
* The Echo instance's save-time rule over the accounts now (D1013): the check the removed
|
|
145759
|
+
* `upsertTarget` made, on the instance door. Speech not started yet has no account to name, so the
|
|
145760
|
+
* write is refused with the reason, never accepted blind.
|
|
145761
|
+
*/
|
|
145762
|
+
function echoTargetValidator(brokers) {
|
|
145763
|
+
return ({ config }) => validateEchoTarget(brokers() ?? [], config);
|
|
145764
|
+
}
|
|
146016
145765
|
process.platform, process.env["SystemRoot"];
|
|
146017
145766
|
/**
|
|
146018
145767
|
* Files only their owner may read: the one place a secret-bearing file is
|
|
@@ -146853,8 +146602,6 @@ var AlexaSpeakController = class {
|
|
|
146853
146602
|
now: this.now,
|
|
146854
146603
|
logger: host.logger,
|
|
146855
146604
|
loadTargets: () => host.readTargets(),
|
|
146856
|
-
putTarget: (target) => host.putTarget(target),
|
|
146857
|
-
removeTarget: (targetId) => host.removeTarget(targetId),
|
|
146858
146605
|
speak: (command) => this.utter(command.brokerId, command.mode, command.targets, command.text)
|
|
146859
146606
|
});
|
|
146860
146607
|
}
|
|
@@ -146884,6 +146631,7 @@ var AlexaSpeakController = class {
|
|
|
146884
146631
|
echoFor(brokerId) {
|
|
146885
146632
|
return this.echoes.get(brokerId) ?? null;
|
|
146886
146633
|
}
|
|
146634
|
+
/** The accounts right now, as the provider and the save-time rule see them. */
|
|
146887
146635
|
brokerViews() {
|
|
146888
146636
|
return this.host.listBrokers().map((ref) => {
|
|
146889
146637
|
const echo = this.echoes.get(ref.id);
|
|
@@ -147431,8 +147179,6 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
147431
147179
|
const speak = new AlexaSpeakController({
|
|
147432
147180
|
logger: this.ctx.logger.child("speak"),
|
|
147433
147181
|
readTargets: () => echoStore.list(),
|
|
147434
|
-
putTarget: (target) => echoStore.upsert(target),
|
|
147435
|
-
removeTarget: (targetId) => echoStore.delete(targetId),
|
|
147436
147182
|
listBrokers: () => this.activeBrokers.map((entry) => ({
|
|
147437
147183
|
id: entry.id,
|
|
147438
147184
|
name: entry.name,
|
|
@@ -147534,6 +147280,7 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
147534
147280
|
kinds: alexaNotifyRecordKinds,
|
|
147535
147281
|
mintId: () => (0, node_crypto.randomUUID)(),
|
|
147536
147282
|
probe: echoTargetProbe(() => this.speak),
|
|
147283
|
+
validate: echoTargetValidator(() => this.speak?.brokerViews() ?? null),
|
|
147537
147284
|
canProbe: () => true
|
|
147538
147285
|
})
|
|
147539
147286
|
], {
|