qualia-framework 2.6.0 → 3.1.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 +108 -30
- package/agents/builder.md +110 -0
- package/agents/planner.md +186 -0
- package/agents/qa-browser.md +186 -0
- package/agents/verifier.md +369 -0
- package/bin/cli.js +691 -492
- package/bin/install.js +622 -0
- package/bin/qualia-ui.js +284 -0
- package/bin/state.js +824 -0
- package/bin/statusline.js +252 -0
- package/docs/erp-contract.md +161 -0
- package/guide.md +63 -0
- package/hooks/auto-update.js +117 -0
- package/hooks/block-env-edit.js +52 -0
- package/hooks/branch-guard.js +68 -0
- package/hooks/migration-guard.js +83 -0
- package/hooks/pre-compact.js +52 -0
- package/hooks/pre-deploy-gate.js +149 -0
- package/hooks/pre-push.js +53 -0
- package/hooks/session-start.js +126 -0
- package/package.json +30 -20
- package/rules/design-reference.md +179 -0
- package/rules/frontend.md +126 -0
- package/rules/infrastructure.md +87 -0
- package/skills/qualia/SKILL.md +88 -0
- package/skills/qualia-build/SKILL.md +115 -0
- package/skills/qualia-debug/SKILL.md +87 -0
- package/skills/qualia-design/SKILL.md +99 -0
- package/skills/qualia-handoff/SKILL.md +66 -0
- package/skills/qualia-help/SKILL.md +60 -0
- package/skills/qualia-idk/SKILL.md +8 -0
- package/skills/qualia-learn/SKILL.md +111 -0
- package/skills/qualia-new/SKILL.md +323 -0
- package/skills/qualia-pause/SKILL.md +63 -0
- package/skills/qualia-plan/SKILL.md +101 -0
- package/skills/qualia-polish/SKILL.md +207 -0
- package/skills/qualia-quick/SKILL.md +37 -0
- package/skills/qualia-report/SKILL.md +114 -0
- package/skills/qualia-resume/SKILL.md +49 -0
- package/skills/qualia-review/SKILL.md +161 -0
- package/skills/qualia-ship/SKILL.md +90 -0
- package/skills/qualia-skill-new/SKILL.md +167 -0
- package/skills/qualia-task/SKILL.md +91 -0
- package/skills/qualia-test/SKILL.md +134 -0
- package/skills/qualia-verify/SKILL.md +113 -0
- package/templates/DESIGN.md +475 -0
- package/templates/help.html +476 -0
- package/templates/plan.md +42 -0
- package/templates/project.md +22 -0
- package/templates/state.md +27 -0
- package/templates/tracking.json +20 -0
- package/tests/bin.test.sh +687 -0
- package/tests/hooks.test.sh +384 -0
- package/tests/runner.js +1956 -0
- package/tests/state.test.sh +713 -0
- package/tests/statusline.test.sh +243 -0
- package/bin/collect-metrics.sh +0 -62
- package/framework/.claudeignore +0 -51
- package/framework/CLAUDE.md +0 -51
- package/framework/MCP_SETUP.md +0 -229
- package/framework/agents/architecture-strategist.md +0 -53
- package/framework/agents/backend-agent.md +0 -150
- package/framework/agents/code-simplicity-reviewer.md +0 -86
- package/framework/agents/frontend-agent.md +0 -111
- package/framework/agents/kieran-typescript-reviewer.md +0 -96
- package/framework/agents/performance-oracle.md +0 -111
- package/framework/agents/qualia-codebase-mapper.md +0 -761
- package/framework/agents/qualia-debugger.md +0 -1204
- package/framework/agents/qualia-executor.md +0 -882
- package/framework/agents/qualia-integration-checker.md +0 -424
- package/framework/agents/qualia-phase-researcher.md +0 -457
- package/framework/agents/qualia-plan-checker.md +0 -700
- package/framework/agents/qualia-planner.md +0 -1245
- package/framework/agents/qualia-project-researcher.md +0 -603
- package/framework/agents/qualia-research-synthesizer.md +0 -200
- package/framework/agents/qualia-roadmapper.md +0 -606
- package/framework/agents/qualia-verifier.md +0 -686
- package/framework/agents/red-team-qa.md +0 -130
- package/framework/agents/security-auditor.md +0 -72
- package/framework/agents/team-orchestrator.md +0 -229
- package/framework/agents/teams/framework-audit-team.md +0 -66
- package/framework/agents/teams/full-stack-team.md +0 -48
- package/framework/agents/teams/optimize-team.md +0 -53
- package/framework/agents/teams/review-team.md +0 -70
- package/framework/agents/teams/ship-team.md +0 -86
- package/framework/agents/test-agent.md +0 -182
- package/framework/hooks/auto-format.sh +0 -54
- package/framework/hooks/block-env-edit.sh +0 -42
- package/framework/hooks/branch-guard.sh +0 -43
- package/framework/hooks/confirm-delete.sh +0 -59
- package/framework/hooks/migration-validate.sh +0 -77
- package/framework/hooks/notification-speak.sh +0 -16
- package/framework/hooks/pre-commit.sh +0 -100
- package/framework/hooks/pre-compact.sh +0 -56
- package/framework/hooks/pre-deploy-gate.sh +0 -160
- package/framework/hooks/qualia-colors.sh +0 -32
- package/framework/hooks/retention-cleanup.sh +0 -62
- package/framework/hooks/save-session-state.sh +0 -185
- package/framework/hooks/session-context-loader.sh +0 -96
- package/framework/hooks/session-learn.sh +0 -32
- package/framework/hooks/skill-announce.sh +0 -123
- package/framework/hooks/tool-error-announce.sh +0 -27
- package/framework/install.ps1 +0 -323
- package/framework/install.sh +0 -313
- package/framework/qualia-framework/VERSION +0 -1
- package/framework/qualia-framework/assets/qualia-logo.png +0 -0
- package/framework/qualia-framework/bin/collect-metrics.sh +0 -67
- package/framework/qualia-framework/bin/generate-report-docx.py +0 -429
- package/framework/qualia-framework/bin/qualia-tools.js +0 -2201
- package/framework/qualia-framework/bin/qualia-tools.test.js +0 -1054
- package/framework/qualia-framework/references/checkpoints.md +0 -775
- package/framework/qualia-framework/references/completion-checklists.md +0 -359
- package/framework/qualia-framework/references/continuation-format.md +0 -249
- package/framework/qualia-framework/references/continuation-prompt.md +0 -97
- package/framework/qualia-framework/references/decimal-phase-calculation.md +0 -65
- package/framework/qualia-framework/references/design-quality.md +0 -56
- package/framework/qualia-framework/references/employee-guide.md +0 -167
- package/framework/qualia-framework/references/git-integration.md +0 -254
- package/framework/qualia-framework/references/git-planning-commit.md +0 -50
- package/framework/qualia-framework/references/model-profile-resolution.md +0 -32
- package/framework/qualia-framework/references/model-profiles.md +0 -73
- package/framework/qualia-framework/references/phase-argument-parsing.md +0 -61
- package/framework/qualia-framework/references/planning-config.md +0 -195
- package/framework/qualia-framework/references/questioning.md +0 -141
- package/framework/qualia-framework/references/tdd.md +0 -263
- package/framework/qualia-framework/references/ui-brand.md +0 -160
- package/framework/qualia-framework/references/verification-patterns.md +0 -612
- package/framework/qualia-framework/templates/DEBUG.md +0 -159
- package/framework/qualia-framework/templates/DESIGN.md +0 -81
- package/framework/qualia-framework/templates/UAT.md +0 -247
- package/framework/qualia-framework/templates/codebase/architecture.md +0 -255
- package/framework/qualia-framework/templates/codebase/concerns.md +0 -310
- package/framework/qualia-framework/templates/codebase/conventions.md +0 -307
- package/framework/qualia-framework/templates/codebase/integrations.md +0 -280
- package/framework/qualia-framework/templates/codebase/stack.md +0 -186
- package/framework/qualia-framework/templates/codebase/structure.md +0 -285
- package/framework/qualia-framework/templates/codebase/testing.md +0 -480
- package/framework/qualia-framework/templates/config.json +0 -35
- package/framework/qualia-framework/templates/context.md +0 -283
- package/framework/qualia-framework/templates/continue-here.md +0 -78
- package/framework/qualia-framework/templates/debug-subagent-prompt.md +0 -91
- package/framework/qualia-framework/templates/discovery.md +0 -146
- package/framework/qualia-framework/templates/lab-notes.md +0 -16
- package/framework/qualia-framework/templates/milestone-archive.md +0 -123
- package/framework/qualia-framework/templates/milestone.md +0 -115
- package/framework/qualia-framework/templates/phase-prompt.md +0 -567
- package/framework/qualia-framework/templates/planner-subagent-prompt.md +0 -117
- package/framework/qualia-framework/templates/project.md +0 -184
- package/framework/qualia-framework/templates/projects/ai-agent.md +0 -156
- package/framework/qualia-framework/templates/projects/mobile-app.md +0 -181
- package/framework/qualia-framework/templates/projects/voice-agent.md +0 -134
- package/framework/qualia-framework/templates/projects/website.md +0 -137
- package/framework/qualia-framework/templates/requirements.md +0 -231
- package/framework/qualia-framework/templates/research-project/ARCHITECTURE.md +0 -204
- package/framework/qualia-framework/templates/research-project/FEATURES.md +0 -147
- package/framework/qualia-framework/templates/research-project/PITFALLS.md +0 -200
- package/framework/qualia-framework/templates/research-project/STACK.md +0 -120
- package/framework/qualia-framework/templates/research-project/SUMMARY.md +0 -170
- package/framework/qualia-framework/templates/research.md +0 -552
- package/framework/qualia-framework/templates/roadmap.md +0 -206
- package/framework/qualia-framework/templates/state.md +0 -179
- package/framework/qualia-framework/templates/summary-complex.md +0 -59
- package/framework/qualia-framework/templates/summary-minimal.md +0 -41
- package/framework/qualia-framework/templates/summary-standard.md +0 -48
- package/framework/qualia-framework/templates/summary.md +0 -246
- package/framework/qualia-framework/templates/user-setup.md +0 -311
- package/framework/qualia-framework/templates/verification-report.md +0 -322
- package/framework/qualia-framework/workflows/add-phase.md +0 -179
- package/framework/qualia-framework/workflows/add-todo.md +0 -157
- package/framework/qualia-framework/workflows/audit-milestone.md +0 -241
- package/framework/qualia-framework/workflows/check-todos.md +0 -176
- package/framework/qualia-framework/workflows/complete-milestone.md +0 -858
- package/framework/qualia-framework/workflows/diagnose-issues.md +0 -219
- package/framework/qualia-framework/workflows/discovery-phase.md +0 -289
- package/framework/qualia-framework/workflows/discuss-phase.md +0 -534
- package/framework/qualia-framework/workflows/execute-phase.md +0 -559
- package/framework/qualia-framework/workflows/execute-plan.md +0 -438
- package/framework/qualia-framework/workflows/help.md +0 -470
- package/framework/qualia-framework/workflows/insert-phase.md +0 -220
- package/framework/qualia-framework/workflows/list-phase-assumptions.md +0 -178
- package/framework/qualia-framework/workflows/map-codebase.md +0 -327
- package/framework/qualia-framework/workflows/new-milestone.md +0 -363
- package/framework/qualia-framework/workflows/new-project.md +0 -982
- package/framework/qualia-framework/workflows/pause-work.md +0 -122
- package/framework/qualia-framework/workflows/plan-milestone-gaps.md +0 -256
- package/framework/qualia-framework/workflows/plan-phase.md +0 -422
- package/framework/qualia-framework/workflows/progress.md +0 -389
- package/framework/qualia-framework/workflows/quick.md +0 -252
- package/framework/qualia-framework/workflows/remove-phase.md +0 -326
- package/framework/qualia-framework/workflows/research-phase.md +0 -74
- package/framework/qualia-framework/workflows/resume-project.md +0 -306
- package/framework/qualia-framework/workflows/set-profile.md +0 -80
- package/framework/qualia-framework/workflows/settings.md +0 -145
- package/framework/qualia-framework/workflows/transition.md +0 -556
- package/framework/qualia-framework/workflows/update.md +0 -197
- package/framework/qualia-framework/workflows/verify-phase.md +0 -195
- package/framework/qualia-framework/workflows/verify-work.md +0 -625
- package/framework/rules/context7.md +0 -14
- package/framework/rules/frontend.md +0 -33
- package/framework/rules/speed.md +0 -23
- package/framework/scripts/__pycache__/say.cpython-314.pyc +0 -0
- package/framework/scripts/apply-retention.sh +0 -120
- package/framework/scripts/bootstrap-pop-os.sh +0 -354
- package/framework/scripts/claude-voice +0 -13
- package/framework/scripts/cleanup.sh +0 -131
- package/framework/scripts/cowork-mode.sh +0 -141
- package/framework/scripts/generate-project-claude-md.sh +0 -153
- package/framework/scripts/load-test-webhook.js +0 -172
- package/framework/scripts/say.py +0 -236
- package/framework/scripts/showcase-video-recorder/ffmpeg-builder.js +0 -167
- package/framework/scripts/showcase-video-recorder/playwright-helpers.js +0 -216
- package/framework/scripts/speak.py +0 -55
- package/framework/scripts/speak.sh +0 -18
- package/framework/scripts/status.sh +0 -138
- package/framework/scripts/sync-to-framework.sh +0 -65
- package/framework/scripts/voice-hotkey.py +0 -227
- package/framework/scripts/voice-input.sh +0 -51
- package/framework/skills/animate/SKILL.md +0 -202
- package/framework/skills/bolder/SKILL.md +0 -144
- package/framework/skills/browser-qa/SKILL.md +0 -536
- package/framework/skills/clarify/SKILL.md +0 -179
- package/framework/skills/client-handoff/SKILL.md +0 -135
- package/framework/skills/collab-onboard/SKILL.md +0 -111
- package/framework/skills/colorize/SKILL.md +0 -170
- package/framework/skills/critique/SKILL.md +0 -126
- package/framework/skills/deep-research/SKILL.md +0 -240
- package/framework/skills/delight/SKILL.md +0 -329
- package/framework/skills/deploy/SKILL.md +0 -261
- package/framework/skills/deploy-verify/SKILL.md +0 -377
- package/framework/skills/deploy-verify/scripts/canary-check.sh +0 -206
- package/framework/skills/deploy-verify/scripts/check-console-errors.js +0 -147
- package/framework/skills/deploy-verify/scripts/check-cwv.js +0 -139
- package/framework/skills/deploy-verify/scripts/project-detect.sh +0 -84
- package/framework/skills/deploy-verify/scripts/verify.sh +0 -548
- package/framework/skills/design-quieter/SKILL.md +0 -130
- package/framework/skills/distill/SKILL.md +0 -149
- package/framework/skills/docs-lookup/SKILL.md +0 -79
- package/framework/skills/fcm-notifications/SKILL.md +0 -125
- package/framework/skills/financial-ledger/SKILL.md +0 -1039
- package/framework/skills/frontend-master/NOTICE.md +0 -4
- package/framework/skills/frontend-master/SKILL.md +0 -127
- package/framework/skills/frontend-master/reference/color-and-contrast.md +0 -132
- package/framework/skills/frontend-master/reference/interaction-design.md +0 -123
- package/framework/skills/frontend-master/reference/motion-design.md +0 -99
- package/framework/skills/frontend-master/reference/responsive-design.md +0 -114
- package/framework/skills/frontend-master/reference/spatial-design.md +0 -100
- package/framework/skills/frontend-master/reference/typography.md +0 -131
- package/framework/skills/frontend-master/reference/ux-writing.md +0 -107
- package/framework/skills/harden/SKILL.md +0 -357
- package/framework/skills/i18n-rtl/SKILL.md +0 -752
- package/framework/skills/learn/SKILL.md +0 -95
- package/framework/skills/memory/SKILL.md +0 -50
- package/framework/skills/mobile-expo/SKILL.md +0 -977
- package/framework/skills/mobile-expo/references/store-checklist.md +0 -550
- package/framework/skills/nestjs-backend/README.md +0 -73
- package/framework/skills/nestjs-backend/SKILL.md +0 -446
- package/framework/skills/nestjs-backend/references/templates.md +0 -1173
- package/framework/skills/normalize/SKILL.md +0 -79
- package/framework/skills/onboard/SKILL.md +0 -242
- package/framework/skills/openrouter-agent/SKILL.md +0 -922
- package/framework/skills/polish/SKILL.md +0 -209
- package/framework/skills/pr/SKILL.md +0 -66
- package/framework/skills/qualia/SKILL.md +0 -199
- package/framework/skills/qualia-add-todo/SKILL.md +0 -68
- package/framework/skills/qualia-audit-milestone/SKILL.md +0 -95
- package/framework/skills/qualia-check-todos/SKILL.md +0 -55
- package/framework/skills/qualia-complete-milestone/SKILL.md +0 -134
- package/framework/skills/qualia-debug/SKILL.md +0 -149
- package/framework/skills/qualia-design/SKILL.md +0 -203
- package/framework/skills/qualia-discuss-phase/SKILL.md +0 -72
- package/framework/skills/qualia-evolve/SKILL.md +0 -200
- package/framework/skills/qualia-execute-phase/SKILL.md +0 -89
- package/framework/skills/qualia-framework-audit/SKILL.md +0 -604
- package/framework/skills/qualia-guide/SKILL.md +0 -32
- package/framework/skills/qualia-help/SKILL.md +0 -114
- package/framework/skills/qualia-idk/SKILL.md +0 -352
- package/framework/skills/qualia-list-phase-assumptions/SKILL.md +0 -67
- package/framework/skills/qualia-new-milestone/SKILL.md +0 -72
- package/framework/skills/qualia-new-project/SKILL.md +0 -232
- package/framework/skills/qualia-optimize/SKILL.md +0 -417
- package/framework/skills/qualia-pause-work/SKILL.md +0 -96
- package/framework/skills/qualia-plan-milestone-gaps/SKILL.md +0 -57
- package/framework/skills/qualia-plan-phase/SKILL.md +0 -104
- package/framework/skills/qualia-production-check/SKILL.md +0 -0
- package/framework/skills/qualia-progress/SKILL.md +0 -53
- package/framework/skills/qualia-quick/SKILL.md +0 -89
- package/framework/skills/qualia-report/SKILL.md +0 -166
- package/framework/skills/qualia-research-phase/SKILL.md +0 -88
- package/framework/skills/qualia-resume-work/SKILL.md +0 -62
- package/framework/skills/qualia-review/SKILL.md +0 -263
- package/framework/skills/qualia-start/SKILL.md +0 -161
- package/framework/skills/qualia-verify-work/SKILL.md +0 -132
- package/framework/skills/rag/SKILL.md +0 -750
- package/framework/skills/responsive/SKILL.md +0 -231
- package/framework/skills/retro/SKILL.md +0 -284
- package/framework/skills/sakani-conventions/SKILL.md +0 -136
- package/framework/skills/sakani-conventions/evals/evals.json +0 -23
- package/framework/skills/sakani-conventions/references/entities.md +0 -365
- package/framework/skills/sakani-conventions/references/error-codes.md +0 -95
- package/framework/skills/seo-master/SKILL.md +0 -490
- package/framework/skills/seo-master/references/checklist.md +0 -199
- package/framework/skills/seo-master/references/structured-data.md +0 -609
- package/framework/skills/ship/SKILL.md +0 -239
- package/framework/skills/stack-researcher/SKILL.md +0 -215
- package/framework/skills/status/SKILL.md +0 -154
- package/framework/skills/status/scripts/health-check.sh +0 -562
- package/framework/skills/subscription-payments/SKILL.md +0 -250
- package/framework/skills/supabase/SKILL.md +0 -973
- package/framework/skills/supabase/references/templates.md +0 -159
- package/framework/skills/team/SKILL.md +0 -67
- package/framework/skills/test-runner/SKILL.md +0 -202
- package/framework/skills/voice-agent/SKILL.md +0 -1312
- package/framework/skills/zoho-workflow/SKILL.md +0 -51
- package/framework/statusline-command.sh +0 -117
- package/framework/teams/default/inboxes/plan-04.json +0 -9
- package/framework/teams/review-team.md +0 -75
- package/framework/teams/ship-team.md +0 -86
- package/profiles/fawzi.json +0 -16
- package/profiles/hasan.json +0 -16
- package/profiles/moayad.json +0 -16
- package/templates/CLAUDE-owner.md +0 -52
- package/templates/CLAUDE.md.hbs +0 -58
- package/templates/env.claude.template +0 -12
- package/templates/settings.json +0 -172
- package/uninstall.sh +0 -90
- /package/{framework/rules → rules}/deployment.md +0 -0
- /package/{framework/rules → rules}/security.md +0 -0
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Pre-compaction hook — saves context before Claude auto-compacts
|
|
3
|
-
# Preserves: changed files, current task, git state, Qualia phase/milestone, project name
|
|
4
|
-
# Cross-platform: uses node instead of jq for JSON array generation
|
|
5
|
-
|
|
6
|
-
COMPACT_DIR="$HOME/.claude/session-env"
|
|
7
|
-
COMPACT_FILE="$COMPACT_DIR/pre-compact.json"
|
|
8
|
-
|
|
9
|
-
mkdir -p "$COMPACT_DIR"
|
|
10
|
-
|
|
11
|
-
CWD=$(pwd)
|
|
12
|
-
PROJECT_NAME=$(basename "$CWD")
|
|
13
|
-
|
|
14
|
-
GIT_BRANCH=""
|
|
15
|
-
GIT_DIFF_FILES=""
|
|
16
|
-
if git rev-parse --is-inside-work-tree &> /dev/null 2>&1; then
|
|
17
|
-
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "")
|
|
18
|
-
# Use node instead of jq to convert newline-separated file list to JSON array
|
|
19
|
-
GIT_DIFF_FILES=$(git diff --name-only HEAD 2>/dev/null | head -30 | node -e "
|
|
20
|
-
let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{
|
|
21
|
-
const a=d.split('\n').filter(l=>l.length>0);
|
|
22
|
-
process.stdout.write(JSON.stringify(a));
|
|
23
|
-
});" 2>/dev/null)
|
|
24
|
-
fi
|
|
25
|
-
|
|
26
|
-
[ -z "$GIT_DIFF_FILES" ] && GIT_DIFF_FILES="[]"
|
|
27
|
-
|
|
28
|
-
# Parse Qualia state from .planning/STATE.md if it exists
|
|
29
|
-
QUALIA_PHASE=""
|
|
30
|
-
QUALIA_MILESTONE=""
|
|
31
|
-
QUALIA_TASK=""
|
|
32
|
-
QUALIA_STATUS=""
|
|
33
|
-
STATE_FILE="$CWD/.planning/STATE.md"
|
|
34
|
-
if [ -f "$STATE_FILE" ]; then
|
|
35
|
-
QUALIA_PHASE=$(grep -m1 "^Phase:" "$STATE_FILE" 2>/dev/null | sed 's/^Phase: *//' || echo "")
|
|
36
|
-
QUALIA_MILESTONE=$(grep -m1 "^## Milestone" "$STATE_FILE" 2>/dev/null | sed 's/^## //' || echo "")
|
|
37
|
-
QUALIA_STATUS=$(grep -m1 "^Status:" "$STATE_FILE" 2>/dev/null | sed 's/^Status: *//' || echo "")
|
|
38
|
-
QUALIA_TASK=$(grep -m1 "^Last activity:" "$STATE_FILE" 2>/dev/null | sed 's/^Last activity: *//' || echo "")
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
cat > "$COMPACT_FILE" << EOF
|
|
42
|
-
{
|
|
43
|
-
"timestamp": "$(date '+%Y-%m-%d %H:%M:%S')",
|
|
44
|
-
"working_directory": "$CWD",
|
|
45
|
-
"project_name": "$PROJECT_NAME",
|
|
46
|
-
"git_branch": "$GIT_BRANCH",
|
|
47
|
-
"changed_files": $GIT_DIFF_FILES,
|
|
48
|
-
"qualia_phase": "$QUALIA_PHASE",
|
|
49
|
-
"qualia_milestone": "$QUALIA_MILESTONE",
|
|
50
|
-
"qualia_status": "$QUALIA_STATUS",
|
|
51
|
-
"qualia_task": "$QUALIA_TASK"
|
|
52
|
-
}
|
|
53
|
-
EOF
|
|
54
|
-
|
|
55
|
-
printf '{"continue":true}'
|
|
56
|
-
exit 0
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Pre-deploy gate — blocks `vercel --prod` if checks fail
|
|
3
|
-
# Teal-branded output to stderr, JSON systemMessage to stdout
|
|
4
|
-
# Exit 0 = allow, Exit 2 = block
|
|
5
|
-
|
|
6
|
-
source "$(dirname "$0")/qualia-colors.sh"
|
|
7
|
-
|
|
8
|
-
if ! command -v node &>/dev/null; then
|
|
9
|
-
[ ! -t 0 ] && cat > /dev/null
|
|
10
|
-
printf '{"continue":false,"stopReason":"DEPLOY GATE: node is not installed — cannot verify safety. Install node to proceed."}'
|
|
11
|
-
exit 2
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Parse command from stdin JSON
|
|
15
|
-
if [ ! -t 0 ]; then
|
|
16
|
-
INPUT=$(cat)
|
|
17
|
-
COMMAND=$(echo "$INPUT" | node -e "try{const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(d.tool_input?.command||d.tool_input||'')}catch(e){}" 2>/dev/null)
|
|
18
|
-
else
|
|
19
|
-
COMMAND=""
|
|
20
|
-
fi
|
|
21
|
-
|
|
22
|
-
# Skip non-deploy commands first (git, npm, etc. may mention vercel in args/messages)
|
|
23
|
-
case "$COMMAND" in
|
|
24
|
-
git\ *|npm\ *|node\ *|cat\ *|echo\ *|grep\ *|ls\ *|cd\ *) exit 0 ;;
|
|
25
|
-
esac
|
|
26
|
-
|
|
27
|
-
# Only gate actual vercel production deploy commands
|
|
28
|
-
case "$COMMAND" in
|
|
29
|
-
vercel\ *--prod*|npx\ vercel\ *--prod*|bunx\ vercel\ *--prod*|pnpx\ vercel\ *--prod*) ;;
|
|
30
|
-
*) exit 0 ;;
|
|
31
|
-
esac
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# Skip if gate passed recently AND no code changes since
|
|
35
|
-
STAMP="/tmp/.deploy-gate-$(echo "$PWD" | md5sum | cut -c1-8)"
|
|
36
|
-
if [ -f "$STAMP" ]; then
|
|
37
|
-
AGE=$(( $(date +%s) - $(stat -c %Y "$STAMP" 2>/dev/null || echo 0) ))
|
|
38
|
-
DIRTY=$(git status --porcelain 2>/dev/null | head -1)
|
|
39
|
-
if [ "$AGE" -lt 300 ] && [ -z "$DIRTY" ]; then
|
|
40
|
-
exit 0
|
|
41
|
-
fi
|
|
42
|
-
rm -f "$STAMP"
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
q_header "PRE-DEPLOY GATE"
|
|
46
|
-
|
|
47
|
-
FAILURES=0
|
|
48
|
-
WARNINGS=0
|
|
49
|
-
FAIL_DETAILS=""
|
|
50
|
-
|
|
51
|
-
# ─── Check 1: TypeScript ───
|
|
52
|
-
if [ -f "tsconfig.json" ]; then
|
|
53
|
-
if npx tsc --noEmit 2>/tmp/tsc-gate.txt; then
|
|
54
|
-
q_pass "TypeScript"
|
|
55
|
-
else
|
|
56
|
-
q_fail "TypeScript errors"
|
|
57
|
-
FAIL_DETAILS="${FAIL_DETAILS}Code errors found — tell Claude: 'fix the TypeScript errors' before deploying. "
|
|
58
|
-
FAILURES=$((FAILURES + 1))
|
|
59
|
-
fi
|
|
60
|
-
else
|
|
61
|
-
q_skip "TypeScript"
|
|
62
|
-
fi
|
|
63
|
-
|
|
64
|
-
# ─── Check 2: ESLint ───
|
|
65
|
-
if [ -f ".eslintrc.json" ] || [ -f ".eslintrc.js" ] || [ -f "eslint.config.js" ] || [ -f "eslint.config.mjs" ]; then
|
|
66
|
-
if npx eslint . --max-warnings=-1 --quiet 2>/dev/null; then
|
|
67
|
-
q_pass "Lint"
|
|
68
|
-
else
|
|
69
|
-
q_fail "Lint errors"
|
|
70
|
-
FAIL_DETAILS="${FAIL_DETAILS}Code quality issues found — tell Claude: 'fix the lint errors' before deploying. "
|
|
71
|
-
FAILURES=$((FAILURES + 1))
|
|
72
|
-
fi
|
|
73
|
-
else
|
|
74
|
-
q_skip "Lint"
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
# ─── Check 3: Tests ───
|
|
78
|
-
if [ -f "package.json" ]; then
|
|
79
|
-
TEST_SCRIPT=$(node -e "try{console.log(require('./package.json').scripts?.test||'')}catch(e){console.log('')}" 2>/dev/null)
|
|
80
|
-
if [ -n "$TEST_SCRIPT" ] && [ "$TEST_SCRIPT" != 'echo "Error: no test specified" && exit 1' ]; then
|
|
81
|
-
if npm test -- --passWithNoTests 2>/tmp/test-gate.txt 1>/dev/null; then
|
|
82
|
-
q_pass "Tests"
|
|
83
|
-
else
|
|
84
|
-
q_fail "Tests failed"
|
|
85
|
-
FAIL_DETAILS="${FAIL_DETAILS}Tests are failing — tell Claude: 'fix the failing tests' before deploying. "
|
|
86
|
-
FAILURES=$((FAILURES + 1))
|
|
87
|
-
fi
|
|
88
|
-
else
|
|
89
|
-
q_skip "Tests"
|
|
90
|
-
fi
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
# ─── Check 4: Environment ───
|
|
94
|
-
if [ -f ".env.example" ] && [ ! -f ".env.local" ] && [ ! -f ".env" ]; then
|
|
95
|
-
q_warn "Missing .env.local"
|
|
96
|
-
WARNINGS=$((WARNINGS + 1))
|
|
97
|
-
else
|
|
98
|
-
q_pass "Environment"
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
# ─── Check 5: Build ───
|
|
102
|
-
if [ -f "package.json" ]; then
|
|
103
|
-
BUILD_SCRIPT=$(node -e "try{console.log(require('./package.json').scripts?.build||'')}catch(e){console.log('')}" 2>/dev/null)
|
|
104
|
-
if [ -n "$BUILD_SCRIPT" ]; then
|
|
105
|
-
if npm run build 2>/tmp/build-gate.txt 1>/dev/null; then
|
|
106
|
-
q_pass "Build"
|
|
107
|
-
else
|
|
108
|
-
q_fail "Build failed"
|
|
109
|
-
FAIL_DETAILS="${FAIL_DETAILS}Build is failing — tell Claude: 'fix the build errors' before deploying. "
|
|
110
|
-
FAILURES=$((FAILURES + 1))
|
|
111
|
-
fi
|
|
112
|
-
else
|
|
113
|
-
q_skip "Build"
|
|
114
|
-
fi
|
|
115
|
-
fi
|
|
116
|
-
|
|
117
|
-
# ─── Check 6: REVIEW.md ───
|
|
118
|
-
REVIEW_FILE=""
|
|
119
|
-
[ -f ".planning/REVIEW.md" ] && REVIEW_FILE=".planning/REVIEW.md"
|
|
120
|
-
[ -z "$REVIEW_FILE" ] && [ -f ".review/REVIEW.md" ] && REVIEW_FILE=".review/REVIEW.md"
|
|
121
|
-
|
|
122
|
-
if [ -z "$REVIEW_FILE" ]; then
|
|
123
|
-
q_fail "No REVIEW.md"
|
|
124
|
-
FAIL_DETAILS="${FAIL_DETAILS}No code review found. Run /qualia-review to generate REVIEW.md. "
|
|
125
|
-
FAILURES=$((FAILURES + 1))
|
|
126
|
-
else
|
|
127
|
-
REVIEW_MTIME=$(stat -c %Y "$REVIEW_FILE" 2>/dev/null || echo 0)
|
|
128
|
-
LATEST_CODE_MTIME=0
|
|
129
|
-
for DIR in src app pages lib components; do
|
|
130
|
-
if [ -d "$DIR" ]; then
|
|
131
|
-
DIR_LATEST=$(find "$DIR" -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \) -printf '%T@\n' 2>/dev/null | sort -rn | head -1 | cut -d. -f1)
|
|
132
|
-
[ -n "$DIR_LATEST" ] && [ "$DIR_LATEST" -gt "$LATEST_CODE_MTIME" ] && LATEST_CODE_MTIME=$DIR_LATEST
|
|
133
|
-
fi
|
|
134
|
-
done
|
|
135
|
-
if [ "$LATEST_CODE_MTIME" -gt 0 ] && [ "$REVIEW_MTIME" -lt "$LATEST_CODE_MTIME" ]; then
|
|
136
|
-
q_fail "REVIEW.md stale"
|
|
137
|
-
FAIL_DETAILS="${FAIL_DETAILS}REVIEW.md is stale. Run /qualia-review to update. "
|
|
138
|
-
FAILURES=$((FAILURES + 1))
|
|
139
|
-
else
|
|
140
|
-
q_pass "Review"
|
|
141
|
-
fi
|
|
142
|
-
fi
|
|
143
|
-
|
|
144
|
-
# ─── Verdict ───
|
|
145
|
-
# Warning only — /ship skill is the real quality gate. Hook is a safety net.
|
|
146
|
-
if [ "$FAILURES" -gt 0 ]; then
|
|
147
|
-
printf '{"continue":true,"systemMessage":"◆ DEPLOY WARNING: %d check(s) failed. %sThe /ship skill should have caught these — if deploying manually, fix first."}' "$FAILURES" "$FAIL_DETAILS"
|
|
148
|
-
exit 0
|
|
149
|
-
fi
|
|
150
|
-
|
|
151
|
-
WARN_MSG=""
|
|
152
|
-
if [ "$WARNINGS" -gt 0 ]; then
|
|
153
|
-
WARN_MSG=" (${WARNINGS} warning(s))"
|
|
154
|
-
fi
|
|
155
|
-
|
|
156
|
-
# Stamp success
|
|
157
|
-
touch "$STAMP"
|
|
158
|
-
|
|
159
|
-
printf '{"continue":true,"systemMessage":"◆ DEPLOY GATE APPROVED%s"}' "$WARN_MSG"
|
|
160
|
-
exit 0
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# Qualia teal brand palette — source this in all hooks
|
|
2
|
-
# Usage: source "$(dirname "$0")/qualia-colors.sh"
|
|
3
|
-
|
|
4
|
-
Q_TEAL='\033[38;2;0;140;130m'
|
|
5
|
-
Q_BRIGHT='\033[38;2;0;200;185m'
|
|
6
|
-
Q_DIM='\033[38;2;0;100;92m'
|
|
7
|
-
Q_WHITE='\033[38;2;230;230;230m'
|
|
8
|
-
Q_PASS='\033[38;2;52;211;153m'
|
|
9
|
-
Q_WARN='\033[38;2;234;179;8m'
|
|
10
|
-
Q_FAIL='\033[38;2;239;68;68m'
|
|
11
|
-
Q_GRAY='\033[38;2;70;78;88m'
|
|
12
|
-
Q_RESET='\033[0m'
|
|
13
|
-
Q_MARK="${Q_BRIGHT}◆${Q_RESET}"
|
|
14
|
-
|
|
15
|
-
# Print a Qualia-branded header line to stderr
|
|
16
|
-
# Usage: q_header "PRE-DEPLOY GATE"
|
|
17
|
-
q_header() {
|
|
18
|
-
printf "${Q_TEAL}━━━${Q_RESET} ${Q_BRIGHT}◆${Q_RESET} ${Q_TEAL}%s${Q_RESET}\n" "$1" >&2
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
# Print a pass/fail/warn/skip line to stderr
|
|
22
|
-
# Usage: q_pass "TypeScript" | q_fail "Build" | q_warn "Env" | q_skip "Tests"
|
|
23
|
-
q_pass() { printf " ${Q_PASS}✓${Q_RESET} ${Q_WHITE}%s${Q_RESET}\n" "$1" >&2; }
|
|
24
|
-
q_fail() { printf " ${Q_FAIL}✗${Q_RESET} ${Q_WHITE}%s${Q_RESET}\n" "$1" >&2; }
|
|
25
|
-
q_warn() { printf " ${Q_WARN}▲${Q_RESET} ${Q_WHITE}%s${Q_RESET}\n" "$1" >&2; }
|
|
26
|
-
q_skip() { printf " ${Q_GRAY}·${Q_RESET} ${Q_GRAY}%s${Q_RESET}\n" "$1" >&2; }
|
|
27
|
-
q_info() { printf " ${Q_DIM}%s${Q_RESET}\n" "$1" >&2; }
|
|
28
|
-
|
|
29
|
-
# Print verdict line to stderr
|
|
30
|
-
# Usage: q_blocked "2 checks failed" | q_approved
|
|
31
|
-
q_blocked() { printf "\n${Q_FAIL}✗${Q_RESET} ${Q_BRIGHT}BLOCKED${Q_RESET} ${Q_DIM}—${Q_RESET} ${Q_WHITE}%s${Q_RESET}\n" "$1" >&2; }
|
|
32
|
-
q_approved(){ printf "\n${Q_PASS}✓${Q_RESET} ${Q_BRIGHT}APPROVED${Q_RESET}\n" >&2; }
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Retention cleanup — runs on SessionStart to enforce retention policies
|
|
3
|
-
# Keeps .claude/ lean by pruning stale data automatically
|
|
4
|
-
# This is the SINGLE SOURCE OF TRUTH for retention — config/retention.json is deprecated
|
|
5
|
-
#
|
|
6
|
-
# Policies:
|
|
7
|
-
# file-history/ 7 days
|
|
8
|
-
# session-env/ 50 JSON files + 10 UUID dirs
|
|
9
|
-
# backups/ 3 days
|
|
10
|
-
# paste-cache/ 3 days
|
|
11
|
-
# shell-snapshots/ 3 days
|
|
12
|
-
# projects/*.jsonl 7 days
|
|
13
|
-
# tasks/ 14 days
|
|
14
|
-
# plans/ 7 days
|
|
15
|
-
|
|
16
|
-
CLAUDE_DIR="$HOME/.claude"
|
|
17
|
-
|
|
18
|
-
# file-history/ — keep 7 days max
|
|
19
|
-
find "$CLAUDE_DIR/file-history/" -type f -mtime +7 -delete 2>/dev/null
|
|
20
|
-
find "$CLAUDE_DIR/file-history/" -type d -empty -delete 2>/dev/null
|
|
21
|
-
|
|
22
|
-
# session-env/ — keep last 10 UUID dirs (sorted by modification time)
|
|
23
|
-
ls -dt "$CLAUDE_DIR/session-env"/*-*-*-*-* 2>/dev/null | tail -n +11 | while IFS= read -r d; do
|
|
24
|
-
rm -rf "$d"
|
|
25
|
-
done
|
|
26
|
-
|
|
27
|
-
# backups/ — keep 3 days
|
|
28
|
-
find "$CLAUDE_DIR/backups/" -type f -mtime +3 -delete 2>/dev/null
|
|
29
|
-
|
|
30
|
-
# paste-cache/ — keep 3 days
|
|
31
|
-
find "$CLAUDE_DIR/paste-cache/" -type f -mtime +3 -delete 2>/dev/null
|
|
32
|
-
|
|
33
|
-
# shell-snapshots/ — keep 3 days
|
|
34
|
-
find "$CLAUDE_DIR/shell-snapshots/" -type f -mtime +3 -delete 2>/dev/null
|
|
35
|
-
|
|
36
|
-
# projects/ session transcripts — keep 7 days (allows --continue on recent sessions)
|
|
37
|
-
find "$CLAUDE_DIR/projects/" -name "*.jsonl" -mtime +7 -delete 2>/dev/null
|
|
38
|
-
find "$CLAUDE_DIR/projects/" -type d -empty -delete 2>/dev/null
|
|
39
|
-
|
|
40
|
-
# tasks/ — keep 14 days (team sessions may span multiple days)
|
|
41
|
-
find "$CLAUDE_DIR/tasks/" -type f -mtime +14 -delete 2>/dev/null
|
|
42
|
-
find "$CLAUDE_DIR/tasks/" -mindepth 1 -type d -empty -delete 2>/dev/null
|
|
43
|
-
|
|
44
|
-
# plans/ — keep 7 days (old Claude Code plan mode files)
|
|
45
|
-
find "$CLAUDE_DIR/plans/" -type f -mtime +7 -delete 2>/dev/null
|
|
46
|
-
|
|
47
|
-
# downloads/ — keep 7 days
|
|
48
|
-
find "$CLAUDE_DIR/downloads/" -type f -mtime +7 -delete 2>/dev/null
|
|
49
|
-
|
|
50
|
-
# image-cache/ — keep 7 days
|
|
51
|
-
find "$CLAUDE_DIR/image-cache/" -type f -mtime +7 -delete 2>/dev/null
|
|
52
|
-
|
|
53
|
-
# thoughts/ — keep 14 days
|
|
54
|
-
find "$CLAUDE_DIR/thoughts/" -type f -mtime +14 -delete 2>/dev/null
|
|
55
|
-
|
|
56
|
-
# session-env/ session_*.json — keep last 50 (matches save-session-state.sh)
|
|
57
|
-
ls -t "$CLAUDE_DIR/session-env"/session_*.json 2>/dev/null | tail -n +51 | while IFS= read -r f; do
|
|
58
|
-
rm -f "$f"
|
|
59
|
-
done
|
|
60
|
-
|
|
61
|
-
printf '{"continue":true}'
|
|
62
|
-
exit 0
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# SessionEnd hook — saves session state + updates rolling digest + auto-handoff
|
|
3
|
-
# Enhanced: cross-project session digest, auto .continue-here.md for significant work
|
|
4
|
-
|
|
5
|
-
SESSION_DIR="$HOME/.claude/session-env"
|
|
6
|
-
KNOWLEDGE_DIR="$HOME/.claude/knowledge"
|
|
7
|
-
DIGEST_FILE="$KNOWLEDGE_DIR/session-digest.md"
|
|
8
|
-
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
9
|
-
SESSION_FILE="$SESSION_DIR/session_$TIMESTAMP.json"
|
|
10
|
-
|
|
11
|
-
# Skip saving for very short sessions (< 30s) to reduce cruft
|
|
12
|
-
SESSION_START_FILE="$SESSION_DIR/.session-start"
|
|
13
|
-
if [ -f "$SESSION_START_FILE" ]; then
|
|
14
|
-
START_TS=$(cat "$SESSION_START_FILE" 2>/dev/null || echo 0)
|
|
15
|
-
NOW_TS=$(date +%s)
|
|
16
|
-
DURATION=$((NOW_TS - START_TS))
|
|
17
|
-
if [ "$DURATION" -lt 30 ]; then
|
|
18
|
-
printf '{"continue":true}'
|
|
19
|
-
exit 0
|
|
20
|
-
fi
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
mkdir -p "$SESSION_DIR"
|
|
24
|
-
mkdir -p "$KNOWLEDGE_DIR"
|
|
25
|
-
|
|
26
|
-
CWD=$(pwd)
|
|
27
|
-
PROJECT_NAME=$(basename "$CWD")
|
|
28
|
-
|
|
29
|
-
# --- Git info ---
|
|
30
|
-
GIT_BRANCH=""
|
|
31
|
-
GIT_STATUS=""
|
|
32
|
-
FILES_CHANGED=0
|
|
33
|
-
LAST_COMMIT_MSG=""
|
|
34
|
-
if git rev-parse --is-inside-work-tree &> /dev/null 2>&1; then
|
|
35
|
-
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "")
|
|
36
|
-
GIT_STATUS=$(git status --porcelain 2>/dev/null | head -20 || echo "")
|
|
37
|
-
# Count ALL files changed: committed in last 2 hours + uncommitted + staged
|
|
38
|
-
COMMITTED=$(git diff --name-only "$(git log --since='2 hours ago' --format=%H | tail -1 2>/dev/null || echo HEAD)" HEAD 2>/dev/null | wc -l || echo 0)
|
|
39
|
-
UNCOMMITTED=$(git diff --name-only 2>/dev/null | wc -l || echo 0)
|
|
40
|
-
STAGED=$(git diff --cached --name-only 2>/dev/null | wc -l || echo 0)
|
|
41
|
-
FILES_CHANGED=$((COMMITTED + UNCOMMITTED + STAGED))
|
|
42
|
-
LAST_COMMIT_MSG=$(git log --oneline -1 --format="%s" 2>/dev/null || echo "")
|
|
43
|
-
fi
|
|
44
|
-
|
|
45
|
-
# --- Summary line (from last commit or branch name) ---
|
|
46
|
-
SUMMARY=""
|
|
47
|
-
if [ -n "$LAST_COMMIT_MSG" ]; then
|
|
48
|
-
SUMMARY="$LAST_COMMIT_MSG"
|
|
49
|
-
elif [ -n "$GIT_BRANCH" ]; then
|
|
50
|
-
SUMMARY="Working on $GIT_BRANCH"
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
# --- Save session JSON ---
|
|
54
|
-
cat > "$SESSION_FILE" << EOF
|
|
55
|
-
{
|
|
56
|
-
"timestamp": "$TIMESTAMP",
|
|
57
|
-
"working_directory": "$CWD",
|
|
58
|
-
"project": "$PROJECT_NAME",
|
|
59
|
-
"git": {
|
|
60
|
-
"branch": "$GIT_BRANCH",
|
|
61
|
-
"has_changes": $([ -n "$GIT_STATUS" ] && echo "true" || echo "false"),
|
|
62
|
-
"files_changed": $FILES_CHANGED
|
|
63
|
-
},
|
|
64
|
-
"summary": "$(echo "$SUMMARY" | sed 's/"/\\"/g')",
|
|
65
|
-
"ended_at": "$(date '+%Y-%m-%d %H:%M:%S')"
|
|
66
|
-
}
|
|
67
|
-
EOF
|
|
68
|
-
|
|
69
|
-
# --- Update rolling session digest (cross-project awareness) ---
|
|
70
|
-
if [ ! -f "$DIGEST_FILE" ]; then
|
|
71
|
-
cat > "$DIGEST_FILE" << 'HEADER'
|
|
72
|
-
# Session Digest — Rolling Log
|
|
73
|
-
> Auto-updated by save-session-state.sh. Last 20 sessions across all projects.
|
|
74
|
-
|
|
75
|
-
HEADER
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
# Prepend new entry (most recent first, after header)
|
|
79
|
-
# Skip noise: sessions in .claude, Projects root, or with 0 files and no summary
|
|
80
|
-
if [ "$PROJECT_NAME" != ".claude" ] && [ "$PROJECT_NAME" != "Projects" ] && { [ "$FILES_CHANGED" -gt 0 ] || [ -n "$SUMMARY" ]; }; then
|
|
81
|
-
DATE_SHORT=$(date '+%m-%d %H:%M')
|
|
82
|
-
ENTRY="| ${DATE_SHORT} | ${PROJECT_NAME} | ${GIT_BRANCH:-—} | ${FILES_CHANGED} | ${SUMMARY:-—} |"
|
|
83
|
-
|
|
84
|
-
# Dedup: skip if ANY existing entry has the same project + branch + summary
|
|
85
|
-
NEW_KEY="${PROJECT_NAME}|${GIT_BRANCH:-—}|${SUMMARY:-—}"
|
|
86
|
-
DUPLICATE=false
|
|
87
|
-
while IFS= read -r line; do
|
|
88
|
-
ENTRY_KEY=$(echo "$line" | awk -F'|' '{gsub(/^ +| +$/,"",$3); gsub(/^ +| +$/,"",$4); gsub(/^ +| +$/,"",$6); print $3"|"$4"|"$6}')
|
|
89
|
-
if [ "$ENTRY_KEY" = "$NEW_KEY" ]; then
|
|
90
|
-
DUPLICATE=true
|
|
91
|
-
break
|
|
92
|
-
fi
|
|
93
|
-
done < <(tail -n +4 "$DIGEST_FILE")
|
|
94
|
-
if [ "$DUPLICATE" = "true" ]; then
|
|
95
|
-
: # duplicate found, skip adding to digest
|
|
96
|
-
else
|
|
97
|
-
|
|
98
|
-
# Read existing entries (skip header — first 3 lines), keep last 19
|
|
99
|
-
EXISTING=$(tail -n +4 "$DIGEST_FILE" | head -19)
|
|
100
|
-
|
|
101
|
-
cat > "$DIGEST_FILE" << HEADER
|
|
102
|
-
# Session Digest — Rolling Log
|
|
103
|
-
> Auto-updated by save-session-state.sh. Last 20 sessions across all projects.
|
|
104
|
-
|
|
105
|
-
${ENTRY}
|
|
106
|
-
${EXISTING}
|
|
107
|
-
HEADER
|
|
108
|
-
fi
|
|
109
|
-
fi
|
|
110
|
-
|
|
111
|
-
# --- Auto-handoff for significant sessions (>5 files changed) ---
|
|
112
|
-
if [ "$FILES_CHANGED" -gt 5 ] && [ "$PROJECT_NAME" != ".claude" ]; then
|
|
113
|
-
HANDOFF_FILE="$CWD/.continue-here.md"
|
|
114
|
-
# Only create if one doesn't already exist (don't overwrite manual handoffs)
|
|
115
|
-
if [ ! -f "$HANDOFF_FILE" ]; then
|
|
116
|
-
RECENT_COMMITS=$(git log --oneline -5 2>/dev/null || echo "none")
|
|
117
|
-
UNCOMMITTED_FILES=$(git diff --name-only 2>/dev/null | head -10 || echo "none")
|
|
118
|
-
STAGED_FILES=$(git diff --cached --name-only 2>/dev/null | head -10 || echo "none")
|
|
119
|
-
|
|
120
|
-
# Dead-ends: reverts, stashes, and abandoned branches from this session
|
|
121
|
-
REVERTS=$(git log --oneline -20 2>/dev/null | grep -i "revert\|undo\|rollback" | head -5 || echo "none")
|
|
122
|
-
STASHES=$(git stash list 2>/dev/null | head -5 || echo "none")
|
|
123
|
-
|
|
124
|
-
cat > "$HANDOFF_FILE" << HANDOFF
|
|
125
|
-
# Auto-Handoff — $(date '+%Y-%m-%d %H:%M')
|
|
126
|
-
|
|
127
|
-
## What was done
|
|
128
|
-
Branch: ${GIT_BRANCH}
|
|
129
|
-
Files changed: ${FILES_CHANGED}
|
|
130
|
-
|
|
131
|
-
Recent commits:
|
|
132
|
-
\`\`\`
|
|
133
|
-
${RECENT_COMMITS}
|
|
134
|
-
\`\`\`
|
|
135
|
-
|
|
136
|
-
## Uncommitted work
|
|
137
|
-
\`\`\`
|
|
138
|
-
${UNCOMMITTED_FILES}
|
|
139
|
-
\`\`\`
|
|
140
|
-
|
|
141
|
-
## Staged (not committed)
|
|
142
|
-
\`\`\`
|
|
143
|
-
${STAGED_FILES}
|
|
144
|
-
\`\`\`
|
|
145
|
-
|
|
146
|
-
## Dead-ends (don't repeat these)
|
|
147
|
-
Reverted/undone work:
|
|
148
|
-
\`\`\`
|
|
149
|
-
${REVERTS}
|
|
150
|
-
\`\`\`
|
|
151
|
-
|
|
152
|
-
Stashed work (may be abandoned):
|
|
153
|
-
\`\`\`
|
|
154
|
-
${STASHES}
|
|
155
|
-
\`\`\`
|
|
156
|
-
|
|
157
|
-
## Next steps
|
|
158
|
-
Review the recent commits and continue from where this session left off.
|
|
159
|
-
Do NOT retry approaches listed in dead-ends above.
|
|
160
|
-
HANDOFF
|
|
161
|
-
fi
|
|
162
|
-
fi
|
|
163
|
-
|
|
164
|
-
# --- Push to portal (with error tracking) ---
|
|
165
|
-
PORTAL_API_KEY="${CLAUDE_PORTAL_API_KEY:-}"
|
|
166
|
-
if [ -n "$PORTAL_API_KEY" ] && [ "$PROJECT_NAME" != ".claude" ]; then
|
|
167
|
-
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "https://portal.qualiasolutions.net/api/claude/session-log" \
|
|
168
|
-
-H "X-API-Key: $PORTAL_API_KEY" \
|
|
169
|
-
-H "Content-Type: application/json" \
|
|
170
|
-
-d @"$SESSION_FILE" \
|
|
171
|
-
--max-time 5 2>/dev/null || echo "000")
|
|
172
|
-
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
|
|
173
|
-
rm -f "$SESSION_DIR/.portal-last-error"
|
|
174
|
-
else
|
|
175
|
-
echo "$HTTP_CODE" > "$SESSION_DIR/.portal-last-error"
|
|
176
|
-
fi
|
|
177
|
-
fi
|
|
178
|
-
|
|
179
|
-
# --- Cleanup old session files (keep last 50 for retrospective analytics — RETR-04) ---
|
|
180
|
-
ls -t "$SESSION_DIR"/session_*.json 2>/dev/null | tail -n +51 | while IFS= read -r f; do
|
|
181
|
-
rm -f "$f"
|
|
182
|
-
done
|
|
183
|
-
|
|
184
|
-
printf '{"continue":true}'
|
|
185
|
-
exit 0
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# SessionStart hook — session context with systemMessage for user visibility
|
|
3
|
-
# stderr only shows in verbose mode; systemMessage shows in normal transcript
|
|
4
|
-
|
|
5
|
-
CWD=$(pwd)
|
|
6
|
-
SESSION_DIR="$HOME/.claude/session-env"
|
|
7
|
-
COMPACT_FILE="$SESSION_DIR/pre-compact.json"
|
|
8
|
-
PROJECT=$(basename "$CWD")
|
|
9
|
-
|
|
10
|
-
# Record session start time for duration-based filtering in save-session-state.sh
|
|
11
|
-
mkdir -p "$SESSION_DIR"
|
|
12
|
-
date +%s > "$SESSION_DIR/.session-start"
|
|
13
|
-
|
|
14
|
-
# Build display message
|
|
15
|
-
MSG="◆ SESSION START"
|
|
16
|
-
ISSUES=""
|
|
17
|
-
|
|
18
|
-
# Last session info
|
|
19
|
-
if [ -f "$COMPACT_FILE" ]; then
|
|
20
|
-
LAST_PROJECT=$(node -e "try{const d=JSON.parse(require('fs').readFileSync('$COMPACT_FILE','utf8'));process.stdout.write(d.project_name||'')}catch(e){}" 2>/dev/null)
|
|
21
|
-
LAST_BRANCH=$(node -e "try{const d=JSON.parse(require('fs').readFileSync('$COMPACT_FILE','utf8'));process.stdout.write(d.git_branch||'')}catch(e){}" 2>/dev/null)
|
|
22
|
-
if [ -n "$LAST_PROJECT" ] && [ "$LAST_PROJECT" != ".claude" ]; then
|
|
23
|
-
MSG="${MSG} | Last: ${LAST_PROJECT} (${LAST_BRANCH:-no branch})"
|
|
24
|
-
fi
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
MSG="${MSG} | Project: ${PROJECT}"
|
|
28
|
-
|
|
29
|
-
# Handoff file
|
|
30
|
-
if [ -f "$CWD/.continue-here.md" ]; then
|
|
31
|
-
MSG="${MSG} | ▲ Handoff: .continue-here.md"
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
# Check hooks health
|
|
35
|
-
HOOKS_OK=0
|
|
36
|
-
HOOKS_TOTAL=0
|
|
37
|
-
for h in branch-guard pre-commit confirm-delete migration-validate pre-deploy-gate block-env-edit auto-format session-context-loader retention-cleanup pre-compact save-session-state session-learn notification-speak qualia-colors skill-announce tool-error-announce; do
|
|
38
|
-
HOOKS_TOTAL=$((HOOKS_TOTAL + 1))
|
|
39
|
-
[ -f "$HOME/.claude/hooks/${h}.sh" ] && HOOKS_OK=$((HOOKS_OK + 1))
|
|
40
|
-
done
|
|
41
|
-
|
|
42
|
-
if [ "$HOOKS_OK" -eq "$HOOKS_TOTAL" ]; then
|
|
43
|
-
MSG="${MSG} | Hooks: ${HOOKS_OK}/${HOOKS_TOTAL}"
|
|
44
|
-
else
|
|
45
|
-
MSG="${MSG} | Hooks: ${HOOKS_OK}/${HOOKS_TOTAL} ($(( HOOKS_TOTAL - HOOKS_OK )) missing)"
|
|
46
|
-
ISSUES="${ISSUES}Missing hooks. "
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
# Check CLAUDE.md exists
|
|
50
|
-
if [ -f "$HOME/.claude/CLAUDE.md" ]; then
|
|
51
|
-
ROLE=$(grep -m1 "^## Role:" "$HOME/.claude/CLAUDE.md" 2>/dev/null | sed 's/^## Role: *//')
|
|
52
|
-
MSG="${MSG} | Role: ${ROLE:-unknown}"
|
|
53
|
-
else
|
|
54
|
-
ISSUES="${ISSUES}CLAUDE.md missing. "
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
# Check settings.json valid
|
|
58
|
-
if [ -f "$HOME/.claude/settings.json" ]; then
|
|
59
|
-
node -e "JSON.parse(require('fs').readFileSync(require('path').join(require('os').homedir(),'.claude','settings.json'),'utf8'))" 2>/dev/null
|
|
60
|
-
if [ $? -ne 0 ]; then
|
|
61
|
-
ISSUES="${ISSUES}settings.json invalid. "
|
|
62
|
-
fi
|
|
63
|
-
fi
|
|
64
|
-
|
|
65
|
-
# Check for stale knowledge files (>30 days old)
|
|
66
|
-
STALE_COUNT=0
|
|
67
|
-
STALE_NAMES=""
|
|
68
|
-
for kf in "$HOME/.claude/knowledge"/*.md; do
|
|
69
|
-
[ -f "$kf" ] || continue
|
|
70
|
-
KF_AGE=$(( ($(date +%s) - $(stat -c %Y "$kf" 2>/dev/null || echo 0)) / 86400 ))
|
|
71
|
-
if [ "$KF_AGE" -gt 30 ]; then
|
|
72
|
-
STALE_COUNT=$((STALE_COUNT + 1))
|
|
73
|
-
STALE_NAMES="${STALE_NAMES} $(basename "$kf")(${KF_AGE}d)"
|
|
74
|
-
fi
|
|
75
|
-
done
|
|
76
|
-
if [ "$STALE_COUNT" -gt 0 ]; then
|
|
77
|
-
ISSUES="${ISSUES}${STALE_COUNT} stale knowledge file(s):${STALE_NAMES}. "
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
# Check portal sync health
|
|
81
|
-
if [ -f "$SESSION_DIR/.portal-last-error" ]; then
|
|
82
|
-
PORTAL_ERR=$(cat "$SESSION_DIR/.portal-last-error" 2>/dev/null)
|
|
83
|
-
ISSUES="${ISSUES}Portal sync failed (HTTP ${PORTAL_ERR}). "
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
|
-
if [ -n "$ISSUES" ]; then
|
|
87
|
-
MSG="${MSG} | ▲ ${ISSUES}"
|
|
88
|
-
fi
|
|
89
|
-
|
|
90
|
-
MSG="${MSG} | Qualia mode activating..."
|
|
91
|
-
|
|
92
|
-
# Escape for JSON
|
|
93
|
-
MSG=$(echo "$MSG" | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
94
|
-
|
|
95
|
-
printf '{"continue":true,"systemMessage":"%s"}' "$MSG"
|
|
96
|
-
exit 0
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SessionEnd hook: prompt for lessons learned if significant work was done
|
|
3
|
-
# "Significant" = more than 3 files modified in the session
|
|
4
|
-
source "$(dirname "$0")/qualia-colors.sh"
|
|
5
|
-
|
|
6
|
-
LEARNED_FILE="$HOME/.claude/knowledge/learned-patterns.md"
|
|
7
|
-
|
|
8
|
-
# Skip if not in a git repo
|
|
9
|
-
git rev-parse --is-inside-work-tree &>/dev/null || exit 0
|
|
10
|
-
|
|
11
|
-
# Count files modified: committed in last 2 hours + uncommitted
|
|
12
|
-
COMMITTED=$(git diff --name-only "$(git log --since='2 hours ago' --format=%H 2>/dev/null | tail -1 || echo HEAD)" HEAD 2>/dev/null | wc -l 2>/dev/null || echo 0)
|
|
13
|
-
UNCOMMITTED=$(git diff --name-only 2>/dev/null | wc -l 2>/dev/null || echo 0)
|
|
14
|
-
MODIFIED_COUNT=$((COMMITTED + UNCOMMITTED))
|
|
15
|
-
|
|
16
|
-
# Only trigger if significant work was done
|
|
17
|
-
if [ "$MODIFIED_COUNT" -le 3 ]; then
|
|
18
|
-
exit 0
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
# Initialize learned-patterns.md if it doesn't exist
|
|
22
|
-
if [ ! -f "$LEARNED_FILE" ]; then
|
|
23
|
-
echo "# Learned Patterns" > "$LEARNED_FILE"
|
|
24
|
-
echo "" >> "$LEARNED_FILE"
|
|
25
|
-
echo "Lessons captured from development sessions." >> "$LEARNED_FILE"
|
|
26
|
-
echo "" >> "$LEARNED_FILE"
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# Output reminder (shown to Claude in session context)
|
|
30
|
-
printf '{"continue":true,"systemMessage":"SESSION_LEARN: %d files changed this session. Consider running /learn to capture any lessons."}' "$MODIFIED_COUNT"
|
|
31
|
-
|
|
32
|
-
exit 0
|