HKUDS/OpenHarnessPublic

"OpenHarness: Open Agent Harness with a Built-in Personal Agent--Ohmo!"

AI summary: An open-source harness for building and managing AI agents.

Stars
15.2K
+24 today
Forks
2.5K
Watchers
85
Open issues
29
Open PRs
47
Contributors
~55
Commits
429
Branches
14

PythonMITCreated Apr 1, 2026Last push 2mo agoLatest release v0.1.9+159 stars this week+159 this month

Star history

since Mar 29, 2026
05K10K15KMar 2026May 2026Jun 2026Aug 2026
15.2K stars as of Aug 6, 2026, tracked back to Mar 29, 2026. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulAugMonWedFri2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 0 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 0 commits2026-02-14: 0 commits2026-02-15: 0 commits2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 0 commits2026-02-25: 0 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 0 commits2026-03-03: 0 commits2026-03-04: 0 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 0 commits2026-03-10: 0 commits2026-03-11: 0 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 0 commits2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 0 commits2026-03-24: 0 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 1 commit2026-04-02: 28 commits2026-04-03: 26 commits2026-04-04: 28 commits2026-04-05: 39 commits2026-04-06: 14 commits2026-04-07: 15 commits2026-04-08: 16 commits2026-04-09: 10 commits2026-04-10: 15 commits2026-04-11: 8 commits2026-04-12: 4 commits2026-04-13: 14 commits2026-04-14: 5 commits2026-04-15: 3 commits2026-04-16: 8 commits2026-04-17: 7 commits2026-04-18: 1 commit2026-04-19: 4 commits2026-04-20: 6 commits2026-04-21: 1 commit2026-04-22: 3 commits2026-04-23: 4 commits2026-04-24: 2 commits2026-04-25: 2 commits2026-04-26: 1 commit2026-04-27: 5 commits2026-04-28: 7 commits2026-04-29: 3 commits2026-04-30: 0 commits2026-05-01: 3 commits2026-05-02: 2 commits2026-05-03: 4 commits2026-05-04: 1 commit2026-05-05: 3 commits2026-05-06: 12 commits2026-05-07: 2 commits2026-05-08: 2 commits2026-05-09: 2 commits2026-05-10: 1 commit2026-05-11: 1 commit2026-05-12: 4 commits2026-05-13: 1 commit2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 9 commits2026-05-17: 4 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 2 commits2026-05-22: 2 commits2026-05-23: 0 commits2026-05-24: 6 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 2 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 5 commits2026-06-05: 0 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 0 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 0 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 0 commits2026-07-04: 0 commits2026-07-05: 0 commits2026-07-06: 0 commits2026-07-07: 0 commits2026-07-08: 0 commits2026-07-09: 0 commits2026-07-10: 0 commits2026-07-11: 0 commits2026-07-12: 0 commits2026-07-13: 0 commits2026-07-14: 0 commits2026-07-15: 0 commits2026-07-16: 0 commits2026-07-17: 0 commits2026-07-18: 0 commits2026-07-19: 0 commits2026-07-20: 0 commits2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 0 commits2026-07-25: 0 commits2026-07-26: 0 commits2026-07-27: 0 commits2026-07-28: 0 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 0 commits2026-08-01: 0 commits2026-08-02: 0 commits2026-08-03: 0 commits2026-08-04: 0 commits2026-08-05: 0 commits2026-08-06: 0 commits2026-08-07: 0 commits2026-08-08: 0 commits
348 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Widely adopted

    15,237 stars

  • Permissive license

    MIT

  • Repeat trending

    4 trending appearances

What OpenHarness does

OpenHarness provides a comprehensive infrastructure for integrating Large Language Models into functional agents. It features an agent loop supporting streaming tool calls, API retries, and parallel execution. The toolkit includes over 40 tools, on-demand skill loading, and a persistent memory system with context compression. It also offers governance features like multi-level permissions and supports swarm coordination for multi-agent tasks.

AI researchers, developers, and power users building complex agentic workflows or personal AI assistants requiring robust tool usage and memory.

  • Agent Loop: Streaming tool-call cycle with API retries and parallel execution.
  • Extensive Toolkit: Includes 43+ tools for file manipulation, shell execution, web searching, and MCP integration.
  • Persistent Memory: Uses MEMORY.md and auto-compaction for maintaining context across sessions.
  • Governance: Multi-level permission modes and interactive approval dialogs for safety.
  • Swarm Coordination: Supports subagent spawning and task management for multi-agent systems.

Where teams use it

Building Custom AI Agents

Developers creating specialized agents that require tool access, memory, and structured reasoning loops.

Multi-Agent Systems

Researchers and engineers building coordinated agent swarms to tackle complex, multi-step tasks.

Personal AI Assistants

Users setting up personalized AI assistants integrated with chat platforms like Telegram or Slack.

Getting started: curl -fsSL https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.sh | bash

README

main branch

OpenHarness    ohmo
oh — OpenHarness & ohmo

English · 简体中文

OpenHarness delivers core lightweight agent infrastructure: tool-use, skills, memory, and multi-agent coordination.

ohmo is a personal AI agent built on OpenHarness — not another chatbot, but an assistant that actually works for you over long sessions. Chat with ohmo in Feishu / Slack / Telegram / Discord, and it forks branches, writes code, runs tests, and opens PRs on its own. ohmo runs on your existing Claude Code or Codex subscription — no extra API key needed.

