@xhulz/nina 0.67.0 → 0.68.1

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 (271) hide show
  1. package/package.json +1 -1
  2. package/releases/0.68.0/core/GAPS.md +125 -0
  3. package/releases/0.68.0/core/answered.json +80 -0
  4. package/releases/0.68.0/core/defaults/tree/.claude/agents/architect.md +1 -0
  5. package/releases/0.68.0/core/defaults/tree/.claude/agents/dba.md +3 -0
  6. package/releases/0.68.0/core/defaults/tree/.claude/agents/devops.md +1 -0
  7. package/releases/0.68.0/core/defaults/tree/.claude/agents/implementer.md +1 -0
  8. package/releases/0.68.0/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
  9. package/releases/0.68.0/core/defaults/tree/.claude/agents/qa.md +7 -0
  10. package/releases/0.68.0/core/defaults/tree/.claude/agents/reviewer.md +3 -0
  11. package/releases/0.68.0/core/defaults/tree/.claude/agents/secops.md +3 -0
  12. package/releases/0.68.0/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
  13. package/releases/0.68.0/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
  14. package/releases/0.68.0/core/tree/.claude/agents/architect.md +134 -0
  15. package/releases/0.68.0/core/tree/.claude/agents/dba.md +119 -0
  16. package/releases/0.68.0/core/tree/.claude/agents/design-reviewer.md +76 -0
  17. package/releases/0.68.0/core/tree/.claude/agents/devops.md +118 -0
  18. package/releases/0.68.0/core/tree/.claude/agents/implementer.md +178 -0
  19. package/releases/0.68.0/core/tree/.claude/agents/integration-tester.md +170 -0
  20. package/releases/0.68.0/core/tree/.claude/agents/planner.md +132 -0
  21. package/releases/0.68.0/core/tree/.claude/agents/qa.md +150 -0
  22. package/releases/0.68.0/core/tree/.claude/agents/reviewer.md +187 -0
  23. package/releases/0.68.0/core/tree/.claude/agents/secops.md +120 -0
  24. package/releases/0.68.0/core/tree/.claude/agents/solidity-auditor.md +126 -0
  25. package/releases/0.68.0/core/tree/.claude/agents/solidity-dev.md +123 -0
  26. package/releases/0.68.0/core/tree/.claude/agents-overview.md +65 -0
  27. package/releases/0.68.0/core/tree/.claude/frontend.md +10 -0
  28. package/releases/0.68.0/core/tree/.claude/graph.md +79 -0
  29. package/releases/0.68.0/core/tree/.claude/patterns.md +252 -0
  30. package/releases/0.68.0/core/tree/.claude/pills/README.md +150 -0
  31. package/releases/0.68.0/core/tree/.claude/pipeline.md +101 -0
  32. package/releases/0.68.0/core/tree/.claude/retrieval.md +103 -0
  33. package/releases/0.68.0/core/tree/.claude/router.md +218 -0
  34. package/releases/0.68.0/core/tree/.claude/templates/integration.md +48 -0
  35. package/releases/0.68.0/core/tree/CLAUDE.md +166 -0
  36. package/releases/0.68.0/core/tree/scripts/cost-watch.mjs +25 -0
  37. package/releases/0.68.0/core/tree/scripts/edit-guard.mjs +24 -0
  38. package/releases/0.68.0/core/tree/scripts/harness-check.mjs +81 -0
  39. package/releases/0.68.0/core/tree/scripts/loop-gate.mjs +19 -0
  40. package/releases/0.68.0/core/vocabulary.json +14 -0
  41. package/releases/0.68.0/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
  42. package/releases/0.68.0/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
  43. package/releases/0.68.0/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
  44. package/releases/0.68.0/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
  45. package/releases/0.68.0/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
  46. package/releases/0.68.0/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
  47. package/releases/0.68.0/surfaces/blockchain/tree/.claude/graph.md +11 -0
  48. package/releases/0.68.0/surfaces/blockchain/tree/.claude/router.md +6 -0
  49. package/releases/0.68.0/surfaces/blockchain/tree/CLAUDE.md +12 -0
  50. package/releases/0.68.0/surfaces/d1/tree/.claude/agents/dba.md +15 -0
  51. package/releases/0.68.0/surfaces/d1/tree/.claude/agents/devops.md +2 -0
  52. package/releases/0.68.0/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
  53. package/releases/0.68.0/surfaces/d1/tree/.claude/patterns.md +8 -0
  54. package/releases/0.68.0/surfaces/d1/tree/CLAUDE.md +2 -0
  55. package/releases/0.68.0/surfaces/db/tree/.claude/agents/architect.md +5 -0
  56. package/releases/0.68.0/surfaces/db/tree/.claude/agents/dba.md +54 -0
  57. package/releases/0.68.0/surfaces/db/tree/.claude/agents/devops.md +5 -0
  58. package/releases/0.68.0/surfaces/db/tree/.claude/agents/implementer.md +2 -0
  59. package/releases/0.68.0/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
  60. package/releases/0.68.0/surfaces/db/tree/.claude/agents/planner.md +2 -0
  61. package/releases/0.68.0/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
  62. package/releases/0.68.0/surfaces/db/tree/.claude/agents/secops.md +2 -0
  63. package/releases/0.68.0/surfaces/db/tree/.claude/agents-overview.md +5 -0
  64. package/releases/0.68.0/surfaces/db/tree/.claude/graph.md +8 -0
  65. package/releases/0.68.0/surfaces/db/tree/.claude/patterns.md +22 -0
  66. package/releases/0.68.0/surfaces/db/tree/.claude/pipeline.md +13 -0
  67. package/releases/0.68.0/surfaces/db/tree/.claude/retrieval.md +5 -0
  68. package/releases/0.68.0/surfaces/db/tree/.claude/router.md +4 -0
  69. package/releases/0.68.0/surfaces/db/tree/CLAUDE.md +17 -0
  70. package/releases/0.68.0/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
  71. package/releases/0.68.0/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
  72. package/releases/0.68.0/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
  73. package/releases/0.68.0/surfaces/drizzle/tree/.claude/patterns.md +7 -0
  74. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
  75. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
  76. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
  77. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
  78. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
  79. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
  80. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
  81. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
  82. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
  83. package/releases/0.68.0/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
  84. package/releases/0.68.0/surfaces/edge-cf/tree/CLAUDE.md +27 -0
  85. package/releases/0.68.0/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
  86. package/releases/0.68.0/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
  87. package/releases/0.68.0/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
  88. package/releases/0.68.0/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
  89. package/releases/0.68.0/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
  90. package/releases/0.68.0/surfaces/frontend/tree/.claude/patterns.md +8 -0
  91. package/releases/0.68.0/surfaces/frontend/tree/.claude/retrieval.md +2 -0
  92. package/releases/0.68.0/surfaces/frontend/tree/.claude/router.md +14 -0
  93. package/releases/0.68.0/surfaces/frontend/tree/CLAUDE.md +5 -0
  94. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
  95. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
  96. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
  97. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
  98. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
  99. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
  100. package/releases/0.68.0/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
  101. package/releases/0.68.0/surfaces/integrations/tree/.claude/graph.md +10 -0
  102. package/releases/0.68.0/surfaces/integrations/tree/.claude/patterns.md +38 -0
  103. package/releases/0.68.0/surfaces/integrations/tree/.claude/pipeline.md +16 -0
  104. package/releases/0.68.0/surfaces/integrations/tree/.claude/retrieval.md +16 -0
  105. package/releases/0.68.0/surfaces/integrations/tree/.claude/router.md +6 -0
  106. package/releases/0.68.0/surfaces/integrations/tree/CLAUDE.md +17 -0
  107. package/releases/0.68.0/surfaces/money/tree/.claude/agents/architect.md +12 -0
  108. package/releases/0.68.0/surfaces/money/tree/.claude/agents/dba.md +14 -0
  109. package/releases/0.68.0/surfaces/money/tree/.claude/agents/implementer.md +11 -0
  110. package/releases/0.68.0/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
  111. package/releases/0.68.0/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
  112. package/releases/0.68.0/surfaces/money/tree/.claude/agents/secops.md +5 -0
  113. package/releases/0.68.0/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
  114. package/releases/0.68.0/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
  115. package/releases/0.68.0/surfaces/money/tree/.claude/graph.md +2 -0
  116. package/releases/0.68.0/surfaces/money/tree/.claude/patterns.md +49 -0
  117. package/releases/0.68.0/surfaces/money/tree/.claude/pipeline.md +2 -0
  118. package/releases/0.68.0/surfaces/money/tree/.claude/retrieval.md +2 -0
  119. package/releases/0.68.0/surfaces/money/tree/CLAUDE.md +11 -0
  120. package/releases/0.68.0/surfaces/pii/tree/.claude/agents/dba.md +2 -0
  121. package/releases/0.68.0/surfaces/pii/tree/.claude/agents/devops.md +8 -0
  122. package/releases/0.68.0/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
  123. package/releases/0.68.0/surfaces/pii/tree/.claude/agents/secops.md +2 -0
  124. package/releases/0.68.0/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
  125. package/releases/0.68.0/surfaces/pii/tree/CLAUDE.md +5 -0
  126. package/releases/0.68.0/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
  127. package/releases/0.68.0/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
  128. package/releases/0.68.0/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
  129. package/releases/0.68.0/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
  130. package/releases/0.68.0/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
  131. package/releases/0.68.0/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
  132. package/releases/0.68.0/surfaces/prisma/tree/.claude/patterns.md +15 -0
  133. package/releases/0.68.0/surfaces/prisma/tree/CLAUDE.md +5 -0
  134. package/releases/0.68.1/core/GAPS.md +125 -0
  135. package/releases/0.68.1/core/answered.json +80 -0
  136. package/releases/0.68.1/core/defaults/tree/.claude/agents/architect.md +1 -0
  137. package/releases/0.68.1/core/defaults/tree/.claude/agents/dba.md +3 -0
  138. package/releases/0.68.1/core/defaults/tree/.claude/agents/devops.md +1 -0
  139. package/releases/0.68.1/core/defaults/tree/.claude/agents/implementer.md +1 -0
  140. package/releases/0.68.1/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
  141. package/releases/0.68.1/core/defaults/tree/.claude/agents/qa.md +7 -0
  142. package/releases/0.68.1/core/defaults/tree/.claude/agents/reviewer.md +3 -0
  143. package/releases/0.68.1/core/defaults/tree/.claude/agents/secops.md +3 -0
  144. package/releases/0.68.1/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
  145. package/releases/0.68.1/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
  146. package/releases/0.68.1/core/tree/.claude/agents/architect.md +134 -0
  147. package/releases/0.68.1/core/tree/.claude/agents/dba.md +119 -0
  148. package/releases/0.68.1/core/tree/.claude/agents/design-reviewer.md +76 -0
  149. package/releases/0.68.1/core/tree/.claude/agents/devops.md +118 -0
  150. package/releases/0.68.1/core/tree/.claude/agents/implementer.md +178 -0
  151. package/releases/0.68.1/core/tree/.claude/agents/integration-tester.md +170 -0
  152. package/releases/0.68.1/core/tree/.claude/agents/planner.md +132 -0
  153. package/releases/0.68.1/core/tree/.claude/agents/qa.md +150 -0
  154. package/releases/0.68.1/core/tree/.claude/agents/reviewer.md +187 -0
  155. package/releases/0.68.1/core/tree/.claude/agents/secops.md +120 -0
  156. package/releases/0.68.1/core/tree/.claude/agents/solidity-auditor.md +126 -0
  157. package/releases/0.68.1/core/tree/.claude/agents/solidity-dev.md +123 -0
  158. package/releases/0.68.1/core/tree/.claude/agents-overview.md +65 -0
  159. package/releases/0.68.1/core/tree/.claude/frontend.md +10 -0
  160. package/releases/0.68.1/core/tree/.claude/graph.md +79 -0
  161. package/releases/0.68.1/core/tree/.claude/patterns.md +252 -0
  162. package/releases/0.68.1/core/tree/.claude/pills/README.md +150 -0
  163. package/releases/0.68.1/core/tree/.claude/pipeline.md +101 -0
  164. package/releases/0.68.1/core/tree/.claude/retrieval.md +103 -0
  165. package/releases/0.68.1/core/tree/.claude/router.md +218 -0
  166. package/releases/0.68.1/core/tree/.claude/templates/integration.md +48 -0
  167. package/releases/0.68.1/core/tree/CLAUDE.md +166 -0
  168. package/releases/0.68.1/core/tree/scripts/cost-watch.mjs +25 -0
  169. package/releases/0.68.1/core/tree/scripts/edit-guard.mjs +24 -0
  170. package/releases/0.68.1/core/tree/scripts/harness-check.mjs +81 -0
  171. package/releases/0.68.1/core/tree/scripts/loop-gate.mjs +19 -0
  172. package/releases/0.68.1/core/vocabulary.json +14 -0
  173. package/releases/0.68.1/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
  174. package/releases/0.68.1/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
  175. package/releases/0.68.1/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
  176. package/releases/0.68.1/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
  177. package/releases/0.68.1/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
  178. package/releases/0.68.1/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
  179. package/releases/0.68.1/surfaces/blockchain/tree/.claude/graph.md +11 -0
  180. package/releases/0.68.1/surfaces/blockchain/tree/.claude/router.md +6 -0
  181. package/releases/0.68.1/surfaces/blockchain/tree/CLAUDE.md +12 -0
  182. package/releases/0.68.1/surfaces/d1/tree/.claude/agents/dba.md +15 -0
  183. package/releases/0.68.1/surfaces/d1/tree/.claude/agents/devops.md +2 -0
  184. package/releases/0.68.1/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
  185. package/releases/0.68.1/surfaces/d1/tree/.claude/patterns.md +8 -0
  186. package/releases/0.68.1/surfaces/d1/tree/CLAUDE.md +2 -0
  187. package/releases/0.68.1/surfaces/db/tree/.claude/agents/architect.md +5 -0
  188. package/releases/0.68.1/surfaces/db/tree/.claude/agents/dba.md +54 -0
  189. package/releases/0.68.1/surfaces/db/tree/.claude/agents/devops.md +5 -0
  190. package/releases/0.68.1/surfaces/db/tree/.claude/agents/implementer.md +2 -0
  191. package/releases/0.68.1/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
  192. package/releases/0.68.1/surfaces/db/tree/.claude/agents/planner.md +2 -0
  193. package/releases/0.68.1/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
  194. package/releases/0.68.1/surfaces/db/tree/.claude/agents/secops.md +2 -0
  195. package/releases/0.68.1/surfaces/db/tree/.claude/agents-overview.md +5 -0
  196. package/releases/0.68.1/surfaces/db/tree/.claude/graph.md +8 -0
  197. package/releases/0.68.1/surfaces/db/tree/.claude/patterns.md +22 -0
  198. package/releases/0.68.1/surfaces/db/tree/.claude/pipeline.md +13 -0
  199. package/releases/0.68.1/surfaces/db/tree/.claude/retrieval.md +5 -0
  200. package/releases/0.68.1/surfaces/db/tree/.claude/router.md +4 -0
  201. package/releases/0.68.1/surfaces/db/tree/CLAUDE.md +17 -0
  202. package/releases/0.68.1/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
  203. package/releases/0.68.1/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
  204. package/releases/0.68.1/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
  205. package/releases/0.68.1/surfaces/drizzle/tree/.claude/patterns.md +7 -0
  206. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
  207. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
  208. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
  209. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
  210. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
  211. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
  212. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
  213. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
  214. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
  215. package/releases/0.68.1/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
  216. package/releases/0.68.1/surfaces/edge-cf/tree/CLAUDE.md +27 -0
  217. package/releases/0.68.1/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
  218. package/releases/0.68.1/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
  219. package/releases/0.68.1/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
  220. package/releases/0.68.1/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
  221. package/releases/0.68.1/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
  222. package/releases/0.68.1/surfaces/frontend/tree/.claude/patterns.md +8 -0
  223. package/releases/0.68.1/surfaces/frontend/tree/.claude/retrieval.md +2 -0
  224. package/releases/0.68.1/surfaces/frontend/tree/.claude/router.md +14 -0
  225. package/releases/0.68.1/surfaces/frontend/tree/CLAUDE.md +5 -0
  226. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
  227. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
  228. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
  229. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
  230. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
  231. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
  232. package/releases/0.68.1/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
  233. package/releases/0.68.1/surfaces/integrations/tree/.claude/graph.md +10 -0
  234. package/releases/0.68.1/surfaces/integrations/tree/.claude/patterns.md +38 -0
  235. package/releases/0.68.1/surfaces/integrations/tree/.claude/pipeline.md +16 -0
  236. package/releases/0.68.1/surfaces/integrations/tree/.claude/retrieval.md +16 -0
  237. package/releases/0.68.1/surfaces/integrations/tree/.claude/router.md +6 -0
  238. package/releases/0.68.1/surfaces/integrations/tree/CLAUDE.md +17 -0
  239. package/releases/0.68.1/surfaces/money/tree/.claude/agents/architect.md +12 -0
  240. package/releases/0.68.1/surfaces/money/tree/.claude/agents/dba.md +14 -0
  241. package/releases/0.68.1/surfaces/money/tree/.claude/agents/implementer.md +11 -0
  242. package/releases/0.68.1/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
  243. package/releases/0.68.1/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
  244. package/releases/0.68.1/surfaces/money/tree/.claude/agents/secops.md +5 -0
  245. package/releases/0.68.1/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
  246. package/releases/0.68.1/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
  247. package/releases/0.68.1/surfaces/money/tree/.claude/graph.md +2 -0
  248. package/releases/0.68.1/surfaces/money/tree/.claude/patterns.md +49 -0
  249. package/releases/0.68.1/surfaces/money/tree/.claude/pipeline.md +2 -0
  250. package/releases/0.68.1/surfaces/money/tree/.claude/retrieval.md +2 -0
  251. package/releases/0.68.1/surfaces/money/tree/CLAUDE.md +11 -0
  252. package/releases/0.68.1/surfaces/pii/tree/.claude/agents/dba.md +2 -0
  253. package/releases/0.68.1/surfaces/pii/tree/.claude/agents/devops.md +8 -0
  254. package/releases/0.68.1/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
  255. package/releases/0.68.1/surfaces/pii/tree/.claude/agents/secops.md +2 -0
  256. package/releases/0.68.1/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
  257. package/releases/0.68.1/surfaces/pii/tree/CLAUDE.md +5 -0
  258. package/releases/0.68.1/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
  259. package/releases/0.68.1/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
  260. package/releases/0.68.1/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
  261. package/releases/0.68.1/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
  262. package/releases/0.68.1/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
  263. package/releases/0.68.1/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
  264. package/releases/0.68.1/surfaces/prisma/tree/.claude/patterns.md +15 -0
  265. package/releases/0.68.1/surfaces/prisma/tree/CLAUDE.md +5 -0
  266. package/src/commands/gate.mjs +1 -1
  267. package/src/commands/learn.mjs +2 -1
  268. package/src/commands/sizes.mjs +72 -30
  269. package/src/gate.mjs +114 -8
  270. package/src/office.html +212 -96
  271. package/src/office.mjs +2 -1
