rivet-design 0.18.2 → 0.18.3

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 (213) hide show
  1. package/README.md +1 -1
  2. package/README.npm.md +1 -1
  3. package/dist/agent-variants/SessionStore.d.ts.map +1 -1
  4. package/dist/agent-variants/SessionStore.js +7 -0
  5. package/dist/agent-variants/SessionStore.js.map +1 -1
  6. package/dist/agent-variants/WorktreeOrchestrator.d.ts +5 -1
  7. package/dist/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
  8. package/dist/agent-variants/WorktreeOrchestrator.js +193 -39
  9. package/dist/agent-variants/WorktreeOrchestrator.js.map +1 -1
  10. package/dist/cli/client.d.ts.map +1 -1
  11. package/dist/cli/client.js +11 -3
  12. package/dist/cli/client.js.map +1 -1
  13. package/dist/cli/commands/generationPreflight.d.ts +12 -0
  14. package/dist/cli/commands/generationPreflight.d.ts.map +1 -0
  15. package/dist/cli/commands/generationPreflight.js +40 -0
  16. package/dist/cli/commands/generationPreflight.js.map +1 -0
  17. package/dist/cli/commands/mcpServe.d.ts.map +1 -1
  18. package/dist/cli/commands/mcpServe.js +54 -12
  19. package/dist/cli/commands/mcpServe.js.map +1 -1
  20. package/dist/cli/commands/open.d.ts.map +1 -1
  21. package/dist/cli/commands/open.js +110 -76
  22. package/dist/cli/commands/open.js.map +1 -1
  23. package/dist/cli/commands/profile.d.ts.map +1 -1
  24. package/dist/cli/commands/profile.js +75 -2
  25. package/dist/cli/commands/profile.js.map +1 -1
  26. package/dist/cli/commands/serve.d.ts.map +1 -1
  27. package/dist/cli/commands/serve.js +20 -0
  28. package/dist/cli/commands/serve.js.map +1 -1
  29. package/dist/cli/commands/shared.d.ts.map +1 -1
  30. package/dist/cli/commands/shared.js +2 -2
  31. package/dist/cli/commands/shared.js.map +1 -1
  32. package/dist/cli/commands/stop.d.ts.map +1 -1
  33. package/dist/cli/commands/stop.js +29 -5
  34. package/dist/cli/commands/stop.js.map +1 -1
  35. package/dist/cli/commands/variants.d.ts +8 -1
  36. package/dist/cli/commands/variants.d.ts.map +1 -1
  37. package/dist/cli/commands/variants.js +13 -4
  38. package/dist/cli/commands/variants.js.map +1 -1
  39. package/dist/cli/referenceOnboarding.d.ts +3 -0
  40. package/dist/cli/referenceOnboarding.d.ts.map +1 -0
  41. package/dist/cli/referenceOnboarding.js +82 -0
  42. package/dist/cli/referenceOnboarding.js.map +1 -0
  43. package/dist/cli/router.d.ts.map +1 -1
  44. package/dist/cli/router.js +7 -7
  45. package/dist/cli/router.js.map +1 -1
  46. package/dist/cli/serverHandshake.d.ts +5 -4
  47. package/dist/cli/serverHandshake.d.ts.map +1 -1
  48. package/dist/cli/serverHandshake.js +66 -57
  49. package/dist/cli/serverHandshake.js.map +1 -1
  50. package/dist/cli/serverShutdown.d.ts +4 -0
  51. package/dist/cli/serverShutdown.d.ts.map +1 -0
  52. package/dist/cli/serverShutdown.js +20 -0
  53. package/dist/cli/serverShutdown.js.map +1 -0
  54. package/dist/cli/serverUnavailable.d.ts +1 -1
  55. package/dist/cli/serverUnavailable.d.ts.map +1 -1
  56. package/dist/cli/serverUnavailable.js +4 -0
  57. package/dist/cli/serverUnavailable.js.map +1 -1
  58. package/dist/cli/serverVersion.d.ts +1 -1
  59. package/dist/cli/serverVersion.d.ts.map +1 -1
  60. package/dist/cli/serverVersion.js +5 -23
  61. package/dist/cli/serverVersion.js.map +1 -1
  62. package/dist/install/codexSkill.d.ts +13 -0
  63. package/dist/install/codexSkill.d.ts.map +1 -0
  64. package/dist/install/codexSkill.js +64 -0
  65. package/dist/install/codexSkill.js.map +1 -0
  66. package/dist/install/harnesses.d.ts.map +1 -1
  67. package/dist/install/harnesses.js +25 -4
  68. package/dist/install/harnesses.js.map +1 -1
  69. package/dist/routes/agentVariants.d.ts +2 -1
  70. package/dist/routes/agentVariants.d.ts.map +1 -1
  71. package/dist/routes/agentVariants.js +26 -28
  72. package/dist/routes/agentVariants.js.map +1 -1
  73. package/dist/routes/cli.d.ts +3 -0
  74. package/dist/routes/cli.d.ts.map +1 -1
  75. package/dist/routes/cli.js +66 -9
  76. package/dist/routes/cli.js.map +1 -1
  77. package/dist/routes/library/profiles.d.ts.map +1 -1
  78. package/dist/routes/library/profiles.js +2 -0
  79. package/dist/routes/library/profiles.js.map +1 -1
  80. package/dist/routes/library/referenceOnboarding.d.ts +4 -0
  81. package/dist/routes/library/referenceOnboarding.d.ts.map +1 -0
  82. package/dist/routes/library/referenceOnboarding.js +94 -0
  83. package/dist/routes/library/referenceOnboarding.js.map +1 -0
  84. package/dist/routes/runtimeAdmission.d.ts +13 -0
  85. package/dist/routes/runtimeAdmission.d.ts.map +1 -0
  86. package/dist/routes/runtimeAdmission.js +42 -0
  87. package/dist/routes/runtimeAdmission.js.map +1 -0
  88. package/dist/server.d.ts +1 -0
  89. package/dist/server.d.ts.map +1 -1
  90. package/dist/server.js +7 -4
  91. package/dist/server.js.map +1 -1
  92. package/dist/services/IntegrationsClient.d.ts +77 -0
  93. package/dist/services/IntegrationsClient.d.ts.map +1 -1
  94. package/dist/services/IntegrationsClient.js +123 -6
  95. package/dist/services/IntegrationsClient.js.map +1 -1
  96. package/dist/services/ProjectImport.d.ts.map +1 -1
  97. package/dist/services/ProjectImport.js +5 -12
  98. package/dist/services/ProjectImport.js.map +1 -1
  99. package/dist/services/RuntimeAdmission.d.ts +31 -0
  100. package/dist/services/RuntimeAdmission.d.ts.map +1 -0
  101. package/dist/services/RuntimeAdmission.js +77 -0
  102. package/dist/services/RuntimeAdmission.js.map +1 -0
  103. package/dist/services/TelemetryService.d.ts +1 -1
  104. package/dist/services/TelemetryService.d.ts.map +1 -1
  105. package/dist/services/TelemetryService.js.map +1 -1
  106. package/dist/services/TreeStore.d.ts +7 -0
  107. package/dist/services/TreeStore.d.ts.map +1 -1
  108. package/dist/services/TreeStore.js +18 -0
  109. package/dist/services/TreeStore.js.map +1 -1
  110. package/dist/services/profiles/DesignProfiles.d.ts +231 -16
  111. package/dist/services/profiles/DesignProfiles.d.ts.map +1 -1
  112. package/dist/services/profiles/DesignProfiles.js +140 -0
  113. package/dist/services/profiles/DesignProfiles.js.map +1 -1
  114. package/dist/services/profiles/ProfileImports.d.ts +3 -3
  115. package/dist/services/profiles/ProfileImports.d.ts.map +1 -1
  116. package/dist/services/profiles/ProfileImports.js +25 -1
  117. package/dist/services/profiles/ProfileImports.js.map +1 -1
  118. package/dist/services/profiles/ProfilePlanning.d.ts +96 -0
  119. package/dist/services/profiles/ProfilePlanning.d.ts.map +1 -0
  120. package/dist/services/profiles/ProfilePlanning.js +187 -0
  121. package/dist/services/profiles/ProfilePlanning.js.map +1 -0
  122. package/dist/services/profiles/ReferenceReader.d.ts +75 -0
  123. package/dist/services/profiles/ReferenceReader.d.ts.map +1 -0
  124. package/dist/services/profiles/ReferenceReader.js +97 -0
  125. package/dist/services/profiles/ReferenceReader.js.map +1 -0
  126. package/dist/services/profiles/analysisBatch.js +1 -1
  127. package/dist/services/profiles/analysisBatch.js.map +1 -1
  128. package/dist/services/profiles/boardPage.d.ts +2 -1
  129. package/dist/services/profiles/boardPage.d.ts.map +1 -1
  130. package/dist/services/profiles/boardPage.js.map +1 -1
  131. package/dist/services/profiles/cosmosPage.d.ts +10 -0
  132. package/dist/services/profiles/cosmosPage.d.ts.map +1 -0
  133. package/dist/services/profiles/cosmosPage.js +104 -0
  134. package/dist/services/profiles/cosmosPage.js.map +1 -0
  135. package/dist/services/runtimeActivity.d.ts +3 -0
  136. package/dist/services/runtimeActivity.d.ts.map +1 -0
  137. package/dist/services/runtimeActivity.js +70 -0
  138. package/dist/services/runtimeActivity.js.map +1 -0
  139. package/dist/services/runtimeVersion.d.ts +4 -0
  140. package/dist/services/runtimeVersion.d.ts.map +1 -0
  141. package/dist/services/runtimeVersion.js +30 -0
  142. package/dist/services/runtimeVersion.js.map +1 -0
  143. package/dist/storage/library/ProjectRuntimeRecords.d.ts +15 -0
  144. package/dist/storage/library/ProjectRuntimeRecords.d.ts.map +1 -0
  145. package/dist/storage/library/ProjectRuntimeRecords.js +66 -0
  146. package/dist/storage/library/ProjectRuntimeRecords.js.map +1 -0
  147. package/dist/storage/library/migrations.d.ts +1 -0
  148. package/dist/storage/library/migrations.d.ts.map +1 -1
  149. package/dist/storage/library/migrations.js +9 -1
  150. package/dist/storage/library/migrations.js.map +1 -1
  151. package/dist/storage/library/schema/projectRuntime.d.ts +72 -0
  152. package/dist/storage/library/schema/projectRuntime.d.ts.map +1 -0
  153. package/dist/storage/library/schema/projectRuntime.js +16 -0
  154. package/dist/storage/library/schema/projectRuntime.js.map +1 -0
  155. package/dist/storage/profiles/ProfilePlans.d.ts +320 -0
  156. package/dist/storage/profiles/ProfilePlans.d.ts.map +1 -0
  157. package/dist/storage/profiles/ProfilePlans.js +256 -0
  158. package/dist/storage/profiles/ProfilePlans.js.map +1 -0
  159. package/dist/storage/profiles/ProfileRecords.d.ts +71 -10
  160. package/dist/storage/profiles/ProfileRecords.d.ts.map +1 -1
  161. package/dist/storage/profiles/ProfileRecords.js +152 -62
  162. package/dist/storage/profiles/ProfileRecords.js.map +1 -1
  163. package/dist/storage/profiles/migrations.d.ts +2 -2
  164. package/dist/storage/profiles/migrations.d.ts.map +1 -1
  165. package/dist/storage/profiles/migrations.js +14 -0
  166. package/dist/storage/profiles/migrations.js.map +1 -1
  167. package/dist/storage/profiles/planSchema.d.ts +347 -0
  168. package/dist/storage/profiles/planSchema.d.ts.map +1 -0
  169. package/dist/storage/profiles/planSchema.js +34 -0
  170. package/dist/storage/profiles/planSchema.js.map +1 -0
  171. package/dist/storage/profiles/schema.d.ts +59 -4
  172. package/dist/storage/profiles/schema.d.ts.map +1 -1
  173. package/dist/storage/profiles/schema.js +14 -1
  174. package/dist/storage/profiles/schema.js.map +1 -1
  175. package/dist/types/cosmos-profile.d.ts +130 -0
  176. package/dist/types/cosmos-profile.d.ts.map +1 -0
  177. package/dist/types/cosmos-profile.js +27 -0
  178. package/dist/types/cosmos-profile.js.map +1 -0
  179. package/dist/types/cosmos.d.ts +330 -0
  180. package/dist/types/cosmos.d.ts.map +1 -0
  181. package/dist/types/cosmos.js +157 -0
  182. package/dist/types/cosmos.js.map +1 -0
  183. package/dist/types/design-profile.d.ts +21 -16
  184. package/dist/types/design-profile.d.ts.map +1 -1
  185. package/dist/types/design-profile.js +6 -1
  186. package/dist/types/design-profile.js.map +1 -1
  187. package/dist/types/reference-connectors.d.ts +226 -0
  188. package/dist/types/reference-connectors.d.ts.map +1 -0
  189. package/dist/types/reference-connectors.js +92 -0
  190. package/dist/types/reference-connectors.js.map +1 -0
  191. package/dist/types/reference-onboarding.d.ts +1065 -0
  192. package/dist/types/reference-onboarding.d.ts.map +1 -0
  193. package/dist/types/reference-onboarding.js +108 -0
  194. package/dist/types/reference-onboarding.js.map +1 -0
  195. package/dist/types/reference-pages.d.ts +168 -0
  196. package/dist/types/reference-pages.d.ts.map +1 -0
  197. package/dist/types/reference-pages.js +26 -0
  198. package/dist/types/reference-pages.js.map +1 -0
  199. package/dist/types/x-bookmarks.d.ts +8 -8
  200. package/dist/utils/skills/cli-guidance.d.ts +1 -1
  201. package/dist/utils/skills/cli-guidance.d.ts.map +1 -1
  202. package/dist/utils/skills/cli-guidance.js +6 -2
  203. package/dist/utils/skills/cli-guidance.js.map +1 -1
  204. package/dist/utils/skills/codex-skill.d.ts +3 -0
  205. package/dist/utils/skills/codex-skill.d.ts.map +1 -0
  206. package/dist/utils/skills/codex-skill.js +30 -0
  207. package/dist/utils/skills/codex-skill.js.map +1 -0
  208. package/package.json +2 -1
  209. package/src/ui/dist/assets/{LibraryApp-NAzSe5xc.js → LibraryApp-DFhxcf--.js} +1 -1
  210. package/src/ui/dist/assets/main-Ayzl0f1H.css +1 -0
  211. package/src/ui/dist/assets/{main-D7LJLJwW.js → main-D5n04THm.js} +78 -78
  212. package/src/ui/dist/index.html +2 -2
  213. package/src/ui/dist/assets/main-f2uWt6ZY.css +0 -1
