Overview
ScryCLI is built on a modern, layered architecture that combines React component patterns with terminal rendering capabilities through Ink, coupled with AI-powered file operations.Architectural Layers
Entry Point & Initialization
The application starts atsrc/bin/index.tsx:
Ink renders React components to the terminal instead of the DOM, enabling rich interactive CLI experiences.
UI Layer (React/Ink)
Application Flow State Machine
The mainApp component (src/ui/App.tsx) orchestrates authentication and model selection:
State Progression
State Progression
State 1: Unauthenticated
- User sees Welcome screen and Auth prompt
- After authentication → moves to State 2
- SelectModel component displays available AI models
- After selection → moves to State 3
- Full InputBox interface becomes available
- User can interact with AI and execute file operations
Input Processing
TheInputBox component (src/ui/InputBox.tsx) is the main interaction hub:
- Distinguish between commands (
/exit,/logout) and natural language prompts - Integrate both
useChatanduseToolExecutorhooks - Display loading states, errors, and results
- Handle keyboard shortcuts (ESC to exit commands)
Data Flow: User Input → Response
Step-by-Step Execution Flow
1. User Enters Prompt
1. User Enters Prompt
User types in Submits to
PromptInput component:InputBox.handleSubmit()2. Command vs. Natural Language Detection
2. Command vs. Natural Language Detection
- Commands starting with
/route toCommandRouter - Everything else goes to AI via
useChat.send()
3. AI Processing (useChat hook)
3. AI Processing (useChat hook)
From
src/hooks/useChat.ts:- Calls
llmCall()fromsrc/model/openRouter.ts - Includes system prompt and file tree context
- Updates state with streaming/final answer
4. AI Response with File Tree Context
4. AI Response with File Tree Context
The AI receives enriched context from The file tree is generated via
src/model/openRouter.ts:getFileTree() which recursively scans the current directory.5. Tool Execution (useToolExecutor hook)
5. Tool Execution (useToolExecutor hook)
From
src/hooks/useToolExecutor.ts:- Triggers when
loadingbecomesfalse - Parses JSON from AI response
- Executes corresponding file operation
6. Result Display
6. Result Display
AnswerDisplay component shows the outcome:- Loading spinner while AI processes
- Error messages in red
- Success results in green bordered box
Configuration Management
ScryCLI stores user preferences in~/.scrycli/config.json via src/config/configManage.ts:
- API keys (OpenRouter)
- Selected AI model
- User authentication state
Key Design Patterns
1. Hook-Based State Management
useChat: Manages AI conversation stateuseToolExecutor: Side-effect hook for file operations- No external state management library needed
2. Separation of Concerns
- UI Layer: Pure React components (Ink)
- Business Logic: Custom hooks
- External Services: Model and tools modules
3. JSON-Based Tool Protocol
AI doesn’t execute code directly—it returns structured JSON that the CLI interprets and executes safely.This architecture prevents arbitrary code execution and provides a clear contract between AI and system.
Performance Considerations
File Tree Caching
The file tree is generated once at startup:- Lazy loading
- Incremental updates
- Ignoring additional directories beyond
node_modules,.git, etc.
Real-Time Streaming
Currently usesgetText() which waits for complete response. Future enhancement could implement streaming for better UX.
Error Handling Strategy
- Caught at hook level
- Displayed in UI via
AnswerDisplay - Logged to console for debugging
