Project 3: Context Window Visualizer
Project 3: Context Window Visualizer
Understanding Token Budgets: See what the AI sees, master what it remembers
Project Metadata
| Attribute | Value |
|---|---|
| Difficulty | Level 2: Intermediate |
| Time Estimate | 1-2 Weeks (20-30 hours) |
| Primary Language | TypeScript |
| Alternative Languages | Python, Rust |
| Prerequisites | Projects 1-2, TypeScript, terminal UI familiarity |
| Main Reference | โAI Engineeringโ by Chip Huyen |
Learning Objectives
By completing this project, you will:
- Understand tokenization deeply - how text becomes tokens, why some content is โexpensiveโ
- Visualize context consumption - see in real-time whatโs filling your context window
- Master context management strategies - when to clear, compact, or restructure
- Build terminal UIs - create interactive dashboards using Ink or Blessed
- Develop intuition for AI memory - understand what the AI โseesโ vs. what it โforgetsโ
Deep Theoretical Foundation
What Is a Context Window?
The context window is the AIโs working memory - everything it can โseeโ at once when generating a response. Unlike human memory which fades gradually, the context window has a hard boundary: either content is in the window and fully visible, or itโs outside and completely invisible.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE CONTEXT WINDOW METAPHOR โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Human Memory AI Context Window โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Recent memories โ โ IN WINDOW โ โ
โ โ (clear, detailed) โ โ (perfectly visible) โ โ
โ โ โ โ โ โ
โ โ Older memories โ โโโโโโโโโโโโโโโโโโโโโโโค โ
โ โ (fuzzy, incomplete) โ โ OUT OF WINDOW โ โ
โ โ โ โ (completely gone) โ โ
โ โ Distant memories โ โ โ โ
โ โ (fragments only) โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Gradient decay Binary cutoff โ
โ โ
โ This is why context management matters: โ
โ โข AI has perfect recall of in-window content โ
โ โข But ZERO recall of out-of-window content โ
โ โข Strategic loading is essential โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Tokens: The Currency of Context
Tokens are the atomic units of AI processing. Understanding tokenization is crucial because itโs often counterintuitive:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ TOKENIZATION EXAMPLES โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ TEXT TOKENS COUNT SURPRISE? โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ "Hello" [Hello] 1 No โ
โ "Hello, world!" [Hello][,] 4 Punctuation โ
โ [world][!] adds tokens โ
โ โ
โ "authentication" [authentic] 2 Long words โ
โ [ation] split โ
โ โ
โ " " (4 spaces) [ ] 1 Whitespace โ
โ efficient โ
โ โ
โ "cafรฉ" [caf][รฉ] 2 Non-ASCII โ
โ expensive โ
โ โ
โ "const x = 42;" [const][ x] 6 Code is โ
โ [ =][ 42] dense โ
โ [;] โ
โ โ
โ JSON with formatting Many High Whitespace โ
โ (indentation, newlines) tokens in JSON โ
โ adds up โ
โ โ
โ Minified JSON Fewer Lower Compact is โ
โ tokens cheaper โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Context Budget Model
Think of context like a financial budget:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CONTEXT BUDGET ALLOCATION โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ TOTAL BUDGET: 200,000 tokens โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โ FIXED COSTS (Cannot be reduced) โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ System Prompt: ~2,000 โ โ Kiro's core instructions โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Agent Config: ~500 โ โ Your agent's persona โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โ VARIABLE COSTS (Your control) โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Steering Rules: 1,000 - 10,000 โ โ โ
โ โ โ (depends on how many .md files in .kiro/steering/) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Context Files: 0 - 100,000+ โ โ โ
โ โ โ (files you /context add) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Chat History: 0 - remainder โ โ โ
โ โ โ (grows with each exchange) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ BUDGET RULE: โ
โ Fixed Costs + Variable Costs <= 200,000 โ
โ โ
โ When you exceed: Oldest chat history is dropped (silently!) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Hidden Dangers of Context Overflow
When you exceed the context limit, Kiro doesnโt error - it silently drops old content:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CONTEXT OVERFLOW BEHAVIOR โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Before Overflow (195,000/200,000 tokens): โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ [Turn 1] User: "Let's refactor the auth system..." โ โ
โ โ [Turn 1] AI: "I'll analyze the current implementation..." โ โ
โ โ [Turn 2] User: "Focus on the OAuth flow" โ โ
โ โ [Turn 2] AI: "The OAuth flow has these components..." โ โ
โ โ [Turn 3] User: "Implement the new design" โ โ
โ โ ... (many more turns) ... โ โ
โ โ [Turn 50] Current context โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ After Overflow (adding 10,000 tokens): โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โณ [Turn 1] DROPPED - AI forgets initial context โ โ
โ โ โณ [Turn 2] DROPPED - AI forgets OAuth focus โ โ
โ โ โ [Turn 3] User: "Implement the new design" โ โ
โ โ โ ... (remaining turns) ... โ โ
โ โ โ [Turn 50] Current context โ โ
โ โ โ [Turn 51] New content โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ RESULT: AI implements "new design" but forgot what it was! โ
โ โ
โ This is why monitoring is critical: โ
โ โข You can't see what the AI has forgotten โ
โ โข The AI doesn't know it forgot โ
โ โข Only proactive monitoring prevents this โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Real-World Analogy: The Whiteboard
Imagine a whiteboard in a meeting room:
- Whiteboard size = Context window limit
- Marker writing = Tokens
- Erasing old content = Context overflow dropping
If you keep writing without ever erasing, eventually you run out of space and must erase the oldest content - even if it was important. The context visualizer is like having a camera on the whiteboard that tracks exactly whatโs written and warns you before important content gets erased.
Historical Context: From 4K to 200K
Context window sizes have grown dramatically:
| Year | Model | Context Window |
|---|---|---|
| 2020 | GPT-2 | 1,024 tokens |
| 2022 | GPT-3.5 | 4,096 tokens |
| 2023 | GPT-4 | 8,192 tokens |
| 2024 | Claude 3 | 100,000 tokens |
| 2025 | Claude 4.5 | 200,000 tokens |
Despite this growth, context remains finite. The 200K window feels infinite until you load a large codebase - then it fills quickly.
Complete Project Specification
What You Are Building
A Real-time Context Monitor that:
- Displays Live Token Usage: Shows current consumption as a progress bar
- Attributes Tokens to Sources: Breaks down usage by chat history, files, steering
- Lists Active Context Files: Shows which files are loaded and their token cost
- Warns Before Overflow: Alerts at 75%, 90% thresholds
- Suggests Optimization: Recommends
/compactor file removal - Updates Continuously: Refreshes as you work in Kiro
Visual Output Target
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ KIRO CONTEXT MONITOR v1.0 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ CONTEXT USAGE: 142,500 / 200,000 tokens (71.3%) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ BREAKDOWN BY SOURCE โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Chat History โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 102,000 โ
โ Context Files โโโโโโโโโโโโ 35,000 โ
โ Steering Rules โโโโ 4,500 โ
โ System/Agent โ 1,000 โ
โ โ
โ CONTEXT FILES (by token cost) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ src/auth/oauth.ts โโโโโโโโโโโโ 12,500 tokens โ
โ src/auth/session.ts โโโโโโโโโโ 10,200 tokens โ
โ src/api/routes.ts โโโโโโ 6,800 tokens โ
โ docs/api_spec.md โโโโ 4,500 tokens โ
โ README.md โ 1,000 tokens โ
โ โ
โ STEERING FILES โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ .kiro/steering/tech.md โโ 2,200 tokens โ
โ .kiro/steering/security.md โ 1,500 tokens โ
โ .kiro/steering/product.md โ 800 tokens โ
โ โ
โ โ WARNING: Chat history is 72% of total context! โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ Recommendations: โ
โ โข Run /compact to summarize chat history โ
โ โข Remove unused context files with /context remove โ
โ โข Consider starting a new session for fresh context โ
โ โ
โ Press [q] to quit | [r] to refresh | [c] to compact โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Architecture Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CONTEXT VISUALIZER ARCHITECTURE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Terminal UI (Ink) โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โ Progress Bar โ โ Breakdown Chart โ โ File List โโ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ Warning Panel โโ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ State updates โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ State Manager โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ contextState: { โโ โ
โ โ โ totalTokens: 142500, โโ โ
โ โ โ limit: 200000, โโ โ
โ โ โ breakdown: { chat: 102000, files: 35000, ... }, โโ โ
โ โ โ files: [ { path, tokens }, ... ], โโ โ
โ โ โ warnings: [ ... ] โโ โ
โ โ โ } โโ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ Polling โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Data Fetcher โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Kiro CLI API โ โ Token Counter โ โ โ
โ โ โ /context show โ โ (tiktoken) โ โ โ
โ โ โโโโโโโโโโฌโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโ โ โ
โ โ โ โ โ โ
โ โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โผ โผ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Kiro CLI โ โ Local Files โ โ
โ โ Process โ โ (for estimation) โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Expected Deliverables
context-visualizer/
โโโ src/
โ โโโ index.tsx # Entry point
โ โโโ App.tsx # Main Ink application
โ โโโ components/
โ โ โโโ ProgressBar.tsx # Token usage bar
โ โ โโโ Breakdown.tsx # Source breakdown
โ โ โโโ FileList.tsx # Context files list
โ โ โโโ WarningPanel.tsx # Alerts and recommendations
โ โ โโโ StatusBar.tsx # Controls and help
โ โโโ hooks/
โ โ โโโ useContextData.ts # Fetch context from Kiro
โ โ โโโ useTokenCounter.ts # Estimate tokens locally
โ โ โโโ usePolling.ts # Periodic refresh
โ โโโ utils/
โ โ โโโ kiroClient.ts # Kiro CLI interaction
โ โ โโโ tokenizer.ts # Token counting
โ โ โโโ formatters.ts # Display formatting
โ โโโ types/
โ โโโ context.ts # TypeScript types
โโโ package.json
โโโ tsconfig.json
โโโ README.md
Solution Architecture
Data Model
// types/context.ts
export interface ContextFile {
path: string;
tokens: number;
addedAt: Date;
category: 'source' | 'doc' | 'config' | 'other';
}
export interface SteeringFile {
path: string;
tokens: number;
scope: 'global' | 'workspace';
inclusion: 'always' | 'agent' | 'never';
}
export interface ContextBreakdown {
systemPrompt: number;
agentConfig: number;
steeringRules: number;
contextFiles: number;
chatHistory: number;
total: number;
}
export interface ContextState {
breakdown: ContextBreakdown;
limit: number;
usagePercent: number;
files: ContextFile[];
steering: SteeringFile[];
lastUpdated: Date;
}
export interface Warning {
level: 'info' | 'warning' | 'critical';
message: string;
recommendation?: string;
}
export interface VisualizerState {
context: ContextState;
warnings: Warning[];
isLoading: boolean;
error?: string;
}
Component Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ INK COMPONENT TREE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ <App> โ
โ โ โ
โ โโโ <Header title="KIRO CONTEXT MONITOR" /> โ
โ โ โ
โ โโโ <ProgressBar โ
โ โ current={142500} โ
โ โ max={200000} โ
โ โ thresholds={[75, 90, 95]} โ
โ โ /> โ
โ โ โ
โ โโโ <Breakdown โ
โ โ data={{ โ
โ โ chatHistory: 102000, โ
โ โ contextFiles: 35000, โ
โ โ steeringRules: 4500, โ
โ โ system: 1000 โ
โ โ }} โ
โ โ /> โ
โ โ โ
โ โโโ <FileList โ
โ โ files={[ โ
โ โ { path: 'src/auth/oauth.ts', tokens: 12500 }, โ
โ โ { path: 'src/auth/session.ts', tokens: 10200 }, โ
โ โ ... โ
โ โ ]} โ
โ โ onRemove={(path) => removeFile(path)} โ
โ โ /> โ
โ โ โ
โ โโโ <WarningPanel warnings={warnings} /> โ
โ โ โ
โ โโโ <StatusBar โ
โ lastUpdated={lastUpdated} โ
โ onRefresh={refresh} โ
โ onCompact={compact} โ
โ /> โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Data Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DATA FLOW โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ 1. POLLING TRIGGER (every 5 seconds or manual) โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 2. FETCH CONTEXT DATA โ โ
โ โ $ kiro-cli /context show --format json โ โ
โ โ Response: { tokens: {...}, files: [...], ... } โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 3. PARSE AND ENRICH โ โ
โ โ โข Extract token counts โ โ
โ โ โข Estimate file tokens if not provided โ โ
โ โ โข Categorize files by type โ โ
โ โ โข Load steering file metadata โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 4. GENERATE WARNINGS โ โ
โ โ IF usagePercent > 90: โ โ
โ โ warnings.push({ level: 'critical', ... }) โ โ
โ โ IF chatHistoryPercent > 70: โ โ
โ โ warnings.push({ level: 'warning', ... }) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 5. UPDATE STATE โ โ
โ โ setState({ โ โ
โ โ context: newContextState, โ โ
โ โ warnings: newWarnings, โ โ
โ โ lastUpdated: new Date() โ โ
โ โ }) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 6. RENDER UI โ โ
โ โ Ink re-renders components with new state โ โ
โ โ Terminal display updates โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Phased Implementation Guide
Phase 1: Foundation (4-5 hours)
Goal: Set up project structure and basic Kiro CLI integration
What to Build:
- TypeScript + Ink project scaffolding
- Basic Kiro CLI client
- Simple token usage display
Hint 1: Initialize with Inkโs create-ink-app or manually:
mkdir context-visualizer && cd context-visualizer
npm init -y
npm install ink react @types/react typescript tsx
npm install -D @types/node
Hint 2: Create a minimal Kiro client:
// utils/kiroClient.ts
import { execSync } from 'child_process';
export function getContextInfo(): object {
try {
const output = execSync('kiro-cli /context show --format json', {
encoding: 'utf8',
timeout: 5000
});
return JSON.parse(output);
} catch (error) {
return { error: 'Failed to get context' };
}
}
Hint 3: Create a basic Ink app:
// src/App.tsx
import React from 'react';
import { Box, Text } from 'ink';
export function App() {
const usage = 142500;
const limit = 200000;
const percent = ((usage / limit) * 100).toFixed(1);
return (
<Box flexDirection="column">
<Text bold>KIRO CONTEXT MONITOR</Text>
<Text>Usage: {usage.toLocaleString()} / {limit.toLocaleString()} ({percent}%)</Text>
</Box>
);
}
Validation Checkpoint: Running npx tsx src/index.tsx shows basic usage stats.
Phase 2: Core Visualization (5-6 hours)
Goal: Build the progress bar and breakdown components
What to Build:
- Animated progress bar with color thresholds
- Breakdown chart showing token sources
- File list component with token counts
Hint 1: Build a progress bar with color coding:
// components/ProgressBar.tsx
import React from 'react';
import { Box, Text } from 'ink';
interface Props {
current: number;
max: number;
width?: number;
}
export function ProgressBar({ current, max, width = 50 }: Props) {
const percent = (current / max) * 100;
const filled = Math.round((percent / 100) * width);
const empty = width - filled;
// Color based on usage
const color = percent > 90 ? 'red' : percent > 75 ? 'yellow' : 'green';
return (
<Box>
<Text>[</Text>
<Text color={color}>{'โ'.repeat(filled)}</Text>
<Text color="gray">{'โ'.repeat(empty)}</Text>
<Text>]</Text>
<Text> {percent.toFixed(1)}%</Text>
</Box>
);
}
Hint 2: Create a horizontal bar chart for breakdown:
// components/Breakdown.tsx
import React from 'react';
import { Box, Text } from 'ink';
interface BreakdownItem {
label: string;
tokens: number;
color: string;
}
export function Breakdown({ items, total }: { items: BreakdownItem[], total: number }) {
const maxWidth = 40;
return (
<Box flexDirection="column">
{items.map(item => {
const barWidth = Math.round((item.tokens / total) * maxWidth);
return (
<Box key={item.label}>
<Text>{item.label.padEnd(18)}</Text>
<Text color={item.color}>{'โ'.repeat(barWidth)}</Text>
<Text> {item.tokens.toLocaleString()}</Text>
</Box>
);
})}
</Box>
);
}
Hint 3: Use Inkโs useInput for keyboard controls:
import { useInput } from 'ink';
function App() {
useInput((input, key) => {
if (input === 'q') process.exit(0);
if (input === 'r') refresh();
if (input === 'c') compact();
});
// ...
}
Validation Checkpoint: Display shows progress bar and breakdown that update with mock data.
Phase 3: Real-time Updates and Warnings (5-6 hours)
Goal: Add polling, warnings, and interactive features
What to Build:
- Polling hook for periodic updates
- Warning generation logic
- Interactive file removal
- Compact command trigger
Hint 1: Create a polling hook:
// hooks/usePolling.ts
import { useState, useEffect, useCallback } from 'react';
export function usePolling<T>(
fetcher: () => Promise<T>,
intervalMs: number = 5000
) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [isLoading, setIsLoading] = useState(true);
const refresh = useCallback(async () => {
try {
setIsLoading(true);
const result = await fetcher();
setData(result);
setError(null);
} catch (e) {
setError(e as Error);
} finally {
setIsLoading(false);
}
}, [fetcher]);
useEffect(() => {
refresh();
const interval = setInterval(refresh, intervalMs);
return () => clearInterval(interval);
}, [refresh, intervalMs]);
return { data, error, isLoading, refresh };
}
Hint 2: Generate contextual warnings:
// utils/warnings.ts
import { ContextState, Warning } from '../types/context';
export function generateWarnings(state: ContextState): Warning[] {
const warnings: Warning[] = [];
// Critical: approaching limit
if (state.usagePercent > 95) {
warnings.push({
level: 'critical',
message: 'Context window nearly full! Oldest content may be dropped.',
recommendation: 'Run /compact immediately or start a new session.'
});
} else if (state.usagePercent > 90) {
warnings.push({
level: 'critical',
message: `Context usage at ${state.usagePercent.toFixed(1)}%`,
recommendation: 'Consider running /compact to free space.'
});
}
// Warning: chat history dominates
const chatPercent = (state.breakdown.chatHistory / state.breakdown.total) * 100;
if (chatPercent > 70) {
warnings.push({
level: 'warning',
message: `Chat history is ${chatPercent.toFixed(0)}% of context`,
recommendation: 'Run /compact to summarize old messages.'
});
}
// Info: large files
const largeFiles = state.files.filter(f => f.tokens > 10000);
if (largeFiles.length > 0) {
warnings.push({
level: 'info',
message: `${largeFiles.length} file(s) exceed 10K tokens`,
recommendation: 'Consider loading only relevant sections.'
});
}
return warnings;
}
Hint 3: Use tiktoken for accurate token counting:
// utils/tokenizer.ts
import { encoding_for_model } from 'tiktoken';
const encoder = encoding_for_model('cl100k_base'); // Claude's tokenizer
export function countTokens(text: string): number {
return encoder.encode(text).length;
}
export async function countFileTokens(path: string): Promise<number> {
const content = await fs.readFile(path, 'utf8');
return countTokens(content);
}
Validation Checkpoint: Visualizer updates every 5 seconds and shows relevant warnings.
Testing Strategy
Unit Tests
// tests/warnings.test.ts
import { generateWarnings } from '../src/utils/warnings';
describe('generateWarnings', () => {
it('generates critical warning above 90% usage', () => {
const state = {
usagePercent: 92,
breakdown: { total: 184000, chatHistory: 100000 },
// ...
};
const warnings = generateWarnings(state);
expect(warnings.some(w => w.level === 'critical')).toBe(true);
});
it('warns when chat history dominates', () => {
const state = {
usagePercent: 50,
breakdown: { total: 100000, chatHistory: 80000 },
// ...
};
const warnings = generateWarnings(state);
expect(warnings.some(w =>
w.level === 'warning' && w.message.includes('Chat history')
)).toBe(true);
});
});
Integration Tests
// tests/integration.test.ts
import { render } from 'ink-testing-library';
import { App } from '../src/App';
describe('App integration', () => {
it('displays usage information', () => {
const { lastFrame } = render(<App />);
expect(lastFrame()).toContain('CONTEXT MONITOR');
expect(lastFrame()).toMatch(/\d+.*\/.*\d+.*tokens/);
});
it('shows warning panel when usage is high', async () => {
// Mock high usage scenario
jest.spyOn(kiroClient, 'getContextInfo').mockResolvedValue({
tokens: { used: 190000, limit: 200000 }
});
const { lastFrame } = render(<App />);
await waitFor(() => {
expect(lastFrame()).toContain('WARNING');
});
});
});
Manual Testing Checklist
- Start visualizer with no Kiro session (should show error gracefully)
- Start visualizer with active session (should show real data)
- Add files with
/context add(should update in visualizer) - Press โrโ to refresh (should update immediately)
- Press โqโ to quit (should exit cleanly)
- Reach 90% usage (should show warning)
- Verify token counts match Kiroโs
/context show
Common Pitfalls and Debugging
Pitfall 1: Kiro CLI Not Responding
Symptom: Visualizer hangs or shows stale data
Cause: No active Kiro session or CLI timeout
Debug:
# Check if Kiro is running
pgrep -f "kiro-cli"
# Test CLI manually
kiro-cli /context show --format json
Solution: Add timeout and fallback:
const output = execSync('kiro-cli /context show --format json', {
timeout: 5000, // 5 second timeout
encoding: 'utf8'
});
Pitfall 2: Token Count Mismatch
Symptom: Your counts donโt match Kiroโs display
Cause: Different tokenizer or encoding
Debug:
// Compare your count with Kiro's
const myCount = countTokens(content);
const kiroCount = getContextInfo().tokens.files[path];
console.log(`My: ${myCount}, Kiro: ${kiroCount}, Diff: ${myCount - kiroCount}`);
Solution: Use the correct tokenizer for Claude models:
import { encoding_for_model } from 'tiktoken';
// Claude uses cl100k_base encoding
const encoder = encoding_for_model('cl100k_base');
Pitfall 3: Terminal Rendering Issues
Symptom: UI is garbled or doesnโt fit
Cause: Terminal size too small or encoding issues
Debug:
# Check terminal size
echo "Columns: $COLUMNS, Lines: $LINES"
Solution: Detect terminal size and adapt:
import { useStdout } from 'ink';
function App() {
const { stdout } = useStdout();
const width = stdout?.columns || 80;
// Adjust bar width based on terminal
const barWidth = Math.max(20, Math.min(width - 30, 60));
}
Pitfall 4: Memory Leak from Polling
Symptom: Application slows down over time
Cause: Interval not cleaned up properly
Debug:
// Log each poll
console.log(`[${new Date().toISOString()}] Polling...`);
Solution: Ensure cleanup in useEffect:
useEffect(() => {
const interval = setInterval(refresh, 5000);
return () => {
clearInterval(interval); // Critical!
};
}, []);
Extensions and Challenges
Extension 1: Historical Tracking
Track context usage over time and generate graphs:
interface ContextSnapshot {
timestamp: Date;
usage: number;
breakdown: ContextBreakdown;
}
// Store snapshots in SQLite or JSON
function recordSnapshot(state: ContextState) {
const snapshot = { timestamp: new Date(), ...state };
appendToHistory(snapshot);
}
// Generate sparkline in terminal
function renderSparkline(history: ContextSnapshot[], width: number): string {
// ...
}
Extension 2: Predictive Warnings
Predict when youโll hit context limit based on growth rate:
function predictOverflow(history: ContextSnapshot[]): Date | null {
// Calculate growth rate
const recent = history.slice(-10);
const growthPerMinute = calculateGrowthRate(recent);
if (growthPerMinute <= 0) return null;
const remaining = limit - current;
const minutesToOverflow = remaining / growthPerMinute;
return new Date(Date.now() + minutesToOverflow * 60 * 1000);
}
Extension 3: Smart Compaction Suggestions
Analyze what would be safe to compact:
function suggestCompaction(state: ContextState): CompactionSuggestion {
// Identify old, unreferenced chat segments
const oldSegments = identifyOldChatSegments(state.chatHistory);
// Estimate savings
const potentialSavings = oldSegments.reduce((sum, s) => sum + s.tokens, 0);
return {
segments: oldSegments,
estimatedSavings: potentialSavings,
safetyLevel: 'safe' // or 'moderate' or 'risky'
};
}
Extension 4: Multi-Session View
Monitor multiple Kiro sessions simultaneously:
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ auth-refactor โ โ api-design โ โ bug-fix โ
โ โโโโโโโโโโโโ 65%โ โ โโโโโโโโโโ 38% โ โ โโโโโโโโโโ 82% โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
Challenge: Token Budget Planner
Create a planning mode that helps allocate context before starting work:
Token Budget Planner
โโโโโโโโโโโโโโโโโโโโ
Available: 200,000 tokens
Planned allocation:
[ ] Core files (src/auth/*) ~15,000
[ ] Documentation (docs/api.md) ~8,000
[ ] Steering rules ~3,000
[ ] Working room for chat ~174,000
Commit plan? [y/n]
Real-World Connections
How Professionals Use This
- Long-Running Projects: Teams monitor context to avoid losing important early decisions
- Code Review Sessions: Reviewers track which files are loaded for comprehensive reviews
- Debugging Sessions: Engineers ensure error context isnโt pushed out by new content
- Documentation Work: Writers monitor that relevant docs stay in context
Industry Patterns
Resource Monitoring (DevOps): This mirrors CPU/memory monitoring dashboards. The patterns of threshold alerts and resource attribution are universal.
Capacity Planning (SRE): Predicting context overflow is similar to predicting disk space exhaustion or memory pressure.
Cost Visibility (FinOps): Token breakdown is analogous to cloud cost allocation by service/team.
Self-Assessment Checklist
Understanding Verification
- Can you explain why tokens are โexpensiveโ differently for different content?
- Special characters, non-ASCII, and formatting add extra tokens
- Code is often more token-dense than prose
- JSON formatting significantly affects token count
- What happens when context overflows?
- Oldest chat history is silently dropped
- AI loses access to early context without warning
- Files and steering rules are not dropped (theyโre โpinnedโ)
- When should you use
/compactvs. starting fresh?/compact: Preserve important context, summarize history- Fresh session: Major topic change, โclean slateโ needed
- How do steering rules affect your context budget?
- Always loaded, consume tokens before you add anything
- More steering = less room for files and chat
- Balance thoroughness with budget
Skill Demonstration
- I can build a terminal UI with Ink
- I can accurately count tokens for any content
- I can integrate with Kiro CLI programmatically
- I can generate actionable warnings based on usage patterns
- I can explain context management to others
Interview Preparation
Be ready to answer:
- โHow would you design context management for an AI application?โ
- โWhat strategies exist for working with limited context windows?โ
- โHow do you prioritize what goes into context vs. whatโs retrieved dynamically?โ
- โWhatโs the relationship between context size and inference cost?โ
Recommended Reading
| Topic | Resource | Why It Helps |
|---|---|---|
| Tokenization | OpenAI Tokenizer docs | Understand how text becomes tokens |
| Context Windows | โAI Engineeringโ Ch. 3-4 | Deep dive on context management |
| React in Terminal | Ink documentation | Building TUIs with React |
| Real-time Systems | โDesigning Data-Intensive Applicationsโ Ch. 11 | Patterns for streaming data |
| Observability | โObservability Engineeringโ by Majors et al. | Dashboard design principles |
What Success Looks Like
When you complete this project, you will have:
- A Working Tool: Real-time context monitor running in your terminal
- Deep Token Intuition: Understanding of what consumes context and why
- TUI Development Skills: Ability to build interactive terminal applications
- Proactive Mindset: Monitoring before problems occur
- Foundation for Optimization: Data to drive context management decisions
Next Steps: Move to Project 4 (Custom Agent Factory) to learn how to create specialized agents with scoped permissions.