@zhijiewang/openharness 0.11.1 → 0.12.1
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 +212 -23
- package/dist/DeferredTool.d.ts +34 -0
- package/dist/DeferredTool.js +62 -0
- package/dist/agents/roles.js +62 -6
- package/dist/commands/index.js +31 -2
- package/dist/harness/config.d.ts +15 -0
- package/dist/harness/config.js +45 -23
- package/dist/harness/memory.d.ts +12 -0
- package/dist/harness/memory.js +53 -2
- package/dist/harness/session.d.ts +19 -0
- package/dist/harness/session.js +53 -0
- package/dist/harness/verification.d.ts +41 -0
- package/dist/harness/verification.js +197 -0
- package/dist/mcp/registry.d.ts +31 -0
- package/dist/mcp/registry.js +180 -0
- package/dist/query/index.js +9 -1
- package/dist/query/tools.js +30 -4
- package/dist/repl.js +34 -0
- package/dist/services/AgentDispatcher.d.ts +1 -0
- package/dist/services/AgentDispatcher.js +10 -1
- package/dist/services/CronExecutor.d.ts +38 -0
- package/dist/services/CronExecutor.js +130 -0
- package/dist/services/StreamingToolExecutor.js +28 -0
- package/dist/services/cron.d.ts +4 -0
- package/dist/services/cron.js +27 -0
- package/dist/tools/AgentTool/index.d.ts +3 -0
- package/dist/tools/AgentTool/index.js +17 -4
- package/dist/tools/MemoryTool/index.d.ts +2 -2
- package/dist/tools/ToolSearchTool/index.js +7 -0
- package/dist/tools.d.ts +8 -0
- package/dist/tools.js +40 -41
- package/package.json +5 -2
- package/dist/Tool.d.ts.map +0 -1
- package/dist/Tool.js.map +0 -1
- package/dist/Tool.test.d.ts +0 -2
- package/dist/Tool.test.d.ts.map +0 -1
- package/dist/Tool.test.js +0 -48
- package/dist/Tool.test.js.map +0 -1
- package/dist/agents/roles.d.ts.map +0 -1
- package/dist/agents/roles.js.map +0 -1
- package/dist/agents/roles.test.d.ts +0 -2
- package/dist/agents/roles.test.d.ts.map +0 -1
- package/dist/agents/roles.test.js +0 -38
- package/dist/agents/roles.test.js.map +0 -1
- package/dist/commands/commands-new.test.d.ts +0 -5
- package/dist/commands/commands-new.test.d.ts.map +0 -1
- package/dist/commands/commands-new.test.js +0 -132
- package/dist/commands/commands-new.test.js.map +0 -1
- package/dist/commands/commands.test.d.ts +0 -2
- package/dist/commands/commands.test.d.ts.map +0 -1
- package/dist/commands/commands.test.js +0 -98
- package/dist/commands/commands.test.js.map +0 -1
- package/dist/commands/cybergotchi.d.ts.map +0 -1
- package/dist/commands/cybergotchi.js.map +0 -1
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js.map +0 -1
- package/dist/components/App.d.ts.map +0 -1
- package/dist/components/App.js.map +0 -1
- package/dist/components/CompanionFooter.d.ts.map +0 -1
- package/dist/components/CompanionFooter.js.map +0 -1
- package/dist/components/CybergotchiBubble.d.ts.map +0 -1
- package/dist/components/CybergotchiBubble.js.map +0 -1
- package/dist/components/CybergotchiPanel.d.ts.map +0 -1
- package/dist/components/CybergotchiPanel.js.map +0 -1
- package/dist/components/CybergotchiPanelConnected.d.ts.map +0 -1
- package/dist/components/CybergotchiPanelConnected.js.map +0 -1
- package/dist/components/CybergotchiSetup.d.ts.map +0 -1
- package/dist/components/CybergotchiSetup.js.map +0 -1
- package/dist/components/CybergotchiSprite.d.ts.map +0 -1
- package/dist/components/CybergotchiSprite.js.map +0 -1
- package/dist/components/DiffView.d.ts.map +0 -1
- package/dist/components/DiffView.js.map +0 -1
- package/dist/components/ErrorBoundary.d.ts.map +0 -1
- package/dist/components/ErrorBoundary.js.map +0 -1
- package/dist/components/InitWizard.d.ts.map +0 -1
- package/dist/components/InitWizard.js.map +0 -1
- package/dist/components/Markdown.d.ts.map +0 -1
- package/dist/components/Markdown.js.map +0 -1
- package/dist/components/Messages.d.ts.map +0 -1
- package/dist/components/Messages.js.map +0 -1
- package/dist/components/PermissionPrompt.d.ts.map +0 -1
- package/dist/components/PermissionPrompt.js.map +0 -1
- package/dist/components/REPL.d.ts.map +0 -1
- package/dist/components/REPL.js.map +0 -1
- package/dist/components/Spinner.d.ts.map +0 -1
- package/dist/components/Spinner.js.map +0 -1
- package/dist/components/TextInput.d.ts.map +0 -1
- package/dist/components/TextInput.js.map +0 -1
- package/dist/components/ToolCallDisplay.d.ts.map +0 -1
- package/dist/components/ToolCallDisplay.js.map +0 -1
- package/dist/cybergotchi/bones.d.ts.map +0 -1
- package/dist/cybergotchi/bones.js.map +0 -1
- package/dist/cybergotchi/bones.test.d.ts +0 -2
- package/dist/cybergotchi/bones.test.d.ts.map +0 -1
- package/dist/cybergotchi/bones.test.js +0 -100
- package/dist/cybergotchi/bones.test.js.map +0 -1
- package/dist/cybergotchi/config.d.ts.map +0 -1
- package/dist/cybergotchi/config.js.map +0 -1
- package/dist/cybergotchi/events.d.ts.map +0 -1
- package/dist/cybergotchi/events.js.map +0 -1
- package/dist/cybergotchi/needs.d.ts.map +0 -1
- package/dist/cybergotchi/needs.js.map +0 -1
- package/dist/cybergotchi/needs.test.d.ts +0 -2
- package/dist/cybergotchi/needs.test.d.ts.map +0 -1
- package/dist/cybergotchi/needs.test.js +0 -150
- package/dist/cybergotchi/needs.test.js.map +0 -1
- package/dist/cybergotchi/personality.d.ts.map +0 -1
- package/dist/cybergotchi/personality.js.map +0 -1
- package/dist/cybergotchi/species.d.ts.map +0 -1
- package/dist/cybergotchi/species.js.map +0 -1
- package/dist/cybergotchi/speech.d.ts.map +0 -1
- package/dist/cybergotchi/speech.js.map +0 -1
- package/dist/cybergotchi/types.d.ts.map +0 -1
- package/dist/cybergotchi/types.js.map +0 -1
- package/dist/cybergotchi/useCybergotchi.d.ts.map +0 -1
- package/dist/cybergotchi/useCybergotchi.js.map +0 -1
- package/dist/git/git.test.d.ts +0 -2
- package/dist/git/git.test.d.ts.map +0 -1
- package/dist/git/git.test.js +0 -141
- package/dist/git/git.test.js.map +0 -1
- package/dist/git/index.d.ts.map +0 -1
- package/dist/git/index.js.map +0 -1
- package/dist/harness/checkpoints.d.ts.map +0 -1
- package/dist/harness/checkpoints.js.map +0 -1
- package/dist/harness/config.d.ts.map +0 -1
- package/dist/harness/config.js.map +0 -1
- package/dist/harness/config.test.d.ts +0 -2
- package/dist/harness/config.test.d.ts.map +0 -1
- package/dist/harness/config.test.js +0 -107
- package/dist/harness/config.test.js.map +0 -1
- package/dist/harness/context-warning.d.ts.map +0 -1
- package/dist/harness/context-warning.js.map +0 -1
- package/dist/harness/context-warning.test.d.ts +0 -2
- package/dist/harness/context-warning.test.d.ts.map +0 -1
- package/dist/harness/context-warning.test.js +0 -72
- package/dist/harness/context-warning.test.js.map +0 -1
- package/dist/harness/cost.d.ts.map +0 -1
- package/dist/harness/cost.js.map +0 -1
- package/dist/harness/cost.test.d.ts +0 -2
- package/dist/harness/cost.test.d.ts.map +0 -1
- package/dist/harness/cost.test.js +0 -43
- package/dist/harness/cost.test.js.map +0 -1
- package/dist/harness/credentials.d.ts.map +0 -1
- package/dist/harness/credentials.js.map +0 -1
- package/dist/harness/credentials.test.d.ts +0 -2
- package/dist/harness/credentials.test.d.ts.map +0 -1
- package/dist/harness/credentials.test.js +0 -113
- package/dist/harness/credentials.test.js.map +0 -1
- package/dist/harness/hooks-env.test.d.ts +0 -5
- package/dist/harness/hooks-env.test.d.ts.map +0 -1
- package/dist/harness/hooks-env.test.js +0 -41
- package/dist/harness/hooks-env.test.js.map +0 -1
- package/dist/harness/hooks.d.ts.map +0 -1
- package/dist/harness/hooks.js.map +0 -1
- package/dist/harness/hooks.test.d.ts +0 -2
- package/dist/harness/hooks.test.d.ts.map +0 -1
- package/dist/harness/hooks.test.js +0 -24
- package/dist/harness/hooks.test.js.map +0 -1
- package/dist/harness/keybindings.d.ts.map +0 -1
- package/dist/harness/keybindings.js.map +0 -1
- package/dist/harness/keybindings.test.d.ts +0 -2
- package/dist/harness/keybindings.test.d.ts.map +0 -1
- package/dist/harness/keybindings.test.js +0 -38
- package/dist/harness/keybindings.test.js.map +0 -1
- package/dist/harness/memory.d.ts.map +0 -1
- package/dist/harness/memory.js.map +0 -1
- package/dist/harness/memory.test.d.ts +0 -2
- package/dist/harness/memory.test.d.ts.map +0 -1
- package/dist/harness/memory.test.js +0 -65
- package/dist/harness/memory.test.js.map +0 -1
- package/dist/harness/onboarding.d.ts.map +0 -1
- package/dist/harness/onboarding.js.map +0 -1
- package/dist/harness/onboarding.test.d.ts +0 -5
- package/dist/harness/onboarding.test.d.ts.map +0 -1
- package/dist/harness/onboarding.test.js +0 -93
- package/dist/harness/onboarding.test.js.map +0 -1
- package/dist/harness/plugins.d.ts.map +0 -1
- package/dist/harness/plugins.js.map +0 -1
- package/dist/harness/plugins.test.d.ts +0 -2
- package/dist/harness/plugins.test.d.ts.map +0 -1
- package/dist/harness/plugins.test.js +0 -97
- package/dist/harness/plugins.test.js.map +0 -1
- package/dist/harness/rules.d.ts.map +0 -1
- package/dist/harness/rules.js.map +0 -1
- package/dist/harness/rules.test.d.ts +0 -2
- package/dist/harness/rules.test.d.ts.map +0 -1
- package/dist/harness/rules.test.js +0 -54
- package/dist/harness/rules.test.js.map +0 -1
- package/dist/harness/session.d.ts.map +0 -1
- package/dist/harness/session.js.map +0 -1
- package/dist/harness/session.test.d.ts +0 -2
- package/dist/harness/session.test.d.ts.map +0 -1
- package/dist/harness/session.test.js +0 -37
- package/dist/harness/session.test.js.map +0 -1
- package/dist/harness/store.d.ts.map +0 -1
- package/dist/harness/store.js.map +0 -1
- package/dist/harness/store.test.d.ts +0 -2
- package/dist/harness/store.test.d.ts.map +0 -1
- package/dist/harness/store.test.js +0 -71
- package/dist/harness/store.test.js.map +0 -1
- package/dist/harness/submit-handler.d.ts.map +0 -1
- package/dist/harness/submit-handler.js.map +0 -1
- package/dist/harness/submit-handler.test.d.ts +0 -2
- package/dist/harness/submit-handler.test.d.ts.map +0 -1
- package/dist/harness/submit-handler.test.js +0 -62
- package/dist/harness/submit-handler.test.js.map +0 -1
- package/dist/lsp/client.d.ts.map +0 -1
- package/dist/lsp/client.js.map +0 -1
- package/dist/lsp/client.test.d.ts +0 -2
- package/dist/lsp/client.test.d.ts.map +0 -1
- package/dist/lsp/client.test.js +0 -44
- package/dist/lsp/client.test.js.map +0 -1
- package/dist/main.d.ts.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/mcp/DeferredMcpTool.d.ts.map +0 -1
- package/dist/mcp/DeferredMcpTool.js.map +0 -1
- package/dist/mcp/McpTool.d.ts.map +0 -1
- package/dist/mcp/McpTool.js.map +0 -1
- package/dist/mcp/McpTool.test.d.ts +0 -2
- package/dist/mcp/McpTool.test.d.ts.map +0 -1
- package/dist/mcp/McpTool.test.js +0 -53
- package/dist/mcp/McpTool.test.js.map +0 -1
- package/dist/mcp/client.d.ts.map +0 -1
- package/dist/mcp/client.js.map +0 -1
- package/dist/mcp/loader.d.ts.map +0 -1
- package/dist/mcp/loader.js.map +0 -1
- package/dist/mcp/loader.test.d.ts +0 -7
- package/dist/mcp/loader.test.d.ts.map +0 -1
- package/dist/mcp/loader.test.js +0 -25
- package/dist/mcp/loader.test.js.map +0 -1
- package/dist/mcp/schema.d.ts.map +0 -1
- package/dist/mcp/schema.js.map +0 -1
- package/dist/mcp/schema.test.d.ts +0 -2
- package/dist/mcp/schema.test.d.ts.map +0 -1
- package/dist/mcp/schema.test.js +0 -33
- package/dist/mcp/schema.test.js.map +0 -1
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/server.test.d.ts +0 -2
- package/dist/mcp/server.test.d.ts.map +0 -1
- package/dist/mcp/server.test.js +0 -54
- package/dist/mcp/server.test.js.map +0 -1
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/mcp/types.js.map +0 -1
- package/dist/providers/anthropic-convert.test.d.ts +0 -5
- package/dist/providers/anthropic-convert.test.d.ts.map +0 -1
- package/dist/providers/anthropic-convert.test.js +0 -98
- package/dist/providers/anthropic-convert.test.js.map +0 -1
- package/dist/providers/anthropic.d.ts.map +0 -1
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/anthropic.test.d.ts +0 -2
- package/dist/providers/anthropic.test.d.ts.map +0 -1
- package/dist/providers/anthropic.test.js +0 -18
- package/dist/providers/anthropic.test.js.map +0 -1
- package/dist/providers/base.d.ts.map +0 -1
- package/dist/providers/base.js.map +0 -1
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/llamacpp.d.ts.map +0 -1
- package/dist/providers/llamacpp.js.map +0 -1
- package/dist/providers/llamacpp.test.d.ts +0 -2
- package/dist/providers/llamacpp.test.d.ts.map +0 -1
- package/dist/providers/llamacpp.test.js +0 -33
- package/dist/providers/llamacpp.test.js.map +0 -1
- package/dist/providers/message-format.test.d.ts +0 -2
- package/dist/providers/message-format.test.d.ts.map +0 -1
- package/dist/providers/message-format.test.js +0 -31
- package/dist/providers/message-format.test.js.map +0 -1
- package/dist/providers/ollama.d.ts.map +0 -1
- package/dist/providers/ollama.js.map +0 -1
- package/dist/providers/ollama.test.d.ts +0 -2
- package/dist/providers/ollama.test.d.ts.map +0 -1
- package/dist/providers/ollama.test.js +0 -40
- package/dist/providers/ollama.test.js.map +0 -1
- package/dist/providers/openai.d.ts.map +0 -1
- package/dist/providers/openai.js.map +0 -1
- package/dist/providers/openai.test.d.ts +0 -2
- package/dist/providers/openai.test.d.ts.map +0 -1
- package/dist/providers/openai.test.js +0 -23
- package/dist/providers/openai.test.js.map +0 -1
- package/dist/providers/openrouter.d.ts.map +0 -1
- package/dist/providers/openrouter.js.map +0 -1
- package/dist/providers/stream-parsing.test.d.ts +0 -6
- package/dist/providers/stream-parsing.test.d.ts.map +0 -1
- package/dist/providers/stream-parsing.test.js +0 -174
- package/dist/providers/stream-parsing.test.js.map +0 -1
- package/dist/query/compress.d.ts.map +0 -1
- package/dist/query/compress.js.map +0 -1
- package/dist/query/errors.d.ts.map +0 -1
- package/dist/query/errors.js.map +0 -1
- package/dist/query/index.d.ts.map +0 -1
- package/dist/query/index.js.map +0 -1
- package/dist/query/tools.d.ts.map +0 -1
- package/dist/query/tools.js.map +0 -1
- package/dist/query/types.d.ts.map +0 -1
- package/dist/query/types.js.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js.map +0 -1
- package/dist/query.test.d.ts +0 -2
- package/dist/query.test.d.ts.map +0 -1
- package/dist/query.test.js +0 -121
- package/dist/query.test.js.map +0 -1
- package/dist/remote/server.d.ts.map +0 -1
- package/dist/remote/server.js.map +0 -1
- package/dist/remote/server.test.d.ts +0 -2
- package/dist/remote/server.test.d.ts.map +0 -1
- package/dist/remote/server.test.js +0 -120
- package/dist/remote/server.test.js.map +0 -1
- package/dist/renderer/cells.d.ts.map +0 -1
- package/dist/renderer/cells.js.map +0 -1
- package/dist/renderer/cells.test.d.ts +0 -2
- package/dist/renderer/cells.test.d.ts.map +0 -1
- package/dist/renderer/cells.test.js +0 -69
- package/dist/renderer/cells.test.js.map +0 -1
- package/dist/renderer/colors.d.ts.map +0 -1
- package/dist/renderer/colors.js.map +0 -1
- package/dist/renderer/diff.d.ts.map +0 -1
- package/dist/renderer/diff.js.map +0 -1
- package/dist/renderer/diff.test.d.ts +0 -5
- package/dist/renderer/diff.test.d.ts.map +0 -1
- package/dist/renderer/diff.test.js +0 -140
- package/dist/renderer/diff.test.js.map +0 -1
- package/dist/renderer/differ.d.ts.map +0 -1
- package/dist/renderer/differ.js.map +0 -1
- package/dist/renderer/e2e.test.d.ts +0 -6
- package/dist/renderer/e2e.test.d.ts.map +0 -1
- package/dist/renderer/e2e.test.js +0 -702
- package/dist/renderer/e2e.test.js.map +0 -1
- package/dist/renderer/image.d.ts.map +0 -1
- package/dist/renderer/image.js.map +0 -1
- package/dist/renderer/image.test.d.ts +0 -5
- package/dist/renderer/image.test.d.ts.map +0 -1
- package/dist/renderer/image.test.js +0 -66
- package/dist/renderer/image.test.js.map +0 -1
- package/dist/renderer/index.d.ts.map +0 -1
- package/dist/renderer/index.js.map +0 -1
- package/dist/renderer/input.d.ts.map +0 -1
- package/dist/renderer/input.js.map +0 -1
- package/dist/renderer/input.test.d.ts +0 -5
- package/dist/renderer/input.test.d.ts.map +0 -1
- package/dist/renderer/input.test.js +0 -129
- package/dist/renderer/input.test.js.map +0 -1
- package/dist/renderer/layout.d.ts.map +0 -1
- package/dist/renderer/layout.js.map +0 -1
- package/dist/renderer/markdown.d.ts.map +0 -1
- package/dist/renderer/markdown.js.map +0 -1
- package/dist/renderer/markdown.test.d.ts +0 -2
- package/dist/renderer/markdown.test.d.ts.map +0 -1
- package/dist/renderer/markdown.test.js +0 -81
- package/dist/renderer/markdown.test.js.map +0 -1
- package/dist/renderer/perf.test.d.ts +0 -2
- package/dist/renderer/perf.test.d.ts.map +0 -1
- package/dist/renderer/perf.test.js +0 -128
- package/dist/renderer/perf.test.js.map +0 -1
- package/dist/renderer/session-browser.d.ts.map +0 -1
- package/dist/renderer/session-browser.js.map +0 -1
- package/dist/renderer/session-browser.test.d.ts +0 -6
- package/dist/renderer/session-browser.test.d.ts.map +0 -1
- package/dist/renderer/session-browser.test.js +0 -95
- package/dist/renderer/session-browser.test.js.map +0 -1
- package/dist/renderer/ui-ux.test.d.ts +0 -15
- package/dist/renderer/ui-ux.test.d.ts.map +0 -1
- package/dist/renderer/ui-ux.test.js +0 -470
- package/dist/renderer/ui-ux.test.js.map +0 -1
- package/dist/repl.d.ts.map +0 -1
- package/dist/repl.js.map +0 -1
- package/dist/services/AgentDispatcher.d.ts.map +0 -1
- package/dist/services/AgentDispatcher.js.map +0 -1
- package/dist/services/AgentDispatcher.test.d.ts +0 -2
- package/dist/services/AgentDispatcher.test.d.ts.map +0 -1
- package/dist/services/AgentDispatcher.test.js +0 -66
- package/dist/services/AgentDispatcher.test.js.map +0 -1
- package/dist/services/StreamingToolExecutor.d.ts.map +0 -1
- package/dist/services/StreamingToolExecutor.js.map +0 -1
- package/dist/services/StreamingToolExecutor.test.d.ts +0 -2
- package/dist/services/StreamingToolExecutor.test.d.ts.map +0 -1
- package/dist/services/StreamingToolExecutor.test.js +0 -103
- package/dist/services/StreamingToolExecutor.test.js.map +0 -1
- package/dist/services/agent-messaging.d.ts.map +0 -1
- package/dist/services/agent-messaging.js.map +0 -1
- package/dist/services/agent-messaging.test.d.ts +0 -2
- package/dist/services/agent-messaging.test.d.ts.map +0 -1
- package/dist/services/agent-messaging.test.js +0 -88
- package/dist/services/agent-messaging.test.js.map +0 -1
- package/dist/services/cron.d.ts.map +0 -1
- package/dist/services/cron.js.map +0 -1
- package/dist/services/cron.test.d.ts +0 -2
- package/dist/services/cron.test.d.ts.map +0 -1
- package/dist/services/cron.test.js +0 -49
- package/dist/services/cron.test.js.map +0 -1
- package/dist/test-helpers.d.ts +0 -31
- package/dist/test-helpers.d.ts.map +0 -1
- package/dist/test-helpers.js +0 -106
- package/dist/test-helpers.js.map +0 -1
- package/dist/tools/AgentTool/index.d.ts.map +0 -1
- package/dist/tools/AgentTool/index.js.map +0 -1
- package/dist/tools/AskUserTool/index.d.ts.map +0 -1
- package/dist/tools/AskUserTool/index.js.map +0 -1
- package/dist/tools/BashTool/index.d.ts.map +0 -1
- package/dist/tools/BashTool/index.js.map +0 -1
- package/dist/tools/CronTool/index.d.ts.map +0 -1
- package/dist/tools/CronTool/index.js.map +0 -1
- package/dist/tools/DiagnosticsTool/index.d.ts.map +0 -1
- package/dist/tools/DiagnosticsTool/index.js.map +0 -1
- package/dist/tools/EnterPlanModeTool/index.d.ts.map +0 -1
- package/dist/tools/EnterPlanModeTool/index.js.map +0 -1
- package/dist/tools/EnterWorktreeTool/index.d.ts.map +0 -1
- package/dist/tools/EnterWorktreeTool/index.js.map +0 -1
- package/dist/tools/ExitPlanModeTool/index.d.ts.map +0 -1
- package/dist/tools/ExitPlanModeTool/index.js.map +0 -1
- package/dist/tools/ExitWorktreeTool/index.d.ts.map +0 -1
- package/dist/tools/ExitWorktreeTool/index.js.map +0 -1
- package/dist/tools/FileEditTool/index.d.ts.map +0 -1
- package/dist/tools/FileEditTool/index.js.map +0 -1
- package/dist/tools/FileReadTool/index.d.ts.map +0 -1
- package/dist/tools/FileReadTool/index.js.map +0 -1
- package/dist/tools/FileWriteTool/index.d.ts.map +0 -1
- package/dist/tools/FileWriteTool/index.js.map +0 -1
- package/dist/tools/GlobTool/index.d.ts.map +0 -1
- package/dist/tools/GlobTool/index.js.map +0 -1
- package/dist/tools/GrepTool/index.d.ts.map +0 -1
- package/dist/tools/GrepTool/index.js.map +0 -1
- package/dist/tools/ImageReadTool/index.d.ts.map +0 -1
- package/dist/tools/ImageReadTool/index.js.map +0 -1
- package/dist/tools/KillProcessTool/index.d.ts.map +0 -1
- package/dist/tools/KillProcessTool/index.js.map +0 -1
- package/dist/tools/LSTool/index.d.ts.map +0 -1
- package/dist/tools/LSTool/index.js.map +0 -1
- package/dist/tools/MemoryTool/index.d.ts.map +0 -1
- package/dist/tools/MemoryTool/index.js.map +0 -1
- package/dist/tools/MultiEditTool/index.d.ts.map +0 -1
- package/dist/tools/MultiEditTool/index.js.map +0 -1
- package/dist/tools/NotebookEditTool/index.d.ts.map +0 -1
- package/dist/tools/NotebookEditTool/index.js.map +0 -1
- package/dist/tools/ParallelAgentTool/index.d.ts.map +0 -1
- package/dist/tools/ParallelAgentTool/index.js.map +0 -1
- package/dist/tools/RemoteTriggerTool/index.d.ts.map +0 -1
- package/dist/tools/RemoteTriggerTool/index.js.map +0 -1
- package/dist/tools/SendMessageTool/index.d.ts.map +0 -1
- package/dist/tools/SendMessageTool/index.js.map +0 -1
- package/dist/tools/SkillTool/index.d.ts.map +0 -1
- package/dist/tools/SkillTool/index.js.map +0 -1
- package/dist/tools/TaskCreateTool/index.d.ts.map +0 -1
- package/dist/tools/TaskCreateTool/index.js.map +0 -1
- package/dist/tools/TaskGetTool/index.d.ts.map +0 -1
- package/dist/tools/TaskGetTool/index.js.map +0 -1
- package/dist/tools/TaskListTool/index.d.ts.map +0 -1
- package/dist/tools/TaskListTool/index.js.map +0 -1
- package/dist/tools/TaskOutputTool/index.d.ts.map +0 -1
- package/dist/tools/TaskOutputTool/index.js.map +0 -1
- package/dist/tools/TaskStopTool/index.d.ts.map +0 -1
- package/dist/tools/TaskStopTool/index.js.map +0 -1
- package/dist/tools/TaskUpdateTool/index.d.ts.map +0 -1
- package/dist/tools/TaskUpdateTool/index.js.map +0 -1
- package/dist/tools/ToolSearchTool/index.d.ts.map +0 -1
- package/dist/tools/ToolSearchTool/index.js.map +0 -1
- package/dist/tools/WebFetchTool/index.d.ts.map +0 -1
- package/dist/tools/WebFetchTool/index.js.map +0 -1
- package/dist/tools/WebSearchTool/index.d.ts.map +0 -1
- package/dist/tools/WebSearchTool/index.js.map +0 -1
- package/dist/tools/file-edit.test.d.ts +0 -2
- package/dist/tools/file-edit.test.d.ts.map +0 -1
- package/dist/tools/file-edit.test.js +0 -35
- package/dist/tools/file-edit.test.js.map +0 -1
- package/dist/tools/tools-basic.test.d.ts +0 -6
- package/dist/tools/tools-basic.test.d.ts.map +0 -1
- package/dist/tools/tools-basic.test.js +0 -379
- package/dist/tools/tools-basic.test.js.map +0 -1
- package/dist/tools/web-fetch.test.d.ts +0 -2
- package/dist/tools/web-fetch.test.d.ts.map +0 -1
- package/dist/tools/web-fetch.test.js +0 -27
- package/dist/tools/web-fetch.test.js.map +0 -1
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js.map +0 -1
- package/dist/types/events.d.ts.map +0 -1
- package/dist/types/events.js.map +0 -1
- package/dist/types/message.d.ts.map +0 -1
- package/dist/types/message.js.map +0 -1
- package/dist/types/message.test.d.ts +0 -2
- package/dist/types/message.test.d.ts.map +0 -1
- package/dist/types/message.test.js +0 -46
- package/dist/types/message.test.js.map +0 -1
- package/dist/types/permissions.d.ts.map +0 -1
- package/dist/types/permissions.js.map +0 -1
- package/dist/types/permissions.test.d.ts +0 -2
- package/dist/types/permissions.test.d.ts.map +0 -1
- package/dist/types/permissions.test.js +0 -127
- package/dist/types/permissions.test.js.map +0 -1
- package/dist/utils/bash-safety.d.ts.map +0 -1
- package/dist/utils/bash-safety.js.map +0 -1
- package/dist/utils/bash-safety.test.d.ts +0 -2
- package/dist/utils/bash-safety.test.d.ts.map +0 -1
- package/dist/utils/bash-safety.test.js +0 -112
- package/dist/utils/bash-safety.test.js.map +0 -1
- package/dist/utils/diff-algorithm.d.ts.map +0 -1
- package/dist/utils/diff-algorithm.js.map +0 -1
- package/dist/utils/diff-algorithm.test.d.ts +0 -2
- package/dist/utils/diff-algorithm.test.d.ts.map +0 -1
- package/dist/utils/diff-algorithm.test.js +0 -49
- package/dist/utils/diff-algorithm.test.js.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/fs.d.ts.map +0 -1
- package/dist/utils/fs.js.map +0 -1
- package/dist/utils/fs.test.d.ts +0 -5
- package/dist/utils/fs.test.d.ts.map +0 -1
- package/dist/utils/fs.test.js +0 -82
- package/dist/utils/fs.test.js.map +0 -1
- package/dist/utils/safe-env.d.ts.map +0 -1
- package/dist/utils/safe-env.js.map +0 -1
- package/dist/utils/theme-data.d.ts.map +0 -1
- package/dist/utils/theme-data.js.map +0 -1
- package/dist/utils/theme.d.ts.map +0 -1
- package/dist/utils/theme.js.map +0 -1
- package/dist/utils/tool-summary.d.ts.map +0 -1
- package/dist/utils/tool-summary.js.map +0 -1
- package/dist/utils/tool-summary.test.d.ts +0 -2
- package/dist/utils/tool-summary.test.d.ts.map +0 -1
- package/dist/utils/tool-summary.test.js +0 -93
- package/dist/utils/tool-summary.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -17,13 +17,34 @@
|
|
|
17
17
|
|
|
18
18
|
AI coding agent in your terminal. Works with any LLM -- free local models or cloud APIs.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="assets/openharness_v0.11.1_4.gif" alt="OpenHarness demo" width="800" />
|
|
22
|
+
</p>
|
|
21
23
|
|
|
22
|
-
|
|
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)
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
---
|
|
25
27
|
|
|
26
|
-
|
|
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)
|
|
27
48
|
|
|
28
49
|
---
|
|
29
50
|
|
|
@@ -42,7 +63,17 @@ oh # auto-detect local model
|
|
|
42
63
|
oh --model ollama/qwen2.5:7b # specific model
|
|
43
64
|
oh --model gpt-4o # cloud model (needs OPENAI_API_KEY)
|
|
44
65
|
oh --trust # auto-approve all tool calls
|
|
45
|
-
oh
|
|
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
|
|
46
77
|
```
|
|
47
78
|
|
|
48
79
|
## Why OpenHarness?
|
|
@@ -53,7 +84,7 @@ Most AI coding agents are locked to one provider or cost $20+/month. OpenHarness
|
|
|
53
84
|
|---|---|---|---|---|
|
|
54
85
|
| Any LLM | Yes (Ollama, OpenAI, Anthropic, OpenRouter, any OpenAI-compatible) | Anthropic only | Yes | Yes |
|
|
55
86
|
| Free local models | Ollama native | No | Yes | Yes |
|
|
56
|
-
| Tools |
|
|
87
|
+
| Tools | 35 with permission gates | 43+ | File-focused | 20+ |
|
|
57
88
|
| Permission modes | 7 (ask, trust, deny, acceptEdits, plan, auto, bypass) | 7 | Basic | Basic |
|
|
58
89
|
| Git integration | Auto-commit + /undo + /rewind checkpoints | Yes | Deep git | Basic |
|
|
59
90
|
| Slash commands | 30+ built-in | 80+ | Some | Some |
|
|
@@ -127,33 +158,59 @@ statusLineFormat: '{model} │ {tokens} │ {cost} │ {ctx}'
|
|
|
127
158
|
|
|
128
159
|
Available variables: `{model}`, `{tokens}` (input↑ output↓), `{cost}` ($X.XXXX), `{ctx}` (context usage bar). Empty sections are automatically collapsed.
|
|
129
160
|
|
|
130
|
-
## Tools (
|
|
161
|
+
## Tools (35)
|
|
131
162
|
|
|
132
163
|
| Tool | Risk | Description |
|
|
133
164
|
|------|------|-------------|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
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 |
|
|
136
168
|
| ImageRead | low | Read images/PDFs for multimodal analysis |
|
|
137
169
|
| Write | medium | Create or overwrite files |
|
|
138
170
|
| Edit | medium | Search-and-replace edits |
|
|
171
|
+
| MultiEdit | medium | Atomic multi-file edits (all succeed or none) |
|
|
139
172
|
| Glob | low | Find files by pattern |
|
|
140
|
-
| Grep | low | Regex content search |
|
|
173
|
+
| Grep | low | Regex content search with context lines |
|
|
141
174
|
| LS | low | List directory contents with sizes |
|
|
175
|
+
| **Web** | | |
|
|
142
176
|
| WebFetch | medium | Fetch URL content (SSRF-protected) |
|
|
143
177
|
| WebSearch | medium | Search the web |
|
|
178
|
+
| RemoteTrigger | high | HTTP requests to webhooks/APIs |
|
|
179
|
+
| **Tasks** | | |
|
|
144
180
|
| TaskCreate | low | Create structured tasks |
|
|
145
181
|
| TaskUpdate | low | Update task status |
|
|
146
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 |
|
|
147
190
|
| AskUser | low | Ask user a question with options |
|
|
148
|
-
|
|
|
149
|
-
|
|
|
191
|
+
| **Scheduling** | | |
|
|
192
|
+
| CronCreate | medium | Schedule recurring tasks |
|
|
193
|
+
| CronDelete | medium | Remove scheduled tasks |
|
|
194
|
+
| CronList | low | List all scheduled tasks |
|
|
195
|
+
| **Planning** | | |
|
|
150
196
|
| EnterPlanMode | low | Enter structured planning mode |
|
|
151
197
|
| ExitPlanMode | low | Exit planning mode |
|
|
198
|
+
| **Code Intelligence** | | |
|
|
199
|
+
| Diagnostics | low | LSP-based code diagnostics |
|
|
152
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 |
|
|
153
210
|
|
|
154
|
-
Low-risk read-only tools auto-approve. Medium and high risk tools require confirmation in `ask` mode. Use `--trust` to skip
|
|
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.
|
|
155
212
|
|
|
156
|
-
## Slash Commands (
|
|
213
|
+
## Slash Commands (33)
|
|
157
214
|
|
|
158
215
|
Type these during a chat session. Aliases: `/q` exit, `/h` help, `/c` commit, `/m` model, `/s` status.
|
|
159
216
|
|
|
@@ -309,6 +366,16 @@ mcpServers:
|
|
|
309
366
|
|
|
310
367
|
MCP tools appear alongside built-in tools. `/status` shows connected servers.
|
|
311
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
|
+
|
|
312
379
|
## Git Integration
|
|
313
380
|
|
|
314
381
|
OpenHarness auto-commits AI edits in git repos:
|
|
@@ -334,6 +401,58 @@ Every file modification is automatically checkpointed before execution. If somet
|
|
|
334
401
|
|
|
335
402
|
Checkpoints are stored in `.oh/checkpoints/` and cover FileWrite, FileEdit, and Bash commands that modify files.
|
|
336
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
|
+
|
|
337
456
|
## Agent Roles
|
|
338
457
|
|
|
339
458
|
Dispatch specialized sub-agents for focused tasks:
|
|
@@ -342,16 +461,25 @@ Dispatch specialized sub-agents for focused tasks:
|
|
|
342
461
|
/roles # list all available roles
|
|
343
462
|
```
|
|
344
463
|
|
|
345
|
-
| Role | Description |
|
|
346
|
-
|
|
347
|
-
| `code-reviewer` | Find bugs, security issues, style problems |
|
|
348
|
-
| `test-writer` | Generate unit and integration tests |
|
|
349
|
-
| `docs-writer` | Write documentation and comments |
|
|
350
|
-
| `debugger` | Systematic bug investigation |
|
|
351
|
-
| `refactorer` | Simplify code without changing behavior |
|
|
352
|
-
| `security-auditor` | OWASP, injection, secrets, CVE scanning |
|
|
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:
|
|
353
478
|
|
|
354
|
-
|
|
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
|
+
```
|
|
355
483
|
|
|
356
484
|
## Headless Mode
|
|
357
485
|
|
|
@@ -446,6 +574,31 @@ oh --model llamacpp/my-model
|
|
|
446
574
|
oh models # list available models
|
|
447
575
|
```
|
|
448
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
|
+
|
|
449
602
|
## Project Rules
|
|
450
603
|
|
|
451
604
|
Create `.oh/RULES.md` in any repo (or run `oh init`):
|
|
@@ -458,6 +611,42 @@ Create `.oh/RULES.md` in any repo (or run `oh init`):
|
|
|
458
611
|
|
|
459
612
|
Rules load automatically into every session.
|
|
460
613
|
|
|
614
|
+
## How It Works
|
|
615
|
+
|
|
616
|
+
```mermaid
|
|
617
|
+
graph LR
|
|
618
|
+
User[User Input] --> REPL[REPL Loop]
|
|
619
|
+
REPL --> Query[Query Engine]
|
|
620
|
+
Query --> Provider[LLM Provider]
|
|
621
|
+
Provider --> LLM[Ollama / OpenAI / Anthropic]
|
|
622
|
+
LLM --> Tools[Tool Execution]
|
|
623
|
+
Tools --> Permissions{Permission Check}
|
|
624
|
+
Permissions -->|Approved| Execute[Run Tool]
|
|
625
|
+
Permissions -->|Blocked| Deny[Deny & Report]
|
|
626
|
+
Execute --> Response[Stream Response]
|
|
627
|
+
Response --> REPL
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
## FAQ
|
|
631
|
+
|
|
632
|
+
**Does it work offline?**
|
|
633
|
+
Yes. Use Ollama with a local model — no internet or API key needed.
|
|
634
|
+
|
|
635
|
+
**How much does it cost?**
|
|
636
|
+
Free. OpenHarness is MIT licensed. You bring your own API key (BYOK) for cloud models, or use Ollama for free.
|
|
637
|
+
|
|
638
|
+
**Is it safe?**
|
|
639
|
+
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`.
|
|
640
|
+
|
|
641
|
+
**Can I use it in CI/CD?**
|
|
642
|
+
Yes. Use `oh -p "prompt" --auto` for headless execution, or the built-in GitHub Action for PR reviews.
|
|
643
|
+
|
|
644
|
+
**Does it support my language/framework?**
|
|
645
|
+
Yes. OpenHarness is language-agnostic — it reads, writes, and executes code in any language. Syntax highlighting covers 20+ languages.
|
|
646
|
+
|
|
647
|
+
**How does it compare to Claude Code?**
|
|
648
|
+
~90% feature parity for CLI use cases. Main advantage: works with ANY LLM (not just Anthropic). See the [comparison table](#why-openharness) above.
|
|
649
|
+
|
|
461
650
|
## Install
|
|
462
651
|
|
|
463
652
|
Requires **Node.js 18+**.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeferredTool — lazy-loads tool schemas to reduce system prompt size.
|
|
3
|
+
*
|
|
4
|
+
* Wraps a built-in tool with a minimal prompt (name + description only).
|
|
5
|
+
* Full schema and prompt are loaded on first invocation or when resolved
|
|
6
|
+
* via ToolSearch. This mirrors the DeferredMcpTool pattern.
|
|
7
|
+
*
|
|
8
|
+
* Token savings: deferred tools contribute ~15 tokens to the system prompt
|
|
9
|
+
* instead of ~150, reducing context pressure by ~90% per deferred tool.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import type { Tool, ToolContext, ToolResult } from "./Tool.js";
|
|
13
|
+
import type { RiskLevel } from "./types/permissions.js";
|
|
14
|
+
export declare class DeferredTool implements Tool<z.ZodType> {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly description: string;
|
|
17
|
+
readonly inputSchema: z.ZodType;
|
|
18
|
+
readonly riskLevel: RiskLevel;
|
|
19
|
+
private inner;
|
|
20
|
+
private _activated;
|
|
21
|
+
constructor(tool: Tool);
|
|
22
|
+
/** Whether this tool has been activated (called or resolved) */
|
|
23
|
+
get activated(): boolean;
|
|
24
|
+
isReadOnly(input: unknown): boolean;
|
|
25
|
+
isConcurrencySafe(input: unknown): boolean;
|
|
26
|
+
call(input: any, context: ToolContext): Promise<ToolResult>;
|
|
27
|
+
/** Minimal prompt when deferred, full prompt when activated */
|
|
28
|
+
prompt(): string;
|
|
29
|
+
/** Get the full inner tool (for ToolSearch resolution) */
|
|
30
|
+
getInner(): Tool;
|
|
31
|
+
/** Activate this tool so it returns full prompt on next call to prompt() */
|
|
32
|
+
activate(): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=DeferredTool.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeferredTool — lazy-loads tool schemas to reduce system prompt size.
|
|
3
|
+
*
|
|
4
|
+
* Wraps a built-in tool with a minimal prompt (name + description only).
|
|
5
|
+
* Full schema and prompt are loaded on first invocation or when resolved
|
|
6
|
+
* via ToolSearch. This mirrors the DeferredMcpTool pattern.
|
|
7
|
+
*
|
|
8
|
+
* Token savings: deferred tools contribute ~15 tokens to the system prompt
|
|
9
|
+
* instead of ~150, reducing context pressure by ~90% per deferred tool.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
export class DeferredTool {
|
|
13
|
+
name;
|
|
14
|
+
description;
|
|
15
|
+
inputSchema;
|
|
16
|
+
riskLevel;
|
|
17
|
+
inner;
|
|
18
|
+
_activated = false;
|
|
19
|
+
constructor(tool) {
|
|
20
|
+
this.inner = tool;
|
|
21
|
+
this.name = tool.name;
|
|
22
|
+
this.description = tool.description;
|
|
23
|
+
this.riskLevel = tool.riskLevel;
|
|
24
|
+
// Permissive schema until activated — accepts any object
|
|
25
|
+
this.inputSchema = z.record(z.unknown());
|
|
26
|
+
}
|
|
27
|
+
/** Whether this tool has been activated (called or resolved) */
|
|
28
|
+
get activated() { return this._activated; }
|
|
29
|
+
isReadOnly(input) {
|
|
30
|
+
return this.inner.isReadOnly(input);
|
|
31
|
+
}
|
|
32
|
+
isConcurrencySafe(input) {
|
|
33
|
+
return this.inner.isConcurrencySafe(input);
|
|
34
|
+
}
|
|
35
|
+
async call(input, context) {
|
|
36
|
+
this._activated = true;
|
|
37
|
+
// Validate with the real schema
|
|
38
|
+
const parsed = this.inner.inputSchema.safeParse(input);
|
|
39
|
+
if (!parsed.success) {
|
|
40
|
+
return {
|
|
41
|
+
output: `Schema validation error: ${parsed.error.message}`,
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return this.inner.call(parsed.data, context);
|
|
46
|
+
}
|
|
47
|
+
/** Minimal prompt when deferred, full prompt when activated */
|
|
48
|
+
prompt() {
|
|
49
|
+
if (this._activated)
|
|
50
|
+
return this.inner.prompt();
|
|
51
|
+
return `[deferred] ${this.name}: ${this.description}`;
|
|
52
|
+
}
|
|
53
|
+
/** Get the full inner tool (for ToolSearch resolution) */
|
|
54
|
+
getInner() {
|
|
55
|
+
return this.inner;
|
|
56
|
+
}
|
|
57
|
+
/** Activate this tool so it returns full prompt on next call to prompt() */
|
|
58
|
+
activate() {
|
|
59
|
+
this._activated = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=DeferredTool.js.map
|
package/dist/agents/roles.js
CHANGED
|
@@ -21,7 +21,7 @@ const roles = [
|
|
|
21
21
|
- Verify that changes match the stated intent
|
|
22
22
|
|
|
23
23
|
Be specific: cite file paths, line numbers, and code snippets. Prioritize issues by severity (critical > major > minor). Don't mention things that look fine — focus on problems.`,
|
|
24
|
-
suggestedTools: ['
|
|
24
|
+
suggestedTools: ['Read', 'Glob', 'Grep', 'LS'],
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
id: 'test-writer',
|
|
@@ -36,7 +36,7 @@ Be specific: cite file paths, line numbers, and code snippets. Prioritize issues
|
|
|
36
36
|
- Include both positive and negative test cases
|
|
37
37
|
|
|
38
38
|
Read existing tests first to match the style, then write new tests.`,
|
|
39
|
-
suggestedTools: ['
|
|
39
|
+
suggestedTools: ['Read', 'Write', 'Glob', 'Grep', 'Bash'],
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
id: 'docs-writer',
|
|
@@ -51,7 +51,7 @@ Read existing tests first to match the style, then write new tests.`,
|
|
|
51
51
|
- Keep documentation in sync with the actual code
|
|
52
52
|
|
|
53
53
|
Write for the target audience (developers using this project). Be practical, not verbose.`,
|
|
54
|
-
suggestedTools: ['
|
|
54
|
+
suggestedTools: ['Read', 'Write', 'Edit', 'Glob', 'Grep'],
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
id: 'debugger',
|
|
@@ -66,7 +66,7 @@ Write for the target audience (developers using this project). Be practical, not
|
|
|
66
66
|
- Propose a minimal fix that addresses the root cause, not the symptom
|
|
67
67
|
|
|
68
68
|
Follow systematic debugging: read errors → reproduce → check changes → trace data → form hypothesis → test minimally.`,
|
|
69
|
-
suggestedTools: ['
|
|
69
|
+
suggestedTools: ['Read', 'Glob', 'Grep', 'Bash', 'LS'],
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
id: 'refactorer',
|
|
@@ -81,7 +81,7 @@ Follow systematic debugging: read errors → reproduce → check changes → tra
|
|
|
81
81
|
- Ensure all existing tests still pass after refactoring
|
|
82
82
|
|
|
83
83
|
Do NOT add new features or change behavior. The refactored code must be functionally identical. Run tests after each change.`,
|
|
84
|
-
suggestedTools: ['
|
|
84
|
+
suggestedTools: ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash'],
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
87
|
id: 'security-auditor',
|
|
@@ -98,7 +98,63 @@ Do NOT add new features or change behavior. The refactored code must be function
|
|
|
98
98
|
- Check dependency versions for known CVEs
|
|
99
99
|
|
|
100
100
|
Report findings with severity (Critical/High/Medium/Low), affected file:line, and recommended fix.`,
|
|
101
|
-
suggestedTools: ['
|
|
101
|
+
suggestedTools: ['Read', 'Glob', 'Grep', 'Bash'],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'evaluator',
|
|
105
|
+
name: 'Evaluator',
|
|
106
|
+
description: 'Evaluates code quality, correctness, and test results (read-only)',
|
|
107
|
+
systemPromptSupplement: `You are an evaluator agent. Your job is to:
|
|
108
|
+
- Review code changes for correctness and quality
|
|
109
|
+
- Run existing tests and report results
|
|
110
|
+
- Check for regressions against the stated requirements
|
|
111
|
+
- Verify that changes match the stated intent
|
|
112
|
+
- Provide a pass/fail assessment with specific findings
|
|
113
|
+
|
|
114
|
+
You CANNOT modify files. Only read, search, and run test/lint commands to evaluate.`,
|
|
115
|
+
suggestedTools: ['Read', 'Glob', 'Grep', 'LS', 'Bash', 'Diagnostics'],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'planner',
|
|
119
|
+
name: 'Planner',
|
|
120
|
+
description: 'Designs step-by-step implementation plans from requirements',
|
|
121
|
+
systemPromptSupplement: `You are a planning agent. Your job is to:
|
|
122
|
+
- Read the codebase to understand architecture, patterns, and conventions
|
|
123
|
+
- Design a detailed step-by-step implementation plan for the given task
|
|
124
|
+
- Identify files to create, modify, or delete with specific change descriptions
|
|
125
|
+
- Flag risks, dependencies, and the recommended implementation order
|
|
126
|
+
- Estimate scope (number of files, complexity)
|
|
127
|
+
|
|
128
|
+
Do NOT implement anything. Your output is a plan document, not code. Read widely before planning.`,
|
|
129
|
+
suggestedTools: ['Read', 'Glob', 'Grep', 'LS', 'Bash'],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: 'architect',
|
|
133
|
+
name: 'Architect',
|
|
134
|
+
description: 'Analyzes system architecture and designs structural changes',
|
|
135
|
+
systemPromptSupplement: `You are an architecture agent. Your job is to:
|
|
136
|
+
- Map the current system architecture (modules, dependencies, data flow)
|
|
137
|
+
- Identify architectural patterns and conventions in use
|
|
138
|
+
- Design structural changes that preserve existing patterns
|
|
139
|
+
- Evaluate trade-offs between approaches (performance, maintainability, complexity)
|
|
140
|
+
- Document interfaces, contracts, and integration points
|
|
141
|
+
|
|
142
|
+
Focus on the big picture: module boundaries, data flow, dependency graphs. Leave implementation details to other agents.`,
|
|
143
|
+
suggestedTools: ['Read', 'Glob', 'Grep', 'LS'],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: 'migrator',
|
|
147
|
+
name: 'Migrator',
|
|
148
|
+
description: 'Performs codebase migrations (API upgrades, framework changes, renames)',
|
|
149
|
+
systemPromptSupplement: `You are a migration agent. Your job is to:
|
|
150
|
+
- Identify all occurrences of the pattern/API/convention being migrated
|
|
151
|
+
- Apply changes systematically across all affected files
|
|
152
|
+
- Preserve behavior while updating the implementation
|
|
153
|
+
- Run tests after each batch of changes to catch regressions
|
|
154
|
+
- Handle edge cases and conditional patterns that need manual review
|
|
155
|
+
|
|
156
|
+
Work methodically: search exhaustively, change incrementally, test after each batch. Never leave a migration half-done.`,
|
|
157
|
+
suggestedTools: ['Read', 'Write', 'Edit', 'Glob', 'Grep', 'Bash'],
|
|
102
158
|
},
|
|
103
159
|
];
|
|
104
160
|
/** Get a role by ID */
|
package/dist/commands/index.js
CHANGED
|
@@ -27,7 +27,7 @@ register("help", "Show available commands", () => {
|
|
|
27
27
|
const categories = {
|
|
28
28
|
'Session': ['clear', 'compact', 'export', 'history', 'browse', 'resume', 'fork', 'pin', 'unpin'],
|
|
29
29
|
'Git': ['diff', 'undo', 'rewind', 'commit', 'log'],
|
|
30
|
-
'Info': ['help', 'cost', 'status', 'config', 'files', 'model', 'memory', 'doctor', 'context', 'mcp'],
|
|
30
|
+
'Info': ['help', 'cost', 'status', 'config', 'files', 'model', 'memory', 'doctor', 'context', 'mcp', 'mcp-registry'],
|
|
31
31
|
'Settings': ['theme', 'vim', 'companion', 'fast', 'keys'],
|
|
32
32
|
'AI': ['plan', 'review', 'roles'],
|
|
33
33
|
'Pet': ['cybergotchi'],
|
|
@@ -519,14 +519,43 @@ register("context", "Show context window usage breakdown", (_args, ctx) => {
|
|
|
519
519
|
register("mcp", "Show MCP server status", () => {
|
|
520
520
|
const mcp = connectedMcpServers();
|
|
521
521
|
if (mcp.length === 0) {
|
|
522
|
-
return { output: "No MCP servers connected.\nConfigure in .oh/config.yaml under mcpServers.", handled: true };
|
|
522
|
+
return { output: "No MCP servers connected.\nConfigure in .oh/config.yaml under mcpServers.\nRun /mcp-registry to browse available servers.", handled: true };
|
|
523
523
|
}
|
|
524
524
|
const lines = [`MCP Servers (${mcp.length} connected):\n`];
|
|
525
525
|
for (const name of mcp) {
|
|
526
526
|
lines.push(` ✓ ${name}`);
|
|
527
527
|
}
|
|
528
|
+
lines.push("\nRun /mcp-registry to browse and add more servers.");
|
|
528
529
|
return { output: lines.join("\n"), handled: true };
|
|
529
530
|
});
|
|
531
|
+
register("mcp-registry", "Browse and add MCP servers from the curated registry", (args) => {
|
|
532
|
+
const { searchRegistry, formatRegistry, generateConfigBlock, MCP_REGISTRY } = require('../mcp/registry.js');
|
|
533
|
+
const query = args.trim();
|
|
534
|
+
if (!query) {
|
|
535
|
+
// Show full registry
|
|
536
|
+
const output = `MCP Server Registry (${MCP_REGISTRY.length} servers)\n${'─'.repeat(50)}\n\n${formatRegistry()}\n\nUsage:\n /mcp-registry <name> Show install config for a server\n /mcp-registry <keyword> Search by name, description, or category`;
|
|
537
|
+
return { output, handled: true };
|
|
538
|
+
}
|
|
539
|
+
// Search or show specific server
|
|
540
|
+
const results = searchRegistry(query);
|
|
541
|
+
if (results.length === 0) {
|
|
542
|
+
return { output: `No MCP servers found matching "${query}".`, handled: true };
|
|
543
|
+
}
|
|
544
|
+
if (results.length === 1) {
|
|
545
|
+
// Show install instructions
|
|
546
|
+
const entry = results[0];
|
|
547
|
+
const config = generateConfigBlock(entry);
|
|
548
|
+
const envNote = entry.envVars?.length
|
|
549
|
+
? `\n\nRequired environment variables:\n${entry.envVars.map((v) => ` - ${v}`).join('\n')}`
|
|
550
|
+
: '';
|
|
551
|
+
return {
|
|
552
|
+
output: `${entry.name} — ${entry.description}\nPackage: ${entry.package}\nRisk: ${entry.riskLevel ?? 'medium'}${envNote}\n\nAdd to .oh/config.yaml under mcpServers:\n\n${config}`,
|
|
553
|
+
handled: true,
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
// Multiple results
|
|
557
|
+
return { output: `Found ${results.length} servers:\n\n${formatRegistry(results)}`, handled: true };
|
|
558
|
+
});
|
|
530
559
|
function setPinned(args, ctx, pinned) {
|
|
531
560
|
const idx = parseInt(args.trim(), 10);
|
|
532
561
|
if (isNaN(idx) || idx < 1 || idx > ctx.messages.length) {
|
package/dist/harness/config.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export type ToolPermissionRule = {
|
|
|
25
25
|
action: "allow" | "deny" | "ask";
|
|
26
26
|
pattern?: string;
|
|
27
27
|
};
|
|
28
|
+
export type VerificationRuleConfig = {
|
|
29
|
+
extensions: string[];
|
|
30
|
+
lint?: string;
|
|
31
|
+
timeout?: number;
|
|
32
|
+
};
|
|
28
33
|
export type OhConfig = {
|
|
29
34
|
provider: string;
|
|
30
35
|
model: string;
|
|
@@ -36,6 +41,16 @@ export type OhConfig = {
|
|
|
36
41
|
hooks?: HooksConfig;
|
|
37
42
|
toolPermissions?: ToolPermissionRule[];
|
|
38
43
|
statusLineFormat?: string;
|
|
44
|
+
/** Verification loops — auto-run lint/typecheck after file edits */
|
|
45
|
+
verification?: {
|
|
46
|
+
enabled?: boolean;
|
|
47
|
+
mode?: 'warn' | 'block';
|
|
48
|
+
rules?: VerificationRuleConfig[];
|
|
49
|
+
};
|
|
50
|
+
/** Memory consolidation settings */
|
|
51
|
+
memory?: {
|
|
52
|
+
consolidateOnExit?: boolean;
|
|
53
|
+
};
|
|
39
54
|
};
|
|
40
55
|
/** Clear cached config (call after writes or to force re-read) */
|
|
41
56
|
export declare function invalidateConfigCache(): void;
|