rivet-design 0.22.0 → 0.23.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 (218) hide show
  1. package/bin/rivet.js +6 -0
  2. package/dist/agent-variants/SessionStore.d.ts +2 -21
  3. package/dist/agent-variants/SessionStore.d.ts.map +1 -1
  4. package/dist/agent-variants/SessionStore.js +15 -279
  5. package/dist/agent-variants/SessionStore.js.map +1 -1
  6. package/dist/agent-variants/WorktreeOrchestrator.d.ts +0 -3
  7. package/dist/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
  8. package/dist/agent-variants/WorktreeOrchestrator.js +1 -62
  9. package/dist/agent-variants/WorktreeOrchestrator.js.map +1 -1
  10. package/dist/agent-variants/WorktreeOrchestrator.testHelpers.d.ts.map +1 -1
  11. package/dist/agent-variants/WorktreeOrchestrator.testHelpers.js +0 -12
  12. package/dist/agent-variants/WorktreeOrchestrator.testHelpers.js.map +1 -1
  13. package/dist/agent-variants/contracts.d.ts +896 -2423
  14. package/dist/agent-variants/contracts.d.ts.map +1 -1
  15. package/dist/agent-variants/contracts.js +2 -84
  16. package/dist/agent-variants/contracts.js.map +1 -1
  17. package/dist/agent-variants/directionBriefs.d.ts +7 -0
  18. package/dist/agent-variants/directionBriefs.d.ts.map +1 -0
  19. package/dist/agent-variants/directionBriefs.js +51 -0
  20. package/dist/agent-variants/directionBriefs.js.map +1 -0
  21. package/dist/agent-variants/index.d.ts +1 -1
  22. package/dist/agent-variants/index.d.ts.map +1 -1
  23. package/dist/agent-variants/runPlan.d.ts +0 -1
  24. package/dist/agent-variants/runPlan.d.ts.map +1 -1
  25. package/dist/agent-variants/runPlan.js +0 -4
  26. package/dist/agent-variants/runPlan.js.map +1 -1
  27. package/dist/agent-variants/sourceContext.d.ts +0 -2
  28. package/dist/agent-variants/sourceContext.d.ts.map +1 -1
  29. package/dist/agent-variants/sourceContext.js +1 -35
  30. package/dist/agent-variants/sourceContext.js.map +1 -1
  31. package/dist/agent-variants/variantsTelemetry.d.ts +0 -3
  32. package/dist/agent-variants/variantsTelemetry.d.ts.map +1 -1
  33. package/dist/agent-variants/variantsTelemetry.js.map +1 -1
  34. package/dist/agent-variants/workItemInput.d.ts +470 -470
  35. package/dist/cli/commands/context.d.ts +3 -1
  36. package/dist/cli/commands/context.d.ts.map +1 -1
  37. package/dist/cli/commands/context.js +38 -1
  38. package/dist/cli/commands/context.js.map +1 -1
  39. package/dist/cli/commands/contextRequest.d.ts +1 -0
  40. package/dist/cli/commands/contextRequest.d.ts.map +1 -1
  41. package/dist/cli/commands/contextRequest.js +65 -5
  42. package/dist/cli/commands/contextRequest.js.map +1 -1
  43. package/dist/cli/commands/guidanceReferences.d.ts +1 -0
  44. package/dist/cli/commands/guidanceReferences.d.ts.map +1 -1
  45. package/dist/cli/commands/guidanceReferences.js +5 -4
  46. package/dist/cli/commands/guidanceReferences.js.map +1 -1
  47. package/dist/cli/commands/guidanceVerifierPackage.d.ts +9 -0
  48. package/dist/cli/commands/guidanceVerifierPackage.d.ts.map +1 -0
  49. package/dist/cli/commands/guidanceVerifierPackage.js +41 -0
  50. package/dist/cli/commands/guidanceVerifierPackage.js.map +1 -0
  51. package/dist/cli/commands/mcpServe.d.ts +1 -0
  52. package/dist/cli/commands/mcpServe.d.ts.map +1 -1
  53. package/dist/cli/commands/mcpServe.js +457 -326
  54. package/dist/cli/commands/mcpServe.js.map +1 -1
  55. package/dist/cli/commands/variants.js +2 -2
  56. package/dist/cli/commands/variants.js.map +1 -1
  57. package/dist/cli/handoffStore.d.ts +0 -1
  58. package/dist/cli/handoffStore.d.ts.map +1 -1
  59. package/dist/cli/handoffStore.js +1 -11
  60. package/dist/cli/handoffStore.js.map +1 -1
  61. package/dist/cli/router.d.ts +3 -1
  62. package/dist/cli/router.d.ts.map +1 -1
  63. package/dist/cli/router.js +4 -3
  64. package/dist/cli/router.js.map +1 -1
  65. package/dist/config/flags.d.ts +0 -3
  66. package/dist/config/flags.d.ts.map +1 -1
  67. package/dist/config/flags.js +0 -1
  68. package/dist/config/flags.js.map +1 -1
  69. package/dist/hosts/workerDefaults.d.ts +0 -1
  70. package/dist/hosts/workerDefaults.d.ts.map +1 -1
  71. package/dist/hosts/workerDefaults.js +1 -2
  72. package/dist/hosts/workerDefaults.js.map +1 -1
  73. package/dist/index-core.d.ts +1 -2
  74. package/dist/index-core.d.ts.map +1 -1
  75. package/dist/index-core.js +1 -3
  76. package/dist/index-core.js.map +1 -1
  77. package/dist/mcp/changeBatchClassification.d.ts +1 -11
  78. package/dist/mcp/changeBatchClassification.d.ts.map +1 -1
  79. package/dist/mcp/changeBatchClassification.js +0 -38
  80. package/dist/mcp/changeBatchClassification.js.map +1 -1
  81. package/dist/routes/library/guidance.d.ts.map +1 -1
  82. package/dist/routes/library/guidance.js +7 -0
  83. package/dist/routes/library/guidance.js.map +1 -1
  84. package/dist/server.d.ts +0 -1
  85. package/dist/server.d.ts.map +1 -1
  86. package/dist/server.js +1 -3
  87. package/dist/server.js.map +1 -1
  88. package/dist/services/AuthService.d.ts +4 -10
  89. package/dist/services/AuthService.d.ts.map +1 -1
  90. package/dist/services/AuthService.js +1 -116
  91. package/dist/services/AuthService.js.map +1 -1
  92. package/dist/services/GuidanceVerifierRunner.d.ts +15 -0
  93. package/dist/services/GuidanceVerifierRunner.d.ts.map +1 -0
  94. package/dist/services/GuidanceVerifierRunner.js +373 -0
  95. package/dist/services/GuidanceVerifierRunner.js.map +1 -0
  96. package/dist/services/HubDiscovery.d.ts +2 -2
  97. package/dist/services/IntegrationsClient.d.ts +3 -3
  98. package/dist/services/MCPOnboardingTelemetry.d.ts +0 -2
  99. package/dist/services/MCPOnboardingTelemetry.d.ts.map +1 -1
  100. package/dist/services/MCPOnboardingTelemetry.js +1 -78
  101. package/dist/services/MCPOnboardingTelemetry.js.map +1 -1
  102. package/dist/services/OperatingSystemServices.d.ts.map +1 -1
  103. package/dist/services/OperatingSystemServices.js +12 -5
  104. package/dist/services/OperatingSystemServices.js.map +1 -1
  105. package/dist/services/ProjectRegistry.d.ts +2 -2
  106. package/dist/services/TelemetryService.d.ts +1 -9
  107. package/dist/services/TelemetryService.d.ts.map +1 -1
  108. package/dist/services/TelemetryService.js +0 -28
  109. package/dist/services/TelemetryService.js.map +1 -1
  110. package/dist/services/VariantGenerationService.d.ts +1 -9
  111. package/dist/services/VariantGenerationService.d.ts.map +1 -1
  112. package/dist/services/VariantGenerationService.js +16 -140
  113. package/dist/services/VariantGenerationService.js.map +1 -1
  114. package/dist/services/VariantRunService.d.ts +0 -6
  115. package/dist/services/VariantRunService.d.ts.map +1 -1
  116. package/dist/services/VariantRunService.js +1 -28
  117. package/dist/services/VariantRunService.js.map +1 -1
  118. package/dist/services/VariantsRuntime.d.ts.map +1 -1
  119. package/dist/services/VariantsRuntime.js +0 -1
  120. package/dist/services/VariantsRuntime.js.map +1 -1
  121. package/dist/services/accessTokenRefresh.d.ts +0 -3
  122. package/dist/services/accessTokenRefresh.d.ts.map +1 -1
  123. package/dist/services/accessTokenRefresh.js +1 -33
  124. package/dist/services/accessTokenRefresh.js.map +1 -1
  125. package/dist/services/guidanceDelivery.d.ts +0 -5
  126. package/dist/services/guidanceDelivery.d.ts.map +1 -1
  127. package/dist/services/guidanceDelivery.js +1 -20
  128. package/dist/services/guidanceDelivery.js.map +1 -1
  129. package/dist/services/guidanceReferences.d.ts.map +1 -1
  130. package/dist/services/guidanceReferences.js +2 -76
  131. package/dist/services/guidanceReferences.js.map +1 -1
  132. package/dist/services/profiles/DesignProfiles.d.ts +31 -16
  133. package/dist/services/profiles/DesignProfiles.d.ts.map +1 -1
  134. package/dist/services/profiles/DesignProfiles.js +71 -17
  135. package/dist/services/profiles/DesignProfiles.js.map +1 -1
  136. package/dist/services/profiles/ProfilePlanning.d.ts +5 -5
  137. package/dist/services/profiles/ReferenceReader.d.ts +2 -2
  138. package/dist/services/profiles/profileContext.d.ts +1 -1
  139. package/dist/services/retainedTextFiles.d.ts +8 -0
  140. package/dist/services/retainedTextFiles.d.ts.map +1 -0
  141. package/dist/services/retainedTextFiles.js +95 -0
  142. package/dist/services/retainedTextFiles.js.map +1 -0
  143. package/dist/services/staticProjectTarget.d.ts +0 -1
  144. package/dist/services/staticProjectTarget.d.ts.map +1 -1
  145. package/dist/services/staticProjectTarget.js +1 -5
  146. package/dist/services/staticProjectTarget.js.map +1 -1
  147. package/dist/services/templates/designCatalog.d.ts +0 -4
  148. package/dist/services/templates/designCatalog.d.ts.map +1 -1
  149. package/dist/services/templates/designCatalog.js +1 -27
  150. package/dist/services/templates/designCatalog.js.map +1 -1
  151. package/dist/storage/profiles/ProfilePlans.d.ts +18 -18
  152. package/dist/storage/profiles/ProfileRecords.d.ts +52 -3
  153. package/dist/storage/profiles/ProfileRecords.d.ts.map +1 -1
  154. package/dist/storage/profiles/ProfileRecords.js +74 -17
  155. package/dist/storage/profiles/ProfileRecords.js.map +1 -1
  156. package/dist/storage/profiles/guidanceVerifier.d.ts +3 -0
  157. package/dist/storage/profiles/guidanceVerifier.d.ts.map +1 -0
  158. package/dist/storage/profiles/guidanceVerifier.js +30 -0
  159. package/dist/storage/profiles/guidanceVerifier.js.map +1 -0
  160. package/dist/storage/profiles/migrations.d.ts +2 -2
  161. package/dist/storage/profiles/migrations.d.ts.map +1 -1
  162. package/dist/storage/profiles/migrations.js +3 -0
  163. package/dist/storage/profiles/migrations.js.map +1 -1
  164. package/dist/storage/profiles/planSchema.d.ts +5 -5
  165. package/dist/storage/profiles/schema.d.ts +28 -1
  166. package/dist/storage/profiles/schema.d.ts.map +1 -1
  167. package/dist/storage/profiles/schema.js +1 -0
  168. package/dist/storage/profiles/schema.js.map +1 -1
  169. package/dist/types/change-types.d.ts +0 -25
  170. package/dist/types/change-types.d.ts.map +1 -1
  171. package/dist/types/cosmos-profile.d.ts +12 -12
  172. package/dist/types/cosmos.d.ts +20 -20
  173. package/dist/types/design-profile.d.ts +16 -16
  174. package/dist/types/guidance-references.d.ts +16 -0
  175. package/dist/types/guidance-references.d.ts.map +1 -1
  176. package/dist/types/guidance-references.js +44 -30
  177. package/dist/types/guidance-references.js.map +1 -1
  178. package/dist/types/guidance-verifier.d.ts +265 -0
  179. package/dist/types/guidance-verifier.d.ts.map +1 -0
  180. package/dist/types/guidance-verifier.js +71 -0
  181. package/dist/types/guidance-verifier.js.map +1 -0
  182. package/dist/types/guidance.d.ts +436 -21
  183. package/dist/types/guidance.d.ts.map +1 -1
  184. package/dist/types/guidance.js +13 -2
  185. package/dist/types/guidance.js.map +1 -1
  186. package/dist/types/reference-connectors.d.ts +20 -20
  187. package/dist/types/reference-onboarding.d.ts +48 -48
  188. package/dist/types/variant-reference.d.ts +4 -4
  189. package/dist/types/x-bookmarks.d.ts +10 -10
  190. package/dist/utils/skills/cli-guidance.d.ts +1 -1
  191. package/dist/utils/skills/cli-guidance.d.ts.map +1 -1
  192. package/dist/utils/skills/cli-guidance.js +19 -6
  193. package/dist/utils/skills/cli-guidance.js.map +1 -1
  194. package/dist/utils/skills/codex-skill.d.ts +1 -1
  195. package/dist/utils/skills/codex-skill.d.ts.map +1 -1
  196. package/dist/utils/skills/codex-skill.js +1 -1
  197. package/package.json +1 -2
  198. package/src/ui/dist/assets/{LibraryEntry-CjxmVfhv.js → LibraryEntry-B9ZkJUtN.js} +8 -8
  199. package/src/ui/dist/assets/main-CXP-A-qy.css +1 -0
  200. package/src/ui/dist/assets/{main-CdSzrhWD.js → main-Dls3YqrM.js} +144 -144
  201. package/src/ui/dist/index.html +2 -2
  202. package/dist/agent-variants/directionAuthoring.d.ts +0 -27
  203. package/dist/agent-variants/directionAuthoring.d.ts.map +0 -1
  204. package/dist/agent-variants/directionAuthoring.js +0 -380
  205. package/dist/agent-variants/directionAuthoring.js.map +0 -1
  206. package/dist/services/ComponentSearchService.d.ts +0 -13
  207. package/dist/services/ComponentSearchService.d.ts.map +0 -1
  208. package/dist/services/ComponentSearchService.js +0 -167
  209. package/dist/services/ComponentSearchService.js.map +0 -1
  210. package/dist/types/style-manipulation-types.d.ts +0 -63
  211. package/dist/types/style-manipulation-types.d.ts.map +0 -1
  212. package/dist/types/style-manipulation-types.js +0 -68
  213. package/dist/types/style-manipulation-types.js.map +0 -1
  214. package/dist/types/token-types.d.ts +0 -24
  215. package/dist/types/token-types.d.ts.map +0 -1
  216. package/dist/types/token-types.js +0 -3
  217. package/dist/types/token-types.js.map +0 -1
  218. package/src/ui/dist/assets/main-DVb3ws41.css +0 -1
