@getverbal/cli 0.7.0 → 0.8.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/agent-hooks/claude.d.ts +10 -0
  2. package/dist/agent-hooks/claude.d.ts.map +1 -0
  3. package/dist/agent-hooks/claude.js +218 -0
  4. package/dist/agent-hooks/claude.js.map +1 -0
  5. package/dist/agent-hooks/cli.d.ts +2 -0
  6. package/dist/agent-hooks/cli.d.ts.map +1 -0
  7. package/dist/agent-hooks/cli.js +271 -0
  8. package/dist/agent-hooks/cli.js.map +1 -0
  9. package/dist/agent-hooks/codex.d.ts +9 -0
  10. package/dist/agent-hooks/codex.d.ts.map +1 -0
  11. package/dist/agent-hooks/codex.js +349 -0
  12. package/dist/agent-hooks/codex.js.map +1 -0
  13. package/dist/agent-hooks/config.d.ts +32 -0
  14. package/dist/agent-hooks/config.d.ts.map +1 -0
  15. package/dist/agent-hooks/config.js +176 -0
  16. package/dist/agent-hooks/config.js.map +1 -0
  17. package/dist/agent-hooks/ingest.d.ts +4 -0
  18. package/dist/agent-hooks/ingest.d.ts.map +1 -0
  19. package/dist/agent-hooks/ingest.js +22 -0
  20. package/dist/agent-hooks/ingest.js.map +1 -0
  21. package/dist/agent-hooks/launchagent.d.ts +7 -0
  22. package/dist/agent-hooks/launchagent.d.ts.map +1 -0
  23. package/dist/agent-hooks/launchagent.js +51 -0
  24. package/dist/agent-hooks/launchagent.js.map +1 -0
  25. package/dist/agent-hooks/runtime-context.d.ts +20 -0
  26. package/dist/agent-hooks/runtime-context.d.ts.map +1 -0
  27. package/dist/agent-hooks/runtime-context.js +90 -0
  28. package/dist/agent-hooks/runtime-context.js.map +1 -0
  29. package/dist/agent-hooks/state.d.ts +26 -0
  30. package/dist/agent-hooks/state.d.ts.map +1 -0
  31. package/dist/agent-hooks/state.js +67 -0
  32. package/dist/agent-hooks/state.js.map +1 -0
  33. package/dist/agent-hooks/tokscale.d.ts +70 -0
  34. package/dist/agent-hooks/tokscale.d.ts.map +1 -0
  35. package/dist/agent-hooks/tokscale.js +142 -0
  36. package/dist/agent-hooks/tokscale.js.map +1 -0
  37. package/dist/agent-hooks/tool-extraction.d.ts +7 -0
  38. package/dist/agent-hooks/tool-extraction.d.ts.map +1 -0
  39. package/dist/agent-hooks/tool-extraction.js +100 -0
  40. package/dist/agent-hooks/tool-extraction.js.map +1 -0
  41. package/dist/agent-hooks/trace.d.ts +17 -0
  42. package/dist/agent-hooks/trace.d.ts.map +1 -0
  43. package/dist/agent-hooks/trace.js +25 -0
  44. package/dist/agent-hooks/trace.js.map +1 -0
  45. package/dist/auth/browser-auth.d.ts +6 -0
  46. package/dist/auth/browser-auth.d.ts.map +1 -0
  47. package/dist/auth/browser-auth.js +202 -0
  48. package/dist/auth/browser-auth.js.map +1 -0
  49. package/dist/auth/credentials.d.ts +6 -0
  50. package/dist/auth/credentials.d.ts.map +1 -0
  51. package/dist/auth/credentials.js +78 -0
  52. package/dist/auth/credentials.js.map +1 -0
  53. package/dist/cli.d.ts +3 -0
  54. package/dist/cli.d.ts.map +1 -0
  55. package/dist/cli.js +550 -148
  56. package/dist/cli.js.map +1 -0
  57. package/dist/commands/dashboard.d.ts +2 -0
  58. package/dist/commands/dashboard.d.ts.map +1 -0
  59. package/dist/commands/dashboard.js +19 -0
  60. package/dist/commands/dashboard.js.map +1 -0
  61. package/dist/commands/hooks.d.ts +2 -0
  62. package/dist/commands/hooks.d.ts.map +1 -0
  63. package/dist/commands/hooks.js +6 -0
  64. package/dist/commands/hooks.js.map +1 -0
  65. package/dist/commands/import.d.ts +2 -0
  66. package/dist/commands/import.d.ts.map +1 -0
  67. package/dist/commands/import.js +129 -0
  68. package/dist/commands/import.js.map +1 -0
  69. package/dist/commands/init.d.ts +2 -0
  70. package/dist/commands/init.d.ts.map +1 -0
  71. package/dist/commands/init.js +262 -0
  72. package/dist/commands/init.js.map +1 -0
  73. package/dist/commands/logout.d.ts +2 -0
  74. package/dist/commands/logout.d.ts.map +1 -0
  75. package/dist/commands/logout.js +17 -0
  76. package/dist/commands/logout.js.map +1 -0
  77. package/dist/commands/mcp-serve.d.ts +2 -0
  78. package/dist/commands/mcp-serve.d.ts.map +1 -0
  79. package/dist/commands/mcp-serve.js +7 -0
  80. package/dist/commands/mcp-serve.js.map +1 -0
  81. package/dist/commands/status.d.ts +2 -0
  82. package/dist/commands/status.d.ts.map +1 -0
  83. package/dist/commands/status.js +43 -0
  84. package/dist/commands/status.js.map +1 -0
  85. package/dist/commands/uninstall.d.ts +2 -0
  86. package/dist/commands/uninstall.d.ts.map +1 -0
  87. package/dist/commands/uninstall.js +43 -0
  88. package/dist/commands/uninstall.js.map +1 -0
  89. package/dist/commands/update.d.ts +2 -0
  90. package/dist/commands/update.d.ts.map +1 -0
  91. package/dist/commands/update.js +58 -0
  92. package/dist/commands/update.js.map +1 -0
  93. package/dist/configure/claude-code.d.ts +7 -0
  94. package/dist/configure/claude-code.d.ts.map +1 -0
  95. package/dist/configure/claude-code.js +11 -0
  96. package/dist/configure/claude-code.js.map +1 -0
  97. package/dist/configure/claude-desktop.d.ts +8 -0
  98. package/dist/configure/claude-desktop.d.ts.map +1 -0
  99. package/dist/configure/claude-desktop.js +28 -0
  100. package/dist/configure/claude-desktop.js.map +1 -0
  101. package/dist/configure/codex.d.ts +7 -0
  102. package/dist/configure/codex.d.ts.map +1 -0
  103. package/dist/configure/codex.js +12 -0
  104. package/dist/configure/codex.js.map +1 -0
  105. package/dist/configure/cursor.d.ts +7 -0
  106. package/dist/configure/cursor.d.ts.map +1 -0
  107. package/dist/configure/cursor.js +12 -0
  108. package/dist/configure/cursor.js.map +1 -0
  109. package/dist/configure/index.d.ts +34 -0
  110. package/dist/configure/index.d.ts.map +1 -0
  111. package/dist/configure/index.js +153 -0
  112. package/dist/configure/index.js.map +1 -0
  113. package/dist/detect/claude-code.d.ts +3 -0
  114. package/dist/detect/claude-code.d.ts.map +1 -0
  115. package/dist/detect/claude-code.js +82 -0
  116. package/dist/detect/claude-code.js.map +1 -0
  117. package/dist/detect/claude-desktop.d.ts +3 -0
  118. package/dist/detect/claude-desktop.d.ts.map +1 -0
  119. package/dist/detect/claude-desktop.js +89 -0
  120. package/dist/detect/claude-desktop.js.map +1 -0
  121. package/dist/detect/codex.d.ts +3 -0
  122. package/dist/detect/codex.d.ts.map +1 -0
  123. package/dist/detect/codex.js +64 -0
  124. package/dist/detect/codex.js.map +1 -0
  125. package/dist/detect/cursor.d.ts +3 -0
  126. package/dist/detect/cursor.d.ts.map +1 -0
  127. package/dist/detect/cursor.js +81 -0
  128. package/dist/detect/cursor.js.map +1 -0
  129. package/dist/detect/index.d.ts +3 -0
  130. package/dist/detect/index.d.ts.map +1 -0
  131. package/dist/detect/index.js +28 -0
  132. package/dist/detect/index.js.map +1 -0
  133. package/dist/import/file-upload.d.ts +10 -0
  134. package/dist/import/file-upload.d.ts.map +1 -0
  135. package/dist/import/file-upload.js +37 -0
  136. package/dist/import/file-upload.js.map +1 -0
  137. package/dist/import/index.d.ts +11 -0
  138. package/dist/import/index.d.ts.map +1 -0
  139. package/dist/import/index.js +51 -0
  140. package/dist/import/index.js.map +1 -0
  141. package/dist/mcp/exports.d.ts +13 -0
  142. package/dist/mcp/exports.d.ts.map +1 -0
  143. package/dist/mcp/exports.js +13 -0
  144. package/dist/mcp/exports.js.map +1 -0
  145. package/dist/mcp/git-context.d.ts +17 -0
  146. package/dist/mcp/git-context.d.ts.map +1 -0
  147. package/dist/mcp/git-context.js +72 -0
  148. package/dist/mcp/git-context.js.map +1 -0
  149. package/dist/mcp/hooks/anthropic.d.ts +31 -0
  150. package/dist/mcp/hooks/anthropic.d.ts.map +1 -0
  151. package/dist/mcp/hooks/anthropic.js +137 -0
  152. package/dist/mcp/hooks/anthropic.js.map +1 -0
  153. package/dist/mcp/hooks/google.d.ts +53 -0
  154. package/dist/mcp/hooks/google.d.ts.map +1 -0
  155. package/dist/mcp/hooks/google.js +161 -0
  156. package/dist/mcp/hooks/google.js.map +1 -0
  157. package/dist/mcp/hooks/index.d.ts +9 -0
  158. package/dist/mcp/hooks/index.d.ts.map +1 -0
  159. package/dist/mcp/hooks/index.js +7 -0
  160. package/dist/mcp/hooks/index.js.map +1 -0
  161. package/dist/mcp/hooks/openai.d.ts +59 -0
  162. package/dist/mcp/hooks/openai.d.ts.map +1 -0
  163. package/dist/mcp/hooks/openai.js +158 -0
  164. package/dist/mcp/hooks/openai.js.map +1 -0
  165. package/dist/mcp/hooks/types.d.ts +8 -0
  166. package/dist/mcp/hooks/types.d.ts.map +1 -0
  167. package/dist/mcp/hooks/types.js +5 -0
  168. package/dist/mcp/hooks/types.js.map +1 -0
  169. package/dist/mcp/ingestor.d.ts +23 -0
  170. package/dist/mcp/ingestor.d.ts.map +1 -0
  171. package/dist/mcp/ingestor.js +310 -0
  172. package/dist/mcp/ingestor.js.map +1 -0
  173. package/dist/mcp/pricing.d.ts +19 -0
  174. package/dist/mcp/pricing.d.ts.map +1 -0
  175. package/dist/mcp/pricing.js +130 -0
  176. package/dist/mcp/pricing.js.map +1 -0
  177. package/dist/mcp/server.d.ts +10 -0
  178. package/dist/mcp/server.d.ts.map +1 -0
  179. package/dist/mcp/server.js +689 -0
  180. package/dist/mcp/server.js.map +1 -0
  181. package/dist/mcp/session-tracker.d.ts +52 -0
  182. package/dist/mcp/session-tracker.d.ts.map +1 -0
  183. package/dist/mcp/session-tracker.js +186 -0
  184. package/dist/mcp/session-tracker.js.map +1 -0
  185. package/dist/mcp/tools/analyze-spending-trend.d.ts +10 -0
  186. package/dist/mcp/tools/analyze-spending-trend.d.ts.map +1 -0
  187. package/dist/mcp/tools/analyze-spending-trend.js +126 -0
  188. package/dist/mcp/tools/analyze-spending-trend.js.map +1 -0
  189. package/dist/mcp/tools/get-budget-status.d.ts +9 -0
  190. package/dist/mcp/tools/get-budget-status.d.ts.map +1 -0
  191. package/dist/mcp/tools/get-budget-status.js +59 -0
  192. package/dist/mcp/tools/get-budget-status.js.map +1 -0
  193. package/dist/mcp/tools/get-cost-breakdown.d.ts +10 -0
  194. package/dist/mcp/tools/get-cost-breakdown.d.ts.map +1 -0
  195. package/dist/mcp/tools/get-cost-breakdown.js +52 -0
  196. package/dist/mcp/tools/get-cost-breakdown.js.map +1 -0
  197. package/dist/mcp/tools/get-model-efficiency.d.ts +9 -0
  198. package/dist/mcp/tools/get-model-efficiency.d.ts.map +1 -0
  199. package/dist/mcp/tools/get-model-efficiency.js +137 -0
  200. package/dist/mcp/tools/get-model-efficiency.js.map +1 -0
  201. package/dist/mcp/tools/get-recent-prompts.d.ts +13 -0
  202. package/dist/mcp/tools/get-recent-prompts.d.ts.map +1 -0
  203. package/dist/mcp/tools/get-recent-prompts.js +56 -0
  204. package/dist/mcp/tools/get-recent-prompts.js.map +1 -0
  205. package/dist/mcp/tools/get-roi-metrics.d.ts +9 -0
  206. package/dist/mcp/tools/get-roi-metrics.d.ts.map +1 -0
  207. package/dist/mcp/tools/get-roi-metrics.js +84 -0
  208. package/dist/mcp/tools/get-roi-metrics.js.map +1 -0
  209. package/dist/mcp/tools/get-usage-summary.d.ts +10 -0
  210. package/dist/mcp/tools/get-usage-summary.d.ts.map +1 -0
  211. package/dist/mcp/tools/get-usage-summary.js +47 -0
  212. package/dist/mcp/tools/get-usage-summary.js.map +1 -0
  213. package/dist/mcp/tools/index.d.ts +221 -0
  214. package/dist/mcp/tools/index.d.ts.map +1 -0
  215. package/dist/mcp/tools/index.js +161 -0
  216. package/dist/mcp/tools/index.js.map +1 -0
  217. package/dist/mcp/tools/list-projects.d.ts +6 -0
  218. package/dist/mcp/tools/list-projects.d.ts.map +1 -0
  219. package/dist/mcp/tools/list-projects.js +43 -0
  220. package/dist/mcp/tools/list-projects.js.map +1 -0
  221. package/dist/mcp/tools/optimize-prompt.d.ts +44 -0
  222. package/dist/mcp/tools/optimize-prompt.d.ts.map +1 -0
  223. package/dist/mcp/tools/optimize-prompt.js +95 -0
  224. package/dist/mcp/tools/optimize-prompt.js.map +1 -0
  225. package/dist/mcp/types.d.ts +118 -0
  226. package/dist/mcp/types.d.ts.map +1 -0
  227. package/dist/mcp/types.js +5 -0
  228. package/dist/mcp/types.js.map +1 -0
  229. package/dist/types.d.ts +18 -0
  230. package/dist/types.d.ts.map +1 -0
  231. package/dist/types.js +2 -0
  232. package/dist/types.js.map +1 -0
  233. package/dist/update-check/check.d.ts +6 -0
  234. package/dist/update-check/check.d.ts.map +1 -0
  235. package/dist/update-check/check.js +64 -0
  236. package/dist/update-check/check.js.map +1 -0
  237. package/dist/update-check/notify.d.ts +6 -0
  238. package/dist/update-check/notify.d.ts.map +1 -0
  239. package/dist/update-check/notify.js +40 -0
  240. package/dist/update-check/notify.js.map +1 -0
  241. package/dist/verify.d.ts +7 -0
  242. package/dist/verify.d.ts.map +1 -0
  243. package/dist/verify.js +40 -0
  244. package/dist/verify.js.map +1 -0
  245. package/dist/version.d.ts +9 -0
  246. package/dist/version.d.ts.map +1 -0
  247. package/dist/version.js +21 -0
  248. package/dist/version.js.map +1 -0
  249. package/package.json +1 -1
