qualia-framework 2.2.1 → 2.4.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/bin/collect-metrics.sh +62 -0
- package/framework/agents/qualia-phase-researcher.md +6 -3
- package/framework/agents/qualia-planner.md +10 -7
- package/framework/agents/qualia-research-synthesizer.md +110 -147
- package/framework/agents/red-team-qa.md +130 -0
- package/framework/hooks/auto-format.sh +9 -1
- package/framework/hooks/confirm-delete.sh +2 -2
- package/framework/hooks/migration-validate.sh +21 -16
- package/framework/hooks/pre-commit.sh +17 -9
- package/framework/hooks/pre-deploy-gate.sh +22 -15
- package/framework/hooks/retention-cleanup.sh +4 -4
- package/framework/hooks/save-session-state.sh +18 -10
- package/framework/hooks/session-context-loader.sh +21 -0
- package/framework/hooks/skill-announce.sh +2 -0
- package/framework/install.sh +9 -4
- package/framework/qualia-engine/VERSION +1 -1
- package/framework/qualia-engine/bin/collect-metrics.sh +71 -0
- package/framework/qualia-engine/bin/qualia-tools.js +104 -63
- package/framework/qualia-engine/references/continuation-prompt.md +97 -0
- package/framework/qualia-engine/references/employee-guide.md +167 -0
- package/framework/qualia-engine/templates/lab-notes.md +16 -0
- package/framework/qualia-engine/templates/projects/ai-agent.md +1 -1
- package/framework/qualia-engine/templates/projects/voice-agent.md +4 -4
- package/framework/qualia-engine/templates/roadmap.md +4 -0
- package/framework/qualia-engine/templates/state.md +3 -0
- package/framework/qualia-engine/workflows/execute-phase.md +17 -17
- package/framework/qualia-engine/workflows/new-project.md +54 -130
- package/framework/qualia-engine/workflows/progress.md +63 -28
- package/framework/skills/client-handoff/SKILL.md +135 -0
- package/framework/skills/collab-onboard/SKILL.md +111 -0
- package/framework/skills/deep-research/SKILL.md +34 -71
- package/framework/skills/docs-lookup/SKILL.md +4 -3
- package/framework/skills/learn/SKILL.md +30 -6
- package/framework/skills/mobile-expo/SKILL.md +117 -4
- package/framework/skills/openrouter-agent/SKILL.md +922 -0
- package/framework/skills/qualia/SKILL.md +65 -19
- package/framework/skills/qualia-audit-milestone/SKILL.md +5 -2
- package/framework/skills/qualia-complete-milestone/SKILL.md +34 -8
- package/framework/skills/qualia-evolve/SKILL.md +200 -0
- package/framework/skills/qualia-execute-phase/SKILL.md +5 -2
- package/framework/skills/qualia-guide/SKILL.md +32 -0
- package/framework/skills/qualia-help/SKILL.md +100 -64
- package/framework/skills/qualia-new-project/SKILL.md +186 -62
- package/framework/skills/qualia-plan-phase/SKILL.md +5 -2
- package/framework/skills/qualia-report/SKILL.md +217 -0
- package/framework/skills/qualia-start/SKILL.md +31 -59
- package/framework/skills/qualia-verify-work/SKILL.md +33 -6
- package/framework/skills/qualia-workflow/SKILL.md +5 -5
- package/framework/skills/ship/SKILL.md +32 -6
- package/framework/skills/voice-agent/SKILL.md +1174 -269
- package/package.json +1 -1
|
@@ -99,7 +99,8 @@ function loadConfig(cwd) {
|
|
|
99
99
|
verifier: get('verifier', { section: 'workflow', field: 'verifier' }) ?? defaults.verifier,
|
|
100
100
|
parallelization,
|
|
101
101
|
};
|
|
102
|
-
} catch {
|
|
102
|
+
} catch (e) {
|
|
103
|
+
process.stderr.write(`WARNING: .planning/config.json is malformed or unreadable, using defaults: ${e.message}\n`);
|
|
103
104
|
return defaults;
|
|
104
105
|
}
|
|
105
106
|
}
|
|
@@ -884,8 +885,8 @@ function cmdCommit(cwd, message, files, raw) {
|
|
|
884
885
|
output(result, raw, 'nothing');
|
|
885
886
|
return;
|
|
886
887
|
}
|
|
887
|
-
const result = { committed: false, hash: null, reason: '
|
|
888
|
-
output(result, raw, '
|
|
888
|
+
const result = { committed: false, hash: null, reason: 'commit_failed', error: commitResult.stderr };
|
|
889
|
+
output(result, raw, 'COMMIT FAILED: ' + (commitResult.stderr || 'unknown error'));
|
|
889
890
|
return;
|
|
890
891
|
}
|
|
891
892
|
|
|
@@ -1156,79 +1157,95 @@ function cmdStateSnapshot(cwd, raw) {
|
|
|
1156
1157
|
|
|
1157
1158
|
const content = fs.readFileSync(statePath, 'utf-8');
|
|
1158
1159
|
|
|
1159
|
-
//
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1160
|
+
// Parse "Phase: X of Y (Name)" or "Phase: X of Y ([Name])"
|
|
1161
|
+
let currentPhase = null, totalPhases = null, currentPhaseName = null;
|
|
1162
|
+
const phaseMatch = content.match(/^Phase:\s*(\d+(?:\.\d+)?)\s*of\s*(\d+)\s*\(([^)]+)\)/m);
|
|
1163
|
+
if (phaseMatch) {
|
|
1164
|
+
currentPhase = phaseMatch[1];
|
|
1165
|
+
totalPhases = parseInt(phaseMatch[2], 10);
|
|
1166
|
+
currentPhaseName = phaseMatch[3].trim();
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// Parse "Plan: A of B in current phase" or "Plan: Not started" or "Plan: All plans complete"
|
|
1170
|
+
let currentPlan = null, totalPlansInPhase = null;
|
|
1171
|
+
const planMatch = content.match(/^Plan:\s*(\d+)\s*of\s*(\d+)/m);
|
|
1172
|
+
if (planMatch) {
|
|
1173
|
+
currentPlan = planMatch[1];
|
|
1174
|
+
totalPlansInPhase = parseInt(planMatch[2], 10);
|
|
1175
|
+
} else {
|
|
1176
|
+
const planAlt = content.match(/^Plan:\s*(.+)/m);
|
|
1177
|
+
if (planAlt) currentPlan = planAlt[1].trim();
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// Parse "Status: ..."
|
|
1181
|
+
let status = null;
|
|
1182
|
+
const statusMatch = content.match(/^Status:\s*(.+)/m);
|
|
1183
|
+
if (statusMatch) status = statusMatch[1].trim();
|
|
1184
|
+
|
|
1185
|
+
// Parse "Last activity: DATE — Description"
|
|
1186
|
+
let lastActivity = null, lastActivityDesc = null;
|
|
1187
|
+
const activityMatch = content.match(/^Last activity:\s*(\S+)\s*(?:—|--)\s*(.+)/m);
|
|
1188
|
+
if (activityMatch) {
|
|
1189
|
+
lastActivity = activityMatch[1].trim();
|
|
1190
|
+
lastActivityDesc = activityMatch[2].trim();
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// Parse "Progress: [...] N%" — extract percentage
|
|
1194
|
+
let progressPercent = null;
|
|
1195
|
+
const progressMatch = content.match(/(\d+)%/);
|
|
1196
|
+
if (progressMatch) progressPercent = parseInt(progressMatch[1], 10);
|
|
1197
|
+
|
|
1198
|
+
// Parse "Assigned to: ..."
|
|
1199
|
+
let assignedTo = null;
|
|
1200
|
+
const assignedMatch = content.match(/^Assigned to:\s*(.+)/m);
|
|
1201
|
+
if (assignedMatch) assignedTo = assignedMatch[1].trim();
|
|
1165
1202
|
|
|
1166
|
-
// Extract
|
|
1167
|
-
|
|
1168
|
-
const currentPhaseName = extractField('Current Phase Name');
|
|
1169
|
-
const totalPhasesRaw = extractField('Total Phases');
|
|
1170
|
-
const currentPlan = extractField('Current Plan');
|
|
1171
|
-
const totalPlansRaw = extractField('Total Plans in Phase');
|
|
1172
|
-
const status = extractField('Status');
|
|
1173
|
-
const progressRaw = extractField('Progress');
|
|
1174
|
-
const lastActivity = extractField('Last Activity');
|
|
1175
|
-
const lastActivityDesc = extractField('Last Activity Description');
|
|
1176
|
-
const pausedAt = extractField('Paused At');
|
|
1177
|
-
|
|
1178
|
-
// Parse numeric fields
|
|
1179
|
-
const totalPhases = totalPhasesRaw ? parseInt(totalPhasesRaw, 10) : null;
|
|
1180
|
-
const totalPlansInPhase = totalPlansRaw ? parseInt(totalPlansRaw, 10) : null;
|
|
1181
|
-
const progressPercent = progressRaw ? parseInt(progressRaw.replace('%', ''), 10) : null;
|
|
1182
|
-
|
|
1183
|
-
// Extract decisions table
|
|
1203
|
+
// Extract decisions from "### Decisions" section
|
|
1204
|
+
// Format: "- [Phase X]: decision summary" or "- [Pre-roadmap]: decision"
|
|
1184
1205
|
const decisions = [];
|
|
1185
|
-
const
|
|
1186
|
-
if (
|
|
1187
|
-
const
|
|
1188
|
-
const
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
if (cells.length >= 3) {
|
|
1206
|
+
const decisionsSection = content.match(/###\s*Decisions\s*\n([\s\S]*?)(?=\n###|\n##|$)/i);
|
|
1207
|
+
if (decisionsSection) {
|
|
1208
|
+
const lines = decisionsSection[1].split('\n');
|
|
1209
|
+
for (const line of lines) {
|
|
1210
|
+
const decMatch = line.match(/^-\s+\[([^\]]+)\]:\s*(.+)/);
|
|
1211
|
+
if (decMatch) {
|
|
1192
1212
|
decisions.push({
|
|
1193
|
-
phase:
|
|
1194
|
-
summary:
|
|
1195
|
-
rationale:
|
|
1213
|
+
phase: decMatch[1].trim(),
|
|
1214
|
+
summary: decMatch[2].trim(),
|
|
1215
|
+
rationale: '',
|
|
1196
1216
|
});
|
|
1197
1217
|
}
|
|
1198
1218
|
}
|
|
1199
1219
|
}
|
|
1200
1220
|
|
|
1201
|
-
// Extract blockers
|
|
1221
|
+
// Extract blockers from "### Blockers/Concerns" section
|
|
1202
1222
|
const blockers = [];
|
|
1203
|
-
const
|
|
1204
|
-
if (
|
|
1205
|
-
const
|
|
1206
|
-
const items = blockersSection.match(/^-\s+(.+)$/gm) || [];
|
|
1223
|
+
const blockersSection = content.match(/###\s*Blockers\/Concerns\s*\n([\s\S]*?)(?=\n###|\n##|$)/i);
|
|
1224
|
+
if (blockersSection) {
|
|
1225
|
+
const items = blockersSection[1].match(/^-\s+(.+)$/gm) || [];
|
|
1207
1226
|
for (const item of items) {
|
|
1208
|
-
|
|
1227
|
+
const text = item.replace(/^-\s+/, '').trim();
|
|
1228
|
+
if (text && !text.match(/^none/i)) blockers.push(text);
|
|
1209
1229
|
}
|
|
1210
1230
|
}
|
|
1211
1231
|
|
|
1212
|
-
// Extract session info
|
|
1213
|
-
const session = {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
if (sessionMatch) {
|
|
1221
|
-
const sessionSection = sessionMatch[1];
|
|
1222
|
-
const lastDateMatch = sessionSection.match(/\*\*Last Date:\*\*\s*(.+)/i);
|
|
1223
|
-
const stoppedAtMatch = sessionSection.match(/\*\*Stopped At:\*\*\s*(.+)/i);
|
|
1224
|
-
const resumeFileMatch = sessionSection.match(/\*\*Resume File:\*\*\s*(.+)/i);
|
|
1225
|
-
|
|
1232
|
+
// Extract session info from "## Session Continuity"
|
|
1233
|
+
const session = { last_date: null, stopped_at: null, resume_file: null };
|
|
1234
|
+
const sessionSection = content.match(/##\s*Session Continuity\s*\n([\s\S]*?)(?=\n##|$)/i);
|
|
1235
|
+
if (sessionSection) {
|
|
1236
|
+
const sec = sessionSection[1];
|
|
1237
|
+
const lastDateMatch = sec.match(/^Last session:\s*(.+)/m);
|
|
1238
|
+
const stoppedAtMatch = sec.match(/^Stopped at:\s*(.+)/m);
|
|
1239
|
+
const resumeFileMatch = sec.match(/^Resume file:\s*(.+)/m);
|
|
1226
1240
|
if (lastDateMatch) session.last_date = lastDateMatch[1].trim();
|
|
1227
1241
|
if (stoppedAtMatch) session.stopped_at = stoppedAtMatch[1].trim();
|
|
1228
|
-
if (resumeFileMatch)
|
|
1242
|
+
if (resumeFileMatch) {
|
|
1243
|
+
const rf = resumeFileMatch[1].trim();
|
|
1244
|
+
session.resume_file = rf.toLowerCase() === 'none' ? null : rf;
|
|
1245
|
+
}
|
|
1229
1246
|
}
|
|
1230
1247
|
|
|
1231
|
-
|
|
1248
|
+
output({
|
|
1232
1249
|
current_phase: currentPhase,
|
|
1233
1250
|
current_phase_name: currentPhaseName,
|
|
1234
1251
|
total_phases: totalPhases,
|
|
@@ -1238,13 +1255,11 @@ function cmdStateSnapshot(cwd, raw) {
|
|
|
1238
1255
|
progress_percent: progressPercent,
|
|
1239
1256
|
last_activity: lastActivity,
|
|
1240
1257
|
last_activity_desc: lastActivityDesc,
|
|
1258
|
+
assigned_to: assignedTo,
|
|
1241
1259
|
decisions,
|
|
1242
1260
|
blockers,
|
|
1243
|
-
paused_at: pausedAt,
|
|
1244
1261
|
session,
|
|
1245
|
-
};
|
|
1246
|
-
|
|
1247
|
-
output(result, raw);
|
|
1262
|
+
}, raw);
|
|
1248
1263
|
}
|
|
1249
1264
|
|
|
1250
1265
|
function cmdSummaryExtract(cwd, summaryPath, fields, raw) {
|
|
@@ -2152,6 +2167,32 @@ function main() {
|
|
|
2152
2167
|
break;
|
|
2153
2168
|
}
|
|
2154
2169
|
|
|
2170
|
+
case '--help':
|
|
2171
|
+
case 'help': {
|
|
2172
|
+
const cmds = [
|
|
2173
|
+
'state load — Load project state + config as JSON',
|
|
2174
|
+
'state-snapshot — Structured snapshot of STATE.md fields',
|
|
2175
|
+
'resolve-model <agent> — Resolve model for agent from profile',
|
|
2176
|
+
'find-phase <number> — Find phase directory path',
|
|
2177
|
+
'commit <msg> --files .. — Commit with planning-aware logic',
|
|
2178
|
+
'verify-summary <path> — Verify SUMMARY.md completeness',
|
|
2179
|
+
'generate-slug <text> — Generate URL-safe slug',
|
|
2180
|
+
'current-timestamp — ISO timestamp',
|
|
2181
|
+
'list-todos [area] — List pending todos',
|
|
2182
|
+
'verify-path-exists <path> — Check if path exists',
|
|
2183
|
+
'config-ensure-section — Ensure config section exists',
|
|
2184
|
+
'init <workflow> [args] — Initialize workflow context',
|
|
2185
|
+
'roadmap get-phase <N> — Get phase details from ROADMAP.md',
|
|
2186
|
+
'phase-plan-index <N> — Get plan inventory with wave grouping',
|
|
2187
|
+
'summary-extract <path> — Extract fields from SUMMARY.md',
|
|
2188
|
+
];
|
|
2189
|
+
console.log('qualia-tools v2.4.1\n');
|
|
2190
|
+
console.log('Usage: qualia-tools <command> [args] [--raw]\n');
|
|
2191
|
+
console.log('Commands:');
|
|
2192
|
+
cmds.forEach(c => console.log(' ' + c));
|
|
2193
|
+
process.exit(0);
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2155
2196
|
default:
|
|
2156
2197
|
error(`Unknown command: ${command}`);
|
|
2157
2198
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Checkpoint Continuation Prompt Template
|
|
2
|
+
|
|
3
|
+
Template for spawning a fresh agent to continue execution after a checkpoint pause.
|
|
4
|
+
|
|
5
|
+
**Why fresh agent:** Resume relies on internal serialization that breaks with parallel tool calls. Fresh agents with explicit state are more reliable.
|
|
6
|
+
|
|
7
|
+
## Template
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
<objective>
|
|
11
|
+
Continue executing plan {plan_id} from task {resume_task_number}: {resume_task_name}.
|
|
12
|
+
Previous tasks are already committed. Do NOT re-execute them.
|
|
13
|
+
</objective>
|
|
14
|
+
|
|
15
|
+
<completed_work>
|
|
16
|
+
## Tasks Already Done
|
|
17
|
+
|
|
18
|
+
{completed_tasks_table}
|
|
19
|
+
|
|
20
|
+
These tasks have been committed. Verify their commits exist before continuing:
|
|
21
|
+
```bash
|
|
22
|
+
git log --oneline --all --grep="{plan_id}" | head -10
|
|
23
|
+
```
|
|
24
|
+
</completed_work>
|
|
25
|
+
|
|
26
|
+
<checkpoint_resolution>
|
|
27
|
+
## Checkpoint Resolution
|
|
28
|
+
|
|
29
|
+
**Checkpoint type:** {checkpoint_type}
|
|
30
|
+
**User response:** {user_response}
|
|
31
|
+
|
|
32
|
+
{resume_instructions}
|
|
33
|
+
</checkpoint_resolution>
|
|
34
|
+
|
|
35
|
+
<resume_from>
|
|
36
|
+
## Resume Point
|
|
37
|
+
|
|
38
|
+
**Task:** {resume_task_number} — {resume_task_name}
|
|
39
|
+
**Plan path:** {plan_path}
|
|
40
|
+
|
|
41
|
+
Read the full plan for context, but only execute from task {resume_task_number} onward.
|
|
42
|
+
Follow the same execution rules: per-task commits, deviation handling, verification.
|
|
43
|
+
</resume_from>
|
|
44
|
+
|
|
45
|
+
<context>
|
|
46
|
+
{state_content}
|
|
47
|
+
{config_content}
|
|
48
|
+
</context>
|
|
49
|
+
|
|
50
|
+
<success_criteria>
|
|
51
|
+
- [ ] Previous commits verified (not re-executed)
|
|
52
|
+
- [ ] Remaining tasks executed from task {resume_task_number}
|
|
53
|
+
- [ ] Each task committed individually
|
|
54
|
+
- [ ] SUMMARY.md created covering ALL tasks (including pre-checkpoint)
|
|
55
|
+
- [ ] STATE.md updated with final position
|
|
56
|
+
</success_criteria>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Resume Instructions by Checkpoint Type
|
|
60
|
+
|
|
61
|
+
### checkpoint:human-verify
|
|
62
|
+
```
|
|
63
|
+
The user has verified the previous work.
|
|
64
|
+
- "approved" → Continue to next task normally.
|
|
65
|
+
- Issue description → Fix the reported issue in the current task context before proceeding.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### checkpoint:decision
|
|
69
|
+
```
|
|
70
|
+
The user selected an option for the decision point.
|
|
71
|
+
- Apply the user's choice: {user_response}
|
|
72
|
+
- This may affect how remaining tasks are implemented.
|
|
73
|
+
- Document the decision in SUMMARY.md under "Decisions Made".
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### checkpoint:human-action
|
|
77
|
+
```
|
|
78
|
+
The user completed a manual action (e.g., authentication, external config).
|
|
79
|
+
- "done" → Verify the action succeeded (run verification command if specified).
|
|
80
|
+
- If verification fails, inform user and wait for retry.
|
|
81
|
+
- If verification passes, continue to next task.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Variables
|
|
85
|
+
|
|
86
|
+
| Variable | Source | Description |
|
|
87
|
+
|----------|--------|-------------|
|
|
88
|
+
| `{plan_id}` | Plan frontmatter | e.g., "03-02" |
|
|
89
|
+
| `{resume_task_number}` | Checkpoint return | Task number to resume from |
|
|
90
|
+
| `{resume_task_name}` | Checkpoint return | Name of the resume task |
|
|
91
|
+
| `{completed_tasks_table}` | Checkpoint return | Markdown table of done tasks with commit hashes |
|
|
92
|
+
| `{checkpoint_type}` | Plan XML | human-verify, decision, or human-action |
|
|
93
|
+
| `{user_response}` | User input | What the user provided at the checkpoint |
|
|
94
|
+
| `{resume_instructions}` | This template | Type-specific instructions from above |
|
|
95
|
+
| `{plan_path}` | Phase directory | Path to the PLAN.md file |
|
|
96
|
+
| `{state_content}` | STATE.md | Inlined project state |
|
|
97
|
+
| `{config_content}` | config.json | Inlined project config |
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# How Qualia Works — Developer Guide
|
|
2
|
+
|
|
3
|
+
> This is everything you need to know. Follow the flow, type the commands. The framework handles the rest.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Big Picture
|
|
8
|
+
|
|
9
|
+
Every project follows one path:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Start → Build → Polish → Review → PR → Deploy → Handoff
|
|
13
|
+
70% 100%
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The framework tells you what to do at every step. When in doubt, type `/qualia` — it reads your project state and tells you the exact next command.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Starting a Project
|
|
21
|
+
|
|
22
|
+
You get assigned a project. Here's what you do:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
/qualia-new-project ← answers questions, sets everything up
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This creates a `.planning/` folder with your roadmap, requirements, and phases. You don't need to understand the files — the framework reads them for you.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## The Build Cycle (repeat for each phase)
|
|
33
|
+
|
|
34
|
+
Your roadmap has phases (Phase 1, Phase 2, etc.). For each one:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
/qualia-plan-phase 1 ← creates the plan
|
|
38
|
+
/qualia-execute-phase 1 ← builds it
|
|
39
|
+
/qualia-verify-work 1 ← tests it
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Then move to the next phase. The framework tells you when to move on.
|
|
43
|
+
|
|
44
|
+
**Don't memorize this.** After each command finishes, it tells you what's next. Or type `/qualia` anytime.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## The Finish Line (this is where most people stall)
|
|
49
|
+
|
|
50
|
+
When all phases are done, you're about 70% done. The framework now guides you through:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
✓ Build phases ← you already did this
|
|
54
|
+
✓ Milestone audit ← framework runs this
|
|
55
|
+
✓ Milestone archived ← framework does this
|
|
56
|
+
▶ Design polish ← /critique → /polish → /harden
|
|
57
|
+
· Code review ← /qualia-review --web
|
|
58
|
+
· Pull request ← /pr
|
|
59
|
+
· Deploy ← Fawzi handles this
|
|
60
|
+
· Client handoff ← /client-handoff
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The framework walks you through each step. Just keep typing `/qualia` to see what's next.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## The 10 Commands That Matter
|
|
68
|
+
|
|
69
|
+
| When | Command | What it does |
|
|
70
|
+
|------|---------|-------------|
|
|
71
|
+
| **Starting** | `/qualia-new-project` | Sets up everything from scratch |
|
|
72
|
+
| **Building** | `/qualia-plan-phase N` | Plans a phase |
|
|
73
|
+
| | `/qualia-execute-phase N` | Builds it |
|
|
74
|
+
| | `/qualia-verify-work N` | Tests it |
|
|
75
|
+
| **Polishing** | `/critique` | Reviews the design |
|
|
76
|
+
| | `/polish` | Fixes spacing, alignment, details |
|
|
77
|
+
| | `/harden` | Handles edge cases, errors, overflow |
|
|
78
|
+
| **Shipping** | `/qualia-review --web` | Code quality + security audit |
|
|
79
|
+
| | `/pr` | Creates a pull request |
|
|
80
|
+
| **Anytime** | `/qualia` | "What should I do next?" |
|
|
81
|
+
|
|
82
|
+
Everything else is optional. These 10 get the job done.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## When You're Stuck
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
/qualia ← "what's next?" — reads state, tells you the command
|
|
90
|
+
/qualia-idk ← "I'm lost" — analyzes everything, suggests a path
|
|
91
|
+
/qualia-debug ← "something is broken" — structured debugging
|
|
92
|
+
/qualia-progress ← "where am I?" — full progress report
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
If none of those help, paste the error and ask Claude directly. If Claude can't fix it, escalate to Fawzi.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Session Start / End
|
|
100
|
+
|
|
101
|
+
**Every session starts the same way.** Claude automatically runs `/qualia-start` which shows you:
|
|
102
|
+
- What project you're in
|
|
103
|
+
- What branch you're on
|
|
104
|
+
- System health
|
|
105
|
+
- What to do next
|
|
106
|
+
|
|
107
|
+
**When you're done for the day:**
|
|
108
|
+
```
|
|
109
|
+
/qualia-pause-work ← saves your context for next time
|
|
110
|
+
/qualia-report ← logs what you did (Fawzi reviews these)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**When you come back:**
|
|
114
|
+
```
|
|
115
|
+
/qualia-resume-work ← picks up where you left off
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Rules (non-negotiable)
|
|
121
|
+
|
|
122
|
+
1. **Feature branches only** — never push to main. The framework blocks it automatically.
|
|
123
|
+
2. **Read before write** — don't edit files you haven't read.
|
|
124
|
+
3. **MVP first** — build what's asked, nothing extra.
|
|
125
|
+
4. **Push to GitHub** — you push code. Fawzi deploys to production.
|
|
126
|
+
5. **`/qualia` is your friend** — lost? type it. It always knows what's next.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## What the Framework Does Behind the Scenes
|
|
131
|
+
|
|
132
|
+
You don't need to understand this, but if you're curious:
|
|
133
|
+
|
|
134
|
+
- **Hooks** run automatically on certain actions (commits, deploys, file writes). They enforce rules like "no pushing to main" and "no editing .env files." If a hook blocks you, it tells you why and how to fix it.
|
|
135
|
+
- **Skills** are the `/commands` you type. They're like recipes — each one does a specific thing.
|
|
136
|
+
- **Agents** are AI workers that skills spawn to do heavy lifting (research, verification, code review). You don't interact with them directly.
|
|
137
|
+
- **`.planning/`** is where the framework tracks everything about your project. Don't edit these files manually — the framework manages them.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Quick Reference Card
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
◆ QUALIA DEVELOPER FLOW
|
|
145
|
+
|
|
146
|
+
/qualia-new-project
|
|
147
|
+
↓
|
|
148
|
+
For each phase:
|
|
149
|
+
/qualia-plan-phase N
|
|
150
|
+
/qualia-execute-phase N
|
|
151
|
+
/qualia-verify-work N
|
|
152
|
+
↓
|
|
153
|
+
/qualia-complete-milestone
|
|
154
|
+
↓
|
|
155
|
+
FINISH LINE:
|
|
156
|
+
/critique → /polish → /harden
|
|
157
|
+
/qualia-review --web
|
|
158
|
+
/pr
|
|
159
|
+
↓
|
|
160
|
+
Fawzi deploys
|
|
161
|
+
↓
|
|
162
|
+
/client-handoff
|
|
163
|
+
↓
|
|
164
|
+
Done.
|
|
165
|
+
|
|
166
|
+
Lost? Type /qualia
|
|
167
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Lab Notes — [Project Name]
|
|
2
|
+
|
|
3
|
+
> What failed, why it failed, and what worked instead.
|
|
4
|
+
> Read by planners and researchers to avoid repeating dead-end approaches.
|
|
5
|
+
> Updated via `/learn` or manually during debugging sessions.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Entry format:
|
|
10
|
+
### Phase N: [Phase Title]
|
|
11
|
+
|
|
12
|
+
**Tried:** [approach that was attempted]
|
|
13
|
+
**Failed because:** [root cause — be specific]
|
|
14
|
+
**Better approach:** [what actually worked, or what to try next]
|
|
15
|
+
**Date:** YYYY-MM-DD
|
|
16
|
+
-->
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
|
|
75
75
|
### Phase 4: Admin Panel
|
|
76
76
|
**Goal:** Admin interface for managing the AI agent: prompts, users, analytics
|
|
77
|
-
**Skills:** [@
|
|
77
|
+
**Skills:** [@supabase, @frontend-master]
|
|
78
78
|
**Tasks:**
|
|
79
79
|
- Admin auth (role-based, separate from user auth)
|
|
80
80
|
- System prompt editor (CRUD, version history)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Project Template: Voice Agent
|
|
2
2
|
|
|
3
|
-
> Voice AI agent with Supabase Edge Functions,
|
|
3
|
+
> Voice AI agent with Supabase Edge Functions, Retell AI, and ElevenLabs.
|
|
4
4
|
|
|
5
|
-
**Stack:** Supabase Edge Functions (Deno),
|
|
5
|
+
**Stack:** Supabase Edge Functions (Deno), Retell AI, ElevenLabs, TypeScript
|
|
6
6
|
**Phases:** 6
|
|
7
7
|
**Type:** voice-agent
|
|
8
8
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
**Tasks:**
|
|
15
15
|
- Design Supabase schema: calls, call_events, contacts, tools, system_config
|
|
16
16
|
- Create edge function scaffold (Deno, cors headers, error handling)
|
|
17
|
-
- Configure
|
|
17
|
+
- Configure Retell AI: API keys, agent creation, ElevenLabs voice selection
|
|
18
18
|
- Environment variables in Supabase (voice provider keys, webhook secret)
|
|
19
19
|
- Basic webhook endpoint that receives and logs call events
|
|
20
20
|
- RLS policies on all tables
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
**Skills:** [@voice-agent]
|
|
33
33
|
**Tasks:**
|
|
34
34
|
- Design conversation flow (state machine: greeting → discovery → action → closing)
|
|
35
|
-
- Create
|
|
35
|
+
- Create Retell AI agent configuration (system prompt, voice, language)
|
|
36
36
|
- Define conversation states and transitions
|
|
37
37
|
- Slot filling logic (extract key info from conversation)
|
|
38
38
|
- Multi-language support (if applicable — e.g., Greek/English/Russian)
|
|
@@ -113,6 +113,10 @@ Phases execute in numeric order: 2 → 2.1 → 2.2 → 3 → 3.1 → 4
|
|
|
113
113
|
- Progress table updated by execute workflow
|
|
114
114
|
- Plan count can be "TBD" initially, refined during planning
|
|
115
115
|
|
|
116
|
+
**FEATURE PHASES ONLY — Do NOT add review, deploy, or handoff phases to the roadmap.**
|
|
117
|
+
|
|
118
|
+
The finish line system handles polish → review → PR → deploy → handoff automatically after all feature phases are done (`/qualia-complete-milestone` triggers it). Adding them as roadmap phases causes employees to do the work twice.
|
|
119
|
+
|
|
116
120
|
**Success criteria:**
|
|
117
121
|
- 2-5 observable behaviors per phase (from user's perspective)
|
|
118
122
|
- Cross-checked against requirements during roadmap creation
|
|
@@ -21,6 +21,7 @@ See: .planning/PROJECT.md (updated [date])
|
|
|
21
21
|
Phase: [X] of [Y] ([Phase name])
|
|
22
22
|
Plan: [A] of [B] in current phase
|
|
23
23
|
Status: [Ready to plan / Planning / Ready to execute / In progress / Phase complete]
|
|
24
|
+
Assigned to: [employee name or "unassigned"]
|
|
24
25
|
Last activity: [YYYY-MM-DD] — [What happened]
|
|
25
26
|
|
|
26
27
|
Progress: [░░░░░░░░░░] 0%
|
|
@@ -69,6 +70,7 @@ None yet.
|
|
|
69
70
|
## Session Continuity
|
|
70
71
|
|
|
71
72
|
Last session: [YYYY-MM-DD HH:MM]
|
|
73
|
+
Last worked by: [employee name]
|
|
72
74
|
Stopped at: [Description of last completed action]
|
|
73
75
|
Resume file: [Path to .continue-here*.md if exists, otherwise "None"]
|
|
74
76
|
```
|
|
@@ -127,6 +129,7 @@ Where we are right now:
|
|
|
127
129
|
- Phase X of Y — which phase
|
|
128
130
|
- Plan A of B — which plan within phase
|
|
129
131
|
- Status — current state
|
|
132
|
+
- Assigned to — which employee is working on this phase
|
|
130
133
|
- Last activity — what happened most recently
|
|
131
134
|
- Progress bar — visual indicator of overall completion
|
|
132
135
|
|