jfl 0.4.4 → 0.6.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 (533) hide show
  1. package/dist/commands/context-hub.d.ts +1 -0
  2. package/dist/commands/context-hub.d.ts.map +1 -1
  3. package/dist/commands/context-hub.js +1064 -41
  4. package/dist/commands/context-hub.js.map +1 -1
  5. package/dist/commands/eval.d.ts +1 -1
  6. package/dist/commands/eval.d.ts.map +1 -1
  7. package/dist/commands/eval.js +192 -1
  8. package/dist/commands/eval.js.map +1 -1
  9. package/dist/commands/findings.d.ts +6 -0
  10. package/dist/commands/findings.d.ts.map +1 -0
  11. package/dist/commands/findings.js +203 -0
  12. package/dist/commands/findings.js.map +1 -0
  13. package/dist/commands/hud.d.ts.map +1 -1
  14. package/dist/commands/hud.js +47 -9
  15. package/dist/commands/hud.js.map +1 -1
  16. package/dist/commands/ide.d.ts +27 -0
  17. package/dist/commands/ide.d.ts.map +1 -0
  18. package/dist/commands/ide.js +546 -0
  19. package/dist/commands/ide.js.map +1 -0
  20. package/dist/commands/onboard.d.ts.map +1 -1
  21. package/dist/commands/onboard.js +212 -2
  22. package/dist/commands/onboard.js.map +1 -1
  23. package/dist/commands/openclaw.d.ts +3 -0
  24. package/dist/commands/openclaw.d.ts.map +1 -1
  25. package/dist/commands/openclaw.js +76 -2
  26. package/dist/commands/openclaw.js.map +1 -1
  27. package/dist/commands/peter.d.ts +3 -0
  28. package/dist/commands/peter.d.ts.map +1 -1
  29. package/dist/commands/peter.js +1168 -58
  30. package/dist/commands/peter.js.map +1 -1
  31. package/dist/commands/pi-fleet.d.ts +18 -0
  32. package/dist/commands/pi-fleet.d.ts.map +1 -0
  33. package/dist/commands/pi-fleet.js +382 -0
  34. package/dist/commands/pi-fleet.js.map +1 -0
  35. package/dist/commands/pi.d.ts.map +1 -1
  36. package/dist/commands/pi.js +18 -3
  37. package/dist/commands/pi.js.map +1 -1
  38. package/dist/commands/scope.d.ts.map +1 -1
  39. package/dist/commands/scope.js +90 -1
  40. package/dist/commands/scope.js.map +1 -1
  41. package/dist/commands/services.d.ts.map +1 -1
  42. package/dist/commands/services.js +18 -0
  43. package/dist/commands/services.js.map +1 -1
  44. package/dist/commands/setup.d.ts +12 -0
  45. package/dist/commands/setup.d.ts.map +1 -0
  46. package/dist/commands/setup.js +322 -0
  47. package/dist/commands/setup.js.map +1 -0
  48. package/dist/commands/status.d.ts.map +1 -1
  49. package/dist/commands/status.js +22 -4
  50. package/dist/commands/status.js.map +1 -1
  51. package/dist/commands/train.d.ts +33 -0
  52. package/dist/commands/train.d.ts.map +1 -0
  53. package/dist/commands/train.js +510 -0
  54. package/dist/commands/train.js.map +1 -0
  55. package/dist/commands/verify.d.ts +14 -0
  56. package/dist/commands/verify.d.ts.map +1 -0
  57. package/dist/commands/verify.js +276 -0
  58. package/dist/commands/verify.js.map +1 -0
  59. package/dist/commands/viz.d.ts.map +1 -1
  60. package/dist/commands/viz.js +417 -0
  61. package/dist/commands/viz.js.map +1 -1
  62. package/dist/dashboard-static/assets/index-CW9ZxqX8.css +1 -0
  63. package/dist/dashboard-static/assets/index-DNN__p4K.js +121 -0
  64. package/dist/dashboard-static/index.html +2 -2
  65. package/dist/index.js +324 -64
  66. package/dist/index.js.map +1 -1
  67. package/dist/lib/agent-config.d.ts +52 -0
  68. package/dist/lib/agent-config.d.ts.map +1 -0
  69. package/dist/lib/agent-config.js +231 -0
  70. package/dist/lib/agent-config.js.map +1 -0
  71. package/dist/lib/agent-generator.d.ts +10 -0
  72. package/dist/lib/agent-generator.d.ts.map +1 -1
  73. package/dist/lib/agent-generator.js +64 -10
  74. package/dist/lib/agent-generator.js.map +1 -1
  75. package/dist/lib/agent-session.d.ts +104 -0
  76. package/dist/lib/agent-session.d.ts.map +1 -0
  77. package/dist/lib/agent-session.js +635 -0
  78. package/dist/lib/agent-session.js.map +1 -0
  79. package/dist/lib/eval-snapshot.d.ts +47 -0
  80. package/dist/lib/eval-snapshot.d.ts.map +1 -0
  81. package/dist/lib/eval-snapshot.js +315 -0
  82. package/dist/lib/eval-snapshot.js.map +1 -0
  83. package/dist/lib/eval-store.d.ts +5 -0
  84. package/dist/lib/eval-store.d.ts.map +1 -1
  85. package/dist/lib/eval-store.js +33 -3
  86. package/dist/lib/eval-store.js.map +1 -1
  87. package/dist/lib/findings-engine.d.ts +51 -0
  88. package/dist/lib/findings-engine.d.ts.map +1 -0
  89. package/dist/lib/findings-engine.js +338 -0
  90. package/dist/lib/findings-engine.js.map +1 -0
  91. package/dist/lib/flow-engine.d.ts +8 -0
  92. package/dist/lib/flow-engine.d.ts.map +1 -1
  93. package/dist/lib/flow-engine.js +84 -2
  94. package/dist/lib/flow-engine.js.map +1 -1
  95. package/dist/lib/hub-client.d.ts +1 -0
  96. package/dist/lib/hub-client.d.ts.map +1 -1
  97. package/dist/lib/hub-client.js +33 -6
  98. package/dist/lib/hub-client.js.map +1 -1
  99. package/dist/lib/ide-panes.d.ts +58 -0
  100. package/dist/lib/ide-panes.d.ts.map +1 -0
  101. package/dist/lib/ide-panes.js +508 -0
  102. package/dist/lib/ide-panes.js.map +1 -0
  103. package/dist/lib/memory-db.js +4 -4
  104. package/dist/lib/memory-db.js.map +1 -1
  105. package/dist/lib/memory-indexer.d.ts.map +1 -1
  106. package/dist/lib/memory-indexer.js +3 -0
  107. package/dist/lib/memory-indexer.js.map +1 -1
  108. package/dist/lib/memory-search.d.ts +148 -4
  109. package/dist/lib/memory-search.d.ts.map +1 -1
  110. package/dist/lib/memory-search.js +496 -58
  111. package/dist/lib/memory-search.js.map +1 -1
  112. package/dist/lib/meta-orchestrator.d.ts +104 -0
  113. package/dist/lib/meta-orchestrator.d.ts.map +1 -0
  114. package/dist/lib/meta-orchestrator.js +373 -0
  115. package/dist/lib/meta-orchestrator.js.map +1 -0
  116. package/dist/lib/peer-agent-generator.d.ts.map +1 -1
  117. package/dist/lib/peer-agent-generator.js +43 -19
  118. package/dist/lib/peer-agent-generator.js.map +1 -1
  119. package/dist/lib/pi-sky/bridge.d.ts +55 -0
  120. package/dist/lib/pi-sky/bridge.d.ts.map +1 -0
  121. package/dist/lib/pi-sky/bridge.js +264 -0
  122. package/dist/lib/pi-sky/bridge.js.map +1 -0
  123. package/dist/lib/pi-sky/cost-monitor.d.ts +21 -0
  124. package/dist/lib/pi-sky/cost-monitor.d.ts.map +1 -0
  125. package/dist/lib/pi-sky/cost-monitor.js +126 -0
  126. package/dist/lib/pi-sky/cost-monitor.js.map +1 -0
  127. package/dist/lib/pi-sky/eval-sweep.d.ts +27 -0
  128. package/dist/lib/pi-sky/eval-sweep.d.ts.map +1 -0
  129. package/dist/lib/pi-sky/eval-sweep.js +141 -0
  130. package/dist/lib/pi-sky/eval-sweep.js.map +1 -0
  131. package/dist/lib/pi-sky/event-router.d.ts +32 -0
  132. package/dist/lib/pi-sky/event-router.d.ts.map +1 -0
  133. package/dist/lib/pi-sky/event-router.js +176 -0
  134. package/dist/lib/pi-sky/event-router.js.map +1 -0
  135. package/dist/lib/pi-sky/experiment.d.ts +9 -0
  136. package/dist/lib/pi-sky/experiment.d.ts.map +1 -0
  137. package/dist/lib/pi-sky/experiment.js +83 -0
  138. package/dist/lib/pi-sky/experiment.js.map +1 -0
  139. package/dist/lib/pi-sky/index.d.ts +16 -0
  140. package/dist/lib/pi-sky/index.d.ts.map +1 -0
  141. package/dist/lib/pi-sky/index.js +16 -0
  142. package/dist/lib/pi-sky/index.js.map +1 -0
  143. package/dist/lib/pi-sky/stratus-gate.d.ts +28 -0
  144. package/dist/lib/pi-sky/stratus-gate.d.ts.map +1 -0
  145. package/dist/lib/pi-sky/stratus-gate.js +61 -0
  146. package/dist/lib/pi-sky/stratus-gate.js.map +1 -0
  147. package/dist/lib/pi-sky/swarm.d.ts +28 -0
  148. package/dist/lib/pi-sky/swarm.d.ts.map +1 -0
  149. package/dist/lib/pi-sky/swarm.js +208 -0
  150. package/dist/lib/pi-sky/swarm.js.map +1 -0
  151. package/dist/lib/pi-sky/types.d.ts +139 -0
  152. package/dist/lib/pi-sky/types.d.ts.map +1 -0
  153. package/dist/lib/pi-sky/types.js +2 -0
  154. package/dist/lib/pi-sky/types.js.map +1 -0
  155. package/dist/lib/pi-sky/voice-bridge.d.ts +20 -0
  156. package/dist/lib/pi-sky/voice-bridge.d.ts.map +1 -0
  157. package/dist/lib/pi-sky/voice-bridge.js +91 -0
  158. package/dist/lib/pi-sky/voice-bridge.js.map +1 -0
  159. package/dist/lib/policy-head.d.ts +40 -0
  160. package/dist/lib/policy-head.d.ts.map +1 -0
  161. package/dist/lib/policy-head.js +234 -0
  162. package/dist/lib/policy-head.js.map +1 -0
  163. package/dist/lib/predictor.d.ts +10 -0
  164. package/dist/lib/predictor.d.ts.map +1 -1
  165. package/dist/lib/predictor.js +46 -7
  166. package/dist/lib/predictor.js.map +1 -1
  167. package/dist/lib/replay-buffer.d.ts +93 -0
  168. package/dist/lib/replay-buffer.d.ts.map +1 -0
  169. package/dist/lib/replay-buffer.js +302 -0
  170. package/dist/lib/replay-buffer.js.map +1 -0
  171. package/dist/lib/sentinel-rl.d.ts +97 -0
  172. package/dist/lib/sentinel-rl.d.ts.map +1 -0
  173. package/dist/lib/sentinel-rl.js +430 -0
  174. package/dist/lib/sentinel-rl.js.map +1 -0
  175. package/dist/lib/session-lock.d.ts +61 -0
  176. package/dist/lib/session-lock.d.ts.map +1 -0
  177. package/dist/lib/session-lock.js +438 -0
  178. package/dist/lib/session-lock.js.map +1 -0
  179. package/dist/lib/setup/agent-generator.d.ts +18 -0
  180. package/dist/lib/setup/agent-generator.d.ts.map +1 -0
  181. package/dist/lib/setup/agent-generator.js +114 -0
  182. package/dist/lib/setup/agent-generator.js.map +1 -0
  183. package/dist/lib/setup/context-analyzer.d.ts +16 -0
  184. package/dist/lib/setup/context-analyzer.d.ts.map +1 -0
  185. package/dist/lib/setup/context-analyzer.js +112 -0
  186. package/dist/lib/setup/context-analyzer.js.map +1 -0
  187. package/dist/lib/setup/doc-auditor.d.ts +54 -0
  188. package/dist/lib/setup/doc-auditor.d.ts.map +1 -0
  189. package/dist/lib/setup/doc-auditor.js +629 -0
  190. package/dist/lib/setup/doc-auditor.js.map +1 -0
  191. package/dist/lib/setup/domain-generator.d.ts +7 -0
  192. package/dist/lib/setup/domain-generator.d.ts.map +1 -0
  193. package/dist/lib/setup/domain-generator.js +58 -0
  194. package/dist/lib/setup/domain-generator.js.map +1 -0
  195. package/dist/lib/setup/smart-eval-generator.d.ts +38 -0
  196. package/dist/lib/setup/smart-eval-generator.d.ts.map +1 -0
  197. package/dist/lib/setup/smart-eval-generator.js +378 -0
  198. package/dist/lib/setup/smart-eval-generator.js.map +1 -0
  199. package/dist/lib/setup/smart-recommender.d.ts +63 -0
  200. package/dist/lib/setup/smart-recommender.d.ts.map +1 -0
  201. package/dist/lib/setup/smart-recommender.js +329 -0
  202. package/dist/lib/setup/smart-recommender.js.map +1 -0
  203. package/dist/lib/setup/spec-generator.d.ts +63 -0
  204. package/dist/lib/setup/spec-generator.d.ts.map +1 -0
  205. package/dist/lib/setup/spec-generator.js +310 -0
  206. package/dist/lib/setup/spec-generator.js.map +1 -0
  207. package/dist/lib/setup/violation-agent-generator.d.ts +32 -0
  208. package/dist/lib/setup/violation-agent-generator.d.ts.map +1 -0
  209. package/dist/lib/setup/violation-agent-generator.js +255 -0
  210. package/dist/lib/setup/violation-agent-generator.js.map +1 -0
  211. package/dist/lib/stratus-client.d.ts +1 -0
  212. package/dist/lib/stratus-client.d.ts.map +1 -1
  213. package/dist/lib/stratus-client.js +24 -2
  214. package/dist/lib/stratus-client.js.map +1 -1
  215. package/dist/lib/telemetry-agent-v2.d.ts +128 -0
  216. package/dist/lib/telemetry-agent-v2.d.ts.map +1 -0
  217. package/dist/lib/telemetry-agent-v2.js +1042 -0
  218. package/dist/lib/telemetry-agent-v2.js.map +1 -0
  219. package/dist/lib/telemetry-agent.d.ts.map +1 -1
  220. package/dist/lib/telemetry-agent.js +27 -6
  221. package/dist/lib/telemetry-agent.js.map +1 -1
  222. package/dist/lib/telemetry-digest.d.ts.map +1 -1
  223. package/dist/lib/telemetry-digest.js +27 -5
  224. package/dist/lib/telemetry-digest.js.map +1 -1
  225. package/dist/lib/telemetry.d.ts.map +1 -1
  226. package/dist/lib/telemetry.js +29 -4
  227. package/dist/lib/telemetry.js.map +1 -1
  228. package/dist/lib/text-preprocessing.d.ts +83 -0
  229. package/dist/lib/text-preprocessing.d.ts.map +1 -0
  230. package/dist/lib/text-preprocessing.js +261 -0
  231. package/dist/lib/text-preprocessing.js.map +1 -0
  232. package/dist/lib/training-buffer.d.ts +86 -0
  233. package/dist/lib/training-buffer.d.ts.map +1 -0
  234. package/dist/lib/training-buffer.js +139 -0
  235. package/dist/lib/training-buffer.js.map +1 -0
  236. package/dist/lib/tuple-miner.d.ts +30 -0
  237. package/dist/lib/tuple-miner.d.ts.map +1 -0
  238. package/dist/lib/tuple-miner.js +427 -0
  239. package/dist/lib/tuple-miner.js.map +1 -0
  240. package/dist/lib/vm-backend.d.ts +72 -0
  241. package/dist/lib/vm-backend.d.ts.map +1 -0
  242. package/dist/lib/vm-backend.js +175 -0
  243. package/dist/lib/vm-backend.js.map +1 -0
  244. package/dist/lib/workspace/backend.d.ts +53 -0
  245. package/dist/lib/workspace/backend.d.ts.map +1 -0
  246. package/dist/lib/workspace/backend.js +37 -0
  247. package/dist/lib/workspace/backend.js.map +1 -0
  248. package/dist/lib/workspace/cmux-adapter.d.ts +46 -0
  249. package/dist/lib/workspace/cmux-adapter.d.ts.map +1 -0
  250. package/dist/lib/workspace/cmux-adapter.js +261 -0
  251. package/dist/lib/workspace/cmux-adapter.js.map +1 -0
  252. package/dist/lib/workspace/data-pipeline.d.ts +35 -0
  253. package/dist/lib/workspace/data-pipeline.d.ts.map +1 -0
  254. package/dist/lib/workspace/data-pipeline.js +463 -0
  255. package/dist/lib/workspace/data-pipeline.js.map +1 -0
  256. package/dist/lib/workspace/engine.d.ts +64 -0
  257. package/dist/lib/workspace/engine.d.ts.map +1 -0
  258. package/dist/lib/workspace/engine.js +397 -0
  259. package/dist/lib/workspace/engine.js.map +1 -0
  260. package/dist/lib/workspace/notifications.d.ts +14 -0
  261. package/dist/lib/workspace/notifications.d.ts.map +1 -0
  262. package/dist/lib/workspace/notifications.js +41 -0
  263. package/dist/lib/workspace/notifications.js.map +1 -0
  264. package/dist/lib/workspace/surface-registry.d.ts +49 -0
  265. package/dist/lib/workspace/surface-registry.d.ts.map +1 -0
  266. package/dist/lib/workspace/surface-registry.js +217 -0
  267. package/dist/lib/workspace/surface-registry.js.map +1 -0
  268. package/dist/lib/workspace/surface-type.d.ts +153 -0
  269. package/dist/lib/workspace/surface-type.d.ts.map +1 -0
  270. package/dist/lib/workspace/surface-type.js +9 -0
  271. package/dist/lib/workspace/surface-type.js.map +1 -0
  272. package/dist/lib/workspace/surfaces/agent-overview.d.ts +16 -0
  273. package/dist/lib/workspace/surfaces/agent-overview.d.ts.map +1 -0
  274. package/dist/lib/workspace/surfaces/agent-overview.js +116 -0
  275. package/dist/lib/workspace/surfaces/agent-overview.js.map +1 -0
  276. package/dist/lib/workspace/surfaces/agent.d.ts +16 -0
  277. package/dist/lib/workspace/surfaces/agent.d.ts.map +1 -0
  278. package/dist/lib/workspace/surfaces/agent.js +112 -0
  279. package/dist/lib/workspace/surfaces/agent.js.map +1 -0
  280. package/dist/lib/workspace/surfaces/claude.d.ts +15 -0
  281. package/dist/lib/workspace/surfaces/claude.d.ts.map +1 -0
  282. package/dist/lib/workspace/surfaces/claude.js +23 -0
  283. package/dist/lib/workspace/surfaces/claude.js.map +1 -0
  284. package/dist/lib/workspace/surfaces/dashboard.d.ts +21 -0
  285. package/dist/lib/workspace/surfaces/dashboard.d.ts.map +1 -0
  286. package/dist/lib/workspace/surfaces/dashboard.js +32 -0
  287. package/dist/lib/workspace/surfaces/dashboard.js.map +1 -0
  288. package/dist/lib/workspace/surfaces/eval.d.ts +15 -0
  289. package/dist/lib/workspace/surfaces/eval.d.ts.map +1 -0
  290. package/dist/lib/workspace/surfaces/eval.js +42 -0
  291. package/dist/lib/workspace/surfaces/eval.js.map +1 -0
  292. package/dist/lib/workspace/surfaces/event-stream.d.ts +16 -0
  293. package/dist/lib/workspace/surfaces/event-stream.d.ts.map +1 -0
  294. package/dist/lib/workspace/surfaces/event-stream.js +40 -0
  295. package/dist/lib/workspace/surfaces/event-stream.js.map +1 -0
  296. package/dist/lib/workspace/surfaces/flow.d.ts +16 -0
  297. package/dist/lib/workspace/surfaces/flow.d.ts.map +1 -0
  298. package/dist/lib/workspace/surfaces/flow.js +49 -0
  299. package/dist/lib/workspace/surfaces/flow.js.map +1 -0
  300. package/dist/lib/workspace/surfaces/index.d.ts +16 -0
  301. package/dist/lib/workspace/surfaces/index.d.ts.map +1 -0
  302. package/dist/lib/workspace/surfaces/index.js +16 -0
  303. package/dist/lib/workspace/surfaces/index.js.map +1 -0
  304. package/dist/lib/workspace/surfaces/portfolio.d.ts +16 -0
  305. package/dist/lib/workspace/surfaces/portfolio.d.ts.map +1 -0
  306. package/dist/lib/workspace/surfaces/portfolio.js +102 -0
  307. package/dist/lib/workspace/surfaces/portfolio.js.map +1 -0
  308. package/dist/lib/workspace/surfaces/service.d.ts +16 -0
  309. package/dist/lib/workspace/surfaces/service.d.ts.map +1 -0
  310. package/dist/lib/workspace/surfaces/service.js +45 -0
  311. package/dist/lib/workspace/surfaces/service.js.map +1 -0
  312. package/dist/lib/workspace/surfaces/shell.d.ts +15 -0
  313. package/dist/lib/workspace/surfaces/shell.d.ts.map +1 -0
  314. package/dist/lib/workspace/surfaces/shell.js +19 -0
  315. package/dist/lib/workspace/surfaces/shell.js.map +1 -0
  316. package/dist/lib/workspace/surfaces/telemetry.d.ts +16 -0
  317. package/dist/lib/workspace/surfaces/telemetry.d.ts.map +1 -0
  318. package/dist/lib/workspace/surfaces/telemetry.js +48 -0
  319. package/dist/lib/workspace/surfaces/telemetry.js.map +1 -0
  320. package/dist/lib/workspace/surfaces/topology.d.ts +15 -0
  321. package/dist/lib/workspace/surfaces/topology.d.ts.map +1 -0
  322. package/dist/lib/workspace/surfaces/topology.js +19 -0
  323. package/dist/lib/workspace/surfaces/topology.js.map +1 -0
  324. package/dist/lib/workspace/surfaces/training.d.ts +16 -0
  325. package/dist/lib/workspace/surfaces/training.d.ts.map +1 -0
  326. package/dist/lib/workspace/surfaces/training.js +22 -0
  327. package/dist/lib/workspace/surfaces/training.js.map +1 -0
  328. package/dist/lib/workspace/tmux-adapter.d.ts +27 -0
  329. package/dist/lib/workspace/tmux-adapter.d.ts.map +1 -0
  330. package/dist/lib/workspace/tmux-adapter.js +106 -0
  331. package/dist/lib/workspace/tmux-adapter.js.map +1 -0
  332. package/dist/mcp/context-hub-mcp.js +7 -24
  333. package/dist/mcp/context-hub-mcp.js.map +1 -1
  334. package/dist/types/flows.d.ts +2 -0
  335. package/dist/types/flows.d.ts.map +1 -1
  336. package/dist/types/ide.d.ts +49 -0
  337. package/dist/types/ide.d.ts.map +1 -0
  338. package/dist/types/ide.js +5 -0
  339. package/dist/types/ide.js.map +1 -0
  340. package/dist/types/platform-digest.d.ts +228 -0
  341. package/dist/types/platform-digest.d.ts.map +1 -0
  342. package/dist/types/platform-digest.js +5 -0
  343. package/dist/types/platform-digest.js.map +1 -0
  344. package/dist/types/telemetry-digest.d.ts +2 -0
  345. package/dist/types/telemetry-digest.d.ts.map +1 -1
  346. package/dist/utils/ensure-project.d.ts +1 -0
  347. package/dist/utils/ensure-project.d.ts.map +1 -1
  348. package/dist/utils/ensure-project.js +19 -7
  349. package/dist/utils/ensure-project.js.map +1 -1
  350. package/dist/utils/jfl-config.d.ts +1 -0
  351. package/dist/utils/jfl-config.d.ts.map +1 -1
  352. package/dist/utils/jfl-config.js +19 -1
  353. package/dist/utils/jfl-config.js.map +1 -1
  354. package/dist/utils/jfl-paths.d.ts +5 -0
  355. package/dist/utils/jfl-paths.d.ts.map +1 -1
  356. package/dist/utils/jfl-paths.js +25 -3
  357. package/dist/utils/jfl-paths.js.map +1 -1
  358. package/package.json +3 -2
  359. package/packages/pi/AGENTS.md +112 -0
  360. package/packages/pi/extensions/agent-grid.ts +191 -0
  361. package/packages/pi/extensions/agent-names.ts +178 -0
  362. package/packages/pi/extensions/autoresearch.ts +427 -0
  363. package/packages/pi/extensions/bookmarks.ts +85 -0
  364. package/packages/pi/extensions/context.ts +184 -0
  365. package/packages/pi/extensions/crm-tool.ts +61 -0
  366. package/packages/pi/extensions/eval-tool.ts +224 -0
  367. package/packages/pi/extensions/eval.ts +60 -0
  368. package/packages/pi/extensions/footer.ts +239 -0
  369. package/packages/pi/extensions/hub-resolver.ts +63 -0
  370. package/packages/pi/extensions/hud-tool.ts +145 -0
  371. package/packages/pi/extensions/index.ts +405 -0
  372. package/packages/pi/extensions/journal.ts +224 -0
  373. package/packages/pi/extensions/map-bridge.ts +178 -0
  374. package/packages/pi/extensions/memory-tool.ts +73 -0
  375. package/packages/pi/extensions/notifications.ts +73 -0
  376. package/packages/pi/extensions/peter-parker.ts +202 -0
  377. package/packages/pi/extensions/policy-head-tool.ts +276 -0
  378. package/packages/pi/extensions/portfolio-bridge.ts +90 -0
  379. package/packages/pi/extensions/session.ts +142 -0
  380. package/packages/pi/extensions/shortcuts.ts +259 -0
  381. package/packages/pi/extensions/stratus-bridge.ts +115 -0
  382. package/packages/pi/extensions/synopsis-tool.ts +83 -0
  383. package/packages/pi/extensions/tool-renderers.ts +353 -0
  384. package/packages/pi/extensions/training-buffer-tool.ts +368 -0
  385. package/packages/pi/extensions/types.ts +163 -0
  386. package/packages/pi/package-lock.json +346 -0
  387. package/packages/pi/package.json +44 -0
  388. package/packages/pi/skills/agent-browser/SKILL.md +116 -0
  389. package/packages/pi/skills/brand-architect/SKILL.md +240 -0
  390. package/packages/pi/skills/brand-architect/config.yaml +137 -0
  391. package/packages/pi/skills/campaign-hud/config.yaml +112 -0
  392. package/packages/pi/skills/content-creator/SKILL.md +294 -0
  393. package/packages/pi/skills/context/SKILL.md +65 -0
  394. package/packages/pi/skills/debug/MULTI_AGENT.md +360 -0
  395. package/packages/pi/skills/debug/SKILL.md +554 -0
  396. package/packages/pi/skills/end/SKILL.md +1782 -0
  397. package/packages/pi/skills/eval/SKILL.md +75 -0
  398. package/packages/pi/skills/fly-deploy/SKILL.md +676 -0
  399. package/packages/pi/skills/founder-video/SKILL.md +467 -0
  400. package/packages/pi/skills/hud/SKILL.md +160 -0
  401. package/packages/pi/skills/orchestrate/SKILL.md +74 -0
  402. package/packages/pi/skills/pi-agents/SKILL.md +78 -0
  403. package/packages/pi/skills/react-best-practices/AGENTS.md +2249 -0
  404. package/packages/pi/skills/react-best-practices/README.md +123 -0
  405. package/packages/pi/skills/react-best-practices/SKILL.md +125 -0
  406. package/packages/pi/skills/react-best-practices/metadata.json +15 -0
  407. package/packages/pi/skills/react-best-practices/rules/_sections.md +46 -0
  408. package/packages/pi/skills/react-best-practices/rules/_template.md +28 -0
  409. package/packages/pi/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  410. package/packages/pi/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  411. package/packages/pi/skills/react-best-practices/rules/async-api-routes.md +38 -0
  412. package/packages/pi/skills/react-best-practices/rules/async-defer-await.md +80 -0
  413. package/packages/pi/skills/react-best-practices/rules/async-dependencies.md +36 -0
  414. package/packages/pi/skills/react-best-practices/rules/async-parallel.md +28 -0
  415. package/packages/pi/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  416. package/packages/pi/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  417. package/packages/pi/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  418. package/packages/pi/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  419. package/packages/pi/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  420. package/packages/pi/skills/react-best-practices/rules/bundle-preload.md +50 -0
  421. package/packages/pi/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  422. package/packages/pi/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  423. package/packages/pi/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  424. package/packages/pi/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  425. package/packages/pi/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  426. package/packages/pi/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  427. package/packages/pi/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  428. package/packages/pi/skills/react-best-practices/rules/js-early-exit.md +50 -0
  429. package/packages/pi/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  430. package/packages/pi/skills/react-best-practices/rules/js-index-maps.md +37 -0
  431. package/packages/pi/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  432. package/packages/pi/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  433. package/packages/pi/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  434. package/packages/pi/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  435. package/packages/pi/skills/react-best-practices/rules/rendering-activity.md +26 -0
  436. package/packages/pi/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  437. package/packages/pi/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  438. package/packages/pi/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  439. package/packages/pi/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  440. package/packages/pi/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  441. package/packages/pi/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  442. package/packages/pi/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  443. package/packages/pi/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  444. package/packages/pi/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  445. package/packages/pi/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  446. package/packages/pi/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  447. package/packages/pi/skills/react-best-practices/rules/rerender-memo.md +44 -0
  448. package/packages/pi/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  449. package/packages/pi/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  450. package/packages/pi/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  451. package/packages/pi/skills/react-best-practices/rules/server-cache-react.md +26 -0
  452. package/packages/pi/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
  453. package/packages/pi/skills/react-best-practices/rules/server-serialization.md +38 -0
  454. package/packages/pi/skills/remotion-best-practices/SKILL.md +43 -0
  455. package/packages/pi/skills/remotion-best-practices/rules/3d.md +86 -0
  456. package/packages/pi/skills/remotion-best-practices/rules/animations.md +29 -0
  457. package/packages/pi/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  458. package/packages/pi/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  459. package/packages/pi/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  460. package/packages/pi/skills/remotion-best-practices/rules/assets.md +78 -0
  461. package/packages/pi/skills/remotion-best-practices/rules/audio.md +172 -0
  462. package/packages/pi/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  463. package/packages/pi/skills/remotion-best-practices/rules/can-decode.md +75 -0
  464. package/packages/pi/skills/remotion-best-practices/rules/charts.md +58 -0
  465. package/packages/pi/skills/remotion-best-practices/rules/compositions.md +146 -0
  466. package/packages/pi/skills/remotion-best-practices/rules/display-captions.md +126 -0
  467. package/packages/pi/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  468. package/packages/pi/skills/remotion-best-practices/rules/fonts.md +152 -0
  469. package/packages/pi/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  470. package/packages/pi/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  471. package/packages/pi/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  472. package/packages/pi/skills/remotion-best-practices/rules/gifs.md +138 -0
  473. package/packages/pi/skills/remotion-best-practices/rules/images.md +130 -0
  474. package/packages/pi/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  475. package/packages/pi/skills/remotion-best-practices/rules/lottie.md +68 -0
  476. package/packages/pi/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  477. package/packages/pi/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  478. package/packages/pi/skills/remotion-best-practices/rules/sequencing.md +106 -0
  479. package/packages/pi/skills/remotion-best-practices/rules/tailwind.md +11 -0
  480. package/packages/pi/skills/remotion-best-practices/rules/text-animations.md +20 -0
  481. package/packages/pi/skills/remotion-best-practices/rules/timing.md +179 -0
  482. package/packages/pi/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  483. package/packages/pi/skills/remotion-best-practices/rules/transitions.md +122 -0
  484. package/packages/pi/skills/remotion-best-practices/rules/trimming.md +53 -0
  485. package/packages/pi/skills/remotion-best-practices/rules/videos.md +171 -0
  486. package/packages/pi/skills/search/SKILL.md +220 -0
  487. package/packages/pi/skills/spec/SKILL.md +377 -0
  488. package/packages/pi/skills/startup/SKILL.md +315 -0
  489. package/packages/pi/skills/web-architect/SKILL.md +309 -0
  490. package/packages/pi/skills/x-algorithm/SKILL.md +305 -0
  491. package/packages/pi/teams/dev-team.yaml +63 -0
  492. package/packages/pi/teams/gtm-team.yaml +79 -0
  493. package/packages/pi/themes/jfl.theme.json +76 -0
  494. package/packages/pi/tsconfig.json +21 -0
  495. package/scripts/collect-tuples.sh +124 -0
  496. package/scripts/destroy-fleet.sh +37 -0
  497. package/scripts/jfl-ide.sh +48 -0
  498. package/scripts/session/session-cleanup.sh +4 -11
  499. package/scripts/session/session-init.sh +6 -0
  500. package/scripts/session/session-sync.sh +25 -0
  501. package/scripts/setup-branch-protection.sh +106 -0
  502. package/scripts/spawn-fleet.sh +144 -0
  503. package/scripts/train/requirements.txt +5 -0
  504. package/scripts/train/train-policy-head.py +477 -0
  505. package/scripts/train/v2/dataset.py +81 -0
  506. package/scripts/train/v2/domain.json +18 -0
  507. package/scripts/train/v2/eval.py +196 -0
  508. package/scripts/train/v2/generate_data.py +219 -0
  509. package/scripts/train/v2/infer.py +188 -0
  510. package/scripts/train/v2/model.py +112 -0
  511. package/scripts/train/v2/precompute.py +132 -0
  512. package/scripts/train/v2/train.py +302 -0
  513. package/scripts/train/v2/transform_buffer.py +227 -0
  514. package/scripts/train/v2/validate_data.py +115 -0
  515. package/scripts/train-policy-head.py +434 -0
  516. package/scripts/vm-swarm/README.md +301 -0
  517. package/scripts/vm-swarm/collect-tuples.sh +331 -0
  518. package/scripts/vm-swarm/create-base-template.sh +339 -0
  519. package/scripts/vm-swarm/kill-fleet.sh +204 -0
  520. package/scripts/vm-swarm/monitor-fleet.sh +346 -0
  521. package/scripts/vm-swarm/spawn-fleet.sh +304 -0
  522. package/template/.claude/settings.json +2 -15
  523. package/template/.github/workflows/jfl-eval.yml +6 -1
  524. package/template/.github/workflows/jfl-review.yml +4 -0
  525. package/template/scripts/session/session-cleanup.sh +2 -11
  526. package/template/scripts/session/session-end-hub.sh +72 -0
  527. package/template/scripts/session/session-end.sh +69 -6
  528. package/template/scripts/session/session-init.sh +55 -30
  529. package/template/scripts/session/session-lock.sh +464 -0
  530. package/template/scripts/session/session-start-hub.sh +105 -0
  531. package/template/templates/service-agent/workflows/jfl-eval.yml +19 -0
  532. package/dist/dashboard-static/assets/index-B6kRK9Rq.js +0 -116
  533. package/dist/dashboard-static/assets/index-BpdKJPLu.css +0 -1
