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.
Files changed (262) hide show
  1. package/README.md +443 -145
  2. package/clawdbot-plugin/clawdbot.plugin.json +20 -0
  3. package/clawdbot-plugin/index.js +555 -0
  4. package/clawdbot-plugin/index.ts +582 -0
  5. package/clawdbot-skill/SKILL.md +33 -336
  6. package/clawdbot-skill/index.ts +491 -321
  7. package/clawdbot-skill/skill.json +4 -13
  8. package/dist/commands/clawdbot.d.ts +11 -0
  9. package/dist/commands/clawdbot.d.ts.map +1 -0
  10. package/dist/commands/clawdbot.js +215 -0
  11. package/dist/commands/clawdbot.js.map +1 -0
  12. package/dist/commands/context-hub.d.ts +5 -0
  13. package/dist/commands/context-hub.d.ts.map +1 -1
  14. package/dist/commands/context-hub.js +394 -28
  15. package/dist/commands/context-hub.js.map +1 -1
  16. package/dist/commands/gtm-process-update.d.ts +10 -0
  17. package/dist/commands/gtm-process-update.d.ts.map +1 -0
  18. package/dist/commands/gtm-process-update.js +101 -0
  19. package/dist/commands/gtm-process-update.js.map +1 -0
  20. package/dist/commands/init.d.ts.map +1 -1
  21. package/dist/commands/init.js +278 -4
  22. package/dist/commands/init.js.map +1 -1
  23. package/dist/commands/login.d.ts.map +1 -1
  24. package/dist/commands/login.js +32 -33
  25. package/dist/commands/login.js.map +1 -1
  26. package/dist/commands/memory.d.ts +38 -0
  27. package/dist/commands/memory.d.ts.map +1 -0
  28. package/dist/commands/memory.js +229 -0
  29. package/dist/commands/memory.js.map +1 -0
  30. package/dist/commands/migrate-services.d.ts +8 -0
  31. package/dist/commands/migrate-services.d.ts.map +1 -0
  32. package/dist/commands/migrate-services.js +182 -0
  33. package/dist/commands/migrate-services.js.map +1 -0
  34. package/dist/commands/onboard.d.ts +24 -0
  35. package/dist/commands/onboard.d.ts.map +1 -0
  36. package/dist/commands/onboard.js +663 -0
  37. package/dist/commands/onboard.js.map +1 -0
  38. package/dist/commands/openclaw.d.ts +56 -0
  39. package/dist/commands/openclaw.d.ts.map +1 -0
  40. package/dist/commands/openclaw.js +700 -0
  41. package/dist/commands/openclaw.js.map +1 -0
  42. package/dist/commands/orchestrate.d.ts +14 -0
  43. package/dist/commands/orchestrate.d.ts.map +1 -0
  44. package/dist/commands/orchestrate.js +270 -0
  45. package/dist/commands/orchestrate.js.map +1 -0
  46. package/dist/commands/profile.d.ts +46 -0
  47. package/dist/commands/profile.d.ts.map +1 -0
  48. package/dist/commands/profile.js +498 -0
  49. package/dist/commands/profile.js.map +1 -0
  50. package/dist/commands/repair.d.ts.map +1 -1
  51. package/dist/commands/repair.js +37 -0
  52. package/dist/commands/repair.js.map +1 -1
  53. package/dist/commands/service-agent.d.ts +16 -0
  54. package/dist/commands/service-agent.d.ts.map +1 -0
  55. package/dist/commands/service-agent.js +375 -0
  56. package/dist/commands/service-agent.js.map +1 -0
  57. package/dist/commands/service-manager.d.ts +12 -0
  58. package/dist/commands/service-manager.d.ts.map +1 -0
  59. package/dist/commands/service-manager.js +967 -0
  60. package/dist/commands/service-manager.js.map +1 -0
  61. package/dist/commands/service-validate.d.ts +12 -0
  62. package/dist/commands/service-validate.d.ts.map +1 -0
  63. package/dist/commands/service-validate.js +611 -0
  64. package/dist/commands/service-validate.js.map +1 -0
  65. package/dist/commands/services-create.d.ts +15 -0
  66. package/dist/commands/services-create.d.ts.map +1 -0
  67. package/dist/commands/services-create.js +1452 -0
  68. package/dist/commands/services-create.js.map +1 -0
  69. package/dist/commands/services-scan.d.ts +13 -0
  70. package/dist/commands/services-scan.d.ts.map +1 -0
  71. package/dist/commands/services-scan.js +251 -0
  72. package/dist/commands/services-scan.js.map +1 -0
  73. package/dist/commands/services-sync-agents.d.ts +23 -0
  74. package/dist/commands/services-sync-agents.d.ts.map +1 -0
  75. package/dist/commands/services-sync-agents.js +207 -0
  76. package/dist/commands/services-sync-agents.js.map +1 -0
  77. package/dist/commands/services.d.ts +19 -0
  78. package/dist/commands/services.d.ts.map +1 -0
  79. package/dist/commands/services.js +742 -0
  80. package/dist/commands/services.js.map +1 -0
  81. package/dist/commands/session.d.ts +5 -1
  82. package/dist/commands/session.d.ts.map +1 -1
  83. package/dist/commands/session.js +68 -586
  84. package/dist/commands/session.js.map +1 -1
  85. package/dist/commands/status.d.ts.map +1 -1
  86. package/dist/commands/status.js +17 -0
  87. package/dist/commands/status.js.map +1 -1
  88. package/dist/commands/update.d.ts.map +1 -1
  89. package/dist/commands/update.js +75 -21
  90. package/dist/commands/update.js.map +1 -1
  91. package/dist/commands/validate-settings.d.ts +37 -0
  92. package/dist/commands/validate-settings.d.ts.map +1 -0
  93. package/dist/commands/validate-settings.js +197 -0
  94. package/dist/commands/validate-settings.js.map +1 -0
  95. package/dist/commands/voice.d.ts +0 -1
  96. package/dist/commands/voice.d.ts.map +1 -1
  97. package/dist/commands/voice.js +16 -15
  98. package/dist/commands/voice.js.map +1 -1
  99. package/dist/index.js +395 -141
  100. package/dist/index.js.map +1 -1
  101. package/dist/lib/agent-generator.d.ts +26 -0
  102. package/dist/lib/agent-generator.d.ts.map +1 -0
  103. package/dist/lib/agent-generator.js +331 -0
  104. package/dist/lib/agent-generator.js.map +1 -0
  105. package/dist/lib/memory-db.d.ts +102 -0
  106. package/dist/lib/memory-db.d.ts.map +1 -0
  107. package/dist/lib/memory-db.js +313 -0
  108. package/dist/lib/memory-db.js.map +1 -0
  109. package/dist/lib/memory-indexer.d.ts +47 -0
  110. package/dist/lib/memory-indexer.d.ts.map +1 -0
  111. package/dist/lib/memory-indexer.js +215 -0
  112. package/dist/lib/memory-indexer.js.map +1 -0
  113. package/dist/lib/memory-search.d.ts +41 -0
  114. package/dist/lib/memory-search.d.ts.map +1 -0
  115. package/dist/lib/memory-search.js +246 -0
  116. package/dist/lib/memory-search.js.map +1 -0
  117. package/dist/lib/openclaw-registry.d.ts +48 -0
  118. package/dist/lib/openclaw-registry.d.ts.map +1 -0
  119. package/dist/lib/openclaw-registry.js +181 -0
  120. package/dist/lib/openclaw-registry.js.map +1 -0
  121. package/dist/lib/openclaw-sdk.d.ts +107 -0
  122. package/dist/lib/openclaw-sdk.d.ts.map +1 -0
  123. package/dist/lib/openclaw-sdk.js +208 -0
  124. package/dist/lib/openclaw-sdk.js.map +1 -0
  125. package/dist/lib/peer-agent-generator.d.ts +44 -0
  126. package/dist/lib/peer-agent-generator.d.ts.map +1 -0
  127. package/dist/lib/peer-agent-generator.js +286 -0
  128. package/dist/lib/peer-agent-generator.js.map +1 -0
  129. package/dist/lib/service-dependencies.d.ts +44 -0
  130. package/dist/lib/service-dependencies.d.ts.map +1 -0
  131. package/dist/lib/service-dependencies.js +314 -0
  132. package/dist/lib/service-dependencies.js.map +1 -0
  133. package/dist/lib/service-detector.d.ts +61 -0
  134. package/dist/lib/service-detector.d.ts.map +1 -0
  135. package/dist/lib/service-detector.js +521 -0
  136. package/dist/lib/service-detector.js.map +1 -0
  137. package/dist/lib/service-gtm.d.ts +157 -0
  138. package/dist/lib/service-gtm.d.ts.map +1 -0
  139. package/dist/lib/service-gtm.js +786 -0
  140. package/dist/lib/service-gtm.js.map +1 -0
  141. package/dist/lib/service-mcp-base.d.ts +103 -0
  142. package/dist/lib/service-mcp-base.d.ts.map +1 -0
  143. package/dist/lib/service-mcp-base.js +263 -0
  144. package/dist/lib/service-mcp-base.js.map +1 -0
  145. package/dist/lib/service-utils.d.ts +103 -0
  146. package/dist/lib/service-utils.d.ts.map +1 -0
  147. package/dist/lib/service-utils.js +368 -0
  148. package/dist/lib/service-utils.js.map +1 -0
  149. package/dist/lib/skill-generator.d.ts +21 -0
  150. package/dist/lib/skill-generator.d.ts.map +1 -0
  151. package/dist/lib/skill-generator.js +253 -0
  152. package/dist/lib/skill-generator.js.map +1 -0
  153. package/dist/lib/stratus-client.d.ts +100 -0
  154. package/dist/lib/stratus-client.d.ts.map +1 -0
  155. package/dist/lib/stratus-client.js +255 -0
  156. package/dist/lib/stratus-client.js.map +1 -0
  157. package/dist/mcp/context-hub-mcp.js +135 -53
  158. package/dist/mcp/context-hub-mcp.js.map +1 -1
  159. package/dist/mcp/service-mcp-server.d.ts +12 -0
  160. package/dist/mcp/service-mcp-server.d.ts.map +1 -0
  161. package/dist/mcp/service-mcp-server.js +434 -0
  162. package/dist/mcp/service-mcp-server.js.map +1 -0
  163. package/dist/mcp/service-peer-mcp.d.ts +36 -0
  164. package/dist/mcp/service-peer-mcp.d.ts.map +1 -0
  165. package/dist/mcp/service-peer-mcp.js +220 -0
  166. package/dist/mcp/service-peer-mcp.js.map +1 -0
  167. package/dist/mcp/service-registry-mcp.d.ts +13 -0
  168. package/dist/mcp/service-registry-mcp.d.ts.map +1 -0
  169. package/dist/mcp/service-registry-mcp.js +330 -0
  170. package/dist/mcp/service-registry-mcp.js.map +1 -0
  171. package/dist/ui/banner.js +1 -1
  172. package/dist/ui/banner.js.map +1 -1
  173. package/dist/ui/context-hub-logs.d.ts +10 -0
  174. package/dist/ui/context-hub-logs.d.ts.map +1 -0
  175. package/dist/ui/context-hub-logs.js +175 -0
  176. package/dist/ui/context-hub-logs.js.map +1 -0
  177. package/dist/ui/service-dashboard.d.ts +11 -0
  178. package/dist/ui/service-dashboard.d.ts.map +1 -0
  179. package/dist/ui/service-dashboard.js +357 -0
  180. package/dist/ui/service-dashboard.js.map +1 -0
  181. package/dist/ui/services-manager.d.ts +11 -0
  182. package/dist/ui/services-manager.d.ts.map +1 -0
  183. package/dist/ui/services-manager.js +507 -0
  184. package/dist/ui/services-manager.js.map +1 -0
  185. package/dist/utils/auth-guard.d.ts.map +1 -1
  186. package/dist/utils/auth-guard.js +8 -9
  187. package/dist/utils/auth-guard.js.map +1 -1
  188. package/dist/utils/claude-md-generator.d.ts +10 -0
  189. package/dist/utils/claude-md-generator.d.ts.map +1 -0
  190. package/dist/utils/claude-md-generator.js +215 -0
  191. package/dist/utils/claude-md-generator.js.map +1 -0
  192. package/dist/utils/ensure-context-hub.d.ts +20 -0
  193. package/dist/utils/ensure-context-hub.d.ts.map +1 -0
  194. package/dist/utils/ensure-context-hub.js +65 -0
  195. package/dist/utils/ensure-context-hub.js.map +1 -0
  196. package/dist/utils/ensure-project.d.ts.map +1 -1
  197. package/dist/utils/ensure-project.js +3 -4
  198. package/dist/utils/ensure-project.js.map +1 -1
  199. package/dist/utils/jfl-config.d.ts +19 -0
  200. package/dist/utils/jfl-config.d.ts.map +1 -0
  201. package/dist/utils/jfl-config.js +112 -0
  202. package/dist/utils/jfl-config.js.map +1 -0
  203. package/dist/utils/jfl-migration.d.ts +29 -0
  204. package/dist/utils/jfl-migration.d.ts.map +1 -0
  205. package/dist/utils/jfl-migration.js +142 -0
  206. package/dist/utils/jfl-migration.js.map +1 -0
  207. package/dist/utils/jfl-paths.d.ts +55 -0
  208. package/dist/utils/jfl-paths.d.ts.map +1 -0
  209. package/dist/utils/jfl-paths.js +120 -0
  210. package/dist/utils/jfl-paths.js.map +1 -0
  211. package/dist/utils/settings-validator.d.ts +73 -0
  212. package/dist/utils/settings-validator.d.ts.map +1 -0
  213. package/dist/utils/settings-validator.js +222 -0
  214. package/dist/utils/settings-validator.js.map +1 -0
  215. package/package.json +19 -3
  216. package/scripts/commit-gtm.sh +56 -0
  217. package/scripts/commit-product.sh +68 -0
  218. package/scripts/context-query.sh +45 -0
  219. package/scripts/session/auto-commit.sh +297 -0
  220. package/scripts/session/jfl-doctor.sh +707 -0
  221. package/scripts/session/session-cleanup.sh +268 -0
  222. package/scripts/session/session-end.sh +198 -0
  223. package/scripts/session/session-init.sh +350 -0
  224. package/scripts/session/session-init.sh.backup +292 -0
  225. package/scripts/session/session-sync.sh +167 -0
  226. package/scripts/session/test-context-preservation.sh +160 -0
  227. package/scripts/session/test-critical-infrastructure.sh +293 -0
  228. package/scripts/session/test-experience-level.sh +336 -0
  229. package/scripts/session/test-session-cleanup.sh +268 -0
  230. package/scripts/session/test-session-sync.sh +320 -0
  231. package/scripts/voice-start.sh +36 -8
  232. package/scripts/where-am-i.sh +78 -0
  233. package/template/.claude/service-settings.json +32 -0
  234. package/template/.claude/settings.json +14 -1
  235. package/template/.claude/skills/end/SKILL.md +1780 -0
  236. package/template/.jfl/config.json +2 -1
  237. package/template/CLAUDE.md +1039 -134
  238. package/template/CLAUDE.md.bak +1187 -0
  239. package/template/scripts/commit-gtm.sh +56 -0
  240. package/template/scripts/commit-product.sh +68 -0
  241. package/template/scripts/migrate-to-branch-sessions.sh +201 -0
  242. package/template/scripts/session/auto-commit.sh +58 -6
  243. package/template/scripts/session/jfl-doctor.sh +137 -17
  244. package/template/scripts/session/session-cleanup.sh +268 -0
  245. package/template/scripts/session/session-end.sh +4 -0
  246. package/template/scripts/session/session-init.sh +253 -66
  247. package/template/scripts/session/test-critical-infrastructure.sh +293 -0
  248. package/template/scripts/session/test-experience-level.sh +336 -0
  249. package/template/scripts/session/test-session-cleanup.sh +268 -0
  250. package/template/scripts/session/test-session-sync.sh +320 -0
  251. package/template/scripts/where-am-i.sh +78 -0
  252. package/template/templates/service-agent/.claude/settings.json +32 -0
  253. package/template/templates/service-agent/CLAUDE.md +334 -0
  254. package/template/templates/service-agent/knowledge/ARCHITECTURE.md +115 -0
  255. package/template/templates/service-agent/knowledge/DEPLOYMENT.md +199 -0
  256. package/template/templates/service-agent/knowledge/RUNBOOK.md +412 -0
  257. package/template/templates/service-agent/knowledge/SERVICE_SPEC.md +77 -0
  258. package/dist/commands/session-mgmt.d.ts +0 -33
  259. package/dist/commands/session-mgmt.d.ts.map +0 -1
  260. package/dist/commands/session-mgmt.js +0 -404
  261. package/dist/commands/session-mgmt.js.map +0 -1
  262. package/template/scripts/session/auto-merge.sh +0 -325
