@ctrlpi/ctrlpi-lab 0.9.25 → 0.9.26

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # ctrlPi Lab
2
2
 
3
3
  [![Platform: Cross-Platform](https://img.shields.io/badge/platform-Cross--Platform-006400.svg)](#quick-start)
4
- [![Version 0.9.25](https://img.shields.io/badge/version-0.9.25-blue.svg)](https://github.com/ctrlpi/ctrlpi-lab/tags)
4
+ [![Version 0.9.26](https://img.shields.io/badge/version-0.9.26-blue.svg)](https://github.com/ctrlpi/ctrlpi-lab/tags)
5
5
  [![Node.js 20+](https://img.shields.io/badge/node.js-20%2B-blue.svg)](https://nodejs.org/)
6
6
  [![Auth: Api-Key](https://img.shields.io/badge/auth-Api--Key-orange.svg)](#usage)
7
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-188038.svg)](LICENSE)
@@ -12,7 +12,7 @@ A local browser dashboard for your ctrlPi setup. Test GPIO and sensor endpoints,
12
12
  watch webhook events, and tail agent logs, with zero dependencies.
13
13
 
14
14
  Runs on **macOS, Linux, and Windows** with **Node.js 20+**. The dashboard connects
15
- to an agent’s REST API; install `pi-gpio-api` or `pico-gpio-api` on your board separately.
15
+ to an agent’s REST API; install `pi-gpio-api`, `pico-gpio-api`, or `esp32-gpio-api` on your board separately.
16
16
 
17
17
  ## Quick start
18
18
 
@@ -24,7 +24,7 @@ npx @ctrlpi/ctrlpi-lab
24
24
 
25
25
  Your browser will open automatically at [http://localhost:7474](http://localhost:7474).
26
26
 
27
- Or clone and run directly (no `npm install` needed):
27
+ Or run directly from source without installing dependencies:
28
28
 
29
29
  ```bash
30
30
  git clone https://github.com/ctrlpi/ctrlpi-lab.git
@@ -32,34 +32,8 @@ cd ctrlpi-lab
32
32
  node ctrlpi-lab.js
33
33
  ```
34
34
 
35
- You can also start it with `npm start`. Python is needed only for the mock-agent tests.
36
- By default, the dashboard listens only on this computer (`127.0.0.1`). To allow LAN
37
- devices to connect, start it with `--host 0.0.0.0`:
38
-
39
- ```bash
40
- npx @ctrlpi/ctrlpi-lab --host 0.0.0.0
41
- ```
42
-
43
- LAN access also exposes the dashboard’s agent credentials and unrestricted proxy to those devices.
44
-
45
- To skip opening a browser:
46
-
47
- ```bash
48
- npx @ctrlpi/ctrlpi-lab --no-open
49
- ```
50
-
51
- To change the port on macOS/Linux:
52
-
53
- ```bash
54
- PORT=9000 npx @ctrlpi/ctrlpi-lab
55
- ```
56
-
57
- Or in Windows PowerShell:
58
-
59
- ```powershell
60
- $env:PORT = "9000"
61
- npx @ctrlpi/ctrlpi-lab
62
- ```
35
+ By default, the dashboard listens only on the local computer (`127.0.0.1`). To allow LAN
36
+ devices to connect, pass `--host 0.0.0.0` (LAN access exposes the dashboard’s agent credentials and unrestricted proxy to those devices). Use `--no-open` to skip opening a browser, or `PORT=9000` to select a different port.
63
37
 
64
38
  ## Discovery
65
39
 
@@ -80,7 +54,7 @@ and verifies a supplied key through the backend proxy before saving.
80
54
  3. Open **Logs** to search the agent’s output, or **Webhooks** to inspect the public
81
55
  ctrlpi.com test feed when that target is configured on your agent.
82
56
 
83
- The **Welcome to ctrlPi** panel includes Pi and Pico installation steps.
57
+ The **Welcome to ctrlPi** panel includes Pi, Pico, and ESP32 installation steps.
84
58
  **API - cURL Examples** provides nine commands using your selected address and key.
85
59
 
86
60
  ### Examples
@@ -101,22 +75,24 @@ bridge target is configured; otherwise, the agent logs the events.
101
75
 
102
76
  ## Configuration
103
77
 
104
- Saved agents are stored in the shared `config.json`'s `agents[]` (`{name, ip, port, api_key}`), the
78
+ Saved agents are stored in the shared `agents-config.json`'s `agents[]` (`{name, ip, port, api_key, updated_at}`), the
105
79
  one list every ctrlpi project reads - add an agent here and `mcp-bridge`, `studio-bridge` and the
106
80
  smart-home bridges all see it. This dashboard's own `lab-config.json` holds the rest: the agent it
107
81
  is currently pointed at (`selected_agent: {ip, port}`, its key coming from that agent's `agents[]`
108
- entry), the MCP server (`mcp: {ip, port, api_key}`), and `online_agents` (what the last network scan
82
+ entry) and `online_agents` (what the last network scan
109
83
  reached, retained as scan history; saved agents remain selectable), as `ip:port` strings. Every host uses the same
110
- `ip` + `port` pair, never a URL, and `mcp-bridge`'s own key is `mcp.api_key`, so no two keys mean
111
- the same thing.
84
+ `ip` + `port` pair, never a URL.
112
85
 
113
86
  > **Where the config lives:** in `~/.ctrlpi/`, always - never next to `ctrlpi-lab.js`, whatever way you
114
- > started it. Two files: the shared **`~/.ctrlpi/config.json`** holds `agents[]` (every ctrlpi project
87
+ > started it. Two files: the shared **`~/.ctrlpi/agents-config.json`** holds `agents[]` (every ctrlpi project
115
88
  > reads and updates that one list), and **`~/.ctrlpi/lab-config.json`** holds what only this dashboard
116
- > owns (`selected_agent`, the `mcp` section, `online_agents`). Pass `--config <path>` (a `.json` file,
89
+ > owns (`selected_agent`, `online_agents`). Pass `--config <path>` (a `.json` file,
117
90
  > or a directory to hold both) to put them anywhere else.
91
+ >
92
+ > When reading the shared agents, ctrlpi-lab also checks if `/var/lib/homebridge/ctrlpi-agents-config.json`
93
+ > exists; if so, it reads it (read-only) and reconciles agents whose `updated_at` is newer. It never writes to the Homebridge config file.
118
94
 
119
- Both files are optional. For example, the shared `~/.ctrlpi/config.json` can contain:
95
+ Both files are optional. For example, the shared `~/.ctrlpi/agents-config.json` can contain:
120
96
 
121
97
  ```json
122
98
  {
@@ -135,21 +111,18 @@ The dashboard’s `~/.ctrlpi/lab-config.json` stores its selected agent and scan
135
111
  }
136
112
  ```
137
113
 
138
- The backend also preserves optional MCP settings as
139
- `mcp: {ip, port, api_key}` for compatibility; the current dashboard has no MCP tab
140
- or registered stdio MCP routes. Use `mcp-bridge` separately for MCP tools.
141
-
142
114
  - The header shows the selected agent’s IP and port after its model. Use the arrow to choose a saved agent,
143
115
  or the **+** button to add an IP/hostname, port, and API key. The key icon edits the selected agent’s key.
144
- - Environment overrides: `API_KEY` (agent key), `MCP_API_KEY` (MCP HTTP key).
145
- - Discovered and last-used agents are saved back to the shared `~/.ctrlpi/config.json` automatically,
116
+ - Environment override: `API_KEY` sets the agent key.
117
+ - Discovered and last-used agents are saved back to the shared `~/.ctrlpi/agents-config.json` automatically,
146
118
  so you don't have to edit it by hand.
147
119
 
148
120
  ## Tabs
149
121
 
150
- - **API**: test GPIO, sensor, and configuration endpoints. The sidebar includes board pinouts,
151
- **Welcome to ctrlPi** with Pi/Pico installation instructions, and nine **API - cURL Examples**
152
- aligned with the Pi API README and populated with the selected address/key. Changing the
122
+ - **API**: test GPIO, sensor, and configuration endpoints. The sidebar's Get Started section has
123
+ **Welcome to ctrlPi** with Pi, Pico and ESP32 installation steps, nine **API - cURL Examples**
124
+ aligned with the Pi API README and populated with the selected address/key, and a **Pinouts**
125
+ link to the board pinouts on ctrlpi.com. Changing the
153
126
  agent’s API key is available only in the red Danger Zone of Config Update.
154
127
  - **Logs**: compact log viewer with text search. Webhook tags are orange.
155
128
  Red trash and refresh icons sit immediately after the search box. Reset Log
@@ -164,69 +137,56 @@ status indicator, and network scan button.
164
137
 
165
138
  ## How it works
166
139
 
167
- Agent requests, including the + form’s health/key checks, pass through
168
- `/api/proxy/url` using `piApiFetch`, avoiding browser CORS restrictions. The backend uses
169
- Node’s built-in `http` and `fetch`, assembles HTML from `pages/`, and caches it in memory.
170
- The Logs tab fetches the selected agent’s `/logs` through that proxy and filters in the browser;
171
- `/api/logs` remains available as a separate backend helper. Webhook feed requests also use the proxy.
172
-
173
- After editing HTML, restart the server and refresh the browser. In development mode
174
- (`npm run dev`), the header’s **Reload page cache** icon rebuilds the cache and reloads the page.
175
- The day/night toggle only changes the theme; it does not rebuild the cache.
176
-
177
- ### Backend endpoints
178
-
179
- | Method | Path | Description |
180
- |--------|------|-------------|
181
- | `GET` | `/` | The dashboard HTML (assembled from `pages/` and cached in memory) |
182
- | `GET` | `/api/default-config` | Connection defaults plus `local_network_prefix` and `dev_mode` |
183
- | `POST` | `/api/save-config` | Saves `api_host` / `api_port` and/or the `mcp` section to `lab-config.json` |
184
- | `GET` · `POST` | `/api/servers` | List / add saved agents (kept in the shared `config.json`) |
185
- | `GET` | `/api/scan?port=` | Scans the local subnet via `/hello`; port defaults to 8314. Add `stream=1` for incremental NDJSON results |
186
- | `GET` | `/api/logs` | Proxies the agent's `GET /logs`; supports `?limit=`, `?search=`, `?category=` |
187
- | `*` | `/api/proxy/url?url=` | General HTTP proxy for the browser's GPIO / MCP-HTTP calls (also relays the `Mcp-Session-Id` header) |
188
- | `POST` | `/api/reload-cache` | Rebuilds cached dashboard HTML from disk |
189
- | `GET` | `/images/{file}` · `/pages/{file}` | Serves image and page files |
140
+ The dashboard runs on Node's built-in HTTP server with zero runtime dependencies. Browser
141
+ requests to agents pass through `/api/proxy/url` using `piApiFetch`, avoiding CORS restrictions.
142
+ HTML assets in `pages/` are assembled and cached in memory. In development mode (`npm run dev`),
143
+ the header’s **Reload page cache** icon rebuilds the cache and reloads the page.
144
+
145
+ The dashboard answers only requests addressed to an IP address, `localhost`, this computer's
146
+ own name (or `<name>.local`) or the `--host` value, and only from its own page. A website you
147
+ visit cannot read your agent keys or reach your agents through it.
190
148
 
191
149
  ## Tests and CI
192
150
 
193
- Requires Node 20+ and Python 3 (`python3`, or set `PYTHON` to its executable).
151
+ Requires Node 20+ and Python 3 (`python3`, or set `PYTHON` to its executable). Python is needed only for the mock-agent tests.
194
152
 
195
153
  ```bash
196
154
  npm test # unit tests + mock-agent HTTP integration tests
197
- npm run test:ci # CI entry point; runs the same tests
198
155
  ```
199
156
 
200
157
  Integration tests launch the real lab server and a local copy of
201
158
  `ctrlpi-cli/mock_agent.py` on OS-assigned loopback ports. They use a temporary
202
159
  `--config` directory, preserve unrelated shared-config fields, and stop child
203
160
  processes and delete temporary configs after each run. No Pi, Pico, public webhook
204
- service, real credentials, or user configuration is needed. The fixture differs
205
- from the CLI copy only in its header and reporting the actual allocated port.
161
+ service, real credentials, or user configuration is needed. The fixture is the same
162
+ `mock_agent.py` the other ctrlPi projects test against.
206
163
 
207
164
  The lab supports `--no-open` to skip opening a browser and `--no-startup-scan`
208
- to skip automatic discovery. Tests use both, plus `HOST=127.0.0.1` and `PORT=0`;
209
- normal startup still opens the browser and discovers agents as before.
165
+ to skip automatic discovery. Tests use both, plus `HOST=127.0.0.1` and `PORT=0`.
210
166
 
211
167
  No npm installation is needed for the app or tests. CI runs all nine combinations
212
168
  of Node 22, 24, and 26 with macOS, Linux (Ubuntu), and Windows. Each job starts the
213
169
  real lab server and the mock agent. There is no coverage reporting or coverage gate.
214
170
 
215
171
  Tests cover agent discovery/selection, adding agents, credentials, real proxy
216
- requests, GPIO write/read state, sensors, configuration persistence, logs, and
217
- webhook rendering. Dashboard tests use a small DOM stub, not a browser. Hardware
218
- timing/electrical behavior, real LAN discovery, external webhook delivery, MCP
219
- bridge interoperability, and visual layout remain outside this suite. The mock
172
+ requests, the Host and Origin check, GPIO write/read state and form values, sensors,
173
+ configuration persistence, logs, and webhook rendering. Dashboard tests use a small DOM stub, not a browser. Hardware
174
+ timing/electrical behavior, real LAN discovery, external webhook delivery, and visual
175
+ layout remain outside this suite. The mock
220
176
  agent approximates the REST contract; it does not replace tests on real hardware.
221
177
 
222
178
  ## Related projects
223
179
 
224
180
  - **[`pi-gpio-api`](https://github.com/ctrlpi/pi-gpio-api)**: Raspberry Pi GPIO REST server that reads inputs and drives outputs (and named sensors) over an HTTP API.
225
181
  - **[`pico-gpio-api`](https://github.com/ctrlpi/pico-gpio-api)**: Raspberry Pi Pico W port of the GPIO REST server, with the same endpoints, wire format, and auth.
226
- - **[`ctrlpi-cli`](https://github.com/ctrlpi/ctrlpi-cli)**: Command-line interface to the same agents, with shared agent configuration.
227
- - **`mcp-bridge`**: MCP server that exposes GPIO control as tools for AI agents (e.g. Claude), executing them over the agents' REST API.
228
- - **`homekit-bridge`**: native Apple HomeKit bridge that exposes GPIO pins and sensors as HomeKit accessories, driven over the agents' REST API.
229
- - **`matter-bridge`**: Matter bridge that exposes GPIO pins and sensors to any Matter platform (Apple Home, Google Home, Alexa, Home Assistant), driven over the agents' REST API.
182
+ - **[`esp32-gpio-api`](https://github.com/ctrlpi/esp32-gpio-api)**: ESP32 port of the GPIO REST server for MicroPython, with the same endpoints, wire format, and auth.
183
+ - **[`mcp-bridge`](https://github.com/ctrlpi/mcp-bridge)**: MCP server that exposes GPIO control as tools for AI agents (e.g. Claude), executing them over the agents' REST API.
184
+ - **[`homebridge-ctrlpi`](https://github.com/ctrlpi/homebridge-ctrlpi)**: A Homebridge plugin that brings Raspberry Pi, Pico W, and ESP32 GPIO into Apple Home, by driving one or more GPIO agents over their REST API.
185
+ - **`homekit-bridge`** *(coming soon)*: Native Apple HomeKit bridge that exposes GPIO pins and sensors as HomeKit accessories, driven over the agents' REST API.
186
+ - **`matter-bridge`** *(coming soon)*: Matter bridge that exposes GPIO pins and sensors to any Matter platform (Apple Home, Google Home, Alexa, Home Assistant), driven over the agents' REST API.
187
+ - **[`ctrlpi-cli`](https://github.com/ctrlpi/ctrlpi-cli)**: Command-line interface for interacting with ctrlPi agents, with shared agent configuration.
188
+ - **[`pico-bay`](https://github.com/ctrlpi/pico-bay)**: Web app and MCP server for managing MicroPython and CircuitPython boards, such as the Raspberry Pi Pico and ESP32, over USB.
189
+ - **`pi-bay`** *(coming soon)*: A local web app and MCP server for Raspberry Pi boards over the network. Edit files, open a remote terminal, and manage your Pi remotely.
230
190
 
231
191
  ## License
232
192