edge-ai-client-ts 1.0.0

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/LICENSE +21 -0
  3. package/README.md +174 -0
  4. package/bin/ec-ts.js +18 -0
  5. package/dist/buffer/disk-queue.d.ts +140 -0
  6. package/dist/buffer/disk-queue.js +370 -0
  7. package/dist/cli/devices.d.ts +1 -0
  8. package/dist/cli/devices.js +61 -0
  9. package/dist/cli/enroll.d.ts +2 -0
  10. package/dist/cli/enroll.js +89 -0
  11. package/dist/cli/index.d.ts +10 -0
  12. package/dist/cli/index.js +116 -0
  13. package/dist/cli/messages.d.ts +1 -0
  14. package/dist/cli/messages.js +59 -0
  15. package/dist/cli/run.d.ts +5 -0
  16. package/dist/cli/run.js +112 -0
  17. package/dist/cli/status.d.ts +1 -0
  18. package/dist/cli/status.js +56 -0
  19. package/dist/cli/whoami.d.ts +2 -0
  20. package/dist/cli/whoami.js +41 -0
  21. package/dist/config/cmd-gate.d.ts +65 -0
  22. package/dist/config/cmd-gate.js +128 -0
  23. package/dist/config/settings.d.ts +209 -0
  24. package/dist/config/settings.js +627 -0
  25. package/dist/crypto/aes-gcm.d.ts +38 -0
  26. package/dist/crypto/aes-gcm.js +90 -0
  27. package/dist/crypto/hmac.d.ts +31 -0
  28. package/dist/crypto/hmac.js +52 -0
  29. package/dist/crypto/tls-guard.d.ts +36 -0
  30. package/dist/crypto/tls-guard.js +54 -0
  31. package/dist/daemon/manager.d.ts +82 -0
  32. package/dist/daemon/manager.js +461 -0
  33. package/dist/index.d.ts +39 -0
  34. package/dist/index.js +63 -0
  35. package/dist/logging/file-logger.d.ts +21 -0
  36. package/dist/logging/file-logger.js +71 -0
  37. package/dist/network/ws-client.d.ts +221 -0
  38. package/dist/network/ws-client.js +1134 -0
  39. package/dist/session/fail-fast.d.ts +70 -0
  40. package/dist/session/fail-fast.js +122 -0
  41. package/dist/session/manager.d.ts +136 -0
  42. package/dist/session/manager.js +291 -0
  43. package/dist/session/persistence.d.ts +103 -0
  44. package/dist/session/persistence.js +194 -0
  45. package/dist/session/pi-rpc.d.ts +164 -0
  46. package/dist/session/pi-rpc.js +412 -0
  47. package/dist/session/sftp.d.ts +64 -0
  48. package/dist/session/sftp.js +335 -0
  49. package/dist/session/shell-frame.d.ts +77 -0
  50. package/dist/session/shell-frame.js +199 -0
  51. package/dist/session/shell.d.ts +124 -0
  52. package/dist/session/shell.js +300 -0
  53. package/docs/CONFIGURATION.md +169 -0
  54. package/docs/INSTALLATION.md +164 -0
  55. package/docs/PROTOCOL.md +248 -0
  56. package/docs/TROUBLESHOOTING.md +177 -0
  57. package/package.json +79 -0
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Edge-client configuration — mirrors `edge-client/src/config/settings.rs`,
3
+ * `machine_id.rs`, `device_secret.rs`, and `mod.rs`.
4
+ *
5
+ * All field names EXACTLY match the Rust struct fields (snake_case), so a
6
+ * `config.toml` written by the Rust client round-trips through the TS client
7
+ * and vice versa.
8
+ *
9
+ * Security invariants preserved from Rust:
10
+ * - `machine_id`: UUIDv4, generated once, persisted atomically.
11
+ * - `device_secret`: atomic write, chmod 600 on Unix.
12
+ * - `relay.device_secret`: `skip_serializing` — never written to config.toml.
13
+ * - `enforceHostnameOrToken`: refuse to start with empty machine_id + no token.
14
+ * - Buffer key + edge-auth-token resolution: env var wins over config.
15
+ */
16
+ import type { CmdGateConfig } from './cmd-gate.js';
17
+ export interface ServerConfig {
18
+ ws_url: string;
19
+ /** Relay URL for `network_mode='lan'`. */
20
+ ws_url_lan?: string;
21
+ /** Relay URL for `network_mode='wan'`. */
22
+ ws_url_wan?: string;
23
+ }
24
+ export interface AgentConfig {
25
+ default_agent_id: string;
26
+ }
27
+ export interface BufferConfig {
28
+ max_memory_mb: number;
29
+ flush_interval_ms: number;
30
+ ack_timeout_ms: number;
31
+ max_retries: number;
32
+ /** AES-256-GCM key for buffer-dump encryption (hex, 64 chars = 32 bytes). */
33
+ key?: string;
34
+ /** Directory for encrypted overflow buffer dumps. */
35
+ dump_dir?: string;
36
+ }
37
+ export interface LoggingConfig {
38
+ level: string;
39
+ local_log_dir: string;
40
+ }
41
+ export interface ShellConfig {
42
+ /** Master on/off. Default false. */
43
+ enabled: boolean;
44
+ default_cols: number;
45
+ default_rows: number;
46
+ }
47
+ export interface ResourcesConfig {
48
+ /** Hard RAM cap in MB (0 = unlimited/legacy). Default 2048. */
49
+ memory_max_mb: number;
50
+ /** CPU quota in percent (200 = 2 cores, 0 = unlimited). Default 50. */
51
+ cpu_quota_percent: number;
52
+ /** Max tasks/processes (0 = unlimited). Default 256. */
53
+ tasks_max: number;
54
+ }
55
+ export interface RelayConfig {
56
+ /** Per-edge shared secret (`EDGE_AUTH_TOKEN`). */
57
+ auth_token?: string;
58
+ /**
59
+ * Per-device credential issued by relay at enrollment. Unique per machine.
60
+ * `skip_serializing` in Rust — NEVER written to config.toml.
61
+ */
62
+ device_secret?: string;
63
+ /** Pinned TLS SPKI fingerprint (SHA-256 hex, 64 chars). */
64
+ fingerprint?: string;
65
+ }
66
+ export interface Settings {
67
+ server: ServerConfig;
68
+ agent: AgentConfig;
69
+ buffer: BufferConfig;
70
+ logging: LoggingConfig;
71
+ machine_id: string;
72
+ /** Operator who owns this machine (set by `enroll`). */
73
+ owner_operator_id?: string;
74
+ /** Path to the `pi` binary (default "pi"; Windows often "pi.cmd"). */
75
+ pi_path?: string;
76
+ shell: ShellConfig;
77
+ relay: RelayConfig;
78
+ resources: ResourcesConfig;
79
+ cmd_gate: CmdGateConfig;
80
+ }
81
+ /**
82
+ * Versioned keyring for buffer-dump encryption (A4 key rotation).
83
+ * `current` encrypts every new dump; `previous` decrypts dumps written
84
+ * before a rotation (then lazily re-encrypted with `current`).
85
+ */
86
+ export interface Keyring {
87
+ current: Uint8Array;
88
+ previous?: Uint8Array;
89
+ }
90
+ /** Construct the default Settings (factory). Mirrors Rust `Settings::default()`. */
91
+ export declare function defaultSettings(): Settings;
92
+ /**
93
+ * The edge-ai-agent config directory. Mirrors Rust's `dirs::config_dir()`:
94
+ * - Linux: `$XDG_CONFIG_HOME/edge-ai-agent` or `~/.config/edge-ai-agent`
95
+ * - macOS: `~/Library/Application Support/edge-ai-agent`
96
+ * - Windows: `%APPDATA%\edge-ai-agent`
97
+ *
98
+ * Creates the directory if missing.
99
+ */
100
+ export declare function configDir(): string;
101
+ /** Path to `config.toml`. */
102
+ export declare function configPath(): string;
103
+ /**
104
+ * Write `data` to `filePath` atomically: write a sibling `.tmp` file then
105
+ * rename over the destination. Prevents torn writes. Mirrors the Rust
106
+ * `atomic_write` pattern in `disk_dump.rs` / `persistence.rs`.
107
+ *
108
+ * On Unix, optionally restricts the file to owner-only (0600).
109
+ */
110
+ export declare function atomicWriteFile(filePath: string, data: string | Buffer, options?: {
111
+ readonly mode?: number;
112
+ }): void;
113
+ /**
114
+ * Read-or-create the persisted machine_id inside `configDir`.
115
+ *
116
+ * 1. If `<configDir>/machine_id` exists and is non-empty after trim → return it.
117
+ * 2. Otherwise: create `configDir`, mint a fresh UUIDv4, atomically persist.
118
+ *
119
+ * Pure inner helper (takes explicit dir) for unit-testability.
120
+ */
121
+ export declare function generateMachineIdForDir(configDirPath: string): string;
122
+ /** Public entry point: resolve config dir and delegate. Mirrors `generate()`. */
123
+ export declare function generateMachineId(): string;
124
+ /**
125
+ * Read the persisted device secret from `configDir`, or `undefined`.
126
+ * Pure inner helper.
127
+ */
128
+ export declare function loadDeviceSecretForDir(configDirPath: string): string | undefined;
129
+ /** Read the persisted device secret from the real config dir, or `undefined`. */
130
+ export declare function loadDeviceSecret(): string | undefined;
131
+ /**
132
+ * Persist a device secret to `configDir` atomically. Overwrites existing.
133
+ * Pure inner helper.
134
+ */
135
+ export declare function storeDeviceSecretForDir(configDirPath: string, secret: string): void;
136
+ /** Persist a device secret to the real config dir (atomic write). */
137
+ export declare function storeDeviceSecret(secret: string): void;
138
+ /**
139
+ * Restrict the persisted secret file to owner-only (0600). Best-effort on
140
+ * Windows (no-op). Mirrors `restrict_perms`.
141
+ */
142
+ export declare function restrictDeviceSecretPerms(configDirPath: string): void;
143
+ /** Persist the current settings to `config.toml`. Mirrors Rust `save()`. */
144
+ export declare function saveSettings(settings: Settings): void;
145
+ /**
146
+ * Parse a TOML or JSON config string into a validated `Settings`.
147
+ * Missing fields fall back to defaults. Mirrors Rust `toml::from_str`.
148
+ */
149
+ export declare function parseSettings(content: string): Settings;
150
+ /**
151
+ * Load settings from `config.toml` (or `config.json`).
152
+ *
153
+ * - If the config file doesn't exist → write defaults and return them.
154
+ * - Applies the `EDGE_OWNER_OPERATOR_ID` env override (env wins over config).
155
+ * - If `machine_id` is empty → generate a UUIDv4, persist, and save.
156
+ *
157
+ * Mirrors Rust `Settings::load()`.
158
+ */
159
+ export declare function loadSettings(): Settings;
160
+ /** True if any resource limit is set (non-zero). */
161
+ export declare function hasResourceLimits(config: ResourcesConfig): boolean;
162
+ /** systemd `MemoryMax=` directive value, or undefined if unlimited. */
163
+ export declare function memoryMaxDirective(config: ResourcesConfig): string | undefined;
164
+ /** systemd `CPUQuota=` directive value, or undefined if unlimited. */
165
+ export declare function cpuQuotaDirective(config: ResourcesConfig): string | undefined;
166
+ /** systemd `TasksMax=` directive value, or undefined if unlimited. */
167
+ export declare function tasksMaxDirective(config: ResourcesConfig): string | undefined;
168
+ /**
169
+ * Resolve resource limits from env overrides. Env wins over config.
170
+ * Env names: `EDGE_MEMORY_MAX_MB`, `EDGE_CPU_QUOTA_PERCENT`, `EDGE_TASKS_MAX`.
171
+ */
172
+ export declare function resolveResources(env: Record<string, string | undefined>, config: ResourcesConfig): ResourcesConfig;
173
+ /** Decode a hex-encoded 32-byte key. Throws on invalid hex or wrong length. */
174
+ export declare function decodeHexKey(hex: string): Uint8Array;
175
+ /**
176
+ * Resolve the buffer encryption key.
177
+ * Precedence: `EDGE_BUFFER_KEY` env > `config.toml` `buffer.key`.
178
+ * Throws if unconfigured (fail-closed).
179
+ */
180
+ export declare function loadBufferKey(settings: Settings): Uint8Array;
181
+ /**
182
+ * Resolve the buffer-encryption keyring (A4 key rotation).
183
+ * `current` follows the same precedence as `loadBufferKey`.
184
+ * `previous` is `EDGE_BUFFER_KEY_PREVIOUS` env (optional, rotation window only).
185
+ */
186
+ export declare function loadKeyring(settings: Settings): Keyring;
187
+ /**
188
+ * Pure precedence resolver for the edge-auth token. Env wins; whitespace is
189
+ * trimmed and empty values treated as unset.
190
+ */
191
+ export declare function resolveEdgeAuthToken(envValue: string | undefined, configValue: string | undefined): string | undefined;
192
+ /**
193
+ * Resolve the edge-auth shared secret.
194
+ * Precedence: `EDGE_AUTH_TOKEN` env → `config.toml` `[relay] auth_token`.
195
+ * Returns `undefined` when unconfigured.
196
+ */
197
+ export declare function loadEdgeAuthToken(settings: Settings): string | undefined;
198
+ /**
199
+ * Edge-side mirror of the relay's auth-escape hatch.
200
+ * Active iff `AUTH_DISABLED=1` OR `ALLOW_AUTH_BYPASS=1`.
201
+ */
202
+ export declare function edgeAuthEscapeHatchActive(): boolean;
203
+ /**
204
+ * Refuse to start with an empty `machine_id` when there is no manual token.
205
+ * Mirrors `enforce_hostname_or_token`.
206
+ *
207
+ * Returns `undefined` on success or an error `string` on refusal.
208
+ */
209
+ export declare function enforceHostnameOrToken(machineId: string): string | undefined;