jfl 0.0.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 (381) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +313 -0
  3. package/clawdbot-skill/README.md +328 -0
  4. package/clawdbot-skill/SKILL.md +362 -0
  5. package/clawdbot-skill/index.ts +486 -0
  6. package/clawdbot-skill/package.json +28 -0
  7. package/clawdbot-skill/skill.json +28 -0
  8. package/dist/commands/agents.d.ts +5 -0
  9. package/dist/commands/agents.d.ts.map +1 -0
  10. package/dist/commands/agents.js +399 -0
  11. package/dist/commands/agents.js.map +1 -0
  12. package/dist/commands/context-hub.d.ts +12 -0
  13. package/dist/commands/context-hub.d.ts.map +1 -0
  14. package/dist/commands/context-hub.js +642 -0
  15. package/dist/commands/context-hub.js.map +1 -0
  16. package/dist/commands/deploy.d.ts +5 -0
  17. package/dist/commands/deploy.d.ts.map +1 -0
  18. package/dist/commands/deploy.js +370 -0
  19. package/dist/commands/deploy.js.map +1 -0
  20. package/dist/commands/feedback.d.ts +2 -0
  21. package/dist/commands/feedback.d.ts.map +1 -0
  22. package/dist/commands/feedback.js +178 -0
  23. package/dist/commands/feedback.js.map +1 -0
  24. package/dist/commands/hud.d.ts +4 -0
  25. package/dist/commands/hud.d.ts.map +1 -0
  26. package/dist/commands/hud.js +262 -0
  27. package/dist/commands/hud.js.map +1 -0
  28. package/dist/commands/init.d.ts +4 -0
  29. package/dist/commands/init.d.ts.map +1 -0
  30. package/dist/commands/init.js +553 -0
  31. package/dist/commands/init.js.map +1 -0
  32. package/dist/commands/login.d.ts +23 -0
  33. package/dist/commands/login.d.ts.map +1 -0
  34. package/dist/commands/login.js +818 -0
  35. package/dist/commands/login.js.map +1 -0
  36. package/dist/commands/ralph.d.ts +9 -0
  37. package/dist/commands/ralph.d.ts.map +1 -0
  38. package/dist/commands/ralph.js +67 -0
  39. package/dist/commands/ralph.js.map +1 -0
  40. package/dist/commands/repair.d.ts +7 -0
  41. package/dist/commands/repair.d.ts.map +1 -0
  42. package/dist/commands/repair.js +283 -0
  43. package/dist/commands/repair.js.map +1 -0
  44. package/dist/commands/session-mgmt.d.ts +33 -0
  45. package/dist/commands/session-mgmt.d.ts.map +1 -0
  46. package/dist/commands/session-mgmt.js +404 -0
  47. package/dist/commands/session-mgmt.js.map +1 -0
  48. package/dist/commands/session.d.ts +2 -0
  49. package/dist/commands/session.d.ts.map +1 -0
  50. package/dist/commands/session.js +639 -0
  51. package/dist/commands/session.js.map +1 -0
  52. package/dist/commands/skills.d.ts +31 -0
  53. package/dist/commands/skills.d.ts.map +1 -0
  54. package/dist/commands/skills.js +314 -0
  55. package/dist/commands/skills.js.map +1 -0
  56. package/dist/commands/status.d.ts +2 -0
  57. package/dist/commands/status.d.ts.map +1 -0
  58. package/dist/commands/status.js +127 -0
  59. package/dist/commands/status.js.map +1 -0
  60. package/dist/commands/synopsis.d.ts +10 -0
  61. package/dist/commands/synopsis.d.ts.map +1 -0
  62. package/dist/commands/synopsis.js +277 -0
  63. package/dist/commands/synopsis.js.map +1 -0
  64. package/dist/commands/update.d.ts +10 -0
  65. package/dist/commands/update.d.ts.map +1 -0
  66. package/dist/commands/update.js +165 -0
  67. package/dist/commands/update.js.map +1 -0
  68. package/dist/commands/voice.d.ts +410 -0
  69. package/dist/commands/voice.d.ts.map +1 -0
  70. package/dist/commands/voice.js +4763 -0
  71. package/dist/commands/voice.js.map +1 -0
  72. package/dist/index.d.ts +9 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +512 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/mcp/context-hub-mcp.d.ts +11 -0
  77. package/dist/mcp/context-hub-mcp.d.ts.map +1 -0
  78. package/dist/mcp/context-hub-mcp.js +548 -0
  79. package/dist/mcp/context-hub-mcp.js.map +1 -0
  80. package/dist/telegram/voice.d.ts +146 -0
  81. package/dist/telegram/voice.d.ts.map +1 -0
  82. package/dist/telegram/voice.js +351 -0
  83. package/dist/telegram/voice.js.map +1 -0
  84. package/dist/types/skills.d.ts +44 -0
  85. package/dist/types/skills.d.ts.map +1 -0
  86. package/dist/types/skills.js +5 -0
  87. package/dist/types/skills.js.map +1 -0
  88. package/dist/ui/banner.d.ts +18 -0
  89. package/dist/ui/banner.d.ts.map +1 -0
  90. package/dist/ui/banner.js +323 -0
  91. package/dist/ui/banner.js.map +1 -0
  92. package/dist/ui/index.d.ts +8 -0
  93. package/dist/ui/index.d.ts.map +1 -0
  94. package/dist/ui/index.js +8 -0
  95. package/dist/ui/index.js.map +1 -0
  96. package/dist/ui/prompts.d.ts +52 -0
  97. package/dist/ui/prompts.d.ts.map +1 -0
  98. package/dist/ui/prompts.js +72 -0
  99. package/dist/ui/prompts.js.map +1 -0
  100. package/dist/ui/theme.d.ts +82 -0
  101. package/dist/ui/theme.d.ts.map +1 -0
  102. package/dist/ui/theme.js +142 -0
  103. package/dist/ui/theme.js.map +1 -0
  104. package/dist/utils/auth-guard.d.ts +66 -0
  105. package/dist/utils/auth-guard.d.ts.map +1 -0
  106. package/dist/utils/auth-guard.js +348 -0
  107. package/dist/utils/auth-guard.js.map +1 -0
  108. package/dist/utils/ensure-project.d.ts +11 -0
  109. package/dist/utils/ensure-project.d.ts.map +1 -0
  110. package/dist/utils/ensure-project.js +70 -0
  111. package/dist/utils/ensure-project.js.map +1 -0
  112. package/dist/utils/git.d.ts +73 -0
  113. package/dist/utils/git.d.ts.map +1 -0
  114. package/dist/utils/git.js +219 -0
  115. package/dist/utils/git.js.map +1 -0
  116. package/dist/utils/github-auth.d.ts +54 -0
  117. package/dist/utils/github-auth.d.ts.map +1 -0
  118. package/dist/utils/github-auth.js +375 -0
  119. package/dist/utils/github-auth.js.map +1 -0
  120. package/dist/utils/github-repo.d.ts +30 -0
  121. package/dist/utils/github-repo.d.ts.map +1 -0
  122. package/dist/utils/github-repo.js +219 -0
  123. package/dist/utils/github-repo.js.map +1 -0
  124. package/dist/utils/platform-auth.d.ts +81 -0
  125. package/dist/utils/platform-auth.d.ts.map +1 -0
  126. package/dist/utils/platform-auth.js +191 -0
  127. package/dist/utils/platform-auth.js.map +1 -0
  128. package/dist/utils/project-config.d.ts +43 -0
  129. package/dist/utils/project-config.d.ts.map +1 -0
  130. package/dist/utils/project-config.js +97 -0
  131. package/dist/utils/project-config.js.map +1 -0
  132. package/dist/utils/skill-registry.d.ts +49 -0
  133. package/dist/utils/skill-registry.d.ts.map +1 -0
  134. package/dist/utils/skill-registry.js +192 -0
  135. package/dist/utils/skill-registry.js.map +1 -0
  136. package/dist/utils/wallet.d.ts +62 -0
  137. package/dist/utils/wallet.d.ts.map +1 -0
  138. package/dist/utils/wallet.js +252 -0
  139. package/dist/utils/wallet.js.map +1 -0
  140. package/dist/utils/x402-client.d.ts +86 -0
  141. package/dist/utils/x402-client.d.ts.map +1 -0
  142. package/dist/utils/x402-client.js +265 -0
  143. package/dist/utils/x402-client.js.map +1 -0
  144. package/package.json +76 -0
  145. package/scripts/postinstall.js +116 -0
  146. package/scripts/test-onboarding.sh +121 -0
  147. package/scripts/voice-start.sh +128 -0
  148. package/scripts/voice-stop.sh +33 -0
  149. package/template/.claude/settings.json +92 -0
  150. package/template/.claude/skills/agent-browser/SKILL.md +116 -0
  151. package/template/.claude/skills/brand-architect/SKILL.md +240 -0
  152. package/template/.claude/skills/brand-architect/config.yaml +137 -0
  153. package/template/.claude/skills/campaign-hud/config.yaml +112 -0
  154. package/template/.claude/skills/content-creator/SKILL.md +294 -0
  155. package/template/.claude/skills/debug/MULTI_AGENT.md +360 -0
  156. package/template/.claude/skills/debug/SKILL.md +549 -0
  157. package/template/.claude/skills/fly-deploy/SKILL.md +676 -0
  158. package/template/.claude/skills/founder-video/SKILL.md +467 -0
  159. package/template/.claude/skills/hud/SKILL.md +157 -0
  160. package/template/.claude/skills/ralph-tui/SKILL.md +210 -0
  161. package/template/.claude/skills/react-best-practices/AGENTS.md +2249 -0
  162. package/template/.claude/skills/react-best-practices/README.md +123 -0
  163. package/template/.claude/skills/react-best-practices/SKILL.md +125 -0
  164. package/template/.claude/skills/react-best-practices/metadata.json +15 -0
  165. package/template/.claude/skills/react-best-practices/rules/_sections.md +46 -0
  166. package/template/.claude/skills/react-best-practices/rules/_template.md +28 -0
  167. package/template/.claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  168. package/template/.claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  169. package/template/.claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
  170. package/template/.claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
  171. package/template/.claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
  172. package/template/.claude/skills/react-best-practices/rules/async-parallel.md +28 -0
  173. package/template/.claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  174. package/template/.claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  175. package/template/.claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  176. package/template/.claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  177. package/template/.claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  178. package/template/.claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
  179. package/template/.claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  180. package/template/.claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  181. package/template/.claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  182. package/template/.claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  183. package/template/.claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  184. package/template/.claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  185. package/template/.claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  186. package/template/.claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
  187. package/template/.claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  188. package/template/.claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
  189. package/template/.claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  190. package/template/.claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  191. package/template/.claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  192. package/template/.claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  193. package/template/.claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
  194. package/template/.claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  195. package/template/.claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  196. package/template/.claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  197. package/template/.claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  198. package/template/.claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  199. package/template/.claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  200. package/template/.claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  201. package/template/.claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  202. package/template/.claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  203. package/template/.claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  204. package/template/.claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  205. package/template/.claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
  206. package/template/.claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  207. package/template/.claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  208. package/template/.claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  209. package/template/.claude/skills/react-best-practices/rules/server-cache-react.md +26 -0
  210. package/template/.claude/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
  211. package/template/.claude/skills/react-best-practices/rules/server-serialization.md +38 -0
  212. package/template/.claude/skills/remotion-best-practices/SKILL.md +43 -0
  213. package/template/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
  214. package/template/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
  215. package/template/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  216. package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  217. package/template/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  218. package/template/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
  219. package/template/.claude/skills/remotion-best-practices/rules/audio.md +172 -0
  220. package/template/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  221. package/template/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
  222. package/template/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
  223. package/template/.claude/skills/remotion-best-practices/rules/compositions.md +146 -0
  224. package/template/.claude/skills/remotion-best-practices/rules/display-captions.md +126 -0
  225. package/template/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  226. package/template/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
  227. package/template/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  228. package/template/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  229. package/template/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  230. package/template/.claude/skills/remotion-best-practices/rules/gifs.md +138 -0
  231. package/template/.claude/skills/remotion-best-practices/rules/images.md +130 -0
  232. package/template/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  233. package/template/.claude/skills/remotion-best-practices/rules/lottie.md +68 -0
  234. package/template/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  235. package/template/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  236. package/template/.claude/skills/remotion-best-practices/rules/sequencing.md +106 -0
  237. package/template/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
  238. package/template/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
  239. package/template/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
  240. package/template/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  241. package/template/.claude/skills/remotion-best-practices/rules/transitions.md +122 -0
  242. package/template/.claude/skills/remotion-best-practices/rules/trimming.md +53 -0
  243. package/template/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
  244. package/template/.claude/skills/search/SKILL.md +220 -0
  245. package/template/.claude/skills/spec/SKILL.md +377 -0
  246. package/template/.claude/skills/startup/SKILL.md +310 -0
  247. package/template/.claude/skills/web-architect/SKILL.md +309 -0
  248. package/template/.claude/skills/x-algorithm/SKILL.md +305 -0
  249. package/template/.jfl/config.json +8 -0
  250. package/template/.mcp.json +11 -0
  251. package/template/CLAUDE.md +960 -0
  252. package/template/content/.gitkeep +0 -0
  253. package/template/context-hub +3 -0
  254. package/template/knowledge/BRAND_BRIEF.md +124 -0
  255. package/template/knowledge/BRAND_DECISIONS.md +168 -0
  256. package/template/knowledge/NARRATIVE.md +114 -0
  257. package/template/knowledge/ROADMAP.md +128 -0
  258. package/template/knowledge/THESIS.md +108 -0
  259. package/template/knowledge/VISION.md +74 -0
  260. package/template/knowledge/VOICE_AND_TONE.md +146 -0
  261. package/template/previews/.gitkeep +0 -0
  262. package/template/scripts/session/auto-commit.sh +245 -0
  263. package/template/scripts/session/auto-merge.sh +325 -0
  264. package/template/scripts/session/jfl-doctor.sh +587 -0
  265. package/template/scripts/session/session-end.sh +194 -0
  266. package/template/scripts/session/session-init.sh +163 -0
  267. package/template/scripts/session/session-sync.sh +167 -0
  268. package/template/scripts/session/test-context-preservation.sh +160 -0
  269. package/template/skills/agent-browser/SKILL.md +116 -0
  270. package/template/skills/brand-architect/SKILL.md +240 -0
  271. package/template/skills/brand-architect/config.yaml +137 -0
  272. package/template/skills/campaign-hud/config.yaml +112 -0
  273. package/template/skills/content-creator/SKILL.md +294 -0
  274. package/template/skills/debug/MULTI_AGENT.md +360 -0
  275. package/template/skills/debug/SKILL.md +549 -0
  276. package/template/skills/fly-deploy/SKILL.md +676 -0
  277. package/template/skills/founder-video/SKILL.md +467 -0
  278. package/template/skills/hud/SKILL.md +204 -0
  279. package/template/skills/ralph-tui/SKILL.md +210 -0
  280. package/template/skills/react-best-practices/AGENTS.md +2249 -0
  281. package/template/skills/react-best-practices/README.md +123 -0
  282. package/template/skills/react-best-practices/SKILL.md +125 -0
  283. package/template/skills/react-best-practices/metadata.json +15 -0
  284. package/template/skills/react-best-practices/rules/_sections.md +46 -0
  285. package/template/skills/react-best-practices/rules/_template.md +28 -0
  286. package/template/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  287. package/template/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  288. package/template/skills/react-best-practices/rules/async-api-routes.md +38 -0
  289. package/template/skills/react-best-practices/rules/async-defer-await.md +80 -0
  290. package/template/skills/react-best-practices/rules/async-dependencies.md +36 -0
  291. package/template/skills/react-best-practices/rules/async-parallel.md +28 -0
  292. package/template/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  293. package/template/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  294. package/template/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  295. package/template/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  296. package/template/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  297. package/template/skills/react-best-practices/rules/bundle-preload.md +50 -0
  298. package/template/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  299. package/template/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  300. package/template/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  301. package/template/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  302. package/template/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  303. package/template/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  304. package/template/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  305. package/template/skills/react-best-practices/rules/js-early-exit.md +50 -0
  306. package/template/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  307. package/template/skills/react-best-practices/rules/js-index-maps.md +37 -0
  308. package/template/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  309. package/template/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  310. package/template/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  311. package/template/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  312. package/template/skills/react-best-practices/rules/rendering-activity.md +26 -0
  313. package/template/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  314. package/template/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  315. package/template/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  316. package/template/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  317. package/template/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  318. package/template/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  319. package/template/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  320. package/template/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  321. package/template/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  322. package/template/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  323. package/template/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  324. package/template/skills/react-best-practices/rules/rerender-memo.md +44 -0
  325. package/template/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  326. package/template/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  327. package/template/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  328. package/template/skills/react-best-practices/rules/server-cache-react.md +26 -0
  329. package/template/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
  330. package/template/skills/react-best-practices/rules/server-serialization.md +38 -0
  331. package/template/skills/remotion-best-practices/SKILL.md +43 -0
  332. package/template/skills/remotion-best-practices/rules/3d.md +86 -0
  333. package/template/skills/remotion-best-practices/rules/animations.md +29 -0
  334. package/template/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  335. package/template/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  336. package/template/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  337. package/template/skills/remotion-best-practices/rules/assets.md +78 -0
  338. package/template/skills/remotion-best-practices/rules/audio.md +172 -0
  339. package/template/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  340. package/template/skills/remotion-best-practices/rules/can-decode.md +75 -0
  341. package/template/skills/remotion-best-practices/rules/charts.md +58 -0
  342. package/template/skills/remotion-best-practices/rules/compositions.md +146 -0
  343. package/template/skills/remotion-best-practices/rules/display-captions.md +126 -0
  344. package/template/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  345. package/template/skills/remotion-best-practices/rules/fonts.md +152 -0
  346. package/template/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  347. package/template/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  348. package/template/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  349. package/template/skills/remotion-best-practices/rules/gifs.md +138 -0
  350. package/template/skills/remotion-best-practices/rules/images.md +130 -0
  351. package/template/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  352. package/template/skills/remotion-best-practices/rules/lottie.md +68 -0
  353. package/template/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  354. package/template/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  355. package/template/skills/remotion-best-practices/rules/sequencing.md +106 -0
  356. package/template/skills/remotion-best-practices/rules/tailwind.md +11 -0
  357. package/template/skills/remotion-best-practices/rules/text-animations.md +20 -0
  358. package/template/skills/remotion-best-practices/rules/timing.md +179 -0
  359. package/template/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  360. package/template/skills/remotion-best-practices/rules/transitions.md +122 -0
  361. package/template/skills/remotion-best-practices/rules/trimming.md +53 -0
  362. package/template/skills/remotion-best-practices/rules/videos.md +171 -0
  363. package/template/skills/search/SKILL.md +220 -0
  364. package/template/skills/spec/SKILL.md +377 -0
  365. package/template/skills/startup/SKILL.md +310 -0
  366. package/template/skills/web-architect/SKILL.md +309 -0
  367. package/template/skills/x-algorithm/SKILL.md +305 -0
  368. package/template/suggestions/.gitkeep +0 -0
  369. package/template/templates/QUICKSTART_SKILL_TO_PRODUCT.md +242 -0
  370. package/template/templates/brand/BRAND_BRIEF.md +124 -0
  371. package/template/templates/brand/BRAND_DECISIONS.md +168 -0
  372. package/template/templates/brand/BRAND_GUIDELINES.md +251 -0
  373. package/template/templates/brand/VOICE_AND_TONE.md +146 -0
  374. package/template/templates/brand/global.css +240 -0
  375. package/template/templates/collaboration/CONTRIBUTOR.md +74 -0
  376. package/template/templates/collaboration/CRM.md +97 -0
  377. package/template/templates/collaboration/TASKS.md +83 -0
  378. package/template/templates/strategic/NARRATIVE.md +114 -0
  379. package/template/templates/strategic/ROADMAP.md +128 -0
  380. package/template/templates/strategic/THESIS.md +108 -0
  381. package/template/templates/strategic/VISION.md +74 -0
