Context from recent agent work
- Prior commits focused on voice/background model gating, speech resolver typing, and timeline cursor loading.
- This change targets a separate CLI command path to avoid overlap.
What changed
- Normalized the optional mode argument once (`mode?.trim()`) and reused it.
- Removed duplicated `client.close()` calls and centralized cleanup in a `finally` block.
- Typed the daemon client variable explicitly (`Awaited<ReturnType<typeof connectToDaemon>> | undefined`).
- Kept user-facing behavior and error codes stable, including DAEMON_NOT_RUNNING and MODE_OPERATION_FAILED.
Reasoning
- The previous implementation duplicated lifecycle handling and relied on non-null assertions for mode values.
- Centralized resource cleanup lowers leak risk and makes control flow easier to audit.
- This is a behavior-preserving refactor aligned with the refactor skill contract.
Verification
- `npm run typecheck`
- `npx tsx packages/cli/tests/10-agent-mode.test.ts`
Accomplishments for next agent
- `runModeCommand` now has a single cleanup path and clearer branching for list vs set mode.
- Mode argument handling is explicit and trimmed before use.
Challenges / follow-up
- CLI output typing still requires `AnyCommandResult<any>` for mixed-shape commands due the current `withOutput` generic design.
- If desired, a future refactor can redesign output typing to support per-branch result schemas without `any`.
Add a minimal privacy policy at /privacy that explains:
- Paseo is self-hosted, no data collection
- The relay uses end-to-end encryption and cannot read messages
- No analytics, tracking, or ads
- Third-party agent providers handle their own auth
Add footer link on home page styled as muted/subtle.
- Hide Changes tab completely when isGit is false instead of just muting it
- Automatically switch to Files tab if user was on Changes when it becomes hidden
- Add refresh button next to sort button in Files pane header
- Refresh button refreshes root directory, expanded directories, and file preview if open