Skip to content

Commit af33ab6

Browse files
committed
Polish: hero GIF (real Playwright recording), badges, mermaid arch, vs alternatives, FAQ, CONTRIBUTING, SECURITY with sandbox notes, CI
1 parent 031541a commit af33ab6

7 files changed

Lines changed: 182 additions & 12 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Bug report
3+
about: Something doesn't work as documented
4+
labels: bug
5+
---
6+
7+
**What you did**
8+
Steps to reproduce.
9+
10+
**What you expected**
11+
One sentence.
12+
13+
**What happened**
14+
Paste the error / wrong output.
15+
16+
**Environment**
17+
- OS:
18+
- Browser:
19+
- Node version:
20+
- Provider / model used:

.github/ISSUE_TEMPLATE/security.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
name: Security concern
3+
about: Sandbox escape, auth bypass, etc. Prefer private reporting (see SECURITY.md).
4+
labels: security
5+
---
6+
7+
> Please consider using GitHub's private vulnerability reporting feature instead of this public template.
8+
9+
**Type of issue**
10+
Sandbox escape / auth / injection / other
11+
12+
**Reproduction**
13+
Minimal steps to trigger.
14+
15+
**Impact**
16+
What an attacker could do.

.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
node: [18, 20]
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-node@v4
18+
with:
19+
node-version: ${{ matrix.node }}
20+
cache: npm
21+
- run: npm ci
22+
- run: npm test
23+
- name: Build
24+
run: npm run build
25+
env:
26+
OPENAI_API_KEY: dummy-for-typecheck-only

CONTRIBUTING.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Contributing
2+
3+
Thanks for your interest in `openforge`. The repo is small (~800 lines) on purpose. PRs that grow the surface area need to justify the addition.
4+
5+
## Setup
6+
7+
```bash
8+
git clone https://github.com/krish9219/openforge
9+
cd openforge
10+
cp .env.example .env # set OPENAI_API_KEY
11+
npm install
12+
npm test # tests run without an API key
13+
npm run dev # http://localhost:3000
14+
```
15+
16+
## High-value contributions
17+
18+
- **`lib/workspace.ts` is the security boundary.** Any change here needs a test that proves a path-traversal attempt is rejected.
19+
- New provider in `lib/llm.ts` (Anthropic is a clean ~30-line add).
20+
- Tests for the file API (`/api/files`).
21+
- UX improvements to the chat / file tree / editor that don't grow the file count by more than ~50 lines.
22+
- CI improvements.
23+
24+
## Unlikely to be accepted
25+
26+
- Inline ghost-text completion. Requires deep IDE-grade behavior; out of scope for the simple browser editor.
27+
- Codebase embeddings / RAG. The "model sees what it reads" guarantee is intentional.
28+
- Multi-user / auth in the core. Run behind a reverse proxy with basic auth.
29+
- Cursor / VS Code-style command palette with hundreds of commands.
30+
31+
## PR checklist
32+
33+
- [ ] `npm test` passes.
34+
- [ ] `npm run build` produces no type errors.
35+
- [ ] If you touched `lib/workspace.ts`, you added or updated a sandbox test.
36+
- [ ] README is updated if behavior changed.

README.md

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
> *A minimal, self-hosted, browser-based AI pair-programmer for any folder.*
44
5+
![demo](docs/demo.gif)
6+
7+
<p align="left">
8+
<a href="https://github.com/krish9219/openforge/stargazers"><img src="https://img.shields.io/github/stars/krish9219/openforge?style=flat-square&color=22d3ee" alt="stars"></a>
9+
<a href="https://github.com/krish9219/openforge/blob/main/LICENSE"><img src="https://img.shields.io/github/license/krish9219/openforge?style=flat-square&color=a3e635" alt="license"></a>
10+
<img src="https://img.shields.io/badge/next.js-14-black?style=flat-square" alt="next">
11+
<img src="https://img.shields.io/badge/editor-monaco-blue?style=flat-square" alt="monaco">
12+
<img src="https://img.shields.io/badge/sandbox-yes-7c3aed?style=flat-square" alt="sandbox">
13+
<a href="https://github.com/krish9219/openforge/actions"><img src="https://img.shields.io/github/actions/workflow/status/krish9219/openforge/ci.yml?branch=main&style=flat-square&label=tests" alt="tests"></a>
14+
</p>
15+
516
Point openforge at a folder. Get a three-pane editor in your browser: file tree, Monaco editor, AI chat. The chat can read your files, write changes, and ask follow-ups. No SaaS account, no per-seat pricing, no telemetry. You own the OS, you own the code, you own the API key.
617

718
## Quick start
@@ -28,20 +39,34 @@ The included `workspace/` folder has a `hello.py` file so you can try the AI imm
2839

2940
## How it works
3041