@@ -54,6 +54,35 @@ const telemetry_1 = require("../telemetry");
54
54
  const displayLocale_1 = require("../../utils/displayLocale");
55
55
  const pluginContext_1 = require("../../hosts/pluginContext");
56
56
  const errorMessage_1 = require("../../utils/errorMessage");
57
+ const GuidanceVerifierRunner_1 = require("../../services/GuidanceVerifierRunner");
58
+ const toolPresentation = (title, behavior) => ({
59
+ title,
60
+ annotations: { title, ...behavior },
61
+ });
62
+ const STATUS_PRESENTATION = toolPresentation('Check Rivet status', {
63
+ readOnlyHint: true,
64
+ destructiveHint: false,
65
+ idempotentHint: true,
66
+ openWorldHint: true,
67
+ });
68
+ const LOGIN_PRESENTATION = toolPresentation('Sign in to Rivet', {
69
+ readOnlyHint: false,
70
+ destructiveHint: false,
71
+ idempotentHint: true,
72
+ openWorldHint: true,
73
+ });
74
+ const VARIANTS_PRESENTATION = toolPresentation('Generate design variants', {
75
+ readOnlyHint: false,
76
+ destructiveHint: true,
77
+ idempotentHint: false,
78
+ openWorldHint: true,
79
+ });
80
+ const DESIGN_CONTEXT_PRESENTATION = toolPresentation('Gather design context', {
81
+ readOnlyHint: false,
82
+ destructiveHint: true,
83
+ idempotentHint: false,
84
+ openWorldHint: true,
85
+ });
57
86
  const DIRECTION_TITLE_MAX_WORDS = 5;
