@xhulz/nina 0.71.0 → 0.73.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 (272) hide show
  1. package/package.json +1 -1
  2. package/releases/0.72.0/core/GAPS.md +125 -0
  3. package/releases/0.72.0/core/answered.json +104 -0
  4. package/releases/0.72.0/core/defaults/tree/.claude/agents/architect.md +1 -0
  5. package/releases/0.72.0/core/defaults/tree/.claude/agents/dba.md +3 -0
  6. package/releases/0.72.0/core/defaults/tree/.claude/agents/devops.md +1 -0
  7. package/releases/0.72.0/core/defaults/tree/.claude/agents/implementer.md +1 -0
  8. package/releases/0.72.0/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
  9. package/releases/0.72.0/core/defaults/tree/.claude/agents/qa.md +7 -0
  10. package/releases/0.72.0/core/defaults/tree/.claude/agents/reviewer.md +3 -0
  11. package/releases/0.72.0/core/defaults/tree/.claude/agents/secops.md +3 -0
  12. package/releases/0.72.0/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
  13. package/releases/0.72.0/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
  14. package/releases/0.72.0/core/tree/.claude/agents/architect.md +135 -0
  15. package/releases/0.72.0/core/tree/.claude/agents/dba.md +119 -0
  16. package/releases/0.72.0/core/tree/.claude/agents/design-reviewer.md +78 -0
  17. package/releases/0.72.0/core/tree/.claude/agents/devops.md +118 -0
  18. package/releases/0.72.0/core/tree/.claude/agents/implementer.md +184 -0
  19. package/releases/0.72.0/core/tree/.claude/agents/integration-tester.md +170 -0
  20. package/releases/0.72.0/core/tree/.claude/agents/planner.md +132 -0
  21. package/releases/0.72.0/core/tree/.claude/agents/qa.md +150 -0
  22. package/releases/0.72.0/core/tree/.claude/agents/reviewer.md +187 -0
  23. package/releases/0.72.0/core/tree/.claude/agents/secops.md +120 -0
  24. package/releases/0.72.0/core/tree/.claude/agents/solidity-auditor.md +126 -0
  25. package/releases/0.72.0/core/tree/.claude/agents/solidity-dev.md +123 -0
  26. package/releases/0.72.0/core/tree/.claude/agents-overview.md +65 -0
  27. package/releases/0.72.0/core/tree/.claude/frontend.md +10 -0
  28. package/releases/0.72.0/core/tree/.claude/graph.md +79 -0
  29. package/releases/0.72.0/core/tree/.claude/patterns.md +256 -0
  30. package/releases/0.72.0/core/tree/.claude/pills/README.md +150 -0
  31. package/releases/0.72.0/core/tree/.claude/pipeline.md +101 -0
  32. package/releases/0.72.0/core/tree/.claude/retrieval.md +103 -0
  33. package/releases/0.72.0/core/tree/.claude/router.md +221 -0
  34. package/releases/0.72.0/core/tree/.claude/templates/integration.md +48 -0
  35. package/releases/0.72.0/core/tree/CLAUDE.md +167 -0
  36. package/releases/0.72.0/core/tree/scripts/cost-watch.mjs +27 -0
  37. package/releases/0.72.0/core/tree/scripts/edit-guard.mjs +24 -0
  38. package/releases/0.72.0/core/tree/scripts/harness-check.mjs +82 -0
  39. package/releases/0.72.0/core/tree/scripts/loop-gate.mjs +19 -0
  40. package/releases/0.72.0/core/vocabulary.json +15 -0
  41. package/releases/0.72.0/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
  42. package/releases/0.72.0/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
  43. package/releases/0.72.0/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
  44. package/releases/0.72.0/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
  45. package/releases/0.72.0/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
  46. package/releases/0.72.0/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
  47. package/releases/0.72.0/surfaces/blockchain/tree/.claude/graph.md +11 -0
  48. package/releases/0.72.0/surfaces/blockchain/tree/.claude/router.md +6 -0
  49. package/releases/0.72.0/surfaces/blockchain/tree/CLAUDE.md +12 -0
  50. package/releases/0.72.0/surfaces/d1/tree/.claude/agents/dba.md +15 -0
  51. package/releases/0.72.0/surfaces/d1/tree/.claude/agents/devops.md +2 -0
  52. package/releases/0.72.0/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
  53. package/releases/0.72.0/surfaces/d1/tree/.claude/patterns.md +8 -0
  54. package/releases/0.72.0/surfaces/d1/tree/CLAUDE.md +2 -0
  55. package/releases/0.72.0/surfaces/db/tree/.claude/agents/architect.md +5 -0
  56. package/releases/0.72.0/surfaces/db/tree/.claude/agents/dba.md +54 -0
  57. package/releases/0.72.0/surfaces/db/tree/.claude/agents/devops.md +5 -0
  58. package/releases/0.72.0/surfaces/db/tree/.claude/agents/implementer.md +2 -0
  59. package/releases/0.72.0/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
  60. package/releases/0.72.0/surfaces/db/tree/.claude/agents/planner.md +2 -0
  61. package/releases/0.72.0/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
  62. package/releases/0.72.0/surfaces/db/tree/.claude/agents/secops.md +2 -0
  63. package/releases/0.72.0/surfaces/db/tree/.claude/agents-overview.md +5 -0
  64. package/releases/0.72.0/surfaces/db/tree/.claude/graph.md +8 -0
  65. package/releases/0.72.0/surfaces/db/tree/.claude/patterns.md +22 -0
  66. package/releases/0.72.0/surfaces/db/tree/.claude/pipeline.md +13 -0
  67. package/releases/0.72.0/surfaces/db/tree/.claude/retrieval.md +5 -0
  68. package/releases/0.72.0/surfaces/db/tree/.claude/router.md +4 -0
  69. package/releases/0.72.0/surfaces/db/tree/CLAUDE.md +17 -0
  70. package/releases/0.72.0/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
  71. package/releases/0.72.0/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
  72. package/releases/0.72.0/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
  73. package/releases/0.72.0/surfaces/drizzle/tree/.claude/patterns.md +7 -0
  74. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
  75. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
  76. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
  77. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
  78. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
  79. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
  80. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
  81. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
  82. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
  83. package/releases/0.72.0/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
  84. package/releases/0.72.0/surfaces/edge-cf/tree/CLAUDE.md +29 -0
  85. package/releases/0.72.0/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
  86. package/releases/0.72.0/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
  87. package/releases/0.72.0/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
  88. package/releases/0.72.0/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
  89. package/releases/0.72.0/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
  90. package/releases/0.72.0/surfaces/frontend/tree/.claude/patterns.md +8 -0
  91. package/releases/0.72.0/surfaces/frontend/tree/.claude/retrieval.md +2 -0
  92. package/releases/0.72.0/surfaces/frontend/tree/.claude/router.md +14 -0
  93. package/releases/0.72.0/surfaces/frontend/tree/CLAUDE.md +5 -0
  94. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
  95. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
  96. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
  97. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
  98. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
  99. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
  100. package/releases/0.72.0/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
  101. package/releases/0.72.0/surfaces/integrations/tree/.claude/graph.md +10 -0
  102. package/releases/0.72.0/surfaces/integrations/tree/.claude/patterns.md +38 -0
  103. package/releases/0.72.0/surfaces/integrations/tree/.claude/pipeline.md +16 -0
  104. package/releases/0.72.0/surfaces/integrations/tree/.claude/retrieval.md +16 -0
  105. package/releases/0.72.0/surfaces/integrations/tree/.claude/router.md +6 -0
  106. package/releases/0.72.0/surfaces/integrations/tree/CLAUDE.md +17 -0
  107. package/releases/0.72.0/surfaces/money/tree/.claude/agents/architect.md +12 -0
  108. package/releases/0.72.0/surfaces/money/tree/.claude/agents/dba.md +14 -0
  109. package/releases/0.72.0/surfaces/money/tree/.claude/agents/implementer.md +11 -0
  110. package/releases/0.72.0/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
  111. package/releases/0.72.0/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
  112. package/releases/0.72.0/surfaces/money/tree/.claude/agents/secops.md +5 -0
  113. package/releases/0.72.0/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
  114. package/releases/0.72.0/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
  115. package/releases/0.72.0/surfaces/money/tree/.claude/graph.md +2 -0
  116. package/releases/0.72.0/surfaces/money/tree/.claude/patterns.md +49 -0
  117. package/releases/0.72.0/surfaces/money/tree/.claude/pipeline.md +2 -0
  118. package/releases/0.72.0/surfaces/money/tree/.claude/retrieval.md +2 -0
  119. package/releases/0.72.0/surfaces/money/tree/CLAUDE.md +11 -0
  120. package/releases/0.72.0/surfaces/pii/tree/.claude/agents/dba.md +2 -0
  121. package/releases/0.72.0/surfaces/pii/tree/.claude/agents/devops.md +8 -0
  122. package/releases/0.72.0/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
  123. package/releases/0.72.0/surfaces/pii/tree/.claude/agents/secops.md +2 -0
  124. package/releases/0.72.0/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
  125. package/releases/0.72.0/surfaces/pii/tree/CLAUDE.md +5 -0
  126. package/releases/0.72.0/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
  127. package/releases/0.72.0/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
  128. package/releases/0.72.0/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
  129. package/releases/0.72.0/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
  130. package/releases/0.72.0/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
  131. package/releases/0.72.0/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
  132. package/releases/0.72.0/surfaces/prisma/tree/.claude/patterns.md +15 -0
  133. package/releases/0.72.0/surfaces/prisma/tree/CLAUDE.md +5 -0
  134. package/releases/0.73.0/core/GAPS.md +125 -0
  135. package/releases/0.73.0/core/answered.json +104 -0
  136. package/releases/0.73.0/core/defaults/tree/.claude/agents/architect.md +1 -0
  137. package/releases/0.73.0/core/defaults/tree/.claude/agents/dba.md +3 -0
  138. package/releases/0.73.0/core/defaults/tree/.claude/agents/devops.md +1 -0
  139. package/releases/0.73.0/core/defaults/tree/.claude/agents/implementer.md +1 -0
  140. package/releases/0.73.0/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
  141. package/releases/0.73.0/core/defaults/tree/.claude/agents/qa.md +7 -0
  142. package/releases/0.73.0/core/defaults/tree/.claude/agents/reviewer.md +3 -0
  143. package/releases/0.73.0/core/defaults/tree/.claude/agents/secops.md +3 -0
  144. package/releases/0.73.0/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
  145. package/releases/0.73.0/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
  146. package/releases/0.73.0/core/tree/.claude/agents/architect.md +135 -0
  147. package/releases/0.73.0/core/tree/.claude/agents/dba.md +119 -0
  148. package/releases/0.73.0/core/tree/.claude/agents/design-reviewer.md +78 -0
  149. package/releases/0.73.0/core/tree/.claude/agents/devops.md +118 -0
  150. package/releases/0.73.0/core/tree/.claude/agents/implementer.md +184 -0
  151. package/releases/0.73.0/core/tree/.claude/agents/integration-tester.md +170 -0
  152. package/releases/0.73.0/core/tree/.claude/agents/planner.md +132 -0
  153. package/releases/0.73.0/core/tree/.claude/agents/qa.md +150 -0
  154. package/releases/0.73.0/core/tree/.claude/agents/reviewer.md +187 -0
  155. package/releases/0.73.0/core/tree/.claude/agents/secops.md +120 -0
  156. package/releases/0.73.0/core/tree/.claude/agents/solidity-auditor.md +126 -0
  157. package/releases/0.73.0/core/tree/.claude/agents/solidity-dev.md +123 -0
  158. package/releases/0.73.0/core/tree/.claude/agents-overview.md +65 -0
  159. package/releases/0.73.0/core/tree/.claude/frontend.md +10 -0
  160. package/releases/0.73.0/core/tree/.claude/graph.md +79 -0
  161. package/releases/0.73.0/core/tree/.claude/patterns.md +256 -0
  162. package/releases/0.73.0/core/tree/.claude/pills/README.md +150 -0
  163. package/releases/0.73.0/core/tree/.claude/pipeline.md +101 -0
  164. package/releases/0.73.0/core/tree/.claude/retrieval.md +103 -0
  165. package/releases/0.73.0/core/tree/.claude/router.md +221 -0
  166. package/releases/0.73.0/core/tree/.claude/templates/integration.md +48 -0
  167. package/releases/0.73.0/core/tree/CLAUDE.md +167 -0
  168. package/releases/0.73.0/core/tree/scripts/cost-watch.mjs +27 -0
  169. package/releases/0.73.0/core/tree/scripts/edit-guard.mjs +24 -0
  170. package/releases/0.73.0/core/tree/scripts/harness-check.mjs +82 -0
  171. package/releases/0.73.0/core/tree/scripts/loop-gate.mjs +19 -0
  172. package/releases/0.73.0/core/vocabulary.json +15 -0
  173. package/releases/0.73.0/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
  174. package/releases/0.73.0/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
  175. package/releases/0.73.0/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
  176. package/releases/0.73.0/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
  177. package/releases/0.73.0/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
  178. package/releases/0.73.0/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
  179. package/releases/0.73.0/surfaces/blockchain/tree/.claude/graph.md +11 -0
  180. package/releases/0.73.0/surfaces/blockchain/tree/.claude/router.md +6 -0
  181. package/releases/0.73.0/surfaces/blockchain/tree/CLAUDE.md +12 -0
  182. package/releases/0.73.0/surfaces/d1/tree/.claude/agents/dba.md +15 -0
  183. package/releases/0.73.0/surfaces/d1/tree/.claude/agents/devops.md +2 -0
  184. package/releases/0.73.0/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
  185. package/releases/0.73.0/surfaces/d1/tree/.claude/patterns.md +8 -0
  186. package/releases/0.73.0/surfaces/d1/tree/CLAUDE.md +2 -0
  187. package/releases/0.73.0/surfaces/db/tree/.claude/agents/architect.md +5 -0
  188. package/releases/0.73.0/surfaces/db/tree/.claude/agents/dba.md +54 -0
  189. package/releases/0.73.0/surfaces/db/tree/.claude/agents/devops.md +5 -0
  190. package/releases/0.73.0/surfaces/db/tree/.claude/agents/implementer.md +2 -0
  191. package/releases/0.73.0/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
  192. package/releases/0.73.0/surfaces/db/tree/.claude/agents/planner.md +2 -0
  193. package/releases/0.73.0/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
  194. package/releases/0.73.0/surfaces/db/tree/.claude/agents/secops.md +2 -0
  195. package/releases/0.73.0/surfaces/db/tree/.claude/agents-overview.md +5 -0
  196. package/releases/0.73.0/surfaces/db/tree/.claude/graph.md +8 -0
  197. package/releases/0.73.0/surfaces/db/tree/.claude/patterns.md +22 -0
  198. package/releases/0.73.0/surfaces/db/tree/.claude/pipeline.md +13 -0
  199. package/releases/0.73.0/surfaces/db/tree/.claude/retrieval.md +5 -0
  200. package/releases/0.73.0/surfaces/db/tree/.claude/router.md +4 -0
  201. package/releases/0.73.0/surfaces/db/tree/CLAUDE.md +17 -0
  202. package/releases/0.73.0/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
  203. package/releases/0.73.0/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
  204. package/releases/0.73.0/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
  205. package/releases/0.73.0/surfaces/drizzle/tree/.claude/patterns.md +7 -0
  206. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
  207. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
  208. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
  209. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
  210. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
  211. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
  212. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
  213. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
  214. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
  215. package/releases/0.73.0/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
  216. package/releases/0.73.0/surfaces/edge-cf/tree/CLAUDE.md +29 -0
  217. package/releases/0.73.0/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
  218. package/releases/0.73.0/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
  219. package/releases/0.73.0/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
  220. package/releases/0.73.0/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
  221. package/releases/0.73.0/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
  222. package/releases/0.73.0/surfaces/frontend/tree/.claude/patterns.md +8 -0
  223. package/releases/0.73.0/surfaces/frontend/tree/.claude/retrieval.md +2 -0
  224. package/releases/0.73.0/surfaces/frontend/tree/.claude/router.md +14 -0
  225. package/releases/0.73.0/surfaces/frontend/tree/CLAUDE.md +5 -0
  226. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
  227. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
  228. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
  229. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
  230. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
  231. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
  232. package/releases/0.73.0/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
  233. package/releases/0.73.0/surfaces/integrations/tree/.claude/graph.md +10 -0
  234. package/releases/0.73.0/surfaces/integrations/tree/.claude/patterns.md +38 -0
  235. package/releases/0.73.0/surfaces/integrations/tree/.claude/pipeline.md +16 -0
  236. package/releases/0.73.0/surfaces/integrations/tree/.claude/retrieval.md +16 -0
  237. package/releases/0.73.0/surfaces/integrations/tree/.claude/router.md +6 -0
  238. package/releases/0.73.0/surfaces/integrations/tree/CLAUDE.md +17 -0
  239. package/releases/0.73.0/surfaces/money/tree/.claude/agents/architect.md +12 -0
  240. package/releases/0.73.0/surfaces/money/tree/.claude/agents/dba.md +14 -0
  241. package/releases/0.73.0/surfaces/money/tree/.claude/agents/implementer.md +11 -0
  242. package/releases/0.73.0/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
  243. package/releases/0.73.0/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
  244. package/releases/0.73.0/surfaces/money/tree/.claude/agents/secops.md +5 -0
  245. package/releases/0.73.0/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
  246. package/releases/0.73.0/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
  247. package/releases/0.73.0/surfaces/money/tree/.claude/graph.md +2 -0
  248. package/releases/0.73.0/surfaces/money/tree/.claude/patterns.md +49 -0
  249. package/releases/0.73.0/surfaces/money/tree/.claude/pipeline.md +2 -0
  250. package/releases/0.73.0/surfaces/money/tree/.claude/retrieval.md +2 -0
  251. package/releases/0.73.0/surfaces/money/tree/CLAUDE.md +11 -0
  252. package/releases/0.73.0/surfaces/pii/tree/.claude/agents/dba.md +2 -0
  253. package/releases/0.73.0/surfaces/pii/tree/.claude/agents/devops.md +8 -0
  254. package/releases/0.73.0/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
  255. package/releases/0.73.0/surfaces/pii/tree/.claude/agents/secops.md +2 -0
  256. package/releases/0.73.0/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
  257. package/releases/0.73.0/surfaces/pii/tree/CLAUDE.md +5 -0
  258. package/releases/0.73.0/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
  259. package/releases/0.73.0/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
  260. package/releases/0.73.0/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
  261. package/releases/0.73.0/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
  262. package/releases/0.73.0/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
  263. package/releases/0.73.0/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
  264. package/releases/0.73.0/surfaces/prisma/tree/.claude/patterns.md +15 -0
  265. package/releases/0.73.0/surfaces/prisma/tree/CLAUDE.md +5 -0
  266. package/src/commands/learn.mjs +5 -3
  267. package/src/commands/sizes.mjs +8 -4
  268. package/src/cost.mjs +3 -3
  269. package/src/dashboard.mjs +2 -1
  270. package/src/office.html +52 -9
  271. package/src/office.mjs +155 -18
  272. package/src/transcripts.mjs +13 -1
