rivet-design 0.25.0 → 0.26.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 (63) hide show
  1. package/README.md +2 -2
  2. package/README.npm.md +2 -2
  3. package/dist/agent-variants/PreviewRuntime.d.ts +1 -20
  4. package/dist/agent-variants/PreviewRuntime.js +1 -102
  5. package/dist/agent-variants/SessionStore.d.ts +1 -8
  6. package/dist/agent-variants/SessionStore.js +2 -32
  7. package/dist/agent-variants/WorkspaceInventory.d.ts +0 -3
  8. package/dist/agent-variants/WorkspaceInventory.js +5 -28
  9. package/dist/agent-variants/WorktreeOrchestrator.d.ts +1 -30
  10. package/dist/agent-variants/WorktreeOrchestrator.js +4 -643
  11. package/dist/agent-variants/WorktreeOrchestrator.testHelpers.d.ts +0 -7
  12. package/dist/agent-variants/WorktreeOrchestrator.testHelpers.js +0 -34
  13. package/dist/agent-variants/contracts.d.ts +0 -60
  14. package/dist/agent-variants/contracts.js +1 -8
  15. package/dist/agent-variants/index.d.ts +1 -1
  16. package/dist/agent-variants/runPlan.d.ts +0 -2
  17. package/dist/agent-variants/runPlan.js +0 -3
  18. package/dist/agent-variants/variant-project-runtime.d.ts +0 -2
  19. package/dist/agent-variants/variantWorkspaceFiles.d.ts +0 -3
  20. package/dist/agent-variants/variantWorkspaceFiles.js +1 -59
  21. package/dist/agent-variants/variantsTelemetry.d.ts +0 -8
  22. package/dist/cli/commands/mcpServe.d.ts +2 -2
  23. package/dist/cli/commands/mcpServe.js +1 -0
  24. package/dist/cli/commands/variants.js +2 -43
  25. package/dist/cli/router.js +3 -2
  26. package/dist/config/flags.d.ts +0 -3
  27. package/dist/config/flags.js +0 -1
  28. package/dist/config/pluginMetrics.js +0 -4
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.js +20 -8
  31. package/dist/install/mcpRegistration.js +1 -0
  32. package/dist/mcp/explorationTools.js +0 -17
  33. package/dist/routes/account.js +4 -2
  34. package/dist/routes/agentVariants.js +1 -89
  35. package/dist/routes/library/browserAccess.d.ts +3 -1
  36. package/dist/routes/library/browserAccess.js +5 -3
  37. package/dist/routes/library/index.js +1 -0
  38. package/dist/services/AuthService.js +2 -2
  39. package/dist/services/ConfigManager.d.ts +18 -1
  40. package/dist/services/ConfigManager.js +91 -4
  41. package/dist/services/SessionBridgeService.d.ts +0 -2
  42. package/dist/services/SessionBridgeService.js +0 -26
  43. package/dist/services/TelemetryService.d.ts +4 -15
  44. package/dist/services/TelemetryService.js +29 -33
  45. package/dist/services/VariantRunService.d.ts +0 -5
  46. package/dist/services/VariantRunService.js +0 -3
  47. package/dist/services/WorktreeManager.d.ts +0 -3
  48. package/dist/services/WorktreeManager.js +7 -54
  49. package/dist/services/createAgentVariantsOrchestrator.js +0 -1
  50. package/dist/services/profiles/DesignProfiles.js +4 -3
  51. package/dist/utils/skills/claude-skill.d.ts +1 -1
  52. package/dist/utils/skills/claude-skill.js +1 -1
  53. package/dist/utils/skills/cli-guidance.d.ts +1 -1
  54. package/dist/utils/skills/cli-guidance.js +6 -8
  55. package/dist/utils/skills/cursor-rules.d.ts +1 -1
  56. package/dist/utils/skills/cursor-rules.js +1 -1
  57. package/package.json +3 -3
  58. package/src/ui/dist/assets/{LibraryEntry-BJl_pPMq.js → LibraryEntry-CFkd6v_O.js} +9 -9
  59. package/src/ui/dist/assets/main-B_jie9r3.js +439 -0
  60. package/src/ui/dist/index.html +1 -1
  61. package/dist/agent-variants/createProjectArtifacts.d.ts +0 -61
  62. package/dist/agent-variants/createProjectArtifacts.js +0 -113
  63. package/src/ui/dist/assets/main-D1832qVC.js +0 -439
@@ -13,15 +13,12 @@ const events_1 = require("events");
13
13
  const fs_1 = __importDefault(require("fs"));
14
14
  const path_1 = __importDefault(require("path"));
15
15
  const DependencyPreparationService_1 = require("../services/DependencyPreparationService");
16
- const simple_git_1 = require("simple-git");
17
16
  const logger_1 = require("../utils/logger");
18
17
  const errors_1 = require("./errors");
19
- const createProjectArtifacts_1 = require("./createProjectArtifacts");
20
18
  const contracts_1 = require("./contracts");
21
19
  const workItemBriefing_1 = require("./workItemBriefing");
22
20
  const briefContent_1 = require("./briefContent");
23
21
  const runLabel_1 = require("./runLabel");
