@zhijiewang/openharness 2.17.0 → 2.19.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 CHANGED
@@ -23,6 +23,8 @@ AI coding agent in your terminal. Works with any LLM -- free local models or clo
23
23
 
24
24
  [![npm version](https://img.shields.io/npm/v/@zhijiewang/openharness)](https://www.npmjs.com/package/@zhijiewang/openharness) [![npm downloads](https://img.shields.io/npm/dm/@zhijiewang/openharness)](https://www.npmjs.com/package/@zhijiewang/openharness) [![license](https://img.shields.io/npm/l/@zhijiewang/openharness)](LICENSE) ![tests](https://img.shields.io/badge/tests-890-brightgreen) ![tools](https://img.shields.io/badge/tools-42-blue) ![Node.js 18+](https://img.shields.io/badge/node-18%2B-green) ![TypeScript](https://img.shields.io/badge/typescript-strict-blue) [![GitHub stars](https://img.shields.io/github/stars/zhijiewong/openharness)](https://github.com/zhijiewong/openharness) [![GitHub issues](https://img.shields.io/github/issues-raw/zhijiewong/openharness)](https://github.com/zhijiewong/openharness/issues) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/zhijiewong/openharness/pulls)
25
25
 
26
+ **English** | [简体中文](README.zh-CN.md)
27
+
26
28
  ---
27
29
 
28
30
  ## Table of Contents
@@ -30,8 +32,8 @@ AI coding agent in your terminal. Works with any LLM -- free local models or clo
30
32
  - [Quick Start](#quick-start)
31
33
  - [Why OpenHarness?](#why-openharness)
32
34
  - [Terminal UI](#terminal-ui)
33
- - [Tools (35)](#tools-35)
34
- - [Slash Commands (33)](#slash-commands-33)
35
+ - [Tools (43)](#tools-43)
36
+ - [Slash Commands](#slash-commands)
35
37
  - [Permission Modes](#permission-modes)
36
38
  - [Hooks](#hooks)
37
39
  - [Checkpoints & Rewind](#checkpoints--rewind)
@@ -57,7 +59,9 @@ oh
57
59
 
58
60
  That's it. OpenHarness auto-detects Ollama and starts chatting. No API key needed.
59
61
 
60
- **Python SDK:** there's also an official Python SDK for driving `oh` from Python programs (notebooks, batch scripts, ML pipelines). Install with `pip install openharness` after the npm install, then `from openharness import query`. See [`python/README.md`](python/README.md).
62
+ **Python SDK:** there's also an official Python SDK for driving `oh` from Python programs (notebooks, batch scripts, ML pipelines). Install with `pip install openharness-sdk` after the npm install (the PyPI distribution is `openharness-sdk` because the unqualified name is taken), then `from openharness import query`. See [`python/README.md`](python/README.md).
63
+
64
+ **TypeScript SDK:** drive `oh` from Node.js (VS Code extensions, Electron apps, build scripts) with `@zhijiewang/openharness-sdk` — `npm install @zhijiewang/openharness-sdk`, then `import { query, OpenHarnessClient, tool } from "@zhijiewang/openharness-sdk"`. Mirrors the Python SDK surface (streaming events, stateful sessions, custom tools, permission callback, session resume). See [`packages/sdk/README.md`](packages/sdk/README.md).
61
65
 
62
66
  ```bash
63
67
  oh init # interactive setup wizard (provider + cybergotchi)
@@ -82,26 +86,6 @@ Ctrl+O # flush transcript to scrollback for revie
82
86
 
83
87
  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`.
84
88
 
85
- | | OpenHarness | Claude Code | Aider | OpenCode |
86
- |---|---|---|---|---|
87
- | Any LLM | Yes (Ollama, OpenAI, Anthropic, OpenRouter, any OpenAI-compatible) | Anthropic only | Yes | Yes |
88
- | Free local models | Ollama native | No | Yes | Yes |
89
- | Tools | 41 with permission gates | 43+ | File-focused | 20+ |
90
- | Permission modes | 7 (ask, trust, deny, acceptEdits, plan, auto, bypass) | 7 | Basic | Basic |
91
- | Git integration | Auto-commit + /undo + /rewind checkpoints | Yes | Deep git | Basic |
92
- | Slash commands | 42+ built-in | 80+ | Some | Some |
93
- | Headless/CI mode | `oh -p "prompt"` or `oh run --json` | Yes | Yes | Yes |
94
- | GitHub Action | Built-in PR review action | Yes | No | No |
95
- | Agent roles | 6 specializations (reviewer, tester, debugger...) | Yes | No | No |
96
- | Vim mode | hjkl, w/b/e, 0/$, x, d, i/a/I/A/o | Full vim | No | No |
97
- | Prompt caching | Anthropic cache_control | Yes | No | No |
98
- | Bash security | AST-based command analysis | AST analysis | No | No |
99
- | Companion | Cybergotchi virtual pet | Basic | No | No |
100
- | Terminal UI | Sequential renderer (Ink pattern) | React + Ink | Basic | BubbleTea |
101
- | Language | TypeScript | TypeScript | Python | Go |
102
- | License | MIT | Proprietary | Apache 2.0 | MIT |
103
- | Price | Free (BYOK) | $20+/month | Free (BYOK) | Free (BYOK) |
104
-
105
89
  ## Terminal UI
106
90
 
107
91
  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.
@@ -160,12 +144,13 @@ statusLineFormat: '{model} │ {tokens} │ {cost} │ {ctx}'
160
144
 
161
145
  Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XXXX), `{ctx}` (context usage bar). Empty sections are automatically collapsed.
162
146
 
163
- ## Tools (35)
147
+ ## Tools (43)
164
148
 
165
149
  | Tool | Risk | Description |
166
150
  |------|------|-------------|
167
151
  | **Core** | | |
168
152
  | Bash | high | Execute shell commands with live streaming output (AST safety analysis) |
153
+ | PowerShell | high | Execute PowerShell commands (Windows-native scripting) |
169
154
  | Read | low | Read files with line ranges, PDF support |
170
155
  | ImageRead | low | Read images/PDFs for multimodal analysis |
171
156
  | Write | medium | Create or overwrite files |
@@ -185,6 +170,7 @@ Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XX
185
170
  | TaskGet | low | Get task details |
186
171
  | TaskStop | low | Stop a running task |
187
172
  | TaskOutput | low | Get task output |
173
+ | TodoWrite | low | Manage session task checklist (Claude Code-compatible) |
188
174
  | **Agents** | | |
189
175
  | Agent | medium | Spawn a sub-agent (with role specialization) |
190
176
  | ParallelAgent | medium | Dispatch multiple agents with DAG dependencies |
@@ -194,9 +180,12 @@ Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XX
194
180
  | CronCreate | medium | Schedule recurring tasks |
195
181
  | CronDelete | medium | Remove scheduled tasks |
196
182
  | CronList | low | List all scheduled tasks |
183
+ | ScheduleWakeup | low | Self-pace the next /loop iteration (cache-aware) |
197
184
  | **Planning** | | |
198
185
  | EnterPlanMode | low | Enter structured planning mode |
199
186
  | ExitPlanMode | low | Exit planning mode |
187
+ | **Pipelines** | | |
188
+ | Pipeline | medium | Run a sequence of tasks with output passed between steps |
200
189
  | **Code Intelligence** | | |
201
190
  | Diagnostics | low | LSP-based code diagnostics |
202
191
  | NotebookEdit | medium | Edit Jupyter notebooks |
@@ -204,17 +193,22 @@ Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XX
204
193
  | Memory | low | Save/list/search persistent memories |
205
194
  | Skill | low | Invoke a skill from .oh/skills/ |
206
195
  | ToolSearch | low | Find tools by description |
196
+ | SessionSearch | low | Search prior sessions for relevant context |
197
+ | **MCP** | | |
198
+ | ListMcpResources | low | List resources from connected MCP servers |
199
+ | ReadMcpResource | low | Read a specific MCP resource by URI |
207
200
  | **Git Worktrees** | | |
208
201
  | EnterWorktree | medium | Create isolated git worktree |
209
202
  | ExitWorktree | medium | Remove a git worktree |
210
203
  | **Process** | | |
211
204
  | KillProcess | high | Stop processes by PID or name |
205
+ | Monitor | medium | Run a background command and stream each output line back to the agent |
212
206
 
213
207
  Low-risk read-only tools auto-approve. Medium and high risk tools require confirmation in `ask` mode. Use `--trust` or `--auto` to skip prompts.
214
208
 
215
- ## Slash Commands (33)
209
+ ## Slash Commands
216
210
 
217
- Type these during a chat session. Aliases: `/q` exit, `/h` help, `/c` commit, `/m` model, `/s` status.
211
+ Over 80 commands are registered. The most-used ones are grouped below; see `/help` in-session for the full list. Aliases: `/q` exit, `/h` help, `/c` commit, `/m` model, `/s` status.
218
212
 
219
213
  **Session:**
220
214
  | Command | Description |
@@ -245,6 +239,8 @@ Type these during a chat session. Aliases: `/q` exit, `/h` help, `/c` commit, `/
245
239
  | `/files` | List files in context |
246
240
  | `/model <name>` | Switch model mid-session |
247
241
  | `/memory` | View and search memories |
242
+ | `/doctor` | Run diagnostic health checks |
243
+ | `/hooks` | List loaded hooks grouped by event |
248
244
 
249
245
  **Settings:**
250
246
  | Command | Description |
@@ -302,11 +298,29 @@ hooks:
302
298
  command: "scripts/cleanup.sh"
303
299
  ```
304
300
 
305
- **Event types:**
306
- - `sessionStart` — fires once when the session begins
307
- - `preToolUse` fires before each tool call; **exit code 1 blocks the tool** and returns an error to the model
308
- - `postToolUse` — fires after each tool call completes
309
- - `sessionEnd` fires when the session ends
301
+ **Event types** (17 total):
302
+
303
+ | Event | When it fires | Can block? |
304
+ |-------|---------------|------------|
305
+ | `sessionStart` | Session begins | |
306
+ | `sessionEnd` | Session ends | — |
307
+ | `turnStart` | Top-level agent turn begins (after user prompt accepted) | — |
308
+ | `turnStop` | Top-level agent turn ends (mirrors Claude Code's `Stop`) | — |
309
+ | `userPromptSubmit` | Before user prompt reaches the LLM | yes — `decision: deny` |
310
+ | `preToolUse` | Before each tool call | yes — exit code 1 / `decision: deny` |
311
+ | `postToolUse` | After successful tool execution | — |
312
+ | `postToolUseFailure` | After tool throws or returns `isError: true` | — |
313
+ | `permissionRequest` | When a tool needs approval (between `preToolUse` and the prompt) | yes — `decision: allow\|deny\|ask` |
314
+ | `fileChanged` | After a tool modifies a file | — |
315
+ | `cwdChanged` | After working directory changes | — |
316
+ | `subagentStart` | A sub-agent is spawned | — |
317
+ | `subagentStop` | A sub-agent completes | — |
318
+ | `preCompact` | Before conversation compaction | — |
319
+ | `postCompact` | After conversation compaction | — |
320
+ | `configChange` | `.oh/config.yaml` is modified during the session | — |
321
+ | `notification` | A notification is dispatched | — |
322
+
323
+ Live introspection: run `/hooks` in-session to see exactly which hooks are loaded, grouped by event.
310
324
 
311
325
  **Environment variables** available to hook scripts:
312
326
 
@@ -316,10 +330,16 @@ hooks:
316
330
  | `OH_TOOL_NAME` | Name of the tool being called (tool events only) |
317
331
  | `OH_TOOL_ARGS` | JSON-encoded tool arguments (tool events only) |
318
332
  | `OH_TOOL_OUTPUT` | JSON-encoded tool output (`postToolUse` only) |
333
+ | `OH_TOOL_INPUT_JSON` | Full JSON tool input (tool events only) |
334
+ | `OH_SESSION_ID` / `OH_MODEL` / `OH_PROVIDER` / `OH_PERMISSION_MODE` | Current session context |
335
+ | `OH_COST` / `OH_TOKENS` | Running cost and token totals |
336
+ | `OH_FILE_PATH` | Path that changed (`fileChanged` only) |
337
+ | `OH_NEW_CWD` | New working directory (`cwdChanged` only) |
338
+ | `OH_TURN_NUMBER` / `OH_TURN_REASON` | Turn boundary context (`turnStart` / `turnStop`) |
319
339
 
320
- Use `match` to restrict a hook to a specific tool name (e.g., `match: Bash` only triggers for the Bash tool).
340
+ Use `match` to restrict a hook to a specific tool name (e.g., `match: Bash` only triggers for the Bash tool). Substring, glob (`Cron*`), and `/regex/flags` patterns are all supported.
321
341
 
322
- See [docs/hooks.md](docs/hooks.md) for the full event reference including the new `userPromptSubmit`, `permissionRequest`, and `postToolUseFailure` events.
342
+ Set `jsonIO: true` on a `command` hook to opt into structured JSON I/O — the harness sends `{event, ...context}` on stdin and reads `{decision, reason, hookSpecificOutput}` from stdout. HTTP hooks accept the same response shape. See [docs/hooks.md](docs/hooks.md) for the full reference.
323
343
 
324
344
  ## Cybergotchi
325
345
 
@@ -517,6 +537,24 @@ cat error.log | oh run "what's wrong here?"
517
537
  git diff | oh run "review these changes"
518
538
  ```
519
539
 
540
+ ### Structured output with `--json-schema`
541
+
542
+ Constrain the model's output to a JSON Schema. Useful for CI scripts that
543
+ parse model output programmatically without regex heuristics:
544
+
545
+ ```bash
546
+ oh -p "output {\"ok\": true, \"count\": 3} as JSON" \
547
+ --trust \
548
+ --json-schema '{"type":"object","properties":{"ok":{"type":"boolean"},"count":{"type":"integer"}},"required":["ok","count"]}'
549
+ ```
550
+
551
+ Behavior:
552
+ - stdout: the validated JSON (single line), only when it passes the schema.
553
+ - stderr: structured errors on failure, plus the raw model output for debugging.
554
+ - Exit codes: **0** valid, **2** malformed schema, **3** model output was not JSON, **4** JSON didn't match the schema.
555
+
556
+ Supported keywords: `type`, `properties`, `required`, `items`, `enum`. For richer validation, pipe the output through a dedicated validator.
557
+
520
558
  ### GitHub Action for PR Review
521
559
 
522
560
  OpenHarness includes a built-in GitHub Action for automated code review:
@@ -608,6 +646,8 @@ provider: ollama
608
646
  model: llama3
609
647
  permissionMode: ask
610
648
  theme: dark
649
+ language: zh-CN # optional — respond in this language (code stays as-is)
650
+ outputStyle: default # optional — "default", "explanatory", "learning", or a custom name
611
651
  ```
612
652
 
613
653
  Then per-project configs only need what's different:
@@ -617,6 +657,27 @@ Then per-project configs only need what's different:
617
657
  model: codellama # override just the model
618
658
  ```
619
659
 
660
+ ### Output Styles
661
+
662
+ Swap the agent's personality without touching its core instructions. Built-ins:
663
+
664
+ - **`default`** — standard software engineering assistant (no preface)
665
+ - **`explanatory`** — adds an `## Insights` section after each task explaining *why* the agent made its choices
666
+ - **`learning`** — leaves 1–3 `TODO(human)` markers at strategic points so you write the instructive parts yourself
667
+
668
+ Create your own styles as markdown files with YAML frontmatter. Save to `.oh/output-styles/<name>.md` (project) or `~/.oh/output-styles/<name>.md` (user). Project shadows user shadows built-in.
669
+
670
+ ````markdown
671
+ ---
672
+ name: code-review
673
+ description: Focused code review mode
674
+ ---
675
+
676
+ Review rigorously. For every function, ask: is the logic correct, is error handling complete, are there edge cases ignored?
677
+ ````
678
+
679
+ Activate with `outputStyle: code-review` in `.oh/config.yaml`.
680
+
620
681
  ## Project Rules
621
682
 
622
683
  Create `.oh/RULES.md` in any repo (or run `oh init`):
@@ -706,7 +767,7 @@ Yes. Use `oh -p "prompt" --auto` for headless execution, or the built-in GitHub
706
767
  Yes. OpenHarness is language-agnostic — it reads, writes, and executes code in any language. Syntax highlighting covers 20+ languages.
707
768
 
708
769
  **How does it compare to Claude Code?**
709
- ~95% feature parity for CLI use cases. Main advantage: works with ANY LLM (not just Anthropic). See the [comparison table](#why-openharness) above.
770
+ ~95% feature parity for CLI use cases. Main advantage: works with ANY LLM (not just Anthropic) and is MIT-licensed. See [Why OpenHarness?](#why-openharness) above.
710
771
 
711
772
  ## Install
712
773