@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.
@@ -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
- Every Bizar agent follows these rules at all times. They are translated from the upstream Claude Fable 5 system prompt, with every Claude-specific tool / function / directory mapped to the BizarHarness equivalent (cline tools, Semble, Skills CLI, Obsidian vault, agent-browser, dashboard artifact pipeline).
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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polderlabs/bizar-plugin",
3
- "version": "6.2.3",
3
+ "version": "6.2.4",
4
4
  "description": "Bizar Norse-pantheon multi-agent plugin for Cline — 14 agents across 4 cost tiers with cost-aware routing and plans.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -177,14 +177,29 @@ export class ClineRuntime {
177
177
 
178
178
  /**
179
179
  * Merge caller's `execution` block with the runtime default
180
- * (`defaultMaxConsecutiveMistakes`). Returns `undefined` when neither
181
- * is set, so the optional field stays out of the config payload.
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 max = callerExecution?.maxConsecutiveMistakes ?? this.defaultMaxConsecutiveMistakes;
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 6 so a single
115
- // malformed tool call doesn't kill the session; the recovery callback
116
- // (mistake-recovery.ts) gives the model guidance on the way back.
117
- clineruntimeMaxConsecutiveMistakes: 6,
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 6, range [3, 20]
384
- // CLI default is 3 which aborts sessions on the FIRST malformed tool call
385
- // (editor { new_text: undefined }, ask_question { options: null }, …).
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: 6,
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: 6 });
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: 6, reason: "invalid_tool_call" });
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("caller-supplied execution.maxConsecutiveMistakes wins over default", async () => {
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 6 when neither raw nor env is provided", () => {
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(6);
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: 10 });
290
- expect(options.clineruntimeMaxConsecutiveMistakes).toBe(10);
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(6);
327
+ expect(options.clineruntimeMaxConsecutiveMistakes).toBe(10);
328
328
  });
329
329
  });
@@ -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`);