openhermes 4.9.2 → 4.11.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/CONTEXT.md +1 -1
- package/README.md +32 -31
- package/bootstrap.ts +262 -45
- package/harness/agents/oh-planner.md +1 -1
- package/harness/agents/openhermes.md +27 -126
- package/harness/codex/AUTOPILOT.md +99 -3
- package/harness/codex/CHARTER.md +3 -4
- package/harness/lib/background/background.test.ts +197 -0
- package/harness/lib/background/index.ts +7 -0
- package/harness/lib/background/interfaces.ts +31 -0
- package/harness/lib/background/manager.ts +320 -0
- package/harness/lib/composer/compose.test.ts +168 -0
- package/harness/lib/composer/compose.ts +65 -0
- package/harness/lib/composer/fragments/01-identity.md +1 -0
- package/harness/lib/composer/fragments/02-delegation.md +6 -0
- package/harness/lib/composer/fragments/03-permissions.md +13 -0
- package/harness/lib/composer/fragments/04-task-flow.md +15 -0
- package/harness/lib/composer/fragments/05-confidence.md +5 -0
- package/harness/lib/composer/fragments/06-parallelization.md +17 -0
- package/harness/lib/composer/fragments/07-shell.md +41 -0
- package/harness/lib/composer/fragments/08-routing.md +8 -0
- package/harness/lib/composer/fragments/09-guardrails.md +12 -0
- package/harness/lib/composer/index.ts +1 -0
- package/harness/lib/hooks/builtins/confidence-gate-hook.ts +70 -0
- package/harness/lib/hooks/builtins/delegation-depth-hook.ts +59 -0
- package/harness/lib/hooks/builtins/error-recovery-hook.ts +107 -0
- package/harness/lib/hooks/builtins/memory-sync-hook.ts +73 -0
- package/harness/lib/hooks/builtins/plan-check-hook.ts +43 -0
- package/harness/lib/hooks/builtins/route-tracking-hook.ts +147 -0
- package/harness/lib/hooks/builtins/sanity-check-hook.ts +52 -0
- package/harness/lib/hooks/builtins/shell-detect-hook.ts +96 -0
- package/harness/lib/hooks/hooks.test.ts +1016 -0
- package/harness/lib/hooks/index.ts +30 -0
- package/harness/lib/hooks/registry.ts +416 -0
- package/harness/lib/hooks/types.ts +71 -0
- package/harness/lib/memory/index.ts +18 -0
- package/harness/lib/memory/interfaces.ts +53 -0
- package/harness/lib/memory/memory-manager.ts +205 -0
- package/harness/lib/memory/memory.test.ts +491 -0
- package/harness/lib/memory/plan-store.ts +366 -0
- package/harness/lib/recovery/handler.ts +243 -0
- package/harness/lib/recovery/index.ts +14 -0
- package/harness/lib/recovery/interfaces.ts +48 -0
- package/harness/lib/recovery/patterns.ts +149 -0
- package/harness/lib/recovery/recovery.test.ts +312 -0
- package/harness/lib/sanity/anomaly-tracker.ts +127 -0
- package/harness/lib/sanity/checker.ts +178 -0
- package/harness/lib/sanity/index.ts +13 -0
- package/harness/lib/sanity/interfaces.ts +24 -0
- package/harness/lib/sanity/sanity.test.ts +472 -0
- package/harness/lib/sync/file-watcher.ts +174 -0
- package/harness/lib/sync/index.ts +11 -0
- package/harness/lib/sync/interfaces.ts +27 -0
- package/harness/lib/sync/plan-sync.ts +536 -0
- package/harness/lib/sync/sync.test.ts +832 -0
- package/harness/skills/oh-init/DEEP.md +2 -2
- package/harness/skills/oh-manifest/SKILL.md +1 -1
- package/harness/skills/oh-plan-review/DEEP.md +1 -1
- package/harness/skills/oh-planner/DEEP.md +3 -3
- package/harness/skills/oh-ship/SKILL.md +1 -1
- package/harness/skills/oh-skill-craft/SKILL.md +1 -4
- package/package.json +5 -5
- package/tsconfig.json +1 -1
- package/harness/commands/oh-doctor.md +0 -205
- package/harness/commands/oh-log.md +0 -18
- package/harness/skills/oh-learn/DEEP.md +0 -44
- package/harness/skills/oh-learn/SKILL.md +0 -30
- package/scripts/count-tokens.mjs +0 -158
- package/scripts/oh-doctor.ps1 +0 -342
|
@@ -26,7 +26,7 @@ OpenHermes is the primary orchestrator. All routing, planning, and delegation fl
|
|
|
26
26
|
- **Test command**: <fill or auto-detect>
|
|
27
27
|
|
|
28
28
|
## Key Directives
|
|
29
|
-
- Plan first. Write to `~/.local/share/
|
|
29
|
+
- Plan first. Write to `~/.local/share/openhermes/plans/<project>/plan-<nnn>.md` before multi-file changes.
|
|
30
30
|
- OpenHermes delegates everything to sub-agents — never executes directly.
|
|
31
31
|
- Verify before claiming success. Read files, run commands, confirm output.
|
|
32
32
|
- Use oh-* skills on demand via the skill tool.
|
|
@@ -40,7 +40,7 @@ Ask user to fill or auto-detect from manifests.
|
|
|
40
40
|
```markdown
|
|
41
41
|
## OpenHermes Orchestrator
|
|
42
42
|
OpenHermes is the primary orchestrator.
|
|
43
|
-
- **Plan**: `~/.local/share/
|
|
43
|
+
- **Plan**: `~/.local/share/openhermes/plans/<project>/plan-<nnn>.md`
|
|
44
44
|
- **Never execute**: delegates everything to sub-agents
|
|
45
45
|
- **Verify before claim**: read files, run commands, confirm output
|
|
46
46
|
```
|
|
@@ -26,6 +26,6 @@ Full build orchestration loop: pre-flight → plan → build → verify → loop
|
|
|
26
26
|
|
|
27
27
|
| Outcome | Route |
|
|
28
28
|
|---------|-------|
|
|
29
|
-
| pass | →
|
|
29
|
+
| pass | → oh-planner |
|
|
30
30
|
| fail | → oh-expert (diagnose loop failure) |
|
|
31
31
|
| blocker | → surface with context and options |
|
|
@@ -80,7 +80,7 @@ One section at a time: Architecture → Code Quality → Tests → Performance.
|
|
|
80
80
|
|
|
81
81
|
## Output
|
|
82
82
|
|
|
83
|
-
Plan file (`~/.local/share/
|
|
83
|
+
Plan file (`~/.local/share/openhermes/plans/<project-name>/plan-<nnn>.md`) updated with findings and decisions.
|
|
84
84
|
|
|
85
85
|
## Anti-patterns
|
|
86
86
|
|
|
@@ -92,18 +92,18 @@ Runs sequentially: **Strategy → Architecture → Design → Engineering → DX
|
|
|
92
92
|
Every plan written by oh-planner uses this canonical format.
|
|
93
93
|
|
|
94
94
|
### Storage
|
|
95
|
-
Canonical path: `~/.local/share/
|
|
95
|
+
Canonical path: `~/.local/share/openhermes/plans/<project>/plan-<nnn>.md`
|
|
96
96
|
|
|
97
97
|
### Template
|
|
98
98
|
```markdown
|
|
99
99
|
# PLAN: <project>
|
|
100
100
|
|
|
101
|
-
Plan ID: <project
|
|
101
|
+
Plan ID: <project>/plan-<nnn>
|
|
102
102
|
Project: <project>
|
|
103
103
|
Status: active | in-progress | blocked | complete | abandoned
|
|
104
104
|
Created: <ts> | Updated: <ts>
|
|
105
105
|
Project Path: <absolute-path>
|
|
106
|
-
Plan Path: <canonical-path>/<project
|
|
106
|
+
Plan Path: <canonical-path>/<project>/plan-<nnn>.md
|
|
107
107
|
Objective: <short>
|
|
108
108
|
|
|
109
109
|
## Current State
|
|
@@ -3,9 +3,7 @@ name: oh-skill-craft
|
|
|
3
3
|
description: "Use when a new OH skill needs to be created, existing skill needs review against standards, or an external capability should be integrated as a skill. Meta-skill for growing the harness."
|
|
4
4
|
tier: 2
|
|
5
5
|
route:
|
|
6
|
-
pass:
|
|
7
|
-
- oh-skills-link
|
|
8
|
-
- oh-learn
|
|
6
|
+
pass: oh-skills-link
|
|
9
7
|
fail: oh-expert
|
|
10
8
|
blocker: surface
|
|
11
9
|
---
|
|
@@ -29,6 +27,5 @@ Create new agent skills for the OpenHermes harness.
|
|
|
29
27
|
| Outcome | Route |
|
|
30
28
|
|---------|-------|
|
|
31
29
|
| pass | → oh-skills-link (verify discovery) |
|
|
32
|
-
| iteration data | → oh-learn (extract patterns) |
|
|
33
30
|
| fail | → oh-expert (diagnose) |
|
|
34
31
|
| blocker | → surface |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openhermes",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.11.2",
|
|
4
4
|
"description": "Autonomous agent orchestration for OpenCode.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"main": "./index.ts",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@opencode-ai/plugin": "1.15.0"
|
|
13
|
-
"gpt-tokenizer": "^3.4.0"
|
|
12
|
+
"@opencode-ai/plugin": "1.15.0"
|
|
14
13
|
},
|
|
15
14
|
"exports": {
|
|
16
15
|
".": "./index.ts",
|
|
@@ -28,10 +27,11 @@
|
|
|
28
27
|
"harness/instructions/",
|
|
29
28
|
"harness/skills/",
|
|
30
29
|
"harness/commands/",
|
|
31
|
-
"harness/agents/"
|
|
30
|
+
"harness/agents/",
|
|
31
|
+
"harness/lib/"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
-
"test": "bun test
|
|
34
|
+
"test": "bun test"
|
|
35
35
|
},
|
|
36
36
|
"keywords": [
|
|
37
37
|
"opencode",
|
package/tsconfig.json
CHANGED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Diagnose OpenHermes + OpenCode health with concrete file-level checks
|
|
3
|
-
agent: OpenHermes
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Run a structured 8-category diagnostic. For each check, inspect the actual files on disk and report PASS/FAIL/WARN with evidence.
|
|
7
|
-
|
|
8
|
-
## 1. Plugin load path
|
|
9
|
-
|
|
10
|
-
**What to check:**
|
|
11
|
-
- Read `%USERPROFILE%\.config\opencode\opencode.jsonc` — verify the `plugin` array contains `"openhermes@git+https://github.com/nathwn12/openhermes.git#dev"`.
|
|
12
|
-
- Check for trailing commas: line 23 has a known trailing `,` after the single plugin entry. The parser may fail on this.
|
|
13
|
-
- Check the resolved install path: `%USERPROFILE%\.cache\opencode\packages\openhermes@git+https_/github.com/nathwn12/openhermes.git#dev/node_modules/openhermes/` — does it exist? Does `harness/` and `index.ts` resolve?
|
|
14
|
-
|
|
15
|
-
**Troubleshooting:**
|
|
16
|
-
- Trailing comma fix: remove `,` from end of line 23 in opencode.jsonc.
|
|
17
|
-
- If the plugin path doesn't match, update opencode.jsonc to point to the correct git ref.
|
|
18
|
-
- If the package directory is missing, OpenCode reinstalls on next launch. Restart and check again.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 2. Skills discovery
|
|
23
|
-
|
|
24
|
-
**What to check:**
|
|
25
|
-
- Count directories in `harness/skills/` — expect exactly 31.
|
|
26
|
-
- Spot-check 3 SKILL.md files for valid YAML frontmatter (must have `name`, `description`, `route`, `tier`, `triggers`).
|
|
27
|
-
- Verify bootstrap.ts injects `config.skills.paths` with two sources: the built-in skills dir AND user skill dirs (`~/.agents/skills/`, `~/.config/opencode/skills/`, `~/.claude/skills/`).
|
|
28
|
-
- Verify NO symlinks are required — discovery uses the plugin API `config.skills.paths` mechanism.
|
|
29
|
-
|
|
30
|
-
**Expected current count:** 31 (confirmed directories match filesystem)
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 3. Command registration
|
|
35
|
-
|
|
36
|
-
**What to check:**
|
|
37
|
-
- List `harness/commands/` — expect exactly 2 `.md` files: `oh-doctor.md` and `oh-log.md`.
|
|
38
|
-
- Read each file's frontmatter — both must have `description` + `agent: OpenHermes`.
|
|
39
|
-
- Verify bootstrap.ts `commandDefinitions()` reads this directory and merges into `config.command`.
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## 4. Agent registration
|
|
44
|
-
|
|
45
|
-
**What to check:**
|
|
46
|
-
- List `harness/agents/` — expect exactly 17 `.md` files (1 primary + 16 subagents).
|
|
47
|
-
- Read `openhermes.md` frontmatter — must have `mode: primary`.
|
|
48
|
-
- Verify primary agent permissions in bootstrap.ts (lines 370-391): `bash: deny`, `edit: deny`, `task: allow`.
|
|
49
|
-
- Verify 16 subagents have explicit permissions in `SUBAGENT_PERMISSIONS` (lines 335-350): `bash: allow`, `edit: allow`, `task: { "oh-*": "deny" }`.
|
|
50
|
-
- Verify delegation loop guard (line 424): max depth = 10.
|
|
51
|
-
- Verify `oh-planner` + `oh-grill` + `oh-skill-craft` are hidden from @-menu (line 366).
|
|
52
|
-
|
|
53
|
-
**Expected:** 17 entries, no missing agent definitions, all permissions assigned.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## 5. Instruction injection
|
|
58
|
-
|
|
59
|
-
**What to check:**
|
|
60
|
-
- Verify all 3 files exist:
|
|
61
|
-
- `harness/codex/CHARTER.md` (target: ~80 lines)
|
|
62
|
-
- `harness/codex/AUTOPILOT.md` (target: ~200 lines)
|
|
63
|
-
- `harness/instructions/SHELL.md` (76 lines)
|
|
64
|
-
- Each file must be > 0 bytes and not a placeholder/stub.
|
|
65
|
-
- Verify bootstrap.ts injects both `harness/codex/` and `harness/instructions/` directories via `config.instructions`.
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## 6. Package integrity
|
|
70
|
-
|
|
71
|
-
**What to check:**
|
|
72
|
-
- Read `package.json` — verify these fields:
|
|
73
|
-
- `name: "openhermes"`
|
|
74
|
-
- `version` — note current version
|
|
75
|
-
- `exports: { ".": "./index.ts", "./bootstrap": "./bootstrap.ts" }`
|
|
76
|
-
- `files` — all 11 entries must resolve to real files/dirs on disk
|
|
77
|
-
- Read `tsconfig.json` — must have: `strict: true`, `target: ESNext`, `module: ESNext`, `moduleResolution: bundler`.
|
|
78
|
-
- Verify `lib/harness-resolver.ts` — check its `REQUIRED_HARNESS_FILES` (CHARTER.md, AUTOPILOT.md, oh-planner/SKILL.md) all resolve from the harness root.
|
|
79
|
-
- Check `scripts/` directory — no `.ps1` files exist. This is the current state. If some are expected, note absence.
|
|
80
|
-
- Run `bun test` if available — note any failures.
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## 7. Auth & config safety
|
|
85
|
-
|
|
86
|
-
**What to check (grep entire project dir):**
|
|
87
|
-
- `.env*` — expect 0 matches
|
|
88
|
-
- `*.key` — expect 0 matches
|
|
89
|
-
- `*secret*` — expect 0 matches
|
|
90
|
-
- `credentials*` — expect 0 matches
|
|
91
|
-
- `auth.json` — expect 0 matches (should be at `%USERPROFILE%\.local\share\opencode\auth.json`, outside the project)
|
|
92
|
-
- Read `.gitignore` — must cover: `node_modules/`, `.config/`, `.opencode/`, `PLAN.d/`, `coverage/`, `*.tgz`
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## 8. Documentation accuracy
|
|
97
|
-
|
|
98
|
-
**What to check:**
|
|
99
|
-
Read `AGENTS.md` and compare its claims against the actual filesystem. Known discrepancies to flag:
|
|
100
|
-
|
|
101
|
-
| Claim | Actual | Status |
|
|
102
|
-
|---|---|---|
|
|
103
|
-
| Line 22: "31 skills (see below)" | Directory has 31 skills | Up to date |
|
|
104
|
-
| Line 19: \`harness/instructions/ — SHELL.md\` | Directory only has SHELL.md | Up to date |
|
|
105
|
-
| Line 23: `lib/ — harness-resolver.ts, logger.ts` | Only `harness-resolver.ts` exists | `logger.ts` removed |
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Quick-wins (automated)
|
|
110
|
-
|
|
111
|
-
For instant automated checks, run the companion PowerShell script which outputs JSON-Lines diagnostics consumable by the OpenHermes orchestrator:
|
|
112
|
-
|
|
113
|
-
```powershell
|
|
114
|
-
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/oh-doctor.ps1
|
|
115
|
-
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/oh-doctor.ps1 -SkipOCChecks
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
This script checks:
|
|
119
|
-
|
|
120
|
-
1. **AGENTS.md accuracy** — skill count (expects 31) and file references
|
|
121
|
-
2. **Package files field** — all `package.json` `files` entries exist on disk
|
|
122
|
-
3. **Harness prerequisites** — CHARTER.md, AUTOPILOT.md, oh-planner/SKILL.md resolve
|
|
123
|
-
4. **Test health** — `bun test` pass/fail counts
|
|
124
|
-
5. **TypeScript compilation** — `bunx tsc --noEmit` clean check
|
|
125
|
-
6. **Secrets scan** — .env, *.key, credentials, auth.json in repo
|
|
126
|
-
7. **.gitignore coverage** — expected entries present
|
|
127
|
-
8. **Runtime checks** — opencode CLI paths, plugin load, skills discovery (skippable)
|
|
128
|
-
|
|
129
|
-
Each check reports PASS/FAIL/WARN with evidence and a suggested fix.
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Troubleshooting reference
|
|
134
|
-
|
|
135
|
-
Use these when a check fails.
|
|
136
|
-
|
|
137
|
-
### Config won't parse
|
|
138
|
-
```
|
|
139
|
-
%USERPROFILE%\.config\opencode\opencode.jsonc
|
|
140
|
-
```
|
|
141
|
-
- Trailing commas: JSONC tolerates them in some parsers but OpenCode's validator rejects them.
|
|
142
|
-
- Fix: open the file and remove any trailing `,` after the last array/object element.
|
|
143
|
-
- Test: run `opencode --print-logs` — parser errors appear in the first few lines.
|
|
144
|
-
|
|
145
|
-
### Plugin won't load
|
|
146
|
-
- Temporarily disable all plugins by setting `"plugin": []` in opencode.jsonc.
|
|
147
|
-
- Restart. If OpenCode works, re-enable plugins one at a time.
|
|
148
|
-
- If the app crashes on launch, check `%USERPROFILE%\.config\opencode\plugins\` directory and move it aside.
|
|
149
|
-
|
|
150
|
-
### Stuck or corrupted cache
|
|
151
|
-
- Clear the full cache: `rm -rf %USERPROFILE%\.cache\opencode` (Windows: delete `%USERPROFILE%\.cache\opencode`).
|
|
152
|
-
- This forces OpenCode to reinstall provider packages on next launch.
|
|
153
|
-
- This resolves `AI_APICallError` and stale provider package issues.
|
|
154
|
-
|
|
155
|
-
### Authentication failures
|
|
156
|
-
- Run `/connect` in the TUI to re-authenticate.
|
|
157
|
-
- Check auth file: `%USERPROFILE%\.local\share\opencode\auth.json` — should be >0 bytes and valid JSON.
|
|
158
|
-
- If corrupted: delete the file, then re-run `/connect`.
|
|
159
|
-
|
|
160
|
-
### Model not found / ProviderModelNotFoundError
|
|
161
|
-
- Run `opencode models` to see available models.
|
|
162
|
-
- Model format: `<providerId>/<modelId>` (e.g. `openai/gpt-4.1`).
|
|
163
|
-
- Verify the provider is authenticated and has access to the requested model.
|
|
164
|
-
|
|
165
|
-
### Log inspection
|
|
166
|
-
- Logs at `%USERPROFILE%\.local\share\opencode\log\` — newest file first.
|
|
167
|
-
- Run `opencode --log-level DEBUG` for verbose output.
|
|
168
|
-
- Run `/oh-log` in OpenCode to read OpenHermes-specific session logs.
|
|
169
|
-
|
|
170
|
-
### ProviderInitError
|
|
171
|
-
- Corrupted or invalid configuration in `~/.local/share/opencode`.
|
|
172
|
-
- Last resort: delete `~/.local/share/opencode` and re-authenticate with `/connect`.
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Report format
|
|
177
|
-
|
|
178
|
-
Summarize diagnostics as:
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
## Diagnosis
|
|
182
|
-
|
|
183
|
-
### PASS items
|
|
184
|
-
- check name — evidence
|
|
185
|
-
|
|
186
|
-
### FAIL / WARN items
|
|
187
|
-
- ❌ FAIL: check name — evidence — fix
|
|
188
|
-
- ⚠️ WARN: check name — evidence — suggestion
|
|
189
|
-
|
|
190
|
-
### Issues table
|
|
191
|
-
| # | Severity | Check | File | Fix |
|
|
192
|
-
|---|----------|-------|------|-----|
|
|
193
|
-
|
|
194
|
-
### Next actions
|
|
195
|
-
1. Priority action — command or manual step
|
|
196
|
-
2. ...
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## Routing
|
|
200
|
-
|
|
201
|
-
| Outcome | Route |
|
|
202
|
-
|---------|-------|
|
|
203
|
-
| All PASS or WARN only | → surface report to user |
|
|
204
|
-
| Any FAIL | → oh-investigate (diagnose issues found) |
|
|
205
|
-
| Unrecoverable (env broken) | → surface to user with findings |
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Read and summarize the OpenHermes session log
|
|
3
|
-
agent: OpenHermes
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Inspect the OpenHermes session log at `~/.local/share/opencode/log/openhermes.log`.
|
|
7
|
-
|
|
8
|
-
Return a structured summary grouped by session ID.
|
|
9
|
-
|
|
10
|
-
Focus on:
|
|
11
|
-
|
|
12
|
-
- `session.created`
|
|
13
|
-
- `session.compacted`
|
|
14
|
-
- `session.error`
|
|
15
|
-
|
|
16
|
-
For each session, show the timeline in order and highlight any error details.
|
|
17
|
-
|
|
18
|
-
Do not dump the whole log verbatim unless explicitly asked.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# oh-learn — Deep Reference
|
|
2
|
-
|
|
3
|
-
## When to Use
|
|
4
|
-
|
|
5
|
-
Session learnings should be captured, reviewed, or promoted as reusable instincts for future work.
|
|
6
|
-
|
|
7
|
-
Triggers: learn from session, extract patterns, run oh-learn.
|
|
8
|
-
|
|
9
|
-
## Instinct Data Model
|
|
10
|
-
|
|
11
|
-
JSONL at `~/.local/share/opencode/openhermes/plans/<project>-instincts.jsonl`:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{"trigger": "specific situation", "action": "recommended response", "confidence": 0.5, "applications": 1, "successes": 1, "category": "coding", "source": "oh-learn:extract", "ts": "2026-05-15T12:00:00Z"}
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
**Trigger:** specific, matchable (not general advice). **Action:** executable (not belief). **Confidence:** starts 0.5, +0.05 per success, -0.02/day decay. **Category:** coding, testing, security, git, planning, orchestration, debugging, ux.
|
|
18
|
-
|
|
19
|
-
## Workflows
|
|
20
|
-
|
|
21
|
-
### Extract
|
|
22
|
-
|
|
23
|
-
Scan session for repeated decisions. For each: write instinct. Check existing file for near-duplicates. Merge (max confidence, increment applications) or append.
|
|
24
|
-
|
|
25
|
-
### Evolve
|
|
26
|
-
|
|
27
|
-
Read all instincts. Group by category then topic. ≥5 instincts with avg confidence ≥ 0.7 → oh-skill-craft spec. 3-4 with confidence ≥ 0.8 → suggest update to existing skill.
|
|
28
|
-
|
|
29
|
-
### Promote
|
|
30
|
-
|
|
31
|
-
Instincts with confidence ≥ 0.85 AND applications ≥ 10 → filter project-specific → append to global `%USERPROFILE%\.config\opencode\instincts.jsonl`. Tag promoted.
|
|
32
|
-
|
|
33
|
-
### Review / Search / Prune / Export
|
|
34
|
-
|
|
35
|
-
Review: totals + distributions. Search: by topic, trigger, category, confidence. Prune: stale >30d with confidence < 0.3. Export: portable JSON.
|
|
36
|
-
|
|
37
|
-
## Anti-patterns
|
|
38
|
-
|
|
39
|
-
- Hoarding every observation (most aren't learnings)
|
|
40
|
-
- Never pruning
|
|
41
|
-
- Storing what not why
|
|
42
|
-
- Over-promoting to global
|
|
43
|
-
- Extracting without applying
|
|
44
|
-
- Ignoring confidence
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: oh-learn
|
|
3
|
-
description: "Capture, review, and promote session learnings as reusable instincts"
|
|
4
|
-
tier: 2
|
|
5
|
-
route:
|
|
6
|
-
pass: done
|
|
7
|
-
fail: surface
|
|
8
|
-
blocker: surface
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# oh-learn
|
|
12
|
-
|
|
13
|
-
Distill session patterns into instincts, cluster into skill candidates, and promote high-signal patterns.
|
|
14
|
-
|
|
15
|
-
## Steps
|
|
16
|
-
|
|
17
|
-
1. Scan session for repeated decisions
|
|
18
|
-
2. Write instinct for each pattern — trigger, action, confidence
|
|
19
|
-
3. Check existing file for near-duplicates; merge or append
|
|
20
|
-
4. Group instincts by category and topic
|
|
21
|
-
5. Promote high-confidence instincts (≥0.85, ≥10 applications) to global scope
|
|
22
|
-
6. Prune stale low-confidence instincts (<0.3, >30 days)
|
|
23
|
-
|
|
24
|
-
## Routing
|
|
25
|
-
|
|
26
|
-
| Outcome | Route |
|
|
27
|
-
|---------|-------|
|
|
28
|
-
| pass | → done |
|
|
29
|
-
| fail | → surface |
|
|
30
|
-
| blocker | → surface |
|
package/scripts/count-tokens.mjs
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exact token counting using gpt-tokenizer.
|
|
3
|
-
* Counts every SKILL.md, bootstrap doc, AGENTS.md, and instructions.
|
|
4
|
-
*/
|
|
5
|
-
import { encode } from "gpt-tokenizer";
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import path from "path";
|
|
8
|
-
|
|
9
|
-
const HOME = process.env.USERPROFILE || process.env.HOME;
|
|
10
|
-
const ROOT = path.resolve("Q:/PROJECTS/PERSONAL/openhermes-pkg");
|
|
11
|
-
|
|
12
|
-
const categories = {
|
|
13
|
-
"OH Bootstrap Docs (on disk, NOT injected)": [
|
|
14
|
-
path.join(ROOT, "harness/codex/AUTOPILOT.md"),
|
|
15
|
-
path.join(ROOT, "harness/codex/CHARTER.md"),
|
|
16
|
-
path.join(ROOT, "harness/instructions/SHELL.md"),
|
|
17
|
-
path.join(ROOT, "CONTEXT.md"),
|
|
18
|
-
path.join(ROOT, "ETHOS.md"),
|
|
19
|
-
],
|
|
20
|
-
"OH Agent Prompt (injected as system prompt)": [
|
|
21
|
-
path.join(ROOT, "harness/agents/openhermes.md"),
|
|
22
|
-
],
|
|
23
|
-
"OH Built-in Skills (31, registered)": [],
|
|
24
|
-
"User Skills (.agents/skills) — on disk, NOT registered": [],
|
|
25
|
-
"User Skills (.config/opencode/skills) — on disk, NOT registered": [],
|
|
26
|
-
"Instructions": [
|
|
27
|
-
path.join(ROOT, "AGENTS.md"),
|
|
28
|
-
path.join(HOME, ".config/opencode/AGENTS.md"),
|
|
29
|
-
],
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// Discover OH built-in skills
|
|
33
|
-
const skillsDir = path.join(ROOT, "harness/skills");
|
|
34
|
-
for (const entry of fs.readdirSync(skillsDir)) {
|
|
35
|
-
const skPath = path.join(skillsDir, entry, "SKILL.md");
|
|
36
|
-
if (fs.existsSync(skPath)) categories["OH Built-in Skills (31, registered)"].push(skPath);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Discover user skills
|
|
40
|
-
const userDirs = [
|
|
41
|
-
path.join(HOME, ".agents/skills"),
|
|
42
|
-
path.join(HOME, ".config/opencode/skills"),
|
|
43
|
-
];
|
|
44
|
-
for (const dir of userDirs) {
|
|
45
|
-
const key = dir.includes(".agents")
|
|
46
|
-
? "User Skills (.agents/skills) — on disk, NOT registered"
|
|
47
|
-
: "User Skills (.config/opencode/skills) — on disk, NOT registered";
|
|
48
|
-
if (fs.existsSync(dir)) {
|
|
49
|
-
for (const entry of fs.readdirSync(dir)) {
|
|
50
|
-
const skPath = path.join(dir, entry, "SKILL.md");
|
|
51
|
-
if (fs.existsSync(skPath)) categories[key].push(skPath);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Extract frontmatter description
|
|
57
|
-
function extractDescription(filePath) {
|
|
58
|
-
try {
|
|
59
|
-
const content = fs.readFileSync(filePath, "utf8");
|
|
60
|
-
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
61
|
-
if (!match) return { description: "", body: content };
|
|
62
|
-
const fm = match[1];
|
|
63
|
-
const descLine = fm.split("\n").find(l => l.trim().startsWith("description:"));
|
|
64
|
-
if (!descLine) return { description: "", body: content.slice(match[0].length) };
|
|
65
|
-
const desc = descLine.slice(descLine.indexOf(":") + 1).trim().replace(/^['"]|['"]$/g, "");
|
|
66
|
-
return { description: desc, body: content.slice(match[0].length) };
|
|
67
|
-
} catch { return { description: "", body: "" }; }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Build what the available_skills XML block looks like (OH built-in skills only)
|
|
71
|
-
function buildAvailableSkillsXml(includeUserSkills = false) {
|
|
72
|
-
const parts = ['<available_skills>'];
|
|
73
|
-
const allDirs = [path.join(ROOT, "harness/skills")];
|
|
74
|
-
if (includeUserSkills) {
|
|
75
|
-
allDirs.push(
|
|
76
|
-
path.join(HOME, ".agents/skills"),
|
|
77
|
-
path.join(HOME, ".config/opencode/skills"),
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
for (const dir of allDirs) {
|
|
81
|
-
if (!fs.existsSync(dir)) continue;
|
|
82
|
-
for (const entry of fs.readdirSync(dir).sort()) {
|
|
83
|
-
const skPath = path.join(dir, entry, "SKILL.md");
|
|
84
|
-
if (!fs.existsSync(skPath)) continue;
|
|
85
|
-
const { description } = extractDescription(skPath);
|
|
86
|
-
parts.push(` <skill>`);
|
|
87
|
-
parts.push(` <name>${entry}</name>`);
|
|
88
|
-
parts.push(` <description>${description}</description>`);
|
|
89
|
-
parts.push(` <location>file:///${skPath.replace(/\\/g, '/')}</location>`);
|
|
90
|
-
parts.push(` </skill>`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
parts.push('</available_skills>');
|
|
94
|
-
return parts.join('\n');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Count everything
|
|
98
|
-
console.log("=".repeat(80));
|
|
99
|
-
console.log("EXACT TOKEN COUNTS (gpt-tokenizer)");
|
|
100
|
-
console.log("=".repeat(80));
|
|
101
|
-
|
|
102
|
-
let grandTotal = 0;
|
|
103
|
-
|
|
104
|
-
for (const [category, files] of Object.entries(categories)) {
|
|
105
|
-
console.log(`\n--- ${category} ---`);
|
|
106
|
-
let catTotal = 0;
|
|
107
|
-
for (const file of files) {
|
|
108
|
-
if (!fs.existsSync(file)) continue;
|
|
109
|
-
const content = fs.readFileSync(file, "utf8");
|
|
110
|
-
const tokens = encode(content).length;
|
|
111
|
-
const name = path.basename(path.dirname(file)) !== "skills"
|
|
112
|
-
? path.basename(file)
|
|
113
|
-
: path.basename(path.dirname(file));
|
|
114
|
-
console.log(` ${name.padEnd(40)} ${String(tokens).padStart(6)} tokens (${content.length.toLocaleString()} bytes)`);
|
|
115
|
-
catTotal += tokens;
|
|
116
|
-
}
|
|
117
|
-
console.log(` ${"-".repeat(50)}`);
|
|
118
|
-
console.log(` TOTAL: ${catTotal} tokens`);
|
|
119
|
-
grandTotal += catTotal;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Available skills XML cost (OH built-in only — user skills no longer registered)
|
|
123
|
-
console.log(`\n--- available_skills XML Block (OH only, 31 skills) ---`);
|
|
124
|
-
const xmlContent = buildAvailableSkillsXml(false);
|
|
125
|
-
const xmlTokens = encode(xmlContent).length;
|
|
126
|
-
console.log(` Total: ${xmlTokens} tokens (${xmlContent.length.toLocaleString()} bytes)`);
|
|
127
|
-
|
|
128
|
-
console.log(`\n--- available_skills XML Block (ALL 61 skills, for comparison) ---`);
|
|
129
|
-
const xmlContentAll = buildAvailableSkillsXml(true);
|
|
130
|
-
const xmlTokensAll = encode(xmlContentAll).length;
|
|
131
|
-
console.log(` Total: ${xmlTokensAll} tokens (${xmlContentAll.length.toLocaleString()} bytes)`);
|
|
132
|
-
|
|
133
|
-
grandTotal += xmlTokens;
|
|
134
|
-
|
|
135
|
-
// System prompt components
|
|
136
|
-
const instructionsTotal = categories["Instructions"].reduce((s, f) => {
|
|
137
|
-
if (!fs.existsSync(f)) return s;
|
|
138
|
-
return s + encode(fs.readFileSync(f, "utf8")).length;
|
|
139
|
-
}, 0);
|
|
140
|
-
const agentPromptTotal = categories["OH Agent Prompt (injected as system prompt)"].reduce((s, f) => {
|
|
141
|
-
if (!fs.existsSync(f)) return s;
|
|
142
|
-
return s + encode(fs.readFileSync(f, "utf8")).length;
|
|
143
|
-
}, 0);
|
|
144
|
-
|
|
145
|
-
console.log(`\n${"=".repeat(80)}`);
|
|
146
|
-
console.log(`TOTAL ALL SKILL FILES: ${categories["OH Built-in Skills (31, registered)"].reduce((s, f) => s + encode(fs.readFileSync(f, "utf8")).length, 0)} tokens`);
|
|
147
|
-
console.log(`TOTAL USER SKILL FILES: ${categories["User Skills (.agents/skills) — on disk, NOT registered"].reduce((s, f) => s + encode(fs.readFileSync(f, "utf8")).length, 0)} tokens`);
|
|
148
|
-
console.log(`TOTAL CONFIG SKILLS: ${categories["User Skills (.config/opencode/skills) — on disk, NOT registered"].reduce((s, f) => s + encode(fs.readFileSync(f, "utf8")).length, 0)} tokens`);
|
|
149
|
-
console.log(`TOTAL INSTRUCTIONS: ${instructionsTotal} tokens`);
|
|
150
|
-
console.log(`AGENT PROMPT (openhermes.md): ${agentPromptTotal} tokens`);
|
|
151
|
-
console.log(`available_skills XML (ALL 61 skills, registered): ${xmlTokensAll} tokens`);
|
|
152
|
-
console.log(`\nBOOTSTRAP INJECTION: REMOVED (was 4,503 via transform hook)`);
|
|
153
|
-
console.log(`ROUTING INVENTORY: REMOVED (was ~902 via buildRoutingInventory())`);
|
|
154
|
-
console.log(`\nPER-TURN SYSTEM PROMPT COST: ${instructionsTotal + xmlTokensAll + agentPromptTotal} tokens`);
|
|
155
|
-
console.log(` (instructions ${instructionsTotal} + available_skills ${xmlTokensAll} + agent prompt ${agentPromptTotal})`);
|
|
156
|
-
console.log(`PRE-REFACTOR COST: ${instructionsTotal + xmlTokensAll + 4503 + 902} tokens`);
|
|
157
|
-
console.log(`SAVINGS: ${(instructionsTotal + xmlTokensAll + 4503 + 902) - (instructionsTotal + xmlTokensAll + agentPromptTotal)} tokens per turn`);
|
|
158
|
-
console.log("=".repeat(80));
|