@cortexmemory/cli 0.1.1 → 0.22.1
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/README.md +8 -0
- package/dist/commands/conversations.d.ts +1 -1
- package/dist/commands/conversations.d.ts.map +1 -1
- package/dist/commands/conversations.js +57 -27
- package/dist/commands/conversations.js.map +1 -1
- package/dist/commands/convex.d.ts +1 -1
- package/dist/commands/convex.d.ts.map +1 -1
- package/dist/commands/convex.js +237 -64
- package/dist/commands/convex.js.map +1 -1
- package/dist/commands/db.d.ts +1 -1
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +59 -109
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/dev.d.ts +8 -8
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +734 -513
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/facts.d.ts +1 -1
- package/dist/commands/facts.d.ts.map +1 -1
- package/dist/commands/facts.js +50 -21
- package/dist/commands/facts.js.map +1 -1
- package/dist/commands/init.d.ts +28 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +895 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/memory.d.ts +1 -1
- package/dist/commands/memory.d.ts.map +1 -1
- package/dist/commands/memory.js +64 -27
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/setup.d.ts +4 -5
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +428 -250
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/spaces.d.ts +1 -1
- package/dist/commands/spaces.d.ts.map +1 -1
- package/dist/commands/spaces.js +100 -43
- package/dist/commands/spaces.js.map +1 -1
- package/dist/commands/status.d.ts +17 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +314 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/users.d.ts +1 -1
- package/dist/commands/users.d.ts.map +1 -1
- package/dist/commands/users.js +80 -42
- package/dist/commands/users.js.map +1 -1
- package/dist/index.js +42 -14
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/__tests__/client.test.d.ts +5 -0
- package/dist/utils/__tests__/client.test.d.ts.map +1 -0
- package/dist/utils/__tests__/client.test.js +88 -0
- package/dist/utils/__tests__/client.test.js.map +1 -0
- package/dist/utils/__tests__/env-file.test.d.ts +7 -0
- package/dist/utils/__tests__/env-file.test.d.ts.map +1 -0
- package/dist/utils/__tests__/env-file.test.js +196 -0
- package/dist/utils/__tests__/env-file.test.js.map +1 -0
- package/dist/utils/__tests__/shell.test.d.ts +7 -0
- package/dist/utils/__tests__/shell.test.d.ts.map +1 -0
- package/dist/utils/__tests__/shell.test.js +89 -0
- package/dist/utils/__tests__/shell.test.js.map +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -39
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/deployment-selector.d.ts +50 -0
- package/dist/utils/deployment-selector.d.ts.map +1 -0
- package/dist/utils/deployment-selector.js +129 -0
- package/dist/utils/deployment-selector.js.map +1 -0
- package/dist/utils/init/convex-setup.d.ts +30 -0
- package/dist/utils/init/convex-setup.d.ts.map +1 -0
- package/dist/utils/init/convex-setup.js +225 -0
- package/dist/utils/init/convex-setup.js.map +1 -0
- package/dist/utils/init/env-generator.d.ts +32 -0
- package/dist/utils/init/env-generator.d.ts.map +1 -0
- package/dist/utils/init/env-generator.js +210 -0
- package/dist/utils/init/env-generator.js.map +1 -0
- package/dist/utils/init/file-operations.d.ts +22 -0
- package/dist/utils/init/file-operations.d.ts.map +1 -0
- package/dist/utils/init/file-operations.js +211 -0
- package/dist/utils/init/file-operations.js.map +1 -0
- package/dist/utils/init/graph-setup.d.ts +35 -0
- package/dist/utils/init/graph-setup.d.ts.map +1 -0
- package/dist/utils/init/graph-setup.js +413 -0
- package/dist/utils/init/graph-setup.js.map +1 -0
- package/dist/utils/init/index.d.ts +11 -0
- package/dist/utils/init/index.d.ts.map +1 -0
- package/dist/utils/init/index.js +11 -0
- package/dist/utils/init/index.js.map +1 -0
- package/dist/utils/init/types.d.ts +73 -0
- package/dist/utils/init/types.d.ts.map +1 -0
- package/dist/utils/init/types.js +5 -0
- package/dist/utils/init/types.js.map +1 -0
- package/dist/utils/shell.d.ts +60 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +188 -0
- package/dist/utils/shell.js.map +1 -0
- package/package.json +25 -20
- package/templates/basic/README.md +105 -0
- package/templates/basic/dev-runner.mjs +215 -0
- package/templates/basic/package-lock.json +1263 -0
- package/templates/basic/package.json +22 -0
- package/templates/basic/src/index.ts +85 -0
- 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.
|
|
3
|
+
"version": "0.22.1",
|
|
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": "
|
|
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
|
|
24
|
-
"test:
|
|
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.
|
|
55
|
-
"commander": "^14.0.2",
|
|
56
|
-
"prompts": "^2.4.2",
|
|
57
|
-
"picocolors": "^1.1.1",
|
|
58
|
-
"ora": "^9.0.0",
|
|
57
|
+
"@cortexmemory/sdk": "^0.21.0",
|
|
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
|
-
"
|
|
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
|
-
"@
|
|
68
|
-
"typescript": "^
|
|
69
|
-
"eslint": "^9.39.
|
|
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
|
-
"
|
|
76
|
-
"
|
|
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
|
+
});
|