rivet-design 0.8.6 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/bin/rivet.js +11 -0
  2. package/dist/config/evaluateFlags.d.ts +6 -2
  3. package/dist/config/evaluateFlags.d.ts.map +1 -1
  4. package/dist/config/evaluateFlags.js +4 -4
  5. package/dist/config/evaluateFlags.js.map +1 -1
  6. package/dist/config/featureFlagUserKey.d.ts +11 -0
  7. package/dist/config/featureFlagUserKey.d.ts.map +1 -0
  8. package/dist/config/featureFlagUserKey.js +21 -0
  9. package/dist/config/featureFlagUserKey.js.map +1 -0
  10. package/dist/config/flags.d.ts +6 -0
  11. package/dist/config/flags.d.ts.map +1 -1
  12. package/dist/config/flags.js +2 -0
  13. package/dist/config/flags.js.map +1 -1
  14. package/dist/config/proxy.d.ts +1 -0
  15. package/dist/config/proxy.d.ts.map +1 -1
  16. package/dist/config/proxy.js +9 -1
  17. package/dist/config/proxy.js.map +1 -1
  18. package/dist/index.js +198 -12
  19. package/dist/index.js.map +1 -1
  20. package/dist/mcp/agent-variants/SessionStore.d.ts +121 -0
  21. package/dist/mcp/agent-variants/SessionStore.d.ts.map +1 -0
  22. package/dist/mcp/agent-variants/SessionStore.js +480 -0
  23. package/dist/mcp/agent-variants/SessionStore.js.map +1 -0
  24. package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts +187 -0
  25. package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts.map +1 -0
  26. package/dist/mcp/agent-variants/WorktreeOrchestrator.js +482 -0
  27. package/dist/mcp/agent-variants/WorktreeOrchestrator.js.map +1 -0
  28. package/dist/mcp/agent-variants/contracts.d.ts +373 -0
  29. package/dist/mcp/agent-variants/contracts.d.ts.map +1 -0
  30. package/dist/mcp/agent-variants/contracts.js +134 -0
  31. package/dist/mcp/agent-variants/contracts.js.map +1 -0
  32. package/dist/mcp/agent-variants/errors.d.ts +8 -0
  33. package/dist/mcp/agent-variants/errors.d.ts.map +1 -0
  34. package/dist/mcp/agent-variants/errors.js +30 -0
  35. package/dist/mcp/agent-variants/errors.js.map +1 -0
  36. package/dist/mcp/agent-variants/index.d.ts +11 -0
  37. package/dist/mcp/agent-variants/index.d.ts.map +1 -0
  38. package/dist/mcp/agent-variants/index.js +15 -0
  39. package/dist/mcp/agent-variants/index.js.map +1 -0
  40. package/dist/mcp/agent-variants/pendingChangesAdapter.d.ts +38 -0
  41. package/dist/mcp/agent-variants/pendingChangesAdapter.d.ts.map +1 -0
  42. package/dist/mcp/agent-variants/pendingChangesAdapter.js +79 -0
  43. package/dist/mcp/agent-variants/pendingChangesAdapter.js.map +1 -0
  44. package/dist/mcp/agent-variants/tools.d.ts +8 -0
  45. package/dist/mcp/agent-variants/tools.d.ts.map +1 -0
  46. package/dist/mcp/agent-variants/tools.js +221 -0
  47. package/dist/mcp/agent-variants/tools.js.map +1 -0
  48. package/dist/mcp/server.d.ts.map +1 -1
  49. package/dist/mcp/server.js +51 -34
  50. package/dist/mcp/server.js.map +1 -1
  51. package/dist/proxy-middleware/proxy-config.d.ts +4 -1
  52. package/dist/proxy-middleware/proxy-config.d.ts.map +1 -1
  53. package/dist/proxy-middleware/proxy-config.js +34 -5
  54. package/dist/proxy-middleware/proxy-config.js.map +1 -1
  55. package/dist/routes/agentVariants.d.ts +16 -0
  56. package/dist/routes/agentVariants.d.ts.map +1 -0
  57. package/dist/routes/agentVariants.js +234 -0
  58. package/dist/routes/agentVariants.js.map +1 -0
  59. package/dist/server.d.ts +3 -0
  60. package/dist/server.d.ts.map +1 -1
  61. package/dist/server.js +24 -8
  62. package/dist/server.js.map +1 -1
  63. package/dist/services/ConfigManager.d.ts +8 -0
  64. package/dist/services/ConfigManager.d.ts.map +1 -1
  65. package/dist/services/ConfigManager.js +13 -0
  66. package/dist/services/ConfigManager.js.map +1 -1
  67. package/dist/services/FeatureFlagService.d.ts +9 -5
  68. package/dist/services/FeatureFlagService.d.ts.map +1 -1
  69. package/dist/services/FeatureFlagService.js +18 -9
  70. package/dist/services/FeatureFlagService.js.map +1 -1
  71. package/dist/services/SessionBridgeService.d.ts +22 -0
  72. package/dist/services/SessionBridgeService.d.ts.map +1 -1
  73. package/dist/services/SessionBridgeService.js +58 -1
  74. package/dist/services/SessionBridgeService.js.map +1 -1
  75. package/dist/services/TelemetryService.d.ts +5 -1
  76. package/dist/services/TelemetryService.d.ts.map +1 -1
  77. package/dist/services/TelemetryService.js +19 -7
  78. package/dist/services/TelemetryService.js.map +1 -1
  79. package/dist/services/WorktreeManager.d.ts +42 -3
  80. package/dist/services/WorktreeManager.d.ts.map +1 -1
  81. package/dist/services/WorktreeManager.js +149 -6
  82. package/dist/services/WorktreeManager.js.map +1 -1
  83. package/dist/types/change-request-types.d.ts +36 -1
  84. package/dist/types/change-request-types.d.ts.map +1 -1
  85. package/dist/utils/devServerCommand.d.ts +19 -0
  86. package/dist/utils/devServerCommand.d.ts.map +1 -0
  87. package/dist/utils/devServerCommand.js +38 -0
  88. package/dist/utils/devServerCommand.js.map +1 -0
  89. package/dist/utils/skills/claude-skill.d.ts +2 -2
  90. package/dist/utils/skills/claude-skill.d.ts.map +1 -1
  91. package/dist/utils/skills/claude-skill.js +87 -4
  92. package/dist/utils/skills/claude-skill.js.map +1 -1
  93. package/dist/utils/skills/cursor-rules.d.ts +2 -2
  94. package/dist/utils/skills/cursor-rules.d.ts.map +1 -1
  95. package/dist/utils/skills/cursor-rules.js +87 -4
  96. package/dist/utils/skills/cursor-rules.js.map +1 -1
  97. package/dist/utils/variantPreviewPort.d.ts +18 -0
  98. package/dist/utils/variantPreviewPort.d.ts.map +1 -0
  99. package/dist/utils/variantPreviewPort.js +28 -0
  100. package/dist/utils/variantPreviewPort.js.map +1 -0
  101. package/package.json +1 -1
  102. package/src/ui/dist/assets/main-Bv0LuxKz.js +382 -0
  103. package/src/ui/dist/assets/main-BzmseUDd.css +1 -0
  104. package/src/ui/dist/index.html +2 -2
  105. package/src/ui/dist/assets/main-DpcUh_b_.js +0 -382
  106. package/src/ui/dist/assets/main-wC0IkT-I.css +0 -1
