Saedra Docs
CLI

Development

Development workflow and file structure

Development workflow

# 1. Start the local infrastructure and API
pnpm run dev:infra
pnpm run dev --filter @saedra/cli --filter ./apps/api

# 2. Point CLI to local API
export SAEDRA_API_URL=http://localhost:3002

# 3. Build the CLI (or use dev mode for watch)
pnpm --filter @saedra/cli build
# or
pnpm --filter @saedra/cli dev

# 4. Test commands
node packages/cli/dist/index.js status
node packages/cli/dist/index.js login

File structure

packages/cli/
├── package.json
├── tsconfig.json
└── src/
    ├── index.ts            # Entry point - registers all commands
    ├── commands/
    │   ├── login.ts        # Login, config management (getConfig, clearConfig, SaedraConfig)
    │   ├── helpers.ts      # Shared utilities: requireAuth, parseError, handleFetchError, selectProject, selectDocument
    │   ├── prompts.ts      # AI prompt constants and builders: REVIEW/FEATURE/COMPRESS/ANALYZE system prompts + buildReviewPrompt, buildFeaturePrompt, buildCompressPrompt, buildAnalyzePrompt
    │   ├── context.ts      # .saedra context file management (init, findSaedraContext)
    │   ├── arch-context.ts # context / explain / memory compress (contextCommand, explainCommand, memoryCompressCommand, fetchState, fetchDecisions, fetchChanges, fetchRules)
    │   ├── projects.ts     # project create / list / delete
    │   ├── documents.ts    # doc create / list / read / edit / push / delete
    │   ├── memory.ts       # memory state view/update/update --ai, decision add/list, change log/list/analyze, rule add/list, timeline
    │   ├── ai.ts           # ai setup / status / remove (getAiConfig, AiConfig, AiProvider)
    │   ├── ai-client.ts    # shared AI abstraction (callAI, streamAI) — supports Claude and OpenAI
    │   └── feature.ts      # ai feature (aiFeatureCommand)
    └── memory/
        └── schemas.ts      # ArchitectureState, Decision, ChangeEvent, ViolationRule, DocumentType

Where credentials are stored

~/.saedra/
├── config.json    # { email, userId, token, apiUrl }
└── ai.json        # { provider, apiKey } — permissions 0600