@getverbal/cli 0.6.0 → 0.7.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 (249) hide show
  1. package/dist/cli.js +18760 -1833
  2. package/package.json +2 -1
  3. package/dist/agent-hooks/claude.d.ts +0 -10
  4. package/dist/agent-hooks/claude.d.ts.map +0 -1
  5. package/dist/agent-hooks/claude.js +0 -218
  6. package/dist/agent-hooks/claude.js.map +0 -1
  7. package/dist/agent-hooks/cli.d.ts +0 -2
  8. package/dist/agent-hooks/cli.d.ts.map +0 -1
  9. package/dist/agent-hooks/cli.js +0 -271
  10. package/dist/agent-hooks/cli.js.map +0 -1
  11. package/dist/agent-hooks/codex.d.ts +0 -9
  12. package/dist/agent-hooks/codex.d.ts.map +0 -1
  13. package/dist/agent-hooks/codex.js +0 -349
  14. package/dist/agent-hooks/codex.js.map +0 -1
  15. package/dist/agent-hooks/config.d.ts +0 -32
  16. package/dist/agent-hooks/config.d.ts.map +0 -1
  17. package/dist/agent-hooks/config.js +0 -176
  18. package/dist/agent-hooks/config.js.map +0 -1
  19. package/dist/agent-hooks/ingest.d.ts +0 -4
  20. package/dist/agent-hooks/ingest.d.ts.map +0 -1
  21. package/dist/agent-hooks/ingest.js +0 -22
  22. package/dist/agent-hooks/ingest.js.map +0 -1
  23. package/dist/agent-hooks/launchagent.d.ts +0 -7
  24. package/dist/agent-hooks/launchagent.d.ts.map +0 -1
  25. package/dist/agent-hooks/launchagent.js +0 -51
  26. package/dist/agent-hooks/launchagent.js.map +0 -1
  27. package/dist/agent-hooks/runtime-context.d.ts +0 -20
  28. package/dist/agent-hooks/runtime-context.d.ts.map +0 -1
  29. package/dist/agent-hooks/runtime-context.js +0 -90
  30. package/dist/agent-hooks/runtime-context.js.map +0 -1
  31. package/dist/agent-hooks/state.d.ts +0 -26
  32. package/dist/agent-hooks/state.d.ts.map +0 -1
  33. package/dist/agent-hooks/state.js +0 -67
  34. package/dist/agent-hooks/state.js.map +0 -1
  35. package/dist/agent-hooks/tokscale.d.ts +0 -70
  36. package/dist/agent-hooks/tokscale.d.ts.map +0 -1
  37. package/dist/agent-hooks/tokscale.js +0 -142
  38. package/dist/agent-hooks/tokscale.js.map +0 -1
  39. package/dist/agent-hooks/tool-extraction.d.ts +0 -7
  40. package/dist/agent-hooks/tool-extraction.d.ts.map +0 -1
  41. package/dist/agent-hooks/tool-extraction.js +0 -100
  42. package/dist/agent-hooks/tool-extraction.js.map +0 -1
  43. package/dist/agent-hooks/trace.d.ts +0 -17
  44. package/dist/agent-hooks/trace.d.ts.map +0 -1
  45. package/dist/agent-hooks/trace.js +0 -25
  46. package/dist/agent-hooks/trace.js.map +0 -1
  47. package/dist/auth/browser-auth.d.ts +0 -6
  48. package/dist/auth/browser-auth.d.ts.map +0 -1
  49. package/dist/auth/browser-auth.js +0 -202
  50. package/dist/auth/browser-auth.js.map +0 -1
  51. package/dist/auth/credentials.d.ts +0 -6
  52. package/dist/auth/credentials.d.ts.map +0 -1
  53. package/dist/auth/credentials.js +0 -78
  54. package/dist/auth/credentials.js.map +0 -1
  55. package/dist/cli.d.ts +0 -3
  56. package/dist/cli.d.ts.map +0 -1
  57. package/dist/cli.js.map +0 -1
  58. package/dist/commands/dashboard.d.ts +0 -2
  59. package/dist/commands/dashboard.d.ts.map +0 -1
  60. package/dist/commands/dashboard.js +0 -19
  61. package/dist/commands/dashboard.js.map +0 -1
  62. package/dist/commands/hooks.d.ts +0 -2
  63. package/dist/commands/hooks.d.ts.map +0 -1
  64. package/dist/commands/hooks.js +0 -6
  65. package/dist/commands/hooks.js.map +0 -1
  66. package/dist/commands/import.d.ts +0 -2
  67. package/dist/commands/import.d.ts.map +0 -1
  68. package/dist/commands/import.js +0 -129
  69. package/dist/commands/import.js.map +0 -1
  70. package/dist/commands/init.d.ts +0 -2
  71. package/dist/commands/init.d.ts.map +0 -1
  72. package/dist/commands/init.js +0 -262
  73. package/dist/commands/init.js.map +0 -1
  74. package/dist/commands/logout.d.ts +0 -2
  75. package/dist/commands/logout.d.ts.map +0 -1
  76. package/dist/commands/logout.js +0 -17
  77. package/dist/commands/logout.js.map +0 -1
  78. package/dist/commands/mcp-serve.d.ts +0 -2
  79. package/dist/commands/mcp-serve.d.ts.map +0 -1
  80. package/dist/commands/mcp-serve.js +0 -7
  81. package/dist/commands/mcp-serve.js.map +0 -1
  82. package/dist/commands/status.d.ts +0 -2
  83. package/dist/commands/status.d.ts.map +0 -1
  84. package/dist/commands/status.js +0 -43
  85. package/dist/commands/status.js.map +0 -1
  86. package/dist/commands/uninstall.d.ts +0 -2
  87. package/dist/commands/uninstall.d.ts.map +0 -1
  88. package/dist/commands/uninstall.js +0 -43
  89. package/dist/commands/uninstall.js.map +0 -1
  90. package/dist/commands/update.d.ts +0 -2
  91. package/dist/commands/update.d.ts.map +0 -1
  92. package/dist/commands/update.js +0 -58
  93. package/dist/commands/update.js.map +0 -1
  94. package/dist/configure/claude-code.d.ts +0 -7
  95. package/dist/configure/claude-code.d.ts.map +0 -1
  96. package/dist/configure/claude-code.js +0 -11
  97. package/dist/configure/claude-code.js.map +0 -1
  98. package/dist/configure/claude-desktop.d.ts +0 -8
  99. package/dist/configure/claude-desktop.d.ts.map +0 -1
  100. package/dist/configure/claude-desktop.js +0 -28
  101. package/dist/configure/claude-desktop.js.map +0 -1
  102. package/dist/configure/codex.d.ts +0 -7
  103. package/dist/configure/codex.d.ts.map +0 -1
  104. package/dist/configure/codex.js +0 -12
  105. package/dist/configure/codex.js.map +0 -1
  106. package/dist/configure/cursor.d.ts +0 -7
  107. package/dist/configure/cursor.d.ts.map +0 -1
  108. package/dist/configure/cursor.js +0 -12
  109. package/dist/configure/cursor.js.map +0 -1
  110. package/dist/configure/index.d.ts +0 -34
  111. package/dist/configure/index.d.ts.map +0 -1
  112. package/dist/configure/index.js +0 -153
  113. package/dist/configure/index.js.map +0 -1
  114. package/dist/detect/claude-code.d.ts +0 -3
  115. package/dist/detect/claude-code.d.ts.map +0 -1
  116. package/dist/detect/claude-code.js +0 -82
  117. package/dist/detect/claude-code.js.map +0 -1
  118. package/dist/detect/claude-desktop.d.ts +0 -3
  119. package/dist/detect/claude-desktop.d.ts.map +0 -1
  120. package/dist/detect/claude-desktop.js +0 -89
  121. package/dist/detect/claude-desktop.js.map +0 -1
  122. package/dist/detect/codex.d.ts +0 -3
  123. package/dist/detect/codex.d.ts.map +0 -1
  124. package/dist/detect/codex.js +0 -64
  125. package/dist/detect/codex.js.map +0 -1
  126. package/dist/detect/cursor.d.ts +0 -3
  127. package/dist/detect/cursor.d.ts.map +0 -1
  128. package/dist/detect/cursor.js +0 -81
  129. package/dist/detect/cursor.js.map +0 -1
  130. package/dist/detect/index.d.ts +0 -3
  131. package/dist/detect/index.d.ts.map +0 -1
  132. package/dist/detect/index.js +0 -28
  133. package/dist/detect/index.js.map +0 -1
  134. package/dist/import/file-upload.d.ts +0 -10
  135. package/dist/import/file-upload.d.ts.map +0 -1
  136. package/dist/import/file-upload.js +0 -37
  137. package/dist/import/file-upload.js.map +0 -1
  138. package/dist/import/index.d.ts +0 -11
  139. package/dist/import/index.d.ts.map +0 -1
  140. package/dist/import/index.js +0 -51
  141. package/dist/import/index.js.map +0 -1
  142. package/dist/mcp/exports.d.ts +0 -13
  143. package/dist/mcp/exports.d.ts.map +0 -1
  144. package/dist/mcp/exports.js +0 -13
  145. package/dist/mcp/exports.js.map +0 -1
  146. package/dist/mcp/git-context.d.ts +0 -17
  147. package/dist/mcp/git-context.d.ts.map +0 -1
  148. package/dist/mcp/git-context.js +0 -72
  149. package/dist/mcp/git-context.js.map +0 -1
  150. package/dist/mcp/hooks/anthropic.d.ts +0 -31
  151. package/dist/mcp/hooks/anthropic.d.ts.map +0 -1
  152. package/dist/mcp/hooks/anthropic.js +0 -137
  153. package/dist/mcp/hooks/anthropic.js.map +0 -1
  154. package/dist/mcp/hooks/google.d.ts +0 -53
  155. package/dist/mcp/hooks/google.d.ts.map +0 -1
  156. package/dist/mcp/hooks/google.js +0 -161
  157. package/dist/mcp/hooks/google.js.map +0 -1
  158. package/dist/mcp/hooks/index.d.ts +0 -9
  159. package/dist/mcp/hooks/index.d.ts.map +0 -1
  160. package/dist/mcp/hooks/index.js +0 -7
  161. package/dist/mcp/hooks/index.js.map +0 -1
  162. package/dist/mcp/hooks/openai.d.ts +0 -59
  163. package/dist/mcp/hooks/openai.d.ts.map +0 -1
  164. package/dist/mcp/hooks/openai.js +0 -158
  165. package/dist/mcp/hooks/openai.js.map +0 -1
  166. package/dist/mcp/hooks/types.d.ts +0 -8
  167. package/dist/mcp/hooks/types.d.ts.map +0 -1
  168. package/dist/mcp/hooks/types.js +0 -5
  169. package/dist/mcp/hooks/types.js.map +0 -1
  170. package/dist/mcp/ingestor.d.ts +0 -23
  171. package/dist/mcp/ingestor.d.ts.map +0 -1
  172. package/dist/mcp/ingestor.js +0 -310
  173. package/dist/mcp/ingestor.js.map +0 -1
  174. package/dist/mcp/pricing.d.ts +0 -19
  175. package/dist/mcp/pricing.d.ts.map +0 -1
  176. package/dist/mcp/pricing.js +0 -130
  177. package/dist/mcp/pricing.js.map +0 -1
  178. package/dist/mcp/server.d.ts +0 -10
  179. package/dist/mcp/server.d.ts.map +0 -1
  180. package/dist/mcp/server.js +0 -689
  181. package/dist/mcp/server.js.map +0 -1
  182. package/dist/mcp/session-tracker.d.ts +0 -52
  183. package/dist/mcp/session-tracker.d.ts.map +0 -1
  184. package/dist/mcp/session-tracker.js +0 -186
  185. package/dist/mcp/session-tracker.js.map +0 -1
  186. package/dist/mcp/tools/analyze-spending-trend.d.ts +0 -10
  187. package/dist/mcp/tools/analyze-spending-trend.d.ts.map +0 -1
  188. package/dist/mcp/tools/analyze-spending-trend.js +0 -126
  189. package/dist/mcp/tools/analyze-spending-trend.js.map +0 -1
  190. package/dist/mcp/tools/get-budget-status.d.ts +0 -9
  191. package/dist/mcp/tools/get-budget-status.d.ts.map +0 -1
  192. package/dist/mcp/tools/get-budget-status.js +0 -59
  193. package/dist/mcp/tools/get-budget-status.js.map +0 -1
  194. package/dist/mcp/tools/get-cost-breakdown.d.ts +0 -10
  195. package/dist/mcp/tools/get-cost-breakdown.d.ts.map +0 -1
  196. package/dist/mcp/tools/get-cost-breakdown.js +0 -52
  197. package/dist/mcp/tools/get-cost-breakdown.js.map +0 -1
  198. package/dist/mcp/tools/get-model-efficiency.d.ts +0 -9
  199. package/dist/mcp/tools/get-model-efficiency.d.ts.map +0 -1
  200. package/dist/mcp/tools/get-model-efficiency.js +0 -137
  201. package/dist/mcp/tools/get-model-efficiency.js.map +0 -1
  202. package/dist/mcp/tools/get-recent-prompts.d.ts +0 -13
  203. package/dist/mcp/tools/get-recent-prompts.d.ts.map +0 -1
  204. package/dist/mcp/tools/get-recent-prompts.js +0 -56
  205. package/dist/mcp/tools/get-recent-prompts.js.map +0 -1
  206. package/dist/mcp/tools/get-roi-metrics.d.ts +0 -9
  207. package/dist/mcp/tools/get-roi-metrics.d.ts.map +0 -1
  208. package/dist/mcp/tools/get-roi-metrics.js +0 -84
  209. package/dist/mcp/tools/get-roi-metrics.js.map +0 -1
  210. package/dist/mcp/tools/get-usage-summary.d.ts +0 -10
  211. package/dist/mcp/tools/get-usage-summary.d.ts.map +0 -1
  212. package/dist/mcp/tools/get-usage-summary.js +0 -47
  213. package/dist/mcp/tools/get-usage-summary.js.map +0 -1
  214. package/dist/mcp/tools/index.d.ts +0 -221
  215. package/dist/mcp/tools/index.d.ts.map +0 -1
  216. package/dist/mcp/tools/index.js +0 -161
  217. package/dist/mcp/tools/index.js.map +0 -1
  218. package/dist/mcp/tools/list-projects.d.ts +0 -6
  219. package/dist/mcp/tools/list-projects.d.ts.map +0 -1
  220. package/dist/mcp/tools/list-projects.js +0 -43
  221. package/dist/mcp/tools/list-projects.js.map +0 -1
  222. package/dist/mcp/tools/optimize-prompt.d.ts +0 -44
  223. package/dist/mcp/tools/optimize-prompt.d.ts.map +0 -1
  224. package/dist/mcp/tools/optimize-prompt.js +0 -95
  225. package/dist/mcp/tools/optimize-prompt.js.map +0 -1
  226. package/dist/mcp/types.d.ts +0 -118
  227. package/dist/mcp/types.d.ts.map +0 -1
  228. package/dist/mcp/types.js +0 -5
  229. package/dist/mcp/types.js.map +0 -1
  230. package/dist/types.d.ts +0 -18
  231. package/dist/types.d.ts.map +0 -1
  232. package/dist/types.js +0 -2
  233. package/dist/types.js.map +0 -1
  234. package/dist/update-check/check.d.ts +0 -6
  235. package/dist/update-check/check.d.ts.map +0 -1
  236. package/dist/update-check/check.js +0 -64
  237. package/dist/update-check/check.js.map +0 -1
  238. package/dist/update-check/notify.d.ts +0 -6
  239. package/dist/update-check/notify.d.ts.map +0 -1
  240. package/dist/update-check/notify.js +0 -40
  241. package/dist/update-check/notify.js.map +0 -1
  242. package/dist/verify.d.ts +0 -7
  243. package/dist/verify.d.ts.map +0 -1
  244. package/dist/verify.js +0 -40
  245. package/dist/verify.js.map +0 -1
  246. package/dist/version.d.ts +0 -9
  247. package/dist/version.d.ts.map +0 -1
  248. package/dist/version.js +0 -21
  249. package/dist/version.js.map +0 -1
