@cortexmemory/cli 0.1.1 → 0.22.0

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.
Files changed (103) hide show
  1. package/README.md +8 -0
  2. package/dist/commands/conversations.d.ts +1 -1
  3. package/dist/commands/conversations.d.ts.map +1 -1
  4. package/dist/commands/conversations.js +57 -27
  5. package/dist/commands/conversations.js.map +1 -1
  6. package/dist/commands/convex.d.ts +1 -1
  7. package/dist/commands/convex.d.ts.map +1 -1
  8. package/dist/commands/convex.js +237 -64
  9. package/dist/commands/convex.js.map +1 -1
  10. package/dist/commands/db.d.ts +1 -1
  11. package/dist/commands/db.d.ts.map +1 -1
  12. package/dist/commands/db.js +59 -109
  13. package/dist/commands/db.js.map +1 -1
  14. package/dist/commands/dev.d.ts +8 -8
  15. package/dist/commands/dev.d.ts.map +1 -1
  16. package/dist/commands/dev.js +734 -513
  17. package/dist/commands/dev.js.map +1 -1
  18. package/dist/commands/facts.d.ts +1 -1
  19. package/dist/commands/facts.d.ts.map +1 -1
  20. package/dist/commands/facts.js +50 -21
  21. package/dist/commands/facts.js.map +1 -1
  22. package/dist/commands/init.d.ts +28 -0
  23. package/dist/commands/init.d.ts.map +1 -0
  24. package/dist/commands/init.js +895 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/memory.d.ts +1 -1
  27. package/dist/commands/memory.d.ts.map +1 -1
  28. package/dist/commands/memory.js +64 -27
  29. package/dist/commands/memory.js.map +1 -1
  30. package/dist/commands/setup.d.ts +4 -5
  31. package/dist/commands/setup.d.ts.map +1 -1
  32. package/dist/commands/setup.js +428 -250
  33. package/dist/commands/setup.js.map +1 -1
  34. package/dist/commands/spaces.d.ts +1 -1
  35. package/dist/commands/spaces.d.ts.map +1 -1
  36. package/dist/commands/spaces.js +100 -43
  37. package/dist/commands/spaces.js.map +1 -1
  38. package/dist/commands/status.d.ts +17 -0
  39. package/dist/commands/status.d.ts.map +1 -0
  40. package/dist/commands/status.js +314 -0
  41. package/dist/commands/status.js.map +1 -0
  42. package/dist/commands/users.d.ts +1 -1
  43. package/dist/commands/users.d.ts.map +1 -1
  44. package/dist/commands/users.js +80 -42
  45. package/dist/commands/users.js.map +1 -1
  46. package/dist/index.js +42 -14
  47. package/dist/index.js.map +1 -1
  48. package/dist/types.d.ts +11 -0
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/utils/__tests__/client.test.d.ts +5 -0
  51. package/dist/utils/__tests__/client.test.d.ts.map +1 -0
  52. package/dist/utils/__tests__/client.test.js +88 -0
  53. package/dist/utils/__tests__/client.test.js.map +1 -0
  54. package/dist/utils/__tests__/env-file.test.d.ts +7 -0
  55. package/dist/utils/__tests__/env-file.test.d.ts.map +1 -0
  56. package/dist/utils/__tests__/env-file.test.js +196 -0
  57. package/dist/utils/__tests__/env-file.test.js.map +1 -0
  58. package/dist/utils/__tests__/shell.test.d.ts +7 -0
  59. package/dist/utils/__tests__/shell.test.d.ts.map +1 -0
  60. package/dist/utils/__tests__/shell.test.js +89 -0
  61. package/dist/utils/__tests__/shell.test.js.map +1 -0
  62. package/dist/utils/config.d.ts.map +1 -1
  63. package/dist/utils/config.js +12 -39
  64. package/dist/utils/config.js.map +1 -1
  65. package/dist/utils/deployment-selector.d.ts +50 -0
  66. package/dist/utils/deployment-selector.d.ts.map +1 -0
  67. package/dist/utils/deployment-selector.js +129 -0
  68. package/dist/utils/deployment-selector.js.map +1 -0
  69. package/dist/utils/init/convex-setup.d.ts +30 -0
  70. package/dist/utils/init/convex-setup.d.ts.map +1 -0
  71. package/dist/utils/init/convex-setup.js +225 -0
  72. package/dist/utils/init/convex-setup.js.map +1 -0
  73. package/dist/utils/init/env-generator.d.ts +32 -0
  74. package/dist/utils/init/env-generator.d.ts.map +1 -0
  75. package/dist/utils/init/env-generator.js +210 -0
  76. package/dist/utils/init/env-generator.js.map +1 -0
  77. package/dist/utils/init/file-operations.d.ts +22 -0
  78. package/dist/utils/init/file-operations.d.ts.map +1 -0
  79. package/dist/utils/init/file-operations.js +211 -0
  80. package/dist/utils/init/file-operations.js.map +1 -0
  81. package/dist/utils/init/graph-setup.d.ts +35 -0
  82. package/dist/utils/init/graph-setup.d.ts.map +1 -0
  83. package/dist/utils/init/graph-setup.js +413 -0
  84. package/dist/utils/init/graph-setup.js.map +1 -0
  85. package/dist/utils/init/index.d.ts +11 -0
  86. package/dist/utils/init/index.d.ts.map +1 -0
  87. package/dist/utils/init/index.js +11 -0
  88. package/dist/utils/init/index.js.map +1 -0
  89. package/dist/utils/init/types.d.ts +73 -0
  90. package/dist/utils/init/types.d.ts.map +1 -0
  91. package/dist/utils/init/types.js +5 -0
  92. package/dist/utils/init/types.js.map +1 -0
  93. package/dist/utils/shell.d.ts +60 -0
  94. package/dist/utils/shell.d.ts.map +1 -0
  95. package/dist/utils/shell.js +188 -0
  96. package/dist/utils/shell.js.map +1 -0
  97. package/package.json +25 -20
  98. package/templates/basic/README.md +105 -0
  99. package/templates/basic/dev-runner.mjs +215 -0
  100. package/templates/basic/package-lock.json +1263 -0
  101. package/templates/basic/package.json +22 -0
  102. package/templates/basic/src/index.ts +85 -0
  103. package/templates/basic/tsconfig.json +17 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Shell Execution Utilities
