@treenity/core 1.0.48 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (696) hide show
  1. package/dist/chain.d.ts +20 -0
  2. package/dist/chain.d.ts.map +1 -0
  3. package/dist/chain.js +59 -0
  4. package/dist/chain.js.map +1 -0
  5. package/dist/client/handle.d.ts +13 -0
  6. package/dist/client/handle.d.ts.map +1 -0
  7. package/dist/client/handle.js +46 -0
  8. package/dist/client/handle.js.map +1 -0
  9. package/dist/client/index.d.ts +21 -0
  10. package/dist/client/index.d.ts.map +1 -0
  11. package/dist/client/index.js +5 -0
  12. package/dist/client/index.js.map +1 -0
  13. package/dist/client/trpc.d.ts +13 -0
  14. package/dist/client/trpc.d.ts.map +1 -0
  15. package/dist/client/trpc.js +78 -0
  16. package/dist/client/trpc.js.map +1 -0
  17. package/dist/client.d.ts +2 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +2 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/comp/handle.d.ts +14 -0
  22. package/dist/comp/handle.d.ts.map +1 -0
  23. package/dist/comp/handle.js +21 -0
  24. package/dist/comp/handle.js.map +1 -0
  25. package/dist/comp/index.d.ts +42 -0
  26. package/dist/comp/index.d.ts.map +1 -0
  27. package/dist/comp/index.js +126 -0
  28. package/dist/comp/index.js.map +1 -0
  29. package/dist/comp/needs.d.ts +26 -0
  30. package/dist/comp/needs.d.ts.map +1 -0
  31. package/dist/comp/needs.js +101 -0
  32. package/dist/comp/needs.js.map +1 -0
  33. package/dist/comp/validate.d.ts +13 -0
  34. package/dist/comp/validate.d.ts.map +1 -0
  35. package/dist/comp/validate.js +117 -0
  36. package/dist/comp/validate.js.map +1 -0
  37. package/dist/comp.d.ts +2 -0
  38. package/dist/comp.d.ts.map +1 -0
  39. package/dist/comp.js +2 -0
  40. package/dist/comp.js.map +1 -0
  41. package/dist/contexts/schema/index.d.ts +7 -0
  42. package/dist/contexts/schema/index.d.ts.map +1 -0
  43. package/dist/contexts/schema/index.js +2 -0
  44. package/dist/contexts/schema/index.js.map +1 -0
  45. package/dist/contexts/schema.d.ts +2 -0
  46. package/dist/contexts/schema.d.ts.map +1 -0
  47. package/dist/contexts/schema.js +2 -0
  48. package/dist/contexts/schema.js.map +1 -0
  49. package/dist/contexts/service/index.d.ts +31 -0
  50. package/dist/contexts/service/index.d.ts.map +1 -0
  51. package/dist/contexts/service/index.js +16 -0
  52. package/dist/contexts/service/index.js.map +1 -0
  53. package/dist/contexts/service.d.ts +1 -14
  54. package/dist/contexts/service.d.ts.map +1 -1
  55. package/dist/contexts/service.js +2 -0
  56. package/dist/contexts/service.js.map +1 -0
  57. package/dist/contexts/telegram/index.d.ts +19 -0
  58. package/dist/contexts/telegram/index.d.ts.map +1 -0
  59. package/dist/contexts/telegram/index.js +89 -0
  60. package/dist/contexts/telegram/index.js.map +1 -0
  61. package/dist/contexts/text/index.d.ts +7 -0
  62. package/dist/contexts/text/index.d.ts.map +1 -0
  63. package/dist/contexts/text/index.js +9 -0
  64. package/dist/contexts/text/index.js.map +1 -0
  65. package/dist/contexts/text.d.ts +2 -0
  66. package/dist/contexts/text.d.ts.map +1 -0
  67. package/dist/contexts/text.js +2 -0
  68. package/dist/contexts/text.js.map +1 -0
  69. package/dist/core/component.d.ts +41 -0
  70. package/dist/core/component.d.ts.map +1 -0
  71. package/dist/core/component.js +105 -0
  72. package/dist/core/component.js.map +1 -0
  73. package/dist/core/context.d.ts +5 -0
  74. package/dist/core/context.d.ts.map +1 -0
  75. package/dist/core/context.js +3 -0
  76. package/dist/core/context.js.map +1 -0
  77. package/dist/core/index.d.ts +5 -0
  78. package/dist/core/index.d.ts.map +1 -0
  79. package/dist/core/index.js +8 -0
  80. package/dist/core/index.js.map +1 -0
  81. package/dist/core/path.d.ts +7 -0
  82. package/dist/core/path.d.ts.map +1 -0
  83. package/dist/core/path.js +37 -0
  84. package/dist/core/path.js.map +1 -0
  85. package/dist/core/registry.d.ts +16 -0
  86. package/dist/core/registry.d.ts.map +1 -0
  87. package/dist/core/registry.js +100 -0
  88. package/dist/core/registry.js.map +1 -0
  89. package/dist/core.d.ts +2 -0
  90. package/dist/core.d.ts.map +1 -0
  91. package/dist/core.js +2 -0
  92. package/dist/core.js.map +1 -0
  93. package/dist/log.d.ts +8 -0
  94. package/dist/log.d.ts.map +1 -0
  95. package/dist/log.js +31 -0
  96. package/dist/log.js.map +1 -0
  97. package/dist/mod/discover.d.ts +4 -0
  98. package/dist/mod/discover.d.ts.map +1 -0
  99. package/dist/mod/discover.js +103 -0
  100. package/dist/mod/discover.js.map +1 -0
  101. package/dist/mod/examples/ticker/seed.d.ts +3 -0
  102. package/dist/mod/examples/ticker/seed.d.ts.map +1 -0
  103. package/dist/mod/examples/ticker/seed.js +16 -0
  104. package/dist/mod/examples/ticker/seed.js.map +1 -0
  105. package/dist/mod/examples/ticker/service.d.ts +2 -0
  106. package/dist/mod/examples/ticker/service.d.ts.map +1 -0
  107. package/dist/mod/examples/ticker/service.js +18 -0
  108. package/dist/mod/examples/ticker/service.js.map +1 -0
  109. package/dist/mod/examples/ticker/types.d.ts +16 -0
  110. package/dist/mod/examples/ticker/types.d.ts.map +1 -0
  111. package/dist/mod/examples/ticker/types.js +20 -0
  112. package/dist/mod/examples/ticker/types.js.map +1 -0
  113. package/dist/mod/examples/ticker/view.d.ts +2 -0
  114. package/dist/mod/examples/ticker/view.d.ts.map +1 -0
  115. package/dist/mod/examples/ticker/view.js +10 -0
  116. package/dist/mod/examples/ticker/view.js.map +1 -0
  117. package/dist/mod/index.d.ts +11 -0
  118. package/dist/mod/index.d.ts.map +1 -0
  119. package/dist/mod/index.js +8 -0
  120. package/dist/mod/index.js.map +1 -0
  121. package/dist/mod/loader.d.ts +18 -0
  122. package/dist/mod/loader.d.ts.map +1 -0
  123. package/dist/mod/loader.js +154 -0
  124. package/dist/mod/loader.js.map +1 -0
  125. package/dist/mod/optimistic.d.ts +34 -0
  126. package/dist/mod/optimistic.d.ts.map +1 -0
  127. package/dist/mod/optimistic.js +176 -0
  128. package/dist/mod/optimistic.js.map +1 -0
  129. package/dist/mod/prefab.d.ts +18 -0
  130. package/dist/mod/prefab.d.ts.map +1 -0
  131. package/dist/mod/prefab.js +42 -0
  132. package/dist/mod/prefab.js.map +1 -0
  133. package/dist/mod/tracking.d.ts +8 -0
  134. package/dist/mod/tracking.d.ts.map +1 -0
  135. package/dist/mod/tracking.js +44 -0
  136. package/dist/mod/tracking.js.map +1 -0
  137. package/dist/mod/types.d.ts +31 -0
  138. package/dist/mod/types.d.ts.map +1 -0
  139. package/dist/mod/types.js +5 -0
  140. package/dist/mod/types.js.map +1 -0
  141. package/dist/mod.d.ts +2 -0
  142. package/dist/mod.d.ts.map +1 -0
  143. package/dist/mod.js +2 -0
  144. package/dist/mod.js.map +1 -0
  145. package/dist/mods/autostart/server.d.ts +2 -0
  146. package/dist/mods/autostart/server.d.ts.map +1 -0
  147. package/dist/mods/autostart/server.js +2 -0
  148. package/dist/mods/autostart/server.js.map +1 -0
  149. package/dist/mods/autostart/service.d.ts +14 -0
  150. package/dist/mods/autostart/service.d.ts.map +1 -0
  151. package/dist/mods/autostart/service.js +88 -0
  152. package/dist/mods/autostart/service.js.map +1 -0
  153. package/dist/mods/llm/index.d.ts +13 -0
  154. package/dist/mods/llm/index.d.ts.map +1 -0
  155. package/dist/mods/llm/index.js +43 -0
  156. package/dist/mods/llm/index.js.map +1 -0
  157. package/dist/mods/llm/server.d.ts +2 -0
  158. package/dist/mods/llm/server.d.ts.map +1 -0
  159. package/dist/mods/llm/server.js +2 -0
  160. package/dist/mods/llm/server.js.map +1 -0
  161. package/dist/mods/mcp/server.d.ts +3 -0
  162. package/dist/mods/mcp/server.d.ts.map +1 -0
  163. package/dist/mods/mcp/server.js +3 -0
  164. package/dist/mods/mcp/server.js.map +1 -0
  165. package/dist/mods/mcp/service.d.ts +2 -0
  166. package/dist/mods/mcp/service.d.ts.map +1 -0
  167. package/dist/mods/mcp/service.js +17 -0
  168. package/dist/mods/mcp/service.js.map +1 -0
  169. package/dist/mods/mcp/types.d.ts +5 -0
  170. package/dist/mods/mcp/types.d.ts.map +1 -0
  171. package/dist/mods/mcp/types.js +7 -0
  172. package/dist/mods/mcp/types.js.map +1 -0
  173. package/dist/mods/treenity/agent-port.d.ts +2 -0
  174. package/dist/mods/treenity/agent-port.d.ts.map +1 -0
  175. package/dist/mods/treenity/agent-port.js +76 -0
  176. package/dist/mods/treenity/agent-port.js.map +1 -0
  177. package/dist/mods/treenity/groups.d.ts +2 -0
  178. package/dist/mods/treenity/groups.d.ts.map +1 -0
  179. package/dist/mods/treenity/groups.js +18 -0
  180. package/dist/mods/treenity/groups.js.map +1 -0
  181. package/dist/mods/treenity/mod-type.d.ts +2 -0
  182. package/dist/mods/treenity/mod-type.d.ts.map +1 -0
  183. package/dist/mods/treenity/mod-type.js +9 -0
  184. package/dist/mods/treenity/mod-type.js.map +1 -0
  185. package/dist/mods/treenity/seed.d.ts +2 -0
  186. package/dist/mods/treenity/seed.d.ts.map +1 -0
  187. package/dist/mods/treenity/seed.js +53 -0
  188. package/dist/mods/treenity/seed.js.map +1 -0
  189. package/dist/mods/treenity/server.d.ts +5 -0
  190. package/dist/mods/treenity/server.d.ts.map +1 -0
  191. package/dist/mods/treenity/server.js +5 -0
  192. package/dist/mods/treenity/server.js.map +1 -0
  193. package/dist/mods/treenity/system.d.ts +36 -0
  194. package/dist/mods/treenity/system.d.ts.map +1 -0
  195. package/dist/mods/treenity/system.js +61 -0
  196. package/dist/mods/treenity/system.js.map +1 -0
  197. package/dist/mods/uix/client.d.ts +3 -0
  198. package/dist/mods/uix/client.d.ts.map +1 -0
  199. package/dist/mods/uix/client.js +96 -0
  200. package/dist/mods/uix/client.js.map +1 -0
  201. package/dist/mods/uix/compile.d.ts +7 -0
  202. package/dist/mods/uix/compile.d.ts.map +1 -0
  203. package/dist/mods/uix/compile.js +94 -0
  204. package/dist/mods/uix/compile.js.map +1 -0
  205. package/dist/mods/uix/jsx-parser.d.ts +2 -0
  206. package/dist/mods/uix/jsx-parser.d.ts.map +1 -0
  207. package/dist/mods/uix/jsx-parser.js +565 -0
  208. package/dist/mods/uix/jsx-parser.js.map +1 -0
  209. package/dist/mods/uix/verify.d.ts +7 -0
  210. package/dist/mods/uix/verify.d.ts.map +1 -0
  211. package/dist/mods/uix/verify.js +59 -0
  212. package/dist/mods/uix/verify.js.map +1 -0
  213. package/dist/schema/catalog.d.ts +23 -0
  214. package/dist/schema/catalog.d.ts.map +1 -0
  215. package/dist/schema/catalog.js +82 -0
  216. package/dist/schema/catalog.js.map +1 -0
  217. package/dist/schema/extract-schemas.d.ts +5 -0
  218. package/dist/schema/extract-schemas.d.ts.map +1 -0
  219. package/dist/schema/extract-schemas.js +444 -0
  220. package/dist/schema/extract-schemas.js.map +1 -0
  221. package/dist/schema/load.d.ts +2 -0
  222. package/dist/schema/load.d.ts.map +1 -0
  223. package/dist/schema/load.js +23 -0
  224. package/dist/schema/load.js.map +1 -0
  225. package/dist/schema/test-fixture.types.d.ts +2 -0
  226. package/dist/schema/test-fixture.types.d.ts.map +1 -0
  227. package/dist/schema/test-fixture.types.js +19 -0
  228. package/dist/schema/test-fixture.types.js.map +1 -0
  229. package/dist/schema/test-opaque.d.ts +3 -0
  230. package/dist/schema/test-opaque.d.ts.map +1 -0
  231. package/dist/schema/test-opaque.js +43 -0
  232. package/dist/schema/test-opaque.js.map +1 -0
  233. package/dist/schema/types.d.ts +37 -0
  234. package/dist/schema/types.d.ts.map +1 -0
  235. package/dist/schema/types.js +3 -0
  236. package/dist/schema/types.js.map +1 -0
  237. package/dist/server/actions.d.ts +35 -0
  238. package/dist/server/actions.d.ts.map +1 -0
  239. package/dist/server/actions.js +170 -0
  240. package/dist/server/actions.js.map +1 -0
  241. package/dist/server/agent.d.ts +6 -0
  242. package/dist/server/agent.d.ts.map +1 -0
  243. package/dist/server/agent.js +15 -0
  244. package/dist/server/agent.js.map +1 -0
  245. package/dist/server/auth.d.ts +39 -0
  246. package/dist/server/auth.d.ts.map +1 -0
  247. package/dist/server/auth.js +335 -0
  248. package/dist/server/auth.js.map +1 -0
  249. package/dist/server/client.d.ts +183 -0
  250. package/dist/server/client.d.ts.map +1 -0
  251. package/dist/server/client.js +22 -0
  252. package/dist/server/client.js.map +1 -0
  253. package/dist/server/cookies.d.ts +5 -0
  254. package/dist/server/cookies.d.ts.map +1 -0
  255. package/dist/server/cookies.js +24 -0
  256. package/dist/server/cookies.js.map +1 -0
  257. package/dist/server/doc-index.d.ts +38 -0
  258. package/dist/server/doc-index.d.ts.map +1 -0
  259. package/dist/server/doc-index.js +244 -0
  260. package/dist/server/doc-index.js.map +1 -0
  261. package/dist/server/errors.d.ts +7 -0
  262. package/dist/server/errors.d.ts.map +1 -0
  263. package/dist/server/errors.js +11 -0
  264. package/dist/server/errors.js.map +1 -0
  265. package/dist/server/factory.d.ts +23 -0
  266. package/dist/server/factory.d.ts.map +1 -0
  267. package/dist/server/factory.js +70 -0
  268. package/dist/server/factory.js.map +1 -0
  269. package/dist/server/main.d.ts +6 -0
  270. package/dist/server/main.d.ts.map +1 -0
  271. package/dist/server/main.js +45 -0
  272. package/dist/server/main.js.map +1 -0
  273. package/dist/server/mcp.d.ts +5 -0
  274. package/dist/server/mcp.d.ts.map +1 -0
  275. package/dist/server/mcp.js +280 -0
  276. package/dist/server/mcp.js.map +1 -0
  277. package/dist/server/migrate.d.ts +3 -0
  278. package/dist/server/migrate.d.ts.map +1 -0
  279. package/dist/server/migrate.js +56 -0
  280. package/dist/server/migrate.js.map +1 -0
  281. package/dist/server/mod-catalog.d.ts +14 -0
  282. package/dist/server/mod-catalog.d.ts.map +1 -0
  283. package/dist/server/mod-catalog.js +40 -0
  284. package/dist/server/mod-catalog.js.map +1 -0
  285. package/dist/server/mods-mount.d.ts +4 -0
  286. package/dist/server/mods-mount.d.ts.map +1 -0
  287. package/dist/server/mods-mount.js +169 -0
  288. package/dist/server/mods-mount.js.map +1 -0
  289. package/dist/server/mount-adapters.d.ts +9 -0
  290. package/dist/server/mount-adapters.d.ts.map +1 -0
  291. package/dist/server/mount-adapters.js +75 -0
  292. package/dist/server/mount-adapters.js.map +1 -0
  293. package/dist/server/mount.d.ts +3 -0
  294. package/dist/server/mount.d.ts.map +1 -0
  295. package/dist/server/mount.js +195 -0
  296. package/dist/server/mount.js.map +1 -0
  297. package/dist/server/prefab.d.ts +18 -0
  298. package/dist/server/prefab.d.ts.map +1 -0
  299. package/dist/server/prefab.js +70 -0
  300. package/dist/server/prefab.js.map +1 -0
  301. package/dist/server/seed/index.d.ts +6 -0
  302. package/dist/server/seed/index.d.ts.map +1 -0
  303. package/dist/server/seed/index.js +16 -0
  304. package/dist/server/seed/index.js.map +1 -0
  305. package/dist/server/server.d.ts +28 -0
  306. package/dist/server/server.d.ts.map +1 -0
  307. package/dist/server/server.js +117 -0
  308. package/dist/server/server.js.map +1 -0
  309. package/dist/server/sub.d.ts +34 -0
  310. package/dist/server/sub.d.ts.map +1 -0
  311. package/dist/server/sub.js +174 -0
  312. package/dist/server/sub.js.map +1 -0
  313. package/dist/server/trpc.d.ts +192 -0
  314. package/dist/server/trpc.d.ts.map +1 -0
  315. package/dist/server/trpc.js +319 -0
  316. package/dist/server/trpc.js.map +1 -0
  317. package/dist/server/types-mount.d.ts +3 -0
  318. package/dist/server/types-mount.d.ts.map +1 -0
  319. package/dist/server/types-mount.js +144 -0
  320. package/dist/server/types-mount.js.map +1 -0
  321. package/dist/server/validate.d.ts +3 -0
  322. package/dist/server/validate.d.ts.map +1 -0
  323. package/dist/server/validate.js +20 -0
  324. package/dist/server/validate.js.map +1 -0
  325. package/dist/server/volatile.d.ts +11 -0
  326. package/dist/server/volatile.d.ts.map +1 -0
  327. package/dist/server/volatile.js +26 -0
  328. package/dist/server/volatile.js.map +1 -0
  329. package/dist/server/watch.d.ts +23 -0
  330. package/dist/server/watch.d.ts.map +1 -0
  331. package/dist/server/watch.js +178 -0
  332. package/dist/server/watch.js.map +1 -0
  333. package/dist/tree/cache.d.ts +3 -0
  334. package/dist/tree/cache.d.ts.map +1 -0
  335. package/dist/tree/cache.js +48 -0
  336. package/dist/tree/cache.js.map +1 -0
  337. package/dist/tree/fs.d.ts +3 -0
  338. package/dist/tree/fs.d.ts.map +1 -0
  339. package/dist/tree/fs.js +274 -0
  340. package/dist/tree/fs.js.map +1 -0
  341. package/dist/tree/index.d.ts +38 -0
  342. package/dist/tree/index.d.ts.map +1 -0
  343. package/dist/tree/index.js +182 -0
  344. package/dist/tree/index.js.map +1 -0
  345. package/dist/tree/inflight.d.ts +2 -0
  346. package/dist/tree/inflight.d.ts.map +1 -0
  347. package/dist/tree/inflight.js +15 -0
  348. package/dist/tree/inflight.js.map +1 -0
  349. package/dist/tree/json-codec.d.ts +2 -0
  350. package/dist/tree/json-codec.d.ts.map +1 -0
  351. package/dist/tree/json-codec.js +13 -0
  352. package/dist/tree/json-codec.js.map +1 -0
  353. package/dist/tree/mimefs.d.ts +13 -0
  354. package/dist/tree/mimefs.d.ts.map +1 -0
  355. package/dist/tree/mimefs.js +124 -0
  356. package/dist/tree/mimefs.js.map +1 -0
  357. package/dist/tree/mongo.d.ts +5 -0
  358. package/dist/tree/mongo.d.ts.map +1 -0
  359. package/dist/tree/mongo.js +110 -0
  360. package/dist/tree/mongo.js.map +1 -0
  361. package/dist/tree/patch.d.ts +30 -0
  362. package/dist/tree/patch.d.ts.map +1 -0
  363. package/dist/tree/patch.js +112 -0
  364. package/dist/tree/patch.js.map +1 -0
  365. package/dist/tree/query.d.ts +12 -0
  366. package/dist/tree/query.d.ts.map +1 -0
  367. package/dist/tree/query.js +61 -0
  368. package/dist/tree/query.js.map +1 -0
  369. package/dist/tree/repath.d.ts +3 -0
  370. package/dist/tree/repath.d.ts.map +1 -0
  371. package/dist/tree/repath.js +38 -0
  372. package/dist/tree/repath.js.map +1 -0
  373. package/dist/tree-chain.d.ts +18 -0
  374. package/dist/tree-chain.d.ts.map +1 -0
  375. package/dist/tree-chain.js +109 -0
  376. package/dist/tree-chain.js.map +1 -0
  377. package/dist/tree.d.ts +2 -0
  378. package/dist/tree.d.ts.map +1 -0
  379. package/dist/tree.js +2 -0
  380. package/dist/tree.js.map +1 -0
  381. package/dist/uri.d.ts +11 -0
  382. package/dist/uri.d.ts.map +1 -0
  383. package/dist/uri.js +79 -0
  384. package/dist/uri.js.map +1 -0
  385. package/package.json +39 -40
  386. package/src/chain.test.ts +190 -0
  387. package/src/chain.ts +82 -0
  388. package/src/client/client.test.ts +192 -0
  389. package/src/client/handle.ts +53 -0
  390. package/src/client/index.ts +18 -0
  391. package/src/client/trpc.ts +91 -0
  392. package/src/client.ts +1 -0
  393. package/src/comp/CLAUDE.md +14 -0
  394. package/src/comp/handle.ts +36 -0
  395. package/src/comp/index.test.ts +129 -0
  396. package/src/comp/index.ts +175 -0
  397. package/src/comp/needs.test.ts +499 -0
  398. package/src/comp/needs.ts +113 -0
  399. package/src/comp/validate.test.ts +304 -0
  400. package/src/comp/validate.ts +125 -0
  401. package/src/comp.ts +1 -0
  402. package/src/contexts/schema/index.ts +7 -0
  403. package/src/contexts/schema.ts +1 -0
  404. package/src/contexts/service/index.test.ts +323 -0
  405. package/src/contexts/service/index.ts +43 -0
  406. package/src/contexts/service.ts +1 -0
  407. package/src/contexts/telegram/index.ts +115 -0
  408. package/src/contexts/text/index.test.ts +31 -0
  409. package/src/contexts/text/index.ts +18 -0
  410. package/src/contexts/text.ts +1 -0
  411. package/src/core/component.ts +151 -0
  412. package/src/core/context.ts +14 -0
  413. package/src/core/index.test.ts +203 -0
  414. package/src/core/index.ts +9 -0
  415. package/src/core/path.ts +35 -0
  416. package/src/core/registry.ts +115 -0
  417. package/src/core.ts +1 -0
  418. package/src/log.test.ts +70 -0
  419. package/src/log.ts +28 -0
  420. package/src/mod/discover.test.ts +133 -0
  421. package/src/mod/discover.ts +100 -0
  422. package/src/mod/docs/00-index.md +19 -0
  423. package/src/mod/docs/01-primitives.md +38 -0
  424. package/src/mod/docs/02-core-api.md +68 -0
  425. package/src/mod/docs/03-registry.md +30 -0
  426. package/src/mod/docs/04-store.md +62 -0
  427. package/src/mod/docs/05-comp.md +111 -0
  428. package/src/mod/docs/06-actions.md +193 -0
  429. package/src/mod/docs/07-realtime.md +100 -0
  430. package/src/mod/docs/08-services.md +33 -0
  431. package/src/mod/docs/09-mounts.md +43 -0
  432. package/src/mod/docs/10-acl.md +60 -0
  433. package/src/mod/docs/11-server.md +62 -0
  434. package/src/mod/docs/12-conventions.md +65 -0
  435. package/src/mod/docs/13-example.md +132 -0
  436. package/src/mod/docs/14-mod-format.md +304 -0
  437. package/src/mod/docs/15-documenting-types.md +156 -0
  438. package/src/mod/examples/ticker/seed.ts +19 -0
  439. package/src/mod/examples/ticker/service.ts +20 -0
  440. package/src/mod/examples/ticker/ticker.test.ts +18 -0
  441. package/src/mod/examples/ticker/types.ts +22 -0
  442. package/src/mod/examples/ticker/view.tsx +19 -0
  443. package/src/mod/index.ts +12 -0
  444. package/src/mod/loader.test.ts +168 -0
  445. package/src/mod/loader.ts +174 -0
  446. package/src/mod/optimistic.test.ts +446 -0
  447. package/src/mod/optimistic.ts +210 -0
  448. package/src/mod/prefab.ts +62 -0
  449. package/src/mod/tracking.test.ts +59 -0
  450. package/src/mod/tracking.ts +51 -0
  451. package/src/mod/types.ts +40 -0
  452. package/src/mod.ts +1 -0
  453. package/src/mods/autostart/CLAUDE.md +6 -0
  454. package/src/mods/autostart/autostart.test.ts +85 -0
  455. package/src/mods/autostart/server.ts +1 -0
  456. package/src/mods/autostart/service.ts +98 -0
  457. package/src/mods/llm/CLAUDE.md +6 -0
  458. package/src/mods/llm/index.ts +57 -0
  459. package/src/mods/llm/llm.test.ts +109 -0
  460. package/src/mods/llm/server.ts +1 -0
  461. package/src/mods/mcp/CLAUDE.md +6 -0
  462. package/src/mods/mcp/server.ts +2 -0
  463. package/src/mods/mcp/service.ts +19 -0
  464. package/src/mods/mcp/types.ts +7 -0
  465. package/src/mods/treenity/agent-port.ts +93 -0
  466. package/src/mods/treenity/groups.ts +19 -0
  467. package/src/mods/treenity/mod-type.ts +10 -0
  468. package/src/mods/treenity/seed.ts +56 -0
  469. package/src/mods/treenity/server.ts +4 -0
  470. package/src/mods/treenity/system.ts +70 -0
  471. package/src/mods/uix/CLAUDE.md +7 -0
  472. package/src/mods/uix/client.ts +117 -0
  473. package/src/mods/uix/compile.test.ts +228 -0
  474. package/src/mods/uix/compile.ts +110 -0
  475. package/src/mods/uix/jsx-parser.test.ts +554 -0
  476. package/src/mods/uix/jsx-parser.ts +489 -0
  477. package/src/mods/uix/lazy-load.test.ts +261 -0
  478. package/src/mods/uix/uix-repomix.md +3509 -0
  479. package/src/mods/uix/verify.ts +68 -0
  480. package/src/schema/CLAUDE.md +13 -0
  481. package/src/schema/catalog.ts +101 -0
  482. package/src/schema/extract-schemas.test.ts +84 -0
  483. package/src/schema/extract-schemas.ts +462 -0
  484. package/src/schema/generated/autostart.json +44 -0
  485. package/src/schema/generated/board.column.json +25 -0
  486. package/src/schema/generated/board.task.json +147 -0
  487. package/src/schema/generated/brahman.action.back.json +12 -0
  488. package/src/schema/generated/brahman.action.broadcast.json +31 -0
  489. package/src/schema/generated/brahman.action.call.json +57 -0
  490. package/src/schema/generated/brahman.action.emittext.json +23 -0
  491. package/src/schema/generated/brahman.action.eval.json +23 -0
  492. package/src/schema/generated/brahman.action.file.json +28 -0
  493. package/src/schema/generated/brahman.action.forward.json +29 -0
  494. package/src/schema/generated/brahman.action.getvalue.json +28 -0
  495. package/src/schema/generated/brahman.action.ifelse.json +42 -0
  496. package/src/schema/generated/brahman.action.keywordselect.json +46 -0
  497. package/src/schema/generated/brahman.action.message.json +127 -0
  498. package/src/schema/generated/brahman.action.onerror.json +29 -0
  499. package/src/schema/generated/brahman.action.page.json +22 -0
  500. package/src/schema/generated/brahman.action.params.json +36 -0
  501. package/src/schema/generated/brahman.action.question.json +43 -0
  502. package/src/schema/generated/brahman.action.remove.json +12 -0
  503. package/src/schema/generated/brahman.action.resethistory.json +12 -0
  504. package/src/schema/generated/brahman.action.resetsession.json +12 -0
  505. package/src/schema/generated/brahman.action.selectlang.json +20 -0
  506. package/src/schema/generated/brahman.action.setvalue.json +27 -0
  507. package/src/schema/generated/brahman.action.tag.json +27 -0
  508. package/src/schema/generated/brahman.bot.json +68 -0
  509. package/src/schema/generated/brahman.page.json +25 -0
  510. package/src/schema/generated/brahman.session.json +29 -0
  511. package/src/schema/generated/brahman.user.json +58 -0
  512. package/src/schema/generated/cafe.contact.json +56 -0
  513. package/src/schema/generated/cafe.mail.json +29 -0
  514. package/src/schema/generated/default.json +15 -0
  515. package/src/schema/generated/doc.page.json +23 -0
  516. package/src/schema/generated/examples.demo.generator.json +16 -0
  517. package/src/schema/generated/examples.demo.sensor.json +35 -0
  518. package/src/schema/generated/groups.json +20 -0
  519. package/src/schema/generated/launcher.json +91 -0
  520. package/src/schema/generated/mcp.server.json +15 -0
  521. package/src/schema/generated/mindmap.map.json +22 -0
  522. package/src/schema/generated/sim.agent.json +24 -0
  523. package/src/schema/generated/sim.ai.json +24 -0
  524. package/src/schema/generated/sim.config.json +38 -0
  525. package/src/schema/generated/sim.descriptive.json +26 -0
  526. package/src/schema/generated/sim.events.json +47 -0
  527. package/src/schema/generated/sim.item.json +20 -0
  528. package/src/schema/generated/sim.memory.json +17 -0
  529. package/src/schema/generated/sim.nearby.json +17 -0
  530. package/src/schema/generated/sim.position.json +25 -0
  531. package/src/schema/generated/sim.round.json +64 -0
  532. package/src/schema/generated/sim.world.json +32 -0
  533. package/src/schema/generated/t.agent.port.json +74 -0
  534. package/src/schema/generated/t.llm.json +20 -0
  535. package/src/schema/generated/t.mod.json +27 -0
  536. package/src/schema/generated/t3d.animator.json +46 -0
  537. package/src/schema/generated/t3d.audio.json +58 -0
  538. package/src/schema/generated/t3d.camera.json +50 -0
  539. package/src/schema/generated/t3d.collider.json +84 -0
  540. package/src/schema/generated/t3d.light.json +90 -0
  541. package/src/schema/generated/t3d.line.json +47 -0
  542. package/src/schema/generated/t3d.lod.json +28 -0
  543. package/src/schema/generated/t3d.material.json +131 -0
  544. package/src/schema/generated/t3d.mesh.json +65 -0
  545. package/src/schema/generated/t3d.object.json +64 -0
  546. package/src/schema/generated/t3d.particles.json +109 -0
  547. package/src/schema/generated/t3d.rigidbody.json +81 -0
  548. package/src/schema/generated/t3d.scene.json +7 -0
  549. package/src/schema/generated/t3d.script.json +23 -0
  550. package/src/schema/generated/t3d.text.json +86 -0
  551. package/src/schema/generated/t3d.trail.json +45 -0
  552. package/src/schema/generated/task.json +96 -0
  553. package/src/schema/generated/test.fixture.json +43 -0
  554. package/src/schema/generated/ticker.config.json +43 -0
  555. package/src/schema/generated/ticker.price.json +20 -0
  556. package/src/schema/generated/todo.item.json +25 -0
  557. package/src/schema/generated/todo.list.json +33 -0
  558. package/src/schema/generated/treenity.system.json +259 -0
  559. package/src/schema/generated/whisper.audio.json +25 -0
  560. package/src/schema/generated/whisper.checklist.json +17 -0
  561. package/src/schema/generated/whisper.config.json +30 -0
  562. package/src/schema/generated/whisper.inbox.json +24 -0
  563. package/src/schema/generated/whisper.meta.json +35 -0
  564. package/src/schema/generated/whisper.text.json +16 -0
  565. package/src/schema/load.ts +24 -0
  566. package/src/schema/schema.test.ts +86 -0
  567. package/src/schema/test-fixture.types.ts +21 -0
  568. package/src/schema/test-opaque.ts +42 -0
  569. package/src/schema/types.ts +33 -0
  570. package/src/server/CLAUDE.md +26 -0
  571. package/src/server/actions.test.ts +272 -0
  572. package/src/server/actions.ts +274 -0
  573. package/src/server/agent-sub.test.ts +90 -0
  574. package/src/server/agent.test.ts +305 -0
  575. package/src/server/agent.ts +17 -0
  576. package/src/server/api.test.ts +454 -0
  577. package/src/server/auth.test.ts +441 -0
  578. package/src/server/auth.ts +386 -0
  579. package/src/server/client.ts +24 -0
  580. package/src/server/conditions.test.ts +128 -0
  581. package/src/server/cookies.ts +25 -0
  582. package/src/server/coverage.test.ts +827 -0
  583. package/src/server/doc-index.ts +286 -0
  584. package/src/server/e2e.test.ts +966 -0
  585. package/src/server/errors.ts +11 -0
  586. package/src/server/factory.ts +99 -0
  587. package/src/server/main.ts +56 -0
  588. package/src/server/mcp.ts +326 -0
  589. package/src/server/migrate.test.ts +123 -0
  590. package/src/server/migrate.ts +62 -0
  591. package/src/server/mod-catalog.ts +59 -0
  592. package/src/server/mods-mount.ts +179 -0
  593. package/src/server/mount-adapters.ts +82 -0
  594. package/src/server/mount.parametrized.test.ts +52 -0
  595. package/src/server/mount.query.test.ts +127 -0
  596. package/src/server/mount.test.ts +497 -0
  597. package/src/server/mount.ts +208 -0
  598. package/src/server/prefab.test.ts +415 -0
  599. package/src/server/prefab.ts +104 -0
  600. package/src/server/seed/index.ts +24 -0
  601. package/src/server/server.ts +153 -0
  602. package/src/server/stress.test.ts +844 -0
  603. package/src/server/sub.test.ts +55 -0
  604. package/src/server/sub.ts +224 -0
  605. package/src/server/trpc.ts +369 -0
  606. package/src/server/types-mount.ts +142 -0
  607. package/src/server/validate.test.ts +91 -0
  608. package/src/server/validate.ts +22 -0
  609. package/src/server/volatile.test.ts +140 -0
  610. package/src/server/volatile.ts +32 -0
  611. package/src/server/watch.test.ts +594 -0
  612. package/src/server/watch.ts +202 -0
  613. package/src/server/workflow.test.ts +82 -0
  614. package/src/tree/CLAUDE.md +13 -0
  615. package/src/tree/cache.test.ts +213 -0
  616. package/src/tree/cache.ts +51 -0
  617. package/src/tree/fs.test.ts +247 -0
  618. package/src/tree/fs.ts +251 -0
  619. package/src/tree/index.test.ts +164 -0
  620. package/src/tree/index.ts +216 -0
  621. package/src/tree/inflight.ts +15 -0
  622. package/src/tree/json-codec.ts +16 -0
  623. package/src/tree/mimefs.test.ts +289 -0
  624. package/src/tree/mimefs.ts +142 -0
  625. package/src/tree/mongo.ts +125 -0
  626. package/src/tree/patch.test.ts +192 -0
  627. package/src/tree/patch.ts +133 -0
  628. package/src/tree/query.test.ts +110 -0
  629. package/src/tree/query.ts +70 -0
  630. package/src/tree/repath.test.ts +86 -0
  631. package/src/tree/repath.ts +53 -0
  632. package/src/tree-chain.test.ts +723 -0
  633. package/src/tree-chain.ts +144 -0
  634. package/src/tree.ts +1 -0
  635. package/src/uri.test.ts +86 -0
  636. package/src/uri.ts +82 -0
  637. package/CHANGELOG.md +0 -314
  638. package/README.md +0 -18
  639. package/dist/context.d.ts +0 -41
  640. package/dist/context.d.ts.map +0 -1
  641. package/dist/context.mjs +0 -81
  642. package/dist/context.mjs.map +0 -1
  643. package/dist/contexts/node-engine.d.ts +0 -12
  644. package/dist/contexts/node-engine.d.ts.map +0 -1
  645. package/dist/contexts/node-engine.mjs +0 -7
  646. package/dist/contexts/node-engine.mjs.map +0 -1
  647. package/dist/contexts/noflo/types.d.ts +0 -20
  648. package/dist/contexts/noflo/types.d.ts.map +0 -1
  649. package/dist/contexts/object.d.ts +0 -11
  650. package/dist/contexts/object.d.ts.map +0 -1
  651. package/dist/contexts/object.mjs +0 -15
  652. package/dist/contexts/object.mjs.map +0 -1
  653. package/dist/contexts/proto.d.ts +0 -11
  654. package/dist/contexts/proto.d.ts.map +0 -1
  655. package/dist/contexts/proto.mjs +0 -7
  656. package/dist/contexts/proto.mjs.map +0 -1
  657. package/dist/contexts/react-context.d.ts +0 -21
  658. package/dist/contexts/react-context.d.ts.map +0 -1
  659. package/dist/contexts/react-context.mjs +0 -24
  660. package/dist/contexts/react-context.mjs.map +0 -1
  661. package/dist/contexts/service.mjs +0 -7
  662. package/dist/contexts/service.mjs.map +0 -1
  663. package/dist/get-type-cache.d.ts +0 -2
  664. package/dist/get-type-cache.d.ts.map +0 -1
  665. package/dist/get-type-cache.mjs +0 -7
  666. package/dist/get-type-cache.mjs.map +0 -1
  667. package/dist/index.d.ts +0 -13
  668. package/dist/index.d.ts.map +0 -1
  669. package/dist/index.mjs +0 -10
  670. package/dist/index.mjs.map +0 -1
  671. package/dist/link/link.d.ts +0 -25
  672. package/dist/link/link.d.ts.map +0 -1
  673. package/dist/link/link.mjs +0 -72
  674. package/dist/link/link.mjs.map +0 -1
  675. package/dist/link/link.test.d.ts +0 -2
  676. package/dist/link/link.test.d.ts.map +0 -1
  677. package/dist/loading.d.ts +0 -9
  678. package/dist/loading.d.ts.map +0 -1
  679. package/dist/meta-type.d.ts +0 -58
  680. package/dist/meta-type.d.ts.map +0 -1
  681. package/dist/meta-type.mjs +0 -104
  682. package/dist/meta-type.mjs.map +0 -1
  683. package/dist/meta.d.ts +0 -20
  684. package/dist/meta.d.ts.map +0 -1
  685. package/dist/meta.mjs +0 -16
  686. package/dist/meta.mjs.map +0 -1
  687. package/dist/node/index.d.ts +0 -2
  688. package/dist/node/index.d.ts.map +0 -1
  689. package/dist/node/types.d.ts +0 -37
  690. package/dist/node/types.d.ts.map +0 -1
  691. package/dist/test/context.test.d.ts +0 -2
  692. package/dist/test/context.test.d.ts.map +0 -1
  693. package/dist/types.d.ts +0 -14
  694. package/dist/types.d.ts.map +0 -1
  695. package/dist/types.mjs +0 -16
  696. package/dist/types.mjs.map +0 -1
