@polderlabs/bizar 6.2.3 → 6.2.4
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/cli/commands/validate.mjs +29 -0
- package/cli/commands/validate.test.mjs +37 -0
- package/config/agents/_shared/AGENT_BASELINE.md +40 -1
- package/config/agents/_shared/CLINE_TOOLS.md +398 -0
- package/config/agents/agent-browser.md +1 -1
- package/config/agents/baldr.md +1 -1
- package/config/agents/forseti.md +1 -1
- package/config/agents/frigg.md +1 -1
- package/config/agents/heimdall.md +1 -1
- package/config/agents/hermod.md +1 -1
- package/config/agents/mimir.md +1 -1
- package/config/agents/odin.md +1 -1
- package/config/agents/quick.md +1 -1
- package/config/agents/semble-search.md +1 -1
- package/config/agents/thor.md +1 -1
- package/config/agents/tyr.md +1 -1
- package/config/agents/vidarr.md +1 -1
- package/config/agents/vor.md +1 -1
- package/package.json +1 -1
- package/plugins/bizar/package.json +1 -1
- package/plugins/bizar/src/clineruntime.ts +18 -3
- package/plugins/bizar/src/options.ts +14 -7
- package/plugins/bizar/tests/clineruntime-config.test.ts +45 -4
- package/plugins/bizar/tests/options.test.ts +6 -6
- package/scripts/bh-full-e2e.mjs +22 -0
- package/scripts/check-agents.mjs +73 -0
|
@@ -362,6 +362,33 @@ const CHECKS = {
|
|
|
362
362
|
}
|
|
363
363
|
},
|
|
364
364
|
|
|
365
|
+
// v6.2.4 — Warn if the user's clineruntimeMaxConsecutiveMistakes is
|
|
366
|
+
// below the plugin's recommended minimum. Cline's CLI default is 3
|
|
367
|
+
// which aborts sessions on the 3rd tool mistake. The Bizar plugin
|
|
368
|
+
// recommends 10 (or `--retries N` with N ≥ 10).
|
|
369
|
+
'mistake-limit-floor': async () => {
|
|
370
|
+
const MIN = 10;
|
|
371
|
+
const cfg = readJsonSafe(clineJsonPath());
|
|
372
|
+
if (!cfg?.plugin || !Array.isArray(cfg.plugin)) {
|
|
373
|
+
return 'no plugin entries in cline.json — skip mistake-limit check';
|
|
374
|
+
}
|
|
375
|
+
const bizarEntry = cfg.plugin.find((p) => Array.isArray(p) && p[0] && p[0].includes('plugins/bizar'));
|
|
376
|
+
if (!bizarEntry) {
|
|
377
|
+
return 'Bizar plugin not registered — skip mistake-limit check';
|
|
378
|
+
}
|
|
379
|
+
const opts = (Array.isArray(bizarEntry) && bizarEntry[1]) || {};
|
|
380
|
+
const raw = opts.clineruntimeMaxConsecutiveMistakes;
|
|
381
|
+
if (typeof raw !== 'number' || raw >= MIN) {
|
|
382
|
+
return `clineruntimeMaxConsecutiveMistakes=${raw ?? 'default 10'} (≥ ${MIN}) — OK`;
|
|
383
|
+
}
|
|
384
|
+
throw new Error(
|
|
385
|
+
`clineruntimeMaxConsecutiveMistakes=${raw} is BELOW the recommended minimum (${MIN}). ` +
|
|
386
|
+
`Cline's default of 3 aborts the session on the 3rd tool mistake. ` +
|
|
387
|
+
`Edit ~/.cline/cline.json plugin[1].clineruntimeMaxConsecutiveMistakes to ${MIN}, or run ` +
|
|
388
|
+
`\`bizar install\` to reset to defaults. (See _shared/CLINE_TOOLS.md for the top-5 mistakes.)`,
|
|
389
|
+
);
|
|
390
|
+
},
|
|
391
|
+
|
|
365
392
|
'default-agent-set': async () => {
|
|
366
393
|
const cfg = readJsonSafe(clineJsonPath());
|
|
367
394
|
if (!cfg?.default_agent) {
|
|
@@ -434,12 +461,14 @@ const CHECK_ORDER = [
|
|
|
434
461
|
'provider-config',
|
|
435
462
|
'cline-settings-provider',
|
|
436
463
|
'9router-reachable',
|
|
464
|
+
'mistake-limit-floor',
|
|
437
465
|
];
|
|
438
466
|
|
|
439
467
|
const LENIENT_CHECKS = new Set([
|
|
440
468
|
'9router-reachable',
|
|
441
469
|
'provider-config', // v6.2.2+ — installer no longer touches provider config; user must configure
|
|
442
470
|
'cline-settings-provider', // v6.2.3 — warns about legacy/fake providerIds; non-blocking
|
|
471
|
+
'mistake-limit-floor', // v6.2.4 — warns about low mistake limit; non-blocking
|
|
443
472
|
]);
|
|
444
473
|
|
|
445
474
|
export function showValidateHelp() {
|
|
@@ -304,4 +304,41 @@ describe('runValidate() — JSON output', () => {
|
|
|
304
304
|
const { exitCode } = await captureRun({ json: true, only: 'this-does-not-exist' });
|
|
305
305
|
assert.equal(exitCode, 2);
|
|
306
306
|
});
|
|
307
|
+
|
|
308
|
+
test('v6.2.4 — mistake-limit-floor warns when clineruntimeMaxConsecutiveMistakes is < 10', async () => {
|
|
309
|
+
const cfg = JSON.parse(readFileSync(join(workDir, 'cline.json'), 'utf8'));
|
|
310
|
+
cfg.plugin = [['./plugins/bizar', { clineruntimeMaxConsecutiveMistakes: 3 }]];
|
|
311
|
+
writeFileSync(join(workDir, 'cline.json'), JSON.stringify(cfg, null, 2));
|
|
312
|
+
const { stdout, exitCode } = await captureRun({ json: true });
|
|
313
|
+
assert.equal(exitCode, 0, 'mistake-limit-floor is lenient so exit stays 0');
|
|
314
|
+
const parsed = JSON.parse(stdout);
|
|
315
|
+
const check = parsed.results.find((r) => r.name === 'mistake-limit-floor');
|
|
316
|
+
assert.ok(check, 'mistake-limit-floor check should be present');
|
|
317
|
+
assert.equal(check.ok, false, 'low mistake limit should warn');
|
|
318
|
+
assert.match(check.message, /BELOW the recommended minimum/);
|
|
319
|
+
assert.match(check.message, /clineruntimeMaxConsecutiveMistakes=3/);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
test('v6.2.4 — mistake-limit-floor OK when clineruntimeMaxConsecutiveMistakes >= 10', async () => {
|
|
323
|
+
const cfg = JSON.parse(readFileSync(join(workDir, 'cline.json'), 'utf8'));
|
|
324
|
+
cfg.plugin = [['./plugins/bizar', { clineruntimeMaxConsecutiveMistakes: 15 }]];
|
|
325
|
+
writeFileSync(join(workDir, 'cline.json'), JSON.stringify(cfg, null, 2));
|
|
326
|
+
const { stdout, exitCode } = await captureRun({ json: true });
|
|
327
|
+
assert.equal(exitCode, 0);
|
|
328
|
+
const parsed = JSON.parse(stdout);
|
|
329
|
+
const check = parsed.results.find((r) => r.name === 'mistake-limit-floor');
|
|
330
|
+
assert.equal(check.ok, true);
|
|
331
|
+
assert.match(check.message, /15/);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test('v6.2.4 — mistake-limit-floor OK when no plugin entry (legacy cline.json)', async () => {
|
|
335
|
+
const cfg = JSON.parse(readFileSync(join(workDir, 'cline.json'), 'utf8'));
|
|
336
|
+
delete cfg.plugin;
|
|
337
|
+
writeFileSync(join(workDir, 'cline.json'), JSON.stringify(cfg, null, 2));
|
|
338
|
+
const { stdout } = await captureRun({ json: true });
|
|
339
|
+
const parsed = JSON.parse(stdout);
|
|
340
|
+
const check = parsed.results.find((r) => r.name === 'mistake-limit-floor');
|
|
341
|
+
assert.match(check.message, /no plugin entries/);
|
|
342
|
+
assert.equal(check.ok, true);
|
|
343
|
+
});
|
|
307
344
|
});
|
|
@@ -5,7 +5,19 @@ description: Always-on rules for every Bizar agent. Loaded automatically by clin
|
|
|
5
5
|
|
|
6
6
|
# Agent Baseline — Always-On Rules
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
> **v6.2.4 — Read `CLINE_TOOLS.md` first.** The Cline tools (`read_file`,
|
|
9
|
+
> `editor`, `apply_patch`, `ask_question`, `use_subagents`, `task`, …)
|
|
10
|
+
> have strict argument shapes. Passing the wrong shape — e.g. `options:
|
|
11
|
+
> null` on `ask_question` — silently fails and counts as a "mistake".
|
|
12
|
+
> After 3 mistakes (10 since v6.2.4) Cline aborts the session.
|
|
13
|
+
> See `_shared/CLINE_TOOLS.md` for the exact schemas.
|
|
14
|
+
|
|
15
|
+
Every Bizar agent follows these rules at all times. They are the
|
|
16
|
+
canonical agent baseline for the BizarHarness system — the Norse-pantheon
|
|
17
|
+
multi-agent system built on top of Cline. The rules below are tuned for
|
|
18
|
+
Bizar specifically: tool names reference Cline's built-in tools
|
|
19
|
+
(`read_file`, `editor`, `ask_question`, …) and Bizar's plugin tools
|
|
20
|
+
(`bizar_*`); storage paths reference `~/.cline/` and `~/.bizar_memory/`.
|
|
9
21
|
|
|
10
22
|
---
|
|
11
23
|
|
|
@@ -25,6 +37,33 @@ Every Bizar agent follows these rules at all times. They are translated from the
|
|
|
25
37
|
|
|
26
38
|
---
|
|
27
39
|
|
|
40
|
+
## 1a. Tool Mistakes — Don't Kill the Session
|
|
41
|
+
|
|
42
|
+
Cline's runtime counts consecutive tool failures (mistakes). When the
|
|
43
|
+
count hits the limit (3 in v6.2.0–v6.2.3; **10 since v6.2.4**), it aborts
|
|
44
|
+
the session with `max consecutive mistakes reached`. The most common
|
|
45
|
+
cause is calling a tool with the wrong argument shape.
|
|
46
|
+
|
|
47
|
+
**Top 5 mistakes that abort sessions — read this and avoid them:**
|
|
48
|
+
|
|
49
|
+
1. **`ask_question` with `options: null` or `options: undefined`.** The tool silently fails and counts as a mistake. Always pass an array of 2–5 strings.
|
|
50
|
+
2. **`editor` with non-matching `old_text`.** Whitespace must match exactly. Always `read_file` first and copy the bytes.
|
|
51
|
+
3. **`editor` with `old_text` that matches multiple places.** Make `old_text` more specific (include more surrounding context) so it matches exactly once.
|
|
52
|
+
4. **`execute_command` with shell redirects (`>`, `>>`).** Bizar blocks these by default. Use `editor` or `apply_patch` to write files.
|
|
53
|
+
5. **`use_subagents` with a single prompt.** Subagents are parallel research. Spawn 3–5 at once, not one at a time.
|
|
54
|
+
|
|
55
|
+
**Recovery: if you hit the mistake limit:**
|
|
56
|
+
|
|
57
|
+
- Stop retrying the same broken call — each retry wastes a mistake.
|
|
58
|
+
- Read `_shared/CLINE_TOOLS.md` for the exact schema.
|
|
59
|
+
- Spawn a fresh session via `bizar_spawn_background` if the runtime is stuck.
|
|
60
|
+
- Ask the user to abort and restart with `bizar doctor` + `bizar validate`.
|
|
61
|
+
|
|
62
|
+
The full reference is at `_shared/CLINE_TOOLS.md` (linked from every agent
|
|
63
|
+
file's `description` frontmatter).
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
28
67
|
## 2. Codebase Search — Use Semble First
|
|
29
68
|
|
|
30
69
|
Semble is the local code search tool — faster and more token-efficient than reading files directly.
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
# Cline Tools Reference
|
|
2
|
+
|
|
3
|
+
> **Read this before calling any Cline tool.** Calling tools with the
|
|
4
|
+
> wrong argument shape is the #1 cause of "max consecutive mistakes
|
|
5
|
+
> reached" session aborts. When in doubt, read this file.
|
|
6
|
+
|
|
7
|
+
Every Bizar agent runs inside a Cline session and has access to
|
|
8
|
+
Cline's built-in tools plus the Bizar plugin's `bizar_*` tools. This
|
|
9
|
+
file is the single source of truth for **how to call every Cline
|
|
10
|
+
tool correctly**.
|
|
11
|
+
|
|
12
|
+
For a list of what each tool does, see https://docs.cline.bot.
|
|
13
|
+
This file focuses on **argument shapes** — the part that, when wrong,
|
|
14
|
+
silently fails or gets flagged as a "mistake".
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Quick reference (cheat sheet)
|
|
19
|
+
|
|
20
|
+
| Tool | Required fields | Common mistake |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `read_file` | `path` | passing a dir instead of a file |
|
|
23
|
+
| `list_files` | `path` | forgetting `recursive: true` for nested lookups |
|
|
24
|
+
| `search_files` | `query` (regex) | passing non-regex without `include_pattern` |
|
|
25
|
+
| `editor` | `path`, `new_text` (and `old_text` OR `insert_line`) | `old_text` not matching whitespace exactly |
|
|
26
|
+
| `apply_patch` | `path`, `patch_text` | missing `*** Begin Patch` / `*** End Patch` sentinels |
|
|
27
|
+
| `execute_command` | `command` | shell redirects (`>`, `>>`) blocked by default; 10-min timeout |
|
|
28
|
+
| `web_fetch` | `url` | passing a non-HTTP URL |
|
|
29
|
+
| `ask_question` | `question`, `options` (array of 2–5) | **`options: null` → silent failure → mistake limit** |
|
|
30
|
+
| `use_skill` | `skill` | passing a skill that isn't installed |
|
|
31
|
+
| `use_subagents` | `prompts` (array of strings) | one prompt per subagent |
|
|
32
|
+
| `task` | `agent` (Bizar agent name), `prompt` | passing a non-Bizar agent name |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## `read_file`
|
|
37
|
+
|
|
38
|
+
Read a file (or a slice of one).
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"path": "/abs/path/to/file.ts",
|
|
43
|
+
"start_line": 10,
|
|
44
|
+
"end_line": 50
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Field | Type | Required | Notes |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| `path` | string | **yes** | Absolute path. Reading a directory throws. |
|
|
51
|
+
| `start_line` | number | no | 1-based. Defaults to 1. |
|
|
52
|
+
| `end_line` | number | no | 1-based, inclusive. If omitted, reads to EOF. |
|
|
53
|
+
|
|
54
|
+
**Failure modes:** `path` to a directory throws `Path is not a file`. `path` to a non-existent file throws. Don't pass `start_line` > `end_line`.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## `list_files`
|
|
59
|
+
|
|
60
|
+
List files in a directory.
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"path": "/abs/path/to/dir",
|
|
65
|
+
"recursive": true
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Field | Type | Required | Notes |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| `path` | string | **yes** | Absolute path to a directory. |
|
|
72
|
+
| `recursive` | bool | no | Default false. **Set true for nested lookups.** |
|
|
73
|
+
|
|
74
|
+
**Failure modes:** `path` to a file throws. The output excludes common build dirs (node_modules, .git, dist, build, .next, coverage, __pycache__, .venv, target, out, bin, obj). Don't rely on the default for deep trees.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## `search_files`
|
|
79
|
+
|
|
80
|
+
Regex search across files.
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"query": "class \\w+ extends Plugin",
|
|
85
|
+
"path": "/abs/path/to/project",
|
|
86
|
+
"include_pattern": "*.ts",
|
|
87
|
+
"max_results": 50
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
| Field | Type | Required | Notes |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| `query` | string | **yes** | Treated as a regex. Use `rg` syntax. |
|
|
94
|
+
| `path` | string | no | Defaults to cwd. Absolute path recommended. |
|
|
95
|
+
| `include_pattern` | string | no | Glob, e.g. `*.ts`, `*.{ts,tsx}`. |
|
|
96
|
+
| `max_results` | number | no | Default 100. Clamped server-side. |
|
|
97
|
+
|
|
98
|
+
**Failure modes:** An invalid regex throws `Invalid regex pattern`. Path to a file throws — must be a directory.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## `editor`
|
|
103
|
+
|
|
104
|
+
The workhorse edit tool. Three modes:
|
|
105
|
+
|
|
106
|
+
### Mode 1 — `old_text` / `new_text` (replace a block)
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"path": "/abs/path/to/file.ts",
|
|
111
|
+
"old_text": "export const foo = 1;\n",
|
|
112
|
+
"new_text": "export const foo = 2;\n"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
- `old_text` must match EXACTLY including whitespace and trailing newline.
|
|
117
|
+
- If `old_text` is not found → tool returns error `text not found in <path>`.
|
|
118
|
+
- If `old_text` matches more than once → tool returns error `multiple occurrences of text found`.
|
|
119
|
+
|
|
120
|
+
**This is the #1 cause of agent mistakes.** When in doubt:
|
|
121
|
+
1. First call `read_file` on the file
|
|
122
|
+
2. Copy the exact bytes (including indentation and trailing newline)
|
|
123
|
+
3. Make the smallest possible edit
|
|
124
|
+
|
|
125
|
+
### Mode 2 — `insert_line` (insert at line N)
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"path": "/abs/path/to/file.ts",
|
|
130
|
+
"insert_line": 42,
|
|
131
|
+
"new_text": "// new comment\nconst x = 1;\n"
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- `insert_line` is 1-based. The new content is INSERTED before line N.
|
|
136
|
+
- Use `insert_line: <last line + 1>` to append at EOF.
|
|
137
|
+
- `insert_line` must be in `1..<last line + 1>`. Out-of-range throws.
|
|
138
|
+
|
|
139
|
+
### Mode 3 — file does not exist (create new)
|
|
140
|
+
|
|
141
|
+
If the file does not exist, omit `old_text` and pass only `new_text`. Cline creates the parent directories automatically.
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"path": "/abs/path/to/new-file.ts",
|
|
146
|
+
"new_text": "// brand new file content\n"
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Common failures:**
|
|
151
|
+
- "No replacement performed: text not found" — whitespace mismatch. Re-read the file and copy the bytes exactly.
|
|
152
|
+
- "multiple occurrences" — your `old_text` is too generic. Make it more specific (include more surrounding context).
|
|
153
|
+
- Missing trailing `\n` — the new_text and old_text must end with `\n` if the file does.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## `apply_patch`
|
|
158
|
+
|
|
159
|
+
Multi-file unified-diff patches. Use when editing several files atomically.
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
*** Begin Patch
|
|
163
|
+
*** Update File: /abs/path/file.ts
|
|
164
|
+
@@ context line
|
|
165
|
+
-old line
|
|
166
|
+
+new line
|
|
167
|
+
*** End Patch
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Sentinels are mandatory.** Missing `*** Begin Patch` or `*** End Patch` → throws `Invalid patch text - incomplete sentinels. Try breaking it into smaller patches.`
|
|
171
|
+
|
|
172
|
+
**Prefer `editor` for single-file edits.** Use `apply_patch` only when you need to:
|
|
173
|
+
- Edit 2+ files in one atomic operation
|
|
174
|
+
- Apply a unified diff you already have
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## `execute_command`
|
|
179
|
+
|
|
180
|
+
Run a shell command.
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"command": "ls -la /tmp",
|
|
185
|
+
"cwd": "/abs/path",
|
|
186
|
+
"timeout": 30000
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
| Field | Type | Required | Notes |
|
|
191
|
+
|---|---|---|---|
|
|
192
|
+
| `command` | string | **yes** | Passed to `/bin/bash -c` (Linux/macOS) or `cmd /c` (Windows). |
|
|
193
|
+
| `cwd` | string | no | Defaults to the Cline session's cwd. |
|
|
194
|
+
| `timeout` | number | no | **Max 600,000 ms (10 min).** Larger values are clamped. |
|
|
195
|
+
|
|
196
|
+
**Critical constraints:**
|
|
197
|
+
- **No shell redirects** (`>`, `>>`, `<`) unless `CLINE_COMMAND_PERMISSIONS.allowRedirects` is true. Use `editor` or `apply_patch` to write files.
|
|
198
|
+
- Long-running processes will hit the timeout. For >10min tasks, use `bizar_spawn_background` instead (Bizar plugin tool).
|
|
199
|
+
- The `command` string IS a shell command. Quote carefully. Use `&&` to chain, `;` to sequence, `|` to pipe.
|
|
200
|
+
|
|
201
|
+
**Common failures:**
|
|
202
|
+
- `command not found` — the binary isn't on PATH. Use absolute path or `which <name>` first.
|
|
203
|
+
- `Permission denied` — file isn't executable, or you're writing to a protected dir.
|
|
204
|
+
- `timeout` — increase `timeout` (max 600000) or move to background agent.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## `web_fetch`
|
|
209
|
+
|
|
210
|
+
Fetch a URL and return the content as text.
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"url": "https://example.com/docs"
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
| Field | Type | Required | Notes |
|
|
219
|
+
|---|---|---|---|
|
|
220
|
+
| `url` | string | **yes** | Must be HTTP/HTTPS. No `file://`. |
|
|
221
|
+
|
|
222
|
+
**Failure modes:** Non-HTTP URLs throw. The fetch goes through Cline's content extractor; PDFs, JS-rendered pages, and login-walled sites may return partial content.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## `ask_question`
|
|
227
|
+
|
|
228
|
+
Ask the user ONE clarifying question with 2–5 options. **This is the most-misused tool.**
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"question": "Which database do you want to use?",
|
|
233
|
+
"options": ["PostgreSQL", "MySQL", "SQLite", "MongoDB"]
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
| Field | Type | Required | Notes |
|
|
238
|
+
|---|---|---|---|
|
|
239
|
+
| `question` | string | **yes** | One question. Multi-question calls fail. |
|
|
240
|
+
| `options` | array of 2–5 strings | **yes** | **MUST be an array of strings.** Must be 2–5 items. |
|
|
241
|
+
|
|
242
|
+
### ⚠️ CRITICAL — `options` is REQUIRED, not optional
|
|
243
|
+
|
|
244
|
+
If you pass `options: null`, `options: undefined`, or `options: []`, Cline
|
|
245
|
+
**silently rejects the call** and counts it as a mistake. After 3 such
|
|
246
|
+
silent failures (since v6.2.0; 10 since v6.2.4), the session aborts.
|
|
247
|
+
|
|
248
|
+
### When to use `ask_question`
|
|
249
|
+
|
|
250
|
+
- A key implementation decision has multiple valid paths
|
|
251
|
+
- The user said something ambiguous and you need to clarify before doing real work
|
|
252
|
+
- You're about to make a destructive change (rm, drop table, force-push)
|
|
253
|
+
|
|
254
|
+
### When NOT to use `ask_question`
|
|
255
|
+
|
|
256
|
+
- You can decide safely using sensible defaults
|
|
257
|
+
- The user's intent is clear from context
|
|
258
|
+
- You're just confirming something you should have done already
|
|
259
|
+
- The answer is in the codebase (use `read_file` / `search_files` first)
|
|
260
|
+
|
|
261
|
+
### Alternatives to `ask_question`
|
|
262
|
+
|
|
263
|
+
- **Use `bizar_spawn_team`** to spawn a team that investigates and proposes options
|
|
264
|
+
- **Use `use_subagents`** to parallelize the investigation
|
|
265
|
+
- **Just pick a sensible default** and document it in your final response
|
|
266
|
+
|
|
267
|
+
### Recovery from `ask_question` mistakes
|
|
268
|
+
|
|
269
|
+
If you accidentally pass `options: null` and the tool errors, **DO NOT retry the same broken call**. Instead:
|
|
270
|
+
1. Switch to a sensible default
|
|
271
|
+
2. Document the decision in your final response
|
|
272
|
+
3. Let the user override later if they disagree
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## `use_skill`
|
|
277
|
+
|
|
278
|
+
Activate a skill.
|
|
279
|
+
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"skill": "commit",
|
|
283
|
+
"args": "-m \"Fix auth bug\""
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
| Field | Type | Required | Notes |
|
|
288
|
+
|---|---|---|---|
|
|
289
|
+
| `skill` | string | **yes** | Exact skill name. Run `skills list` to see available. |
|
|
290
|
+
| `args` | string | no | Passed to the skill's runner. |
|
|
291
|
+
|
|
292
|
+
**Failure modes:** Unknown skill name throws. Skills are case-sensitive.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## `use_subagents`
|
|
297
|
+
|
|
298
|
+
Spawn parallel read-only research subagents.
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{
|
|
302
|
+
"prompts": [
|
|
303
|
+
"Trace the auth flow from login button to JWT verification. Cite file paths.",
|
|
304
|
+
"Find every place the database schema is migrated. Cite file paths.",
|
|
305
|
+
"List all the env vars the app reads at startup. Cite file paths."
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
| Field | Type | Required | Notes |
|
|
311
|
+
|---|---|---|---|
|
|
312
|
+
| `prompts` | array of strings | **yes** | **One research question per subagent.** Each prompt should be focused and self-contained. |
|
|
313
|
+
|
|
314
|
+
### Subagent rules
|
|
315
|
+
|
|
316
|
+
- Subagents are **read-only**. They can read files, search, run read-only commands (ls, grep, git log). They **cannot** edit, write, apply patches, or use the browser.
|
|
317
|
+
- Subagents return a focused report citing the most relevant file paths. Read those files yourself before editing.
|
|
318
|
+
- Subagents run in parallel — fire 3–5 at once for broad research, not one at a time.
|
|
319
|
+
- Subagent results do NOT trigger approval — they run under the "Read project files" auto-approve permission.
|
|
320
|
+
|
|
321
|
+
### When to use subagents
|
|
322
|
+
|
|
323
|
+
- Onboarding to an unfamiliar codebase (map architecture in parallel)
|
|
324
|
+
- Investigating cross-cutting concerns (auth + logging + errors)
|
|
325
|
+
- Pre-edit research (gather context from related files)
|
|
326
|
+
|
|
327
|
+
### When NOT to use subagents
|
|
328
|
+
|
|
329
|
+
- Small focused task where you already know which file
|
|
330
|
+
- Editing files (use `editor` or `apply_patch` instead)
|
|
331
|
+
- Running commands that mutate state (use `execute_command` with `cwd`)
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## `task` (Bizar plugin — dispatch to a Bizar agent)
|
|
336
|
+
|
|
337
|
+
Synchronously delegate to a Bizar agent (Odin, Thor, Tyr, Heimdall, Mimir, etc.).
|
|
338
|
+
|
|
339
|
+
```json
|
|
340
|
+
{
|
|
341
|
+
"agent": "thor",
|
|
342
|
+
"prompt": "Implement the rate-limiter middleware in src/middleware/ratelimit.ts"
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
| Field | Type | Required | Notes |
|
|
347
|
+
|---|---|---|---|
|
|
348
|
+
| `agent` | string | **yes** | A Bizar agent name: `odin`, `thor`, `tyr`, `heimdall`, `mimir`, `frigg`, `hermod`, `baldr`, `vor`, `vidarr`, `forseti`. NOT a Cline-built-in agent. |
|
|
349
|
+
| `prompt` | string | **yes** | What to do. Be specific. |
|
|
350
|
+
|
|
351
|
+
**Failure modes:** Unknown agent name throws. The agent runs synchronously and returns its result inline.
|
|
352
|
+
|
|
353
|
+
### Sync vs async dispatch
|
|
354
|
+
|
|
355
|
+
- `task` — synchronous, blocks until the agent returns. Use when the parent needs the result before continuing.
|
|
356
|
+
- `bizar_spawn_background` (Bizar plugin) — async, returns immediately. Use for long-running work that doesn't block the parent.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## `bizar_*` tools (Bizar plugin)
|
|
361
|
+
|
|
362
|
+
The Bizar plugin adds these on top of the Cline built-ins:
|
|
363
|
+
|
|
364
|
+
- `bizar_spawn_background(agent, prompt, timeoutMs)` — async background agent
|
|
365
|
+
- `bizar_status(instanceId)` — check background instance
|
|
366
|
+
- `bizar_collect(instanceId, timeoutMs)` — wait for background result (BLOCKS)
|
|
367
|
+
- `bizar_kill(instanceId)` — terminate background
|
|
368
|
+
- `bizar_spawn_team(teamName, mission)` — coordinated agent team
|
|
369
|
+
- `bizar_team_status(sessionId)` — team progress
|
|
370
|
+
- `bizar_plan_action(action, planSlug, ...)` — visual plan canvas
|
|
371
|
+
- `bizar_wait_for_feedback(planSlug)` — block until human reviews plan
|
|
372
|
+
- `bizar_memory_search(query)` / `read` / `write` / `list` — Bizar memory vault
|
|
373
|
+
- `bizar_graph_query(concept)` / `path` / `explain` — knowledge graph
|
|
374
|
+
|
|
375
|
+
These are documented in `.cline/instructions/bizar-tools.md` (auto-loaded into every session).
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Recovery: when you hit the mistake limit
|
|
380
|
+
|
|
381
|
+
If Cline says "max consecutive mistakes reached (3 in v6.2.0–v6.2.3, 10 since v6.2.4)", the session aborts. To recover:
|
|
382
|
+
|
|
383
|
+
1. **Stop retrying the same broken call.** Each retry wastes a mistake.
|
|
384
|
+
2. **Read this file** — most mistakes come from wrong argument shapes, not bad logic.
|
|
385
|
+
3. **Use simpler tools** — `read_file` instead of `editor` for inspection; `apply_patch` instead of `editor` for multi-line.
|
|
386
|
+
4. **Spawn a fresh session** if the runtime is in a bad state.
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Per-tool I/O contract
|
|
391
|
+
|
|
392
|
+
All Cline tools return text via stdout-like output. Failed tools return
|
|
393
|
+
either:
|
|
394
|
+
- A structured error message (e.g. "No replacement performed: text not found in /path")
|
|
395
|
+
- An exception thrown back to the agent (which Cline wraps as a mistake)
|
|
396
|
+
|
|
397
|
+
There is no `success: true|false` field. You must read the response text
|
|
398
|
+
to know what happened.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: agent-browser — Primary agent for browser-driven E2E verification. No-edit permissions. Drives Chrome for Testing via the agent-browser CLI for end-to-end testing of web apps.
|
|
2
|
+
description: agent-browser — Primary agent for browser-driven E2E verification. No-edit permissions. Drives Chrome for Testing via the agent-browser CLI for end-to-end testing of web apps. Reads `_shared/CLINE_TOOLS.md` before any tool call.
|
|
3
3
|
mode: primary
|
|
4
4
|
model: openrouter/minimax/minimax-m2.7
|
|
5
5
|
color: "#84cc16"
|
package/config/agents/baldr.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Baldr — UI/UX design system specialist. Creates DESIGN.md files using Google's design.md standard. Aesthetic direction, typography, design tokens, anti-slop audits. Does not implement code.
|
|
2
|
+
description: Baldr — UI/UX design system specialist. Creates DESIGN.md files using Google's design.md standard. Aesthetic direction, typography, design tokens, anti-slop audits. Does not implement code., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#ec4899"
|
package/config/agents/forseti.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Forseti — Audits, criticizes, and corrects implementation plans before execution. No write permissions. Review only.
|
|
2
|
+
description: Forseti — Audits, criticizes, and corrects implementation plans before execution. No write permissions. Review only., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M3
|
|
5
5
|
color: "#ef4444"
|
package/config/agents/frigg.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Frigg — Read-only codebase Q&A. Answers questions about the project with file references, never modifies anything. Routes to no one.
|
|
2
|
+
description: Frigg — Read-only codebase Q&A. Answers questions about the project with file references, never modifies anything. Routes to no one., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#f472b6"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Heimdall — Simple, routine, and deterministic tasks using DeepSeek. Quick edits, mechanical work, file operations. The ever-watchful guardian.
|
|
2
|
+
description: Heimdall — Simple, routine, and deterministic tasks using DeepSeek. Quick edits, mechanical work, file operations. The ever-watchful guardian., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#10b981"
|
package/config/agents/hermod.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Hermod — Git and GitHub operations specialist using MiniMax M2.7. The only agent allowed to perform write-level git (commit, push, merge, rebase, branch) and `gh` CLI operations.
|
|
2
|
+
description: Hermod — Git and GitHub operations specialist using MiniMax M2.7. The only agent allowed to perform write-level git (commit, push, merge, rebase, branch) and `gh` CLI operations., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#f59e0b"
|
package/config/agents/mimir.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Mimir — Deep codebase research and exploration. Uses Semble as primary search tool. Architecture analysis, pattern discovery, documentation research, and project initialization.
|
|
2
|
+
description: Mimir — Deep codebase research and exploration. Uses Semble as primary search tool. Architecture analysis, pattern discovery, documentation research, and project initialization., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#06b6d4"
|
package/config/agents/odin.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Odin — Pure router that delegates all work to subagents. Routes across Frigg (DeepSeek/Q&A), Vör (DeepSeek/clarify), Mimir (DeepSeek/research), Heimdall (DeepSeek/simple), Hermod (M2.7/git), Thor (M2.7/mid), Baldr (M2.7/design), Tyr (M3/top), Vidarr (GPT-5.5/ultra), Forseti (verifier/M3).
|
|
2
|
+
description: Odin — Pure router that delegates all work to subagents. Routes across Frigg (DeepSeek/Q&A), Vör (DeepSeek/clarify), Mimir (DeepSeek/research), Heimdall (DeepSeek/simple), Hermod (M2.7/git), Thor (M2.7/mid), Baldr (M2.7/design), Tyr (M3/top), Vidarr (GPT-5.5/ultra), Forseti (verifier/M3)., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: primary
|
|
4
4
|
model: minimaxcustom/MiniMax-M3
|
|
5
5
|
color: "#6366f1"
|
package/config/agents/quick.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Quick (quick) — fast single-shot tasks. No delegation, no parallel streams. Use for small edits, mechanical changes, one-shot questions. Routes to no one.
|
|
2
|
+
description: Quick (quick) — fast single-shot tasks. No delegation, no parallel streams. Use for small edits, mechanical changes, one-shot questions. Routes to no one., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: primary
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7-highspeed
|
|
5
5
|
color: "#22d3ee"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Code search agent for exploring any codebase. Use for finding code by intent, locating implementations, understanding how something works, or discovering related code. Prefer over Bash/Read for any semantic or exploratory question.
|
|
2
|
+
description: Code search agent for exploring any codebase. Use for finding code by intent, locating implementations, understanding how something works, or discovering related code. Prefer over Bash/Read for any semantic or exploratory question., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#64748b"
|
package/config/agents/thor.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Thor — Handles medium-complexity implementation tasks using MiniMax M2.7. New features, non-trivial debugging, refactoring, code review, and writing tests.
|
|
2
|
+
description: Thor — Handles medium-complexity implementation tasks using MiniMax M2.7. New features, non-trivial debugging, refactoring, code review, and writing tests., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#a855f7"
|
package/config/agents/tyr.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Tyr — Handles the most complex implementation, debugging, and architectural work using MiniMax M3. Reserved for the hardest problems. Always plan-then-Forseti-gate.
|
|
2
|
+
description: Tyr — Handles the most complex implementation, debugging, and architectural work using MiniMax M3. Reserved for the hardest problems. Always plan-then-Forseti-gate., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M3
|
|
5
5
|
color: "#dc2626"
|
package/config/agents/vidarr.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Vidarr — The ultimate fallback via MiniMax M3. For the hardest problems when Tyr stalls, debugging is stuck, or novel insight is needed. Use sparingly — highest cost.
|
|
2
|
+
description: Vidarr — The ultimate fallback via MiniMax M3. For the hardest problems when Tyr stalls, debugging is stuck, or novel insight is needed. Use sparingly — highest cost., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M3
|
|
5
5
|
color: "#0ea5e9"
|
package/config/agents/vor.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Vör — Asks clarifying questions for ambiguous or incomplete requests. Reads project context first, then asks one targeted, project-specific question.
|
|
2
|
+
description: Vör — Asks clarifying questions for ambiguous or incomplete requests. Reads project context first, then asks one targeted, project-specific question., Cline tool argument shapes (CLINE_TOOLS.md).
|
|
3
3
|
mode: subagent
|
|
4
4
|
model: minimaxcustom/MiniMax-M2.7
|
|
5
5
|
color: "#a78bfa"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polderlabs/bizar",
|
|
3
|
-
"version": "6.2.
|
|
3
|
+
"version": "6.2.4",
|
|
4
4
|
"description": "Norse-pantheon multi-agent system for cline — 13 agents across 4 cost tiers with cost-aware routing, plans, and a configurable agent harness. v4 ships as a single npm package bundling the dashboard server, cline plugin, and typed SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -177,14 +177,29 @@ export class ClineRuntime {
|
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
179
|
* Merge caller's `execution` block with the runtime default
|
|
180
|
-
* (`defaultMaxConsecutiveMistakes`).
|
|
181
|
-
*
|
|
180
|
+
* (`defaultMaxConsecutiveMistakes`).
|
|
181
|
+
*
|
|
182
|
+
* v6.2.4 — Plugin's defaultMaxConsecutiveMistakes is now a FLOOR,
|
|
183
|
+
* not a default. The Cline CLI's `--retries` flag defaults to 3
|
|
184
|
+
* and previously silently overrode our 6 (or higher) — leading
|
|
185
|
+
* to premature session aborts after just 3 tool errors. Now we
|
|
186
|
+
* use Math.max(plugin_default, caller_value) so the user can
|
|
187
|
+
* still raise the limit with `--retries 15`, but the plugin's
|
|
188
|
+
* higher default is honored on plain `cline` invocations.
|
|
189
|
+
*
|
|
190
|
+
* Returns `undefined` when neither is set, so the optional field
|
|
191
|
+
* stays out of the config payload.
|
|
182
192
|
*/
|
|
183
193
|
private buildExecution(
|
|
184
194
|
callerExecution: StartSessionOpts["execution"],
|
|
185
195
|
): StartSessionOpts["execution"] | undefined {
|
|
186
196
|
if (!callerExecution && this.defaultMaxConsecutiveMistakes === undefined) return undefined;
|
|
187
|
-
const
|
|
197
|
+
const callerMax = callerExecution?.maxConsecutiveMistakes;
|
|
198
|
+
const pluginMax = this.defaultMaxConsecutiveMistakes;
|
|
199
|
+
const max =
|
|
200
|
+
callerMax !== undefined && pluginMax !== undefined
|
|
201
|
+
? Math.max(callerMax, pluginMax)
|
|
202
|
+
: callerMax ?? pluginMax;
|
|
188
203
|
return { ...callerExecution, ...(max !== undefined ? { maxConsecutiveMistakes: max } : {}) };
|
|
189
204
|
}
|
|
190
205
|
|
|
@@ -111,10 +111,14 @@ export const DEFAULT_OPTIONS: NormalizedOptions = {
|
|
|
111
111
|
backgroundThinkingLoopTimeoutMs: 300_000, // 5 min
|
|
112
112
|
backgroundMaxInterventions: 1,
|
|
113
113
|
// v0.3.1 — ClineRuntime execution surface
|
|
114
|
-
// SDK default `??6`; CLI overrides to 3. We pick
|
|
115
|
-
// malformed tool
|
|
116
|
-
// (mistake-recovery.ts) gives the model guidance on the
|
|
117
|
-
|
|
114
|
+
// SDK default `??6`; CLI overrides to 3. We pick 10 so several
|
|
115
|
+
// malformed tool calls don't kill the session; the recovery
|
|
116
|
+
// callback (mistake-recovery.ts) gives the model guidance on the
|
|
117
|
+
// way back. v6.2.4 — bumped from 6 → 10 because the Cline CLI's
|
|
118
|
+
// --retries default of 3 was previously overriding this entirely.
|
|
119
|
+
// Now `buildExecution` uses Math.max(plugin_default, caller_value)
|
|
120
|
+
// so this acts as a FLOOR, not a default.
|
|
121
|
+
clineruntimeMaxConsecutiveMistakes: 10,
|
|
118
122
|
};
|
|
119
123
|
|
|
120
124
|
const SECRET_DIRS: readonly string[] = [
|
|
@@ -380,9 +384,12 @@ export function normalizeOptions(raw: RawOptions | undefined): {
|
|
|
380
384
|
|
|
381
385
|
// --- v0.3.1 ClineRuntime execution surface -------------------------------
|
|
382
386
|
|
|
383
|
-
// clineruntimeMaxConsecutiveMistakes: default
|
|
384
|
-
//
|
|
385
|
-
//
|
|
387
|
+
// clineruntimeMaxConsecutiveMistakes: default 10, range [3, 20]
|
|
388
|
+
// v6.2.4 — bumped from 6 to 10. CLI default is 3 which aborts
|
|
389
|
+
// sessions on the FIRST 3 malformed tool calls (editor { new_text:
|
|
390
|
+
// undefined }, run_commands exit code != 0, ask_question { options:
|
|
391
|
+
// null }, …). With the v6.2.4 buildExecution fix (Math.max floor),
|
|
392
|
+
// our higher default now always wins on plain `cline` invocations.
|
|
386
393
|
// The harness wires a recovery callback that keeps the session alive on
|
|
387
394
|
// recoverable mistakes, so we only need a slightly-larger ceiling.
|
|
388
395
|
const rawMaxConsecutive = toFiniteInt(r.clineruntimeMaxConsecutiveMistakes);
|
|
@@ -73,7 +73,7 @@ describe("ClineRuntime.startSession — execution plumbing", () => {
|
|
|
73
73
|
};
|
|
74
74
|
const runtime = new ClineRuntime({
|
|
75
75
|
logger: stubLogger(),
|
|
76
|
-
defaultMaxConsecutiveMistakes:
|
|
76
|
+
defaultMaxConsecutiveMistakes: 10,
|
|
77
77
|
defaultOnConsecutiveMistakeLimitReached: recovery,
|
|
78
78
|
});
|
|
79
79
|
(runtime as unknown as { core: unknown }).core = makeFakeCore();
|
|
@@ -84,16 +84,57 @@ describe("ClineRuntime.startSession — execution plumbing", () => {
|
|
|
84
84
|
prompt: "go",
|
|
85
85
|
});
|
|
86
86
|
const cfg = capturedConfig[0]!.config;
|
|
87
|
-
expect(cfg.execution).toEqual({ maxConsecutiveMistakes:
|
|
87
|
+
expect(cfg.execution).toEqual({ maxConsecutiveMistakes: 10 });
|
|
88
88
|
expect(typeof cfg.onConsecutiveMistakeLimitReached).toBe("function");
|
|
89
89
|
// Invoke the wire-through function and confirm it IS the recovery closure.
|
|
90
90
|
const fn = cfg.onConsecutiveMistakeLimitReached as (ctx: ConsecutiveMistakeLimitContext) => unknown;
|
|
91
|
-
fn({ iteration: 1, consecutiveMistakes: 3, maxConsecutiveMistakes:
|
|
91
|
+
fn({ iteration: 1, consecutiveMistakes: 3, maxConsecutiveMistakes: 10, reason: "invalid_tool_call" });
|
|
92
92
|
expect(recoveryCalls.length).toBe(1);
|
|
93
93
|
expect(recoveryCalls[0]!.reason).toBe("invalid_tool_call");
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
test("
|
|
96
|
+
test("v6.2.4 — plugin default is a FLOOR; CLI default of 3 is bumped to plugin default", async () => {
|
|
97
|
+
// This is the v6.2.0 → v6.2.4 regression test. Previously the
|
|
98
|
+
// caller's maxConsecutiveMistakes (e.g. the Cline CLI's --retries
|
|
99
|
+
// default of 3) would silently override the plugin's higher
|
|
100
|
+
// default. Now we use Math.max so the plugin's 10 wins.
|
|
101
|
+
const runtime = new ClineRuntime({
|
|
102
|
+
logger: stubLogger(),
|
|
103
|
+
defaultMaxConsecutiveMistakes: 10,
|
|
104
|
+
});
|
|
105
|
+
(runtime as unknown as { core: unknown }).core = makeFakeCore();
|
|
106
|
+
await runtime.startSession({
|
|
107
|
+
providerId: "anthropic",
|
|
108
|
+
modelId: "claude-sonnet-4-6",
|
|
109
|
+
workspaceRoot: "/tmp",
|
|
110
|
+
prompt: "go",
|
|
111
|
+
execution: { maxConsecutiveMistakes: 3, reminderAfterIterations: 8 },
|
|
112
|
+
});
|
|
113
|
+
const cfg = capturedConfig[0]!.config;
|
|
114
|
+
expect(cfg.execution?.maxConsecutiveMistakes).toBe(10,
|
|
115
|
+
"plugin default must win over CLI default of 3 (was a v6.0 regression)");
|
|
116
|
+
expect(cfg.execution?.reminderAfterIterations).toBe(8, "other caller fields pass through");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("caller-supplied HIGHER execution.maxConsecutiveMistakes still wins", async () => {
|
|
120
|
+
const runtime = new ClineRuntime({
|
|
121
|
+
logger: stubLogger(),
|
|
122
|
+
defaultMaxConsecutiveMistakes: 10,
|
|
123
|
+
});
|
|
124
|
+
(runtime as unknown as { core: unknown }).core = makeFakeCore();
|
|
125
|
+
await runtime.startSession({
|
|
126
|
+
providerId: "anthropic",
|
|
127
|
+
modelId: "claude-sonnet-4-6",
|
|
128
|
+
workspaceRoot: "/tmp",
|
|
129
|
+
prompt: "go",
|
|
130
|
+
execution: { maxConsecutiveMistakes: 20, reminderAfterIterations: 8 },
|
|
131
|
+
});
|
|
132
|
+
const cfg = capturedConfig[0]!.config;
|
|
133
|
+
expect(cfg.execution?.maxConsecutiveMistakes).toBe(20,
|
|
134
|
+
"user can still raise the limit with --retries 20");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("caller-supplied execution.maxConsecutiveMistakes wins over default (legacy behavior)", async () => {
|
|
97
138
|
const runtime = new ClineRuntime({
|
|
98
139
|
logger: stubLogger(),
|
|
99
140
|
defaultMaxConsecutiveMistakes: 4,
|
|
@@ -278,16 +278,16 @@ describe("readEnvFlags", () => {
|
|
|
278
278
|
// ── clineruntimeMaxConsecutiveMistakes ───────────────────────────────────────
|
|
279
279
|
|
|
280
280
|
describe("clineruntimeMaxConsecutiveMistakes (v0.3.1)", () => {
|
|
281
|
-
test("default is
|
|
281
|
+
test("default is 10 when neither raw nor env is provided (v6.2.4)", () => {
|
|
282
282
|
delete process.env.BIZAR_MAX_CONSECUTIVE_MISTAKES;
|
|
283
283
|
const { options } = normalizeOptions({});
|
|
284
|
-
expect(options.clineruntimeMaxConsecutiveMistakes).toBe(
|
|
284
|
+
expect(options.clineruntimeMaxConsecutiveMistakes).toBe(10);
|
|
285
285
|
});
|
|
286
286
|
|
|
287
287
|
test("raw value is honored when in range", () => {
|
|
288
288
|
delete process.env.BIZAR_MAX_CONSECUTIVE_MISTAKES;
|
|
289
|
-
const { options, notes } = normalizeOptions({ clineruntimeMaxConsecutiveMistakes:
|
|
290
|
-
expect(options.clineruntimeMaxConsecutiveMistakes).toBe(
|
|
289
|
+
const { options, notes } = normalizeOptions({ clineruntimeMaxConsecutiveMistakes: 15 });
|
|
290
|
+
expect(options.clineruntimeMaxConsecutiveMistakes).toBe(15);
|
|
291
291
|
expect(notes.some((n) => n.includes("clineruntimeMaxConsecutiveMistakes"))).toBe(false);
|
|
292
292
|
});
|
|
293
293
|
|
|
@@ -321,9 +321,9 @@ describe("clineruntimeMaxConsecutiveMistakes (v0.3.1)", () => {
|
|
|
321
321
|
delete process.env.BIZAR_MAX_CONSECUTIVE_MISTAKES;
|
|
322
322
|
});
|
|
323
323
|
|
|
324
|
-
test("non-numeric raw falls back to default", () => {
|
|
324
|
+
test("non-numeric raw falls back to default (10)", () => {
|
|
325
325
|
delete process.env.BIZAR_MAX_CONSECUTIVE_MISTAKES;
|
|
326
326
|
const { options } = normalizeOptions({ clineruntimeMaxConsecutiveMistakes: "not-a-number" });
|
|
327
|
-
expect(options.clineruntimeMaxConsecutiveMistakes).toBe(
|
|
327
|
+
expect(options.clineruntimeMaxConsecutiveMistakes).toBe(10);
|
|
328
328
|
});
|
|
329
329
|
});
|
package/scripts/bh-full-e2e.mjs
CHANGED
|
@@ -343,6 +343,28 @@ try {
|
|
|
343
343
|
record('plugin hooks dir scannable', false, err.message);
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
// ── 9.5. Verify all 14 agents reference the shared docs (v6.2.4) ─────
|
|
347
|
+
// Catches drift: an agent that doesn't reference AGENT_BASELINE.md or
|
|
348
|
+
// CLINE_TOOLS.md won't get the always-on rules at runtime.
|
|
349
|
+
try {
|
|
350
|
+
const { spawnSync } = await import('node:child_process');
|
|
351
|
+
const r = spawnSync('node', ['scripts/check-agents.mjs'], {
|
|
352
|
+
encoding: 'utf8',
|
|
353
|
+
cwd: REPO_ROOT,
|
|
354
|
+
timeout: 10000,
|
|
355
|
+
});
|
|
356
|
+
if (r.status === 0) {
|
|
357
|
+
// Extract the count from the output
|
|
358
|
+
const m = /All (\d+) agents/.exec(r.stdout || '');
|
|
359
|
+
const n = m ? m[1] : '?';
|
|
360
|
+
record('all 14 agents reference AGENT_BASELINE + CLINE_TOOLS', true, `${n} agents OK`);
|
|
361
|
+
} else {
|
|
362
|
+
record('all 14 agents reference AGENT_BASELINE + CLINE_TOOLS', false, (r.stdout || r.stderr || '').trim().split('\n').slice(-3).join(' | '));
|
|
363
|
+
}
|
|
364
|
+
} catch (err) {
|
|
365
|
+
record('all 14 agents reference AGENT_BASELINE + CLINE_TOOLS', false, err.message);
|
|
366
|
+
}
|
|
367
|
+
|
|
346
368
|
// ── 10. Verify cline CLI is on PATH and recent enough ──────────
|
|
347
369
|
try {
|
|
348
370
|
const { spawnSync } = await import('node:child_process');
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scripts/check-agents.mjs
|
|
3
|
+
*
|
|
4
|
+
* v6.2.4 — Verifies every agent file references the right shared docs.
|
|
5
|
+
*
|
|
6
|
+
* Fails (exit 1) if any of the 14 Bizar agents is missing the
|
|
7
|
+
* AGENT_BASELINE or CLINE_TOOLS reference. This catches drift early —
|
|
8
|
+
* an agent that doesn't reference the baseline doesn't get the
|
|
9
|
+
* always-on rules at runtime.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const ROOT = join(__filename, '..', '..');
|
|
17
|
+
|
|
18
|
+
const AGENT_FILES = [
|
|
19
|
+
'agent-browser.md',
|
|
20
|
+
'baldr.md',
|
|
21
|
+
'forseti.md',
|
|
22
|
+
'frigg.md',
|
|
23
|
+
'heimdall.md',
|
|
24
|
+
'hermod.md',
|
|
25
|
+
'mimir.md',
|
|
26
|
+
'odin.md',
|
|
27
|
+
'quick.md',
|
|
28
|
+
'semble-search.md',
|
|
29
|
+
'thor.md',
|
|
30
|
+
'tyr.md',
|
|
31
|
+
'vidarr.md',
|
|
32
|
+
'vor.md',
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
let failed = 0;
|
|
36
|
+
const rows = [];
|
|
37
|
+
|
|
38
|
+
for (const file of AGENT_FILES) {
|
|
39
|
+
const path = join(ROOT, 'config', 'agents', file);
|
|
40
|
+
let text = '';
|
|
41
|
+
try {
|
|
42
|
+
text = readFileSync(path, 'utf8');
|
|
43
|
+
} catch (err) {
|
|
44
|
+
rows.push([file, 'MISSING FILE', '']);
|
|
45
|
+
failed++;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const hasBaseline = /AGENT_BASELINE|agent-baseline/i.test(text);
|
|
49
|
+
const hasClineTools = /CLINE_TOOLS/i.test(text);
|
|
50
|
+
if (!hasBaseline && !hasClineTools) {
|
|
51
|
+
rows.push([file, 'NO REFERENCE', 'needs AGENT_BASELINE or CLINE_TOOLS in description']);
|
|
52
|
+
failed++;
|
|
53
|
+
} else {
|
|
54
|
+
const refs = [
|
|
55
|
+
hasBaseline ? 'AGENT_BASELINE' : null,
|
|
56
|
+
hasClineTools ? 'CLINE_TOOLS' : null,
|
|
57
|
+
].filter(Boolean).join('+');
|
|
58
|
+
rows.push([file, 'OK', refs]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log('\n Agent → Shared-Docs reference check (v6.2.4)\n');
|
|
63
|
+
console.log(' ' + 'agent'.padEnd(24) + 'status'.padEnd(14) + 'references');
|
|
64
|
+
console.log(' ' + '-'.repeat(60));
|
|
65
|
+
for (const [file, status, refs] of rows) {
|
|
66
|
+
console.log(' ' + file.padEnd(24) + status.padEnd(14) + refs);
|
|
67
|
+
}
|
|
68
|
+
console.log('');
|
|
69
|
+
if (failed > 0) {
|
|
70
|
+
console.log(` ✗ ${failed} agent(s) missing the AGENT_BASELINE/CLINE_TOOLS reference.\n`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
console.log(` ✓ All ${AGENT_FILES.length} agents reference the shared docs.\n`);
|