opencode-autoresearch 3.3.0 → 3.4.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.
- package/.opencode/INSTALL.md +85 -0
- package/.opencode-plugin/plugin.json +2 -2
- package/AGENTS.md +29 -27
- package/INSTALL.md +275 -0
- package/README.md +122 -34
- package/VERSION +1 -1
- package/dist/cli.js +8 -8
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/helpers.d.ts +6 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +77 -4
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -1
- package/dist/run-manager.d.ts.map +1 -1
- package/dist/run-manager.js +6 -6
- package/dist/run-manager.js.map +1 -1
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +4 -3
- package/dist/wizard.js.map +1 -1
- package/docs/ARCHITECTURE.md +54 -9
- package/docs/OPENCODE_INSTALL.md +80 -19
- package/docs/QUICKSTART.md +145 -0
- package/docs/RELEASE.md +16 -15
- package/hooks/status.sh +14 -12
- package/hooks/stop.sh +47 -13
- package/hooks/verify-package.sh +36 -3
- package/package.json +25 -5
- package/plugins/autoresearch.ts +7 -0
- package/skills/hermes/INTEGRATION.md +156 -0
- package/skills/hermes/README.md +159 -0
- package/skills/hermes/autoresearch-prompt.md +270 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
### OpenCode
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g opencode-autoresearch
|
|
9
|
+
autoresearch doctor
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Hermes Agent
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# 1. Install the skill
|
|
16
|
+
git clone https://github.com/Maleick/AutoResearch.git
|
|
17
|
+
cd AutoResearch
|
|
18
|
+
npm install
|
|
19
|
+
mkdir -p ~/.hermes/skills/software-development/autoresearch
|
|
20
|
+
cp skills/hermes/autoresearch-prompt.md ~/.hermes/skills/software-development/autoresearch/SKILL.md
|
|
21
|
+
cp skills/hermes/INTEGRATION.md ~/.hermes/skills/software-development/autoresearch/REFERENCES.md
|
|
22
|
+
|
|
23
|
+
# 2. Create a cronjob
|
|
24
|
+
hermes cron create \
|
|
25
|
+
--name "autoresearch-loop" \
|
|
26
|
+
--workdir ~/projects/AutoResearch \
|
|
27
|
+
--skill autoresearch-hermes \
|
|
28
|
+
"every 15m" \
|
|
29
|
+
"Run AutoResearch iteration loop. Detect phase from .autoresearch/state.json and execute one phase. Approved verify command: 'npm run test:coverage'. Approved guard command: 'npm run typecheck'."
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Basic Usage
|
|
33
|
+
|
|
34
|
+
### 1. Initialize a run
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
autoresearch init \
|
|
38
|
+
--goal "Improve response time" \
|
|
39
|
+
--metric "response_time_ms" \
|
|
40
|
+
--direction "lower" \
|
|
41
|
+
--verify "npm test"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Check status
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
autoresearch status
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Record an iteration
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
autoresearch record \
|
|
54
|
+
--decision keep \
|
|
55
|
+
--metric-value "120" \
|
|
56
|
+
--verify-status pass \
|
|
57
|
+
--change-summary "Optimized database queries" \
|
|
58
|
+
--labels "perf,database"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 4. View history
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
autoresearch history
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 5. Complete the run
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
autoresearch complete
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Background Runs
|
|
74
|
+
|
|
75
|
+
For overnight or long-running improvements:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
autoresearch init \
|
|
79
|
+
--goal "Refactor codebase" \
|
|
80
|
+
--metric "complexity" \
|
|
81
|
+
--direction "lower" \
|
|
82
|
+
--verify "npm test" \
|
|
83
|
+
--mode background \
|
|
84
|
+
--iterations 20
|
|
85
|
+
|
|
86
|
+
autoresearch launch
|
|
87
|
+
# ... work on other things ...
|
|
88
|
+
autoresearch status
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Hermes Background Runs
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Initialize state from a trusted shell before enabling unattended cron
|
|
95
|
+
autoresearch init \
|
|
96
|
+
--goal "Improve test coverage" \
|
|
97
|
+
--metric "coverage_pct" \
|
|
98
|
+
--direction "higher" \
|
|
99
|
+
--verify "npm run test:coverage" \
|
|
100
|
+
--guard "npm run typecheck" \
|
|
101
|
+
--iterations 20 \
|
|
102
|
+
--mode background
|
|
103
|
+
|
|
104
|
+
# Start cron
|
|
105
|
+
hermes cron resume autoresearch-loop
|
|
106
|
+
|
|
107
|
+
# Check progress
|
|
108
|
+
cat .autoresearch/state.json | jq .
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Self-Improvement
|
|
112
|
+
|
|
113
|
+
Run AutoResearch on itself:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
autoresearch init \
|
|
117
|
+
--goal "Improve test coverage" \
|
|
118
|
+
--metric "test_count" \
|
|
119
|
+
--direction "higher" \
|
|
120
|
+
--verify "npm test" \
|
|
121
|
+
--mode background
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Shell Completion
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Bash
|
|
128
|
+
autoresearch completion --shell bash >> ~/.bashrc
|
|
129
|
+
|
|
130
|
+
# Zsh
|
|
131
|
+
autoresearch completion --shell zsh >> ~/.zshrc
|
|
132
|
+
|
|
133
|
+
# Fish
|
|
134
|
+
autoresearch completion --shell fish >> ~/.config/fish/completions/autoresearch.fish
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Exporting Results
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# JSON export
|
|
141
|
+
autoresearch export --format json > results.json
|
|
142
|
+
|
|
143
|
+
# Markdown report
|
|
144
|
+
autoresearch report > report.md
|
|
145
|
+
```
|
package/docs/RELEASE.md
CHANGED
|
@@ -4,7 +4,7 @@ This package uses npm publish for releases. GitHub Actions automates the full re
|
|
|
4
4
|
|
|
5
5
|
## Version Alignment
|
|
6
6
|
|
|
7
|
-
`VERSION`, `package.json`, `src/constants.ts`, and `.opencode-plugin/plugin.json` must all stay aligned. The `VERSION` file is the canonical source of truth.
|
|
7
|
+
`VERSION`, `package.json`, `package-lock.json`, `src/constants.ts`, and `.opencode-plugin/plugin.json` must all stay aligned. The `VERSION` file is the canonical source of truth.
|
|
8
8
|
|
|
9
9
|
## Release Steps
|
|
10
10
|
|
|
@@ -12,10 +12,10 @@ This package uses npm publish for releases. GitHub Actions automates the full re
|
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
# Update VERSION file
|
|
15
|
-
echo "3.
|
|
15
|
+
echo "3.3.3" > VERSION
|
|
16
16
|
|
|
17
17
|
# Sync to package.json
|
|
18
|
-
npm version 3.
|
|
18
|
+
npm version 3.3.3 --no-git-tag-version
|
|
19
19
|
|
|
20
20
|
# Sync to src/constants.ts
|
|
21
21
|
# Update the VERSION export manually or use sed
|
|
@@ -36,25 +36,24 @@ npm test
|
|
|
36
36
|
Add a new section for the version in `CHANGELOG.md`:
|
|
37
37
|
|
|
38
38
|
```markdown
|
|
39
|
-
## [3.
|
|
39
|
+
## [3.3.3] - YYYY-MM-DD
|
|
40
40
|
|
|
41
41
|
### Added
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- Enhanced subagent pool with meta-orchestrator role
|
|
42
|
+
- Root install handoff
|
|
43
|
+
- Public install verification notes
|
|
45
44
|
|
|
46
45
|
### Changed
|
|
47
|
-
-
|
|
48
|
-
-
|
|
46
|
+
- Installation docs
|
|
47
|
+
- Package verification allowlist
|
|
49
48
|
```
|
|
50
49
|
|
|
51
50
|
### 4. Commit and tag
|
|
52
51
|
|
|
53
52
|
```bash
|
|
54
53
|
git add -A
|
|
55
|
-
git commit -m "Release v3.
|
|
56
|
-
git tag v3.
|
|
57
|
-
git push origin main v3.
|
|
54
|
+
git commit -m "Release v3.3.3"
|
|
55
|
+
git tag v3.3.3
|
|
56
|
+
git push origin main v3.3.3
|
|
58
57
|
```
|
|
59
58
|
|
|
60
59
|
### 5. Automated release
|
|
@@ -64,8 +63,8 @@ GitHub Actions will:
|
|
|
64
63
|
1. Build and type-check
|
|
65
64
|
2. Verify package contents
|
|
66
65
|
3. Run tests
|
|
67
|
-
4. Create a GitHub Release with CHANGELOG section
|
|
68
|
-
5. Publish to npm
|
|
66
|
+
4. Create a GitHub Release with the CHANGELOG section
|
|
67
|
+
5. Publish to npm with provenance through trusted publishing
|
|
69
68
|
|
|
70
69
|
## Manual publish (fallback)
|
|
71
70
|
|
|
@@ -86,7 +85,9 @@ The shipped package includes:
|
|
|
86
85
|
- `commands/` — OpenCode command surfaces (`autoresearch.md`, `autoresearch/*.md`)
|
|
87
86
|
- `skills/autoresearch/` — Skill bundle with references
|
|
88
87
|
- `hooks/` — Shell hooks for session lifecycle
|
|
89
|
-
- `docs/` —
|
|
88
|
+
- selected `docs/` files — `ARCHITECTURE.md`, `OPENCODE_INSTALL.md`, `QUICKSTART.md`, `RELEASE.md`, documentation site assets, and `CNAME`
|
|
89
|
+
- `INSTALL.md` — Public raw OpenCode install handoff
|
|
90
|
+
- `.opencode/INSTALL.md` — OpenCode native plugin install guide
|
|
90
91
|
- `.opencode-plugin/plugin.json` — OpenCode plugin manifest
|
|
91
92
|
- `AGENTS.md` — Agent guide
|
|
92
93
|
- `VERSION` — Version marker
|
package/hooks/status.sh
CHANGED
|
@@ -7,18 +7,20 @@ set -e
|
|
|
7
7
|
STATUS_FILE="${AUTORESEARCH_STATE:-.autoresearch/state.json}"
|
|
8
8
|
|
|
9
9
|
if [ -f "$STATUS_FILE" ]; then
|
|
10
|
-
node --input-type=module -e
|
|
11
|
-
import { readFileSync } from
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
console.log(
|
|
16
|
-
console.log(
|
|
17
|
-
console.log(
|
|
18
|
-
console.log(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
AUTORESEARCH_STATUS_FILE="$STATUS_FILE" node --input-type=module -e '
|
|
11
|
+
import { readFileSync } from "fs";
|
|
12
|
+
const statusFile = process.env.AUTORESEARCH_STATUS_FILE;
|
|
13
|
+
if (!statusFile) throw new Error("Missing AUTORESEARCH_STATUS_FILE");
|
|
14
|
+
const s = JSON.parse(readFileSync(statusFile, "utf8"));
|
|
15
|
+
console.log("Auto Research run: " + s.run_id);
|
|
16
|
+
console.log("Status: " + s.status);
|
|
17
|
+
console.log("Mode: " + s.mode);
|
|
18
|
+
console.log("Goal: " + s.goal);
|
|
19
|
+
console.log("Iterations: " + s.stats.total_iterations);
|
|
20
|
+
console.log("Kept: " + s.stats.kept + " | Discarded: " + s.stats.discarded);
|
|
21
|
+
if (s.flags.needs_human) console.log("NEEDS HUMAN");
|
|
22
|
+
if (s.flags.stop_requested) console.log("STOP REQUESTED");
|
|
23
|
+
' 2>/dev/null || echo "No active run."
|
|
22
24
|
else
|
|
23
25
|
echo "No active run."
|
|
24
26
|
fi
|
package/hooks/stop.sh
CHANGED
|
@@ -5,24 +5,58 @@
|
|
|
5
5
|
set -e
|
|
6
6
|
|
|
7
7
|
STATUS_FILE="${AUTORESEARCH_STATE:-.autoresearch/state.json}"
|
|
8
|
+
WORKSPACE_ROOT="$(pwd -P)"
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
case "$STATUS_FILE" in
|
|
11
|
+
/*) STATUS_FILE_ABS="$STATUS_FILE" ;;
|
|
12
|
+
*) STATUS_FILE_ABS="$WORKSPACE_ROOT/$STATUS_FILE" ;;
|
|
13
|
+
esac
|
|
14
|
+
|
|
15
|
+
if [ -L "$STATUS_FILE_ABS" ]; then
|
|
16
|
+
echo "Refusing symlinked state file."
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
STATUS_DIR="${STATUS_FILE_ABS%/*}"
|
|
21
|
+
STATUS_NAME="${STATUS_FILE_ABS##*/}"
|
|
22
|
+
STATUS_DIR_REAL="$(cd "$STATUS_DIR" 2>/dev/null && pwd -P)" || {
|
|
23
|
+
echo "No active run."
|
|
24
|
+
exit 0
|
|
25
|
+
}
|
|
26
|
+
STATUS_FILE_REAL="$STATUS_DIR_REAL/$STATUS_NAME"
|
|
27
|
+
WORKSPACE_STATE_DIR="$WORKSPACE_ROOT/.autoresearch"
|
|
28
|
+
|
|
29
|
+
case "$STATUS_FILE_REAL" in
|
|
30
|
+
"$WORKSPACE_STATE_DIR"/*) ;;
|
|
31
|
+
*)
|
|
32
|
+
echo "Refusing state file outside workspace."
|
|
33
|
+
exit 0
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
|
|
37
|
+
if [ -f "$STATUS_FILE_ABS" ]; then
|
|
38
|
+
mode=$(AUTORESEARCH_STATUS_FILE="$STATUS_FILE_ABS" node --input-type=module -e '
|
|
39
|
+
import { readFileSync } from "fs";
|
|
40
|
+
const statusFile = process.env.AUTORESEARCH_STATUS_FILE;
|
|
41
|
+
if (!statusFile) throw new Error("Missing AUTORESEARCH_STATUS_FILE");
|
|
42
|
+
const s = JSON.parse(readFileSync(statusFile, "utf8"));
|
|
43
|
+
console.log(s.mode || "");
|
|
44
|
+
' 2>/dev/null || true)
|
|
15
45
|
if [ "$mode" = "background" ]; then
|
|
16
|
-
node --input-type=module -e
|
|
17
|
-
import { readFileSync, writeFileSync } from
|
|
18
|
-
const
|
|
46
|
+
AUTORESEARCH_STATUS_FILE="$STATUS_FILE_ABS" node --input-type=module -e '
|
|
47
|
+
import { readFileSync, renameSync, writeFileSync } from "fs";
|
|
48
|
+
const statusFile = process.env.AUTORESEARCH_STATUS_FILE;
|
|
49
|
+
if (!statusFile) throw new Error("Missing AUTORESEARCH_STATUS_FILE");
|
|
50
|
+
const s = JSON.parse(readFileSync(statusFile, "utf8"));
|
|
19
51
|
s.updated_at = new Date().toISOString();
|
|
20
52
|
s.flags.stop_requested = true;
|
|
21
53
|
s.flags.background_active = false;
|
|
22
|
-
s.status =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
54
|
+
s.status = "stopping";
|
|
55
|
+
const tmp = `${statusFile}.tmp.${process.pid}`;
|
|
56
|
+
writeFileSync(tmp, JSON.stringify(s, null, 2) + "\n", { mode: 0o600 });
|
|
57
|
+
renameSync(tmp, statusFile);
|
|
58
|
+
console.log("Stop requested for run: " + s.run_id);
|
|
59
|
+
' 2>/dev/null || echo "Could not update state."
|
|
26
60
|
else
|
|
27
61
|
echo "Only background runs can be stopped."
|
|
28
62
|
fi
|
package/hooks/verify-package.sh
CHANGED
|
@@ -16,17 +16,50 @@ const packResult = JSON.parse(raw);
|
|
|
16
16
|
const entries = Array.isArray(packResult) ? packResult : [packResult];
|
|
17
17
|
const files = entries.flatMap((entry) => Array.isArray(entry.files) ? entry.files : []);
|
|
18
18
|
|
|
19
|
-
const allowedRoots = new Set(["dist", "hooks", "commands", "skills", "
|
|
20
|
-
const allowedFiles = new Set([
|
|
19
|
+
const allowedRoots = new Set(["dist", "hooks", "commands", "skills", ".opencode-plugin"]);
|
|
20
|
+
const allowedFiles = new Set([
|
|
21
|
+
"package.json",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"AGENTS.md",
|
|
25
|
+
"VERSION",
|
|
26
|
+
"INSTALL.md",
|
|
27
|
+
".opencode/INSTALL.md",
|
|
28
|
+
"plugins/autoresearch.ts",
|
|
29
|
+
"docs/ARCHITECTURE.md",
|
|
30
|
+
"docs/autoresearch-loop.svg",
|
|
31
|
+
"docs/CNAME",
|
|
32
|
+
"docs/index.html",
|
|
33
|
+
"docs/OPENCODE_INSTALL.md",
|
|
34
|
+
"docs/QUICKSTART.md",
|
|
35
|
+
"docs/RELEASE.md",
|
|
36
|
+
]);
|
|
21
37
|
const requiredFiles = [
|
|
38
|
+
"INSTALL.md",
|
|
39
|
+
".opencode/INSTALL.md",
|
|
22
40
|
".opencode-plugin/plugin.json",
|
|
41
|
+
"AGENTS.md",
|
|
42
|
+
"dist/cli.js",
|
|
43
|
+
"dist/index.js",
|
|
44
|
+
"dist/index.d.ts",
|
|
23
45
|
"hooks/init.sh",
|
|
24
46
|
"skills/autoresearch/SKILL.md",
|
|
25
47
|
"commands/autoresearch.md",
|
|
26
48
|
];
|
|
27
49
|
|
|
28
50
|
const normalizePath = (filePath) => filePath.replace(/^package\//, "");
|
|
29
|
-
const
|
|
51
|
+
const forbiddenFiles = new Set([
|
|
52
|
+
"autoresearch-results.tsv",
|
|
53
|
+
"autoresearch-report.md",
|
|
54
|
+
"autoresearch-memory.md",
|
|
55
|
+
"autoresearch-hook-context.json",
|
|
56
|
+
]);
|
|
57
|
+
const isForbidden = (filePath) =>
|
|
58
|
+
filePath === ".autoresearch" ||
|
|
59
|
+
filePath.startsWith(".autoresearch/") ||
|
|
60
|
+
filePath === ".autoresearch-test-tmp" ||
|
|
61
|
+
filePath.startsWith(".autoresearch-test-tmp/") ||
|
|
62
|
+
forbiddenFiles.has(filePath);
|
|
30
63
|
const isAllowed = (filePath) => {
|
|
31
64
|
if (allowedFiles.has(filePath)) return true;
|
|
32
65
|
const [root] = filePath.split("/");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-autoresearch",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Autonomous recursive self-improvement engine for OpenCode. Subagent-first iteration loop with
|
|
3
|
+
"version": "3.4.0",
|
|
4
|
+
"description": "Autonomous recursive self-improvement engine for OpenCode and Hermes Agent. Subagent-first iteration loop with mechanical verification.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Maleick",
|
|
7
7
|
"url": "https://github.com/Maleick"
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"keywords": [
|
|
19
19
|
"opencode",
|
|
20
|
+
"hermes",
|
|
20
21
|
"plugin",
|
|
22
|
+
"agent",
|
|
21
23
|
"autoresearch",
|
|
22
24
|
"automation",
|
|
23
25
|
"workflows",
|
|
@@ -42,7 +44,16 @@
|
|
|
42
44
|
"hooks",
|
|
43
45
|
"commands",
|
|
44
46
|
"skills",
|
|
45
|
-
"
|
|
47
|
+
"plugins/autoresearch.ts",
|
|
48
|
+
"docs/ARCHITECTURE.md",
|
|
49
|
+
"docs/autoresearch-loop.svg",
|
|
50
|
+
"docs/CNAME",
|
|
51
|
+
"docs/index.html",
|
|
52
|
+
"docs/OPENCODE_INSTALL.md",
|
|
53
|
+
"docs/QUICKSTART.md",
|
|
54
|
+
"docs/RELEASE.md",
|
|
55
|
+
"INSTALL.md",
|
|
56
|
+
".opencode/INSTALL.md",
|
|
46
57
|
".opencode-plugin",
|
|
47
58
|
"AGENTS.md",
|
|
48
59
|
"VERSION",
|
|
@@ -52,14 +63,23 @@
|
|
|
52
63
|
"scripts": {
|
|
53
64
|
"build": "tsc",
|
|
54
65
|
"typecheck": "tsc --noEmit",
|
|
55
|
-
"
|
|
66
|
+
"audit": "npm audit --audit-level=moderate",
|
|
67
|
+
"test": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.config.json",
|
|
56
68
|
"verify:pack": "bash hooks/verify-package.sh",
|
|
57
|
-
"prepack": "tsc"
|
|
69
|
+
"prepack": "node scripts/sync-version.mjs && tsc"
|
|
58
70
|
},
|
|
59
71
|
"devDependencies": {
|
|
72
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
73
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
74
|
+
"@semantic-release/exec": "^7.1.0",
|
|
75
|
+
"@semantic-release/git": "^10.0.1",
|
|
76
|
+
"@semantic-release/github": "^12.0.6",
|
|
77
|
+
"@semantic-release/npm": "^13.1.5",
|
|
78
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
60
79
|
"@types/jest": "^30.0.0",
|
|
61
80
|
"@types/node": "^20.0.0",
|
|
62
81
|
"jest": "^30.3.0",
|
|
82
|
+
"semantic-release": "^25.0.3",
|
|
63
83
|
"ts-jest": "^29.4.9",
|
|
64
84
|
"typescript": "^5.9.3"
|
|
65
85
|
},
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# AutoResearch Hermes Integration
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
AutoResearch can run on Hermes Agent using `delegate_task` for subagent pools and `cronjob` for recurring iteration loops.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Hermes Cron (every 15m)
|
|
11
|
+
→ Check state.json for active run
|
|
12
|
+
→ If running: spawn subagents (Scout, Analyst, Verifier)
|
|
13
|
+
→ Each subagent performs one iteration phase
|
|
14
|
+
→ Verify results mechanically
|
|
15
|
+
→ Keep/Discard based on metrics
|
|
16
|
+
→ Update state.json
|
|
17
|
+
→ Repeat until stop condition
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Key Differences from OpenCode
|
|
21
|
+
|
|
22
|
+
| Feature | OpenCode | Hermes |
|
|
23
|
+
|---------|----------|--------|
|
|
24
|
+
| Entry | `/autoresearch` slash command | `cronjob` or `delegate_task` |
|
|
25
|
+
| Subagents | Standing pool | `delegate_task` batch (max 3) |
|
|
26
|
+
| State | `.autoresearch/state.json` | Same file + Hermes memory |
|
|
27
|
+
| Verification | `npm test`, etc. | Same — mechanical verification |
|
|
28
|
+
| Background | `autoresearch launch` | `cronjob` with `background=True` |
|
|
29
|
+
| Resume | `autoresearch resume` | Cron continues automatically |
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# 1. Install AutoResearch CLI (for state management)
|
|
35
|
+
npm install -g opencode-autoresearch
|
|
36
|
+
|
|
37
|
+
# 2. Create Hermes cron for AutoResearch
|
|
38
|
+
cd ~/projects/AutoResearch
|
|
39
|
+
hermes cron create \
|
|
40
|
+
--name "autoresearch-loop" \
|
|
41
|
+
--workdir ~/projects/AutoResearch \
|
|
42
|
+
--skill autoresearch-hermes \
|
|
43
|
+
"every 15m" \
|
|
44
|
+
"Run AutoResearch iteration loop. Detect phase from .autoresearch/state.json and execute one phase. Approved verify command is \`npm run test:coverage\` and approved guard command is \`npm run typecheck\`"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Hermes Prompt Template
|
|
48
|
+
|
|
49
|
+
See `skills/hermes/autoresearch-prompt.md` for the full cron prompt.
|
|
50
|
+
|
|
51
|
+
## Commands Mapping
|
|
52
|
+
|
|
53
|
+
| OpenCode Command | Hermes Equivalent |
|
|
54
|
+
|-----------------|-------------------|
|
|
55
|
+
| `/autoresearch` | Cron runs iteration loop |
|
|
56
|
+
| `/autoresearch:plan` | Subagent task: plan experiments |
|
|
57
|
+
| `/autoresearch:debug` | Subagent task: debug failures |
|
|
58
|
+
| `/autoresearch:fix` | Subagent task: fix issues |
|
|
59
|
+
| `/autoresearch:learn` | Memory tool + pattern analysis |
|
|
60
|
+
| `autoresearch init` | Manual setup (same CLI) |
|
|
61
|
+
| `autoresearch status` | `cat .autoresearch/state.json` |
|
|
62
|
+
| `autoresearch launch` | `hermes cron create` |
|
|
63
|
+
| `autoresearch stop` | `hermes cron pause` |
|
|
64
|
+
| `autoresearch resume` | `hermes cron resume` |
|
|
65
|
+
|
|
66
|
+
## State File Format
|
|
67
|
+
|
|
68
|
+
Hermes uses the same `.autoresearch/state.json` format as OpenCode:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"schema_version": 1,
|
|
73
|
+
"run_id": "2026-05-03-001",
|
|
74
|
+
"status": "initialized",
|
|
75
|
+
"mode": "background",
|
|
76
|
+
"goal": "Improve test coverage",
|
|
77
|
+
"metric": {
|
|
78
|
+
"name": "coverage_pct",
|
|
79
|
+
"direction": "higher",
|
|
80
|
+
"baseline": "72.4",
|
|
81
|
+
"best": "72.4",
|
|
82
|
+
"latest": "72.4"
|
|
83
|
+
},
|
|
84
|
+
"verify": "npm run test:coverage",
|
|
85
|
+
"guard": "npm run typecheck",
|
|
86
|
+
"stats": {
|
|
87
|
+
"total_iterations": 12,
|
|
88
|
+
"kept": 8,
|
|
89
|
+
"discarded": 4
|
|
90
|
+
},
|
|
91
|
+
"flags": {
|
|
92
|
+
"needs_human": false,
|
|
93
|
+
"stop_requested": false,
|
|
94
|
+
"background_active": true,
|
|
95
|
+
"stop_ready": false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Subagent Roles
|
|
101
|
+
|
|
102
|
+
### Scout
|
|
103
|
+
- **Goal**: Find improvement opportunities
|
|
104
|
+
- **Toolsets**: `["terminal", "file", "web"]`
|
|
105
|
+
- **Context**: Current codebase, test results, coverage reports
|
|
106
|
+
|
|
107
|
+
### Analyst
|
|
108
|
+
- **Goal**: Analyze patterns in kept/discarded iterations
|
|
109
|
+
- **Toolsets**: `["file", "web"]`
|
|
110
|
+
- **Context**: `autoresearch-results.tsv`, memory
|
|
111
|
+
|
|
112
|
+
### Verifier
|
|
113
|
+
- **Goal**: Run mechanical verification
|
|
114
|
+
- **Toolsets**: `["terminal"]`
|
|
115
|
+
- **Context**: Operator-approved verify command and guard command; repository state commands are metadata only
|
|
116
|
+
|
|
117
|
+
## Memory Integration
|
|
118
|
+
|
|
119
|
+
Hermes `memory` tool stores:
|
|
120
|
+
- Successful strategies per project type
|
|
121
|
+
- Common failure patterns
|
|
122
|
+
- Optimal iteration counts per goal type
|
|
123
|
+
- Best verify/guard command combinations
|
|
124
|
+
|
|
125
|
+
## Example Cron Prompt
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
You are AutoResearch running on Hermes Agent.
|
|
129
|
+
|
|
130
|
+
## Current Run
|
|
131
|
+
Run ID: {{run_id}}
|
|
132
|
+
Goal: {{goal}}
|
|
133
|
+
Metric: {{metric}}
|
|
134
|
+
Iteration: {{current}}/{{max}}
|
|
135
|
+
|
|
136
|
+
## Phase: {{phase}}
|
|
137
|
+
|
|
138
|
+
{{phase_instructions}}
|
|
139
|
+
|
|
140
|
+
## STOP after completing this phase.
|
|
141
|
+
Next cron run will continue with the next phase.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Limitations
|
|
145
|
+
|
|
146
|
+
- Hermes max 3 concurrent subagents vs OpenCode's standing pool
|
|
147
|
+
- Hermes cron intervals minimum 5 minutes vs OpenCode's real-time
|
|
148
|
+
- No `/autoresearch:` slash command variants (use separate cron jobs)
|
|
149
|
+
- Memory is session-based; use `memory` tool for persistence
|
|
150
|
+
- Commits and destructive rollback require explicit user approval
|
|
151
|
+
|
|
152
|
+
## Future Enhancements
|
|
153
|
+
|
|
154
|
+
- [ ] Auto-detect optimal cron interval based on iteration duration
|
|
155
|
+
- [ ] Integration with Hermes checkpoint/rollback for safe resets
|
|
156
|
+
- [ ] Cross-session memory for strategy learning
|