Join the community: contribute Harness for open agent development.

Quick Start Architecture Tools Tests License

Python React Pytest E2E Output CI Feishu WeChat

One Command (oh) to Launch OpenHarness and Unlock All Agent Harnesses.

Supports CLI agent integration including OpenClaw, nanobot, Cursor, and more.

OpenHarness Terminal Demo


✨ OpenHarness's Key Harness Features

🔄 Agent Loop

Engine

• Streaming Tool-Call Cycle

• API Retry with Exponential Backoff

• Parallel Tool Execution

• Token Counting & Cost Tracking

🔧 Harness Toolkit

Toolkit

• 43 Tools (File, Shell, Search, Web, MCP)

• On-Demand Skill Loading (.md)

• Plugin Ecosystem (Skills + Hooks + Agents)

• Compatible with anthropics/skills & plugins

🧠 Context & Memory

Context

• CLAUDE.md Discovery & Injection

• Context Compression (Auto-Compact)

• MEMORY.md Persistent Memory

• Session Resume & History

🛡️ Governance

Governance

• Multi-Level Permission Modes

• Path-Level & Command Rules

• PreToolUse / PostToolUse Hooks

• Interactive Approval Dialogs

🤝 Swarm Coordination

Swarm

• Subagent Spawning & Delegation

• Team Registry & Task Management

• Background Task Lifecycle

ClawTeam Integration (Roadmap)


🤔 What is an Agent Harness?

An Agent Harness is the complete infrastructure that wraps around an LLM to make it a functional agent. The model provides intelligence; the harness provides hands, eyes, memory, and safety boundaries.

Harness = Tools + Knowledge + Observation + Action + Permissions

OpenHarness is an open-source Python implementation designed for researchers, builders, and the community:

  • Understand how production AI agents work under the hood
  • Experiment with cutting-edge tools, skills, and agent coordination patterns
  • Extend the harness with custom plugins, providers, and domain knowledge
  • Build specialized agents on top of proven architecture

📰 What's New

  • Unreleased 🔍 Dry-run safe preview:
    • oh --dry-run previews resolved runtime settings, auth state, skills, commands, tools, and configured MCP servers without executing the model, tools, or subagents.
    • Dry-run now reports a ready / warning / blocked readiness verdict with concrete next-step suggestions such as fixing auth, fixing MCP config, or running the prompt directly.
    • Prompt previews include likely matching skills and tools, while slash-command previews show whether the command is mostly read-only or stateful.
  • 2026-04-18 ⚙️ v0.1.7 — Packaging & TUI polish:
    • Install script now links oh, ohmo, and openharness into ~/.local/bin instead of prepending the virtualenv bin directory to PATH, which avoids clobbering Conda-managed shells.
    • React TUI now supports Shift+Enter to insert a newline while keeping plain Enter as submit.
    • Busy-state animation in the React TUI is quieter and less error-prone on Windows terminals, with conservative spinner frames and reduced flashing.
  • 2026-04-10 🧠 v0.1.6 — Auto-Compaction & Markdown TUI:
    • Auto-Compaction preserves task state and channel logs across context compression — agents can run multi-day sessions without manual compact/clear
    • Subprocess teammates run in headless worker mode; agent team creation stabilized
    • Assistant messages now render full Markdown in the React TUI
    • ohmo gains channel slash commands and multimodal attachment support
  • 2026-04-08 🔌 v0.1.5 — MCP HTTP transport & Swarm polling:
    • MCP protocol adds HTTP transport, auto-reconnect on disconnect, and tool-only server compatibility
    • JSON Schema types inferred for MCP tool inputs — no manual type mapping needed
    • ohmo channels support file attachments and multimodal gateway messages
    • Subprocess agents are now pollable in real runs; permission modals serialized to prevent input swallowing
  • 2026-04-08 🌙 v0.1.4 — Multi-provider auth & Moonshot/Kimi:
    • Native Moonshot/Kimi provider with reasoning_content support for thinking models
    • Auth overhaul: fixed provider-switching key mismatch, OPENAI_BASE_URL env override, profile-scoped credential priority
    • MCP gracefully handles disconnected servers in call_tool / read_resource
    • Security: built-in sensitive-path protection in PermissionChecker, hardened web_fetch URL validation
    • Stability: EIO crash recovery in Ink TUI, --debug logging, Windows cmd flash fix
  • 2026-04-06 🚀 v0.1.2 — Unified setup flows and ohmo personal-agent app:
    • oh setup now guides provider selection as workflows instead of exposing raw auth/provider internals
    • Compatible API setup is now profile-scoped, so Anthropic/OpenAI-compatible endpoints can keep separate keys
    • ohmo ships as a packaged app with ~/.ohmo workspace, gateway, bootstrap prompts, and channel config flow
  • 2026-04-01 🎨 v0.1.0 — Initial OpenHarness open-source release featuring complete Harness architecture:

Start here: Quick Start · Provider Compatibility · Showcase · Contributing · Changelog


🚀 Quick Start

1. Install

Linux / macOS / WSL

# One-click install
curl -fsSL https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.sh | bash

# Or via pip
pip install openharness-ai

Windows (Native)

