Session CLI Tools

Development guide for CLI tools that maintain context across invocations through session management.

Session CLI tools maintain context across multiple invocations without requiring a persistent background process. They save and restore a context identifier between calls via files, enabling multi-turn workflows.

Before reading this page, review the Common Standards that apply to all tool types.

Why Sessions are Needed

Some tools operate in multi-turn fashion — each invocation depends on the results and context of previous ones. Take agent_cursor (a CLI wrapper for Cursor IDE) as an example:

# Turn 1: Analyze the codebase
agent_cursor run "Analyze this project's architecture" --session main
# Cursor returns analysis results and produces a session_id

# Turn 2: Continue based on the analysis
agent_cursor run "Based on the previous analysis, refactor the auth module" --session main
# Automatically resumes the previous session_id — Cursor knows what "previous analysis" means

Without Sessions, the second invocation would have no idea what "the previous analysis" refers to, and the user would need to manually manage session_ids and pass --resume parameters. Session aliases automate this entirely.

The key difference from Daemon: Sessions don't require a persistent background process. The tool still follows "run and exit" — it just saves and restores a context identifier between invocations via files.

Architecture Overview

First invocation:
┌─────────┐    Args    ┌───────────┐    Result + session_id    ┌──────────────┐
│  Caller  │  ──────►  │  CLI Tool  │  ──────────────────►    │  Output      │
│          │           │           │                           │              │
└─────────┘           └─────┬─────┘                           └──────────────┘
                            │ Save
                            ▼
                    ~/.tool/sessions/main.json

Subsequent invocations:
┌─────────┐    Args    ┌───────────┐    Result    ┌──────────────┐
│  Caller  │  ──────►  │  CLI Tool  │  ──────►   │  Output      │
│          │           │  Auto-     │             │              │
│          │           │  resume    │             │              │
└─────────┘           └─────┬─────┘             └──────────────┘
                            │ Read
                            ▲
                    ~/.tool/sessions/main.json

Project Structure

agent_cursor/
├── main.go
├── go.mod
├── cmd/
│   ├── root.go           # Root command, global --session flag
│   ├── skill.go          # skillSpec constant
│   ├── run.go            # Execute command (auto-resume)
│   └── session.go        # session ls / show / rm subcommands
└── internal/
    ├── output/
    │   └── output.go
    └── session/
        └── session.go    # Session persistence logic

Session Data Structure

type SessionData struct {
    Name      string    `json:"name"`
    SessionID string    `json:"sessionId"`
    CWD       string    `json:"cwd"`
    CreatedAt time.Time `json:"createdAt"`
    UpdatedAt time.Time `json:"updatedAt"`
}

Session files are stored at ~/.agent_cursor/sessions/<name>.json, where the filename is the session alias.

Global --session Flag

Registered via PersistentFlags so all subcommands can use Sessions:

func init() {
    rootCmd.PersistentFlags().StringVarP(&sessionName, "session", "s", "",
        "Session alias name for automatic resume")
    rootCmd.PersistentFlags().StringVar(&cwdPath, "cwd", "",
        "Working directory for Cursor agent (default: current directory)")
}

Automatic Session Resumption

Automatically check and resume sessions during command execution — users don't need to know session_ids exist:

if sessionName != "" && resumeID == "" {
    sess, err := session.Load(sessionName)
    if err == nil && sess.SessionID != "" {
        effectiveResumeID = sess.SessionID
    }
}

// Save session after execution
if sessionName != "" && result.SessionID != "" {
    session.Save(sessionName, result.SessionID, cwd)
}

Session Subcommands

Provide a session subcommand group for managing existing sessions:

agent_cursor session ls              # List all sessions
agent_cursor session show <name>     # View session details (session_id, creation time, etc.)
agent_cursor session rm <name>       # Delete a session

Development Checklist

  • All basic requirements from Common Standards
  • Global --session flag
  • Session data persisted to files (~/.tool/sessions/)
  • Automatic session resumption during command execution
  • Automatic session saving after command execution
  • session ls / session show / session rm management subcommands
  • --skill documents session usage and multi-turn interaction workflows