@polderlabs/bizar 5.6.0-beta.4 → 5.6.0-beta.5
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/README.md +254 -352
- package/bizar-dash/ARCHITECTURE.md +148 -30
- package/package.json +1 -1
- package/packages/sdk/ARCHITECTURE.md +19 -4
- package/packages/sdk/package.json +1 -1
- package/plugins/bizar/ARCHITECTURE.md +67 -15
- package/plugins/bizar/CONSTRAINTS.md +35 -7
- package/plugins/bizar/tests/README.md +99 -0
package/README.md
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
# BizarHarness ᛟ
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Cline-based multi-agent coding harness with a closed learning loop.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
13 agents across 4 cost tiers. Odin routes, subagents execute, Forseti audits.
|
|
8
|
+
ClineCore in-process — no subprocess, no port, no serve-info file.
|
|
8
9
|
|
|
9
|
-
[](https://www.npmjs.com/package/bizar)
|
|
10
|
-
[](https://www.npmjs.com/package/@polderlabs/bizar)
|
|
11
|
+
[](https://github.com/DrB0rk/BizarHarness)
|
|
12
|
+
[](https://docs.cline.bot)
|
|
13
|
+
[](https://github.com/DrB0rk/BizarHarness)
|
|
14
|
+
[](docs/INDEX.md)
|
|
15
|
+
[](docs/safety.md)
|
|
16
|
+
[](plugins/bizar/skills)
|
|
12
17
|
[](https://www.skills.sh)
|
|
18
|
+
[](https://github.com/headroomlabs-ai/headroom)
|
|
13
19
|
[](LICENSE)
|
|
14
|
-
[](https://docs.cline.bot)
|
|
15
|
-
[](#-the-pantheon)
|
|
16
|
-
[](CONTRIBUTING.md)
|
|
17
20
|
|
|
18
21
|
`npm install @polderlabs/bizar` · `npx bizar`
|
|
19
22
|
|
|
@@ -23,423 +26,307 @@
|
|
|
23
26
|
|
|
24
27
|
## Table of Contents
|
|
25
28
|
|
|
29
|
+
- [What's new in v6.0.0](#-whats-new-in-v600)
|
|
30
|
+
- [Quick start](#-quick-start)
|
|
26
31
|
- [The Pantheon](#-the-pantheon)
|
|
27
32
|
- [Architecture](#-architecture)
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
33
|
+
- [Tools (22 total)](#-tools-22-total)
|
|
34
|
+
- [Hooks (4 + 2 safety)](#-hooks-4--2-safety)
|
|
35
|
+
- [Safety — DANGEROUS_PATTERNS](#-safety--dangerous-patterns)
|
|
36
|
+
- [Skill Curator — closed learning loop](#-skill-curator--closed-learning-loop)
|
|
37
|
+
- [Knowledge Graph Tools](#-knowledge-graph-tools)
|
|
38
|
+
- [Harness engineering audit (73/73)](#-harness-engineering-audit-7373)
|
|
39
|
+
- [Documentation](#-documentation)
|
|
40
|
+
- [Migration from v5.5.x](#-migration-from-v55x)
|
|
34
41
|
- [Contributing](#-contributing)
|
|
35
42
|
- [License](#-license)
|
|
36
43
|
|
|
37
44
|
---
|
|
38
45
|
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
┌─────────────┐
|
|
43
|
-
│ᛟ ODIN │
|
|
44
|
-
├─────────────┤
|
|
45
|
-
│Router (M3) │
|
|
46
|
-
└─────────────┘
|
|
47
|
-
|
|
48
|
-
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐
|
|
49
|
-
│ᛢ VÖR │ │ᛗ MIMIR │ │ᚹ HEIMDALL│ │ᚱ HERMOD │ │ᚦ THOR │ │ᛒ BALDR │ │ᛏ TYR │ │ᛉ VIDARR │
|
|
50
|
-
├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├──────────┤
|
|
51
|
-
│Clarify │ │Research │ │Simple │ │GitOps │ │Medium │ │Design │ │Complex │ │Last │
|
|
52
|
-
│DeepSeek │ │DeepSeek │ │DeepSeek │ │M2.7 │ │M2.7 │ │M2.7 │ │M3 │ │GPT-5.5 │
|
|
53
|
-
│FREE │ │FREE │ │FREE │ │$ │ │$ │ │$ │ │$$ │ │$$$ │
|
|
54
|
-
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘
|
|
55
|
-
|
|
56
|
-
┌─────────────┐
|
|
57
|
-
│ᚨ FORSETI │
|
|
58
|
-
├─────────────┤
|
|
59
|
-
│Auditor (M3) │
|
|
60
|
-
│edit: deny │
|
|
61
|
-
└─────────────┘
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
> _Generated by PlantUML ASCII art (`plantuml -utxt`)_
|
|
65
|
-
|
|
66
|
-
### Agents
|
|
67
|
-
|
|
68
|
-
| Agent | Rune | Model | Cost | Role |
|
|
69
|
-
|---|---|---|---|---|
|
|
70
|
-
| **Odin** | ᛟ | MiniMax M3 | $0.30/M · $1.20/M out | Primary router — never executes, only delegates |
|
|
71
|
-
| **Frigg** | ᚠ | DeepSeek V4 Flash | **Free** | Read-only Q&A — ask questions, get answers, never modifies |
|
|
72
|
-
| **Vör** | ᛢ | DeepSeek V4 Flash | **Free** | Clarifies ambiguous requests — asks questions until task is well-defined |
|
|
73
|
-
| **Mimir** | ᛗ | DeepSeek V4 Flash | **Free** | Research & codebase exploration (Semble-first) |
|
|
74
|
-
| **Heimdall** | ᚹ | DeepSeek V4 Flash | **Free** | Simple tasks, quick edits, file operations |
|
|
75
|
-
| **Hermod** | ᚱ | MiniMax M2.7 | $0.30/M · $1.20/M out | Git & GitHub operations (commit, PR, merge, rebase) |
|
|
76
|
-
| **Thor** | ᚦ | MiniMax M2.7 | $0.30/M · $1.20/M out | Moderate implementation, debugging, refactoring |
|
|
77
|
-
| **Baldr** | ᛒ | MiniMax M2.7 | $0.30/M · $1.20/M out | UI/UX design system (DESIGN.md plans, visual audits) |
|
|
78
|
-
| **Tyr** | ᛏ | MiniMax M3 | $0.30/M · $1.20/M out | Complex implementation, architecture, deep debugging |
|
|
79
|
-
| **Vidarr** | ᛉ | GPT-5.5 | Subscription | Last resort — GPT-5.5 |
|
|
80
|
-
| **Forseti** | ᚨ | MiniMax M3 | $0.30/M · $1.20/M out | Adversarial plan reviewer (edit: deny, audit-only) |
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## ⚙ Architecture
|
|
46
|
+
## ✨ What's new in v6.0.0
|
|
85
47
|
|
|
86
|
-
|
|
48
|
+
v6.0.0 is a **complete rewrite** of the plugin framework from OpenCode
|
|
49
|
+
to Cline. The plugin embeds ClineCore in-process — no subprocess spawn,
|
|
50
|
+
no port, no password, no serve-info file. Plugin `setup()` returns in
|
|
51
|
+
~3ms (was: 30s+ timeout).
|
|
87
52
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
│ │ plan review (when complex)│
|
|
101
|
-
│ │──────────────────────────────>│
|
|
102
|
-
│ │ approve / changes required │
|
|
103
|
-
│ │<──────────────────────────────│
|
|
104
|
-
│ │ │ │
|
|
105
|
-
│ │<─── results ───│ │
|
|
106
|
-
│<─ synth ─│ │ │
|
|
107
|
-
```
|
|
53
|
+
| Feature | Description |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| **In-process ClineCore** | `ClineRuntime` wrapper replaces the subprocess. No port, no password. |
|
|
56
|
+
| **22 tools, 4 hooks** | All use `createTool()` from `@cline/sdk`. 0 compat shims. |
|
|
57
|
+
| **Cline agent teams** | New `bizar_spawn_team` + `bizar_team_status` tools. |
|
|
58
|
+
| **Knowledge graph tools** | New `bizar_graph_query/path/explain` over `.bizar/graph/graph.json`. |
|
|
59
|
+
| **DANGEROUS_PATTERNS gate** | 36 patterns (25 deny + 11 require-approval) checked in `beforeTool`. |
|
|
60
|
+
| **Skill curator** | Per-skill use/failure tracking. The differentiator (1/106 projects). |
|
|
61
|
+
| **Pre-compaction memory flush** | Durable snapshot before summarizer. Closes the durability gap. |
|
|
62
|
+
| **In-process memory vault** | Tools read/write `~/.bizar_memory/` directly. No dashboard needed. |
|
|
63
|
+
| **Harness audit 73/73** | Full L01–L12 compliance. `make check-arch` enforces 7 rules. |
|
|
64
|
+
| **Removed: Plugins view** | Use **Mods** only. v5.6.0-beta.3. |
|
|
108
65
|
|
|
109
|
-
|
|
110
|
-
- **Odin never executes work** — stripped of `bash`, `glob`, `grep`, `edit`, `write`, `question`
|
|
111
|
-
- **Vör handles ambiguity** — Odin cannot ask questions; routes unclear requests to Vör
|
|
112
|
-
- **Always parallel** — every request splits into 2+ simultaneous `task` calls
|
|
113
|
-
- **Implementation splits across Thor + Tyr** frontend/backend, file split, impl+tests
|
|
114
|
-
- **Forseti gates all Tier 4/5 work** — Tyr and Vidarr plans audited before execution
|
|
115
|
-
- **Bizar Memory Service** — local Obsidian-compatible Markdown + Git-shared sync. Three namespaces: `projects/<id>/`, `global/bizar/`, `users/<id>/`. No external memory service required.
|
|
66
|
+
See the full [CHANGELOG.md](CHANGELOG.md) for v5.6.0-beta.1 → beta.4.
|
|
116
67
|
|
|
117
68
|
---
|
|
118
69
|
|
|
119
|
-
## 🚀
|
|
120
|
-
|
|
121
|
-
### Quick — npm (recommended)
|
|
122
|
-
|
|
123
|
-
Published on [npmjs.com/package/bizar](https://www.npmjs.com/package/bizar).
|
|
124
|
-
|
|
125
|
-
Run without installing:
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
npx bizar
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Or install globally:
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
npm install -g @polderlabs/bizar
|
|
135
|
-
bizar
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Or add to a project:
|
|
70
|
+
## 🚀 Quick start
|
|
139
71
|
|
|
140
72
|
```bash
|
|
73
|
+
# Install (stable v5.5.6)
|
|
141
74
|
npm install @polderlabs/bizar
|
|
142
|
-
npx bizar
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
The interactive installer walks you through component selection, agent choice, install mode, API key setup, and auto-restarts cline.
|
|
146
|
-
|
|
147
|
-
> **v4.0.0:** `@polderlabs/bizar` is now a single package — the dashboard server, the cline plugin, and the typed SDK all ship inside it. No more separate `@polderlabs/bizar-dash` install.
|
|
148
75
|
|
|
149
|
-
|
|
76
|
+
# Or try the v6.0.0 beta (Cline rewrite)
|
|
77
|
+
npm install @polderlabs/bizar@beta
|
|
150
78
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
git clone git@github.com:DrB0rk/BizarHarness.git
|
|
155
|
-
cd BizarHarness
|
|
156
|
-
chmod +x install.sh
|
|
157
|
-
./install.sh
|
|
79
|
+
# Run
|
|
80
|
+
npx bizar
|
|
158
81
|
```
|
|
159
82
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
> This `install.sh` script is bash-only and does **not** run on Windows natively. Windows contributors should use the npm path above instead.
|
|
83
|
+
The installer handles:
|
|
163
84
|
|
|
164
|
-
|
|
85
|
+
- Cloning the dashboard repo
|
|
86
|
+
- Configuring the Cline plugin
|
|
87
|
+
- Setting up Semble (code search MCP) and Skills CLI
|
|
88
|
+
- Headroom (token-saving proxy)
|
|
165
89
|
|
|
166
|
-
|
|
90
|
+
If you'd rather install manually, see
|
|
91
|
+
[docs/migration-guide.md](docs/migration-guide.md).
|
|
167
92
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
- [Node.js 18+](https://nodejs.org/) on `PATH`
|
|
171
|
-
- [Python 3.10+](https://www.python.org/downloads/windows/) (only required for the optional `bizar graph` knowledge-graph feature)
|
|
172
|
-
- [Git for Windows](https://git-scm.com/download/win) — only needed if you want to run the bash `install.sh` from a Git Bash shell
|
|
173
|
-
|
|
174
|
-
**Install**
|
|
175
|
-
|
|
176
|
-
```powershell
|
|
177
|
-
npm install -g @polderlabs/bizar
|
|
178
|
-
bizar
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
**Optional: graph feature (knowledge graph + per-project .bizar/)**
|
|
182
|
-
|
|
183
|
-
The `bizar graph build` subcommand uses [graphify](https://github.com/bretbhomas/graphify). Install uv and graphify from PowerShell:
|
|
93
|
+
---
|
|
184
94
|
|
|
185
|
-
|
|
186
|
-
# Install uv (Python package manager) — Windows-native PowerShell installer
|
|
187
|
-
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
95
|
+
## ᛉ The Pantheon
|
|
188
96
|
|
|
189
|
-
# Install graphify
|
|
190
|
-
uv tool install graphifyy
|
|
191
97
|
```
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
98
|
+
┌─────────────┐
|
|
99
|
+
│ᛟ ODIN │
|
|
100
|
+
├─────────────┤
|
|
101
|
+
│Router (M3) │
|
|
102
|
+
└─────────────┘
|
|
103
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐
|
|
104
|
+
│ᛢ VÖR │ │ᛗ MIMIR │ │ᚹ HEIMDALL│ │ᚱ HERMOD │ │ᚦ THOR │ │ᛒ BALDR │ │ᛏ TYR │ │ᛉ VIDARR │
|
|
105
|
+
├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├──────────┤
|
|
106
|
+
│Clarifier│ │Research │ │Simple │ │Git ops │ │Mid impl │ │Design │ │High impl│ │Reasoning │
|
|
107
|
+
│(M2.7) │ │(M2.7) │ │(M2.7) │ │(M2.7) │ │(M2.7) │ │(M2.7) │ │(M3) │ │(M3-Reason)│
|
|
108
|
+
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────┘
|
|
109
|
+
↑ ↑
|
|
110
|
+
Forseti audits Forseti audits
|
|
111
|
+
all Tier 4/5 work
|
|
197
112
|
```
|
|
198
113
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- The bash `install.sh` does not run on Windows cmd/PowerShell; use the `npm install -g` path above.
|
|
204
|
-
- Headroom ships a Python/npm installer. On Windows, install it manually: `pip install "headroom-ai[all]"` or `npm install -g headroom-ai`, then run `headroom wrap cline`.
|
|
205
|
-
|
|
206
|
-
### Prerequisites
|
|
207
|
-
|
|
208
|
-
- [cline CLI](https://docs.cline.bot) installed and on `$PATH`
|
|
209
|
-
- Provider connections (via `/connect` in cline TUI)
|
|
210
|
-
- [Headroom](https://github.com/headroomlabs-ai/headroom) (recommended) — CLI proxy that reduces LLM token consumption by 60-90%
|
|
211
|
-
- [Semble](https://github.com/semble-ai/semble) (recommended) — AI-powered code search (used by Mimir agent)
|
|
212
|
-
- [Skills CLI](https://www.skills.sh) (recommended) — Agent skill package manager (`npx skills add <owner/repo>`)
|
|
213
|
-
|
|
214
|
-
### Headroom Setup
|
|
114
|
+
Odin is the only primary agent. Every request hits him first. He
|
|
115
|
+
**never executes work** — he decomposes into parallel streams and
|
|
116
|
+
dispatches to subagents. The Forseti gate audits all Tier 4/5 work
|
|
117
|
+
(Tyr, Vidarr) before execution.
|
|
215
118
|
|
|
216
|
-
[
|
|
119
|
+
See [plugins/bizar/ARCHITECTURE.md](plugins/bizar/ARCHITECTURE.md) for
|
|
120
|
+
the full agent roster and routing rules.
|
|
217
121
|
|
|
218
|
-
|
|
122
|
+
---
|
|
219
123
|
|
|
220
|
-
|
|
221
|
-
# Python (recommended)
|
|
222
|
-
pip install "headroom-ai[all]"
|
|
124
|
+
## ⚙ Architecture
|
|
223
125
|
|
|
224
|
-
# npm
|
|
225
|
-
npm install -g headroom-ai
|
|
226
126
|
```
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
127
|
+
┌────────────────────────────────────────────────────────────────────┐
|
|
128
|
+
│ Layer 1: UI (bizar-dash/) │
|
|
129
|
+
│ - React + TypeScript dashboard (17 tabs) │
|
|
130
|
+
│ - Express server (HTTP + WS) │
|
|
131
|
+
│ - In-process ClineCore via @cline/sdk (replaces cline serve) │
|
|
132
|
+
│ - Harness engineering dashboard view │
|
|
133
|
+
│ - Kanban board (5 columns + backlog) │
|
|
134
|
+
└────────────────────────────────────────────────────────────────────┘
|
|
135
|
+
↕ HTTP REST + WebSocket
|
|
136
|
+
┌────────────────────────────────────────────────────────────────────┐
|
|
137
|
+
│ Layer 0: Core (plugins/bizar/) │
|
|
138
|
+
│ - Cline plugin entry (AgentPlugin from @cline/sdk) │
|
|
139
|
+
│ - 22 tools + 4 hooks + 1 approval gate │
|
|
140
|
+
│ - In-process ClineRuntime (wraps ClineCore.create()) │
|
|
141
|
+
│ - In-process memory vault │
|
|
142
|
+
│ - DANGEROUS_PATTERNS approval gate │
|
|
143
|
+
│ - Skill curator (closed learning loop) │
|
|
144
|
+
│ - Pre-compaction memory flush │
|
|
145
|
+
└────────────────────────────────────────────────────────────────────┘
|
|
146
|
+
↕ Cline SDK
|
|
147
|
+
┌────────────────────────────────────────────────────────────────────┐
|
|
148
|
+
│ Substrate: ClineCore (@cline/core) │
|
|
149
|
+
│ - In-process runtime, no subprocess │
|
|
150
|
+
│ - startSession / send / abort / subscribe │
|
|
151
|
+
│ - Session storage, model dispatch, agent team tools │
|
|
152
|
+
└────────────────────────────────────────────────────────────────────┘
|
|
232
153
|
```
|
|
233
154
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
### Semble Setup
|
|
237
|
-
|
|
238
|
-
[Semble](https://github.com/semble-ai/semble) provides AI-powered code search. It indexes your codebase and enables natural-language queries like "where is authentication handled" without relying on grep. The Mimir research agent uses Semble as its primary search tool.
|
|
155
|
+
See [docs/architecture.md](docs/architecture.md) for the full layer
|
|
156
|
+
model, module map, and inter-component contracts.
|
|
239
157
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
# Install uv if not present
|
|
244
|
-
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
245
|
-
|
|
246
|
-
# Install Semble with MCP support
|
|
247
|
-
uv tool install "semble[mcp]"
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Skills CLI Setup
|
|
158
|
+
---
|
|
251
159
|
|
|
252
|
-
|
|
160
|
+
## 🛠 Tools (22 total)
|
|
253
161
|
|
|
254
|
-
|
|
162
|
+
| Category | Count | Tools |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| **Background agents** | 9 | `bizar_spawn_background`, `bizar_status`, `bizar_collect`, `bizar_kill`, `bizar_pause`, `bizar_resume`, `bizar_send_message`, `bizar_get_comments`, `bizar_report_progress` |
|
|
165
|
+
| **Memory** | 4 | `bizar_memory_list`, `bizar_memory_read`, `bizar_memory_write`, `bizar_memory_search` |
|
|
166
|
+
| **Plan / Glyphs** | 4 | `bizar_plan_action`, `bizar_open_kb`, `bizar_wait_for_feedback`, `bizar_read_glyph_feedback` |
|
|
167
|
+
| **Cline agent teams** | 2 | `bizar_spawn_team`, `bizar_team_status` |
|
|
168
|
+
| **Knowledge graph** | 3 | `bizar_graph_query`, `bizar_graph_path`, `bizar_graph_explain` |
|
|
169
|
+
| **Total** | **22** | All use `createTool` from `@cline/sdk` directly |
|
|
255
170
|
|
|
256
|
-
|
|
257
|
-
npm install -g skills
|
|
258
|
-
```
|
|
171
|
+
---
|
|
259
172
|
|
|
260
|
-
|
|
173
|
+
## 🪝 Hooks (4 + 2 safety)
|
|
261
174
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
175
|
+
| Hook | Purpose |
|
|
176
|
+
| --- | --- |
|
|
177
|
+
| `beforeTool` | Loop guard + **DANGEROUS_PATTERNS gate** |
|
|
178
|
+
| `afterTool` | Per-tool-call log to `LogWriter` |
|
|
179
|
+
| `beforeModel` | **Pre-compaction memory flush** (writes snapshot to vault) |
|
|
180
|
+
| `onEvent` | `message-added` (slash commands) + `run-finished`/`run-failed` (memory write) |
|
|
266
181
|
|
|
267
|
-
|
|
182
|
+
| Safety component | Purpose |
|
|
183
|
+
| --- | --- |
|
|
184
|
+
| `skill-curator` (manual) | Reports skill usage + flags revisions |
|
|
185
|
+
| `memory-flush-on-compact` (auto) | Writes snapshot to vault when `shouldCompact()` returns true |
|
|
268
186
|
|
|
269
187
|
---
|
|
270
188
|
|
|
271
|
-
##
|
|
272
|
-
|
|
273
|
-
BizarHarness agents **proactively discover and install skills** during execution using the Skills CLI. When Heimdall, Thor, Tyr, or Vidarr receives a task, they:
|
|
189
|
+
## 🛡 Safety — DANGEROUS_PATTERNS
|
|
274
190
|
|
|
275
|
-
|
|
276
|
-
2. **Check installed** with `skills list --json` to see what's already available
|
|
277
|
-
3. **Install from known repos** based on the task domain — e.g., `skills add supabase/agent-skills --all -y` for database work, `skills add vercel-labs/agent-skills --all -y` for frontend
|
|
278
|
-
4. **Use** the skill's instructions at `~/.cline/skills/<name>/SKILL.md` via the `skill` tool
|
|
191
|
+
**36 patterns** checked on every tool call. 25 deny + 11 require-approval.
|
|
279
192
|
|
|
280
|
-
|
|
193
|
+
| Category | Examples |
|
|
194
|
+
| --- | --- |
|
|
195
|
+
| **Filesystem destruction** | `rm -rf /`, `rm -rf /etc`, `mkfs`, `dd of=/dev/sda`, fork bomb |
|
|
196
|
+
| **Privilege escalation** | `sudo`, `su - root`, `chmod 777`, `chown root` |
|
|
197
|
+
| **SSRF** | `http://169.254.169.254/*` (AWS metadata), `metadata.google.internal`, `metadata.azure.com` |
|
|
198
|
+
| **Process control** | `kill -9 1`, `shutdown`, `reboot`, `init 0` |
|
|
199
|
+
| **Sensitive file reads** | `~/.ssh/`, `~/.aws/credentials`, `~/.config/gcloud`, `/proc/<pid>/environ` |
|
|
200
|
+
| **Network exfiltration** | `wget ... \| sh`, `curl ... \| sh` |
|
|
201
|
+
| **Dangerous git** | `git push --force origin main`, `git reset --hard`, `git clean -fd` |
|
|
202
|
+
| **Prompt injection** | `ignore previous instructions`, `reveal your system prompt` |
|
|
281
203
|
|
|
282
|
-
|
|
204
|
+
**Always-on.** No env var to disable. Source patterns from
|
|
205
|
+
[Hermes](https://github.com/walkinglabs/awesome-harness-engineering) +
|
|
206
|
+
[OpenFang](https://github.com/RightNow-AI/openfang) +
|
|
207
|
+
[OpenClaw](https://github.com/openclaw/openclaw).
|
|
283
208
|
|
|
284
|
-
|
|
285
|
-
|--------|-------|
|
|
286
|
-
| General (find-skills, skill-creator) | `vercel-labs/skills` |
|
|
287
|
-
| Frontend (React, a11y, web-design) | `vercel-labs/agent-skills`, `shadcn/ui` |
|
|
288
|
-
| Backend (Supabase, Postgres, auth) | `supabase/agent-skills` |
|
|
289
|
-
| Testing (TDD, E2E, Playwright) | `mattpocock/skills`, `microsoft/playwright-cli` |
|
|
290
|
-
| Design (frontend-design, UI/UX) | `anthropics/skills`, `leonxlnx/taste-skill` |
|
|
209
|
+
See [docs/safety.md](docs/safety.md) for the full reference.
|
|
291
210
|
|
|
292
211
|
---
|
|
293
212
|
|
|
213
|
+
## 🧠 Skill Curator — closed learning loop
|
|
294
214
|
|
|
215
|
+
**The differentiator.** Of 106 cataloged agent-harness projects, exactly
|
|
216
|
+
one (Hermes Agent) has this. Bizar is now the second.
|
|
295
217
|
|
|
296
|
-
|
|
218
|
+
Tracks per-skill use/failure in `~/.bizar/skills/usage.jsonl`:
|
|
297
219
|
|
|
298
|
-
|
|
220
|
+
```ts
|
|
221
|
+
import { recordSkillUse, generateCuratorReport } from "bizar/hooks/skill-curator";
|
|
299
222
|
|
|
300
|
-
|
|
223
|
+
recordSkillUse("pump-then-test", "failure");
|
|
224
|
+
recordSkillUse("pump-then-test", "failure");
|
|
225
|
+
const report = generateCuratorReport({ worktree, logger });
|
|
226
|
+
// { totalSkills: 14, needsRevision: 1, stale: 0, ... }
|
|
227
|
+
```
|
|
301
228
|
|
|
302
|
-
|
|
229
|
+
The closed loop:
|
|
303
230
|
|
|
304
231
|
```
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
│ Layer 3: LightRAG is derived index (P2) │ ← semantic retrieval
|
|
313
|
-
│ bizar memory reindex │ (stub in Phase 1)
|
|
314
|
-
└─────────────────────────────────────────────┘
|
|
232
|
+
Tasks run → recordSkillUse(skill, success|failure)
|
|
233
|
+
→ usage.jsonl accumulates
|
|
234
|
+
→ generateCuratorReport() identifies:
|
|
235
|
+
- skills with 5+ failures (needs-revision)
|
|
236
|
+
- skills with 0 uses in 30 days (stale)
|
|
237
|
+
- new skills (proposals)
|
|
238
|
+
→ next sprint addresses the report
|
|
315
239
|
```
|
|
316
240
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
### Modes
|
|
320
|
-
|
|
321
|
-
| Mode | Vault location | Cross-project sharing | Default? |
|
|
322
|
-
|---|---|---|---|
|
|
323
|
-
| `local-only` | `<project>/.obsidian/` | No — per-project vault | **Yes** |
|
|
324
|
-
| `managed` | `~/.local/share/bizar/memory/<repoName>/` | Yes — one shared repo with three namespaces | Opt-in |
|
|
325
|
-
|
|
326
|
-
Pick `managed` at `bizar init` time, or run `bizar memory link ~/.local/share/bizar/memory/<repoName>/` to convert an existing project to managed mode.
|
|
327
|
-
|
|
328
|
-
### Namespaces
|
|
329
|
-
|
|
330
|
-
The `managed` repo is split into three top-level directories. Every note lives in exactly one:
|
|
331
|
-
|
|
332
|
-
| Namespace | Purpose | Example path |
|
|
333
|
-
|---|---|---|
|
|
334
|
-
| `projects/<projectId>/` | Per-project memory — conventions, ADRs, bugs, commands | `projects/bizarharness/architecture_decision__lightrag-stub.md` |
|
|
335
|
-
| `global/bizar/` | Cross-project knowledge — agent patterns, Bizar internals | `global/bizar/coding_convention__plan-then-forseti.md` |
|
|
336
|
-
| `users/<userId>/` | Personal scratch — user preferences, todos, draft thoughts | `users/drb0rk/user_preference__tabs-not-spaces.md` |
|
|
337
|
-
|
|
338
|
-
### CLI commands
|
|
339
|
-
|
|
340
|
-
The `bizar memory <sub>` family has 11 subcommands:
|
|
341
|
-
|
|
342
|
-
| Subcommand | Purpose | Example |
|
|
343
|
-
|---|---|---|
|
|
344
|
-
| `init` | Create `.bizar/memory.json` and the per-project vault | `bizar memory init --memory-mode local-only` |
|
|
345
|
-
| `status` | Show mode, link target, dirty files, last sync | `bizar memory status` |
|
|
346
|
-
| `link <path>` | Bind the project to a managed memory repo | `bizar memory link ~/.local/share/bizar/memory/work/` |
|
|
347
|
-
| `unlink` | Detach from managed mode (vault stays on disk) | `bizar memory unlink` |
|
|
348
|
-
| `pull` | `git pull` the linked memory repo | `bizar memory pull` |
|
|
349
|
-
| `commit` | Stage dirty notes + run secret scan + `git commit` | `bizar memory commit -m "add auth ADR"` |
|
|
350
|
-
| `push` | `git push` the linked memory repo | `bizar memory push` |
|
|
351
|
-
| `sync` | pull → reindex → commit → push (the common path) | `bizar memory sync` |
|
|
352
|
-
| `reindex` | Rebuild the derived LightRAG index (Phase 2 stub) | `bizar memory reindex` |
|
|
353
|
-
| `conflicts` | List notes with merge conflicts awaiting resolution | `bizar memory conflicts` |
|
|
354
|
-
| `doctor` | Run schema + secrets + Git health checks | `bizar memory doctor` |
|
|
355
|
-
|
|
356
|
-
### Dashboard routes
|
|
357
|
-
|
|
358
|
-
The dashboard exposes 18 REST endpoints under `/api/memory/*` for note CRUD, schema validation, secret scanning, Git sync, search, and health checks. The legacy `/api/obsidian/*` routes are preserved with back-compat response shapes.
|
|
359
|
-
|
|
360
|
-
### Secrets and schema
|
|
361
|
-
|
|
362
|
-
Every note passing through `bizar memory sync` is scanned against 12 secret patterns (HIGH/MEDIUM). HIGH-severity matches block the commit; MEDIUM matches warn but allow. Required frontmatter is 8 fields (`memory_id`, `type`, `project_id`, `status`, `confidence`, `created`, `updated`, `tags`); 11 memory types are recognized, 6 statuses, 3 confidence levels.
|
|
241
|
+
See [docs/curator.md](docs/curator.md) for the full reference.
|
|
363
242
|
|
|
364
243
|
---
|
|
365
244
|
|
|
366
|
-
##
|
|
367
|
-
|
|
368
|
-
After installation, run `/connect` in cline to add API keys:
|
|
245
|
+
## 🕸 Knowledge Graph Tools
|
|
369
246
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
| **Cline Zen** | `cline/deepseek-v4-flash-free` | Free API key from [cline.ai](https://docs.cline.bot) — create account, get key, no charges |
|
|
373
|
-
| **MiniMax (direct)** | `minimax/MiniMax-M2.7`, `minimax/MiniMax-M3` | API key from [MiniMax](https://platform.minimaxi.com) |
|
|
374
|
-
| **OpenAI** | `openai/gpt-5.5` | ChatGPT subscription (OAuth) |
|
|
247
|
+
Three tools expose the existing `.bizar/graph/graph.json` (built by
|
|
248
|
+
`graphify`) to agents:
|
|
375
249
|
|
|
376
|
-
|
|
250
|
+
| Tool | Use case |
|
|
251
|
+
| --- | --- |
|
|
252
|
+
| `bizar_graph_query` | Substring search across node id, label, source file |
|
|
253
|
+
| `bizar_graph_path` | BFS shortest path between two nodes |
|
|
254
|
+
| `bizar_graph_explain` | Natural-language node summary with neighbors |
|
|
377
255
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
## 🧭 Routing
|
|
256
|
+
The BizarHarness project graph has **814 nodes** (mostly code
|
|
257
|
+
symbols + docs). Path queries work once `graphify` adds edges.
|
|
381
258
|
|
|
382
|
-
|
|
383
|
-
|---|---|
|
|
384
|
-
| Ambiguous or incomplete requests | @vör (free, asks clarifying questions) |
|
|
385
|
-
| File lookup, quick edits, boilerplate | @heimdall (free) |
|
|
386
|
-
| Codebase research, documentation analysis | @mimir (free, Semble-first) |
|
|
387
|
-
| Git commit, PR, merge, rebase, conflict resolution | @hermod (M2.7) |
|
|
388
|
-
| Moderate implementation, debugging, code review | @thor (M2.7) |
|
|
389
|
-
| Design systems, DESIGN.md, visual audits | @baldr (M2.7, plans only) |
|
|
390
|
-
| Complex features, architecture, deep debugging | @tyr (M3, audited by @forseti) |
|
|
391
|
-
| Stuck debugging, novel problems, postmortems | @vidarr (GPT-5.5, last resort) |
|
|
392
|
-
| Plan audit, adversarial review | @forseti (M3, edit: deny) |
|
|
393
|
-
|
|
394
|
-
**Cost escalation:** `Free → $Mid (M2.7) → $$High (M3) → $$$Ultra (GPT-5.5)`
|
|
259
|
+
See [docs/graph-tools.md](docs/graph-tools.md) for the full reference.
|
|
395
260
|
|
|
396
261
|
---
|
|
397
262
|
|
|
398
|
-
##
|
|
399
|
-
|
|
400
|
-
|
|
263
|
+
## 🛡 Harness engineering audit (73/73)
|
|
264
|
+
|
|
265
|
+
v6.0.0 passes the full L01–L12 audit at **73/73 = 100%**:
|
|
266
|
+
|
|
267
|
+
| Subsystem | Score |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| 1. Instructions | 11/11 (entry + hard constraints + state files + clock-in/out) |
|
|
270
|
+
| 2. Tools | 2/2 (`.claude/settings.json` + MCP integrations) |
|
|
271
|
+
| 3. Environment | 5/5 (lockfile + `.nvmrc` + Makefile + setup + dev) |
|
|
272
|
+
| 4. State | 4/4 (`PROGRESS.md` + `DECISIONS.md` + `feature_list.json`) |
|
|
273
|
+
| 5. Feedback | 7/7 (`make check/test/e2e/clean-check/arch/vcr/session-*`) |
|
|
274
|
+
| 6. L05 Cross-session | 6/6 (Current State + clock-in/out + context anxiety) |
|
|
275
|
+
| 7. L03 System of record | 4/4 (ACID: Durability, Consistency, Atomicity, Proximity) |
|
|
276
|
+
| 8. L07 WIP=1 + VCR | 3/3 (WIP=1 + `make vcr` + VCR 20/20 = 1.0) |
|
|
277
|
+
| 9. L08 Feature list | 6/6 (evidence + verify-feature + granularity + state machine) |
|
|
278
|
+
| 10. L09 DoD | 5/5 (3-layer verification + runtime signals + repair instructions) |
|
|
279
|
+
| 11. L10 E2E + Arch | 8/8 (`make e2e` + `make check-arch` + 7 arch rules + E2E requirement) |
|
|
280
|
+
| 12. L11 Observability | 7/7 (sprint contract + rubric + session-trace + make session-*) |
|
|
281
|
+
| 13. L12 Clean State | 5/5 (5-dimension checklist + clean-check + quality doc + dual-mode) |
|
|
401
282
|
|
|
283
|
+
```bash
|
|
284
|
+
bash tools/audit-harness.sh .
|
|
285
|
+
# Total: 73 / 73 harness components present
|
|
286
|
+
# Critical: 7 / 7
|
|
287
|
+
# Recommended: 66 / 66
|
|
402
288
|
```
|
|
403
|
-
### 2026-06-16: Fixed routing issue
|
|
404
|
-
- **Context**: Odin was self-handling instead of routing
|
|
405
|
-
- **Lesson**: Stripped bash/glob/grep/edit from Odin — forces delegation
|
|
406
|
-
- **Pattern**: Primary agents should never have executable tools
|
|
407
|
-
- **Agent**: heimdall
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
---
|
|
411
289
|
|
|
412
|
-
|
|
290
|
+
See [PROGRESS.md](PROGRESS.md) § Current State and the
|
|
291
|
+
[Harness tab](bizar-dash/src/web/views/Harness.tsx) in the dashboard.
|
|
413
292
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
```bash
|
|
417
|
-
# Create a new plan
|
|
418
|
-
bizar plan new my-feature
|
|
419
|
-
|
|
420
|
-
# Open an existing plan
|
|
421
|
-
bizar plan open my-feature
|
|
293
|
+
---
|
|
422
294
|
|
|
423
|
-
|
|
424
|
-
|
|
295
|
+
## 📚 Documentation
|
|
296
|
+
|
|
297
|
+
| What | Where |
|
|
298
|
+
| --- | --- |
|
|
299
|
+
| **Documentation index** | [docs/INDEX.md](docs/INDEX.md) |
|
|
300
|
+
| Entry point (agents) | [AGENTS.md](AGENTS.md) |
|
|
301
|
+
| Current state | [PROGRESS.md](PROGRESS.md) |
|
|
302
|
+
| Decisions (ADRs) | [DECISIONS.md](DECISIONS.md) |
|
|
303
|
+
| Architecture | [docs/architecture.md](docs/architecture.md) |
|
|
304
|
+
| Safety | [docs/safety.md](docs/safety.md) |
|
|
305
|
+
| Skill curator | [docs/curator.md](docs/curator.md) |
|
|
306
|
+
| Graph tools | [docs/graph-tools.md](docs/graph-tools.md) |
|
|
307
|
+
| Quality scores | [docs/quality-document.md](docs/quality-document.md) |
|
|
308
|
+
| Migration guide | [docs/migration-guide.md](docs/migration-guide.md) |
|
|
309
|
+
| Plugin module | [plugins/bizar/ARCHITECTURE.md](plugins/bizar/ARCHITECTURE.md) |
|
|
310
|
+
| Plugin constraints | [plugins/bizar/CONSTRAINTS.md](plugins/bizar/CONSTRAINTS.md) |
|
|
311
|
+
| Dashboard module | [bizar-dash/ARCHITECTURE.md](bizar-dash/ARCHITECTURE.md) |
|
|
312
|
+
| SDK module | [packages/sdk/ARCHITECTURE.md](packages/sdk/ARCHITECTURE.md) |
|
|
313
|
+
| Changelog | [CHANGELOG.md](CHANGELOG.md) |
|
|
425
314
|
|
|
426
|
-
|
|
427
|
-
bizar plan export my-feature > my-feature.mdx
|
|
315
|
+
---
|
|
428
316
|
|
|
429
|
-
|
|
430
|
-
bizar plan delete my-feature
|
|
431
|
-
```
|
|
317
|
+
## 🔄 Migration from v5.5.x
|
|
432
318
|
|
|
433
|
-
|
|
319
|
+
Upgrading from the OpenCode-based v5.5.x? See
|
|
320
|
+
[docs/migration-guide.md](docs/migration-guide.md) for:
|
|
434
321
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
| `comments.json` | Section comments | ✗ No |
|
|
440
|
-
| `meta.json` | Title, status, author, timestamps | ✓ Yes |
|
|
322
|
+
- Breaking changes (tool shape, hook shape)
|
|
323
|
+
- New tools (Cline agent teams, graph tools, curator)
|
|
324
|
+
- Removed tools (Plugins → Mods)
|
|
325
|
+
- Verification commands
|
|
441
326
|
|
|
442
|
-
|
|
327
|
+
TL;DR: `npm install @polderlabs/bizar@beta` and update any custom
|
|
328
|
+
slash commands that consumed the old `{ output: JSON.stringify(...) }`
|
|
329
|
+
shape.
|
|
443
330
|
|
|
444
331
|
---
|
|
445
332
|
|
|
@@ -447,17 +334,23 @@ The HTML viewer runs a tiny local HTTP server (`localhost:4321`) — no network,
|
|
|
447
334
|
|
|
448
335
|
PRs welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
|
449
336
|
|
|
450
|
-
|
|
337
|
+
The harness engineering protocol:
|
|
451
338
|
|
|
452
|
-
|
|
339
|
+
1. **Before:** Fill [templates/sprint-contract.md](templates/sprint-contract.md)
|
|
340
|
+
(scope, DoD, exclusions).
|
|
341
|
+
2. **During:** Run `make session-start` to record session start.
|
|
342
|
+
3. **After:** Score against [templates/evaluator-rubric.md](templates/evaluator-rubric.md)
|
|
343
|
+
(every dim B+).
|
|
344
|
+
4. **End of session:** Run `make clean-check` and `make check`. Commit
|
|
345
|
+
with a WHY-focused message.
|
|
453
346
|
|
|
454
|
-
Development
|
|
455
|
-
See [DrB0rk/BizarHarness-dev](https://github.com/DrB0rk/BizarHarness-dev) (private)
|
|
456
|
-
for the local dev environment, including the Docker-based cline sandbox used to
|
|
457
|
-
test config and plugin changes without touching the system cline install.
|
|
347
|
+
### Development
|
|
458
348
|
|
|
459
|
-
|
|
460
|
-
|
|
349
|
+
Development of BizarHarness uses a separate sandbox repo for Docker/dev
|
|
350
|
+
tooling. See [DrB0rk/BizarHarness-dev](https://github.com/DrB0rk/BizarHarness-dev)
|
|
351
|
+
(private) for the local dev environment, including the Docker-based
|
|
352
|
+
Cline sandbox used to test config and plugin changes without touching
|
|
353
|
+
the system Cline install.
|
|
461
354
|
|
|
462
355
|
---
|
|
463
356
|
|
|
@@ -467,6 +360,15 @@ MIT — see [LICENSE](LICENSE).
|
|
|
467
360
|
|
|
468
361
|
---
|
|
469
362
|
|
|
363
|
+
## Acknowledgments
|
|
364
|
+
|
|
365
|
+
Inspired by the [walkinglabs/learn-harness-engineering](https://github.com/walkinglabs/learn-harness-engineering)
|
|
366
|
+
course and the [awesome-harness-engineering](https://github.com/walkinglabs/awesome-harness-engineering)
|
|
367
|
+
curated list. Built on [Cline](https://docs.cline.bot) and
|
|
368
|
+
[@cline/sdk](https://www.npmjs.com/package/@cline/sdk).
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
470
372
|
<div align="center">
|
|
471
373
|
<small>
|
|
472
374
|
ᚱᚨᛞᛖ ᚹᛖᛚ · ᛟᚲ ᛈᚱᛟᛋᛈᛖᚱ<br>
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> The dashboard server + React UI. This module is Layer 1 (UI) and
|
|
4
4
|
> communicates with the plugin via HTTP/WS. It also embeds ClineCore
|
|
5
|
-
> in-process for background-agent spawning. See
|
|
6
|
-
> for the layer
|
|
5
|
+
> in-process for background-agent spawning. See
|
|
6
|
+
> [docs/architecture.md](../docs/architecture.md) for the layer
|
|
7
|
+
> model.
|
|
7
8
|
|
|
8
9
|
## Top-level layout
|
|
9
10
|
|
|
@@ -12,7 +13,7 @@ bizar-dash/
|
|
|
12
13
|
├── src/
|
|
13
14
|
│ ├── server/
|
|
14
15
|
│ │ ├── index.mjs # Express server entry
|
|
15
|
-
│ │ ├── bg-spawner.mjs # Background agent spawner (ClineCore)
|
|
16
|
+
│ │ ├── bg-spawner.mjs # Background agent spawner (ClineCore in-process)
|
|
16
17
|
│ │ ├── cline-sdk.mjs # SDK wrapper (legacy compat)
|
|
17
18
|
│ │ ├── serve-info.mjs # Serve-info file IO
|
|
18
19
|
│ │ ├── tasks-store.mjs # Per-project task storage
|
|
@@ -21,35 +22,110 @@ bizar-dash/
|
|
|
21
22
|
│ │ ├── memory-secrets.mjs # Secret scanner
|
|
22
23
|
│ │ ├── memory-git.mjs # Memory vault git ops
|
|
23
24
|
│ │ ├── memory-lightrag.mjs # Semantic search (optional)
|
|
24
|
-
│ │ ├──
|
|
25
|
-
│ │
|
|
26
|
-
│ │
|
|
27
|
-
│ │
|
|
28
|
-
│ │
|
|
29
|
-
│ │
|
|
30
|
-
│ │
|
|
31
|
-
│ │
|
|
32
|
-
│ │
|
|
25
|
+
│ │ ├── memory-config.mjs # Memory config
|
|
26
|
+
│ │ ├── memory-obsidian.mjs # Obsidian-style read API
|
|
27
|
+
│ │ ├── memory-sync.mjs # Memory sync
|
|
28
|
+
│ │ ├── memory-conflicts.mjs # Memory conflict resolution
|
|
29
|
+
│ │ ├── memory-path-safety.mjs # Memory path safety
|
|
30
|
+
│ │ ├── memory-cli.mjs # Memory CLI commands
|
|
31
|
+
│ │ ├── memory-protocol-drift.mjs # Memory protocol drift detection
|
|
32
|
+
│ │ ├── activity-log.mjs # Activity log
|
|
33
|
+
│ │ ├── auth.mjs # Auth
|
|
34
|
+
│ │ ├── otel.mjs # OpenTelemetry
|
|
35
|
+
│ │ ├── metrics.mjs # Metrics
|
|
36
|
+
│ │ ├── diagnostics-store.mjs # Diagnostics
|
|
37
|
+
│ │ ├── obsidian-store.mjs # Obsidian store
|
|
38
|
+
│ │ ├── settings-store.mjs # Settings store
|
|
39
|
+
│ │ ├── background-store.mjs # Background state
|
|
40
|
+
│ │ ├── agents-store.mjs # Agents store
|
|
41
|
+
│ │ ├── backup-store.mjs # Backups
|
|
42
|
+
│ │ ├── dialog-store.mjs # Dialog state
|
|
43
|
+
│ │ ├── dialog-poller.mjs # Dialog polling
|
|
44
|
+
│ │ ├── search-store.mjs # Search index
|
|
45
|
+
│ │ ├── providers-store.mjs # Provider catalog
|
|
46
|
+
│ │ ├── plan-delegator.mjs # Task → agent delegator
|
|
47
|
+
│ │ ├── task-delegator.mjs # Task delegator
|
|
48
|
+
│ │ ├── cline-runner.mjs # Cline runner
|
|
49
|
+
│ │ ├── cline-sdk.mjs # Cline SDK wrapper
|
|
50
|
+
│ │ ├── v2-auth-file.mjs # v2 auth file
|
|
51
|
+
│ │ ├── v2-event-bus.mjs # v2 event bus
|
|
52
|
+
│ │ └── routes/ # REST API routes
|
|
53
|
+
│ │ ├── memory.mjs
|
|
54
|
+
│ │ ├── tasks.mjs
|
|
55
|
+
│ │ ├── background.mjs
|
|
56
|
+
│ │ ├── overview.mjs
|
|
57
|
+
│ │ ├── projects.mjs
|
|
58
|
+
│ │ ├── history.mjs
|
|
59
|
+
│ │ ├── settings.mjs
|
|
60
|
+
│ │ ├── providers.mjs
|
|
61
|
+
│ │ ├── env-vars.mjs
|
|
62
|
+
│ │ ├── usage.mjs
|
|
63
|
+
│ │ ├── update.mjs
|
|
64
|
+
│ │ ├── lightrag.mjs
|
|
65
|
+
│ │ ├── opencode-sessions.mjs
|
|
66
|
+
│ │ ├── opencode-session-detail.mjs
|
|
67
|
+
│ │ ├── doctor.mjs
|
|
68
|
+
│ │ ├── dialogs.mjs
|
|
69
|
+
│ │ ├── artifacts.mjs
|
|
70
|
+
│ │ ├── agents.mjs
|
|
71
|
+
│ │ ├── memory.mjs
|
|
72
|
+
│ │ ├── agents.mjs
|
|
73
|
+
│ │ ├── chat.mjs
|
|
74
|
+
│ │ ├── cline-sessions.mjs
|
|
75
|
+
│ │ ├── cline-session-detail.mjs
|
|
76
|
+
│ │ ├── config.mjs
|
|
77
|
+
│ │ ├── artifacts.mjs
|
|
78
|
+
│ │ ├── chat.mjs
|
|
79
|
+
│ │ └── misc.mjs
|
|
33
80
|
│ └── web/
|
|
34
|
-
│ ├── App.tsx # Root shell + WS routing
|
|
35
|
-
│ ├──
|
|
36
|
-
│
|
|
37
|
-
│ │ ├── BackgroundAgents.tsx # Live BG agent viewer
|
|
38
|
-
│ │ ├── Chat.tsx
|
|
81
|
+
│ ├── App.tsx # Root shell + WS routing (v6.0.0)
|
|
82
|
+
│ ├── MobileApp.tsx # Mobile root shell
|
|
83
|
+
│ ├── views/ # Page-level views (17)
|
|
39
84
|
│ │ ├── Overview.tsx
|
|
85
|
+
│ │ ├── Chat.tsx
|
|
40
86
|
│ │ ├── Agents.tsx
|
|
41
|
-
│ │
|
|
42
|
-
│ ├──
|
|
43
|
-
│
|
|
87
|
+
│ │ ├── Artifacts.tsx # Glyphs
|
|
88
|
+
│ │ ├── Tasks.tsx # 5-column kanban + team badge
|
|
89
|
+
│ │ ├── Activity.tsx
|
|
90
|
+
│ │ ├── BackgroundAgents.tsx # Live BG agent viewer
|
|
91
|
+
│ │ ├── Skills.tsx
|
|
92
|
+
│ │ ├── Memory.tsx
|
|
93
|
+
│ │ ├── Mods.tsx
|
|
94
|
+
│ │ ├── Marketplace.tsx
|
|
95
|
+
│ │ ├── Schedules.tsx
|
|
96
|
+
│ │ ├── History.tsx
|
|
97
|
+
│ │ ├── MiniMaxUsage.tsx
|
|
98
|
+
│ │ ├── Eval.tsx
|
|
99
|
+
│ │ ├── Doctor.tsx
|
|
100
|
+
│ │ ├── Harness.tsx # v6.0.0 — 73/73 audit
|
|
101
|
+
│ │ └── Settings.tsx
|
|
102
|
+
│ ├── components/ # Reusable components (~50)
|
|
103
|
+
│ │ ├── Topbar.tsx # 17-tab nav + Cline runtime badge (v6.0.0)
|
|
104
|
+
│ │ ├── Sidebar.tsx
|
|
105
|
+
│ │ ├── Modal.tsx
|
|
106
|
+
│ │ ├── Toast.tsx
|
|
107
|
+
│ │ ├── SearchModal.tsx
|
|
108
|
+
│ │ ├── Notifications.tsx
|
|
109
|
+
│ │ ├── CommandDialog.tsx
|
|
110
|
+
│ │ ├── Card.tsx
|
|
111
|
+
│ │ ├── Button.tsx
|
|
112
|
+
│ │ ├── Tag.tsx
|
|
113
|
+
│ │ ├── Spinner.tsx
|
|
114
|
+
│ │ ├── SettingsNav.tsx
|
|
115
|
+
│ │ ├── StatusBadge.tsx
|
|
116
|
+
│ │ └── ... (~40 more)
|
|
117
|
+
│ ├── hooks/ # React hooks
|
|
118
|
+
│ ├── lib/ # API client + types
|
|
119
|
+
│ └── styles/ # CSS (~10 files)
|
|
44
120
|
├── scripts/ # smoke-bg-retry.mjs
|
|
45
|
-
├── styles/ # CSS
|
|
46
|
-
└── tests/ # bun:test + vitest
|
|
121
|
+
├── styles/ # CSS (legacy)
|
|
122
|
+
└── tests/ # bun:test + vitest (~150 files)
|
|
47
123
|
```
|
|
48
124
|
|
|
49
125
|
## Public contract
|
|
50
126
|
|
|
51
|
-
The dashboard listens on `BIZAR_DASHBOARD_PORT` (default 4321).
|
|
52
|
-
exposes:
|
|
127
|
+
The dashboard listens on `BIZAR_DASHBOARD_PORT` (default 4321).
|
|
128
|
+
It exposes:
|
|
53
129
|
|
|
54
130
|
- `GET /api/snapshot` — full state for the UI
|
|
55
131
|
- `GET /api/agents` — registered agents
|
|
@@ -61,19 +137,61 @@ exposes:
|
|
|
61
137
|
- `POST /api/tasks` — create task
|
|
62
138
|
- `PATCH /api/tasks/:id/status` — move task between columns
|
|
63
139
|
- `WS /ws` — server-sent events for live updates
|
|
140
|
+
- `GET /api/doctor/health` — health endpoint (Harness view consumes)
|
|
141
|
+
|
|
142
|
+
## Tabs (17, v6.0.0)
|
|
143
|
+
|
|
144
|
+
| Tab | Description |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| `overview` | Status cards, recent activity, project selector |
|
|
147
|
+
| `chat` | 3-column chat (rail / thread / info) |
|
|
148
|
+
| `agents` | Agent roster, dispatch visualization |
|
|
149
|
+
| `glyphs` | Glyph artifact viewer |
|
|
150
|
+
| `tasks` | 5-column kanban + team badge |
|
|
151
|
+
| `activity` | Activity feed |
|
|
152
|
+
| `active` | Live BG agent viewer (5s poll + WS) |
|
|
153
|
+
| `skills` | Skills browser (bizar-dash/skills/*) |
|
|
154
|
+
| `memory` | Memory subsystem (4 sources + config) |
|
|
155
|
+
| `mods` | Mod manager |
|
|
156
|
+
| `schedules` | Cron schedules |
|
|
157
|
+
| `history` | Session history |
|
|
158
|
+
| `usage` | MiniMax Usage (hand-rolled SVG chart) |
|
|
159
|
+
| `eval` | Eval framework |
|
|
160
|
+
| `doctor` | System health + diagnostics |
|
|
161
|
+
| `harness` | **NEW v6.0.0** — 73/73 audit + make targets |
|
|
162
|
+
| `settings` | Settings (theme, network, agent, etc.) |
|
|
64
163
|
|
|
65
164
|
## Key invariants
|
|
66
165
|
|
|
67
|
-
- Dashboard must NOT re-implement ClineCore features (use
|
|
166
|
+
- Dashboard must NOT re-implement ClineCore features (use
|
|
167
|
+
`@cline/core`).
|
|
68
168
|
- Background spawner uses ClineCore in-process (not `cline serve`).
|
|
69
|
-
- Kanban board consumes `tasks:change` + `tasks:delete` WS
|
|
70
|
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
|
|
169
|
+
- Kanban board consumes `tasks:change` + `tasks:delete` WS
|
|
170
|
+
events.
|
|
171
|
+
- Memory store is on disk at `~/.bizar_memory/` (shared with
|
|
172
|
+
the plugin).
|
|
173
|
+
- Express order matters: `/tasks/bulk` and `/tasks/submit`
|
|
174
|
+
MUST be declared before `/tasks/:id` so the literal segment
|
|
175
|
+
isn't captured as an `:id` parameter.
|
|
74
176
|
|
|
75
177
|
## Verification
|
|
76
178
|
|
|
77
179
|
- `make check` — TS compile + tests
|
|
78
180
|
- `make e2e` — exercises the dashboard's kanban board via the
|
|
79
181
|
`Tasks.tsx` view against the `/api/tasks` REST endpoints
|
|
182
|
+
- `make clean-check` — 5-dimension clean-state check
|
|
183
|
+
|
|
184
|
+
## v6.0.0 highlights
|
|
185
|
+
|
|
186
|
+
- **Cline runtime badge in topbar** (pulsing purple)
|
|
187
|
+
- **Harness tab** — 73/73 audit, subsystem status, make targets
|
|
188
|
+
- **Tasks kanban team badge** — tasks tagged with `team:*`
|
|
189
|
+
show a "team" badge with sparkle icon
|
|
190
|
+
- **Brand version pill** — gradient style for "v6.0.0"
|
|
191
|
+
- **No Plugins tab** — removed in v5.6.0-beta.3 (Mods only)
|
|
192
|
+
|
|
193
|
+
## See also
|
|
194
|
+
|
|
195
|
+
- [docs/architecture.md](../docs/architecture.md) — layer model
|
|
196
|
+
- [docs/safety.md](../docs/safety.md) — DANGEROUS_PATTERNS reference
|
|
197
|
+
- [docs/decisions/DEC-006-kanban-board.md](../docs/decisions/DEC-006-kanban-board.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polderlabs/bizar",
|
|
3
|
-
"version": "5.6.0-beta.
|
|
3
|
+
"version": "5.6.0-beta.5",
|
|
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,7 +1,9 @@
|
|
|
1
1
|
# packages/sdk/ — Architecture
|
|
2
2
|
|
|
3
|
-
> TypeScript SDK wrapper for the Bizar Harness. Provides typed
|
|
4
|
-
> to
|
|
3
|
+
> TypeScript SDK wrapper for the Bizar Harness. Provides typed
|
|
4
|
+
> access to Cline events and HTTP responses. The plugin (Layer 0)
|
|
5
|
+
> embeds ClineCore in-process and does NOT use this SDK; the
|
|
6
|
+
> dashboard's HTTP client uses this SDK for legacy compat.
|
|
5
7
|
|
|
6
8
|
## Top-level layout
|
|
7
9
|
|
|
@@ -43,9 +45,22 @@ for await (const event of events) {
|
|
|
43
45
|
in-process for both plugin and dashboard.
|
|
44
46
|
- Discriminated error model via `isBizarError(event)`.
|
|
45
47
|
- Event shapes are versioned (current: `runtime.team.progress.v1`).
|
|
46
|
-
- Tests use vitest (`bun test` doesn't pick them up — see
|
|
48
|
+
- Tests use vitest (`bun test` doesn't pick them up — see
|
|
49
|
+
test files for vitest config).
|
|
50
|
+
|
|
51
|
+
## Versioning
|
|
52
|
+
|
|
53
|
+
- `@polderlabs/bizar-sdk` follows semver.
|
|
54
|
+
- Beta releases: `0.x.0-beta.N` (e.g. `0.2.0-beta.4`).
|
|
55
|
+
- Stable releases: `0.x.0` once v0.2 stabilizes.
|
|
47
56
|
|
|
48
57
|
## Verification
|
|
49
58
|
|
|
50
59
|
- `make check` — TS compile + tests (incl. vitest)
|
|
51
|
-
- `make e2e` — SDK wrapper integration (plugin ↔ dashboard
|
|
60
|
+
- `make e2e` — SDK wrapper integration (plugin ↔ dashboard
|
|
61
|
+
roundtrip)
|
|
62
|
+
|
|
63
|
+
## See also
|
|
64
|
+
|
|
65
|
+
- [docs/architecture.md](../../docs/architecture.md) — layer model
|
|
66
|
+
- [@polderlabs/bizar-sdk on npm](https://www.npmjs.com/package/@polderlabs/bizar-sdk)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# plugins/bizar/ — Architecture
|
|
2
2
|
|
|
3
3
|
> The Cline plugin entry and all 19 tools. This module is Layer 0
|
|
4
|
-
> (Core) and runs inside the Cline host. See
|
|
5
|
-
> for the layer
|
|
4
|
+
> (Core) and runs inside the Cline host. See
|
|
5
|
+
> [docs/architecture.md](../docs/architecture.md) for the layer
|
|
6
|
+
> model.
|
|
6
7
|
|
|
7
8
|
## Top-level layout
|
|
8
9
|
|
|
@@ -12,6 +13,7 @@ plugins/bizar/
|
|
|
12
13
|
├── src/
|
|
13
14
|
│ ├── clineruntime.ts # ClineCore wrapper (in-process)
|
|
14
15
|
│ ├── memory-vault.ts # Obsidian-compatible vault (in-process)
|
|
16
|
+
│ ├── dangerous-patterns.ts # 36 safety patterns (v6.0.0)
|
|
15
17
|
│ ├── background.ts # InstanceManager (state tracking)
|
|
16
18
|
│ ├── background-state.ts # Persisted state shape
|
|
17
19
|
│ ├── plan-fs.ts # Plan directory read/write
|
|
@@ -28,7 +30,9 @@ plugins/bizar/
|
|
|
28
30
|
│ ├── logger.ts # Logger interface
|
|
29
31
|
│ ├── hooks/
|
|
30
32
|
│ │ ├── memory-inject.ts # beforeModel hook
|
|
31
|
-
│ │
|
|
33
|
+
│ │ ├── memory-write-on-end.ts # onEvent hook (session.idle/error)
|
|
34
|
+
│ │ ├── skill-curator.ts # Closed learning loop (v6.0.0)
|
|
35
|
+
│ │ └── memory-flush-on-compact.ts # Pre-compact snapshot (v6.0.0)
|
|
32
36
|
│ └── tools/ # 19 tools
|
|
33
37
|
│ ├── bg-collect.ts
|
|
34
38
|
│ ├── bg-get-comments.ts
|
|
@@ -48,8 +52,11 @@ plugins/bizar/
|
|
|
48
52
|
│ ├── read-glyph-feedback.ts
|
|
49
53
|
│ ├── team-spawn.ts
|
|
50
54
|
│ ├── team-status.ts
|
|
51
|
-
│
|
|
52
|
-
|
|
55
|
+
│ ├── wait-for-feedback.ts
|
|
56
|
+
│ ├── graph-query.ts # Knowledge graph (v6.0.0)
|
|
57
|
+
│ ├── graph-path.ts # Shortest path (v6.0.0)
|
|
58
|
+
│ └── graph-explain.ts # Node summary (v6.0.0)
|
|
59
|
+
└── tests/ # bun:test (45 files)
|
|
53
60
|
```
|
|
54
61
|
|
|
55
62
|
## Public contract
|
|
@@ -67,24 +74,69 @@ const plugin: AgentPlugin = {
|
|
|
67
74
|
export default plugin;
|
|
68
75
|
```
|
|
69
76
|
|
|
77
|
+
## Tools (19 total)
|
|
78
|
+
|
|
79
|
+
| Category | Count | Tools |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| **Background agents** | 9 | `bizar_spawn_background`, `bizar_status`, `bizar_collect`, `bizar_kill`, `bizar_pause`, `bizar_resume`, `bizar_send_message`, `bizar_get_comments`, `bizar_report_progress` |
|
|
82
|
+
| **Memory** | 4 | `bizar_memory_list`, `bizar_memory_read`, `bizar_memory_write`, `bizar_memory_search` |
|
|
83
|
+
| **Plan / Glyphs** | 4 | `bizar_plan_action`, `bizar_open_kb`, `bizar_wait_for_feedback`, `bizar_read_glyph_feedback` |
|
|
84
|
+
| **Cline agent teams** | 2 | `bizar_spawn_team`, `bizar_team_status` |
|
|
85
|
+
| **Knowledge graph** | 3 | `bizar_graph_query`, `bizar_graph_path`, `bizar_graph_explain` |
|
|
86
|
+
| **Total** | **22** | (19 + 3 graph) |
|
|
87
|
+
|
|
88
|
+
> Note: 19 was the count before v6.0.0 added the 3 graph tools.
|
|
89
|
+
> Current total: **22 tools**.
|
|
90
|
+
|
|
91
|
+
## Hooks (4 + 2 safety)
|
|
92
|
+
|
|
93
|
+
| Hook | Purpose |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| `beforeTool` | Loop guard + DANGEROUS_PATTERNS gate |
|
|
96
|
+
| `afterTool` | Per-tool-call log to `LogWriter` |
|
|
97
|
+
| `beforeModel` | Pre-compaction memory flush (writes snapshot to vault) |
|
|
98
|
+
| `onEvent` | `message-added` (slash commands) + `run-finished`/`run-failed` (memory write) |
|
|
99
|
+
|
|
100
|
+
| Safety hook | Purpose |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `skill-curator` (manual) | Reports skill usage + flags revisions |
|
|
103
|
+
| `memory-flush-on-compact` (auto) | Writes snapshot to vault when `shouldCompact()` returns true |
|
|
104
|
+
|
|
70
105
|
## State flow
|
|
71
106
|
|
|
72
|
-
1. `setup()` builds the runtime context (logger, env flags,
|
|
73
|
-
|
|
107
|
+
1. `setup()` builds the runtime context (logger, env flags,
|
|
108
|
+
stores).
|
|
109
|
+
2. Brings up `ClineRuntime` (best-effort; team tools only if
|
|
110
|
+
it works).
|
|
74
111
|
3. Brings up `InstanceManager` in bg-only mode (no HTTP).
|
|
75
|
-
4. Builds
|
|
76
|
-
|
|
112
|
+
4. Builds 22 tools via `buildTools(runtimeCtx, instanceManager,
|
|
113
|
+
clineRuntime)`.
|
|
114
|
+
5. Each tool uses
|
|
115
|
+
`createTool({ name, description, inputSchema: z.object({...}).shape, execute })`.
|
|
77
116
|
6. Hooks are computed lazily from the runtime context.
|
|
78
117
|
|
|
79
118
|
## Key invariants
|
|
80
119
|
|
|
81
|
-
- Plugin must NOT import from `bizar-dash
|
|
82
|
-
- Memory tools MUST use the in-process vault (no HTTP).
|
|
83
|
-
- Tools MUST use `createTool
|
|
84
|
-
- ClineRuntime MUST be used (no `cline serve` subprocess).
|
|
120
|
+
- **Plugin must NOT import from `bizar-dash/`** (Layer 1).
|
|
121
|
+
- **Memory tools MUST use the in-process vault** (no HTTP).
|
|
122
|
+
- **Tools MUST use `createTool`** (no manual `AgentTool` shapes).
|
|
123
|
+
- **ClineRuntime MUST be used** (no `cline serve` subprocess).
|
|
124
|
+
- **All tool calls MUST pass `checkDangerous()`** in `beforeTool`.
|
|
125
|
+
- **Compaction MUST trigger a flush** in `beforeModel`.
|
|
85
126
|
|
|
86
127
|
## Verification
|
|
87
128
|
|
|
88
129
|
- `make check` — TS compile + tests
|
|
89
|
-
- `make e2e` — real plugin load +
|
|
90
|
-
- `make check-arch` — arch-rules.json enforcement
|
|
130
|
+
- `make e2e` — real plugin load + 27 tool/hook checks
|
|
131
|
+
- `make check-arch` — arch-rules.json enforcement (7 rules)
|
|
132
|
+
- `make clean-check` — 5-dimension clean-state check
|
|
133
|
+
|
|
134
|
+
## See also
|
|
135
|
+
|
|
136
|
+
- [plugins/bizar/CONSTRAINTS.md](CONSTRAINTS.md) — module hard rules
|
|
137
|
+
- [docs/architecture.md](../docs/architecture.md) — layer model
|
|
138
|
+
- [docs/safety.md](../docs/safety.md) — DANGEROUS_PATTERNS reference
|
|
139
|
+
- [docs/curator.md](../docs/curator.md) — Skill curator
|
|
140
|
+
- [docs/graph-tools.md](../docs/graph-tools.md) — Graph tools
|
|
141
|
+
- [docs/decisions/DEC-001-cline-rewrite.md](../docs/decisions/DEC-001-cline-rewrite.md)
|
|
142
|
+
— the OpenCode → Cline rewrite
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# plugins/bizar/ — Hard Rules
|
|
2
2
|
|
|
3
|
-
> Module-specific hard rules. These complement the root
|
|
4
|
-
> constraints. Violations break the
|
|
3
|
+
> Module-specific hard rules. These complement the root
|
|
4
|
+
> [AGENTS.md](../../AGENTS.md) constraints. Violations break the
|
|
5
|
+
> plugin's portability or safety guarantees.
|
|
5
6
|
|
|
6
7
|
## Hard rules
|
|
7
8
|
|
|
8
9
|
- **MUST** use `createTool` from `@cline/sdk` for every tool.
|
|
9
|
-
# why: Ensures the AgentTool shape is correct and the host can
|
|
10
|
+
# why: Ensures the `AgentTool` shape is correct and the host can
|
|
10
11
|
# validate the inputSchema.
|
|
11
12
|
- **MUST** use the in-process `ClineRuntime` (no `cline serve` subprocess).
|
|
12
13
|
# why: The subprocess hangs in headless test environments.
|
|
@@ -19,11 +20,21 @@
|
|
|
19
20
|
# why: Cross-layer violation. Use `@cline/sdk` or `packages/sdk/`.
|
|
20
21
|
- **MUST NOT** use `fetch('http://127.0.0.1:...')` for memory.
|
|
21
22
|
# why: The plugin must work in-process without a dashboard.
|
|
22
|
-
- **MUST NOT** return `{ output: JSON.stringify(...) }` from tool
|
|
23
|
-
`execute()`.
|
|
23
|
+
- **MUST NOT** return `{ output: JSON.stringify(...) }` from tool `execute()`.
|
|
24
24
|
# why: Use the structured `AgentToolResult` shape (`{ ok, ... }`).
|
|
25
25
|
- **MUST NOT** hand-roll `AgentTool` shapes (use `createTool`).
|
|
26
26
|
# why: Hand-rolled tools drift from the Cline contract.
|
|
27
|
+
- **MUST** pass every tool call through `checkDangerous()` in `beforeTool`.
|
|
28
|
+
# why: 36 dangerous patterns must be checked before the call
|
|
29
|
+
# reaches the host. Deny decisions stop the call.
|
|
30
|
+
- **MUST** call `createMemoryFlushOnCompact().maybeFlush()` in
|
|
31
|
+
`beforeModel` when usage crosses the compaction threshold.
|
|
32
|
+
# why: Compaction drops context before persistence; the flush
|
|
33
|
+
# writes a durable snapshot first.
|
|
34
|
+
- **MUST NOT** spawn subagents with `rm -rf`, `sudo`, SSRF, or
|
|
35
|
+
prompt-injection content. (Enforced by `checkDangerous()`.)
|
|
36
|
+
# why: Defense in depth — even legitimate agents sometimes
|
|
37
|
+
# generate bad tool calls.
|
|
27
38
|
|
|
28
39
|
## Soft rules
|
|
29
40
|
|
|
@@ -31,9 +42,26 @@
|
|
|
31
42
|
- Prefer `Bun.file().text()` over `fs.readFileSync` for async reads.
|
|
32
43
|
- Use `logger.debug()` not `console.debug()`.
|
|
33
44
|
- Use `process.env.BIZAR_*` for environment-driven config.
|
|
45
|
+
- The plugin's `setup()` should not block. Use `try/catch` for
|
|
46
|
+
ClineRuntime setup; fall back gracefully.
|
|
47
|
+
|
|
48
|
+
## Anti-patterns
|
|
49
|
+
|
|
50
|
+
- ❌ Adding new tool types via the old OpenCode `tool()` factory
|
|
51
|
+
→ Use `createTool()`.
|
|
52
|
+
- ❌ Putting state in the plugin entry's module scope
|
|
53
|
+
→ Use `ctx.stateStore` for per-session state.
|
|
54
|
+
- ❌ Calling `process.exit()` from a hook
|
|
55
|
+
→ Return `{ stop: true, reason: '...' }` to the host.
|
|
56
|
+
- ❌ Spawning long-lived side effects in `beforeTool`
|
|
57
|
+
→ Use the `afterTool` hook for post-call actions.
|
|
58
|
+
- ❌ Skipping `checkDangerous()` for "trusted" tools
|
|
59
|
+
→ All tool calls go through the gate, no exceptions.
|
|
34
60
|
|
|
35
61
|
## When in doubt
|
|
36
62
|
|
|
37
|
-
1. Read
|
|
38
|
-
2. Check
|
|
63
|
+
1. Read [docs/architecture.md](../../docs/architecture.md) for the layer model.
|
|
64
|
+
2. Check [.harness/arch-rules.json](../../.harness/arch-rules.json) for enforced rules.
|
|
39
65
|
3. Run `make check-arch` before committing.
|
|
66
|
+
4. Read [docs/decisions/DEC-007-tool-approval-gate.md](../../docs/decisions/DEC-007-tool-approval-gate.md)
|
|
67
|
+
for the safety gate.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Plugin Tests
|
|
2
|
+
|
|
3
|
+
> `bun test plugins/bizar/tests/` — 658 tests across 45 files
|
|
4
|
+
> (as of v6.0.0-beta.4).
|
|
5
|
+
|
|
6
|
+
## Test categories
|
|
7
|
+
|
|
8
|
+
| File | What it tests | Tests |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| `safety.test.ts` (v6.0.0) | DANGEROUS_PATTERNS, skill curator, memory flush, graph tools | 19 |
|
|
11
|
+
| `init-helpers.test.ts` | `withTimeout` + `readValidSessionIds` (legacy) | 11 |
|
|
12
|
+
| `settings.test.ts` | Settings store IO | ~30 |
|
|
13
|
+
| `commands.test.ts` | Slash command parser (pure) | ~20 |
|
|
14
|
+
| `commands-impl.test.ts` | Slash command executor | ~30 |
|
|
15
|
+
| `tools/plan-action.test.ts` | Plan add element / add comment / get canvas | ~20 |
|
|
16
|
+
| `tools/wait-for-feedback.test.ts` | Wait for feedback | ~15 |
|
|
17
|
+
| `tools/read-glyph-feedback.test.ts` | Read glyph feedback | ~10 |
|
|
18
|
+
| `tools/bg-spawn-delegation.test.ts` | BG spawn delegation | ~25 |
|
|
19
|
+
| `tools/cline-runner.test.ts` | Cline runner | ~20 |
|
|
20
|
+
| `tools/bg-get-comments.test.ts` | BG get comments | ~10 |
|
|
21
|
+
| `reasoning-clean.test.ts` | <think> block stripper | ~15 |
|
|
22
|
+
| `key-rotation.test.ts` | API key rotation | ~10 |
|
|
23
|
+
| `loop.test.ts` | Loop guard (loopThresholdWarn) | ~10 |
|
|
24
|
+
| `block.test.ts` | State-store locking | ~15 |
|
|
25
|
+
| `stall-think.test.ts` | Stall detection | ~10 |
|
|
26
|
+
| `background/*` | BG agent state machine | ~50 |
|
|
27
|
+
| `hooks/*` | Hook integration | ~30 |
|
|
28
|
+
| `state/*` | State machine | ~20 |
|
|
29
|
+
|
|
30
|
+
## Running
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# All plugin tests
|
|
34
|
+
bun test plugins/bizar
|
|
35
|
+
|
|
36
|
+
# Single file
|
|
37
|
+
bun test plugins/bizar/tests/safety.test.ts
|
|
38
|
+
|
|
39
|
+
# Single test (by name)
|
|
40
|
+
bun test plugins/bizar/tests/safety.test.ts --test-name-pattern 'skill-curator'
|
|
41
|
+
|
|
42
|
+
# E2E (real plugin load + 27 tool/hook checks)
|
|
43
|
+
bun run /tmp/bh-full-e2e.mjs
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Test isolation
|
|
47
|
+
|
|
48
|
+
Tests are isolated via `mkdtempSync` for any file I/O. The skill
|
|
49
|
+
curator uses `BIZAR_SKILL_USAGE_FILE` env var to redirect writes
|
|
50
|
+
to a temp location. The memory flush uses `vaultRoot` constructor
|
|
51
|
+
option for the same purpose.
|
|
52
|
+
|
|
53
|
+
## Adding a new test
|
|
54
|
+
|
|
55
|
+
1. Create `plugins/bizar/tests/<name>.test.ts` (or
|
|
56
|
+
`plugins/bizar/tests/tools/<name>.test.ts` for tool tests).
|
|
57
|
+
2. Use `bun:test` (not vitest).
|
|
58
|
+
3. Use `mkdtempSync` for any file I/O so the test is isolated.
|
|
59
|
+
4. Add the test to the table above.
|
|
60
|
+
5. Run `bun test plugins/bizar` to confirm green.
|
|
61
|
+
|
|
62
|
+
## Test patterns
|
|
63
|
+
|
|
64
|
+
### Unit test for a tool
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { describe, it, expect } from "bun:test";
|
|
68
|
+
import { createMyTool } from "../src/tools/my-tool.js";
|
|
69
|
+
|
|
70
|
+
describe("my-tool", () => {
|
|
71
|
+
it("returns ok on success", async () => {
|
|
72
|
+
const tool = createMyTool({ worktree: "/tmp", logger: silentLogger });
|
|
73
|
+
const r = await tool.execute({ foo: "bar" }, { sessionId: "s" });
|
|
74
|
+
expect(r.ok).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Integration test for a hook
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { createSkillCurator } from "../src/hooks/skill-curator.js";
|
|
83
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
84
|
+
import { tmpdir } from "node:os";
|
|
85
|
+
import { join } from "node:path";
|
|
86
|
+
|
|
87
|
+
describe("skill-curator", () => {
|
|
88
|
+
let tmp: string;
|
|
89
|
+
beforeEach(() => { tmp = mkdtempSync(join(tmpdir(), "bh-")); });
|
|
90
|
+
afterEach(() => { rmSync(tmp, { recursive: true, force: true }); });
|
|
91
|
+
|
|
92
|
+
it("records and reports", () => {
|
|
93
|
+
const c = createSkillCurator({ worktree: tmp, logger: silentLogger });
|
|
94
|
+
c.record("foo", "success");
|
|
95
|
+
const r = c.report();
|
|
96
|
+
expect(r.totalSkills).toBe(1);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
```
|