rivet-design 0.16.2 → 0.17.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 (279) hide show
  1. package/README.md +8 -2
  2. package/README.npm.md +8 -2
  3. package/bin/rivet.js +15 -7
  4. package/dist/agent-variants/variantContext.d.ts +1 -0
  5. package/dist/agent-variants/variantContext.d.ts.map +1 -1
  6. package/dist/agent-variants/variantContext.js +1 -1
  7. package/dist/agent-variants/variantContext.js.map +1 -1
  8. package/dist/cli/commandNames.d.ts +2 -0
  9. package/dist/cli/commandNames.d.ts.map +1 -1
  10. package/dist/cli/commandNames.js +16 -1
  11. package/dist/cli/commandNames.js.map +1 -1
  12. package/dist/cli/commands/libraryOpen.d.ts +10 -0
  13. package/dist/cli/commands/libraryOpen.d.ts.map +1 -0
  14. package/dist/cli/commands/libraryOpen.js +126 -0
  15. package/dist/cli/commands/libraryOpen.js.map +1 -0
  16. package/dist/cli/commands/open.d.ts +39 -0
  17. package/dist/cli/commands/open.d.ts.map +1 -1
  18. package/dist/cli/commands/open.js +35 -21
  19. package/dist/cli/commands/open.js.map +1 -1
  20. package/dist/cli/commands/serve.d.ts.map +1 -1
  21. package/dist/cli/commands/serve.js +33 -0
  22. package/dist/cli/commands/serve.js.map +1 -1
  23. package/dist/cli/router.d.ts.map +1 -1
  24. package/dist/cli/router.js +34 -3
  25. package/dist/cli/router.js.map +1 -1
  26. package/dist/cli/serverHandshake.d.ts +7 -5
  27. package/dist/cli/serverHandshake.d.ts.map +1 -1
  28. package/dist/cli/serverHandshake.js +16 -12
  29. package/dist/cli/serverHandshake.js.map +1 -1
  30. package/dist/install/installationChannel.d.ts +4 -0
  31. package/dist/install/installationChannel.d.ts.map +1 -0
  32. package/dist/install/installationChannel.js +13 -0
  33. package/dist/install/installationChannel.js.map +1 -0
  34. package/dist/library/HubClient.d.ts +12 -0
  35. package/dist/library/HubClient.d.ts.map +1 -0
  36. package/dist/library/HubClient.js +109 -0
  37. package/dist/library/HubClient.js.map +1 -0
  38. package/dist/library/HubServer.d.ts +16 -0
  39. package/dist/library/HubServer.d.ts.map +1 -0
  40. package/dist/library/HubServer.js +95 -0
  41. package/dist/library/HubServer.js.map +1 -0
  42. package/dist/library/StaticPreviewServer.d.ts +7 -0
  43. package/dist/library/StaticPreviewServer.d.ts.map +1 -0
  44. package/dist/library/StaticPreviewServer.js +18 -0
  45. package/dist/library/StaticPreviewServer.js.map +1 -0
  46. package/dist/library/http.d.ts +11 -0
  47. package/dist/library/http.d.ts.map +1 -0
  48. package/dist/library/http.js +31 -0
  49. package/dist/library/http.js.map +1 -0
  50. package/dist/library/importFiles.d.ts +18 -0
  51. package/dist/library/importFiles.d.ts.map +1 -0
  52. package/dist/library/importFiles.js +184 -0
  53. package/dist/library/importFiles.js.map +1 -0
  54. package/dist/proxy-middleware/preview-bridge.d.ts.map +1 -1
  55. package/dist/proxy-middleware/preview-bridge.js +6 -16
  56. package/dist/proxy-middleware/preview-bridge.js.map +1 -1
  57. package/dist/routes/account.d.ts +4 -0
  58. package/dist/routes/account.d.ts.map +1 -0
  59. package/dist/routes/account.js +53 -0
  60. package/dist/routes/account.js.map +1 -0
  61. package/dist/routes/agentVariants.d.ts +2 -13
  62. package/dist/routes/agentVariants.d.ts.map +1 -1
  63. package/dist/routes/agentVariants.js +53 -79
  64. package/dist/routes/agentVariants.js.map +1 -1
  65. package/dist/routes/library/app.d.ts +8 -0
  66. package/dist/routes/library/app.d.ts.map +1 -0
  67. package/dist/routes/library/app.js +26 -0
  68. package/dist/routes/library/app.js.map +1 -0
  69. package/dist/routes/library/index.d.ts +5 -0
  70. package/dist/routes/library/index.d.ts.map +1 -0
  71. package/dist/routes/library/index.js +32 -0
  72. package/dist/routes/library/index.js.map +1 -0
  73. package/dist/routes/library/middleware.d.ts +9 -0
  74. package/dist/routes/library/middleware.d.ts.map +1 -0
  75. package/dist/routes/library/middleware.js +58 -0
  76. package/dist/routes/library/middleware.js.map +1 -0
  77. package/dist/routes/library/navigation.d.ts +5 -0
  78. package/dist/routes/library/navigation.d.ts.map +1 -0
  79. package/dist/routes/library/navigation.js +39 -0
  80. package/dist/routes/library/navigation.js.map +1 -0
  81. package/dist/routes/library/projects.d.ts +5 -0
  82. package/dist/routes/library/projects.d.ts.map +1 -0
  83. package/dist/routes/library/projects.js +42 -0
  84. package/dist/routes/library/projects.js.map +1 -0
  85. package/dist/routes/library/schemas.d.ts +23 -0
  86. package/dist/routes/library/schemas.d.ts.map +1 -0
  87. package/dist/routes/library/schemas.js +10 -0
  88. package/dist/routes/library/schemas.js.map +1 -0
  89. package/dist/routes/library/staticPreview.d.ts +4 -0
  90. package/dist/routes/library/staticPreview.d.ts.map +1 -0
  91. package/dist/routes/library/staticPreview.js +39 -0
  92. package/dist/routes/library/staticPreview.js.map +1 -0
  93. package/dist/routes/library/types.d.ts +22 -0
  94. package/dist/routes/library/types.d.ts.map +1 -0
  95. package/dist/routes/library/types.js +3 -0
  96. package/dist/routes/library/types.js.map +1 -0
  97. package/dist/routes/library/variants.d.ts +5 -0
  98. package/dist/routes/library/variants.d.ts.map +1 -0
  99. package/dist/routes/library/variants.js +35 -0
  100. package/dist/routes/library/variants.js.map +1 -0
  101. package/dist/server.d.ts +2 -0
  102. package/dist/server.d.ts.map +1 -1
  103. package/dist/server.js +18 -30
  104. package/dist/server.js.map +1 -1
  105. package/dist/services/HistoryReplayService.js +1 -1
  106. package/dist/services/HistoryReplayService.js.map +1 -1
  107. package/dist/services/HubDiscovery.d.ts +46 -0
  108. package/dist/services/HubDiscovery.d.ts.map +1 -0
  109. package/dist/services/HubDiscovery.js +58 -0
  110. package/dist/services/HubDiscovery.js.map +1 -0
  111. package/dist/services/HubNavigation.d.ts +36 -0
  112. package/dist/services/HubNavigation.d.ts.map +1 -0
  113. package/dist/services/HubNavigation.js +76 -0
  114. package/dist/services/HubNavigation.js.map +1 -0
  115. package/dist/services/ProjectCardPreviews.d.ts +27 -0
  116. package/dist/services/ProjectCardPreviews.d.ts.map +1 -0
  117. package/dist/services/ProjectCardPreviews.js +112 -0
  118. package/dist/services/ProjectCardPreviews.js.map +1 -0
  119. package/dist/services/ProjectFolderPicker.d.ts +20 -0
  120. package/dist/services/ProjectFolderPicker.d.ts.map +1 -0
  121. package/dist/services/ProjectFolderPicker.js +174 -0
  122. package/dist/services/ProjectFolderPicker.js.map +1 -0
  123. package/dist/services/ProjectImport.d.ts +13 -0
  124. package/dist/services/ProjectImport.d.ts.map +1 -0
  125. package/dist/services/ProjectImport.js +226 -0
  126. package/dist/services/ProjectImport.js.map +1 -0
  127. package/dist/services/ProjectLibrary.d.ts +74 -0
  128. package/dist/services/ProjectLibrary.d.ts.map +1 -0
  129. package/dist/services/ProjectLibrary.js +261 -0
  130. package/dist/services/ProjectLibrary.js.map +1 -0
  131. package/dist/services/ProjectMetadataStore.d.ts +6 -19
  132. package/dist/services/ProjectMetadataStore.d.ts.map +1 -1
  133. package/dist/services/ProjectMetadataStore.js +29 -147
  134. package/dist/services/ProjectMetadataStore.js.map +1 -1
  135. package/dist/services/ProjectRegistry.d.ts +80 -0
  136. package/dist/services/ProjectRegistry.d.ts.map +1 -0
  137. package/dist/services/ProjectRegistry.js +147 -0
  138. package/dist/services/ProjectRegistry.js.map +1 -0
  139. package/dist/services/ProjectRuntimeService.d.ts +18 -0
  140. package/dist/services/ProjectRuntimeService.d.ts.map +1 -0
  141. package/dist/services/ProjectRuntimeService.js +143 -0
  142. package/dist/services/ProjectRuntimeService.js.map +1 -0
  143. package/dist/services/ProjectScreenshotService.d.ts +15 -0
  144. package/dist/services/ProjectScreenshotService.d.ts.map +1 -0
  145. package/dist/services/ProjectScreenshotService.js +90 -0
  146. package/dist/services/ProjectScreenshotService.js.map +1 -0
  147. package/dist/services/ProjectStorage.d.ts +20 -0
  148. package/dist/services/ProjectStorage.d.ts.map +1 -0
  149. package/dist/services/ProjectStorage.js +41 -0
  150. package/dist/services/ProjectStorage.js.map +1 -0
  151. package/dist/services/StaticLibraryPreviews.d.ts +21 -0
  152. package/dist/services/StaticLibraryPreviews.d.ts.map +1 -0
  153. package/dist/services/StaticLibraryPreviews.js +61 -0
  154. package/dist/services/StaticLibraryPreviews.js.map +1 -0
  155. package/dist/services/TelemetryService.d.ts +7 -0
  156. package/dist/services/TelemetryService.d.ts.map +1 -1
  157. package/dist/services/TelemetryService.js +7 -1
  158. package/dist/services/TelemetryService.js.map +1 -1
  159. package/dist/services/TreeStore.d.ts +8 -3
  160. package/dist/services/TreeStore.d.ts.map +1 -1
  161. package/dist/services/TreeStore.js +39 -18
  162. package/dist/services/TreeStore.js.map +1 -1
  163. package/dist/services/VariantGenerationService.d.ts +5 -0
  164. package/dist/services/VariantGenerationService.d.ts.map +1 -1
  165. package/dist/services/VariantGenerationService.js +13 -1
  166. package/dist/services/VariantGenerationService.js.map +1 -1
  167. package/dist/services/VariantHistoryService.d.ts +18 -162
  168. package/dist/services/VariantHistoryService.d.ts.map +1 -1
  169. package/dist/services/VariantHistoryService.js +187 -45
  170. package/dist/services/VariantHistoryService.js.map +1 -1
  171. package/dist/services/VariantRunService.d.ts +3 -0
  172. package/dist/services/VariantRunService.d.ts.map +1 -1
  173. package/dist/services/VariantRunService.js +2 -0
  174. package/dist/services/VariantRunService.js.map +1 -1
  175. package/dist/services/VariantsRuntime.d.ts +4 -0
  176. package/dist/services/VariantsRuntime.d.ts.map +1 -1
  177. package/dist/services/VariantsRuntime.js +6 -1
  178. package/dist/services/VariantsRuntime.js.map +1 -1
  179. package/dist/services/createAgentVariantsOrchestrator.d.ts +2 -0
  180. package/dist/services/createAgentVariantsOrchestrator.d.ts.map +1 -1
  181. package/dist/services/createAgentVariantsOrchestrator.js +1 -0
  182. package/dist/services/createAgentVariantsOrchestrator.js.map +1 -1
  183. package/dist/services/historyRoots.d.ts +14 -0
  184. package/dist/services/historyRoots.d.ts.map +1 -0
  185. package/dist/services/historyRoots.js +44 -0
  186. package/dist/services/historyRoots.js.map +1 -0
  187. package/dist/services/libraryErrors.d.ts +7 -0
  188. package/dist/services/libraryErrors.d.ts.map +1 -0
  189. package/dist/services/libraryErrors.js +14 -0
  190. package/dist/services/libraryErrors.js.map +1 -0
  191. package/dist/storage/library/BundleMetadataStore.d.ts +53 -0
  192. package/dist/storage/library/BundleMetadataStore.d.ts.map +1 -0
  193. package/dist/storage/library/BundleMetadataStore.js +317 -0
  194. package/dist/storage/library/BundleMetadataStore.js.map +1 -0
  195. package/dist/storage/library/CoordinatorRecords.d.ts +25 -0
  196. package/dist/storage/library/CoordinatorRecords.d.ts.map +1 -0
  197. package/dist/storage/library/CoordinatorRecords.js +84 -0
  198. package/dist/storage/library/CoordinatorRecords.js.map +1 -0
  199. package/dist/storage/library/ProjectPreviewCache.d.ts +34 -0
  200. package/dist/storage/library/ProjectPreviewCache.d.ts.map +1 -0
  201. package/dist/storage/library/ProjectPreviewCache.js +62 -0
  202. package/dist/storage/library/ProjectPreviewCache.js.map +1 -0
  203. package/dist/storage/library/ProjectRecords.d.ts +64 -0
  204. package/dist/storage/library/ProjectRecords.d.ts.map +1 -0
  205. package/dist/storage/library/ProjectRecords.js +139 -0
  206. package/dist/storage/library/ProjectRecords.js.map +1 -0
  207. package/dist/storage/library/database.d.ts +13 -0
  208. package/dist/storage/library/database.d.ts.map +1 -0
  209. package/dist/storage/library/database.js +106 -0
  210. package/dist/storage/library/database.js.map +1 -0
  211. package/dist/storage/library/migrations.d.ts +5 -0
  212. package/dist/storage/library/migrations.d.ts.map +1 -0
  213. package/dist/storage/library/migrations.js +61 -0
  214. package/dist/storage/library/migrations.js.map +1 -0
  215. package/dist/storage/library/schema/bundle.d.ts +734 -0
  216. package/dist/storage/library/schema/bundle.d.ts.map +1 -0
  217. package/dist/storage/library/schema/bundle.js +79 -0
  218. package/dist/storage/library/schema/bundle.js.map +1 -0
  219. package/dist/storage/library/schema/coordinator.d.ts +72 -0
  220. package/dist/storage/library/schema/coordinator.d.ts.map +1 -0
  221. package/dist/storage/library/schema/coordinator.js +12 -0
  222. package/dist/storage/library/schema/coordinator.js.map +1 -0
  223. package/dist/storage/library/schema/registry.d.ts +198 -0
  224. package/dist/storage/library/schema/registry.d.ts.map +1 -0
  225. package/dist/storage/library/schema/registry.js +32 -0
  226. package/dist/storage/library/schema/registry.js.map +1 -0
  227. package/dist/storage/library/sourcePresentation.d.ts +3 -0
  228. package/dist/storage/library/sourcePresentation.d.ts.map +1 -0
  229. package/dist/storage/library/sourcePresentation.js +70 -0
  230. package/dist/storage/library/sourcePresentation.js.map +1 -0
  231. package/dist/storage/project-metadata/ProjectMetadataRecords.d.ts +41 -0
  232. package/dist/storage/project-metadata/ProjectMetadataRecords.d.ts.map +1 -0
  233. package/dist/storage/project-metadata/ProjectMetadataRecords.js +120 -0
  234. package/dist/storage/project-metadata/ProjectMetadataRecords.js.map +1 -0
  235. package/dist/storage/project-metadata/database.d.ts +12 -0
  236. package/dist/storage/project-metadata/database.d.ts.map +1 -0
  237. package/dist/storage/project-metadata/database.js +79 -0
  238. package/dist/storage/project-metadata/database.js.map +1 -0
  239. package/dist/{services/projectMetadataMigrations.d.ts → storage/project-metadata/migrations.d.ts} +1 -1
  240. package/dist/storage/project-metadata/migrations.d.ts.map +1 -0
  241. package/dist/{services/projectMetadataMigrations.js → storage/project-metadata/migrations.js} +1 -1
  242. package/dist/storage/project-metadata/migrations.js.map +1 -0
  243. package/dist/storage/project-metadata/schema.d.ts +288 -0
  244. package/dist/storage/project-metadata/schema.d.ts.map +1 -0
  245. package/dist/storage/project-metadata/schema.js +35 -0
  246. package/dist/storage/project-metadata/schema.js.map +1 -0
  247. package/dist/types/account.d.ts +8 -0
  248. package/dist/types/account.d.ts.map +1 -0
  249. package/dist/types/account.js +3 -0
  250. package/dist/types/account.js.map +1 -0
  251. package/dist/types/project-library.d.ts +28 -0
  252. package/dist/types/project-library.d.ts.map +1 -0
  253. package/dist/types/project-library.js +3 -0
  254. package/dist/types/project-library.js.map +1 -0
  255. package/dist/types/variant-history.d.ts +173 -0
  256. package/dist/types/variant-history.d.ts.map +1 -0
  257. package/dist/types/variant-history.js +3 -0
  258. package/dist/types/variant-history.js.map +1 -0
  259. package/dist/utils/htmlDocument.d.ts +13 -0
  260. package/dist/utils/htmlDocument.d.ts.map +1 -0
  261. package/dist/utils/htmlDocument.js +42 -0
  262. package/dist/utils/htmlDocument.js.map +1 -0
  263. package/dist/utils/windowPlacement.d.ts +20 -0
  264. package/dist/utils/windowPlacement.d.ts.map +1 -0
  265. package/dist/utils/windowPlacement.js +20 -0
  266. package/dist/utils/windowPlacement.js.map +1 -0
  267. package/package.json +10 -3
  268. package/scripts/verify-node-version.cjs +9 -6
  269. package/src/ui/dist/assets/LibraryApp-B2MZyxIp.js +16 -0
  270. package/src/ui/dist/assets/main-1IMq5Huu.css +1 -0
  271. package/src/ui/dist/assets/main-BId3Sa7r.js +438 -0
  272. package/src/ui/dist/favicon-16.png +0 -0
  273. package/src/ui/dist/favicon-32.png +0 -0
  274. package/src/ui/dist/favicon.ico +0 -0
  275. package/src/ui/dist/index.html +2 -2
  276. package/dist/services/projectMetadataMigrations.d.ts.map +0 -1
  277. package/dist/services/projectMetadataMigrations.js.map +0 -1
  278. package/src/ui/dist/assets/main-BjwDfDy8.js +0 -423
  279. package/src/ui/dist/assets/main-Ct1aZend.css +0 -1
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ProjectLibrary = exports.currentLibraryRoot = void 0;
7
+ const libraryErrors_1 = require("./libraryErrors");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const installationChannel_1 = require("../install/installationChannel");
10
+ const path_1 = __importDefault(require("path"));
11
+ const ProjectRegistry_1 = require("./ProjectRegistry");
12
+ const ProjectImport_1 = require("./ProjectImport");
13
+ const BundleMetadataStore_1 = require("../storage/library/BundleMetadataStore");
14
+ const ProjectStorage_1 = require("./ProjectStorage");
15
+ const TreeStore_1 = require("./TreeStore");
16
+ const VariantHistoryService_1 = require("./VariantHistoryService");
17
+ const historyRoots_1 = require("./historyRoots");
18
+ /** Resolves the installation's library root, with explicit isolated roots for automation. */
19
+ const currentLibraryRoot = (env = process.env) => {
20
+ const channel = (0, installationChannel_1.installationChannel)(env);
21
+ return env.RIVET_LIBRARY_ROOT
22
+ ? path_1.default.resolve(env.RIVET_LIBRARY_ROOT)
23
+ : (0, ProjectRegistry_1.libraryRoot)({ channel });
24
+ };
25
+ exports.currentLibraryRoot = currentLibraryRoot;
26
+ /** Serves project-scoped saved history without starting application runtimes. */
27
+ class ProjectLibrary {
28
+ registry;
29
+ owners = new Map();
30
+ issues = new Map();
31
+ isClosed = false;
32
+ constructor(registry) {
33
+ this.registry = registry;
34
+ }
35
+ /** Opens the project library independently of any selected workspace. */
36
+ static async open(root = (0, exports.currentLibraryRoot)()) {
37
+ return new ProjectLibrary(await ProjectRegistry_1.ProjectRegistry.open(root));
38
+ }
39
+ /** Registers an opened project and imports its quiescent supported history. */
40
+ async prepare(projectPath) {
41
+ const project = this.registry.register({ projectPath });
42
+ for (const nested of (0, historyRoots_1.nestedFreshSessionWorkdirs)(project.projectPath))
43
+ this.registry.attachHistoryRoot({
44
+ projectId: project.id,
45
+ projectPath: nested,
46
+ });
47
+ let migration;
48
+ try {
49
+ migration = await (0, ProjectImport_1.importProject)({
50
+ registry: this.registry,
51
+ projectId: project.id,
52
+ });
53
+ }
54
+ catch (error) {
55
+ // Unimportable saved history never blocks opening the working folder;
56
+ // the project keeps its project-local storage and reports the failure.
57
+ migration = {
58
+ status: 'deferred',
59
+ reason: error instanceof Error ? error.message : String(error),
60
+ };
61
+ }
62
+ if (project.storageKind !== this.registry.get(project.id).storageKind)
63
+ await this.invalidate(project.id);
64
+ if (migration.status === 'diverged' || migration.status === 'deferred')
65
+ this.issues.set(project.id, migration.reason ??
66
+ 'Preserved source history differs from the imported bundle');
67
+ return { project: this.registry.get(project.id), migration };
68
+ }
69
+ /** Relinks a working folder and refreshes its storage attachment. */
70
+ async relink(args) {
71
+ const project = this.registry.relink(args);
72
+ await this.invalidate(project.id);
73
+ this.issues.delete(project.id);
74
+ return project;
75
+ }
76
+ /** Closes cached metadata before changing the project's storage attachment. */
77
+ async invalidate(projectId) {
78
+ const pending = this.owners.get(projectId);
79
+ this.owners.delete(projectId);
80
+ if (!pending)
81
+ return;
82
+ const owner = await pending;
83
+ owner.history.metadata.closeAll();
84
+ owner.bundle?.close();
85
+ }
86
+ /** Lists registered workspaces and known issues without opening saved history. */
87
+ listProjects() {
88
+ return this.registry
89
+ .list()
90
+ .map((project) => ({ ...project, issue: this.issues.get(project.id) }));
91
+ }
92
+ /** Builds the library view from saved history and current workspace availability. */
93
+ async snapshot() {
94
+ const variants = await this.listVariants();
95
+ return {
96
+ projects: this.listProjects(),
97
+ variants: variants.map(({ projectId, manifest, hasStaticPreview }) => ({
98
+ projectId,
99
+ sessionId: manifest.sessionId,
100
+ variantId: manifest.variantId,
101
+ label: manifest.label,
102
+ brief: manifest.brief,
103
+ createdAt: manifest.createdAt,
104
+ hasStaticPreview,
105
+ hasInteractivePreview: manifest.serve?.kind === 'dev-server',
106
+ })),
107
+ };
108
+ }
109
+ /** Applies metadata edits through the exact direction's authoritative history owner. */
110
+ async updateVariant(args) {
111
+ const found = await this.variant(args);
112
+ if (!found)
113
+ throw new libraryErrors_1.LibraryError('variant_not_found', 'Unknown saved direction');
114
+ const target = { ...args, projectPath: found.projectPath };
115
+ if (args.label !== undefined)
116
+ await found.history.renameVariant({ ...target, label: args.label });
117
+ if (args.status)
118
+ await found.history.markStatus({ ...target, status: args.status });
119
+ }
120
+ /** Verifies the selected project and saved direction before delivering navigation. */
121
+ async assertNavigationTarget(target) {
122
+ if (target.projectId)
123
+ this.registry.get(target.projectId);
124
+ if (target.projectId &&
125
+ target.sessionId &&
126
+ target.variantId &&
127
+ !(await this.variant({
128
+ projectId: target.projectId,
129
+ sessionId: target.sessionId,
130
+ variantId: target.variantId,
131
+ })))
132
+ throw new libraryErrors_1.LibraryError('variant_not_found', 'Unknown saved direction');
133
+ }
134
+ /** Returns one shared history service for a project's persisted storage owner. */
135
+ async history(projectId) {
136
+ return (await this.owner(projectId)).history;
137
+ }
138
+ /** Registers a generated directory with the same history owner before generation writes. */
139
+ async attachGeneratedRoot({ projectId, projectPath, }) {
140
+ fs_1.default.mkdirSync(projectPath, { recursive: true });
141
+ this.registry.attachHistoryRoot({ projectId, projectPath });
142
+ const owner = await this.owner(projectId);
143
+ if (!owner.bundle)
144
+ return;
145
+ const dataDirectory = this.registry.bundleDirectory(projectId);
146
+ for (const root of new Set([
147
+ path_1.default.resolve(projectPath),
148
+ fs_1.default.realpathSync(projectPath),
149
+ ])) {
150
+ owner.storage.attach({
151
+ projectPath: root,
152
+ dataDirectory,
153
+ cacheDirectory: path_1.default.join(this.registry.root, 'cache', projectId),
154
+ });
155
+ }
156
+ }
157
+ /** Lists one project's directions, including preserved generated history roots. */
158
+ async listProject(projectId) {
159
+ const project = this.registry.get(projectId);
160
+ if (!project.isAvailable && project.storageKind === 'project')
161
+ throw new Error('Working folder and project-local history are unavailable');
162
+ const history = await this.history(projectId);
163
+ const roots = project.storageKind === 'bundle'
164
+ ? [project.projectPath]
165
+ : this.registry.historyRoots(projectId);
166
+ const entries = (await Promise.all(roots.map(async (projectPath) => (await history.listVariantsFromIndex({ projectPath })).map((entry) => ({ ...entry, projectId, projectPath }))))).flat();
167
+ const unique = new Map();
168
+ for (const entry of entries) {
169
+ if (entry.manifest.status === 'removed' ||
170
+ entry.manifest.status === 'cancelled')
171
+ continue;
172
+ const key = `${entry.manifest.sessionId}:${entry.manifest.variantId}`;
173
+ const existing = unique.get(key);
174
+ if (existing &&
175
+ JSON.stringify(existing.manifest) !== JSON.stringify(entry.manifest))
176
+ throw new Error('Conflicting history identities across attached roots');
177
+ unique.set(key, entry);
178
+ }
179
+ return [...unique.values()];
180
+ }
181
+ /** Aggregates readable projects while retaining individual project availability errors. */
182
+ async listVariants(projectId) {
183
+ if (projectId)
184
+ return this.listProject(projectId);
185
+ const projects = this.registry.list();
186
+ const results = await Promise.allSettled(projects.map((project) => this.listProject(project.id)));
187
+ return results
188
+ .flatMap((result, index) => {
189
+ if (result.status === 'fulfilled')
190
+ return result.value;
191
+ this.issues.set(projects[index].id, result.reason instanceof Error
192
+ ? result.reason.message
193
+ : String(result.reason));
194
+ return [];
195
+ })
196
+ .sort((a, b) => b.manifest.createdAt.localeCompare(a.manifest.createdAt));
197
+ }
198
+ /** Resolves an exact reference together with the filesystem root that owns it. */
199
+ async variant(reference) {
200
+ const project = this.registry.get(reference.projectId);
201
+ const history = await this.history(project.id);
202
+ const roots = project.storageKind === 'bundle'
203
+ ? [project.projectPath]
204
+ : this.registry.historyRoots(project.id);
205
+ for (const projectPath of roots) {
206
+ const detail = await history.getVariant({ ...reference, projectPath });
207
+ if (detail)
208
+ return { detail, projectPath, history };
209
+ }
210
+ return null;
211
+ }
212
+ /** Releases metadata connections; running project processes have separate lifetimes. */
213
+ close() {
214
+ if (this.isClosed)
215
+ return;
216
+ this.isClosed = true;
217
+ for (const owner of this.owners.values())
218
+ void owner.then((value) => {
219
+ value.history.metadata.closeAll();
220
+ value.bundle?.close();
221
+ }, () => undefined);
222
+ this.registry.close();
223
+ }
224
+ /** Initializes one storage owner and shares it across concurrent library reads. */
225
+ owner(projectId) {
226
+ const existing = this.owners.get(projectId);
227
+ if (existing)
228
+ return existing;
229
+ const pending = this.createOwner(projectId);
230
+ this.owners.set(projectId, pending);
231
+ void pending.catch(() => this.owners.delete(projectId));
232
+ return pending;
233
+ }
234
+ /** Attaches bundle metadata only when its registry activation is committed. */
235
+ async createOwner(projectId) {
236
+ const project = this.registry.get(projectId);
237
+ const storage = new ProjectStorage_1.ProjectStorage();
238
+ let bundle;
239
+ if (project.storageKind === 'bundle') {
240
+ const dataDirectory = this.registry.bundleDirectory(projectId);
241
+ if (!fs_1.default.existsSync(path_1.default.join(dataDirectory, 'metadata.sqlite')))
242
+ throw new Error('The saved project database is missing');
243
+ const roots = this.registry.historyRoots(projectId);
244
+ bundle = await BundleMetadataStore_1.BundleMetadataStore.open({
245
+ directory: dataDirectory,
246
+ project,
247
+ });
248
+ for (const projectPath of roots) {
249
+ storage.attach({
250
+ projectPath,
251
+ dataDirectory,
252
+ cacheDirectory: path_1.default.join(this.registry.root, 'cache', projectId),
253
+ });
254
+ }
255
+ }
256
+ const history = new VariantHistoryService_1.VariantHistoryService(new TreeStore_1.TreeStore(storage), undefined, { bundle });
257
+ return { history, storage, bundle };
258
+ }
259
+ }
260
+ exports.ProjectLibrary = ProjectLibrary;
261
+ //# sourceMappingURL=ProjectLibrary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectLibrary.js","sourceRoot":"","sources":["../../src/services/ProjectLibrary.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,7 @@
1
- import type { VariantHistoryManifest, VariantHistoryStatus } from './VariantHistoryService';
2
- import { type ProjectMetadataMigration } from './projectMetadataMigrations';
3
- /** A variant row as stored in (or destined for) the projection. `manifest`
4
- * reproduces the on-disk manifest exactly; `hasStaticPreview` is the listing
5
- * affordance captured when the row was projected. */
6
- export interface VariantIndexEntry {
7
- manifest: VariantHistoryManifest;
8
- hasStaticPreview: boolean;
9
- }
10
- export interface VariantIndexEntryInput extends VariantIndexEntry {
11
- /** The manifest file's mtime when projected — freshness-audit metadata. */
12
- manifestMtimeMs: number;
13
- }
1
+ import { ProjectStorage } from './ProjectStorage';
2
+ import type { VariantHistoryManifest, VariantHistoryStatus, VariantIndexEntry, VariantIndexEntryInput } from '../types/variant-history';
3
+ export type { VariantIndexEntry, VariantIndexEntryInput, } from '../types/variant-history';
4
+ import { type ProjectMetadataMigration } from '../storage/project-metadata/migrations';
14
5
  /**
15
6
  * Embedded SQLite metadata projection at `<project>/.rivet/rivet.db`.
16
7
  *
@@ -25,6 +16,7 @@ export interface VariantIndexEntryInput extends VariantIndexEntry {
25
16
  * timeout for cross-process access.
26
17
  */
