diff --git a/packages/cli/src/__tests__/e2e/daemon.md b/packages/cli/src/__tests__/e2e/daemon.md new file mode 100644 index 0000000..b810686 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/daemon.md @@ -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 diff --git a/packages/cli/src/__tests__/e2e/dev.md b/packages/cli/src/__tests__/e2e/dev.md new file mode 100644 index 0000000..8c2ef12 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/dev.md @@ -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 diff --git a/packages/cli/src/__tests__/e2e/init.md b/packages/cli/src/__tests__/e2e/init.md new file mode 100644 index 0000000..652b505 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/init.md @@ -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 ` clones and sets up workspace + +## init workflow + +- 🔲 creates workflow scaffold under workflows/ +- 🔲 generated workflow has valid structure diff --git a/packages/cli/src/__tests__/e2e/remote.md b/packages/cli/src/__tests__/e2e/remote.md new file mode 100644 index 0000000..d91cede --- /dev/null +++ b/packages/cli/src/__tests__/e2e/remote.md @@ -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 diff --git a/packages/cli/src/__tests__/e2e/sense.md b/packages/cli/src/__tests__/e2e/sense.md new file mode 100644 index 0000000..4b2196b --- /dev/null +++ b/packages/cli/src/__tests__/e2e/sense.md @@ -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: }` 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 diff --git a/packages/cli/src/__tests__/e2e/smoke.md b/packages/cli/src/__tests__/e2e/smoke.md new file mode 100644 index 0000000..c2817ff --- /dev/null +++ b/packages/cli/src/__tests__/e2e/smoke.md @@ -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 diff --git a/packages/cli/src/__tests__/e2e/store.md b/packages/cli/src/__tests__/e2e/store.md new file mode 100644 index 0000000..f1c0ca6 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/store.md @@ -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 diff --git a/packages/cli/src/__tests__/e2e/thread.md b/packages/cli/src/__tests__/e2e/thread.md new file mode 100644 index 0000000..fa6f3d2 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/thread.md @@ -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 `` completes without throwing +- 🔲 inspect non-existent runId — error message +- 🔲 output contains workflow name, roles, round count + +## thread show + +- ✅ show `` 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 diff --git a/packages/cli/src/__tests__/e2e/validate.md b/packages/cli/src/__tests__/e2e/validate.md new file mode 100644 index 0000000..b44ca00 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/validate.md @@ -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 diff --git a/packages/cli/src/__tests__/e2e/workflow.md b/packages/cli/src/__tests__/e2e/workflow.md new file mode 100644 index 0000000..70f7269 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/workflow.md @@ -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