24
- const runPlan_1 = require("./runPlan");
25
22
  const previewQa_1 = require("./previewQa");
26
23
  const WorkspaceInventory_1 = require("./WorkspaceInventory");
27
24
  const WorkspaceProvisioning_1 = require("./WorkspaceProvisioning");
@@ -32,7 +29,6 @@ const variantContext_1 = require("./variantContext");
32
29
  const designContext_1 = require("./designContext");
33
30
  const variantsTelemetry_1 = require("./variantsTelemetry");
34
31
  const variantWorkspaceFiles_1 = require("./variantWorkspaceFiles");
35
- const errnoCode_1 = require("../utils/errnoCode");
36
32
  const errorMessage_1 = require("../utils/errorMessage");
37
33
  const pathContainment_1 = require("../utils/pathContainment");
38
34
  var variantWorkspaceFiles_2 = require("./variantWorkspaceFiles");
@@ -201,7 +197,6 @@ class AgentVariantsOrchestrator {
201
197
  resolveEnv;
202
198
  telemetry;
203
199
  installDependencies;
204
- materializeProject;
205
200
  previewQaRunner;
206
201
  variantHistory;
207
202
  provisionTimeoutMs;
@@ -211,7 +206,6 @@ class AgentVariantsOrchestrator {
211
206
  workspaceInventory;
212
207
  workspaceProvisioning;
213
208
  previewRuntime;
214
- inflightCommits = new Map();
215
209
  activeSessionId = null;
216
210
  events = new events_1.EventEmitter();
217
211
  constructor(deps) {
@@ -225,8 +219,6 @@ class AgentVariantsOrchestrator {
225
219
  this.telemetry = deps.telemetry ?? variantsTelemetry_1.NOOP_TELEMETRY;
226
220
  this.installDependencies =
227
221
  deps.installDependencies ?? variantWorkspaceFiles_1.defaultInstallDependencies;
228
- this.materializeProject =
229
- deps.materializeProject ?? variantWorkspaceFiles_1.defaultMaterializeProject;
230
222
  this.previewQaRunner = deps.previewQaRunner ?? defaultPreviewQaRunner;
231
223
  this.variantHistory = deps.variantHistory ?? new VariantHistoryService_1.VariantHistoryService();
232
224
  this.provisionTimeoutMs = deps.provisionTimeoutMs ?? PROVISION_TIMEOUT_MS;
@@ -258,16 +250,11 @@ class AgentVariantsOrchestrator {
258
250
  hasUiClients: () => this.uiClientCount > 0,
259
251
  changed: () => this.emitChange(),
260
252
  switchPreviewPort: deps.switchPreviewPort,
261
- setCommittedDevServerHealth: deps.setCommittedDevServerHealth,
262
- startStaticPreviewServer: deps.startStaticPreviewServer,
263
253
  activeVariantServerIdleTtlMs: this.activeVariantServerIdleTtlMs,
264
254
  devServerRestartDelayMs: this.devServerRestartDelayMs,
265
255
  });
266
256
  }
267
257
  propose(args) {
268
- void this.previewRuntime.stopLingeringCommitted().catch((err) => {
269
- log.warn('Stopping lingering committed dev servers failed', err);
270
- });
271
258
  const result = this.store.propose(args);
272
259
  this.activeSessionId = result.sessionId;
273
260
  this.ensureResources(result.sessionId);
@@ -885,9 +872,6 @@ class AgentVariantsOrchestrator {
885
872
  entryPath: args.entryPath,
886
873
  isWebsite: Boolean(args.previewRoutes?.length),
887
874
  });
888
- void this.previewRuntime.stopLingeringCommitted().catch((err) => {
889
- log.warn('Stopping lingering committed dev servers failed', err);
890
- });
891
875
  const created = this.store.createSessionFromStaticHistoryVariant({
892
876
  source: args.source,
893
877
  prompt: args.prompt ?? args.description ?? args.label,
@@ -945,9 +929,6 @@ class AgentVariantsOrchestrator {
945
929
  return { sessionId, variantId: sourceVariantId };
946
930
  }
947
931
  }
948
- getVariantPick(sessionId) {
949
- return this.store.getVariantPick(sessionId);
950
- }
951
932
  refineVariant(args) {
952
933
  this.telemetry.trackAgentVariantsRefinementRequested?.({
953
934
  sessionId: args.sessionId,
@@ -1058,7 +1039,6 @@ class AgentVariantsOrchestrator {
1058
1039
  }
1059
1040
  const qa = resources?.qaResults.get(variant.workItemId);
1060
1041
  const isSucceeded = variant.status === 'succeeded';
1061
- const qaFailed = qa?.status === 'failed';
1062
1042
  const canView = Boolean(preview) || (isSucceeded && Boolean(port));
1063
1043
  const previewFailure = this.previewRuntime.getFailure(sessionId, variant.workItemId);
1064
1044
  const previewUnavailable = !canView && isSucceeded && previewFailure
@@ -1067,10 +1047,6 @@ class AgentVariantsOrchestrator {
1067
1047
  portInUse: previewFailure.portInUse || undefined,
1068
1048
  }
1069
1049
  : undefined;
1070
- const canCommit = isSucceeded && !qaFailed;
1071
- const commitDisabledReason = qaFailed
1072
- ? (qa?.summary ?? 'Variant failed QA')
1073
- : 'Wait for a successful variant';
1074
1050
  return {
1075
1051
  ...variant,
1076
1052
  design: (0, designContext_1.enrichDesignSource)(variant.design),
@@ -1090,12 +1066,6 @@ class AgentVariantsOrchestrator {
1090
1066
  qa,
1091
1067
  }),
1092
1068
  },
1093
- commit: canCommit
1094
- ? { enabled: true }
1095
- : {
1096
- enabled: false,
1097
- reason: commitDisabledReason,
1098
- },
1099
1069
  },
1100
1070
  };
1101
1071
  });
@@ -1460,8 +1430,6 @@ class AgentVariantsOrchestrator {
1460
1430
  const ctx = this.store.getProjectContext(sessionId);
1461
1431
  if (ctx.kind !== 'existing' || ctx.projectPath !== projectPath)
1462
1432
  return null;
1463
- if (this.store.getVariantPick(sessionId))
1464
- return null;
1465
1433
  const stage = this.store.getStage(sessionId);
1466
1434
  if (stage === 'cancelled' || stage === 'failed')
1467
1435
  return null;
@@ -1825,385 +1793,8 @@ class AgentVariantsOrchestrator {
1825
1793
  sessionStage: result.sessionStage,
1826
1794
  };
1827
1795
  }
1828
- async commitVariant(args) {
1829
- const prior = this.inflightCommits.get(args.sessionId);
1830
- const run = (async () => {
1831
- if (prior) {
1832
- await prior.catch(() => undefined);
1833
- }
1834
- return this.commitVariantImpl(args);
1835
- })();
1836
- this.inflightCommits.set(args.sessionId, run);
1837
- try {
1838
- return await run;
1839
- }
1840
- catch (error) {
1841
- this.telemetry.trackAgentVariantsCommitFailed?.({
1842
- sessionId: args.sessionId,
1843
- targetVariantId: args.variantId,
1844
- mode: 'commit',
1845
- requestStatus: 'failed',
1846
- failureReason: error,
1847
- });
1848
- throw error;
1849
- }
1850
- finally {
1851
- if (this.inflightCommits.get(args.sessionId) === run) {
1852
- this.inflightCommits.delete(args.sessionId);
1853
- }
1854
- }
1855
- }
1856
- async commitVariantImpl(args) {
1857
- const existingPick = this.store.getVariantPick(args.sessionId);
1858
- if (existingPick && existingPick.variantId === args.variantId) {
1859
- const projectContext = this.store.getProjectContext(args.sessionId);
1860
- let historyProjectPath;
1861
- if (projectContext.kind === 'fresh') {
1862
- historyProjectPath = projectContext.workspacePath;
1863
- }
1864
- else {
1865
- try {
1866
- historyProjectPath = (await this.resolveEnv(args.sessionId))
1867
- ?.projectPath;
1868
- }
1869
- catch {
1870
- historyProjectPath = undefined;
1871
- }
1872
- }
1873
- if (historyProjectPath) {
1874
- void this.persistVariantHistoryAtCommit({
1875
- sessionId: args.sessionId,
1876
- chosenVariantId: args.variantId,
1877
- projectPath: historyProjectPath,
1878
- projectKind: projectContext.kind,
1879
- destinationPath: existingPick.destinationPath ?? historyProjectPath,
1880
- }).catch((err) => {
1881
- log.warn(`persistVariantHistoryAtCommit (duplicate retry) failed for session ${args.sessionId}`, err);
1882
- });
1883
- }
1884
- const replayPort = this.previewRuntime.getCommittedPort(args.sessionId);
1885
- return {
1886
- enqueued: false,
1887
- duplicate: true,
1888
- changedFilesCount: existingPick.changedFilesCount,
1889
- payloadKind: existingPick.payload.kind === 'new-project'
1890
- ? 'project-created'
1891
- : existingPick.payload.kind,
1892
- destinationPath: existingPick.destinationPath,
1893
- ...(replayPort
1894
- ? { previewUrl: `http://${FRESH_DEV_SERVER_HOST}:${replayPort}` }
1895
- : {}),
1896
- };
1897
- }
1898
- const resources = this.resources.get(args.sessionId);
1899
- if (!resources) {
1900
- throw new errors_1.AgentVariantsError('SESSION_NOT_FOUND', `No live resources for session ${args.sessionId} (already torn down?)`);
1901
- }
1902
- const variantSnapshot = this.getVariants(args.sessionId).find((variant) => variant.workItemId === args.variantId);
1903
- if (!variantSnapshot || variantSnapshot.actions?.commit?.enabled !== true) {
1904
- throw new errors_1.AgentVariantsError('INVALID_STAGE_ACTION', variantSnapshot?.actions?.commit?.reason ??
1905
- 'Variant is not committable');
1906
- }
1907
- await this.settleHistoryPersists();
1908
- const input = this.store.requireVariantWorkItemInput({
1909
- sessionId: args.sessionId,
1910
- workItemId: args.variantId,
1911
- kinds: ['code_gen', 'static_preview'],
1912
- });
1913
- const projectContext = this.store.getProjectContext(args.sessionId);
1914
- if (projectContext.kind === 'fresh') {
1915
- await this.persistCompletedFreshVariantsForCommit(args.sessionId);
1916
- }
1917
- let payload;
1918
- let envelopeDestination;
1919
- let changedFilesCount;
1920
- let runnablePaths;
1921
- let committedPreviewPort;
1922
- if (projectContext.kind === 'fresh') {
1923
- const destinationPath = projectContext.workspacePath;
1924
- let realDestination;
1925
- try {
1926
- realDestination = fs_1.default.realpathSync(destinationPath);
1927
- }
1928
- catch {
1929
- realDestination = undefined;
1930
- }
1931
- const commitPolicy = (0, runPlan_1.resolveRunPlanPolicy)(projectContext).commit;
1932
- const isViteApp = commitPolicy === 'materialize_project';
1933
- if (isViteApp) {
1934
- this.assertDestinationAvailable(destinationPath);
1935
- }
1936
- else {
1937
- const compareBase = realDestination ?? destinationPath;
1938
- const anyAssetBaseIsDestination = [
1939
- ...this.workspaceInventory.getStaticPreviews(args.sessionId),
1940
- ].some((sp) => sp.assetBase === compareBase);
1941
- if (!anyAssetBaseIsDestination) {
1942
- const allowed = new Set();
1943
- for (const sp of this.workspaceInventory.getStaticPreviews(args.sessionId)) {
1944
- if (sp.assetBase &&
1945
- (0, pathContainment_1.isPathStrictlyInsideRoot)(compareBase, sp.assetBase)) {
1946
- allowed.add(path_1.default.basename(sp.assetBase));
1947
- }
1948
- }
1949
- this.assertDestinationAvailable(destinationPath, allowed);
1950
- }
1951
- }
1952
- if (isViteApp) {
1953
- const record = this.workspaceInventory.getWorktree(args.sessionId, args.variantId);
1954
- if (!record) {
1955
- throw new errors_1.AgentVariantsError('WORK_ITEM_NOT_FOUND', `Unknown variantId ${args.variantId} for session ${args.sessionId}`);
1956
- }
1957
- let usedRename = false;
1958
- let isDependencyInstallRequired = false;
1959
- try {
1960
- if ((0, variantWorkspaceFiles_1.areSameVolume)(record.worktreePath, destinationPath)) {
1961
- await this.previewRuntime.stopVariantServers(args.sessionId);
1962
- isDependencyInstallRequired = await (0, variantWorkspaceFiles_1.resolveNodeModulesSymlink)(record.worktreePath);
1963
- await this.renameWorktreeIntoDestination(record.worktreePath, destinationPath);
1964
- usedRename = true;
1965
- }
1966
- else {
1967
- await this.materializeProject(record.worktreePath, destinationPath);
1968
- }
1969
- }
1970
- catch (err) {
1971
- const message = (0, errorMessage_1.errorMessage)(err);
1972
- throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', `Failed to materialize vite_app variant to ${destinationPath}: ${message}`);
1973
- }
1974
- changedFilesCount = (0, variantWorkspaceFiles_1.countWorktreeFiles)(destinationPath);
1975
- if (!usedRename) {
1976
- void this.installDependencies(destinationPath)
1977
- .then(() => this.previewRuntime.startCommitted({
1978
- sessionId: args.sessionId,
1979
- destinationPath,
1980
- }))
1981
- .catch((err) => {
1982
- log.warn(`Background install + committed dev server start after vite_app commit failed for ${destinationPath}`, err);
1983
- });
1984
- }
1985
- else if (isDependencyInstallRequired) {
1986
- await this.installDependencies(destinationPath);
1987
- }
1988
- if (usedRename) {
1989
- try {
1990
- runnablePaths = this.preserveUnchosenVariants({
1991
- sessionId: args.sessionId,
1992
- chosenVariantId: args.variantId,
1993
- destinationPath,
1994
- });
1995
- }
1996
- catch (err) {
1997
- log.warn(`preserveUnchosenVariants failed for session ${args.sessionId}; continuing without history`, err);
1998
- }
1999
- committedPreviewPort = await this.previewRuntime.startCommitted({
2000
- sessionId: args.sessionId,
2001
- destinationPath,
2002
- mode: 'vite_app',
2003
- });
2004
- }
2005
- payload = {
2006
- kind: 'project-created',
2007
- destinationPath,
2008
- changedFilesCount,
2009
- note: usedRename
2010
- ? 'Vite app moved to destinationPath (rename); node_modules came along.'
2011
- : 'Vite app materialized at destinationPath; `npm install` running in the background.',
2012
- };
2013
- envelopeDestination = destinationPath;
2014
- }
2015
- else {
2016
- const staticPreview = this.workspaceInventory.getStaticPreview(args.sessionId, args.variantId);
2017
- const htmlFromDir = staticPreview
2018
- ? this.getStaticPreviewHtml(args.sessionId, args.variantId)
2019
- : undefined;
2020
- const htmlFromSnapshot = await this.variantHistory.readStaticPreview({
2021
- projectPath: projectContext.workspacePath,
2022
- sessionId: args.sessionId,
2023
- variantId: args.variantId,
2024
- });
2025
- if (!staticPreview && !htmlFromSnapshot) {
2026
- throw new errors_1.AgentVariantsError('INVALID_STAGE_ACTION', `No static preview found for variant ${args.variantId} — wait for report_variant_complete(succeeded) first`);
2027
- }
2028
- try {
2029
- fs_1.default.mkdirSync(destinationPath, { recursive: true });
2030
- let flattenBase = realDestination;
2031
- if (!flattenBase) {
2032
- try {
2033
- flattenBase = fs_1.default.realpathSync(destinationPath);
2034
- }
2035
- catch {
2036
- flattenBase = destinationPath;
2037
- }
2038
- }
2039
- const chosenAssetBase = staticPreview?.assetBase;
2040
- if (chosenAssetBase &&
2041
- (0, pathContainment_1.isPathStrictlyInsideRoot)(flattenBase, chosenAssetBase)) {
2042
- for (const entry of fs_1.default.readdirSync(chosenAssetBase)) {
2043
- const src = path_1.default.join(chosenAssetBase, entry);
2044
- const dst = path_1.default.join(flattenBase, entry);
2045
- if (path_1.default.resolve(dst) === path_1.default.resolve(chosenAssetBase)) {
2046
- continue;
2047
- }
2048
- if (fs_1.default.existsSync(dst)) {
2049
- fs_1.default.rmSync(dst, { recursive: true, force: true });
2050
- }
2051
- try {
2052
- fs_1.default.renameSync(src, dst);
2053
- }
2054
- catch (err) {
2055
- if ((0, errnoCode_1.errnoCode)(err) !== 'EXDEV')
2056
- throw err;
2057
- fs_1.default.cpSync(src, dst, { recursive: true });
2058
- fs_1.default.rmSync(src, { recursive: true, force: true });
2059
- }
2060
- }
2061
- fs_1.default.rmSync(chosenAssetBase, { recursive: true, force: true });
2062
- }
2063
- for (const other of this.workspaceInventory.getStaticPreviews(args.sessionId)) {
2064
- if (other.workItemId === args.variantId)
2065
- continue;
2066
- if (other.assetBase &&
2067
- (0, pathContainment_1.isPathStrictlyInsideRoot)(flattenBase, other.assetBase)) {
2068
- fs_1.default.rmSync(other.assetBase, { recursive: true, force: true });
2069
- }
2070
- }
2071
- fs_1.default.writeFileSync(path_1.default.join(destinationPath, 'index.html'), htmlFromDir ?? htmlFromSnapshot ?? '', 'utf8');
2072
- }
2073
- catch (err) {
2074
- const message = (0, errorMessage_1.errorMessage)(err);
2075
- throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', `Failed to write static preview to ${destinationPath}: ${message}`);
2076
- }
2077
- changedFilesCount = (0, variantWorkspaceFiles_1.countWorktreeFiles)(destinationPath);
2078
- committedPreviewPort = await this.previewRuntime.startCommitted({
2079
- sessionId: args.sessionId,
2080
- destinationPath,
2081
- mode: 'static_preview',
2082
- });
2083
- payload = {
2084
- kind: 'project-created',
2085
- destinationPath,
2086
- changedFilesCount,
2087
- note: 'Static preview written to index.html at destinationPath.',
2088
- };
2089
- envelopeDestination = destinationPath;
2090
- }
2091
- }
2092
- else {
2093
- const env = await this.resolveEnv(args.sessionId);
2094
- const record = this.workspaceInventory.getWorktree(args.sessionId, args.variantId);
2095
- const saved = record
2096
- ? null
2097
- : await this.getSavedVariant({
2098
- projectPath: env.projectPath,
2099
- sessionId: args.sessionId,
2100
- variantId: args.variantId,
2101
- });
2102
- const diff = record?.diff ?? saved?.diff;
2103
- if (!record && !saved) {
2104
- throw new errors_1.AgentVariantsError('WORK_ITEM_NOT_FOUND', `Unknown variantId ${args.variantId} for session ${args.sessionId}`);
2105
- }
2106
- if (diff === undefined) {
2107
- throw new errors_1.AgentVariantsError('INVALID_STAGE_ACTION', `Variant ${args.variantId} has no captured diff yet — wait for report_variant_complete(succeeded) first`);
2108
- }
2109
- changedFilesCount = (0, variantWorkspaceFiles_1.countDiffFiles)(diff);
2110
- if (!this.worktrees.applyDiffToProject) {
2111
- throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', 'WorktreeManager does not support applying diffs to the project tree');
2112
- }
2113
- try {
2114
- await this.worktrees.applyDiffToProject(diff, env.projectPath);
2115
- }
2116
- catch (err) {
2117
- const message = (0, errorMessage_1.errorMessage)(err);
2118
- throw new errors_1.AgentVariantsError('RUNTIME_VALIDATION_FAILED', `Failed to apply variant ${args.variantId} to ${env.projectPath}: ${message}`);
2119
- }
2120
- payload = {
2121
- kind: 'diff-applied',
2122
- diff,
2123
- target: input.target,
2124
- changedFilesCount,
2125
- note: "Variant diff applied to the user's working tree (uncommitted).",
2126
- };
2127
- envelopeDestination = env.projectPath;
2128
- }
2129
- const envelope = {
2130
- sourceSessionId: args.sessionId,
2131
- variantId: args.variantId,
2132
- variantLabel: input.briefLabel,
2133
- destinationPath: envelopeDestination,
2134
- changedFilesCount,
2135
- payload,
2136
- };
2137
- this.store.recordVariantPick({
2138
- sessionId: args.sessionId,
2139
- envelope,
2140
- });
2141
- const historyProjectPath = projectContext.kind === 'fresh'
2142
- ? projectContext.workspacePath
2143
- : envelopeDestination;
2144
- try {
2145
- await this.persistVariantHistoryAtCommit({
2146
- sessionId: args.sessionId,
2147
- chosenVariantId: args.variantId,
2148
- projectPath: historyProjectPath,
2149
- projectKind: projectContext.kind,
2150
- destinationPath: envelopeDestination,
2151
- runnablePaths,
2152
- });
2153
- }
2154
- catch (err) {
2155
- log.warn(`persistVariantHistoryAtCommit failed for session ${args.sessionId}`, err);
2156
- }
2157
- resources.committedVariantIds.add(args.variantId);
2158
- if (this.activeSessionId === args.sessionId &&
2159
- payload.kind !== 'project-created') {
2160
- this.activeSessionId = null;
2161
- }
2162
- const dwellMsFromTerminal = resources.terminalAt
2163
- ? Date.now() - resources.terminalAt
2164
- : null;
2165
- this.telemetry.track('agent_variants.committed', {
2166
- source: 'mcp',
2167
- sessionId: args.sessionId,
2168
- workItemId: args.variantId,
2169
- payloadKind: payload.kind,
2170
- changedFilesCount,
2171
- dwellMsFromTerminal,
2172
- isFresh: projectContext.kind === 'fresh',
2173
- });
2174
- this.emitChange();
2175
- log.info(`Variant ${args.variantId} (${input.briefLabel}) committed by user`);
2176
- if (!args.skipTeardown) {
2177
- void this.teardownSession(args.sessionId, 'committed').catch((err) => {
2178
- log.warn(`teardownSession after commit failed for ${args.sessionId}`, err);
2179
- });
2180
- }
2181
- return {
2182
- enqueued: true,
2183
- duplicate: false,
2184
- changedFilesCount,
2185
- payloadKind: payload.kind,
2186
- destinationPath: envelopeDestination,
2187
- ...(committedPreviewPort
2188
- ? {
2189
- previewUrl: `http://${FRESH_DEV_SERVER_HOST}:${committedPreviewPort}`,
2190
- }
2191
- : {}),
2192
- };
2193
- }
2194
- async cleanupCommittedSession(sessionId) {
2195
- await this.teardownSession(sessionId, 'committed');
2196
- }
2197
- assertDestinationAvailable(destinationPath, additionalAllowedEntries = new Set()) {
2198
- if (!fs_1.default.existsSync(destinationPath))
2199
- return;
2200
- const entries = fs_1.default.readdirSync(destinationPath);
2201
- const userVisibleEntries = entries.filter((entry) => entry !== '.rivet' &&
2202
- entry !== '.gitignore' &&
2203
- !additionalAllowedEntries.has(entry));
2204
- if (userVisibleEntries.length === 0)
2205
- return;
2206
- throw new errors_1.AgentVariantsError('DESTINATION_NOT_EMPTY', `Destination ${destinationPath} is not empty (${userVisibleEntries.length} entries) — refuse to materialize.`);
1796
+ async cleanupSession(sessionId) {
1797
+ await this.teardownSession(sessionId, 'shutdown');
2207
1798
  }
2208
1799
  getVariantDiff(sessionId, variantId) {
2209
1800
  return this.workspaceInventory.getWorktree(sessionId, variantId)?.diff;
@@ -3047,52 +2638,6 @@ class AgentVariantsOrchestrator {
3047
2638
  }
3048
2639
  }
3049
2640
  }
3050
- async persistCompletedFreshVariantsForCommit(sessionId) {
3051
- const projectContext = this.store.getProjectContext(sessionId);
3052
- if (projectContext.kind !== 'fresh')
3053
- return;
3054
- const variants = this.store
3055
- .getVariants(sessionId)
3056
- .filter((variant) => variant.status === 'succeeded');
3057
- for (const variant of variants) {
3058
- try {
3059
- await this.persistCompletedArtifactVariant({
3060
- sessionId,
3061
- workItemId: variant.workItemId,
3062
- });
3063
- }
3064
- catch (err) {
3065
- log.warn(`persistCompletedFreshVariantsForCommit failed for ${sessionId}/${variant.workItemId}`, err);
3066
- }
3067
- }
3068
- }
3069
- async persistVariantHistoryAtCommit(args) {
3070
- const variants = this.store.getVariants(args.sessionId);
3071
- for (const variant of variants) {
3072
- if (variant.status !== 'succeeded')
3073
- continue;
3074
- const workItemId = variant.workItemId;
3075
- const isChosen = workItemId === args.chosenVariantId;
3076
- const status = isChosen
3077
- ? 'committed'
3078
- : 'rejected';
3079
- const saved = isChosen
3080
- ? await this.getSavedVariant({
3081
- projectPath: args.projectPath,
3082
- sessionId: args.sessionId,
3083
- variantId: workItemId,
3084
- })
3085
- : null;
3086
- await this.variantHistory.markStatus({
3087
- projectPath: args.projectPath,
3088
- sessionId: saved?.manifest.sessionId ?? args.sessionId,
3089
- variantId: saved?.manifest.variantId ?? workItemId,
3090
- status,
3091
- destinationPath: isChosen ? args.destinationPath : undefined,
3092
- runnablePath: args.runnablePaths?.get(workItemId),
3093
- });
3094
- }
3095
- }
3096
2641
  async markPersistedVariantsCancelled(sessionId) {
3097
2642
  if (!this.store.hasSession(sessionId))
3098
2643
  return;
@@ -3175,180 +2720,6 @@ class AgentVariantsOrchestrator {
3175
2720
  return undefined;
3176
2721
  }
3177
2722
  }
3178
- preserveUnchosenVariants(args) {
3179
- const resources = this.resources.get(args.sessionId);
3180
- const runnablePaths = new Map();
3181
- if (!resources)
3182
- return runnablePaths;
3183
- const destinationParent = path_1.default.dirname(args.destinationPath);
3184
- const projectSlug = path_1.default.basename(args.destinationPath);
3185
- const historyDir = (0, createProjectArtifacts_1.createVariantsHistoryPath)(destinationParent, projectSlug);
3186
- const briefs = this.store.getBriefs(args.sessionId);
3187
- const variants = this.store.getVariants(args.sessionId);
3188
- const briefIndexById = new Map(briefs.map((b, i) => [b.briefId, i]));
3189
- const manifestEntries = [];
3190
- let chosenSlug = '';
3191
- for (const variant of variants) {
3192
- const input = this.store.getVariantWorkItemInput(args.sessionId, variant.workItemId);
3193
- const label = input?.briefLabel ?? variant.label ?? 'variant';
3194
- const slug = (0, createProjectArtifacts_1.createProjectVariantSlug)(label);
3195
- const briefIdx = briefIndexById.get(variant.briefId) ?? 0;
3196
- const numericPrefix = String(briefIdx + 1).padStart(2, '0');
3197
- const folderName = `${numericPrefix}-${slug}`;
3198
- if (variant.workItemId === args.chosenVariantId) {
3199
- chosenSlug = slug;
3200
- runnablePaths.set(variant.workItemId, projectSlug);
3201
- manifestEntries.push({
3202
- variantId: variant.workItemId,
3203
- label,
3204
- slug,
3205
- folder: null,
3206
- isChosen: true,
3207
- chosenPath: `../${projectSlug}`,
3208
- });
3209
- continue;
3210
- }
3211
- const record = this.workspaceInventory.getWorktree(args.sessionId, variant.workItemId);
3212
- if (!record) {
3213
- manifestEntries.push({
3214
- variantId: variant.workItemId,
3215
- label,
3216
- slug,
3217
- folder: null,
3218
- isChosen: false,
3219
- });
3220
- continue;
3221
- }
3222
- if (!fs_1.default.existsSync(record.worktreePath)) {
3223
- manifestEntries.push({
3224
- variantId: variant.workItemId,
3225
- label,
3226
- slug,
3227
- folder: null,
3228
- isChosen: false,
3229
- });
3230
- continue;
3231
- }
3232
- try {
3233
- const newPath = this.worktrees.moveWorktreeToHistory
3234
- ? this.worktrees.moveWorktreeToHistory(record.worktreePath, historyDir, folderName)
3235
- : (() => {
3236
- fs_1.default.mkdirSync(historyDir, { recursive: true });
3237
- const dest = path_1.default.join(historyDir, folderName);
3238
- fs_1.default.renameSync(record.worktreePath, dest);
3239
- return dest;
3240
- })();
3241
- record.worktreePath = newPath;
3242
- runnablePaths.set(variant.workItemId, `${path_1.default.basename(historyDir)}/${folderName}`);
3243
- manifestEntries.push({
3244
- variantId: variant.workItemId,
3245
- label,
3246
- slug,
3247
- folder: folderName,
3248
- isChosen: false,
3249
- });
3250
- }
3251
- catch (err) {
3252
- log.warn(`moveWorktreeToHistory failed for variant ${variant.workItemId}`, err);
3253
- manifestEntries.push({
3254
- variantId: variant.workItemId,
3255
- label,
3256
- slug,
3257
- folder: null,
3258
- isChosen: false,
3259
- });
3260
- }
3261
- }
3262
- const manifest = {
3263
- schemaVersion: createProjectArtifacts_1.CREATE_PROJECT_MANIFEST_SCHEMA_VERSION,
3264
- createdAt: new Date().toISOString(),
3265
- sessionId: args.sessionId,
3266
- chosenVariantId: args.chosenVariantId,
3267
- chosenSlug: chosenSlug || projectSlug,
3268
- variants: manifestEntries,
3269
- };
3270
- try {
3271
- (0, createProjectArtifacts_1.writeCreateProjectManifestFile)((0, createProjectArtifacts_1.createVariantsHistoryManifestPath)(destinationParent, projectSlug), manifest);
3272
- }
3273
- catch (err) {
3274
- log.warn(`Writing variants history manifest failed for ${historyDir}`, err);
3275
- }
3276
- this.workspaceInventory.preserveViteSibling(args.sessionId);
3277
- return runnablePaths;
3278
- }
3279
- async renameWorktreeIntoDestination(sourceWorktreePath, destinationPath) {
3280
- const destinationParent = path_1.default.dirname(destinationPath);
3281
- await fs_1.default.promises.mkdir(destinationParent, { recursive: true });
3282
- let preservedRivetParent;
3283
- const existingRivetPath = path_1.default.join(destinationPath, '.rivet');
3284
- if (fs_1.default.existsSync(destinationPath)) {
3285
- preservedRivetParent = await fs_1.default.promises.mkdtemp(path_1.default.join(destinationParent, '.rivet-preserve-'));
3286
- if (fs_1.default.existsSync(existingRivetPath)) {
3287
- await fs_1.default.promises.rename(existingRivetPath, path_1.default.join(preservedRivetParent, '.rivet'));
3288
- }
3289
- await fs_1.default.promises.rm(destinationPath, { recursive: true, force: true });
3290
- }
3291
- try {
3292
- await fs_1.default.promises.rename(sourceWorktreePath, destinationPath);
3293
- }
3294
- catch (err) {
3295
- if (preservedRivetParent && !fs_1.default.existsSync(destinationPath)) {
3296
- await fs_1.default.promises.mkdir(destinationPath, { recursive: true });
3297
- const preservedRivetPath = path_1.default.join(preservedRivetParent, '.rivet');
3298
- if (fs_1.default.existsSync(preservedRivetPath)) {
3299
- await fs_1.default.promises.rename(preservedRivetPath, existingRivetPath);
3300
- }
3301
- }
3302
- throw err;
3303
- }
3304
- if (preservedRivetParent) {
3305
- const preservedRivetPath = path_1.default.join(preservedRivetParent, '.rivet');
3306
- if (fs_1.default.existsSync(preservedRivetPath)) {
3307
- if (fs_1.default.existsSync(existingRivetPath)) {
3308
- await fs_1.default.promises.cp(preservedRivetPath, existingRivetPath, {
3309
- recursive: true,
3310
- force: true,
3311
- });
3312
- await fs_1.default.promises.rm(preservedRivetPath, {
3313
- recursive: true,
3314
- force: true,
3315
- });
3316
- }
3317
- else {
3318
- await fs_1.default.promises.rename(preservedRivetPath, existingRivetPath);
3319
- }
3320
- }
3321
- await fs_1.default.promises.rm(preservedRivetParent, {
3322
- recursive: true,
3323
- force: true,
3324
- });
3325
- }
3326
- const dotGit = path_1.default.join(destinationPath, '.git');
3327
- try {
3328
- fs_1.default.rmSync(dotGit, { recursive: true, force: true });
3329
- }
3330
- catch { }
3331
- try {
3332
- const git = (0, simple_git_1.simpleGit)(destinationPath);
3333
- await git.raw(['init']);
3334
- await git.raw(['add', '-A']);
3335
- await git
3336
- .raw([
3337
- '-c',
3338
- 'user.name=Rivet',
3339
- '-c',
3340
- 'user.email=hello@tryrivet.design',
3341
- 'commit',
3342
- '--no-gpg-sign',
3343
- '-m',
3344
- 'Initial commit (created with Rivet)',
3345
- ])
3346
- .catch(() => { });
3347
- }
3348
- catch (err) {
3349
- log.warn(`Initial git history setup at ${destinationPath} failed`, err);
3350
- }
3351
- }
3352
2723
  async teardownSession(sessionId, reason) {
3353
2724
  const resources = this.resources.get(sessionId);
3354
2725
  if (!resources)
@@ -3363,17 +2734,8 @@ class AgentVariantsOrchestrator {
3363
2734
  this.settleHistoryPersists(),
3364
2735
  new Promise((resolve) => setTimeout(resolve, SETTLE_PERSISTS_TEARDOWN_TIMEOUT_MS)),
3365
2736
  ]);
3366
- await this.previewRuntime.closeSession(sessionId, reason);
3367
- let isFresh = false;
3368
- try {
3369
- isFresh = this.store.getProjectContext(sessionId).kind === 'fresh';
3370
- }
3371
- catch { }
3372
- await this.workspaceInventory.disposeAssignments({
3373
- sessionId,
3374
- isFresh,
3375
- isCommitted: reason === 'committed',
3376
- });
2737
+ await this.previewRuntime.closeSession(sessionId);
2738
+ await this.workspaceInventory.disposeAssignments({ sessionId });
3377
2739
  this.resources.delete(sessionId);
3378
2740
  }
3379
2741
  ensureResources(sessionId) {
@@ -3381,7 +2743,6 @@ class AgentVariantsOrchestrator {
3381
2743
  if (!r) {
3382
2744
  r = {
3383
2745
  sessionId,
3384
- committedVariantIds: new Set(),
3385
2746
  startedAt: Date.now(),
3386
2747
  nextRoundIndex: 0,
3387
2748
  rounds: new Map(),