# One-click install (PowerShell)
iex (Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/HKUDS/OpenHarness/main/scripts/install.ps1')

# Or via pip
pip install openharness-ai

Note: Windows support is now native. In PowerShell, use openh instead of oh because oh can resolve to the built-in Out-Host alias.

2. Configure

oh setup    # interactive wizard — pick a provider, authenticate, done
# On Windows PowerShell, use: openh setup

Supports Claude / OpenAI / Copilot / Codex / Moonshot(Kimi) / GLM / MiniMax / NVIDIA NIM and any compatible endpoint.

3. Run

oh
# On Windows PowerShell, use: openh

OpenHarness Landing Screen

4. Set up ohmo (Personal Agent)

Want an AI agent that works for you from Feishu / Slack / Telegram / Discord?

ohmo init             # initialize ~/.ohmo workspace
ohmo config           # configure channels and provider
ohmo gateway start    # start the gateway — ohmo is now live in your chat app

ohmo runs on your existing Claude Code subscription or Codex subscription — no extra API key needed.

Non-Interactive Mode (Pipes & Scripts)

# Single prompt → stdout
oh -p "Explain this codebase"

# JSON output for programmatic use
oh -p "List all functions in main.py" --output-format json

# Stream JSON events in real-time
oh -p "Fix the bug" --output-format stream-json

Dry Run (Safe Preview)

Use --dry-run when you want to inspect what OpenHarness would use before any live execution starts.

# Preview an interactive session setup
oh --dry-run

# Preview one prompt without executing the model or tools
oh --dry-run -p "Review this bug fix and grep for failing tests"

# Preview a slash command path
oh --dry-run -p "/plugin list"

# Get structured output for scripts or channels
oh --dry-run -p "Explain this repository" --output-format json

Dry-run is intentionally static:

  • It does not call the model
  • It does not execute tools or spawn subagents
  • It does not connect to MCP servers
  • It does resolve settings, auth status, prompt assembly, skills, commands, tools, and obvious MCP config problems

Readiness levels:

  • ready: configuration looks usable; the next suggested action is usually to run the prompt directly
  • warning: OpenHarness can resolve the session, but something important still looks wrong, such as broken MCP config or missing auth for later model work
  • blocked: the requested path will not run successfully as-is, for example an unknown slash command or a prompt that cannot resolve a runtime client

next actions in the dry-run output tell you the shortest fix or follow-up step, such as:

  • run oh auth login
  • fix or disable broken MCP configuration
  • run the prompt directly with oh -p "..." or open the interactive UI with oh

🔌 Provider Compatibility

OpenHarness treats providers as workflows backed by named profiles. In day-to-day use, prefer:

oh setup
oh provider list
oh provider use <profile>

Built-in Workflows

Workflow What it is Typical backends
Anthropic-Compatible API Anthropic-style request format Claude official, Kimi, GLM, MiniMax, internal Anthropic-compatible gateways
Claude Subscription Claude CLI subscription bridge Local ~/.claude/.credentials.json
OpenAI-Compatible API OpenAI-style request format OpenAI official, OpenRouter, DashScope, DeepSeek, SiliconFlow, Groq, Ollama, GitHub Models
Codex Subscription Codex CLI subscription bridge Local ~/.codex/auth.json
GitHub Copilot Copilot OAuth workflow GitHub Copilot device-flow login

Compatible API Families

Anthropic-Compatible API

Typical examples:

Backend Base URL Example models
Claude official https://api.anthropic.com claude-sonnet-4-6, claude-opus-4-6
Moonshot / Kimi https://api.moonshot.cn/anthropic kimi-k2.5
Zhipu / GLM custom Anthropic-compatible endpoint glm-4.5
MiniMax custom Anthropic-compatible endpoint minimax-m1

OpenAI-Compatible API

Any provider implementing the OpenAI /v1/chat/completions style API works:

Backend Base URL Example models
OpenAI https://api.openai.com/v1 gpt-5.4, gpt-4.1
OpenRouter https://openrouter.ai/api/v1 provider-specific
Alibaba DashScope https://dashscope.aliyuncs.com/compatible-mode/v1 qwen3.5-flash, qwen3-max, deepseek-r1
DeepSeek https://api.deepseek.com deepseek-chat, deepseek-reasoner
GitHub Models https://models.inference.ai.azure.com gpt-4o, Meta-Llama-3.1-405B-Instruct
SiliconFlow https://api.siliconflow.cn/v1 deepseek-ai/DeepSeek-V3
NVIDIA NIM https://integrate.api.nvidia.com/v1 openai/gpt-oss-120b, nvidia/llama-3.3-nemotron-super-49b-v1
Google Gemini https://generativelanguage.googleapis.com/v1beta/openai gemini-2.5-flash, gemini-2.5-pro
Groq https://api.groq.com/openai/v1 llama-3.3-70b-versatile
Ollama (local) http://localhost:11434/v1 any local model

Advanced Profile Management

# List saved workflows
oh provider list

# Switch the active workflow
oh provider use codex

# Add your own compatible endpoint
oh provider add my-endpoint \
  --label "My Endpoint" \
  --provider openai \
  --api-format openai \
  --auth-source openai_api_key \
  --model my-model \
  --base-url https://example.com/v1

For custom compatible endpoints, OpenHarness can bind credentials per profile instead of forcing every Anthropic-compatible or OpenAI-compatible backend to share the same API key.

Ollama (Local Models)

Run local models through Ollama's OpenAI-compatible endpoint:

# Add an Ollama provider profile
oh provider add ollama \
  --label "Ollama" \
  --provider Ollama \
  --api-format openai \
  --auth-source openai_api_key \
  --model glm-4.7-flash:q8_0 \
  --base-url http://localhost:11434/v1
Saved provider profile: ollama
# Activate and verify
oh provider use ollama
Activated provider profile: ollama
oh provider list
  claude-api: Anthropic-Compatible API [ready]
  ...
  moonshot: Moonshot (Kimi) [missing auth]
    auth=moonshot_api_key model=kimi-k2.5 base_url=https://api.moonshot.cn/v1
* ollama: Ollama [ready]
    auth=openai_api_key model=glm-4.7-flash:q8_0 base_url=http://localhost:11434/v1

GitHub Copilot Format (--api-format copilot)

Use your existing GitHub Copilot subscription as the LLM backend. Authentication uses GitHub's OAuth device flow — no API keys needed.

# One-time login (opens browser for GitHub authorization)
oh auth copilot-login

# Then launch with Copilot as the provider
uv run oh --api-format copilot

# Or via environment variable
export OPENHARNESS_API_FORMAT=copilot
uv run oh

# Check auth status
oh auth status

# Remove stored credentials
oh auth copilot-logout
Feature Details
Auth method GitHub OAuth device flow (no API key needed)
Token management Automatic refresh of short-lived session tokens
Enterprise Supports GitHub Enterprise via --github-domain flag
Models Uses Copilot's default model selection
API OpenAI-compatible chat completions under the hood

🏗️ Harness Architecture

OpenHarness implements the core Agent Harness pattern with 10 subsystems:

openharness/
  engine/          # 🧠 Agent Loop — query → stream → tool-call → loop
  tools/           # 🔧 43 Tools — file I/O, shell, search, web, MCP
  skills/          # 📚 Knowledge — on-demand skill loading (.md files)
  plugins/         # 🔌 Extensions — commands, hooks, agents, MCP servers
  permissions/     # 🛡️ Safety — multi-level modes, path rules, command deny
  hooks/           # ⚡ Lifecycle — PreToolUse/PostToolUse event hooks
  commands/        # 💬 54 Commands — /help, /commit, /plan, /resume, ...
  mcp/             # 🌐 MCP — Model Context Protocol client
  memory/          # 🧠 Memory — persistent cross-session knowledge
  tasks/           # 📋 Tasks — background task management
  coordinator/     # 🤝 Multi-Agent — subagent spawning, team coordination
  prompts/         # 📝 Context — system prompt assembly, CLAUDE.md, skills
  config/          # ⚙️ Settings — multi-layer config, migrations
  ui/              # 🖥️ React TUI — backend protocol + frontend

The Agent Loop

The heart of the harness. One loop, endlessly composable:

while True:
    response = await api.stream(messages, tools)
    
    if response.stop_reason != "tool_use":
        break  # Model is done
    
    for tool_call in response.tool_uses:
        # Permission check → Hook → Execute → Hook → Result
        result = await harness.execute_tool(tool_call)
    
    messages.append(tool_results)
    # Loop continues — model sees results, decides next action

The model decides what to do. The harness handles how — safely, efficiently, with full observability.

Harness Flow

flowchart LR
    U[User Prompt] --> C[CLI or React TUI]
    C --> R[RuntimeBundle]
    R --> Q[QueryEngine]
    Q --> A[Anthropic-compatible API Client]
    A -->|tool_use| T[Tool Registry]
    T --> P[Permissions + Hooks]
    P --> X[Files Shell Web MCP Tasks]
    X --> Q
Loading

✨ Features

🔧 Tools (43+)

Category Tools Description
File I/O Bash, Read, Write, Edit, Glob, Grep Core file operations with permission checks
Search WebFetch, WebSearch, ToolSearch, LSP Web and code search capabilities
Notebook NotebookEdit Jupyter notebook cell editing
Agent Agent, SendMessage, TeamCreate/Delete Subagent spawning and coordination
Task TaskCreate/Get/List/Update/Stop/Output Background task management
MCP MCPTool, ListMcpResources, ReadMcpResource Model Context Protocol integration
Mode EnterPlanMode, ExitPlanMode, Worktree Workflow mode switching
Schedule CronCreate/List/Delete, RemoteTrigger Scheduled and remote execution
Meta Skill, Config, Brief, Sleep, AskUser Knowledge loading, configuration, interaction

Every tool has:

  • Pydantic input validation — structured, type-safe inputs
  • Self-describing JSON Schema — models understand tools automatically
  • Permission integration — checked before every execution
  • Hook support — PreToolUse/PostToolUse lifecycle events

📚 Skills System

Skills are on-demand knowledge — loaded only when the model needs them:

Available Skills:
- commit: Create clean, well-structured git commits
- review: Review code for bugs, security issues, and quality
- debug: Diagnose and fix bugs systematically
- plan: Design an implementation plan before coding
- test: Write and run tests for code
- simplify: Refactor code to be simpler and more maintainable
- pdf: PDF processing with pypdf (from anthropics/skills)
- xlsx: Excel operations (from anthropics/skills)
- ... 40+ more

Skills can live in bundled, user, ohmo, project, or plugin locations. User-level skills are loaded from:

~/.openharness/skills/<skill>/SKILL.md
~/.claude/skills/<skill>/SKILL.md
~/.agents/skills/<skill>/SKILL.md

Project-level skills are enabled by default and are discovered from the current working directory up to the git root:

<project>/.openharness/skills/<skill>/SKILL.md
<project>/.agents/skills/<skill>/SKILL.md
<project>/.claude/skills/<skill>/SKILL.md

Disable project skills for untrusted repositories with:

oh config set allow_project_skills false

Use /skills to list loaded skills with their source and path. User-invocable skills can be run directly as slash commands, for example /deploy staging.

Compatible with anthropics/skills — use the SKILL.md directory layout above.

🌐 Web search and proxy settings

Built-in web_search uses DuckDuckGo HTML search by default. In regions where that endpoint is unreachable, point OpenHarness at a trusted public HTML search endpoint or your own SearXNG instance:

export OPENHARNESS_WEB_SEARCH_URL="https://your-searxng.example/search"

web_search and web_fetch keep trust_env=False for SSRF safety, so they do not automatically inherit HTTP_PROXY / HTTPS_PROXY. If you need a proxy, opt in with an OpenHarness-specific variable:

export OPENHARNESS_WEB_PROXY="http://127.0.0.1:7890"

The proxy URL must be HTTP/HTTPS and cannot contain embedded credentials.

🔌 Plugin System

Compatible with claude-code plugins. Tested with 12 official plugins:

Plugin Type What it does
commit-commands Commands Git commit, push, PR workflows
security-guidance Hooks Security warnings on file edits
hookify Commands + Agents Create custom behavior hooks
feature-dev Commands Feature development workflow
code-review Agents Multi-agent PR review
pr-review-toolkit Agents Specialized PR review agents
# Manage plugins
oh plugin list
oh plugin install <source>
oh plugin enable <name>

🤝 Ecosystem Workflows

OpenHarness is useful as a lightweight harness layer around Claude-style tooling conventions:

  • OpenClaw-oriented workflows can reuse Markdown-first knowledge and command-driven collaboration patterns.
  • Claude-style plugins and skills stay portable because OpenHarness keeps those formats familiar.
  • ClawTeam-style multi-agent work maps well onto the built-in team, task, and background execution primitives.

For concrete usage ideas instead of generic claims, see docs/SHOWCASE.md.

🛡️ Permissions

Multi-level safety with fine-grained control:

Mode Behavior Use Case
Default Ask before write/execute Daily development
Auto Allow everything Sandboxed environments
Plan Mode Block all writes Large refactors, review first

Path-level rules in settings.json:

{
  "permission": {
    "mode": "default",
    "path_rules": [{"pattern": "/etc/*", "allow": false}],
    "denied_commands": ["rm -rf /", "DROP TABLE *"]
  }
}

🖥️ Terminal UI

React/Ink TUI with full interactive experience:

  • Command picker: Type / → arrow keys to select → Enter
  • Permission dialog: Interactive y/n with tool details
  • Mode switcher: /permissions → select from list
  • Session resume: /resume → pick from history
  • Animated spinner: Real-time feedback during tool execution
  • Keyboard shortcuts: Shown at the bottom, context-aware

📡 CLI

oh [OPTIONS] COMMAND [ARGS]

Session:     -c/--continue, -r/--resume, -n/--name
Model:       -m/--model, --effort, --max-turns
Output:      -p/--print, --output-format text|json|stream-json
Permissions: --permission-mode, --dangerously-skip-permissions
Context:     -s/--system-prompt, --append-system-prompt, --settings
Advanced:    -d/--debug, --mcp-config, --bare

Subcommands: oh setup | oh provider | oh auth | oh mcp | oh plugin

🧑‍💼 ohmo Personal Agent

ohmo is a personal-agent app built on top of OpenHarness. It is packaged alongside oh, with its own workspace and gateway:

# Initialize personal workspace
ohmo init

# Configure gateway channels and pick a provider profile
ohmo config

# Run the personal agent
ohmo

# Run the gateway in foreground
ohmo gateway run

# Check or restart the gateway
ohmo gateway status
ohmo gateway restart

Key concepts:

  • ~/.ohmo/
    • personal workspace root
  • soul.md
    • long-term agent personality and behavior
  • identity.md
    • who ohmo is
  • user.md
    • user profile and preferences
  • BOOTSTRAP.md
    • first-run landing ritual
  • memory/
    • personal memory
  • gateway.json
    • selected provider profile and channel configuration

ohmo config uses the same workflow language as oh setup, so you can point the personal-agent gateway at:

  • Anthropic-Compatible API
  • Claude Subscription
  • OpenAI-Compatible API
  • Codex Subscription
  • GitHub Copilot

ohmo init creates the home workspace once. After that, use ohmo config to update provider and channel settings; if the gateway is already running, the config flow can restart it for you.

Currently ohmo init / ohmo config can guide channel setup for:

  • Telegram
  • Slack
  • Discord
  • Feishu

📊 Test Results

Suite Tests Status
Unit + Integration 114 ✅ All passing
CLI Flags E2E 6 ✅ Real model calls
Harness Features E2E 9 ✅ Retry, skills, parallel, permissions
React TUI E2E 3 ✅ Welcome, conversation, status
TUI Interactions E2E 4 ✅ Commands, permissions, shortcuts
Real Skills + Plugins 12 ✅ anthropics/skills + claude-code/plugins
# Run all tests
uv run pytest -q                           # 114 unit/integration
python scripts/test_harness_features.py     # Harness E2E
python scripts/test_real_skills_plugins.py  # Real plugins E2E

🔧 Extending OpenHarness

Add a Custom Tool

from pydantic import BaseModel, Field
from openharness.tools.base import BaseTool, ToolExecutionContext, ToolResult

class MyToolInput(BaseModel):
    query: str = Field(description="Search query")

class MyTool(BaseTool):
    name = "my_tool"
    description = "Does something useful"
    input_model = MyToolInput

    async def execute(self, arguments: MyToolInput, context: ToolExecutionContext) -> ToolResult:
        return ToolResult(output=f"Result for: {arguments.query}")

Add a Custom Skill

Create ~/.openharness/skills/my-skill.md:

---
name: my-skill
description: Expert guidance for my specific domain
---

# My Skill

## When to use
Use when the user asks about [your domain].

## Workflow
1. Step one
2. Step two
...

Add a Plugin

Create .openharness/plugins/my-plugin/.claude-plugin/plugin.json:

{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "My custom plugin"
}

Add commands in commands/*.md, hooks in hooks/hooks.json, agents in agents/*.md.


🌍 Showcase

OpenHarness is most useful when treated as a small, inspectable harness you can adapt to a real workflow:

  • Repo coding assistant for reading code, patching files, and running checks locally.
  • Headless scripting tool for json and stream-json output in automation flows.
  • Plugin and skill testbed for experimenting with Claude-style extensions.
  • Multi-agent prototype harness for task delegation and background execution.
  • Provider comparison sandbox across Anthropic-compatible backends.

See docs/SHOWCASE.md for short, reproducible examples.


🤝 Contributing

OpenHarness is a community-driven research project. We welcome contributions in:

Area Examples
Tools New tool implementations for specific domains
Skills Domain knowledge .md files (finance, science, DevOps...)
Plugins Workflow plugins with commands, hooks, agents
Providers Support for more LLM backends (OpenAI, Ollama, etc.)
Multi-Agent Coordination protocols, team patterns
Testing E2E scenarios, edge cases, benchmarks
Documentation Architecture guides, tutorials, translations
# Development setup
git clone https://github.com/HKUDS/OpenHarness.git
cd OpenHarness
uv sync --extra dev
uv run pytest -q  # Verify everything works

Useful contributor entry points:


🔧 Troubleshooting

Backspace key in macOS Terminal.app

OpenHarness handles both common terminal delete sequences, including the raw DEL byte (0x7f) that macOS Terminal.app sends for Backspace. If Backspace inserts spaces or visible control characters instead of deleting text, upgrade OpenHarness first.

For older versions that do not include this fix, use a terminal that sends a standard Backspace sequence or adjust your terminal keyboard profile as a temporary workaround.


📄 License

MIT — see LICENSE.


OpenHarness
Oh my Harness!
The model is the agent. The code is the harness.

Thanks for visiting ✨ OpenHarness!

Views

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

4 total
  1. # v0.1.9 — Skill Workflows and Provider Key Updates OpenHarness v0.1.9 is a small follow-up release after v0.1.8 focused on making skills easier to create and invoke, plus fixing provider API key updates. ## Highlights - **Bundled skill creator** - Added a bundled `skill-creator` skill for creating, improving, and verifying OpenHarness/ohmo skills. - This makes repeatable workflows easier to capture as first-class skills. - **User-invocable skill slash commands** - Skills marked as user-invocable can now be triggered directly with slash commands. - Slash-invoked skills support user arguments and can request a model override through skill metadata. - **Provider API key update fix** - `oh setup` now lets users update the API key for an already-configured API-key provider profile. - `oh provider edit <profile> --api-key <key>` can replace a saved profile key directly. - `oh provider add ... --api-key <key>` can store a key while creating a provider profile. ## Fixes - Fixed issue #238, where users could change a configured provider model but had no supported path to update the saved API key. ## Install ```bash pip install --upgrade openharness-ai==0.1.9 ``` ##

  2. # v0.1.8 — Providers, ohmo Feishu Groups, and Safer Remotes OpenHarness v0.1.8 is a stabilization and provider-expansion release. It adds more first-class provider workflows, improves ohmo's Feishu group experience, hardens remote-channel security, and fixes several Windows/MCP reliability issues. ## Highlights - **New provider workflows** - Added NVIDIA NIM as a built-in OpenAI-compatible provider using `NVIDIA_API_KEY`. - Added ModelScope Inference API support. - Added Qwen (DashScope), MiniMax, and Gemini provider profiles. - Improved OpenAI-compatible API behavior, including explicit bearer authorization headers and `<think>` block filtering for compatible streaming responses. - **ohmo Feishu group support** - Added Feishu managed group creation flow for ohmo. - Added gateway-scoped provider/model commands for chat-based operation. - Improved group routing and mention policy so ohmo responds in shared Feishu groups only when explicitly addressed. - Hardened Feishu attachment filename handling. - **Security and remote-channel hardening** - Kept sensitive config/auth/provider/model/ship commands local-only by default in remote channels. - Kept bridge comm

  3. Highlights for 0.1.7 - Safer install flow: `scripts/install.sh` now links `oh`, `ohmo`, and `openharness` into `~/.local/bin` instead of prepending the virtualenv `bin` directory to `PATH`, which avoids clobbering Conda-managed shells. - Better React TUI input: `Shift+Enter` now inserts a newline while plain `Enter` still submits. - Quieter busy-state animation: the extra pseudo-animation line was removed, and Windows terminals now use conservative ASCII spinner frames to reduce flashing. - PyPI package published: `openharness-ai==0.1.7`. ## What's Changed * feat(tui): pair tool-call and tool-result rows for cleaner transcript by @yl-jiang in https://github.com/HKUDS/OpenHarness/pull/111 * fix(auth): cache keyring probe and rename misleading encrypt/decrypt by @glitch-ux in https://github.com/HKUDS/OpenHarness/pull/106 * feat(providers): add built-in Google Gemini provider profile by @glitch-ux in https://github.com/HKUDS/OpenHarness/pull/105 * fix: regenerate system prompt on checkpoint restore by @JiangweiYe76 in https://github.com/HKUDS/OpenHarness/pull/104 * fix(tui): keep busy spinner active throughout agent turn by @yl-jiang in https://github.com/HKUDS/OpenHarness/pull/116

  4. ## Highlights **ohmo** — a personal AI agent built on OpenHarness. Chat with ohmo in Feishu / Slack / Telegram / Discord, and it forks branches, writes code, runs tests, and opens PRs on its own. ohmo runs on your existing Claude Code or Codex subscription — no extra API key needed. ```bash pip install openharness-ai oh setup oh ``` ```bash ohmo init && ohmo config && ohmo gateway start ``` --- ## What's New since v0.1.0 ### 🤖 Swarm & Multi-Agent - Full coordinator orchestration system with agent definition loading - InProcessBackend with contextvars isolation, subprocess backend for pollable agents - WorktreeManager with git worktree isolation per teammate - TeamLifecycleManager with persistent team file management - Mailbox communication system with file-lock layer extracted to standalone module - Permission sync protocol for leader-worker bridging - Subprocess teammates run in headless worker mode ### 🧠 Auto-Compaction - Context auto-compression for long-running sessions - Task state and channel logs preserved across compaction - Tested: ohmo ran 4 days straight without manual compact or clear ### 📡 ohmo Personal Agent - `ohmo init` / `ohmo config` / `ohmo gateway sta

Commits per week

last 52 weeks
1170Week of 2025-08-10: 0 commitsWeek of 2025-08-17: 0 commitsWeek of 2025-08-24: 0 commitsWeek of 2025-08-31: 0 commitsWeek of 2025-09-07: 0 commitsWeek of 2025-09-14: 0 commitsWeek of 2025-09-21: 0 commitsWeek of 2025-09-28: 0 commitsWeek of 2025-10-05: 0 commitsWeek of 2025-10-12: 0 commitsWeek of 2025-10-19: 0 commitsWeek of 2025-10-26: 0 commitsWeek of 2025-11-02: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 0 commitsWeek of 2026-02-08: 0 commitsWeek of 2026-02-15: 0 commitsWeek of 2026-02-22: 0 commitsWeek of 2026-03-01: 0 commitsWeek of 2026-03-08: 0 commitsWeek of 2026-03-15: 0 commitsWeek of 2026-03-22: 0 commitsWeek of 2026-03-29: 83 commitsWeek of 2026-04-05: 117 commitsWeek of 2026-04-12: 42 commitsWeek of 2026-04-19: 22 commitsWeek of 2026-04-26: 21 commitsWeek of 2026-05-03: 26 commitsWeek of 2026-05-10: 16 commitsWeek of 2026-05-17: 8 commitsWeek of 2026-05-24: 8 commitsWeek of 2026-05-31: 5 commitsWeek of 2026-06-07: 0 commitsWeek of 2026-06-14: 0 commitsWeek of 2026-06-21: 0 commitsWeek of 2026-06-28: 0 commitsWeek of 2026-07-05: 0 commitsWeek of 2026-07-12: 0 commitsWeek of 2026-07-19: 0 commitsWeek of 2026-07-26: 0 commitsWeek of 2026-08-02: 0 commitsAug 10, 2025Aug 2, 2026
348 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 2 commitsSun 1:00 — 0 commitsSun 2:00 — 3 commitsSun 3:00 — 0 commitsSun 4:00 — 1 commitsSun 5:00 — 0 commitsSun 6:00 — 7 commitsSun 7:00 — 3 commitsSun 8:00 — 4 commitsSun 9:00 — 10 commitsSun 10:00 — 8 commitsSun 11:00 — 0 commitsSun 12:00 — 2 commitsSun 13:00 — 5 commitsSun 14:00 — 7 commitsSun 15:00 — 3 commitsSun 16:00 — 3 commitsSun 17:00 — 2 commitsSun 18:00 — 0 commitsSun 19:00 — 1 commitsSun 20:00 — 2 commitsSun 21:00 — 1 commitsSun 22:00 — 0 commitsSun 23:00 — 0 commitsMon 0:00 — 1 commitsMon 1:00 — 0 commitsMon 2:00 — 0 commitsMon 3:00 — 0 commitsMon 4:00 — 0 commitsMon 5:00 — 5 commitsMon 6:00 — 3 commitsMon 7:00 — 2 commitsMon 8:00 — 6 commitsMon 9:00 — 3 commitsMon 10:00 — 0 commitsMon 11:00 — 1 commitsMon 12:00 — 2 commitsMon 13:00 — 4 commitsMon 14:00 — 2 commitsMon 15:00 — 2 commitsMon 16:00 — 3 commitsMon 17:00 — 2 commitsMon 18:00 — 1 commitsMon 19:00 — 1 commitsMon 20:00 — 1 commitsMon 21:00 — 0 commitsMon 22:00 — 3 commitsMon 23:00 — 0 commitsTue 0:00 — 1 commitsTue 1:00 — 0 commitsTue 2:00 — 2 commitsTue 3:00 — 2 commitsTue 4:00 — 0 commitsTue 5:00 — 1 commitsTue 6:00 — 0 commitsTue 7:00 — 1 commitsTue 8:00 — 2 commitsTue 9:00 — 2 commitsTue 10:00 — 4 commitsTue 11:00 — 2 commitsTue 12:00 — 1 commitsTue 13:00 — 4 commitsTue 14:00 — 3 commitsTue 15:00 — 5 commitsTue 16:00 — 3 commitsTue 17:00 — 2 commitsTue 18:00 — 0 commitsTue 19:00 — 1 commitsTue 20:00 — 0 commitsTue 21:00 — 0 commitsTue 22:00 — 0 commitsTue 23:00 — 0 commitsWed 0:00 — 0 commitsWed 1:00 — 0 commitsWed 2:00 — 0 commitsWed 3:00 — 0 commitsWed 4:00 — 0 commitsWed 5:00 — 0 commitsWed 6:00 — 0 commitsWed 7:00 — 4 commitsWed 8:00 — 3 commitsWed 9:00 — 5 commitsWed 10:00 — 4 commitsWed 11:00 — 4 commitsWed 12:00 — 5 commitsWed 13:00 — 4 commitsWed 14:00 — 3 commitsWed 15:00 — 2 commitsWed 16:00 — 2 commitsWed 17:00 — 0 commitsWed 18:00 — 1 commitsWed 19:00 — 0 commitsWed 20:00 — 3 commitsWed 21:00 — 1 commitsWed 22:00 — 0 commitsWed 23:00 — 0 commitsThu 0:00 — 4 commitsThu 1:00 — 18 commitsThu 2:00 — 3 commitsThu 3:00 — 0 commitsThu 4:00 — 0 commitsThu 5:00 — 1 commitsThu 6:00 — 0 commitsThu 7:00 — 2 commitsThu 8:00 — 0 commitsThu 9:00 — 3 commitsThu 10:00 — 2 commitsThu 11:00 — 3 commitsThu 12:00 — 4 commitsThu 13:00 — 3 commitsThu 14:00 — 4 commitsThu 15:00 — 3 commitsThu 16:00 — 2 commitsThu 17:00 — 0 commitsThu 18:00 — 0 commitsThu 19:00 — 3 commitsThu 20:00 — 0 commitsThu 21:00 — 0 commitsThu 22:00 — 2 commitsThu 23:00 — 2 commitsFri 0:00 — 2 commitsFri 1:00 — 0 commitsFri 2:00 — 0 commitsFri 3:00 — 2 commitsFri 4:00 — 2 commitsFri 5:00 — 1 commitsFri 6:00 — 1 commitsFri 7:00 — 1 commitsFri 8:00 — 5 commitsFri 9:00 — 10 commitsFri 10:00 — 10 commitsFri 11:00 — 4 commitsFri 12:00 — 2 commitsFri 13:00 — 4 commitsFri 14:00 — 1 commitsFri 15:00 — 1 commitsFri 16:00 — 2 commitsFri 17:00 — 2 commitsFri 18:00 — 2 commitsFri 19:00 — 2 commitsFri 20:00 — 1 commitsFri 21:00 — 0 commitsFri 22:00 — 1 commitsFri 23:00 — 1 commitsSat 0:00 — 0 commitsSat 1:00 — 1 commitsSat 2:00 — 0 commitsSat 3:00 — 1 commitsSat 4:00 — 0 commitsSat 5:00 — 1 commitsSat 6:00 — 3 commitsSat 7:00 — 3 commitsSat 8:00 — 4 commitsSat 9:00 — 4 commitsSat 10:00 — 4 commitsSat 11:00 — 4 commitsSat 12:00 — 3 commitsSat 13:00 — 2 commitsSat 14:00 — 5 commitsSat 15:00 — 0 commitsSat 16:00 — 2 commitsSat 17:00 — 4 commitsSat 18:00 — 1 commitsSat 19:00 — 7 commitsSat 20:00 — 0 commitsSat 21:00 — 1 commitsSat 22:00 — 1 commitsSat 23:00 — 1 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.
DateListRankStars gained
Apr 6, 2026daily#12+260
Apr 5, 2026daily#8+448
Apr 4, 2026daily#9+331
Apr 3, 2026daily#18+258