@prowi/deskcheck 0.3.0 → 0.4.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.
- package/README.md +78 -84
- package/build/cli.js +345 -40
- package/build/cli.js.map +1 -1
- package/build/config/loader.d.ts.map +1 -1
- package/build/config/loader.js +5 -2
- package/build/config/loader.js.map +1 -1
- package/build/config/types.d.ts +14 -2
- package/build/config/types.d.ts.map +1 -1
- package/build/mcp/tools.d.ts.map +1 -1
- package/build/mcp/tools.js +26 -50
- package/build/mcp/tools.js.map +1 -1
- package/build/prompts/ExecutorPrompt.d.ts +4 -2
- package/build/prompts/ExecutorPrompt.d.ts.map +1 -1
- package/build/prompts/ExecutorPrompt.js +40 -33
- package/build/prompts/ExecutorPrompt.js.map +1 -1
- package/build/prompts/PartitionerPrompt.d.ts +12 -0
- package/build/prompts/PartitionerPrompt.d.ts.map +1 -0
- package/build/prompts/PartitionerPrompt.js +54 -0
- package/build/prompts/PartitionerPrompt.js.map +1 -0
- package/build/prompts/ResolverPrompt.d.ts +11 -0
- package/build/prompts/ResolverPrompt.d.ts.map +1 -0
- package/build/prompts/ResolverPrompt.js +45 -0
- package/build/prompts/ResolverPrompt.js.map +1 -0
- package/build/renderers/review/MarkdownRenderer.js +5 -2
- package/build/renderers/review/MarkdownRenderer.js.map +1 -1
- package/build/renderers/review/TerminalRenderer.js +5 -2
- package/build/renderers/review/TerminalRenderer.js.map +1 -1
- package/build/renderers/review/WatchRenderer.d.ts.map +1 -1
- package/build/renderers/review/WatchRenderer.js +10 -1
- package/build/renderers/review/WatchRenderer.js.map +1 -1
- package/build/server/controllers/ReviewController.d.ts +12 -3
- package/build/server/controllers/ReviewController.d.ts.map +1 -1
- package/build/server/controllers/ReviewController.js +50 -6
- package/build/server/controllers/ReviewController.js.map +1 -1
- package/build/server/server.d.ts.map +1 -1
- package/build/server/server.js +22 -1
- package/build/server/server.js.map +1 -1
- package/build/services/ExecutorService.d.ts +18 -3
- package/build/services/ExecutorService.d.ts.map +1 -1
- package/build/services/ExecutorService.js +51 -14
- package/build/services/ExecutorService.js.map +1 -1
- package/build/services/FindingsParserService.d.ts +1 -8
- package/build/services/FindingsParserService.d.ts.map +1 -1
- package/build/services/FindingsParserService.js +20 -45
- package/build/services/FindingsParserService.js.map +1 -1
- package/build/services/criteria/module-parser.d.ts +6 -4
- package/build/services/criteria/module-parser.d.ts.map +1 -1
- package/build/services/criteria/module-parser.js +27 -21
- package/build/services/criteria/module-parser.js.map +1 -1
- package/build/services/review/CodeSnippetService.d.ts +10 -0
- package/build/services/review/CodeSnippetService.d.ts.map +1 -0
- package/build/services/review/CodeSnippetService.js +54 -0
- package/build/services/review/CodeSnippetService.js.map +1 -0
- package/build/services/review/ReviewInputResolverService.d.ts +25 -0
- package/build/services/review/ReviewInputResolverService.d.ts.map +1 -0
- package/build/services/review/ReviewInputResolverService.js +106 -0
- package/build/services/review/ReviewInputResolverService.js.map +1 -0
- package/build/services/review/ReviewOrchestratorService.d.ts.map +1 -1
- package/build/services/review/ReviewOrchestratorService.js +21 -20
- package/build/services/review/ReviewOrchestratorService.js.map +1 -1
- package/build/services/review/ReviewPartitionerService.d.ts +46 -0
- package/build/services/review/ReviewPartitionerService.d.ts.map +1 -0
- package/build/services/review/ReviewPartitionerService.js +208 -0
- package/build/services/review/ReviewPartitionerService.js.map +1 -0
- package/build/services/review/ReviewPlanBuilderService.d.ts +25 -7
- package/build/services/review/ReviewPlanBuilderService.d.ts.map +1 -1
- package/build/services/review/ReviewPlanBuilderService.js +88 -30
- package/build/services/review/ReviewPlanBuilderService.js.map +1 -1
- package/build/services/review/ReviewStorageService.d.ts +34 -10
- package/build/services/review/ReviewStorageService.d.ts.map +1 -1
- package/build/services/review/ReviewStorageService.js +100 -14
- package/build/services/review/ReviewStorageService.js.map +1 -1
- package/build/services/testing/TestRunnerService.d.ts +4 -0
- package/build/services/testing/TestRunnerService.d.ts.map +1 -1
- package/build/services/testing/TestRunnerService.js +14 -10
- package/build/services/testing/TestRunnerService.js.map +1 -1
- package/build/types/criteria.d.ts +8 -6
- package/build/types/criteria.d.ts.map +1 -1
- package/build/types/review.d.ts +123 -28
- package/build/types/review.d.ts.map +1 -1
- package/package.json +3 -1
- package/ui/dist/index.html +12 -63
- package/build/prompts/PlannerPrompt.d.ts +0 -12
- package/build/prompts/PlannerPrompt.d.ts.map +0 -1
- package/build/prompts/PlannerPrompt.js +0 -34
- package/build/prompts/PlannerPrompt.js.map +0 -1
- package/build/services/review/ReviewContextExtractorService.d.ts +0 -17
- package/build/services/review/ReviewContextExtractorService.d.ts.map +0 -1
- package/build/services/review/ReviewContextExtractorService.js +0 -69
- package/build/services/review/ReviewContextExtractorService.js.map +0 -1
- package/build/services/review/ReviewPlannerService.d.ts +0 -29
- package/build/services/review/ReviewPlannerService.d.ts.map +0 -1
- package/build/services/review/ReviewPlannerService.js +0 -122
- package/build/services/review/ReviewPlannerService.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Modular code review powered by Claude. Define what to check as markdown, deskcheck runs each check in a fresh AI agent, and aggregates the findings.
|
|
4
4
|
|
|
5
|
-