58
87
  const DIRECTION_SUBTITLE_MAX_WORDS = 10;
59
88
  const RELEVANT_FILE_MAX_COUNT = 12;
@@ -118,7 +147,7 @@ const STATUS_DESCRIPTION = 'Current Rivet session state for this project: server
118
147
  "include: ['history'] adds past variant sets; ['auth'] adds signed-in state.";
119
148
  const VARIANTS_DESCRIPTION = "Drive the variant lifecycle ('directions' in the UI). Actions: 'start' (generate N directions), " +
120
149
  "'complete' (report one work item done), 'commit' (write a chosen variant to the working tree), 'cancel'. " +
121
- "Before 'start', author a 1\u20133 word runLabel summarizing the batch and one brief per direction: label = 1\u20135 word title naming the concrete change; body = \u226410-word subtitle; " +
150
+ "Before every 'start', including fresh apps, resolve saved instructions with rivet_design_context contextAction=resolve, then author a 1\u20133 word runLabel summarizing the batch and one brief per direction: label = 1\u20135 word title naming the concrete change; body = \u226410-word subtitle; " +
122
151
  `Write runLabel, label, and body naturally in ${DISPLAY_LOCALE}. ` +
123
152
  'optional notes = richer implementation intent (tokens, motion specs, constraints) delivered verbatim to that direction\u2019s worker. briefs.length sets the count. ' +
124
153
  "Rivet normally builds directions with its own server-side workers: variants in flight with NO nextAction means watch rivet_status until terminal — implement nothing. When a response DOES carry nextAction.action='complete_host_variant_work' (executor unavailable), follow its parallelism instructions EXACTLY: they name the worker agent type when one applies, and each item's workerPrompt points at a server-authored briefing containing the full packet and completion command \u2014 compose nothing, never re-plan briefs, and let each worker self-report the moment it finishes. " +
@@ -167,21 +196,30 @@ const buildMcpServer = async (options = {}) => {
167
196
  const project = toolProject ?? serveProject;
168
197
  return project ? ['--project', project] : [];
169
198
  };