@@ -0,0 +1,89 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-desktop.js","sourceRoot":"","sources":["../../src/detect/claude-desktop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DetectionResult } from '../types.js';
2
+ export declare function detectCodex(): Promise<DetectionResult>;
3
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,64 @@
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
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,3 @@
1
+ import type { DetectionResult } from '../types.js';
2
+ export declare function detectCursor(): Promise<DetectionResult>;
3
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,81 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/detect/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DetectionResult } from '../types.js';
2
+ export declare function detectAll(): Promise<DetectionResult[]>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,28 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detect/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,gBAAgB,EAAE;QAClB,mBAAmB,EAAE;QACrB,YAAY,EAAE;QACd,WAAW,EAAE;KACd,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACnC,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC;QACD,4DAA4D;QAC5D,MAAM,KAAK,GAA8B,CAAC,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9F,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;QAC3B,OAAO;YACL,IAAI;YACJ,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,EAAE;YACd,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,GAAG,IAAI,qBAAqB,MAAM,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;SACtH,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Credentials } from '../types.js';
2
+ /**
3
+ * Upload a Claude or ChatGPT export file to the backend import endpoint.
4
+ */
5
+ export declare function uploadExportFile(filePath: string, source: 'claude' | 'chatgpt', credentials: Credentials): Promise<{
6
+ success: boolean;
7
+ eventsCreated: number;
8
+ error?: string;
9
+ }>;
10
+ //# sourceMappingURL=file-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload.d.ts","sourceRoot":"","sources":["../../src/import/file-upload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,QAAQ,GAAG,SAAS,EAC5B,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuCtE"}
@@ -0,0 +1,37 @@
1
+ import { readFileSync, statSync } from 'node:fs';
2
+ const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 MB (matches server limit)
3
+ /**
4
+ * Upload a Claude or ChatGPT export file to the backend import endpoint.
5
+ */
6
+ export async function uploadExportFile(filePath, source, credentials) {
7
+ const stat = statSync(filePath);
8
+ if (stat.size > MAX_FILE_SIZE) {
9
+ return {
10
+ success: false,
11
+ eventsCreated: 0,
12
+ error: `File too large (${Math.round(stat.size / 1024 / 1024)}MB). Maximum is 100MB.`,
13
+ };
14
+ }
15
+ const content = readFileSync(filePath, 'utf-8');
16
+ const endpoint = source === 'claude'
17
+ ? `${credentials.api_url}/api/v1/import/claude`
18
+ : `${credentials.api_url}/api/v1/import/chatgpt`;
19
+ const res = await fetch(endpoint, {
20
+ method: 'POST',
21
+ headers: {
22
+ Authorization: `Bearer ${credentials.api_key}`,
23
+ 'Content-Type': 'application/json',
24
+ },
25
+ body: content,
26
+ });
27
+ if (!res.ok) {
28
+ const body = await res.text();
29
+ return { success: false, eventsCreated: 0, error: `HTTP ${res.status}: ${body}` };
30
+ }
31
+ const result = (await res.json());
32
+ return {
33
+ success: result.success,
34
+ eventsCreated: result.events_created ?? result.conversations_processed ?? 0,
35
+ };
36
+ }
37
+ //# sourceMappingURL=file-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload.js","sourceRoot":"","sources":["../../src/import/file-upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGjD,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,gCAAgC;AAEzE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,MAA4B,EAC5B,WAAwB;IAExB,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;QAC9B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,aAAa,EAAE,CAAC;YAChB,KAAK,EAAE,mBAAmB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,wBAAwB;SACtF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,QAAQ,GACZ,MAAM,KAAK,QAAQ;QACjB,CAAC,CAAC,GAAG,WAAW,CAAC,OAAO,uBAAuB;QAC/C,CAAC,CAAC,GAAG,WAAW,CAAC,OAAO,wBAAwB,CAAC;IAErD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,WAAW,CAAC,OAAO,EAAE;YAC9C,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,EAAE,CAAC;IACpF,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAI/B,CAAC;IAEF,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,uBAAuB,IAAI,CAAC;KAC5E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface ImportSource {
2
+ id: string;
3
+ label: string;
4
+ path: string;
5
+ count: number;
6
+ }
7
+ /**
8
+ * Scan the local filesystem for importable AI tool history.
9
+ */
10
+ export declare function detectImportSources(): ImportSource[];
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/import/index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,YAAY,EAAE,CAiCpD"}
@@ -0,0 +1,51 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ /**
5
+ * Scan the local filesystem for importable AI tool history.
6
+ */
7
+ export function detectImportSources() {
8
+ const sources = [];
9
+ const home = homedir();
10
+ // Claude Code history
11
+ const claudeDir = join(home, '.claude');
12
+ if (existsSync(claudeDir)) {
13
+ const sessions = countSessions(claudeDir, 'projects');
14
+ if (sessions > 0) {
15
+ sources.push({
16
+ id: 'claude-code',
17
+ label: 'Claude Code history (~/.claude/)',
18
+ path: claudeDir,
19
+ count: sessions,
20
+ });
21
+ }
22
+ }
23
+ // Codex sessions
24
+ const codexDir = join(home, '.codex');
25
+ if (existsSync(codexDir)) {
26
+ const sessions = countSessions(codexDir, 'sessions');
27
+ if (sessions > 0) {
28
+ sources.push({
29
+ id: 'codex',
30
+ label: 'Codex sessions (~/.codex/)',
31
+ path: codexDir,
32
+ count: sessions,
33
+ });
34
+ }
35
+ }
36
+ return sources;
37
+ }
38
+ function countSessions(dir, subdir) {
39
+ try {
40
+ const target = join(dir, subdir);
41
+ if (!existsSync(target))
42
+ return 0;
43
+ return readdirSync(target, { recursive: true })
44
+ .filter((f) => String(f).endsWith('.jsonl') || String(f).endsWith('.json'))
45
+ .length;
46
+ }
47
+ catch {
48
+ return 0;
49
+ }
50
+ }
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/import/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AASlC;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,sBAAsB;IACtB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACtD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,kCAAkC;gBACzC,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACtC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,OAAO;gBACX,KAAK,EAAE,4BAA4B;gBACnC,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,MAAc;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,CAAC;QAClC,OAAO,WAAW,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;aAC5C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAC1E,MAAM,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Public API exports for @verbal/mcp-service
3
+ *
4
+ * Import from this module when using the SDK hooks in your application:
5
+ * ```ts
6
+ * import { VerbalIngestor, createAnthropicHook } from '@verbal/mcp-service';
7
+ * ```
8
+ */
9
+ export { VerbalIngestor, attachExitHooks } from './ingestor.js';
10
+ export type { UsageEvent, IngestPayload, IngestorConfig, IngestResult } from './types.js';
11
+ export { createAnthropicHook, attachAnthropicStreamHooks, createOpenAIHooks, createOpenAIFetchHook, createGoogleHook, trackGoogleWithOTel, } from './hooks/index.js';
12
+ export type { HookTracker, OpenAIRunHooks } from './hooks/index.js';
13
+ //# sourceMappingURL=exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../src/mcp/exports.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1F,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Public API exports for @verbal/mcp-service
3
+ *
4
+ * Import from this module when using the SDK hooks in your application:
5
+ * ```ts
6
+ * import { VerbalIngestor, createAnthropicHook } from '@verbal/mcp-service';
7
+ * ```
8
+ */
9
+ // Core ingestor
10
+ export { VerbalIngestor, attachExitHooks } from './ingestor.js';
11
+ // Hook adapters
12
+ export { createAnthropicHook, attachAnthropicStreamHooks, createOpenAIHooks, createOpenAIFetchHook, createGoogleHook, trackGoogleWithOTel, } from './hooks/index.js';
13
+ //# sourceMappingURL=exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.js","sourceRoot":"","sources":["../../src/mcp/exports.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,gBAAgB;AAChB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAKhE,gBAAgB;AAChB,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface GitContext {
2
+ repo_name: string | null;
3
+ branch: string | null;
4
+ commit_hash: string | null;
5
+ commit_message: string | null;
6
+ files_changed: number;
7
+ lines_added: number;
8
+ lines_deleted: number;
9
+ is_dirty: boolean;
10
+ remote_url: string | null;
11
+ }
12
+ /**
13
+ * Gather git context from the current working directory
14
+ * Returns null if not a git repository
15
+ */
16
+ export declare function getGitContext(cwd: string): GitContext | null;
17
+ //# sourceMappingURL=git-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-context.d.ts","sourceRoot":"","sources":["../../src/mcp/git-context.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAiBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA2D5D"}
@@ -0,0 +1,72 @@
1
+ import { execSync } from 'child_process';
2
+ /**
3
+ * Execute git command and return output (or null on failure)
4
+ */
5
+ function gitCommand(cmd, cwd) {
6
+ try {
7
+ return execSync(cmd, {
8
+ cwd,
9
+ encoding: 'utf8',
10
+ stdio: ['pipe', 'pipe', 'ignore'], // Suppress stderr
11
+ }).trim();
12
+ }
13
+ catch (error) {
14
+ return null;
15
+ }
16
+ }
17
+ /**
18
+ * Gather git context from the current working directory
19
+ * Returns null if not a git repository
20
+ */
21
+ export function getGitContext(cwd) {
22
+ // Check if we're in a git repo
23
+ const isGitRepo = gitCommand('git rev-parse --is-inside-work-tree', cwd);
24
+ if (!isGitRepo) {
25
+ return null;
26
+ }
27
+ // Get branch name
28
+ const branch = gitCommand('git rev-parse --abbrev-ref HEAD', cwd);
29
+ // Get commit hash
30
+ const commitHash = gitCommand('git rev-parse HEAD', cwd);
31
+ // Get commit message (first line)
32
+ const commitMessage = gitCommand('git log -1 --pretty=%s', cwd);
33
+ // Get repo name from remote URL
34
+ const remoteUrl = gitCommand('git config --get remote.origin.url', cwd);
35
+ let repoName = null;
36
+ if (remoteUrl) {
37
+ // Extract repo name from URL (works for GitHub, GitLab, etc.)
38
+ const match = remoteUrl.match(/\/([^/]+?)(?:\.git)?$/);
39
+ repoName = match ? match[1] : null;
40
+ }
41
+ // Check for uncommitted changes
42
+ const statusOutput = gitCommand('git status --porcelain', cwd);
43
+ const isDirty = statusOutput ? statusOutput.length > 0 : false;
44
+ // Get file change stats (uncommitted changes)
45
+ let filesChanged = 0;
46
+ let linesAdded = 0;
47
+ let linesDeleted = 0;
48
+ if (isDirty) {
49
+ const diffStats = gitCommand('git diff --stat', cwd);
50
+ if (diffStats) {
51
+ // Parse output like: "3 files changed, 42 insertions(+), 7 deletions(-)"
52
+ const filesMatch = diffStats.match(/(\d+) files? changed/);
53
+ const insertionsMatch = diffStats.match(/(\d+) insertions?/);
54
+ const deletionsMatch = diffStats.match(/(\d+) deletions?/);
55
+ filesChanged = filesMatch ? parseInt(filesMatch[1], 10) : 0;
56
+ linesAdded = insertionsMatch ? parseInt(insertionsMatch[1], 10) : 0;
57
+ linesDeleted = deletionsMatch ? parseInt(deletionsMatch[1], 10) : 0;
58
+ }
59
+ }
60
+ return {
61
+ repo_name: repoName,
62
+ branch,
63
+ commit_hash: commitHash,
64
+ commit_message: commitMessage,
65
+ files_changed: filesChanged,
66
+ lines_added: linesAdded,
67
+ lines_deleted: linesDeleted,
68
+ is_dirty: isDirty,
69
+ remote_url: remoteUrl,
70
+ };
71
+ }
72
+ //# sourceMappingURL=git-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-context.js","sourceRoot":"","sources":["../../src/mcp/git-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Anthropic SDK hook adapter using custom fetch middleware
3
+ *
4
+ * Usage:
5
+ * ```ts
6
+ * import Anthropic from '@anthropic-ai/sdk';
7
+ * import { createAnthropicHook } from '@verbal/mcp-service/hooks/anthropic';
8
+ *
9
+ * const trackedFetch = createAnthropicHook(ingestor);
10
+ * const client = new Anthropic({
11
+ * apiKey: process.env.ANTHROPIC_API_KEY,
12
+ * fetch: trackedFetch,
13
+ * });
14
+ * ```
15
+ */
16
+ import type { HookTracker } from './types.js';
17
+ export declare function createAnthropicHook(tracker: HookTracker): typeof fetch;
18
+ /**
19
+ * Hook for Anthropic streaming responses using event listeners
20
+ *
21
+ * Usage:
22
+ * ```ts
23
+ * const stream = await client.messages.stream({...});
24
+ * attachStreamHooks(stream, ingestor, promptContent);
25
+ * ```
26
+ */
27
+ export declare function attachAnthropicStreamHooks(stream: {
28
+ on(event: 'message', handler: (message: unknown) => void): void;
29
+ on(event: 'error', handler: (error: unknown) => void): void;
30
+ }, tracker: HookTracker, promptContent: string, startTime?: number): void;
31
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/mcp/hooks/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,KAAK,CAsDtE;AA8CD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE;IACN,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAChE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7D,EACD,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,MAAmB,GAC7B,IAAI,CAiCN"}