rivet-design 0.9.3 → 0.9.5
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 +26 -10
- package/dist/mcp/agent-variants/SessionStore.d.ts.map +1 -1
- package/dist/mcp/agent-variants/SessionStore.js +189 -44
- package/dist/mcp/agent-variants/SessionStore.js.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts +209 -13
- package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.js +1489 -61
- package/dist/mcp/agent-variants/WorktreeOrchestrator.js.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.d.ts +65 -0
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.d.ts.map +1 -0
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.js +162 -0
- package/dist/mcp/agent-variants/WorktreeOrchestrator.testHelpers.js.map +1 -0
- package/dist/mcp/agent-variants/contracts.d.ts +1576 -64
- package/dist/mcp/agent-variants/contracts.d.ts.map +1 -1
- package/dist/mcp/agent-variants/contracts.js +202 -9
- package/dist/mcp/agent-variants/contracts.js.map +1 -1
- package/dist/mcp/agent-variants/createProjectArtifacts.d.ts +78 -0
- package/dist/mcp/agent-variants/createProjectArtifacts.d.ts.map +1 -0
- package/dist/mcp/agent-variants/createProjectArtifacts.js +123 -0
- package/dist/mcp/agent-variants/createProjectArtifacts.js.map +1 -0
- package/dist/mcp/agent-variants/createZeroToOneTool.d.ts +67 -25
- package/dist/mcp/agent-variants/createZeroToOneTool.d.ts.map +1 -1
- package/dist/mcp/agent-variants/createZeroToOneTool.js +60 -126
- package/dist/mcp/agent-variants/createZeroToOneTool.js.map +1 -1
- package/dist/mcp/agent-variants/errors.d.ts +1 -1
- package/dist/mcp/agent-variants/errors.d.ts.map +1 -1
- package/dist/mcp/agent-variants/errors.js +1 -0
- package/dist/mcp/agent-variants/errors.js.map +1 -1
- package/dist/mcp/agent-variants/index.d.ts +3 -4
- package/dist/mcp/agent-variants/index.d.ts.map +1 -1
- package/dist/mcp/agent-variants/index.js +2 -2
- package/dist/mcp/agent-variants/index.js.map +1 -1
- package/dist/mcp/agent-variants/inspirationDesignContext.d.ts +10 -0
- package/dist/mcp/agent-variants/inspirationDesignContext.d.ts.map +1 -1
- package/dist/mcp/agent-variants/inspirationDesignContext.js +104 -16
- package/dist/mcp/agent-variants/inspirationDesignContext.js.map +1 -1
- package/dist/mcp/agent-variants/pendingChangesAdapter.d.ts.map +1 -1
- package/dist/mcp/agent-variants/pendingChangesAdapter.js +11 -0
- package/dist/mcp/agent-variants/pendingChangesAdapter.js.map +1 -1
- package/dist/mcp/agent-variants/previewQa.d.ts +61 -0
- package/dist/mcp/agent-variants/previewQa.d.ts.map +1 -0
- package/dist/mcp/agent-variants/previewQa.js +374 -0
- package/dist/mcp/agent-variants/previewQa.js.map +1 -0
- package/dist/mcp/agent-variants/sourceContext.d.ts +1 -0
- package/dist/mcp/agent-variants/sourceContext.d.ts.map +1 -1
- package/dist/mcp/agent-variants/sourceContext.js +28 -3
- package/dist/mcp/agent-variants/sourceContext.js.map +1 -1
- package/dist/mcp/agent-variants/tools.d.ts +40 -3
- package/dist/mcp/agent-variants/tools.d.ts.map +1 -1
- package/dist/mcp/agent-variants/tools.js +262 -38
- package/dist/mcp/agent-variants/tools.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +32 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/prompts/agentModPrompts.d.ts.map +1 -1
- package/dist/prompts/agentModPrompts.js +11 -10
- package/dist/prompts/agentModPrompts.js.map +1 -1
- package/dist/proxy-middleware/proxy-config.d.ts +2 -2
- package/dist/proxy-middleware/proxy-config.d.ts.map +1 -1
- package/dist/proxy-middleware/proxy-config.js +66 -22
- package/dist/proxy-middleware/proxy-config.js.map +1 -1
- package/dist/routes/agentVariants.d.ts +2 -13
- package/dist/routes/agentVariants.d.ts.map +1 -1
- package/dist/routes/agentVariants.js +156 -2
- package/dist/routes/agentVariants.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +79 -4
- package/dist/server.js.map +1 -1
- package/dist/services/ProjectDetectionService.d.ts.map +1 -1
- package/dist/services/ProjectDetectionService.js +21 -0
- package/dist/services/ProjectDetectionService.js.map +1 -1
- package/dist/services/VariantHistoryService.d.ts +117 -0
- package/dist/services/VariantHistoryService.d.ts.map +1 -0
- package/dist/services/VariantHistoryService.js +385 -0
- package/dist/services/VariantHistoryService.js.map +1 -0
- package/dist/services/WorktreeManager.d.ts +67 -9
- package/dist/services/WorktreeManager.d.ts.map +1 -1
- package/dist/services/WorktreeManager.js +209 -26
- package/dist/services/WorktreeManager.js.map +1 -1
- package/dist/services/agent/AgentCore.d.ts +1 -1
- package/dist/services/agent/AgentCore.d.ts.map +1 -1
- package/dist/services/agent/AgentCore.js +24 -1
- package/dist/services/agent/AgentCore.js.map +1 -1
- package/dist/services/agent/AgentModService.d.ts +1 -1
- package/dist/services/agent/AgentModService.js +7 -7
- package/dist/services/agent/AgentModService.js.map +1 -1
- package/dist/services/templates/viteReactTs.d.ts +6 -0
- package/dist/services/templates/viteReactTs.d.ts.map +1 -1
- package/dist/services/templates/viteReactTs.js +8 -1
- package/dist/services/templates/viteReactTs.js.map +1 -1
- package/dist/types/change-request-types.d.ts +14 -0
- package/dist/types/change-request-types.d.ts.map +1 -1
- package/dist/utils/skills/claude-skill.d.ts +1 -1
- package/dist/utils/skills/claude-skill.js +2 -2
- package/dist/utils/skills/cursor-rules.d.ts +1 -1
- package/dist/utils/skills/cursor-rules.js +1 -1
- package/dist/utils/skills/shared-variants-protocol.d.ts +1 -1
- package/dist/utils/skills/shared-variants-protocol.d.ts.map +1 -1
- package/dist/utils/skills/shared-variants-protocol.js +31 -32
- package/dist/utils/skills/shared-variants-protocol.js.map +1 -1
- package/package.json +4 -5
- package/src/ui/dist/assets/main-OdmwI8Od.css +1 -0
- package/src/ui/dist/assets/{main-DejhsBWR.js → main-SuZlKEi0.js} +115 -115
- package/src/ui/dist/index.html +2 -2
- package/src/ui/dist/assets/main-C9jfEp80.css +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export type VariantHistoryStatus = 'completed' | 'committed' | 'rejected' | 'cancelled';
|
|
2
|
+
export type VariantHistoryKind = 'diff' | 'project-created';
|
|
3
|
+
/** Where the persisted DESIGN.md came from. Slug entries point at a curated
|
|
4
|
+
* catalog inspiration; markdown entries carry user-supplied / Agent Browser
|
|
5
|
+
* extracted content. `label` is always human-readable for the history UI. */
|
|
6
|
+
export interface VariantDesignSource {
|
|
7
|
+
kind: 'slug' | 'markdown';
|
|
8
|
+
label: string;
|
|
9
|
+
/** Catalog slug — present only when `kind === 'slug'`. */
|
|
10
|
+
slug?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface VariantHistoryManifest {
|
|
13
|
+
schemaVersion: number;
|
|
14
|
+
variantId: string;
|
|
15
|
+
sessionId: string;
|
|
16
|
+
label: string;
|
|
17
|
+
brief: string;
|
|
18
|
+
sessionPrompt: string;
|
|
19
|
+
kind: VariantHistoryKind;
|
|
20
|
+
status: VariantHistoryStatus;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
statusChangedAt: string;
|
|
23
|
+
baseSha?: string;
|
|
24
|
+
destinationPath?: string;
|
|
25
|
+
changedFilesCount: number;
|
|
26
|
+
designSource?: VariantDesignSource;
|
|
27
|
+
}
|
|
28
|
+
export interface VariantHistorySessionFile {
|
|
29
|
+
schemaVersion: number;
|
|
30
|
+
sessionId: string;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
sessionPrompt: string;
|
|
33
|
+
projectKind: 'existing' | 'fresh';
|
|
34
|
+
}
|
|
35
|
+
export interface PersistVariantArgs {
|
|
36
|
+
projectPath: string;
|
|
37
|
+
sessionId: string;
|
|
38
|
+
variantId: string;
|
|
39
|
+
label: string;
|
|
40
|
+
brief: string;
|
|
41
|
+
sessionPrompt: string;
|
|
42
|
+
kind: VariantHistoryKind;
|
|
43
|
+
/** Required when kind === 'diff'. */
|
|
44
|
+
diff?: string;
|
|
45
|
+
/** Required when kind === 'project-created'. Directory whose contents are copied into `files/`. */
|
|
46
|
+
sourceDir?: string;
|
|
47
|
+
baseSha?: string;
|
|
48
|
+
destinationPath?: string;
|
|
49
|
+
changedFilesCount: number;
|
|
50
|
+
/** Defaults to 'completed'. Use 'committed' / 'rejected' when persisting at commit time. */
|
|
51
|
+
initialStatus?: VariantHistoryStatus;
|
|
52
|
+
projectKind: 'existing' | 'fresh';
|
|
53
|
+
/** Generated DESIGN.md body to persist as a top-level artifact alongside
|
|
54
|
+
* the diff/files. Currently only populated for fresh-project variants —
|
|
55
|
+
* existing-project variants don't generate a DESIGN.md. */
|
|
56
|
+
designMarkdown?: string;
|
|
57
|
+
designSource?: VariantDesignSource;
|
|
58
|
+
}
|
|
59
|
+
export interface ListVariantsArgs {
|
|
60
|
+
projectPath: string;
|
|
61
|
+
limit?: number;
|
|
62
|
+
status?: VariantHistoryStatus;
|
|
63
|
+
}
|
|
64
|
+
export interface VariantHistoryEntry {
|
|
65
|
+
manifest: VariantHistoryManifest;
|
|
66
|
+
/** Absolute path to the variant's directory under `.rivet/variants/<sessionId>/<variantId>/`. */
|
|
67
|
+
variantDir: string;
|
|
68
|
+
/** True when `files/index.html` exists on disk — i.e. the variant can be
|
|
69
|
+
* rendered as a static preview in an iframe. Vite_app variants and diff
|
|
70
|
+
* variants are false. Computed at list/get time so the UI can filter
|
|
71
|
+
* click-to-preview affordances without poking the disk itself. */
|
|
72
|
+
hasStaticPreview: boolean;
|
|
73
|
+
}
|
|
74
|
+
export interface VariantHistoryDetail extends VariantHistoryEntry {
|
|
75
|
+
/** Diff body — present for `kind: 'diff'` variants. */
|
|
76
|
+
diff?: string;
|
|
77
|
+
/** Project-relative file list under `files/` — present for `kind: 'project-created'` variants. */
|
|
78
|
+
files?: string[];
|
|
79
|
+
/** Generated DESIGN.md body — present when the variant was scaffolded with
|
|
80
|
+
* a design context (fresh-project variants only). */
|
|
81
|
+
designMarkdown?: string;
|
|
82
|
+
}
|
|
83
|
+
export declare class VariantHistoryService {
|
|
84
|
+
variantsRoot(projectPath: string): string;
|
|
85
|
+
sessionDir(projectPath: string, sessionId: string): string;
|
|
86
|
+
variantDir(projectPath: string, sessionId: string, variantId: string): string;
|
|
87
|
+
persistVariant(args: PersistVariantArgs): Promise<void>;
|
|
88
|
+
markStatus(args: {
|
|
89
|
+
projectPath: string;
|
|
90
|
+
sessionId: string;
|
|
91
|
+
variantId: string;
|
|
92
|
+
status: VariantHistoryStatus;
|
|
93
|
+
/** Optional manifest patch applied alongside the status flip. Used at
|
|
94
|
+
* commit time so the chosen fresh-project variant records the path
|
|
95
|
+
* the materialized project landed at. */
|
|
96
|
+
destinationPath?: string;
|
|
97
|
+
}): Promise<void>;
|
|
98
|
+
listVariants(args: ListVariantsArgs): Promise<VariantHistoryEntry[]>;
|
|
99
|
+
getVariant(args: {
|
|
100
|
+
projectPath: string;
|
|
101
|
+
sessionId: string;
|
|
102
|
+
variantId: string;
|
|
103
|
+
}): Promise<VariantHistoryDetail | null>;
|
|
104
|
+
/**
|
|
105
|
+
* Read the persisted static-preview HTML for a variant. Returns null when
|
|
106
|
+
* the variant isn't on disk or doesn't have a `files/index.html`. Used by
|
|
107
|
+
* the REST history-static endpoint that backs the AgentVariantsPanel
|
|
108
|
+
* iframe when a past variant is clicked.
|
|
109
|
+
*/
|
|
110
|
+
readStaticPreview(args: {
|
|
111
|
+
projectPath: string;
|
|
112
|
+
sessionId: string;
|
|
113
|
+
variantId: string;
|
|
114
|
+
}): Promise<string | null>;
|
|
115
|
+
ensureGitignore(projectPath: string): Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=VariantHistoryService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariantHistoryService.d.ts","sourceRoot":"","sources":["../../src/services/VariantHistoryService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.VariantHistoryService = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const logger_1 = require("../utils/logger");
|
|
11
|
+
const log = (0, logger_1.createLogger)('VariantHistoryService');
|
|
12
|
+
const HISTORY_SCHEMA_VERSION = 1;
|
|
13
|
+
const RIVET_DIRNAME = '.rivet';
|
|
14
|
+
const VARIANTS_DIRNAME = 'variants';
|
|
15
|
+
const SESSION_FILENAME = 'session.json';
|
|
16
|
+
const MANIFEST_FILENAME = 'manifest.json';
|
|
17
|
+
const DIFF_FILENAME = 'diff.patch';
|
|
18
|
+
const FILES_DIRNAME = 'files';
|
|
19
|
+
const DESIGN_FILENAME = 'DESIGN.md';
|
|
20
|
+
const STATIC_INDEX_FILENAME = 'index.html';
|
|
21
|
+
const GITIGNORE_FILENAME = '.gitignore';
|
|
22
|
+
const GITIGNORE_LINE = '.rivet/';
|
|
23
|
+
const COPY_EXCLUDE = new Set([
|
|
24
|
+
'node_modules',
|
|
25
|
+
'.git',
|
|
26
|
+
'.vite',
|
|
27
|
+
'.rivet',
|
|
28
|
+
'dist',
|
|
29
|
+
'build',
|
|
30
|
+
'.next',
|
|
31
|
+
'.cache',
|
|
32
|
+
]);
|
|
33
|
+
/** Statuses that are end-states from the user's perspective — once a variant
|
|
34
|
+
* reaches one of these, history must not silently regress it (e.g. a late
|
|
35
|
+
* `persistVariant` from the success path shouldn't reset a `committed`
|
|
36
|
+
* manifest to `completed`, and `markPersistedVariantsCancelled` shouldn't
|
|
37
|
+
* overwrite the chosen variant's `committed` status with `cancelled`). */
|
|
38
|
+
const TERMINAL_STATUSES = new Set([
|
|
39
|
+
'committed',
|
|
40
|
+
'rejected',
|
|
41
|
+
]);
|
|
42
|
+
/** Reject ids containing path separators, `..`, or NUL bytes so caller-
|
|
43
|
+
* controlled REST/MCP input can't escape `<project>/.rivet/variants/`. ids
|
|
44
|
+
* are produced by `crypto.randomUUID()` and stored slugs, both of which fit
|
|
45
|
+
* this character class. */
|
|
46
|
+
const SAFE_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
47
|
+
const assertSafeId = (value, name) => {
|
|
48
|
+
if (!SAFE_ID_PATTERN.test(value)) {
|
|
49
|
+
throw new Error(`VariantHistoryService: invalid ${name} '${value}' — must match ${SAFE_ID_PATTERN}`);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
class VariantHistoryService {
|
|
53
|
+
variantsRoot(projectPath) {
|
|
54
|
+
return path_1.default.join(projectPath, RIVET_DIRNAME, VARIANTS_DIRNAME);
|
|
55
|
+
}
|
|
56
|
+
sessionDir(projectPath, sessionId) {
|
|
57
|
+
return path_1.default.join(this.variantsRoot(projectPath), sessionId);
|
|
58
|
+
}
|
|
59
|
+
variantDir(projectPath, sessionId, variantId) {
|
|
60
|
+
return path_1.default.join(this.sessionDir(projectPath, sessionId), variantId);
|
|
61
|
+
}
|
|
62
|
+
async persistVariant(args) {
|
|
63
|
+
assertSafeId(args.sessionId, 'sessionId');
|
|
64
|
+
assertSafeId(args.variantId, 'variantId');
|
|
65
|
+
if (args.kind === 'diff' && args.diff === undefined) {
|
|
66
|
+
throw new Error(`persistVariant: kind='diff' requires a diff body (sessionId=${args.sessionId} variantId=${args.variantId})`);
|
|
67
|
+
}
|
|
68
|
+
if (args.kind === 'project-created' && !args.sourceDir) {
|
|
69
|
+
throw new Error(`persistVariant: kind='project-created' requires sourceDir (sessionId=${args.sessionId} variantId=${args.variantId})`);
|
|
70
|
+
}
|
|
71
|
+
const sessionDir = this.sessionDir(args.projectPath, args.sessionId);
|
|
72
|
+
const variantDir = this.variantDir(args.projectPath, args.sessionId, args.variantId);
|
|
73
|
+
await promises_1.default.mkdir(variantDir, { recursive: true });
|
|
74
|
+
// Race guard: persistVariant runs at code_gen success and again on retries
|
|
75
|
+
// / late callbacks. If the manifest has already reached a terminal status
|
|
76
|
+
// via markStatus (committed/rejected), preserve that status so the late
|
|
77
|
+
// persist doesn't silently reset the user's pick to `completed`.
|
|
78
|
+
const existingManifestPath = path_1.default.join(variantDir, MANIFEST_FILENAME);
|
|
79
|
+
let preservedStatus;
|
|
80
|
+
let preservedStatusChangedAt;
|
|
81
|
+
let preservedDestinationPath;
|
|
82
|
+
try {
|
|
83
|
+
const raw = await promises_1.default.readFile(existingManifestPath, 'utf8');
|
|
84
|
+
const prior = JSON.parse(raw);
|
|
85
|
+
if (TERMINAL_STATUSES.has(prior.status)) {
|
|
86
|
+
preservedStatus = prior.status;
|
|
87
|
+
preservedStatusChangedAt = prior.statusChangedAt;
|
|
88
|
+
preservedDestinationPath = prior.destinationPath;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
const code = err.code;
|
|
93
|
+
if (code !== 'ENOENT') {
|
|
94
|
+
log.warn(`persistVariant: prior manifest read failed at ${existingManifestPath}`, err);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const sessionPath = path_1.default.join(sessionDir, SESSION_FILENAME);
|
|
98
|
+
if (!fs_1.default.existsSync(sessionPath)) {
|
|
99
|
+
const sessionFile = {
|
|
100
|
+
schemaVersion: HISTORY_SCHEMA_VERSION,
|
|
101
|
+
sessionId: args.sessionId,
|
|
102
|
+
createdAt: new Date().toISOString(),
|
|
103
|
+
sessionPrompt: args.sessionPrompt,
|
|
104
|
+
projectKind: args.projectKind,
|
|
105
|
+
};
|
|
106
|
+
await promises_1.default.writeFile(sessionPath, `${JSON.stringify(sessionFile, null, 2)}\n`, 'utf8');
|
|
107
|
+
}
|
|
108
|
+
const now = new Date().toISOString();
|
|
109
|
+
const manifest = {
|
|
110
|
+
schemaVersion: HISTORY_SCHEMA_VERSION,
|
|
111
|
+
variantId: args.variantId,
|
|
112
|
+
sessionId: args.sessionId,
|
|
113
|
+
label: args.label,
|
|
114
|
+
brief: args.brief,
|
|
115
|
+
sessionPrompt: args.sessionPrompt,
|
|
116
|
+
kind: args.kind,
|
|
117
|
+
status: preservedStatus ?? args.initialStatus ?? 'completed',
|
|
118
|
+
createdAt: now,
|
|
119
|
+
statusChangedAt: preservedStatusChangedAt ?? now,
|
|
120
|
+
baseSha: args.baseSha,
|
|
121
|
+
destinationPath: preservedDestinationPath ?? args.destinationPath,
|
|
122
|
+
changedFilesCount: args.changedFilesCount,
|
|
123
|
+
designSource: args.designSource,
|
|
124
|
+
};
|
|
125
|
+
await promises_1.default.writeFile(path_1.default.join(variantDir, MANIFEST_FILENAME), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
126
|
+
if (args.kind === 'diff') {
|
|
127
|
+
await promises_1.default.writeFile(path_1.default.join(variantDir, DIFF_FILENAME), args.diff ?? '', 'utf8');
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
const filesDir = path_1.default.join(variantDir, FILES_DIRNAME);
|
|
131
|
+
await promises_1.default.rm(filesDir, { recursive: true, force: true });
|
|
132
|
+
await copyDirFiltered(args.sourceDir, filesDir);
|
|
133
|
+
}
|
|
134
|
+
if (args.designMarkdown !== undefined) {
|
|
135
|
+
await promises_1.default.writeFile(path_1.default.join(variantDir, DESIGN_FILENAME), args.designMarkdown, 'utf8');
|
|
136
|
+
}
|
|
137
|
+
await this.ensureGitignore(args.projectPath);
|
|
138
|
+
log.info(`Persisted variant ${args.variantId} (session ${args.sessionId}, kind ${args.kind}, status ${manifest.status})`);
|
|
139
|
+
}
|
|
140
|
+
async markStatus(args) {
|
|
141
|
+
assertSafeId(args.sessionId, 'sessionId');
|
|
142
|
+
assertSafeId(args.variantId, 'variantId');
|
|
143
|
+
const manifestPath = path_1.default.join(this.variantDir(args.projectPath, args.sessionId, args.variantId), MANIFEST_FILENAME);
|
|
144
|
+
let manifest;
|
|
145
|
+
try {
|
|
146
|
+
const raw = await promises_1.default.readFile(manifestPath, 'utf8');
|
|
147
|
+
manifest = JSON.parse(raw);
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
// ENOENT is the expected "variant was never persisted" case — any
|
|
151
|
+
// caller that drives the state machine via stubs skips the persistence
|
|
152
|
+
// hook. Only surface unexpected errors (permission denied, corrupt JSON).
|
|
153
|
+
const code = err.code;
|
|
154
|
+
if (code !== 'ENOENT') {
|
|
155
|
+
log.warn(`markStatus: manifest read failed at ${manifestPath} (session ${args.sessionId} variant ${args.variantId})`, err);
|
|
156
|
+
}
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Refuse to downgrade a terminal status. Specifically blocks
|
|
160
|
+
// markPersistedVariantsCancelled from rewriting a committed/rejected
|
|
161
|
+
// variant as `cancelled` when the session tears down post-commit, and
|
|
162
|
+
// prevents stray late-cancels from clobbering a finalized pick.
|
|
163
|
+
if (TERMINAL_STATUSES.has(manifest.status) &&
|
|
164
|
+
manifest.status !== args.status) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const destinationChanged = args.destinationPath !== undefined &&
|
|
168
|
+
manifest.destinationPath !== args.destinationPath;
|
|
169
|
+
if (manifest.status === args.status && !destinationChanged)
|
|
170
|
+
return;
|
|
171
|
+
manifest.status = args.status;
|
|
172
|
+
manifest.statusChangedAt = new Date().toISOString();
|
|
173
|
+
if (args.destinationPath !== undefined) {
|
|
174
|
+
manifest.destinationPath = args.destinationPath;
|
|
175
|
+
}
|
|
176
|
+
await promises_1.default.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
177
|
+
}
|
|
178
|
+
async listVariants(args) {
|
|
179
|
+
const root = this.variantsRoot(args.projectPath);
|
|
180
|
+
if (!fs_1.default.existsSync(root))
|
|
181
|
+
return [];
|
|
182
|
+
let sessionIds;
|
|
183
|
+
try {
|
|
184
|
+
sessionIds = await promises_1.default.readdir(root);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
log.warn(`listVariants: failed to read ${root}`, err);
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
const entries = [];
|
|
191
|
+
for (const sessionId of sessionIds) {
|
|
192
|
+
const sessionDir = path_1.default.join(root, sessionId);
|
|
193
|
+
const stat = await safeStat(sessionDir);
|
|
194
|
+
if (!stat?.isDirectory())
|
|
195
|
+
continue;
|
|
196
|
+
let variantIds;
|
|
197
|
+
try {
|
|
198
|
+
variantIds = await promises_1.default.readdir(sessionDir);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
for (const variantId of variantIds) {
|
|
204
|
+
const variantDir = path_1.default.join(sessionDir, variantId);
|
|
205
|
+
const vStat = await safeStat(variantDir);
|
|
206
|
+
if (!vStat?.isDirectory())
|
|
207
|
+
continue;
|
|
208
|
+
const manifest = await readManifest(path_1.default.join(variantDir, MANIFEST_FILENAME));
|
|
209
|
+
if (!manifest)
|
|
210
|
+
continue;
|
|
211
|
+
if (args.status && manifest.status !== args.status)
|
|
212
|
+
continue;
|
|
213
|
+
const hasStaticPreview = await fileExists(path_1.default.join(variantDir, FILES_DIRNAME, STATIC_INDEX_FILENAME));
|
|
214
|
+
entries.push({ manifest, variantDir, hasStaticPreview });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
entries.sort((a, b) => b.manifest.createdAt.localeCompare(a.manifest.createdAt));
|
|
218
|
+
if (args.limit !== undefined && args.limit > 0) {
|
|
219
|
+
return entries.slice(0, args.limit);
|
|
220
|
+
}
|
|
221
|
+
return entries;
|
|
222
|
+
}
|
|
223
|
+
async getVariant(args) {
|
|
224
|
+
assertSafeId(args.sessionId, 'sessionId');
|
|
225
|
+
assertSafeId(args.variantId, 'variantId');
|
|
226
|
+
const variantDir = this.variantDir(args.projectPath, args.sessionId, args.variantId);
|
|
227
|
+
const manifest = await readManifest(path_1.default.join(variantDir, MANIFEST_FILENAME));
|
|
228
|
+
if (!manifest)
|
|
229
|
+
return null;
|
|
230
|
+
const hasStaticPreview = await fileExists(path_1.default.join(variantDir, FILES_DIRNAME, STATIC_INDEX_FILENAME));
|
|
231
|
+
const detail = {
|
|
232
|
+
manifest,
|
|
233
|
+
variantDir,
|
|
234
|
+
hasStaticPreview,
|
|
235
|
+
};
|
|
236
|
+
if (manifest.kind === 'diff') {
|
|
237
|
+
try {
|
|
238
|
+
detail.diff = await promises_1.default.readFile(path_1.default.join(variantDir, DIFF_FILENAME), 'utf8');
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
detail.diff = '';
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
detail.files = await listFilesRecursive(path_1.default.join(variantDir, FILES_DIRNAME));
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
detail.designMarkdown = await promises_1.default.readFile(path_1.default.join(variantDir, DESIGN_FILENAME), 'utf8');
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
const code = err.code;
|
|
252
|
+
if (code !== 'ENOENT') {
|
|
253
|
+
log.warn(`getVariant: DESIGN.md read failed at ${variantDir}`, err);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return detail;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Read the persisted static-preview HTML for a variant. Returns null when
|
|
260
|
+
* the variant isn't on disk or doesn't have a `files/index.html`. Used by
|
|
261
|
+
* the REST history-static endpoint that backs the AgentVariantsPanel
|
|
262
|
+
* iframe when a past variant is clicked.
|
|
263
|
+
*/
|
|
264
|
+
async readStaticPreview(args) {
|
|
265
|
+
assertSafeId(args.sessionId, 'sessionId');
|
|
266
|
+
assertSafeId(args.variantId, 'variantId');
|
|
267
|
+
const indexPath = path_1.default.join(this.variantDir(args.projectPath, args.sessionId, args.variantId), FILES_DIRNAME, STATIC_INDEX_FILENAME);
|
|
268
|
+
try {
|
|
269
|
+
return await promises_1.default.readFile(indexPath, 'utf8');
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
const code = err.code;
|
|
273
|
+
if (code !== 'ENOENT') {
|
|
274
|
+
log.warn(`readStaticPreview: failed at ${indexPath}`, err);
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
async ensureGitignore(projectPath) {
|
|
280
|
+
const gitignorePath = path_1.default.join(projectPath, GITIGNORE_FILENAME);
|
|
281
|
+
let current = '';
|
|
282
|
+
try {
|
|
283
|
+
current = await promises_1.default.readFile(gitignorePath, 'utf8');
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
const code = err.code;
|
|
287
|
+
if (code !== 'ENOENT') {
|
|
288
|
+
log.warn(`ensureGitignore: read ${gitignorePath} failed`, err);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Any line that, on its own, already excludes the whole `.rivet/` tree.
|
|
293
|
+
// Narrower patterns like `.rivet/variants/` (what older Rivet versions
|
|
294
|
+
// wrote) do NOT count — we want `.rivet/<slug>/` snapshots, manifests, and
|
|
295
|
+
// history all covered by a single broad rule, so we append the broader
|
|
296
|
+
// pattern alongside.
|
|
297
|
+
const lines = current.split(/\r?\n/);
|
|
298
|
+
const alreadyCoversAll = lines.some((line) => {
|
|
299
|
+
const trimmed = line.trim();
|
|
300
|
+
return (trimmed === '.rivet' ||
|
|
301
|
+
trimmed === '.rivet/' ||
|
|
302
|
+
trimmed === '/.rivet' ||
|
|
303
|
+
trimmed === '/.rivet/' ||
|
|
304
|
+
trimmed === '**/.rivet' ||
|
|
305
|
+
trimmed === '**/.rivet/');
|
|
306
|
+
});
|
|
307
|
+
if (alreadyCoversAll)
|
|
308
|
+
return;
|
|
309
|
+
const needsNewline = current.length > 0 && !current.endsWith('\n');
|
|
310
|
+
const appended = `${current}${needsNewline ? '\n' : ''}${GITIGNORE_LINE}\n`;
|
|
311
|
+
await promises_1.default.writeFile(gitignorePath, appended, 'utf8');
|
|
312
|
+
log.info(`Appended ${GITIGNORE_LINE} to ${gitignorePath}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.VariantHistoryService = VariantHistoryService;
|
|
316
|
+
async function readManifest(manifestPath) {
|
|
317
|
+
try {
|
|
318
|
+
const raw = await promises_1.default.readFile(manifestPath, 'utf8');
|
|
319
|
+
const parsed = JSON.parse(raw);
|
|
320
|
+
if (typeof parsed.variantId !== 'string')
|
|
321
|
+
return null;
|
|
322
|
+
return parsed;
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
async function safeStat(p) {
|
|
329
|
+
try {
|
|
330
|
+
return await promises_1.default.stat(p);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function fileExists(p) {
|
|
337
|
+
try {
|
|
338
|
+
const s = await promises_1.default.stat(p);
|
|
339
|
+
return s.isFile();
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async function copyDirFiltered(src, dest) {
|
|
346
|
+
await promises_1.default.mkdir(dest, { recursive: true });
|
|
347
|
+
const entries = await promises_1.default.readdir(src, { withFileTypes: true });
|
|
348
|
+
for (const entry of entries) {
|
|
349
|
+
if (COPY_EXCLUDE.has(entry.name))
|
|
350
|
+
continue;
|
|
351
|
+
const from = path_1.default.join(src, entry.name);
|
|
352
|
+
const to = path_1.default.join(dest, entry.name);
|
|
353
|
+
if (entry.isDirectory()) {
|
|
354
|
+
await copyDirFiltered(from, to);
|
|
355
|
+
}
|
|
356
|
+
else if (entry.isFile()) {
|
|
357
|
+
await promises_1.default.copyFile(from, to);
|
|
358
|
+
}
|
|
359
|
+
// Symlinks are deliberately dropped. Source dirs are agent-controlled
|
|
360
|
+
// (variant worktrees) and `readStaticPreview` later serves whatever
|
|
361
|
+
// `files/index.html` points at through the history static route —
|
|
362
|
+
// preserving a symlink to e.g. ~/.ssh/id_rsa would turn that route into
|
|
363
|
+
// a host-file read primitive.
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
async function listFilesRecursive(root) {
|
|
367
|
+
if (!fs_1.default.existsSync(root))
|
|
368
|
+
return [];
|
|
369
|
+
const out = [];
|
|
370
|
+
const walk = async (dir, prefix) => {
|
|
371
|
+
const entries = await promises_1.default.readdir(dir, { withFileTypes: true });
|
|
372
|
+
for (const entry of entries) {
|
|
373
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
374
|
+
if (entry.isDirectory()) {
|
|
375
|
+
await walk(path_1.default.join(dir, entry.name), rel);
|
|
376
|
+
}
|
|
377
|
+
else if (entry.isFile()) {
|
|
378
|
+
out.push(rel);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
await walk(root, '');
|
|
383
|
+
return out.sort();
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=VariantHistoryService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariantHistoryService.js","sourceRoot":"","sources":["../../src/services/VariantHistoryService.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { type ChildProcess } from 'child_process';
|
|
|
2
2
|
import { type TemplateBundle } from './templates/viteReactTs';
|
|
3
3
|
import type { DesignContextEntry } from '../mcp/agent-variants/contracts';
|
|
4
4
|
import type { SourceContextInput } from '../mcp/agent-variants/contracts';
|
|
5
|
+
export declare const FRESH_WORKTREES_DIRNAME = ".rivet-variants";
|
|
5
6
|
export declare const INSTANCE_PREFIX: string;
|
|
6
7
|
export declare class WorktreeManager {
|
|
7
8
|
private readonly resolveProjectPath;
|
|
@@ -69,6 +70,13 @@ export declare class WorktreeManager {
|
|
|
69
70
|
* which would wipe the user's pre-existing work.
|
|
70
71
|
*/
|
|
71
72
|
applyDiff(diff: string, reverse: boolean): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Apply a unified diff to an arbitrary project path. Same engine as
|
|
75
|
+
* `applyDiff` but the cwd is a parameter, so callers (e.g. the variants
|
|
76
|
+
* orchestrator) can target the user's project regardless of which path this
|
|
77
|
+
* manager instance was constructed with.
|
|
78
|
+
*/
|
|
79
|
+
applyDiffToProject(diff: string, projectPath: string): Promise<void>;
|
|
72
80
|
/** Bind port 0 to get an OS-assigned free port */
|
|
73
81
|
getFreePort(): Promise<number>;
|
|
74
82
|
/** Validate a diff via `git apply --check` without modifying files */
|
|
@@ -85,22 +93,34 @@ export declare class WorktreeManager {
|
|
|
85
93
|
* For existing-project sessions, asks git to unregister the worktree
|
|
86
94
|
* (handles `.git/worktrees/*` cleanup) and falls back to plain rm. For
|
|
87
95
|
* fresh-project sessions (no projectPath) the worktrees are detached
|
|
88
|
-
* directories with their own `.git`
|
|
89
|
-
* and we just rm the matching
|
|
96
|
+
* directories with their own `.git` under `<destinationParent>/.rivet-variants/`
|
|
97
|
+
* — git registry cleanup is a no-op and we just rm the matching dirs.
|
|
98
|
+
*
|
|
99
|
+
* `freshDestinationParent` is required when the session was fresh; pass
|
|
100
|
+
* `path.dirname(projectContext.workspacePath)` so we know which
|
|
101
|
+
* `.rivet-variants/` root to sweep.
|
|
90
102
|
*/
|
|
91
|
-
cleanupSession(sessionId: string): Promise<void>;
|
|
103
|
+
cleanupSession(sessionId: string, freshDestinationParent?: string): Promise<void>;
|
|
92
104
|
/**
|
|
93
105
|
* Create N worktrees for a fresh-project session by writing a template
|
|
94
|
-
* bundle into each
|
|
95
|
-
* optionally writing a DESIGN.md per slot, and committing a
|
|
106
|
+
* bundle into each `<destinationParent>/.rivet-variants/rivet-variants-pid<PID>-<sessionId>-<i>`
|
|
107
|
+
* directory, optionally writing a DESIGN.md per slot, and committing a
|
|
108
|
+
* baseline.
|
|
109
|
+
*
|
|
110
|
+
* Worktrees live under the user's destinationParent (not /tmp) so commit
|
|
111
|
+
* time can be a same-volume rename instead of a cross-volume copy. The
|
|
112
|
+
* destinationParent is registered to a small JSON file so a future MCP
|
|
113
|
+
* startup can sweep orphans even when the original process crashed.
|
|
96
114
|
*
|
|
97
115
|
* Does NOT run `npm install` — the orchestrator dispatches that as a
|
|
98
116
|
* background task so failures surface via work-item state without blocking
|
|
99
117
|
* the MCP tool response.
|
|
100
118
|
*
|
|
101
|
-
* @effect Creates
|
|
119
|
+
* @effect Creates directories under destinationParent, writes template
|
|
120
|
+
* files, runs git init/add/commit, appends destinationParent to
|
|
121
|
+
* the fresh-worktree-roots registry.
|
|
102
122
|
*/
|
|
103
|
-
createFreshWorktrees(sessionId: string, count: number, template: TemplateBundle, designContext
|
|
123
|
+
createFreshWorktrees(sessionId: string, count: number, template: TemplateBundle, designContext: ReadonlyArray<DesignContextEntry | undefined> | undefined, sourceContext: SourceContextInput | undefined, destinationParent: string): Promise<string[]>;
|
|
104
124
|
/**
|
|
105
125
|
* Write SOURCE_CONTEXT.md when source context exists for the session.
|
|
106
126
|
*
|
|
@@ -113,13 +133,51 @@ export declare class WorktreeManager {
|
|
|
113
133
|
* @effect Writes DESIGN.md when a design context is available.
|
|
114
134
|
*/
|
|
115
135
|
private writeDesignContext;
|
|
136
|
+
/**
|
|
137
|
+
* Move a worktree to its history location preserving contents. Used by the
|
|
138
|
+
* orchestrator at commit time so unchosen variants survive on disk as
|
|
139
|
+
* runnable references (siblings of the chosen project).
|
|
140
|
+
*
|
|
141
|
+
* Returns the destination path (`<historyDir>/<folderName>`).
|
|
142
|
+
*
|
|
143
|
+
* @effect renames `srcWorktreePath` → `<historyDir>/<folderName>`, creating
|
|
144
|
+
* the historyDir if needed.
|
|
145
|
+
*/
|
|
146
|
+
moveWorktreeToHistory(srcWorktreePath: string, historyDir: string, folderName: string): string;
|
|
147
|
+
/**
|
|
148
|
+
* Repoint a worktree's `node_modules` at a relative symlink so it tracks
|
|
149
|
+
* the chosen variant's real install after both have moved into their new
|
|
150
|
+
* permanent homes. Idempotent — removes any existing entry first.
|
|
151
|
+
*/
|
|
152
|
+
repointNodeModulesSymlink(worktreePath: string, sharedNodeModulesAbsPath: string): void;
|
|
116
153
|
/** Remove all fresh worktrees for a session.
|
|
117
154
|
*
|
|
118
|
-
* @effect Removes
|
|
155
|
+
* @effect Removes directories under <destinationParent>/.rivet-variants/
|
|
156
|
+
* matching ${INSTANCE_PREFIX}-<sessionId>-*. Also removes the
|
|
157
|
+
* .rivet-variants/ parent if it becomes empty so the editor file
|
|
158
|
+
* tree doesn't accumulate noise.
|
|
159
|
+
*
|
|
160
|
+
* When `preserve` is provided, entries whose basenames are in the set are
|
|
161
|
+
* skipped — used by the orchestrator after a vite_app commit, where the
|
|
162
|
+
* unchosen variant worktrees have already been moved to a sibling history
|
|
163
|
+
* dir and must not be re-deleted.
|
|
119
164
|
*/
|
|
120
|
-
cleanupFreshWorktrees(sessionId: string): void;
|
|
165
|
+
cleanupFreshWorktrees(sessionId: string, destinationParent: string, preserve?: ReadonlySet<string>): void;
|
|
121
166
|
private assertSafeSessionId;
|
|
122
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Append a freshRoot path to the registry (de-duped). Called by
|
|
170
|
+
* createFreshWorktrees so future MCP startups can sweep orphans even if
|
|
171
|
+
* the original process crashed before teardown ran.
|
|
172
|
+
*/
|
|
173
|
+
export declare const registerFreshWorktreeRoot: (freshRoot: string) => void;
|
|
174
|
+
/**
|
|
175
|
+
* Sweep orphan worktrees from /tmp (existing-project flow) and from every
|
|
176
|
+
* registered fresh-worktree root (fresh-project flow). Filters by
|
|
177
|
+
* INSTANCE_PREFIX (includes PID) so each server instance only removes its
|
|
178
|
+
* own worktrees and never touches those of sibling instances. Prunes
|
|
179
|
+
* registry entries whose directory no longer exists so the file stays small.
|
|
180
|
+
*/
|
|
123
181
|
export declare const cleanupOrphanedWorktrees: () => void;
|
|
124
182
|
/**
|
|
125
183
|
* Prune stale worktree registry entries for a project (`.git/worktrees/<name>`
|