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,320 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Rigorous tests for session-sync.sh
4
+ # Tests both positive cases AND anti-tests (what should NOT happen)
5
+ #
6
+ # @purpose Test session-sync.sh before committing (work-loss prevention)
7
+
8
+ set -e
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ TEST_DIR="/tmp/jfl-session-sync-test-$$"
12
+ REPO_DIR="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || echo ".")"
13
+ REPO_DIR="${REPO_DIR%/.git}"
14
+
15
+ # Colors
16
+ RED='\033[0;31m'
17
+ GREEN='\033[0;32m'
18
+ YELLOW='\033[1;33m'
19
+ BLUE='\033[0;34m'
20
+ NC='\033[0m'
21
+
22
+ TESTS_PASSED=0
23
+ TESTS_FAILED=0
24
+
25
+ pass() {
26
+ echo -e "${GREEN}āœ“${NC} $1"
27
+ TESTS_PASSED=$((TESTS_PASSED + 1))
28
+ }
29
+
30
+ fail() {
31
+ echo -e "${RED}āœ—${NC} $1"
32
+ TESTS_FAILED=$((TESTS_FAILED + 1))
33
+ }
34
+
35
+ section() {
36
+ echo ""
37
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
38
+ echo -e "${BLUE}$1${NC}"
39
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
40
+ }
41
+
42
+ cleanup() {
43
+ rm -rf "$TEST_DIR" 2>/dev/null || true
44
+ }
45
+
46
+ trap cleanup EXIT
47
+
48
+ # ==============================================================================
49
+ # Test 1: Script Safety Checks
50
+ # ==============================================================================
51
+
52
+ test_safety_checks() {
53
+ section "Test 1: Safety Checks (prevent data loss)"
54
+
55
+ # Check for uncommitted changes protection
56
+ if grep -q "has uncommitted changes AND is behind" "$SCRIPT_DIR/session-sync.sh"; then
57
+ pass "Protects against pulling over uncommitted changes"
58
+ else
59
+ fail "No protection for uncommitted changes + pull"
60
+ fi
61
+
62
+ # Check that it uses 'set -e' for failure propagation
63
+ if head -10 "$SCRIPT_DIR/session-sync.sh" | grep -q "set -e"; then
64
+ pass "Uses 'set -e' for error propagation"
65
+ else
66
+ fail "Doesn't use 'set -e' - errors may be silent"
67
+ fi
68
+
69
+ # Check that it exits with error code on failure
70
+ if grep -q "exit 1" "$SCRIPT_DIR/session-sync.sh"; then
71
+ pass "Exits with error code on failure"
72
+ else
73
+ fail "Doesn't exit with error - CI/CD won't catch failures"
74
+ fi
75
+
76
+ # Anti-test: Verify it doesn't use --force flags
77
+ if grep -E "git pull.*--force|git reset --hard" "$SCRIPT_DIR/session-sync.sh" >/dev/null; then
78
+ fail "DANGER: Uses destructive git commands (--force, --hard)"
79
+ else
80
+ pass "Doesn't use destructive git commands"
81
+ fi
82
+
83
+ # Check for graceful network failure handling
84
+ if grep -q "Could not fetch.*no network" "$SCRIPT_DIR/session-sync.sh"; then
85
+ pass "Handles network failures gracefully"
86
+ else
87
+ fail "No graceful handling of network failures"
88
+ fi
89
+ }
90
+
91
+ # ==============================================================================
92
+ # Test 2: Detached HEAD Handling
93
+ # ==============================================================================
94
+
95
+ test_detached_head() {
96
+ section "Test 2: Detached HEAD Handling (submodules)"
97
+
98
+ # Check if script detects detached HEAD
99
+ if grep -q "detached HEAD state" "$SCRIPT_DIR/session-sync.sh"; then
100
+ pass "Detects detached HEAD state"
101
+ else
102
+ fail "Doesn't detect detached HEAD"
103
+ fi
104
+
105
+ # Check if it attempts to fix detached HEAD
106
+ if grep -A5 "detached HEAD" "$SCRIPT_DIR/session-sync.sh" | grep -q "checkout main"; then
107
+ pass "Attempts to fix detached HEAD automatically"
108
+ else
109
+ fail "Doesn't auto-fix detached HEAD"
110
+ fi
111
+
112
+ # Anti-test: Verify it doesn't force checkout (would lose work)
113
+ if grep -E "git checkout.*-f|git checkout.*--force" "$SCRIPT_DIR/session-sync.sh" >/dev/null; then
114
+ fail "DANGER: Uses force checkout (loses uncommitted work)"
115
+ else
116
+ pass "Doesn't use force checkout"
117
+ fi
118
+ }
119
+
120
+ # ==============================================================================
121
+ # Test 3: Submodule vs Symlink Detection
122
+ # ==============================================================================
123
+
124
+ test_product_detection() {
125
+ section "Test 3: Product Detection (submodule vs symlink)"
126
+
127
+ # Check for submodule detection (has .git FILE)
128
+ if grep -q "It's a submodule" "$SCRIPT_DIR/session-sync.sh"; then
129
+ pass "Detects submodules correctly (.git as file)"
130
+ else
131
+ fail "Doesn't detect submodules"
132
+ fi
133
+
134
+ # Check for symlink detection
135
+ if grep -q "\[ -L \"\$PRODUCT_PATH\" \]" "$SCRIPT_DIR/session-sync.sh"; then
136
+ pass "Detects symlinks correctly"
137
+ else
138
+ fail "Doesn't detect symlinks"
139
+ fi
140
+
141
+ # Check for missing product handling
142
+ if grep -q "Initializing product submodule" "$SCRIPT_DIR/session-sync.sh"; then
143
+ pass "Handles missing product gracefully"
144
+ else
145
+ fail "Doesn't handle missing product"
146
+ fi
147
+
148
+ # Check for symlink deprecation warning
149
+ if grep -q "product/ is a symlink, not a submodule" "$SCRIPT_DIR/session-sync.sh"; then
150
+ pass "Warns about legacy symlink usage"
151
+ else
152
+ fail "Doesn't warn about symlinks (legacy pattern)"
153
+ fi
154
+ }
155
+
156
+ # ==============================================================================
157
+ # Test 4: Failure Tracking
158
+ # ==============================================================================
159
+
160
+ test_failure_tracking() {
161
+ section "Test 4: Failure Tracking (exit codes)"
162
+
163
+ # Check that failures are tracked
164
+ if grep -q "FAILURES=0" "$SCRIPT_DIR/session-sync.sh"; then
165
+ pass "Initializes failure counter"
166
+ else
167
+ fail "Doesn't track failures"
168
+ fi
169
+
170
+ # Check that failures increment counter
171
+ if grep -q "FAILURES=\$((FAILURES + 1))" "$SCRIPT_DIR/session-sync.sh"; then
172
+ pass "Increments failure counter on errors"
173
+ else
174
+ fail "Doesn't increment failure counter"
175
+ fi
176
+
177
+ # Check that exit code reflects failures
178
+ if grep -A5 "if.*FAILURES.*-gt 0" "$SCRIPT_DIR/session-sync.sh" | grep -q "exit 1"; then
179
+ pass "Exits with code 1 when failures occur"
180
+ else
181
+ fail "Doesn't exit with error code on failures"
182
+ fi
183
+ }
184
+
185
+ # ==============================================================================
186
+ # Test 5: Integration with Current Repo
187
+ # ==============================================================================
188
+
189
+ test_current_repo_integration() {
190
+ section "Test 5: Integration with Current Repo"
191
+
192
+ cd "$REPO_DIR"
193
+
194
+ # Test that script runs without crashing
195
+ if "$SCRIPT_DIR/session-sync.sh" >/dev/null 2>&1; then
196
+ pass "Script runs successfully on current repo"
197
+ else
198
+ exit_code=$?
199
+ if [[ $exit_code -eq 1 ]]; then
200
+ # Check if failure was due to uncommitted changes (safe failure)
201
+ output=$("$SCRIPT_DIR/session-sync.sh" 2>&1 || true)
202
+ if echo "$output" | grep -q "uncommitted changes"; then
203
+ pass "Script correctly fails on uncommitted changes"
204
+ else
205
+ fail "Script failed for unknown reason (exit code 1)"
206
+ fi
207
+ else
208
+ fail "Script crashed with exit code $exit_code"
209
+ fi
210
+ fi
211
+
212
+ # Test that it doesn't modify uncommitted changes
213
+ before_status=$(git status --porcelain)
214
+ "$SCRIPT_DIR/session-sync.sh" >/dev/null 2>&1 || true
215
+ after_status=$(git status --porcelain)
216
+
217
+ if [[ "$before_status" == "$after_status" ]]; then
218
+ pass "Doesn't modify uncommitted changes"
219
+ else
220
+ fail "DANGER: Modified uncommitted changes!"
221
+ fi
222
+ }
223
+
224
+ # ==============================================================================
225
+ # Test 6: Behind/Ahead Detection
226
+ # ==============================================================================
227
+
228
+ test_behind_ahead_detection() {
229
+ section "Test 6: Behind/Ahead Detection"
230
+
231
+ # Check for behind detection
232
+ if grep -q "commits behind origin" "$SCRIPT_DIR/session-sync.sh"; then
233
+ pass "Detects when repo is behind origin"
234
+ else
235
+ fail "Doesn't detect behind status"
236
+ fi
237
+
238
+ # Check for ahead detection
239
+ if grep -q "commits ahead" "$SCRIPT_DIR/session-sync.sh"; then
240
+ pass "Detects when repo is ahead (unpushed)"
241
+ else
242
+ fail "Doesn't detect ahead status"
243
+ fi
244
+
245
+ # Check for up-to-date message
246
+ if grep -q "is up to date" "$SCRIPT_DIR/session-sync.sh"; then
247
+ pass "Reports when repo is up to date"
248
+ else
249
+ fail "Doesn't report up-to-date status"
250
+ fi
251
+ }
252
+
253
+ # ==============================================================================
254
+ # Test 7: Recursive Submodule Update
255
+ # ==============================================================================
256
+
257
+ test_recursive_submodules() {
258
+ section "Test 7: Recursive Submodule Handling"
259
+
260
+ # Check for recursive submodule update
261
+ if grep -q "submodule update.*--recursive" "$SCRIPT_DIR/session-sync.sh"; then
262
+ pass "Updates submodules recursively"
263
+ else
264
+ fail "Doesn't update nested submodules"
265
+ fi
266
+
267
+ # Check for --init flag (initializes new submodules)
268
+ if grep -q "submodule update --init" "$SCRIPT_DIR/session-sync.sh"; then
269
+ pass "Initializes new submodules automatically"
270
+ else
271
+ fail "Doesn't initialize new submodules"
272
+ fi
273
+ }
274
+
275
+ # ==============================================================================
276
+ # Run All Tests
277
+ # ==============================================================================
278
+
279
+ main() {
280
+ echo ""
281
+ echo "╔══════════════════════════════════════════════════════════╗"
282
+ echo "ā•‘ session-sync.sh Rigorous Testing ā•‘"
283
+ echo "ā•‘ Before Commit Verification ā•‘"
284
+ echo "ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•"
285
+
286
+ test_safety_checks
287
+ test_detached_head
288
+ test_product_detection
289
+ test_failure_tracking
290
+ test_current_repo_integration
291
+ test_behind_ahead_detection
292
+ test_recursive_submodules
293
+
294
+ # Summary
295
+ echo ""
296
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
297
+ echo -e "${BLUE}Test Results${NC}"
298
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
299
+ echo -e "${GREEN}Passed:${NC} $TESTS_PASSED"
300
+ if [[ $TESTS_FAILED -gt 0 ]]; then
301
+ echo -e "${RED}Failed:${NC} $TESTS_FAILED"
302
+ echo ""
303
+ echo -e "${RED}session-sync.sh NOT READY TO COMMIT${NC}"
304
+ exit 1
305
+ else
306
+ echo ""
307
+ echo -e "${GREEN}āœ“ session-sync.sh ready to commit${NC}"
308
+ echo ""
309
+ echo "Safety verified:"
310
+ echo " • Won't pull over uncommitted changes"
311
+ echo " • Exits with error on failure"
312
+ echo " • Handles network failures gracefully"
313
+ echo " • No destructive operations"
314
+ echo " • Detached HEAD auto-fix"
315
+ echo " • Recursive submodule updates"
316
+ exit 0
317
+ fi
318
+ }
319
+
320
+ main "$@"
@@ -11,7 +11,41 @@ VAD_MODEL="$MODELS_DIR/ggml-silero-vad.bin"
11
11
  SOCKET_PATH="$JFL_DIR/voice.sock"