@@ -1233,6 +1233,9 @@ class AgentVariantsOrchestrator {
1233
1233
  sourceVariantId: args.source.variantId,
1234
1234
  targetVariantId: append.workItemId,
1235
1235
  });
1236
+ if (this.store.getProjectContext(args.sessionId).kind === 'existing') {
1237
+ await this.prepareArtifactBase(args.sessionId);
1238
+ }
1236
1239
  this.emitChange();
1237
1240
  return {
1238
1241
  workItemId: append.workItemId,
@@ -1281,6 +1284,9 @@ class AgentVariantsOrchestrator {
1281
1284
  assetBase,
1282
1285
  hasAssets,
1283
1286
  });
1287
+ if (args.projectContext.kind === 'existing') {
1288
+ await this.prepareArtifactBase(created.sessionId);
1289
+ }
1284
1290
  this.emitChange();
1285
1291
  return {
1286
1292
  sessionId: created.sessionId,
@@ -2402,6 +2408,7 @@ class AgentVariantsOrchestrator {
2402
2408
  throw new errors_1.AgentVariantsError('INVALID_STAGE_ACTION', variantSnapshot?.actions?.commit?.reason ??
2403
2409
  'Variant is not committable');
2404
2410
  }
2411
+ await this.settleHistoryPersists();
2405
2412
  const input = this.store.getWorkItemInput(args.sessionId, args.variantId);
2406
2413
  const projectContext = this.store.getProjectContext(args.sessionId);
2407
2414
  if (projectContext.kind === 'fresh') {
@@ -2585,18 +2592,26 @@ class AgentVariantsOrchestrator {
2585
2592
  else {
2586
2593
  const env = await this.resolveEnv(args.sessionId);
2587
2594
  const record = resources.worktrees.get(args.variantId);
2588
- if (!record) {
2595
+ const saved = record
2596
+ ? null
2597
+ : await this.getSavedVariant({
2598
+ projectPath: env.projectPath,
2599
+ sessionId: args.sessionId,
2600
+ variantId: args.variantId,
2601
+ });
2602
+ const diff = record?.diff ?? saved?.diff;
2603
+ if (!record && !saved) {
2589
2604
  throw new errors_1.AgentVariantsError('WORK_ITEM_NOT_FOUND', `Unknown variantId ${args.variantId} for session ${args.sessionId}`);
2590
2605
  }
2591
- if (record.diff === undefined) {
2606
+ if (diff === undefined) {
2592
2607
  throw new errors_1.AgentVariantsError('INVALID_STAGE_ACTION', `Variant ${args.variantId} has no captured diff yet — wait for report_variant_complete(succeeded) first`);
2593
2608
  }
2594
- changedFilesCount = countDiffFiles(record.diff);
2609
+ changedFilesCount = countDiffFiles(diff);
2595
2610
  if (!this.worktrees.applyDiffToProject) {
2596
2611
  throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', 'WorktreeManager does not support applying diffs to the project tree');
2597
2612
  }
2598
2613
  try {
2599
- await this.worktrees.applyDiffToProject(record.diff, env.projectPath);
2614
+ await this.worktrees.applyDiffToProject(diff, env.projectPath);
2600
2615
  }
2601
2616
  catch (err) {
2602
2617
  const message = err instanceof Error ? err.message : String(err);
@@ -2604,7 +2619,7 @@ class AgentVariantsOrchestrator {
2604
2619
  }
2605
2620
  payload = {
2606
2621
  kind: 'diff-applied',
2607
- diff: record.diff,
2622
+ diff,
2608
2623
  target: input.target,
2609
2624
  changedFilesCount,
2610
2625
  note: "Variant diff applied to the user's working tree (uncommitted).",
@@ -3312,7 +3327,12 @@ class AgentVariantsOrchestrator {
3312
3327
  const workspacePath = projectContext.kind === 'fresh'
3313
3328
  ? projectContext.workspacePath
3314
3329
  : undefined;
3330
+ const assignedWorkspace = resources.workspaceManager.getAssignedWorkspace(workItemId);
3331
+ const assignedArtifactBase = assignedWorkspace?.kind === 'artifact_directory'
3332
+ ? assignedWorkspace.rootPath
3333
+ : undefined;
3315
3334
  let dir = resolvedAssetBase ??
3335
+ assignedArtifactBase ??
3316
3336
  (workspacePath
3317
3337
  ? path_1.default.join(workspacePath, `.rivet-preview-${workItemId}`)
3318
3338
  : undefined);
@@ -3345,22 +3365,19 @@ class AgentVariantsOrchestrator {
3345
3365
  briefId: input.briefId,
3346
3366
  entryPath: 'index.html',
3347
3367
  assetBase: dir,
3348
- hasAssets: Boolean(resolvedAssetBase),
3368
+ hasAssets: Boolean(resolvedAssetBase || assignedArtifactBase),
3349
3369
  };
3350
3370
  resources.staticPreviews.set(workItemId, record);
3351
- const assignedWorkspace = resources.workspaceManager.getAssignedWorkspace(workItemId);
3352
3371
  if (assignedWorkspace?.kind === 'artifact_directory' &&
3353
3372
  assignedWorkspace.rootPath !== record.assetBase) {
3354
3373
  resources.workspaceManager.removeArtifactWorkspace(workItemId);
3355
3374
  }
3356
- if (this.store.getProjectContext(sessionId).kind === 'fresh') {
3357
- this.trackHistoryPersist(this.persistCompletedFreshVariant({
3358
- sessionId,
3359
- workItemId,
3360
- }).catch((err) => {
3361
- log.warn(`persistCompletedFreshVariant failed for ${sessionId}/${workItemId}`, err);
3362
- }));
3363
- }
3375
+ this.trackHistoryPersist(this.persistCompletedArtifactVariant({
3376
+ sessionId,
3377
+ workItemId,
3378
+ }).catch((err) => {
3379
+ log.warn(`persistCompletedArtifactVariant failed for ${sessionId}/${workItemId}`, err);
3380
+ }));
3364
3381
  const leasedAt = resources.leasedAt.get(workItemId);
3365
3382
  trackStaticPreviewCompleted(this.telemetry, {
3366
3383
  sessionId,
@@ -3409,11 +3426,11 @@ class AgentVariantsOrchestrator {
3409
3426
  }));
3410
3427
  }
3411
3428
  else {
3412
- this.trackHistoryPersist(this.persistCompletedFreshVariant({
3429
+ this.trackHistoryPersist(this.persistCompletedArtifactVariant({
3413
3430
  sessionId,
3414
3431
  workItemId,
3415
3432
  }).catch((err) => {
3416
- log.warn(`persistCompletedFreshVariant failed for ${sessionId}/${workItemId}`, err);
3433
+ log.warn(`persistCompletedArtifactVariant failed for ${sessionId}/${workItemId}`, err);
3417
3434
  }));
3418
3435
  }
3419
3436
  if (!isFresh) {
@@ -3452,7 +3469,11 @@ class AgentVariantsOrchestrator {
3452
3469
  projectContext: this.store.getProjectContext(args.sessionId),
3453
3470
  });
3454
3471
  const previousRecord = resources.staticPreviews.get(input.variantId);
3455
- const dir = resolvedAssetBase ?? previousRecord?.assetBase;
3472
+ const refinementWorkspace = resources.workspaceManager.getAssignedWorkspace(args.workItemId);
3473
+ const assignedArtifactBase = refinementWorkspace?.kind === 'artifact_directory'
3474
+ ? refinementWorkspace.rootPath
3475
+ : undefined;
3476
+ const dir = resolvedAssetBase ?? assignedArtifactBase ?? previousRecord?.assetBase;
3456
3477
  if (dir) {
3457
3478
  try {
3458
3479
  fs_1.default.mkdirSync(dir, { recursive: true });
@@ -3472,10 +3493,11 @@ class AgentVariantsOrchestrator {
3472
3493
  briefId: targetInput.briefId,
3473
3494
  entryPath: 'index.html',
3474
3495
  assetBase: dir,
3475
- hasAssets: Boolean(resolvedAssetBase) || Boolean(previousRecord?.hasAssets),
3496
+ hasAssets: Boolean(resolvedAssetBase) ||
3497
+ Boolean(assignedArtifactBase) ||
3498
+ Boolean(previousRecord?.hasAssets),
3476
3499
  });
3477
3500
  }
3478
- const refinementWorkspace = resources.workspaceManager.getAssignedWorkspace(args.workItemId);
3479
3501
  if (refinementWorkspace?.kind === 'artifact_directory' &&
3480
3502
  dir === refinementWorkspace.rootPath) {
3481
3503
  resources.workspaceManager.promoteArtifactWorkspace({
@@ -3484,13 +3506,13 @@ class AgentVariantsOrchestrator {
3484
3506
  });
3485
3507
  }
3486
3508
  try {
3487
- await this.persistCompletedFreshVariant({
3509
+ await this.persistCompletedArtifactVariant({
3488
3510
  sessionId: args.sessionId,
3489
3511
  workItemId: input.variantId,
3490
3512
  });
3491
3513
  }
3492
3514
  catch (err) {
3493
- log.warn(`persistCompletedFreshVariant failed for refined variant ${input.variantId} (session ${args.sessionId}); preview already swapped`, err);
3515
+ log.warn(`persistCompletedArtifactVariant failed for refined variant ${input.variantId} (session ${args.sessionId}); preview already swapped`, err);
3494
3516
  }
3495
3517
  }
3496
3518
  get devServerManager() {
@@ -3510,6 +3532,69 @@ class AgentVariantsOrchestrator {
3510
3532
  await Promise.allSettled([...this.pendingHistoryPersists]);
3511
3533
  }
3512
3534
  }
3535
+ async getSavedVariant(args) {
3536
+ const saved = await this.variantHistory.getVariant(args);
3537
+ if (saved)
3538
+ return saved;
3539
+ const origin = this.resolveHistoryParentVariant(args.sessionId, args.variantId);
3540
+ if (!origin ||
3541
+ (origin.sessionId === args.sessionId &&
3542
+ origin.variantId === args.variantId))
3543
+ return null;
3544
+ return this.variantHistory.getVariant({
3545
+ projectPath: args.projectPath,
3546
+ ...origin,
3547
+ });
3548
+ }
3549
+ async isHistoryDurableForRestart() {
3550
+ await this.settleHistoryPersists();
3551
+ const sessions = new Set(this.resources.keys());
3552
+ if (this.activeSessionId)
3553
+ sessions.add(this.activeSessionId);
3554
+ for (const sessionId of sessions) {
3555
+ if (!this.store.hasSession(sessionId))
3556
+ continue;
3557
+ if (!contracts_1.TERMINAL_STAGES.has(this.store.getStage(sessionId)))
3558
+ return false;
3559
+ const context = this.store.getProjectContext(sessionId);
3560
+ const projectPath = context.kind === 'fresh'
3561
+ ? context.workspacePath
3562
+ : (await this.resolveEnv(sessionId)).projectPath;
3563
+ for (const variant of this.getVariants(sessionId)) {
3564
+ if (variant.status === 'pending' || variant.status === 'running')
3565
+ return false;
3566
+ if (variant.status !== 'succeeded')
3567
+ continue;
3568
+ const saved = await this.getSavedVariant({
3569
+ projectPath,
3570
+ sessionId,
3571
+ variantId: variant.workItemId,
3572
+ });
3573
+ if (!saved ||
3574
+ (!saved.hasStaticPreview &&
3575
+ !saved.diff?.trim() &&
3576
+ !saved.files?.length))
3577
+ return false;
3578
+ const resources = this.resources.get(sessionId);
3579
+ const preview = resources?.staticPreviews.get(variant.workItemId) ??
3580
+ this.getStaticPreviewByBriefId(sessionId, variant.briefId);
3581
+ if (preview) {
3582
+ const currentHtml = await fs_1.default.promises.readFile(path_1.default.join(preview.assetBase, preview.entryPath), 'utf8');
3583
+ const savedHtml = await this.variantHistory.readStaticPreview({
3584
+ projectPath,
3585
+ sessionId: saved.manifest.sessionId,
3586
+ variantId: saved.manifest.variantId,
3587
+ });
3588
+ if (currentHtml !== savedHtml)
3589
+ return false;
3590
+ }
3591
+ const diff = resources?.worktrees.get(variant.workItemId)?.diff;
3592
+ if (diff && saved.diff !== diff)
3593
+ return false;
3594
+ }
3595
+ }
3596
+ return true;
3597
+ }
3513
3598
  async persistCompletedExistingVariant(args) {
3514
3599
  const projectContext = this.store.getProjectContext(args.sessionId);
3515
3600
  if (projectContext.kind !== 'existing')
@@ -3689,11 +3774,65 @@ class AgentVariantsOrchestrator {
3689
3774
  });
3690
3775
  return 'registered';
3691
3776
  }
3692
- async persistCompletedFreshVariant(args) {
3777
+ async prepareArtifactBase(sessionId) {
3778
+ const { projectPath } = await this.resolveEnv(sessionId);
3779
+ return this.variantHistory.store.putBase({
3780
+ projectPath,
3781
+ sessionId: `${sessionId}-artifacts`,
3782
+ baseDir: projectPath,
3783
+ });
3784
+ }
3785
+ async createArtifactDiff(args) {
3786
+ const base = await this.prepareArtifactBase(args.sessionId);
3787
+ const env = await this.resolveEnv(args.sessionId);
3788
+ const entryPath = env.framework === 'static' ? env.entryPath : 'index.html';
3789
+ const entryFile = path_1.default.resolve(args.sourceDir, entryPath);
3790
+ if (!isStrictlyInside(entryFile, args.sourceDir)) {
3791
+ throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', 'Artifact entry must be inside its project directory.');
3792
+ }
3793
+ const isEntryMapped = entryFile !== path_1.default.join(args.sourceDir, 'index.html');
3794
+ if (isEntryMapped) {
3795
+ fs_1.default.mkdirSync(path_1.default.dirname(entryFile), { recursive: true });
3796
+ fs_1.default.copyFileSync(path_1.default.join(args.sourceDir, 'index.html'), entryFile);
3797
+ }
3798
+ const store = this.variantHistory.store;
3799
+ const tree = await store.putTree({
3800
+ projectPath: args.projectPath,
3801
+ sourceDir: args.sourceDir,
3802
+ ref: store.variantRef(args.sessionId, args.workItemId),
3803
+ message: 'rivet artifact',
3804
+ });
3805
+ const gitRoot = (await this.worktrees.getGitRoot?.()) ?? args.projectPath;
3806
+ const relative = path_1.default.relative(gitRoot, args.projectPath);
3807
+ if (relative === '..' ||
3808
+ relative.startsWith(`..${path_1.default.sep}`) ||
3809
+ path_1.default.isAbsolute(relative)) {
3810
+ throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', 'Artifact project must be inside its Git root.');
3811
+ }
3812
+ const files = fs_1.default
3813
+ .readdirSync(args.sourceDir, { recursive: true, withFileTypes: true })
3814
+ .filter((entry) => entry.isFile())
3815
+ .map((entry) => path_1.default
3816
+ .relative(args.sourceDir, path_1.default.join(entry.parentPath, entry.name))
3817
+ .split(path_1.default.sep)
3818
+ .join('/'))
3819
+ .filter((file) => !isEntryMapped || file !== 'index.html');
3820
+ return store.diffFiles({
3821
+ projectPath: args.projectPath,
3822
+ fromRef: base.commitSha,
3823
+ toRef: tree.commitSha,
3824
+ files,
3825
+ pathPrefix: relative ? `${relative.split(path_1.default.sep).join('/')}/` : '',
3826
+ });
3827
+ }
3828
+ async persistCompletedArtifactVariant(args) {
3693
3829
  const projectContext = this.store.getProjectContext(args.sessionId);
3694
- if (projectContext.kind !== 'fresh')
3695
- return;
3696
- const historyProjectPath = projectContext.workspacePath;
3830
+ const historyProjectPath = projectContext.kind === 'fresh'
3831
+ ? projectContext.workspacePath
3832
+ : (await this.resolveEnv(args.sessionId)).projectPath;
3833
+ const contextRoots = projectContext.kind === 'fresh'
3834
+ ? [projectContext.workspacePath, projectContext.workspaceRoot]
3835
+ : [historyProjectPath];
3697
3836
  const input = this.store.getWorkItemInput(args.sessionId, args.workItemId);
3698
3837
  const sessionPrompt = this.store.getPrompt(args.sessionId);
3699
3838
  const designArtifact = resolveDesignArtifact(input.designContextEntry);
@@ -3713,14 +3852,16 @@ class AgentVariantsOrchestrator {
3713
3852
  stagedHtml = fs_1.default.readFileSync(path_1.default.join(staticPreview.assetBase, 'index.html'), 'utf8');
3714
3853
  }
3715
3854
  catch (err) {
3716
- log.warn(`persistCompletedFreshVariant: could not read index.html for ${args.workItemId}`, err);
3855
+ log.warn(`persistCompletedArtifactVariant: could not read index.html for ${args.workItemId}`, err);
3717
3856
  }
3718
3857
  fs_1.default.writeFileSync(path_1.default.join(tmpStagingDir, 'index.html'), stagedHtml, 'utf8');
3719
- fs_1.default.writeFileSync(path_1.default.join(tmpStagingDir, 'brief.md'), `# ${input.briefLabel}\n\n${input.briefBody}\n`, 'utf8');
3858
+ if (projectContext.kind === 'fresh') {
3859
+ fs_1.default.writeFileSync(path_1.default.join(tmpStagingDir, 'brief.md'), `# ${input.briefLabel}\n\n${input.briefBody}\n`, 'utf8');
3860
+ }
3720
3861
  sourceDir = tmpStagingDir;
3721
3862
  }
3722
3863
  if (!sourceDir) {
3723
- log.warn(`persistCompletedFreshVariant: no source for ${args.workItemId} (session ${args.sessionId}); skipping`);
3864
+ log.warn(`persistCompletedArtifactVariant: no source for ${args.workItemId} (session ${args.sessionId}); skipping`);
3724
3865
  return;
3725
3866
  }
3726
3867
  const changedFilesCount = staticPreview ? 1 : countWorktreeFiles(sourceDir);
@@ -3759,6 +3900,14 @@ class AgentVariantsOrchestrator {
3759
3900
  },
3760
3901
  };
3761
3902
  try {
3903
+ const diff = projectContext.kind === 'existing'
3904
+ ? await this.createArtifactDiff({
3905
+ sessionId: args.sessionId,
3906
+ workItemId: args.workItemId,
3907
+ sourceDir,
3908
+ projectPath: historyProjectPath,
3909
+ })
3910
+ : undefined;
3762
3911
  await this.variantHistory.persistVariant({
3763
3912
  projectPath: historyProjectPath,
3764
3913
  sessionId: args.sessionId,
@@ -3768,20 +3917,18 @@ class AgentVariantsOrchestrator {
3768
3917
  brief: input.briefBody,
3769
3918
  references: input.references,
3770
3919
  referenceContext: input.context,
3771
- referenceContextRoots: [
3772
- projectContext.workspacePath,
3773
- projectContext.workspaceRoot,
3774
- ]
3920
+ referenceContextRoots: contextRoots
3775
3921
  .filter((projectPath) => Boolean(projectPath))
3776
3922
  .map((projectPath) => path_1.default.join(this.variantHistory.store.storage.resolve(projectPath)
3777
3923
  .dataDirectory, 'variant-context')),
3778
3924
  sessionPrompt,
3779
3925
  runLabel: input.runLabel ?? this.store.getRunLabel(args.sessionId),
3780
- kind: 'project-created',
3926
+ kind: projectContext.kind === 'fresh' ? 'project-created' : 'diff',
3927
+ ...(diff !== undefined ? { diff } : {}),
3781
3928
  sourceDir,
3782
3929
  preview,
3783
- changedFilesCount,
3784
- projectKind: 'fresh',
3930
+ changedFilesCount: diff === undefined ? changedFilesCount : countDiffFiles(diff),
3931
+ projectKind: projectContext.kind,
3785
3932
  designMarkdown: designArtifact?.markdown,
3786
3933
  designSource: designArtifact?.source,
3787
3934
  snapshotDir: sourceDir,
@@ -3814,7 +3961,7 @@ class AgentVariantsOrchestrator {
3814
3961
  .filter((variant) => variant.status === 'succeeded');
3815
3962
  for (const variant of variants) {
3816
3963
  try {
3817
- await this.persistCompletedFreshVariant({
3964
+ await this.persistCompletedArtifactVariant({
3818
3965
  sessionId,
3819
3966
  workItemId: variant.workItemId,
3820
3967
  });
@@ -3834,10 +3981,17 @@ class AgentVariantsOrchestrator {
3834
3981
  const status = isChosen
3835
3982
  ? 'committed'
3836
3983
  : 'rejected';
3984
+ const saved = isChosen
3985
+ ? await this.getSavedVariant({
3986
+ projectPath: args.projectPath,
3987
+ sessionId: args.sessionId,
3988
+ variantId: workItemId,
3989
+ })
3990
+ : null;
3837
3991
  await this.variantHistory.markStatus({
3838
3992
  projectPath: args.projectPath,
3839
- sessionId: args.sessionId,
3840
- variantId: workItemId,
3993
+ sessionId: saved?.manifest.sessionId ?? args.sessionId,
3994
+ variantId: saved?.manifest.variantId ?? workItemId,
3841
3995
  status,
3842
3996
  destinationPath: isChosen ? args.destinationPath : undefined,
3843
3997
  runnablePath: args.runnablePaths?.get(workItemId),