@vibesdotdev/storage 0.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 (423) hide show
  1. package/README.md +75 -0
  2. package/SPEC.md +60 -0
  3. package/dist/adapters/index.d.ts +14 -0
  4. package/dist/adapters/index.d.ts.map +1 -0
  5. package/dist/adapters/index.js +15 -0
  6. package/dist/adapters/index.js.map +1 -0
  7. package/dist/bridge/index.d.ts +3 -0
  8. package/dist/bridge/index.d.ts.map +1 -0
  9. package/dist/bridge/index.js +2 -0
  10. package/dist/bridge/index.js.map +1 -0
  11. package/dist/bridge/storage-kind-bridge.d.ts +27 -0
  12. package/dist/bridge/storage-kind-bridge.d.ts.map +1 -0
  13. package/dist/bridge/storage-kind-bridge.js +110 -0
  14. package/dist/bridge/storage-kind-bridge.js.map +1 -0
  15. package/dist/bridge/types.d.ts +45 -0
  16. package/dist/bridge/types.d.ts.map +1 -0
  17. package/dist/bridge/types.js +8 -0
  18. package/dist/bridge/types.js.map +1 -0
  19. package/dist/cli/commands/list/storage.list.cli-command.descriptor.d.ts +4 -0
  20. package/dist/cli/commands/list/storage.list.cli-command.descriptor.d.ts.map +1 -0
  21. package/dist/cli/commands/list/storage.list.cli-command.descriptor.js +18 -0
  22. package/dist/cli/commands/list/storage.list.cli-command.descriptor.js.map +1 -0
  23. package/dist/cli/commands/list/storage.list.cli-command.impl.d.ts +11 -0
  24. package/dist/cli/commands/list/storage.list.cli-command.impl.d.ts.map +1 -0
  25. package/dist/cli/commands/list/storage.list.cli-command.impl.js +48 -0
  26. package/dist/cli/commands/list/storage.list.cli-command.impl.js.map +1 -0
  27. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.d.ts +4 -0
  28. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.d.ts.map +1 -0
  29. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.js +26 -0
  30. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.js.map +1 -0
  31. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.d.ts +13 -0
  32. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.d.ts.map +1 -0
  33. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.js +136 -0
  34. package/dist/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.js.map +1 -0
  35. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.d.ts +4 -0
  36. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.d.ts.map +1 -0
  37. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.js +26 -0
  38. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.js.map +1 -0
  39. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.d.ts +13 -0
  40. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.d.ts.map +1 -0
  41. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.js +165 -0
  42. package/dist/cli/commands/sync/push/storage.sync.push.cli-command.impl.js.map +1 -0
  43. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.d.ts +4 -0
  44. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.d.ts.map +1 -0
  45. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.js +20 -0
  46. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.js.map +1 -0
  47. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.d.ts +12 -0
  48. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.d.ts.map +1 -0
  49. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.js +95 -0
  50. package/dist/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.js.map +1 -0
  51. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.d.ts +4 -0
  52. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.d.ts.map +1 -0
  53. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.js +15 -0
  54. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.js.map +1 -0
  55. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.d.ts +13 -0
  56. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.d.ts.map +1 -0
  57. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.js +150 -0
  58. package/dist/cli/commands/sync/status/storage.sync.status.cli-command.impl.js.map +1 -0
  59. package/dist/cli/context.consumer.d.ts +26 -0
  60. package/dist/cli/context.consumer.d.ts.map +1 -0
  61. package/dist/cli/context.consumer.js +164 -0
  62. package/dist/cli/context.consumer.js.map +1 -0
  63. package/dist/cli/storage.cli-group.descriptor.d.ts +4 -0
  64. package/dist/cli/storage.cli-group.descriptor.d.ts.map +1 -0
  65. package/dist/cli/storage.cli-group.descriptor.js +11 -0
  66. package/dist/cli/storage.cli-group.descriptor.js.map +1 -0
  67. package/dist/cli/storage.sync.cli-group.descriptor.d.ts +4 -0
  68. package/dist/cli/storage.sync.cli-group.descriptor.d.ts.map +1 -0
  69. package/dist/cli/storage.sync.cli-group.descriptor.js +12 -0
  70. package/dist/cli/storage.sync.cli-group.descriptor.js.map +1 -0
  71. package/dist/cli/types.d.ts +26 -0
  72. package/dist/cli/types.d.ts.map +1 -0
  73. package/dist/cli/types.js +11 -0
  74. package/dist/cli/types.js.map +1 -0
  75. package/dist/client/index.d.ts +10 -0
  76. package/dist/client/index.d.ts.map +1 -0
  77. package/dist/client/index.js +10 -0
  78. package/dist/client/index.js.map +1 -0
  79. package/dist/client/list-browsable-adapters.d.ts +31 -0
  80. package/dist/client/list-browsable-adapters.d.ts.map +1 -0
  81. package/dist/client/list-browsable-adapters.js +40 -0
  82. package/dist/client/list-browsable-adapters.js.map +1 -0
  83. package/dist/daemon/commands/sync.d.ts +23 -0
  84. package/dist/daemon/commands/sync.d.ts.map +1 -0
  85. package/dist/daemon/commands/sync.js +169 -0
  86. package/dist/daemon/commands/sync.js.map +1 -0
  87. package/dist/docs/adapters.docs.descriptor.d.ts +4 -0
  88. package/dist/docs/adapters.docs.descriptor.d.ts.map +1 -0
  89. package/dist/docs/adapters.docs.descriptor.js +223 -0
  90. package/dist/docs/adapters.docs.descriptor.js.map +1 -0
  91. package/dist/docs/manifests.docs.descriptor.d.ts +4 -0
  92. package/dist/docs/manifests.docs.descriptor.d.ts.map +1 -0
  93. package/dist/docs/manifests.docs.descriptor.js +316 -0
  94. package/dist/docs/manifests.docs.descriptor.js.map +1 -0
  95. package/dist/docs/records.docs.descriptor.d.ts +4 -0
  96. package/dist/docs/records.docs.descriptor.d.ts.map +1 -0
  97. package/dist/docs/records.docs.descriptor.js +269 -0
  98. package/dist/docs/records.docs.descriptor.js.map +1 -0
  99. package/dist/docs/sync.docs.descriptor.d.ts +4 -0
  100. package/dist/docs/sync.docs.descriptor.d.ts.map +1 -0
  101. package/dist/docs/sync.docs.descriptor.js +279 -0
  102. package/dist/docs/sync.docs.descriptor.js.map +1 -0
  103. package/dist/index.d.ts +27 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +29 -0
  106. package/dist/index.js.map +1 -0
  107. package/dist/interfaces/adapter.d.ts +382 -0
  108. package/dist/interfaces/adapter.d.ts.map +1 -0
  109. package/dist/interfaces/adapter.js +11 -0
  110. package/dist/interfaces/adapter.js.map +1 -0
  111. package/dist/interfaces/document-store.d.ts +62 -0
  112. package/dist/interfaces/document-store.d.ts.map +1 -0
  113. package/dist/interfaces/document-store.js +8 -0
  114. package/dist/interfaces/document-store.js.map +1 -0
  115. package/dist/interfaces/index.d.ts +17 -0
  116. package/dist/interfaces/index.d.ts.map +1 -0
  117. package/dist/interfaces/index.js +24 -0
  118. package/dist/interfaces/index.js.map +1 -0
  119. package/dist/interfaces/key-value.d.ts +95 -0
  120. package/dist/interfaces/key-value.d.ts.map +1 -0
  121. package/dist/interfaces/key-value.js +8 -0
  122. package/dist/interfaces/key-value.js.map +1 -0
  123. package/dist/interfaces/query-builder.d.ts +31 -0
  124. package/dist/interfaces/query-builder.d.ts.map +1 -0
  125. package/dist/interfaces/query-builder.js +11 -0
  126. package/dist/interfaces/query-builder.js.map +1 -0
  127. package/dist/interfaces/record/index.d.ts +7 -0
  128. package/dist/interfaces/record/index.d.ts.map +1 -0
  129. package/dist/interfaces/record/index.js +7 -0
  130. package/dist/interfaces/record/index.js.map +1 -0
  131. package/dist/interfaces/record/interface.d.ts +593 -0
  132. package/dist/interfaces/record/interface.d.ts.map +1 -0
  133. package/dist/interfaces/record/interface.js +49 -0
  134. package/dist/interfaces/record/interface.js.map +1 -0
  135. package/dist/interfaces/repository.d.ts +262 -0
  136. package/dist/interfaces/repository.d.ts.map +1 -0
  137. package/dist/interfaces/repository.js +8 -0
  138. package/dist/interfaces/repository.js.map +1 -0
  139. package/dist/interfaces/schema/index.d.ts +8 -0
  140. package/dist/interfaces/schema/index.d.ts.map +1 -0
  141. package/dist/interfaces/schema/index.js +10 -0
  142. package/dist/interfaces/schema/index.js.map +1 -0
  143. package/dist/interfaces/schema/schema-interface.d.ts +516 -0
  144. package/dist/interfaces/schema/schema-interface.d.ts.map +1 -0
  145. package/dist/interfaces/schema/schema-interface.js +31 -0
  146. package/dist/interfaces/schema/schema-interface.js.map +1 -0
  147. package/dist/interfaces/schema/table-interface.d.ts +250 -0
  148. package/dist/interfaces/schema/table-interface.d.ts.map +1 -0
  149. package/dist/interfaces/schema/table-interface.js +31 -0
  150. package/dist/interfaces/schema/table-interface.js.map +1 -0
  151. package/dist/interfaces/storage-consumer-fs.d.ts +40 -0
  152. package/dist/interfaces/storage-consumer-fs.d.ts.map +1 -0
  153. package/dist/interfaces/storage-consumer-fs.js +42 -0
  154. package/dist/interfaces/storage-consumer-fs.js.map +1 -0
  155. package/dist/manifest/base.d.ts +187 -0
  156. package/dist/manifest/base.d.ts.map +1 -0
  157. package/dist/manifest/base.js +516 -0
  158. package/dist/manifest/base.js.map +1 -0
  159. package/dist/manifest/cloud-sync.consumer.d.ts +7 -0
  160. package/dist/manifest/cloud-sync.consumer.d.ts.map +1 -0
  161. package/dist/manifest/cloud-sync.consumer.js +82 -0
  162. package/dist/manifest/cloud-sync.consumer.js.map +1 -0
  163. package/dist/manifest/index.d.ts +7 -0
  164. package/dist/manifest/index.d.ts.map +1 -0
  165. package/dist/manifest/index.js +7 -0
  166. package/dist/manifest/index.js.map +1 -0
  167. package/dist/manifest/source-policy.d.ts +8 -0
  168. package/dist/manifest/source-policy.d.ts.map +1 -0
  169. package/dist/manifest/source-policy.js +62 -0
  170. package/dist/manifest/source-policy.js.map +1 -0
  171. package/dist/paths.d.ts +6 -0
  172. package/dist/paths.d.ts.map +1 -0
  173. package/dist/paths.js +152 -0
  174. package/dist/paths.js.map +1 -0
  175. package/dist/policy/context.d.ts +9 -0
  176. package/dist/policy/context.d.ts.map +1 -0
  177. package/dist/policy/context.js +29 -0
  178. package/dist/policy/context.js.map +1 -0
  179. package/dist/policy/index.d.ts +4 -0
  180. package/dist/policy/index.d.ts.map +1 -0
  181. package/dist/policy/index.js +4 -0
  182. package/dist/policy/index.js.map +1 -0
  183. package/dist/policy/overrides.d.ts +40 -0
  184. package/dist/policy/overrides.d.ts.map +1 -0
  185. package/dist/policy/overrides.js +37 -0
  186. package/dist/policy/overrides.js.map +1 -0
  187. package/dist/policy/persistence.d.ts +38 -0
  188. package/dist/policy/persistence.d.ts.map +1 -0
  189. package/dist/policy/persistence.js +65 -0
  190. package/dist/policy/persistence.js.map +1 -0
  191. package/dist/policy/types.d.ts +21 -0
  192. package/dist/policy/types.d.ts.map +1 -0
  193. package/dist/policy/types.js +7 -0
  194. package/dist/policy/types.js.map +1 -0
  195. package/dist/record/base.d.ts +186 -0
  196. package/dist/record/base.d.ts.map +1 -0
  197. package/dist/record/base.js +1437 -0
  198. package/dist/record/base.js.map +1 -0
  199. package/dist/record/events.d.ts +71 -0
  200. package/dist/record/events.d.ts.map +1 -0
  201. package/dist/record/events.js +52 -0
  202. package/dist/record/events.js.map +1 -0
  203. package/dist/record/extensions.d.ts +51 -0
  204. package/dist/record/extensions.d.ts.map +1 -0
  205. package/dist/record/extensions.js +222 -0
  206. package/dist/record/extensions.js.map +1 -0
  207. package/dist/record/index.d.ts +7 -0
  208. package/dist/record/index.d.ts.map +1 -0
  209. package/dist/record/index.js +7 -0
  210. package/dist/record/index.js.map +1 -0
  211. package/dist/resolver/storage-backed-resolver.d.ts +23 -0
  212. package/dist/resolver/storage-backed-resolver.d.ts.map +1 -0
  213. package/dist/resolver/storage-backed-resolver.js +187 -0
  214. package/dist/resolver/storage-backed-resolver.js.map +1 -0
  215. package/dist/schemas/adapter-descriptor.d.ts +108 -0
  216. package/dist/schemas/adapter-descriptor.d.ts.map +1 -0
  217. package/dist/schemas/adapter-descriptor.js +101 -0
  218. package/dist/schemas/adapter-descriptor.js.map +1 -0
  219. package/dist/schemas/index.d.ts +14 -0
  220. package/dist/schemas/index.d.ts.map +1 -0
  221. package/dist/schemas/index.js +12 -0
  222. package/dist/schemas/index.js.map +1 -0
  223. package/dist/schemas/manifest-descriptor.d.ts +110 -0
  224. package/dist/schemas/manifest-descriptor.d.ts.map +1 -0
  225. package/dist/schemas/manifest-descriptor.js +114 -0
  226. package/dist/schemas/manifest-descriptor.js.map +1 -0
  227. package/dist/schemas/record/descriptor.d.ts +570 -0
  228. package/dist/schemas/record/descriptor.d.ts.map +1 -0
  229. package/dist/schemas/record/descriptor.js +389 -0
  230. package/dist/schemas/record/descriptor.js.map +1 -0
  231. package/dist/schemas/record/index.d.ts +8 -0
  232. package/dist/schemas/record/index.d.ts.map +1 -0
  233. package/dist/schemas/record/index.js +7 -0
  234. package/dist/schemas/record/index.js.map +1 -0
  235. package/dist/schemas/record/relation.d.ts +36 -0
  236. package/dist/schemas/record/relation.d.ts.map +1 -0
  237. package/dist/schemas/record/relation.js +37 -0
  238. package/dist/schemas/record/relation.js.map +1 -0
  239. package/dist/schemas/schema/descriptor.d.ts +231 -0
  240. package/dist/schemas/schema/descriptor.d.ts.map +1 -0
  241. package/dist/schemas/schema/descriptor.js +205 -0
  242. package/dist/schemas/schema/descriptor.js.map +1 -0
  243. package/dist/schemas/schema/index.d.ts +7 -0
  244. package/dist/schemas/schema/index.d.ts.map +1 -0
  245. package/dist/schemas/schema/index.js +7 -0
  246. package/dist/schemas/schema/index.js.map +1 -0
  247. package/dist/schemas/sync-bridge-descriptor.d.ts +124 -0
  248. package/dist/schemas/sync-bridge-descriptor.d.ts.map +1 -0
  249. package/dist/schemas/sync-bridge-descriptor.js +67 -0
  250. package/dist/schemas/sync-bridge-descriptor.js.map +1 -0
  251. package/dist/server/manifest-route.d.ts +92 -0
  252. package/dist/server/manifest-route.d.ts.map +1 -0
  253. package/dist/server/manifest-route.js +226 -0
  254. package/dist/server/manifest-route.js.map +1 -0
  255. package/dist/storage-policy.context.descriptor.d.ts +16 -0
  256. package/dist/storage-policy.context.descriptor.d.ts.map +1 -0
  257. package/dist/storage-policy.context.descriptor.js +16 -0
  258. package/dist/storage-policy.context.descriptor.js.map +1 -0
  259. package/dist/storage-policy.context.server.d.ts +14 -0
  260. package/dist/storage-policy.context.server.d.ts.map +1 -0
  261. package/dist/storage-policy.context.server.js +27 -0
  262. package/dist/storage-policy.context.server.js.map +1 -0
  263. package/dist/storage.plugin.d.ts +38 -0
  264. package/dist/storage.plugin.d.ts.map +1 -0
  265. package/dist/storage.plugin.js +204 -0
  266. package/dist/storage.plugin.js.map +1 -0
  267. package/dist/sync/cloud-pull.d.ts +15 -0
  268. package/dist/sync/cloud-pull.d.ts.map +1 -0
  269. package/dist/sync/cloud-pull.js +130 -0
  270. package/dist/sync/cloud-pull.js.map +1 -0
  271. package/dist/sync/cloud-record-crud-config.d.ts +19 -0
  272. package/dist/sync/cloud-record-crud-config.d.ts.map +1 -0
  273. package/dist/sync/cloud-record-crud-config.js +22 -0
  274. package/dist/sync/cloud-record-crud-config.js.map +1 -0
  275. package/dist/sync/record-sync-bridge.d.ts +5 -0
  276. package/dist/sync/record-sync-bridge.d.ts.map +1 -0
  277. package/dist/sync/record-sync-bridge.js +121 -0
  278. package/dist/sync/record-sync-bridge.js.map +1 -0
  279. package/dist/sync/resolve-sync-target.d.ts +23 -0
  280. package/dist/sync/resolve-sync-target.d.ts.map +1 -0
  281. package/dist/sync/resolve-sync-target.js +45 -0
  282. package/dist/sync/resolve-sync-target.js.map +1 -0
  283. package/dist/sync/schemas/cloud-pull.d.ts +25 -0
  284. package/dist/sync/schemas/cloud-pull.d.ts.map +1 -0
  285. package/dist/sync/schemas/cloud-pull.js +7 -0
  286. package/dist/sync/schemas/cloud-pull.js.map +1 -0
  287. package/dist/sync/schemas/index.d.ts +9 -0
  288. package/dist/sync/schemas/index.d.ts.map +1 -0
  289. package/dist/sync/schemas/index.js +9 -0
  290. package/dist/sync/schemas/index.js.map +1 -0
  291. package/dist/sync/schemas/sync-helpers.d.ts +17 -0
  292. package/dist/sync/schemas/sync-helpers.d.ts.map +1 -0
  293. package/dist/sync/schemas/sync-helpers.js +7 -0
  294. package/dist/sync/schemas/sync-helpers.js.map +1 -0
  295. package/dist/sync/schemas/sync-state.d.ts +65 -0
  296. package/dist/sync/schemas/sync-state.d.ts.map +1 -0
  297. package/dist/sync/schemas/sync-state.js +32 -0
  298. package/dist/sync/schemas/sync-state.js.map +1 -0
  299. package/dist/sync/sync-bridge.d.ts +80 -0
  300. package/dist/sync/sync-bridge.d.ts.map +1 -0
  301. package/dist/sync/sync-bridge.js +617 -0
  302. package/dist/sync/sync-bridge.js.map +1 -0
  303. package/dist/sync/sync-manifest.d.ts +20 -0
  304. package/dist/sync/sync-manifest.d.ts.map +1 -0
  305. package/dist/sync/sync-manifest.js +140 -0
  306. package/dist/sync/sync-manifest.js.map +1 -0
  307. package/dist/sync/sync-state.consumer.d.ts +23 -0
  308. package/dist/sync/sync-state.consumer.d.ts.map +1 -0
  309. package/dist/sync/sync-state.consumer.js +111 -0
  310. package/dist/sync/sync-state.consumer.js.map +1 -0
  311. package/dist/transform/index.d.ts +75 -0
  312. package/dist/transform/index.d.ts.map +1 -0
  313. package/dist/transform/index.js +81 -0
  314. package/dist/transform/index.js.map +1 -0
  315. package/dist/transform/transform-descriptor.d.ts +51 -0
  316. package/dist/transform/transform-descriptor.d.ts.map +1 -0
  317. package/dist/transform/transform-descriptor.js +30 -0
  318. package/dist/transform/transform-descriptor.js.map +1 -0
  319. package/dist/tui/storage-explorer.descriptor.d.ts +14 -0
  320. package/dist/tui/storage-explorer.descriptor.d.ts.map +1 -0
  321. package/dist/tui/storage-explorer.descriptor.js +29 -0
  322. package/dist/tui/storage-explorer.descriptor.js.map +1 -0
  323. package/dist/tui/storage-explorer.impl.consumer.d.ts +11 -0
  324. package/dist/tui/storage-explorer.impl.consumer.d.ts.map +1 -0
  325. package/dist/tui/storage-explorer.impl.consumer.js +13 -0
  326. package/dist/tui/storage-explorer.impl.consumer.js.map +1 -0
  327. package/dist/tui/storage-open.descriptor.d.ts +14 -0
  328. package/dist/tui/storage-open.descriptor.d.ts.map +1 -0
  329. package/dist/tui/storage-open.descriptor.js +28 -0
  330. package/dist/tui/storage-open.descriptor.js.map +1 -0
  331. package/dist/tui/storage-open.impl.consumer.d.ts +11 -0
  332. package/dist/tui/storage-open.impl.consumer.d.ts.map +1 -0
  333. package/dist/tui/storage-open.impl.consumer.js +13 -0
  334. package/dist/tui/storage-open.impl.consumer.js.map +1 -0
  335. package/dist/utils/error-context.d.ts +2 -0
  336. package/dist/utils/error-context.d.ts.map +1 -0
  337. package/dist/utils/error-context.js +17 -0
  338. package/dist/utils/error-context.js.map +1 -0
  339. package/package.json +241 -0
  340. package/src/adapters/index.ts +13 -0
  341. package/src/bridge/index.ts +2 -0
  342. package/src/bridge/storage-kind-bridge.ts +131 -0
  343. package/src/bridge/types.ts +46 -0
  344. package/src/cli/commands/list/storage.list.cli-command.descriptor.ts +20 -0
  345. package/src/cli/commands/list/storage.list.cli-command.impl.ts +72 -0
  346. package/src/cli/commands/sync/pull/storage.sync.pull.cli-command.descriptor.ts +28 -0
  347. package/src/cli/commands/sync/pull/storage.sync.pull.cli-command.impl.ts +171 -0
  348. package/src/cli/commands/sync/push/storage.sync.push.cli-command.descriptor.ts +28 -0
  349. package/src/cli/commands/sync/push/storage.sync.push.cli-command.impl.ts +213 -0
  350. package/src/cli/commands/sync/resolve/storage.sync.resolve.cli-command.descriptor.ts +22 -0
  351. package/src/cli/commands/sync/resolve/storage.sync.resolve.cli-command.impl.ts +129 -0
  352. package/src/cli/commands/sync/status/storage.sync.status.cli-command.descriptor.ts +17 -0
  353. package/src/cli/commands/sync/status/storage.sync.status.cli-command.impl.ts +192 -0
  354. package/src/cli/context.consumer.ts +195 -0
  355. package/src/cli/storage.cli-group.descriptor.ts +13 -0
  356. package/src/cli/storage.sync.cli-group.descriptor.ts +14 -0
  357. package/src/cli/types.ts +25 -0
  358. package/src/client/index.ts +10 -0
  359. package/src/client/list-browsable-adapters.ts +42 -0
  360. package/src/daemon/commands/sync.ts +225 -0
  361. package/src/docs/adapters.docs.descriptor.ts +225 -0
  362. package/src/docs/manifests.docs.descriptor.ts +318 -0
  363. package/src/docs/records.docs.descriptor.ts +271 -0
  364. package/src/docs/sync.docs.descriptor.ts +281 -0
  365. package/src/index.ts +109 -0
  366. package/src/interfaces/adapter.ts +451 -0
  367. package/src/interfaces/document-store.ts +74 -0
  368. package/src/interfaces/index.ts +117 -0
  369. package/src/interfaces/key-value.ts +112 -0
  370. package/src/interfaces/query-builder.ts +31 -0
  371. package/src/interfaces/record/index.ts +58 -0
  372. package/src/interfaces/record/interface.ts +723 -0
  373. package/src/interfaces/repository.ts +300 -0
  374. package/src/interfaces/schema/index.ts +37 -0
  375. package/src/interfaces/schema/schema-interface.ts +586 -0
  376. package/src/interfaces/schema/table-interface.ts +314 -0
  377. package/src/interfaces/storage-consumer-fs.ts +66 -0
  378. package/src/manifest/base.ts +594 -0
  379. package/src/manifest/cloud-sync.consumer.ts +120 -0
  380. package/src/manifest/index.ts +7 -0
  381. package/src/manifest/source-policy.ts +74 -0
  382. package/src/paths.ts +171 -0
  383. package/src/policy/context.ts +30 -0
  384. package/src/policy/index.ts +20 -0
  385. package/src/policy/overrides.ts +46 -0
  386. package/src/policy/persistence.ts +117 -0
  387. package/src/policy/types.ts +28 -0
  388. package/src/record/base.ts +1872 -0
  389. package/src/record/events.ts +56 -0
  390. package/src/record/extensions.ts +308 -0
  391. package/src/record/index.ts +7 -0
  392. package/src/resolver/storage-backed-resolver.ts +255 -0
  393. package/src/schemas/adapter-descriptor.ts +128 -0
  394. package/src/schemas/index.ts +104 -0
  395. package/src/schemas/manifest-descriptor.ts +143 -0
  396. package/src/schemas/record/descriptor.ts +621 -0
  397. package/src/schemas/record/index.ts +60 -0
  398. package/src/schemas/record/relation.ts +49 -0
  399. package/src/schemas/schema/descriptor.ts +278 -0
  400. package/src/schemas/schema/index.ts +14 -0
  401. package/src/schemas/sync-bridge-descriptor.ts +143 -0
  402. package/src/server/manifest-route.ts +319 -0
  403. package/src/storage-policy.context.descriptor.ts +17 -0
  404. package/src/storage-policy.context.server.ts +34 -0
  405. package/src/storage.plugin.ts +264 -0
  406. package/src/sync/cloud-pull.ts +202 -0
  407. package/src/sync/cloud-record-crud-config.ts +41 -0
  408. package/src/sync/record-sync-bridge.ts +183 -0
  409. package/src/sync/resolve-sync-target.ts +57 -0
  410. package/src/sync/schemas/cloud-pull.ts +26 -0
  411. package/src/sync/schemas/index.ts +18 -0
  412. package/src/sync/schemas/sync-helpers.ts +18 -0
  413. package/src/sync/schemas/sync-state.ts +41 -0
  414. package/src/sync/sync-bridge.ts +763 -0
  415. package/src/sync/sync-manifest.ts +212 -0
  416. package/src/sync/sync-state.consumer.ts +144 -0
  417. package/src/transform/index.ts +130 -0
  418. package/src/transform/transform-descriptor.ts +53 -0
  419. package/src/tui/storage-explorer.descriptor.ts +32 -0
  420. package/src/tui/storage-explorer.impl.consumer.ts +14 -0
  421. package/src/tui/storage-open.descriptor.ts +31 -0
  422. package/src/tui/storage-open.impl.consumer.ts +14 -0
  423. package/src/utils/error-context.ts +19 -0
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Sync Manifest Helper (Consumer)
3
+ *
4
+ * Core bidirectional sync logic for a single manifest.
5
+ * Extracted from MaintenanceStorageSyncJob to keep file size under limit.
6
+ */
7
+
8
+ import type { SyncState } from './schemas/sync-state';
9
+ import type { SyncHelpers } from './schemas/sync-helpers';
10
+ import { logger } from '@vibesdotdev/logging';
11
+
12
+ export type { SyncHelpers } from './schemas/sync-helpers';
13
+
14
+ /**
15
+ * Result of syncing a single manifest.
16
+ * Owned by storage — workers and CLI commands consume this type.
17
+ */
18
+ export interface ManifestSyncResult {
19
+ manifestId: string;
20
+ action: 'pushed' | 'pulled' | 'skipped' | 'conflict' | 'error';
21
+ message?: string;
22
+ }
23
+
24
+ const LOG_PREFIX = '[maintenance.storage-sync]';
25
+
26
+ export async function syncManifest(
27
+ manifestId: string,
28
+ syncState: SyncState,
29
+ helpers: SyncHelpers
30
+ ): Promise<ManifestSyncResult> {
31
+ const { getVibesRuntime } = await import('@vibesdotdev/runtime');
32
+ const runtime = getVibesRuntime();
33
+ const { StorageManifest } = await import('../manifest/index.js');
34
+
35
+ // Load local data via default adapter
36
+ const localManifest = new StorageManifest(manifestId);
37
+ let localData: unknown;
38
+ try {
39
+ localData = await localManifest.load();
40
+ } catch (schemaError) {
41
+ // Schema validation failed — data exists but doesn't match current schema.
42
+ // This is a data migration issue, not a sync issue.
43
+ const msg = schemaError instanceof Error ? schemaError.message : String(schemaError);
44
+ helpers.markError(syncState, manifestId, `Schema validation failed: ${msg}`);
45
+ return {
46
+ manifestId,
47
+ action: 'error',
48
+ message: `Local data fails schema validation (needs migration): ${msg}`
49
+ };
50
+ }
51
+ const localHash = localData ? helpers.computeHash(localData) : null;
52
+
53
+ // Load remote data via cloud-api adapter
54
+ const { remoteData, remoteHash } = await loadRemoteData(runtime, manifestId, helpers);
55
+
56
+ const prev = helpers.getManifestSyncState(syncState, manifestId);
57
+
58
+ // Decision matrix
59
+ if (!localData && !remoteData) {
60
+ return { manifestId, action: 'skipped', message: 'No data on either side' };
61
+ }
62
+
63
+ if (localHash === remoteHash) {
64
+ if (prev.syncStatus !== 'in-sync') {
65
+ helpers.markSynced(syncState, manifestId, localHash ?? '', 'push');
66
+ }
67
+ return { manifestId, action: 'skipped', message: 'Already in sync' };
68
+ }
69
+
70
+ const localChanged = localHash !== prev.localHash;
71
+ const remoteChanged = remoteHash !== prev.remoteHash;
72
+
73
+ if (localChanged && remoteChanged && remoteHash !== null) {
74
+ helpers.markConflict(syncState, manifestId, localHash ?? '', remoteHash);
75
+ return { manifestId, action: 'conflict', message: 'Both local and remote changed' };
76
+ }
77
+
78
+ if (remoteChanged && !localChanged && remoteData) {
79
+ if (helpers.dryRun) {
80
+ return { manifestId, action: 'pulled', message: '[dry-run] Would pull from cloud' };
81
+ }
82
+ await localManifest.save(remoteData as never);
83
+ helpers.markSynced(syncState, manifestId, remoteHash ?? '', 'pull');
84
+ logger.info(`${LOG_PREFIX} Pulled ${manifestId} from cloud`);
85
+ return { manifestId, action: 'pulled' };
86
+ }
87
+
88
+ if (localData) {
89
+ return pushToCloud(runtime, manifestId, localData, localHash, syncState, helpers);
90
+ }
91
+
92
+ return { manifestId, action: 'skipped', message: 'No actionable state' };
93
+ }
94
+
95
+ async function loadRemoteData(
96
+ runtime: ReturnType<Awaited<typeof import('@vibesdotdev/runtime')>['getVibesRuntime']>,
97
+ manifestId: string,
98
+ helpers: SyncHelpers
99
+ ): Promise<{ remoteData: unknown; remoteHash: string | null }> {
100
+ try {
101
+ const cloudAdapter = await runtime
102
+ .query('storage/adapter')
103
+ .filter((d: { id: string }) => d.id === 'storage.cloud-api')
104
+ .resolve();
105
+
106
+ if (!cloudAdapter) return { remoteData: null, remoteHash: null };
107
+
108
+ const descriptor = runtime
109
+ .query('storage/manifest')
110
+ .filter((d: { id: string }) => d.id === manifestId)
111
+ .firstDescriptor() as unknown as {
112
+ namespace: string;
113
+ schema: unknown;
114
+ adapterConfig?: Record<string, Record<string, unknown>>;
115
+ } | null;
116
+
117
+ if (!descriptor) return { remoteData: null, remoteHash: null };
118
+
119
+ const adapter = cloudAdapter as {
120
+ registerEndpoint(ns: string, ep: string): void;
121
+ ensureReady(): Promise<void>;
122
+ documentStore<T>(ns: string, schema: unknown): { load(): Promise<T | null> };
123
+ };
124
+
125
+ const cloudConfig = descriptor.adapterConfig?.['storage.cloud-api'] as
126
+ | { endpoint?: string }
127
+ | undefined;
128
+ if (cloudConfig?.endpoint) {
129
+ adapter.registerEndpoint(descriptor.namespace, cloudConfig.endpoint);
130
+ }
131
+ await adapter.ensureReady();
132
+
133
+ const store = adapter.documentStore<unknown>(descriptor.namespace, descriptor.schema);
134
+ const remoteData = await store.load();
135
+ const remoteHash = remoteData ? helpers.computeHash(remoteData) : null;
136
+ return { remoteData, remoteHash };
137
+ } catch (error) {
138
+ logger.debug(`${LOG_PREFIX} Cloud read failed for ${manifestId}`, {
139
+ error: (error as Error).message
140
+ });
141
+ return { remoteData: null, remoteHash: null };
142
+ }
143
+ }
144
+
145
+ async function pushToCloud(
146
+ runtime: ReturnType<Awaited<typeof import('@vibesdotdev/runtime')>['getVibesRuntime']>,
147
+ manifestId: string,
148
+ localData: unknown,
149
+ localHash: string | null,
150
+ syncState: SyncState,
151
+ helpers: SyncHelpers
152
+ ): Promise<ManifestSyncResult> {
153
+ if (helpers.dryRun) {
154
+ return { manifestId, action: 'pushed', message: '[dry-run] Would push to cloud' };
155
+ }
156
+
157
+ try {
158
+ const cloudAdapter = await runtime
159
+ .query('storage/adapter')
160
+ .filter((d: { id: string }) => d.id === 'storage.cloud-api')
161
+ .resolve();
162
+
163
+ if (!cloudAdapter) {
164
+ helpers.markLocalAhead(syncState, manifestId, localHash ?? '');
165
+ return { manifestId, action: 'skipped', message: 'Cloud adapter not available for push' };
166
+ }
167
+
168
+ const descriptor = runtime
169
+ .query('storage/manifest')
170
+ .filter((d: { id: string }) => d.id === manifestId)
171
+ .firstDescriptor() as unknown as {
172
+ namespace: string;
173
+ schema: unknown;
174
+ adapterConfig?: Record<string, Record<string, unknown>>;
175
+ } | null;
176
+
177
+ const adapter = cloudAdapter as {
178
+ registerEndpoint(ns: string, ep: string): void;
179
+ ensureReady(): Promise<void>;
180
+ documentStore<T>(ns: string, schema: unknown): { save(data: T): Promise<void> };
181
+ };
182
+
183
+ if (!descriptor) {
184
+ helpers.markLocalAhead(syncState, manifestId, localHash ?? '');
185
+ return {
186
+ manifestId,
187
+ action: 'skipped',
188
+ message: 'Manifest descriptor not registered for push'
189
+ };
190
+ }
191
+
192
+ // Register per-manifest endpoint override
193
+ const cloudConfig = descriptor.adapterConfig?.['storage.cloud-api'] as
194
+ | { endpoint?: string }
195
+ | undefined;
196
+ if (cloudConfig?.endpoint) {
197
+ adapter.registerEndpoint(descriptor.namespace, cloudConfig.endpoint);
198
+ }
199
+ await adapter.ensureReady();
200
+
201
+ const store = adapter.documentStore<unknown>(descriptor.namespace, descriptor.schema);
202
+ await store.save(localData);
203
+
204
+ helpers.markSynced(syncState, manifestId, localHash ?? '', 'push');
205
+ logger.info(`${LOG_PREFIX} Pushed ${manifestId} to cloud`);
206
+ return { manifestId, action: 'pushed' };
207
+ } catch (error) {
208
+ const msg = (error as Error).message;
209
+ helpers.markError(syncState, manifestId, msg);
210
+ return { manifestId, action: 'error', message: `Push failed: ${msg}` };
211
+ }
212
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Storage Sync State Tracking (Consumer)
3
+ *
4
+ * Tracks per-manifest sync state: hashes, timestamps, and conflict status.
5
+ * Stored in ~/.vibes/sync-state.json via direct JSON I/O (intentionally
6
+ * bypasses StorageManifest to avoid circular dependency).
7
+ *
8
+ * Consumer-scoped: uses host fs for persistence.
9
+ */
10
+
11
+ import { existsSync } from 'fs';
12
+ import { join } from 'path';
13
+ import { homedir } from 'os';
14
+ import { createHash } from 'node:crypto';
15
+ import { SyncStateSchema, type SyncState, type ManifestSyncState } from './schemas/sync-state';
16
+
17
+ // Re-export types for consumers
18
+ export type { SyncState, SyncStatus, ManifestSyncState } from './schemas/sync-state';
19
+
20
+ const SYNC_STATE_DIR = join(homedir(), '.vibes');
21
+ const SYNC_STATE_PATH = join(SYNC_STATE_DIR, 'sync-state.json');
22
+
23
+ function createDefaultState(): SyncState {
24
+ return {
25
+ version: 1,
26
+ updatedAt: new Date().toISOString(),
27
+ manifests: {}
28
+ };
29
+ }
30
+
31
+ function createDefaultManifestState(manifestId: string): ManifestSyncState {
32
+ return {
33
+ manifestId,
34
+ localHash: null,
35
+ remoteHash: null,
36
+ lastLocalChange: null,
37
+ lastRemoteChange: null,
38
+ lastSyncAt: null,
39
+ lastSyncDirection: null,
40
+ syncStatus: 'never-synced',
41
+ errorMessage: null
42
+ };
43
+ }
44
+
45
+ export async function loadSyncState(): Promise<SyncState> {
46
+ if (!existsSync(SYNC_STATE_PATH)) {
47
+ return createDefaultState();
48
+ }
49
+
50
+ try {
51
+ const { readFile } = await import('node:fs/promises');
52
+ const raw = await readFile(SYNC_STATE_PATH, 'utf-8');
53
+ const parsed = JSON.parse(raw);
54
+ return SyncStateSchema.parse(parsed);
55
+ } catch {
56
+ return createDefaultState();
57
+ }
58
+ }
59
+
60
+ export async function saveSyncState(state: SyncState): Promise<void> {
61
+ state.updatedAt = new Date().toISOString();
62
+
63
+ if (!existsSync(SYNC_STATE_DIR)) {
64
+ const { mkdir } = await import('node:fs/promises');
65
+ await mkdir(SYNC_STATE_DIR, { recursive: true });
66
+ }
67
+
68
+ const { writeFile } = await import('node:fs/promises');
69
+ await writeFile(SYNC_STATE_PATH, JSON.stringify(state, null, 2));
70
+ }
71
+
72
+ export function getManifestSyncState(state: SyncState, manifestId: string): ManifestSyncState {
73
+ return state.manifests[manifestId] ?? createDefaultManifestState(manifestId);
74
+ }
75
+
76
+ export function updateManifestSyncState(
77
+ state: SyncState,
78
+ manifestId: string,
79
+ update: Partial<ManifestSyncState>
80
+ ): void {
81
+ const current = getManifestSyncState(state, manifestId);
82
+ state.manifests[manifestId] = { ...current, ...update, manifestId };
83
+ }
84
+
85
+ export function markSynced(
86
+ state: SyncState,
87
+ manifestId: string,
88
+ hash: string,
89
+ direction: 'push' | 'pull'
90
+ ): void {
91
+ const now = new Date().toISOString();
92
+ updateManifestSyncState(state, manifestId, {
93
+ localHash: hash,
94
+ remoteHash: hash,
95
+ lastSyncAt: now,
96
+ lastSyncDirection: direction,
97
+ syncStatus: 'in-sync',
98
+ errorMessage: null,
99
+ ...(direction === 'push' ? { lastLocalChange: now } : { lastRemoteChange: now })
100
+ });
101
+ }
102
+
103
+ export function markLocalAhead(state: SyncState, manifestId: string, localHash: string): void {
104
+ updateManifestSyncState(state, manifestId, {
105
+ localHash,
106
+ lastLocalChange: new Date().toISOString(),
107
+ syncStatus: 'local-ahead'
108
+ });
109
+ }
110
+
111
+ export function markRemoteAhead(state: SyncState, manifestId: string, remoteHash: string): void {
112
+ updateManifestSyncState(state, manifestId, {
113
+ remoteHash,
114
+ lastRemoteChange: new Date().toISOString(),
115
+ syncStatus: 'remote-ahead'
116
+ });
117
+ }
118
+
119
+ export function markConflict(
120
+ state: SyncState,
121
+ manifestId: string,
122
+ localHash: string,
123
+ remoteHash: string
124
+ ): void {
125
+ updateManifestSyncState(state, manifestId, {
126
+ localHash,
127
+ remoteHash,
128
+ syncStatus: 'conflict'
129
+ });
130
+ }
131
+
132
+ export function markError(state: SyncState, manifestId: string, errorMessage: string): void {
133
+ updateManifestSyncState(state, manifestId, { errorMessage });
134
+ }
135
+
136
+ export function markAllPaused(state: SyncState): void {
137
+ for (const manifestId of Object.keys(state.manifests)) {
138
+ updateManifestSyncState(state, manifestId, { syncStatus: 'paused' });
139
+ }
140
+ }
141
+
142
+ export function computeHash(data: unknown): string {
143
+ return createHash('sha256').update(JSON.stringify(data)).digest('hex');
144
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Storage transform registration + resolution helpers.
3
+ *
4
+ * Plugins register transforms via `createStorageTransform()` (returns
5
+ * descriptor + implementation) and `runtime.registerDescriptor` +
6
+ * `runtime.registerLoader`. Consumers (typically `vibesCrudCollection`)
7
+ * call `resolveStorageTransform(runtime, id)` to pull both the descriptor
8
+ * metadata and the live `fromRow` / `toRow` functions.
9
+ *
10
+ * The runtime kind itself (`storage/transform`) is declared in
11
+ * `storage.plugin.ts` so it's available before any app plugin tries to
12
+ * register against it.
13
+ */
14
+
15
+ import { createRuntimeImplementation } from '@vibesdotdev/runtime';
16
+ import type { RuntimeImplementationWrapper } from '@vibesdotdev/runtime';
17
+ import {
18
+ StorageTransformDescriptorSchema,
19
+ type StorageTransformDescriptor,
20
+ type StorageTransformImplementation
21
+ } from './transform-descriptor.ts';
22
+
23
+ export {
24
+ StorageTransformDescriptorSchema,
25
+ type StorageTransformDescriptor,
26
+ type StorageTransformImplementation
27
+ } from './transform-descriptor.ts';
28
+
29
+ // NOTE: createDefaultDbTransforms and commonFieldMappings are available from
30
+ // @vibesdotdev/storage-adapter-drizzle/transforms directly.
31
+
32
+ /**
33
+ * Minimal shape required from the runtime for transform resolution.
34
+ * Avoids a hard import of `VibesRuntime` so this module stays
35
+ * dependency-light.
36
+ */
37
+ interface RuntimeForTransform {
38
+ query(kind: string): {
39
+ withId(id: string): {
40
+ firstDescriptor?: () => StorageTransformDescriptor | null;
41
+ resolve?: () => Promise<unknown> | unknown;
42
+ };
43
+ };
44
+ }
45
+
46
+ export interface CreateStorageTransformOptions<TRow, TDescriptor> {
47
+ /** Stable id, typically `<manifest-id>` (e.g. `'ai.providers'`). */
48
+ id: string;
49
+ /** Storage manifest this transform is paired with. */
50
+ manifestId?: string;
51
+ /** Human description for diagnostics. */
52
+ description?: string;
53
+ /** Row → descriptor mapping (read path). */
54
+ fromRow: (row: TRow) => TDescriptor;
55
+ /** Descriptor → row mapping (write path). Omit for read-only manifests. */
56
+ toRow?: (descriptor: Partial<TDescriptor>) => Partial<TRow>;
57
+ }
58
+
59
+ /**
60
+ * Build the descriptor + runtime implementation pair for a transform.
61
+ *
62
+ * Usage from an app-local plugin / hook:
63
+ *
64
+ * ```ts
65
+ * const aiProvidersTransform = createStorageTransform<ProviderRow, ProviderDescriptor>({
66
+ * id: 'ai.providers',
67
+ * manifestId: 'ai.providers',
68
+ * fromRow: (row) => ({ id: row.id, kind: 'ai/provider', ... }),
69
+ * toRow: (d) => ({ name: d.name, ... })
70
+ * });
71
+ *
72
+ * runtime.registerDescriptor('storage/transform', aiProvidersTransform.descriptor);
73
+ * runtime.registerLoader(
74
+ * 'storage/transform',
75
+ * aiProvidersTransform.descriptor.id,
76
+ * async () => aiProvidersTransform.implementation
77
+ * );
78
+ * ```
79
+ */
80
+ export function createStorageTransform<TRow, TDescriptor>(
81
+ options: CreateStorageTransformOptions<TRow, TDescriptor>
82
+ ): {
83
+ descriptor: StorageTransformDescriptor;
84
+ implementation: RuntimeImplementationWrapper<StorageTransformImplementation<TRow, TDescriptor>>;
85
+ } {
86
+ const direction = options.toRow ? 'bidirectional' : 'read';
87
+ const descriptor = StorageTransformDescriptorSchema.parse({
88
+ kind: 'storage/transform',
89
+ id: options.id,
90
+ manifestId: options.manifestId,
91
+ description: options.description,
92
+ direction
93
+ });
94
+
95
+ const impl: StorageTransformImplementation<TRow, TDescriptor> = options.toRow
96
+ ? { fromRow: options.fromRow, toRow: options.toRow }
97
+ : { fromRow: options.fromRow };
98
+
99
+ const implementation = createRuntimeImplementation({
100
+ id: descriptor.id,
101
+ kind: 'storage/transform',
102
+ implementation: impl
103
+ }) as RuntimeImplementationWrapper<StorageTransformImplementation<TRow, TDescriptor>>;
104
+
105
+ return { descriptor, implementation };
106
+ }
107
+
108
+ /**
109
+ * Resolve a transform's live implementation from the runtime by id.
110
+ *
111
+ * Returns `null` when no transform is registered for the id — callers
112
+ * should treat that as "no row↔descriptor mapping configured" and fall
113
+ * back to identity (the row IS the descriptor wire shape).
114
+ */
115
+ export async function resolveStorageTransform<TRow = unknown, TDescriptor = unknown>(
116
+ runtime: RuntimeForTransform,
117
+ id: string
118
+ ): Promise<StorageTransformImplementation<TRow, TDescriptor> | null> {
119
+ const scoped = runtime.query('storage/transform').withId(id);
120
+ if (typeof scoped.resolve !== 'function') return null;
121
+ try {
122
+ const resolved = await scoped.resolve();
123
+ if (!resolved || typeof resolved !== 'object') return null;
124
+ const impl = resolved as Partial<StorageTransformImplementation<TRow, TDescriptor>>;
125
+ if (typeof impl.fromRow !== 'function') return null;
126
+ return impl as StorageTransformImplementation<TRow, TDescriptor>;
127
+ } catch {
128
+ return null;
129
+ }
130
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Storage Transform Descriptor Schema
3
+ *
4
+ * Descriptors for `storage/transform` runtime kind. A transform converts
5
+ * between a storage-adapter row shape (e.g. a Drizzle row from `model_providers`)
6
+ * and the manifest's wire-shape descriptor (e.g. `AIProviderDescriptor`).
7
+ *
8
+ * The descriptor is data (id + metadata); the actual `fromRow` / `toRow`
9
+ * functions live in the runtime implementation registered via
10
+ * `runtime.registerLoader('storage/transform', id, ...)`. This split keeps
11
+ * descriptors serializable while implementations can hold closures.
12
+ */
13
+
14
+ import * as z from 'zod/v4';
15
+ import { RuntimeDescriptorSchema } from '@vibesdotdev/runtime/schemas/descriptor';
16
+
17
+ export const StorageTransformDescriptorSchema = RuntimeDescriptorSchema.extend({
18
+ kind: z.literal('storage/transform'),
19
+
20
+ /**
21
+ * Optional binding to a `storage/manifest` descriptor — most transforms
22
+ * exist to serve one specific manifest. Helpers can verify that the
23
+ * caller's descriptor matches when resolving by id.
24
+ */
25
+ manifestId: z.string().optional(),
26
+
27
+ /**
28
+ * Direction this transform supports. `'bidirectional'` is the common
29
+ * case (DB row ↔ wire descriptor); `'read'` means the manifest is
30
+ * read-only over HTTP (no write-path mapping needed).
31
+ */
32
+ direction: z.enum(['read', 'write', 'bidirectional']).default('bidirectional')
33
+ });
34
+
35
+ export type StorageTransformDescriptor = z.infer<typeof StorageTransformDescriptorSchema>;
36
+
37
+ /**
38
+ * Runtime implementation interface for `storage/transform`.
39
+ *
40
+ * `TRow` is the storage adapter's native row shape (a Drizzle `$inferSelect`
41
+ * type for `storage.drizzle.*`, a JSON-blob shape for `storage.json`, etc.).
42
+ * `TDescriptor` is the wire-shape descriptor consumed by manifests and
43
+ * exposed to cross-app callers via `vibesCrudCollection`.
44
+ */
45
+ export interface StorageTransformImplementation<TRow = unknown, TDescriptor = unknown> {
46
+ /** Map a single row from the storage adapter into a wire-shape descriptor. */
47
+ fromRow(row: TRow): TDescriptor;
48
+ /**
49
+ * Map a wire-shape descriptor (or partial patch) into an adapter row
50
+ * shape suitable for insert/update. Omit for read-only transforms.
51
+ */
52
+ toRow?(descriptor: Partial<TDescriptor>): Partial<TRow>;
53
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Storage Explorer — tui/app descriptor
3
+ *
4
+ * Interactive storage browser for inspecting adapter health,
5
+ * browsing namespaces, and viewing stored entries.
6
+ *
7
+ * NOTE: The actual TUI types (TuiAppDescriptor) live in @vibesdotdev/tui, but
8
+ * storage must not depend on tui in production (that would re-create the cycle).
9
+ * We declare the shape inline here using the base RuntimeDescriptor-compatible fields.
10
+ */
11
+
12
+ import type { RuntimeDescriptor } from '@vibesdotdev/runtime';
13
+
14
+ const descriptor: RuntimeDescriptor & Record<string, unknown> = {
15
+ kind: 'tui/app',
16
+ id: 'storage.explorer',
17
+ name: 'Storage Explorer',
18
+ description: 'Inspect storage adapters, namespaces, and persisted runtime data.',
19
+ tags: ['system', 'ops'],
20
+ // TUI-specific fields passed through as opaque data
21
+ title: 'Storage Explorer',
22
+ icon: '🗄',
23
+ category: 'System',
24
+ audience: 'ops',
25
+ order: 5,
26
+ route: '/storage',
27
+ sidebar: true,
28
+ embeddable: true,
29
+ enabled: true
30
+ } as RuntimeDescriptor & Record<string, unknown>;
31
+
32
+ export default descriptor;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Storage Explorer TUI implementation (consumer stub).
3
+ *
4
+ * The actual implementation requires @vibesdotdev/tui components.
5
+ * This stub is loaded at runtime only when the TUI stack is present.
6
+ * When TUI is not available, the onRegister hook in storage.plugin.ts
7
+ * skips registration entirely via runtime.hasKind('tui/app').
8
+ */
9
+
10
+ const implementation: Record<string, unknown> = {
11
+ render: () => ({ type: 'placeholder', message: 'Storage Explorer requires TUI runtime' })
12
+ };
13
+
14
+ export default implementation;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Storage Open — tui/command descriptor
3
+ *
4
+ * Navigates to the Storage Explorer.
5
+ * Triggered via /storage slash command or keybinding.
6
+ *
7
+ * NOTE: The actual TUI types (TuiCommandDescriptor) live in @vibesdotdev/tui, but
8
+ * storage must not depend on tui in production (that would re-create the cycle).
9
+ * We declare the shape inline here using the base RuntimeDescriptor-compatible fields.
10
+ */
11
+
12
+ import type { RuntimeDescriptor } from '@vibesdotdev/runtime';
13
+
14
+ const descriptor: RuntimeDescriptor & Record<string, unknown> = {
15
+ kind: 'tui/command',
16
+ id: 'storage.open',
17
+ title: 'Open Storage Explorer',
18
+ name: 'Open Storage Explorer',
19
+ description: 'Navigate to the Storage Explorer',
20
+ tags: ['navigation'],
21
+ // TUI-specific fields passed through as opaque data
22
+ trigger: '/storage',
23
+ aliases: ['/store', '/db'],
24
+ category: 'Navigation',
25
+ keybinding: 'g then d',
26
+ acceptsArgs: false,
27
+ order: 5,
28
+ enabled: true
29
+ } as RuntimeDescriptor & Record<string, unknown>;
30
+
31
+ export default descriptor;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Storage Open TUI command implementation (consumer stub).
3
+ *
4
+ * The actual implementation requires @vibesdotdev/tui components.
5
+ * This stub is loaded at runtime only when the TUI stack is present.
6
+ * When TUI is not available, the onRegister hook in storage.plugin.ts
7
+ * skips registration entirely via runtime.hasKind('tui/command').
8
+ */
9
+
10
+ const implementation: Record<string, unknown> = {
11
+ execute: () => ({ type: 'navigate', route: '/storage' })
12
+ };
13
+
14
+ export default implementation;
@@ -0,0 +1,19 @@
1
+ export function toErrorContext(error: unknown): Record<string, unknown> | undefined {
2
+ if (error instanceof Error) {
3
+ return {
4
+ error: error.message,
5
+ name: error.name,
6
+ stack: error.stack
7
+ };
8
+ }
9
+
10
+ if (typeof error === 'object' && error !== null && !Array.isArray(error)) {
11
+ return error as Record<string, unknown>;
12
+ }
13
+
14
+ if (error === undefined) {
15
+ return undefined;
16
+ }
17
+
18
+ return { error: String(error) };
19
+ }