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
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: oh-security
3
+ description: "Security audit: secrets archaeology, dependency supply chain, CI/CD security, OWASP Top 10, STRIDE threat modeling, LLM security. Two modes: daily (8/10 confidence gate) and comprehensive (2/10 bar)."
4
+ tier: 3
5
+ benefits-from: [oh-expert]
6
+ triggers:
7
+ - "security audit"
8
+ - "threat model"
9
+ - "check for vulnerabilities"
10
+ - "owasp review"
11
+ - "pentest"
12
+ - "security review"
13
+ - "cso"
14
+ ---
15
+
16
+ # oh-security
17
+
18
+ Security audit that finds the doors that are actually unlocked. Two modes: **daily** (8/10 confidence gate — low noise, high signal) and **comprehensive** (2/10 bar — casts a wider net, more findings). Output is a Security Posture Report with severity ratings and remediation plans. Does NOT make code changes — diagnosis only.
19
+
20
+ ## Mode Selection
21
+
22
+ - **Daily** (default) — 8/10 confidence gate. Only flag findings with strong evidence. Skips speculative or trace-only checks. Runs all phases but reports only clear findings.
23
+ - **Comprehensive** (`--comprehensive`) — 2/10 bar. Surfaces more. Includes trace-only flags, speculative dependency issues, and historical pattern matching.
24
+
25
+ ## Phases
26
+
27
+ ### Phase 0: Stack Detection + Architecture Mental Model
28
+ Detect the project's language stack and framework. Build an explicit mental model: what are the components, trust boundaries, data flows, and attack surface.
29
+
30
+ ### Phase 1: Attack Surface Census
31
+ Map what an attacker sees:
32
+ - Public vs authenticated vs admin endpoints
33
+ - File upload points, external integrations, background jobs
34
+ - WebSocket channels, webhook receivers
35
+ - CI/CD workflows, container configs, IaC, deploy targets
36
+
37
+ ### Phase 2: Secrets Archaeology
38
+ Scan git history for leaked credentials (AWS keys, OpenAI keys, GitHub tokens, Slack tokens, generic secrets). Check `.env` tracking status. Scan CI configs for inline secrets.
39
+
40
+ ### Phase 3: Dependency Supply Chain
41
+ Check beyond `npm audit`: known CVEs in direct deps, install scripts in production deps, lockfile integrity, abandoned packages. Diff-mode limits to changed deps.
42
+
43
+ ### Phase 4: CI/CD Pipeline Security
44
+ Check for unpinned third-party actions, `pull_request_target` misuse, script injection via `${{ github.event.* }}`, secrets exposed as env vars, CODEOWNERS protection on workflow files.
45
+
46
+ ### Phase 5: Infrastructure Shadow Surface
47
+ Dockerfiles (root user, secrets in ARG, missing USER), config files with prod DB URLs, IaC (overly permissive IAM, privileged K8s). Staging configs referencing prod.
48
+
49
+ ### Phase 6: Webhook & Integration Audit
50
+ Webhook endpoints without signature verification, TLS verification disabled in prod, overly broad OAuth scopes.
51
+
52
+ ### Phase 7: LLM & AI Security
53
+ Prompt injection vectors (user input flowing into system prompts), unsanitized LLM output rendered in UI, tool/function calling without validation, hardcoded AI API keys.
54
+
55
+ ### Phase 8: OWASP Top 10 + STRIDE
56
+ Map findings to OWASP Top 10 categories and STRIDE threat model. Identify gaps in coverage across categories.
57
+
58
+ ## Output Format
59
+
60
+ ```
61
+ Security Posture Report
62
+ ══════════════════════
63
+ Project: <name>
64
+ Branch: <branch>
65
+ Mode: daily | comprehensive
66
+ Date: <date>
67
+
68
+ Critical (n):
69
+ - <finding> — <file:line> — <remediation>
70
+
71
+ High (n):
72
+ - <finding> — <file:line> — <remediation>
73
+
74
+ Medium (n):
75
+ - <finding> — <file:line> — <remediation>
76
+
77
+ Low (n):
78
+ - <finding> — <file:line> — <remediation>
79
+
80
+ OWASP Coverage:
81
+ A01:Broken Access Control — n findings
82
+ A02:Cryptographic Failures — n findings
83
+ ...
84
+
85
+ STRIDE:
86
+ Spoofing — n
87
+ Tampering — n
88
+ Repudiation — n
89
+ Info Disclosure — n
90
+ Denial of Service — n
91
+ Elevation of Privilege — n
92
+ ```
93
+
94
+ ## Rules
95
+
96
+ - **Read-only.** No fixes. Diagnosis only, except for auto-fixable low-severity findings when explicitly asked.
97
+ - **Daily mode** gates findings at 8/10 confidence. If you would not stake your reputation on it, skip it in daily mode.
98
+ - **Comprehensive mode** gates at 2/10. Surface everything plausible. The user decides.
99
+ - **No false positives on git history.** Placeholder values ("your_", "changeme") excluded. Rotated secrets still flagged (they were exposed).
100
+ - **Prioritize by blast radius.** Remote code execution > credential exposure > info leak > best-practice gap.
101
+ - **Always distinguish direct vs transitive** dependencies in supply chain findings.
102
+ - **Use Grep/Glob tools** for searches, not bash grep. The bash blocks below show WHAT to search, not HOW.
103
+
104
+ ## Routing
105
+
106
+ | Outcome | Route |
107
+ |---------|-------|
108
+ | pass | → [report findings to user] |
109
+ | fail | → oh-investigate (deepen on findings) |
110
+ | blocker | → surface to user |
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: oh-ship
3
+ description: "Deploy and PR pipeline — test, bump, changelog, PR, deploy, verify"
4
+ ---
5
+
6
+ # oh-ship
7
+
8
+ ## When to Use
9
+ When code is ready to ship. Runs the full release pipeline from test to PR to deploy verification.
10
+
11
+ ## Workflow
12
+ 1. **Pre-flight** — run test suite, lint, typecheck
13
+ 2. **Version bump** — read VERSION file or package.json, bump according to semver
14
+ 3. **Changelog** — generate from commit history since last tag. Polish voice: consistent tense, group by type (features, fixes, breaking)
15
+ 4. **Commit + push** — create release commit with changelog
16
+ 5. **PR** — create GitHub PR with summary, test evidence, deploy plan
17
+ 6. **Merge** — merge PR after CI passes
18
+ 7. **Deploy** — trigger deploy (platform-specific)
19
+ 8. **Verify** — canary check, health endpoints, smoke tests
20
+ 9. **Post-ship docs sync** — read all project docs (README, ARCHITECTURE.md, CONTRIBUTING.md), cross-reference the diff, update to match what shipped:
21
+ - README: new features, changed APIs, updated examples
22
+ - CHANGELOG: verify polish against what actually merged
23
+ - ARCHITECTURE.md / CONTRIBUTING.md: reflect any structural or workflow changes
24
+ - TODOS.md: remove completed items, add any new deferred items discovered during ship
25
+ - VERSION file: bump if not already done
26
+
27
+ ## Anti-patterns
28
+ - Skipping pre-flight checks ("just a quick fix")
29
+ - Bumping version without changelog
30
+ - Deploying without post-deploy verification
31
+ - Not tagging releases
32
+
33
+ ## Routing
34
+
35
+ | Outcome | Route |
36
+ |---------|-------|
37
+ | pass | → oh-retro (post-ship review) |
38
+ | fail | → oh-expert (diagnose deployment failure) |
39
+ | blocker | → surface to user |
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: oh-skill-craft
3
+ description: "Create new agent skills with proper structure, frontmatter, progressive disclosure, and bundled resources. Meta-skill for growing the harness."
4
+ tier: 2
5
+ benefits-from: [oh-expert]
6
+ triggers:
7
+ - "create a skill"
8
+ - "write a skill"
9
+ - "new skill"
10
+ - "skill-craft"
11
+ - "meta-skill"
12
+ - "add a capability"
13
+ ---
14
+
15
+ # oh-skill-craft
16
+
17
+ Create new agent skills for the OpenHermes harness. Skills are the unit of progressive disclosure — loaded on demand, not preloaded.
18
+
19
+ ## Skill Structure
20
+
21
+ ```
22
+ harness/skills/<oh-name>/
23
+ ├── SKILL.md # Main instructions (required)
24
+ ├── REFERENCE.md # Detailed docs (if SKILL.md exceeds 100 lines)
25
+ └── scripts/ # Utility scripts (if deterministic operations needed)
26
+ ```
27
+
28
+ ## SKILL.md Template
29
+
30
+ ```markdown
31
+ ---
32
+ name: oh-<name>
33
+ description: "Brief description. Use when [specific triggers]."
34
+ tier: <2|3|4>
35
+ benefits-from: [<skill-dependencies>]
36
+ triggers:
37
+ - "<trigger phrase>"
38
+ - "<another trigger>"
39
+ ---
40
+
41
+ # oh-<name>
42
+
43
+ <one-paragraph summary>
44
+
45
+ ## When to Use
46
+
47
+ <when to invoke this skill>
48
+
49
+ ## Workflow
50
+
51
+ 1. <step>
52
+ 2. <step>
53
+ 3. <step>
54
+
55
+ ## Anti-patterns
56
+
57
+ - <anti-pattern 1>
58
+ - <anti-pattern 2>
59
+ ```
60
+
61
+ ## Description Requirements
62
+
63
+ The description is the only thing the agent sees when deciding which skill to load. Make it actionable:
64
+
65
+ **Good:** "Create new agent skills with proper structure, frontmrmatter, and bundled resources. Use when user wants to create, write, or build a new skill."
66
+
67
+ **Bad:** "Helps with skills."
68
+
69
+ ## Field Guide
70
+
71
+ | Frontmatter Field | Required | Purpose |
72
+ |---|---|---|
73
+ | `name` | yes | Must match `^[a-z0-9]+(-[a-z0-9]+)*$` and directory name |
74
+ | `description` | yes | Max 200 chars. First sentence = what it does. Second = when to use. |
75
+ | `tier` | no | 2=tool, 3=strategic, 4=autonomous. Controls preamble verbosity. |
76
+ | `benefits-from` | no | Skill dependencies. Listed skills should be loaded first. |
77
+ | `triggers` | no | Natural language patterns that should route to this skill. |
78
+
79
+ ## When to Add Scripts
80
+ - Operation is deterministic (validation, formatting)
81
+ - Same code would be generated repeatedly
82
+ - Errors need explicit handling
83
+
84
+ Scripts save tokens and improve reliability vs generated code.
85
+
86
+ ## When to Split Files
87
+ - SKILL.md exceeds 100 lines
88
+ - Content has distinct domains
89
+ - Advanced features are rarely used (put in REFERENCE.md)
90
+
91
+ ## Review Checklist
92
+
93
+ - [ ] Description includes triggers ("Use when...")
94
+ - [ ] SKILL.md under 100 lines
95
+ - [ ] No time-sensitive info (dates, versions, deprecation warnings)
96
+ - [ ] Consistent oh- prefix and terminology
97
+ - [ ] Concrete examples included
98
+ - [ ] Anti-patterns documented
99
+ - [ ] Tests still pass after adding (`npm test`)
100
+
101
+ ## Routing
102
+
103
+ | Outcome | Route |
104
+ |---------|-------|
105
+ | pass | → oh-skills-link (verify skill discovery) |
106
+ | fail | → oh-expert (diagnose skill creation issues) |
107
+ | blocker | → surface to user |
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: oh-skills-link
3
+ description: "Verify that OpenCode can discover the package-local skills directory"
4
+ ---
5
+
6
+ # oh-skills-link
7
+
8
+ ## When to Use
9
+ After installing new skills or updating existing ones. Verifies that OpenCode can discover the package-local skills directory.
10
+
11
+ ## Workflow
12
+ 1. Read skills from `harness/skills/`
13
+ 2. Confirm `config.skills.paths` points at the package-local harness path
14
+ 3. Skip unchanged skills when checking manifests
15
+ 4. Log missing, invalid, or newly added skills
16
+
17
+ ## Anti-patterns
18
+ - Linking skills without verifying they exist in harness
19
+ - Copying skills into global config during normal operation
20
+ - Overwriting user-modified skills without explicit intent
21
+ - Linking broken or incomplete skills
22
+
23
+ ## Routing
24
+
25
+ | Outcome | Route |
26
+ |---------|-------|
27
+ | pass | → [report link status to user] |
28
+ | fail | → oh-skill-craft (fix or rebuild broken skill) |
29
+ | blocker | → surface to user |
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: oh-skills-list
3
+ description: "List all available oh-* skills with descriptions"
4
+ ---
5
+
6
+ # oh-skills-list
7
+
8
+ ## When to Use
9
+ To discover what skills are available. Lists every skill with its name, description, and category.
10
+
11
+ ## Output
12
+ Markdown table of skills:
13
+
14
+ | Skill | Description | Category |
15
+ |-------|-------------|----------|
16
+ | oh-plan | Strategy + architecture review | Orchestration |
17
+ | oh-qa | Full QA workflow | Quality |
18
+ | ... | ... | ... |
19
+
20
+ ## Anti-patterns
21
+ - Listing "all available" but missing recently installed skills
22
+ - Showing skill file paths instead of human-readable descriptions
23
+ - Not categorising skills (flat list is hard to scan)
24
+
25
+ ## Routing
26
+
27
+ | Outcome | Route |
28
+ |---------|-------|
29
+ | pass | → [done — read-only report] |
30
+ | fail | → [surface issue to user] |
31
+ | blocker | → surface to user |
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: oh-triage
3
+ description: "Issue triage state machine — classify, prioritise, assign"
4
+ ---
5
+
6
+ # oh-triage
7
+
8
+ ## When to Use
9
+ When new issues come in, or when reviewing the issue backlog. Drives issues through a triage state machine.
10
+
11
+ ## States
12
+ 1. **Needs triage** — new issue, unclassified
13
+ 2. **Needs info** — waiting on reporter for clarification
14
+ 3. **Ready for agent** — well-specified, can be picked up
15
+ 4. **Ready for human** — needs human judgment or access
16
+ 5. **Wontfix** — declined with reason
17
+
18
+ ## Workflow
19
+ 1. Read new issues (label: `needs-triage`)
20
+ 2. Classify: bug / feature / enhancement / question
21
+ 3. Assess severity and priority
22
+ 4. Assign to appropriate state and owner
23
+ 5. Add triage metadata labels
24
+
25
+ ## Anti-patterns
26
+ - Leaving issues in "needs triage" indefinitely
27
+ - Triaging without reading the full issue
28
+ - Wontfix without explanation (leaves reporter unhappy)
29
+
30
+ ## Routing
31
+
32
+ | Outcome | Route |
33
+ |---------|-------|
34
+ | pass | → oh-issue (publish triaged issues) or oh-handoff (pass to agent) |
35
+ | fail | → oh-expert (clarify ambiguous issue) |
36
+ | blocker | → surface to user |
package/index.mjs CHANGED
@@ -1,58 +1,3 @@
1
- import { AutorecallPlugin } from "./autorecall.mjs"
2
- import { CuratorPlugin } from "./curator.mjs"
3
- import { SkillBuilderPlugin } from "./skill-builder.mjs"
4
- import { BootstrapPlugin } from "./bootstrap.mjs"
5
- import { MemoryToolsPlugin } from "./lib/memory-tools-plugin.mjs"
6
- import { AmbientMemoryPlugin } from "./lib/ambient-memory.mjs"
7
- import { OhcPlugin } from "./lib/ohc/pruner.mjs"
8
- import { UpdaterPlugin } from "./lib/ohc/updater.mjs"
9
-
10
- function chain(...fns) {
11
- const h = fns.filter(Boolean)
12
- if (!h.length) return undefined
13
- if (h.length === 1) return h[0]
14
- return async (i, o) => { for (const fn of h) await fn(i, o) }
15
- }
16
-
17
- export default async (input) => {
18
- const results = await Promise.allSettled([
19
- BootstrapPlugin(input),
20
- AutorecallPlugin(input),
21
- CuratorPlugin(input),
22
- SkillBuilderPlugin(input),
23
- MemoryToolsPlugin(input),
24
- AmbientMemoryPlugin(input),
25
- OhcPlugin(input),
26
- UpdaterPlugin(input),
27
- ])
28
- const [bootstrap, autorecall, curator, skillBuilder, memoryTools, ambient, ohc, updater] = results.map(r => r.status === 'fulfilled' ? r.value : {})
29
-
30
- const merged = {}
31
-
32
- if (bootstrap.config) merged.config = bootstrap.config
33
-
34
- const toolHandlers = { ...memoryTools.tool, ...ohc.tool }
35
- if (Object.keys(toolHandlers).length) merged.tool = toolHandlers
36
-
37
- merged["experimental.chat.system.transform"] = chain(ohc["experimental.chat.system.transform"])
38
- merged["experimental.chat.messages.transform"] = chain(
39
- ambient["experimental.chat.messages.transform"],
40
- bootstrap["experimental.chat.messages.transform"],
41
- ohc["experimental.chat.messages.transform"],
42
- )
43
- merged["command.execute.before"] = chain(updater["command.execute.before"], ohc["command.execute.before"])
44
-
45
- const eventHandlers = [autorecall.event, curator.event, skillBuilder.event].filter(Boolean)
46
- if (eventHandlers.length) {
47
- merged.event = async (payload) => {
48
- await Promise.allSettled(eventHandlers.map(fn => fn(payload)))
49
- }
50
- }
51
-
52
- for (const hook of ["experimental.session.compacting", "tool.execute.after"]) {
53
- const handler = chain(curator[hook], skillBuilder[hook])
54
- if (handler) merged[hook] = handler
55
- }
56
-
57
- return merged
58
- }
1
+ import { BootstrapPlugin } from "./bootstrap.mjs"
2
+
3
+ export default BootstrapPlugin
@@ -0,0 +1,77 @@
1
+ // Shared harness directory resolver — canonical implementation.
2
+ // Extracted from bootstrap.mjs to eliminate DRY violation with goal-tracker.mjs.
3
+ // Both consumers import from here.
4
+
5
+ import path from "node:path"
6
+ import fs from "node:fs"
7
+ import { fileURLToPath } from "node:url"
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
10
+ const PKG_DIR = path.resolve(__dirname, "..")
11
+
12
+ const REQUIRED_HARNESS_FILES = [
13
+ ["codex", "CONSTITUTION.md"],
14
+ ["instructions", "RUNTIME.md"],
15
+ ["skills", "oh-plan", "SKILL.md"],
16
+ ]
17
+
18
+ function ancestorDirs(start, limit = 6) {
19
+ const dirs = []
20
+ let current = path.resolve(start)
21
+ for (let i = 0; i < limit; i++) {
22
+ dirs.push(current)
23
+ const parent = path.dirname(current)
24
+ if (parent === current) break
25
+ current = parent
26
+ }
27
+ return dirs
28
+ }
29
+
30
+ function buildHarnessCandidates(currentDir, execPath, cwd) {
31
+ const roots = [path.resolve(currentDir, "harness")]
32
+ const seen = new Set(roots)
33
+
34
+ const anchors = [path.dirname(execPath), path.dirname(path.dirname(execPath)), cwd]
35
+ for (const anchor of anchors) {
36
+ for (const dir of ancestorDirs(anchor)) {
37
+ for (const root of [
38
+ path.join(dir, "harness"),
39
+ path.join(dir, "node_modules", "openhermes", "harness"),
40
+ path.join(dir, "bin", "node_modules", "openhermes", "harness"),
41
+ ]) {
42
+ const normalized = path.normalize(root)
43
+ if (seen.has(normalized)) continue
44
+ seen.add(normalized)
45
+ roots.push(normalized)
46
+ }
47
+ }
48
+ }
49
+
50
+ return roots
51
+ }
52
+
53
+ function hasRequiredHarnessFiles(root) {
54
+ return REQUIRED_HARNESS_FILES.every(parts => fs.existsSync(path.join(root, ...parts)))
55
+ }
56
+
57
+ export function resolveHarnessRoot({
58
+ currentDir = PKG_DIR,
59
+ execPath = process.execPath,
60
+ cwd = process.cwd(),
61
+ candidateRoots,
62
+ } = {}) {
63
+ const roots = candidateRoots ?? buildHarnessCandidates(currentDir, execPath, cwd)
64
+ for (const root of roots) {
65
+ if (hasRequiredHarnessFiles(root)) return root
66
+ }
67
+ return path.resolve(currentDir, "harness")
68
+ }
69
+
70
+ let _harnessDir
71
+
72
+ export function setHarnessRootForTest(dir) { _harnessDir = dir }
73
+
74
+ export function getHarnessDir() {
75
+ if (!_harnessDir) _harnessDir = resolveHarnessRoot()
76
+ return _harnessDir
77
+ }
package/lib/logger.mjs ADDED
@@ -0,0 +1,62 @@
1
+ import path from "node:path"
2
+ import os from "node:os"
3
+ import fs from "node:fs"
4
+
5
+ const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 }
6
+ const CURRENT_LEVEL = LEVELS[process.env.OPENCODE_LOG_LEVEL?.trim().toLowerCase()] ?? (process.env.OPENHERMES_LOG_LEVEL?.trim().toLowerCase() === "debug" ? LEVELS.debug : LEVELS.warn)
7
+
8
+ const LOG_DIR = path.join(os.homedir(), ".local", "share", "opencode", "log")
9
+ const LOG_FILE = path.join(LOG_DIR, "openhermes.log")
10
+
11
+ function ts() {
12
+ const d = new Date()
13
+ return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2,"0")}-${d.getDate().toString().padStart(2,"0")} ${d.getHours().toString().padStart(2,"0")}:${d.getMinutes().toString().padStart(2,"0")}:${d.getSeconds().toString().padStart(2,"0")}.${d.getMilliseconds().toString().padStart(3,"0")}`
14
+ }
15
+
16
+ function formatArgs(args) {
17
+ return args.map(a => {
18
+ if (a === null) return "null"
19
+ if (a === undefined) return "undefined"
20
+ if (typeof a === "object") {
21
+ try { return a?.message || JSON.stringify(a) } catch { return String(a) }
22
+ }
23
+ return String(a)
24
+ }).join(" ")
25
+ }
26
+
27
+ function shouldLog(levelName) {
28
+ return LEVELS[levelName] >= CURRENT_LEVEL
29
+ }
30
+
31
+ let _fd = null
32
+ function getFd() {
33
+ if (_fd) return _fd
34
+ try {
35
+ fs.mkdirSync(LOG_DIR, { recursive: true })
36
+ _fd = fs.openSync(LOG_FILE, "a")
37
+ } catch {
38
+ _fd = -1
39
+ }
40
+ return _fd
41
+ }
42
+
43
+ export function createLogger(name) {
44
+ const prefix = `[openhermes:${name}]`
45
+
46
+ function emit(levelName, ...args) {
47
+ if (!shouldLog(levelName)) return
48
+ const fd = getFd()
49
+ if (fd < 0) return
50
+ const line = `${ts()} ${prefix} [${levelName.toUpperCase()}] ${formatArgs(args)}\n`
51
+ try { fs.writeSync(fd, line) } catch {}
52
+ }
53
+
54
+ return {
55
+ debug: (...args) => emit("debug", ...args),
56
+ info: (...args) => emit("info", ...args),
57
+ warn: (...args) => emit("warn", ...args),
58
+ error: (...args) => emit("error", ...args),
59
+ }
60
+ }
61
+
62
+ export const rootLogger = createLogger("root")
package/package.json CHANGED
@@ -1,53 +1,49 @@
1
- {
2
- "name": "openhermes",
3
- "version": "2.6.1",
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
- "commands:audit": "node harness/scripts/sync-commands.mjs --audit",
31
- "commands:generate": "node harness/scripts/sync-commands.mjs --generate",
32
- "commands:sync": "node harness/scripts/sync-commands.mjs --sync",
33
- "commands:full": "node harness/scripts/sync-commands.mjs"
34
- },
35
- "keywords": [
36
- "opencode",
37
- "opencode-plugin",
38
- "openhermes",
39
- "checkpoint",
40
- "curation",
41
- "memory",
42
- "skills"
43
- ],
44
- "repository": {
45
- "type": "git",
46
- "url": "git+https://github.com/nathwn12/openhermes.git"
47
- },
48
- "bugs": {
49
- "url": "https://github.com/nathwn12/openhermes/issues"
50
- },
51
- "homepage": "https://github.com/nathwn12/openhermes#readme",
52
- "author": "nathwn12"
53
- }
1
+ {
2
+ "name": "openhermes",
3
+ "version": "4.0.0",
4
+ "description": "OpenCode-native skills, commands, and rules orchestration for OpenHermes.",
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
+ "./bootstrap": "./bootstrap.mjs"
14
+ },
15
+ "files": [
16
+ "index.mjs",
17
+ "bootstrap.mjs",
18
+ "ETHOS.md",
19
+ "CONTEXT.md",
20
+ "lib/",
21
+ "test/",
22
+ "harness/codex/",
23
+ "harness/instructions/",
24
+ "harness/skills/",
25
+ "harness/commands/",
26
+ "harness/agents/"
27
+ ],
28
+ "scripts": {
29
+ "test": "node --test test/*.test.mjs"
30
+ },
31
+ "keywords": [
32
+ "opencode",
33
+ "openhermes",
34
+ "orchestrator",
35
+ "skills",
36
+ "commands",
37
+ "agents",
38
+ "rules"
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
+ }