@polderlabs/bizar 6.2.0 → 6.2.2

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://docs.cline.bot/config.json",
3
3
  "instructions": [".cline/instructions/bizar-tools.md"],
4
- "model": "9router/minimax/MiniMax-M3",
5
- "small_model": "9router/minimax/MiniMax-M2.7",
4
+ "model": "minimaxcustom/MiniMax-M3",
5
+ "small_model": "minimaxcustom/MiniMax-M2.7",
6
6
  "default_agent": "odin",
7
7
  "permission": "allow",
8
8
  "snapshot": false,
@@ -35,7 +35,7 @@
35
35
  "threshold": 0.5,
36
36
  "preserve_recent": 10,
37
37
  "strategy": "summarize",
38
- "model": "9router/minimax/MiniMax-M3"
38
+ "model": "minimaxcustom/MiniMax-M3"
39
39
  }
40
40
  }]
41
41
  ],
@@ -52,7 +52,7 @@
52
52
  "odin": {
53
53
  "description": "Odin — Pure router that delegates all work to subagents.",
54
54
  "mode": "primary",
55
- "model": "9router/minimax/MiniMax-M3",
55
+ "model": "minimaxcustom/MiniMax-M3",
56
56
  "color": "#6366f1",
57
57
  "permission": {
58
58
  "task": "allow",
@@ -66,7 +66,7 @@
66
66
  "vor": {
67
67
  "description": "Vör — The Questioning One.",
68
68
  "mode": "subagent",
69
- "model": "9router/minimax/MiniMax-M2.7",
69
+ "model": "minimaxcustom/MiniMax-M2.7",
70
70
  "color": "#8b5cf6",
71
71
  "permission": {
72
72
  "read": "allow",
@@ -77,7 +77,7 @@
77
77
  "frigg": {
78
78
  "description": "Frigg — All-knowing Q&A agent.",
79
79
  "mode": "primary",
80
- "model": "9router/minimax/MiniMax-M2.7",
80
+ "model": "minimaxcustom/MiniMax-M2.7",
81
81
  "color": "#06b6d4",
82
82
  "permission": {
83
83
  "read": "allow",
@@ -93,7 +93,7 @@
93
93
  "quick": {
94
94
  "description": "Quick — Fast single-shot tasks.",
95
95
  "mode": "primary",
96
- "model": "9router/minimax/MiniMax-M2.7",
96
+ "model": "minimaxcustom/MiniMax-M2.7",
97
97
  "color": "#22d3ee",
98
98
  "permission": {
99
99
  "read": "allow",
@@ -112,7 +112,7 @@
112
112
  "mimir": {
113
113
  "description": "Mimir — Research and codebase exploration agent.",
114
114
  "mode": "subagent",
115
- "model": "9router/minimax/MiniMax-M2.7",
115
+ "model": "minimaxcustom/MiniMax-M2.7",
116
116
  "color": "#0ea5e9",
117
117
  "permission": {
118
118
  "read": "allow",
@@ -130,7 +130,7 @@
130
130
  "heimdall": {
131
131
  "description": "Heimdall — Simple, routine, deterministic tasks.",
132
132
  "mode": "subagent",
133
- "model": "9router/minimax/MiniMax-M2.7",
133
+ "model": "minimaxcustom/MiniMax-M2.7",
134
134
  "color": "#10b981",
135
135
  "permission": {
136
136
  "read": "allow",
@@ -147,7 +147,7 @@
147
147
  "hermod": {
148
148
  "description": "Hermod — Git and GitHub operations specialist.",
149
149
  "mode": "subagent",
150
- "model": "9router/minimax/MiniMax-M2.7",
150
+ "model": "minimaxcustom/MiniMax-M2.7",
151
151
  "color": "#06b6d4",
152
152
  "permission": {
153
153
  "read": "allow",
@@ -163,7 +163,7 @@
163
163
  "thor": {
164
164
  "description": "Thor — Medium-complexity tasks, strong and reliable.",
165
165
  "mode": "subagent",
166
- "model": "9router/minimax/MiniMax-M2.7",
166
+ "model": "minimaxcustom/MiniMax-M2.7",
167
167
  "color": "#a855f7",
168
168
  "permission": {
169
169
  "read": "allow",
@@ -180,7 +180,7 @@
180
180
  "baldr": {
181
181
  "description": "Baldr — UI/UX design system specialist.",
182
182
  "mode": "subagent",
183
- "model": "9router/minimax/MiniMax-M2.7",
183
+ "model": "minimaxcustom/MiniMax-M2.7",
184
184
  "color": "#ec4899",
185
185
  "permission": {
186
186
  "read": "allow",
@@ -197,7 +197,7 @@
197
197
  "tyr": {
198
198
  "description": "Tyr — Complex implementation, debugging, architecture.",
199
199
  "mode": "subagent",
200
- "model": "9router/minimax/MiniMax-M3",
200
+ "model": "minimaxcustom/MiniMax-M3",
201
201
  "color": "#f59e0b",
202
202
  "permission": {
203
203
  "read": "allow",
@@ -214,7 +214,7 @@
214
214
  "vidarr": {
215
215
  "description": "Vidarr — Ultimate fallback via MiniMax M3.",
216
216
  "mode": "subagent",
217
- "model": "9router/minimax/MiniMax-M3",
217
+ "model": "minimaxcustom/MiniMax-M3",
218
218
  "color": "#dc2626",
219
219
  "permission": {
220
220
  "read": "allow",
@@ -231,7 +231,7 @@
231
231
  "forseti": {
232
232
  "description": "Forseti — Audits and corrects plans before execution.",
233
233
  "mode": "subagent",
234
- "model": "9router/minimax/MiniMax-M3",
234
+ "model": "minimaxcustom/MiniMax-M3",
235
235
  "color": "#ef4444",
236
236
  "permission": {
237
237
  "read": "allow",
@@ -249,7 +249,7 @@
249
249
  "browser-harness": {
250
250
  "description": "browser-harness — Primary agent for browser-driven E2E verification. No-edit permissions. Drives Chrome via CDP for end-to-end testing of web apps.",
251
251
  "mode": "primary",
252
- "model": "9router/minimax/MiniMax-M2.7",
252
+ "model": "minimaxcustom/MiniMax-M2.7",
253
253
  "color": "#84cc16",
254
254
  "permission": {
255
255
  "read": "allow",
@@ -332,84 +332,11 @@
332
332
  "description": "Validate the Bizar install: cline.json, plugin entry, agents, skills, hooks, rules, commands, and provider config.",
333
333
  "agent": "heimdall",
334
334
  "template": "commands-bizar/validate.md\n\n$ARGUMENTS"
335
- }
336
- },
337
- "provider": {
338
- "9router": {
339
- "baseUrl": "http://localhost:20128/v1",
340
- "apiKey": "${env:NINEROUTER_KEY}",
341
- "models": {
342
- "minimax/MiniMax-M3": {
343
- "interleaved": { "field": "reasoning_details" },
344
- "reasoning": true,
345
- "options": {
346
- "thinking": { "type": "enabled" }
347
- }
348
- },
349
- "minimax/MiniMax-M2.7": {
350
- "interleaved": { "field": "reasoning_details" },
351
- "reasoning": true,
352
- "options": {
353
- "thinking": { "type": "enabled" }
354
- }
355
- },
356
- "minimax/MiniMax-M2.5": {
357
- "interleaved": { "field": "reasoning_details" },
358
- "reasoning": true,
359
- "options": {
360
- "thinking": { "type": "enabled" }
361
- }
362
- },
363
- "minimax/MiniMax-M2.1": {
364
- "interleaved": { "field": "reasoning_details" },
365
- "reasoning": true,
366
- "options": {
367
- "thinking": { "type": "enabled" }
368
- }
369
- },
370
- "kr/auto": {
371
- "reasoning": false
372
- },
373
- "kr/auto-thinking": {
374
- "reasoning": true
375
- },
376
- "kr/claude-sonnet-4.5": {
377
- "reasoning": false
378
- },
379
- "kr/claude-haiku-4.5": {
380
- "reasoning": false
381
- },
382
- "kr/deepseek-3.2": {
383
- "reasoning": false
384
- },
385
- "openrouter/cohere/north-mini-code:free": {
386
- "reasoning": false
387
- },
388
- "openrouter/poolside/laguna-m.1:free": {
389
- "reasoning": false
390
- },
391
- "openrouter/nvidia/nemotron-3-super-120b-a12b:free": {
392
- "reasoning": true
393
- }
394
- }
395
335
  },
396
- "minimax": {
397
- "models": {
398
- "MiniMax-M3": {
399
- "interleaved": { "field": "reasoning_details" },
400
- "reasoning": true,
401
- "options": {
402
- "thinking": { "type": "enabled" }
403
- }
404
- },
405
- "MiniMax-M2.7": {
406
- "interleaved": { "field": "reasoning_details" },
407
- "reasoning": true,
408
- "options": {
409
- "thinking": { "type": "enabled" }
410
- }
411
- }
412
- }
336
+ "setup-provider": {
337
+ "description": "Configure a provider in cline.json. Since v6.2.2 the installer no longer touches provider config — use this to add your own.",
338
+ "agent": "heimdall",
339
+ "template": "commands-bizar/setup-provider.md\n\n$ARGUMENTS"
413
340
  }
414
341
  }
415
342
  }
@@ -0,0 +1,95 @@
1
+ ---
2
+ description: Configure a provider in cline.json (apiKey, baseUrl, model catalog). The installer no longer touches provider config — use this command to set one up.
3
+ agent: heimdall
4
+ ---
5
+ # /setup-provider — Configure a provider in cline.json
6
+
7
+ The Bizar installer no longer configures a provider for you (since
8
+ v6.2.2 — the user owns provider config). Use this command to add
9
+ or update a provider in `~/.cline/cline.json`.
10
+
11
+ ## What It Does
12
+
13
+ Interactively (or non-interactively with flags), the setup-provider
14
+ command writes a `provider` block to `~/.cline/cline.json` with:
15
+
16
+ - `baseUrl` — the API endpoint (e.g. `http://localhost:20128/v1` for
17
+ the local 9Router gateway)
18
+ - `apiKey` — the provider's API key (read from `env:` reference or
19
+ direct value)
20
+ - `models` — the model catalog (the IDs returned by
21
+ `GET /v1/models`)
22
+
23
+ ## Default: 9Router Gateway
24
+
25
+ If the user invokes `/setup-provider` with no arguments, default to
26
+ the local 9Router gateway at `http://localhost:20128/v1`. The
27
+ catalog comes from `GET http://localhost:20128/v1/models`. As of
28
+ v6.2.2, that catalog includes:
29
+
30
+ - `minimax/MiniMax-M3` (reasoning)
31
+ - `minimax/MiniMax-M2.7` (reasoning)
32
+ - `nvidia/minimaxai/minimax-m3` (reasoning)
33
+ - `nvidia/minimaxai/minimax-m2.7` (reasoning)
34
+ - `nvidia/z-ai/glm-5.2`
35
+ - `nvidia/deepseek-ai/deepseek-v4-pro`
36
+ - `nvidia/deepseek-ai/deepseek-v4-flash`
37
+ - `nvidia/moonshotai/kimi-k2.6`
38
+ - `nvidia/nemotron-3-ultra-550b-a55b`
39
+ - `openrouter/cohere/north-mini-code:free`
40
+ - `openrouter/poolside/laguna-m.1:free`
41
+ - `openrouter/nvidia/nemotron-3-super-120b-a12b:free`
42
+ - (and several more `minimax/MiniMax-M2.x` variants)
43
+
44
+ ## Flags
45
+
46
+ - `--gateway <url>` — override the 9Router URL (default
47
+ `http://localhost:20128/v1`)
48
+ - `--key <key>` — provider API key (writes `${env:KEY_NAME}` if it
49
+ looks like an env var name, otherwise writes the literal)
50
+ - `--provider <name>` — provider name in cline.json (default `9router`)
51
+ - `--model <id>` — add a single model instead of fetching the catalog
52
+ - `--list` — print the model catalog from `/v1/models` and exit
53
+ - `--remove <name>` — remove a provider by name
54
+
55
+ ## Examples
56
+
57
+ ```
58
+ # Use the default 9Router gateway with the live model catalog
59
+ /setup-provider
60
+
61
+ # Custom provider
62
+ /setup-provider --provider my-anthropic --gateway https://api.anthropic.com/v1 --key sk-ant-...
63
+
64
+ # Just list the available models
65
+ /setup-provider --list
66
+ ```
67
+
68
+ ## Implementation
69
+
70
+ 1. If `--list`, GET `${gateway}/v1/models` and pretty-print the IDs.
71
+ 2. If `--remove`, edit `~/.cline/cline.json` and remove the
72
+ `provider.<name>` block.
73
+ 3. Otherwise, read `~/.cline/cline.json`. If the file doesn't
74
+ exist, error — the user should run `bizar install` first.
75
+ 4. Build the new `provider.<name>` block from the flags + fetched
76
+ catalog.
77
+ 5. Write the file back atomically (write to `cline.json.tmp`,
78
+ then `rename`).
79
+ 6. Run `bizar validate` to confirm everything is wired up.
80
+
81
+ ## Security
82
+
83
+ Never echo or log the full API key. If the user supplies a key on
84
+ the command line, write it as a literal value (or `${env:KEY}`
85
+ reference if it matches a `KEY_NAME` pattern). Never commit
86
+ `~/.cline/cline.json` to source control — it may contain real
87
+ secrets.
88
+
89
+ ## Related
90
+
91
+ - `bizar connect` — interactive TUI for provider setup (alternative)
92
+ - `bizar install` — installs the Bizar scaffolding (NOT provider config
93
+ since v6.2.2)
94
+ - `bizar validate` — confirms provider config is wired correctly
95
+ - Cline provider config: https://docs.cline.bot/customization/providers
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ // PostToolUse — Bizar harness hook.
3
+ //
4
+ // Runs AFTER a tool completes. Reads JSON from stdin, outputs JSON to
5
+ // stdout. This hook does NOT block (post-tool actions can't undo the
6
+ // call); it just adds context for the AI's next decision.
7
+ //
8
+ // Responsibilities:
9
+ // 1. Log tool latency for performance observability (append-only JSONL).
10
+ // 2. Surface any pre-tool warnings (e.g. console.log detected) AFTER
11
+ // the tool ran, so the model gets a second chance to fix it.
12
+ // 3. Remind the AI to run /test before claiming "done".
13
+
14
+ 'use strict';
15
+
16
+ const fs = require('fs');
17
+ const os = require('os');
18
+ const path = require('path');
19
+
20
+ let raw = '';
21
+ process.stdin.setEncoding('utf8');
22
+ process.stdin.on('data', (chunk) => { raw += chunk; });
23
+ process.stdin.on('end', () => {
24
+ let input = {};
25
+ try { input = JSON.parse(raw); } catch { input = {}; }
26
+ const post = input.postToolUse || {};
27
+ const toolName = String(post.toolName || '');
28
+ const success = post.success !== false;
29
+ const executionTimeMs = Number(post.executionTimeMs) || 0;
30
+ const params = (post.parameters && typeof post.parameters === 'object') ? post.parameters : {};
31
+
32
+ // 1. Append-only JSONL log under ~/.config/bizar/hook-logs/
33
+ try {
34
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
35
+ fs.mkdirSync(logDir, { recursive: true });
36
+ const today = new Date().toISOString().slice(0, 10);
37
+ const logFile = path.join(logDir, `post-tool-use-${today}.jsonl`);
38
+ const line = JSON.stringify({
39
+ ts: new Date().toISOString(),
40
+ tool: toolName,
41
+ success,
42
+ executionTimeMs,
43
+ sessionId: input.taskId || null,
44
+ });
45
+ fs.appendFileSync(logFile, line + '\n');
46
+ } catch { /* best-effort */ }
47
+
48
+ const out = { cancel: false, contextModification: '' };
49
+ const notes = [];
50
+
51
+ if (!success) {
52
+ notes.push(`Bizar PostToolUse: tool '${toolName}' failed. Investigate the error before proceeding.`);
53
+ } else if (executionTimeMs > 5000) {
54
+ notes.push(`Bizar PostToolUse: tool '${toolName}' took ${executionTimeMs}ms — consider whether this is worth the cost.`);
55
+ }
56
+
57
+ // Surface a reminder for write_to_file / apply_patch to src/.
58
+ const path = params.path || params.file_path || params.filePath || params.target_file || '';
59
+ if (/^write_to_file$|^apply_patch$|^replace_in_file$|^edit$/i.test(toolName) &&
60
+ /\/src\/|\/plugins\/|\/packages\//.test(String(path))) {
61
+ notes.push("Bizar PostToolUse: if you're done editing, run `/test` to gate the change with tests before claiming complete.");
62
+ }
63
+
64
+ out.contextModification = notes.join(' ');
65
+ process.stdout.write(JSON.stringify(out) + '\n');
66
+ });
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ // PreToolUse — Bizar harness hook.
3
+ //
4
+ // Cline hook script (https://docs.cline.bot/customization/hooks).
5
+ // Runs BEFORE any tool call. Reads JSON from stdin, outputs JSON to
6
+ // stdout. Returns `{ cancel: true, errorMessage: "..." }` to block
7
+ // the tool call, or `{ cancel: false, contextModification: "..." }`
8
+ // to add context for the next AI decision.
9
+ //
10
+ // This hook enforces three Bizar harness invariants:
11
+ // 1. Block writes to .env, secrets, .lock files, node_modules.
12
+ // 2. Warn (don't block) on console.log / debugger / .only() in src/.
13
+ // 3. Always return a small context line for the next AI decision.
14
+
15
+ 'use strict';
16
+
17
+ let raw = '';
18
+ process.stdin.setEncoding('utf8');
19
+ process.stdin.on('data', (chunk) => { raw += chunk; });
20
+ process.stdin.on('end', () => {
21
+ let input = {};
22
+ try { input = JSON.parse(raw); } catch { input = {}; }
23
+ const pre = input.preToolUse || {};
24
+ const toolName = String(pre.toolName || '');
25
+ const params = (pre.parameters && typeof pre.parameters === 'object') ? pre.parameters : {};
26
+
27
+ const out = { cancel: false, contextModification: '' };
28
+ const notes = [];
29
+
30
+ // Extract the most common "path" parameter (varies by tool name).
31
+ const path =
32
+ params.path ||
33
+ params.file_path ||
34
+ params.filePath ||
35
+ params.target_file ||
36
+ params.targetFile ||
37
+ params.notebook_path ||
38
+ '';
39
+
40
+ const lower = String(path).toLowerCase();
41
+
42
+ // 1. Hard block — secrets + protected paths.
43
+ const blocked = [
44
+ /\/\.env(\.|$|\/)/,
45
+ /\/\.envrc$/,
46
+ /\/secrets?\//,
47
+ /\/credentials?/,
48
+ /\/node_modules\//,
49
+ /\.(lock|lockb)$/,
50
+ /\/package-lock\.json$/,
51
+ /\/bun\.lockb?$/,
52
+ /\/yarn\.lock$/,
53
+ ];
54
+ if (path && blocked.some((re) => re.test(lower))) {
55
+ out.cancel = true;
56
+ out.errorMessage = `PreToolUse: refusing to write to protected path '${path}' (Bizar harness policy).`;
57
+ process.stdout.write(JSON.stringify(out) + '\n');
58
+ return;
59
+ }
60
+
61
+ // 2. Warn — debug artifacts in src/.
62
+ if (path && /\.(ts|tsx|js|jsx|mjs|cjs)$/.test(lower)) {
63
+ if (/\/src\//.test(lower) || /\/plugins\//.test(lower) || /\/packages\//.test(lower)) {
64
+ const text = JSON.stringify(params);
65
+ if (/\bconsole\.(log|debug|warn)\b/.test(text) && !/\bconsole\.(error|info)\b/.test(text)) {
66
+ notes.push('Heads up: console.log detected in src — `make clean-check` will fail.');
67
+ }
68
+ if (/\bdebugger\b/.test(text)) {
69
+ notes.push('Heads up: debugger statement detected — remove before committing.');
70
+ }
71
+ if (/\.only\s*\(/.test(text) && !/^[\s\S]*\.skip\s*\(/m.test(text)) {
72
+ notes.push('Heads up: .only() detected — `make clean-check` will fail.');
73
+ }
74
+ }
75
+ }
76
+
77
+ // 3. Always add a small context line for the AI's next decision.
78
+ notes.push(`Bizar PreToolUse: tool=${toolName || 'unknown'} path=${path || '(no path)'}`);
79
+
80
+ out.contextModification = notes.join(' ');
81
+ process.stdout.write(JSON.stringify(out) + '\n');
82
+ });
@@ -1,29 +1,68 @@
1
- # Hook System
1
+ # Bizar Harness — Cline Hooks
2
2
 
3
- BizarHarness uses **behavioral hooks** — agent-level instructions that simulate hook behavior. Since cline doesn't have a native hook runtime, all hooks are implemented as agent behavioral patterns.
3
+ This directory contains Cline-native hook scripts. They are NOT markdown
4
+ behavioral patterns — they are real Cline hook executables that run at
5
+ specific lifecycle events.
4
6
 
5
- ## Available Hooks
7
+ ## Format
6
8
 
7
- | Hook | Type | Trigger | Behavior |
8
- |------|------|---------|----------|
9
- | `pre-tool-use` | Behavioral | Before any edit/write | Check for secrets, verify permissions |
10
- | `post-tool-use` | Behavioral | After any edit/write | Auto-lint, auto-format, auto-test |
11
- | `session-start` | Behavioral | On session start | Read .bizar/, Hindsight recall, stack detection |
12
- | `session-end` | Behavioral | On task completion | Append to AGENTS_SELF_IMPROVEMENT.md |
13
- | `pre-commit` | Behavioral | Before git commit | Check for console.log, .env leaks, lint |
14
- | `post-implement` | Behavioral | After parallel implementation | Run test gate, verify both agents' outputs |
9
+ Cline hooks are executable scripts (no extension) with a shebang line:
15
10
 
16
- ## How It Works
11
+ ```bash
12
+ #!/usr/bin/env node
13
+ ```
17
14
 
18
- Each hook is enforced by agent instructions in the agent `.md` files:
15
+ They live in two locations:
16
+ - **Global**: `~/Documents/Cline/Hooks/` (applies to all workspaces)
17
+ - **Workspace**: `.clinerules/hooks/` (applies to one project)
19
18
 
20
- - **Pre-tool-use**: All implementation agents check for exposed secrets before any `write` or `edit` call
21
- - **Post-tool-use**: After file modifications, agents auto-run the linter and formatter
22
- - **Session-start**: Odin reads `.bizar/PROJECT.md` and Hindsight; Heimdall runs `bizar init` if missing
23
- - **Session-end**: Odin dispatches Heimdall to auto-extract self-improvement entries
24
- - **Pre-commit**: Hermod checks for console.log and .env before allowing git commits
25
- - **Post-implement**: After Thor+Tyr complete, Odin routes to Thor for test gate
19
+ The `bizar install` / `bizar update` commands install these scripts to
20
+ **both** locations with `chmod +x` so Cline picks them up.
26
21
 
27
- ## Customization
22
+ ## What each hook does
28
23
 
29
- To disable a hook, remove its instruction from the relevant agent `.md` file(s) in `~/.config/cline/agents/`.
24
+ | Hook | Stage | Job |
25
+ |------|-------|-----|
26
+ | `TaskStart` | New task | Prime the AI with `.bizar/PROJECT.md` + memory-vault search |
27
+ | `TaskResume` | Existing task resumed | Re-read project state, check `git log` since last run |
28
+ | `UserPromptSubmit` | User submits prompt | Tag the prompt for routing (`/team`, `/plow-through`, etc.) |
29
+ | `PreToolUse` | Before every tool | Block writes to `.env`, `secrets/`, `node_modules/`, lockfiles; warn on `console.log`/`debugger`/`.only()` in `src/` |
30
+ | `PostToolUse` | After every tool | Log latency to `~/.config/bizar/hook-logs/`, remind to run `/test` after edits |
31
+
32
+ ## I/O contract
33
+
34
+ Cline invokes each hook with **JSON on stdin** and reads **JSON on stdout**.
35
+
36
+ Input shape (Cline → hook):
37
+
38
+ ```json
39
+ {
40
+ "clineVersion": "3.0.39",
41
+ "hookName": "PreToolUse",
42
+ "taskId": "...",
43
+ "preToolUse": { "toolName": "write_to_file", "parameters": { "path": "src/foo.ts", ... } }
44
+ }
45
+ ```
46
+
47
+ Output shape (hook → Cline):
48
+
49
+ ```json
50
+ {
51
+ "cancel": false,
52
+ "contextModification": "small note for the next AI decision"
53
+ }
54
+ ```
55
+
56
+ Set `cancel: true` to block the tool call. The optional `errorMessage`
57
+ is shown to the user.
58
+
59
+ ## Disabling a hook
60
+
61
+ Rename the file to add a `.disabled` suffix (e.g. `PreToolUse.disabled`)
62
+ or remove the executable bit (`chmod -x PreToolUse`). Cline silently
63
+ skips hooks it can't execute.
64
+
65
+ ## See also
66
+
67
+ - [Cline hooks documentation](https://docs.cline.bot/customization/hooks)
68
+ - `cli/commands/validate.mjs` — `bizar validate` includes a `hooks-installed` check
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ // TaskResume — Bizar harness hook.
3
+ //
4
+ // Runs when an existing task is resumed. Reads JSON from stdin, outputs
5
+ // JSON to stdout. Used to remind the model of previous progress and to
6
+ // detect scope drift since the last run.
7
+
8
+ 'use strict';
9
+
10
+ const fs = require('fs');
11
+ const os = require('os');
12
+ const path = require('path');
13
+
14
+ let raw = '';
15
+ process.stdin.setEncoding('utf8');
16
+ process.stdin.on('data', (chunk) => { raw += chunk; });
17
+ process.stdin.on('end', () => {
18
+ let input = {};
19
+ try { input = JSON.parse(raw); } catch { input = {}; }
20
+ const task = input.taskResume || {};
21
+ const previous = task.previousState || {};
22
+
23
+ try {
24
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
25
+ fs.mkdirSync(logDir, { recursive: true });
26
+ const today = new Date().toISOString().slice(0, 10);
27
+ const logFile = path.join(logDir, `task-resume-${today}.jsonl`);
28
+ fs.appendFileSync(logFile, JSON.stringify({
29
+ ts: new Date().toISOString(),
30
+ taskId: input.taskId || null,
31
+ lastMessageTs: previous.lastMessageTs || null,
32
+ messageCount: previous.messageCount || null,
33
+ }) + '\n');
34
+ } catch { /* best-effort */ }
35
+
36
+ const notes = [
37
+ 'Bizar TaskResume: re-read `.bizar/PROJECT.md` and `PROGRESS.md` before continuing.',
38
+ 'Bizar TaskResume: check `git log --oneline -10` to see what changed since the last run.',
39
+ ];
40
+ if (previous.conversationHistoryDeleted) {
41
+ notes.push('Bizar TaskResume: WARNING — conversation history was deleted. Context from previous run is gone; verify scope before continuing.');
42
+ }
43
+
44
+ process.stdout.write(JSON.stringify({
45
+ cancel: false,
46
+ contextModification: notes.join(' '),
47
+ }) + '\n');
48
+ });
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ // TaskStart — Bizar harness hook.
3
+ //
4
+ // Runs when a NEW task is started (not when resuming). Reads JSON from
5
+ // stdin, outputs JSON to stdout. Used to prime the AI with project
6
+ // context and to record the start of a session.
7
+
8
+ 'use strict';
9
+
10
+ const fs = require('fs');
11
+ const os = require('os');
12
+ const path = require('path');
13
+
14
+ let raw = '';
15
+ process.stdin.setEncoding('utf8');
16
+ process.stdin.on('data', (chunk) => { raw += chunk; });
17
+ process.stdin.on('end', () => {
18
+ let input = {};
19
+ try { input = JSON.parse(raw); } catch { input = {}; }
20
+ const task = input.taskStart || {};
21
+ const initial = String(task.taskMetadata?.initialTask || '').slice(0, 500);
22
+
23
+ // Log task start to ~/.config/bizar/hook-logs/
24
+ try {
25
+ const logDir = path.join(os.homedir(), '.config', 'bizar', 'hook-logs');
26
+ fs.mkdirSync(logDir, { recursive: true });
27
+ const today = new Date().toISOString().slice(0, 10);
28
+ const logFile = path.join(logDir, `task-start-${today}.jsonl`);
29
+ fs.appendFileSync(logFile, JSON.stringify({
30
+ ts: new Date().toISOString(),
31
+ taskId: input.taskId || null,
32
+ clineVersion: input.clineVersion || null,
33
+ initial: initial,
34
+ }) + '\n');
35
+ } catch { /* best-effort */ }
36
+
37
+ const notes = [
38
+ 'Bizar TaskStart: read `.bizar/PROJECT.md` (if present) before any routing decision.',
39
+ 'Bizar TaskStart: if memory vault exists, run `bizar memory search "<topic>"` first.',
40
+ 'Bizar TaskStart: Odin dispatches to subagents via `task` (sync) or `bizar_spawn_background` (async).',
41
+ ];
42
+
43
+ process.stdout.write(JSON.stringify({
44
+ cancel: false,
45
+ contextModification: notes.join(' '),
46
+ }) + '\n');
47
+ });