@@ -1,7 +0,0 @@
1
- import type { Credentials, DetectionResult } from '../types.js';
2
- /**
3
- * Configures the Verbal MCP server in Cursor IDE.
4
- * Writes to ~/.cursor/mcp.json, preserving any existing MCP server entries.
5
- */
6
- export declare function configureCursor(_detection: DetectionResult, credentials: Credentials, billingType?: 'api' | 'subscription', useGlobal?: boolean): Promise<void>;
7
- //# sourceMappingURL=cursor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/configure/cursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhE;;;GAGG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,KAAK,GAAG,cAAc,EACpC,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -1,12 +0,0 @@
1
- import { homedir } from 'node:os';
2
- import { join } from 'node:path';
3
- import { mergeConfig } from './index.js';
4
- /**
5
- * Configures the Verbal MCP server in Cursor IDE.
6
- * Writes to ~/.cursor/mcp.json, preserving any existing MCP server entries.
7
- */
8
- export async function configureCursor(_detection, credentials, billingType, useGlobal = false) {
9
- const configPath = join(homedir(), '.cursor', 'mcp.json');
10
- mergeConfig(configPath, credentials, billingType, useGlobal);
11
- }
12
- //# sourceMappingURL=cursor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/configure/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAA2B,EAC3B,WAAwB,EACxB,WAAoC,EACpC,YAAqB,KAAK;IAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC1D,WAAW,CAAC,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;AAC/D,CAAC"}
@@ -1,34 +0,0 @@
1
- import type { Credentials, DetectionResult } from '../types.js';
2
- export interface ConfigureResult {
3
- tool: string;
4
- success: boolean;
5
- error?: string;
6
- }
7
- /**
8
- * Builds the verbal MCP server entry object from credentials.
9
- *
10
- * When useGlobal=true the entry invokes the globally installed `getverbal`
11
- * binary directly. When useGlobal=false (default) it falls back to npx so
12
- * the command works even without a global install.
13
- */
14
- export declare function buildVerbalMcpEntry(credentials: Credentials, billingType?: 'api' | 'subscription', useGlobal?: boolean): Record<string, unknown>;
15
- /**
16
- * Safely reads an existing config file, merges in the verbal MCP entry,
17
- * and writes it back atomically using a .tmp file + rename.
18
- *
19
- * Only the mcpServers.verbal key is overwritten; all other keys are preserved.
20
- */
21
- export declare function mergeConfig(configPath: string, credentials: Credentials, billingType?: 'api' | 'subscription', useGlobal?: boolean): void;
22
- /**
23
- * Removes the mcpServers.verbal key from a config file.
24
- * If removing it leaves mcpServers empty, removes mcpServers too.
25
- * No-op if the file doesn't exist or has no verbal entry.
26
- */
27
- export declare function removeVerbalConfig(configPath: string): void;
28
- /**
29
- * Configures all detected AI tools with the Verbal MCP server.
30
- * Skips tools where detected === false.
31
- * Returns a results array — never throws on individual failures.
32
- */
33
- export declare function configureAll(detections: DetectionResult[], credentials: Credentials, useGlobal?: boolean): Promise<ConfigureResult[]>;
34
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/configure/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAahE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,EACxB,WAAW,GAAE,KAAK,GAAG,cAAsB,EAC3C,SAAS,GAAE,OAAe,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBzB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,KAAK,GAAG,cAAc,EACpC,SAAS,GAAE,OAAe,GACzB,IAAI,CA+BN;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CA0C3D;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,eAAe,EAAE,EAC7B,WAAW,EAAE,WAAW,EACxB,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,eAAe,EAAE,CAAC,CAyC5B"}
@@ -1,153 +0,0 @@
1
- import { mkdirSync, readFileSync, renameSync, writeFileSync, existsSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { configureClaudeCode } from './claude-code.js';
4
- import { configureClaudeDesktop } from './claude-desktop.js';
5
- import { configureCursor } from './cursor.js';
6
- import { configureCodex } from './codex.js';
7
- const TOOL_DEFAULT_BILLING_TYPE = {
8
- 'claude-code': 'api',
9
- 'claude-desktop': 'subscription',
10
- 'cursor': 'subscription',
11
- 'codex': 'api',
12
- };
13
- /**
14
- * Builds the verbal MCP server entry object from credentials.
15
- *
16
- * When useGlobal=true the entry invokes the globally installed `getverbal`
17
- * binary directly. When useGlobal=false (default) it falls back to npx so
18
- * the command works even without a global install.
19
- */
20
- export function buildVerbalMcpEntry(credentials, billingType = 'api', useGlobal = false) {
21
- return {
22
- command: useGlobal ? 'getverbal' : 'npx',
23
- args: useGlobal ? ['mcp-serve'] : ['-y', 'getverbal', 'mcp-serve'],
24
- env: {
25
- VERBAL_API_KEY: credentials.api_key,
26
- VERBAL_API_URL: credentials.api_url,
27
- VERBAL_INGEST_URL: credentials.ingest_url,
28
- VERBAL_SOURCE: 'mcp',
29
- VERBAL_CAPTURE_MODE: 'full',
30
- VERBAL_TRACE_ENABLED: 'true',
31
- VERBAL_GIT_CONTEXT_ENABLED: 'true',
32
- VERBAL_COST_CALC_ENABLED: 'true',
33
- VERBAL_BILLING_TYPE: billingType,
34
- },
35
- };
36
- }
37
- /**
38
- * Safely reads an existing config file, merges in the verbal MCP entry,
39
- * and writes it back atomically using a .tmp file + rename.
40
- *
41
- * Only the mcpServers.verbal key is overwritten; all other keys are preserved.
42
- */
43
- export function mergeConfig(configPath, credentials, billingType, useGlobal = false) {
44
- // Ensure parent directories exist
45
- mkdirSync(dirname(configPath), { recursive: true });
46
- // Read existing config or start fresh
47
- let config = {};
48
- if (existsSync(configPath)) {
49
- try {
50
- config = JSON.parse(readFileSync(configPath, 'utf-8'));
51
- }
52
- catch {
53
- // Malformed JSON — start fresh rather than bail out
54
- config = {};
55
- }
56
- }
57
- // Ensure mcpServers key exists
58
- if (config['mcpServers'] === undefined || config['mcpServers'] === null || typeof config['mcpServers'] !== 'object') {
59
- config['mcpServers'] = {};
60
- }
61
- // Set only the verbal entry — preserve all other MCP server configs
62
- config['mcpServers']['verbal'] = buildVerbalMcpEntry(credentials, billingType, useGlobal);
63
- // Atomic write: write to .tmp then rename
64
- const tmpPath = `${configPath}.tmp`;
65
- writeFileSync(tmpPath, JSON.stringify(config, null, 2), 'utf-8');
66
- renameSync(tmpPath, configPath);
67
- }
68
- /**
69
- * Removes the mcpServers.verbal key from a config file.
70
- * If removing it leaves mcpServers empty, removes mcpServers too.
71
- * No-op if the file doesn't exist or has no verbal entry.
72
- */
73
- export function removeVerbalConfig(configPath) {
74
- const resolvedPath = resolve(configPath);
75
- // 1. Read the config file — return silently if not found
76
- if (!existsSync(resolvedPath)) {
77
- return;
78
- }
79
- let config;
80
- try {
81
- config = JSON.parse(readFileSync(resolvedPath, 'utf-8'));
82
- }
83
- catch {
84
- // Malformed JSON — nothing safe to do, leave it alone
85
- return;
86
- }
87
- // 2. Remove mcpServers.verbal if it exists
88
- if (config['mcpServers'] !== undefined &&
89
- config['mcpServers'] !== null &&
90
- typeof config['mcpServers'] === 'object') {
91
- const mcpServers = config['mcpServers'];
92
- if (!Object.prototype.hasOwnProperty.call(mcpServers, 'verbal')) {
93
- // No verbal entry — nothing to do
94
- return;
95
- }
96
- delete mcpServers['verbal'];
97
- // 3. If mcpServers is now empty, remove the key entirely
98
- if (Object.keys(mcpServers).length === 0) {
99
- delete config['mcpServers'];
100
- }
101
- }
102
- else {
103
- // No mcpServers section — nothing to do
104
- return;
105
- }
106
- // 4. Atomic write: tmp + rename
107
- const tmpPath = `${resolvedPath}.tmp`;
108
- writeFileSync(tmpPath, JSON.stringify(config, null, 2), 'utf-8');
109
- renameSync(tmpPath, resolvedPath);
110
- }
111
- /**
112
- * Configures all detected AI tools with the Verbal MCP server.
113
- * Skips tools where detected === false.
114
- * Returns a results array — never throws on individual failures.
115
- */
116
- export async function configureAll(detections, credentials, useGlobal = false) {
117
- const results = [];
118
- for (const detection of detections) {
119
- if (!detection.detected) {
120
- continue;
121
- }
122
- let success = false;
123
- let error;
124
- const billingType = TOOL_DEFAULT_BILLING_TYPE[detection.tool] ?? 'api';
125
- try {
126
- switch (detection.tool) {
127
- case 'claude-code':
128
- await configureClaudeCode(detection, credentials, billingType, useGlobal);
129
- break;
130
- case 'claude-desktop':
131
- await configureClaudeDesktop(detection, credentials, billingType, useGlobal);
132
- break;
133
- case 'cursor':
134
- await configureCursor(detection, credentials, billingType, useGlobal);
135
- break;
136
- case 'codex':
137
- await configureCodex(detection, credentials, billingType, useGlobal);
138
- break;
139
- default: {
140
- const _exhaustive = detection.tool;
141
- throw new Error(`Unknown tool: ${String(_exhaustive)}`);
142
- }
143
- }
144
- success = true;
145
- }
146
- catch (err) {
147
- error = err instanceof Error ? err.message : String(err);
148
- }
149
- results.push({ tool: detection.tool, success, error });
150
- }
151
- return results;
152
- }
153
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/configure/index.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { DetectionResult } from '../types.js';
2
- export declare function detectClaudeCode(): Promise<DetectionResult>;
3
- //# sourceMappingURL=claude-code.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC,CAiFjE"}
@@ -1,82 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
- import { execSync } from 'node:child_process';
5
- export async function detectClaudeCode() {
6
- const configPath = join(process.cwd(), '.mcp.json');
7
- try {
8
- // Check for claude binary
9
- let binaryPath;
10
- let version;
11
- try {
12
- binaryPath = execSync('which claude', { encoding: 'utf-8', timeout: 5000 }).trim();
13
- }
14
- catch {
15
- // Binary not in PATH
16
- }
17
- // Check for ~/.claude/ directory
18
- const claudeDir = join(homedir(), '.claude');
19
- const hasClaudioDir = existsSync(claudeDir);
20
- const detected = binaryPath !== undefined || hasClaudioDir;
21
- if (!detected) {
22
- return {
23
- tool: 'claude-code',
24
- detected: false,
25
- configPath,
26
- existingConfig: false,
27
- details: 'Claude Code not found',
28
- };
29
- }
30
- // Try to get version
31
- if (binaryPath) {
32
- try {
33
- const versionOutput = execSync('claude --version', { encoding: 'utf-8', timeout: 5000 }).trim();
34
- // Output is typically "Claude Code v1.2.3" or just "1.2.3"
35
- const match = versionOutput.match(/(\d+\.\d+\.\d+)/);
36
- if (match) {
37
- version = match[1];
38
- }
39
- }
40
- catch {
41
- // Version check failed — non-fatal
42
- }
43
- }
44
- // Check if .mcp.json already has mcpServers.verbal
45
- let existingConfig = false;
46
- if (existsSync(configPath)) {
47
- try {
48
- const raw = readFileSync(configPath, 'utf-8');
49
- const parsed = JSON.parse(raw);
50
- const mcpServers = parsed['mcpServers'];
51
- if (mcpServers !== null && typeof mcpServers === 'object') {
52
- existingConfig = 'verbal' in mcpServers;
53
- }
54
- }
55
- catch {
56
- // Malformed JSON — treat as no existing config
57
- }
58
- }
59
- const location = binaryPath ?? claudeDir;
60
- const details = version
61
- ? `Claude Code v${version} at ${location}`
62
- : `Claude Code at ${location}`;
63
- return {
64
- tool: 'claude-code',
65
- detected: true,
66
- version,
67
- configPath,
68
- existingConfig,
69
- details,
70
- };
71
- }
72
- catch {
73
- return {
74
- tool: 'claude-code',
75
- detected: false,
76
- configPath,
77
- existingConfig: false,
78
- details: 'Claude Code detection failed',
79
- };
80
- }
81
- }
82
- //# sourceMappingURL=claude-code.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,UAA8B,CAAC;QACnC,IAAI,OAA2B,CAAC;QAEhC,IAAI,CAAC;YACH,UAAU,GAAG,QAAQ,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrF,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;QAED,iCAAiC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;QAC7C,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,UAAU,KAAK,SAAS,IAAI,aAAa,CAAC;QAE3D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;gBACL,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,KAAK;gBACf,UAAU;gBACV,cAAc,EAAE,KAAK;gBACrB,OAAO,EAAE,uBAAuB;aACjC,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,QAAQ,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChG,2DAA2D;gBAC3D,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACrD,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;YACrC,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;gBAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;gBACxC,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBAC1D,cAAc,GAAG,QAAQ,IAAK,UAAsC,CAAC;gBACvE,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,+CAA+C;YACjD,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,IAAI,SAAS,CAAC;QACzC,MAAM,OAAO,GAAG,OAAO;YACrB,CAAC,CAAC,gBAAgB,OAAO,OAAO,QAAQ,EAAE;YAC1C,CAAC,CAAC,kBAAkB,QAAQ,EAAE,CAAC;QAEjC,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,IAAI;YACd,OAAO;YACP,UAAU;YACV,cAAc;YACd,OAAO;SACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,KAAK;YACf,UAAU;YACV,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,8BAA8B;SACxC,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { DetectionResult } from '../types.js';
2
- export declare function detectClaudeDesktop(): Promise<DetectionResult>;
3
- //# sourceMappingURL=claude-desktop.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-desktop.d.ts","sourceRoot":"","sources":["../../src/detect/claude-desktop.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA6CnD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,CAAC,CA+CpE"}
@@ -1,89 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
- import { execSync } from 'node:child_process';
5
- function getConfigPath() {
6
- const platform = process.platform;
7
- if (platform === 'darwin') {
8
- return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
9
- }
10
- if (platform === 'win32') {
11
- return join(process.env['APPDATA'] ?? homedir(), 'Claude', 'claude_desktop_config.json');
12
- }
13
- // Linux
14
- return join(homedir(), '.config', 'claude', 'claude_desktop_config.json');
15
- }
16
- function isInstalled() {
17
- const platform = process.platform;
18
- if (platform === 'darwin') {
19
- return (existsSync('/Applications/Claude.app') ||
20
- existsSync(join(homedir(), 'Applications', 'Claude.app')));
21
- }
22
- if (platform === 'win32') {
23
- const localAppData = process.env['LOCALAPPDATA'] ?? join(homedir(), 'AppData', 'Local');
24
- return existsSync(join(localAppData, 'Programs', 'Claude', 'Claude.exe'));
25
- }
26
- // Linux — check for claude-desktop binary in PATH
27
- try {
28
- execSync('which claude-desktop', { encoding: 'utf-8', timeout: 5000 });
29
- return true;
30
- }
31
- catch {
32
- return false;
33
- }
34
- }
35
- function platformLabel() {
36
- const platform = process.platform;
37
- if (platform === 'darwin')
38
- return 'macOS app';
39
- if (platform === 'win32')
40
- return 'Windows app';
41
- return 'Linux';
42
- }
43
- export async function detectClaudeDesktop() {
44
- const configPath = getConfigPath();
45
- try {
46
- const detected = isInstalled();
47
- if (!detected) {
48
- return {
49
- tool: 'claude-desktop',
50
- detected: false,
51
- configPath,
52
- existingConfig: false,
53
- details: 'Claude Desktop not found',
54
- };
55
- }
56
- // Check if config already has mcpServers.verbal
57
- let existingConfig = false;
58
- if (existsSync(configPath)) {
59
- try {
60
- const raw = readFileSync(configPath, 'utf-8');
61
- const parsed = JSON.parse(raw);
62
- const mcpServers = parsed['mcpServers'];
63
- if (mcpServers !== null && typeof mcpServers === 'object') {
64
- existingConfig = 'verbal' in mcpServers;
65
- }
66
- }
67
- catch {
68
- // Malformed JSON — treat as no existing config
69
- }
70
- }
71
- return {
72
- tool: 'claude-desktop',
73
- detected: true,
74
- configPath,
75
- existingConfig,
76
- details: `Claude Desktop (${platformLabel()})`,
77
- };
78
- }
79
- catch {
80
- return {
81
- tool: 'claude-desktop',
82
- detected: false,
83
- configPath,
84
- existingConfig: false,
85
- details: 'Claude Desktop detection failed',
86
- };
87
- }
88
- }
89
- //# sourceMappingURL=claude-desktop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-desktop.js","sourceRoot":"","sources":["../../src/detect/claude-desktop.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { DetectionResult } from '../types.js';
2
- export declare function detectCodex(): Promise<DetectionResult>;
3
- //# sourceMappingURL=codex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/detect/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,CA+D5D"}
@@ -1,64 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
- import { execSync } from 'node:child_process';
5
- export async function detectCodex() {
6
- const configPath = join(homedir(), '.codex', 'config.json');
7
- try {
8
- // Check for codex binary in PATH
9
- let binaryPath;
10
- try {
11
- binaryPath = execSync('which codex', { encoding: 'utf-8', timeout: 5000 }).trim();
12
- }
13
- catch {
14
- // Binary not in PATH
15
- }
16
- // Check for ~/.codex/ directory
17
- const codexDir = join(homedir(), '.codex');
18
- const hasCodexDir = existsSync(codexDir);
19
- const detected = binaryPath !== undefined || hasCodexDir;
20
- if (!detected) {
21
- return {
22
- tool: 'codex',
23
- detected: false,
24
- configPath,
25
- existingConfig: false,
26
- details: 'Codex CLI not found',
27
- };
28
- }
29
- // Check if ~/.codex/config.json already has mcpServers.verbal
30
- let existingConfig = false;
31
- if (existsSync(configPath)) {
32
- try {
33
- const raw = readFileSync(configPath, 'utf-8');
34
- const parsed = JSON.parse(raw);
35
- const mcpServers = parsed['mcpServers'];
36
- if (mcpServers !== null && typeof mcpServers === 'object') {
37
- existingConfig = 'verbal' in mcpServers;
38
- }
39
- }
40
- catch {
41
- // Malformed JSON — treat as no existing config
42
- }
43
- }
44
- const location = binaryPath ?? codexDir;
45
- const details = `Codex CLI at ${location}`;
46
- return {
47
- tool: 'codex',
48
- detected: true,
49
- configPath,
50
- existingConfig,
51
- details,
52
- };
53
- }
54
- catch {
55
- return {
56
- tool: 'codex',
57
- detected: false,
58
- configPath,
59
- existingConfig: false,
60
- details: 'Codex CLI detection failed',
61
- };
62
- }
63
- }
64
- //# sourceMappingURL=codex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/detect/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,iCAAiC;QACjC,IAAI,UAA8B,CAAC;QAEnC,IAAI,CAAC;YACH,UAAU,GAAG,QAAQ,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;QAED,gCAAgC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEzC,MAAM,QAAQ,GAAG,UAAU,KAAK,SAAS,IAAI,WAAW,CAAC;QAEzD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,KAAK;gBACf,UAAU;gBACV,cAAc,EAAE,KAAK;gBACrB,OAAO,EAAE,qBAAqB;aAC/B,CAAC;QACJ,CAAC;QAED,8DAA8D;QAC9D,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;gBAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;gBACxC,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBAC1D,cAAc,GAAG,QAAQ,IAAK,UAAsC,CAAC;gBACvE,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,+CAA+C;YACjD,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,IAAI,QAAQ,CAAC;QACxC,MAAM,OAAO,GAAG,gBAAgB,QAAQ,EAAE,CAAC;QAE3C,OAAO;YACL,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,IAAI;YACd,UAAU;YACV,cAAc;YACd,OAAO;SACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,KAAK;YACf,UAAU;YACV,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,4BAA4B;SACtC,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { DetectionResult } from '../types.js';
2
- export declare function detectCursor(): Promise<DetectionResult>;
3
- //# sourceMappingURL=cursor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/detect/cursor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CAgF7D"}
@@ -1,81 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
- import { execSync } from 'node:child_process';
5
- export async function detectCursor() {
6
- const configPath = join(homedir(), '.cursor', 'mcp.json');
7
- try {
8
- // Check for cursor binary in PATH
9
- let binaryPath;
10
- let version;
11
- try {
12
- binaryPath = execSync('which cursor', { encoding: 'utf-8', timeout: 5000 }).trim();
13
- }
14
- catch {
15
- // Binary not in PATH
16
- }
17
- // Check for ~/.cursor/ directory
18
- const cursorDir = join(homedir(), '.cursor');
19
- const hasCursorDir = existsSync(cursorDir);
20
- const detected = binaryPath !== undefined || hasCursorDir;
21
- if (!detected) {
22
- return {
23
- tool: 'cursor',
24
- detected: false,
25
- configPath,
26
- existingConfig: false,
27
- details: 'Cursor not found',
28
- };
29
- }
30
- // Try to get version
31
- if (binaryPath) {
32
- try {
33
- const versionOutput = execSync('cursor --version', { encoding: 'utf-8', timeout: 5000 }).trim();
34
- const match = versionOutput.match(/(\d+\.\d+\.\d+)/);
35
- if (match) {
36
- version = match[1];
37
- }
38
- }
39
- catch {
40
- // Version check failed — non-fatal
41
- }
42
- }
43
- // Check if ~/.cursor/mcp.json already has mcpServers.verbal
44
- let existingConfig = false;
45
- if (existsSync(configPath)) {
46
- try {
47
- const raw = readFileSync(configPath, 'utf-8');
48
- const parsed = JSON.parse(raw);
49
- const mcpServers = parsed['mcpServers'];
50
- if (mcpServers !== null && typeof mcpServers === 'object') {
51
- existingConfig = 'verbal' in mcpServers;
52
- }
53
- }
54
- catch {
55
- // Malformed JSON — treat as no existing config
56
- }
57
- }
58
- const location = binaryPath ?? cursorDir;
59
- const details = version
60
- ? `Cursor v${version} at ${location}`
61
- : `Cursor at ${location}`;
62
- return {
63
- tool: 'cursor',
64
- detected: true,
65
- version,
66
- configPath,
67
- existingConfig,
68
- details,
69
- };
70
- }
71
- catch {
72
- return {
73
- tool: 'cursor',
74
- detected: false,
75
- configPath,
76
- existingConfig: false,
77
- details: 'Cursor detection failed',
78
- };
79
- }
80
- }
81
- //# sourceMappingURL=cursor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/detect/cursor.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { DetectionResult } from '../types.js';
2
- export declare function detectAll(): Promise<DetectionResult[]>;
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detect/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,wBAAsB,SAAS,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAuB5D"}
@@ -1,28 +0,0 @@
1
- import { detectClaudeCode } from './claude-code.js';
2
- import { detectClaudeDesktop } from './claude-desktop.js';
3
- import { detectCursor } from './cursor.js';
4
- import { detectCodex } from './codex.js';
5
- export async function detectAll() {
6
- const results = await Promise.allSettled([
7
- detectClaudeCode(),
8
- detectClaudeDesktop(),
9
- detectCursor(),
10
- detectCodex(),
11
- ]);
12
- return results.map((result, index) => {
13
- if (result.status === 'fulfilled') {
14
- return result.value;
15
- }
16
- // A detector itself threw — return a safe fallback per tool
17
- const tools = ['claude-code', 'claude-desktop', 'cursor', 'codex'];
18
- const tool = tools[index];
19
- return {
20
- tool,
21
- detected: false,
22
- configPath: '',
23
- existingConfig: false,
24
- details: `${tool} detection error: ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`,
25
- };
26
- });
27
- }
28
- //# sourceMappingURL=index.js.map