@@ -0,0 +1,268 @@
1
+ #!/bin/bash
2
+ #
3
+ # Session Cleanup - Auto-merge session and cleanup
4
+ #
5
+ # Called by Stop hook or /end skill to clean up sessions.
6
+ # Handles both worktree mode (multiple sessions) and direct mode (single session).
7
+ # Only keeps branches that have real conflicts or uncommitted work.
8
+
9
+ set -e
10
+
11
+ # Get working branch from config (fallback to main)
12
+ get_working_branch() {
13
+ local config_branch=$(jq -r '.working_branch // empty' .jfl/config.json 2>/dev/null)
14
+ if [[ -n "$config_branch" ]]; then
15
+ echo "$config_branch"
16
+ else
17
+ echo "main"
18
+ fi
19
+ }
20
+
21
+ WORKING_BRANCH=$(get_working_branch)
22
+
23
+ # Stop background processes first
24
+ echo "Stopping background processes..."
25
+
26
+ # Stop auto-commit if running
27
+ if [ -f ".jfl/auto-commit.pid" ]; then
28
+ PID=$(cat ".jfl/auto-commit.pid")
29
+ if kill -0 "$PID" 2>/dev/null; then
30
+ echo " Stopping auto-commit (PID: $PID)..."
31
+ kill -TERM "$PID" 2>/dev/null || true
32
+ sleep 1
33
+ # Force kill if still running
34
+ kill -0 "$PID" 2>/dev/null && kill -9 "$PID" 2>/dev/null || true
35
+ fi
36
+ rm -f ".jfl/auto-commit.pid"
37
+ fi
38
+
39
+ # Stop auto-merge if running
40
+ if [ -f ".auto-merge.pid" ]; then
41
+ PID=$(cat ".auto-merge.pid")
42
+ if kill -0 "$PID" 2>/dev/null; then
43
+ echo " Stopping auto-merge (PID: $PID)..."
44
+ kill -TERM "$PID" 2>/dev/null || true
45
+ sleep 1
46
+ kill -0 "$PID" 2>/dev/null && kill -9 "$PID" 2>/dev/null || true
47
+ fi
48
+ rm -f ".auto-merge.pid"
49
+ fi
50
+
51
+ # Stop context-hub if running (already handled by Stop hook, but be defensive)
52
+ if [ -f ".jfl/context-hub.pid" ]; then
53
+ PID=$(cat ".jfl/context-hub.pid")
54
+ if kill -0 "$PID" 2>/dev/null; then
55
+ echo " Stopping context-hub (PID: $PID)..."
56
+ kill -TERM "$PID" 2>/dev/null || true
57
+ sleep 1
58
+ kill -0 "$PID" 2>/dev/null && kill -9 "$PID" 2>/dev/null || true
59
+ fi
60
+ rm -f ".jfl/context-hub.pid"
61
+ fi
62
+
63
+ # Get current session info
64
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "")
65
+ if [ -z "$BRANCH" ]; then
66
+ echo "Not on a branch, skipping cleanup"
67
+ exit 0
68
+ fi
69
+
70
+ # Skip if not a session branch
71
+ if [[ ! "$BRANCH" =~ ^session- ]]; then
72
+ echo "Not a session branch, skipping cleanup"
73
+ exit 0
74
+ fi
75
+
76
+ # Detect mode: are we in a worktree or working directly?
77
+ IN_WORKTREE=false
78
+ if [[ "$(pwd)" == *"/worktrees/session-"* ]]; then
79
+ IN_WORKTREE=true
80
+ echo "Cleaning up worktree session: $BRANCH"
81
+ else
82
+ echo "Cleaning up direct session: $BRANCH"
83
+ fi
84
+
85
+ # Auto-commit any uncommitted changes first
86
+ if ! git diff --quiet || ! git diff --cached --quiet; then
87
+ echo "Auto-committing changes..."
88
+
89
+ # Check if last commit is already "session: end" (make idempotent)
90
+ LAST_MSG=$(git log -1 --pretty=%s 2>/dev/null || echo "")
91
+ if [[ "$LAST_MSG" =~ ^session:\ end ]]; then
92
+ echo "Last commit already is 'session: end', skipping duplicate commit"
93
+ else
94
+ git add -A
95
+ # Unstage session metadata files that should never be committed
96
+ git reset HEAD .jfl/current-session-branch.txt 2>/dev/null || true
97
+ git reset HEAD .jfl/current-worktree.txt 2>/dev/null || true
98
+ git reset HEAD .jfl/worktree-path.txt 2>/dev/null || true
99
+ git commit -m "session: end $(date +%Y-%m-%d\ %H:%M)" || true
100
+ fi
101
+ fi
102
+
103
+ # Detect main repo location
104
+ if [ "$IN_WORKTREE" = true ]; then
105
+ # We're in a worktree - find main repo
106
+ MAIN_REPO=$(git rev-parse --git-common-dir 2>/dev/null | sed 's|/\.git$||')
107
+ if [ -z "$MAIN_REPO" ] || [ ! -d "$MAIN_REPO" ]; then
108
+ # Fallback: find parent directory
109
+ MAIN_REPO=$(git worktree list | grep "(bare)" | awk '{print $1}' | head -1)
110
+ if [ -z "$MAIN_REPO" ]; then
111
+ MAIN_REPO=$(git worktree list | head -1 | awk '{print $1}')
112
+ fi
113
+ fi
114
+ else
115
+ # We're in direct mode - already in main repo
116
+ MAIN_REPO=$(pwd)
117
+ fi
118
+
119
+ # Pre-merge cleanup: Remove files that will definitely conflict
120
+ echo "Pre-merge cleanup..."
121
+ git rm -f .jfl/current-session-branch.txt 2>/dev/null || true
122
+ git rm -f .jfl/current-worktree.txt 2>/dev/null || true
123
+ git rm -f .jfl/worktree-path.txt 2>/dev/null || true
124
+
125
+ # Remove any git conflict artifacts from previous failed merges
126
+ find .jfl -name "journal~*" -type f -delete 2>/dev/null || true
127
+
128
+ # Commit cleanup if there are changes
129
+ if ! git diff --quiet HEAD 2>/dev/null; then
130
+ git commit -m "cleanup: remove session metadata before merge" 2>/dev/null || true
131
+ fi
132
+
133
+ # Try to merge to working branch
134
+ echo "Attempting to merge $BRANCH to $WORKING_BRANCH..."
135
+ cd "$MAIN_REPO"
136
+
137
+ # Checkout working branch in the main repo
138
+ if ! git checkout "$WORKING_BRANCH" 2>/dev/null; then
139
+ echo "⚠ Could not checkout $WORKING_BRANCH, skipping merge"
140
+ echo " Session branch $BRANCH preserved for manual merge"
141
+ # Notify jfl-services that session ended
142
+ if command -v curl >/dev/null 2>&1; then
143
+ curl -s -X DELETE "http://localhost:3401/sessions/$BRANCH" >/dev/null 2>&1 || true
144
+ fi
145
+ exit 0
146
+ fi
147
+
148
+ # Attempt merge with auto-resolve for .jfl/ conflicts
149
+ MERGE_OUTPUT=$(git merge --no-edit -X ours "$BRANCH" 2>&1)
150
+ MERGE_STATUS=$?
151
+
152
+ if [ $MERGE_STATUS -eq 0 ]; then
153
+ echo "✓ Merged $BRANCH to $WORKING_BRANCH"
154
+
155
+ # Push to origin
156
+ git push origin "$WORKING_BRANCH" 2>/dev/null || echo "⚠ Push failed - run manually: git push origin $WORKING_BRANCH"
157
+
158
+ # Remove worktree if it exists
159
+ WORKTREE_PATH=$(git worktree list | grep "$BRANCH" | awk '{print $1}' | head -1)
160
+ if [ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ]; then
161
+ echo "Removing worktree at $WORKTREE_PATH..."
162
+ rm -rf "$WORKTREE_PATH" 2>/dev/null || true
163
+ git worktree prune 2>/dev/null || true
164
+ fi
165
+
166
+ # Delete the branch
167
+ echo "Deleting branch $BRANCH..."
168
+ git branch -D "$BRANCH" 2>/dev/null || true
169
+
170
+ echo "✓ Session cleanup complete - merged to $WORKING_BRANCH and pushed"
171
+
172
+ # Notify jfl-services that session ended
173
+ if command -v curl >/dev/null 2>&1; then
174
+ curl -s -X DELETE "http://localhost:3401/sessions/$BRANCH" >/dev/null 2>&1 || true
175
+ fi
176
+ else
177
+ # Merge failed - try auto-resolving common conflicts
178
+ echo "Initial merge failed, attempting auto-resolve..."
179
+
180
+ # Check what conflicts we have
181
+ CONFLICTS=$(git diff --name-only --diff-filter=U 2>/dev/null)
182
+
183
+ AUTO_RESOLVED=true
184
+ while IFS= read -r file; do
185
+ if [[ -z "$file" ]]; then
186
+ continue
187
+ fi
188
+
189
+ case "$file" in
190
+ .jfl/current-session-branch.txt|.jfl/current-worktree.txt|.jfl/worktree-path.txt)
191
+ # Session metadata - just remove it
192
+ echo " Auto-resolving: $file (removing)"
193
+ git rm -f "$file" 2>/dev/null || true
194
+ ;;
195
+ .jfl/journal~*)
196
+ # Git conflict artifact - remove it
197
+ echo " Auto-resolving: $file (removing artifact)"
198
+ git rm -f "$file" 2>/dev/null || true
199
+ ;;
200
+ product)
201
+ # Product directory conflict (likely symlink vs dir)
202
+ # Keep working branch's version (which should be platform symlink or nothing)
203
+ echo " Auto-resolving: $file (keeping $WORKING_BRANCH's version)"
204
+ git checkout --ours "$file" 2>/dev/null || git rm -f "$file" 2>/dev/null || true
205
+ ;;
206
+ platform|cli|runner)
207
+ # Submodule conflicts - keep working branch's version
208
+ echo " Auto-resolving: $file (keeping $WORKING_BRANCH's submodule state)"
209
+ git checkout --ours "$file" 2>/dev/null || true
210
+ ;;
211
+ *)
212
+ # Unknown conflict - can't auto-resolve
213
+ echo " ⚠ Cannot auto-resolve: $file"
214
+ AUTO_RESOLVED=false
215
+ ;;
216
+ esac
217
+ done <<< "$CONFLICTS"
218
+
219
+ if [ "$AUTO_RESOLVED" = true ]; then
220
+ # All conflicts resolved, complete the merge
221
+ echo "All conflicts auto-resolved, completing merge..."
222
+ git add -A
223
+ git commit --no-edit 2>/dev/null || true
224
+
225
+ echo "✓ Merged $BRANCH to $WORKING_BRANCH (with auto-resolution)"
226
+
227
+ # Push to origin
228
+ git push origin "$WORKING_BRANCH" 2>/dev/null || echo "⚠ Push failed - run manually: git push origin $WORKING_BRANCH"
229
+
230
+ # Remove worktree
231
+ WORKTREE_PATH=$(git worktree list | grep "$BRANCH" | awk '{print $1}' | head -1)
232
+ if [ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ]; then
233
+ echo "Removing worktree at $WORKTREE_PATH..."
234
+ rm -rf "$WORKTREE_PATH" 2>/dev/null || true
235
+ git worktree prune 2>/dev/null || true
236
+ fi
237
+
238
+ # Delete the branch
239
+ echo "Deleting branch $BRANCH..."
240
+ git branch -D "$BRANCH" 2>/dev/null || true
241
+
242
+ echo "✓ Session cleanup complete - merged to $WORKING_BRANCH and pushed"
243
+
244
+ # Notify jfl-services that session ended
245
+ if command -v curl >/dev/null 2>&1; then
246
+ curl -s -X DELETE "http://localhost:3401/sessions/$BRANCH" >/dev/null 2>&1 || true
247
+ fi
248
+ else
249
+ # Still have unresolved conflicts
250
+ echo "⚠ Merge conflicts remain, keeping branch $BRANCH"
251
+ echo " Review later with: git log $WORKING_BRANCH..$BRANCH"
252
+ echo " Conflicting files:"
253
+ git diff --name-only --diff-filter=U 2>/dev/null | sed 's/^/ - /'
254
+ git merge --abort 2>/dev/null || true
255
+
256
+ # Notify jfl-services that session ended (even though we kept the branch)
257
+ if command -v curl >/dev/null 2>&1; then
258
+ curl -s -X DELETE "http://localhost:3401/sessions/$BRANCH" >/dev/null 2>&1 || true
259
+ fi
260
+ fi
261
+ fi
262
+
263
+ # Final notification to jfl-services (in case we skipped merge paths)
264
+ if command -v curl >/dev/null 2>&1; then
265
+ curl -s -X DELETE "http://localhost:3401/sessions/$BRANCH" >/dev/null 2>&1 || true
266
+ fi
267
+
268
+ exit 0
@@ -0,0 +1,198 @@
1
+ #!/bin/bash
2
+ # session-end.sh - Gracefully end a JFL session
3
+ # Handles both worktree sessions (merge + cleanup) and main branch sessions
4
+ #
5
+ # Usage:
6
+ # ./scripts/session/session-end.sh # Standard end
7
+ # ./scripts/session/session-end.sh --force # Force end (even with uncommitted changes)
8
+
9
+ set -e
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ PROJECT_ROOT="$(pwd)"
13
+ LOG_DIR="$PROJECT_ROOT/.jfl/logs"
14
+ SESSION_FILE="$PROJECT_ROOT/.jfl/current-session.json"
15
+
16
+ # Colors
17
+ RED='\033[0;31m'
18
+ GREEN='\033[0;32m'
19
+ YELLOW='\033[1;33m'
20
+ BLUE='\033[0;34m'
21
+ NC='\033[0m'
22
+
23
+ FORCE=false
24
+ while [[ $# -gt 0 ]]; do
25
+ case $1 in
26
+ --force|-f)
27
+ FORCE=true
28
+ shift
29
+ ;;
30
+ *)
31
+ shift
32
+ ;;
33
+ esac
34
+ done
35
+
36
+ echo ""
37
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
38
+ echo " JFL Session End"
39
+ echo " $(date '+%Y-%m-%d %H:%M:%S')"
40
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
41
+ echo ""
42
+
43
+ cd "$PROJECT_ROOT"
44
+
45
+ # Check if this is a worktree session
46
+ IS_WORKTREE=false
47
+ SESSION_NAME=""
48
+ WORKTREE_PATH=""
49
+
50
+ if [ -f "$SESSION_FILE" ]; then
51
+ # Parse session info
52
+ if grep -q '"worktree": true' "$SESSION_FILE" 2>/dev/null; then
53
+ IS_WORKTREE=true
54
+ SESSION_NAME=$(grep -o '"session_name"[^,}]*' "$SESSION_FILE" | cut -d'"' -f4)
55
+ WORKTREE_PATH=$(grep -o '"worktree_path"[^,}]*' "$SESSION_FILE" | cut -d'"' -f4)
56
+ fi
57
+ fi
58
+
59
+ if $IS_WORKTREE && [ -n "$SESSION_NAME" ] && [ "$SESSION_NAME" != "main" ] && [ "$SESSION_NAME" != "null" ]; then
60
+ echo -e "${BLUE}→${NC} Ending worktree session: $SESSION_NAME"
61
+ echo ""
62
+
63
+ # Use worktree-session.sh to properly end (merge + cleanup)
64
+ if [ -f "$SCRIPT_DIR/worktree-session.sh" ]; then
65
+ "$SCRIPT_DIR/worktree-session.sh" end "$SESSION_NAME"
66
+ else
67
+ echo -e "${RED}✗${NC} worktree-session.sh not found!"
68
+ echo " Manual cleanup needed:"
69
+ echo " 1. cd $WORKTREE_PATH && git add -A && git commit"
70
+ echo " 2. Merge branch $SESSION_NAME to main"
71
+ echo " 3. Remove worktree: git worktree remove $WORKTREE_PATH"
72
+ exit 1
73
+ fi
74
+
75
+ # Clean up session file
76
+ rm -f "$SESSION_FILE"
77
+
78
+ else
79
+ # Main branch session - just commit and push
80
+ echo -e "${BLUE}→${NC} Ending main branch session..."
81
+
82
+ # Step 1: Stop auto-commit
83
+ echo -e "${BLUE}→${NC} Stopping auto-commit..."
84
+ "$SCRIPT_DIR/auto-commit.sh" stop 2>/dev/null || true
85
+
86
+ # Step 2: Take final snapshot (fast - skip large files)
87
+ echo -e "${BLUE}→${NC} Taking final snapshot..."
88
+ mkdir -p "$LOG_DIR"
89
+ SNAPSHOT_END="$LOG_DIR/snapshot-end-$(date +%Y%m%d-%H%M%S).txt"
90
+ CRITICAL_PATHS=("knowledge/" "previews/" "content/" "suggestions/" "CLAUDE.md")
91
+
92
+ # Skip .jfl/ for snapshots (contains large memory.db)
93
+ # Use stat instead of md5 for speed (size + mtime is enough for change detection)
94
+ for p in "${CRITICAL_PATHS[@]}"; do
95
+ if [ -e "$PROJECT_ROOT/$p" ]; then
96
+ find "$PROJECT_ROOT/$p" -type f -exec stat -f "%z %m %N" {} \; 2>/dev/null
97
+ fi
98
+ done | sort > "$SNAPSHOT_END"
99
+
100
+ # Step 3: Check for uncommitted changes
101
+ echo -e "${BLUE}→${NC} Checking for uncommitted changes..."
102
+ CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
103
+
104
+ if [ "$CHANGES" -gt 0 ]; then
105
+ echo -e "${YELLOW}⚠${NC} Found $CHANGES uncommitted changes"
106
+ git status --short
107
+
108
+ echo ""
109
+ echo -e "${BLUE}→${NC} Committing all changes..."
110
+ git add -A
111
+ # Unstage session metadata files that should never be committed
112
+ git reset HEAD .jfl/current-session-branch.txt 2>/dev/null || true
113
+ git reset HEAD .jfl/current-worktree.txt 2>/dev/null || true
114
+ git reset HEAD .jfl/worktree-path.txt 2>/dev/null || true
115
+
116
+ COMMIT_MSG="session: end $(date '+%Y-%m-%d %H:%M')"
117
+
118
+ if git commit -m "$COMMIT_MSG"; then
119
+ echo -e "${GREEN}✓${NC} Changes committed"
120
+ else
121
+ echo -e "${YELLOW}⚠${NC} Nothing to commit"
122
+ fi
123
+ else
124
+ echo -e "${GREEN}✓${NC} No uncommitted changes"
125
+ fi
126
+
127
+ # Step 4: Push to remote
128
+ echo -e "${BLUE}→${NC} Pushing to remote..."
129
+ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
130
+ if git push origin "$CURRENT_BRANCH" 2>/dev/null; then
131
+ echo -e "${GREEN}✓${NC} Pushed to origin/$CURRENT_BRANCH"
132
+ else
133
+ echo -e "${YELLOW}⚠${NC} Push failed (will retry on next session)"
134
+ fi
135
+
136
+ # Step 5: Sync product repo if symlink/submodule
137
+ PRODUCT_PATH="$PROJECT_ROOT/product"
138
+ if [ -L "$PRODUCT_PATH" ] || [ -d "$PRODUCT_PATH/.git" ]; then
139
+ echo ""
140
+ echo -e "${BLUE}→${NC} Syncing product repo..."
141
+
142
+ if [ -L "$PRODUCT_PATH" ]; then
143
+ TARGET=$(readlink "$PRODUCT_PATH")
144
+ if [[ "$TARGET" == ../* ]]; then
145
+ TARGET="$PROJECT_ROOT/$TARGET"
146
+ fi
147
+ TARGET=$(cd "$TARGET" 2>/dev/null && pwd)
148
+ else
149
+ TARGET="$PRODUCT_PATH"
150
+ fi
151
+
152
+ if [ -d "$TARGET/.git" ]; then
153
+ cd "$TARGET"
154
+ PRODUCT_CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
155
+ if [ "$PRODUCT_CHANGES" -gt 0 ]; then
156
+ git add -A
157
+ git commit -m "session: end $(date '+%Y-%m-%d %H:%M')" || true
158
+ git push 2>/dev/null || echo -e "${YELLOW}⚠${NC} Product push failed"
159
+ echo -e "${GREEN}✓${NC} Product repo synced"
160
+ else
161
+ echo -e "${GREEN}✓${NC} Product repo clean"
162
+ fi
163
+ cd "$PROJECT_ROOT"
164
+ fi
165
+ fi
166
+
167
+ # Step 6: Compare snapshots
168
+ if [ -f "$SESSION_FILE" ]; then
169
+ SNAPSHOT_BEFORE=$(grep -o '"snapshot_before"[^,}]*' "$SESSION_FILE" | cut -d'"' -f4)
170
+
171
+ if [ -f "$SNAPSHOT_BEFORE" ]; then
172
+ echo ""
173
+ echo -e "${BLUE}→${NC} Session file changes:"
174
+ DIFF_OUTPUT=$(diff "$SNAPSHOT_BEFORE" "$SNAPSHOT_END" 2>/dev/null || true)
175
+
176
+ if [ -n "$DIFF_OUTPUT" ]; then
177
+ ADDED=$(echo "$DIFF_OUTPUT" | grep "^>" | wc -l | tr -d ' ')
178
+ REMOVED=$(echo "$DIFF_OUTPUT" | grep "^<" | wc -l | tr -d ' ')
179
+ echo " Files added/modified: $ADDED"
180
+ echo " Files removed: $REMOVED"
181
+ echo "$DIFF_OUTPUT" > "$LOG_DIR/session-diff-$(date +%Y%m%d-%H%M%S).txt"
182
+ else
183
+ echo " No file changes this session"
184
+ fi
185
+ fi
186
+ fi
187
+
188
+ # Clean up session file
189
+ rm -f "$SESSION_FILE"
190
+
191
+ echo ""
192
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
193
+ echo -e " ${GREEN}Session ended successfully!${NC}"
194
+ echo ""
195
+ echo " All changes committed and pushed."
196
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
197
+ echo ""
198
+ fi