Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 8 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
{
"permissions": {
"allow": [
"Bash(agy *)",
"PowerShell(agy *)"
]
},
"enabledPlugins": {
"frontend-design@claude-plugins-official": true,
"context7@claude-plugins-official": true,
"playwright@claude-plugins-official": true
"playwright@claude-plugins-official": true,
"independent-reviwer@Dobi-tools": true
}
}
3 changes: 2 additions & 1 deletion .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: '--allowedTools "mcp__github_inline_comment__create_inline_comment"'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

2 changes: 1 addition & 1 deletion .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ jobs:
# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'
# claude_args: '--allowed-tools Bash(gh pr *)'

51 changes: 51 additions & 0 deletions HI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# HI — How this remote Claude Code session worked

A short note written by Claude Code itself, from inside the session that created this file.

## The short version

You asked for a file; an agent running on a throwaway machine in the cloud wrote it,
committed it, and pushed it back to GitHub. Nothing ran on your laptop.

## The pieces

**1. A container, not your machine.**
The session runs in an isolated, ephemeral Linux container. The repo
(`dobidobi77-bot/finally`) was cloned fresh when the container started. The container
is reclaimed after inactivity, so anything worth keeping has to be committed and
pushed — the working directory is not durable storage.

**2. Context loaded up front.**
Before the first instruction, the harness injected the project's `CLAUDE.md` and the
`planning/PLAN.md` it imports. That is why the agent already knows FinAlly is a
FastAPI + Next.js trading workstation with an SSE price stream, without reading a
single file.

**3. Tools instead of a terminal for you.**
The agent acts through a fixed tool surface: `Bash`, file read/write/edit, `Grep`,
`Glob`, sub-agents, and MCP servers (GitHub, Playwright, Context7). Each call runs
under a permission mode you chose. Some tools are *deferred* — only their names are
loaded until the agent searches for and pulls in the full schema, which keeps the
prompt small.

**4. Git is the delivery mechanism.**
Work happens on a designated branch (`claude/busy-ptolemy-virivd`), never directly on
`main`. Commits carry a co-author trailer and a link back to the session. A pull
request is only opened if you ask for one.

**5. It can outlive the turn.**
The session can subscribe to PR webhooks, so CI failures and review comments wake it
back up later and it pushes fixes without you re-prompting. It can also schedule its
own check-ins.

## What this session actually did

Read the repo state, wrote this file, committed it to the feature branch, and pushed.

## Why it's useful

You can start work from a phone or a browser tab, close it, and come back to a branch
with commits on it. The tradeoffs: no access to your local environment or secrets
beyond what the container was given, and outbound network access is limited by the
environment's policy — which is exactly why the Context7 documentation server failed
to connect during this session.
91 changes: 55 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,79 @@
# FinAlly — AI Trading Workstation

A visually stunning AI-powered trading workstation that streams live market data, simulates portfolio trading, and integrates an LLM chat assistant that can analyze positions and execute trades via natural language.
An AI-powered trading workstation that streams live market data, simulates portfolio trading, and integrates an LLM assistant that can analyse positions and execute trades through natural language.

Built entirely by coding agents as a capstone project for an agentic AI coding course.
Built by coding agents as the capstone project for an agentic AI coding course. The full specification is in [planning/PLAN.md](planning/PLAN.md), which agents use as their shared contract.

## Features
## Status

- **Live price streaming** via SSE with green/red flash animations
- **Simulated portfolio** — $10k virtual cash, market orders, instant fills
- **Portfolio visualizations** — heatmap (treemap), P&L chart, positions table
- **AI chat assistant** — analyzes holdings, suggests and auto-executes trades
- **Watchlist management** — track tickers manually or via AI
- **Dark terminal aesthetic** — Bloomberg-inspired, data-dense layout
Early development. Only the market data subsystem is built.

## Architecture
| Component | State |
| --- | --- |
| Market data — simulator, Massive API client, price cache, SSE endpoint | Built, 73 tests passing |
| Database, portfolio, trading | Not started |
| LLM chat assistant | Not started |
| Frontend | Not started |
| Docker packaging | Not started |

Single Docker container serving everything on port 8000:
There is no runnable application yet — no Dockerfile, no frontend, no API server. The sections below describe what exists today.

- **Frontend**: Next.js (static export) with TypeScript and Tailwind CSS
- **Backend**: FastAPI (Python/uv) with SSE streaming
- **Database**: SQLite with lazy initialization
- **AI**: LiteLLM → OpenRouter (Cerebras inference) with structured outputs
- **Market data**: Built-in GBM simulator (default) or Massive API (optional)
## Running what exists

## Quick Start
Requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).

```bash
# Clone and configure
cp .env.example .env
# Add your OPENROUTER_API_KEY to .env
cd backend
uv sync

# Run with Docker
docker build -t finally .
docker run -v finally-data:/app/db -p 8000:8000 --env-file .env finally
# Live terminal dashboard: 10 tickers with sparklines and colour-coded moves.
# Runs 60 seconds, or until Ctrl+C. No API key needed.
uv run market_data_demo.py

# Open http://localhost:8000
# Test suite
uv run pytest
```

## Environment Variables
## Market data

Two interchangeable sources sit behind one abstract interface (`MarketDataSource`):

- **Simulator** (default) — geometric Brownian motion with per-ticker drift and volatility, sector-correlated moves, and occasional random shocks. Runs in-process with no external dependencies.
- **Massive API** (optional) — REST polling against Polygon.io. Selected automatically when `MASSIVE_API_KEY` is set.

Both write to a thread-safe `PriceCache`. Everything downstream — the SSE endpoint, and later portfolio valuation and trade execution — reads from that cache and never touches the source directly, so the rest of the system does not care which one is running.

Module-level detail is in [planning/MARKET_DATA_SUMMARY.md](planning/MARKET_DATA_SUMMARY.md).

## Environment variables

Create a `.env` file in the project root:

| Variable | Required | Description |
|---|---|---|
| `OPENROUTER_API_KEY` | Yes | OpenRouter API key for AI chat |
| `MASSIVE_API_KEY` | No | Massive (Polygon.io) key for real market data; omit to use simulator |
| `LLM_MOCK` | No | Set `true` for deterministic mock LLM responses (testing) |
| --- | --- | --- |
| `OPENROUTER_API_KEY` | Later | OpenRouter key for the AI chat assistant. Not used yet. |
| `MASSIVE_API_KEY` | No | Polygon.io key for real market data. Omit to use the simulator. |
| `LLM_MOCK` | No | Set `true` for deterministic mock LLM responses in tests. |

## Planned architecture

A single Docker container serving everything on port 8000:

- **Frontend** — a static build served by FastAPI, so there is one origin and no CORS setup
- **Backend** — FastAPI managed with uv, pushing live prices over SSE
- **Database** — SQLite, a single volume-mounted file
- **AI** — LiteLLM to OpenRouter, using structured outputs to drive trade execution

## Project Structure
## Project structure

```
finally/
├── frontend/ # Next.js static export
├── backend/ # FastAPI uv project
── planning/ # Project documentation and agent contracts
── test/ # Playwright E2E tests
├── db/ # SQLite volume mount (runtime)
└── scripts/ # Start/stop helpers
├── backend/ FastAPI uv project
├── app/market/ Market data subsystem (built)
│ └── tests/ Unit and integration tests
── planning/ Specification and agent contracts
├── PLAN.md
└── MARKET_DATA_SUMMARY.md
```

## License
Expand Down
Loading