@glrs-dev/cli 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-assessor.md +77 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-builder.md +24 -116
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-planner.md +38 -160
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-scoper.md +58 -0
- package/dist/vendor/harness-opencode/dist/{chunk-BWERBERN.js → chunk-6CZPRUMJ.js} +12 -62
- package/dist/vendor/harness-opencode/dist/chunk-DZG4D3OH.js +54 -0
- package/dist/vendor/harness-opencode/dist/chunk-OYRKOEXK.js +88 -0
- package/dist/vendor/harness-opencode/dist/cli.js +1622 -4226
- package/dist/vendor/harness-opencode/dist/index.js +831 -166
- package/dist/vendor/harness-opencode/dist/{install-5JKWK6Z4.js → install-6775ZBDG.js} +1 -1
- package/dist/vendor/harness-opencode/dist/paths-WZ23ZQOV.js +18 -0
- package/dist/vendor/harness-opencode/package.json +1 -1
- package/package.json +1 -1
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-builder.open.md +0 -129
- package/dist/vendor/harness-opencode/dist/chunk-57EOY72Y.js +0 -174
- package/dist/vendor/harness-opencode/dist/chunk-5TAMY7P6.js +0 -67
- package/dist/vendor/harness-opencode/dist/chunk-BKTFWXLG.js +0 -204
- package/dist/vendor/harness-opencode/dist/chunk-EK7K4NTV.js +0 -747
- package/dist/vendor/harness-opencode/dist/chunk-KB7M7JXU.js +0 -145
- package/dist/vendor/harness-opencode/dist/chunk-RNRCXQ65.js +0 -56
- package/dist/vendor/harness-opencode/dist/paths-LT3QQKCF.js +0 -18
- package/dist/vendor/harness-opencode/dist/pilot/mcp/status-server.d.ts +0 -1
- package/dist/vendor/harness-opencode/dist/pilot/mcp/status-server.js +0 -228
- package/dist/vendor/harness-opencode/dist/pilot-config-7LJZ23YK.js +0 -55
- package/dist/vendor/harness-opencode/dist/runs-QWPL3TKV.js +0 -18
- package/dist/vendor/harness-opencode/dist/safety-gate-WM3EWOCY.js +0 -10
- package/dist/vendor/harness-opencode/dist/setup-hook-FHTXMAQL.js +0 -88
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/SKILL.md +0 -80
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/dag-shape.md +0 -47
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/decomposition.md +0 -63
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/first-principles.md +0 -29
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/milestones.md +0 -57
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/qa-expectations.md +0 -120
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/self-review.md +0 -46
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/task-context.md +0 -47
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/touches-scope.md +0 -81
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/verify-design.md +0 -163
- package/dist/vendor/harness-opencode/dist/tasks-KJ3WN2KY.js +0 -32
|
@@ -1,747 +0,0 @@
|
|
|
1
|
-
// src/agents/shared/index.ts
|
|
2
|
-
import { readFileSync } from "fs";
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
4
|
-
import { dirname, join } from "path";
|
|
5
|
-
var HERE = dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
function readMd(name) {
|
|
7
|
-
const candidates = [
|
|
8
|
-
join(HERE, name),
|
|
9
|
-
// dev: src/agents/shared/
|
|
10
|
-
join(HERE, "agents", "shared", name),
|
|
11
|
-
// dist: dist/ → dist/agents/shared/
|
|
12
|
-
join(HERE, "..", "..", "..", "src", "agents", "shared", name)
|
|
13
|
-
// fallback dev
|
|
14
|
-
];
|
|
15
|
-
for (const p of candidates) {
|
|
16
|
-
try {
|
|
17
|
-
return readFileSync(p, "utf8");
|
|
18
|
-
} catch {
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
throw new Error(`Could not find shared file: ${name}`);
|
|
22
|
-
}
|
|
23
|
-
var WORKFLOW_MECHANICS_RULE = readMd("workflow-mechanics.md");
|
|
24
|
-
|
|
25
|
-
// src/agents/index.ts
|
|
26
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
27
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
28
|
-
import { dirname as dirname2, join as join2 } from "path";
|
|
29
|
-
var HERE2 = dirname2(fileURLToPath2(import.meta.url));
|
|
30
|
-
function readPrompt(name) {
|
|
31
|
-
const candidates = [
|
|
32
|
-
join2(HERE2, "prompts", name),
|
|
33
|
-
// dev: src/agents/prompts/
|
|
34
|
-
join2(HERE2, "agents", "prompts", name),
|
|
35
|
-
// dist: dist/ → dist/agents/prompts/
|
|
36
|
-
join2(HERE2, "..", "..", "src", "agents", "prompts", name)
|
|
37
|
-
// fallback dev
|
|
38
|
-
];
|
|
39
|
-
for (const p of candidates) {
|
|
40
|
-
try {
|
|
41
|
-
return readFileSync2(p, "utf8");
|
|
42
|
-
} catch {
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
throw new Error(`Could not find prompt file: ${name}`);
|
|
46
|
-
}
|
|
47
|
-
var primePrompt = readPrompt("prime.md");
|
|
48
|
-
var planPrompt = readPrompt("plan.md");
|
|
49
|
-
var buildPrompt = readPrompt("build.md");
|
|
50
|
-
var buildOpenPrompt = readPrompt("build.open.md");
|
|
51
|
-
var qaReviewerPrompt = readPrompt("qa-reviewer.md");
|
|
52
|
-
var qaReviewerOpenPrompt = readPrompt("qa-reviewer.open.md");
|
|
53
|
-
var qaThoroughPrompt = readPrompt("qa-thorough.md");
|
|
54
|
-
var planReviewerPrompt = readPrompt("plan-reviewer.md");
|
|
55
|
-
var codeSearcherPrompt = readPrompt("code-searcher.md");
|
|
56
|
-
var gapAnalyzerPrompt = readPrompt("gap-analyzer.md");
|
|
57
|
-
var architectureAdvisorPrompt = readPrompt("architecture-advisor.md");
|
|
58
|
-
var docsMaintainerPrompt = readPrompt("docs-maintainer.md");
|
|
59
|
-
var libReaderPrompt = readPrompt("lib-reader.md");
|
|
60
|
-
var agentsMdWriterPrompt = readPrompt("agents-md-writer.md");
|
|
61
|
-
var pilotBuilderPrompt = readPrompt("pilot-builder.md");
|
|
62
|
-
var pilotBuilderOpenPrompt = readPrompt("pilot-builder.open.md");
|
|
63
|
-
var pilotPlannerPrompt = readPrompt("pilot-planner.md");
|
|
64
|
-
var researchPrompt = readPrompt("research.md");
|
|
65
|
-
var researchWebPrompt = readPrompt("research-web.md");
|
|
66
|
-
var researchLocalPrompt = readPrompt("research-local.md");
|
|
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
|
-
}
|
|
80
|
-
function stripFrontmatter(md) {
|
|
81
|
-
if (!md.startsWith("---")) return md;
|
|
82
|
-
const end = md.indexOf("\n---", 3);
|
|
83
|
-
if (end === -1) return md;
|
|
84
|
-
return md.slice(end + 4).trimStart();
|
|
85
|
-
}
|
|
86
|
-
function parseFrontmatter(md) {
|
|
87
|
-
if (!md.startsWith("---")) return {};
|
|
88
|
-
const end = md.indexOf("\n---", 3);
|
|
89
|
-
if (end === -1) return {};
|
|
90
|
-
const block = md.slice(4, end);
|
|
91
|
-
const result = {};
|
|
92
|
-
let currentKey = null;
|
|
93
|
-
let currentValue = [];
|
|
94
|
-
const flush = () => {
|
|
95
|
-
if (currentKey) {
|
|
96
|
-
result[currentKey] = currentValue.join(" ").trim();
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
for (const line of block.split("\n")) {
|
|
100
|
-
if (currentKey && (line.startsWith(" ") || line.startsWith(" "))) {
|
|
101
|
-
currentValue.push(line.trim());
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
const colon = line.indexOf(":");
|
|
105
|
-
if (colon === -1) {
|
|
106
|
-
flush();
|
|
107
|
-
currentKey = null;
|
|
108
|
-
currentValue = [];
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
flush();
|
|
112
|
-
currentKey = line.slice(0, colon).trim();
|
|
113
|
-
const value = line.slice(colon + 1).trim();
|
|
114
|
-
currentValue = value ? [value] : [];
|
|
115
|
-
}
|
|
116
|
-
flush();
|
|
117
|
-
return result;
|
|
118
|
-
}
|
|
119
|
-
function injectWorkflowMechanics(prompt) {
|
|
120
|
-
return prompt.replace("{WORKFLOW_MECHANICS_RULE}", WORKFLOW_MECHANICS_RULE);
|
|
121
|
-
}
|
|
122
|
-
function agentFromPrompt(raw, overrides = {}) {
|
|
123
|
-
const fm = parseFrontmatter(raw);
|
|
124
|
-
const body = stripFrontmatter(raw);
|
|
125
|
-
const prompt = injectWorkflowMechanics(body);
|
|
126
|
-
const base = {
|
|
127
|
-
description: fm["description"] ?? "",
|
|
128
|
-
mode: fm["mode"] ?? "subagent",
|
|
129
|
-
model: fm["model"] ?? void 0,
|
|
130
|
-
prompt
|
|
131
|
-
};
|
|
132
|
-
return { ...base, ...overrides };
|
|
133
|
-
}
|
|
134
|
-
var CORE_BASH_ALLOW_LIST = {
|
|
135
|
-
// File inspection — safe read-only commands the reviewers use heavily.
|
|
136
|
-
"ls *": "allow",
|
|
137
|
-
"cat *": "allow",
|
|
138
|
-
"head *": "allow",
|
|
139
|
-
"tail *": "allow",
|
|
140
|
-
"wc *": "allow",
|
|
141
|
-
"grep *": "allow",
|
|
142
|
-
"rg *": "allow",
|
|
143
|
-
"find *": "allow",
|
|
144
|
-
"file *": "allow",
|
|
145
|
-
"stat *": "allow",
|
|
146
|
-
"which *": "allow",
|
|
147
|
-
"whereis *": "allow",
|
|
148
|
-
"basename *": "allow",
|
|
149
|
-
"dirname *": "allow",
|
|
150
|
-
"realpath *": "allow",
|
|
151
|
-
"readlink *": "allow",
|
|
152
|
-
"diff *": "allow",
|
|
153
|
-
"sort *": "allow",
|
|
154
|
-
"uniq *": "allow",
|
|
155
|
-
"xxd *": "allow",
|
|
156
|
-
"tree *": "allow",
|
|
157
|
-
"date *": "allow",
|
|
158
|
-
"echo *": "allow",
|
|
159
|
-
// Git read-only subcommands (explicit rather than `git *` so we don't
|
|
160
|
-
// accidentally whitelist `git push` variants the destructive-deny
|
|
161
|
-
// table counteracts via longer-pattern matches — but clarity > trust).
|
|
162
|
-
"git status *": "allow",
|
|
163
|
-
"git log *": "allow",
|
|
164
|
-
"git diff *": "allow",
|
|
165
|
-
"git show *": "allow",
|
|
166
|
-
"git branch *": "allow",
|
|
167
|
-
"git merge-base *": "allow",
|
|
168
|
-
"git rev-parse *": "allow",
|
|
169
|
-
"git rev-list *": "allow",
|
|
170
|
-
"git blame *": "allow",
|
|
171
|
-
"git config --get *": "allow",
|
|
172
|
-
"git config --get": "allow",
|
|
173
|
-
"git remote *": "allow",
|
|
174
|
-
"git stash list *": "allow",
|
|
175
|
-
"git stash list": "allow",
|
|
176
|
-
"git ls-files *": "allow",
|
|
177
|
-
"git describe *": "allow",
|
|
178
|
-
"git tag *": "allow",
|
|
179
|
-
"git fetch *": "allow",
|
|
180
|
-
// Package/build tooling — the reviewers run lint/test/typecheck.
|
|
181
|
-
"pnpm lint *": "allow",
|
|
182
|
-
"pnpm test *": "allow",
|
|
183
|
-
"pnpm typecheck *": "allow",
|
|
184
|
-
"pnpm build *": "allow",
|
|
185
|
-
"pnpm run *": "allow",
|
|
186
|
-
"pnpm install *": "allow",
|
|
187
|
-
"pnpm --filter *": "allow",
|
|
188
|
-
"pnpm -w *": "allow",
|
|
189
|
-
"bun run *": "allow",
|
|
190
|
-
"bun test *": "allow",
|
|
191
|
-
"bun install *": "allow",
|
|
192
|
-
"bunx *": "allow",
|
|
193
|
-
"npm run *": "allow",
|
|
194
|
-
"npm test *": "allow",
|
|
195
|
-
"npx *": "allow",
|
|
196
|
-
"yarn *": "allow",
|
|
197
|
-
"tsc *": "allow",
|
|
198
|
-
"eslint *": "allow",
|
|
199
|
-
"prettier *": "allow",
|
|
200
|
-
"biome *": "allow",
|
|
201
|
-
// Our own CLI — the plan agent and qa-reviewer both call plan-check/plan-dir.
|
|
202
|
-
"bunx @glrs-dev/harness-plugin-opencode *": "allow",
|
|
203
|
-
"glrs-oc *": "allow",
|
|
204
|
-
// GitHub CLI — read-only gh calls are fine; destructive `gh pr merge`
|
|
205
|
-
// is gated at the PRIME level by human intent (user runs /ship).
|
|
206
|
-
"gh pr view *": "allow",
|
|
207
|
-
"gh pr list *": "allow",
|
|
208
|
-
"gh issue view *": "allow",
|
|
209
|
-
"gh issue list *": "allow",
|
|
210
|
-
"gh api *": "allow"
|
|
211
|
-
};
|
|
212
|
-
var CORE_DESTRUCTIVE_BASH_DENIES = {
|
|
213
|
-
"rm -rf /*": "deny",
|
|
214
|
-
"rm -rf ~*": "deny",
|
|
215
|
-
"chmod *": "deny",
|
|
216
|
-
"chown *": "deny",
|
|
217
|
-
"sudo *": "deny",
|
|
218
|
-
"git push --force*": "deny",
|
|
219
|
-
"git push -f *": "deny",
|
|
220
|
-
"git push * --force*": "deny",
|
|
221
|
-
"git push * -f": "deny",
|
|
222
|
-
"git push * main*": "deny",
|
|
223
|
-
"git push * master*": "deny",
|
|
224
|
-
// --force-with-lease is the safe variant — explicit allow rule sorts
|
|
225
|
-
// after the broad --force deny so the lease variant survives.
|
|
226
|
-
"git push --force-with-lease*": "allow",
|
|
227
|
-
"git push * --force-with-lease*": "allow"
|
|
228
|
-
};
|
|
229
|
-
var PRIME_PERMISSIONS = {
|
|
230
|
-
edit: "allow",
|
|
231
|
-
bash: {
|
|
232
|
-
"*": "allow",
|
|
233
|
-
...CORE_BASH_ALLOW_LIST,
|
|
234
|
-
...CORE_DESTRUCTIVE_BASH_DENIES,
|
|
235
|
-
// git clean & git reset --hard are allowed for prime because
|
|
236
|
-
// /fresh runs them after its own question-tool confirmation gate;
|
|
237
|
-
// a permission-layer prompt on top is redundant noise (see issue #54).
|
|
238
|
-
// BUILD keeps the stricter default (deny/ask).
|
|
239
|
-
"git clean *": "allow",
|
|
240
|
-
"git reset --hard*": "allow"
|
|
241
|
-
},
|
|
242
|
-
webfetch: "allow",
|
|
243
|
-
// Per-tool permissions (index signature on AgentConfig allows these)
|
|
244
|
-
ast_grep: "allow",
|
|
245
|
-
tsc_check: "allow",
|
|
246
|
-
eslint_check: "allow",
|
|
247
|
-
todo_scan: "allow",
|
|
248
|
-
comment_check: "allow",
|
|
249
|
-
question: "allow",
|
|
250
|
-
serena: "allow",
|
|
251
|
-
memory: "allow",
|
|
252
|
-
git: "allow",
|
|
253
|
-
playwright: "allow",
|
|
254
|
-
linear: "allow"
|
|
255
|
-
};
|
|
256
|
-
var PLAN_PERMISSIONS = {
|
|
257
|
-
edit: "allow",
|
|
258
|
-
// Plan agent is read-only aside from writing under the plan dir — but
|
|
259
|
-
// it does need to RESOLVE the plan dir via the `plan-dir` CLI
|
|
260
|
-
// subcommand (returns an absolute path derived from the worktree's
|
|
261
|
-
// repo-folder key; see src/plan-paths.ts and src/cli.ts). The object-
|
|
262
|
-
// form denies bash broadly and re-allows only `bunx
|
|
263
|
-
// @glrs-dev/harness-plugin-opencode plan-dir[...]`. No other bash invocation
|
|
264
|
-
// is permitted, so the read-only-aside-from-plans invariant holds.
|
|
265
|
-
bash: {
|
|
266
|
-
"*": "deny",
|
|
267
|
-
"bunx @glrs-dev/harness-plugin-opencode plan-dir": "allow",
|
|
268
|
-
"bunx @glrs-dev/harness-plugin-opencode plan-dir *": "allow",
|
|
269
|
-
"glrs-oc plan-dir": "allow",
|
|
270
|
-
"glrs-oc plan-dir *": "allow"
|
|
271
|
-
},
|
|
272
|
-
webfetch: "allow",
|
|
273
|
-
ast_grep: "deny",
|
|
274
|
-
tsc_check: "deny",
|
|
275
|
-
eslint_check: "deny",
|
|
276
|
-
todo_scan: "allow",
|
|
277
|
-
comment_check: "allow",
|
|
278
|
-
question: "allow",
|
|
279
|
-
serena: "allow",
|
|
280
|
-
memory: "allow",
|
|
281
|
-
git: "allow",
|
|
282
|
-
playwright: "deny",
|
|
283
|
-
linear: "allow"
|
|
284
|
-
};
|
|
285
|
-
var BUILD_PERMISSIONS = {
|
|
286
|
-
edit: "allow",
|
|
287
|
-
bash: {
|
|
288
|
-
"*": "allow",
|
|
289
|
-
...CORE_BASH_ALLOW_LIST,
|
|
290
|
-
...CORE_DESTRUCTIVE_BASH_DENIES,
|
|
291
|
-
// Build is stricter than prime on mutation: no `git clean`
|
|
292
|
-
// (build shouldn't wipe worktree mid-execution), and
|
|
293
|
-
// `git reset --hard` must prompt explicitly.
|
|
294
|
-
"git clean *": "deny",
|
|
295
|
-
"git reset --hard*": "ask"
|
|
296
|
-
},
|
|
297
|
-
webfetch: "allow",
|
|
298
|
-
ast_grep: "allow",
|
|
299
|
-
tsc_check: "allow",
|
|
300
|
-
eslint_check: "allow",
|
|
301
|
-
todo_scan: "allow",
|
|
302
|
-
comment_check: "allow",
|
|
303
|
-
question: "allow",
|
|
304
|
-
serena: "allow",
|
|
305
|
-
memory: "allow",
|
|
306
|
-
git: "allow",
|
|
307
|
-
playwright: "allow",
|
|
308
|
-
linear: "allow"
|
|
309
|
-
};
|
|
310
|
-
var QA_REVIEWER_PERMISSIONS = {
|
|
311
|
-
edit: "deny",
|
|
312
|
-
// Object-form bash: the scalar `"allow"` shape loses to OpenCode's
|
|
313
|
-
// upstream subagent-default `{bash, *, ask}` via last-match-wins (see
|
|
314
|
-
// the root-cause comment near PRIME_PERMISSIONS). Enumerated
|
|
315
|
-
// specific patterns in CORE_BASH_ALLOW_LIST sort AFTER the upstream
|
|
316
|
-
// wildcard ask and win for the commands they match. `"*": "allow"`
|
|
317
|
-
// is kept as a backstop but may still lose to the upstream rule for
|
|
318
|
-
// commands not in the enumerated list; those are the known blind spot.
|
|
319
|
-
bash: {
|
|
320
|
-
"*": "allow",
|
|
321
|
-
...CORE_BASH_ALLOW_LIST,
|
|
322
|
-
...CORE_DESTRUCTIVE_BASH_DENIES
|
|
323
|
-
},
|
|
324
|
-
webfetch: "deny",
|
|
325
|
-
ast_grep: "allow",
|
|
326
|
-
tsc_check: "allow",
|
|
327
|
-
eslint_check: "allow",
|
|
328
|
-
todo_scan: "allow",
|
|
329
|
-
comment_check: "allow",
|
|
330
|
-
question: "allow",
|
|
331
|
-
serena: "allow",
|
|
332
|
-
memory: "deny",
|
|
333
|
-
git: "allow",
|
|
334
|
-
playwright: "allow",
|
|
335
|
-
linear: "deny"
|
|
336
|
-
};
|
|
337
|
-
var QA_THOROUGH_PERMISSIONS = {
|
|
338
|
-
edit: "deny",
|
|
339
|
-
// Same object-form as QA_REVIEWER_PERMISSIONS — see the shape rationale
|
|
340
|
-
// there. qa-thorough re-runs the full suite unconditionally (per its
|
|
341
|
-
// prompt), so it touches the same command surface as qa-reviewer and
|
|
342
|
-
// needs the identical bash allow-list.
|
|
343
|
-
bash: {
|
|
344
|
-
"*": "allow",
|
|
345
|
-
...CORE_BASH_ALLOW_LIST,
|
|
346
|
-
...CORE_DESTRUCTIVE_BASH_DENIES
|
|
347
|
-
},
|
|
348
|
-
webfetch: "deny",
|
|
349
|
-
ast_grep: "allow",
|
|
350
|
-
tsc_check: "allow",
|
|
351
|
-
eslint_check: "allow",
|
|
352
|
-
todo_scan: "allow",
|
|
353
|
-
comment_check: "allow",
|
|
354
|
-
question: "allow",
|
|
355
|
-
serena: "allow",
|
|
356
|
-
memory: "deny",
|
|
357
|
-
git: "allow",
|
|
358
|
-
playwright: "allow",
|
|
359
|
-
linear: "deny"
|
|
360
|
-
};
|
|
361
|
-
var PLAN_REVIEWER_PERMISSIONS = {
|
|
362
|
-
edit: "deny",
|
|
363
|
-
bash: "deny",
|
|
364
|
-
webfetch: "deny",
|
|
365
|
-
ast_grep: "allow",
|
|
366
|
-
tsc_check: "deny",
|
|
367
|
-
eslint_check: "deny",
|
|
368
|
-
todo_scan: "allow",
|
|
369
|
-
comment_check: "allow",
|
|
370
|
-
question: "allow",
|
|
371
|
-
serena: "allow",
|
|
372
|
-
memory: "deny",
|
|
373
|
-
git: "allow",
|
|
374
|
-
playwright: "deny",
|
|
375
|
-
linear: "deny"
|
|
376
|
-
};
|
|
377
|
-
var GAP_ANALYZER_PERMISSIONS = {
|
|
378
|
-
edit: "deny",
|
|
379
|
-
bash: "deny",
|
|
380
|
-
webfetch: "deny",
|
|
381
|
-
ast_grep: "deny",
|
|
382
|
-
tsc_check: "deny",
|
|
383
|
-
eslint_check: "deny",
|
|
384
|
-
todo_scan: "allow",
|
|
385
|
-
comment_check: "allow",
|
|
386
|
-
question: "allow",
|
|
387
|
-
serena: "allow",
|
|
388
|
-
memory: "allow",
|
|
389
|
-
git: "deny",
|
|
390
|
-
playwright: "deny",
|
|
391
|
-
linear: "allow"
|
|
392
|
-
};
|
|
393
|
-
var CODE_SEARCHER_PERMISSIONS = {
|
|
394
|
-
edit: "deny",
|
|
395
|
-
bash: "deny",
|
|
396
|
-
webfetch: "deny",
|
|
397
|
-
ast_grep: "allow",
|
|
398
|
-
tsc_check: "deny",
|
|
399
|
-
eslint_check: "deny",
|
|
400
|
-
todo_scan: "deny",
|
|
401
|
-
comment_check: "deny",
|
|
402
|
-
question: "allow",
|
|
403
|
-
serena: "allow",
|
|
404
|
-
memory: "deny",
|
|
405
|
-
git: "deny",
|
|
406
|
-
playwright: "deny",
|
|
407
|
-
linear: "deny"
|
|
408
|
-
};
|
|
409
|
-
var ARCHITECTURE_ADVISOR_PERMISSIONS = {
|
|
410
|
-
edit: "deny",
|
|
411
|
-
bash: "deny",
|
|
412
|
-
webfetch: "deny",
|
|
413
|
-
ast_grep: "allow",
|
|
414
|
-
tsc_check: "deny",
|
|
415
|
-
eslint_check: "deny",
|
|
416
|
-
todo_scan: "allow",
|
|
417
|
-
comment_check: "allow",
|
|
418
|
-
question: "allow",
|
|
419
|
-
serena: "allow",
|
|
420
|
-
memory: "allow",
|
|
421
|
-
git: "allow",
|
|
422
|
-
playwright: "deny",
|
|
423
|
-
linear: "allow"
|
|
424
|
-
};
|
|
425
|
-
var LIB_READER_PERMISSIONS = {
|
|
426
|
-
edit: "deny",
|
|
427
|
-
bash: "deny",
|
|
428
|
-
webfetch: "deny",
|
|
429
|
-
ast_grep: "deny",
|
|
430
|
-
tsc_check: "deny",
|
|
431
|
-
eslint_check: "deny",
|
|
432
|
-
todo_scan: "deny",
|
|
433
|
-
comment_check: "deny",
|
|
434
|
-
question: "allow",
|
|
435
|
-
serena: "deny",
|
|
436
|
-
memory: "allow",
|
|
437
|
-
git: "deny",
|
|
438
|
-
playwright: "deny",
|
|
439
|
-
linear: "deny"
|
|
440
|
-
};
|
|
441
|
-
var AGENTS_MD_WRITER_PERMISSIONS = {
|
|
442
|
-
edit: "allow",
|
|
443
|
-
bash: "ask",
|
|
444
|
-
// preserve ask-semantics from frontmatter
|
|
445
|
-
webfetch: "deny",
|
|
446
|
-
ast_grep: "allow",
|
|
447
|
-
tsc_check: "deny",
|
|
448
|
-
eslint_check: "deny",
|
|
449
|
-
todo_scan: "allow",
|
|
450
|
-
comment_check: "allow",
|
|
451
|
-
question: "allow",
|
|
452
|
-
serena: "allow",
|
|
453
|
-
memory: "deny",
|
|
454
|
-
git: "allow",
|
|
455
|
-
playwright: "deny",
|
|
456
|
-
linear: "deny"
|
|
457
|
-
};
|
|
458
|
-
var PILOT_BUILDER_PERMISSIONS = {
|
|
459
|
-
edit: "allow",
|
|
460
|
-
bash: {
|
|
461
|
-
"*": "allow",
|
|
462
|
-
...CORE_BASH_ALLOW_LIST,
|
|
463
|
-
...CORE_DESTRUCTIVE_BASH_DENIES,
|
|
464
|
-
// Pilot-specific destructive denies — the builder NEVER commits,
|
|
465
|
-
// pushes, switches branches, or opens PRs. The worker does this
|
|
466
|
-
// for the agent.
|
|
467
|
-
"git commit*": "deny",
|
|
468
|
-
"git push*": "deny",
|
|
469
|
-
"git tag*": "deny",
|
|
470
|
-
"git checkout *": "deny",
|
|
471
|
-
"git switch *": "deny",
|
|
472
|
-
"git branch *": "deny",
|
|
473
|
-
"git restore --source*": "deny",
|
|
474
|
-
"git reset *": "deny",
|
|
475
|
-
"gh pr *": "deny",
|
|
476
|
-
"gh release *": "deny"
|
|
477
|
-
},
|
|
478
|
-
webfetch: "allow",
|
|
479
|
-
ast_grep: "allow",
|
|
480
|
-
tsc_check: "allow",
|
|
481
|
-
eslint_check: "allow",
|
|
482
|
-
todo_scan: "allow",
|
|
483
|
-
comment_check: "allow",
|
|
484
|
-
// Builder is unattended — must never call the question tool. (The
|
|
485
|
-
// worker enforces this via the prompt + STOP protocol; permission
|
|
486
|
-
// denial is a backstop.)
|
|
487
|
-
question: "deny",
|
|
488
|
-
serena: "allow",
|
|
489
|
-
memory: "deny",
|
|
490
|
-
// pilot tasks are stateless; no per-session memory.
|
|
491
|
-
git: "allow",
|
|
492
|
-
// read-only git tools (status, log, diff).
|
|
493
|
-
playwright: "deny",
|
|
494
|
-
linear: "deny"
|
|
495
|
-
};
|
|
496
|
-
var PILOT_PLANNER_PERMISSIONS = {
|
|
497
|
-
edit: "allow",
|
|
498
|
-
bash: {
|
|
499
|
-
"*": "deny",
|
|
500
|
-
// Read-only inspection — same surface as PLAN_PERMISSIONS, plus a few.
|
|
501
|
-
"ls *": "allow",
|
|
502
|
-
"cat *": "allow",
|
|
503
|
-
"head *": "allow",
|
|
504
|
-
"tail *": "allow",
|
|
505
|
-
"wc *": "allow",
|
|
506
|
-
"grep *": "allow",
|
|
507
|
-
"rg *": "allow",
|
|
508
|
-
"find *": "allow",
|
|
509
|
-
"git status *": "allow",
|
|
510
|
-
"git log *": "allow",
|
|
511
|
-
"git diff *": "allow",
|
|
512
|
-
"git show *": "allow",
|
|
513
|
-
"git branch *": "allow",
|
|
514
|
-
"git rev-parse *": "allow",
|
|
515
|
-
// Pilot CLI: validate, plan-dir for self-check + path resolution.
|
|
516
|
-
"bunx @glrs-dev/harness-plugin-opencode pilot validate *": "allow",
|
|
517
|
-
"bunx @glrs-dev/harness-plugin-opencode pilot validate": "allow",
|
|
518
|
-
"bunx @glrs-dev/harness-plugin-opencode pilot plan-dir": "allow",
|
|
519
|
-
"bunx @glrs-dev/harness-plugin-opencode pilot plan-dir *": "allow",
|
|
520
|
-
"bunx @glrs-dev/harness-plugin-opencode plan-dir": "allow",
|
|
521
|
-
"bunx @glrs-dev/harness-plugin-opencode plan-dir *": "allow",
|
|
522
|
-
"glrs-oc pilot validate *": "allow",
|
|
523
|
-
"glrs-oc pilot validate": "allow",
|
|
524
|
-
"glrs-oc pilot plan-dir": "allow",
|
|
525
|
-
"glrs-oc pilot plan-dir *": "allow",
|
|
526
|
-
"glrs-oc plan-dir": "allow",
|
|
527
|
-
"glrs-oc plan-dir *": "allow"
|
|
528
|
-
},
|
|
529
|
-
// No webfetch by default — the planner reads tickets via the linear
|
|
530
|
-
// MCP. If the user invokes with a GitHub URL, they need the linear
|
|
531
|
-
// / webfetch combination explicitly. Mark deny here and the operator
|
|
532
|
-
// can override per-session.
|
|
533
|
-
webfetch: "deny",
|
|
534
|
-
ast_grep: "allow",
|
|
535
|
-
tsc_check: "deny",
|
|
536
|
-
// no need to typecheck; we're writing YAML.
|
|
537
|
-
eslint_check: "deny",
|
|
538
|
-
todo_scan: "allow",
|
|
539
|
-
comment_check: "allow",
|
|
540
|
-
question: "allow",
|
|
541
|
-
// the planner CAN ask the human (interactive).
|
|
542
|
-
serena: "allow",
|
|
543
|
-
memory: "deny",
|
|
544
|
-
git: "allow",
|
|
545
|
-
// read-only git tools.
|
|
546
|
-
playwright: "deny",
|
|
547
|
-
linear: "allow"
|
|
548
|
-
};
|
|
549
|
-
var RESEARCH_PERMISSIONS = {
|
|
550
|
-
edit: "allow",
|
|
551
|
-
bash: {
|
|
552
|
-
"*": "allow",
|
|
553
|
-
...CORE_BASH_ALLOW_LIST,
|
|
554
|
-
...CORE_DESTRUCTIVE_BASH_DENIES
|
|
555
|
-
},
|
|
556
|
-
webfetch: "allow",
|
|
557
|
-
ast_grep: "allow",
|
|
558
|
-
tsc_check: "deny",
|
|
559
|
-
eslint_check: "deny",
|
|
560
|
-
todo_scan: "allow",
|
|
561
|
-
comment_check: "allow",
|
|
562
|
-
question: "allow",
|
|
563
|
-
serena: "allow",
|
|
564
|
-
memory: "allow",
|
|
565
|
-
git: "allow",
|
|
566
|
-
playwright: "deny",
|
|
567
|
-
linear: "allow"
|
|
568
|
-
};
|
|
569
|
-
var AGENT_TIERS = {
|
|
570
|
-
prime: "deep",
|
|
571
|
-
plan: "deep",
|
|
572
|
-
"qa-thorough": "deep",
|
|
573
|
-
"architecture-advisor": "deep",
|
|
574
|
-
"plan-reviewer": "deep",
|
|
575
|
-
"gap-analyzer": "deep",
|
|
576
|
-
"pilot-planner": "deep",
|
|
577
|
-
research: "deep",
|
|
578
|
-
"research-web": "deep",
|
|
579
|
-
"research-local": "deep",
|
|
580
|
-
"research-auto": "deep",
|
|
581
|
-
build: "mid-execute",
|
|
582
|
-
"qa-reviewer": "mid-execute",
|
|
583
|
-
"pilot-builder": "mid-execute",
|
|
584
|
-
"docs-maintainer": "mid",
|
|
585
|
-
"lib-reader": "mid",
|
|
586
|
-
"agents-md-writer": "mid",
|
|
587
|
-
"code-searcher": "fast"
|
|
588
|
-
};
|
|
589
|
-
function createAgents() {
|
|
590
|
-
return {
|
|
591
|
-
// Primary agents
|
|
592
|
-
prime: agentFromPrompt(primePrompt, {
|
|
593
|
-
description: "End-to-end PRIME (Primary Routing and Intelligence Management Entity). Takes a request from intent to ready-to-ship in one session. Default primary agent.",
|
|
594
|
-
mode: "primary",
|
|
595
|
-
model: "anthropic/claude-opus-4-7",
|
|
596
|
-
temperature: 0.2,
|
|
597
|
-
permission: PRIME_PERMISSIONS
|
|
598
|
-
}),
|
|
599
|
-
plan: agentFromPrompt(planPrompt, {
|
|
600
|
-
description: "Interactive planner. Orchestrates gap analysis and adversarial review. Produces a written plan in the repo-shared plan directory (resolve via `bunx @glrs-dev/harness-plugin-opencode plan-dir`).",
|
|
601
|
-
mode: "all",
|
|
602
|
-
model: "anthropic/claude-opus-4-7",
|
|
603
|
-
temperature: 0.3,
|
|
604
|
-
permission: PLAN_PERMISSIONS
|
|
605
|
-
}),
|
|
606
|
-
build: agentFromPrompt(buildPrompt, {
|
|
607
|
-
description: "Executes a written plan. Runs tests inline, gates completion on QA review.",
|
|
608
|
-
mode: "all",
|
|
609
|
-
model: "anthropic/claude-sonnet-4-6",
|
|
610
|
-
temperature: 0.1,
|
|
611
|
-
permission: BUILD_PERMISSIONS
|
|
612
|
-
}),
|
|
613
|
-
// Subagents — model/mode/description from frontmatter, permissions
|
|
614
|
-
// via overrides (see permission blocks above). docs-maintainer has no
|
|
615
|
-
// frontmatter permission declaration and keeps that behavior.
|
|
616
|
-
"qa-reviewer": agentFromPrompt(qaReviewerPrompt, {
|
|
617
|
-
permission: QA_REVIEWER_PERMISSIONS
|
|
618
|
-
}),
|
|
619
|
-
"qa-thorough": agentFromPrompt(qaThoroughPrompt, {
|
|
620
|
-
permission: QA_THOROUGH_PERMISSIONS
|
|
621
|
-
}),
|
|
622
|
-
"plan-reviewer": agentFromPrompt(planReviewerPrompt, {
|
|
623
|
-
permission: PLAN_REVIEWER_PERMISSIONS
|
|
624
|
-
}),
|
|
625
|
-
"code-searcher": agentFromPrompt(codeSearcherPrompt, {
|
|
626
|
-
permission: CODE_SEARCHER_PERMISSIONS
|
|
627
|
-
}),
|
|
628
|
-
"gap-analyzer": agentFromPrompt(gapAnalyzerPrompt, {
|
|
629
|
-
permission: GAP_ANALYZER_PERMISSIONS
|
|
630
|
-
}),
|
|
631
|
-
"architecture-advisor": agentFromPrompt(architectureAdvisorPrompt, {
|
|
632
|
-
permission: ARCHITECTURE_ADVISOR_PERMISSIONS
|
|
633
|
-
}),
|
|
634
|
-
"docs-maintainer": agentFromPrompt(docsMaintainerPrompt),
|
|
635
|
-
"lib-reader": agentFromPrompt(libReaderPrompt, {
|
|
636
|
-
permission: LIB_READER_PERMISSIONS
|
|
637
|
-
}),
|
|
638
|
-
"agents-md-writer": agentFromPrompt(agentsMdWriterPrompt, {
|
|
639
|
-
permission: AGENTS_MD_WRITER_PERMISSIONS
|
|
640
|
-
}),
|
|
641
|
-
// Pilot subsystem agents (Phase F1 + F2). The frontmatter sets
|
|
642
|
-
// mode/model/description; temperature is passed via override
|
|
643
|
-
// because `agentFromPrompt` doesn't currently parse the
|
|
644
|
-
// temperature field (and we don't want to change that helper for
|
|
645
|
-
// every agent at once — out of scope for F1/F2).
|
|
646
|
-
"pilot-builder": agentFromPrompt(pilotBuilderPrompt, {
|
|
647
|
-
mode: "subagent",
|
|
648
|
-
model: "anthropic/claude-sonnet-4-6",
|
|
649
|
-
temperature: 0.1,
|
|
650
|
-
permission: PILOT_BUILDER_PERMISSIONS
|
|
651
|
-
}),
|
|
652
|
-
"pilot-planner": agentFromPrompt(pilotPlannerPrompt, {
|
|
653
|
-
mode: "subagent",
|
|
654
|
-
model: "anthropic/claude-opus-4-7",
|
|
655
|
-
temperature: 0.3,
|
|
656
|
-
permission: PILOT_PLANNER_PERMISSIONS
|
|
657
|
-
}),
|
|
658
|
-
// Research agent — mode:all for both primary invocation and task-tool dispatch
|
|
659
|
-
research: agentFromPrompt(researchPrompt, {
|
|
660
|
-
description: "Research orchestrator \u2014 decomposes a research query into parallel workstreams, dispatches research skills (research / research-web / research-local / research-auto) as subagents, reviews findings for gaps, iterates, and synthesizes. Use when the user asks to investigate, explore, deep-dive, or understand a complex topic that needs multiple workstreams.",
|
|
661
|
-
mode: "all",
|
|
662
|
-
model: "anthropic/claude-opus-4-7",
|
|
663
|
-
temperature: 0.3,
|
|
664
|
-
permission: RESEARCH_PERMISSIONS
|
|
665
|
-
}),
|
|
666
|
-
// Research subagents — thin shims that load the bundled skills
|
|
667
|
-
"research-web": agentFromPrompt(researchWebPrompt, {
|
|
668
|
-
description: "Research orchestrator subagent \u2014 Multi-agent web research orchestrator. Decomposes a research question into parallel agent workstreams, launches them, monitors progress, and synthesizes results. Use when user says 'research this topic', 'I need to understand', 'deep dive into', 'investigate the market for', 'what do we know about'. Provide the research topic and context.",
|
|
669
|
-
mode: "all",
|
|
670
|
-
model: "anthropic/claude-opus-4-7",
|
|
671
|
-
temperature: 0.3,
|
|
672
|
-
permission: RESEARCH_PERMISSIONS
|
|
673
|
-
}),
|
|
674
|
-
"research-local": agentFromPrompt(researchLocalPrompt, {
|
|
675
|
-
description: "Research orchestrator subagent \u2014 Deep codebase research using parallel Explore subagents. Decomposes a question about the local codebase into research tasks, launches parallel explorations, reviews for gaps, iterates, and synthesizes findings with specific file paths and line numbers. Use when user says 'how does X work in this codebase', 'where is Y implemented', 'trace the data flow for Z', 'what patterns does this repo use', 'explain the architecture of'. Provide the research topic as arguments.",
|
|
676
|
-
mode: "all",
|
|
677
|
-
model: "anthropic/claude-opus-4-7",
|
|
678
|
-
temperature: 0.3,
|
|
679
|
-
permission: RESEARCH_PERMISSIONS
|
|
680
|
-
}),
|
|
681
|
-
"research-auto": agentFromPrompt(researchAutoPrompt, {
|
|
682
|
-
description: "Research orchestrator subagent \u2014 Autonomous experimentation skill. Agent interviews the user, sets up a lab, then explores freely (think, test, reflect) until stopped or a target is hit. Works for any domain where you can measure or evaluate a result. Use when user says 'optimize this', 'experiment with', 'find the best approach', 'iterate on', 'research mode'. Do NOT use for binary validation tests (use /spec-lab instead). Based on ResearcherSkill v1.4.4 by krzysztofdudek.",
|
|
683
|
-
mode: "all",
|
|
684
|
-
model: "anthropic/claude-opus-4-7",
|
|
685
|
-
temperature: 0.3,
|
|
686
|
-
permission: RESEARCH_PERMISSIONS
|
|
687
|
-
})
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
// src/model-validator.ts
|
|
692
|
-
var CATWALK_PROVIDER_PATTERN = /^(?:bedrock|vertex|vertexai)\//;
|
|
693
|
-
var LEGACY_PRE_100_PATTERN = /^(bedrock|vertex|vertexai)\/claude-(opus|sonnet|haiku)(-\d+)?$/;
|
|
694
|
-
var LEGACY_TO_MODELS_DEV = {
|
|
695
|
-
// --- Pre-PR-#100 Bedrock (no subpath) ---
|
|
696
|
-
"bedrock/claude-opus": "amazon-bedrock/global.anthropic.claude-opus-4-7",
|
|
697
|
-
"bedrock/claude-opus-4": "amazon-bedrock/global.anthropic.claude-opus-4-7",
|
|
698
|
-
"bedrock/claude-sonnet": "amazon-bedrock/global.anthropic.claude-sonnet-4-6",
|
|
699
|
-
"bedrock/claude-sonnet-4": "amazon-bedrock/global.anthropic.claude-sonnet-4-6",
|
|
700
|
-
"bedrock/claude-haiku": "amazon-bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
701
|
-
"bedrock/claude-haiku-4": "amazon-bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
702
|
-
// --- Pre-Models.dev Bedrock (had subpath, but wrong provider prefix) ---
|
|
703
|
-
"bedrock/anthropic.claude-opus-4-6": "amazon-bedrock/global.anthropic.claude-opus-4-7",
|
|
704
|
-
"bedrock/anthropic.claude-opus-4-7": "amazon-bedrock/global.anthropic.claude-opus-4-7",
|
|
705
|
-
"bedrock/anthropic.claude-sonnet-4-6": "amazon-bedrock/global.anthropic.claude-sonnet-4-6",
|
|
706
|
-
"bedrock/anthropic.claude-haiku-4-5-20251001-v1:0": "amazon-bedrock/global.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
707
|
-
// --- Pre-PR-#100 Vertex (no @date suffix) ---
|
|
708
|
-
"vertex/claude-opus": "google-vertex-anthropic/claude-opus-4-7@default",
|
|
709
|
-
"vertex/claude-opus-4": "google-vertex-anthropic/claude-opus-4-7@default",
|
|
710
|
-
"vertex/claude-sonnet": "google-vertex-anthropic/claude-sonnet-4-6@default",
|
|
711
|
-
"vertex/claude-sonnet-4": "google-vertex-anthropic/claude-sonnet-4-6@default",
|
|
712
|
-
"vertex/claude-haiku": "google-vertex-anthropic/claude-haiku-4-5@20251001",
|
|
713
|
-
"vertex/claude-haiku-4": "google-vertex-anthropic/claude-haiku-4-5@20251001",
|
|
714
|
-
"vertexai/claude-opus": "google-vertex-anthropic/claude-opus-4-7@default",
|
|
715
|
-
"vertexai/claude-opus-4": "google-vertex-anthropic/claude-opus-4-7@default",
|
|
716
|
-
"vertexai/claude-sonnet": "google-vertex-anthropic/claude-sonnet-4-6@default",
|
|
717
|
-
"vertexai/claude-sonnet-4": "google-vertex-anthropic/claude-sonnet-4-6@default",
|
|
718
|
-
"vertexai/claude-haiku": "google-vertex-anthropic/claude-haiku-4-5@20251001",
|
|
719
|
-
"vertexai/claude-haiku-4": "google-vertex-anthropic/claude-haiku-4-5@20251001",
|
|
720
|
-
// --- Pre-Models.dev Vertex (had @date suffix, wrong provider prefix) ---
|
|
721
|
-
"vertexai/claude-opus-4-6@20250610": "google-vertex-anthropic/claude-opus-4-6@default",
|
|
722
|
-
"vertexai/claude-opus-4-7@20250610": "google-vertex-anthropic/claude-opus-4-7@default",
|
|
723
|
-
"vertexai/claude-sonnet-4-6@20250725": "google-vertex-anthropic/claude-sonnet-4-6@default",
|
|
724
|
-
"vertexai/claude-haiku-4-5@20251001": "google-vertex-anthropic/claude-haiku-4-5@20251001"
|
|
725
|
-
};
|
|
726
|
-
function validateModelOverride(id) {
|
|
727
|
-
if (typeof id !== "string") return { valid: true };
|
|
728
|
-
if (id.length === 0) return { valid: true };
|
|
729
|
-
if (CATWALK_PROVIDER_PATTERN.test(id)) {
|
|
730
|
-
const suggestion = LEGACY_TO_MODELS_DEV[id] ?? "run `bunx @glrs-dev/harness-plugin-opencode install` to pick a current preset";
|
|
731
|
-
const reason = LEGACY_PRE_100_PATTERN.test(id) ? `"${id}" is a pre-PR-#100 model ID format that does not resolve in OpenCode. Bedrock IDs need the \`amazon-bedrock\` provider prefix (not \`bedrock\`); Vertex Claude IDs need the \`google-vertex-anthropic\` provider prefix (not \`vertex\` / \`vertexai\`).` : `"${id}" uses a provider prefix (\`${id.split("/")[0]}\`) that does not exist in OpenCode's runtime. AWS Bedrock's provider ID is \`amazon-bedrock\`; Vertex Claude's is \`google-vertex-anthropic\`.`;
|
|
732
|
-
return { valid: false, reason, suggestion };
|
|
733
|
-
}
|
|
734
|
-
return { valid: true };
|
|
735
|
-
}
|
|
736
|
-
function formatModelOverrideWarning(id, source, suggestion) {
|
|
737
|
-
const suggestionText = suggestion ? ` Suggested replacement: \`${suggestion}\`.` : "";
|
|
738
|
-
return `[@glrs-dev/harness-plugin-opencode] Warning: invalid model override "${id}" (from ${source}).${suggestionText} Run \`bunx @glrs-dev/harness-plugin-opencode doctor\` for details.`;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
export {
|
|
742
|
-
getStrictPrompt,
|
|
743
|
-
AGENT_TIERS,
|
|
744
|
-
createAgents,
|
|
745
|
-
validateModelOverride,
|
|
746
|
-
formatModelOverrideWarning
|
|
747
|
-
};
|