@treenity/mods 3.0.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 (486) hide show
  1. package/board/board.test.ts +212 -0
  2. package/board/client.ts +1 -0
  3. package/board/seed.ts +26 -0
  4. package/board/server.ts +5 -0
  5. package/board/types.ts +87 -0
  6. package/board/view.tsx +574 -0
  7. package/brahman/CLAUDE.md +18 -0
  8. package/brahman/brahman.test.ts +855 -0
  9. package/brahman/client.ts +2 -0
  10. package/brahman/helpers.ts +374 -0
  11. package/brahman/server.ts +2 -0
  12. package/brahman/service.ts +328 -0
  13. package/brahman/types.ts +727 -0
  14. package/brahman/view.tsx +73 -0
  15. package/brahman/views/action-cards.tsx +615 -0
  16. package/brahman/views/bot-view.tsx +76 -0
  17. package/brahman/views/chat-editor.tsx +782 -0
  18. package/brahman/views/chat-preview.tsx +266 -0
  19. package/brahman/views/menu-editor.tsx +451 -0
  20. package/brahman/views/page-layout.tsx +285 -0
  21. package/brahman/views/tstring-input.tsx +84 -0
  22. package/cafe/CLAUDE.md +7 -0
  23. package/cafe/seed.ts +8 -0
  24. package/cafe/server.ts +2 -0
  25. package/cafe/types.ts +32 -0
  26. package/canary/seed.ts +8 -0
  27. package/canary/server.ts +3 -0
  28. package/canary/service.ts +101 -0
  29. package/canary/types.ts +16 -0
  30. package/dist/board/client.d.ts +2 -0
  31. package/dist/board/client.d.ts.map +1 -0
  32. package/dist/board/client.js +2 -0
  33. package/dist/board/client.js.map +1 -0
  34. package/dist/board/seed.d.ts +2 -0
  35. package/dist/board/seed.d.ts.map +1 -0
  36. package/dist/board/seed.js +23 -0
  37. package/dist/board/seed.js.map +1 -0
  38. package/dist/board/server.d.ts +3 -0
  39. package/dist/board/server.d.ts.map +1 -0
  40. package/dist/board/server.js +5 -0
  41. package/dist/board/server.js.map +1 -0
  42. package/dist/board/types.d.ts +45 -0
  43. package/dist/board/types.d.ts.map +1 -0
  44. package/dist/board/types.js +82 -0
  45. package/dist/board/types.js.map +1 -0
  46. package/dist/board/view.d.ts +2 -0
  47. package/dist/board/view.d.ts.map +1 -0
  48. package/dist/board/view.js +254 -0
  49. package/dist/board/view.js.map +1 -0
  50. package/dist/brahman/client.d.ts +3 -0
  51. package/dist/brahman/client.d.ts.map +1 -0
  52. package/dist/brahman/client.js +3 -0
  53. package/dist/brahman/client.js.map +1 -0
  54. package/dist/brahman/helpers.d.ts +51 -0
  55. package/dist/brahman/helpers.d.ts.map +1 -0
  56. package/dist/brahman/helpers.js +321 -0
  57. package/dist/brahman/helpers.js.map +1 -0
  58. package/dist/brahman/server.d.ts +3 -0
  59. package/dist/brahman/server.d.ts.map +1 -0
  60. package/dist/brahman/server.js +3 -0
  61. package/dist/brahman/server.js.map +1 -0
  62. package/dist/brahman/service.d.ts +2 -0
  63. package/dist/brahman/service.d.ts.map +1 -0
  64. package/dist/brahman/service.js +310 -0
  65. package/dist/brahman/service.js.map +1 -0
  66. package/dist/brahman/types.d.ts +335 -0
  67. package/dist/brahman/types.d.ts.map +1 -0
  68. package/dist/brahman/types.js +633 -0
  69. package/dist/brahman/types.js.map +1 -0
  70. package/dist/brahman/view.d.ts +2 -0
  71. package/dist/brahman/view.d.ts.map +1 -0
  72. package/dist/brahman/view.js +47 -0
  73. package/dist/brahman/view.js.map +1 -0
  74. package/dist/brahman/views/action-cards.d.ts +60 -0
  75. package/dist/brahman/views/action-cards.d.ts.map +1 -0
  76. package/dist/brahman/views/action-cards.js +283 -0
  77. package/dist/brahman/views/action-cards.js.map +1 -0
  78. package/dist/brahman/views/bot-view.d.ts +5 -0
  79. package/dist/brahman/views/bot-view.d.ts.map +1 -0
  80. package/dist/brahman/views/bot-view.js +14 -0
  81. package/dist/brahman/views/bot-view.js.map +1 -0
  82. package/dist/brahman/views/chat-editor.d.ts +5 -0
  83. package/dist/brahman/views/chat-editor.d.ts.map +1 -0
  84. package/dist/brahman/views/chat-editor.js +306 -0
  85. package/dist/brahman/views/chat-editor.js.map +1 -0
  86. package/dist/brahman/views/chat-preview.d.ts +5 -0
  87. package/dist/brahman/views/chat-preview.d.ts.map +1 -0
  88. package/dist/brahman/views/chat-preview.js +145 -0
  89. package/dist/brahman/views/chat-preview.js.map +1 -0
  90. package/dist/brahman/views/menu-editor.d.ts +11 -0
  91. package/dist/brahman/views/menu-editor.d.ts.map +1 -0
  92. package/dist/brahman/views/menu-editor.js +171 -0
  93. package/dist/brahman/views/menu-editor.js.map +1 -0
  94. package/dist/brahman/views/page-layout.d.ts +5 -0
  95. package/dist/brahman/views/page-layout.d.ts.map +1 -0
  96. package/dist/brahman/views/page-layout.js +114 -0
  97. package/dist/brahman/views/page-layout.js.map +1 -0
  98. package/dist/brahman/views/tstring-input.d.ts +15 -0
  99. package/dist/brahman/views/tstring-input.d.ts.map +1 -0
  100. package/dist/brahman/views/tstring-input.js +23 -0
  101. package/dist/brahman/views/tstring-input.js.map +1 -0
  102. package/dist/cafe/seed.d.ts +2 -0
  103. package/dist/cafe/seed.d.ts.map +1 -0
  104. package/dist/cafe/seed.js +7 -0
  105. package/dist/cafe/seed.js.map +1 -0
  106. package/dist/cafe/server.d.ts +3 -0
  107. package/dist/cafe/server.d.ts.map +1 -0
  108. package/dist/cafe/server.js +3 -0
  109. package/dist/cafe/server.js.map +1 -0
  110. package/dist/cafe/types.d.ts +2 -0
  111. package/dist/cafe/types.d.ts.map +1 -0
  112. package/dist/cafe/types.js +31 -0
  113. package/dist/cafe/types.js.map +1 -0
  114. package/dist/canary/seed.d.ts +2 -0
  115. package/dist/canary/seed.d.ts.map +1 -0
  116. package/dist/canary/seed.js +7 -0
  117. package/dist/canary/seed.js.map +1 -0
  118. package/dist/canary/server.d.ts +4 -0
  119. package/dist/canary/server.d.ts.map +1 -0
  120. package/dist/canary/server.js +4 -0
  121. package/dist/canary/server.js.map +1 -0
  122. package/dist/canary/service.d.ts +2 -0
  123. package/dist/canary/service.d.ts.map +1 -0
  124. package/dist/canary/service.js +101 -0
  125. package/dist/canary/service.js.map +1 -0
  126. package/dist/canary/types.d.ts +9 -0
  127. package/dist/canary/types.d.ts.map +1 -0
  128. package/dist/canary/types.js +13 -0
  129. package/dist/canary/types.js.map +1 -0
  130. package/dist/doc/client.d.ts +3 -0
  131. package/dist/doc/client.d.ts.map +1 -0
  132. package/dist/doc/client.js +5 -0
  133. package/dist/doc/client.js.map +1 -0
  134. package/dist/doc/fs-codec.d.ts +2 -0
  135. package/dist/doc/fs-codec.d.ts.map +1 -0
  136. package/dist/doc/fs-codec.js +44 -0
  137. package/dist/doc/fs-codec.js.map +1 -0
  138. package/dist/doc/markdown.d.ts +13 -0
  139. package/dist/doc/markdown.d.ts.map +1 -0
  140. package/dist/doc/markdown.js +250 -0
  141. package/dist/doc/markdown.js.map +1 -0
  142. package/dist/doc/prefab.d.ts +2 -0
  143. package/dist/doc/prefab.d.ts.map +1 -0
  144. package/dist/doc/prefab.js +23 -0
  145. package/dist/doc/prefab.js.map +1 -0
  146. package/dist/doc/renderers.d.ts +2 -0
  147. package/dist/doc/renderers.d.ts.map +1 -0
  148. package/dist/doc/renderers.js +94 -0
  149. package/dist/doc/renderers.js.map +1 -0
  150. package/dist/doc/seed.d.ts +2 -0
  151. package/dist/doc/seed.d.ts.map +1 -0
  152. package/dist/doc/seed.js +9 -0
  153. package/dist/doc/seed.js.map +1 -0
  154. package/dist/doc/server.d.ts +6 -0
  155. package/dist/doc/server.d.ts.map +1 -0
  156. package/dist/doc/server.js +6 -0
  157. package/dist/doc/server.js.map +1 -0
  158. package/dist/doc/slash-command.d.ts +3 -0
  159. package/dist/doc/slash-command.d.ts.map +1 -0
  160. package/dist/doc/slash-command.js +123 -0
  161. package/dist/doc/slash-command.js.map +1 -0
  162. package/dist/doc/slash-menu.d.ts +15 -0
  163. package/dist/doc/slash-menu.d.ts.map +1 -0
  164. package/dist/doc/slash-menu.js +54 -0
  165. package/dist/doc/slash-menu.js.map +1 -0
  166. package/dist/doc/text.d.ts +2 -0
  167. package/dist/doc/text.d.ts.map +1 -0
  168. package/dist/doc/text.js +22 -0
  169. package/dist/doc/text.js.map +1 -0
  170. package/dist/doc/toolbar.d.ts +5 -0
  171. package/dist/doc/toolbar.d.ts.map +1 -0
  172. package/dist/doc/toolbar.js +15 -0
  173. package/dist/doc/toolbar.js.map +1 -0
  174. package/dist/doc/treenity-block-view.d.ts +2 -0
  175. package/dist/doc/treenity-block-view.d.ts.map +1 -0
  176. package/dist/doc/treenity-block-view.js +37 -0
  177. package/dist/doc/treenity-block-view.js.map +1 -0
  178. package/dist/doc/treenity-block.d.ts +3 -0
  179. package/dist/doc/treenity-block.d.ts.map +1 -0
  180. package/dist/doc/treenity-block.js +27 -0
  181. package/dist/doc/treenity-block.js.map +1 -0
  182. package/dist/doc/types.d.ts +2 -0
  183. package/dist/doc/types.d.ts.map +1 -0
  184. package/dist/doc/types.js +10 -0
  185. package/dist/doc/types.js.map +1 -0
  186. package/dist/launcher/client.d.ts +5 -0
  187. package/dist/launcher/client.d.ts.map +1 -0
  188. package/dist/launcher/client.js +5 -0
  189. package/dist/launcher/client.js.map +1 -0
  190. package/dist/launcher/icons.d.ts +2 -0
  191. package/dist/launcher/icons.d.ts.map +1 -0
  192. package/dist/launcher/icons.js +57 -0
  193. package/dist/launcher/icons.js.map +1 -0
  194. package/dist/launcher/seed.d.ts +2 -0
  195. package/dist/launcher/seed.d.ts.map +1 -0
  196. package/dist/launcher/seed.js +36 -0
  197. package/dist/launcher/seed.js.map +1 -0
  198. package/dist/launcher/server.d.ts +3 -0
  199. package/dist/launcher/server.d.ts.map +1 -0
  200. package/dist/launcher/server.js +3 -0
  201. package/dist/launcher/server.js.map +1 -0
  202. package/dist/launcher/types.d.ts +21 -0
  203. package/dist/launcher/types.d.ts.map +1 -0
  204. package/dist/launcher/types.js +47 -0
  205. package/dist/launcher/types.js.map +1 -0
  206. package/dist/launcher/view.d.ts +2 -0
  207. package/dist/launcher/view.d.ts.map +1 -0
  208. package/dist/launcher/view.js +187 -0
  209. package/dist/launcher/view.js.map +1 -0
  210. package/dist/launcher/widgets.d.ts +2 -0
  211. package/dist/launcher/widgets.d.ts.map +1 -0
  212. package/dist/launcher/widgets.js +73 -0
  213. package/dist/launcher/widgets.js.map +1 -0
  214. package/dist/mindmap/branch.d.ts +17 -0
  215. package/dist/mindmap/branch.d.ts.map +1 -0
  216. package/dist/mindmap/branch.js +47 -0
  217. package/dist/mindmap/branch.js.map +1 -0
  218. package/dist/mindmap/client.d.ts +3 -0
  219. package/dist/mindmap/client.d.ts.map +1 -0
  220. package/dist/mindmap/client.js +3 -0
  221. package/dist/mindmap/client.js.map +1 -0
  222. package/dist/mindmap/radial-tree.d.ts +14 -0
  223. package/dist/mindmap/radial-tree.d.ts.map +1 -0
  224. package/dist/mindmap/radial-tree.js +184 -0
  225. package/dist/mindmap/radial-tree.js.map +1 -0
  226. package/dist/mindmap/sidebar.d.ts +8 -0
  227. package/dist/mindmap/sidebar.d.ts.map +1 -0
  228. package/dist/mindmap/sidebar.js +24 -0
  229. package/dist/mindmap/sidebar.js.map +1 -0
  230. package/dist/mindmap/types.d.ts +8 -0
  231. package/dist/mindmap/types.d.ts.map +1 -0
  232. package/dist/mindmap/types.js +10 -0
  233. package/dist/mindmap/types.js.map +1 -0
  234. package/dist/mindmap/use-tree-data.d.ts +14 -0
  235. package/dist/mindmap/use-tree-data.d.ts.map +1 -0
  236. package/dist/mindmap/use-tree-data.js +95 -0
  237. package/dist/mindmap/use-tree-data.js.map +1 -0
  238. package/dist/mindmap/view.d.ts +3 -0
  239. package/dist/mindmap/view.d.ts.map +1 -0
  240. package/dist/mindmap/view.js +141 -0
  241. package/dist/mindmap/view.js.map +1 -0
  242. package/dist/sensor-demo/client.d.ts +2 -0
  243. package/dist/sensor-demo/client.d.ts.map +1 -0
  244. package/dist/sensor-demo/client.js +2 -0
  245. package/dist/sensor-demo/client.js.map +1 -0
  246. package/dist/sensor-demo/server.d.ts +2 -0
  247. package/dist/sensor-demo/server.d.ts.map +1 -0
  248. package/dist/sensor-demo/server.js +2 -0
  249. package/dist/sensor-demo/server.js.map +1 -0
  250. package/dist/sensor-demo/service.d.ts +2 -0
  251. package/dist/sensor-demo/service.d.ts.map +1 -0
  252. package/dist/sensor-demo/service.js +27 -0
  253. package/dist/sensor-demo/service.js.map +1 -0
  254. package/dist/sensor-demo/types.d.ts +15 -0
  255. package/dist/sensor-demo/types.d.ts.map +1 -0
  256. package/dist/sensor-demo/types.js +18 -0
  257. package/dist/sensor-demo/types.js.map +1 -0
  258. package/dist/sensor-demo/view.d.ts +2 -0
  259. package/dist/sensor-demo/view.d.ts.map +1 -0
  260. package/dist/sensor-demo/view.js +33 -0
  261. package/dist/sensor-demo/view.js.map +1 -0
  262. package/dist/sensor-generator/action.d.ts +2 -0
  263. package/dist/sensor-generator/action.d.ts.map +1 -0
  264. package/dist/sensor-generator/action.js +23 -0
  265. package/dist/sensor-generator/action.js.map +1 -0
  266. package/dist/sensor-generator/client.d.ts +2 -0
  267. package/dist/sensor-generator/client.d.ts.map +1 -0
  268. package/dist/sensor-generator/client.js +2 -0
  269. package/dist/sensor-generator/client.js.map +1 -0
  270. package/dist/sensor-generator/server.d.ts +2 -0
  271. package/dist/sensor-generator/server.d.ts.map +1 -0
  272. package/dist/sensor-generator/server.js +2 -0
  273. package/dist/sensor-generator/server.js.map +1 -0
  274. package/dist/sensor-generator/view.d.ts +2 -0
  275. package/dist/sensor-generator/view.d.ts.map +1 -0
  276. package/dist/sensor-generator/view.js +64 -0
  277. package/dist/sensor-generator/view.js.map +1 -0
  278. package/dist/sim/client.d.ts +2 -0
  279. package/dist/sim/client.d.ts.map +1 -0
  280. package/dist/sim/client.js +2 -0
  281. package/dist/sim/client.js.map +1 -0
  282. package/dist/sim/seed.d.ts +2 -0
  283. package/dist/sim/seed.d.ts.map +1 -0
  284. package/dist/sim/seed.js +50 -0
  285. package/dist/sim/seed.js.map +1 -0
  286. package/dist/sim/server.d.ts +3 -0
  287. package/dist/sim/server.d.ts.map +1 -0
  288. package/dist/sim/server.js +3 -0
  289. package/dist/sim/server.js.map +1 -0
  290. package/dist/sim/service.d.ts +4 -0
  291. package/dist/sim/service.d.ts.map +1 -0
  292. package/dist/sim/service.js +528 -0
  293. package/dist/sim/service.js.map +1 -0
  294. package/dist/sim/types.d.ts +63 -0
  295. package/dist/sim/types.d.ts.map +1 -0
  296. package/dist/sim/types.js +57 -0
  297. package/dist/sim/types.js.map +1 -0
  298. package/dist/sim/view.d.ts +2 -0
  299. package/dist/sim/view.d.ts.map +1 -0
  300. package/dist/sim/view.js +205 -0
  301. package/dist/sim/view.js.map +1 -0
  302. package/dist/table/client.d.ts +4 -0
  303. package/dist/table/client.d.ts.map +1 -0
  304. package/dist/table/client.js +4 -0
  305. package/dist/table/client.js.map +1 -0
  306. package/dist/table/edit.d.ts +2 -0
  307. package/dist/table/edit.d.ts.map +1 -0
  308. package/dist/table/edit.js +115 -0
  309. package/dist/table/edit.js.map +1 -0
  310. package/dist/table/server.d.ts +2 -0
  311. package/dist/table/server.d.ts.map +1 -0
  312. package/dist/table/server.js +2 -0
  313. package/dist/table/server.js.map +1 -0
  314. package/dist/table/types.d.ts +18 -0
  315. package/dist/table/types.d.ts.map +1 -0
  316. package/dist/table/types.js +13 -0
  317. package/dist/table/types.js.map +1 -0
  318. package/dist/table/use-debounced-sync.d.ts +8 -0
  319. package/dist/table/use-debounced-sync.d.ts.map +1 -0
  320. package/dist/table/use-debounced-sync.js +56 -0
  321. package/dist/table/use-debounced-sync.js.map +1 -0
  322. package/dist/table/view.d.ts +2 -0
  323. package/dist/table/view.d.ts.map +1 -0
  324. package/dist/table/view.js +199 -0
  325. package/dist/table/view.js.map +1 -0
  326. package/dist/tasks/server.d.ts +2 -0
  327. package/dist/tasks/server.d.ts.map +1 -0
  328. package/dist/tasks/server.js +2 -0
  329. package/dist/tasks/server.js.map +1 -0
  330. package/dist/tasks/types.d.ts +22 -0
  331. package/dist/tasks/types.d.ts.map +1 -0
  332. package/dist/tasks/types.js +34 -0
  333. package/dist/tasks/types.js.map +1 -0
  334. package/dist/three/client.d.ts +2 -0
  335. package/dist/three/client.d.ts.map +1 -0
  336. package/dist/three/client.js +2 -0
  337. package/dist/three/client.js.map +1 -0
  338. package/dist/three/seed.d.ts +2 -0
  339. package/dist/three/seed.d.ts.map +1 -0
  340. package/dist/three/seed.js +45 -0
  341. package/dist/three/seed.js.map +1 -0
  342. package/dist/three/server.d.ts +3 -0
  343. package/dist/three/server.d.ts.map +1 -0
  344. package/dist/three/server.js +3 -0
  345. package/dist/three/server.js.map +1 -0
  346. package/dist/three/types.d.ts +178 -0
  347. package/dist/three/types.d.ts.map +1 -0
  348. package/dist/three/types.js +209 -0
  349. package/dist/three/types.js.map +1 -0
  350. package/dist/three/view.d.ts +2 -0
  351. package/dist/three/view.d.ts.map +1 -0
  352. package/dist/three/view.js +307 -0
  353. package/dist/three/view.js.map +1 -0
  354. package/dist/todo/client.d.ts +3 -0
  355. package/dist/todo/client.d.ts.map +1 -0
  356. package/dist/todo/client.js +3 -0
  357. package/dist/todo/client.js.map +1 -0
  358. package/dist/todo/seed.d.ts +2 -0
  359. package/dist/todo/seed.d.ts.map +1 -0
  360. package/dist/todo/seed.js +8 -0
  361. package/dist/todo/seed.js.map +1 -0
  362. package/dist/todo/server.d.ts +3 -0
  363. package/dist/todo/server.d.ts.map +1 -0
  364. package/dist/todo/server.js +3 -0
  365. package/dist/todo/server.js.map +1 -0
  366. package/dist/todo/types.d.ts +15 -0
  367. package/dist/todo/types.d.ts.map +1 -0
  368. package/dist/todo/types.js +29 -0
  369. package/dist/todo/types.js.map +1 -0
  370. package/dist/todo/view.d.ts +2 -0
  371. package/dist/todo/view.d.ts.map +1 -0
  372. package/dist/todo/view.js +27 -0
  373. package/dist/todo/view.js.map +1 -0
  374. package/dist/whisper/client.d.ts +2 -0
  375. package/dist/whisper/client.d.ts.map +1 -0
  376. package/dist/whisper/client.js +2 -0
  377. package/dist/whisper/client.js.map +1 -0
  378. package/dist/whisper/inbox.d.ts +2 -0
  379. package/dist/whisper/inbox.d.ts.map +1 -0
  380. package/dist/whisper/inbox.js +50 -0
  381. package/dist/whisper/inbox.js.map +1 -0
  382. package/dist/whisper/route.d.ts +10 -0
  383. package/dist/whisper/route.d.ts.map +1 -0
  384. package/dist/whisper/route.js +154 -0
  385. package/dist/whisper/route.js.map +1 -0
  386. package/dist/whisper/seed.d.ts +2 -0
  387. package/dist/whisper/seed.d.ts.map +1 -0
  388. package/dist/whisper/seed.js +14 -0
  389. package/dist/whisper/seed.js.map +1 -0
  390. package/dist/whisper/server.d.ts +5 -0
  391. package/dist/whisper/server.d.ts.map +1 -0
  392. package/dist/whisper/server.js +5 -0
  393. package/dist/whisper/server.js.map +1 -0
  394. package/dist/whisper/service.d.ts +2 -0
  395. package/dist/whisper/service.d.ts.map +1 -0
  396. package/dist/whisper/service.js +26 -0
  397. package/dist/whisper/service.js.map +1 -0
  398. package/dist/whisper/types.d.ts +38 -0
  399. package/dist/whisper/types.d.ts.map +1 -0
  400. package/dist/whisper/types.js +45 -0
  401. package/dist/whisper/types.js.map +1 -0
  402. package/dist/whisper/view.d.ts +2 -0
  403. package/dist/whisper/view.d.ts.map +1 -0
  404. package/dist/whisper/view.js +40 -0
  405. package/dist/whisper/view.js.map +1 -0
  406. package/doc/CLAUDE.md +49 -0
  407. package/doc/client.ts +5 -0
  408. package/doc/editor.css +283 -0
  409. package/doc/fs-codec.test.ts +119 -0
  410. package/doc/fs-codec.ts +50 -0
  411. package/doc/markdown.test.ts +152 -0
  412. package/doc/markdown.ts +284 -0
  413. package/doc/prefab.ts +26 -0
  414. package/doc/renderers.tsx +126 -0
  415. package/doc/seed.ts +10 -0
  416. package/doc/server.ts +5 -0
  417. package/doc/slash-command.ts +136 -0
  418. package/doc/slash-menu.tsx +91 -0
  419. package/doc/text.ts +20 -0
  420. package/doc/toolbar.tsx +86 -0
  421. package/doc/treenity-block-view.tsx +116 -0
  422. package/doc/treenity-block.ts +31 -0
  423. package/doc/types.ts +10 -0
  424. package/launcher/client.ts +4 -0
  425. package/launcher/icons.tsx +234 -0
  426. package/launcher/launcher.css +64 -0
  427. package/launcher/seed.ts +41 -0
  428. package/launcher/server.ts +2 -0
  429. package/launcher/types.ts +53 -0
  430. package/launcher/view.tsx +401 -0
  431. package/launcher/widgets.tsx +171 -0
  432. package/mindmap/branch.tsx +163 -0
  433. package/mindmap/client.ts +2 -0
  434. package/mindmap/mindmap.css +243 -0
  435. package/mindmap/sidebar.tsx +127 -0
  436. package/mindmap/types.ts +10 -0
  437. package/mindmap/view.tsx +247 -0
  438. package/package.json +75 -0
  439. package/sensor-demo/CLAUDE.md +3 -0
  440. package/sensor-demo/client.ts +1 -0
  441. package/sensor-demo/server.ts +1 -0
  442. package/sensor-demo/service.ts +27 -0
  443. package/sensor-demo/types.ts +20 -0
  444. package/sensor-demo/view.tsx +64 -0
  445. package/sensor-generator/CLAUDE.md +3 -0
  446. package/sensor-generator/action.ts +28 -0
  447. package/sensor-generator/client.ts +1 -0
  448. package/sensor-generator/server.ts +1 -0
  449. package/sensor-generator/view.tsx +107 -0
  450. package/sim/CLAUDE.md +16 -0
  451. package/sim/client.ts +1 -0
  452. package/sim/seed.ts +55 -0
  453. package/sim/server.ts +2 -0
  454. package/sim/service.ts +594 -0
  455. package/sim/sim.test.ts +282 -0
  456. package/sim/types.ts +87 -0
  457. package/sim/view.tsx +446 -0
  458. package/table/client.ts +3 -0
  459. package/table/edit.tsx +241 -0
  460. package/table/server.ts +1 -0
  461. package/table/types.ts +22 -0
  462. package/table/use-debounced-sync.ts +67 -0
  463. package/table/view.tsx +339 -0
  464. package/tasks/CLAUDE.md +6 -0
  465. package/tasks/server.ts +1 -0
  466. package/tasks/types.ts +36 -0
  467. package/three/CLAUDE.md +6 -0
  468. package/three/client.ts +1 -0
  469. package/three/seed.ts +54 -0
  470. package/three/server.ts +2 -0
  471. package/three/types.ts +238 -0
  472. package/three/view.tsx +453 -0
  473. package/todo/client.ts +2 -0
  474. package/todo/seed.ts +9 -0
  475. package/todo/server.ts +2 -0
  476. package/todo/types.ts +32 -0
  477. package/todo/view.tsx +67 -0
  478. package/whisper/CLAUDE.md +16 -0
  479. package/whisper/client.ts +1 -0
  480. package/whisper/inbox.ts +54 -0
  481. package/whisper/route.ts +182 -0
  482. package/whisper/seed.ts +15 -0
  483. package/whisper/server.ts +4 -0
  484. package/whisper/service.ts +29 -0
  485. package/whisper/types.ts +51 -0
  486. package/whisper/view.tsx +81 -0