@@ -0,0 +1,629 @@
1
+ /**
2
+ * @purpose Audit GTM workspace docs — bifurcated: framework vs customer docs
3
+ *
4
+ * Framework docs: came from templates/skills, compare to upstream, track version drift
5
+ * Customer docs: PRDs, knowledge, custom content — analyze for staleness, token cost, relevance
6
+ *
7
+ * Core insight: "this doc costs you $X per day and adds zero value" > "this doc is long, split it"
8
+ */
9
+ import { existsSync, readFileSync, readdirSync, statSync } from "fs";
10
+ import { join, relative, basename } from "path";
11
+ // Markers that indicate a doc came from a framework/template
12
+ const FRAMEWORK_MARKERS = [
13
+ "<!-- jfl-template",
14
+ "<!-- generated by jfl",
15
+ "# generated by jfl",
16
+ "<!-- skill:",
17
+ "<!-- managed by",
18
+ "DO NOT EDIT — managed by",
19
+ "Auto-generated from template",
20
+ ];
21
+ // Directories that typically contain framework-managed content
22
+ const FRAMEWORK_DIRS = [
23
+ ".claude/skills",
24
+ ".claude/commands",
25
+ ".cursor/rules",
26
+ "skills/",
27
+ ];
28
+ // Directories that typically contain customer content
29
+ const CUSTOMER_DIRS = [
30
+ "knowledge/",
31
+ "docs/",
32
+ "prds/",
33
+ "specs/",
34
+ "rfcs/",
35
+ "design/",
36
+ "decisions/",
37
+ ];
38
+ // Well-known framework files
39
+ const FRAMEWORK_FILES = new Set([
40
+ "CLAUDE.md",
41
+ "AGENTS.md",
42
+ ".cursorrules",
43
+ ".claude/settings.json",
44
+ "CONVENTIONS.md",
45
+ "CONTRIBUTING.md",
46
+ ]);
47
+ const MAX_DOC_LINES = 300;
48
+ const STALE_DAYS = 14;
49
+ const TOKENS_PER_CHAR = 0.25; // rough estimate
50
+ // ============================================================================
51
+ // Main audit
52
+ // ============================================================================
53
+ export function auditDocs(projectRoot, insight) {
54
+ const result = {
55
+ docs: [],
56
+ totalDocs: 0,
57
+ totalLines: 0,
58
+ totalBytes: 0,
59
+ totalTokens: 0,
60
+ frameworkDocs: [],
61
+ customerDocs: [],
62
+ staleDocs: [],
63
+ bloatedDocs: [],
64
+ missingDocs: [],
65
+ unreferencedDocs: [],
66
+ recommendations: [],
67
+ };
68
+ const mdFiles = findMarkdownFiles(projectRoot);
69
+ const now = new Date();
70
+ // Build reference index from journals — which docs/paths get mentioned?
71
+ const journalReferences = buildJournalReferenceIndex(insight);
72
+ // Check for manifest (tracks what came from templates)
73
+ const manifest = loadManifest(projectRoot);
74
+ for (const filePath of mdFiles) {
75
+ const stat = statSync(filePath);
76
+ const content = readFileSync(filePath, "utf-8");
77
+ const lines = content.split("\n").length;
78
+ const relPath = relative(projectRoot, filePath);
79
+ const daysSinceModified = (now.getTime() - stat.mtime.getTime()) / (1000 * 60 * 60 * 24);
80
+ const tokenEstimate = Math.ceil(content.length * TOKENS_PER_CHAR);
81
+ // Classify origin
82
+ const origin = classifyOrigin(relPath, content, manifest);
83
+ // Calculate stale score
84
+ let staleScore = 0;
85
+ if (daysSinceModified > STALE_DAYS * 3)
86
+ staleScore = 1.0;
87
+ else if (daysSinceModified > STALE_DAYS * 2)
88
+ staleScore = 0.8;
89
+ else if (daysSinceModified > STALE_DAYS)
90
+ staleScore = 0.5;
91
+ else
92
+ staleScore = daysSinceModified / STALE_DAYS * 0.3;
93
+ // Calculate bloat score
94
+ let bloatScore = 0;
95
+ if (lines > MAX_DOC_LINES * 3)
96
+ bloatScore = 1.0;
97
+ else if (lines > MAX_DOC_LINES * 2)
98
+ bloatScore = 0.8;
99
+ else if (lines > MAX_DOC_LINES)
100
+ bloatScore = 0.5;
101
+ // Calculate relevance from journal references
102
+ const refCount = countReferences(relPath, journalReferences);
103
+ const relevanceScore = Math.min(1, refCount / 5); // 5+ references = fully relevant
104
+ // Extract sections (H1/H2)
105
+ const sections = extractSections(content);
106
+ // Count TODOs
107
+ const todoMatches = content.match(/\bTODO\b|\bFIXME\b|\bHACK\b|\bXXX\b/gi) || [];
108
+ const todoCount = todoMatches.length;
109
+ // Find dead links
110
+ const deadLinks = findDeadLinks(content, projectRoot);
111
+ // Build issues list
112
+ const issues = [];
113
+ if (staleScore > 0.5)
114
+ issues.push(`Not modified in ${Math.floor(daysSinceModified)} days`);
115
+ if (bloatScore > 0.5)
116
+ issues.push(`${lines} lines (${tokenEstimate} tokens)`);
117
+ if (relevanceScore < 0.1 && lines > 50)
118
+ issues.push("Never referenced in journals");
119
+ if (todoCount > 3)
120
+ issues.push(`${todoCount} unresolved TODOs`);
121
+ if (deadLinks.length > 0)
122
+ issues.push(`${deadLinks.length} dead link(s)`);
123
+ // Framework-specific: check for version drift
124
+ if (origin === "framework" && manifest) {
125
+ const entry = manifest.files?.[relPath];
126
+ if (entry?.templateVersion && entry?.currentHash) {
127
+ issues.push(`Template version: ${entry.templateVersion}`);
128
+ }
129
+ }
130
+ // Customer-specific: token cost awareness
131
+ if (origin === "customer" && relevanceScore < 0.2 && tokenEstimate > 1000) {
132
+ issues.push(`Costs ~${tokenEstimate} tokens/session with 0 journal references`);
133
+ }
134
+ const doc = {
135
+ path: filePath,
136
+ relativePath: relPath,
137
+ sizeBytes: stat.size,
138
+ lines,
139
+ lastModified: stat.mtime,
140
+ staleScore,
141
+ bloatScore,
142
+ relevanceScore,
143
+ origin,
144
+ tokenEstimate,
145
+ issues,
146
+ sections,
147
+ todoCount,
148
+ deadLinks,
149
+ referenceCount: refCount,
150
+ };
151
+ result.docs.push(doc);
152
+ result.totalDocs++;
153
+ result.totalLines += lines;
154
+ result.totalBytes += stat.size;
155
+ result.totalTokens += tokenEstimate;
156
+ if (origin === "framework")
157
+ result.frameworkDocs.push(doc);
158
+ else
159
+ result.customerDocs.push(doc);
160
+ if (staleScore > 0.5)
161
+ result.staleDocs.push(doc);
162
+ if (bloatScore > 0.5)
163
+ result.bloatedDocs.push(doc);
164
+ if (refCount === 0 && lines > 30)
165
+ result.unreferencedDocs.push(doc);
166
+ }
167
+ // Check for missing expected docs
168
+ checkMissingDocs(projectRoot, result);
169
+ // Generate bifurcated recommendations
170
+ result.recommendations = generateRecommendations(result, insight);
171
+ return result;
172
+ }
173
+ // ============================================================================
174
+ // Origin classification
175
+ // ============================================================================
176
+ function classifyOrigin(relPath, content, manifest) {
177
+ // Check manifest first (most reliable)
178
+ if (manifest?.files?.[relPath])
179
+ return "framework";
180
+ // Check for framework markers in content
181
+ const contentLower = content.toLowerCase();
182
+ for (const marker of FRAMEWORK_MARKERS) {
183
+ if (contentLower.includes(marker.toLowerCase()))
184
+ return "framework";
185
+ }
186
+ // Check well-known framework files
187
+ if (FRAMEWORK_FILES.has(basename(relPath)) || FRAMEWORK_FILES.has(relPath)) {
188
+ return "framework";
189
+ }
190
+ // Check directory-based heuristics
191
+ for (const dir of FRAMEWORK_DIRS) {
192
+ if (relPath.startsWith(dir))
193
+ return "framework";
194
+ }
195
+ for (const dir of CUSTOMER_DIRS) {
196
+ if (relPath.startsWith(dir))
197
+ return "customer";
198
+ }
199
+ // Default: if it's in the root, probably framework; if nested, probably customer
200
+ if (!relPath.includes("/"))
201
+ return "framework";
202
+ return "customer";
203
+ }
204
+ function buildJournalReferenceIndex(insight) {
205
+ const pathMentions = new Map();
206
+ const termMentions = new Map();
207
+ // File hotspots from journal analysis
208
+ for (const hotspot of insight.fileHotspots) {
209
+ pathMentions.set(hotspot.path, hotspot.touches);
210
+ }
211
+ // Common patterns → terms
212
+ for (const pattern of insight.commonPatterns) {
213
+ const words = pattern.toLowerCase().split(/\s+/).filter(w => w.length > 4);
214
+ for (const w of words) {
215
+ termMentions.set(w, (termMentions.get(w) || 0) + 1);
216
+ }
217
+ }
218
+ return { pathMentions, termMentions };
219
+ }
220
+ function countReferences(relPath, index) {
221
+ let count = 0;
222
+ // Direct path mentions
223
+ for (const [path, touches] of index.pathMentions) {
224
+ if (relPath.includes(path) || path.includes(relPath.replace(/\.md$/, ""))) {
225
+ count += touches;
226
+ }
227
+ }
228
+ // Term overlap (weaker signal)
229
+ const pathTerms = relPath.toLowerCase().replace(/[/_.-]/g, " ").split(/\s+/).filter(t => t.length > 4);
230
+ for (const term of pathTerms) {
231
+ count += (index.termMentions.get(term) || 0) * 0.2;
232
+ }
233
+ return Math.round(count);
234
+ }
235
+ // ============================================================================
236
+ // Recommendations — bifurcated by origin
237
+ // ============================================================================
238
+ function generateRecommendations(audit, insight) {
239
+ const recs = [];
240
+ // ---- Framework doc recommendations ----
241
+ for (const doc of audit.frameworkDocs) {
242
+ // Bloated framework docs → specific split guidance
243
+ if (doc.bloatScore > 0.5 && doc.sections.length > 3) {
244
+ const sectionList = doc.sections.slice(0, 6).join(", ");
245
+ recs.push({
246
+ type: "split",
247
+ target: doc.relativePath,
248
+ rationale: `${doc.lines} lines with ${doc.sections.length} sections (${sectionList}). Split by purpose: setup instructions, coding standards, and reference material should be separate files.`,
249
+ priority: doc.bloatScore > 0.8 ? 1 : 2,
250
+ estimatedSavings: `~${doc.tokenEstimate} tokens/session → ${Math.floor(doc.tokenEstimate * 0.4)} after split (agents only load relevant sections)`,
251
+ origin: "framework",
252
+ action: `Split into ${Math.min(doc.sections.length, 4)} focused files by section topic`,
253
+ });
254
+ }
255
+ else if (doc.bloatScore > 0.5) {
256
+ recs.push({
257
+ type: "trim",
258
+ target: doc.relativePath,
259
+ rationale: `${doc.lines} lines but only ${doc.sections.length || 1} section(s). Likely has verbose explanations that could be condensed.`,
260
+ priority: 2,
261
+ estimatedSavings: `~${Math.floor(doc.tokenEstimate * 0.3)} tokens removable`,
262
+ origin: "framework",
263
+ action: "Remove verbose explanations, convert prose to bullet points, eliminate redundant examples",
264
+ });
265
+ }
266
+ // Framework docs with many TODOs → template needs updating
267
+ if (doc.todoCount > 3) {
268
+ recs.push({
269
+ type: "update",
270
+ target: doc.relativePath,
271
+ rationale: `Framework doc has ${doc.todoCount} unresolved TODOs — template is shipping incomplete scaffolding`,
272
+ priority: 1,
273
+ origin: "framework",
274
+ action: "Resolve TODOs or remove placeholder sections that aren't actionable",
275
+ });
276
+ }
277
+ // Dead links in framework docs → broken template
278
+ if (doc.deadLinks.length > 0) {
279
+ recs.push({
280
+ type: "update",
281
+ target: doc.relativePath,
282
+ rationale: `${doc.deadLinks.length} dead link(s): ${doc.deadLinks.slice(0, 3).join(", ")}`,
283
+ priority: 1,
284
+ origin: "framework",
285
+ action: "Fix or remove broken references — these mislead agents",
286
+ });
287
+ }
288
+ }
289
+ // ---- Customer doc recommendations ----
290
+ for (const doc of audit.customerDocs) {
291
+ // Customer doc never referenced + large → biggest win
292
+ if (doc.referenceCount === 0 && doc.tokenEstimate > 500) {
293
+ const daysSinceModified = Math.floor((new Date().getTime() - doc.lastModified.getTime()) / (1000 * 60 * 60 * 24));
294
+ if (daysSinceModified > STALE_DAYS) {
295
+ recs.push({
296
+ type: "archive",
297
+ target: doc.relativePath,
298
+ rationale: `Costs ~${doc.tokenEstimate} tokens/session but has 0 journal references in ${insight.totalSessions} sessions. Last modified ${daysSinceModified} days ago. Archiving saves tokens without losing anything agents use.`,
299
+ priority: 1,
300
+ estimatedSavings: `${doc.tokenEstimate} tokens/session (~$${(doc.tokenEstimate * 0.000003 * 30).toFixed(2)}/month at typical rates)`,
301
+ origin: "customer",
302
+ action: `Move to archive/ or .jfl/archived-docs/ — recoverable but out of context window`,
303
+ });
304
+ }
305
+ else {
306
+ recs.push({
307
+ type: "archive",
308
+ target: doc.relativePath,
309
+ rationale: `${doc.tokenEstimate} tokens/session, 0 journal references across ${insight.totalSessions} sessions. Recently modified but agents aren't using it.`,
310
+ priority: 2,
311
+ estimatedSavings: `${doc.tokenEstimate} tokens/session`,
312
+ origin: "customer",
313
+ action: "Verify this doc is actually loaded into agent context. If not needed, archive it.",
314
+ });
315
+ }
316
+ }
317
+ // Customer doc with high reference count but stale → needs refresh
318
+ if (doc.referenceCount > 3 && doc.staleScore > 0.5) {
319
+ recs.push({
320
+ type: "refresh",
321
+ target: doc.relativePath,
322
+ rationale: `Referenced ${doc.referenceCount} times in journals but not updated in ${Math.floor((new Date().getTime() - doc.lastModified.getTime()) / (1000 * 60 * 60 * 24))} days. Agents rely on this — make sure it's accurate.`,
323
+ priority: 1,
324
+ origin: "customer",
325
+ action: "Review against current system state. Update or confirm accuracy.",
326
+ });
327
+ }
328
+ // Customer doc that's bloated → specific guidance based on sections
329
+ if (doc.bloatScore > 0.5) {
330
+ if (doc.sections.length >= 4) {
331
+ // Has clear section structure → can split meaningfully
332
+ const topicGroups = groupSections(doc.sections);
333
+ recs.push({
334
+ type: "split",
335
+ target: doc.relativePath,
336
+ rationale: `${doc.lines} lines across ${doc.sections.length} sections. Topics: ${topicGroups.join("; ")}. Splitting lets agents load only relevant context.`,
337
+ priority: 2,
338
+ estimatedSavings: `${doc.tokenEstimate} tokens → ~${Math.floor(doc.tokenEstimate / doc.sections.length)} per split file`,
339
+ origin: "customer",
340
+ action: `Split into ${Math.min(topicGroups.length, 4)} files by topic area`,
341
+ });
342
+ }
343
+ else {
344
+ // No clear sections → trim
345
+ recs.push({
346
+ type: "trim",
347
+ target: doc.relativePath,
348
+ rationale: `${doc.lines} lines but lacks clear section structure. Likely has redundant content or could be condensed.`,
349
+ priority: 3,
350
+ estimatedSavings: `~${Math.floor(doc.tokenEstimate * 0.3)} tokens removable`,
351
+ origin: "customer",
352
+ action: "Add section headers, remove redundant explanations, extract examples to separate files",
353
+ });
354
+ }
355
+ }
356
+ // Old TODOs in customer docs → stale promises
357
+ if (doc.todoCount > 0 && doc.staleScore > 0.3) {
358
+ recs.push({
359
+ type: "update",
360
+ target: doc.relativePath,
361
+ rationale: `${doc.todoCount} TODOs in a doc not updated in ${Math.floor((new Date().getTime() - doc.lastModified.getTime()) / (1000 * 60 * 60 * 24))} days — these are likely stale or completed`,
362
+ priority: 3,
363
+ origin: "customer",
364
+ action: "Resolve, remove, or convert stale TODOs to done items",
365
+ });
366
+ }
367
+ }
368
+ // ---- Cross-origin: duplication detection ----
369
+ const duplicateGroups = findPotentialDuplicates(audit.docs);
370
+ for (const group of duplicateGroups) {
371
+ recs.push({
372
+ type: "dedupe",
373
+ target: group.map(d => d.relativePath).join(" + "),
374
+ rationale: `These docs share similar topics (${group[0].sections.filter(s => group[1]?.sections.includes(s)).join(", ") || "similar content"}). Merge or deduplicate to reduce token cost.`,
375
+ priority: 2,
376
+ estimatedSavings: `~${group.reduce((sum, d) => sum + d.tokenEstimate, 0)} combined tokens → could halve with merge`,
377
+ origin: "unknown",
378
+ action: "Review for overlap. Keep one authoritative version.",
379
+ });
380
+ }
381
+ // ---- Missing docs for active areas ----
382
+ checkMissingDocsForActivity(audit, insight, recs);
383
+ // ---- Token budget summary ----
384
+ const unreferencedTokens = audit.unreferencedDocs.reduce((sum, d) => sum + d.tokenEstimate, 0);
385
+ if (unreferencedTokens > 5000) {
386
+ recs.unshift({
387
+ type: "archive",
388
+ target: `${audit.unreferencedDocs.length} unreferenced docs`,
389
+ rationale: `${audit.unreferencedDocs.length} docs (${unreferencedTokens} tokens) are never referenced in journals. Archiving all would save ~${unreferencedTokens} tokens/session.`,
390
+ priority: 1,
391
+ estimatedSavings: `${unreferencedTokens} tokens/session (~$${(unreferencedTokens * 0.000003 * 30 * 20).toFixed(2)}/month at 20 sessions/day)`,
392
+ origin: "unknown",
393
+ action: "Review list and archive docs that aren't needed in agent context",
394
+ });
395
+ }
396
+ return recs.sort((a, b) => a.priority - b.priority);
397
+ }
398
+ // ============================================================================
399
+ // Duplication detection
400
+ // ============================================================================
401
+ function findPotentialDuplicates(docs) {
402
+ const groups = [];
403
+ const seen = new Set();
404
+ for (let i = 0; i < docs.length; i++) {
405
+ if (seen.has(docs[i].relativePath))
406
+ continue;
407
+ if (docs[i].sections.length < 2)
408
+ continue;
409
+ const group = [docs[i]];
410
+ for (let j = i + 1; j < docs.length; j++) {
411
+ if (seen.has(docs[j].relativePath))
412
+ continue;
413
+ if (docs[j].sections.length < 2)
414
+ continue;
415
+ // Check section overlap
416
+ const overlap = docs[i].sections.filter(s => docs[j].sections.some(s2 => sectionsSimilar(s, s2)));
417
+ const overlapRatio = overlap.length / Math.min(docs[i].sections.length, docs[j].sections.length);
418
+ if (overlapRatio > 0.5) {
419
+ group.push(docs[j]);
420
+ seen.add(docs[j].relativePath);
421
+ }
422
+ }
423
+ if (group.length > 1) {
424
+ seen.add(docs[i].relativePath);
425
+ groups.push(group);
426
+ }
427
+ }
428
+ return groups.slice(0, 5); // cap at 5 groups
429
+ }
430
+ function sectionsSimilar(a, b) {
431
+ const normalize = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, " ").trim();
432
+ const na = normalize(a);
433
+ const nb = normalize(b);
434
+ if (na === nb)
435
+ return true;
436
+ // Check word overlap
437
+ const wa = new Set(na.split(/\s+/));
438
+ const wb = new Set(nb.split(/\s+/));
439
+ const intersection = [...wa].filter(w => wb.has(w) && w.length > 3);
440
+ return intersection.length >= 2;
441
+ }
442
+ // ============================================================================
443
+ // Helpers
444
+ // ============================================================================
445
+ function extractSections(content) {
446
+ const sections = [];
447
+ for (const line of content.split("\n")) {
448
+ const match = line.match(/^#{1,2}\s+(.+)/);
449
+ if (match)
450
+ sections.push(match[1].trim());
451
+ }
452
+ return sections;
453
+ }
454
+ function groupSections(sections) {
455
+ // Group sections by topic keywords
456
+ const topics = new Map();
457
+ for (const s of sections) {
458
+ const words = s.toLowerCase().split(/\s+/);
459
+ const key = words.find(w => w.length > 4) || words[0] || "misc";
460
+ if (!topics.has(key))
461
+ topics.set(key, []);
462
+ topics.get(key).push(s);
463
+ }
464
+ return [...topics.entries()].map(([topic, secs]) => `${topic} (${secs.length} sections)`).slice(0, 5);
465
+ }
466
+ function findDeadLinks(content, projectRoot) {
467
+ const dead = [];
468
+ const linkMatches = content.match(/\[([^\]]+)\]\(([^)]+)\)/g) || [];
469
+ for (const link of linkMatches) {
470
+ const match = link.match(/\]\(([^)]+)\)/);
471
+ if (!match || match[1].startsWith("http") || match[1].startsWith("#"))
472
+ continue;
473
+ const target = join(projectRoot, match[1]);
474
+ if (!existsSync(target))
475
+ dead.push(match[1]);
476
+ }
477
+ return dead;
478
+ }
479
+ function loadManifest(projectRoot) {
480
+ const paths = [
481
+ join(projectRoot, ".jfl", "manifest.json"),
482
+ join(projectRoot, ".jfl", "template-manifest.json"),
483
+ ];
484
+ for (const p of paths) {
485
+ if (existsSync(p)) {
486
+ try {
487
+ return JSON.parse(readFileSync(p, "utf-8"));
488
+ }
489
+ catch {
490
+ continue;
491
+ }
492
+ }
493
+ }
494
+ return null;
495
+ }
496
+ function checkMissingDocs(projectRoot, result) {
497
+ const expected = [
498
+ { name: "VISION.md", purpose: "North star and product direction" },
499
+ { name: "ROADMAP.md", purpose: "Current priorities and milestones" },
500
+ { name: "ARCHITECTURE.md", purpose: "System design and service map" },
501
+ { name: "CHANGELOG.md", purpose: "What shipped and when" },
502
+ ];
503
+ const knowledgeDir = join(projectRoot, "knowledge");
504
+ for (const exp of expected) {
505
+ const paths = [
506
+ join(projectRoot, exp.name),
507
+ join(knowledgeDir, exp.name),
508
+ ];
509
+ if (!paths.some(p => existsSync(p))) {
510
+ result.missingDocs.push(`${exp.name} — ${exp.purpose}`);
511
+ }
512
+ }
513
+ }
514
+ function checkMissingDocsForActivity(audit, insight, recs) {
515
+ for (const hotspot of insight.fileHotspots.slice(0, 5)) {
516
+ const dir = hotspot.path.split("/").slice(0, 2).join("/");
517
+ const hasDocs = audit.docs.some(d => d.relativePath.startsWith(dir));
518
+ if (!hasDocs && hotspot.touches > 10) {
519
+ recs.push({
520
+ type: "create",
521
+ target: `${dir}/README.md`,
522
+ rationale: `${hotspot.path} has ${hotspot.touches} touches across sessions but no documentation. Agents working here have no context.`,
523
+ priority: 2,
524
+ origin: "customer",
525
+ action: "Create a README explaining the purpose, key files, and conventions for this directory",
526
+ });
527
+ }
528
+ }
529
+ }
530
+ // ============================================================================
531
+ // Stratus-powered deep analysis
532
+ // ============================================================================
533
+ export function buildDocAuditPrompt(audit, insight) {
534
+ return `You are an expert at maintaining lean, effective workspace documentation for AI-assisted development.
535
+
536
+ ## Context
537
+ Total docs: ${audit.totalDocs} (${audit.totalLines} lines, ${audit.totalTokens} tokens, ${(audit.totalBytes / 1024).toFixed(0)}KB)
538
+ Framework docs: ${audit.frameworkDocs.length} (${audit.frameworkDocs.reduce((s, d) => s + d.tokenEstimate, 0)} tokens)
539
+ Customer docs: ${audit.customerDocs.length} (${audit.customerDocs.reduce((s, d) => s + d.tokenEstimate, 0)} tokens)
540
+ Unreferenced docs: ${audit.unreferencedDocs.length} (${audit.unreferencedDocs.reduce((s, d) => s + d.tokenEstimate, 0)} tokens wasted)
541
+
542
+ ## Framework Docs (from templates/skills — JFL manages these)
543
+ ${audit.frameworkDocs.filter(d => d.issues.length > 0).slice(0, 10).map(d => `- ${d.relativePath}: ${d.lines} lines, ${d.tokenEstimate} tokens, refs=${d.referenceCount}, sections=[${d.sections.slice(0, 4).join(", ")}] ${d.issues.length > 0 ? "⚠ " + d.issues.join("; ") : ""}`).join("\n") || "All clean"}
544
+
545
+ ## Customer Docs (PRDs, knowledge, roadmaps — user manages these)
546
+ ${audit.customerDocs.filter(d => d.issues.length > 0).slice(0, 15).map(d => `- ${d.relativePath}: ${d.lines} lines, ${d.tokenEstimate} tokens, refs=${d.referenceCount}, age=${Math.floor((new Date().getTime() - d.lastModified.getTime()) / 86400000)}d, sections=[${d.sections.slice(0, 4).join(", ")}] ${d.issues.length > 0 ? "⚠ " + d.issues.join("; ") : ""}`).join("\n") || "All clean"}
547
+
548
+ ## Unreferenced (never mentioned in ${insight.totalSessions} journal sessions)
549
+ ${audit.unreferencedDocs.slice(0, 10).map(d => `- ${d.relativePath}: ${d.tokenEstimate} tokens, origin=${d.origin}, age=${Math.floor((new Date().getTime() - d.lastModified.getTime()) / 86400000)}d`).join("\n") || "None"}
550
+
551
+ ## What agents actually work on (journal patterns)
552
+ ${insight.commonPatterns.slice(0, 8).join("\n") || "No patterns"}
553
+
554
+ ## Sessions: ${insight.totalSessions}, Entries: ${insight.totalEntries}
555
+
556
+ ## Instructions
557
+
558
+ Give specific, actionable recommendations. For each:
559
+ 1. **type**: "trim" | "update" | "create" | "archive" | "split" | "merge" | "refresh" | "dedupe"
560
+ 2. **target**: file path
561
+ 3. **rationale**: why, citing token costs and reference counts
562
+ 4. **priority**: 1-3
563
+ 5. **action**: exactly what to do (not generic "split into sections" — say which sections and why)
564
+ 6. **origin**: "framework" or "customer"
565
+ 7. **estimatedSavings**: token count saved
566
+
567
+ Key principle: "this doc costs N tokens/session and has 0 journal references" > "this doc is long"
568
+
569
+ Respond ONLY with valid JSON array. No markdown wrapping.`;
570
+ }
571
+ export async function getSmartDocRecommendations(projectRoot, insight) {
572
+ const audit = auditDocs(projectRoot, insight);
573
+ const prompt = buildDocAuditPrompt(audit, insight);
574
+ const apiKey = process.env.STRATUS_API_KEY;
575
+ const apiUrl = process.env.STRATUS_API_URL || "https://api.stratus.run/v1/chat/completions";
576
+ if (!apiKey)
577
+ return audit.recommendations;
578
+ try {
579
+ const response = await fetch(apiUrl, {
580
+ method: "POST",
581
+ headers: {
582
+ "Content-Type": "application/json",
583
+ "Authorization": `Bearer ${apiKey}`,
584
+ },
585
+ body: JSON.stringify({
586
+ model: "stratus-x1ac-base-claude-haiku-4-5",
587
+ messages: [{ role: "user", content: prompt }],
588
+ max_tokens: 3000,
589
+ temperature: 0.3,
590
+ }),
591
+ });
592
+ if (!response.ok)
593
+ return audit.recommendations;
594
+ const data = await response.json();
595
+ const content = data.choices?.[0]?.message?.content || "";
596
+ const jsonStr = content.replace(/^```json?\n?/, "").replace(/\n?```$/, "").trim();
597
+ const smartRecs = JSON.parse(jsonStr);
598
+ // Merge: smart recs first, then any heuristic recs not covered
599
+ return [...smartRecs, ...audit.recommendations.filter(r => !smartRecs.some(s => s.target === r.target && s.type === r.type))];
600
+ }
601
+ catch {
602
+ return audit.recommendations;
603
+ }
604
+ }
605
+ // ============================================================================
606
+ // File discovery
607
+ // ============================================================================
608
+ function findMarkdownFiles(dir, depth = 0) {
609
+ if (depth > 3)
610
+ return [];
611
+ const files = [];
612
+ const skip = new Set(["node_modules", ".git", ".jfl", "dist", "build", ".next", "__pycache__", "archive", "archived-docs"]);
613
+ try {
614
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
615
+ if (skip.has(entry.name))
616
+ continue;
617
+ const fullPath = join(dir, entry.name);
618
+ if (entry.isFile() && entry.name.endsWith(".md")) {
619
+ files.push(fullPath);
620
+ }
621
+ else if (entry.isDirectory()) {
622
+ files.push(...findMarkdownFiles(fullPath, depth + 1));
623
+ }
624
+ }
625
+ }
626
+ catch { /* permission errors */ }
627
+ return files;
628
+ }
629
+ //# sourceMappingURL=doc-auditor.js.map