rivet-design 0.10.5 → 0.10.7
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.
- package/dist/mcp/agent-variants/SessionStore.d.ts +11 -0
- package/dist/mcp/agent-variants/SessionStore.d.ts.map +1 -1
- package/dist/mcp/agent-variants/SessionStore.js +44 -14
- package/dist/mcp/agent-variants/SessionStore.js.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts +44 -3
- package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.js +297 -63
- package/dist/mcp/agent-variants/WorktreeOrchestrator.js.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.d.ts +4 -0
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.d.ts.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.js +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.js.map +1 -1
- package/dist/mcp/agent-variants/contracts.d.ts +28 -0
- package/dist/mcp/agent-variants/contracts.d.ts.map +1 -1
- package/dist/mcp/agent-variants/contracts.js.map +1 -1
- package/dist/mcp/agent-variants/createZeroToOneTool.d.ts +47 -265
- package/dist/mcp/agent-variants/createZeroToOneTool.d.ts.map +1 -1
- package/dist/mcp/agent-variants/createZeroToOneTool.js +147 -207
- package/dist/mcp/agent-variants/createZeroToOneTool.js.map +1 -1
- package/dist/mcp/agent-variants/generatedDestination.d.ts +75 -0
- package/dist/mcp/agent-variants/generatedDestination.d.ts.map +1 -0
- package/dist/mcp/agent-variants/generatedDestination.js +104 -0
- package/dist/mcp/agent-variants/generatedDestination.js.map +1 -0
- package/dist/mcp/agent-variants/index.d.ts +0 -1
- package/dist/mcp/agent-variants/index.d.ts.map +1 -1
- package/dist/mcp/agent-variants/index.js +1 -3
- package/dist/mcp/agent-variants/index.js.map +1 -1
- package/dist/mcp/agent-variants/pinterestSourceContext.d.ts +18 -0
- package/dist/mcp/agent-variants/pinterestSourceContext.d.ts.map +1 -0
- package/dist/mcp/agent-variants/pinterestSourceContext.js +134 -0
- package/dist/mcp/agent-variants/pinterestSourceContext.js.map +1 -0
- package/dist/mcp/agent-variants/runPlan.d.ts +107 -0
- package/dist/mcp/agent-variants/runPlan.d.ts.map +1 -0
- package/dist/mcp/agent-variants/runPlan.js +97 -0
- package/dist/mcp/agent-variants/runPlan.js.map +1 -0
- package/dist/mcp/agent-variants/tools.d.ts +48 -3
- package/dist/mcp/agent-variants/tools.d.ts.map +1 -1
- package/dist/mcp/agent-variants/tools.js +54 -47
- package/dist/mcp/agent-variants/tools.js.map +1 -1
- package/dist/mcp/integrations/tools.d.ts +14 -0
- package/dist/mcp/integrations/tools.d.ts.map +1 -0
- package/dist/mcp/integrations/tools.js +38 -0
- package/dist/mcp/integrations/tools.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +18 -13
- package/dist/mcp/server.js.map +1 -1
- package/dist/routes/agentVariants.d.ts.map +1 -1
- package/dist/routes/agentVariants.js +5 -0
- package/dist/routes/agentVariants.js.map +1 -1
- package/dist/services/IntegrationsClient.d.ts +58 -0
- package/dist/services/IntegrationsClient.d.ts.map +1 -0
- package/dist/services/IntegrationsClient.js +81 -0
- package/dist/services/IntegrationsClient.js.map +1 -0
- package/dist/services/staticStarter.d.ts +1 -1
- package/dist/services/staticStarter.d.ts.map +1 -1
- package/dist/services/staticStarter.js +76 -19
- package/dist/services/staticStarter.js.map +1 -1
- package/dist/utils/skills/describe-motion-protocol.d.ts +1 -1
- package/dist/utils/skills/describe-motion-protocol.d.ts.map +1 -1
- package/dist/utils/skills/describe-motion-protocol.js +11 -11
- package/dist/utils/skills/shared-variants-protocol.d.ts.map +1 -1
- package/dist/utils/skills/shared-variants-protocol.js +6 -4
- package/dist/utils/skills/shared-variants-protocol.js.map +1 -1
- package/package.json +1 -1
- package/src/ui/dist/assets/main-DUIrSkV3.css +1 -0
- package/src/ui/dist/assets/main-DYpxGvCu.js +646 -0
- package/src/ui/dist/index.html +2 -2
- package/src/ui/dist/assets/main-CioUvt6B.css +0 -1
- package/src/ui/dist/assets/main-wU_rUu3_.js +0 -646
|
@@ -3,74 +3,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
6
|
+
exports.slugifyPrompt = exports.normalizeWorkspaceRoot = void 0;
|
|
7
|
+
exports.kickoffSourceGroundedZeroToOne = kickoffSourceGroundedZeroToOne;
|
|
9
8
|
const os_1 = __importDefault(require("os"));
|
|
10
9
|
const path_1 = __importDefault(require("path"));
|
|
11
10
|
const v3_1 = require("zod/v3");
|
|
12
|
-
const
|
|
11
|
+
const generatedDestination_1 = require("./generatedDestination");
|
|
12
|
+
// Re-exported for back-compat: tests and other call sites import these from
|
|
13
|
+
// here; the canonical definitions now live in `generatedDestination`.
|
|
14
|
+
var generatedDestination_2 = require("./generatedDestination");
|
|
15
|
+
Object.defineProperty(exports, "normalizeWorkspaceRoot", { enumerable: true, get: function () { return generatedDestination_2.normalizeWorkspaceRoot; } });
|
|
16
|
+
Object.defineProperty(exports, "slugifyPrompt", { enumerable: true, get: function () { return generatedDestination_2.slugifyPrompt; } });
|
|
13
17
|
const contracts_1 = require("./contracts");
|
|
14
18
|
const errors_1 = require("./errors");
|
|
15
19
|
const SessionStore_1 = require("./SessionStore");
|
|
16
20
|
const sourceContext_1 = require("./sourceContext");
|
|
21
|
+
const pinterestSourceContext_1 = require("./pinterestSourceContext");
|
|
17
22
|
const DEFAULT_VARIANT_COUNT = 3;
|
|
18
23
|
const MIN_VARIANT_COUNT = 2;
|
|
19
24
|
const MAX_VARIANT_COUNT = 8;
|
|
20
|
-
const SLUG_SUFFIX_BYTES = 2;
|
|
21
|
-
exports.createZeroToOneInput = {
|
|
22
|
-
prompt: v3_1.z.string().min(1),
|
|
23
|
-
count: v3_1.z.number().int().min(MIN_VARIANT_COUNT).max(MAX_VARIANT_COUNT).optional(),
|
|
24
|
-
destinationParent: v3_1.z.string().optional(),
|
|
25
|
-
framework: v3_1.z.enum(['vite']).optional(),
|
|
26
|
-
sourceContext: contracts_1.sourceContextInputSchema.optional(),
|
|
27
|
-
sessionId: v3_1.z.string().optional(),
|
|
28
|
-
};
|
|
29
|
-
const createZeroToOneToolInput = exports.createZeroToOneInput;
|
|
30
25
|
const proposeVariantsInputSchema = v3_1.z.object(contracts_1.proposeVariantsInput);
|
|
31
|
-
/**
|
|
32
|
-
* Slugify a prompt into a directory-safe kebab-case name with a short random
|
|
33
|
-
* suffix so concurrent calls with the same prompt don't collide.
|
|
34
|
-
*/
|
|
35
|
-
const slugifyPrompt = (prompt) => {
|
|
36
|
-
const base = prompt
|
|
37
|
-
.toLowerCase()
|
|
38
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
39
|
-
.replace(/^-+|-+$/g, '')
|
|
40
|
-
.slice(0, 40);
|
|
41
|
-
const suffix = (0, crypto_1.randomBytes)(SLUG_SUFFIX_BYTES).toString('hex');
|
|
42
|
-
return base ? `${base}-${suffix}` : `rivet-app-${suffix}`;
|
|
43
|
-
};
|
|
44
|
-
exports.slugifyPrompt = slugifyPrompt;
|
|
45
26
|
const failed = (code, message) => ({
|
|
46
27
|
stage: 'failed',
|
|
47
28
|
errorCode: code,
|
|
48
29
|
message,
|
|
49
30
|
});
|
|
50
|
-
/**
|
|
51
|
-
* Collapse a candidate workspace root back to the real workspace when it points
|
|
52
|
-
* inside a `.rivet/` tree.
|
|
53
|
-
*
|
|
54
|
-
* The editor bridge can become bound to a previously generated subproject
|
|
55
|
-
* (`<root>/.rivet/<slug>`) — e.g. after the user opens that subproject in the
|
|
56
|
-
* visual editor. Without this guard the next zero-to-one session would resolve
|
|
57
|
-
* its `destinationParent` to that subproject and join `.rivet/<slug>` onto it,
|
|
58
|
-
* producing a nested `<root>/.rivet/<slug>/.rivet/<slug2>`. That nesting breaks
|
|
59
|
-
* preview/history path resolution (everything is rooted at `workspaceRoot`), so
|
|
60
|
-
* generated variants land on disk but render blank on click.
|
|
61
|
-
*
|
|
62
|
-
* Truncating at the segment before the first `.rivet` keeps the single-`.rivet`
|
|
63
|
-
* invariant. Idempotent: a path with no `.rivet` segment is returned unchanged.
|
|
64
|
-
*/
|
|
65
|
-
const normalizeWorkspaceRoot = (candidate) => {
|
|
66
|
-
const resolved = path_1.default.resolve(candidate);
|
|
67
|
-
const segments = resolved.split(path_1.default.sep);
|
|
68
|
-
const idx = segments.indexOf('.rivet');
|
|
69
|
-
if (idx <= 0)
|
|
70
|
-
return resolved;
|
|
71
|
-
return segments.slice(0, idx).join(path_1.default.sep) || path_1.default.sep;
|
|
72
|
-
};
|
|
73
|
-
exports.normalizeWorkspaceRoot = normalizeWorkspaceRoot;
|
|
74
31
|
/**
|
|
75
32
|
* Returns true when a file-copy root is specific enough to authorize asset
|
|
76
33
|
* reads. Broad roots such as the home directory or filesystem root would let
|
|
@@ -82,162 +39,153 @@ const isSpecificAssetSourceRoot = (root, homePath) => {
|
|
|
82
39
|
resolvedRoot !== path_1.default.parse(resolvedRoot).root);
|
|
83
40
|
};
|
|
84
41
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
42
|
+
* Run the source-grounded fresh-project kickoff: validate the framework,
|
|
43
|
+
* resolve/normalize inspiration sources, derive the destination, build the
|
|
44
|
+
* `kind:'fresh'` project context (with sourceContext + assetSourceRoot), open
|
|
45
|
+
* the visual editor, and start the source-research flow via
|
|
46
|
+
* `orchestrator.propose`. Returns the multi-step `awaiting_*` stage the agent
|
|
47
|
+
* drives next. Owns its own try/catch so callers can surface the result
|
|
48
|
+
* directly. Called by `start_variants(mode='zero_to_one')` when a session is
|
|
49
|
+
* source-grounded.
|
|
89
50
|
*/
|
|
90
|
-
|
|
51
|
+
async function kickoffSourceGroundedZeroToOne(args, deps) {
|
|
91
52
|
const homedir = deps.homedir ?? os_1.default.homedir;
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
53
|
+
try {
|
|
54
|
+
const framework = args.framework ?? 'vite';
|
|
55
|
+
if (framework !== 'vite') {
|
|
56
|
+
return failed('UNSUPPORTED_FRAMEWORK', `Source-grounded zero-to-one only supports framework='vite' in v1; got '${framework}'.`);
|
|
57
|
+
}
|
|
58
|
+
const count = clampCount(args.count);
|
|
59
|
+
const inputSourceUrls = args.sourceContext?.sourceUrls ?? [];
|
|
60
|
+
const sourceUrls = (0, sourceContext_1.resolveSourceUrls)(args.prompt, args.sourceContext);
|
|
61
|
+
// Compare raw inputs in their normalized form so URLs that only differ by
|
|
62
|
+
// hash fragments or trailing punctuation aren't reported as dropped when
|
|
63
|
+
// they were in fact included.
|
|
64
|
+
const resolvedSet = new Set(sourceUrls);
|
|
65
|
+
const droppedUrls = inputSourceUrls.filter((u) => {
|
|
66
|
+
const normalized = (0, sourceContext_1.normalizeUrl)(u);
|
|
67
|
+
return normalized === null || !resolvedSet.has(normalized);
|
|
68
|
+
});
|
|
69
|
+
const warnings = droppedUrls.map((url) => `Skipped source URL '${url}' — failed validation (private network, unsupported scheme, or unreachable).`);
|
|
70
|
+
const inputSourceArtifacts = (0, sourceContext_1.normalizeSourceArtifacts)(args.sourceContext?.sourceArtifacts);
|
|
71
|
+
const projectPath = deps.getProjectPath?.() ?? undefined;
|
|
72
|
+
const cwd = deps.cwd ?? (() => process.cwd());
|
|
73
|
+
// Shared with the prompt-only path: resolve the destination parent (arg →
|
|
74
|
+
// open editor project → cwd), slugify, collapse any nested `.rivet/`, and
|
|
75
|
+
// create `<workspaceRoot>/.rivet/` so the commit-time materialize step has
|
|
76
|
+
// a directory to write into.
|
|
77
|
+
const dest = (0, generatedDestination_1.deriveGeneratedDestination)({
|
|
78
|
+
prompt: args.prompt,
|
|
79
|
+
destinationParent: args.destinationParent,
|
|
80
|
+
editorProjectPath: projectPath,
|
|
81
|
+
cwd,
|
|
82
|
+
});
|
|
83
|
+
if (!dest.ok) {
|
|
84
|
+
return failed(dest.errorCode, dest.message);
|
|
85
|
+
}
|
|
86
|
+
const { workspaceRoot, destinationPath } = dest;
|
|
87
|
+
const assetSourceRoot = projectPath && isSpecificAssetSourceRoot(projectPath, homedir())
|
|
88
|
+
? path_1.default.resolve(projectPath)
|
|
89
|
+
: undefined;
|
|
90
|
+
const pinterestSourceContext = await (0, pinterestSourceContext_1.enrichPinterestSourceContext)({
|
|
91
|
+
sourceUrls,
|
|
92
|
+
integrationsClient: deps.integrationsClient,
|
|
93
|
+
});
|
|
94
|
+
warnings.push(...pinterestSourceContext.warnings);
|
|
95
|
+
const sourceArtifacts = (0, sourceContext_1.normalizeSourceArtifacts)([
|
|
96
|
+
...inputSourceArtifacts,
|
|
97
|
+
...pinterestSourceContext.sourceArtifacts,
|
|
98
|
+
]);
|
|
99
|
+
const projectContext = {
|
|
100
|
+
kind: 'fresh',
|
|
101
|
+
workspacePath: destinationPath,
|
|
102
|
+
workspaceRoot,
|
|
103
|
+
framework: 'vite',
|
|
104
|
+
...(assetSourceRoot ? { assetSourceRoot } : {}),
|
|
105
|
+
...(sourceUrls.length > 0 ||
|
|
106
|
+
sourceArtifacts.length > 0 ||
|
|
107
|
+
args.sourceContext?.preserveBrand !== undefined
|
|
108
|
+
? {
|
|
109
|
+
sourceContext: {
|
|
110
|
+
...(sourceUrls.length > 0 ? { sourceUrls } : {}),
|
|
111
|
+
...(sourceArtifacts.length > 0 ? { sourceArtifacts } : {}),
|
|
112
|
+
...(args.sourceContext?.preserveBrand !== undefined
|
|
113
|
+
? { preserveBrand: args.sourceContext.preserveBrand }
|
|
114
|
+
: {}),
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
: {}),
|
|
118
|
+
};
|
|
119
|
+
const proposeInput = {
|
|
120
|
+
sessionId: args.sessionId,
|
|
121
|
+
prompt: args.prompt,
|
|
122
|
+
count,
|
|
123
|
+
projectContext,
|
|
124
|
+
};
|
|
125
|
+
// Validate via the shared schema before delegating, so the proxy and
|
|
126
|
+
// direct callers see the same rejection shape.
|
|
127
|
+
const parsed = proposeVariantsInputSchema.safeParse(proposeInput);
|
|
128
|
+
if (!parsed.success) {
|
|
129
|
+
return failed('SCHEMA_VALIDATION_FAILED', parsed.error.message);
|
|
130
|
+
}
|
|
131
|
+
const visualEditor = deps.ensureVisualEditorOpen
|
|
132
|
+
? await deps.ensureVisualEditorOpen({
|
|
133
|
+
projectPath: destinationPath,
|
|
144
134
|
workspaceRoot,
|
|
145
135
|
framework: 'vite',
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
};
|
|
161
|
-
// Ensure the destination's parent (`<workspaceRoot>/.rivet/`) exists
|
|
162
|
-
// so the materialize step at commit time has a directory to write
|
|
163
|
-
// into. The destination itself is created during materialize.
|
|
164
|
-
fs_1.default.mkdirSync(path_1.default.dirname(destinationPath), { recursive: true });
|
|
165
|
-
const proposeInput = {
|
|
166
|
-
sessionId: args.sessionId,
|
|
167
|
-
prompt: args.prompt,
|
|
168
|
-
count,
|
|
169
|
-
projectContext,
|
|
170
|
-
};
|
|
171
|
-
// Validate via the shared schema before delegating, so the proxy and
|
|
172
|
-
// direct callers see the same rejection shape.
|
|
173
|
-
const parsed = proposeVariantsInputSchema.safeParse(proposeInput);
|
|
174
|
-
if (!parsed.success) {
|
|
175
|
-
return jsonResponse(failed('SCHEMA_VALIDATION_FAILED', parsed.error.message));
|
|
176
|
-
}
|
|
177
|
-
const visualEditor = deps.ensureVisualEditorOpen
|
|
178
|
-
? await deps.ensureVisualEditorOpen({
|
|
179
|
-
projectPath: destinationPath,
|
|
180
|
-
workspaceRoot,
|
|
181
|
-
framework: 'vite',
|
|
182
|
-
})
|
|
183
|
-
: undefined;
|
|
184
|
-
const result = deps.orchestrator.propose(parsed.data);
|
|
185
|
-
if (sourceUrls.length > 0 || sourceArtifacts.length > 0) {
|
|
186
|
-
deps.telemetry?.trackAgentVariantsSourceContextQuality?.({
|
|
187
|
-
sessionId: result.sessionId,
|
|
188
|
-
sourceUrlCount: sourceUrls.length,
|
|
189
|
-
artifactCount: sourceArtifacts.length,
|
|
190
|
-
hasScreenshotReferences: sourceArtifacts.some((artifact) => artifact.kind === 'screenshotNotes'),
|
|
191
|
-
preserveBrand: Boolean(args.sourceContext?.preserveBrand),
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
if (result.stage === 'awaiting_source_plan') {
|
|
195
|
-
return jsonResponse({
|
|
196
|
-
sessionId: result.sessionId,
|
|
197
|
-
stage: 'awaiting_source_plan',
|
|
198
|
-
sourcePlanWorkItem: {
|
|
199
|
-
id: result.sourcePlanWorkItem.id,
|
|
200
|
-
kind: 'source_plan',
|
|
201
|
-
attempt: result.sourcePlanWorkItem.attempt,
|
|
202
|
-
input: result.sourcePlanWorkItem.input,
|
|
203
|
-
output_schema: SessionStore_1.SOURCE_PLAN_OUTPUT_SCHEMA,
|
|
204
|
-
},
|
|
205
|
-
nextAction: 'continue_variants',
|
|
206
|
-
...(visualEditor ? { visualEditor } : {}),
|
|
207
|
-
...(warnings.length > 0 ? { warnings } : {}),
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
return jsonResponse({
|
|
136
|
+
})
|
|
137
|
+
: undefined;
|
|
138
|
+
const result = deps.orchestrator.propose(parsed.data);
|
|
139
|
+
if (sourceUrls.length > 0 || sourceArtifacts.length > 0) {
|
|
140
|
+
deps.telemetry?.trackAgentVariantsSourceContextQuality?.({
|
|
141
|
+
sessionId: result.sessionId,
|
|
142
|
+
sourceUrlCount: sourceUrls.length,
|
|
143
|
+
artifactCount: sourceArtifacts.length,
|
|
144
|
+
hasScreenshotReferences: sourceArtifacts.some((artifact) => artifact.kind === 'screenshotNotes'),
|
|
145
|
+
preserveBrand: Boolean(args.sourceContext?.preserveBrand),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (result.stage === 'awaiting_source_plan') {
|
|
149
|
+
return {
|
|
211
150
|
sessionId: result.sessionId,
|
|
212
|
-
stage: '
|
|
213
|
-
|
|
214
|
-
id: result.
|
|
215
|
-
kind: '
|
|
216
|
-
attempt: result.
|
|
217
|
-
input: result.
|
|
218
|
-
output_schema:
|
|
151
|
+
stage: 'awaiting_source_plan',
|
|
152
|
+
sourcePlanWorkItem: {
|
|
153
|
+
id: result.sourcePlanWorkItem.id,
|
|
154
|
+
kind: 'source_plan',
|
|
155
|
+
attempt: result.sourcePlanWorkItem.attempt,
|
|
156
|
+
input: result.sourcePlanWorkItem.input,
|
|
157
|
+
output_schema: SessionStore_1.SOURCE_PLAN_OUTPUT_SCHEMA,
|
|
219
158
|
},
|
|
220
|
-
nextAction: '
|
|
159
|
+
nextAction: 'continue_variants',
|
|
160
|
+
destinationPath,
|
|
221
161
|
...(visualEditor ? { visualEditor } : {}),
|
|
222
162
|
...(warnings.length > 0 ? { warnings } : {}),
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
catch (err) {
|
|
226
|
-
const code = err instanceof errors_1.AgentVariantsError
|
|
227
|
-
? err.code
|
|
228
|
-
: 'SCHEMA_VALIDATION_FAILED';
|
|
229
|
-
const message = err instanceof Error
|
|
230
|
-
? err.message
|
|
231
|
-
: 'Unknown error in create_zero_to_one_project';
|
|
232
|
-
return jsonResponse({
|
|
233
|
-
stage: 'failed',
|
|
234
|
-
errorCode: code,
|
|
235
|
-
message,
|
|
236
|
-
});
|
|
163
|
+
};
|
|
237
164
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
165
|
+
return {
|
|
166
|
+
sessionId: result.sessionId,
|
|
167
|
+
stage: 'awaiting_briefs',
|
|
168
|
+
briefWorkItem: {
|
|
169
|
+
id: result.briefWorkItem.id,
|
|
170
|
+
kind: 'brief',
|
|
171
|
+
attempt: result.briefWorkItem.attempt,
|
|
172
|
+
input: result.briefWorkItem.input,
|
|
173
|
+
output_schema: { briefs: 'Array<{briefId, label, body}>' },
|
|
174
|
+
},
|
|
175
|
+
nextAction: 'report_variant_briefs',
|
|
176
|
+
destinationPath,
|
|
177
|
+
...(visualEditor ? { visualEditor } : {}),
|
|
178
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
const code = err instanceof errors_1.AgentVariantsError ? err.code : 'SCHEMA_VALIDATION_FAILED';
|
|
183
|
+
const message = err instanceof Error
|
|
184
|
+
? err.message
|
|
185
|
+
: 'Unknown error in source-grounded zero-to-one kickoff';
|
|
186
|
+
return { stage: 'failed', errorCode: code, message };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
241
189
|
const clampCount = (count) => {
|
|
242
190
|
if (count === undefined)
|
|
243
191
|
return DEFAULT_VARIANT_COUNT;
|
|
@@ -247,12 +195,4 @@ const clampCount = (count) => {
|
|
|
247
195
|
return MAX_VARIANT_COUNT;
|
|
248
196
|
return count;
|
|
249
197
|
};
|
|
250
|
-
const jsonResponse = (payload) => ({
|
|
251
|
-
content: [
|
|
252
|
-
{
|
|
253
|
-
type: 'text',
|
|
254
|
-
text: JSON.stringify(payload),
|
|
255
|
-
},
|
|
256
|
-
],
|
|
257
|
-
});
|
|
258
198
|
//# sourceMappingURL=createZeroToOneTool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZeroToOneTool.js","sourceRoot":"","sources":["../../../src/mcp/agent-variants/createZeroToOneTool.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"createZeroToOneTool.js","sourceRoot":"","sources":["../../../src/mcp/agent-variants/createZeroToOneTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared destination derivation for generated ("fresh" / zero-to-one) projects.
|
|
3
|
+
*
|
|
4
|
+
* Both kickoff paths — `start_variants(mode='zero_to_one')` and the
|
|
5
|
+
* source-grounded `create_zero_to_one_project` — turn a prompt into the same
|
|
6
|
+
* thing: a slugified subproject directory under `<workspaceRoot>/.rivet/<slug>/`.
|
|
7
|
+
* They used to derive it with two near-identical copies of the same logic,
|
|
8
|
+
* which had already drifted: the `start_variants` path skipped
|
|
9
|
+
* `normalizeWorkspaceRoot`, so a `destinationParent` that already sat inside a
|
|
10
|
+
* `.rivet/` tree produced a nested `.rivet/<slug>/.rivet/<slug2>` that breaks
|
|
11
|
+
* preview/history path resolution. Centralizing here removes the duplication
|
|
12
|
+
* and gives both paths the nesting guard.
|
|
13
|
+
*/
|
|
14
|
+
import type { ErrorCode } from './errors';
|
|
15
|
+
/**
|
|
16
|
+
* Slugify a prompt into a directory-safe kebab-case name with a short random
|
|
17
|
+
* suffix so concurrent calls with the same prompt don't collide.
|
|
18
|
+
*/
|
|
19
|
+
export declare const slugifyPrompt: (prompt: string) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Collapse a candidate workspace root back to the real workspace when it points
|
|
22
|
+
* inside a `.rivet/` tree.
|
|
23
|
+
*
|
|
24
|
+
* The editor bridge can become bound to a previously generated subproject
|
|
25
|
+
* (`<root>/.rivet/<slug>`) — e.g. after the user opens that subproject in the
|
|
26
|
+
* visual editor. Without this guard the next zero-to-one session would resolve
|
|
27
|
+
* its `destinationParent` to that subproject and join `.rivet/<slug>` onto it,
|
|
28
|
+
* producing a nested `<root>/.rivet/<slug>/.rivet/<slug2>`. That nesting breaks
|
|
29
|
+
* preview/history path resolution (everything is rooted at `workspaceRoot`), so
|
|
30
|
+
* generated variants land on disk but render blank on click.
|
|
31
|
+
*
|
|
32
|
+
* Truncating at the segment before the first `.rivet` keeps the single-`.rivet`
|
|
33
|
+
* invariant. Idempotent: a path with no `.rivet` segment is returned unchanged.
|
|
34
|
+
*/
|
|
35
|
+
export declare const normalizeWorkspaceRoot: (candidate: string) => string;
|
|
36
|
+
export interface GeneratedDestination {
|
|
37
|
+
slug: string;
|
|
38
|
+
/** The user's working dir that owns all Rivet artifacts for the session. */
|
|
39
|
+
workspaceRoot: string;
|
|
40
|
+
/** Where the generated subproject's files live:
|
|
41
|
+
* `<workspaceRoot>/.rivet/<slug>/`. */
|
|
42
|
+
destinationPath: string;
|
|
43
|
+
}
|
|
44
|
+
export interface DeriveDestinationFailure {
|
|
45
|
+
errorCode: ErrorCode;
|
|
46
|
+
message: string;
|
|
47
|
+
}
|
|
48
|
+
export type DeriveGeneratedDestinationResult = ({
|
|
49
|
+
ok: true;
|
|
50
|
+
} & GeneratedDestination) | ({
|
|
51
|
+
ok: false;
|
|
52
|
+
} & DeriveDestinationFailure);
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the destination for a generated project from a prompt.
|
|
55
|
+
*
|
|
56
|
+
* Destination-parent default chain: explicit `destinationParent` arg →
|
|
57
|
+
* currently-open editor project → MCP server cwd. cwd (not homedir) so
|
|
58
|
+
* generated projects land near where the user is actually working rather than
|
|
59
|
+
* dumped at the home root.
|
|
60
|
+
*
|
|
61
|
+
* Returns a discriminated result so each caller can format the failure in its
|
|
62
|
+
* own response shape. On `ok`, the parent of `destinationPath` has been
|
|
63
|
+
* created so the materialize step at commit time has a directory to write into.
|
|
64
|
+
*/
|
|
65
|
+
export declare function deriveGeneratedDestination(args: {
|
|
66
|
+
prompt: string;
|
|
67
|
+
destinationParent?: string;
|
|
68
|
+
editorProjectPath?: string;
|
|
69
|
+
cwd: () => string;
|
|
70
|
+
/** Override for the emptiness probe (tests). Defaults to isDestinationEmpty. */
|
|
71
|
+
destinationIsEmpty?: (destinationPath: string) => boolean;
|
|
72
|
+
/** Override for directory creation (tests). Defaults to fs.mkdirSync. */
|
|
73
|
+
mkdir?: (dir: string) => void;
|
|
74
|
+
}): DeriveGeneratedDestinationResult;
|
|
75
|
+
//# sourceMappingURL=generatedDestination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generatedDestination.d.ts","sourceRoot":"","sources":["../../../src/mcp/agent-variants/generatedDestination.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI1C;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,MAQ9C,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,GAAI,WAAW,MAAM,KAAG,MAM1D,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB;4CACwC;IACxC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,gCAAgC,GACxC,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,oBAAoB,CAAC,GACrC,CAAC;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,GAAG,wBAAwB,CAAC,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,gFAAgF;IAChF,kBAAkB,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1D,yEAAyE;IACzE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,GAAG,gCAAgC,CAiCnC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared destination derivation for generated ("fresh" / zero-to-one) projects.
|
|
4
|
+
*
|
|
5
|
+
* Both kickoff paths — `start_variants(mode='zero_to_one')` and the
|
|
6
|
+
* source-grounded `create_zero_to_one_project` — turn a prompt into the same
|
|
7
|
+
* thing: a slugified subproject directory under `<workspaceRoot>/.rivet/<slug>/`.
|
|
8
|
+
* They used to derive it with two near-identical copies of the same logic,
|
|
9
|
+
* which had already drifted: the `start_variants` path skipped
|
|
10
|
+
* `normalizeWorkspaceRoot`, so a `destinationParent` that already sat inside a
|
|
11
|
+
* `.rivet/` tree produced a nested `.rivet/<slug>/.rivet/<slug2>` that breaks
|
|
12
|
+
* preview/history path resolution. Centralizing here removes the duplication
|
|
13
|
+
* and gives both paths the nesting guard.
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.normalizeWorkspaceRoot = exports.slugifyPrompt = void 0;
|
|
20
|
+
exports.deriveGeneratedDestination = deriveGeneratedDestination;
|
|
21
|
+
const crypto_1 = require("crypto");
|
|
22
|
+
const fs_1 = __importDefault(require("fs"));
|
|
23
|
+
const path_1 = __importDefault(require("path"));
|
|
24
|
+
const viteReactTs_1 = require("../../services/templates/viteReactTs");
|
|
25
|
+
const SLUG_SUFFIX_BYTES = 2;
|
|
26
|
+
/**
|
|
27
|
+
* Slugify a prompt into a directory-safe kebab-case name with a short random
|
|
28
|
+
* suffix so concurrent calls with the same prompt don't collide.
|
|
29
|
+
*/
|
|
30
|
+
const slugifyPrompt = (prompt) => {
|
|
31
|
+
const base = prompt
|
|
32
|
+
.toLowerCase()
|
|
33
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
34
|
+
.replace(/^-+|-+$/g, '')
|
|
35
|
+
.slice(0, 40);
|
|
36
|
+
const suffix = (0, crypto_1.randomBytes)(SLUG_SUFFIX_BYTES).toString('hex');
|
|
37
|
+
return base ? `${base}-${suffix}` : `rivet-app-${suffix}`;
|
|
38
|
+
};
|
|
39
|
+
exports.slugifyPrompt = slugifyPrompt;
|
|
40
|
+
/**
|
|
41
|
+
* Collapse a candidate workspace root back to the real workspace when it points
|
|
42
|
+
* inside a `.rivet/` tree.
|
|
43
|
+
*
|
|
44
|
+
* The editor bridge can become bound to a previously generated subproject
|
|
45
|
+
* (`<root>/.rivet/<slug>`) — e.g. after the user opens that subproject in the
|
|
46
|
+
* visual editor. Without this guard the next zero-to-one session would resolve
|
|
47
|
+
* its `destinationParent` to that subproject and join `.rivet/<slug>` onto it,
|
|
48
|
+
* producing a nested `<root>/.rivet/<slug>/.rivet/<slug2>`. That nesting breaks
|
|
49
|
+
* preview/history path resolution (everything is rooted at `workspaceRoot`), so
|
|
50
|
+
* generated variants land on disk but render blank on click.
|
|
51
|
+
*
|
|
52
|
+
* Truncating at the segment before the first `.rivet` keeps the single-`.rivet`
|
|
53
|
+
* invariant. Idempotent: a path with no `.rivet` segment is returned unchanged.
|
|
54
|
+
*/
|
|
55
|
+
const normalizeWorkspaceRoot = (candidate) => {
|
|
56
|
+
const resolved = path_1.default.resolve(candidate);
|
|
57
|
+
const segments = resolved.split(path_1.default.sep);
|
|
58
|
+
const idx = segments.indexOf('.rivet');
|
|
59
|
+
if (idx <= 0)
|
|
60
|
+
return resolved;
|
|
61
|
+
return segments.slice(0, idx).join(path_1.default.sep) || path_1.default.sep;
|
|
62
|
+
};
|
|
63
|
+
exports.normalizeWorkspaceRoot = normalizeWorkspaceRoot;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the destination for a generated project from a prompt.
|
|
66
|
+
*
|
|
67
|
+
* Destination-parent default chain: explicit `destinationParent` arg →
|
|
68
|
+
* currently-open editor project → MCP server cwd. cwd (not homedir) so
|
|
69
|
+
* generated projects land near where the user is actually working rather than
|
|
70
|
+
* dumped at the home root.
|
|
71
|
+
*
|
|
72
|
+
* Returns a discriminated result so each caller can format the failure in its
|
|
73
|
+
* own response shape. On `ok`, the parent of `destinationPath` has been
|
|
74
|
+
* created so the materialize step at commit time has a directory to write into.
|
|
75
|
+
*/
|
|
76
|
+
function deriveGeneratedDestination(args) {
|
|
77
|
+
const destinationParent = args.destinationParent ?? args.editorProjectPath ?? args.cwd();
|
|
78
|
+
if (!path_1.default.isAbsolute(destinationParent)) {
|
|
79
|
+
return {
|
|
80
|
+
ok: false,
|
|
81
|
+
errorCode: 'SCHEMA_VALIDATION_FAILED',
|
|
82
|
+
message: `destinationParent must be absolute; got '${destinationParent}'.`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const slug = (0, exports.slugifyPrompt)(args.prompt);
|
|
86
|
+
// Subprojects nest under `<workspaceRoot>/.rivet/<slug>/` so every Rivet
|
|
87
|
+
// artifact (generated app files, variant history, manifests) lives in one
|
|
88
|
+
// hidden directory — the user's working dir stays clean. Normalize first so
|
|
89
|
+
// we never nest one `.rivet/` inside another.
|
|
90
|
+
const workspaceRoot = (0, exports.normalizeWorkspaceRoot)(destinationParent);
|
|
91
|
+
const destinationPath = path_1.default.join(workspaceRoot, '.rivet', slug);
|
|
92
|
+
const isEmpty = args.destinationIsEmpty ?? viteReactTs_1.isDestinationEmpty;
|
|
93
|
+
if (!isEmpty(destinationPath)) {
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
errorCode: 'DESTINATION_NOT_EMPTY',
|
|
97
|
+
message: `Destination '${destinationPath}' is not empty.`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const mkdir = args.mkdir ?? ((dir) => fs_1.default.mkdirSync(dir, { recursive: true }));
|
|
101
|
+
mkdir(path_1.default.dirname(destinationPath));
|
|
102
|
+
return { ok: true, slug, workspaceRoot, destinationPath };
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=generatedDestination.js.map
|