@iceinvein/agent-skills 0.1.20 → 0.1.21

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 CHANGED
@@ -96,6 +96,14 @@ Skills for producing job application materials that read like a human wrote them
96
96
  |-------|------|--------------|
97
97
  | **code-intelligence** | MCP server | Semantic code search, call hierarchy, dependency graphs, and impact analysis. Powered by `@iceinvein/code-intelligence-mcp`. |
98
98
 
99
+ ### Orchestration
100
+
101
+ Skills that compose the other audit skills into higher-level workflows.
102
+
103
+ | Skill | What it does |
104
+ |-------|--------------|
105
+ | **improve-my-codebase** | Runs every applicable audit skill in parallel against your codebase, ranks findings by convergence (multiple audits agreeing) and per-file rollup, and writes a prioritized improvement report. Default sweeps everything; positional args switch modes (`quick`, `diff`, `interactive`) or narrow scope (`focus <area>`, `module <path>`). |
106
+
99
107
  ## Commands
100
108
 
101
109
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iceinvein/agent-skills",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Install agent skills into AI coding tools",
5
5
  "author": "iceinvein",
6
6
  "license": "MIT",
@@ -0,0 +1,26 @@
1
+ # Catalogue fields for improve-my-codebase
2
+
3
+ The `improve-my-codebase` orchestrator reads `skills/index.json` and routes audits based on two fields:
4
+
5
+ ## `applies: string[]`
6
+
7
+ Areas a skill is relevant to. The orchestrator runs an audit only when at least one of its `applies` values matches a detected stack signal (or `any`).
8
+
9
+ | Value | Meaning | Detection signal |
10
+ |-------|---------|------------------|
11
+ | `any` | Always applicable | Always matches |
12
+ | `ui` | Requires UI surface | `.tsx`/`.jsx`/`.vue`/`.svelte`/`.html`/`.css` files, or `react`/`vue`/`svelte`/`solid` in `package.json` deps |
13
+ | `domain` | Requires domain layer | Directory named `domain/`, `entities/`, `aggregates/`, or domain-driven naming |
14
+ | `integration` | Requires messaging/events | Directory named `events/`, `messaging/`, `queues/`, or deps `kafkajs`/`amqplib`/`bullmq` |
15
+ | `architecture` | Cross-cutting structural | Always matches in projects with > 5 files |
16
+ | `errors` | Error handling concerns | Always matches in any non-trivial codebase |
17
+ | `legacy` | Modifying existing code | Only fires when invoked with `diff` mode |
18
+
19
+ ## `quick: boolean`
20
+
21
+ Whether the audit qualifies for the `quick` mode. Quick audits should:
22
+ - Be primarily structural or static (file structure, imports, naming).
23
+ - Avoid deep semantic reasoning over function bodies.
24
+ - Return findings within roughly 60 seconds on a medium repo.
25
+
26
+ If unsure, mark `quick: false`. Better to miss in quick mode than to blow the latency budget.
@@ -0,0 +1,516 @@
1
+ ---
2
+ name: improve-my-codebase
3
+ description: Use when the user wants a prioritized improvement report across an entire codebase or a scoped subset. Orchestrates the existing audit skills (Parnas, Ousterhout, Hickey, Martin, Evans, Rams, etc.) in parallel and produces a ranked, per-file report. Trigger on "/improve-my-codebase", "audit my codebase", "what should I improve", "review the whole repo", or scoped variants.
4
+ ---
5
+
6
+ # Improve My Codebase
7
+
8
+ A meta-orchestrator that runs the existing audit skills in this package across a codebase, then synthesizes their findings into a single prioritized report. Default invocation runs a full sweep; positional args switch modes (quick, diff, interactive) or narrow scope (focus area, module path).
9
+
10
+ **Core principle:** every issue surfaced should be one a senior engineer would agree is worth a developer's attention. Convergent findings (multiple audits flagging the same file or symbol) rank above single-axis findings, because independent perspectives agreeing is the strongest signal of real problems.
11
+
12
+ ## When to Use
13
+
14
+ - A user types `/improve-my-codebase` or asks for a codebase-wide audit.
15
+ - A user wants to know what's worth improving in a repo before planning work.
16
+ - A user wants a scoped audit of changed files (`diff` mode) or a single module (`module <path>`).
17
+
18
+ **Not for:**
19
+ - Reviewing a single function or short snippet. Invoke the relevant single-axis audit directly.
20
+ - Auto-applying fixes. This skill emits a report only.
21
+ - Replacing the individual audit skills. They remain the source of truth and are dispatched here, not duplicated.
22
+
23
+ ## Invocation
24
+
25
+ ```
26
+ /improve-my-codebase # full sweep
27
+ /improve-my-codebase quick # fast subset, top 5 issues
28
+ /improve-my-codebase diff # only changed files vs. main
29
+ /improve-my-codebase interactive # interview-driven
30
+ /improve-my-codebase focus <area> # narrow to one axis
31
+ /improve-my-codebase module <path> # scope to a directory or file
32
+ /improve-my-codebase diff focus <area> # composition
33
+ /improve-my-codebase module <path> focus <area>
34
+ ```
35
+
36
+ Argument rules:
37
+ - Positional. No leading `--`.
38
+ - Modes: `quick`, `diff`, `interactive`. First match wins; mutually exclusive.
39
+ - Scope filters: `focus <area>`, `module <path>`. Compose freely with each other and with default/diff modes.
40
+ - `quick` and `interactive` ignore scope tokens (warn, do not error).
41
+ - Unknown tokens: warn and drop, do not abort.
42
+
43
+ ## Process Overview
44
+
45
+ Six sequential phases. Each phase is described in its own section below.
46
+
47
+ 1. Parse args.
48
+ 2. Detect stack.
49
+ 3. Route audits.
50
+ 4. Dispatch subagents in parallel.
51
+ 5. Synthesize findings.
52
+ 6. Write report.
53
+
54
+ The orchestrator is read-only until phase 6.
55
+
56
+ ## Phase 1: Parse args
57
+
58
+ The orchestrator receives a single string of positional args after the command. Tokenize on whitespace and classify each token.
59
+
60
+ **Token classes:**
61
+ - **Mode tokens**: `quick`, `diff`, `interactive`. The first one encountered wins; later mode tokens are warned and dropped.
62
+ - **Scope tokens**: `focus`, `module`. Each consumes the next token as its value.
63
+ - **Unknown tokens**: warn and drop.
64
+
65
+ **Output structure:**
66
+
67
+ ```json
68
+ {
69
+ "mode": "full" | "quick" | "diff" | "interactive",
70
+ "scope": {
71
+ "module": "<path>" | null,
72
+ "focus": "<area>" | null
73
+ },
74
+ "raw": "<original arg string>"
75
+ }
76
+ ```
77
+
78
+ **Rules:**
79
+ - Empty args produce `{mode: "full", scope: {module: null, focus: null}}`.
80
+ - `quick` or `interactive` with scope tokens present: keep mode, set scope to `{module: null, focus: null}`, emit warning "scope tokens ignored in <mode> mode".
81
+ - `focus` without a value: emit error listing valid areas (from catalogue), exit before dispatch.
82
+ - `module` without a value: emit error "module requires a path argument", exit before dispatch.
83
+ - `module <path>` where path does not exist: emit error "no such module: <path>", exit before dispatch.
84
+
85
+ **Valid focus areas** (derived from the `applies` vocabulary):
86
+ `any`, `ui`, `domain`, `integration`, `architecture`, `errors`, `legacy`.
87
+
88
+ **Worked examples:**
89
+
90
+ | Input | Output |
91
+ |-------|--------|
92
+ | `""` | `{mode: "full", scope: {module: null, focus: null}}` |
93
+ | `"quick"` | `{mode: "quick", scope: {module: null, focus: null}}` |
94
+ | `"diff"` | `{mode: "diff", scope: {module: null, focus: null}}` |
95
+ | `"focus architecture"` | `{mode: "full", scope: {module: null, focus: "architecture"}}` |
96
+ | `"diff focus architecture"` | `{mode: "diff", scope: {module: null, focus: "architecture"}}` |
97
+ | `"module src/auth focus architecture"` | `{mode: "full", scope: {module: "src/auth", focus: "architecture"}}` |
98
+ | `"quick focus ui"` | `{mode: "quick", scope: {module: null, focus: null}}` plus warning |
99
+ | `"banana"` | `{mode: "full", scope: {module: null, focus: null}}` plus warning |
100
+
101
+ ## Phase 2: Detect stack
102
+
103
+ Determine which audit categories apply to this repo. Use cheap signals only; do not walk the full repo tree.
104
+
105
+ **Detection output:**
106
+
107
+ ```json
108
+ {
109
+ "languages": ["typescript", "..."],
110
+ "frameworks": ["react", "..."],
111
+ "hasUI": true,
112
+ "hasDomainLayer": false,
113
+ "hasIntegration": false,
114
+ "hasArchitecture": true
115
+ }
116
+ ```
117
+
118
+ **Defaults**: all booleans default to `false`; `languages` and `frameworks` default to `[]`. A signal flipping a field to `true` or appending an entry is the only way values get populated.
119
+
120
+ **Signals to gather (run all four; the steps are cheap and orthogonal):**
121
+
122
+ 1. **`package.json` if present**: read `dependencies` and `devDependencies`.
123
+ - Frameworks: any of `react`, `vue`, `@angular/core`, `svelte`, `solid-js`. Sets `frameworks` and `hasUI: true`.
124
+ - Integration: any of `kafkajs`, `amqplib`, `bullmq`, `nats`, `mqtt`. Sets `hasIntegration: true`.
125
+ 2. **Top-level directory listing**: one `find . -maxdepth 3 -type d -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/build/*" -not -path "*/coverage/*" -not -path "*/tests/fixtures/*"`.
126
+ - `domain/`, `entities/`, `aggregates/`: sets `hasDomainLayer: true`.
127
+ - `events/`, `messaging/`, `queues/`, `consumers/`: sets `hasIntegration: true`.
128
+ 3. **File extension frequency**: one `find . -maxdepth 4 -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/build/*" -not -path "*/coverage/*" -not -path "*/tests/fixtures/*"`, count by extension.
129
+ - **Frequency threshold for UI**: at least 3 files matching `.tsx`/`.jsx`/`.vue`/`.svelte`/`.html`/`.css`/`.scss` sets `hasUI: true`. A single fixture file should not flip the signal.
130
+ - `.ts`/`.js`: adds `typescript`/`javascript` to `languages` (>= 1 file).
131
+ - `.py`: adds `python` (>= 1).
132
+ - `.rs`: adds `rust` (>= 1).
133
+ - `.go`: adds `go` (>= 1).
134
+ 4. **`hasArchitecture`**: true if total non-test source files >= 5 (excluding the same paths above).
135
+
136
+ **Failure behavior:**
137
+ - If no `package.json` and no source-file extensions are detected, treat as "no signal" and warn: "no recognizable codebase signals detected; running only `applies: any` audits".
138
+ - Detection is best-effort. False positives (e.g. an empty `events/` directory) are acceptable; the per-audit applicability check upstream will already drop irrelevant ones.
139
+
140
+ **What NOT to do:**
141
+ - Do not read source file contents for detection.
142
+ - Do not run language-specific tooling (no `tsc`, no `eslint`).
143
+ - Do not exceed two `find` invocations and one `package.json` read.
144
+
145
+ ## Phase 3: Route audits
146
+
147
+ Choose which audits to dispatch.
148
+
149
+ **Inputs:**
150
+ - Detection result from Phase 2.
151
+ - Parsed args from Phase 1.
152
+ - Catalogue: `skills/index.json`.
153
+
154
+ **Algorithm:**
155
+
156
+ 1. Load catalogue from `skills/index.json`. If the file is missing, unreadable, or fails JSON parse, hard fail per the error table (the orchestrator cannot route without a catalogue). Filter to entries with both `applies` and `quick` fields (i.e. audit skills).
157
+ 2. **Apply detection filter:** keep an audit if any of its `applies` values matches an active signal:
158
+ - `any` always matches.
159
+ - `ui` matches if `hasUI`.
160
+ - `domain` matches if `hasDomainLayer`.
161
+ - `integration` matches if `hasIntegration`.
162
+ - `architecture` matches if `hasArchitecture`.
163
+ - `errors` matches if `hasArchitecture` (proxy: any non-trivial codebase has error-handling concerns).
164
+ - `legacy` matches only if `mode === "diff"`.
165
+ 3. **Apply mode filter:**
166
+ - `quick` mode: keep only entries with `quick: true`.
167
+ - `diff` mode: no further filter (handled by `legacy` matching above).
168
+ - `interactive` and `full` modes: no further filter.
169
+ 4. **Apply focus filter:** if `scope.focus` is set, keep only entries whose `applies` array contains that focus area.
170
+ 5. If the resulting list is empty, abort dispatch and emit one of:
171
+ - "No audits applicable to detected stack: <signals>. Override with `focus <area>`."
172
+ - "No audits matched `focus <area>`. Valid areas: <list>."
173
+ - "No quick audits applicable; rerun without `quick`."
174
+
175
+ **Module scope** is **not** applied here. It carries forward to Phase 4 as a per-subagent scope hint, because audit routing is the same regardless of whether the audit examines the whole repo or one path.
176
+
177
+ **Worked example:**
178
+ - Repo: Bun backend with `events/` directory.
179
+ - Detection: `{hasUI: false, hasDomainLayer: false, hasIntegration: true, hasArchitecture: true}`.
180
+ - Args: `quick focus architecture`.
181
+ - Step 2: keep audits with `any`, `architecture`, or `integration`.
182
+ - Step 3: `quick` mode keeps only `quick: true`. Result: `module-secret-auditor`, `coupling-auditor`, `cohesion-analyzer`, `demeter-enforcer`, `dependency-direction-auditor`, `cqs-auditor`, `temporal-coupling-detector`, plus any `any+quick` audits.
183
+ - Step 4: `focus architecture` drops audits whose `applies` does not include `architecture`. Result: `module-secret-auditor`, `coupling-auditor`, `cohesion-analyzer`, `demeter-enforcer`, `dependency-direction-auditor`, `cqs-auditor`.
184
+
185
+ ### Diff mode file set
186
+
187
+ When `mode === "diff"`, before dispatch the orchestrator computes the changed-file set:
188
+
189
+ 1. Run `git diff --name-only origin/main...HEAD` (fall back to `git diff --name-only main...HEAD` if no `origin` remote).
190
+ 2. Filter out paths that no longer exist (deleted files) and paths in the standard ignored set (`node_modules/`, `.git/`, `dist/`, `build/`, `coverage/`, `tests/fixtures/`).
191
+ 3. If the resulting list is empty, emit "diff mode: no changed files vs. main; rerun without `diff` or specify a commit range" per the error table and exit before dispatch.
192
+ 4. Otherwise, this list is passed to each subagent as the `Scope` (the `Diff:` form of the prompt template in Phase 4).
193
+
194
+ ## Phase 4: Dispatch subagents
195
+
196
+ For each routed audit, spawn one parallel `Agent` call with `subagent_type: general-purpose`. All dispatches go in **a single message with multiple tool calls** so they execute concurrently.
197
+
198
+ **Per-subagent prompt template:**
199
+
200
+ ````
201
+ You are running the <audit-id> audit on a codebase.
202
+
203
+ # Principles to apply
204
+
205
+ <paste the full content of skills/<audit-id>/SKILL.md verbatim>
206
+
207
+ # Scope
208
+
209
+ <one of:>
210
+ - Whole repo at <repo-root-absolute-path>.
211
+ - Module: <module-path-absolute>.
212
+ - Diff: only the following files changed vs. main: <newline-separated list>.
213
+
214
+ # Method
215
+
216
+ 1. Read the principles above.
217
+ 2. Examine the in-scope files. Use Read, Grep, and Glob. Do not run commands that mutate state.
218
+ 3. Identify violations of the principles. For each, capture: file path, optional line and symbol, severity, the specific principle violated, evidence (a short quoted or paraphrased snippet), and a 1-2 sentence recommendation.
219
+ 4. Severity: high = a senior engineer would advocate fixing this in the next sprint; med = should be fixed during related work; low = nice to have.
220
+ 5. Be conservative. If you are not confident a violation is real, omit it.
221
+
222
+ # Output contract
223
+
224
+ Return ONLY a JSON array of Finding objects. No markdown fences. No commentary before or after. If you find nothing, return [].
225
+
226
+ Schema:
227
+
228
+ [
229
+ {
230
+ "audit": "<audit-id>",
231
+ "file": "<repo-relative path>",
232
+ "line": <int or null>,
233
+ "symbol": "<string or null>",
234
+ "severity": "high" | "med" | "low",
235
+ "principle": "<short principle name, e.g. 'control coupling'>",
236
+ "evidence": "<1-3 sentence quote or paraphrase>",
237
+ "recommendation": "<1-2 sentence fix>"
238
+ }
239
+ ]
240
+
241
+ # Constraints
242
+
243
+ - Do not exceed 25 findings. If more exist, emit the 25 highest severity.
244
+ - Do not invent file paths or line numbers. Cite real locations.
245
+ - Do not include findings outside the declared scope.
246
+ ````
247
+
248
+ **Concurrency**: dispatch all subagents in a single tool-call batch. Subagents do not communicate with each other.
249
+
250
+ **Soft cap**: if a subagent has not returned within 5 minutes, drop it. The orchestrator does not have a wall-clock timer; this cap is enforced by treating any subagent that fails to return cleanly as `status: failed` and continuing.
251
+
252
+ **Retry policy:**
253
+ - If a subagent returns prose, markdown fences, or text that does not parse as JSON, retry **once** with this follow-up prompt:
254
+ > Your previous response was not valid JSON. Return ONLY a JSON array conforming to the schema specified earlier. No prose, no markdown fences, no commentary. If you found nothing, return `[]`.
255
+ - After the second failure, drop the audit and record `{audit, status: 'failed', reason: 'malformed JSON after 2 attempts'}`.
256
+ - Do not retry on timeout or tool-call crash.
257
+
258
+ **Per-finding validation:**
259
+ - Required fields: `audit`, `file`, `severity`, `principle`, `evidence`, `recommendation`.
260
+ - `severity` must be one of `"high"`, `"med"`, `"low"`.
261
+ - `audit` must equal the dispatched audit ID.
262
+ - A finding that fails validation is dropped; the count is added to that audit's metadata.
263
+
264
+ **Per-audit metadata produced** (consumed by Phase 5):
265
+
266
+ ```json
267
+ {
268
+ "audit": "<audit-id>",
269
+ "status": "ok" | "failed",
270
+ "reason": "<string or null>",
271
+ "dropped_findings": <int, count of findings dropped at validation>,
272
+ "retried": <bool, true if recovered on attempt 2>
273
+ }
274
+ ```
275
+
276
+ One such record is emitted per dispatched audit. Successful runs use `status: "ok"`, `reason: null`. Failed runs use `status: "failed"` and a reason string (e.g. `"timeout"`, `"crashed"`, `"malformed JSON after 2 attempts"`).
277
+
278
+ ## Phase 5: Synthesize
279
+
280
+ Merge all `Finding[]` arrays into a single `Report` object.
281
+
282
+ **Inputs:**
283
+ - Map of `audit-id -> Finding[]` (one entry per dispatched audit; failed audits omitted from this map).
284
+ - Per-audit metadata: `{audit, status, dropped_findings, retried, reason}`.
285
+
286
+ **Algorithm:**
287
+
288
+ 1. **Flatten** all findings into a single list, keeping `audit` on each.
289
+ 2. **Group by file**: for each unique `file`, collect every finding on that file across all audits.
290
+ 3. **Compute per-finding weight:**
291
+ - `severity_weight`: high = 3, med = 2, low = 1.
292
+ - `convergence_weight = min(3.0, 1 + 0.5 * (distinct_audits_on_file - 1))` where `distinct_audits_on_file` counts how many distinct audit IDs appear in the findings on this file.
293
+ - `symbol_boost`: if the finding has a non-null `symbol` AND at least one other finding on the same file shares that symbol AND comes from a different audit, multiply by `1.25`.
294
+ - `weight = severity_weight * convergence_weight * symbol_boost`.
295
+ 4. **Per-file score**: sum of `weight` across all findings on that file.
296
+ 5. **Sort files** by per-file score descending. For each file in the result, attach `top_issue` = the `principle` of the highest-weight finding on that file. Take the top N files (`N = 5` if `mode === "quick"`, else `10`; or all if fewer) for the "files most worth fixing" section.
297
+ 6. **Sort findings** flat by `weight` descending. For each finding in the result, attach `convergence` = `"<distinct_audits_on_file> audits on this file"` (e.g. "4 audits on this file"). Take the top M findings (`M = 5` if `mode === "quick"`, else `25`; or all if fewer) for the "top cross-cutting findings" section.
298
+ 7. **Build per-audit summaries**: for each audit ID present in the input map and with `findings.length > 0`, compute `{finding_count: <int>, unique_file_count: <int>, findings_by_file: [{file, findings: [...sorted by weight desc]}, ...]}`. Audits that returned `[]` are omitted from `by_audit_summary` (so Phase 6's per-axis index does not link to empty files).
299
+ 8. **Preserve raw findings**: copy the input `audit-id -> Finding[]` map to `Report.by_audit` verbatim (audits with empty arrays are still present here for completeness; the per-axis index in Phase 6 reads `by_audit_summary` instead, which omits empty audits).
300
+ 9. **Compute `audits_na`**: `audits_na = catalogue_audit_count - audits_dispatched_count` where `catalogue_audit_count` is the total number of audits in the catalogue with `applies` and `quick` fields, and `audits_dispatched_count` is the number routed by Phase 3 (regardless of pass/fail).
301
+
302
+ **Output `Report` structure:**
303
+
304
+ ```json
305
+ {
306
+ "metadata": {
307
+ "date": "YYYY-MM-DD",
308
+ "mode": "full" | "quick" | "diff" | "interactive",
309
+ "scope": { "module": "...", "focus": "..." },
310
+ "audits_succeeded": 14,
311
+ "audits_failed": 2,
312
+ "audits_na": 4,
313
+ "audits_total": 30,
314
+ "failures": [{"audit": "event-design-reviewer", "reason": "malformed JSON after 2 attempts"}],
315
+ "retries": [{"audit": "rams-design-audit", "recovered_on_attempt": 2}],
316
+ "findings_high": 47,
317
+ "findings_med": 89,
318
+ "findings_low": 34
319
+ },
320
+ "top_files": [
321
+ {
322
+ "file": "src/checkout/order.ts",
323
+ "score": 31.0,
324
+ "audits_hit": ["coupling-auditor", "complexity-accountant", "cohesion-analyzer", "cqs-auditor"],
325
+ "top_issue": "<principle of highest-weight finding on this file>"
326
+ }
327
+ ],
328
+ "top_findings": [
329
+ {
330
+ "weight": 11.25,
331
+ "finding": { "<full Finding object>": "..." },
332
+ "convergence": "4 audits on this file"
333
+ }
334
+ ],
335
+ "by_audit": {
336
+ "coupling-auditor": [],
337
+ "complexity-accountant": []
338
+ },
339
+ "by_audit_summary": {
340
+ "coupling-auditor": {
341
+ "finding_count": 12,
342
+ "unique_file_count": 7,
343
+ "findings_by_file": [
344
+ {
345
+ "file": "src/checkout/order.ts",
346
+ "findings": []
347
+ }
348
+ ]
349
+ }
350
+ }
351
+ }
352
+ ```
353
+
354
+ **Worked example (scoring):**
355
+
356
+ Three findings on `src/checkout/order.ts`:
357
+ - `coupling-auditor`, severity high, symbol `OrderService.applyDiscount`.
358
+ - `cohesion-analyzer`, severity med, symbol `OrderService.applyDiscount`.
359
+ - `complexity-accountant`, severity high, symbol `OrderService` (different).
360
+
361
+ `distinct_audits_on_file = 3` so `convergence_weight = 1 + 0.5 * 2 = 2.0`.
362
+
363
+ - Finding 1: `severity = 3`, `convergence = 2.0`, `symbol_boost = 1.25` (shares symbol with finding 2 from a different audit). `weight = 7.5`.
364
+ - Finding 2: `severity = 2`, `convergence = 2.0`, `symbol_boost = 1.25`. `weight = 5.0`.
365
+ - Finding 3: `severity = 3`, `convergence = 2.0`, `symbol_boost = 1.0` (its symbol is unique among the file's findings). `weight = 6.0`.
366
+
367
+ Per-file score: `7.5 + 5.0 + 6.0 = 18.5`. Findings sorted by weight: 1, 3, 2.
368
+
369
+ ## Phase 6: Write report
370
+
371
+ The only filesystem-mutating phase. Produces one top-level rollup and one per-axis file per fired audit.
372
+
373
+ **Output paths:**
374
+ - `docs/improvements/YYYY-MM-DD/audit.md` (top-level rollup).
375
+ - `docs/improvements/YYYY-MM-DD/audit/<audit-id>.md` (one per audit that returned at least one finding).
376
+
377
+ If `docs/improvements/YYYY-MM-DD/` already exists for today, append a numeric suffix: `audit-2.md`, `audit-3.md`, etc. Do not overwrite a previous run.
378
+
379
+ **`audit.md` template:**
380
+
381
+ ````markdown
382
+ # Codebase audit: {{date}}
383
+
384
+ **Mode**: {{mode}}{{#if scope.focus}} focus {{scope.focus}}{{/if}}{{#if scope.module}} module {{scope.module}}{{/if}}
385
+ **Audits run**: {{audits_succeeded}} succeeded / {{audits_failed}} failed / {{audits_na}} N/A / {{audits_total}} total
386
+ **Findings**: {{findings_high}} high, {{findings_med}} med, {{findings_low}} low
387
+
388
+ {{#if failures}}
389
+ **Failed audits**: {{#each failures}}{{audit}} ({{reason}}){{#unless @last}}, {{/unless}}{{/each}}
390
+ {{/if}}
391
+ {{#if retries}}
392
+ **Retries recovered**: {{#each retries}}{{audit}}{{#unless @last}}, {{/unless}}{{/each}}
393
+ {{/if}}
394
+
395
+ ## Files most worth fixing
396
+
397
+ | File | Score | Audits hit | Top issue |
398
+ |------|-------|------------|-----------|
399
+ {{#each top_files}}| {{file}} | {{score}} | {{audits_hit}} | {{top_issue}} |
400
+ {{/each}}
401
+
402
+ ## Top cross-cutting findings
403
+
404
+ {{#each top_findings}}
405
+ {{@index}}. **{{convergence}}**: `{{finding.file}}{{#if finding.line}}:{{finding.line}}{{/if}}` flagged by {{finding.audit}}: {{finding.principle}}. [details](audit/{{finding.audit}}.md)
406
+ - Evidence: {{finding.evidence}}
407
+ - Recommendation: {{finding.recommendation}}
408
+ {{/each}}
409
+
410
+ ## Per-axis reports
411
+
412
+ {{#each by_audit_summary}}
413
+ - [{{@key}}](audit/{{@key}}.md): {{this.finding_count}} findings
414
+ {{/each}}
415
+ ````
416
+
417
+ **Per-axis `audit/<audit-id>.md` template:**
418
+
419
+ The template renders against `Report.by_audit_summary[<audit-id>]` (produced in Phase 5 step 7).
420
+
421
+ ````markdown
422
+ # {{audit-id}} findings
423
+
424
+ {{finding_count}} findings on {{unique_file_count}} files.
425
+
426
+ {{#each findings_by_file}}
427
+ ## `{{file}}`
428
+
429
+ {{#each findings}}
430
+ ### {{principle}} ({{severity}}){{#if line}} (line {{line}}){{/if}}{{#if symbol}} (`{{symbol}}`){{/if}}
431
+
432
+ **Evidence:** {{evidence}}
433
+
434
+ **Recommendation:** {{recommendation}}
435
+
436
+ {{/each}}
437
+ {{/each}}
438
+ ````
439
+
440
+ **Terminal summary** (printed after writing files):
441
+
442
+ ```
443
+ Codebase audit complete.
444
+
445
+ Mode: <mode>
446
+ Findings: <high>H / <med>M / <low>L across <audits_succeeded> audits
447
+
448
+ Top 5 files to fix:
449
+ 1. <file> (score <score>, hit by <audits_hit>)
450
+ 2. ...
451
+
452
+ Top 5 cross-cutting issues:
453
+ 1. [<convergence>] <file>:<line> : <principle>
454
+ 2. ...
455
+
456
+ Full report: docs/improvements/<date>/audit.md
457
+ ```
458
+
459
+ **Failure handling:**
460
+ - If the target directory cannot be created or written to (permissions, disk full): fall back to printing the full `audit.md` content to the terminal, surface the write error, and do not write the per-axis files. The user can copy-paste the report.
461
+ - If a per-axis file fails to write but `audit.md` succeeds: emit a warning with the audit ID, continue, and link in `audit.md` is left as a broken link with an explanatory note.
462
+
463
+ ## Orchestration: putting it together
464
+
465
+ When the user invokes `/improve-my-codebase [args]`, execute phases in order. Stop early on hard failures (per the error table). Soft failures (subagent issues) are recorded in metadata and do not stop the run.
466
+
467
+ Pseudocode:
468
+
469
+ ```
470
+ parsed = parseArgs(rawArgs)
471
+ if parsed.errors: emit, exit
472
+
473
+ detection = detectStack(repoRoot)
474
+ if detection.noSignal: warn, continue with applies:any audits only
475
+
476
+ audits = routeAudits(catalogue, detection, parsed)
477
+ if audits.empty: emit specific message, exit
478
+
479
+ if parsed.mode == "interactive":
480
+ invoke interactive interview (see Interactive Mode section); produces a refined `parsed`,
481
+ then re-run routeAudits.
482
+
483
+ findings = dispatchSubagents(audits, parsed.scope, repoRoot) // parallel
484
+ report = synthesize(findings, audits, parsed)
485
+ writeReport(report, todaysDateDir)
486
+ printTerminalSummary(report)
487
+ ```
488
+
489
+ ## Interactive Mode
490
+
491
+ When `parsed.mode === "interactive"`:
492
+
493
+ 1. Show the user the detected stack and the audit set the orchestrator would run by default.
494
+ 2. Ask, one at a time:
495
+ - "Anything you've been losing time on lately?" (free text, suggests a `focus` area)
496
+ - "Any directory you want to scope to?" (path or skip; sets `module`)
497
+ - "Quick scan or thorough?" (sets `quick` or full)
498
+ 3. Apply the answers as if they were args, re-route, then proceed to dispatch.
499
+ 4. Confirm the final audit list before dispatching: "Running these audits: <list>. OK?"
500
+
501
+ Interactive mode is the only path that reroutes after Phase 3.
502
+
503
+ ## Error handling
504
+
505
+ | Failure | Phase | Response |
506
+ |---------|-------|----------|
507
+ | No audits applicable | 3 | Skip dispatch. Emit message. Suggest `focus <area>` to override. |
508
+ | `module <path>` does not exist | 1 | Hard fail. Print path + suggestion. |
509
+ | `diff` mode with no changed files | 3 | Tell user, suggest `full` or commit-range. Do not run. |
510
+ | `focus <area>` matches no audits | 3 | List valid areas. Exit. |
511
+ | Subagent timeout | 4 | Drop. Record `{audit, status: 'failed', reason: 'timeout'}`. Continue. |
512
+ | Subagent crash | 4 | Drop. Record. Continue. No retry. |
513
+ | Subagent malformed JSON | 4 | Retry up to 1 time (2 attempts total). Then drop. |
514
+ | Finding fails schema | 5 | Drop bad finding only. Note count in metadata. |
515
+ | Cannot write report file | 6 | Fall back to terminal-only. Print full report. Surface write error. |
516
+ | `index.json` missing/malformed | 3 | Hard fail. Suggest reinstalling. |
package/skills/index.json CHANGED
@@ -3,13 +3,17 @@
3
3
  "name": "design-review",
4
4
  "description": "Brooks-inspired design integrity review — tests conceptual integrity, constraint exploitation, removal discipline, and scope control",
5
5
  "type": "prompt",
6
- "version": "1.0.0"
6
+ "version": "1.0.0",
7
+ "applies": ["any"],
8
+ "quick": false
7
9
  },
8
10
  {
9
11
  "name": "codebase-architecture",
10
12
  "description": "Architecture review for existing codebases or structured design for new projects, with patterns reference",
11
13
  "type": "prompt",
12
- "version": "1.0.0"
14
+ "version": "1.0.0",
15
+ "applies": ["any", "architecture"],
16
+ "quick": false
13
17
  },
14
18
  {
15
19
  "name": "code-intelligence",
@@ -21,145 +25,193 @@
21
25
  "name": "contract-enforcer",
22
26
  "description": "Meyer-inspired Design by Contract — preconditions, postconditions, invariants, and failure contracts for non-trivial functions",
23
27
  "type": "prompt",
24
- "version": "1.0.0"
28
+ "version": "1.0.0",
29
+ "applies": ["any"],
30
+ "quick": false
25
31
  },
26
32
  {
27
33
  "name": "complexity-accountant",
28
34
  "description": "Ousterhout-inspired complexity analysis — deep vs shallow modules, complexity budget, justified abstractions",
29
35
  "type": "prompt",
30
- "version": "1.0.0"
36
+ "version": "1.0.0",
37
+ "applies": ["any"],
38
+ "quick": false
31
39
  },
32
40
  {
33
41
  "name": "module-secret-auditor",
34
42
  "description": "Parnas-inspired information hiding analysis — module boundaries drawn by change-reason, not by noun or technical layer",
35
43
  "type": "prompt",
36
- "version": "1.0.0"
44
+ "version": "1.0.0",
45
+ "applies": ["architecture"],
46
+ "quick": true
37
47
  },
38
48
  {
39
49
  "name": "seam-finder",
40
50
  "description": "Feathers-inspired legacy code modification — find seams, make minimal incisions, preserve existing behavior",
41
51
  "type": "prompt",
42
- "version": "1.0.0"
52
+ "version": "1.0.0",
53
+ "applies": ["legacy"],
54
+ "quick": true
43
55
  },
44
56
  {
45
57
  "name": "simplicity-razor",
46
58
  "description": "Hickey-inspired simplicity analysis — simple vs easy, complecting detection, strand decomposition",
47
59
  "type": "prompt",
48
- "version": "1.0.0"
60
+ "version": "1.0.0",
61
+ "applies": ["any"],
62
+ "quick": false
49
63
  },
50
64
  {
51
65
  "name": "coupling-auditor",
52
66
  "description": "Constantine & Yourdon-inspired coupling analysis — classify, measure, and reduce interdependence between modules",
53
67
  "type": "prompt",
54
- "version": "1.0.0"
68
+ "version": "1.0.0",
69
+ "applies": ["architecture"],
70
+ "quick": true
55
71
  },
56
72
  {
57
73
  "name": "evolution-analyzer",
58
74
  "description": "Lehman-inspired software evolution analysis — trajectory assessment, debt visibility, and change impact on system health",
59
75
  "type": "prompt",
60
- "version": "1.0.0"
76
+ "version": "1.0.0",
77
+ "applies": ["any"],
78
+ "quick": false
61
79
  },
62
80
  {
63
81
  "name": "error-strategist",
64
82
  "description": "Duffy & Abrahams-inspired error handling — classify errors (bug/recoverable/fatal), assign safety guarantees, design recovery boundaries",
65
83
  "type": "prompt",
66
- "version": "1.0.0"
84
+ "version": "1.0.0",
85
+ "applies": ["errors"],
86
+ "quick": false
67
87
  },
68
88
  {
69
89
  "name": "rams-design-audit",
70
90
  "description": "Dieter Rams-inspired design audit — every visual element must earn its presence, less but better, clarity through restraint",
71
91
  "type": "prompt",
72
- "version": "1.0.0"
92
+ "version": "1.0.0",
93
+ "applies": ["ui"],
94
+ "quick": true
73
95
  },
74
96
  {
75
97
  "name": "cognitive-load-auditor",
76
98
  "description": "Jeff Johnson-inspired cognitive load analysis — evaluate UI against Miller's Law, Hick's Law, Fitts's Law, and working memory limits",
77
99
  "type": "prompt",
78
- "version": "1.0.0"
100
+ "version": "1.0.0",
101
+ "applies": ["ui"],
102
+ "quick": false
79
103
  },
80
104
  {
81
105
  "name": "gestalt-reviewer",
82
106
  "description": "Gestalt-inspired visual perception audit — proximity, similarity, closure, continuity, and figure-ground analysis for UI layouts",
83
107
  "type": "prompt",
84
- "version": "1.0.0"
108
+ "version": "1.0.0",
109
+ "applies": ["ui"],
110
+ "quick": true
85
111
  },
86
112
  {
87
113
  "name": "integration-pattern-auditor",
88
114
  "description": "Hohpe & Woolf-inspired messaging analysis — name the integration pattern, verify delivery guarantees, identify missing infrastructure",
89
115
  "type": "prompt",
90
- "version": "1.0.0"
116
+ "version": "1.0.0",
117
+ "applies": ["integration"],
118
+ "quick": false
91
119
  },
92
120
  {
93
121
  "name": "unidirectional-flow-enforcer",
94
122
  "description": "Elm Architecture-inspired data flow analysis — enforce unidirectional state flow, detect bidirectional mutations, trace state lifecycle in UI applications",
95
123
  "type": "prompt",
96
- "version": "1.0.0"
124
+ "version": "1.0.0",
125
+ "applies": ["ui"],
126
+ "quick": false
97
127
  },
98
128
  {
99
129
  "name": "event-design-reviewer",
100
130
  "description": "Evans/Vernon/Dahan-inspired event design — domain-meaningful naming, fat payloads, schema evolution, and the domain expert test",
101
131
  "type": "prompt",
102
- "version": "1.0.0"
132
+ "version": "1.0.0",
133
+ "applies": ["integration", "domain"],
134
+ "quick": false
103
135
  },
104
136
  {
105
137
  "name": "dependency-direction-auditor",
106
138
  "description": "Martin-inspired dependency direction analysis — trace imports across layers, classify violations by severity, recommend inversion",
107
139
  "type": "prompt",
108
- "version": "1.0.0"
140
+ "version": "1.0.0",
141
+ "applies": ["architecture"],
142
+ "quick": true
109
143
  },
110
144
  {
111
145
  "name": "cohesion-analyzer",
112
146
  "description": "Constantine & Yourdon-inspired cohesion analysis — classify module focus on the 7-level spectrum, find split lines, reduce mixed responsibilities",
113
147
  "type": "prompt",
114
- "version": "1.0.0"
148
+ "version": "1.0.0",
149
+ "applies": ["architecture"],
150
+ "quick": true
115
151
  },
116
152
  {
117
153
  "name": "demeter-enforcer",
118
154
  "description": "Lieberherr-inspired Law of Demeter analysis — detect chain violations, parameter drilling, and hidden traversal; fix with tell-don't-ask or parameter narrowing",
119
155
  "type": "prompt",
120
- "version": "1.0.0"
156
+ "version": "1.0.0",
157
+ "applies": ["architecture"],
158
+ "quick": true
121
159
  },
122
160
  {
123
161
  "name": "bounded-context-auditor",
124
162
  "description": "Evans-inspired bounded context analysis — detect linguistic fractures, draw context maps, identify leaking language and shared model pollution",
125
163
  "type": "prompt",
126
- "version": "1.0.0"
164
+ "version": "1.0.0",
165
+ "applies": ["domain"],
166
+ "quick": false
127
167
  },
128
168
  {
129
169
  "name": "port-adapter-auditor",
130
170
  "description": "Cockburn-inspired hexagonal architecture analysis — identify ports and adapters, classify boundary health, ensure core testability and swappability",
131
171
  "type": "prompt",
132
- "version": "1.0.0"
172
+ "version": "1.0.0",
173
+ "applies": ["architecture"],
174
+ "quick": false
133
175
  },
134
176
  {
135
177
  "name": "idempotency-guardian",
136
178
  "description": "Helland-inspired idempotency analysis — classify mutation points, check protection mechanisms, evaluate side effect safety for retry-safe systems",
137
179
  "type": "prompt",
138
- "version": "1.0.0"
180
+ "version": "1.0.0",
181
+ "applies": ["integration"],
182
+ "quick": false
139
183
  },
140
184
  {
141
185
  "name": "type-driven-designer",
142
186
  "description": "Wlaschin & Minsky-inspired type design — make illegal states unrepresentable through branded types, discriminated unions, and domain-encoded constraints",
143
187
  "type": "prompt",
144
- "version": "1.0.0"
188
+ "version": "1.0.0",
189
+ "applies": ["any"],
190
+ "quick": false
145
191
  },
146
192
  {
147
193
  "name": "cqs-auditor",
148
194
  "description": "Meyer-inspired Command-Query Separation — classify functions as commands or queries, detect mixed violations, separate side effects from return values",
149
195
  "type": "prompt",
150
- "version": "1.0.0"
196
+ "version": "1.0.0",
197
+ "applies": ["architecture"],
198
+ "quick": true
151
199
  },
152
200
  {
153
201
  "name": "composability-auditor",
154
202
  "description": "Unix Philosophy-inspired composability analysis — identify reuse blockers, decompose self-sufficient units into composable pieces with standard interfaces",
155
203
  "type": "prompt",
156
- "version": "1.0.0"
204
+ "version": "1.0.0",
205
+ "applies": ["any"],
206
+ "quick": false
157
207
  },
158
208
  {
159
209
  "name": "temporal-coupling-detector",
160
210
  "description": "Hidden ordering dependency analysis — detect two-phase init, method order dependencies, invisible preconditions, and resource lifecycle violations; fix with types, parameters, and factory patterns",
161
211
  "type": "prompt",
162
- "version": "1.0.0"
212
+ "version": "1.0.0",
213
+ "applies": ["any"],
214
+ "quick": true
163
215
  },
164
216
  {
165
217
  "name": "terse",
@@ -196,5 +248,11 @@
196
248
  "description": "Manage reusable writing personas for cover letters using the NNGroup 4-dimension tone framework. Locks in tone, sentence style, and vocabulary across applications.",
197
249
  "type": "prompt",
198
250
  "version": "1.0.0"
251
+ },
252
+ {
253
+ "name": "improve-my-codebase",
254
+ "description": "Orchestrator skill that runs every applicable audit skill in parallel and produces a prioritized, convergence-ranked improvement report",
255
+ "type": "prompt",
256
+ "version": "1.0.0"
199
257
  }
200
258
  ]