funifier-mcp 0.2.27 → 0.3.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.
Files changed (88) hide show
  1. package/.cursor/rules/funifier.mdc +7 -7
  2. package/.github/copilot-instructions.md +10 -8
  3. package/AGENTS.md +8 -4
  4. package/README.md +6 -12
  5. package/datasource-funifier-docs/.coverage.json +1 -1
  6. package/dist/cli/init.d.ts.map +1 -1
  7. package/dist/cli/init.js +13 -9
  8. package/dist/cli/init.js.map +1 -1
  9. package/dist/cli/init.test.js +28 -9
  10. package/dist/cli/init.test.js.map +1 -1
  11. package/dist/cli/prompts.d.ts +1 -0
  12. package/dist/cli/prompts.d.ts.map +1 -1
  13. package/dist/cli/prompts.js +8 -0
  14. package/dist/cli/prompts.js.map +1 -1
  15. package/dist/cli/search.js +3 -3
  16. package/dist/cli/search.js.map +1 -1
  17. package/dist/cli/search.test.js +9 -9
  18. package/dist/cli/search.test.js.map +1 -1
  19. package/dist/mcp/bundle.js +84 -84
  20. package/dist/mcp/check-update.d.ts +5 -0
  21. package/dist/mcp/check-update.d.ts.map +1 -1
  22. package/dist/mcp/check-update.js +21 -10
  23. package/dist/mcp/check-update.js.map +1 -1
  24. package/dist/mcp/check-update.test.d.ts +2 -0
  25. package/dist/mcp/check-update.test.d.ts.map +1 -0
  26. package/dist/mcp/check-update.test.js +33 -0
  27. package/dist/mcp/check-update.test.js.map +1 -0
  28. package/dist/mcp/prompts/templates.d.ts.map +1 -1
  29. package/dist/mcp/prompts/templates.js +35 -0
  30. package/dist/mcp/prompts/templates.js.map +1 -1
  31. package/dist/mcp/resources/documentation.d.ts.map +1 -1
  32. package/dist/mcp/resources/documentation.js +2 -1
  33. package/dist/mcp/resources/documentation.js.map +1 -1
  34. package/dist/mcp/tools/docs-flow.test.d.ts +2 -0
  35. package/dist/mcp/tools/docs-flow.test.d.ts.map +1 -0
  36. package/dist/mcp/tools/docs-flow.test.js +91 -0
  37. package/dist/mcp/tools/docs-flow.test.js.map +1 -0
  38. package/dist/mcp/tools/index.d.ts.map +1 -1
  39. package/dist/mcp/tools/index.js +27 -0
  40. package/dist/mcp/tools/index.js.map +1 -1
  41. package/dist/mcp/tools/read-doc.d.ts +3 -0
  42. package/dist/mcp/tools/read-doc.d.ts.map +1 -0
  43. package/dist/mcp/tools/read-doc.js +97 -0
  44. package/dist/mcp/tools/read-doc.js.map +1 -0
  45. package/dist/mcp/tools/read-doc.test.d.ts +2 -0
  46. package/dist/mcp/tools/read-doc.test.d.ts.map +1 -0
  47. package/dist/mcp/tools/read-doc.test.js +92 -0
  48. package/dist/mcp/tools/read-doc.test.js.map +1 -0
  49. package/dist/mcp/tools/search-docs.js +3 -3
  50. package/dist/mcp/tools/search-docs.js.map +1 -1
  51. package/dist/mcp/tools/search-docs.test.d.ts +2 -0
  52. package/dist/mcp/tools/search-docs.test.d.ts.map +1 -0
  53. package/dist/mcp/tools/search-docs.test.js +100 -0
  54. package/dist/mcp/tools/search-docs.test.js.map +1 -0
  55. package/package.json +1 -1
  56. package/skills/acquire-funifier-knowledge/SKILL.md +25 -2
  57. package/skills/acquire-funifier-knowledge/assets/templates/OVERVIEW.md +39 -0
  58. package/skills/funifier/SKILL.md +5 -3
  59. package/skills/funifier/references/configure-security.md +7 -7
  60. package/skills/funifier/references/create-action.md +7 -7
  61. package/skills/funifier/references/create-aggregate.md +8 -8
  62. package/skills/funifier/references/create-challenge.md +8 -8
  63. package/skills/funifier/references/create-competition.md +6 -6
  64. package/skills/funifier/references/create-crossword.md +1 -1
  65. package/skills/funifier/references/create-custom-object.md +7 -7
  66. package/skills/funifier/references/create-custom-page.md +8 -8
  67. package/skills/funifier/references/create-folder.md +6 -6
  68. package/skills/funifier/references/create-lastmile.md +1 -1
  69. package/skills/funifier/references/create-leaderboard.md +8 -8
  70. package/skills/funifier/references/create-level.md +7 -7
  71. package/skills/funifier/references/create-notification.md +7 -7
  72. package/skills/funifier/references/create-point.md +7 -7
  73. package/skills/funifier/references/create-quiz.md +7 -7
  74. package/skills/funifier/references/create-scheduler.md +10 -10
  75. package/skills/funifier/references/create-story.md +1 -1
  76. package/skills/funifier/references/create-swap.md +6 -6
  77. package/skills/funifier/references/create-trigger.md +14 -14
  78. package/skills/funifier/references/create-virtual-good.md +7 -7
  79. package/skills/funifier/references/create-webhook.md +7 -7
  80. package/skills/funifier/references/create-websocket.md +8 -8
  81. package/skills/funifier/references/create-widget.md +7 -7
  82. package/skills/funifier/references/debug.md +16 -16
  83. package/skills/funifier/references/help.md +8 -8
  84. package/skills/funifier/references/implement-frontend.md +15 -15
  85. package/skills/funifier/references/import-csv.md +7 -7
  86. package/skills/funifier/references/manage-player.md +6 -6
  87. package/skills/funifier/references/manage-team.md +6 -6
  88. package/skills/funifier/references/upload-file.md +6 -6
