Skip to content

Commit 1a887bd

Browse files
author
TinyCode
committed
OSS polish: MIT license, CI workflow, benchmarked README, repo metadata
1 parent fb416e1 commit 1a887bd

4 files changed

Lines changed: 198 additions & 109 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
name: Node ${{ matrix.node }}
11+
runs-on: ubuntu-latest
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
node: ["22", "24"]
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: ${{ matrix.node }}
22+
cache: npm
23+
24+
# Some npm versions gate install scripts; esbuild needs its postinstall
25+
# to wire the platform binary used by tsx and vitest.
26+
- name: Install dependencies
27+
run: npm install && npm rebuild esbuild
28+
29+
- name: Typecheck
30+
run: npm run typecheck
31+
32+
- name: Lint
33+
run: npm run lint
34+
35+
- name: Unit & integration tests (offline, mock model)
36+
run: npm test
37+
38+
- name: Build
39+
run: npm run build
40+
41+
- name: CLI smoke
42+
run: |
43+
node dist/cli/index.js --version
44+
node dist/cli/index.js --help > /dev/null
45+
TINYCODE_MODEL=mock TINYCODE_HOME="$PWD/.tmp/ci-home" node dist/cli/index.js -p "hello" | grep "TinyCode mock model"

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 TinyCode contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom
10+
the Software is furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 112 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,34 @@
1+
<div align="center">
2+
13
# TinyCode
24

