openhermes 1.2.2
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 +281 -0
- package/autorecall.mjs +167 -0
- package/bootstrap.mjs +255 -0
- package/curator.mjs +470 -0
- package/harness/commands/build-fix.md +60 -0
- package/harness/commands/code-review.md +71 -0
- package/harness/commands/doctor.md +42 -0
- package/harness/commands/learn.md +37 -0
- package/harness/commands/memory-search.md +37 -0
- package/harness/commands/plan.md +53 -0
- package/harness/commands/security.md +93 -0
- package/harness/constitution/soul.md +76 -0
- package/harness/instructions/RUNTIME.md +21 -0
- package/harness/prompts/architect.txt +175 -0
- package/harness/prompts/build-error-resolver.md +37 -0
- package/harness/prompts/code-reviewer.md +33 -0
- package/harness/prompts/e2e-runner.txt +305 -0
- package/harness/prompts/explore.md +29 -0
- package/harness/prompts/planner.md +30 -0
- package/harness/prompts/security-reviewer.md +35 -0
- package/harness/rules/audit.md +84 -0
- package/harness/rules/checkpointing.md +75 -0
- package/harness/rules/context-loading.md +33 -0
- package/harness/rules/credential-exposure.md +0 -0
- package/harness/rules/delegation.md +76 -0
- package/harness/rules/memory-management.md +28 -0
- package/harness/rules/precedence.md +52 -0
- package/harness/rules/promotion.md +46 -0
- package/harness/rules/ranking.md +64 -0
- package/harness/rules/retrieval.md +94 -0
- package/harness/rules/runtime-guards.md +196 -0
- package/harness/rules/self-heal.md +79 -0
- package/harness/rules/session-start.md +34 -0
- package/harness/rules/skills-management.md +165 -0
- package/harness/rules/state-drift.md +192 -0
- package/harness/rules/verification.md +88 -0
- package/harness/skills/.bundled_manifest +17 -0
- package/harness/skills/.usage.json +6 -0
- package/harness/skills/api-design/SKILL.md +523 -0
- package/harness/skills/backend-patterns/SKILL.md +598 -0
- package/harness/skills/coding-standards/SKILL.md +549 -0
- package/harness/skills/e2e-testing/SKILL.md +326 -0
- package/harness/skills/frontend-patterns/SKILL.md +642 -0
- package/harness/skills/frontend-slides/SKILL.md +184 -0
- package/harness/skills/security-review/SKILL.md +495 -0
- package/harness/skills/strategic-compact/SKILL.md +131 -0
- package/harness/skills/tdd-workflow/SKILL.md +463 -0
- package/harness/skills/verification-loop/SKILL.md +126 -0
- package/index.mjs +5 -0
- package/lib/hardening.mjs +113 -0
- package/lib/memory-tools-plugin.mjs +265 -0
- package/lib/schema-validator.mjs +77 -0
- package/lib/tools/_memory.mjs +230 -0
- package/lib/tools/hm_get.mjs +13 -0
- package/lib/tools/hm_latest.mjs +12 -0
- package/lib/tools/hm_list.mjs +13 -0
- package/lib/tools/hm_put.mjs +14 -0
- package/lib/tools/hm_search.mjs +16 -0
- package/package.json +49 -0
- package/schemas/audit.schema.json +61 -0
- package/schemas/backlog.schema.json +42 -0
- package/schemas/checkpoint.schema.json +44 -0
- package/schemas/constraint.schema.json +41 -0
- package/schemas/decision.schema.json +42 -0
- package/schemas/instinct.schema.json +42 -0
- package/schemas/loop-state.schema.json +33 -0
- package/schemas/mistake.schema.json +43 -0
- package/schemas/verification_receipt.schema.json +67 -0
- package/skill-builder.mjs +113 -0
package/bootstrap.mjs
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import fs from "node:fs"
|
|
3
|
+
import os from "node:os"
|
|
4
|
+
import { fileURLToPath } from "node:url"
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
7
|
+
const HARNESS_DIR = path.resolve(__dirname, "harness")
|
|
8
|
+
const RULES_DIR = path.join(HARNESS_DIR, "rules")
|
|
9
|
+
const SKILLS_DIR = path.join(HARNESS_DIR, "skills")
|
|
10
|
+
const CONSTITUTION_FILE = path.join(HARNESS_DIR, "constitution", "soul.md")
|
|
11
|
+
const RUNTIME_FILE = path.join(HARNESS_DIR, "instructions", "RUNTIME.md")
|
|
12
|
+
const TOOLS_SOURCE_DIR = path.resolve(__dirname, "lib", "tools")
|
|
13
|
+
const USER_TOOLS_DIR = path.join(os.homedir(), ".config", "opencode", "tools")
|
|
14
|
+
|
|
15
|
+
let _bootstrapCache = undefined
|
|
16
|
+
|
|
17
|
+
function buildBootstrapContent() {
|
|
18
|
+
const constitution = fs.readFileSync(CONSTITUTION_FILE, "utf8")
|
|
19
|
+
const runtime = fs.readFileSync(RUNTIME_FILE, "utf8")
|
|
20
|
+
|
|
21
|
+
const router = `## AGENTS.md
|
|
22
|
+
|
|
23
|
+
OpenHermes thin constitutional router. Full harness → \`${HARNESS_DIR}\\\`.
|
|
24
|
+
|
|
25
|
+
## Soul
|
|
26
|
+
|
|
27
|
+
Pragmatic. Concise. Task-oriented. Subagent-first. Inspect, then act. Smallest correct change. Verify, don't claim. Receipts over vibes. Recover by narrowing, not posturing. Skeptical — demand proof. Precision-first search: needle then broad, never reverse.
|
|
28
|
+
|
|
29
|
+
## Safety
|
|
30
|
+
|
|
31
|
+
Snapshot before mutation. Never delete unrelated files. Never assume \`%USERPROFILE%\\\\.config\\\\opencode\` is a git repo. Verify or roll back. **NEVER delete \`auth.json\`** (\`%USERPROFILE%\\\\.local\\\\share\\\\opencode\\\\auth.json\`).
|
|
32
|
+
|
|
33
|
+
## Arsenal
|
|
34
|
+
|
|
35
|
+
| Category | Items |
|
|
36
|
+
|----------|-------|
|
|
37
|
+
| **Native tools** | \`read\`, \`write\`, \`edit\`, \`glob\`, \`grep\`, \`bash\`, \`task\`, \`webfetch\`, \`skill\`, \`todowrite\`, \`todoread\` |
|
|
38
|
+
| **MCP: openhermes-memory** | \`hm_put\`, \`hm_get\`, \`hm_list\`, \`hm_latest\`, \`hm_search\` |
|
|
39
|
+
| **Memory recall cache** | \`openhermes/memory/recall/cache.json\` — read on session start, no MCP round-trip |
|
|
40
|
+
| **Subagents** | \`explore\` (read-only), \`general\` (multi-step), \`architect\`, \`planner\`, \`build-error-resolver\`, \`code-reviewer\`, \`security-reviewer\`, \`e2e-runner\` |
|
|
41
|
+
| **Plugins** | \`curator\` (checkpoints, mistakes, audit, compaction), \`autorecall\` (recall cache on \`session.created\`), \`skill-builder\` (complex session detection) |
|
|
42
|
+
|
|
43
|
+
## Skills (available via \`skill\` tool)
|
|
44
|
+
|
|
45
|
+
\`agent-browser\` \`batch-files\` \`caveman\` \`create-architectural-decision-record\` \`create-readme\` \`design-md\` \`diagnose\` \`docker-expert\` \`enhance-prompt\` \`find-skills\` \`grill-me\` \`grill-with-docs\` \`improve-codebase-architecture\` \`opencode-doctor\` \`opencode-ecc-lifecycle\` \`opencode-docs\` \`opencode-expert\` \`opencode-models\` \`opencode-recall\` \`react:components\` \`setup-matt-pocock-skills\` \`skill-creator\` \`squeez-expert\` \`stitch-design\` \`stitch-loop\` \`tailored-resume-generator\` \`taste-design\` \`tdd\` \`to-issues\` \`to-prd\` \`triage\` \`typescript-expert\` \`write-a-skill\` \`write-coding-standards-from-file\` \`zoom-out\`
|
|
46
|
+
|
|
47
|
+
**OpenHermes-specific skills (discovered from harness):** \`api-design\` \`backend-patterns\` \`coding-standards\` \`e2e-testing\` \`frontend-patterns\` \`frontend-slides\` \`security-review\` \`strategic-compact\` \`tdd-workflow\` \`verification-loop\`
|
|
48
|
+
|
|
49
|
+
## Delegation (Mandatory)
|
|
50
|
+
|
|
51
|
+
Main context = coordination + verification only. Substantive work → subagent.
|
|
52
|
+
|
|
53
|
+
| Trigger | Subagent |
|
|
54
|
+
|---------|----------|
|
|
55
|
+
| Multi-file implementation | \`architect\` or \`planner\` |
|
|
56
|
+
| Build/TS error | \`build-error-resolver\` |
|
|
57
|
+
| Code review | \`code-reviewer\` |
|
|
58
|
+
| Security audit | \`security-reviewer\` |
|
|
59
|
+
| E2E testing | \`e2e-runner\` |
|
|
60
|
+
| Multi-file search/exploration | \`explore\` or \`general\` |
|
|
61
|
+
| Any non-trivial multi-step | appropriate specialist |
|
|
62
|
+
|
|
63
|
+
Never delegate trivial single-step ops. Subagent returns diff + summary + verification; inspect return only. Full ref: \`${RULES_DIR}\\\\delegation.md\`.
|
|
64
|
+
|
|
65
|
+
## Memory — Gated & Precision-First
|
|
66
|
+
|
|
67
|
+
- **Start**: Read recall cache first. If stale/missing → \`hm_latest\` for relevant classes.
|
|
68
|
+
- **Before work**: Narrow \`hm_search\` by class, scope, keywords. Never read full indexes.
|
|
69
|
+
- **Before close**: Query same-type mistakes (7 days). Match → \`code-reviewer\` or \`security-reviewer\`.
|
|
70
|
+
- **On failure**: \`hm_search\` for similar incidents. Search memory before asking user.
|
|
71
|
+
- **Precision ladder**: \`hm_latest\` → \`hm_search\` → \`hm_get\` → \`hm_list\` (last resort). Full index reads only for explicit audit/repair tasks.
|
|
72
|
+
- **Anti-spam**: No obvious facts, no one-off prefs, no temp state, no low-risk mistakes. Supersede, don't duplicate. Full rules: \`${RULES_DIR}\\\\retrieval.md\`, \`${RULES_DIR}\\\\memory-management.md\`.
|
|
73
|
+
|
|
74
|
+
## Self-Edit Authority
|
|
75
|
+
|
|
76
|
+
| Auto | Conditional | Needs approval |
|
|
77
|
+
|------|-------------|----------------|
|
|
78
|
+
| Memory entries, mistakes, checkpoints, receipts | openhermes docs/schemas/templates/non-core rules patches | AGENTS.md core, model routing, permissions, config, protected settings |
|
|
79
|
+
|
|
80
|
+
Full tiers: \`${RULES_DIR}\\\\self-heal.md\`.
|
|
81
|
+
|
|
82
|
+
## Precedence
|
|
83
|
+
|
|
84
|
+
1. User instruction. 2. Safety/legal/destructive guard. 3. Constitution (\`${HARNESS_DIR}\\\\constitution\\\`). 4. Project constraints. 5. Project decisions. 6. Verified guards. 7. Checkpoints. 8. Instincts. 9. Freeform notes. Full: \`${RULES_DIR}\\\\precedence.md\`.
|
|
85
|
+
|
|
86
|
+
## Hygiene
|
|
87
|
+
|
|
88
|
+
- Checkpoint on meaningful boundaries. Compress closed segments immediately.
|
|
89
|
+
- After subagent return: verify → compress that block.
|
|
90
|
+
- Compress proactively.
|
|
91
|
+
- Skill candidates → \`/learn\` only if repeated pattern + \`hm_search\` confirms no dup. See \`${RULES_DIR}\\\\skills-management.md\`.
|
|
92
|
+
- Audit triggers: openhermes/config change, repeated failures, session start when last audit >7 days. See \`${RULES_DIR}\\\\audit.md\`.
|
|
93
|
+
|
|
94
|
+
## Escalation
|
|
95
|
+
|
|
96
|
+
T0: observe → log mistake → smallest fix. T1: add prevention rule → verify. T2: diagnosis/specialist → backlog. T3: constrained safe mode. Full: \`${RULES_DIR}\\\\self-heal.md\`.
|
|
97
|
+
|
|
98
|
+
## State
|
|
99
|
+
|
|
100
|
+
- **Config root**: \`%USERPROFILE%\\\\.config\\\\opencode\`
|
|
101
|
+
- **Auth**: \`%USERPROFILE%\\\\.local\\\\share\\\\opencode\\\\auth.json\` (NEVER delete)
|
|
102
|
+
- **Forensic ledger**: \`%USERPROFILE%\\\\.local\\\\share\\\\opencode\\\\opencode.db\``
|
|
103
|
+
|
|
104
|
+
return [
|
|
105
|
+
`<OPENHERMES_BOOTSTRAP>\nOpenHermes v${getOwnVersion()} active. Harness: \`${HARNESS_DIR}\\\`. Memory at \`~/.config/opencode/openhermes/memory/\`. Rules at \`${RULES_DIR}\\\`. Skills discoverable via \`skill\` tool — use \`skill\` tool to list/load them.`,
|
|
106
|
+
`<OPENHERMES_CONSTITUTION>\n${constitution}\n</OPENHERMES_CONSTITUTION>`,
|
|
107
|
+
`<OPENHERMES_RUNTIME>\n${runtime}\n</OPENHERMES_RUNTIME>`,
|
|
108
|
+
`<OPENHERMES_ROUTER>\n${router}\n</OPENHERMES_ROUTER>`
|
|
109
|
+
].join("\n\n")
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getOwnVersion() {
|
|
113
|
+
try {
|
|
114
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8"))
|
|
115
|
+
return pkg.version || "1.0.0"
|
|
116
|
+
} catch { return "1.0.0" }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function installToolFiles() {
|
|
120
|
+
try {
|
|
121
|
+
if (!fs.existsSync(TOOLS_SOURCE_DIR)) return
|
|
122
|
+
const files = fs.readdirSync(TOOLS_SOURCE_DIR).filter(f => f.endsWith(".mjs") && f !== "_memory.mjs")
|
|
123
|
+
if (!files.length) return
|
|
124
|
+
fs.mkdirSync(USER_TOOLS_DIR, { recursive: true })
|
|
125
|
+
const pkgVersion = getOwnVersion()
|
|
126
|
+
const markerPath = path.join(USER_TOOLS_DIR, ".openhermes-version")
|
|
127
|
+
let installedVersion = ""
|
|
128
|
+
try { installedVersion = fs.readFileSync(markerPath, "utf8").trim() } catch {}
|
|
129
|
+
if (installedVersion === pkgVersion) {
|
|
130
|
+
const existing = fs.readdirSync(USER_TOOLS_DIR).filter(f => f.endsWith(".mjs"))
|
|
131
|
+
const needed = [...files, "_memory.mjs"]
|
|
132
|
+
if (needed.every(f => existing.includes(f))) return
|
|
133
|
+
}
|
|
134
|
+
for (const f of ["_memory.mjs", ...files]) {
|
|
135
|
+
const src = path.join(TOOLS_SOURCE_DIR, f)
|
|
136
|
+
const dst = path.join(USER_TOOLS_DIR, f)
|
|
137
|
+
if (fs.existsSync(src)) fs.copyFileSync(src, dst)
|
|
138
|
+
}
|
|
139
|
+
fs.writeFileSync(markerPath, pkgVersion, "utf8")
|
|
140
|
+
process.stderr.write(`[openhermes-bootstrap] installed ${files.length + 1} tool files (v${pkgVersion})\n`)
|
|
141
|
+
} catch (err) {
|
|
142
|
+
process.stderr.write(`[openhermes-bootstrap] tool install error: ${err.message}\n`)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export const BootstrapPlugin = async ({ client, directory }) => {
|
|
147
|
+
installToolFiles()
|
|
148
|
+
|
|
149
|
+
const getContent = () => {
|
|
150
|
+
if (_bootstrapCache !== undefined) return _bootstrapCache
|
|
151
|
+
try {
|
|
152
|
+
_bootstrapCache = buildBootstrapContent()
|
|
153
|
+
} catch (err) {
|
|
154
|
+
console.error("[openhermes-bootstrap] failed to build bootstrap content:", err.message)
|
|
155
|
+
_bootstrapCache = null
|
|
156
|
+
}
|
|
157
|
+
return _bootstrapCache
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
name: "openhermes-bootstrap",
|
|
162
|
+
|
|
163
|
+
config: async (config) => {
|
|
164
|
+
config.skills = config.skills || {}
|
|
165
|
+
config.skills.paths = config.skills.paths || []
|
|
166
|
+
if (!config.skills.paths.includes(SKILLS_DIR)) {
|
|
167
|
+
config.skills.paths.push(SKILLS_DIR)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
config.agent = config.agent || {}
|
|
171
|
+
const PROMPTS_DIR = path.join(HARNESS_DIR, "prompts")
|
|
172
|
+
const p = (name) => `{file:${path.join(PROMPTS_DIR, name)}}`
|
|
173
|
+
|
|
174
|
+
const SUBAGENTS = {
|
|
175
|
+
"architect": {
|
|
176
|
+
description: "Software architecture specialist for system design",
|
|
177
|
+
mode: "subagent",
|
|
178
|
+
prompt: p("architect.txt"),
|
|
179
|
+
permission: { read: "allow", edit: "deny", bash: "deny" }
|
|
180
|
+
},
|
|
181
|
+
"build-error-resolver": {
|
|
182
|
+
description: "Build and TypeScript error resolution specialist",
|
|
183
|
+
mode: "subagent",
|
|
184
|
+
prompt: p("build-error-resolver.md"),
|
|
185
|
+
permission: { read: "allow", edit: "allow" }
|
|
186
|
+
},
|
|
187
|
+
"code-reviewer": {
|
|
188
|
+
description: "Expert code review specialist",
|
|
189
|
+
mode: "subagent",
|
|
190
|
+
prompt: p("code-reviewer.md"),
|
|
191
|
+
permission: { read: "allow", edit: "deny", bash: "deny", task: { explore: "allow", "*": "deny" } }
|
|
192
|
+
},
|
|
193
|
+
"e2e-runner": {
|
|
194
|
+
description: "End-to-end testing specialist using Playwright",
|
|
195
|
+
mode: "subagent",
|
|
196
|
+
prompt: p("e2e-runner.txt"),
|
|
197
|
+
permission: { read: "allow", edit: "allow" }
|
|
198
|
+
},
|
|
199
|
+
"explore": {
|
|
200
|
+
description: "Fast read-only codebase exploration agent",
|
|
201
|
+
mode: "subagent",
|
|
202
|
+
prompt: p("explore.md"),
|
|
203
|
+
permission: { read: "allow", grep: "allow", glob: "allow", list: "allow", edit: "deny", bash: "deny" }
|
|
204
|
+
},
|
|
205
|
+
"planner": {
|
|
206
|
+
description: "Expert planning specialist for complex features and refactoring",
|
|
207
|
+
mode: "subagent",
|
|
208
|
+
color: "#3B82F6",
|
|
209
|
+
prompt: p("planner.md"),
|
|
210
|
+
permission: { read: "allow", edit: "deny", bash: "deny" }
|
|
211
|
+
},
|
|
212
|
+
"security-reviewer": {
|
|
213
|
+
description: "Security vulnerability detection and remediation specialist",
|
|
214
|
+
mode: "subagent",
|
|
215
|
+
prompt: p("security-reviewer.md"),
|
|
216
|
+
permission: { read: "allow", edit: "deny", bash: "deny", task: { "*": "allow" } }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
for (const [name, def] of Object.entries(SUBAGENTS)) {
|
|
220
|
+
if (!config.agent[name]) config.agent[name] = def
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
config.command = config.command || {}
|
|
224
|
+
const COMMANDS_DIR = path.join(HARNESS_DIR, "commands")
|
|
225
|
+
const ct = (file) => `{file:${path.join(COMMANDS_DIR, file)}}\n\n$ARGUMENTS`
|
|
226
|
+
|
|
227
|
+
const COMMANDS = {
|
|
228
|
+
"build-fix": { agent: "build-error-resolver", description: "Fix build and TypeScript errors", subtask: true, template: ct("build-fix.md") },
|
|
229
|
+
"code-review": { agent: "code-reviewer", description: "Review code for quality, security, and maintainability", subtask: true, template: ct("code-review.md") },
|
|
230
|
+
"plan": { agent: "planner", description: "Create a detailed implementation plan", subtask: true, template: ct("plan.md") },
|
|
231
|
+
"security": { agent: "security-reviewer", description: "Run comprehensive security review", subtask: true, template: ct("security.md") },
|
|
232
|
+
"doctor": { agent: "OpenHermes", description: "Run OpenCode OpenHermes health diagnostics", subtask: true, template: ct("doctor.md") },
|
|
233
|
+
"memory-search": { agent: "OpenHermes", description: "Search OpenHermes memory with LLM summarization", subtask: true, template: ct("memory-search.md") },
|
|
234
|
+
"learn": { agent: "OpenHermes", description: "Create a new skill from recent work patterns", subtask: true, template: ct("learn.md") }
|
|
235
|
+
}
|
|
236
|
+
for (const [name, def] of Object.entries(COMMANDS)) {
|
|
237
|
+
if (!config.command[name]) config.command[name] = def
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
"experimental.chat.messages.transform": async (_input, output) => {
|
|
242
|
+
try {
|
|
243
|
+
const bootstrap = getContent()
|
|
244
|
+
if (!bootstrap || !output.messages || !output.messages.length) return
|
|
245
|
+
const firstUser = output.messages.find(m => m && m.info && m.info.role === "user")
|
|
246
|
+
if (!firstUser || !firstUser.parts || !firstUser.parts.length) return
|
|
247
|
+
if (firstUser.parts.some(p => p.type === "text" && p.text.includes("OPENHERMES_BOOTSTRAP"))) return
|
|
248
|
+
const ref = firstUser.parts[0]
|
|
249
|
+
firstUser.parts.unshift({ ...ref, type: "text", text: bootstrap })
|
|
250
|
+
} catch (err) {
|
|
251
|
+
console.error("[openhermes-bootstrap] transform error:", err.message)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|