Files
Felix ZhangandGitHub 736a16e219 Add session management to account-cli (#260)
* Add session management to account-cli

Introduce session lifecycle (create, list, resolve, destroy) for three
modes: operator, smart-wallet, and external-eoa. Sessions are stored as
JSON files under ~/.base-account/sessions/ with owner-only permissions
(0o700/0o600) and secure deletion (random-byte overwrite before unlink).

Key additions:
- Session types with CAIP-2 chain identifiers and schema versioning
- Deterministic session resolution via BASE_SESSION env var or auto-select
- CLI commands: `session list`, `session info`, `session destroy [--all]`
- Audit logging (JSONL) for all session create/destroy operations
- Path traversal protection on session file paths
- CAIP-2 parsing/validation utilities with known chain aliases
- Comprehensive unit tests (615 lines) and integration tests (212 lines)

Made-with: Cursor

* Add dedicated tests for permissions and secure-delete utilities

Made-with: Cursor

* yarn format

* Refactor core/session into its own directory

Made-with: Cursor

* Remove accidentally committed symlink

Made-with: Cursor

* Rename session.test.ts to index.test.ts to match module name

Made-with: Cursor

* Address PR review feedback from spencerstock

- Fix secure deletion: use 'r+' flag instead of 'w' to overwrite
  existing data blocks in-place rather than truncating first
- Add Windows platform guard to permission checks so POSIX-only
  mode verification is skipped on win32
- Make destroyAllSessions read directory directly instead of going
  through listSessions(), so a single corrupt file can't block the
  escape hatch
- Use case-insensitive address comparison in resolveSession and
  session destroy for Ethereum address compatibility
- Remove redundant env var re-check from getBaseDir() that could
  silently override setBaseDir() in tests
- Use path.sep in path traversal guard for Windows compatibility

Made-with: Cursor

* Widen account field to string for CAIP address compatibility and improve destroy help text

Made-with: Cursor
2026-03-25 13:47:24 -07:00
..

@base-org/account-cli

Agent-first CLI for interacting with a user's Base Account.

Development

Prerequisites

# Build the SDK dependency (account-cli depends on @base-org/account)
yarn workspace @base-org/account build

Build & Run

# Build the CLI
yarn workspace @base-org/account-cli build

# Run it
node packages/account-cli/dist/index.js --help

Watch Mode

yarn workspace @base-org/account-cli dev

This runs tsc --watch — every save recompiles to dist/. Then run node packages/account-cli/dist/index.js to test.

Tests

yarn workspace @base-org/account-cli test --run

Typecheck & Lint

yarn workspace @base-org/account-cli typecheck
npx biome lint packages/account-cli/

Architecture

Two layers with a hard boundary:

  • commands/ — CLI adapter. Parses flags with Commander, calls into core/, formats output. Only layer that touches process, stdin/stdout, or TTY.
  • core/ — Business logic. Zero CLI dependencies. Typed inputs → typed outputs. Reusable by a future MCP server.

Adding a command

  1. Create src/core/<name>.ts — pure function, typed inputs/outputs, no process or CLI deps
  2. Create src/commands/<name>.ts — parse flags with Commander, call core, call formatOutput
  3. Register in src/index.ts

output/index.ts provides formatOutput and formatError. types/errors.ts provides CLIError for structured error codes.