42+
```mermaid
43+
flowchart LR
44+
B[browser<br/>Monaco + chat] -->|HTTP| F[/api/files<br/>GET tree / GET file / PUT file/]
45+
B -->|HTTP POST stream| C[/api/chat NDJSON/]
46+
C --> A[agent loop<br/>lib/llm.ts]
47+
A -->|list_files| W[lib/workspace.ts<br/>sandboxed]
48+
A -->|read_file| W
49+
A -->|write_file| W
50+
W --> D[(WORKSPACE_DIR<br/>your folder)]
51+
A -->|response| B
3152
```
32-
browser (Monaco + React)
33-
│ ⇅ HTTP
34-
Next.js API routes
35-
├── /api/files GET tree | GET file | PUT file
36-
└── /api/chat POST messages -> NDJSON stream of events
37-
38-
agent loop (lib/llm.ts)
39-
├── list_files() -> workspace tree as JSON
40-
├── read_file(path) -> file content
41-
└── write_file(path, c) -> overwrites file
42-
```
4353

44-
Every tool call is sandboxed by `lib/workspace.ts::safe(path)`, which resolves the input against `WORKSPACE_DIR` and rejects anything that escapes. Tool iterations are capped at 8 per turn to prevent loops.
54+
Every tool call is sandboxed by `lib/workspace.ts::safe(path)`, which resolves the input against `WORKSPACE_DIR` and rejects anything that escapes. Tool iterations are capped at 8 per turn to prevent loops. The chat stream is NDJSON — one event per line — so the UI renders tool calls and tool results as they happen.
55+
56+
## vs. the alternatives
57+
58+
| | openforge | Cursor | Continue | Cline | Aider |
59+
|---|---|---|---|---|---|
60+
| **Self-hosted on a server** | yes | no (desktop app) | no (IDE extension) | no (IDE extension) | yes (CLI) |
61+
| **Browser-based UI** | yes | no | no | no | no |
62+
| **Inline ghost-text completion** | no | yes | yes | no | no |
63+
| **Codebase indexing / embeddings** | no | yes | yes | yes | partial |
64+
| **Multi-file edit via chat** | yes | yes | yes | yes | yes |
65+
| **Visible tool calls** | yes | hidden | yes | yes | no |
66+
| **LOC you must read to debug** | ~800 | proprietary | thousands | thousands | ~10k |
67+
| **Best for** | self-host on a VPS, read on iPad | desktop dev | VS Code / JetBrains users | VS Code agentic users | terminal lovers |
68+
69+
If you want the best AI coding experience and don't care about self-hosting, use **Cursor** or **Continue**. If you want to read every line of the thing that's editing your files and run it on a Raspberry Pi, this is for you.
4570

4671
## What this is NOT
4772

@@ -68,6 +93,20 @@ If you want autocomplete-grade integration today, look at **Continue.dev** (VS C
6893
- There is no authentication. Run on `localhost`, behind a VPN, or behind HTTP basic auth at the proxy.
6994
- The `/api/chat` route accepts arbitrary message history. Don't expose this publicly without rate-limiting.
7095

96+
## FAQ
97+
98+
**Why not just use Cursor?** If Cursor works for you, use it. openforge exists for people who want to run an AI editor on a server they control, reach it from any device through a browser, and read every line of code that touches their files.
99+
100+
**Why no inline completion?** Building reliable inline ghost-text requires model-side support (FIM completion APIs), token-level streaming, and careful UX. The chat-driven panel is the 80% solution in 800 lines.
101+
102+
**Why no codebase embeddings?** Adding embeddings means another service, another index, and another set of failure modes. The model only sees what it explicitly reads via `read_file` — that's transparent and debuggable.
103+
104+
**Can the AI escape the sandbox?** It cannot — `safe()` resolves every path against `WORKSPACE_DIR` and rejects anything that escapes via `..`. The tests cover this (`workspace.test.ts`). If you find a way, please report it as a security issue.
105+
106+
**Anthropic / local models support?** OpenAI today. Adding Anthropic is ~30 lines in `lib/llm.ts` — open an issue and I'll point you at the spot.
107+
108+
**Multi-folder support?** Not yet. `WORKSPACE_DIR` is global. A folder switcher in the sidebar is a clean addition if you want to PR it.
109+
71110
## Tests
72111

73112
```bash
@@ -76,6 +115,14 @@ npm test
76115

77116
Tests cover the path sandbox, tree listing, and file read/write. They run without an API key.
78117

118+
## Contributing
119+
120+
See [CONTRIBUTING.md](CONTRIBUTING.md). Security: see [SECURITY.md](SECURITY.md). The sandbox in `lib/workspace.ts` is the single most important file — extra scrutiny there.
121+
122+
## Star history
123+
124+
[![Star History Chart](https://api.star-history.com/svg?repos=krish9219/openforge&type=Date)](https://star-history.com/#krish9219/openforge&Date)
125+
79126
## License
80127

81128
MIT — see [LICENSE](LICENSE).

SECURITY.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Security policy
2+
3+
## Supported versions
4+
5+
Only the `main` branch is supported. There are no version releases yet.
6+
7+
## Reporting
8+
9+
Email the maintainer via the GitHub profile, or use GitHub's private vulnerability reporting. Please do not open public issues for sandbox-escape or auth-related concerns.
10+
11+
## Threat model
12+
13+
`openforge` exposes a folder on disk to an LLM. The risks:
14+
15+
- **Path traversal via the AI's tool arguments.** Mitigation: `lib/workspace.ts::safe()` resolves every path against `WORKSPACE_DIR` and rejects anything that escapes. Tested in `lib/workspace.test.ts`. If you find a bypass, this is a high-priority security issue.
16+
- **Path traversal via the HTTP API.** `/api/files?path=...` passes the user input through `safe()` before reading or writing. Same protection.
17+
- **Prompt injection through file contents.** A file the AI reads can contain instructions that override the system prompt. The mitigation is the 8-iteration cap and the small, well-defined tool surface (only `list_files`, `read_file`, `write_file`).
18+
- **No authentication.** The dev server is open. Production deployments must be behind reverse-proxy auth (basic auth at nginx, Cloudflare Access, etc.). Documented in the README.
19+
20+
## What's intentionally not protected
21+
22+
- The contents of files the AI writes. If you ask it to write malicious code, it will. That's not a security issue, that's the user holding the gun by the trigger.
23+
- The API key in `.env`. Standard file-system permissions are the right protection.
24+
25+
If you find a vulnerability outside this list, please report it.

docs/demo.gif

737 KB
Loading

0 commit comments

Comments
 (0)