@imenam/mcp-documentor 1.0.91 → 1.0.93

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.
Files changed (83) hide show
  1. package/README.md +343 -327
  2. package/dist/src/core/git-sync.js +1 -0
  3. package/dist/src/core/publication-store.d.ts +76 -0
  4. package/dist/src/core/publication-store.js +180 -0
  5. package/dist/src/gui-worker.js +183 -67
  6. package/dist/src/index.js +118 -4
  7. package/gui/dist/assets/DocContent-BxncLHIS.css +1 -0
  8. package/gui/dist/assets/DocContent-qNz5QMPa.js +346 -0
  9. package/gui/dist/assets/arc-DvP0UOkD.js +1 -0
  10. package/gui/dist/assets/architectureDiagram-3BPJPVTR-3wEHUA1o.js +36 -0
  11. package/gui/dist/assets/{blockDiagram-GPEHLZMM-G4A-rV4c.js → blockDiagram-GPEHLZMM-C01nZdXH.js} +1 -1
  12. package/gui/dist/assets/{c4Diagram-AAUBKEIU-Dq3aMw8v.js → c4Diagram-AAUBKEIU-C995ER45.js} +1 -1
  13. package/gui/dist/assets/channel-Cjefy81D.js +1 -0
  14. package/gui/dist/assets/chunk-2J33WTMH-B7Z-cZqf.js +1 -0
  15. package/gui/dist/assets/chunk-4BX2VUAB-BRtaRRAZ.js +1 -0
  16. package/gui/dist/assets/chunk-55IACEB6-CZbPaYTs.js +1 -0
  17. package/gui/dist/assets/{chunk-727SXJPM-Dv3Ay2KV.js → chunk-727SXJPM-BMKPsW_V.js} +1 -1
  18. package/gui/dist/assets/{chunk-AQP2D5EJ-BycHHbwh.js → chunk-AQP2D5EJ-BQJRaqJz.js} +1 -1
  19. package/gui/dist/assets/{chunk-FMBD7UC4-DBoCiqpY.js → chunk-FMBD7UC4-BiKjOUxU.js} +1 -1
  20. package/gui/dist/assets/chunk-ND2GUHAM-BQYUzZi5.js +1 -0
  21. package/gui/dist/assets/chunk-QZHKN3VN-C0mI_9k0.js +1 -0
  22. package/gui/dist/assets/classDiagram-4FO5ZUOK-U-TA2l-f.js +1 -0
  23. package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-U-TA2l-f.js +1 -0
  24. package/gui/dist/assets/cose-bilkent-S5V4N54A-9QkakK6h.js +1 -0
  25. package/gui/dist/assets/dagre-BM42HDAG-p_TitJwo.js +4 -0
  26. package/gui/dist/assets/diagram-2AECGRRQ-T3ul_-C1.js +43 -0
  27. package/gui/dist/assets/diagram-5GNKFQAL-Cv4-mYjj.js +10 -0
  28. package/gui/dist/assets/{diagram-KO2AKTUF-CZAde8Sg.js → diagram-KO2AKTUF-GEuY7REm.js} +1 -1
  29. package/gui/dist/assets/diagram-LMA3HP47-BlZVA1ZL.js +24 -0
  30. package/gui/dist/assets/diagram-OG6HWLK6-DZ9muekA.js +24 -0
  31. package/gui/dist/assets/{erDiagram-TEJ5UH35-DPUEmQfe.js → erDiagram-TEJ5UH35-BQ_TWeSA.js} +1 -1
  32. package/gui/dist/assets/{flowDiagram-I6XJVG4X-p2HfkBjW.js → flowDiagram-I6XJVG4X-BVxlCJhG.js} +1 -1
  33. package/gui/dist/assets/ganttDiagram-6RSMTGT7-DlHxknKg.js +292 -0
  34. package/gui/dist/assets/gitGraphDiagram-PVQCEYII-DYHNhcQ1.js +106 -0
  35. package/gui/dist/assets/infoDiagram-5YYISTIA-usWWgsgX.js +2 -0
  36. package/gui/dist/assets/{ishikawaDiagram-YF4QCWOH-DZ61Cc8a.js → ishikawaDiagram-YF4QCWOH-GXA4mXdI.js} +1 -1
  37. package/gui/dist/assets/{journeyDiagram-JHISSGLW-qYtEmFuB.js → journeyDiagram-JHISSGLW-DuiQ_voI.js} +1 -1
  38. package/gui/dist/assets/{kanban-definition-UN3LZRKU-Bs-W313s.js → kanban-definition-UN3LZRKU-Cf5Zx4Ai.js} +1 -1
  39. package/gui/dist/assets/linear-Dxg5B9lZ.js +1 -0
  40. package/gui/dist/assets/main-BoIDzkiC.js +10 -0
  41. package/gui/dist/assets/main-DDy8gF40.css +1 -0
  42. package/gui/dist/assets/{mindmap-definition-RKZ34NQL-CvBqAH4c.js → mindmap-definition-RKZ34NQL-BI-GTubt.js} +1 -1
  43. package/gui/dist/assets/{pieDiagram-4H26LBE5-BD2UcQce.js → pieDiagram-4H26LBE5-jm6JjM7-.js} +1 -1
  44. package/gui/dist/assets/public-5AzxUEZY.css +1 -0
  45. package/gui/dist/assets/public-BbfNIL4J.js +1 -0
  46. package/gui/dist/assets/{quadrantDiagram-W4KKPZXB-DEuynlP9.js → quadrantDiagram-W4KKPZXB-D_FMBvP7.js} +1 -1
  47. package/gui/dist/assets/{requirementDiagram-4Y6WPE33-DPxfzOF3.js → requirementDiagram-4Y6WPE33-DrAnq7B5.js} +1 -1
  48. package/gui/dist/assets/{sankeyDiagram-5OEKKPKP-C70_cePR.js → sankeyDiagram-5OEKKPKP-BBxMYinl.js} +1 -1
  49. package/gui/dist/assets/{sequenceDiagram-3UESZ5HK-FDb_1B1W.js → sequenceDiagram-3UESZ5HK-CzlReNxZ.js} +1 -1
  50. package/gui/dist/assets/stateDiagram-AJRCARHV-CAj_FaGh.js +1 -0
  51. package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-DL8IxfA-.js +1 -0
  52. package/gui/dist/assets/{timeline-definition-PNZ67QCA-DNUx0JIp.js → timeline-definition-PNZ67QCA-CHzi4ypa.js} +1 -1
  53. package/gui/dist/assets/{vennDiagram-CIIHVFJN-DEAfzbjb.js → vennDiagram-CIIHVFJN-DT2hW75o.js} +1 -1
  54. package/gui/dist/assets/{wardley-L42UT6IY-_REPWPb-.js → wardley-L42UT6IY-BBPqyjj6.js} +1 -1
  55. package/gui/dist/assets/{wardleyDiagram-YWT4CUSO-CZFLXFE3.js → wardleyDiagram-YWT4CUSO-CoB6ihhL.js} +1 -1
  56. package/gui/dist/assets/{xychartDiagram-2RQKCTM6-P2Nhif6M.js → xychartDiagram-2RQKCTM6-FgTwWkea.js} +1 -1
  57. package/gui/dist/index.html +4 -2
  58. package/gui/dist/public.html +17 -0
  59. package/package.json +1 -1
  60. package/gui/dist/assets/arc-VljQAUvA.js +0 -1
  61. package/gui/dist/assets/architectureDiagram-3BPJPVTR-lbkjtvmN.js +0 -36
  62. package/gui/dist/assets/channel-DFvG2cZZ.js +0 -1
  63. package/gui/dist/assets/chunk-2J33WTMH-VSzyIJHo.js +0 -1
  64. package/gui/dist/assets/chunk-4BX2VUAB-DER41q8w.js +0 -1
  65. package/gui/dist/assets/chunk-55IACEB6-BlOGGRk4.js +0 -1
  66. package/gui/dist/assets/chunk-ND2GUHAM-DGKypjhb.js +0 -1
  67. package/gui/dist/assets/chunk-QZHKN3VN-B8Gn_mBo.js +0 -1
  68. package/gui/dist/assets/classDiagram-4FO5ZUOK-B8xEoAMI.js +0 -1
  69. package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-B8xEoAMI.js +0 -1
  70. package/gui/dist/assets/cose-bilkent-S5V4N54A-DyamTuYj.js +0 -1
  71. package/gui/dist/assets/dagre-BM42HDAG-BKC5D2WN.js +0 -4
  72. package/gui/dist/assets/diagram-2AECGRRQ-BV2lBpwH.js +0 -43
  73. package/gui/dist/assets/diagram-5GNKFQAL-DGwbAj4W.js +0 -10
  74. package/gui/dist/assets/diagram-LMA3HP47-fQfo0z7i.js +0 -24
  75. package/gui/dist/assets/diagram-OG6HWLK6-BlD3VAFM.js +0 -24
  76. package/gui/dist/assets/ganttDiagram-6RSMTGT7-CWfFoy4g.js +0 -292
  77. package/gui/dist/assets/gitGraphDiagram-PVQCEYII-DkTKzmes.js +0 -106
  78. package/gui/dist/assets/index-BJ4WCWig.css +0 -1
  79. package/gui/dist/assets/index-C8LVeAsA.js +0 -358
  80. package/gui/dist/assets/infoDiagram-5YYISTIA-CXHTqZoU.js +0 -2
  81. package/gui/dist/assets/linear-CU6J91M5.js +0 -1
  82. package/gui/dist/assets/stateDiagram-AJRCARHV-BH1bq2it.js +0 -1
  83. package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-BfpDu1Qi.js +0 -1
