@cortexmemory/cli 0.26.2 → 0.27.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/commands/convex.js +1 -1
- package/dist/commands/convex.js.map +1 -1
- package/dist/commands/deploy.d.ts +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +771 -144
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +210 -36
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +273 -43
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +102 -46
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +94 -7
- package/dist/commands/status.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +23 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/app-template-sync.d.ts +95 -0
- package/dist/utils/app-template-sync.d.ts.map +1 -0
- package/dist/utils/app-template-sync.js +425 -0
- package/dist/utils/app-template-sync.js.map +1 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +20 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/deployment-selector.d.ts +21 -0
- package/dist/utils/deployment-selector.d.ts.map +1 -1
- package/dist/utils/deployment-selector.js +32 -0
- package/dist/utils/deployment-selector.js.map +1 -1
- package/dist/utils/init/graph-setup.d.ts.map +1 -1
- package/dist/utils/init/graph-setup.js +25 -2
- package/dist/utils/init/graph-setup.js.map +1 -1
- package/dist/utils/init/quickstart-setup.d.ts +87 -0
- package/dist/utils/init/quickstart-setup.d.ts.map +1 -0
- package/dist/utils/init/quickstart-setup.js +462 -0
- package/dist/utils/init/quickstart-setup.js.map +1 -0
- package/dist/utils/schema-sync.d.ts.map +1 -1
- package/dist/utils/schema-sync.js +27 -21
- package/dist/utils/schema-sync.js.map +1 -1
- package/package.json +3 -2
- package/templates/vercel-ai-quickstart/.env.local.example +45 -0
- package/templates/vercel-ai-quickstart/README.md +280 -0
- package/templates/vercel-ai-quickstart/app/api/auth/check/route.ts +30 -0
- package/templates/vercel-ai-quickstart/app/api/auth/login/route.ts +83 -0
- package/templates/vercel-ai-quickstart/app/api/auth/register/route.ts +94 -0
- package/templates/vercel-ai-quickstart/app/api/auth/setup/route.ts +59 -0
- package/templates/vercel-ai-quickstart/app/api/chat/route.ts +277 -0
- package/templates/vercel-ai-quickstart/app/api/conversations/route.ts +179 -0
- package/templates/vercel-ai-quickstart/app/api/facts/route.ts +39 -0
- package/templates/vercel-ai-quickstart/app/api/health/route.ts +99 -0
- package/templates/vercel-ai-quickstart/app/api/memories/route.ts +37 -0
- package/templates/vercel-ai-quickstart/app/globals.css +275 -0
- package/templates/vercel-ai-quickstart/app/layout.tsx +19 -0
- package/templates/vercel-ai-quickstart/app/page.tsx +216 -0
- package/templates/vercel-ai-quickstart/components/AdminSetup.tsx +139 -0
- package/templates/vercel-ai-quickstart/components/AuthProvider.tsx +283 -0
- package/templates/vercel-ai-quickstart/components/ChatHistorySidebar.tsx +323 -0
- package/templates/vercel-ai-quickstart/components/ChatInterface.tsx +334 -0
- package/templates/vercel-ai-quickstart/components/ConvexClientProvider.tsx +21 -0
- package/templates/vercel-ai-quickstart/components/DataPreview.tsx +57 -0
- package/templates/vercel-ai-quickstart/components/HealthStatus.tsx +214 -0
- package/templates/vercel-ai-quickstart/components/LayerCard.tsx +263 -0
- package/templates/vercel-ai-quickstart/components/LayerFlowDiagram.tsx +195 -0
- package/templates/vercel-ai-quickstart/components/LoginScreen.tsx +202 -0
- package/templates/vercel-ai-quickstart/components/MemorySpaceSwitcher.tsx +93 -0
- package/templates/vercel-ai-quickstart/convex/conversations.ts +67 -0
- package/templates/vercel-ai-quickstart/convex/facts.ts +131 -0
- package/templates/vercel-ai-quickstart/convex/health.ts +15 -0
- package/templates/vercel-ai-quickstart/convex/memories.ts +104 -0
- package/templates/vercel-ai-quickstart/convex/schema.ts +20 -0
- package/templates/vercel-ai-quickstart/convex/users.ts +105 -0
- package/templates/vercel-ai-quickstart/jest.config.js +45 -0
- package/templates/vercel-ai-quickstart/lib/animations.ts +146 -0
- package/templates/vercel-ai-quickstart/lib/cortex.ts +27 -0
- package/templates/vercel-ai-quickstart/lib/layer-tracking.ts +214 -0
- package/templates/vercel-ai-quickstart/lib/password.ts +120 -0
- package/templates/vercel-ai-quickstart/next.config.js +27 -0
- package/templates/vercel-ai-quickstart/package.json +46 -0
- package/templates/vercel-ai-quickstart/postcss.config.js +5 -0
- package/templates/vercel-ai-quickstart/tailwind.config.js +37 -0
- package/templates/vercel-ai-quickstart/tests/helpers/mock-cortex.ts +263 -0
- package/templates/vercel-ai-quickstart/tests/helpers/setup.ts +48 -0
- package/templates/vercel-ai-quickstart/tests/integration/auth.test.ts +455 -0
- package/templates/vercel-ai-quickstart/tests/integration/conversations.test.ts +461 -0
- package/templates/vercel-ai-quickstart/tests/unit/password.test.ts +228 -0
- package/templates/vercel-ai-quickstart/tsconfig.json +33 -0
package/dist/commands/deploy.js
CHANGED
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Top-level commands for deploying and updating Cortex projects:
|
|
5
5
|
* - deploy: Deploy schema and functions to Convex
|
|
6
|
-
* - update: Update @cortexmemory/sdk and convex packages
|
|
6
|
+
* - update: Update @cortexmemory/sdk and convex packages across deployments and apps
|
|
7
7
|
*/
|
|
8
8
|
import ora from "ora";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import fs from "fs-extra";
|
|
9
11
|
import { resolveConfig, loadConfig } from "../utils/config.js";
|
|
10
|
-
import { selectDeployment } from "../utils/deployment-selector.js";
|
|
12
|
+
import { selectDeployment, getEnabledDeployments, } from "../utils/deployment-selector.js";
|
|
11
13
|
import { getDeploymentInfo } from "../utils/client.js";
|
|
12
14
|
import { printSuccess, printError, printWarning, printInfo, printSection, } from "../utils/formatting.js";
|
|
13
15
|
import { execCommand, execCommandLive } from "../utils/shell.js";
|
|
16
|
+
import { syncAppTemplate, checkTemplateSync, printTemplateSyncResult, } from "../utils/app-template-sync.js";
|
|
14
17
|
import pc from "picocolors";
|
|
15
18
|
/**
|
|
16
19
|
* Build environment for Convex commands, removing inherited CONVEX_* vars
|
|
@@ -136,195 +139,819 @@ export function registerDeployCommands(program, _config) {
|
|
|
136
139
|
// cortex update
|
|
137
140
|
program
|
|
138
141
|
.command("update")
|
|
139
|
-
.description("Update @cortexmemory/sdk and convex packages")
|
|
140
|
-
.option("-d, --deployment <name>", "Target deployment")
|
|
142
|
+
.description("Update @cortexmemory/sdk and convex packages across all enabled deployments and apps")
|
|
143
|
+
.option("-d, --deployment <name>", "Target a specific deployment only")
|
|
144
|
+
.option("-a, --app <name>", "Target a specific app only")
|
|
145
|
+
.option("--apps-only", "Only update apps (skip deployments)", false)
|
|
146
|
+
.option("--deployments-only", "Only update deployments (skip apps)", false)
|
|
147
|
+
.option("--dev", "Use dev mode (link to local SDK via CORTEX_SDK_DEV_PATH)", false)
|
|
148
|
+
.option("--sync-template", "Sync app template files (components, routes, etc.)", false)
|
|
141
149
|
.option("--sdk-version <version>", "Specific Cortex SDK version to install")
|
|
142
150
|
.option("--convex-version <version>", "Specific Convex version to install")
|
|
151
|
+
.option("--provider-version <version>", "Specific vercel-ai-provider version to install")
|
|
143
152
|
.option("-y, --yes", "Auto-accept all updates", false)
|
|
144
153
|
.action(async (options) => {
|
|
145
154
|
const currentConfig = await loadConfig();
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
// Check for dev mode
|
|
156
|
+
const devPath = process.env.CORTEX_SDK_DEV_PATH;
|
|
157
|
+
const isDevMode = options.dev || !!devPath;
|
|
158
|
+
if (isDevMode && !devPath) {
|
|
159
|
+
console.log(pc.red("\n Dev mode requires CORTEX_SDK_DEV_PATH environment variable"));
|
|
160
|
+
console.log(pc.dim(" Set it to the path of your local Project-Cortex repo:"));
|
|
161
|
+
console.log(pc.dim(" export CORTEX_SDK_DEV_PATH=/path/to/Project-Cortex\n"));
|
|
148
162
|
return;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
}
|
|
164
|
+
// If -a flag is provided, use single app mode
|
|
165
|
+
if (options.app) {
|
|
166
|
+
const app = currentConfig.apps?.[options.app];
|
|
167
|
+
if (!app) {
|
|
168
|
+
console.log(pc.red(`\n App "${options.app}" not found`));
|
|
169
|
+
const appNames = Object.keys(currentConfig.apps || {});
|
|
170
|
+
if (appNames.length > 0) {
|
|
171
|
+
console.log(pc.dim(` Available: ${appNames.join(", ")}`));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.log(pc.dim(" No apps configured. Run 'cortex init' to add one."));
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
155
178
|
try {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
179
|
+
await updateApp(options.app, app, {
|
|
180
|
+
...options,
|
|
181
|
+
devPath: isDevMode ? devPath : undefined,
|
|
182
|
+
syncTemplate: options.syncTemplate,
|
|
183
|
+
});
|
|
161
184
|
}
|
|
162
|
-
catch {
|
|
163
|
-
|
|
185
|
+
catch (error) {
|
|
186
|
+
printError(`Failed to update app "${options.app}": ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
164
187
|
}
|
|
165
|
-
|
|
166
|
-
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// If -d flag is provided, use single deployment mode (existing behavior)
|
|
191
|
+
if (options.deployment) {
|
|
192
|
+
const selection = await selectDeployment(currentConfig, options, "update packages");
|
|
193
|
+
if (!selection)
|
|
194
|
+
return;
|
|
195
|
+
const { name, deployment } = selection;
|
|
167
196
|
try {
|
|
168
|
-
|
|
169
|
-
latestSdkVersion = result.stdout.trim();
|
|
197
|
+
await updateDeployment(name, deployment, options);
|
|
170
198
|
}
|
|
171
|
-
catch {
|
|
172
|
-
|
|
199
|
+
catch (error) {
|
|
200
|
+
printError(`Failed to update deployment "${name}": ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
173
201
|
}
|
|
174
|
-
|
|
175
|
-
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// Determine what to update based on flags
|
|
205
|
+
const updateDeployments = !options.appsOnly;
|
|
206
|
+
const updateApps = !options.deploymentsOnly;
|
|
207
|
+
// Get enabled deployments and apps
|
|
208
|
+
const { deployments: enabledDeployments } = getEnabledDeployments(currentConfig);
|
|
209
|
+
const enabledApps = Object.entries(currentConfig.apps || {})
|
|
210
|
+
.filter(([, app]) => app.enabled)
|
|
211
|
+
.map(([name, app]) => ({ name, app }));
|
|
212
|
+
const hasDeployments = enabledDeployments.length > 0;
|
|
213
|
+
const hasApps = enabledApps.length > 0;
|
|
214
|
+
if (updateDeployments && !hasDeployments && !options.appsOnly) {
|
|
215
|
+
console.log(pc.yellow("\n No enabled deployments found"));
|
|
216
|
+
}
|
|
217
|
+
if (updateApps && !hasApps && !options.deploymentsOnly) {
|
|
218
|
+
console.log(pc.yellow("\n No enabled apps found"));
|
|
219
|
+
}
|
|
220
|
+
if ((!updateDeployments || !hasDeployments) && (!updateApps || !hasApps)) {
|
|
221
|
+
console.log(pc.red("\n Nothing to update"));
|
|
222
|
+
console.log(pc.dim(" Run 'cortex init' to configure deployments and apps\n"));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Single deployment + no apps - proceed directly (backwards compatibility)
|
|
226
|
+
if (updateDeployments && enabledDeployments.length === 1 && (!updateApps || !hasApps)) {
|
|
227
|
+
const { name, deployment } = enabledDeployments[0];
|
|
228
|
+
console.log(pc.dim(` Using: ${name}`));
|
|
229
|
+
await updateDeployment(name, deployment, options);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// Multiple targets or apps - show status dashboard
|
|
233
|
+
console.log();
|
|
234
|
+
const spinner = ora("Checking package versions...").start();
|
|
235
|
+
// Get latest versions once (shared across all targets)
|
|
236
|
+
let latestSdkVersion = "unknown";
|
|
237
|
+
let latestConvexVersion = "unknown";
|
|
238
|
+
let latestProviderVersion = "unknown";
|
|
239
|
+
let latestAiVersion = "unknown";
|
|
240
|
+
let sdkConvexPeerDep = "unknown";
|
|
241
|
+
try {
|
|
242
|
+
const [sdkResult, convexResult, providerResult, aiResult, peerDepResult] = await Promise.all([
|
|
243
|
+
execCommand("npm", ["view", "@cortexmemory/sdk", "version"], {
|
|
244
|
+
quiet: true,
|
|
245
|
+
}).catch(() => ({ stdout: "unknown" })),
|
|
246
|
+
execCommand("npm", ["view", "convex", "version"], {
|
|
247
|
+
quiet: true,
|
|
248
|
+
}).catch(() => ({ stdout: "unknown" })),
|
|
249
|
+
execCommand("npm", ["view", "@cortexmemory/vercel-ai-provider", "version"], {
|
|
250
|
+
quiet: true,
|
|
251
|
+
}).catch(() => ({ stdout: "unknown" })),
|
|
252
|
+
execCommand("npm", ["view", "ai", "version"], {
|
|
253
|
+
quiet: true,
|
|
254
|
+
}).catch(() => ({ stdout: "unknown" })),
|
|
255
|
+
execCommand("npm", ["view", "@cortexmemory/sdk", "peerDependencies", "--json"], { quiet: true }).catch(() => ({ stdout: "{}" })),
|
|
256
|
+
]);
|
|
257
|
+
latestSdkVersion = sdkResult.stdout.trim() || "unknown";
|
|
258
|
+
latestConvexVersion = convexResult.stdout.trim() || "unknown";
|
|
259
|
+
latestProviderVersion = providerResult.stdout.trim() || "unknown";
|
|
260
|
+
latestAiVersion = aiResult.stdout.trim() || "unknown";
|
|
176
261
|
try {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
currentConvexVersion =
|
|
180
|
-
data.dependencies?.convex?.version ?? "not installed";
|
|
262
|
+
const peerDeps = JSON.parse(peerDepResult.stdout);
|
|
263
|
+
sdkConvexPeerDep = peerDeps?.convex ?? "unknown";
|
|
181
264
|
}
|
|
182
265
|
catch {
|
|
183
|
-
// Ignore errors
|
|
266
|
+
// Ignore parse errors
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Ignore errors
|
|
271
|
+
}
|
|
272
|
+
const deploymentInfos = [];
|
|
273
|
+
const appInfos = [];
|
|
274
|
+
// Check deployments
|
|
275
|
+
if (updateDeployments && hasDeployments) {
|
|
276
|
+
for (const { name, deployment, projectPath } of enabledDeployments) {
|
|
277
|
+
let currentSdkVersion = "not installed";
|
|
278
|
+
let currentConvexVersion = "not installed";
|
|
279
|
+
try {
|
|
280
|
+
const result = await execCommand("npm", ["list", "@cortexmemory/sdk", "--json"], { quiet: true, cwd: projectPath });
|
|
281
|
+
const data = JSON.parse(result.stdout);
|
|
282
|
+
currentSdkVersion =
|
|
283
|
+
data.dependencies?.["@cortexmemory/sdk"]?.version ??
|
|
284
|
+
"not installed";
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// Ignore errors
|
|
288
|
+
}
|
|
289
|
+
try {
|
|
290
|
+
const result = await execCommand("npm", ["list", "convex", "--json"], {
|
|
291
|
+
quiet: true,
|
|
292
|
+
cwd: projectPath,
|
|
293
|
+
});
|
|
294
|
+
const data = JSON.parse(result.stdout);
|
|
295
|
+
currentConvexVersion =
|
|
296
|
+
data.dependencies?.convex?.version ?? "not installed";
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// Ignore errors
|
|
300
|
+
}
|
|
301
|
+
const targetSdkVersion = options.sdkVersion ?? latestSdkVersion;
|
|
302
|
+
const needsUpdate = currentSdkVersion !== targetSdkVersion ||
|
|
303
|
+
currentSdkVersion === "not installed";
|
|
304
|
+
deploymentInfos.push({
|
|
305
|
+
name,
|
|
306
|
+
deployment,
|
|
307
|
+
projectPath,
|
|
308
|
+
currentSdkVersion,
|
|
309
|
+
currentConvexVersion,
|
|
310
|
+
needsUpdate,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// Check apps
|
|
315
|
+
if (updateApps && hasApps) {
|
|
316
|
+
for (const { name, app } of enabledApps) {
|
|
317
|
+
const appPath = path.join(app.projectPath, app.path);
|
|
318
|
+
let currentSdkVersion = "not installed";
|
|
319
|
+
let currentProviderVersion = "not installed";
|
|
320
|
+
let currentConvexVersion = "not installed";
|
|
321
|
+
let currentAiVersion = "not installed";
|
|
322
|
+
let isDevLinked = false;
|
|
323
|
+
// Check package.json for file: references (dev linked)
|
|
324
|
+
try {
|
|
325
|
+
const packageJsonPath = path.join(appPath, "package.json");
|
|
326
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
327
|
+
const pkg = await fs.readJson(packageJsonPath);
|
|
328
|
+
const sdkDep = pkg.dependencies?.["@cortexmemory/sdk"];
|
|
329
|
+
const providerDep = pkg.dependencies?.["@cortexmemory/vercel-ai-provider"];
|
|
330
|
+
isDevLinked = sdkDep?.startsWith("file:") || providerDep?.startsWith("file:");
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Ignore errors
|
|
335
|
+
}
|
|
336
|
+
// Get installed versions
|
|
337
|
+
try {
|
|
338
|
+
const result = await execCommand("npm", ["list", "@cortexmemory/sdk", "@cortexmemory/vercel-ai-provider", "convex", "ai", "--json"], { quiet: true, cwd: appPath });
|
|
339
|
+
const data = JSON.parse(result.stdout);
|
|
340
|
+
currentSdkVersion =
|
|
341
|
+
data.dependencies?.["@cortexmemory/sdk"]?.version ?? "not installed";
|
|
342
|
+
currentProviderVersion =
|
|
343
|
+
data.dependencies?.["@cortexmemory/vercel-ai-provider"]?.version ?? "not installed";
|
|
344
|
+
currentConvexVersion =
|
|
345
|
+
data.dependencies?.convex?.version ?? "not installed";
|
|
346
|
+
currentAiVersion =
|
|
347
|
+
data.dependencies?.ai?.version ?? "not installed";
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
// Ignore errors
|
|
351
|
+
}
|
|
352
|
+
const targetSdkVersion = isDevMode ? "dev" : (options.sdkVersion ?? latestSdkVersion);
|
|
353
|
+
const needsUpdate = isDevMode
|
|
354
|
+
? !isDevLinked // Dev mode: needs update if not already dev-linked
|
|
355
|
+
: (currentSdkVersion !== targetSdkVersion || currentSdkVersion === "not installed");
|
|
356
|
+
// Check template sync status if --sync-template is enabled
|
|
357
|
+
let templateFilesToUpdate = 0;
|
|
358
|
+
let templateFilesToAdd = 0;
|
|
359
|
+
let needsTemplateSync = false;
|
|
360
|
+
if (options.syncTemplate) {
|
|
361
|
+
try {
|
|
362
|
+
const templateStatus = await checkTemplateSync(app);
|
|
363
|
+
templateFilesToUpdate = templateStatus.filesOutdated.length;
|
|
364
|
+
templateFilesToAdd = templateStatus.filesMissing.length;
|
|
365
|
+
needsTemplateSync = templateStatus.needsSync;
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Ignore errors
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
appInfos.push({
|
|
372
|
+
name,
|
|
373
|
+
app,
|
|
374
|
+
appPath,
|
|
375
|
+
currentSdkVersion,
|
|
376
|
+
currentProviderVersion,
|
|
377
|
+
currentConvexVersion,
|
|
378
|
+
currentAiVersion,
|
|
379
|
+
needsUpdate,
|
|
380
|
+
isDevLinked,
|
|
381
|
+
templateFilesToUpdate,
|
|
382
|
+
templateFilesToAdd,
|
|
383
|
+
needsTemplateSync,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
spinner.stop();
|
|
388
|
+
// Display status dashboard
|
|
389
|
+
if (isDevMode) {
|
|
390
|
+
console.log(pc.magenta(" ═══ DEV MODE ═══"));
|
|
391
|
+
console.log(pc.dim(` SDK path: ${devPath}`));
|
|
392
|
+
console.log();
|
|
393
|
+
}
|
|
394
|
+
console.log(pc.bold(" Latest versions:"));
|
|
395
|
+
console.log(` @cortexmemory/sdk: ${pc.cyan(latestSdkVersion)}`);
|
|
396
|
+
console.log(` @cortexmemory/vercel-ai-provider: ${pc.cyan(latestProviderVersion)}`);
|
|
397
|
+
console.log(` convex: ${pc.cyan(latestConvexVersion)}`);
|
|
398
|
+
console.log(` ai: ${pc.cyan(latestAiVersion)}`);
|
|
399
|
+
if (sdkConvexPeerDep !== "unknown") {
|
|
400
|
+
console.log(` SDK requires convex: ${pc.dim(sdkConvexPeerDep)}`);
|
|
401
|
+
}
|
|
402
|
+
console.log();
|
|
403
|
+
// Show deployment status
|
|
404
|
+
if (deploymentInfos.length > 0) {
|
|
405
|
+
printSection("Deployments", {});
|
|
406
|
+
console.log();
|
|
407
|
+
for (const info of deploymentInfos) {
|
|
408
|
+
const isDefault = info.name === currentConfig.default;
|
|
409
|
+
const defaultBadge = isDefault ? pc.cyan(" (default)") : "";
|
|
410
|
+
const statusIcon = info.needsUpdate
|
|
411
|
+
? pc.yellow("●")
|
|
412
|
+
: pc.green("●");
|
|
413
|
+
console.log(` ${statusIcon} ${pc.bold(info.name)}${defaultBadge}`);
|
|
414
|
+
console.log(pc.dim(` Path: ${info.projectPath}`));
|
|
415
|
+
console.log(` SDK: ${info.currentSdkVersion === latestSdkVersion ? pc.green(info.currentSdkVersion) : pc.yellow(info.currentSdkVersion)}`);
|
|
416
|
+
console.log(` Convex: ${info.currentConvexVersion === latestConvexVersion ? pc.green(info.currentConvexVersion) : pc.yellow(info.currentConvexVersion)}`);
|
|
417
|
+
console.log();
|
|
184
418
|
}
|
|
185
|
-
|
|
186
|
-
|
|
419
|
+
}
|
|
420
|
+
// Show app status
|
|
421
|
+
if (appInfos.length > 0) {
|
|
422
|
+
printSection("Apps", {});
|
|
423
|
+
console.log();
|
|
424
|
+
for (const info of appInfos) {
|
|
425
|
+
const devBadge = info.isDevLinked ? pc.magenta(" [DEV]") : "";
|
|
426
|
+
const needsAnyUpdate = info.needsUpdate || info.needsTemplateSync;
|
|
427
|
+
const statusIcon = needsAnyUpdate
|
|
428
|
+
? pc.yellow("●")
|
|
429
|
+
: pc.green("●");
|
|
430
|
+
console.log(` ${statusIcon} ${pc.bold(info.name)}${devBadge}`);
|
|
431
|
+
console.log(pc.dim(` Path: ${info.appPath}`));
|
|
432
|
+
console.log(` SDK: ${info.isDevLinked ? pc.magenta("file:...") : (info.currentSdkVersion === latestSdkVersion ? pc.green(info.currentSdkVersion) : pc.yellow(info.currentSdkVersion))}`);
|
|
433
|
+
console.log(` Provider: ${info.isDevLinked ? pc.magenta("file:...") : (info.currentProviderVersion === latestProviderVersion ? pc.green(info.currentProviderVersion) : pc.yellow(info.currentProviderVersion))}`);
|
|
434
|
+
console.log(` AI: ${info.currentAiVersion === latestAiVersion ? pc.green(info.currentAiVersion) : pc.yellow(info.currentAiVersion)}`);
|
|
435
|
+
console.log(` Convex: ${info.currentConvexVersion === latestConvexVersion ? pc.green(info.currentConvexVersion) : pc.yellow(info.currentConvexVersion)}`);
|
|
436
|
+
// Show template sync status if --sync-template is enabled
|
|
437
|
+
if (options.syncTemplate) {
|
|
438
|
+
const totalTemplateChanges = info.templateFilesToUpdate + info.templateFilesToAdd;
|
|
439
|
+
if (totalTemplateChanges > 0) {
|
|
440
|
+
console.log(` Template: ${pc.yellow(`${totalTemplateChanges} file(s) to sync`)}`);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
console.log(` Template: ${pc.green("up to date")}`);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
console.log();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// Count updates needed
|
|
450
|
+
const deploymentsNeedingUpdate = deploymentInfos.filter((d) => d.needsUpdate);
|
|
451
|
+
const appsNeedingUpdate = appInfos.filter((a) => a.needsUpdate || (options.syncTemplate && a.needsTemplateSync));
|
|
452
|
+
const totalNeedingUpdate = deploymentsNeedingUpdate.length + appsNeedingUpdate.length;
|
|
453
|
+
// Check if any updates needed
|
|
454
|
+
if (totalNeedingUpdate === 0) {
|
|
455
|
+
printSuccess("Everything is up to date!");
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
// Prompt for confirmation
|
|
459
|
+
const updateParts = [];
|
|
460
|
+
if (deploymentsNeedingUpdate.length > 0) {
|
|
461
|
+
updateParts.push(`${deploymentsNeedingUpdate.length} deployment(s)`);
|
|
462
|
+
}
|
|
463
|
+
if (appsNeedingUpdate.length > 0) {
|
|
464
|
+
updateParts.push(`${appsNeedingUpdate.length} app(s)`);
|
|
465
|
+
}
|
|
466
|
+
console.log(pc.cyan(` ${updateParts.join(" and ")} need updates`));
|
|
467
|
+
console.log();
|
|
468
|
+
let shouldProceed = options.yes;
|
|
469
|
+
if (!shouldProceed) {
|
|
470
|
+
const { default: prompts } = await import("prompts");
|
|
471
|
+
const response = await prompts({
|
|
472
|
+
type: "confirm",
|
|
473
|
+
name: "proceed",
|
|
474
|
+
message: `Update all ${totalNeedingUpdate} target(s)?`,
|
|
475
|
+
initial: true,
|
|
476
|
+
});
|
|
477
|
+
shouldProceed = response.proceed;
|
|
478
|
+
}
|
|
479
|
+
if (!shouldProceed) {
|
|
480
|
+
console.log(pc.yellow("\n Operation cancelled\n"));
|
|
481
|
+
console.log(pc.dim(" Tip: Use '-d <name>' for deployments or '-a <name>' for apps\n"));
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
// Perform updates
|
|
485
|
+
console.log();
|
|
486
|
+
let deploymentSuccessCount = 0;
|
|
487
|
+
let deploymentFailCount = 0;
|
|
488
|
+
let appSuccessCount = 0;
|
|
489
|
+
let appFailCount = 0;
|
|
490
|
+
// Update deployments
|
|
491
|
+
for (const info of deploymentsNeedingUpdate) {
|
|
492
|
+
console.log(pc.bold(`\n━━━ Updating deployment: ${info.name} ━━━\n`));
|
|
187
493
|
try {
|
|
188
|
-
|
|
189
|
-
|
|
494
|
+
await updateDeployment(info.name, info.deployment, {
|
|
495
|
+
...options,
|
|
496
|
+
yes: true,
|
|
497
|
+
});
|
|
498
|
+
deploymentSuccessCount++;
|
|
190
499
|
}
|
|
191
|
-
catch {
|
|
192
|
-
|
|
500
|
+
catch (error) {
|
|
501
|
+
printError(`Failed to update ${info.name}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
502
|
+
deploymentFailCount++;
|
|
193
503
|
}
|
|
194
|
-
|
|
195
|
-
|
|
504
|
+
}
|
|
505
|
+
// Update apps
|
|
506
|
+
for (const info of appsNeedingUpdate) {
|
|
507
|
+
console.log(pc.bold(`\n━━━ Updating app: ${info.name} ━━━\n`));
|
|
196
508
|
try {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
509
|
+
await updateApp(info.name, info.app, {
|
|
510
|
+
...options,
|
|
511
|
+
devPath: isDevMode ? devPath : undefined,
|
|
512
|
+
syncTemplate: options.syncTemplate,
|
|
513
|
+
yes: true,
|
|
514
|
+
});
|
|
515
|
+
appSuccessCount++;
|
|
200
516
|
}
|
|
201
|
-
catch {
|
|
202
|
-
|
|
517
|
+
catch (error) {
|
|
518
|
+
printError(`Failed to update ${info.name}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
519
|
+
appFailCount++;
|
|
203
520
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
521
|
+
}
|
|
522
|
+
// Summary
|
|
523
|
+
console.log();
|
|
524
|
+
console.log(pc.bold("━━━ Summary ━━━"));
|
|
525
|
+
console.log();
|
|
526
|
+
if (deploymentSuccessCount > 0) {
|
|
527
|
+
printSuccess(`${deploymentSuccessCount} deployment(s) updated successfully`);
|
|
528
|
+
}
|
|
529
|
+
if (deploymentFailCount > 0) {
|
|
530
|
+
printWarning(`${deploymentFailCount} deployment(s) failed to update`);
|
|
531
|
+
}
|
|
532
|
+
if (appSuccessCount > 0) {
|
|
533
|
+
printSuccess(`${appSuccessCount} app(s) updated successfully`);
|
|
534
|
+
}
|
|
535
|
+
if (appFailCount > 0) {
|
|
536
|
+
printWarning(`${appFailCount} app(s) failed to update`);
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Update packages for a single deployment
|
|
542
|
+
*/
|
|
543
|
+
async function updateDeployment(name, deployment, options) {
|
|
544
|
+
const projectPath = deployment.projectPath || process.cwd();
|
|
545
|
+
const spinner = ora("Checking for updates...").start();
|
|
546
|
+
try {
|
|
547
|
+
// Get current Cortex SDK version
|
|
548
|
+
let currentSdkVersion = "not installed";
|
|
549
|
+
try {
|
|
550
|
+
const result = await execCommand("npm", ["list", "@cortexmemory/sdk", "--json"], { quiet: true, cwd: projectPath });
|
|
551
|
+
const data = JSON.parse(result.stdout);
|
|
552
|
+
currentSdkVersion =
|
|
553
|
+
data.dependencies?.["@cortexmemory/sdk"]?.version ?? "not installed";
|
|
554
|
+
}
|
|
555
|
+
catch {
|
|
556
|
+
// Ignore errors
|
|
557
|
+
}
|
|
558
|
+
// Get latest Cortex SDK version from npm
|
|
559
|
+
let latestSdkVersion = "unknown";
|
|
560
|
+
try {
|
|
561
|
+
const result = await execCommand("npm", ["view", "@cortexmemory/sdk", "version"], { quiet: true });
|
|
562
|
+
latestSdkVersion = result.stdout.trim();
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
// Ignore errors
|
|
566
|
+
}
|
|
567
|
+
// Get current Convex version
|
|
568
|
+
let currentConvexVersion = "not installed";
|
|
569
|
+
try {
|
|
570
|
+
const result = await execCommand("npm", ["list", "convex", "--json"], {
|
|
571
|
+
quiet: true,
|
|
572
|
+
cwd: projectPath,
|
|
573
|
+
});
|
|
574
|
+
const data = JSON.parse(result.stdout);
|
|
575
|
+
currentConvexVersion =
|
|
576
|
+
data.dependencies?.convex?.version ?? "not installed";
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
// Ignore errors
|
|
580
|
+
}
|
|
581
|
+
// Get latest Convex version from npm
|
|
582
|
+
let latestConvexVersion = "unknown";
|
|
583
|
+
try {
|
|
584
|
+
const result = await execCommand("npm", ["view", "convex", "version"], {
|
|
585
|
+
quiet: true,
|
|
209
586
|
});
|
|
587
|
+
latestConvexVersion = result.stdout.trim();
|
|
588
|
+
}
|
|
589
|
+
catch {
|
|
590
|
+
// Ignore errors
|
|
591
|
+
}
|
|
592
|
+
// Get Cortex SDK's peer dependency on Convex
|
|
593
|
+
let sdkConvexPeerDep = "unknown";
|
|
594
|
+
try {
|
|
595
|
+
const result = await execCommand("npm", ["view", "@cortexmemory/sdk", "peerDependencies", "--json"], { quiet: true });
|
|
596
|
+
const peerDeps = JSON.parse(result.stdout);
|
|
597
|
+
sdkConvexPeerDep = peerDeps?.convex ?? "unknown";
|
|
598
|
+
}
|
|
599
|
+
catch {
|
|
600
|
+
// Ignore errors
|
|
601
|
+
}
|
|
602
|
+
spinner.stop();
|
|
603
|
+
// Display current status
|
|
604
|
+
console.log();
|
|
605
|
+
printSection("Package Status", {
|
|
606
|
+
Deployment: name,
|
|
607
|
+
"Project Path": projectPath,
|
|
608
|
+
});
|
|
609
|
+
console.log();
|
|
610
|
+
console.log(pc.bold(" @cortexmemory/sdk"));
|
|
611
|
+
console.log(` Current: ${currentSdkVersion === latestSdkVersion ? pc.green(currentSdkVersion) : pc.yellow(currentSdkVersion)}`);
|
|
612
|
+
console.log(` Latest: ${latestSdkVersion}`);
|
|
613
|
+
console.log();
|
|
614
|
+
console.log(pc.bold(" convex"));
|
|
615
|
+
console.log(` Current: ${currentConvexVersion === latestConvexVersion ? pc.green(currentConvexVersion) : pc.yellow(currentConvexVersion)}`);
|
|
616
|
+
console.log(` Latest: ${latestConvexVersion}`);
|
|
617
|
+
if (sdkConvexPeerDep !== "unknown") {
|
|
618
|
+
console.log(` SDK requires: ${pc.dim(sdkConvexPeerDep)}`);
|
|
619
|
+
}
|
|
620
|
+
console.log();
|
|
621
|
+
// Determine what needs updating
|
|
622
|
+
const targetSdkVersion = options.sdkVersion ?? latestSdkVersion;
|
|
623
|
+
const sdkNeedsUpdate = currentSdkVersion !== targetSdkVersion &&
|
|
624
|
+
currentSdkVersion !== "not installed";
|
|
625
|
+
const sdkNeedsInstall = currentSdkVersion === "not installed";
|
|
626
|
+
// Check if Convex has a patch update available beyond what SDK requires
|
|
627
|
+
const parseVersion = (v) => {
|
|
628
|
+
const match = v.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
629
|
+
if (!match)
|
|
630
|
+
return null;
|
|
631
|
+
return {
|
|
632
|
+
major: parseInt(match[1]),
|
|
633
|
+
minor: parseInt(match[2]),
|
|
634
|
+
patch: parseInt(match[3]),
|
|
635
|
+
};
|
|
636
|
+
};
|
|
637
|
+
const currentConvex = parseVersion(currentConvexVersion);
|
|
638
|
+
const latestConvex = parseVersion(latestConvexVersion);
|
|
639
|
+
let convexPatchAvailable = false;
|
|
640
|
+
if (currentConvex && latestConvex) {
|
|
641
|
+
// Patch update = same major.minor, higher patch
|
|
642
|
+
convexPatchAvailable =
|
|
643
|
+
currentConvex.major === latestConvex.major &&
|
|
644
|
+
currentConvex.minor === latestConvex.minor &&
|
|
645
|
+
currentConvex.patch < latestConvex.patch;
|
|
646
|
+
}
|
|
647
|
+
const targetConvexVersion = options.convexVersion ??
|
|
648
|
+
(convexPatchAvailable ? latestConvexVersion : null);
|
|
649
|
+
const convexNeedsUpdate = targetConvexVersion && currentConvexVersion !== targetConvexVersion;
|
|
650
|
+
// Nothing to update
|
|
651
|
+
if (!sdkNeedsUpdate &&
|
|
652
|
+
!sdkNeedsInstall &&
|
|
653
|
+
!convexNeedsUpdate &&
|
|
654
|
+
!convexPatchAvailable) {
|
|
655
|
+
printSuccess("All packages are up to date!");
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
// Update Cortex SDK if needed
|
|
659
|
+
if (sdkNeedsUpdate || sdkNeedsInstall) {
|
|
210
660
|
console.log();
|
|
211
|
-
|
|
212
|
-
console.log(` Current: ${currentSdkVersion === latestSdkVersion ? pc.green(currentSdkVersion) : pc.yellow(currentSdkVersion)}`);
|
|
213
|
-
console.log(` Latest: ${latestSdkVersion}`);
|
|
661
|
+
printInfo(`${sdkNeedsInstall ? "Installing" : "Updating"} @cortexmemory/sdk@${targetSdkVersion}...`);
|
|
214
662
|
console.log();
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
663
|
+
const exitCode = await execCommandLive("npm", ["install", `@cortexmemory/sdk@${targetSdkVersion}`], { cwd: projectPath });
|
|
664
|
+
if (exitCode === 0) {
|
|
665
|
+
printSuccess(`${sdkNeedsInstall ? "Installed" : "Updated"} @cortexmemory/sdk to ${targetSdkVersion}`);
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
printError("SDK update failed");
|
|
669
|
+
throw new Error("SDK update failed");
|
|
220
670
|
}
|
|
671
|
+
}
|
|
672
|
+
else if (currentSdkVersion !== "not installed") {
|
|
673
|
+
printSuccess("@cortexmemory/sdk is already up to date");
|
|
674
|
+
}
|
|
675
|
+
// Check for Convex patch update
|
|
676
|
+
if (convexPatchAvailable && !options.convexVersion) {
|
|
221
677
|
console.log();
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
major: parseInt(match[1]),
|
|
234
|
-
minor: parseInt(match[2]),
|
|
235
|
-
patch: parseInt(match[3]),
|
|
236
|
-
};
|
|
237
|
-
};
|
|
238
|
-
const currentConvex = parseVersion(currentConvexVersion);
|
|
239
|
-
const latestConvex = parseVersion(latestConvexVersion);
|
|
240
|
-
let convexPatchAvailable = false;
|
|
241
|
-
if (currentConvex && latestConvex) {
|
|
242
|
-
// Patch update = same major.minor, higher patch
|
|
243
|
-
convexPatchAvailable =
|
|
244
|
-
currentConvex.major === latestConvex.major &&
|
|
245
|
-
currentConvex.minor === latestConvex.minor &&
|
|
246
|
-
currentConvex.patch < latestConvex.patch;
|
|
247
|
-
}
|
|
248
|
-
const targetConvexVersion = options.convexVersion ??
|
|
249
|
-
(convexPatchAvailable ? latestConvexVersion : null);
|
|
250
|
-
const convexNeedsUpdate = targetConvexVersion && currentConvexVersion !== targetConvexVersion;
|
|
251
|
-
// Nothing to update
|
|
252
|
-
if (!sdkNeedsUpdate &&
|
|
253
|
-
!sdkNeedsInstall &&
|
|
254
|
-
!convexNeedsUpdate &&
|
|
255
|
-
!convexPatchAvailable) {
|
|
256
|
-
printSuccess("All packages are up to date!");
|
|
257
|
-
return;
|
|
678
|
+
console.log(pc.cyan(` Convex patch update available: ${currentConvexVersion} → ${latestConvexVersion}`));
|
|
679
|
+
let shouldUpdate = options.yes;
|
|
680
|
+
if (!shouldUpdate) {
|
|
681
|
+
const { default: prompts } = await import("prompts");
|
|
682
|
+
const response = await prompts({
|
|
683
|
+
type: "confirm",
|
|
684
|
+
name: "update",
|
|
685
|
+
message: "Update Convex to latest patch version?",
|
|
686
|
+
initial: true,
|
|
687
|
+
});
|
|
688
|
+
shouldUpdate = response.update;
|
|
258
689
|
}
|
|
259
|
-
|
|
260
|
-
if (sdkNeedsUpdate || sdkNeedsInstall) {
|
|
690
|
+
if (shouldUpdate) {
|
|
261
691
|
console.log();
|
|
262
|
-
printInfo(
|
|
692
|
+
printInfo(`Updating convex@${latestConvexVersion}...`);
|
|
263
693
|
console.log();
|
|
264
|
-
const exitCode = await execCommandLive("npm", ["install",
|
|
694
|
+
const exitCode = await execCommandLive("npm", ["install", `convex@${latestConvexVersion}`], { cwd: projectPath });
|
|
265
695
|
if (exitCode === 0) {
|
|
266
|
-
printSuccess(
|
|
696
|
+
printSuccess(`Updated convex to ${latestConvexVersion}`);
|
|
267
697
|
}
|
|
268
698
|
else {
|
|
269
|
-
|
|
270
|
-
process.exit(1);
|
|
699
|
+
printWarning("Convex update failed, but SDK update was successful");
|
|
271
700
|
}
|
|
272
701
|
}
|
|
273
|
-
else
|
|
274
|
-
|
|
702
|
+
else {
|
|
703
|
+
console.log(pc.dim(" Skipping Convex update"));
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
else if (options.convexVersion) {
|
|
707
|
+
// Explicit version requested
|
|
708
|
+
console.log();
|
|
709
|
+
printInfo(`Updating convex@${options.convexVersion}...`);
|
|
710
|
+
console.log();
|
|
711
|
+
const exitCode = await execCommandLive("npm", ["install", `convex@${options.convexVersion}`], { cwd: projectPath });
|
|
712
|
+
if (exitCode === 0) {
|
|
713
|
+
printSuccess(`Updated convex to ${options.convexVersion}`);
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
printWarning("Convex update failed");
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
console.log();
|
|
720
|
+
printSuccess("Update complete!");
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
spinner.stop();
|
|
724
|
+
throw error;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Update packages for a single app
|
|
729
|
+
*/
|
|
730
|
+
async function updateApp(name, app, options) {
|
|
731
|
+
const appPath = path.join(app.projectPath, app.path);
|
|
732
|
+
const isDevMode = !!options.devPath;
|
|
733
|
+
if (!await fs.pathExists(appPath)) {
|
|
734
|
+
printError(`App path not found: ${appPath}`);
|
|
735
|
+
throw new Error(`App path not found: ${appPath}`);
|
|
736
|
+
}
|
|
737
|
+
const spinner = ora("Checking for updates...").start();
|
|
738
|
+
try {
|
|
739
|
+
// Read package.json
|
|
740
|
+
const packageJsonPath = path.join(appPath, "package.json");
|
|
741
|
+
if (!await fs.pathExists(packageJsonPath)) {
|
|
742
|
+
spinner.stop();
|
|
743
|
+
printError(`No package.json found at ${appPath}`);
|
|
744
|
+
throw new Error(`No package.json found at ${appPath}`);
|
|
745
|
+
}
|
|
746
|
+
const pkg = await fs.readJson(packageJsonPath);
|
|
747
|
+
// Check current versions
|
|
748
|
+
let currentSdkVersion = "not installed";
|
|
749
|
+
let currentProviderVersion = "not installed";
|
|
750
|
+
let currentConvexVersion = "not installed";
|
|
751
|
+
let currentAiVersion = "not installed";
|
|
752
|
+
let isDevLinked = false;
|
|
753
|
+
// Check if already dev-linked
|
|
754
|
+
const sdkDep = pkg.dependencies?.["@cortexmemory/sdk"];
|
|
755
|
+
const providerDep = pkg.dependencies?.["@cortexmemory/vercel-ai-provider"];
|
|
756
|
+
isDevLinked = sdkDep?.startsWith("file:") || providerDep?.startsWith("file:");
|
|
757
|
+
// Get installed versions
|
|
758
|
+
try {
|
|
759
|
+
const result = await execCommand("npm", ["list", "@cortexmemory/sdk", "@cortexmemory/vercel-ai-provider", "convex", "ai", "--json"], { quiet: true, cwd: appPath });
|
|
760
|
+
const data = JSON.parse(result.stdout);
|
|
761
|
+
currentSdkVersion =
|
|
762
|
+
data.dependencies?.["@cortexmemory/sdk"]?.version ?? "not installed";
|
|
763
|
+
currentProviderVersion =
|
|
764
|
+
data.dependencies?.["@cortexmemory/vercel-ai-provider"]?.version ?? "not installed";
|
|
765
|
+
currentConvexVersion =
|
|
766
|
+
data.dependencies?.convex?.version ?? "not installed";
|
|
767
|
+
currentAiVersion =
|
|
768
|
+
data.dependencies?.ai?.version ?? "not installed";
|
|
769
|
+
}
|
|
770
|
+
catch {
|
|
771
|
+
// Ignore errors
|
|
772
|
+
}
|
|
773
|
+
// Get latest versions from npm
|
|
774
|
+
let latestSdkVersion = "unknown";
|
|
775
|
+
let latestProviderVersion = "unknown";
|
|
776
|
+
let latestConvexVersion = "unknown";
|
|
777
|
+
let latestAiVersion = "unknown";
|
|
778
|
+
try {
|
|
779
|
+
const [sdkResult, providerResult, convexResult, aiResult] = await Promise.all([
|
|
780
|
+
execCommand("npm", ["view", "@cortexmemory/sdk", "version"], { quiet: true }).catch(() => ({ stdout: "unknown" })),
|
|
781
|
+
execCommand("npm", ["view", "@cortexmemory/vercel-ai-provider", "version"], { quiet: true }).catch(() => ({ stdout: "unknown" })),
|
|
782
|
+
execCommand("npm", ["view", "convex", "version"], { quiet: true }).catch(() => ({ stdout: "unknown" })),
|
|
783
|
+
execCommand("npm", ["view", "ai", "version"], { quiet: true }).catch(() => ({ stdout: "unknown" })),
|
|
784
|
+
]);
|
|
785
|
+
latestSdkVersion = sdkResult.stdout.trim() || "unknown";
|
|
786
|
+
latestProviderVersion = providerResult.stdout.trim() || "unknown";
|
|
787
|
+
latestConvexVersion = convexResult.stdout.trim() || "unknown";
|
|
788
|
+
latestAiVersion = aiResult.stdout.trim() || "unknown";
|
|
789
|
+
}
|
|
790
|
+
catch {
|
|
791
|
+
// Ignore errors
|
|
792
|
+
}
|
|
793
|
+
spinner.stop();
|
|
794
|
+
// Display current status
|
|
795
|
+
console.log();
|
|
796
|
+
printSection("App Package Status", {
|
|
797
|
+
App: name,
|
|
798
|
+
Type: app.type,
|
|
799
|
+
Path: appPath,
|
|
800
|
+
});
|
|
801
|
+
if (isDevMode) {
|
|
802
|
+
console.log();
|
|
803
|
+
console.log(pc.magenta(" ═══ DEV MODE ═══"));
|
|
804
|
+
console.log(pc.dim(` Will link to: ${options.devPath}`));
|
|
805
|
+
}
|
|
806
|
+
console.log();
|
|
807
|
+
console.log(pc.bold(" @cortexmemory/sdk"));
|
|
808
|
+
if (isDevLinked) {
|
|
809
|
+
console.log(` Current: ${pc.magenta("file:... (dev linked)")}`);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
console.log(` Current: ${currentSdkVersion === latestSdkVersion ? pc.green(currentSdkVersion) : pc.yellow(currentSdkVersion)}`);
|
|
813
|
+
}
|
|
814
|
+
console.log(` Latest: ${latestSdkVersion}`);
|
|
815
|
+
console.log();
|
|
816
|
+
console.log(pc.bold(" @cortexmemory/vercel-ai-provider"));
|
|
817
|
+
if (isDevLinked) {
|
|
818
|
+
console.log(` Current: ${pc.magenta("file:... (dev linked)")}`);
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
console.log(` Current: ${currentProviderVersion === latestProviderVersion ? pc.green(currentProviderVersion) : pc.yellow(currentProviderVersion)}`);
|
|
822
|
+
}
|
|
823
|
+
console.log(` Latest: ${latestProviderVersion}`);
|
|
824
|
+
console.log();
|
|
825
|
+
console.log(pc.bold(" convex"));
|
|
826
|
+
console.log(` Current: ${currentConvexVersion === latestConvexVersion ? pc.green(currentConvexVersion) : pc.yellow(currentConvexVersion)}`);
|
|
827
|
+
console.log(` Latest: ${latestConvexVersion}`);
|
|
828
|
+
console.log();
|
|
829
|
+
console.log(pc.bold(" ai (Vercel AI SDK)"));
|
|
830
|
+
console.log(` Current: ${currentAiVersion === latestAiVersion ? pc.green(currentAiVersion) : pc.yellow(currentAiVersion)}`);
|
|
831
|
+
console.log(` Latest: ${latestAiVersion}`);
|
|
832
|
+
console.log();
|
|
833
|
+
// Determine update strategy
|
|
834
|
+
if (isDevMode) {
|
|
835
|
+
// Dev mode: update package.json with file: references
|
|
836
|
+
if (isDevLinked) {
|
|
837
|
+
printSuccess("App is already dev-linked. Running npm install to refresh...");
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
printInfo("Switching to dev mode with local SDK...");
|
|
275
841
|
}
|
|
276
|
-
//
|
|
277
|
-
|
|
842
|
+
// Update package.json with file: references
|
|
843
|
+
const devSdkPath = options.devPath;
|
|
844
|
+
const devProviderPath = path.join(devSdkPath, "packages", "vercel-ai-provider");
|
|
845
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
846
|
+
pkg.dependencies["@cortexmemory/sdk"] = `file:${devSdkPath}`;
|
|
847
|
+
pkg.dependencies["@cortexmemory/vercel-ai-provider"] = `file:${devProviderPath}`;
|
|
848
|
+
await fs.writeJson(packageJsonPath, pkg, { spaces: 2 });
|
|
849
|
+
console.log(pc.cyan(" Updated package.json with file: references"));
|
|
850
|
+
// Run npm install
|
|
851
|
+
console.log();
|
|
852
|
+
printInfo("Running npm install...");
|
|
853
|
+
console.log();
|
|
854
|
+
const exitCode = await execCommandLive("npm", ["install", "--legacy-peer-deps"], { cwd: appPath });
|
|
855
|
+
if (exitCode === 0) {
|
|
278
856
|
console.log();
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
message: "Update Convex to latest patch version?",
|
|
287
|
-
initial: true,
|
|
288
|
-
});
|
|
289
|
-
shouldUpdate = response.update;
|
|
290
|
-
}
|
|
291
|
-
if (shouldUpdate) {
|
|
292
|
-
console.log();
|
|
293
|
-
printInfo(`Updating convex@${latestConvexVersion}...`);
|
|
294
|
-
console.log();
|
|
295
|
-
const exitCode = await execCommandLive("npm", ["install", `convex@${latestConvexVersion}`], { cwd: projectPath });
|
|
296
|
-
if (exitCode === 0) {
|
|
297
|
-
printSuccess(`Updated convex to ${latestConvexVersion}`);
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
printWarning("Convex update failed, but SDK update was successful");
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
console.log(pc.dim(" Skipping Convex update"));
|
|
305
|
-
}
|
|
857
|
+
printSuccess("Dev mode linking complete!");
|
|
858
|
+
console.log(pc.dim(` SDK linked to: ${devSdkPath}`));
|
|
859
|
+
console.log(pc.dim(` Provider linked to: ${devProviderPath}`));
|
|
860
|
+
}
|
|
861
|
+
else {
|
|
862
|
+
printError("npm install failed");
|
|
863
|
+
throw new Error("npm install failed");
|
|
306
864
|
}
|
|
307
|
-
|
|
308
|
-
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
// Normal mode: update to latest versions from npm
|
|
868
|
+
const targetSdkVersion = options.sdkVersion ?? latestSdkVersion;
|
|
869
|
+
const targetProviderVersion = options.providerVersion ?? latestProviderVersion;
|
|
870
|
+
// Check if we need to remove dev links first
|
|
871
|
+
if (isDevLinked) {
|
|
872
|
+
printInfo("Removing dev links and switching to npm packages...");
|
|
873
|
+
pkg.dependencies["@cortexmemory/sdk"] = `^${targetSdkVersion}`;
|
|
874
|
+
pkg.dependencies["@cortexmemory/vercel-ai-provider"] = `^${targetProviderVersion}`;
|
|
875
|
+
await fs.writeJson(packageJsonPath, pkg, { spaces: 2 });
|
|
876
|
+
console.log(pc.cyan(" Updated package.json with npm versions"));
|
|
877
|
+
}
|
|
878
|
+
// Determine what needs updating
|
|
879
|
+
const sdkNeedsUpdate = currentSdkVersion !== targetSdkVersion || isDevLinked;
|
|
880
|
+
const providerNeedsUpdate = currentProviderVersion !== targetProviderVersion || isDevLinked;
|
|
881
|
+
// Nothing to update
|
|
882
|
+
if (!sdkNeedsUpdate && !providerNeedsUpdate) {
|
|
883
|
+
printSuccess("All packages are up to date!");
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
// Build install command
|
|
887
|
+
const packagesToInstall = [];
|
|
888
|
+
if (sdkNeedsUpdate) {
|
|
889
|
+
packagesToInstall.push(`@cortexmemory/sdk@${targetSdkVersion}`);
|
|
890
|
+
}
|
|
891
|
+
if (providerNeedsUpdate) {
|
|
892
|
+
packagesToInstall.push(`@cortexmemory/vercel-ai-provider@${targetProviderVersion}`);
|
|
893
|
+
}
|
|
894
|
+
if (packagesToInstall.length > 0) {
|
|
309
895
|
console.log();
|
|
310
|
-
printInfo(`
|
|
896
|
+
printInfo(`Installing: ${packagesToInstall.join(", ")}...`);
|
|
311
897
|
console.log();
|
|
312
|
-
const exitCode = await execCommandLive("npm", ["install",
|
|
898
|
+
const exitCode = await execCommandLive("npm", ["install", ...packagesToInstall, "--legacy-peer-deps"], { cwd: appPath });
|
|
313
899
|
if (exitCode === 0) {
|
|
314
|
-
printSuccess(
|
|
900
|
+
printSuccess("Packages updated successfully");
|
|
315
901
|
}
|
|
316
902
|
else {
|
|
317
|
-
|
|
903
|
+
printError("Package update failed");
|
|
904
|
+
throw new Error("Package update failed");
|
|
318
905
|
}
|
|
319
906
|
}
|
|
320
907
|
console.log();
|
|
321
|
-
printSuccess("
|
|
908
|
+
printSuccess("Package update complete!");
|
|
322
909
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
910
|
+
// Template sync (if enabled)
|
|
911
|
+
if (options.syncTemplate) {
|
|
912
|
+
console.log();
|
|
913
|
+
printSection("Template Sync", {});
|
|
914
|
+
console.log();
|
|
915
|
+
try {
|
|
916
|
+
const templateResult = await syncAppTemplate(app, { dryRun: false });
|
|
917
|
+
if (templateResult.error) {
|
|
918
|
+
printWarning(`Template sync skipped: ${templateResult.error}`);
|
|
919
|
+
}
|
|
920
|
+
else if (templateResult.synced) {
|
|
921
|
+
printTemplateSyncResult(templateResult);
|
|
922
|
+
// Run npm install if package.json was updated with new dependencies
|
|
923
|
+
if (templateResult.packageJsonUpdated) {
|
|
924
|
+
const totalNewDeps = templateResult.depsAdded.length + templateResult.devDepsAdded.length;
|
|
925
|
+
if (totalNewDeps > 0) {
|
|
926
|
+
console.log();
|
|
927
|
+
printInfo(`Installing ${totalNewDeps} new dependencies...`);
|
|
928
|
+
console.log(pc.dim(` Running in: ${templateResult.appPath}`));
|
|
929
|
+
console.log();
|
|
930
|
+
const exitCode = await execCommandLive("npm", ["install", "--legacy-peer-deps"], { cwd: templateResult.appPath });
|
|
931
|
+
if (exitCode === 0) {
|
|
932
|
+
printSuccess("Dependencies installed");
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
printWarning("npm install failed - you may need to run it manually");
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
else {
|
|
941
|
+
console.log(pc.dim(" Template files are up to date"));
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
catch (error) {
|
|
945
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
946
|
+
printWarning(`Template sync failed: ${message}`);
|
|
947
|
+
}
|
|
327
948
|
}
|
|
328
|
-
|
|
949
|
+
console.log();
|
|
950
|
+
printSuccess("Update complete!");
|
|
951
|
+
}
|
|
952
|
+
catch (error) {
|
|
953
|
+
spinner.stop();
|
|
954
|
+
throw error;
|
|
955
|
+
}
|
|
329
956
|
}
|
|
330
957
|
//# sourceMappingURL=deploy.js.map
|