devsmind-mcp 2.1.1 → 2.2.2
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 +189 -28
- package/dist/cli/index.js +52 -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/memory.d.ts +11 -0
- package/dist/cli/integrations/memory.js +151 -0
- package/dist/cli/integrations/memory.js.map +1 -0
- package/dist/cli/integrations/prompt.d.ts +54 -0
- package/dist/cli/integrations/prompt.js +360 -0
- package/dist/cli/integrations/prompt.js.map +1 -0
- package/dist/cli/integrations/registry.d.ts +102 -0
- package/dist/cli/integrations/registry.js +330 -0
- package/dist/cli/integrations/registry.js.map +1 -0
- package/dist/cli/rule.d.ts +14 -1
- package/dist/cli/rule.js +119 -57
- 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 +21 -1
- package/dist/db/database.js +35 -2
- package/dist/db/database.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.js +57 -25
- package/dist/mcp/server.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/dist/utils/scanner.d.ts +7 -0
- package/dist/utils/scanner.js +9 -3
- package/dist/utils/scanner.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,360 @@
|
|
|
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.pickMemoryScope = pickMemoryScope;
|
|
47
|
+
exports.pickMode = pickMode;
|
|
48
|
+
exports.pickDirectory = pickDirectory;
|
|
49
|
+
exports.mergeMcpConfig = mergeMcpConfig;
|
|
50
|
+
exports.writeConfigFile = writeConfigFile;
|
|
51
|
+
exports.mergeRuleFile = mergeRuleFile;
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const os = __importStar(require("os"));
|
|
55
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
56
|
+
const registry_1 = require("./registry");
|
|
57
|
+
/** Thrown when the user cancels a prompt (Esc / Ctrl-C). Callers treat it as a clean abort. */
|
|
58
|
+
class CancelledError extends Error {
|
|
59
|
+
constructor() {
|
|
60
|
+
super('cancelled');
|
|
61
|
+
this.name = 'CancelledError';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.CancelledError = CancelledError;
|
|
65
|
+
function assertAnswer(value) {
|
|
66
|
+
if (value === undefined)
|
|
67
|
+
throw new CancelledError();
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
// ─── Basic prompt wrappers (abort on cancel) ─────────────────────────────────
|
|
71
|
+
async function selectPrompt(message, choices, initial = 0) {
|
|
72
|
+
const res = await (0, prompts_1.default)({ type: 'select', name: 'v', message, choices, initial });
|
|
73
|
+
return assertAnswer(res.v);
|
|
74
|
+
}
|
|
75
|
+
async function confirmPrompt(message, initial = true) {
|
|
76
|
+
const res = await (0, prompts_1.default)({ type: 'confirm', name: 'v', message, initial });
|
|
77
|
+
return assertAnswer(res.v);
|
|
78
|
+
}
|
|
79
|
+
// ─── Target / transport / scope / mode pickers ───────────────────────────────
|
|
80
|
+
async function pickTarget() {
|
|
81
|
+
const ides = registry_1.TARGETS.filter(t => t.kind === 'ide');
|
|
82
|
+
const clis = registry_1.TARGETS.filter(t => t.kind === 'cli');
|
|
83
|
+
const choices = [];
|
|
84
|
+
if (ides.length) {
|
|
85
|
+
choices.push({ title: '── IDEs ──', value: null });
|
|
86
|
+
for (const t of ides)
|
|
87
|
+
choices.push({ title: ` ${t.label}`, value: t });
|
|
88
|
+
}
|
|
89
|
+
if (clis.length) {
|
|
90
|
+
choices.push({ title: '── CLI tools ──', value: null });
|
|
91
|
+
for (const t of clis)
|
|
92
|
+
choices.push({ title: ` ${t.label}`, value: t });
|
|
93
|
+
}
|
|
94
|
+
// Skip the non-selectable header rows if one is chosen.
|
|
95
|
+
const picked = await selectPrompt('What are you working in?', choices, 1);
|
|
96
|
+
if (!picked) {
|
|
97
|
+
// Header row selected — re-ask.
|
|
98
|
+
return pickTarget();
|
|
99
|
+
}
|
|
100
|
+
return picked;
|
|
101
|
+
}
|
|
102
|
+
async function pickTransport(target) {
|
|
103
|
+
const transports = target.mcp.transports;
|
|
104
|
+
if (transports.length === 1)
|
|
105
|
+
return transports[0];
|
|
106
|
+
const describe = {
|
|
107
|
+
stdio: 'stdio — the tool launches DevsMind itself. Run `devsmind sync` after pulling graph changes.',
|
|
108
|
+
http: 'HTTP — connect to a server you start with `devsmind start`.',
|
|
109
|
+
};
|
|
110
|
+
return selectPrompt('Which connection type?', transports.map(t => ({ title: t.toUpperCase(), value: t, description: describe[t] })), 0);
|
|
111
|
+
}
|
|
112
|
+
async function pickMcpScope(target) {
|
|
113
|
+
const scopes = target.mcp.scopes;
|
|
114
|
+
if (scopes.length === 1)
|
|
115
|
+
return scopes[0];
|
|
116
|
+
return pickScopeGeneric(scopes, s => s.scope);
|
|
117
|
+
}
|
|
118
|
+
async function pickRuleScope(target) {
|
|
119
|
+
const scopes = target.rules.scopes;
|
|
120
|
+
if (scopes.length === 1)
|
|
121
|
+
return scopes[0];
|
|
122
|
+
return pickScopeGeneric(scopes, s => s.scope);
|
|
123
|
+
}
|
|
124
|
+
/** Assumes `target.memory.supported` and `scopes` are already checked by the caller. */
|
|
125
|
+
async function pickMemoryScope(target) {
|
|
126
|
+
const scopes = target.memory.scopes ?? [];
|
|
127
|
+
if (scopes.length === 1)
|
|
128
|
+
return scopes[0];
|
|
129
|
+
return pickScopeGeneric(scopes, s => s.scope);
|
|
130
|
+
}
|
|
131
|
+
async function pickScopeGeneric(scopes, scopeOf) {
|
|
132
|
+
const label = {
|
|
133
|
+
project: 'This project only',
|
|
134
|
+
global: 'Global (all your projects)',
|
|
135
|
+
};
|
|
136
|
+
return selectPrompt('Which scope?', scopes.map(s => ({ title: label[scopeOf(s)], value: s })), 0);
|
|
137
|
+
}
|
|
138
|
+
async function pickMode() {
|
|
139
|
+
return selectPrompt('How do you want to do this?', [
|
|
140
|
+
{ title: '🤖 Let the terminal set it up for me', value: 'auto', description: 'Creates/merges the config file for you (with a preview + confirmation).' },
|
|
141
|
+
{ title: '📋 Just show me what to add (manual)', value: 'manual', description: 'Prints the exact file path and snippet to copy-paste.' },
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
// ─── Directory navigator ("cd around, use this folder") ──────────────────────
|
|
145
|
+
/**
|
|
146
|
+
* Interactive directory browser. Lets the user cd up/down from `startDir`,
|
|
147
|
+
* type/paste a path (handy for other drives or far-away folders), and confirm a
|
|
148
|
+
* folder. Returns the chosen absolute directory. Only existing directories can
|
|
149
|
+
* be confirmed. Throws {@link CancelledError} if the user aborts.
|
|
150
|
+
*/
|
|
151
|
+
async function pickDirectory(startDir, purpose, opts = {}) {
|
|
152
|
+
const allowTyped = opts.allowTyped !== false;
|
|
153
|
+
let currentDir = path.resolve(startDir);
|
|
154
|
+
if (!existsDir(currentDir))
|
|
155
|
+
currentDir = process.cwd();
|
|
156
|
+
// Defensive cap: a human never navigates thousands of steps; this only trips
|
|
157
|
+
// if the prompt stream is misbehaving (e.g. non-interactive), and prevents a hang.
|
|
158
|
+
let guard = 0;
|
|
159
|
+
while (guard++ < 5000) {
|
|
160
|
+
console.log(`\n📂 ${purpose}`);
|
|
161
|
+
console.log(` Current: ${currentDir.replace(/\\/g, '/')}`);
|
|
162
|
+
const choices = [];
|
|
163
|
+
choices.push({ title: `✅ Use this folder`, value: { action: 'use' } });
|
|
164
|
+
const parent = path.dirname(currentDir);
|
|
165
|
+
if (parent !== currentDir) {
|
|
166
|
+
choices.push({ title: '⬆ Go up (..)', value: { action: 'up' } });
|
|
167
|
+
}
|
|
168
|
+
if (allowTyped) {
|
|
169
|
+
choices.push({ title: '⌨️ Type / paste a path…', value: { action: 'type' } });
|
|
170
|
+
}
|
|
171
|
+
let subdirs = [];
|
|
172
|
+
try {
|
|
173
|
+
subdirs = fs.readdirSync(currentDir, { withFileTypes: true })
|
|
174
|
+
.filter(d => d.isDirectory() && (opts.showHidden || !d.name.startsWith('.') || d.name === '.devmind'))
|
|
175
|
+
.map(d => d.name)
|
|
176
|
+
.sort();
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
subdirs = [];
|
|
180
|
+
}
|
|
181
|
+
for (const name of subdirs) {
|
|
182
|
+
choices.push({ title: `📁 ${name}/`, value: { action: 'into', dir: name } });
|
|
183
|
+
}
|
|
184
|
+
const res = await selectPrompt('Navigate or select:', choices, 0);
|
|
185
|
+
if (res.action === 'use')
|
|
186
|
+
return currentDir;
|
|
187
|
+
if (res.action === 'up')
|
|
188
|
+
currentDir = parent;
|
|
189
|
+
if (res.action === 'into' && res.dir)
|
|
190
|
+
currentDir = path.join(currentDir, res.dir);
|
|
191
|
+
if (res.action === 'type') {
|
|
192
|
+
const typed = await (0, prompts_1.default)({ type: 'text', name: 'v', message: 'Enter a folder path:', initial: currentDir });
|
|
193
|
+
const v = typed.v;
|
|
194
|
+
if (typeof v === 'string' && v.trim()) {
|
|
195
|
+
const resolved = path.resolve(v.trim().replace(/^~(?=[\\/]|$)/, os.homedir()));
|
|
196
|
+
if (existsDir(resolved)) {
|
|
197
|
+
currentDir = resolved;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
console.log(` ⚠️ Not an existing folder: ${resolved.replace(/\\/g, '/')}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
throw new CancelledError();
|
|
206
|
+
}
|
|
207
|
+
function existsDir(p) {
|
|
208
|
+
try {
|
|
209
|
+
return fs.statSync(p).isDirectory();
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Merge a single named server entry into an MCP config file, without clobbering
|
|
217
|
+
* any existing servers. Supports JSON (nested serverMapPath) and TOML (Codex).
|
|
218
|
+
*/
|
|
219
|
+
function mergeMcpConfig(filePath, format, serverMapPath, serverName, entry) {
|
|
220
|
+
const existed = fs.existsSync(filePath);
|
|
221
|
+
if (format === 'toml') {
|
|
222
|
+
return mergeTomlServer(filePath, serverMapPath, serverName, entry, existed);
|
|
223
|
+
}
|
|
224
|
+
// JSON (and JSONC-tolerant tools — we emit clean JSON).
|
|
225
|
+
let root = {};
|
|
226
|
+
if (existed) {
|
|
227
|
+
try {
|
|
228
|
+
const txt = fs.readFileSync(filePath, 'utf-8').trim();
|
|
229
|
+
root = txt ? JSON.parse(txt) : {};
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
throw new Error(`${filePath} exists but is not valid JSON. Fix or remove it, then re-run (or use manual mode).`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Walk/create the nested server-map container.
|
|
236
|
+
let container = root;
|
|
237
|
+
for (const key of serverMapPath) {
|
|
238
|
+
if (typeof container[key] !== 'object' || container[key] === null || Array.isArray(container[key])) {
|
|
239
|
+
container[key] = {};
|
|
240
|
+
}
|
|
241
|
+
container = container[key];
|
|
242
|
+
}
|
|
243
|
+
container[serverName] = entry;
|
|
244
|
+
const content = JSON.stringify(root, null, 2) + '\n';
|
|
245
|
+
return { content, existed, preview: content };
|
|
246
|
+
}
|
|
247
|
+
// ─── Minimal TOML section writer (for Codex ~/.codex/config.toml) ─────────────
|
|
248
|
+
function tomlValue(v) {
|
|
249
|
+
if (typeof v === 'string')
|
|
250
|
+
return JSON.stringify(v); // TOML basic strings match JSON string escaping
|
|
251
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
252
|
+
return String(v);
|
|
253
|
+
if (Array.isArray(v))
|
|
254
|
+
return '[' + v.map(tomlValue).join(', ') + ']';
|
|
255
|
+
// Nested tables are not expected in our entries; fall back to JSON-ish inline.
|
|
256
|
+
return JSON.stringify(v);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Render a `[header]` table for the given entry. Only flat key/value pairs and
|
|
260
|
+
* arrays of primitives are expected (command/args/url/headers-as-inline).
|
|
261
|
+
*/
|
|
262
|
+
function renderTomlTable(header, entry) {
|
|
263
|
+
const lines = [`[${header}]`];
|
|
264
|
+
for (const [k, v] of Object.entries(entry)) {
|
|
265
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
266
|
+
// Inline table for objects like env/headers.
|
|
267
|
+
const inner = Object.entries(v)
|
|
268
|
+
.map(([ik, iv]) => `${ik} = ${tomlValue(iv)}`)
|
|
269
|
+
.join(', ');
|
|
270
|
+
lines.push(`${k} = { ${inner} }`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
lines.push(`${k} = ${tomlValue(v)}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return lines.join('\n') + '\n';
|
|
277
|
+
}
|
|
278
|
+
function mergeTomlServer(filePath, serverMapPath, serverName, entry, existed) {
|
|
279
|
+
// Header e.g. "mcp_servers.devsmind"
|
|
280
|
+
const header = [...serverMapPath, serverName].join('.');
|
|
281
|
+
const table = renderTomlTable(header, entry);
|
|
282
|
+
let existing = '';
|
|
283
|
+
if (existed) {
|
|
284
|
+
try {
|
|
285
|
+
existing = fs.readFileSync(filePath, 'utf-8');
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
existing = '';
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
let content;
|
|
292
|
+
const headerLine = `[${header}]`;
|
|
293
|
+
if (existing.includes(headerLine)) {
|
|
294
|
+
// Replace the existing table (from its header to the next table header or EOF).
|
|
295
|
+
const lines = existing.split(/\r?\n/);
|
|
296
|
+
const start = lines.findIndex(l => l.trim() === headerLine);
|
|
297
|
+
let end = lines.length;
|
|
298
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
299
|
+
if (/^\s*\[/.test(lines[i])) {
|
|
300
|
+
end = i;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const before = lines.slice(0, start).join('\n').replace(/\s*$/, '');
|
|
305
|
+
const after = lines.slice(end).join('\n').replace(/^\s*/, '');
|
|
306
|
+
content = [before, table.trimEnd(), after].filter(s => s.length).join('\n\n') + '\n';
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
const base = existing.trimEnd();
|
|
310
|
+
content = (base ? base + '\n\n' : '') + table;
|
|
311
|
+
}
|
|
312
|
+
return { content, existed, preview: table };
|
|
313
|
+
}
|
|
314
|
+
/** Write merged content, creating parent dirs as needed. */
|
|
315
|
+
function writeConfigFile(filePath, content) {
|
|
316
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
317
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
318
|
+
}
|
|
319
|
+
// ─── Rule file merging ───────────────────────────────────────────────────────
|
|
320
|
+
exports.RULE_START = '<!-- devsmind:rule:start -->';
|
|
321
|
+
exports.RULE_END = '<!-- devsmind:rule:end -->';
|
|
322
|
+
/**
|
|
323
|
+
* Produce the new contents of a rules file.
|
|
324
|
+
* - `standalone`: the file is dedicated to DevsMind — write the (optionally
|
|
325
|
+
* wrapped) rule body outright.
|
|
326
|
+
* - `append-section`: merge a delimited DevsMind block into a shared file,
|
|
327
|
+
* replacing any prior block so re-runs update in place instead of duplicating.
|
|
328
|
+
*/
|
|
329
|
+
function mergeRuleFile(filePath, ruleBody, style, wrap) {
|
|
330
|
+
const existed = fs.existsSync(filePath);
|
|
331
|
+
if (style === 'standalone') {
|
|
332
|
+
const body = wrap ? wrap(ruleBody) : ruleBody;
|
|
333
|
+
const content = body.replace(/\n*$/, '\n');
|
|
334
|
+
return { content, existed, preview: content };
|
|
335
|
+
}
|
|
336
|
+
const block = `${exports.RULE_START}\n${ruleBody}\n${exports.RULE_END}`;
|
|
337
|
+
const existing = existed ? safeRead(filePath) : '';
|
|
338
|
+
const startIdx = existing.indexOf(exports.RULE_START);
|
|
339
|
+
const endIdx = existing.indexOf(exports.RULE_END);
|
|
340
|
+
let content;
|
|
341
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
342
|
+
content = existing.slice(0, startIdx) + block + existing.slice(endIdx + exports.RULE_END.length);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
const base = existing.replace(/\n*$/, '');
|
|
346
|
+
content = (base ? base + '\n\n' : '') + block;
|
|
347
|
+
}
|
|
348
|
+
if (!content.endsWith('\n'))
|
|
349
|
+
content += '\n';
|
|
350
|
+
return { content, existed, preview: block };
|
|
351
|
+
}
|
|
352
|
+
function safeRead(filePath) {
|
|
353
|
+
try {
|
|
354
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return '';
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
//# 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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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry of AI coding tools DevsMind can integrate with. This single table
|
|
3
|
+
* drives both `devsmind mcp` (add the MCP server) and `devsmind rule` (write the
|
|
4
|
+
* workspace rule). To fix or add a tool, edit an entry here — nothing else.
|
|
5
|
+
*/
|
|
6
|
+
export type Transport = 'stdio' | 'http';
|
|
7
|
+
export type ConfigFormat = 'json' | 'toml';
|
|
8
|
+
export type Scope = 'project' | 'global';
|
|
9
|
+
/** A path that may differ per-OS. Strings may contain a leading `~` for the home dir. */
|
|
10
|
+
export type OsPath = string | {
|
|
11
|
+
win32: string;
|
|
12
|
+
darwin: string;
|
|
13
|
+
linux: string;
|
|
14
|
+
};
|
|
15
|
+
export interface McpScope {
|
|
16
|
+
scope: Scope;
|
|
17
|
+
/** Project paths are relative to the workspace root; global paths are absolute (may start with `~`). */
|
|
18
|
+
file: OsPath;
|
|
19
|
+
format: ConfigFormat;
|
|
20
|
+
/** Key-path to the server map, e.g. ['mcpServers'] or ['servers'] or ['mcp_servers']. */
|
|
21
|
+
serverMapPath: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface RuleScope {
|
|
24
|
+
scope: Scope;
|
|
25
|
+
file: OsPath;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Where to seed a tool's own persistent agent-memory/skills store — distinct
|
|
29
|
+
* from `rules`, which is a static file a human maintains. Only populated for
|
|
30
|
+
* tools where research confirmed the tool actually reads back a file it didn't
|
|
31
|
+
* create itself (see `memory.supported` below); everything else gets manual
|
|
32
|
+
* guidance instead of a write that might silently do nothing or get clobbered.
|
|
33
|
+
*/
|
|
34
|
+
export interface MemoryScope {
|
|
35
|
+
scope: Scope;
|
|
36
|
+
/** Directory to seed. For tools whose exact path includes an undocumented
|
|
37
|
+
* per-project hash (Claude Code), this is the nearest KNOWN parent — the
|
|
38
|
+
* user confirms the rest via the folder navigator. */
|
|
39
|
+
dir: OsPath;
|
|
40
|
+
/** Filename DevsMind owns within that directory — never the tool's own index/log file. */
|
|
41
|
+
file: string;
|
|
42
|
+
format: 'markdown' | 'skill-md';
|
|
43
|
+
/** True when `dir` is only a starting point and the user must navigate to the real folder. */
|
|
44
|
+
needsUserConfirmedDir?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface IdeTarget {
|
|
47
|
+
id: string;
|
|
48
|
+
label: string;
|
|
49
|
+
kind: 'ide' | 'cli';
|
|
50
|
+
mcp: {
|
|
51
|
+
scopes: McpScope[];
|
|
52
|
+
/** Supported transports; first is the preferred default. */
|
|
53
|
+
transports: Transport[];
|
|
54
|
+
/** The value object placed under serverMap['devsmind'] for a given transport. */
|
|
55
|
+
entry: (t: Transport, ctx: EntryContext) => Record<string, unknown>;
|
|
56
|
+
/** Optional CLI one-liner installer (e.g. `claude mcp add ...`). */
|
|
57
|
+
cliInstaller?: (t: Transport, ctx: EntryContext) => string;
|
|
58
|
+
/** Extra guidance printed in manual mode. */
|
|
59
|
+
note?: string;
|
|
60
|
+
};
|
|
61
|
+
rules: {
|
|
62
|
+
scopes: RuleScope[];
|
|
63
|
+
/** `standalone` = dedicated devsmind file; `append-section` = merge a delimited block into a shared file. */
|
|
64
|
+
style: 'standalone' | 'append-section';
|
|
65
|
+
/** Optional transform of the rule body before writing (e.g. Cursor .mdc frontmatter). */
|
|
66
|
+
wrap?: (body: string) => string;
|
|
67
|
+
};
|
|
68
|
+
memory: {
|
|
69
|
+
/** False when no safe write path exists — manual guidance only, no file is ever touched. */
|
|
70
|
+
supported: boolean;
|
|
71
|
+
/** The tool's own name for this feature — use it verbatim in prompts, not a generic "memory". */
|
|
72
|
+
featureName: string;
|
|
73
|
+
scopes?: MemoryScope[];
|
|
74
|
+
wrap?: (body: string) => string;
|
|
75
|
+
/** Shown (instead of writing) when supported is false, or as extra context alongside a write. */
|
|
76
|
+
note: string;
|
|
77
|
+
/** Claude Code only: also offer to append a one-line pointer into MEMORY.md so an
|
|
78
|
+
* unreferenced topic file (loaded only "on demand") is actually discoverable. */
|
|
79
|
+
pointerFile?: {
|
|
80
|
+
file: string;
|
|
81
|
+
style: 'append-section';
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Context available when rendering a server entry. */
|
|
86
|
+
export interface EntryContext {
|
|
87
|
+
devmindDir: string;
|
|
88
|
+
port: number;
|
|
89
|
+
}
|
|
90
|
+
/** Standard stdio entry: the IDE spawns `devsmind start --stdio`. */
|
|
91
|
+
export declare function stdioEntry(): Record<string, unknown>;
|
|
92
|
+
/** Standard HTTP entry: connect to the already-running server. */
|
|
93
|
+
export declare function httpEntry(ctx: EntryContext): Record<string, unknown>;
|
|
94
|
+
/** Resolve an {@link OsPath} to a concrete string for the current platform, expanding a leading `~`. */
|
|
95
|
+
export declare function resolveOsPath(p: OsPath): string;
|
|
96
|
+
/**
|
|
97
|
+
* Resolve the absolute file path for a config/rule scope.
|
|
98
|
+
* Project scopes are joined onto `workspaceRoot`; global scopes are absolute.
|
|
99
|
+
*/
|
|
100
|
+
export declare function resolveScopeFile(file: OsPath, scope: Scope, workspaceRoot: string): string;
|
|
101
|
+
export declare const TARGETS: IdeTarget[];
|
|
102
|
+
export declare function getTarget(id: string): IdeTarget | undefined;
|