feat(docker): add dev.sh with auto-funding and ATM app setup

- Add dev.sh script for managing regtest development environment
- Implement cmd_fund to fund ATM app owner via Lightning.Pub API
- Add --fund flag to cmd_up for automatic funding on startup
- Update setup_atm_app to write VITE_APP_ID to machine .env
- Fix Electron IPC to pass appId and extensionApiUrl to renderer
- Restructure repo from nested lamassu-next/ to root

The dev.sh script now supports:
- ./dev.sh up --fund  # Start regtest and auto-fund ATM
- ./dev.sh fund       # Fund existing ATM app
- ./dev.sh status     # Show environment status
- ./dev.sh reset      # Clean restart

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-02-15 14:19:16 -05:00
commit c98f126ba7
180 changed files with 2695 additions and 9587 deletions

218
.claude/skills/docs.md Normal file
View file

@ -0,0 +1,218 @@
# /docs - Documentation Agent
## Purpose
Keep documentation synchronized with code, generate API docs, and maintain architecture diagrams.
## Invocation
```
/docs [command] [target]
```
Commands:
- `sync` - Sync docs with code changes
- `api` - Generate API documentation
- `diagram` - Update architecture diagrams
- `readme` - Update package README
- `changelog` - Generate changelog entry
## Documentation Structure
```
docs/
├── architecture/
│ ├── overview.md # High-level architecture
│ ├── nostr-protocol.md # Nostr integration details
│ ├── lightning-flow.md # Payment flows
│ └── hardware-hal.md # HAL documentation
├── api/
│ ├── nostr-client.md # @lamassu/nostr-client API
│ ├── clink.md # @lamassu/clink API
│ ├── state-machine.md # @lamassu/state-machine API
│ └── hal.md # @lamassu/hal API
├── guides/
│ ├── development.md # Dev setup guide
│ ├── hardware-testing.md # Testing with real hardware
│ └── deployment.md # NixOS deployment guide
└── adrs/ # Architecture Decision Records
├── 001-nostr-backbone.md
├── 002-clink-over-bolt12.md
└── ...
```
## Sync Tasks
### Code → Docs Sync
When code changes:
1. Detect modified files
2. Check if related docs exist
3. Flag outdated documentation
4. Suggest updates
### Doc → Code Validation
Ensure docs reference actual code:
- [ ] Function names match
- [ ] Parameter types correct
- [ ] Return types accurate
- [ ] Examples compile/run
## API Documentation
### TypeScript Packages
Generate from TSDoc comments:
```typescript
/**
* Create a CLINK offer for receiving payments
*
* @param identity - Machine identity (nsec/npub)
* @param relays - Relay URLs to include in offer
* @param priceType - 'fixed' | 'variable' | 'spontaneous'
* @param amount - Amount in sats (required for fixed)
* @returns Encoded noffer string
*
* @example
* ```typescript
* const offer = createOffer(identity, ['wss://relay.example'], 'fixed', 10000)
* // Returns: noffer1...
* ```
*/
export function createOffer(...): string
```
### Rust Crate (HAL)
Generate from rustdoc comments:
```rust
/// Connect to a bill validator
///
/// # Arguments
/// * `port` - Serial port path (e.g., "/dev/ttyUSB0")
///
/// # Errors
/// Returns `ValidatorError::ConnectionFailed` if port unavailable
///
/// # Example
/// ```
/// let mut validator = Id003Validator::new("/dev/ttyUSB0", "USD");
/// validator.connect().await?;
/// ```
pub async fn connect(&mut self) -> Result<(), ValidatorError>
```
## Diagram Updates
### Mermaid Diagrams
Keep architecture diagrams current:
```mermaid
sequenceDiagram
participant U as User
participant A as ATM
participant R as Relay
participant L as Lightning.Pub
U->>A: Insert $20 bill
A->>A: Validate bill
A->>R: Publish CLINK offer
U->>R: Send payment request
R->>A: Forward request
A->>L: Generate invoice
L->>A: Return invoice
A->>R: Send invoice to user
U->>L: Pay invoice
L->>A: Payment confirmed
A->>U: Display success
```
### Auto-update triggers
- New event kinds added → Update protocol diagram
- State machine changes → Update flow diagram
- New hardware driver → Update HAL diagram
## Changelog Generation
### Format (Keep a Changelog)
```markdown
## [Unreleased]
### Added
- CLINK offer support for cash-in flow
- Puloon dispenser driver
### Changed
- Upgraded to XState v5 actor model
### Fixed
- Race condition in bill acceptance
### Security
- Added NIP-44 encryption for receipts
```
### Auto-detection
From git commits since last release:
- `feat:` → Added
- `fix:` → Fixed
- `refactor:` → Changed
- `security:` → Security
- `BREAKING:` → Breaking Changes
## Output Format
### Sync Report
```markdown
## Documentation Sync: [target]
### Outdated Docs
| Doc | Code Change | Status |
|-----|-------------|--------|
| api/clink.md | createOffer params | ⚠️ Outdated |
| guides/development.md | New env var | ⚠️ Missing |
### Suggested Updates
1. `api/clink.md:45` - Add `timeout` parameter to createOffer
2. `guides/development.md` - Add LIGHTNING_PUB_URL env var
### Missing Documentation
- `packages/cashu/src/wallet.ts` - No API docs
```
### Generated Docs
```markdown
## Generated: [file]
### API Reference
#### `createOffer(identity, relays, priceType, amount?)`
Creates a CLINK offer for receiving Lightning payments.
**Parameters:**
| Name | Type | Description |
|------|------|-------------|
| identity | MachineIdentity | Machine nsec/npub |
| relays | string[] | Relay URLs |
| priceType | 'fixed' \| 'variable' | Pricing model |
| amount | number? | Amount in sats |
**Returns:** `string` - Encoded noffer
**Example:**
```typescript
const offer = createOffer(identity, ['wss://relay'], 'fixed', 10000)
```
```
## Example Usage
```
/docs sync packages/clink/
```
```
/docs api packages/nostr-client/src/
```
```
/docs changelog --since v0.1.0
```

200
.claude/skills/hal-check.md Normal file
View file

@ -0,0 +1,200 @@
# /hal-check - Hardware Abstraction Layer Agent
## Purpose
Validate HAL driver implementations against existing lamassu-machine drivers and hardware specifications.
## Invocation
```
/hal-check [command] [driver]
```
Commands:
- `port` - Validate porting from lamassu-machine
- `protocol` - Check protocol implementation
- `safety` - Rust safety review
- `mock` - Validate mock implementation
Drivers:
- `id003`, `ccnet`, `cashflow`, `bnr`, `genmega`, `hcm2`, `gsr50` (validators)
- `puloon`, `f56`, `genmega`, `hcm2`, `gsr50` (dispensers)
- `nippon`, `zebra`, `genmega` (printers)
## Porting Validation
### Source Reference
Each Rust driver should map 1:1 with lamassu-machine JavaScript:
| Rust File | JavaScript Source |
|-----------|-------------------|
| `validators/id003.rs` | `lib/id003/*.js` |
| `validators/ccnet.rs` | `lib/ccnet/*.js` |
| `dispensers/puloon.rs` | `lib/puloon/*.js` |
| `dispensers/f56.rs` | `lib/f56/*.js` |
### Porting Checklist
```
/hal-check port id003
```
Validates:
- [ ] All protocol commands implemented
- [ ] State machine matches JS FSM
- [ ] CRC/checksum calculation identical
- [ ] Timeout values match
- [ ] Error codes mapped correctly
- [ ] Denomination tables match
### Protocol Commands
#### ID003 (JCM)
| Command | Code | JS Reference |
|---------|------|--------------|
| RESET | 0x40 | id003.js:reset() |
| ENABLE | 0x13 | id003fsm.js:enable |
| DISABLE | 0x14 | id003fsm.js:disable |
| STACK | 0x15 | id003fsm.js:stack |
| RETURN | 0x16 | id003fsm.js:return |
| STATUS | 0x10 | id003fsm.js:poll |
#### Puloon
| Command | Code | JS Reference |
|---------|------|--------------|
| RESET | 0x44 | puloonrs232.js |
| DISPENSE | 0x45 | puloonrs232.js |
| STATUS | 0x46 | puloonrs232.js |
## Safety Review (Rust-specific)
### Memory Safety
- [ ] No `unsafe` without justification comment
- [ ] Buffer sizes validated before read/write
- [ ] No panic paths in production code
- [ ] Proper error propagation with Result
### Concurrency Safety
- [ ] Serial port access properly synchronized
- [ ] Event channels bounded
- [ ] No deadlock potential
- [ ] Timeout on all blocking operations
### Hardware Safety
- [ ] Dispenser amounts validated (prevent over-dispense)
- [ ] Bill count cross-checked
- [ ] Error states trigger hardware reset
- [ ] Graceful degradation on hardware failure
## Mock Validation
### Mock Requirements
Mocks must simulate:
1. Normal operation flow
2. Error conditions
3. Timing (realistic delays)
4. State persistence
### Mock Test Coverage
```
/hal-check mock puloon
```
Validates mock implements:
- [ ] `connect()` - Success and failure paths
- [ ] `dispense()` - Full and partial dispense
- [ ] `reset()` - Error recovery
- [ ] Event emission timing
- [ ] Cassette state tracking
## Protocol Analysis
### Packet Structure Validation
```
/hal-check protocol id003
```
Compares Rust packet building with JS:
```rust
// Rust implementation
fn build_packet(&self, data: &[u8]) -> Vec<u8> {
let mut packet = vec![0x02]; // SYNC
packet.push(data.len() as u8 + 4);
packet.extend_from_slice(data);
let crc = self.calculate_crc(&packet);
packet.push((crc & 0xFF) as u8);
packet.push((crc >> 8) as u8);
packet
}
```
Against JavaScript:
```javascript
// lamassu-machine/lib/id003/id003rs232.js
function buildPacket(data) {
const buf = Buffer.alloc(data.length + 4)
buf[0] = 0x02 // SYNC
buf[1] = data.length + 4
data.copy(buf, 2)
const crc = calculateCrc(buf.slice(0, -2))
buf.writeUInt16LE(crc, buf.length - 2)
return buf
}
```
## Output Format
### Port Validation
```markdown
## HAL Port Validation: id003
### Command Coverage
| Command | JS | Rust | Match |
|---------|-------|------|-------|
| RESET | ✅ | ✅ | ✅ |
| ENABLE | ✅ | ✅ | ✅ |
| STATUS | ✅ | ⚠️ | Partial |
### Protocol Differences
- [ ] `id003.rs:78` - CRC uses different polynomial than JS
### Missing Implementations
- [ ] `HOLD` command not implemented (used in id003fsm.js:holdBill)
### Recommendations
1. Verify CRC calculation against test vectors from JS
2. Add HOLD command for escrow mode
```
### Safety Review
```markdown
## HAL Safety Review: puloon
### Memory Safety
- [x] No unsafe blocks
- [x] Buffer bounds checked
- [ ] `dispense()` at line 145 - unwrap() could panic
### Concurrency Safety
- [x] Serial port mutex protected
- [x] Event channel bounded (16)
### Hardware Safety
- [x] Amount validation in dispense()
- [ ] No cassette empty check before dispense
### Critical Issues
1. `puloon.rs:145` - Replace unwrap() with proper error handling
2. `puloon.rs:178` - Add cassette level check before dispensing
```
## Example Usage
```
/hal-check port id003
```
```
/hal-check safety packages/hal/src/dispensers/
```
```
/hal-check mock --all
```

View file

@ -0,0 +1,168 @@
# /lightning-check - Lightning.Pub Conformity Agent
## Purpose
Validate Lightning.Pub integration and CLINK protocol conformity.
## Invocation
```
/lightning-check [target] [--clink] [--wallet]
```
Where:
- `target` - File or directory to check
- `--clink` - Focus on CLINK offer/debit flow
- `--wallet` - Focus on wallet operations
## Lightning.Pub Integration
### Connection
Lightning.Pub uses Nostr for all communication:
```typescript
// Connection via nprofile
const nprofile = 'nprofile1...' // Contains pubkey + relay hints
// All operations are Nostr events to Lightning.Pub's pubkey
await relay.publish({
kind: 21002, // CLINK debit
content: encrypted_request,
tags: [['p', lightningPubPubkey]],
})
```
### Required Checks
- [ ] Using correct event kinds (21001, 21002, 21003)
- [ ] Proper NIP-44 encryption for requests
- [ ] Handling async responses via subscription
- [ ] Proper error handling for payment failures
## CLINK Protocol
### Offer Flow (Kind 21001)
```
User scans noffer → Wallet sends 21002 → ATM responds with invoice → User pays
```
Validation:
- [ ] noffer encoding is valid
- [ ] Relays included in offer
- [ ] Price type correctly specified (fixed/variable/spontaneous)
- [ ] Amount bounds validated
### Debit Flow (Kind 21002)
Request structure:
```json
{
"method": "pay_invoice",
"params": {
"invoice": "lnbc...",
"amount_msat": 100000
}
}
```
Response structure:
```json
{
"result": {
"preimage": "...",
"fee_msat": 1000
}
}
```
Validation:
- [ ] Invoice format valid (BOLT11)
- [ ] Amount matches invoice
- [ ] Preimage verified against payment hash
- [ ] Fee within acceptable bounds
- [ ] Timeout handling
### Manage Flow (Kind 21003)
For operator commands:
```json
{
"method": "get_balance",
"params": {}
}
```
Validation:
- [ ] Only authorized operators can send
- [ ] Commands are properly authenticated
- [ ] Responses handled securely
## Invoice Validation
### BOLT11 Checks
- [ ] Valid bech32 encoding
- [ ] Expiry not passed
- [ ] Amount matches expected
- [ ] Description hash valid (if used)
- [ ] Payment hash extractable
### Security Checks
- [ ] Never pay same invoice twice
- [ ] Amount limits enforced
- [ ] Rate limiting on payments
- [ ] Proper logging (no sensitive data)
## Wallet Operations
### Balance Queries
- [ ] Cached appropriately (not every render)
- [ ] Error handling for offline
- [ ] Display in correct units (sats, not msat)
### Invoice Generation
- [ ] Unique payment hashes
- [ ] Reasonable expiry times
- [ ] Description for record-keeping
- [ ] Amount in correct units
## Output Format
```markdown
## Lightning.Pub Conformity: [target]
### CLINK Protocol
| Flow | Status | Notes |
|------|--------|-------|
| Offer (21001) | ✅ | |
| Debit (21002) | ⚠️ | Missing timeout |
| Manage (21003) | ✅ | |
### Invoice Handling
- [ ] `file:line` - Issue description
### Integration Issues
- [ ] Description with fix suggestion
### Recommendations
- [ ] Performance/UX improvements
```
## Example Usage
```
/lightning-check packages/lightning/src/ --clink
```
Output:
```markdown
## Lightning.Pub Conformity: packages/lightning/src/
### CLINK Protocol
| Flow | Status | Notes |
|------|--------|-------|
| Offer (21001) | ✅ | Properly encoded |
| Debit (21002) | ⚠️ | No timeout handling |
### Issues Found
- [ ] `client.ts:89` - Debit request has no timeout, could hang indefinitely
- [ ] `client.ts:112` - Payment hash not verified against preimage
### Recommendations
- Add 30-second timeout for CLINK debit requests
- Implement invoice deduplication to prevent double-pay
```

View file

@ -0,0 +1,125 @@
# /nostr-check - Nostr Conformity Agent
## Purpose
Validate Nostr Implementation Proposals (NIP) conformity and optimize Nostr-related code.
## Invocation
```
/nostr-check [target] [--nips NIP1,NIP2,...]
```
Where `target` can be:
- A file path
- A directory
- `--events` to validate event structures
- `--relay` to check relay configuration
## Relevant NIPs for Lamassu ATM
### Core NIPs (Must Implement)
| NIP | Description | Usage in Lamassu |
|-----|-------------|------------------|
| NIP-01 | Basic protocol | Event structure, relay communication |
| NIP-19 | bech32 entities | npub, nsec, nprofile encoding |
| NIP-42 | Auth | Private relay authentication |
| NIP-44 | Encrypted payloads | Secure DMs, receipts |
| NIP-59 | Gift wrapping | Anonymous message delivery |
### Application NIPs
| NIP | Description | Usage in Lamassu |
|-----|-------------|------------------|
| NIP-17 | Private DMs | Receipt delivery |
| NIP-47 | Nostr Wallet Connect | Potential wallet integration |
| NIP-57 | Lightning Zaps | Optional tipping |
### Custom Event Kinds
| Kind | Description | Structure |
|------|-------------|-----------|
| 21001 | CLINK Offer | `{ pubkey, relays, priceType, amount? }` |
| 21002 | CLINK Debit | Payment request/response |
| 21003 | CLINK Manage | Operator commands |
| 30078 | Machine Status | Replaceable, `d` tag = "status" |
| 30079 | Transaction Record | Replaceable, `d` tag = "tx:{txid}" |
## Validation Checks
### Event Structure (NIP-01)
```typescript
interface Event {
id: string // 32-byte hex
pubkey: string // 32-byte hex
created_at: number // Unix timestamp
kind: number // Event kind
tags: string[][] // Array of tag arrays
content: string // Arbitrary string
sig: string // 64-byte hex signature
}
```
- [ ] `id` is valid SHA256 of serialized event
- [ ] `pubkey` is valid 32-byte hex
- [ ] `created_at` is reasonable (not far future/past)
- [ ] `kind` is valid for application
- [ ] `tags` are properly formatted
- [ ] `sig` is valid Schnorr signature
### bech32 Encoding (NIP-19)
- [ ] npub/nsec properly encoded
- [ ] nprofile includes relay hints
- [ ] nevent includes author pubkey
- [ ] No confusion between hex and bech32
### Encryption (NIP-44)
- [ ] Using NIP-44 (not deprecated NIP-04)
- [ ] Proper key derivation
- [ ] Random nonce for each message
- [ ] MAC verification before decryption
### Auth (NIP-42)
- [ ] Challenge-response implemented
- [ ] Auth events have proper `relay` tag
- [ ] Auth events signed correctly
- [ ] Timeout handling for auth flow
## Optimization Suggestions
### Relay Communication
- Use connection pooling
- Implement proper reconnection with backoff
- Batch event publishing when possible
- Use REQ filters efficiently
### Event Handling
- Verify signatures before processing
- Cache verified events
- Use proper indexing for event lookups
- Implement proper subscription management
## Output Format
```markdown
## Nostr Conformity: [target]
### NIP Compliance
| NIP | Status | Notes |
|-----|--------|-------|
| NIP-01 | ✅ Pass | |
| NIP-19 | ⚠️ Issue | See below |
### Issues Found
- [ ] `file:line` - Description
### Optimization Opportunities
- [ ] Description with rationale
### Custom Event Validation
| Kind | Valid | Notes |
|------|-------|-------|
| 30078 | ✅ | Machine status properly formatted |
```
## Example Usage
```
/nostr-check packages/nostr-client/src/events.ts --nips NIP-01,NIP-19
```

105
.claude/skills/security.md Normal file
View file

@ -0,0 +1,105 @@
# /security - Security Review Agent
## Purpose
Perform security audits on code changes, focusing on Bitcoin/Lightning ATM-specific vulnerabilities.
## Invocation
```
/security [target]
```
Where `target` can be:
- A file path (e.g., `packages/lightning/src/client.ts`)
- A directory (e.g., `packages/hal/`)
- `--staged` for staged git changes
- `--all` for full codebase scan
## Review Checklist
### 1. Bitcoin/Lightning Security
- [ ] Private keys never logged or exposed
- [ ] nsec (Nostr secret keys) protected with proper permissions (0600)
- [ ] Invoice amounts validated before payment
- [ ] Payment preimages handled securely
- [ ] No hardcoded mnemonics, seeds, or keys
- [ ] Proper BOLT11/BOLT12 invoice validation
### 2. Hardware Security (ATM-specific)
- [ ] Bill validator amounts cross-checked
- [ ] Dispenser commands validated (prevent over-dispensing)
- [ ] Hardware error states handled gracefully
- [ ] No race conditions in cash handling
- [ ] Timeout handling for hardware operations
### 3. Nostr Security
- [ ] NIP-44 encryption used for sensitive messages
- [ ] Event signatures verified before processing
- [ ] Relay URLs validated (no injection)
- [ ] NIP-42 auth implemented for private relay
- [ ] No pubkey/npub confusion (proper type safety)
### 4. General Security
- [ ] Input validation on all external data
- [ ] SQL injection prevention (parameterized queries)
- [ ] No command injection in Bash/shell calls
- [ ] Proper error handling (no sensitive data in errors)
- [ ] Rate limiting on API endpoints
- [ ] HTTPS/WSS enforced in production
### 5. Rust-specific (HAL)
- [ ] No `unsafe` blocks without justification
- [ ] Error handling with Result, no unwrap() in production
- [ ] Buffer bounds checking for serial communication
- [ ] Proper lifetime management
### 6. TypeScript-specific
- [ ] Strict null checks honored
- [ ] No `any` types
- [ ] Zod validation on external data
- [ ] No eval() or dynamic code execution
## Output Format
```markdown
## Security Review: [target]
### Critical Issues
- [ ] Issue description with file:line reference
### High Priority
- [ ] Issue description with file:line reference
### Medium Priority
- [ ] Issue description with file:line reference
### Low Priority / Suggestions
- [ ] Suggestion with rationale
### Passed Checks
- [x] Check that passed
```
## Example Usage
```
/security packages/lightning/src/client.ts
```
Output:
```markdown
## Security Review: packages/lightning/src/client.ts
### Critical Issues
None found.
### High Priority
- [ ] `client.ts:45` - Invoice amount not validated before `payInvoice()` call
### Medium Priority
- [ ] `client.ts:78` - Error message includes full stack trace, may leak internal paths
### Passed Checks
- [x] Private keys not exposed in logs
- [x] NIP-44 encryption used for DMs
- [x] Proper TypeScript strict mode
```

201
.claude/skills/test.md Normal file
View file

@ -0,0 +1,201 @@
# /test - Testing Agent
## Purpose
Run tests, analyze coverage, generate test cases, and validate ATM transaction flows.
## Invocation
```
/test [command] [target]
```
Commands:
- `run` - Run tests (default)
- `coverage` - Run with coverage report
- `generate` - Generate test cases for a file
- `flow` - Validate transaction flow
- `hardware` - Run hardware mock tests
## Test Categories
### 1. Unit Tests
Location: `*.test.ts` or `*.spec.ts` alongside source files
```bash
pnpm test # All tests
pnpm test --filter @lamassu/nostr-client # Specific package
```
### 2. Integration Tests
Location: `tests/integration/`
Tests cross-package interactions:
- Nostr client + CLINK
- State machine + Hardware mocks
- Lightning client + Invoice handling
### 3. E2E Tests (Playwright)
Location: `tests/e2e/`
Full transaction flows:
- Cash-in flow (bill insert → Lightning payment)
- Cash-out flow (Lightning receive → dispense)
- Error recovery flows
### 4. Hardware Mock Tests
Test against mock hardware:
```bash
pnpm test:hardware # With mock validator/dispenser
REAL_HARDWARE=true pnpm test:hardware # With real hardware (CI skip)
```
## Test Generation
### For a new file:
```
/test generate packages/lightning/src/client.ts
```
Generates test skeleton:
```typescript
import { describe, it, expect, vi } from 'vitest'
import { LightningPubClient } from './client'
describe('LightningPubClient', () => {
describe('createInvoice', () => {
it('should create valid BOLT11 invoice', async () => {
// TODO: Implement
})
it('should handle network errors', async () => {
// TODO: Implement
})
it('should validate amount bounds', async () => {
// TODO: Implement
})
})
})
```
### Test Case Suggestions
Based on code analysis, suggest test cases for:
- Happy path
- Edge cases (null, empty, max values)
- Error conditions
- Timeout scenarios
- Concurrent operations
## Transaction Flow Validation
### Cash-In Flow
```
/test flow cash-in
```
Validates:
1. Idle → Select Cash-In
2. Bill insertion events received
3. Amount calculation correct
4. CLINK offer generated
5. Payment received event
6. Receipt sent (optional)
7. Return to Idle
### Cash-Out Flow
```
/test flow cash-out
```
Validates:
1. Idle → Select Cash-Out
2. Amount selection
3. Invoice generated
4. Payment received
5. Cash dispensed
6. Bills removed detection (F56)
7. Return to Idle
### Error Flows
```
/test flow errors
```
Validates:
- Hardware timeout recovery
- Payment failure handling
- Network disconnection
- Partial dispense handling
## Coverage Requirements
### Minimum Coverage Targets
| Package | Statements | Branches | Functions |
|---------|------------|----------|-----------|
| nostr-client | 80% | 75% | 80% |
| clink | 80% | 75% | 80% |
| state-machine | 90% | 85% | 90% |
| lightning | 80% | 75% | 80% |
| hal (mocks) | 70% | 65% | 70% |
### Critical Paths (100% coverage required)
- Payment processing
- Cash dispensing logic
- Key handling
- Amount calculations
## Output Format
### Test Run
```markdown
## Test Results: [target]
### Summary
- Total: 42
- Passed: 40
- Failed: 2
- Skipped: 0
### Failed Tests
1. `client.test.ts` > createInvoice > should validate amount
- Expected: Error thrown
- Received: Invoice created with negative amount
### Coverage
| File | Statements | Branches | Functions |
|------|------------|----------|-----------|
| client.ts | 85% | 78% | 90% |
```
### Test Generation
```markdown
## Generated Tests: [file]
### Test File
`packages/lightning/src/client.test.ts`
### Suggested Test Cases
1. **createInvoice**
- ✅ Valid amount creates invoice
- ✅ Zero amount rejected
- ✅ Negative amount rejected
- ✅ Network error handled
### Missing Coverage
- `payInvoice` has no tests
- Error handling branch at line 45 untested
```
## Example Usage
```
/test coverage packages/state-machine/
```
```
/test generate packages/clink/src/offer.ts
```
```
/test flow cash-out
```