Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
44a1ec8
feat: add playwright dependency
ayan-de May 9, 2026
3fbb2a0
feat: add Result type and Logger utility
ayan-de May 9, 2026
0fd2276
feat: add scalable browser layer with provider system
ayan-de May 9, 2026
9a5de72
fix: use proper Locator types in PageAdapter interface
ayan-de May 9, 2026
be76787
feat: add context layer with strategy pattern
ayan-de May 9, 2026
4d91e08
fix: single-pass file traversal in FileTreeStrategy
ayan-de May 9, 2026
712784d
feat: add parser layer with strategy chain
ayan-de May 9, 2026
995d51d
feat: add file applicator
ayan-de May 9, 2026
7cbc58c
feat: add scalable /freecode command with provider system
ayan-de May 9, 2026
e272bb4
feat: improve response parsing, robust polling, and browser interacti…
ayan-de May 10, 2026
556c37a
docs: add agent development guide to CLAUDE.md
ayan-de May 10, 2026
8a096ec
feat: add initial README for FreeCode TUI with setup, run, and usage …
May 11, 2026
262f549
feat: initialize CLI app with package.json, TypeScript configuration,…
May 21, 2026
9802f54
feat: implement ReadTool for reading file contents with support for d…
May 21, 2026
13a1084
feat: implement WriteTool for creating and overwriting files with dir…
May 21, 2026
6f3376a
feat: implement JSON-RPC server for tool management and execution
May 21, 2026
00054dd
feat: implement CLI client for JSON-RPC communication with tools
May 21, 2026
342a7bf
feat: refactor file change application to use callTool for file opera…
May 21, 2026
7e22ac8
design: vscode chat extension spec
May 21, 2026
2670c76
plan: vscode chat extension implementation
May 21, 2026
671a6b4
chore: add .worktrees to gitignore
May 21, 2026
2e74cce
feat(vscode): scaffold extension with basic manifest and types
May 21, 2026
45b73cc
feat(vscode): add IPC client for CLI communication
May 21, 2026
d5c0a0c
feat(vscode): add chat store with Zustand
May 21, 2026
8c86cb6
feat(vscode): add message part components
May 21, 2026
90646e1
feat(vscode): add Message, MessageList, MessageInput components
May 21, 2026
8468704
feat(vscode): add ChatView webview provider and App root
May 21, 2026
cabe443
feat(vscode): add build configuration and verify compilation
May 21, 2026
062468e
refactor: rename extension to freecode-chat and update package structure
May 22, 2026
1f336af
docs: update agent guide and architecture overview for AI providers a…
ayan-de May 23, 2026
ef160c0
feat: add architecture specification for FreeCode and update pnpm-loc…
ayan-de May 23, 2026
a5f84b6
docs: add architecture spec and migration plan
ayan-de May 24, 2026
07c713e
feat(shared): add shared types and IPC protocol package
ayan-de May 24, 2026
46dfd2b
feat(cli): add browser, parser, context, applier, and agent modules
ayan-de May 24, 2026
0283c8a
refactor(tui): convert to thin client, delegate all logic to CLI via IPC
ayan-de May 24, 2026
f33fd10
refactor(vscode): convert to thin client, use @freecode/shared types
ayan-de May 24, 2026
039bf51
docs: update architecture specification with agent loop and design pa…
ayan-de May 24, 2026
aea1bfe
fix(tsconfig): add missing ignoreDeprecations option
ayan-de May 24, 2026
69009e5
feat(web): add architecture tabs and diagram animation hooks
ayan-de May 24, 2026
17e4b9a
feat(web): add architecture diagram components
ayan-de May 24, 2026
e2c2816
feat(web): add architecture content container
ayan-de May 24, 2026
c30b914
feat(web): add presentation components
ayan-de May 24, 2026
e5bf2f6
feat(web): add internal architecture page
ayan-de May 24, 2026
6d803aa
feat(web): add link to internal architecture page
ayan-de May 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,3 +36,6 @@ yarn-error.log*
# Misc
.DS_Store
*.pem

# Worktrees
.worktrees
343 changes: 214 additions & 129 deletions AGENTS.md

Large diffs are not rendered by default.

256 changes: 256 additions & 0 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
# FreeCode Agent Guide

> How to work on this codebase — architectural principles, patterns, and practices.

## Project Overview

FreeCode is a CLI tool that drives AI coding assistants (ChatGPT, Claude, Gemini) via browser automation to assist with coding tasks. The architecture uses a **thin-client model**: multiple frontends (TUI, VS Code extension) delegate all intelligence to a shared CLI backend via JSON-RPC over stdin/stdout.

The system uses a two-phase approach: the AI first returns which files it needs, then receives those files + prompt and returns structured file changes.

