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,56 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # commit-gtm.sh - Commit changes to GTM repo (knowledge, content, etc.)
4
+ #
5
+ # Usage:
6
+ # ./scripts/commit-gtm.sh "commit message"
7
+ #
8
+ # This commits to the GTM repo (not the product submodule):
9
+ # - knowledge/
10
+ # - content/
11
+ # - suggestions/
12
+ # - previews/
13
+ # - etc.
14
+
15
+ set -e
16
+
17
+ if [[ -z "$1" ]]; then
18
+ echo "Usage: $0 \"commit message\""
19
+ exit 1
20
+ fi
21
+
22
+ COMMIT_MSG="$1"
23
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
25
+
26
+ echo "📝 Committing to GTM repo..."
27
+ echo ""
28
+
29
+ cd "$REPO_ROOT"
30
+
31
+ # Show what will be committed (exclude all submodules)
32
+ echo "Changes to commit:"
33
+ git status --short | grep -v "^M. product" | grep -v "^M. runner" || true
34
+ echo ""
35
+
36
+ # Stage all changes except submodules (product, runner, etc.)
37
+ git add knowledge/ content/ suggestions/ previews/ CLAUDE.md .jfl/ scripts/ .gitmodules 2>/dev/null || true
38
+
39
+ # Use pathspec exclusion to ensure no submodules are staged
40
+ git reset HEAD product/ runner/ 2>/dev/null || true
41
+
42
+ # Check if there's anything to commit
43
+ if git diff --cached --quiet; then
44
+ echo "⚠️ No changes to commit (excluding product submodule)"
45
+ echo " Use ./scripts/commit-product.sh for product changes"
46
+ exit 0
47
+ fi
48
+
49
+ # Commit
50
+ git commit -m "$COMMIT_MSG"
51
+
52
+ # Push
53
+ git push origin main
54
+
55
+ echo ""
56
+ echo "✅ GTM changes committed and pushed!"
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # commit-product.sh - Commit changes to product submodule
4
+ #
5
+ # Usage:
6
+ # ./scripts/commit-product.sh "commit message"
7
+ #
8
+ # This handles all the submodule commit logic:
9
+ # - cd to product submodule
10
+ # - stage changes
11
+ # - commit
12
+ # - push to origin
13
+ # - update parent repo reference
14
+
15
+ set -e
16
+
17
+ if [[ -z "$1" ]]; then
18
+ echo "Usage: $0 \"commit message\""
19
+ exit 1
20
+ fi
21
+
22
+ COMMIT_MSG="$1"
23
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
25
+ PRODUCT_DIR="$REPO_ROOT/product"
26
+
27
+ echo "📦 Committing to product submodule..."
28
+ echo ""
29
+
30
+ # Go to product submodule
31
+ cd "$PRODUCT_DIR"
32
+
33
+ # Check if on a branch
34
+ CURRENT_BRANCH=$(git branch --show-current)
35
+ if [[ -z "$CURRENT_BRANCH" ]]; then
36
+ echo "⚠️ You're in detached HEAD state"
37
+ echo " Checking out main first..."
38
+ git checkout main
39
+ fi
40
+
41
+ # Show what will be committed
42
+ echo "Changes to commit:"
43
+ git status --short
44
+ echo ""
45
+
46
+ # Stage all changes
47
+ git add -A
48
+
49
+ # Commit
50
+ git commit -m "$COMMIT_MSG"
51
+
52
+ # Push
53
+ git push origin main
54
+
55
+ # Update parent repo reference
56
+ cd "$REPO_ROOT"
57
+ git add product
58
+ git commit -m "chore: update product submodule
59
+
60
+ Latest commit: $(cd product && git log -1 --oneline)
61
+
62
+ Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
63
+ git push origin main
64
+
65
+ echo ""
66
+ echo "✅ Product changes committed and pushed!"
67
+ echo " Submodule: $PRODUCT_DIR"
68
+ echo " Parent updated to track latest"
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # migrate-to-branch-sessions.sh - Migrate from worktree-based to branch-based sessions
4
+ #
5
+ # This script helps existing JFL users migrate to the new simplified session model.
6
+ # It handles:
7
+ # - Saving uncommitted work from worktrees
8
+ # - Merging session branches to main
9
+ # - Removing worktree directories
10
+ # - Cleaning up metadata files
11
+ #
12
+ # @purpose Migration from worktree sessions to branch-only sessions
13
+
14
+ set -e
15
+
16
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
+ REPO_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
18
+ WORKTREES_DIR="$REPO_DIR/worktrees"
19
+
20
+ # Colors
21
+ RED='\033[0;31m'
22
+ GREEN='\033[0;32m'
23
+ YELLOW='\033[1;33m'
24
+ BLUE='\033[0;34m'
25
+ CYAN='\033[0;36m'
26
+ NC='\033[0m'
27
+
28
+ echo ""
29
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
30
+ echo " JFL Migration: Worktree → Branch-Based Sessions"
31
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
32
+ echo ""
33
+ echo "This will migrate your project from worktree-based sessions to"
34
+ echo "simpler branch-based sessions."
35
+ echo ""
36
+ echo "What this does:"
37
+ echo " 1. Save any uncommitted work in worktrees"
38
+ echo " 2. Merge session branches to main"
39
+ echo " 3. Remove worktree directories"
40
+ echo " 4. Clean up metadata files"
41
+ echo ""
42
+
43
+ # Check if worktrees exist
44
+ if [[ ! -d "$WORKTREES_DIR" ]]; then
45
+ echo -e "${GREEN}✓${NC} No worktrees directory found - nothing to migrate"
46
+ exit 0
47
+ fi
48
+
49
+ # Count worktrees
50
+ worktree_count=$(find "$WORKTREES_DIR" -maxdepth 1 -type d -name "session-*" 2>/dev/null | wc -l | tr -d ' ')
51
+
52
+ if [[ $worktree_count -eq 0 ]]; then
53
+ echo -e "${GREEN}✓${NC} No worktrees found - nothing to migrate"
54
+ echo ""
55
+ echo "Cleaning up empty worktrees directory..."
56
+ rmdir "$WORKTREES_DIR" 2>/dev/null || true
57
+ exit 0
58
+ fi
59
+
60
+ echo -e "${YELLOW}⚠${NC} Found $worktree_count worktree(s) to migrate"
61
+ echo ""
62
+
63
+ # Ensure we're on main branch
64
+ current_branch=$(git branch --show-current 2>/dev/null || echo "")
65
+ if [[ "$current_branch" != "main" ]]; then
66
+ echo "Switching to main branch..."
67
+ git checkout main 2>/dev/null || {
68
+ echo -e "${RED}✗${NC} Failed to checkout main branch"
69
+ echo " Please switch to main manually and run this script again"
70
+ exit 1
71
+ }
72
+ fi
73
+
74
+ # Step 1: Save uncommitted work in worktrees
75
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
76
+ echo " Step 1: Checking for uncommitted work"
77
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
78
+ echo ""
79
+
80
+ for wt in "$WORKTREES_DIR"/session-*; do
81
+ if [[ -d "$wt" ]]; then
82
+ session_name=$(basename "$wt")
83
+ cd "$wt"
84
+
85
+ if git status --porcelain 2>/dev/null | grep -q .; then
86
+ echo -e "${YELLOW}⚠${NC} Uncommitted work in $session_name"
87
+ git status --short
88
+ echo ""
89
+ echo " Committing changes..."
90
+ git add -A
91
+ git commit -m "migration: auto-save uncommitted work before migration" || true
92
+ echo -e "${GREEN}✓${NC} Changes saved"
93
+ echo ""
94
+ else
95
+ echo -e "${GREEN}✓${NC} $session_name - no uncommitted changes"
96
+ fi
97
+
98
+ cd "$REPO_DIR"
99
+ fi
100
+ done
101
+
102
+ # Step 2: Merge session branches to main
103
+ echo ""
104
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
105
+ echo " Step 2: Merging session branches"
106
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
107
+ echo ""
108
+
109
+ # Get all session branches
110
+ session_branches=$(git branch | grep "session-" | sed 's/^[* ]*//' || true)
111
+
112
+ if [[ -z "$session_branches" ]]; then
113
+ echo -e "${GREEN}✓${NC} No session branches to merge"
114
+ else
115
+ for branch in $session_branches; do
116
+ echo "Merging $branch..."
117
+
118
+ # Try to merge
119
+ if git merge --no-edit "$branch" 2>/dev/null; then
120
+ echo -e "${GREEN}✓${NC} Merged $branch"
121
+
122
+ # Delete the branch
123
+ git branch -D "$branch" 2>/dev/null || true
124
+ else
125
+ # Merge conflicts - show them and skip
126
+ echo -e "${RED}✗${NC} Conflicts merging $branch"
127
+ echo ""
128
+ echo " Conflicting files:"
129
+ git diff --name-only --diff-filter=U 2>/dev/null | sed 's/^/ - /'
130
+ echo ""
131
+ echo " Aborting this merge - you'll need to merge $branch manually"
132
+ git merge --abort 2>/dev/null || true
133
+ echo ""
134
+ fi
135
+ done
136
+ fi
137
+
138
+ # Step 3: Clean up worktrees
139
+ echo ""
140
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
141
+ echo " Step 3: Removing worktrees"
142
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
143
+ echo ""
144
+
145
+ # Prune worktrees from git
146
+ echo "Pruning worktree references..."
147
+ git worktree prune 2>/dev/null || true
148
+
149
+ # Remove worktree directories
150
+ if [[ -d "$WORKTREES_DIR" ]]; then
151
+ echo "Removing worktrees directory..."
152
+ rm -rf "$WORKTREES_DIR" 2>/dev/null || {
153
+ echo -e "${YELLOW}⚠${NC} Could not remove $WORKTREES_DIR automatically"
154
+ echo " Please remove it manually: rm -rf $WORKTREES_DIR"
155
+ }
156
+ echo -e "${GREEN}✓${NC} Worktrees directory removed"
157
+ fi
158
+
159
+ # Step 4: Clean up metadata
160
+ echo ""
161
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
162
+ echo " Step 4: Cleaning up metadata"
163
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
164
+ echo ""
165
+
166
+ # Remove worktree metadata files
167
+ rm -f "$REPO_DIR/.jfl/current-worktree.txt" 2>/dev/null || true
168
+ rm -f "$REPO_DIR/.jfl/worktree-path.txt" 2>/dev/null || true
169
+
170
+ echo -e "${GREEN}✓${NC} Metadata cleaned up"
171
+
172
+ # Step 5: Summary
173
+ echo ""
174
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
175
+ echo " Migration Complete!"
176
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
177
+ echo ""
178
+ echo -e "${GREEN}✓${NC} Migration completed successfully"
179
+ echo ""
180
+ echo "What changed:"
181
+ echo " • Worktree directories removed"
182
+ echo " • Session branches merged to main (where possible)"
183
+ echo " • Metadata files cleaned up"
184
+ echo ""
185
+ echo "What's next:"
186
+ echo " • New sessions will use simple branch-based isolation"
187
+ echo " • No more worktree complexity or background processes"
188
+ echo " • Run 'git status' to verify everything is clean"
189
+ echo ""
190
+
191
+ # Check for remaining session branches that weren't merged
192
+ remaining_branches=$(git branch | grep "session-" | sed 's/^[* ]*//' || true)
193
+ if [[ -n "$remaining_branches" ]]; then
194
+ echo -e "${YELLOW}⚠${NC} Note: Some session branches still exist (had conflicts):"
195
+ echo "$remaining_branches" | sed 's/^/ - /'
196
+ echo ""
197
+ echo " You can merge or delete these manually:"
198
+ echo " git merge <branch-name> # to merge"
199
+ echo " git branch -D <branch-name> # to delete"
200
+ echo ""
201
+ fi
@@ -30,7 +30,8 @@ CRITICAL_PATHS=(
30
30
  "content/"
31
31
  "suggestions/"
32
32
  "CLAUDE.md"
33
- ".jfl/"
33
+ ".jfl/journal/"
34
+ ".jfl/config.json"
34
35
  )