@@ -0,0 +1,11 @@
1
+ // Domain errors for server operations.
2
+ // Transport-agnostic: tRPC, HTTP, MCP each map these to their own format.
3
+
4
+ export type ErrorCode = 'NOT_FOUND' | 'BAD_REQUEST' | 'CONFLICT' | 'FORBIDDEN';
5
+
6
+ export class OpError extends Error {
7
+ override readonly name = 'OpError';
8
+ constructor(public readonly code: ErrorCode, message: string) {
9
+ super(message);
10
+ }
11
+ }
@@ -0,0 +1,99 @@
1
+ // treenity() — server factory
2
+ // Builds the full pipeline from config, returns a composable server instance.
3
+
4
+ import { type ServiceHandle, startServices } from '#contexts/service/index';
5
+ import { A, createNode, R, S, W } from '#core';
6
+ import { loadLocalMods } from '#mod';
7
+ import { createMemoryTree, type Tree } from '#tree';
8
+ import type { Server } from 'node:http';
9
+ import { createEnsure, type Ensure, seed as defaultSeed } from './seed';
10
+ import { createHttpServer, createPipeline, type Pipeline } from './server';
11
+
12
+ export type TreenityConfig = {
13
+ dataDir?: string;
14
+ modsDir?: string | false;
15
+ seed?: (store: Tree, ensure: Ensure) => Promise<void>;
16
+ autostart?: boolean;
17
+ };
18
+
19
+ export type ListenOpts = {
20
+ host?: string;
21
+ allowedOrigins?: string[];
22
+ staticDir?: string;
23
+ };
24
+
25
+ export type TreenityInstance = Pipeline & {
26
+ stop(): Promise<void>;
27
+ };
28
+
29
+ export type TreenityServer = TreenityInstance & {
30
+ listen(port?: number, opts?: ListenOpts): Promise<Server>;
31
+ };
32
+
33
+ export async function treenity(config?: TreenityConfig): Promise<TreenityServer> {
34
+ const dataDir = config?.dataDir ?? './data';
35
+ const autostart = config?.autostart ?? true;
36
+
37
+ // 1. Load mods
38
+ if (config?.modsDir !== false) {
39
+ const modsDir = config?.modsDir ?? new URL('../mods', import.meta.url).pathname;
40
+ const { loaded, failed } = await loadLocalMods(modsDir, 'server');
41
+ if (failed.length) console.error('failed mods:', failed.map(f => `${f.name}: ${f.error.message}`).join(', '));
42
+ if (loaded.length) console.log(`mods: ${loaded.join(', ')}`);
43
+ }
44
+
45
+ // 2. Bootstrap: root node with overlay(base, work)
46
+ const bootstrap = createMemoryTree();
47
+ const rootNode = createNode('/', 'root', {}, {
48
+ mount: { $type: 't.mount.overlay', layers: ['base', 'work'] },
49
+ base: { $type: 't.mount.fs', root: dataDir + '/base' },
50
+ work: { $type: 't.mount.fs', root: dataDir + '/work' },
51
+ });
52
+ rootNode.$acl = [
53
+ { g: 'public', p: R },
54
+ { g: 'authenticated', p: R | S },
55
+ { g: 'admins', p: R | W | A | S },
56
+ ];
57
+ await bootstrap.set(rootNode);
58
+
59
+ // 3. Build pipeline
60
+ const pipeline = createPipeline(bootstrap);
61
+ const { store, mountable } = pipeline;
62
+
63
+ // 4. Seed
64
+ const seedFn = config?.seed ?? defaultSeed;
65
+ await seedFn(mountable, createEnsure(mountable));
66
+
67
+ // 5. Autostart services
68
+ let serviceHandle: ServiceHandle | null = null;
69
+ if (autostart) {
70
+ serviceHandle = await startServices(store, store.subscribe.bind(store) as import('#contexts/service/index').ServiceCtx['subscribe']);
71
+ }
72
+
73
+ const stop = async () => {
74
+ await serviceHandle?.stop();
75
+ };
76
+
77
+ return {
78
+ store: pipeline.store,
79
+ mountable: pipeline.mountable,
80
+ watcher: pipeline.watcher,
81
+ router: pipeline.router,
82
+ createContext: pipeline.createContext,
83
+ stop,
84
+
85
+ async listen(port = 3211, opts?: ListenOpts) {
86
+ const host = opts?.host ?? '127.0.0.1';
87
+ const server = createHttpServer(pipeline, {
88
+ allowedOrigins: opts?.allowedOrigins,
89
+ staticDir: opts?.staticDir,
90
+ });
91
+ return new Promise<Server>((resolve) => {
92
+ server.listen(port, host, () => {
93
+ console.log(`treenity ${host}:${port}`);
94
+ resolve(server);
95
+ });
96
+ });
97
+ },
98
+ };
99
+ }
@@ -0,0 +1,56 @@
1
+ import 'dotenv/config';
2
+ import { startServices } from '#contexts/service/index';
3
+ import { type NodeData } from '#core';
4
+ import { loadLocalMods } from '#mod';
5
+ import { createMemoryTree } from '#tree';
6
+ import './mount-adapters';
7
+ import { readFile } from 'node:fs/promises';
8
+ import { resolve } from 'node:path';
9
+ import { seed } from './seed';
10
+ import '#schema/load';
11
+ import '#contexts/text/index';
12
+ import '#contexts/schema/index';
13
+ import { createTreenityServer } from './server';
14
+
15
+ // Lock CWD — no library may change it
16
+ process.chdir = () => { throw new Error('process.chdir is forbidden'); };
17
+
18
+ // ── Root config ──
19
+ const rootPath = resolve(process.argv[2] || 'root.json');
20
+ const rootNode = JSON.parse(await readFile(rootPath, 'utf-8')) as NodeData;
21
+
22
+ // Internal mods (core/src/mods/)
23
+ const internalModsDir = new URL('../mods', import.meta.url).pathname;
24
+ const internal = await loadLocalMods(internalModsDir, 'server');
25
+
26
+ // External mods (root mods/)
27
+ const externalModsDir = new URL('../../../mods', import.meta.url).pathname;
28
+ const external = await loadLocalMods(externalModsDir, 'server');
29
+
30
+ const allFailed = [...internal.failed, ...external.failed];
31
+ if (allFailed.length) console.error('failed mods:', allFailed.map(f => `${f.name}: ${f.error.message}`).join(', '));
32
+ console.log(`mods: ${[...internal.loaded, ...external.loaded].join(', ')}`);
33
+
34
+ const port = Number(process.env.PORT) || 3211;
35
+
36
+ // ── Bootstrap from root.json ──
37
+ const bootstrap = createMemoryTree();
38
+ await bootstrap.set(rootNode);
39
+
40
+ const { server, store, mountable } = createTreenityServer(bootstrap);
41
+ await seed(mountable);
42
+
43
+ // MCP now starts via autostart service (/sys/autostart/mcp → /sys/mcp)
44
+ const serviceHandle = process.env.NO_SERVICES ? null
45
+ : await startServices(store, store.subscribe.bind(store) as import('#contexts/service/index').ServiceCtx['subscribe']);
46
+
47
+ const host = process.env.HOST || '127.0.0.1';
48
+ server.listen(port, host, () => console.log(`treenity trpc ${host}:${port}`));
49
+
50
+ process.on('unhandledRejection', (err) => console.error('[UNHANDLED]', err));
51
+
52
+ process.on('SIGTERM', async () => {
53
+ await serviceHandle?.stop();
54
+ server.close();
55
+ process.exit(0);
56
+ });
@@ -0,0 +1,326 @@
1
+ // Treenity MCP Server — exposes tree store as MCP tools
2
+ // StreamableHTTP transport, stateless, token auth via ?token= or Authorization header
3
+
4
+ import { createNode } from '#core';
5
+ import { verifyViewSource } from '#mods/uix/verify';
6
+ import { TypeCatalog } from '#schema/catalog';
7
+ import type { Tree } from '#tree';
8
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
10
+ import { createServer, type Server } from 'node:http';
11
+ import { z } from 'zod/v3';
12
+ import { executeAction } from './actions';
13
+ import { buildClaims, resolveToken, type Session, withAcl } from './auth';
14
+ import { deployPrefab } from './prefab';
15
+
16
+ /** Compact YAML-like serializer — readable for LLMs, much less noisy than JSON */
17
+ function yaml(val: unknown, depth = 0, maxStr = 300): string {
18
+ const pad = ' '.repeat(depth);
19
+ if (val == null) return 'null';
20
+ if (typeof val === 'boolean' || typeof val === 'number') return String(val);
21
+ if (typeof val === 'string') {
22
+ if (maxStr < Infinity && val.length > maxStr) return JSON.stringify(val.slice(0, maxStr) + '…');
23
+ return /[\n\r:#\[\]{}",]/.test(val) || val === '' ? JSON.stringify(val) : val;
24
+ }
25
+ if (Array.isArray(val)) {
26
+ if (!val.length) return '[]';
27
+ if (val.every(v => typeof v !== 'object' || v == null)) {
28
+ const inline = `[${val.map(v => yaml(v, 0, maxStr)).join(', ')}]`;
29
+ if (inline.length < 80) return inline;
30
+ }
31
+ return val.map(item => {
32
+ if (typeof item !== 'object' || item == null) return `${pad}- ${yaml(item, 0, maxStr)}`;
33
+ const inner = yaml(item, depth + 1, maxStr);
34
+ const lines = inner.split('\n');
35
+ return lines.length === 1
36
+ ? `${pad}- ${lines[0].trimStart()}`
37
+ : `${pad}- ${lines[0].trimStart()}\n${lines.slice(1).map(l => `${pad} ${l.trimStart()}`).join('\n')}`;
38
+ }).join('\n');
39
+ }
40
+ if (typeof val === 'object') {
41
+ const entries = Object.entries(val as Record<string, unknown>);
42
+ if (!entries.length) return '{}';
43
+ return entries.map(([k, v]) => {
44
+ if (v != null && typeof v === 'object') {
45
+ const inner = yaml(v, depth + 1, maxStr);
46
+ if (!inner.includes('\n') && inner.length < 60) return `${pad}${k}: ${inner.trimStart()}`;
47
+ return `${pad}${k}:\n${inner}`;
48
+ }
49
+ return `${pad}${k}: ${yaml(v, 0, maxStr)}`;
50
+ }).join('\n');
51
+ }
52
+ return String(val);
53
+ }
54
+
55
+ const text = (s: string) => ({ content: [{ type: 'text' as const, text: s }] });
56
+ const catalog = new TypeCatalog();
57
+
58
+ /** Count non-system fields on a node */
59
+ function dataKeys(node: Record<string, unknown>) {
60
+ return Object.keys(node).filter(k => !k.startsWith('$'));
61
+ }
62
+
63
+ async function buildMcpServer(store: Tree, session: Session, claims?: string[]) {
64
+ claims ??= await buildClaims(store, session.userId);
65
+ const aclStore = withAcl(store, session.userId, claims);
66
+
67
+ const mcp = new McpServer({ name: 'treenity', version: '1.0.0' });
68
+
69
+ mcp.registerTool(
70
+ 'get_node',
71
+ {
72
+ description: 'Read a node by path. Returns full untruncated values.',
73
+ inputSchema: { path: z.string() },
74
+ },
75
+ async ({ path }) => {
76
+ const node = await aclStore.get(path);
77
+ return text(node ? yaml(node, 0, Infinity) : `not found: ${path}`);
78
+ },
79
+ );
80
+
81
+ mcp.registerTool(
82
+ 'list_children',
83
+ {
84
+ description: 'List children of a node. Long string values may be truncated — use get_node for full data.',
85
+ inputSchema: {
86
+ path: z.string(),
87
+ depth: z.number().optional(),
88
+ detail: z.boolean().optional().describe('Show first-level fields and component types'),
89
+ full: z.boolean().optional().describe('Return complete YAML of each node'),
90
+ },
91
+ },
92
+ async ({ path, depth, detail, full }) => {
93
+ const ctx = { queryContextPath: path, userId: session.userId };
94
+ const result = await aclStore.getChildren(path, { depth }, ctx);
95
+ const { items, total } = result;
96
+
97
+ if (full) return text(yaml({ total, items }));
98
+
99
+ if (detail) {
100
+ const lines = items.map(n => {
101
+ const name = n.$path.split('/').at(-1);
102
+ const keys = dataKeys(n);
103
+ const header = n.$type === 'dir' ? `${name}/` : `${name}: ${n.$type} [${keys.length}]`;
104
+ const fields = keys.map(k => {
105
+ const v = (n as Record<string, unknown>)[k];
106
+ if (v && typeof v === 'object' && '$type' in (v as object))
107
+ return ` ${k}: ${(v as Record<string, unknown>).$type}`;
108
+ if (Array.isArray(v)) return ` ${k}: [${v.length}]`;
109
+ const s = String(v);
110
+ return ` ${k}: ${s.length > 60 ? s.slice(0, 60) + '…' : s}`;
111
+ });
112
+ return header + (fields.length ? '\n' + fields.join('\n') : '');
113
+ });
114
+ return text(lines.join('\n') + `\n(${total} total)`);
115
+ }
116
+
117
+ // Default: ls-like — name, type, field count
118
+ const lines = items.map(n => {
119
+ const name = n.$path.split('/').at(-1);
120
+ if (n.$type === 'dir') return `${name}/`;
121
+ return `${name} ${n.$type} [${dataKeys(n).length}]`;
122
+ });
123
+ return text(lines.join('\n') + (total > items.length ? `\n(${total} total)` : ''));
124
+ },
125
+ );
126
+
127
+ mcp.registerTool(
128
+ 'set_node',
129
+ {
130
+ description: 'Create or update a node',
131
+ inputSchema: {
132
+ path: z.string(),
133
+ type: z.string(),
134
+ components: z.record(z.unknown()).optional(),
135
+ acl: z.array(z.object({ g: z.string(), p: z.number() })).optional(),
136
+ owner: z.string().optional(),
137
+ },
138
+ },
139
+ async ({ path, type, components, acl, owner }) => {
140
+ const existing = await aclStore.get(path);
141
+ const node = existing ?? createNode(path, type);
142
+ if (!existing) node.$type = type;
143
+ if (components) {
144
+ for (const [k, v] of Object.entries(components)) {
145
+ if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;
146
+ // LLMs often wrap node-level fields in a component matching the node $type.
147
+ // Flatten: merge as plain fields instead of creating a redundant component.
148
+ const comp = v as Record<string, unknown> | null;
149
+ if (comp && typeof comp === 'object' && comp.$type === type) {
150
+ for (const [fk, fv] of Object.entries(comp)) {
151
+ if (fk !== '$type') node[fk] = fv;
152
+ }
153
+ continue;
154
+ }
155
+ node[k] = v;
156
+ }
157
+ }
158
+ if (acl) node.$acl = acl;
159
+ if (owner) node.$owner = owner;
160
+ await aclStore.set(node);
161
+ return text(yaml(node));
162
+ },
163
+ );
164
+
165
+ mcp.registerTool(
166
+ 'execute',
167
+ {
168
+ description: 'Execute an action on a node or component. Actions are methods registered on types.',
169
+ inputSchema: {
170
+ path: z.string(),
171
+ action: z.string(),
172
+ type: z.string().optional(), // component $type for verification/scan
173
+ key: z.string().optional(), // component field key for direct lookup
174
+ data: z.record(z.unknown()).optional(),
175
+ },
176
+ },
177
+ async ({ path, action, type, key, data }) => {
178
+ const result = await executeAction(aclStore, path, type, key, action, data);
179
+ return text(yaml(result ?? { ok: true }));
180
+ },
181
+ );
182
+
183
+ mcp.registerTool(
184
+ 'deploy_prefab',
185
+ {
186
+ description: 'Deploy a module prefab (node tree template) to a target path. Idempotent: skips existing nodes. Browse available prefabs via list_children /sys/mods.',
187
+ inputSchema: {
188
+ source: z.string().describe('Prefab path: /sys/mods/{mod}/prefabs/{name}'),
189
+ target: z.string().describe('Target path where nodes will be created'),
190
+ allowAbsolute: z.boolean().optional().describe('Allow prefab to write outside target (e.g. /sys/autostart refs). Default: false'),
191
+ },
192
+ },
193
+ async ({ source, target, allowAbsolute }) => {
194
+ const result = await deployPrefab(aclStore, source, target, { allowAbsolute });
195
+ return text(yaml(result));
196
+ },
197
+ );
198
+
199
+ mcp.registerTool(
200
+ 'compile_view',
201
+ {
202
+ description: 'Verify that a UIX view source compiles correctly. Pass path to check an existing type node, or source to verify before writing.',
203
+ inputSchema: {
204
+ path: z.string().optional().describe('Path to type node (e.g. /sys/types/cosmos/system) — reads view.source'),
205
+ source: z.string().optional().describe('Raw JSX/TSX source to verify directly'),
206
+ },
207
+ },
208
+ async ({ path, source }) => {
209
+ let code = source;
210
+ if (!code) {
211
+ if (!path) return text('error: provide path or source');
212
+ const node = await aclStore.get(path);
213
+ if (!node) return text(`not found: ${path}`);
214
+ code = (node as any)?.view?.source;
215
+ if (!code || typeof code !== 'string') return text(`no view.source on ${path}`);
216
+ }
217
+ const result = verifyViewSource(code);
218
+ return text(yaml(result));
219
+ },
220
+ );
221
+
222
+ mcp.registerTool(
223
+ 'remove_node',
224
+ {
225
+ description: 'Remove a node by path',
226
+ inputSchema: { path: z.string() },
227
+ },
228
+ async ({ path }) => {
229
+ const ok = await aclStore.remove(path);
230
+ return text(ok ? `removed: ${path}` : `not found: ${path}`);
231
+ },
232
+ );
233
+
234
+ // ── Discovery tools — powered by TypeCatalog ──
235
+
236
+ mcp.registerTool(
237
+ 'catalog',
238
+ {
239
+ description: 'List all registered types with title, properties, and action names. Use this first to discover what types exist.',
240
+ inputSchema: {},
241
+ },
242
+ async () => text(yaml(catalog.list())),
243
+ );
244
+
245
+ mcp.registerTool(
246
+ 'describe_type',
247
+ {
248
+ description: 'Get full schema of a type: properties, actions with argument types, and cross-references to other types. Use after catalog to understand a specific type deeply.',
249
+ inputSchema: { type: z.string().describe('Type name, e.g. "cafe.contact" or "board.task"') },
250
+ },
251
+ async ({ type: typeName }) => {
252
+ const desc = catalog.describe(typeName);
253
+ return text(desc ? yaml(desc) : `type not found: ${typeName}`);
254
+ },
255
+ );
256
+
257
+ mcp.registerTool(
258
+ 'search_types',
259
+ {
260
+ description: 'Search types by keyword across names, titles, property names, and action names. Use to find types relevant to a task.',
261
+ inputSchema: { query: z.string().describe('Search keyword, e.g. "order", "mail", "contact"') },
262
+ },
263
+ async ({ query }) => text(yaml(catalog.search(query))),
264
+ );
265
+
266
+ return mcp;
267
+ }
268
+
269
+ function extractToken(req: import('node:http').IncomingMessage): string | null {
270
+ const auth = req.headers.authorization;
271
+ if (typeof auth === 'string' && auth.startsWith('Bearer ')) return auth.slice(7);
272
+
273
+ const qs = (req.url ?? '').split('?')[1];
274
+ if (qs) {
275
+ const match = qs.match(/(?:^|&)token=([^&]+)/);
276
+ if (match) return decodeURIComponent(match[1]);
277
+ }
278
+ return null;
279
+ }
280
+
281
+ /** Create MCP HTTP server. Returns server handle for lifecycle management. */
282
+ export function createMcpHttpServer(store: Tree, port: number): Server {
283
+ const server = createServer(async (req, res) => {
284
+ res.setHeader('Access-Control-Allow-Origin', '*');
285
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
286
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, mcp-session-id');
287
+ if (req.method === 'OPTIONS') {
288
+ res.writeHead(204);
289
+ res.end();
290
+ return;
291
+ }
292
+
293
+ const url = (req.url ?? '/').split('?')[0];
294
+ if (url !== '/mcp') {
295
+ res.writeHead(404);
296
+ res.end('not found');
297
+ return;
298
+ }
299
+
300
+ // Auth: token from ?token= or Authorization header
301
+ // Dev mode: localhost without TENANT gets admin session (no token needed)
302
+ const token = extractToken(req);
303
+ let session: Session | null = null;
304
+ let devClaims: string[] | undefined;
305
+ if (token) {
306
+ session = await resolveToken(store, token);
307
+ } else if (!process.env.TENANT) {
308
+ session = { userId: 'mcp-dev' } as Session;
309
+ devClaims = ['u:mcp-dev', 'authenticated', 'admins'];
310
+ }
311
+ if (!session) {
312
+ res.writeHead(401, { 'Content-Type': 'text/plain' });
313
+ res.end('token required (?token= or Authorization: Bearer)');
314
+ return;
315
+ }
316
+
317
+ // Stateless: fresh transport + server per request, ACL-wrapped
318
+ const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
319
+ const mcp = await buildMcpServer(store, session, devClaims);
320
+ await mcp.connect(transport);
321
+ await transport.handleRequest(req, res);
322
+ });
323
+
324
+ server.listen(port, '127.0.0.1', () => console.log(`treenity mcp :${port}`));
325
+ return server;
326
+ }
@@ -0,0 +1,123 @@
1
+ import { createNode, register, unregister } from '#core';
2
+ import { createMemoryTree } from '#tree';
3
+ import assert from 'node:assert/strict';
4
+ import { afterEach, describe, it } from 'node:test';
5
+ import { withMigration } from './migrate';
6
+
7
+ const TEST_TYPE = 'test.migrated';
8
+
9
+ describe('withMigration', () => {
10
+ afterEach(() => {
11
+ unregister(TEST_TYPE, 'migrate');
12
+ });
13
+
14
+ it('passes through nodes without migrations', async () => {
15
+ const inner = createMemoryTree();
16
+ const store = withMigration(inner);
17
+ const node = createNode('/a', 'dir', { label: 'hi' });
18
+ await inner.set(node);
19
+
20
+ const got = await store.get('/a');
21
+ assert.equal(got?.label, 'hi');
22
+ assert.equal((got as any).$v, undefined);
23
+ });
24
+
25
+ it('runs migration chain on read for v0 node', async () => {
26
+ register(TEST_TYPE, 'migrate', () => ({
27
+ 1: (n: any) => { n.items = Array.isArray(n.items) ? n.items : []; },
28
+ 2: (n: any) => { n.label ??= 'default'; },
29
+ }));
30
+
31
+ const inner = createMemoryTree();
32
+ const store = withMigration(inner);
33
+ await inner.set(createNode('/a', TEST_TYPE, { items: 'old-string' }));
34
+
35
+ const got = await store.get('/a');
36
+ assert.deepEqual(got?.items, []);
37
+ assert.equal(got?.label, 'default');
38
+ assert.equal((got as any).$v, 2);
39
+ });
40
+
41
+ it('skips already-applied migrations', async () => {
42
+ let ran1 = false;
43
+ register(TEST_TYPE, 'migrate', () => ({
44
+ 1: (_n: any) => { ran1 = true; },
45
+ 2: (n: any) => { n.upgraded = true; },
46
+ }));
47
+
48
+ const inner = createMemoryTree();
49
+ const store = withMigration(inner);
50
+ await inner.set({ ...createNode('/a', TEST_TYPE), $v: 1 } as any);
51
+
52
+ const got = await store.get('/a');
53
+ assert.equal(ran1, false);
54
+ assert.equal(got?.upgraded, true);
55
+ assert.equal((got as any).$v, 2);
56
+ });
57
+
58
+ it('returns node unchanged when already at current version', async () => {
59
+ register(TEST_TYPE, 'migrate', () => ({
60
+ 1: (n: any) => { n.touched = true; },
61
+ }));
62
+
63
+ const inner = createMemoryTree();
64
+ const store = withMigration(inner);
65
+ await inner.set({ ...createNode('/a', TEST_TYPE), $v: 1 } as any);
66
+
67
+ const got = await store.get('/a');
68
+ assert.equal(got?.touched, undefined);
69
+ assert.equal((got as any).$v, 1);
70
+ });
71
+
72
+ it('stamps $v on set()', async () => {
73
+ register(TEST_TYPE, 'migrate', () => ({
74
+ 1: (_n: any) => {},
75
+ 2: (_n: any) => {},
76
+ }));
77
+
78
+ const inner = createMemoryTree();
79
+ const store = withMigration(inner);
80
+ const node = createNode('/a', TEST_TYPE, { x: 1 });
81
+ await store.set(node);
82
+
83
+ // Read from inner store to see what was actually persisted
84
+ const raw = await inner.get('/a');
85
+ assert.equal((raw as any).$v, 2);
86
+ });
87
+
88
+ it('migrates children in getChildren()', async () => {
89
+ register(TEST_TYPE, 'migrate', () => ({
90
+ 1: (n: any) => { n.fixed = true; },
91
+ }));
92
+
93
+ const inner = createMemoryTree();
94
+ const store = withMigration(inner);
95
+ await inner.set(createNode('/parent', 'dir'));
96
+ await inner.set(createNode('/parent/a', TEST_TYPE, { val: 1 }));
97
+ await inner.set(createNode('/parent/b', TEST_TYPE, { val: 2 }));
98
+
99
+ const { items } = await store.getChildren('/parent');
100
+ assert.equal(items.length, 2);
101
+ for (const item of items) {
102
+ assert.equal(item.fixed, true);
103
+ assert.equal((item as any).$v, 1);
104
+ }
105
+ });
106
+
107
+ it('does not mutate the original stored node', async () => {
108
+ register(TEST_TYPE, 'migrate', () => ({
109
+ 1: (n: any) => { n.data = 'migrated'; },
110
+ }));
111
+
112
+ const inner = createMemoryTree();
113
+ const store = withMigration(inner);
114
+ await inner.set(createNode('/a', TEST_TYPE, { data: 'old' }));
115
+
116
+ await store.get('/a');
117
+
118
+ // Inner store should still have original data
119
+ const raw = await inner.get('/a');
120
+ assert.equal(raw?.data, 'old');
121
+ assert.equal((raw as any).$v, undefined);
122
+ });
123
+ });
@@ -0,0 +1,62 @@
1
+ // Per-type schema migration — normalizes nodes on read, stamps $v on write.
2
+ // Migrations registered via: register(type, 'migrate', { 1: fn, 2: fn })
3
+ // Absent $v = version 0. Migration functions mutate the node clone in-place.
4
+ // NOTE: not wired into pipeline yet — will be added between validated and subscriptions
5
+
6
+ import { type NodeData, resolveExact } from '#core';
7
+ import type { Tree } from '#tree';
8
+
9
+ type Migrator = (node: Record<string, unknown>) => void;
10
+ type Migrations = Record<number, Migrator>;
11
+
12
+ function getMigrations(type: string): { migrations: Migrations; version: number } | null {
13
+ const handler = resolveExact(type, 'migrate');
14
+ if (!handler) return null;
15
+ const migrations = handler() as unknown as Migrations;
16
+ const keys = Object.keys(migrations).map(Number).sort((a, b) => a - b);
17
+ if (!keys.length) return null;
18
+ return { migrations, version: keys[keys.length - 1] };
19
+ }
20
+
21
+ function migrateNode(node: NodeData): NodeData {
22
+ const m = getMigrations(node.$type);
23
+ if (!m) return node;
24
+
25
+ const nodeV = (node as any).$v as number ?? 0;
26
+ if (nodeV >= m.version) return node;
27
+
28
+ const clone = structuredClone(node);
29
+ for (const [v, fn] of Object.entries(m.migrations).sort(([a], [b]) => +a - +b)) {
30
+ if (+v > nodeV) fn(clone as Record<string, unknown>);
31
+ }
32
+ (clone as any).$v = m.version;
33
+ return clone;
34
+ }
35
+
36
+ function stampVersion(node: NodeData): void {
37
+ const m = getMigrations(node.$type);
38
+ if (!m) return;
39
+ (node as any).$v = m.version;
40
+ }
41
+
42
+ export function withMigration(store: Tree): Tree {
43
+ return {
44
+ ...store,
45
+
46
+ async get(path, ctx) {
47
+ const node = await store.get(path, ctx);
48
+ if (!node) return node;
49
+ return migrateNode(node);
50
+ },
51
+
52
+ async getChildren(path, opts, ctx) {
53
+ const page = await store.getChildren(path, opts, ctx);
54
+ return { ...page, items: page.items.map(migrateNode) };
55
+ },
56
+
57
+ async set(node, ctx) {
58
+ stampVersion(node);
59
+ return store.set(node, ctx);
60
+ },
61
+ };
62
+ }