12
12
  TOKEN_PATH="$JFL_DIR/voice-server.token"
13
13
  PID_FILE="$JFL_DIR/voice-server.pid"
14
- WHISPER_SERVER="/Users/alectaggart/CascadeProjects/jfl-platform/packages/whisper-server/build/whisper-stream-server"
14
+
15
+ # Detect whisper server location
16
+ if [[ -n "$WHISPER_SERVER_PATH" ]]; then
17
+ WHISPER_SERVER="$WHISPER_SERVER_PATH"
18
+ else
19
+ # Auto-detect based on project structure
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ PROJECT_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "")"
22
+
23
+ # Common locations to check
24
+ POSSIBLE_PATHS=(
25
+ "$PROJECT_ROOT/../jfl-platform/packages/whisper-server/build/whisper-stream-server"
26
+ "$PROJECT_ROOT/packages/whisper-server/build/whisper-stream-server"
27
+ "$HOME/code/goose/jfl/jfl-platform/packages/whisper-server/build/whisper-stream-server"
28
+ )
29
+
30
+ for path in "${POSSIBLE_PATHS[@]}"; do
31
+ if [[ -x "$path" ]]; then
32
+ WHISPER_SERVER="$path"
33
+ break
34
+ fi
35
+ done
36
+
37
+ if [[ -z "$WHISPER_SERVER" || ! -x "$WHISPER_SERVER" ]]; then
38
+ echo -e "${RED}āœ— Whisper server not found${NC}"
39
+ echo -e "${GRAY} Tried locations:${NC}"
40
+ for path in "${POSSIBLE_PATHS[@]}"; do
41
+ echo -e "${GRAY} - $path${NC}"
42
+ done
43
+ echo ""
44
+ echo -e "${GRAY} Set WHISPER_SERVER_PATH environment variable or ensure jfl-platform is at ../jfl-platform${NC}"
45
+ echo -e "${GRAY} Or build the server: cd jfl-platform/packages/whisper-server && ./build.sh${NC}"
46
+ exit 1
47
+ fi
48
+ fi
15
49
 
