codedev-mcp 3.2.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 (229) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -0
  4. package/dist/analyzers/api-contract.d.ts +46 -0
  5. package/dist/analyzers/api-contract.d.ts.map +1 -0
  6. package/dist/analyzers/api-contract.js +319 -0
  7. package/dist/analyzers/api-contract.js.map +1 -0
  8. package/dist/analyzers/architecture.d.ts +37 -0
  9. package/dist/analyzers/architecture.d.ts.map +1 -0
  10. package/dist/analyzers/architecture.js +149 -0
  11. package/dist/analyzers/architecture.js.map +1 -0
  12. package/dist/analyzers/branch-compare.d.ts +46 -0
  13. package/dist/analyzers/branch-compare.d.ts.map +1 -0
  14. package/dist/analyzers/branch-compare.js +128 -0
  15. package/dist/analyzers/branch-compare.js.map +1 -0
  16. package/dist/analyzers/cicd.d.ts +42 -0
  17. package/dist/analyzers/cicd.d.ts.map +1 -0
  18. package/dist/analyzers/cicd.js +237 -0
  19. package/dist/analyzers/cicd.js.map +1 -0
  20. package/dist/analyzers/codebase.d.ts +64 -0
  21. package/dist/analyzers/codebase.d.ts.map +1 -0
  22. package/dist/analyzers/codebase.js +354 -0
  23. package/dist/analyzers/codebase.js.map +1 -0
  24. package/dist/analyzers/complexity-heatmap.d.ts +50 -0
  25. package/dist/analyzers/complexity-heatmap.d.ts.map +1 -0
  26. package/dist/analyzers/complexity-heatmap.js +156 -0
  27. package/dist/analyzers/complexity-heatmap.js.map +1 -0
  28. package/dist/analyzers/context-pack.d.ts +43 -0
  29. package/dist/analyzers/context-pack.d.ts.map +1 -0
  30. package/dist/analyzers/context-pack.js +232 -0
  31. package/dist/analyzers/context-pack.js.map +1 -0
  32. package/dist/analyzers/coverage.d.ts +70 -0
  33. package/dist/analyzers/coverage.d.ts.map +1 -0
  34. package/dist/analyzers/coverage.js +313 -0
  35. package/dist/analyzers/coverage.js.map +1 -0
  36. package/dist/analyzers/db-schema.d.ts +55 -0
  37. package/dist/analyzers/db-schema.d.ts.map +1 -0
  38. package/dist/analyzers/db-schema.js +237 -0
  39. package/dist/analyzers/db-schema.js.map +1 -0
  40. package/dist/analyzers/dead-code.d.ts +34 -0
  41. package/dist/analyzers/dead-code.d.ts.map +1 -0
  42. package/dist/analyzers/dead-code.js +131 -0
  43. package/dist/analyzers/dead-code.js.map +1 -0
  44. package/dist/analyzers/dep-vuln.d.ts +36 -0
  45. package/dist/analyzers/dep-vuln.d.ts.map +1 -0
  46. package/dist/analyzers/dep-vuln.js +342 -0
  47. package/dist/analyzers/dep-vuln.js.map +1 -0
  48. package/dist/analyzers/docs.d.ts +47 -0
  49. package/dist/analyzers/docs.d.ts.map +1 -0
  50. package/dist/analyzers/docs.js +473 -0
  51. package/dist/analyzers/docs.js.map +1 -0
  52. package/dist/analyzers/git.d.ts +115 -0
  53. package/dist/analyzers/git.d.ts.map +1 -0
  54. package/dist/analyzers/git.js +214 -0
  55. package/dist/analyzers/git.js.map +1 -0
  56. package/dist/analyzers/iac.d.ts +39 -0
  57. package/dist/analyzers/iac.d.ts.map +1 -0
  58. package/dist/analyzers/iac.js +233 -0
  59. package/dist/analyzers/iac.js.map +1 -0
  60. package/dist/analyzers/impact.d.ts +51 -0
  61. package/dist/analyzers/impact.d.ts.map +1 -0
  62. package/dist/analyzers/impact.js +235 -0
  63. package/dist/analyzers/impact.js.map +1 -0
  64. package/dist/analyzers/monorepo.d.ts +36 -0
  65. package/dist/analyzers/monorepo.d.ts.map +1 -0
  66. package/dist/analyzers/monorepo.js +233 -0
  67. package/dist/analyzers/monorepo.js.map +1 -0
  68. package/dist/analyzers/notebook.d.ts +53 -0
  69. package/dist/analyzers/notebook.d.ts.map +1 -0
  70. package/dist/analyzers/notebook.js +149 -0
  71. package/dist/analyzers/notebook.js.map +1 -0
  72. package/dist/analyzers/perf-profile.d.ts +39 -0
  73. package/dist/analyzers/perf-profile.d.ts.map +1 -0
  74. package/dist/analyzers/perf-profile.js +222 -0
  75. package/dist/analyzers/perf-profile.js.map +1 -0
  76. package/dist/analyzers/scaffold.d.ts +46 -0
  77. package/dist/analyzers/scaffold.d.ts.map +1 -0
  78. package/dist/analyzers/scaffold.js +313 -0
  79. package/dist/analyzers/scaffold.js.map +1 -0
  80. package/dist/analyzers/security.d.ts +42 -0
  81. package/dist/analyzers/security.d.ts.map +1 -0
  82. package/dist/analyzers/security.js +281 -0
  83. package/dist/analyzers/security.js.map +1 -0
  84. package/dist/analyzers/symbols.d.ts +49 -0
  85. package/dist/analyzers/symbols.d.ts.map +1 -0
  86. package/dist/analyzers/symbols.js +212 -0
  87. package/dist/analyzers/symbols.js.map +1 -0
  88. package/dist/analyzers/tree-sitter.d.ts +71 -0
  89. package/dist/analyzers/tree-sitter.d.ts.map +1 -0
  90. package/dist/analyzers/tree-sitter.js +333 -0
  91. package/dist/analyzers/tree-sitter.js.map +1 -0
  92. package/dist/analyzers/type-flow.d.ts +39 -0
  93. package/dist/analyzers/type-flow.d.ts.map +1 -0
  94. package/dist/analyzers/type-flow.js +75 -0
  95. package/dist/analyzers/type-flow.js.map +1 -0
  96. package/dist/cache/memory-cache.d.ts +130 -0
  97. package/dist/cache/memory-cache.d.ts.map +1 -0
  98. package/dist/cache/memory-cache.js +273 -0
  99. package/dist/cache/memory-cache.js.map +1 -0
  100. package/dist/config.d.ts +32 -0
  101. package/dist/config.d.ts.map +1 -0
  102. package/dist/config.js +57 -0
  103. package/dist/config.js.map +1 -0
  104. package/dist/constants/instructions.d.ts +2 -0
  105. package/dist/constants/instructions.d.ts.map +1 -0
  106. package/dist/constants/instructions.js +82 -0
  107. package/dist/constants/instructions.js.map +1 -0
  108. package/dist/db/connection.d.ts +12 -0
  109. package/dist/db/connection.d.ts.map +1 -0
  110. package/dist/db/connection.js +34 -0
  111. package/dist/db/connection.js.map +1 -0
  112. package/dist/db/json-store.d.ts +111 -0
  113. package/dist/db/json-store.d.ts.map +1 -0
  114. package/dist/db/json-store.js +201 -0
  115. package/dist/db/json-store.js.map +1 -0
  116. package/dist/db/sqlite-store.d.ts +153 -0
  117. package/dist/db/sqlite-store.d.ts.map +1 -0
  118. package/dist/db/sqlite-store.js +388 -0
  119. package/dist/db/sqlite-store.js.map +1 -0
  120. package/dist/index.d.ts +17 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +116 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/resources/health.d.ts +35 -0
  125. package/dist/resources/health.d.ts.map +1 -0
  126. package/dist/resources/health.js +81 -0
  127. package/dist/resources/health.js.map +1 -0
  128. package/dist/schemas/output-schemas.d.ts +517 -0
  129. package/dist/schemas/output-schemas.d.ts.map +1 -0
  130. package/dist/schemas/output-schemas.js +296 -0
  131. package/dist/schemas/output-schemas.js.map +1 -0
  132. package/dist/search/fast-search.d.ts +90 -0
  133. package/dist/search/fast-search.d.ts.map +1 -0
  134. package/dist/search/fast-search.js +387 -0
  135. package/dist/search/fast-search.js.map +1 -0
  136. package/dist/search/semantic.d.ts +26 -0
  137. package/dist/search/semantic.d.ts.map +1 -0
  138. package/dist/search/semantic.js +458 -0
  139. package/dist/search/semantic.js.map +1 -0
  140. package/dist/tools/analysis.d.ts +7 -0
  141. package/dist/tools/analysis.d.ts.map +1 -0
  142. package/dist/tools/analysis.js +491 -0
  143. package/dist/tools/analysis.js.map +1 -0
  144. package/dist/tools/architecture.d.ts +7 -0
  145. package/dist/tools/architecture.d.ts.map +1 -0
  146. package/dist/tools/architecture.js +176 -0
  147. package/dist/tools/architecture.js.map +1 -0
  148. package/dist/tools/devops.d.ts +7 -0
  149. package/dist/tools/devops.d.ts.map +1 -0
  150. package/dist/tools/devops.js +179 -0
  151. package/dist/tools/devops.js.map +1 -0
  152. package/dist/tools/docs.d.ts +7 -0
  153. package/dist/tools/docs.d.ts.map +1 -0
  154. package/dist/tools/docs.js +102 -0
  155. package/dist/tools/docs.js.map +1 -0
  156. package/dist/tools/git.d.ts +7 -0
  157. package/dist/tools/git.d.ts.map +1 -0
  158. package/dist/tools/git.js +475 -0
  159. package/dist/tools/git.js.map +1 -0
  160. package/dist/tools/nav.d.ts +7 -0
  161. package/dist/tools/nav.d.ts.map +1 -0
  162. package/dist/tools/nav.js +275 -0
  163. package/dist/tools/nav.js.map +1 -0
  164. package/dist/tools/notebook.d.ts +7 -0
  165. package/dist/tools/notebook.d.ts.map +1 -0
  166. package/dist/tools/notebook.js +102 -0
  167. package/dist/tools/notebook.js.map +1 -0
  168. package/dist/tools/performance.d.ts +7 -0
  169. package/dist/tools/performance.d.ts.map +1 -0
  170. package/dist/tools/performance.js +59 -0
  171. package/dist/tools/performance.js.map +1 -0
  172. package/dist/tools/quality.d.ts +7 -0
  173. package/dist/tools/quality.d.ts.map +1 -0
  174. package/dist/tools/quality.js +279 -0
  175. package/dist/tools/quality.js.map +1 -0
  176. package/dist/tools/scaffold.d.ts +7 -0
  177. package/dist/tools/scaffold.d.ts.map +1 -0
  178. package/dist/tools/scaffold.js +80 -0
  179. package/dist/tools/scaffold.js.map +1 -0
  180. package/dist/tools/search.d.ts +7 -0
  181. package/dist/tools/search.d.ts.map +1 -0
  182. package/dist/tools/search.js +308 -0
  183. package/dist/tools/search.js.map +1 -0
  184. package/dist/tools/security.d.ts +7 -0
  185. package/dist/tools/security.d.ts.map +1 -0
  186. package/dist/tools/security.js +138 -0
  187. package/dist/tools/security.js.map +1 -0
  188. package/dist/utils/analytics.d.ts +69 -0
  189. package/dist/utils/analytics.d.ts.map +1 -0
  190. package/dist/utils/analytics.js +144 -0
  191. package/dist/utils/analytics.js.map +1 -0
  192. package/dist/utils/concurrency.d.ts +43 -0
  193. package/dist/utils/concurrency.d.ts.map +1 -0
  194. package/dist/utils/concurrency.js +78 -0
  195. package/dist/utils/concurrency.js.map +1 -0
  196. package/dist/utils/fallback.d.ts +52 -0
  197. package/dist/utils/fallback.d.ts.map +1 -0
  198. package/dist/utils/fallback.js +137 -0
  199. package/dist/utils/fallback.js.map +1 -0
  200. package/dist/utils/git-hooks.d.ts +24 -0
  201. package/dist/utils/git-hooks.d.ts.map +1 -0
  202. package/dist/utils/git-hooks.js +108 -0
  203. package/dist/utils/git-hooks.js.map +1 -0
  204. package/dist/utils/languages.d.ts +72 -0
  205. package/dist/utils/languages.d.ts.map +1 -0
  206. package/dist/utils/languages.js +463 -0
  207. package/dist/utils/languages.js.map +1 -0
  208. package/dist/utils/logger.d.ts +13 -0
  209. package/dist/utils/logger.d.ts.map +1 -0
  210. package/dist/utils/logger.js +34 -0
  211. package/dist/utils/logger.js.map +1 -0
  212. package/dist/utils/plugins.d.ts +105 -0
  213. package/dist/utils/plugins.d.ts.map +1 -0
  214. package/dist/utils/plugins.js +325 -0
  215. package/dist/utils/plugins.js.map +1 -0
  216. package/dist/utils/security.d.ts +17 -0
  217. package/dist/utils/security.d.ts.map +1 -0
  218. package/dist/utils/security.js +48 -0
  219. package/dist/utils/security.js.map +1 -0
  220. package/dist/utils/streaming.d.ts +56 -0
  221. package/dist/utils/streaming.d.ts.map +1 -0
  222. package/dist/utils/streaming.js +95 -0
  223. package/dist/utils/streaming.js.map +1 -0
  224. package/dist/version.d.ts +3 -0
  225. package/dist/version.d.ts.map +1 -0
  226. package/dist/version.js +3 -0
  227. package/dist/version.js.map +1 -0
  228. package/mcp.json +100 -0
  229. package/package.json +89 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Plugin architecture for codedev-mcp.
