rivet-design 0.10.0 → 0.10.2

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 (126) hide show
  1. package/dist/config/flags.d.ts +3 -0
  2. package/dist/config/flags.d.ts.map +1 -1
  3. package/dist/config/flags.js +3 -0
  4. package/dist/config/flags.js.map +1 -1
  5. package/dist/index.d.ts +32 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +249 -3
  8. package/dist/index.js.map +1 -1
  9. package/dist/mcp/agent-variants/SessionStore.d.ts +43 -0
  10. package/dist/mcp/agent-variants/SessionStore.d.ts.map +1 -1
  11. package/dist/mcp/agent-variants/SessionStore.js +174 -9
  12. package/dist/mcp/agent-variants/SessionStore.js.map +1 -1
  13. package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts +21 -0
  14. package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
  15. package/dist/mcp/agent-variants/WorktreeOrchestrator.js +225 -11
  16. package/dist/mcp/agent-variants/WorktreeOrchestrator.js.map +1 -1
  17. package/dist/mcp/agent-variants/contracts.d.ts +13 -4
  18. package/dist/mcp/agent-variants/contracts.d.ts.map +1 -1
  19. package/dist/mcp/agent-variants/contracts.js +4 -1
  20. package/dist/mcp/agent-variants/contracts.js.map +1 -1
  21. package/dist/mcp/agent-variants/errors.d.ts +1 -1
  22. package/dist/mcp/agent-variants/errors.d.ts.map +1 -1
  23. package/dist/mcp/agent-variants/errors.js +1 -0
  24. package/dist/mcp/agent-variants/errors.js.map +1 -1
  25. package/dist/mcp/agent-variants/tools.d.ts.map +1 -1
  26. package/dist/mcp/agent-variants/tools.js +17 -0
  27. package/dist/mcp/agent-variants/tools.js.map +1 -1
  28. package/dist/mcp/changeBatchClassification.d.ts +2 -0
  29. package/dist/mcp/changeBatchClassification.d.ts.map +1 -1
  30. package/dist/mcp/changeBatchClassification.js +7 -0
  31. package/dist/mcp/changeBatchClassification.js.map +1 -1
  32. package/dist/mcp/server.d.ts +25 -0
  33. package/dist/mcp/server.d.ts.map +1 -1
  34. package/dist/mcp/server.js +156 -102
  35. package/dist/mcp/server.js.map +1 -1
  36. package/dist/proxy-middleware/preview-bridge.d.ts +24 -0
  37. package/dist/proxy-middleware/preview-bridge.d.ts.map +1 -0
  38. package/dist/proxy-middleware/preview-bridge.js +358 -0
  39. package/dist/proxy-middleware/preview-bridge.js.map +1 -0
  40. package/dist/proxy-middleware/proxy-config.d.ts +5 -1
  41. package/dist/proxy-middleware/proxy-config.d.ts.map +1 -1
  42. package/dist/proxy-middleware/proxy-config.js +62 -18
  43. package/dist/proxy-middleware/proxy-config.js.map +1 -1
  44. package/dist/routes/controls.d.ts +7 -0
  45. package/dist/routes/controls.d.ts.map +1 -0
  46. package/dist/routes/controls.js +50 -0
  47. package/dist/routes/controls.js.map +1 -0
  48. package/dist/routes/mcp.d.ts +3 -1
  49. package/dist/routes/mcp.d.ts.map +1 -1
  50. package/dist/routes/mcp.js +172 -28
  51. package/dist/routes/mcp.js.map +1 -1
  52. package/dist/routes/static.d.ts +6 -1
  53. package/dist/routes/static.d.ts.map +1 -1
  54. package/dist/routes/static.js +15 -3
  55. package/dist/routes/static.js.map +1 -1
  56. package/dist/server.d.ts +48 -0
  57. package/dist/server.d.ts.map +1 -1
  58. package/dist/server.js +230 -33
  59. package/dist/server.js.map +1 -1
  60. package/dist/services/AgentSessionService.d.ts +87 -0
  61. package/dist/services/AgentSessionService.d.ts.map +1 -0
  62. package/dist/services/AgentSessionService.js +275 -0
  63. package/dist/services/AgentSessionService.js.map +1 -0
  64. package/dist/services/ConfigManager.d.ts +7 -0
  65. package/dist/services/ConfigManager.d.ts.map +1 -1
  66. package/dist/services/ConfigManager.js +13 -0
  67. package/dist/services/ConfigManager.js.map +1 -1
  68. package/dist/services/FeatureFlagService.d.ts.map +1 -1
  69. package/dist/services/FeatureFlagService.js +13 -0
  70. package/dist/services/FeatureFlagService.js.map +1 -1
  71. package/dist/services/HostedDemoAuthSessionService.d.ts +6 -0
  72. package/dist/services/HostedDemoAuthSessionService.d.ts.map +1 -1
  73. package/dist/services/HostedDemoAuthSessionService.js +13 -0
  74. package/dist/services/HostedDemoAuthSessionService.js.map +1 -1
  75. package/dist/services/InlineVariantGenerationService.d.ts +50 -0
  76. package/dist/services/InlineVariantGenerationService.d.ts.map +1 -0
  77. package/dist/services/InlineVariantGenerationService.js +394 -0
  78. package/dist/services/InlineVariantGenerationService.js.map +1 -0
  79. package/dist/services/InterfaceGenerationService.d.ts +12 -0
  80. package/dist/services/InterfaceGenerationService.d.ts.map +1 -0
  81. package/dist/services/InterfaceGenerationService.js +256 -0
  82. package/dist/services/InterfaceGenerationService.js.map +1 -0
  83. package/dist/services/SessionBridgeService.d.ts +11 -3
  84. package/dist/services/SessionBridgeService.d.ts.map +1 -1
  85. package/dist/services/SessionBridgeService.js +35 -3
  86. package/dist/services/SessionBridgeService.js.map +1 -1
  87. package/dist/services/TerminalAgentRunner.d.ts +65 -0
  88. package/dist/services/TerminalAgentRunner.d.ts.map +1 -0
  89. package/dist/services/TerminalAgentRunner.js +511 -0
  90. package/dist/services/TerminalAgentRunner.js.map +1 -0
  91. package/dist/services/WorktreeManager.d.ts +5 -4
  92. package/dist/services/WorktreeManager.d.ts.map +1 -1
  93. package/dist/services/WorktreeManager.js +22 -12
  94. package/dist/services/WorktreeManager.js.map +1 -1
  95. package/dist/services/accessTokenRefresh.d.ts +8 -0
  96. package/dist/services/accessTokenRefresh.d.ts.map +1 -1
  97. package/dist/services/accessTokenRefresh.js +30 -1
  98. package/dist/services/accessTokenRefresh.js.map +1 -1
  99. package/dist/services/createAgentVariantsOrchestrator.d.ts +16 -0
  100. package/dist/services/createAgentVariantsOrchestrator.d.ts.map +1 -0
  101. package/dist/services/createAgentVariantsOrchestrator.js +42 -0
  102. package/dist/services/createAgentVariantsOrchestrator.js.map +1 -0
  103. package/dist/types/change-request-types.d.ts +29 -0
  104. package/dist/types/change-request-types.d.ts.map +1 -1
  105. package/dist/types/editor-interface-types.d.ts +67 -0
  106. package/dist/types/editor-interface-types.d.ts.map +1 -0
  107. package/dist/types/editor-interface-types.js +12 -0
  108. package/dist/types/editor-interface-types.js.map +1 -0
  109. package/dist/utils/elementFileHintSignals.d.ts +8 -0
  110. package/dist/utils/elementFileHintSignals.d.ts.map +1 -0
  111. package/dist/utils/elementFileHintSignals.js +40 -0
  112. package/dist/utils/elementFileHintSignals.js.map +1 -0
  113. package/dist/utils/formatElementTargetingContext.d.ts +34 -0
  114. package/dist/utils/formatElementTargetingContext.d.ts.map +1 -0
  115. package/dist/utils/formatElementTargetingContext.js +88 -0
  116. package/dist/utils/formatElementTargetingContext.js.map +1 -0
  117. package/dist/utils/queueAccess.d.ts +11 -0
  118. package/dist/utils/queueAccess.d.ts.map +1 -0
  119. package/dist/utils/queueAccess.js +15 -0
  120. package/dist/utils/queueAccess.js.map +1 -0
  121. package/package.json +1 -1
  122. package/src/ui/dist/assets/main-C8QYh4jE.css +1 -0
  123. package/src/ui/dist/assets/main-CMk2ORlB.js +645 -0
  124. package/src/ui/dist/index.html +2 -2
  125. package/src/ui/dist/assets/main-BZEruoyc.css +0 -1
  126. package/src/ui/dist/assets/main-CIJUZXe8.js +0 -382
