openhermes 2.6.1 → 4.0.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.
Files changed (158) hide show
  1. package/CONTEXT.md +18 -0
  2. package/ETHOS.md +15 -0
  3. package/README.md +135 -292
  4. package/bootstrap.mjs +174 -499
  5. package/harness/agents/openhermes.md +87 -0
  6. package/harness/codex/CONSTITUTION.md +70 -148
  7. package/harness/codex/ROUTING.md +126 -0
  8. package/harness/commands/oh-doctor.md +26 -0
  9. package/harness/instructions/CONVENTIONS.md +206 -206
  10. package/harness/instructions/RUNTIME.md +54 -31
  11. package/harness/skills/oh-builder/SKILL.md +98 -0
  12. package/harness/skills/oh-caveman/SKILL.md +33 -0
  13. package/harness/skills/oh-expert/SKILL.md +121 -0
  14. package/harness/skills/oh-freeze/SKILL.md +28 -0
  15. package/harness/skills/oh-gauntlet/SKILL.md +119 -0
  16. package/harness/skills/oh-grill/SKILL.md +77 -0
  17. package/harness/skills/oh-guard/SKILL.md +33 -0
  18. package/harness/skills/oh-handoff/SKILL.md +33 -0
  19. package/harness/skills/oh-health/SKILL.md +90 -0
  20. package/harness/skills/oh-init/SKILL.md +78 -0
  21. package/harness/skills/oh-investigate/SKILL.md +35 -0
  22. package/harness/skills/oh-issue/SKILL.md +36 -0
  23. package/harness/skills/oh-learn/SKILL.md +28 -0
  24. package/harness/skills/oh-manifest/SKILL.md +84 -0
  25. package/harness/skills/oh-plan-review/SKILL.md +128 -0
  26. package/harness/skills/oh-planner/SKILL.md +157 -0
  27. package/harness/skills/oh-prd/SKILL.md +35 -0
  28. package/harness/skills/oh-retro/SKILL.md +33 -0
  29. package/harness/skills/oh-review/SKILL.md +110 -0
  30. package/harness/skills/oh-security/SKILL.md +110 -0
  31. package/harness/skills/oh-ship/SKILL.md +39 -0
  32. package/harness/skills/oh-skill-craft/SKILL.md +107 -0
  33. package/harness/skills/oh-skills-link/SKILL.md +29 -0
  34. package/harness/skills/oh-skills-list/SKILL.md +31 -0
  35. package/harness/skills/oh-triage/SKILL.md +36 -0
  36. package/index.mjs +3 -58
  37. package/lib/harness-resolver.mjs +77 -0
  38. package/lib/logger.mjs +62 -0
  39. package/package.json +49 -53
  40. package/test/plugins-behavioral.test.mjs +64 -0
  41. package/test/plugins.test.mjs +62 -0
  42. package/autorecall.mjs +0 -237
  43. package/curator.mjs +0 -455
  44. package/harness/commands/build-fix.md +0 -60
  45. package/harness/commands/checkpoint.md +0 -68
  46. package/harness/commands/code-review.md +0 -71
  47. package/harness/commands/doctor.md +0 -42
  48. package/harness/commands/eval.md +0 -89
  49. package/harness/commands/go-build.md +0 -87
  50. package/harness/commands/go-review.md +0 -71
  51. package/harness/commands/harness-audit.md +0 -90
  52. package/harness/commands/learn.md +0 -37
  53. package/harness/commands/loop-start.md +0 -38
  54. package/harness/commands/loop-status.md +0 -30
  55. package/harness/commands/memory-search.md +0 -37
  56. package/harness/commands/model-route.md +0 -32
  57. package/harness/commands/ohc.md +0 -13
  58. package/harness/commands/orchestrate.md +0 -88
  59. package/harness/commands/plan.md +0 -53
  60. package/harness/commands/quality-gate.md +0 -35
  61. package/harness/commands/refactor-clean.md +0 -102
  62. package/harness/commands/rust-build.md +0 -78
  63. package/harness/commands/rust-review.md +0 -65
  64. package/harness/commands/security.md +0 -93
  65. package/harness/commands/setup-pm.md +0 -65
  66. package/harness/commands/skill-create.md +0 -99
  67. package/harness/commands/test-coverage.md +0 -80
  68. package/harness/commands/update-codemaps.md +0 -81
  69. package/harness/commands/update-docs.md +0 -67
  70. package/harness/commands/verify.md +0 -68
  71. package/harness/prompts/architect.txt +0 -189
  72. package/harness/prompts/build-cpp.md +0 -98
  73. package/harness/prompts/build-error-resolver.md +0 -44
  74. package/harness/prompts/build-go.md +0 -340
  75. package/harness/prompts/build-java.md +0 -140
  76. package/harness/prompts/build-kotlin.md +0 -137
  77. package/harness/prompts/build-rust.md +0 -108
  78. package/harness/prompts/code-reviewer.md +0 -40
  79. package/harness/prompts/doc-updater.md +0 -206
  80. package/harness/prompts/docs-lookup.md +0 -71
  81. package/harness/prompts/e2e-runner.txt +0 -317
  82. package/harness/prompts/explore.md +0 -42
  83. package/harness/prompts/harness-optimizer.md +0 -42
  84. package/harness/prompts/loop-operator.md +0 -53
  85. package/harness/prompts/planner.md +0 -37
  86. package/harness/prompts/refactor-cleaner.md +0 -256
  87. package/harness/prompts/review-cpp.md +0 -81
  88. package/harness/prompts/review-database.md +0 -261
  89. package/harness/prompts/review-go.md +0 -257
  90. package/harness/prompts/review-java.md +0 -113
  91. package/harness/prompts/review-kotlin.md +0 -143
  92. package/harness/prompts/review-python.md +0 -101
  93. package/harness/prompts/review-rust.md +0 -77
  94. package/harness/prompts/security-reviewer.md +0 -42
  95. package/harness/prompts/tdd-guide.md +0 -228
  96. package/harness/rules/audit.md +0 -84
  97. package/harness/rules/checkpointing.md +0 -75
  98. package/harness/rules/context-loading.md +0 -33
  99. package/harness/rules/credential-exposure.md +0 -0
  100. package/harness/rules/delegation.md +0 -80
  101. package/harness/rules/handoff.md +0 -267
  102. package/harness/rules/memory-management.md +0 -28
  103. package/harness/rules/precedence.md +0 -52
  104. package/harness/rules/promotion.md +0 -46
  105. package/harness/rules/ranking.md +0 -64
  106. package/harness/rules/retrieval.md +0 -94
  107. package/harness/rules/runtime-guards.md +0 -196
  108. package/harness/rules/self-heal.md +0 -79
  109. package/harness/rules/session-start.md +0 -34
  110. package/harness/rules/skills-management.md +0 -165
  111. package/harness/rules/state-drift.md +0 -192
  112. package/harness/rules/verification.md +0 -88
  113. package/harness/scripts/sync-commands.mjs +0 -259
  114. package/harness/skills/.bundled_manifest +0 -17
  115. package/harness/skills/.usage.json +0 -6
  116. package/harness/skills/api-design/SKILL.md +0 -523
  117. package/harness/skills/backend-patterns/SKILL.md +0 -598
  118. package/harness/skills/coding-standards/SKILL.md +0 -549
  119. package/harness/skills/e2e-testing/SKILL.md +0 -326
  120. package/harness/skills/frontend-patterns/SKILL.md +0 -642
  121. package/harness/skills/frontend-slides/SKILL.md +0 -184
  122. package/harness/skills/security-review/SKILL.md +0 -495
  123. package/harness/skills/strategic-compact/SKILL.md +0 -131
  124. package/harness/skills/tdd-workflow/SKILL.md +0 -463
  125. package/harness/skills/verification-loop/SKILL.md +0 -126
  126. package/lib/ambient-memory.mjs +0 -167
  127. package/lib/handoff.mjs +0 -176
  128. package/lib/hardening.mjs +0 -128
  129. package/lib/memory-tools-plugin.mjs +0 -365
  130. package/lib/ohc/block-sync.mjs +0 -69
  131. package/lib/ohc/compress/search.mjs +0 -152
  132. package/lib/ohc/compress/state.mjs +0 -76
  133. package/lib/ohc/config.mjs +0 -186
  134. package/lib/ohc/message-ids.mjs +0 -168
  135. package/lib/ohc/notify.mjs +0 -154
  136. package/lib/ohc/protected-patterns.mjs +0 -54
  137. package/lib/ohc/prune-apply.mjs +0 -134
  138. package/lib/ohc/pruner.mjs +0 -610
  139. package/lib/ohc/reaper.mjs +0 -70
  140. package/lib/ohc/state.mjs +0 -266
  141. package/lib/ohc/strategies/deduplication.mjs +0 -72
  142. package/lib/ohc/strategies/index.mjs +0 -2
  143. package/lib/ohc/strategies/purge-errors.mjs +0 -43
  144. package/lib/ohc/token-utils.mjs +0 -26
  145. package/lib/ohc/updater.mjs +0 -133
  146. package/lib/paths.mjs +0 -50
  147. package/lib/schema-validator.mjs +0 -77
  148. package/lib/search.mjs +0 -48
  149. package/schemas/audit.schema.json +0 -82
  150. package/schemas/backlog.schema.json +0 -63
  151. package/schemas/checkpoint.schema.json +0 -65
  152. package/schemas/constraint.schema.json +0 -62
  153. package/schemas/decision.schema.json +0 -63
  154. package/schemas/instinct.schema.json +0 -63
  155. package/schemas/loop-state.schema.json +0 -33
  156. package/schemas/mistake.schema.json +0 -64
  157. package/schemas/verification_receipt.schema.json +0 -88
  158. package/skill-builder.mjs +0 -88
