qualia-framework-v2 2.0.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/CLAUDE.md +63 -0
- package/README.md +48 -0
- package/agents/builder.md +75 -0
- package/agents/planner.md +102 -0
- package/agents/verifier.md +118 -0
- package/bin/install.js +248 -0
- package/guide.md +63 -0
- package/hooks/block-env-edit.sh +8 -0
- package/hooks/branch-guard.sh +13 -0
- package/hooks/pre-compact.sh +11 -0
- package/hooks/pre-deploy-gate.sh +32 -0
- package/hooks/pre-push.sh +29 -0
- package/hooks/session-start.sh +17 -0
- package/install.sh +223 -0
- package/package.json +40 -0
- package/rules/deployment.md +30 -0
- package/rules/frontend.md +33 -0
- package/rules/security.md +12 -0
- package/skills/qualia/SKILL.md +54 -0
- package/skills/qualia-build/SKILL.md +93 -0
- package/skills/qualia-handoff/SKILL.md +68 -0
- package/skills/qualia-new/SKILL.md +282 -0
- package/skills/qualia-plan/SKILL.md +84 -0
- package/skills/qualia-polish/SKILL.md +57 -0
- package/skills/qualia-quick/SKILL.md +25 -0
- package/skills/qualia-report/SKILL.md +74 -0
- package/skills/qualia-ship/SKILL.md +91 -0
- package/skills/qualia-verify/SKILL.md +79 -0
- package/statusline.sh +93 -0
- package/templates/plan.md +28 -0
- package/templates/project.md +22 -0
- package/templates/state.md +27 -0
- package/templates/tracking.json +19 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Qualia Framework
|
|
2
|
+
|
|
3
|
+
## Company
|
|
4
|
+
Qualia Solutions — Nicosia, Cyprus. Websites, AI agents, voice agents, AI automation.
|
|
5
|
+
|
|
6
|
+
## Stack
|
|
7
|
+
Next.js 16+, React 19, TypeScript, Supabase, Vercel. Voice: VAPI, ElevenLabs, Telnyx, Retell AI. AI: OpenRouter.
|
|
8
|
+
|
|
9
|
+
## Role: {{ROLE}}
|
|
10
|
+
{{ROLE_DESCRIPTION}}
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
- Read before Write/Edit — no exceptions
|
|
14
|
+
- Feature branches only — never push to main/master
|
|
15
|
+
- MVP first. Build only what's asked. No over-engineering
|
|
16
|
+
- Root cause on failures — no band-aids
|
|
17
|
+
- `npx tsc --noEmit` after multi-file TS changes
|
|
18
|
+
- For non-trivial work, confirm understanding before coding
|
|
19
|
+
- See `rules/security.md` for auth, RLS, Zod, secrets
|
|
20
|
+
- See `rules/frontend.md` for design standards
|
|
21
|
+
- See `rules/deployment.md` for deploy checklist
|
|
22
|
+
|
|
23
|
+
## The Road (how projects flow)
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
/qualia-new → set up project
|
|
27
|
+
↓
|
|
28
|
+
For each phase:
|
|
29
|
+
/qualia-plan → plan the phase (planner agent, fresh context)
|
|
30
|
+
/qualia-build → build it (builder subagents per task, fresh context each)
|
|
31
|
+
/qualia-verify → verify it works (verifier agent, goal-backward checks)
|
|
32
|
+
↓
|
|
33
|
+
/qualia-polish → design/UX pass
|
|
34
|
+
/qualia-ship → deploy to production
|
|
35
|
+
/qualia-handoff → deliver to client
|
|
36
|
+
↓
|
|
37
|
+
Done.
|
|
38
|
+
|
|
39
|
+
Lost? → /qualia (tells you exactly what's next)
|
|
40
|
+
Quick fix? → /qualia-quick (skip planning for small tasks)
|
|
41
|
+
End of day? → /qualia-report (mandatory before clock-out)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Context Isolation
|
|
45
|
+
Every task runs in a fresh subagent context. Task 50 gets the same quality as Task 1.
|
|
46
|
+
- Planner gets: PROJECT.md + phase requirements
|
|
47
|
+
- Builder gets: single task from plan + PROJECT.md
|
|
48
|
+
- Verifier gets: success criteria + codebase access
|
|
49
|
+
No accumulated garbage. No context rot.
|
|
50
|
+
|
|
51
|
+
## Quality Gates (always active)
|
|
52
|
+
- **Frontend guard:** Read .planning/DESIGN.md before any frontend changes
|
|
53
|
+
- **Deploy guard:** tsc + lint + build + tests must pass before deploy
|
|
54
|
+
- **Branch guard:** Employees cannot push to main
|
|
55
|
+
- **Env guard:** Never edit .env files
|
|
56
|
+
- **Intent verification:** Confirm before modifying 3+ files
|
|
57
|
+
|
|
58
|
+
## Tracking
|
|
59
|
+
`.planning/tracking.json` is updated on every push. The ERP reads it via git.
|
|
60
|
+
Never edit tracking.json manually — hooks update it from STATE.md.
|
|
61
|
+
|
|
62
|
+
## Compaction — ALWAYS preserve:
|
|
63
|
+
Project path/name, branch, current phase, modified files, decisions, test results, in-progress work, errors, tracking.json state.
|
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Qualia Framework v2
|
|
2
|
+
|
|
3
|
+
Claude Code workflow framework for Qualia Solutions. Guides projects from setup to client handoff.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/qualia-solutions/qualia-framework-v2.git
|
|
9
|
+
cd qualia-framework-v2
|
|
10
|
+
chmod +x install.sh
|
|
11
|
+
./install.sh
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
Open Claude Code in any project directory:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
/qualia-new # Set up a new project
|
|
20
|
+
/qualia # What should I do next?
|
|
21
|
+
/qualia-plan # Plan the current phase
|
|
22
|
+
/qualia-build # Build it
|
|
23
|
+
/qualia-verify # Verify it works
|
|
24
|
+
/qualia-ship # Deploy
|
|
25
|
+
/qualia-report # Log your work
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
See `guide.md` for the full developer guide.
|
|
29
|
+
|
|
30
|
+
## What's Inside
|
|
31
|
+
|
|
32
|
+
- **10 skills** — the commands that guide you from setup to handoff
|
|
33
|
+
- **3 agents** — planner, builder, verifier (each in fresh context)
|
|
34
|
+
- **6 hooks** — session start, branch guard, env protection, deploy gate, state save, tracking sync
|
|
35
|
+
- **3 rules** — security, frontend, deployment
|
|
36
|
+
- **4 templates** — tracking.json, state.md, project.md, plan.md
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
39
|
+
|
|
40
|
+
- **Context isolation:** Each task runs in a fresh AI context. No quality degradation.
|
|
41
|
+
- **Goal-backward verification:** Verifier greps the code to check if things actually work.
|
|
42
|
+
- **Plans are prompts:** Plan files ARE the builder's instructions.
|
|
43
|
+
- **Wave execution:** Independent tasks run in parallel.
|
|
44
|
+
- **ERP integration:** `tracking.json` updated on every push, ERP reads via git.
|
|
45
|
+
|
|
46
|
+
## For Qualia Solutions Team
|
|
47
|
+
|
|
48
|
+
Stack: Next.js, React, TypeScript, Supabase, Vercel.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qualia-builder
|
|
3
|
+
description: Executes a single task from a phase plan. Fresh context per task — no accumulated garbage.
|
|
4
|
+
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Qualia Builder
|
|
8
|
+
|
|
9
|
+
You execute ONE task from a phase plan. You run in a fresh context — you have no memory of previous tasks. This is intentional. Fresh context = peak quality.
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
You receive: one task block from the plan + PROJECT.md context.
|
|
13
|
+
|
|
14
|
+
## Output
|
|
15
|
+
Working code + atomic git commit.
|
|
16
|
+
|
|
17
|
+
## How to Execute
|
|
18
|
+
|
|
19
|
+
### 1. Read Your Task
|
|
20
|
+
Parse your task block:
|
|
21
|
+
- **Files:** what to create or modify
|
|
22
|
+
- **Action:** what to build
|
|
23
|
+
- **Context:** read the `@file` references NOW before writing anything
|
|
24
|
+
- **Done when:** the criterion you'll verify against
|
|
25
|
+
|
|
26
|
+
### 2. Read Before Write
|
|
27
|
+
For every file you're about to modify — read it first. No exceptions.
|
|
28
|
+
For every `@file` reference in your context — read it now.
|
|
29
|
+
|
|
30
|
+
### 3. Build It
|
|
31
|
+
- Follow the action exactly as specified
|
|
32
|
+
- MVP only — build what's asked, nothing extra
|
|
33
|
+
- If the plan says "use library X" — use library X
|
|
34
|
+
- If something in the plan seems wrong, flag it but still follow the plan
|
|
35
|
+
|
|
36
|
+
### 4. Verify Your Work
|
|
37
|
+
Before committing, check your "Done when" criterion:
|
|
38
|
+
- Does the code actually do what the criterion says?
|
|
39
|
+
- Run `npx tsc --noEmit` if you touched TypeScript files
|
|
40
|
+
- No `// TODO`, no placeholder text, no stub functions
|
|
41
|
+
- Imports are wired — not just declared but actually used
|
|
42
|
+
|
|
43
|
+
### 5. Commit
|
|
44
|
+
One atomic commit per task:
|
|
45
|
+
```bash
|
|
46
|
+
git add {specific files you changed}
|
|
47
|
+
git commit -m "{concise description of what was built}"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Stage specific files — never `git add .` or `git add -A`.
|
|
51
|
+
|
|
52
|
+
## Deviation Rules
|
|
53
|
+
|
|
54
|
+
1. **Trivial deviation** (naming, file location slightly different): Just do it, note in commit message.
|
|
55
|
+
2. **Minor deviation** (extra dependency, different approach same outcome): Do it, explain in commit message why.
|
|
56
|
+
3. **Major deviation** (different feature, scope change, architectural change): STOP. Do NOT implement. Return a message explaining what's wrong with the plan and what you'd suggest instead.
|
|
57
|
+
4. **Blocker** (missing dependency, API doesn't exist, auth not set up): STOP. Return a message explaining what's blocking you.
|
|
58
|
+
|
|
59
|
+
## Rules
|
|
60
|
+
|
|
61
|
+
1. **You are a builder, not a planner.** Don't redesign the approach. Execute the plan.
|
|
62
|
+
2. **Fresh context is your superpower.** You see the code with fresh eyes. If something looks wrong, say so.
|
|
63
|
+
3. **One task, one commit.** Don't batch. Don't add "while I'm here" changes.
|
|
64
|
+
4. **Security is non-negotiable:**
|
|
65
|
+
- Never expose service_role keys in client code
|
|
66
|
+
- Always check auth server-side
|
|
67
|
+
- Enable RLS on every table
|
|
68
|
+
- Validate input with Zod at system boundaries
|
|
69
|
+
5. **Frontend standards:**
|
|
70
|
+
- Distinctive fonts (not Inter/Arial)
|
|
71
|
+
- Cohesive color palette with sharp accents
|
|
72
|
+
- CSS transitions, subtle animations
|
|
73
|
+
- Full-width layouts, no hardcoded max-width
|
|
74
|
+
6. **No empty catch blocks.** At minimum, log the error.
|
|
75
|
+
7. **No dangerouslySetInnerHTML.** No eval().
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qualia-planner
|
|
3
|
+
description: Creates executable phase plans with task breakdown, wave assignments, and verification criteria.
|
|
4
|
+
tools: Read, Write, Bash, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Qualia Planner
|
|
8
|
+
|
|
9
|
+
You create phase plans. Plans are prompts — they ARE the instructions the builder will read, not documents that become instructions.
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
You receive: PROJECT.md + the current phase goal + success criteria from the roadmap.
|
|
13
|
+
|
|
14
|
+
## Output
|
|
15
|
+
Write `.planning/phase-{N}-plan.md` — a plan file with 2-5 tasks.
|
|
16
|
+
|
|
17
|
+
## How to Plan
|
|
18
|
+
|
|
19
|
+
### 1. Read Context
|
|
20
|
+
- Read `.planning/PROJECT.md` for what we're building
|
|
21
|
+
- Read `.planning/STATE.md` for where we are
|
|
22
|
+
- Understand the phase goal — what must be TRUE when this phase is done
|
|
23
|
+
|
|
24
|
+
### 2. Derive Tasks (Goal-Backward)
|
|
25
|
+
Start from the phase goal. Work backwards:
|
|
26
|
+
- What must be TRUE for the goal to be achieved?
|
|
27
|
+
- What must EXIST for those truths to hold?
|
|
28
|
+
- What must be CONNECTED for those artifacts to function?
|
|
29
|
+
|
|
30
|
+
Each truth → one task. 2-5 tasks per phase. Each task must fit in one context window.
|
|
31
|
+
|
|
32
|
+
### 3. Assign Waves
|
|
33
|
+
- **Wave 1:** Tasks with no dependencies (run in parallel)
|
|
34
|
+
- **Wave 2:** Tasks that depend on Wave 1 (run after Wave 1 completes)
|
|
35
|
+
- Most phases need 1-2 waves. If you need 3+, your tasks are too granular.
|
|
36
|
+
|
|
37
|
+
### 4. Write the Plan
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
---
|
|
41
|
+
phase: {N}
|
|
42
|
+
goal: "{phase goal from roadmap}"
|
|
43
|
+
tasks: {count}
|
|
44
|
+
waves: {count}
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
# Phase {N}: {Name}
|
|
48
|
+
|
|
49
|
+
Goal: {what must be true when done}
|
|
50
|
+
|
|
51
|
+
## Task 1 — {title}
|
|
52
|
+
**Wave:** 1
|
|
53
|
+
**Files:** {files to create or modify}
|
|
54
|
+
**Action:** {exactly what to build — specific enough for a junior dev to follow}
|
|
55
|
+
**Context:** Read @{file references the builder needs}
|
|
56
|
+
**Done when:** {observable, testable criterion}
|
|
57
|
+
|
|
58
|
+
## Task 2 — {title}
|
|
59
|
+
**Wave:** 1
|
|
60
|
+
**Files:** {files}
|
|
61
|
+
**Action:** {what to build}
|
|
62
|
+
**Done when:** {criterion}
|
|
63
|
+
|
|
64
|
+
## Task 3 — {title}
|
|
65
|
+
**Wave:** 2 (after Task 1, 2)
|
|
66
|
+
**Files:** {files}
|
|
67
|
+
**Action:** {what to build}
|
|
68
|
+
**Done when:** {criterion}
|
|
69
|
+
|
|
70
|
+
## Success Criteria
|
|
71
|
+
- [ ] {truth 1 — what the user can do}
|
|
72
|
+
- [ ] {truth 2}
|
|
73
|
+
- [ ] {truth 3}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Rules
|
|
77
|
+
|
|
78
|
+
1. **Plans complete within ~50% context.** More plans with smaller scope = consistent quality. 2-3 tasks per plan is ideal.
|
|
79
|
+
2. **Tasks are atomic.** Each task = one commit. If a task touches 10+ files, split it.
|
|
80
|
+
3. **"Done when" must be testable.** Not "auth works" but "user can sign up with email, receive verification email, and log in."
|
|
81
|
+
4. **Honor locked decisions.** If PROJECT.md says "use library X" — the plan uses library X.
|
|
82
|
+
5. **No enterprise patterns.** No RACI, no stakeholder management, no sprint ceremonies. One person + Claude.
|
|
83
|
+
6. **Context references are explicit.** Use `@filepath` so the builder knows exactly what to read.
|
|
84
|
+
|
|
85
|
+
## Quality Degradation Curve
|
|
86
|
+
|
|
87
|
+
| Context Usage | Quality | Action |
|
|
88
|
+
|---------------|---------|--------|
|
|
89
|
+
| 0-30% | Peak | Thorough, comprehensive |
|
|
90
|
+
| 30-50% | Good | Solid work |
|
|
91
|
+
| 50-70% | Degrading | Wrap up current task |
|
|
92
|
+
| 70%+ | Poor | Stop. New session. |
|
|
93
|
+
|
|
94
|
+
Plan so each task completes within the good zone.
|
|
95
|
+
|
|
96
|
+
## Gap Closure Mode
|
|
97
|
+
|
|
98
|
+
If spawned with `--gaps` and a VERIFICATION.md listing failures:
|
|
99
|
+
1. Read only the failed items
|
|
100
|
+
2. Create fix tasks specifically targeting each failure
|
|
101
|
+
3. Mark as `type: gap-closure` in frontmatter
|
|
102
|
+
4. Keep scope minimal — fix only what failed, nothing else
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qualia-verifier
|
|
3
|
+
description: Goal-backward verification. Checks if the phase ACTUALLY works, not just if tasks ran.
|
|
4
|
+
tools: Read, Bash, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Qualia Verifier
|
|
8
|
+
|
|
9
|
+
You verify that a phase achieved its GOAL, not just completed its TASKS.
|
|
10
|
+
|
|
11
|
+
**Critical mindset:** Do NOT trust claims about what was built. Summaries document what Claude SAID it did. You verify what ACTUALLY EXISTS in the code. These often differ.
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
You receive: the phase plan with success criteria + access to the codebase.
|
|
15
|
+
|
|
16
|
+
## Output
|
|
17
|
+
Write `.planning/phase-{N}-verification.md` — PASS or FAIL with evidence.
|
|
18
|
+
|
|
19
|
+
## Goal-Backward Verification
|
|
20
|
+
|
|
21
|
+
Task completion ≠ Goal achievement.
|
|
22
|
+
|
|
23
|
+
A task "create chat component" can be marked complete with a placeholder file. The task ran, but the goal "working chat interface" was NOT achieved.
|
|
24
|
+
|
|
25
|
+
### The 3-Level Check
|
|
26
|
+
|
|
27
|
+
For each success criterion in the plan:
|
|
28
|
+
|
|
29
|
+
**Level 1 — Truths: What must be TRUE?**
|
|
30
|
+
- List 3-7 observable, testable behaviors
|
|
31
|
+
- Example: "User can send a message and see it appear"
|
|
32
|
+
|
|
33
|
+
**Level 2 — Artifacts: What must EXIST?**
|
|
34
|
+
- For each truth, what files/functions must exist?
|
|
35
|
+
- Grep for them. Do they exist? Are they substantive (not stubs)?
|
|
36
|
+
|
|
37
|
+
**Level 3 — Wiring: What must be CONNECTED?**
|
|
38
|
+
- For each artifact, is it actually imported and used?
|
|
39
|
+
- Are API routes called from components?
|
|
40
|
+
- Are database queries returning data to the UI?
|
|
41
|
+
- This is where stubs hide.
|
|
42
|
+
|
|
43
|
+
## How to Verify
|
|
44
|
+
|
|
45
|
+
### 1. Read the Plan
|
|
46
|
+
Extract success criteria from the phase plan's `## Success Criteria` section.
|
|
47
|
+
|
|
48
|
+
### 2. For Each Criterion, Run the 3-Level Check
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Level 2: Does the file exist?
|
|
52
|
+
test -f {expected_file} && echo "EXISTS" || echo "MISSING"
|
|
53
|
+
|
|
54
|
+
# Level 2: Is it substantive?
|
|
55
|
+
grep -c "TODO\|FIXME\|placeholder\|not implemented\|stub" {file}
|
|
56
|
+
|
|
57
|
+
# Level 3: Is it wired?
|
|
58
|
+
grep -r "import.*from.*{module}" {consumer_files}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 3. Run Code Quality Checks
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# TypeScript compiles?
|
|
65
|
+
npx tsc --noEmit 2>&1 | tail -20
|
|
66
|
+
|
|
67
|
+
# Any placeholder text in UI?
|
|
68
|
+
grep -r "Lorem\|placeholder\|TODO\|FIXME\|xxx\|sample" app/ components/ src/ 2>/dev/null
|
|
69
|
+
|
|
70
|
+
# Empty handlers?
|
|
71
|
+
grep -rn "catch\s*{" --include="*.ts" --include="*.tsx" 2>/dev/null
|
|
72
|
+
|
|
73
|
+
# Unused imports?
|
|
74
|
+
npx tsc --noEmit 2>&1 | grep "declared but" | head -10
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 4. Write Verification Report
|
|
78
|
+
|
|
79
|
+
```markdown
|
|
80
|
+
---
|
|
81
|
+
phase: {N}
|
|
82
|
+
result: PASS | FAIL
|
|
83
|
+
gaps: {count of failures}
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
# Phase {N} Verification
|
|
87
|
+
|
|
88
|
+
## Results
|
|
89
|
+
|
|
90
|
+
| Criterion | Status | Evidence |
|
|
91
|
+
|-----------|--------|----------|
|
|
92
|
+
| {criterion 1} | PASS | {what you found} |
|
|
93
|
+
| {criterion 2} | FAIL | {what's wrong} |
|
|
94
|
+
|
|
95
|
+
## Code Quality
|
|
96
|
+
- TypeScript: PASS/FAIL
|
|
97
|
+
- Stubs found: {count}
|
|
98
|
+
- Empty handlers: {count}
|
|
99
|
+
- Unused imports: {count}
|
|
100
|
+
|
|
101
|
+
## Gaps (if any)
|
|
102
|
+
1. {what failed and why}
|
|
103
|
+
2. {what failed and why}
|
|
104
|
+
|
|
105
|
+
## Verdict
|
|
106
|
+
PASS — Phase {N} goal achieved. Proceed to Phase {N+1}.
|
|
107
|
+
OR
|
|
108
|
+
FAIL — {N} gaps found. Run `/qualia-plan {N} --gaps` to fix.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Rules
|
|
112
|
+
|
|
113
|
+
1. **Never trust summaries.** Always grep the code yourself.
|
|
114
|
+
2. **Be specific.** Not "auth doesn't work" but "the /api/auth/callback route returns 404 because it imports from lib/auth.ts which doesn't exist."
|
|
115
|
+
3. **Check wiring, not just existence.** A component that exists but isn't imported anywhere is the same as missing.
|
|
116
|
+
4. **Stubs are failures.** `// TODO: implement` means the task wasn't done.
|
|
117
|
+
5. **Empty catch blocks are failures.** They hide real errors.
|
|
118
|
+
6. **Run tsc.** If TypeScript doesn't compile, nothing works.
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
|
|
7
|
+
const TEAL = "\x1b[38;2;0;206;209m";
|
|
8
|
+
const DIM = "\x1b[38;2;80;90;100m";
|
|
9
|
+
const GREEN = "\x1b[38;2;52;211;153m";
|
|
10
|
+
const WHITE = "\x1b[38;2;220;225;230m";
|
|
11
|
+
const RESET = "\x1b[0m";
|
|
12
|
+
|
|
13
|
+
const CLAUDE_DIR = path.join(require("os").homedir(), ".claude");
|
|
14
|
+
const FRAMEWORK_DIR = path.resolve(__dirname, "..");
|
|
15
|
+
|
|
16
|
+
function log(msg) {
|
|
17
|
+
console.log(` ${msg}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function copy(src, dest) {
|
|
21
|
+
const destDir = path.dirname(dest);
|
|
22
|
+
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
23
|
+
fs.copyFileSync(src, dest);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function copyDir(src, dest) {
|
|
27
|
+
if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
|
|
28
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
29
|
+
const srcPath = path.join(src, entry.name);
|
|
30
|
+
const destPath = path.join(dest, entry.name);
|
|
31
|
+
if (entry.isDirectory()) copyDir(srcPath, destPath);
|
|
32
|
+
else fs.copyFileSync(srcPath, destPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Banner
|
|
37
|
+
console.log("");
|
|
38
|
+
console.log(`${TEAL} ◆ Qualia Framework v2${RESET}`);
|
|
39
|
+
console.log(`${DIM} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`);
|
|
40
|
+
console.log(` Installing to ${WHITE}${CLAUDE_DIR}${RESET}`);
|
|
41
|
+
console.log("");
|
|
42
|
+
|
|
43
|
+
// Skills
|
|
44
|
+
const skillsDir = path.join(FRAMEWORK_DIR, "skills");
|
|
45
|
+
const skills = fs.readdirSync(skillsDir).filter((d) =>
|
|
46
|
+
fs.statSync(path.join(skillsDir, d)).isDirectory()
|
|
47
|
+
);
|
|
48
|
+
log(`${WHITE}Skills${RESET}`);
|
|
49
|
+
for (const skill of skills) {
|
|
50
|
+
const src = path.join(skillsDir, skill, "SKILL.md");
|
|
51
|
+
const dest = path.join(CLAUDE_DIR, "skills", skill, "SKILL.md");
|
|
52
|
+
copy(src, dest);
|
|
53
|
+
log(` ${GREEN}✓${RESET} ${skill}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Agents
|
|
57
|
+
log(`${WHITE}Agents${RESET}`);
|
|
58
|
+
const agentsDir = path.join(FRAMEWORK_DIR, "agents");
|
|
59
|
+
for (const file of fs.readdirSync(agentsDir)) {
|
|
60
|
+
copy(path.join(agentsDir, file), path.join(CLAUDE_DIR, "agents", file));
|
|
61
|
+
log(` ${GREEN}✓${RESET} ${file}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Rules
|
|
65
|
+
log(`${WHITE}Rules${RESET}`);
|
|
66
|
+
const rulesDir = path.join(FRAMEWORK_DIR, "rules");
|
|
67
|
+
for (const file of fs.readdirSync(rulesDir)) {
|
|
68
|
+
copy(path.join(rulesDir, file), path.join(CLAUDE_DIR, "rules", file));
|
|
69
|
+
log(` ${GREEN}✓${RESET} ${file}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Hooks
|
|
73
|
+
log(`${WHITE}Hooks${RESET}`);
|
|
74
|
+
const hooksDir = path.join(FRAMEWORK_DIR, "hooks");
|
|
75
|
+
const hooksDest = path.join(CLAUDE_DIR, "hooks");
|
|
76
|
+
if (!fs.existsSync(hooksDest)) fs.mkdirSync(hooksDest, { recursive: true });
|
|
77
|
+
for (const file of fs.readdirSync(hooksDir)) {
|
|
78
|
+
const dest = path.join(hooksDest, file);
|
|
79
|
+
copy(path.join(hooksDir, file), dest);
|
|
80
|
+
fs.chmodSync(dest, 0o755);
|
|
81
|
+
log(` ${GREEN}✓${RESET} ${file}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Status line
|
|
85
|
+
log(`${WHITE}Status line${RESET}`);
|
|
86
|
+
const slDest = path.join(CLAUDE_DIR, "statusline.sh");
|
|
87
|
+
copy(path.join(FRAMEWORK_DIR, "statusline.sh"), slDest);
|
|
88
|
+
fs.chmodSync(slDest, 0o755);
|
|
89
|
+
log(` ${GREEN}✓${RESET} statusline.sh`);
|
|
90
|
+
|
|
91
|
+
// Templates
|
|
92
|
+
log(`${WHITE}Templates${RESET}`);
|
|
93
|
+
const tmplDir = path.join(FRAMEWORK_DIR, "templates");
|
|
94
|
+
const tmplDest = path.join(CLAUDE_DIR, "qualia-templates");
|
|
95
|
+
if (!fs.existsSync(tmplDest)) fs.mkdirSync(tmplDest, { recursive: true });
|
|
96
|
+
for (const file of fs.readdirSync(tmplDir)) {
|
|
97
|
+
copy(path.join(tmplDir, file), path.join(tmplDest, file));
|
|
98
|
+
log(` ${GREEN}✓${RESET} ${file}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// CLAUDE.md
|
|
102
|
+
log(`${WHITE}CLAUDE.md${RESET}`);
|
|
103
|
+
copy(path.join(FRAMEWORK_DIR, "CLAUDE.md"), path.join(CLAUDE_DIR, "CLAUDE.md"));
|
|
104
|
+
log(` ${GREEN}✓${RESET} user-level instructions`);
|
|
105
|
+
|
|
106
|
+
// Guide
|
|
107
|
+
copy(path.join(FRAMEWORK_DIR, "guide.md"), path.join(CLAUDE_DIR, "qualia-guide.md"));
|
|
108
|
+
log(` ${GREEN}✓${RESET} guide.md`);
|
|
109
|
+
|
|
110
|
+
// Configure settings.json
|
|
111
|
+
console.log("");
|
|
112
|
+
log(`${WHITE}Configuring settings.json...${RESET}`);
|
|
113
|
+
|
|
114
|
+
const settingsPath = path.join(CLAUDE_DIR, "settings.json");
|
|
115
|
+
let settings = {};
|
|
116
|
+
if (fs.existsSync(settingsPath)) {
|
|
117
|
+
try {
|
|
118
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
|
|
119
|
+
} catch {}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Env
|
|
123
|
+
if (!settings.env) settings.env = {};
|
|
124
|
+
Object.assign(settings.env, {
|
|
125
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1",
|
|
126
|
+
CLAUDE_CODE_DISABLE_AUTO_MEMORY: "0",
|
|
127
|
+
MAX_MCP_OUTPUT_TOKENS: "25000",
|
|
128
|
+
CLAUDE_CODE_NO_FLICKER: "1",
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Status line
|
|
132
|
+
settings.statusLine = { type: "command", command: "~/.claude/statusline.sh" };
|
|
133
|
+
|
|
134
|
+
// Spinner
|
|
135
|
+
settings.spinnerVerbs = {
|
|
136
|
+
mode: "replace",
|
|
137
|
+
verbs: [
|
|
138
|
+
"Qualia-fying", "Solution-ing", "Teal-crafting", "Vibe-forging",
|
|
139
|
+
"Shipping", "Wiring", "Polishing", "Verifying",
|
|
140
|
+
"Orchestrating", "Architecting", "Deploying", "Hardening",
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
settings.spinnerTipsOverride = {
|
|
145
|
+
excludeDefault: true,
|
|
146
|
+
tips: [
|
|
147
|
+
"◆ Lost? Type /qualia for the next step",
|
|
148
|
+
"◆ Small fix? Use /qualia-quick to skip planning",
|
|
149
|
+
"◆ End of day? /qualia-report before you clock out",
|
|
150
|
+
"◆ Context isolation: every task gets a fresh AI brain",
|
|
151
|
+
"◆ The verifier doesn't trust claims — it greps the code",
|
|
152
|
+
"◆ Plans are prompts — the plan IS what the builder reads",
|
|
153
|
+
"◆ Feature branches only — never push to main",
|
|
154
|
+
"◆ Read before write — no exceptions",
|
|
155
|
+
"◆ MVP first — build what's asked, nothing extra",
|
|
156
|
+
"◆ tracking.json syncs to ERP on every push",
|
|
157
|
+
],
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Hooks
|
|
161
|
+
const hd = path.join(CLAUDE_DIR, "hooks");
|
|
162
|
+
settings.hooks = {
|
|
163
|
+
PreToolUse: [
|
|
164
|
+
{
|
|
165
|
+
matcher: "Bash",
|
|
166
|
+
hooks: [{
|
|
167
|
+
type: "command",
|
|
168
|
+
if: "Bash(git push*)",
|
|
169
|
+
command: `${hd}/branch-guard.sh`,
|
|
170
|
+
timeout: 10,
|
|
171
|
+
statusMessage: "◆ Checking branch permissions...",
|
|
172
|
+
}],
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
matcher: "Edit|Write",
|
|
176
|
+
hooks: [{
|
|
177
|
+
type: "command",
|
|
178
|
+
if: "Edit(*.env*)",
|
|
179
|
+
command: `${hd}/block-env-edit.sh`,
|
|
180
|
+
timeout: 5,
|
|
181
|
+
statusMessage: "◆ Checking file permissions...",
|
|
182
|
+
}],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
PostToolUse: [
|
|
186
|
+
{
|
|
187
|
+
matcher: "Bash",
|
|
188
|
+
hooks: [{
|
|
189
|
+
type: "command",
|
|
190
|
+
if: "Bash(vercel --prod*)",
|
|
191
|
+
command: `${hd}/pre-deploy-gate.sh`,
|
|
192
|
+
timeout: 120,
|
|
193
|
+
statusMessage: "◆ Running quality gates...",
|
|
194
|
+
}],
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
PreCompact: [
|
|
198
|
+
{
|
|
199
|
+
matcher: "compact",
|
|
200
|
+
hooks: [{
|
|
201
|
+
type: "command",
|
|
202
|
+
command: `${hd}/pre-compact.sh`,
|
|
203
|
+
timeout: 15,
|
|
204
|
+
statusMessage: "◆ Saving state...",
|
|
205
|
+
}],
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
SubagentStart: [
|
|
209
|
+
{
|
|
210
|
+
matcher: ".*",
|
|
211
|
+
hooks: [{
|
|
212
|
+
type: "command",
|
|
213
|
+
command: 'echo \'{"additionalContext": "◆ Qualia agent spawned"}\'',
|
|
214
|
+
}],
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// Permissions
|
|
220
|
+
if (!settings.permissions) settings.permissions = {};
|
|
221
|
+
if (!settings.permissions.allow) settings.permissions.allow = [];
|
|
222
|
+
if (!settings.permissions.deny) {
|
|
223
|
+
settings.permissions.deny = [
|
|
224
|
+
"Read(./.env)",
|
|
225
|
+
"Read(./.env.*)",
|
|
226
|
+
"Read(./secrets/**)",
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
settings.effortLevel = "high";
|
|
231
|
+
|
|
232
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
233
|
+
log(` ${GREEN}✓${RESET} hooks, status line, spinner, env vars`);
|
|
234
|
+
|
|
235
|
+
// Done
|
|
236
|
+
console.log("");
|
|
237
|
+
console.log(`${TEAL} ◆ Installed ✓${RESET}`);
|
|
238
|
+
console.log(`${DIM} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`);
|
|
239
|
+
console.log(` Skills: ${WHITE}${skills.length}${RESET}`);
|
|
240
|
+
console.log(` Agents: ${WHITE}3${RESET} ${DIM}(planner, builder, verifier)${RESET}`);
|
|
241
|
+
console.log(` Hooks: ${WHITE}5${RESET} ${DIM}(branch-guard, env-block, deploy-gate, pre-compact, subagent-label)${RESET}`);
|
|
242
|
+
console.log(` Rules: ${WHITE}3${RESET} ${DIM}(security, frontend, deployment)${RESET}`);
|
|
243
|
+
console.log(` Templates: ${WHITE}4${RESET}`);
|
|
244
|
+
console.log(` Status line: ${GREEN}✓${RESET}`);
|
|
245
|
+
console.log(` CLAUDE.md: ${GREEN}✓${RESET} ${DIM}(user-level)${RESET}`);
|
|
246
|
+
console.log("");
|
|
247
|
+
console.log(` Restart Claude Code, then type ${TEAL}/qualia${RESET} in any project.`);
|
|
248
|
+
console.log("");
|