devsmind-mcp 2.1.1 → 2.2.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.
- package/README.md +110 -28
- package/dist/cli/index.js +38 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.js +48 -56
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/integrations/mcp.d.ts +8 -0
- package/dist/cli/integrations/mcp.js +164 -0
- package/dist/cli/integrations/mcp.js.map +1 -0
- package/dist/cli/integrations/prompt.d.ts +52 -0
- package/dist/cli/integrations/prompt.js +352 -0
- package/dist/cli/integrations/prompt.js.map +1 -0
- package/dist/cli/integrations/registry.d.ts +67 -0
- package/dist/cli/integrations/registry.js +271 -0
- package/dist/cli/integrations/registry.js.map +1 -0
- package/dist/cli/rule.d.ts +14 -1
- package/dist/cli/rule.js +92 -40
- package/dist/cli/rule.js.map +1 -1
- package/dist/cli/sync.d.ts +13 -0
- package/dist/cli/sync.js +119 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/db/database.d.ts +6 -0
- package/dist/db/database.js +17 -0
- package/dist/db/database.js.map +1 -1
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.js +31 -0
- package/dist/utils/config.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.handleMcp = handleMcp;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const config_1 = require("../../utils/config");
|
|
39
|
+
const server_1 = require("../../mcp/server");
|
|
40
|
+
const registry_1 = require("./registry");
|
|
41
|
+
const prompt_1 = require("./prompt");
|
|
42
|
+
const SERVER_NAME = 'devsmind';
|
|
43
|
+
/**
|
|
44
|
+
* `devsmind mcp` — guided walkthrough that adds DevsMind as an MCP server to a
|
|
45
|
+
* chosen IDE or CLI, either by printing the exact snippet (manual) or by
|
|
46
|
+
* creating/merging the tool's config file (automatic, with preview + confirm).
|
|
47
|
+
*/
|
|
48
|
+
async function handleMcp(opts) {
|
|
49
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
50
|
+
console.error(`❌ \`devsmind mcp\` is interactive and needs a terminal.\n` +
|
|
51
|
+
` Run it directly in your shell (not piped/redirected).`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const devmindDir = (0, config_1.resolveDevmindDir)(opts.path);
|
|
55
|
+
const workspaceRoot = devmindDir ? path.dirname(devmindDir) : process.cwd();
|
|
56
|
+
if (!devmindDir) {
|
|
57
|
+
console.log(`\n⚠️ No .devmind brain found here — you can still add the MCP config, but run` +
|
|
58
|
+
` \`devsmind init\` in your project so the server has a brain to serve.`);
|
|
59
|
+
}
|
|
60
|
+
const ctx = { devmindDir: devmindDir ?? workspaceRoot, port: server_1.DEVSMIND_PORT };
|
|
61
|
+
try {
|
|
62
|
+
const target = await (0, prompt_1.pickTarget)();
|
|
63
|
+
const transport = await (0, prompt_1.pickTransport)(target);
|
|
64
|
+
const scope = await (0, prompt_1.pickMcpScope)(target);
|
|
65
|
+
const entry = target.mcp.entry(transport, ctx);
|
|
66
|
+
if (target.mcp.note)
|
|
67
|
+
console.log(`\nℹ️ ${target.mcp.note}`);
|
|
68
|
+
const mode = await (0, prompt_1.pickMode)();
|
|
69
|
+
if (mode === 'manual') {
|
|
70
|
+
printManual(target.label, scope, workspaceRoot, entry);
|
|
71
|
+
if (target.mcp.cliInstaller) {
|
|
72
|
+
console.log(`\n💡 Or use the tool's own installer:`);
|
|
73
|
+
console.log(` ${target.mcp.cliInstaller(transport, ctx)}`);
|
|
74
|
+
}
|
|
75
|
+
printNudge(transport);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Automatic mode.
|
|
79
|
+
let filePath;
|
|
80
|
+
if (scope.scope === 'project') {
|
|
81
|
+
const base = await (0, prompt_1.pickDirectory)(workspaceRoot, `Where is the project root for ${target.label}?`);
|
|
82
|
+
filePath = path.join(base, (0, registry_1.resolveOsPath)(scope.file));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
filePath = (0, registry_1.resolveScopeFile)(scope.file, 'global', workspaceRoot);
|
|
86
|
+
}
|
|
87
|
+
const merged = (0, prompt_1.mergeMcpConfig)(filePath, scope.format, scope.serverMapPath, SERVER_NAME, entry);
|
|
88
|
+
console.log(`\n📝 Target: ${filePath.replace(/\\/g, '/')} (${merged.existed ? 'merge into existing' : 'create new'})`);
|
|
89
|
+
if (scope.scope === 'global') {
|
|
90
|
+
console.log(` ⚠️ This is a GLOBAL config file affecting all your projects.`);
|
|
91
|
+
}
|
|
92
|
+
console.log(`\n${merged.existed ? 'The "devsmind" entry to be added:' : 'File contents to be written:'}\n`);
|
|
93
|
+
console.log(indent(merged.preview));
|
|
94
|
+
const ok = await (0, prompt_1.confirmPrompt)('Write this?', true);
|
|
95
|
+
if (!ok) {
|
|
96
|
+
console.log('\nAborted — nothing written.');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
(0, prompt_1.writeConfigFile)(filePath, merged.content);
|
|
100
|
+
console.log(`\n✅ DevsMind added to ${target.label} at ${filePath.replace(/\\/g, '/')}`);
|
|
101
|
+
printNudge(transport);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
if (err instanceof prompt_1.CancelledError) {
|
|
105
|
+
console.log('\nCancelled.');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function printManual(label, scope, workspaceRoot, entry) {
|
|
112
|
+
const filePath = (0, registry_1.resolveScopeFile)(scope.file, scope.scope, workspaceRoot);
|
|
113
|
+
const divider = '─'.repeat(70);
|
|
114
|
+
console.log(`\n${divider}`);
|
|
115
|
+
console.log(` Add DevsMind to ${label}`);
|
|
116
|
+
console.log(`${divider}`);
|
|
117
|
+
console.log(`\n1. Open (or create) this file:`);
|
|
118
|
+
console.log(` ${filePath.replace(/\\/g, '/')}${scope.scope === 'global' ? ' (global)' : ''}`);
|
|
119
|
+
console.log(`\n2. Add this ${scope.format.toUpperCase()} entry (merge with anything already there):\n`);
|
|
120
|
+
console.log(indent(renderSnippet(scope.format, scope.serverMapPath, entry)));
|
|
121
|
+
}
|
|
122
|
+
/** Render just the devsmind entry as a standalone snippet (no existing content). */
|
|
123
|
+
function renderSnippet(format, serverMapPath, entry) {
|
|
124
|
+
if (format === 'toml') {
|
|
125
|
+
const header = [...serverMapPath, SERVER_NAME].join('.');
|
|
126
|
+
const lines = [`[${header}]`];
|
|
127
|
+
for (const [k, v] of Object.entries(entry)) {
|
|
128
|
+
lines.push(`${k} = ${tomlLiteral(v)}`);
|
|
129
|
+
}
|
|
130
|
+
return lines.join('\n');
|
|
131
|
+
}
|
|
132
|
+
// JSON: nest entry under the server map path.
|
|
133
|
+
let obj = { [SERVER_NAME]: entry };
|
|
134
|
+
for (let i = serverMapPath.length - 1; i >= 0; i--) {
|
|
135
|
+
obj = { [serverMapPath[i]]: obj };
|
|
136
|
+
}
|
|
137
|
+
return JSON.stringify(obj, null, 2);
|
|
138
|
+
}
|
|
139
|
+
function tomlLiteral(v) {
|
|
140
|
+
if (typeof v === 'string')
|
|
141
|
+
return JSON.stringify(v);
|
|
142
|
+
if (Array.isArray(v))
|
|
143
|
+
return '[' + v.map(tomlLiteral).join(', ') + ']';
|
|
144
|
+
if (v && typeof v === 'object') {
|
|
145
|
+
const inner = Object.entries(v)
|
|
146
|
+
.map(([k, iv]) => `${k} = ${tomlLiteral(iv)}`)
|
|
147
|
+
.join(', ');
|
|
148
|
+
return `{ ${inner} }`;
|
|
149
|
+
}
|
|
150
|
+
return String(v);
|
|
151
|
+
}
|
|
152
|
+
function indent(text) {
|
|
153
|
+
return text.split('\n').map(l => ' ' + l).join('\n');
|
|
154
|
+
}
|
|
155
|
+
function printNudge(transport) {
|
|
156
|
+
if (transport === 'stdio') {
|
|
157
|
+
console.log(`\n📌 stdio setup: your tool launches DevsMind itself. After you \`git pull\``);
|
|
158
|
+
console.log(` graph changes, run \`devsmind sync\` to load them into your local brain.`);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(`\n📌 HTTP setup: start the server yourself with \`devsmind start\` (port ${server_1.DEVSMIND_PORT}).`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/cli/integrations/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IdeTarget, Transport, McpScope, RuleScope, ConfigFormat } from './registry';
|
|
2
|
+
/** Thrown when the user cancels a prompt (Esc / Ctrl-C). Callers treat it as a clean abort. */
|
|
3
|
+
export declare class CancelledError extends Error {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
6
|
+
export declare function selectPrompt<T>(message: string, choices: Array<{
|
|
7
|
+
title: string;
|
|
8
|
+
value: T;
|
|
9
|
+
description?: string;
|
|
10
|
+
}>, initial?: number): Promise<T>;
|
|
11
|
+
export declare function confirmPrompt(message: string, initial?: boolean): Promise<boolean>;
|
|
12
|
+
export declare function pickTarget(): Promise<IdeTarget>;
|
|
13
|
+
export declare function pickTransport(target: IdeTarget): Promise<Transport>;
|
|
14
|
+
export declare function pickMcpScope(target: IdeTarget): Promise<McpScope>;
|
|
15
|
+
export declare function pickRuleScope(target: IdeTarget): Promise<RuleScope>;
|
|
16
|
+
export type Mode = 'auto' | 'manual';
|
|
17
|
+
export declare function pickMode(): Promise<Mode>;
|
|
18
|
+
/**
|
|
19
|
+
* Interactive directory browser. Lets the user cd up/down from `startDir`,
|
|
20
|
+
* type/paste a path (handy for other drives or far-away folders), and confirm a
|
|
21
|
+
* folder. Returns the chosen absolute directory. Only existing directories can
|
|
22
|
+
* be confirmed. Throws {@link CancelledError} if the user aborts.
|
|
23
|
+
*/
|
|
24
|
+
export declare function pickDirectory(startDir: string, purpose: string, opts?: {
|
|
25
|
+
allowTyped?: boolean;
|
|
26
|
+
showHidden?: boolean;
|
|
27
|
+
}): Promise<string>;
|
|
28
|
+
export interface MergeResult {
|
|
29
|
+
/** Full new file content to write. */
|
|
30
|
+
content: string;
|
|
31
|
+
/** True if the file already existed (we merged) vs. created fresh. */
|
|
32
|
+
existed: boolean;
|
|
33
|
+
/** Human-readable preview of what will be written (for confirmation). */
|
|
34
|
+
preview: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Merge a single named server entry into an MCP config file, without clobbering
|
|
38
|
+
* any existing servers. Supports JSON (nested serverMapPath) and TOML (Codex).
|
|
39
|
+
*/
|
|
40
|
+
export declare function mergeMcpConfig(filePath: string, format: ConfigFormat, serverMapPath: string[], serverName: string, entry: Record<string, unknown>): MergeResult;
|
|
41
|
+
/** Write merged content, creating parent dirs as needed. */
|
|
42
|
+
export declare function writeConfigFile(filePath: string, content: string): void;
|
|
43
|
+
export declare const RULE_START = "<!-- devsmind:rule:start -->";
|
|
44
|
+
export declare const RULE_END = "<!-- devsmind:rule:end -->";
|
|
45
|
+
/**
|
|
46
|
+
* Produce the new contents of a rules file.
|
|
47
|
+
* - `standalone`: the file is dedicated to DevsMind — write the (optionally
|
|
48
|
+
* wrapped) rule body outright.
|
|
49
|
+
* - `append-section`: merge a delimited DevsMind block into a shared file,
|
|
50
|
+
* replacing any prior block so re-runs update in place instead of duplicating.
|
|
51
|
+
*/
|
|
52
|
+
export declare function mergeRuleFile(filePath: string, ruleBody: string, style: 'standalone' | 'append-section', wrap?: (body: string) => string): MergeResult;
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.RULE_END = exports.RULE_START = exports.CancelledError = void 0;
|
|
40
|
+
exports.selectPrompt = selectPrompt;
|
|
41
|
+
exports.confirmPrompt = confirmPrompt;
|
|
42
|
+
exports.pickTarget = pickTarget;
|
|
43
|
+
exports.pickTransport = pickTransport;
|
|
44
|
+
exports.pickMcpScope = pickMcpScope;
|
|
45
|
+
exports.pickRuleScope = pickRuleScope;
|
|
46
|
+
exports.pickMode = pickMode;
|
|
47
|
+
exports.pickDirectory = pickDirectory;
|
|
48
|
+
exports.mergeMcpConfig = mergeMcpConfig;
|
|
49
|
+
exports.writeConfigFile = writeConfigFile;
|
|
50
|
+
exports.mergeRuleFile = mergeRuleFile;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const os = __importStar(require("os"));
|
|
54
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
55
|
+
const registry_1 = require("./registry");
|
|
56
|
+
/** Thrown when the user cancels a prompt (Esc / Ctrl-C). Callers treat it as a clean abort. */
|
|
57
|
+
class CancelledError extends Error {
|
|
58
|
+
constructor() {
|
|
59
|
+
super('cancelled');
|
|
60
|
+
this.name = 'CancelledError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.CancelledError = CancelledError;
|
|
64
|
+
function assertAnswer(value) {
|
|
65
|
+
if (value === undefined)
|
|
66
|
+
throw new CancelledError();
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
// ─── Basic prompt wrappers (abort on cancel) ─────────────────────────────────
|
|
70
|
+
async function selectPrompt(message, choices, initial = 0) {
|
|
71
|
+
const res = await (0, prompts_1.default)({ type: 'select', name: 'v', message, choices, initial });
|
|
72
|
+
return assertAnswer(res.v);
|
|
73
|
+
}
|
|
74
|
+
async function confirmPrompt(message, initial = true) {
|
|
75
|
+
const res = await (0, prompts_1.default)({ type: 'confirm', name: 'v', message, initial });
|
|
76
|
+
return assertAnswer(res.v);
|
|
77
|
+
}
|
|
78
|
+
// ─── Target / transport / scope / mode pickers ───────────────────────────────
|
|
79
|
+
async function pickTarget() {
|
|
80
|
+
const ides = registry_1.TARGETS.filter(t => t.kind === 'ide');
|
|
81
|
+
const clis = registry_1.TARGETS.filter(t => t.kind === 'cli');
|
|
82
|
+
const choices = [];
|
|
83
|
+
if (ides.length) {
|
|
84
|
+
choices.push({ title: '── IDEs ──', value: null });
|
|
85
|
+
for (const t of ides)
|
|
86
|
+
choices.push({ title: ` ${t.label}`, value: t });
|
|
87
|
+
}
|
|
88
|
+
if (clis.length) {
|
|
89
|
+
choices.push({ title: '── CLI tools ──', value: null });
|
|
90
|
+
for (const t of clis)
|
|
91
|
+
choices.push({ title: ` ${t.label}`, value: t });
|
|
92
|
+
}
|
|
93
|
+
// Skip the non-selectable header rows if one is chosen.
|
|
94
|
+
const picked = await selectPrompt('What are you working in?', choices, 1);
|
|
95
|
+
if (!picked) {
|
|
96
|
+
// Header row selected — re-ask.
|
|
97
|
+
return pickTarget();
|
|
98
|
+
}
|
|
99
|
+
return picked;
|
|
100
|
+
}
|
|
101
|
+
async function pickTransport(target) {
|
|
102
|
+
const transports = target.mcp.transports;
|
|
103
|
+
if (transports.length === 1)
|
|
104
|
+
return transports[0];
|
|
105
|
+
const describe = {
|
|
106
|
+
stdio: 'stdio — the tool launches DevsMind itself. Run `devsmind sync` after pulling graph changes.',
|
|
107
|
+
http: 'HTTP — connect to a server you start with `devsmind start`.',
|
|
108
|
+
};
|
|
109
|
+
return selectPrompt('Which connection type?', transports.map(t => ({ title: t.toUpperCase(), value: t, description: describe[t] })), 0);
|
|
110
|
+
}
|
|
111
|
+
async function pickMcpScope(target) {
|
|
112
|
+
const scopes = target.mcp.scopes;
|
|
113
|
+
if (scopes.length === 1)
|
|
114
|
+
return scopes[0];
|
|
115
|
+
return pickScopeGeneric(scopes, s => s.scope);
|
|
116
|
+
}
|
|
117
|
+
async function pickRuleScope(target) {
|
|
118
|
+
const scopes = target.rules.scopes;
|
|
119
|
+
if (scopes.length === 1)
|
|
120
|
+
return scopes[0];
|
|
121
|
+
return pickScopeGeneric(scopes, s => s.scope);
|
|
122
|
+
}
|
|
123
|
+
async function pickScopeGeneric(scopes, scopeOf) {
|
|
124
|
+
const label = {
|
|
125
|
+
project: 'This project only',
|
|
126
|
+
global: 'Global (all your projects)',
|
|
127
|
+
};
|
|
128
|
+
return selectPrompt('Which scope?', scopes.map(s => ({ title: label[scopeOf(s)], value: s })), 0);
|
|
129
|
+
}
|
|
130
|
+
async function pickMode() {
|
|
131
|
+
return selectPrompt('How do you want to do this?', [
|
|
132
|
+
{ title: '🤖 Let the terminal set it up for me', value: 'auto', description: 'Creates/merges the config file for you (with a preview + confirmation).' },
|
|
133
|
+
{ title: '📋 Just show me what to add (manual)', value: 'manual', description: 'Prints the exact file path and snippet to copy-paste.' },
|
|
134
|
+
]);
|
|
135
|
+
}
|
|
136
|
+
// ─── Directory navigator ("cd around, use this folder") ──────────────────────
|
|
137
|
+
/**
|
|
138
|
+
* Interactive directory browser. Lets the user cd up/down from `startDir`,
|
|
139
|
+
* type/paste a path (handy for other drives or far-away folders), and confirm a
|
|
140
|
+
* folder. Returns the chosen absolute directory. Only existing directories can
|
|
141
|
+
* be confirmed. Throws {@link CancelledError} if the user aborts.
|
|
142
|
+
*/
|
|
143
|
+
async function pickDirectory(startDir, purpose, opts = {}) {
|
|
144
|
+
const allowTyped = opts.allowTyped !== false;
|
|
145
|
+
let currentDir = path.resolve(startDir);
|
|
146
|
+
if (!existsDir(currentDir))
|
|
147
|
+
currentDir = process.cwd();
|
|
148
|
+
// Defensive cap: a human never navigates thousands of steps; this only trips
|
|
149
|
+
// if the prompt stream is misbehaving (e.g. non-interactive), and prevents a hang.
|
|
150
|
+
let guard = 0;
|
|
151
|
+
while (guard++ < 5000) {
|
|
152
|
+
console.log(`\n📂 ${purpose}`);
|
|
153
|
+
console.log(` Current: ${currentDir.replace(/\\/g, '/')}`);
|
|
154
|
+
const choices = [];
|
|
155
|
+
choices.push({ title: `✅ Use this folder`, value: { action: 'use' } });
|
|
156
|
+
const parent = path.dirname(currentDir);
|
|
157
|
+
if (parent !== currentDir) {
|
|
158
|
+
choices.push({ title: '⬆ Go up (..)', value: { action: 'up' } });
|
|
159
|
+
}
|
|
160
|
+
if (allowTyped) {
|
|
161
|
+
choices.push({ title: '⌨️ Type / paste a path…', value: { action: 'type' } });
|
|
162
|
+
}
|
|
163
|
+
let subdirs = [];
|
|
164
|
+
try {
|
|
165
|
+
subdirs = fs.readdirSync(currentDir, { withFileTypes: true })
|
|
166
|
+
.filter(d => d.isDirectory() && (opts.showHidden || !d.name.startsWith('.') || d.name === '.devmind'))
|
|
167
|
+
.map(d => d.name)
|
|
168
|
+
.sort();
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
subdirs = [];
|
|
172
|
+
}
|
|
173
|
+
for (const name of subdirs) {
|
|
174
|
+
choices.push({ title: `📁 ${name}/`, value: { action: 'into', dir: name } });
|
|
175
|
+
}
|
|
176
|
+
const res = await selectPrompt('Navigate or select:', choices, 0);
|
|
177
|
+
if (res.action === 'use')
|
|
178
|
+
return currentDir;
|
|
179
|
+
if (res.action === 'up')
|
|
180
|
+
currentDir = parent;
|
|
181
|
+
if (res.action === 'into' && res.dir)
|
|
182
|
+
currentDir = path.join(currentDir, res.dir);
|
|
183
|
+
if (res.action === 'type') {
|
|
184
|
+
const typed = await (0, prompts_1.default)({ type: 'text', name: 'v', message: 'Enter a folder path:', initial: currentDir });
|
|
185
|
+
const v = typed.v;
|
|
186
|
+
if (typeof v === 'string' && v.trim()) {
|
|
187
|
+
const resolved = path.resolve(v.trim().replace(/^~(?=[\\/]|$)/, os.homedir()));
|
|
188
|
+
if (existsDir(resolved)) {
|
|
189
|
+
currentDir = resolved;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log(` ⚠️ Not an existing folder: ${resolved.replace(/\\/g, '/')}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
throw new CancelledError();
|
|
198
|
+
}
|
|
199
|
+
function existsDir(p) {
|
|
200
|
+
try {
|
|
201
|
+
return fs.statSync(p).isDirectory();
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Merge a single named server entry into an MCP config file, without clobbering
|
|
209
|
+
* any existing servers. Supports JSON (nested serverMapPath) and TOML (Codex).
|
|
210
|
+
*/
|
|
211
|
+
function mergeMcpConfig(filePath, format, serverMapPath, serverName, entry) {
|
|
212
|
+
const existed = fs.existsSync(filePath);
|
|
213
|
+
if (format === 'toml') {
|
|
214
|
+
return mergeTomlServer(filePath, serverMapPath, serverName, entry, existed);
|
|
215
|
+
}
|
|
216
|
+
// JSON (and JSONC-tolerant tools — we emit clean JSON).
|
|
217
|
+
let root = {};
|
|
218
|
+
if (existed) {
|
|
219
|
+
try {
|
|
220
|
+
const txt = fs.readFileSync(filePath, 'utf-8').trim();
|
|
221
|
+
root = txt ? JSON.parse(txt) : {};
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
throw new Error(`${filePath} exists but is not valid JSON. Fix or remove it, then re-run (or use manual mode).`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Walk/create the nested server-map container.
|
|
228
|
+
let container = root;
|
|
229
|
+
for (const key of serverMapPath) {
|
|
230
|
+
if (typeof container[key] !== 'object' || container[key] === null || Array.isArray(container[key])) {
|
|
231
|
+
container[key] = {};
|
|
232
|
+
}
|
|
233
|
+
container = container[key];
|
|
234
|
+
}
|
|
235
|
+
container[serverName] = entry;
|
|
236
|
+
const content = JSON.stringify(root, null, 2) + '\n';
|
|
237
|
+
return { content, existed, preview: content };
|
|
238
|
+
}
|
|
239
|
+
// ─── Minimal TOML section writer (for Codex ~/.codex/config.toml) ─────────────
|
|
240
|
+
function tomlValue(v) {
|
|
241
|
+
if (typeof v === 'string')
|
|
242
|
+
return JSON.stringify(v); // TOML basic strings match JSON string escaping
|
|
243
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
244
|
+
return String(v);
|
|
245
|
+
if (Array.isArray(v))
|
|
246
|
+
return '[' + v.map(tomlValue).join(', ') + ']';
|
|
247
|
+
// Nested tables are not expected in our entries; fall back to JSON-ish inline.
|
|
248
|
+
return JSON.stringify(v);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Render a `[header]` table for the given entry. Only flat key/value pairs and
|
|
252
|
+
* arrays of primitives are expected (command/args/url/headers-as-inline).
|
|
253
|
+
*/
|
|
254
|
+
function renderTomlTable(header, entry) {
|
|
255
|
+
const lines = [`[${header}]`];
|
|
256
|
+
for (const [k, v] of Object.entries(entry)) {
|
|
257
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
258
|
+
// Inline table for objects like env/headers.
|
|
259
|
+
const inner = Object.entries(v)
|
|
260
|
+
.map(([ik, iv]) => `${ik} = ${tomlValue(iv)}`)
|
|
261
|
+
.join(', ');
|
|
262
|
+
lines.push(`${k} = { ${inner} }`);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
lines.push(`${k} = ${tomlValue(v)}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return lines.join('\n') + '\n';
|
|
269
|
+
}
|
|
270
|
+
function mergeTomlServer(filePath, serverMapPath, serverName, entry, existed) {
|
|
271
|
+
// Header e.g. "mcp_servers.devsmind"
|
|
272
|
+
const header = [...serverMapPath, serverName].join('.');
|
|
273
|
+
const table = renderTomlTable(header, entry);
|
|
274
|
+
let existing = '';
|
|
275
|
+
if (existed) {
|
|
276
|
+
try {
|
|
277
|
+
existing = fs.readFileSync(filePath, 'utf-8');
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
existing = '';
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
let content;
|
|
284
|
+
const headerLine = `[${header}]`;
|
|
285
|
+
if (existing.includes(headerLine)) {
|
|
286
|
+
// Replace the existing table (from its header to the next table header or EOF).
|
|
287
|
+
const lines = existing.split(/\r?\n/);
|
|
288
|
+
const start = lines.findIndex(l => l.trim() === headerLine);
|
|
289
|
+
let end = lines.length;
|
|
290
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
291
|
+
if (/^\s*\[/.test(lines[i])) {
|
|
292
|
+
end = i;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const before = lines.slice(0, start).join('\n').replace(/\s*$/, '');
|
|
297
|
+
const after = lines.slice(end).join('\n').replace(/^\s*/, '');
|
|
298
|
+
content = [before, table.trimEnd(), after].filter(s => s.length).join('\n\n') + '\n';
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
const base = existing.trimEnd();
|
|
302
|
+
content = (base ? base + '\n\n' : '') + table;
|
|
303
|
+
}
|
|
304
|
+
return { content, existed, preview: table };
|
|
305
|
+
}
|
|
306
|
+
/** Write merged content, creating parent dirs as needed. */
|
|
307
|
+
function writeConfigFile(filePath, content) {
|
|
308
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
309
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
310
|
+
}
|
|
311
|
+
// ─── Rule file merging ───────────────────────────────────────────────────────
|
|
312
|
+
exports.RULE_START = '<!-- devsmind:rule:start -->';
|
|
313
|
+
exports.RULE_END = '<!-- devsmind:rule:end -->';
|
|
314
|
+
/**
|
|
315
|
+
* Produce the new contents of a rules file.
|
|
316
|
+
* - `standalone`: the file is dedicated to DevsMind — write the (optionally
|
|
317
|
+
* wrapped) rule body outright.
|
|
318
|
+
* - `append-section`: merge a delimited DevsMind block into a shared file,
|
|
319
|
+
* replacing any prior block so re-runs update in place instead of duplicating.
|
|
320
|
+
*/
|
|
321
|
+
function mergeRuleFile(filePath, ruleBody, style, wrap) {
|
|
322
|
+
const existed = fs.existsSync(filePath);
|
|
323
|
+
if (style === 'standalone') {
|
|
324
|
+
const body = wrap ? wrap(ruleBody) : ruleBody;
|
|
325
|
+
const content = body.replace(/\n*$/, '\n');
|
|
326
|
+
return { content, existed, preview: content };
|
|
327
|
+
}
|
|
328
|
+
const block = `${exports.RULE_START}\n${ruleBody}\n${exports.RULE_END}`;
|
|
329
|
+
const existing = existed ? safeRead(filePath) : '';
|
|
330
|
+
const startIdx = existing.indexOf(exports.RULE_START);
|
|
331
|
+
const endIdx = existing.indexOf(exports.RULE_END);
|
|
332
|
+
let content;
|
|
333
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
334
|
+
content = existing.slice(0, startIdx) + block + existing.slice(endIdx + exports.RULE_END.length);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
const base = existing.replace(/\n*$/, '');
|
|
338
|
+
content = (base ? base + '\n\n' : '') + block;
|
|
339
|
+
}
|
|
340
|
+
if (!content.endsWith('\n'))
|
|
341
|
+
content += '\n';
|
|
342
|
+
return { content, existed, preview: block };
|
|
343
|
+
}
|
|
344
|
+
function safeRead(filePath) {
|
|
345
|
+
try {
|
|
346
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
return '';
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/cli/integrations/prompt.ts"],"names":[],"mappings":"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"}
|