package/src/office.html CHANGED
@@ -152,22 +152,36 @@ function disc(ctx, cx, cy, r, color) {
152
152
  }
153
153
 
154
154
  // ─── the floor plan ───────────────────────────────────────────────────────────────────────────
155
- const LW = 480;
156
- const CORRIDOR_X = 224;
157
- const CORRIDOR_W = 32;
158
- const HALL_X = CORRIDOR_X + CORRIDOR_W / 2;
155
+ /*
156
+ * Two rows of rooms either side of one corridor that runs across the building, the garden below. The floor is laid
157
+ * out for the window it is drawn in: a room's desks go in as many rows as make the whole office come out largest, so
158
+ * a wide window gets long rooms side by side and a narrow one deeper rooms. Rooms used to stand in two columns, three
159
+ * deep, off a corridor down the middle, four desks a row: once a stage got as many desks as it ever ran at once, a
160
+ * project's office grew taller than wide, fitted whole it stood small in the middle of a wide window, and people
161
+ * watching it asked whether it worked at all.
162
+ */
159
163
  const FACE = 24;
160
164
  const DESK_STEP = 52;
161
165
  const DESK_ROW = 46;
166
+ const CORRIDOR_H = 32;
162
167
  const GARDEN = 52;
168
+ /** The reception's own floor: its counter, the waiting chairs, the vending machine. */
169
+ const LOBBY_W = 224;
170
+ const LOBBY_H = 116;
171
+ /** A room below the corridor is entered through the wall it faces, and walked down a strip by its right wall to its lane. */
172
+ const STRIP = 22;
173
+ /** The column a room's shelf or rack stands in, past its last desk. */
174
+ const CORNER = 28;
175
+ /** An empty room is somewhere to sit, as wide as four desks. */
176
+ const EMPTY_W = 224;
163
177
 