@@ -416,6 +416,106 @@ class AgentVariantsOrchestrator {
416
416
  this.emitChange();
417
417
  return decorated;
418
418
  }
419
+ beginStaticPreviewRefinements(args) {
420
+ const seenVariantIds = new Set();
421
+ for (const target of args.targets) {
422
+ if (seenVariantIds.has(target.variantId))
423
+ continue;
424
+ seenVariantIds.add(target.variantId);
425
+ const currentHtml = this.resources
426
+ .get(args.sessionId)
427
+ ?.staticPreviews.get(target.variantId)?.html ??
428
+ (() => {
429
+ try {
430
+ const output = this.store.getWorkItemOutput(args.sessionId, target.variantId);
431
+ return output?.html;
432
+ }
433
+ catch {
434
+ return undefined;
435
+ }
436
+ })();
437
+ try {
438
+ this.store.createRefineVariantWorkItem({
439
+ sessionId: args.sessionId,
440
+ variantId: target.variantId,
441
+ instruction: target.instruction,
442
+ currentHtml,
443
+ });
444
+ }
445
+ catch (error) {
446
+ if (error instanceof errors_1.AgentVariantsError &&
447
+ error.code === 'PENDING_CHANGE_CONFLICT') {
448
+ // A refinement is already queued for this variant and the newer
449
+ // comment was already consumed from the bridge. Fold it into the
450
+ // still-pending item so it isn't silently dropped.
451
+ const folded = this.store.appendPendingRefineVariantInstruction({
452
+ sessionId: args.sessionId,
453
+ variantId: target.variantId,
454
+ instruction: target.instruction,
455
+ });
456
+ if (!folded) {
457
+ this.store.createRefineVariantWorkItem({
458
+ sessionId: args.sessionId,
459
+ variantId: target.variantId,
460
+ instruction: target.instruction,
461
+ currentHtml,
462
+ });
463
+ }
464
+ continue;
465
+ }
466
+ throw error;
467
+ }
468
+ }
469
+ this.emitChange();
470
+ }
471
+ getVariantPick(sessionId) {
472
+ return this.store.getVariantPick(sessionId);
473
+ }
474
+ refineVariant(args) {
475
+ try {
476
+ const lease = this.store.leaseRefineItemForVariant({
477
+ sessionId: args.sessionId,
478
+ variantId: args.variantId,
479
+ leaseOwner: args.leaseOwner,
480
+ });
481
+ this.emitChange();
482
+ return lease;
483
+ }
484
+ catch (error) {
485
+ if (!(error instanceof errors_1.AgentVariantsError) ||
486
+ error.code !== 'INVALID_STAGE_ACTION' ||
487
+ !error.message.includes('No pending refinement exists')) {
488
+ throw error;
489
+ }
490
+ }
491
+ const currentHtml = this.resources
492
+ .get(args.sessionId)
493
+ ?.staticPreviews.get(args.variantId)?.html ??
494
+ (() => {
495
+ try {
496
+ const output = this.store.getWorkItemOutput(args.sessionId, args.variantId);
497
+ return output?.html;
498
+ }
499
+ catch {
500
+ return undefined;
501
+ }
502
+ })();
503
+ const refineItem = this.store.createRefineVariantWorkItem({
504
+ sessionId: args.sessionId,
505
+ variantId: args.variantId,
506
+ instruction: args.instruction,
507
+ currentHtml,
508
+ });
509
+ // Lease the just-created refine item by id. A generic
510
+ // requestWork({ requestedLeaseCount: 1 }) takes the first leasable item in
511
+ // work-item order, which could be an unrelated still-pending static_preview
512
+ // rather than this refinement.
513
+ return this.requestWork({
514
+ sessionId: args.sessionId,
515
+ leaseOwner: args.leaseOwner,
516
+ workItemId: refineItem.id,
517
+ });
518
+ }
419
519
  getStage(sessionId) {
420
520
  return this.store.getStage(sessionId);
421
521
  }
