@zhijiewang/openharness 1.0.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +741 -741
- package/dist/agents/roles.d.ts +4 -2
- package/dist/agents/roles.js +69 -5
- package/dist/commands/index.js +87 -29
- package/dist/harness/config.d.ts +17 -0
- package/dist/harness/marketplace.d.ts +62 -0
- package/dist/harness/marketplace.js +242 -0
- package/dist/harness/plugins.d.ts +1 -1
- package/dist/harness/plugins.js +15 -1
- package/dist/harness/telemetry.d.ts +59 -0
- package/dist/harness/telemetry.js +129 -0
- package/dist/main.js +40 -40
- package/dist/providers/router.d.ts +48 -0
- package/dist/providers/router.js +61 -0
- package/dist/query/compress.d.ts +5 -0
- package/dist/query/compress.js +45 -4
- package/dist/remote/auth.d.ts +25 -0
- package/dist/remote/auth.js +73 -0
- package/dist/remote/server.d.ts +18 -2
- package/dist/remote/server.js +168 -39
- package/dist/repl.js +8 -0
- package/dist/services/PipelineExecutor.d.ts +48 -0
- package/dist/services/PipelineExecutor.js +179 -0
- package/dist/services/a2a.d.ts +119 -0
- package/dist/services/a2a.js +176 -0
- package/dist/tools/PipelineTool/index.d.ts +40 -0
- package/dist/tools/PipelineTool/index.js +53 -0
- package/dist/tools/WebFetchTool/index.js +2 -2
- package/dist/tools.js +3 -0
- package/package.json +73 -73
package/README.md
CHANGED
|
@@ -1,741 +1,741 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="assets/logo-256.png" alt="openHarness logo" width="128" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
# OpenHarness
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
___
|
|
9
|
-
/ \
|
|
10
|
-
( ) ___ ___ ___ _ _ _ _ _ ___ _ _ ___ ___ ___
|
|
11
|
-
`~w~` / _ \| _ \| __| \| | || | /_\ | _ \ \| | __/ __/ __|
|
|
12
|
-
(( )) | (_) | _/| _|| .` | __ |/ _ \| / .` | _|\__ \__ \
|
|
13
|
-
))(( \___/|_| |___|_|\_|_||_/_/ \_\_|_\_|\_|___|___/___/
|
|
14
|
-
(( ))
|
|
15
|
-
`--`
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
AI coding agent in your terminal. Works with any LLM -- free local models or cloud APIs.
|
|
19
|
-
|
|
20
|
-
<p align="center">
|
|
21
|
-
<img src="assets/openharness_v0.11.1_4.gif" alt="OpenHarness demo" width="800" />
|
|
22
|
-
</p>
|
|
23
|
-
|
|
24
|
-
[](https://www.npmjs.com/package/@zhijiewang/openharness) [](https://www.npmjs.com/package/@zhijiewang/openharness) [](LICENSE)     [](https://github.com/zhijiewong/openharness) [](https://github.com/zhijiewong/openharness/issues) [](https://github.com/zhijiewong/openharness/pulls)
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Table of Contents
|
|
29
|
-
|
|
30
|
-
- [Quick Start](#quick-start)
|
|
31
|
-
- [Why OpenHarness?](#why-openharness)
|
|
32
|
-
- [Terminal UI](#terminal-ui)
|
|
33
|
-
- [Tools (35)](#tools-35)
|
|
34
|
-
- [Slash Commands (33)](#slash-commands-33)
|
|
35
|
-
- [Permission Modes](#permission-modes)
|
|
36
|
-
- [Hooks](#hooks)
|
|
37
|
-
- [Checkpoints & Rewind](#checkpoints--rewind)
|
|
38
|
-
- [Agent Roles](#agent-roles)
|
|
39
|
-
- [Headless Mode & CI/CD](#headless-mode)
|
|
40
|
-
- [Cybergotchi](#cybergotchi)
|
|
41
|
-
- [MCP Servers](#mcp-servers)
|
|
42
|
-
- [Providers](#providers)
|
|
43
|
-
- [FAQ](#faq)
|
|
44
|
-
- [Install](#install)
|
|
45
|
-
- [Development](#development)
|
|
46
|
-
- [Contributing](#contributing)
|
|
47
|
-
- [Community](#community)
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Quick Start
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
npm install -g @zhijiewang/openharness
|
|
55
|
-
oh
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
That's it. OpenHarness auto-detects Ollama and starts chatting. No API key needed.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
oh init # interactive setup wizard (provider + cybergotchi)
|
|
62
|
-
oh # auto-detect local model
|
|
63
|
-
oh --model ollama/qwen2.5:7b # specific model
|
|
64
|
-
oh --model gpt-4o # cloud model (needs OPENAI_API_KEY)
|
|
65
|
-
oh --trust # auto-approve all tool calls
|
|
66
|
-
oh --auto # auto-approve, block dangerous bash
|
|
67
|
-
oh -p "fix the tests" --trust # headless mode (single prompt, exit)
|
|
68
|
-
oh run "review code" --json # CI/CD with JSON output
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**In-session commands:**
|
|
72
|
-
```
|
|
73
|
-
/rewind # undo last AI file change (checkpoint restore)
|
|
74
|
-
/roles # list agent specializations
|
|
75
|
-
/vim # toggle vim mode
|
|
76
|
-
Ctrl+O # flush transcript to scrollback for review
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Why OpenHarness?
|
|
80
|
-
|
|
81
|
-
Most AI coding agents are locked to one provider or cost $20+/month. OpenHarness works with any LLM -- run it free with Ollama on your own machine, or connect to any cloud API. Every AI edit is git-committed and reversible with `/undo`.
|
|
82
|
-
|
|
83
|
-
| | OpenHarness | Claude Code | Aider | OpenCode |
|
|
84
|
-
|---|---|---|---|---|
|
|
85
|
-
| Any LLM | Yes (Ollama, OpenAI, Anthropic, OpenRouter, any OpenAI-compatible) | Anthropic only | Yes | Yes |
|
|
86
|
-
| Free local models | Ollama native | No | Yes | Yes |
|
|
87
|
-
| Tools | 35 with permission gates | 43+ | File-focused | 20+ |
|
|
88
|
-
| Permission modes | 7 (ask, trust, deny, acceptEdits, plan, auto, bypass) | 7 | Basic | Basic |
|
|
89
|
-
| Git integration | Auto-commit + /undo + /rewind checkpoints | Yes | Deep git | Basic |
|
|
90
|
-
| Slash commands | 30+ built-in | 80+ | Some | Some |
|
|
91
|
-
| Headless/CI mode | `oh -p "prompt"` or `oh run --json` | Yes | Yes | Yes |
|
|
92
|
-
| GitHub Action | Built-in PR review action | Yes | No | No |
|
|
93
|
-
| Agent roles | 6 specializations (reviewer, tester, debugger...) | Yes | No | No |
|
|
94
|
-
| Vim mode | hjkl, w/b/e, 0/$, x, d, i/a/I/A/o | Full vim | No | No |
|
|
95
|
-
| Prompt caching | Anthropic cache_control | Yes | No | No |
|
|
96
|
-
| Bash security | AST-based command analysis | AST analysis | No | No |
|
|
97
|
-
| Companion | Cybergotchi virtual pet | Basic | No | No |
|
|
98
|
-
| Terminal UI | Sequential renderer (Ink pattern) | React + Ink | Basic | BubbleTea |
|
|
99
|
-
| Language | TypeScript | TypeScript | Python | Go |
|
|
100
|
-
| License | MIT | Proprietary | Apache 2.0 | MIT |
|
|
101
|
-
| Price | Free (BYOK) | $20+/month | Free (BYOK) | Free (BYOK) |
|
|
102
|
-
|
|
103
|
-
## Terminal UI
|
|
104
|
-
|
|
105
|
-
OpenHarness features a sequential terminal renderer inspired by Ink/Claude Code's default mode. Completed messages flush to native scrollback (scrollable), while the live area (streaming, spinner, input) rewrites in-place using relative cursor movement.
|
|
106
|
-
|
|
107
|
-
### Keybindings
|
|
108
|
-
|
|
109
|
-
| Key | Action |
|
|
110
|
-
|-----|--------|
|
|
111
|
-
| `Enter` | Submit prompt |
|
|
112
|
-
| `Alt+Enter` | Insert newline (multi-line input) |
|
|
113
|
-
| `↑` / `↓` | Navigate input history |
|
|
114
|
-
| `Ctrl+C` | Cancel current request / exit |
|
|
115
|
-
| `Ctrl+A` / `Ctrl+E` | Jump to start / end of input |
|
|
116
|
-
| `Ctrl+O` | Toggle thinking block expansion |
|
|
117
|
-
| `Ctrl+K` | Toggle code block expansion in messages |
|
|
118
|
-
| `Tab` | Autocomplete slash commands / file paths / cycle tool outputs |
|
|
119
|
-
| `/vim` | Toggle Vim mode (normal/insert) |
|
|
120
|
-
|
|
121
|
-
Scrolling is handled by the terminal's native scrollbar. Completed messages flow into the terminal scrollback buffer. Use your terminal's search (e.g., `Ctrl+Shift+F` in VS Code) to search conversation history.
|
|
122
|
-
|
|
123
|
-
### Features
|
|
124
|
-
|
|
125
|
-
- **Markdown rendering** — headings, code blocks, bold, italic, lists, tables, blockquotes, links
|
|
126
|
-
- **Syntax highlighting** — keywords, strings, comments, numbers, types (JS/TS/Python/Rust/Go and 20+ languages)
|
|
127
|
-
- **Collapsible code blocks** — blocks over 8 lines auto-collapse; `Ctrl+K` to expand all
|
|
128
|
-
- **Collapsible thinking** — thinking blocks collapse to a one-line summary after completion; `Ctrl+O` to expand
|
|
129
|
-
- **Shimmer spinner** — animated "Thinking" indicator with color transitions (magenta → yellow at 30s → red at 60s)
|
|
130
|
-
- **Tool call display** — args preview, live streaming output, result summaries (line counts, elapsed time), expand/collapse with `Tab`
|
|
131
|
-
- **Permission prompts** — bordered box with risk coloring, bold colored **Y**es/**N**o/**D**iff keys, syntax-highlighted inline diffs
|
|
132
|
-
- **Status line** — model name, token count, cost, context usage bar (customizable via config)
|
|
133
|
-
- **Context warning** — yellow alert when context window exceeds 75%
|
|
134
|
-
- **Native terminal scrollbar** — completed messages flow into scrollback; use your terminal's scrollbar and search
|
|
135
|
-
- **Multi-line input** — `Alt+Enter` for newlines; paste detection auto-inserts newlines
|
|
136
|
-
- **Autocomplete** — slash commands and file paths with descriptions; Tab to cycle
|
|
137
|
-
- **File path autocomplete** — Tab-completes paths with `[dir]`/`[file]` indicators
|
|
138
|
-
- **Session browser** — `/browse` to interactively browse and resume past sessions
|
|
139
|
-
- **Companion mascot** — animated Cybergotchi in the footer (toggle with `/companion off|on`)
|
|
140
|
-
|
|
141
|
-
### Themes
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
oh --light # light theme for bright terminals
|
|
145
|
-
/theme light # switch mid-session (saved automatically)
|
|
146
|
-
/theme dark # switch back
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Theme preference is saved to `.oh/config.yaml` and persists across sessions.
|
|
150
|
-
|
|
151
|
-
### Custom Status Line
|
|
152
|
-
|
|
153
|
-
Customize the status bar format in `.oh/config.yaml`:
|
|
154
|
-
|
|
155
|
-
```yaml
|
|
156
|
-
statusLineFormat: '{model} │ {tokens} │ {cost} │ {ctx}'
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XXXX), `{ctx}` (context usage bar). Empty sections are automatically collapsed.
|
|
160
|
-
|
|
161
|
-
## Tools (35)
|
|
162
|
-
|
|
163
|
-
| Tool | Risk | Description |
|
|
164
|
-
|------|------|-------------|
|
|
165
|
-
| **Core** | | |
|
|
166
|
-
| Bash | high | Execute shell commands with live streaming output (AST safety analysis) |
|
|
167
|
-
| Read | low | Read files with line ranges, PDF support |
|
|
168
|
-
| ImageRead | low | Read images/PDFs for multimodal analysis |
|
|
169
|
-
| Write | medium | Create or overwrite files |
|
|
170
|
-
| Edit | medium | Search-and-replace edits |
|
|
171
|
-
| MultiEdit | medium | Atomic multi-file edits (all succeed or none) |
|
|
172
|
-
| Glob | low | Find files by pattern |
|
|
173
|
-
| Grep | low | Regex content search with context lines |
|
|
174
|
-
| LS | low | List directory contents with sizes |
|
|
175
|
-
| **Web** | | |
|
|
176
|
-
| WebFetch | medium | Fetch URL content (SSRF-protected) |
|
|
177
|
-
| WebSearch | medium | Search the web |
|
|
178
|
-
| RemoteTrigger | high | HTTP requests to webhooks/APIs |
|
|
179
|
-
| **Tasks** | | |
|
|
180
|
-
| TaskCreate | low | Create structured tasks |
|
|
181
|
-
| TaskUpdate | low | Update task status |
|
|
182
|
-
| TaskList | low | List all tasks |
|
|
183
|
-
| TaskGet | low | Get task details |
|
|
184
|
-
| TaskStop | low | Stop a running task |
|
|
185
|
-
| TaskOutput | low | Get task output |
|
|
186
|
-
| **Agents** | | |
|
|
187
|
-
| Agent | medium | Spawn a sub-agent (with role specialization) |
|
|
188
|
-
| ParallelAgent | medium | Dispatch multiple agents with DAG dependencies |
|
|
189
|
-
| SendMessage | low | Agent-to-agent peer messaging |
|
|
190
|
-
| AskUser | low | Ask user a question with options |
|
|
191
|
-
| **Scheduling** | | |
|
|
192
|
-
| CronCreate | medium | Schedule recurring tasks |
|
|
193
|
-
| CronDelete | medium | Remove scheduled tasks |
|
|
194
|
-
| CronList | low | List all scheduled tasks |
|
|
195
|
-
| **Planning** | | |
|
|
196
|
-
| EnterPlanMode | low | Enter structured planning mode |
|
|
197
|
-
| ExitPlanMode | low | Exit planning mode |
|
|
198
|
-
| **Code Intelligence** | | |
|
|
199
|
-
| Diagnostics | low | LSP-based code diagnostics |
|
|
200
|
-
| NotebookEdit | medium | Edit Jupyter notebooks |
|
|
201
|
-
| **Memory & Discovery** | | |
|
|
202
|
-
| Memory | low | Save/list/search persistent memories |
|
|
203
|
-
| Skill | low | Invoke a skill from .oh/skills/ |
|
|
204
|
-
| ToolSearch | low | Find tools by description |
|
|
205
|
-
| **Git Worktrees** | | |
|
|
206
|
-
| EnterWorktree | medium | Create isolated git worktree |
|
|
207
|
-
| ExitWorktree | medium | Remove a git worktree |
|
|
208
|
-
| **Process** | | |
|
|
209
|
-
| KillProcess | high | Stop processes by PID or name |
|
|
210
|
-
|
|
211
|
-
Low-risk read-only tools auto-approve. Medium and high risk tools require confirmation in `ask` mode. Use `--trust` or `--auto` to skip prompts.
|
|
212
|
-
|
|
213
|
-
## Slash Commands (33)
|
|
214
|
-
|
|
215
|
-
Type these during a chat session. Aliases: `/q` exit, `/h` help, `/c` commit, `/m` model, `/s` status.
|
|
216
|
-
|
|
217
|
-
**Session:**
|
|
218
|
-
| Command | Description |
|
|
219
|
-
|---------|-------------|
|
|
220
|
-
| `/clear` | Clear conversation history |
|
|
221
|
-
| `/compact` | Compress conversation to free context |
|
|
222
|
-
| `/export` | Export conversation to markdown |
|
|
223
|
-
| `/history [n]` | List recent sessions; `/history search <term>` to search |
|
|
224
|
-
| `/browse` | Interactive session browser with preview |
|
|
225
|
-
| `/resume <id>` | Resume a saved session |
|
|
226
|
-
| `/fork` | Fork current session |
|
|
227
|
-
|
|
228
|
-
**Git:**
|
|
229
|
-
| Command | Description |
|
|
230
|
-
|---------|-------------|
|
|
231
|
-
| `/diff` | Show uncommitted git changes |
|
|
232
|
-
| `/undo` | Undo last AI commit |
|
|
233
|
-
| `/commit [msg]` | Create a git commit |
|
|
234
|
-
| `/log` | Show recent git commits |
|
|
235
|
-
|
|
236
|
-
**Info:**
|
|
237
|
-
| Command | Description |
|
|
238
|
-
|---------|-------------|
|
|
239
|
-
| `/help` | Show all available commands (categorized) |
|
|
240
|
-
| `/cost` | Show session cost and token usage |
|
|
241
|
-
| `/status` | Show model, mode, git branch, MCP servers |
|
|
242
|
-
| `/config` | Show configuration |
|
|
243
|
-
| `/files` | List files in context |
|
|
244
|
-
| `/model <name>` | Switch model mid-session |
|
|
245
|
-
| `/memory` | View and search memories |
|
|
246
|
-
|
|
247
|
-
**Settings:**
|
|
248
|
-
| Command | Description |
|
|
249
|
-
|---------|-------------|
|
|
250
|
-
| `/theme dark\|light` | Switch theme (saved to config) |
|
|
251
|
-
| `/vim` | Toggle Vim mode |
|
|
252
|
-
| `/companion off\|on` | Toggle companion visibility |
|
|
253
|
-
|
|
254
|
-
**AI:**
|
|
255
|
-
| Command | Description |
|
|
256
|
-
|---------|-------------|
|
|
257
|
-
| `/plan <task>` | Enter plan mode |
|
|
258
|
-
| `/review` | Review recent code changes |
|
|
259
|
-
|
|
260
|
-
**Pet:**
|
|
261
|
-
| Command | Description |
|
|
262
|
-
|---------|-------------|
|
|
263
|
-
| `/cybergotchi` | Feed, pet, rest, status, rename, or reset your companion |
|
|
264
|
-
|
|
265
|
-
## Permission Modes
|
|
266
|
-
|
|
267
|
-
Control how aggressively OpenHarness auto-approves tool calls:
|
|
268
|
-
|
|
269
|
-
| Mode | Flag | Behavior |
|
|
270
|
-
|------|------|----------|
|
|
271
|
-
| `ask` | `--permission-mode ask` | Prompt for medium/high risk operations (default) |
|
|
272
|
-
| `trust` | `--trust` | Auto-approve everything |
|
|
273
|
-
| `deny` | `--deny` | Only allow low-risk read-only operations |
|
|
274
|
-
| `acceptEdits` | `--permission-mode acceptEdits` | Auto-approve file edits, ask for Bash/WebFetch/Agent |
|
|
275
|
-
| `plan` | `--permission-mode plan` | Read-only mode — block all write operations |
|
|
276
|
-
| `auto` | `--auto` | Auto-approve all, block dangerous bash (AST-analyzed) |
|
|
277
|
-
| `bypassPermissions` | `--permission-mode bypassPermissions` | Approve everything unconditionally (CI only) |
|
|
278
|
-
|
|
279
|
-
Bash commands are analyzed by a lightweight AST parser that detects destructive patterns (`rm -rf`, `git push --force`, `curl | bash`, etc.) and adjusts risk level accordingly.
|
|
280
|
-
|
|
281
|
-
Set permanently in `.oh/config.yaml`: `permissionMode: 'acceptEdits'`
|
|
282
|
-
|
|
283
|
-
## Hooks
|
|
284
|
-
|
|
285
|
-
Run shell scripts automatically at key session events by adding a `hooks` block to `.oh/config.yaml`:
|
|
286
|
-
|
|
287
|
-
```yaml
|
|
288
|
-
hooks:
|
|
289
|
-
- event: sessionStart
|
|
290
|
-
command: "echo 'Session started' >> ~/.oh/session.log"
|
|
291
|
-
|
|
292
|
-
- event: preToolUse
|
|
293
|
-
command: "scripts/check-tool.sh"
|
|
294
|
-
match: Bash # optional: only trigger for this tool name
|
|
295
|
-
|
|
296
|
-
- event: postToolUse
|
|
297
|
-
command: "scripts/after-tool.sh"
|
|
298
|
-
|
|
299
|
-
- event: sessionEnd
|
|
300
|
-
command: "scripts/cleanup.sh"
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
**Event types:**
|
|
304
|
-
- `sessionStart` — fires once when the session begins
|
|
305
|
-
- `preToolUse` — fires before each tool call; **exit code 1 blocks the tool** and returns an error to the model
|
|
306
|
-
- `postToolUse` — fires after each tool call completes
|
|
307
|
-
- `sessionEnd` — fires when the session ends
|
|
308
|
-
|
|
309
|
-
**Environment variables** available to hook scripts:
|
|
310
|
-
|
|
311
|
-
| Variable | Description |
|
|
312
|
-
|----------|-------------|
|
|
313
|
-
| `OH_EVENT` | Event type (`sessionStart`, `preToolUse`, etc.) |
|
|
314
|
-
| `OH_TOOL_NAME` | Name of the tool being called (tool events only) |
|
|
315
|
-
| `OH_TOOL_ARGS` | JSON-encoded tool arguments (tool events only) |
|
|
316
|
-
| `OH_TOOL_OUTPUT` | JSON-encoded tool output (`postToolUse` only) |
|
|
317
|
-
|
|
318
|
-
Use `match` to restrict a hook to a specific tool name (e.g., `match: Bash` only triggers for the Bash tool).
|
|
319
|
-
|
|
320
|
-
## Cybergotchi
|
|
321
|
-
|
|
322
|
-
OpenHarness ships with a Tamagotchi-style companion that lives in the side panel. It reacts to your session in real time — celebrating streaks, complaining when tools fail, and getting hungry if you ignore it.
|
|
323
|
-
|
|
324
|
-
**Hatch one:**
|
|
325
|
-
```
|
|
326
|
-
oh init # wizard includes cybergotchi setup
|
|
327
|
-
/cybergotchi # or hatch mid-session
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
**Commands:**
|
|
331
|
-
```
|
|
332
|
-
/cybergotchi feed # +30 hunger
|
|
333
|
-
/cybergotchi pet # +20 happiness
|
|
334
|
-
/cybergotchi rest # +40 energy
|
|
335
|
-
/cybergotchi status # show needs + lifetime stats
|
|
336
|
-
/cybergotchi rename # give it a new name
|
|
337
|
-
/cybergotchi reset # start over with a new species
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
**Needs** decay over time (hunger fastest, happiness slowest). Feed and pet your gotchi to keep it happy.
|
|
341
|
-
|
|
342
|
-
**Evolution** — your gotchi evolves based on lifetime milestones:
|
|
343
|
-
- Stage 1 (✦ magenta): 10 sessions or 50 commits
|
|
344
|
-
- Stage 2 (★ yellow + crown): 100 tasks completed or a 25-tool streak
|
|
345
|
-
|
|
346
|
-
**18 species** to choose from: duck, cat, owl, penguin, rabbit, turtle, snail, octopus, axolotl, cactus, mushroom, chonk, capybara, goose, and more.
|
|
347
|
-
|
|
348
|
-
## MCP Servers
|
|
349
|
-
|
|
350
|
-
Connect any MCP (Model Context Protocol) server by editing `.oh/config.yaml`:
|
|
351
|
-
|
|
352
|
-
```yaml
|
|
353
|
-
provider: anthropic
|
|
354
|
-
model: claude-sonnet-4-6
|
|
355
|
-
permissionMode: ask
|
|
356
|
-
mcpServers:
|
|
357
|
-
- name: filesystem
|
|
358
|
-
command: npx
|
|
359
|
-
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
360
|
-
- name: github
|
|
361
|
-
command: npx
|
|
362
|
-
args: ["-y", "@modelcontextprotocol/server-github"]
|
|
363
|
-
env:
|
|
364
|
-
GITHUB_PERSONAL_ACCESS_TOKEN: ghp_...
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
MCP tools appear alongside built-in tools. `/status` shows connected servers.
|
|
368
|
-
|
|
369
|
-
**MCP Server Registry** — browse and install from a curated catalog:
|
|
370
|
-
|
|
371
|
-
```
|
|
372
|
-
/mcp-registry # browse all available servers
|
|
373
|
-
/mcp-registry github # show install config for a specific server
|
|
374
|
-
/mcp-registry database # search by category
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Categories: filesystem, git, database, api, search, productivity, dev-tools, ai.
|
|
378
|
-
|
|
379
|
-
## Git Integration
|
|
380
|
-
|
|
381
|
-
OpenHarness auto-commits AI edits in git repos:
|
|
382
|
-
|
|
383
|
-
```
|
|
384
|
-
oh: Edit src/app.ts # auto-committed with "oh:" prefix
|
|
385
|
-
oh: Write tests/app.test.ts
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
- Every AI file change is committed automatically
|
|
389
|
-
- `/undo` reverts the last AI commit (only OH commits, never yours)
|
|
390
|
-
- `/diff` shows what changed
|
|
391
|
-
- Your dirty files are safe — committed separately before AI edits
|
|
392
|
-
|
|
393
|
-
## Checkpoints & Rewind
|
|
394
|
-
|
|
395
|
-
Every file modification is automatically checkpointed before execution. If something goes wrong:
|
|
396
|
-
|
|
397
|
-
```
|
|
398
|
-
/rewind # restore files from the last checkpoint
|
|
399
|
-
/undo # revert the last AI git commit
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
Checkpoints are stored in `.oh/checkpoints/` and cover FileWrite, FileEdit, and Bash commands that modify files.
|
|
403
|
-
|
|
404
|
-
## Verification Loops
|
|
405
|
-
|
|
406
|
-
After every file edit (Edit, Write, MultiEdit), openHarness automatically runs language-appropriate lint/typecheck commands and feeds the results back into the agent context. This is the single highest-impact harness engineering pattern — research shows 2-3x quality improvement from automated feedback.
|
|
407
|
-
|
|
408
|
-
**Auto-detection** — if your project has `tsconfig.json`, `.eslintrc*`, `pyproject.toml`, `go.mod`, or `Cargo.toml`, verification rules are detected automatically. No configuration needed.
|
|
409
|
-
|
|
410
|
-
**Custom rules** via `.oh/config.yaml`:
|
|
411
|
-
|
|
412
|
-
```yaml
|
|
413
|
-
verification:
|
|
414
|
-
enabled: true # default: true (auto-detect)
|
|
415
|
-
mode: warn # 'warn' appends to output, 'block' marks as error
|
|
416
|
-
rules:
|
|
417
|
-
- extensions: [".ts", ".tsx"]
|
|
418
|
-
lint: "npx tsc --noEmit 2>&1 | head -20"
|
|
419
|
-
timeout: 15000
|
|
420
|
-
- extensions: [".py"]
|
|
421
|
-
lint: "ruff check {file} 2>&1 | head -10"
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
The agent sees `[Verification passed]` or `[Verification FAILED]` with the linter output after each edit, enabling self-correction.
|
|
425
|
-
|
|
426
|
-
## Memory Consolidation
|
|
427
|
-
|
|
428
|
-
On session exit, openHarness automatically prunes stale memories using temporal decay:
|
|
429
|
-
|
|
430
|
-
- Memories not accessed in 30+ days lose 0.1 relevance per 30-day period
|
|
431
|
-
- Memories below 0.1 relevance are permanently deleted
|
|
432
|
-
- Updated relevance scores are persisted to memory files
|
|
433
|
-
|
|
434
|
-
This keeps the memory system lean and relevant. Configure in `.oh/config.yaml`:
|
|
435
|
-
|
|
436
|
-
```yaml
|
|
437
|
-
memory:
|
|
438
|
-
consolidateOnExit: true # default: true
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
## Scheduled Tasks (Cron)
|
|
442
|
-
|
|
443
|
-
Create recurring tasks that run automatically in the background:
|
|
444
|
-
|
|
445
|
-
```
|
|
446
|
-
# Via slash commands
|
|
447
|
-
/cron list # show all scheduled tasks
|
|
448
|
-
/cron create "check-tests" # create a new task (interactive)
|
|
449
|
-
/cron delete <id> # remove a task
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
**Schedule syntax:** `every 5m`, `every 2h`, `every 1d`
|
|
453
|
-
|
|
454
|
-
The cron executor checks every 60 seconds for due tasks and runs them via sub-queries. Results are stored in `~/.oh/crons/history/`.
|
|
455
|
-
|
|
456
|
-
## Agent Roles
|
|
457
|
-
|
|
458
|
-
Dispatch specialized sub-agents for focused tasks:
|
|
459
|
-
|
|
460
|
-
```
|
|
461
|
-
/roles # list all available roles
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
| Role | Description | Tools |
|
|
465
|
-
|------|-------------|-------|
|
|
466
|
-
| `code-reviewer` | Find bugs, security issues, style problems | Read-only |
|
|
467
|
-
| `test-writer` | Generate unit and integration tests | Read + Write |
|
|
468
|
-
| `docs-writer` | Write documentation and comments | Read + Write + Edit |
|
|
469
|
-
| `debugger` | Systematic bug investigation | Read-only + Bash |
|
|
470
|
-
| `refactorer` | Simplify code without changing behavior | All file tools + Bash |
|
|
471
|
-
| `security-auditor` | OWASP, injection, secrets, CVE scanning | Read-only + Bash |
|
|
472
|
-
| `evaluator` | Evaluate code quality and run tests (read-only) | Read-only + Bash + Diagnostics |
|
|
473
|
-
| `planner` | Design step-by-step implementation plans | Read-only + Bash |
|
|
474
|
-
| `architect` | Analyze architecture and design structural changes | Read-only |
|
|
475
|
-
| `migrator` | Systematic codebase migrations and upgrades | All file tools + Bash |
|
|
476
|
-
|
|
477
|
-
Each role restricts the sub-agent to only its suggested tools. You can also pass `allowed_tools` explicitly:
|
|
478
|
-
|
|
479
|
-
```
|
|
480
|
-
Agent({ subagent_type: 'evaluator', prompt: 'Run all tests and report results' })
|
|
481
|
-
Agent({ allowed_tools: ['Read', 'Grep'], prompt: 'Search for all TODO comments' })
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
## Headless Mode
|
|
485
|
-
|
|
486
|
-
Run a single prompt without interactive UI — perfect for CI/CD and scripting:
|
|
487
|
-
|
|
488
|
-
```bash
|
|
489
|
-
# Chat command with -p flag (recommended)
|
|
490
|
-
oh -p "fix the failing tests" --model ollama/llama3 --trust
|
|
491
|
-
oh -p "review src/query.ts" --auto --output-format json
|
|
492
|
-
|
|
493
|
-
# Run command (alternative)
|
|
494
|
-
oh run "fix the failing tests" --model ollama/llama3 --trust
|
|
495
|
-
oh run "add error handling to api.ts" --json # JSON output
|
|
496
|
-
|
|
497
|
-
# Pipe stdin
|
|
498
|
-
cat error.log | oh run "what's wrong here?"
|
|
499
|
-
git diff | oh run "review these changes"
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
### GitHub Action for PR Review
|
|
503
|
-
|
|
504
|
-
OpenHarness includes a built-in GitHub Action for automated code review:
|
|
505
|
-
|
|
506
|
-
```yaml
|
|
507
|
-
# .github/workflows/ai-review.yml
|
|
508
|
-
on:
|
|
509
|
-
pull_request:
|
|
510
|
-
types: [opened, synchronize]
|
|
511
|
-
|
|
512
|
-
jobs:
|
|
513
|
-
review:
|
|
514
|
-
runs-on: ubuntu-latest
|
|
515
|
-
steps:
|
|
516
|
-
- uses: actions/checkout@v4
|
|
517
|
-
with:
|
|
518
|
-
fetch-depth: 0
|
|
519
|
-
- uses: ./.github/actions/review
|
|
520
|
-
with:
|
|
521
|
-
model: 'claude-sonnet-4-6'
|
|
522
|
-
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
Exit code 0 on success, 1 on failure.
|
|
526
|
-
|
|
527
|
-
## Providers
|
|
528
|
-
|
|
529
|
-
```bash
|
|
530
|
-
# Local (free, no API key needed)
|
|
531
|
-
oh --model ollama/llama3
|
|
532
|
-
oh --model ollama/qwen2.5:7b
|
|
533
|
-
|
|
534
|
-
# Cloud
|
|
535
|
-
OPENAI_API_KEY=sk-... oh --model gpt-4o
|
|
536
|
-
ANTHROPIC_API_KEY=sk-ant-... oh --model claude-sonnet-4-6
|
|
537
|
-
OPENROUTER_API_KEY=sk-or-... oh --model openrouter/meta-llama/llama-3-70b
|
|
538
|
-
|
|
539
|
-
# llama.cpp / GGUF
|
|
540
|
-
oh --model llamacpp/my-model
|
|
541
|
-
|
|
542
|
-
# LM Studio
|
|
543
|
-
oh --model lmstudio/my-model
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
### llama.cpp / GGUF (local, no Ollama needed)
|
|
547
|
-
|
|
548
|
-
For direct GGUF support via `llama-server`, without the overhead of Ollama. Often faster for large models.
|
|
549
|
-
|
|
550
|
-
**Prerequisites:**
|
|
551
|
-
- Install llama.cpp: `brew install llama.cpp` or download from [github.com/ggml-org/llama.cpp](https://github.com/ggml-org/llama.cpp)
|
|
552
|
-
- Download a GGUF model (e.g., from [HuggingFace](https://huggingface.co))
|
|
553
|
-
|
|
554
|
-
**Start llama-server:**
|
|
555
|
-
```bash
|
|
556
|
-
llama-server --model ./your-model.gguf --port 8080 --alias my-model
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
**Configure via `oh init`:**
|
|
560
|
-
- Run `oh init` and select "llama.cpp / GGUF" when prompted
|
|
561
|
-
|
|
562
|
-
**Or configure manually** in `.oh/config.yaml`:
|
|
563
|
-
```yaml
|
|
564
|
-
provider: llamacpp
|
|
565
|
-
model: my-model
|
|
566
|
-
baseUrl: http://localhost:8080
|
|
567
|
-
permissionMode: ask
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
**Run:**
|
|
571
|
-
```bash
|
|
572
|
-
oh
|
|
573
|
-
oh --model llamacpp/my-model
|
|
574
|
-
oh models # list available models
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
## Configuration Hierarchy
|
|
578
|
-
|
|
579
|
-
Config is loaded in layers (later overrides earlier):
|
|
580
|
-
|
|
581
|
-
1. **Global** `~/.oh/config.yaml` — default provider, model, theme for all projects
|
|
582
|
-
2. **Project** `.oh/config.yaml` — project-specific settings
|
|
583
|
-
3. **Local** `.oh/config.local.yaml` — personal overrides (gitignored)
|
|
584
|
-
|
|
585
|
-
Set your default provider once globally:
|
|
586
|
-
|
|
587
|
-
```yaml
|
|
588
|
-
# ~/.oh/config.yaml
|
|
589
|
-
provider: ollama
|
|
590
|
-
model: llama3
|
|
591
|
-
permissionMode: ask
|
|
592
|
-
theme: dark
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
Then per-project configs only need what's different:
|
|
596
|
-
|
|
597
|
-
```yaml
|
|
598
|
-
# .oh/config.yaml
|
|
599
|
-
model: codellama # override just the model
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
## Project Rules
|
|
603
|
-
|
|
604
|
-
Create `.oh/RULES.md` in any repo (or run `oh init`):
|
|
605
|
-
|
|
606
|
-
```markdown
|
|
607
|
-
- Always run tests after changes
|
|
608
|
-
- Use strict TypeScript
|
|
609
|
-
- Never commit to main directly
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
Rules load automatically into every session.
|
|
613
|
-
|
|
614
|
-
## Skills & Plugins
|
|
615
|
-
|
|
616
|
-
### Skills
|
|
617
|
-
|
|
618
|
-
Skills are markdown files with YAML frontmatter that add reusable behaviors:
|
|
619
|
-
|
|
620
|
-
```markdown
|
|
621
|
-
---
|
|
622
|
-
name: deploy
|
|
623
|
-
description: Deploy the application to production
|
|
624
|
-
trigger: deploy
|
|
625
|
-
tools: [Bash, Read]
|
|
626
|
-
---
|
|
627
|
-
|
|
628
|
-
Run the deploy script with health checks...
|
|
629
|
-
```
|
|
630
|
-
|
|
631
|
-
**Locations** (searched in order):
|
|
632
|
-
1. `.oh/skills/` — project-level skills
|
|
633
|
-
2. `~/.oh/skills/` — global skills (available in all projects)
|
|
634
|
-
|
|
635
|
-
Skills auto-trigger when the user's message contains the trigger keyword, or can be invoked explicitly with `/skill deploy`.
|
|
636
|
-
|
|
637
|
-
### Plugins
|
|
638
|
-
|
|
639
|
-
Plugins are npm packages that bundle skills, hooks, and MCP servers:
|
|
640
|
-
|
|
641
|
-
```json
|
|
642
|
-
{
|
|
643
|
-
"name": "my-openharness-plugin",
|
|
644
|
-
"version": "1.0.0",
|
|
645
|
-
"skills": ["skills/deploy.md", "skills/review.md"],
|
|
646
|
-
"hooks": {
|
|
647
|
-
"sessionStart": "scripts/setup.sh"
|
|
648
|
-
},
|
|
649
|
-
"mcpServers": [
|
|
650
|
-
{ "name": "my-api", "command": "npx", "args": ["-y", "@my-org/mcp-server"] }
|
|
651
|
-
]
|
|
652
|
-
}
|
|
653
|
-
```
|
|
654
|
-
|
|
655
|
-
Save as `openharness-plugin.json` in your npm package root. Install with `npm install`, and openHarness discovers it automatically from `node_modules/`.
|
|
656
|
-
|
|
657
|
-
## How It Works
|
|
658
|
-
|
|
659
|
-
```mermaid
|
|
660
|
-
graph LR
|
|
661
|
-
User[User Input] --> REPL[REPL Loop]
|
|
662
|
-
REPL --> Query[Query Engine]
|
|
663
|
-
Query --> Provider[LLM Provider]
|
|
664
|
-
Provider --> LLM[Ollama / OpenAI / Anthropic]
|
|
665
|
-
LLM --> Tools[Tool Execution]
|
|
666
|
-
Tools --> Permissions{Permission Check}
|
|
667
|
-
Permissions -->|Approved| Execute[Run Tool]
|
|
668
|
-
Permissions -->|Blocked| Deny[Deny & Report]
|
|
669
|
-
Execute --> Response[Stream Response]
|
|
670
|
-
Response --> REPL
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
## FAQ
|
|
674
|
-
|
|
675
|
-
**Does it work offline?**
|
|
676
|
-
Yes. Use Ollama with a local model — no internet or API key needed.
|
|
677
|
-
|
|
678
|
-
**How much does it cost?**
|
|
679
|
-
Free. OpenHarness is MIT licensed. You bring your own API key (BYOK) for cloud models, or use Ollama for free.
|
|
680
|
-
|
|
681
|
-
**Is it safe?**
|
|
682
|
-
Yes. 7 permission modes control what tools can do. Bash commands are analyzed by an AST parser that blocks destructive patterns (`rm -rf`, `curl | bash`, etc.). Every file change is checkpointed and reversible with `/rewind`.
|
|
683
|
-
|
|
684
|
-
**Can I use it in CI/CD?**
|
|
685
|
-
Yes. Use `oh -p "prompt" --auto` for headless execution, or the built-in GitHub Action for PR reviews.
|
|
686
|
-
|
|
687
|
-
**Does it support my language/framework?**
|
|
688
|
-
Yes. OpenHarness is language-agnostic — it reads, writes, and executes code in any language. Syntax highlighting covers 20+ languages.
|
|
689
|
-
|
|
690
|
-
**How does it compare to Claude Code?**
|
|
691
|
-
~90% feature parity for CLI use cases. Main advantage: works with ANY LLM (not just Anthropic). See the [comparison table](#why-openharness) above.
|
|
692
|
-
|
|
693
|
-
## Install
|
|
694
|
-
|
|
695
|
-
Requires **Node.js 18+**.
|
|
696
|
-
|
|
697
|
-
```bash
|
|
698
|
-
# From npm
|
|
699
|
-
npm install -g @zhijiewang/openharness
|
|
700
|
-
|
|
701
|
-
# From source
|
|
702
|
-
git clone https://github.com/zhijiewong/openharness.git
|
|
703
|
-
cd openharness
|
|
704
|
-
npm install && npm install -g .
|
|
705
|
-
```
|
|
706
|
-
|
|
707
|
-
## Development
|
|
708
|
-
|
|
709
|
-
```bash
|
|
710
|
-
npm install
|
|
711
|
-
npx tsx src/main.tsx # run in dev mode
|
|
712
|
-
npx tsc --noEmit # type check
|
|
713
|
-
npm test # run tests
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
### Adding a tool
|
|
717
|
-
|
|
718
|
-
Create `src/tools/YourTool/index.ts` implementing the `Tool` interface with a Zod input schema, register it in `src/tools.ts`.
|
|
719
|
-
|
|
720
|
-
### Adding a provider
|
|
721
|
-
|
|
722
|
-
Create `src/providers/yourprovider.ts` implementing the `Provider` interface, add a case in `src/providers/index.ts`.
|
|
723
|
-
|
|
724
|
-
## Contributing
|
|
725
|
-
|
|
726
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
727
|
-
|
|
728
|
-
## Community
|
|
729
|
-
|
|
730
|
-
Join the OpenHarness community to get help, share your workflows, and discuss the future of AI coding agents!
|
|
731
|
-
|
|
732
|
-
| Platform | Details & Links |
|
|
733
|
-
| :--- | :--- |
|
|
734
|
-
| 🟣 **Discord** | [**Join our Discord Server**](https://discord.gg/ezVrqy3qu) to chat with developers and get real-time support. |
|
|
735
|
-
| 🔵 **Feishu / Lark** | Scan the QR code below to collaborate with the community:<br><br><img src="https://github.com/user-attachments/assets/54ade077-22ad-45d2-b38a-623464677d53" width="160" alt="Feishu Group QR Code"> |
|
|
736
|
-
| 🟢 **WeChat** | Scan the QR code below to join our WeChat group:<br><br><img src="https://github.com/user-attachments/assets/adcf291a-9ffe-4738-8608-f46a21e18db0" width="160" alt="WeChat Group QR Code"> |
|
|
737
|
-
|
|
738
|
-
## License
|
|
739
|
-
|
|
740
|
-
MIT
|
|
741
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo-256.png" alt="openHarness logo" width="128" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# OpenHarness
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
___
|
|
9
|
+
/ \
|
|
10
|
+
( ) ___ ___ ___ _ _ _ _ _ ___ _ _ ___ ___ ___
|
|
11
|
+
`~w~` / _ \| _ \| __| \| | || | /_\ | _ \ \| | __/ __/ __|
|
|
12
|
+
(( )) | (_) | _/| _|| .` | __ |/ _ \| / .` | _|\__ \__ \
|
|
13
|
+
))(( \___/|_| |___|_|\_|_||_/_/ \_\_|_\_|\_|___|___/___/
|
|
14
|
+
(( ))
|
|
15
|
+
`--`
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
AI coding agent in your terminal. Works with any LLM -- free local models or cloud APIs.
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="assets/openharness_v0.11.1_4.gif" alt="OpenHarness demo" width="800" />
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
[](https://www.npmjs.com/package/@zhijiewang/openharness) [](https://www.npmjs.com/package/@zhijiewang/openharness) [](LICENSE)     [](https://github.com/zhijiewong/openharness) [](https://github.com/zhijiewong/openharness/issues) [](https://github.com/zhijiewong/openharness/pulls)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Table of Contents
|
|
29
|
+
|
|
30
|
+
- [Quick Start](#quick-start)
|
|
31
|
+
- [Why OpenHarness?](#why-openharness)
|
|
32
|
+
- [Terminal UI](#terminal-ui)
|
|
33
|
+
- [Tools (35)](#tools-35)
|
|
34
|
+
- [Slash Commands (33)](#slash-commands-33)
|
|
35
|
+
- [Permission Modes](#permission-modes)
|
|
36
|
+
- [Hooks](#hooks)
|
|
37
|
+
- [Checkpoints & Rewind](#checkpoints--rewind)
|
|
38
|
+
- [Agent Roles](#agent-roles)
|
|
39
|
+
- [Headless Mode & CI/CD](#headless-mode)
|
|
40
|
+
- [Cybergotchi](#cybergotchi)
|
|
41
|
+
- [MCP Servers](#mcp-servers)
|
|
42
|
+
- [Providers](#providers)
|
|
43
|
+
- [FAQ](#faq)
|
|
44
|
+
- [Install](#install)
|
|
45
|
+
- [Development](#development)
|
|
46
|
+
- [Contributing](#contributing)
|
|
47
|
+
- [Community](#community)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install -g @zhijiewang/openharness
|
|
55
|
+
oh
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
That's it. OpenHarness auto-detects Ollama and starts chatting. No API key needed.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
oh init # interactive setup wizard (provider + cybergotchi)
|
|
62
|
+
oh # auto-detect local model
|
|
63
|
+
oh --model ollama/qwen2.5:7b # specific model
|
|
64
|
+
oh --model gpt-4o # cloud model (needs OPENAI_API_KEY)
|
|
65
|
+
oh --trust # auto-approve all tool calls
|
|
66
|
+
oh --auto # auto-approve, block dangerous bash
|
|
67
|
+
oh -p "fix the tests" --trust # headless mode (single prompt, exit)
|
|
68
|
+
oh run "review code" --json # CI/CD with JSON output
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**In-session commands:**
|
|
72
|
+
```
|
|
73
|
+
/rewind # undo last AI file change (checkpoint restore)
|
|
74
|
+
/roles # list agent specializations
|
|
75
|
+
/vim # toggle vim mode
|
|
76
|
+
Ctrl+O # flush transcript to scrollback for review
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Why OpenHarness?
|
|
80
|
+
|
|
81
|
+
Most AI coding agents are locked to one provider or cost $20+/month. OpenHarness works with any LLM -- run it free with Ollama on your own machine, or connect to any cloud API. Every AI edit is git-committed and reversible with `/undo`.
|
|
82
|
+
|
|
83
|
+
| | OpenHarness | Claude Code | Aider | OpenCode |
|
|
84
|
+
|---|---|---|---|---|
|
|
85
|
+
| Any LLM | Yes (Ollama, OpenAI, Anthropic, OpenRouter, any OpenAI-compatible) | Anthropic only | Yes | Yes |
|
|
86
|
+
| Free local models | Ollama native | No | Yes | Yes |
|
|
87
|
+
| Tools | 35 with permission gates | 43+ | File-focused | 20+ |
|
|
88
|
+
| Permission modes | 7 (ask, trust, deny, acceptEdits, plan, auto, bypass) | 7 | Basic | Basic |
|
|
89
|
+
| Git integration | Auto-commit + /undo + /rewind checkpoints | Yes | Deep git | Basic |
|
|
90
|
+
| Slash commands | 30+ built-in | 80+ | Some | Some |
|
|
91
|
+
| Headless/CI mode | `oh -p "prompt"` or `oh run --json` | Yes | Yes | Yes |
|
|
92
|
+
| GitHub Action | Built-in PR review action | Yes | No | No |
|
|
93
|
+
| Agent roles | 6 specializations (reviewer, tester, debugger...) | Yes | No | No |
|
|
94
|
+
| Vim mode | hjkl, w/b/e, 0/$, x, d, i/a/I/A/o | Full vim | No | No |
|
|
95
|
+
| Prompt caching | Anthropic cache_control | Yes | No | No |
|
|
96
|
+
| Bash security | AST-based command analysis | AST analysis | No | No |
|
|
97
|
+
| Companion | Cybergotchi virtual pet | Basic | No | No |
|
|
98
|
+
| Terminal UI | Sequential renderer (Ink pattern) | React + Ink | Basic | BubbleTea |
|
|
99
|
+
| Language | TypeScript | TypeScript | Python | Go |
|
|
100
|
+
| License | MIT | Proprietary | Apache 2.0 | MIT |
|
|
101
|
+
| Price | Free (BYOK) | $20+/month | Free (BYOK) | Free (BYOK) |
|
|
102
|
+
|
|
103
|
+
## Terminal UI
|
|
104
|
+
|
|
105
|
+
OpenHarness features a sequential terminal renderer inspired by Ink/Claude Code's default mode. Completed messages flush to native scrollback (scrollable), while the live area (streaming, spinner, input) rewrites in-place using relative cursor movement.
|
|
106
|
+
|
|
107
|
+
### Keybindings
|
|
108
|
+
|
|
109
|
+
| Key | Action |
|
|
110
|
+
|-----|--------|
|
|
111
|
+
| `Enter` | Submit prompt |
|
|
112
|
+
| `Alt+Enter` | Insert newline (multi-line input) |
|
|
113
|
+
| `↑` / `↓` | Navigate input history |
|
|
114
|
+
| `Ctrl+C` | Cancel current request / exit |
|
|
115
|
+
| `Ctrl+A` / `Ctrl+E` | Jump to start / end of input |
|
|
116
|
+
| `Ctrl+O` | Toggle thinking block expansion |
|
|
117
|
+
| `Ctrl+K` | Toggle code block expansion in messages |
|
|
118
|
+
| `Tab` | Autocomplete slash commands / file paths / cycle tool outputs |
|
|
119
|
+
| `/vim` | Toggle Vim mode (normal/insert) |
|
|
120
|
+
|
|
121
|
+
Scrolling is handled by the terminal's native scrollbar. Completed messages flow into the terminal scrollback buffer. Use your terminal's search (e.g., `Ctrl+Shift+F` in VS Code) to search conversation history.
|
|
122
|
+
|
|
123
|
+
### Features
|
|
124
|
+
|
|
125
|
+
- **Markdown rendering** — headings, code blocks, bold, italic, lists, tables, blockquotes, links
|
|
126
|
+
- **Syntax highlighting** — keywords, strings, comments, numbers, types (JS/TS/Python/Rust/Go and 20+ languages)
|
|
127
|
+
- **Collapsible code blocks** — blocks over 8 lines auto-collapse; `Ctrl+K` to expand all
|
|
128
|
+
- **Collapsible thinking** — thinking blocks collapse to a one-line summary after completion; `Ctrl+O` to expand
|
|
129
|
+
- **Shimmer spinner** — animated "Thinking" indicator with color transitions (magenta → yellow at 30s → red at 60s)
|
|
130
|
+
- **Tool call display** — args preview, live streaming output, result summaries (line counts, elapsed time), expand/collapse with `Tab`
|
|
131
|
+
- **Permission prompts** — bordered box with risk coloring, bold colored **Y**es/**N**o/**D**iff keys, syntax-highlighted inline diffs
|
|
132
|
+
- **Status line** — model name, token count, cost, context usage bar (customizable via config)
|
|
133
|
+
- **Context warning** — yellow alert when context window exceeds 75%
|
|
134
|
+
- **Native terminal scrollbar** — completed messages flow into scrollback; use your terminal's scrollbar and search
|
|
135
|
+
- **Multi-line input** — `Alt+Enter` for newlines; paste detection auto-inserts newlines
|
|
136
|
+
- **Autocomplete** — slash commands and file paths with descriptions; Tab to cycle
|
|
137
|
+
- **File path autocomplete** — Tab-completes paths with `[dir]`/`[file]` indicators
|
|
138
|
+
- **Session browser** — `/browse` to interactively browse and resume past sessions
|
|
139
|
+
- **Companion mascot** — animated Cybergotchi in the footer (toggle with `/companion off|on`)
|
|
140
|
+
|
|
141
|
+
### Themes
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
oh --light # light theme for bright terminals
|
|
145
|
+
/theme light # switch mid-session (saved automatically)
|
|
146
|
+
/theme dark # switch back
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Theme preference is saved to `.oh/config.yaml` and persists across sessions.
|
|
150
|
+
|
|
151
|
+
### Custom Status Line
|
|
152
|
+
|
|
153
|
+
Customize the status bar format in `.oh/config.yaml`:
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
statusLineFormat: '{model} │ {tokens} │ {cost} │ {ctx}'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XXXX), `{ctx}` (context usage bar). Empty sections are automatically collapsed.
|
|
160
|
+
|
|
161
|
+
## Tools (35)
|
|
162
|
+
|
|
163
|
+
| Tool | Risk | Description |
|
|
164
|
+
|------|------|-------------|
|
|
165
|
+
| **Core** | | |
|
|
166
|
+
| Bash | high | Execute shell commands with live streaming output (AST safety analysis) |
|
|
167
|
+
| Read | low | Read files with line ranges, PDF support |
|
|
168
|
+
| ImageRead | low | Read images/PDFs for multimodal analysis |
|
|
169
|
+
| Write | medium | Create or overwrite files |
|
|
170
|
+
| Edit | medium | Search-and-replace edits |
|
|
171
|
+
| MultiEdit | medium | Atomic multi-file edits (all succeed or none) |
|
|
172
|
+
| Glob | low | Find files by pattern |
|
|
173
|
+
| Grep | low | Regex content search with context lines |
|
|
174
|
+
| LS | low | List directory contents with sizes |
|
|
175
|
+
| **Web** | | |
|
|
176
|
+
| WebFetch | medium | Fetch URL content (SSRF-protected) |
|
|
177
|
+
| WebSearch | medium | Search the web |
|
|
178
|
+
| RemoteTrigger | high | HTTP requests to webhooks/APIs |
|
|
179
|
+
| **Tasks** | | |
|
|
180
|
+
| TaskCreate | low | Create structured tasks |
|
|
181
|
+
| TaskUpdate | low | Update task status |
|
|
182
|
+
| TaskList | low | List all tasks |
|
|
183
|
+
| TaskGet | low | Get task details |
|
|
184
|
+
| TaskStop | low | Stop a running task |
|
|
185
|
+
| TaskOutput | low | Get task output |
|
|
186
|
+
| **Agents** | | |
|
|
187
|
+
| Agent | medium | Spawn a sub-agent (with role specialization) |
|
|
188
|
+
| ParallelAgent | medium | Dispatch multiple agents with DAG dependencies |
|
|
189
|
+
| SendMessage | low | Agent-to-agent peer messaging |
|
|
190
|
+
| AskUser | low | Ask user a question with options |
|
|
191
|
+
| **Scheduling** | | |
|
|
192
|
+
| CronCreate | medium | Schedule recurring tasks |
|
|
193
|
+
| CronDelete | medium | Remove scheduled tasks |
|
|
194
|
+
| CronList | low | List all scheduled tasks |
|
|
195
|
+
| **Planning** | | |
|
|
196
|
+
| EnterPlanMode | low | Enter structured planning mode |
|
|
197
|
+
| ExitPlanMode | low | Exit planning mode |
|
|
198
|
+
| **Code Intelligence** | | |
|
|
199
|
+
| Diagnostics | low | LSP-based code diagnostics |
|
|
200
|
+
| NotebookEdit | medium | Edit Jupyter notebooks |
|
|
201
|
+
| **Memory & Discovery** | | |
|
|
202
|
+
| Memory | low | Save/list/search persistent memories |
|
|
203
|
+
| Skill | low | Invoke a skill from .oh/skills/ |
|
|
204
|
+
| ToolSearch | low | Find tools by description |
|
|
205
|
+
| **Git Worktrees** | | |
|
|
206
|
+
| EnterWorktree | medium | Create isolated git worktree |
|
|
207
|
+
| ExitWorktree | medium | Remove a git worktree |
|
|
208
|
+
| **Process** | | |
|
|
209
|
+
| KillProcess | high | Stop processes by PID or name |
|
|
210
|
+
|
|
211
|
+
Low-risk read-only tools auto-approve. Medium and high risk tools require confirmation in `ask` mode. Use `--trust` or `--auto` to skip prompts.
|
|
212
|
+
|
|
213
|
+
## Slash Commands (33)
|
|
214
|
+
|
|
215
|
+
Type these during a chat session. Aliases: `/q` exit, `/h` help, `/c` commit, `/m` model, `/s` status.
|
|
216
|
+
|
|
217
|
+
**Session:**
|
|
218
|
+
| Command | Description |
|
|
219
|
+
|---------|-------------|
|
|
220
|
+
| `/clear` | Clear conversation history |
|
|
221
|
+
| `/compact` | Compress conversation to free context |
|
|
222
|
+
| `/export` | Export conversation to markdown |
|
|
223
|
+
| `/history [n]` | List recent sessions; `/history search <term>` to search |
|
|
224
|
+
| `/browse` | Interactive session browser with preview |
|
|
225
|
+
| `/resume <id>` | Resume a saved session |
|
|
226
|
+
| `/fork` | Fork current session |
|
|
227
|
+
|
|
228
|
+
**Git:**
|
|
229
|
+
| Command | Description |
|
|
230
|
+
|---------|-------------|
|
|
231
|
+
| `/diff` | Show uncommitted git changes |
|
|
232
|
+
| `/undo` | Undo last AI commit |
|
|
233
|
+
| `/commit [msg]` | Create a git commit |
|
|
234
|
+
| `/log` | Show recent git commits |
|
|
235
|
+
|
|
236
|
+
**Info:**
|
|
237
|
+
| Command | Description |
|
|
238
|
+
|---------|-------------|
|
|
239
|
+
| `/help` | Show all available commands (categorized) |
|
|
240
|
+
| `/cost` | Show session cost and token usage |
|
|
241
|
+
| `/status` | Show model, mode, git branch, MCP servers |
|
|
242
|
+
| `/config` | Show configuration |
|
|
243
|
+
| `/files` | List files in context |
|
|
244
|
+
| `/model <name>` | Switch model mid-session |
|
|
245
|
+
| `/memory` | View and search memories |
|
|
246
|
+
|
|
247
|
+
**Settings:**
|
|
248
|
+
| Command | Description |
|
|
249
|
+
|---------|-------------|
|
|
250
|
+
| `/theme dark\|light` | Switch theme (saved to config) |
|
|
251
|
+
| `/vim` | Toggle Vim mode |
|
|
252
|
+
| `/companion off\|on` | Toggle companion visibility |
|
|
253
|
+
|
|
254
|
+
**AI:**
|
|
255
|
+
| Command | Description |
|
|
256
|
+
|---------|-------------|
|
|
257
|
+
| `/plan <task>` | Enter plan mode |
|
|
258
|
+
| `/review` | Review recent code changes |
|
|
259
|
+
|
|
260
|
+
**Pet:**
|
|
261
|
+
| Command | Description |
|
|
262
|
+
|---------|-------------|
|
|
263
|
+
| `/cybergotchi` | Feed, pet, rest, status, rename, or reset your companion |
|
|
264
|
+
|
|
265
|
+
## Permission Modes
|
|
266
|
+
|
|
267
|
+
Control how aggressively OpenHarness auto-approves tool calls:
|
|
268
|
+
|
|
269
|
+
| Mode | Flag | Behavior |
|
|
270
|
+
|------|------|----------|
|
|
271
|
+
| `ask` | `--permission-mode ask` | Prompt for medium/high risk operations (default) |
|
|
272
|
+
| `trust` | `--trust` | Auto-approve everything |
|
|
273
|
+
| `deny` | `--deny` | Only allow low-risk read-only operations |
|
|
274
|
+
| `acceptEdits` | `--permission-mode acceptEdits` | Auto-approve file edits, ask for Bash/WebFetch/Agent |
|
|
275
|
+
| `plan` | `--permission-mode plan` | Read-only mode — block all write operations |
|
|
276
|
+
| `auto` | `--auto` | Auto-approve all, block dangerous bash (AST-analyzed) |
|
|
277
|
+
| `bypassPermissions` | `--permission-mode bypassPermissions` | Approve everything unconditionally (CI only) |
|
|
278
|
+
|
|
279
|
+
Bash commands are analyzed by a lightweight AST parser that detects destructive patterns (`rm -rf`, `git push --force`, `curl | bash`, etc.) and adjusts risk level accordingly.
|
|
280
|
+
|
|
281
|
+
Set permanently in `.oh/config.yaml`: `permissionMode: 'acceptEdits'`
|
|
282
|
+
|
|
283
|
+
## Hooks
|
|
284
|
+
|
|
285
|
+
Run shell scripts automatically at key session events by adding a `hooks` block to `.oh/config.yaml`:
|
|
286
|
+
|
|
287
|
+
```yaml
|
|
288
|
+
hooks:
|
|
289
|
+
- event: sessionStart
|
|
290
|
+
command: "echo 'Session started' >> ~/.oh/session.log"
|
|
291
|
+
|
|
292
|
+
- event: preToolUse
|
|
293
|
+
command: "scripts/check-tool.sh"
|
|
294
|
+
match: Bash # optional: only trigger for this tool name
|
|
295
|
+
|
|
296
|
+
- event: postToolUse
|
|
297
|
+
command: "scripts/after-tool.sh"
|
|
298
|
+
|
|
299
|
+
- event: sessionEnd
|
|
300
|
+
command: "scripts/cleanup.sh"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Event types:**
|
|
304
|
+
- `sessionStart` — fires once when the session begins
|
|
305
|
+
- `preToolUse` — fires before each tool call; **exit code 1 blocks the tool** and returns an error to the model
|
|
306
|
+
- `postToolUse` — fires after each tool call completes
|
|
307
|
+
- `sessionEnd` — fires when the session ends
|
|
308
|
+
|
|
309
|
+
**Environment variables** available to hook scripts:
|
|
310
|
+
|
|
311
|
+
| Variable | Description |
|
|
312
|
+
|----------|-------------|
|
|
313
|
+
| `OH_EVENT` | Event type (`sessionStart`, `preToolUse`, etc.) |
|
|
314
|
+
| `OH_TOOL_NAME` | Name of the tool being called (tool events only) |
|
|
315
|
+
| `OH_TOOL_ARGS` | JSON-encoded tool arguments (tool events only) |
|
|
316
|
+
| `OH_TOOL_OUTPUT` | JSON-encoded tool output (`postToolUse` only) |
|
|
317
|
+
|
|
318
|
+
Use `match` to restrict a hook to a specific tool name (e.g., `match: Bash` only triggers for the Bash tool).
|
|
319
|
+
|
|
320
|
+
## Cybergotchi
|
|
321
|
+
|
|
322
|
+
OpenHarness ships with a Tamagotchi-style companion that lives in the side panel. It reacts to your session in real time — celebrating streaks, complaining when tools fail, and getting hungry if you ignore it.
|
|
323
|
+
|
|
324
|
+
**Hatch one:**
|
|
325
|
+
```
|
|
326
|
+
oh init # wizard includes cybergotchi setup
|
|
327
|
+
/cybergotchi # or hatch mid-session
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Commands:**
|
|
331
|
+
```
|
|
332
|
+
/cybergotchi feed # +30 hunger
|
|
333
|
+
/cybergotchi pet # +20 happiness
|
|
334
|
+
/cybergotchi rest # +40 energy
|
|
335
|
+
/cybergotchi status # show needs + lifetime stats
|
|
336
|
+
/cybergotchi rename # give it a new name
|
|
337
|
+
/cybergotchi reset # start over with a new species
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Needs** decay over time (hunger fastest, happiness slowest). Feed and pet your gotchi to keep it happy.
|
|
341
|
+
|
|
342
|
+
**Evolution** — your gotchi evolves based on lifetime milestones:
|
|
343
|
+
- Stage 1 (✦ magenta): 10 sessions or 50 commits
|
|
344
|
+
- Stage 2 (★ yellow + crown): 100 tasks completed or a 25-tool streak
|
|
345
|
+
|
|
346
|
+
**18 species** to choose from: duck, cat, owl, penguin, rabbit, turtle, snail, octopus, axolotl, cactus, mushroom, chonk, capybara, goose, and more.
|
|
347
|
+
|
|
348
|
+
## MCP Servers
|
|
349
|
+
|
|
350
|
+
Connect any MCP (Model Context Protocol) server by editing `.oh/config.yaml`:
|
|
351
|
+
|
|
352
|
+
```yaml
|
|
353
|
+
provider: anthropic
|
|
354
|
+
model: claude-sonnet-4-6
|
|
355
|
+
permissionMode: ask
|
|
356
|
+
mcpServers:
|
|
357
|
+
- name: filesystem
|
|
358
|
+
command: npx
|
|
359
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
360
|
+
- name: github
|
|
361
|
+
command: npx
|
|
362
|
+
args: ["-y", "@modelcontextprotocol/server-github"]
|
|
363
|
+
env:
|
|
364
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: ghp_...
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
MCP tools appear alongside built-in tools. `/status` shows connected servers.
|
|
368
|
+
|
|
369
|
+
**MCP Server Registry** — browse and install from a curated catalog:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
/mcp-registry # browse all available servers
|
|
373
|
+
/mcp-registry github # show install config for a specific server
|
|
374
|
+
/mcp-registry database # search by category
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Categories: filesystem, git, database, api, search, productivity, dev-tools, ai.
|
|
378
|
+
|
|
379
|
+
## Git Integration
|
|
380
|
+
|
|
381
|
+
OpenHarness auto-commits AI edits in git repos:
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
oh: Edit src/app.ts # auto-committed with "oh:" prefix
|
|
385
|
+
oh: Write tests/app.test.ts
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
- Every AI file change is committed automatically
|
|
389
|
+
- `/undo` reverts the last AI commit (only OH commits, never yours)
|
|
390
|
+
- `/diff` shows what changed
|
|
391
|
+
- Your dirty files are safe — committed separately before AI edits
|
|
392
|
+
|
|
393
|
+
## Checkpoints & Rewind
|
|
394
|
+
|
|
395
|
+
Every file modification is automatically checkpointed before execution. If something goes wrong:
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
/rewind # restore files from the last checkpoint
|
|
399
|
+
/undo # revert the last AI git commit
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Checkpoints are stored in `.oh/checkpoints/` and cover FileWrite, FileEdit, and Bash commands that modify files.
|
|
403
|
+
|
|
404
|
+
## Verification Loops
|
|
405
|
+
|
|
406
|
+
After every file edit (Edit, Write, MultiEdit), openHarness automatically runs language-appropriate lint/typecheck commands and feeds the results back into the agent context. This is the single highest-impact harness engineering pattern — research shows 2-3x quality improvement from automated feedback.
|
|
407
|
+
|
|
408
|
+
**Auto-detection** — if your project has `tsconfig.json`, `.eslintrc*`, `pyproject.toml`, `go.mod`, or `Cargo.toml`, verification rules are detected automatically. No configuration needed.
|
|
409
|
+
|
|
410
|
+
**Custom rules** via `.oh/config.yaml`:
|
|
411
|
+
|
|
412
|
+
```yaml
|
|
413
|
+
verification:
|
|
414
|
+
enabled: true # default: true (auto-detect)
|
|
415
|
+
mode: warn # 'warn' appends to output, 'block' marks as error
|
|
416
|
+
rules:
|
|
417
|
+
- extensions: [".ts", ".tsx"]
|
|
418
|
+
lint: "npx tsc --noEmit 2>&1 | head -20"
|
|
419
|
+
timeout: 15000
|
|
420
|
+
- extensions: [".py"]
|
|
421
|
+
lint: "ruff check {file} 2>&1 | head -10"
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
The agent sees `[Verification passed]` or `[Verification FAILED]` with the linter output after each edit, enabling self-correction.
|
|
425
|
+
|
|
426
|
+
## Memory Consolidation
|
|
427
|
+
|
|
428
|
+
On session exit, openHarness automatically prunes stale memories using temporal decay:
|
|
429
|
+
|
|
430
|
+
- Memories not accessed in 30+ days lose 0.1 relevance per 30-day period
|
|
431
|
+
- Memories below 0.1 relevance are permanently deleted
|
|
432
|
+
- Updated relevance scores are persisted to memory files
|
|
433
|
+
|
|
434
|
+
This keeps the memory system lean and relevant. Configure in `.oh/config.yaml`:
|
|
435
|
+
|
|
436
|
+
```yaml
|
|
437
|
+
memory:
|
|
438
|
+
consolidateOnExit: true # default: true
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Scheduled Tasks (Cron)
|
|
442
|
+
|
|
443
|
+
Create recurring tasks that run automatically in the background:
|
|
444
|
+
|
|
445
|
+
```
|
|
446
|
+
# Via slash commands
|
|
447
|
+
/cron list # show all scheduled tasks
|
|
448
|
+
/cron create "check-tests" # create a new task (interactive)
|
|
449
|
+
/cron delete <id> # remove a task
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Schedule syntax:** `every 5m`, `every 2h`, `every 1d`
|
|
453
|
+
|
|
454
|
+
The cron executor checks every 60 seconds for due tasks and runs them via sub-queries. Results are stored in `~/.oh/crons/history/`.
|
|
455
|
+
|
|
456
|
+
## Agent Roles
|
|
457
|
+
|
|
458
|
+
Dispatch specialized sub-agents for focused tasks:
|
|
459
|
+
|
|
460
|
+
```
|
|
461
|
+
/roles # list all available roles
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
| Role | Description | Tools |
|
|
465
|
+
|------|-------------|-------|
|
|
466
|
+
| `code-reviewer` | Find bugs, security issues, style problems | Read-only |
|
|
467
|
+
| `test-writer` | Generate unit and integration tests | Read + Write |
|
|
468
|
+
| `docs-writer` | Write documentation and comments | Read + Write + Edit |
|
|
469
|
+
| `debugger` | Systematic bug investigation | Read-only + Bash |
|
|
470
|
+
| `refactorer` | Simplify code without changing behavior | All file tools + Bash |
|
|
471
|
+
| `security-auditor` | OWASP, injection, secrets, CVE scanning | Read-only + Bash |
|
|
472
|
+
| `evaluator` | Evaluate code quality and run tests (read-only) | Read-only + Bash + Diagnostics |
|
|
473
|
+
| `planner` | Design step-by-step implementation plans | Read-only + Bash |
|
|
474
|
+
| `architect` | Analyze architecture and design structural changes | Read-only |
|
|
475
|
+
| `migrator` | Systematic codebase migrations and upgrades | All file tools + Bash |
|
|
476
|
+
|
|
477
|
+
Each role restricts the sub-agent to only its suggested tools. You can also pass `allowed_tools` explicitly:
|
|
478
|
+
|
|
479
|
+
```
|
|
480
|
+
Agent({ subagent_type: 'evaluator', prompt: 'Run all tests and report results' })
|
|
481
|
+
Agent({ allowed_tools: ['Read', 'Grep'], prompt: 'Search for all TODO comments' })
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Headless Mode
|
|
485
|
+
|
|
486
|
+
Run a single prompt without interactive UI — perfect for CI/CD and scripting:
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
# Chat command with -p flag (recommended)
|
|
490
|
+
oh -p "fix the failing tests" --model ollama/llama3 --trust
|
|
491
|
+
oh -p "review src/query.ts" --auto --output-format json
|
|
492
|
+
|
|
493
|
+
# Run command (alternative)
|
|
494
|
+
oh run "fix the failing tests" --model ollama/llama3 --trust
|
|
495
|
+
oh run "add error handling to api.ts" --json # JSON output
|
|
496
|
+
|
|
497
|
+
# Pipe stdin
|
|
498
|
+
cat error.log | oh run "what's wrong here?"
|
|
499
|
+
git diff | oh run "review these changes"
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### GitHub Action for PR Review
|
|
503
|
+
|
|
504
|
+
OpenHarness includes a built-in GitHub Action for automated code review:
|
|
505
|
+
|
|
506
|
+
```yaml
|
|
507
|
+
# .github/workflows/ai-review.yml
|
|
508
|
+
on:
|
|
509
|
+
pull_request:
|
|
510
|
+
types: [opened, synchronize]
|
|
511
|
+
|
|
512
|
+
jobs:
|
|
513
|
+
review:
|
|
514
|
+
runs-on: ubuntu-latest
|
|
515
|
+
steps:
|
|
516
|
+
- uses: actions/checkout@v4
|
|
517
|
+
with:
|
|
518
|
+
fetch-depth: 0
|
|
519
|
+
- uses: ./.github/actions/review
|
|
520
|
+
with:
|
|
521
|
+
model: 'claude-sonnet-4-6'
|
|
522
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Exit code 0 on success, 1 on failure.
|
|
526
|
+
|
|
527
|
+
## Providers
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
# Local (free, no API key needed)
|
|
531
|
+
oh --model ollama/llama3
|
|
532
|
+
oh --model ollama/qwen2.5:7b
|
|
533
|
+
|
|
534
|
+
# Cloud
|
|
535
|
+
OPENAI_API_KEY=sk-... oh --model gpt-4o
|
|
536
|
+
ANTHROPIC_API_KEY=sk-ant-... oh --model claude-sonnet-4-6
|
|
537
|
+
OPENROUTER_API_KEY=sk-or-... oh --model openrouter/meta-llama/llama-3-70b
|
|
538
|
+
|
|
539
|
+
# llama.cpp / GGUF
|
|
540
|
+
oh --model llamacpp/my-model
|
|
541
|
+
|
|
542
|
+
# LM Studio
|
|
543
|
+
oh --model lmstudio/my-model
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### llama.cpp / GGUF (local, no Ollama needed)
|
|
547
|
+
|
|
548
|
+
For direct GGUF support via `llama-server`, without the overhead of Ollama. Often faster for large models.
|
|
549
|
+
|
|
550
|
+
**Prerequisites:**
|
|
551
|
+
- Install llama.cpp: `brew install llama.cpp` or download from [github.com/ggml-org/llama.cpp](https://github.com/ggml-org/llama.cpp)
|
|
552
|
+
- Download a GGUF model (e.g., from [HuggingFace](https://huggingface.co))
|
|
553
|
+
|
|
554
|
+
**Start llama-server:**
|
|
555
|
+
```bash
|
|
556
|
+
llama-server --model ./your-model.gguf --port 8080 --alias my-model
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
**Configure via `oh init`:**
|
|
560
|
+
- Run `oh init` and select "llama.cpp / GGUF" when prompted
|
|
561
|
+
|
|
562
|
+
**Or configure manually** in `.oh/config.yaml`:
|
|
563
|
+
```yaml
|
|
564
|
+
provider: llamacpp
|
|
565
|
+
model: my-model
|
|
566
|
+
baseUrl: http://localhost:8080
|
|
567
|
+
permissionMode: ask
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
**Run:**
|
|
571
|
+
```bash
|
|
572
|
+
oh
|
|
573
|
+
oh --model llamacpp/my-model
|
|
574
|
+
oh models # list available models
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
## Configuration Hierarchy
|
|
578
|
+
|
|
579
|
+
Config is loaded in layers (later overrides earlier):
|
|
580
|
+
|
|
581
|
+
1. **Global** `~/.oh/config.yaml` — default provider, model, theme for all projects
|
|
582
|
+
2. **Project** `.oh/config.yaml` — project-specific settings
|
|
583
|
+
3. **Local** `.oh/config.local.yaml` — personal overrides (gitignored)
|
|
584
|
+
|
|
585
|
+
Set your default provider once globally:
|
|
586
|
+
|
|
587
|
+
```yaml
|
|
588
|
+
# ~/.oh/config.yaml
|
|
589
|
+
provider: ollama
|
|
590
|
+
model: llama3
|
|
591
|
+
permissionMode: ask
|
|
592
|
+
theme: dark
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
Then per-project configs only need what's different:
|
|
596
|
+
|
|
597
|
+
```yaml
|
|
598
|
+
# .oh/config.yaml
|
|
599
|
+
model: codellama # override just the model
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
## Project Rules
|
|
603
|
+
|
|
604
|
+
Create `.oh/RULES.md` in any repo (or run `oh init`):
|
|
605
|
+
|
|
606
|
+
```markdown
|
|
607
|
+
- Always run tests after changes
|
|
608
|
+
- Use strict TypeScript
|
|
609
|
+
- Never commit to main directly
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
Rules load automatically into every session.
|
|
613
|
+
|
|
614
|
+
## Skills & Plugins
|
|
615
|
+
|
|
616
|
+
### Skills
|
|
617
|
+
|
|
618
|
+
Skills are markdown files with YAML frontmatter that add reusable behaviors:
|
|
619
|
+
|
|
620
|
+
```markdown
|
|
621
|
+
---
|
|
622
|
+
name: deploy
|
|
623
|
+
description: Deploy the application to production
|
|
624
|
+
trigger: deploy
|
|
625
|
+
tools: [Bash, Read]
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
Run the deploy script with health checks...
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
**Locations** (searched in order):
|
|
632
|
+
1. `.oh/skills/` — project-level skills
|
|
633
|
+
2. `~/.oh/skills/` — global skills (available in all projects)
|
|
634
|
+
|
|
635
|
+
Skills auto-trigger when the user's message contains the trigger keyword, or can be invoked explicitly with `/skill deploy`.
|
|
636
|
+
|
|
637
|
+
### Plugins
|
|
638
|
+
|
|
639
|
+
Plugins are npm packages that bundle skills, hooks, and MCP servers:
|
|
640
|
+
|
|
641
|
+
```json
|
|
642
|
+
{
|
|
643
|
+
"name": "my-openharness-plugin",
|
|
644
|
+
"version": "1.0.0",
|
|
645
|
+
"skills": ["skills/deploy.md", "skills/review.md"],
|
|
646
|
+
"hooks": {
|
|
647
|
+
"sessionStart": "scripts/setup.sh"
|
|
648
|
+
},
|
|
649
|
+
"mcpServers": [
|
|
650
|
+
{ "name": "my-api", "command": "npx", "args": ["-y", "@my-org/mcp-server"] }
|
|
651
|
+
]
|
|
652
|
+
}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
Save as `openharness-plugin.json` in your npm package root. Install with `npm install`, and openHarness discovers it automatically from `node_modules/`.
|
|
656
|
+
|
|
657
|
+
## How It Works
|
|
658
|
+
|
|
659
|
+
```mermaid
|
|
660
|
+
graph LR
|
|
661
|
+
User[User Input] --> REPL[REPL Loop]
|
|
662
|
+
REPL --> Query[Query Engine]
|
|
663
|
+
Query --> Provider[LLM Provider]
|
|
664
|
+
Provider --> LLM[Ollama / OpenAI / Anthropic]
|
|
665
|
+
LLM --> Tools[Tool Execution]
|
|
666
|
+
Tools --> Permissions{Permission Check}
|
|
667
|
+
Permissions -->|Approved| Execute[Run Tool]
|
|
668
|
+
Permissions -->|Blocked| Deny[Deny & Report]
|
|
669
|
+
Execute --> Response[Stream Response]
|
|
670
|
+
Response --> REPL
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
## FAQ
|
|
674
|
+
|
|
675
|
+
**Does it work offline?**
|
|
676
|
+
Yes. Use Ollama with a local model — no internet or API key needed.
|
|
677
|
+
|
|
678
|
+
**How much does it cost?**
|
|
679
|
+
Free. OpenHarness is MIT licensed. You bring your own API key (BYOK) for cloud models, or use Ollama for free.
|
|
680
|
+
|
|
681
|
+
**Is it safe?**
|
|
682
|
+
Yes. 7 permission modes control what tools can do. Bash commands are analyzed by an AST parser that blocks destructive patterns (`rm -rf`, `curl | bash`, etc.). Every file change is checkpointed and reversible with `/rewind`.
|
|
683
|
+
|
|
684
|
+
**Can I use it in CI/CD?**
|
|
685
|
+
Yes. Use `oh -p "prompt" --auto` for headless execution, or the built-in GitHub Action for PR reviews.
|
|
686
|
+
|
|
687
|
+
**Does it support my language/framework?**
|
|
688
|
+
Yes. OpenHarness is language-agnostic — it reads, writes, and executes code in any language. Syntax highlighting covers 20+ languages.
|
|
689
|
+
|
|
690
|
+
**How does it compare to Claude Code?**
|
|
691
|
+
~90% feature parity for CLI use cases. Main advantage: works with ANY LLM (not just Anthropic). See the [comparison table](#why-openharness) above.
|
|
692
|
+
|
|
693
|
+
## Install
|
|
694
|
+
|
|
695
|
+
Requires **Node.js 18+**.
|
|
696
|
+
|
|
697
|
+
```bash
|
|
698
|
+
# From npm
|
|
699
|
+
npm install -g @zhijiewang/openharness
|
|
700
|
+
|
|
701
|
+
# From source
|
|
702
|
+
git clone https://github.com/zhijiewong/openharness.git
|
|
703
|
+
cd openharness
|
|
704
|
+
npm install && npm install -g .
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
## Development
|
|
708
|
+
|
|
709
|
+
```bash
|
|
710
|
+
npm install
|
|
711
|
+
npx tsx src/main.tsx # run in dev mode
|
|
712
|
+
npx tsc --noEmit # type check
|
|
713
|
+
npm test # run tests
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### Adding a tool
|
|
717
|
+
|
|
718
|
+
Create `src/tools/YourTool/index.ts` implementing the `Tool` interface with a Zod input schema, register it in `src/tools.ts`.
|
|
719
|
+
|
|
720
|
+
### Adding a provider
|
|
721
|
+
|
|
722
|
+
Create `src/providers/yourprovider.ts` implementing the `Provider` interface, add a case in `src/providers/index.ts`.
|
|
723
|
+
|
|
724
|
+
## Contributing
|
|
725
|
+
|
|
726
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
727
|
+
|
|
728
|
+
## Community
|
|
729
|
+
|
|
730
|
+
Join the OpenHarness community to get help, share your workflows, and discuss the future of AI coding agents!
|
|
731
|
+
|
|
732
|
+
| Platform | Details & Links |
|
|
733
|
+
| :--- | :--- |
|
|
734
|
+
| 🟣 **Discord** | [**Join our Discord Server**](https://discord.gg/ezVrqy3qu) to chat with developers and get real-time support. |
|
|
735
|
+
| 🔵 **Feishu / Lark** | Scan the QR code below to collaborate with the community:<br><br><img src="https://github.com/user-attachments/assets/54ade077-22ad-45d2-b38a-623464677d53" width="160" alt="Feishu Group QR Code"> |
|
|
736
|
+
| 🟢 **WeChat** | Scan the QR code below to join our WeChat group:<br><br><img src="https://github.com/user-attachments/assets/adcf291a-9ffe-4738-8608-f46a21e18db0" width="160" alt="WeChat Group QR Code"> |
|
|
737
|
+
|
|
738
|
+
## License
|
|
739
|
+
|
|
740
|
+
MIT
|
|
741
|
+
|