27
18
  export declare class ProjectMetadataStore {
19
+ private readonly storage;
28
20
  private readonly handles;
29
21
  /** Projects whose index must rebuild before it can be trusted again,
30
22
  * regardless of the durable state row. Recording staleness here cannot
@@ -35,7 +27,7 @@ export declare class ProjectMetadataStore {
35
27
  private readonly migrations;
36
28
  /** `migrations` is injectable so tests can exercise upgrade paths with
37
29
  * synthetic lists; production callers use the default. */
38
- constructor(migrations?: readonly ProjectMetadataMigration[]);
30
+ constructor(migrations?: readonly ProjectMetadataMigration[], storage?: ProjectStorage);
39
31
  databasePath(projectPath: string): string;
40
32
  hasDatabase(projectPath: string): boolean;
41
33
  /**
@@ -109,10 +101,6 @@ export declare class ProjectMetadataStore {
109
101
  writeVariantsUiState(projectPath: string, json: string): Promise<void>;
110
102
  /** Close every open handle. For tests and process shutdown. */
111
103
  closeAll(): void;
112
- private selectEntries;
113
- private upsertRow;
114
- private readState;
115
- private writeState;
116
104
  /**
117
105
  * Open the project's database, creating and migrating it as needed. A
118
106
  * corrupt file is deleted (with its WAL/SHM siblings) and recreated once —
@@ -122,7 +110,6 @@ export declare class ProjectMetadataStore {
122
110
  * @effect Creates `.rivet/` and the database file; caches the open handle.
123
111
  */
124
112
  private openDatabase;
125
- private openAndMigrate;
126
113
  private deleteDatabaseFiles;
127
114
  }
