@imenam/mcp-documentor 1.0.74 → 1.0.76
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 +271 -259
- package/dist/shared/schemas/doc.schema.d.ts +1 -4
- package/dist/shared/schemas/doc.schema.js +1 -4
- package/dist/src/cli/setup-mcp.d.ts +20 -1
- package/dist/src/cli/setup-mcp.js +65 -6
- package/dist/src/core/storage-engine.d.ts +14 -15
- package/dist/src/core/storage-engine.js +15 -51
- package/dist/src/gui-worker.js +91 -34
- package/dist/src/index.js +99 -106
- package/dist/src/tools/check-links.js +1 -1
- package/dist/src/tools/list-projects.js +7 -5
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/gui/dist/assets/{arc-BNuZ3dSL.js → arc-CsM5OJTM.js} +1 -1
- package/gui/dist/assets/{architectureDiagram-3BPJPVTR-D8g3tPQx.js → architectureDiagram-3BPJPVTR-BwIu1llT.js} +1 -1
- package/gui/dist/assets/{blockDiagram-GPEHLZMM-limhup8_.js → blockDiagram-GPEHLZMM-BVijVnPI.js} +1 -1
- package/gui/dist/assets/{c4Diagram-AAUBKEIU-Ct39JMIy.js → c4Diagram-AAUBKEIU-D-rcZUZu.js} +1 -1
- package/gui/dist/assets/channel-DKPwwuQf.js +1 -0
- package/gui/dist/assets/{chunk-2J33WTMH-BkLJTezj.js → chunk-2J33WTMH-ByfTGREe.js} +1 -1
- package/gui/dist/assets/{chunk-4BX2VUAB-CR5NbhDR.js → chunk-4BX2VUAB-B_5oCXyz.js} +1 -1
- package/gui/dist/assets/{chunk-55IACEB6-CtQYMnJS.js → chunk-55IACEB6-Bc2Kq9HD.js} +1 -1
- package/gui/dist/assets/{chunk-727SXJPM-B2q7tUn8.js → chunk-727SXJPM-CVwmKEMQ.js} +1 -1
- package/gui/dist/assets/{chunk-AQP2D5EJ-Bbcnrfrp.js → chunk-AQP2D5EJ-BkMuEFxD.js} +1 -1
- package/gui/dist/assets/{chunk-FMBD7UC4-D8gd4zRe.js → chunk-FMBD7UC4-CU7EDl9I.js} +1 -1
- package/gui/dist/assets/{chunk-ND2GUHAM-DiZKzZtG.js → chunk-ND2GUHAM-1b34Dtkn.js} +1 -1
- package/gui/dist/assets/{chunk-QZHKN3VN-CrKx-e2_.js → chunk-QZHKN3VN-DnUfMecI.js} +1 -1
- package/gui/dist/assets/classDiagram-4FO5ZUOK-CnCvVGW9.js +1 -0
- package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-CnCvVGW9.js +1 -0
- package/gui/dist/assets/{cose-bilkent-S5V4N54A-BDUCVkTl.js → cose-bilkent-S5V4N54A-D9OBrxKr.js} +1 -1
- package/gui/dist/assets/{dagre-BM42HDAG-DkoYBHXK.js → dagre-BM42HDAG-zDqwL8xs.js} +1 -1
- package/gui/dist/assets/{diagram-2AECGRRQ-BT1YJHon.js → diagram-2AECGRRQ-ejbP8WIj.js} +1 -1
- package/gui/dist/assets/{diagram-5GNKFQAL-C00r6F35.js → diagram-5GNKFQAL-Cv9WmtFO.js} +1 -1
- package/gui/dist/assets/{diagram-KO2AKTUF-B4wcN5a_.js → diagram-KO2AKTUF-BI0ybJiN.js} +1 -1
- package/gui/dist/assets/{diagram-LMA3HP47-B9FqCfel.js → diagram-LMA3HP47-DlVGttLq.js} +1 -1
- package/gui/dist/assets/{diagram-OG6HWLK6-COPCDzdG.js → diagram-OG6HWLK6-DjoAH-Fq.js} +1 -1
- package/gui/dist/assets/{erDiagram-TEJ5UH35-BGQGT2wN.js → erDiagram-TEJ5UH35-BVQHVGK4.js} +1 -1
- package/gui/dist/assets/{flowDiagram-I6XJVG4X-A7jKWUpi.js → flowDiagram-I6XJVG4X-oZP2Z-6T.js} +1 -1
- package/gui/dist/assets/{ganttDiagram-6RSMTGT7-NhFkpY-x.js → ganttDiagram-6RSMTGT7-dy4QyEOP.js} +1 -1
- package/gui/dist/assets/{gitGraphDiagram-PVQCEYII-z0AqyYG4.js → gitGraphDiagram-PVQCEYII-BxgLy7Ln.js} +1 -1
- package/gui/dist/assets/{index-Dub5OLKk.js → index-Dtv0slFQ.js} +66 -66
- package/gui/dist/assets/{infoDiagram-5YYISTIA-D69UR9u9.js → infoDiagram-5YYISTIA-DNOdinpR.js} +1 -1
- package/gui/dist/assets/{ishikawaDiagram-YF4QCWOH-DSTqIoro.js → ishikawaDiagram-YF4QCWOH-C4pQ434G.js} +1 -1
- package/gui/dist/assets/{journeyDiagram-JHISSGLW-CekXdcoE.js → journeyDiagram-JHISSGLW-CBrVYW94.js} +1 -1
- package/gui/dist/assets/{kanban-definition-UN3LZRKU-CseGvFK9.js → kanban-definition-UN3LZRKU-Df-rgiY8.js} +1 -1
- package/gui/dist/assets/{linear-BtVl_9_C.js → linear-B_6fRXVt.js} +1 -1
- package/gui/dist/assets/{mindmap-definition-RKZ34NQL-XLjQIU37.js → mindmap-definition-RKZ34NQL-CRAd_VDM.js} +1 -1
- package/gui/dist/assets/{pieDiagram-4H26LBE5-BcvUzWoW.js → pieDiagram-4H26LBE5-CJkmLrDI.js} +1 -1
- package/gui/dist/assets/{quadrantDiagram-W4KKPZXB-BzoYEmNW.js → quadrantDiagram-W4KKPZXB-D-rDEcnF.js} +1 -1
- package/gui/dist/assets/{requirementDiagram-4Y6WPE33-icKC1_Nd.js → requirementDiagram-4Y6WPE33-DE8MhSMe.js} +1 -1
- package/gui/dist/assets/{sankeyDiagram-5OEKKPKP-mi3i-2dZ.js → sankeyDiagram-5OEKKPKP-BwlxtrUs.js} +1 -1
- package/gui/dist/assets/{sequenceDiagram-3UESZ5HK-XrcDkRlM.js → sequenceDiagram-3UESZ5HK-B4LjBzWg.js} +1 -1
- package/gui/dist/assets/{stateDiagram-AJRCARHV-UXaqrCNT.js → stateDiagram-AJRCARHV-Bv72afPK.js} +1 -1
- package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-BKJDOkkR.js +1 -0
- package/gui/dist/assets/{timeline-definition-PNZ67QCA-yd6607p6.js → timeline-definition-PNZ67QCA-CBxgf8iW.js} +1 -1
- package/gui/dist/assets/{vennDiagram-CIIHVFJN-BsRqUcIp.js → vennDiagram-CIIHVFJN-DPSdK06q.js} +1 -1
- package/gui/dist/assets/{wardley-L42UT6IY-BmdA7yk0.js → wardley-L42UT6IY-JIAzuoPm.js} +1 -1
- package/gui/dist/assets/{wardleyDiagram-YWT4CUSO-CRdmckD8.js → wardleyDiagram-YWT4CUSO-YDfaF1wT.js} +1 -1
- package/gui/dist/assets/{xychartDiagram-2RQKCTM6-DWpNIQY-.js → xychartDiagram-2RQKCTM6-DHlPryZX.js} +1 -1
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/src/tools/set-project.d.ts +0 -14
- package/dist/src/tools/set-project.js +0 -18
- package/gui/dist/assets/channel-uoEIgtym.js +0 -1
- package/gui/dist/assets/classDiagram-4FO5ZUOK-DmhYb54l.js +0 -1
- package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-DmhYb54l.js +0 -1
- package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-Bhdu4lv4.js +0 -1
package/dist/src/index.js
CHANGED
|
@@ -20,7 +20,6 @@ import { searchDocs } from "./tools/search-docs.js";
|
|
|
20
20
|
import { checkFreshness, computeFreshness } from "./tools/check-freshness.js";
|
|
21
21
|
import { findAndHashSection } from "./core/section-tracker.js";
|
|
22
22
|
import { toAbsolutePath } from "./core/path-resolver.js";
|
|
23
|
-
import { setProject } from "./tools/set-project.js";
|
|
24
23
|
import { listProjects } from "./tools/list-projects.js";
|
|
25
24
|
import { refreshFileSnapshot } from "./tools/refresh-file-snapshot.js";
|
|
26
25
|
import { getDocMetadata } from "./tools/get-doc-metadata.js";
|
|
@@ -50,8 +49,14 @@ const __dirname = path.dirname(__filename);
|
|
|
50
49
|
// Les flags CLI sont traités avant toute initialisation (storage, sqlite, logs) :
|
|
51
50
|
// ils s'exécutent dans le répertoire de l'utilisateur, pas dans un serveur MCP.
|
|
52
51
|
if (process.argv.slice(2).includes("--claude-setup-mcp")) {
|
|
53
|
-
const
|
|
54
|
-
|
|
52
|
+
const argv = process.argv.slice(2);
|
|
53
|
+
const { runSetupMcp, parseGuiExposure } = await import("./cli/setup-mcp.js");
|
|
54
|
+
const parsed = parseGuiExposure(argv);
|
|
55
|
+
if ("error" in parsed) {
|
|
56
|
+
console.error(`Erreur : ${parsed.error}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
process.exit(runSetupMcp({ cwd: process.cwd(), force: argv.includes("--force"), exposure: parsed.exposure }));
|
|
55
60
|
}
|
|
56
61
|
function findProjectRoot(startDir) {
|
|
57
62
|
let current = startDir;
|
|
@@ -73,6 +78,7 @@ function getConfig() {
|
|
|
73
78
|
}
|
|
74
79
|
return {
|
|
75
80
|
proxyUrl: process.env.PROXY_URL,
|
|
81
|
+
appPort: process.env.APP_PORT,
|
|
76
82
|
version: APP_VERSION,
|
|
77
83
|
};
|
|
78
84
|
}
|
|
@@ -80,7 +86,9 @@ getConfig();
|
|
|
80
86
|
const storageEngine = new StorageEngine(rootDir);
|
|
81
87
|
const embeddingStore = new EmbeddingStore();
|
|
82
88
|
const embeddingEngine = new EmbeddingEngine(embeddingStore);
|
|
83
|
-
|
|
89
|
+
for (const project of storageEngine.getConfig().projects) {
|
|
90
|
+
storageEngine.ensureProject(project);
|
|
91
|
+
}
|
|
84
92
|
const openaiModel = process.env.MCP_DOCUMENTOR_OPENAI_MODEL || "text-embedding-3-small";
|
|
85
93
|
embeddingStore.init(storageEngine.getDataDir(), openaiModel);
|
|
86
94
|
const historyStore = new HistoryStore();
|
|
@@ -123,8 +131,8 @@ function handleIPCMessage(msg) {
|
|
|
123
131
|
else if (msg.type === "GET_CONFIG") {
|
|
124
132
|
handleGetConfig(msg);
|
|
125
133
|
}
|
|
126
|
-
else if (msg.type === "
|
|
127
|
-
|
|
134
|
+
else if (msg.type === "CREATE_PROJECT") {
|
|
135
|
+
handleCreateProject(msg);
|
|
128
136
|
}
|
|
129
137
|
else if (msg.type === "LIST_PROJECTS") {
|
|
130
138
|
handleListProjects(msg);
|
|
@@ -188,25 +196,45 @@ function requireProjectFromIPC(msg) {
|
|
|
188
196
|
throw new Error("project is required for this operation");
|
|
189
197
|
return project;
|
|
190
198
|
}
|
|
199
|
+
/** Loads one project's summaries and flags each entry as stale/broken. */
|
|
200
|
+
async function listDocsWithFreshness(project) {
|
|
201
|
+
const docs = await storageEngine.listDocs(project);
|
|
202
|
+
for (const doc of docs) {
|
|
203
|
+
const full = await storageEngine.getDoc(doc.id, project);
|
|
204
|
+
if (full && full.tracked_files.length > 0) {
|
|
205
|
+
const report = computeFreshness(full.tracked_files, project);
|
|
206
|
+
doc.isStale = report.status === "stale" || report.status === "broken";
|
|
207
|
+
doc.isBroken = report.status === "broken";
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return docs;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Tells every connected GUI that one project's docs changed. Clients showing
|
|
214
|
+
* that project refetch; the others ignore it. Broadcasting a full INITIAL_STATE
|
|
215
|
+
* here used to drag every client onto the writer's project.
|
|
216
|
+
*/
|
|
217
|
+
function broadcastDocsChanged(project) {
|
|
218
|
+
broadcastToGUI({
|
|
219
|
+
type: "DOCS_CHANGED",
|
|
220
|
+
data: { project },
|
|
221
|
+
timestamp: new Date().toISOString(),
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Server-side state only: the project list and server capabilities. Which
|
|
226
|
+
* project a client displays is that client's own business (URL + local
|
|
227
|
+
* preference), so no docs and no active project are pushed here.
|
|
228
|
+
*/
|
|
191
229
|
async function handleGetInitialState(msg) {
|
|
192
230
|
try {
|
|
193
231
|
const config = storageEngine.getConfig();
|
|
194
|
-
const docs = await storageEngine.listDocs();
|
|
195
|
-
for (const doc of docs) {
|
|
196
|
-
const full = await storageEngine.getDoc(doc.id); // doc.id is now the full path
|
|
197
|
-
if (full && full.tracked_files.length > 0) {
|
|
198
|
-
const report = computeFreshness(full.tracked_files, config.currentProject);
|
|
199
|
-
doc.isStale = report.status === "stale" || report.status === "broken";
|
|
200
|
-
doc.isBroken = report.status === "broken";
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
232
|
const bundles = storageEngine.getBundles();
|
|
204
233
|
broadcastToGUI({
|
|
205
234
|
type: "INITIAL_STATE",
|
|
206
235
|
correlationId: msg.correlationId,
|
|
207
236
|
data: {
|
|
208
237
|
config,
|
|
209
|
-
docs,
|
|
210
238
|
projects: config.projects,
|
|
211
239
|
bundles,
|
|
212
240
|
readOnly: isReadOnly(),
|
|
@@ -228,39 +256,31 @@ async function handleGetConfig(msg) {
|
|
|
228
256
|
timestamp: new Date().toISOString(),
|
|
229
257
|
});
|
|
230
258
|
}
|
|
231
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Creates an empty project. It does NOT change any server-side "active"
|
|
261
|
+
* project — there is none: the selector in the GUI is a per-client view.
|
|
262
|
+
*/
|
|
263
|
+
async function handleCreateProject(msg) {
|
|
232
264
|
try {
|
|
233
265
|
const project = path.basename(msg.data.project);
|
|
234
266
|
if (!project || project === "..")
|
|
235
267
|
throw new Error("Invalid project name");
|
|
236
268
|
storageEngine.ensureProject(project);
|
|
237
|
-
const config = storageEngine.getConfig();
|
|
238
|
-
config.currentProject = project;
|
|
239
|
-
storageEngine.saveConfig(config);
|
|
240
|
-
const docs = await storageEngine.listDocs();
|
|
241
|
-
for (const doc of docs) {
|
|
242
|
-
const full = await storageEngine.getDoc(doc.id);
|
|
243
|
-
if (full && full.tracked_files.length > 0) {
|
|
244
|
-
const report = computeFreshness(full.tracked_files, project);
|
|
245
|
-
doc.isStale = report.status === "stale" || report.status === "broken";
|
|
246
|
-
doc.isBroken = report.status === "broken";
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
269
|
broadcastToGUI({
|
|
250
|
-
type: "
|
|
270
|
+
type: "CREATE_PROJECT_RESPONSE",
|
|
251
271
|
correlationId: msg.correlationId,
|
|
252
|
-
data: { success: true,
|
|
272
|
+
data: { success: true, project, projects: storageEngine.getConfig().projects },
|
|
253
273
|
timestamp: new Date().toISOString(),
|
|
254
274
|
});
|
|
255
275
|
broadcastToGUI({
|
|
256
|
-
type: "
|
|
257
|
-
data: {
|
|
276
|
+
type: "PROJECTS_CHANGED",
|
|
277
|
+
data: { projects: storageEngine.getConfig().projects },
|
|
258
278
|
timestamp: new Date().toISOString(),
|
|
259
279
|
});
|
|
260
280
|
}
|
|
261
281
|
catch (err) {
|
|
262
282
|
broadcastToGUI({
|
|
263
|
-
type: "
|
|
283
|
+
type: "CREATE_PROJECT_RESPONSE",
|
|
264
284
|
correlationId: msg.correlationId,
|
|
265
285
|
error: err.message,
|
|
266
286
|
timestamp: new Date().toISOString(),
|
|
@@ -278,16 +298,7 @@ async function handleListProjects(msg) {
|
|
|
278
298
|
}
|
|
279
299
|
async function handleListDocs(msg) {
|
|
280
300
|
try {
|
|
281
|
-
const
|
|
282
|
-
const docs = await storageEngine.listDocs();
|
|
283
|
-
for (const doc of docs) {
|
|
284
|
-
const full = await storageEngine.getDoc(doc.id);
|
|
285
|
-
if (full && full.tracked_files.length > 0) {
|
|
286
|
-
const report = computeFreshness(full.tracked_files, currentProject);
|
|
287
|
-
doc.isStale = report.status === "stale" || report.status === "broken";
|
|
288
|
-
doc.isBroken = report.status === "broken";
|
|
289
|
-
}
|
|
290
|
-
}
|
|
301
|
+
const docs = await listDocsWithFreshness(requireProjectFromIPC(msg));
|
|
291
302
|
broadcastToGUI({
|
|
292
303
|
type: "LIST_DOCS_RESPONSE",
|
|
293
304
|
correlationId: msg.correlationId,
|
|
@@ -327,8 +338,7 @@ async function handleGetDoc(msg) {
|
|
|
327
338
|
}
|
|
328
339
|
async function handleListFoldersIPC(msg) {
|
|
329
340
|
try {
|
|
330
|
-
const
|
|
331
|
-
const docs = await storageEngine.listDocs(project);
|
|
341
|
+
const docs = await storageEngine.listDocs(requireProjectFromIPC(msg));
|
|
332
342
|
const folders = new Set();
|
|
333
343
|
for (const doc of docs) {
|
|
334
344
|
if (doc.folder) {
|
|
@@ -394,21 +404,7 @@ async function handleCreateDocIPC(msg) {
|
|
|
394
404
|
data: { success: true, id },
|
|
395
405
|
timestamp: new Date().toISOString(),
|
|
396
406
|
});
|
|
397
|
-
|
|
398
|
-
const docs = await storageEngine.listDocs();
|
|
399
|
-
for (const doc of docs) {
|
|
400
|
-
const full = await storageEngine.getDoc(doc.id);
|
|
401
|
-
if (full && full.tracked_files.length > 0) {
|
|
402
|
-
const report = computeFreshness(full.tracked_files, config.currentProject);
|
|
403
|
-
doc.isStale = report.status === "stale" || report.status === "broken";
|
|
404
|
-
doc.isBroken = report.status === "broken";
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
broadcastToGUI({
|
|
408
|
-
type: "INITIAL_STATE",
|
|
409
|
-
data: { config, docs, projects: config.projects },
|
|
410
|
-
timestamp: new Date().toISOString(),
|
|
411
|
-
});
|
|
407
|
+
broadcastDocsChanged(project);
|
|
412
408
|
}
|
|
413
409
|
catch (err) {
|
|
414
410
|
broadcastToGUI({
|
|
@@ -430,9 +426,10 @@ async function handleUpdateDocIPC(msg) {
|
|
|
430
426
|
return;
|
|
431
427
|
}
|
|
432
428
|
try {
|
|
429
|
+
const project = requireProjectFromIPC(msg);
|
|
433
430
|
const result = await updateDoc(storageEngine, embeddingEngine, {
|
|
434
431
|
path: msg.data.id,
|
|
435
|
-
project
|
|
432
|
+
project,
|
|
436
433
|
content: msg.data.content,
|
|
437
434
|
...(msg.data.title !== undefined && { title: msg.data.title }),
|
|
438
435
|
});
|
|
@@ -453,6 +450,7 @@ async function handleUpdateDocIPC(msg) {
|
|
|
453
450
|
data: { success: true, message },
|
|
454
451
|
timestamp: new Date().toISOString(),
|
|
455
452
|
});
|
|
453
|
+
broadcastDocsChanged(project);
|
|
456
454
|
}
|
|
457
455
|
catch (err) {
|
|
458
456
|
broadcastToGUI({
|
|
@@ -493,21 +491,7 @@ async function handleDeleteDocIPC(msg) {
|
|
|
493
491
|
data: { success: true, message },
|
|
494
492
|
timestamp: new Date().toISOString(),
|
|
495
493
|
});
|
|
496
|
-
|
|
497
|
-
const docs = await storageEngine.listDocs();
|
|
498
|
-
for (const doc of docs) {
|
|
499
|
-
const full = await storageEngine.getDoc(doc.id);
|
|
500
|
-
if (full && full.tracked_files.length > 0) {
|
|
501
|
-
const report = computeFreshness(full.tracked_files, config.currentProject);
|
|
502
|
-
doc.isStale = report.status === "stale" || report.status === "broken";
|
|
503
|
-
doc.isBroken = report.status === "broken";
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
broadcastToGUI({
|
|
507
|
-
type: "INITIAL_STATE",
|
|
508
|
-
data: { config, docs, projects: config.projects },
|
|
509
|
-
timestamp: new Date().toISOString(),
|
|
510
|
-
});
|
|
494
|
+
broadcastDocsChanged(project);
|
|
511
495
|
}
|
|
512
496
|
catch (err) {
|
|
513
497
|
broadcastToGUI({
|
|
@@ -603,9 +587,9 @@ async function handleSearchDocs(msg) {
|
|
|
603
587
|
});
|
|
604
588
|
}
|
|
605
589
|
else {
|
|
606
|
-
const
|
|
607
|
-
results = await embeddingEngine.search(query,
|
|
608
|
-
const doc = await storageEngine.getDoc(docPath);
|
|
590
|
+
const project = requireProjectFromIPC(msg);
|
|
591
|
+
results = await embeddingEngine.search(query, project, top_k || 5, async (docPath) => {
|
|
592
|
+
const doc = await storageEngine.getDoc(docPath, project);
|
|
609
593
|
if (!doc)
|
|
610
594
|
return null;
|
|
611
595
|
return { title: doc.title, content: doc.content };
|
|
@@ -832,9 +816,13 @@ function startGuiWorker() {
|
|
|
832
816
|
});
|
|
833
817
|
return child;
|
|
834
818
|
}
|
|
819
|
+
/** La GUI a besoin soit d'un proxy, soit d'un port local (mode standalone). */
|
|
820
|
+
function guiIsConfigured() {
|
|
821
|
+
return !!(process.env.PROXY_URL?.trim() || process.env.APP_PORT?.trim());
|
|
822
|
+
}
|
|
835
823
|
function launchGUI() {
|
|
836
|
-
if (!
|
|
837
|
-
logger.info('[MASTER] PROXY_URL
|
|
824
|
+
if (!guiIsConfigured()) {
|
|
825
|
+
logger.info('[MASTER] Ni PROXY_URL ni APP_PORT défini — GUI désactivée.');
|
|
838
826
|
guiStatus = "disabled";
|
|
839
827
|
return;
|
|
840
828
|
}
|
|
@@ -842,10 +830,10 @@ function launchGUI() {
|
|
|
842
830
|
startGuiWorker();
|
|
843
831
|
}
|
|
844
832
|
async function reconnectGui(args) {
|
|
845
|
-
getConfig(); // relit le .env au cas où PROXY_URL aurait été ajouté après le démarrage
|
|
846
|
-
if (!
|
|
833
|
+
getConfig(); // relit le .env au cas où PROXY_URL/APP_PORT aurait été ajouté après le démarrage
|
|
834
|
+
if (!guiIsConfigured()) {
|
|
847
835
|
return {
|
|
848
|
-
content: [{ type: "text", text: "Error: PROXY_URL is
|
|
836
|
+
content: [{ type: "text", text: "Error: neither PROXY_URL nor APP_PORT is set — the GUI is disabled. Add PROXY_URL (to expose the GUI through the proxy) or APP_PORT (to serve it directly on localhost) to the .env file, then call reconnect_gui again." }],
|
|
849
837
|
isError: true,
|
|
850
838
|
};
|
|
851
839
|
}
|
|
@@ -854,9 +842,9 @@ async function reconnectGui(args) {
|
|
|
854
842
|
const force = args?.force === true;
|
|
855
843
|
if (alive && !force) {
|
|
856
844
|
if (guiStatus === "starting") {
|
|
857
|
-
return { content: [{ type: "text", text: "GUI worker is already starting
|
|
845
|
+
return { content: [{ type: "text", text: "GUI worker is already starting. Wait a few seconds, then call reconnect_gui again if needed." }] };
|
|
858
846
|
}
|
|
859
|
-
return { content: [{ type: "text", text: `GUI is already
|
|
847
|
+
return { content: [{ type: "text", text: `GUI is already running${guiUrl ? ` at ${guiUrl}` : ""}. Nothing to do (use force=true to restart it anyway).` }] };
|
|
860
848
|
}
|
|
861
849
|
logger.info(`[MASTER] reconnect_gui: ${alive ? "restarting (force)" : "relaunching"} GUI worker...`);
|
|
862
850
|
const result = await new Promise((resolve) => {
|
|
@@ -867,20 +855,24 @@ async function reconnectGui(args) {
|
|
|
867
855
|
guiStartWaiter = (r) => { cleanup(); resolve(r); };
|
|
868
856
|
newChild.on("exit", onExit);
|
|
869
857
|
});
|
|
858
|
+
const proxyUrl = process.env.PROXY_URL?.trim();
|
|
870
859
|
if (result.outcome === "ready") {
|
|
871
|
-
return { content: [{ type: "text", text: `GUI reconnected
|
|
860
|
+
return { content: [{ type: "text", text: `GUI reconnected. URL: ${result.url}` }] };
|
|
872
861
|
}
|
|
873
862
|
if (result.outcome === "already_running") {
|
|
874
|
-
return { content: [{ type: "text", text: `GUI is already
|
|
863
|
+
return { content: [{ type: "text", text: `GUI is already served by another MCP instance. URL: ${result.url ?? "unknown"}` }] };
|
|
875
864
|
}
|
|
876
865
|
if (result.outcome === "exited") {
|
|
866
|
+
const hint = proxyUrl
|
|
867
|
+
? `The proxy server is probably still unreachable at ${proxyUrl}. Start the proxy server, then call reconnect_gui again.`
|
|
868
|
+
: `Port ${process.env.APP_PORT} is probably already taken by another process. Free it or set another APP_PORT, then call reconnect_gui again.`;
|
|
877
869
|
return {
|
|
878
|
-
content: [{ type: "text", text: `GUI worker exited before
|
|
870
|
+
content: [{ type: "text", text: `GUI worker exited before it was ready (code=${result.code}). ${hint}` }],
|
|
879
871
|
isError: true,
|
|
880
872
|
};
|
|
881
873
|
}
|
|
882
874
|
return {
|
|
883
|
-
content: [{ type: "text", text: `GUI worker started but did not confirm
|
|
875
|
+
content: [{ type: "text", text: `GUI worker started but did not confirm it was ready within 15s. Check the logs (${resolveLogDir(rootDir)}), then retry.` }],
|
|
884
876
|
isError: true,
|
|
885
877
|
};
|
|
886
878
|
}
|
|
@@ -1059,20 +1051,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
1059
1051
|
required: [],
|
|
1060
1052
|
},
|
|
1061
1053
|
},
|
|
1062
|
-
{
|
|
1063
|
-
name: "set_project",
|
|
1064
|
-
description: "Switch the active project and update it as the default for all subsequent MCP tool operations. If the project name does not exist yet, it is created automatically. Also controls what the GUI displays.",
|
|
1065
|
-
inputSchema: {
|
|
1066
|
-
type: "object",
|
|
1067
|
-
properties: {
|
|
1068
|
-
project: { type: "string", description: "Project name to switch to (created if it does not exist)" },
|
|
1069
|
-
},
|
|
1070
|
-
required: ["project"],
|
|
1071
|
-
},
|
|
1072
|
-
},
|
|
1073
1054
|
{
|
|
1074
1055
|
name: "list_projects",
|
|
1075
|
-
description: "List all available documentation projects
|
|
1056
|
+
description: "List all available documentation projects. There is no active project: every tool call names the project it targets.",
|
|
1076
1057
|
inputSchema: {
|
|
1077
1058
|
type: "object",
|
|
1078
1059
|
properties: {},
|
|
@@ -1154,9 +1135,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
1154
1135
|
inputSchema: {
|
|
1155
1136
|
type: "object",
|
|
1156
1137
|
properties: {
|
|
1157
|
-
project: { type: "string", description: "Project
|
|
1138
|
+
project: { type: "string", description: "Project whose entries are checked. Required — never defaulted to a current project." },
|
|
1158
1139
|
},
|
|
1159
|
-
required: [],
|
|
1140
|
+
required: ["project"],
|
|
1160
1141
|
},
|
|
1161
1142
|
},
|
|
1162
1143
|
{
|
|
@@ -1410,7 +1391,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1410
1391
|
case "check_freshness":
|
|
1411
1392
|
return await checkFreshness(storageEngine, args);
|
|
1412
1393
|
case "set_project":
|
|
1413
|
-
|
|
1394
|
+
// Removed: there is no server-side active project any more. Kept as an
|
|
1395
|
+
// explicit answer for agents that still remember the old tool.
|
|
1396
|
+
return {
|
|
1397
|
+
isError: true,
|
|
1398
|
+
content: [
|
|
1399
|
+
{
|
|
1400
|
+
type: "text",
|
|
1401
|
+
text: "set_project no longer exists: there is no active project. " +
|
|
1402
|
+
"Pass the project explicitly to every tool call (use list_projects to see them). " +
|
|
1403
|
+
"A project is created on demand by create_doc.",
|
|
1404
|
+
},
|
|
1405
|
+
],
|
|
1406
|
+
};
|
|
1414
1407
|
case "list_projects":
|
|
1415
1408
|
return await listProjects(storageEngine);
|
|
1416
1409
|
case "refresh_file_snapshot":
|
|
@@ -38,7 +38,7 @@ export async function checkLinks(storageEngine, args) {
|
|
|
38
38
|
try {
|
|
39
39
|
const validated = CheckLinksArgsSchema.parse(args);
|
|
40
40
|
const config = storageEngine.getConfig();
|
|
41
|
-
const project = validated.project
|
|
41
|
+
const project = validated.project;
|
|
42
42
|
const knownProjects = new Set(config.projects);
|
|
43
43
|
const docs = await storageEngine.listDocs(project);
|
|
44
44
|
const validIds = new Set(docs.map((d) => d.id));
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
export async function listProjects(storageEngine) {
|
|
2
2
|
try {
|
|
3
3
|
const config = storageEngine.getConfig();
|
|
4
|
-
const lines = config.projects.map((p) => {
|
|
5
|
-
const marker = p === config.currentProject ? " (active)" : "";
|
|
6
|
-
return `- ${p}${marker}`;
|
|
7
|
-
});
|
|
4
|
+
const lines = config.projects.map((p) => `- ${p}`);
|
|
8
5
|
return {
|
|
9
|
-
content: [
|
|
6
|
+
content: [
|
|
7
|
+
{
|
|
8
|
+
type: "text",
|
|
9
|
+
text: `Projects:\n\n${lines.join("\n")}\n\nThere is no active project: every tool call names the project it targets explicitly.`,
|
|
10
|
+
},
|
|
11
|
+
],
|
|
10
12
|
};
|
|
11
13
|
}
|
|
12
14
|
catch (err) {
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const APP_VERSION = "1.0.
|
|
1
|
+
export declare const APP_VERSION = "1.0.76";
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated version file - do not edit manually
|
|
2
|
-
export const APP_VERSION = '1.0.
|
|
2
|
+
export const APP_VERSION = '1.0.76';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./index-
|
|
1
|
+
import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./index-Dtv0slFQ.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=A.apply(this,arguments)-an,F=un(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|