@infinitedusky/indusk-mcp 1.4.2 → 1.4.4
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/bin/commands/init.js +38 -0
- package/dist/bin/commands/update.js +86 -1
- package/package.json +1 -1
|
@@ -267,6 +267,44 @@ export async function init(projectRoot, options = {}) {
|
|
|
267
267
|
console.info(` ${ext.manifest.name}: ${result.slice(0, 100)}`);
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
+
// Print expected .mcp.json config for extensions with mcp_server
|
|
271
|
+
if (ext.manifest.mcp_server) {
|
|
272
|
+
const mcpJsonPath = join(projectRoot, ".mcp.json");
|
|
273
|
+
let hasMcpEntry = false;
|
|
274
|
+
if (existsSync(mcpJsonPath)) {
|
|
275
|
+
try {
|
|
276
|
+
const mcpConfig = JSON.parse(readFileSync(mcpJsonPath, "utf-8"));
|
|
277
|
+
hasMcpEntry = !!mcpConfig?.mcpServers?.[ext.manifest.name];
|
|
278
|
+
}
|
|
279
|
+
catch { }
|
|
280
|
+
}
|
|
281
|
+
if (!hasMcpEntry) {
|
|
282
|
+
const srv = ext.manifest.mcp_server;
|
|
283
|
+
const config = {};
|
|
284
|
+
if (srv.type)
|
|
285
|
+
config.type = srv.type;
|
|
286
|
+
if (srv.url)
|
|
287
|
+
config.url = srv.url;
|
|
288
|
+
if (srv.command)
|
|
289
|
+
config.command = srv.command;
|
|
290
|
+
if (srv.args)
|
|
291
|
+
config.args = srv.args;
|
|
292
|
+
if (srv.headers)
|
|
293
|
+
config.headers = srv.headers;
|
|
294
|
+
if (srv.env)
|
|
295
|
+
config.env = srv.env;
|
|
296
|
+
console.info(`\n ${ext.manifest.name}: add this to .mcp.json:\n`);
|
|
297
|
+
console.info(` "${ext.manifest.name}": ${JSON.stringify(config, null, " ")}\n`);
|
|
298
|
+
if (srv.setup_instructions) {
|
|
299
|
+
for (const instruction of srv.setup_instructions) {
|
|
300
|
+
console.info(` ${instruction}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
console.info(` ${ext.manifest.name}: .mcp.json entry exists`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
270
308
|
}
|
|
271
309
|
if (enabledExts.length === 0) {
|
|
272
310
|
console.info(" no extensions enabled — run 'extensions enable' to add tool integrations");
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { cpSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { globSync } from "glob";
|
|
6
|
+
import { loadExtension } from "../../lib/extension-loader.js";
|
|
6
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
8
|
const packageRoot = join(__dirname, "../../..");
|
|
8
9
|
function fileHash(path) {
|
|
@@ -137,4 +138,88 @@ export async function update(projectRoot) {
|
|
|
137
138
|
else {
|
|
138
139
|
console.info(" hooks not installed (run init to install)");
|
|
139
140
|
}
|
|
141
|
+
// Sync enabled built-in extensions (manifests, skills, print mcp_server config)
|
|
142
|
+
console.info("\nChecking for extension updates...\n");
|
|
143
|
+
const builtinDir = join(packageRoot, "extensions");
|
|
144
|
+
const enabledDir = join(projectRoot, ".indusk/extensions");
|
|
145
|
+
let extUpdated = 0;
|
|
146
|
+
let extCurrent = 0;
|
|
147
|
+
if (existsSync(builtinDir) && existsSync(enabledDir)) {
|
|
148
|
+
const enabledFiles = readdirSync(enabledDir).filter((f) => f.endsWith(".json") && !f.startsWith("."));
|
|
149
|
+
for (const file of enabledFiles) {
|
|
150
|
+
const name = file.replace(".json", "");
|
|
151
|
+
const builtinManifest = join(builtinDir, name, "manifest.json");
|
|
152
|
+
const enabledManifest = join(enabledDir, file);
|
|
153
|
+
// Only sync built-in extensions (skip third-party)
|
|
154
|
+
if (!existsSync(builtinManifest))
|
|
155
|
+
continue;
|
|
156
|
+
const sourceH = fileHash(builtinManifest);
|
|
157
|
+
const targetH = fileHash(enabledManifest);
|
|
158
|
+
if (sourceH !== targetH) {
|
|
159
|
+
cpSync(builtinManifest, enabledManifest);
|
|
160
|
+
console.info(` updated: ${name} manifest`);
|
|
161
|
+
extUpdated++;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.info(` current: ${name}`);
|
|
165
|
+
extCurrent++;
|
|
166
|
+
}
|
|
167
|
+
// Sync extension skill
|
|
168
|
+
const builtinSkill = join(builtinDir, name, "skill.md");
|
|
169
|
+
const targetSkill = join(skillsTarget, name, "SKILL.md");
|
|
170
|
+
if (existsSync(builtinSkill) && existsSync(targetSkill)) {
|
|
171
|
+
const skillSourceH = fileHash(builtinSkill);
|
|
172
|
+
const skillTargetH = fileHash(targetSkill);
|
|
173
|
+
if (skillSourceH !== skillTargetH) {
|
|
174
|
+
cpSync(builtinSkill, targetSkill);
|
|
175
|
+
console.info(` updated: ${name} skill`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (existsSync(builtinSkill) && !existsSync(targetSkill)) {
|
|
179
|
+
mkdirSync(join(skillsTarget, name), { recursive: true });
|
|
180
|
+
cpSync(builtinSkill, targetSkill);
|
|
181
|
+
console.info(` added: ${name} skill`);
|
|
182
|
+
}
|
|
183
|
+
// Print mcp_server config if extension has one
|
|
184
|
+
const manifest = loadExtension(enabledManifest);
|
|
185
|
+
if (manifest?.mcp_server) {
|
|
186
|
+
const mcpJsonPath = join(projectRoot, ".mcp.json");
|
|
187
|
+
let hasMcpEntry = false;
|
|
188
|
+
if (existsSync(mcpJsonPath)) {
|
|
189
|
+
try {
|
|
190
|
+
const mcpConfig = JSON.parse(readFileSync(mcpJsonPath, "utf-8"));
|
|
191
|
+
hasMcpEntry = !!mcpConfig?.mcpServers?.[name];
|
|
192
|
+
}
|
|
193
|
+
catch { }
|
|
194
|
+
}
|
|
195
|
+
if (!hasMcpEntry) {
|
|
196
|
+
const srv = manifest.mcp_server;
|
|
197
|
+
const config = {};
|
|
198
|
+
if (srv.type)
|
|
199
|
+
config.type = srv.type;
|
|
200
|
+
if (srv.url)
|
|
201
|
+
config.url = srv.url;
|
|
202
|
+
if (srv.command)
|
|
203
|
+
config.command = srv.command;
|
|
204
|
+
if (srv.args)
|
|
205
|
+
config.args = srv.args;
|
|
206
|
+
if (srv.headers)
|
|
207
|
+
config.headers = srv.headers;
|
|
208
|
+
if (srv.env)
|
|
209
|
+
config.env = srv.env;
|
|
210
|
+
console.info(`\n ${name}: add this to .mcp.json:\n`);
|
|
211
|
+
console.info(` "${name}": ${JSON.stringify(config, null, " ")}\n`);
|
|
212
|
+
if (srv.setup_instructions) {
|
|
213
|
+
for (const instruction of srv.setup_instructions) {
|
|
214
|
+
console.info(` ${instruction}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
console.info(`\n${extUpdated} updated, ${extCurrent} current.`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
console.info(" no extensions enabled");
|
|
224
|
+
}
|
|
140
225
|
}
|