@zhijiewang/openharness 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/registry.json +262 -0
- package/data/skills/code-review.md +19 -0
- package/data/skills/commit.md +17 -0
- package/data/skills/debug.md +24 -0
- package/data/skills/diagnose.md +24 -0
- package/data/skills/plan.md +25 -0
- package/data/skills/simplify.md +24 -0
- package/data/skills/tdd.md +22 -0
- package/dist/agents/roles.d.ts +12 -2
- package/dist/agents/roles.js +65 -6
- package/dist/commands/ai.js +27 -7
- package/dist/commands/skills.d.ts +1 -1
- package/dist/commands/skills.js +51 -6
- package/dist/components/App.js +7 -1
- package/dist/harness/config.d.ts +24 -0
- package/dist/harness/hooks.d.ts +14 -0
- package/dist/harness/hooks.js +205 -11
- package/dist/harness/marketplace.d.ts +77 -2
- package/dist/harness/marketplace.js +260 -38
- package/dist/harness/memory.d.ts +34 -0
- package/dist/harness/memory.js +96 -0
- package/dist/harness/plugins.d.ts +13 -3
- package/dist/harness/plugins.js +98 -17
- package/dist/harness/session-db.d.ts +8 -1
- package/dist/harness/session-db.js +24 -3
- package/dist/harness/skill-registry.d.ts +26 -2
- package/dist/harness/skill-registry.js +42 -4
- package/dist/tools/AgentTool/index.d.ts +2 -2
- package/dist/tools/DiagnosticsTool/index.d.ts +1 -1
- package/dist/tools/GrepTool/index.d.ts +6 -6
- package/dist/tools/MemoryTool/index.d.ts +4 -4
- package/dist/tools/MonitorTool/index.js +5 -1
- package/dist/types/permissions.js +104 -42
- package/dist/utils/bash-safety.d.ts +19 -0
- package/dist/utils/bash-safety.js +179 -1
- package/dist/utils/safe-env.d.ts +5 -1
- package/dist/utils/safe-env.js +19 -1
- package/package.json +3 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skills": [
|
|
3
|
+
{
|
|
4
|
+
"name": "code-review",
|
|
5
|
+
"description": "Systematic code review for bugs, security, and style",
|
|
6
|
+
"author": "zhijiewong",
|
|
7
|
+
"version": "1.0.0",
|
|
8
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/code-review.md",
|
|
9
|
+
"tags": ["review", "quality", "security"],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
12
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "debug",
|
|
16
|
+
"description": "Systematic debugging approach",
|
|
17
|
+
"author": "zhijiewong",
|
|
18
|
+
"version": "1.0.0",
|
|
19
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/debug.md",
|
|
20
|
+
"tags": ["debug", "fix", "troubleshoot"],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
23
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "tdd",
|
|
27
|
+
"description": "Test-driven development workflow",
|
|
28
|
+
"author": "zhijiewong",
|
|
29
|
+
"version": "1.0.0",
|
|
30
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/tdd.md",
|
|
31
|
+
"tags": ["test", "tdd", "testing"],
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
34
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "commit",
|
|
38
|
+
"description": "Create well-formed git commits",
|
|
39
|
+
"author": "zhijiewong",
|
|
40
|
+
"version": "1.0.0",
|
|
41
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/commit.md",
|
|
42
|
+
"tags": ["git", "commit", "version-control"],
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
45
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "diagnose",
|
|
49
|
+
"description": "Diagnose why an agent run failed, regressed, or produced unexpected output",
|
|
50
|
+
"author": "zhijiewong",
|
|
51
|
+
"version": "1.0.0",
|
|
52
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/diagnose.md",
|
|
53
|
+
"tags": ["agent", "debug", "diagnose", "ops"],
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
56
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "plan",
|
|
60
|
+
"description": "Design an implementation plan before coding",
|
|
61
|
+
"author": "zhijiewong",
|
|
62
|
+
"version": "1.0.0",
|
|
63
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/plan.md",
|
|
64
|
+
"tags": ["plan", "design", "architecture"],
|
|
65
|
+
"license": "MIT",
|
|
66
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
67
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "simplify",
|
|
71
|
+
"description": "Refactor code to be simpler and more maintainable without changing behavior",
|
|
72
|
+
"author": "zhijiewong",
|
|
73
|
+
"version": "1.0.0",
|
|
74
|
+
"source": "https://raw.githubusercontent.com/zhijiewong/openharness/main/data/skills/simplify.md",
|
|
75
|
+
"tags": ["refactor", "simplify", "quality"],
|
|
76
|
+
"license": "MIT",
|
|
77
|
+
"attribution": "© 2025 OpenHarness contributors",
|
|
78
|
+
"upstream": "https://github.com/zhijiewong/openharness"
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
{
|
|
82
|
+
"name": "superpowers-brainstorming",
|
|
83
|
+
"description": "Explores user intent, requirements and design before implementation. Use before any creative work.",
|
|
84
|
+
"author": "Jesse Vincent",
|
|
85
|
+
"version": "5.0.7",
|
|
86
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/brainstorming/SKILL.md",
|
|
87
|
+
"tags": ["plan", "brainstorm", "design", "superpowers"],
|
|
88
|
+
"license": "MIT",
|
|
89
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
90
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "superpowers-systematic-debugging",
|
|
94
|
+
"description": "Structured debugging approach before proposing fixes",
|
|
95
|
+
"author": "Jesse Vincent",
|
|
96
|
+
"version": "5.0.7",
|
|
97
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/systematic-debugging/SKILL.md",
|
|
98
|
+
"tags": ["debug", "fix", "superpowers"],
|
|
99
|
+
"license": "MIT",
|
|
100
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
101
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "superpowers-test-driven-development",
|
|
105
|
+
"description": "Strict TDD workflow — test first, minimal implementation, refactor",
|
|
106
|
+
"author": "Jesse Vincent",
|
|
107
|
+
"version": "5.0.7",
|
|
108
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/test-driven-development/SKILL.md",
|
|
109
|
+
"tags": ["test", "tdd", "superpowers"],
|
|
110
|
+
"license": "MIT",
|
|
111
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
112
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "superpowers-writing-plans",
|
|
116
|
+
"description": "Author detailed implementation plans for multi-step tasks before touching code",
|
|
117
|
+
"author": "Jesse Vincent",
|
|
118
|
+
"version": "5.0.7",
|
|
119
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/writing-plans/SKILL.md",
|
|
120
|
+
"tags": ["plan", "write", "superpowers"],
|
|
121
|
+
"license": "MIT",
|
|
122
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
123
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "superpowers-executing-plans",
|
|
127
|
+
"description": "Execute a written implementation plan with review checkpoints",
|
|
128
|
+
"author": "Jesse Vincent",
|
|
129
|
+
"version": "5.0.7",
|
|
130
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/executing-plans/SKILL.md",
|
|
131
|
+
"tags": ["execute", "plan", "superpowers"],
|
|
132
|
+
"license": "MIT",
|
|
133
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
134
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "superpowers-using-git-worktrees",
|
|
138
|
+
"description": "Create isolated git worktrees for feature development with safety verification",
|
|
139
|
+
"author": "Jesse Vincent",
|
|
140
|
+
"version": "5.0.7",
|
|
141
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/using-git-worktrees/SKILL.md",
|
|
142
|
+
"tags": ["git", "worktree", "superpowers"],
|
|
143
|
+
"license": "MIT",
|
|
144
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
145
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "superpowers-verification-before-completion",
|
|
149
|
+
"description": "Run verification commands and confirm output before claiming work is complete",
|
|
150
|
+
"author": "Jesse Vincent",
|
|
151
|
+
"version": "5.0.7",
|
|
152
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/verification-before-completion/SKILL.md",
|
|
153
|
+
"tags": ["verify", "complete", "superpowers"],
|
|
154
|
+
"license": "MIT",
|
|
155
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
156
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"name": "superpowers-dispatching-parallel-agents",
|
|
160
|
+
"description": "Dispatch multiple independent tasks to parallel sub-agents",
|
|
161
|
+
"author": "Jesse Vincent",
|
|
162
|
+
"version": "5.0.7",
|
|
163
|
+
"source": "https://raw.githubusercontent.com/obra/superpowers/main/skills/dispatching-parallel-agents/SKILL.md",
|
|
164
|
+
"tags": ["parallel", "agent", "superpowers"],
|
|
165
|
+
"license": "MIT",
|
|
166
|
+
"attribution": "© 2025 Jesse Vincent — superpowers plugin",
|
|
167
|
+
"upstream": "https://github.com/obra/superpowers"
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
{
|
|
171
|
+
"name": "cli-anything-shotcut",
|
|
172
|
+
"description": "CLI for Shotcut — stateful video editing via MLT XML, designed for agents",
|
|
173
|
+
"author": "HKUDS",
|
|
174
|
+
"version": "0.1.0",
|
|
175
|
+
"source": "https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/shotcut/agent-harness/cli_anything/shotcut/skills/SKILL.md",
|
|
176
|
+
"tags": ["video", "editing", "shotcut", "cli-anything"],
|
|
177
|
+
"license": "Apache-2.0",
|
|
178
|
+
"attribution": "© HKUDS CLI-Anything contributors",
|
|
179
|
+
"upstream": "https://github.com/HKUDS/CLI-Anything"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "cli-anything-obsidian",
|
|
183
|
+
"description": "CLI for Obsidian via the Local REST API — knowledge management harness",
|
|
184
|
+
"author": "HKUDS",
|
|
185
|
+
"version": "0.1.0",
|
|
186
|
+
"source": "https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/obsidian/agent-harness/cli_anything/obsidian/skills/SKILL.md",
|
|
187
|
+
"tags": ["obsidian", "notes", "kb", "cli-anything"],
|
|
188
|
+
"license": "Apache-2.0",
|
|
189
|
+
"attribution": "© HKUDS CLI-Anything contributors",
|
|
190
|
+
"upstream": "https://github.com/HKUDS/CLI-Anything"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "cli-anything-zotero",
|
|
194
|
+
"description": "CLI for Zotero — reference management automation",
|
|
195
|
+
"author": "HKUDS",
|
|
196
|
+
"version": "0.4.1",
|
|
197
|
+
"source": "https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/zotero/agent-harness/cli_anything/zotero/skills/SKILL.md",
|
|
198
|
+
"tags": ["zotero", "research", "references", "cli-anything"],
|
|
199
|
+
"license": "Apache-2.0",
|
|
200
|
+
"attribution": "© HKUDS CLI-Anything contributors",
|
|
201
|
+
"upstream": "https://github.com/HKUDS/CLI-Anything"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "cli-anything-blender",
|
|
205
|
+
"description": "CLI for Blender — 3D modeling automation",
|
|
206
|
+
"author": "HKUDS",
|
|
207
|
+
"version": "0.1.0",
|
|
208
|
+
"source": "https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/blender/agent-harness/cli_anything/blender/skills/SKILL.md",
|
|
209
|
+
"tags": ["blender", "3d", "modeling", "cli-anything"],
|
|
210
|
+
"license": "Apache-2.0",
|
|
211
|
+
"attribution": "© HKUDS CLI-Anything contributors",
|
|
212
|
+
"upstream": "https://github.com/HKUDS/CLI-Anything"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"name": "cli-anything-inkscape",
|
|
216
|
+
"description": "CLI for Inkscape — vector graphics automation",
|
|
217
|
+
"author": "HKUDS",
|
|
218
|
+
"version": "0.1.0",
|
|
219
|
+
"source": "https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/inkscape/agent-harness/cli_anything/inkscape/skills/SKILL.md",
|
|
220
|
+
"tags": ["inkscape", "svg", "vector", "cli-anything"],
|
|
221
|
+
"license": "Apache-2.0",
|
|
222
|
+
"attribution": "© HKUDS CLI-Anything contributors",
|
|
223
|
+
"upstream": "https://github.com/HKUDS/CLI-Anything"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"name": "cli-anything-godot",
|
|
227
|
+
"description": "CLI for Godot — game engine automation with E2E demo pipeline",
|
|
228
|
+
"author": "HKUDS",
|
|
229
|
+
"version": "0.1.0",
|
|
230
|
+
"source": "https://raw.githubusercontent.com/HKUDS/CLI-Anything/main/godot/agent-harness/cli_anything/godot/skills/SKILL.md",
|
|
231
|
+
"tags": ["godot", "game", "engine", "cli-anything"],
|
|
232
|
+
"license": "Apache-2.0",
|
|
233
|
+
"attribution": "© HKUDS CLI-Anything contributors",
|
|
234
|
+
"upstream": "https://github.com/HKUDS/CLI-Anything"
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
{
|
|
238
|
+
"name": "tob-smart-contract-audit",
|
|
239
|
+
"description": "Trail of Bits — smart contract security audit workflow (link-only, CC-BY-SA)",
|
|
240
|
+
"author": "Trail of Bits",
|
|
241
|
+
"version": "1.0.0",
|
|
242
|
+
"source": "https://raw.githubusercontent.com/trailofbits/skills/main/skills/smart-contract-audit/SKILL.md",
|
|
243
|
+
"tags": ["security", "audit", "smart-contract", "tob"],
|
|
244
|
+
"license": "CC-BY-SA-4.0",
|
|
245
|
+
"attribution": "© Trail of Bits — CC-BY-SA-4.0 (ShareAlike)",
|
|
246
|
+
"upstream": "https://github.com/trailofbits/skills",
|
|
247
|
+
"installable": false
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"name": "tob-malware-detection",
|
|
251
|
+
"description": "Trail of Bits — malware detection workflow (link-only, CC-BY-SA)",
|
|
252
|
+
"author": "Trail of Bits",
|
|
253
|
+
"version": "1.0.0",
|
|
254
|
+
"source": "https://raw.githubusercontent.com/trailofbits/skills/main/skills/malware-detection/SKILL.md",
|
|
255
|
+
"tags": ["security", "malware", "detection", "tob"],
|
|
256
|
+
"license": "CC-BY-SA-4.0",
|
|
257
|
+
"attribution": "© Trail of Bits — CC-BY-SA-4.0 (ShareAlike)",
|
|
258
|
+
"upstream": "https://github.com/trailofbits/skills",
|
|
259
|
+
"installable": false
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review
|
|
3
|
+
description: Systematic code review for bugs, security, and quality
|
|
4
|
+
whenToUse: When reviewing code changes, PRs, or completed implementations
|
|
5
|
+
allowedTools: [Read, Glob, Grep, Bash]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code Review
|
|
9
|
+
|
|
10
|
+
Review the code systematically for:
|
|
11
|
+
|
|
12
|
+
1. **Correctness** — Does the code do what it claims? Logic errors?
|
|
13
|
+
2. **Security** — SQL injection, XSS, command injection, path traversal, secrets in code?
|
|
14
|
+
3. **Error handling** — Are errors caught and handled appropriately?
|
|
15
|
+
4. **Edge cases** — Null/empty inputs, boundary conditions, concurrent access?
|
|
16
|
+
5. **Performance** — Unnecessary loops, missing indexes, N+1 queries?
|
|
17
|
+
6. **Readability** — Clear naming, reasonable complexity, adequate (not excessive) comments?
|
|
18
|
+
|
|
19
|
+
Report findings with file path, line number, severity (critical/warning/info), and suggested fix.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commit
|
|
3
|
+
description: Create well-formed git commits
|
|
4
|
+
whenToUse: When the user asks to commit changes or create a PR
|
|
5
|
+
allowedTools: [Bash, Read, Glob]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Git Commit Workflow
|
|
9
|
+
|
|
10
|
+
1. Run `git status` and `git diff` to see what changed
|
|
11
|
+
2. Run `git log --oneline -5` to match the repo's commit message style
|
|
12
|
+
3. Stage specific files (not `git add -A`) to avoid committing secrets or binaries
|
|
13
|
+
4. Write a concise commit message:
|
|
14
|
+
- First line: imperative mood, under 72 chars, describes the "why"
|
|
15
|
+
- Body (if needed): explain context, not just what changed
|
|
16
|
+
5. Create the commit
|
|
17
|
+
6. Run `git status` to verify success
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debug
|
|
3
|
+
description: Systematic debugging approach
|
|
4
|
+
whenToUse: When encountering any bug, test failure, or unexpected behavior
|
|
5
|
+
allowedTools: [Read, Bash, Grep, Glob]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Systematic Debugging
|
|
9
|
+
|
|
10
|
+
Follow this process:
|
|
11
|
+
|
|
12
|
+
1. **Reproduce** — Confirm the bug exists. Run the failing test or command.
|
|
13
|
+
2. **Read the error** — What does the error message actually say? Read the full stack trace.
|
|
14
|
+
3. **Locate** — Find the exact line where the error occurs. Read the surrounding code.
|
|
15
|
+
4. **Understand** — Why does this code produce the wrong result? Trace the data flow.
|
|
16
|
+
5. **Hypothesize** — Form a specific theory about the cause.
|
|
17
|
+
6. **Verify** — Test your theory with a minimal change or print statement.
|
|
18
|
+
7. **Fix** — Make the smallest change that fixes the bug.
|
|
19
|
+
8. **Confirm** — Run the test/command again to verify the fix works.
|
|
20
|
+
|
|
21
|
+
Rules:
|
|
22
|
+
- Don't guess. Read the error message carefully.
|
|
23
|
+
- Don't change multiple things at once.
|
|
24
|
+
- Don't skip the reproduce step.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diagnose
|
|
3
|
+
description: Diagnose why an agent run failed, regressed, or produced unexpected output — using structured evidence instead of intuition
|
|
4
|
+
whenToUse: When an agent run produced wrong output, crashed mid-execution, or regressed from a previous successful run
|
|
5
|
+
allowedTools: [Read, Bash, Grep, Glob]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Diagnose Agent Run
|
|
9
|
+
|
|
10
|
+
Apply this when something an agent did went wrong — not for ordinary code bugs (use `debug` for those).
|
|
11
|
+
|
|
12
|
+
1. **Define the failure precisely** — What was the expected output? What was the actual output? One sentence each.
|
|
13
|
+
2. **Locate the artifacts** — Find the run's logs, transcripts, tool-call traces, and any files it produced. Common locations: `.oh/logs/`, `.oh/tasks.json`, `.oh/sessions/`, stderr capture.
|
|
14
|
+
3. **Reconstruct the timeline** — Walk through tool calls in order. Where did the trajectory diverge from what should have happened?
|
|
15
|
+
4. **Isolate the inflection point** — Find the single tool call, prompt step, or input that turned a working run into a broken one.
|
|
16
|
+
5. **Form a hypothesis** — Was it bad input, model regression, missing context, tool timeout, permission denial, or stale memory? Be specific.
|
|
17
|
+
6. **Verify with a minimal repro** — Re-run only the inflection step in isolation. Confirm the same wrong behavior reproduces.
|
|
18
|
+
7. **Report** — Write up: failure mode, inflection point (file:line or message index), root cause, suggested fix.
|
|
19
|
+
|
|
20
|
+
Rules:
|
|
21
|
+
- Don't guess from the symptom. Read the actual logs.
|
|
22
|
+
- Distinguish "the model made a bad decision" from "the harness broke" — they need different fixes.
|
|
23
|
+
- If the run is non-deterministic, repro at least 3 times before claiming a hypothesis.
|
|
24
|
+
- Never edit code as part of diagnosis. The output is a report, not a fix.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan
|
|
3
|
+
description: Design an implementation plan before coding
|
|
4
|
+
whenToUse: When the user asks to build a feature, fix a non-trivial bug, or refactor — anything beyond a one-line change
|
|
5
|
+
allowedTools: [Read, Glob, Grep]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Implementation Planning
|
|
9
|
+
|
|
10
|
+
Plan before you code. The output is a written plan, not edited files.
|
|
11
|
+
|
|
12
|
+
1. **Restate the goal** — One sentence describing what success looks like. Confirm with the user if ambiguous.
|
|
13
|
+
2. **Map the affected surface** — List every file you'll touch and every public interface you'll change.
|
|
14
|
+
3. **Find existing patterns** — Search the codebase for similar features. Reuse existing utilities; don't invent parallel ones.
|
|
15
|
+
4. **Identify the minimal change** — What's the smallest set of edits that delivers the goal? Resist scope creep.
|
|
16
|
+
5. **Sequence the work** — Order the changes so each step is independently testable. Each step should leave the build green.
|
|
17
|
+
6. **Plan verification** — How will you know each step worked? List the commands or manual checks.
|
|
18
|
+
7. **Surface risks** — What could go wrong? Migration data loss, breaking changes, perf regression, security holes? Note each with a mitigation.
|
|
19
|
+
8. **Write it up** — A short doc with: goal, files touched, sequence, verification, risks. Get user approval before coding.
|
|
20
|
+
|
|
21
|
+
Rules:
|
|
22
|
+
- Don't write code in this phase. Only research and write the plan.
|
|
23
|
+
- A plan that lists "all the things" is not a plan. Pick the recommended approach.
|
|
24
|
+
- Cite files and functions you'll reuse with `path:line` references.
|
|
25
|
+
- If you can't write the plan in one page, the scope is too big — split it.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: simplify
|
|
3
|
+
description: Refactor code to be simpler and more maintainable without changing behavior
|
|
4
|
+
whenToUse: When code is hard to read, has duplicated logic, over-abstracts, or accumulated dead branches
|
|
5
|
+
allowedTools: [Read, Edit, Bash, Glob, Grep]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Simplify Code
|
|
9
|
+
|
|
10
|
+
Simpler code is easier to read, change, and debug. Behavior must not change.
|
|
11
|
+
|
|
12
|
+
1. **Read the code in scope** — Understand what it does end-to-end before touching anything.
|
|
13
|
+
2. **List the smells** — Duplication, dead branches, premature abstraction, deeply nested conditionals, vague names, comments that explain WHAT instead of WHY.
|
|
14
|
+
3. **Confirm tests cover the behavior** — If there are no tests, write characterization tests first. Refactoring without tests is gambling.
|
|
15
|
+
4. **Make one change at a time** — Inline a wrapper, extract a function, rename a variable, delete dead code. Run tests after each.
|
|
16
|
+
5. **Prefer deletion over addition** — If you can remove code without breaking tests, that's almost always the right move.
|
|
17
|
+
6. **Stop when it's good enough** — Don't refactor for its own sake. Stop when further changes wouldn't meaningfully improve readability.
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
- Never change behavior. If you discover a bug, file it separately — don't fix it during a refactor.
|
|
21
|
+
- Three similar lines is better than a premature abstraction. Wait until the third or fourth occurrence before extracting.
|
|
22
|
+
- Delete comments that explain what well-named code already says.
|
|
23
|
+
- If the change touches more than one file or one concern, split it into separate refactors.
|
|
24
|
+
- Don't introduce new dependencies, frameworks, or patterns.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: Test-driven development workflow
|
|
4
|
+
whenToUse: When implementing any feature or bugfix, before writing implementation code
|
|
5
|
+
allowedTools: [Read, Edit, Write, Bash, Glob, Grep]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Test-Driven Development
|
|
9
|
+
|
|
10
|
+
Follow this workflow strictly:
|
|
11
|
+
|
|
12
|
+
1. **Write the test first** — Create a failing test that describes the expected behavior
|
|
13
|
+
2. **Run the test** — Verify it fails for the right reason
|
|
14
|
+
3. **Write minimal implementation** — Only enough code to make the test pass
|
|
15
|
+
4. **Run tests again** — Verify all tests pass
|
|
16
|
+
5. **Refactor** — Clean up the code while keeping tests green
|
|
17
|
+
|
|
18
|
+
Rules:
|
|
19
|
+
- Never write implementation before the test
|
|
20
|
+
- Each test should test one thing
|
|
21
|
+
- Keep tests fast and isolated
|
|
22
|
+
- Use descriptive test names that explain the behavior
|
package/dist/agents/roles.d.ts
CHANGED
|
@@ -13,10 +13,20 @@ export type AgentRole = {
|
|
|
13
13
|
name: string;
|
|
14
14
|
description: string;
|
|
15
15
|
systemPromptSupplement: string;
|
|
16
|
-
/** Suggested tools to include (empty = all tools) */
|
|
16
|
+
/** Suggested tools to include (empty = all tools) — Anthropic alias: `tools` */
|
|
17
17
|
suggestedTools?: string[];
|
|
18
|
+
/** Tool denylist applied after suggestedTools — Anthropic standard: `disallowedTools` */
|
|
19
|
+
disallowedTools?: string[];
|
|
20
|
+
/** Per-agent model override (e.g. "sonnet", "opus", "haiku", or a full model ID) */
|
|
21
|
+
model?: string;
|
|
22
|
+
/** Isolation mode for sub-agent execution. Default: inherits parent. */
|
|
23
|
+
isolation?: "none" | "worktree";
|
|
24
|
+
/** Per-agent MCP servers injected only when this agent runs (parsed via raw passthrough; dispatcher wiring is a future task). */
|
|
25
|
+
mcpServers?: Record<string, unknown>;
|
|
26
|
+
/** Per-agent hooks (parsed via raw passthrough; dispatcher wiring is a future task). */
|
|
27
|
+
hooks?: Record<string, unknown>;
|
|
18
28
|
};
|
|
19
|
-
/** Discover markdown agent roles from .oh/agents/
|
|
29
|
+
/** Discover markdown agent roles from .oh/agents/ + ~/.oh/agents/ + .claude/agents/ + ~/.claude/agents/ */
|
|
20
30
|
export declare function discoverMarkdownAgents(): AgentRole[];
|
|
21
31
|
/** Get a role by ID (checks built-in first, then markdown agents) */
|
|
22
32
|
export declare function getRole(id: string): AgentRole | undefined;
|
package/dist/agents/roles.js
CHANGED
|
@@ -163,14 +163,37 @@ import { homedir } from "node:os";
|
|
|
163
163
|
import { basename, join } from "node:path";
|
|
164
164
|
const PROJECT_AGENTS_DIR = join(".oh", "agents");
|
|
165
165
|
const GLOBAL_AGENTS_DIR = join(homedir(), ".oh", "agents");
|
|
166
|
+
// Claude Code ecosystem mirror paths
|
|
167
|
+
const CC_PROJECT_AGENTS_DIR = join(".claude", "agents");
|
|
168
|
+
const CC_GLOBAL_AGENTS_DIR = join(homedir(), ".claude", "agents");
|
|
169
|
+
/** Parse a frontmatter list value. Accepts `[a, b]` (YAML inline) OR `a b c` (Claude Code style). */
|
|
170
|
+
function parseAgentList(raw) {
|
|
171
|
+
const trimmed = raw.trim();
|
|
172
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
173
|
+
return trimmed
|
|
174
|
+
.slice(1, -1)
|
|
175
|
+
.split(",")
|
|
176
|
+
.map((t) => t.trim())
|
|
177
|
+
.filter(Boolean);
|
|
178
|
+
}
|
|
179
|
+
// Claude Code spec: comma-separated OR space-separated bare tokens. Handle both.
|
|
180
|
+
return trimmed
|
|
181
|
+
.replace(/^["']|["']$/g, "")
|
|
182
|
+
.split(/[,\s]+/)
|
|
183
|
+
.map((t) => t.trim())
|
|
184
|
+
.filter(Boolean);
|
|
185
|
+
}
|
|
166
186
|
/**
|
|
167
187
|
* Parse a markdown agent file into an AgentRole.
|
|
168
188
|
*
|
|
169
|
-
* Format:
|
|
189
|
+
* Format (OH-native + Claude Code interoperable):
|
|
170
190
|
* ---
|
|
171
191
|
* name: My Agent
|
|
172
192
|
* description: What it does
|
|
173
|
-
* tools:
|
|
193
|
+
* tools: Read, Grep, Bash # space- or comma-separated, OR YAML array
|
|
194
|
+
* disallowedTools: Write, Edit # tool denylist
|
|
195
|
+
* model: sonnet # model override
|
|
196
|
+
* isolation: worktree # explicit isolation mode
|
|
174
197
|
* ---
|
|
175
198
|
*
|
|
176
199
|
* System prompt content...
|
|
@@ -182,20 +205,43 @@ function parseAgentMarkdown(raw, filePath) {
|
|
|
182
205
|
const fm = fmMatch[1];
|
|
183
206
|
const nameMatch = fm.match(/^name:\s*(.+)$/m);
|
|
184
207
|
const descMatch = fm.match(/^description:\s*(.+)$/m);
|
|
185
|
-
const toolsMatch = fm.match(/^tools:\s
|
|
208
|
+
const toolsMatch = fm.match(/^tools:\s*(.+)$/m);
|
|
209
|
+
const disallowedMatch = fm.match(/^disallowedTools:\s*(.+)$/m) ?? fm.match(/^disallowed-tools:\s*(.+)$/m);
|
|
210
|
+
const modelMatch = fm.match(/^model:\s*(.+)$/m);
|
|
211
|
+
const isolationMatch = fm.match(/^isolation:\s*(.+)$/m);
|
|
186
212
|
const fmEnd = raw.indexOf("---", raw.indexOf("---") + 3);
|
|
187
213
|
const content = fmEnd > 0 ? raw.slice(fmEnd + 3).trim() : "";
|
|
188
214
|
const id = basename(filePath, ".md")
|
|
189
215
|
.toLowerCase()
|
|
190
216
|
.replace(/[^a-z0-9]+/g, "-");
|
|
217
|
+
const isolation = isolationMatch?.[1]?.trim().replace(/^["']|["']$/g, "");
|
|
218
|
+
const validIsolation = isolation === "worktree" || isolation === "none" ? isolation : undefined;
|
|
219
|
+
// Parse optional inline-JSON fields (mcpServers, hooks). These are block fields in
|
|
220
|
+
// Anthropic's YAML but we support single-line JSON for lightweight frontmatter use.
|
|
221
|
+
const mcpServersMatch = fm.match(/^mcpServers:\s*(\{[\s\S]*?\})\s*$/m);
|
|
222
|
+
const hooksMatch = fm.match(/^hooks:\s*(\{[\s\S]*?\})\s*$/m);
|
|
191
223
|
return {
|
|
192
224
|
id,
|
|
193
225
|
name: nameMatch?.[1]?.trim() ?? id,
|
|
194
226
|
description: descMatch?.[1]?.trim() ?? "",
|
|
195
227
|
systemPromptSupplement: content,
|
|
196
|
-
suggestedTools: toolsMatch ? toolsMatch[1]
|
|
228
|
+
suggestedTools: toolsMatch ? parseAgentList(toolsMatch[1]) : undefined,
|
|
229
|
+
disallowedTools: disallowedMatch ? parseAgentList(disallowedMatch[1]) : undefined,
|
|
230
|
+
model: modelMatch?.[1]?.trim().replace(/^["']|["']$/g, ""),
|
|
231
|
+
isolation: validIsolation,
|
|
232
|
+
mcpServers: mcpServersMatch ? tryParseJson(mcpServersMatch[1]) : undefined,
|
|
233
|
+
hooks: hooksMatch ? tryParseJson(hooksMatch[1]) : undefined,
|
|
197
234
|
};
|
|
198
235
|
}
|
|
236
|
+
function tryParseJson(raw) {
|
|
237
|
+
try {
|
|
238
|
+
const v = JSON.parse(raw);
|
|
239
|
+
return v && typeof v === "object" ? v : undefined;
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
199
245
|
/** Load agent roles from a directory of .md files */
|
|
200
246
|
function loadAgentsFromDir(dir) {
|
|
201
247
|
if (!existsSync(dir))
|
|
@@ -213,9 +259,22 @@ function loadAgentsFromDir(dir) {
|
|
|
213
259
|
})
|
|
214
260
|
.filter((r) => r !== null);
|
|
215
261
|
}
|
|
216
|
-
/** Discover markdown agent roles from .oh/agents/
|
|
262
|
+
/** Discover markdown agent roles from .oh/agents/ + ~/.oh/agents/ + .claude/agents/ + ~/.claude/agents/ */
|
|
217
263
|
export function discoverMarkdownAgents() {
|
|
218
|
-
|
|
264
|
+
const all = [
|
|
265
|
+
...loadAgentsFromDir(PROJECT_AGENTS_DIR),
|
|
266
|
+
...loadAgentsFromDir(GLOBAL_AGENTS_DIR),
|
|
267
|
+
...loadAgentsFromDir(CC_PROJECT_AGENTS_DIR),
|
|
268
|
+
...loadAgentsFromDir(CC_GLOBAL_AGENTS_DIR),
|
|
269
|
+
];
|
|
270
|
+
// De-duplicate by id (first wins — OH paths take precedence over .claude paths)
|
|
271
|
+
const seen = new Set();
|
|
272
|
+
return all.filter((r) => {
|
|
273
|
+
if (seen.has(r.id))
|
|
274
|
+
return false;
|
|
275
|
+
seen.add(r.id);
|
|
276
|
+
return true;
|
|
277
|
+
});
|
|
219
278
|
}
|
|
220
279
|
/** Get a role by ID (checks built-in first, then markdown agents) */
|
|
221
280
|
export function getRole(id) {
|
package/dist/commands/ai.js
CHANGED
|
@@ -109,12 +109,29 @@ export function registerAICommands(register) {
|
|
|
109
109
|
lines.push("Send messages with: Agent({ prompt: 'ask the other agent...', allowed_tools: ['SendMessage'] })");
|
|
110
110
|
return { output: lines.join("\n"), handled: true };
|
|
111
111
|
});
|
|
112
|
-
|
|
112
|
+
const pluginsHandler = (args) => {
|
|
113
113
|
const { discoverPlugins, discoverSkills } = require("../harness/plugins.js");
|
|
114
114
|
const { searchMarketplace, installPlugin, uninstallPlugin, getInstalledPlugins, listMarketplaces, addMarketplace, removeMarketplace, formatMarketplaceSearch, formatInstalledPlugins, } = require("../harness/marketplace.js");
|
|
115
115
|
const parts = args.trim().split(/\s+/);
|
|
116
116
|
const subcommand = parts[0] ?? "";
|
|
117
117
|
const rest = parts.slice(1).join(" ");
|
|
118
|
+
if (subcommand === "info" && rest) {
|
|
119
|
+
const installed = getInstalledPlugins();
|
|
120
|
+
const p = installed.find((x) => x.name === rest);
|
|
121
|
+
if (!p)
|
|
122
|
+
return { output: `Plugin "${rest}" not found among installed plugins.`, handled: true };
|
|
123
|
+
const lines = [
|
|
124
|
+
`${p.name}@${p.version}`,
|
|
125
|
+
p.description ? ` ${p.description}` : "",
|
|
126
|
+
p.author ? ` by ${p.author}` : "",
|
|
127
|
+
p.license ? ` license: ${p.license}` : "",
|
|
128
|
+
p.homepage ? ` homepage: ${p.homepage}` : "",
|
|
129
|
+
p.keywords?.length ? ` keywords: ${p.keywords.join(", ")}` : "",
|
|
130
|
+
` marketplace: ${p.marketplace}`,
|
|
131
|
+
` cachePath: ${p.cachePath}`,
|
|
132
|
+
].filter(Boolean);
|
|
133
|
+
return { output: lines.join("\n"), handled: true };
|
|
134
|
+
}
|
|
118
135
|
if (subcommand === "marketplace") {
|
|
119
136
|
const action = parts[1];
|
|
120
137
|
const source = parts.slice(2).join(" ");
|
|
@@ -192,13 +209,16 @@ export function registerAICommands(register) {
|
|
|
192
209
|
}
|
|
193
210
|
lines.push("");
|
|
194
211
|
lines.push("Commands:");
|
|
195
|
-
lines.push(" /
|
|
196
|
-
lines.push(" /
|
|
197
|
-
lines.push(" /
|
|
198
|
-
lines.push(" /
|
|
199
|
-
lines.push(" /
|
|
212
|
+
lines.push(" /plugin info <name> Show full manifest for a plugin");
|
|
213
|
+
lines.push(" /plugin search <query> Search marketplaces");
|
|
214
|
+
lines.push(" /plugin install <name> Install from marketplace");
|
|
215
|
+
lines.push(" /plugin uninstall <name> Remove a plugin");
|
|
216
|
+
lines.push(" /plugin marketplace add <src> Add a marketplace");
|
|
217
|
+
lines.push(" /plugin marketplace List marketplaces");
|
|
200
218
|
return { output: lines.join("\n"), handled: true };
|
|
201
|
-
}
|
|
219
|
+
};
|
|
220
|
+
register("plugins", "Manage plugins: list, search, install, uninstall, marketplace, info", pluginsHandler);
|
|
221
|
+
register("plugin", "Alias of /plugins (Claude Code-style singular)", pluginsHandler);
|
|
202
222
|
register("cybergotchi", "Manage your cybergotchi — feed · pet · rest · status · rename · reset", (args) => {
|
|
203
223
|
return handleCybergotchiCommand(args);
|
|
204
224
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Skill management commands — /skill-create, /skill-delete, /skill-edit, /skill-search, /skill-install
|
|
2
|
+
* Skill management commands — /skills, /skill-create, /skill-delete, /skill-edit, /skill-search, /skill-install
|
|
3
3
|
*/
|
|
4
4
|
import type { CommandHandler } from "./types.js";
|
|
5
5
|
export declare function registerSkillCommands(register: (name: string, description: string, handler: CommandHandler) => void): void;
|