@@ -0,0 +1,247 @@
1
+ // MindMap View — Miro-style horizontal tree with organic curves
2
+ // Each node fetches its own children via useChildren when expanded
3
+
4
+ import { register } from '@treenity/core';
5
+ import type { View } from '@treenity/react/context';
6
+ import { useChildren } from '@treenity/react/hooks';
7
+ import { select } from 'd3-selection';
8
+ import 'd3-transition';
9
+ import { zoom as d3zoom, type ZoomBehavior, zoomIdentity } from 'd3-zoom';
10
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
11
+ import { MindMapBranch, MindMapCtx, type MindMapState } from './branch';
12
+ import { MindMapSidebar } from './sidebar';
13
+ import type { MindMapConfig } from './types';
14
+ import './mindmap.css';
15
+
16
+ const PALETTE = [
17
+ '#6366f1', '#f59e0b', '#10b981', '#ef4444', '#8b5cf6',
18
+ '#06b6d4', '#f97316', '#ec4899', '#14b8a6', '#84cc16',
19
+ ];
20
+
21
+ const LEVEL_W = 200;
22
+ const SPACING = 36;
23
+
24
+ function sCurve(dx: number, dy: number): string {
25
+ const cx = dx * 0.5;
26
+ return `M0,0 C${cx},0 ${cx},${dy} ${dx},${dy}`;
27
+ }
28
+
29
+ function basename(path: string): string {
30
+ if (path === '/') return '/';
31
+ const i = path.lastIndexOf('/');
32
+ return i < 0 ? path : path.slice(i + 1);
33
+ }
34
+
35
+ const MindMapView: View<MindMapConfig> = ({ value, ctx }) => {
36
+ const rootPath = value.root || ctx?.node?.$path || '/';
37
+ const rootName = basename(rootPath);
38
+
39
+ const [expanded, setExpanded] = useState<Set<string>>(() => new Set([rootPath]));
40
+ const [selectedPath, setSelectedPath] = useState<string | null>(null);
41
+ const containerRef = useRef<HTMLDivElement>(null);
42
+ const svgRef = useRef<SVGSVGElement>(null);
43
+ const gRef = useRef<SVGGElement>(null);
44
+ const zoomRef = useRef<ZoomBehavior<SVGSVGElement, unknown> | null>(null);
45
+ const [dims, setDims] = useState({ w: 800, h: 600 });
46
+
47
+ const rootChildren = useChildren(rootPath, { watch: true, watchNew: true });
48
+
49
+ const left = useMemo(() => rootChildren.filter((_, i) => i % 2 === 1), [rootChildren]);
50
+ const right = useMemo(() => rootChildren.filter((_, i) => i % 2 === 0), [rootChildren]);
51
+
52
+ useEffect(() => {
53
+ if (!containerRef.current) return;
54
+ const ro = new ResizeObserver(entries => {
55
+ const { width, height } = entries[0].contentRect;
56
+ setDims({ w: width, h: height });
57
+ });
58
+ ro.observe(containerRef.current);
59
+ return () => ro.disconnect();
60
+ }, []);
61
+
62
+ useEffect(() => {
63
+ if (!svgRef.current || !gRef.current) return;
64
+ const svg = select(svgRef.current);
65
+ const g = select(gRef.current);
66
+
67
+ const zoomBehavior = d3zoom<SVGSVGElement, unknown>()
68
+ .scaleExtent([0.1, 4])
69
+ .on('zoom', event => g.attr('transform', event.transform.toString()));
70
+
71
+ svg.call(zoomBehavior);
72
+ svg.call(zoomBehavior.transform, zoomIdentity.translate(dims.w / 2, dims.h / 2).scale(0.85));
73
+ zoomRef.current = zoomBehavior;
74
+
75
+ return () => { svg.on('.zoom', null); };
76
+ }, [dims.w, dims.h]);
77
+
78
+ const fitView = useCallback(() => {
79
+ if (!svgRef.current || !zoomRef.current || !gRef.current) return;
80
+ const svg = select(svgRef.current);
81
+ const bounds = gRef.current.getBBox();
82
+ if (!bounds.width || !bounds.height) return;
83
+
84
+ const pad = 60;
85
+ const scale = Math.min((dims.w - pad * 2) / bounds.width, (dims.h - pad * 2) / bounds.height, 1.5);
86
+ const tx = dims.w / 2 - (bounds.x + bounds.width / 2) * scale;
87
+ const ty = dims.h / 2 - (bounds.y + bounds.height / 2) * scale;
88
+
89
+ svg.transition().duration(400).call(
90
+ zoomRef.current.transform,
91
+ zoomIdentity.translate(tx, ty).scale(scale),
92
+ );
93
+ }, [dims.w, dims.h]);
94
+
95
+ const handleToggle = useCallback((path: string) => {
96
+ setExpanded(prev => {
97
+ const next = new Set(prev);
98
+ if (next.has(path)) {
99
+ for (const p of next) {
100
+ if (p === path || p.startsWith(path + '/')) next.delete(p);
101
+ }
102
+ } else {
103
+ next.add(path);
104
+ }
105
+ return next;
106
+ });
107
+ }, []);
108
+
109
+ const handleSelect = useCallback((path: string) => {
110
+ setSelectedPath(prev => prev === path ? null : path);
111
+ }, []);
112
+
113
+ const handleCloseSidebar = useCallback(() => setSelectedPath(null), []);
114
+
115
+ const handleNavigate = useCallback((path: string) => {
116
+ window.history.pushState(null, '', '/t' + path);
117
+ window.dispatchEvent(new PopStateEvent('popstate'));
118
+ }, []);
119
+
120
+ useEffect(() => {
121
+ const handler = (e: KeyboardEvent) => {
122
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;
123
+ if (e.key === 'Enter' && selectedPath) { e.preventDefault(); handleToggle(selectedPath); }
124
+ if (e.key === 'Escape') setSelectedPath(null);
125
+ };
126
+ window.addEventListener('keydown', handler);
127
+ return () => window.removeEventListener('keydown', handler);
128
+ }, [selectedPath, handleToggle]);
129
+
130
+ const mmState: MindMapState = useMemo(
131
+ () => ({ expanded, selectedPath, onToggle: handleToggle, onSelect: handleSelect }),
132
+ [expanded, selectedPath, handleToggle, handleSelect],
133
+ );
134
+
135
+ const svgW = selectedPath ? dims.w - 280 : dims.w;
136
+ const rootW = rootName.length * 10 + 48;
137
+
138
+ return (
139
+ <div className="mm-container" ref={containerRef}>
140
+ <div className="mm-tree-wrap">
141
+ <div className="mm-toolbar">
142
+ <button className="mm-btn" onClick={fitView} title="Fit view">
143
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
144
+ <path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
145
+ </svg>
146
+ </button>
147
+ </div>
148
+
149
+ <svg ref={svgRef} width={svgW} height={dims.h} className="mm-svg">
150
+ <MindMapCtx.Provider value={mmState}>
151
+ <g ref={gRef}>
152
+ {/* Curves from root to right children */}
153
+ {right.map((child, i) => {
154
+ const totalH = (right.length - 1) * SPACING;
155
+ const cy = -totalH / 2 + i * SPACING;
156
+ const color = PALETTE[(i * 2) % PALETTE.length];
157
+ return (
158
+ <path
159
+ key={`link-r-${child.$path}`}
160
+ d={sCurve(LEVEL_W, cy)}
161
+ fill="none"
162
+ stroke={color}
163
+ strokeWidth={3}
164
+ strokeOpacity={0.6}
165
+ strokeLinecap="round"
166
+ className="mm-link"
167
+ />
168
+ );
169
+ })}
170
+
171
+ {/* Curves from root to left children */}
172
+ {left.map((child, i) => {
173
+ const totalH = (left.length - 1) * SPACING;
174
+ const cy = -totalH / 2 + i * SPACING;
175
+ const color = PALETTE[(i * 2 + 1) % PALETTE.length];
176
+ return (
177
+ <path
178
+ key={`link-l-${child.$path}`}
179
+ d={sCurve(-LEVEL_W, cy)}
180
+ fill="none"
181
+ stroke={color}
182
+ strokeWidth={3}
183
+ strokeOpacity={0.6}
184
+ strokeLinecap="round"
185
+ className="mm-link"
186
+ />
187
+ );
188
+ })}
189
+
190
+ {/* Root — pill shape with solid bg */}
191
+ <g
192
+ className={`mm-node mm-root${selectedPath === rootPath ? ' mm-node-selected' : ''}`}
193
+ onClick={() => handleSelect(rootPath)}
194
+ >
195
+ <rect
196
+ x={-rootW / 2}
197
+ y={-20}
198
+ width={rootW}
199
+ height={40}
200
+ rx={20}
201
+ className="mm-root-bg"
202
+ />
203
+ <text textAnchor="middle" dominantBaseline="central" className="mm-root-label">
204
+ {rootName}
205
+ </text>
206
+ </g>
207
+
208
+ {/* Right child nodes */}
209
+ {right.map((child, i) => {
210
+ const totalH = (right.length - 1) * SPACING;
211
+ const cy = -totalH / 2 + i * SPACING;
212
+ const color = PALETTE[(i * 2) % PALETTE.length];
213
+ return (
214
+ <g key={child.$path} transform={`translate(${LEVEL_W},${cy})`}>
215
+ <MindMapBranch node={child} side="right" color={color} depth={1} />
216
+ </g>
217
+ );
218
+ })}
219
+
220
+ {/* Left child nodes */}
221
+ {left.map((child, i) => {
222
+ const totalH = (left.length - 1) * SPACING;
223
+ const cy = -totalH / 2 + i * SPACING;
224
+ const color = PALETTE[(i * 2 + 1) % PALETTE.length];
225
+ return (
226
+ <g key={child.$path} transform={`translate(${-LEVEL_W},${cy})`}>
227
+ <MindMapBranch node={child} side="left" color={color} depth={1} />
228
+ </g>
229
+ );
230
+ })}
231
+ </g>
232
+ </MindMapCtx.Provider>
233
+ </svg>
234
+ </div>
235
+
236
+ {selectedPath && (
237
+ <MindMapSidebar
238
+ path={selectedPath}
239
+ onClose={handleCloseSidebar}
240
+ onNavigate={handleNavigate}
241
+ />
242
+ )}
243
+ </div>
244
+ );
245
+ };
246
+
247
+ register('mindmap.map', 'react', MindMapView);
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@treenity/mods",
3
+ "version": "3.0.1",
4
+ "description": "Official Treenity modules — board, sim, cafe, doc, mindmap, and more.",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "license": "AGPL-3.0",
10
+ "author": "Treenity <hello@treenity.ai> (https://treenity.ai)",
11
+ "homepage": "https://github.com/treenity-ai/treenity",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/treenity-ai/treenity.git",
15
+ "directory": "mods"
16
+ },
17
+ "keywords": [
18
+ "treenity",
19
+ "mods",
20
+ "modules",
21
+ "ecs",
22
+ "composable",
23
+ "ai-native"
24
+ ],
25
+ "exports": {
26
+ "./*": {
27
+ "development": [
28
+ "./*.ts",
29
+ "./*.tsx"
30
+ ],
31
+ "types": [
32
+ "./dist/*.d.ts"
33
+ ],
34
+ "default": [
35
+ "./dist/*.js"
36
+ ]
37
+ }
38
+ },
39
+ "files": [
40
+ "dist",
41
+ "board",
42
+ "brahman",
43
+ "cafe",
44
+ "canary",
45
+ "doc",
46
+ "launcher",
47
+ "mindmap",
48
+ "sensor-demo",
49
+ "sensor-generator",
50
+ "sim",
51
+ "table",
52
+ "tasks",
53
+ "three",
54
+ "todo",
55
+ "whisper",
56
+ "LICENSE"
57
+ ],
58
+ "scripts": {
59
+ "build": "tsc -p tsconfig.build.json",
60
+ "prepack": "npm run build"
61
+ },
62
+ "peerDependencies": {
63
+ "@treenity/core": "^3.0.0",
64
+ "@treenity/react": "^3.0.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "@treenity/react": {
68
+ "optional": true
69
+ }
70
+ },
71
+ "devDependencies": {
72
+ "tsx": "^4.21.0",
73
+ "typescript": "^5.9.3"
74
+ }
75
+ }
@@ -0,0 +1,3 @@
1
+ # sensor-demo
2
+
3
+ Демо живых сенсоров. Сервис генерирует синусоидальные + шумные показания как дочерние ноды каждую секунду, хранит последние 10.
@@ -0,0 +1 @@
1
+ import './view';
@@ -0,0 +1 @@
1
+ import './service';
@@ -0,0 +1,27 @@
1
+ // Sensor demo — generates fake readings every second as children
2
+
3
+ import { createNode, register } from '@treenity/core';
4
+ import '@treenity/core/contexts/service';
5
+ import { SensorReading } from './types';
6
+
7
+ register('examples.demo.sensor', 'service', async (node, ctx) => {
8
+ let seq = 0;
9
+ const MAX = 10;
10
+ const timer = setInterval(async () => {
11
+ const ts = Date.now();
12
+ const name = String(ts).slice(-6).padStart(6, '0');
13
+ await ctx.store.set(createNode(`${node.$path}/${name}`, SensorReading, {
14
+ ts,
15
+ value: +(20 + Math.sin(seq * 0.1) * 5 + Math.random() * 2).toFixed(1),
16
+ seq: seq++,
17
+ }));
18
+ // Trim old readings
19
+ const { items } = await ctx.store.getChildren(node.$path);
20
+ if (items.length > MAX) {
21
+ items.sort((a, b) => (a.ts as number) - (b.ts as number));
22
+ for (const old of items.slice(0, items.length - MAX)) await ctx.store.remove(old.$path);
23
+ }
24
+ }, 1000);
25
+ console.log(`[sensor-demo] started on ${node.$path}`);
26
+ return { stop: async () => clearInterval(timer) };
27
+ });
@@ -0,0 +1,20 @@
1
+ import { registerType } from '@treenity/core/comp';
2
+
3
+ /** @description Fake sensor that generates readings around a base value */
4
+ export class SensorDemo {
5
+ baseValue = 20;
6
+
7
+ /** @description Set the base value around which readings oscillate */
8
+ async setBase(data: { /** Base temperature */ value: number }) {
9
+ this.baseValue = data.value;
10
+ }
11
+ }
12
+ registerType('examples.demo.sensor', SensorDemo);
13
+
14
+ /** @description A single sensor reading data point */
15
+ export class SensorReading {
16
+ ts = 0;
17
+ value = 0;
18
+ seq = 0;
19
+ }
20
+ registerType('examples.demo.sensor.reading', SensorReading);
@@ -0,0 +1,64 @@
1
+ // Sensor feed — live view of last N readings, auto-updates via watchNew
2
+
3
+ import { type NodeData, register } from '@treenity/core';
4
+ import { useChildren } from '@treenity/react/hooks';
5
+
6
+ const MAX = 10;
7
+
8
+ function SensorFeed({ value }: { value: NodeData }) {
9
+ const children = useChildren(value.$path, { watch: true, watchNew: true });
10
+ const last = children.slice(-MAX).reverse();
11
+
12
+ return (
13
+ <div style={{ fontFamily: 'var(--mono)', fontSize: 13 }}>
14
+ <div
15
+ style={{
16
+ fontSize: 11,
17
+ color: 'var(--text-3)',
18
+ textTransform: 'uppercase',
19
+ letterSpacing: 0.5,
20
+ marginBottom: 8,
21
+ }}
22
+ >
23
+ Live sensor feed ({children.length} total)
24
+ </div>
25
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
26
+ {last.map((n, i) => {
27
+ const ts = n.ts as number;
28
+ const val = n.value as number;
29
+ const seq = n.seq as number;
30
+ const time = new Date(ts).toLocaleTimeString();
31
+ const bar = Math.round(((val - 15) / 15) * 20);
32
+ return (
33
+ <div
34
+ key={n.$path}
35
+ style={{
36
+ display: 'flex',
37
+ gap: 8,
38
+ padding: '4px 8px',
39
+ background: i === 0 ? 'var(--accent-bg, rgba(99,102,241,0.15))' : 'var(--surface)',
40
+ borderRadius: 'var(--radius)',
41
+ transition: 'background 0.3s',
42
+ opacity: 1 - i * 0.07,
43
+ }}
44
+ >
45
+ <span style={{ color: 'var(--text-3)', minWidth: 32 }}>#{seq}</span>
46
+ <span style={{ color: 'var(--text-2)', minWidth: 70 }}>{time}</span>
47
+ <span style={{ color: 'var(--accent)', minWidth: 50, textAlign: 'right' }}>
48
+ {val}°
49
+ </span>
50
+ <span style={{ color: 'var(--accent)', opacity: 0.5 }}>
51
+ {'█'.repeat(Math.max(0, bar))}
52
+ </span>
53
+ </div>
54
+ );
55
+ })}
56
+ {last.length === 0 && (
57
+ <div style={{ color: 'var(--text-3)', padding: 8 }}>Waiting for data...</div>
58
+ )}
59
+ </div>
60
+ </div>
61
+ );
62
+ }
63
+
64
+ register('examples.demo.sensor', 'react', SensorFeed as any);
@@ -0,0 +1,3 @@
1
+ # sensor-generator
2
+
3
+ Стриминговый генератор сенсоров по запросу. Generator action выдаёт N показаний по одному с задержкой — демо streaming action паттерна.
@@ -0,0 +1,28 @@
1
+ // Sensor generator demo — on-demand scan that streams N readings via generator action
2
+
3
+ import { type NodeData, register } from '@treenity/core';
4
+ import { type ActionCtx } from '@treenity/core/server/actions';
5
+
6
+ /** @description Stream N sensor readings as a generator, persisting each as a child node */
7
+ register(
8
+ 'examples.demo.generator',
9
+ 'action:scan',
10
+ async function* (ctx: ActionCtx, data: unknown) {
11
+ const count = (data as { count?: number })?.count ?? 10;
12
+ const delay = (data as { delay?: number })?.delay ?? 500;
13
+ for (let i = 0; i < count; i++) {
14
+ if (ctx.signal.aborted) return;
15
+ const ts = Date.now();
16
+ const node = {
17
+ $path: `${ctx.node.$path}/${String(ts).slice(-6)}`,
18
+ $type: 'sensor-reading',
19
+ ts,
20
+ value: +(20 + Math.sin(i * 0.3) * 5 + Math.random() * 2).toFixed(1),
21
+ seq: i,
22
+ } as NodeData;
23
+ await ctx.store.set(node);
24
+ yield node;
25
+ await new Promise((r) => setTimeout(r, delay));
26
+ }
27
+ },
28
+ );
@@ -0,0 +1 @@
1
+ import './view';
@@ -0,0 +1 @@
1
+ import './action';
@@ -0,0 +1,107 @@
1
+ // Sensor generator — on-demand scan, streams results via streamAction subscription
2
+
3
+ import { type NodeData, register } from '@treenity/core';
4
+ import { useCurrentNode } from '@treenity/react/context';
5
+ import { trpc } from '@treenity/react/trpc';
6
+ import { useCallback, useRef, useState } from 'react';
7
+
8
+ function GeneratorDemo() {
9
+ const node = useCurrentNode();
10
+ const [items, setItems] = useState<NodeData[]>([]);
11
+ const [running, setRunning] = useState(false);
12
+ const unsubRef = useRef<(() => void) | null>(null);
13
+
14
+ const scan = useCallback(() => {
15
+ unsubRef.current?.();
16
+ setItems([]);
17
+ setRunning(true);
18
+ const sub = trpc.streamAction.subscribe(
19
+ { path: node.$path, action: 'scan', data: { count: 10, delay: 500 } },
20
+ {
21
+ onData: (item) => {
22
+ const n = item as NodeData;
23
+ if (n?.$path) setItems((prev) => [...prev, n]);
24
+ },
25
+ onComplete: () => setRunning(false),
26
+ onError: () => setRunning(false),
27
+ },
28
+ );
29
+ unsubRef.current = () => sub.unsubscribe();
30
+ }, [node.$path]);
31
+
32
+ const stop = useCallback(() => {
33
+ unsubRef.current?.();
34
+ unsubRef.current = null;
35
+ setRunning(false);
36
+ }, []);
37
+
38
+ return (
39
+ <div style={{ fontFamily: 'var(--mono)', fontSize: 13 }}>
40
+ <div
41
+ style={{
42
+ fontSize: 11,
43
+ color: 'var(--text-3)',
44
+ textTransform: 'uppercase',
45
+ letterSpacing: 0.5,
46
+ marginBottom: 8,
47
+ }}
48
+ >
49
+ Generator scan {running && `(${items.length}/10)`}
50
+ </div>
51
+ <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
52
+ <button
53
+ onClick={running ? stop : scan}
54
+ style={{
55
+ padding: '4px 12px',
56
+ borderRadius: 'var(--radius)',
57
+ border: '1px solid var(--border)',
58
+ background: running ? 'var(--danger, #c44)' : 'var(--accent)',
59
+ color: '#fff',
60
+ cursor: 'pointer',
61
+ fontSize: 12,
62
+ }}
63
+ >
64
+ {running ? 'Stop' : 'Scan'}
65
+ </button>
66
+ </div>
67
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
68
+ {items.map((n, i) => {
69
+ const val = n.value as number;
70
+ const seq = n.seq as number;
71
+ const time = new Date(n.ts as number).toLocaleTimeString();
72
+ const bar = Math.round(((val - 15) / 15) * 20);
73
+ return (
74
+ <div
75
+ key={n.$path}
76
+ style={{
77
+ display: 'flex',
78
+ gap: 8,
79
+ padding: '4px 8px',
80
+ background:
81
+ i === items.length - 1
82
+ ? 'var(--accent-bg, rgba(99,102,241,0.15))'
83
+ : 'var(--surface)',
84
+ borderRadius: 'var(--radius)',
85
+ transition: 'background 0.3s',
86
+ }}
87
+ >
88
+ <span style={{ color: 'var(--text-3)', minWidth: 32 }}>#{seq}</span>
89
+ <span style={{ color: 'var(--text-2)', minWidth: 70 }}>{time}</span>
90
+ <span style={{ color: 'var(--accent)', minWidth: 50, textAlign: 'right' }}>
91
+ {val}°
92
+ </span>
93
+ <span style={{ color: 'var(--accent)', opacity: 0.5 }}>
94
+ {'█'.repeat(Math.max(0, bar))}
95
+ </span>
96
+ </div>
97
+ );
98
+ })}
99
+ {items.length === 0 && !running && (
100
+ <div style={{ color: 'var(--text-3)', padding: 8 }}>Press Scan to generate readings</div>
101
+ )}
102
+ </div>
103
+ </div>
104
+ );
105
+ }
106
+
107
+ register('examples.demo.generator', 'react', GeneratorDemo);
package/sim/CLAUDE.md ADDED
@@ -0,0 +1,16 @@
1
+ # sim
2
+
3
+ Раундовая мульти-агентная LLM-симуляция. Агенты на 2D-карте каждый раунд вызывают Claude (или mock) для speak/move/remember/interact. Actions обнаруживаются из реестра типов — любая нода с `action:*` становится интерактивной.
4
+
5
+ ## Types (8 компонентов)
6
+ - `sim.position` — координаты x, y
7
+ - `sim.descriptive` — имя, описание, appearance
8
+ - `sim.memory` — memories[], reflections[]
9
+ - `sim.config` — world settings (размер, задержка, модель)
10
+ - `sim.round` — номер раунда
11
+ - `sim.events` — лог событий
12
+ - `sim.ai` — AI-настройки агента
13
+ - `sim.nearby` — proximity cache
14
+
15
+ ## Services
16
+ - `sim.world` — раундовый цикл: think → dispatch tools → update state
package/sim/client.ts ADDED
@@ -0,0 +1 @@
1
+ import './view';
package/sim/seed.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { type NodeData } from '@treenity/core';
2
+ import { registerPrefab } from '@treenity/core/mod';
3
+
4
+ registerPrefab('sim', 'seed', [
5
+ { $path: 'sim', $type: 'dir' },
6
+
7
+ { $path: 'sim/world', $type: 'sim.world',
8
+ config: { $type: 'sim.config', width: 600, height: 400, roundDelay: 5000, running: false, model: 'claude-haiku-4-5-20251001' },
9
+ round: { $type: 'sim.round', current: 0, phase: 'idle', log: [] },
10
+ },
11
+
12
+ // Agents
13
+ { $path: 'sim/world/alice', $type: 'sim.agent',
14
+ descriptive: { $type: 'sim.descriptive', name: 'Alice', icon: '\u{1F52C}', description: 'Curious researcher who asks deep questions' },
15
+ ai: { $type: 'sim.ai', systemPrompt: 'You are Alice, a curious researcher. You love asking questions and exploring ideas. You are friendly but intellectually rigorous.' },
16
+ position: { $type: 'sim.position', x: 150, y: 200, radius: 200 },
17
+ memory: { $type: 'sim.memory', entries: [] },
18
+ events: { $type: 'sim.events', entries: [] },
19
+ },
20
+ { $path: 'sim/world/bob', $type: 'sim.agent',
21
+ descriptive: { $type: 'sim.descriptive', name: 'Bob', icon: '\u{1F6E0}', description: 'Practical engineer who builds things' },
22
+ ai: { $type: 'sim.ai', systemPrompt: 'You are Bob, a practical engineer. You focus on building and solving concrete problems. Straightforward and hands-on.' },
23
+ position: { $type: 'sim.position', x: 450, y: 200, radius: 200 },
24
+ memory: { $type: 'sim.memory', entries: [] },
25
+ events: { $type: 'sim.events', entries: [] },
26
+ },
27
+ { $path: 'sim/world/eve', $type: 'sim.agent',
28
+ descriptive: { $type: 'sim.descriptive', name: 'Eve', icon: '\u{1F3A8}', description: 'Creative artist who sees beauty everywhere' },
29
+ ai: { $type: 'sim.ai', systemPrompt: 'You are Eve, a creative artist. You express yourself through metaphors and see connections others miss. Passionate and emotional.' },
30
+ position: { $type: 'sim.position', x: 300, y: 100, radius: 200 },
31
+ memory: { $type: 'sim.memory', entries: [] },
32
+ events: { $type: 'sim.events', entries: [] },
33
+ },
34
+ { $path: 'sim/world/guide', $type: 'sim.agent',
35
+ descriptive: { $type: 'sim.descriptive', name: 'Guide', icon: '\u{1F4D6}', description: 'System narrator who explains how the simulation works' },
36
+ ai: { $type: 'sim.ai', systemPrompt: `You are Guide, the narrator of this simulation. You explain what is happening to observers.
37
+ You know the system: agents live in a 2D world, each has a hearing radius. They act in rounds — everyone thinks in parallel (quorum), then actions execute: speak (heard by nearby agents), move (change position), remember (save to memory).
38
+ Describe the dynamics you observe: who moved where, who spoke, who heard whom. Be concise and insightful, like a nature documentary narrator.` },
39
+ position: { $type: 'sim.position', x: 300, y: 350, radius: 350 },
40
+ memory: { $type: 'sim.memory', entries: [] },
41
+ events: { $type: 'sim.events', entries: [] },
42
+ },
43
+
44
+ // Items
45
+ { $path: 'sim/world/workbench', $type: 'sim.item',
46
+ descriptive: { $type: 'sim.descriptive', name: 'Workbench', icon: '\u{1F527}', description: 'A sturdy workbench with tools. Agents can examine or use it.' },
47
+ position: { $type: 'sim.position', x: 500, y: 350, radius: 80 },
48
+ },
49
+ { $path: 'sim/world/crystal', $type: 'sim.item',
50
+ descriptive: { $type: 'sim.descriptive', name: 'Crystal', icon: '\u{1F48E}', description: 'A mysterious glowing crystal. It hums softly when touched.' },
51
+ position: { $type: 'sim.position', x: 100, y: 350, radius: 60 },
52
+ },
53
+
54
+ { $path: '/sys/autostart/sim', $type: 'ref', $ref: '/sim/world' },
55
+ ] as NodeData[]);
package/sim/server.ts ADDED
@@ -0,0 +1,2 @@
1
+ import './service';
2
+ import './seed';