170
- const runCommand = async (command, rest, toolCallHandoffArgs = []) => {
199
+ const verificationAbort = new AbortController();
200
+ const runCommand = async (command, rest, commandOptions = {}) => {
171
201
  const progress = [];
172
202
  const io = {
173
203
  writeEnvelope: () => { },
174
204
  writeProgress: (message) => progress.push(message),
175
205
  };
176
- const argv = [...rest, ...handoffArgs, ...toolCallHandoffArgs];
206
+ const argv = [
207
+ ...rest,
208
+ ...handoffArgs,
209
+ ...(commandOptions.handoffArgs ?? []),
210
+ ];
177
211
  const startedAt = Date.now();
178
212
  let result;
179
213
  try {
180
214
  await maybeResumePendingLogin();
181
- result = await dispatch(command, argv, io);
215
+ result = await dispatch(command, argv, io, {
216
+ signal: commandOptions.signal,
217
+ });
182
218
  if (!result.envelope.ok && (0, exports.isStaleAttachError)(result.envelope)) {
183
219
  (0, client_1.invalidateAttachCache)();
184
- result = await dispatch(command, argv, io);
220
+ result = await dispatch(command, argv, io, {
221
+ signal: commandOptions.signal,
222
+ });
185
223
  }
186
224
  }
187
225
  catch (error) {
@@ -309,15 +347,19 @@ const buildMcpServer = async (options = {}) => {
309
347
  return result;
310
348
  });
311
349
  };
312
- mcp.tool('rivet_status', STATUS_DESCRIPTION, {
313
- project: v3_1.z
314
- .string()
315
- .optional()
316
- .describe('Project root path; defaults to the server for the current directory'),
317
- include: v3_1.z
318
- .array(v3_1.z.enum(['history', 'auth']))
319
- .optional()
320
- .describe('history = committed/past variant sets; auth = signed-in state'),
350
+ mcp.registerTool('rivet_status', {
351
+ ...STATUS_PRESENTATION,
352
+ description: STATUS_DESCRIPTION,
353
+ inputSchema: {
354
+ project: v3_1.z
355
+ .string()
356
+ .optional()
357
+ .describe('Project root path; defaults to the server for the current directory'),
358
+ include: v3_1.z
359
+ .array(v3_1.z.enum(['history', 'auth']))
360
+ .optional()
361
+ .describe('history = committed/past variant sets; auth = signed-in state'),
362
+ },
321
363
  }, async ({ project, include }) => {
322
364
  const startedAt = Date.now();
323
365
  const wantHistory = include?.includes('history') ?? false;
@@ -368,14 +410,18 @@ const buildMcpServer = async (options = {}) => {
368
410
  },
369
411
  });
370
412
  });
371
- mcp.tool('rivet_login', LOGIN_DESCRIPTION, {
372
- waitSeconds: v3_1.z
373
- .number()
374
- .int()
375
- .min(0)
376
- .max(LOGIN_WAIT_MAX_SECONDS)
377
- .optional()
378
- .describe('How long to wait for the user to finish the browser sign-in before returning (default 45). Pass a higher value when the user says they need a moment; 0 returns immediately after opening the browser.'),
413
+ mcp.registerTool('rivet_login', {
414
+ ...LOGIN_PRESENTATION,
415
+ description: LOGIN_DESCRIPTION,
416
+ inputSchema: {
417
+ waitSeconds: v3_1.z
418
+ .number()
419
+ .int()
420
+ .min(0)
421
+ .max(LOGIN_WAIT_MAX_SECONDS)
422
+ .optional()
423
+ .describe('How long to wait for the user to finish the browser sign-in before returning (default 45). Pass a higher value when the user says they need a moment; 0 returns immediately after opening the browser.'),
424
+ },
379
425
  }, async ({ waitSeconds }) => {
380
426
  const startedAt = Date.now();
381
427
  const loginResult = (data, ok = true) => {
@@ -470,170 +516,177 @@ const buildMcpServer = async (options = {}) => {
470
516
  }, false);
471
517
  }
472
518
  });
473
- mcp.tool('rivet_variants', VARIANTS_DESCRIPTION, {
474
- action: v3_1.z.enum(['start', 'complete', 'commit', 'cancel']),
475
- instruction: v3_1.z
476
- .string()
477
- .optional()
478
- .describe('start: what to vary and how'),
479
- runLabel: contracts_1.runLabelSchema.describe('start: AI-authored 1–3 word summary shared by every direction in this batch'),
480
- count: v3_1.z
481
- .number()
482
- .int()
483
- .positive()
484
- .optional()
485
- .describe('start: number of variants'),
486
- briefs: v3_1.z
487
- .array(v3_1.z.object({
488
- label: v3_1.z
519
+ mcp.registerTool('rivet_variants', {
520
+ ...VARIANTS_PRESENTATION,
521
+ description: VARIANTS_DESCRIPTION,
522
+ inputSchema: {
523
+ action: v3_1.z.enum(['start', 'complete', 'commit', 'cancel']),
524
+ instruction: v3_1.z
489
525
  .string()
490
- .trim()
491
- .min(1)
492
- .max(48)
493
- .refine((label) => label.split(/\s+/).length <= DIRECTION_TITLE_MAX_WORDS, {
494
- message: 'Direction titles must contain at most 5 words',
526
+ .optional()
527
+ .describe('start: what to vary and how'),
528
+ runLabel: contracts_1.runLabelSchema.describe('start: AI-authored 1–3 word summary shared by every direction in this batch'),
529
+ count: v3_1.z
530
+ .number()
531
+ .int()
532
+ .positive()
533
+ .optional()
534
+ .describe('start: number of variants'),
535
+ briefs: v3_1.z
536
+ .array(v3_1.z.object({
537
+ label: v3_1.z
538
+ .string()
539
+ .trim()
540
+ .min(1)
541
+ .max(48)
542
+ .refine((label) => label.split(/\s+/).length <= DIRECTION_TITLE_MAX_WORDS, {
543
+ message: 'Direction titles must contain at most 5 words',
544
+ })
545
+ .describe('AI-authored 1–5 word direction title'),
546
+ body: v3_1.z
547
+ .string()
548
+ .trim()
549
+ .min(1)
550
+ .max(600)
551
+ .refine((body) => body.split(/\s+/).length <= DIRECTION_SUBTITLE_MAX_WORDS, {
552
+ message: 'Direction subtitles must contain at most 10 words',
553
+ })
554
+ .describe('Concise direction subtitle of at most 10 words'),
555
+ notes: v3_1.z
556
+ .string()
557
+ .trim()
558
+ .min(1)
559
+ .max(4000)
560
+ .optional()
561
+ .describe('Optional implementation notes for this direction, passed verbatim to its worker (design tokens, motion specs, constraints). Not shown in UI chips.'),
562
+ visualReferenceUrl: v3_1.z.string().url().optional(),
563
+ }))
564
+ .min(contracts_1.VARIANT_COUNT_MIN)
565
+ .max(contracts_1.VARIANT_COUNT_MAX)
566
+ .superRefine((briefs, context) => {
567
+ const labels = briefs.map((brief) => brief.label.toLowerCase());
568
+ if (new Set(labels).size !== labels.length) {
569
+ context.addIssue({
570
+ code: v3_1.z.ZodIssueCode.custom,
571
+ message: 'Direction titles must be distinct',
572
+ });
573
+ }
495
574
  })
496
- .describe('AI-authored 1–5 word direction title'),
497
- body: v3_1.z
575
+ .optional()
576
+ .describe('start: one AI-authored title/subtitle brief per direction; use one for a single visualization or distinct briefs for divergent ideas; briefs.length sets the variant count'),
577
+ element: v3_1.z
498
578
  .string()
499
- .trim()
500
- .min(1)
501
- .max(600)
502
- .refine((body) => body.split(/\s+/).length <= DIRECTION_SUBTITLE_MAX_WORDS, {
503
- message: 'Direction subtitles must contain at most 10 words',
504
- })
505
- .describe('Concise direction subtitle of at most 10 words'),
506
- notes: v3_1.z
579
+ .optional()
580
+ .describe('start: CSS selector scoping the variation'),
581
+ files: v3_1.z
582
+ .array(v3_1.z.string().trim().min(1))
583
+ .max(RELEVANT_FILE_MAX_COUNT)
584
+ .optional()
585
+ .describe('start: known project files for workers to inspect before broader discovery'),
586
+ fresh: v3_1.z
587
+ .boolean()
588
+ .optional()
589
+ .describe('start: ignore prior variant context'),
590
+ profile: v3_1.z
591
+ .enum(['auto', 'off'])
592
+ .optional()
593
+ .describe('start: saved references are off by default; auto selects relevant references when the user asks for them'),
594
+ guidance: v3_1.z
595
+ .enum(['auto', 'off'])
596
+ .optional()
597
+ .describe('start: apply saved instructions, or turn them off for this request only'),
598
+ excludedGuidanceIds: v3_1.z
599
+ .array(v3_1.z.string().min(1).max(200))
600
+ .optional()
601
+ .describe('start: saved instruction document IDs to exclude for this request only'),
602
+ fidelity: v3_1.z
603
+ .enum(['low', 'medium', 'high'])
604
+ .optional()
605
+ .describe("start: the user's design-fidelity intent. low = fast sketch-grade workers (quick ideas/explorations); medium = balanced; high = the default with maximum deliberation, up to a few minutes (polished/pixel-perfect/final asks). Omit when unstated."),
606
+ workerProvider: v3_1.z
607
+ .enum(['claude', 'codex', 'cursor'])
608
+ .optional()
609
+ .describe('start: run the workers on this provider CLI instead of the one matching your caller agent. Pass ONLY when the user explicitly asks ("use opus for the workers") — it spends on that provider\'s subscription, so never infer it.'),
610
+ workerModel: v3_1.z
507
611
  .string()
508
612
  .trim()
509
613
  .min(1)
510
- .max(4000)
614
+ .max(200)
511
615
  .optional()
512
- .describe('Optional implementation notes for this direction, passed verbatim to its worker (design tokens, motion specs, constraints). Not shown in UI chips.'),
513
- visualReferenceUrl: v3_1.z.string().url().optional(),
514
- }))
515
- .min(contracts_1.VARIANT_COUNT_MIN)
516
- .max(contracts_1.VARIANT_COUNT_MAX)
517
- .superRefine((briefs, context) => {
518
- const labels = briefs.map((brief) => brief.label.toLowerCase());
519
- if (new Set(labels).size !== labels.length) {
520
- context.addIssue({
521
- code: v3_1.z.ZodIssueCode.custom,
522
- message: 'Direction titles must be distinct',
523
- });
524
- }
525
- })
526
- .optional()
527
- .describe('start: one AI-authored title/subtitle brief per direction; use one for a single visualization or distinct briefs for divergent ideas; briefs.length sets the variant count'),
528
- element: v3_1.z
529
- .string()
530
- .optional()
531
- .describe('start: CSS selector scoping the variation'),
532
- files: v3_1.z
533
- .array(v3_1.z.string().trim().min(1))
534
- .max(RELEVANT_FILE_MAX_COUNT)
535
- .optional()
536
- .describe('start: known project files for workers to inspect before broader discovery'),
537
- fresh: v3_1.z
538
- .boolean()
539
- .optional()
540
- .describe('start: ignore prior variant context'),
541
- profile: v3_1.z
542
- .enum(['auto', 'off'])
543
- .optional()
544
- .describe('start: saved references are off by default; auto selects relevant references when the user asks for them'),
545
- guidance: v3_1.z
546
- .enum(['auto', 'off'])
547
- .optional()
548
- .describe('start: apply saved instructions, or turn them off for this request only'),
549
- excludedGuidanceIds: v3_1.z
550
- .array(v3_1.z.string().min(1).max(200))
551
- .optional()
552
- .describe('start: saved instruction document IDs to exclude for this request only'),
553
- fidelity: v3_1.z
554
- .enum(['low', 'medium', 'high'])
555
- .optional()
556
- .describe("start: the user's design-fidelity intent. low = fast sketch-grade workers (quick ideas/explorations); medium = balanced; high = the default with maximum deliberation, up to a few minutes (polished/pixel-perfect/final asks). Omit when unstated."),
557
- workerProvider: v3_1.z
558
- .enum(['claude', 'codex', 'cursor'])
559
- .optional()
560
- .describe('start: run the workers on this provider CLI instead of the one matching your caller agent. Pass ONLY when the user explicitly asks ("use opus for the workers") — it spends on that provider\'s subscription, so never infer it.'),
561
- workerModel: v3_1.z
562
- .string()
563
- .trim()
564
- .min(1)
565
- .max(200)
566
- .optional()
567
- .describe('start: pin the worker model id for the selected (or caller-matching) provider. Pass ONLY on an explicit user request; a pinned model never silently falls back.'),
568
- contextImages: v3_1.z
569
- .array(v3_1.z.string().trim().min(1))
570
- .min(1)
571
- .optional()
572
- .describe('start: local reference image file paths (png/jpg/webp/gif/avif). Rivet copies them into the run context and every worker views them natively — pass the actual images instead of describing them in notes.'),
573
- contextAssets: v3_1.z
574
- .array(contracts_1.contextAssetInputSchema)
575
- .min(1)
576
- .max(contracts_1.CONTEXT_ASSET_MAX_ITEMS)
577
- .optional()
578
- .describe('start: local regular files copied into every variant workspace and exposed to workers with stable file and reference paths.'),
579
- referencePages: v3_1.z
580
- .array(v3_1.z.string().trim().min(1))
581
- .min(1)
582
- .max(3)
583
- .optional()
584
- .describe('start (fresh only): reference page URLs. Rivet renders each page server-side (design evidence + screenshot) — pass the raw URLs, never capture evidence or screenshot pages yourself.'),
585
- referenceVideos: v3_1.z
586
- .array(v3_1.z.string().trim().min(1))
587
- .min(1)
588
- .max(2)
589
- .optional()
590
- .describe('start (fresh only): local reference video file paths (mp4/mov/webm/m4v). Rivet samples keyframes server-side — pass the raw paths, never run ffmpeg yourself.'),
591
- target: v3_1.z
592
- .string()
593
- .optional()
594
- .describe('start: sessionId:variantId — refine an existing variant in place'),
595
- workId: v3_1.z.string().optional().describe('complete: host work item id'),
596
- status: v3_1.z
597
- .enum(['succeeded', 'failed', 'cancelled'])
598
- .optional()
599
- .describe('complete: terminal work status'),
600
- output: v3_1.z
601
- .unknown()
602
- .optional()
603
- .describe('complete: optional orchestrator output payload'),
604
- error: v3_1.z.string().optional().describe('complete: failure message'),
605
- title: v3_1.z.string().optional().describe('complete: optional variant title'),
606
- description: v3_1.z
607
- .string()
608
- .optional()
609
- .describe('complete: optional variant description'),
610
- variantId: v3_1.z
611
- .string()
612
- .optional()
613
- .describe('commit: the variant to write into the working tree'),
614
- sessionId: v3_1.z
615
- .string()
616
- .optional()
617
- .describe('complete/commit: source session (optional) · cancel: session to cancel (required)'),
618
- project: v3_1.z.string().optional().describe('Project root path'),
616
+ .describe('start: pin the worker model id for the selected (or caller-matching) provider. Pass ONLY on an explicit user request; a pinned model never silently falls back.'),
617
+ contextImages: v3_1.z
618
+ .array(v3_1.z.string().trim().min(1))
619
+ .min(1)
620
+ .optional()
621
+ .describe('start: local reference image file paths (png/jpg/webp/gif/avif). Rivet copies them into the run context and every worker views them natively — pass the actual images instead of describing them in notes.'),
622
+ contextAssets: v3_1.z
623
+ .array(contracts_1.contextAssetInputSchema)
624
+ .min(1)
625
+ .max(contracts_1.CONTEXT_ASSET_MAX_ITEMS)
626
+ .optional()
627
+ .describe('start: local regular files copied into every variant workspace and exposed to workers with stable file and reference paths.'),
628
+ referencePages: v3_1.z
629
+ .array(v3_1.z.string().trim().min(1))
630
+ .min(1)
631
+ .max(3)
632
+ .optional()
633
+ .describe('start (fresh only): reference page URLs. Rivet renders each page server-side (design evidence + screenshot) — pass the raw URLs, never capture evidence or screenshot pages yourself.'),
634
+ referenceVideos: v3_1.z
635
+ .array(v3_1.z.string().trim().min(1))
636
+ .min(1)
637
+ .max(2)
638
+ .optional()
639
+ .describe('start (fresh only): local reference video file paths (mp4/mov/webm/m4v). Rivet samples keyframes server-side — pass the raw paths, never run ffmpeg yourself.'),
640
+ target: v3_1.z
641
+ .string()
642
+ .optional()
643
+ .describe('start: sessionId:variantId — refine an existing variant in place'),
644
+ workId: v3_1.z.string().optional().describe('complete: host work item id'),
645
+ status: v3_1.z
646
+ .enum(['succeeded', 'failed', 'cancelled'])
647
+ .optional()
648
+ .describe('complete: terminal work status'),
649
+ output: v3_1.z
650
+ .unknown()
651
+ .optional()
652
+ .describe('complete: optional orchestrator output payload'),
653
+ error: v3_1.z.string().optional().describe('complete: failure message'),
654
+ title: v3_1.z
655
+ .string()
656
+ .optional()
657
+ .describe('complete: optional variant title'),
658
+ description: v3_1.z
659
+ .string()
660
+ .optional()
661
+ .describe('complete: optional variant description'),
662
+ variantId: v3_1.z
663
+ .string()
664
+ .optional()
665
+ .describe('commit: the variant to write into the working tree'),
666
+ sessionId: v3_1.z
667
+ .string()
668
+ .optional()
669
+ .describe('complete/commit: source session (optional) · cancel: session to cancel (required)'),
670
+ project: v3_1.z.string().optional().describe('Project root path'),
671
+ },
619
672
  }, async ({ action, instruction, runLabel, count, briefs, element, files, fresh, fidelity, profile, guidance, excludedGuidanceIds, workerProvider, workerModel, contextImages, contextAssets, referencePages, referenceVideos, target, workId, status, output, error, title, description, variantId, sessionId, project, }, extra) => {
620
673
  const startedAt = Date.now();
621
674
  let rest;
622
675
  if (action === 'start') {
623
- if (!briefs && !fresh) {
676
+ if (!briefs) {
624
677
  return completeToolCall({
625
678
  toolName: 'rivet_variants',
626
679
  operation: action,
627
680
  startedAt,
628
- envelope: (0, envelope_1.errorResult)('rivet_variants', 'USAGE_ERROR', 'rivet_variants action=start requires briefs with one AI-authored title/subtitle per direction (fresh starts may omit them — Rivet authors directions server-side).').envelope,
681
+ envelope: (0, envelope_1.errorResult)('rivet_variants', 'USAGE_ERROR', 'rivet_variants action=start requires briefs with one AI-authored title/subtitle per direction, including fresh starts.').envelope,
629
682
  });
630
683
  }
631
- if (!runLabel && !fresh) {
684
+ if (!runLabel) {
632
685
  return completeToolCall({
633
686
  toolName: 'rivet_variants',
634
687
  operation: action,
635
688
  startedAt,
636
- envelope: (0, envelope_1.errorResult)('rivet_variants', 'USAGE_ERROR', 'rivet_variants action=start requires runLabel with an AI-authored 1–3 word batch summary (fresh starts may omit it).').envelope,
689
+ envelope: (0, envelope_1.errorResult)('rivet_variants', 'USAGE_ERROR', 'rivet_variants action=start requires runLabel with an AI-authored 1–3 word batch summary, including fresh starts.').envelope,
637
690
  });
638
691
  }
639
692
  rest = [
@@ -692,7 +745,7 @@ const buildMcpServer = async (options = {}) => {
692
745
  else {
693
746
  rest = ['cancel', ...(sessionId !== undefined ? [sessionId] : [])];
694
747
  }
695
- const { envelope, progress } = await runCommand('variants', [...rest, ...projectArgs(project)], (0, callerModel_1.callerModelArgsFromToolMeta)(extra._meta));
748
+ const { envelope, progress } = await runCommand('variants', [...rest, ...projectArgs(project)], { handoffArgs: (0, callerModel_1.callerModelArgsFromToolMeta)(extra._meta) });
696
749
  return completeToolCall({
697
750
  toolName: 'rivet_variants',
698
751
  operation: action,
@@ -703,162 +756,210 @@ const buildMcpServer = async (options = {}) => {
703
756
  (target !== undefined ? target.split(':')[0] : undefined),
704
757
  });
705
758
  });
706
- mcp.tool('rivet_design_context', DESIGN_CONTEXT_DESCRIPTION, {
707
- contextAction: v3_1.z
708
- .enum([
709
- 'add',
710
- 'list',
711
- 'show',
712
- 'update',
713
- 'enable',
714
- 'disable',
715
- 'remove',
716
- 'resolve',
717
- 'inspect',
718
- ])
719
- .optional()
720
- .describe('Manage saved instructions applied across projects. Separate from optional reference profiles; lookup uses no model.'),
721
- contextId: v3_1.z
722
- .string()
723
- .min(1)
724
- .max(200)
725
- .optional()
726
- .describe('Saved instruction document ID for show, update, enable, disable, or remove'),
727
- contextFile: v3_1.z
728
- .string()
729
- .min(1)
730
- .optional()
731
- .describe('Local UTF-8 Markdown file copied when adding or updating saved instructions'),
732
- contextReferences: v3_1.z
733
- .string()
734
- .min(1)
735
- .optional()
736
- .describe('Local JSON reference manifest for context add/update. Entries are {kind:"url"|"repository",url,intent,revision?,files?:[{name,path}]} or {kind:"directory",path,intent}. Repository URLs default to URL-only; existing local repositories or installed libraries use directory pointers without cloning or copying contents. Directory paths resolve relative to the manifest and remain live read-only sources, not snapshots. Omit files and additional setup Markdown unless the user explicitly requests a snapshot or approves a file selection. URLs are not fetched; this does not authorize source ingestion.'),
737
- guidance: v3_1.z
738
- .enum(['auto', 'off'])
739
- .optional()
740
- .describe('resolve: selection mode for this read only'),
741
- excludedGuidanceIds: v3_1.z
742
- .array(v3_1.z.string().min(1).max(200))
743
- .optional()
744
- .describe('resolve: saved instruction document IDs to exclude for this read only'),
745
- url: v3_1.z
746
- .string()
747
- .optional()
748
- .describe('The URL to gather design context from'),
749
- profileAction: v3_1.z
750
- .enum([
751
- 'status',
752
- 'diagnostics',
753
- 'rebuild-index',
754
- 'enable',
755
- 'disable',
756
- 'connect',
757
- 'refresh',
758
- 'pause',
759
- 'resume',
760
- 'retry',
761
- 'add-text',
762
- 'add-images',
763
- 'pins',
764
- 'add-variant',
765
- 'references',
766
- 'reference',
767
- 'include',
768
- 'exclude',
769
- 'remove',
770
- 'suggest',
771
- 'inspect',
772
- 'discover',
773
- 'plan',
774
- 'import',
775
- 'onboarding',
776
- ])
777
- .optional()
778
- .describe('Manage the local cross-project design profile instead of fetching a URL. sourceId also identifies a job for pause/resume/retry.'),
779
- title: v3_1.z.string().optional(),
780
- text: v3_1.z.string().optional(),
781
- files: v3_1.z.array(v3_1.z.string()).optional(),
782
- query: v3_1.z.string().optional(),
783
- sourceId: v3_1.z.string().optional(),
784
- profileId: v3_1.z
785
- .string()
786
- .uuid()
787
- .optional()
788
- .describe('Library identity from the copied command'),
789
- referenceKeys: v3_1.z
790
- .array(v3_1.z.string())
791
- .min(1)
792
- .max(design_library_1.DESIGN_REFERENCE_BATCH_LIMIT)
793
- .optional()
794
- .describe('One or more copied shortId@revision keys to resolve in a single query'),
795
- isDetailed: v3_1.z
796
- .boolean()
797
- .optional()
798
- .describe('Include full saved text, analysis, sources, and validated image paths; default metadata only'),
799
- discoveryId: v3_1.z
800
- .string()
801
- .uuid()
802
- .optional()
803
- .describe('Saved discovery to plan selected collections from'),
804
- planId: v3_1.z
805
- .string()
806
- .uuid()
807
- .optional()
808
- .describe('Saved plan to inspect or explicitly approve'),
809
- planRevision: v3_1.z
810
- .string()
811
- .optional()
812
- .describe('Exact revision shown in the reviewed plan'),
813
- collectionIds: v3_1.z.array(v3_1.z.string()).optional(),
814
- isApproved: v3_1.z
815
- .boolean()
816
- .optional()
817
- .describe('Set true only after the user approves the displayed scope and agent usage'),
818
- onboardingAction: v3_1.z.enum(['later', 'dismiss', 'reset']).optional(),
819
- referenceProvider: v3_1.z
820
- .enum(['cosmos', 'pinterest', 'arena', 'x'])
821
- .optional()
822
- .describe('Provider to discover or set onboarding preferences for. Cosmos discovery requires its public profile URL.'),
823
- requestId: v3_1.z
824
- .string()
825
- .min(1)
826
- .max(200)
827
- .optional()
828
- .describe('Top-level workId from variants start to inspect, or suggestion request identity'),
829
- projectId: v3_1.z
830
- .string()
831
- .optional()
832
- .describe('Stable library project ID for pins or add-variant'),
833
- variantRef: v3_1.z
834
- .string()
835
- .optional()
836
- .describe('Exact sessionId:variantId to save as profile context'),
837
- note: v3_1.z.string().optional(),
838
- imageFile: v3_1.z
839
- .string()
840
- .optional()
841
- .describe('Supplied screenshot for a direction without a saved static preview'),
842
- runtime: v3_1.z.enum(['codex', 'claude', 'cursor']).optional(),
843
- screenshot: v3_1.z
844
- .boolean()
845
- .optional()
846
- .describe('Capture a screenshot (render path only)'),
847
- width: v3_1.z
848
- .number()
849
- .int()
850
- .positive()
851
- .optional()
852
- .describe('Viewport width (render path only)'),
853
- height: v3_1.z
854
- .number()
855
- .int()
856
- .positive()
857
- .optional()
858
- .describe('Viewport height (render path only)'),
859
- project: v3_1.z.string().optional().describe('Project root path'),
860
- }, async ({ url, contextAction, contextId, contextFile, contextReferences, guidance, excludedGuidanceIds, screenshot, width, height, project, profileAction, title, text, files, query, sourceId, profileId, referenceKeys, isDetailed, discoveryId, planId, planRevision, collectionIds, isApproved, onboardingAction, referenceProvider, requestId, projectId, variantRef, note, imageFile, runtime, }) => {
759
+ mcp.registerTool('rivet_design_context', {
760
+ ...DESIGN_CONTEXT_PRESENTATION,
761
+ description: DESIGN_CONTEXT_DESCRIPTION,
762
+ inputSchema: {
763
+ contextAction: v3_1.z
764
+ .enum([
765
+ 'add',
766
+ 'list',
767
+ 'show',
768
+ 'update',
769
+ 'enable',
770
+ 'disable',
771
+ 'remove',
772
+ 'resolve',
773
+ 'inspect',
774
+ 'verifier',
775
+ 'verify',
776
+ ])
777
+ .optional()
778
+ .describe('Manage saved instructions applied across projects. verifier retrieves one source and its checking recipe without execution; verify explicitly runs a saved executable package locally against project and contextVerifierInput. No automatic verification. Separate from optional reference profiles; lookup uses no model.'),
779
+ contextId: v3_1.z
780
+ .string()
781
+ .min(1)
782
+ .max(200)
783
+ .optional()
784
+ .describe('Saved instruction document ID for show, update, enable, disable, remove, verifier, or verify'),
785
+ contextFile: v3_1.z
786
+ .string()
787
+ .min(1)
788
+ .optional()
789
+ .describe('Local UTF-8 Markdown file copied when adding or updating saved instructions'),
790
+ contextVerifier: v3_1.z
791
+ .string()
792
+ .min(1)
793
+ .optional()
794
+ .describe('update: local UTF-8 Markdown verifier recipe, saved only after the user agrees to reuse it; requires contextSourceDigest'),
795
+ contextVerifierPackage: v3_1.z
796
+ .string()
797
+ .min(1)
798
+ .optional()
799
+ .describe('update: local JSON manifest {runtime:"node",entrypoint:"verify.mjs",files:[{name,path}]} for trusted local executable code retained beside contextVerifier; no dependency installation'),
800
+ contextVerifierInput: v3_1.z
801
+ .string()
802
+ .min(1)
803
+ .optional()
804
+ .describe('verify: required local JSON object with package-specific target URL, selectors, modes and prerequisites; explicit local execution, not a sandbox'),
805
+ contextSourceDigest: v3_1.z
806
+ .string()
807
+ .regex(/^[a-f0-9]{64}$/)
808
+ .optional()
809
+ .describe('update: exact sourceDigest from contextAction verifier, binding the recipe to the source inspected'),
810
+ removeContextVerifier: v3_1.z
811
+ .boolean()
812
+ .optional()
813
+ .describe('update: remove only the saved verifier recipe, preserving its source'),
814
+ contextReferences: v3_1.z
815
+ .string()
816
+ .min(1)
817
+ .optional()
818
+ .describe('Local JSON reference manifest for context add/update. Entries are {kind:"url"|"repository",url,intent,revision?,files?:[{name,path}]} or {kind:"directory",path,intent}. Repository URLs default to URL-only; existing local repositories or installed libraries use directory pointers without cloning or copying contents. Directory paths resolve relative to the manifest and remain live read-only sources, not snapshots. Omit files and additional setup Markdown unless the user explicitly requests a snapshot or approves a file selection. URLs are not fetched; this does not authorize source ingestion.'),
819
+ guidance: v3_1.z
820
+ .enum(['auto', 'off'])
821
+ .optional()
822
+ .describe('resolve: selection mode for this read only'),
823
+ excludedGuidanceIds: v3_1.z
824
+ .array(v3_1.z.string().min(1).max(200))
825
+ .optional()
826
+ .describe('resolve: saved instruction document IDs to exclude for this read only'),
827
+ url: v3_1.z
828
+ .string()
829
+ .optional()
830
+ .describe('The URL to gather design context from'),
831
+ profileAction: v3_1.z
832
+ .enum([
833
+ 'status',
834
+ 'diagnostics',
835
+ 'rebuild-index',
836
+ 'enable',
837
+ 'disable',
838
+ 'connect',
839
+ 'refresh',
840
+ 'pause',
841
+ 'resume',
842
+ 'retry',
843
+ 'add-text',
844
+ 'add-images',
845
+ 'pins',
846
+ 'add-variant',
847
+ 'references',
848
+ 'reference',
849
+ 'include',
850
+ 'exclude',
851
+ 'remove',
852
+ 'suggest',
853
+ 'inspect',
854
+ 'discover',
855
+ 'plan',
856
+ 'import',
857
+ 'onboarding',
858
+ ])
859
+ .optional()
860
+ .describe('Manage the local cross-project design profile instead of fetching a URL. sourceId also identifies a job for pause/resume/retry.'),
861
+ title: v3_1.z.string().optional(),
862
+ text: v3_1.z.string().optional(),
863
+ files: v3_1.z.array(v3_1.z.string()).optional(),
864
+ query: v3_1.z.string().optional(),
865
+ sourceId: v3_1.z.string().optional(),
866
+ profileId: v3_1.z
867
+ .string()
868
+ .uuid()
869
+ .optional()
870
+ .describe('Library identity from the copied command'),
871
+ referenceKeys: v3_1.z
872
+ .array(v3_1.z.string())
873
+ .min(1)
874
+ .max(design_library_1.DESIGN_REFERENCE_BATCH_LIMIT)
875
+ .optional()
876
+ .describe('One or more copied shortId@revision keys to resolve in a single query'),
877
+ isDetailed: v3_1.z
878
+ .boolean()
879
+ .optional()
880
+ .describe('Include full saved text, analysis, sources, and validated image paths; default metadata only'),
881
+ discoveryId: v3_1.z
882
+ .string()
883
+ .uuid()
884
+ .optional()
885
+ .describe('Saved discovery to plan selected collections from'),
886
+ planId: v3_1.z
887
+ .string()
888
+ .uuid()
889
+ .optional()
890
+ .describe('Saved plan to inspect or explicitly approve'),
891
+ planRevision: v3_1.z
892
+ .string()
893
+ .optional()
894
+ .describe('Exact revision shown in the reviewed plan'),
895
+ collectionIds: v3_1.z.array(v3_1.z.string()).optional(),
896
+ isApproved: v3_1.z
897
+ .boolean()
898
+ .optional()
899
+ .describe('Set true only after the user approves the displayed scope and agent usage'),
900
+ onboardingAction: v3_1.z.enum(['later', 'dismiss', 'reset']).optional(),
901
+ referenceProvider: v3_1.z
902
+ .enum(['cosmos', 'pinterest', 'arena', 'x'])
903
+ .optional()
904
+ .describe('Provider to discover or set onboarding preferences for. Cosmos discovery requires its public profile URL.'),
905
+ requestId: v3_1.z
906
+ .string()
907
+ .min(1)
908
+ .max(200)
909
+ .optional()
910
+ .describe('Top-level workId from variants start to inspect, or suggestion request identity'),
911
+ projectId: v3_1.z
912
+ .string()
913
+ .optional()
914
+ .describe('Stable library project ID for pins or add-variant'),
915
+ variantRef: v3_1.z
916
+ .string()
917
+ .optional()
918
+ .describe('Exact sessionId:variantId to save as profile context'),
919
+ note: v3_1.z.string().optional(),
920
+ imageFile: v3_1.z
921
+ .string()
922
+ .optional()
923
+ .describe('Supplied screenshot for a direction without a saved static preview'),
924
+ runtime: v3_1.z.enum(['codex', 'claude', 'cursor']).optional(),
925
+ screenshot: v3_1.z
926
+ .boolean()
927
+ .optional()
928
+ .describe('Capture a screenshot (render path only)'),
929
+ width: v3_1.z
930
+ .number()
931
+ .int()
932
+ .positive()
933
+ .optional()
934
+ .describe('Viewport width (render path only)'),
935
+ height: v3_1.z
936
+ .number()
937
+ .int()
938
+ .positive()
939
+ .optional()
940
+ .describe('Viewport height (render path only)'),
941
+ project: v3_1.z.string().optional().describe('Project root path'),
942
+ },
943
+ }, async ({ url, contextAction, contextId, contextFile, contextReferences, contextVerifier, contextVerifierPackage, contextVerifierInput, contextSourceDigest, removeContextVerifier, guidance, excludedGuidanceIds, screenshot, width, height, project, profileAction, title, text, files, query, sourceId, profileId, referenceKeys, isDetailed, discoveryId, planId, planRevision, collectionIds, isApproved, onboardingAction, referenceProvider, requestId, projectId, variantRef, note, imageFile, runtime, }, extra) => {
861
944
  const startedAt = Date.now();
945
+ const hasVerifierUpdate = contextVerifier !== undefined ||
946
+ contextVerifierPackage !== undefined ||
947
+ contextSourceDigest !== undefined ||
948
+ removeContextVerifier === true;
949
+ if (contextVerifierInput !== undefined && contextAction !== 'verify')
950
+ return completeToolCall({
951
+ toolName: 'rivet_design_context',
952
+ operation: 'context.verify',
953
+ startedAt,
954
+ envelope: (0, envelope_1.errorResult)('context.verify', 'USAGE_ERROR', 'contextVerifierInput requires contextAction verify').envelope,
955
+ });
956
+ if (hasVerifierUpdate && contextAction !== 'update')
957
+ return completeToolCall({
958
+ toolName: 'rivet_design_context',
959
+ operation: 'context.update',
960
+ startedAt,
961
+ envelope: (0, envelope_1.errorResult)('context.update', 'USAGE_ERROR', 'Verifier changes require contextAction update').envelope,
962
+ });
862
963
  if (contextAction) {
863
964
  if (profileAction || url) {
864
965
  return completeToolCall({
@@ -874,6 +975,8 @@ const buildMcpServer = async (options = {}) => {
874
975
  'enable',
875
976
  'disable',
876
977
  'remove',
978
+ 'verifier',
979
+ 'verify',
877
980
  ].includes(contextAction);
878
981
  const isWriteAction = contextAction === 'add' || contextAction === 'update';
879
982
  const isResolveAction = contextAction === 'resolve';
@@ -890,6 +993,19 @@ const buildMcpServer = async (options = {}) => {
890
993
  ...(isWriteAction && contextReferences !== undefined
891
994
  ? ['--references', contextReferences]
892
995
  : []),
996
+ ...(contextVerifier !== undefined
997
+ ? ['--verifier', contextVerifier]
998
+ : []),
999
+ ...(contextVerifierPackage !== undefined
1000
+ ? ['--verifier-package', contextVerifierPackage]
1001
+ : []),
1002
+ ...(contextVerifierInput !== undefined
1003
+ ? ['--input', contextVerifierInput]
1004
+ : []),
1005
+ ...(contextSourceDigest !== undefined
1006
+ ? ['--source-digest', contextSourceDigest]
1007
+ : []),
1008
+ ...(removeContextVerifier ? ['--remove-verifier'] : []),
893
1009
  ...(isResolveAction && guidance !== undefined
894
1010
  ? ['--guidance', guidance]
895
1011
  : []),
@@ -897,7 +1013,7 @@ const buildMcpServer = async (options = {}) => {
897
1013
  ? ['--exclude-guidance', JSON.stringify(excludedGuidanceIds)]
898
1014
  : []),
899
1015
  ...projectArgs(project),
900
- ]);
1016
+ ], { signal: AbortSignal.any([extra.signal, verificationAbort.signal]) });
901
1017
  return completeToolCall({
902
1018
  toolName: 'rivet_design_context',
903
1019
  operation: `context.${contextAction}`,
@@ -994,7 +1110,14 @@ const buildMcpServer = async (options = {}) => {
994
1110
  progress,
995
1111
  });
996
1112
  });
997
- return { mcp, telemetry };
1113
+ return {
1114
+ mcp,
1115
+ telemetry,
1116
+ cancelVerifications: async () => {
1117
+ verificationAbort.abort();
1118
+ await (0, GuidanceVerifierRunner_1.cancelGuidanceVerifications)();
1119
+ },
1120
+ };
998
1121
  };
999
1122
  exports.buildMcpServer = buildMcpServer;
1000
1123
  const guardStdout = () => {
@@ -1053,12 +1176,20 @@ const handleMcpServe = async (rest, io) => {
1053
1176
  catch (error) {
1054
1177
  return (0, envelope_1.errorResult)('mcp', 'OPERATION_FAILED', `Could not start the MCP server: ${(0, errorMessage_1.errorMessage)(error)}`);
1055
1178
  }
1056
- built.mcp.server.onclose = () => {
1057
- const shutdown = built.telemetry?.shutdown();
1058
- void Promise.resolve(shutdown)
1179
+ let isClosing = false;
1180
+ const shutdown = () => {
1181
+ if (isClosing)
1182
+ return;
1183
+ isClosing = true;
1184
+ void built
1185
+ .cancelVerifications()
1186
+ .then(() => built.telemetry?.shutdown())
1059
1187
  .catch(() => { })
1060
1188
  .finally(() => process.exit(0));
1061
1189
  };
1190
+ built.mcp.server.onclose = shutdown;
1191
+ process.once('SIGINT', shutdown);
1192
+ process.once('SIGTERM', shutdown);
1062
1193
  io.writeProgress('Rivet MCP server started on stdio (rivet mcp serve)');
1063
1194
  return new Promise(() => { });
1064
1195
  };