@camstack/system 1.2.90 → 1.2.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +25 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +25 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-block-store.d.ts +11 -0
- package/dist/builtins/core-blocks/core-blocks.addon.js +12 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +12 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/auth-schema.d.ts +42 -0
- package/dist/builtins/local-auth/local-auth.addon.js +43 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +43 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +16 -5
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +16 -5
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +19 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +19 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +12 -0
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-CYqL8oZq.js → dist-9Gfk4KOk.js} +275 -44
- package/dist/{dist-DMhxx5Kr.mjs → dist-DhrTd8LL.mjs} +275 -44
- package/dist/index.js +38 -1
- package/dist/index.mjs +38 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-9Gfk4KOk.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
let node_module = require("node:module");
|
|
@@ -1144,10 +1144,21 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
|
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
this.getDb().exec(`CREATE TABLE IF NOT EXISTS "${table}" (${colDefs.join(", ")})`);
|
|
1147
|
-
if (schema.indexes)
|
|
1148
|
-
const
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1147
|
+
if (schema.indexes) {
|
|
1148
|
+
const pkName = schema.columns.find((c) => c.primaryKey === true)?.name ?? "id";
|
|
1149
|
+
const nonPkColumns = schema.columns.filter((c) => c.name !== pkName).map((c) => c.name);
|
|
1150
|
+
const kvBlobColumn = nonPkColumns.length === 1 && nonPkColumns[0] === "data" ? "data" : null;
|
|
1151
|
+
const isRealColumn = (field) => field === pkName || nonPkColumns.includes(field);
|
|
1152
|
+
const indexExpr = (field) => {
|
|
1153
|
+
if (isRealColumn(field)) return `"${field}"`;
|
|
1154
|
+
return kvBlobColumn === null ? null : `json_extract("${kvBlobColumn}", '$.${field}')`;
|
|
1155
|
+
};
|
|
1156
|
+
for (const idx of schema.indexes) {
|
|
1157
|
+
const exprs = idx.columns.map((c) => indexExpr(c));
|
|
1158
|
+
if (exprs.some((e) => e === null)) continue;
|
|
1159
|
+
const unique = idx.unique ? "UNIQUE " : "";
|
|
1160
|
+
this.getDb().exec(`CREATE ${unique}INDEX IF NOT EXISTS "${idx.name}" ON "${table}" (${exprs.join(", ")})`);
|
|
1161
|
+
}
|
|
1151
1162
|
}
|
|
1152
1163
|
this.structuredTables.set(table, fingerprint);
|
|
1153
1164
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as decodeVectorBase64, Dt as asJsonObject, Rt as parseJsonUnknown, _t as BaseAddon, f as RUNTIME_DEFAULTS, gt as errMsg, ht as vectorStoreCapability, k as dataStoreProviderCapability, mt as vectorDimFromBase64, w as bareAddonId } from "../../dist-
|
|
1
|
+
import { A as decodeVectorBase64, Dt as asJsonObject, Rt as parseJsonUnknown, _t as BaseAddon, f as RUNTIME_DEFAULTS, gt as errMsg, ht as vectorStoreCapability, k as dataStoreProviderCapability, mt as vectorDimFromBase64, w as bareAddonId } from "../../dist-DhrTd8LL.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { statSync } from "node:fs";
|
|
@@ -1138,10 +1138,21 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
|
|
|
1138
1138
|
}
|
|
1139
1139
|
}
|
|
1140
1140
|
this.getDb().exec(`CREATE TABLE IF NOT EXISTS "${table}" (${colDefs.join(", ")})`);
|
|
1141
|
-
if (schema.indexes)
|
|
1142
|
-
const
|
|
1143
|
-
const
|
|
1144
|
-
|
|
1141
|
+
if (schema.indexes) {
|
|
1142
|
+
const pkName = schema.columns.find((c) => c.primaryKey === true)?.name ?? "id";
|
|
1143
|
+
const nonPkColumns = schema.columns.filter((c) => c.name !== pkName).map((c) => c.name);
|
|
1144
|
+
const kvBlobColumn = nonPkColumns.length === 1 && nonPkColumns[0] === "data" ? "data" : null;
|
|
1145
|
+
const isRealColumn = (field) => field === pkName || nonPkColumns.includes(field);
|
|
1146
|
+
const indexExpr = (field) => {
|
|
1147
|
+
if (isRealColumn(field)) return `"${field}"`;
|
|
1148
|
+
return kvBlobColumn === null ? null : `json_extract("${kvBlobColumn}", '$.${field}')`;
|
|
1149
|
+
};
|
|
1150
|
+
for (const idx of schema.indexes) {
|
|
1151
|
+
const exprs = idx.columns.map((c) => indexExpr(c));
|
|
1152
|
+
if (exprs.some((e) => e === null)) continue;
|
|
1153
|
+
const unique = idx.unique ? "UNIQUE " : "";
|
|
1154
|
+
this.getDb().exec(`CREATE ${unique}INDEX IF NOT EXISTS "${idx.name}" ON "${table}" (${exprs.join(", ")})`);
|
|
1155
|
+
}
|
|
1145
1156
|
}
|
|
1146
1157
|
this.structuredTables.set(table, fingerprint);
|
|
1147
1158
|
}
|
|
@@ -3,13 +3,18 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-9Gfk4KOk.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
10
10
|
let node_path = require("node:path");
|
|
11
11
|
node_path = require_chunk.__toESM(node_path);
|
|
12
12
|
//#region src/builtins/storage-orchestrator/location-store.ts
|
|
13
|
+
/**
|
|
14
|
+
* @durable class=config owner=storage-orchestrator
|
|
15
|
+
* write="an operator creates or edits a location (basePath, minFreePercent, enabled, node pin); plus the boot reconcile — declared defaults seeded on a fresh install, and in-memory-only locations backfilled when the store is late-wired"
|
|
16
|
+
* retention="none — a row goes only when the operator deletes the location, or when the declaration pass prunes one whose declaring addon is gone. Bounded by the storage targets a human configures."
|
|
17
|
+
*/
|
|
13
18
|
var STORAGE_LOCATIONS = "storage_locations";
|
|
14
19
|
/**
|
|
15
20
|
* Reserved key under which the cluster `nodeId` (SP1) is persisted INSIDE
|
|
@@ -799,11 +804,23 @@ var StorageOrchestratorService = class {
|
|
|
799
804
|
* 2. backfill — in-memory locations the DB doesn't have yet (the
|
|
800
805
|
* pre-store seed defaults on a fresh install) are persisted, so the
|
|
801
806
|
* store becomes the durable source of truth from here on.
|
|
807
|
+
*
|
|
808
|
+
* **The re-entry guard latches on a SUCCESSFUL hydrate, not on the attempt** —
|
|
809
|
+
* `loadAll()` is awaited BEFORE `this.locationStore` is assigned, and the
|
|
810
|
+
* order is load-bearing. Latching first meant one transient read error
|
|
811
|
+
* answered `hasStore()` true forever, so the addon's `ensureStoreWired` gate
|
|
812
|
+
* skipped every retry; the service then ran the whole process lifetime on
|
|
813
|
+
* pre-store seed defaults while `upsert` mirrored them onto rows it had never
|
|
814
|
+
* read, silently replacing the operator's persisted `minFreePercent`. Failing
|
|
815
|
+
* back to store-less is the safe direction: an in-memory-only service writes
|
|
816
|
+
* nothing over what is on disk, and the next `capability:provider-registered`
|
|
817
|
+
* event tries again. Held by
|
|
818
|
+
* `__tests__/storage-orchestrator-persistence.spec.ts`.
|
|
802
819
|
*/
|
|
803
820
|
async attachStore(store) {
|
|
804
821
|
if (this.locationStore) return;
|
|
805
|
-
this.locationStore = store;
|
|
806
822
|
const rows = await store.loadAll();
|
|
823
|
+
this.locationStore = store;
|
|
807
824
|
const dbIds = new Set(rows.map((r) => r.id));
|
|
808
825
|
for (const loc of rows) {
|
|
809
826
|
const upgraded = !loc.isSystem && loc.id === `${loc.type}:default` ? {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { Lt as parseJsonObject, _t as BaseAddon, g as StorageMigrationJobSchema, h as StorageLocationTypeSchema, lt as storageCapability, st as settingsStoreCapability, ut as storageMigrationCapability } from "../../dist-
|
|
1
|
+
import { Lt as parseJsonObject, _t as BaseAddon, g as StorageMigrationJobSchema, h as StorageLocationTypeSchema, lt as storageCapability, st as settingsStoreCapability, ut as storageMigrationCapability } from "../../dist-DhrTd8LL.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
5
|
//#region src/builtins/storage-orchestrator/location-store.ts
|
|
6
|
+
/**
|
|
7
|
+
* @durable class=config owner=storage-orchestrator
|
|
8
|
+
* write="an operator creates or edits a location (basePath, minFreePercent, enabled, node pin); plus the boot reconcile — declared defaults seeded on a fresh install, and in-memory-only locations backfilled when the store is late-wired"
|
|
9
|
+
* retention="none — a row goes only when the operator deletes the location, or when the declaration pass prunes one whose declaring addon is gone. Bounded by the storage targets a human configures."
|
|
10
|
+
*/
|
|
6
11
|
var STORAGE_LOCATIONS = "storage_locations";
|
|
7
12
|
/**
|
|
8
13
|
* Reserved key under which the cluster `nodeId` (SP1) is persisted INSIDE
|
|
@@ -792,11 +797,23 @@ var StorageOrchestratorService = class {
|
|
|
792
797
|
* 2. backfill — in-memory locations the DB doesn't have yet (the
|
|
793
798
|
* pre-store seed defaults on a fresh install) are persisted, so the
|
|
794
799
|
* store becomes the durable source of truth from here on.
|
|
800
|
+
*
|
|
801
|
+
* **The re-entry guard latches on a SUCCESSFUL hydrate, not on the attempt** —
|
|
802
|
+
* `loadAll()` is awaited BEFORE `this.locationStore` is assigned, and the
|
|
803
|
+
* order is load-bearing. Latching first meant one transient read error
|
|
804
|
+
* answered `hasStore()` true forever, so the addon's `ensureStoreWired` gate
|
|
805
|
+
* skipped every retry; the service then ran the whole process lifetime on
|
|
806
|
+
* pre-store seed defaults while `upsert` mirrored them onto rows it had never
|
|
807
|
+
* read, silently replacing the operator's persisted `minFreePercent`. Failing
|
|
808
|
+
* back to store-less is the safe direction: an in-memory-only service writes
|
|
809
|
+
* nothing over what is on disk, and the next `capability:provider-registered`
|
|
810
|
+
* event tries again. Held by
|
|
811
|
+
* `__tests__/storage-orchestrator-persistence.spec.ts`.
|
|
795
812
|
*/
|
|
796
813
|
async attachStore(store) {
|
|
797
814
|
if (this.locationStore) return;
|
|
798
|
-
this.locationStore = store;
|
|
799
815
|
const rows = await store.loadAll();
|
|
816
|
+
this.locationStore = store;
|
|
800
817
|
const dbIds = new Set(rows.map((r) => r.id));
|
|
801
818
|
for (const loc of rows) {
|
|
802
819
|
const upgraded = !loc.isSystem && loc.id === `${loc.type}:default` ? {
|
|
@@ -139,6 +139,18 @@ export declare class StorageOrchestratorService {
|
|
|
139
139
|
* 2. backfill — in-memory locations the DB doesn't have yet (the
|
|
140
140
|
* pre-store seed defaults on a fresh install) are persisted, so the
|
|
141
141
|
* store becomes the durable source of truth from here on.
|
|
142
|
+
*
|
|
143
|
+
* **The re-entry guard latches on a SUCCESSFUL hydrate, not on the attempt** —
|
|
144
|
+
* `loadAll()` is awaited BEFORE `this.locationStore` is assigned, and the
|
|
145
|
+
* order is load-bearing. Latching first meant one transient read error
|
|
146
|
+
* answered `hasStore()` true forever, so the addon's `ensureStoreWired` gate
|
|
147
|
+
* skipped every retry; the service then ran the whole process lifetime on
|
|
148
|
+
* pre-store seed defaults while `upsert` mirrored them onto rows it had never
|
|
149
|
+
* read, silently replacing the operator's persisted `minFreePercent`. Failing
|
|
150
|
+
* back to store-less is the safe direction: an in-memory-only service writes
|
|
151
|
+
* nothing over what is on disk, and the next `capability:provider-registered`
|
|
152
|
+
* event tries again. Held by
|
|
153
|
+
* `__tests__/storage-orchestrator-persistence.spec.ts`.
|
|
142
154
|
*/
|
|
143
155
|
attachStore(store: ILocationStore): Promise<void>;
|
|
144
156
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-9Gfk4KOk.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Pt as hydrateSchema, _t as BaseAddon, gt as errMsg } from "../../dist-
|
|
1
|
+
import { Pt as hydrateSchema, _t as BaseAddon, gt as errMsg } from "../../dist-DhrTd8LL.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-9Gfk4KOk.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { J as logDestinationCapability, _t as BaseAddon } from "../../dist-
|
|
1
|
+
import { J as logDestinationCapability, _t as BaseAddon } from "../../dist-DhrTd8LL.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -728,12 +728,6 @@ var WELL_KNOWN_TAB_MAP = Object.fromEntries([
|
|
|
728
728
|
icon: "shapes",
|
|
729
729
|
order: 38
|
|
730
730
|
},
|
|
731
|
-
{
|
|
732
|
-
id: "scenes",
|
|
733
|
-
label: "Scenes",
|
|
734
|
-
icon: "scan-eye",
|
|
735
|
-
order: 36
|
|
736
|
-
},
|
|
737
731
|
{
|
|
738
732
|
id: "analytics",
|
|
739
733
|
label: "Analytics",
|
|
@@ -10105,6 +10099,17 @@ var LlmImageSchema = zod.z.object({
|
|
|
10105
10099
|
bytes: zod.z.instanceof(Uint8Array),
|
|
10106
10100
|
mimeType: zod.z.string()
|
|
10107
10101
|
});
|
|
10102
|
+
/**
|
|
10103
|
+
* Retry policy. `enabled: false` is NOT the same as `maxAttempts: 1` in intent —
|
|
10104
|
+
* the flag is what a consumer table flips, the count is what the operator tunes.
|
|
10105
|
+
* A retry doubles the wall time of a call, so the two gates that run inside a
|
|
10106
|
+
* notification's budget keep it off (see `CONSUMER_RETRY_POLICY` in addon-ai).
|
|
10107
|
+
*/
|
|
10108
|
+
var LlmRetryPolicySchema = zod.z.object({
|
|
10109
|
+
enabled: zod.z.boolean().default(false),
|
|
10110
|
+
/** Total attempts INCLUDING the first. 1 = no retry. */
|
|
10111
|
+
maxAttempts: zod.z.number().int().min(1).max(5).default(1)
|
|
10112
|
+
});
|
|
10108
10113
|
var LlmGenerateBaseInputSchema = zod.z.object({
|
|
10109
10114
|
/** Collection routing (the notification-output posture). */
|
|
10110
10115
|
addonId: zod.z.string().optional(),
|
|
@@ -10119,7 +10124,28 @@ var LlmGenerateBaseInputSchema = zod.z.object({
|
|
|
10119
10124
|
jsonSchema: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
10120
10125
|
/** Per-call override of the profile default. */
|
|
10121
10126
|
maxTokens: zod.z.number().int().positive().optional(),
|
|
10122
|
-
temperature: zod.z.number().optional()
|
|
10127
|
+
temperature: zod.z.number().optional(),
|
|
10128
|
+
/** Per-call override of the profile default (nucleus sampling). */
|
|
10129
|
+
topP: zod.z.number().min(0).max(1).optional(),
|
|
10130
|
+
/** Per-call override of the profile default (top-k sampling). */
|
|
10131
|
+
topK: zod.z.number().int().positive().optional(),
|
|
10132
|
+
/** Per-call override of `profile.timeoutMs` — the total generation bound. */
|
|
10133
|
+
timeoutMs: zod.z.number().int().positive().optional(),
|
|
10134
|
+
/** Per-call override; beats both the consumer table and the profile. */
|
|
10135
|
+
retry: LlmRetryPolicySchema.optional(),
|
|
10136
|
+
/**
|
|
10137
|
+
* Caller-minted id that makes this generation CANCELLABLE.
|
|
10138
|
+
*
|
|
10139
|
+
* Without it a caller that stops waiting cannot stop the work: the gates race
|
|
10140
|
+
* the call against 8 s and free their own slot when the timer wins, while the
|
|
10141
|
+
* generation upstream keeps running to `profile.timeoutMs` — 60 s by default,
|
|
10142
|
+
* on a single-threaded local model. The per-camera bound then counts WAITS,
|
|
10143
|
+
* not generations, and the real load is unbounded.
|
|
10144
|
+
*
|
|
10145
|
+
* `AbortSignal` cannot cross a process boundary; an id can. Pass one here and
|
|
10146
|
+
* `llm.cancel({ requestId })` tears the socket down.
|
|
10147
|
+
*/
|
|
10148
|
+
requestId: zod.z.string().optional()
|
|
10123
10149
|
});
|
|
10124
10150
|
/**
|
|
10125
10151
|
* `llm-runtime` — node-side managed llama.cpp executor (spec §4). Registered
|
|
@@ -10158,8 +10184,49 @@ var ManagedRuntimeConfigSchema = zod.z.object({
|
|
|
10158
10184
|
gpuLayers: zod.z.number().int().default(0),
|
|
10159
10185
|
/** Default: cpus-2, clamped ≥1 (resolved node-side). */
|
|
10160
10186
|
threads: zod.z.number().int().optional(),
|
|
10161
|
-
/** Concurrent slots. */
|
|
10187
|
+
/** Concurrent slots (`--parallel`). */
|
|
10162
10188
|
parallel: zod.z.number().int().default(1),
|
|
10189
|
+
/** Logical batch size (`-b`). Larger = faster prompt ingest, more RAM. */
|
|
10190
|
+
batchSize: zod.z.number().int().positive().optional(),
|
|
10191
|
+
/** Physical batch / micro-batch (`-ub`). */
|
|
10192
|
+
ubatchSize: zod.z.number().int().positive().optional(),
|
|
10193
|
+
/**
|
|
10194
|
+
* `--flash-attn`. Cuts KV-cache memory on the backends that implement it and
|
|
10195
|
+
* is a no-op elsewhere, so it is offered rather than assumed.
|
|
10196
|
+
*/
|
|
10197
|
+
flashAttention: zod.z.boolean().default(false),
|
|
10198
|
+
/**
|
|
10199
|
+
* `--mlock`. Pins the weights in RAM so the OS cannot page them out mid
|
|
10200
|
+
* inference. Costs the full model size in resident memory — which is exactly
|
|
10201
|
+
* what the RAM budget is counting.
|
|
10202
|
+
*/
|
|
10203
|
+
mlock: zod.z.boolean().default(false),
|
|
10204
|
+
/**
|
|
10205
|
+
* `--no-mmap`. Reads the whole GGUF up front instead of mapping it. Slower to
|
|
10206
|
+
* start, but avoids the page-fault stalls a network or spinning-disk model
|
|
10207
|
+
* store produces on every first token.
|
|
10208
|
+
*/
|
|
10209
|
+
noMmap: zod.z.boolean().default(false),
|
|
10210
|
+
/** `--cache-type-k` / `--cache-type-v` — quantising the KV cache is the
|
|
10211
|
+
* cheapest way to fit a longer context in the same RAM. */
|
|
10212
|
+
cacheTypeK: zod.z.enum([
|
|
10213
|
+
"f32",
|
|
10214
|
+
"f16",
|
|
10215
|
+
"q8_0",
|
|
10216
|
+
"q5_1",
|
|
10217
|
+
"q5_0",
|
|
10218
|
+
"q4_1",
|
|
10219
|
+
"q4_0"
|
|
10220
|
+
]).optional(),
|
|
10221
|
+
cacheTypeV: zod.z.enum([
|
|
10222
|
+
"f32",
|
|
10223
|
+
"f16",
|
|
10224
|
+
"q8_0",
|
|
10225
|
+
"q5_1",
|
|
10226
|
+
"q5_0",
|
|
10227
|
+
"q4_1",
|
|
10228
|
+
"q4_0"
|
|
10229
|
+
]).optional(),
|
|
10163
10230
|
/** Else lazy: first generate boots it. */
|
|
10164
10231
|
autoStart: zod.z.boolean().default(false),
|
|
10165
10232
|
/** 0 = never; frees RAM after quiet periods. */
|
|
@@ -10262,10 +10329,44 @@ var LlmProfileSchema = zod.z.object({
|
|
|
10262
10329
|
baseUrl: zod.z.string().optional(),
|
|
10263
10330
|
/** ConfigUISchema type:'password' — never round-trips (spec §5). */
|
|
10264
10331
|
apiKey: zod.z.string().optional(),
|
|
10332
|
+
/** Vision on/off. A vision call against a `false` profile is REFUSED, never
|
|
10333
|
+
* degraded to text — that shipped once and produced a confident answer to a
|
|
10334
|
+
* question about a picture nobody sent. */
|
|
10265
10335
|
supportsVision: zod.z.boolean(),
|
|
10266
10336
|
temperature: zod.z.number().min(0).max(2).optional(),
|
|
10337
|
+
/** Nucleus sampling. Every wire we speak has it. */
|
|
10338
|
+
topP: zod.z.number().min(0).max(1).optional(),
|
|
10339
|
+
/** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
|
|
10340
|
+
* wire does, and the client drops it there (measured: the request body gets
|
|
10341
|
+
* `top_p` and no `top_k`). The profile editor hides the field wherever it
|
|
10342
|
+
* would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
|
|
10343
|
+
topK: zod.z.number().int().positive().optional(),
|
|
10267
10344
|
maxTokens: zod.z.number().int().positive().optional(),
|
|
10345
|
+
/** Prompt context window. Advisory for cloud kinds (they enforce their own);
|
|
10346
|
+
* for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
|
|
10347
|
+
* the model with, so it is the one field that changes a PROCESS. */
|
|
10348
|
+
contextLength: zod.z.number().int().positive().optional(),
|
|
10349
|
+
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
10350
|
+
* two system prompts fighting is worse than either alone). */
|
|
10351
|
+
systemPrompt: zod.z.string().optional(),
|
|
10352
|
+
/** Total generation bound — the only one a unary call has. */
|
|
10268
10353
|
timeoutMs: zod.z.number().int().positive().default(6e4),
|
|
10354
|
+
/** Wait for response headers only. */
|
|
10355
|
+
connectTimeoutMs: zod.z.number().int().positive().default(1e4),
|
|
10356
|
+
/** Accepted, but no output yet — a cold GPU load lives here. */
|
|
10357
|
+
firstTokenTimeoutMs: zod.z.number().int().positive().default(12e4),
|
|
10358
|
+
/** Output started then stopped. */
|
|
10359
|
+
idleTimeoutMs: zod.z.number().int().positive().default(6e4),
|
|
10360
|
+
/** Profile-level default. The per-consumer table and a per-call override
|
|
10361
|
+
* both beat it — see `resolveRetryPolicy`. */
|
|
10362
|
+
retry: LlmRetryPolicySchema.default({
|
|
10363
|
+
enabled: false,
|
|
10364
|
+
maxAttempts: 1
|
|
10365
|
+
}),
|
|
10366
|
+
/** Whether this profile may use tools. The tool-call plumbing rides the
|
|
10367
|
+
* library; the REGISTRY of callable tools is ours and is empty in v1, so a
|
|
10368
|
+
* `true` here buys the wiring, not behaviour, until tools are registered. */
|
|
10369
|
+
toolsEnabled: zod.z.boolean().default(false),
|
|
10269
10370
|
extraHeaders: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
10270
10371
|
/** kind === 'managed-local' only (spec §4). */
|
|
10271
10372
|
runtime: ManagedRuntimeConfigSchema.optional()
|
|
@@ -10338,6 +10439,17 @@ var llmCapability = {
|
|
|
10338
10439
|
methods: {
|
|
10339
10440
|
generate: method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }),
|
|
10340
10441
|
generateVision: method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }),
|
|
10442
|
+
/**
|
|
10443
|
+
* Stop a generation started with a `requestId`.
|
|
10444
|
+
*
|
|
10445
|
+
* Idempotent and always successful: cancelling an id that already finished,
|
|
10446
|
+
* never existed, or was cancelled a moment ago is a no-op. A caller that has
|
|
10447
|
+
* given up must never have to handle an error from giving up.
|
|
10448
|
+
*/
|
|
10449
|
+
cancel: method(zod.z.object({
|
|
10450
|
+
addonId: zod.z.string().optional(),
|
|
10451
|
+
requestId: zod.z.string()
|
|
10452
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
10341
10453
|
listProfileKinds: method(zod.z.object({}), zod.z.array(LlmProfileKindDescriptorSchema)),
|
|
10342
10454
|
listProfiles: method(zod.z.object({}), zod.z.array(LlmProfileSchema)),
|
|
10343
10455
|
upsertProfile: method(zod.z.object({ profile: LlmProfileSchema }), LlmProfileSchema, {
|
|
@@ -12312,28 +12424,36 @@ var NcOccupancyConditionSchema = zod.z.object({
|
|
|
12312
12424
|
/**
|
|
12313
12425
|
* Audio condition (IMMEDIATE trigger) — a rule on SOUND, not on a picture.
|
|
12314
12426
|
*
|
|
12315
|
-
*
|
|
12316
|
-
*
|
|
12317
|
-
*
|
|
12318
|
-
*
|
|
12319
|
-
*
|
|
12320
|
-
*
|
|
12321
|
-
*
|
|
12322
|
-
*
|
|
12323
|
-
*
|
|
12324
|
-
*
|
|
12325
|
-
*
|
|
12326
|
-
*
|
|
12327
|
-
*
|
|
12328
|
-
*
|
|
12329
|
-
*
|
|
12330
|
-
*
|
|
12331
|
-
*
|
|
12332
|
-
*
|
|
12333
|
-
*
|
|
12334
|
-
*
|
|
12335
|
-
*
|
|
12336
|
-
* `
|
|
12427
|
+
* **TWO EXCLUSIVE MODES** (operator decision 2026-08-14, D157). Which one a
|
|
12428
|
+
* rule is in is not a stored field — it is WHICH FILTER the rule carries, so
|
|
12429
|
+
* there is no second switch that can disagree with the first and every rule
|
|
12430
|
+
* authored before the decision migrates for free (`audioModeOf`):
|
|
12431
|
+
*
|
|
12432
|
+
* - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
|
|
12433
|
+
* classifier labels with one of them. No window, no percentage:
|
|
12434
|
+
* `hitPercent` and `samplingSeconds` are ignored, and the rule's own
|
|
12435
|
+
* `throttle` cooldown is the only brake. The per-label confidence floor is
|
|
12436
|
+
* the analyzer's (`classificationMinScore`, per device) — a label only
|
|
12437
|
+
* reaches this condition if the classifier was already confident enough.
|
|
12438
|
+
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
12439
|
+
* the condition: at least `hitPercent`% of the samples over
|
|
12440
|
+
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
12441
|
+
* {@link NC_AUDIO_DBFS_FLOOR}: negative-going, `0` = full scale). The window
|
|
12442
|
+
* must be FULL before it can match — a window open for two of its ten
|
|
12443
|
+
* seconds is 100% of nothing.
|
|
12444
|
+
*
|
|
12445
|
+
* **Why label mode has no window.** It had one, and it never fired: the
|
|
12446
|
+
* analyzer emits ~1 audio frame per second but YAMNet only LABELS one to three
|
|
12447
|
+
* of them per episode, even through continuous crying. The measured maximum
|
|
12448
|
+
* `hitPercent` over the whole live history was 40 — under the shipped default
|
|
12449
|
+
* of 60, so a label rule could not fire at all, ever. A percentage of frames is
|
|
12450
|
+
* the wrong question to ask of a sparse classifier.
|
|
12451
|
+
*
|
|
12452
|
+
* **Fail-closed when NEITHER is given** — every sample would be a trivial hit
|
|
12453
|
+
* and the rule would fire on silence. The schema cannot express "exactly one
|
|
12454
|
+
* of" without becoming a ZodEffects the cap path would have to special-case, so
|
|
12455
|
+
* the exclusivity is enforced where every editor writes (`patchAudio`) and a
|
|
12456
|
+
* legacy rule carrying both resolves to LABEL (the mode that fires).
|
|
12337
12457
|
*
|
|
12338
12458
|
* Labels are the audio macro classes (`AUDIO_MACRO_LABELS` / the NC taxonomy's
|
|
12339
12459
|
* `audio-*` ids). Both spellings are accepted — the matcher normalizes the
|
|
@@ -12341,13 +12461,13 @@ var NcOccupancyConditionSchema = zod.z.object({
|
|
|
12341
12461
|
* an operator who typed `dog` mean the same thing.
|
|
12342
12462
|
*/
|
|
12343
12463
|
var NcAudioConditionSchema = zod.z.object({
|
|
12344
|
-
/**
|
|
12464
|
+
/** LABEL MODE: audio macro labels. Present ⇒ fires on the first labelled frame. */
|
|
12345
12465
|
labels: zod.z.array(zod.z.string().min(1)).min(1).optional(),
|
|
12346
|
-
/**
|
|
12466
|
+
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
12347
12467
|
dbThreshold: zod.z.number().min(-96).max(0).optional(),
|
|
12348
|
-
/**
|
|
12468
|
+
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
12349
12469
|
hitPercent: zod.z.number().int().min(1).max(100).default(60),
|
|
12350
|
-
/**
|
|
12470
|
+
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
12351
12471
|
samplingSeconds: zod.z.number().int().min(1).max(300).default(10)
|
|
12352
12472
|
});
|
|
12353
12473
|
/**
|
|
@@ -26642,10 +26762,22 @@ var recordingExportCapability = {
|
|
|
26642
26762
|
* thing except the comparator: `similarity` (CLIP cosine at the same ROI coords
|
|
26643
26763
|
* vs condition-tagged references) and `llm` (vision-LLM judgment over the crop).
|
|
26644
26764
|
*
|
|
26645
|
-
*
|
|
26646
|
-
*
|
|
26647
|
-
*
|
|
26648
|
-
*
|
|
26765
|
+
* **No `deviceConfig`, deliberately.** This shipped as the D14 widget archetype,
|
|
26766
|
+
* which put a "Scenes" tab on one camera's detail page. That is the wrong shape
|
|
26767
|
+
* for the thing: a scene is a standing question about the property ("is the bin
|
|
26768
|
+
* still out"), and the operator's question is "which of my scenes have tripped",
|
|
26769
|
+
* across every camera at once — not "what does camera 617 think". Buried one
|
|
26770
|
+
* camera deep it also could not be found. The surface is now a top-level admin
|
|
26771
|
+
* page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
|
|
26772
|
+
* picks the camera inside the create flow, the same shape Events and Faces have.
|
|
26773
|
+
*
|
|
26774
|
+
* The consequence to keep in mind: `host/scene-monitor-editor` is gone from
|
|
26775
|
+
* `HOST_WIDGETS` too. `scripts/check-host-widget-resolves.ts` asserts BOTH
|
|
26776
|
+
* directions, so a registration nobody declares fails exactly as loudly as a
|
|
26777
|
+
* declaration nobody registers. The editor is imported directly by the page.
|
|
26778
|
+
*
|
|
26779
|
+
* `status.kind:'push'` — the engine pushes on every hysteresis flip /
|
|
26780
|
+
* availability change; consumers never poll.
|
|
26649
26781
|
*/
|
|
26650
26782
|
/** Extensible condition tag. Seeded 'day' | 'ir' (the two variants the operator
|
|
26651
26783
|
* captures) plus 'night' | 'dawn' | 'dusk' from the resolver's sun-times band.
|
|
@@ -26794,12 +26926,6 @@ var sceneMonitorCapability = {
|
|
|
26794
26926
|
kind: "wrapper",
|
|
26795
26927
|
defaultActive: true,
|
|
26796
26928
|
deviceTypes: [DeviceType.Camera],
|
|
26797
|
-
deviceConfig: { ui: {
|
|
26798
|
-
kind: "widget",
|
|
26799
|
-
widgetId: "host/scene-monitor-editor",
|
|
26800
|
-
tab: "scenes",
|
|
26801
|
-
label: "Scenes"
|
|
26802
|
-
} },
|
|
26803
26929
|
methods: {
|
|
26804
26930
|
listScenes: method(zod.z.object({ deviceId: zod.z.number() }), SceneMonitorStatusSchema),
|
|
26805
26931
|
createScene: method(zod.z.object({
|
|
@@ -27658,6 +27784,61 @@ var NetworkAddressSchema = zod.z.object({
|
|
|
27658
27784
|
family: zod.z.string(),
|
|
27659
27785
|
internal: zod.z.boolean()
|
|
27660
27786
|
});
|
|
27787
|
+
/**
|
|
27788
|
+
* Provenance of the site coordinates, and the whole reason this is not just two
|
|
27789
|
+
* numbers.
|
|
27790
|
+
*
|
|
27791
|
+
* - `operator-set` — a human typed it, or accepted a detection. Authoritative;
|
|
27792
|
+
* nothing overwrites it.
|
|
27793
|
+
* - `derived-from-ip` — the hub geolocated its own public IP once, because a
|
|
27794
|
+
* default that is right to a few kilometres beats the coarse UTC clock split
|
|
27795
|
+
* the sun-times consumers otherwise fall back to.
|
|
27796
|
+
*
|
|
27797
|
+
* The UI shows which one it is. An operator who cannot tell a guess from their
|
|
27798
|
+
* own input will eventually trust the guess.
|
|
27799
|
+
*/
|
|
27800
|
+
var SiteLocationSourceSchema = zod.z.enum(["operator-set", "derived-from-ip"]);
|
|
27801
|
+
/**
|
|
27802
|
+
* Where the installation physically is — a fact of the SITE, not of any addon.
|
|
27803
|
+
*
|
|
27804
|
+
* It used to live in `pipeline-analytics`' global settings, which made a
|
|
27805
|
+
* property of the building a property of one analytics addon. Anything that
|
|
27806
|
+
* needs sun-times (scene condition variants today; anything solar tomorrow)
|
|
27807
|
+
* reads it from here.
|
|
27808
|
+
*/
|
|
27809
|
+
var SiteLocationSchema = zod.z.object({
|
|
27810
|
+
/** WGS84 decimal degrees. */
|
|
27811
|
+
latitude: zod.z.number().min(-90).max(90),
|
|
27812
|
+
longitude: zod.z.number().min(-180).max(180),
|
|
27813
|
+
source: SiteLocationSourceSchema,
|
|
27814
|
+
/** Epoch ms the value was last written. */
|
|
27815
|
+
updatedAt: zod.z.number(),
|
|
27816
|
+
/**
|
|
27817
|
+
* Human-readable place the geo-IP service reported ("Napoli, IT"). Display
|
|
27818
|
+
* only — never parsed, never matched on. Absent for an operator-typed value.
|
|
27819
|
+
*/
|
|
27820
|
+
label: zod.z.string().optional()
|
|
27821
|
+
});
|
|
27822
|
+
/**
|
|
27823
|
+
* The read shape: the location plus the honest state of the one-shot derivation.
|
|
27824
|
+
*
|
|
27825
|
+
* `derivationAttemptedAt` is what makes the "one call, ever" contract
|
|
27826
|
+
* inspectable. When it is set and `location` is null, the geo-IP lookup ran and
|
|
27827
|
+
* failed; the hub will NOT try again on its own — the fallback is declared
|
|
27828
|
+
* (consumers degrade to their own last resort) and the operator either types the
|
|
27829
|
+
* coordinates or presses detect.
|
|
27830
|
+
*/
|
|
27831
|
+
var SiteLocationStatusSchema = zod.z.object({
|
|
27832
|
+
location: SiteLocationSchema.nullable(),
|
|
27833
|
+
derivationAttemptedAt: zod.z.number().nullable(),
|
|
27834
|
+
/** Why the last derivation failed, for the UI to show instead of a shrug. */
|
|
27835
|
+
derivationError: zod.z.string().nullable()
|
|
27836
|
+
});
|
|
27837
|
+
/** `null` clears the location and re-arms nothing — the derivation stays spent. */
|
|
27838
|
+
var SetSiteLocationInputSchema = zod.z.object({
|
|
27839
|
+
latitude: zod.z.number().min(-90).max(90),
|
|
27840
|
+
longitude: zod.z.number().min(-180).max(180)
|
|
27841
|
+
}).nullable();
|
|
27661
27842
|
var systemCapability = {
|
|
27662
27843
|
name: "system",
|
|
27663
27844
|
scope: "system",
|
|
@@ -27675,6 +27856,32 @@ var systemCapability = {
|
|
|
27675
27856
|
forceRetentionCleanup: method(zod.z.void(), zod.z.void(), {
|
|
27676
27857
|
kind: "mutation",
|
|
27677
27858
|
auth: "admin"
|
|
27859
|
+
}),
|
|
27860
|
+
/**
|
|
27861
|
+
* The site coordinates, deriving a default from the hub's public IP on the
|
|
27862
|
+
* FIRST read that finds nothing stored.
|
|
27863
|
+
*
|
|
27864
|
+
* The derivation is one-shot and bounded: one outbound request, a few
|
|
27865
|
+
* seconds, its outcome persisted either way. A hub with no internet pays it
|
|
27866
|
+
* once and never again, and neither boot nor any consumer is blocked on it —
|
|
27867
|
+
* the caller gets `location: null` and degrades exactly as it did before this
|
|
27868
|
+
* method existed.
|
|
27869
|
+
*/
|
|
27870
|
+
getSiteLocation: method(zod.z.void(), SiteLocationStatusSchema),
|
|
27871
|
+
/** Operator input. Always lands as `source: 'operator-set'`. */
|
|
27872
|
+
setSiteLocation: method(SetSiteLocationInputSchema, SiteLocationStatusSchema, {
|
|
27873
|
+
kind: "mutation",
|
|
27874
|
+
auth: "admin"
|
|
27875
|
+
}),
|
|
27876
|
+
/**
|
|
27877
|
+
* Re-run the geo-IP derivation now. The ONLY way a spent or failed
|
|
27878
|
+
* derivation is retried — there is no timer, and no read path retries.
|
|
27879
|
+
* Overwrites an existing `derived-from-ip` value; refuses to clobber an
|
|
27880
|
+
* `operator-set` one.
|
|
27881
|
+
*/
|
|
27882
|
+
detectSiteLocation: method(zod.z.void(), SiteLocationStatusSchema, {
|
|
27883
|
+
kind: "mutation",
|
|
27884
|
+
auth: "admin"
|
|
27678
27885
|
})
|
|
27679
27886
|
},
|
|
27680
27887
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
@@ -31410,6 +31617,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
31410
31617
|
addonId: null,
|
|
31411
31618
|
access: "create"
|
|
31412
31619
|
},
|
|
31620
|
+
"llm.cancel": {
|
|
31621
|
+
capName: "llm",
|
|
31622
|
+
capScope: "system",
|
|
31623
|
+
addonId: null,
|
|
31624
|
+
access: "create"
|
|
31625
|
+
},
|
|
31413
31626
|
"llm.deleteModel": {
|
|
31414
31627
|
capName: "llm",
|
|
31415
31628
|
capScope: "system",
|
|
@@ -34344,6 +34557,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34344
34557
|
addonId: null,
|
|
34345
34558
|
access: "create"
|
|
34346
34559
|
},
|
|
34560
|
+
"system.detectSiteLocation": {
|
|
34561
|
+
capName: "system",
|
|
34562
|
+
capScope: "system",
|
|
34563
|
+
addonId: null,
|
|
34564
|
+
access: "create"
|
|
34565
|
+
},
|
|
34347
34566
|
"system.featureFlags": {
|
|
34348
34567
|
capName: "system",
|
|
34349
34568
|
capScope: "system",
|
|
@@ -34362,6 +34581,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34362
34581
|
addonId: null,
|
|
34363
34582
|
access: "view"
|
|
34364
34583
|
},
|
|
34584
|
+
"system.getSiteLocation": {
|
|
34585
|
+
capName: "system",
|
|
34586
|
+
capScope: "system",
|
|
34587
|
+
addonId: null,
|
|
34588
|
+
access: "view"
|
|
34589
|
+
},
|
|
34365
34590
|
"system.health": {
|
|
34366
34591
|
capName: "system",
|
|
34367
34592
|
capScope: "system",
|
|
@@ -34386,6 +34611,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
34386
34611
|
addonId: null,
|
|
34387
34612
|
access: "create"
|
|
34388
34613
|
},
|
|
34614
|
+
"system.setSiteLocation": {
|
|
34615
|
+
capName: "system",
|
|
34616
|
+
capScope: "system",
|
|
34617
|
+
addonId: null,
|
|
34618
|
+
access: "create"
|
|
34619
|
+
},
|
|
34389
34620
|
"terminalSession.adoptLegacyMonitor": {
|
|
34390
34621
|
capName: "terminal-session",
|
|
34391
34622
|
capScope: "system",
|