ctxman 3.0.0 → 3.1.1

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 (224) hide show
  1. package/.ctxman/llm-profiles.json +1067 -39
  2. package/.ctxman/profiles/backend-team.json +13 -0
  3. package/.ctxman/profiles/default.json +12 -0
  4. package/.ctxman/profiles/devops-team.json +21 -0
  5. package/.ctxman/profiles/frontend-team.json +20 -0
  6. package/.ctxman/templates/bug-fix.json +17 -0
  7. package/.ctxman/templates/code-review.json +9 -0
  8. package/.ctxman/templates/documentation.json +9 -0
  9. package/.ctxman/templates/feature.json +9 -0
  10. package/.ctxman/templates/full-context.json +9 -0
  11. package/.ctxman/templates/refactoring.json +18 -0
  12. package/.ctxman/templates/testing.json +9 -0
  13. package/.ctxman/wizard-profiles/security-audit/profile.json +7 -1
  14. package/LICENSE +21 -0
  15. package/README.md +381 -136
  16. package/bin/cli.js +1880 -529
  17. package/bin/cm-ask.js +18 -67
  18. package/bin/cm-audit.js +121 -0
  19. package/bin/cm-count.js +151 -0
  20. package/bin/cm-gitingest.js +128 -115
  21. package/bin/cm-map.js +242 -0
  22. package/bin/cm-mcp.js +293 -0
  23. package/bin/cm-pack.js +405 -0
  24. package/bin/cm-policy.js +170 -0
  25. package/bin/cm-pr.js +248 -0
  26. package/bin/cm-search.js +178 -0
  27. package/bin/cm-update.js +128 -128
  28. package/bin/cm-why.js +197 -0
  29. package/bin/mcp-server.js +8 -24
  30. package/ctxman.js +237 -183
  31. package/examples/README.md +19 -4
  32. package/examples/github-actions/ctxman-check.yml +49 -0
  33. package/examples/wizard-profiles/security-audit/profile.json +7 -1
  34. package/index.d.ts +1422 -0
  35. package/index.js +55 -31
  36. package/lib/agents/pr-failure-agent.js +48 -45
  37. package/lib/analyzers/ai-suggester.js +451 -0
  38. package/lib/analyzers/dependency-scanner.js +505 -0
  39. package/lib/analyzers/duplicate-detector.js +264 -0
  40. package/lib/analyzers/go-method-analyzer.js +151 -110
  41. package/lib/analyzers/import-tracker.js +431 -0
  42. package/lib/analyzers/method-analyzer.js +1055 -434
  43. package/lib/analyzers/performance-dashboard.js +687 -0
  44. package/lib/analyzers/token-calculator.js +895 -504
  45. package/lib/analyzers/unused-exports-detector.js +336 -0
  46. package/lib/api/mcp/install.js +424 -0
  47. package/lib/api/mcp/prompts.js +281 -281
  48. package/lib/api/mcp/resources.js +300 -241
  49. package/lib/api/mcp/sandbox.js +89 -0
  50. package/lib/api/mcp/server.js +772 -312
  51. package/lib/api/mcp/start.js +125 -0
  52. package/lib/api/mcp/transports/HttpSseTransport.js +60 -52
  53. package/lib/api/rest/server.js +105 -28
  54. package/lib/cache/CacheManager.js +9 -17
  55. package/lib/core/Analyzer.js +16 -10
  56. package/lib/core/ContextBuilder.js +19 -28
  57. package/lib/core/Reporter.js +15 -14
  58. package/lib/core/Scanner.js +81 -12
  59. package/lib/count/index.js +100 -0
  60. package/lib/formatters/format-registry.js +394 -372
  61. package/lib/formatters/gitingest-formatter.js +656 -621
  62. package/lib/formatters/toon-formatter-v1.3.js +637 -632
  63. package/lib/formatters/toon-formatter.js +239 -240
  64. package/lib/integrations/git/BlameTracker.js +4 -4
  65. package/lib/integrations/git/DiffAnalyzer.js +38 -31
  66. package/lib/integrations/git/GitClient.js +71 -53
  67. package/lib/lsp/server.js +311 -0
  68. package/lib/map/graph.js +299 -0
  69. package/lib/map/imports.js +233 -0
  70. package/lib/map/index.js +33 -0
  71. package/lib/map/rank.js +253 -0
  72. package/lib/map/render.js +346 -0
  73. package/lib/map/resolver.js +574 -0
  74. package/lib/pack/budget.js +111 -0
  75. package/lib/pack/code-lexer.js +360 -0
  76. package/lib/pack/compress.js +414 -0
  77. package/lib/pack/index.js +354 -0
  78. package/lib/pack/renderers/common.js +134 -0
  79. package/lib/pack/renderers/index.js +24 -0
  80. package/lib/pack/renderers/json.js +47 -0
  81. package/lib/pack/renderers/markdown.js +54 -0
  82. package/lib/pack/renderers/plain.js +38 -0
  83. package/lib/pack/renderers/xml.js +85 -0
  84. package/lib/pack/select.js +177 -0
  85. package/lib/pack/split.js +182 -0
  86. package/lib/pack/tree.js +35 -0
  87. package/lib/parsers/gitignore-parser.js +116 -107
  88. package/lib/parsers/method-filter-parser.js +50 -33
  89. package/lib/plugins/ExporterPlugin.js +3 -3
  90. package/lib/plugins/LanguagePlugin.js +3 -3
  91. package/lib/plugins/PluginManager.js +7 -13
  92. package/lib/policy/audit.js +312 -0
  93. package/lib/policy/enforce.js +125 -0
  94. package/lib/policy/ignore-files.js +169 -0
  95. package/lib/policy/index.js +53 -0
  96. package/lib/policy/policy.js +489 -0
  97. package/lib/pr/diff-parser.js +267 -0
  98. package/lib/pr/method-mapper.js +148 -0
  99. package/lib/pr/pr-context.js +829 -0
  100. package/lib/pr/pr-git.js +149 -0
  101. package/lib/pr/pr-renderer.js +644 -0
  102. package/lib/pr/related-tests.js +296 -0
  103. package/lib/rag/DataSourcePlugin.js +5 -5
  104. package/lib/rag/EmbeddingProvider.js +19 -8
  105. package/lib/rag/Indexer.js +14 -5
  106. package/lib/rag/VectorStoreFactory.js +3 -3
  107. package/lib/rag/ask.js +122 -0
  108. package/lib/rag/sources/FileDataSource.js +12 -9
  109. package/lib/rag/stores/BaseVectorStore.js +5 -5
  110. package/lib/rag/stores/ChromaDBStore.js +10 -10
  111. package/lib/rag/stores/LanceDBStore.js +29 -19
  112. package/lib/rag/stores/PineconeStore.js +11 -9
  113. package/lib/search/bm25.js +433 -0
  114. package/lib/search/code-units.js +201 -0
  115. package/lib/search/symbols.js +189 -0
  116. package/lib/ui/dashboard.js +120 -89
  117. package/lib/ui/index.js +1 -6
  118. package/lib/ui/init-wizard-ui.js +550 -0
  119. package/lib/ui/progress-bar.js +94 -88
  120. package/lib/ui/select-input.js +40 -32
  121. package/lib/ui/template-selector.js +99 -0
  122. package/lib/ui/wizard.js +374 -329
  123. package/lib/utils/claude-token-counter.js +151 -0
  124. package/lib/utils/cli-output.js +17 -0
  125. package/lib/utils/clipboard-utils.js +49 -50
  126. package/lib/utils/config-utils.js +81 -66
  127. package/lib/utils/context-versioning.js +532 -0
  128. package/lib/utils/error-handler.js +112 -112
  129. package/lib/utils/file-utils.js +153 -69
  130. package/lib/utils/format-converter.js +356 -283
  131. package/lib/utils/git-utils.js +366 -294
  132. package/lib/utils/llm-cost-estimator.js +281 -0
  133. package/lib/utils/llm-detector.js +242 -78
  134. package/lib/utils/logger.js +246 -237
  135. package/lib/utils/messages.js +355 -0
  136. package/lib/utils/multi-repo-manager.js +364 -0
  137. package/lib/utils/profile-manager.js +380 -0
  138. package/lib/utils/safe-read.js +61 -0
  139. package/lib/utils/secret-redactor.js +61 -0
  140. package/lib/utils/snapshot-manager.js +679 -0
  141. package/lib/utils/template-manager.js +378 -0
  142. package/lib/utils/token-utils.js +201 -170
  143. package/lib/utils/tokenizer-adapter.js +421 -377
  144. package/lib/utils/updater.js +539 -506
  145. package/lib/watch/FileWatcher.js +12 -8
  146. package/lib/watch/IncrementalAnalyzer.js +7 -7
  147. package/lib/why/coupling.js +81 -0
  148. package/lib/why/errors.js +23 -0
  149. package/lib/why/git.js +169 -0
  150. package/lib/why/history.js +108 -0
  151. package/lib/why/index.js +720 -0
  152. package/lib/why/ownership.js +79 -0
  153. package/lib/why/paths.js +207 -0
  154. package/lib/why/references.js +259 -0
  155. package/lib/why/render.js +722 -0
  156. package/lib/why/search.js +358 -0
  157. package/lib/why/target.js +389 -0
  158. package/lib/wizards/config-generator.js +257 -0
  159. package/lib/wizards/project-detector.js +572 -0
  160. package/package.json +44 -10
  161. package/.ctxman/logs/ctxman-2026-07-02.log +0 -156
  162. package/.ctxman/self-knowledge/documents.lance/_transactions/0-b3dd1558-f95b-44b9-a154-18e8c330ae7a.txn +0 -0
  163. package/.ctxman/self-knowledge/documents.lance/_transactions/1-44bff6d4-e552-4010-a769-e09ad822698d.txn +0 -0
  164. package/.ctxman/self-knowledge/documents.lance/_transactions/10-37260794-5947-4ecb-b4c8-d732f58f40f1.txn +0 -0
  165. package/.ctxman/self-knowledge/documents.lance/_transactions/11-0d52a883-5518-463c-9b6d-986c3af89dfd.txn +0 -0
  166. package/.ctxman/self-knowledge/documents.lance/_transactions/12-ae354646-52f2-49c9-90fb-2e6ed8932663.txn +0 -0
  167. package/.ctxman/self-knowledge/documents.lance/_transactions/13-5d7d5e57-27da-498b-b734-091b9d38da13.txn +0 -0
  168. package/.ctxman/self-knowledge/documents.lance/_transactions/14-558ce928-810b-4252-a364-fdd1ee6f8a25.txn +0 -0
  169. package/.ctxman/self-knowledge/documents.lance/_transactions/15-27e3a58f-8b64-43b8-a9f4-e3369446968b.txn +0 -0
  170. package/.ctxman/self-knowledge/documents.lance/_transactions/16-a110c390-e5c8-4464-b976-bc7f5195fa15.txn +0 -0
  171. package/.ctxman/self-knowledge/documents.lance/_transactions/17-97513225-53de-4216-b61a-6337bd0cc4ad.txn +0 -0
  172. package/.ctxman/self-knowledge/documents.lance/_transactions/18-5ba450f0-c527-459c-bf4f-6d79b5e4285f.txn +0 -0
  173. package/.ctxman/self-knowledge/documents.lance/_transactions/19-600d3a63-5225-49e9-b8b7-30e037b564ab.txn +0 -0
  174. package/.ctxman/self-knowledge/documents.lance/_transactions/2-48a61b4e-92cf-4342-8376-914c1b99a9f9.txn +0 -0
  175. package/.ctxman/self-knowledge/documents.lance/_transactions/20-121dd912-5410-410e-84ff-82c7a23604a0.txn +0 -0
  176. package/.ctxman/self-knowledge/documents.lance/_transactions/3-bc6844ab-7ea3-4bb3-9ee1-538ce5664a9c.txn +0 -0
  177. package/.ctxman/self-knowledge/documents.lance/_transactions/4-d5e1754f-dbb5-454e-a9be-2a7da8d7bcf9.txn +0 -0
  178. package/.ctxman/self-knowledge/documents.lance/_transactions/5-4fae93df-0568-4b6f-8acf-8bef4bba6047.txn +0 -0
  179. package/.ctxman/self-knowledge/documents.lance/_transactions/6-4b1b8b87-068e-49a3-ba2b-d8dae628b252.txn +0 -0
  180. package/.ctxman/self-knowledge/documents.lance/_transactions/7-63d040fb-d2fa-4c0f-bed0-53411918a7b0.txn +0 -0
  181. package/.ctxman/self-knowledge/documents.lance/_transactions/8-c5628cf6-264c-420f-aab8-bc96a9083591.txn +0 -0
  182. package/.ctxman/self-knowledge/documents.lance/_transactions/9-c94570aa-5e53-4fcb-971f-cecc1d1d5492.txn +0 -0
  183. package/.ctxman/self-knowledge/documents.lance/_versions/1.manifest +0 -0
  184. package/.ctxman/self-knowledge/documents.lance/_versions/10.manifest +0 -0
  185. package/.ctxman/self-knowledge/documents.lance/_versions/11.manifest +0 -0
  186. package/.ctxman/self-knowledge/documents.lance/_versions/12.manifest +0 -0
  187. package/.ctxman/self-knowledge/documents.lance/_versions/13.manifest +0 -0
  188. package/.ctxman/self-knowledge/documents.lance/_versions/14.manifest +0 -0
  189. package/.ctxman/self-knowledge/documents.lance/_versions/15.manifest +0 -0
  190. package/.ctxman/self-knowledge/documents.lance/_versions/16.manifest +0 -0
  191. package/.ctxman/self-knowledge/documents.lance/_versions/17.manifest +0 -0
  192. package/.ctxman/self-knowledge/documents.lance/_versions/18.manifest +0 -0
  193. package/.ctxman/self-knowledge/documents.lance/_versions/19.manifest +0 -0
  194. package/.ctxman/self-knowledge/documents.lance/_versions/2.manifest +0 -0
  195. package/.ctxman/self-knowledge/documents.lance/_versions/20.manifest +0 -0
  196. package/.ctxman/self-knowledge/documents.lance/_versions/21.manifest +0 -0
  197. package/.ctxman/self-knowledge/documents.lance/_versions/3.manifest +0 -0
  198. package/.ctxman/self-knowledge/documents.lance/_versions/4.manifest +0 -0
  199. package/.ctxman/self-knowledge/documents.lance/_versions/5.manifest +0 -0
  200. package/.ctxman/self-knowledge/documents.lance/_versions/6.manifest +0 -0
  201. package/.ctxman/self-knowledge/documents.lance/_versions/7.manifest +0 -0
  202. package/.ctxman/self-knowledge/documents.lance/_versions/8.manifest +0 -0
  203. package/.ctxman/self-knowledge/documents.lance/_versions/9.manifest +0 -0
  204. package/.ctxman/self-knowledge/documents.lance/data/000010010011011101000010de8621405d9d5cb06540dbf02c.lance +0 -0
  205. package/.ctxman/self-knowledge/documents.lance/data/0000101001011100011000003fb62a4aa8978974075c144f1c.lance +0 -0
  206. package/.ctxman/self-knowledge/documents.lance/data/000011010000100111001011c6cc824d628f3bb1f4e04cd5d0.lance +0 -0
  207. package/.ctxman/self-knowledge/documents.lance/data/001000001000011001011100d8f74349ada090b332cd1df669.lance +0 -0
  208. package/.ctxman/self-knowledge/documents.lance/data/01000001111010001000010045ab44467bb1e7e4d8ae06bd58.lance +0 -0
  209. package/.ctxman/self-knowledge/documents.lance/data/01000101101110111110011131ef904241a89e1ffb6ddaf8e3.lance +0 -0
  210. package/.ctxman/self-knowledge/documents.lance/data/010010110000010000011010fbfcc145c6a8a827b28057a07e.lance +0 -0
  211. package/.ctxman/self-knowledge/documents.lance/data/1000011000101010001110003fb4f045c3835982efa1405324.lance +0 -0
  212. package/.ctxman/self-knowledge/documents.lance/data/100111011101110111101011f4396b410fa06af3b028d204e6.lance +0 -0
  213. package/.ctxman/self-knowledge/documents.lance/data/100111100111101000001100596b174e00995d6cc2969cc8dc.lance +0 -0
  214. package/.ctxman/self-knowledge/documents.lance/data/1010001100011000110010102ea16b484d887c7c9725feffd6.lance +0 -0
  215. package/.ctxman/self-knowledge/documents.lance/data/101101100010101111110111c5230944d9b3af7301b6392dda.lance +0 -0
  216. package/.ctxman/self-knowledge/documents.lance/data/1011011100100111111110105892bf41b5a530fedd7cf516f1.lance +0 -0
  217. package/.ctxman/self-knowledge/documents.lance/data/10111110000010001011110164e8774742bade87b483c10f36.lance +0 -0
  218. package/.ctxman/self-knowledge/documents.lance/data/1100000100010110001110103ffaca40a2a42c85067ebaf9ae.lance +0 -0
  219. package/.ctxman/self-knowledge/documents.lance/data/110000010001110110101110664bde4c76a78dfc14b05e83b8.lance +0 -0
  220. package/.ctxman/self-knowledge/documents.lance/data/11001100111000010100110050645c4281b1f35b2022234f7f.lance +0 -0
  221. package/.ctxman/self-knowledge/documents.lance/data/1101111011001100110111017214924a368f5719eab2246619.lance +0 -0
  222. package/.ctxman/self-knowledge/documents.lance/data/1110000111001010001000002150c24dcab653d39d07032e63.lance +0 -0
  223. package/.ctxman/self-knowledge/documents.lance/data/1110100000000100000011014d20534967a18b5c87721659ff.lance +0 -0
  224. package/.ctxman/self-knowledge/documents.lance/data/11110101111010000101011135a0114ef2b35dc6f1297a3381.lance +0 -0
