bots-garden/mini-mepublic Fork
⑂ main
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

Plan builtin tool #10

Merged@k33g wants to merge feature/tasks-builtin into main
Merged as 2db607d6c817.
29 files changed
modified .tickets/issues/0004-do-we-need-mcp.yaml +1 -2
@@ -6,9 +6,8 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-15T22:38:45.129Z
9-updatedAt: 2026-09-21T19:04:58.320Z
9+updatedAt: 2026-09-22T20:57:39.912Z
1010 labels: []
11-milestone: v0.04
1211 body: |
1312 I would say no - use a CLI
1413
@@ -6,9 +6,8 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-15T22:38:45.129Z8 createdAt: 2026-09-15T22:38:45.129Z
9-updatedAt: 2026-09-21T19:04:58.320Z9+updatedAt: 2026-09-22T20:57:39.912Z
10 labels: []10 labels: []
11-milestone: v0.04
12 body: |11 body: |
13 I would say no - use a CLI12 I would say no - use a CLI
14 13
modified .tickets/issues/0025-tasks-plan-builtin.yaml +26 -5
@@ -1,14 +1,35 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 25
33 title: Tasks / Plan builtin
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-19T16:06:33.119Z
9-updatedAt: 2026-09-19T16:06:33.119Z
10-labels: []
11-milestone: v0.04
12-body: ""
9+updatedAt: 2026-09-22T20:54:40.140Z
10+labels:
11+ - kind::feature
12+ - builtin tool
13+ - priority::medium
14+milestone: v0.0.4
15+body: |
16+ ## Implementation note (Mistral Vibe, 2026-09-22)
17+
18+ Model-driven plan management: when user gives a list of tasks, the agent autonomously creates and tracks a plan.
19+
20+ **Components:**
21+ - `internal/tools/plan.go`: plan tool with in-memory PlanStore (session-scoped)
22+ - Actions: create, get, update, next, status, list, delete
23+ - `skills/plan-manager/SKILL.md`: detection patterns and usage guidelines
24+ - Config: `planTool: true/false` in agent.yaml (default: true)
25+ - Integration: plans cleared on `/new` command
26+
27+ **Storage:** Option A (in-memory, per-session). Lost on restart.
28+
29+ **Display:** Status line in responses (e.g., `[2/5] Task 2: Fix bugs (in_progress)`)
30+
31+ **Tests:** `internal/tools/plan_test.go` - all passing
32+
33+ **Docs:** EN+FR how-to guides in `docs/en/how-to/manage-plans-and-tasks.md` and `docs/fr/how-to/manage-plans-and-tasks.md`
1334 tasks: []
1435 comments: []
@@ -1,14 +1,35 @@
1 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.1 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2 id: 252 id: 25
3 title: Tasks / Plan builtin3 title: Tasks / Plan builtin
4-state: open4+state: closed
5 author:5 author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-19T16:06:33.119Z8 createdAt: 2026-09-19T16:06:33.119Z
9-updatedAt: 2026-09-19T16:06:33.119Z9+updatedAt: 2026-09-22T20:54:40.140Z
10-labels: []10+labels:
11-milestone: v0.0411+ - kind::feature
12-body: ""12+ - builtin tool
13+ - priority::medium
14+milestone: v0.0.4
15+body: |
16+ ## Implementation note (Mistral Vibe, 2026-09-22)
17+
18+ Model-driven plan management: when user gives a list of tasks, the agent autonomously creates and tracks a plan.
19+
20+ **Components:**
21+ - `internal/tools/plan.go`: plan tool with in-memory PlanStore (session-scoped)
22+ - Actions: create, get, update, next, status, list, delete
23+ - `skills/plan-manager/SKILL.md`: detection patterns and usage guidelines
24+ - Config: `planTool: true/false` in agent.yaml (default: true)
25+ - Integration: plans cleared on `/new` command
26+
27+ **Storage:** Option A (in-memory, per-session). Lost on restart.
28+
29+ **Display:** Status line in responses (e.g., `[2/5] Task 2: Fix bugs (in_progress)`)
30+
31+ **Tests:** `internal/tools/plan_test.go` - all passing
32+
33+ **Docs:** EN+FR how-to guides in `docs/en/how-to/manage-plans-and-tasks.md` and `docs/fr/how-to/manage-plans-and-tasks.md`
13 tasks: []34 tasks: []
14 comments: []35 comments: []
modified .tickets/issues/0030-how-to-use-mini-me-with-claude.yaml +1 -2
@@ -6,9 +6,8 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-21T04:00:56.971Z
9-updatedAt: 2026-09-21T19:03:27.354Z
9+updatedAt: 2026-09-22T20:57:22.310Z
1010 labels: []
11-milestone: v0.04
1211 body: |
1312 ## Analysis (Claude, 2026-09-21 — not implemented)
1413
@@ -6,9 +6,8 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-21T04:00:56.971Z8 createdAt: 2026-09-21T04:00:56.971Z
9-updatedAt: 2026-09-21T19:03:27.354Z9+updatedAt: 2026-09-22T20:57:22.310Z
10 labels: []10 labels: []
11-milestone: v0.04
12 body: |11 body: |
13 ## Analysis (Claude, 2026-09-21 — not implemented)12 ## Analysis (Claude, 2026-09-21 — not implemented)
14 13
modified .tickets/issues/0031-how-to-use-mini-me-with-gemini.yaml +1 -2
@@ -6,9 +6,8 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-21T04:01:15.166Z
9-updatedAt: 2026-09-21T19:04:28.691Z
9+updatedAt: 2026-09-22T20:56:55.345Z
1010 labels: []
11-milestone: v0.04
1211 body: |
1312 ## Analysis (Claude, 2026-09-21 — not implemented)
1413
@@ -6,9 +6,8 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-21T04:01:15.166Z8 createdAt: 2026-09-21T04:01:15.166Z
9-updatedAt: 2026-09-21T19:04:28.691Z9+updatedAt: 2026-09-22T20:56:55.345Z
10 labels: []10 labels: []
11-milestone: v0.04
12 body: |11 body: |
13 ## Analysis (Claude, 2026-09-21 — not implemented)12 ## Analysis (Claude, 2026-09-21 — not implemented)
14 13
modified .tickets/issues/0032-add-prompt-flag.yaml +2 -2
@@ -6,9 +6,9 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-21T04:47:19.089Z
9-updatedAt: 2026-09-21T04:58:31.828Z
9+updatedAt: 2026-09-22T20:54:40.140Z
1010 labels: []
11-milestone: v0.04
11+milestone: v0.0.4
1212 epic: CLI
1313 body: ""
1414 tasks: []
@@ -6,9 +6,9 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-21T04:47:19.089Z8 createdAt: 2026-09-21T04:47:19.089Z
9-updatedAt: 2026-09-21T04:58:31.828Z9+updatedAt: 2026-09-22T20:54:40.140Z
10 labels: []10 labels: []
11-milestone: v0.0411+milestone: v0.0.4
12 epic: CLI12 epic: CLI
13 body: ""13 body: ""
14 tasks: []14 tasks: []
modified .tickets/issues/0033-invoke-another-mini-me.yaml +1 -2
@@ -6,9 +6,8 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-21T04:48:03.596Z
9-updatedAt: 2026-09-21T04:58:54.762Z
9+updatedAt: 2026-09-22T20:56:40.361Z
1010 labels: []
11-milestone: v0.04
1211 epic: Builtin tools
1312 body: |
1413 Should I use ACP ? I think yes
@@ -6,9 +6,8 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-21T04:48:03.596Z8 createdAt: 2026-09-21T04:48:03.596Z
9-updatedAt: 2026-09-21T04:58:54.762Z9+updatedAt: 2026-09-22T20:56:40.361Z
10 labels: []10 labels: []
11-milestone: v0.04
12 epic: Builtin tools11 epic: Builtin tools
13 body: |12 body: |
14 Should I use ACP ? I think yes13 Should I use ACP ? I think yes
modified .tickets/issues/0035-create-sbx-template-kit-for-mini-me.yaml +2 -2
@@ -1,12 +1,12 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 35
33 title: Create SBX Template + Kit for Mini-Me
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-21T04:51:17.051Z
9-updatedAt: 2026-09-21T19:06:52.839Z
9+updatedAt: 2026-09-22T20:55:22.352Z
1010 labels: []
1111 milestone: v0.0.3
1212 body: |
@@ -1,12 +1,12 @@
1 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.1 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2 id: 352 id: 35
3 title: Create SBX Template + Kit for Mini-Me3 title: Create SBX Template + Kit for Mini-Me
4-state: open4+state: closed
5 author:5 author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-21T04:51:17.051Z8 createdAt: 2026-09-21T04:51:17.051Z
9-updatedAt: 2026-09-21T19:06:52.839Z9+updatedAt: 2026-09-22T20:55:22.352Z
10 labels: []10 labels: []
11 milestone: v0.0.311 milestone: v0.0.3
12 body: |12 body: |
modified .tickets/issues/0036-hooks.yaml +2 -2
@@ -6,9 +6,9 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-21T06:32:48.566Z
9-updatedAt: 2026-09-21T06:32:48.566Z
9+updatedAt: 2026-09-22T20:54:40.140Z
1010 labels: []
11-milestone: v0.04
11+milestone: v0.0.4
1212 body: ""
1313 tasks: []
1414 comments: []
@@ -6,9 +6,9 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-21T06:32:48.566Z8 createdAt: 2026-09-21T06:32:48.566Z
9-updatedAt: 2026-09-21T06:32:48.566Z9+updatedAt: 2026-09-22T20:54:40.140Z
10 labels: []10 labels: []
11-milestone: v0.0411+milestone: v0.0.4
12 body: ""12 body: ""
13 tasks: []13 tasks: []
14 comments: []14 comments: []
modified .tickets/milestones.yaml +2 -2
@@ -4,8 +4,8 @@ milestones:
44 state: closed
55 dueOn: 2026-09-18
66 - title: v0.0.3
7- state: open
7+ state: closed
88 dueOn: 2026-09-30
9- - title: v0.04
9+ - title: v0.0.4
1010 state: open
1111 dueOn: 2026-10-15
@@ -4,8 +4,8 @@ milestones:
4 state: closed4 state: closed
5 dueOn: 2026-09-185 dueOn: 2026-09-18
6 - title: v0.0.36 - title: v0.0.3
7- state: open7+ state: closed
8 dueOn: 2026-09-308 dueOn: 2026-09-30
9- - title: v0.049+ - title: v0.0.4
10 state: open10 state: open
11 dueOn: 2026-10-1511 dueOn: 2026-10-15
added .vibe/AGENTS.md +80 -0
new file mode 100644
@@ -0,0 +1,80 @@
1+# Working in this sandbox
2+
3+Instructions installed by the `dev-toolkit` kit. They apply to **every** session, whatever the project.
4+
5+## Always start by reading the project memory
6+
7+Before planning, before asking the user anything, before touching a file — check for a `.memory/` directory at the repository root:
8+
9+```bash
10+ls .memory/ 2>/dev/null
11+```
12+
13+**If it exists, read it before doing anything else:**
14+
15+| Read | Why |
16+| --- | --- |
17+| `.memory/summary.md` | What the project is, its architecture, the decisions currently in force, the real build/test/run commands. |
18+| the tail of `.memory/history.md` | What has already been done, and why it was done that way. |
19+| the most recent file in `.memory/handoffs/` | Where the last session stopped: work in flight, next steps, blockers, traps. |
20+
21+Then, before you propose anything:
22+
23+- **Do not ask the user for information that is already recorded there.** Re-deriving state that is written down wastes the user's time and is the main reason this record exists.
24+- **Do not re-litigate a decision recorded in `summary.md`** without saying you are doing so and why. If you think a decision in force is wrong, say so explicitly and let the user decide.
25+- **Surface unfinished work.** If a handoff records work in flight, report it and ask whether to resume it or start something new — do not silently start something else on top of it.
26+- **Reuse the commands the memory documents.** Do not invent a parallel way to build or test a project that already has one.
27+
28+If `.memory/` does not exist yet, carry on — you will create it when you write your handoff (see below).
29+
30+## Always finish by updating the project memory
31+
32+**Every session ends with all three files below brought up to date. No exceptions** — not for a one-line fix, not for a session that only read code, not for a session that failed to achieve anything.
33+
34+You cannot detect the moment a session actually ends, so use this trigger instead: **do this as the last action before you hand control back, having finished or abandoned what the user asked for.** If the work then continues, extend what you already wrote instead of adding a second set of entries.
35+
36+Two rules govern all three files. **Match the length to the work** — a one-line fix earns a few lines, not a filled-in template; padding with "N/A" makes the record unreadable, which is the one way this mandate defeats itself. And **record what the next person cannot re-derive** — where you stopped, what you tried that failed, the trap you hit, the decision still waiting on the user. Not a diff summary; git already has that.
37+
38+### 1. `summary.md` — edit in place, never regenerate
39+
40+- **Change only the parts your session actually establishes or invalidates.** Leave the rest byte-for-byte alone. You have seen a slice of this project; the file holds what every previous session established, and rewriting it wholesale from your slice silently destroys accurate content you never looked at. This is the single biggest risk in this whole mandate.
41+- **Only from what you verified** — a command you ran, a file you read. Never a plausible guess.
42+- **If nothing about the project's state changed, leave the file untouched.** That is what "update" means; it is not an exception to the mandate.
43+- What you could not check goes under an explicit `## Not yet established` heading. A summary that states unknowns as unknown is useful; one that states guesses as fact is worse than none, because the next session will trust it.
44+
45+### 2. `history.md` — append exactly one entry
46+
47+- One dated entry per session, appended at the end. **Never rewrite or delete an existing entry**, including your own from an earlier turn.
48+- Cover: what was asked, what changed, decisions made and alternatives rejected, tests, quality gate result, docs touched — dropping the lines that have no content.
49+- A read-only or failed session gets an entry too. One line stating that, and why, is a complete entry.
50+
51+### 3. `handoffs/YYYY-MM-DD-<slug>.md` — write or update today's
52+
53+- The slug names the topic. If a file for today already covers this topic, **update it**; if today's work is a different topic, write a new file under a different slug. Never overwrite another session's handoff.
54+- **A session that achieved nothing still gets a handoff**, and it is one of the valuable ones: it stops the next agent walking into the same wall.
55+
56+### If `.memory/` does not exist
57+
58+Create the whole skeleton — `README.md`, `summary.md`, `history.md`, and `handoffs/` with your handoff in it. All four, even if your session touched one file, so a later session finds a record to read and extend rather than a bare directory. `summary.md` is then written under the same rules as above: only what you verified, the rest under `## Not yet established`. `history.md` starts with its first dated entry: this session.
59+
60+The full templates for all three files are in the `methodical-dev` skill (Phase 7). Use them as a menu, not a form to fill in.
61+
62+## Keep the memory true
63+
64+`.memory/` is **committed to the repository**, not gitignored. It only stays useful if it stays accurate, and the three files stay accurate in different ways: `summary.md` is a **snapshot** — it describes the present and carries no history. `history.md` and `handoffs/` are the **record** — they only ever grow, and are never tidied up, condensed, or corrected after the fact. A history you edit is not a history.
65+
66+`.memory/` is for whoever *continues building* the project. `docs/` is for whoever *uses* it. Keep the two apart rather than duplicating content between them.
67+
68+## Skills installed by this kit
69+
70+Prefer these over doing the same work by hand:
71+
72+| Skill | Use it for |
73+| --- | --- |
74+| `methodical-dev` | Any non-trivial change. Approval-gated: requirements → plan → implementation with tests → quality gate → EN+FR docs → `.memory/` update. Start here. |
75+| `quality` | Measuring code quality with qlty and refactoring until the gate passes. Never invoke qlty ad hoc instead. |
76+| `diataxis-doc` | Writing or restructuring documentation with the Diátaxis four-quadrant method. |
77+
78+Never make a check pass by weakening it — no new `exclude_patterns`, no lowered thresholds, no disabled plugins, no deleted or skipped tests. Fix the code, or report that you could not.
79+
80+The `quality` skill defines two narrow exceptions, both conditioned on evidence and on the user's agreement: excluding a vendored `kits/` directory (the measurement tool cannot measure itself), and removing a plugin proven to analyse nothing. Neither is a licence to trim a number — read the skill before invoking either, and never widen them.
new file mode 100644
@@ -0,0 +1,80 @@
1+# Working in this sandbox
2+
3+Instructions installed by the `dev-toolkit` kit. They apply to **every** session, whatever the project.
4+
5+## Always start by reading the project memory
6+
7+Before planning, before asking the user anything, before touching a file — check for a `.memory/` directory at the repository root:
8+
9+```bash
10+ls .memory/ 2>/dev/null
11+```
12+
13+**If it exists, read it before doing anything else:**
14+
15+| Read | Why |
16+| --- | --- |
17+| `.memory/summary.md` | What the project is, its architecture, the decisions currently in force, the real build/test/run commands. |
18+| the tail of `.memory/history.md` | What has already been done, and why it was done that way. |
19+| the most recent file in `.memory/handoffs/` | Where the last session stopped: work in flight, next steps, blockers, traps. |
20+
21+Then, before you propose anything:
22+
23+- **Do not ask the user for information that is already recorded there.** Re-deriving state that is written down wastes the user's time and is the main reason this record exists.
24+- **Do not re-litigate a decision recorded in `summary.md`** without saying you are doing so and why. If you think a decision in force is wrong, say so explicitly and let the user decide.
25+- **Surface unfinished work.** If a handoff records work in flight, report it and ask whether to resume it or start something new — do not silently start something else on top of it.
26+- **Reuse the commands the memory documents.** Do not invent a parallel way to build or test a project that already has one.
27+
28+If `.memory/` does not exist yet, carry on — you will create it when you write your handoff (see below).
29+
30+## Always finish by updating the project memory
31+
32+**Every session ends with all three files below brought up to date. No exceptions** — not for a one-line fix, not for a session that only read code, not for a session that failed to achieve anything.
33+
34+You cannot detect the moment a session actually ends, so use this trigger instead: **do this as the last action before you hand control back, having finished or abandoned what the user asked for.** If the work then continues, extend what you already wrote instead of adding a second set of entries.
35+
36+Two rules govern all three files. **Match the length to the work** — a one-line fix earns a few lines, not a filled-in template; padding with "N/A" makes the record unreadable, which is the one way this mandate defeats itself. And **record what the next person cannot re-derive** — where you stopped, what you tried that failed, the trap you hit, the decision still waiting on the user. Not a diff summary; git already has that.
37+
38+### 1. `summary.md` — edit in place, never regenerate
39+
40+- **Change only the parts your session actually establishes or invalidates.** Leave the rest byte-for-byte alone. You have seen a slice of this project; the file holds what every previous session established, and rewriting it wholesale from your slice silently destroys accurate content you never looked at. This is the single biggest risk in this whole mandate.
41+- **Only from what you verified** — a command you ran, a file you read. Never a plausible guess.
42+- **If nothing about the project's state changed, leave the file untouched.** That is what "update" means; it is not an exception to the mandate.
43+- What you could not check goes under an explicit `## Not yet established` heading. A summary that states unknowns as unknown is useful; one that states guesses as fact is worse than none, because the next session will trust it.
44+
45+### 2. `history.md` — append exactly one entry
46+
47+- One dated entry per session, appended at the end. **Never rewrite or delete an existing entry**, including your own from an earlier turn.
48+- Cover: what was asked, what changed, decisions made and alternatives rejected, tests, quality gate result, docs touched — dropping the lines that have no content.
49+- A read-only or failed session gets an entry too. One line stating that, and why, is a complete entry.
50+
51+### 3. `handoffs/YYYY-MM-DD-<slug>.md` — write or update today's
52+
53+- The slug names the topic. If a file for today already covers this topic, **update it**; if today's work is a different topic, write a new file under a different slug. Never overwrite another session's handoff.
54+- **A session that achieved nothing still gets a handoff**, and it is one of the valuable ones: it stops the next agent walking into the same wall.
55+
56+### If `.memory/` does not exist
57+
58+Create the whole skeleton — `README.md`, `summary.md`, `history.md`, and `handoffs/` with your handoff in it. All four, even if your session touched one file, so a later session finds a record to read and extend rather than a bare directory. `summary.md` is then written under the same rules as above: only what you verified, the rest under `## Not yet established`. `history.md` starts with its first dated entry: this session.
59+
60+The full templates for all three files are in the `methodical-dev` skill (Phase 7). Use them as a menu, not a form to fill in.
61+
62+## Keep the memory true
63+
64+`.memory/` is **committed to the repository**, not gitignored. It only stays useful if it stays accurate, and the three files stay accurate in different ways: `summary.md` is a **snapshot** — it describes the present and carries no history. `history.md` and `handoffs/` are the **record** — they only ever grow, and are never tidied up, condensed, or corrected after the fact. A history you edit is not a history.
65+
66+`.memory/` is for whoever *continues building* the project. `docs/` is for whoever *uses* it. Keep the two apart rather than duplicating content between them.
67+
68+## Skills installed by this kit
69+
70+Prefer these over doing the same work by hand:
71+
72+| Skill | Use it for |
73+| --- | --- |
74+| `methodical-dev` | Any non-trivial change. Approval-gated: requirements → plan → implementation with tests → quality gate → EN+FR docs → `.memory/` update. Start here. |
75+| `quality` | Measuring code quality with qlty and refactoring until the gate passes. Never invoke qlty ad hoc instead. |
76+| `diataxis-doc` | Writing or restructuring documentation with the Diátaxis four-quadrant method. |
77+
78+Never make a check pass by weakening it — no new `exclude_patterns`, no lowered thresholds, no disabled plugins, no deleted or skipped tests. Fix the code, or report that you could not.
79+
80+The `quality` skill defines two narrow exceptions, both conditioned on evidence and on the user's agreement: excluding a vendored `kits/` directory (the measurement tool cannot measure itself), and removing a plugin proven to analyse nothing. Neither is a licence to trim a number — read the skill before invoking either, and never widen them.
added .vibe/skills/diataxis-doc/SKILL.md +520 -0
Large diff collapsed to keep the page fast — load it when you need it.
added .vibe/skills/methodical-dev/SKILL.md +603 -0
Large diff collapsed to keep the page fast — load it when you need it.
added .vibe/skills/quality/SKILL.md +266 -0
new file mode 100644
@@ -0,0 +1,266 @@
1+---
2+name: quality
3+description: Audit and improve this project's code quality with qlty. Sets qlty up on first use, measures lint issues / code smells / complexity, writes a timestamped Markdown report under .quality/, tracks progression across runs, and refactors until the quality gate passes. Use when asked to check code quality, run a quality report, review technical debt, see whether quality is improving, or clean up / refactor the codebase.
4+---
5+
6+# Quality
7+
8+Measure this project's code quality with [qlty](https://docs.qlty.sh), report it, and
9+refactor until the gate passes.
10+
11+The measurement is a script, not a judgement call — run it, then act on what it says.
12+It is read-only with respect to the source tree (`qlty check` runs with `--no-fix`), so
13+measuring never quietly rewrites the code you are about to reason about.
14+
15+## 1. Set up (only if needed)
16+
17+The setup is self-healing; just run the script. It verifies `qlty` is on `PATH`, that
18+the workspace is a git repository, and runs `qlty init --yes` when there is no
19+`.qlty/qlty.toml` yet.
20+
21+If `qlty` is missing entirely, the sandbox was not created with the `dev-toolkit`
22+kit. Say so and stop — do not install qlty by hand.
23+
24+**If the project vendors this kit** — a `kits/` directory holding the sources that get
25+installed into `~/.claude/` — add it to `exclude_patterns` in `.qlty/qlty.toml` on the
26+first run:
27+
28+```toml
29+exclude_patterns = [
30+ # … the defaults qlty init wrote …
31+ "kits/**", # the kit's own sources, including this skill's quality_report.py
32+]
33+```
34+
35+This is **not** an exception to "do not game the gate" below. The reason is narrower and
36+holds regardless of what the numbers say: `quality_report.py` is the script that
37+*produces* the measurement, so leaving it in scope means measuring the instrument with
38+itself. Two of its findings are structurally unfixable — a script whose job is to run
39+`qlty` must import and call `subprocess`, which every Python security linter flags.
40+
41+Two conditions make this legitimate rather than convenient, and both must hold:
42+
43+- **It is the project's decision, not yours.** Say what the exclusion hides and why, and
44+ let the user choose. Adding it unilaterally is the forbidden move.
45+- **Write down what it hides.** Put the actual findings in a comment next to the pattern.
46+ Some of them are usually real defects in the script — over-complex functions, unused
47+ imports — and they should be fixed at the kit's source rather than forgotten. An
48+ exclusion that records what it silences stays honest; one that just makes a number
49+ drop is the start of the drift.
50+
51+## 2. Measure
52+
53+From the project root:
54+
55+```bash
56+python3 ~/.claude/skills/quality/scripts/quality_report.py --workspace .
57+```
58+
59+On a cold cache the first run takes several minutes: qlty downloads its plugin
60+definitions and the linter binaries. Subsequent runs are fast (the cache lives on a
61+persistent volume at `~/.qlty`).
62+
63+The script:
64+
65+- runs `qlty check --all`, `qlty smells --all`, and `qlty metrics --all`
66+- writes `.quality/report-<timestamp>.md` and `.quality/report-latest.md`
67+- appends one JSON line to `.quality/history.jsonl`
68+- prints the report to stdout
69+- **exits `0` if the gate passed, `1` if it failed, `2` on a tooling error**
70+
71+Use the exit code as the loop condition. Do not re-derive the verdict yourself.
72+
73+## 3. Read the report
74+
75+The report contains:
76+
77+| Section | What to do with it |
78+| --- | --- |
79+| **Gate violations** | The work list. Each line is a threshold that was breached. |
80+| **Lint issues** by level, top rules, most affected files | Where to start — but read the count correctly first, see below. |
81+| **Code smells** | Duplication and over-complex structure — these need real refactoring, not a formatter. |
82+| **Metrics** | `complex` / `cyclo` per file; the "Most complex files" table names refactoring targets. |
83+| **Trend** | Last 10 runs. This is how you show progression. |
84+| **Tooling notes** | Present only when a qlty invocation failed — investigate before trusting the numbers. |
85+
86+### Read the count before you trust it
87+
88+"Fix the highest-count rule first" is the right instinct and the wrong first step. A
89+count is `occurrences`, not `distinct problems`, and the two diverge badly in two common
90+cases:
91+
92+- **One finding, repeated per manifest.** `osv-scanner` reports a dependency CVE once per
93+ `go.mod` / `package.json` it appears in. A monorepo with a dozen manifests turns one
94+ vulnerable version into a hundred-plus findings, and adding a three-line example
95+ manifest multiplies the total without degrading anything.
96+- **One finding, repeated per file.** A linter that fails to parse the language emits one
97+ finding per source file. That looks like the largest cluster in the report and is worth
98+ exactly nothing.
99+
100+And before treating a *delta* as a regression: **re-run.** A count that moves while the
101+tree is untouched is measuring the tool, not the code. The usual cause is a linter
102+answering from its own partially-populated cache — qlty invokes several with
103+`--allow-parallel-runners`, and an invocation returning in a fraction of a second did
104+not re-analyse anything. That failure mode **under-reports**: the low number is the
105+wrong one, so it looks like an improvement.
106+
107+When you suspect it, clear that linter's cache and run its binary directly, several
108+times, until the result is stable; `.qlty/out/invoke-*.yaml` records the exact command,
109+environment and duration qlty used. Work from that figure, not from the report, and say
110+in your report which number you trust and why. Remember too that **a gate threshold
111+pinned to an unstable measurement will trip on its own** — give it margin, and write
112+down that the margin is the tool's fault, so it gets removed rather than inherited.
113+
114+So before picking a target, check **how many distinct rules and how many distinct files**
115+a count spans:
116+
117+```bash
118+# qlty check has no --json; SARIF is the machine-readable form
119+qlty check --all --no-fix --no-upgrade-check --sarif > /tmp/qlty.sarif
120+```
121+
122+Then group the results by `ruleId` and by file URI. A rule spanning many files with one
123+occurrence each, or many rules spanning the same short file list, means the count is
124+telling you about the *shape of the scan*, not the state of the code. Say so in your
125+report — a total nobody can interpret gets ignored, and then a real regression hides in
126+it.
127+
128+## 4. Refactor until the gate passes
129+
130+If the gate failed, refactor. Loop:
131+
132+1. Pick the largest cluster of violations from the report (one rule, or one file).
133+2. Fix formatting mechanically first — `qlty fmt` handles it, and it clears a lot of
134+ noise cheaply:
135+ ```bash
136+ qlty fmt --all --no-upgrade-check
137+ ```
138+3. Fix the remaining issues by editing the code. For smells, prefer extracting a
139+ function or collapsing a duplicated block over suppressing the finding.
140+4. Verify nothing broke, using **this project's own** build and test commands. The
141+ repository's tooling is the authority on what those are — check for a `Makefile`,
142+ `Taskfile.yml`, `package.json` scripts, `pyproject.toml`, or the CI workflow before
143+ assuming. Common cases:
144+
145+ | Stack | Verification |
146+ | --- | --- |
147+ | Go | `go build ./... && go test ./...` |
148+ | Go targeting WebAssembly | also `tinygo build -target=wasip1 ./...` — TinyGo rejects some constructs the standard toolchain accepts, so a passing `go build` is not sufficient |
149+ | Node / TypeScript | `npm test` (or the script the project defines), plus `tsc --noEmit` if the project is typed |
150+ | Python | `pytest` |
151+ | Rust | `cargo build && cargo test && cargo clippy -- -D warnings` |
152+ | Rust targeting WebAssembly | also `cargo build --target wasm32-wasip2` — and note the asymmetry below |
153+ | VS Code extension | the compile script, then `vsce package` — packaging validates the manifest, which `tsc` does not |
154+ | Zed extension | `cargo build --release --target wasm32-wasip2` |
155+
156+ If the project has no tests, say so in the report rather than letting a green build
157+ stand in as proof the refactoring was safe.
158+
159+ **Two traps specific to WebAssembly targets.** Both let a refactoring look verified
160+ when it is not:
161+
162+ - A **wasm build passing does not mean the tests ran.** `cargo build --target
163+ wasm32-wasip2` links with rustc's own bundled `rust-lld`, so it succeeds even
164+ with no C toolchain present, while `cargo test` — which builds for the *host* —
165+ fails at link time with ``error: linker `cc` not found``. If you see that error,
166+ the tests did not run; do not report the wasm build as verification.
167+ - An **extension cannot be exercised here.** No editor runs in this sandbox, so
168+ neither VS Code's Extension Development Host nor Zed's *Install Dev Extension*
169+ is available, and `@vscode/test-electron` needs an X server this kit does not
170+ install. Compile, unit-test and package — then say plainly that the integration
171+ path is untested rather than implying it passed.
172+5. Re-run the measurement from step 2 and compare against the previous run.
173+
174+Stop when any of these is true:
175+
176+- **The gate passes.** Report the before/after numbers from the Trend table.
177+- **Five iterations have run.** Stop and report honestly: what improved, what remains,
178+ and why the rest is hard.
179+- **Two consecutive runs show no improvement.** You are stuck — stop and explain what
180+ the blocker is rather than churning the code.
181+
182+Commit as you go, one focused commit per cluster of fixes, so the progression is
183+visible in git as well as in `.quality/history.jsonl`.
184+
185+## Do not game the gate
186+
187+The gate is only worth something if it is measuring the code. All of the following make
188+the number go down while making the project worse — never do them, even if the gate is
189+the only thing standing between you and "done":
190+
191+- Adding `exclude_patterns`, disabling a plugin, setting a plugin to `mode = "monitor"`,
192+ or raising a threshold in `.qlty/qlty.toml`.
193+- Loosening `.quality/gate.json`.
194+- Deleting, skipping, or emptying tests.
195+- Adding blanket lint suppressions (`//nolint`, `// qlty-ignore`) to silence a finding
196+ you could fix.
197+
198+A narrowly-scoped suppression with a comment explaining why the finding is a false
199+positive is legitimate. If you believe a threshold is genuinely wrong for this project,
200+say so and let the user decide — do not change it yourself.
201+
202+### The one plugin you may remove: a broken one
203+
204+"Disabling a plugin" above means a plugin that *finds things you would rather not fix*. A
205+plugin that **analyses nothing** is a different object, and keeping it is not rigour: its
206+findings crowd out the ones that matter and make the total unreadable.
207+
208+The two are indistinguishable from the report alone, so removal requires a **reproducible
209+diagnosis**, never an impression. Establish all four of these before touching the config:
210+
211+1. **It is not the language version or a specific construct.** Put a trivially small,
212+ unambiguously valid file of that language in a *fresh* git repository, enable only
213+ that plugin, and run it. If a five-line hello-world fails, no source construct is to
214+ blame.
215+2. **It is not this project.** Same point — the probe repository shares nothing with the
216+ codebase under measurement.
217+3. **It is not the environment qlty gives plugins.** qlty runs plugins with a stripped
218+ environment (empty `PATH` and `HOME`). Run the plugin's own binary directly, with your
219+ full environment, on the same probe file. Read the invocation qlty used from
220+ `.qlty/out/invoke-*.yaml`, which records the exact `script`, `env` and `stderr`.
221+4. **It is not the plugin family.** If sibling plugins sharing the same runtime produce
222+ real findings, the failure is specific rather than environmental.
223+
224+If all four hold, remove the plugin — and **write the diagnosis as a comment where you
225+removed it**, so the next session finds the evidence instead of re-adding it on instinct.
226+Note in your report which other tooling still covers that ground; if nothing does, the
227+answer is to replace the plugin, not merely to drop it.
228+
229+`mode = "monitor"` is *not* the remedy here. It does not stop a plugin's findings from
230+counting; it only changes how they are surfaced. A broken plugin left in monitor mode
231+keeps polluting the total, which is how one ends up unnoticed for months.
232+
233+**Do not encode "plugin X is broken" into this skill.** Such a failure belongs to one
234+version, one platform and one moment; a list of known-bad plugins ages badly and, worse,
235+tempts the next agent to skip the diagnosis. The method above is what belongs here — its
236+results belong in the project's own config and notes.
237+
238+## Tuning the gate
239+
240+Defaults are strict: zero error-level issues, zero warning-level issues, zero smells.
241+Override any subset by writing `.quality/gate.json`:
242+
243+```json
244+{
245+ "max_error": 0,
246+ "max_warning": 0,
247+ "max_note": null,
248+ "max_smells": 0,
249+ "max_file_complexity": 60,
250+ "max_total_complexity": null
251+}
252+```
253+
254+`null` disables a check. `max_file_complexity` flags individual files whose `complex`
255+metric exceeds the limit, which is the most useful knob for a codebase with existing
256+debt: it lets you hold the line on the worst files without demanding a perfect score
257+everywhere at once.
258+
259+## Reference
260+
261+- `qlty check --help`, `qlty smells --help`, `qlty metrics --help` for the full flag set.
262+- Note `qlty check` has **no** `--json`; machine-readable output is `--sarif`.
263+- Pass `--no-upgrade-check` to every qlty command — the sandbox blocks its update host.
264+- Reports and history under `.quality/` are meant to be committed so progression
265+ survives sandbox recreation. Add `.quality/` to `.gitignore` if the user prefers them
266+ to stay local.
new file mode 100644
@@ -0,0 +1,266 @@
1+---
2+name: quality
3+description: Audit and improve this project's code quality with qlty. Sets qlty up on first use, measures lint issues / code smells / complexity, writes a timestamped Markdown report under .quality/, tracks progression across runs, and refactors until the quality gate passes. Use when asked to check code quality, run a quality report, review technical debt, see whether quality is improving, or clean up / refactor the codebase.
4+---
5+
6+# Quality
7+
8+Measure this project's code quality with [qlty](https://docs.qlty.sh), report it, and
9+refactor until the gate passes.
10+
11+The measurement is a script, not a judgement call — run it, then act on what it says.
12+It is read-only with respect to the source tree (`qlty check` runs with `--no-fix`), so
13+measuring never quietly rewrites the code you are about to reason about.
14+
15+## 1. Set up (only if needed)
16+
17+The setup is self-healing; just run the script. It verifies `qlty` is on `PATH`, that
18+the workspace is a git repository, and runs `qlty init --yes` when there is no
19+`.qlty/qlty.toml` yet.
20+
21+If `qlty` is missing entirely, the sandbox was not created with the `dev-toolkit`
22+kit. Say so and stop — do not install qlty by hand.
23+
24+**If the project vendors this kit** — a `kits/` directory holding the sources that get
25+installed into `~/.claude/` — add it to `exclude_patterns` in `.qlty/qlty.toml` on the
26+first run:
27+
28+```toml
29+exclude_patterns = [
30+ # … the defaults qlty init wrote …
31+ "kits/**", # the kit's own sources, including this skill's quality_report.py
32+]
33+```
34+
35+This is **not** an exception to "do not game the gate" below. The reason is narrower and
36+holds regardless of what the numbers say: `quality_report.py` is the script that
37+*produces* the measurement, so leaving it in scope means measuring the instrument with
38+itself. Two of its findings are structurally unfixable — a script whose job is to run
39+`qlty` must import and call `subprocess`, which every Python security linter flags.
40+
41+Two conditions make this legitimate rather than convenient, and both must hold:
42+
43+- **It is the project's decision, not yours.** Say what the exclusion hides and why, and
44+ let the user choose. Adding it unilaterally is the forbidden move.
45+- **Write down what it hides.** Put the actual findings in a comment next to the pattern.
46+ Some of them are usually real defects in the script — over-complex functions, unused
47+ imports — and they should be fixed at the kit's source rather than forgotten. An
48+ exclusion that records what it silences stays honest; one that just makes a number
49+ drop is the start of the drift.
50+
51+## 2. Measure
52+
53+From the project root:
54+
55+```bash
56+python3 ~/.claude/skills/quality/scripts/quality_report.py --workspace .
57+```
58+
59+On a cold cache the first run takes several minutes: qlty downloads its plugin
60+definitions and the linter binaries. Subsequent runs are fast (the cache lives on a
61+persistent volume at `~/.qlty`).
62+
63+The script:
64+
65+- runs `qlty check --all`, `qlty smells --all`, and `qlty metrics --all`
66+- writes `.quality/report-<timestamp>.md` and `.quality/report-latest.md`
67+- appends one JSON line to `.quality/history.jsonl`
68+- prints the report to stdout
69+- **exits `0` if the gate passed, `1` if it failed, `2` on a tooling error**
70+
71+Use the exit code as the loop condition. Do not re-derive the verdict yourself.
72+
73+## 3. Read the report
74+
75+The report contains:
76+
77+| Section | What to do with it |
78+| --- | --- |
79+| **Gate violations** | The work list. Each line is a threshold that was breached. |
80+| **Lint issues** by level, top rules, most affected files | Where to start — but read the count correctly first, see below. |
81+| **Code smells** | Duplication and over-complex structure — these need real refactoring, not a formatter. |
82+| **Metrics** | `complex` / `cyclo` per file; the "Most complex files" table names refactoring targets. |
83+| **Trend** | Last 10 runs. This is how you show progression. |
84+| **Tooling notes** | Present only when a qlty invocation failed — investigate before trusting the numbers. |
85+
86+### Read the count before you trust it
87+
88+"Fix the highest-count rule first" is the right instinct and the wrong first step. A
89+count is `occurrences`, not `distinct problems`, and the two diverge badly in two common
90+cases:
91+
92+- **One finding, repeated per manifest.** `osv-scanner` reports a dependency CVE once per
93+ `go.mod` / `package.json` it appears in. A monorepo with a dozen manifests turns one
94+ vulnerable version into a hundred-plus findings, and adding a three-line example
95+ manifest multiplies the total without degrading anything.
96+- **One finding, repeated per file.** A linter that fails to parse the language emits one
97+ finding per source file. That looks like the largest cluster in the report and is worth
98+ exactly nothing.
99+
100+And before treating a *delta* as a regression: **re-run.** A count that moves while the
101+tree is untouched is measuring the tool, not the code. The usual cause is a linter
102+answering from its own partially-populated cache — qlty invokes several with
103+`--allow-parallel-runners`, and an invocation returning in a fraction of a second did
104+not re-analyse anything. That failure mode **under-reports**: the low number is the
105+wrong one, so it looks like an improvement.
106+
107+When you suspect it, clear that linter's cache and run its binary directly, several
108+times, until the result is stable; `.qlty/out/invoke-*.yaml` records the exact command,
109+environment and duration qlty used. Work from that figure, not from the report, and say
110+in your report which number you trust and why. Remember too that **a gate threshold
111+pinned to an unstable measurement will trip on its own** — give it margin, and write
112+down that the margin is the tool's fault, so it gets removed rather than inherited.
113+
114+So before picking a target, check **how many distinct rules and how many distinct files**
115+a count spans:
116+
117+```bash
118+# qlty check has no --json; SARIF is the machine-readable form
119+qlty check --all --no-fix --no-upgrade-check --sarif > /tmp/qlty.sarif
120+```
121+
122+Then group the results by `ruleId` and by file URI. A rule spanning many files with one
123+occurrence each, or many rules spanning the same short file list, means the count is
124+telling you about the *shape of the scan*, not the state of the code. Say so in your
125+report — a total nobody can interpret gets ignored, and then a real regression hides in
126+it.
127+
128+## 4. Refactor until the gate passes
129+
130+If the gate failed, refactor. Loop:
131+
132+1. Pick the largest cluster of violations from the report (one rule, or one file).
133+2. Fix formatting mechanically first — `qlty fmt` handles it, and it clears a lot of
134+ noise cheaply:
135+ ```bash
136+ qlty fmt --all --no-upgrade-check
137+ ```
138+3. Fix the remaining issues by editing the code. For smells, prefer extracting a
139+ function or collapsing a duplicated block over suppressing the finding.
140+4. Verify nothing broke, using **this project's own** build and test commands. The
141+ repository's tooling is the authority on what those are — check for a `Makefile`,
142+ `Taskfile.yml`, `package.json` scripts, `pyproject.toml`, or the CI workflow before
143+ assuming. Common cases:
144+
145+ | Stack | Verification |
146+ | --- | --- |
147+ | Go | `go build ./... && go test ./...` |
148+ | Go targeting WebAssembly | also `tinygo build -target=wasip1 ./...` — TinyGo rejects some constructs the standard toolchain accepts, so a passing `go build` is not sufficient |
149+ | Node / TypeScript | `npm test` (or the script the project defines), plus `tsc --noEmit` if the project is typed |
150+ | Python | `pytest` |
151+ | Rust | `cargo build && cargo test && cargo clippy -- -D warnings` |
152+ | Rust targeting WebAssembly | also `cargo build --target wasm32-wasip2` — and note the asymmetry below |
153+ | VS Code extension | the compile script, then `vsce package` — packaging validates the manifest, which `tsc` does not |
154+ | Zed extension | `cargo build --release --target wasm32-wasip2` |
155+
156+ If the project has no tests, say so in the report rather than letting a green build
157+ stand in as proof the refactoring was safe.
158+
159+ **Two traps specific to WebAssembly targets.** Both let a refactoring look verified
160+ when it is not:
161+
162+ - A **wasm build passing does not mean the tests ran.** `cargo build --target
163+ wasm32-wasip2` links with rustc's own bundled `rust-lld`, so it succeeds even
164+ with no C toolchain present, while `cargo test` — which builds for the *host* —
165+ fails at link time with ``error: linker `cc` not found``. If you see that error,
166+ the tests did not run; do not report the wasm build as verification.
167+ - An **extension cannot be exercised here.** No editor runs in this sandbox, so
168+ neither VS Code's Extension Development Host nor Zed's *Install Dev Extension*
169+ is available, and `@vscode/test-electron` needs an X server this kit does not
170+ install. Compile, unit-test and package — then say plainly that the integration
171+ path is untested rather than implying it passed.
172+5. Re-run the measurement from step 2 and compare against the previous run.
173+
174+Stop when any of these is true:
175+
176+- **The gate passes.** Report the before/after numbers from the Trend table.
177+- **Five iterations have run.** Stop and report honestly: what improved, what remains,
178+ and why the rest is hard.
179+- **Two consecutive runs show no improvement.** You are stuck — stop and explain what
180+ the blocker is rather than churning the code.
181+
182+Commit as you go, one focused commit per cluster of fixes, so the progression is
183+visible in git as well as in `.quality/history.jsonl`.
184+
185+## Do not game the gate
186+
187+The gate is only worth something if it is measuring the code. All of the following make
188+the number go down while making the project worse — never do them, even if the gate is
189+the only thing standing between you and "done":
190+
191+- Adding `exclude_patterns`, disabling a plugin, setting a plugin to `mode = "monitor"`,
192+ or raising a threshold in `.qlty/qlty.toml`.
193+- Loosening `.quality/gate.json`.
194+- Deleting, skipping, or emptying tests.
195+- Adding blanket lint suppressions (`//nolint`, `// qlty-ignore`) to silence a finding
196+ you could fix.
197+
198+A narrowly-scoped suppression with a comment explaining why the finding is a false
199+positive is legitimate. If you believe a threshold is genuinely wrong for this project,
200+say so and let the user decide — do not change it yourself.
201+
202+### The one plugin you may remove: a broken one
203+
204+"Disabling a plugin" above means a plugin that *finds things you would rather not fix*. A
205+plugin that **analyses nothing** is a different object, and keeping it is not rigour: its
206+findings crowd out the ones that matter and make the total unreadable.
207+
208+The two are indistinguishable from the report alone, so removal requires a **reproducible
209+diagnosis**, never an impression. Establish all four of these before touching the config:
210+
211+1. **It is not the language version or a specific construct.** Put a trivially small,
212+ unambiguously valid file of that language in a *fresh* git repository, enable only
213+ that plugin, and run it. If a five-line hello-world fails, no source construct is to
214+ blame.
215+2. **It is not this project.** Same point — the probe repository shares nothing with the
216+ codebase under measurement.
217+3. **It is not the environment qlty gives plugins.** qlty runs plugins with a stripped
218+ environment (empty `PATH` and `HOME`). Run the plugin's own binary directly, with your
219+ full environment, on the same probe file. Read the invocation qlty used from
220+ `.qlty/out/invoke-*.yaml`, which records the exact `script`, `env` and `stderr`.
221+4. **It is not the plugin family.** If sibling plugins sharing the same runtime produce
222+ real findings, the failure is specific rather than environmental.
223+
224+If all four hold, remove the plugin — and **write the diagnosis as a comment where you
225+removed it**, so the next session finds the evidence instead of re-adding it on instinct.
226+Note in your report which other tooling still covers that ground; if nothing does, the
227+answer is to replace the plugin, not merely to drop it.
228+
229+`mode = "monitor"` is *not* the remedy here. It does not stop a plugin's findings from
230+counting; it only changes how they are surfaced. A broken plugin left in monitor mode
231+keeps polluting the total, which is how one ends up unnoticed for months.
232+
233+**Do not encode "plugin X is broken" into this skill.** Such a failure belongs to one
234+version, one platform and one moment; a list of known-bad plugins ages badly and, worse,
235+tempts the next agent to skip the diagnosis. The method above is what belongs here — its
236+results belong in the project's own config and notes.
237+
238+## Tuning the gate
239+
240+Defaults are strict: zero error-level issues, zero warning-level issues, zero smells.
241+Override any subset by writing `.quality/gate.json`:
242+
243+```json
244+{
245+ "max_error": 0,
246+ "max_warning": 0,
247+ "max_note": null,
248+ "max_smells": 0,
249+ "max_file_complexity": 60,
250+ "max_total_complexity": null
251+}
252+```
253+
254+`null` disables a check. `max_file_complexity` flags individual files whose `complex`
255+metric exceeds the limit, which is the most useful knob for a codebase with existing
256+debt: it lets you hold the line on the worst files without demanding a perfect score
257+everywhere at once.
258+
259+## Reference
260+
261+- `qlty check --help`, `qlty smells --help`, `qlty metrics --help` for the full flag set.
262+- Note `qlty check` has **no** `--json`; machine-readable output is `--sarif`.
263+- Pass `--no-upgrade-check` to every qlty command — the sandbox blocks its update host.
264+- Reports and history under `.quality/` are meant to be committed so progression
265+ survives sandbox recreation. Add `.quality/` to `.gitignore` if the user prefers them
266+ to stay local.
added .vibe/skills/quality/scripts/quality_report.py +463 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified agent.dmr.yaml +4 -0
@@ -27,6 +27,10 @@ bashTool: true
2727 # The built-in file tools: read_file, write_file, edit_file.
2828 editTools: true
2929
30+# The built-in plan tool for managing multi-step plans.
31+# Set to false to disable plan creation and tracking via the `plan` tool.
32+planTool: true
33+
3034 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
3135 # The file extension picks the server. A server missing from the PATH is skipped with a warning.
3236 # No server listed = no `lsp` tool. Examples (uncomment what you have installed):
@@ -27,6 +27,10 @@ bashTool: true
27 # The built-in file tools: read_file, write_file, edit_file. 27 # The built-in file tools: read_file, write_file, edit_file.
28 editTools: true28 editTools: true
29 29
30+# The built-in plan tool for managing multi-step plans.
31+# Set to false to disable plan creation and tracking via the `plan` tool.
32+planTool: true
33+
30 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).34 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
31 # The file extension picks the server. A server missing from the PATH is skipped with a warning.35 # The file extension picks the server. A server missing from the PATH is skipped with a warning.
32 # No server listed = no `lsp` tool. Examples (uncomment what you have installed):36 # No server listed = no `lsp` tool. Examples (uncomment what you have installed):
modified agent.llamacpp.yaml +4 -0
@@ -23,6 +23,10 @@ bashTool: true
2323 # The built-in file tools: read_file, write_file, edit_file.
2424 editTools: true
2525
26+# The built-in plan tool for managing multi-step plans.
27+# Set to false to disable plan creation and tracking via the `plan` tool.
28+planTool: true
29+
2630 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
2731 # The file extension picks the server. A server missing from the PATH is skipped with a warning.
2832 # No server listed = no `lsp` tool. Examples (uncomment what you have installed):
@@ -23,6 +23,10 @@ bashTool: true
23 # The built-in file tools: read_file, write_file, edit_file. 23 # The built-in file tools: read_file, write_file, edit_file.
24 editTools: true24 editTools: true
25 25
26+# The built-in plan tool for managing multi-step plans.
27+# Set to false to disable plan creation and tracking via the `plan` tool.
28+planTool: true
29+
26 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).30 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
27 # The file extension picks the server. A server missing from the PATH is skipped with a warning.31 # The file extension picks the server. A server missing from the PATH is skipped with a warning.
28 # No server listed = no `lsp` tool. Examples (uncomment what you have installed):32 # No server listed = no `lsp` tool. Examples (uncomment what you have installed):
modified agent.lsp.yaml +4 -0
@@ -34,6 +34,10 @@ bashTool: true
3434 # The built-in file tools: read_file, write_file, edit_file.
3535 editTools: true
3636
37+# The built-in plan tool for managing multi-step plans.
38+# Set to false to disable plan creation and tracking via the `plan` tool.
39+planTool: true
40+
3741 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
3842 # The file extension picks the server. A server missing from the PATH is skipped with a warning at start-up;
3943 # with no server on the PATH the tool is not declared. Install what you use, uncomment its entry.
@@ -34,6 +34,10 @@ bashTool: true
34 # The built-in file tools: read_file, write_file, edit_file. 34 # The built-in file tools: read_file, write_file, edit_file.
35 editTools: true35 editTools: true
36 36
37+# The built-in plan tool for managing multi-step plans.
38+# Set to false to disable plan creation and tracking via the `plan` tool.
39+planTool: true
40+
37 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).41 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
38 # The file extension picks the server. A server missing from the PATH is skipped with a warning at start-up;42 # The file extension picks the server. A server missing from the PATH is skipped with a warning at start-up;
39 # with no server on the PATH the tool is not declared. Install what you use, uncomment its entry.43 # with no server on the PATH the tool is not declared. Install what you use, uncomment its entry.
added demo/README.md +9 -0
new file mode 100644
@@ -0,0 +1,9 @@
1+# Mini Me Project
2+
3+## What is Mini Me?
4+
5+[Insert a detailed explanation of what Mini Me is here.]
6+
7+## License
8+
9+This project is licensed under the WTF License.
new file mode 100644
@@ -0,0 +1,9 @@
1+# Mini Me Project
2+
3+## What is Mini Me?
4+
5+[Insert a detailed explanation of what Mini Me is here.]
6+
7+## License
8+
9+This project is licensed under the WTF License.
modified demo/agent.dmr.2.yaml +4 -0
@@ -29,6 +29,10 @@ bashTool: true
2929 # The built-in file tools: read_file, write_file, edit_file.
3030 editTools: true
3131
32+# The built-in plan tool for managing multi-step plans.
33+# Set to false to disable plan creation and tracking via the `plan` tool.
34+planTool: true
35+
3236 lsp:
3337 servers:
3438 - name: gopls # go install golang.org/x/tools/gopls@latest
@@ -29,6 +29,10 @@ bashTool: true
29 # The built-in file tools: read_file, write_file, edit_file. 29 # The built-in file tools: read_file, write_file, edit_file.
30 editTools: true30 editTools: true
31 31
32+# The built-in plan tool for managing multi-step plans.
33+# Set to false to disable plan creation and tracking via the `plan` tool.
34+planTool: true
35+
32 lsp:36 lsp:
33 servers:37 servers:
34 - name: gopls # go install golang.org/x/tools/gopls@latest38 - name: gopls # go install golang.org/x/tools/gopls@latest
modified demo/agent.dmr.yaml +4 -0
@@ -29,6 +29,10 @@ bashTool: true
2929 # The built-in file tools: read_file, write_file, edit_file.
3030 editTools: true
3131
32+# The built-in plan tool for managing multi-step plans.
33+# Set to false to disable plan creation and tracking via the `plan` tool.
34+planTool: true
35+
3236 lsp:
3337 servers:
3438 - name: gopls # go install golang.org/x/tools/gopls@latest
@@ -29,6 +29,10 @@ bashTool: true
29 # The built-in file tools: read_file, write_file, edit_file. 29 # The built-in file tools: read_file, write_file, edit_file.
30 editTools: true30 editTools: true
31 31
32+# The built-in plan tool for managing multi-step plans.
33+# Set to false to disable plan creation and tracking via the `plan` tool.
34+planTool: true
35+
32 lsp:36 lsp:
33 servers:37 servers:
34 - name: gopls # go install golang.org/x/tools/gopls@latest38 - name: gopls # go install golang.org/x/tools/gopls@latest
modified demo/agent.lsp.yaml +4 -0
@@ -39,6 +39,10 @@ bashTool: true
3939 # The built-in file tools: read_file, write_file, edit_file.
4040 editTools: true
4141
42+# The built-in plan tool for managing multi-step plans.
43+# Set to false to disable plan creation and tracking via the `plan` tool.
44+planTool: true
45+
4246 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
4347 # The file extension picks the server. A server missing from the PATH is skipped with a warning at start-up;
4448 # with no server on the PATH the tool is not declared. Install what you use, uncomment its entry.
@@ -39,6 +39,10 @@ bashTool: true
39 # The built-in file tools: read_file, write_file, edit_file. 39 # The built-in file tools: read_file, write_file, edit_file.
40 editTools: true40 editTools: true
41 41
42+# The built-in plan tool for managing multi-step plans.
43+# Set to false to disable plan creation and tracking via the `plan` tool.
44+planTool: true
45+
42 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).46 # Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
43 # The file extension picks the server. A server missing from the PATH is skipped with a warning at start-up;47 # The file extension picks the server. A server missing from the PATH is skipped with a warning at start-up;
44 # with no server on the PATH the tool is not declared. Install what you use, uncomment its entry.48 # with no server on the PATH the tool is not declared. Install what you use, uncomment its entry.
added docs/en/how-to/manage-plans-and-tasks.md +440 -0
Large diff collapsed to keep the page fast — load it when you need it.
added docs/fr/how-to/manage-plans-and-tasks.md +440 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/agent/agent.go +3 -0
@@ -21,6 +21,7 @@ import (
2121 "mm/internal/skills"
2222 "mm/internal/spinner"
2323 "mm/internal/store"
24+ "mm/internal/tools"
2425
2526 "github.com/firebase/genkit/go/ai"
2627 )
@@ -443,6 +444,8 @@ func startNewSession(e *engine.Engine, d *detector.LoopDetector, system string,
443444 forgotten := session.Forgotten(old)
444445 e.ForgetInputTokens()
445446 d.Reset()
447+ // Clear any active plans when starting a new session
448+ tools.ClearAllPlans()
446449 dimln(fmt.Sprintf("🆕 new session: %d message(s) forgotten", forgotten))
447450 return session.Fresh(system)
448451 }
@@ -21,6 +21,7 @@ import (
21 "mm/internal/skills"21 "mm/internal/skills"
22 "mm/internal/spinner"22 "mm/internal/spinner"
23 "mm/internal/store"23 "mm/internal/store"
24+ "mm/internal/tools"
24 25
25 "github.com/firebase/genkit/go/ai"26 "github.com/firebase/genkit/go/ai"
26 )27 )
@@ -443,6 +444,8 @@ func startNewSession(e *engine.Engine, d *detector.LoopDetector, system string,
443 forgotten := session.Forgotten(old)444 forgotten := session.Forgotten(old)
444 e.ForgetInputTokens()445 e.ForgetInputTokens()
445 d.Reset()446 d.Reset()
447+ // Clear any active plans when starting a new session
448+ tools.ClearAllPlans()
446 dimln(fmt.Sprintf("🆕 new session: %d message(s) forgotten", forgotten))449 dimln(fmt.Sprintf("🆕 new session: %d message(s) forgotten", forgotten))
447 return session.Fresh(system)450 return session.Fresh(system)
448 }451 }
modified internal/config/config.go +5 -0
@@ -96,6 +96,10 @@ type Config struct {
9696 // One binary, two set-ups: that is what lets the two be compared.
9797 EditTools bool `yaml:"editTools"`
9898
99+ // PlanTool: declare the built-in plan tool for managing multi-step plans.
100+ // On by default. Off to disable plan creation and tracking via the `plan` tool.
101+ PlanTool bool `yaml:"planTool"`
102+
99103 // Sampling: generation settings (OpenAI API keys; the plugin converts them.)
100104 Sampling map[string]any `yaml:"sampling"`
101105
@@ -251,6 +255,7 @@ var Cfg = Config{
251255 SkillsDir: "skills",
252256 BashTool: true,
253257 EditTools: true,
258+ PlanTool: true,
254259 System: `You are a coding agent working in a terminal.
255260 You have a "bash" tool to run shell commands.
256261 Use it to explore files, run tests, inspect the repository, etc.
@@ -96,6 +96,10 @@ type Config struct {
96 // One binary, two set-ups: that is what lets the two be compared.96 // One binary, two set-ups: that is what lets the two be compared.
97 EditTools bool `yaml:"editTools"`97 EditTools bool `yaml:"editTools"`
98 98
99+ // PlanTool: declare the built-in plan tool for managing multi-step plans.
100+ // On by default. Off to disable plan creation and tracking via the `plan` tool.
101+ PlanTool bool `yaml:"planTool"`
102+
99 // Sampling: generation settings (OpenAI API keys; the plugin converts them.)103 // Sampling: generation settings (OpenAI API keys; the plugin converts them.)
100 Sampling map[string]any `yaml:"sampling"`104 Sampling map[string]any `yaml:"sampling"`
101 105
@@ -251,6 +255,7 @@ var Cfg = Config{
251 SkillsDir: "skills",255 SkillsDir: "skills",
252 BashTool: true,256 BashTool: true,
253 EditTools: true,257 EditTools: true,
258+ PlanTool: true,
254 System: `You are a coding agent working in a terminal.259 System: `You are a coding agent working in a terminal.
255 You have a "bash" tool to run shell commands.260 You have a "bash" tool to run shell commands.
256 Use it to explore files, run tests, inspect the repository, etc.261 Use it to explore files, run tests, inspect the repository, etc.
added internal/tools/plan.go +694 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/tools/plan_test.go +542 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified main.go +4 -0
@@ -233,6 +233,10 @@ func assembleTools(e *engine.Engine, d *detector.LoopDetector) toolSet {
233233 tools.EditFile(e.G, d))
234234 set.names = append(set.names, "read_file", "write_file", "edit_file")
235235 }
236+ if config.Cfg.PlanTool {
237+ set.tools = append(set.tools, tools.PlanTool(e.G, d))
238+ set.names = append(set.names, "plan")
239+ }
236240 assembleLSP(e, d, &set)
237241 return set
238242 }
@@ -233,6 +233,10 @@ func assembleTools(e *engine.Engine, d *detector.LoopDetector) toolSet {
233 tools.EditFile(e.G, d))233 tools.EditFile(e.G, d))
234 set.names = append(set.names, "read_file", "write_file", "edit_file")234 set.names = append(set.names, "read_file", "write_file", "edit_file")
235 }235 }
236+ if config.Cfg.PlanTool {
237+ set.tools = append(set.tools, tools.PlanTool(e.G, d))
238+ set.names = append(set.names, "plan")
239+ }
236 assembleLSP(e, d, &set)240 assembleLSP(e, d, &set)
237 return set241 return set
238 }242 }
added skills/plan-manager/SKILL.md +472 -0
Large diff collapsed to keep the page fast — load it when you need it.