128
115
  //# sourceMappingURL=ProjectMetadataStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectMetadataStore.d.ts","sourceRoot":"","sources":["../../src/services/ProjectMetadataStore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AA2BrC;;sDAEsD;AACtD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,sBAAsB,CAAC;IACjC,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,2EAA2E;IAC3E,eAAe,EAAE,MAAM,CAAC;CACzB;AAkBD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D;;;;iFAI6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAEjE;+DAC2D;gBAEzD,UAAU,GAAE,SAAS,wBAAwB,EAAgC;IAK/E,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIzC,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIzC;;;;;OAKG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD;;;;;;OAMG;IACG,yBAAyB,CAAC,IAAI,EAAE;QACpC,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,sBAAsB,CAAC;QACjC,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,OAAO,CAAC;KAC3B,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjB;;;;;;;OAOG;IACG,mBAAmB,CAAC,IAAI,EAAE;QAC9B,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,sBAAsB,EAAE,CAAC;KACnC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBjB;;kFAE8E;IACxE,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAShE;;;;;;;;OAQG;IACG,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazD,YAAY,CAAC,IAAI,EAAE;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,oBAAoB,CAAC;KAC/B,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAW1B,cAAc,CAAC,IAAI,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAehC;;;;;OAKG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMtE;;;;OAIG;IACG,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5E,+DAA+D;IAC/D,QAAQ,IAAI,IAAI;IAWhB,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,SAAS;IAkCjB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,UAAU;IAOlB;;;;;;;OAOG;YACW,YAAY;YAqDZ,cAAc;IA4B5B,OAAO,CAAC,mBAAmB;CAY5B"}