package/dist/src/index.js CHANGED
@@ -54,7 +54,8 @@ import { getImage } from "./tools/get-image.js";
54
54
  import { SyncEngine } from "./core/git-sync.js";
55
55
  import { syncStatus, pullDocs, pushDocs, syncDocs, resolveSyncConflict } from "./tools/sync.js";
56
56
  import { listConflicts, getConflictHunks, resolveConflictHunks } from "./tools/conflicts.js";
57
- import { textSourceDescriptions, } from "../shared/schemas/doc.schema.js";
57
+ import { hashDocContent, PublicationStore } from "./core/publication-store.js";
58
+ import { MoveDocArgsSchema, textSourceDescriptions, } from "../shared/schemas/doc.schema.js";
58
59
  import { isReadOnly, WRITE_TOOLS } from "../shared/read-only.js";
59
60
  const __filename = fileURLToPath(import.meta.url);
60
61
  const __dirname = path.dirname(__filename);
@@ -109,6 +110,7 @@ historyStore.init(storageEngine.getDataDir());
109
110
  storageEngine.setHistoryStore(historyStore);
110
111
  const syncEngine = new SyncEngine(storageEngine);
111
112
  const localState = new LocalState(storageEngine.getDataDir());
113
+ const publicationStore = new PublicationStore(storageEngine.getDataDir());
112
114
  setBlobStoreDir(path.join(storageEngine.getDataDir(), "blob-cache"));
