jfl 0.4.4 → 0.5.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 (427) hide show
  1. package/dist/commands/context-hub.d.ts.map +1 -1
  2. package/dist/commands/context-hub.js +818 -39
  3. package/dist/commands/context-hub.js.map +1 -1
  4. package/dist/commands/eval.d.ts +1 -1
  5. package/dist/commands/eval.d.ts.map +1 -1
  6. package/dist/commands/eval.js +192 -1
  7. package/dist/commands/eval.js.map +1 -1
  8. package/dist/commands/findings.d.ts +6 -0
  9. package/dist/commands/findings.d.ts.map +1 -0
  10. package/dist/commands/findings.js +203 -0
  11. package/dist/commands/findings.js.map +1 -0
  12. package/dist/commands/hud.d.ts.map +1 -1
  13. package/dist/commands/hud.js +47 -9
  14. package/dist/commands/hud.js.map +1 -1
  15. package/dist/commands/ide.d.ts +27 -0
  16. package/dist/commands/ide.d.ts.map +1 -0
  17. package/dist/commands/ide.js +546 -0
  18. package/dist/commands/ide.js.map +1 -0
  19. package/dist/commands/onboard.d.ts.map +1 -1
  20. package/dist/commands/onboard.js +212 -2
  21. package/dist/commands/onboard.js.map +1 -1
  22. package/dist/commands/openclaw.d.ts +3 -0
  23. package/dist/commands/openclaw.d.ts.map +1 -1
  24. package/dist/commands/openclaw.js +76 -2
  25. package/dist/commands/openclaw.js.map +1 -1
  26. package/dist/commands/peter.d.ts +1 -0
  27. package/dist/commands/peter.d.ts.map +1 -1
  28. package/dist/commands/peter.js +935 -15
  29. package/dist/commands/peter.js.map +1 -1
  30. package/dist/commands/pi-fleet.d.ts +18 -0
  31. package/dist/commands/pi-fleet.d.ts.map +1 -0
  32. package/dist/commands/pi-fleet.js +382 -0
  33. package/dist/commands/pi-fleet.js.map +1 -0
  34. package/dist/commands/pi.d.ts.map +1 -1
  35. package/dist/commands/pi.js +18 -3
  36. package/dist/commands/pi.js.map +1 -1
  37. package/dist/commands/scope.d.ts.map +1 -1
  38. package/dist/commands/scope.js +90 -1
  39. package/dist/commands/scope.js.map +1 -1
  40. package/dist/commands/services.d.ts.map +1 -1
  41. package/dist/commands/services.js +18 -0
  42. package/dist/commands/services.js.map +1 -1
  43. package/dist/commands/status.d.ts.map +1 -1
  44. package/dist/commands/status.js +22 -4
  45. package/dist/commands/status.js.map +1 -1
  46. package/dist/commands/viz.d.ts.map +1 -1
  47. package/dist/commands/viz.js +417 -0
  48. package/dist/commands/viz.js.map +1 -1
  49. package/dist/dashboard-static/assets/index-B6b867Pv.js +121 -0
  50. package/dist/dashboard-static/assets/index-Y4BrqxV-.css +1 -0
  51. package/dist/dashboard-static/index.html +2 -2
  52. package/dist/index.js +225 -61
  53. package/dist/index.js.map +1 -1
  54. package/dist/lib/agent-config.d.ts +52 -0
  55. package/dist/lib/agent-config.d.ts.map +1 -0
  56. package/dist/lib/agent-config.js +231 -0
  57. package/dist/lib/agent-config.js.map +1 -0
  58. package/dist/lib/agent-generator.d.ts +10 -0
  59. package/dist/lib/agent-generator.d.ts.map +1 -1
  60. package/dist/lib/agent-generator.js +64 -10
  61. package/dist/lib/agent-generator.js.map +1 -1
  62. package/dist/lib/agent-session.d.ts +104 -0
  63. package/dist/lib/agent-session.d.ts.map +1 -0
  64. package/dist/lib/agent-session.js +627 -0
  65. package/dist/lib/agent-session.js.map +1 -0
  66. package/dist/lib/eval-snapshot.d.ts +47 -0
  67. package/dist/lib/eval-snapshot.d.ts.map +1 -0
  68. package/dist/lib/eval-snapshot.js +315 -0
  69. package/dist/lib/eval-snapshot.js.map +1 -0
  70. package/dist/lib/eval-store.d.ts +5 -0
  71. package/dist/lib/eval-store.d.ts.map +1 -1
  72. package/dist/lib/eval-store.js +33 -3
  73. package/dist/lib/eval-store.js.map +1 -1
  74. package/dist/lib/findings-engine.d.ts +51 -0
  75. package/dist/lib/findings-engine.d.ts.map +1 -0
  76. package/dist/lib/findings-engine.js +338 -0
  77. package/dist/lib/findings-engine.js.map +1 -0
  78. package/dist/lib/flow-engine.d.ts +8 -0
  79. package/dist/lib/flow-engine.d.ts.map +1 -1
  80. package/dist/lib/flow-engine.js +84 -2
  81. package/dist/lib/flow-engine.js.map +1 -1
  82. package/dist/lib/hub-client.d.ts +1 -0
  83. package/dist/lib/hub-client.d.ts.map +1 -1
  84. package/dist/lib/hub-client.js +33 -6
  85. package/dist/lib/hub-client.js.map +1 -1
  86. package/dist/lib/ide-panes.d.ts +58 -0
  87. package/dist/lib/ide-panes.d.ts.map +1 -0
  88. package/dist/lib/ide-panes.js +508 -0
  89. package/dist/lib/ide-panes.js.map +1 -0
  90. package/dist/lib/memory-db.js +4 -4
  91. package/dist/lib/memory-db.js.map +1 -1
  92. package/dist/lib/memory-indexer.d.ts.map +1 -1
  93. package/dist/lib/memory-indexer.js +3 -0
  94. package/dist/lib/memory-indexer.js.map +1 -1
  95. package/dist/lib/memory-search.d.ts +148 -4
  96. package/dist/lib/memory-search.d.ts.map +1 -1
  97. package/dist/lib/memory-search.js +496 -58
  98. package/dist/lib/memory-search.js.map +1 -1
  99. package/dist/lib/meta-orchestrator.d.ts +104 -0
  100. package/dist/lib/meta-orchestrator.d.ts.map +1 -0
  101. package/dist/lib/meta-orchestrator.js +373 -0
  102. package/dist/lib/meta-orchestrator.js.map +1 -0
  103. package/dist/lib/peer-agent-generator.d.ts.map +1 -1
  104. package/dist/lib/peer-agent-generator.js +43 -19
  105. package/dist/lib/peer-agent-generator.js.map +1 -1
  106. package/dist/lib/policy-head.d.ts +25 -0
  107. package/dist/lib/policy-head.d.ts.map +1 -0
  108. package/dist/lib/policy-head.js +136 -0
  109. package/dist/lib/policy-head.js.map +1 -0
  110. package/dist/lib/replay-buffer.d.ts +93 -0
  111. package/dist/lib/replay-buffer.d.ts.map +1 -0
  112. package/dist/lib/replay-buffer.js +302 -0
  113. package/dist/lib/replay-buffer.js.map +1 -0
  114. package/dist/lib/sentinel-rl.d.ts +97 -0
  115. package/dist/lib/sentinel-rl.d.ts.map +1 -0
  116. package/dist/lib/sentinel-rl.js +430 -0
  117. package/dist/lib/sentinel-rl.js.map +1 -0
  118. package/dist/lib/session-lock.d.ts +61 -0
  119. package/dist/lib/session-lock.d.ts.map +1 -0
  120. package/dist/lib/session-lock.js +438 -0
  121. package/dist/lib/session-lock.js.map +1 -0
  122. package/dist/lib/stratus-client.d.ts +1 -0
  123. package/dist/lib/stratus-client.d.ts.map +1 -1
  124. package/dist/lib/stratus-client.js +24 -2
  125. package/dist/lib/stratus-client.js.map +1 -1
  126. package/dist/lib/telemetry-agent-v2.d.ts +128 -0
  127. package/dist/lib/telemetry-agent-v2.d.ts.map +1 -0
  128. package/dist/lib/telemetry-agent-v2.js +1042 -0
  129. package/dist/lib/telemetry-agent-v2.js.map +1 -0
  130. package/dist/lib/telemetry-agent.d.ts.map +1 -1
  131. package/dist/lib/telemetry-agent.js +27 -6
  132. package/dist/lib/telemetry-agent.js.map +1 -1
  133. package/dist/lib/telemetry-digest.d.ts.map +1 -1
  134. package/dist/lib/telemetry-digest.js +27 -5
  135. package/dist/lib/telemetry-digest.js.map +1 -1
  136. package/dist/lib/telemetry.d.ts.map +1 -1
  137. package/dist/lib/telemetry.js +29 -4
  138. package/dist/lib/telemetry.js.map +1 -1
  139. package/dist/lib/text-preprocessing.d.ts +83 -0
  140. package/dist/lib/text-preprocessing.d.ts.map +1 -0
  141. package/dist/lib/text-preprocessing.js +261 -0
  142. package/dist/lib/text-preprocessing.js.map +1 -0
  143. package/dist/lib/training-buffer.d.ts +86 -0
  144. package/dist/lib/training-buffer.d.ts.map +1 -0
  145. package/dist/lib/training-buffer.js +139 -0
  146. package/dist/lib/training-buffer.js.map +1 -0
  147. package/dist/lib/tuple-miner.d.ts +30 -0
  148. package/dist/lib/tuple-miner.d.ts.map +1 -0
  149. package/dist/lib/tuple-miner.js +427 -0
  150. package/dist/lib/tuple-miner.js.map +1 -0
  151. package/dist/lib/vm-backend.d.ts +72 -0
  152. package/dist/lib/vm-backend.d.ts.map +1 -0
  153. package/dist/lib/vm-backend.js +175 -0
  154. package/dist/lib/vm-backend.js.map +1 -0
  155. package/dist/lib/workspace/backend.d.ts +53 -0
  156. package/dist/lib/workspace/backend.d.ts.map +1 -0
  157. package/dist/lib/workspace/backend.js +37 -0
  158. package/dist/lib/workspace/backend.js.map +1 -0
  159. package/dist/lib/workspace/cmux-adapter.d.ts +46 -0
  160. package/dist/lib/workspace/cmux-adapter.d.ts.map +1 -0
  161. package/dist/lib/workspace/cmux-adapter.js +261 -0
  162. package/dist/lib/workspace/cmux-adapter.js.map +1 -0
  163. package/dist/lib/workspace/data-pipeline.d.ts +35 -0
  164. package/dist/lib/workspace/data-pipeline.d.ts.map +1 -0
  165. package/dist/lib/workspace/data-pipeline.js +463 -0
  166. package/dist/lib/workspace/data-pipeline.js.map +1 -0
  167. package/dist/lib/workspace/engine.d.ts +64 -0
  168. package/dist/lib/workspace/engine.d.ts.map +1 -0
  169. package/dist/lib/workspace/engine.js +397 -0
  170. package/dist/lib/workspace/engine.js.map +1 -0
  171. package/dist/lib/workspace/notifications.d.ts +14 -0
  172. package/dist/lib/workspace/notifications.d.ts.map +1 -0
  173. package/dist/lib/workspace/notifications.js +41 -0
  174. package/dist/lib/workspace/notifications.js.map +1 -0
  175. package/dist/lib/workspace/surface-registry.d.ts +49 -0
  176. package/dist/lib/workspace/surface-registry.d.ts.map +1 -0
  177. package/dist/lib/workspace/surface-registry.js +217 -0
  178. package/dist/lib/workspace/surface-registry.js.map +1 -0
  179. package/dist/lib/workspace/surface-type.d.ts +153 -0
  180. package/dist/lib/workspace/surface-type.d.ts.map +1 -0
  181. package/dist/lib/workspace/surface-type.js +9 -0
  182. package/dist/lib/workspace/surface-type.js.map +1 -0
  183. package/dist/lib/workspace/surfaces/agent-overview.d.ts +16 -0
  184. package/dist/lib/workspace/surfaces/agent-overview.d.ts.map +1 -0
  185. package/dist/lib/workspace/surfaces/agent-overview.js +116 -0
  186. package/dist/lib/workspace/surfaces/agent-overview.js.map +1 -0
  187. package/dist/lib/workspace/surfaces/agent.d.ts +16 -0
  188. package/dist/lib/workspace/surfaces/agent.d.ts.map +1 -0
  189. package/dist/lib/workspace/surfaces/agent.js +112 -0
  190. package/dist/lib/workspace/surfaces/agent.js.map +1 -0
  191. package/dist/lib/workspace/surfaces/claude.d.ts +15 -0
  192. package/dist/lib/workspace/surfaces/claude.d.ts.map +1 -0
  193. package/dist/lib/workspace/surfaces/claude.js +23 -0
  194. package/dist/lib/workspace/surfaces/claude.js.map +1 -0
  195. package/dist/lib/workspace/surfaces/dashboard.d.ts +21 -0
  196. package/dist/lib/workspace/surfaces/dashboard.d.ts.map +1 -0
  197. package/dist/lib/workspace/surfaces/dashboard.js +32 -0
  198. package/dist/lib/workspace/surfaces/dashboard.js.map +1 -0
  199. package/dist/lib/workspace/surfaces/eval.d.ts +15 -0
  200. package/dist/lib/workspace/surfaces/eval.d.ts.map +1 -0
  201. package/dist/lib/workspace/surfaces/eval.js +42 -0
  202. package/dist/lib/workspace/surfaces/eval.js.map +1 -0
  203. package/dist/lib/workspace/surfaces/event-stream.d.ts +16 -0
  204. package/dist/lib/workspace/surfaces/event-stream.d.ts.map +1 -0
  205. package/dist/lib/workspace/surfaces/event-stream.js +40 -0
  206. package/dist/lib/workspace/surfaces/event-stream.js.map +1 -0
  207. package/dist/lib/workspace/surfaces/flow.d.ts +16 -0
  208. package/dist/lib/workspace/surfaces/flow.d.ts.map +1 -0
  209. package/dist/lib/workspace/surfaces/flow.js +49 -0
  210. package/dist/lib/workspace/surfaces/flow.js.map +1 -0
  211. package/dist/lib/workspace/surfaces/index.d.ts +16 -0
  212. package/dist/lib/workspace/surfaces/index.d.ts.map +1 -0
  213. package/dist/lib/workspace/surfaces/index.js +16 -0
  214. package/dist/lib/workspace/surfaces/index.js.map +1 -0
  215. package/dist/lib/workspace/surfaces/portfolio.d.ts +16 -0
  216. package/dist/lib/workspace/surfaces/portfolio.d.ts.map +1 -0
  217. package/dist/lib/workspace/surfaces/portfolio.js +102 -0
  218. package/dist/lib/workspace/surfaces/portfolio.js.map +1 -0
  219. package/dist/lib/workspace/surfaces/service.d.ts +16 -0
  220. package/dist/lib/workspace/surfaces/service.d.ts.map +1 -0
  221. package/dist/lib/workspace/surfaces/service.js +45 -0
  222. package/dist/lib/workspace/surfaces/service.js.map +1 -0
  223. package/dist/lib/workspace/surfaces/shell.d.ts +15 -0
  224. package/dist/lib/workspace/surfaces/shell.d.ts.map +1 -0
  225. package/dist/lib/workspace/surfaces/shell.js +19 -0
  226. package/dist/lib/workspace/surfaces/shell.js.map +1 -0
  227. package/dist/lib/workspace/surfaces/telemetry.d.ts +16 -0
  228. package/dist/lib/workspace/surfaces/telemetry.d.ts.map +1 -0
  229. package/dist/lib/workspace/surfaces/telemetry.js +48 -0
  230. package/dist/lib/workspace/surfaces/telemetry.js.map +1 -0
  231. package/dist/lib/workspace/surfaces/topology.d.ts +15 -0
  232. package/dist/lib/workspace/surfaces/topology.d.ts.map +1 -0
  233. package/dist/lib/workspace/surfaces/topology.js +19 -0
  234. package/dist/lib/workspace/surfaces/topology.js.map +1 -0
  235. package/dist/lib/workspace/surfaces/training.d.ts +16 -0
  236. package/dist/lib/workspace/surfaces/training.d.ts.map +1 -0
  237. package/dist/lib/workspace/surfaces/training.js +22 -0
  238. package/dist/lib/workspace/surfaces/training.js.map +1 -0
  239. package/dist/lib/workspace/tmux-adapter.d.ts +27 -0
  240. package/dist/lib/workspace/tmux-adapter.d.ts.map +1 -0
  241. package/dist/lib/workspace/tmux-adapter.js +106 -0
  242. package/dist/lib/workspace/tmux-adapter.js.map +1 -0
  243. package/dist/mcp/context-hub-mcp.js +7 -24
  244. package/dist/mcp/context-hub-mcp.js.map +1 -1
  245. package/dist/types/flows.d.ts +2 -0
  246. package/dist/types/flows.d.ts.map +1 -1
  247. package/dist/types/ide.d.ts +49 -0
  248. package/dist/types/ide.d.ts.map +1 -0
  249. package/dist/types/ide.js +5 -0
  250. package/dist/types/ide.js.map +1 -0
  251. package/dist/types/platform-digest.d.ts +228 -0
  252. package/dist/types/platform-digest.d.ts.map +1 -0
  253. package/dist/types/platform-digest.js +5 -0
  254. package/dist/types/platform-digest.js.map +1 -0
  255. package/dist/types/telemetry-digest.d.ts +2 -0
  256. package/dist/types/telemetry-digest.d.ts.map +1 -1
  257. package/dist/utils/ensure-project.d.ts +1 -0
  258. package/dist/utils/ensure-project.d.ts.map +1 -1
  259. package/dist/utils/ensure-project.js +19 -7
  260. package/dist/utils/ensure-project.js.map +1 -1
  261. package/dist/utils/jfl-config.d.ts +1 -0
  262. package/dist/utils/jfl-config.d.ts.map +1 -1
  263. package/dist/utils/jfl-config.js +19 -1
  264. package/dist/utils/jfl-config.js.map +1 -1
  265. package/dist/utils/jfl-paths.d.ts +5 -0
  266. package/dist/utils/jfl-paths.d.ts.map +1 -1
  267. package/dist/utils/jfl-paths.js +25 -3
  268. package/dist/utils/jfl-paths.js.map +1 -1
  269. package/package.json +3 -2
  270. package/packages/pi/AGENTS.md +112 -0
  271. package/packages/pi/extensions/agent-grid.ts +191 -0
  272. package/packages/pi/extensions/agent-names.ts +178 -0
  273. package/packages/pi/extensions/autoresearch.ts +427 -0
  274. package/packages/pi/extensions/bookmarks.ts +85 -0
  275. package/packages/pi/extensions/context.ts +151 -0
  276. package/packages/pi/extensions/crm-tool.ts +61 -0
  277. package/packages/pi/extensions/eval-tool.ts +224 -0
  278. package/packages/pi/extensions/eval.ts +60 -0
  279. package/packages/pi/extensions/footer.ts +239 -0
  280. package/packages/pi/extensions/hud-tool.ts +145 -0
  281. package/packages/pi/extensions/index.ts +392 -0
  282. package/packages/pi/extensions/journal.ts +224 -0
  283. package/packages/pi/extensions/map-bridge.ts +178 -0
  284. package/packages/pi/extensions/memory-tool.ts +68 -0
  285. package/packages/pi/extensions/notifications.ts +73 -0
  286. package/packages/pi/extensions/peter-parker.ts +202 -0
  287. package/packages/pi/extensions/policy-head-tool.ts +276 -0
  288. package/packages/pi/extensions/portfolio-bridge.ts +90 -0
  289. package/packages/pi/extensions/session.ts +90 -0
  290. package/packages/pi/extensions/shortcuts.ts +259 -0
  291. package/packages/pi/extensions/stratus-bridge.ts +115 -0
  292. package/packages/pi/extensions/synopsis-tool.ts +83 -0
  293. package/packages/pi/extensions/tool-renderers.ts +352 -0
  294. package/packages/pi/extensions/training-buffer-tool.ts +368 -0
  295. package/packages/pi/extensions/types.ts +163 -0
  296. package/packages/pi/package-lock.json +346 -0
  297. package/packages/pi/package.json +44 -0
  298. package/packages/pi/skills/agent-browser/SKILL.md +116 -0
  299. package/packages/pi/skills/brand-architect/SKILL.md +240 -0
  300. package/packages/pi/skills/brand-architect/config.yaml +137 -0
  301. package/packages/pi/skills/campaign-hud/config.yaml +112 -0
  302. package/packages/pi/skills/content-creator/SKILL.md +294 -0
  303. package/packages/pi/skills/context/SKILL.md +65 -0
  304. package/packages/pi/skills/debug/MULTI_AGENT.md +360 -0
  305. package/packages/pi/skills/debug/SKILL.md +554 -0
  306. package/packages/pi/skills/end/SKILL.md +1782 -0
  307. package/packages/pi/skills/eval/SKILL.md +75 -0
  308. package/packages/pi/skills/fly-deploy/SKILL.md +676 -0
  309. package/packages/pi/skills/founder-video/SKILL.md +467 -0
  310. package/packages/pi/skills/hud/SKILL.md +160 -0
  311. package/packages/pi/skills/orchestrate/SKILL.md +74 -0
  312. package/packages/pi/skills/pi-agents/SKILL.md +78 -0
  313. package/packages/pi/skills/react-best-practices/AGENTS.md +2249 -0
  314. package/packages/pi/skills/react-best-practices/README.md +123 -0
  315. package/packages/pi/skills/react-best-practices/SKILL.md +125 -0
  316. package/packages/pi/skills/react-best-practices/metadata.json +15 -0
  317. package/packages/pi/skills/react-best-practices/rules/_sections.md +46 -0
  318. package/packages/pi/skills/react-best-practices/rules/_template.md +28 -0
  319. package/packages/pi/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  320. package/packages/pi/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  321. package/packages/pi/skills/react-best-practices/rules/async-api-routes.md +38 -0
  322. package/packages/pi/skills/react-best-practices/rules/async-defer-await.md +80 -0
  323. package/packages/pi/skills/react-best-practices/rules/async-dependencies.md +36 -0
  324. package/packages/pi/skills/react-best-practices/rules/async-parallel.md +28 -0
  325. package/packages/pi/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  326. package/packages/pi/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  327. package/packages/pi/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  328. package/packages/pi/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  329. package/packages/pi/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  330. package/packages/pi/skills/react-best-practices/rules/bundle-preload.md +50 -0
  331. package/packages/pi/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  332. package/packages/pi/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  333. package/packages/pi/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  334. package/packages/pi/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  335. package/packages/pi/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  336. package/packages/pi/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  337. package/packages/pi/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  338. package/packages/pi/skills/react-best-practices/rules/js-early-exit.md +50 -0
  339. package/packages/pi/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  340. package/packages/pi/skills/react-best-practices/rules/js-index-maps.md +37 -0
  341. package/packages/pi/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  342. package/packages/pi/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  343. package/packages/pi/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  344. package/packages/pi/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  345. package/packages/pi/skills/react-best-practices/rules/rendering-activity.md +26 -0
  346. package/packages/pi/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  347. package/packages/pi/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  348. package/packages/pi/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  349. package/packages/pi/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  350. package/packages/pi/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  351. package/packages/pi/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  352. package/packages/pi/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  353. package/packages/pi/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  354. package/packages/pi/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  355. package/packages/pi/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  356. package/packages/pi/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  357. package/packages/pi/skills/react-best-practices/rules/rerender-memo.md +44 -0
  358. package/packages/pi/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  359. package/packages/pi/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  360. package/packages/pi/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  361. package/packages/pi/skills/react-best-practices/rules/server-cache-react.md +26 -0
  362. package/packages/pi/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
  363. package/packages/pi/skills/react-best-practices/rules/server-serialization.md +38 -0
  364. package/packages/pi/skills/remotion-best-practices/SKILL.md +43 -0
  365. package/packages/pi/skills/remotion-best-practices/rules/3d.md +86 -0
  366. package/packages/pi/skills/remotion-best-practices/rules/animations.md +29 -0
  367. package/packages/pi/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  368. package/packages/pi/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  369. package/packages/pi/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  370. package/packages/pi/skills/remotion-best-practices/rules/assets.md +78 -0
  371. package/packages/pi/skills/remotion-best-practices/rules/audio.md +172 -0
  372. package/packages/pi/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  373. package/packages/pi/skills/remotion-best-practices/rules/can-decode.md +75 -0
  374. package/packages/pi/skills/remotion-best-practices/rules/charts.md +58 -0
  375. package/packages/pi/skills/remotion-best-practices/rules/compositions.md +146 -0
  376. package/packages/pi/skills/remotion-best-practices/rules/display-captions.md +126 -0
  377. package/packages/pi/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  378. package/packages/pi/skills/remotion-best-practices/rules/fonts.md +152 -0
  379. package/packages/pi/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  380. package/packages/pi/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  381. package/packages/pi/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  382. package/packages/pi/skills/remotion-best-practices/rules/gifs.md +138 -0
  383. package/packages/pi/skills/remotion-best-practices/rules/images.md +130 -0
  384. package/packages/pi/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
  385. package/packages/pi/skills/remotion-best-practices/rules/lottie.md +68 -0
  386. package/packages/pi/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
  387. package/packages/pi/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  388. package/packages/pi/skills/remotion-best-practices/rules/sequencing.md +106 -0
  389. package/packages/pi/skills/remotion-best-practices/rules/tailwind.md +11 -0
  390. package/packages/pi/skills/remotion-best-practices/rules/text-animations.md +20 -0
  391. package/packages/pi/skills/remotion-best-practices/rules/timing.md +179 -0
  392. package/packages/pi/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
  393. package/packages/pi/skills/remotion-best-practices/rules/transitions.md +122 -0
  394. package/packages/pi/skills/remotion-best-practices/rules/trimming.md +53 -0
  395. package/packages/pi/skills/remotion-best-practices/rules/videos.md +171 -0
  396. package/packages/pi/skills/search/SKILL.md +220 -0
  397. package/packages/pi/skills/spec/SKILL.md +377 -0
  398. package/packages/pi/skills/startup/SKILL.md +315 -0
  399. package/packages/pi/skills/web-architect/SKILL.md +309 -0
  400. package/packages/pi/skills/x-algorithm/SKILL.md +305 -0
  401. package/packages/pi/teams/dev-team.yaml +63 -0
  402. package/packages/pi/teams/gtm-team.yaml +79 -0
  403. package/packages/pi/themes/jfl.theme.json +76 -0
  404. package/packages/pi/tsconfig.json +21 -0
  405. package/scripts/collect-tuples.sh +124 -0
  406. package/scripts/destroy-fleet.sh +37 -0
  407. package/scripts/jfl-ide.sh +48 -0
  408. package/scripts/session/session-cleanup.sh +4 -11
  409. package/scripts/session/session-init.sh +6 -0
  410. package/scripts/session/session-sync.sh +25 -0
  411. package/scripts/setup-branch-protection.sh +106 -0
  412. package/scripts/spawn-fleet.sh +144 -0
  413. package/scripts/train-policy-head.py +434 -0
  414. package/scripts/vm-swarm/README.md +301 -0
  415. package/scripts/vm-swarm/collect-tuples.sh +331 -0
  416. package/scripts/vm-swarm/create-base-template.sh +339 -0
  417. package/scripts/vm-swarm/kill-fleet.sh +204 -0
  418. package/scripts/vm-swarm/monitor-fleet.sh +346 -0
  419. package/scripts/vm-swarm/spawn-fleet.sh +304 -0
  420. package/template/.github/workflows/jfl-eval.yml +6 -1
  421. package/template/.github/workflows/jfl-review.yml +4 -0
  422. package/template/scripts/session/session-end.sh +69 -6
  423. package/template/scripts/session/session-init.sh +55 -30
  424. package/template/scripts/session/session-lock.sh +464 -0
  425. package/template/templates/service-agent/workflows/jfl-eval.yml +19 -0
  426. package/dist/dashboard-static/assets/index-B6kRK9Rq.js +0 -116
  427. package/dist/dashboard-static/assets/index-BpdKJPLu.css +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jfl",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "description": "Just Fucking Launch - CLI for AI-powered GTM and development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,6 +11,7 @@
