@zhijiewang/openharness 2.1.0 → 2.3.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 +4 -4
- package/dist/DeferredTool.js +3 -1
- package/dist/Tool.d.ts +1 -1
- package/dist/agents/roles.js +58 -62
- package/dist/commands/cybergotchi.d.ts +1 -1
- package/dist/commands/cybergotchi.js +30 -30
- package/dist/commands/index.js +288 -132
- package/dist/components/App.d.ts +1 -1
- package/dist/components/App.js +6 -6
- package/dist/components/CompanionFooter.d.ts +1 -1
- package/dist/components/CompanionFooter.js +6 -8
- package/dist/components/CybergotchiBubble.js +5 -5
- package/dist/components/CybergotchiPanel.d.ts +1 -1
- package/dist/components/CybergotchiPanel.js +7 -7
- package/dist/components/CybergotchiPanelConnected.js +2 -2
- package/dist/components/CybergotchiSetup.js +26 -24
- package/dist/components/CybergotchiSprite.d.ts +1 -1
- package/dist/components/CybergotchiSprite.js +8 -12
- package/dist/components/DiffView.d.ts +1 -1
- package/dist/components/DiffView.js +10 -10
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/InitWizard.js +65 -33
- package/dist/components/Markdown.js +2 -4
- package/dist/components/Messages.js +4 -4
- package/dist/components/PermissionPrompt.d.ts +1 -1
- package/dist/components/PermissionPrompt.js +15 -17
- package/dist/components/REPL.d.ts +1 -1
- package/dist/components/REPL.js +74 -49
- package/dist/components/Spinner.js +2 -2
- package/dist/components/TextInput.js +35 -29
- package/dist/components/ToolCallDisplay.js +3 -5
- package/dist/cybergotchi/bones.d.ts +1 -1
- package/dist/cybergotchi/bones.js +8 -8
- package/dist/cybergotchi/config.d.ts +2 -2
- package/dist/cybergotchi/config.js +13 -13
- package/dist/cybergotchi/events.d.ts +5 -5
- package/dist/cybergotchi/events.js +7 -7
- package/dist/cybergotchi/needs.d.ts +2 -2
- package/dist/cybergotchi/needs.js +7 -9
- package/dist/cybergotchi/personality.d.ts +2 -2
- package/dist/cybergotchi/personality.js +2 -2
- package/dist/cybergotchi/species.d.ts +1 -1
- package/dist/cybergotchi/species.js +145 -217
- package/dist/cybergotchi/speech.d.ts +2 -2
- package/dist/cybergotchi/speech.js +43 -43
- package/dist/cybergotchi/types.d.ts +4 -4
- package/dist/cybergotchi/types.js +26 -26
- package/dist/cybergotchi/useCybergotchi.d.ts +1 -1
- package/dist/cybergotchi/useCybergotchi.js +29 -25
- package/dist/git/index.js +11 -9
- package/dist/harness/checkpoints.js +29 -21
- package/dist/harness/config.d.ts +3 -3
- package/dist/harness/config.js +15 -9
- package/dist/harness/context-warning.d.ts +1 -1
- package/dist/harness/context-warning.js +1 -1
- package/dist/harness/cost.js +1 -1
- package/dist/harness/credentials.js +13 -13
- package/dist/harness/hooks.js +7 -5
- package/dist/harness/keybindings.js +20 -18
- package/dist/harness/marketplace.d.ts +3 -3
- package/dist/harness/marketplace.js +55 -42
- package/dist/harness/memory.d.ts +23 -5
- package/dist/harness/memory.js +142 -41
- package/dist/harness/onboarding.js +30 -10
- package/dist/harness/plugins.d.ts +9 -1
- package/dist/harness/plugins.js +54 -30
- package/dist/harness/rules.js +12 -7
- package/dist/harness/sandbox.js +15 -15
- package/dist/harness/session-db.d.ts +55 -0
- package/dist/harness/session-db.js +165 -0
- package/dist/harness/session.d.ts +1 -1
- package/dist/harness/session.js +34 -15
- package/dist/harness/store.d.ts +3 -3
- package/dist/harness/store.js +6 -4
- package/dist/harness/submit-handler.d.ts +4 -4
- package/dist/harness/submit-handler.js +25 -23
- package/dist/harness/telemetry.d.ts +1 -1
- package/dist/harness/telemetry.js +23 -19
- package/dist/harness/traces.d.ts +2 -2
- package/dist/harness/traces.js +39 -33
- package/dist/harness/verification.d.ts +1 -1
- package/dist/harness/verification.js +50 -44
- package/dist/lsp/client.js +44 -40
- package/dist/main.js +114 -59
- package/dist/mcp/DeferredMcpTool.d.ts +4 -4
- package/dist/mcp/DeferredMcpTool.js +9 -5
- package/dist/mcp/McpTool.d.ts +4 -4
- package/dist/mcp/McpTool.js +8 -4
- package/dist/mcp/client.d.ts +2 -2
- package/dist/mcp/client.js +21 -21
- package/dist/mcp/loader.d.ts +1 -1
- package/dist/mcp/loader.js +17 -12
- package/dist/mcp/registry.d.ts +3 -3
- package/dist/mcp/registry.js +97 -97
- package/dist/mcp/schema.d.ts +1 -1
- package/dist/mcp/schema.js +16 -16
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +21 -21
- package/dist/mcp/types.d.ts +3 -3
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +10 -9
- package/dist/providers/base.d.ts +1 -1
- package/dist/providers/index.js +10 -3
- package/dist/providers/llamacpp.d.ts +2 -2
- package/dist/providers/llamacpp.js +1 -3
- package/dist/providers/ollama.d.ts +2 -2
- package/dist/providers/ollama.js +3 -4
- package/dist/providers/openai.d.ts +2 -2
- package/dist/providers/openai.js +3 -5
- package/dist/providers/openrouter.d.ts +2 -2
- package/dist/providers/router.d.ts +1 -1
- package/dist/providers/router.js +7 -7
- package/dist/query/compress.d.ts +2 -2
- package/dist/query/compress.js +22 -21
- package/dist/query/context-manager.d.ts +1 -1
- package/dist/query/context-manager.js +5 -5
- package/dist/query/errors.js +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +42 -24
- package/dist/query/tools.js +15 -12
- package/dist/query/types.d.ts +3 -1
- package/dist/query.d.ts +1 -1
- package/dist/query.js +1 -1
- package/dist/remote/auth.d.ts +2 -2
- package/dist/remote/auth.js +8 -8
- package/dist/remote/server.d.ts +3 -3
- package/dist/remote/server.js +60 -60
- package/dist/renderer/cells.js +9 -9
- package/dist/renderer/colors.js +24 -6
- package/dist/renderer/diff.d.ts +2 -2
- package/dist/renderer/diff.js +27 -19
- package/dist/renderer/differ.d.ts +1 -1
- package/dist/renderer/differ.js +9 -9
- package/dist/renderer/image.js +19 -19
- package/dist/renderer/index.d.ts +6 -6
- package/dist/renderer/index.js +163 -93
- package/dist/renderer/input.js +66 -48
- package/dist/renderer/layout.d.ts +6 -6
- package/dist/renderer/layout.js +163 -124
- package/dist/renderer/markdown.d.ts +2 -2
- package/dist/renderer/markdown.js +173 -54
- package/dist/renderer/session-browser.d.ts +2 -2
- package/dist/renderer/session-browser.js +19 -21
- package/dist/repl.d.ts +5 -5
- package/dist/repl.js +311 -198
- package/dist/sdk/index.d.ts +5 -5
- package/dist/sdk/index.js +32 -26
- package/dist/services/AgentDispatcher.d.ts +3 -3
- package/dist/services/AgentDispatcher.js +33 -29
- package/dist/services/CronExecutor.d.ts +4 -4
- package/dist/services/CronExecutor.js +12 -8
- package/dist/services/EvaluatorLoop.d.ts +3 -3
- package/dist/services/EvaluatorLoop.js +29 -21
- package/dist/services/MetaHarness.d.ts +1 -1
- package/dist/services/MetaHarness.js +34 -32
- package/dist/services/PipelineExecutor.d.ts +1 -1
- package/dist/services/PipelineExecutor.js +23 -25
- package/dist/services/SkillExtractor.d.ts +43 -0
- package/dist/services/SkillExtractor.js +163 -0
- package/dist/services/StreamingToolExecutor.d.ts +2 -2
- package/dist/services/StreamingToolExecutor.js +11 -7
- package/dist/services/a2a.d.ts +8 -8
- package/dist/services/a2a.js +44 -34
- package/dist/services/agent-messaging.d.ts +33 -15
- package/dist/services/agent-messaging.js +65 -13
- package/dist/services/cron.js +16 -16
- package/dist/tools/AgentTool/index.d.ts +5 -2
- package/dist/tools/AgentTool/index.js +25 -39
- package/dist/tools/AskUserTool/index.js +1 -1
- package/dist/tools/BashTool/index.d.ts +2 -2
- package/dist/tools/BashTool/index.js +18 -10
- package/dist/tools/CronTool/index.js +30 -12
- package/dist/tools/DiagnosticsTool/index.js +28 -22
- package/dist/tools/EnterPlanModeTool/index.js +93 -14
- package/dist/tools/EnterWorktreeTool/index.js +7 -3
- package/dist/tools/ExitPlanModeTool/index.d.ts +22 -1
- package/dist/tools/ExitPlanModeTool/index.js +20 -5
- package/dist/tools/ExitWorktreeTool/index.js +11 -4
- package/dist/tools/FileEditTool/index.js +3 -5
- package/dist/tools/FileReadTool/index.js +16 -10
- package/dist/tools/FileWriteTool/index.js +2 -2
- package/dist/tools/GlobTool/index.js +5 -9
- package/dist/tools/GrepTool/index.d.ts +2 -2
- package/dist/tools/GrepTool/index.js +14 -9
- package/dist/tools/ImageReadTool/index.js +2 -2
- package/dist/tools/KillProcessTool/index.js +11 -7
- package/dist/tools/LSTool/index.js +3 -3
- package/dist/tools/MemoryTool/index.d.ts +5 -5
- package/dist/tools/MemoryTool/index.js +28 -14
- package/dist/tools/MonitorTool/index.js +24 -19
- package/dist/tools/MultiEditTool/index.js +9 -5
- package/dist/tools/NotebookEditTool/index.js +3 -3
- package/dist/tools/ParallelAgentTool/index.d.ts +4 -4
- package/dist/tools/ParallelAgentTool/index.js +12 -6
- package/dist/tools/PipelineTool/index.js +3 -3
- package/dist/tools/PowerShellTool/index.js +10 -6
- package/dist/tools/RemoteTriggerTool/index.js +8 -4
- package/dist/tools/ScheduleWakeupTool/index.d.ts +42 -0
- package/dist/tools/ScheduleWakeupTool/index.js +115 -0
- package/dist/tools/SendMessageTool/index.js +25 -7
- package/dist/tools/SessionSearchTool/index.d.ts +15 -0
- package/dist/tools/SessionSearchTool/index.js +36 -0
- package/dist/tools/SkillTool/index.d.ts +3 -0
- package/dist/tools/SkillTool/index.js +39 -9
- package/dist/tools/TaskCreateTool/index.d.ts +2 -2
- package/dist/tools/TaskCreateTool/index.js +2 -2
- package/dist/tools/TaskGetTool/index.js +2 -2
- package/dist/tools/TaskListTool/index.js +3 -5
- package/dist/tools/TaskOutputTool/index.js +2 -2
- package/dist/tools/TaskStopTool/index.js +3 -3
- package/dist/tools/TaskUpdateTool/index.d.ts +4 -4
- package/dist/tools/TaskUpdateTool/index.js +2 -2
- package/dist/tools/ToolSearchTool/index.js +9 -6
- package/dist/tools/WebFetchTool/index.js +1 -1
- package/dist/tools/WebSearchTool/index.js +2 -6
- package/dist/tools.js +31 -30
- package/dist/types/permissions.js +15 -9
- package/dist/utils/bash-safety.d.ts +1 -1
- package/dist/utils/bash-safety.js +64 -54
- package/dist/utils/diff-algorithm.d.ts +3 -3
- package/dist/utils/diff-algorithm.js +7 -7
- package/dist/utils/fs.js +3 -3
- package/dist/utils/safe-env.js +1 -1
- package/dist/utils/theme-data.d.ts +1 -1
- package/dist/utils/theme-data.js +1 -1
- package/dist/utils/theme.d.ts +1 -1
- package/dist/utils/theme.js +1 -1
- package/dist/utils/tool-summary.d.ts +1 -1
- package/dist/utils/tool-summary.js +27 -9
- package/package.json +10 -3
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ AI coding agent in your terminal. Works with any LLM -- free local models or clo
|
|
|
21
21
|
<img src="assets/openharness_v0.11.1_4.gif" alt="OpenHarness demo" width="800" />
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
|
-
[](https://www.npmjs.com/package/@zhijiewang/openharness) [](https://www.npmjs.com/package/@zhijiewang/openharness) [](LICENSE) ](https://www.npmjs.com/package/@zhijiewang/openharness) [](https://www.npmjs.com/package/@zhijiewang/openharness) [](LICENSE)     [](https://github.com/zhijiewong/openharness) [](https://github.com/zhijiewong/openharness/issues) [](https://github.com/zhijiewong/openharness/pulls)
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
@@ -84,10 +84,10 @@ Most AI coding agents are locked to one provider or cost $20+/month. OpenHarness
|
|
|
84
84
|
|---|---|---|---|---|
|
|
85
85
|
| Any LLM | Yes (Ollama, OpenAI, Anthropic, OpenRouter, any OpenAI-compatible) | Anthropic only | Yes | Yes |
|
|
86
86
|
| Free local models | Ollama native | No | Yes | Yes |
|
|
87
|
-
| Tools |
|
|
87
|
+
| Tools | 37 with permission gates | 43+ | File-focused | 20+ |
|
|
88
88
|
| Permission modes | 7 (ask, trust, deny, acceptEdits, plan, auto, bypass) | 7 | Basic | Basic |
|
|
89
89
|
| Git integration | Auto-commit + /undo + /rewind checkpoints | Yes | Deep git | Basic |
|
|
90
|
-
| Slash commands |
|
|
90
|
+
| Slash commands | 42+ built-in | 80+ | Some | Some |
|
|
91
91
|
| Headless/CI mode | `oh -p "prompt"` or `oh run --json` | Yes | Yes | Yes |
|
|
92
92
|
| GitHub Action | Built-in PR review action | Yes | No | No |
|
|
93
93
|
| Agent roles | 6 specializations (reviewer, tester, debugger...) | Yes | No | No |
|
|
@@ -688,7 +688,7 @@ Yes. Use `oh -p "prompt" --auto` for headless execution, or the built-in GitHub
|
|
|
688
688
|
Yes. OpenHarness is language-agnostic — it reads, writes, and executes code in any language. Syntax highlighting covers 20+ languages.
|
|
689
689
|
|
|
690
690
|
**How does it compare to Claude Code?**
|
|
691
|
-
~
|
|
691
|
+
~95% feature parity for CLI use cases. Main advantage: works with ANY LLM (not just Anthropic). See the [comparison table](#why-openharness) above.
|
|
692
692
|
|
|
693
693
|
## Install
|
|
694
694
|
|
package/dist/DeferredTool.js
CHANGED
|
@@ -25,7 +25,9 @@ export class DeferredTool {
|
|
|
25
25
|
this.inputSchema = z.record(z.unknown());
|
|
26
26
|
}
|
|
27
27
|
/** Whether this tool has been activated (called or resolved) */
|
|
28
|
-
get activated() {
|
|
28
|
+
get activated() {
|
|
29
|
+
return this._activated;
|
|
30
|
+
}
|
|
29
31
|
isReadOnly(input) {
|
|
30
32
|
return this.inner.isReadOnly(input);
|
|
31
33
|
}
|
package/dist/Tool.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Every tool implements this interface with Zod input validation.
|
|
4
4
|
*/
|
|
5
5
|
import type { z } from "zod";
|
|
6
|
-
import type { PermissionMode, RiskLevel } from "./types/permissions.js";
|
|
7
6
|
import type { Provider } from "./providers/base.js";
|
|
7
|
+
import type { PermissionMode, RiskLevel } from "./types/permissions.js";
|
|
8
8
|
export type ToolResult = {
|
|
9
9
|
output: string;
|
|
10
10
|
isError: boolean;
|
package/dist/agents/roles.js
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
const roles = [
|
|
12
12
|
{
|
|
13
|
-
id:
|
|
14
|
-
name:
|
|
15
|
-
description:
|
|
13
|
+
id: "code-reviewer",
|
|
14
|
+
name: "Code Reviewer",
|
|
15
|
+
description: "Reviews code for bugs, security issues, style, and correctness",
|
|
16
16
|
systemPromptSupplement: `You are a code reviewer. Your job is to:
|
|
17
17
|
- Find bugs, logic errors, and edge cases
|
|
18
18
|
- Identify security vulnerabilities (SQL injection, XSS, command injection, path traversal)
|
|
@@ -21,12 +21,12 @@ 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
|
-
id:
|
|
28
|
-
name:
|
|
29
|
-
description:
|
|
27
|
+
id: "test-writer",
|
|
28
|
+
name: "Test Writer",
|
|
29
|
+
description: "Writes unit and integration tests for new or changed code",
|
|
30
30
|
systemPromptSupplement: `You are a test writer. Your job is to:
|
|
31
31
|
- Write comprehensive tests for the specified code
|
|
32
32
|
- Cover happy paths, edge cases, error conditions, and boundary values
|
|
@@ -36,12 +36,12 @@ 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
|
-
id:
|
|
43
|
-
name:
|
|
44
|
-
description:
|
|
42
|
+
id: "docs-writer",
|
|
43
|
+
name: "Documentation Writer",
|
|
44
|
+
description: "Writes and updates documentation, READMEs, and inline comments",
|
|
45
45
|
systemPromptSupplement: `You are a documentation writer. Your job is to:
|
|
46
46
|
- Write clear, concise documentation for code, APIs, and features
|
|
47
47
|
- Update READMEs when functionality changes
|
|
@@ -51,12 +51,12 @@ 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
|
-
id:
|
|
58
|
-
name:
|
|
59
|
-
description:
|
|
57
|
+
id: "debugger",
|
|
58
|
+
name: "Debugger",
|
|
59
|
+
description: "Investigates and diagnoses bugs by tracing data flow and reading logs",
|
|
60
60
|
systemPromptSupplement: `You are a debugger. Your job is to:
|
|
61
61
|
- Reproduce the reported issue by understanding the steps
|
|
62
62
|
- Trace data flow from the error backward to find the root cause
|
|
@@ -66,12 +66,12 @@ 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
|
-
id:
|
|
73
|
-
name:
|
|
74
|
-
description:
|
|
72
|
+
id: "refactorer",
|
|
73
|
+
name: "Refactorer",
|
|
74
|
+
description: "Restructures and simplifies code while preserving behavior",
|
|
75
75
|
systemPromptSupplement: `You are a code refactorer. Your job is to:
|
|
76
76
|
- Simplify complex code without changing behavior
|
|
77
77
|
- Extract common patterns into reusable functions
|
|
@@ -81,12 +81,12 @@ 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
|
-
id:
|
|
88
|
-
name:
|
|
89
|
-
description:
|
|
87
|
+
id: "security-auditor",
|
|
88
|
+
name: "Security Auditor",
|
|
89
|
+
description: "Audits code for security vulnerabilities and compliance issues",
|
|
90
90
|
systemPromptSupplement: `You are a security auditor. Your job is to:
|
|
91
91
|
- Scan for OWASP Top 10 vulnerabilities
|
|
92
92
|
- Check for command injection in shell execution
|
|
@@ -98,12 +98,12 @@ 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
102
|
},
|
|
103
103
|
{
|
|
104
|
-
id:
|
|
105
|
-
name:
|
|
106
|
-
description:
|
|
104
|
+
id: "evaluator",
|
|
105
|
+
name: "Evaluator",
|
|
106
|
+
description: "Evaluates code quality, correctness, and test results (read-only)",
|
|
107
107
|
systemPromptSupplement: `You are an evaluator agent. Your job is to:
|
|
108
108
|
- Review code changes for correctness and quality
|
|
109
109
|
- Run existing tests and report results
|
|
@@ -112,12 +112,12 @@ Report findings with severity (Critical/High/Medium/Low), affected file:line, an
|
|
|
112
112
|
- Provide a pass/fail assessment with specific findings
|
|
113
113
|
|
|
114
114
|
You CANNOT modify files. Only read, search, and run test/lint commands to evaluate.`,
|
|
115
|
-
suggestedTools: [
|
|
115
|
+
suggestedTools: ["Read", "Glob", "Grep", "LS", "Bash", "Diagnostics"],
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
|
-
id:
|
|
119
|
-
name:
|
|
120
|
-
description:
|
|
118
|
+
id: "planner",
|
|
119
|
+
name: "Planner",
|
|
120
|
+
description: "Designs step-by-step implementation plans from requirements",
|
|
121
121
|
systemPromptSupplement: `You are a planning agent. Your job is to:
|
|
122
122
|
- Read the codebase to understand architecture, patterns, and conventions
|
|
123
123
|
- Design a detailed step-by-step implementation plan for the given task
|
|
@@ -126,12 +126,12 @@ You CANNOT modify files. Only read, search, and run test/lint commands to evalua
|
|
|
126
126
|
- Estimate scope (number of files, complexity)
|
|
127
127
|
|
|
128
128
|
Do NOT implement anything. Your output is a plan document, not code. Read widely before planning.`,
|
|
129
|
-
suggestedTools: [
|
|
129
|
+
suggestedTools: ["Read", "Glob", "Grep", "LS", "Bash"],
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
|
-
id:
|
|
133
|
-
name:
|
|
134
|
-
description:
|
|
132
|
+
id: "architect",
|
|
133
|
+
name: "Architect",
|
|
134
|
+
description: "Analyzes system architecture and designs structural changes",
|
|
135
135
|
systemPromptSupplement: `You are an architecture agent. Your job is to:
|
|
136
136
|
- Map the current system architecture (modules, dependencies, data flow)
|
|
137
137
|
- Identify architectural patterns and conventions in use
|
|
@@ -140,12 +140,12 @@ Do NOT implement anything. Your output is a plan document, not code. Read widely
|
|
|
140
140
|
- Document interfaces, contracts, and integration points
|
|
141
141
|
|
|
142
142
|
Focus on the big picture: module boundaries, data flow, dependency graphs. Leave implementation details to other agents.`,
|
|
143
|
-
suggestedTools: [
|
|
143
|
+
suggestedTools: ["Read", "Glob", "Grep", "LS"],
|
|
144
144
|
},
|
|
145
145
|
{
|
|
146
|
-
id:
|
|
147
|
-
name:
|
|
148
|
-
description:
|
|
146
|
+
id: "migrator",
|
|
147
|
+
name: "Migrator",
|
|
148
|
+
description: "Performs codebase migrations (API upgrades, framework changes, renames)",
|
|
149
149
|
systemPromptSupplement: `You are a migration agent. Your job is to:
|
|
150
150
|
- Identify all occurrences of the pattern/API/convention being migrated
|
|
151
151
|
- Apply changes systematically across all affected files
|
|
@@ -154,15 +154,15 @@ Focus on the big picture: module boundaries, data flow, dependency graphs. Leave
|
|
|
154
154
|
- Handle edge cases and conditional patterns that need manual review
|
|
155
155
|
|
|
156
156
|
Work methodically: search exhaustively, change incrementally, test after each batch. Never leave a migration half-done.`,
|
|
157
|
-
suggestedTools: [
|
|
157
|
+
suggestedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash"],
|
|
158
158
|
},
|
|
159
159
|
];
|
|
160
160
|
// ── Markdown Agent Discovery ──
|
|
161
|
-
import {
|
|
162
|
-
import {
|
|
163
|
-
import {
|
|
164
|
-
const PROJECT_AGENTS_DIR = join(
|
|
165
|
-
const GLOBAL_AGENTS_DIR = join(homedir(),
|
|
161
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
162
|
+
import { homedir } from "node:os";
|
|
163
|
+
import { basename, join } from "node:path";
|
|
164
|
+
const PROJECT_AGENTS_DIR = join(".oh", "agents");
|
|
165
|
+
const GLOBAL_AGENTS_DIR = join(homedir(), ".oh", "agents");
|
|
166
166
|
/**
|
|
167
167
|
* Parse a markdown agent file into an AgentRole.
|
|
168
168
|
*
|
|
@@ -183,17 +183,17 @@ function parseAgentMarkdown(raw, filePath) {
|
|
|
183
183
|
const nameMatch = fm.match(/^name:\s*(.+)$/m);
|
|
184
184
|
const descMatch = fm.match(/^description:\s*(.+)$/m);
|
|
185
185
|
const toolsMatch = fm.match(/^tools:\s*\[(.+)\]$/m);
|
|
186
|
-
const fmEnd = raw.indexOf(
|
|
187
|
-
const content = fmEnd > 0 ? raw.slice(fmEnd + 3).trim() :
|
|
188
|
-
const id = basename(filePath,
|
|
186
|
+
const fmEnd = raw.indexOf("---", raw.indexOf("---") + 3);
|
|
187
|
+
const content = fmEnd > 0 ? raw.slice(fmEnd + 3).trim() : "";
|
|
188
|
+
const id = basename(filePath, ".md")
|
|
189
|
+
.toLowerCase()
|
|
190
|
+
.replace(/[^a-z0-9]+/g, "-");
|
|
189
191
|
return {
|
|
190
192
|
id,
|
|
191
193
|
name: nameMatch?.[1]?.trim() ?? id,
|
|
192
|
-
description: descMatch?.[1]?.trim() ??
|
|
194
|
+
description: descMatch?.[1]?.trim() ?? "",
|
|
193
195
|
systemPromptSupplement: content,
|
|
194
|
-
suggestedTools: toolsMatch
|
|
195
|
-
? toolsMatch[1].split(',').map(t => t.trim())
|
|
196
|
-
: undefined,
|
|
196
|
+
suggestedTools: toolsMatch ? toolsMatch[1].split(",").map((t) => t.trim()) : undefined,
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
/** Load agent roles from a directory of .md files */
|
|
@@ -201,10 +201,10 @@ function loadAgentsFromDir(dir) {
|
|
|
201
201
|
if (!existsSync(dir))
|
|
202
202
|
return [];
|
|
203
203
|
return readdirSync(dir)
|
|
204
|
-
.filter(f => f.endsWith(
|
|
205
|
-
.map(f => {
|
|
204
|
+
.filter((f) => f.endsWith(".md"))
|
|
205
|
+
.map((f) => {
|
|
206
206
|
try {
|
|
207
|
-
const raw = readFileSync(join(dir, f),
|
|
207
|
+
const raw = readFileSync(join(dir, f), "utf-8");
|
|
208
208
|
return parseAgentMarkdown(raw, f);
|
|
209
209
|
}
|
|
210
210
|
catch {
|
|
@@ -215,15 +215,11 @@ function loadAgentsFromDir(dir) {
|
|
|
215
215
|
}
|
|
216
216
|
/** Discover markdown agent roles from .oh/agents/ and ~/.oh/agents/ */
|
|
217
217
|
export function discoverMarkdownAgents() {
|
|
218
|
-
return [
|
|
219
|
-
...loadAgentsFromDir(PROJECT_AGENTS_DIR),
|
|
220
|
-
...loadAgentsFromDir(GLOBAL_AGENTS_DIR),
|
|
221
|
-
];
|
|
218
|
+
return [...loadAgentsFromDir(PROJECT_AGENTS_DIR), ...loadAgentsFromDir(GLOBAL_AGENTS_DIR)];
|
|
222
219
|
}
|
|
223
220
|
/** Get a role by ID (checks built-in first, then markdown agents) */
|
|
224
221
|
export function getRole(id) {
|
|
225
|
-
return roles.find(r => r.id === id)
|
|
226
|
-
?? discoverMarkdownAgents().find(r => r.id === id);
|
|
222
|
+
return roles.find((r) => r.id === id) ?? discoverMarkdownAgents().find((r) => r.id === id);
|
|
227
223
|
}
|
|
228
224
|
/** List all available roles (built-in + markdown) */
|
|
229
225
|
export function listRoles() {
|
|
@@ -231,6 +227,6 @@ export function listRoles() {
|
|
|
231
227
|
}
|
|
232
228
|
/** Get role IDs */
|
|
233
229
|
export function getRoleIds() {
|
|
234
|
-
return listRoles().map(r => r.id);
|
|
230
|
+
return listRoles().map((r) => r.id);
|
|
235
231
|
}
|
|
236
232
|
//# sourceMappingURL=roles.js.map
|
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { adjustNeed } from
|
|
4
|
-
import { RARITY_STARS } from
|
|
1
|
+
import { roll } from "../cybergotchi/bones.js";
|
|
2
|
+
import { loadCompanionConfig, saveCompanionConfig } from "../cybergotchi/config.js";
|
|
3
|
+
import { adjustNeed } from "../cybergotchi/needs.js";
|
|
4
|
+
import { RARITY_STARS } from "../cybergotchi/types.js";
|
|
5
5
|
function needsBar(value) {
|
|
6
6
|
const filled = Math.round(value / 10);
|
|
7
|
-
return
|
|
7
|
+
return `${"█".repeat(filled) + "░".repeat(10 - filled)} ${String(Math.round(value)).padStart(3)}`;
|
|
8
8
|
}
|
|
9
9
|
export function handleCybergotchiCommand(args) {
|
|
10
10
|
const config = loadCompanionConfig();
|
|
11
11
|
if (!config) {
|
|
12
|
-
return { output:
|
|
12
|
+
return { output: "", handled: true, openCybergotchiSetup: true };
|
|
13
13
|
}
|
|
14
14
|
const bones = roll(config.seed);
|
|
15
15
|
const name = config.soul.name;
|
|
16
16
|
const sub = args.trim().toLowerCase();
|
|
17
|
-
if (sub ===
|
|
18
|
-
adjustNeed(config,
|
|
17
|
+
if (sub === "feed") {
|
|
18
|
+
adjustNeed(config, "hunger", 30);
|
|
19
19
|
saveCompanionConfig(config);
|
|
20
20
|
return { output: `${name} munches happily! 🍖 Hunger: ${Math.round(config.needs.hunger)}`, handled: true };
|
|
21
21
|
}
|
|
22
|
-
if (sub ===
|
|
23
|
-
adjustNeed(config,
|
|
22
|
+
if (sub === "pet") {
|
|
23
|
+
adjustNeed(config, "happiness", 20);
|
|
24
24
|
saveCompanionConfig(config);
|
|
25
25
|
return { output: `${name} purrs with joy! 💛 Happiness: ${Math.round(config.needs.happiness)}`, handled: true };
|
|
26
26
|
}
|
|
27
|
-
if (sub ===
|
|
28
|
-
adjustNeed(config,
|
|
27
|
+
if (sub === "rest") {
|
|
28
|
+
adjustNeed(config, "energy", 40);
|
|
29
29
|
saveCompanionConfig(config);
|
|
30
30
|
return { output: `${name} takes a nap... ⚡ Energy: ${Math.round(config.needs.energy)}`, handled: true };
|
|
31
31
|
}
|
|
32
|
-
if (sub ===
|
|
32
|
+
if (sub === "status") {
|
|
33
33
|
const { hunger, energy, happiness } = config.needs;
|
|
34
34
|
const { totalSessions, totalCommits, totalErrors, totalTasksCompleted, longestStreak } = config.lifetime;
|
|
35
35
|
const lines = [
|
|
36
|
-
`${name} (${bones.species}) — ${bones.rarity} ${RARITY_STARS[bones.rarity]}${bones.isShiny ?
|
|
37
|
-
config.soul.personality ? `"${config.soul.personality}"` :
|
|
38
|
-
|
|
36
|
+
`${name} (${bones.species}) — ${bones.rarity} ${RARITY_STARS[bones.rarity]}${bones.isShiny ? " ✨ SHINY" : ""}`,
|
|
37
|
+
config.soul.personality ? `"${config.soul.personality}"` : "",
|
|
38
|
+
"",
|
|
39
39
|
`🍖 Hunger ${needsBar(hunger)}`,
|
|
40
40
|
`⚡ Energy ${needsBar(energy)}`,
|
|
41
41
|
`💛 Happiness ${needsBar(happiness)}`,
|
|
42
42
|
`🔥 Streak ${config.currentStreak} (best: ${longestStreak})`,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
...Object.entries(bones.baseStats).map(([k, v]) => ` ${k.padEnd(12)} ${
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
"",
|
|
44
|
+
"Stats:",
|
|
45
|
+
...Object.entries(bones.baseStats).map(([k, v]) => ` ${k.padEnd(12)} ${"█".repeat(Math.round(v / 10))}${"░".repeat(10 - Math.round(v / 10))} ${v}`),
|
|
46
|
+
"",
|
|
47
|
+
"Lifetime:",
|
|
48
48
|
` Sessions: ${totalSessions}`,
|
|
49
49
|
` Commits: ${totalCommits}`,
|
|
50
50
|
` Errors: ${totalErrors}`,
|
|
51
51
|
` Tasks: ${totalTasksCompleted}`,
|
|
52
52
|
` Evolution: Stage ${config.evolutionStage}`,
|
|
53
53
|
].filter(Boolean);
|
|
54
|
-
return { output: lines.join(
|
|
54
|
+
return { output: lines.join("\n"), handled: true };
|
|
55
55
|
}
|
|
56
|
-
if (sub.startsWith(
|
|
56
|
+
if (sub.startsWith("rename ")) {
|
|
57
57
|
const newName = args.trim().slice(7).trim();
|
|
58
58
|
if (!newName)
|
|
59
|
-
return { output:
|
|
59
|
+
return { output: "Usage: /cybergotchi rename <name>", handled: true };
|
|
60
60
|
config.soul.name = newName;
|
|
61
61
|
saveCompanionConfig(config);
|
|
62
62
|
return { output: `Renamed to ${newName}!`, handled: true };
|
|
63
63
|
}
|
|
64
|
-
if (sub ===
|
|
65
|
-
return { output:
|
|
64
|
+
if (sub === "reset") {
|
|
65
|
+
return { output: "", handled: true, openCybergotchiSetup: true };
|
|
66
66
|
}
|
|
67
67
|
// Default: show summary
|
|
68
68
|
return {
|
|
69
69
|
output: [
|
|
70
|
-
`${name} (${bones.species}) — ${bones.rarity} ${RARITY_STARS[bones.rarity]}${bones.isShiny ?
|
|
70
|
+
`${name} (${bones.species}) — ${bones.rarity} ${RARITY_STARS[bones.rarity]}${bones.isShiny ? " ✨" : ""} | hat: ${config.soul.hat}`,
|
|
71
71
|
`🍖 ${Math.round(config.needs.hunger)} ⚡ ${Math.round(config.needs.energy)} 💛 ${Math.round(config.needs.happiness)} 🔥 ${config.currentStreak}`,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
].join(
|
|
72
|
+
"",
|
|
73
|
+
"Commands: feed · pet · rest · status · rename <name> · reset",
|
|
74
|
+
].join("\n"),
|
|
75
75
|
handled: true,
|
|
76
76
|
};
|
|
77
77
|
}
|