rivet-design 0.28.2 → 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 +13 -4
- 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 +1 -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/library/browserLaunch.d.ts +2 -1
- package/dist/library/browserLaunch.js +3 -2
- package/dist/routes/referenceProfiles.js +3 -3
- package/dist/server.js +2 -1
- 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/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/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/skills/cli-guidance.d.ts +1 -1
- package/dist/utils/skills/cli-guidance.js +2 -1
- package/package.json +2 -2
- package/src/ui/dist/assets/LibraryEntry-CSU5OJwC.js +2 -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 +2 -2
- package/src/ui/dist/pages/empty-project.html +1 -1
- package/src/ui/dist/pages/rivet-page.html +2 -2
- package/src/ui/dist/assets/LibraryEntry-B8-RtQpK.js +0 -2
- package/src/ui/dist/assets/main-11-ME6E3.css +0 -1
- package/src/ui/dist/assets/main-BGCGsyhl.js +0 -204
|
@@ -93,6 +93,7 @@ const handleLibraryOpen = async (args, io, options = {}) => {
|
|
|
93
93
|
const editorUrl = await (0, browserLaunch_1.createLibraryLaunchUrl)({
|
|
94
94
|
hub,
|
|
95
95
|
path: `/rivet/library${projectSuffix}`,
|
|
96
|
+
callerAgent: context.handoff?.agent,
|
|
96
97
|
});
|
|
97
98
|
const browser = await (0, browser_1.requestBrowserOpen)({
|
|
98
99
|
url: editorUrl,
|
|
@@ -184,6 +184,7 @@ const buildMcpServer = async (options = {}) => {
|
|
|
184
184
|
...(0, telemetry_1.variantContextMetadataForArgs)(command, rest),
|
|
185
185
|
...(0, telemetry_1.verificationMetadataForEnvelope)(result.envelope),
|
|
186
186
|
...callerFields,
|
|
187
|
+
error: result.cause,
|
|
187
188
|
source: 'mcp',
|
|
188
189
|
});
|
|
189
190
|
}
|
|
@@ -455,7 +456,10 @@ const handleMcpServe = async (rest, io) => {
|
|
|
455
456
|
await built.mcp.connect(new StdioServerTransport());
|
|
456
457
|
}
|
|
457
458
|
catch (error) {
|
|
458
|
-
return
|
|
459
|
+
return {
|
|
460
|
+
...(0, envelope_1.errorResult)('mcp', 'OPERATION_FAILED', `Could not start the MCP server: ${(0, errorMessage_1.errorMessage)(error)}`),
|
|
461
|
+
cause: error,
|
|
462
|
+
};
|
|
459
463
|
}
|
|
460
464
|
let isClosing = false;
|
|
461
465
|
const shutdown = () => {
|
|
@@ -40,6 +40,7 @@ exports.ensureProjectRuntime = exports.validateProjectOpen = exports.PROJECT_RUN
|
|
|
40
40
|
const projectRuntimeUpgrade_1 = require("../projectRuntimeUpgrade");
|
|
41
41
|
const child_process_1 = require("child_process");
|
|
42
42
|
const subprocessEnvironment_1 = require("../../utils/subprocessEnvironment");
|
|
43
|
+
const launchRuntime_1 = require("../../utils/launchRuntime");
|
|
43
44
|
const fs_1 = __importDefault(require("fs"));
|
|
44
45
|
const path_1 = __importDefault(require("path"));
|
|
45
46
|
const envelope_1 = require("../envelope");
|
|
@@ -173,7 +174,7 @@ const serveEnvFor = (handoff, baseEnv) => ({
|
|
|
173
174
|
}
|
|
174
175
|
: {}),
|
|
175
176
|
});
|
|
176
|
-
const openedData = async (attached, wasAlreadyRunning) => {
|
|
177
|
+
const openedData = async ({ attached, wasAlreadyRunning, callerAgent, }) => {
|
|
177
178
|
let session;
|
|
178
179
|
try {
|
|
179
180
|
const status = await (0, client_1.requestServer)(attached, '/api/cli/status');
|
|
@@ -186,7 +187,7 @@ const openedData = async (attached, wasAlreadyRunning) => {
|
|
|
186
187
|
attached: true,
|
|
187
188
|
alreadyRunning: wasAlreadyRunning,
|
|
188
189
|
rivetPort: attached.handshake.rivetPort,
|
|
189
|
-
editorUrl: (0, client_1.editorUrlFor)(attached),
|
|
190
|
+
editorUrl: (0, launchRuntime_1.withLaunchRuntime)((0, client_1.editorUrlFor)(attached), callerAgent),
|
|
190
191
|
sessionId: session?.sessionId ?? attached.handshake.sessionId,
|
|
191
192
|
applyMode: attached.handshake.applyMode,
|
|
192
193
|
resolvedRunner: session?.resolvedRunner ?? null,
|
|
@@ -296,7 +297,11 @@ const ensureProjectRuntime = async (context, io, dependencies = {}) => {
|
|
|
296
297
|
if (replacement.outcome === 'attach') {
|
|
297
298
|
const readinessError = await verifyRuntimeReadiness(existing, appHealthTimeoutMs);
|
|
298
299
|
if (!readinessError) {
|
|
299
|
-
return finishProjectOpen(await openedData(
|
|
300
|
+
return finishProjectOpen(await openedData({
|
|
301
|
+
attached: existing,
|
|
302
|
+
wasAlreadyRunning: true,
|
|
303
|
+
callerAgent: context.handoff?.agent,
|
|
304
|
+
}), io);
|
|
300
305
|
}
|
|
301
306
|
if ((0, telemetry_1.serverUnavailableReasonForEnvelope)(readinessError.envelope) !==
|
|
302
307
|
'app_health_failed')
|
|
@@ -351,7 +356,11 @@ const ensureProjectRuntime = async (context, io, dependencies = {}) => {
|
|
|
351
356
|
const readinessError = await verifyRuntimeReadiness(attached, appHealthTimeoutMs);
|
|
352
357
|
if (readinessError)
|
|
353
358
|
return readinessError;
|
|
354
|
-
const data = await openedData(
|
|
359
|
+
const data = await openedData({
|
|
360
|
+
attached,
|
|
361
|
+
wasAlreadyRunning: false,
|
|
362
|
+
callerAgent: context.handoff?.agent,
|
|
363
|
+
});
|
|
355
364
|
return finishProjectOpen({ ...data, ...(interruptedWork ? { interruptedWork } : {}) }, io);
|
|
356
365
|
}
|
|
357
366
|
finally {
|
|
@@ -16,11 +16,18 @@ const envelope_1 = require("../envelope");
|
|
|
16
16
|
const callerRunnerPaths_1 = require("../callerRunnerPaths");
|
|
17
17
|
const errorMessage_1 = require("../../utils/errorMessage");
|
|
18
18
|
const subprocessEnvironment_1 = require("../../utils/subprocessEnvironment");
|
|
19
|
+
const profileDisconnect_1 = require("./profileDisconnect");
|
|
19
20
|
const PROFILE_REQUEST_TIMEOUT_MS = 55_000;
|
|
20
21
|
const PROFILE_SEARCH_TIMEOUT_MS = 120_000;
|
|
21
22
|
const handleProfile = async (args) => {
|
|
22
23
|
const action = args[0] ?? 'status';
|
|
23
24
|
const command = `profile.${action}`;
|
|
25
|
+
if (action === 'disconnect') {
|
|
26
|
+
const context = (0, shared_1.parseCommandContext)(command, args.slice(1));
|
|
27
|
+
return (0, shared_1.isCommandResult)(context)
|
|
28
|
+
? context
|
|
29
|
+
: (0, profileDisconnect_1.handleProfileDisconnect)(context.flags.positionals);
|
|
30
|
+
}
|
|
24
31
|
const context = (0, shared_1.parseCommandContext)(command, args.slice(1), {
|
|
25
32
|
runtime: { takesValue: true },
|
|
26
33
|
detail: { takesValue: false },
|
|
@@ -266,7 +273,7 @@ const handleProfile = async (args) => {
|
|
|
266
273
|
};
|
|
267
274
|
break;
|
|
268
275
|
default:
|
|
269
|
-
return (0, envelope_1.errorResult)(command, 'USAGE_ERROR', 'Usage: rivet profile <status|diagnostics|discover|plan|import|onboarding|rebuild-index|enable|disable|connect|refresh|pause|resume|retry|add-text|add-images|pins|add-variant|inspect|references|reference|search|include|exclude|remove|suggest>');
|
|
276
|
+
return (0, envelope_1.errorResult)(command, 'USAGE_ERROR', 'Usage: rivet profile <status|diagnostics|discover|plan|import|onboarding|rebuild-index|enable|disable|connect|disconnect|refresh|pause|resume|retry|add-text|add-images|pins|add-variant|inspect|references|reference|search|include|exclude|remove|suggest>');
|
|
270
277
|
}
|
|
271
278
|
const hub = await (0, HubClient_1.ensureHub)({
|
|
272
279
|
root: (0, ProjectLibrary_1.currentLibraryRoot)(),
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleProfileDisconnect = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const ConfigManager_1 = require("../../services/ConfigManager");
|
|
6
|
+
const IntegrationsClient_1 = require("../../services/IntegrationsClient");
|
|
7
|
+
const reference_connectors_1 = require("../../types/reference-connectors");
|
|
8
|
+
const envelope_1 = require("../envelope");
|
|
9
|
+
const COMMAND = 'profile.disconnect';
|
|
10
|
+
const handleProfileDisconnect = async (positionals) => {
|
|
11
|
+
const selected = zod_1.z
|
|
12
|
+
.tuple([reference_connectors_1.AuthenticatedReferenceProviderSchema])
|
|
13
|
+
.safeParse(positionals);
|
|
14
|
+
if (!selected.success)
|
|
15
|
+
return (0, envelope_1.errorResult)(COMMAND, 'USAGE_ERROR', 'Usage: rivet profile disconnect <pinterest|arena|x>');
|
|
16
|
+
try {
|
|
17
|
+
const config = (0, ConfigManager_1.getConfigManager)();
|
|
18
|
+
const accountId = config.getUserId();
|
|
19
|
+
if (!accountId || !config.isAuthenticated())
|
|
20
|
+
return (0, envelope_1.errorResult)(COMMAND, 'AUTH_REQUIRED', 'Sign in to Rivet before disconnecting a reference account.');
|
|
21
|
+
const provider = selected.data[0];
|
|
22
|
+
const result = await new IntegrationsClient_1.IntegrationsClient().disconnect(provider, accountId);
|
|
23
|
+
if (result.status === 'ok')
|
|
24
|
+
return (0, envelope_1.okResult)(COMMAND, { provider, isDisconnected: true });
|
|
25
|
+
if (config.getUserId() !== accountId)
|
|
26
|
+
return (0, envelope_1.errorResult)(COMMAND, 'OPERATION_FAILED', 'Rivet account changed. Retry with the intended account.', { reason: 'account_changed' });
|
|
27
|
+
return (0, envelope_1.errorResult)(COMMAND, result.reason === 'auth_required' ? 'AUTH_REQUIRED' : 'OPERATION_FAILED', result.message, { reason: result.reason });
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return (0, envelope_1.errorResult)(COMMAND, 'OPERATION_FAILED', 'Could not confirm reference account disconnection. Check your Rivet sign-in and connection, then retry.');
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.handleProfileDisconnect = handleProfileDisconnect;
|
|
34
|
+
//# sourceMappingURL=profileDisconnect.js.map
|
|
@@ -17,7 +17,10 @@ const pluginContext_1 = require("../../hosts/pluginContext");
|
|
|
17
17
|
const commandErrorResult = (command, error) => error instanceof pluginContext_1.PluginContextMismatchError ||
|
|
18
18
|
error instanceof telemetryPolicy_1.TelemetryPolicyMismatchError
|
|
19
19
|
? (0, envelope_1.errorResult)(command, 'SERVER_UNAVAILABLE', error.message, { serverUnavailableReason: error.reason }, { isRecoverable: false })
|
|
20
|
-
:
|
|
20
|
+
: {
|
|
21
|
+
...(0, envelope_1.errorResult)(command, 'OPERATION_FAILED', (0, errorMessage_1.errorMessage)(error)),
|
|
22
|
+
cause: error,
|
|
23
|
+
};
|
|
21
24
|
exports.commandErrorResult = commandErrorResult;
|
|
22
25
|
exports.SHARED_FLAG_SPEC = {
|
|
23
26
|
project: { takesValue: true },
|
package/dist/cli/envelope.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export type CliEnvelope<TData = unknown> = CliOkEnvelope<TData> | CliErrorEnvelo
|
|
|
55
55
|
export type CliCommandResult = {
|
|
56
56
|
envelope: CliEnvelope;
|
|
57
57
|
exitCode: CliExitCode;
|
|
58
|
+
cause?: unknown;
|
|
58
59
|
};
|
|
59
60
|
export declare const okResult: (command: string, data: unknown) => CliCommandResult;
|
|
60
61
|
export declare const loginRecovery: (authUrl?: string) => CliErrorRecovery;
|
package/dist/cli/router.js
CHANGED
|
@@ -52,8 +52,9 @@ const COMMAND_USAGE = {
|
|
|
52
52
|
'resolve [--guidance auto|off] [--exclude-guidance <JSON IDs>] returns current effective text and native paths without a model call. inspect <workId> --project <path> reads retained generation context. Guidance above 32 KiB emits an advisory warning, not a truncation or rejection. The HTTP request limit remains 50 MiB.',
|
|
53
53
|
],
|
|
54
54
|
profile: [
|
|
55
|
-
'rivet profile <status|diagnostics|discover|plan|import|onboarding|rebuild-index|enable|disable|connect|refresh|pause|resume|retry|add-text|add-images|pins|add-variant|inspect|references|reference|search|include|exclude|remove|suggest> [options]',
|
|
55
|
+
'rivet profile <status|diagnostics|discover|plan|import|onboarding|rebuild-index|enable|disable|connect|disconnect|refresh|pause|resume|retry|add-text|add-images|pins|add-variant|inspect|references|reference|search|include|exclude|remove|suggest> [options]',
|
|
56
56
|
'Search saved references by design intent with rivet profile search "<query>" [--source <sourceId>] [--limit N]. Results include stable keys for exact profile reference lookup and whether each source is included in automatic generation.',
|
|
57
|
+
'Disconnect a linked account with rivet profile disconnect <pinterest|arena|x>. This removes the signed-in Rivet account’s provider connection and keeps saved references. Exactly one provider is required. It needs no running editor or worker runtime. Provider authorization revocation varies by provider.',
|
|
57
58
|
'Resolve copied references in one batch with rivet profile reference <profileId> <shortId@revision>... . Default output is compact metadata. Add --detail only when full text, analysis, sources, and validated image paths are needed. No model work.',
|
|
58
59
|
'Manage saved design references, including Pinterest, Are.na, public Cosmos collections, and X bookmarks (https://x.com/i/bookmarks). A disconnected X account returns an authorization URL; sign in and repeat connect. Connect reference accounts with discover pinterest|arena|x, or discover <public Cosmos profile URL>. Complete OAuth if requested and repeat discovery. Use plan <discoveryId> --collections <JSON>, then import <planId> --revision <revision> --approve after user consent. Onboarding preferences accept --provider cosmos|pinterest|arena|x. Read a saved preview with plan <planId>. Model work uses the selected agent runtime.',
|
|
59
60
|
],
|
|
@@ -264,6 +265,10 @@ const dispatch = async (command, rest, io, options = {}) => {
|
|
|
264
265
|
return (0, envelope_1.errorResult)(command, 'USAGE_ERROR', `Unknown command: ${command}`);
|
|
265
266
|
};
|
|
266
267
|
exports.dispatch = dispatch;
|
|
268
|
+
const stdoutReservedForProtocolIO = (io) => ({
|
|
269
|
+
...io,
|
|
270
|
+
writeEnvelope: (envelope) => io.writeProgress((0, envelope_1.serializeEnvelope)(envelope)),
|
|
271
|
+
});
|
|
267
272
|
const runCliControlCommand = async (args, io = io_1.processCliIO) => {
|
|
268
273
|
const { redirectLogsToStderr } = await Promise.resolve().then(() => __importStar(require('../utils/logger')));
|
|
269
274
|
redirectLogsToStderr();
|
|
@@ -290,7 +295,7 @@ const runCliControlCommand = async (args, io = io_1.processCliIO) => {
|
|
|
290
295
|
catch (error) {
|
|
291
296
|
result = (0, shared_1.commandErrorResult)(command, error);
|
|
292
297
|
}
|
|
293
|
-
const exitCode = (0, io_1.emitResult)(io, result);
|
|
298
|
+
const exitCode = (0, io_1.emitResult)(command === 'mcp' ? stdoutReservedForProtocolIO(io) : io, result);
|
|
294
299
|
if (!rest.includes('--no-telemetry') &&
|
|
295
300
|
!(command === '__hub' && process.env.RIVET_LIBRARY_TELEMETRY === '0')) {
|
|
296
301
|
try {
|
|
@@ -311,6 +316,7 @@ const runCliControlCommand = async (args, io = io_1.processCliIO) => {
|
|
|
311
316
|
...(0, telemetry_1.browserMetadataForEnvelope)(result.envelope),
|
|
312
317
|
...(0, telemetry_1.verificationMetadataForEnvelope)(result.envelope),
|
|
313
318
|
...(0, handoff_1.callerTelemetryFieldsFromArgs)(rest),
|
|
319
|
+
error: result.cause,
|
|
314
320
|
});
|
|
315
321
|
telemetry.reportInstallRefActivations();
|
|
316
322
|
await telemetry.shutdown(result.envelope.command === 'variants.get'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ConnectedHub } from './HubClient';
|
|
2
|
-
export declare const createLibraryLaunchUrl: ({ hub, path, }: {
|
|
2
|
+
export declare const createLibraryLaunchUrl: ({ hub, path, callerAgent, }: {
|
|
3
3
|
hub: ConnectedHub;
|
|
4
4
|
path: string;
|
|
5
|
+
callerAgent?: string;
|
|
5
6
|
}) => Promise<string>;
|
|
6
7
|
//# sourceMappingURL=browserLaunch.d.ts.map
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createLibraryLaunchUrl = void 0;
|
|
4
4
|
const HubClient_1 = require("./HubClient");
|
|
5
|
-
const
|
|
5
|
+
const launchRuntime_1 = require("../utils/launchRuntime");
|
|
6
|
+
const createLibraryLaunchUrl = async ({ hub, path, callerAgent, }) => {
|
|
6
7
|
const { code } = await (0, HubClient_1.requestHub)({
|
|
7
8
|
hub,
|
|
8
9
|
endpoint: '/launch-codes',
|
|
@@ -11,7 +12,7 @@ const createLibraryLaunchUrl = async ({ hub, path, }) => {
|
|
|
11
12
|
const url = new URL(path, hub.url);
|
|
12
13
|
url.hostname = 'localhost';
|
|
13
14
|
url.hash = new URLSearchParams({ code }).toString();
|
|
14
|
-
return url.toString();
|
|
15
|
+
return (0, launchRuntime_1.withLaunchRuntime)(url.toString(), callerAgent);
|
|
15
16
|
};
|
|
16
17
|
exports.createLibraryLaunchUrl = createLibraryLaunchUrl;
|
|
17
18
|
//# sourceMappingURL=browserLaunch.js.map
|
|
@@ -6,7 +6,7 @@ const zod_1 = require("zod");
|
|
|
6
6
|
const HubClient_1 = require("../library/HubClient");
|
|
7
7
|
const ProjectLibrary_1 = require("../services/ProjectLibrary");
|
|
8
8
|
const ConfigManager_1 = require("../services/ConfigManager");
|
|
9
|
-
const
|
|
9
|
+
const reference_connectors_1 = require("../types/reference-connectors");
|
|
10
10
|
const reference_onboarding_1 = require("../types/reference-onboarding");
|
|
11
11
|
const design_profile_1 = require("../types/design-profile");
|
|
12
12
|
const errorMessage_1 = require("../utils/errorMessage");
|
|
@@ -28,11 +28,11 @@ const createReferenceProfilesRouter = () => {
|
|
|
28
28
|
}));
|
|
29
29
|
});
|
|
30
30
|
router.post('/reference-profiles/discoveries', async (req, res) => {
|
|
31
|
-
const
|
|
31
|
+
const input = reference_connectors_1.ReferenceDiscoveryRequestSchema.parse(req.body);
|
|
32
32
|
res.status(201).json(await (0, HubClient_1.requestHub)({
|
|
33
33
|
hub: await connectedHub(),
|
|
34
34
|
endpoint: '/profile/discoveries',
|
|
35
|
-
body:
|
|
35
|
+
body: input,
|
|
36
36
|
}));
|
|
37
37
|
});
|
|
38
38
|
router.post('/reference-profiles/import-plans', async (req, res) => {
|
package/dist/server.js
CHANGED
|
@@ -487,13 +487,14 @@ const startServer = async (options) => {
|
|
|
487
487
|
app.get('/api/config', async (_req, res) => {
|
|
488
488
|
const configManager = (0, ConfigManager_1.getConfigManager)();
|
|
489
489
|
const livePath = sessionBridge?.getProjectPath() ?? projectPath;
|
|
490
|
+
const initiator = sessionBridge?.getSessionRuntimeInfo().sessionInitiator;
|
|
490
491
|
res.json({
|
|
491
492
|
agentModeAvailable: configManager.isAuthenticated(),
|
|
492
493
|
email: configManager.getEmail(),
|
|
493
494
|
userId: configManager.getUserId(),
|
|
494
495
|
name: configManager.getDisplayName(),
|
|
495
496
|
isMCPSession: sessionBridge?.isActive() ?? false,
|
|
496
|
-
mcpEditor: mcpEditor ?? null,
|
|
497
|
+
mcpEditor: mcpEditor ?? (initiator?.kind === 'agent' ? initiator.agent : null),
|
|
497
498
|
agentApplyMode: sessionBridge?.isActive()
|
|
498
499
|
? (agentApplyMode ?? 'external')
|
|
499
500
|
: null,
|
|
@@ -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, }: {
|