@@ -1,319 +1,319 @@
1
- import { getLogger } from "../../utils/logger.js";
2
- import { Analyzer } from "../../core/Analyzer.js";
3
- import { ContextBuilder } from "../../core/ContextBuilder.js";
4
- import fs from "fs";
1
+ import { getLogger } from '../../utils/logger.js';
2
+ import { Analyzer } from '../../core/Analyzer.js';
3
+ import { ContextBuilder } from '../../core/ContextBuilder.js';
4
+ import fs from 'fs';
5
5
 
6
- const logger = getLogger("MCP:Prompts");
6
+ const logger = getLogger('MCP:Prompts');
7
7
 
8
8
  /**
9
9
  * PromptProvider manages MCP prompt templates
10
10
  * Provides reusable templates for common development workflows
11
11
  */
12
12
  export class PromptProvider {
13
- constructor(analyzer = null, contextBuilder = null) {
14
- this.analyzer = analyzer || new Analyzer();
15
- this.contextBuilder = contextBuilder || new ContextBuilder();
16
- this.templates = this.initializeTemplates();
17
- }
13
+ constructor(analyzer = null, contextBuilder = null) {
14
+ this.analyzer = analyzer || new Analyzer();
15
+ this.contextBuilder = contextBuilder || new ContextBuilder();
16
+ this.templates = this.initializeTemplates();
17
+ }
18
18
 
19
- /**
20
- * Initialize default prompt templates
21
- * @private
22
- */
23
- initializeTemplates() {
24
- return {
25
- code_review: {
26
- name: "code_review",
27
- title: "Code Review",
28
- description: "Analyze code quality, identify issues, and suggest improvements",
29
- arguments: [
30
- {
31
- name: "code",
32
- description: "The code to review (optional if filePath provided)",
33
- required: false
34
- },
35
- {
36
- name: "filePath",
37
- description: "Path to the file to review",
38
- required: false
39
- },
40
- {
41
- name: "focus",
42
- description: "Specific aspect to focus on (security, performance, readability, etc.)",
43
- required: false
44
- }
45
- ],
46
- handler: this.codeReviewHandler.bind(this)
47
- },
19
+ /**
20
+ * Initialize default prompt templates
21
+ * @private
22
+ */
23
+ initializeTemplates() {
24
+ return {
25
+ code_review: {
26
+ name: 'code_review',
27
+ title: 'Code Review',
28
+ description: 'Analyze code quality, identify issues, and suggest improvements',
29
+ arguments: [
30
+ {
31
+ name: 'code',
32
+ description: 'The code to review (optional if filePath provided)',
33
+ required: false,
34
+ },
35
+ {
36
+ name: 'filePath',
37
+ description: 'Path to the file to review',
38
+ required: false,
39
+ },
40
+ {
41
+ name: 'focus',
42
+ description: 'Specific aspect to focus on (security, performance, readability, etc.)',
43
+ required: false,
44
+ },
45
+ ],
46
+ handler: this.codeReviewHandler.bind(this),
47
+ },
48
48
 
49
- refactor_code: {
50
- name: "refactor_code",
51
- title: "Refactor Code",
52
- description: "Suggest refactoring strategies to improve code structure and maintainability",
53
- arguments: [
54
- {
55
- name: "filePath",
56
- description: "Path to the file to refactor",
57
- required: true
58
- },
59
- {
60
- name: "focus",
61
- description: "Refactoring focus (modularity, testability, performance, etc.)",
62
- required: false
63
- }
64
- ],
65
- handler: this.refactorHandler.bind(this)
66
- },
49
+ refactor_code: {
50
+ name: 'refactor_code',
51
+ title: 'Refactor Code',
52
+ description: 'Suggest refactoring strategies to improve code structure and maintainability',
53
+ arguments: [
54
+ {
55
+ name: 'filePath',
56
+ description: 'Path to the file to refactor',
57
+ required: true,
58
+ },
59
+ {
60
+ name: 'focus',
61
+ description: 'Refactoring focus (modularity, testability, performance, etc.)',
62
+ required: false,
63
+ },
64
+ ],
65
+ handler: this.refactorHandler.bind(this),
66
+ },
67
67
 
68
- explain_codebase: {
69
- name: "explain_codebase",
70
- title: "Explain Codebase",
71
- description: "Explain the architecture and structure of the codebase",
72
- arguments: [
73
- {
74
- name: "projectPath",
75
- description: "Path to the project root",
76
- required: true
77
- },
78
- {
79
- name: "aspect",
80
- description: "Specific aspect to explain (architecture, dependencies, patterns, etc.)",
81
- required: false
82
- }
83
- ],
84
- handler: this.explainCodebaseHandler.bind(this)
85
- },
68
+ explain_codebase: {
69
+ name: 'explain_codebase',
70
+ title: 'Explain Codebase',
71
+ description: 'Explain the architecture and structure of the codebase',
72
+ arguments: [
73
+ {
74
+ name: 'projectPath',
75
+ description: 'Path to the project root',
76
+ required: true,
77
+ },
78
+ {
79
+ name: 'aspect',
80
+ description: 'Specific aspect to explain (architecture, dependencies, patterns, etc.)',
81
+ required: false,
82
+ },
83
+ ],
84
+ handler: this.explainCodebaseHandler.bind(this),
85
+ },
86
86
 
87
- debug_issue: {
88
- name: "debug_issue",
89
- title: "Debug Issue",
90
- description: "Help debug and diagnose code issues",
91
- arguments: [
92
- {
93
- name: "error",
94
- description: "Error message or description of the issue",
95
- required: true
96
- },
97
- {
98
- name: "stackTrace",
99
- description: "Stack trace (if available)",
100
- required: false
101
- },
102
- {
103
- name: "filePath",
104
- description: "Path to the file where the issue occurs",
105
- required: false
106
- }
107
- ],
108
- handler: this.debugHandler.bind(this)
109
- },
87
+ debug_issue: {
88
+ name: 'debug_issue',
89
+ title: 'Debug Issue',
90
+ description: 'Help debug and diagnose code issues',
91
+ arguments: [
92
+ {
93
+ name: 'error',
94
+ description: 'Error message or description of the issue',
95
+ required: true,
96
+ },
97
+ {
98
+ name: 'stackTrace',
99
+ description: 'Stack trace (if available)',
100
+ required: false,
101
+ },
102
+ {
103
+ name: 'filePath',
104
+ description: 'Path to the file where the issue occurs',
105
+ required: false,
106
+ },
107
+ ],
108
+ handler: this.debugHandler.bind(this),
109
+ },
110
110
 
111
- write_tests: {
112
- name: "write_tests",
113
- title: "Write Tests",
114
- description: "Generate test cases for functions or modules",
115
- arguments: [
116
- {
117
- name: "filePath",
118
- description: "Path to the file to test",
119
- required: true
120
- },
121
- {
122
- name: "functions",
123
- description: "Specific functions to test (comma-separated)",
124
- required: false
125
- },
126
- {
127
- name: "framework",
128
- description: "Testing framework (vitest, jest, mocha, etc.)",
129
- required: false
130
- }
131
- ],
132
- handler: this.writeTestsHandler.bind(this)
133
- }
134
- };
135
- }
111
+ write_tests: {
112
+ name: 'write_tests',
113
+ title: 'Write Tests',
114
+ description: 'Generate test cases for functions or modules',
115
+ arguments: [
116
+ {
117
+ name: 'filePath',
118
+ description: 'Path to the file to test',
119
+ required: true,
120
+ },
121
+ {
122
+ name: 'functions',
123
+ description: 'Specific functions to test (comma-separated)',
124
+ required: false,
125
+ },
126
+ {
127
+ name: 'framework',
128
+ description: 'Testing framework (vitest, jest, mocha, etc.)',
129
+ required: false,
130
+ },
131
+ ],
132
+ handler: this.writeTestsHandler.bind(this),
133
+ },
134
+ };
135
+ }
136
136
 
137
- /**
138
- * List available prompts
139
- * @param {string} cursor - Optional cursor for pagination
140
- * @returns {Object} List of prompts
141
- */
142
- listPrompts(cursor = null) {
143
- const prompts = Object.values(this.templates).map(template => ({
144
- name: template.name,
145
- title: template.title,
146
- description: template.description,
147
- arguments: template.arguments
148
- }));
137
+ /**
138
+ * List available prompts
139
+ * @param {string} cursor - Optional cursor for pagination
140
+ * @returns {Object} List of prompts
141
+ */
142
+ listPrompts(_cursor = null) {
143
+ const prompts = Object.values(this.templates).map((template) => ({
144
+ name: template.name,
145
+ title: template.title,
146
+ description: template.description,
147
+ arguments: template.arguments,
148
+ }));
149
149
 
150
- logger.info(`Listed ${prompts.length} prompts`);
151
- return { prompts };
152
- }
150
+ logger.info(`Listed ${prompts.length} prompts`);
151
+ return { prompts };
152
+ }
153
153
 
154
- /**
155
- * Get a specific prompt with arguments
156
- * @param {string} name - Prompt name
157
- * @param {Object} args - Prompt arguments
158
- * @returns {Promise<Object>} Rendered prompt
159
- */
160
- async getPrompt(name, args = {}) {
161
- logger.info(`Getting prompt: ${name}`);
154
+ /**
155
+ * Get a specific prompt with arguments
156
+ * @param {string} name - Prompt name
157
+ * @param {Object} args - Prompt arguments
158
+ * @returns {Promise<Object>} Rendered prompt
159
+ */
160
+ async getPrompt(name, args = {}) {
161
+ logger.info(`Getting prompt: ${name}`);
162
162
 
163
- const template = this.templates[name];
164
- if (!template) {
165
- throw new Error(`Prompt template not found: ${name}`);
166
- }
163
+ const template = this.templates[name];
164
+ if (!template) {
165
+ throw new Error(`Prompt template not found: ${name}`);
166
+ }
167
167
 
168
- // Validate required arguments
169
- this.validateArguments(template, args);
168
+ // Validate required arguments
169
+ this.validateArguments(template, args);
170
170
 
171
- // Execute template handler
172
- const messages = await template.handler(args);
171
+ // Execute template handler
172
+ const messages = await template.handler(args);
173
173
 
174
- return {
175
- description: template.description,
176
- messages
177
- };
178
- }
174
+ return {
175
+ description: template.description,
176
+ messages,
177
+ };
178
+ }
179
179
 
180
- /**
181
- * Validate prompt arguments
182
- * @private
183
- */
184
- validateArguments(template, args) {
185
- for (const arg of template.arguments) {
186
- if (arg.required && !(arg.name in args)) {
187
- throw new Error(`Missing required argument: ${arg.name}`);
188
- }
189
- }
180
+ /**
181
+ * Validate prompt arguments
182
+ * @private
183
+ */
184
+ validateArguments(template, args) {
185
+ for (const arg of template.arguments) {
186
+ if (arg.required && !(arg.name in args)) {
187
+ throw new Error(`Missing required argument: ${arg.name}`);
188
+ }
190
189
  }
190
+ }
191
191
 
192
- /**
193
- * Code review prompt handler
194
- * @private
195
- */
196
- async codeReviewHandler(args) {
197
- let code = args.code;
198
-
199
- // If filePath provided, read the file
200
- if (args.filePath && !code) {
201
- try {
202
- code = fs.readFileSync(args.filePath, "utf-8");
203
- } catch (error) {
204
- throw new Error(`Failed to read file: ${error.message}`);
205
- }
206
- }
207
-
208
- if (!code) {
209
- throw new Error("Either 'code' or 'filePath' must be provided");
210
- }
192
+ /**
193
+ * Code review prompt handler
194
+ * @private
195
+ */
196
+ async codeReviewHandler(args) {
197
+ let code = args.code;
211
198
 
212
- const focusText = args.focus ? ` with focus on ${args.focus}` : "";
213
- const fileInfo = args.filePath ? ` from ${args.filePath}` : "";
199
+ // If filePath provided, read the file
200
+ if (args.filePath && !code) {
201
+ try {
202
+ code = fs.readFileSync(args.filePath, 'utf-8');
203
+ } catch (error) {
204
+ throw new Error(`Failed to read file: ${error.message}`);
205
+ }
206
+ }
214
207
 
215
- return [
216
- {
217
- role: "user",
218
- content: {
219
- type: "text",
220
- text: `Please review the following code${fileInfo}${focusText}:\n\n\`\`\`\n${code}\n\`\`\`\n\nProvide feedback on:\n1. Code quality and best practices\n2. Potential bugs or issues\n3. Performance considerations\n4. Readability and maintainability\n5. Suggested improvements`
221
- }
222
- }
223
- ];
208
+ if (!code) {
209
+ throw new Error("Either 'code' or 'filePath' must be provided");
224
210
  }
225
211
 
226
- /**
227
- * Refactor prompt handler
228
- * @private
229
- */
230
- async refactorHandler(args) {
231
- const code = fs.readFileSync(args.filePath, "utf-8");
232
- const focusText = args.focus ? ` focusing on ${args.focus}` : "";
212
+ const focusText = args.focus ? ` with focus on ${args.focus}` : '';
213
+ const fileInfo = args.filePath ? ` from ${args.filePath}` : '';
233
214
 
234
- return [
235
- {
236
- role: "user",
237
- content: {
238
- type: "text",
239
- text: `Please suggest refactoring strategies for the following code from ${args.filePath}${focusText}:\n\n\`\`\`\n${code}\n\`\`\`\n\nProvide:\n1. Identified code smells\n2. Refactoring suggestions\n3. Expected benefits\n4. Implementation steps`
240
- }
241
- }
242
- ];
243
- }
215
+ return [
216
+ {
217
+ role: 'user',
218
+ content: {
219
+ type: 'text',
220
+ text: `Please review the following code${fileInfo}${focusText}:\n\n\`\`\`\n${code}\n\`\`\`\n\nProvide feedback on:\n1. Code quality and best practices\n2. Potential bugs or issues\n3. Performance considerations\n4. Readability and maintainability\n5. Suggested improvements`,
221
+ },
222
+ },
223
+ ];
224
+ }
244
225
 
245
- /**
246
- * Explain codebase prompt handler
247
- * @private
248
- */
249
- async explainCodebaseHandler(args) {
250
- const Scanner = (await import("../../core/Scanner.js")).Scanner;
251
- const scanner = new Scanner(args.projectPath);
252
- const files = scanner.scan();
253
- const analysis = await this.analyzer.analyze(files);
226
+ /**
227
+ * Refactor prompt handler
228
+ * @private
229
+ */
230
+ async refactorHandler(args) {
231
+ const code = fs.readFileSync(args.filePath, 'utf-8');
232
+ const focusText = args.focus ? ` focusing on ${args.focus}` : '';
254
233
 
255
- const aspectText = args.aspect ? ` with focus on ${args.aspect}` : "";
256
- const stats = analysis.stats;
234
+ return [
235
+ {
236
+ role: 'user',
237
+ content: {
238
+ type: 'text',
239
+ text: `Please suggest refactoring strategies for the following code from ${args.filePath}${focusText}:\n\n\`\`\`\n${code}\n\`\`\`\n\nProvide:\n1. Identified code smells\n2. Refactoring suggestions\n3. Expected benefits\n4. Implementation steps`,
240
+ },
241
+ },
242
+ ];
243
+ }
257
244
 
258
- return [
259
- {
260
- role: "user",
261
- content: {
262
- type: "text",
263
- text: `Please explain the codebase at ${args.projectPath}${aspectText}.\n\nCodebase Statistics:\n- Total Files: ${stats.totalFiles}\n- Total Lines: ${stats.totalLines}\n- Total Tokens: ${stats.totalTokens}\n- Languages: ${Object.keys(stats.byLanguage || {}).join(", ")}\n\nProvide:\n1. Architecture overview\n2. Key components and their relationships\n3. Design patterns used\n4. Technology stack\n5. Notable characteristics`
264
- }
265
- }
266
- ];
267
- }
245
+ /**
246
+ * Explain codebase prompt handler
247
+ * @private
248
+ */
249
+ async explainCodebaseHandler(args) {
250
+ const Scanner = (await import('../../core/Scanner.js')).Scanner;
251
+ const scanner = new Scanner(args.projectPath);
252
+ const files = scanner.scan();
253
+ const analysis = await this.analyzer.analyze(files);
268
254
 
269
- /**
270
- * Debug prompt handler
271
- * @private
272
- */
273
- async debugHandler(args) {
274
- let debugContext = `Error: ${args.error}`;
255
+ const aspectText = args.aspect ? ` with focus on ${args.aspect}` : '';
256
+ const stats = analysis.stats;
275
257
 
276
- if (args.stackTrace) {
277
- debugContext += `\n\nStack Trace:\n${args.stackTrace}`;
278
- }
258
+ return [
259
+ {
260
+ role: 'user',
261
+ content: {
262
+ type: 'text',
263
+ text: `Please explain the codebase at ${args.projectPath}${aspectText}.\n\nCodebase Statistics:\n- Total Files: ${stats.totalFiles}\n- Total Lines: ${stats.totalLines}\n- Total Tokens: ${stats.totalTokens}\n- Languages: ${Object.keys(stats.byLanguage || {}).join(', ')}\n\nProvide:\n1. Architecture overview\n2. Key components and their relationships\n3. Design patterns used\n4. Technology stack\n5. Notable characteristics`,
264
+ },
265
+ },
266
+ ];
267
+ }
279
268
 
280
- if (args.filePath) {
281
- try {
282
- const code = fs.readFileSync(args.filePath, "utf-8");
283
- debugContext += `\n\nRelevant Code (${args.filePath}):\n\`\`\`\n${code}\n\`\`\``;
284
- } catch (error) {
285
- // File read failed, continue without code
286
- }
287
- }
269
+ /**
270
+ * Debug prompt handler
271
+ * @private
272
+ */
273
+ async debugHandler(args) {
274
+ let debugContext = `Error: ${args.error}`;
288
275
 
289
- return [
290
- {
291
- role: "user",
292
- content: {
293
- type: "text",
294
- text: `Please help debug the following issue:\n\n${debugContext}\n\nProvide:\n1. Root cause analysis\n2. Possible fixes\n3. Prevention strategies\n4. Related best practices`
295
- }
296
- }
297
- ];
276
+ if (args.stackTrace) {
277
+ debugContext += `\n\nStack Trace:\n${args.stackTrace}`;
298
278
  }
299
279
 
300
- /**
301
- * Write tests prompt handler
302
- * @private
303
- */
304
- async writeTestsHandler(args) {
305
- const code = fs.readFileSync(args.filePath, "utf-8");
306
- const functionsText = args.functions ? ` for functions: ${args.functions}` : "";
307
- const frameworkText = args.framework ? ` using ${args.framework}` : "";
308
-
309
- return [
310
- {
311
- role: "user",
312
- content: {
313
- type: "text",
314
- text: `Please write comprehensive tests${functionsText}${frameworkText} for the following code from ${args.filePath}:\n\n\`\`\`\n${code}\n\`\`\`\n\nProvide:\n1. Unit tests for individual functions\n2. Edge case tests\n3. Integration tests (if applicable)\n4. Mock/stub examples\n5. Test organization suggestions`
315
- }
316
- }
317
- ];
280
+ if (args.filePath) {
281
+ try {
282
+ const code = fs.readFileSync(args.filePath, 'utf-8');
283
+ debugContext += `\n\nRelevant Code (${args.filePath}):\n\`\`\`\n${code}\n\`\`\``;
284
+ } catch (_error) {
285
+ // File read failed, continue without code
286
+ }
318
287
  }
288
+
289
+ return [
290
+ {
291
+ role: 'user',
292
+ content: {
293
+ type: 'text',
294
+ text: `Please help debug the following issue:\n\n${debugContext}\n\nProvide:\n1. Root cause analysis\n2. Possible fixes\n3. Prevention strategies\n4. Related best practices`,
295
+ },
296
+ },
297
+ ];
298
+ }
299
+
300
+ /**
301
+ * Write tests prompt handler
302
+ * @private
303
+ */
304
+ async writeTestsHandler(args) {
305
+ const code = fs.readFileSync(args.filePath, 'utf-8');
306
+ const functionsText = args.functions ? ` for functions: ${args.functions}` : '';
307
+ const frameworkText = args.framework ? ` using ${args.framework}` : '';
308
+
309
+ return [
310
+ {
311
+ role: 'user',
312
+ content: {
313
+ type: 'text',
314
+ text: `Please write comprehensive tests${functionsText}${frameworkText} for the following code from ${args.filePath}:\n\n\`\`\`\n${code}\n\`\`\`\n\nProvide:\n1. Unit tests for individual functions\n2. Edge case tests\n3. Integration tests (if applicable)\n4. Mock/stub examples\n5. Test organization suggestions`,
315
+ },
316
+ },
317
+ ];
318
+ }
319
319
  }