@@ -512,6 +612,13 @@ class AgentVariantsOrchestrator {
512
612
  return this.resources.get(sessionId)?.worktrees.get(workItemId)
513
613
  ?.worktreePath;
514
614
  }
615
+ /**
616
+ * Resolve the project cwd inside a worktree so subdirectory projects run
617
+ * from the same repo-relative location.
618
+ */
619
+ getProjectCwdInWorktree(worktreePath) {
620
+ return this.worktrees.getProjectCwdInWorktree(worktreePath);
621
+ }
515
622
  /** Resolve the dev server port for a code-gen work item, if running. */
516
623
  getDevServerPort(sessionId, workItemId) {
517
624
  return this.resources.get(sessionId)?.worktrees.get(workItemId)?.port;
@@ -586,7 +693,8 @@ class AgentVariantsOrchestrator {
586
693
  // plant a symlink under the base (e.g. via a follow-up Write tool call)
587
694
  // could pivot outside the sandbox.
588
695
  const target = path_1.default.resolve(record.assetBase, '.' + path_1.default.sep + requestedPath);
589
- if (target !== record.assetBase && !target.startsWith(record.assetBase + path_1.default.sep)) {
696
+ if (target !== record.assetBase &&
697
+ !target.startsWith(record.assetBase + path_1.default.sep)) {
590
698
  return undefined;
591
699
  }
592
700
  let realTarget;
@@ -769,6 +877,9 @@ class AgentVariantsOrchestrator {
769
877
  };
770
878
  }
771
879
  async reportComplete(args) {
880
+ const workItemKind = this.store.hasSession(args.sessionId)
881
+ ? this.store.getWorkItemKind(args.sessionId, args.workItemId)
882
+ : undefined;
772
883
  // Contract validation: a `succeeded` static_preview report MUST carry the
773
884
  // deliverable inline as `output.html` (with optional `css` / `js`). Agents
774
885
  // sometimes default to writing files to disk and reporting back a file
@@ -778,10 +889,10 @@ class AgentVariantsOrchestrator {
778
889
  // of silently producing an empty-preview run.
779
890
  if (args.status === 'succeeded' &&
780
891
  this.store.hasSession(args.sessionId) &&
781
- this.store.getWorkItemKind(args.sessionId, args.workItemId) ===
782
- 'static_preview' &&
892
+ (workItemKind === 'static_preview' ||
893
+ workItemKind === 'refine_variant') &&
783
894
  !parseStaticPreviewOutput(normalizeOutput(args.output))) {
784
- throw new errors_1.AgentVariantsError('SCHEMA_VALIDATION_FAILED', 'static_preview report_variant_complete requires output.html (string, non-empty). ' +
895
+ throw new errors_1.AgentVariantsError('SCHEMA_VALIDATION_FAILED', `${workItemKind} report_variant_complete requires output.html (string, non-empty). ` +
785
896
  'Pass the full HTML inline as output: { html: "<!doctype html>...", css?: "...", js?: "..." }. ' +
786
897
  'Do NOT write the HTML to a file and report a file list — Rivet renders the HTML inline; on-disk files are not read.');
787
898
  }
@@ -790,8 +901,45 @@ class AgentVariantsOrchestrator {
790
901
  // verdict converts the report to `failed` with code `VARIANT_QA_FAILED`
791
902
  // so the variant never reaches `ready` and `getVariants` can disable
792
903
  // its commit action.
793
- const qaOverride = await this.evaluateQaForReport(args);
794
- const effectiveArgs = qaOverride?.overrideArgs ?? args;
904
+ const qaOverride = workItemKind === 'refine_variant'
905
+ ? null
906
+ : await this.evaluateQaForReport(args);
907
+ let effectiveArgs = qaOverride?.overrideArgs ?? args;
908
+ // For a successful refine_variant, swap the refined static preview into
909
+ // place and persist history BEFORE recording success in the store. This
910
+ // keeps the user-visible `refinement.status: succeeded` (and the snapshot
911
+ // emitted below) from ever being observable while the variant still serves
912
+ // stale HTML. If post-processing throws, convert the report to `failed` so
913
+ // the agent/UI surface the failure instead of a success pointing at
914
+ // unrefreshed output.
915
+ if (workItemKind === 'refine_variant' &&
916
+ effectiveArgs.status === 'succeeded') {
917
+ try {
918
+ this.store.validateReportLease({
919
+ sessionId: args.sessionId,
920
+ workItemId: args.workItemId,
921
+ leaseId: args.leaseId,
922
+ attempt: args.attempt,
923
+ });
924
+ await this.handleStaticPreviewRefinement({
925
+ sessionId: args.sessionId,
926
+ workItemId: args.workItemId,
927
+ output: args.output,
928
+ });
929
+ }
930
+ catch (err) {
931
+ log.error(`handleStaticPreviewRefinement failed for ${args.sessionId}/${args.workItemId}`, err);
932
+ const code = err instanceof errors_1.AgentVariantsError ? err.code : 'INTERNAL_ERROR';
933
+ const message = err instanceof Error
934
+ ? err.message
935
+ : 'Static preview refinement post-processing failed';
936
+ effectiveArgs = {
937
+ ...effectiveArgs,
938
+ status: 'failed',
939
+ error: { code, message },
940
+ };
941
+ }
942
+ }
795
943
  const result = this.store.reportComplete(effectiveArgs);
796
944
  this.emitChange();
797
945
  // Per-variant telemetry on terminal item statuses (skip 'running'
@@ -848,7 +996,8 @@ class AgentVariantsOrchestrator {
848
996
  });
849
997
  }
850
998
  }
851
- if (effectiveArgs.status === 'succeeded') {
999
+ if (effectiveArgs.status === 'succeeded' &&
1000
+ workItemKind !== 'refine_variant') {
852
1001
  void this.handleSucceededReport({
853
1002
  sessionId: args.sessionId,
854
1003
  workItemId: args.workItemId,
@@ -1075,8 +1224,7 @@ class AgentVariantsOrchestrator {
1075
1224
  if (!anyAssetBaseIsDestination) {
1076
1225
  const allowed = new Set();
1077
1226
  for (const sp of resources.staticPreviews.values()) {
1078
- if (sp.assetBase &&
1079
- isStrictlyInside(sp.assetBase, compareBase)) {
1227
+ if (sp.assetBase && isStrictlyInside(sp.assetBase, compareBase)) {
1080
1228
  allowed.add(path_1.default.basename(sp.assetBase));
1081
1229
  }
1082
1230
  }
@@ -1426,7 +1574,9 @@ class AgentVariantsOrchestrator {
1426
1574
  payloadKind: payload.kind,
1427
1575
  destinationPath: envelopeDestination,
1428
1576
  ...(committedPreviewPort
1429
- ? { previewUrl: `http://${FRESH_DEV_SERVER_HOST}:${committedPreviewPort}` }
1577
+ ? {
1578
+ previewUrl: `http://${FRESH_DEV_SERVER_HOST}:${committedPreviewPort}`,
1579
+ }
1430
1580
  : {}),
1431
1581
  };
1432
1582
  }
@@ -1697,6 +1847,10 @@ class AgentVariantsOrchestrator {
1697
1847
  return null;
1698
1848
  if (!this.store.hasSession(args.sessionId))
1699
1849
  return null;
1850
+ if (this.store.getWorkItemKind(args.sessionId, args.workItemId) !==
1851
+ 'static_preview') {
1852
+ return null;
1853
+ }
1700
1854
  const projectContext = this.store.getProjectContext(args.sessionId);
1701
1855
  if (projectContext.kind !== 'fresh')
1702
1856
  return null;
@@ -1868,6 +2022,64 @@ class AgentVariantsOrchestrator {
1868
2022
  log.warn(`Failed to start dev server for variant ${workItemId}; live preview disabled for this variant`, err);
1869
2023
  }
1870
2024
  }
2025
+ async handleStaticPreviewRefinement(args) {
2026
+ const resources = this.resources.get(args.sessionId);
2027
+ if (!resources) {
2028
+ throw new errors_1.AgentVariantsError('SESSION_NOT_FOUND', `No live resources for session ${args.sessionId}`);
2029
+ }
2030
+ const input = this.store.getWorkItemInput(args.sessionId, args.workItemId);
2031
+ if (!input.variantId) {
2032
+ throw new errors_1.AgentVariantsError('MISSING_REQUIRED_INPUT', 'refine_variant work item is missing variantId');
2033
+ }
2034
+ const parsed = parseStaticPreviewOutput(normalizeOutput(args.output));
2035
+ if (!parsed) {
2036
+ throw new errors_1.AgentVariantsError('SCHEMA_VALIDATION_FAILED', 'refine_variant report_variant_complete requires output.html');
2037
+ }
2038
+ const targetInput = this.store.getWorkItemInput(args.sessionId, input.variantId);
2039
+ if (!targetInput.briefId) {
2040
+ throw new errors_1.AgentVariantsError('VARIANT_NOT_EDITABLE', 'Target static_preview variant is missing briefId');
2041
+ }
2042
+ const resolvedAssetBase = resolveStaticPreviewAssetBase({
2043
+ assetBase: parsed.assetBase,
2044
+ projectContext: this.store.getProjectContext(args.sessionId),
2045
+ });
2046
+ // A refinement that only rewrites HTML won't re-declare an assetBase, but
2047
+ // the refined markup can still reference the original sibling assets
2048
+ // (images, GLB, fonts). Fall back to the variant's existing asset base so
2049
+ // those relative URLs keep resolving instead of 404ing after the swap.
2050
+ const previousAssetBase = resources.staticPreviews.get(input.variantId)?.assetBase;
2051
+ const assetBase = resolvedAssetBase ?? previousAssetBase;
2052
+ // Swap the served preview to the refined HTML. This is the critical step:
2053
+ // once this is in place the success the caller records (and the snapshot it
2054
+ // emits) never serves stale HTML. It runs before store.reportComplete so a
2055
+ // validation failure above converts to a `failed` report rather than a
2056
+ // success pointing at unrefreshed output.
2057
+ this.store.replaceWorkItemOutput(args.sessionId, input.variantId, {
2058
+ ...parsed,
2059
+ ...(assetBase ? { assetBase } : {}),
2060
+ });
2061
+ resources.staticPreviews.set(input.variantId, {
2062
+ workItemId: input.variantId,
2063
+ briefId: targetInput.briefId,
2064
+ html: parsed.html,
2065
+ ...(assetBase ? { assetBase } : {}),
2066
+ });
2067
+ // History persistence is best-effort, mirroring handleSucceededReport's
2068
+ // fire-and-forget persistence for freshly completed variants. A failure
2069
+ // here (e.g. a transient filesystem race) must not fail the refinement or
2070
+ // discard the already-serving refined HTML.
2071
+ try {
2072
+ await this.persistCompletedFreshVariant({
2073
+ sessionId: args.sessionId,
2074
+ workItemId: input.variantId,
2075
+ });
2076
+ }
2077
+ catch (err) {
2078
+ log.warn(`persistCompletedFreshVariant failed for refined variant ${input.variantId} (session ${args.sessionId}); preview already swapped`, err);
2079
+ }
2080
+ // The caller (reportComplete) emits the change after recording success so
2081
+ // the snapshot reflects both the swapped HTML and refinement.status.
2082
+ }
1871
2083
  /**
1872
2084
  * Persist a completed existing-project code_gen variant into
1873
2085
  * `<env.projectPath>/.rivet/variants/<sessionId>/<variantId>/`. Called from
@@ -1887,7 +2099,9 @@ class AgentVariantsOrchestrator {
1887
2099
  log.warn(`persistCompletedExistingVariant: resolveEnv failed for ${args.sessionId}`, err);
1888
2100
  return;
1889
2101
  }
1890
- const record = this.resources.get(args.sessionId)?.worktrees.get(args.workItemId);
2102
+ const record = this.resources
2103
+ .get(args.sessionId)
2104
+ ?.worktrees.get(args.workItemId);
1891
2105
  let sourceDir;
1892
2106
  if (env.framework === 'static' && record) {
1893
2107
  try {