package/curator.mjs DELETED
@@ -1,455 +0,0 @@
1
- import path from "node:path"
2
- import fs from "node:fs"
3
- import { findUnsupportedSchemaKeywords, validateSchema } from "./lib/schema-validator.mjs"
4
- import { atomicWriteJson, buildEnvironmentFingerprint, fingerprintFile, readJson, redactSensitiveText, sanitizeRecord, truncateText } from "./lib/hardening.mjs"
5
- import { fileURLToPath } from "node:url"
6
- import { dirname } from "node:path"
7
- import { getDataRoot, getMemoryRoot } from "./lib/paths.mjs"
8
-
9
- const __dirname = dirname(fileURLToPath(import.meta.url))
10
-
11
- const CHECKPOINT_DEBOUNCE_MS = 300000
12
- const COMPACTION_CONTEXT_LIMIT = 12000
13
- const lastCheckpoint = { ts: 0 }
14
- const writtenThisSession = []
15
- const CURATOR_LOGS = /^(1|true|yes)$/i.test(process.env.OPENCODE_CURATOR_LOGS || "")
16
-
17
- function curatorLog(message) {
18
- if (!CURATOR_LOGS) return
19
- process.stderr.write(`${message}\n`)
20
- }
21
-
22
- function isMeaningfulText(value) {
23
- return typeof value === "string" && value.trim().length > 0 && !/^(n\/a|none|tbd|placeholder|pending|session in progress|no active checkpoint content)$/i.test(value.trim())
24
- }
25
-
26
- function safeLogMessage(message, limit = 160) {
27
- return truncateText(redactSensitiveText(message || ""), limit)
28
- }
29
-
30
- function indexEntry(root, plural, record) {
31
- const indexPath = path.join(root, "memory", plural, "index.json")
32
- let index = readJson(indexPath, [])
33
- if (!Array.isArray(index)) index = []
34
- const entry = {
35
- id: record.id,
36
- summary: record.summary,
37
- status: record.status,
38
- updated_at: record.updated_at || record.created_at,
39
- path: `openhermes/memory/${plural}/${record.id}.json`
40
- }
41
- const existing = index.findIndex(e => e.id === record.id)
42
- if (existing >= 0) index[existing] = entry
43
- else index.push(entry)
44
- atomicWriteJson(indexPath, index)
45
- }
46
-
47
- function updateLoopState(root, patch) {
48
- const statePath = path.join(root, "runtime", "loop-state.json")
49
- const state = readJson(statePath, null) || {}
50
- const next = {
51
- ...state,
52
- ...patch,
53
- updated_at: patch.updated_at || new Date().toISOString(),
54
- }
55
- const schema = loadSchema("loop-state")
56
- if (!schema) return false
57
- const unsupported = findUnsupportedSchemaKeywords(schema)
58
- if (unsupported.length) return false
59
- const errors = validateSchema(schema, next, "$")
60
- if (errors.length) return false
61
- atomicWriteJson(statePath, next)
62
- return true
63
- }
64
-
65
- function loadSchema(classId) {
66
- const fp = path.join(__dirname, "schemas", `${classId}.schema.json`)
67
- try { return JSON.parse(fs.readFileSync(fp, "utf8")) } catch { return null }
68
- }
69
-
70
- function validateRecordAgainstSchema(record) {
71
- const schema = loadSchema(record.class)
72
- if (!schema) {
73
- curatorLog(`[curator] no schema found for class "${record.class}", fallback check`)
74
- const required = record.class === "checkpoint"
75
- ? ["id", "class", "summary", "mission", "current_state", "next_actions", "blockers", "risk_notes", "provenance", "created_at", "status"]
76
- : ["id", "class", "summary", "provenance", "created_at", "status"]
77
- const missing = required.filter(r => !record[r] && record[r] !== null)
78
- if (missing.length) {
79
- curatorLog(`[curator] validation failed: missing ${missing.join(", ")}`)
80
- return false
81
- }
82
- if (record.class === "checkpoint" && record.provenance && !record.provenance.session_id) {
83
- curatorLog(`[curator] validation failed: provenance.session_id required`)
84
- return false
85
- }
86
- return true
87
- }
88
- const unsupported = findUnsupportedSchemaKeywords(schema)
89
- if (unsupported.length) {
90
- curatorLog(`[curator] schema validation failed: unsupported keywords ${unsupported.join(", ")}`)
91
- return false
92
- }
93
- const errors = validateSchema(schema, record, "$")
94
- if (errors.length) {
95
- curatorLog(`[curator] schema validation failed: ${errors.join("; ")}`)
96
- return false
97
- }
98
- if (record.class === "checkpoint") {
99
- const requiredText = [record.mission, record.current_state]
100
- if (!requiredText.every(isMeaningfulText)) return false
101
- if (!Array.isArray(record.next_actions) || record.next_actions.length === 0) return false
102
- if (!Array.isArray(record.blockers) || record.blockers.length === 0) return false
103
- if (!Array.isArray(record.risk_notes) || record.risk_notes.length === 0) return false
104
- }
105
- return true
106
- }
107
-
108
- async function writeCheckpoint(root, project, directory, trigger, summary, options = {}) {
109
- const now = Date.now()
110
- if (!options.force && now - lastCheckpoint.ts < CHECKPOINT_DEBOUNCE_MS) return null
111
- lastCheckpoint.ts = now
112
-
113
- const ts = new Date().toISOString()
114
- const id = `chk_${ts.replace(/[:.]/g, "-")}`
115
- const environmentFingerprint = buildEnvironmentFingerprint(root, directory, project)
116
- const isCompaction = trigger === "experimental.session.compacting"
117
- const record = {
118
- id,
119
- class: "checkpoint",
120
- scope: "session",
121
- summary: summary || (isCompaction ? `Pre-compaction checkpoint for ${project?.name || path.basename(directory)}` : `Idle checkpoint for ${project?.name || path.basename(directory)}`),
122
- mission: isCompaction
123
- ? "Preserve the current OpenHermes runtime state before compaction trims working context."
124
- : "Preserve the current OpenHermes session state so the next turn can resume safely.",
125
- current_state: isCompaction
126
- ? "A compaction run is starting; runtime memory, recall freshness, and loop-state validation are being hardened before context is reduced."
127
- : "The session is idle and the curator is maintaining durable state, schema validation, and memory hygiene for the next turn.",
128
- next_actions: isCompaction
129
- ? [
130
- "Verify the pre-compaction checkpoint was written and indexed.",
131
- "Inject only fresh recall context into the compaction buffer.",
132
- "Confirm loop-state writes remain schema-valid after compaction.",
133
- ]
134
- : [
135
- "Keep loop-state and memory writes atomic.",
136
- "Redact sensitive text before persisting new records.",
137
- "Recheck stale recall cache handling on the next compaction pass.",
138
- ],
139
- blockers: [
140
- "No blocking runtime failure is present; this checkpoint captures a safe handoff state.",
141
- ],
142
- risk_notes: isCompaction
143
- ? [
144
- "A stale recall cache can reintroduce outdated compaction context if fingerprints drift.",
145
- "Loop-state writes must continue to satisfy the required status, phase, heartbeat_at, and updated_at fields.",
146
- ]
147
- : [
148
- "Placeholder checkpoint content is no longer acceptable for durable handoff.",
149
- "Sensitive text must be redacted before memory persistence.",
150
- ],
151
- provenance: {
152
- session_id: project?.session_id || `session-${Date.now()}`,
153
- harness_root: root,
154
- project_root: directory,
155
- },
156
- description: `Auto-curated checkpoint from curator plugin on ${trigger}`,
157
- source: "agent",
158
- status: "active",
159
- created_at: ts,
160
- updated_at: ts,
161
- project: project?.name || path.basename(directory),
162
- environment_fingerprint: environmentFingerprint,
163
- }
164
- const safeRecord = sanitizeRecord(record, { maxStringLength: 4000 })
165
- if (!validateRecordAgainstSchema(safeRecord)) return null
166
- const dir = path.join(root, "memory", "checkpoints")
167
- fs.mkdirSync(dir, { recursive: true })
168
- atomicWriteJson(path.join(dir, `${id}.json`), safeRecord)
169
- indexEntry(root, "checkpoints", safeRecord)
170
- updateLoopState(root, {
171
- last_checkpoint_id: id,
172
- phase: trigger,
173
- heartbeat_at: ts,
174
- updated_at: ts,
175
- status: trigger === "experimental.session.compacting" ? "active" : "idle",
176
- })
177
- writtenThisSession.push(id)
178
- curatorLog(`[curator] checkpoint written: ${id} (trigger: ${trigger})`)
179
- return id
180
- }
181
-
182
- function writeMistakeRecord(root, project, directory, error) {
183
- const ts = new Date().toISOString()
184
- const errorMsg = typeof error === "object" && error !== null
185
- ? (error.message || JSON.stringify(error).slice(0, 200))
186
- : (error?.toString() || "Unknown error")
187
- const safeErrorMsg = truncateText(redactSensitiveText(errorMsg), 200)
188
- const id = `mist_${ts.replace(/[:.]/g, "-")}`
189
- const environmentFingerprint = buildEnvironmentFingerprint(root, directory, project)
190
- const record = {
191
- id,
192
- class: "mistake",
193
- scope: "harness",
194
- summary: `Session error: ${safeErrorMsg}`,
195
- failure: `Session error: ${safeErrorMsg}`,
196
- root_cause: safeErrorMsg,
197
- provenance: {
198
- session_id: project?.session_id || `session-${Date.now()}`,
199
- harness_root: root,
200
- project_root: directory,
201
- },
202
- source: "agent",
203
- type: "other",
204
- fix: `Auto-generated - investigate via session_id: ${project?.session_id || "unknown"}`,
205
- prevention: "curator.js writeMistakeRecord must validate against mistake.schema.json",
206
- strike: 1,
207
- status: "active",
208
- created_at: ts,
209
- updated_at: ts,
210
- project: project?.name || path.basename(directory),
211
- environment_fingerprint: environmentFingerprint,
212
- }
213
- const dir = path.join(getMemoryRoot(), "mistakes")
214
- fs.mkdirSync(dir, { recursive: true })
215
- const fp = path.join(dir, "mistakes.jsonl")
216
- const safeRecord = sanitizeRecord(record, { maxStringLength: 4000 })
217
- let entries = []
218
- try { entries = fs.readFileSync(fp, "utf8").trim().split("\n").filter(Boolean).map(l => JSON.parse(l)) } catch {}
219
- const idx = entries.findIndex(e => e.id === safeRecord.id)
220
- if (idx >= 0) entries[idx] = safeRecord; else entries.push(safeRecord)
221
- const text = entries.map(e => JSON.stringify(e)).join("\n")
222
- fs.writeFileSync(fp, text ? text + "\n" : "", "utf8")
223
- curatorLog(`[curator] mistake logged: ${id} - ${safeLogMessage(errorMsg, 80)}`)
224
- return id
225
- }
226
-
227
- function writeVerificationReceipt(root, project, directory, checkpointId) {
228
- const ts = new Date().toISOString()
229
- const id = `vr_${ts.replace(/[:.]/g, "-")}`
230
- const artifactPath = path.join(root, "memory", "checkpoints", `${checkpointId}.json`)
231
- const environmentFingerprint = buildEnvironmentFingerprint(root, directory, project)
232
- const record = {
233
- id,
234
- class: "verification_receipt",
235
- scope: "session",
236
- summary: `Auto-verification receipt for checkpoint ${checkpointId}`,
237
- artifact: `openhermes/memory/checkpoints/${checkpointId}.json`,
238
- artifact_type: "file",
239
- fingerprint: fingerprintFile(artifactPath) || { path: `openhermes/memory/checkpoints/${checkpointId}.json` },
240
- environment: {
241
- cwd: directory,
242
- os: "win32",
243
- shell: "cmd.exe",
244
- provider: "lmstudio"
245
- },
246
- method: "manual-inspection",
247
- command: `curator.js auto-verification on session.idle`,
248
- result: "pass",
249
- result_detail: `Checkpoint ${checkpointId} written and indexed. Session completed successfully.`,
250
- provenance: {
251
- session_id: project?.session_id || `session-${Date.now()}`,
252
- harness_root: root,
253
- project_root: directory,
254
- },
255
- confidence: 0.8,
256
- source: "agent",
257
- status: "active",
258
- created_at: ts,
259
- updated_at: ts,
260
- project: project?.name || path.basename(directory),
261
- environment_fingerprint: environmentFingerprint,
262
- }
263
- const dir = path.join(root, "memory", "verification_receipts")
264
- fs.mkdirSync(dir, { recursive: true })
265
- const safeRecord = sanitizeRecord(record, { maxStringLength: 4000 })
266
- atomicWriteJson(path.join(dir, `${id}.json`), safeRecord)
267
- indexEntry(root, "verification_receipts", safeRecord)
268
- curatorLog(`[curator] verification_receipt written: ${id}`)
269
- return id
270
- }
271
-
272
- async function handleSessionIdle(directory, project) {
273
- try {
274
- const root = getDataRoot()
275
- const checkpointId = await writeCheckpoint(root, project, directory, "session.idle", null)
276
- if (checkpointId) {
277
- writeVerificationReceipt(root, project, directory, checkpointId)
278
- }
279
- } catch (err) {
280
- curatorLog(`[curator] handleSessionIdle error: ${safeLogMessage(err.message)}`)
281
- }
282
- }
283
-
284
- async function handleSessionCompacted(directory, project) {
285
- try {
286
- const root = getDataRoot()
287
- const ts = new Date().toISOString()
288
- updateLoopState(root, {
289
- status: "compacted",
290
- last_gate_result: "compaction completed",
291
- phase: "session.compacted",
292
- heartbeat_at: ts,
293
- updated_at: ts,
294
- })
295
- } catch (err) {
296
- curatorLog(`[curator] handleSessionCompacted error: ${safeLogMessage(err.message)}`)
297
- }
298
- }
299
-
300
- async function handleSessionError(directory, project, event) {
301
- try {
302
- const root = getDataRoot()
303
- const ts = new Date().toISOString()
304
- const errorMsg = typeof event?.error === "object" && event.error !== null
305
- ? (event.error.message || JSON.stringify(event.error).slice(0, 200))
306
- : (event?.error?.toString() || event?.message || "Unknown error")
307
- const safeErrorMsg = safeLogMessage(errorMsg, 200)
308
- updateLoopState(root, {
309
- status: "error",
310
- phase: "session.error",
311
- last_error: safeErrorMsg,
312
- heartbeat_at: ts,
313
- updated_at: ts,
314
- })
315
- writeMistakeRecord(root, project, directory, event.error || event)
316
- } catch (err) {
317
- curatorLog(`[curator] handleSessionError error: ${safeLogMessage(err.message)}`)
318
- }
319
- }
320
-
321
- async function handlePermissionReplied(directory, project, event) {
322
- try {
323
- const root = getDataRoot()
324
- const ts = new Date().toISOString()
325
- const id = `audit_perm_${ts.replace(/[:.]/g, "-")}`
326
- const environmentFingerprint = buildEnvironmentFingerprint(root, directory, project)
327
- const record = {
328
- id,
329
- class: "audit",
330
- scope: "harness",
331
- summary: `Permission reply: ${event.action || "?"} for ${event.tool || "?"}`,
332
- target: event.tool || "unknown",
333
- description: `Permission decision: ${event.action || "?"} - tool: ${event.tool || "?"}, pattern: ${event.pattern || "?"}`,
334
- overall_score: 0,
335
- checks: [
336
- {
337
- name: "permission decision audit",
338
- status: "pass",
339
- details: `Permission ${event.action || "?"} logged for tool ${event.tool || "?"}`,
340
- },
341
- ],
342
- top_actions: [
343
- "Auto-recorded permission event — no manual remediation needed.",
344
- ],
345
- integrity: {
346
- refs_ok: true,
347
- provenance_ok: true,
348
- duplicates_ok: true,
349
- },
350
- provenance: {
351
- session_id: project?.session_id || `session-${Date.now()}`,
352
- harness_root: root,
353
- project_root: directory,
354
- },
355
- source: "agent",
356
- status: "closed",
357
- created_at: ts,
358
- updated_at: ts,
359
- project: project?.name || path.basename(directory),
360
- environment_fingerprint: environmentFingerprint,
361
- }
362
- const safeRecord = sanitizeRecord(record, { maxStringLength: 4000 })
363
- const auditSchema = loadSchema("audit")
364
- if (auditSchema) {
365
- const unsupported = findUnsupportedSchemaKeywords(auditSchema)
366
- if (!unsupported.length) {
367
- const errors = validateSchema(auditSchema, safeRecord, "$")
368
- if (errors.length) return
369
- }
370
- }
371
- const dir = path.join(root, "memory", "audits")
372
- fs.mkdirSync(dir, { recursive: true })
373
- atomicWriteJson(path.join(dir, `${id}.json`), safeRecord)
374
- indexEntry(root, "audits", safeRecord)
375
- curatorLog(`[curator] permission audit logged: ${event.tool} -> ${event.action}`)
376
- } catch (err) {
377
- curatorLog(`[curator] handlePermissionReplied error: ${safeLogMessage(err.message)}`)
378
- }
379
- }
380
-
381
- export const CuratorPlugin = async ({ project, directory }) => {
382
- return {
383
- event: async ({ event }) => {
384
- // A1: v1 migration owned by autorecall.mjs — removed to avoid race
385
- if (event.type === "session.created") {
386
- lastCheckpoint.ts = 0
387
- writtenThisSession.length = 0
388
- }
389
- if (event.type === "session.idle") {
390
- await handleSessionIdle(directory, project)
391
- } else if (event.type === "session.compacted") {
392
- await handleSessionCompacted(directory, project)
393
- } else if (event.type === "session.error") {
394
- await handleSessionError(directory, project, event)
395
- } else if (event.type === "permission.replied") {
396
- await handlePermissionReplied(directory, project, event)
397
- } else if (event.type === "command.executed") {
398
- curatorLog(`[curator] command executed: ${event.command || "?"}`)
399
- }
400
- },
401
- "experimental.session.compacting": async (input, output) => {
402
- try {
403
- const root = getDataRoot()
404
- const projectKey = project?.name || path.basename(directory)
405
- const checkpointIndex = readJson(path.join(root, "memory", "checkpoints", "index.json"), [])
406
- const constraintsIndex = readJson(path.join(root, "memory", "constraints", "index.json"), [])
407
- const environmentFingerprint = buildEnvironmentFingerprint(root, directory, project)
408
- const preCompactionCheckpointId = await writeCheckpoint(root, project, directory, "experimental.session.compacting", `Pre-compaction checkpoint for ${projectKey}`, { force: true })
409
-
410
- const latestCheckpoint = Array.isArray(checkpointIndex) && checkpointIndex.length > 0
411
- ? checkpointIndex.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))[0]
412
- : null
413
-
414
- const activeConstraints = Array.isArray(constraintsIndex)
415
- ? constraintsIndex.filter(c => c.status === "active")
416
- : []
417
-
418
- const inject = [
419
- `## OpenHermes State`,
420
- `- Project: ${projectKey}`,
421
- `- Latest checkpoint: ${latestCheckpoint ? latestCheckpoint.summary : "none"}`,
422
- preCompactionCheckpointId ? `- Pre-compaction checkpoint: ${preCompactionCheckpointId}` : null,
423
- `- Active constraints: ${activeConstraints.length}`,
424
- `- Memory writes this session: ${writtenThisSession.length}`,
425
- writtenThisSession.length > 0 ? `- Recent writes: ${writtenThisSession.slice(-3).join(", ")}` : null,
426
- `- Session hook: experimental.session.compacting`,
427
- ].filter(Boolean).join("\n")
428
-
429
- const recallCache = readJson(path.join(root, "memory", "recall", "cache.json"), null)
430
- const cacheMatches = recallCache && recallCache.fingerprint && recallCache.fingerprint.sha256 === environmentFingerprint.sha256
431
- const cacheFresh = cacheMatches && recallCache.freshness_marker && recallCache.freshness_marker.updated_at
432
- ? (Date.now() - Date.parse(recallCache.freshness_marker.updated_at) <= (recallCache.freshness_marker.ttl_ms || 0))
433
- : false
434
- const contextSink = Array.isArray(output.context) ? output.context : (output.context = [])
435
- if (recallCache && recallCache.context && cacheFresh) {
436
- const merged = truncateText(`${inject}\n\n${recallCache.context}`, COMPACTION_CONTEXT_LIMIT)
437
- contextSink.push(merged)
438
- curatorLog(`[curator] compaction injected harness state + autorecall (${merged.length} chars)`)
439
- } else {
440
- contextSink.push(truncateText(inject, COMPACTION_CONTEXT_LIMIT))
441
- curatorLog(`[curator] compaction injected harness state (stale or missing autorecall cache)`)
442
- }
443
- updateLoopState(root, {
444
- phase: "compress",
445
- heartbeat_at: new Date().toISOString(),
446
- status: "active",
447
- })
448
- } catch (err) {
449
- curatorLog(`[curator] compaction error: ${safeLogMessage(err.message)}`)
450
- const contextSink = Array.isArray(output.context) ? output.context : (output.context = [])
451
- contextSink.push(truncateText(`## OpenHermes State\n- Project: ${project?.name || path.basename(directory)}\n- Hook: experimental.session.compacting (error state)\n`, COMPACTION_CONTEXT_LIMIT))
452
- }
453
- },
454
- }
455
- }
@@ -1,60 +0,0 @@
1
- ---
2
- description: Fix build and TypeScript errors with minimal changes
3
- agent: build-error-resolver
4
- subtask: true
5
- ---
6
-
7
- # Build Fix Command
8
-
9
- Fix build and TypeScript errors with minimal changes: $ARGUMENTS
10
-
11
- ## Current type errors
12
-
13
- !npx tsc --noEmit 2>&1 || echo "tsc not available or no errors"
14
-
15
- ## Your Task
16
-
17
- 1. **Run type check**: `npx tsc --noEmit`
18
- 2. **Collect all errors**
19
- 3. **Fix errors one by one** with minimal changes
20
- 4. **Verify each fix** doesn't introduce new errors
21
- 5. **Run final check** to confirm all errors resolved
22
-
23
- ## Approach
24
-
25
- ### DO:
26
- - PASS: Fix type errors with correct types
27
- - PASS: Add missing imports
28
- - PASS: Fix syntax errors
29
- - PASS: Make minimal changes
30
- - PASS: Preserve existing behavior
31
- - PASS: Run `tsc --noEmit` after each change
32
-
33
- ### DON'T:
34
- - FAIL: Refactor code
35
- - FAIL: Add new features
36
- - FAIL: Change architecture
37
- - FAIL: Use `any` type (unless absolutely necessary)
38
- - FAIL: Add `@ts-ignore` comments
39
- - FAIL: Change business logic
40
-
41
- ## Common Error Fixes
42
-
43
- | Error | Fix |
44
- |-------|-----|
45
- | Type 'X' is not assignable to type 'Y' | Add correct type annotation |
46
- | Property 'X' does not exist | Add property to interface or fix property name |
47
- | Cannot find module 'X' | Install package or fix import path |
48
- | Argument of type 'X' is not assignable | Cast or fix function signature |
49
- | Object is possibly 'undefined' | Add null check or optional chaining |
50
-
51
- ## Verification Steps
52
-
53
- After fixes:
54
- 1. `npx tsc --noEmit` - should show 0 errors
55
- 2. `npm run build` - should succeed
56
- 3. `npm test` - tests should still pass
57
-
58
- ---
59
-
60
- **IMPORTANT**: Focus on fixing errors only. No refactoring, no improvements, no architectural changes. Get the build green with minimal diff.
@@ -1,68 +0,0 @@
1
- ---
2
- description: Save verification state and progress checkpoint
3
- agent: OpenHermes
4
- subtask: true
5
- ---
6
-
7
- # Checkpoint Command
8
-
9
- Save current verification state and create progress checkpoint: $ARGUMENTS
10
-
11
- ## Your Task
12
-
13
- Create a snapshot of current progress including:
14
-
15
- 1. **Tests status** - Which tests pass/fail
16
- 2. **Coverage** - Current coverage metrics
17
- 3. **Build status** - Build succeeds or errors
18
- 4. **Code changes** - Summary of modifications
19
- 5. **Next steps** - What remains to be done
20
-
21
- ## Checkpoint Format
22
-
23
- ### Checkpoint: [Timestamp]
24
-
25
- **Tests**
26
- - Total: X
27
- - Passing: Y
28
- - Failing: Z
29
- - Coverage: XX%
30
-
31
- **Build**
32
- - Status: PASS: Passing / FAIL: Failing
33
- - Errors: [if any]
34
-
35
- **Changes Since Last Checkpoint**
36
- ```
37
- git diff --stat [last-checkpoint-commit]
38
- ```
39
-
40
- **Completed Tasks**
41
- - [x] Task 1
42
- - [x] Task 2
43
- - [ ] Task 3 (in progress)
44
-
45
- **Blocking Issues**
46
- - [Issue description]
47
-
48
- **Next Steps**
49
- 1. Step 1
50
- 2. Step 2
51
-
52
- ## Usage with Verification Loop
53
-
54
- Checkpoints integrate with the verification loop:
55
-
56
- ```
57
- /plan → implement → /checkpoint → /verify → /checkpoint → implement → ...
58
- ```
59
-
60
- Use checkpoints to:
61
- - Save state before risky changes
62
- - Track progress through phases
63
- - Enable rollback if needed
64
- - Document verification points
65
-
66
- ---
67
-
68
- **TIP**: Create checkpoints at natural breakpoints: after each phase, before major refactoring, after fixing critical bugs.
@@ -1,71 +0,0 @@
1
- ---
2
- description: Review code for quality, security, and maintainability
3
- agent: code-reviewer
4
- subtask: true
5
- ---
6
-
7
- # Code Review Command
8
-
9
- Review code changes for quality, security, and maintainability: $ARGUMENTS
10
-
11
- ## Changed files
12
-
13
- !git diff --name-only HEAD 2>&1 || echo "No git repo or no changes"
14
-
15
- ## Your Task
16
-
17
- 1. **Analyze each changed file** for issues
18
- 3. **Generate structured report**
19
- 4. **Provide actionable recommendations**
20
-
21
- ## Check Categories
22
-
23
- ### Security Issues (CRITICAL)
24
- - [ ] Hardcoded credentials, API keys, tokens
25
- - [ ] SQL injection vulnerabilities
26
- - [ ] XSS vulnerabilities
27
- - [ ] Missing input validation
28
- - [ ] Insecure dependencies
29
- - [ ] Path traversal risks
30
- - [ ] Authentication/authorization flaws
31
-
32
- ### Code Quality (HIGH)
33
- - [ ] Functions > 50 lines
34
- - [ ] Files > 800 lines
35
- - [ ] Nesting depth > 4 levels
36
- - [ ] Missing error handling
37
- - [ ] console.log statements
38
- - [ ] TODO/FIXME comments
39
- - [ ] Missing JSDoc for public APIs
40
-
41
- ### Best Practices (MEDIUM)
42
- - [ ] Mutation patterns (use immutable instead)
43
- - [ ] Unnecessary complexity
44
- - [ ] Missing tests for new code
45
- - [ ] Accessibility issues (a11y)
46
- - [ ] Performance concerns
47
-
48
- ### Style (LOW)
49
- - [ ] Inconsistent naming
50
- - [ ] Missing type annotations
51
- - [ ] Formatting issues
52
-
53
- ## Report Format
54
-
55
- For each issue found:
56
-
57
- ```
58
- **[SEVERITY]** file.ts:123
59
- Issue: [Description]
60
- Fix: [How to fix]
61
- ```
62
-
63
- ## Decision
64
-
65
- - **CRITICAL or HIGH issues**: Block commit, require fixes
66
- - **MEDIUM issues**: Recommend fixes before merge
67
- - **LOW issues**: Optional improvements
68
-
69
- ---
70
-
71
- **IMPORTANT**: Never approve code with security vulnerabilities!
@@ -1,42 +0,0 @@
1
- ---
2
- description: Run OpenCode openhermes health diagnostics
3
- agent: OpenHermes
4
- subtask: true
5
- ---
6
-
7
- # Doctor Command
8
-
9
- Run full OpenCode openhermes diagnostics. $ARGUMENTS
10
-
11
- ## Your Task
12
-
13
- 1. Load the opencode-doctor skill: `skill({ name: "opencode-doctor" })`
14
- 2. Follow its instructions to validate:
15
- - Config syntax (opencode.json valid JSON)
16
- - Provider connectivity (LM Studio at http://127.0.0.1:1234/v1)
17
- - Cache state (memory records, recall cache)
18
- - Auth file integrity
19
- 3. Report results with any fix suggestions
20
-
21
- ## Automated Checks
22
-
23
- Run these commands and report results:
24
-
25
- !opencode debug config
26
- !opencode debug info
27
- !opencode debug paths
28
-
29
- ## Report Format
30
-
31
- | Check | Result | Issue |
32
- |-------|--------|-------|
33
- | Config JSON | PASS/FAIL | |
34
- | Provider | PASS/FAIL | |
35
- | Memory MCP | PASS/FAIL | |
36
- | Plugins | PASS/FAIL | |
37
- | Skills | PASS/FAIL | |
38
-
39
- ## After Diagnosis
40
-
41
- If issues found: propose fixes, wait for approval, apply.
42
- If clean: report "OpenHermes: HEALTHY."