16
50
  # Colors
17
51
  RED='\033[0;31m'
@@ -21,15 +55,9 @@ GRAY='\033[0;90m'
21
55
  NC='\033[0m'
22
56
 
23
57
  echo -e "${GREEN}šŸŽ¤ JFL Voice - Starting${NC}"
58
+ echo -e "${GRAY}Using whisper server: $WHISPER_SERVER${NC}"
24
59
  echo ""
25
60
 
26
- # Check if server binary exists
27
- if [ ! -f "$WHISPER_SERVER" ]; then
28
- echo -e "${RED}āœ— Whisper server not built${NC}"
29
- echo -e "${GRAY} Run: cd product/packages/whisper-server && ./build.sh${NC}"
30
- exit 1
31
- fi
32
-
33
61
  # Check if models exist
34
62
  if [ ! -f "$WHISPER_MODEL" ]; then
35
63
  echo -e "${YELLOW}⚠ Whisper model not found. Downloading...${NC}"
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # where-am-i.sh - Quick context check for git operations
4
+ #
5
+ # Shows:
6
+ # - Current directory
7
+ # - Which repo you're in (GTM or product submodule)
8
+ # - Current branch
9
+ # - Uncommitted changes
10
+ #
11
+ # Usage:
12
+ # ./scripts/where-am-i.sh
13
+
14
+ set -e
15
+
16
+ CWD=$(pwd)
17
+
18
+ # Colors
19
+ BLUE='\033[0;34m'
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ NC='\033[0m'
23
+
24
+ echo ""
25
+ echo -e "${BLUE}šŸ“ Current Location${NC}"
26
+ echo "─────────────────────────────────────"
27
+ echo ""
28
+
29
+ # Show current directory
30
+ echo -e "Directory: ${GREEN}$CWD${NC}"
31
+
32
+ # Detect which repo context (check for submodules first, then GTM)
33
+ REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
34
+
35
+ if [[ "$CWD" == *"/product"* ]] || [[ "$REMOTE_URL" == *"jfl-platform"* ]]; then
36
+ echo -e "Context: ${YELLOW}product submodule${NC} (jfl-platform)"
37
+ echo ""
38
+ echo "To commit here: ./scripts/commit-product.sh \"message\""
39
+ elif [[ "$CWD" == *"/runner"* ]] || [[ "$REMOTE_URL" == *"jfl-runner"* ]]; then
40
+ echo -e "Context: ${YELLOW}runner submodule${NC} (jfl-runner)"
41
+ echo ""
42
+ echo "To commit here: cd ../; git add runner && git commit -m \"Update runner submodule\""
43
+ elif [[ "$REMOTE_URL" == *"JFL-GTM"* ]] || [[ -f ".jfl/config.json" ]]; then
44
+ echo -e "Context: ${GREEN}GTM repo${NC} (main project)"
45
+ echo ""
46
+ echo "To commit here: ./scripts/commit-gtm.sh \"message\""
47
+ else
48
+ # Check if we're in any submodule
49
+ if git rev-parse --show-superproject-working-tree &>/dev/null; then
50
+ SUBMODULE_NAME=$(basename "$CWD")
51
+ echo -e "Context: ${YELLOW}${SUBMODULE_NAME} submodule${NC}"
52
+ else
53
+ echo -e "Context: ${YELLOW}unknown${NC}"
54
+ fi
55
+ fi
56
+
57
+ echo ""
58
+
59
+ # Show current branch
60
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "detached HEAD")
61
+ if [[ "$BRANCH" == "detached HEAD" ]]; then
62
+ echo -e "Branch: ${YELLOW}āš ļø detached HEAD${NC}"
63
+ echo " (run: git checkout main)"
64
+ else
65
+ echo -e "Branch: ${GREEN}$BRANCH${NC}"
66
+ fi
67
+
68
+ # Show uncommitted changes
69
+ CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
70
+ if [[ "$CHANGES" -gt 0 ]]; then
71
+ echo -e "Changes: ${YELLOW}$CHANGES uncommitted${NC}"
72
+ echo ""
73
+ git status --short
74
+ else
75
+ echo -e "Changes: ${GREEN}none (clean)${NC}"
76
+ fi
77
+
78
+ echo ""
@@ -0,0 +1,32 @@
1
+ {
2
+ "claudeMdPath": "CLAUDE.md",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "matcher": "",
7
+ "hooks": [
8
+ {
9
+ "type": "command",
10
+ "command": "echo '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n Service Agent Session\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n' && SERVICE_NAME=$(jq -r '.name // \"unknown\"' .jfl/config.json 2>/dev/null || echo 'unknown') && echo \" Service: $SERVICE_NAME\" && echo '' && if [ -f .jfl/status.json ]; then echo 'Status:' && cat .jfl/status.json | jq -r '\" \" + (.status // \"unknown\")'; fi && echo '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n Validating configuration...\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n' && if command -v jfl >/dev/null 2>&1; then jfl services validate 2>&1 | grep -E '^\\[|^Summary:' || echo ' (validation skipped - jfl not in PATH)'; else echo ' (validation skipped - jfl not installed)'; fi && echo '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n Ready to work\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'"
11
+ },
12
+ {
13
+ "type": "command",
14
+ "command": "if command -v jfl >/dev/null 2>&1; then jfl services sync-agents --current >> .jfl/logs/peer-sync.log 2>&1 & fi",
15
+ "async": true
16
+ }
17
+ ]
18
+ }
19
+ ],
20
+ "Stop": [
21
+ {
22
+ "matcher": "",
23
+ "hooks": [
24
+ {
25
+ "type": "command",
26
+ "command": "SESSION=$(git branch --show-current 2>/dev/null || echo 'main') && if [ -d .jfl/journal ] && [ $(ls -1 .jfl/journal/*.jsonl 2>/dev/null | wc -l) -eq 0 ]; then echo 'āš ļø WARNING: No journal entry for this session. Service work should be documented.'; fi && if [ -f .jfl/status.json ]; then jq --arg ts \"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\" '.last_updated = $ts' .jfl/status.json > .jfl/status.json.tmp && mv .jfl/status.json.tmp .jfl/status.json; fi"
27
+ }
28
+ ]
29
+ }
30
+ ]
31
+ }
32
+ }
@@ -2,6 +2,7 @@
2
2
  "hooks": {
3
3
  "SessionStart": [
4
4
  {
5
+ "matcher": "",
5
6
  "hooks": [
6
7
  {
7
8
  "type": "command",
@@ -43,6 +44,16 @@
43
44
  "command": "if echo \"$TOOL_INPUT\" | grep -q '\"status\":\\s*\"completed\"'; then BRANCH=$(cat .jfl/current-session-branch.txt 2>/dev/null || git branch --show-current); echo ''; echo '═══════════════════════════════════════════════════════════'; echo 'šŸ“ JOURNAL REQUIRED: Task completed'; echo '═══════════════════════════════════════════════════════════'; echo 'WRITE JOURNAL ENTRY NOW. File: .jfl/journal/'\"${BRANCH}\"'.jsonl'; echo '═══════════════════════════════════════════════════════════'; fi"
44
45
  }
45
46
  ]
47
+ },
48
+ {
49
+ "matcher": "Write",
50
+ "hooks": [
51
+ {
52
+ "type": "command",
53
+ "command": "FILE=$(echo \"$TOOL_INPUT\" | grep -oE '\"file_path\":\\s*\"[^\"]+\"' | head -1 | sed 's/.*\"\\([^\"]*\\)\"/\\1/'); if echo \"$FILE\" | grep -q '\\.jfl/inbox/service-update-.*\\.trigger'; then echo ''; echo ''; echo '═══════════════════════════════════════════════════════════'; echo 'šŸ“” SERVICE UPDATE DETECTED'; echo '═══════════════════════════════════════════════════════════'; jfl gtm process-service-update 2>/dev/null || echo 'GTM command not available'; fi",
54
+ "async": true
55
+ }
56
+ ]
46
57
  }
47
58
  ],
48
59
  "UserPromptSubmit": [
@@ -58,6 +69,7 @@
58
69
  ],
59
70
  "Stop": [
60
71
  {
72
+ "matcher": "",
61
73
  "hooks": [
62
74
  {
63
75
  "type": "command",
@@ -69,13 +81,14 @@
69
81
  },
70
82
  {
71
83
  "type": "command",
72
- "command": "./scripts/session/session-end.sh 2>&1 || (git add -A && git diff --cached --quiet || git commit -m 'auto: stop save') 2>/dev/null; echo 'āœ“ Session ended'; exit 0"
84
+ "command": "./scripts/session/session-cleanup.sh >> .jfl/logs/session-cleanup.log 2>&1 || echo 'Cleanup skipped'; exit 0"
73
85
  }
74
86
  ]
75
87
  }
76
88
  ],
77
89
  "PreCompact": [
78
90
  {
91
+ "matcher": "",
79
92
  "hooks": [
80
93
  {
81
94
  "type": "command",