package/src/office.html CHANGED
@@ -31,8 +31,15 @@
31
31
  #tasks .who { margin-top: 3px; color: #c9cde0; font-size: 12px; overflow-wrap: anywhere; }
32
32
  #tasks .now { margin-top: 2px; color: #ffd34d; font-size: 12px; }
33
33
  #tasks .now.quiet { color: #8a8fa8; }
34
+ #tasks ul.agents { list-style: none; margin: 8px 0 0; padding: 0; }
35
+ #tasks ul.agents li { margin: 0 0 7px; padding: 0 0 0 14px; }
36
+ #tasks ul.agents li::before { left: 1px; top: 4px; width: 7px; height: 7px; border: 0; background: #ffd34d; animation: beat 1.2s ease-in-out infinite; }
37
+ #tasks .agent { overflow-wrap: anywhere; font-size: 12px; color: #c9cde0; }
38
+ #tasks .role { font: 600 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #fff8e8; margin-right: 6px; }
39
+ #tasks .desc { margin-top: 1px; color: #8a8fa8; font-size: 11px; overflow-wrap: anywhere; }
40
+ #tasks .took { margin-top: 1px; color: #a9adbf; font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
34
41
  @keyframes beat { 50% { opacity: 0.35; } }
35
- @media (prefers-reduced-motion: reduce) { #tasks li.running::before { animation: none; } }
42
+ @media (prefers-reduced-motion: reduce) { #tasks li.running::before, #tasks ul.agents li::before { animation: none; } }
36
43
  </style>
37
44
  </head>
38
45
  <body>
@@ -805,6 +812,14 @@ function onBeat(b) {
805
812
  }
806
813
  return;
807
814
  }
815
+ if (b.type === 'home') {
816
+ // Reported, and nobody came for the work in time: it goes home, unless it was sent back to work meanwhile.
817
+ const p = b.agent ? people.get(b.agent) : null;
818
+ if (!p || !(p.reported || p.reporting) || p.leaving) return;
819
+ if (b.instant) leave(p, true);
820
+ else act(p, () => p.reported && !p.typing && !p.leaving && leave(p));
821
+ return;
822
+ }
808
823
  if (b.type === 'refused' || b.type === 'stale') {
809
824
  // A dispatch the owner refused never ran; a run that never reported has stopped. Either way, whoever sat down
810
825
  // for it gets up — and a refusal answers the gate's call.
@@ -975,14 +990,16 @@ function syncButtons() {
975
990
  * The session's work, task by task, as the server cuts it — the way `nina runs` does: each named by the words the
976
991
  * orchestrator gave its first dispatch, with the stages that worked on it, from when that went out to the verdict
977
992
  * that closed it. The server sends the whole list whenever it changes, and it replaces what is here. A task still
978
- * open counts up while anyone is at work on it, and stops at the last thing that happened while nobody is.
993
+ * open counts up while anyone is at work on it, and stops at the last of its runs to start or end while nobody is;
994
+ * under it, each of its agents at work, as Claude Code lists its own: the stage, what it is doing now, the words of
995
+ * its dispatch, how long it has been at work and the context it holds.
979
996
  */
980
997
  const SIDE = 300;
981
998
  /** Narrower than this, the timeline is drawn over the room, and starts hidden. */
982
999
  const NARROW = 760;
983
1000
  const TASKS_KEY = 'nina-office-tasks';
984
1001
  let tasks = [];
985
- /** The newest dispatch or verdict: a replay's clock, and where an idle task's count stops. */
1002
+ /** The newest dispatch or verdict: a replay's clock. */
986
1003
  let lastActivity = 0;
987
1004
  let tasksOpen = (() => {
988
1005
  try {
@@ -998,6 +1015,15 @@ let tasksOpen = (() => {
998
1015
  const atWork = () => [...new Set([...people.values()].filter((p) => p.work && !p.reported && !p.leaving).map((p) => p.role))];
999
1016
 
1000
1017
  const two = (n) => String(n).padStart(2, '0');
1018
+ /** How long an agent has been at work, as Claude Code says it: 28s, 7m 19s, 1h 4m. */
1019
+ function took(ms) {
1020
+ const s = Math.max(0, Math.floor(ms / 1000));
1021
+ if (s < 60) return `${s}s`;
1022
+ if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`;
1023
+ return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`;
1024
+ }
1025
+ /** A count of tokens: 850, 49.8k, 1.2M — a count that rounds to a thousand thousands is a million. */
1026
+ const tokens = (n) => (n >= 999_950 ? `${(n / 1e6).toFixed(1)}M` : n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n));
1001
1027
  /** A moment as the hour, with the day when it is not the day of `beside` — now, or the moment it follows. */
1002
1028
  function stamp(at, beside) {
1003
1029
  const t = new Date(at);
@@ -1021,26 +1047,43 @@ function counter(ms) {
1021
1047
  function drawTasks() {
1022
1048
  if (!tasksOpen) return;
1023
1049
  const clock = status.startsWith('replay') ? lastActivity : Date.now();
1024
- const working = atWork();
1025
- const line = (cls, text) => {
1026
- const el = document.createElement('div');
1050
+ const line = (cls, text, tag = 'div') => {
1051
+ const el = document.createElement(tag);
1027
1052
  el.className = cls;
1028
1053
  el.textContent = text;
1029
1054
  return el;
1030
1055
  };
1056
+ // What it is doing now, as Claude Code's list leads with, and under it the words its dispatch was given.
1057
+ const agentRow = (a) => {
1058
+ const li = document.createElement('li');
1059
+ const what = line('agent', '');
1060
+ what.append(line('role', a.role, 'span'), a.doing ?? a.desc ?? '');
1061
+ li.append(what);
1062
+ if (a.doing && a.desc) li.append(line('desc', a.desc));
1063
+ li.append(line('took', a.tokens === null ? took(clock - a.start) : `${took(clock - a.start)} · ${tokens(a.tokens)} tokens`));
1064
+ return li;
1065
+ };
1031
1066
  const shown = [...tasks].sort((a, b) => b.start - a.start);
1032
1067
  document.getElementById('task-list').replaceChildren(
1033
1068
  ...shown.map((t) => {
1034
1069
  const li = document.createElement('li');
1035
1070
  const running = t.end === null;
1036
- const idle = running && working.length === 0;
1071
+ const agents = t.agents ?? [];
1072
+ const idle = running && agents.length === 0;
1037
1073
  li.className = running ? (idle ? 'idle' : 'running') : t.how === 'closed' ? 'done' : 'ended';
1038
1074
  li.append(line('name', t.name || '(no description)'));
1039
1075
  if (t.who?.length > 0) li.append(line('who', t.who.map(([role, n]) => (n > 1 ? `${role} ×${n}` : role)).join(' · ')));
1040
1076
  if (running) {
1041
- const upTo = idle ? Math.max(t.start, lastActivity) : Math.max(t.start, clock);
1077
+ // Idle, it stops at the last of its own runs to start or end, whatever another task is doing.
1078
+ const upTo = idle ? Math.max(t.start, t.last ?? t.start) : Math.max(t.start, clock);
1042
1079
  li.append(line('when', `${stamp(t.start, clock)} → now · ${counter(upTo - t.start)}`));
1043
- li.append(line('now', idle ? `idle since ${stamp(lastActivity, clock)}` : `at work: ${working.join(', ')}`));
1080
+ if (idle) li.append(line('now', `idle since ${stamp(t.last ?? t.start, clock)}`));
1081
+ else {
1082
+ const list = document.createElement('ul');
1083
+ list.className = 'agents';
1084
+ list.append(...agents.map(agentRow));
1085
+ li.append(list);
1086
+ }
1044
1087
  } else {
1045
1088
  li.append(line('when', `${stamp(t.start, clock)} → ${stamp(t.end, t.start)} · ${span(t.end - t.start)}`));
1046
1089
  // A task that waited — overnight, on the owner — says how much of it anyone was at work.
package/src/office.mjs CHANGED
@@ -4,11 +4,14 @@
4
4
  * Each stage of the project's composed graph has a desk, and each agent the loop gate saw launched is someone
5
5
  * sitting at one. The gate's ledger is what is read, and it holds metadata only, so the office shows who worked,
6
6
  * what they answered, the ids of the issues they named and the few words the orchestrator gave each dispatch —
7
- * never what an agent wrote or reported. Beside the room, a timeline of the session's tasks (`officeTimeline`), cut
8
- * and named as `nina runs` cuts and names them:
7
+ * never what an agent reported. Of a run's own transcript it reads when it was last written, how much context it
8
+ * holds and what it is doing — the description it gave its shell command, or a tool and a file's name (`actionOf`).
9
+ * Beside the room, a timeline of the session's tasks (`officeTimeline`), cut and named as `nina runs` cuts and names
10
+ * them, each open one with its agents at work:
9
11
  *
10
12
  * a dispatch someone sits down to work, the folder carried over by whoever handed it on
11
13
  * a verdict a check over their head, or a cross when it sends work back
14
+ * a report nothing follows after `HANDOFF_MS`, its agent goes home
12
15
  * a verdict the graph sends to the a question mark over the one who asked, until the owner speaks
13
16
  * owner, or the orchestrator asking
14
17
  * the gate asking at a cap the phone on the reception's counter rings, the owner's line
@@ -31,7 +34,8 @@ import { readLedger, sessionLedgers } from './gate.mjs';
31
34
  import { readProfile, slugFor } from './paths.mjs';
32
35
  import { projectStoreFile, readStoreFile } from './store.mjs';
33
36
  import { CYCLE_ENDS, IN_FLIGHT, cyclesOf } from './commands/stats.mjs';
34
- import { isLoopBack, transcriptsOf } from './transcripts.mjs';
37
+ import { contextSize, isLoopBack, transcriptsOf } from './transcripts.mjs';
38
+ import { gained } from './cost.mjs';
35
39
  import { shapeOf } from './commands/pipeline.mjs';
36
40
  import { listenHere, openInBrowser, refuseElsewhere, untilStopped } from './serve.mjs';
37
41
 
@@ -48,6 +52,14 @@ export const OFFICE_PORT = 6462;
48
52
  */
49
53
  export const PARTY_QUIET_MS = 20_000;
50
54
 
55
+ /**
56
+ * How long one whose report is in waits at its desk to hand its work on before it goes home. Any dispatch moves the
57
+ * reported on, but with tasks side by side the next could be a long while coming: of two projects' 1,266 reports, 346
58
+ * sat on past two minutes and 149 past ten, done and with nothing in hand, while Claude Code had already let them go.
59
+ * Of 544 hand-offs, 92.8% went out within two minutes, and 93.9% within three.
60
+ */
61
+ export const HANDOFF_MS = 2 * 60 * 1000;
62
+
51
63
  /** How far back, when a live client moves to a session already running, beats still play rather than set the room. */
52
64
  const SWITCH_GRACE_MS = 10_000;
53
65
 
@@ -77,14 +89,13 @@ export const SILENT_MS = 45 * 60 * 1000;
77
89
  const staleAt = (start, heard) => (heard === null ? start.at + STALE_MS : Math.max(start.at, heard) + SILENT_MS);
78
90
 
79
91
  /**
80
- * When each run of a session last wrote its own transcript, so that a run still writing is at work however long it
81
- * takes. A run is found by its agent's id once the gate knows it, and before that — a foreground run still going — by
82
- * the tool_use id that launched it, which its transcript's `.meta.json` keeps.
92
+ * Each run's own transcript in a session. A run is found by its agent's id once the gate knows it, and before that — a
93
+ * foreground run still going — by the tool_use id that launched it, which its transcript's `.meta.json` keeps.
83
94
  *
84
95
  * @param {string} target - The project directory.
85
- * @returns {(session: string|null) => (start: {agent: string|null, id: string|null}) => number|null}
96
+ * @returns {(session: string|null) => (start: {agent: string|null, id: string|null}) => string|null}
86
97
  */
87
- export function runClock(target) {
98
+ export function runFiles(target) {
88
99
  // Named as the gate names the project's ledgers, by where it really is: reached through a link, it is the same one.
89
100
  let real = target;
90
101
  try {
@@ -121,9 +132,23 @@ export function runClock(target) {
121
132
  }
122
133
  if (launchedBy.has(meta)) byLaunch.set(launchedBy.get(meta), file);
123
134
  }
135
+ return (start) => (start.agent && byAgent.get(start.agent)) || (start.id && byLaunch.get(start.id)) || null;
136
+ };
137
+ }
138
+
139
+ /**
140
+ * When each run of a session last wrote its own transcript, so that a run still writing is at work however long it
141
+ * takes.
142
+ *
143
+ * @param {(session: string|null) => (start: object) => string|null} files - Each run's transcript (`runFiles`).
144
+ * @returns {(session: string|null) => (start: {agent: string|null, id: string|null}) => number|null}
145
+ */
146
+ export function runClock(files) {
147
+ return (session) => {
148
+ const fileOf = files(session);
124
149
  const written = new Map();
125
150
  return (start) => {
126
- const file = (start.agent && byAgent.get(start.agent)) || (start.id && byLaunch.get(start.id)) || null;
151
+ const file = fileOf(start);
127
152
  if (!file) return null;
128
153
  if (!written.has(file)) {
129
154
  try {
@@ -137,6 +162,89 @@ export function runClock(target) {
137
162
  };
138
163
  }
139
164
 
165
+ /** The most of a run's own words the timeline shows for what it is doing. */
166
+ const ACTION_MAX = 120;
167
+
168
+ /**
169
+ * What a tool call is doing, in the few words a list beside the room has: the description the run gave a shell
170
+ * command, which the run writes for a person to read, or the tool and the name of the file it works on. Never the
171
+ * command, a path, a pattern, another tool's input or what came back.
172
+ *
173
+ * @param {object} block - A `tool_use` block of an assistant message.
174
+ * @returns {string|null}
175
+ */
176
+ export function actionOf(block) {
177
+ if (block?.type !== 'tool_use' || typeof block.name !== 'string') return null;
178
+ const input = block.input && typeof block.input === 'object' ? block.input : {};
179
+ // An MCP tool is named by its server too: the tool's own name says what it does.
180
+ const name = block.name.startsWith('mcp__') ? (block.name.split('__').filter(Boolean).at(-1) ?? block.name) : block.name;
181
+ const said = block.name === 'Bash' && typeof input.description === 'string' ? input.description.replace(/\s+/g, ' ').trim() : '';
182
+ if (said) return said.length > ACTION_MAX ? `${said.slice(0, ACTION_MAX - 1)}…` : said;
183
+ const path = [input.file_path, input.notebook_path].find((x) => typeof x === 'string' && x.trim());
184
+ // A transcript written on Windows names its files with backslashes, which a path read here does not split on.
185
+ return path ? `${name} ${basename(path.trim().replace(/\\/g, '/'))}` : name;
186
+ }
187
+
188
+ /**
189
+ * Each run of a session as its own transcript tells it now: how much context it holds (`contextSize` of its newest
190
+ * message) and what it is doing (`actionOf` its newest tool call) — what Claude Code shows beside each of its running
191
+ * agents, but for a line it writes as it watches, which it keeps nowhere. Read once a look and only what the
192
+ * transcript gained since the last, keeping those and nothing else the run wrote; each with when its message was
193
+ * written, so a replay is told the run as it stood at a beat.
194
+ *
195
+ * @param {(session: string|null) => (start: object) => string|null} files - Each run's transcript (`runFiles`).
196
+ * @returns {(session: string|null) => (start: {agent: string|null, id: string|null}, moment?: number) => {tokens: number|null, doing: string|null}|null}
197
+ */
198
+ export function runState(files) {
199
+ /** By transcript, in the session last looked at: how far it was read, its last message, the counts and actions by when. */
200
+ let read = new Map();
201
+ let looking = null;
202
+ return (session) => {
203
+ // The office follows one session at a time: one it moved away from is read again if it comes back.
204
+ if (session !== looking) read = new Map();
205
+ looking = session;
206
+ const fileOf = files(session);
207
+ const looked = new Set();
208
+ return (start, moment = Number.POSITIVE_INFINITY) => {
209
+ const file = fileOf(start);
210
+ if (!file) return null;
211
+ if (!read.has(file)) read.set(file, { offset: 0, last: null, counts: [], actions: [] });
212
+ const kept = read.get(file);
213
+ if (!looked.has(file)) {
214
+ looked.add(file);
215
+ try {
216
+ const { text, to } = gained(file, kept.offset);
217
+ // A transcript shorter than what was read of it is another one: read again from its start.
218
+ if (to < kept.offset) Object.assign(kept, { last: null, counts: [], actions: [] });
219
+ kept.offset = to;
220
+ for (const line of text.split('\n')) {
221
+ if (!line.includes('"cache_read_input_tokens"')) continue;
222
+ try {
223
+ const row = JSON.parse(line);
224
+ const at = Date.parse(row?.timestamp);
225
+ if (!row?.message?.usage || !row.message.id || !Number.isFinite(at)) continue;
226
+ // A message is written once for each of its blocks, with the same usage: its first is counted, and
227
+ // each of its tool calls is a step.
228
+ if (row.message.id !== kept.last) kept.counts.push([at, contextSize(row.message.usage)]);
229
+ kept.last = row.message.id;
230
+ for (const block of Array.isArray(row.message.content) ? row.message.content : []) {
231
+ const action = actionOf(block);
232
+ if (action) kept.actions.push([at, action]);
233
+ }
234
+ } catch {
235
+ // A torn line loses one message's count; the next one has its own.
236
+ }
237
+ }
238
+ } catch {
239
+ // A transcript gone between the listing and the read tells what it had.
240
+ }
241
+ }
242
+ const by = (list) => list.findLast(([at]) => at <= moment)?.[1] ?? null;
243
+ return { tokens: by(kept.counts), doing: by(kept.actions) };
244
+ };
245
+ };
246
+ }
247
+
140
248
  /** A wait between two of the office's looks this much longer than it asks for is the machine having slept. */
141
249
  const SLEPT_MS = 60_000;
142
250
 
@@ -256,11 +364,12 @@ function readStarts(ledger) {
256
364
  * verdict that ends a cycle of the timeline, qa's `PASS` — is a party at once, whoever else is at work. Any other pass
257
365
  * ends the work — a party — when nothing since the last dispatch was sent back, something since then could route to
258
366
  * `done`, nobody is still at work, and no dispatch follows within `PARTY_QUIET_MS`; at once when the pass routes only
259
- * to a terminal. A party that waits on the quiet is only beaten once `now` has passed it.
367
+ * to a terminal. A party that waits on the quiet is only beaten once `now` has passed it. So is the beat that sends one
368
+ * whose report is in home (`home`): `HANDOFF_MS` after its verdict, when no dispatch and no party came between.
260
369
  *
261
370
  * @param {object[]} entries - The ledger, oldest first.
262
371
  * @param {{edges: {from: string, to: string, token: string}[]}} graph - The project's parsed graph.
263
- * @param {number} [now] - The time a waiting party is judged against; `Infinity` for a session that has ended.
372
+ * @param {number} [now] - The time a waiting party or a going home is judged against; `Infinity` for a session that has ended.
264
373
  * @param {(start: object) => number|null} [heard] - When a run last wrote its transcript (`runClock`), or null.
265
374
  * @returns {object[]} Beats, each `{id, at, type, ...}`; the id is stable as the ledger grows.
266
375
  */
@@ -345,6 +454,19 @@ export function officeBeats(ledger, graph, now = Date.now(), heard = () => null)
345
454
  // A reset written for the model's own question, by ledgers older than the `question` entry, is not the owner.
346
455
  else if (e.k === 'reset' && e.why !== 'ask') beats.push({ id, at, type: 'owner' });
347
456
  });
457
+ // One whose report is in goes home once `HANDOFF_MS` passes with no dispatch and no party, either of which sends the
458
+ // reported on anyway. Its work, handed on later, the orchestrator carries. One that asked the owner stays with its
459
+ // question until the work moves on. "After" is the ledger's order, which the beats keep until they are sorted: a
460
+ // qa's party falls at its verdict's own moment.
461
+ const moves = beats.flatMap((b, i) => ((b.type === 'work' && !b.message) || b.type === 'party' ? [{ i, at: b.at }] : []));
462
+ const home = [];
463
+ beats.forEach((v, i) => {
464
+ if (v.type !== 'verdict' || v.asks) return;
465
+ const moment = v.at + HANDOFF_MS;
466
+ if (now < moment || moves.some((m) => m.i > i && m.at <= moment)) return;
467
+ home.push({ id: `home:${v.id}`, at: moment, type: 'home', role: v.role, agent: v.agent });
468
+ });
469
+ beats.push(...home);
348
470
  // Stable: beats of one moment keep the ledger's order. A beat that waited — a party, a refusal — sorts where it fell.
349
471
  return beats.sort((a, b) => a.at - b.at);
350
472
  }
@@ -359,13 +481,18 @@ export function officeBeats(ledger, graph, now = Date.now(), heard = () => null)
359
481
  * grows — a run still at work lets nothing through until its verdict, a dispatch is known refused only seconds later
360
482
  * — and sent piece by piece, a task that a later fact merged away stayed on the page for good.
361
483
  *
484
+ * A task still open lists its agents at work, oldest first, each with its stage, the words its own dispatch was given,
485
+ * when it started, how much context it holds and what it is doing (`runState`) — the detail Claude Code shows of its
486
+ * own running agents. Every task says when the last of its runs started or ended, which an idle one counts up to.
487
+ *
362
488
  * @param {object[]} ledger - The ledger, oldest first.
363
489
  * @param {number} [now] - The moment it is read at: a run with no verdict that has not gone quiet is still at work.
364
490
  * @param {Map<string, string>} [names] - Descriptions by dispatch id, for entries that carry none.
365
491
  * @param {(start: object) => number|null} [heard] - When a run last wrote its transcript (`runClock`), or null.
366
- * @returns {{key: string, name: string|null, start: number, end: number|null, how: string|null, busy: number|null, who: [string, number][]}[]}
492
+ * @param {(start: object) => {tokens: number|null, doing: string|null}|null} [state] - A run as its transcript tells it (`runState`).
493
+ * @returns {{key: string, name: string|null, start: number, end: number|null, last: number, how: string|null, busy: number|null, who: [string, number][], agents: {role: string, desc: string|null, start: number, tokens: number|null, doing: string|null}[]}[]}
367
494
  */
368
- export function officeTimeline(ledger, now = Date.now(), names = new Map(), heard = () => null) {
495
+ export function officeTimeline(ledger, now = Date.now(), names = new Map(), heard = () => null, state = () => null) {
369
496
  const { entries, starts, verdictOf } = readStarts(ledger);
370
497
  // A run a message started — an agent resumed after it had reported — is named by the message's summary, or, in a
371
498
  // ledger from before the gate kept one, by the words the agent was launched with: it goes on with that work.
@@ -385,15 +512,22 @@ export function officeTimeline(ledger, now = Date.now(), names = new Map(), hear
385
512
  // A task its closing verdict ended while one of its runs is still at work stays open until that run reports: work
386
513
  // planned side by side — three architects sent together, one of whose specs went on to qa — fell inside the task
387
514
  // the first one's qa closed, and the room showed two architects at work beside a list with no task open.
388
- const open = cycle.end === 'open' || cycle.runs.some((r) => r.verdict === IN_FLIGHT && r.start.end == null);
515
+ const atWork = cycle.runs.filter((r) => r.verdict === IN_FLIGHT && r.start.end == null);
516
+ const open = cycle.end === 'open' || atWork.length > 0;
517
+ const last = Math.max(...cycle.runs.map((r) => r.start.end ?? r.start.at));
389
518
  return {
390
519
  key: first.key,
391
520
  name: first.desc ? String(first.desc) : null,
392
521
  start: first.start.at,
393
- end: open ? null : Math.max(...cycle.runs.map((r) => r.start.end ?? r.start.at)),
522
+ end: open ? null : last,
523
+ last,
394
524
  how: open ? null : cycle.end,
395
525
  busy: open ? null : busyFor(cycle.runs.map((r) => r.start)),
396
526
  who: [...who],
527
+ agents: atWork.map((r) => {
528
+ const told = state(r.start);
529
+ return { role: r.role, desc: r.desc ? String(r.desc) : null, start: r.start.at, tokens: told?.tokens ?? null, doing: told?.doing ?? null };
530
+ }),
397
531
  };
398
532
  });
399
533
  }
@@ -505,7 +639,9 @@ export function officeRoutes({ target, wanted, replay = false }) {
505
639
  const timers = new Set();
506
640
 
507
641
  const names = storeNames(target);
508
- const clock = runClock(target);
642
+ const files = runFiles(target);
643
+ const clock = runClock(files);
644
+ const looks = runState(files);
509
645
  const wake = wakeClock();
510
646
 
511
647
  /** The session to show, and its entries; read again only when its ledger changed. */
@@ -559,7 +695,7 @@ export function officeRoutes({ target, wanted, replay = false }) {
559
695
  return at === null ? null : Math.max(at, woke);
560
696
  };
561
697
  const beats = officeBeats(state.entries, graph, now, heard);
562
- const tasks = officeTimeline(state.entries, now, names(state.entries), heard);
698
+ const tasks = officeTimeline(state.entries, now, names(state.entries), heard, looks(state.session));
563
699
  for (const client of clients) {
564
700
  if (client.replay) continue;
565
701
  if (client.session !== state.session) greet(client, state);
@@ -580,7 +716,8 @@ export function officeRoutes({ target, wanted, replay = false }) {
580
716
  const beats = officeBeats(state.entries, graph, Number.POSITIVE_INFINITY, heard);
581
717
  // The timeline as it stood at each beat: cut from the ledger up to that moment, so a replay tells nothing early.
582
718
  const known = names(state.entries);
583
- const tasksAt = (moment) => officeTimeline(state.entries.filter((e) => Date.parse(e?.at) <= moment), moment, known, heard);
719
+ const look = looks(state.session);
720
+ const tasksAt = (moment) => officeTimeline(state.entries.filter((e) => Date.parse(e?.at) <= moment), moment, known, heard, (start) => look(start, moment));
584
721
  // What came before the first dispatch sets the room, at once: a session often opens on many of the owner's
585
722
  // messages, and played out they kept the office empty for a minute.
586
723
  let i = Math.max(0, beats.findIndex((b) => b.type === 'work'));
@@ -1114,7 +1114,7 @@ const REWRITE_FLOOR = 30_000;
1114
1114
  */
1115
1115
  export function contextOf(usage) {
1116
1116
  const n = (v) => (typeof v === 'number' ? v : 0);
1117
- const turns = [...usage.values()].map(({ usage: u }) => ({ size: n(u.input_tokens) + n(u.cache_read_input_tokens) + n(u.cache_creation_input_tokens), written: n(u.cache_creation_input_tokens) }));
1117
+ const turns = [...usage.values()].map(({ usage: u }) => ({ size: contextSize(u), written: n(u.cache_creation_input_tokens) }));
1118
1118
  const sizes = turns.map((t) => t.size);
1119
1119
  let rewrites = 0;
1120
1120
  let rewritten = 0;
@@ -1127,6 +1127,18 @@ export function contextOf(usage) {
1127
1127
  return { turns: sizes.length, start: sizes[0] ?? null, peak: sizes.length > 0 ? Math.max(...sizes) : null, rewrites, rewritten };
1128
1128
  }
1129
1129
 
1130
+ /**
1131
+ * The context a turn held: everything it read, from the cache or not. What `stats` measures a round's context by, the
1132
+ * cost watch a run's, and the office an agent at work.
1133
+ *
1134
+ * @param {object} usage - A message's usage.
1135
+ * @returns {number} Tokens.
1136
+ */
1137
+ export function contextSize(usage) {
1138
+ const n = (v) => (typeof v === 'number' ? v : 0);
1139
+ return n(usage?.input_tokens) + n(usage?.cache_read_input_tokens) + n(usage?.cache_creation_input_tokens);
1140
+ }
1141
+
1130
1142
  /** How the cost watch opens an output it clipped (`src/cost.mjs`), which is how a snapshot counts them. */
1131
1143
  export const CLIP_MARK = '[NINA clipped this output';
1132
1144