@camstack/core 0.1.1 → 0.1.2
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/local-backup/index.d.mts +42 -0
- package/dist/builtins/local-backup/index.d.ts +42 -0
- package/dist/builtins/local-backup/index.js +188 -0
- package/dist/builtins/local-backup/index.js.map +1 -0
- package/dist/builtins/local-backup/index.mjs +11 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.mts +2 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +2 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +210 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js.map +1 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +10 -0
- package/dist/builtins/sqlite-storage/index.d.mts +4 -0
- package/dist/builtins/sqlite-storage/index.d.ts +4 -0
- package/dist/builtins/sqlite-storage/index.js +1025 -0
- package/dist/builtins/sqlite-storage/index.js.map +1 -0
- package/dist/builtins/sqlite-storage/index.mjs +31 -0
- package/dist/builtins/sqlite-storage/index.mjs.map +1 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.mts +2 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +2 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +317 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js.map +1 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +10 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs.map +1 -0
- package/dist/builtins/winston-logging/index.d.mts +30 -0
- package/dist/builtins/winston-logging/index.d.ts +30 -0
- package/dist/builtins/winston-logging/index.js +185 -0
- package/dist/builtins/winston-logging/index.js.map +1 -0
- package/dist/builtins/winston-logging/index.mjs +11 -0
- package/dist/builtins/winston-logging/index.mjs.map +1 -0
- package/dist/chunk-LQFPAEQF.mjs +147 -0
- package/dist/chunk-LQFPAEQF.mjs.map +1 -0
- package/dist/{chunk-LZOMFHX3.mjs → chunk-QEMJH3KY.mjs} +11 -1
- package/dist/chunk-QEMJH3KY.mjs.map +1 -0
- package/dist/chunk-R3DIIBBX.mjs +532 -0
- package/dist/chunk-R3DIIBBX.mjs.map +1 -0
- package/dist/chunk-SO4LROOT.mjs +150 -0
- package/dist/chunk-SO4LROOT.mjs.map +1 -0
- package/dist/chunk-SPA4JBKN.mjs +175 -0
- package/dist/chunk-SPA4JBKN.mjs.map +1 -0
- package/dist/chunk-YXNXYYHL.mjs +282 -0
- package/dist/chunk-YXNXYYHL.mjs.map +1 -0
- package/dist/dist-N7SR63RN.mjs +3515 -0
- package/dist/dist-N7SR63RN.mjs.map +1 -0
- package/dist/filesystem-storage.addon-C42r589X.d.mts +57 -0
- package/dist/filesystem-storage.addon-C42r589X.d.ts +57 -0
- package/dist/index.d.mts +281 -849
- package/dist/index.d.ts +281 -849
- package/dist/index.js +8351 -1942
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4086 -2164
- package/dist/index.mjs.map +1 -1
- package/dist/onnxruntime_binding-6Q6HXASN.node +0 -0
- package/dist/onnxruntime_binding-EKZT2NRK.node +0 -0
- package/dist/onnxruntime_binding-P6S7V3CI.node +0 -0
- package/dist/onnxruntime_binding-PJNNIIUO.node +0 -0
- package/dist/onnxruntime_binding-UN6SPTQK.node +0 -0
- package/dist/sql-schema-CKz78rId.d.mts +97 -0
- package/dist/sql-schema-CKz78rId.d.ts +97 -0
- package/dist/sqlite-settings.addon-DigoKwpZ.d.mts +70 -0
- package/dist/sqlite-settings.addon-DigoKwpZ.d.ts +70 -0
- package/dist/{storage-location-manager-F4YZMHGM.mjs → storage-location-manager-UQRGHTCA.mjs} +2 -2
- package/dist/storage-location-manager-UQRGHTCA.mjs.map +1 -0
- package/dist/{wrapper-NTBY5HOA.mjs → wrapper-Y55ADNM5.mjs} +2 -2
- package/package.json +64 -12
- /package/dist/{chunk-LZOMFHX3.mjs.map → builtins/local-backup/index.mjs.map} +0 -0
- /package/dist/{storage-location-manager-F4YZMHGM.mjs.map → builtins/sqlite-storage/filesystem-storage.addon.mjs.map} +0 -0
- /package/dist/{wrapper-NTBY5HOA.mjs.map → wrapper-Y55ADNM5.mjs.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,71 @@
|
|
|
1
|
-
import { ModelDownloadOptions, ModelDownloadResult,
|
|
2
|
-
export { EventFilter, EventSource, IScopedLogger, SystemEvent } from '@camstack/types';
|
|
1
|
+
import { IScopedLogger, ModelDownloadOptions, ModelDownloadResult, IAddonModelManager, ModelCatalogEntry, ModelFormat, IPythonEnvironment, PythonProbeResult, PythonEnvReady, PipelineConfig, ValidationResult, FrameInput, PipelineResult, AudioChunkInput, PipelineNode, ElementState as ElementState$1, LoggerFactory, ProcessConfig, ManagedProcessStatus, INetworkQualityTracker, ClientNetworkStats, DeviceNetworkStats, ReplResult, AgentInfo, AgentEntry, AgentStatus, AgentTask, TaskDispatchOptions, AgentTaskResult, LogEntry, LogFilter, AgentRegistrationInfo, AgentToHubMessage, HubToAgentMessage, AgentRuntimeStatus, ITaskHandler, TaskContext, IEventBus, FeatureManifest, FeatureFlag, SystemEvent, EventFilter, IStorageProvider as IStorageProvider$1, ISettingsBackend, TokenScope, ScopedToken, TokenPayload, UserRole, UserRecord, INotificationOutput, Notification, Toast, IAddonRouteProvider, IAddonHttpRoute, PlatformCapabilities, HardwareInfo, PlatformScore, ModelRequirement, ResolvedInferenceConfig, ProviderListItem } from '@camstack/types';
|
|
2
|
+
export { AgentEntry, AgentInfo, AgentResources, AgentStatus, AgentTask, AgentTaskResult, BackupManifest, ClientNetworkStats, DeviceNetworkStats, EventFilter, EventSource, FeatureFlag, FeatureManifest, INetworkQualityTracker, IScopedLogger, LogEntry, LogFilter, LogLevel, ManagedProcessStatus, ProcessConfig, ProcessStats, ProviderListItem, ReplResult, StreamNetworkStats, SystemEvent, TaskDispatchOptions, TokenPayload, UserRecord, UserRole, ValidationIssue, ValidationResult } from '@camstack/types';
|
|
3
3
|
import { ChildProcess } from 'node:child_process';
|
|
4
|
-
import {
|
|
4
|
+
import { AddonLoader, AddonEngineManager, CapabilityRegistry } from '@camstack/kernel';
|
|
5
|
+
export { A as AddonTableSchema, C as CORE_TABLE_DDL, F as FileSystemStorage, S as SettingsStore, a as SqliteStorageAddon, b as SqliteStorageProvider, c as addonTableToDdl } from './sql-schema-CKz78rId.js';
|
|
6
|
+
export { WinstonDestination, WinstonLoggingAddon } from './builtins/winston-logging/index.js';
|
|
7
|
+
export { BackupConfig, LocalBackupAddon, LocalBackupService } from './builtins/local-backup/index.js';
|
|
8
|
+
|
|
9
|
+
interface PlatformInfo {
|
|
10
|
+
readonly platform: NodeJS.Platform;
|
|
11
|
+
readonly arch: NodeJS.Architecture;
|
|
12
|
+
}
|
|
13
|
+
declare function getPlatformInfo(): PlatformInfo;
|
|
14
|
+
declare function buildBinaryPath(dataDir: string, name: string, platform?: string): string;
|
|
15
|
+
/** Check if a binary exists in PATH */
|
|
16
|
+
declare function findInPath(name: string): string | null;
|
|
17
|
+
interface DownloadOptions {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly url: string;
|
|
20
|
+
readonly targetDir: string;
|
|
21
|
+
readonly targetName: string;
|
|
22
|
+
readonly logger: IScopedLogger;
|
|
23
|
+
readonly isArchive?: boolean;
|
|
24
|
+
readonly archiveFormat?: 'zip' | 'tar.gz' | 'tar.xz';
|
|
25
|
+
/** Relative path within archive to the binary (e.g., 'ffmpeg-6.1/bin/ffmpeg') */
|
|
26
|
+
readonly archiveInnerPath?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Download a binary to the target directory.
|
|
30
|
+
* Handles archives (zip, tar.gz, tar.xz) and raw binaries.
|
|
31
|
+
*/
|
|
32
|
+
declare function downloadBinary(opts: DownloadOptions): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Ensure a binary is available. Checks:
|
|
35
|
+
* 1. Target path (already downloaded)
|
|
36
|
+
* 2. System PATH
|
|
37
|
+
* 3. Download from URL
|
|
38
|
+
*/
|
|
39
|
+
declare function ensureBinary(opts: {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly targetDir: string;
|
|
42
|
+
readonly downloadUrl: string;
|
|
43
|
+
readonly logger: IScopedLogger;
|
|
44
|
+
readonly isArchive?: boolean;
|
|
45
|
+
readonly archiveFormat?: 'zip' | 'tar.gz' | 'tar.xz';
|
|
46
|
+
readonly archiveInnerPath?: string;
|
|
47
|
+
}): Promise<string>;
|
|
48
|
+
|
|
49
|
+
declare function getFfmpegDownloadUrl(platform: string, arch: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Ensure ffmpeg binary is available.
|
|
52
|
+
* Checks: deps dir → system PATH → download.
|
|
53
|
+
*/
|
|
54
|
+
declare function ensureFfmpeg(dataDir: string, logger: IScopedLogger): Promise<string>;
|
|
55
|
+
|
|
56
|
+
declare const PYTHON_VERSION = "3.12.12";
|
|
57
|
+
declare function getPythonDownloadUrl(platform: string, arch: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* Ensure a portable Python is available.
|
|
60
|
+
* Checks: embedded python → system PATH → download portable.
|
|
61
|
+
*
|
|
62
|
+
* Returns the path to the python3 binary.
|
|
63
|
+
*/
|
|
64
|
+
declare function ensurePython(dataDir: string, logger: IScopedLogger): Promise<string | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Install Python packages into the portable Python environment.
|
|
67
|
+
*/
|
|
68
|
+
declare function installPythonPackages(pythonPath: string, packages: readonly string[], logger: IScopedLogger): Promise<void>;
|
|
5
69
|
|
|
6
70
|
type EventCallback<T = unknown> = (data: T) => void;
|
|
7
71
|
declare class EventBus {
|
|
@@ -13,8 +77,69 @@ declare class EventBus {
|
|
|
13
77
|
listenerCount(event: string): number;
|
|
14
78
|
}
|
|
15
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Download a single file from a URL to a destination path.
|
|
82
|
+
* Uses native fetch() (Node 22+) which handles redirects natively.
|
|
83
|
+
* Streams to disk with optional progress callback.
|
|
84
|
+
* Returns the destination path. Skips download if file already exists.
|
|
85
|
+
*/
|
|
86
|
+
declare function downloadFile(url: string, destPath: string, onProgress?: (downloaded: number, total: number) => void): Promise<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Fetch JSON from a URL using native fetch().
|
|
89
|
+
*/
|
|
90
|
+
declare function fetchJson(url: string): Promise<unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* Download a model with fallback URLs and optional SHA256 verification.
|
|
93
|
+
* Legacy API preserved for backward compatibility -- delegates to downloadFile().
|
|
94
|
+
*/
|
|
16
95
|
declare function downloadModel(options: ModelDownloadOptions): Promise<ModelDownloadResult>;
|
|
17
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Unified model download service.
|
|
99
|
+
*
|
|
100
|
+
* Handles downloading model files and extra files (labels, dicts) from a
|
|
101
|
+
* catalog of ModelCatalogEntry items. Supports single-file models and
|
|
102
|
+
* directory bundles (e.g., .mlpackage for CoreML).
|
|
103
|
+
*
|
|
104
|
+
* Addons use this via `context.models.ensure(modelId, format)`.
|
|
105
|
+
*/
|
|
106
|
+
declare class ModelDownloadService implements IAddonModelManager {
|
|
107
|
+
private readonly modelsDir;
|
|
108
|
+
private readonly onProgress?;
|
|
109
|
+
private readonly catalog;
|
|
110
|
+
constructor(modelsDir: string, catalog: readonly ModelCatalogEntry[], onProgress?: ((modelId: string, downloaded: number, total: number) => void) | undefined);
|
|
111
|
+
/**
|
|
112
|
+
* Ensure a model (and its extra files) is downloaded.
|
|
113
|
+
* Returns the local filesystem path to the model file/directory.
|
|
114
|
+
*/
|
|
115
|
+
ensure(modelId: string, format?: ModelFormat): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Ensure extra files for a model are downloaded.
|
|
118
|
+
* Returns the local paths of all extra files.
|
|
119
|
+
*/
|
|
120
|
+
ensureExtraFiles(modelId: string): Promise<readonly string[]>;
|
|
121
|
+
/** Absolute path to the shared models directory. */
|
|
122
|
+
getModelsDir(): string;
|
|
123
|
+
/** Check if a model file is already present on disk. */
|
|
124
|
+
isDownloaded(modelId: string, format?: ModelFormat): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Legacy API: download a model by ID (delegates to ensure with default format).
|
|
127
|
+
* Required by IAddonModelManager interface.
|
|
128
|
+
*/
|
|
129
|
+
downloadModel(id: string): Promise<string>;
|
|
130
|
+
/** Get the catalog entry for a model by ID. */
|
|
131
|
+
getEntry(modelId: string): ModelCatalogEntry | undefined;
|
|
132
|
+
private pickDefaultFormat;
|
|
133
|
+
private modelFilePath;
|
|
134
|
+
/**
|
|
135
|
+
* Download a directory bundle (e.g., .mlpackage) from HuggingFace.
|
|
136
|
+
* ATOMIC: downloads to temp dir, renames only on complete success.
|
|
137
|
+
*/
|
|
138
|
+
private downloadDirectory;
|
|
139
|
+
/** Recursively list all files in a HuggingFace directory via API. */
|
|
140
|
+
private listHfFiles;
|
|
141
|
+
}
|
|
142
|
+
|
|
18
143
|
declare class PythonEnvManager implements IPythonEnvironment {
|
|
19
144
|
private readonly dataDir;
|
|
20
145
|
private venvPath;
|
|
@@ -27,113 +152,6 @@ declare class PythonEnvManager implements IPythonEnvironment {
|
|
|
27
152
|
spawn(script: string, args: readonly string[]): ChildProcess;
|
|
28
153
|
}
|
|
29
154
|
|
|
30
|
-
interface AddonInstallerConfig {
|
|
31
|
-
/** Directory where addons are installed (e.g., ~/.camstack/addons or {dataDir}/addons) */
|
|
32
|
-
readonly addonsDir: string;
|
|
33
|
-
/** Builtin packages to auto-install on first boot */
|
|
34
|
-
readonly builtinPackages: readonly string[];
|
|
35
|
-
/** npm registry URL (default: https://registry.npmjs.org) */
|
|
36
|
-
readonly registry?: string;
|
|
37
|
-
}
|
|
38
|
-
interface InstalledPackage {
|
|
39
|
-
readonly name: string;
|
|
40
|
-
readonly version: string;
|
|
41
|
-
readonly path: string;
|
|
42
|
-
}
|
|
43
|
-
declare class AddonInstaller {
|
|
44
|
-
private readonly config;
|
|
45
|
-
constructor(config: AddonInstallerConfig);
|
|
46
|
-
/** Initialize addon directory — create if not exists, install builtins if needed */
|
|
47
|
-
initialize(): Promise<void>;
|
|
48
|
-
/** Ensure addon directory exists with a package.json */
|
|
49
|
-
private ensureAddonDirectory;
|
|
50
|
-
/** Install builtin packages if not already present */
|
|
51
|
-
private installBuiltins;
|
|
52
|
-
/**
|
|
53
|
-
* Ensure a set of packages are installed — installs any that are missing.
|
|
54
|
-
* This is the public entry-point used during boot to guarantee required
|
|
55
|
-
* addon packages are present before the loader tries to resolve them.
|
|
56
|
-
*/
|
|
57
|
-
ensureInstalled(packages: string[]): Promise<void>;
|
|
58
|
-
/** Check if a package is installed */
|
|
59
|
-
isInstalled(packageName: string): boolean;
|
|
60
|
-
/** Get installed package info */
|
|
61
|
-
getInstalledPackage(packageName: string): InstalledPackage | null;
|
|
62
|
-
/** List all installed addon packages (those with camstack.addons in package.json) */
|
|
63
|
-
listInstalled(): InstalledPackage[];
|
|
64
|
-
/** Install one or more packages from npm */
|
|
65
|
-
installPackages(packages: readonly string[]): Promise<void>;
|
|
66
|
-
/** Uninstall a package */
|
|
67
|
-
uninstallPackage(packageName: string): Promise<void>;
|
|
68
|
-
/** Update a package to latest version */
|
|
69
|
-
updatePackage(packageName: string): Promise<void>;
|
|
70
|
-
/** Install an addon from a local .tgz file */
|
|
71
|
-
installFromTgz(tgzPath: string): Promise<void>;
|
|
72
|
-
/** Update all packages */
|
|
73
|
-
updateAll(): Promise<void>;
|
|
74
|
-
/** Get the node_modules path for require/import resolution */
|
|
75
|
-
getNodeModulesPath(): string;
|
|
76
|
-
}
|
|
77
|
-
/** Default builtin packages that are auto-installed on first boot */
|
|
78
|
-
declare const BUILTIN_PACKAGES: readonly string[];
|
|
79
|
-
|
|
80
|
-
interface RegisteredAddon {
|
|
81
|
-
readonly declaration: AddonDeclaration;
|
|
82
|
-
readonly packageName: string;
|
|
83
|
-
readonly addonClass: new () => ICamstackAddon;
|
|
84
|
-
}
|
|
85
|
-
declare class AddonLoader {
|
|
86
|
-
private addons;
|
|
87
|
-
/** Load all addons from an npm package */
|
|
88
|
-
loadPackage(packageName: string): Promise<void>;
|
|
89
|
-
/** Load addon from a direct path (for development/testing) */
|
|
90
|
-
loadFromPath(addonId: string, modulePath: string, packageName: string, declaration?: Partial<AddonDeclaration>): Promise<void>;
|
|
91
|
-
/** Get a registered addon by ID */
|
|
92
|
-
getAddon(addonId: string): RegisteredAddon | undefined;
|
|
93
|
-
/** List all registered addons */
|
|
94
|
-
listAddons(): RegisteredAddon[];
|
|
95
|
-
/** Check if an addon is registered */
|
|
96
|
-
hasAddon(addonId: string): boolean;
|
|
97
|
-
/** Create a new instance of an addon (not yet initialized) */
|
|
98
|
-
createInstance(addonId: string): ICamstackAddon;
|
|
99
|
-
/** Load all installed addon packages from the addon directory */
|
|
100
|
-
loadAllInstalled(installer: AddonInstaller): Promise<void>;
|
|
101
|
-
/** Load addon package from a specific filesystem path */
|
|
102
|
-
loadPackageFromPath(packageName: string, packagePath: string): Promise<void>;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
declare class AddonEngineManager {
|
|
106
|
-
private readonly loader;
|
|
107
|
-
private readonly baseContext;
|
|
108
|
-
private engines;
|
|
109
|
-
constructor(loader: AddonLoader, baseContext: Partial<Omit<AddonContext, 'addonConfig'>>);
|
|
110
|
-
/**
|
|
111
|
-
* Get or create an addon engine for the given effective config.
|
|
112
|
-
* Cameras with the same addonId + effective config share the same engine.
|
|
113
|
-
*/
|
|
114
|
-
getOrCreateEngine(addonId: string, globalConfig: Record<string, unknown>, cameraOverride?: Record<string, unknown>): Promise<ICamstackAddon>;
|
|
115
|
-
/** Get all active engines */
|
|
116
|
-
getActiveEngines(): Map<string, ICamstackAddon>;
|
|
117
|
-
/** Shutdown a specific engine by its config key */
|
|
118
|
-
shutdownEngine(configKey: string): Promise<void>;
|
|
119
|
-
/** Shutdown all engines */
|
|
120
|
-
shutdownAll(): Promise<void>;
|
|
121
|
-
/** Compute a deterministic config key (visible for tests) */
|
|
122
|
-
computeConfigKey(addonId: string, effectiveConfig: Record<string, unknown>): string;
|
|
123
|
-
private hashConfig;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
interface ValidationIssue {
|
|
127
|
-
readonly step?: string;
|
|
128
|
-
readonly addon?: string;
|
|
129
|
-
readonly message: string;
|
|
130
|
-
readonly severity: 'error' | 'warning';
|
|
131
|
-
}
|
|
132
|
-
interface ValidationResult {
|
|
133
|
-
readonly valid: boolean;
|
|
134
|
-
readonly errors: readonly ValidationIssue[];
|
|
135
|
-
readonly warnings: readonly ValidationIssue[];
|
|
136
|
-
}
|
|
137
155
|
declare class PipelineValidator {
|
|
138
156
|
private readonly loader;
|
|
139
157
|
constructor(loader: AddonLoader);
|
|
@@ -155,169 +173,7 @@ declare class PipelineRunner {
|
|
|
155
173
|
private executeChildren;
|
|
156
174
|
}
|
|
157
175
|
|
|
158
|
-
|
|
159
|
-
* Central registry for all capability providers and consumers.
|
|
160
|
-
* Lives in @camstack/core. Mode-aware: singleton (one active) or collection (all active).
|
|
161
|
-
*
|
|
162
|
-
* Uses injected LoggingService, NEVER NestJS static Logger.
|
|
163
|
-
*/
|
|
164
|
-
declare class CapabilityRegistry {
|
|
165
|
-
private readonly logger;
|
|
166
|
-
private readonly configReader;
|
|
167
|
-
private readonly capabilities;
|
|
168
|
-
/** Per-device singleton overrides: deviceId → (capability → addonId) */
|
|
169
|
-
private readonly deviceOverrides;
|
|
170
|
-
/** Per-device collection filters: deviceId → (capability → addonIds[]) */
|
|
171
|
-
private readonly deviceCollectionFilters;
|
|
172
|
-
constructor(logger: IScopedLogger, configReader: (capability: string) => string | undefined);
|
|
173
|
-
/**
|
|
174
|
-
* Declare a capability (typically called when addon manifests are loaded).
|
|
175
|
-
* Must be called before registerProvider/registerConsumer for that capability.
|
|
176
|
-
*/
|
|
177
|
-
declareCapability(declaration: CapabilityDeclaration): void;
|
|
178
|
-
/**
|
|
179
|
-
* Register a capability provider (called by addon loader when addon is enabled).
|
|
180
|
-
* For singleton: auto-activates if user-preferred or first registered.
|
|
181
|
-
* For collection: adds to active set and notifies consumers.
|
|
182
|
-
*/
|
|
183
|
-
registerProvider(capability: string, addonId: string, provider: unknown): void;
|
|
184
|
-
/**
|
|
185
|
-
* Unregister a provider (called when addon is disabled/uninstalled).
|
|
186
|
-
*/
|
|
187
|
-
unregisterProvider(capability: string, addonId: string): void;
|
|
188
|
-
/**
|
|
189
|
-
* Register a consumer that wants to be notified when providers change.
|
|
190
|
-
* If a provider is already active, the consumer is immediately notified.
|
|
191
|
-
* Returns a disposer function for cleanup.
|
|
192
|
-
*/
|
|
193
|
-
registerConsumer<T = unknown>(registration: CapabilityConsumerRegistration<T>): () => void;
|
|
194
|
-
/**
|
|
195
|
-
* Get the active singleton provider for a capability.
|
|
196
|
-
* Returns null if none set.
|
|
197
|
-
*/
|
|
198
|
-
getSingleton<T = unknown>(capability: string): T | null;
|
|
199
|
-
/**
|
|
200
|
-
* Get all active collection providers for a capability.
|
|
201
|
-
*/
|
|
202
|
-
getCollection<T = unknown>(capability: string): readonly T[];
|
|
203
|
-
/**
|
|
204
|
-
* Set which addon should be the active singleton for a capability.
|
|
205
|
-
* Call with `immediate: true` to also swap the runtime provider now
|
|
206
|
-
* (consumers' onSet will be awaited).
|
|
207
|
-
*/
|
|
208
|
-
setActiveSingleton(capability: string, addonId: string, immediate?: boolean): Promise<void>;
|
|
209
|
-
/**
|
|
210
|
-
* Get the mode declared for a capability.
|
|
211
|
-
*/
|
|
212
|
-
getMode(capability: string): CapabilityMode | undefined;
|
|
213
|
-
/**
|
|
214
|
-
* List all registered capabilities with their providers.
|
|
215
|
-
*/
|
|
216
|
-
listCapabilities(): CapabilityInfo[];
|
|
217
|
-
/**
|
|
218
|
-
* Check if all dependencies for a capability are satisfied (have active providers).
|
|
219
|
-
*/
|
|
220
|
-
areDependenciesMet(declaration: CapabilityDeclaration): boolean;
|
|
221
|
-
/**
|
|
222
|
-
* Get the dependency-ordered list of capability names for boot sequencing.
|
|
223
|
-
* Returns capabilities sorted topologically by dependsOn.
|
|
224
|
-
* Throws if a cycle is detected.
|
|
225
|
-
*/
|
|
226
|
-
getBootOrder(): string[];
|
|
227
|
-
/**
|
|
228
|
-
* Set a per-device singleton override. When resolveForDevice is called for
|
|
229
|
-
* this device + capability, the specified addon's provider is returned
|
|
230
|
-
* instead of the global singleton.
|
|
231
|
-
*/
|
|
232
|
-
setDeviceOverride(deviceId: string, capability: string, addonId: string): void;
|
|
233
|
-
/**
|
|
234
|
-
* Clear a per-device singleton override, reverting to the global singleton.
|
|
235
|
-
*/
|
|
236
|
-
clearDeviceOverride(deviceId: string, capability: string): void;
|
|
237
|
-
/**
|
|
238
|
-
* Get all per-device singleton overrides for a device.
|
|
239
|
-
* Returns a Map of capability name to addon ID.
|
|
240
|
-
*/
|
|
241
|
-
getDeviceOverrides(deviceId: string): Map<string, string>;
|
|
242
|
-
/**
|
|
243
|
-
* Resolve a singleton provider for a specific device.
|
|
244
|
-
* 1. Check device override — return that addon's provider
|
|
245
|
-
* 2. Fallback to global singleton
|
|
246
|
-
*/
|
|
247
|
-
resolveForDevice<T = unknown>(capability: string, deviceId: string): T | null;
|
|
248
|
-
/**
|
|
249
|
-
* Set a per-device collection filter. When resolveCollectionForDevice is called
|
|
250
|
-
* for this device + capability, only providers from the specified addon IDs
|
|
251
|
-
* are returned instead of the full collection.
|
|
252
|
-
*/
|
|
253
|
-
setDeviceCollectionFilter(deviceId: string, capability: string, addonIds: string[]): void;
|
|
254
|
-
/**
|
|
255
|
-
* Clear a per-device collection filter, reverting to the full collection.
|
|
256
|
-
*/
|
|
257
|
-
clearDeviceCollectionFilter(deviceId: string, capability: string): void;
|
|
258
|
-
/**
|
|
259
|
-
* Resolve collection providers for a specific device.
|
|
260
|
-
* If a filter exists for the device + capability, only those addon's providers are returned.
|
|
261
|
-
* If no filter exists, the full collection is returned.
|
|
262
|
-
*/
|
|
263
|
-
resolveCollectionForDevice<T = unknown>(capability: string, deviceId: string): readonly T[];
|
|
264
|
-
/**
|
|
265
|
-
* Get a specific addon's provider by addon ID, regardless of whether it's the active singleton.
|
|
266
|
-
* Useful for per-device overrides that need to look up any registered provider.
|
|
267
|
-
*/
|
|
268
|
-
getProviderByAddonId<T = unknown>(capability: string, addonId: string): T | null;
|
|
269
|
-
private activateSingleton;
|
|
270
|
-
private activateSingletonAsync;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
interface InfraCapability {
|
|
274
|
-
/** Capability name */
|
|
275
|
-
readonly name: string;
|
|
276
|
-
/** If true, boot aborts when this capability's addon fails to initialize */
|
|
277
|
-
readonly required: boolean;
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Infrastructure capabilities that must boot before all other addons.
|
|
281
|
-
* Enabled in Phase 1 of the boot sequence. Order matters: storage before logging.
|
|
282
|
-
*/
|
|
283
|
-
declare const INFRA_CAPABILITIES: readonly InfraCapability[];
|
|
284
|
-
/** Check if a capability name is an infrastructure capability */
|
|
285
|
-
declare function isInfraCapability(name: string): boolean;
|
|
286
|
-
|
|
287
|
-
type ProcessState = 'stopped' | 'starting' | 'running' | 'stopping' | 'error';
|
|
288
|
-
interface ProcessConfig {
|
|
289
|
-
readonly id: string;
|
|
290
|
-
readonly label: string;
|
|
291
|
-
readonly command?: string;
|
|
292
|
-
readonly modulePath?: string;
|
|
293
|
-
readonly args?: string[];
|
|
294
|
-
readonly env?: Record<string, string>;
|
|
295
|
-
readonly autoRestart: boolean;
|
|
296
|
-
readonly maxRestarts?: number;
|
|
297
|
-
readonly healthCheck?: {
|
|
298
|
-
readonly intervalMs: number;
|
|
299
|
-
readonly timeoutMs: number;
|
|
300
|
-
readonly failureThreshold: number;
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
interface ProcessStats {
|
|
304
|
-
readonly pid: number;
|
|
305
|
-
readonly cpu: number;
|
|
306
|
-
readonly memory: number;
|
|
307
|
-
readonly uptime: number;
|
|
308
|
-
readonly restartCount: number;
|
|
309
|
-
}
|
|
310
|
-
interface ManagedProcessStatus {
|
|
311
|
-
readonly id: string;
|
|
312
|
-
readonly label: string;
|
|
313
|
-
readonly state: ProcessState;
|
|
314
|
-
readonly pid?: number;
|
|
315
|
-
readonly stats?: ProcessStats;
|
|
316
|
-
readonly lastCrashAt?: number;
|
|
317
|
-
readonly lastCrashError?: string;
|
|
318
|
-
readonly restartCount: number;
|
|
319
|
-
readonly nextRestartAt?: number;
|
|
320
|
-
}
|
|
176
|
+
type ProcessState = ElementState$1;
|
|
321
177
|
|
|
322
178
|
/** Event emitter for process lifecycle events */
|
|
323
179
|
type ProcessEventEmitter = {
|
|
@@ -363,30 +219,6 @@ declare class ProcessManager {
|
|
|
363
219
|
shutdownAll(): Promise<void>;
|
|
364
220
|
}
|
|
365
221
|
|
|
366
|
-
interface StreamNetworkStats {
|
|
367
|
-
readonly nominalBitrateKbps: number;
|
|
368
|
-
readonly observedBitrateKbps: number;
|
|
369
|
-
readonly peakBitrateKbps: number;
|
|
370
|
-
readonly packetLossPercent: number;
|
|
371
|
-
readonly lastUpdated: number;
|
|
372
|
-
}
|
|
373
|
-
interface ClientNetworkStats {
|
|
374
|
-
readonly rttMs: number;
|
|
375
|
-
readonly jitterMs: number;
|
|
376
|
-
readonly estimatedBandwidthKbps: number;
|
|
377
|
-
readonly lastUpdated: number;
|
|
378
|
-
}
|
|
379
|
-
interface DeviceNetworkStats {
|
|
380
|
-
readonly deviceId: string;
|
|
381
|
-
readonly streams: Readonly<Record<string, StreamNetworkStats>>;
|
|
382
|
-
readonly client?: ClientNetworkStats;
|
|
383
|
-
}
|
|
384
|
-
interface INetworkQualityTracker {
|
|
385
|
-
reportStreamStats(deviceId: string, streamId: string, bitrateKbps: number, packetLoss?: number): void;
|
|
386
|
-
reportClientStats(deviceId: string, stats: Omit<ClientNetworkStats, 'lastUpdated'>): void;
|
|
387
|
-
getDeviceStats(deviceId: string): DeviceNetworkStats | null;
|
|
388
|
-
getAllStats(): readonly DeviceNetworkStats[];
|
|
389
|
-
}
|
|
390
222
|
declare class NetworkQualityTracker implements INetworkQualityTracker {
|
|
391
223
|
private readonly devices;
|
|
392
224
|
private static readonly MAX_SAMPLES;
|
|
@@ -408,11 +240,7 @@ interface ReplSessionContext {
|
|
|
408
240
|
/** Pre-populated variables available in the REPL session */
|
|
409
241
|
readonly variables: Record<string, unknown>;
|
|
410
242
|
}
|
|
411
|
-
|
|
412
|
-
readonly output: string;
|
|
413
|
-
readonly type: 'value' | 'error' | 'void';
|
|
414
|
-
readonly duration: number;
|
|
415
|
-
}
|
|
243
|
+
|
|
416
244
|
interface IReplEngine {
|
|
417
245
|
execute(code: string, context: ReplSessionContext): Promise<ReplResult>;
|
|
418
246
|
getCompletions(partial: string, context: ReplSessionContext): Promise<string[]>;
|
|
@@ -436,62 +264,6 @@ declare class ReplEngine implements IReplEngine {
|
|
|
436
264
|
private buildSandbox;
|
|
437
265
|
}
|
|
438
266
|
|
|
439
|
-
interface AgentInfo {
|
|
440
|
-
readonly id: string;
|
|
441
|
-
readonly name: string;
|
|
442
|
-
readonly capabilities: readonly string[];
|
|
443
|
-
readonly host: string;
|
|
444
|
-
readonly port: number;
|
|
445
|
-
readonly resources?: AgentResources;
|
|
446
|
-
}
|
|
447
|
-
interface AgentResources {
|
|
448
|
-
readonly cpuCores?: number;
|
|
449
|
-
readonly memoryMB?: number;
|
|
450
|
-
readonly gpuAvailable?: boolean;
|
|
451
|
-
readonly gpuModel?: string;
|
|
452
|
-
}
|
|
453
|
-
interface AgentStatus {
|
|
454
|
-
readonly id: string;
|
|
455
|
-
readonly name: string;
|
|
456
|
-
readonly state: 'online' | 'offline' | 'degraded';
|
|
457
|
-
readonly capabilities: readonly string[];
|
|
458
|
-
readonly lastHeartbeat: number;
|
|
459
|
-
readonly connectedSince?: number;
|
|
460
|
-
readonly resources?: AgentResources;
|
|
461
|
-
readonly activeTaskCount: number;
|
|
462
|
-
readonly completedTaskCount: number;
|
|
463
|
-
readonly failedTaskCount: number;
|
|
464
|
-
}
|
|
465
|
-
interface AgentTask {
|
|
466
|
-
readonly id: string;
|
|
467
|
-
readonly capability: string;
|
|
468
|
-
readonly input: Record<string, unknown>;
|
|
469
|
-
readonly timeout: number;
|
|
470
|
-
readonly priority: 'low' | 'normal' | 'high';
|
|
471
|
-
readonly label?: string;
|
|
472
|
-
}
|
|
473
|
-
interface AgentTaskResult {
|
|
474
|
-
readonly taskId: string;
|
|
475
|
-
readonly agentId: string;
|
|
476
|
-
readonly status: 'success' | 'error' | 'timeout';
|
|
477
|
-
readonly output?: Record<string, unknown>;
|
|
478
|
-
readonly error?: string;
|
|
479
|
-
readonly durationMs: number;
|
|
480
|
-
}
|
|
481
|
-
interface TaskDispatchOptions {
|
|
482
|
-
readonly preferredAgent?: string;
|
|
483
|
-
readonly capability: string;
|
|
484
|
-
readonly remoteOnly?: boolean;
|
|
485
|
-
}
|
|
486
|
-
interface AgentEntry {
|
|
487
|
-
readonly info: AgentInfo;
|
|
488
|
-
state: 'online' | 'offline' | 'degraded';
|
|
489
|
-
connectedSince: number;
|
|
490
|
-
lastHeartbeat: number;
|
|
491
|
-
activeTaskCount: number;
|
|
492
|
-
completedTaskCount: number;
|
|
493
|
-
failedTaskCount: number;
|
|
494
|
-
}
|
|
495
267
|
/** Event emitter for agent lifecycle and task events */
|
|
496
268
|
type AgentEventEmitter = {
|
|
497
269
|
emitAgentRegistered(agentId: string, capabilities: readonly string[]): void;
|
|
@@ -543,21 +315,6 @@ declare class TaskDispatcher {
|
|
|
543
315
|
private sendToAgent;
|
|
544
316
|
}
|
|
545
317
|
|
|
546
|
-
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
547
|
-
interface LogEntry {
|
|
548
|
-
timestamp: Date;
|
|
549
|
-
level: LogLevel;
|
|
550
|
-
scope: string[];
|
|
551
|
-
message: string;
|
|
552
|
-
meta?: Record<string, unknown>;
|
|
553
|
-
}
|
|
554
|
-
interface LogFilter {
|
|
555
|
-
scope?: string[];
|
|
556
|
-
level?: LogLevel;
|
|
557
|
-
since?: Date;
|
|
558
|
-
until?: Date;
|
|
559
|
-
limit?: number;
|
|
560
|
-
}
|
|
561
318
|
declare class LogRingBuffer {
|
|
562
319
|
private readonly capacity;
|
|
563
320
|
private readonly buffer;
|
|
@@ -706,128 +463,6 @@ declare class RecordTaskHandler implements ITaskHandler {
|
|
|
706
463
|
cancel(): Promise<void>;
|
|
707
464
|
}
|
|
708
465
|
|
|
709
|
-
declare class FileSystemStorage implements IFileStorage$1 {
|
|
710
|
-
private readonly basePath;
|
|
711
|
-
constructor(basePath: string);
|
|
712
|
-
readFile(filePath: string): Promise<Buffer>;
|
|
713
|
-
writeFile(filePath: string, data: Buffer): Promise<void>;
|
|
714
|
-
deleteFile(filePath: string): Promise<void>;
|
|
715
|
-
listFiles(prefix?: string): Promise<readonly string[]>;
|
|
716
|
-
getFileUrl(_path: string): Promise<string>;
|
|
717
|
-
exists(filePath: string): Promise<boolean>;
|
|
718
|
-
}
|
|
719
|
-
declare class SqliteStorageProvider implements IStorageProvider$1 {
|
|
720
|
-
private mainDb;
|
|
721
|
-
private sharedStructured;
|
|
722
|
-
private readonly locations;
|
|
723
|
-
initialize(): Promise<void>;
|
|
724
|
-
/**
|
|
725
|
-
* Configure all storage locations.
|
|
726
|
-
* ONE single SQLite database (camstack.db) is used for ALL structured storage.
|
|
727
|
-
* File-based locations use the filesystem at their configured path.
|
|
728
|
-
*/
|
|
729
|
-
configure(config: {
|
|
730
|
-
locations: Record<string, string>;
|
|
731
|
-
}): Promise<void>;
|
|
732
|
-
getLocation(name: StorageLocationName$1): IStorageLocation$1;
|
|
733
|
-
shutdown(): Promise<void>;
|
|
734
|
-
export(_locationName: StorageLocationName$1): Promise<Buffer>;
|
|
735
|
-
import(_locationName: StorageLocationName$1, _data: Buffer): Promise<void>;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
declare class SqliteStorageAddon implements ICamstackAddon, IConfigurable {
|
|
739
|
-
readonly manifest: AddonManifest;
|
|
740
|
-
private provider;
|
|
741
|
-
initialize(context: AddonContext): Promise<void>;
|
|
742
|
-
shutdown(): Promise<void>;
|
|
743
|
-
getProvider(): SqliteStorageProvider;
|
|
744
|
-
getCapabilityProvider<K extends keyof CapabilityProviderMap>(name: K): CapabilityProviderMap[K] | null;
|
|
745
|
-
getConfigSchema(): ConfigUISchema;
|
|
746
|
-
getConfig(): Record<string, unknown>;
|
|
747
|
-
onConfigChange(_config: Record<string, unknown>): Promise<void>;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
interface WinstonConfig {
|
|
751
|
-
readonly level: string;
|
|
752
|
-
readonly retentionDays: number;
|
|
753
|
-
/** Resolved absolute path to the logs directory (replaces the old dataPath field). */
|
|
754
|
-
readonly logsDir: string;
|
|
755
|
-
}
|
|
756
|
-
declare class WinstonDestination implements ILogDestination$1 {
|
|
757
|
-
private logger;
|
|
758
|
-
initialize(config?: WinstonConfig): Promise<void>;
|
|
759
|
-
write(entry: LogEntry$1): void;
|
|
760
|
-
query(_filter: LogFilter$1): Promise<readonly LogEntry$1[]>;
|
|
761
|
-
shutdown(): Promise<void>;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
declare class WinstonLoggingAddon implements ICamstackAddon, IConfigurable {
|
|
765
|
-
readonly manifest: AddonManifest;
|
|
766
|
-
private destination;
|
|
767
|
-
private currentConfig;
|
|
768
|
-
initialize(context: AddonContext): Promise<void>;
|
|
769
|
-
shutdown(): Promise<void>;
|
|
770
|
-
getDestination(): WinstonDestination;
|
|
771
|
-
getCapabilityProvider<K extends keyof CapabilityProviderMap>(name: K): CapabilityProviderMap[K] | null;
|
|
772
|
-
getConfigSchema(): ConfigUISchema;
|
|
773
|
-
getConfig(): Record<string, unknown>;
|
|
774
|
-
onConfigChange(config: Record<string, unknown>): Promise<void>;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
interface BackupManifest {
|
|
778
|
-
readonly id: string;
|
|
779
|
-
readonly timestamp: number;
|
|
780
|
-
readonly label?: string;
|
|
781
|
-
readonly locations: readonly string[];
|
|
782
|
-
readonly sizeMB: number;
|
|
783
|
-
readonly path: string;
|
|
784
|
-
}
|
|
785
|
-
interface BackupConfig {
|
|
786
|
-
readonly backupDir: string;
|
|
787
|
-
readonly retentionCount: number;
|
|
788
|
-
}
|
|
789
|
-
declare class LocalBackupService {
|
|
790
|
-
private readonly config;
|
|
791
|
-
private readonly logger;
|
|
792
|
-
private readonly eventBus;
|
|
793
|
-
private readonly storage;
|
|
794
|
-
private manifests;
|
|
795
|
-
constructor(config: BackupConfig, logger: IScopedLogger, eventBus: IEventBus, storage: IStorageLocation$1);
|
|
796
|
-
/** Create a backup of specified locations */
|
|
797
|
-
backup(options?: {
|
|
798
|
-
locations?: string[];
|
|
799
|
-
label?: string;
|
|
800
|
-
}): Promise<BackupManifest>;
|
|
801
|
-
/** Restore from a backup */
|
|
802
|
-
restore(backupId: string): Promise<void>;
|
|
803
|
-
/** List all backups sorted by timestamp descending */
|
|
804
|
-
list(): readonly BackupManifest[];
|
|
805
|
-
/** Delete a specific backup */
|
|
806
|
-
delete(backupId: string): Promise<void>;
|
|
807
|
-
private pruneOldBackups;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
declare class LocalBackupAddon implements ICamstackAddon, IConfigurable {
|
|
811
|
-
readonly manifest: AddonManifest;
|
|
812
|
-
private service;
|
|
813
|
-
private currentConfig;
|
|
814
|
-
initialize(context: AddonContext): Promise<void>;
|
|
815
|
-
shutdown(): Promise<void>;
|
|
816
|
-
getService(): LocalBackupService;
|
|
817
|
-
getCapabilityProvider<K extends keyof CapabilityProviderMap>(name: K): CapabilityProviderMap[K] | null;
|
|
818
|
-
getConfigSchema(): ConfigUISchema;
|
|
819
|
-
getConfig(): Record<string, unknown>;
|
|
820
|
-
onConfigChange(config: Record<string, unknown>): Promise<void>;
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
declare class AdminUIAddon implements ICamstackAddon {
|
|
824
|
-
readonly id = "admin-ui";
|
|
825
|
-
readonly manifest: AddonManifest;
|
|
826
|
-
initialize(_ctx: AddonContext): Promise<void>;
|
|
827
|
-
shutdown(): Promise<void>;
|
|
828
|
-
getCapabilityProvider<K extends keyof CapabilityProviderMap>(name: K): CapabilityProviderMap[K] | null;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
466
|
type ElementState = 'stopped' | 'starting' | 'running' | 'stopping' | 'error' | 'disabled';
|
|
832
467
|
interface ElementStatus {
|
|
833
468
|
state: ElementState;
|
|
@@ -856,18 +491,6 @@ declare class LifecycleStateMachine {
|
|
|
856
491
|
private isValidTransition;
|
|
857
492
|
}
|
|
858
493
|
|
|
859
|
-
interface FeatureManifest {
|
|
860
|
-
streaming: boolean;
|
|
861
|
-
notifications: boolean;
|
|
862
|
-
objectDetection: boolean;
|
|
863
|
-
remoteAccess: boolean;
|
|
864
|
-
agentCluster: boolean;
|
|
865
|
-
smartHome: boolean;
|
|
866
|
-
recordings: boolean;
|
|
867
|
-
backup: boolean;
|
|
868
|
-
repl: boolean;
|
|
869
|
-
}
|
|
870
|
-
type FeatureFlag = keyof FeatureManifest;
|
|
871
494
|
type FeatureConfigReader = {
|
|
872
495
|
readonly features: FeatureManifest;
|
|
873
496
|
};
|
|
@@ -878,240 +501,6 @@ declare class FeatureManager {
|
|
|
878
501
|
getManifest(): FeatureManifest;
|
|
879
502
|
}
|
|
880
503
|
|
|
881
|
-
/** Bootstrap config -- loaded from config.yaml ONLY at startup.
|
|
882
|
-
* All other settings live in SQL (system_settings table). */
|
|
883
|
-
declare const bootstrapSchema: z.ZodObject<{
|
|
884
|
-
/** Server mode: 'hub' (full server) or 'agent' (worker node) */
|
|
885
|
-
mode: z.ZodDefault<z.ZodEnum<["hub", "agent"]>>;
|
|
886
|
-
server: z.ZodDefault<z.ZodObject<{
|
|
887
|
-
port: z.ZodDefault<z.ZodNumber>;
|
|
888
|
-
host: z.ZodDefault<z.ZodString>;
|
|
889
|
-
dataPath: z.ZodDefault<z.ZodString>;
|
|
890
|
-
}, "strip", z.ZodTypeAny, {
|
|
891
|
-
port: number;
|
|
892
|
-
host: string;
|
|
893
|
-
dataPath: string;
|
|
894
|
-
}, {
|
|
895
|
-
port?: number | undefined;
|
|
896
|
-
host?: string | undefined;
|
|
897
|
-
dataPath?: string | undefined;
|
|
898
|
-
}>>;
|
|
899
|
-
auth: z.ZodDefault<z.ZodObject<{
|
|
900
|
-
jwtSecret: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
901
|
-
adminUsername: z.ZodDefault<z.ZodString>;
|
|
902
|
-
adminPassword: z.ZodDefault<z.ZodString>;
|
|
903
|
-
}, "strip", z.ZodTypeAny, {
|
|
904
|
-
jwtSecret: string | null;
|
|
905
|
-
adminUsername: string;
|
|
906
|
-
adminPassword: string;
|
|
907
|
-
}, {
|
|
908
|
-
jwtSecret?: string | null | undefined;
|
|
909
|
-
adminUsername?: string | undefined;
|
|
910
|
-
adminPassword?: string | undefined;
|
|
911
|
-
}>>;
|
|
912
|
-
/** Hub connection config — only used when mode='agent' */
|
|
913
|
-
hub: z.ZodDefault<z.ZodObject<{
|
|
914
|
-
url: z.ZodDefault<z.ZodString>;
|
|
915
|
-
token: z.ZodDefault<z.ZodString>;
|
|
916
|
-
}, "strip", z.ZodTypeAny, {
|
|
917
|
-
url: string;
|
|
918
|
-
token: string;
|
|
919
|
-
}, {
|
|
920
|
-
url?: string | undefined;
|
|
921
|
-
token?: string | undefined;
|
|
922
|
-
}>>;
|
|
923
|
-
/** Agent-specific config — only used when mode='agent' */
|
|
924
|
-
agent: z.ZodDefault<z.ZodObject<{
|
|
925
|
-
name: z.ZodDefault<z.ZodString>;
|
|
926
|
-
/** Port for the agent status page (minimal HTML) */
|
|
927
|
-
statusPort: z.ZodDefault<z.ZodNumber>;
|
|
928
|
-
}, "strip", z.ZodTypeAny, {
|
|
929
|
-
name: string;
|
|
930
|
-
statusPort: number;
|
|
931
|
-
}, {
|
|
932
|
-
name?: string | undefined;
|
|
933
|
-
statusPort?: number | undefined;
|
|
934
|
-
}>>;
|
|
935
|
-
}, "strip", z.ZodTypeAny, {
|
|
936
|
-
agent: {
|
|
937
|
-
name: string;
|
|
938
|
-
statusPort: number;
|
|
939
|
-
};
|
|
940
|
-
auth: {
|
|
941
|
-
jwtSecret: string | null;
|
|
942
|
-
adminUsername: string;
|
|
943
|
-
adminPassword: string;
|
|
944
|
-
};
|
|
945
|
-
mode: "agent" | "hub";
|
|
946
|
-
hub: {
|
|
947
|
-
url: string;
|
|
948
|
-
token: string;
|
|
949
|
-
};
|
|
950
|
-
server: {
|
|
951
|
-
port: number;
|
|
952
|
-
host: string;
|
|
953
|
-
dataPath: string;
|
|
954
|
-
};
|
|
955
|
-
}, {
|
|
956
|
-
agent?: {
|
|
957
|
-
name?: string | undefined;
|
|
958
|
-
statusPort?: number | undefined;
|
|
959
|
-
} | undefined;
|
|
960
|
-
auth?: {
|
|
961
|
-
jwtSecret?: string | null | undefined;
|
|
962
|
-
adminUsername?: string | undefined;
|
|
963
|
-
adminPassword?: string | undefined;
|
|
964
|
-
} | undefined;
|
|
965
|
-
mode?: "agent" | "hub" | undefined;
|
|
966
|
-
hub?: {
|
|
967
|
-
url?: string | undefined;
|
|
968
|
-
token?: string | undefined;
|
|
969
|
-
} | undefined;
|
|
970
|
-
server?: {
|
|
971
|
-
port?: number | undefined;
|
|
972
|
-
host?: string | undefined;
|
|
973
|
-
dataPath?: string | undefined;
|
|
974
|
-
} | undefined;
|
|
975
|
-
}>;
|
|
976
|
-
type BootstrapConfig = z.infer<typeof bootstrapSchema>;
|
|
977
|
-
/**
|
|
978
|
-
* Runtime defaults -- used by ConfigManager.get() for backward compatibility
|
|
979
|
-
* until Plan B wires all runtime settings to the system_settings SQL table.
|
|
980
|
-
*/
|
|
981
|
-
declare const RUNTIME_DEFAULTS: Record<string, unknown>;
|
|
982
|
-
type ServerMode = 'hub' | 'agent';
|
|
983
|
-
type AppConfig = BootstrapConfig & {
|
|
984
|
-
features: {
|
|
985
|
-
streaming: boolean;
|
|
986
|
-
notifications: boolean;
|
|
987
|
-
objectDetection: boolean;
|
|
988
|
-
remoteAccess: boolean;
|
|
989
|
-
agentCluster: boolean;
|
|
990
|
-
smartHome: boolean;
|
|
991
|
-
recordings: boolean;
|
|
992
|
-
backup: boolean;
|
|
993
|
-
repl: boolean;
|
|
994
|
-
};
|
|
995
|
-
storage: {
|
|
996
|
-
provider: string;
|
|
997
|
-
locations: Record<string, string>;
|
|
998
|
-
};
|
|
999
|
-
logging: {
|
|
1000
|
-
level: string;
|
|
1001
|
-
retentionDays: number;
|
|
1002
|
-
};
|
|
1003
|
-
eventBus: {
|
|
1004
|
-
ringBufferSize: number;
|
|
1005
|
-
};
|
|
1006
|
-
addons: {
|
|
1007
|
-
enabled: string[];
|
|
1008
|
-
};
|
|
1009
|
-
retention: {
|
|
1010
|
-
detectionEventsDays: number;
|
|
1011
|
-
audioLevelsDays: number;
|
|
1012
|
-
};
|
|
1013
|
-
providers: Array<{
|
|
1014
|
-
id: string;
|
|
1015
|
-
type: string;
|
|
1016
|
-
name: string;
|
|
1017
|
-
url?: string;
|
|
1018
|
-
username?: string;
|
|
1019
|
-
password?: string;
|
|
1020
|
-
mqtt?: {
|
|
1021
|
-
brokerUrl: string;
|
|
1022
|
-
username?: string;
|
|
1023
|
-
password?: string;
|
|
1024
|
-
topicPrefix: string;
|
|
1025
|
-
};
|
|
1026
|
-
}>;
|
|
1027
|
-
};
|
|
1028
|
-
|
|
1029
|
-
interface ISettingsStore {
|
|
1030
|
-
getSystem(key: string): unknown;
|
|
1031
|
-
setSystem(key: string, value: unknown): void;
|
|
1032
|
-
getAllSystem(): Record<string, unknown>;
|
|
1033
|
-
getAllAddon(addonId: string): Record<string, unknown>;
|
|
1034
|
-
setAllAddon(addonId: string, config: Record<string, unknown>): void;
|
|
1035
|
-
getAllProvider(providerId: string): Record<string, unknown>;
|
|
1036
|
-
setProvider(providerId: string, key: string, value: unknown): void;
|
|
1037
|
-
getAllDevice(deviceId: string): Record<string, unknown>;
|
|
1038
|
-
setDevice(deviceId: string, key: string, value: unknown): void;
|
|
1039
|
-
}
|
|
1040
|
-
declare class ConfigManager {
|
|
1041
|
-
private readonly configPath;
|
|
1042
|
-
private bootstrapConfig;
|
|
1043
|
-
private settingsStore;
|
|
1044
|
-
constructor(configPath: string);
|
|
1045
|
-
/** Called by main.ts after the SQLite DB is ready (Phase 2). */
|
|
1046
|
-
setSettingsStore(store: ISettingsStore): void;
|
|
1047
|
-
/**
|
|
1048
|
-
* Get a config value by dot-notation path.
|
|
1049
|
-
* Priority: bootstrap config -> SQL system_settings -> RUNTIME_DEFAULTS fallback.
|
|
1050
|
-
*/
|
|
1051
|
-
get<T>(path: string): T;
|
|
1052
|
-
/**
|
|
1053
|
-
* Write a value to SQL system_settings.
|
|
1054
|
-
* Throws if the settings store is not yet wired.
|
|
1055
|
-
*/
|
|
1056
|
-
set(key: string, value: unknown): void;
|
|
1057
|
-
/**
|
|
1058
|
-
* Bulk-read all system_settings keys that belong to a logical section.
|
|
1059
|
-
* A "section" is the first segment of a dot-notation key (e.g. 'features', 'logging').
|
|
1060
|
-
*/
|
|
1061
|
-
getSection(section: string): Record<string, unknown>;
|
|
1062
|
-
/**
|
|
1063
|
-
* Bulk-write a section of runtime settings to SQL system_settings.
|
|
1064
|
-
* Each entry in `data` is stored as `section.key`.
|
|
1065
|
-
*/
|
|
1066
|
-
setSection(section: string, data: Record<string, unknown>): void;
|
|
1067
|
-
/** Read all config for an addon from addon_settings. */
|
|
1068
|
-
getAddonConfig(addonId: string): Record<string, unknown>;
|
|
1069
|
-
/** Write (bulk-replace) config for an addon to addon_settings. */
|
|
1070
|
-
setAddonConfig(addonId: string, config: Record<string, unknown>): void;
|
|
1071
|
-
/** Read all config for a provider from provider_settings. */
|
|
1072
|
-
getProviderConfig(providerId: string): Record<string, unknown>;
|
|
1073
|
-
/** Write (upsert) a single key for a provider to provider_settings. */
|
|
1074
|
-
setProviderConfig(providerId: string, key: string, value: unknown): void;
|
|
1075
|
-
/** Read all config for a device from device_settings. */
|
|
1076
|
-
getDeviceConfig(deviceId: string): Record<string, unknown>;
|
|
1077
|
-
/** Write (upsert) a single key for a device to device_settings. */
|
|
1078
|
-
setDeviceConfig(deviceId: string, key: string, value: unknown): void;
|
|
1079
|
-
/** Get a value from the parsed bootstrap config */
|
|
1080
|
-
getBootstrap<T>(path: string): T;
|
|
1081
|
-
/** Features accessor -- reads from SQL when available, falls back to RUNTIME_DEFAULTS */
|
|
1082
|
-
get features(): FeatureManifest;
|
|
1083
|
-
/**
|
|
1084
|
-
* Returns a merged view of bootstrap config + runtime defaults for backward compat.
|
|
1085
|
-
*/
|
|
1086
|
-
get raw(): AppConfig;
|
|
1087
|
-
/**
|
|
1088
|
-
* Atomically update one top-level section of config.yaml and sync in-memory.
|
|
1089
|
-
* Only bootstrap sections (server, auth) are persisted. Runtime settings should
|
|
1090
|
-
* go to SQL (Plan B).
|
|
1091
|
-
*/
|
|
1092
|
-
update(section: string, data: Record<string, unknown>): void;
|
|
1093
|
-
/**
|
|
1094
|
-
* Deep-set a value in a nested plain object using a dot-notation path.
|
|
1095
|
-
* Returns a new object (immutable).
|
|
1096
|
-
*/
|
|
1097
|
-
private setNested;
|
|
1098
|
-
/**
|
|
1099
|
-
* Apply env var overrides onto the raw YAML object.
|
|
1100
|
-
* Only bootstrap-level env vars are applied.
|
|
1101
|
-
*/
|
|
1102
|
-
private applyEnvOverrides;
|
|
1103
|
-
private loadYaml;
|
|
1104
|
-
private warnDefaultCredentials;
|
|
1105
|
-
private getFromBootstrap;
|
|
1106
|
-
private getFromRuntimeDefaults;
|
|
1107
|
-
/**
|
|
1108
|
-
* Perform a prefix-based nested lookup against SQL system_settings.
|
|
1109
|
-
* e.g. path='features' matches keys 'features.streaming', 'features.notifications', etc.
|
|
1110
|
-
* Returns an object keyed by the sub-key, or undefined if nothing is found.
|
|
1111
|
-
*/
|
|
1112
|
-
private getNestedFromSystemSettings;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
504
|
declare class SystemEventBus implements IEventBus {
|
|
1116
505
|
private readonly ringBuffer;
|
|
1117
506
|
private readonly subscribers;
|
|
@@ -1185,8 +574,8 @@ interface IStorageProvider {
|
|
|
1185
574
|
initialize(): Promise<void>;
|
|
1186
575
|
shutdown(): Promise<void>;
|
|
1187
576
|
getLocation(name: StorageLocationName): IStorageLocation;
|
|
1188
|
-
export(locationName: StorageLocationName): Promise<Buffer>;
|
|
1189
|
-
import(locationName: StorageLocationName, data: Buffer): Promise<void>;
|
|
577
|
+
export?(locationName: StorageLocationName): Promise<Buffer>;
|
|
578
|
+
import?(locationName: StorageLocationName, data: Buffer): Promise<void>;
|
|
1190
579
|
}
|
|
1191
580
|
interface QueryFilter {
|
|
1192
581
|
where?: Record<string, unknown>;
|
|
@@ -1223,94 +612,38 @@ interface IStorageLocation {
|
|
|
1223
612
|
structured?: IStructuredStorage;
|
|
1224
613
|
files?: IFileStorage;
|
|
1225
614
|
}
|
|
615
|
+
/**
|
|
616
|
+
* StorageManager — bridge between legacy code (getLocation/getLocationPath)
|
|
617
|
+
* and the new capability-based storage system.
|
|
618
|
+
*
|
|
619
|
+
* Legacy consumers call getLocation('addon', namespace) to get structured + file storage.
|
|
620
|
+
* This manager builds the response from:
|
|
621
|
+
* - SettingsBackend (for structured queries) — provided by sqlite-settings addon
|
|
622
|
+
* - LocationManager (for file paths) — set during Phase 2 boot
|
|
623
|
+
*/
|
|
1226
624
|
declare class StorageManager {
|
|
1227
|
-
private
|
|
625
|
+
private legacyProvider;
|
|
1228
626
|
private locationManager;
|
|
1229
|
-
|
|
627
|
+
private newStorageProvider;
|
|
628
|
+
private settingsBackend;
|
|
629
|
+
/** @deprecated Set by legacy capability consumer — use setNewStorageProvider instead */
|
|
630
|
+
setProvider(provider: IStorageProvider | IStorageProvider$1): void;
|
|
631
|
+
setNewStorageProvider(provider: IStorageProvider$1): void;
|
|
632
|
+
setSettingsBackend(backend: ISettingsBackend): void;
|
|
1230
633
|
getProvider(): IStorageProvider;
|
|
1231
|
-
/**
|
|
1232
|
-
* Set the StorageLocationManager (called from main.ts during Phase 2 boot,
|
|
1233
|
-
* before NestJS lifecycle hooks run).
|
|
1234
|
-
*/
|
|
1235
634
|
setLocationManager(manager: StorageLocationManager): void;
|
|
1236
|
-
/**
|
|
1237
|
-
* Get the StorageLocationManager (for file path resolution).
|
|
1238
|
-
* Available after Phase 2 boot (main.ts calls setLocationManager).
|
|
1239
|
-
*/
|
|
1240
635
|
getLocationManager(): StorageLocationManager;
|
|
1241
|
-
/**
|
|
1242
|
-
* Initialize the StorageLocationManager with a dataPath and set it on this service.
|
|
1243
|
-
* Called during 3-phase boot from main.ts (Phase 2).
|
|
1244
|
-
*/
|
|
1245
636
|
initializeLocations(dataPath: string): Promise<void>;
|
|
1246
|
-
/**
|
|
1247
|
-
* Return the base filesystem path for a named storage location.
|
|
1248
|
-
* Convenience wrapper around locationManager.getBackend(name).basePath.
|
|
1249
|
-
* Available after Phase 2 boot (main.ts calls setLocationManager).
|
|
1250
|
-
*/
|
|
1251
637
|
getLocationPath(name: StorageLocationName): string;
|
|
1252
638
|
/**
|
|
1253
|
-
* Get a storage location
|
|
1254
|
-
*
|
|
1255
|
-
* With namespace: returns a scoped view where all collections/paths are prefixed
|
|
1256
|
-
* e.g., getLocation('addon', 'providers/frigate-1') -> collections prefixed with 'providers/frigate-1/'
|
|
639
|
+
* Get a storage location with optional namespace scoping.
|
|
640
|
+
* Builds IStorageLocation from settingsBackend (structured) + locationManager (files).
|
|
1257
641
|
*/
|
|
1258
642
|
getLocation(name: StorageLocationName | string, namespace?: string): IStorageLocation;
|
|
643
|
+
private createLegacyShim;
|
|
1259
644
|
private createNamespacedLocation;
|
|
1260
645
|
}
|
|
1261
646
|
|
|
1262
|
-
/**
|
|
1263
|
-
* Thin wrapper over better-sqlite3 that manages the four settings tables:
|
|
1264
|
-
* system_settings, addon_settings, provider_settings, device_settings.
|
|
1265
|
-
*
|
|
1266
|
-
* All values are stored as JSON text and deserialized on read.
|
|
1267
|
-
*/
|
|
1268
|
-
declare class SettingsStore {
|
|
1269
|
-
private readonly db;
|
|
1270
|
-
constructor(dbPath: string);
|
|
1271
|
-
getSystem(key: string): unknown;
|
|
1272
|
-
setSystem(key: string, value: unknown): void;
|
|
1273
|
-
getAllSystem(): Record<string, unknown>;
|
|
1274
|
-
getAddon(addonId: string, key: string): unknown;
|
|
1275
|
-
setAddon(addonId: string, key: string, value: unknown): void;
|
|
1276
|
-
getAllAddon(addonId: string): Record<string, unknown>;
|
|
1277
|
-
/** Bulk-replace all keys for an addon (within a transaction). */
|
|
1278
|
-
setAllAddon(addonId: string, config: Record<string, unknown>): void;
|
|
1279
|
-
getProvider(providerId: string, key: string): unknown;
|
|
1280
|
-
setProvider(providerId: string, key: string, value: unknown): void;
|
|
1281
|
-
getAllProvider(providerId: string): Record<string, unknown>;
|
|
1282
|
-
getDevice(deviceId: string, key: string): unknown;
|
|
1283
|
-
setDevice(deviceId: string, key: string, value: unknown): void;
|
|
1284
|
-
getAllDevice(deviceId: string): Record<string, unknown>;
|
|
1285
|
-
/** Close the SQLite connection (call on shutdown). */
|
|
1286
|
-
close(): void;
|
|
1287
|
-
/** Check if system_settings is empty (used for first-boot seeding). */
|
|
1288
|
-
isSystemSettingsEmpty(): boolean;
|
|
1289
|
-
/** Seed system_settings with RUNTIME_DEFAULTS (only on first boot). */
|
|
1290
|
-
seedDefaults(): void;
|
|
1291
|
-
private initTables;
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
/** Core table DDL statements -- executed on first boot */
|
|
1295
|
-
declare const CORE_TABLE_DDL: readonly string[];
|
|
1296
|
-
/** Addon table schema declaration */
|
|
1297
|
-
interface AddonTableSchema {
|
|
1298
|
-
readonly name: string;
|
|
1299
|
-
readonly columns: ReadonlyArray<{
|
|
1300
|
-
readonly name: string;
|
|
1301
|
-
readonly type: 'TEXT' | 'INTEGER' | 'REAL' | 'JSON';
|
|
1302
|
-
readonly primaryKey?: boolean;
|
|
1303
|
-
readonly notNull?: boolean;
|
|
1304
|
-
}>;
|
|
1305
|
-
readonly indexes?: ReadonlyArray<{
|
|
1306
|
-
readonly name: string;
|
|
1307
|
-
readonly columns: readonly string[];
|
|
1308
|
-
readonly unique?: boolean;
|
|
1309
|
-
}>;
|
|
1310
|
-
}
|
|
1311
|
-
/** Generate CREATE TABLE DDL from addon schema */
|
|
1312
|
-
declare function addonTableToDdl(schema: AddonTableSchema): string[];
|
|
1313
|
-
|
|
1314
647
|
/**
|
|
1315
648
|
* Manages scoped API tokens with restricted addon/route/capability access.
|
|
1316
649
|
* Framework-agnostic — dependencies injected via constructor.
|
|
@@ -1348,18 +681,6 @@ declare class ScopedTokenManager {
|
|
|
1348
681
|
updateLastUsed(tokenId: string): Promise<void>;
|
|
1349
682
|
}
|
|
1350
683
|
|
|
1351
|
-
type UserRole = 'super_admin' | 'admin' | 'viewer';
|
|
1352
|
-
interface TokenPayload {
|
|
1353
|
-
type?: 'api_key';
|
|
1354
|
-
keyId?: string;
|
|
1355
|
-
userId?: string;
|
|
1356
|
-
username?: string;
|
|
1357
|
-
role: UserRole;
|
|
1358
|
-
allowedProviders: string[] | '*';
|
|
1359
|
-
allowedDevices: Record<string, string[] | '*'>;
|
|
1360
|
-
iat?: number;
|
|
1361
|
-
exp?: number;
|
|
1362
|
-
}
|
|
1363
684
|
type AuthConfigReader = {
|
|
1364
685
|
get<T>(path: string): T;
|
|
1365
686
|
update(section: string, data: Record<string, unknown>): void;
|
|
@@ -1379,6 +700,15 @@ declare class AuthManager {
|
|
|
1379
700
|
prefix: string;
|
|
1380
701
|
};
|
|
1381
702
|
validateApiKey(token: string, storedHash: string): boolean;
|
|
703
|
+
/**
|
|
704
|
+
* Create a service token for agent/worker authentication.
|
|
705
|
+
* Used when forking workers or when agents register.
|
|
706
|
+
*/
|
|
707
|
+
createServiceToken(opts: {
|
|
708
|
+
readonly agentId: string;
|
|
709
|
+
readonly role?: string;
|
|
710
|
+
readonly expiresIn?: string;
|
|
711
|
+
}): string;
|
|
1382
712
|
/**
|
|
1383
713
|
* Set the scoped token manager for the auth chain.
|
|
1384
714
|
*/
|
|
@@ -1429,16 +759,6 @@ declare class ApiKeyManager {
|
|
|
1429
759
|
findById(id: string): Promise<ApiKeyRecord | null>;
|
|
1430
760
|
}
|
|
1431
761
|
|
|
1432
|
-
interface UserRecord {
|
|
1433
|
-
id: string;
|
|
1434
|
-
username: string;
|
|
1435
|
-
passwordHash: string;
|
|
1436
|
-
role: UserRole;
|
|
1437
|
-
allowedProviders: string[] | '*';
|
|
1438
|
-
allowedDevices: Record<string, string[] | '*'>;
|
|
1439
|
-
createdAt: number;
|
|
1440
|
-
updatedAt: number;
|
|
1441
|
-
}
|
|
1442
762
|
interface CreateUserInput {
|
|
1443
763
|
username: string;
|
|
1444
764
|
password: string;
|
|
@@ -1612,6 +932,125 @@ declare class CapabilityResolver {
|
|
|
1612
932
|
getEffectiveCapabilities(device: IResolvableDevice): string[];
|
|
1613
933
|
}
|
|
1614
934
|
|
|
935
|
+
interface TlsCertPair {
|
|
936
|
+
readonly cert: Buffer;
|
|
937
|
+
readonly key: Buffer;
|
|
938
|
+
}
|
|
939
|
+
interface EnsureTlsResult {
|
|
940
|
+
readonly certPath: string;
|
|
941
|
+
readonly keyPath: string;
|
|
942
|
+
readonly generated: boolean;
|
|
943
|
+
}
|
|
944
|
+
interface CertOptions {
|
|
945
|
+
/** Common Name for the cert (default: 'camstack.local') */
|
|
946
|
+
readonly commonName?: string;
|
|
947
|
+
/** Validity in days (default: 825 — max for browsers) */
|
|
948
|
+
readonly validDays?: number;
|
|
949
|
+
/** Additional SANs (DNS names or IPs) */
|
|
950
|
+
readonly extraSans?: readonly string[];
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Ensure a self-signed TLS certificate exists in the given directory.
|
|
954
|
+
* Generates one if missing. Returns paths to cert and key files.
|
|
955
|
+
*/
|
|
956
|
+
declare function ensureTlsCert(dataDir: string, options?: CertOptions): Promise<EnsureTlsResult>;
|
|
957
|
+
/**
|
|
958
|
+
* Load TLS cert+key from files. Returns Buffers suitable for Node.js TLS options.
|
|
959
|
+
*/
|
|
960
|
+
declare function loadTlsCert(certPath: string, keyPath: string): TlsCertPair;
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Factory for creating tRPC clients for addons.
|
|
964
|
+
*
|
|
965
|
+
* Two modes:
|
|
966
|
+
* - Direct caller (in-process): zero overhead, uses createCallerFactory
|
|
967
|
+
* - WSS client (worker/agent): real WebSocket connection to the server
|
|
968
|
+
*/
|
|
969
|
+
interface DirectCallerOptions {
|
|
970
|
+
/** The tRPC router instance (from buildAppRouter) */
|
|
971
|
+
readonly router: unknown;
|
|
972
|
+
/** Context for the caller (user identity, etc.) */
|
|
973
|
+
readonly context: {
|
|
974
|
+
readonly user: {
|
|
975
|
+
readonly id: string;
|
|
976
|
+
readonly username: string;
|
|
977
|
+
readonly role: string;
|
|
978
|
+
};
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
interface WssClientOptions {
|
|
982
|
+
/** WebSocket URL (e.g., wss://localhost:4443/trpc) */
|
|
983
|
+
readonly url: string;
|
|
984
|
+
/** Auth token for the connection */
|
|
985
|
+
readonly token: string;
|
|
986
|
+
}
|
|
987
|
+
declare class AddonApiFactory {
|
|
988
|
+
/**
|
|
989
|
+
* Build a WSS URL from host and port.
|
|
990
|
+
*/
|
|
991
|
+
buildWssUrl(host: string, port: number): string;
|
|
992
|
+
/**
|
|
993
|
+
* Create a direct caller -- calls tRPC procedures directly in-process.
|
|
994
|
+
* Zero network overhead. Used for in-process addons and dev mode.
|
|
995
|
+
*
|
|
996
|
+
* @param options.router - The tRPC router from buildAppRouter()
|
|
997
|
+
* @param options.context - The auth context (service account)
|
|
998
|
+
* @returns A tRPC caller that can be used as context.api
|
|
999
|
+
*/
|
|
1000
|
+
createDirectCaller(options: DirectCallerOptions): unknown;
|
|
1001
|
+
/**
|
|
1002
|
+
* Create a WSS tRPC client -- connects to the server via WebSocket.
|
|
1003
|
+
* Used for forked workers and remote agents.
|
|
1004
|
+
*
|
|
1005
|
+
* @param options.url - WSS URL (e.g., wss://localhost:4443/trpc)
|
|
1006
|
+
* @param options.token - Bearer token for authentication
|
|
1007
|
+
* @returns A tRPC client that can be used as context.api
|
|
1008
|
+
*/
|
|
1009
|
+
createWssClient(options: WssClientOptions): Promise<{
|
|
1010
|
+
readonly client: unknown;
|
|
1011
|
+
readonly close: () => void;
|
|
1012
|
+
}>;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
declare class PlatformScorer {
|
|
1016
|
+
private cached;
|
|
1017
|
+
/** Probe hardware + runtimes and score all backend combos. Cached after first call. */
|
|
1018
|
+
probe(): Promise<PlatformCapabilities>;
|
|
1019
|
+
probeHardware(): Promise<HardwareInfo>;
|
|
1020
|
+
private probeNodeBackends;
|
|
1021
|
+
private probePythonBackends;
|
|
1022
|
+
private scoreBackends;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
declare class InferenceConfigResolver {
|
|
1026
|
+
private readonly scores;
|
|
1027
|
+
private readonly hardware;
|
|
1028
|
+
constructor(scores: readonly PlatformScore[], hardware: HardwareInfo);
|
|
1029
|
+
/**
|
|
1030
|
+
* Compute accuracy/backend weights based on available system RAM.
|
|
1031
|
+
* availableRAM_MB is now sourced from systeminformation (reliable cross-platform),
|
|
1032
|
+
* not os.freemem() which is broken on macOS.
|
|
1033
|
+
*
|
|
1034
|
+
* - > 16 GB available: prefer larger, more accurate models (accuracy 0.6, backend 0.4)
|
|
1035
|
+
* - > 8 GB available: balanced (accuracy 0.5, backend 0.5)
|
|
1036
|
+
* - <= 8 GB available: prefer speed (accuracy 0.4, backend 0.6)
|
|
1037
|
+
*/
|
|
1038
|
+
private getWeights;
|
|
1039
|
+
/**
|
|
1040
|
+
* Given an addon's model requirements, pick the best model + runtime + backend.
|
|
1041
|
+
*
|
|
1042
|
+
* Algorithm:
|
|
1043
|
+
* 1. Filter models by available RAM (minRAM_MB < 25% of available RAM)
|
|
1044
|
+
* 2. For each remaining model, find the best platform score whose format
|
|
1045
|
+
* is available in the model's formats
|
|
1046
|
+
* 3. Pick the model with the highest combined score using RAM-adaptive weights:
|
|
1047
|
+
* - High RAM (>16 GB): accuracy × 0.6 + backend × 0.4 (prefer accuracy)
|
|
1048
|
+
* - Mid RAM (>8 GB): accuracy × 0.5 + backend × 0.5 (balanced)
|
|
1049
|
+
* - Low RAM (<=8 GB): accuracy × 0.4 + backend × 0.6 (prefer speed)
|
|
1050
|
+
*/
|
|
1051
|
+
resolve(requirements: readonly ModelRequirement[]): ResolvedInferenceConfig;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1615
1054
|
/** Minimal device registry interface for provider management */
|
|
1616
1055
|
type ProviderDeviceRegistry = {
|
|
1617
1056
|
registerProviderDevices(providerId: string, devices: readonly IRegistrableDevice[]): void;
|
|
@@ -1644,14 +1083,7 @@ interface IManagedProvider {
|
|
|
1644
1083
|
getDevices(): readonly IRegistrableDevice[];
|
|
1645
1084
|
subscribeLiveEvents(callback: (event: LiveEvent) => void): () => void;
|
|
1646
1085
|
}
|
|
1647
|
-
|
|
1648
|
-
id: string;
|
|
1649
|
-
type: string;
|
|
1650
|
-
name: string;
|
|
1651
|
-
status: ProviderStatus;
|
|
1652
|
-
started: boolean;
|
|
1653
|
-
lifecycle: ElementStatus;
|
|
1654
|
-
}
|
|
1086
|
+
|
|
1655
1087
|
declare class ProviderManager<P extends IManagedProvider = IManagedProvider> {
|
|
1656
1088
|
private readonly deviceRegistry;
|
|
1657
1089
|
private readonly eventBus;
|
|
@@ -1671,4 +1103,4 @@ declare class ProviderManager<P extends IManagedProvider = IManagedProvider> {
|
|
|
1671
1103
|
shutdownAll(): Promise<void>;
|
|
1672
1104
|
}
|
|
1673
1105
|
|
|
1674
|
-
export {
|
|
1106
|
+
export { AddonApiFactory, AddonRouteRegistry, AgentClient, type AgentClientConfig, type AgentEventEmitter, AgentRegistry, AgentTaskRunner, ApiKeyManager, type ApiKeyRecord, type ApiKeyStorageAccess, type AuthConfigReader, AuthManager, type BinaryHandler, type CapabilityBinding, CapabilityResolver, type CertOptions, type ConnectionHandler, DecodeTaskHandler, DetectTaskHandler, DeviceRegistry, type DirectCallerOptions, type ElementState, type ElementStatus, type EnsureTlsResult, EventBus, type FeatureConfigReader, FeatureManager, FsStorageBackend, type IAddonRegistryAccess, type IStorageProvider as ICoreStorageProvider, type IDeviceCapability, type IFileStorage, type ILogDestination, type IManagedProvider, type IRegisteredDevice, type IReplContextProvider, type IReplEngine, type IResolvableDevice, type IStorageBackend, type IStorageLocation, type IStructuredStorage, InferenceConfigResolver, LifecycleStateMachine, LogManager, LogRingBuffer, ManagedProcess, type MessageHandler, ModelDownloadService, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PlatformScorer, type ProcessEventEmitter, type ProcessLoggerFactory, ProcessManager, type ProcessState, type ProviderDeviceRegistry, ProviderManager, PythonEnvManager, type QueryFilter, RecordTaskHandler, ReplEngine, type ReplScope, type ReplSessionContext, ScopedLogger, ScopedTokenManager, StorageLocationManager, type StorageLocationName, StorageManager, type StorageRecord, SystemEventBus, TaskDispatcher, type TlsCertPair, ToastService, type Unsubscribe, type UserConfigReader, UserManager, type UserStorageAccess, type WssClientOptions, buildBinaryPath, downloadBinary, downloadFile, downloadModel, ensureBinary, ensureFfmpeg, ensurePython, ensureTlsCert, fetchJson, findInPath, getFfmpegDownloadUrl, getPlatformInfo, getPythonDownloadUrl, installPythonPackages, loadTlsCert };
|