|
|
6
|
-
|
|
7
5
|
## Why deskcheck?
|
|
8
6
|
|
|
9
7
|
Traditional code review tools leave a gap:
|
|
@@ -12,11 +10,11 @@ Traditional code review tools leave a gap:
|
|
|
12
10
|
- **Linters** verify syntax — they can't tell you "this endpoint is missing input validation"
|
|
13
11
|
- **A single LLM** reviewing a whole branch suffers **context rot** — as its context fills up, it starts missing the patterns it's supposed to catch
|
|
14
12
|
|
|
15
|
-
Deskcheck solves this by breaking every review into the smallest possible unit
|
|
13
|
+
Deskcheck solves this by breaking every review into the smallest possible unit. A **partitioner agent** reads your criterion and decides how to split the matched files into focused subtasks. Each subtask runs in a **fresh reviewer agent** with clean context — only the code it needs and the specific rules to check. Results are aggregated mechanically.
|
|
16
14
|
|
|
17
15
|
```
|
|
18
|
-
Your code + Criteria → N
|
|
19
|
-
|
|
16
|
+
Your code + Criteria → Partitioner → N reviewer agents → Aggregated findings
|
|
17
|
+
(per-criterion) (fresh context each)
|
|
20
18
|
```
|
|
21
19
|
|
|
22
20
|
## Quick Start
|
|
@@ -31,8 +29,8 @@ deskcheck init
|
|
|
31
29
|
# Review your branch changes against main
|
|
32
30
|
deskcheck diff main
|
|
33
31
|
|
|
34
|
-
# Review
|
|
35
|
-
deskcheck "src/services/
|
|
32
|
+
# Review with natural language
|
|
33
|
+
deskcheck "review src/services/"
|
|
36
34
|
|
|
37
35
|
# Open the web dashboard
|
|
38
36
|
deskcheck serve
|
|
@@ -42,15 +40,15 @@ deskcheck serve
|
|
|
42
40
|
|
|
43
41
|
### 1. You define criteria as markdown
|
|
44
42
|
|
|
45
|
-
Each criterion is a markdown file with YAML frontmatter that says **what to check**, **which files to check**, and **how
|
|
43
|
+
Each criterion is a markdown file with YAML frontmatter that says **what to check**, **which files to check**, and **how to partition the work**:
|
|
46
44
|
|
|
47
45
|
```yaml
|
|
48
46
|
---
|
|
49
47
|
description: "Checks for common security vulnerabilities"
|
|
50
|
-
severity: critical
|
|
51
48
|
globs:
|
|
52
49
|
- "src/**/*.ts"
|
|
53
50
|
- "!src/**/*.test.ts"
|
|
51
|
+
partition: one task per file
|
|
54
52
|
model: sonnet
|
|
55
53
|
---
|
|
56
54
|
|
|
@@ -60,7 +58,7 @@ You are a security reviewer. Check for:
|
|
|
60
58
|
2. **SQL injection** — string concatenation in database queries
|
|
61
59
|
3. **Missing input validation** — user input used without sanitization
|
|
62
60
|
|
|
63
|
-
For each issue, report the severity, file, line
|
|
61
|
+
For each issue, report the severity, file, line range, and a fix suggestion.
|
|
64
62
|
```
|
|
65
63
|
|
|
66
64
|
Put criteria in `deskcheck/criteria/` — organize them however you like:
|
|
@@ -75,56 +73,52 @@ deskcheck/criteria/
|
|
|
75
73
|
└── error-handling.md
|
|
76
74
|
```
|
|
77
75
|
|
|
78
|
-
### 2.
|
|
79
|
-
|
|
80
|
-
Each criterion has `globs` that define which files it applies to. When you run `deskcheck diff main`, it gets the list of changed files and matches them against every criterion's globs. Each match becomes a **task**: one file + one criterion.
|
|
81
|
-
|
|
82
|
-
### 3. Each task runs in a fresh agent
|
|
76
|
+
### 2. The pipeline runs in four steps
|
|
83
77
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
- Access to read tools (Read, Glob, Grep) for additional context
|
|
88
|
-
|
|
89
|
-
No context leakage between tasks. A fresh agent reviewing one file against one set of rules catches issues with near-100% reliability.
|
|
78
|
+
```
|
|
79
|
+
Matching → Partitioning → Reviewing → Complete
|
|
80
|
+
```
|
|
90
81
|
|
|
91
|
-
|
|
82
|
+
1. **Matching** — files from `git diff` (or a natural-language file list) are matched against each criterion's glob patterns. Programmatic, no LLM.
|
|
83
|
+
2. **Partitioning** — for each matched criterion, a fresh agent reads the `partition` instruction and splits the matched files into focused subtasks. The partitioner can inspect files with Read/Grep/Glob to make informed decisions (e.g. "one method per task" requires reading the file to list methods).
|
|
84
|
+
3. **Reviewing** — each subtask runs in a fresh reviewer agent with only the criterion instructions, the assigned files, and the scope. Reviewers fetch their own context from disk (diffs for change-mode, full files for all-mode). Up to 5 run concurrently.
|
|
85
|
+
4. **Complete** — issues are aggregated by file, criterion, and severity.
|
|
92
86
|
|
|
93
|
-
|
|
87
|
+
### 3. Findings are aggregated
|
|
94
88
|
|
|
95
|
-
|
|
89
|
+
Results are grouped and viewable in the terminal, as markdown (for PR comments), as JSON (for tooling), or in the **web dashboard** (`deskcheck serve`). The dashboard shows a four-step pipeline bar, per-criterion subtask breakdowns, partitioner reasoning, and issue cards with code snippets and suggested fixes.
|
|
96
90
|
|
|
97
91
|
## CLI Commands
|
|
98
92
|
|
|
99
93
|
### `deskcheck diff [git-args...]`
|
|
100
94
|
|
|
101
|
-
Deterministic review of git changes. No LLM
|
|
95
|
+
Deterministic review of git changes. No LLM resolver — scope and file list are derived directly from `git diff`.
|
|
102
96
|
|
|
103
97
|
```bash
|
|
104
|
-
deskcheck diff
|
|
105
|
-
deskcheck diff
|
|
106
|
-
deskcheck diff HEAD~3
|
|
107
|
-
deskcheck diff main --
|
|
108
|
-
deskcheck diff main --
|
|
109
|
-
deskcheck diff main --
|
|
110
|
-
deskcheck diff main --
|
|
111
|
-
deskcheck diff main --criteria=dto-enforcement # Only run one criterion
|
|
112
|
-
deskcheck diff main --criteria=security,naming # Only run specific criteria
|
|
98
|
+
deskcheck diff # Working tree vs HEAD (staged + unstaged)
|
|
99
|
+
deskcheck diff main # Changes vs main
|
|
100
|
+
deskcheck diff HEAD~3 # Last 3 commits
|
|
101
|
+
deskcheck diff main --dry-run # Preview plan (runs partitioners) without executing reviewers
|
|
102
|
+
deskcheck diff main --fail-on=critical # Exit 1 if critical findings (for CI)
|
|
103
|
+
deskcheck diff main --format=markdown # Markdown output (for PR comments)
|
|
104
|
+
deskcheck diff main --criteria=security # Only run one criterion
|
|
113
105
|
```
|
|
114
106
|
|
|
115
107
|
### `deskcheck "<prompt>"`
|
|
116
108
|
|
|
117
|
-
Natural
|
|
109
|
+
Natural-language review — a resolver agent interprets what you want to check and produces a `{ scope, files }` pair, then the same downstream pipeline runs.
|
|
118
110
|
|
|
119
111
|
```bash
|
|
120
|
-
deskcheck "src/services/
|
|
112
|
+
deskcheck "review src/services/"
|
|
121
113
|
deskcheck "check the auth module"
|
|
122
|
-
deskcheck "
|
|
114
|
+
deskcheck "review changes against develop"
|
|
115
|
+
deskcheck "review src/" --scope changes:main # Override resolver's scope inference
|
|
116
|
+
deskcheck "review src/" --criteria=security # Only run specific criteria
|
|
123
117
|
```
|
|
124
118
|
|
|
125
119
|
### `deskcheck serve`
|
|
126
120
|
|
|
127
|
-
Web dashboard with live updates.
|
|
121
|
+
Web dashboard with live updates via SSE. Four views: run list, review overview (pipeline + criteria + issues), criterion detail (partitioner reasoning + subtask list), and subtask detail (issue cards with code).
|
|
128
122
|
|
|
129
123
|
```bash
|
|
130
124
|
deskcheck serve # Start on default port (3000)
|
|
@@ -144,7 +138,7 @@ deskcheck show --fail-on=warning # Exit 1 if warnings or worse
|
|
|
144
138
|
|
|
145
139
|
### `deskcheck watch [plan-id]`
|
|
146
140
|
|
|
147
|
-
Live terminal tree view of a run in progress.
|
|
141
|
+
Live terminal tree view of a run in progress. Shows partition decisions and per-subtask `[focus]` annotations.
|
|
148
142
|
|
|
149
143
|
### `deskcheck list`
|
|
150
144
|
|
|
@@ -160,32 +154,10 @@ deskcheck test controller-conventions # Run tests for one criterion
|
|
|
160
154
|
deskcheck test --criteria=dto-enforcement,naming # Run tests for specific criteria
|
|
161
155
|
```
|
|
162
156
|
|
|
163
|
-
Test fixtures live in `deskcheck/tests/` mirroring the criteria directory structure. Each test case has a fixture file (code to review) and an `expected.md` (what should be found). An LLM judge compares actual findings against expectations and produces scores:
|
|
164
|
-
|
|
165
|
-
- **Recall** — Were expected violations found?
|
|
166
|
-
- **Precision** — Were all findings legitimate?
|
|
167
|
-
- **Scope compliance** — Did every finding come from the criterion's checklist?
|
|
168
|
-
|
|
169
|
-
Results are persisted in `.deskcheck/test-runs/` for inspection.
|
|
170
|
-
|
|
171
157
|
### `deskcheck init`
|
|
172
158
|
|
|
173
159
|
Scaffold config and criteria directory for a new project.
|
|
174
160
|
|
|
175
|
-
## Web Dashboard
|
|
176
|
-
|
|
177
|
-
Start with `deskcheck serve` and open `http://localhost:3000`.
|
|
178
|
-
|
|
179
|
-
**Run overview** — progress bar, usage/cost tracking, sortable task table with severity filters, and file coverage:
|
|
180
|
-
|
|
181
|
-

