jfl 0.1.0 → 0.2.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/README.md +443 -145
- package/clawdbot-plugin/clawdbot.plugin.json +20 -0
- package/clawdbot-plugin/index.js +555 -0
- package/clawdbot-plugin/index.ts +582 -0
- package/clawdbot-skill/SKILL.md +33 -336
- package/clawdbot-skill/index.ts +491 -321
- package/clawdbot-skill/skill.json +4 -13
- package/dist/commands/clawdbot.d.ts +11 -0
- package/dist/commands/clawdbot.d.ts.map +1 -0
- package/dist/commands/clawdbot.js +215 -0
- package/dist/commands/clawdbot.js.map +1 -0
- package/dist/commands/context-hub.d.ts +5 -0
- package/dist/commands/context-hub.d.ts.map +1 -1
- package/dist/commands/context-hub.js +394 -28
- package/dist/commands/context-hub.js.map +1 -1
- package/dist/commands/gtm-process-update.d.ts +10 -0
- package/dist/commands/gtm-process-update.d.ts.map +1 -0
- package/dist/commands/gtm-process-update.js +101 -0
- package/dist/commands/gtm-process-update.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +278 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +32 -33
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/memory.d.ts +38 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +229 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/migrate-services.d.ts +8 -0
- package/dist/commands/migrate-services.d.ts.map +1 -0
- package/dist/commands/migrate-services.js +182 -0
- package/dist/commands/migrate-services.js.map +1 -0
- package/dist/commands/onboard.d.ts +24 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +663 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/openclaw.d.ts +56 -0
- package/dist/commands/openclaw.d.ts.map +1 -0
- package/dist/commands/openclaw.js +700 -0
- package/dist/commands/openclaw.js.map +1 -0
- package/dist/commands/orchestrate.d.ts +14 -0
- package/dist/commands/orchestrate.d.ts.map +1 -0
- package/dist/commands/orchestrate.js +270 -0
- package/dist/commands/orchestrate.js.map +1 -0
- package/dist/commands/profile.d.ts +46 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +498 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/repair.d.ts.map +1 -1
- package/dist/commands/repair.js +37 -0
- package/dist/commands/repair.js.map +1 -1
- package/dist/commands/service-agent.d.ts +16 -0
- package/dist/commands/service-agent.d.ts.map +1 -0
- package/dist/commands/service-agent.js +375 -0
- package/dist/commands/service-agent.js.map +1 -0
- package/dist/commands/service-manager.d.ts +12 -0
- package/dist/commands/service-manager.d.ts.map +1 -0
- package/dist/commands/service-manager.js +967 -0
- package/dist/commands/service-manager.js.map +1 -0
- package/dist/commands/service-validate.d.ts +12 -0
- package/dist/commands/service-validate.d.ts.map +1 -0
- package/dist/commands/service-validate.js +611 -0
- package/dist/commands/service-validate.js.map +1 -0
- package/dist/commands/services-create.d.ts +15 -0
- package/dist/commands/services-create.d.ts.map +1 -0
- package/dist/commands/services-create.js +1452 -0
- package/dist/commands/services-create.js.map +1 -0
- package/dist/commands/services-scan.d.ts +13 -0
- package/dist/commands/services-scan.d.ts.map +1 -0
- package/dist/commands/services-scan.js +251 -0
- package/dist/commands/services-scan.js.map +1 -0
- package/dist/commands/services-sync-agents.d.ts +23 -0
- package/dist/commands/services-sync-agents.d.ts.map +1 -0
- package/dist/commands/services-sync-agents.js +207 -0
- package/dist/commands/services-sync-agents.js.map +1 -0
- package/dist/commands/services.d.ts +19 -0
- package/dist/commands/services.d.ts.map +1 -0
- package/dist/commands/services.js +742 -0
- package/dist/commands/services.js.map +1 -0
- package/dist/commands/session.d.ts +5 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +68 -586
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +17 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +75 -21
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate-settings.d.ts +37 -0
- package/dist/commands/validate-settings.d.ts.map +1 -0
- package/dist/commands/validate-settings.js +197 -0
- package/dist/commands/validate-settings.js.map +1 -0
- package/dist/commands/voice.d.ts +0 -1
- package/dist/commands/voice.d.ts.map +1 -1
- package/dist/commands/voice.js +16 -15
- package/dist/commands/voice.js.map +1 -1
- package/dist/index.js +395 -141
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-generator.d.ts +26 -0
- package/dist/lib/agent-generator.d.ts.map +1 -0
- package/dist/lib/agent-generator.js +331 -0
- package/dist/lib/agent-generator.js.map +1 -0
- package/dist/lib/memory-db.d.ts +102 -0
- package/dist/lib/memory-db.d.ts.map +1 -0
- package/dist/lib/memory-db.js +313 -0
- package/dist/lib/memory-db.js.map +1 -0
- package/dist/lib/memory-indexer.d.ts +47 -0
- package/dist/lib/memory-indexer.d.ts.map +1 -0
- package/dist/lib/memory-indexer.js +215 -0
- package/dist/lib/memory-indexer.js.map +1 -0
- package/dist/lib/memory-search.d.ts +41 -0
- package/dist/lib/memory-search.d.ts.map +1 -0
- package/dist/lib/memory-search.js +246 -0
- package/dist/lib/memory-search.js.map +1 -0
- package/dist/lib/openclaw-registry.d.ts +48 -0
- package/dist/lib/openclaw-registry.d.ts.map +1 -0
- package/dist/lib/openclaw-registry.js +181 -0
- package/dist/lib/openclaw-registry.js.map +1 -0
- package/dist/lib/openclaw-sdk.d.ts +107 -0
- package/dist/lib/openclaw-sdk.d.ts.map +1 -0
- package/dist/lib/openclaw-sdk.js +208 -0
- package/dist/lib/openclaw-sdk.js.map +1 -0
- package/dist/lib/peer-agent-generator.d.ts +44 -0
- package/dist/lib/peer-agent-generator.d.ts.map +1 -0
- package/dist/lib/peer-agent-generator.js +286 -0
- package/dist/lib/peer-agent-generator.js.map +1 -0
- package/dist/lib/service-dependencies.d.ts +44 -0
- package/dist/lib/service-dependencies.d.ts.map +1 -0
- package/dist/lib/service-dependencies.js +314 -0
- package/dist/lib/service-dependencies.js.map +1 -0
- package/dist/lib/service-detector.d.ts +61 -0
- package/dist/lib/service-detector.d.ts.map +1 -0
- package/dist/lib/service-detector.js +521 -0
- package/dist/lib/service-detector.js.map +1 -0
- package/dist/lib/service-gtm.d.ts +157 -0
- package/dist/lib/service-gtm.d.ts.map +1 -0
- package/dist/lib/service-gtm.js +786 -0
- package/dist/lib/service-gtm.js.map +1 -0
- package/dist/lib/service-mcp-base.d.ts +103 -0
- package/dist/lib/service-mcp-base.d.ts.map +1 -0
- package/dist/lib/service-mcp-base.js +263 -0
- package/dist/lib/service-mcp-base.js.map +1 -0
- package/dist/lib/service-utils.d.ts +103 -0
- package/dist/lib/service-utils.d.ts.map +1 -0
- package/dist/lib/service-utils.js +368 -0
- package/dist/lib/service-utils.js.map +1 -0
- package/dist/lib/skill-generator.d.ts +21 -0
- package/dist/lib/skill-generator.d.ts.map +1 -0
- package/dist/lib/skill-generator.js +253 -0
- package/dist/lib/skill-generator.js.map +1 -0
- package/dist/lib/stratus-client.d.ts +100 -0
- package/dist/lib/stratus-client.d.ts.map +1 -0
- package/dist/lib/stratus-client.js +255 -0
- package/dist/lib/stratus-client.js.map +1 -0
- package/dist/mcp/context-hub-mcp.js +135 -53
- package/dist/mcp/context-hub-mcp.js.map +1 -1
- package/dist/mcp/service-mcp-server.d.ts +12 -0
- package/dist/mcp/service-mcp-server.d.ts.map +1 -0
- package/dist/mcp/service-mcp-server.js +434 -0
- package/dist/mcp/service-mcp-server.js.map +1 -0
- package/dist/mcp/service-peer-mcp.d.ts +36 -0
- package/dist/mcp/service-peer-mcp.d.ts.map +1 -0
- package/dist/mcp/service-peer-mcp.js +220 -0
- package/dist/mcp/service-peer-mcp.js.map +1 -0
- package/dist/mcp/service-registry-mcp.d.ts +13 -0
- package/dist/mcp/service-registry-mcp.d.ts.map +1 -0
- package/dist/mcp/service-registry-mcp.js +330 -0
- package/dist/mcp/service-registry-mcp.js.map +1 -0
- package/dist/ui/banner.js +1 -1
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/context-hub-logs.d.ts +10 -0
- package/dist/ui/context-hub-logs.d.ts.map +1 -0
- package/dist/ui/context-hub-logs.js +175 -0
- package/dist/ui/context-hub-logs.js.map +1 -0
- package/dist/ui/service-dashboard.d.ts +11 -0
- package/dist/ui/service-dashboard.d.ts.map +1 -0
- package/dist/ui/service-dashboard.js +357 -0
- package/dist/ui/service-dashboard.js.map +1 -0
- package/dist/ui/services-manager.d.ts +11 -0
- package/dist/ui/services-manager.d.ts.map +1 -0
- package/dist/ui/services-manager.js +507 -0
- package/dist/ui/services-manager.js.map +1 -0
- package/dist/utils/auth-guard.d.ts.map +1 -1
- package/dist/utils/auth-guard.js +8 -9
- package/dist/utils/auth-guard.js.map +1 -1
- package/dist/utils/claude-md-generator.d.ts +10 -0
- package/dist/utils/claude-md-generator.d.ts.map +1 -0
- package/dist/utils/claude-md-generator.js +215 -0
- package/dist/utils/claude-md-generator.js.map +1 -0
- package/dist/utils/ensure-context-hub.d.ts +20 -0
- package/dist/utils/ensure-context-hub.d.ts.map +1 -0
- package/dist/utils/ensure-context-hub.js +65 -0
- package/dist/utils/ensure-context-hub.js.map +1 -0
- package/dist/utils/ensure-project.d.ts.map +1 -1
- package/dist/utils/ensure-project.js +3 -4
- package/dist/utils/ensure-project.js.map +1 -1
- package/dist/utils/jfl-config.d.ts +19 -0
- package/dist/utils/jfl-config.d.ts.map +1 -0
- package/dist/utils/jfl-config.js +112 -0
- package/dist/utils/jfl-config.js.map +1 -0
- package/dist/utils/jfl-migration.d.ts +29 -0
- package/dist/utils/jfl-migration.d.ts.map +1 -0
- package/dist/utils/jfl-migration.js +142 -0
- package/dist/utils/jfl-migration.js.map +1 -0
- package/dist/utils/jfl-paths.d.ts +55 -0
- package/dist/utils/jfl-paths.d.ts.map +1 -0
- package/dist/utils/jfl-paths.js +120 -0
- package/dist/utils/jfl-paths.js.map +1 -0
- package/dist/utils/settings-validator.d.ts +73 -0
- package/dist/utils/settings-validator.d.ts.map +1 -0
- package/dist/utils/settings-validator.js +222 -0
- package/dist/utils/settings-validator.js.map +1 -0
- package/package.json +19 -3
- package/scripts/commit-gtm.sh +56 -0
- package/scripts/commit-product.sh +68 -0
- package/scripts/context-query.sh +45 -0
- package/scripts/session/auto-commit.sh +297 -0
- package/scripts/session/jfl-doctor.sh +707 -0
- package/scripts/session/session-cleanup.sh +268 -0
- package/scripts/session/session-end.sh +198 -0
- package/scripts/session/session-init.sh +350 -0
- package/scripts/session/session-init.sh.backup +292 -0
- package/scripts/session/session-sync.sh +167 -0
- package/scripts/session/test-context-preservation.sh +160 -0
- package/scripts/session/test-critical-infrastructure.sh +293 -0
- package/scripts/session/test-experience-level.sh +336 -0
- package/scripts/session/test-session-cleanup.sh +268 -0
- package/scripts/session/test-session-sync.sh +320 -0
- package/scripts/voice-start.sh +36 -8
- package/scripts/where-am-i.sh +78 -0
- package/template/.claude/service-settings.json +32 -0
- package/template/.claude/settings.json +14 -1
- package/template/.claude/skills/end/SKILL.md +1780 -0
- package/template/.jfl/config.json +2 -1
- package/template/CLAUDE.md +1039 -134
- package/template/CLAUDE.md.bak +1187 -0
- package/template/scripts/commit-gtm.sh +56 -0
- package/template/scripts/commit-product.sh +68 -0
- package/template/scripts/migrate-to-branch-sessions.sh +201 -0
- package/template/scripts/session/auto-commit.sh +58 -6
- package/template/scripts/session/jfl-doctor.sh +137 -17
- package/template/scripts/session/session-cleanup.sh +268 -0
- package/template/scripts/session/session-end.sh +4 -0
- package/template/scripts/session/session-init.sh +253 -66
- package/template/scripts/session/test-critical-infrastructure.sh +293 -0
- package/template/scripts/session/test-experience-level.sh +336 -0
- package/template/scripts/session/test-session-cleanup.sh +268 -0
- package/template/scripts/session/test-session-sync.sh +320 -0
- package/template/scripts/where-am-i.sh +78 -0
- package/template/templates/service-agent/.claude/settings.json +32 -0
- package/template/templates/service-agent/CLAUDE.md +334 -0
- package/template/templates/service-agent/knowledge/ARCHITECTURE.md +115 -0
- package/template/templates/service-agent/knowledge/DEPLOYMENT.md +199 -0
- package/template/templates/service-agent/knowledge/RUNBOOK.md +412 -0
- package/template/templates/service-agent/knowledge/SERVICE_SPEC.md +77 -0
- package/dist/commands/session-mgmt.d.ts +0 -33
- package/dist/commands/session-mgmt.d.ts.map +0 -1
- package/dist/commands/session-mgmt.js +0 -404
- package/dist/commands/session-mgmt.js.map +0 -1
- package/template/scripts/session/auto-merge.sh +0 -325
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Test Suite: Session Cleanup
|
|
4
|
+
#
|
|
5
|
+
# Tests session-cleanup.sh against critical safety requirements:
|
|
6
|
+
# - NEVER loses uncommitted work
|
|
7
|
+
# - NEVER loses conflicting changes
|
|
8
|
+
# - ONLY auto-merges safe commits (auto-saves, journal entries)
|
|
9
|
+
# - ALWAYS preserves journal entries
|
|
10
|
+
# - Properly removes worktrees after successful merge
|
|
11
|
+
# - Handles all exit scenarios (normal, Ctrl+C, crash, kill)
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
REPO_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
17
|
+
|
|
18
|
+
# Colors
|
|
19
|
+
RED='\033[0;31m'
|
|
20
|
+
GREEN='\033[0;32m'
|
|
21
|
+
YELLOW='\033[1;33m'
|
|
22
|
+
NC='\033[0m' # No Color
|
|
23
|
+
|
|
24
|
+
TESTS_RUN=0
|
|
25
|
+
TESTS_PASSED=0
|
|
26
|
+
TESTS_FAILED=0
|
|
27
|
+
|
|
28
|
+
print_test() {
|
|
29
|
+
echo ""
|
|
30
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
31
|
+
echo "TEST: $1"
|
|
32
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
pass() {
|
|
36
|
+
echo -e "${GREEN}✓ PASS${NC}: $1"
|
|
37
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
38
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fail() {
|
|
42
|
+
echo -e "${RED}✗ FAIL${NC}: $1"
|
|
43
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
44
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
anti_test() {
|
|
48
|
+
echo -e "${YELLOW}⚠ ANTI-TEST${NC}: $1 (should NOT happen)"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
52
|
+
# Safety Tests - CRITICAL: Must never lose work
|
|
53
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
54
|
+
|
|
55
|
+
print_test "SAFETY: Cleanup script exists and is executable"
|
|
56
|
+
if [[ -f "$SCRIPT_DIR/session-cleanup.sh" ]]; then
|
|
57
|
+
pass "session-cleanup.sh exists"
|
|
58
|
+
else
|
|
59
|
+
fail "session-cleanup.sh not found"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
if [[ -x "$SCRIPT_DIR/session-cleanup.sh" ]]; then
|
|
63
|
+
pass "session-cleanup.sh is executable"
|
|
64
|
+
else
|
|
65
|
+
fail "session-cleanup.sh not executable"
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
print_test "SAFETY: Script has auto-commit before merge"
|
|
69
|
+
if grep -q "git add -A" "$SCRIPT_DIR/session-cleanup.sh" && \
|
|
70
|
+
grep -q "git commit" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
71
|
+
pass "Auto-commits before attempting merge"
|
|
72
|
+
else
|
|
73
|
+
fail "Missing auto-commit before merge - WILL LOSE WORK"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
print_test "SAFETY: Script checks if on session branch"
|
|
77
|
+
if grep -q 'if.*session-' "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
78
|
+
pass "Checks for session branch before cleanup"
|
|
79
|
+
else
|
|
80
|
+
fail "Doesn't check branch type - might cleanup non-session branches"
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
print_test "SAFETY: Script aborts merge on conflicts"
|
|
84
|
+
if grep -q "git merge --abort" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
85
|
+
pass "Aborts merge on conflicts (preserves work)"
|
|
86
|
+
else
|
|
87
|
+
fail "Doesn't abort on conflicts - WILL LOSE CONFLICTING CHANGES"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
print_test "SAFETY: Script uses auto-resolve strategy for .jfl/ conflicts"
|
|
91
|
+
if grep -q -- "-X ours" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
92
|
+
pass "Uses -X ours for auto-resolving .jfl/ conflicts"
|
|
93
|
+
else
|
|
94
|
+
fail "Missing conflict resolution strategy - merges will fail unnecessarily"
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
print_test "ANTI-TEST: Script doesn't use --force flags"
|
|
98
|
+
anti_test "git push --force"
|
|
99
|
+
if grep -q "push.*--force" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
100
|
+
fail "Uses --force push - DANGEROUS"
|
|
101
|
+
else
|
|
102
|
+
pass "No --force push (safe)"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
anti_test "git clean -f"
|
|
106
|
+
if grep -q "git clean" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
107
|
+
fail "Uses git clean - WILL LOSE UNTRACKED FILES"
|
|
108
|
+
else
|
|
109
|
+
pass "No git clean (safe)"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
anti_test "git reset --hard"
|
|
113
|
+
if grep -q "reset.*--hard" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
114
|
+
fail "Uses reset --hard - WILL LOSE UNCOMMITTED WORK"
|
|
115
|
+
else
|
|
116
|
+
pass "No reset --hard (safe)"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
120
|
+
# Integration Tests - Works with existing infrastructure
|
|
121
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
122
|
+
|
|
123
|
+
print_test "INTEGRATION: Stop hook calls session-cleanup.sh"
|
|
124
|
+
SETTINGS_FILE="$REPO_DIR/.claude/settings.json"
|
|
125
|
+
if [[ -f "$SETTINGS_FILE" ]]; then
|
|
126
|
+
if grep -q "session-cleanup.sh" "$SETTINGS_FILE"; then
|
|
127
|
+
pass "Stop hook configured to run cleanup"
|
|
128
|
+
else
|
|
129
|
+
fail "Stop hook doesn't call session-cleanup.sh"
|
|
130
|
+
fi
|
|
131
|
+
else
|
|
132
|
+
fail ".claude/settings.json not found"
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
print_test "INTEGRATION: Signal handler calls session-cleanup.sh"
|
|
136
|
+
AUTO_COMMIT_SCRIPT="$SCRIPT_DIR/auto-commit.sh"
|
|
137
|
+
if [[ -f "$AUTO_COMMIT_SCRIPT" ]]; then
|
|
138
|
+
if grep -A 10 "graceful_shutdown" "$AUTO_COMMIT_SCRIPT" | grep -q "session-cleanup.sh"; then
|
|
139
|
+
pass "Signal handler calls cleanup on Ctrl+C/kill"
|
|
140
|
+
else
|
|
141
|
+
fail "Signal handler doesn't call session-cleanup.sh - branches pile up on Ctrl+C"
|
|
142
|
+
fi
|
|
143
|
+
else
|
|
144
|
+
fail "auto-commit.sh not found"
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
print_test "INTEGRATION: Signal traps are set"
|
|
148
|
+
if grep -q "trap.*graceful_shutdown.*SIGINT.*SIGTERM" "$AUTO_COMMIT_SCRIPT"; then
|
|
149
|
+
pass "Signal traps set for SIGINT and SIGTERM"
|
|
150
|
+
else
|
|
151
|
+
fail "Missing signal traps - Ctrl+C won't trigger cleanup"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
155
|
+
# Functional Tests - Script behavior
|
|
156
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
157
|
+
|
|
158
|
+
print_test "FUNCTIONAL: Script skips cleanup on non-session branches"
|
|
159
|
+
CLEANUP_OUTPUT=$("$SCRIPT_DIR/session-cleanup.sh" 2>&1 || true)
|
|
160
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
161
|
+
|
|
162
|
+
if [[ ! "$CURRENT_BRANCH" =~ ^session- ]]; then
|
|
163
|
+
if echo "$CLEANUP_OUTPUT" | grep -q "Not a session branch"; then
|
|
164
|
+
pass "Skips cleanup on non-session branch (main)"
|
|
165
|
+
else
|
|
166
|
+
fail "Doesn't skip non-session branches - might cleanup main!"
|
|
167
|
+
fi
|
|
168
|
+
else
|
|
169
|
+
pass "Currently on session branch, skipping non-session test"
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
print_test "FUNCTIONAL: Script switches to main before merge"
|
|
173
|
+
if grep -q "git checkout main" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
174
|
+
pass "Switches to main before merging"
|
|
175
|
+
else
|
|
176
|
+
fail "Doesn't checkout main - merge will fail"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
print_test "FUNCTIONAL: Script removes worktree after successful merge"
|
|
180
|
+
if grep -q "git worktree.*remove" "$SCRIPT_DIR/session-cleanup.sh" || \
|
|
181
|
+
grep -q "rm -rf.*WORKTREE" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
182
|
+
pass "Removes worktree after merge"
|
|
183
|
+
else
|
|
184
|
+
fail "Doesn't remove worktree - will pile up disk usage"
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
print_test "FUNCTIONAL: Script deletes branch after successful merge"
|
|
188
|
+
if grep -q "git branch -D" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
189
|
+
pass "Deletes branch after successful merge"
|
|
190
|
+
else
|
|
191
|
+
fail "Doesn't delete branch - will pile up branches"
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
print_test "FUNCTIONAL: Script handles missing worktree gracefully"
|
|
195
|
+
if grep -q "\[ -n.*WORKTREE" "$SCRIPT_DIR/session-cleanup.sh" || \
|
|
196
|
+
grep -q "\[ -d.*WORKTREE" "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
197
|
+
pass "Checks if worktree exists before removing"
|
|
198
|
+
else
|
|
199
|
+
fail "Doesn't check worktree existence - might error on missing worktree"
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
203
|
+
# Edge Cases
|
|
204
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
205
|
+
|
|
206
|
+
print_test "EDGE CASE: Script handles 'not on a branch' scenario"
|
|
207
|
+
if grep -q 'if \[ -z.*BRANCH' "$SCRIPT_DIR/session-cleanup.sh"; then
|
|
208
|
+
pass "Checks if on a branch (handles detached HEAD)"
|
|
209
|
+
else
|
|
210
|
+
fail "Doesn't check for detached HEAD - will fail in that state"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
print_test "EDGE CASE: Script exits cleanly on all paths"
|
|
214
|
+
if tail -5 "$SCRIPT_DIR/session-cleanup.sh" | grep -q "exit 0"; then
|
|
215
|
+
pass "Script exits cleanly (exit 0)"
|
|
216
|
+
else
|
|
217
|
+
fail "Script might exit with error code - will break hooks"
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
print_test "EDGE CASE: Script doesn't fail entire hook chain"
|
|
221
|
+
# Check that cleanup is called with || true in hooks
|
|
222
|
+
if grep -q "session-cleanup.sh.*||" "$SETTINGS_FILE" 2>/dev/null; then
|
|
223
|
+
pass "Cleanup failure doesn't break hook chain"
|
|
224
|
+
else
|
|
225
|
+
fail "Cleanup failure could break Stop hook - session won't end"
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
229
|
+
# Performance Tests
|
|
230
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
231
|
+
|
|
232
|
+
print_test "PERFORMANCE: Cleanup redirects to log file"
|
|
233
|
+
if grep -q "session-cleanup.sh.*>>" "$SETTINGS_FILE" 2>/dev/null; then
|
|
234
|
+
pass "Cleanup output goes to log file (doesn't spam user)"
|
|
235
|
+
else
|
|
236
|
+
fail "Cleanup output not redirected - will spam terminal"
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
print_test "PERFORMANCE: Cleanup runs in background/async"
|
|
240
|
+
if grep -q "session-cleanup.sh.*2>&1" "$SETTINGS_FILE" 2>/dev/null; then
|
|
241
|
+
pass "Cleanup stderr redirected (clean output)"
|
|
242
|
+
else
|
|
243
|
+
fail "Cleanup stderr not redirected - errors spam terminal"
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
247
|
+
# Summary
|
|
248
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
249
|
+
|
|
250
|
+
echo ""
|
|
251
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
252
|
+
echo "TEST SUMMARY"
|
|
253
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
254
|
+
echo "Total tests: $TESTS_RUN"
|
|
255
|
+
echo -e "${GREEN}Passed:${NC} $TESTS_PASSED"
|
|
256
|
+
echo -e "${RED}Failed:${NC} $TESTS_FAILED"
|
|
257
|
+
|
|
258
|
+
if [ $TESTS_FAILED -eq 0 ]; then
|
|
259
|
+
echo ""
|
|
260
|
+
echo -e "${GREEN}✓ All tests passed!${NC}"
|
|
261
|
+
echo "Session cleanup is safe and ready for production."
|
|
262
|
+
exit 0
|
|
263
|
+
else
|
|
264
|
+
echo ""
|
|
265
|
+
echo -e "${RED}✗ $TESTS_FAILED test(s) failed!${NC}"
|
|
266
|
+
echo "Fix failing tests before deploying to ensure work is never lost."
|
|
267
|
+
exit 1
|
|
268
|
+
fi
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Rigorous tests for session-sync.sh
|
|
4
|
+
# Tests both positive cases AND anti-tests (what should NOT happen)
|
|
5
|
+
#
|
|
6
|
+
# @purpose Test session-sync.sh before committing (work-loss prevention)
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
TEST_DIR="/tmp/jfl-session-sync-test-$$"
|
|
12
|
+
REPO_DIR="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || echo ".")"
|
|
13
|
+
REPO_DIR="${REPO_DIR%/.git}"
|
|
14
|
+
|
|
15
|
+
# Colors
|
|
16
|
+
RED='\033[0;31m'
|
|
17
|
+
GREEN='\033[0;32m'
|
|
18
|
+
YELLOW='\033[1;33m'
|
|
19
|
+
BLUE='\033[0;34m'
|
|
20
|
+
NC='\033[0m'
|
|
21
|
+
|
|
22
|
+
TESTS_PASSED=0
|
|
23
|
+
TESTS_FAILED=0
|
|
24
|
+
|
|
25
|
+
pass() {
|
|
26
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
27
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fail() {
|
|
31
|
+
echo -e "${RED}✗${NC} $1"
|
|
32
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
section() {
|
|
36
|
+
echo ""
|
|
37
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
38
|
+
echo -e "${BLUE}$1${NC}"
|
|
39
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
cleanup() {
|
|
43
|
+
rm -rf "$TEST_DIR" 2>/dev/null || true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
trap cleanup EXIT
|
|
47
|
+
|
|
48
|
+
# ==============================================================================
|
|
49
|
+
# Test 1: Script Safety Checks
|
|
50
|
+
# ==============================================================================
|
|
51
|
+
|
|
52
|
+
test_safety_checks() {
|
|
53
|
+
section "Test 1: Safety Checks (prevent data loss)"
|
|
54
|
+
|
|
55
|
+
# Check for uncommitted changes protection
|
|
56
|
+
if grep -q "has uncommitted changes AND is behind" "$SCRIPT_DIR/session-sync.sh"; then
|
|
57
|
+
pass "Protects against pulling over uncommitted changes"
|
|
58
|
+
else
|
|
59
|
+
fail "No protection for uncommitted changes + pull"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Check that it uses 'set -e' for failure propagation
|
|
63
|
+
if head -10 "$SCRIPT_DIR/session-sync.sh" | grep -q "set -e"; then
|
|
64
|
+
pass "Uses 'set -e' for error propagation"
|
|
65
|
+
else
|
|
66
|
+
fail "Doesn't use 'set -e' - errors may be silent"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Check that it exits with error code on failure
|
|
70
|
+
if grep -q "exit 1" "$SCRIPT_DIR/session-sync.sh"; then
|
|
71
|
+
pass "Exits with error code on failure"
|
|
72
|
+
else
|
|
73
|
+
fail "Doesn't exit with error - CI/CD won't catch failures"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Anti-test: Verify it doesn't use --force flags
|
|
77
|
+
if grep -E "git pull.*--force|git reset --hard" "$SCRIPT_DIR/session-sync.sh" >/dev/null; then
|
|
78
|
+
fail "DANGER: Uses destructive git commands (--force, --hard)"
|
|
79
|
+
else
|
|
80
|
+
pass "Doesn't use destructive git commands"
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Check for graceful network failure handling
|
|
84
|
+
if grep -q "Could not fetch.*no network" "$SCRIPT_DIR/session-sync.sh"; then
|
|
85
|
+
pass "Handles network failures gracefully"
|
|
86
|
+
else
|
|
87
|
+
fail "No graceful handling of network failures"
|
|
88
|
+
fi
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# ==============================================================================
|
|
92
|
+
# Test 2: Detached HEAD Handling
|
|
93
|
+
# ==============================================================================
|
|
94
|
+
|
|
95
|
+
test_detached_head() {
|
|
96
|
+
section "Test 2: Detached HEAD Handling (submodules)"
|
|
97
|
+
|
|
98
|
+
# Check if script detects detached HEAD
|
|
99
|
+
if grep -q "detached HEAD state" "$SCRIPT_DIR/session-sync.sh"; then
|
|
100
|
+
pass "Detects detached HEAD state"
|
|
101
|
+
else
|
|
102
|
+
fail "Doesn't detect detached HEAD"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Check if it attempts to fix detached HEAD
|
|
106
|
+
if grep -A5 "detached HEAD" "$SCRIPT_DIR/session-sync.sh" | grep -q "checkout main"; then
|
|
107
|
+
pass "Attempts to fix detached HEAD automatically"
|
|
108
|
+
else
|
|
109
|
+
fail "Doesn't auto-fix detached HEAD"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# Anti-test: Verify it doesn't force checkout (would lose work)
|
|
113
|
+
if grep -E "git checkout.*-f|git checkout.*--force" "$SCRIPT_DIR/session-sync.sh" >/dev/null; then
|
|
114
|
+
fail "DANGER: Uses force checkout (loses uncommitted work)"
|
|
115
|
+
else
|
|
116
|
+
pass "Doesn't use force checkout"
|
|
117
|
+
fi
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# ==============================================================================
|
|
121
|
+
# Test 3: Submodule vs Symlink Detection
|
|
122
|
+
# ==============================================================================
|
|
123
|
+
|
|
124
|
+
test_product_detection() {
|
|
125
|
+
section "Test 3: Product Detection (submodule vs symlink)"
|
|
126
|
+
|
|
127
|
+
# Check for submodule detection (has .git FILE)
|
|
128
|
+
if grep -q "It's a submodule" "$SCRIPT_DIR/session-sync.sh"; then
|
|
129
|
+
pass "Detects submodules correctly (.git as file)"
|
|
130
|
+
else
|
|
131
|
+
fail "Doesn't detect submodules"
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
# Check for symlink detection
|
|
135
|
+
if grep -q "\[ -L \"\$PRODUCT_PATH\" \]" "$SCRIPT_DIR/session-sync.sh"; then
|
|
136
|
+
pass "Detects symlinks correctly"
|
|
137
|
+
else
|
|
138
|
+
fail "Doesn't detect symlinks"
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Check for missing product handling
|
|
142
|
+
if grep -q "Initializing product submodule" "$SCRIPT_DIR/session-sync.sh"; then
|
|
143
|
+
pass "Handles missing product gracefully"
|
|
144
|
+
else
|
|
145
|
+
fail "Doesn't handle missing product"
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
# Check for symlink deprecation warning
|
|
149
|
+
if grep -q "product/ is a symlink, not a submodule" "$SCRIPT_DIR/session-sync.sh"; then
|
|
150
|
+
pass "Warns about legacy symlink usage"
|
|
151
|
+
else
|
|
152
|
+
fail "Doesn't warn about symlinks (legacy pattern)"
|
|
153
|
+
fi
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# ==============================================================================
|
|
157
|
+
# Test 4: Failure Tracking
|
|
158
|
+
# ==============================================================================
|
|
159
|
+
|
|
160
|
+
test_failure_tracking() {
|
|
161
|
+
section "Test 4: Failure Tracking (exit codes)"
|
|
162
|
+
|
|
163
|
+
# Check that failures are tracked
|
|
164
|
+
if grep -q "FAILURES=0" "$SCRIPT_DIR/session-sync.sh"; then
|
|
165
|
+
pass "Initializes failure counter"
|
|
166
|
+
else
|
|
167
|
+
fail "Doesn't track failures"
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Check that failures increment counter
|
|
171
|
+
if grep -q "FAILURES=\$((FAILURES + 1))" "$SCRIPT_DIR/session-sync.sh"; then
|
|
172
|
+
pass "Increments failure counter on errors"
|
|
173
|
+
else
|
|
174
|
+
fail "Doesn't increment failure counter"
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# Check that exit code reflects failures
|
|
178
|
+
if grep -A5 "if.*FAILURES.*-gt 0" "$SCRIPT_DIR/session-sync.sh" | grep -q "exit 1"; then
|
|
179
|
+
pass "Exits with code 1 when failures occur"
|
|
180
|
+
else
|
|
181
|
+
fail "Doesn't exit with error code on failures"
|
|
182
|
+
fi
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# ==============================================================================
|
|
186
|
+
# Test 5: Integration with Current Repo
|
|
187
|
+
# ==============================================================================
|
|
188
|
+
|
|
189
|
+
test_current_repo_integration() {
|
|
190
|
+
section "Test 5: Integration with Current Repo"
|
|
191
|
+
|
|
192
|
+
cd "$REPO_DIR"
|
|
193
|
+
|
|
194
|
+
# Test that script runs without crashing
|
|
195
|
+
if "$SCRIPT_DIR/session-sync.sh" >/dev/null 2>&1; then
|
|
196
|
+
pass "Script runs successfully on current repo"
|
|
197
|
+
else
|
|
198
|
+
exit_code=$?
|
|
199
|
+
if [[ $exit_code -eq 1 ]]; then
|
|
200
|
+
# Check if failure was due to uncommitted changes (safe failure)
|
|
201
|
+
output=$("$SCRIPT_DIR/session-sync.sh" 2>&1 || true)
|
|
202
|
+
if echo "$output" | grep -q "uncommitted changes"; then
|
|
203
|
+
pass "Script correctly fails on uncommitted changes"
|
|
204
|
+
else
|
|
205
|
+
fail "Script failed for unknown reason (exit code 1)"
|
|
206
|
+
fi
|
|
207
|
+
else
|
|
208
|
+
fail "Script crashed with exit code $exit_code"
|
|
209
|
+
fi
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
# Test that it doesn't modify uncommitted changes
|
|
213
|
+
before_status=$(git status --porcelain)
|
|
214
|
+
"$SCRIPT_DIR/session-sync.sh" >/dev/null 2>&1 || true
|
|
215
|
+
after_status=$(git status --porcelain)
|
|
216
|
+
|
|
217
|
+
if [[ "$before_status" == "$after_status" ]]; then
|
|
218
|
+
pass "Doesn't modify uncommitted changes"
|
|
219
|
+
else
|
|
220
|
+
fail "DANGER: Modified uncommitted changes!"
|
|
221
|
+
fi
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# ==============================================================================
|
|
225
|
+
# Test 6: Behind/Ahead Detection
|
|
226
|
+
# ==============================================================================
|
|
227
|
+
|
|
228
|
+
test_behind_ahead_detection() {
|
|
229
|
+
section "Test 6: Behind/Ahead Detection"
|
|
230
|
+
|
|
231
|
+
# Check for behind detection
|
|
232
|
+
if grep -q "commits behind origin" "$SCRIPT_DIR/session-sync.sh"; then
|
|
233
|
+
pass "Detects when repo is behind origin"
|
|
234
|
+
else
|
|
235
|
+
fail "Doesn't detect behind status"
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# Check for ahead detection
|
|
239
|
+
if grep -q "commits ahead" "$SCRIPT_DIR/session-sync.sh"; then
|
|
240
|
+
pass "Detects when repo is ahead (unpushed)"
|
|
241
|
+
else
|
|
242
|
+
fail "Doesn't detect ahead status"
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Check for up-to-date message
|
|
246
|
+
if grep -q "is up to date" "$SCRIPT_DIR/session-sync.sh"; then
|
|
247
|
+
pass "Reports when repo is up to date"
|
|
248
|
+
else
|
|
249
|
+
fail "Doesn't report up-to-date status"
|
|
250
|
+
fi
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# ==============================================================================
|
|
254
|
+
# Test 7: Recursive Submodule Update
|
|
255
|
+
# ==============================================================================
|
|
256
|
+
|
|
257
|
+
test_recursive_submodules() {
|
|
258
|
+
section "Test 7: Recursive Submodule Handling"
|
|
259
|
+
|
|
260
|
+
# Check for recursive submodule update
|
|
261
|
+
if grep -q "submodule update.*--recursive" "$SCRIPT_DIR/session-sync.sh"; then
|
|
262
|
+
pass "Updates submodules recursively"
|
|
263
|
+
else
|
|
264
|
+
fail "Doesn't update nested submodules"
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
# Check for --init flag (initializes new submodules)
|
|
268
|
+
if grep -q "submodule update --init" "$SCRIPT_DIR/session-sync.sh"; then
|
|
269
|
+
pass "Initializes new submodules automatically"
|
|
270
|
+
else
|
|
271
|
+
fail "Doesn't initialize new submodules"
|
|
272
|
+
fi
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
# ==============================================================================
|
|
276
|
+
# Run All Tests
|
|
277
|
+
# ==============================================================================
|
|
278
|
+
|
|
279
|
+
main() {
|
|
280
|
+
echo ""
|
|
281
|
+
echo "╔══════════════════════════════════════════════════════════╗"
|
|
282
|
+
echo "║ session-sync.sh Rigorous Testing ║"
|
|
283
|
+
echo "║ Before Commit Verification ║"
|
|
284
|
+
echo "╚══════════════════════════════════════════════════════════╝"
|
|
285
|
+
|
|
286
|
+
test_safety_checks
|
|
287
|
+
test_detached_head
|
|
288
|
+
test_product_detection
|
|
289
|
+
test_failure_tracking
|
|
290
|
+
test_current_repo_integration
|
|
291
|
+
test_behind_ahead_detection
|
|
292
|
+
test_recursive_submodules
|
|
293
|
+
|
|
294
|
+
# Summary
|
|
295
|
+
echo ""
|
|
296
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
297
|
+
echo -e "${BLUE}Test Results${NC}"
|
|
298
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
299
|
+
echo -e "${GREEN}Passed:${NC} $TESTS_PASSED"
|
|
300
|
+
if [[ $TESTS_FAILED -gt 0 ]]; then
|
|
301
|
+
echo -e "${RED}Failed:${NC} $TESTS_FAILED"
|
|
302
|
+
echo ""
|
|
303
|
+
echo -e "${RED}session-sync.sh NOT READY TO COMMIT${NC}"
|
|
304
|
+
exit 1
|
|
305
|
+
else
|
|
306
|
+
echo ""
|
|
307
|
+
echo -e "${GREEN}✓ session-sync.sh ready to commit${NC}"
|
|
308
|
+
echo ""
|
|
309
|
+
echo "Safety verified:"
|
|
310
|
+
echo " • Won't pull over uncommitted changes"
|
|
311
|
+
echo " • Exits with error on failure"
|
|
312
|
+
echo " • Handles network failures gracefully"
|
|
313
|
+
echo " • No destructive operations"
|
|
314
|
+
echo " • Detached HEAD auto-fix"
|
|
315
|
+
echo " • Recursive submodule updates"
|
|
316
|
+
exit 0
|
|
317
|
+
fi
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
main "$@"
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# where-am-i.sh - Quick context check for git operations
|
|
4
|
+
#
|
|
5
|
+
# Shows:
|
|
6
|
+
# - Current directory
|
|
7
|
+
# - Which repo you're in (GTM or product submodule)
|
|
8
|
+
# - Current branch
|
|
9
|
+
# - Uncommitted changes
|
|
10
|
+
#
|
|
11
|
+
# Usage:
|
|
12
|
+
# ./scripts/where-am-i.sh
|
|
13
|
+
|
|
14
|
+
set -e
|
|
15
|
+
|
|
16
|
+
CWD=$(pwd)
|
|
17
|
+
|
|
18
|
+
# Colors
|
|
19
|
+
BLUE='\033[0;34m'
|
|
20
|
+
GREEN='\033[0;32m'
|
|
21
|
+
YELLOW='\033[1;33m'
|
|
22
|
+
NC='\033[0m'
|
|
23
|
+
|
|
24
|
+
echo ""
|
|
25
|
+
echo -e "${BLUE}📍 Current Location${NC}"
|
|
26
|
+
echo "─────────────────────────────────────"
|
|
27
|
+
echo ""
|
|
28
|
+
|
|
29
|
+
# Show current directory
|
|
30
|
+
echo -e "Directory: ${GREEN}$CWD${NC}"
|
|
31
|
+
|
|
32
|
+
# Detect which repo context (check for submodules first, then GTM)
|
|
33
|
+
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
|
|
34
|
+
|
|
35
|
+
if [[ "$CWD" == *"/product"* ]] || [[ "$REMOTE_URL" == *"jfl-platform"* ]]; then
|
|
36
|
+
echo -e "Context: ${YELLOW}product submodule${NC} (jfl-platform)"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "To commit here: ./scripts/commit-product.sh \"message\""
|
|
39
|
+
elif [[ "$CWD" == *"/runner"* ]] || [[ "$REMOTE_URL" == *"jfl-runner"* ]]; then
|
|
40
|
+
echo -e "Context: ${YELLOW}runner submodule${NC} (jfl-runner)"
|
|
41
|
+
echo ""
|
|
42
|
+
echo "To commit here: cd ../; git add runner && git commit -m \"Update runner submodule\""
|
|
43
|
+
elif [[ "$REMOTE_URL" == *"JFL-GTM"* ]] || [[ -f ".jfl/config.json" ]]; then
|
|
44
|
+
echo -e "Context: ${GREEN}GTM repo${NC} (main project)"
|
|
45
|
+
echo ""
|
|
46
|
+
echo "To commit here: ./scripts/commit-gtm.sh \"message\""
|
|
47
|
+
else
|
|
48
|
+
# Check if we're in any submodule
|
|
49
|
+
if git rev-parse --show-superproject-working-tree &>/dev/null; then
|
|
50
|
+
SUBMODULE_NAME=$(basename "$CWD")
|
|
51
|
+
echo -e "Context: ${YELLOW}${SUBMODULE_NAME} submodule${NC}"
|
|
52
|
+
else
|
|
53
|
+
echo -e "Context: ${YELLOW}unknown${NC}"
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
echo ""
|
|
58
|
+
|
|
59
|
+
# Show current branch
|
|
60
|
+
BRANCH=$(git branch --show-current 2>/dev/null || echo "detached HEAD")
|
|
61
|
+
if [[ "$BRANCH" == "detached HEAD" ]]; then
|
|
62
|
+
echo -e "Branch: ${YELLOW}⚠️ detached HEAD${NC}"
|
|
63
|
+
echo " (run: git checkout main)"
|
|
64
|
+
else
|
|
65
|
+
echo -e "Branch: ${GREEN}$BRANCH${NC}"
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Show uncommitted changes
|
|
69
|
+
CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
70
|
+
if [[ "$CHANGES" -gt 0 ]]; then
|
|
71
|
+
echo -e "Changes: ${YELLOW}$CHANGES uncommitted${NC}"
|
|
72
|
+
echo ""
|
|
73
|
+
git status --short
|
|
74
|
+
else
|
|
75
|
+
echo -e "Changes: ${GREEN}none (clean)${NC}"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo ""
|