docs: E2E test scenario specs for all CLI subcommands #176

Merged
xiaomo merged 1 commits from docs/e2e-scenarios into main 2026-04-27 07:33:42 +00:00
10 changed files with 178 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# nerve daemon — E2E Scenarios
## daemon start
- ✅ starts daemon, writes PID file, kernel comes up (via lifecycle test)
- 🔲 start when already running — error or no-op
- 🔲 start with `--foreground` flag
## daemon stop
- ✅ stops daemon, clears PID file (via lifecycle test)
- 🔲 stop when not running — graceful message
## daemon status
- ✅ reports "running" when daemon is up, "not running" when stopped (via lifecycle test)
- 🔲 `--json` output
## daemon restart
- 🔲 restarts daemon — stop + start round-trip
- 🔲 restart when not running — starts fresh
## daemon logs (nerve logs)
- ✅ shows "log file not found" when no log exists
- ✅ displays last N lines (tail mode)
- ✅ respects `-n` flag to limit lines
- ✅ supports `--offset` for pagination
- ✅ shows pagination hint when earlier lines exist
- ✅ shows empty message for empty log file
- 🔲 `--follow` / `-f` streams new lines
+5
View File
@@ -0,0 +1,5 @@
# nerve dev — E2E Scenarios
- 🔲 runs foreground kernel session with hot-reload
- 🔲 exits cleanly on Ctrl+C / SIGINT
- 🔲 detects sense file changes and reloads
+14
View File
@@ -0,0 +1,14 @@
# nerve init — E2E Scenarios
## init (workspace)
-`--force` creates workspace layout (nerve.yaml, senses/, workflows/)
- ✅ generated nerve.yaml passes validate
- ✅ init without `--force` on existing dir exits 1
- 🔲 init in empty dir without `--force` — succeeds
- 🔲 `--from <git-url>` clones and sets up workspace
## init workflow
- 🔲 creates workflow scaffold under workflows/
- 🔲 generated workflow has valid structure
+36
View File
@@ -0,0 +1,36 @@
# nerve remote — E2E Scenarios
## remote add
- 🔲 adds a named remote, persists to config
- 🔲 duplicate name — error message
## remote list
- 🔲 lists all remotes with name and host
- 🔲 empty state — no remotes
## remote show
- 🔲 shows remote details (host, token masked)
- 🔲 non-existent remote — error message
## remote set-url
- 🔲 updates remote host
- 🔲 non-existent remote — error message
## remote set-token
- 🔲 updates remote token
- 🔲 non-existent remote — error message
## remote remove
- 🔲 removes a remote
- 🔲 non-existent remote — error message
## remote default
- 🔲 set default remote
- 🔲 show current default
+29
View File
@@ -0,0 +1,29 @@
# nerve sense — E2E Scenarios
## sense list
- ✅ prints sense list with name, group, throttle, triggers, and last signal time
- 🔲 empty state — no senses registered, prints empty message
- 🔲 `--json` — outputs valid JSON array
## sense trigger
- ✅ trigger known sense exits 0, stdout contains "Triggered"
- ✅ trigger non-existent sense writes error to stderr and exits 1
- ✅ sends correct IPC message `{ type: trigger-sense, sense: <name> }` to daemon
## sense query
- ✅ after trigger, persisted `_signals` table has at least one row
- ✅ default output lists payload column and counter count
-`--json` prints valid JSON array with payload on each row
-`--sql` runs custom read-only SQL and prints result
- 🔲 query non-existent sense — error message
- 🔲 `--limit` / `--offset` pagination
## sense schema
- ✅ prints CREATE TABLE statements for the sense database
- ✅ includes `_signals` table in output
-`--json` prints valid JSON array of SQL strings
- 🔲 schema for non-existent sense — error message
+6
View File
@@ -0,0 +1,6 @@
# nerve smoke — E2E Scenarios
Full round-trip integration tests that exercise multiple subcommands together.
- ✅ sense list + sense query after trigger — registers sense, triggers, verifies persisted signal and query output
- 🔲 init → dev → trigger workflow → thread inspect round-trip
+8
View File
@@ -0,0 +1,8 @@
# nerve store — E2E Scenarios
## store archive
- ✅ archives old workflow logs to JSONL, removes rows from logs DB, thread list still reads workflow_runs
-`--vacuum` completes VACUUM after archiving
- 🔲 archive with no old data — exits cleanly with "nothing to archive"
- 🔲 archive with custom `--before` date filter
+24
View File
@@ -0,0 +1,24 @@
# nerve thread — E2E Scenarios
## thread list
-`--all` completes without throwing
- 🔲 lists active threads with run ID, workflow name, status
- 🔲 empty state — no threads
## thread inspect
- ✅ inspect `<runId>` completes without throwing
- 🔲 inspect non-existent runId — error message
- 🔲 output contains workflow name, roles, round count
## thread show
- ✅ show `<runId>` completes without throwing (role rounds path)
- 🔲 show non-existent runId — error message
- 🔲 output contains conversation messages
## thread kill
- 🔲 kill active thread — exits 0, thread stops
- 🔲 kill non-existent thread — error message
@@ -0,0 +1,7 @@
# nerve validate — E2E Scenarios
- ✅ exits 0 for valid nerve.yaml
- ✅ exits 1 for invalid nerve.yaml
- ✅ exits 1 for malformed config (missing required fields)
- ✅ exits 1 when nerve.yaml is missing
- 🔲 `--json` outputs structured validation errors
@@ -0,0 +1,17 @@
# nerve workflow — E2E Scenarios
## workflow list
- 🔲 lists registered workflows with name and status
- 🔲 empty state — no workflows registered
## workflow status
- 🔲 shows status of a specific workflow
- 🔲 non-existent workflow — error message
## workflow trigger
- ✅ trigger + thread list/inspect/show round-trip (echo workflow)
- 🔲 trigger non-existent workflow — error message
- 🔲 trigger with `--input` JSON payload