11
11
  },
12
12
  "files": [
13
13
  "dist",
14
+ "packages/pi",
14
15
  "scripts",
15
16
  "template",
16
17
  "clawdbot-skill",
@@ -90,7 +91,7 @@
90
91
  "@types/react": "^19.2.13",
91
92
  "@types/sql.js": "^1.4.9",
92
93
  "@types/ws": "^8.18.1",
93
- "jest": "^30.2.0",
94
+ "jest": "^30.3.0",
94
95
  "ts-jest": "^29.4.6",
95
96
  "tsx": "^4.7.0",
96
97
  "typescript": "^5.3.3"
@@ -0,0 +1,112 @@
1
+ # @jfl/pi — Multi-Agent Coordination
2
+
3
+ This document describes how multiple Pi sessions coordinate within a JFL project.
4
+
5
+ ## Session Isolation
6
+
7
+ Each Pi session gets its own branch (via JFL session management):
8
+ ```
9
+ session-goose-20260125-xxxx
10
+ session-hath-20260126-xxxx
11
+ ```
12
+
13
+ Agents write to their own journal files:
14
+ ```
15
+ .jfl/journal/session-goose-20260125-xxxx.jsonl
16
+ .jfl/journal/session-hath-20260126-xxxx.jsonl
17
+ ```
18
+
19
+ Context Hub aggregates all journals — each agent can see what others did via `jfl_context`.
20
+
21
+ ## Event Bus Coordination
22
+
23
+ All agents connect to the same Context Hub (port 4242) via the MAP event bus.
24
+
25
+ Key events agents emit and consume:
26
+
27
+ | Event | Emitter | Consumers |
28
+ |-------|---------|-----------|
29
+ | `agent:health` | All agents | Grid overlay, PP |
30
+ | `eval:scored` | Eval agent | PP, Stratus bridge |
31
+ | `review:findings` | Reviewer agent | PP |
32
+ | `task:requested` | PP, human | Builder agent |
33
+ | `journal:entry` | Any agent | Footer, context |
34
+ | `peter:dispatched` | PP | Status display |
35
+ | `peter:completed` | PP | Status display |
36
+
37
+ ## Scope Enforcement
38
+
39
+ Each GTM can declare a context scope in `.jfl/config.json`:
40
+
41
+ ```json
42
+ {
43
+ "context_scope": {
44
+ "produces": ["discovery:*", "eval:*"],
45
+ "consumes": ["strategy:*", "seo:serp-data"],
46
+ "denied": ["portfolio:financial-*"]
47
+ }
48
+ }
49
+ ```
50
+
51
+ The `map-bridge` extension reads this and filters subscriptions accordingly.
52
+ Cross-GTM leakage is blocked at the subscription level.
53
+
54
+ ## Portfolio Hierarchy
55
+
56
+ ```
57
+ portfolio-hub (runs Context Hub on port 4242)
58
+ ├── productrank-gtm (port 4243)
59
+ │ └── agents: scout, builder, eval
60
+ ├── seo-agent (port 4244)
61
+ │ └── agents: crawler, ranker
62
+ └── visaclaw (port 4245)
63
+ └── agents: mcp-registry, payment
64
+ ```
65
+
66
+ Each GTM's `portfolio-bridge` extension phones home to parent on session end,
67
+ syncing journals and eval scores for cross-GTM RL training.
68
+
69
+ ## Peter Parker Loop
70
+
71
+ PP runs in the primary session and orchestrates others via Pi RPC:
72
+
73
+ ```
74
+ task:requested → PP queries Stratus → pick best action
75
+ → spawn Pi RPC agent
76
+ → monitor → eval:scored
77
+ → if findings: spawn reviewer
78
+ → max 5 iterations
79
+ → peter:completed
80
+ ```
81
+
82
+ ## Running Multiple Sessions
83
+
84
+ ```bash
85
+ # Terminal 1: Your interactive session
86
+ jfl pi
87
+
88
+ # Terminal 2: Spawn agent team
89
+ jfl pi agents run --team teams/gtm-team.yaml
90
+
91
+ # Inside Pi session: monitor agents
92
+ /grid
93
+
94
+ # Inside Pi session: trigger PP task
95
+ /peter Fix the failing evals in src/lib/eval.ts
96
+ ```
97
+
98
+ ## Debugging
99
+
100
+ ```bash
101
+ # Watch all MAP events
102
+ jfl flows watch
103
+
104
+ # Check agent health
105
+ curl http://localhost:4242/api/events?pattern=agent:health
106
+
107
+ # View training buffer
108
+ tail -f ~/.jfl/training-buffer.jsonl
109
+
110
+ # View journal across all sessions
111
+ cat .jfl/journal/*.jsonl | sort -t'"' -k4 | tail -20
112
+ ```
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Agent Grid Extension
3
+ *
4
+ * /grid command shows a live overlay of all active Pi sessions.
5
+ * Polls Context Hub for agent:health events.
6
+ * Beautiful themed card layout with status icons.
7
+ *
8
+ * @purpose /grid command — themed agent status overlay with live polling
9
+ */
10
+
11
+ import { existsSync, readdirSync, statSync } from "fs"
12
+ import { join } from "path"
13
+ import type { PiContext, PiTheme } from "./types.js"
14
+ import { hubUrl, authToken } from "./map-bridge.js"
15
+ import { resolveDisplayName, formatAgentLabel } from "./agent-names.js"
16
+
17
+ interface AgentHealth {
18
+ name: string
19
+ role: string
20
+ status: "running" | "idle" | "blocked" | "error"
21
+ task?: string
22
+ duration?: number
23
+ model?: string
24
+ lastSeen: number
25
+ }
26
+
27
+ const agents = new Map<string, AgentHealth>()
28
+
29
+ function formatDuration(ms?: number): string {
30
+ if (!ms) return "-"
31
+ const s = Math.floor(ms / 1000)
32
+ if (s < 60) return `${s}s`
33
+ const m = Math.floor(s / 60)
34
+ const rs = s % 60
35
+ return `${m}m${rs > 0 ? ` ${rs}s` : ""}`
36
+ }
37
+
38
+ async function pollAgentHealth(): Promise<void> {
39
+ try {
40
+ const resp = await fetch(`${hubUrl}/api/events?pattern=agent:health&limit=50`, {
41
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {},
42
+ })
43
+ if (!resp.ok) return
44
+
45
+ const data = await resp.json() as { events?: Array<{ data?: AgentHealth; ts?: string }> }
46
+ for (const event of data.events ?? []) {
47
+ if (!event.data?.name) continue
48
+ agents.set(event.data.name, {
49
+ ...event.data,
50
+ lastSeen: event.ts ? new Date(event.ts).getTime() : Date.now(),
51
+ })
52
+ }
53
+ } catch {}
54
+ }
55
+
56
+ function getLocalSessions(root: string): Array<{ name: string; age: number }> {
57
+ const journalDir = join(root, ".jfl", "journal")
58
+ if (!existsSync(journalDir)) return []
59
+ const now = Date.now()
60
+ const sessions: Array<{ name: string; age: number }> = []
61
+ for (const f of readdirSync(journalDir)) {
62
+ if (!f.startsWith("session-") || !f.endsWith(".jsonl")) continue
63
+ try {
64
+ const stat = statSync(join(journalDir, f))
65
+ const age = now - stat.mtimeMs
66
+ if (age < 600000) {
67
+ sessions.push({ name: resolveDisplayName(f.replace(".jsonl", "").replace("session-", "")), age })
68
+ }
69
+ } catch {}
70
+ }
71
+ return sessions
72
+ }
73
+
74
+ export function setupAgentGrid(ctx: PiContext): void {
75
+ ctx.on("map:agent:health", (data) => {
76
+ const health = data as AgentHealth
77
+ if (!health.name) return
78
+ agents.set(health.name, { ...health, lastSeen: Date.now() })
79
+ })
80
+
81
+ ctx.registerCommand({
82
+ name: "grid",
83
+ description: "Show live agent grid overlay",
84
+ async handler(_args, ctx) {
85
+ if (!ctx.ui.hasUI) {
86
+ ctx.ui.notify("Agent grid requires interactive mode", { level: "warn" })
87
+ return
88
+ }
89
+
90
+ await pollAgentHealth()
91
+
92
+ await ctx.ui.custom<void>((tui: any, theme: PiTheme, _kb: any, done: (r: void) => void) => {
93
+ let interval: ReturnType<typeof setInterval> | null = null
94
+
95
+ interval = setInterval(async () => {
96
+ await pollAgentHealth()
97
+ tui.requestRender()
98
+ }, 3000)
99
+
100
+ return {
101
+ handleInput(key: string) {
102
+ if (key === "\x1b" || key === "q") {
103
+ if (interval) clearInterval(interval)
104
+ done(undefined)
105
+ }
106
+ },
107
+
108
+ render(width: number): string[] {
109
+ const w = Math.min(width, 80)
110
+ const lines: string[] = []
111
+ const agentList = Array.from(agents.values())
112
+ const localSessions = getLocalSessions(ctx.session.projectRoot)
113
+
114
+ lines.push("")
115
+ lines.push(` ${theme.fg("accent", "◆")} ${theme.bold("Agent Grid")}`)
116
+ lines.push(` ${theme.fg("border", "─".repeat(w - 4))}`)
117
+ lines.push("")
118
+
119
+ if (agentList.length > 0) {
120
+ lines.push(` ${theme.fg("accent", "MAP Agents")} ${theme.fg("dim", `(${agentList.length})`)}`)
121
+ lines.push("")
122
+
123
+ for (const a of agentList) {
124
+ const now = Date.now()
125
+ const age = now - a.lastSeen
126
+ const isOnline = age < 30000
127
+
128
+ const statusIcon = a.status === "running" ? theme.fg("success", "●")
129
+ : a.status === "error" ? theme.fg("error", "✗")
130
+ : a.status === "blocked" ? theme.fg("warning", "◆")
131
+ : theme.fg("dim", "○")
132
+
133
+ const onlineStr = isOnline ? "" : theme.fg("error", " (offline)")
134
+ const displayName = resolveDisplayName(a.name)
135
+
136
+ lines.push(` ${statusIcon} ${theme.fg("text", displayName.padEnd(20))} ${theme.fg("muted", a.role ?? "")}${onlineStr}`)
137
+
138
+ if (a.task) {
139
+ lines.push(` ${theme.fg("dim", a.task.slice(0, w - 8))}`)
140
+ }
141
+ if (a.model || a.duration) {
142
+ const parts = [
143
+ a.model ? theme.fg("dim", a.model) : "",
144
+ a.duration ? theme.fg("dim", formatDuration(a.duration)) : "",
145
+ ].filter(Boolean)
146
+ if (parts.length) lines.push(` ${parts.join(" │ ")}`)
147
+ }
148
+ }
149
+ }
150
+
151
+ if (localSessions.length > 0) {
152
+ if (agentList.length > 0) lines.push("")
153
+ lines.push(` ${theme.fg("accent", "Local Sessions")} ${theme.fg("dim", `(${localSessions.length})`)}`)
154
+ lines.push("")
155
+
156
+ for (const s of localSessions) {
157
+ const ageStr = s.age < 60000 ? `${Math.floor(s.age / 1000)}s`
158
+ : s.age < 3600000 ? `${Math.floor(s.age / 60000)}m`
159
+ : `${Math.floor(s.age / 3600000)}h`
160
+ const icon = s.age < 120000 ? theme.fg("success", "●") : theme.fg("dim", "○")
161
+ lines.push(` ${icon} ${theme.fg("text", s.name)} ${theme.fg("dim", ageStr + " ago")}`)
162
+ }
163
+ }
164
+
165
+ if (agentList.length === 0 && localSessions.length === 0) {
166
+ lines.push(` ${theme.fg("dim", "No active agents or sessions")}`)
167
+ lines.push(` ${theme.fg("dim", "Start agents: jfl pi agents run --team teams/gtm-team.yaml")}`)
168
+ }
169
+
170
+ lines.push("")
171
+ lines.push(` ${theme.fg("dim", "Esc/q close │ refreshes every 3s")}`)
172
+ lines.push("")
173
+
174
+ return lines
175
+ },
176
+
177
+ invalidate() {},
178
+ }
179
+ }, { overlay: true })
180
+ },
181
+ })
182
+ }
183
+
184
+ export function emitAgentHealth(
185
+ ctx: PiContext,
186
+ health: Omit<AgentHealth, "lastSeen">
187
+ ): void {
188
+ ctx.emit("agent:health", { ...health, ts: new Date().toISOString() })
189
+ }
190
+
191
+ export function stopAgentGrid(): void {}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Agent Display Name Resolver
3
+ *
4
+ * Converts raw agent identifiers (file paths, kebab-case names, frontmatter names)
5
+ * into clean, human-readable display names for the TUI.
6
+ *
7
+ * @purpose Resolve ugly agent IDs to pretty display names across all TUI surfaces
8
+ */
9
+
10
+ import { existsSync, readFileSync, readdirSync } from "fs"
11
+ import { join, basename } from "path"
12
+
13
+ export interface AgentInfo {
14
+ id: string
15
+ displayName: string
16
+ type: "service" | "peer" | "skill" | "custom"
17
+ color?: string
18
+ description?: string
19
+ serviceName?: string
20
+ }
21
+
22
+ const displayNameCache = new Map<string, AgentInfo>()
23
+ let projectRoot = ""
24
+
25
+ export function initAgentNames(root: string): void {
26
+ projectRoot = root
27
+ displayNameCache.clear()
28
+ scanAgentFiles(root)
29
+ }
30
+
31
+ function scanAgentFiles(root: string): void {
32
+ const agentsDir = join(root, ".claude", "agents")
33
+ if (!existsSync(agentsDir)) return
34
+
35
+ for (const file of readdirSync(agentsDir)) {
36
+ if (!file.endsWith(".md") || file.startsWith("_") || file === "README.md") continue
37
+
38
+ const filePath = join(agentsDir, file)
39
+ try {
40
+ const content = readFileSync(filePath, "utf-8")
41
+ const info = parseAgentFile(file, content)
42
+ if (info) displayNameCache.set(info.id, info)
43
+ } catch {}
44
+ }
45
+ }
46
+
47
+ function parseAgentFile(filename: string, content: string): AgentInfo | null {
48
+ const id = filename.replace(/\.md$/, "")
49
+
50
+ const frontmatter = parseFrontmatter(content)
51
+ const fmName = frontmatter.name ?? id
52
+ const color = frontmatter.color
53
+ const description = frontmatter.description
54
+
55
+ const type = detectAgentType(id, frontmatter)
56
+ const serviceName = extractServiceName(id)
57
+ const displayName = frontmatter.label
58
+ ?? frontmatter.display_name
59
+ ?? buildDisplayName(id, type)
60
+
61
+ return { id, displayName, type, color, description, serviceName }
62
+ }
63
+
64
+ function parseFrontmatter(content: string): Record<string, string> {
65
+ const match = content.match(/^---\n([\s\S]*?)\n---/)
66
+ if (!match) return {}
67
+
68
+ const result: Record<string, string> = {}
69
+ for (const line of match[1].split("\n")) {
70
+ const kv = line.match(/^(\w[\w_-]*)\s*:\s*(.+)/)
71
+ if (kv) result[kv[1]] = kv[2].trim()
72
+ }
73
+ return result
74
+ }
75
+
76
+ function detectAgentType(id: string, fm: Record<string, string>): AgentInfo["type"] {
77
+ if (fm.type === "peer-service" || id.startsWith("peer-service-") || id.startsWith("peer-")) return "peer"
78
+ if (id.startsWith("service-") || fm.type === "service") return "service"
79
+ const skillNames = ["web-architect", "content-creator", "brand-architect"]
80
+ if (skillNames.includes(id)) return "skill"
81
+ return "custom"
82
+ }
83
+
84
+ function extractServiceName(id: string): string {
85
+ return id
86
+ .replace(/^service-/, "")
87
+ .replace(/^peer-service-/, "")
88
+ .replace(/^peer-/, "")
89
+ }
90
+
91
+ function buildDisplayName(id: string, type: AgentInfo["type"]): string {
92
+ const clean = extractServiceName(id)
93
+ const titled = kebabToTitle(clean)
94
+ if (type === "peer") return titled
95
+ return titled
96
+ }
97
+
98
+ const ACRONYMS = new Set(["api", "ui", "cli", "db", "ml", "ai", "ci", "cd", "io", "id", "url", "uri", "sdk", "rl", "mcp", "gtm", "crm", "cms", "cdn", "dns", "tcp", "udp", "ssh", "tls", "ssl", "jwt", "aws", "gcp"])
99
+
100
+ function kebabToTitle(str: string): string {
101
+ return str
102
+ .split("-")
103
+ .map(word => ACRONYMS.has(word.toLowerCase()) ? word.toUpperCase() : word.charAt(0).toUpperCase() + word.slice(1))
104
+ .join(" ")
105
+ }
106
+
107
+ /**
108
+ * Resolve any raw agent identifier to a clean display name.
109
+ *
110
+ * Handles:
111
+ * .claude/agents/service-stratus-api.md → Stratus API
112
+ * service-stratus-api → Stratus API
113
+ * peer-service-context-hub → Context Hub
114
+ * stratus-api.md → Stratus API
115
+ * web-architect → Web Architect
116
+ */
117
+ export function resolveDisplayName(raw: string): string {
118
+ const id = raw
119
+ .replace(/^@/, "")
120
+ .replace(/^\.?claude\/agents\//, "")
121
+ .replace(/\.md$/, "")
122
+ .replace(/^.*\//, "")
123
+
124
+ const cached = displayNameCache.get(id)
125
+ if (cached) return cached.displayName
126
+
127
+ const type = detectAgentType(id, {})
128
+ return buildDisplayName(id, type)
129
+ }
130
+
131
+ /**
132
+ * Resolve to full agent info (name, type, color, description).
133
+ */
134
+ export function resolveAgentInfo(raw: string): AgentInfo {
135
+ const id = raw
136
+ .replace(/^@/, "")
137
+ .replace(/^\.?claude\/agents\//, "")
138
+ .replace(/\.md$/, "")
139
+ .replace(/^.*\//, "")
140
+
141
+ const cached = displayNameCache.get(id)
142
+ if (cached) return cached
143
+
144
+ const type = detectAgentType(id, {})
145
+ return {
146
+ id,
147
+ displayName: buildDisplayName(id, type),
148
+ type,
149
+ serviceName: extractServiceName(id),
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Get all known agents with display info.
155
+ */
156
+ export function listAgents(): AgentInfo[] {
157
+ if (displayNameCache.size === 0 && projectRoot) scanAgentFiles(projectRoot)
158
+ return Array.from(displayNameCache.values())
159
+ }
160
+
161
+ /**
162
+ * Format an agent name for TUI display with optional type badge.
163
+ */
164
+ export function formatAgentLabel(raw: string, opts?: { badge?: boolean }): string {
165
+ const info = resolveAgentInfo(raw)
166
+
167
+ if (!opts?.badge) return info.displayName
168
+
169
+ const badges: Record<AgentInfo["type"], string> = {
170
+ service: "svc",
171
+ peer: "peer",
172
+ skill: "skill",
173
+ custom: "",
174
+ }
175
+
176
+ const badge = badges[info.type]
177
+ return badge ? `${info.displayName} [${badge}]` : info.displayName
178
+ }