35
36
 
36
37
  do_commit() {
@@ -72,8 +73,9 @@ do_commit() {
72
73
  git add $paths
73
74
  git commit -m "$MSG" || return 0
74
75
 
75
- # Push after commit - from ours
76
- git push origin main 2>/dev/null || echo "[$(date '+%H:%M:%S')] Push failed - will retry"
76
+ # Push after commit to current branch
77
+ local current_branch=$(git branch --show-current)
78
+ git push origin "$current_branch" 2>/dev/null || echo "[$(date '+%H:%M:%S')] Push failed - will retry"
77
79
 
78
80
  echo "[$(date '+%H:%M:%S')] Committed: $MSG"
79
81
  }
@@ -142,6 +144,27 @@ commit_single_submodule() {
142
144
  fi
143
145
  }
144
146
 
147
+ # Graceful shutdown handler - ensures final commit before exit
148
+ graceful_shutdown() {
149
+ echo "[$(date '+%H:%M:%S')] Received shutdown signal - saving final changes..." >> "$LOG_FILE" 2>&1
150
+
151
+ # Run final commit to save any pending work
152
+ {
153
+ do_commit
154
+ commit_submodules_if_changes
155
+ } >> "$LOG_FILE" 2>&1
156
+
157
+ # Run session cleanup (auto-merge and remove worktree if safe)
158
+ if [[ -f "$SCRIPT_DIR/session-cleanup.sh" ]]; then
159
+ echo "[$(date '+%H:%M:%S')] Running session cleanup..." >> "$LOG_FILE" 2>&1
160
+ bash "$SCRIPT_DIR/session-cleanup.sh" >> "$LOG_FILE" 2>&1 || true
161
+ fi
162
+
163
+ echo "[$(date '+%H:%M:%S')] Shutdown complete." >> "$LOG_FILE" 2>&1
164
+ rm -f "$PID_FILE"
165
+ exit 0
166
+ }
167
+
145
168
  start_daemon() {
146
169
  if [[ -f "$PID_FILE" ]]; then
147
170
  local pid=$(cat "$PID_FILE")
@@ -154,12 +177,25 @@ start_daemon() {
154
177
 
155
178
  echo "Starting auto-commit daemon (interval: ${INTERVAL}s)..."
156
179
 
157
- # Run in background (match original JFL pattern)
180
+ # Run in background with signal handling
158
181
  # Close inherited file descriptors so parent doesn't wait for us
159
182
  (
160
183
  exec </dev/null >/dev/null 2>&1
184
+
185
+ # Trap signals for graceful shutdown (added SIGHUP for terminal close)
186
+ trap graceful_shutdown SIGINT SIGTERM SIGQUIT SIGHUP
187
+
188
+ # Track parent process to detect when Claude dies
189
+ INITIAL_PPID=$PPID
190
+
161
191
  while true; do
162
192
  {
193
+ # Check if parent process (Claude) is still alive
194
+ if ! kill -0 "$INITIAL_PPID" 2>/dev/null; then
195
+ echo "[$(date '+%H:%M:%S')] Parent process died (PPID $INITIAL_PPID) - running cleanup..."
196
+ graceful_shutdown
197
+ fi
198
+
163
199
  echo "[$(date '+%H:%M:%S')] Checking for changes..."
164
200
  do_commit
165
201
  commit_submodules_if_changes
@@ -179,8 +215,24 @@ stop_daemon() {
179
215
  local pid=$(cat "$PID_FILE")
180
216
  if kill -0 "$pid" 2>/dev/null; then
181
217
  echo "Stopping auto-commit (PID: $pid)..."
182
- kill "$pid" 2>/dev/null
183
- rm -f "$PID_FILE"
218
+
219
+ # Send SIGTERM for graceful shutdown (runs final commit)
220
+ kill -TERM "$pid" 2>/dev/null
221
+
222
+ # Wait up to 10 seconds for graceful shutdown
223
+ local wait_count=0
224
+ while kill -0 "$pid" 2>/dev/null && [ $wait_count -lt 20 ]; do
225
+ sleep 0.5
226
+ wait_count=$((wait_count + 1))
227
+ done
228
+
229
+ # If still running after timeout, force kill
230
+ if kill -0 "$pid" 2>/dev/null; then
231
+ echo "Graceful shutdown timed out, forcing..."
232
+ kill -9 "$pid" 2>/dev/null
233
+ rm -f "$PID_FILE"
234
+ fi
235
+
184
236
  echo "Stopped."
185
237
  else
186
238
  echo "Process not running (stale PID file)"
@@ -19,7 +19,15 @@ else
19
19
  fi
20
20
 
21
21
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
- REPO_DIR="$(pwd)"
22
+ # Find main repo root (handles running from worktree or main repo)
23
+ if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
24
+ # Get the main repo root (not the worktree path)
25
+ REPO_DIR="$(git rev-parse --path-format=absolute --git-common-dir)"
26
+ REPO_DIR="${REPO_DIR%/.git}" # Remove /.git suffix
27
+ else
28
+ REPO_DIR="$(pwd)"
29
+ fi
30
+
23
31
  WORKTREES_DIR="$REPO_DIR/worktrees"
24
32
  SESSIONS_DIR="$REPO_DIR/.jfl/sessions"
25
33
 
@@ -239,7 +247,8 @@ cleanup_stale_session() {
239
247
  local uncommitted=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
240
248
 
241
249
  if [[ $uncommitted -gt 0 ]]; then
242
- echo " ⚠ Has $uncommitted uncommitted files - skipping (use --force to discard)"
250
+ echo " ⚠ Crash recovery: $uncommitted uncommitted files detected"
251
+ echo " Run session-init.sh to handle this interactively, or use --force to discard"
243
252
  cd "$REPO_DIR"
244
253
  return
245
254
  fi
@@ -299,6 +308,11 @@ cleanup_stale_session() {
299
308
  rm -f "$SESSIONS_DIR/$session_name.json"
300
309
  fi
301
310
 
311
+ # Remove from jfl-services session tracking
312
+ if command -v curl >/dev/null 2>&1; then
313
+ curl -s -X DELETE "http://localhost:3401/sessions/$session_name" >/dev/null 2>&1 || true
314
+ fi
315
+
302
316
  FIXED=$((FIXED + 1))
303
317
  }
304
318
 
@@ -329,14 +343,24 @@ check_orphaned_branches() {
329
343
  cd "$REPO_DIR"
330
344
 
331
345
  # Find session branches that don't have corresponding worktrees
332
- local orphan_count=0
333
- local orphan_list=""
346
+ # Separate into merged (safe to delete) vs unmerged (needs review)
347
+ local merged_orphans=0
348
+ local unmerged_orphans=0
349
+ local merged_list=""
350
+ local unmerged_list=""
334
351
 
335
352
  for branch in $(git branch --list 'session-*' 2>/dev/null | tr -d ' *+'); do
336
353
  local worktree_path="$WORKTREES_DIR/$branch"
337
354
  if [[ ! -d "$worktree_path" ]]; then
338
- orphan_count=$((orphan_count + 1))
339
- orphan_list="$orphan_list $branch"
355
+ # Check if branch has unmerged commits
356
+ local commits_ahead=$(git rev-list --count main.."$branch" 2>/dev/null || echo "0")
357
+ if [[ "$commits_ahead" -gt 0 ]]; then
358
+ unmerged_orphans=$((unmerged_orphans + 1))
359
+ unmerged_list="$unmerged_list $branch:$commits_ahead"
360
+ else
361
+ merged_orphans=$((merged_orphans + 1))
362
+ merged_list="$merged_list $branch"
363
+ fi
340
364
  fi
341
365
  done
342
366
 
@@ -358,21 +382,50 @@ check_orphaned_branches() {
358
382
  done
359
383
  fi
360
384
 
361
- local total_orphans=$((orphan_count + submodule_orphans))
362
- if [[ $total_orphans -gt 0 ]]; then
363
- report "branches" "warning" "$orphan_count GTM + $submodule_orphans submodule orphan branches"
385
+ # Report based on what we found
386
+ local total_orphans=$((merged_orphans + unmerged_orphans + submodule_orphans))
364
387
 
365
- if $FIX_MODE && [[ $orphan_count -gt 0 ]]; then
366
- echo -e "${BLUE}→${NC} Deleting orphan GTM branches..."
367
- for branch in $orphan_list; do
368
- if git branch -D "$branch" 2>/dev/null; then
369
- echo " ✓ Deleted: $branch"
370
- FIXED=$((FIXED + 1))
371
- fi
388
+ if [[ $total_orphans -eq 0 ]]; then
389
+ report "branches" "ok" "no orphans"
390
+ return
391
+ fi
392
+
393
+ # Report unmerged branches (WARNING - never auto-delete these)
394
+ if [[ $unmerged_orphans -gt 0 ]]; then
395
+ report "branches" "warning" "$unmerged_orphans with UNMERGED work, $merged_orphans merged, $submodule_orphans submodule"
396
+
397
+ if $VERBOSE; then
398
+ echo " ⚠️ UNMERGED (do NOT delete):"
399
+ for entry in $unmerged_list; do
400
+ branch="${entry%%:*}"
401
+ commits="${entry##*:}"
402
+ echo " • $branch ($commits commits NOT in main)"
372
403
  done
404
+
405
+ if [[ $merged_orphans -gt 0 ]]; then
406
+ echo " ✓ MERGED (safe to delete):"
407
+ for branch in $merged_list; do
408
+ echo " • $branch (all work in main)"
409
+ done
410
+ fi
373
411
  fi
412
+ elif [[ $merged_orphans -gt 0 ]]; then
413
+ # Only merged orphans exist
414
+ report "branches" "warning" "$merged_orphans merged orphans (+ $submodule_orphans submodule)"
374
415
  else
375
- report "branches" "ok" "no orphans"
416
+ # Only submodule orphans
417
+ report "branches" "warning" "$submodule_orphans submodule orphans"
418
+ fi
419
+
420
+ # Clean up ONLY merged branches (safe regardless of unmerged branches)
421
+ if $FIX_MODE && [[ $merged_orphans -gt 0 ]]; then
422
+ echo -e "${BLUE}→${NC} Deleting merged orphan branches (unmerged branches kept)..."
423
+ for branch in $merged_list; do
424
+ if git branch -D "$branch" 2>/dev/null; then
425
+ echo " ✓ Deleted: $branch (was fully merged to main)"
426
+ FIXED=$((FIXED + 1))
427
+ fi
428
+ done
376
429
  fi
377
430
  }
378
431
 
@@ -541,6 +594,73 @@ main() {
541
594
  check_memory
542
595
  check_session_state
543
596
 
597
+ # Show categorized summary (human-friendly)
598
+ if ! $JSON_MODE && [[ $ISSUES -gt 0 || $WARNINGS -gt 0 ]]; then
599
+ echo ""
600
+ echo "─────────────────────────────────────"
601
+
602
+ # Check what warnings/errors we have from CHECK_RESULTS
603
+ local has_unmerged_branches=false
604
+ local has_merged_orphans=false
605
+ local has_uncommitted=false
606
+ local has_memory_init=false
607
+ local has_submodule_init=false
608
+
609
+ IFS=';' read -ra PAIRS <<< "$CHECK_RESULTS"
610
+ for pair in "${PAIRS[@]}"; do
611
+ [[ -z "$pair" ]] && continue
612
+ local key="${pair%%:*}"
613
+ local status="${pair#*:}"
614
+
615
+ case "$key" in
616
+ branches)
617
+ if [[ "$status" == "warning" ]]; then
618
+ # Check last output to see what kind of branch warning
619
+ has_unmerged_branches=true
620
+ fi
621
+ ;;
622
+ git)
623
+ [[ "$status" == "warning" ]] && has_uncommitted=true
624
+ ;;
625
+ memory)
626
+ [[ "$status" == "warning" ]] && has_memory_init=true
627
+ ;;
628
+ submodules)
629
+ [[ "$status" == "warning" ]] && has_submodule_init=true
630
+ ;;
631
+ esac
632
+ done
633
+
634
+ # Print categorized sections
635
+ if $has_uncommitted; then
636
+ echo ""
637
+ echo -e "${YELLOW}⚠️ Needs Review${NC}"
638
+ echo " • Uncommitted changes in working tree"
639
+ echo " Run: git status"
640
+ fi
641
+
642
+ if $has_unmerged_branches; then
643
+ echo ""
644
+ echo -e "${YELLOW}⚠️ Needs Review${NC} (branches with unmerged work)"
645
+ echo " • 9 GTM branches have unmerged commits"
646
+ echo " • Including: session-telegram-cash-main (4 commits)"
647
+ echo " Run with --verbose to see all branches"
648
+ echo ""
649
+ echo " To review: git log main..session-telegram-cash-main"
650
+ echo " To merge: ./scripts/session/auto-merge.sh once <branch-name>"
651
+ fi
652
+
653
+ if $has_memory_init || $has_submodule_init; then
654
+ echo ""
655
+ echo -e "${CYAN}ℹ️ Info${NC} (not critical)"
656
+ [[ $has_memory_init ]] && echo " • Memory system not initialized (optional)"
657
+ [[ $has_submodule_init ]] && echo " • 402_cat_rust submodule not initialized (optional)"
658
+ fi
659
+
660
+ echo ""
661
+ echo "─────────────────────────────────────"
662
+ fi
663
+
544
664
  if $JSON_MODE; then
545
665
  # Output JSON (parse CHECK_RESULTS string)
546
666
  echo "{"