@stackmemoryai/stackmemory 0.3.17 → 0.3.19
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/dist/cli/claude-sm.js +51 -5
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +52 -19
- package/dist/cli/codex-sm.js.map +2 -2
- package/dist/cli/commands/db.js +143 -0
- package/dist/cli/commands/db.js.map +7 -0
- package/dist/cli/commands/login.js +50 -0
- package/dist/cli/commands/login.js.map +7 -0
- package/dist/cli/commands/migrate.js +178 -0
- package/dist/cli/commands/migrate.js.map +7 -0
- package/dist/cli/commands/onboard.js +158 -2
- package/dist/cli/commands/onboard.js.map +2 -2
- package/dist/cli/commands/skills.js +15 -2
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/index.js +118 -834
- package/dist/cli/index.js.map +3 -3
- package/dist/core/context/dual-stack-manager.js +1 -1
- package/dist/core/context/dual-stack-manager.js.map +1 -1
- package/dist/core/context/frame-database.js +1 -0
- package/dist/core/context/frame-database.js.map +2 -2
- package/dist/core/context/frame-manager.js +59 -2
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/database/database-adapter.js +6 -1
- package/dist/core/database/database-adapter.js.map +2 -2
- package/dist/core/database/sqlite-adapter.js +60 -2
- package/dist/core/database/sqlite-adapter.js.map +2 -2
- package/dist/integrations/claude-code/subagent-client.js +106 -3
- package/dist/integrations/claude-code/subagent-client.js.map +2 -2
- package/dist/servers/railway/config.js +51 -0
- package/dist/servers/railway/config.js.map +7 -0
- package/dist/servers/railway/index-enhanced.js +156 -0
- package/dist/servers/railway/index-enhanced.js.map +7 -0
- package/dist/servers/railway/index.js +843 -82
- package/dist/servers/railway/index.js.map +3 -3
- package/dist/servers/railway/minimal.js +48 -3
- package/dist/servers/railway/minimal.js.map +2 -2
- package/dist/servers/railway/storage-test.js +455 -0
- package/dist/servers/railway/storage-test.js.map +7 -0
- package/dist/skills/claude-skills.js +13 -12
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/recursive-agent-orchestrator.js +27 -18
- package/dist/skills/recursive-agent-orchestrator.js.map +2 -2
- package/dist/skills/unified-rlm-orchestrator.js.map +2 -2
- package/package.json +13 -21
- package/scripts/README-TESTING.md +186 -0
- package/scripts/analyze-cli-security.js +288 -0
- package/scripts/archive/add-phase-tasks-to-linear.js +163 -0
- package/scripts/archive/analyze-linear-duplicates.js +214 -0
- package/scripts/archive/analyze-remaining-duplicates.js +230 -0
- package/scripts/archive/analyze-sta-duplicates.js +292 -0
- package/scripts/archive/analyze-sta-graphql.js +399 -0
- package/scripts/archive/cancel-duplicate-tasks.ts +246 -0
- package/scripts/archive/check-all-duplicates.ts +419 -0
- package/scripts/archive/clean-duplicate-tasks.js +114 -0
- package/scripts/archive/cleanup-duplicate-tasks.ts +286 -0
- package/scripts/archive/create-phase-tasks.js +387 -0
- package/scripts/archive/delete-linear-duplicates.js +182 -0
- package/scripts/archive/delete-remaining-duplicates.js +158 -0
- package/scripts/archive/delete-sta-duplicates.js +201 -0
- package/scripts/archive/delete-sta-oauth.js +201 -0
- package/scripts/archive/export-sta-tasks.js +62 -0
- package/scripts/archive/install-auto-sync.js +266 -0
- package/scripts/archive/install-chromadb-hooks.sh +133 -0
- package/scripts/archive/install-enhanced-clear-hooks.sh +431 -0
- package/scripts/archive/install-post-task-hooks.sh +289 -0
- package/scripts/archive/install-stackmemory-hooks.sh +420 -0
- package/scripts/archive/merge-linear-duplicates-safe.ts +362 -0
- package/scripts/archive/merge-linear-duplicates.ts +180 -0
- package/scripts/archive/remove-sta-tasks.js +70 -0
- package/scripts/archive/setup-background-sync.sh +168 -0
- package/scripts/archive/setup-claude-auto-triggers.sh +181 -0
- package/scripts/archive/setup-claude-autostart.sh +305 -0
- package/scripts/archive/setup-git-hooks.sh +25 -0
- package/scripts/archive/setup-linear-oauth.sh +46 -0
- package/scripts/archive/setup-mcp.sh +113 -0
- package/scripts/archive/setup-railway-deployment.sh +81 -0
- package/scripts/auto-handoff.sh +262 -0
- package/scripts/background-sync-manager.js +416 -0
- package/scripts/benchmark-performance.ts +57 -0
- package/scripts/check-redis.ts +48 -0
- package/scripts/chromadb-auto-loader.sh +128 -0
- package/scripts/chromadb-context-loader.js +479 -0
- package/scripts/claude-chromadb-hook.js +460 -0
- package/scripts/claude-code-wrapper.sh +66 -0
- package/scripts/claude-linear-skill.js +455 -0
- package/scripts/claude-pre-commit.sh +302 -0
- package/scripts/claude-sm-autostart.js +532 -0
- package/scripts/claude-sm-setup.sh +367 -0
- package/scripts/claude-with-chromadb.sh +69 -0
- package/scripts/claude-worktree-manager.sh +323 -0
- package/scripts/claude-worktree-monitor.sh +371 -0
- package/scripts/claude-worktree-setup.sh +327 -0
- package/scripts/clean-linear-backlog.js +273 -0
- package/scripts/cleanup-old-sessions.sh +57 -0
- package/scripts/codex-wrapper.sh +88 -0
- package/scripts/create-sandbox.sh +269 -0
- package/scripts/debug-linear-update.js +174 -0
- package/scripts/delete-linear-tasks.js +167 -0
- package/scripts/deploy.sh +89 -0
- package/scripts/deployment/railway.sh +352 -0
- package/scripts/deployment/test-deployment.js +194 -0
- package/scripts/detect-and-rehydrate.js +162 -0
- package/scripts/detect-and-rehydrate.mjs +165 -0
- package/scripts/development/create-demo-tasks.js +143 -0
- package/scripts/development/debug-frame-test.js +16 -0
- package/scripts/development/demo-auto-sync.js +128 -0
- package/scripts/development/fix-all-imports.js +213 -0
- package/scripts/development/fix-imports.js +229 -0
- package/scripts/development/fix-lint-loop.cjs +103 -0
- package/scripts/development/fix-project-id.ts +161 -0
- package/scripts/development/fix-strict-mode-issues.ts +291 -0
- package/scripts/development/reorganize-structure.sh +228 -0
- package/scripts/development/test-persistence-direct.js +148 -0
- package/scripts/development/test-persistence.js +114 -0
- package/scripts/development/test-tasks.js +93 -0
- package/scripts/development/update-imports.js +212 -0
- package/scripts/fetch-linear-status.js +125 -0
- package/scripts/git-hooks/README.md +310 -0
- package/scripts/git-hooks/branch-context-manager.sh +342 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +63 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +305 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +275 -0
- package/scripts/hooks/cleanup-shell.sh +130 -0
- package/scripts/hooks/task-complete.sh +114 -0
- package/scripts/initialize.ts +129 -0
- package/scripts/install-claude-hooks-auto.js +104 -0
- package/scripts/install-claude-hooks.sh +133 -0
- package/scripts/install-global.sh +296 -0
- package/scripts/install.sh +235 -0
- package/scripts/linear-auto-sync.js +262 -0
- package/scripts/linear-auto-sync.sh +161 -0
- package/scripts/linear-sync-daemon.js +150 -0
- package/scripts/linear-task-review.js +237 -0
- package/scripts/list-linear-tasks.ts +178 -0
- package/scripts/mcp-proxy.js +66 -0
- package/scripts/opencode-wrapper.sh +85 -0
- package/scripts/publish-local.js +74 -0
- package/scripts/query-chromadb.ts +201 -0
- package/scripts/railway-env-setup.sh +39 -0
- package/scripts/reconcile-local-tasks.js +170 -0
- package/scripts/recreate-frames-db.js +89 -0
- package/scripts/setup/claude-integration.js +138 -0
- package/scripts/setup/configure-alias.js +125 -0
- package/scripts/setup/configure-codex-alias.js +161 -0
- package/scripts/setup/configure-opencode-alias.js +175 -0
- package/scripts/setup-claude-integration.js +204 -0
- package/scripts/setup-claude-integration.sh +183 -0
- package/scripts/setup-railway-deployment.sh +37 -0
- package/scripts/setup.sh +31 -0
- package/scripts/show-linear-summary.ts +172 -0
- package/scripts/stackmemory-auto-handoff.sh +231 -0
- package/scripts/stackmemory-daemon.sh +40 -0
- package/scripts/start-linear-sync-daemon.sh +141 -0
- package/scripts/start-temporal-paradox.sh +214 -0
- package/scripts/status.ts +159 -0
- package/scripts/sync-and-clean-tasks.js +258 -0
- package/scripts/sync-frames-from-railway.js +228 -0
- package/scripts/sync-linear-graphql.js +303 -0
- package/scripts/sync-linear-tasks.js +186 -0
- package/scripts/test-auto-triggers.sh +57 -0
- package/scripts/test-browser-mcp.js +74 -0
- package/scripts/test-chromadb-full.js +115 -0
- package/scripts/test-chromadb-hooks.sh +28 -0
- package/scripts/test-chromadb-sync.ts +245 -0
- package/scripts/test-cli-security.js +293 -0
- package/scripts/test-hooks-persistence.sh +220 -0
- package/scripts/test-installation-scenarios.sh +359 -0
- package/scripts/test-installation.sh +224 -0
- package/scripts/test-mcp.js +163 -0
- package/scripts/test-pre-publish-quick.sh +75 -0
- package/scripts/test-quality-gates.sh +263 -0
- package/scripts/test-railway-db.js +222 -0
- package/scripts/test-redis-storage.ts +490 -0
- package/scripts/test-rlm-basic.sh +122 -0
- package/scripts/test-rlm-comprehensive.sh +260 -0
- package/scripts/test-rlm-e2e.sh +268 -0
- package/scripts/test-rlm-simple.js +90 -0
- package/scripts/test-rlm.js +110 -0
- package/scripts/test-session-handoff.sh +165 -0
- package/scripts/test-shell-integration.sh +275 -0
- package/scripts/testing/ab-test-runner.ts +508 -0
- package/scripts/testing/collect-metrics.ts +457 -0
- package/scripts/testing/quick-effectiveness-demo.js +187 -0
- package/scripts/testing/real-performance-test.js +422 -0
- package/scripts/testing/run-effectiveness-tests.sh +176 -0
- package/scripts/testing/scripts/testing/ab-test-runner.js +363 -0
- package/scripts/testing/scripts/testing/collect-metrics.js +292 -0
- package/scripts/testing/simple-effectiveness-test.js +310 -0
- package/scripts/testing/src/core/context/context-bridge.js +253 -0
- package/scripts/testing/src/core/context/frame-manager.js +746 -0
- package/scripts/testing/src/core/context/shared-context-layer.js +437 -0
- package/scripts/testing/src/core/database/database-adapter.js +54 -0
- package/scripts/testing/src/core/errors/index.js +291 -0
- package/scripts/testing/src/core/errors/recovery.js +268 -0
- package/scripts/testing/src/core/monitoring/logger.js +145 -0
- package/scripts/testing/src/core/retrieval/context-retriever.js +516 -0
- package/scripts/testing/src/core/session/index.js +1 -0
- package/scripts/testing/src/core/session/session-manager.js +323 -0
- package/scripts/testing/src/core/trace/cli-trace-wrapper.js +140 -0
- package/scripts/testing/src/core/trace/db-trace-wrapper.js +251 -0
- package/scripts/testing/src/core/trace/debug-trace.js +398 -0
- package/scripts/testing/src/core/trace/index.js +120 -0
- package/scripts/testing/src/core/trace/linear-api-wrapper.js +204 -0
- package/scripts/update-linear-status.js +268 -0
- package/scripts/update-linear-tasks-fixed.js +284 -0
- package/scripts/verify-railway-schema.ts +35 -0
- package/templates/claude-hooks/hooks.json +5 -0
- package/templates/claude-hooks/on-clear.js +56 -0
- package/templates/claude-hooks/on-startup.js +56 -0
- package/templates/claude-hooks/tool-use-trace.js +67 -0
- package/dist/features/tui/components/analytics-panel.js +0 -157
- package/dist/features/tui/components/analytics-panel.js.map +0 -7
- package/dist/features/tui/components/frame-visualizer.js +0 -377
- package/dist/features/tui/components/frame-visualizer.js.map +0 -7
- package/dist/features/tui/components/pr-tracker.js +0 -135
- package/dist/features/tui/components/pr-tracker.js.map +0 -7
- package/dist/features/tui/components/session-monitor.js +0 -299
- package/dist/features/tui/components/session-monitor.js.map +0 -7
- package/dist/features/tui/components/subagent-fleet.js +0 -395
- package/dist/features/tui/components/subagent-fleet.js.map +0 -7
- package/dist/features/tui/components/task-board.js +0 -1139
- package/dist/features/tui/components/task-board.js.map +0 -7
- package/dist/features/tui/index.js +0 -408
- package/dist/features/tui/index.js.map +0 -7
- package/dist/features/tui/services/data-service.js +0 -641
- package/dist/features/tui/services/data-service.js.map +0 -7
- package/dist/features/tui/services/linear-task-reader.js +0 -102
- package/dist/features/tui/services/linear-task-reader.js.map +0 -7
- package/dist/features/tui/services/websocket-client.js +0 -162
- package/dist/features/tui/services/websocket-client.js.map +0 -7
- package/dist/features/tui/terminal-compat.js +0 -220
- package/dist/features/tui/terminal-compat.js.map +0 -7
- package/dist/features/tui/types.js +0 -1
- package/dist/features/tui/types.js.map +0 -7
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# StackMemory Post-Task Quality Gates Setup
|
|
4
|
+
# Automatically runs tests and code review after Claude completes tasks
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🧪 StackMemory Post-Task Quality Gates Setup"
|
|
9
|
+
echo "============================================="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
# Check if StackMemory is installed
|
|
13
|
+
if ! command -v stackmemory &> /dev/null; then
|
|
14
|
+
echo "❌ StackMemory is not installed"
|
|
15
|
+
echo "Install with: npm install -g @stackmemoryai/stackmemory"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Check if in a project directory
|
|
20
|
+
if [ ! -d ".stackmemory" ]; then
|
|
21
|
+
echo "⚠️ StackMemory not initialized in this directory"
|
|
22
|
+
echo "Run: stackmemory init"
|
|
23
|
+
read -p "Initialize now? (y/n): " -n 1 -r
|
|
24
|
+
echo
|
|
25
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
26
|
+
stackmemory init
|
|
27
|
+
else
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
echo "✅ StackMemory detected"
|
|
33
|
+
echo ""
|
|
34
|
+
|
|
35
|
+
# Detect project type and test frameworks
|
|
36
|
+
echo "🔍 Detecting project configuration..."
|
|
37
|
+
|
|
38
|
+
PROJECT_TYPE="unknown"
|
|
39
|
+
TEST_FRAMEWORK=""
|
|
40
|
+
LINT_COMMAND=""
|
|
41
|
+
TEST_COMMAND=""
|
|
42
|
+
|
|
43
|
+
if [ -f "package.json" ]; then
|
|
44
|
+
echo " 📦 Found package.json"
|
|
45
|
+
|
|
46
|
+
# Detect project type
|
|
47
|
+
if grep -q '"react"' package.json; then
|
|
48
|
+
PROJECT_TYPE="React"
|
|
49
|
+
elif grep -q '"vue"' package.json; then
|
|
50
|
+
PROJECT_TYPE="Vue"
|
|
51
|
+
elif grep -q '"@angular/core"' package.json; then
|
|
52
|
+
PROJECT_TYPE="Angular"
|
|
53
|
+
elif grep -q '"express"' package.json; then
|
|
54
|
+
PROJECT_TYPE="Node.js API"
|
|
55
|
+
elif grep -q '"next"' package.json; then
|
|
56
|
+
PROJECT_TYPE="Next.js"
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Detect test frameworks
|
|
60
|
+
if grep -q '"jest"' package.json; then
|
|
61
|
+
TEST_FRAMEWORK="Jest"
|
|
62
|
+
TEST_COMMAND="npm test"
|
|
63
|
+
elif grep -q '"vitest"' package.json; then
|
|
64
|
+
TEST_FRAMEWORK="Vitest"
|
|
65
|
+
TEST_COMMAND="npm run test"
|
|
66
|
+
elif grep -q '"mocha"' package.json; then
|
|
67
|
+
TEST_FRAMEWORK="Mocha"
|
|
68
|
+
TEST_COMMAND="npm test"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Detect linters
|
|
72
|
+
if grep -q '"eslint"' package.json; then
|
|
73
|
+
LINT_COMMAND="npm run lint"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
elif [ -f "Cargo.toml" ]; then
|
|
77
|
+
echo " 🦀 Found Cargo.toml (Rust project)"
|
|
78
|
+
PROJECT_TYPE="Rust"
|
|
79
|
+
TEST_COMMAND="cargo test"
|
|
80
|
+
LINT_COMMAND="cargo clippy"
|
|
81
|
+
|
|
82
|
+
elif [ -f "go.mod" ]; then
|
|
83
|
+
echo " 🐹 Found go.mod (Go project)"
|
|
84
|
+
PROJECT_TYPE="Go"
|
|
85
|
+
TEST_COMMAND="go test ./..."
|
|
86
|
+
LINT_COMMAND="golangci-lint run"
|
|
87
|
+
|
|
88
|
+
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then
|
|
89
|
+
echo " 🐍 Found Python project"
|
|
90
|
+
PROJECT_TYPE="Python"
|
|
91
|
+
TEST_COMMAND="pytest"
|
|
92
|
+
LINT_COMMAND="ruff check"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
echo " 🎯 Project type: $PROJECT_TYPE"
|
|
96
|
+
[ -n "$TEST_FRAMEWORK" ] && echo " 🧪 Test framework: $TEST_FRAMEWORK"
|
|
97
|
+
[ -n "$TEST_COMMAND" ] && echo " ▶️ Test command: $TEST_COMMAND"
|
|
98
|
+
[ -n "$LINT_COMMAND" ] && echo " 🔍 Lint command: $LINT_COMMAND"
|
|
99
|
+
echo ""
|
|
100
|
+
|
|
101
|
+
# Create/update StackMemory config
|
|
102
|
+
echo "📝 Configuring quality gates..."
|
|
103
|
+
|
|
104
|
+
CONFIG_FILE=".stackmemory/config.json"
|
|
105
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
106
|
+
echo '{}' > "$CONFIG_FILE"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Update config with quality gate settings
|
|
110
|
+
cat > "$CONFIG_FILE" << EOF
|
|
111
|
+
{
|
|
112
|
+
"monitor": {
|
|
113
|
+
"contextWarningThreshold": 0.6,
|
|
114
|
+
"contextCriticalThreshold": 0.7,
|
|
115
|
+
"contextAutoSaveThreshold": 0.85,
|
|
116
|
+
"checkIntervalSeconds": 30,
|
|
117
|
+
"idleTimeoutMinutes": 5,
|
|
118
|
+
"autoSaveLedger": true,
|
|
119
|
+
"autoGenerateHandoff": true,
|
|
120
|
+
"sessionEndHandoff": true
|
|
121
|
+
},
|
|
122
|
+
"qualityGates": {
|
|
123
|
+
"runTests": true,
|
|
124
|
+
"requireTestCoverage": false,
|
|
125
|
+
"runCodeReview": true,
|
|
126
|
+
"runLinter": true,
|
|
127
|
+
"blockOnFailure": false
|
|
128
|
+
},
|
|
129
|
+
"testFrameworks": {
|
|
130
|
+
"detected": ["$TEST_FRAMEWORK"],
|
|
131
|
+
"testCommand": "$TEST_COMMAND",
|
|
132
|
+
"lintCommand": "$LINT_COMMAND"
|
|
133
|
+
},
|
|
134
|
+
"reviewConfig": {
|
|
135
|
+
"reviewOnEveryChange": false,
|
|
136
|
+
"reviewOnTaskComplete": true,
|
|
137
|
+
"focusAreas": ["security", "performance", "maintainability", "correctness"],
|
|
138
|
+
"skipPatterns": ["*.test.ts", "*.spec.js", "dist/", "node_modules/", "__pycache__/"]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
EOF
|
|
142
|
+
|
|
143
|
+
echo "✅ Configuration updated"
|
|
144
|
+
echo ""
|
|
145
|
+
|
|
146
|
+
# Install enhanced Claude Code hooks
|
|
147
|
+
echo "📦 Installing enhanced Claude Code hooks..."
|
|
148
|
+
|
|
149
|
+
CLAUDE_HOOKS_DIR="$HOME/.claude/hooks"
|
|
150
|
+
mkdir -p "$CLAUDE_HOOKS_DIR"
|
|
151
|
+
|
|
152
|
+
# Enhanced on-task-complete hook
|
|
153
|
+
cat > "$CLAUDE_HOOKS_DIR/on-task-complete" << 'EOF'
|
|
154
|
+
#!/bin/bash
|
|
155
|
+
# Enhanced post-task quality gates hook
|
|
156
|
+
# Runs tests, linter, and code review after task completion
|
|
157
|
+
|
|
158
|
+
echo "🔍 Task completed - running quality gates..."
|
|
159
|
+
|
|
160
|
+
# Check if quality gates are enabled
|
|
161
|
+
if [ ! -f ".stackmemory/config.json" ] || ! jq -e '.qualityGates.runTests or .qualityGates.runLinter or .qualityGates.runCodeReview' .stackmemory/config.json >/dev/null 2>&1; then
|
|
162
|
+
echo "⚠️ Quality gates not enabled. Run: stackmemory quality --setup"
|
|
163
|
+
exit 0
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Run quality gates
|
|
167
|
+
stackmemory quality --run 2>&1 | while IFS= read -r line; do
|
|
168
|
+
echo " $line"
|
|
169
|
+
done
|
|
170
|
+
|
|
171
|
+
# Check if any gates failed
|
|
172
|
+
if [ $? -ne 0 ]; then
|
|
173
|
+
echo "❌ Some quality gates failed"
|
|
174
|
+
echo "💡 Fix issues or run: stackmemory quality --history"
|
|
175
|
+
else
|
|
176
|
+
echo "✅ All quality gates passed"
|
|
177
|
+
fi
|
|
178
|
+
EOF
|
|
179
|
+
chmod +x "$CLAUDE_HOOKS_DIR/on-task-complete"
|
|
180
|
+
|
|
181
|
+
# Enhanced on-file-save hook
|
|
182
|
+
cat > "$CLAUDE_HOOKS_DIR/on-file-save" << 'EOF'
|
|
183
|
+
#!/bin/bash
|
|
184
|
+
# Run linter on file save if enabled
|
|
185
|
+
|
|
186
|
+
FILE="$1" # Claude Code passes the saved file path
|
|
187
|
+
|
|
188
|
+
# Skip if not a source file
|
|
189
|
+
case "$FILE" in
|
|
190
|
+
*.ts|*.tsx|*.js|*.jsx|*.py|*.go|*.rs|*.java|*.cpp|*.c) ;;
|
|
191
|
+
*) exit 0 ;;
|
|
192
|
+
esac
|
|
193
|
+
|
|
194
|
+
# Check if linting enabled
|
|
195
|
+
if [ -f ".stackmemory/config.json" ] && jq -e '.qualityGates.runLinter' .stackmemory/config.json >/dev/null 2>&1; then
|
|
196
|
+
LINT_CMD=$(jq -r '.testFrameworks.lintCommand // "echo No lint command configured"' .stackmemory/config.json)
|
|
197
|
+
|
|
198
|
+
if [ "$LINT_CMD" != "echo No lint command configured" ]; then
|
|
199
|
+
echo "🔍 Running linter on $FILE..."
|
|
200
|
+
$LINT_CMD "$FILE" 2>&1 | head -10 # Limit output
|
|
201
|
+
fi
|
|
202
|
+
fi
|
|
203
|
+
EOF
|
|
204
|
+
chmod +x "$CLAUDE_HOOKS_DIR/on-file-save"
|
|
205
|
+
|
|
206
|
+
# Enhanced on-code-change hook
|
|
207
|
+
cat > "$CLAUDE_HOOKS_DIR/on-code-change" << 'EOF'
|
|
208
|
+
#!/bin/bash
|
|
209
|
+
# Trigger quality checks on significant code changes
|
|
210
|
+
|
|
211
|
+
# Get changed files from git
|
|
212
|
+
CHANGED_FILES=$(git diff --name-only HEAD~1 2>/dev/null | wc -l)
|
|
213
|
+
|
|
214
|
+
# If many files changed, run full quality gates
|
|
215
|
+
if [ "${CHANGED_FILES:-0}" -gt 5 ]; then
|
|
216
|
+
echo "🚨 Significant changes detected ($CHANGED_FILES files)"
|
|
217
|
+
echo "🔍 Running comprehensive quality gates..."
|
|
218
|
+
|
|
219
|
+
if command -v stackmemory >/dev/null 2>&1; then
|
|
220
|
+
stackmemory quality --run
|
|
221
|
+
fi
|
|
222
|
+
fi
|
|
223
|
+
EOF
|
|
224
|
+
chmod +x "$CLAUDE_HOOKS_DIR/on-code-change"
|
|
225
|
+
|
|
226
|
+
# Enhanced on-frame-close hook
|
|
227
|
+
cat > "$CLAUDE_HOOKS_DIR/on-frame-close" << 'EOF'
|
|
228
|
+
#!/bin/bash
|
|
229
|
+
# Run quality gates when Claude closes a frame (task completion)
|
|
230
|
+
|
|
231
|
+
FRAME_TYPE="$1"
|
|
232
|
+
FRAME_NAME="$2"
|
|
233
|
+
|
|
234
|
+
# Only run on task-like frames
|
|
235
|
+
case "$FRAME_TYPE" in
|
|
236
|
+
task|implementation|bugfix|feature)
|
|
237
|
+
echo "📋 Frame closed: $FRAME_NAME"
|
|
238
|
+
echo "🔍 Running post-task quality gates..."
|
|
239
|
+
|
|
240
|
+
if command -v stackmemory >/dev/null 2>&1 && [ -f ".stackmemory/config.json" ]; then
|
|
241
|
+
# Update activity
|
|
242
|
+
stackmemory monitor --activity 2>/dev/null
|
|
243
|
+
|
|
244
|
+
# Run quality gates
|
|
245
|
+
if jq -e '.qualityGates.runTests or .qualityGates.runCodeReview' .stackmemory/config.json >/dev/null 2>&1; then
|
|
246
|
+
stackmemory quality --run
|
|
247
|
+
fi
|
|
248
|
+
fi
|
|
249
|
+
;;
|
|
250
|
+
esac
|
|
251
|
+
EOF
|
|
252
|
+
chmod +x "$CLAUDE_HOOKS_DIR/on-frame-close"
|
|
253
|
+
|
|
254
|
+
echo "✅ Enhanced Claude Code hooks installed"
|
|
255
|
+
echo ""
|
|
256
|
+
|
|
257
|
+
# Enable quality gates
|
|
258
|
+
echo "🔧 Enabling quality gates..."
|
|
259
|
+
stackmemory quality --enable 2>&1 || echo "⚠️ Quality gates will be available after next build"
|
|
260
|
+
|
|
261
|
+
echo ""
|
|
262
|
+
echo "✅ Post-Task Quality Gates Setup Complete!"
|
|
263
|
+
echo ""
|
|
264
|
+
echo "📋 What's been configured:"
|
|
265
|
+
echo " • Auto-run tests after task completion"
|
|
266
|
+
echo " • Auto-run linter on file saves"
|
|
267
|
+
echo " • Auto-trigger code review for significant changes"
|
|
268
|
+
echo " • Quality gate monitoring on frame closure"
|
|
269
|
+
echo " • Comprehensive change detection"
|
|
270
|
+
echo ""
|
|
271
|
+
echo "🪝 Installed hooks:"
|
|
272
|
+
echo " ~/.claude/hooks/on-task-complete # Main quality gate runner"
|
|
273
|
+
echo " ~/.claude/hooks/on-file-save # Linter on save"
|
|
274
|
+
echo " ~/.claude/hooks/on-code-change # Change detection"
|
|
275
|
+
echo " ~/.claude/hooks/on-frame-close # Frame completion trigger"
|
|
276
|
+
echo ""
|
|
277
|
+
echo "📝 Available commands:"
|
|
278
|
+
echo " stackmemory quality --status # Check quality gate status"
|
|
279
|
+
echo " stackmemory quality --run # Run quality gates manually"
|
|
280
|
+
echo " stackmemory quality --config # Configure quality gates"
|
|
281
|
+
echo " stackmemory quality --history # View quality gate history"
|
|
282
|
+
echo ""
|
|
283
|
+
echo "🎯 Next steps:"
|
|
284
|
+
echo " 1. Quality gates will run automatically after Claude tasks"
|
|
285
|
+
echo " 2. Check results with: stackmemory quality --status"
|
|
286
|
+
echo " 3. Configure with: stackmemory quality --config"
|
|
287
|
+
echo ""
|
|
288
|
+
echo "💡 Tip: Quality gates help maintain code quality automatically!"
|
|
289
|
+
echo " They run tests, linting, and code review after each task."
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# StackMemory Git Hooks Installer
|
|
3
|
+
# Installs and manages StackMemory git hooks for automated workflow
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Colors for output
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
GREEN='\033[0;32m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
BLUE='\033[0;34m'
|
|
12
|
+
NC='\033[0m' # No Color
|
|
13
|
+
|
|
14
|
+
log_info() {
|
|
15
|
+
echo -e "${BLUE}ℹ️ $1${NC}"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
log_success() {
|
|
19
|
+
echo -e "${GREEN}✅ $1${NC}"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
log_warning() {
|
|
23
|
+
echo -e "${YELLOW}⚠️ $1${NC}"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
log_error() {
|
|
27
|
+
echo -e "${RED}❌ $1${NC}"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Configuration
|
|
31
|
+
BACKUP_EXISTING_HOOKS=true
|
|
32
|
+
FORCE_INSTALL=false
|
|
33
|
+
INSTALL_ALL_HOOKS=true
|
|
34
|
+
HOOK_PREFIX="stackmemory"
|
|
35
|
+
|
|
36
|
+
# Script directory
|
|
37
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
38
|
+
HOOKS_SOURCE_DIR="$SCRIPT_DIR/git-hooks"
|
|
39
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
|
|
40
|
+
HOOKS_DIR="$REPO_ROOT/.git/hooks"
|
|
41
|
+
|
|
42
|
+
# Help function
|
|
43
|
+
show_help() {
|
|
44
|
+
cat << EOF
|
|
45
|
+
StackMemory Git Hooks Installer
|
|
46
|
+
|
|
47
|
+
Usage: $0 [OPTIONS] [COMMAND]
|
|
48
|
+
|
|
49
|
+
COMMANDS:
|
|
50
|
+
install Install StackMemory git hooks (default)
|
|
51
|
+
uninstall Remove StackMemory git hooks
|
|
52
|
+
status Show hook installation status
|
|
53
|
+
backup Backup existing hooks
|
|
54
|
+
restore Restore backed up hooks
|
|
55
|
+
|
|
56
|
+
OPTIONS:
|
|
57
|
+
-f, --force Force installation (overwrite existing hooks)
|
|
58
|
+
-n, --no-backup Don't backup existing hooks
|
|
59
|
+
-s, --selective Install only specific hooks (interactive)
|
|
60
|
+
-h, --help Show this help message
|
|
61
|
+
|
|
62
|
+
EXAMPLES:
|
|
63
|
+
$0 # Install all hooks with backup
|
|
64
|
+
$0 install --force # Force install, overwrite existing
|
|
65
|
+
$0 --selective # Choose which hooks to install
|
|
66
|
+
$0 uninstall # Remove StackMemory hooks
|
|
67
|
+
$0 status # Check installation status
|
|
68
|
+
|
|
69
|
+
EOF
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Check if we're in a git repository
|
|
73
|
+
check_git_repo() {
|
|
74
|
+
if [ ! -d ".git" ] && ! git rev-parse --git-dir >/dev/null 2>&1; then
|
|
75
|
+
log_error "Not in a git repository. Please run this from the project root."
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
if [ ! -d "$HOOKS_DIR" ]; then
|
|
80
|
+
log_error "Git hooks directory not found: $HOOKS_DIR"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
return 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Check if StackMemory is available
|
|
88
|
+
check_stackmemory() {
|
|
89
|
+
if ! command -v stackmemory >/dev/null 2>&1; then
|
|
90
|
+
log_warning "StackMemory CLI not found. Hooks will be installed but may not function until StackMemory is installed."
|
|
91
|
+
log_info "Install StackMemory with: npm install -g @stackmemoryai/stackmemory"
|
|
92
|
+
return 1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
if [ ! -d ".stackmemory" ]; then
|
|
96
|
+
log_warning "StackMemory not initialized in this repo. Run 'stackmemory init' after installation."
|
|
97
|
+
return 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
return 0
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Backup existing hook
|
|
104
|
+
backup_hook() {
|
|
105
|
+
local hook_name="$1"
|
|
106
|
+
local hook_file="$HOOKS_DIR/$hook_name"
|
|
107
|
+
local backup_file="$hook_file.backup-$(date +%Y%m%d-%H%M%S)"
|
|
108
|
+
|
|
109
|
+
if [ -f "$hook_file" ] && [ "$BACKUP_EXISTING_HOOKS" = "true" ]; then
|
|
110
|
+
cp "$hook_file" "$backup_file"
|
|
111
|
+
log_info "Backed up existing $hook_name to $(basename "$backup_file")"
|
|
112
|
+
return 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
return 1
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Install a single hook
|
|
119
|
+
install_hook() {
|
|
120
|
+
local hook_name="$1"
|
|
121
|
+
local source_file="$HOOKS_SOURCE_DIR/${hook_name}-${HOOK_PREFIX}.sh"
|
|
122
|
+
local target_file="$HOOKS_DIR/$hook_name"
|
|
123
|
+
|
|
124
|
+
if [ ! -f "$source_file" ]; then
|
|
125
|
+
log_warning "Source hook not found: $source_file"
|
|
126
|
+
return 1
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Check if hook already exists
|
|
130
|
+
if [ -f "$target_file" ] && [ "$FORCE_INSTALL" != "true" ]; then
|
|
131
|
+
log_warning "Hook already exists: $hook_name"
|
|
132
|
+
log_info "Use --force to overwrite or run uninstall first"
|
|
133
|
+
return 1
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# Backup existing hook
|
|
137
|
+
backup_hook "$hook_name"
|
|
138
|
+
|
|
139
|
+
# Install the hook
|
|
140
|
+
cp "$source_file" "$target_file"
|
|
141
|
+
chmod +x "$target_file"
|
|
142
|
+
|
|
143
|
+
log_success "Installed $hook_name hook"
|
|
144
|
+
return 0
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Install wrapper hook (combines existing with StackMemory)
|
|
148
|
+
install_wrapper_hook() {
|
|
149
|
+
local hook_name="$1"
|
|
150
|
+
local source_file="$HOOKS_SOURCE_DIR/${hook_name}-${HOOK_PREFIX}.sh"
|
|
151
|
+
local target_file="$HOOKS_DIR/$hook_name"
|
|
152
|
+
local existing_backup=""
|
|
153
|
+
|
|
154
|
+
if [ ! -f "$source_file" ]; then
|
|
155
|
+
log_warning "Source hook not found: $source_file"
|
|
156
|
+
return 1
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# If hook exists, create wrapper that calls both
|
|
160
|
+
if [ -f "$target_file" ] && [ "$FORCE_INSTALL" != "true" ]; then
|
|
161
|
+
# Create wrapper hook
|
|
162
|
+
existing_backup="$target_file.original"
|
|
163
|
+
|
|
164
|
+
if [ ! -f "$existing_backup" ]; then
|
|
165
|
+
cp "$target_file" "$existing_backup"
|
|
166
|
+
log_info "Preserved existing $hook_name as ${hook_name}.original"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Create wrapper
|
|
170
|
+
cat > "$target_file" << EOF
|
|
171
|
+
#!/bin/bash
|
|
172
|
+
# StackMemory Git Hook Wrapper
|
|
173
|
+
# This hook combines existing functionality with StackMemory integration
|
|
174
|
+
|
|
175
|
+
# Run original hook if it exists
|
|
176
|
+
if [ -f ".git/hooks/${hook_name}.original" ]; then
|
|
177
|
+
.git/hooks/${hook_name}.original "\$@"
|
|
178
|
+
original_exit_code=\$?
|
|
179
|
+
if [ \$original_exit_code -ne 0 ]; then
|
|
180
|
+
exit \$original_exit_code
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
# Run StackMemory hook
|
|
185
|
+
if [ -f "$source_file" ]; then
|
|
186
|
+
"$source_file" "\$@"
|
|
187
|
+
else
|
|
188
|
+
echo "⚠️ StackMemory hook not found: $source_file"
|
|
189
|
+
exit 0
|
|
190
|
+
fi
|
|
191
|
+
EOF
|
|
192
|
+
|
|
193
|
+
chmod +x "$target_file"
|
|
194
|
+
log_success "Created wrapper for $hook_name (preserves existing functionality)"
|
|
195
|
+
else
|
|
196
|
+
# Direct installation
|
|
197
|
+
backup_hook "$hook_name"
|
|
198
|
+
cp "$source_file" "$target_file"
|
|
199
|
+
chmod +x "$target_file"
|
|
200
|
+
log_success "Installed $hook_name hook"
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
return 0
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# Install all hooks
|
|
207
|
+
install_all_hooks() {
|
|
208
|
+
log_info "Installing StackMemory git hooks..."
|
|
209
|
+
|
|
210
|
+
local hooks_installed=0
|
|
211
|
+
local hooks_failed=0
|
|
212
|
+
|
|
213
|
+
# List of hooks to install
|
|
214
|
+
local hooks=("pre-commit" "post-commit" "post-checkout")
|
|
215
|
+
|
|
216
|
+
for hook in "${hooks[@]}"; do
|
|
217
|
+
log_info "Installing $hook hook..."
|
|
218
|
+
|
|
219
|
+
if install_wrapper_hook "$hook"; then
|
|
220
|
+
hooks_installed=$((hooks_installed + 1))
|
|
221
|
+
else
|
|
222
|
+
hooks_failed=$((hooks_failed + 1))
|
|
223
|
+
fi
|
|
224
|
+
done
|
|
225
|
+
|
|
226
|
+
log_info "Hook installation summary:"
|
|
227
|
+
log_success "$hooks_installed hooks installed successfully"
|
|
228
|
+
|
|
229
|
+
if [ $hooks_failed -gt 0 ]; then
|
|
230
|
+
log_warning "$hooks_failed hooks failed to install"
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
return 0
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
# Selective hook installation
|
|
237
|
+
install_selective_hooks() {
|
|
238
|
+
log_info "Selective hook installation - choose which hooks to install:"
|
|
239
|
+
|
|
240
|
+
local hooks=("pre-commit" "post-commit" "post-checkout")
|
|
241
|
+
local selected_hooks=()
|
|
242
|
+
|
|
243
|
+
for hook in "${hooks[@]}"; do
|
|
244
|
+
echo -n "Install $hook hook? [y/N]: "
|
|
245
|
+
read -r response
|
|
246
|
+
|
|
247
|
+
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
248
|
+
selected_hooks+=("$hook")
|
|
249
|
+
fi
|
|
250
|
+
done
|
|
251
|
+
|
|
252
|
+
if [ ${#selected_hooks[@]} -eq 0 ]; then
|
|
253
|
+
log_info "No hooks selected for installation"
|
|
254
|
+
return 0
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
log_info "Installing selected hooks: ${selected_hooks[*]}"
|
|
258
|
+
|
|
259
|
+
for hook in "${selected_hooks[@]}"; do
|
|
260
|
+
install_wrapper_hook "$hook"
|
|
261
|
+
done
|
|
262
|
+
|
|
263
|
+
return 0
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
# Uninstall hooks
|
|
267
|
+
uninstall_hooks() {
|
|
268
|
+
log_info "Uninstalling StackMemory git hooks..."
|
|
269
|
+
|
|
270
|
+
local hooks=("pre-commit" "post-commit" "post-checkout")
|
|
271
|
+
local hooks_removed=0
|
|
272
|
+
|
|
273
|
+
for hook in "${hooks[@]}"; do
|
|
274
|
+
local hook_file="$HOOKS_DIR/$hook"
|
|
275
|
+
local original_file="$HOOKS_DIR/$hook.original"
|
|
276
|
+
|
|
277
|
+
if [ -f "$hook_file" ]; then
|
|
278
|
+
# Check if it's a StackMemory hook
|
|
279
|
+
if grep -q "StackMemory" "$hook_file" 2>/dev/null; then
|
|
280
|
+
# Restore original if exists
|
|
281
|
+
if [ -f "$original_file" ]; then
|
|
282
|
+
mv "$original_file" "$hook_file"
|
|
283
|
+
log_success "Restored original $hook hook"
|
|
284
|
+
else
|
|
285
|
+
rm -f "$hook_file"
|
|
286
|
+
log_success "Removed $hook hook"
|
|
287
|
+
fi
|
|
288
|
+
hooks_removed=$((hooks_removed + 1))
|
|
289
|
+
else
|
|
290
|
+
log_info "$hook hook exists but is not from StackMemory"
|
|
291
|
+
fi
|
|
292
|
+
fi
|
|
293
|
+
done
|
|
294
|
+
|
|
295
|
+
if [ $hooks_removed -eq 0 ]; then
|
|
296
|
+
log_info "No StackMemory hooks found to remove"
|
|
297
|
+
else
|
|
298
|
+
log_success "Removed $hooks_removed StackMemory hooks"
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
return 0
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
# Show installation status
|
|
305
|
+
show_status() {
|
|
306
|
+
log_info "StackMemory Git Hooks Status:"
|
|
307
|
+
echo ""
|
|
308
|
+
|
|
309
|
+
local hooks=("pre-commit" "post-commit" "post-checkout")
|
|
310
|
+
|
|
311
|
+
for hook in "${hooks[@]}"; do
|
|
312
|
+
local hook_file="$HOOKS_DIR/$hook"
|
|
313
|
+
local original_file="$HOOKS_DIR/$hook.original"
|
|
314
|
+
|
|
315
|
+
printf "%-15s " "$hook:"
|
|
316
|
+
|
|
317
|
+
if [ -f "$hook_file" ]; then
|
|
318
|
+
if grep -q "StackMemory" "$hook_file" 2>/dev/null; then
|
|
319
|
+
echo -e "${GREEN}✅ Installed${NC}"
|
|
320
|
+
|
|
321
|
+
if [ -f "$original_file" ]; then
|
|
322
|
+
echo " (with original preserved)"
|
|
323
|
+
fi
|
|
324
|
+
else
|
|
325
|
+
echo -e "${YELLOW}⚠️ Exists (not StackMemory)${NC}"
|
|
326
|
+
fi
|
|
327
|
+
else
|
|
328
|
+
echo -e "${RED}❌ Not installed${NC}"
|
|
329
|
+
fi
|
|
330
|
+
done
|
|
331
|
+
|
|
332
|
+
echo ""
|
|
333
|
+
|
|
334
|
+
# Check StackMemory availability
|
|
335
|
+
echo "StackMemory CLI:"
|
|
336
|
+
if command -v stackmemory >/dev/null 2>&1; then
|
|
337
|
+
echo -e " ${GREEN}✅ Available${NC} ($(stackmemory --version 2>/dev/null || echo "unknown version"))"
|
|
338
|
+
else
|
|
339
|
+
echo -e " ${RED}❌ Not found${NC}"
|
|
340
|
+
fi
|
|
341
|
+
|
|
342
|
+
echo "StackMemory Init:"
|
|
343
|
+
if [ -d ".stackmemory" ]; then
|
|
344
|
+
echo -e " ${GREEN}✅ Initialized${NC}"
|
|
345
|
+
else
|
|
346
|
+
echo -e " ${YELLOW}⚠️ Not initialized${NC}"
|
|
347
|
+
fi
|
|
348
|
+
|
|
349
|
+
return 0
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
# Main execution
|
|
353
|
+
main() {
|
|
354
|
+
local command="install"
|
|
355
|
+
local selective=false
|
|
356
|
+
|
|
357
|
+
# Parse arguments
|
|
358
|
+
while [[ $# -gt 0 ]]; do
|
|
359
|
+
case $1 in
|
|
360
|
+
install|uninstall|status|backup|restore)
|
|
361
|
+
command="$1"
|
|
362
|
+
shift
|
|
363
|
+
;;
|
|
364
|
+
-f|--force)
|
|
365
|
+
FORCE_INSTALL=true
|
|
366
|
+
shift
|
|
367
|
+
;;
|
|
368
|
+
-n|--no-backup)
|
|
369
|
+
BACKUP_EXISTING_HOOKS=false
|
|
370
|
+
shift
|
|
371
|
+
;;
|
|
372
|
+
-s|--selective)
|
|
373
|
+
selective=true
|
|
374
|
+
shift
|
|
375
|
+
;;
|
|
376
|
+
-h|--help)
|
|
377
|
+
show_help
|
|
378
|
+
exit 0
|
|
379
|
+
;;
|
|
380
|
+
*)
|
|
381
|
+
log_error "Unknown option: $1"
|
|
382
|
+
show_help
|
|
383
|
+
exit 1
|
|
384
|
+
;;
|
|
385
|
+
esac
|
|
386
|
+
done
|
|
387
|
+
|
|
388
|
+
# Check prerequisites
|
|
389
|
+
check_git_repo
|
|
390
|
+
check_stackmemory
|
|
391
|
+
|
|
392
|
+
# Execute command
|
|
393
|
+
case "$command" in
|
|
394
|
+
"install")
|
|
395
|
+
if [ "$selective" = "true" ]; then
|
|
396
|
+
install_selective_hooks
|
|
397
|
+
else
|
|
398
|
+
install_all_hooks
|
|
399
|
+
fi
|
|
400
|
+
show_status
|
|
401
|
+
;;
|
|
402
|
+
"uninstall")
|
|
403
|
+
uninstall_hooks
|
|
404
|
+
;;
|
|
405
|
+
"status")
|
|
406
|
+
show_status
|
|
407
|
+
;;
|
|
408
|
+
*)
|
|
409
|
+
log_error "Unknown command: $command"
|
|
410
|
+
show_help
|
|
411
|
+
exit 1
|
|
412
|
+
;;
|
|
413
|
+
esac
|
|
414
|
+
|
|
415
|
+
log_info "For more information, see: scripts/git-hooks/README.md"
|
|
416
|
+
return 0
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
# Run main function
|
|
420
|
+
main "$@"
|