164
178
  /** The rooms, by phase, in the order the work moves through them. A stage not named here works in build. */
165
179
  const PHASES = [
166
- { key: 'design', name: 'design', side: 'left', roles: ['planner', 'architect', 'design-reviewer'] },
167
- { key: 'build', name: 'build', side: 'left', roles: ['implementer', 'solidity-dev'] },
168
- { key: 'review', name: 'review & gates', side: 'right', roles: ['reviewer', 'dba', 'integration-tester', 'solidity-auditor'] },
169
- { key: 'lab', name: 'test lab', side: 'right', roles: ['qa'] },
170
- { key: 'release', name: 'release', side: 'right', roles: ['devops', 'secops'] },
180
+ { key: 'design', name: 'design', band: 'top', roles: ['planner', 'architect', 'design-reviewer'] },
181
+ { key: 'build', name: 'build', band: 'top', roles: ['implementer', 'solidity-dev'] },
182
+ { key: 'review', name: 'review & gates', band: 'top', roles: ['reviewer', 'dba', 'integration-tester', 'solidity-auditor'] },
183
+ { key: 'lab', name: 'test lab', band: 'bottom', roles: ['qa'] },
184
+ { key: 'release', name: 'release', band: 'bottom', roles: ['devops', 'secops'] },
171
185
  ];
