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
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import fs from "fs"
|
|
2
|
+
import path from "path"
|
|
3
|
+
import os from "os"
|
|
4
|
+
|
|
5
|
+
const ROOT = path.join(os.homedir(), ".config", "opencode", "openhermes")
|
|
6
|
+
const MEMORY_DIR = path.join(ROOT, "memory")
|
|
7
|
+
|
|
8
|
+
const CLASSES = ["audit", "checkpoint", "mistake", "instinct", "decision", "constraint", "backlog", "verification_receipt"]
|
|
9
|
+
const PLURALS = {
|
|
10
|
+
audit: "audits", checkpoint: "checkpoints", mistake: "mistakes",
|
|
11
|
+
instinct: "instincts", decision: "decisions", constraint: "constraints",
|
|
12
|
+
backlog: "backlog", verification_receipt: "verification_receipts",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isPlainObject(v) { return !!v && typeof v === "object" && !Array.isArray(v) }
|
|
16
|
+
|
|
17
|
+
function stableStringify(v, space = 0) {
|
|
18
|
+
function sort(o) {
|
|
19
|
+
if (Array.isArray(o)) return o.map(sort)
|
|
20
|
+
if (!isPlainObject(o)) return o
|
|
21
|
+
const r = {}
|
|
22
|
+
for (const k of Object.keys(o).sort()) r[k] = sort(o[k])
|
|
23
|
+
return r
|
|
24
|
+
}
|
|
25
|
+
return JSON.stringify(sort(v), null, space)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function classDir(cls) { return path.join(MEMORY_DIR, PLURALS[cls]) }
|
|
29
|
+
|
|
30
|
+
function atomicWriteJson(fp, data) {
|
|
31
|
+
const tmp = fp + ".tmp"
|
|
32
|
+
fs.writeFileSync(tmp, stableStringify(data, 2), "utf8")
|
|
33
|
+
fs.renameSync(tmp, fp)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function readJSON(fp, fallback) {
|
|
37
|
+
try { return JSON.parse(fs.readFileSync(fp, "utf8")) } catch { return fallback }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function readJSONL(fp) {
|
|
41
|
+
try {
|
|
42
|
+
return fs.readFileSync(fp, "utf8").split(/\r?\n/).map(l => l.trim()).filter(Boolean).map(l => JSON.parse(l))
|
|
43
|
+
} catch { return [] }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function buildEntry(cls, r) {
|
|
47
|
+
const e = {
|
|
48
|
+
id: r.id, summary: r.summary, status: r.status,
|
|
49
|
+
updated_at: r.updated_at ?? r.created_at,
|
|
50
|
+
path: path.join("openhermes", "memory", PLURALS[cls], `${r.id}.json`),
|
|
51
|
+
scope: r.scope ?? null, project: r.project ?? null,
|
|
52
|
+
}
|
|
53
|
+
if (cls === "audit") { e.target = r.target; e.overall_score = r.overall_score }
|
|
54
|
+
if (cls === "backlog") { e.priority = r.priority; e.trigger = r.trigger }
|
|
55
|
+
return e
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function hasExpired(r) {
|
|
59
|
+
if (r?.status === "expired" || r?.status === "decayed") return true
|
|
60
|
+
if (r?.decay_at && Date.parse(r.decay_at) < Date.now()) return true
|
|
61
|
+
if (r?.expires_at && Date.parse(r.expires_at) < Date.now()) return true
|
|
62
|
+
return false
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function sortRecent(entries) {
|
|
66
|
+
function ts(e) { return e?.updated_at ?? e?.created_at ?? "" }
|
|
67
|
+
return [...entries].sort((a, b) => {
|
|
68
|
+
const at = Date.parse(ts(a)), bt = Date.parse(ts(b))
|
|
69
|
+
if (!Number.isNaN(at) && !Number.isNaN(bt) && at !== bt) return bt - at
|
|
70
|
+
return String(ts(b)).localeCompare(String(ts(a)))
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function filterActive(entries) { return entries.filter(e => !hasExpired(e)) }
|
|
75
|
+
|
|
76
|
+
function validateSchemaSimple(record) {
|
|
77
|
+
const required = {
|
|
78
|
+
audit: ["id", "class", "summary", "target", "overall_score", "checks"],
|
|
79
|
+
checkpoint: ["id", "class", "summary", "mission", "current_state", "provenance"],
|
|
80
|
+
mistake: ["id", "class", "summary", "failure", "root_cause", "type", "strike"],
|
|
81
|
+
instinct: ["id", "class", "summary", "claim", "provenance"],
|
|
82
|
+
decision: ["id", "class", "summary", "decision", "rationale", "provenance"],
|
|
83
|
+
constraint: ["id", "class", "summary", "constraint", "provenance"],
|
|
84
|
+
backlog: ["id", "class", "summary", "priority"],
|
|
85
|
+
verification_receipt: ["id", "class", "summary", "fingerprint", "method", "result"],
|
|
86
|
+
}
|
|
87
|
+
const cls = record.class
|
|
88
|
+
const reqs = required[cls]
|
|
89
|
+
if (!reqs) return { ok: true }
|
|
90
|
+
const missing = reqs.filter(r => !record[r] && record[r] !== null && record[r] !== undefined)
|
|
91
|
+
if (missing.length) return { ok: false, errors: missing.map(m => `$.${m} is required`) }
|
|
92
|
+
return { ok: true }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function queryList(cls, limit = 10) {
|
|
96
|
+
if (cls === "mistake") {
|
|
97
|
+
return sortRecent(filterActive(readJSONL(path.join(classDir(cls), "mistakes.jsonl")))).slice(0, limit)
|
|
98
|
+
}
|
|
99
|
+
const dir = classDir(cls)
|
|
100
|
+
let files = []
|
|
101
|
+
try { files = fs.readdirSync(dir).filter(f => f.endsWith(".json") && f !== "index.json").map(f => path.join(dir, f)) } catch { return [] }
|
|
102
|
+
const entries = files.map(f => readJSON(f, null)).filter(Boolean).map(r => buildEntry(cls, r))
|
|
103
|
+
return sortRecent(filterActive(entries)).slice(0, limit)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function queryGet(cls, id) {
|
|
107
|
+
if (cls === "mistake") return readJSONL(path.join(classDir(cls), "mistakes.jsonl")).find(e => e?.id === id) ?? null
|
|
108
|
+
return readJSON(path.join(classDir(cls), `${id}.json`), null)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function scoreRelevance(r, query, project) {
|
|
112
|
+
const q = query.toLowerCase()
|
|
113
|
+
let score = 0
|
|
114
|
+
const fields = [r.summary, r.id, r.description, r.mission, r.current_state, r.failure, r.root_cause, r.fix, r.prevention, r.command, r.project, r.scope, ...(Array.isArray(r.tags) ? r.tags : []), ...(Array.isArray(r.next_actions) ? r.next_actions : []), ...(Array.isArray(r.refs) ? r.refs : [])].filter(Boolean)
|
|
115
|
+
for (const f of fields) {
|
|
116
|
+
const str = String(f).toLowerCase()
|
|
117
|
+
let idx = 0; let count = 0
|
|
118
|
+
while ((idx = str.indexOf(q, idx)) !== -1) { count++; idx += q.length }
|
|
119
|
+
score += count * 10
|
|
120
|
+
if (str.startsWith(q)) score += 5
|
|
121
|
+
if (str.includes(q)) score += 2
|
|
122
|
+
}
|
|
123
|
+
if (r.project && r.project.toLowerCase() === (project || "").toLowerCase()) score += 20
|
|
124
|
+
if (r.project && project && r.project.toLowerCase().includes(project.toLowerCase())) score += 10
|
|
125
|
+
const age = Date.now() - Date.parse(r.updated_at || r.created_at || 0)
|
|
126
|
+
if (!Number.isNaN(age)) score += Math.max(0, 10 - age / 604800000)
|
|
127
|
+
if (r.status === "active") score += 3
|
|
128
|
+
if (r.status === "closed") score -= 2
|
|
129
|
+
return score
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function writeObject(cls, record) {
|
|
133
|
+
const dir = classDir(cls)
|
|
134
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
135
|
+
const fp = path.join(dir, `${record.id}.json`)
|
|
136
|
+
atomicWriteJson(fp, record)
|
|
137
|
+
const indexPath = path.join(dir, "index.json")
|
|
138
|
+
let index = readJSON(indexPath, [])
|
|
139
|
+
if (!Array.isArray(index)) index = []
|
|
140
|
+
const idx = index.findIndex(e => e?.id === record.id)
|
|
141
|
+
const entry = buildEntry(cls, record)
|
|
142
|
+
if (idx >= 0) index[idx] = entry; else index.push(entry)
|
|
143
|
+
atomicWriteJson(indexPath, index)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function upsertMistake(record) {
|
|
147
|
+
const dir = classDir("mistake")
|
|
148
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
149
|
+
const fp = path.join(dir, "mistakes.jsonl")
|
|
150
|
+
let entries = readJSONL(fp)
|
|
151
|
+
const idx = entries.findIndex(e => e?.id === record.id)
|
|
152
|
+
if (idx >= 0) entries[idx] = record; else entries.push(record)
|
|
153
|
+
const text = entries.map(e => stableStringify(e)).join("\n")
|
|
154
|
+
fs.writeFileSync(fp, text ? `${text}\n` : "", "utf8")
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function handlePut(cls, id, dataStr) {
|
|
158
|
+
let parsed
|
|
159
|
+
try { parsed = JSON.parse(dataStr) } catch (e) { return `data must be valid JSON: ${e.message}` }
|
|
160
|
+
if (!isPlainObject(parsed)) return "data must be a JSON object"
|
|
161
|
+
if (!id?.trim()) return "non-blank id is required"
|
|
162
|
+
|
|
163
|
+
const now = new Date().toISOString()
|
|
164
|
+
const record = {
|
|
165
|
+
...parsed, id, class: cls,
|
|
166
|
+
source: parsed.source ?? "agent",
|
|
167
|
+
status: parsed.status ?? "active",
|
|
168
|
+
created_at: parsed.created_at ?? now,
|
|
169
|
+
updated_at: now,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const validation = validateSchemaSimple(record)
|
|
173
|
+
if (!validation.ok) return `Validation errors: ${validation.errors.join("; ")}`
|
|
174
|
+
|
|
175
|
+
if (cls === "mistake") upsertMistake(record)
|
|
176
|
+
else writeObject(cls, record)
|
|
177
|
+
|
|
178
|
+
return stableStringify({ ok: true, id })
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function handleGet(cls, id) {
|
|
182
|
+
if (!id?.trim()) return "non-blank id is required"
|
|
183
|
+
const record = queryGet(cls, id.trim())
|
|
184
|
+
if (!record) return stableStringify({ ok: false, found: false })
|
|
185
|
+
return stableStringify({ ok: true, record })
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function handleList(cls, limit = 10) {
|
|
189
|
+
const entries = queryList(cls, Math.min(limit, 100))
|
|
190
|
+
return stableStringify({ ok: true, count: entries.length, entries })
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function handleLatest(cls) {
|
|
194
|
+
const list = queryList(cls, 100)
|
|
195
|
+
const active = filterActive(list)
|
|
196
|
+
if (!active[0]?.id) return stableStringify({ ok: false, found: false })
|
|
197
|
+
const record = queryGet(cls, active[0].id)
|
|
198
|
+
if (!record) return stableStringify({ ok: false, found: false })
|
|
199
|
+
return stableStringify({ ok: true, record })
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function handleSearch(query, scope, classes, project, limit) {
|
|
203
|
+
const q = (query || "").trim()
|
|
204
|
+
if (!q) return "non-blank query is required"
|
|
205
|
+
const clsList = Array.isArray(classes) && classes.length ? classes : CLASSES
|
|
206
|
+
const lim = Math.min(limit ?? 10, 50)
|
|
207
|
+
let records = []
|
|
208
|
+
for (const cls of clsList) {
|
|
209
|
+
if (cls === "mistake") {
|
|
210
|
+
for (const m of readJSONL(path.join(classDir(cls), "mistakes.jsonl"))) {
|
|
211
|
+
if (!hasExpired(m)) records.push(m)
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
const dir = classDir(cls)
|
|
215
|
+
let files = []
|
|
216
|
+
try { files = fs.readdirSync(dir).filter(f => f.endsWith(".json") && f !== "index.json") } catch { continue }
|
|
217
|
+
for (const f of files) {
|
|
218
|
+
const r = readJSON(path.join(dir, f), null)
|
|
219
|
+
if (r && !hasExpired(r)) records.push(r)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (scope === "global") records = records.filter(r => r.scope === "global" || !r.scope)
|
|
224
|
+
else if (scope === "local") records = records.filter(r => r.scope === "project" || r.scope === "session")
|
|
225
|
+
const scored = records.map(r => ({ ...buildEntry(r.class || "verification_receipt", r), score: scoreRelevance(r, q, project || "") }))
|
|
226
|
+
.filter(e => e.score > 0)
|
|
227
|
+
.sort((a, b) => b.score - a.score)
|
|
228
|
+
.slice(0, lim)
|
|
229
|
+
return stableStringify({ ok: true, count: scored.length, query: q, results: scored })
|
|
230
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin"
|
|
2
|
+
import { handleGet } from "./_memory.mjs"
|
|
3
|
+
|
|
4
|
+
export default tool({
|
|
5
|
+
description: "Get a specific OpenHermes memory record by class and ID",
|
|
6
|
+
args: {
|
|
7
|
+
class: tool.schema.enum(["audit", "checkpoint", "mistake", "instinct", "decision", "constraint", "backlog", "verification_receipt"]).describe("Memory class"),
|
|
8
|
+
id: tool.schema.string().describe("Record ID to retrieve"),
|
|
9
|
+
},
|
|
10
|
+
async execute(args) {
|
|
11
|
+
return handleGet(args.class, args.id)
|
|
12
|
+
},
|
|
13
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin"
|
|
2
|
+
import { handleLatest } from "./_memory.mjs"
|
|
3
|
+
|
|
4
|
+
export default tool({
|
|
5
|
+
description: "Get the latest active OpenHermes memory record by class (returns the full record, not just metadata)",
|
|
6
|
+
args: {
|
|
7
|
+
class: tool.schema.enum(["audit", "checkpoint", "mistake", "instinct", "decision", "constraint", "backlog", "verification_receipt"]).describe("Memory class to get the latest from"),
|
|
8
|
+
},
|
|
9
|
+
async execute(args) {
|
|
10
|
+
return handleLatest(args.class)
|
|
11
|
+
},
|
|
12
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin"
|
|
2
|
+
import { handleList } from "./_memory.mjs"
|
|
3
|
+
|
|
4
|
+
export default tool({
|
|
5
|
+
description: "List OpenHermes memory records by class, sorted by recency (newest first)",
|
|
6
|
+
args: {
|
|
7
|
+
class: tool.schema.enum(["audit", "checkpoint", "mistake", "instinct", "decision", "constraint", "backlog", "verification_receipt"]).describe("Memory class to list"),
|
|
8
|
+
limit: tool.schema.number().optional().default(10).describe("Max results (max 100)"),
|
|
9
|
+
},
|
|
10
|
+
async execute(args) {
|
|
11
|
+
return handleList(args.class, args.limit)
|
|
12
|
+
},
|
|
13
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin"
|
|
2
|
+
import { handlePut } from "./_memory.mjs"
|
|
3
|
+
|
|
4
|
+
export default tool({
|
|
5
|
+
description: "Create or update an OpenHermes memory record (checkpoints, mistakes, decisions, constraints, instincts, audits, backlog items, verification receipts)",
|
|
6
|
+
args: {
|
|
7
|
+
class: tool.schema.enum(["audit", "checkpoint", "mistake", "instinct", "decision", "constraint", "backlog", "verification_receipt"]).describe("Memory class to write to"),
|
|
8
|
+
id: tool.schema.string().describe("Unique record ID (e.g. 'chk_2026-01-01T00-00-00-000Z')"),
|
|
9
|
+
data: tool.schema.string().describe("JSON string of the record fields (summary, scope, provenance, etc.)"),
|
|
10
|
+
},
|
|
11
|
+
async execute(args) {
|
|
12
|
+
return handlePut(args.class, args.id, args.data)
|
|
13
|
+
},
|
|
14
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin"
|
|
2
|
+
import { handleSearch } from "./_memory.mjs"
|
|
3
|
+
|
|
4
|
+
export default tool({
|
|
5
|
+
description: "Search OpenHermes memory records with keyword matching and relevance ranking. Searches across all classes by default.",
|
|
6
|
+
args: {
|
|
7
|
+
query: tool.schema.string().describe("Search query string (matches against summary, id, description, tags, etc.)"),
|
|
8
|
+
scope: tool.schema.enum(["global", "local", "auto"]).optional().default("auto").describe("Search scope: global (only global-scope records), local (only project/session-scope), auto (all)"),
|
|
9
|
+
classes: tool.schema.array(tool.schema.enum(["audit", "checkpoint", "mistake", "instinct", "decision", "constraint", "backlog", "verification_receipt"])).optional().describe("Memory classes to search (default: all)"),
|
|
10
|
+
project: tool.schema.string().optional().describe("Project name filter for boosted relevance scoring"),
|
|
11
|
+
limit: tool.schema.number().optional().default(10).describe("Max results (max 50)"),
|
|
12
|
+
},
|
|
13
|
+
async execute(args) {
|
|
14
|
+
return handleSearch(args.query, args.scope, args.classes, args.project, args.limit)
|
|
15
|
+
},
|
|
16
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openhermes",
|
|
3
|
+
"version": "1.2.2",
|
|
4
|
+
"description": "OpenHermes plugin suite for OpenCode — autonomous checkpointing, native memory tools, subagent routing, slash commands, and skill-candidate detection.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./index.mjs",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@opencode-ai/plugin": "1.14.46"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./index.mjs",
|
|
13
|
+
"./autorecall": "./autorecall.mjs",
|
|
14
|
+
"./curator": "./curator.mjs",
|
|
15
|
+
"./skill-builder": "./skill-builder.mjs",
|
|
16
|
+
"./bootstrap": "./bootstrap.mjs"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"index.mjs",
|
|
20
|
+
"autorecall.mjs",
|
|
21
|
+
"curator.mjs",
|
|
22
|
+
"skill-builder.mjs",
|
|
23
|
+
"bootstrap.mjs",
|
|
24
|
+
"lib/",
|
|
25
|
+
"schemas/",
|
|
26
|
+
"harness/"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "node --test"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"opencode",
|
|
33
|
+
"opencode-plugin",
|
|
34
|
+
"openhermes",
|
|
35
|
+
"checkpoint",
|
|
36
|
+
"curation",
|
|
37
|
+
"memory",
|
|
38
|
+
"skills"
|
|
39
|
+
],
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/nathwn12/openhermes.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/nathwn12/openhermes/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/nathwn12/openhermes#readme",
|
|
48
|
+
"author": "nathwn12"
|
|
49
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Audit",
|
|
4
|
+
"description": "Structured evaluation of openhermes quality, integrity, and drift.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["id", "class", "summary", "target", "overall_score", "checks", "top_actions", "integrity", "provenance", "created_at", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"id": { "type": "string", "description": "Unique identifier, recommended pattern: audit-YYYYMMDD-short-slug" },
|
|
9
|
+
"class": { "type": "string", "const": "audit" },
|
|
10
|
+
"project": { "type": ["string", "null"], "description": "Project identifier; null for openhermes scope" },
|
|
11
|
+
"scope": { "type": "string", "enum": ["project", "global", "session", "harness"], "description": "Scope of applicability" },
|
|
12
|
+
"summary": { "type": "string", "description": "One-line description of audit scope and result" },
|
|
13
|
+
"tags": { "type": "array", "items": { "type": "string" }, "description": "Searchable tags" },
|
|
14
|
+
"source": { "type": "string", "enum": ["user", "agent", "audit", "migration", "repair"], "description": "Origin of this record" },
|
|
15
|
+
"provenance": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["session_id"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"session_id": { "type": "string" },
|
|
20
|
+
"task_id": { "type": "string" },
|
|
21
|
+
"db_refs": { "type": "array", "items": { "type": "string" } },
|
|
22
|
+
"file_refs": { "type": "array", "items": { "type": "string" } },
|
|
23
|
+
"log_refs": { "type": "array", "items": { "type": "string" } }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"created_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
27
|
+
"updated_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
28
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1, "default": 1.0 },
|
|
29
|
+
"signal": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
|
|
30
|
+
"visibility": { "type": "string", "enum": ["implicit", "selective", "explicit"] },
|
|
31
|
+
"status": { "type": "string", "enum": ["active", "superseded", "archived", "closed", "open"] },
|
|
32
|
+
"refs": { "type": "array", "items": { "type": "string" }, "description": "Related object IDs or file paths" },
|
|
33
|
+
"review_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
34
|
+
"decay_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
35
|
+
"archived_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
36
|
+
"target": { "type": "string", "enum": ["harness", "agents", "memory", "refs", "migration"], "description": "What this audit targets" },
|
|
37
|
+
"overall_score": { "type": "number", "minimum": 0, "maximum": 100, "description": "Overall health score (0-100)" },
|
|
38
|
+
"checks": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"items": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"required": ["name", "status"],
|
|
43
|
+
"properties": {
|
|
44
|
+
"name": { "type": "string", "description": "Check name" },
|
|
45
|
+
"status": { "type": "string", "enum": ["pass", "warn", "fail"], "description": "Check result" },
|
|
46
|
+
"details": { "type": "string", "description": "Additional detail" }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"top_actions": { "type": "array", "items": { "type": "string" }, "description": "Highest-priority remediations" },
|
|
51
|
+
"integrity": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"required": ["refs_ok", "provenance_ok", "duplicates_ok"],
|
|
54
|
+
"properties": {
|
|
55
|
+
"refs_ok": { "type": "boolean", "description": "All references resolve" },
|
|
56
|
+
"provenance_ok": { "type": "boolean", "description": "All objects have valid provenance" },
|
|
57
|
+
"duplicates_ok": { "type": "boolean", "description": "No duplicate IDs found" }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Backlog Item",
|
|
4
|
+
"description": "Evidence-backed self-improvement item for openhermes or project maintenance.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["id", "class", "summary", "title", "priority", "trigger", "provenance", "created_at", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"id": { "type": "string", "description": "Unique identifier, recommended pattern: backlog-YYYYMMDD-short-slug" },
|
|
9
|
+
"class": { "type": "string", "const": "backlog" },
|
|
10
|
+
"project": { "type": ["string", "null"], "description": "Project identifier; null for openhermes scope" },
|
|
11
|
+
"scope": { "type": "string", "enum": ["project", "global", "session", "harness"], "description": "Scope of applicability" },
|
|
12
|
+
"summary": { "type": "string", "description": "One-line description of the backlog item" },
|
|
13
|
+
"tags": { "type": "array", "items": { "type": "string" }, "description": "Searchable tags" },
|
|
14
|
+
"source": { "type": "string", "enum": ["user", "agent", "audit", "migration", "repair"], "description": "Origin of this record" },
|
|
15
|
+
"provenance": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["session_id"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"session_id": { "type": "string" },
|
|
20
|
+
"task_id": { "type": "string" },
|
|
21
|
+
"db_refs": { "type": "array", "items": { "type": "string" } },
|
|
22
|
+
"file_refs": { "type": "array", "items": { "type": "string" } },
|
|
23
|
+
"log_refs": { "type": "array", "items": { "type": "string" } }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"created_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
27
|
+
"updated_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
28
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1, "default": 0.8 },
|
|
29
|
+
"signal": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
|
|
30
|
+
"visibility": { "type": "string", "enum": ["implicit", "selective", "explicit"] },
|
|
31
|
+
"status": { "type": "string", "enum": ["active", "superseded", "archived", "closed", "open"] },
|
|
32
|
+
"refs": { "type": "array", "items": { "type": "string" }, "description": "Related object IDs or file paths" },
|
|
33
|
+
"review_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
34
|
+
"decay_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
35
|
+
"archived_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
36
|
+
"title": { "type": "string", "description": "Human-readable title for this backlog item" },
|
|
37
|
+
"priority": { "type": "string", "enum": ["low", "medium", "high", "critical", "P0", "P1", "P2", "P3", "P4"], "description": "Priority level (low/medium/high/critical or P0-P4)" },
|
|
38
|
+
"trigger": { "type": "string", "enum": ["audit", "mistake", "drift", "user", "manual"], "description": "What triggered creation of this item" },
|
|
39
|
+
"evidence_refs": { "type": "array", "items": { "type": "string" }, "description": "References to evidence (audit IDs, mistake IDs, file paths)" },
|
|
40
|
+
"done_when": { "type": "array", "items": { "type": "string" }, "description": "Acceptance criteria — concrete conditions for closure" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Checkpoint",
|
|
4
|
+
"description": "Bridge between volatile working context and durable state. Written before compaction.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["id", "class", "summary", "mission", "current_state", "next_actions", "provenance", "created_at", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"id": { "type": "string", "description": "Unique identifier, recommended pattern: checkpoint-YYYYMMDD-short-slug" },
|
|
9
|
+
"class": { "type": "string", "const": "checkpoint" },
|
|
10
|
+
"project": { "type": ["string", "null"], "description": "Project identifier; null for global/openhermes/session scope" },
|
|
11
|
+
"scope": { "type": "string", "enum": ["project", "global", "session", "harness"], "description": "Scope of applicability" },
|
|
12
|
+
"summary": { "type": "string", "description": "One-line description of checkpoint state" },
|
|
13
|
+
"tags": { "type": "array", "items": { "type": "string" }, "description": "Searchable tags" },
|
|
14
|
+
"source": { "type": "string", "enum": ["user", "agent", "audit", "migration", "repair"], "description": "Origin of this record" },
|
|
15
|
+
"provenance": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["session_id"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"session_id": { "type": "string" },
|
|
20
|
+
"task_id": { "type": "string" },
|
|
21
|
+
"db_refs": { "type": "array", "items": { "type": "string" } },
|
|
22
|
+
"file_refs": { "type": "array", "items": { "type": "string" } },
|
|
23
|
+
"log_refs": { "type": "array", "items": { "type": "string" } }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"created_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
27
|
+
"updated_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
28
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1, "default": 1.0 },
|
|
29
|
+
"signal": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
|
|
30
|
+
"visibility": { "type": "string", "enum": ["implicit", "selective", "explicit"] },
|
|
31
|
+
"status": { "type": "string", "enum": ["active", "superseded", "archived", "closed", "open"] },
|
|
32
|
+
"refs": { "type": "array", "items": { "type": "string" }, "description": "Related object IDs or file paths" },
|
|
33
|
+
"review_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
34
|
+
"decay_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
35
|
+
"archived_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
36
|
+
"mission": { "type": "string", "description": "Current task or goal" },
|
|
37
|
+
"current_state": { "type": "string", "description": "What has been done so far" },
|
|
38
|
+
"active_decisions": { "type": "array", "items": { "type": "string" }, "description": "Decision IDs currently shaping behavior" },
|
|
39
|
+
"active_constraints": { "type": "array", "items": { "type": "string" }, "description": "Constraint IDs currently enforced" },
|
|
40
|
+
"blockers": { "type": "array", "items": { "type": "string" }, "description": "What is preventing progress" },
|
|
41
|
+
"next_actions": { "type": "array", "items": { "type": "string" }, "description": "Concrete next steps" },
|
|
42
|
+
"risk_notes": { "type": "array", "items": { "type": "string" }, "description": "Open questions, untested assumptions, fragile state" }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Constraint",
|
|
4
|
+
"description": "Hard limits, environment realities, user boundaries, safety rules, tool boundaries.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["id", "class", "summary", "rule", "enforcement", "source_kind", "active", "provenance", "created_at", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"id": { "type": "string", "description": "Unique identifier, recommended pattern: constraint-YYYYMMDD-short-slug" },
|
|
9
|
+
"class": { "type": "string", "const": "constraint" },
|
|
10
|
+
"project": { "type": ["string", "null"], "description": "Project identifier; null for global/openhermes/session scope" },
|
|
11
|
+
"scope": { "type": "string", "enum": ["project", "global", "session", "harness"], "description": "Scope of applicability" },
|
|
12
|
+
"summary": { "type": "string", "description": "One-line description of the constraint" },
|
|
13
|
+
"tags": { "type": "array", "items": { "type": "string" }, "description": "Searchable tags" },
|
|
14
|
+
"source": { "type": "string", "enum": ["user", "agent", "audit", "migration", "repair"], "description": "Origin of this record" },
|
|
15
|
+
"provenance": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["session_id"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"session_id": { "type": "string" },
|
|
20
|
+
"task_id": { "type": "string" },
|
|
21
|
+
"db_refs": { "type": "array", "items": { "type": "string" } },
|
|
22
|
+
"file_refs": { "type": "array", "items": { "type": "string" } },
|
|
23
|
+
"log_refs": { "type": "array", "items": { "type": "string" } }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"created_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
27
|
+
"updated_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
28
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1, "default": 1.0 },
|
|
29
|
+
"signal": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
|
|
30
|
+
"visibility": { "type": "string", "enum": ["implicit", "selective", "explicit"] },
|
|
31
|
+
"status": { "type": "string", "enum": ["active", "superseded", "archived", "closed", "open"] },
|
|
32
|
+
"refs": { "type": "array", "items": { "type": "string" }, "description": "Related object IDs or file paths" },
|
|
33
|
+
"review_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
34
|
+
"decay_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
35
|
+
"archived_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
36
|
+
"rule": { "type": "string", "description": "The constraint rule text" },
|
|
37
|
+
"enforcement": { "type": "string", "enum": ["hard", "soft"], "description": "Whether violations are blocked (hard) or warned (soft)" },
|
|
38
|
+
"source_kind": { "type": "string", "enum": ["user", "runtime", "safety", "tool", "policy"], "description": "What kind of source produced this constraint" },
|
|
39
|
+
"active": { "type": "boolean", "description": "Whether this constraint is currently enforced" }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Decision",
|
|
4
|
+
"description": "Durable user or openhermes choices that shape future behavior.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["id", "class", "summary", "context", "choice", "reason", "consequences", "provenance", "created_at", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"id": { "type": "string", "description": "Unique identifier, recommended pattern: decision-YYYYMMDD-short-slug" },
|
|
9
|
+
"class": { "type": "string", "const": "decision" },
|
|
10
|
+
"project": { "type": ["string", "null"], "description": "Project identifier; null for global/openhermes/session scope" },
|
|
11
|
+
"scope": { "type": "string", "enum": ["project", "global", "session", "harness"], "description": "Scope of applicability" },
|
|
12
|
+
"summary": { "type": "string", "description": "One-line description of the decision" },
|
|
13
|
+
"tags": { "type": "array", "items": { "type": "string" }, "description": "Searchable tags" },
|
|
14
|
+
"source": { "type": "string", "enum": ["user", "agent", "audit", "migration", "repair"], "description": "Origin of this record" },
|
|
15
|
+
"provenance": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["session_id"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"session_id": { "type": "string" },
|
|
20
|
+
"task_id": { "type": "string" },
|
|
21
|
+
"db_refs": { "type": "array", "items": { "type": "string" } },
|
|
22
|
+
"file_refs": { "type": "array", "items": { "type": "string" } },
|
|
23
|
+
"log_refs": { "type": "array", "items": { "type": "string" } }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"created_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
27
|
+
"updated_at": { "type": "string", "format": "date-time", "description": "ISO-8601 timestamp" },
|
|
28
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1, "default": 1.0 },
|
|
29
|
+
"signal": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
|
|
30
|
+
"visibility": { "type": "string", "enum": ["implicit", "selective", "explicit"] },
|
|
31
|
+
"status": { "type": "string", "enum": ["active", "superseded", "archived", "closed", "open"] },
|
|
32
|
+
"refs": { "type": "array", "items": { "type": "string" }, "description": "Related object IDs or file paths" },
|
|
33
|
+
"review_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
34
|
+
"decay_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
35
|
+
"archived_at": { "type": ["string", "null"], "format": "date-time", "description": "ISO-8601 or null" },
|
|
36
|
+
"context": { "type": "string", "description": "Full context in which the decision was made" },
|
|
37
|
+
"choice": { "type": "string", "description": "The specific choice made" },
|
|
38
|
+
"reason": { "type": "string", "description": "Rationale for the choice" },
|
|
39
|
+
"consequences": { "type": "array", "items": { "type": "string" }, "description": "Expected or observed consequences" },
|
|
40
|
+
"supersedes": { "type": "array", "items": { "type": "string" }, "description": "Decision IDs this decision supersedes" }
|
|
41
|
+
}
|
|
42
|
+
}
|