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,164 @@
1
+ # Installation
2
+
3
+ This guide covers installing `edge-ai-client-ts` on Linux, macOS, and
4
+ Windows for **end users** (running the client) and for **contributors**
5
+ (working on the package itself).
6
+
7
+ ---
8
+
9
+ ## End-user install
10
+
11
+ ### 1. Prerequisites
12
+
13
+ - **Node.js >= 20** (we use `crypto.randomUUID`, native `fetch`, modern ESM).
14
+ Check with:
15
+ ```bash
16
+ node --version # must print v20.x or newer
17
+ ```
18
+ If you need to install or upgrade Node, use [nvm](https://github.com/nvm-sh/nvm)
19
+ (Linux/macOS) or [fnm](https://github.com/Schniz/fnm) (cross-platform).
20
+
21
+ - A **C/C++ toolchain** is only required if `node-pty` does not ship a
22
+ prebuilt binary for your platform. Most users on x86_64 / arm64 Linux,
23
+ x86_64 / arm64 macOS, and x86_64 Windows do **not** need it.
24
+
25
+ ### 2. Install via npm
26
+
27
+ ```bash
28
+ npm install -g edge-ai-client-ts
29
+ ```
30
+
31
+ Verify the binary is on `PATH`:
32
+
33
+ ```bash
34
+ ec-ts --help
35
+ ```
36
+
37
+ ### 3. Configure secrets (NEVER commit them)
38
+
39
+ Set the fleet shared secret and any optional pins via environment
40
+ variables. **Do not paste these into shell history** — use a secrets
41
+ manager or a `.env` file with restrictive permissions.
42
+
43
+ ```bash
44
+ # Linux/macOS — current shell only
45
+ export EDGE_AUTH_TOKEN="<your-fleet-shared-secret>"
46
+
47
+ # Optional: pin the relay's TLS certificate (extract via the openssl
48
+ # one-liner in the upstream docs)
49
+ # export EDGE_RELAY_FINGERPRINT="<sha256:base64>"
50
+
51
+ # Optional: enable offline buffer encryption (32 bytes = 64 hex chars)
52
+ # export EDGE_BUFFER_KEY="<64 hex chars>"
53
+ ```
54
+
55
+ Persist across shells by adding the exports to `~/.bashrc`,
56
+ `~/.zshrc`, or `~/.config/fish/config.fish`.
57
+
58
+ ### 4. Enroll against your relay
59
+
60
+ After creating an operator in the Edge AI Agent dashboard, copy the
61
+ **per-operator API key** (format `opk_<base64>`) and enroll:
62
+
63
+ ```bash
64
+ ec-ts enroll --key "<your-operator-api-key>"
65
+ ```
66
+
67
+ This persists the credential to the **OS keychain** (Keychain on macOS,
68
+ Credential Manager on Windows, libsecret/Secret Service on Linux). The
69
+ plain key never touches a config file.
70
+
71
+ ### 5. Run the daemon
72
+
73
+ Foreground (foreground is the default; useful for development):
74
+
75
+ ```bash
76
+ ec-ts run
77
+ ```
78
+
79
+ As a system service (auto-start on boot):
80
+
81
+ ```bash
82
+ ec-ts run --install-service
83
+ # Uninstall later with:
84
+ ec-ts run --uninstall-service
85
+ ```
86
+
87
+ The service manager installs:
88
+
89
+ | OS | Service unit |
90
+ |----|--------------|
91
+ | Linux | `~/.config/systemd/user/ec-ts.service` |
92
+ | macOS | `~/Library/LaunchAgents/com.edgeai.ec-ts.plist` |
93
+ | Windows | `\LeastPrivilege` scheduled task |
94
+
95
+ ---
96
+
97
+ ## Contributor install
98
+
99
+ ### 1. Clone the monorepo
100
+
101
+ ```bash
102
+ git clone https://github.com/baphuongna/edge-ai-agent.git
103
+ cd edge-ai-agent/edge-client-ts
104
+ ```
105
+
106
+ ### 2. Install dependencies
107
+
108
+ ```bash
109
+ npm install
110
+ ```
111
+
112
+ ### 3. Verify
113
+
114
+ ```bash
115
+ npm run typecheck # tsc --noEmit
116
+ npm test # vitest run
117
+ npm run build # compile to dist/
118
+ ```
119
+
120
+ ### 4. End-to-end smoke (optional)
121
+
122
+ The smoke test connects a real daemon to a local `ws-service` and
123
+ verifies register → heartbeat → ack → reconnect. See
124
+ [`e2e-smoke/README.md`](../e2e-smoke/README.md).
125
+
126
+ ```bash
127
+ npm run smoke
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Upgrading
133
+
134
+ ```bash
135
+ npm install -g edge-ai-client-ts@latest
136
+ ```
137
+
138
+ Configuration and OS-keychain credentials are preserved across upgrades.
139
+ To downgrade, pin the version:
140
+
141
+ ```bash
142
+ npm install -g edge-ai-client-ts@1.0.0
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Uninstall
148
+
149
+ ```bash
150
+ # Remove the daemon + service
151
+ ec-ts run --uninstall-service
152
+
153
+ # Remove the package
154
+ npm uninstall -g edge-ai-client-ts
155
+
156
+ # Optional: wipe the per-user config directory
157
+ rm -rf ~/.config/edge-ai-agent # Linux
158
+ rm -rf ~/Library/Application\ Support/edge-ai-agent # macOS
159
+ # Windows: %APPDATA%\edge-ai-agent
160
+ ```
161
+
162
+ OS-keychain entries live in your platform's standard credential store and
163
+ are removed with your platform's credential manager (do not forget to
164
+ revoke the operator API key in the dashboard as well).
@@ -0,0 +1,248 @@
1
+ # Wire protocol reference
2
+
3
+ `edge-ai-client-ts` speaks the **exact same wire protocol** as the
4
+ Rust `edge-client` (`ec` binary). This document is the authoritative
5
+ spec; both clients must conform.
6
+
7
+ > If you find a discrepancy between the TS and Rust implementations,
8
+ > that is a bug — open an issue.
9
+
10
+ ---
11
+
12
+ ## Transport
13
+
14
+ - **WebSocket** to the relay's `/edge` path (text + binary frames).
15
+ - **Subprotocol** header: `Sec-WebSocket-Protocol: edgeai-v2, <auth_token>[, device-secret=<value>]`.
16
+ - The `<auth_token>` is the **fleet shared secret** (`EDGE_AUTH_TOKEN`).
17
+ - `device-secret=<value>` is sent when the device has been issued a
18
+ per-machine secret (post-enrollment).
19
+ - **TLS** (recommended for production):
20
+ - `wss://` only — `ws://` is refused when `EDGEAI_REQUIRE_TLS=1` or
21
+ `NODE_ENV=production`.
22
+ - Optional **SPKI fingerprint pin** (SHA-256 hex of the DER
23
+ `SubjectPublicKeyInfo`). Pin mismatch → handshake aborted.
24
+
25
+ ---
26
+
27
+ ## `/edge` JSON connection
28
+
29
+ All messages are JSON, UTF-8 text frames.
30
+
31
+ ### Client → Server
32
+
33
+ #### `register`
34
+
35
+ First message after upgrade.
36
+
37
+ ```json
38
+ {
39
+ "type": "register",
40
+ "machine_id": "<uuid-v4>",
41
+ "agent_id": "worker_default",
42
+ "platform": "linux",
43
+ "hostname": "<short-hostname>",
44
+ "agent_version": "0.1.0",
45
+ "operator_id": "op_<your-operator-id>"
46
+ }
47
+ ```
48
+
49
+ | Field | Required | Notes |
50
+ |-------|----------|-------|
51
+ | `machine_id` | yes | Stable per-machine UUID. The relay uses this as the device PK. |
52
+ | `agent_id` | yes | Default agent id for dispatch when the dashboard does not pin one. |
53
+ | `platform` | no | `linux` / `darwin` / `win32`. |
54
+ | `hostname` | no | Display only; relay stores on `devices.display_name`. |
55
+ | `agent_version` | no | Display only. |
56
+ | `operator_id` | no | When set, the relay auto-claims ownership on first heartbeat. |
57
+
58
+ #### `heartbeat`
59
+
60
+ Every `heartbeat_interval_s` seconds (default 30).
61
+
62
+ ```json
63
+ {
64
+ "type": "heartbeat",
65
+ "machine_id": "<uuid-v4>",
66
+ "operator_id": "op_<your-operator-id>",
67
+ "system": {
68
+ "cpu_cores": 8,
69
+ "cpu_usage_pct": 12.4,
70
+ "mem_total_mb": 16384,
71
+ "mem_available_mb": 9216,
72
+ "disk_total_gb": 512.0,
73
+ "disk_free_gb": 320.5,
74
+ "load_avg_1m": 0.42,
75
+ "process_count": 312
76
+ }
77
+ }
78
+ ```
79
+
80
+ #### `ack`
81
+
82
+ Acknowledge receipt of a `stream` message from the relay.
83
+
84
+ ```json
85
+ { "type": "ack", "msg_id": "<relay-msg-id>" }
86
+ ```
87
+
88
+ #### `stream` (rare)
89
+
90
+ The TS client sends `stream` messages from the offline buffer drain —
91
+ they have the same shape as relay → client `stream` messages.
92
+
93
+ #### `execute_response` / `agent_list` / `browser_fetch_result`
94
+
95
+ Server-originated RPC responses, forwarded back to the dashboard.
96
+
97
+ ### Server → Client
98
+
99
+ #### `registered`
100
+
101
+ Sent once on successful registration.
102
+
103
+ ```json
104
+ { "type": "registered", "machine_id": "<uuid-v4>", "agent_id": "worker_default" }
105
+ ```
106
+
107
+ If the relay just minted a per-device secret, the next message is
108
+ `device_secret_issued` (one-time).
109
+
110
+ #### `device_secret_issued`
111
+
112
+ ```json
113
+ {
114
+ "type": "device_secret_issued",
115
+ "secret": "<base64-32-bytes>",
116
+ "device_id": "<uuid-v4>"
117
+ }
118
+ ```
119
+
120
+ #### `stream`
121
+
122
+ A message destined for the local agent.
123
+
124
+ ```json
125
+ {
126
+ "type": "stream",
127
+ "msg_id": "<uuid-v4>",
128
+ "machine_id": "<uuid-v4>",
129
+ "agent_id": "worker_default",
130
+ "payload": { "...": "agent-specific JSON" },
131
+ "timestamp": 1721000000000
132
+ }
133
+ ```
134
+
135
+ The TS client forwards `payload` to the local `agent_id` Pi process and
136
+ replies with `ack`.
137
+
138
+ #### `set_config`
139
+
140
+ Live config push from the relay.
141
+
142
+ ```json
143
+ {
144
+ "type": "set_config",
145
+ "heartbeat_interval_s": 30,
146
+ "network_mode": "lan"
147
+ }
148
+ ```
149
+
150
+ #### `execute` / `list_agents` / `get_available_models` / `browser_fetch`
151
+
152
+ RPC commands from the dashboard. The TS client spawns the relevant
153
+ handler and replies via the buffer queue.
154
+
155
+ ---
156
+
157
+ ## `/shell-edge` binary channel
158
+
159
+ After `/edge` registration succeeds, the TS client opens a second
160
+ WebSocket to `/shell-edge`. This channel carries **binary frames** for
161
+ shell sessions — byte-exact with the Rust client.
162
+
163
+ ### Frame layout
164
+
165
+ ```
166
+ +----------------+----------------+----------+----------------+
167
+ | session_id | FrameType | payload_len (u32 BE) | payload |
168
+ | 16 bytes (UUID)| 1 byte | 4 bytes | N bytes |
169
+ +----------------+----------------+----------------------+------------+
170
+ ```
171
+
172
+ Total header size: **17 bytes** (UUID + FrameType + u32 BE length).
173
+
174
+ ### `FrameType` enum
175
+
176
+ | Value | Name | Direction | Payload |
177
+ |-------|------|-----------|---------|
178
+ | 0x00 | `Data` | both | PTY output bytes |
179
+ | 0x01 | `Resize` | client → server | `{ cols: u16 BE, rows: u16 BE }` |
180
+ | 0x02 | `Close` | both | empty (graceful shutdown) |
181
+ | 0x03 | `Ping` | both | empty (heartbeat) |
182
+ | 0x04 | `Pong` | both | empty (heartbeat reply) |
183
+
184
+ The first frame after upgrade MUST carry a `session_id` matching the
185
+ one issued by the relay's `share_token` handshake. A mismatch is a
186
+ fatal protocol error (close code 4403).
187
+
188
+ ---
189
+
190
+ ## Buffer dump encryption
191
+
192
+ When the in-memory queue overflows, the daemon encrypts entries with
193
+ AES-256-GCM and writes them to disk.
194
+
195
+ ### Envelope
196
+
197
+ ```
198
+ +----------------+----------+----------------------------+
199
+ | KEY_VERSION=1 | nonce | ciphertext + GCM tag |
200
+ | 1 byte | 12 bytes | N bytes |
201
+ +----------------+----------+----------------------------+
202
+ ```
203
+
204
+ - **KEY_VERSION**: always `0x01` in v1.x. A future major version may
205
+ introduce `0x02`.
206
+ - **nonce**: 12 random bytes (NEVER reuse with the same key).
207
+ - **key**: 32 bytes (256 bits), configured via `EDGE_BUFFER_KEY` (hex, 64 chars).
208
+ - **tag**: 16 bytes (default GCM tag length).
209
+ - **algorithm**: AES-256-GCM (RFC 5116).
210
+
211
+ Key rotation is supported via `EDGE_BUFFER_KEY_PREVIOUS` — the daemon
212
+ can decrypt entries written with the previous key and re-encrypt with
213
+ the new one on next dump.
214
+
215
+ ---
216
+
217
+ ## TLS pinning
218
+
219
+ When `relay.fingerprint` (or `EDGE_RELAY_FINGERPRINT`) is set, the
220
+ client:
221
+
222
+ 1. Completes the standard TLS handshake against the Mozilla CA bundle.
223
+ 2. Extracts the leaf certificate's `SubjectPublicKeyInfo`.
224
+ 3. Hashes it with SHA-256.
225
+ 4. Compares in constant time against the configured pin.
226
+
227
+ **Extract the pin for a relay cert:**
228
+
229
+ ```bash
230
+ openssl s_client -connect <relay-host>:443 < /dev/null 2>/dev/null \
231
+ | openssl x509 -pubkey -noout \
232
+ | openssl pkey -pubin -outform DER \
233
+ | openssl dgst -sha256 -binary \
234
+ | xxd -p -c 64
235
+ ```
236
+
237
+ > **Cert-renewal-safe.** The pin is over the **public key**, not the
238
+ > full cert — operators do not need to repin on a cert rotation,
239
+ > only on a keypair rotation.
240
+
241
+ ---
242
+
243
+ ## Versioning
244
+
245
+ The wire protocol is versioned implicitly via the `Sec-WebSocket-Protocol`
246
+ identifier (`edgeai-v2`). Future major versions will use `edgeai-v3`,
247
+ etc. The TS client will refuse to connect if the relay advertises an
248
+ unrecognized protocol version.
@@ -0,0 +1,177 @@
1
+ # Troubleshooting
2
+
3
+ A field guide for the most common `edge-ai-client-ts` errors and how
4
+ to fix them.
5
+
6
+ > **Security note:** when filing an issue or asking for support, **never
7
+ > share your `EDGE_AUTH_TOKEN`, `EDGE_BUFFER_KEY`, `EDGE_RELAY_FINGERPRINT`,
8
+ > or operator API key.** Redact everything matching `<secret>=…` in logs
9
+ > before pasting.
10
+
11
+ ---
12
+
13
+ ## Install / `npm install -g` fails
14
+
15
+ ### `EACCES: permission denied`
16
+
17
+ You ran `npm install -g` without sudo. Either:
18
+
19
+ - Re-run with `sudo`:
20
+ ```bash
21
+ sudo npm install -g edge-ai-client-ts
22
+ ```
23
+ - Or fix npm's global prefix (recommended):
24
+ ```bash
25
+ mkdir -p ~/.npm-global
26
+ npm config set prefix '~/.npm-global'
27
+ export PATH="$HOME/.npm-global/bin:$PATH"
28
+ # Persist in ~/.bashrc / ~/.zshrc
29
+ npm install -g edge-ai-client-ts
30
+ ```
31
+
32
+ ### `node-pty` build fails (no prebuilt binary)
33
+
34
+ Most platforms have a prebuilt `.node` artifact. If yours does not:
35
+
36
+ - **Linux**: `apt install build-essential python3` (Debian/Ubuntu) or
37
+ `dnf install gcc-c++ make python3` (Fedora).
38
+ - **macOS**: `xcode-select --install`.
39
+ - **Windows**: install [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools)
40
+ or use the Visual Studio Build Tools.
41
+
42
+ ### `ec-ts: command not found` after install
43
+
44
+ The global `bin` dir is not on `PATH`. Find it with:
45
+
46
+ ```bash
47
+ npm config get prefix
48
+ # Add "$prefix/bin" to PATH.
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Runtime / the daemon won't start
54
+
55
+ ### `WebSocket upgrade rejected (no detail)`
56
+
57
+ The relay rejected the upgrade. Common causes:
58
+
59
+ | Cause | Fix |
60
+ |-------|-----|
61
+ | Missing or wrong `EDGE_AUTH_TOKEN` | Re-export the env var, restart the daemon. |
62
+ | TLS pin mismatch (`relay_fingerprint`) | Re-extract the SPKI hash with the `openssl` one-liner in the upstream docs. |
63
+ | Relay is `wss://` but you configured `ws://` (or vice versa) | Match the scheme; set `EDGEAI_REQUIRE_TLS=1` to force `wss://`. |
64
+ | Operator revoked in the dashboard | Re-enroll with a new key (`ec-ts enroll --key <new-key>`). |
65
+
66
+ ### `EAI_AGAIN` / `ENOTFOUND` (DNS resolution)
67
+
68
+ The relay hostname does not resolve. Check:
69
+
70
+ ```bash
71
+ # Replace "relay.example.com" with your ws_url host
72
+ nslookup relay.example.com
73
+ curl -v https://relay.example.com/health
74
+ ```
75
+
76
+ If you are behind a corporate proxy, set `HTTPS_PROXY` (and `NO_PROXY`
77
+ for the local relay) per Node's conventions.
78
+
79
+ ### `Buffer full: 16777276 bytes would exceed cap of 16777216 bytes`
80
+
81
+ The in-memory queue hit `buffer.max_memory_mb`. Increase it, or speed up
82
+ flushes:
83
+
84
+ ```toml
85
+ [buffer]
86
+ max_memory_mb = 64 # default 50; raise to 128+ on busy nodes
87
+ flush_interval_ms = 50 # default 100; lower for faster drain
88
+ ```
89
+
90
+ Also check that `EDGE_BUFFER_KEY` is set — without it, the daemon cannot
91
+ dump the overflow to encrypted disk and starts dropping entries.
92
+
93
+ ---
94
+
95
+ ## Connection / WS flaps
96
+
97
+ ### Daemon connects, then immediately disconnects
98
+
99
+ Look in the daemon log (`local_log_dir` from config). Two frequent
100
+ patterns:
101
+
102
+ - **`displaced by duplicate machine_id registration`** — another
103
+ daemon (TypeScript or Rust) is already registered with the same
104
+ `machine_id`. Kill the duplicate or set a unique `machine_id` per
105
+ daemon.
106
+ - **`401 Unauthorized`** — fleet shared secret mismatch. Verify
107
+ `EDGE_AUTH_TOKEN` matches the relay's `RELAY_AUTH_TOKEN`.
108
+
109
+ ### `WebSocket protocol error: Handshake not finished`
110
+
111
+ The relay closed the upgrade mid-handshake. Most common cause: an
112
+ intermediating proxy (nginx, Cloudflare Tunnel) is stripping the
113
+ `Sec-WebSocket-Protocol` subprotocol header. The `edgeai-v2` protocol
114
+ identifier carries the auth token, so if the proxy strips it the relay
115
+ sees an unauthenticated request.
116
+
117
+ **Fix (Cloudflare Tunnel):** ensure the tunnel preserves headers. With
118
+ `cloudflared` defaults the `Sec-WebSocket-Protocol` header IS forwarded
119
+ to the upstream; double-check your `config.yml` `originRequest` block.
120
+
121
+ ---
122
+
123
+ ## `ec-ts enroll` problems
124
+
125
+ ### `keychain unavailable` on Linux
126
+
127
+ `ec-ts` requires `libsecret` to store the per-operator API key. Install:
128
+
129
+ ```bash
130
+ sudo apt install libsecret-1-0 libsecret-1-dev # Debian/Ubuntu
131
+ sudo dnf install libsecret libsecret-devel # Fedora
132
+ ```
133
+
134
+ Then make sure a Secret Service provider is running (GNOME Keyring,
135
+ KDE Wallet, KeePassXC with Secret Service integration, etc.).
136
+
137
+ ### `enroll` succeeds but `run` still says "no operator"
138
+
139
+ The keychain item may not be visible to the daemon process. Check:
140
+
141
+ ```bash
142
+ # Linux
143
+ secret-tool search service edge-ai-agent
144
+
145
+ # macOS
146
+ security find-generic-password -s edge-ai-agent
147
+ ```
148
+
149
+ If the item is missing, re-enroll with the same key.
150
+
151
+ ---
152
+
153
+ ## Performance / memory
154
+
155
+ - **`memory_max_mb`** is a SOFT cap. The daemon dumps to disk above it,
156
+ not OOM-kills.
157
+ - **`tasks_max`** caps concurrent sessions + RPCs. Raise it on
158
+ machines running many parallel agents.
159
+ - For long-lived nodes with intermittent connectivity, also raise
160
+ `buffer.max_memory_mb` and `buffer.max_retries`.
161
+
162
+ ---
163
+
164
+ ## Getting more help
165
+
166
+ 1. Run `ec-ts status --once` and capture the output (redact secrets).
167
+ 2. Tail the daemon log (`local_log_dir` from your config).
168
+ 3. File an issue at <https://github.com/baphuongna/edge-ai-agent/issues>
169
+ with:
170
+ - `ec-ts --version` and `node --version`
171
+ - OS / architecture
172
+ - Redacted `ec-ts whoami --verbose` output
173
+ - The relevant daemon log lines
174
+
175
+ The maintainers will not ask for your `EDGE_AUTH_TOKEN` or operator API
176
+ key — if you accidentally paste one, **rotate it immediately** in the
177
+ dashboard.
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "edge-ai-client-ts",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript edge-client for the Edge AI Agent fleet — pure-npm reimplementation of the Rust `ec` binary with byte-compatible wire protocol.",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Edge AI Agent Contributors",
8
+ "url": "https://github.com/baphuongna/edge-ai-agent"
9
+ },
10
+ "homepage": "https://github.com/baphuongna/edge-ai-agent/tree/main/edge-client-ts#readme",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/baphuongna/edge-ai-agent.git",
14
+ "directory": "edge-client-ts"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/baphuongna/edge-ai-agent/issues"
18
+ },
19
+ "keywords": [
20
+ "edge",
21
+ "agent",
22
+ "ai",
23
+ "iot",
24
+ "telemetry",
25
+ "relay",
26
+ "websocket",
27
+ "fleet",
28
+ "daemon",
29
+ "typescript"
30
+ ],
31
+ "bin": {
32
+ "ec-ts": "./bin/ec-ts.js"
33
+ },
34
+ "main": "./dist/index.js",
35
+ "types": "./dist/index.d.ts",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "import": "./dist/index.js"
40
+ }
41
+ },
42
+ "files": [
43
+ "dist/",
44
+ "bin/",
45
+ "LICENSE",
46
+ "README.md",
47
+ "CHANGELOG.md",
48
+ "docs/"
49
+ ],
50
+ "engines": {
51
+ "node": ">=20"
52
+ },
53
+ "publishConfig": {
54
+ "registry": "https://registry.npmjs.org/"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc -p tsconfig.build.json && tsc-alias",
58
+ "typecheck": "tsc --noEmit",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest",
61
+ "lint": "tsc --noEmit",
62
+ "prepublishOnly": "npm run typecheck && npm test && npm run build",
63
+ "smoke:preflight": "node e2e-smoke/preflight.mjs",
64
+ "smoke": "npm run build && npm run smoke:preflight && node e2e-smoke/smoke.mjs"
65
+ },
66
+ "dependencies": {
67
+ "commander": "^12.1.0",
68
+ "node-pty": "^1.0.0",
69
+ "smol-toml": "^1.3.1",
70
+ "ws": "^8.18.0"
71
+ },
72
+ "devDependencies": {
73
+ "@types/node": "^20.14.0",
74
+ "@types/ws": "^8.5.12",
75
+ "tsc-alias": "^1.9.0",
76
+ "typescript": "^5.5.4",
77
+ "vitest": "^2.1.1"
78
+ }
79
+ }