3
+ *
4
+ * Shared utilities for executing shell commands safely.
5
+ * Used by init wizard and other CLI commands.
6
+ */
7
+ import { spawn } from "child_process";
8
+ import { existsSync, readdirSync } from "fs";
9
+ import path from "path";
10
+ import { createRequire } from "module";
11
+ // Create require function for ES modules
12
+ const require = createRequire(import.meta.url);
13
+ /**
14
+ * Allowlist of safe commands that can be executed
15
+ */
16
+ const ALLOWED_COMMANDS = [
17
+ "npx",
18
+ "convex",
19
+ "npm",
20
+ "pnpm",
21
+ "yarn",
22
+ "bun",
23
+ "git",
24
+ "node",
25
+ "docker",
26
+ // Process inspection commands (for kill menu)
27
+ "lsof",
28
+ "pgrep",
29
+ "ps",
30
+ ];
31
+ /**
32
+ * Check if a command exists in the system
33
+ */
34
+ export async function commandExists(command) {
35
+ return new Promise((resolve) => {
36
+ // Use platform-specific command (which for Unix, where for Windows)
37
+ const cmd = process.platform === "win32" ? "where" : "which";
38
+ const child = spawn(cmd, [command]);
39
+ child.on("close", (code) => resolve(code === 0));
40
+ });
41
+ }
42
+ /**
43
+ * Execute a shell command and return the output
44
+ *
45
+ * SECURITY: This function only executes commands from an allowlist.
46
+ * User input is NEVER passed as the command parameter.
47
+ */
48
+ export async function execCommand(command, args, options = {}) {
49
+ // Validate command is from allowlist (defense in depth)
50
+ if (!ALLOWED_COMMANDS.includes(command)) {
51
+ throw new Error(`Invalid command: ${command}. Only allowed: ${ALLOWED_COMMANDS.join(", ")}`);
52
+ }
53
+ return new Promise((resolve, reject) => {
54
+ const child = spawn(command, args, {
55
+ cwd: options.cwd,
56
+ env: { ...process.env, ...options.env },
57
+ });
58
+ let stdout = "";
59
+ let stderr = "";
60
+ child.stdout?.on("data", (data) => {
61
+ const str = data.toString();
62
+ stdout += str;
63
+ if (!options.quiet) {
64
+ process.stdout.write(str);
65
+ }
66
+ });
67
+ child.stderr?.on("data", (data) => {
68
+ const str = data.toString();
69
+ stderr += str;
70
+ if (!options.quiet) {
71
+ process.stderr.write(str);
72
+ }
73
+ });
74
+ child.on("error", (error) => {
75
+ reject(error);
76
+ });
77
+ child.on("close", (code) => {
78
+ resolve({ stdout, stderr, code: code ?? 1 });
79
+ });
80
+ });
81
+ }
82
+ /**
83
+ * Execute a command with live output (stdio: inherit)
84
+ *
85
+ * SECURITY: This function only executes commands from an allowlist.
86
+ * User input is NEVER passed as the command parameter.
87
+ */
88
+ export async function execCommandLive(command, args, options = {}) {
89
+ // Validate command is from allowlist (defense in depth)
90
+ if (!ALLOWED_COMMANDS.includes(command)) {
91
+ throw new Error(`Invalid command: ${command}. Only allowed: ${ALLOWED_COMMANDS.join(", ")}`);
92
+ }
93
+ return new Promise((resolve, reject) => {
94
+ const child = spawn(command, args, {
95
+ cwd: options.cwd,
96
+ stdio: "inherit",
97
+ env: { ...process.env, ...options.env },
98
+ });
99
+ child.on("error", (error) => {
100
+ reject(error);
101
+ });
102
+ child.on("close", (code) => {
103
+ resolve(code ?? 1);
104
+ });
105
+ });
106
+ }
107
+ /**
108
+ * Validate project name
109
+ */
110
+ export function isValidProjectName(name) {
111
+ return /^[a-z0-9-_]+$/.test(name);
112
+ }
113
+ /**
114
+ * Check if directory is empty
115
+ */
116
+ export function isDirectoryEmpty(dirPath) {
117
+ if (!existsSync(dirPath)) {
118
+ return true;
119
+ }
120
+ const files = readdirSync(dirPath);
121
+ return files.length === 0 || (files.length === 1 && files[0] === ".git");
122
+ }
123
+ /**
124
+ * Get the path to the installed SDK package
125
+ * @param projectPath - Optional project path to look in (defaults to current directory)
126
+ */
127
+ export function getSDKPath(projectPath) {
128
+ try {
129
+ // If projectPath provided, look in that project's node_modules
130
+ if (projectPath) {
131
+ const sdkPath = path.join(projectPath, "node_modules", "@cortexmemory", "sdk");
132
+ if (existsSync(sdkPath)) {
133
+ return sdkPath;
134
+ }
135
+ }
136
+ // Fallback: use require.resolve from current location
137
+ const sdkPackageJson = require.resolve("@cortexmemory/sdk/package.json");
138
+ return path.dirname(sdkPackageJson);
139
+ }
140
+ catch {
141
+ return null;
142
+ }
143
+ }
144
+ /**
145
+ * Parse Convex URL to determine if it's local or cloud
146
+ */
147
+ export function isLocalConvexUrl(url) {
148
+ return url.includes("localhost") || url.includes("127.0.0.1");
149
+ }
150
+ /**
151
+ * Fetch the latest SDK package.json from npm registry
152
+ */
153
+ export async function fetchLatestSDKMetadata() {
154
+ try {
155
+ const result = await execCommand("npm", [
156
+ "view",
157
+ "@cortexmemory/sdk",
158
+ "peerDependencies.convex",
159
+ "version",
160
+ "--json",
161
+ ], { quiet: true });
162
+ if (result.code !== 0) {
163
+ throw new Error(`npm view failed: ${result.stderr}`);
164
+ }
165
+ const data = JSON.parse(result.stdout);
166
+ let convexVersion;
167
+ let sdkVersion;
168
+ if (typeof data === "string") {
169
+ throw new Error("Unexpected npm view response format");
170
+ }
171
+ else {
172
+ convexVersion = data["peerDependencies.convex"] || "^1.29.3";
173
+ sdkVersion = data["version"] || "latest";
174
+ }
175
+ return {
176
+ convexVersion,
177
+ sdkVersion,
178
+ };
179
+ }
180
+ catch {
181
+ // Fallback to safe defaults
182
+ return {
183
+ convexVersion: "^1.29.3",
184
+ sdkVersion: "latest",
185
+ };
186
+ }
187
+ }
188
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@cortexmemory/cli",
3
- "version": "0.1.1",
3
+ "version": "0.22.0",
4
4
  "description": "CLI tool for managing Cortex Memory deployments, performing administrative tasks, and streamlining development workflows",