---

## Architecture

**TUI and VSCode are pure presentation layers. All business logic lives in CLI.**

```
┌─────────────────────────────────────────────────────────────┐
│ TUI │
│ (apps/tui) — pure UI shell │
│ Uses pi-tui for terminal rendering │
│ IPC client sends/receives JSON-RPC │
└──────────────────────────┬──────────────────────────────────┘
│ JSON-RPC (stdin/stdout)
┌─────────────────────────────────────────────────────────────┐
│ CLI Backend │
│ (apps/cli) — ALL intelligence │
│ Browser controller, parser, tools, context engine, │
│ agent loop, file applier │
└──────────────────────────┬──────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ AI Provider (Browser) │
│ ChatGPT / Claude / Gemini │
└─────────────────────────────────────────────────────────────┘
```

**Key principle:** TUI and VSCode are pure presentation layers. All business logic lives in CLI.

---

## Project Structure

```
freecode/
├── packages/
│ └── shared/ # Shared types + IPC protocol ONLY
│ └── src/
│ ├── types.ts # Message, MessagePart, ToolResult,
│ │ # FileChange, ParsedResponse
│ ├── ipc/
│ │ └── protocol.ts # JsonRpcRequest/Response, StreamResponse
│ └── index.ts
├── apps/
│ ├── cli/ # ALL intelligence lives here
│ │ └── src/
│ │ ├── server.ts # JSON-RPC stdin/stdout server
│ │ ├── agent/ # Agent loop + session management
│ │ ├── browser/ # Playwright + CDP + provider adapters
│ │ ├── context/ # File tree + context collection
│ │ ├── parser/ # Response parsing
│ │ ├── tools/ # Tool definitions + execution
│ │ └── applier/ # File diff + write
│ │
│ ├── tui/ # Pure UI shell — no business logic
│ │ └── src/
│ │ ├── index.ts # Entry point: mounts TUI, connects IPC
│ │ ├── commands/ # TUI-specific commands (model select)
│ │ ├── ipc/
│ │ │ └── client.ts # JSON-RPC client to CLI
│ │ └── assets/
│ │
│ └── vscode/ # Pure UI shell — no business logic
│ └── src/
│ ├── extension.ts # VS Code extension entry point
│ ├── chat/ # React webview components
│ ├── stores/ # Zustand stores (UI state only)
│ └── ipc/
│ └── client.ts # JSON-RPC client to CLI
└── docs/
└── superpowers/
├── specs/ # Design specifications
└── plans/ # Implementation plans
```

---

## Boundary: What Lives Where

| Concern | CLI | TUI | VSCode |
|---------|-----|-----|--------|
| Browser automation (Playwright/CDP) | ✅ | ❌ | ❌ |
| Provider adapters (ChatGPT, Claude) | ✅ | ❌ | ❌ |
| Agent loop + session management | ✅ | ❌ | ❌ |
| Context collection (file tree) | ✅ | ❌ | ❌ |
| Response parsing | ✅ | ❌ | ❌ |
| Tool execution | ✅ | ❌ | ❌ |
| File diff + writing | ✅ | ❌ | ❌ |
| TUI rendering (pi-tui) | ❌ | ✅ | ❌ |
| VS Code webview | ❌ | ❌ | ✅ |
| IPC client | ❌ | ✅ | ✅ |

---

## IPC Protocol

CLI exposes a JSON-RPC 2.0 interface over stdin/stdout. Both TUI and VSCode use the same protocol.

### Methods

| Method | Params | Returns | Description |
|--------|--------|---------|-------------|
| `tools.list` | — | `ToolListItem[]` | List available tools |
| `tools.call` | `{ name: string, args: Record<string, unknown> }` | `ToolResult` | Execute a tool |
| `session.start` | `{ projectPath: string, provider?: string }` | `{ sessionId: string }` | Start a new session |
| `session.send` | `{ sessionId: string, message: string }` | `StreamResponse` (streaming) | Send a message |
| `session.stop` | `{ sessionId: string }` | `void` | Abort current turn |
| `providers.list` | — | `ProviderInfo[]` | List available AI providers |

### Streaming Response

```typescript
interface StreamResponse {
type: "text" | "code" | "tool" | "done" | "error";
content: string;
toolName?: string; // when type === "tool"
toolArgs?: unknown; // when type === "tool"
toolResult?: string; // when type === "tool" (after execution)
}
```

---

## Type Sharing

Core domain types live in `packages/shared/src/types.ts`. No duplicate type definitions in frontends.

```typescript
export interface Message {
id: string;
role: "user" | "assistant";
parts: MessagePart[];
timestamp: number;
}

export type MessagePart =
| { type: "text"; content: string }
| { type: "code"; language: string; content: string }
| { type: "tool"; tool: { name: string; args: Record<string, unknown> }; result?: string };
```

