haac-aikit 0.7.3 → 0.8.1

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
@@ -4,9 +4,7 @@
4
4
  [![GitHub](https://img.shields.io/badge/github-Hamad--Center%2Fhaac--aikit-blue?logo=github)](https://github.com/Hamad-Center/haac-aikit)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
6
6
 
7
- A CLI that drops a working AI-coding setup into any repo — rules, skills, safety hooks, subagents, MCP stub, CI templates — and then helps you figure out which of those rules are actually doing anything.
8
-
9
- Works with Claude Code, Cursor, GitHub Copilot, Windsurf, Aider, Gemini CLI, and OpenAI Codex CLI.
7
+ One command drops a working AI-coding setup into any repo — rules, skills, safety hooks, subagents, MCP stub, CI templates — for Claude Code, Cursor, Copilot, Windsurf, Aider, Gemini CLI, and Codex.
10
8
 
11
9
  ## Quickstart
12
10
 
@@ -14,7 +12,7 @@ Works with Claude Code, Cursor, GitHub Copilot, Windsurf, Aider, Gemini CLI, and
14
12
  npx haac-aikit
15
13
  ```
16
14
 
17
- The wizard takes about 30 seconds and writes a `.aikitrc.json` you can commit. Re-run later with `aikit sync`.
15
+ 30-second wizard, writes a `.aikitrc.json` you can commit. Re-run anytime with `aikit sync`.
18
16
 
19
17
  For CI or scripts:
20
18
 
@@ -22,158 +20,39 @@ For CI or scripts:
22
20
  npx haac-aikit --yes --tools=claude,cursor,copilot --preset=standard
23
21
  ```
24
22
 
25
- ## Why this exists
26
-
27
- Every AI tool now wants its own rules file: CLAUDE.md, `.cursor/rules/`, `copilot-instructions.md`, AGENTS.md. They all do roughly the same thing — tell the model how your team writes code — but you end up maintaining four copies, none of which you can tell are working.
28
-
29
- You write 30 rules and pray. The kit you cloned last quarter ships a CLAUDE.md with rules about Python even though you write Go. You never delete the dead ones because you can't tell they're dead.
30
-
31
- haac-aikit gives you the curated baseline like other kits do (skills, hooks, agents, etc.), and on top of that it adds three things no other kit ships:
32
-
33
- 1. **Observability** — telemetry hooks log which rules are loaded and violated, so `aikit doctor --rules` can tell you which to keep, strengthen, or delete.
34
- 2. **Dialect translation** — Cursor's MDC, Claude's emphasis tokens, Aider's imperative phrasing all want different things. Same canonical AGENTS.md, reformatted per tool.
35
- 3. **`aikit learn`** — mines your team's PR review comments for repeated corrections and proposes them as new rules.
36
-
37
- ## What changes after you install it
38
-
39
- **Right after `aikit init`:**
40
-
41
- - One `AGENTS.md` becomes the source of truth for every AI tool you use. You stop maintaining four copies of the same rules.
42
- - Force-pushing to `main`, committing secrets, reading `.env*` / `.ssh/` / `.aws/` files, `rm -rf` outside the project, and about a dozen other footguns are blocked at the hook level. They don't depend on the AI cooperating — the hook fires before the tool call.
43
- - 18 process skills (TDD, brainstorming, debugging, etc.) sit in `.claude/skills/` and load on demand. Always-on cost is roughly 100 tokens per skill, so your context window stays clean.
44
- - Per-PR safety: a `gitleaks` workflow ships in `.github/workflows/` so secrets caught at commit time don't slip through code review either.
45
-
46
- **After a week or two of use:**
47
-
48
- - `aikit doctor --rules` shows you which rules fire often, which fire and get violated, and which never come up. You delete the dead ones, strengthen the disputed ones, and stop guessing.
49
- - The `.aikit/events.jsonl` log accumulates a real record of every rule load and pattern violation — local, gitignored, never uploaded. If you opt into the LLM judge it also includes per-turn cited / violated verdicts.
50
-
51
- **After a month:**
52
-
53
- - `aikit learn --limit=30` mines your merged PRs for repeated review comments and proposes new rules. Patterns like "we always validate at the boundary" or "use named exports here" that used to live only in code review get codified without anyone hand-typing them.
54
- - The optional GitHub Actions workflow posts a sticky PR comment with a rule-adherence score, so regressions across releases are visible at PR-review time.
55
-
56
- **What you don't get locked into:**
57
-
58
- - AGENTS.md is portable — Cursor, Copilot, Codex, Aider, and Gemini all read it. Switching tools doesn't mean rewriting your rules.
59
- - The catalog (skills, hooks, agents) is just markdown and shell scripts under `.claude/`. Take it and walk away whenever — haac-aikit never reaches back into your repo and there's no SaaS to cancel.
60
- - All telemetry is local. The opt-in LLM judge calls the Anthropic API only with your own key, only on `Stop` events, and you can pull the env var anytime.
61
-
62
23
  ## What you get
63
24
 
64
25
  ### Minimal scope
65
26
 
66
27
  | File | Purpose |
67
28
  |---|---|
68
- | `AGENTS.md` | The canonical project rules — your edits outside the BEGIN/END markers are never touched |
69
- | `CLAUDE.md` | Five-line shim that imports `@AGENTS.md` plus a Claude-only override block |
70
- | `.cursor/rules/000-base.mdc` | Cursor MDC, dialect-translated from AGENTS.md (not a generic shim) |
71
- | `.github/copilot-instructions.md`, `GEMINI.md`, `CONVENTIONS.md`, `.windsurf/rules/project.md` | Per-tool shims |
72
- | `.mcp.json` | MCP stub with filesystem, memory, fetch — three servers, ~1k tokens of tool defs |
29
+ | `AGENTS.md` | Canonical rules — your edits outside BEGIN/END markers are never touched |
30
+ | `CLAUDE.md` | Five-line shim that imports `@AGENTS.md` |
31
+ | `.cursor/rules/000-base.mdc` | Dialect-translated MDC (not a generic copy) |
32
+ | Per-tool shims | Copilot, Gemini, Windsurf, Aider |
33
+ | `.mcp.json` | MCP stub: filesystem, memory, fetch |
73
34
  | `.claude/settings.json` | Hardened permissions: deny list for secrets and destructive commands |
74
- | `.aikitrc.json` | Versioned config so re-runs are deterministic |
75
35
 
76
- ### Standard scope (default) adds
36
+ ### Standard scope adds
77
37
 
78
- - 18 process skills, organised into Tier 1 (always-on) and Tier 2 (opt-in). Skill bodies only load when triggered, so the at-rest cost is roughly 100 tokens each.
79
- - **Agents** in `.claude/agents/`: 10 always-on (planner, reviewer, debugger, pr-describer, …) plus opt-in specialty agents (simplifier, prompt-engineer, evals-author, …) selected via the wizard.
80
- - **Conflict-aware sync**: if you've modified an installed template (e.g., `.claude/agents/reviewer.md`), `aikit sync` and `aikit update` now prompt before overwriting instead of silently replacing it.
81
- - Safety hooks that block dangerous bash, force-push to main, secret commits, and reads of sensitive files.
82
- - Observability hooks (see below).
83
- - A starter `.claude/aikit-rules.json` with regex patterns for common things like no `console.log`, no default exports, no `any`.
84
- - `docs/claude-md-reference.md` — a 2026 reference doc on Anthropic's memory features for your team.
85
- - `.claude/rules/example.md` — a starter path-scoped rule that only loads when matching files are read.
86
- - CI workflows: gitleaks, standard CI, optional `@claude` PR responder, optional rule-adherence PR comment.
38
+ - **18 process skills** in `.claude/skills/` TDD, brainstorming, debugging, git workflows, and more. Bodies load on demand, ~100 tokens at rest.
39
+ - **14 agents** in `.claude/agents/` planner, reviewer, debugger, pr-describer, and more.
40
+ - **Safety hooks** — blocks force-push to main, secret commits, `rm -rf`, reads of `.env*` / `.ssh*` / `.aws*`. Fires before the tool call, doesn't rely on the model cooperating.
41
+ - **Rule observability hooks** logs which rules load and which get violated, feeds `aikit doctor --rules`.
42
+ - **HTML design system** — `docs/aikit-html-design-system.html` ships with every standard install; use `/html` to generate rich browser-viewable artifacts instead of long markdown.
43
+ - CI workflows: gitleaks, standard CI, optional `@claude` PR responder.
87
44
 
88
45
  ### Everything scope adds
89
46
 
90
- Dev container, OTel exporter, plugin wrapper, auto-sync CI, and shape-specific agents (frontend / backend / mobile, picked based on the project shape you select in the wizard).
47
+ Dev container, OTel exporter, plugin wrapper, auto-sync CI, shape-specific agents (frontend / backend / mobile).
91
48
 
92
- ## Rule observability
49
+ ## What makes it different
93
50
 
94
- After a few Claude Code sessions:
95
-
96
- ```
97
- $ aikit doctor --rules
98
-
99
- Hot rules (working as intended)
100
- commit.conventional-commits — 47 loads
101
- security.no-sensitive-files — 12 loads
102
-
103
- Disputed rules (>30% violation rate)
104
- code-style.no-console-log — 47 loads, 18 pattern violations
105
- Frequently violated. Strengthen with IMPORTANT/YOU MUST or move to a hook.
106
-
107
- Dead rules (never observed)
108
- legacy.bounded-contexts
109
- Never loaded, cited, or violated. Consider removing or rephrasing.
110
- ```
111
-
112
- This comes from three small hooks shipped at standard scope:
113
-
114
- - **`log-rule-event.sh`** runs on `InstructionsLoaded`. It scans loaded files for `<!-- id: code-style.no-any -->` markers and writes one event per rule per session.
115
- - **`check-pattern-violations.sh`** runs on `PostToolUse` for Edit/Write. It reads `.claude/aikit-rules.json` and flags any pattern matches in the file Claude just wrote.
116
- - **`judge-rule-compliance.sh`** runs on `Stop`. It's opt-in. If you set `AIKIT_JUDGE=1` and `ANTHROPIC_API_KEY`, it asks Claude Haiku to verdict whether each loaded rule was cited or violated this turn (~$0.001/turn). Without both env vars it returns immediately and does nothing.
117
-
118
- All three hooks append to `.aikit/events.jsonl`, which `sync` adds to `.gitignore`. Nothing leaves your machine unless you opt in to the judge.
119
-
120
- `aikit report` formats the same data as Markdown (PR-comment ready) or JSON (`--format=json`, for CI). Without judge data, the adherence score is `null` with `basis: "no-evidence"` rather than a fake number derived from load counts.
121
-
122
- ### Adding observability to your own rules
123
-
124
- In any rule file, add a stable HTML-comment ID:
125
-
126
- ```markdown
127
- - <!-- id: code-style.no-any emphasis=high paths=src/**/*.ts --> Use `unknown` and type guards, not `any`.
128
- ```
51
+ **Rule observability.** Telemetry hooks tell you which rules fire, which get violated, and which are dead weight. `aikit doctor --rules` shows the buckets; `aikit report` formats them for a PR comment. [docs/observability.md](docs/observability.md)
129
52
 
130
- The `id` is required for telemetry. `emphasis` and `paths` are optional metadata read by the dialect translators. HTML comments cost zero context tokens Claude strips them before injection so this is free observability.
53
+ **Dialect translation.** One canonical `AGENTS.md`, reformatted per tool proper MDC frontmatter for Cursor, emphasis tokens for Claude, imperative phrasing for Aider. You stop maintaining four copies of the same rules. [docs/dialects.md](docs/dialects.md)
131
54
 
132
- ## Dialect translation
133
-
134
- Other multi-tool kits copy the same content into every per-tool file. haac-aikit reformats per dialect.
135
-
136
- For Cursor that means: `.cursor/rules/000-base.mdc` gets proper MDC frontmatter, **bold** emphasis on rules tagged `emphasis=high`, and a paths hint surfaced inline. Rule IDs are preserved so the observability hooks see them load alongside AGENTS.md.
137
-
138
- Claude, Aider, Copilot, and Gemini translators are the next thing on the roadmap.
139
-
140
- ## Learn from your PR history
141
-
142
- ```
143
- $ aikit learn --limit=30
144
- ```
145
-
146
- Pulls the last 30 merged PRs via `gh`, scans review and issue comments for correction phrases ("we always", "don't here", "actually let's", "nit:"), tokenises them, clusters by Jaccard similarity, and prints proposals in a paste-ready block:
147
-
148
- ```
149
- <!-- BEGIN:learned -->
150
- ## Learned conventions
151
- - <!-- id: learned.use-named-exports --> we always use named exports here, not default
152
- - <!-- id: learned.validate-input-boundary --> please validate inputs at the API boundary
153
- <!-- END:learned -->
154
- ```
155
-
156
- Review the suggestions, paste the keepers into AGENTS.md. The similarity threshold is intentionally permissive — false positives are easy to reject, missed signal is harder to recover. There are no ML dependencies; it's regex, a stopword list, and a five-line stemmer.
157
-
158
- ## Update safety
159
-
160
- haac-aikit owns content between BEGIN/END markers. Everything outside is yours.
161
-
162
- ```markdown
163
- # My Project
164
-
165
- My own notes — never touched by aikit.
166
-
167
- <!-- BEGIN:haac-aikit -->
168
- managed content
169
- <!-- END:haac-aikit -->
170
-
171
- More of my notes — also never touched.
172
- ```
173
-
174
- `aikit sync` is idempotent: running it twice produces the same files. `aikit diff` shows what would change. `aikit update` shows the diff and prompts before writing.
175
-
176
- The marker engine handles four dialects automatically (`.md` → `<!-- ... -->`, `.yml` → `# `, `.json` → `// `, shell → `# `). If a downstream user removes a marker by accident, the hook refuses to silently re-append — it errors out so you can investigate.
55
+ **Learn from your PR history.** `aikit learn --limit=30` mines merged PR review comments for repeated corrections and proposes them as new rules. No ML — just regex, a stopword list, and Jaccard similarity. → [docs/learn.md](docs/learn.md)
177
56
 
178
57
  ## Commands
179
58
 
@@ -181,7 +60,7 @@ The marker engine handles four dialects automatically (`.md` → `<!-- ... -->`,
181
60
  aikit interactive wizard
182
61
  aikit sync regenerate from .aikitrc.json (idempotent)
183
62
  aikit update pull latest templates, show diff, prompt
184
- aikit diff show drift between current state and a fresh generation
63
+ aikit diff show drift between current state and a fresh sync
185
64
  aikit add <item> add a single skill, command, agent, or hook
186
65
  aikit list show installed items + catalog availability
187
66
  aikit doctor schema, triggers, broken-link checks
@@ -191,39 +70,27 @@ aikit report --format=json same data, structured for CI
191
70
  aikit learn --limit=30 propose rules from your PR review history
192
71
  ```
193
72
 
194
- Most prompts have a `--flag` equivalent for headless use.
195
-
196
- ## Design choices, in case they help you decide
197
-
198
- - **Skills are ~100 tokens at rest.** Bodies load only when the skill is triggered. A kit with 30 always-on skill bodies eats your context window before you've started.
199
- - **AGENTS.md is canonical, CLAUDE.md is a 5-line shim that imports it.** One source of truth across all tools.
200
- - **Three MCP servers by default.** Five servers can be ~77K tokens of tool definitions. Most projects don't need a search engine *and* a database *and* a filesystem in every conversation.
201
- - **Marker-protected templates.** This was the first thing I broke in my own setup before adding the marker engine. Your edits outside the markers survive every `sync`.
202
- - **No LLM-generated content in the catalog.** Every shipped skill / hook / agent is human-curated. ETH Zurich's 2026 study on LLM-augmented context found dumps add cost without improving success rate.
203
-
204
- ## How haac-aikit compares
73
+ ## How it compares
205
74
 
206
75
  | | haac-aikit | rulesync | ruler | claudekit |
207
76
  |---|---|---|---|---|
208
- | Includes content (skills, agents, hooks) | yes | no — config manager only | no — config manager only | Claude-only |
209
- | Cross-tool | 7 tools | yes | yes | no |
210
- | Open Skills standard (agentskills.io) | yes | no | no | no |
211
- | Config file backed | `.aikitrc.json` | no | no | no |
212
- | Idempotent BEGIN/END markers | yes | no | `.bak` backups | no |
77
+ | Includes content (skills, agents, hooks) | yes | no | no | Claude-only |
78
+ | Cross-tool (7 tools) | yes | yes | yes | no |
213
79
  | Rule observability | yes | no | no | no |
214
80
  | Dialect translation | yes | no | no | no |
215
81
  | Learn from PR history | yes | no | no | no |
82
+ | Idempotent BEGIN/END markers | yes | no | `.bak` backups | no |
216
83
 
217
84
  ## Status
218
85
 
219
- This is 0.7.0. The strategy plan reserves 1.0 until at least three external teams have used the observability loop on real PRs until then, expect breaking changes between minor versions. 0.7.0 ships the tiered agent system, 8 new agents, interactive conflict resolution, and the Cursor dialect translator; Claude, Aider, Copilot, and Gemini translators are next.
86
+ 0.8.0. Holding 1.0 until at least three external teams have used the observability loop on real PRs. Until then, expect breaking changes between minor versions.
87
+
88
+ Looking for teams to try it — feedback shapes 1.0. Comment on [issue #1](https://github.com/Hamad-Center/haac-aikit/issues/1).
220
89
 
221
90
  ## Contributing
222
91
 
223
92
  Issues and PRs welcome at [github.com/Hamad-Center/haac-aikit](https://github.com/Hamad-Center/haac-aikit).
224
93
 
225
- I'm looking for **three teams** to try the observability loop on a real codebase. Your feedback shapes 1.0. Comment on [issue #1](https://github.com/Hamad-Center/haac-aikit/issues/1) if you're up for it.
226
-
227
94
  ## License
228
95
 
229
- MIT. See [ATTRIBUTIONS.md](ATTRIBUTIONS.md) for the list of adapted sources.
96
+ MIT. See [ATTRIBUTIONS.md](ATTRIBUTIONS.md).
@@ -0,0 +1,26 @@
1
+ Generate an HTML artifact for the current context using the html-artifacts skill.
2
+
3
+ ## Usage
4
+ `/html [optional intent]`
5
+
6
+ ## Steps
7
+
8
+ 1. **Determine intent**
9
+ - If called with args (e.g. `/html code review of today's PR`): use the args as the intent.
10
+ - If called with no args: infer intent from the current conversation — what task is in progress, what was just discussed, what files are open.
11
+
12
+ 2. **Pick the use-case pattern**
13
+ Using the `html-artifacts` skill, identify which of the five patterns fits:
14
+ Spec/Planning, Code Review, Report/Research, Prototype, or Custom Editor.
15
+
16
+ 3. **Generate the artifact**
17
+ - Apply the built-in design system CSS tokens
18
+ - If `docs/aikit-html-design-system.html` exists in the project, read it first and inherit its CSS variable values
19
+ - Follow the structure guidance for the chosen pattern
20
+ - Pure HTML/CSS/JS only — no external CDN dependencies
21
+
22
+ 4. **Save and report**
23
+ - Determine a short slug from the intent (e.g. `code-review-auth-pr`, `weekly-report`)
24
+ - Save to `.aikit/artifacts/<slug>-<timestamp>.html`
25
+ - Print the full path
26
+ - Suggest opening: `open <path>` (macOS) / `xdg-open <path>` (Linux)
@@ -0,0 +1,178 @@
1
+ <!-- Customize the CSS variables above. The model reads this file when generating HTML artifacts. -->
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>haac-aikit HTML Design System</title>
8
+ <style>
9
+ /* ─── Design tokens ────────────────────────────────────────────────────────
10
+ Edit these variables to retheme all HTML artifacts generated by the model.
11
+ ──────────────────────────────────────────────────────────────────────── */
12
+ :root {
13
+ --color-bg: #0f1117;
14
+ --color-surface: #1a1d27;
15
+ --color-border: #2e3143;
16
+ --color-text: #e2e8f0;
17
+ --color-muted: #8892a4;
18
+ --color-accent: #6366f1;
19
+ --color-ok: #22c55e;
20
+ --color-warn: #f59e0b;
21
+ --color-error: #ef4444;
22
+ --radius: 6px;
23
+ --font-sans: system-ui, -apple-system, sans-serif;
24
+ --font-mono: "JetBrains Mono", "Fira Code", monospace;
25
+ --space: 4px;
26
+ }
27
+
28
+ /* ─── Reset & base ─────────────────────────────────────────────────────── */
29
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
30
+ body {
31
+ background: var(--color-bg);
32
+ color: var(--color-text);
33
+ font-family: var(--font-sans);
34
+ font-size: 14px;
35
+ line-height: 1.6;
36
+ padding: calc(var(--space) * 8);
37
+ max-width: 900px;
38
+ margin: 0 auto;
39
+ }
40
+ h1, h2, h3 { font-weight: 600; margin-bottom: calc(var(--space) * 3); }
41
+ h1 { font-size: 1.5rem; margin-bottom: calc(var(--space) * 6); }
42
+ h2 { font-size: 1.1rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-top: calc(var(--space) * 10); }
43
+ p { color: var(--color-muted); margin-bottom: calc(var(--space) * 4); }
44
+ section { margin-bottom: calc(var(--space) * 12); }
45
+
46
+ /* ─── Card ──────────────────────────────────────────────────────────────── */
47
+ .card {
48
+ background: var(--color-surface);
49
+ border: 1px solid var(--color-border);
50
+ border-radius: var(--radius);
51
+ padding: calc(var(--space) * 5);
52
+ margin-bottom: calc(var(--space) * 4);
53
+ }
54
+
55
+ /* ─── Badge ─────────────────────────────────────────────────────────────── */
56
+ .badge {
57
+ display: inline-block;
58
+ font-size: 11px;
59
+ font-weight: 600;
60
+ padding: 2px 8px;
61
+ border-radius: 999px;
62
+ text-transform: uppercase;
63
+ letter-spacing: 0.04em;
64
+ }
65
+ .badge-ok { background: color-mix(in srgb, var(--color-ok) 15%, transparent); color: var(--color-ok); }
66
+ .badge-warn { background: color-mix(in srgb, var(--color-warn) 15%, transparent); color: var(--color-warn); }
67
+ .badge-error { background: color-mix(in srgb, var(--color-error) 15%, transparent); color: var(--color-error); }
68
+ .badge-info { background: color-mix(in srgb, var(--color-accent) 15%, transparent); color: var(--color-accent); }
69
+
70
+ /* ─── Tabs ──────────────────────────────────────────────────────────────── */
71
+ .tabs { border-bottom: 1px solid var(--color-border); display: flex; gap: calc(var(--space) * 1); margin-bottom: calc(var(--space) * 4); }
72
+ .tab {
73
+ padding: calc(var(--space) * 2) calc(var(--space) * 4);
74
+ cursor: pointer;
75
+ border-bottom: 2px solid transparent;
76
+ color: var(--color-muted);
77
+ font-size: 13px;
78
+ font-weight: 500;
79
+ background: none;
80
+ border-top: none;
81
+ border-left: none;
82
+ border-right: none;
83
+ }
84
+ .tab:hover { color: var(--color-text); }
85
+ .tab.active { border-bottom-color: var(--color-accent); color: var(--color-text); }
86
+ .tab-panel { display: none; }
87
+ .tab-panel.active { display: block; }
88
+
89
+ /* ─── Code block ────────────────────────────────────────────────────────── */
90
+ .code-block {
91
+ background: var(--color-surface);
92
+ border: 1px solid var(--color-border);
93
+ border-radius: var(--radius);
94
+ padding: calc(var(--space) * 4);
95
+ font-family: var(--font-mono);
96
+ font-size: 12px;
97
+ overflow-x: auto;
98
+ white-space: pre;
99
+ color: var(--color-text);
100
+ margin-bottom: calc(var(--space) * 4);
101
+ }
102
+
103
+ /* ─── Diff ──────────────────────────────────────────────────────────────── */
104
+ .diff-block { font-family: var(--font-mono); font-size: 12px; border: 1px solid var(--color-border); border-radius: var(--radius); overflow: hidden; margin-bottom: calc(var(--space) * 4); }
105
+ .diff-line { display: flex; padding: 2px calc(var(--space) * 3); }
106
+ .diff-line-add { background: color-mix(in srgb, var(--color-ok) 10%, transparent); }
107
+ .diff-line-del { background: color-mix(in srgb, var(--color-error) 10%, transparent); }
108
+ .diff-line-ctx { color: var(--color-muted); }
109
+ .diff-gutter { user-select: none; color: var(--color-muted); min-width: 32px; text-align: right; margin-right: calc(var(--space) * 3); }
110
+ .diff-sign { min-width: 12px; color: var(--color-muted); }
111
+ .diff-line-add .diff-sign { color: var(--color-ok); }
112
+ .diff-line-del .diff-sign { color: var(--color-error); }
113
+ </style>
114
+ </head>
115
+ <body>
116
+
117
+ <h1>haac-aikit HTML Design System</h1>
118
+ <p>Reference file for HTML artifacts generated by the model. Edit the CSS custom properties at the top of this file to retheme all output.</p>
119
+
120
+ <section>
121
+ <h2>Card</h2>
122
+ <div class="card">
123
+ <strong>Card title</strong>
124
+ <p>Use cards to group related content. Nest inside grid or flex containers for multi-column layouts.</p>
125
+ </div>
126
+ </section>
127
+
128
+ <section>
129
+ <h2>Badges</h2>
130
+ <span class="badge badge-ok">ok</span>
131
+ <span class="badge badge-warn">warn</span>
132
+ <span class="badge badge-error">error</span>
133
+ <span class="badge badge-info">info</span>
134
+ </section>
135
+
136
+ <section>
137
+ <h2>Tabs</h2>
138
+ <div class="tabs" id="demo-tabs">
139
+ <button class="tab active" data-panel="p1">Option A</button>
140
+ <button class="tab" data-panel="p2">Option B</button>
141
+ <button class="tab" data-panel="p3">Option C</button>
142
+ </div>
143
+ <div id="p1" class="tab-panel active"><div class="card">Content for Option A.</div></div>
144
+ <div id="p2" class="tab-panel"><div class="card">Content for Option B.</div></div>
145
+ <div id="p3" class="tab-panel"><div class="card">Content for Option C.</div></div>
146
+ <script>
147
+ document.querySelectorAll('.tabs').forEach(tabGroup => {
148
+ tabGroup.addEventListener('click', e => {
149
+ const btn = e.target.closest('.tab');
150
+ if (!btn) return;
151
+ tabGroup.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
152
+ btn.classList.add('active');
153
+ const panelId = btn.dataset.panel;
154
+ document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
155
+ document.getElementById(panelId).classList.add('active');
156
+ });
157
+ });
158
+ </script>
159
+ </section>
160
+
161
+ <section>
162
+ <h2>Code block</h2>
163
+ <div class="code-block">const greeting = "hello, world";
164
+ console.log(greeting);</div>
165
+ </section>
166
+
167
+ <section>
168
+ <h2>Diff</h2>
169
+ <div class="diff-block">
170
+ <div class="diff-line diff-line-ctx"><span class="diff-gutter">1</span><span class="diff-sign"> </span><span>import { foo } from './foo';</span></div>
171
+ <div class="diff-line diff-line-del"><span class="diff-gutter">2</span><span class="diff-sign">-</span><span>const x = foo();</span></div>
172
+ <div class="diff-line diff-line-add"><span class="diff-gutter">3</span><span class="diff-sign">+</span><span>const x = await foo();</span></div>
173
+ <div class="diff-line diff-line-ctx"><span class="diff-gutter">4</span><span class="diff-sign"> </span><span>export { x };</span></div>
174
+ </div>
175
+ </section>
176
+
177
+ </body>
178
+ </html>
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: html-artifacts
3
+ description: Use when generating output that would benefit from rich formatting — specs, plans, reports, code review explainers, design prototypes, or custom editors. Teaches when to proactively offer HTML instead of markdown and how to structure each artifact type.
4
+ version: "1.0.0"
5
+ source: haac-aikit
6
+ license: MIT
7
+ ---
8
+
9
+ ## When to use
10
+ - Output is > ~80 lines of content
11
+ - Task involves comparison, multiple options, or visual layout
12
+ - User asks for a spec, plan, report, PR explainer, or prototype
13
+ - User mentions "share", "send to team", or "easy to read"
14
+
15
+ ## Proactive offer rule
16
+ When conditions above are met but the user didn't explicitly ask for HTML, say one sentence before proceeding:
17
+
18
+ > "I can generate this as an HTML artifact for easier reading — want that?"
19
+
20
+ Wait for a yes/no. If yes, proceed with HTML. If no, use markdown.
21
+
22
+ ## Five use-case patterns
23
+
24
+ ### 1. Spec / Planning
25
+ **Trigger:** Long spec, multiple options to compare
26
+ **Structure:** Tabs per option, decision log section, embedded mockup slots
27
+ **Don't:** Skip the decision rationale — that's the whole point of the doc
28
+
29
+ ### 2. Code Review
30
+ **Trigger:** PR explainer, diff walkthrough, architecture audit
31
+ **Structure:** Rendered diff with color, severity badges (ok/warn/error), inline margin annotations
32
+ **Don't:** Show a raw unified diff without color — unreadable
33
+
34
+ ### 3. Report / Research
35
+ **Trigger:** Status report, incident summary, research synthesis
36
+ **Structure:** Executive summary at top, SVG diagrams, section anchors for navigation
37
+ **Don't:** Bury the conclusion — lead with it
38
+
39
+ ### 4. Prototype
40
+ **Trigger:** Animation tuning, layout exploration, parameter tweaking
41
+ **Structure:** Sliders/knobs for live adjustment, preview pane, "copy params" export button
42
+ **Don't:** Ship without an export mechanism — the params need to go somewhere
43
+
44
+ ### 5. Custom Editor
45
+ **Trigger:** Ticket triage, config editing, dataset curation
46
+ **Structure:** Drag/sort or form UI, constraint warnings, "copy as JSON/prompt" export button
47
+ **Don't:** Let the editor be the only output — always export
48
+
49
+ ## Built-in design system
50
+
51
+ Inject this CSS block into every artifact. If the project has `docs/aikit-html-design-system.html`, read it first and use those variable values instead.
52
+
53
+ ```css
54
+ :root {
55
+ --color-bg: #0f1117;
56
+ --color-surface: #1a1d27;
57
+ --color-border: #2e3143;
58
+ --color-text: #e2e8f0;
59
+ --color-muted: #8892a4;
60
+ --color-accent: #6366f1;
61
+ --color-ok: #22c55e;
62
+ --color-warn: #f59e0b;
63
+ --color-error: #ef4444;
64
+ --radius: 6px;
65
+ --font-sans: system-ui, -apple-system, sans-serif;
66
+ --font-mono: "JetBrains Mono", "Fira Code", monospace;
67
+ --space: 4px;
68
+ }
69
+ ```
70
+
71
+ Pre-built components available: `.card`, `.badge` (`.badge-ok/warn/error/info`), `.tabs` + `.tab` + `.tab-panel`, `.code-block`, `.diff-block` + `.diff-line` + `.diff-line-add/del/ctx`.
72
+
73
+ ## Output rules
74
+ - Save to `.aikit/artifacts/<slug>-<timestamp>.html` (this path is gitignored)
75
+ - After saving, print the path and suggest: `open <path>` (macOS) or `xdg-open <path>` (Linux)
76
+ - Pure HTML/CSS/JS only — no external CDN dependencies, no build step
77
+ - Mobile-responsive: use `max-width` + `padding` on body, `<meta name="viewport">`
78
+
79
+ ## Markdown-first rule
80
+ Existing brainstorming and planning skills stay markdown-first. Only switch to HTML when the user accepts the proactive offer or explicitly requests it (e.g. via `/html`). This preserves cross-tool compatibility.
package/dist/cli.mjs CHANGED
@@ -1280,6 +1280,7 @@ function loadCatalog() {
1280
1280
  mcpJson: () => read("mcp/mcp.json"),
1281
1281
  settingsJson: () => read("settings/settings.json"),
1282
1282
  claudeMdReference: () => read("docs/claude-md-reference.md"),
1283
+ htmlDesignSystem: () => read("docs/html-design-system.html"),
1283
1284
  aikitRulesJson: () => read("rules/aikit-rules.json")
1284
1285
  };
1285
1286
  }
@@ -1536,6 +1537,7 @@ async function runSync(argv) {
1536
1537
  results.push(safeWrite(".claude/settings.json", catalog.settingsJson(), { ...opts, useMarkers: false }));
1537
1538
  if (config.scope !== "minimal") {
1538
1539
  results.push(safeWrite("docs/claude-md-reference.md", catalog.claudeMdReference(), { ...opts, useMarkers: false }));
1540
+ results.push(safeWrite("docs/aikit-html-design-system.html", catalog.htmlDesignSystem(), { ...opts, useMarkers: false }));
1539
1541
  results.push(safeWrite(".claude/aikit-rules.json", catalog.aikitRulesJson(), { ...opts, useMarkers: false }));
1540
1542
  results.push(...syncDir("rules/claude-rules", ".claude/rules", opts, [".md"]));
1541
1543
  }