5
5
  "type": "module",
6
6
  "bin": {
7
- "cortex": "./dist/index.js"
7
+ "cortex": "dist/index.js"
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -20,8 +20,11 @@
20
20
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
21
21
  "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
22
22
  "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
23
- "test:unit": "node --experimental-vm-modules node_modules/jest/bin/jest.js src/utils/__tests__",
24
- "test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js tests/",
23
+ "test:unit": "node --experimental-vm-modules node_modules/jest/bin/jest.js --selectProjects unit",
24
+ "test:commands": "node --experimental-vm-modules node_modules/jest/bin/jest.js --selectProjects commands",
25
+ "test:e2e": "node --experimental-vm-modules node_modules/jest/bin/jest.js --selectProjects e2e",
26
+ "test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js --selectProjects e2e",
27
+ "test:fast": "node --experimental-vm-modules node_modules/jest/bin/jest.js --selectProjects unit commands",
25
28
  "typecheck": "tsc --noEmit",
26
29
  "prepublishOnly": "npm run lint && npm run build && npm run test:unit"
27
30
  },
@@ -39,7 +42,7 @@
39
42
  "license": "Apache-2.0",
40
43
  "repository": {
41
44
  "type": "git",
42
- "url": "https://github.com/SaintNick1214/Project-Cortex.git",
45
+ "url": "git+https://github.com/SaintNick1214/Project-Cortex.git",
43
46
  "directory": "packages/cortex-cli"
44
47
  },