113
115
  setCodeRootProvider((project) => localState.getCodeRoot(project));
114
116
  setCodeSourceProvider({
@@ -120,7 +122,6 @@ let guiLauncher;
120
122
  let guiStatus = "disabled";
121
123
  let guiUrl = null;
122
124
  let guiStartWaiter = null;
123
- const sseControllers = new Set();
124
125
  function broadcastToGUI(message) {
125
126
  const child = guiLauncher.getProcess();
126
127
  if (child?.connected) {
@@ -248,6 +249,18 @@ function dispatchIPCMessage(msg) {
248
249
  return { success: true };
249
250
  });
250
251
  }
252
+ else if (msg.type === "LIST_PUBLICATIONS") {
253
+ replyToGUI(msg, "LIST_PUBLICATIONS_RESPONSE", () => listPublications(msg.data?.project || undefined));
254
+ }
255
+ else if (msg.type === "PUBLISH_DOC") {
256
+ replyToGUI(msg, "PUBLISH_DOC_RESPONSE", () => publishDoc(msg.data ?? {}));
257
+ }
258
+ else if (msg.type === "UPDATE_PUBLICATION") {
259
+ replyToGUI(msg, "UPDATE_PUBLICATION_RESPONSE", () => updatePublication(msg.data ?? {}));
260
+ }
261
+ else if (msg.type === "UNPUBLISH_DOC") {
262
+ replyToGUI(msg, "UNPUBLISH_DOC_RESPONSE", () => unpublishDoc(msg.data ?? {}));
263
+ }
251
264
  else {
252
265
  logger.debug(`Unhandled message from GUI: ${msg.type}`);
253
266
  }
@@ -359,6 +372,14 @@ async function handleGetInitialState(msg) {
359
372
  }
360
373
  catch (err) {
361
374
  logger.error(`Failed to get initial state: ${err.message}`);
375
+ if (msg.correlationId) {
376
+ broadcastToGUI({
377
+ type: "INITIAL_STATE",
378
+ correlationId: msg.correlationId,
379
+ error: err.message,
380
+ timestamp: new Date().toISOString(),
381
+ });
382
+ }
362
383
  }
363
384
  }
364
385
  async function handleGetConfig(msg) {
@@ -909,6 +930,95 @@ async function handleGetDocVersionIPC(msg) {
909
930
  });
910
931
  }