@@ -0,0 +1,38 @@
1
+ import type { ChangeRequest } from '../../types/change-request-types';
2
+ import type { VariantPickEnvelope, VariantPickPayload } from './contracts';
3
+ /**
4
+ * Bridge contract — matches `SessionBridgeService.queueChangeRequest` so this
5
+ * adapter can pass a `SessionBridgeService` instance directly. The fake bridge
6
+ * in unit tests captures intents without touching disk.
7
+ */
8
+ export interface BridgeQueue {
9
+ queueChangeRequest(intent: ChangeRequest): void;
10
+ }
11
+ /** @deprecated — alias kept for tests that haven't migrated yet. */
12
+ export type BridgeChangeIntent = ChangeRequest;
13
+ export interface AdapterTelemetry {
14
+ enqueued(envelope: VariantPickEnvelope): void;
15
+ duplicateSuppressed(envelope: VariantPickEnvelope): void;
16
+ }
17
+ export declare class PendingChangesAdapter {
18
+ private readonly enqueued;
19
+ private readonly bridge;
20
+ private readonly telemetry;
21
+ constructor(bridge: BridgeQueue, telemetry?: AdapterTelemetry);
22
+ /**
23
+ * Enqueue a chosen variant into the existing pending-changes channel.
24
+ * Idempotent on `{sourceSessionId, variantId}`: a repeated submit with the
25
+ * same key returns `enqueued: false, duplicate: true` and does not re-call
26
+ * the bridge.
27
+ */
28
+ enqueue(envelope: VariantPickEnvelope): {
29
+ enqueued: boolean;
30
+ duplicate: boolean;
31
+ };
32
+ /**
33
+ * Test/inspect helper — count of unique variants successfully enqueued.
34
+ */
35
+ size(): number;
36
+ }
37
+ export type { VariantPickPayload };
38
+ //# sourceMappingURL=pendingChangesAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pendingChangesAdapter.d.ts","sourceRoot":"","sources":["../../../src/mcp/agent-variants/pendingChangesAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EAEd,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;CACjD;AAED,oEAAoE;AACpE,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC9C,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC1D;AAOD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;gBAEjC,MAAM,EAAE,WAAW,EAAE,SAAS,GAAE,gBAAiC;IAK7E;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,mBAAmB,GAAG;QACtC,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;KACpB;IAqBD;;OAEG;IACH,IAAI,IAAI,MAAM;CAGf;AAmCD,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PendingChangesAdapter = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const NOOP_TELEMETRY = {
6
+ enqueued: () => undefined,
7
+ duplicateSuppressed: () => undefined,
8
+ };
9
+ class PendingChangesAdapter {
10
+ enqueued = new Map();
11
+ bridge;
12
+ telemetry;
13
+ constructor(bridge, telemetry = NOOP_TELEMETRY) {
14
+ this.bridge = bridge;
15
+ this.telemetry = telemetry;
16
+ }
17
+ /**
18
+ * Enqueue a chosen variant into the existing pending-changes channel.
19
+ * Idempotent on `{sourceSessionId, variantId}`: a repeated submit with the
20
+ * same key returns `enqueued: false, duplicate: true` and does not re-call
21
+ * the bridge.
22
+ */
23
+ enqueue(envelope) {
24
+ const key = idempotencyKey(envelope);
25
+ if (this.enqueued.has(key)) {
26
+ this.telemetry.duplicateSuppressed(envelope);
27
+ return { enqueued: false, duplicate: true };
28
+ }
29
+ const variantItem = toVariantChangeItem(envelope);
30
+ const request = {
31
+ changes: [variantItem],
32
+ sourceFiles: [],
33
+ traceId: (0, crypto_1.randomUUID)(),
34
+ agentRunId: (0, crypto_1.randomUUID)(),
35
+ };
36
+ this.bridge.queueChangeRequest(request);
37
+ this.enqueued.set(key, envelope);
38
+ this.telemetry.enqueued(envelope);
39
+ return { enqueued: true, duplicate: false };
40
+ }
41
+ /**
42
+ * Test/inspect helper — count of unique variants successfully enqueued.
43
+ */
44
+ size() {
45
+ return this.enqueued.size;
46
+ }
47
+ }
48
+ exports.PendingChangesAdapter = PendingChangesAdapter;
49
+ function idempotencyKey(envelope) {
50
+ return `${envelope.sourceSessionId}|${envelope.variantId}`;
51
+ }
52
+ function toVariantChangeItem(envelope) {
53
+ const base = {
54
+ kind: 'variant',
55
+ sourceSessionId: envelope.sourceSessionId,
56
+ variantId: envelope.variantId,
57
+ variantLabel: envelope.variantLabel,
58
+ destinationPath: envelope.destinationPath,
59
+ changedFilesCount: envelope.changedFilesCount,
60
+ };
61
+ if (envelope.payload.kind === 'diff') {
62
+ return {
63
+ ...base,
64
+ payload: {
65
+ kind: 'diff',
66
+ diff: envelope.payload.diff,
67
+ target: envelope.payload.target,
68
+ },
69
+ };
70
+ }
71
+ return {
72
+ ...base,
73
+ payload: {
74
+ kind: 'new-project',
75
+ sourceWorktreePath: envelope.payload.sourceWorktreePath,
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=pendingChangesAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pendingChangesAdapter.js","sourceRoot":"","sources":["../../../src/mcp/agent-variants/pendingChangesAdapter.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AAwBpC,MAAM,cAAc,GAAqB;IACvC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS;IACzB,mBAAmB,EAAE,GAAG,EAAE,CAAC,SAAS;CACrC,CAAC;AAEF,MAAa,qBAAqB;IACf,QAAQ,GAAG,IAAI,GAAG,EAA+B,CAAC;IAClD,MAAM,CAAc;IACpB,SAAS,CAAmB;IAE7C,YAAY,MAAmB,EAAE,YAA8B,cAAc;QAC3E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAA6B;QAInC,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC;QAED,MAAM,WAAW,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,OAAO,GAAkB;YAC7B,OAAO,EAAE,CAAC,WAAW,CAAC;YACtB,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,IAAA,mBAAU,GAAE;YACrB,UAAU,EAAE,IAAA,mBAAU,GAAE;SACzB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF;AA9CD,sDA8CC;AAED,SAAS,cAAc,CAAC,QAA6B;IACnD,OAAO,GAAG,QAAQ,CAAC,eAAe,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;AAC7D,CAAC;AAED,SAAS,mBAAmB,CAAC,QAA6B;IACxD,MAAM,IAAI,GAAG;QACX,IAAI,EAAE,SAAkB;QACxB,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;KAC9C,CAAC;IACF,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACrC,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI;gBAC3B,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;aAChC;SACF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,GAAG,IAAI;QACP,OAAO,EAAE;YACP,IAAI,EAAE,aAAa;YACnB,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,kBAAkB;SACxD;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { AgentVariantsOrchestrator } from './WorktreeOrchestrator';
3
+ export interface ToolDeps {
4
+ orchestrator: AgentVariantsOrchestrator;
5
+ leaseOwner: () => string;
6
+ }
7
+ export declare function registerAgentVariantsTools(mcp: McpServer, deps: ToolDeps): void;
8
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/agent-variants/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0BzE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,yBAAyB,CAAC;IACxC,UAAU,EAAE,MAAM,MAAM,CAAC;CAC1B;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,QAAQ,GACb,IAAI,CAoON"}
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerAgentVariantsTools = registerAgentVariantsTools;
4
+ const contracts_1 = require("./contracts");
5
+ const errors_1 = require("./errors");
6
+ function registerAgentVariantsTools(mcp, deps) {
7
+ mcp.tool('propose_variants', 'START HERE for any "create variants", "show me N options for X", "explore approaches to X", "build me Y from scratch", or "create a new Z app" request. DO NOT generate variants natively (Task tool, parallel tool calls, or your own creative process). Returns { sessionId, briefWorkItem }. Protocol: 1) call this tool, 2) run the brief work item with your own LLM to generate N briefs, 3) call report_variant_briefs, 3.5) AUTO-OPEN the Rivet editor — call detect_project + open_visual_editor if not already open; the user needs the iframe up to see variants render, do NOT wait for them to ask, 4) SHOW the briefs to the user IN CHAT as a numbered list and ask "look good or want adjustments?" — DO NOT ask which one to pick, 5) wait for user feedback (affirmative → proceed; tweak → bodyOverride or re-brief), 6) call approve_variant_briefs({sessionId, briefIds: [all]}), 7) call continue_variants(action="request_work") to lease all items in parallel (scaffold_base first for fresh-project), 8) run all code-gens IN PARALLEL in their own worktreePath, calling report_variant_complete per item, 9) DO NOT print diffs — instead tell the user the variants are ready and to use the chip at the bottom-center of the Rivet iframe to cycle (prev/next pills) and commit (check button), 10) watch_for_changes (or poll get_pending_changes) — when the user clicks the check, you get a VariantChangeItem on the queue, 11) apply via git apply (diff payload) or copy the worktree (new-project payload). Pass projectContext.kind=fresh with workspacePath for brand-new projects.', contracts_1.proposeVariantsInput, async (args) => {
8
+ try {
9
+ const result = deps.orchestrator.propose({
10
+ sessionId: args.sessionId,
11
+ prompt: args.prompt,
12
+ count: args.count,
13
+ target: args.target,
14
+ projectContext: args.projectContext,
15
+ });
16
+ const out = {
17
+ sessionId: result.sessionId,
18
+ stage: 'awaiting_briefs',
19
+ briefWorkItem: {
20
+ id: result.briefWorkItem.id,
21
+ kind: 'brief',
22
+ attempt: result.briefWorkItem.attempt,
23
+ input: result.briefWorkItem.input,
24
+ output_schema: { briefs: 'Array<{briefId, label, body}>' },
25
+ },
26
+ nextAction: 'report_variant_briefs',
27
+ };
28
+ return jsonResponse(out);
29
+ }
30
+ catch (err) {
31
+ return errorResponse(err);
32
+ }
33
+ });
34
+ mcp.tool('report_variant_briefs', 'Agent reports N drafted briefs back to Rivet after running its own LLM call on the brief work item. Transitions the session to awaiting_approval; user reviews briefs in the variants tab.', contracts_1.reportVariantBriefsInput, async (args) => {
35
+ try {
36
+ const result = deps.orchestrator.reportBriefs({
37
+ sessionId: args.sessionId,
38
+ workItemId: args.workItemId,
39
+ attempt: args.attempt,
40
+ leaseId: args.leaseId,
41
+ briefs: args.briefs,
42
+ });
43
+ const out = {
44
+ stage: 'awaiting_approval',
45
+ briefs: result.briefs,
46
+ nextAction: 'continue_variants',
47
+ };
48
+ return jsonResponse(out);
49
+ }
50
+ catch (err) {
51
+ return errorResponse(err);
52
+ }
53
+ });
54
+ mcp.tool('approve_variant_briefs', 'Call AFTER showing the briefs to the user in chat and getting an affirmative ("looks good", "yep", "go") OR refined selections from them. Provide briefIds for ALL the briefs the user wants generated (typically all of them). Each approved brief gets a parallel code-gen work item — Rivet provisions one isolated worktree per item. Advance via continue_variants(action="request_work") to lease and run them in parallel. For tweak-with-feedback, use the selections form with bodyOverride per brief.', contracts_1.approveVariantBriefsInput, async (args) => {
55
+ try {
56
+ const selections = args.selections ??
57
+ (args.briefIds ?? []).map((briefId) => ({ briefId }));
58
+ if (selections.length === 0) {
59
+ throw new Error('approve_variant_briefs requires either briefIds or selections');
60
+ }
61
+ const result = await deps.orchestrator.approve({
62
+ sessionId: args.sessionId,
63
+ selections,
64
+ });
65
+ const out = {
66
+ stage: 'work_items_ready',
67
+ approvedCount: result.approvedCount,
68
+ codeGenWorkItemIds: result.codeGenWorkItemIds,
69
+ scaffoldBaseWorkItemId: result.scaffoldBaseWorkItemId ?? null,
70
+ nextAction: 'continue_variants',
71
+ };
72
+ return jsonResponse(out);
73
+ }
74
+ catch (err) {
75
+ return errorResponse(err);
76
+ }
77
+ });
78
+ mcp.tool('commit_variant', "Call AFTER all variants have been generated AND you've shown each variant's diff/changes to the user in chat AND the user has picked one. Pass the variantId (the workItemId of the chosen variant). Rivet looks up that variant's captured diff and enqueues it onto the existing pending-changes channel — call get_pending_changes next to retrieve and apply. Idempotent on (sessionId, variantId).", contracts_1.commitVariantInput, async (args) => {
79
+ try {
80
+ const result = await deps.orchestrator.commitVariant({
81
+ sessionId: args.sessionId,
82
+ variantId: args.variantId,
83
+ });
84
+ const out = {
85
+ stage: deps.orchestrator.getStage(args.sessionId),
86
+ enqueued: result.enqueued,
87
+ duplicate: result.duplicate,
88
+ changedFilesCount: result.changedFilesCount,
89
+ };
90
+ return jsonResponse(out);
91
+ }
92
+ catch (err) {
93
+ return errorResponse(err);
94
+ }
95
+ });
96
+ mcp.tool('continue_variants', 'Long-poll/state-pump the variants flow. action=check returns immediately; action=wait blocks up to ~5min for a state change; action=request_work asks for a lease on ready work items.', contracts_1.continueVariantsInput, async (args) => {
97
+ try {
98
+ const stage = deps.orchestrator.getStage(args.sessionId);
99
+ if (stage === 'awaiting_briefs') {
100
+ // continue_variants while still awaiting briefs means the agent
101
+ // hasn't run the brief work item yet — that's a programming error.
102
+ throw new errors_1.AgentVariantsError('INVALID_STAGE_ACTION', 'Run the brief work item and call report_variant_briefs before continue_variants');
103
+ }
104
+ if (stage === 'awaiting_approval') {
105
+ return jsonResponse({
106
+ stage: 'awaiting_approval',
107
+ briefs: deps.orchestrator.getBriefs(args.sessionId),
108
+ });
109
+ }
110
+ if (stage === 'work_items_ready' &&
111
+ args.action === 'request_work') {
112
+ const lease = deps.orchestrator.requestWork({
113
+ sessionId: args.sessionId,
114
+ leaseOwner: deps.leaseOwner(),
115
+ requestedLeaseCount: args.requestedLeaseCount,
116
+ });
117
+ return jsonResponse({
118
+ stage: 'work_items_ready',
119
+ leaseId: lease.leaseId,
120
+ leaseTtlMs: lease.leaseTtlMs,
121
+ leasedWorkItems: lease.leasedWorkItems,
122
+ });
123
+ }
124
+ if (stage === 'work_items_ready' || stage === 'waiting_for_results') {
125
+ return jsonResponse({
126
+ stage: 'waiting_for_results',
127
+ progress: deps.orchestrator.getProgress(args.sessionId),
128
+ });
129
+ }
130
+ // Terminal stages
131
+ return jsonResponse({
132
+ stage,
133
+ summary: deps.orchestrator.getSummary(args.sessionId),
134
+ });
135
+ }
136
+ catch (err) {
137
+ return errorResponse(err);
138
+ }
139
+ });
140
+ mcp.tool('report_variant_complete', "Agent reports per-variant code-gen status: running (heartbeat), succeeded, failed, or cancelled. Requires a valid leaseId and matching attempt obtained from continue_variants(action='request_work').", contracts_1.reportVariantCompleteInput, async (args) => {
141
+ try {
142
+ const result = await deps.orchestrator.reportComplete({
143
+ sessionId: args.sessionId,
144
+ workItemId: args.workItemId,
145
+ leaseId: args.leaseId,
146
+ attempt: args.attempt,
147
+ status: args.status,
148
+ output: args.output,
149
+ error: args.error,
150
+ });
151
+ let out;
152
+ if (result.stage === 'ready' ||
153
+ result.stage === 'degraded' ||
154
+ result.stage === 'failed' ||
155
+ result.stage === 'cancelled') {
156
+ out = {
157
+ stage: result.stage,
158
+ summary: result.summary ?? deps.orchestrator.getSummary(args.sessionId),
159
+ };
160
+ }
161
+ else {
162
+ out = {
163
+ stage: 'waiting_for_results',
164
+ progress: result.progress,
165
+ };
166
+ }
167
+ return jsonResponse(out);
168
+ }
169
+ catch (err) {
170
+ return errorResponse(err);
171
+ }
172
+ });
173
+ mcp.tool('cancel_variants', 'Cancel an in-flight variants session. Stops accepting new execution leases, marks running items cancelled, and triggers cleanup.', contracts_1.cancelVariantsInput, async (args) => {
174
+ try {
175
+ const result = await deps.orchestrator.cancel({
176
+ sessionId: args.sessionId,
177
+ reason: args.reason,
178
+ });
179
+ const out = {
180
+ stage: 'cancelled',
181
+ cleanupStatus: result.cleanupStatus,
182
+ };
183
+ return jsonResponse(out);
184
+ }
185
+ catch (err) {
186
+ return errorResponse(err);
187
+ }
188
+ });
189
+ }
190
+ // --- Helpers --------------------------------------------------------------
191
+ // Return type is left implicit so the MCP SDK's overload selection picks the
192
+ // raw-shape variant; tagging an explicit interface here breaks the index
193
+ // signature the SDK expects.
194
+ function jsonResponse(payload) {
195
+ return {
196
+ content: [
197
+ {
198
+ type: 'text',
199
+ text: JSON.stringify(payload),
200
+ },
201
+ ],
202
+ };
203
+ }
204
+ function errorResponse(err) {
205
+ const code = err instanceof errors_1.AgentVariantsError ? err.code : 'SCHEMA_VALIDATION_FAILED';
206
+ const message = err instanceof Error ? err.message : 'Unknown error in agent-variants tool';
207
+ return {
208
+ content: [
209
+ {
210
+ type: 'text',
211
+ text: JSON.stringify({
212
+ stage: 'failed',
213
+ errorCode: code,
214
+ message,
215
+ }),
216
+ },
217
+ ],
218
+ isError: true,
219
+ };
220
+ }
221
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/mcp/agent-variants/tools.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAyfA,eAAO,MAAM,cAAc,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,IAAI,CAm8BrE,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAgeA,eAAO,MAAM,cAAc,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,IAAI,CAo/BrE,CAAC"}
@@ -16,41 +16,16 @@ const index_1 = require("../index");
16
16
  const evaluateFlags_1 = require("../config/evaluateFlags");
17
17
  const skillWriter_1 = require("../utils/skillWriter");
18
18
  const portUtils_1 = require("../utils/portUtils");
19
+ const agent_variants_1 = require("./agent-variants");
20
+ const WorktreeManager_1 = require("../services/WorktreeManager");
21
+ const ProjectDetectionService_1 = require("../services/ProjectDetectionService");
19
22
  const child_process_1 = require("child_process");
20
23
  const fs_1 = __importDefault(require("fs"));
21
24
  const path_1 = __importDefault(require("path"));
22
25
  const util_1 = require("util");
26
+ const devServerCommand_1 = require("../utils/devServerCommand");
23
27
  const log = (0, index_core_1.createLogger)('MCPServer');
24
28
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
25
- // Dev server command + default port per framework
26
- const FRAMEWORK_DEV_CONFIG = {
27
- nextjs: { devCommand: 'dev', defaultPort: 3000 },
28
- vite: { devCommand: 'dev', defaultPort: 5173 },
29
- cra: { devCommand: 'start', defaultPort: 3000 },
30
- remix: { devCommand: 'dev', defaultPort: 3000 },
31
- svelte: { devCommand: 'dev', defaultPort: 5173 },
32
- static: { devCommand: '', defaultPort: 0 },
33
- };
34
- /** Build the shell command to start the user's dev server on a specific port. */
35
- function buildDevServerCommand(framework, packageManager, devCommand, port) {
36
- // CRA uses PORT env var instead of a CLI flag
37
- if (framework === 'cra') {
38
- const args = packageManager === 'npm' ? ['run', devCommand] : [devCommand];
39
- return { cmd: packageManager, args, env: { PORT: String(port) } };
40
- }
41
- // All others (Next.js, Vite, Remix, Svelte) accept --port
42
- if (packageManager === 'npm') {
43
- return {
44
- cmd: 'npm',
45
- args: ['run', devCommand, '--', '--port', String(port)],
46
- env: {},
47
- };
48
- }
49
- if (packageManager === 'yarn') {
50
- return { cmd: 'yarn', args: [devCommand, '--port', String(port)], env: {} };
51
- }
52
- return { cmd: 'pnpm', args: [devCommand, '--port', String(port)], env: {} };
53
- }
54
29
  /** Poll until the port responds to HTTP or the timeout is reached. */
55
30
  async function waitForPort(port, host, timeoutMs = 60_000) {
56
31
  const deadline = Date.now() + timeoutMs;
@@ -314,6 +289,8 @@ function getSendButtonLabel(mcpEditor) {
314
289
  return 'Send to Cursor';
315
290
  if (mcpEditor === 'codex')
316
291
  return 'Send to Codex';
292
+ if (mcpEditor === 'claude-desktop')
293
+ return 'Send to Claude';
317
294
  return 'Send to Claude Code';
318
295
  }
319
296
  function trackChangesQueuedFromIntent(intent, bridge, telemetry, sessionId) {
@@ -393,10 +370,42 @@ const startMCPServer = async (mcpEditor) => {
393
370
  // then silence all output — users shouldn't see Rivet logs in their terminal.
394
371
  // Error capture (_onError) still fires for PostHog since it bypasses loglevel.
395
372
  (0, index_core_1.redirectLogsToStderr)();
396
- (0, index_core_1.setLogLevel)('SILENT');
373
+ // Default silent so MCP transport stays clean; opt in via env for debugging
374
+ // (e.g. `RIVET_LOG_LEVEL=debug` in the MCP client's env block).
375
+ (0, index_core_1.setLogLevel)(process.env.RIVET_LOG_LEVEL ?? 'SILENT');
397
376
  const sendButtonLabel = getSendButtonLabel(mcpEditor);
398
377
  const bridge = new SessionBridgeService_1.SessionBridgeService();
399
378
  const telemetry = new TelemetryService_1.TelemetryService();
379
+ // Agent-driven variants orchestrator. Long-lived singleton: state machine +
380
+ // worktree lifecycle for any variants session, surfaced via the 5 MCP tools
381
+ // (registered below near mcp.connect) and the /api/variants Express routes
382
+ // (mounted by startServer when this orchestrator is passed in).
383
+ const agentVariantsStore = new agent_variants_1.SessionStore();
384
+ const agentVariantsAdapter = new agent_variants_1.PendingChangesAdapter(bridge);
385
+ // WorktreeManager binds its project path lazily — the orchestrator
386
+ // outlives any MCP session, but `bridge.getProjectPath()` only becomes
387
+ // known once `open_visual_editor` runs. The getter resolves on each call.
388
+ const agentVariantsOrchestrator = new agent_variants_1.AgentVariantsOrchestrator({
389
+ store: agentVariantsStore,
390
+ worktreeManager: new WorktreeManager_1.WorktreeManager(() => bridge.getProjectPath() ?? process.cwd()),
391
+ pendingChangesAdapter: agentVariantsAdapter,
392
+ telemetry,
393
+ resolveProjectEnvironment: async (sessionId) => {
394
+ const projectPath = bridge.getProjectPath() ?? process.cwd();
395
+ const detection = new ProjectDetectionService_1.ProjectDetectionService();
396
+ const framework = detection.detectFramework(projectPath);
397
+ const packageManager = await detection.detectPackageManager(projectPath);
398
+ const devCommand = devServerCommand_1.FRAMEWORK_DEV_CONFIG[framework]?.devCommand ?? 'dev';
399
+ log.info(`Resolved env for variants session ${sessionId}: ${framework}/${packageManager}`);
400
+ return {
401
+ projectPath,
402
+ framework,
403
+ packageManager,
404
+ devCommand,
405
+ buildDevCommand: (port) => (0, devServerCommand_1.buildDevServerCommand)(framework, packageManager, devCommand, port),
406
+ };
407
+ },
408
+ });
400
409
  /** Complete the active run correlation and refresh git status in the Rivet UI. */
401
410
  const handleRefreshGit = (sessionId) => {
402
411
  const activeRunCorrelation = bridge.completeActiveRunCorrelation();
@@ -599,7 +608,7 @@ const startMCPServer = async (mcpEditor) => {
599
608
  isError: true,
600
609
  };
601
610
  }
602
- const devConfig = FRAMEWORK_DEV_CONFIG[framework] ?? {
611
+ const devConfig = devServerCommand_1.FRAMEWORK_DEV_CONFIG[framework] ?? {
603
612
  devCommand: 'dev',
604
613
  defaultPort: 3000,
605
614
  };
@@ -651,7 +660,7 @@ const startMCPServer = async (mcpEditor) => {
651
660
  let nextDevServerOwnership = 'none';
652
661
  const startupModeSelection = requestedStartupMode ? 'explicit' : 'auto';
653
662
  if (framework !== 'static') {
654
- const frameworkConfig = FRAMEWORK_DEV_CONFIG[framework] ?? {
663
+ const frameworkConfig = devServerCommand_1.FRAMEWORK_DEV_CONFIG[framework] ?? {
655
664
  devCommand: 'dev',
656
665
  defaultPort: 3000,
657
666
  };
@@ -763,7 +772,7 @@ const startMCPServer = async (mcpEditor) => {
763
772
  detection.readConfiguredPort(projectPath) ??
764
773
  frameworkConfig.defaultPort;
765
774
  nextDevServerPort = await (0, portUtils_1.findAvailablePort)(preferredPort);
766
- const { cmd, args: cmdArgs, env, } = buildDevServerCommand(framework, packageManager, frameworkConfig.devCommand, nextDevServerPort);
775
+ const { cmd, args: cmdArgs, env, } = (0, devServerCommand_1.buildDevServerCommand)(framework, packageManager, frameworkConfig.devCommand, nextDevServerPort);
767
776
  log.info(`Auto-starting dev server: ${cmd} ${cmdArgs.join(' ')} in ${projectPath}`);
768
777
  devServerProcess = (0, child_process_1.spawn)(cmd, cmdArgs, {
769
778
  cwd: projectPath,
@@ -875,6 +884,7 @@ const startMCPServer = async (mcpEditor) => {
875
884
  userPort: nextDevServerPort ?? 0,
876
885
  userHost: nextDevServerHost,
877
886
  sessionBridge: bridge,
887
+ agentVariantsOrchestrator,
878
888
  telemetry,
879
889
  mcpEditor,
880
890
  skipProcessHandlers: true,
@@ -980,7 +990,7 @@ const startMCPServer = async (mcpEditor) => {
980
990
  startupModeSelection,
981
991
  requestedStartupMode,
982
992
  isGitEnabled: isGitEnabledForSession,
983
- next_step: mcpEditor === 'cursor' || mcpEditor === 'codex'
993
+ next_step: mcpEditor === 'cursor' || mcpEditor === 'codex' || mcpEditor === 'claude-desktop'
984
994
  ? `Rivet is open. Tell the user: "Rivet is ready — make your visual changes and click '${sendButtonLabel}'." Then call watch_for_changes({ sessionId: "${sessionId}" }) to wait for their changes. After applying, STOP and ask the user if they want to keep watching or go back to normal prompting.`
985
995
  : `Rivet is open. Tell the user: "Rivet is ready — make your visual changes and click '${sendButtonLabel}'."
986
996
 
@@ -1156,6 +1166,13 @@ If the Monitor tool is not available, call watch_for_changes({ sessionId: "${ses
1156
1166
  ],
1157
1167
  };
1158
1168
  });
1169
+ // Register the agent-variants MCP tools (orchestrator was constructed at
1170
+ // the top of runMcpServer so it's shared with the Express routes).
1171
+ (0, agent_variants_1.registerAgentVariantsTools)(mcp, {
1172
+ orchestrator: agentVariantsOrchestrator,
1173
+ leaseOwner: () => 'mcp-server',
1174
+ });
1175
+ log.info('agent-variants MCP tools registered');
1159
1176
  // Connect via stdio
1160
1177
  const transport = new stdio_js_1.StdioServerTransport();
1161
1178
  await mcp.connect(transport);