qualia-framework 6.2.10 → 6.3.0
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/AGENTS.md +1 -0
- package/CLAUDE.md +1 -0
- package/README.md +16 -23
- package/bin/cli.js +49 -2
- package/bin/command-surface.js +71 -0
- package/bin/harness-eval.js +296 -0
- package/bin/install.js +17 -20
- package/bin/knowledge-flush.js +21 -10
- package/bin/knowledge.js +1 -1
- package/bin/project-snapshot.js +20 -0
- package/bin/report-payload.js +18 -0
- package/bin/runtime-manifest.js +3 -0
- package/bin/state.js +31 -0
- package/bin/trust-score.js +3 -11
- package/bin/work-packet.js +228 -0
- package/docs/erp-contract.md +81 -1
- package/docs/onboarding.html +0 -11
- package/guide.md +14 -15
- package/hooks/fawzi-approval-guard.js +143 -0
- package/hooks/pre-deploy-gate.js +74 -1
- package/hooks/session-start.js +29 -1
- package/package.json +1 -1
- package/qualia-design/frontend.md +2 -2
- package/rules/codex-goal.md +1 -1
- package/rules/one-opinion.md +2 -2
- package/rules/speed.md +0 -1
- package/skills/qualia/SKILL.md +4 -4
- package/skills/qualia-feature/SKILL.md +1 -1
- package/skills/qualia-fix/SKILL.md +4 -4
- package/skills/qualia-learn/SKILL.md +1 -1
- package/skills/qualia-polish/REFERENCE.md +1 -1
- package/skills/qualia-polish/SKILL.md +19 -4
- package/skills/{qualia-vibe/scripts/extract.mjs → qualia-polish/scripts/vibe-extract.mjs} +4 -4
- package/skills/{qualia-vibe/scripts/tokens.mjs → qualia-polish/scripts/vibe-tokens.mjs} +6 -6
- package/skills/qualia-road/SKILL.md +15 -20
- package/skills/qualia-ship/SKILL.md +12 -5
- package/skills/qualia-verify/SKILL.md +9 -1
- package/templates/help.html +1 -12
- package/tests/bin.test.sh +144 -72
- package/tests/hooks.test.sh +81 -1
- package/tests/install-smoke.test.sh +13 -3
- package/tests/lib.test.sh +145 -3
- package/tests/published-install-smoke.test.sh +4 -3
- package/tests/refs.test.sh +9 -4
- package/tests/runner.js +29 -28
- package/tests/state.test.sh +68 -0
- package/skills/qualia-debug/SKILL.md +0 -193
- package/skills/qualia-flush/SKILL.md +0 -198
- package/skills/qualia-help/SKILL.md +0 -74
- package/skills/qualia-hook-gen/SKILL.md +0 -206
- package/skills/qualia-idk/SKILL.md +0 -166
- package/skills/qualia-issues/SKILL.md +0 -151
- package/skills/qualia-pause/SKILL.md +0 -68
- package/skills/qualia-resume/SKILL.md +0 -52
- package/skills/qualia-skill-new/SKILL.md +0 -173
- package/skills/qualia-triage/SKILL.md +0 -152
- package/skills/qualia-vibe/SKILL.md +0 -229
- package/skills/qualia-zoom/SKILL.md +0 -51
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-debug
|
|
3
|
-
description: "Investigation lane for unclear bugs and weird behavior. Parses symptoms, runs diagnostic scans, identifies root cause, and either reports insufficient evidence or routes actionable repair work to /qualia-fix. Trigger on 'debug', 'find bug', 'why is this broken', 'something is weird', 'investigate', 'root cause', 'not sure what's failing', 'CSS issue', 'slow page', 'performance'."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
- Edit
|
|
8
|
-
- Write
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
- Agent
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# /qualia-debug — Investigative Debugging (one-shot)
|
|
15
|
-
|
|
16
|
-
Parse the symptom. Run diagnostics. Find root cause. Write report, or route to `/qualia-fix` when the repair is actionable. **One-shot — no mandatory user questions.**
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
- `/qualia-debug {symptom}` — investigate a specific symptom
|
|
21
|
-
- `/qualia-debug` — no symptom given: investigate recently-changed files for obvious bugs
|
|
22
|
-
- `/qualia-debug --frontend {symptom}` — layout/z-index/overflow bias
|
|
23
|
-
- `/qualia-debug --perf {symptom}` — performance bias
|
|
24
|
-
|
|
25
|
-
If the user says "fix it" and the expected behavior is known, prefer `/qualia-fix`. Debug is for uncertainty; fix is for repair.
|
|
26
|
-
|
|
27
|
-
## Tool Budget
|
|
28
|
-
|
|
29
|
-
Max 10 Read/Grep/Bash calls for investigation. If you haven't narrowed to root cause in 10, return `INSUFFICIENT EVIDENCE after 10 steps. Narrowed to: {files}. Recommend: {next diagnostic}.` Do not keep guessing.
|
|
30
|
-
|
|
31
|
-
## Process
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
node ${QUALIA_BIN}/qualia-ui.js banner debug
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### 1. Parse Symptom from $ARGUMENTS
|
|
38
|
-
|
|
39
|
-
- If arguments provided → that's the symptom. Extract: what's broken, where (file/page/feature), when (on click? on load? after change?).
|
|
40
|
-
- If arguments empty → run `git diff HEAD~3 --stat` to find recently-touched files. Treat those as the suspect set. Symptom = "something in recent changes".
|
|
41
|
-
|
|
42
|
-
### 2. Check Known Fixes First (cheap)
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
node ${QUALIA_BIN}/knowledge.js search "{symptom_keywords}"
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
If a known fix matches, apply it and jump to step 5 (verify). Known fixes are pre-verified patterns — no need to re-investigate.
|
|
49
|
-
|
|
50
|
-
### 3. Diagnostic Scan
|
|
51
|
-
|
|
52
|
-
Run the scan matching the symptom type. All commands in a scan block run as parallel Bash calls in a single response turn.
|
|
53
|
-
|
|
54
|
-
**General mode (default):**
|
|
55
|
-
```bash
|
|
56
|
-
# Compile errors
|
|
57
|
-
npx tsc --noEmit 2>&1 | grep "error TS" | head -20
|
|
58
|
-
|
|
59
|
-
# Empty catch / swallowed errors
|
|
60
|
-
grep -rn "catch\s*{}\|catch\s*(.*)\s*{\s*}" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | head -10
|
|
61
|
-
|
|
62
|
-
# Recent console.error or thrown errors
|
|
63
|
-
grep -rn "console\.error\|throw new" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | head -10
|
|
64
|
-
|
|
65
|
-
# Broken imports
|
|
66
|
-
npx tsc --noEmit 2>&1 | grep -i "Cannot find module\|has no exported"
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Frontend mode (`--frontend`):**
|
|
70
|
-
```bash
|
|
71
|
-
# Stacking context audit (z-index issues)
|
|
72
|
-
grep -rn "z-index\|z-\[" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | head -20
|
|
73
|
-
|
|
74
|
-
# Overflow candidates (horizontal scroll, clipping)
|
|
75
|
-
grep -rn "100vw\|overflow.*hidden\|overflow-x\|position.*fixed" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | head -15
|
|
76
|
-
|
|
77
|
-
# Fixed dimensions breaking mobile
|
|
78
|
-
grep -rn "width:.*[0-9]\+px\|height:.*[0-9]\+px\|w-\[[0-9]\+px\|h-\[[0-9]\+px" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | grep -v "min-\|max-" | head -10
|
|
79
|
-
|
|
80
|
-
# Flex/grid blowout candidates
|
|
81
|
-
grep -rn "flex\|grid" --include="*.tsx" app/ components/ src/ 2>/dev/null | grep -v "min-w-0\|minmax(0" | wc -l
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Perf mode (`--perf`):**
|
|
85
|
-
```bash
|
|
86
|
-
# Sequential awaits that should be Promise.all
|
|
87
|
-
grep -rn "const.*=.*await" --include="*.tsx" --include="*.ts" app/ src/ 2>/dev/null | grep -v "Promise.all\|Promise.allSettled" | head -15
|
|
88
|
-
|
|
89
|
-
# Large files
|
|
90
|
-
find app/ components/ src/ -name "*.tsx" -o -name "*.ts" 2>/dev/null | xargs wc -l 2>/dev/null | sort -rn | head -10
|
|
91
|
-
|
|
92
|
-
# Missing next/image
|
|
93
|
-
grep -rn "<img " --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null | grep -v "next/image" | wc -l
|
|
94
|
-
|
|
95
|
-
# No dynamic imports (possible big bundles)
|
|
96
|
-
grep -rn "import(\|next/dynamic" --include="*.tsx" --include="*.ts" app/ src/ 2>/dev/null | wc -l
|
|
97
|
-
|
|
98
|
-
# Client-boundary usage
|
|
99
|
-
grep -rln "'use client'" --include="*.tsx" app/ components/ src/ 2>/dev/null | wc -l
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### 4. Form Hypothesis + Route or Apply Minimal Fix
|
|
103
|
-
|
|
104
|
-
From the diagnostic output, state the root cause in one sentence with `file:line` citation. No hedging — either you have evidence or you write `INSUFFICIENT EVIDENCE` and return (step 6).
|
|
105
|
-
|
|
106
|
-
If the user explicitly asked for repair and the fix is <= 3 files, route to `/qualia-fix {symptom}` with the root cause summary. If this debug invocation is already mid-repair, apply the minimal fix here for backward compatibility.
|
|
107
|
-
|
|
108
|
-
Apply the minimal fix:
|
|
109
|
-
- Only edit files whose contents caused the symptom
|
|
110
|
-
- One concept per commit — don't fold in cleanup
|
|
111
|
-
- Don't refactor adjacent code
|
|
112
|
-
- If the fix touches > 3 files, stop and ask the user first (major refactor disguised as a debug)
|
|
113
|
-
|
|
114
|
-
### 5. Verify Fix
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
# TypeScript still compiles?
|
|
118
|
-
npx tsc --noEmit 2>&1 | grep -c "error TS" # Expect 0
|
|
119
|
-
|
|
120
|
-
# Symptom reproduction — ideally a grep that would have matched the bug
|
|
121
|
-
# and now returns empty:
|
|
122
|
-
grep -rn "{pattern that represented the bug}" {scope} 2>/dev/null
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
If the verification fails, revert and return to step 3 with narrower hypothesis.
|
|
126
|
-
|
|
127
|
-
### 6. Write DEBUG Report
|
|
128
|
-
|
|
129
|
-
Create the report directory and write to `.planning/reports/debug/DEBUG-{YYYY-MM-DD-HHMM}.md`:
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
mkdir -p .planning/reports/debug
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
```markdown
|
|
136
|
-
# Debug Report — {YYYY-MM-DD HH:MM}
|
|
137
|
-
|
|
138
|
-
**Symptom:** {user description or "recent changes" if no args}
|
|
139
|
-
**Mode:** general | frontend | perf
|
|
140
|
-
**Tool calls used:** {N}/10
|
|
141
|
-
|
|
142
|
-
## Investigation
|
|
143
|
-
- Diagnostic scans run: {list}
|
|
144
|
-
- Files examined: {list}
|
|
145
|
-
- Patterns searched: {list}
|
|
146
|
-
|
|
147
|
-
## Root Cause
|
|
148
|
-
{file:line} — "{quoted problematic code}" — {explanation of why it caused the symptom}
|
|
149
|
-
|
|
150
|
-
## Fix Applied
|
|
151
|
-
- Files: {list}
|
|
152
|
-
- Diff summary: {one paragraph}
|
|
153
|
-
- Verification: {commands run + results}
|
|
154
|
-
|
|
155
|
-
## Related Observations
|
|
156
|
-
- {any adjacent issues noticed but NOT fixed in this debug pass}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### 7. Commit
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
git add {specific files you changed}
|
|
163
|
-
git commit -m "fix: {what was broken and why}"
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## INSUFFICIENT EVIDENCE Return
|
|
167
|
-
|
|
168
|
-
If you exhaust the 10-call budget without a confident root cause:
|
|
169
|
-
|
|
170
|
-
```markdown
|
|
171
|
-
# Debug Report — {YYYY-MM-DD HH:MM}
|
|
172
|
-
|
|
173
|
-
**Symptom:** {description}
|
|
174
|
-
**Outcome:** INSUFFICIENT EVIDENCE after 10 inspection steps
|
|
175
|
-
|
|
176
|
-
## Narrowed To
|
|
177
|
-
- Files examined: {list}
|
|
178
|
-
- Ruled out: {list}
|
|
179
|
-
- Remaining suspects: {list}
|
|
180
|
-
|
|
181
|
-
## Recommended Next Diagnostic
|
|
182
|
-
- {specific next step for the user — e.g., "run `npm run dev` and watch browser console for the specific error", or "add console.log at file:line and reproduce"}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Do NOT apply a speculative fix. Return the report and stop.
|
|
186
|
-
|
|
187
|
-
## Rules
|
|
188
|
-
|
|
189
|
-
- **No mandatory questions.** This is one-shot. If symptom args are missing, investigate recent changes.
|
|
190
|
-
- **Root cause or INSUFFICIENT EVIDENCE** — no "probably" fixes.
|
|
191
|
-
- **Minimal fix only.** One concept, one commit. No refactors dressed as debug. Prefer `/qualia-fix` for explicit repair requests.
|
|
192
|
-
- **Tool budget is hard.** 10 calls, then stop.
|
|
193
|
-
- **Every investigation gets a DEBUG report in `.planning/reports/debug/`** — creates a searchable record without cluttering the root.
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-flush
|
|
3
|
-
description: "Promote daily-log raw entries to the curated knowledge tier — Karpathy-style raw→wiki flush. Reads ${QUALIA_KNOWLEDGE}/daily-log/*.md, identifies recurring patterns and decisions, writes them to ${QUALIA_KNOWLEDGE}/concepts/{topic}.md, updates index.md. Trigger on 'flush memory', 'promote learnings', 'consolidate logs', 'qualia-flush', 'process daily logs', or run weekly."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
- Write
|
|
8
|
-
- Edit
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# /qualia-flush — Promote Raw Daily Logs to Curated Concepts
|
|
14
|
-
|
|
15
|
-
Closes the **raw → wiki** loop in the Qualia memory layer. The Stop hook
|
|
16
|
-
(`hooks/stop-session-log.js`) appends mechanical session checkpoints to
|
|
17
|
-
`${QUALIA_KNOWLEDGE}/daily-log/{date}.md`.
|
|
18
|
-
Those entries accumulate but stay raw — they describe what happened, not
|
|
19
|
-
what to do about it. This skill reads the recent daily-log entries with an
|
|
20
|
-
LLM (you) and writes durable concepts that the builder, planner, and
|
|
21
|
-
debug skills will surface later via `node ${QUALIA_BIN}/knowledge.js`.
|
|
22
|
-
|
|
23
|
-
Inspired by Karpathy's LLM knowledge bases and Cole Medin's self-evolving
|
|
24
|
-
Claude memory pattern (NotebookLM, 2026-04-25). Both run a daily/weekly
|
|
25
|
-
flush that promotes raw observations into structured wiki articles. We do
|
|
26
|
-
the same — manually-triggered, internal-data only, no vector DB.
|
|
27
|
-
|
|
28
|
-
## When to run
|
|
29
|
-
|
|
30
|
-
- **Manually:** `/qualia-flush` whenever the daily-log feels rich. Once a week
|
|
31
|
-
is the recommended cadence. More than once a day is wasteful — the
|
|
32
|
-
signal-to-noise ratio is too low at single-day windows.
|
|
33
|
-
- **CLI runner:** `qualia-framework flush` wraps the cron-friendly
|
|
34
|
-
`bin/knowledge-flush.js` non-interactive runner.
|
|
35
|
-
|
|
36
|
-
## Inputs
|
|
37
|
-
|
|
38
|
-
- `--days N` (optional, default 14) — how many days of daily-log to consider
|
|
39
|
-
- `--project NAME` (optional) — only flush entries for one project
|
|
40
|
-
- `--dry-run` (optional) — print the proposed writes, don't touch disk
|
|
41
|
-
|
|
42
|
-
If the user invokes the skill bare (no args), default to `--days 14` and
|
|
43
|
-
all projects. Show a one-line preview before writing anything destructive.
|
|
44
|
-
|
|
45
|
-
## Process
|
|
46
|
-
|
|
47
|
-
### 1. Banner + check the floor
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
node ${QUALIA_BIN}/qualia-ui.js banner flush 2>/dev/null || true
|
|
51
|
-
|
|
52
|
-
# Resolve the knowledge dir. Fail loud if it doesn't exist — flush is
|
|
53
|
-
# meaningless without a daily-log to read.
|
|
54
|
-
KNOWLEDGE_DIR="$HOME/.claude/knowledge"
|
|
55
|
-
DAILY_DIR="$KNOWLEDGE_DIR/daily-log"
|
|
56
|
-
if [ ! -d "$DAILY_DIR" ]; then
|
|
57
|
-
echo "QUALIA: No daily-log at $DAILY_DIR — Stop hook hasn't run yet, or knowledge layer wasn't initialized."
|
|
58
|
-
echo "Run: npx qualia-framework@latest install"
|
|
59
|
-
exit 1
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
# Default 14-day window. Date math is cross-platform-safe with Node.
|
|
63
|
-
WINDOW_DAYS="${WINDOW_DAYS:-14}"
|
|
64
|
-
node -e "
|
|
65
|
-
const d = new Date();
|
|
66
|
-
d.setDate(d.getDate() - $WINDOW_DAYS);
|
|
67
|
-
console.log(d.toISOString().split('T')[0]);
|
|
68
|
-
" > /tmp/qualia-flush-cutoff
|
|
69
|
-
CUTOFF=$(cat /tmp/qualia-flush-cutoff)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 2. Collect the daily-log entries in window
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# Iterate every file in daily-log/ whose name (YYYY-MM-DD.md) is >= CUTOFF.
|
|
76
|
-
# Concatenate them into one stream so the LLM (you) can scan as one corpus.
|
|
77
|
-
ls "$DAILY_DIR"/*.md 2>/dev/null | while read -r f; do
|
|
78
|
-
base=$(basename "$f" .md)
|
|
79
|
-
if [ "$base" \> "$CUTOFF" ] || [ "$base" = "$CUTOFF" ]; then
|
|
80
|
-
echo "=== $base ==="
|
|
81
|
-
cat "$f"
|
|
82
|
-
echo ""
|
|
83
|
-
fi
|
|
84
|
-
done
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
You now have the raw stream. Read it.
|
|
88
|
-
|
|
89
|
-
### 3. Identify what's worth promoting
|
|
90
|
-
|
|
91
|
-
Read every entry. Group by project. Look for these signals — these are
|
|
92
|
-
the things that promote into the wiki:
|
|
93
|
-
|
|
94
|
-
| Signal in raw entry | What to extract | Goes to |
|
|
95
|
-
|---|---|---|
|
|
96
|
-
| Same fix appears in 2+ sessions | A common fix recipe | `common-fixes.md` (via `knowledge.js append --type fix`) |
|
|
97
|
-
| A pattern shows up in 3+ projects | A reusable pattern | `learned-patterns.md` (via `knowledge.js append --type pattern`) |
|
|
98
|
-
| A client-name or project preference recurs | A client preference | `client-prefs.md` (via `knowledge.js append --type client`) |
|
|
99
|
-
| A new technology/library used successfully | A stack note | `concepts/{tech}.md` (new file, Write directly) |
|
|
100
|
-
| A recurring failure mode (verify-fail, regression) | A pitfall | `learned-patterns.md` framed as "anti-pattern: …" |
|
|
101
|
-
|
|
102
|
-
Things to **NOT** promote:
|
|
103
|
-
- Single-occurrence quirks (they're noise until they recur).
|
|
104
|
-
- Bare commit/branch info — that's already in git, no value duplicating.
|
|
105
|
-
- Anything containing secrets, tokens, customer PII. The knowledge layer
|
|
106
|
-
is plain markdown, never put secrets here.
|
|
107
|
-
- Entries from `--dry-run` runs of other skills (they'll show as activity
|
|
108
|
-
but didn't actually do anything).
|
|
109
|
-
|
|
110
|
-
### 4. Write the promotions
|
|
111
|
-
|
|
112
|
-
For each thing worth promoting, use the loader's `append`:
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
node ${QUALIA_BIN}/knowledge.js append \
|
|
116
|
-
--type {pattern|fix|client} \
|
|
117
|
-
--title "{Concise title — what's the recurring thing?}" \
|
|
118
|
-
--body "{The promoted lesson. Be specific. Include the project name(s) and dates where this pattern was observed so future you can verify.}" \
|
|
119
|
-
--project "{specific project, or 'general' if cross-project}" \
|
|
120
|
-
--context "Promoted by /qualia-flush from daily-log entries on {dates}"
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
For a brand-new topic that doesn't fit pattern/fix/client (e.g. a Stripe
|
|
124
|
-
integration approach worth its own file), Write to
|
|
125
|
-
`${QUALIA_KNOWLEDGE}/concepts/{topic}.md`. Then **update `index.md`** so the
|
|
126
|
-
new file is reachable — list it under "What's where" with one line:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
# After writing concepts/stripe-checkout.md:
|
|
130
|
-
node ${QUALIA_BIN}/knowledge.js path stripe-checkout
|
|
131
|
-
# Returned path = ${QUALIA_KNOWLEDGE}/stripe-checkout.md (NOTE: top-level, not concepts/)
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
> **Loader behavior:** `knowledge.js load <name>` resolves bare names by walking
|
|
135
|
-
> top-level + subdirectories (`concepts/`, `daily-log/`) for an exact match.
|
|
136
|
-
> Write durable entries to `concepts/{topic}.md`; the loader will find them.
|
|
137
|
-
|
|
138
|
-
### 5. Mark the window as flushed
|
|
139
|
-
|
|
140
|
-
Write a stamp file so subsequent flushes can default to "since the last
|
|
141
|
-
flush" instead of "last 14 days":
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
date -u +%Y-%m-%dT%H:%M:%SZ > "$HOME/.claude/.qualia-last-flush"
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### 6. Summarize
|
|
148
|
-
|
|
149
|
-
Print to the user, in plain language:
|
|
150
|
-
|
|
151
|
-
- N daily-log files scanned (date range)
|
|
152
|
-
- M promotions written (with file:title for each)
|
|
153
|
-
- K things considered but not promoted (single-occurrence — wait for them to recur)
|
|
154
|
-
|
|
155
|
-
Format:
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
⬢ Flushed daily-log {start} → {end} ({N} files, {total entries} entries)
|
|
159
|
-
Promoted to wiki:
|
|
160
|
-
+ learned-patterns.md "Supabase RLS in same migration" (3 sessions, 2 projects)
|
|
161
|
-
+ common-fixes.md "next/font crash on Vercel" (2 sessions)
|
|
162
|
-
+ concepts/voice-agent-call-state.md (new file)
|
|
163
|
-
Skipped {K} single-occurrence entries — will revisit if they recur.
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Style
|
|
167
|
-
|
|
168
|
-
- **Be conservative.** False-positive promotions (writing noise as if it's a
|
|
169
|
-
pattern) pollute the wiki and erode trust. Better to skip a candidate and
|
|
170
|
-
let it recur next week than to inflate the curated tier.
|
|
171
|
-
- **Cite your sources.** Every promoted entry should reference the
|
|
172
|
-
daily-log dates that sourced it, in the `--context` field. If a future
|
|
173
|
-
flush wants to update it, the trail is there.
|
|
174
|
-
- **Keep titles short.** `--title "Supabase RLS same migration"` not `"You should always remember that when working with Supabase you need to..."`. The body is for nuance.
|
|
175
|
-
- **Don't promote private projects across boundaries.** A pattern from
|
|
176
|
-
Project A is fine to promote as cross-project ONLY if it generalizes.
|
|
177
|
-
Client-specific things stay client-specific (`--type client --project X`).
|
|
178
|
-
|
|
179
|
-
## Anti-patterns
|
|
180
|
-
|
|
181
|
-
- **Mass-promoting everything:** if you found "promotions" for 90% of
|
|
182
|
-
daily-log entries, you're labeling, not promoting. Be selective.
|
|
183
|
-
- **Re-promoting on every flush:** before appending, run
|
|
184
|
-
`node ${QUALIA_BIN}/knowledge.js search "{title keywords}"` to check if
|
|
185
|
-
the pattern already exists. If it does, either update it (find by `**ID:**`
|
|
186
|
-
line) or skip — never duplicate.
|
|
187
|
-
- **Hand-writing to `learned-patterns.md` etc. directly:** always go
|
|
188
|
-
through `knowledge.js append` so the canonical entry format and ID
|
|
189
|
-
generation stay consistent. This skill is the only sanctioned promoter,
|
|
190
|
-
but even it uses the loader for writes.
|
|
191
|
-
|
|
192
|
-
## Output contract
|
|
193
|
-
|
|
194
|
-
If invoked with `--dry-run`, print the proposed writes and exit without
|
|
195
|
-
touching disk. Otherwise, after step 6 returns the summary, the skill is
|
|
196
|
-
done — no follow-up prompts. The user sees the summary and the wiki tier
|
|
197
|
-
has new entries that are immediately reachable to every other skill via
|
|
198
|
-
the loader.
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-help
|
|
3
|
-
description: "Open the BROWSER HTML reference for the Qualia Framework — themed page with all commands, rules, services, and the road. The default when a browser is available. For terminal-only output (SSH, headless), use /qualia-road. Triggers: 'help', 'how does this work', 'show me the commands', 'qualia help', 'reference', 'open the docs'."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# /qualia-help — Framework Reference
|
|
10
|
-
|
|
11
|
-
Opens a Qualia-themed HTML reference guide in your default browser.
|
|
12
|
-
|
|
13
|
-
## Process
|
|
14
|
-
|
|
15
|
-
### 1. Generate the HTML
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Read the template and inject the current version.
|
|
19
|
-
# Prefer .qualia-config.json; fall back to the framework package.json; last resort is the
|
|
20
|
-
# literal string "latest" so the UI never lies about a specific version.
|
|
21
|
-
VERSION=$(node -e "
|
|
22
|
-
const fs = require('fs'), path = require('path'), os = require('os');
|
|
23
|
-
const cfg = path.join(os.homedir(), '.claude', '.qualia-config.json');
|
|
24
|
-
const pkg = path.join(os.homedir(), '.claude', 'qualia-framework', 'package.json');
|
|
25
|
-
try { const v = JSON.parse(fs.readFileSync(cfg,'utf8')).version; if (v) { console.log(v); process.exit(0); } } catch {}
|
|
26
|
-
try { const v = JSON.parse(fs.readFileSync(pkg,'utf8')).version; if (v) { console.log('v'+v); process.exit(0); } } catch {}
|
|
27
|
-
console.log('latest');
|
|
28
|
-
" 2>/dev/null || echo "latest")
|
|
29
|
-
TEMPLATE="$HOME/.claude/qualia-templates/help.html"
|
|
30
|
-
OUTPUT="/tmp/qualia-help.html"
|
|
31
|
-
|
|
32
|
-
# If template doesn't exist in the user home, check the installed framework copy.
|
|
33
|
-
if [ ! -f "$TEMPLATE" ]; then
|
|
34
|
-
for CANDIDATE in "$HOME/.claude/qualia-framework/templates/help.html"; do
|
|
35
|
-
if [ -f "$CANDIDATE" ]; then TEMPLATE="$CANDIDATE"; break; fi
|
|
36
|
-
done
|
|
37
|
-
fi
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 2. Inject version and open
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# Replace {{VERSION}} placeholder with actual version
|
|
44
|
-
sed "s/{{VERSION}}/$VERSION/g" "$TEMPLATE" > "$OUTPUT"
|
|
45
|
-
|
|
46
|
-
# Open in default browser (cross-platform)
|
|
47
|
-
if command -v xdg-open &>/dev/null; then
|
|
48
|
-
xdg-open "$OUTPUT" # Linux
|
|
49
|
-
elif command -v open &>/dev/null; then
|
|
50
|
-
open "$OUTPUT" # macOS
|
|
51
|
-
elif command -v start &>/dev/null; then
|
|
52
|
-
start "$OUTPUT" # Windows (Git Bash)
|
|
53
|
-
else
|
|
54
|
-
echo "Open this file in your browser: $OUTPUT"
|
|
55
|
-
fi
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 3. Confirm
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
node ${QUALIA_BIN}/qualia-ui.js banner router
|
|
62
|
-
node ${QUALIA_BIN}/qualia-ui.js ok "Reference guide opened in browser"
|
|
63
|
-
node ${QUALIA_BIN}/qualia-ui.js info "File: /tmp/qualia-help.html"
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
If the browser does not open automatically, tell the user the file path so they can open it manually.
|
|
67
|
-
|
|
68
|
-
## Notes
|
|
69
|
-
|
|
70
|
-
- The HTML file is self-contained — no external dependencies except Google Fonts
|
|
71
|
-
- Works offline after first load (fonts cache)
|
|
72
|
-
- Qualia-themed: dark background, teal accents, Outfit + Inter fonts
|
|
73
|
-
- Shows: The Road, all commands grouped, verification scoring, rules, stack, GitHub orgs
|
|
74
|
-
- Version is injected dynamically from .qualia-config.json
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: qualia-hook-gen
|
|
3
|
-
description: "Take a project's CLAUDE.md or rules/*.md instruction and convert it deterministically into a Claude Code pre-tool-use hook. Generates block-{cmd}.sh + the settings.json patch + activation steps. Lets users actually shrink their CLAUDE.md instead of just hearing the instruction-budget advice. Trigger on 'qualia-hook-gen', 'turn this rule into a hook', 'enforce this deterministically', 'block npm', 'force pnpm', 'convert claude.md to hooks', 'shrink my instruction budget'."
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Bash
|
|
6
|
-
- Read
|
|
7
|
-
- Write
|
|
8
|
-
- Edit
|
|
9
|
-
- Grep
|
|
10
|
-
- Glob
|
|
11
|
-
argument-hint: "[--rule \"text\"] [--from CLAUDE.md] [--name HOOK_NAME] [--scope global|project] [--dry-run]"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# /qualia-hook-gen — Convert instructions → deterministic hooks
|
|
15
|
-
|
|
16
|
-
LLMs have a realistic instruction budget of ~300-500 instructions before quality degrades (Matt Pocock). A line in CLAUDE.md like "use pnpm not npm" burns budget on EVERY request — even when the task has nothing to do with package management. Worse, it's non-deterministic: the model can still run `npm install` if it forgets.
|
|
17
|
-
|
|
18
|
-
The fix: convert that instruction into a deterministic `pre-tool-use` hook. The hook blocks the wrong command (or rewrites it to the right one) at execution time, frees the instruction budget, and works regardless of context window state.
|
|
19
|
-
|
|
20
|
-
## When to use
|
|
21
|
-
|
|
22
|
-
- Your CLAUDE.md has 50+ lines and you want to slim it
|
|
23
|
-
- A specific instruction is enforceable as a CLI rule (use X not Y, never run Z, redirect A to B)
|
|
24
|
-
- You want a hook for a specific failure mode (e.g., "always use --force-with-lease, never --force")
|
|
25
|
-
|
|
26
|
-
## What it does NOT do
|
|
27
|
-
|
|
28
|
-
- Hooks for stylistic guidance (e.g., "prefer composition over inheritance") — that's not enforceable by command match. Stays in skills.
|
|
29
|
-
- Hooks for non-deterministic checks (e.g., "validate the design feel"). Use `/qualia-polish` instead.
|
|
30
|
-
- Hooks that need state across multiple commands. Use Qualia's existing state.js machinery.
|
|
31
|
-
|
|
32
|
-
## Process
|
|
33
|
-
|
|
34
|
-
### 1. Identify the rule
|
|
35
|
-
|
|
36
|
-
Three input modes:
|
|
37
|
-
|
|
38
|
-
| Mode | Source |
|
|
39
|
-
|---|---|
|
|
40
|
-
| `--rule "..."` | Direct argument (e.g. `--rule "use pnpm not npm"`) |
|
|
41
|
-
| `--from CLAUDE.md` | Pull instructions from the file, list them, let user pick |
|
|
42
|
-
| (no arg) | Read CLAUDE.md, scan for enforceable rules, propose top 3 candidates |
|
|
43
|
-
|
|
44
|
-
### 2. Classify enforceability
|
|
45
|
-
|
|
46
|
-
For the chosen rule, classify into one of three patterns:
|
|
47
|
-
|
|
48
|
-
| Pattern | Example | Hook shape |
|
|
49
|
-
|---|---|---|
|
|
50
|
-
| **Block** | "never use `git push --force` to main" | exit 2 with message if pattern matches |
|
|
51
|
-
| **Rewrite** | "use pnpm not npm" | exit 2 with message guiding to alternative |
|
|
52
|
-
| **Warn** | "prefer next/image over <img>" | exit 0 but print warning to stderr |
|
|
53
|
-
|
|
54
|
-
If the rule isn't classifiable as any of these — i.e. it's stylistic or judgment-based — HALT with: "This rule isn't deterministically enforceable. Keep it in CLAUDE.md or move to a skill. Examples of enforceable rules: package-manager redirects, destructive-command blocks, file-path enforcement."
|
|
55
|
-
|
|
56
|
-
### 3. Generate the hook script
|
|
57
|
-
|
|
58
|
-
Write to `hooks/block-{name}.js` (Node, cross-platform — same shape as existing hooks):
|
|
59
|
-
|
|
60
|
-
```javascript
|
|
61
|
-
#!/usr/bin/env node
|
|
62
|
-
// hooks/block-{name}.js — auto-generated by /qualia-hook-gen
|
|
63
|
-
// Original instruction: "{rule text}"
|
|
64
|
-
// Pattern: {block | rewrite | warn}
|
|
65
|
-
// Generated: {ISO date}
|
|
66
|
-
|
|
67
|
-
const { readFileSync } = require("fs");
|
|
68
|
-
let payload;
|
|
69
|
-
try { payload = JSON.parse(readFileSync(0, "utf8")); } catch { process.exit(0); }
|
|
70
|
-
const cmd = (payload.tool_input && payload.tool_input.command) || "";
|
|
71
|
-
|
|
72
|
-
// Match condition (regex from rule classification)
|
|
73
|
-
if (!/{matcher}/i.test(cmd)) process.exit(0); // not our concern
|
|
74
|
-
|
|
75
|
-
// Action
|
|
76
|
-
console.error("⚠ Qualia hook ({name}): {message}");
|
|
77
|
-
console.error(" Suggested: {suggested_alt}");
|
|
78
|
-
process.exit(2); // 2 = BLOCK in Claude Code hook protocol
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
The exact matcher + message + suggestion are filled by the synthesizer based on the rule classification.
|
|
82
|
-
|
|
83
|
-
### 4. Generate the settings.json patch
|
|
84
|
-
|
|
85
|
-
```json
|
|
86
|
-
{
|
|
87
|
-
"hooks": {
|
|
88
|
-
"PreToolUse": [
|
|
89
|
-
{
|
|
90
|
-
"matcher": "Bash",
|
|
91
|
-
"hooks": [
|
|
92
|
-
{
|
|
93
|
-
"type": "command",
|
|
94
|
-
"if": "Bash({if-condition})",
|
|
95
|
-
"command": "node \"${HOME}/.claude/hooks/block-{name}.js\"",
|
|
96
|
-
"timeout": 5,
|
|
97
|
-
"statusMessage": "⬢ Checking {what}..."
|
|
98
|
-
}
|
|
99
|
-
]
|
|
100
|
-
}
|
|
101
|
-
]
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
The `if` condition narrows when the hook fires (e.g., `Bash(npm*)` to fire only on npm). Saves cycles by skipping the hook entirely on irrelevant commands.
|
|
107
|
-
|
|
108
|
-
### 5. Test the hook
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
# Simulate a triggering command
|
|
112
|
-
echo '{"tool_input":{"command":"{triggering_example}"}}' | \
|
|
113
|
-
node hooks/block-{name}.js
|
|
114
|
-
echo "Exit: $?" # should be 2
|
|
115
|
-
|
|
116
|
-
# Simulate a non-triggering command
|
|
117
|
-
echo '{"tool_input":{"command":"{safe_example}"}}' | \
|
|
118
|
-
node hooks/block-{name}.js
|
|
119
|
-
echo "Exit: $?" # should be 0
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
If the test passes, proceed. If not, debug the matcher regex.
|
|
123
|
-
|
|
124
|
-
### 6. Activate
|
|
125
|
-
|
|
126
|
-
Two scopes:
|
|
127
|
-
|
|
128
|
-
| Scope | Action |
|
|
129
|
-
|---|---|
|
|
130
|
-
| `--scope project` (default for project rules) | Add the patch to `.claude/settings.json` in the project root |
|
|
131
|
-
| `--scope global` | Add to `${QUALIA_HOME}/settings.json`. Use only if rule applies to ALL projects |
|
|
132
|
-
|
|
133
|
-
Use the existing settings-merge logic from `bin/install.js:756-778` (preserves user fields, atomic write, backup-before-overwrite).
|
|
134
|
-
|
|
135
|
-
### 7. Suggest CLAUDE.md slim
|
|
136
|
-
|
|
137
|
-
After activating, scan CLAUDE.md / `rules/*.md` for the original instruction. If found, suggest the user remove it (don't auto-remove — let the user verify the hook works first):
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
✓ Hook installed: hooks/block-{name}.js
|
|
141
|
-
✓ Settings patched: .claude/settings.json
|
|
142
|
-
ℹ You can now remove this line from CLAUDE.md (the hook enforces it deterministically):
|
|
143
|
-
> "{original instruction}"
|
|
144
|
-
ℹ Test with: echo '{"tool_input":{"command":"{triggering_example}"}}' | node hooks/block-{name}.js
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### 8. Commit
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
git add hooks/block-{name}.js .claude/settings.json
|
|
151
|
-
git -c user.name="Qualia Solutions" -c user.email="info@qualiasolutions.net" \
|
|
152
|
-
commit -m "feat(hook): block-{name} — enforces \"{rule}\" deterministically"
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## Examples
|
|
156
|
-
|
|
157
|
-
**Block npm in favor of pnpm:**
|
|
158
|
-
```
|
|
159
|
-
/qualia-hook-gen --rule "use pnpm not npm"
|
|
160
|
-
→ hooks/block-npm.js (matches /^\s*npm\s+(install|i|run|exec)/, exit 2)
|
|
161
|
-
→ .claude/settings.json (PreToolUse > Bash > if: Bash(npm*))
|
|
162
|
-
→ "npm install" now blocks with: "Use pnpm not npm. Run: pnpm install"
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
**Block destructive git on main:**
|
|
166
|
-
```
|
|
167
|
-
/qualia-hook-gen --rule "never push --force to main"
|
|
168
|
-
→ hooks/block-force-push-main.js (matches /git push.*--force.*main/)
|
|
169
|
-
→ Already covered by hooks/git-guardrails.js — surface this overlap and skip
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**Force /server/ for service_role usage:**
|
|
173
|
-
```
|
|
174
|
-
/qualia-hook-gen --rule "service_role only in lib/server/*"
|
|
175
|
-
→ Not enforceable as a CLI hook (it's a code-level rule).
|
|
176
|
-
→ HALT with recommendation: ESLint rule or pre-deploy-gate.js entry instead.
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
## Token discipline
|
|
180
|
-
|
|
181
|
-
This skill itself is short by design (~150 lines SKILL.md). REFERENCE.md (if added later) only carries verbatim hook templates. The whole point of `/qualia-hook-gen` is to REDUCE token cost across a project, not add to it.
|
|
182
|
-
|
|
183
|
-
Per-invocation: ~3K tokens for the rule-classification + hook-template synthesis. Net savings: every subsequent request saves the ~50-200 tokens that the moved CLAUDE.md instruction was costing.
|
|
184
|
-
|
|
185
|
-
## Failure modes
|
|
186
|
-
|
|
187
|
-
| Symptom | Cause | Action |
|
|
188
|
-
|---|---|---|
|
|
189
|
-
| Rule isn't a CLI command | Stylistic / judgment-based | HALT with recommendation: skill or ESLint rule |
|
|
190
|
-
| Matcher would catch too much | Regex too greedy | Tighten with `--name` and explicit pattern; user-confirm before write |
|
|
191
|
-
| Hook conflicts with existing | Same command already hooked | Surface the conflict; refuse to overwrite without `--force` |
|
|
192
|
-
| Settings.json malformed | Pre-existing bad JSON | Refuse to patch; ask user to fix settings.json first |
|
|
193
|
-
| `node` not on hook PATH | Cross-platform issue | Use `process.execPath` resolution; framework's existing hooks handle this |
|
|
194
|
-
|
|
195
|
-
## Rules
|
|
196
|
-
|
|
197
|
-
1. **Hook is determinism, skill is guidance.** Hooks can only block/rewrite/warn on CLI patterns. Stylistic rules stay in skills.
|
|
198
|
-
2. **Never overwrite an existing hook silently.** If `hooks/block-{name}.js` exists, surface and ask.
|
|
199
|
-
3. **Test before committing.** The hook must pass the trigger + non-trigger smoke tests before commit.
|
|
200
|
-
4. **Suggest CLAUDE.md cleanup.** After install, surface the now-redundant CLAUDE.md line. Don't auto-delete — user verifies the hook works first.
|
|
201
|
-
5. **Match Qualia's hook shape.** All hooks are pure Node, cross-platform, exit 0/2. No `.sh` scripts (Windows compat).
|
|
202
|
-
|
|
203
|
-
## Pairs with
|
|
204
|
-
|
|
205
|
-
- `/qualia-optimize --deepen` — runs sometimes after a hook-gen pass when CLAUDE.md gets short enough that the codebase architecture becomes the next bottleneck
|
|
206
|
-
- Existing hooks: `git-guardrails.js`, `pre-deploy-gate.js`, `vercel-account-guard.js`, `env-empty-guard.js`, `supabase-destructive-guard.js`. New hooks generated by this skill follow the same conventions.
|