3
+ * Users extend the server with custom analyzers without forking.
4
+ *
5
+ * Plugin locations (in priority order):
6
+ * 1. ./.codedev-mcp/plugins/ (project-local)
7
+ * 2. ~/.codedev-mcp/plugins/ (user-global)
8
+ * 3. npm packages: codedev-plugin-* (marketplace)
9
+ *
10
+ * Plugin format:
11
+ * Each plugin is a directory with a plugin.json manifest and an index.js entry point.
12
+ * npm marketplace plugins follow the same format but are installed via npm.
13
+ */
14
+ export interface PluginManifest {
15
+ name: string;
16
+ version: string;
17
+ description: string;
18
+ author?: string;
19
+ tools?: PluginToolDef[];
20
+ patterns?: PluginPatternDef[];
21
+ languages?: PluginLanguageDef[];
22
+ }
23
+ export interface PluginToolDef {
24
+ name: string;
25
+ description: string;
26
+ inputSchema: Record<string, unknown>;
27
+ }
28
+ export interface PluginPatternDef {
29
+ name: string;
30
+ pattern: string;
31
+ severity: string;
32
+ description: string;
33
+ recommendation: string;
34
+ }
35
+ export interface PluginLanguageDef {
36
+ name: string;
37
+ extensions: string[];
38
+ commentSingle?: string;
39
+ commentMultiStart?: string;
40
+ commentMultiEnd?: string;
41
+ functionPatterns?: string[];
42
+ classPatterns?: string[];
43
+ }
44
+ export interface PluginModule {
45
+ tools?: Record<string, (params: Record<string, unknown>, context: {
46
+ cwd: string;
47
+ }) => Promise<string>>;
48
+ }
49
+ export interface LoadedPlugin {
50
+ manifest: PluginManifest;
51
+ pluginPath: string;
52
+ module?: PluginModule;
53
+ }
54
+ /**
55
+ * Discover and load plugins from standard locations + npm marketplace.
56
+ * @param cwd - The working directory to search for plugins.
57
+ * @returns An array of loaded plugins.
58
+ */
59
+ export declare function loadPlugins(cwd: string): Promise<LoadedPlugin[]>;
60
+ /**
61
+ * Get all custom patterns from loaded plugins.
62
+ * @param plugins - The loaded plugins.
63
+ * @returns An array of pattern definitions from all plugins.
64
+ */
65
+ export declare function getPluginPatterns(plugins: LoadedPlugin[]): PluginPatternDef[];
66
+ /**
67
+ * Get all custom language definitions from plugins.
68
+ * @param plugins - The loaded plugins.
69
+ * @returns An array of language definitions from all plugins.
70
+ */
71
+ export declare function getPluginLanguages(plugins: LoadedPlugin[]): PluginLanguageDef[];
72
+ /**
73
+ * Get all custom tool definitions from plugins.
74
+ * @param plugins - The loaded plugins.
75
+ * @returns An array of tool definitions with their plugin names.
76
+ */
77
+ export declare function getPluginTools(plugins: LoadedPlugin[]): {
78
+ plugin: string;
79
+ tool: PluginToolDef;
80
+ }[];
81
+ /**
82
+ * Execute a plugin tool handler.
83
+ * @param plugin - The loaded plugin to execute.
84
+ * @param toolName - The tool name to invoke.
85
+ * @param params - Parameters to pass to the tool.
86
+ * @param context - Execution context.
87
+ * @param context.cwd - The current working directory.
88
+ * @returns The string result from the tool handler.
89
+ */
90
+ export declare function executePluginTool(plugin: LoadedPlugin, toolName: string, params: Record<string, unknown>, context: {
91
+ cwd: string;
92
+ }): Promise<string>;
93
+ /**
94
+ * Generate a plugin scaffold for users.
95
+ * Produces both plugin.json (native) and package.json (npm marketplace) formats.
96
+ * @param name - The plugin name.
97
+ * @returns An object containing manifest, packageJson, indexJs, and readme strings.
98
+ */
99
+ export declare function generatePluginScaffold(name: string): {
100
+ manifest: string;
101
+ packageJson: string;
102
+ indexJs: string;
103
+ readme: string;
104
+ };
105
+ //# sourceMappingURL=plugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/utils/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;CACxG;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAwDtE;AAqHD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,gBAAgB,EAAE,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,iBAAiB,EAAE,CAE/E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,EAAE,CAEjG;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GACvB,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CA0GA"}
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Plugin architecture for codedev-mcp.
3
+ * Users extend the server with custom analyzers without forking.
4
+ *
5
+ * Plugin locations (in priority order):
6
+ * 1. ./.codedev-mcp/plugins/ (project-local)
7
+ * 2. ~/.codedev-mcp/plugins/ (user-global)
8
+ * 3. npm packages: codedev-plugin-* (marketplace)
9
+ *
10
+ * Plugin format:
11
+ * Each plugin is a directory with a plugin.json manifest and an index.js entry point.
12
+ * npm marketplace plugins follow the same format but are installed via npm.
13
+ */
14
+ import { readFile, readdir, access } from 'node:fs/promises';
15
+ import path from 'node:path';
16
+ import { logger } from './logger.js';
17
+ /**
18
+ * Discover and load plugins from standard locations + npm marketplace.
19
+ * @param cwd - The working directory to search for plugins.
20
+ * @returns An array of loaded plugins.
21
+ */
22
+ export async function loadPlugins(cwd) {
23
+ const plugins = [];
24
+ // 1. Local and global plugin directories
25
+ const pluginDirs = [
26
+ path.join(cwd, '.codedev-mcp', 'plugins'),
27
+ path.join(process.env.HOME || '', '.codedev-mcp', 'plugins'),
28
+ ];
29
+ for (const dir of pluginDirs) {
30
+ try {
31
+ await access(dir);
32
+ const entries = await readdir(dir, { withFileTypes: true });
33
+ for (const entry of entries) {
34
+ if (!entry.isDirectory())
35
+ continue;
36
+ const pluginPath = path.join(dir, entry.name);
37
+ const manifestPath = path.join(pluginPath, 'plugin.json');
38
+ try {
39
+ const manifestContent = await readFile(manifestPath, 'utf-8');
40
+ const manifest = JSON.parse(manifestContent);
41
+ // Validate manifest
42
+ if (!manifest.name || !manifest.version) {
43
+ logger.error(`Plugin ${entry.name}: Invalid manifest (missing name or version)`);
44
+ continue;
45
+ }
46
+ // Try loading the module
47
+ let module;
48
+ const entryPoint = path.join(pluginPath, 'index.js');
49
+ try {
50
+ await access(entryPoint);
51
+ const importedModule = await import(entryPoint);
52
+ module = importedModule;
53
+ }
54
+ catch {
55
+ // Plugin might not have code (pattern-only or language-only plugins)
56
+ }
57
+ plugins.push({ manifest, pluginPath, module });
58
+ }
59
+ catch {
60
+ // Skip directories without valid plugin.json
61
+ }
62
+ }
63
+ }
64
+ catch {
65
+ // Plugin directory doesn't exist
66
+ }
67
+ }
68
+ // 2. npm marketplace: auto-discover codedev-plugin-* packages
69
+ const npmPlugins = await discoverNpmPlugins(cwd);
70
+ plugins.push(...npmPlugins);
71
+ return plugins;
72
+ }
73
+ /**
74
+ * Discover npm packages matching the `codedev-plugin-*` naming convention.
75
+ * Searches node_modules in the project and globally.
76
+ * @param cwd - The working directory.
77
+ * @returns An array of loaded npm plugins.
78
+ */
79
+ async function discoverNpmPlugins(cwd) {
80
+ const plugins = [];
81
+ const PREFIX = 'codedev-plugin-';
82
+ const searchDirs = [
83
+ path.join(cwd, 'node_modules'),
84
+ path.join(process.env.HOME || '', '.codedev-mcp', 'node_modules'),
85
+ ];
86
+ // Also check global node_modules
87
+ const globalPrefix = process.env.npm_config_prefix || '/usr/local';
88
+ searchDirs.push(path.join(globalPrefix, 'lib', 'node_modules'));
89
+ for (const nodeModulesDir of searchDirs) {
90
+ try {
91
+ await access(nodeModulesDir);
92
+ const entries = await readdir(nodeModulesDir, { withFileTypes: true });
93
+ for (const entry of entries) {
94
+ // Match codedev-plugin-* or @scope/codedev-plugin-*
95
+ if (entry.isDirectory() && entry.name.startsWith(PREFIX)) {
96
+ const plugin = await loadNpmPlugin(path.join(nodeModulesDir, entry.name));
97
+ if (plugin)
98
+ plugins.push(plugin);
99
+ }
100
+ // Check scoped packages (@scope/codedev-plugin-*)
101
+ if (entry.isDirectory() && entry.name.startsWith('@')) {
102
+ try {
103
+ const scopedEntries = await readdir(path.join(nodeModulesDir, entry.name), { withFileTypes: true });
104
+ for (const scopedEntry of scopedEntries) {
105
+ if (scopedEntry.isDirectory() && scopedEntry.name.startsWith(PREFIX)) {
106
+ const plugin = await loadNpmPlugin(path.join(nodeModulesDir, entry.name, scopedEntry.name));
107
+ if (plugin)
108
+ plugins.push(plugin);
109
+ }
110
+ }
111
+ }
112
+ catch {
113
+ /* skip */
114
+ }
115
+ }
116
+ }
117
+ }
118
+ catch {
119
+ /* node_modules doesn't exist */
120
+ }
121
+ }
122
+ return plugins;
123
+ }
124
+ /**
125
+ * Load a single npm marketplace plugin from its package directory.
126
+ * @param pkgDir - The package directory path.
127
+ * @returns The loaded plugin or null if loading failed.
128
+ */
129
+ async function loadNpmPlugin(pkgDir) {
130
+ try {
131
+ // Try plugin.json first (codedev-mcp native format)
132
+ const manifestPath = path.join(pkgDir, 'plugin.json');
133
+ let manifest;
134
+ try {
135
+ const content = await readFile(manifestPath, 'utf-8');
136
+ manifest = JSON.parse(content);
137
+ }
138
+ catch {
139
+ // Fallback: read package.json and extract codedev config
140
+ const pkgJsonPath = path.join(pkgDir, 'package.json');
141
+ const pkgContent = await readFile(pkgJsonPath, 'utf-8');
142
+ const pkgJson = JSON.parse(pkgContent);
143
+ // Plugin must have a "codedev" key in package.json
144
+ const codedevConfig = pkgJson.codedev;
145
+ if (!codedevConfig)
146
+ return null;
147
+ manifest = {
148
+ name: pkgJson.name,
149
+ version: pkgJson.version,
150
+ description: pkgJson.description || '',
151
+ author: pkgJson.author,
152
+ tools: codedevConfig.tools,
153
+ patterns: codedevConfig.patterns,
154
+ languages: codedevConfig.languages,
155
+ };
156
+ }
157
+ if (!manifest.name || !manifest.version)
158
+ return null;
159
+ // Try loading the module
160
+ let module;
161
+ try {
162
+ const entryPoint = path.join(pkgDir, 'index.js');
163
+ await access(entryPoint);
164
+ module = (await import(entryPoint));
165
+ }
166
+ catch {
167
+ // Try package.json main field
168
+ try {
169
+ const pkgContent = await readFile(path.join(pkgDir, 'package.json'), 'utf-8');
170
+ const pkgJson = JSON.parse(pkgContent);
171
+ if (pkgJson.main) {
172
+ module = (await import(path.join(pkgDir, pkgJson.main)));
173
+ }
174
+ }
175
+ catch {
176
+ /* no module */
177
+ }
178
+ }
179
+ return { manifest, pluginPath: pkgDir, module };
180
+ }
181
+ catch {
182
+ return null;
183
+ }
184
+ }
185
+ /**
186
+ * Get all custom patterns from loaded plugins.
187
+ * @param plugins - The loaded plugins.
188
+ * @returns An array of pattern definitions from all plugins.
189
+ */
190
+ export function getPluginPatterns(plugins) {
191
+ return plugins.flatMap((p) => p.manifest.patterns || []);
192
+ }
193
+ /**
194
+ * Get all custom language definitions from plugins.
195
+ * @param plugins - The loaded plugins.
196
+ * @returns An array of language definitions from all plugins.
197
+ */
198
+ export function getPluginLanguages(plugins) {
199
+ return plugins.flatMap((p) => p.manifest.languages || []);
200
+ }
201
+ /**
202
+ * Get all custom tool definitions from plugins.
203
+ * @param plugins - The loaded plugins.
204
+ * @returns An array of tool definitions with their plugin names.
205
+ */
206
+ export function getPluginTools(plugins) {
207
+ return plugins.flatMap((p) => (p.manifest.tools || []).map((t) => ({ plugin: p.manifest.name, tool: t })));
208
+ }
209
+ /**
210
+ * Execute a plugin tool handler.
211
+ * @param plugin - The loaded plugin to execute.
212
+ * @param toolName - The tool name to invoke.
213
+ * @param params - Parameters to pass to the tool.
214
+ * @param context - Execution context.
215
+ * @param context.cwd - The current working directory.
216
+ * @returns The string result from the tool handler.
217
+ */
218
+ export async function executePluginTool(plugin, toolName, params, context) {
219
+ if (!plugin.module?.tools?.[toolName]) {
220
+ throw new Error(`Tool "${toolName}" not found in plugin "${plugin.manifest.name}"`);
221
+ }
222
+ return plugin.module.tools[toolName](params, context);
223
+ }
224
+ /**
225
+ * Generate a plugin scaffold for users.
226
+ * Produces both plugin.json (native) and package.json (npm marketplace) formats.
227
+ * @param name - The plugin name.
228
+ * @returns An object containing manifest, packageJson, indexJs, and readme strings.
229
+ */
230
+ export function generatePluginScaffold(name) {
231
+ const manifest = JSON.stringify({
232
+ name,
233
+ version: '1.0.0',
234
+ description: `Custom codedev-mcp plugin: ${name}`,
235
+ tools: [
236
+ {
237
+ name: `${name}_analyze`,
238
+ description: `Run ${name} analysis`,
239
+ inputSchema: {
240
+ type: 'object',
241
+ properties: {
242
+ path: { type: 'string', description: 'File or directory to analyze' },
243
+ },
244
+ },
245
+ },
246
+ ],
247
+ patterns: [
248
+ {
249
+ name: `${name}_check`,
250
+ pattern: 'TODO',
251
+ severity: 'info',
252
+ description: `Custom ${name} pattern check`,
253
+ recommendation: 'Review and address this pattern.',
254
+ },
255
+ ],
256
+ }, null, 2);
257
+ const packageJson = JSON.stringify({
258
+ name: `codedev-plugin-${name}`,
259
+ version: '1.0.0',
260
+ description: `codedev-mcp marketplace plugin: ${name}`,
261
+ main: 'index.js',
262
+ keywords: ['codedev-mcp', 'mcp', 'code-analysis', 'plugin'],
263
+ codedev: {
264
+ tools: [
265
+ {
266
+ name: `${name}_analyze`,
267
+ description: `Run ${name} analysis`,
268
+ inputSchema: { type: 'object', properties: { path: { type: 'string' } } },
269
+ },
270
+ ],
271
+ patterns: [
272
+ {
273
+ name: `${name}_check`,
274
+ pattern: 'TODO',
275
+ severity: 'info',
276
+ description: `Custom ${name} pattern check`,
277
+ recommendation: 'Review and address this pattern.',
278
+ },
279
+ ],
280
+ },
281
+ }, null, 2);
282
+ const indexJs = `
283
+ // ${name} plugin for codedev-mcp
284
+ // Exports tool handlers that the server will call
285
+
286
+ export const tools = {
287
+ async ${name}_analyze(params, context) {
288
+ const { cwd } = context;
289
+ const targetPath = params.path || cwd;
290
+
291
+ // Your custom analysis logic here
292
+ return \`${name} analysis complete for \${targetPath}\`;
293
+ },
294
+ };
295
+ `.trim();
296
+ const readme = `# codedev-plugin-${name}
297
+
298
+ Custom plugin for codedev-mcp.
299
+
300
+ ## Installation
301
+
302
+ ### npm marketplace (recommended)
303
+ \`\`\`bash
304
+ npm install -g codedev-plugin-${name}
305
+ \`\`\`
306
+
307
+ ### Manual
308
+ 1. Copy this folder to \`~/.codedev-mcp/plugins/${name}/\`
309
+ 2. Restart codedev-mcp
310
+
311
+ ## Tools
312
+ - \`${name}_analyze\`: Run custom analysis
313
+
314
+ ## Patterns
315
+ - \`${name}_check\`: Custom pattern detection
316
+
317
+ ## Publishing
318
+ \`\`\`bash
319
+ npm publish
320
+ \`\`\`
321
+ The \`codedev-plugin-\` prefix is automatically discovered by codedev-mcp.
322
+ `;
323
+ return { manifest, packageJson, indexJs, readme };
324
+ }
325
+ //# sourceMappingURL=plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/utils/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA8CrC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,yCAAyC;IACzC,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,cAAc,EAAE,SAAS,CAAC;KAC7D,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAE5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAAE,SAAS;gBAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;gBAE1D,IAAI,CAAC;oBACH,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;oBAC9D,MAAM,QAAQ,GAAmB,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;oBAE7D,oBAAoB;oBACpB,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;wBACxC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,IAAI,8CAA8C,CAAC,CAAC;wBACjF,SAAS;oBACX,CAAC;oBAED,yBAAyB;oBACzB,IAAI,MAAgC,CAAC;oBACrC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;oBACrD,IAAI,CAAC;wBACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;wBACzB,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;wBAChD,MAAM,GAAG,cAA8B,CAAC;oBAC1C,CAAC;oBAAC,MAAM,CAAC;wBACP,qEAAqE;oBACvE,CAAC;oBAED,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACP,6CAA6C;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;IAE5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAC3C,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,iBAAiB,CAAC;IAEjC,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,cAAc,EAAE,cAAc,CAAC;KAClE,CAAC;IAEF,iCAAiC;IACjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,YAAY,CAAC;IACnE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAEhE,KAAK,MAAM,cAAc,IAAI,UAAU,EAAE,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAEvE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,oDAAoD;gBACpD,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBACzD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC1E,IAAI,MAAM;wBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;gBACD,kDAAkD;gBAClD,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACtD,IAAI,CAAC;wBACH,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;wBACpG,KAAK,MAAM,WAAW,IAAI,aAAa,EAAE,CAAC;4BACxC,IAAI,WAAW,CAAC,WAAW,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gCACrE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;gCAC5F,IAAI,MAAM;oCAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;4BACnC,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,UAAU;oBACZ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAC,MAAc;IACzC,IAAI,CAAC;QACH,oDAAoD;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,QAAwB,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACtD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;YACzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACtD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAA4B,CAAC;YAElE,mDAAmD;YACnD,MAAM,aAAa,GAAG,OAAO,CAAC,OAA8C,CAAC;YAC7E,IAAI,CAAC,aAAa;gBAAE,OAAO,IAAI,CAAC;YAEhC,QAAQ,GAAG;gBACT,IAAI,EAAE,OAAO,CAAC,IAAc;gBAC5B,OAAO,EAAE,OAAO,CAAC,OAAiB;gBAClC,WAAW,EAAG,OAAO,CAAC,WAAsB,IAAI,EAAE;gBAClD,MAAM,EAAE,OAAO,CAAC,MAA4B;gBAC5C,KAAK,EAAE,aAAa,CAAC,KAAoC;gBACzD,QAAQ,EAAE,aAAa,CAAC,QAA0C;gBAClE,SAAS,EAAE,aAAa,CAAC,SAA4C;aACtE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAErD,yBAAyB;QACzB,IAAI,MAAgC,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACjD,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;YACzB,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,CAAiB,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;YAC9B,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;gBAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAA4B,CAAC;gBAClE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;oBACjB,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAc,CAAC,CAAC,CAAiB,CAAC;gBACrF,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAuB;IACvD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAuB;IACxD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7G,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAoB,EACpB,QAAgB,EAChB,MAA+B,EAC/B,OAAwB;IAExB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,SAAS,QAAQ,0BAA0B,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IAMjD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAC7B;QACE,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,8BAA8B,IAAI,EAAE;QACjD,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,GAAG,IAAI,UAAU;gBACvB,WAAW,EAAE,OAAO,IAAI,WAAW;gBACnC,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;qBACtE;iBACF;aACF;SACF;QACD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,GAAG,IAAI,QAAQ;gBACrB,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,MAAM;gBAChB,WAAW,EAAE,UAAU,IAAI,gBAAgB;gBAC3C,cAAc,EAAE,kCAAkC;aACnD;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAChC;QACE,IAAI,EAAE,kBAAkB,IAAI,EAAE;QAC9B,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,mCAAmC,IAAI,EAAE;QACtD,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,CAAC;QAC3D,OAAO,EAAE;YACP,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,GAAG,IAAI,UAAU;oBACvB,WAAW,EAAE,OAAO,IAAI,WAAW;oBACnC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;iBAC1E;aACF;YACD,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,GAAG,IAAI,QAAQ;oBACrB,OAAO,EAAE,MAAM;oBACf,QAAQ,EAAE,MAAM;oBAChB,WAAW,EAAE,UAAU,IAAI,gBAAgB;oBAC3C,cAAc,EAAE,kCAAkC;iBACnD;aACF;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IAEF,MAAM,OAAO,GAAG;KACb,IAAI;;;;UAIC,IAAI;;;;;eAKC,IAAI;;;CAGlB,CAAC,IAAI,EAAE,CAAC;IAEP,MAAM,MAAM,GAAG,oBAAoB,IAAI;;;;;;;;gCAQT,IAAI;;;;kDAIc,IAAI;;;;MAIhD,IAAI;;;MAGJ,IAAI;;;;;;;CAOT,CAAC;IAEA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Validate that a path is safe to access within permissible roots.
3
+ * Throws strict errors for violations.
4
+ *
5
+ * @param userPath - The input path from the user/agent (relative or absolute)
6
+ * @param allowedRoots - Array of absolute paths permissible for access
7
+ * @param cwd - Current working directory for resolving relative paths
8
+ * @returns The normalized, validated absolute path.
9
+ */
10
+ export declare function validatePath(userPath: string, allowedRoots: string[], cwd: string): string;
11
+ /**
12
+ * Sanitize input to reject suspicious patterns immediately.
13
+ * @param input - The input string to sanitize.
14
+ * @returns The sanitized input string.
15
+ */
16
+ export declare function sanitizeInput(input: string): string;
17
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAkC1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD"}
@@ -0,0 +1,48 @@
1
+ import path from 'node:path';
2
+ /**
3
+ * Validate that a path is safe to access within permissible roots.
4
+ * Throws strict errors for violations.
5
+ *
6
+ * @param userPath - The input path from the user/agent (relative or absolute)
7
+ * @param allowedRoots - Array of absolute paths permissible for access
8
+ * @param cwd - Current working directory for resolving relative paths
9
+ * @returns The normalized, validated absolute path.
10
+ */
11
+ export function validatePath(userPath, allowedRoots, cwd) {
12
+ // 1. Basic Input Validation
13
+ if (userPath.includes('\0')) {
14
+ throw new Error('Security Blocked: Path contains null bytes.');
15
+ }
16
+ // 2. Resolve absolute path
17
+ const resolved = path.resolve(cwd, userPath);
18
+ // 3. Normalize (resolves .. segments)
19
+ const normalized = path.normalize(resolved);
20
+ // 4. Verify containment
21
+ // Check if the path starts with any of the allowed roots
22
+ // Must compare with trailing separator to prevent /var/lib vs /var/lib-private partial matches
23
+ // Exception: if the path IS the root itself.
24
+ const isAllowed = allowedRoots.some((root) => {
25
+ const relative = path.relative(root, normalized);
26
+ // blocked: relative starts with '..' (outside root)
27
+ // blocked: absolute path (different drive on windows, or just outside)
28
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
29
+ return false;
30
+ }
31
+ return true;
32
+ });
33
+ if (!isAllowed) {
34
+ throw new Error(`Security Blocked: Path "${userPath}" resolves to "${normalized}", which is outside allowed roots: [${allowedRoots.join(', ')}]`);
35
+ }
36
+ return normalized;
37
+ }
38
+ /**
39
+ * Sanitize input to reject suspicious patterns immediately.
40
+ * @param input - The input string to sanitize.
41
+ * @returns The sanitized input string.
42
+ */
43
+ export function sanitizeInput(input) {
44
+ if (input.includes('\0'))
45
+ throw new Error('Input contains null bytes');
46
+ return input;
47
+ }
48
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,YAAsB,EAAE,GAAW;IAChF,4BAA4B;IAC5B,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE7C,sCAAsC;IACtC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE5C,wBAAwB;IACxB,yDAAyD;IACzD,+FAA+F;IAC/F,6CAA6C;IAC7C,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEjD,oDAAoD;QACpD,uEAAuE;QACvE,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,2BAA2B,QAAQ,kBAAkB,UAAU,uCAAuC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACjI,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACvE,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Streaming Utilities
3
+ * Provides streaming support for large results
4
+ */
5
+ export interface StreamOptions {
6
+ chunkSize?: number;
7
+ delayMs?: number;
8
+ onProgress?: (progress: number, total: number) => void;
9
+ }
10
+ /**
11
+ * Stream large text content in chunks
12
+ * @param content - The text content to stream.
13
+ * @param options - Streaming options (chunkSize, delayMs, onProgress).
14
+ * @returns An async generator yielding string chunks.
15
+ */
16
+ export declare function streamContent(content: string, options?: StreamOptions): AsyncGenerator<string, void, unknown>;
17
+ /**
18
+ * Stream array results in batches
19
+ * @param items - The array of items to stream.
20
+ * @param options - Streaming options (chunkSize, delayMs, onProgress).
21
+ * @returns An async generator yielding batches of items.
22
+ */
23
+ export declare function streamArray<T>(items: T[], options?: StreamOptions): AsyncGenerator<T[], void, unknown>;
24
+ /**
25
+ * Format streaming response with progress
26
+ * @param chunks - The chunks to format.
27
+ * @param metadata - Metadata with total and processed counts.
28
+ * @param metadata.total - Total number of items.
29
+ * @param metadata.processed - Number of items processed.
30
+ * @returns A formatted string with progress indicator.
31
+ */
32
+ export declare function formatStreamingResponse(chunks: string[], metadata: {
33
+ total: number;
34
+ processed: number;
35
+ }): string;
36
+ /**
37
+ * Wrap a long-running operation with timeout
38
+ * @param operation - The promise to wrap with a timeout.
39
+ * @param timeoutMs - The timeout duration in milliseconds.
40
+ * @param operationName - A name for the operation (used in error messages).
41
+ * @returns The result of the operation.
42
+ */
43
+ export declare function withTimeout<T>(operation: Promise<T>, timeoutMs: number, operationName?: string): Promise<T>;
44
+ /**
45
+ * Truncate large results with summary
46
+ * @param items - The array of items to truncate.
47
+ * @param maxItems - Maximum number of items to keep.
48
+ * @returns An object with truncated items and metadata.
49
+ */
50
+ export declare function truncateResults<T>(items: T[], maxItems: number): {
51
+ items: T[];
52
+ truncated: boolean;
53
+ total: number;
54
+ shown: number;
55
+ };
56
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/utils/streaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD;AAED;;;;;GAKG;AACH,wBAAuB,aAAa,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,aAAkB,GAC1B,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAgBvC;AAED;;;;;GAKG;AACH,wBAAuB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,GAAE,aAAkB,GAAG,cAAc,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAgBjH;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAGhH;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EACrB,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,MAAoB,GAClC,OAAO,CAAC,CAAC,CAAC,CAaZ;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,CAAC,EAAE,EACV,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAUlE"}