@vpxa/kb 0.1.24 → 0.1.26

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 (209) hide show
  1. package/README.md +3 -3
  2. package/package.json +9 -2
  3. package/packages/analyzers/dist/symbol-analyzer.js +5 -5
  4. package/packages/cli/dist/commands/init/adapters.js +1 -1
  5. package/packages/cli/dist/commands/init/constants.d.ts +4 -1
  6. package/packages/cli/dist/commands/init/constants.js +1 -1
  7. package/packages/cli/dist/commands/init/frontmatter.d.ts +54 -0
  8. package/packages/cli/dist/commands/init/frontmatter.js +2 -0
  9. package/packages/cli/dist/commands/init/index.js +4 -4
  10. package/packages/cli/dist/commands/init/manifest.d.ts +71 -0
  11. package/packages/cli/dist/commands/init/manifest.js +1 -0
  12. package/packages/cli/dist/commands/init/scaffold.d.ts +28 -5
  13. package/packages/cli/dist/commands/init/scaffold.js +1 -1
  14. package/packages/cli/dist/commands/init/templates.js +38 -9
  15. package/packages/cli/dist/commands/init/user.d.ts +3 -3
  16. package/packages/cli/dist/commands/init/user.js +4 -4
  17. package/packages/cli/dist/commands/system.js +2 -2
  18. package/packages/cli/dist/kb-init.js +1 -1
  19. package/packages/core/dist/errors.d.ts +2 -2
  20. package/packages/core/dist/errors.js +1 -1
  21. package/packages/core/dist/logger.d.ts +2 -1
  22. package/packages/core/dist/logger.js +1 -1
  23. package/packages/core/dist/types.d.ts +6 -0
  24. package/packages/dashboard/dist/assets/index-9ysCkze9.js +21 -0
  25. package/packages/dashboard/dist/assets/index-9ysCkze9.js.map +1 -0
  26. package/packages/dashboard/dist/assets/index-CHpVij2M.css +1 -0
  27. package/packages/dashboard/dist/index.html +18 -0
  28. package/packages/elicitation/dist/__tests__/build.test.d.ts +1 -0
  29. package/packages/elicitation/dist/__tests__/build.test.js +35 -0
  30. package/packages/elicitation/dist/__tests__/fields.test.d.ts +1 -0
  31. package/packages/elicitation/dist/__tests__/fields.test.js +81 -0
  32. package/packages/elicitation/dist/__tests__/normalize.test.d.ts +1 -0
  33. package/packages/elicitation/dist/__tests__/normalize.test.js +60 -0
  34. package/packages/elicitation/dist/build.d.ts +13 -0
  35. package/packages/elicitation/dist/build.js +23 -0
  36. package/packages/elicitation/dist/fields.d.ts +41 -0
  37. package/packages/elicitation/dist/fields.js +62 -0
  38. package/packages/elicitation/dist/index.d.ts +10 -0
  39. package/packages/elicitation/dist/index.js +12 -0
  40. package/packages/elicitation/dist/normalize.d.ts +15 -0
  41. package/packages/elicitation/dist/normalize.js +31 -0
  42. package/packages/elicitation/dist/types.d.ts +85 -0
  43. package/packages/elicitation/dist/types.js +8 -0
  44. package/packages/kb-client/dist/direct-client.d.ts +37 -0
  45. package/packages/kb-client/dist/direct-client.js +1 -0
  46. package/packages/kb-client/dist/index.d.ts +5 -0
  47. package/packages/kb-client/dist/index.js +1 -0
  48. package/packages/kb-client/dist/mcp-client.d.ts +19 -0
  49. package/packages/kb-client/dist/mcp-client.js +4 -0
  50. package/packages/kb-client/dist/parsers.d.ts +35 -0
  51. package/packages/kb-client/dist/parsers.js +2 -0
  52. package/packages/kb-client/dist/types.d.ts +62 -0
  53. package/packages/kb-client/dist/types.js +1 -0
  54. package/packages/present/dist/index.html +384 -0
  55. package/packages/server/dist/completions.d.ts +14 -0
  56. package/packages/server/dist/completions.js +1 -0
  57. package/packages/server/dist/dashboard-static.d.ts +27 -0
  58. package/packages/server/dist/dashboard-static.js +1 -0
  59. package/packages/server/dist/elicitor.d.ts +18 -0
  60. package/packages/server/dist/elicitor.js +1 -0
  61. package/packages/server/dist/index.js +1 -1
  62. package/packages/server/dist/mcp-logging.js +1 -1
  63. package/packages/server/dist/output-schemas.d.ts +118 -1
  64. package/packages/server/dist/output-schemas.js +1 -1
  65. package/packages/server/dist/prompts.d.ts +9 -2
  66. package/packages/server/dist/prompts.js +13 -7
  67. package/packages/server/dist/resources/curated-resources.js +1 -1
  68. package/packages/server/dist/resources/resource-notifier.d.ts +45 -0
  69. package/packages/server/dist/resources/resource-notifier.js +1 -0
  70. package/packages/server/dist/sampling.d.ts +41 -0
  71. package/packages/server/dist/sampling.js +2 -0
  72. package/packages/server/dist/server.d.ts +5 -2
  73. package/packages/server/dist/server.js +2 -2
  74. package/packages/server/dist/task-manager.d.ts +40 -0
  75. package/packages/server/dist/task-manager.js +1 -0
  76. package/packages/server/dist/tool-metadata.js +1 -1
  77. package/packages/server/dist/tool-prefix.d.ts +12 -0
  78. package/packages/server/dist/tool-prefix.js +1 -0
  79. package/packages/server/dist/tools/analyze.tools.js +4 -4
  80. package/packages/server/dist/tools/audit.tool.js +1 -1
  81. package/packages/server/dist/tools/brainstorm.tool.d.ts +7 -0
  82. package/packages/server/dist/tools/brainstorm.tool.js +9 -0
  83. package/packages/server/dist/tools/context.tools.js +9 -9
  84. package/packages/server/dist/tools/execution.tools.d.ts +2 -1
  85. package/packages/server/dist/tools/execution.tools.js +4 -4
  86. package/packages/server/dist/tools/forge.tools.js +10 -10
  87. package/packages/server/dist/tools/forget.tool.d.ts +2 -1
  88. package/packages/server/dist/tools/forget.tool.js +1 -1
  89. package/packages/server/dist/tools/graph.tool.js +2 -2
  90. package/packages/server/dist/tools/manipulation.tools.js +4 -4
  91. package/packages/server/dist/tools/onboard.tool.js +2 -2
  92. package/packages/server/dist/tools/present-blocks.d.ts +46 -0
  93. package/packages/server/dist/tools/present-blocks.js +27 -0
  94. package/packages/server/dist/tools/present-charts.d.ts +31 -0
  95. package/packages/server/dist/tools/present-charts.js +34 -0
  96. package/packages/server/dist/tools/present-theme.d.ts +14 -0
  97. package/packages/server/dist/tools/present-theme.js +395 -0
  98. package/packages/server/dist/tools/present-utils.d.ts +11 -0
  99. package/packages/server/dist/tools/present-utils.js +1 -0
  100. package/packages/server/dist/tools/present.tool.d.ts +7 -0
  101. package/packages/server/dist/tools/present.tool.js +113 -0
  102. package/packages/server/dist/tools/produce.tool.js +2 -2
  103. package/packages/server/dist/tools/reindex.tool.d.ts +2 -1
  104. package/packages/server/dist/tools/reindex.tool.js +2 -2
  105. package/packages/server/dist/tools/remember.tool.d.ts +2 -1
  106. package/packages/server/dist/tools/remember.tool.js +2 -2
  107. package/packages/server/dist/tools/replay.tool.js +1 -1
  108. package/packages/server/dist/tools/search.tool.d.ts +2 -1
  109. package/packages/server/dist/tools/search.tool.js +5 -4
  110. package/packages/server/dist/tools/status.tool.js +2 -2
  111. package/packages/server/dist/tools/update.tool.d.ts +2 -1
  112. package/packages/server/dist/tools/update.tool.js +1 -1
  113. package/packages/server/dist/tools/utility.tools.js +1 -1
  114. package/packages/tools/dist/batch.js +1 -1
  115. package/packages/tools/dist/checkpoint.js +1 -1
  116. package/packages/tools/dist/config-extractor.d.ts +9 -0
  117. package/packages/tools/dist/config-extractor.js +7 -0
  118. package/packages/tools/dist/dead-symbols.js +2 -2
  119. package/packages/tools/dist/diagram-builder.d.ts +9 -0
  120. package/packages/tools/dist/diagram-builder.js +9 -0
  121. package/packages/tools/dist/evidence-map.d.ts +12 -1
  122. package/packages/tools/dist/evidence-map.js +2 -2
  123. package/packages/tools/dist/find-examples.js +2 -2
  124. package/packages/tools/dist/forge-classify.d.ts +4 -0
  125. package/packages/tools/dist/forge-classify.js +1 -1
  126. package/packages/tools/dist/git-context.d.ts +1 -0
  127. package/packages/tools/dist/git-context.js +3 -3
  128. package/packages/tools/dist/index.d.ts +3 -2
  129. package/packages/tools/dist/index.js +1 -1
  130. package/packages/tools/dist/onboard-utils.d.ts +12 -0
  131. package/packages/tools/dist/onboard-utils.js +1 -0
  132. package/packages/tools/dist/onboard.js +2 -21
  133. package/packages/tools/dist/regex-utils.d.ts +8 -0
  134. package/packages/tools/dist/regex-utils.js +1 -0
  135. package/packages/tools/dist/rename.js +2 -2
  136. package/packages/tools/dist/replay.d.ts +2 -1
  137. package/packages/tools/dist/replay.js +4 -4
  138. package/packages/tools/dist/symbol.js +3 -3
  139. package/packages/tools/dist/synthesis-engine.d.ts +13 -0
  140. package/packages/tools/dist/synthesis-engine.js +6 -0
  141. package/packages/tools/dist/trace.js +2 -2
  142. package/packages/tui/dist/App-DXY0-tlW.js +2 -0
  143. package/packages/tui/dist/App.d.ts +3 -3
  144. package/packages/tui/dist/App.js +1 -1
  145. package/packages/tui/dist/CuratedPanel-BIamXLNy.js +2 -0
  146. package/packages/tui/dist/LogPanel-D6u6o84n.js +3 -0
  147. package/packages/tui/dist/SearchPanel-CpJGczAc.js +2 -0
  148. package/packages/tui/dist/StatusPanel-BAbUxyqQ.js +2 -0
  149. package/packages/tui/dist/hooks/useKBClient.d.ts +9 -0
  150. package/packages/tui/dist/hooks/useKBClient.js +2 -0
  151. package/packages/tui/dist/hooks/usePolling.d.ts +8 -0
  152. package/packages/tui/dist/hooks/usePolling.js +2 -0
  153. package/packages/tui/dist/index.d.ts +6 -2
  154. package/packages/tui/dist/index.js +1 -1
  155. package/packages/tui/dist/jsx-runtime-y6Gdq5PZ.js +294 -0
  156. package/packages/tui/dist/panels/CuratedPanel.d.ts +1 -7
  157. package/packages/tui/dist/panels/CuratedPanel.js +1 -1
  158. package/packages/tui/dist/panels/LogPanel.js +1 -1
  159. package/packages/tui/dist/panels/SearchPanel.d.ts +1 -10
  160. package/packages/tui/dist/panels/SearchPanel.js +1 -1
  161. package/packages/tui/dist/panels/StatusPanel.d.ts +1 -7
  162. package/packages/tui/dist/panels/StatusPanel.js +1 -1
  163. package/packages/tui/dist/react-D__J1GQe.js +24 -0
  164. package/packages/tui/dist/types-VcTHNV6s.d.ts +64 -0
  165. package/packages/tui/dist/useKBClient-C35iA4uG.js +2 -0
  166. package/packages/tui/dist/usePolling-BbjnRWgx.js +2 -0
  167. package/scaffold/adapters/copilot.mjs +9 -81
  168. package/scaffold/definitions/agents.mjs +12 -0
  169. package/scaffold/definitions/bodies.mjs +39 -14
  170. package/scaffold/definitions/protocols.mjs +149 -0
  171. package/scaffold/definitions/tools.mjs +40 -5
  172. package/scaffold/general/agents/Architect-Reviewer-Alpha.agent.md +1 -1
  173. package/scaffold/general/agents/Architect-Reviewer-Beta.agent.md +1 -1
  174. package/scaffold/general/agents/Code-Reviewer-Alpha.agent.md +1 -1
  175. package/scaffold/general/agents/Code-Reviewer-Beta.agent.md +1 -1
  176. package/scaffold/general/agents/Debugger.agent.md +2 -2
  177. package/scaffold/general/agents/Documenter.agent.md +2 -2
  178. package/scaffold/general/agents/Explorer.agent.md +4 -3
  179. package/scaffold/general/agents/Frontend.agent.md +1 -1
  180. package/scaffold/general/agents/Implementer.agent.md +1 -1
  181. package/scaffold/general/agents/Orchestrator.agent.md +16 -1
  182. package/scaffold/general/agents/Planner.agent.md +11 -4
  183. package/scaffold/general/agents/Refactor.agent.md +1 -1
  184. package/scaffold/general/agents/Researcher-Alpha.agent.md +1 -1
  185. package/scaffold/general/agents/Researcher-Beta.agent.md +1 -1
  186. package/scaffold/general/agents/Researcher-Delta.agent.md +1 -1
  187. package/scaffold/general/agents/Researcher-Gamma.agent.md +1 -1
  188. package/scaffold/general/agents/Security.agent.md +10 -8
  189. package/scaffold/general/agents/_shared/architect-reviewer-base.md +1 -0
  190. package/scaffold/general/agents/_shared/code-agent-base.md +28 -0
  191. package/scaffold/general/agents/_shared/code-reviewer-base.md +1 -0
  192. package/scaffold/general/agents/_shared/forge-protocol.md +44 -0
  193. package/scaffold/general/agents/_shared/researcher-base.md +14 -0
  194. package/scaffold/general/agents/templates/adr-template.md +1 -0
  195. package/scaffold/general/agents/templates/execution-state.md +1 -0
  196. package/skills/knowledge-base/SKILL.md +19 -6
  197. package/skills/present/SKILL.md +153 -0
  198. package/packages/server/dist/tools/toolkit.tools.d.ts +0 -36
  199. package/packages/server/dist/tools/toolkit.tools.js +0 -20
  200. package/packages/tui/dist/App-DE_tdOhs.js +0 -2
  201. package/packages/tui/dist/CuratedPanel-sYdZAICX.js +0 -2
  202. package/packages/tui/dist/LogPanel-Ce3jMQbH.js +0 -3
  203. package/packages/tui/dist/SearchPanel-DREo6zgt.js +0 -2
  204. package/packages/tui/dist/StatusPanel-2ex8fLOO.js +0 -2
  205. package/packages/tui/dist/embedder.interface-IFCBpOlX.d.ts +0 -28
  206. package/packages/tui/dist/index-C8NmOF18.d.ts +0 -13
  207. package/packages/tui/dist/jsx-runtime-Cof-kwFn.js +0 -316
  208. package/packages/tui/dist/store.interface-CnY6SPOH.d.ts +0 -150
  209. /package/packages/tui/dist/{devtools-DUyj952l.js → devtools-DMOZMn70.js} +0 -0
