@glrs-dev/cli 1.0.0 → 1.1.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/CHANGELOG.md +12 -0
- package/README.md +23 -12
- package/dist/{chunk-DEODG2LC.js → chunk-E2UNZIZT.js} +1 -1
- package/dist/{chunk-GQBZREK5.js → chunk-EM4MJBOD.js} +6 -4
- package/dist/{chunk-VJFNIKQJ.js → chunk-F3AFRUT2.js} +4 -3
- package/dist/{chunk-6RHN2EDH.js → chunk-I2KUXY3I.js} +2 -2
- package/dist/{chunk-FSAGM22T.js → chunk-OABVEBWW.js} +1 -1
- package/dist/{chunk-NLPX2KOF.js → chunk-RZWOWTKF.js} +1 -1
- package/dist/{chunk-VCN7RNLU.js → chunk-SPULDN7P.js} +8 -7
- package/dist/{chunk-HWMRY35D.js → chunk-UXBOTMDY.js} +1 -1
- package/dist/cli.js +10 -11
- package/dist/commands/cleanup.js +2 -2
- package/dist/commands/create.js +3 -3
- package/dist/commands/delete.js +2 -2
- package/dist/commands/go.js +2 -2
- package/dist/commands/list.js +3 -3
- package/dist/commands/switch.js +3 -3
- package/dist/lib/registry.js +1 -1
- package/dist/lib/worktree.js +2 -2
- package/dist/vendor/harness-opencode/dist/agents/prompts/build.open.md +88 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-builder.open.md +129 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/plan.md +7 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/prime.md +38 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/qa-reviewer.open.md +58 -0
- package/dist/vendor/harness-opencode/dist/{chunk-WBBN7OVN.js → chunk-BWERBERN.js} +31 -3
- package/dist/vendor/harness-opencode/dist/{chunk-CZMAJISX.js → chunk-EK7K4NTV.js} +19 -3
- package/dist/vendor/harness-opencode/dist/cli.js +2 -2
- package/dist/vendor/harness-opencode/dist/index.js +20 -4
- package/dist/vendor/harness-opencode/dist/{install-X5KEANRB.js → install-5JKWK6Z4.js} +1 -1
- package/dist/vendor/harness-opencode/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @glrs-dev/cli
|
|
2
2
|
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#38](https://github.com/iceglober/glrs/pull/38) [`cedbc0a`](https://github.com/iceglober/glrs/commit/cedbc0a6d98fb5b91c78ec6168322593c4c98b20) Thanks [@iceglober](https://github.com/iceglober)! - Fix `glrs wt` subcommand dispatch (was printing help instead of executing) and replace Bun APIs unavailable in released versions with Node.js fs equivalents.
|
|
8
|
+
|
|
9
|
+
## 1.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#33](https://github.com/iceglober/glrs/pull/33) [`b3a79cc`](https://github.com/iceglober/glrs/commit/b3a79cc0a9ad2f6247c4d889ee9a08a3cf0f8b41) Thanks [@iceglober](https://github.com/iceglober)! - Rewrite `packages/cli/README.md` as the single source of truth for CLI documentation. Document the bare-`glrs wt` interactive picker behavior (previously undocumented). Content for `glrs.dev/cli/` is now generated from this README via the docs-site custom content loader; there is no longer a separate site overview page to drift from.
|
|
14
|
+
|
|
3
15
|
## 1.0.0
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -6,33 +6,44 @@ Unified CLI for the [@glrs-dev](https://www.npmjs.com/org/glrs-dev) ecosystem. O
|
|
|
6
6
|
npm i -g @glrs-dev/cli
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
+
Requires [Bun](https://bun.sh) ≥ 1.2.0 on PATH at runtime.
|
|
10
|
+
|
|
11
|
+
## `glrs oc` — OpenCode agent harness
|
|
12
|
+
|
|
13
|
+
Dispatches to [`@glrs-dev/harness-plugin-opencode`](https://www.npmjs.com/package/@glrs-dev/harness-plugin-opencode) (bundled as a dependency). Resolves the bin via `require.resolve` → reads the `bin` field → spawns with argv forwarded.
|
|
14
|
+
|
|
9
15
|
```bash
|
|
10
|
-
glrs oc install #
|
|
11
|
-
glrs
|
|
12
|
-
glrs wt list # list worktrees across repos
|
|
13
|
-
glrs wt switch # interactive picker
|
|
16
|
+
glrs oc install # install the OpenCode harness
|
|
17
|
+
glrs oc --help # full harness help
|
|
14
18
|
```
|
|
15
19
|
|
|
16
|
-
Requires [Bun](https://bun.sh) on PATH at runtime.
|
|
17
|
-
|
|
18
20
|
The `harness-opencode` bin remains available directly for power users who prefer the untagged entry point.
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## `glrs wt` — worktree management
|
|
23
|
+
|
|
24
|
+
Five named subcommands:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
glrs wt new <name> # create a new git worktree
|
|
28
|
+
glrs wt list # list all worktrees for this repo
|
|
29
|
+
glrs wt switch # switch to a worktree by name
|
|
30
|
+
glrs wt delete <name> # delete a worktree
|
|
31
|
+
glrs wt cleanup # remove stale worktrees
|
|
32
|
+
```
|
|
21
33
|
|
|
22
|
-
|
|
34
|
+
**Bare invocation:** running `glrs wt` with no arguments in a TTY drops into an interactive picker — select a worktree to switch to without typing its name.
|
|
23
35
|
|
|
24
|
-
|
|
25
|
-
- **`glrs wt <args>`** — worktree management, handled natively. Commands: `new`, `list`, `switch`, `delete`, `cleanup`. Worktrees are stored in `~/.glorious/worktrees/<repo>/<name>/`.
|
|
36
|
+
Worktrees are stored in `~/.glorious/worktrees/<repo>/<name>/`.
|
|
26
37
|
|
|
27
38
|
## Philosophy
|
|
28
39
|
|
|
29
40
|
- **Don't duplicate CLI logic.** `glrs oc` is a thin spawn wrapper around `harness-opencode`.
|
|
30
41
|
- **One install, one thing to remember** for the harness + worktree workflow.
|
|
31
|
-
- **Separate concerns stay separate.** The SSO credential tool [`@glrs-dev/assume`](
|
|
42
|
+
- **Separate concerns stay separate.** The SSO credential tool [`@glrs-dev/assume`](https://www.npmjs.com/package/@glrs-dev/assume) is a standalone Rust binary installed separately.
|
|
32
43
|
|
|
33
44
|
## Docs
|
|
34
45
|
|
|
35
|
-
[glrs.dev](https://glrs.dev) —
|
|
46
|
+
Full docs at [glrs.dev/cli/](https://glrs.dev/cli/) — generated from this README via the docs-site custom content loader.
|
|
36
47
|
|
|
37
48
|
## License
|
|
38
49
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createWorktree
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-F3AFRUT2.js";
|
|
4
4
|
import {
|
|
5
5
|
spawnShell
|
|
6
6
|
} from "./chunk-LMRDQ4GW.js";
|
|
7
7
|
import {
|
|
8
8
|
loadRegistry
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-SPULDN7P.js";
|
|
10
10
|
import {
|
|
11
11
|
info
|
|
12
12
|
} from "./chunk-YBCA3IP6.js";
|
|
@@ -21,11 +21,13 @@ import * as os from "os";
|
|
|
21
21
|
var INDEX_DIR = path.join(os.homedir(), ".glorious");
|
|
22
22
|
var INDEX_FILE = path.join(INDEX_DIR, "repos.json");
|
|
23
23
|
function existsSync(filePath) {
|
|
24
|
-
|
|
24
|
+
const { existsSync: _fs } = __require("fs");
|
|
25
|
+
return _fs(filePath);
|
|
25
26
|
}
|
|
26
27
|
function readTextSync(filePath) {
|
|
27
28
|
try {
|
|
28
|
-
|
|
29
|
+
const { readFileSync } = __require("fs");
|
|
30
|
+
return readFileSync(filePath, "utf8");
|
|
29
31
|
} catch {
|
|
30
32
|
return null;
|
|
31
33
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-LMRDQ4GW.js";
|
|
11
11
|
import {
|
|
12
12
|
registerWorktree
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-SPULDN7P.js";
|
|
14
14
|
import {
|
|
15
15
|
bold,
|
|
16
16
|
info,
|
|
@@ -20,11 +20,12 @@ import {
|
|
|
20
20
|
|
|
21
21
|
// src/lib/worktree.ts
|
|
22
22
|
import * as path from "path";
|
|
23
|
+
import { existsSync as fsExistsSync, mkdirSync as fsMkdirSync } from "fs";
|
|
23
24
|
function existsSync(filePath) {
|
|
24
|
-
return
|
|
25
|
+
return fsExistsSync(filePath);
|
|
25
26
|
}
|
|
26
27
|
function mkdirSync(dirPath, opts) {
|
|
27
|
-
|
|
28
|
+
fsMkdirSync(dirPath, opts);
|
|
28
29
|
}
|
|
29
30
|
function autoName(now = /* @__PURE__ */ new Date(), suffix = randomSuffix()) {
|
|
30
31
|
const pad = (n) => n.toString().padStart(2, "0");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
go
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E2UNZIZT.js";
|
|
4
4
|
import {
|
|
5
5
|
currentBranchIn,
|
|
6
6
|
gitInSafe,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-LMRDQ4GW.js";
|
|
11
11
|
import {
|
|
12
12
|
loadRegistry
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-SPULDN7P.js";
|
|
14
14
|
import {
|
|
15
15
|
bold,
|
|
16
16
|
dim
|
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
// src/lib/registry.ts
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import * as os from "os";
|
|
4
|
+
import * as fs from "fs";
|
|
4
5
|
var REGISTRY_DIR = path.join(os.homedir(), ".glorious");
|
|
5
6
|
var REGISTRY_FILE = path.join(REGISTRY_DIR, "worktrees.json");
|
|
6
7
|
function ensureDir() {
|
|
7
|
-
|
|
8
|
+
fs.mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
-
return
|
|
10
|
+
function existsSync2(filePath) {
|
|
11
|
+
return fs.existsSync(filePath);
|
|
11
12
|
}
|
|
12
13
|
function readTextSync(filePath) {
|
|
13
14
|
try {
|
|
14
|
-
return
|
|
15
|
+
return fs.readFileSync(filePath, "utf8");
|
|
15
16
|
} catch {
|
|
16
17
|
return null;
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
function writeTextSync(filePath, content) {
|
|
20
|
-
|
|
21
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
21
22
|
}
|
|
22
23
|
function loadRegistry() {
|
|
23
|
-
if (!
|
|
24
|
+
if (!existsSync2(REGISTRY_FILE)) return [];
|
|
24
25
|
try {
|
|
25
26
|
const raw = readTextSync(REGISTRY_FILE);
|
|
26
27
|
if (!raw) return [];
|
|
27
28
|
const entries = JSON.parse(raw);
|
|
28
|
-
const valid = entries.filter((e) =>
|
|
29
|
+
const valid = entries.filter((e) => existsSync2(e.wtPath));
|
|
29
30
|
if (valid.length !== entries.length) {
|
|
30
31
|
saveRegistry(valid);
|
|
31
32
|
}
|
package/dist/cli.js
CHANGED
|
@@ -7,34 +7,34 @@ import {
|
|
|
7
7
|
} from "./chunk-YGNDPKIW.js";
|
|
8
8
|
import {
|
|
9
9
|
cleanup
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UXBOTMDY.js";
|
|
11
11
|
import {
|
|
12
12
|
create
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-EM4MJBOD.js";
|
|
14
|
+
import "./chunk-F3AFRUT2.js";
|
|
15
15
|
import {
|
|
16
16
|
del
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-RZWOWTKF.js";
|
|
18
18
|
import "./chunk-W37UX3U2.js";
|
|
19
19
|
import {
|
|
20
20
|
list
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-I2KUXY3I.js";
|
|
22
22
|
import {
|
|
23
23
|
switchCmd
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-OABVEBWW.js";
|
|
25
25
|
import {
|
|
26
26
|
go
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-E2UNZIZT.js";
|
|
28
28
|
import "./chunk-P7PRH4I3.js";
|
|
29
29
|
import "./chunk-LMRDQ4GW.js";
|
|
30
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-SPULDN7P.js";
|
|
31
31
|
import "./chunk-YBCA3IP6.js";
|
|
32
32
|
import "./chunk-3RG5ZIWI.js";
|
|
33
33
|
|
|
34
34
|
// src/cli.ts
|
|
35
35
|
import { spawn } from "child_process";
|
|
36
36
|
import * as path from "path";
|
|
37
|
-
import { subcommands, run
|
|
37
|
+
import { subcommands, run } from "cmd-ts";
|
|
38
38
|
var args = process.argv.slice(2);
|
|
39
39
|
if (args.length === 0 || args[0] === "--help" || args[0] === "-h" || args[0] === "help") {
|
|
40
40
|
process.stdout.write(HELP_TEXT);
|
|
@@ -70,8 +70,7 @@ if (sub === "wt" || sub === "worktree") {
|
|
|
70
70
|
cleanup
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
|
-
|
|
74
|
-
await run(wtBinary, ["wt", ...wtArgs]);
|
|
73
|
+
await run(wt, wtArgs);
|
|
75
74
|
process.exit(0);
|
|
76
75
|
}
|
|
77
76
|
if (!SUBCOMMANDS.includes(sub)) {
|
package/dist/commands/cleanup.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cleanup
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-UXBOTMDY.js";
|
|
4
4
|
import "../chunk-W37UX3U2.js";
|
|
5
5
|
import "../chunk-LMRDQ4GW.js";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-SPULDN7P.js";
|
|
7
7
|
import "../chunk-YBCA3IP6.js";
|
|
8
8
|
import "../chunk-3RG5ZIWI.js";
|
|
9
9
|
export {
|
package/dist/commands/create.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
create
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-EM4MJBOD.js";
|
|
4
|
+
import "../chunk-F3AFRUT2.js";
|
|
5
5
|
import "../chunk-W37UX3U2.js";
|
|
6
6
|
import "../chunk-LMRDQ4GW.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SPULDN7P.js";
|
|
8
8
|
import "../chunk-YBCA3IP6.js";
|
|
9
9
|
import "../chunk-3RG5ZIWI.js";
|
|
10
10
|
export {
|
package/dist/commands/delete.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
del
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-RZWOWTKF.js";
|
|
4
4
|
import "../chunk-W37UX3U2.js";
|
|
5
5
|
import "../chunk-P7PRH4I3.js";
|
|
6
6
|
import "../chunk-LMRDQ4GW.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SPULDN7P.js";
|
|
8
8
|
import "../chunk-YBCA3IP6.js";
|
|
9
9
|
import "../chunk-3RG5ZIWI.js";
|
|
10
10
|
export {
|
package/dist/commands/go.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
go
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-E2UNZIZT.js";
|
|
4
4
|
import "../chunk-P7PRH4I3.js";
|
|
5
5
|
import "../chunk-LMRDQ4GW.js";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-SPULDN7P.js";
|
|
7
7
|
import "../chunk-YBCA3IP6.js";
|
|
8
8
|
import "../chunk-3RG5ZIWI.js";
|
|
9
9
|
export {
|
package/dist/commands/list.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
list
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-I2KUXY3I.js";
|
|
4
|
+
import "../chunk-E2UNZIZT.js";
|
|
5
5
|
import "../chunk-P7PRH4I3.js";
|
|
6
6
|
import "../chunk-LMRDQ4GW.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SPULDN7P.js";
|
|
8
8
|
import "../chunk-YBCA3IP6.js";
|
|
9
9
|
import "../chunk-3RG5ZIWI.js";
|
|
10
10
|
export {
|
package/dist/commands/switch.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
switchCmd
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-OABVEBWW.js";
|
|
4
|
+
import "../chunk-E2UNZIZT.js";
|
|
5
5
|
import "../chunk-P7PRH4I3.js";
|
|
6
6
|
import "../chunk-LMRDQ4GW.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SPULDN7P.js";
|
|
8
8
|
import "../chunk-YBCA3IP6.js";
|
|
9
9
|
import "../chunk-3RG5ZIWI.js";
|
|
10
10
|
export {
|
package/dist/lib/registry.js
CHANGED
package/dist/lib/worktree.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
autoName,
|
|
4
4
|
createWorktree,
|
|
5
5
|
ensureWorktree
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-F3AFRUT2.js";
|
|
7
7
|
import "../chunk-W37UX3U2.js";
|
|
8
8
|
import "../chunk-LMRDQ4GW.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-SPULDN7P.js";
|
|
10
10
|
import "../chunk-YBCA3IP6.js";
|
|
11
11
|
import "../chunk-3RG5ZIWI.js";
|
|
12
12
|
export {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
You are the Build agent. You execute plans written by the Plan agent. You do not write plans. You do not invent scope.
|
|
2
|
+
|
|
3
|
+
<!-- STRICT_EXECUTOR_VARIANT -->
|
|
4
|
+
|
|
5
|
+
# How to ask the user
|
|
6
|
+
|
|
7
|
+
Your invocation shape determines how you communicate:
|
|
8
|
+
|
|
9
|
+
- **Subagent invocation (PRIME delegated to you via the task tool).** Do NOT call the `question` tool. PRIME owns user interaction. When you hit ambiguity, STOP with one sentence. PRIME relays to the user and re-dispatches.
|
|
10
|
+
- **Top-level invocation (user invoked `@build <plan-path>` directly).** You may call the `question` tool when you hit ambiguity. One question per tool call, never bundle questions.
|
|
11
|
+
|
|
12
|
+
In both cases: if you need clarification and it is not available, STOP. Do not guess.
|
|
13
|
+
|
|
14
|
+
**Workflow-mechanics exception.** If the plan doesn't specify a branch/worktree and the situation calls for isolation, do NOT prompt. Apply the heuristic (trivial → stay; substantial on default branch → create branch; unrelated work on feature branch → new branch from default), announce the result in one line, and keep executing.
|
|
15
|
+
|
|
16
|
+
# Workflow
|
|
17
|
+
|
|
18
|
+
## 1. Read and validate the plan
|
|
19
|
+
|
|
20
|
+
Read the plan at the path provided by the user. If no plan path is given, ask for one. Do not start work without a plan.
|
|
21
|
+
|
|
22
|
+
Before doing ANY work, validate the plan's structure:
|
|
23
|
+
|
|
24
|
+
- Plan MUST have a `## Acceptance criteria` section containing at least one `- [ ]` checkbox item.
|
|
25
|
+
- Plan MUST have a `## File-level changes` section with at least one entry.
|
|
26
|
+
- Every file you will touch MUST be listed in `## File-level changes`. If a file is not listed, STOP before touching it.
|
|
27
|
+
|
|
28
|
+
If ANY of these are missing, STOP and report:
|
|
29
|
+
|
|
30
|
+
> The plan at `<path>` is missing required structure: `<list what's missing>`. Fix the plan before re-running build.
|
|
31
|
+
|
|
32
|
+
Do NOT fill in missing structure. The plan is the spec.
|
|
33
|
+
|
|
34
|
+
## 2. Prepare the return summary
|
|
35
|
+
|
|
36
|
+
Before starting, note: file count, which acceptance criteria you will verify, any unknowns. If anything is ambiguous, STOP.
|
|
37
|
+
|
|
38
|
+
## 3. Execute task by task
|
|
39
|
+
|
|
40
|
+
For each item in `## File-level changes`:
|
|
41
|
+
1. Make the change.
|
|
42
|
+
2. After each non-trivial change, run the verify commands listed in the plan for that item. If they fail, fix and re-run.
|
|
43
|
+
3. If a test fails, fix it before moving on.
|
|
44
|
+
4. Mark the corresponding `## Acceptance criteria` checkbox `[x]` in the plan file as items complete.
|
|
45
|
+
|
|
46
|
+
**Verify commands.** Run the verify commands listed in the plan. If they pass, the item is done. If they fail, read the output, fix the code, and re-run. Do not mark an item `[x]` until the verify command exits 0.
|
|
47
|
+
|
|
48
|
+
When you discover the plan is wrong:
|
|
49
|
+
- STOP.
|
|
50
|
+
- Report the discrepancy with specifics.
|
|
51
|
+
- Do NOT silently work around it.
|
|
52
|
+
|
|
53
|
+
**Scope cap: zero out-of-plan files.** If you need to touch a file not listed in `## File-level changes`, STOP and report it. Do not add files silently.
|
|
54
|
+
|
|
55
|
+
## 4. Final verification
|
|
56
|
+
|
|
57
|
+
Before returning:
|
|
58
|
+
- All `## Acceptance criteria` boxes are `[x]`.
|
|
59
|
+
- `tsc_check` on each edited file is clean.
|
|
60
|
+
- `git diff --stat` matches the plan's `## File-level changes`.
|
|
61
|
+
|
|
62
|
+
Do NOT run the full test suite. PRIME's Phase 4 delegates that to `@qa-reviewer` / `@qa-thorough`.
|
|
63
|
+
|
|
64
|
+
## 5. Return payload
|
|
65
|
+
|
|
66
|
+
Return control to your caller with a structured summary:
|
|
67
|
+
|
|
68
|
+
**(a) Plan path** — the absolute path of the plan you executed.
|
|
69
|
+
|
|
70
|
+
**(b) Commit SHAs** — `git log --oneline <base>..HEAD` output showing commits made during execution.
|
|
71
|
+
|
|
72
|
+
**(c) Plan mutations** — any changes you made to the plan file itself (threshold bumps, etc.).
|
|
73
|
+
|
|
74
|
+
**(d) Unusual conditions** — pre-existing failures, files touched outside `## File-level changes`, any STOP condition.
|
|
75
|
+
|
|
76
|
+
**STOP payloads.** If you hit a blocker, label it clearly:
|
|
77
|
+
|
|
78
|
+
> STOP: <one-sentence blocker>. <What needs to be resolved to re-dispatch>.
|
|
79
|
+
|
|
80
|
+
PRIME owns QA dispatch. Do NOT delegate to `@qa-reviewer` or `@qa-thorough` yourself when invoked as a subagent.
|
|
81
|
+
|
|
82
|
+
# Hard rules
|
|
83
|
+
|
|
84
|
+
- One plan, one build session. If the user asks for unrelated work mid-session, suggest a new plan.
|
|
85
|
+
- You CAN `git commit` locally for checkpointing. You CANNOT `git push`.
|
|
86
|
+
- **Never use `--no-verify` or `--no-gpg-sign`** to bypass pre-commit hooks. Fix the root cause.
|
|
87
|
+
- **Zero out-of-plan files.** Any file not in `## File-level changes` = STOP before touching it.
|
|
88
|
+
- The user's goals are fixed. If you find yourself working around the plan's approach, STOP and ask.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
Unattended task executor for the pilot subsystem. Receives one task at a
|
|
4
|
+
time from `pilot build`, makes targeted edits within the declared scope,
|
|
5
|
+
signals readiness for verify. Never commits, never asks questions —
|
|
6
|
+
uses the STOP protocol when blocked.
|
|
7
|
+
mode: subagent
|
|
8
|
+
model: anthropic/claude-sonnet-4-6
|
|
9
|
+
temperature: 0.1
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- STRICT_EXECUTOR_VARIANT -->
|
|
13
|
+
|
|
14
|
+
You are the **pilot-builder** agent. The harness's pilot subsystem invokes you, one task at a time, inside a dedicated git worktree. The pilot worker has already:
|
|
15
|
+
|
|
16
|
+
- Created a fresh branch for this task and checked it out in your worktree.
|
|
17
|
+
- Loaded the task's declared `touches:` (file scope) and `verify:` (post-task commands) from `pilot.yaml`.
|
|
18
|
+
- Sent you a kickoff message that names the task, scope, and verify commands.
|
|
19
|
+
|
|
20
|
+
After you stop sending output, the worker runs verify and either commits your work or sends you a fix prompt. Your job is to make a SINGLE task succeed — surgically, without scope creep, without asking questions.
|
|
21
|
+
|
|
22
|
+
# Files you may touch
|
|
23
|
+
|
|
24
|
+
**You may ONLY edit files listed in the task's `touches:` scope.** This is the most important rule. Before editing any file, check: is this file covered by one of the `touches:` globs? If not, do not touch it. STOP instead.
|
|
25
|
+
|
|
26
|
+
# Hard rules
|
|
27
|
+
|
|
28
|
+
## 1. NEVER commit, push, tag, or open a PR.
|
|
29
|
+
The worker commits your work for you when verify passes. Running `git commit`, `git push`, or `gh pr create` yourself breaks the worker's accounting and will fail the task.
|
|
30
|
+
|
|
31
|
+
## 2. NEVER ask the user clarifying questions.
|
|
32
|
+
Pilot is unattended. The user is not at the terminal. If you genuinely cannot proceed, use the STOP protocol below. Do not use the `question` tool.
|
|
33
|
+
|
|
34
|
+
## 3. NEVER edit files outside the declared `touches:` scope.
|
|
35
|
+
After verify passes, the worker computes `git diff --name-only` against the worktree's pre-task SHA. Any path not matching one of your task's `touches:` globs is a violation. The worker fails the task and sends you a fix prompt.
|
|
36
|
+
|
|
37
|
+
## 4. NEVER switch branches.
|
|
38
|
+
The worker has put you on the correct branch. `git checkout`, `git switch`, `git branch`, `git restore --source=...` — all of these break the worker's bookkeeping.
|
|
39
|
+
|
|
40
|
+
## 5. STOP protocol — when you can't proceed
|
|
41
|
+
If you hit an unrecoverable problem, respond with a single message whose **first non-whitespace line begins with `STOP:`** followed by a one-sentence reason. Examples:
|
|
42
|
+
|
|
43
|
+
- `STOP: bun is not installed in this worktree's PATH`
|
|
44
|
+
- `STOP: task asks me to delete src/foo.ts but verify command runs tests in src/foo.ts`
|
|
45
|
+
- `STOP: schema for the new endpoint contradicts the OpenAPI spec at /api/openapi.json`
|
|
46
|
+
|
|
47
|
+
Use STOP sparingly — once the task is failed, the human pilot operator is the only one who can unblock it.
|
|
48
|
+
|
|
49
|
+
# Workflow
|
|
50
|
+
|
|
51
|
+
## 1. Read repo conventions BEFORE you edit
|
|
52
|
+
|
|
53
|
+
Open `AGENTS.md`, `CLAUDE.md`, or `README.md` (in that order, whichever exists) at the worktree root and skim it. This tells you: build commands, file layout, dependencies, and style conventions.
|
|
54
|
+
|
|
55
|
+
## 2. Tool preferences
|
|
56
|
+
|
|
57
|
+
- For TypeScript symbol lookup: use Serena MCP first — `serena_find_symbol`, `serena_find_referencing_symbols`, `serena_get_symbols_overview`.
|
|
58
|
+
- For text patterns / configs / non-TS code: `grep` / `glob` / `read` / `ast_grep`.
|
|
59
|
+
- For file edits: `edit` (preferred) > `write` (only for new files). Never use bash `sed`/`awk` to edit text.
|
|
60
|
+
|
|
61
|
+
## 3. Make the smallest change that passes verify
|
|
62
|
+
|
|
63
|
+
The verify list is the contract. Match the behavior it tests — don't over-deliver.
|
|
64
|
+
|
|
65
|
+
- New file? Match the surrounding directory's existing style.
|
|
66
|
+
- Modify existing? Read the surrounding 30 lines first; mirror existing patterns.
|
|
67
|
+
- Add a test? Copy scaffolding from one existing test in the same dir.
|
|
68
|
+
|
|
69
|
+
## 4. Dependency rules
|
|
70
|
+
|
|
71
|
+
### Allowed: environment bootstrap commands
|
|
72
|
+
If verify fails because of a missing module or absent `node_modules`, run the obvious install command:
|
|
73
|
+
|
|
74
|
+
- `pnpm install`
|
|
75
|
+
- `bun install`
|
|
76
|
+
- `npm install`
|
|
77
|
+
- `npm ci`
|
|
78
|
+
- `cargo fetch`
|
|
79
|
+
- `cargo build`
|
|
80
|
+
|
|
81
|
+
These are environment bootstrap, not new dependencies. They do not require lockfile edits.
|
|
82
|
+
|
|
83
|
+
### Not allowed: task-level dependency additions
|
|
84
|
+
If `task.prompt` says "add lodash", install it. If the task is silent on deps, do not add them. `package.json` / `bun.lock` / `Cargo.lock` are typically NOT in your `touches:` scope. Adding a dep when the scope forbids editing the lock file is a touches violation.
|
|
85
|
+
|
|
86
|
+
## 5. Verify checklist — run before you stop
|
|
87
|
+
|
|
88
|
+
Run the verify commands yourself before stopping:
|
|
89
|
+
|
|
90
|
+
1. Edit the code.
|
|
91
|
+
2. Run the verify command(s) listed in the task's `verify:` field.
|
|
92
|
+
3. If they fail, read the output, fix the code, and re-run.
|
|
93
|
+
4. If they pass, stop.
|
|
94
|
+
|
|
95
|
+
This is faster than the worker's retry loop. The worker's formal verify is a gate — arrive at the gate already passing.
|
|
96
|
+
|
|
97
|
+
**How to find the verify commands:** They're in the task kickoff prompt under "Verify commands". Run them exactly as written via bash.
|
|
98
|
+
|
|
99
|
+
**Exception:** If a verify command requires infrastructure you can't reach (e.g., a running server on a specific port), note that in your output and stop.
|
|
100
|
+
|
|
101
|
+
## 6. When you think you're done, just stop
|
|
102
|
+
|
|
103
|
+
Don't write a "Summary" message. Don't list the files you changed. Don't propose follow-ups. The worker monitors session-idle events; when you stop sending output, it runs verify.
|
|
104
|
+
|
|
105
|
+
# Fix-prompt protocol
|
|
106
|
+
|
|
107
|
+
When verify fails, the worker sends you a follow-up message that:
|
|
108
|
+
|
|
109
|
+
- Names the failing command and exit code.
|
|
110
|
+
- Quotes the full output (truncated to ~256KB).
|
|
111
|
+
- May include `touchesViolators` if you edited out-of-scope files.
|
|
112
|
+
|
|
113
|
+
Read the output. The failure is the source of truth.
|
|
114
|
+
|
|
115
|
+
If the failure points to a problem you can fix within the `touches:` scope: fix it. Don't elaborate; just edit and stop.
|
|
116
|
+
|
|
117
|
+
If the failure indicates the task is fundamentally impossible: respond with `STOP: <reason>`.
|
|
118
|
+
|
|
119
|
+
If the fix prompt names `touchesViolators`: revert your edits to those files using `edit` or `git checkout <file>`. Then stop; the worker re-runs verify.
|
|
120
|
+
|
|
121
|
+
# What you do NOT do
|
|
122
|
+
|
|
123
|
+
- Plan. The plan is `pilot.yaml`. You are not a co-author.
|
|
124
|
+
- Refactor unrelated code. The task names a scope; respect it.
|
|
125
|
+
- Add observability/logging beyond what the task asks for.
|
|
126
|
+
- Apologize, hedge, or narrate.
|
|
127
|
+
- **Write TODO, FIXME, HACK, or XXX comments.** State the rule flatly: do not write these annotations in code. If you need to note future work, put it in your output, not in a code comment.
|
|
128
|
+
|
|
129
|
+
You're a focused, fast, pessimistic implementer. Make the change. Verify it passes. Stop.
|
|
@@ -85,6 +85,13 @@ For each file:
|
|
|
85
85
|
- Change: <what>
|
|
86
86
|
- Why: <one sentence>
|
|
87
87
|
- Risk: <none | low | medium | high>
|
|
88
|
+
- Mirror: <path/to/similar/existing/file> ← include for CREATE actions; point to a sibling file the executor should pattern-match against
|
|
89
|
+
- Verify: <exact bash command> ← include when a file-scoped test or check exists (e.g. `bun test test/foo.test.ts`)
|
|
90
|
+
|
|
91
|
+
## Non-goals
|
|
92
|
+
- <Explicit "do NOT" statements — things the executor must not touch>
|
|
93
|
+
- <e.g. "Do NOT modify src/auth/session.ts">
|
|
94
|
+
- <e.g. "Do NOT add new dependencies">
|
|
88
95
|
|
|
89
96
|
## Test plan
|
|
90
97
|
- <Specific tests to add or update, with file paths>
|
|
@@ -246,6 +246,11 @@ For reference (you do NOT write this — `@plan` does), the plan file follows th
|
|
|
246
246
|
- Change: <what>
|
|
247
247
|
- Why: <one sentence>
|
|
248
248
|
- Risk: <none | low | medium | high>
|
|
249
|
+
- Mirror: <path/to/similar/existing/file> ← optional; for CREATE actions, point to a sibling file the executor should pattern-match
|
|
250
|
+
- Verify: <exact bash command> ← optional; per-file verification command (e.g. `bun test test/foo.test.ts`)
|
|
251
|
+
|
|
252
|
+
## Non-goals
|
|
253
|
+
- <Explicit "do NOT" statements — things the executor must not touch>
|
|
249
254
|
|
|
250
255
|
## Test plan
|
|
251
256
|
- <Specific tests to add or update>
|
|
@@ -267,6 +272,39 @@ Pass a single `prompt` to `@build` containing the absolute plan path and nothing
|
|
|
267
272
|
|
|
268
273
|
> Execute the plan at `<absolute-plan-path>`. Return with (a) commit SHAs from `git log --oneline <base>..HEAD`, (b) any plan mutations you made (threshold bumps, scope expansions under the 2-file limit), (c) pre-existing failures encountered and logged to the plan's `## Open questions`, (d) any STOP condition that requires me to re-dispatch. Do NOT invoke `@qa-reviewer` — I own QA dispatch in Phase 4.
|
|
269
274
|
|
|
275
|
+
### Structured handoff for strict executors
|
|
276
|
+
|
|
277
|
+
When `@build` is running as a strict executor (the `mid-execute` tier is configured — check whether the plan's file-level changes are detailed enough), supplement the delegation prompt with a structured context block. Strict executors refuse to proceed without explicit file lists and tests; they pattern-match better than they instruction-follow. The research is clear: feeding the executor the *exact tests it must satisfy* drops regressions 70% vs procedural TDD advice.
|
|
278
|
+
|
|
279
|
+
Include this block in your delegation prompt (after the plan path) when delegating to a strict executor:
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
Structured context (supplements the plan):
|
|
283
|
+
|
|
284
|
+
Files you may touch (ONLY these):
|
|
285
|
+
- <path> (<CREATE|EDIT|DELETE>) ← mirror: <sibling-file-path>
|
|
286
|
+
- <path> (<EDIT>)
|
|
287
|
+
...
|
|
288
|
+
|
|
289
|
+
Verify commands (run after each file, must exit 0):
|
|
290
|
+
- <exact bash command for file-scoped test>
|
|
291
|
+
- <typecheck command>
|
|
292
|
+
- <lint command scoped to changed paths>
|
|
293
|
+
|
|
294
|
+
Non-goals (do NOT do these):
|
|
295
|
+
- Do NOT modify <file/module outside scope>
|
|
296
|
+
- Do NOT add new dependencies
|
|
297
|
+
- Do NOT change the public API of <symbol>
|
|
298
|
+
...
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Rules for the structured block:**
|
|
302
|
+
- **Files**: copy from the plan's `## File-level changes`. For CREATE actions, include the `Mirror:` field value if present — this is the single most reliable hint for small models.
|
|
303
|
+
- **Verify commands**: derive from the plan's per-file `Verify:` fields, the `## Test plan`, and the repo's standard commands (`bun test`, `bun run typecheck`, `bun run lint`). Be specific — `bun test test/foo.test.ts` beats `bun test`.
|
|
304
|
+
- **Non-goals**: copy from the plan's `## Non-goals` section. If the plan doesn't have one, derive from `## Out of scope` + the implicit boundary (files NOT in the file-level changes list).
|
|
305
|
+
- **When to include**: always include when `mid-execute` is configured. When `@build` is on the standard `mid` tier (reasoning builder), the plan path alone is sufficient — the reasoning prompt handles inference from context.
|
|
306
|
+
- **Keep it under 2K tokens**: the structured block is context, not a second plan. If it exceeds 2K tokens, you're over-specifying — the plan itself should carry the detail.
|
|
307
|
+
|
|
270
308
|
### On `@build`'s return
|
|
271
309
|
|
|
272
310
|
1. **Validate the diff matches the plan.** Run `git diff --stat <base>..HEAD` and confirm the file list matches the plan's `## File-level changes`. If `@build` touched files outside the plan without a justification in its return payload, that's scope drift — investigate before proceeding.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-reviewer
|
|
3
|
+
description: Fast adversarial reviewer. Always re-runs verifiers. Returns [PASS] or [FAIL]. Default for typical diffs.
|
|
4
|
+
mode: subagent
|
|
5
|
+
model: anthropic/claude-sonnet-4-6
|
|
6
|
+
temperature: 0.1
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- STRICT_EXECUTOR_VARIANT -->
|
|
10
|
+
|
|
11
|
+
You are the QA Reviewer (fast variant, open-weights edition). Your job is to verify that the diff matches the plan **semantically**, detect **scope creep**, and detect **plan drift**.
|
|
12
|
+
|
|
13
|
+
Do not ask the user questions. Return `[PASS]` or `[FAIL]` only. If you're tempted to ask, FAIL instead and let the build agent fix it.
|
|
14
|
+
|
|
15
|
+
**Always re-run tests, lint, and typecheck.** Do not skip verification steps. Run every command yourself before returning `[PASS]`.
|
|
16
|
+
|
|
17
|
+
# Process
|
|
18
|
+
|
|
19
|
+
1. **Read the plan** at the path provided.
|
|
20
|
+
2. **Inspect the diff.** Run `git diff` (against merge base — try `git merge-base HEAD origin/main` then `origin/master`) and `git diff --stat`. Also run `git status` to see untracked files.
|
|
21
|
+
3. **Plan-drift check (AUTO-FAIL).** For each modified file in the diff, verify it appears in the plan's `## File-level changes`. A modified file NOT listed in `## File-level changes` is AUTO-FAIL. Report as `Plan drift: <path> modified but not in ## File-level changes`.
|
|
22
|
+
4. **Scope-creep check.** For each UNTRACKED file (from `git status`) that is NOT in `## File-level changes`, run `git log --oneline -- <file>` to determine whether the file is pre-existing work or scope creep. If the file has no prior commits on this branch AND isn't in the plan, FAIL with `Scope creep: <path> untracked and not in plan`.
|
|
23
|
+
5. **Semantic verification.** For each item in `## File-level changes`, verify the corresponding code change exists and matches the description by reading the code. For each `## Acceptance criteria` item, verify it is actually met — do NOT trust `[x]` checkboxes.
|
|
24
|
+
6. **Plan-state verify commands.** Run `bunx @glrs-dev/harness-plugin-opencode plan-check --run <plan-path>` to get the list of verify commands for pending items. Execute each one via `bash`. Any non-zero exit → FAIL with `Verify failed: <command> (exit N)`. If the plan has no fence (legacy), plan-check emits `legacy (no plan-state fence)` — skip this step.
|
|
25
|
+
7. **Full-suite re-run.** Run the project's test / lint / typecheck commands (discover from `package.json` scripts / `Makefile` / `AGENTS.md`). Any failure → FAIL.
|
|
26
|
+
8. **Scan for new tech debt.** Run `todo_scan` with `onlyChanged: true`. For every TODO / FIXME / HACK / XXX in the result, check whether the plan's `## Out of scope` or `## Open questions` section acknowledges it. Unacknowledged new debt → FAIL with the specific `file:line`.
|
|
27
|
+
9. **AGENTS.md freshness (light check).** If the change shifts a convention documented in a local `AGENTS.md` in a touched directory, FAIL with `Update <path>/AGENTS.md to reflect <specific change>`.
|
|
28
|
+
|
|
29
|
+
# Output
|
|
30
|
+
|
|
31
|
+
Exactly one of these two formats. Nothing else.
|
|
32
|
+
|
|
33
|
+
**If everything passes:**
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
[PASS]
|
|
37
|
+
|
|
38
|
+
<2–3 sentence summary of verified changes.>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**If anything fails:**
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
[FAIL]
|
|
45
|
+
|
|
46
|
+
1. <File:line> — <Specific issue>
|
|
47
|
+
2. <File:line> — <Next issue>
|
|
48
|
+
...
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
# Rules
|
|
52
|
+
|
|
53
|
+
- Never suggest fixes. Report precisely; the build agent will fix.
|
|
54
|
+
- Never trust the build agent's narrative. "Pre-existing work" requires `git log --oneline -- <file>` evidence.
|
|
55
|
+
- A single failing item is enough to FAIL. Do not minimize.
|
|
56
|
+
- **AUTO-FAIL on plan drift.** Modified file not in `## File-level changes` → FAIL, no exceptions.
|
|
57
|
+
- **AUTO-FAIL on scope creep.** Untracked file not in plan with no prior commits → FAIL.
|
|
58
|
+
- If the diff is large (>10 files or >500 lines) or touches high-risk paths (auth / crypto / billing / migrations), tell the PRIME to delegate to `@qa-thorough` instead.
|
|
@@ -257,7 +257,7 @@ async function requirePlugin() {
|
|
|
257
257
|
);
|
|
258
258
|
process.exit(1);
|
|
259
259
|
}
|
|
260
|
-
const { install: install2 } = await import("./install-
|
|
260
|
+
const { install: install2 } = await import("./install-5JKWK6Z4.js");
|
|
261
261
|
await install2({ nonInteractive: true });
|
|
262
262
|
}
|
|
263
263
|
|
|
@@ -764,6 +764,25 @@ ${c.bold}Ready.${c.reset} Run ${c.green}opencode${c.reset} to start.
|
|
|
764
764
|
fast: [preset.fast]
|
|
765
765
|
};
|
|
766
766
|
ok(`Models configured`);
|
|
767
|
+
const midExecIdx = await promptChoice(
|
|
768
|
+
" Use a strict executor for build agents? (recommended for Kimi/Qwen/DeepSeek)",
|
|
769
|
+
["No (use mid model as reasoning builder)", "Yes (configure mid-execute model)"],
|
|
770
|
+
0
|
|
771
|
+
);
|
|
772
|
+
if (midExecIdx === 1) {
|
|
773
|
+
const { input } = await import("@inquirer/prompts");
|
|
774
|
+
const midExecModel = await input({
|
|
775
|
+
message: " mid-execute model ID:",
|
|
776
|
+
default: preset.mid
|
|
777
|
+
});
|
|
778
|
+
if (midExecModel) {
|
|
779
|
+
pluginOpts.models["mid-execute"] = [midExecModel];
|
|
780
|
+
newModelsValue["mid-execute"] = [midExecModel];
|
|
781
|
+
info(` mid-execute \u2192 ${midExecModel} (strict executor prompts)`);
|
|
782
|
+
}
|
|
783
|
+
} else {
|
|
784
|
+
info(` mid-execute: skipped (build agents use mid model with reasoning prompts)`);
|
|
785
|
+
}
|
|
767
786
|
} else if (!pluginOpts._skipModels) {
|
|
768
787
|
info("Enter model IDs in <provider>/<model-id> format (e.g. amazon-bedrock/global.anthropic.claude-opus-4-7)");
|
|
769
788
|
const { input } = await import("@inquirer/prompts");
|
|
@@ -771,17 +790,26 @@ ${c.bold}Ready.${c.reset} Run ${c.green}opencode${c.reset} to start.
|
|
|
771
790
|
const midModel = await input({ message: " mid (balanced):" });
|
|
772
791
|
const fastModel = await input({ message: " fast (cheapest):" });
|
|
773
792
|
if (deepModel) {
|
|
793
|
+
const resolvedMid = midModel || deepModel;
|
|
774
794
|
pluginOpts.models = {
|
|
775
795
|
deep: [deepModel],
|
|
776
|
-
mid: [
|
|
796
|
+
mid: [resolvedMid],
|
|
777
797
|
fast: [fastModel || midModel || deepModel]
|
|
778
798
|
};
|
|
779
799
|
newModelsValue = {
|
|
780
800
|
deep: [deepModel],
|
|
781
|
-
mid: [
|
|
801
|
+
mid: [resolvedMid],
|
|
782
802
|
fast: [fastModel || midModel || deepModel]
|
|
783
803
|
};
|
|
784
804
|
ok("Models: custom");
|
|
805
|
+
const midExecModel = await input({ message: " mid-execute (optional strict executor, press Enter to skip):" });
|
|
806
|
+
if (midExecModel) {
|
|
807
|
+
pluginOpts.models["mid-execute"] = [midExecModel];
|
|
808
|
+
newModelsValue["mid-execute"] = [midExecModel];
|
|
809
|
+
info(` mid-execute \u2192 ${midExecModel} (strict executor prompts)`);
|
|
810
|
+
} else {
|
|
811
|
+
info(` mid-execute: skipped (build agents use mid model with reasoning prompts)`);
|
|
812
|
+
}
|
|
785
813
|
} else {
|
|
786
814
|
ok("Models: OpenCode defaults");
|
|
787
815
|
}
|
|
@@ -47,7 +47,9 @@ function readPrompt(name) {
|
|
|
47
47
|
var primePrompt = readPrompt("prime.md");
|
|
48
48
|
var planPrompt = readPrompt("plan.md");
|
|
49
49
|
var buildPrompt = readPrompt("build.md");
|
|
50
|
+
var buildOpenPrompt = readPrompt("build.open.md");
|
|
50
51
|
var qaReviewerPrompt = readPrompt("qa-reviewer.md");
|
|
52
|
+
var qaReviewerOpenPrompt = readPrompt("qa-reviewer.open.md");
|
|
51
53
|
var qaThoroughPrompt = readPrompt("qa-thorough.md");
|
|
52
54
|
var planReviewerPrompt = readPrompt("plan-reviewer.md");
|
|
53
55
|
var codeSearcherPrompt = readPrompt("code-searcher.md");
|
|
@@ -57,11 +59,24 @@ var docsMaintainerPrompt = readPrompt("docs-maintainer.md");
|
|
|
57
59
|
var libReaderPrompt = readPrompt("lib-reader.md");
|
|
58
60
|
var agentsMdWriterPrompt = readPrompt("agents-md-writer.md");
|
|
59
61
|
var pilotBuilderPrompt = readPrompt("pilot-builder.md");
|
|
62
|
+
var pilotBuilderOpenPrompt = readPrompt("pilot-builder.open.md");
|
|
60
63
|
var pilotPlannerPrompt = readPrompt("pilot-planner.md");
|
|
61
64
|
var researchPrompt = readPrompt("research.md");
|
|
62
65
|
var researchWebPrompt = readPrompt("research-web.md");
|
|
63
66
|
var researchLocalPrompt = readPrompt("research-local.md");
|
|
64
67
|
var researchAutoPrompt = readPrompt("research-auto.md");
|
|
68
|
+
var EXECUTOR_VARIANT_AGENTS = {
|
|
69
|
+
build: { reasoning: buildPrompt, strict: buildOpenPrompt },
|
|
70
|
+
"qa-reviewer": { reasoning: qaReviewerPrompt, strict: qaReviewerOpenPrompt },
|
|
71
|
+
"pilot-builder": { reasoning: pilotBuilderPrompt, strict: pilotBuilderOpenPrompt }
|
|
72
|
+
};
|
|
73
|
+
function getStrictPrompt(agentName) {
|
|
74
|
+
const variants = EXECUTOR_VARIANT_AGENTS[agentName];
|
|
75
|
+
if (!variants) {
|
|
76
|
+
throw new Error(`getStrictPrompt: no strict variant registered for agent "${agentName}"`);
|
|
77
|
+
}
|
|
78
|
+
return variants.strict;
|
|
79
|
+
}
|
|
65
80
|
function stripFrontmatter(md) {
|
|
66
81
|
if (!md.startsWith("---")) return md;
|
|
67
82
|
const end = md.indexOf("\n---", 3);
|
|
@@ -563,12 +578,12 @@ var AGENT_TIERS = {
|
|
|
563
578
|
"research-web": "deep",
|
|
564
579
|
"research-local": "deep",
|
|
565
580
|
"research-auto": "deep",
|
|
566
|
-
build: "mid",
|
|
567
|
-
"qa-reviewer": "mid",
|
|
581
|
+
build: "mid-execute",
|
|
582
|
+
"qa-reviewer": "mid-execute",
|
|
583
|
+
"pilot-builder": "mid-execute",
|
|
568
584
|
"docs-maintainer": "mid",
|
|
569
585
|
"lib-reader": "mid",
|
|
570
586
|
"agents-md-writer": "mid",
|
|
571
|
-
"pilot-builder": "mid",
|
|
572
587
|
"code-searcher": "fast"
|
|
573
588
|
};
|
|
574
589
|
function createAgents() {
|
|
@@ -724,6 +739,7 @@ function formatModelOverrideWarning(id, source, suggestion) {
|
|
|
724
739
|
}
|
|
725
740
|
|
|
726
741
|
export {
|
|
742
|
+
getStrictPrompt,
|
|
727
743
|
AGENT_TIERS,
|
|
728
744
|
createAgents,
|
|
729
745
|
validateModelOverride,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createAgents,
|
|
4
4
|
validateModelOverride
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EK7K4NTV.js";
|
|
6
6
|
import {
|
|
7
7
|
getSessionsPath,
|
|
8
8
|
registerSession,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
install,
|
|
13
13
|
requirePlugin
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-BWERBERN.js";
|
|
15
15
|
import "./chunk-VJUETC6A.js";
|
|
16
16
|
import {
|
|
17
17
|
getPilotDir,
|
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
AGENT_TIERS,
|
|
3
3
|
createAgents,
|
|
4
4
|
formatModelOverrideWarning,
|
|
5
|
+
getStrictPrompt,
|
|
5
6
|
validateModelOverride
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-EK7K4NTV.js";
|
|
7
8
|
import {
|
|
8
9
|
PACKAGE_NAME,
|
|
9
10
|
readOurPackageVersion,
|
|
@@ -163,6 +164,7 @@ function writePermDebugSnapshot(config) {
|
|
|
163
164
|
function resolveHarnessModels(agents, config, pluginOptions) {
|
|
164
165
|
const modelsConfig = pluginOptions?.models ?? config.harness?.models;
|
|
165
166
|
if (!modelsConfig) return agents;
|
|
167
|
+
const midExecuteConfigured = modelsConfig["mid-execute"] !== void 0;
|
|
166
168
|
const warnedIds = /* @__PURE__ */ new Set();
|
|
167
169
|
const warnIfInvalid = (value, source) => {
|
|
168
170
|
const result = validateModelOverride(value);
|
|
@@ -181,11 +183,25 @@ function resolveHarnessModels(agents, config, pluginOptions) {
|
|
|
181
183
|
}
|
|
182
184
|
const tier = AGENT_TIERS[agentName];
|
|
183
185
|
if (tier) {
|
|
184
|
-
|
|
186
|
+
let perTier = modelsConfig[tier];
|
|
187
|
+
if (tier === "mid-execute" && perTier === void 0) {
|
|
188
|
+
perTier = modelsConfig["mid"];
|
|
189
|
+
}
|
|
185
190
|
if (perTier !== void 0) {
|
|
186
191
|
const picked = Array.isArray(perTier) ? perTier[0] : perTier;
|
|
187
192
|
agentCfg.model = picked;
|
|
188
|
-
warnIfInvalid(picked, `models.${tier}`);
|
|
193
|
+
warnIfInvalid(picked, `models.${tier === "mid-execute" && !midExecuteConfigured ? "mid (fallback)" : tier}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (midExecuteConfigured) {
|
|
198
|
+
const EXECUTOR_AGENTS = ["build", "qa-reviewer", "pilot-builder"];
|
|
199
|
+
for (const agentName of EXECUTOR_AGENTS) {
|
|
200
|
+
const agentCfg = agents[agentName];
|
|
201
|
+
if (!agentCfg) continue;
|
|
202
|
+
try {
|
|
203
|
+
agentCfg.prompt = getStrictPrompt(agentName);
|
|
204
|
+
} catch {
|
|
189
205
|
}
|
|
190
206
|
}
|
|
191
207
|
}
|
|
@@ -1850,7 +1866,7 @@ import { join as join8 } from "path";
|
|
|
1850
1866
|
var APP_KEY = "A-US-3617699429";
|
|
1851
1867
|
var ENDPOINT = "https://us.aptabase.com/api/v0/event";
|
|
1852
1868
|
var PKG_NAME = "@glrs-dev/harness-plugin-opencode";
|
|
1853
|
-
var PKG_VERSION = true ? "1.
|
|
1869
|
+
var PKG_VERSION = true ? "1.1.0" : "dev";
|
|
1854
1870
|
var DISABLED = process.env.HARNESS_OPENCODE_TELEMETRY === "0" || process.env.HARNESS_OPENCODE_TELEMETRY === "false" || process.env.DO_NOT_TRACK === "1" || process.env.CI === "true";
|
|
1855
1871
|
var SESSION_ID = randomUUID();
|
|
1856
1872
|
function getInstallId() {
|