@@ -0,0 +1,587 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # jfl-doctor.sh - Health check for JFL projects
4
+ # Inspired by Takopi's doctor command
5
+ #
6
+ # Usage:
7
+ # ./scripts/session/jfl-doctor.sh # Run health checks
8
+ # ./scripts/session/jfl-doctor.sh --fix # Auto-fix issues
9
+ # ./scripts/session/jfl-doctor.sh --json # Output as JSON
10
+
11
+ set -e
12
+
13
+ # Require bash 4+ for associative arrays, or work around it
14
+ if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then
15
+ # Fallback for older bash - just track counts
16
+ USE_ASSOC_ARRAYS=false
17
+ else
18
+ USE_ASSOC_ARRAYS=true
19
+ fi
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ REPO_DIR="$(pwd)"
23
+ WORKTREES_DIR="$REPO_DIR/worktrees"
24
+ SESSIONS_DIR="$REPO_DIR/.jfl/sessions"
25
+
26
+ # Colors
27
+ RED='\033[0;31m'
28
+ GREEN='\033[0;32m'
29
+ YELLOW='\033[1;33m'
30
+ BLUE='\033[0;34m'
31
+ NC='\033[0m'
32
+
33
+ # Parse args
34
+ FIX_MODE=false
35
+ JSON_MODE=false
36
+ VERBOSE=false
37
+
38
+ while [[ $# -gt 0 ]]; do
39
+ case $1 in
40
+ --fix|-f)
41
+ FIX_MODE=true
42
+ shift
43
+ ;;
44
+ --json|-j)
45
+ JSON_MODE=true
46
+ shift
47
+ ;;
48
+ --verbose|-v)
49
+ VERBOSE=true
50
+ shift
51
+ ;;
52
+ *)
53
+ shift
54
+ ;;
55
+ esac
56
+ done
57
+
58
+ # Check results (simple approach for bash 3 compatibility)
59
+ ISSUES=0
60
+ WARNINGS=0
61
+ FIXED=0
62
+ CHECK_RESULTS="" # Will store "name:status" pairs
63
+
64
+ # Check if a PID is still running
65
+ is_pid_running() {
66
+ local pid="$1"
67
+ # Validate PID is a positive integer
68
+ if [[ -z "$pid" ]]; then
69
+ return 1
70
+ fi
71
+ # Check if it's a number
72
+ if ! [[ "$pid" =~ ^[0-9]+$ ]]; then
73
+ return 1
74
+ fi
75
+ if [[ "$pid" -le 0 ]]; then
76
+ return 1
77
+ fi
78
+ kill -0 "$pid" 2>/dev/null
79
+ }
80
+
81
+ # Report check result
82
+ report() {
83
+ local name="$1"
84
+ local status="$2" # ok, warning, error
85
+ local message="$3"
86
+ local detail="${4:-}"
87
+
88
+ # Store for JSON output
89
+ CHECK_RESULTS="${CHECK_RESULTS}${name}:${status};"
90
+
91
+ if $JSON_MODE; then
92
+ return
93
+ fi
94
+
95
+ case $status in
96
+ ok)
97
+ echo -e "${GREEN}✓${NC} $name: $message"
98
+ ;;
99
+ warning)
100
+ echo -e "${YELLOW}⚠${NC} $name: $message"
101
+ WARNINGS=$((WARNINGS + 1))
102
+ ;;
103
+ error)
104
+ echo -e "${RED}✗${NC} $name: $message"
105
+ ISSUES=$((ISSUES + 1))
106
+ ;;
107
+ esac
108
+
109
+ if [[ -n "$detail" ]] && $VERBOSE; then
110
+ echo " $detail"
111
+ fi
112
+ }
113
+
114
+ # Check: Git status
115
+ check_git() {
116
+ cd "$REPO_DIR"
117
+
118
+ # Check if we're in a git repo
119
+ if ! git rev-parse --git-dir &>/dev/null; then
120
+ report "git" "error" "Not a git repository"
121
+ return
122
+ fi
123
+
124
+ # Check for uncommitted changes
125
+ local changes=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
126
+ if [[ $changes -gt 0 ]]; then
127
+ report "git" "warning" "$changes uncommitted changes"
128
+ else
129
+ report "git" "ok" "clean working tree"
130
+ fi
131
+ }
132
+
133
+ # Check: Submodules
134
+ check_submodules() {
135
+ cd "$REPO_DIR"
136
+
137
+ if [[ ! -f ".gitmodules" ]]; then
138
+ report "submodules" "ok" "none configured"
139
+ return
140
+ fi
141
+
142
+ local submodule_paths=$(grep "path = " .gitmodules 2>/dev/null | sed 's/.*path = //')
143
+ local issues=0
144
+ local details=""
145
+
146
+ for submodule_path in $submodule_paths; do
147
+ local full_path="$REPO_DIR/$submodule_path"
148
+
149
+ # Resolve symlink
150
+ if [[ -L "$full_path" ]]; then
151
+ full_path=$(cd "$full_path" 2>/dev/null && pwd) || continue
152
+ fi
153
+
154
+ if [[ ! -d "$full_path" ]]; then
155
+ issues=$((issues + 1))
156
+ details="$details $submodule_path (missing)"
157
+ continue
158
+ fi
159
+
160
+ # Check if submodule is initialized
161
+ if [[ ! -d "$full_path/.git" ]] && [[ ! -f "$full_path/.git" ]]; then
162
+ issues=$((issues + 1))
163
+ details="$details $submodule_path (not initialized)"
164
+ continue
165
+ fi
166
+
167
+ # Check for uncommitted changes in submodule
168
+ cd "$full_path"
169
+ local sub_changes=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
170
+ if [[ $sub_changes -gt 0 ]]; then
171
+ issues=$((issues + 1))
172
+ details="$details $submodule_path ($sub_changes uncommitted)"
173
+ fi
174
+ cd "$REPO_DIR"
175
+ done
176
+
177
+ if [[ $issues -gt 0 ]]; then
178
+ report "submodules" "warning" "$issues issue(s):$details"
179
+ else
180
+ report "submodules" "ok" "all synced"
181
+ fi
182
+ }
183
+
184
+ # Check: Stale sessions (PID not running)
185
+ check_stale_sessions() {
186
+ local stale_count=0
187
+ local stale_list=""
188
+ local active_count=0
189
+
190
+ if [[ ! -d "$WORKTREES_DIR" ]]; then
191
+ report "sessions" "ok" "no worktrees"
192
+ return
193
+ fi
194
+
195
+ for worktree in "$WORKTREES_DIR"/session-*; do
196
+ if [[ -d "$worktree" ]]; then
197
+ local session_name=$(basename "$worktree")
198
+ local pid_file="$worktree/.jfl/auto-commit.pid"
199
+
200
+ if [[ -f "$pid_file" ]]; then
201
+ local pid=$(cat "$pid_file" 2>/dev/null)
202
+ if is_pid_running "$pid"; then
203
+ active_count=$((active_count + 1))
204
+ continue
205
+ fi
206
+ fi
207
+
208
+ # No PID or PID not running = stale
209
+ stale_count=$((stale_count + 1))
210
+ stale_list="$stale_list $session_name"
211
+ fi
212
+ done
213
+
214
+ if [[ $stale_count -gt 0 ]]; then
215
+ report "sessions" "error" "$stale_count stale (PID not running), $active_count active" "$stale_list"
216
+
217
+ if $FIX_MODE; then
218
+ echo -e "${BLUE}→${NC} Cleaning up stale sessions..."
219
+ for session in $stale_list; do
220
+ cleanup_stale_session "$session"
221
+ done
222
+ fi
223
+ elif [[ $active_count -gt 0 ]]; then
224
+ report "sessions" "ok" "$active_count active"
225
+ else
226
+ report "sessions" "ok" "none"
227
+ fi
228
+ }
229
+
230
+ # Cleanup a single stale session
231
+ cleanup_stale_session() {
232
+ local session_name="$1"
233
+ local worktree_path="$WORKTREES_DIR/$session_name"
234
+
235
+ echo " Cleaning: $session_name"
236
+
237
+ # Check for uncommitted work first
238
+ cd "$worktree_path" 2>/dev/null || return
239
+ local uncommitted=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
240
+
241
+ if [[ $uncommitted -gt 0 ]]; then
242
+ echo " ⚠ Has $uncommitted uncommitted files - skipping (use --force to discard)"
243
+ cd "$REPO_DIR"
244
+ return
245
+ fi
246
+
247
+ # Check for unpushed commits
248
+ local current_branch=$(git branch --show-current 2>/dev/null)
249
+ if [[ -n "$current_branch" ]]; then
250
+ # Get remote tracking branch
251
+ local remote_branch=$(git rev-parse --abbrev-ref "$current_branch@{upstream}" 2>/dev/null)
252
+
253
+ if [[ -n "$remote_branch" ]]; then
254
+ # Check if there are unpushed commits
255
+ local unpushed=$(git log "$remote_branch..$current_branch" --oneline 2>/dev/null | wc -l | tr -d ' ')
256
+
257
+ if [[ $unpushed -gt 0 ]]; then
258
+ echo " ⚠ Has $unpushed unpushed commits - skipping (push first or use --force)"
259
+ cd "$REPO_DIR"
260
+ return
261
+ fi
262
+ else
263
+ # No upstream branch - check if branch has any commits
264
+ local commit_count=$(git rev-list --count "$current_branch" 2>/dev/null | tr -d ' ')
265
+
266
+ if [[ $commit_count -gt 0 ]]; then
267
+ echo " ⚠ Branch has commits but no remote tracking - skipping (push first or use --force)"
268
+ cd "$REPO_DIR"
269
+ return
270
+ fi
271
+ fi
272
+ fi
273
+
274
+ cd "$REPO_DIR"
275
+
276
+ # Stop any background processes
277
+ if [[ -f "$worktree_path/.jfl/auto-commit.pid" ]]; then
278
+ local pid=$(cat "$worktree_path/.jfl/auto-commit.pid")
279
+ kill "$pid" 2>/dev/null || true
280
+ fi
281
+
282
+ if [[ -f "$worktree_path/.auto-merge.pid" ]]; then
283
+ local pid=$(cat "$worktree_path/.auto-merge.pid")
284
+ kill "$pid" 2>/dev/null || true
285
+ fi
286
+
287
+ # Remove worktree
288
+ if git worktree remove "$worktree_path" --force 2>/dev/null; then
289
+ echo " ✓ Worktree removed"
290
+ fi
291
+
292
+ # Delete branch
293
+ if git branch -D "$session_name" 2>/dev/null; then
294
+ echo " ✓ Branch deleted"
295
+ fi
296
+
297
+ # Remove session state
298
+ if [[ -f "$SESSIONS_DIR/$session_name.json" ]]; then
299
+ rm -f "$SESSIONS_DIR/$session_name.json"
300
+ fi
301
+
302
+ FIXED=$((FIXED + 1))
303
+ }
304
+
305
+ # Check: Orphaned worktrees (git worktree prune)
306
+ check_orphaned_worktrees() {
307
+ cd "$REPO_DIR"
308
+
309
+ local orphans
310
+ orphans=$(git worktree list --porcelain 2>/dev/null | grep -c "prunable" 2>/dev/null) || orphans=0
311
+
312
+ if [[ "$orphans" -gt 0 ]]; then
313
+ report "worktrees" "warning" "$orphans orphaned (prunable)"
314
+
315
+ if $FIX_MODE; then
316
+ echo -e "${BLUE}→${NC} Pruning orphaned worktrees..."
317
+ git worktree prune
318
+ echo " ✓ Pruned"
319
+ FIXED=$((FIXED + 1))
320
+ fi
321
+ else
322
+ local total=$(ls -d "$WORKTREES_DIR"/session-* 2>/dev/null | wc -l | tr -d ' ')
323
+ report "worktrees" "ok" "$total total"
324
+ fi
325
+ }
326
+
327
+ # Check: Orphaned session branches
328
+ check_orphaned_branches() {
329
+ cd "$REPO_DIR"
330
+
331
+ # Find session branches that don't have corresponding worktrees
332
+ local orphan_count=0
333
+ local orphan_list=""
334
+
335
+ for branch in $(git branch --list 'session-*' 2>/dev/null | tr -d ' *+'); do
336
+ local worktree_path="$WORKTREES_DIR/$branch"
337
+ if [[ ! -d "$worktree_path" ]]; then
338
+ orphan_count=$((orphan_count + 1))
339
+ orphan_list="$orphan_list $branch"
340
+ fi
341
+ done
342
+
343
+ # Also check submodules for orphan branches
344
+ local submodule_orphans=0
345
+ if [[ -f ".gitmodules" ]]; then
346
+ local submodule_paths=$(grep "path = " .gitmodules 2>/dev/null | sed 's/.*path = //')
347
+ for submodule_path in $submodule_paths; do
348
+ local full_path="$REPO_DIR/$submodule_path"
349
+ if [[ -L "$full_path" ]]; then
350
+ full_path=$(cd "$full_path" 2>/dev/null && pwd) || continue
351
+ fi
352
+ if [[ -d "$full_path/.git" ]] || [[ -f "$full_path/.git" ]]; then
353
+ cd "$full_path"
354
+ local sub_orphans=$(git branch --list 'session-*' 2>/dev/null | wc -l | tr -d ' ')
355
+ submodule_orphans=$((submodule_orphans + sub_orphans))
356
+ cd "$REPO_DIR"
357
+ fi
358
+ done
359
+ fi
360
+
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"
364
+
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
372
+ done
373
+ fi
374
+ else
375
+ report "branches" "ok" "no orphans"
376
+ fi
377
+ }
378
+
379
+ # Check: Lock files
380
+ check_locks() {
381
+ local stale_locks=0
382
+ local lock_list=""
383
+
384
+ # Check for .lock files with stale PIDs
385
+ local lock_files=$(find "$REPO_DIR/.jfl" "$WORKTREES_DIR" -name "*.lock" 2>/dev/null || true)
386
+ for lock_file in $lock_files; do
387
+ if [[ -f "$lock_file" ]]; then
388
+ # Try to parse PID from lock file
389
+ local pid=$(grep -o '"pid":[[:space:]]*[0-9]*' "$lock_file" 2>/dev/null | grep -o '[0-9]*')
390
+ if [[ -n "$pid" ]] && ! is_pid_running "$pid"; then
391
+ stale_locks=$((stale_locks + 1))
392
+ lock_list="$lock_list $lock_file"
393
+ fi
394
+ fi
395
+ done
396
+
397
+ if [[ $stale_locks -gt 0 ]]; then
398
+ report "locks" "warning" "$stale_locks stale lock(s)"
399
+
400
+ if $FIX_MODE; then
401
+ echo -e "${BLUE}→${NC} Removing stale locks..."
402
+ for lock in $lock_list; do
403
+ rm -f "$lock"
404
+ echo " ✓ Removed: $(basename $lock)"
405
+ FIXED=$((FIXED + 1))
406
+ done
407
+ fi
408
+ else
409
+ report "locks" "ok" "no stale locks"
410
+ fi
411
+ }
412
+
413
+ # Check: Memory MCP
414
+ check_memory() {
415
+ local memory_db="$REPO_DIR/.jfl/memory.db"
416
+
417
+ if [[ ! -f "$memory_db" ]]; then
418
+ report "memory" "warning" "not initialized"
419
+ return
420
+ fi
421
+
422
+ # Try to get memory count if sqlite3 is available
423
+ if command -v sqlite3 &>/dev/null; then
424
+ local count=$(sqlite3 "$memory_db" "SELECT COUNT(*) FROM memories;" 2>/dev/null || echo 0)
425
+ report "memory" "ok" "$count memories indexed"
426
+ else
427
+ local size=$(ls -lh "$memory_db" 2>/dev/null | awk '{print $5}')
428
+ report "memory" "ok" "database exists ($size)"
429
+ fi
430
+ }
431
+
432
+ # Check: Unmerged session branches and conflicts
433
+ check_unmerged_sessions() {
434
+ local unmerged=0
435
+ local conflicts=0
436
+ local merged=0
437
+
438
+ # Check for .merge-conflict files in worktrees
439
+ for worktree in "$WORKTREES_DIR"/session-*; do
440
+ if [[ -d "$worktree" ]]; then
441
+ local session_name=$(basename "$worktree")
442
+
443
+ # Check for conflict marker
444
+ if [[ -f "$worktree/.merge-conflict" ]]; then
445
+ conflicts=$((conflicts + 1))
446
+
447
+ if $FIX_MODE; then
448
+ # Try to resolve by running auto-merge with new auto-resolve logic
449
+ rm -f "$worktree/.merge-conflict"
450
+ if "$SCRIPT_DIR/auto-merge.sh" once "$session_name" 2>/dev/null; then
451
+ merged=$((merged + 1))
452
+ FIXED=$((FIXED + 1))
453
+ else
454
+ # Still can't merge - recreate conflict marker will happen in auto-merge
455
+ conflicts=$((conflicts + 1))
456
+ fi
457
+ fi
458
+ fi
459
+
460
+ # Check for unmerged commits (session ahead of main)
461
+ local commits_ahead=$(git rev-list --count main.."$session_name" 2>/dev/null || echo "0")
462
+ if [[ "$commits_ahead" -gt 0 ]]; then
463
+ unmerged=$((unmerged + 1))
464
+
465
+ if $FIX_MODE && [[ ! -f "$worktree/.merge-conflict" ]]; then
466
+ # Try to merge
467
+ if "$SCRIPT_DIR/auto-merge.sh" once "$session_name" 2>/dev/null; then
468
+ merged=$((merged + 1))
469
+ FIXED=$((FIXED + 1))
470
+ unmerged=$((unmerged - 1))
471
+ fi
472
+ fi
473
+ fi
474
+ fi
475
+ done
476
+
477
+ if [[ $conflicts -gt 0 ]]; then
478
+ if $FIX_MODE && [[ $merged -gt 0 ]]; then
479
+ report "merge" "ok" "resolved $merged conflicts, $conflicts remaining"
480
+ else
481
+ report "merge" "error" "$conflicts unresolved merge conflicts"
482
+ fi
483
+ elif [[ $unmerged -gt 0 ]]; then
484
+ if $FIX_MODE; then
485
+ report "merge" "ok" "merged $merged sessions, $unmerged remaining"
486
+ else
487
+ report "merge" "warning" "$unmerged sessions with unmerged commits"
488
+ fi
489
+ else
490
+ report "merge" "ok" "all sessions merged"
491
+ fi
492
+ }
493
+
494
+ # Check: Session state files
495
+ check_session_state() {
496
+ mkdir -p "$SESSIONS_DIR"
497
+
498
+ local state_files=$(ls "$SESSIONS_DIR"/*.json 2>/dev/null | wc -l | tr -d ' ')
499
+ local orphan_states=0
500
+
501
+ for state_file in "$SESSIONS_DIR"/*.json; do
502
+ if [[ -f "$state_file" ]]; then
503
+ local session_name=$(basename "$state_file" .json)
504
+ if [[ ! -d "$WORKTREES_DIR/$session_name" ]]; then
505
+ orphan_states=$((orphan_states + 1))
506
+
507
+ if $FIX_MODE; then
508
+ rm -f "$state_file"
509
+ FIXED=$((FIXED + 1))
510
+ fi
511
+ fi
512
+ fi
513
+ done
514
+
515
+ if [[ $orphan_states -gt 0 ]]; then
516
+ if $FIX_MODE; then
517
+ report "state" "ok" "cleaned $orphan_states orphan state files"
518
+ else
519
+ report "state" "warning" "$orphan_states orphan state files"
520
+ fi
521
+ else
522
+ report "state" "ok" "$state_files session state files"
523
+ fi
524
+ }
525
+
526
+ # Main
527
+ main() {
528
+ if ! $JSON_MODE; then
529
+ echo ""
530
+ echo "jfl doctor"
531
+ echo "─────────────────────────────────────"
532
+ fi
533
+
534
+ check_git
535
+ check_submodules
536
+ check_stale_sessions
537
+ check_orphaned_worktrees
538
+ check_orphaned_branches
539
+ check_unmerged_sessions
540
+ check_locks
541
+ check_memory
542
+ check_session_state
543
+
544
+ if $JSON_MODE; then
545
+ # Output JSON (parse CHECK_RESULTS string)
546
+ echo "{"
547
+ echo ' "checks": {'
548
+ local first=true
549
+ IFS=';' read -ra PAIRS <<< "$CHECK_RESULTS"
550
+ for pair in "${PAIRS[@]}"; do
551
+ if [[ -n "$pair" ]]; then
552
+ local key="${pair%%:*}"
553
+ local value="${pair#*:}"
554
+ if ! $first; then echo ","; fi
555
+ first=false
556
+ echo -n " \"$key\": \"$value\""
557
+ fi
558
+ done
559
+ echo ""
560
+ echo " },"
561
+ echo " \"issues\": $ISSUES,"
562
+ echo " \"warnings\": $WARNINGS,"
563
+ echo " \"fixed\": $FIXED"
564
+ echo "}"
565
+ else
566
+ echo ""
567
+ if [[ $ISSUES -gt 0 ]] || [[ $WARNINGS -gt 0 ]]; then
568
+ if $FIX_MODE; then
569
+ echo -e "Fixed $FIXED issue(s). Remaining: $ISSUES error(s), $WARNINGS warning(s)"
570
+ else
571
+ echo -e "$ISSUES error(s), $WARNINGS warning(s)"
572
+ echo ""
573
+ echo "Run 'jfl-doctor.sh --fix' to auto-fix issues"
574
+ fi
575
+ else
576
+ echo -e "${GREEN}All checks passed!${NC}"
577
+ fi
578
+ echo ""
579
+ fi
580
+
581
+ # Exit with error code if issues found
582
+ if [[ $ISSUES -gt 0 ]]; then
583
+ exit 1
584
+ fi
585
+ }
586
+
587
+ main "$@"