rivet-design 0.28.1 → 0.28.3
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/cli/commands/libraryOpen.js +1 -0
- package/dist/cli/commands/mcpServe.js +5 -1
- package/dist/cli/commands/open.js +17 -6
- package/dist/cli/commands/profile.js +8 -1
- package/dist/cli/commands/profileDisconnect.d.ts +3 -0
- package/dist/cli/commands/profileDisconnect.js +34 -0
- package/dist/cli/commands/serve.js +2 -0
- package/dist/cli/commands/shared.js +4 -1
- package/dist/cli/envelope.d.ts +1 -0
- package/dist/cli/router.js +8 -2
- package/dist/jest.globalSetup.d.ts +3 -0
- package/dist/jest.globalSetup.js +19 -0
- package/dist/library/browserLaunch.d.ts +2 -1
- package/dist/library/browserLaunch.js +3 -2
- package/dist/proxy-middleware/proxy-config.d.ts +0 -1
- package/dist/proxy-middleware/proxy-config.js +6 -34
- package/dist/routes/agentVariants.js +20 -173
- package/dist/routes/referenceProfiles.js +3 -3
- package/dist/routes/static.js +8 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +15 -26
- package/dist/services/AuthService.js +7 -61
- package/dist/services/IntegrationsClient.d.ts +2 -1
- package/dist/services/IntegrationsClient.js +46 -20
- package/dist/services/TelemetryService.d.ts +16 -2
- package/dist/services/TelemetryService.js +18 -0
- package/dist/services/accessTokenRefresh.js +2 -2
- package/dist/services/profiles/DesignProfiles.d.ts +16 -0
- package/dist/services/profiles/DesignProfiles.js +78 -17
- package/dist/services/profiles/ProfileAnalysis.d.ts +3 -0
- package/dist/services/profiles/ProfileAnalysis.js +66 -1
- package/dist/services/profiles/ProfileImports.d.ts +2 -0
- package/dist/services/profiles/ProfileImports.js +2 -0
- package/dist/services/templates/viteReactTs.js +1 -1
- package/dist/storage/profiles/ProfileRecords.d.ts +17 -0
- package/dist/storage/profiles/ProfileRecords.js +45 -7
- package/dist/storage/profiles/migrations.d.ts +2 -2
- package/dist/storage/profiles/migrations.js +7 -0
- package/dist/storage/profiles/schema.d.ts +48 -0
- package/dist/storage/profiles/schema.js +3 -0
- package/dist/types/api-responses.d.ts +39 -0
- package/dist/types/api-responses.js +12 -1
- package/dist/types/design-profile.d.ts +12 -0
- package/dist/types/design-profile.js +10 -1
- package/dist/types/rivet-page-types.d.ts +48 -0
- package/dist/types/rivet-page-types.js +6 -0
- package/dist/utils/failureReason.js +1 -1
- package/dist/utils/hostedLogPrivacy.js +1 -1
- package/dist/utils/launchRuntime.d.ts +2 -0
- package/dist/utils/launchRuntime.js +12 -0
- package/dist/utils/rivetPage.d.ts +8 -0
- package/dist/utils/rivetPage.js +24 -0
- package/dist/utils/rivetPage.testHelpers.d.ts +6 -0
- package/dist/utils/rivetPage.testHelpers.js +18 -0
- package/dist/utils/rivetPageDocument.d.ts +7 -0
- package/dist/utils/rivetPageDocument.js +41 -0
- package/dist/utils/scriptJson.d.ts +2 -0
- package/dist/utils/scriptJson.js +9 -0
- package/dist/utils/skills/cli-guidance.d.ts +1 -1
- package/dist/utils/skills/cli-guidance.js +2 -1
- package/dist/utils/uiDistPath.d.ts +2 -0
- package/dist/utils/uiDistPath.js +22 -0
- package/package.json +8 -5
- package/src/ui/dist/assets/LibraryEntry-CSU5OJwC.js +2 -0
- package/src/ui/dist/assets/google-g-CpxN0HWb.png +0 -0
- package/src/ui/dist/assets/main-B89lcZEY.css +1 -0
- package/src/ui/dist/assets/main-DeCxjHC1.js +204 -0
- package/src/ui/dist/index.html +3 -3
- package/src/ui/dist/pages/empty-project.html +53 -0
- package/src/ui/dist/pages/rivet-page.html +53 -0
- package/dist/routes/emptyStatePage.d.ts +0 -2
- package/dist/routes/emptyStatePage.js +0 -589
- package/src/ui/dist/assets/LibraryEntry-DS6Ce0sW.js +0 -112
- package/src/ui/dist/assets/logo-animation/clasp.png +0 -0
- package/src/ui/dist/assets/logo-animation/eraser.png +0 -0
- package/src/ui/dist/assets/logo-animation/playdough.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/bubblephone.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/cart.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/chair.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/desk.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/mug.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/pitcher.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/pot.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/startac.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/terracotta-1.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/terracotta-2.png +0 -0
- package/src/ui/dist/assets/logo-animation/sea/vhsplant.png +0 -0
- package/src/ui/dist/assets/main-CQSk-6km.css +0 -1
- package/src/ui/dist/assets/main-DkKRuatC.js +0 -218
package/dist/server.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ import type { VariantRunService } from './services/VariantRunService';
|
|
|
7
7
|
import type { VariantsRuntime } from './services/VariantsRuntime';
|
|
8
8
|
export declare const INACTIVE_VARIANTS_EVENT_HEARTBEAT_MS = 30000;
|
|
9
9
|
export declare const RIVET_CORS_ALLOWED_HEADERS: string[];
|
|
10
|
-
export declare const DIST_UI_PATH: string;
|
|
11
10
|
type RivetUiBootstrap = {
|
|
12
11
|
agentApplyMode: 'embedded' | 'external' | null;
|
|
13
12
|
queueAccessToken: string | null;
|
|
@@ -58,6 +57,7 @@ export type ServerOptions = Omit<CLIOptions, 'help' | 'version' | 'debug'> & {
|
|
|
58
57
|
userHost?: string;
|
|
59
58
|
beforeShutdown?: () => Promise<void>;
|
|
60
59
|
resolveLibraryOrigin?: () => string | undefined;
|
|
60
|
+
resolveProjectName?: (projectPath: string) => string | undefined;
|
|
61
61
|
createLibraryViewUrl?: (view: 'projects' | 'references') => Promise<string | null>;
|
|
62
62
|
};
|
|
63
63
|
export type ServerHandle = {
|
package/dist/server.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.startServer = exports.runServerShutdownTasks = exports.isRivetCorsOriginAllowed = exports.isRivetUiStaticAssetPath = exports.isEmbeddedAgentUiHost = exports.resolveEmbeddedAgentUiOrigin = exports.resolveRivetListenHost = exports.sendInactiveVariantsEventStream = exports.readRivetUiIndexHtml = exports.injectRivetUiBootstrap = exports.
|
|
39
|
+
exports.startServer = exports.runServerShutdownTasks = exports.isRivetCorsOriginAllowed = exports.isRivetUiStaticAssetPath = exports.isEmbeddedAgentUiHost = exports.resolveEmbeddedAgentUiOrigin = exports.resolveRivetListenHost = exports.sendInactiveVariantsEventStream = exports.readRivetUiIndexHtml = exports.injectRivetUiBootstrap = exports.RIVET_CORS_ALLOWED_HEADERS = exports.INACTIVE_VARIANTS_EVENT_HEARTBEAT_MS = void 0;
|
|
40
40
|
const editorSession_1 = require("./cli/editorSession");
|
|
41
41
|
const editorAccess_1 = require("./routes/editorAccess");
|
|
42
42
|
const editorAccess_2 = require("./utils/editorAccess");
|
|
@@ -77,6 +77,8 @@ const VariantHistoryService_1 = require("./services/VariantHistoryService");
|
|
|
77
77
|
const RequestAuthContext_1 = require("./services/RequestAuthContext");
|
|
78
78
|
const middleware_1 = require("./routes/library/middleware");
|
|
79
79
|
const errorMessage_1 = require("./utils/errorMessage");
|
|
80
|
+
const scriptJson_1 = require("./utils/scriptJson");
|
|
81
|
+
const uiDistPath_1 = require("./utils/uiDistPath");
|
|
80
82
|
const pluginContext_1 = require("./hosts/pluginContext");
|
|
81
83
|
const log = (0, index_core_1.createLogger)('RivetServer');
|
|
82
84
|
const QUEUE_ACCESS_TOKEN_BYTES = 32;
|
|
@@ -93,36 +95,21 @@ exports.RIVET_CORS_ALLOWED_HEADERS = [
|
|
|
93
95
|
'x-rivet-queue-token',
|
|
94
96
|
editorAccess_2.EDITOR_ACCESS_TOKEN_HEADER,
|
|
95
97
|
];
|
|
96
|
-
const resolveUiPath = () => {
|
|
97
|
-
const bundledPath = path_1.default.join(__dirname, 'ui/dist');
|
|
98
|
-
const devPath = path_1.default.join(__dirname, '../src/ui/dist');
|
|
99
|
-
if (fs_1.default.existsSync(bundledPath)) {
|
|
100
|
-
log.debug(`Using bundled UI path: ${bundledPath}`);
|
|
101
|
-
return bundledPath;
|
|
102
|
-
}
|
|
103
|
-
log.debug(`Using development UI path: ${devPath}`);
|
|
104
|
-
return devPath;
|
|
105
|
-
};
|
|
106
|
-
exports.DIST_UI_PATH = resolveUiPath();
|
|
107
98
|
const NO_USER_DEV_SERVER_PORT = 0;
|
|
108
99
|
const setNoStoreHeaders = (res) => {
|
|
109
100
|
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
|
110
101
|
res.setHeader('Pragma', 'no-cache');
|
|
111
102
|
res.setHeader('Expires', '0');
|
|
112
103
|
};
|
|
113
|
-
const escapeScriptJson = (value) => JSON.stringify(value)
|
|
114
|
-
.replace(/</g, '\\u003c')
|
|
115
|
-
.replace(/\u2028/g, '\\u2028')
|
|
116
|
-
.replace(/\u2029/g, '\\u2029');
|
|
117
104
|
const injectRivetUiBootstrap = (html, bootstrap) => {
|
|
118
|
-
const script = `<script id="${RIVET_BOOTSTRAP_SCRIPT_ID}">window.__RIVET_BOOTSTRAP__=${escapeScriptJson(bootstrap)};</script>`;
|
|
105
|
+
const script = `<script id="${RIVET_BOOTSTRAP_SCRIPT_ID}">window.__RIVET_BOOTSTRAP__=${(0, scriptJson_1.escapeScriptJson)(bootstrap)};</script>`;
|
|
119
106
|
if (html.includes('</head>')) {
|
|
120
107
|
return html.replace('</head>', `${script}</head>`);
|
|
121
108
|
}
|
|
122
109
|
return `${script}${html}`;
|
|
123
110
|
};
|
|
124
111
|
exports.injectRivetUiBootstrap = injectRivetUiBootstrap;
|
|
125
|
-
const readRivetUiIndexHtml = () => fs_1.default.readFileSync(path_1.default.join(
|
|
112
|
+
const readRivetUiIndexHtml = () => fs_1.default.readFileSync(path_1.default.join(uiDistPath_1.DIST_UI_PATH, RIVET_UI_INDEX_FILENAME), 'utf8');
|
|
126
113
|
exports.readRivetUiIndexHtml = readRivetUiIndexHtml;
|
|
127
114
|
const sendInactiveVariantsEventStream = (req, res) => {
|
|
128
115
|
res.set({
|
|
@@ -366,15 +353,15 @@ const startServer = async (options) => {
|
|
|
366
353
|
const serve = express_1.default.static(directory, uiStaticOptions);
|
|
367
354
|
return (req, res, next) => isPreviewRequest(req) ? next() : serve(req, res, next);
|
|
368
355
|
};
|
|
369
|
-
app.use('/assets', serveEditorAssets(path_1.default.join(
|
|
370
|
-
app.use('/rivet/assets', serveEditorAssets(path_1.default.join(
|
|
371
|
-
app.use('/fonts', serveEditorAssets(path_1.default.join(
|
|
372
|
-
app.use('/rivet/fonts', serveEditorAssets(path_1.default.join(
|
|
356
|
+
app.use('/assets', serveEditorAssets(path_1.default.join(uiDistPath_1.DIST_UI_PATH, 'assets')));
|
|
357
|
+
app.use('/rivet/assets', serveEditorAssets(path_1.default.join(uiDistPath_1.DIST_UI_PATH, 'assets')));
|
|
358
|
+
app.use('/fonts', serveEditorAssets(path_1.default.join(uiDistPath_1.DIST_UI_PATH, 'fonts')));
|
|
359
|
+
app.use('/rivet/fonts', serveEditorAssets(path_1.default.join(uiDistPath_1.DIST_UI_PATH, 'fonts')));
|
|
373
360
|
app.get('/favicon.ico', (_req, res) => {
|
|
374
|
-
res.sendFile('favicon.ico', { root:
|
|
361
|
+
res.sendFile('favicon.ico', { root: uiDistPath_1.DIST_UI_PATH });
|
|
375
362
|
});
|
|
376
363
|
app.get('/rivet/favicon.ico', (_req, res) => {
|
|
377
|
-
res.sendFile('favicon.ico', { root:
|
|
364
|
+
res.sendFile('favicon.ico', { root: uiDistPath_1.DIST_UI_PATH });
|
|
378
365
|
});
|
|
379
366
|
app.get(/^\/rivet\/library(?:\/.*)?$/, (req, res) => {
|
|
380
367
|
const resolvedLibraryOrigin = options.resolveLibraryOrigin?.();
|
|
@@ -391,7 +378,7 @@ const startServer = async (options) => {
|
|
|
391
378
|
}
|
|
392
379
|
sendRivetUiIndex(req, res);
|
|
393
380
|
});
|
|
394
|
-
log.info(`Serving UI assets from: ${
|
|
381
|
+
log.info(`Serving UI assets from: ${uiDistPath_1.DIST_UI_PATH}`);
|
|
395
382
|
if (framework === 'static' && !hasUserDevServer) {
|
|
396
383
|
app.get('/', (req, res, next) => {
|
|
397
384
|
if (isPreviewRequest(req)) {
|
|
@@ -500,17 +487,19 @@ const startServer = async (options) => {
|
|
|
500
487
|
app.get('/api/config', async (_req, res) => {
|
|
501
488
|
const configManager = (0, ConfigManager_1.getConfigManager)();
|
|
502
489
|
const livePath = sessionBridge?.getProjectPath() ?? projectPath;
|
|
490
|
+
const initiator = sessionBridge?.getSessionRuntimeInfo().sessionInitiator;
|
|
503
491
|
res.json({
|
|
504
492
|
agentModeAvailable: configManager.isAuthenticated(),
|
|
505
493
|
email: configManager.getEmail(),
|
|
506
494
|
userId: configManager.getUserId(),
|
|
507
495
|
name: configManager.getDisplayName(),
|
|
508
496
|
isMCPSession: sessionBridge?.isActive() ?? false,
|
|
509
|
-
mcpEditor: mcpEditor ?? null,
|
|
497
|
+
mcpEditor: mcpEditor ?? (initiator?.kind === 'agent' ? initiator.agent : null),
|
|
510
498
|
agentApplyMode: sessionBridge?.isActive()
|
|
511
499
|
? (agentApplyMode ?? 'external')
|
|
512
500
|
: null,
|
|
513
501
|
projectPath: livePath,
|
|
502
|
+
projectName: options.resolveProjectName?.(livePath) ?? path_1.default.basename(livePath),
|
|
514
503
|
projectId: options.projectId ?? null,
|
|
515
504
|
libraryOrigin: options.resolveLibraryOrigin?.() ?? null,
|
|
516
505
|
});
|
|
@@ -36,6 +36,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.AuthService = exports.validateAccessToken = void 0;
|
|
37
37
|
const zod_1 = require("zod");
|
|
38
38
|
const logger_1 = require("../utils/logger");
|
|
39
|
+
const rivetPage_1 = require("../utils/rivetPage");
|
|
40
|
+
const rivet_page_types_1 = require("../types/rivet-page-types");
|
|
39
41
|
const ConfigManager_1 = require("./ConfigManager");
|
|
40
42
|
const http_1 = require("http");
|
|
41
43
|
const accessTokenRefresh_1 = require("./accessTokenRefresh");
|
|
@@ -46,7 +48,6 @@ const proxy_1 = require("../config/proxy");
|
|
|
46
48
|
const log = (0, logger_1.createLogger)('AuthService');
|
|
47
49
|
const LOOPBACK_HOST = '127.0.0.1';
|
|
48
50
|
const LOOPBACK_PORT = 0;
|
|
49
|
-
const CALLBACK_COMPLETE_PATH = '/complete';
|
|
50
51
|
const OAUTH_CALLBACK_TIMEOUT_MS = 120_000;
|
|
51
52
|
const MAX_CALLBACK_BODY_BYTES = 64 * 1024;
|
|
52
53
|
const PROFILE_FETCH_TIMEOUT_MS = 10_000;
|
|
@@ -101,64 +102,6 @@ const readRequestBody = (request) => {
|
|
|
101
102
|
request.on('error', reject);
|
|
102
103
|
});
|
|
103
104
|
};
|
|
104
|
-
const getLoopbackCallbackHtml = () => {
|
|
105
|
-
return `<!doctype html>
|
|
106
|
-
<html>
|
|
107
|
-
<head>
|
|
108
|
-
<meta charset="utf-8" />
|
|
109
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
110
|
-
<title>Rivet authentication</title>
|
|
111
|
-
<style>
|
|
112
|
-
body {
|
|
113
|
-
margin: 0;
|
|
114
|
-
min-height: 100vh;
|
|
115
|
-
display: grid;
|
|
116
|
-
place-items: center;
|
|
117
|
-
font-family: system-ui, sans-serif;
|
|
118
|
-
background: #0b0b0f;
|
|
119
|
-
color: #fff;
|
|
120
|
-
}
|
|
121
|
-
main {
|
|
122
|
-
max-width: 420px;
|
|
123
|
-
padding: 32px;
|
|
124
|
-
text-align: center;
|
|
125
|
-
}
|
|
126
|
-
</style>
|
|
127
|
-
</head>
|
|
128
|
-
<body>
|
|
129
|
-
<main>
|
|
130
|
-
<h1>Finishing Rivet sign in...</h1>
|
|
131
|
-
<p>You can return to your editor after this page completes.</p>
|
|
132
|
-
</main>
|
|
133
|
-
<script>
|
|
134
|
-
const params = new URLSearchParams(window.location.search);
|
|
135
|
-
const hash = new URLSearchParams(window.location.hash.slice(1));
|
|
136
|
-
if (window.location.hash) {
|
|
137
|
-
window.history.replaceState(
|
|
138
|
-
null,
|
|
139
|
-
document.title,
|
|
140
|
-
window.location.pathname + window.location.search
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
fetch('/complete', {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
headers: { 'Content-Type': 'application/json' },
|
|
146
|
-
body: JSON.stringify({
|
|
147
|
-
sessionId: params.get('session'),
|
|
148
|
-
accessToken: hash.get('access_token'),
|
|
149
|
-
refreshToken: hash.get('refresh_token')
|
|
150
|
-
})
|
|
151
|
-
}).then((response) => {
|
|
152
|
-
document.querySelector('h1').textContent = response.ok
|
|
153
|
-
? 'Rivet sign in complete'
|
|
154
|
-
: 'Rivet sign in failed';
|
|
155
|
-
}).catch(() => {
|
|
156
|
-
document.querySelector('h1').textContent = 'Rivet sign in failed';
|
|
157
|
-
});
|
|
158
|
-
</script>
|
|
159
|
-
</body>
|
|
160
|
-
</html>`;
|
|
161
|
-
};
|
|
162
105
|
const validateAccessToken = async (proxyUrl, accessToken) => {
|
|
163
106
|
const response = await fetch(`${proxyUrl.replace(/\/$/, '')}/api/user/profile`, {
|
|
164
107
|
method: 'GET',
|
|
@@ -204,11 +147,14 @@ const createLoopbackOAuthCallback = async () => {
|
|
|
204
147
|
const server = (0, http_1.createServer)((request, response) => {
|
|
205
148
|
const url = new URL(request.url ?? '/', `http://${LOOPBACK_HOST}`);
|
|
206
149
|
if (request.method === 'GET') {
|
|
207
|
-
sendTextResponse(response, 200,
|
|
150
|
+
sendTextResponse(response, 200, (0, rivetPage_1.renderRivetPage)({
|
|
151
|
+
page: { kind: 'sign-in-callback' },
|
|
152
|
+
head: { title: 'Rivet authentication' },
|
|
153
|
+
}));
|
|
208
154
|
return;
|
|
209
155
|
}
|
|
210
156
|
if (request.method !== 'POST' ||
|
|
211
|
-
url.pathname !==
|
|
157
|
+
url.pathname !== rivet_page_types_1.SIGN_IN_CALLBACK_COMPLETE_PATH) {
|
|
212
158
|
sendTextResponse(response, 404, 'Not found');
|
|
213
159
|
return;
|
|
214
160
|
}
|
|
@@ -114,6 +114,7 @@ export type IntegrationDisconnectResult = {
|
|
|
114
114
|
status: 'ok';
|
|
115
115
|
} | {
|
|
116
116
|
status: 'error';
|
|
117
|
+
reason: 'auth_required' | 'account_changed' | 'request_failed';
|
|
117
118
|
message: string;
|
|
118
119
|
};
|
|
119
120
|
export type IntegrationProvider = 'pinterest' | 'arena' | 'x';
|
|
@@ -213,6 +214,6 @@ export declare class IntegrationsClient {
|
|
|
213
214
|
}): Promise<XBookmarksResult>;
|
|
214
215
|
listIntegrations(): Promise<IntegrationListResult>;
|
|
215
216
|
connect(provider: IntegrationProvider): Promise<IntegrationConnectResult>;
|
|
216
|
-
disconnect(provider: IntegrationProvider): Promise<IntegrationDisconnectResult>;
|
|
217
|
+
disconnect(provider: IntegrationProvider, expectedAccountId?: string): Promise<IntegrationDisconnectResult>;
|
|
217
218
|
}
|
|
218
219
|
//# sourceMappingURL=IntegrationsClient.d.ts.map
|
|
@@ -17,6 +17,7 @@ const RequestAuthContext_1 = require("./RequestAuthContext");
|
|
|
17
17
|
const errorMessage_1 = require("../utils/errorMessage");
|
|
18
18
|
const log = (0, logger_1.createLogger)('IntegrationsClient');
|
|
19
19
|
const REQUEST_TIMEOUT_MS = 30_000;
|
|
20
|
+
const ACCOUNT_CHANGED_MESSAGE = 'Rivet account changed. Retry with the intended account.';
|
|
20
21
|
const NormalizedPinSchema = zod_1.z.object({
|
|
21
22
|
id: zod_1.z.string(),
|
|
22
23
|
image_urls: zod_1.z.array(zod_1.z.string()),
|
|
@@ -132,6 +133,8 @@ const IntegrationConnectBodySchema = zod_1.z.object({
|
|
|
132
133
|
message: zod_1.z.string().optional(),
|
|
133
134
|
error: zod_1.z.string().optional(),
|
|
134
135
|
});
|
|
136
|
+
const IntegrationDisconnectBodySchema = zod_1.z.object({ success: zod_1.z.literal(true) });
|
|
137
|
+
const XDisconnectBodySchema = zod_1.z.object({ status: zod_1.z.literal('ok') });
|
|
135
138
|
const INTEGRATION_PROVIDERS = [
|
|
136
139
|
'pinterest',
|
|
137
140
|
'arena',
|
|
@@ -160,7 +163,7 @@ class IntegrationsClient {
|
|
|
160
163
|
}
|
|
161
164
|
return token;
|
|
162
165
|
}
|
|
163
|
-
async requestWithBearer(request) {
|
|
166
|
+
async requestWithBearer(request, expectedAccountId) {
|
|
164
167
|
const token = await this.getBearerToken();
|
|
165
168
|
if (!token) {
|
|
166
169
|
return null;
|
|
@@ -182,6 +185,9 @@ class IntegrationsClient {
|
|
|
182
185
|
if (!refreshed) {
|
|
183
186
|
return response;
|
|
184
187
|
}
|
|
188
|
+
if (expectedAccountId !== undefined &&
|
|
189
|
+
this.configManager.getUserId() !== expectedAccountId)
|
|
190
|
+
throw new Error(ACCOUNT_CHANGED_MESSAGE);
|
|
185
191
|
updateAuth(refreshed);
|
|
186
192
|
return request(refreshed.token);
|
|
187
193
|
}
|
|
@@ -492,31 +498,51 @@ class IntegrationsClient {
|
|
|
492
498
|
};
|
|
493
499
|
}
|
|
494
500
|
}
|
|
495
|
-
async disconnect(provider) {
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
501
|
+
async disconnect(provider, expectedAccountId) {
|
|
502
|
+
const isAccountCurrent = () => expectedAccountId === undefined ||
|
|
503
|
+
this.configManager.getUserId() === expectedAccountId;
|
|
504
|
+
const accountChanged = {
|
|
505
|
+
status: 'error',
|
|
506
|
+
reason: 'account_changed',
|
|
507
|
+
message: ACCOUNT_CHANGED_MESSAGE,
|
|
508
|
+
};
|
|
509
|
+
const requestFailed = {
|
|
510
|
+
status: 'error',
|
|
511
|
+
reason: 'request_failed',
|
|
512
|
+
message: 'Could not confirm reference account disconnection. Check your Rivet sign-in and connection, then retry.',
|
|
513
|
+
};
|
|
514
|
+
const del = async (bearer) => {
|
|
515
|
+
if (!isAccountCurrent())
|
|
516
|
+
throw new Error(accountChanged.message);
|
|
517
|
+
return fetch(`${this.proxyUrl}/api/integrations/${provider}`, {
|
|
518
|
+
method: 'DELETE',
|
|
519
|
+
headers: { Authorization: `Bearer ${bearer}` },
|
|
520
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
521
|
+
});
|
|
522
|
+
};
|
|
500
523
|
try {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (!response.ok) {
|
|
506
|
-
const text = await response.text().catch(() => '');
|
|
524
|
+
if (!isAccountCurrent())
|
|
525
|
+
return accountChanged;
|
|
526
|
+
const response = await this.requestWithBearer(del, expectedAccountId);
|
|
527
|
+
if (!response || response.status === 401)
|
|
507
528
|
return {
|
|
508
529
|
status: 'error',
|
|
509
|
-
|
|
530
|
+
reason: 'auth_required',
|
|
531
|
+
message: 'Sign in to Rivet before disconnecting a reference account.',
|
|
510
532
|
};
|
|
511
|
-
|
|
533
|
+
if (!response.ok)
|
|
534
|
+
return requestFailed;
|
|
535
|
+
const acknowledgement = await response.json();
|
|
536
|
+
const schema = provider === 'x'
|
|
537
|
+
? XDisconnectBodySchema
|
|
538
|
+
: IntegrationDisconnectBodySchema;
|
|
539
|
+
if (!schema.safeParse(acknowledgement).success)
|
|
540
|
+
return requestFailed;
|
|
512
541
|
return { status: 'ok' };
|
|
513
542
|
}
|
|
514
|
-
catch
|
|
515
|
-
log.warn('Integration disconnect
|
|
516
|
-
return
|
|
517
|
-
status: 'error',
|
|
518
|
-
message: (0, errorMessage_1.errorMessage)(error, 'Unknown error'),
|
|
519
|
-
};
|
|
543
|
+
catch {
|
|
544
|
+
log.warn('Integration disconnect request failed');
|
|
545
|
+
return isAccountCurrent() ? requestFailed : accountChanged;
|
|
520
546
|
}
|
|
521
547
|
}
|
|
522
548
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AccountIdentity } from './ConfigManager';
|
|
2
2
|
import type { BrowserMetadata, DesignContextKind, ServerUnavailableReason, VariantContextMetadata, VerificationMetadata } from '../cli/telemetry';
|
|
3
3
|
import type { GuidanceErrorCode, GuidanceSelection } from '../types/guidance';
|
|
4
|
+
import { type ProfileImportKind, type ProfileImportStep, type ProfileMedia, type ProfilePreparationOffReason, type ProfileProvider } from '../types/design-profile';
|
|
4
5
|
import type { MCPAuthMethod, MCPAuthState, MCPOnboardingCorrelation, MCPOAuthCallbackResult } from './MCPOnboardingTelemetry';
|
|
5
6
|
import { type MCPVariantsTelemetryMetadata } from './MCPVariantsTelemetry';
|
|
6
7
|
export type RequestRejectionReason = 'host_not_allowed' | 'origin_not_allowed' | 'editor_token_on_preview';
|
|
@@ -21,13 +22,25 @@ export interface LibraryOperation {
|
|
|
21
22
|
error?: unknown;
|
|
22
23
|
}
|
|
23
24
|
export interface ProfileOperation {
|
|
24
|
-
stage: 'action' | 'import' | 'preparation' | 'maintenance';
|
|
25
|
-
operation: 'reference_discovery' | 'reference_lookup' | 'reference_search' | 'reference_plan' | 'reference_approval' | 'reference_onboarding' | 'reference_onboarding_offered' | 'enable' | 'disable' | 'text_import' | 'image_import' | 'variant_import' | 'source_connect' | 'source_refresh' | 'job_control' | 'source_control' | 'index_rebuild' | 'import' | 'preparation';
|
|
25
|
+
stage: 'action' | 'import' | 'preparation' | 'maintenance' | 'analysis';
|
|
26
|
+
operation: 'reference_discovery' | 'reference_lookup' | 'reference_search' | 'reference_plan' | 'reference_approval' | 'reference_onboarding' | 'reference_onboarding_offered' | 'enable' | 'disable' | 'text_import' | 'image_import' | 'variant_import' | 'source_connect' | 'source_refresh' | 'job_control' | 'source_control' | 'index_rebuild' | 'import' | 'preparation' | 'analysis';
|
|
26
27
|
outcome: 'completed' | 'failed' | 'deferred';
|
|
27
28
|
durationMs: number;
|
|
28
29
|
referenceCount?: number;
|
|
29
30
|
status?: 'selected' | 'empty' | 'off' | 'unavailable' | 'timeout';
|
|
30
31
|
error?: unknown;
|
|
32
|
+
provider?: ProfileProvider;
|
|
33
|
+
importKind?: ProfileImportKind;
|
|
34
|
+
failedStep?: ProfileImportStep;
|
|
35
|
+
addedCount?: number;
|
|
36
|
+
removedCount?: number;
|
|
37
|
+
staleHours?: number;
|
|
38
|
+
mediaKind?: ProfileMedia['representation'] | 'text' | 'mixed';
|
|
39
|
+
candidateCount?: number;
|
|
40
|
+
providerMix?: ProfileProvider[];
|
|
41
|
+
offReason?: ProfilePreparationOffReason;
|
|
42
|
+
providerCount?: number;
|
|
43
|
+
sourceCount?: number;
|
|
31
44
|
}
|
|
32
45
|
export interface GuidanceOperation {
|
|
33
46
|
operation: 'add' | 'update' | 'remove' | 'resolve' | 'delivery' | 'verifier';
|
|
@@ -78,6 +91,7 @@ export declare class TelemetryService {
|
|
|
78
91
|
callerRunId?: string;
|
|
79
92
|
designContextKind?: DesignContextKind;
|
|
80
93
|
source?: 'cli' | 'mcp';
|
|
94
|
+
error?: unknown;
|
|
81
95
|
} & VariantContextMetadata & BrowserMetadata & VerificationMetadata): void;
|
|
82
96
|
trackAuthStarted(data: {
|
|
83
97
|
surface: AuthTelemetrySurface;
|
|
@@ -13,6 +13,7 @@ const telemetryContract_1 = require("../config/telemetryContract");
|
|
|
13
13
|
const failureReason_1 = require("../utils/failureReason");
|
|
14
14
|
const posthog_1 = require("../config/posthog");
|
|
15
15
|
const proxy_1 = require("../config/proxy");
|
|
16
|
+
const design_profile_1 = require("../types/design-profile");
|
|
16
17
|
const MCPVariantsTelemetry_1 = require("./MCPVariantsTelemetry");
|
|
17
18
|
const errorMessage_1 = require("../utils/errorMessage");
|
|
18
19
|
const serverUnavailable_1 = require("../cli/serverUnavailable");
|
|
@@ -43,6 +44,7 @@ const mcpEditorEventValue = (editor) => {
|
|
|
43
44
|
return 'other';
|
|
44
45
|
};
|
|
45
46
|
const HASH_PREFIX_LENGTH = 12;
|
|
47
|
+
const optionalProperty = (key, value) => value === undefined ? {} : { [key]: value };
|
|
46
48
|
class TelemetryService {
|
|
47
49
|
trackGuidanceOperation(data) {
|
|
48
50
|
this.track(`mcp_guidance_${data.operation}_${data.outcome}`, {
|
|
@@ -62,7 +64,20 @@ class TelemetryService {
|
|
|
62
64
|
...(data.referenceCount !== undefined
|
|
63
65
|
? { reference_count: data.referenceCount }
|
|
64
66
|
: {}),
|
|
67
|
+
...optionalProperty('candidate_count', data.candidateCount),
|
|
65
68
|
...(data.status ? { status: data.status } : {}),
|
|
69
|
+
...optionalProperty('off_reason', data.offReason),
|
|
70
|
+
...optionalProperty('provider_mix', data.providerMix),
|
|
71
|
+
...optionalProperty('provider', data.provider),
|
|
72
|
+
...optionalProperty('media_kind', data.mediaKind),
|
|
73
|
+
...optionalProperty('job_kind', data.importKind),
|
|
74
|
+
...optionalProperty('trigger', data.importKind && design_profile_1.PROFILE_IMPORT_TRIGGERS[data.importKind]),
|
|
75
|
+
...optionalProperty('failed_step', data.failedStep),
|
|
76
|
+
...optionalProperty('added_count', data.addedCount),
|
|
77
|
+
...optionalProperty('removed_count', data.removedCount),
|
|
78
|
+
...optionalProperty('stale_hours', data.staleHours),
|
|
79
|
+
...optionalProperty('provider_count', data.providerCount),
|
|
80
|
+
...optionalProperty('source_count', data.sourceCount),
|
|
66
81
|
...(0, failureReason_1.failureReasonCodeProperties)(data.error),
|
|
67
82
|
});
|
|
68
83
|
}
|
|
@@ -306,6 +321,9 @@ class TelemetryService {
|
|
|
306
321
|
error_code: data.errorCode,
|
|
307
322
|
is_recoverable: data.isRecoverable,
|
|
308
323
|
server_unavailable_reason: data.serverUnavailableReason,
|
|
324
|
+
...(data.command === 'mcp'
|
|
325
|
+
? (0, failureReason_1.failureReasonProperties)(data.error)
|
|
326
|
+
: (0, failureReason_1.failureReasonCodeProperties)(data.error)),
|
|
309
327
|
duration_ms: data.durationMs,
|
|
310
328
|
caller_agent: data.callerAgent,
|
|
311
329
|
caller_model: data.callerModel,
|
|
@@ -74,6 +74,7 @@ export declare class DesignProfiles {
|
|
|
74
74
|
revision: number;
|
|
75
75
|
stage: "download" | "analysis";
|
|
76
76
|
error: string;
|
|
77
|
+
reasonCode: "timeout" | "unknown" | "aborted" | "multiple_lockfiles" | "unsupported_package_manager" | "invalid_package_manager_field" | "invalid_manifest" | "invalid_workspace" | "path_outside_workspace" | "dangling_symlink" | "version_unreadable" | "version_mismatch" | "no_install_command" | "install_failed" | "lockfile_outdated" | "engine_incompatible" | "install_script_failed" | "installer_unstoppable" | "inputs_changed" | "ENOENT" | "EACCES" | "EPERM" | "EEXIST" | "ENOTDIR" | "EISDIR" | "ELOOP" | "ENOSPC" | "EMFILE" | "EADDRINUSE" | "ECONNREFUSED" | "ECONNRESET" | "ETIMEDOUT" | "EBUSY" | "ENOTSUP" | "EINVAL" | "ENOTEMPTY" | "EROFS" | "EAI_AGAIN" | null;
|
|
77
78
|
attempts: number;
|
|
78
79
|
updatedAt: string;
|
|
79
80
|
}[];
|
|
@@ -88,6 +89,8 @@ export declare class DesignProfiles {
|
|
|
88
89
|
total: number | null;
|
|
89
90
|
error: string | null;
|
|
90
91
|
updatedAt: string;
|
|
92
|
+
addedCount: number;
|
|
93
|
+
removedCount: number;
|
|
91
94
|
}[];
|
|
92
95
|
id: string;
|
|
93
96
|
revision: string;
|
|
@@ -687,6 +690,8 @@ export declare class DesignProfiles {
|
|
|
687
690
|
total: number | null;
|
|
688
691
|
error: string | null;
|
|
689
692
|
updatedAt: string;
|
|
693
|
+
addedCount: number;
|
|
694
|
+
removedCount: number;
|
|
690
695
|
}[];
|
|
691
696
|
rebuild: {
|
|
692
697
|
singleton: number;
|
|
@@ -720,6 +725,7 @@ export declare class DesignProfiles {
|
|
|
720
725
|
revision: number;
|
|
721
726
|
stage: "download" | "analysis";
|
|
722
727
|
error: string;
|
|
728
|
+
reasonCode: "timeout" | "unknown" | "aborted" | "multiple_lockfiles" | "unsupported_package_manager" | "invalid_package_manager_field" | "invalid_manifest" | "invalid_workspace" | "path_outside_workspace" | "dangling_symlink" | "version_unreadable" | "version_mismatch" | "no_install_command" | "install_failed" | "lockfile_outdated" | "engine_incompatible" | "install_script_failed" | "installer_unstoppable" | "inputs_changed" | "ENOENT" | "EACCES" | "EPERM" | "EEXIST" | "ENOTDIR" | "EISDIR" | "ELOOP" | "ENOSPC" | "EMFILE" | "EADDRINUSE" | "ECONNREFUSED" | "ECONNRESET" | "ETIMEDOUT" | "EBUSY" | "ENOTSUP" | "EINVAL" | "ENOTEMPTY" | "EROFS" | "EAI_AGAIN" | null;
|
|
723
729
|
attempts: number;
|
|
724
730
|
updatedAt: string;
|
|
725
731
|
}[];
|
|
@@ -768,6 +774,8 @@ export declare class DesignProfiles {
|
|
|
768
774
|
total: number | null;
|
|
769
775
|
error: string | null;
|
|
770
776
|
updatedAt: string;
|
|
777
|
+
addedCount: number;
|
|
778
|
+
removedCount: number;
|
|
771
779
|
}[];
|
|
772
780
|
rebuild: {
|
|
773
781
|
singleton: number;
|
|
@@ -828,6 +836,8 @@ export declare class DesignProfiles {
|
|
|
828
836
|
total: number | null;
|
|
829
837
|
error: string | null;
|
|
830
838
|
updatedAt: string;
|
|
839
|
+
addedCount: number;
|
|
840
|
+
removedCount: number;
|
|
831
841
|
}[];
|
|
832
842
|
rebuild: {
|
|
833
843
|
singleton: number;
|
|
@@ -965,6 +975,8 @@ export declare class DesignProfiles {
|
|
|
965
975
|
total: number | null;
|
|
966
976
|
error: string | null;
|
|
967
977
|
updatedAt: string;
|
|
978
|
+
addedCount: number;
|
|
979
|
+
removedCount: number;
|
|
968
980
|
};
|
|
969
981
|
} | {
|
|
970
982
|
status: "authorization_required";
|
|
@@ -1003,6 +1015,8 @@ export declare class DesignProfiles {
|
|
|
1003
1015
|
total: number | null;
|
|
1004
1016
|
error: string | null;
|
|
1005
1017
|
updatedAt: string;
|
|
1018
|
+
addedCount: number;
|
|
1019
|
+
removedCount: number;
|
|
1006
1020
|
}[];
|
|
1007
1021
|
rebuild: {
|
|
1008
1022
|
singleton: number;
|
|
@@ -1049,6 +1063,8 @@ export declare class DesignProfiles {
|
|
|
1049
1063
|
total: number | null;
|
|
1050
1064
|
error: string | null;
|
|
1051
1065
|
updatedAt: string;
|
|
1066
|
+
addedCount: number;
|
|
1067
|
+
removedCount: number;
|
|
1052
1068
|
};
|
|
1053
1069
|
}>;
|
|
1054
1070
|
updateSource({ id, isIncluded, isRemoved, runtime, }: {
|