@cortex-context/cli 0.0.5 → 0.0.6
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/index.js +414 -101
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -5617,7 +5617,7 @@ var require_dist = __commonJS({
|
|
|
5617
5617
|
});
|
|
5618
5618
|
};
|
|
5619
5619
|
}
|
|
5620
|
-
var
|
|
5620
|
+
var prompts5 = require_prompts();
|
|
5621
5621
|
var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
|
|
5622
5622
|
var noop = () => {
|
|
5623
5623
|
};
|
|
@@ -5668,7 +5668,7 @@ var require_dist = __commonJS({
|
|
|
5668
5668
|
var _question2 = question;
|
|
5669
5669
|
name = _question2.name;
|
|
5670
5670
|
type = _question2.type;
|
|
5671
|
-
if (
|
|
5671
|
+
if (prompts5[type] === void 0) {
|
|
5672
5672
|
throw new Error(`prompt type (${type}) is not defined`);
|
|
5673
5673
|
}
|
|
5674
5674
|
if (override2[question.name] !== void 0) {
|
|
@@ -5679,7 +5679,7 @@ var require_dist = __commonJS({
|
|
|
5679
5679
|
}
|
|
5680
5680
|
}
|
|
5681
5681
|
try {
|
|
5682
|
-
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : yield
|
|
5682
|
+
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : yield prompts5[type](question);
|
|
5683
5683
|
answers[name] = answer = yield getFormattedAnswer(question, answer, true);
|
|
5684
5684
|
quit = yield onSubmit(question, answer, answers);
|
|
5685
5685
|
} catch (err) {
|
|
@@ -5711,7 +5711,7 @@ var require_dist = __commonJS({
|
|
|
5711
5711
|
}
|
|
5712
5712
|
module2.exports = Object.assign(prompt, {
|
|
5713
5713
|
prompt,
|
|
5714
|
-
prompts:
|
|
5714
|
+
prompts: prompts5,
|
|
5715
5715
|
inject,
|
|
5716
5716
|
override
|
|
5717
5717
|
});
|
|
@@ -7798,7 +7798,7 @@ var require_prompts2 = __commonJS({
|
|
|
7798
7798
|
var require_lib = __commonJS({
|
|
7799
7799
|
"node_modules/prompts/lib/index.js"(exports2, module2) {
|
|
7800
7800
|
"use strict";
|
|
7801
|
-
var
|
|
7801
|
+
var prompts5 = require_prompts2();
|
|
7802
7802
|
var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
|
|
7803
7803
|
var noop = () => {
|
|
7804
7804
|
};
|
|
@@ -7830,7 +7830,7 @@ var require_lib = __commonJS({
|
|
|
7830
7830
|
throw new Error("prompt message is required");
|
|
7831
7831
|
}
|
|
7832
7832
|
({ name, type } = question);
|
|
7833
|
-
if (
|
|
7833
|
+
if (prompts5[type] === void 0) {
|
|
7834
7834
|
throw new Error(`prompt type (${type}) is not defined`);
|
|
7835
7835
|
}
|
|
7836
7836
|
if (override2[question.name] !== void 0) {
|
|
@@ -7841,7 +7841,7 @@ var require_lib = __commonJS({
|
|
|
7841
7841
|
}
|
|
7842
7842
|
}
|
|
7843
7843
|
try {
|
|
7844
|
-
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await
|
|
7844
|
+
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await prompts5[type](question);
|
|
7845
7845
|
answers[name] = answer = await getFormattedAnswer(question, answer, true);
|
|
7846
7846
|
quit = await onSubmit(question, answer, answers);
|
|
7847
7847
|
} catch (err) {
|
|
@@ -7864,7 +7864,7 @@ var require_lib = __commonJS({
|
|
|
7864
7864
|
function override(answers) {
|
|
7865
7865
|
prompt._override = Object.assign({}, answers);
|
|
7866
7866
|
}
|
|
7867
|
-
module2.exports = Object.assign(prompt, { prompt, prompts:
|
|
7867
|
+
module2.exports = Object.assign(prompt, { prompt, prompts: prompts5, inject, override });
|
|
7868
7868
|
}
|
|
7869
7869
|
});
|
|
7870
7870
|
|
|
@@ -16901,7 +16901,7 @@ var source_default = chalk;
|
|
|
16901
16901
|
// src/commands/init.ts
|
|
16902
16902
|
var import_path8 = require("path");
|
|
16903
16903
|
var import_fs8 = require("fs");
|
|
16904
|
-
var
|
|
16904
|
+
var import_prompts2 = __toESM(require_prompts3());
|
|
16905
16905
|
|
|
16906
16906
|
// node_modules/ora/index.js
|
|
16907
16907
|
var import_node_process7 = __toESM(require("process"), 1);
|
|
@@ -17840,7 +17840,10 @@ function writeConfig(config2) {
|
|
|
17840
17840
|
(0, import_fs.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
17841
17841
|
}
|
|
17842
17842
|
const current = readConfig();
|
|
17843
|
-
(0, import_fs.writeFileSync)(
|
|
17843
|
+
(0, import_fs.writeFileSync)(
|
|
17844
|
+
CONFIG_FILE,
|
|
17845
|
+
JSON.stringify({ ...current, ...config2 }, null, 2)
|
|
17846
|
+
);
|
|
17844
17847
|
}
|
|
17845
17848
|
function deleteConfig() {
|
|
17846
17849
|
if ((0, import_fs.existsSync)(CONFIG_FILE)) {
|
|
@@ -17944,11 +17947,56 @@ function printInstallResult(label, result, dryRun) {
|
|
|
17944
17947
|
var import_fs3 = require("fs");
|
|
17945
17948
|
var import_path3 = require("path");
|
|
17946
17949
|
var import_os2 = require("os");
|
|
17947
|
-
|
|
17948
|
-
|
|
17950
|
+
var import_prompts = __toESM(require_prompts3());
|
|
17951
|
+
async function detectWorkspaceTarget(workspacePath) {
|
|
17952
|
+
const hasVscode = (0, import_fs3.existsSync)((0, import_path3.join)(workspacePath, ".vscode"));
|
|
17953
|
+
const hasCursor = (0, import_fs3.existsSync)((0, import_path3.join)(workspacePath, ".cursor"));
|
|
17954
|
+
const hasClaude = (0, import_fs3.existsSync)((0, import_path3.join)(workspacePath, ".claude"));
|
|
17955
|
+
if (hasVscode) {
|
|
17956
|
+
return {
|
|
17957
|
+
target: "vscode",
|
|
17958
|
+
mcpPath: (0, import_path3.join)(workspacePath, ".vscode", "mcp.json"),
|
|
17959
|
+
isFallback: false
|
|
17960
|
+
};
|
|
17961
|
+
}
|
|
17962
|
+
if (hasCursor) {
|
|
17963
|
+
return {
|
|
17964
|
+
target: "cursor",
|
|
17965
|
+
mcpPath: (0, import_path3.join)(workspacePath, ".cursor", "mcp.json"),
|
|
17966
|
+
isFallback: false
|
|
17967
|
+
};
|
|
17968
|
+
}
|
|
17969
|
+
if (hasClaude) {
|
|
17970
|
+
return {
|
|
17971
|
+
target: "claude",
|
|
17972
|
+
mcpPath: (0, import_path3.join)(workspacePath, ".claude", "mcp.json"),
|
|
17973
|
+
isFallback: false
|
|
17974
|
+
};
|
|
17975
|
+
}
|
|
17976
|
+
console.log(
|
|
17977
|
+
source_default.yellow(
|
|
17978
|
+
" \u26A0 No IDE workspace detected (.vscode/, .cursor/, .claude/)"
|
|
17979
|
+
)
|
|
17980
|
+
);
|
|
17981
|
+
console.log(
|
|
17982
|
+
source_default.dim(
|
|
17983
|
+
" .agents/ is the emerging standard for IDE-agnostic AI config."
|
|
17984
|
+
)
|
|
17985
|
+
);
|
|
17986
|
+
const { confirm } = await (0, import_prompts.default)({
|
|
17987
|
+
type: "confirm",
|
|
17988
|
+
name: "confirm",
|
|
17989
|
+
message: "Install MCP config into .agents/mcp.json?",
|
|
17990
|
+
initial: true
|
|
17991
|
+
});
|
|
17992
|
+
if (!confirm) return null;
|
|
17993
|
+
return {
|
|
17994
|
+
target: "agents",
|
|
17995
|
+
mcpPath: (0, import_path3.join)(workspacePath, ".agents", "mcp.json"),
|
|
17996
|
+
isFallback: true
|
|
17997
|
+
};
|
|
17949
17998
|
}
|
|
17950
|
-
function readMcpConfig(
|
|
17951
|
-
const mcpPath = getMcpConfigPath(workspacePath);
|
|
17999
|
+
function readMcpConfig(mcpPath) {
|
|
17952
18000
|
if (!(0, import_fs3.existsSync)(mcpPath)) return { servers: {} };
|
|
17953
18001
|
try {
|
|
17954
18002
|
return JSON.parse((0, import_fs3.readFileSync)(mcpPath, "utf-8"));
|
|
@@ -17956,12 +18004,12 @@ function readMcpConfig(workspacePath) {
|
|
|
17956
18004
|
return { servers: {} };
|
|
17957
18005
|
}
|
|
17958
18006
|
}
|
|
17959
|
-
function writeMcpConfig(
|
|
17960
|
-
|
|
18007
|
+
function writeMcpConfig(mcpPath, config2) {
|
|
18008
|
+
(0, import_fs3.mkdirSync)((0, import_path3.dirname)(mcpPath), { recursive: true });
|
|
17961
18009
|
(0, import_fs3.writeFileSync)(mcpPath, JSON.stringify(config2, null, 2) + "\n");
|
|
17962
18010
|
}
|
|
17963
|
-
function injectCortexMcpServer(
|
|
17964
|
-
const config2 = readMcpConfig(
|
|
18011
|
+
function injectCortexMcpServer(mcpPath, cortexUrl, cortexToken) {
|
|
18012
|
+
const config2 = readMcpConfig(mcpPath);
|
|
17965
18013
|
const existed = "cortex" in config2.servers;
|
|
17966
18014
|
config2.servers["cortex"] = {
|
|
17967
18015
|
type: "stdio",
|
|
@@ -17972,74 +18020,63 @@ function injectCortexMcpServer(workspacePath, cortexUrl, cortexToken) {
|
|
|
17972
18020
|
...cortexToken ? { CORTEX_API_TOKEN: cortexToken } : {}
|
|
17973
18021
|
}
|
|
17974
18022
|
};
|
|
17975
|
-
writeMcpConfig(
|
|
18023
|
+
writeMcpConfig(mcpPath, config2);
|
|
17976
18024
|
return {
|
|
17977
18025
|
added: !existed,
|
|
17978
18026
|
updated: existed
|
|
17979
18027
|
};
|
|
17980
18028
|
}
|
|
17981
|
-
function removeCortexMcpServer(
|
|
17982
|
-
const config2 = readMcpConfig(
|
|
18029
|
+
function removeCortexMcpServer(mcpPath) {
|
|
18030
|
+
const config2 = readMcpConfig(mcpPath);
|
|
17983
18031
|
if (!("cortex" in config2.servers)) return { removed: false };
|
|
17984
18032
|
delete config2.servers["cortex"];
|
|
17985
|
-
writeMcpConfig(
|
|
18033
|
+
writeMcpConfig(mcpPath, config2);
|
|
17986
18034
|
return { removed: true };
|
|
17987
18035
|
}
|
|
17988
|
-
function hasCortexMcp(
|
|
17989
|
-
const config2 = readMcpConfig(
|
|
18036
|
+
function hasCortexMcp(mcpPath) {
|
|
18037
|
+
const config2 = readMcpConfig(mcpPath);
|
|
17990
18038
|
return "cortex" in config2.servers;
|
|
17991
18039
|
}
|
|
17992
18040
|
function printMcpStatus(workspacePath) {
|
|
17993
|
-
const
|
|
17994
|
-
|
|
17995
|
-
|
|
17996
|
-
|
|
18041
|
+
const candidates = [
|
|
18042
|
+
{
|
|
18043
|
+
label: ".vscode/mcp.json",
|
|
18044
|
+
path: (0, import_path3.join)(workspacePath, ".vscode", "mcp.json")
|
|
18045
|
+
},
|
|
18046
|
+
{
|
|
18047
|
+
label: ".cursor/mcp.json",
|
|
18048
|
+
path: (0, import_path3.join)(workspacePath, ".cursor", "mcp.json")
|
|
18049
|
+
},
|
|
18050
|
+
{
|
|
18051
|
+
label: ".claude/mcp.json",
|
|
18052
|
+
path: (0, import_path3.join)(workspacePath, ".claude", "mcp.json")
|
|
18053
|
+
},
|
|
18054
|
+
{
|
|
18055
|
+
label: ".agents/mcp.json",
|
|
18056
|
+
path: (0, import_path3.join)(workspacePath, ".agents", "mcp.json")
|
|
18057
|
+
}
|
|
18058
|
+
];
|
|
18059
|
+
let found = false;
|
|
18060
|
+
for (const { label, path } of candidates) {
|
|
18061
|
+
if (!(0, import_fs3.existsSync)(path)) continue;
|
|
18062
|
+
const config2 = readMcpConfig(path);
|
|
18063
|
+
if ("cortex" in config2.servers) {
|
|
18064
|
+
const url = config2.servers["cortex"]?.env?.["CORTEX_URL"] ?? "(not set)";
|
|
18065
|
+
console.log(
|
|
18066
|
+
source_default.green(` \u2713 MCP server "cortex" configured in ${label} \u2192 ${url}`)
|
|
18067
|
+
);
|
|
18068
|
+
found = true;
|
|
18069
|
+
}
|
|
17997
18070
|
}
|
|
17998
|
-
|
|
17999
|
-
if ("cortex" in config2.servers) {
|
|
18000
|
-
const entry = config2.servers["cortex"];
|
|
18001
|
-
const url = entry.env?.["CORTEX_URL"] ?? "(not set)";
|
|
18002
|
-
console.log(source_default.green(` \u2713 MCP server "cortex" configured \u2192 ${url}`));
|
|
18003
|
-
} else {
|
|
18071
|
+
if (!found) {
|
|
18004
18072
|
console.log(
|
|
18005
|
-
source_default.yellow(' \u26A0 MCP server "cortex" not found in
|
|
18073
|
+
source_default.yellow(' \u26A0 MCP server "cortex" not found in any known config')
|
|
18006
18074
|
);
|
|
18007
18075
|
}
|
|
18008
18076
|
}
|
|
18009
18077
|
function getCursorMcpPath(workspacePath) {
|
|
18010
18078
|
return (0, import_path3.join)(workspacePath, ".cursor", "mcp.json");
|
|
18011
18079
|
}
|
|
18012
|
-
function configureCursorMcp(workspacePath, cortexUrl, cortexToken) {
|
|
18013
|
-
const cursorDir = (0, import_path3.join)(workspacePath, ".cursor");
|
|
18014
|
-
if (!(0, import_fs3.existsSync)(cursorDir)) {
|
|
18015
|
-
return {
|
|
18016
|
-
configured: false,
|
|
18017
|
-
skipped: true,
|
|
18018
|
-
reason: ".cursor/ not found (Cursor not configured)"
|
|
18019
|
-
};
|
|
18020
|
-
}
|
|
18021
|
-
const mcpPath = getCursorMcpPath(workspacePath);
|
|
18022
|
-
let config2 = { servers: {} };
|
|
18023
|
-
if ((0, import_fs3.existsSync)(mcpPath)) {
|
|
18024
|
-
try {
|
|
18025
|
-
config2 = JSON.parse((0, import_fs3.readFileSync)(mcpPath, "utf-8"));
|
|
18026
|
-
} catch {
|
|
18027
|
-
config2 = { servers: {} };
|
|
18028
|
-
}
|
|
18029
|
-
}
|
|
18030
|
-
config2.servers["cortex"] = {
|
|
18031
|
-
type: "stdio",
|
|
18032
|
-
command: "npx",
|
|
18033
|
-
args: ["-y", "@cortex-context/cli", "mcp-serve"],
|
|
18034
|
-
env: {
|
|
18035
|
-
CORTEX_URL: cortexUrl,
|
|
18036
|
-
...cortexToken ? { CORTEX_API_TOKEN: cortexToken } : {}
|
|
18037
|
-
}
|
|
18038
|
-
};
|
|
18039
|
-
(0, import_fs3.mkdirSync)(cursorDir, { recursive: true });
|
|
18040
|
-
(0, import_fs3.writeFileSync)(mcpPath, JSON.stringify(config2, null, 2) + "\n");
|
|
18041
|
-
return { configured: true, skipped: false };
|
|
18042
|
-
}
|
|
18043
18080
|
function removeCursorMcp(workspacePath) {
|
|
18044
18081
|
const mcpPath = getCursorMcpPath(workspacePath);
|
|
18045
18082
|
if (!(0, import_fs3.existsSync)(mcpPath)) return { removed: false };
|
|
@@ -18156,7 +18193,6 @@ function writeCortexConfig(workspacePath, force) {
|
|
|
18156
18193
|
}
|
|
18157
18194
|
const templatePath = (0, import_path4.join)(
|
|
18158
18195
|
__dirname,
|
|
18159
|
-
"..",
|
|
18160
18196
|
"templates",
|
|
18161
18197
|
"local",
|
|
18162
18198
|
"cortex.config.template.yaml"
|
|
@@ -18173,10 +18209,10 @@ function writeCortexConfig(workspacePath, force) {
|
|
|
18173
18209
|
var import_child_process = require("child_process");
|
|
18174
18210
|
var import_fs5 = require("fs");
|
|
18175
18211
|
var import_path5 = require("path");
|
|
18212
|
+
var import_os3 = require("os");
|
|
18176
18213
|
async function deployLocalStack(workspacePath) {
|
|
18177
18214
|
const templatePath = (0, import_path5.join)(
|
|
18178
18215
|
__dirname,
|
|
18179
|
-
"..",
|
|
18180
18216
|
"templates",
|
|
18181
18217
|
"local",
|
|
18182
18218
|
"docker-compose.local.yml"
|
|
@@ -18209,6 +18245,58 @@ function isDockerAvailable() {
|
|
|
18209
18245
|
return false;
|
|
18210
18246
|
}
|
|
18211
18247
|
}
|
|
18248
|
+
async function installDocker() {
|
|
18249
|
+
const os2 = (0, import_os3.platform)();
|
|
18250
|
+
try {
|
|
18251
|
+
if (os2 === "linux") {
|
|
18252
|
+
console.log(
|
|
18253
|
+
source_default.dim(" \u2192 Running Docker install script (curl | sh)...")
|
|
18254
|
+
);
|
|
18255
|
+
(0, import_child_process.execSync)("curl -fsSL https://get.docker.com | sh", { stdio: "inherit" });
|
|
18256
|
+
const user = process.env["USER"] ?? process.env["LOGNAME"];
|
|
18257
|
+
if (user) {
|
|
18258
|
+
(0, import_child_process.spawnSync)("usermod", ["-aG", "docker", user], { stdio: "inherit" });
|
|
18259
|
+
}
|
|
18260
|
+
return { installed: true };
|
|
18261
|
+
}
|
|
18262
|
+
if (os2 === "darwin") {
|
|
18263
|
+
console.log(source_default.dim(" \u2192 Installing Docker Desktop via Homebrew..."));
|
|
18264
|
+
(0, import_child_process.execSync)("brew install --cask docker", { stdio: "inherit" });
|
|
18265
|
+
return { installed: true };
|
|
18266
|
+
}
|
|
18267
|
+
if (os2 === "win32") {
|
|
18268
|
+
console.log(source_default.dim(" \u2192 Installing Docker Desktop via winget..."));
|
|
18269
|
+
(0, import_child_process.execSync)(
|
|
18270
|
+
"winget install --id Docker.DockerDesktop -e --silent --accept-package-agreements --accept-source-agreements",
|
|
18271
|
+
{
|
|
18272
|
+
stdio: "inherit",
|
|
18273
|
+
shell: "cmd.exe"
|
|
18274
|
+
}
|
|
18275
|
+
);
|
|
18276
|
+
return { installed: true };
|
|
18277
|
+
}
|
|
18278
|
+
return { installed: false, reason: `Unsupported OS: ${os2}` };
|
|
18279
|
+
} catch (err) {
|
|
18280
|
+
return {
|
|
18281
|
+
installed: false,
|
|
18282
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
18283
|
+
};
|
|
18284
|
+
}
|
|
18285
|
+
}
|
|
18286
|
+
async function waitForCortexHealth(cortexUrl, maxWaitMs = 12e4) {
|
|
18287
|
+
const deadline = Date.now() + maxWaitMs;
|
|
18288
|
+
while (Date.now() < deadline) {
|
|
18289
|
+
try {
|
|
18290
|
+
const res = await fetch(`${cortexUrl}/health`, {
|
|
18291
|
+
signal: AbortSignal.timeout(4e3)
|
|
18292
|
+
});
|
|
18293
|
+
if (res.ok) return { healthy: true };
|
|
18294
|
+
} catch {
|
|
18295
|
+
}
|
|
18296
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
18297
|
+
}
|
|
18298
|
+
return { healthy: false };
|
|
18299
|
+
}
|
|
18212
18300
|
|
|
18213
18301
|
// src/lib/hooks.ts
|
|
18214
18302
|
var import_fs6 = require("fs");
|
|
@@ -18388,7 +18476,7 @@ async function initCommand(options) {
|
|
|
18388
18476
|
cortexToken = "dev-token-local";
|
|
18389
18477
|
console.log(source_default.dim(" Mode: local Docker stack"));
|
|
18390
18478
|
} else {
|
|
18391
|
-
const responses = await (0,
|
|
18479
|
+
const responses = await (0, import_prompts2.default)(
|
|
18392
18480
|
[
|
|
18393
18481
|
{
|
|
18394
18482
|
type: options.url ? null : "text",
|
|
@@ -18518,23 +18606,34 @@ async function initCommand(options) {
|
|
|
18518
18606
|
if (!options.skipMcp) {
|
|
18519
18607
|
console.log("");
|
|
18520
18608
|
console.log(source_default.bold(" Phase 2: MCP Server"));
|
|
18521
|
-
const
|
|
18522
|
-
|
|
18523
|
-
cortexUrl,
|
|
18524
|
-
cortexToken
|
|
18525
|
-
);
|
|
18526
|
-
if (mcpStatus.added) {
|
|
18527
|
-
console.log(source_default.green(" \u2713 .vscode/mcp.json \u2014 Cortex server added"));
|
|
18528
|
-
} else {
|
|
18529
|
-
console.log(source_default.cyan(" \u21BB .vscode/mcp.json \u2014 Cortex server updated"));
|
|
18530
|
-
}
|
|
18531
|
-
const cursorMcp = configureCursorMcp(workspacePath, cortexUrl, cortexToken);
|
|
18532
|
-
if (cursorMcp.configured) {
|
|
18609
|
+
const detected = await detectWorkspaceTarget(workspacePath);
|
|
18610
|
+
if (!detected) {
|
|
18533
18611
|
console.log(
|
|
18534
|
-
source_default.
|
|
18612
|
+
source_default.yellow(" \u26A0 MCP config skipped \u2014 no target directory confirmed")
|
|
18535
18613
|
);
|
|
18536
|
-
} else
|
|
18537
|
-
|
|
18614
|
+
} else {
|
|
18615
|
+
const targetLabel = {
|
|
18616
|
+
vscode: ".vscode/mcp.json",
|
|
18617
|
+
cursor: ".cursor/mcp.json",
|
|
18618
|
+
claude: ".claude/mcp.json",
|
|
18619
|
+
agents: ".agents/mcp.json"
|
|
18620
|
+
};
|
|
18621
|
+
const label = targetLabel[detected.target] ?? detected.mcpPath;
|
|
18622
|
+
if (detected.isFallback) {
|
|
18623
|
+
console.log(
|
|
18624
|
+
source_default.dim(` \u2139 Installing into ${label} (IDE-agnostic standard)`)
|
|
18625
|
+
);
|
|
18626
|
+
}
|
|
18627
|
+
const mcpStatus = injectCortexMcpServer(
|
|
18628
|
+
detected.mcpPath,
|
|
18629
|
+
cortexUrl,
|
|
18630
|
+
cortexToken
|
|
18631
|
+
);
|
|
18632
|
+
if (mcpStatus.added) {
|
|
18633
|
+
console.log(source_default.green(` \u2713 ${label} \u2014 Cortex server added`));
|
|
18634
|
+
} else {
|
|
18635
|
+
console.log(source_default.cyan(` \u21BB ${label} \u2014 Cortex server updated`));
|
|
18636
|
+
}
|
|
18538
18637
|
}
|
|
18539
18638
|
const claudeMcp = configureClaudeDesktop(cortexUrl, cortexToken);
|
|
18540
18639
|
if (claudeMcp.configured) {
|
|
@@ -27926,15 +28025,176 @@ async function serveCommand() {
|
|
|
27926
28025
|
await runMcpServer();
|
|
27927
28026
|
}
|
|
27928
28027
|
|
|
28028
|
+
// src/commands/server.ts
|
|
28029
|
+
var import_os4 = require("os");
|
|
28030
|
+
var import_prompts3 = __toESM(require_prompts3());
|
|
28031
|
+
var CORTEX_URL2 = "http://localhost:8082";
|
|
28032
|
+
var NEO4J_URL = "http://localhost:7474";
|
|
28033
|
+
async function serverCommand(options) {
|
|
28034
|
+
console.log("");
|
|
28035
|
+
console.log(source_default.bold.cyan(" \u25C6 Cortex Context \u2014 Server"));
|
|
28036
|
+
console.log(
|
|
28037
|
+
source_default.dim(
|
|
28038
|
+
" Installs and starts the Cortex stack (Neo4j + Cortex API) via Docker."
|
|
28039
|
+
)
|
|
28040
|
+
);
|
|
28041
|
+
console.log("");
|
|
28042
|
+
const workDir = options.dir ?? process.cwd();
|
|
28043
|
+
console.log(source_default.bold(" Step 1: Docker"));
|
|
28044
|
+
const dockerReady = isDockerAvailable();
|
|
28045
|
+
if (dockerReady) {
|
|
28046
|
+
console.log(source_default.green(" \u2713 Docker is available"));
|
|
28047
|
+
} else {
|
|
28048
|
+
console.log(source_default.yellow(" \u26A0 Docker not found on PATH"));
|
|
28049
|
+
if (options.skipDockerInstall) {
|
|
28050
|
+
console.error(
|
|
28051
|
+
source_default.red(
|
|
28052
|
+
" \u2717 --skip-docker-install set but Docker is required. Install Docker manually and retry."
|
|
28053
|
+
)
|
|
28054
|
+
);
|
|
28055
|
+
process.exit(1);
|
|
28056
|
+
}
|
|
28057
|
+
const os2 = (0, import_os4.platform)();
|
|
28058
|
+
const installMethod = {
|
|
28059
|
+
linux: "curl | sh (official script, may require sudo)",
|
|
28060
|
+
darwin: "Homebrew (brew install --cask docker)",
|
|
28061
|
+
win32: "winget (winget install Docker.DockerDesktop)"
|
|
28062
|
+
};
|
|
28063
|
+
const method = installMethod[os2] ?? `unsupported OS (${os2})`;
|
|
28064
|
+
if (!installMethod[os2]) {
|
|
28065
|
+
console.error(
|
|
28066
|
+
source_default.red(` \u2717 Automatic Docker install is not supported on ${os2}.`)
|
|
28067
|
+
);
|
|
28068
|
+
console.error(
|
|
28069
|
+
source_default.dim(
|
|
28070
|
+
" Install Docker manually: https://docs.docker.com/get-docker/"
|
|
28071
|
+
)
|
|
28072
|
+
);
|
|
28073
|
+
process.exit(1);
|
|
28074
|
+
}
|
|
28075
|
+
console.log("");
|
|
28076
|
+
console.log(source_default.dim(` Install method: ${method}`));
|
|
28077
|
+
console.log(source_default.dim(" This will install Docker on your machine."));
|
|
28078
|
+
console.log("");
|
|
28079
|
+
const { confirm } = await (0, import_prompts3.default)({
|
|
28080
|
+
type: "confirm",
|
|
28081
|
+
name: "confirm",
|
|
28082
|
+
message: "Install Docker now?",
|
|
28083
|
+
initial: true
|
|
28084
|
+
});
|
|
28085
|
+
if (!confirm) {
|
|
28086
|
+
console.log(
|
|
28087
|
+
source_default.yellow("\n Aborted. Install Docker manually and run again.")
|
|
28088
|
+
);
|
|
28089
|
+
process.exit(0);
|
|
28090
|
+
}
|
|
28091
|
+
console.log("");
|
|
28092
|
+
const spinner = ora(" Installing Docker...").start();
|
|
28093
|
+
const result = await installDocker();
|
|
28094
|
+
if (!result.installed) {
|
|
28095
|
+
spinner.fail(source_default.red(` \u2717 Docker install failed: ${result.reason}`));
|
|
28096
|
+
console.log(
|
|
28097
|
+
source_default.dim(
|
|
28098
|
+
" Install Docker manually: https://docs.docker.com/get-docker/"
|
|
28099
|
+
)
|
|
28100
|
+
);
|
|
28101
|
+
process.exit(1);
|
|
28102
|
+
}
|
|
28103
|
+
spinner.succeed(source_default.green(" \u2713 Docker installed"));
|
|
28104
|
+
if (os2 === "win32") {
|
|
28105
|
+
console.log(
|
|
28106
|
+
source_default.yellow(
|
|
28107
|
+
" \u26A0 Docker Desktop was installed. Please start it manually, then re-run this command."
|
|
28108
|
+
)
|
|
28109
|
+
);
|
|
28110
|
+
process.exit(0);
|
|
28111
|
+
}
|
|
28112
|
+
if (os2 === "linux") {
|
|
28113
|
+
console.log(
|
|
28114
|
+
source_default.dim(
|
|
28115
|
+
" \u2139 You may need to log out and back in for the docker group to take effect."
|
|
28116
|
+
)
|
|
28117
|
+
);
|
|
28118
|
+
}
|
|
28119
|
+
console.log("");
|
|
28120
|
+
}
|
|
28121
|
+
console.log("");
|
|
28122
|
+
console.log(source_default.bold(" Step 2: Containers to start"));
|
|
28123
|
+
console.log(source_default.dim(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
28124
|
+
console.log(source_default.dim(" \u2502 neo4j \u2192 localhost:7474 (UI: 7474) \u2502"));
|
|
28125
|
+
console.log(source_default.dim(" \u2502 cortex-api \u2192 localhost:8082 \u2502"));
|
|
28126
|
+
console.log(source_default.dim(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
28127
|
+
console.log("");
|
|
28128
|
+
console.log(source_default.dim(` Working directory: ${workDir}`));
|
|
28129
|
+
console.log("");
|
|
28130
|
+
const { proceed } = await (0, import_prompts3.default)({
|
|
28131
|
+
type: "confirm",
|
|
28132
|
+
name: "proceed",
|
|
28133
|
+
message: "Start the Cortex stack now?",
|
|
28134
|
+
initial: true
|
|
28135
|
+
});
|
|
28136
|
+
if (!proceed) {
|
|
28137
|
+
console.log(source_default.yellow("\n Aborted."));
|
|
28138
|
+
process.exit(0);
|
|
28139
|
+
}
|
|
28140
|
+
console.log("");
|
|
28141
|
+
console.log(source_default.bold(" Step 3: Starting Cortex stack"));
|
|
28142
|
+
const startSpinner = ora(" Running docker compose up -d...").start();
|
|
28143
|
+
const startResult = await deployLocalStack(workDir);
|
|
28144
|
+
if (!startResult.started) {
|
|
28145
|
+
startSpinner.fail(
|
|
28146
|
+
source_default.red(` \u2717 Docker Compose failed: ${startResult.error}`)
|
|
28147
|
+
);
|
|
28148
|
+
process.exit(1);
|
|
28149
|
+
}
|
|
28150
|
+
startSpinner.succeed(source_default.green(" \u2713 Containers started"));
|
|
28151
|
+
console.log("");
|
|
28152
|
+
console.log(source_default.bold(" Step 4: Waiting for Cortex API..."));
|
|
28153
|
+
const healthSpinner = ora(
|
|
28154
|
+
" Polling http://localhost:8082/health (up to 2 min)..."
|
|
28155
|
+
).start();
|
|
28156
|
+
const { healthy } = await waitForCortexHealth(CORTEX_URL2);
|
|
28157
|
+
if (!healthy) {
|
|
28158
|
+
healthSpinner.warn(
|
|
28159
|
+
source_default.yellow(
|
|
28160
|
+
" \u26A0 Cortex API did not respond in time \u2014 containers may still be starting."
|
|
28161
|
+
)
|
|
28162
|
+
);
|
|
28163
|
+
console.log(source_default.dim(` Check manually: curl ${CORTEX_URL2}/health`));
|
|
28164
|
+
console.log(
|
|
28165
|
+
source_default.dim(" Or: docker compose -f docker-compose.local.yml logs")
|
|
28166
|
+
);
|
|
28167
|
+
} else {
|
|
28168
|
+
healthSpinner.succeed(source_default.green(" \u2713 Cortex API is healthy"));
|
|
28169
|
+
}
|
|
28170
|
+
console.log("");
|
|
28171
|
+
console.log(source_default.bold.green(" \u2705 Cortex stack is running!"));
|
|
28172
|
+
console.log("");
|
|
28173
|
+
console.log(source_default.bold(" Services:"));
|
|
28174
|
+
console.log(source_default.cyan(` Cortex API \u2192 ${CORTEX_URL2}`));
|
|
28175
|
+
console.log(source_default.cyan(` Neo4j UI \u2192 ${NEO4J_URL}`));
|
|
28176
|
+
console.log(source_default.dim(" Neo4j login \u2192 neo4j / cortex-local"));
|
|
28177
|
+
console.log("");
|
|
28178
|
+
console.log(source_default.bold(" Next steps:"));
|
|
28179
|
+
console.log(source_default.dim(" 1. Initialize your workspace:"));
|
|
28180
|
+
console.log(source_default.cyan(` cortex-context init --url ${CORTEX_URL2}`));
|
|
28181
|
+
console.log(source_default.dim(" 2. Check connectivity:"));
|
|
28182
|
+
console.log(source_default.cyan(" cortex-context doctor"));
|
|
28183
|
+
console.log("");
|
|
28184
|
+
console.log(source_default.dim(" To stop the stack:"));
|
|
28185
|
+
console.log(source_default.dim(" docker compose -f docker-compose.local.yml down"));
|
|
28186
|
+
console.log("");
|
|
28187
|
+
}
|
|
28188
|
+
|
|
27929
28189
|
// src/commands/uninstall.ts
|
|
27930
28190
|
var import_path13 = require("path");
|
|
27931
28191
|
var import_fs12 = require("fs");
|
|
27932
|
-
var
|
|
28192
|
+
var import_prompts4 = __toESM(require_prompts3());
|
|
27933
28193
|
var CORTEX_SKILLS = [
|
|
27934
28194
|
"cortex-research",
|
|
27935
28195
|
"cortex-dimensions",
|
|
27936
28196
|
"cortex-ingest",
|
|
27937
|
-
"generate-spec"
|
|
28197
|
+
"cortex-generate-spec"
|
|
27938
28198
|
];
|
|
27939
28199
|
async function uninstallCommand(options) {
|
|
27940
28200
|
console.log("");
|
|
@@ -27950,7 +28210,9 @@ async function uninstallCommand(options) {
|
|
|
27950
28210
|
);
|
|
27951
28211
|
const hasMcp = (0, import_fs12.existsSync)((0, import_path13.join)(workspacePath, ".vscode", "mcp.json"));
|
|
27952
28212
|
const hasCursorMcp = (0, import_fs12.existsSync)((0, import_path13.join)(workspacePath, ".cursor", "mcp.json"));
|
|
27953
|
-
const hasHook = (0, import_fs12.existsSync)(
|
|
28213
|
+
const hasHook = (0, import_fs12.existsSync)(
|
|
28214
|
+
(0, import_path13.join)(workspacePath, ".git", "hooks", "post-commit")
|
|
28215
|
+
);
|
|
27954
28216
|
const hasConfig = (0, import_fs12.existsSync)(
|
|
27955
28217
|
(0, import_path13.join)(process.env["HOME"] ?? "~", ".cortex-context", "config.json")
|
|
27956
28218
|
);
|
|
@@ -27967,7 +28229,9 @@ async function uninstallCommand(options) {
|
|
|
27967
28229
|
}
|
|
27968
28230
|
}
|
|
27969
28231
|
if (!options.keepHook && hasHook) {
|
|
27970
|
-
console.log(
|
|
28232
|
+
console.log(
|
|
28233
|
+
source_default.dim(" \xB7 .git/hooks/post-commit (cortex auto-sync hook)")
|
|
28234
|
+
);
|
|
27971
28235
|
}
|
|
27972
28236
|
if (!options.keepConfig && hasConfig) {
|
|
27973
28237
|
console.log(source_default.dim(" \xB7 ~/.cortex-context/config.json"));
|
|
@@ -27980,7 +28244,7 @@ async function uninstallCommand(options) {
|
|
|
27980
28244
|
}
|
|
27981
28245
|
console.log("");
|
|
27982
28246
|
if (!options.yes) {
|
|
27983
|
-
const { confirmed } = await (0,
|
|
28247
|
+
const { confirmed } = await (0, import_prompts4.default)({
|
|
27984
28248
|
type: "confirm",
|
|
27985
28249
|
name: "confirmed",
|
|
27986
28250
|
message: "Proceed with uninstall?",
|
|
@@ -27999,13 +28263,21 @@ async function uninstallCommand(options) {
|
|
|
27999
28263
|
try {
|
|
28000
28264
|
const result = removeCortexMcpServer(workspacePath);
|
|
28001
28265
|
if (result.removed) {
|
|
28002
|
-
console.log(
|
|
28266
|
+
console.log(
|
|
28267
|
+
source_default.green(' \u2713 .vscode/mcp.json \u2014 "cortex" entry removed')
|
|
28268
|
+
);
|
|
28003
28269
|
removed++;
|
|
28004
28270
|
} else {
|
|
28005
|
-
console.log(
|
|
28271
|
+
console.log(
|
|
28272
|
+
source_default.dim(' \xB7 .vscode/mcp.json \u2014 no "cortex" entry found')
|
|
28273
|
+
);
|
|
28006
28274
|
}
|
|
28007
28275
|
} catch (err) {
|
|
28008
|
-
console.log(
|
|
28276
|
+
console.log(
|
|
28277
|
+
source_default.red(
|
|
28278
|
+
` \u2717 .vscode/mcp.json \u2014 ${err instanceof Error ? err.message : err}`
|
|
28279
|
+
)
|
|
28280
|
+
);
|
|
28009
28281
|
errors++;
|
|
28010
28282
|
}
|
|
28011
28283
|
}
|
|
@@ -28013,18 +28285,28 @@ async function uninstallCommand(options) {
|
|
|
28013
28285
|
try {
|
|
28014
28286
|
const result = removeCursorMcp(workspacePath);
|
|
28015
28287
|
if (result.removed) {
|
|
28016
|
-
console.log(
|
|
28288
|
+
console.log(
|
|
28289
|
+
source_default.green(' \u2713 .cursor/mcp.json \u2014 "cortex" entry removed')
|
|
28290
|
+
);
|
|
28017
28291
|
removed++;
|
|
28018
28292
|
}
|
|
28019
28293
|
} catch (err) {
|
|
28020
|
-
console.log(
|
|
28294
|
+
console.log(
|
|
28295
|
+
source_default.red(
|
|
28296
|
+
` \u2717 .cursor/mcp.json \u2014 ${err instanceof Error ? err.message : err}`
|
|
28297
|
+
)
|
|
28298
|
+
);
|
|
28021
28299
|
errors++;
|
|
28022
28300
|
}
|
|
28023
28301
|
}
|
|
28024
28302
|
try {
|
|
28025
28303
|
const result = removeClaudeDesktopMcp();
|
|
28026
28304
|
if (result.removed) {
|
|
28027
|
-
console.log(
|
|
28305
|
+
console.log(
|
|
28306
|
+
source_default.green(
|
|
28307
|
+
` \u2713 Claude Desktop \u2014 "cortex" entry removed (${result.path})`
|
|
28308
|
+
)
|
|
28309
|
+
);
|
|
28028
28310
|
removed++;
|
|
28029
28311
|
}
|
|
28030
28312
|
} catch {
|
|
@@ -28037,7 +28319,11 @@ async function uninstallCommand(options) {
|
|
|
28037
28319
|
console.log(source_default.green(` \u2713 .github/skills/${skill}/ \u2014 removed`));
|
|
28038
28320
|
removed++;
|
|
28039
28321
|
} catch (err) {
|
|
28040
|
-
console.log(
|
|
28322
|
+
console.log(
|
|
28323
|
+
source_default.red(
|
|
28324
|
+
` \u2717 .github/skills/${skill}/ \u2014 ${err instanceof Error ? err.message : err}`
|
|
28325
|
+
)
|
|
28326
|
+
);
|
|
28041
28327
|
errors++;
|
|
28042
28328
|
}
|
|
28043
28329
|
}
|
|
@@ -28052,7 +28338,9 @@ async function uninstallCommand(options) {
|
|
|
28052
28338
|
console.log(source_default.green(" \u2713 .git/hooks/post-commit \u2014 removed"));
|
|
28053
28339
|
removed++;
|
|
28054
28340
|
} else {
|
|
28055
|
-
console.log(
|
|
28341
|
+
console.log(
|
|
28342
|
+
source_default.dim(" \xB7 .git/hooks/post-commit \u2014 not ours, skipped")
|
|
28343
|
+
);
|
|
28056
28344
|
}
|
|
28057
28345
|
} catch {
|
|
28058
28346
|
}
|
|
@@ -28063,17 +28351,33 @@ async function uninstallCommand(options) {
|
|
|
28063
28351
|
console.log(source_default.green(" \u2713 ~/.cortex-context/config.json \u2014 removed"));
|
|
28064
28352
|
removed++;
|
|
28065
28353
|
} catch (err) {
|
|
28066
|
-
console.log(
|
|
28354
|
+
console.log(
|
|
28355
|
+
source_default.red(
|
|
28356
|
+
` \u2717 ~/.cortex-context/config.json \u2014 ${err instanceof Error ? err.message : err}`
|
|
28357
|
+
)
|
|
28358
|
+
);
|
|
28067
28359
|
errors++;
|
|
28068
28360
|
}
|
|
28069
28361
|
}
|
|
28070
28362
|
console.log("");
|
|
28071
28363
|
if (errors === 0) {
|
|
28072
|
-
console.log(
|
|
28364
|
+
console.log(
|
|
28365
|
+
source_default.bold.green(
|
|
28366
|
+
` \u2705 Uninstall complete (${removed} item${removed !== 1 ? "s" : ""} removed)`
|
|
28367
|
+
)
|
|
28368
|
+
);
|
|
28073
28369
|
console.log("");
|
|
28074
|
-
console.log(
|
|
28370
|
+
console.log(
|
|
28371
|
+
source_default.dim(
|
|
28372
|
+
' Reload VS Code (Cmd/Ctrl+Shift+P \u2192 "Reload Window") to deactivate the MCP server.'
|
|
28373
|
+
)
|
|
28374
|
+
);
|
|
28075
28375
|
} else {
|
|
28076
|
-
console.log(
|
|
28376
|
+
console.log(
|
|
28377
|
+
source_default.bold.yellow(
|
|
28378
|
+
` \u26A0 Uninstall finished with ${errors} error${errors !== 1 ? "s" : ""}`
|
|
28379
|
+
)
|
|
28380
|
+
);
|
|
28077
28381
|
}
|
|
28078
28382
|
console.log("");
|
|
28079
28383
|
}
|
|
@@ -28101,6 +28405,15 @@ function createCli() {
|
|
|
28101
28405
|
"--local",
|
|
28102
28406
|
"Deploy a local Cortex stack with Docker (mutually exclusive with --url)"
|
|
28103
28407
|
).option("--skip-mcp", "Skip MCP server configuration").option("--skip-skills", "Skip Skills installation").option("--skip-hooks", "Skip git hook installation").option("--skip-rules", "Skip Copilot/Cursor rules injection").option("--force", "Overwrite existing files without prompting").action(initCommand);
|
|
28408
|
+
program3.command("server").description(
|
|
28409
|
+
"Install Docker (if needed) and start the Cortex stack (Neo4j + Cortex API) locally"
|
|
28410
|
+
).option(
|
|
28411
|
+
"--dir <path>",
|
|
28412
|
+
"Directory to place docker-compose.local.yml (defaults to current directory)"
|
|
28413
|
+
).option(
|
|
28414
|
+
"--skip-docker-install",
|
|
28415
|
+
"Fail instead of auto-installing Docker when it is not found"
|
|
28416
|
+
).action(serverCommand);
|
|
28104
28417
|
program3.command("sync").description("Ingest latest git diff into the Cortex Knowledge Graph").option("--repo <path>", "Repository path (defaults to current directory)").option("--dry-run", "Show diff without sending to Cortex API").action(syncCommand);
|
|
28105
28418
|
program3.command("update").description(
|
|
28106
28419
|
"Update Skills and MCP Server files to the latest bundled version"
|