1
+ {"version":3,"file":"ProjectMetadataStore.d.ts","sourceRoot":"","sources":["../../src/services/ProjectMetadataStore.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,wCAAwC,CAAC;AAsBhD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAc7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;IACrE;;;;iFAI6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAEjE;+DAC2D;gBAEzD,UAAU,GAAE,SAAS,wBAAwB,EAAgC,EAC5D,OAAO,GAAE,cAAqC;IAKjE,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAOzC,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIzC;;;;;OAKG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD;;;;;;OAMG;IACG,yBAAyB,CAAC,IAAI,EAAE;QACpC,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,sBAAsB,CAAC;QACjC,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,OAAO,CAAC;KAC3B,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjB;;;;;;;OAOG;IACG,mBAAmB,CAAC,IAAI,EAAE;QAC9B,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,sBAAsB,EAAE,CAAC;KACnC,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjB;;kFAE8E;IACxE,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAShE;;;;;;;;OAQG;IACG,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazD,YAAY,CAAC,IAAI,EAAE;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,oBAAoB,CAAC;KAC/B,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAK1B,cAAc,CAAC,IAAI,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAKhC;;;;;OAKG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAMtE;;;;OAIG;IACG,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5E,+DAA+D;IAC/D,QAAQ,IAAI,IAAI;IAWhB;;;;;;;OAOG;YACW,YAAY;IAsD1B,OAAO,CAAC,mBAAmB;CAY5B"}
@@ -1,37 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
@@ -39,10 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
6
  exports.ProjectMetadataStore = void 0;
40
7
  const fs_1 = __importDefault(require("fs"));
41
8
  const path_1 = __importDefault(require("path"));
9
+ const ProjectStorage_1 = require("./ProjectStorage");
42
10
  const logger_1 = require("../utils/logger");
43
- const projectMetadataMigrations_1 = require("./projectMetadataMigrations");
11
+ const ProjectMetadataRecords_1 = require("../storage/project-metadata/ProjectMetadataRecords");
12
+ const migrations_1 = require("../storage/project-metadata/migrations");
44
13
  const log = (0, logger_1.createLogger)('ProjectMetadataStore');
45
- const RIVET_DIRNAME = '.rivet';
46
14
  const DATABASE_FILENAME = 'rivet.db';
47
15
  /** Extra files SQLite keeps alongside the database in WAL mode. Removed
48
16
  * together with the database when recovering from corruption — a stale WAL
@@ -57,19 +25,6 @@ const VARIANT_INDEX_STALE = 'stale';
57
25
  * the arrangement to the default, which callers accept as the trade-off for
58
26
  * keeping this out of a separate `.rivet` file. */
59
27
  const VARIANTS_UI_STATE_KEY = 'variants_ui_state';
60
- /** How long a statement waits on a cross-process lock before failing. The
61
- * CLI and server processes can open the same project database. */
62
- const BUSY_TIMEOUT_MS = 5_000;
63
- /** node:sqlite is loaded lazily so its one-time ExperimentalWarning fires
64
- * only in processes that actually touch the projection, not on every CLI
65
- * invocation's stderr. */
66
- let databaseSyncCtor = null;
67
- const loadDatabaseSync = async () => {
68
- if (!databaseSyncCtor) {
69
- databaseSyncCtor = (await Promise.resolve().then(() => __importStar(require('node:sqlite')))).DatabaseSync;
70
- }
71
- return databaseSyncCtor;
72
- };
73
28
  /**
74
29
  * Embedded SQLite metadata projection at `<project>/.rivet/rivet.db`.
75
30
  *
@@ -84,6 +39,7 @@ const loadDatabaseSync = async () => {
84
39
  * timeout for cross-process access.
85
40
  */
86
41
  class ProjectMetadataStore {
42
+ storage;
87
43
  handles = new Map();
88
44
  /** Projects whose index must rebuild before it can be trusted again,
89
45
  * regardless of the durable state row. Recording staleness here cannot
@@ -94,11 +50,12 @@ class ProjectMetadataStore {
94
50
  migrations;
95
51
  /** `migrations` is injectable so tests can exercise upgrade paths with
96
52
  * synthetic lists; production callers use the default. */
97
- constructor(migrations = projectMetadataMigrations_1.PROJECT_METADATA_MIGRATIONS) {
53
+ constructor(migrations = migrations_1.PROJECT_METADATA_MIGRATIONS, storage = new ProjectStorage_1.ProjectStorage()) {
54
+ this.storage = storage;
98
55
  this.migrations = migrations;
99
56
  }
100
57
  databasePath(projectPath) {
101
- return path_1.default.join(projectPath, RIVET_DIRNAME, DATABASE_FILENAME);
58
+ return path_1.default.join(this.storage.resolve(projectPath).dataDirectory, DATABASE_FILENAME);
102
59
  }
103
60
  hasDatabase(projectPath) {
104
61
  return fs_1.default.existsSync(this.databasePath(projectPath));
@@ -121,7 +78,7 @@ class ProjectMetadataStore {
121
78
  */
122
79
  async upsertVariantFromManifest(args) {
123
80
  const db = await this.openDatabase(args.projectPath);
124
- this.upsertRow(db, args);
81
+ db.upsert(args);
125
82
  }
126
83
  /**
127
84
  * Replace the project's entire variants index with `entries` and mark it
@@ -133,20 +90,13 @@ class ProjectMetadataStore {
133
90
  */
134
91
  async rebuildVariantIndex(args) {
135
92
  const db = await this.openDatabase(args.projectPath);
136
- db.exec('BEGIN IMMEDIATE');
137
- try {
138
- db.exec('DELETE FROM variants');
139
- for (const entry of args.entries) {
140
- this.upsertRow(db, { ...entry, projectPath: args.projectPath });
141
- }
142
- this.writeState(db, VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_READY);
143
- db.exec('COMMIT');
144
- this.staleOverrides.delete(path_1.default.resolve(args.projectPath));
145
- }
146
- catch (err) {
147
- db.exec('ROLLBACK');
148
- throw err;
149
- }
93
+ db.transaction(() => {
94
+ db.clearVariants();
95
+ for (const entry of args.entries)
96
+ db.upsert(entry);
97
+ db.writeState(VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_READY);
98
+ });
99
+ this.staleOverrides.delete(path_1.default.resolve(args.projectPath));
150
100
  }
151
101
  /** Whether the variants index can serve reads: the database exists, opens
152
102
  * at a supported schema version, no in-process staleness override is
@@ -159,7 +109,7 @@ class ProjectMetadataStore {
159
109
  return false;
160
110
  }
161
111
  const db = await this.openDatabase(projectPath);
162
- return this.readState(db, VARIANT_INDEX_STATE_KEY) === VARIANT_INDEX_READY;
112
+ return db.readState(VARIANT_INDEX_STATE_KEY) === VARIANT_INDEX_READY;
163
113
  }
164
114
  /**
165
115
  * Flag the variants index as out of sync with the manifests on disk, so
@@ -174,7 +124,7 @@ class ProjectMetadataStore {
174
124
  this.staleOverrides.add(path_1.default.resolve(projectPath));
175
125
  try {
176
126
  const db = await this.openDatabase(projectPath);
177
- this.writeState(db, VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_STALE);
127
+ db.writeState(VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_STALE);
178
128
  }
179
129
  catch (err) {
180
130
  log.warn(`markVariantIndexStale: durable stale flag failed for ${projectPath} — the in-memory override still forces a rebuild in this process`, err);
@@ -182,21 +132,11 @@ class ProjectMetadataStore {
182
132
  }
183
133
  async listVariants(args) {
184
134
  const db = await this.openDatabase(args.projectPath);
185
- const conditions = [];
186
- const params = [];
187
- if (args.status) {
188
- conditions.push('status = ?');
189
- params.push(args.status);
190
- }
191
- return this.selectEntries(db, conditions, params, args.limit);
135
+ return db.list({ status: args.status, limit: args.limit });
192
136
  }
193
137
  async searchVariants(args) {
194
138
  const db = await this.openDatabase(args.projectPath);
195
- // Escape LIKE wildcards so the query only ever matches literally.
196
- const escaped = args.query.replace(/[\\%_]/g, (match) => `\\${match}`);
197
- const pattern = `%${escaped}%`;
198
- const clause = "(label LIKE ? ESCAPE '\\' OR brief LIKE ? ESCAPE '\\' OR session_prompt LIKE ? ESCAPE '\\' OR run_label LIKE ? ESCAPE '\\')";
199
- return this.selectEntries(db, [clause], [pattern, pattern, pattern, pattern], args.limit);
139
+ return db.search({ query: args.query, limit: args.limit });
200
140
  }
201
141
  /**
202
142
  * Read the variants panel's stored UI arrangement, or null when none has
@@ -208,7 +148,7 @@ class ProjectMetadataStore {
208
148
  if (!this.hasDatabase(projectPath))
209
149
  return null;
210
150
  const db = await this.openDatabase(projectPath);
211
- return this.readState(db, VARIANTS_UI_STATE_KEY);
151
+ return db.readState(VARIANTS_UI_STATE_KEY);
212
152
  }
213
153
  /**
214
154
  * Persist the variants panel's UI arrangement.
@@ -217,7 +157,7 @@ class ProjectMetadataStore {
217
157
  */
218
158
  async writeVariantsUiState(projectPath, json) {
219
159
  const db = await this.openDatabase(projectPath);
220
- this.writeState(db, VARIANTS_UI_STATE_KEY, json);
160
+ db.writeState(VARIANTS_UI_STATE_KEY, json);
221
161
  }
222
162
  /** Close every open handle. For tests and process shutdown. */
223
163
  closeAll() {
@@ -231,38 +171,6 @@ class ProjectMetadataStore {
231
171
  }
232
172
  this.handles.clear();
233
173
  }
234
- selectEntries(db, conditions, params, limit) {
235
- const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
236
- // Newest-first with id tiebreaks so equal timestamps order predictably.
237
- let sql = `SELECT manifest_json, has_static_preview FROM variants ${where} ORDER BY created_at DESC, session_id ASC, variant_id ASC`;
238
- if (limit !== undefined && limit > 0) {
239
- sql += ' LIMIT ?';
240
- params = [...params, limit];
241
- }
242
- const rows = db.prepare(sql).all(...params);
243
- return rows.map((row) => ({
244
- manifest: JSON.parse(row.manifest_json),
245
- hasStaticPreview: row.has_static_preview === 1,
246
- }));
247
- }
248
- upsertRow(db, args) {
249
- const { manifest } = args;
250
- db.prepare(`INSERT OR REPLACE INTO variants (
251
- session_id, variant_id, label, brief, session_prompt, run_label,
252
- status, created_at, status_changed_at, has_tree, serve_kind,
253
- has_static_preview, manifest_mtime_ms, manifest_json
254
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(manifest.sessionId, manifest.variantId, manifest.label, manifest.brief, manifest.sessionPrompt, manifest.runLabel ?? null, manifest.status, manifest.createdAt, manifest.statusChangedAt, manifest.tree ? 1 : 0, manifest.serve?.kind ?? null, args.hasStaticPreview ? 1 : 0, Math.round(args.manifestMtimeMs), JSON.stringify(manifest));
255
- }
256
- readState(db, key) {
257
- const row = db
258
- .prepare('SELECT value FROM metadata_state WHERE key = ?')
259
- .get(key);
260
- return row?.value ?? null;
261
- }
262
- writeState(db, key, value) {
263
- db.prepare(`INSERT INTO metadata_state (key, value, updated_at) VALUES (?, ?, ?)
264
- ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`).run(key, value, new Date().toISOString());
265
- }
266
174
  /**
267
175
  * Open the project's database, creating and migrating it as needed. A
268
176
  * corrupt file is deleted (with its WAL/SHM siblings) and recreated once —
@@ -290,28 +198,27 @@ class ProjectMetadataStore {
290
198
  this.handles.delete(key);
291
199
  }
292
200
  fs_1.default.mkdirSync(path_1.default.dirname(dbPath), { recursive: true });
293
- let opened;
201
+ let db;
294
202
  try {
295
- opened = await this.openAndMigrate(dbPath);
203
+ db = await ProjectMetadataRecords_1.ProjectMetadataRecords.open(dbPath, this.migrations);
296
204
  }
297
205
  catch (err) {
298
- if (err instanceof projectMetadataMigrations_1.UnsupportedSchemaVersionError)
206
+ if (err instanceof migrations_1.UnsupportedSchemaVersionError)
299
207
  throw err;
300
208
  log.warn(`openDatabase: ${dbPath} is unreadable — recreating the projection`, err);
301
209
  this.deleteDatabaseFiles(dbPath);
302
- opened = await this.openAndMigrate(dbPath);
210
+ db = await ProjectMetadataRecords_1.ProjectMetadataRecords.open(dbPath, this.migrations);
303
211
  }
304
- const { db, wasUpgraded } = opened;
305
- if (wasUpgraded) {
306
- // Migrations only change schema shape (see projectMetadataMigrations)
212
+ if (db.wasUpgraded) {
213
+ // Storage migrations only change schema shape
307
214
  // — any column they add that derives from manifests starts empty.
308
215
  // Marking the index stale makes the next read re-project every row,
309
216
  // so migrations never need data backfills of their own. Outside
310
- // openAndMigrate so a failed flag write can't look like corruption;
217
+ // connection setup so a failed flag write can't look like corruption;
311
218
  // the in-memory override alone already forces the rebuild.
312
219
  this.staleOverrides.add(key);
313
220
  try {
314
- this.writeState(db, VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_STALE);
221
+ db.writeState(VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_STALE);
315
222
  }
316
223
  catch (err) {
317
224
  log.warn(`openDatabase: durable stale flag failed after upgrading ${dbPath}`, err);
@@ -320,31 +227,6 @@ class ProjectMetadataStore {
320
227
  this.handles.set(key, db);
321
228
  return db;
322
229
  }
323
- async openAndMigrate(dbPath) {
324
- const DatabaseSync = await loadDatabaseSync();
325
- const db = new DatabaseSync(dbPath);
326
- try {
327
- db.exec('PRAGMA journal_mode = WAL');
328
- db.exec(`PRAGMA busy_timeout = ${BUSY_TIMEOUT_MS}`);
329
- const { fromVersion, toVersion } = (0, projectMetadataMigrations_1.applyProjectMetadataMigrations)(db, {
330
- migrations: this.migrations,
331
- });
332
- const wasUpgraded = fromVersion > 0 && toVersion > fromVersion;
333
- if (wasUpgraded) {
334
- log.info(`openAndMigrate: upgraded ${dbPath} from schema version ${fromVersion} to ${toVersion} — index will rebuild on next read`);
335
- }
336
- return { db, wasUpgraded };
337
- }
338
- catch (err) {
339
- try {
340
- db.close();
341
- }
342
- catch {
343
- // The open error is the one worth surfacing.
344
- }
345
- throw err;
346
- }
347
- }
348
230
  deleteDatabaseFiles(dbPath) {
349
231
  for (const target of [
350
232
  dbPath,