---

## Architectural Principles

### Core Design Principles

1. **SOLID** — Single responsibility, Open-closed, Liskov substitution, Interface segregation, Dependency inversion
2. **YAGNI** — Only implement what's needed now; avoid speculative generalization
3. **DRY** — Don't repeat yourself; extract shared logic to single sources of truth
4. **Decomposition** — Each file/module does one thing well; avoid bloated files

### Thin Client Principles

1. **Zero business logic in frontends** — TUI and VSCode do only rendering and IPC. No browser automation, no file reading, no parsing.
2. **IPC is the only bridge** — All communication between frontends and CLI goes through JSON-RPC. No shared state.
3. **CLI owns everything** — Browser controller, providers, context engine, parser, tools, agent loop all live in CLI.

---

## Key Design Decisions

### 1. Long-Running CLI Daemon

CLI stays alive between turns, maintaining browser connection and session state. Starting a new browser + logging in per prompt is slow (5-15 seconds). A persistent connection enables sub-second response for subsequent turns.

### 2. Two-Phase Context Collection

Before sending a prompt, CLI first asks the LLM which files it needs, then reads only those files:
1. Send prompt + file tree to LLM → LLM returns list of needed files
2. CLI reads those files
3. Send files + prompt to LLM → LLM returns structured response

### 3. Format-Agnostic Parser

Parser tries multiple strategies (structured, markdown, JSON) in chain until one succeeds. LLMs are inconsistent in output format.

### 4. Diff Preview Before Apply

File changes are shown as a diff to the user for approval before writing. Prevents accidental data loss.

---

## File Naming Conventions

| Type | Convention | Example |
|------|-----------|---------|
| Components | PascalCase | `ChatLayout.tsx`, `CodePart.tsx` |
| Stores | kebab-case | `chat-store.ts` |
| IPC client | camelCase | `ipc/client.ts` |
| Provider adapters | camelCase | `chatgpt.ts` |
| Tool implementations | camelCase | `read.ts`, `write.ts` |
| Parser extractors | camelCase | `structured.ts`, `markdown.ts` |

---

## Adding New Features

### 1. Identify the domain

- **Browser layer** (`apps/cli/src/browser/`) — Playwright/CDP, DOM adapters
- **Context layer** (`apps/cli/src/context/`) — File tree, context compilation
- **Parser layer** (`apps/cli/src/parser/`) — Response parsing (JSON/markdown/tool)
- **Applier layer** (`apps/cli/src/applier/`) — File writing, diff generation
- **Tools layer** (`apps/cli/src/tools/`) — Tool definitions and execution
- **UI components** (`apps/tui/src/`, `apps/vscode/src/`) — Rendering only

### 2. Check existing patterns

Before adding code, verify:
- Does a similar pattern exist? Follow it.
- Is this functionality needed in more than one place? Extract to shared.
- Does this component do more than one thing? Decompose.

### 3. File limits

If a file exceeds ~150 lines, decompose:
- Extract sub-components
- Move helper functions to utils
- Split store logic into separate files

---

## Key Invariants

1. **Frontends are dumb** — TUI and VSCode only render UI and send/receive IPC. All logic is in CLI.
2. **IPC is the only bridge** — No shared state between frontends and CLI.
3. **Types are centralized** — Core domain types live in `packages/shared`. No duplicate type definitions.
4. **Providers are swappable** — ChatGPT/Claude adapters in `browser/providers/` can be swapped without changing core logic.
5. **Parser is chain-based** — Multiple extractors tried in order until one succeeds.

---

## Deferred Items

- **MCP server integration** — Expose tools via Model Context Protocol
- **Storage layer** — Persistent session history across restarts
- **Claude/Gemini providers** — Additional AI provider adapters
- **Rust TUI** — Higher-fidelity terminal rendering (only if performance demands)

Don't implement these unless explicitly requested.
21 changes: 21 additions & 0 deletions apps/cli/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
{
"name": "@freecode/cli",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "src/index.ts",
"scripts": {
"dev": "tsx src/index.ts",
"build": "tsc",
"lint": "tsc --noEmit"
},
"dependencies": {
"@freecode/shared": "workspace:*",
"playwright": "^1.42.0"
},
"devDependencies": {
"@types/node": "^22.15.3",
"tsx": "^4.0.0",
"typescript": "^5.7.0"
}
}
6 changes: 6 additions & 0 deletions apps/cli/src/agent/index.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
// =============================================================================
// Agent Module
// =============================================================================

export { executePromptCycle } from './loop.js';
export type { AgentResult, StreamCallback, StreamEvent, ExecutorOptions } from './types.js';
Loading