-
Notifications
You must be signed in to change notification settings - Fork 1
Launch Zaparoo CLI v2 #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
ccb9446
Replace MCP server with Zaparoo CLI
wizzomafizzo ea5353f
Add Online User API toolkit
wizzomafizzo cc3b8e9
Harden CLI safety and validation
wizzomafizzo 103a1cb
Harden API audits and lock recovery
wizzomafizzo f424799
Document Online credential behavior
wizzomafizzo 8a6a0af
Harden AI-first CLI and agent workflows
wizzomafizzo 00d703a
Harden CLI validation and failure handling
wizzomafizzo fe1c2ff
Tighten agent safety and capability reporting
wizzomafizzo 5783d72
Refine agent guidance and local planning
wizzomafizzo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../skills |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,5 +3,7 @@ build/ | |
| *.tsbuildinfo | ||
| .env | ||
| .claude/ | ||
| .pi/ | ||
| .mcp.json | ||
| CLAUDE.md | ||
| docs/plans/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,77 +1,74 @@ | ||
| # zaparoo-mcp | ||
| # zaparoo-cli | ||
|
|
||
| MCP server that bridges AI assistants to Zaparoo Core devices (NFC-based game launchers) over WebSocket using JSON-RPC 2.0. | ||
| Remote developer CLI and Agent Skills for exploring Zaparoo APIs, building integrations, and diagnosing Zaparoo Core devices. | ||
|
|
||
| ## Project map | ||
|
|
||
| - `src/cli/` — parser, output/errors, thin command handlers. | ||
| - `src/client/` — bounded one-shot client, endpoint/config/resolution, redacted trace JSONL. | ||
| - `src/crypto/` — PAKE pairing, credential storage, encrypted sessions, Core-derived fixtures. | ||
| - `src/api/` — versioned Core method/notification snapshot and baseline. | ||
| - `src/discovery/` — bounded mDNS discovery for `_zaparoo._tcp`. | ||
| - `src/online/` — public Online User API contract, bounded HTTPS client, pagination, and errors. | ||
| - `skills/` — canonical packaged Agent Skills; `.agents/skills` links here for project discovery. | ||
| - `docs/` — public CLI contracts and developer guidance. | ||
| - `scripts/` — Core API audit plus package/skill release checks. | ||
|
|
||
| For first-party Zaparoo application work, reference the latest development version of [Zaparoo Core](https://github.com/ZaparooProject/zaparoo-core). For third-party integration work, reference the latest stable [public Core API documentation](https://zaparoo.org/docs/core/api/). Use `https://developers.zaparoo.com/openapi-user.yaml` as sole Online User API authority. Treat behavior missing from public documentation as a documentation gap; do not infer a third-party contract from unreleased implementation details. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| npm run build # Build to build/index.js | ||
| npm run dev # Build in watch mode | ||
| npm run lint:fix # Auto-fix lint issues (Biome) | ||
| npm run format # Format code (Biome) | ||
| npm run check # CI lint+format check | ||
| npm test # Run tests (Vitest) | ||
| npm run test:watch # Tests in watch mode | ||
| pnpm run api:audit -- --core ../zaparoo-core | ||
| pnpm run api:user:audit | ||
| pnpm run build | ||
| pnpm run check | ||
| pnpm run lint:fix | ||
| pnpm run format | ||
| pnpm run skills:check | ||
| pnpm test | ||
| pnpm run typecheck | ||
| pnpm run package:smoke | ||
| ``` | ||
|
|
||
| ## Architecture | ||
| Before finishing broad changes, run API audit, check, typecheck, full tests, build, and pack dry-run. | ||
|
|
||
| ### Connection layer (`src/connection/`) | ||
| - `DeviceConnection` — WebSocket client for a single Zaparoo device. Handles JSON-RPC request/response correlation, automatic reconnection with exponential backoff, and heartbeat pings. | ||
| - `DeviceManager` — orchestrates multiple connections. `getDevice(id?)` returns a specific device or the first READY one. Supports dynamic `addDevice()`/`removeDevice()` for mDNS discovery. | ||
| ## CLI rules | ||
|
|
||
| ### Discovery (`src/discovery/`) | ||
| - `MdnsDiscovery` — browses for `_zaparoo._tcp` services via mDNS using `bonjour-service`. Emits `discovered`/`removed` events. Runs automatically when no devices are manually configured. | ||
| - Package identity is `@zaparoo/cli`; packaged installs expose `zaparoo-cli`. | ||
| - In source checkout, build then use `node build/index.js ...`; do not assume global CLI exists. | ||
| - One-shot machine output uses `--json`; watch streams use `--jsonl`. | ||
| - Errors go to stderr with non-zero exit codes. | ||
| - Core commands open bounded WebSocket sessions, perform calls, then close. Backup operations use unbounded method policy. | ||
| - Online commands use fixed official HTTPS origin, reject redirects, and send bearer keys only to `/v1` requests. | ||
| - Credentials default to `~/.config/zaparoo-cli/credentials.json`, remain versioned/atomic/mode `0600`, and never appear in output or traces. | ||
| - `src/api/methods.ts` mirrors registered Core methods. Keep `rpc` as debug escape hatch; do not promote unregistered `run.script`. | ||
| - Public integration guidance must use public API docs. Treat missing public behavior as a documentation gap, not a reason to inspect private implementation. | ||
|
|
||
| ### Tools (`src/tools/`) | ||
| Each file registers one MCP tool via `registerXxxTool(server, manager)`. All tools are wired up in `src/tools/index.ts` through `registerAllTools()`. | ||
| ## Adding commands | ||
|
|
||
| ### Resources (`src/resources/`) | ||
| - `zaparoo://devices` — all device states | ||
| - `zaparoo://{deviceId}/state` — per-device state (readers, media, tokens) | ||
| - `zaparoo://reference/zapscript` — ZapScript language reference | ||
| 1. Add thin handler under `src/cli/commands/`. | ||
| 2. Use `withClient()` from `src/cli/commands/common.ts`. | ||
| 3. Return plain data; let `src/cli/output.ts` render it. | ||
| 4. Validate required params and add colocated tests for non-trivial mapping. | ||
| 5. Decode binary API payloads through atomic owner-only output files. | ||
|
|
||
| ### Notifications (`src/notifications/`) | ||
| `NotificationHandler` listens for device events, updates `DeviceStateStore` (in-memory cache), and pushes MCP resource change notifications. | ||
| ## Skills and artifacts | ||
|
|
||
| ### Config (`src/config.ts`) | ||
| CLI args take precedence over env vars. Optional: `--devices`/`ZAPAROO_DEVICES`, `--keys`/`ZAPAROO_KEYS`. Default port is 7497. When no devices are configured, mDNS discovery is enabled automatically. Use `--no-discovery` or `ZAPAROO_NO_DISCOVERY=1` to disable. Tool filtering: `--allowed-tools`/`ZAPAROO_ALLOWED_TOOLS` (comma-separated whitelist) or `--blocked-tools`/`ZAPAROO_BLOCKED_TOOLS` (comma-separated blacklist). Cannot use both simultaneously. | ||
| - Skills must work from npm/Pi package and standalone `npx skills` install; no hardcoded checkout paths in `skills/`. | ||
| - Standalone skills may not include `build/`; check before using package-relative fallback. | ||
| - Offline log/database retrieval is guidance in `skills/zaparoo-artifacts/`, not product code. | ||
| - Do not add CLI SSH, PowerShell, filesystem scouting, process probing, Core stop/restart, or artifact collector logic. | ||
| - Agents choose user-authorized transport/commands. Live SQLite copies are always potentially inconsistent; include present WAL/SHM/journal sidecars. | ||
|
|
||
| ## Adding a new tool | ||
| ## Live-device safety | ||
|
|
||
| 1. Create `src/tools/mytool.ts` with a `registerMyTool(server, manager)` function | ||
| 2. Define input schema with Zod, use `toolRequest()` from `src/tools/helpers.ts` to call the device | ||
| 3. Add an entry to the `registry` array in `src/tools/index.ts` inside `registerAllTools()` | ||
| Ask before launching/stopping media, input, NFC writes, mapping/settings/profile changes, update apply, inbox clear, or downtime. Never automatically stop or restart Core. Pairing initiation is Core-side/localhost-only; completion uses client PAKE PIN flow. | ||
|
|
||
| ## Testing | ||
|
|
||
| Tests use Vitest and live alongside source files as `*.test.ts`. Test files are excluded from `tsconfig.json` compilation so they don't end up in build output. | ||
|
|
||
| **What to test:** Focus on modules with real logic — parsing, state management, error handling, branching. Don't write tests that just assert tool registration boilerplate or static content. | ||
|
|
||
| **Mocking patterns:** | ||
| - Mock `ws` module with a `MockWebSocket` class extending `EventEmitter` for `DeviceConnection` tests. Use `vi.useFakeTimers()` for timeout/backoff tests. | ||
| - Mock `DeviceConnection` import via `vi.mock()` for `DeviceManager` tests, tracking created instances in an array. | ||
| - Mock `node:util` `parseArgs` for config tests to control CLI arg values. | ||
| - Mock `bonjour-service` with a mock class returning `EventEmitter`-based browsers for `MdnsDiscovery` tests. | ||
| - Use `as unknown as <Type>` double-cast for partial mocks of complex interfaces (DeviceManager, MCP Server). | ||
| - Reset module-level mock state (e.g., `lastMockWs`, `createdDevices`) in `beforeEach`. | ||
|
|
||
| **Test guidelines:** | ||
| - Test files MUST be colocated with source: `src/foo.ts` → `src/foo.test.ts` | ||
| - Prefer testing through public interfaces over reaching into private methods | ||
| - Every test that uses fake timers MUST call `vi.useRealTimers()` in `afterEach` | ||
| - Don't write tests that give false confidence — if an assertion can't actually fail when the code is broken, remove it | ||
|
|
||
| ## Conventions | ||
|
|
||
| - Tool names MUST be prefixed with `zaparoo_` | ||
| - Resource URIs MUST use the `zaparoo://` scheme | ||
| - All tool inputs MUST be validated with Zod schemas | ||
| - Use `import type` for type-only imports — Biome enforces this (`useImportType`) | ||
| - Zod is imported from `zod/v3` (Zod v4 package, v3-compatible API) | ||
| - Error responses from tools MUST use the `{ isError: true }` pattern (see `src/tools/helpers.ts`) | ||
| - Device IDs use `host:port` format | ||
| - NEVER use CommonJS (`require`/`module.exports`) — this is an ESM-only project | ||
| - PR descriptions MUST NOT include test plans — keep them to a summary only | ||
| - NEVER amend commits — always create new commits | ||
| - Tests use Vitest beside source as `*.test.ts`. | ||
| - Mock WebSocket with EventEmitter-based `ws` doubles where practical. | ||
| - Every fake-timer test restores real timers in `afterEach`. | ||
| - Online tests mock fetch and never use real API keys. | ||
| - Live pairing, Online account, SSH, and stopped-database acceptance require designated targets and explicit approval; report skipped checks. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.