45
48
  "publishConfig": {
@@ -51,28 +54,30 @@
51
54
  "node": ">=20"
52
55
  },
53
56
  "dependencies": {
54
- "@cortexmemory/sdk": "^0.16.0",
55
- "commander": "^14.0.2",
56
- "prompts": "^2.4.2",
57
- "picocolors": "^1.1.1",
58
- "ora": "^9.0.0",
57
+ "@cortexmemory/sdk": "file:../../cortexmemory-sdk-0.21.0.tgz",
59
58
  "cli-table3": "^0.6.5",
59
+ "commander": "^14.0.2",
60
+ "convex": "^1.31.2",
60
61
  "cosmiconfig": "^9.0.0",
61
- "convex": "^1.30.0",
62
62
  "dotenv": "^17.2.3",
63
- "neo4j-driver": "^6.0.1"
63
+ "fs-extra": "^11.3.3",
64
+ "neo4j-driver": "^6.0.1",
65
+ "ora": "^9.0.0",
66
+ "picocolors": "^1.1.1",
67
+ "prompts": "^2.4.2"
64
68
  },
65
69
  "devDependencies": {
70
+ "@eslint/js": "^9.39.2",
71
+ "@types/fs-extra": "^11.0.4",
72
+ "@types/jest": "^30.0.0",
73
+ "@types/node": "^25.0.3",
66
74
  "@types/prompts": "^2.4.9",
67
- "@types/node": "^24.10.1",
68
- "typescript": "^5.9.3",
69
- "eslint": "^9.39.1",
70
- "@eslint/js": "^9.39.1",
71
- "@typescript-eslint/eslint-plugin": "^8.48.1",
72
- "@typescript-eslint/parser": "^8.48.1",
75
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
76
+ "@typescript-eslint/parser": "^8.50.0",
77
+ "eslint": "^9.39.2",
73
78
  "globals": "^16.5.0",
74
79
  "jest": "^30.2.0",
75
- "@types/jest": "^30.0.0",
76
- "ts-jest": "^29.4.6"
80
+ "ts-jest": "^29.4.6",
81
+ "typescript": "^5.9.3"
77
82
  }