@@ -1,2 +1,7 @@
1
+ declare function isOutdated(current: string, latest: string): boolean;
2
+ export declare function setUpdateNotice(notice: string): void;
3
+ /** Returns the pending update notice once, then clears it (show only once per session). */
4
+ export declare function consumeUpdateNotice(): string | null;
1
5
  export declare function checkForUpdate(): Promise<void>;
6
+ export { isOutdated };
2
7
  //# sourceMappingURL=check-update.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-update.d.ts","sourceRoot":"","sources":["../../src/mcp/check-update.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA4BpD"}
1
+ {"version":3,"file":"check-update.d.ts","sourceRoot":"","sources":["../../src/mcp/check-update.ts"],"names":[],"mappings":"AAAA,iBAAS,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAW5D;AAMD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,2FAA2F;AAC3F,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAInD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBpD;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setUpdateNotice = setUpdateNotice;
4
+ exports.consumeUpdateNotice = consumeUpdateNotice;
3
5
  exports.checkForUpdate = checkForUpdate;
6
+ exports.isOutdated = isOutdated;
4
7
  function isOutdated(current, latest) {
5
8
  const toTuple = (v) => v
6
9
  .replace(/[^0-9.]/g, "")
@@ -14,6 +17,18 @@ function isOutdated(current, latest) {
14
17
  return lMin > cMin;
15
18
  return lPatch > cPatch;
16
19
  }
20
+ // Set when an update is detected; surfaced once on the next tool result so the
21
+ // user actually sees it (stdio MCP stderr is hidden from chat by most clients).
22
+ let pendingNotice = null;
23
+ function setUpdateNotice(notice) {
24
+ pendingNotice = notice;
25
+ }
26
+ /** Returns the pending update notice once, then clears it (show only once per session). */
27
+ function consumeUpdateNotice() {
28
+ const notice = pendingNotice;
29
+ pendingNotice = null;
30
+ return notice;
31
+ }
17
32
  async function checkForUpdate() {
18
33
  // eslint-disable-next-line @typescript-eslint/no-var-requires
19
34
  const { version: current } = require("../../package.json");
@@ -30,15 +45,11 @@ async function checkForUpdate() {
30
45
  catch {
31
46
  return;
32
47
  }
33
- if (isOutdated(current, latest)) {
34
- console.error([
35
- "",
36
- "┌─────────────────────────────────────────────────────────┐",
37
- `│ Funifier MCP update available: ${current} ${latest}`,
38
- "│ Run: npx funifier-mcp@latest init │",
39
- "└─────────────────────────────────────────────────────────┘",
40
- "",
41
- ].join("\n"));
42
- }
48
+ if (!isOutdated(current, latest))
49
+ return;
50
+ const notice = `⬆ funifier-mcp update available: ${current} → ${latest}. Run: npx funifier-mcp@latest init`;
51
+ setUpdateNotice(notice);
52
+ // Fallback for clients/power users that surface server stderr.
53
+ console.error(notice);
43
54
  }
44
55
  //# sourceMappingURL=check-update.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-update.js","sourceRoot":"","sources":["../../src/mcp/check-update.ts"],"names":[],"mappings":";;AAaA,wCA4BC;AAzCD,SAAS,UAAU,CAAC,OAAe,EAAE,MAAc;IACjD,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAC5B,CAAC;SACE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACtC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACtC,OAAO,MAAM,GAAG,MAAM,CAAC;AACzB,CAAC;AAEM,KAAK,UAAU,cAAc;IAClC,8DAA8D;IAC9D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;IAElF,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gDAAgD,EAAE;YACxE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwB,CAAC;QACvD,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,IAAI,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CACX;YACE,EAAE;YACF,6DAA6D;YAC7D,qCAAqC,OAAO,MAAM,MAAM,EAAE;YAC1D,6DAA6D;YAC7D,6DAA6D;YAC7D,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"check-update.js","sourceRoot":"","sources":["../../src/mcp/check-update.ts"],"names":[],"mappings":";;AAiBA,0CAEC;AAGD,kDAIC;AAED,wCAsBC;AAEQ,gCAAU;AApDnB,SAAS,UAAU,CAAC,OAAe,EAAE,MAAc;IACjD,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAC5B,CAAC;SACE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACtC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,GAAG,IAAI,CAAC;IACtC,OAAO,MAAM,GAAG,MAAM,CAAC;AACzB,CAAC;AAED,+EAA+E;AAC/E,gFAAgF;AAChF,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC,SAAgB,eAAe,CAAC,MAAc;IAC5C,aAAa,GAAG,MAAM,CAAC;AACzB,CAAC;AAED,2FAA2F;AAC3F,SAAgB,mBAAmB;IACjC,MAAM,MAAM,GAAG,aAAa,CAAC;IAC7B,aAAa,GAAG,IAAI,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,cAAc;IAClC,8DAA8D;IAC9D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;IAElF,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gDAAgD,EAAE;YACxE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwB,CAAC;QACvD,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;QAAE,OAAO;IAEzC,MAAM,MAAM,GAAG,oCAAoC,OAAO,MAAM,MAAM,qCAAqC,CAAC;IAC5G,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,+DAA+D;IAC/D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=check-update.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-update.test.d.ts","sourceRoot":"","sources":["../../src/mcp/check-update.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const check_update_1 = require("./check-update");
5
+ (0, vitest_1.describe)("isOutdated", () => {
6
+ (0, vitest_1.it)("detects newer major/minor/patch", () => {
7
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("1.0.0", "2.0.0")).toBe(true);
8
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("1.2.0", "1.3.0")).toBe(true);
9
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("1.2.3", "1.2.4")).toBe(true);
10
+ });
11
+ (0, vitest_1.it)("returns false when current is equal or ahead", () => {
12
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("1.2.3", "1.2.3")).toBe(false);
13
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("2.0.0", "1.9.9")).toBe(false);
14
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("1.3.0", "1.2.9")).toBe(false);
15
+ });
16
+ (0, vitest_1.it)("ignores non-numeric prefixes like ^ or v", () => {
17
+ (0, vitest_1.expect)((0, check_update_1.isOutdated)("0.2.27", "v0.3.0")).toBe(true);
18
+ });
19
+ });
20
+ (0, vitest_1.describe)("update notice", () => {
21
+ (0, vitest_1.beforeEach)(() => {
22
+ (0, check_update_1.consumeUpdateNotice)(); // clear any leftover state
23
+ });
24
+ (0, vitest_1.it)("returns null when no notice is pending", () => {
25
+ (0, vitest_1.expect)((0, check_update_1.consumeUpdateNotice)()).toBeNull();
26
+ });
27
+ (0, vitest_1.it)("returns the notice once, then clears it", () => {
28
+ (0, check_update_1.setUpdateNotice)("update me");
29
+ (0, vitest_1.expect)((0, check_update_1.consumeUpdateNotice)()).toBe("update me");
30
+ (0, vitest_1.expect)((0, check_update_1.consumeUpdateNotice)()).toBeNull();
31
+ });
32
+ });
33
+ //# sourceMappingURL=check-update.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-update.test.js","sourceRoot":"","sources":["../../src/mcp/check-update.test.ts"],"names":[],"mappings":";;AAAA,mCAA0D;AAC1D,iDAAkF;AAElF,IAAA,iBAAQ,EAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAA,WAAE,EAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,IAAA,eAAM,EAAC,IAAA,yBAAU,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,mBAAU,EAAC,GAAG,EAAE;QACd,IAAA,kCAAmB,GAAE,CAAC,CAAC,2BAA2B;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,IAAA,eAAM,EAAC,IAAA,kCAAmB,GAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,IAAA,8BAAe,EAAC,WAAW,CAAC,CAAC;QAC7B,IAAA,eAAM,EAAC,IAAA,kCAAmB,GAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,IAAA,kCAAmB,GAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/mcp/prompts/templates.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,QA6FhD"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/mcp/prompts/templates.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,QAsIhD"}
@@ -55,6 +55,41 @@ function registerPrompts(server) {
55
55
  ],