911
932
  }
933
+ /** A publication as the GUI lists it: the stored record plus the state of the document it froze. */
934
+ async function describePublication(publication) {
935
+ const doc = await storageEngine.getDoc(publication.docId, publication.project);
936
+ const status = !doc
937
+ ? "missing"
938
+ : hashDocContent(doc.title, doc.content) === publication.contentHash
939
+ ? "current"
940
+ : "modified";
941
+ return {
942
+ id: publication.id,
943
+ token: publication.token,
944
+ project: publication.project,
945
+ docId: publication.docId,
946
+ title: publication.title,
947
+ version: publication.version,
948
+ note: publication.note,
949
+ createdAt: publication.createdAt,
950
+ publishedAt: publication.publishedAt,
951
+ status,
952
+ currentVersion: doc ? latestVersion(publication.project, publication.docId) : null,
953
+ };
954
+ }
955
+ function latestVersion(project, docId) {
956
+ return historyStore.listVersions(project, docId)[0]?.version ?? null;
957
+ }
958
+ function assertWritable() {
959
+ if (isReadOnly())
960
+ throw new Error("READ_ONLY mode: publishing is disabled");
961
+ }
962
+ function broadcastPublicationsChanged(project) {
963
+ broadcastToGUI({ type: "PUBLICATIONS_CHANGED", data: { project }, timestamp: new Date().toISOString() });
964
+ }
965
+ async function listPublications(project) {
966
+ const publications = publicationStore.list().filter((p) => !project || p.project === project);
967
+ return { publications: await Promise.all(publications.map(describePublication)) };
968
+ }
969
+ /** The document as it is now, frozen with the version note. */
970
+ async function freezeInput(project, docId, note) {
971
+ const doc = await storageEngine.getDoc(docId, project);
972
+ if (!doc)
973
+ throw new Error(`Doc "${docId}" not found in project "${project}"`);
974
+ return {
975
+ project,
976
+ docId,
977
+ title: doc.title,
978
+ content: doc.content,
979
+ version: latestVersion(project, docId),
980
+ note: note,
981
+ };
982
+ }
983
+ async function publishDoc(data) {
984
+ assertWritable();
985
+ if (!data.project || !data.id)
986
+ throw new Error("project and id are required");
987
+ const publication = publicationStore.publish(await freezeInput(data.project, data.id, data.note));
988
+ logger.info(`Published [${publication.project}] ${publication.docId}`);
989
+ broadcastPublicationsChanged(publication.project);
990
+ return { publication: await describePublication(publication) };
991
+ }
992
+ async function updatePublication(data) {
993
+ assertWritable();
994
+ const existing = data.publicationId ? publicationStore.get(data.publicationId) : undefined;
995
+ if (!existing)
996
+ throw new Error(`Publication "${data.publicationId}" does not exist`);
997
+ const publication = publicationStore.update(existing.id, await freezeInput(existing.project, existing.docId, data.note));
998
+ logger.info(`Publication of [${publication.project}] ${publication.docId} updated`);
999
+ broadcastPublicationsChanged(publication.project);
1000
+ return { publication: await describePublication(publication) };
1001
+ }
1002
+ async function unpublishDoc(data) {
1003
+ assertWritable();
1004
+ if (!data.publicationId)
1005
+ throw new Error("publicationId is required");
1006
+ const publication = publicationStore.unpublish(data.publicationId);
1007
+ logger.info(`Unpublished [${publication.project}] ${publication.docId}`);
1008
+ broadcastPublicationsChanged(publication.project);
1009
+ return { success: true };
1010
+ }
1011
+ /** A moved document keeps its publication: the link stays valid and its state follows the new path. */
1012
+ function movePublication(args) {
1013
+ const parsed = MoveDocArgsSchema.parse(args);
1014
+ const newProject = parsed.new_project ?? parsed.project;
1015
+ const moved = publicationStore.moveDoc(parsed.project, parsed.path, newProject, parsed.new_path ?? parsed.path);
1016
+ if (!moved)
1017
+ return;
1018
+ broadcastPublicationsChanged(parsed.project);
1019
+ if (newProject !== parsed.project)
1020
+ broadcastPublicationsChanged(newProject);
1021
+ }
912
1022
  guiLauncher = new GuiLauncher({
913
1023
  guiPath: path.join(__dirname, "gui-worker.js"),
914
1024
  env: { ...process.env },
@@ -1640,8 +1750,12 @@ async function handleToolCall(request) {
1640
1750
  return await checkLinks(storageEngine, args);
1641
1751
  case "delete_doc":
1642
1752
  return await deleteDoc(storageEngine, embeddingEngine, args);
1643
- case "move_doc":
1644
- return await moveDoc(storageEngine, embeddingEngine, args);
1753
+ case "move_doc": {
1754
+ const result = await moveDoc(storageEngine, embeddingEngine, args);
1755
+ if (!result.isError)
1756
+ movePublication(args);
1757
+ return result;
1758
+ }
1645
1759
  case "get_doc_tree":
1646
1760
  return await getDocTree(storageEngine, args);
1647
1761
  case "list_doc_versions":
@@ -0,0 +1 @@
1
+ *{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;background:#090b0f;color:#e1e4e8;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#root{width:100%;height:100vh}.doc-inline-link{display:inline;padding:0;border:none;background:none;color:#58a6ff;cursor:pointer;font-size:inherit;font-family:inherit;text-decoration:underline;text-underline-offset:2px}.doc-inline-link:hover{color:#79c0ff}.doc-inline-link--broken{color:#f85149;cursor:not-allowed;text-decoration:underline wavy}.doc-inline-link--cross-project{color:#d2a8ff}.doc-inline-link--cross-project:hover{color:#e2c0ff}.doc-content h1{font-size:2em;margin:.67em 0;border-bottom:1px solid #21262d;padding-bottom:.3em}.doc-content h2{font-size:1.5em;margin:.83em 0;border-bottom:1px solid #21262d;padding-bottom:.3em}.doc-content h3{font-size:1.25em;margin:1em 0}.doc-content h4{font-size:1em;margin:1.33em 0}.doc-content p{margin:1em 0;line-height:1.6}.doc-content code{background:#161b22;padding:2px 6px;border-radius:4px;font-family:Fira Code,Cascadia Code,monospace;font-size:.9em;font-variant-ligatures:none}.doc-content pre{background:#161b22;padding:16px;border-radius:8px;overflow-x:auto;border:1px solid #30363d}.doc-content pre code{background:none;padding:0}.doc-content ul,.doc-content ol{padding-left:2em;margin:1em 0}.doc-content li{margin:.25em 0;line-height:1.6}.doc-content table{border-collapse:collapse;width:100%;margin:1em 0}.doc-content th,.doc-content td{border:1px solid #30363d;padding:8px 12px;text-align:left}.doc-content th{background:#161b22;font-weight:600}.doc-content a{color:#58a6ff;text-decoration:none}.doc-content a:hover{text-decoration:underline}.doc-content blockquote{border-left:3px solid #30363d;padding-left:16px;margin:1em 0;color:#8b949e}.code-block-wrapper{border:1px solid #30363d;border-radius:6px;margin:12px 0;overflow:hidden}.code-block-header{display:flex;align-items:center;justify-content:space-between;padding:4px 12px;background:#21262d;border-bottom:1px solid #30363d}.code-block-lang-select{background:transparent;border:none;color:#8b949e;font-size:11px;font-family:Fira Code,Cascadia Code,Consolas,monospace;cursor:pointer;outline:none;padding:2px 0}.code-block-lang-select:hover{color:#c9d1d9}.code-block-lang{color:#8b949e;font-size:11px;font-family:Fira Code,Cascadia Code,Consolas,monospace;padding:2px 0}.code-block-lang-select option{background:#21262d;color:#c9d1d9}.code-block-copy-btn{background:none;border:1px solid #30363d;color:#8b949e;font-size:11px;cursor:pointer;padding:2px 8px;border-radius:4px;transition:all .15s}.code-block-copy-btn:hover{background:#30363d;color:#c9d1d9}.mermaid-block-wrapper{border:1px solid #30363d;border-radius:6px;margin:12px 0;overflow:hidden;background:#161b22}.mermaid-block-header{display:flex;align-items:center;justify-content:space-between;padding:4px 12px;background:#21262d;border-bottom:1px solid #30363d}.mermaid-block-title{color:#8b949e;font-family:Fira Code,Cascadia Code,Consolas,monospace;font-size:11px}.mermaid-block-actions{display:flex;align-items:center;gap:8px}.mermaid-zoom-controls{display:flex;align-items:center;gap:2px}.mermaid-zoom-btn{background:#30363d;border:1px solid #484f58;color:#c9d1d9;border-radius:4px;width:22px;height:22px;font-size:14px;line-height:1;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;transition:background .15s}.mermaid-zoom-btn:hover:not(:disabled){background:#484f58}.mermaid-zoom-btn:disabled{opacity:.35;cursor:not-allowed}.mermaid-zoom-reset{background:transparent;border:1px solid #484f58;color:#8b949e;border-radius:4px;height:22px;min-width:40px;font-size:11px;font-family:Fira Code,Cascadia Code,Consolas,monospace;cursor:pointer;padding:0 4px;transition:background .15s,color .15s}.mermaid-zoom-reset:hover{background:#30363d;color:#c9d1d9}.mermaid-block-content{padding:16px;overflow:auto}.mermaid-block-zoom-container{display:block;transform-origin:top center;transition:transform .15s ease}.mermaid-block-zoom-container svg{display:block;max-width:100%;height:auto;margin:0 auto}.mermaid-block-error{margin:0;color:#f85149;font-family:Fira Code,Cascadia Code,Consolas,monospace;font-size:13px;line-height:1.5;white-space:pre-wrap}.doc-content img.doc-image{max-width:100%;height:auto;border-radius:6px;margin:8px 0;display:block}