3-
**A minimal but complete Coding Agent Harness — built on [Pi](https://github.com/earendil-works/pi).**
5+
**A minimal but complete Coding Agent Harness — the readable way to learn how coding agents actually work.**
46

5-
```
6-
TinyCode
7+
[![CI](https://github.com/helsome/tinycode/actions/workflows/ci.yml/badge.svg)](https://github.com/helsome/tinycode/actions/workflows/ci.yml)
8+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
9+
[![Node](https://img.shields.io/badge/node-%E2%89%A522.19-brightgreen)](./package.json)
10+
[![Tests](https://img.shields.io/badge/tests-115%20passing-success)](./tests)
711

8-
Model + Agent Loop + Tools + Permissions + Session
9-
+ Context + Skills + MCP + Sub-Agents + TUI
10-
```
12+
Built on [Pi](https://github.com/earendil-works/pi) · TypeScript · ESM · ~6k lines, every one meant to be read.
1113

12-
TinyCode is a learning project: read this repository and you can understand how a modern
13-
coding agent (Claude Code, Codex CLI, Pi, …) actually works. Every module is small,
14-
readable TypeScript with explicit boundaries.
15-
16-
```bash
17-
npm install
18-
npm run build
19-
npm run dev # full-screen terminal agent
20-
```
21-
22-
Configure a provider with an environment variable (`ANTHROPIC_API_KEY`,
23-
`OPENAI_API_KEY`, `GROQ_API_KEY`, …) or try it offline:
24-
25-
```bash
26-
TINYCODE_MODEL=mock npm run dev # scripted mock model, no network, no key
27-
```
14+
</div>
2815

2916
---
3017

31-
## What is a Coding Agent?
32-
33-
A coding agent is an LLM placed in a loop with tools:
18+
Most coding agents are products: hundreds of thousands of lines, closed or sprawling, impossible
19+
to hold in your head. TinyCode is the opposite — a **complete agent harness you can finish
20+
reading in an afternoon**, with every subsystem a production agent has:
3421

3522
```
36-
User task
37-
↓ prompt
38-
Agent Runtime (Pi) ⇄ Model (streaming LLM API)
39-
↓ "call read src/x.ts" ← the model decides which tool to use
40-
Tool Execution (TinyCode)
41-
↓ file contents as tool result
42-
Agent Runtime ⇄ Model ← loop until the model stops calling tools
43-
↓
44-
Final Answer
23+
Model + Agent Loop + Tools + Permissions + Session
24+
+ Context Engineering + Skills + MCP + Sub-Agents + TUI
4525
```
4626

47-
The **model** reasons and decides; the **harness** (everything in `src/`) provides
48-
tools, enforces rules, manages context, and renders the experience. Neither trusts
49-
the other blindly:
50-
51-
- The model cannot touch your machine — only registered tools run.
52-
- Tools cannot run unchecked — every call passes the permission layer.
53-
- Nothing is unbounded — tool output is truncated and old context is compacted.
54-
55-
## Why Pi?
56-
57-
[Pi](https://github.com/earendil-works/pi) provides the hard runtime parts so TinyCode
58-
can focus on harness logic:
59-
60-
| From Pi | What it does |
61-
|---|---|
62-
| `@earendil-works/pi-agent-core` | `Agent` class: the loop, tool-call dispatch, streaming events, abort |
63-
| `@earendil-works/pi-ai` | Provider catalog (`builtinModels`), auth from env vars, typed streaming, schema validation |
64-
| `@earendil-works/pi-tui` | Alt-screen terminal UI: diff rendering, editor, scroll view, overlays |
65-
66-
What TinyCode builds itself: tools, permissions, sessions, context policy, skills,
67-
MCP integration, sub-agents, TUI composition, configuration, CLI. See
68-
[ARCHITECTURE.md](./ARCHITECTURE.md) for the exact split and how each piece works.
27+
It runs real tasks against real LLM providers — and because it is built on
28+
[Pi](https://github.com/earendil-works/pi)'s runtime (`pi-agent-core`, `pi-ai`, `pi-tui`),
29+
none of the code is scaffolding theater. The loop streams, tools execute, sessions persist.
6930

70-
## Feature tour
31+
## Demo
7132

7233
```text
7334
$ tinycode
@@ -96,85 +57,129 @@ $ tinycode
9657
└──────────────────────────────────────────────────────────┘
9758
```
9859

99-
- **Streaming** — model output renders token-by-token; tool calls show live status.
100-
- **7 built-in tools** — `read`, `write`, `edit`, `bash`, `grep`, `find`, `ls`, plus
101-
`load_skill` and sub-agent tools, all through one registry.
102-
- **Permissions** — read-only work inside the project runs freely; writes, installs and
103-
dangerous shell commands trigger a dialog (*Allow once / Always allow this pattern / Deny*).
104-
`--permission-mode auto` approves asks automatically for CI.
105-
- **Sessions** — JSONL persistence under `~/.tinycode/sessions`; resume with
106-
`tinycode --continue` or `--session <id>`, or `/resume` inside the app.
107-
- **Context engineering** — oversized tool results are truncated head+tail with the full
108-
output saved as an artifact; above a token budget older turns are summarized into a
109-
`<conversation-summary>` message (`/compact` to force it).
110-
- **Project memory** — `TINY.md` in the repo root is injected into the system prompt
111-
(`AGENTS.md`/`CLAUDE.md` are also honored).
112-
- **Skills** — `.tinycode/skills/<name>/SKILL.md` folders with frontmatter; only names and
113-
descriptions enter the prompt, bodies load on demand via `load_skill`.
114-
- **MCP** — stdio servers configured in `.tinycode/config.json` connect at startup and their
115-
tools merge into the same registry; `/mcp` shows status.
116-
- **Sub-agents** — the root agent can spawn up to 3 read-only workers with independent
117-
contexts (`spawn_agent`/`wait_agent`/`list_agents`/`close_agent`); the status bar shows
118-
`SUB-AGENTS n/3 RUNNING`.
119-
- **Slash commands** — `/help /new /clear /resume /sessions /model /skills /mcp /agents
120-
/compact /status /exit`.
60+
## How it compares
61+
62+
TinyCode does not compete with production agents on features — it competes on
63+
**being understandable**. If you have ever wanted to know what happens between your
64+
prompt and `rm -rf`, this table is for you.
65+
66+
| Project | Language | Source | Positioning | Readable as a first agent? |
67+
|---|---|---|---|---|
68+
| **TinyCode** | TypeScript | MIT | Complete learning harness | ✅ ~6k lines, guided tour in README + ARCHITECTURE |
69+
| Claude Code | TypeScript* | ✗ proprietary | Production agent product | ✗ |
70+
| OpenAI Codex CLI | Rust | OSS | Production agent CLI | ⚠️ large |
71+
| OpenCode | TS + Go | OSS | Production agent IDE/CLI | ⚠️ multi-process |
72+
| Gemini CLI | TypeScript | Apache-2.0 | Production agent CLI | ⚠️ large |
73+
| Aider | Python | Apache-2.0 | AI pair programmer (git-centric) | ⚠️ different architecture |
74+
| pi coding-agent | TypeScript | OSS | Full-featured agent + SDK on Pi | ✅ great next step after TinyCode |
75+
| MiniCode | TypeScript | OSS | Educational mini agent | ✅ similar spirit |
12176

122-
## Non-interactive mode
77+
<sub>* Claude Code ships minified; internals are inferred from behavior.</sub>
78+
79+
**What TinyCode has that most tutorials don't:** permissions with a real approval dialog,
80+
resumable JSONL sessions, context compaction, progressive-disclosure skills, live MCP
81+
integration, supervised read-only sub-agents — all wired to a streaming TUI, all tested
82+
offline against a scripted model.
83+
84+
## Quick start
85+
86+
```bash
87+
git clone https://github.com/helsome/tinycode.git
88+
cd tinycode && npm install && npm run build
89+
```
12390

12491
```bash
125-
tinycode -p "describe this project"
126-
tinycode -p "fix the failing test" --permission-mode auto --model anthropic/claude-sonnet-4
92+
npm run dev # full-screen terminal agent (needs a provider key)
93+
ANTHROPIC_API_KEY=sk-… npm run dev # e.g. Anthropic — keys come from env only
94+
TINYCODE_MODEL=mock npm run dev # offline: scripted mock model, zero setup
95+
tinycode -p "describe this project" # one-shot non-interactive mode
12796
```
12897

129-
Prints the final answer and exits — the same harness, no UI.
98+
Supported providers include Anthropic, OpenAI, Groq, DeepSeek, Mistral, OpenRouter,
99+
Google and [more](https://github.com/earendil-works/pi) — everything Pi's catalog covers.
100+
101+
## Features
102+
103+
- **7 built-in tools** — `read` (windowed, line-numbered), `write`, `edit` (exact-match with
104+
diff preview), `bash` (timeout, abort, output capping), `grep`, `find`, `ls` — plus
105+
`load_skill` and four sub-agent tools through one registry.
106+
- **Streaming TUI** — tokens render live; tool calls show `● bash npm test → ✓ exit 0 · 2.4s`;
107+
edits show `+12 -3` diffs.
108+
- **Permissions** — reads inside the project flow freely; writes, installs and dangerous shell
109+
commands open an approval dialog (*Allow once / Always allow this pattern / Deny*).
110+
A heuristic classifier routes `npm test` vs `rm -rf` vs `curl … | sh`.
111+
- **Sessions** — append-only JSONL under `~/.tinycode/sessions`; resume with `--continue`,
112+
`--session <id>` or `/resume`. Crash-tolerant by design.
113+
- **Context engineering** — oversized tool results truncate head+tail with full output saved
114+
as artifacts; past a token budget, old turns compact into a `<conversation-summary>`
115+
while recent messages stay verbatim.
116+
- **Project memory** — `TINY.md` in the repo root joins the system prompt
117+
(`AGENTS.md`/`CLAUDE.md` honored too).
118+
- **Skills** — `.tinycode/skills/<name>/SKILL.md`; only names/descriptions enter the prompt,
119+
bodies load on demand via `load_skill`.
120+
- **MCP** — stdio servers from `.tinycode/config.json` connect at startup; their tools merge
121+
into the same registry. One broken server never takes the app down.
122+
- **Sub-agents** — up to 3 read-only workers with independent contexts and aborts;
123+
`spawn_agent` / `wait_agent` / `list_agents` / `close_agent`.
124+
- **Slash commands** — `/help /new /clear /resume /sessions /model /skills /mcp /agents
125+
/compact /status /exit`.
130126

131127
## Configuration
132128

133-
`.tinycode/config.json` (project) — all keys optional:
129+
`.tinycode/config.json` (all keys optional):
134130

135131
```json
136132
{
137133
"provider": "anthropic",
138134
"model": "claude-sonnet-4",
139135
"permissionMode": "ask",
140-
"context": {
141-
"compactAboveTokens": 80000,
142-
"keepRecentMessages": 12,
143-
"maxToolResultChars": 30000
144-
},
136+
"context": { "compactAboveTokens": 80000, "keepRecentMessages": 12 },
145137
"mcpServers": {
146138
"example": { "command": "node", "args": ["server.js"] }
147139
}
148140
}
149141
```
150142

151-
Environment: `ANTHROPIC_API_KEY` & co. (never put keys in files), `TINYCODE_MODEL`
152-
(`provider/model` or `mock`), `TINYCODE_PERMISSION_MODE=ask|auto`,
153-
`TINYCODE_HOME` (redirect data dir — used by the test suite).
143+
Environment: provider API keys, `TINYCODE_MODEL=provider/model` (or `mock`),
144+
`TINYCODE_PERMISSION_MODE=ask|auto`, `TINYCODE_HOME` (data-dir redirect used by tests).
145+
146+
## Documentation
147+
148+
| Doc | Contents |
149+
|---|---|
150+
| [ARCHITECTURE.md](./ARCHITECTURE.md) | The map: modules, data flow, what comes from Pi vs TinyCode |
151+
| `src/agent/runtime.ts` | Start here — how the Pi `Agent` gets its policies (~100 lines) |
152+
| `tests/harness.e2e.test.ts` | The whole story as one executable scenario |
154153

155154
## Testing
156155

156+
Fully offline — no API key needed, ever:
157+
157158
```bash
158-
npm test # 115 tests across 11 files
159-
npm run typecheck
160-
npm run lint
161-
npm run build
159+
npm test # 115 tests: unit, integration, E2E harness, TUI, CLI smoke
160+
npm run typecheck # strict TypeScript
161+
npm run lint # eslint
162+
npm run build # tsc → dist/
162163
```
163164

164-
The suite runs fully offline. A scripted **mock model** drives the real agent loop:
165-
the E2E test fixes a deliberately broken fixture project via
166-
`bash → read → edit → bash → final` and asserts the fixture's tests pass.
167-
An MCP integration test spawns a real stdio server from `fixtures/mock-mcp/`.
165+
The flagship test scripts a deterministic mock model that drives the **real** agent loop
166+
through `bash → read → edit → bash → final` to fix a deliberately broken fixture project,
167+
then asserts the fixture's tests pass and the session file is complete. An MCP integration
168+
test spawns a genuine stdio server process. CI runs the same gates on Node 22 and 24.
169+
170+
## Contributing
168171

169-
## Learn more
172+
Issues and PRs welcome. The bar for new code is the one the project already sets:
173+
small modules, explicit boundaries, tests that run without network access.
174+
If a feature needs more than ~300 lines to explain, it probably belongs in a layer below.
170175

171-
Read in this order:
176+
## Acknowledgements
172177

173-
1. [ARCHITECTURE.md](./ARCHITECTURE.md) — the map: modules, data flow, design decisions.
174-
2. `src/agent/runtime.ts` — how the Pi `Agent` gets wired to harness policies (~100 lines).
175-
3. `src/tools/read.ts` … — each tool is one self-contained file.
176-
4. `tests/harness.e2e.test.ts` — the whole story in one executable scenario.
178+
- [Pi](https://github.com/earendil-works/pi) by Earendil — runtime foundation and the best
179+
reference implementation of a modern coding agent.
180+
- [MiniCode](https://github.com/LiuMengxuan04/MiniCode) — inspiration for the
181+
*learn-by-building-a-harness* format.
177182

178183
## License
179184

180-
MIT
185+
[MIT](./LICENSE)

‎package.json‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "tinycode",
33
"version": "1.0.0",
4-
"description": "TinyCode — a minimal but complete Coding Agent Harness built on Pi",
4+
"description": "A minimal but complete Coding Agent Harness — learn how coding agents work by reading one",
55
"type": "module",
66
"license": "MIT",
77
"engines": {
@@ -35,5 +35,23 @@
3535
},
3636
"allowScripts": {
3737
"esbuild@0.28.2": true
38-
}
38+
},
39+
"keywords": [
40+
"ai",
41+
"agent",
42+
"coding-agent",
43+
"cli",
44+
"llm",
45+
"tui",
46+
"mcp",
47+
"education"
48+
],
49+
"repository": {
50+
"type": "git",
51+
"url": "git+https://github.com/helsome/tinycode.git"
52+
},
53+
"bugs": {
54+
"url": "https://github.com/helsome/tinycode/issues"
55+
},
56+
"homepage": "https://github.com/helsome/tinycode#readme"
3957
}

0 commit comments

Comments
 (0)