56
56
  };
57
57
  });
58
+ server.prompt("map_instance", "Map, document and audit an existing Funifier instance (read-only) into docs/funifier/, including a Mermaid architecture map", {
59
+ focus: zod_1.z
60
+ .string()
61
+ .optional()
62
+ .describe("Optional focus area, e.g. 'triggers' or 'mechanics'. Omit to map the whole instance."),
63
+ }, ({ focus }) => {
64
+ const scope = focus
65
+ ? `Focus the deep mapping on: ${focus}. Still inventory and count the other categories, but keep their docs at a high level.`
66
+ : "Map the full instance.";
67
+ return {
68
+ messages: [
69
+ {
70
+ role: "user",
71
+ content: {
72
+ type: "text",
73
+ text: [
74
+ "I want to map and document this EXISTING Funifier instance. This is a READ-ONLY audit — never create, edit or delete anything.",
75
+ scope,
76
+ "",
77
+ "If the `acquire-funifier-knowledge` skill is available, follow it for the full contract. Otherwise, follow these steps:",
78
+ "1. Confirm the MCP connection (e.g. funifier_database action=collections) and record the instance URL/name and today's date.",
79
+ "2. Inventory every listable type with funifier_list (trigger, scheduler, action, challenge, point, level, leaderboard, quiz, virtual-good-catalog/item, public-endpoint, custom-page, widget, websocket, aggregate, challenge-aggregate, auth-module, ai-knowledge), and use funifier_database action=collections to find off-enum elements (webhooks, notifications, competitions, player, team).",
80
+ "3. For objects that need detail, use funifier_get mode=read to extract rules, conditions and actions.",
81
+ "4. Cross-link the objects: which trigger feeds which point/challenge, which scheduler calls which endpoint, which actions satisfy each challenge, which leaderboards use which points.",
82
+ "5. From those (and ONLY those) relationships, build a Mermaid architecture map — 'what fires/awards/feeds/calls what' — and put it in OVERVIEW.md. Every edge must trace to a real configured field; never draw a speculative edge — use a dashed `-.->` marked [ASK USER] when unsure. Collapse any category with >8 objects into a single node annotated with its count.",
83
+ "6. Write the documentation set under docs/funifier/ (OVERVIEW, GAME_MECHANICS, TRIGGERS, SCHEDULERS, CUSTOM_ENDPOINTS, CUSTOM_PAGES, LEADERBOARDS, PLAYER_MODEL, INTEGRATIONS, TECHNIQUES_AND_PATTERNS, CONCERNS). Every claim points to an object ID; no section left empty.",
84
+ "7. Finish with a summary of counts, where each doc lives, and a numbered list of [ASK USER] items to resolve.",
85
+ "",
86
+ "Use only read-only tools: funifier_list, funifier_get (mode=read), funifier_logs, funifier_database (query/aggregate/collections only), funifier_folder (inside/breadcrumb only). Never use funifier_save, funifier_delete, funifier_execute, database insert/update/delete/bulk, or folder progress.",
87
+ ].join("\n"),
88
+ },
89
+ },
90
+ ],
91
+ };
92
+ });
58
93
  server.prompt("implement_frontend", "Implement frontend code using Funifier aggregates", async () => {
59
94
  return {
60
95
  messages: [
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/mcp/prompts/templates.ts"],"names":[],"mappings":";;AAGA,0CA6FC;AAhGD,6BAAwB;AAGxB,SAAgB,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,MAAM,CACX,iBAAiB,EACjB,0DAA0D,EAC1D;QACE,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mEAAmE,CAAC;KAC/F,EACD,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QACX,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;4BACJ,mCAAmC,IAAI,GAAG;4BAC1C,EAAE;4BACF,oBAAoB;4BACpB,iFAAiF,IAAI,GAAG;4BACxF,0CAA0C,IAAI,0BAA0B;4BACxE,qEAAqE;4BACrE,kEAAkE,IAAI,EAAE;4BACxE,EAAE;4BACF,2DAA2D,IAAI,aAAa;yBAC7E,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,gBAAgB,EAChB,sDAAsD,EACtD;QACE,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QACzE,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;KACpD,EACD,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE;QACf,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;4BACJ,oCAAoC,IAAI,aAAa,EAAE,IAAI;4BAC3D,EAAE;4BACF,oBAAoB;4BACpB,yCAAyC,IAAI,yBAAyB;4BACtE,kEAAkE;4BAClE,oGAAoG;4BACpG,gFAAgF;4BAChF,iDAAiD;4BACjD,EAAE;4BACF,yBAAyB,IAAI,wBAAwB;yBACtD,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB,mDAAmD,EACnD,KAAK,IAAI,EAAE;QACT,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;4BACJ,uEAAuE;4BACvE,EAAE;4BACF,oBAAoB;4BACpB,+EAA+E;4BAC/E,+DAA+D;4BAC/D,kEAAkE;4BAClE,wEAAwE;4BACxE,gDAAgD;4BAChD,EAAE;4BACF,+EAA+E;yBAChF,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/mcp/prompts/templates.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"documentation.d.ts","sourceRoot":"","sources":["../../../src/mcp/resources/documentation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAGtF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAiI3D"}
1
+ {"version":3,"file":"documentation.d.ts","sourceRoot":"","sources":["../../../src/mcp/resources/documentation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAGtF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAkI3D"}
@@ -8,7 +8,8 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
10
10
  function registerResources(server) {
11
- // Resolve docs. Source of truth is datasource-funifier-docs/knowledge/ at the project root.
11
+ // Resolve docs. Source of truth is datasource-funifier-docs/knowledge/, resolved relative to
12
+ // this file (the project root in dev, node_modules/funifier-mcp/ when installed as a package).
12
13
  // When running from compiled dist/mcp/resources/documentation.js: __dirname is dist/mcp/resources/ (3 levels up)
13
14
  // When running from esbuild bundle dist/mcp/bundle.js: __dirname is dist/mcp/ (2 levels up)
14
15
  // Try both paths for datasource-funifier-docs, then fall back to legacy doc/knowledge for published package.
@@ -1 +1 @@
1
- {"version":3,"file":"documentation.js","sourceRoot":"","sources":["../../../src/mcp/resources/documentation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documentation.js","sourceRoot":"","sources":["../../../src/mcp/resources/documentation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=docs-flow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-flow.test.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/docs-flow.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
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
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const search_docs_1 = require("./search-docs");
41
+ const read_doc_1 = require("./read-doc");
42
+ const lexical_1 = require("../../core/lexical");
43
+ // End-to-end guarantee of the "swap": docs live only in a package-style root
44
+ // (knowledge/ + .search-index.json) — never copied into the project cwd — and the
45
+ // path that funifier_search_docs returns is consumed verbatim by funifier_read_doc.
46
+ let root;
47
+ let docsPath;
48
+ const TRIGGER_BODY = "# Trigger\n\n## Groovy event\n\nUNIQUE-MARKER-DOC-CONTENT — fires on before_win with a groovy script.";
49
+ function harness() {
50
+ const handlers = {};
51
+ const server = {
52
+ registerTool: (name, _config, handler) => {
53
+ handlers[name] = handler;
54
+ },
55
+ };
56
+ (0, search_docs_1.registerSearchDocsTool)(server, docsPath);
57
+ (0, read_doc_1.registerReadDocTool)(server, docsPath);
58
+ return handlers;
59
+ }
60
+ (0, vitest_1.beforeAll)(() => {
61
+ root = fs.mkdtempSync(path.join(os.tmpdir(), "funifier-docsflow-"));
62
+ docsPath = path.join(root, "knowledge");
63
+ fs.mkdirSync(path.join(docsPath, "modules"), { recursive: true });
64
+ fs.writeFileSync(path.join(docsPath, "modules", "trigger.md"), TRIGGER_BODY);
65
+ fs.writeFileSync(path.join(docsPath, "modules", "quiz.md"), "# Quiz\n\nQuestions and answers.");
66
+ const files = new Map([
67
+ ["knowledge/modules/trigger.md", TRIGGER_BODY],
68
+ ["knowledge/modules/quiz.md", "# Quiz\n\nQuestions and answers."],
69
+ ]);
70
+ fs.writeFileSync(path.join(root, ".search-index.json"), JSON.stringify((0, lexical_1.buildIndex)(files)));
71
+ });
72
+ (0, vitest_1.afterAll)(() => {
73
+ fs.rmSync(root, { recursive: true, force: true });
74
+ });
75
+ (0, vitest_1.describe)("docs search -> read flow (package layout, no cwd copy)", () => {
76
+ (0, vitest_1.it)("search returns a path that read consumes verbatim to return the doc content", () => {
77
+ const h = harness();
78
+ const search = h["funifier_search_docs"]({ query: "trigger groovy event before_win" });
79
+ (0, vitest_1.expect)(search.isError).toBeUndefined();
80
+ const text = search.content[0].text;
81
+ const match = text.match(/^\s*1\.\s+(\S+)\s+\[score:/m);
82
+ (0, vitest_1.expect)(match).not.toBeNull();
83
+ const topPath = match[1];
84
+ (0, vitest_1.expect)(topPath).toBe("modules/trigger");
85
+ // Feed the search result straight into the read tool — the formats must line up.
86
+ const read = h["funifier_read_doc"]({ path: topPath });
87
+ (0, vitest_1.expect)(read.isError).toBeUndefined();
88
+ (0, vitest_1.expect)(read.content[0].text).toContain("UNIQUE-MARKER-DOC-CONTENT");
89
+ });
90
+ });
91
+ //# sourceMappingURL=docs-flow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-flow.test.js","sourceRoot":"","sources":["../../../src/mcp/tools/docs-flow.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAY1C,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAWtF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAqC1C,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAetF"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerTools = registerTools;
4
+ const check_update_1 = require("../check-update");
4
5
  const connect_1 = require("./connect");
5
6
  const list_1 = require("./list");
6
7
  const get_1 = require("./get");
@@ -11,7 +12,32 @@ const logs_1 = require("./logs");
11
12
  const database_1 = require("./database");
12
13
  const folder_1 = require("./folder");
13
14
  const search_docs_1 = require("./search-docs");
15
+ const read_doc_1 = require("./read-doc");
16
+ /**
17
+ * Wraps every tool handler so a pending update notice is prepended to the first
18
+ * tool result of the session. Tool results are the only channel the user reliably
19
+ * sees in a stdio MCP client. The handler is always the last argument.
20
+ */
21
+ function decorateWithUpdateNotice(server) {
22
+ const original = server.registerTool.bind(server);
23
+ server.registerTool = ((...args) => {
24
+ const handler = args[args.length - 1];
25
+ if (typeof handler === "function") {
26
+ args[args.length - 1] = async (...handlerArgs) => {
27
+ const result = await handler(...handlerArgs);
28
+ const notice = (0, check_update_1.consumeUpdateNotice)();
29
+ if (notice && result && Array.isArray(result.content)) {
30
+ result.content.unshift({ type: "text", text: notice });
31
+ }
32
+ return result;
33
+ };
34
+ }
35
+ return original(...args);
36
+ });
37
+ }
14
38
  function registerTools(server, apiHolder, docsPath) {
39
+ // Must run before the tools below register, so their handlers get wrapped.
40
+ decorateWithUpdateNotice(server);
15
41
  (0, connect_1.registerConnectTool)(server, apiHolder);
16
42
  (0, list_1.registerListTool)(server, apiHolder);
17
43
  (0, get_1.registerGetTool)(server, apiHolder);
@@ -22,5 +48,6 @@ function registerTools(server, apiHolder, docsPath) {
22
48
  (0, database_1.registerDatabaseTool)(server, apiHolder);
23
49
  (0, folder_1.registerFolderTool)(server, apiHolder);
24
50
  (0, search_docs_1.registerSearchDocsTool)(server, docsPath);
51
+ (0, read_doc_1.registerReadDocTool)(server, docsPath);
25
52
  }
26
53
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":";;AAaA,sCAWC;AAtBD,uCAAgD;AAChD,iCAA0C;AAC1C,+BAAwC;AACxC,iCAA0C;AAC1C,qCAA8C;AAC9C,uCAAgD;AAChD,iCAA0C;AAC1C,yCAAkD;AAClD,qCAA8C;AAC9C,+CAAuD;AAEvD,SAAgB,aAAa,CAAC,MAAiB,EAAE,SAAoB,EAAE,QAAgB;IACrF,IAAA,6BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,IAAA,uBAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,qBAAe,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,IAAA,uBAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,2BAAkB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,IAAA,6BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,IAAA,uBAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,+BAAoB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxC,IAAA,2BAAkB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,IAAA,oCAAsB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":";;AAsCA,sCAeC;AAnDD,kDAAsD;AACtD,uCAAgD;AAChD,iCAA0C;AAC1C,+BAAwC;AACxC,iCAA0C;AAC1C,qCAA8C;AAC9C,uCAAgD;AAChD,iCAA0C;AAC1C,yCAAkD;AAClD,qCAA8C;AAC9C,+CAAuD;AACvD,yCAAiD;AAEjD;;;;GAIG;AACH,SAAS,wBAAwB,CAAC,MAAiB;IACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAA4B,CAAC;IAC7E,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAW,EAAE,EAAE;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,WAAkB,EAAE,EAAE;gBACtD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC;gBAC7C,MAAM,MAAM,GAAG,IAAA,kCAAmB,GAAE,CAAC;gBACrC,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBACtD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3B,CAAC,CAA+B,CAAC;AACnC,CAAC;AAED,SAAgB,aAAa,CAAC,MAAiB,EAAE,SAAoB,EAAE,QAAgB;IACrF,2EAA2E;IAC3E,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAEjC,IAAA,6BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,IAAA,uBAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,qBAAe,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,IAAA,uBAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,2BAAkB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,IAAA,6BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACvC,IAAA,uBAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,IAAA,+BAAoB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxC,IAAA,2BAAkB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,IAAA,oCAAsB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAA,8BAAmB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerReadDocTool(server: McpServer, docsPath: string): void;
3
+ //# sourceMappingURL=read-doc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-doc.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/read-doc.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAuDtE"}
@@ -0,0 +1,97 @@
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.registerReadDocTool = registerReadDocTool;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const zod_1 = require("zod");
40
+ // Accepts the same identifiers the search tool and skill references emit:
41
+ // "modules/trigger", "funifier://docs/modules/trigger", or "knowledge/modules/trigger.md".
42
+ function normalizeDocPath(input) {
43
+ return input
44
+ .trim()
45
+ .replace(/^funifier:\/\/docs\//, "")
46
+ .replace(/^\/+/, "")
47
+ .replace(/^knowledge\//, "")
48
+ .replace(/\.md$/, "");
49
+ }
50
+ function registerReadDocTool(server, docsPath) {
51
+ const root = path.resolve(docsPath);
52
+ server.registerTool("funifier_read_doc", {
53
+ title: "Read Funifier Documentation",
54
+ description: "Read the full markdown of a Funifier documentation file by path. " +
55
+ "Use after funifier_search_docs to load the most relevant docs. " +
56
+ "Accepts paths like 'modules/trigger', 'guides/java-entities', or a 'funifier://docs/...' URI.",
57
+ inputSchema: {
58
+ path: zod_1.z
59
+ .string()
60
+ .describe("Doc path — e.g. 'modules/trigger', 'guides/aggregates', or 'funifier://docs/modules/trigger'"),
61
+ },
62
+ annotations: {
63
+ readOnlyHint: true,
64
+ destructiveHint: false,
65
+ idempotentHint: true,
66
+ openWorldHint: false,
67
+ },
68
+ }, ({ path: docPath }) => {
69
+ const normalized = normalizeDocPath(docPath);
70
+ if (!normalized) {
71
+ return {
72
+ content: [{ type: "text", text: "Provide a doc path, e.g. funifier_read_doc path=modules/trigger" }],
73
+ isError: true,
74
+ };
75
+ }
76
+ const filePath = path.resolve(root, `${normalized}.md`);
77
+ if (filePath !== root && !filePath.startsWith(root + path.sep)) {
78
+ return {
79
+ content: [{ type: "text", text: `Invalid doc path: ${docPath}` }],
80
+ isError: true,
81
+ };
82
+ }
83
+ if (!fs.existsSync(filePath)) {
84
+ return {
85
+ content: [{
86
+ type: "text",
87
+ text: `Documentation not found: ${normalized}. Use funifier_search_docs to find valid paths.`,
88
+ }],
89
+ isError: true,
90
+ };
91
+ }
92
+ return {
93
+ content: [{ type: "text", text: fs.readFileSync(filePath, "utf-8") }],
94
+ };
95
+ });
96
+ }
97
+ //# sourceMappingURL=read-doc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-doc.js","sourceRoot":"","sources":["../../../src/mcp/tools/read-doc.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,kDAuDC;AAvED,uCAAyB;AACzB,2CAA6B;AAC7B,6BAAwB;AAGxB,0EAA0E;AAC1E,2FAA2F;AAC3F,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,KAAK;SACT,IAAI,EAAE;SACN,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;SACnC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAiB,EAAE,QAAgB;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EACT,mEAAmE;YACnE,iEAAiE;YACjE,+FAA+F;QACjG,WAAW,EAAE;YACX,IAAI,EAAE,OAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,CAAC,8FAA8F,CAAC;SAC5G;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iEAAiE,EAAE,CAAC;gBACpG,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,UAAU,KAAK,CAAC,CAAC;QACxD,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/D,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,OAAO,EAAE,EAAE,CAAC;gBACjE,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,4BAA4B,UAAU,iDAAiD;qBAC9F,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;SACtE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=read-doc.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-doc.test.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/read-doc.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
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
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const read_doc_1 = require("./read-doc");
41
+ let docsRoot;
42
+ function makeInvoke() {
43
+ const handlers = {};
44
+ const server = {
45
+ registerTool: (name, _config, handler) => {
46
+ handlers[name] = handler;
47
+ },
48
+ };
49
+ (0, read_doc_1.registerReadDocTool)(server, docsRoot);
50
+ return (args) => handlers["funifier_read_doc"](args);
51
+ }
52
+ (0, vitest_1.beforeAll)(() => {
53
+ docsRoot = fs.mkdtempSync(path.join(os.tmpdir(), "funifier-docs-"));
54
+ fs.mkdirSync(path.join(docsRoot, "modules"), { recursive: true });
55
+ fs.writeFileSync(path.join(docsRoot, "modules", "trigger.md"), "# Trigger\n\nHello trigger.");
56
+ fs.writeFileSync(path.join(docsRoot, "secret.md"), "TOP SECRET");
57
+ });
58
+ (0, vitest_1.afterAll)(() => {
59
+ fs.rmSync(docsRoot, { recursive: true, force: true });
60
+ });
61
+ (0, vitest_1.describe)("funifier_read_doc", () => {
62
+ (0, vitest_1.it)("returns markdown content for a bare path", () => {
63
+ const result = makeInvoke()({ path: "modules/trigger" });
64
+ (0, vitest_1.expect)(result.isError).toBeUndefined();
65
+ (0, vitest_1.expect)(result.content[0].text).toContain("Hello trigger.");
66
+ });
67
+ (0, vitest_1.it)("accepts the funifier://docs/ URI form", () => {
68
+ const result = makeInvoke()({ path: "funifier://docs/modules/trigger" });
69
+ (0, vitest_1.expect)(result.isError).toBeUndefined();
70
+ (0, vitest_1.expect)(result.content[0].text).toContain("Hello trigger.");
71
+ });
72
+ (0, vitest_1.it)("accepts the knowledge/...md form", () => {
73
+ const result = makeInvoke()({ path: "knowledge/modules/trigger.md" });
74
+ (0, vitest_1.expect)(result.isError).toBeUndefined();
75
+ (0, vitest_1.expect)(result.content[0].text).toContain("Hello trigger.");
76
+ });
77
+ (0, vitest_1.it)("returns isError for a missing doc", () => {
78
+ const result = makeInvoke()({ path: "modules/does-not-exist" });
79
+ (0, vitest_1.expect)(result.isError).toBe(true);
80
+ (0, vitest_1.expect)(result.content[0].text).toContain("not found");
81
+ });
82
+ (0, vitest_1.it)("rejects path traversal outside the docs root", () => {
83
+ const result = makeInvoke()({ path: "../secret" });
84
+ (0, vitest_1.expect)(result.isError).toBe(true);
85
+ (0, vitest_1.expect)(result.content[0].text).not.toContain("TOP SECRET");
86
+ });
87
+ (0, vitest_1.it)("returns isError for an empty path", () => {
88
+ const result = makeInvoke()({ path: " " });
89
+ (0, vitest_1.expect)(result.isError).toBe(true);
90
+ });
91
+ });
92
+ //# sourceMappingURL=read-doc.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-doc.test.js","sourceRoot":"","sources":["../../../src/mcp/tools/read-doc.test.ts"],"names":[],"mappings":"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"}