|
|
182
|
-
|
|
183
|
-
**File detail** — click any file to see all findings across criteria, with severity filtering and grouping options:
|
|
184
|
-
|
|
185
|
-

|
|
186
|
-
|
|
187
|
-
The dashboard uses SSE for live updates — watch tasks complete in real time during execution.
|
|
188
|
-
|
|
189
161
|
## Criterion Reference
|
|
190
162
|
|
|
191
163
|
### Frontmatter Fields
|
|
@@ -193,10 +165,10 @@ The dashboard uses SSE for live updates — watch tasks complete in real time du
|
|
|
193
165
|
| Field | Required | Default | Description |
|
|
194
166
|
|-------|----------|---------|-------------|
|
|
195
167
|
| `description` | Yes | — | Human-readable description shown in reports |
|
|
196
|
-
| `severity` | Yes | — | Importance: `critical`, `high`, `medium`, `low` |
|
|
197
168
|
| `globs` | Yes | — | File patterns to match. Prefix with `!` to exclude |
|
|
198
|
-
| `
|
|
199
|
-
| `model` | No | `"haiku"` | Claude model: `haiku`, `sonnet`, `opus` |
|
|
169
|
+
| `partition` | No | `"one task per matched file"` | Natural-language instruction for how the partitioner agent should split matched files into subtasks |
|
|
170
|
+
| `model` | No | `"haiku"` | Claude model for reviewer agents: `haiku`, `sonnet`, `opus` |
|
|
171
|
+
| `tools` | No | `[]` | Extra tools available to reviewers for this criterion (e.g. `["WebFetch"]`), layered on top of built-ins |
|
|
200
172
|
|
|
201
173
|
### Choosing the Right Model
|
|
202
174
|
|
|
@@ -212,19 +184,32 @@ The dashboard uses SSE for live updates — watch tasks complete in real time du
|
|
|
212
184
|
|
|
213
185
|
### The Detective Prompt
|
|
214
186
|
|
|
215
|
-
The markdown body below the frontmatter is the **detective prompt** — instructions given to each
|
|
187
|
+
The markdown body below the frontmatter is the **detective prompt** — instructions given to each reviewer agent. Include:
|
|
216
188
|
|
|
217
189
|
- **What to check** — specific patterns and violations
|
|
218
190
|
- **What NOT to check** — exclusions to reduce false positives
|
|
219
191
|
- **Severity guidance** — when to report critical vs warning vs info
|
|
220
192
|
|
|
221
|
-
|
|
193
|
+
Reviewers have built-in tools (Read, Grep, Glob, Bash) and fetch their own context based on the scope, so your prompt can reference other files:
|
|
222
194
|
|
|
223
195
|
```markdown
|
|
224
196
|
Read `.eslintrc.js` to understand the project's linting config.
|
|
225
197
|
Then check for architectural patterns that ESLint can't catch.
|
|
226
198
|
```
|
|
227
199
|
|
|
200
|
+
### Partition Instruction
|
|
201
|
+
|
|
202
|
+
The `partition` field tells the partitioner agent how to split matched files into subtasks. Examples:
|
|
203
|
+
|
|
204
|
+
```yaml
|
|
205
|
+
partition: one task per file # Simple, default-like
|
|
206
|
+
partition: one public method per task # Sub-file: same file appears in multiple subtasks with different focus
|
|
207
|
+
partition: group each test with its source # Cross-file grouping
|
|
208
|
+
partition: bundle all controllers together # Single grouped review
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The partitioner agent reads this instruction, inspects the matched files using its tools, and produces subtasks with `files`, optional `focus` (sub-file narrowing), and optional `hint` (reasoning for the grouping).
|
|
212
|
+
|
|
228
213
|
## Configuration
|
|
229
214
|
|
|
230
215
|
Configuration lives in `.deskcheck/config.json` (created by `deskcheck init`):
|
|
@@ -239,7 +224,8 @@ Configuration lives in `.deskcheck/config.json` (created by `deskcheck init`):
|
|
|
239
224
|
"mcp_servers": {}
|
|
240
225
|
},
|
|
241
226
|
"agents": {
|
|
242
|
-
"
|
|
227
|
+
"resolver": { "model": "haiku" },
|
|
228
|
+
"partitioner": { "model": "haiku" },
|
|
243
229
|
"executor": {},
|
|
244
230
|
"evaluator": { "model": "haiku" },
|
|
245
231
|
"judge": { "model": "opus" }
|
|
@@ -247,8 +233,10 @@ Configuration lives in `.deskcheck/config.json` (created by `deskcheck init`):
|
|
|
247
233
|
}
|
|
248
234
|
```
|
|
249
235
|
|
|
250
|
-
-
|
|
251
|
-
- The **
|
|
236
|
+
- **Built-in reviewer tools** (`Read`, `Grep`, `Glob`, `Bash`) are always available regardless of `shared.allowed_tools`. The config tools layer on top.
|
|
237
|
+
- The **reviewer model** comes from each criterion's `model` field, not from config.
|
|
238
|
+
- The **partitioner model** comes from `agents.partitioner.model` (shared across all criteria).
|
|
239
|
+
- The **resolver model** (for natural-language `deskcheck "<prompt>"`) comes from `agents.resolver.model`.
|
|
252
240
|
|
|
253
241
|
## CI Integration
|
|
254
242
|
|
|
@@ -280,26 +268,36 @@ Deskcheck can run as an MCP server for Claude Code integration:
|
|
|
280
268
|
}
|
|
281
269
|
```
|
|
282
270
|
|
|
283
|
-
##
|
|
271
|
+
## Demo & Development
|
|
272
|
+
|
|
273
|
+
### Seed fixtures for UI work (free, no API calls)
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npm run seed -- --clean # Write 5 synthetic plans exercising every UI state
|
|
277
|
+
deskcheck serve # http://localhost:3000
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Run a real review against the demo project (~5–15¢)
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
cd examples/demo-project
|
|
284
|
+
git init -q && git add -A && git commit -qm init # one-time setup
|
|
285
|
+
deskcheck "review src/" # runs resolver + partitioners + reviewers
|
|
286
|
+
```
|
|
284
287
|
|
|
285
|
-
|
|
288
|
+
See [`examples/demo-project/README.md`](examples/demo-project/README.md) for the planted issues and expected findings.
|
|
286
289
|
|
|
287
|
-
|
|
290
|
+
### Development setup
|
|
288
291
|
|
|
289
292
|
The fastest way to get started is with the included **Dev Container** (VS Code + Docker):
|
|
290
293
|
|
|
291
294
|
1. Open the repo in VS Code
|
|
292
|
-
2. When prompted, click **"Reopen in Container"**
|
|
295
|
+
2. When prompted, click **"Reopen in Container"**
|
|
293
296
|
3. Press **Ctrl+Shift+B** to launch the dev environment
|
|
294
297
|
|
|
295
|
-
This starts
|
|
296
|
-
- **Backend server** on port 3000 (builds TypeScript, then runs `deskcheck serve`)
|
|
297
|
-
- **TypeScript watch** (`tsc --watch` for backend changes)
|
|
298
|
-
- **Vite dev server** on port 5173 (Vue UI with hot reload)
|
|
299
|
-
|
|
300
|
-
Open `http://localhost:5173` for UI development — API requests are proxied to the backend automatically.
|
|
298
|
+
This starts backend server (port 3000), TypeScript watch, and Vite dev server (port 5173).
|
|
301
299
|
|
|
302
|
-
|
|
300
|
+
Without Dev Container:
|
|
303
301
|
|
|
304
302
|
```bash
|
|
305
303
|
# Terminal 1: backend
|
|
@@ -312,10 +310,6 @@ npm run dev
|
|
|
312
310
|
cd ui && npm install && npm run dev
|
|
313
311
|
```
|
|
314
312
|
|
|
315
|
-
## Disclaimer
|
|
316
|
-
|
|
317
|
-
This tool was vibe-coded in a single day using [Claude Code](https://claude.ai/claude-code). The architecture, implementation, web UI, and even this README were built through conversation with Claude Opus 4.6. It works, we use it, but it hasn't been battle-tested at scale. Expect rough edges. Contributions welcome.
|
|
318
|
-
|
|
319
313
|
## License
|
|
320
314
|
|
|
321
315
|
MIT
|