@@ -0,0 +1 @@
1
+ .react-flow{--xy-edge-stroke-default:#b1b1b7;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#555;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#ffffff80;--xy-minimap-background-color-default:#fff;--xy-minimap-mask-background-color-default:#f0f0f099;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#e2e2e2;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:transparent;--xy-background-pattern-dots-color-default:#91919a;--xy-background-pattern-lines-color-default:#eee;--xy-background-pattern-cross-color-default:#e2e2e2;background-color:var(--xy-background-color,var(--xy-background-color-default));--xy-node-color-default:inherit;--xy-node-border-default:1px solid #1a192b;--xy-node-background-color-default:#fff;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #00000014;--xy-node-boxshadow-selected-default:0 0 0 .5px #1a192b;--xy-node-border-radius-default:3px;--xy-handle-background-color-default:#1a192b;--xy-handle-border-color-default:#fff;--xy-selection-background-color-default:#0059dc14;--xy-selection-border-default:1px dotted #0059dccc;--xy-controls-button-background-color-default:#fefefe;--xy-controls-button-background-color-hover-default:#f4f4f4;--xy-controls-button-color-default:inherit;--xy-controls-button-color-hover-default:inherit;--xy-controls-button-border-color-default:#eee;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#fff;--xy-edge-label-color-default:inherit;--xy-resize-background-color-default:#3367d9;direction:ltr}.react-flow.dark{--xy-edge-stroke-default:#3e3e3e;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#727272;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#96969640;--xy-minimap-background-color-default:#141414;--xy-minimap-mask-background-color-default:#3c3c3c99;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#2b2b2b;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:#141414;--xy-background-pattern-dots-color-default:#777;--xy-background-pattern-lines-color-default:#777;--xy-background-pattern-cross-color-default:#777;--xy-node-color-default:#f8f8f8;--xy-node-border-default:1px solid #3c3c3c;--xy-node-background-color-default:#1e1e1e;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #ffffff14;--xy-node-boxshadow-selected-default:0 0 0 .5px #999;--xy-handle-background-color-default:#bebebe;--xy-handle-border-color-default:#1e1e1e;--xy-selection-background-color-default:#c8c8dc14;--xy-selection-border-default:1px dotted #c8c8dccc;--xy-controls-button-background-color-default:#2b2b2b;--xy-controls-button-background-color-hover-default:#3e3e3e;--xy-controls-button-color-default:#f8f8f8;--xy-controls-button-color-hover-default:#fff;--xy-controls-button-border-color-default:#5b5b5b;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#141414;--xy-edge-label-color-default:#f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props,var(--xy-background-color,var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width,var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke,var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width,var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{pointer-events:none;position:absolute;overflow:visible}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected,var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:.5s linear infinite dashdraw}svg.react-flow__connectionline{z-index:1001;position:absolute;overflow:visible}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{-webkit-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default;position:absolute}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:0 0;pointer-events:none}.react-flow__nodesselection-rect{pointer-events:all;cursor:grab;position:absolute}.react-flow__handle{pointer-events:none;background-color:var(--xy-handle-background-color,var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color,var(--xy-handle-border-color-default));border-radius:100%;width:6px;min-width:5px;height:6px;min-height:5px;position:absolute}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;bottom:0;left:50%;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{z-index:5;margin:15px;position:absolute}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px)translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px)translateY(-50%)}.react-flow__attribution{background:var(--xy-attribution-background-color,var(--xy-attribution-background-color-default));margin:0;padding:2px 3px;font-size:10px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10px}}.react-flow__edgelabel-renderer{pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__viewport-portal{-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__minimap{background:var(--xy-minimap-background-color-props,var(--xy-minimap-background-color,var(--xy-minimap-background-color-default)))}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var(--xy-minimap-mask-background-color-props,var(--xy-minimap-mask-background-color,var(--xy-minimap-mask-background-color-default)));stroke:var(--xy-minimap-mask-stroke-color-props,var(--xy-minimap-mask-stroke-color,var(--xy-minimap-mask-stroke-color-default)));stroke-width:var(--xy-minimap-mask-stroke-width-props,var(--xy-minimap-mask-stroke-width,var(--xy-minimap-mask-stroke-width-default)))}.react-flow__minimap-node{fill:var(--xy-minimap-node-background-color-props,var(--xy-minimap-node-background-color,var(--xy-minimap-node-background-color-default)));stroke:var(--xy-minimap-node-stroke-color-props,var(--xy-minimap-node-stroke-color,var(--xy-minimap-node-stroke-color-default)));stroke-width:var(--xy-minimap-node-stroke-width-props,var(--xy-minimap-node-stroke-width,var(--xy-minimap-node-stroke-width-default)))}.react-flow__background-pattern.dots{fill:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-dots-color-default)))}.react-flow__background-pattern.lines{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-lines-color-default)))}.react-flow__background-pattern.cross{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-cross-color-default)))}.react-flow__controls{box-shadow:var(--xy-controls-box-shadow,var(--xy-controls-box-shadow-default));flex-direction:column;display:flex}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{background:var(--xy-controls-button-background-color,var(--xy-controls-button-background-color-default));border:none;border-bottom:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)));width:26px;height:26px;color:var(--xy-controls-button-color-props,var(--xy-controls-button-color,var(--xy-controls-button-color-default)));cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;padding:4px;display:flex}.react-flow__controls-button svg{fill:currentColor;width:100%;max-width:12px;max-height:12px}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{border-radius:var(--xy-node-border-radius,var(--xy-node-border-radius-default));width:150px;color:var(--xy-node-color,var(--xy-node-color-default));text-align:center;border:var(--xy-node-border,var(--xy-node-border-default));background-color:var(--xy-node-background-color,var(--xy-node-background-color-default));padding:10px;font-size:12px}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover,var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected,var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color,var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color,var(--xy-selection-background-color-default));border:var(--xy-selection-border,var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var(--xy-controls-button-background-color-hover-props,var(--xy-controls-button-background-color-hover,var(--xy-controls-button-background-color-hover-default)));color:var(--xy-controls-button-color-hover-props,var(--xy-controls-button-color-hover,var(--xy-controls-button-color-hover-default)))}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)))}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border:1px solid #fff;border-radius:1px;width:5px;height:5px;translate:-50% -50%}.react-flow__resize-control.handle.left{top:50%;left:0}.react-flow__resize-control.handle.right{top:50%;left:100%}.react-flow__resize-control.handle.top{top:0;left:50%}.react-flow__resize-control.handle.bottom{top:100%;left:50%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border-style:solid;border-width:0}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;height:100%;top:0;transform:translate(-50%)}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{width:100%;height:1px;left:0;transform:translateY(-50%)}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color,var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color,var(--xy-edge-label-color-default))}
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>KB Dashboard</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ html, body, #root { width: 100%; height: 100%; overflow: hidden; }
10
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0d1117; color: #c9d1d9; }
11
+ </style>
12
+ <script type="module" crossorigin src="/_dashboard/assets/index-9ysCkze9.js"></script>
13
+ <link rel="stylesheet" crossorigin href="/_dashboard/assets/index-CHpVij2M.css">
14
+ </head>
15
+ <body>
16
+ <div id="root"></div>
17
+ </body>
18
+ </html>
@@ -0,0 +1,35 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { buildElicitRequest, buildFormSchema } from '../build.js';
3
+ import { field } from '../fields.js';
4
+ describe('buildFormSchema', () => {
5
+ it('builds a schema from fields', () => {
6
+ const schema = buildFormSchema({
7
+ name: field.text('Name'),
8
+ confirm: field.confirm('OK?'),
9
+ });
10
+ expect(schema.type).toBe('object');
11
+ expect(Object.keys(schema.properties)).toEqual(['name', 'confirm']);
12
+ expect(schema.required).toBeUndefined();
13
+ });
14
+ it('includes required array when provided', () => {
15
+ const schema = buildFormSchema({ name: field.text('Name') }, ['name']);
16
+ expect(schema.required).toEqual(['name']);
17
+ });
18
+ it('omits required when empty array', () => {
19
+ const schema = buildFormSchema({ name: field.text('Name') }, []);
20
+ expect(schema.required).toBeUndefined();
21
+ });
22
+ });
23
+ describe('buildElicitRequest', () => {
24
+ it('builds a complete request', () => {
25
+ const req = buildElicitRequest('Choose your options:', {
26
+ color: field.select('Color', ['red', 'blue']),
27
+ count: field.number('Count', { minimum: 1 }),
28
+ }, ['color']);
29
+ expect(req.message).toBe('Choose your options:');
30
+ expect(req.schema.type).toBe('object');
31
+ expect(req.schema.properties.color.type).toBe('string');
32
+ expect(req.schema.properties.count.type).toBe('number');
33
+ expect(req.schema.required).toEqual(['color']);
34
+ });
35
+ });
@@ -0,0 +1,81 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { field } from '../fields.js';
3
+ describe('field builders', () => {
4
+ describe('text', () => {
5
+ it('creates a text field with title only', () => {
6
+ const f = field.text('Name');
7
+ expect(f).toEqual({ type: 'string', title: 'Name' });
8
+ });
9
+ it('creates a text field with all options', () => {
10
+ const f = field.text('Query', {
11
+ description: 'Search query',
12
+ minLength: 1,
13
+ maxLength: 500,
14
+ default: 'hello',
15
+ });
16
+ expect(f.type).toBe('string');
17
+ expect(f.title).toBe('Query');
18
+ expect(f.description).toBe('Search query');
19
+ expect(f.minLength).toBe(1);
20
+ expect(f.maxLength).toBe(500);
21
+ expect(f.default).toBe('hello');
22
+ });
23
+ it('omits undefined optional fields', () => {
24
+ const f = field.text('Name', { description: 'test' });
25
+ expect(f).not.toHaveProperty('minLength');
26
+ expect(f).not.toHaveProperty('maxLength');
27
+ expect(f).not.toHaveProperty('default');
28
+ });
29
+ });
30
+ describe('select', () => {
31
+ it('creates a single-select field', () => {
32
+ const f = field.select('Color', ['red', 'green', 'blue']);
33
+ expect(f).toEqual({
34
+ type: 'string',
35
+ title: 'Color',
36
+ enum: ['red', 'green', 'blue'],
37
+ });
38
+ });
39
+ it('supports enumNames and default', () => {
40
+ const f = field.select('Size', ['s', 'm', 'l'], {
41
+ enumNames: ['Small', 'Medium', 'Large'],
42
+ default: 'm',
43
+ });
44
+ expect(f.enumNames).toEqual(['Small', 'Medium', 'Large']);
45
+ expect(f.default).toBe('m');
46
+ });
47
+ });
48
+ describe('multi', () => {
49
+ it('creates a multi-select field', () => {
50
+ const f = field.multi('Tags', ['a', 'b', 'c']);
51
+ expect(f).toEqual({
52
+ type: 'array',
53
+ title: 'Tags',
54
+ items: { type: 'string', enum: ['a', 'b', 'c'] },
55
+ uniqueItems: true,
56
+ });
57
+ });
58
+ });
59
+ describe('confirm', () => {
60
+ it('creates a boolean field', () => {
61
+ const f = field.confirm('Proceed?');
62
+ expect(f).toEqual({ type: 'boolean', title: 'Proceed?' });
63
+ });
64
+ it('supports default value', () => {
65
+ const f = field.confirm('Enable', { default: true });
66
+ expect(f.default).toBe(true);
67
+ });
68
+ });
69
+ describe('number', () => {
70
+ it('creates a number field', () => {
71
+ const f = field.number('Count');
72
+ expect(f).toEqual({ type: 'number', title: 'Count' });
73
+ });
74
+ it('creates an integer field with range', () => {
75
+ const f = field.number('Page', { integer: true, minimum: 1, maximum: 100 });
76
+ expect(f.type).toBe('integer');
77
+ expect(f.minimum).toBe(1);
78
+ expect(f.maximum).toBe(100);
79
+ });
80
+ });
81
+ });
@@ -0,0 +1,60 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { normalizeResponse } from '../normalize.js';
3
+ describe('normalizeResponse', () => {
4
+ it('returns cancel for null input', () => {
5
+ expect(normalizeResponse(null)).toEqual({ action: 'cancel' });
6
+ });
7
+ it('returns cancel for undefined input', () => {
8
+ expect(normalizeResponse(undefined)).toEqual({ action: 'cancel' });
9
+ });
10
+ it('normalizes accept with valid content', () => {
11
+ const result = normalizeResponse({
12
+ action: 'accept',
13
+ content: { name: 'test', count: 42, ok: true },
14
+ });
15
+ expect(result.action).toBe('accept');
16
+ expect(result.content).toEqual({ name: 'test', count: 42, ok: true });
17
+ });
18
+ it('normalizes accept with string array content', () => {
19
+ const result = normalizeResponse({
20
+ action: 'accept',
21
+ content: { tags: ['a', 'b', 'c'] },
22
+ });
23
+ expect(result.action).toBe('accept');
24
+ expect(result.content).toEqual({ tags: ['a', 'b', 'c'] });
25
+ });
26
+ it('strips non-primitive content values', () => {
27
+ const result = normalizeResponse({
28
+ action: 'accept',
29
+ content: { valid: 'yes', nested: { bad: true } },
30
+ });
31
+ expect(result.content).toEqual({ valid: 'yes' });
32
+ });
33
+ it('strips mixed arrays', () => {
34
+ const result = normalizeResponse({
35
+ action: 'accept',
36
+ content: { mixed: [1, 'two'] },
37
+ });
38
+ // Mixed array is not all strings, should be stripped
39
+ expect(result.content).toEqual({});
40
+ });
41
+ it('normalizes decline without content', () => {
42
+ const result = normalizeResponse({ action: 'decline' });
43
+ expect(result).toEqual({ action: 'decline' });
44
+ });
45
+ it('normalizes cancel', () => {
46
+ const result = normalizeResponse({ action: 'cancel' });
47
+ expect(result).toEqual({ action: 'cancel' });
48
+ });
49
+ it('treats unknown action as cancel', () => {
50
+ const result = normalizeResponse({ action: 'timeout' });
51
+ expect(result).toEqual({ action: 'cancel' });
52
+ });
53
+ it('drops content when action is decline', () => {
54
+ const result = normalizeResponse({
55
+ action: 'decline',
56
+ content: { leftover: 'data' },
57
+ });
58
+ expect(result.content).toBeUndefined();
59
+ });
60
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Request builder — construct MCP-compatible elicitation request parameters.
3
+ */
4
+ import type { ElicitFormSchema, ElicitOptions, FieldSchema } from './types.js';
5
+ /** Build a form schema from a record of named fields. */
6
+ export declare function buildFormSchema(fields: Record<string, FieldSchema>, required?: string[]): ElicitFormSchema;
7
+ /**
8
+ * Build the full elicitation request options.
9
+ * `message` — prompt text shown above the form.
10
+ * `fields` — record of field-id → FieldSchema.
11
+ * `required` — field ids that must be filled.
12
+ */
13
+ export declare function buildElicitRequest(message: string, fields: Record<string, FieldSchema>, required?: string[]): ElicitOptions;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Request builder — construct MCP-compatible elicitation request parameters.
3
+ */
4
+ /** Build a form schema from a record of named fields. */
5
+ export function buildFormSchema(fields, required) {
6
+ return {
7
+ type: 'object',
8
+ properties: fields,
9
+ ...(required && required.length > 0 ? { required } : {}),
10
+ };
11
+ }
12
+ /**
13
+ * Build the full elicitation request options.
14
+ * `message` — prompt text shown above the form.
15
+ * `fields` — record of field-id → FieldSchema.
16
+ * `required` — field ids that must be filled.
17
+ */
18
+ export function buildElicitRequest(message, fields, required) {
19
+ return {
20
+ message,
21
+ schema: buildFormSchema(fields, required),
22
+ };
23
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Field builders — create typed field schemas for MCP elicitation forms.
3
+ *
4
+ * Usage:
5
+ * field.text('Name', { description: 'Your full name' })
6
+ * field.select('Color', ['red', 'green', 'blue'])
7
+ * field.confirm('Proceed?')
8
+ */
9
+ import type { ArrayFieldSchema, BooleanFieldSchema, EnumFieldSchema, NumberFieldSchema, TextFieldSchema } from './types.js';
10
+ export declare const field: {
11
+ /** Free text input. */
12
+ readonly text: (title: string, opts?: {
13
+ description?: string;
14
+ minLength?: number;
15
+ maxLength?: number;
16
+ default?: string;
17
+ }) => TextFieldSchema;
18
+ /** Single-select dropdown/radio. */
19
+ readonly select: (title: string, options: string[], opts?: {
20
+ description?: string;
21
+ enumNames?: string[];
22
+ default?: string;
23
+ }) => EnumFieldSchema;
24
+ /** Multi-select checkboxes. */
25
+ readonly multi: (title: string, options: string[], opts?: {
26
+ description?: string;
27
+ }) => ArrayFieldSchema;
28
+ /** Boolean checkbox / confirmation. */
29
+ readonly confirm: (title: string, opts?: {
30
+ description?: string;
31
+ default?: boolean;
32
+ }) => BooleanFieldSchema;
33
+ /** Numeric input. */
34
+ readonly number: (title: string, opts?: {
35
+ description?: string;
36
+ minimum?: number;
37
+ maximum?: number;
38
+ integer?: boolean;
39
+ default?: number;
40
+ }) => NumberFieldSchema;
41
+ };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Field builders — create typed field schemas for MCP elicitation forms.
3
+ *
4
+ * Usage:
5
+ * field.text('Name', { description: 'Your full name' })
6
+ * field.select('Color', ['red', 'green', 'blue'])
7
+ * field.confirm('Proceed?')
8
+ */
9
+ export const field = {
10
+ /** Free text input. */
11
+ text(title, opts) {
12
+ return {
13
+ type: 'string',
14
+ title,
15
+ ...(opts?.description !== undefined && { description: opts.description }),
16
+ ...(opts?.minLength !== undefined && { minLength: opts.minLength }),
17
+ ...(opts?.maxLength !== undefined && { maxLength: opts.maxLength }),
18
+ ...(opts?.default !== undefined && { default: opts.default }),
19
+ };
20
+ },
21
+ /** Single-select dropdown/radio. */
22
+ select(title, options, opts) {
23
+ return {
24
+ type: 'string',
25
+ title,
26
+ enum: options,
27
+ ...(opts?.description !== undefined && { description: opts.description }),
28
+ ...(opts?.enumNames !== undefined && { enumNames: opts.enumNames }),
29
+ ...(opts?.default !== undefined && { default: opts.default }),
30
+ };
31
+ },
32
+ /** Multi-select checkboxes. */
33
+ multi(title, options, opts) {
34
+ return {
35
+ type: 'array',
36
+ title,
37
+ items: { type: 'string', enum: options },
38
+ uniqueItems: true,
39
+ ...(opts?.description !== undefined && { description: opts.description }),
40
+ };
41
+ },
42
+ /** Boolean checkbox / confirmation. */
43
+ confirm(title, opts) {
44
+ return {
45
+ type: 'boolean',
46
+ title,
47
+ ...(opts?.description !== undefined && { description: opts.description }),
48
+ ...(opts?.default !== undefined && { default: opts.default }),
49
+ };
50
+ },
51
+ /** Numeric input. */
52
+ number(title, opts) {
53
+ return {
54
+ type: opts?.integer ? 'integer' : 'number',
55
+ title,
56
+ ...(opts?.description !== undefined && { description: opts.description }),
57
+ ...(opts?.minimum !== undefined && { minimum: opts.minimum }),
58
+ ...(opts?.maximum !== undefined && { maximum: opts.maximum }),
59
+ ...(opts?.default !== undefined && { default: opts.default }),
60
+ };
61
+ },
62
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @kb/elicitation — MCP elicitation primitives.
3
+ *
4
+ * Provides field builders, request construction, and response normalization
5
+ * for MCP elicitation (interactive user input during tool execution).
6
+ */
7
+ export type { ElicitAction, ElicitContent, ElicitFormSchema, ElicitOptions, ElicitResponse, Elicitor, FieldSchema, TextFieldSchema, EnumFieldSchema, ArrayFieldSchema, BooleanFieldSchema, NumberFieldSchema, } from './types.js';
8
+ export { field } from './fields.js';
9
+ export { buildFormSchema, buildElicitRequest } from './build.js';
10
+ export { normalizeResponse } from './normalize.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @kb/elicitation — MCP elicitation primitives.
3
+ *
4
+ * Provides field builders, request construction, and response normalization
5
+ * for MCP elicitation (interactive user input during tool execution).
6
+ */
7
+ // Field builders
8
+ export { field } from './fields.js';
9
+ // Request construction
10
+ export { buildFormSchema, buildElicitRequest } from './build.js';
11
+ // Response normalization
12
+ export { normalizeResponse } from './normalize.js';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Response normalization — convert raw MCP ElicitResult into typed ElicitResponse.
3
+ */
4
+ import type { ElicitContent, ElicitResponse } from './types.js';
5
+ /** Raw elicitation result from the MCP SDK. */
6
+ interface RawElicitResult {
7
+ action: string;
8
+ content?: Record<string, unknown>;
9
+ }
10
+ /**
11
+ * Normalize a raw MCP elicitation result into a typed response.
12
+ * Handles missing fields, unknown actions, and type coercion.
13
+ */
14
+ export declare function normalizeResponse<T extends ElicitContent = ElicitContent>(raw: RawElicitResult | undefined | null): ElicitResponse<T>;
15
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Response normalization — convert raw MCP ElicitResult into typed ElicitResponse.
3
+ */
4
+ const VALID_ACTIONS = new Set(['accept', 'decline', 'cancel']);
5
+ /**
6
+ * Normalize a raw MCP elicitation result into a typed response.
7
+ * Handles missing fields, unknown actions, and type coercion.
8
+ */
9
+ export function normalizeResponse(raw) {
10
+ if (!raw) {
11
+ return { action: 'cancel' };
12
+ }
13
+ const action = VALID_ACTIONS.has(raw.action)
14
+ ? raw.action
15
+ : 'cancel';
16
+ if (action !== 'accept' || !raw.content) {
17
+ return { action };
18
+ }
19
+ // Coerce content values to allowed types
20
+ const content = {};
21
+ for (const [key, value] of Object.entries(raw.content)) {
22
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
23
+ content[key] = value;
24
+ }
25
+ else if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {
26
+ content[key] = value;
27
+ }
28
+ // Skip unknown types silently — defensive normalization
29
+ }
30
+ return { action, content: content };
31
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * MCP elicitation types.
3
+ *
4
+ * Elicitation allows tools to request structured input from the user via
5
+ * the MCP client. The schema follows JSON Schema constraints:
6
+ * only flat primitives and string arrays are supported.
7
+ */
8
+ /** User action on the elicitation dialog. */
9
+ export type ElicitAction = 'accept' | 'decline' | 'cancel';
10
+ /** Flat content map — MCP only supports primitives + string arrays. */
11
+ export type ElicitContent = Record<string, string | number | boolean | string[]>;
12
+ /** Normalized elicitation response. */
13
+ export interface ElicitResponse<T extends ElicitContent = ElicitContent> {
14
+ action: ElicitAction;
15
+ content?: T;
16
+ }
17
+ export interface TextFieldSchema {
18
+ type: 'string';
19
+ title: string;
20
+ description?: string;
21
+ minLength?: number;
22
+ maxLength?: number;
23
+ default?: string;
24
+ }
25
+ export interface EnumFieldSchema {
26
+ type: 'string';
27
+ title: string;
28
+ description?: string;
29
+ enum: string[];
30
+ enumNames?: string[];
31
+ default?: string;
32
+ }
33
+ export interface ArrayFieldSchema {
34
+ type: 'array';
35
+ title: string;
36
+ description?: string;
37
+ items: {
38
+ type: 'string';
39
+ enum: string[];
40
+ };
41
+ uniqueItems: true;
42
+ }
43
+ export interface BooleanFieldSchema {
44
+ type: 'boolean';
45
+ title: string;
46
+ description?: string;
47
+ default?: boolean;
48
+ }
49
+ export interface NumberFieldSchema {
50
+ type: 'number' | 'integer';
51
+ title: string;
52
+ description?: string;
53
+ minimum?: number;
54
+ maximum?: number;
55
+ default?: number;
56
+ }
57
+ export type FieldSchema = TextFieldSchema | EnumFieldSchema | ArrayFieldSchema | BooleanFieldSchema | NumberFieldSchema;
58
+ /** JSON Schema object for the elicitation form. */
59
+ export interface ElicitFormSchema {
60
+ type: 'object';
61
+ properties: Record<string, FieldSchema>;
62
+ required?: string[];
63
+ }
64
+ export interface ElicitOptions {
65
+ message: string;
66
+ schema: ElicitFormSchema;
67
+ }
68
+ /**
69
+ * High-level elicitation interface exposed to tools.
70
+ * Wraps `server.createElicitation()` with convenience methods.
71
+ */
72
+ export interface Elicitor {
73
+ /** Whether the connected client supports elicitation. */
74
+ readonly available: boolean;
75
+ /** Ask a structured form question. */
76
+ ask<T extends ElicitContent = ElicitContent>(opts: ElicitOptions): Promise<ElicitResponse<T>>;
77
+ /** Yes/no confirmation. */
78
+ confirm(message: string): Promise<boolean>;
79
+ /** Pick one from a list. Returns null if declined/cancelled. */
80
+ selectOne(message: string, options: string[]): Promise<string | null>;
81
+ /** Pick many from a list. Returns empty array if declined/cancelled. */
82
+ selectMany(message: string, options: string[]): Promise<string[]>;
83
+ /** Free text prompt. Returns null if declined/cancelled. */
84
+ promptText(message: string, description?: string): Promise<string | null>;
85
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP elicitation types.
3
+ *
4
+ * Elicitation allows tools to request structured input from the user via
5
+ * the MCP client. The schema follows JSON Schema constraints:
6
+ * only flat primitives and string arrays are supported.
7
+ */
8
+ export {};
@@ -0,0 +1,37 @@
1
+ import { IKBClient, KBGraphData, KBKnowledgeEntry, KBSearchResult, KBStatus } from "./types.js";
2
+ import { IEmbedder } from "@kb/embeddings";
3
+ import { IGraphStore, IKnowledgeStore } from "@kb/store";
4
+
5
+ //#region packages/kb-client/src/direct-client.d.ts
6
+ interface CuratedEntry {
7
+ path: string;
8
+ title: string;
9
+ category: string;
10
+ tags: string[];
11
+ content: string;
12
+ }
13
+ interface DirectClientDeps {
14
+ store: IKnowledgeStore;
15
+ embedder: IEmbedder;
16
+ graphStore?: IGraphStore;
17
+ /** Function to list curated entries */
18
+ listCurated?: () => Promise<CuratedEntry[]>;
19
+ /** Function to read a single curated entry */
20
+ readCurated?: (path: string) => Promise<CuratedEntry | null>;
21
+ }
22
+ declare class DirectKBClient implements IKBClient {
23
+ private readonly deps;
24
+ constructor(deps: DirectClientDeps);
25
+ getStatus(): Promise<KBStatus>;
26
+ search(query: string, options?: {
27
+ limit?: number;
28
+ mode?: 'hybrid' | 'semantic' | 'keyword';
29
+ }): Promise<KBSearchResult[]>;
30
+ listKnowledge(): Promise<KBKnowledgeEntry[]>;
31
+ readKnowledge(path: string): Promise<KBKnowledgeEntry | null>;
32
+ getGraph(query?: string): Promise<KBGraphData>;
33
+ getFileTree(): Promise<string[]>;
34
+ private getEdgesForNodes;
35
+ }
36
+ //#endregion
37
+ export { DirectClientDeps, DirectKBClient };
@@ -0,0 +1 @@
1
+ const e=1e3;var t=class{constructor(e){this.deps=e}async getStatus(){let e=await this.deps.store.getStats();return{totalRecords:e.totalRecords,totalFiles:e.totalFiles,lastIndexedAt:e.lastIndexedAt??null,onboarded:e.totalRecords>0}}async search(e,t){let n=t?.limit??10,i=t?.mode??`hybrid`;if(i===`keyword`)return(await this.deps.store.ftsSearch(e,{limit:n})).map(r);let a=await this.deps.embedder.embedQuery(e);if(i===`semantic`)return(await this.deps.store.search(a,{limit:n})).map(r);let[o,s]=await Promise.all([this.deps.store.search(a,{limit:n*2}),this.deps.store.ftsSearch(e,{limit:n*2}).catch(()=>[])]),c=new Map;for(let e of[...o,...s]){let t=c.get(e.record.id);(!t||e.score>t.score)&&c.set(e.record.id,e)}return[...c.values()].sort((e,t)=>t.score-e.score).slice(0,n).map(r)}async listKnowledge(){return this.deps.listCurated?(await this.deps.listCurated()).map(n):[]}async readKnowledge(e){if(!this.deps.readCurated)return null;let t=await this.deps.readCurated(e);return t?n(t):null}async getGraph(t){if(!this.deps.graphStore)return{nodes:[],edges:[]};let n=await this.deps.graphStore.findNodes(t?{namePattern:t,limit:500}:{limit:500});if(n.length===0)return{nodes:[],edges:[]};let r=t?await this.getEdgesForNodes(n):await this.deps.graphStore.findEdges({limit:e});return{nodes:n.map(e=>({id:e.id,name:e.name,type:e.type,...e.sourcePath?{sourcePath:e.sourcePath}:{}})),edges:i(r).map(e=>({fromId:e.fromId,toId:e.toId,type:e.type}))}}async getFileTree(){return this.deps.store.listSourcePaths()}async getEdgesForNodes(t){let n=this.deps.graphStore;if(!n)return[];let r=t.flatMap(t=>[n.findEdges({fromId:t.id,limit:e}),n.findEdges({toId:t.id,limit:e})]);return(await Promise.all(r)).flat()}};function n(e){return{path:e.path,title:e.title,category:e.category,tags:e.tags,content:e.content}}function r(e){return{sourcePath:e.record.sourcePath,contentType:e.record.contentType,score:e.score,content:e.record.content,headingPath:e.record.headingPath,startLine:e.record.startLine,endLine:e.record.endLine}}function i(e){let t=new Map;for(let n of e)t.set(n.id,n);return[...t.values()]}export{t as DirectKBClient};
@@ -0,0 +1,5 @@
1
+ import { IKBClient, KBGraphData, KBKnowledgeEntry, KBSearchResult, KBStatus } from "./types.js";
2
+ import { DirectClientDeps, DirectKBClient } from "./direct-client.js";
3
+ import { McpKBClient } from "./mcp-client.js";
4
+ import { ParsedContent, extractStructured, extractText, parseToolResult, tryParseJson } from "./parsers.js";
5
+ export { type DirectClientDeps, DirectKBClient, type IKBClient, type KBGraphData, type KBKnowledgeEntry, type KBSearchResult, type KBStatus, McpKBClient, type ParsedContent, extractStructured, extractText, parseToolResult, tryParseJson };
@@ -0,0 +1 @@
1
+ import{DirectKBClient as e}from"./direct-client.js";import{extractStructured as t,extractText as n,parseToolResult as r,tryParseJson as i}from"./parsers.js";import{McpKBClient as a}from"./mcp-client.js";export{e as DirectKBClient,a as McpKBClient,t as extractStructured,n as extractText,r as parseToolResult,i as tryParseJson};
@@ -0,0 +1,19 @@
1
+ import { IKBClient, KBGraphData, KBKnowledgeEntry, KBSearchResult, KBStatus } from "./types.js";
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+
4
+ //#region packages/kb-client/src/mcp-client.d.ts
5
+ declare class McpKBClient implements IKBClient {
6
+ private readonly client;
7
+ constructor(client: Client);
8
+ getStatus(): Promise<KBStatus>;
9
+ search(query: string, options?: {
10
+ limit?: number;
11
+ mode?: 'hybrid' | 'semantic' | 'keyword';
12
+ }): Promise<KBSearchResult[]>;
13
+ listKnowledge(): Promise<KBKnowledgeEntry[]>;
14
+ readKnowledge(path: string): Promise<KBKnowledgeEntry | null>;
15
+ getGraph(query?: string): Promise<KBGraphData>;
16
+ getFileTree(): Promise<string[]>;
17
+ }
18
+ //#endregion
19
+ export { McpKBClient };
@@ -0,0 +1,4 @@
1
+ import{extractStructured as e,extractText as t}from"./parsers.js";var n=class{constructor(e){this.client=e}async getStatus(){let e=await this.client.callTool({name:`status`,arguments:{}}),t=i(e);if(t)return{totalRecords:l(t.totalRecords),totalFiles:l(t.totalFiles),lastIndexedAt:d(t.lastIndexedAt),onboarded:!!t.onboarded};let n=r(e);return{totalRecords:a(n,/Records:\s*(\d+)/i),totalFiles:a(n,/Files:\s*(\d+)/i),lastIndexedAt:null,onboarded:!/not onboarded/i.test(n)}}async search(e,t){let n=await this.client.callTool({name:`search`,arguments:{query:e,limit:t?.limit??10,search_mode:t?.mode??`hybrid`}}),a=i(n);return a?.results?a.results.map(e=>({sourcePath:f(e.sourcePath??e.path),contentType:f(e.contentType,`unknown`),score:l(e.score),content:f(e.content??e.snippet),headingPath:p(e.headingPath),startLine:u(e.startLine),endLine:u(e.endLine)})):o(r(n))}async listKnowledge(){let e=i(await this.client.callTool({name:`list`,arguments:{}}));return e?.entries?e.entries.map(e=>({path:f(e.path),title:f(e.title),category:f(e.category),tags:m(e.tags),content:f(e.content)})):[]}async readKnowledge(e){try{let t=r(await this.client.callTool({name:`read`,arguments:{path:e}}));return!t||/not found/i.test(t)?null:{path:e,title:e.split(`/`).pop()??e,category:e.split(`/`).at(-2)??`uncategorized`,tags:[],content:t}}catch{return null}}async getGraph(e){let t=s(r(await this.client.callTool({name:`graph`,arguments:{action:`find_nodes`,...e?{name_pattern:e}:{},limit:500}})));return t.length===0?{nodes:[],edges:[]}:{nodes:t,edges:c(r(await this.client.callTool({name:`graph`,arguments:{action:`find_edges`,limit:1e3}})))}}async getFileTree(){let e=await this.client.callTool({name:`find`,arguments:{glob:`**/*`,limit:1e4}}),t=i(e);return t?.results?t.results.map(e=>typeof e==`string`?e:e.path??``).filter(e=>e.length>0):r(e).split(`
2
+ `).map(e=>e.trim()).filter(e=>e.length>0)}};function r(e){return t(e)}function i(t){return e(t)}function a(e,t){let n=t.exec(e);return n?Number.parseInt(n[1],10):0}function o(e){let t=[],n=e.split(/\n(?=\d+\.\s|\*\*)/);for(let e of n){let n=/(?:\*\*|`)([^*`]+?)(?:\*\*|`)/.exec(e),r=/score:\s*([\d.]+)/i.exec(e);n&&t.push({sourcePath:n[1].trim(),contentType:`unknown`,score:r?Number.parseFloat(r[1]):0,content:e.replace(/^.*\n/,``).trim().slice(0,200)})}return t}function s(e){let t=[];for(let n of e.split(`
3
+ `)){let e=/\*\*(.+?)\*\*\s*\(([^,)]+)(?:,\s*id:\s*`?([\w-]+)`?)?/.exec(n);e&&t.push({id:e[3]??`node-${t.length}`,name:e[1],type:e[2]})}return t}function c(e){let t=[];for(let n of e.split(`
4
+ `)){let e=/`?([\w-]+)`?\s*[—-]+\[(\w+)\][→>]\s*`?([\w-]+)`?/.exec(n);e&&t.push({fromId:e[1],toId:e[3],type:e[2]})}return t}function l(e){return typeof e==`number`?e:0}function u(e){return typeof e==`number`?e:void 0}function d(e){return typeof e==`string`?e:null}function f(e,t=``){return typeof e==`string`?e:t}function p(e){return typeof e==`string`?e:void 0}function m(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}export{n as McpKBClient};