78
83
  }
@@ -0,0 +1,105 @@
1
+ # {{PROJECT_NAME}}
2
+
3
+ AI agent with persistent memory powered by [Cortex Memory SDK](https://github.com/SaintNick1214/Project-Cortex).
4
+
5
+ ## Getting Started
6
+
7
+ Your Convex backend functions are deployed and configured!
8
+
9
+ ### For Local Development
10
+
11
+ **Terminal 1** - Start Convex:
12
+
13
+ ```bash
14
+ npm run dev
15
+ ```
16
+
17
+ Leave this running. It watches for changes and keeps Convex server active.
18
+
19
+ **Terminal 2** - Run your agent:
20
+
21
+ ```bash
22
+ npm start
23
+ ```
24
+
25
+ ### For Cloud Deployments
26
+
27
+ Your Convex is already running in the cloud, so just:
28
+
29
+ ```bash
30
+ npm start
31
+ ```
32
+
33
+ ## Project Structure
34
+
35
+ ```
36
+ .
37
+ ├── src/
38
+ │ └── index.ts # Your AI agent code
39
+ ├── convex/ # Cortex backend functions (deployed to Convex)
40
+ │ ├── schema.ts # Database schema
41
+ │ ├── conversations.ts # Conversation management
42
+ │ ├── memories.ts # Memory storage and search
43
+ │ └── ... # Other Cortex functions
44
+ ├── .env.local # Environment configuration (not committed)
45
+ └── package.json
46
+ ```
47
+
48
+ ## What You Get
49
+
50
+ - **Persistent Memory** - Your agent remembers conversations indefinitely
51
+ - **Semantic Search** - Find relevant memories using natural language
52
+ - **ACID Storage** - Reliable, consistent data storage
53
+ - **Vector Search** - Optional embedding-based search (cloud only)
54
+ - **User Profiles** - Manage user data and preferences
55
+ - **Multi-Agent Support** - Coordinate between multiple agents
56
+
57
+ ## Next Steps
58
+
59
+ ### Add Vector Embeddings
60
+
61
+ For semantic search, add an embedding provider:
62
+
63
+ ```typescript
64
+ import OpenAI from "openai";
65
+
66
+ const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
67
+
68
+ await cortex.memory.remember({
69
+ memorySpaceId: "my-agent",
70
+ conversationId: "conv-1",
71
+ userMessage: "message",
72
+ agentResponse: "response",
73
+ userId: "user-1",
74
+ userName: "User",
75
+ generateEmbedding: async (text) => {
76
+ const result = await openai.embeddings.create({
77
+ model: "text-embedding-3-small",
78
+ input: text,
79
+ });
80
+ return result.data[0].embedding;
81
+ },
82
+ });
83
+ ```
84
+
85
+ ### Enable Graph Database
86
+
87
+ For advanced relationship queries, set up a graph database:
88
+
89
+ 1. Start Neo4j: `docker-compose -f docker-compose.graph.yml up -d`
90
+ 2. See `src/graph-init.example.ts` for setup code
91
+
92
+ ### Learn More
93
+
94
+ - [Documentation](https://github.com/SaintNick1214/Project-Cortex/tree/main/Documentation)
95
+ - [API Reference](https://github.com/SaintNick1214/Project-Cortex/tree/main/Documentation/03-api-reference)
96
+ - [Examples](https://github.com/SaintNick1214/Project-Cortex/tree/main/Examples)
97
+
98
+ ## Support
99
+
100
+ - [GitHub Issues](https://github.com/SaintNick1214/Project-Cortex/issues)
101
+ - [GitHub Discussions](https://github.com/SaintNick1214/Project-Cortex/discussions)
102
+
103
+ ## License
104
+
105
+ Apache-2.0
@@ -0,0 +1,215 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable no-undef */
3
+ /**
4
+ * Development runner for Cortex projects
5
+ * Starts Convex in watch mode
6
+ */
7
+
8
+ import { spawn } from "child_process";
9
+ import { config } from "dotenv";
10
+ import { existsSync } from "fs";
11
+
12
+ // Load environment variables
13
+ config({ path: ".env.local" });
14
+
15
+ const CONVEX_URL = process.env.CONVEX_URL || "";
16
+ const isLocal =
17
+ CONVEX_URL.includes("localhost") || CONVEX_URL.includes("127.0.0.1");
18
+ const hasGraphConfig = process.env.NEO4J_URI || process.env.NEO4J_USERNAME;
19
+ const hasDockerCompose = existsSync("./docker-compose.graph.yml");
20
+
21
+ console.log("🚀 Starting Cortex development environment...\n");
22
+
23
+ // Start graph database if configured
24
+ if (hasGraphConfig && hasDockerCompose) {
25
+ console.log("🕸️ Starting graph database...");
26
+
27
+ // First check if Docker daemon is running
28
+ const dockerCheck = spawn("docker", ["info"], { stdio: "pipe" });
29
+
30
+ const dockerRunning = await new Promise((resolve) => {
31
+ let stderr = "";
32
+ dockerCheck.stderr?.on("data", (data) => {
33
+ stderr += data.toString();
34
+ });
35
+
36
+ dockerCheck.on("close", (code) => {
37
+ if (
38
+ code !== 0 &&
39
+ stderr.includes("Cannot connect to the Docker daemon")
40
+ ) {
41
+ console.log(" ❌ Docker is not running");
42
+ console.log(" 💡 Start Docker Desktop and run npm run dev again");
43
+ console.log("");
44
+ resolve(false);
45
+ } else {
46
+ resolve(true);
47
+ }
48
+ });
49
+
50
+ dockerCheck.on("error", () => {
51
+ console.log(" ⚠️ Docker not installed");
52
+ console.log(" 💡 Install: https://docker.com/products/docker-desktop");
53
+ console.log("");
54
+ resolve(false);
55
+ });
56
+ });
57
+
58
+ if (!dockerRunning) {
59
+ // Skip graph database startup
60
+ } else {
61
+ // Docker is running, start/restart containers
62
+ // Use 'up -d' which will start existing stopped containers or create new ones
63
+ const dockerUp = spawn(
64
+ "docker-compose",
65
+ ["-f", "docker-compose.graph.yml", "up", "-d", "--remove-orphans"],
66
+ {
67
+ stdio: "pipe",
68
+ },
69
+ );
70
+
71
+ await new Promise((resolve) => {
72
+ let stdout = "";
73
+ let stderr = "";
74
+
75
+ dockerUp.stdout?.on("data", (data) => {
76
+ stdout += data.toString();
77
+ });
78
+
79
+ dockerUp.stderr?.on("data", (data) => {
80
+ stderr += data.toString();
81
+ });
82
+
83
+ dockerUp.on("close", (code) => {
84
+ if (code === 0) {
85
+ // Check if containers started or were already running
86
+ if (stdout.includes("Running") || stdout.includes("Started")) {
87
+ if (stdout.includes("Running")) {
88
+ console.log(" ✓ Graph database already running");
89
+ } else {
90
+ console.log(" ✓ Graph database started");
91
+ }
92
+
93
+ if (
94
+ process.env.NEO4J_URI?.includes("neo4j") ||
95
+ stdout.includes("neo4j")
96
+ ) {
97
+ console.log(" Browser: http://localhost:7474");
98
+ } else {
99
+ console.log(" Lab: http://localhost:3000");
100
+ }
101
+ } else {
102
+ console.log(" ✓ Graph database ready");
103
+ }
104
+ } else {
105
+ console.log(" ⚠️ Failed to start graph database");
106
+
107
+ // Check common issues
108
+ if (stderr.includes("Cannot connect to the Docker daemon")) {
109
+ console.log(" ❌ Docker is not running");
110
+ console.log(" 💡 Start Docker Desktop and try again");
111
+ } else if (
112
+ stderr.includes("already in use") ||
113
+ stderr.includes("Conflict")
114
+ ) {
115
+ console.log(
116
+ " ⚠️ Container name conflict (old stopped container)",
117
+ );
118
+ console.log(" 💡 Fix: docker rm cortex-neo4j cortex-memgraph");
119
+ console.log(" Then run: npm run dev");
120
+ } else if (stderr.includes("already running")) {
121
+ console.log(" ✓ Container already running (that's fine!)");
122
+ } else if (stderr) {
123
+ console.log(
124
+ " Error:",
125
+ stderr.split("\n").find((l) => l.trim()) || stderr.split("\n")[0],
126
+ );
127
+ }
128
+ }
129
+ resolve();
130
+ });
131
+
132
+ dockerUp.on("error", () => {
133
+ console.log(" ⚠️ docker-compose command not found");
134
+ console.log(
135
+ " 💡 Install Docker Desktop: https://docker.com/products/docker-desktop",
136
+ );
137
+ resolve();
138
+ });
139
+ });
140
+ console.log("");
141
+ }
142
+ }
143
+
144
+ if (isLocal) {
145
+ console.log("📝 Mode: LOCAL");
146
+ console.log("🌐 Convex: http://127.0.0.1:3210");
147
+ } else {
148
+ console.log("📝 Mode: CLOUD");
149
+ console.log("🌐 Convex:", CONVEX_URL);
150
+ }
151
+
152
+ console.log("\n🔄 Watching for changes...");
153
+ console.log(" Press Ctrl+C to stop\n");
154
+
155
+ // Start Convex dev in watch mode
156
+ const args = ["convex", "dev"];
157
+
158
+ if (isLocal) {
159
+ args.push("--url", "http://127.0.0.1:3210");
160
+ }
161
+
162
+ const child = spawn("npx", args, {
163
+ stdio: "inherit",
164
+ env: process.env,
165
+ });
166
+
167
+ child.on("error", (err) => {
168
+ console.error("❌ Failed to start Convex:", err);
169
+ process.exit(1);
170
+ });
171
+
172
+ child.on("close", (code) => {
173
+ if (code !== 0 && !stopping) {
174
+ // Only show error if we're not intentionally stopping
175
+ console.error(`\n❌ Convex exited unexpectedly with code ${code}`);
176
+ process.exit(code);
177
+ }
178
+ });
179
+
180
+ // Handle Ctrl+C
181
+ let stopping = false;
182
+ process.on("SIGINT", () => {
183
+ if (stopping) return; // Prevent double execution
184
+ stopping = true;
185
+
186
+ console.log("\n\n👋 Stopping development environment...");
187
+
188
+ // Kill Convex gracefully
189
+ child.kill("SIGTERM");
190
+
191
+ // Stop graph database if it was started
192
+ if (hasGraphConfig && hasDockerCompose) {
193
+ console.log("🕸️ Stopping graph database...");
194
+ const dockerDown = spawn(
195
+ "docker-compose",
196
+ ["-f", "docker-compose.graph.yml", "stop"],
197
+ {
198
+ stdio: "pipe",
199
+ },
200
+ );
201
+
202
+ dockerDown.on("close", () => {
203
+ console.log(" ✓ Graph database stopped");
204
+ process.exit(0);
205
+ });
206
+
207
+ // Timeout after 5 seconds
208
+ setTimeout(() => {
209
+ console.log(" ⏱️ Timeout - forcing exit");
210
+ process.exit(0);
211
+ }, 5000);
212
+ } else {
213
+ process.exit(0);
214
+ }
215
+ });