172
186
 
173
187
  const rooms = new Map(PHASES.map((ph) => [ph.key, { ...ph, stages: [] }]));
@@ -177,71 +191,167 @@ ROOM.stages.forEach((role, i) => {
177
191
  // declares `× many` in a page served before it was.
178
192
  rooms.get(phase).stages.push({ role, index: i, seats: ROOM.seats?.[role] ?? (ROOM.many.includes(role) ? 2 : 1) });
179
193
  });
180
- const lobby = { key: 'lobby', name: 'reception', side: 'left', stages: [] };
181
- const columns = {
182
- left: [rooms.get('design'), rooms.get('build'), lobby],
183
- right: [rooms.get('review'), rooms.get('lab'), rooms.get('release')],
194
+ const lobby = { key: 'lobby', name: 'reception', band: 'bottom', stages: [] };
195
+ const bands = {
196
+ top: [rooms.get('design'), rooms.get('build'), rooms.get('review')],
197
+ bottom: [lobby, rooms.get('lab'), rooms.get('release')],
184
198
  };
185
199
  for (const room of [...rooms.values(), lobby]) {
186
- const desks = room.stages.reduce((n, st) => n + st.seats, 0);
187
- room.deskCount = desks;
188
- room.rows = Math.max(1, Math.ceil(desks / 4));
189
- room.h = room === lobby ? 116 : FACE + 8 + room.rows * DESK_ROW + 26;
200
+ room.deskCount = room.stages.reduce((n, st) => n + st.seats, 0);
201
+ room.corner = room.key === 'lab' || room.key === 'release';
190
202
  }
191
- for (const [side, list] of Object.entries(columns)) {
192
- let y = 0;
193
- for (const room of list) {
194
- room.x = side === 'left' ? 0 : CORRIDOR_X + CORRIDOR_W;
195
- room.w = side === 'left' ? CORRIDOR_X : LW - room.x;
196
- room.y = y;
197
- y += room.h;
198
- }
203
+
204
+ /** How wide a room's name plate is, so what hangs beside it starts after it. */
205
+ const signWidth = (room) => Math.max(40, room.name.length * 4 + 8);
206
+ /** Where a room's shelf or rack stands: in its column, before the strip of a room below the corridor. */
207
+ const cornerX = (room) => room.x + room.w - (room.band === 'bottom' ? STRIP : 0) - CORNER + 3;
208
+ /** Desks a row in a room whose band has `rows` rows of them. */
209
+ const perRow = (room, rows) => Math.ceil(room.deskCount / rows);
210
+ /** How wide a room is with its desks in `rows` rows. */
211
+ function roomWidth(room, rows) {
212
+ if (room === lobby) return LOBBY_W + STRIP;
213
+ const desks = room.deskCount ? 12 + perRow(room, rows) * DESK_STEP + 4 + (room.corner ? CORNER : 0) : EMPTY_W;
214
+ return Math.max(desks, signWidth(room) + 24) + (room.band === 'bottom' ? STRIP : 0);
199
215
  }
200
- // The shorter column's last room takes up the difference, so both reach the garden wall together.
201
- const FLOOR_H = Math.max(...Object.values(columns).map((list) => list.at(-1).y + list.at(-1).h));
202
- for (const list of Object.values(columns)) list.at(-1).h = FLOOR_H - list.at(-1).y;
203
- const LH = FLOOR_H + GARDEN;
204
- for (const room of [...rooms.values(), lobby]) {
205
- room.laneY = room.y + room.h - 14;
206
- room.doorX = room.side === 'left' ? room.x + room.w : room.x;
216
+ /** How tall a band of rooms is with their desks in at most `rows` rows. */
217
+ function bandHeight(list, rows) {
218
+ const most = Math.max(1, ...list.filter((r) => r.deskCount).map((r) => Math.ceil(r.deskCount / perRow(r, rows))));
219
+ return Math.max(list.includes(lobby) ? LOBBY_H : 0, FACE + 8 + most * DESK_ROW + 26);
220
+ }
221
+ /** The office's size with each band's desks in so many rows. */
222
+ function measure(arrangement) {
223
+ const wide = (band) => bands[band].reduce((x, room) => x + roomWidth(room, arrangement[band]), 0);
224
+ return { w: Math.max(wide('top'), wide('bottom')), h: bandHeight(bands.top, arrangement.top) + CORRIDOR_H + bandHeight(bands.bottom, arrangement.bottom) + GARDEN };
225
+ }
226
+ /** The rows for each band that make the whole office come out largest in a space `width` by `height`. */
227
+ function arrange(width, height) {
228
+ // A page loaded hidden, as the dashboard's frame is until its tab is opened, has no size yet: it lays out for a common
229
+ // window, and again when it is shown.
230
+ const [W, H] = width > 0 && height > 0 ? [width, height] : [1200, 800];
231
+ const most = (band) => Math.max(1, ...bands[band].map((r) => r.deskCount));
232
+ let best = null;
233
+ for (let top = 1; top <= most('top'); top += 1) {
234
+ for (let bottom = 1; bottom <= most('bottom'); bottom += 1) {
235
+ const size = measure({ top, bottom });
236
+ const zoom = Math.min(W / size.w, H / size.h);
237
+ if (!best || zoom > best.zoom + 1e-9) best = { top, bottom, zoom };
238
+ }
239
+ }
240
+ return best;
207
241
  }
208
242
 
209
- /** Each stage's desks and the places to stand by them; and the stage of a role. */
243
+ /** Each stage's desks and the places to stand by them, placed by `layout`; and the stage of a role. */
210
244
  const stages = new Map();
211
245
  for (const room of rooms.values()) {
212
- let n = 0;
213
246
  for (const st of room.stages) {
214
- const stage = { role: st.role, room, shirt: SHIRTS[st.index % SHIRTS.length], desks: [], slots: [], folder: null };
215
- for (let k = 0; k < st.seats; k += 1, n += 1) {
216
- const dx = room.x + 12 + (n % 4) * DESK_STEP;
217
- const dy = room.y + FACE + 6 + Math.floor(n / 4) * DESK_ROW;
218
- const aisle = dx + 44;
219
- const seatY = dy + 34;
220
- const exit = [{ x: aisle, y: seatY }, { x: aisle, y: room.laneY }];
221
- stage.desks.push({ dx, dy });
222
- stage.slots.push({ x: dx + 18, y: seatY, room, exit, kind: 'seat', who: null, desk: stage.desks.at(-1) });
247
+ const stage = { role: st.role, room, shirt: SHIRTS[st.index % SHIRTS.length], desks: [], slots: [], folder: null, drop: { room }, spare: { room, kind: 'stand', role: st.role } };
248
+ for (let k = 0; k < st.seats; k += 1) {
249
+ stage.desks.push({});
250
+ stage.slots.push({ room, kind: 'seat', who: null, desk: stage.desks.at(-1) });
223
251
  }
224
- const first = stage.desks[0];
225
- stage.drop = { x: first.dx + 44, y: first.dy + 30, room, exit: [{ x: first.dx + 44, y: room.laneY }] };
226
- stage.spare = { x: first.dx + 44, y: first.dy + 40, room, exit: [{ x: first.dx + 44, y: room.laneY }], kind: 'stand' };
227
252
  stages.set(st.role, stage);
228
253
  }
229
254
  }
230
- const COUNTER = { x: lobby.x + 14, y: lobby.y + FACE + 22, w: 104 };
255
+ const COUNTER = { w: 104 };
231
256
  // NINA stands at the end of the counter, facing the room: behind it, only her head showed.
232
- const BOSS_HOME = { x: COUNTER.x + COUNTER.w + 10, y: COUNTER.y + 8, room: lobby, exit: [{ x: COUNTER.x + COUNTER.w + 10, y: lobby.laneY }], kind: 'stand' };
257
+ const BOSS_HOME = { room: lobby, kind: 'stand' };
233
258
  // The owner is not drawn: they are the phone on the counter, where the gate's calls ring and their answers come in.
234
- const PHONE = { x: COUNTER.x + 72, y: COUNTER.y - 11 };
235
- const OWNER_HOME = { x: PHONE.x + 5, y: PHONE.y + 14, room: lobby, kind: 'line' };
236
- const ENTRANCE = { x: lobby.x + 150, y: FLOOR_H - 2, room: lobby, exit: [{ x: lobby.x + 150, y: lobby.laneY }], kind: 'stand' };
259
+ const PHONE = {};
260
+ const OWNER_HOME = { room: lobby, kind: 'line' };
261
+ const ENTRANCE = { room: lobby, kind: 'stand' };
262
+ const RECEPTION = {};
263
+
264
+ let LW = 0;
265
+ let LH = 0;
266
+ let FLOOR_H = 0;
267
+ let HALL_Y = 0;
268
+ /** The rows each band's desks are in now. */
269
+ let arranged = null;
270
+
271
+ /**
272
+ * Lays the floor out with each band's desks in so many rows. Every place someone can be is the same object before and
273
+ * after, moved, so whoever sits, stands or walks keeps it.
274
+ */
275
+ function layout(arrangement) {
276
+ arranged = arrangement;
277
+ const [wasW, wasH] = [LW, LH];
278
+ LW = measure(arrangement).w;
279
+ const topH = bandHeight(bands.top, arrangement.top);
280
+ const bottomH = bandHeight(bands.bottom, arrangement.bottom);
281
+ HALL_Y = topH + CORRIDOR_H / 2;
282
+ FLOOR_H = topH + CORRIDOR_H + bottomH;
283
+ LH = FLOOR_H + GARDEN;
284
+ for (const [band, list] of Object.entries(bands)) {
285
+ let x = 0;
286
+ for (const room of list) {
287
+ room.per = perRow(room, arrangement[band]);
288
+ room.x = x;
289
+ room.w = roomWidth(room, arrangement[band]);
290
+ room.y = band === 'top' ? 0 : topH + CORRIDOR_H;
291
+ room.h = band === 'top' ? topH : bottomH;
292
+ x += room.w;
293
+ }
294
+ // The narrower band's last room takes up the difference, so both reach the end wall together.
295
+ list.at(-1).w += LW - x;
296
+ }
297
+ for (const room of [...rooms.values(), lobby]) {
298
+ room.laneY = room.y + room.h - 14;
299
+ // A room above the corridor opens onto it through its bottom wall; one below, through the wall it faces, at its strip.
300
+ room.doorX = room.band === 'top' ? room.x + room.w - 14 : room.x + room.w - STRIP / 2;
301
+ }
302
+ for (const room of rooms.values()) {
303
+ let n = 0;
304
+ for (const st of room.stages) {
305
+ const stage = stages.get(st.role);
306
+ stage.slots.forEach((slot, k) => {
307
+ const dx = room.x + 12 + (n % room.per) * DESK_STEP;
308
+ const dy = room.y + FACE + 6 + Math.floor(n / room.per) * DESK_ROW;
309
+ const aisle = dx + 44;
310
+ const seatY = dy + 34;
311
+ n += 1;
312
+ Object.assign(stage.desks[k], { dx, dy });
313
+ Object.assign(slot, { x: dx + 18, y: seatY, exit: [{ x: aisle, y: seatY }, { x: aisle, y: room.laneY }] });
314
+ });
315
+ const first = stage.desks[0];
316
+ Object.assign(stage.drop, { x: first.dx + 44, y: first.dy + 30, exit: [{ x: first.dx + 44, y: room.laneY }] });
317
+ Object.assign(stage.spare, { x: first.dx + 44, y: first.dy + 40, exit: [{ x: first.dx + 44, y: room.laneY }] });
318
+ }
319
+ }
320
+ Object.assign(COUNTER, { x: lobby.x + 14, y: lobby.y + FACE + 22 });
321
+ Object.assign(BOSS_HOME, { x: COUNTER.x + COUNTER.w + 10, y: COUNTER.y + 8, exit: [{ x: COUNTER.x + COUNTER.w + 10, y: lobby.laneY }] });
322
+ Object.assign(PHONE, { x: COUNTER.x + 72, y: COUNTER.y - 11 });
323
+ Object.assign(OWNER_HOME, { x: PHONE.x + 5, y: PHONE.y + 14 });
324
+ Object.assign(ENTRANCE, { x: lobby.x + 150, y: FLOOR_H - 2, exit: [{ x: lobby.x + 150, y: lobby.laneY }] });
325
+ Object.assign(RECEPTION, { x: COUNTER.x + COUNTER.w / 2, y: COUNTER.y + 14 });
326
+ drawBackground();
327
+ world.width = LW;
328
+ world.height = LH;
329
+ // The view stays over the same part of the office.
330
+ cam.x = wasW ? (cam.x / wasW) * LW : LW / 2;
331
+ cam.y = wasH ? (cam.y / wasH) * LH : LH / 2;
332
+ // Whoever is somewhere is drawn there again; whoever is on their way sets out again from where they were. A place
333
+ // beside a stage's full desks is a copy of its spare spot, held as where someone stands, sits, is going, or left
334
+ // from: each is moved with the spot it copies.
335
+ for (const p of [...people.values(), boss, owner]) {
336
+ for (const spot of [p.slot, p.at, p.current?.to, ...p.queue.map((q) => q.to)]) {
337
+ if (!spot?.extra) continue;
338
+ const { x, y, exit } = stages.get(spot.role).spare;
339
+ Object.assign(spot, { x, y, exit });
340
+ }
341
+ const from = p.at ?? ENTRANCE;
342
+ p.x = from.x;
343
+ p.y = from.y;
344
+ if (p.current?.kind === 'walk') p.path = route(from, p.current.to);
345
+ }
346
+ }
237
347
 
238
- /** The way from where someone stands to a spot: out to their room's lane, along the corridor when it is another room. */
348
+ /** The way from where someone stands to a spot: out to their room's lane and door, along the corridor when it is another room. */
239
349
  function route(from, to) {
240
350
  const out = from.exit ?? [{ x: from.x, y: from.room.laneY }];
241
351
  const into = [...(to.exit ?? [{ x: to.x, y: to.room.laneY }])].reverse();
242
352
  const pts = [...out];
243
353
  if (from.room !== to.room) {
244
- pts.push({ x: from.room.doorX, y: from.room.laneY }, { x: HALL_X, y: from.room.laneY }, { x: HALL_X, y: to.room.laneY }, { x: to.room.doorX, y: to.room.laneY });
354
+ pts.push({ x: from.room.doorX, y: from.room.laneY }, { x: from.room.doorX, y: HALL_Y }, { x: to.room.doorX, y: HALL_Y }, { x: to.room.doorX, y: to.room.laneY });
245
355
  }
246
356
  pts.push(...into, { x: to.x, y: to.y });
247
357
  return pts.filter((p, i) => i === 0 || p.x !== pts[i - 1].x || p.y !== pts[i - 1].y);
@@ -321,38 +431,35 @@ function wallItem(g, room, kind, x) {
321
431
  function sign(g, x, y, w) {
322
432
  box(g, x, y, w, 9, C.sign, C.ink);
323
433
  }
324
- /** How wide a room's name plate is, so what hangs beside it starts after it. */
325
- const signWidth = (room) => Math.max(40, room.name.length * 4 + 8);
326
434
  /** Where a room's clock, board or poster hangs: towards the far end of its wall. */
327
435
  const wallSpot = (room) => room.x + room.w - 70;
436
+ /** Whether a room's wall has space for its clock, board or poster past its name plate; and for a window between them. */
437
+ const hangs = (room) => wallSpot(room) >= room.x + 8 + signWidth(room) + 6;
438
+ const windowed = (room) => room.x + 8 + signWidth(room) + 16 + 30 <= (hangs(room) ? wallSpot(room) : room.x + room.w - (room.band === 'bottom' ? STRIP : 0)) - 6;
328
439
 
329
440
  const background = document.createElement('canvas');
330
- background.width = LW;
331
- background.height = LH;
332
- {
441
+ /** The building, drawn again whenever the floor is laid out anew. */
442
+ function drawBackground() {
443
+ background.width = LW;
444
+ background.height = LH;
333
445
  const g = background.getContext('2d');
334
446
  // The garden, and the path to the door.
335
447
  rect(g, 0, FLOOR_H, LW, GARDEN, C.grass);
336
- for (let i = 0; i < 260; i += 1) {
448
+ for (let i = 0; i < Math.round(LW * 0.55); i += 1) {
337
449
  const hx = hash(`tuft${i}`);
338
450
  rect(g, hx % LW, FLOOR_H + 4 + ((hx >> 9) % (GARDEN - 6)), 1, 2, i % 3 ? C.grassDark : C.grassLight);
339
451
  }
340
452
  rect(g, ENTRANCE.x - 10, FLOOR_H, 20, GARDEN, C.path);
341
453
  for (let y = FLOOR_H + 4; y < LH; y += 8) rect(g, ENTRANCE.x - 10, y, 20, 1, C.pathDark);
342
- for (const tx of [6, 60, 112, 200, 268, 330, 392, 446]) if (Math.abs(tx + 9 - ENTRANCE.x) > 24) tree(g, tx, FLOOR_H + 14);
343
- for (const fx of [34, 92, 236, 300, 362, 424]) if (Math.abs(fx - ENTRANCE.x) > 20) {
454
+ for (let tx = 6; tx < LW - 18; tx += 56 + (hash(`tree${tx}`) % 12)) if (Math.abs(tx + 9 - ENTRANCE.x) > 24) tree(g, tx, FLOOR_H + 14);
455
+ for (let fx = 34; fx < LW - 8; fx += 62) if (Math.abs(fx - ENTRANCE.x) > 20) {
344
456
  rect(g, fx, FLOOR_H + 6, 2, 2, C.flower);
345
457
  rect(g, fx + 5, FLOOR_H + 9, 2, 2, C.flowerY);
346
458
  }
347
- // The corridor, its floor running the building's height.
348
- tiles(g, CORRIDOR_X, 0, CORRIDOR_W, FLOOR_H, C.hall, C.hallLine);
349
- rect(g, CORRIDOR_X, 0, CORRIDOR_W, FACE, C.wallFace);
350
- rect(g, CORRIDOR_X, FACE - 10, CORRIDOR_W, 8, C.band);
351
- rect(g, CORRIDOR_X, FACE - 2, CORRIDOR_W, 2, C.base);
352
- box(g, CORRIDOR_X + 9, 4, 14, 9, '#3ec74d');
353
- rect(g, CORRIDOR_X + 11, 7, 10, 3, C.white);
354
- plant(g, CORRIDOR_X + 9, FACE + 2, true);
355
- plant(g, CORRIDOR_X + 9, FLOOR_H - 26, true);
459
+ // The corridor, across the building between the two rows of rooms.
460
+ const hallTop = HALL_Y - CORRIDOR_H / 2;
461
+ tiles(g, 0, hallTop, LW, CORRIDOR_H, C.hall, C.hallLine);
462
+ plant(g, 6, hallTop + 6, true);
356
463
  // Each room: its floor, the wall it faces, its furniture.
357
464
  for (const room of [...rooms.values(), lobby]) {
358
465
  tiles(g, room.x, room.y, room.w, room.h, C.floor, C.floorLine);
@@ -362,11 +469,16 @@ background.height = LH;
362
469
  rect(g, room.x, room.y + FACE - 10, room.w, 1, C.bandDark);
363
470
  rect(g, room.x, room.y + FACE - 2, room.w, 2, C.base);
364
471
  if (room !== lobby) sign(g, room.x + 8, room.y + 4, signWidth(room));
472
+ if (room.band === 'bottom') {
473
+ // The doorway in the wall it faces, onto the corridor.
474
+ tiles(g, room.doorX - 10, room.y, 20, FACE, C.floor, C.floorLine);
475
+ rect(g, room.doorX - 11, room.y, 1, FACE, C.ink);
476
+ rect(g, room.doorX + 10, room.y, 1, FACE, C.ink);
477
+ }
365
478
  }
366
479
  for (const room of rooms.values()) {
367
- const far = room.side === 'left' ? room.x + 6 : room.x + room.w - 22;
368
- wallItem(g, room, 'window', room.x + 8 + signWidth(room) + 16);
369
- wallItem(g, room, room.key === 'design' ? 'board' : room.key === 'lab' ? 'poster' : 'clock', wallSpot(room));
480
+ if (windowed(room)) wallItem(g, room, 'window', room.x + 8 + signWidth(room) + 16);
481
+ if (hangs(room)) wallItem(g, room, room.key === 'design' ? 'board' : room.key === 'lab' ? 'poster' : 'clock', wallSpot(room));
370
482
  for (const st of room.stages) for (const d of stages.get(st.role).desks) deskAt(g, d.dx, d.dy);
371
483
  if (room.stages.length === 0) {
372
484
  // A room with no stage of its own is somewhere to sit.
@@ -374,14 +486,14 @@ background.height = LH;
374
486
  box(g, room.x + 70, room.y + FACE + 20, room.w - 140, 14, C.wood);
375
487
  for (let i = 0; i < 4; i += 1) box(g, room.x + 58 + i * 30, room.y + FACE + 8, 10, 9, C.seatRed);
376
488
  }
377
- plant(g, far, room.laneY - 18, true);
378
- // The shelf and the rack stand in a room's far corner, where only a fourth desk reaches — in design, the
379
- // design-reviewer's desk was the fourth and stood under the shelf — so a room with four desks has neither.
380
- const corner = room.deskCount < 4;
381
- if (room.key === 'release' && corner) shelf(g, room.x + room.w - 30, room.y + FACE + 2);
382
- if (room.key === 'lab' && corner) {
383
- box(g, room.x + room.w - 24, room.y + FACE + 2, 16, 30, C.rack);
384
- for (let i = 0; i < 6; i += 1) rect(g, room.x + room.w - 21, room.y + FACE + 5 + i * 4, 2, 1, i % 3 ? C.ledG : C.ledR);
489
+ plant(g, room.x + 4, room.laneY - 18, true);
490
+ // The shelf and the rack stand in a column of their own past the last desk: in the room's far corner, the fourth
491
+ // desk of a room stood under them.
492
+ const corner = cornerX(room);
493
+ if (room.key === 'release') shelf(g, corner, room.y + FACE + 2);
494
+ if (room.key === 'lab') {
495
+ box(g, corner + 3, room.y + FACE + 2, 16, 30, C.rack);
496
+ for (let i = 0; i < 6; i += 1) rect(g, corner + 6, room.y + FACE + 5 + i * 4, 2, 1, i % 3 ? C.ledG : C.ledR);
385
497
  }
386
498
  }
387
499
  // The reception: the counter's back, the waiting chairs, a vending machine, plants; the sign on its wall.
@@ -405,7 +517,7 @@ background.height = LH;
405
517
  rect(g, lobby.x + 140, lobby.y + FACE + 22, 40, 16, C.rug);
406
518
  box(g, lobby.x + 150, lobby.y + FACE + 26, 20, 8, C.wood);
407
519
  plant(g, COUNTER.x - 12, COUNTER.y - 4, false);
408
- plant(g, lobby.x + 208, lobby.laneY - 20, true);
520
+ plant(g, lobby.x + 206, lobby.laneY - 20, true);
409
521
  rect(g, ENTRANCE.x - 12, FLOOR_H - 8, 24, 6, C.rugEdge);
410
522
  }
411
523
  // The walls themselves: their white tops, outlined, with doors onto the corridor and out to the garden.
@@ -418,15 +530,17 @@ background.height = LH;
418
530
  rect(g, x0, y - 1, x1 - x0, 2, C.wallTop);
419
531
  };
420
532
  for (const room of [...rooms.values(), lobby]) {
421
- wallH(room.x, room.x + room.w, room.y + 1);
422
- const outer = room.side === 'left' ? room.x + 1 : room.x + room.w - 1;
423
- wallV(outer, room.y, room.y + room.h);
424
- const doorTop = room.laneY - 12;
425
- const doorBottom = room.laneY + 8;
426
- wallV(room.doorX, room.y, doorTop);
427
- wallV(room.doorX, doorBottom, room.y + room.h);
428
- rect(g, room.doorX - 2, doorTop - 2, 4, 2, C.rail);
533
+ // A room above the corridor has its door in the wall along its bottom; one below, in the wall along its top.
534
+ const doorWall = room.band === 'top' ? room.y + room.h - 1 : room.y + 1;
535
+ wallH(room.x, room.doorX - 10, doorWall);
536
+ wallH(room.doorX + 10, room.x + room.w, doorWall);
537
+ rect(g, room.doorX - 12, doorWall - 2, 2, 4, C.rail);
538
+ rect(g, room.doorX + 10, doorWall - 2, 2, 4, C.rail);
539
+ if (room.band === 'top') wallH(room.x, room.x + room.w, room.y + 1);
540
+ if (room.x > 0) wallV(room.x, room.y, room.y + room.h);
429
541
  }
542
+ wallV(1, 0, FLOOR_H);
543
+ wallV(LW - 1, 0, FLOOR_H);
430
544
  wallH(0, ENTRANCE.x - 12, FLOOR_H - 1);
431
545
  wallH(ENTRANCE.x + 12, LW, FLOOR_H - 1);
432
546
  }
@@ -475,6 +589,8 @@ function seatAt(stage, p, instant = false) {
475
589
  }
476
590
  }
477
591
  if (!slot) {
592
+ // Already standing beside this stage's full desks, they stay where they stand.
593
+ if (p.slot?.extra && p.slot.role === stage.role) return p.slot;
478
594
  const extra = { ...stage.spare, who: p, extra: true };
479
595
  if (p.slot && p.slot.who === p) p.slot.who = null;
480
596
  p.slot = extra;
@@ -546,7 +662,6 @@ let banner = null;
546
662
  /** What the view follows when it is closer than the whole office: a person as they walk, or a spot. */
547
663
  let focus = null;
548
664
  const follow = (target) => (focus = target);
549
- const RECEPTION = { x: COUNTER.x + COUNTER.w / 2, y: COUNTER.y + 14 };
550
665
  /** The stage a dispatch past its cap was for, while the gate's call waits on the owner. */
551
666
  let capRole = null;
552
667
  function settleCap() {
@@ -805,8 +920,6 @@ function step(p, dt) {
805
920
  }
806
921
 
807
922
  const world = document.createElement('canvas');
808
- world.width = LW;
809
- world.height = LH;
810
923
  const w = world.getContext('2d');
811
924
  const screen = document.getElementById('screen');
812
925
  const s = screen.getContext('2d');
@@ -834,7 +947,7 @@ let scale = 1;
834
947
  let band = 0;
835
948
  let ox = 0;
836
949
  let oy = 0;
837
- const cam = { x: LW / 2, y: LH / 2 };
950
+ const cam = { x: 0, y: 0 };
838
951
  let handsOffUntil = 0;
839
952
  /** 'fit', a zoom the viewer chose in points an office pixel, or null when they never chose. */
840
953
  let chosen = null;
@@ -967,6 +1080,9 @@ function resize() {
967
1080
  screen.style.width = `${window.innerWidth - side}px`;
968
1081
  screen.style.height = `${window.innerHeight}px`;
969
1082
  band = Math.round(BAND * dpr);
1083
+ // The floor is laid out for the space the office is drawn in, and again when that space takes another shape.
1084
+ const next = arrange(window.innerWidth - side, window.innerHeight - BAND);
1085
+ if (!arranged || next.top !== arranged.top || next.bottom !== arranged.bottom) layout(next);
970
1086
  fit = Math.min(screen.width / LW, (screen.height - band) / LH);
971
1087
  scale = level() * dpr;
972
1088
  syncButtons();
@@ -1101,7 +1217,7 @@ function drawWorld(now) {
1101
1217
  // The clock in each room says the time it is here.
1102
1218
  const t = new Date();
1103
1219
  for (const room of rooms.values()) {
1104
- if (room.key === 'design' || room.key === 'lab') continue;
1220
+ if (room.key === 'design' || room.key === 'lab' || !hangs(room)) continue;
1105
1221
  const cx = wallSpot(room) + 5;
1106
1222
  const cy = room.y + 10;
1107
1223
  for (const [len, turn] of [[2, (t.getHours() % 12) / 12 + t.getMinutes() / 720], [3, t.getMinutes() / 60]]) {
@@ -1175,7 +1291,7 @@ function drawScreen(now) {
1175
1291
  if (Number.isInteger(scale) || scale > 4) s.drawImage(world, ox, oy, LW * scale, LH * scale);
1176
1292
  else {
1177
1293
  const k = Math.max(1, Math.ceil(scale));
1178
- if (crisp.width !== LW * k) {
1294
+ if (crisp.width !== LW * k || crisp.height !== LH * k) {
1179
1295
  crisp.width = LW * k;
1180
1296
  crisp.height = LH * k;
1181
1297
  }
package/src/office.mjs CHANGED
@@ -100,7 +100,8 @@ const REPLAY_MIN_GAP_MS = 500;
100
100
  * @param {object[]} ledger - The ledger, oldest first.
101
101
  */
102
102
  function readStarts(ledger) {
103
- const entries = ledger.filter((e) => Number.isFinite(Date.parse(e?.at)));
103
+ // What a session carried over from the one before it is that session's work, drawn there.
104
+ const entries = ledger.filter((e) => Number.isFinite(Date.parse(e?.at)) && !e.inherited);
104
105
  const time = (e) => Date.parse(e.at);
105
106
  const dispatches = new Map();
106
107
  for (const e of entries) if (e.k === 'dispatch' && e.id && !dispatches.has(e.id)) dispatches.set(e.id, e);