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,350 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# session-init.sh - Initialize a JFL session properly
|
|
4
|
+
#
|
|
5
|
+
# Called by SessionStart hook. Does:
|
|
6
|
+
# 1. Quick doctor check (warn only, don't block)
|
|
7
|
+
# 2. Clean up stale sessions if > 5
|
|
8
|
+
# 3. Create new worktree for this session
|
|
9
|
+
# 4. Output path for Claude to cd into
|
|
10
|
+
#
|
|
11
|
+
# @purpose Session initialization with worktree creation
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
REPO_DIR="${JFL_REPO_DIR:-$(pwd)}"
|
|
17
|
+
WORKTREES_DIR="$REPO_DIR/worktrees"
|
|
18
|
+
|
|
19
|
+
cd "$REPO_DIR" || exit 1
|
|
20
|
+
|
|
21
|
+
# Colors
|
|
22
|
+
RED='\033[0;31m'
|
|
23
|
+
GREEN='\033[0;32m'
|
|
24
|
+
YELLOW='\033[1;33m'
|
|
25
|
+
CYAN='\033[0;36m'
|
|
26
|
+
NC='\033[0m'
|
|
27
|
+
|
|
28
|
+
# ==============================================================================
|
|
29
|
+
# Step 0: Sync repos to latest (prevent context loss)
|
|
30
|
+
# ==============================================================================
|
|
31
|
+
|
|
32
|
+
echo ""
|
|
33
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
34
|
+
echo " JFL Session Init"
|
|
35
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
36
|
+
|
|
37
|
+
# Sync repos before creating worktree (ensures worktree is from latest main)
|
|
38
|
+
if [[ -x "$SCRIPT_DIR/session-sync.sh" ]]; then
|
|
39
|
+
echo ""
|
|
40
|
+
"$SCRIPT_DIR/session-sync.sh" || {
|
|
41
|
+
echo -e "${YELLOW}⚠${NC} Session sync failed, continuing with local state"
|
|
42
|
+
}
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# ==============================================================================
|
|
46
|
+
# Step 1: Quick health check (warn only)
|
|
47
|
+
# ==============================================================================
|
|
48
|
+
|
|
49
|
+
# Count stale sessions (no PID or PID not running)
|
|
50
|
+
stale_count=0
|
|
51
|
+
active_count=0
|
|
52
|
+
|
|
53
|
+
if [[ -d "$WORKTREES_DIR" ]]; then
|
|
54
|
+
for worktree in "$WORKTREES_DIR"/session-*; do
|
|
55
|
+
if [[ -d "$worktree" ]]; then
|
|
56
|
+
pid_file="$worktree/.jfl/auto-commit.pid"
|
|
57
|
+
if [[ -f "$pid_file" ]]; then
|
|
58
|
+
pid=$(cat "$pid_file" 2>/dev/null)
|
|
59
|
+
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
60
|
+
active_count=$((active_count + 1))
|
|
61
|
+
continue
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
stale_count=$((stale_count + 1))
|
|
65
|
+
fi
|
|
66
|
+
done
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Report status
|
|
70
|
+
if [[ $stale_count -gt 0 ]]; then
|
|
71
|
+
echo -e "${YELLOW}⚠${NC} $stale_count stale sessions, $active_count active"
|
|
72
|
+
else
|
|
73
|
+
echo -e "${GREEN}✓${NC} $active_count active sessions"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# ==============================================================================
|
|
77
|
+
# Step 2: Auto-cleanup if too many stale sessions
|
|
78
|
+
# ==============================================================================
|
|
79
|
+
|
|
80
|
+
if [[ $stale_count -gt 5 ]]; then
|
|
81
|
+
echo -e "${YELLOW}→${NC} Cleaning up stale sessions (> 5)..."
|
|
82
|
+
"$SCRIPT_DIR/jfl-doctor.sh" --fix 2>/dev/null | grep -E "^ (Cleaning|✓)" || true
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# ==============================================================================
|
|
86
|
+
# Step 2.5: Crash Reconciliation - Check for uncommitted work in stale sessions
|
|
87
|
+
# ==============================================================================
|
|
88
|
+
|
|
89
|
+
if [[ -d "$WORKTREES_DIR" ]]; then
|
|
90
|
+
worktrees_with_changes=""
|
|
91
|
+
change_count=0
|
|
92
|
+
|
|
93
|
+
for worktree in "$WORKTREES_DIR"/session-*; do
|
|
94
|
+
if [[ -d "$worktree" ]]; then
|
|
95
|
+
# Check if worktree has uncommitted changes
|
|
96
|
+
cd "$worktree"
|
|
97
|
+
if [[ -n $(git status --porcelain 2>/dev/null) ]]; then
|
|
98
|
+
session_name=$(basename "$worktree")
|
|
99
|
+
worktrees_with_changes="$worktrees_with_changes $session_name"
|
|
100
|
+
change_count=$((change_count + 1))
|
|
101
|
+
fi
|
|
102
|
+
cd "$REPO_DIR"
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
if [[ $change_count -gt 0 ]]; then
|
|
107
|
+
echo ""
|
|
108
|
+
echo -e "${RED}⚠${NC} Found $change_count session(s) with uncommitted work"
|
|
109
|
+
echo ""
|
|
110
|
+
|
|
111
|
+
for session in $worktrees_with_changes; do
|
|
112
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
113
|
+
cd "$worktree_path"
|
|
114
|
+
files=$(git status --porcelain | wc -l | tr -d ' ')
|
|
115
|
+
echo " • $session ($files files)"
|
|
116
|
+
cd "$REPO_DIR"
|
|
117
|
+
done
|
|
118
|
+
|
|
119
|
+
echo ""
|
|
120
|
+
echo -e "${YELLOW}This work needs to be saved before continuing.${NC}"
|
|
121
|
+
echo ""
|
|
122
|
+
|
|
123
|
+
# Check if running non-interactively (hook context)
|
|
124
|
+
if [[ ! -t 0 ]]; then
|
|
125
|
+
# Non-interactive - auto-commit (safest)
|
|
126
|
+
echo "Running non-interactively - auto-committing all changes..."
|
|
127
|
+
choice="1"
|
|
128
|
+
else
|
|
129
|
+
# Interactive - ask user
|
|
130
|
+
echo "Options:"
|
|
131
|
+
echo " 1) Auto-commit all and continue (safest - no work lost)"
|
|
132
|
+
echo " 2) Show me the changes (for review)"
|
|
133
|
+
echo " 3) Skip for now (manual cleanup)"
|
|
134
|
+
echo ""
|
|
135
|
+
read -p "Choose [1-3]: " choice
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
case "$choice" in
|
|
139
|
+
1)
|
|
140
|
+
echo ""
|
|
141
|
+
echo -e "${CYAN}→${NC} Auto-committing all changes..."
|
|
142
|
+
for session in $worktrees_with_changes; do
|
|
143
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
144
|
+
cd "$worktree_path"
|
|
145
|
+
|
|
146
|
+
if [[ -n $(git status --porcelain 2>/dev/null) ]]; then
|
|
147
|
+
# Critical paths
|
|
148
|
+
git add knowledge/ previews/ content/ suggestions/ CLAUDE.md .jfl/ 2>/dev/null || true
|
|
149
|
+
|
|
150
|
+
if git commit -m "crash recovery: auto-save uncommitted work from $session" 2>/dev/null; then
|
|
151
|
+
echo -e " ${GREEN}✓${NC} $session - committed and saved"
|
|
152
|
+
git push origin "$(git branch --show-current)" 2>/dev/null || true
|
|
153
|
+
fi
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
cd "$REPO_DIR"
|
|
157
|
+
done
|
|
158
|
+
echo ""
|
|
159
|
+
echo -e "${GREEN}✓${NC} All changes saved. Continuing..."
|
|
160
|
+
;;
|
|
161
|
+
2)
|
|
162
|
+
echo ""
|
|
163
|
+
for session in $worktrees_with_changes; do
|
|
164
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
165
|
+
echo "─────────────────────────────────────"
|
|
166
|
+
echo "$session:"
|
|
167
|
+
echo ""
|
|
168
|
+
cd "$worktree_path"
|
|
169
|
+
git status --short
|
|
170
|
+
cd "$REPO_DIR"
|
|
171
|
+
echo ""
|
|
172
|
+
done
|
|
173
|
+
echo "─────────────────────────────────────"
|
|
174
|
+
echo ""
|
|
175
|
+
read -p "Commit these changes? [y/N]: " commit_choice
|
|
176
|
+
if [[ "$commit_choice" =~ ^[Yy]$ ]]; then
|
|
177
|
+
for session in $worktrees_with_changes; do
|
|
178
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
179
|
+
cd "$worktree_path"
|
|
180
|
+
git add knowledge/ previews/ content/ suggestions/ CLAUDE.md .jfl/ 2>/dev/null || true
|
|
181
|
+
git commit -m "crash recovery: manual save from $session" 2>/dev/null || true
|
|
182
|
+
git push origin "$(git branch --show-current)" 2>/dev/null || true
|
|
183
|
+
cd "$REPO_DIR"
|
|
184
|
+
done
|
|
185
|
+
echo -e "${GREEN}✓${NC} Changes committed"
|
|
186
|
+
fi
|
|
187
|
+
;;
|
|
188
|
+
3)
|
|
189
|
+
echo ""
|
|
190
|
+
echo -e "${YELLOW}Skipping crash recovery.${NC}"
|
|
191
|
+
echo "You can manually handle these sessions later."
|
|
192
|
+
echo ""
|
|
193
|
+
;;
|
|
194
|
+
*)
|
|
195
|
+
echo ""
|
|
196
|
+
echo -e "${RED}Invalid choice. Skipping.${NC}"
|
|
197
|
+
;;
|
|
198
|
+
esac
|
|
199
|
+
fi
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# ==============================================================================
|
|
203
|
+
# Step 2.9: Check for concurrent sessions via jfl-services
|
|
204
|
+
# ==============================================================================
|
|
205
|
+
|
|
206
|
+
# Generate session details first
|
|
207
|
+
user=$(git config user.name 2>/dev/null | tr ' ' '-' | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-' || echo "user")
|
|
208
|
+
user="${user:0:30}"
|
|
209
|
+
date_str=$(date +%Y%m%d)
|
|
210
|
+
time_str=$(date +%H%M)
|
|
211
|
+
random_id=$(openssl rand -hex 3 2>/dev/null || printf "%06x" $RANDOM$RANDOM)
|
|
212
|
+
session_name="session-${user}-${date_str}-${time_str}-${random_id}"
|
|
213
|
+
|
|
214
|
+
# Get working branch (from config or current branch)
|
|
215
|
+
working_branch=$(jq -r '.working_branch // empty' .jfl/config.json 2>/dev/null)
|
|
216
|
+
if [[ -z "$working_branch" ]]; then
|
|
217
|
+
working_branch=$(git branch --show-current)
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Check for concurrent sessions via jfl-services API
|
|
221
|
+
use_worktree=false
|
|
222
|
+
api_response=""
|
|
223
|
+
if command -v curl >/dev/null 2>&1; then
|
|
224
|
+
api_response=$(curl -s -X GET "http://localhost:3401/sessions/active?projectPath=$(pwd)" 2>/dev/null || echo "")
|
|
225
|
+
|
|
226
|
+
if [[ -n "$api_response" ]] && echo "$api_response" | jq -e '.count' >/dev/null 2>&1; then
|
|
227
|
+
session_count=$(echo "$api_response" | jq -r '.count // 0')
|
|
228
|
+
|
|
229
|
+
if [[ $session_count -gt 0 ]]; then
|
|
230
|
+
use_worktree=true
|
|
231
|
+
echo -e "${YELLOW}→${NC} Multiple sessions detected ($session_count active) - using worktree for isolation"
|
|
232
|
+
else
|
|
233
|
+
echo -e "${GREEN}→${NC} Single session - working directly on branch $working_branch"
|
|
234
|
+
fi
|
|
235
|
+
else
|
|
236
|
+
# API unavailable - fall back to local detection
|
|
237
|
+
echo -e "${YELLOW}→${NC} jfl-services unavailable - checking locally..."
|
|
238
|
+
local_sessions=$(ps aux | grep -c "claude.*$(pwd)" 2>/dev/null || echo "1")
|
|
239
|
+
if [[ $local_sessions -gt 2 ]]; then
|
|
240
|
+
use_worktree=true
|
|
241
|
+
echo -e "${YELLOW}→${NC} Multiple processes detected - using worktree for isolation"
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
else
|
|
245
|
+
# No curl - assume single session
|
|
246
|
+
echo -e "${GREEN}→${NC} Working directly on branch $working_branch"
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
# Register this session with jfl-services
|
|
250
|
+
if command -v curl >/dev/null 2>&1; then
|
|
251
|
+
curl -s -X POST "http://localhost:3401/sessions/start" \
|
|
252
|
+
-H "Content-Type: application/json" \
|
|
253
|
+
-d "{\"id\":\"$session_name\",\"projectPath\":\"$(pwd)\",\"branch\":\"$working_branch\",\"user\":\"$user\",\"pid\":$$,\"worktree\":\"$use_worktree\"}" \
|
|
254
|
+
>/dev/null 2>&1 || true
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
# ==============================================================================
|
|
258
|
+
# Step 3: Create worktree (if needed) or work directly
|
|
259
|
+
# ==============================================================================
|
|
260
|
+
|
|
261
|
+
if [[ "$use_worktree" == "true" ]]; then
|
|
262
|
+
# WORKTREE MODE: Multiple sessions detected
|
|
263
|
+
echo ""
|
|
264
|
+
echo "Creating worktree session: $session_name"
|
|
265
|
+
|
|
266
|
+
worktree_path="$WORKTREES_DIR/$session_name"
|
|
267
|
+
|
|
268
|
+
# Create worktree
|
|
269
|
+
if git worktree add "$worktree_path" -b "$session_name" 2>&1 | head -3; then
|
|
270
|
+
echo -e "${GREEN}✓${NC} Worktree created"
|
|
271
|
+
else
|
|
272
|
+
echo -e "${RED}✗${NC} Failed to create worktree"
|
|
273
|
+
# Fall back to direct branch mode
|
|
274
|
+
use_worktree=false
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
if [[ "$use_worktree" == "true" ]]; then
|
|
278
|
+
# Initialize submodules in worktree (quick, no network)
|
|
279
|
+
cd "$worktree_path"
|
|
280
|
+
if [[ -f ".gitmodules" ]]; then
|
|
281
|
+
if [[ ! -d "product/.git" ]] && [[ ! -f "product/.git" ]]; then
|
|
282
|
+
echo "→ Initializing submodules..."
|
|
283
|
+
git submodule update --init --depth 1 product 2>/dev/null || true
|
|
284
|
+
fi
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
# Create session directories
|
|
288
|
+
mkdir -p .jfl/logs
|
|
289
|
+
|
|
290
|
+
# CRITICAL: Symlink journal to main repo so entries persist after worktree cleanup
|
|
291
|
+
rm -rf .jfl/journal 2>/dev/null || true
|
|
292
|
+
ln -sf "$REPO_DIR/.jfl/journal" .jfl/journal
|
|
293
|
+
echo -e "${GREEN}✓${NC} Journal symlinked to main repo"
|
|
294
|
+
|
|
295
|
+
# Start auto-commit in background
|
|
296
|
+
if [[ -x "$SCRIPT_DIR/auto-commit.sh" ]]; then
|
|
297
|
+
"$SCRIPT_DIR/auto-commit.sh" start >> .jfl/logs/auto-commit.log 2>&1 &
|
|
298
|
+
echo -e "${GREEN}✓${NC} Auto-commit started"
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
cd "$REPO_DIR"
|
|
302
|
+
|
|
303
|
+
# Save paths
|
|
304
|
+
echo "$worktree_path" > "$REPO_DIR/.jfl/current-worktree.txt"
|
|
305
|
+
echo "$session_name" > "$REPO_DIR/.jfl/current-session-branch.txt"
|
|
306
|
+
echo "$session_name" > "$worktree_path/.jfl/current-session-branch.txt"
|
|
307
|
+
|
|
308
|
+
echo ""
|
|
309
|
+
echo -e "${GREEN}✓${NC} Session ready in worktree: $worktree_path"
|
|
310
|
+
echo ""
|
|
311
|
+
fi
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
if [[ "$use_worktree" != "true" ]]; then
|
|
315
|
+
# DIRECT MODE: Single session, work on current branch
|
|
316
|
+
echo ""
|
|
317
|
+
echo "Direct session mode: $session_name"
|
|
318
|
+
|
|
319
|
+
# Ensure we're on working branch
|
|
320
|
+
current_branch=$(git branch --show-current)
|
|
321
|
+
if [[ "$current_branch" != "$working_branch" ]]; then
|
|
322
|
+
echo "→ Switching to working branch: $working_branch"
|
|
323
|
+
git checkout "$working_branch" 2>&1 | head -3
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
# Create session branch from working branch
|
|
327
|
+
if git checkout -b "$session_name" 2>&1 | head -3; then
|
|
328
|
+
echo -e "${GREEN}✓${NC} Session branch created: $session_name"
|
|
329
|
+
else
|
|
330
|
+
echo -e "${YELLOW}⚠${NC} Continuing on branch: $current_branch"
|
|
331
|
+
session_name="$current_branch"
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# Create session directories
|
|
335
|
+
mkdir -p .jfl/logs
|
|
336
|
+
|
|
337
|
+
# Start auto-commit in background
|
|
338
|
+
if [[ -x "$SCRIPT_DIR/auto-commit.sh" ]]; then
|
|
339
|
+
"$SCRIPT_DIR/auto-commit.sh" start >> .jfl/logs/auto-commit.log 2>&1 &
|
|
340
|
+
echo -e "${GREEN}✓${NC} Auto-commit started"
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
# Save session info (no worktree path in direct mode)
|
|
344
|
+
echo "direct" > "$REPO_DIR/.jfl/current-worktree.txt"
|
|
345
|
+
echo "$session_name" > "$REPO_DIR/.jfl/current-session-branch.txt"
|
|
346
|
+
|
|
347
|
+
echo ""
|
|
348
|
+
echo -e "${GREEN}✓${NC} Session ready on branch: $session_name"
|
|
349
|
+
echo ""
|
|
350
|
+
fi
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# session-init.sh - Initialize a JFL session properly
|
|
4
|
+
#
|
|
5
|
+
# Called by SessionStart hook. Does:
|
|
6
|
+
# 1. Quick doctor check (warn only, don't block)
|
|
7
|
+
# 2. Clean up stale sessions if > 5
|
|
8
|
+
# 3. Create new worktree for this session
|
|
9
|
+
# 4. Output path for Claude to cd into
|
|
10
|
+
#
|
|
11
|
+
# @purpose Session initialization with worktree creation
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
REPO_DIR="${JFL_REPO_DIR:-$(pwd)}"
|
|
17
|
+
WORKTREES_DIR="$REPO_DIR/worktrees"
|
|
18
|
+
|
|
19
|
+
cd "$REPO_DIR" || exit 1
|
|
20
|
+
|
|
21
|
+
# Colors
|
|
22
|
+
RED='\033[0;31m'
|
|
23
|
+
GREEN='\033[0;32m'
|
|
24
|
+
YELLOW='\033[1;33m'
|
|
25
|
+
CYAN='\033[0;36m'
|
|
26
|
+
NC='\033[0m'
|
|
27
|
+
|
|
28
|
+
# ==============================================================================
|
|
29
|
+
# Step 0: Sync repos to latest (prevent context loss)
|
|
30
|
+
# ==============================================================================
|
|
31
|
+
|
|
32
|
+
echo ""
|
|
33
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
34
|
+
echo " JFL Session Init"
|
|
35
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
36
|
+
|
|
37
|
+
# Sync repos before creating worktree (ensures worktree is from latest main)
|
|
38
|
+
if [[ -x "$SCRIPT_DIR/session-sync.sh" ]]; then
|
|
39
|
+
echo ""
|
|
40
|
+
"$SCRIPT_DIR/session-sync.sh" || {
|
|
41
|
+
echo -e "${YELLOW}⚠${NC} Session sync failed, continuing with local state"
|
|
42
|
+
}
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# ==============================================================================
|
|
46
|
+
# Step 1: Quick health check (warn only)
|
|
47
|
+
# ==============================================================================
|
|
48
|
+
|
|
49
|
+
# Count stale sessions (no PID or PID not running)
|
|
50
|
+
stale_count=0
|
|
51
|
+
active_count=0
|
|
52
|
+
|
|
53
|
+
if [[ -d "$WORKTREES_DIR" ]]; then
|
|
54
|
+
for worktree in "$WORKTREES_DIR"/session-*; do
|
|
55
|
+
if [[ -d "$worktree" ]]; then
|
|
56
|
+
pid_file="$worktree/.jfl/auto-commit.pid"
|
|
57
|
+
if [[ -f "$pid_file" ]]; then
|
|
58
|
+
pid=$(cat "$pid_file" 2>/dev/null)
|
|
59
|
+
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
60
|
+
active_count=$((active_count + 1))
|
|
61
|
+
continue
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
stale_count=$((stale_count + 1))
|
|
65
|
+
fi
|
|
66
|
+
done
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Report status
|
|
70
|
+
if [[ $stale_count -gt 0 ]]; then
|
|
71
|
+
echo -e "${YELLOW}⚠${NC} $stale_count stale sessions, $active_count active"
|
|
72
|
+
else
|
|
73
|
+
echo -e "${GREEN}✓${NC} $active_count active sessions"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# ==============================================================================
|
|
77
|
+
# Step 2: Auto-cleanup if too many stale sessions
|
|
78
|
+
# ==============================================================================
|
|
79
|
+
|
|
80
|
+
if [[ $stale_count -gt 5 ]]; then
|
|
81
|
+
echo -e "${YELLOW}→${NC} Cleaning up stale sessions (> 5)..."
|
|
82
|
+
"$SCRIPT_DIR/jfl-doctor.sh" --fix 2>/dev/null | grep -E "^ (Cleaning|✓)" || true
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# ==============================================================================
|
|
86
|
+
# Step 2.5: Crash Reconciliation - Check for uncommitted work in stale sessions
|
|
87
|
+
# ==============================================================================
|
|
88
|
+
|
|
89
|
+
if [[ -d "$WORKTREES_DIR" ]]; then
|
|
90
|
+
worktrees_with_changes=""
|
|
91
|
+
change_count=0
|
|
92
|
+
|
|
93
|
+
for worktree in "$WORKTREES_DIR"/session-*; do
|
|
94
|
+
if [[ -d "$worktree" ]]; then
|
|
95
|
+
# Check if worktree has uncommitted changes
|
|
96
|
+
cd "$worktree"
|
|
97
|
+
if [[ -n $(git status --porcelain 2>/dev/null) ]]; then
|
|
98
|
+
session_name=$(basename "$worktree")
|
|
99
|
+
worktrees_with_changes="$worktrees_with_changes $session_name"
|
|
100
|
+
change_count=$((change_count + 1))
|
|
101
|
+
fi
|
|
102
|
+
cd "$REPO_DIR"
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
if [[ $change_count -gt 0 ]]; then
|
|
107
|
+
echo ""
|
|
108
|
+
echo -e "${RED}⚠${NC} Found $change_count session(s) with uncommitted work"
|
|
109
|
+
echo ""
|
|
110
|
+
|
|
111
|
+
for session in $worktrees_with_changes; do
|
|
112
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
113
|
+
cd "$worktree_path"
|
|
114
|
+
files=$(git status --porcelain | wc -l | tr -d ' ')
|
|
115
|
+
echo " • $session ($files files)"
|
|
116
|
+
cd "$REPO_DIR"
|
|
117
|
+
done
|
|
118
|
+
|
|
119
|
+
echo ""
|
|
120
|
+
echo -e "${YELLOW}This work needs to be saved before continuing.${NC}"
|
|
121
|
+
echo ""
|
|
122
|
+
|
|
123
|
+
# Check if running non-interactively (hook context)
|
|
124
|
+
if [[ ! -t 0 ]]; then
|
|
125
|
+
# Non-interactive - auto-commit (safest)
|
|
126
|
+
echo "Running non-interactively - auto-committing all changes..."
|
|
127
|
+
choice="1"
|
|
128
|
+
else
|
|
129
|
+
# Interactive - ask user
|
|
130
|
+
echo "Options:"
|
|
131
|
+
echo " 1) Auto-commit all and continue (safest - no work lost)"
|
|
132
|
+
echo " 2) Show me the changes (for review)"
|
|
133
|
+
echo " 3) Skip for now (manual cleanup)"
|
|
134
|
+
echo ""
|
|
135
|
+
read -p "Choose [1-3]: " choice
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
case "$choice" in
|
|
139
|
+
1)
|
|
140
|
+
echo ""
|
|
141
|
+
echo -e "${CYAN}→${NC} Auto-committing all changes..."
|
|
142
|
+
for session in $worktrees_with_changes; do
|
|
143
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
144
|
+
cd "$worktree_path"
|
|
145
|
+
|
|
146
|
+
if [[ -n $(git status --porcelain 2>/dev/null) ]]; then
|
|
147
|
+
# Critical paths
|
|
148
|
+
git add knowledge/ previews/ content/ suggestions/ CLAUDE.md .jfl/ 2>/dev/null || true
|
|
149
|
+
|
|
150
|
+
if git commit -m "crash recovery: auto-save uncommitted work from $session" 2>/dev/null; then
|
|
151
|
+
echo -e " ${GREEN}✓${NC} $session - committed and saved"
|
|
152
|
+
git push origin "$(git branch --show-current)" 2>/dev/null || true
|
|
153
|
+
fi
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
cd "$REPO_DIR"
|
|
157
|
+
done
|
|
158
|
+
echo ""
|
|
159
|
+
echo -e "${GREEN}✓${NC} All changes saved. Continuing..."
|
|
160
|
+
;;
|
|
161
|
+
2)
|
|
162
|
+
echo ""
|
|
163
|
+
for session in $worktrees_with_changes; do
|
|
164
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
165
|
+
echo "─────────────────────────────────────"
|
|
166
|
+
echo "$session:"
|
|
167
|
+
echo ""
|
|
168
|
+
cd "$worktree_path"
|
|
169
|
+
git status --short
|
|
170
|
+
cd "$REPO_DIR"
|
|
171
|
+
echo ""
|
|
172
|
+
done
|
|
173
|
+
echo "─────────────────────────────────────"
|
|
174
|
+
echo ""
|
|
175
|
+
read -p "Commit these changes? [y/N]: " commit_choice
|
|
176
|
+
if [[ "$commit_choice" =~ ^[Yy]$ ]]; then
|
|
177
|
+
for session in $worktrees_with_changes; do
|
|
178
|
+
worktree_path="$WORKTREES_DIR/$session"
|
|
179
|
+
cd "$worktree_path"
|
|
180
|
+
git add knowledge/ previews/ content/ suggestions/ CLAUDE.md .jfl/ 2>/dev/null || true
|
|
181
|
+
git commit -m "crash recovery: manual save from $session" 2>/dev/null || true
|
|
182
|
+
git push origin "$(git branch --show-current)" 2>/dev/null || true
|
|
183
|
+
cd "$REPO_DIR"
|
|
184
|
+
done
|
|
185
|
+
echo -e "${GREEN}✓${NC} Changes committed"
|
|
186
|
+
fi
|
|
187
|
+
;;
|
|
188
|
+
3)
|
|
189
|
+
echo ""
|
|
190
|
+
echo -e "${YELLOW}Skipping crash recovery.${NC}"
|
|
191
|
+
echo "You can manually handle these sessions later."
|
|
192
|
+
echo ""
|
|
193
|
+
;;
|
|
194
|
+
*)
|
|
195
|
+
echo ""
|
|
196
|
+
echo -e "${RED}Invalid choice. Skipping.${NC}"
|
|
197
|
+
;;
|
|
198
|
+
esac
|
|
199
|
+
fi
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# ==============================================================================
|
|
203
|
+
# Step 3: Create new worktree
|
|
204
|
+
# ==============================================================================
|
|
205
|
+
|
|
206
|
+
# Generate session name with collision protection
|
|
207
|
+
user=$(git config user.name 2>/dev/null | tr ' ' '-' | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-' || echo "user")
|
|
208
|
+
# Truncate long usernames to prevent path issues
|
|
209
|
+
user="${user:0:30}"
|
|
210
|
+
date_str=$(date +%Y%m%d)
|
|
211
|
+
time_str=$(date +%H%M)
|
|
212
|
+
|
|
213
|
+
# Generate unique session name, retry if collision detected
|
|
214
|
+
max_attempts=5
|
|
215
|
+
attempt=0
|
|
216
|
+
while [[ $attempt -lt $max_attempts ]]; do
|
|
217
|
+
random_id=$(openssl rand -hex 3 2>/dev/null || printf "%06x" $RANDOM$RANDOM)
|
|
218
|
+
session_name="session-${user}-${date_str}-${time_str}-${random_id}"
|
|
219
|
+
|
|
220
|
+
# Check for collision: journal file or worktree already exists
|
|
221
|
+
if [[ -f "$REPO_DIR/.jfl/journal/${session_name}.jsonl" ]] || [[ -d "$WORKTREES_DIR/$session_name" ]]; then
|
|
222
|
+
echo -e "${YELLOW}⚠${NC} Session name collision, regenerating..."
|
|
223
|
+
attempt=$((attempt + 1))
|
|
224
|
+
sleep 0.1 # Brief pause before retry
|
|
225
|
+
else
|
|
226
|
+
break
|
|
227
|
+
fi
|
|
228
|
+
done
|
|
229
|
+
|
|
230
|
+
if [[ $attempt -ge $max_attempts ]]; then
|
|
231
|
+
echo -e "${RED}✗${NC} Failed to generate unique session name after $max_attempts attempts"
|
|
232
|
+
exit 1
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
worktree_path="$WORKTREES_DIR/$session_name"
|
|
236
|
+
|
|
237
|
+
echo ""
|
|
238
|
+
echo "Creating session: $session_name"
|
|
239
|
+
|
|
240
|
+
# Create worktree
|
|
241
|
+
if git worktree add "$worktree_path" -b "$session_name" 2>&1 | head -3; then
|
|
242
|
+
echo -e "${GREEN}✓${NC} Worktree created"
|
|
243
|
+
else
|
|
244
|
+
echo -e "${RED}✗${NC} Failed to create worktree"
|
|
245
|
+
# Fall back to main branch
|
|
246
|
+
echo "main" > "$REPO_DIR/.jfl/current-worktree.txt"
|
|
247
|
+
echo "main" > "$REPO_DIR/.jfl/current-session-branch.txt"
|
|
248
|
+
exit 0
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# Initialize submodules in worktree (quick, no network)
|
|
252
|
+
cd "$worktree_path"
|
|
253
|
+
if [[ -f ".gitmodules" ]]; then
|
|
254
|
+
if [[ ! -d "product/.git" ]] && [[ ! -f "product/.git" ]]; then
|
|
255
|
+
echo "→ Initializing submodules..."
|
|
256
|
+
git submodule update --init --depth 1 product 2>/dev/null || true
|
|
257
|
+
fi
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
# Create session directories
|
|
261
|
+
mkdir -p .jfl/logs
|
|
262
|
+
|
|
263
|
+
# CRITICAL: Symlink journal to main repo so entries persist after worktree cleanup
|
|
264
|
+
# Without this, journal entries written in worktree are lost when worktree is removed!
|
|
265
|
+
rm -rf .jfl/journal 2>/dev/null || true
|
|
266
|
+
ln -sf "$REPO_DIR/.jfl/journal" .jfl/journal
|
|
267
|
+
echo -e "${GREEN}✓${NC} Journal symlinked to main repo"
|
|
268
|
+
|
|
269
|
+
# Start auto-commit in background
|
|
270
|
+
if [[ -x "$SCRIPT_DIR/auto-commit.sh" ]]; then
|
|
271
|
+
"$SCRIPT_DIR/auto-commit.sh" start >> .jfl/logs/auto-commit.log 2>&1 &
|
|
272
|
+
echo -e "${GREEN}✓${NC} Auto-commit started"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
cd "$REPO_DIR"
|
|
276
|
+
|
|
277
|
+
# ==============================================================================
|
|
278
|
+
# Step 4: Save state and output instructions
|
|
279
|
+
# ==============================================================================
|
|
280
|
+
|
|
281
|
+
# Save paths
|
|
282
|
+
echo "$worktree_path" > "$REPO_DIR/.jfl/current-worktree.txt"
|
|
283
|
+
echo "$session_name" > "$REPO_DIR/.jfl/current-session-branch.txt"
|
|
284
|
+
|
|
285
|
+
# Also save in worktree
|
|
286
|
+
echo "$session_name" > "$worktree_path/.jfl/current-session-branch.txt"
|
|
287
|
+
|
|
288
|
+
echo ""
|
|
289
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
290
|
+
echo -e " ${CYAN}CLAUDE: You MUST run:${NC} cd $worktree_path"
|
|
291
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
292
|
+
echo ""
|