@hasna/connectors 0.5.0 → 0.5.2

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 (223) hide show
  1. package/bin/index.js +147 -6
  2. package/bin/mcp.js +92 -1
  3. package/bin/serve.js +91 -0
  4. package/connectors/connect-ably/.env.example +11 -0
  5. package/connectors/connect-ably/CLAUDE.md +111 -0
  6. package/connectors/connect-ably/README.md +193 -0
  7. package/connectors/connect-ably/package.json +54 -0
  8. package/connectors/connect-ably/scripts/release.ts +179 -0
  9. package/connectors/connect-ably/src/api/channels.ts +33 -0
  10. package/connectors/connect-ably/src/api/client.ts +203 -0
  11. package/connectors/connect-ably/src/api/index.ts +59 -0
  12. package/connectors/connect-ably/src/api/messages.ts +48 -0
  13. package/connectors/connect-ably/src/api/presence.ts +39 -0
  14. package/connectors/connect-ably/src/api/stats.ts +29 -0
  15. package/connectors/connect-ably/src/cli/index.ts +397 -0
  16. package/connectors/connect-ably/src/index.ts +102 -0
  17. package/connectors/connect-ably/src/types/index.ts +294 -0
  18. package/connectors/connect-ably/src/utils/auth.ts +274 -0
  19. package/connectors/connect-ably/src/utils/bulk.ts +212 -0
  20. package/connectors/connect-ably/src/utils/config.ts +323 -0
  21. package/connectors/connect-ably/src/utils/output.ts +175 -0
  22. package/connectors/connect-ably/src/utils/settings.ts +114 -0
  23. package/connectors/connect-ably/src/utils/storage.ts +198 -0
  24. package/connectors/connect-ably/tsconfig.json +16 -0
  25. package/connectors/connect-box/.env.example +11 -0
  26. package/connectors/connect-box/CLAUDE.md +272 -0
  27. package/connectors/connect-box/README.md +193 -0
  28. package/connectors/connect-box/package.json +51 -0
  29. package/connectors/connect-box/scripts/release.ts +179 -0
  30. package/connectors/connect-box/src/api/client.ts +213 -0
  31. package/connectors/connect-box/src/api/example.ts +48 -0
  32. package/connectors/connect-box/src/api/index.ts +51 -0
  33. package/connectors/connect-box/src/cli/index.ts +254 -0
  34. package/connectors/connect-box/src/index.ts +103 -0
  35. package/connectors/connect-box/src/types/index.ts +237 -0
  36. package/connectors/connect-box/src/utils/auth.ts +274 -0
  37. package/connectors/connect-box/src/utils/bulk.ts +212 -0
  38. package/connectors/connect-box/src/utils/config.ts +326 -0
  39. package/connectors/connect-box/src/utils/output.ts +175 -0
  40. package/connectors/connect-box/src/utils/settings.ts +114 -0
  41. package/connectors/connect-box/src/utils/storage.ts +198 -0
  42. package/connectors/connect-box/tsconfig.json +16 -0
  43. package/connectors/connect-clearbit/.env.example +11 -0
  44. package/connectors/connect-clearbit/CLAUDE.md +272 -0
  45. package/connectors/connect-clearbit/README.md +193 -0
  46. package/connectors/connect-clearbit/package.json +51 -0
  47. package/connectors/connect-clearbit/scripts/release.ts +179 -0
  48. package/connectors/connect-clearbit/src/api/client.ts +213 -0
  49. package/connectors/connect-clearbit/src/api/example.ts +48 -0
  50. package/connectors/connect-clearbit/src/api/index.ts +51 -0
  51. package/connectors/connect-clearbit/src/cli/index.ts +254 -0
  52. package/connectors/connect-clearbit/src/index.ts +103 -0
  53. package/connectors/connect-clearbit/src/types/index.ts +237 -0
  54. package/connectors/connect-clearbit/src/utils/auth.ts +274 -0
  55. package/connectors/connect-clearbit/src/utils/bulk.ts +212 -0
  56. package/connectors/connect-clearbit/src/utils/config.ts +326 -0
  57. package/connectors/connect-clearbit/src/utils/output.ts +175 -0
  58. package/connectors/connect-clearbit/src/utils/settings.ts +114 -0
  59. package/connectors/connect-clearbit/src/utils/storage.ts +198 -0
  60. package/connectors/connect-clearbit/tsconfig.json +16 -0
  61. package/connectors/connect-coda/.env.example +11 -0
  62. package/connectors/connect-coda/CLAUDE.md +272 -0
  63. package/connectors/connect-coda/README.md +193 -0
  64. package/connectors/connect-coda/package.json +51 -0
  65. package/connectors/connect-coda/scripts/release.ts +179 -0
  66. package/connectors/connect-coda/src/api/client.ts +213 -0
  67. package/connectors/connect-coda/src/api/example.ts +48 -0
  68. package/connectors/connect-coda/src/api/index.ts +51 -0
  69. package/connectors/connect-coda/src/cli/index.ts +254 -0
  70. package/connectors/connect-coda/src/index.ts +103 -0
  71. package/connectors/connect-coda/src/types/index.ts +237 -0
  72. package/connectors/connect-coda/src/utils/auth.ts +274 -0
  73. package/connectors/connect-coda/src/utils/bulk.ts +212 -0
  74. package/connectors/connect-coda/src/utils/config.ts +326 -0
  75. package/connectors/connect-coda/src/utils/output.ts +175 -0
  76. package/connectors/connect-coda/src/utils/settings.ts +114 -0
  77. package/connectors/connect-coda/src/utils/storage.ts +198 -0
  78. package/connectors/connect-coda/tsconfig.json +16 -0
  79. package/connectors/connect-dropbox/.env.example +11 -0
  80. package/connectors/connect-dropbox/CLAUDE.md +119 -0
  81. package/connectors/connect-dropbox/README.md +193 -0
  82. package/connectors/connect-dropbox/package.json +51 -0
  83. package/connectors/connect-dropbox/src/api/client.ts +222 -0
  84. package/connectors/connect-dropbox/src/api/index.ts +395 -0
  85. package/connectors/connect-dropbox/src/cli/index.ts +627 -0
  86. package/connectors/connect-dropbox/src/index.ts +20 -0
  87. package/connectors/connect-dropbox/src/types/index.ts +516 -0
  88. package/connectors/connect-dropbox/src/utils/config.ts +197 -0
  89. package/connectors/connect-dropbox/tsconfig.json +16 -0
  90. package/connectors/connect-linode/.env.example +11 -0
  91. package/connectors/connect-linode/CLAUDE.md +272 -0
  92. package/connectors/connect-linode/README.md +193 -0
  93. package/connectors/connect-linode/package.json +51 -0
  94. package/connectors/connect-linode/scripts/release.ts +179 -0
  95. package/connectors/connect-linode/src/api/client.ts +213 -0
  96. package/connectors/connect-linode/src/api/example.ts +48 -0
  97. package/connectors/connect-linode/src/api/index.ts +51 -0
  98. package/connectors/connect-linode/src/cli/index.ts +254 -0
  99. package/connectors/connect-linode/src/index.ts +103 -0
  100. package/connectors/connect-linode/src/types/index.ts +237 -0
  101. package/connectors/connect-linode/src/utils/auth.ts +274 -0
  102. package/connectors/connect-linode/src/utils/bulk.ts +212 -0
  103. package/connectors/connect-linode/src/utils/config.ts +326 -0
  104. package/connectors/connect-linode/src/utils/output.ts +175 -0
  105. package/connectors/connect-linode/src/utils/settings.ts +114 -0
  106. package/connectors/connect-linode/src/utils/storage.ts +198 -0
  107. package/connectors/connect-linode/tsconfig.json +16 -0
  108. package/connectors/connect-mailgun/.env.example +11 -0
  109. package/connectors/connect-mailgun/CLAUDE.md +272 -0
  110. package/connectors/connect-mailgun/README.md +193 -0
  111. package/connectors/connect-mailgun/package.json +51 -0
  112. package/connectors/connect-mailgun/scripts/release.ts +179 -0
  113. package/connectors/connect-mailgun/src/api/client.ts +213 -0
  114. package/connectors/connect-mailgun/src/api/example.ts +48 -0
  115. package/connectors/connect-mailgun/src/api/index.ts +51 -0
  116. package/connectors/connect-mailgun/src/cli/index.ts +254 -0
  117. package/connectors/connect-mailgun/src/index.ts +103 -0
  118. package/connectors/connect-mailgun/src/types/index.ts +237 -0
  119. package/connectors/connect-mailgun/src/utils/auth.ts +274 -0
  120. package/connectors/connect-mailgun/src/utils/bulk.ts +212 -0
  121. package/connectors/connect-mailgun/src/utils/config.ts +326 -0
  122. package/connectors/connect-mailgun/src/utils/output.ts +175 -0
  123. package/connectors/connect-mailgun/src/utils/settings.ts +114 -0
  124. package/connectors/connect-mailgun/src/utils/storage.ts +198 -0
  125. package/connectors/connect-mailgun/tsconfig.json +16 -0
  126. package/connectors/connect-messagebird/.env.example +11 -0
  127. package/connectors/connect-messagebird/CLAUDE.md +272 -0
  128. package/connectors/connect-messagebird/README.md +193 -0
  129. package/connectors/connect-messagebird/package.json +51 -0
  130. package/connectors/connect-messagebird/scripts/release.ts +179 -0
  131. package/connectors/connect-messagebird/src/api/client.ts +213 -0
  132. package/connectors/connect-messagebird/src/api/example.ts +48 -0
  133. package/connectors/connect-messagebird/src/api/index.ts +51 -0
  134. package/connectors/connect-messagebird/src/cli/index.ts +254 -0
  135. package/connectors/connect-messagebird/src/index.ts +103 -0
  136. package/connectors/connect-messagebird/src/types/index.ts +237 -0
  137. package/connectors/connect-messagebird/src/utils/auth.ts +274 -0
  138. package/connectors/connect-messagebird/src/utils/bulk.ts +212 -0
  139. package/connectors/connect-messagebird/src/utils/config.ts +326 -0
  140. package/connectors/connect-messagebird/src/utils/output.ts +175 -0
  141. package/connectors/connect-messagebird/src/utils/settings.ts +114 -0
  142. package/connectors/connect-messagebird/src/utils/storage.ts +198 -0
  143. package/connectors/connect-messagebird/tsconfig.json +16 -0
  144. package/connectors/connect-miro/.env.example +11 -0
  145. package/connectors/connect-miro/CLAUDE.md +272 -0
  146. package/connectors/connect-miro/README.md +193 -0
  147. package/connectors/connect-miro/package.json +51 -0
  148. package/connectors/connect-miro/scripts/release.ts +179 -0
  149. package/connectors/connect-miro/src/api/client.ts +213 -0
  150. package/connectors/connect-miro/src/api/example.ts +48 -0
  151. package/connectors/connect-miro/src/api/index.ts +51 -0
  152. package/connectors/connect-miro/src/cli/index.ts +254 -0
  153. package/connectors/connect-miro/src/index.ts +103 -0
  154. package/connectors/connect-miro/src/types/index.ts +237 -0
  155. package/connectors/connect-miro/src/utils/auth.ts +274 -0
  156. package/connectors/connect-miro/src/utils/bulk.ts +212 -0
  157. package/connectors/connect-miro/src/utils/config.ts +326 -0
  158. package/connectors/connect-miro/src/utils/output.ts +175 -0
  159. package/connectors/connect-miro/src/utils/settings.ts +114 -0
  160. package/connectors/connect-miro/src/utils/storage.ts +198 -0
  161. package/connectors/connect-miro/tsconfig.json +16 -0
  162. package/connectors/connect-monday/.env.example +11 -0
  163. package/connectors/connect-monday/CLAUDE.md +128 -0
  164. package/connectors/connect-monday/README.md +193 -0
  165. package/connectors/connect-monday/package.json +52 -0
  166. package/connectors/connect-monday/src/api/client.ts +59 -0
  167. package/connectors/connect-monday/src/api/index.ts +539 -0
  168. package/connectors/connect-monday/src/cli/index.ts +479 -0
  169. package/connectors/connect-monday/src/index.ts +19 -0
  170. package/connectors/connect-monday/src/types/index.ts +274 -0
  171. package/connectors/connect-monday/src/utils/config.ts +197 -0
  172. package/connectors/connect-monday/src/utils/output.ts +119 -0
  173. package/connectors/connect-monday/tsconfig.json +16 -0
  174. package/connectors/connect-pipedrive/.env.example +11 -0
  175. package/connectors/connect-pipedrive/CLAUDE.md +128 -0
  176. package/connectors/connect-pipedrive/README.md +193 -0
  177. package/connectors/connect-pipedrive/package.json +52 -0
  178. package/connectors/connect-pipedrive/src/api/client.ts +121 -0
  179. package/connectors/connect-pipedrive/src/api/index.ts +306 -0
  180. package/connectors/connect-pipedrive/src/cli/index.ts +824 -0
  181. package/connectors/connect-pipedrive/src/index.ts +19 -0
  182. package/connectors/connect-pipedrive/src/types/index.ts +335 -0
  183. package/connectors/connect-pipedrive/src/utils/config.ts +171 -0
  184. package/connectors/connect-pipedrive/src/utils/output.ts +119 -0
  185. package/connectors/connect-pipedrive/tsconfig.json +16 -0
  186. package/connectors/connect-pusher/.env.example +11 -0
  187. package/connectors/connect-pusher/CLAUDE.md +272 -0
  188. package/connectors/connect-pusher/README.md +193 -0
  189. package/connectors/connect-pusher/package.json +51 -0
  190. package/connectors/connect-pusher/scripts/release.ts +179 -0
  191. package/connectors/connect-pusher/src/api/client.ts +213 -0
  192. package/connectors/connect-pusher/src/api/example.ts +48 -0
  193. package/connectors/connect-pusher/src/api/index.ts +51 -0
  194. package/connectors/connect-pusher/src/cli/index.ts +254 -0
  195. package/connectors/connect-pusher/src/index.ts +103 -0
  196. package/connectors/connect-pusher/src/types/index.ts +237 -0
  197. package/connectors/connect-pusher/src/utils/auth.ts +274 -0
  198. package/connectors/connect-pusher/src/utils/bulk.ts +212 -0
  199. package/connectors/connect-pusher/src/utils/config.ts +326 -0
  200. package/connectors/connect-pusher/src/utils/output.ts +175 -0
  201. package/connectors/connect-pusher/src/utils/settings.ts +114 -0
  202. package/connectors/connect-pusher/src/utils/storage.ts +198 -0
  203. package/connectors/connect-pusher/tsconfig.json +16 -0
  204. package/connectors/connect-vonage/.env.example +11 -0
  205. package/connectors/connect-vonage/CLAUDE.md +272 -0
  206. package/connectors/connect-vonage/README.md +193 -0
  207. package/connectors/connect-vonage/package.json +51 -0
  208. package/connectors/connect-vonage/scripts/release.ts +179 -0
  209. package/connectors/connect-vonage/src/api/client.ts +213 -0
  210. package/connectors/connect-vonage/src/api/example.ts +48 -0
  211. package/connectors/connect-vonage/src/api/index.ts +51 -0
  212. package/connectors/connect-vonage/src/cli/index.ts +254 -0
  213. package/connectors/connect-vonage/src/index.ts +103 -0
  214. package/connectors/connect-vonage/src/types/index.ts +237 -0
  215. package/connectors/connect-vonage/src/utils/auth.ts +274 -0
  216. package/connectors/connect-vonage/src/utils/bulk.ts +212 -0
  217. package/connectors/connect-vonage/src/utils/config.ts +326 -0
  218. package/connectors/connect-vonage/src/utils/output.ts +175 -0
  219. package/connectors/connect-vonage/src/utils/settings.ts +114 -0
  220. package/connectors/connect-vonage/src/utils/storage.ts +198 -0
  221. package/connectors/connect-vonage/tsconfig.json +16 -0
  222. package/dist/index.js +91 -0
  223. package/package.json +1 -1
@@ -0,0 +1,824 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { Pipedrive } from '../api';
5
+ import {
6
+ getApiKey,
7
+ setApiKey,
8
+ clearConfig,
9
+ getConfigDir,
10
+ setProfileOverride,
11
+ getCurrentProfile,
12
+ setCurrentProfile,
13
+ listProfiles,
14
+ createProfile,
15
+ deleteProfile,
16
+ profileExists,
17
+ loadProfile,
18
+ } from '../utils/config';
19
+ import type { OutputFormat } from '../utils/output';
20
+ import { success, error, info, print, warn } from '../utils/output';
21
+
22
+ const CONNECTOR_NAME = 'connect-pipedrive';
23
+ const VERSION = '0.0.1';
24
+
25
+ const program = new Command();
26
+
27
+ program
28
+ .name(CONNECTOR_NAME)
29
+ .description('Pipedrive connector - CRM persons, organizations, deals, and activities')
30
+ .version(VERSION)
31
+ .option('-k, --api-key <key>', 'API key (overrides config)')
32
+ .option('-f, --format <format>', 'Output format (json, pretty)', 'pretty')
33
+ .option('-p, --profile <profile>', 'Use a specific profile')
34
+ .hook('preAction', (thisCommand) => {
35
+ const opts = thisCommand.opts();
36
+ if (opts.profile) {
37
+ if (!profileExists(opts.profile)) {
38
+ error(`Profile "${opts.profile}" does not exist. Create it with "${CONNECTOR_NAME} profile create ${opts.profile}"`);
39
+ process.exit(1);
40
+ }
41
+ setProfileOverride(opts.profile);
42
+ }
43
+ if (opts.apiKey) {
44
+ process.env.PIPEDRIVE_API_KEY = opts.apiKey;
45
+ }
46
+ });
47
+
48
+ function getFormat(cmd: Command): OutputFormat {
49
+ const parent = cmd.parent;
50
+ return (parent?.opts().format || 'pretty') as OutputFormat;
51
+ }
52
+
53
+ function getClient(): Pipedrive {
54
+ const apiKey = getApiKey();
55
+ if (!apiKey) {
56
+ error(`No API key configured. Run "${CONNECTOR_NAME} config set-key <key>" or set PIPEDRIVE_API_KEY environment variable.`);
57
+ process.exit(1);
58
+ }
59
+ return new Pipedrive({ apiKey });
60
+ }
61
+
62
+ // ============================================
63
+ // Profile Commands
64
+ // ============================================
65
+ const profileCmd = program
66
+ .command('profile')
67
+ .description('Manage configuration profiles');
68
+
69
+ profileCmd
70
+ .command('list')
71
+ .description('List all profiles')
72
+ .action(() => {
73
+ const profiles = listProfiles();
74
+ const current = getCurrentProfile();
75
+
76
+ if (profiles.length === 0) {
77
+ info('No profiles found. Use "profile create <name>" to create one.');
78
+ return;
79
+ }
80
+
81
+ success(`Profiles:`);
82
+ profiles.forEach(p => {
83
+ const isActive = p === current ? chalk.green(' (active)') : '';
84
+ console.log(` ${p}${isActive}`);
85
+ });
86
+ });
87
+
88
+ profileCmd
89
+ .command('use <name>')
90
+ .description('Switch to a profile')
91
+ .action((name: string) => {
92
+ if (!profileExists(name)) {
93
+ error(`Profile "${name}" does not exist. Create it with "profile create ${name}"`);
94
+ process.exit(1);
95
+ }
96
+ setCurrentProfile(name);
97
+ success(`Switched to profile: ${name}`);
98
+ });
99
+
100
+ profileCmd
101
+ .command('create <name>')
102
+ .description('Create a new profile')
103
+ .option('--api-key <key>', 'API key')
104
+ .option('--use', 'Switch to this profile after creation')
105
+ .action((name: string, opts) => {
106
+ if (profileExists(name)) {
107
+ error(`Profile "${name}" already exists`);
108
+ process.exit(1);
109
+ }
110
+
111
+ createProfile(name, {
112
+ apiKey: opts.apiKey,
113
+ });
114
+ success(`Profile "${name}" created`);
115
+
116
+ if (opts.use) {
117
+ setCurrentProfile(name);
118
+ info(`Switched to profile: ${name}`);
119
+ }
120
+ });
121
+
122
+ profileCmd
123
+ .command('delete <name>')
124
+ .description('Delete a profile')
125
+ .action((name: string) => {
126
+ if (name === 'default') {
127
+ error('Cannot delete the default profile');
128
+ process.exit(1);
129
+ }
130
+ if (deleteProfile(name)) {
131
+ success(`Profile "${name}" deleted`);
132
+ } else {
133
+ error(`Profile "${name}" not found`);
134
+ process.exit(1);
135
+ }
136
+ });
137
+
138
+ profileCmd
139
+ .command('show [name]')
140
+ .description('Show profile configuration')
141
+ .action((name?: string) => {
142
+ const profileName = name || getCurrentProfile();
143
+ const config = loadProfile(profileName);
144
+ const active = getCurrentProfile();
145
+
146
+ console.log(chalk.bold(`Profile: ${profileName}${profileName === active ? chalk.green(' (active)') : ''}`));
147
+ info(`API Key: ${config.apiKey ? `${config.apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
148
+ });
149
+
150
+ // ============================================
151
+ // Config Commands
152
+ // ============================================
153
+ const configCmd = program
154
+ .command('config')
155
+ .description('Manage CLI configuration (for active profile)');
156
+
157
+ configCmd
158
+ .command('set-key <apiKey>')
159
+ .description('Set API key')
160
+ .action((apiKey: string) => {
161
+ setApiKey(apiKey);
162
+ success(`API key saved to profile: ${getCurrentProfile()}`);
163
+ });
164
+
165
+ configCmd
166
+ .command('show')
167
+ .description('Show current configuration')
168
+ .action(() => {
169
+ const profileName = getCurrentProfile();
170
+ const apiKey = getApiKey();
171
+
172
+ console.log(chalk.bold(`Active Profile: ${profileName}`));
173
+ info(`Config directory: ${getConfigDir()}`);
174
+ info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
175
+ });
176
+
177
+ configCmd
178
+ .command('clear')
179
+ .description('Clear configuration for active profile')
180
+ .action(() => {
181
+ clearConfig();
182
+ success(`Configuration cleared for profile: ${getCurrentProfile()}`);
183
+ });
184
+
185
+ // ============================================
186
+ // Person Commands
187
+ // ============================================
188
+ const personCmd = program
189
+ .command('person')
190
+ .description('Person management');
191
+
192
+ personCmd
193
+ .command('list')
194
+ .description('List all persons')
195
+ .option('--limit <number>', 'Maximum results', '100')
196
+ .action(async (opts) => {
197
+ try {
198
+ const client = getClient();
199
+ const result = await client.listPersons({ limit: parseInt(opts.limit) });
200
+ print(result, getFormat(personCmd));
201
+ } catch (err) {
202
+ error(String(err));
203
+ process.exit(1);
204
+ }
205
+ });
206
+
207
+ personCmd
208
+ .command('get <id>')
209
+ .description('Get a person by ID')
210
+ .action(async (id: string) => {
211
+ try {
212
+ const client = getClient();
213
+ const result = await client.getPerson(parseInt(id));
214
+ print(result, getFormat(personCmd));
215
+ } catch (err) {
216
+ error(String(err));
217
+ process.exit(1);
218
+ }
219
+ });
220
+
221
+ personCmd
222
+ .command('create')
223
+ .description('Create a new person')
224
+ .requiredOption('--name <name>', 'Person name')
225
+ .option('--email <email>', 'Email')
226
+ .option('--phone <phone>', 'Phone')
227
+ .option('--org-id <id>', 'Organization ID')
228
+ .action(async (opts) => {
229
+ try {
230
+ const client = getClient();
231
+ const result = await client.createPerson({
232
+ name: opts.name,
233
+ email: opts.email,
234
+ phone: opts.phone,
235
+ org_id: opts.orgId ? parseInt(opts.orgId) : undefined,
236
+ });
237
+ success('Person created!');
238
+ print(result, getFormat(personCmd));
239
+ } catch (err) {
240
+ error(String(err));
241
+ process.exit(1);
242
+ }
243
+ });
244
+
245
+ personCmd
246
+ .command('delete <id>')
247
+ .description('Delete a person')
248
+ .action(async (id: string) => {
249
+ try {
250
+ const client = getClient();
251
+ await client.deletePerson(parseInt(id));
252
+ success(`Person ${id} deleted`);
253
+ } catch (err) {
254
+ error(String(err));
255
+ process.exit(1);
256
+ }
257
+ });
258
+
259
+ personCmd
260
+ .command('search <term>')
261
+ .description('Search persons')
262
+ .option('--limit <number>', 'Maximum results', '100')
263
+ .action(async (term: string, opts) => {
264
+ try {
265
+ const client = getClient();
266
+ const result = await client.searchPersons(term, { limit: parseInt(opts.limit) });
267
+ print(result, getFormat(personCmd));
268
+ } catch (err) {
269
+ error(String(err));
270
+ process.exit(1);
271
+ }
272
+ });
273
+
274
+ // ============================================
275
+ // Organization Commands
276
+ // ============================================
277
+ const orgCmd = program
278
+ .command('organization')
279
+ .alias('org')
280
+ .description('Organization management');
281
+
282
+ orgCmd
283
+ .command('list')
284
+ .description('List all organizations')
285
+ .option('--limit <number>', 'Maximum results', '100')
286
+ .action(async (opts) => {
287
+ try {
288
+ const client = getClient();
289
+ const result = await client.listOrganizations({ limit: parseInt(opts.limit) });
290
+ print(result, getFormat(orgCmd));
291
+ } catch (err) {
292
+ error(String(err));
293
+ process.exit(1);
294
+ }
295
+ });
296
+
297
+ orgCmd
298
+ .command('get <id>')
299
+ .description('Get an organization by ID')
300
+ .action(async (id: string) => {
301
+ try {
302
+ const client = getClient();
303
+ const result = await client.getOrganization(parseInt(id));
304
+ print(result, getFormat(orgCmd));
305
+ } catch (err) {
306
+ error(String(err));
307
+ process.exit(1);
308
+ }
309
+ });
310
+
311
+ orgCmd
312
+ .command('create')
313
+ .description('Create a new organization')
314
+ .requiredOption('--name <name>', 'Organization name')
315
+ .option('--address <address>', 'Address')
316
+ .action(async (opts) => {
317
+ try {
318
+ const client = getClient();
319
+ const result = await client.createOrganization({
320
+ name: opts.name,
321
+ address: opts.address,
322
+ });
323
+ success('Organization created!');
324
+ print(result, getFormat(orgCmd));
325
+ } catch (err) {
326
+ error(String(err));
327
+ process.exit(1);
328
+ }
329
+ });
330
+
331
+ orgCmd
332
+ .command('delete <id>')
333
+ .description('Delete an organization')
334
+ .action(async (id: string) => {
335
+ try {
336
+ const client = getClient();
337
+ await client.deleteOrganization(parseInt(id));
338
+ success(`Organization ${id} deleted`);
339
+ } catch (err) {
340
+ error(String(err));
341
+ process.exit(1);
342
+ }
343
+ });
344
+
345
+ orgCmd
346
+ .command('search <term>')
347
+ .description('Search organizations')
348
+ .option('--limit <number>', 'Maximum results', '100')
349
+ .action(async (term: string, opts) => {
350
+ try {
351
+ const client = getClient();
352
+ const result = await client.searchOrganizations(term, { limit: parseInt(opts.limit) });
353
+ print(result, getFormat(orgCmd));
354
+ } catch (err) {
355
+ error(String(err));
356
+ process.exit(1);
357
+ }
358
+ });
359
+
360
+ // ============================================
361
+ // Deal Commands
362
+ // ============================================
363
+ const dealCmd = program
364
+ .command('deal')
365
+ .description('Deal management');
366
+
367
+ dealCmd
368
+ .command('list')
369
+ .description('List all deals')
370
+ .option('--limit <number>', 'Maximum results', '100')
371
+ .option('--status <status>', 'Filter by status (open, won, lost)')
372
+ .action(async (opts) => {
373
+ try {
374
+ const client = getClient();
375
+ const result = await client.listDeals({
376
+ limit: parseInt(opts.limit),
377
+ status: opts.status,
378
+ });
379
+ print(result, getFormat(dealCmd));
380
+ } catch (err) {
381
+ error(String(err));
382
+ process.exit(1);
383
+ }
384
+ });
385
+
386
+ dealCmd
387
+ .command('get <id>')
388
+ .description('Get a deal by ID')
389
+ .action(async (id: string) => {
390
+ try {
391
+ const client = getClient();
392
+ const result = await client.getDeal(parseInt(id));
393
+ print(result, getFormat(dealCmd));
394
+ } catch (err) {
395
+ error(String(err));
396
+ process.exit(1);
397
+ }
398
+ });
399
+
400
+ dealCmd
401
+ .command('create')
402
+ .description('Create a new deal')
403
+ .requiredOption('--title <title>', 'Deal title')
404
+ .option('--value <value>', 'Deal value')
405
+ .option('--currency <currency>', 'Currency')
406
+ .option('--person-id <id>', 'Person ID')
407
+ .option('--org-id <id>', 'Organization ID')
408
+ .option('--stage-id <id>', 'Stage ID')
409
+ .action(async (opts) => {
410
+ try {
411
+ const client = getClient();
412
+ const result = await client.createDeal({
413
+ title: opts.title,
414
+ value: opts.value ? parseFloat(opts.value) : undefined,
415
+ currency: opts.currency,
416
+ person_id: opts.personId ? parseInt(opts.personId) : undefined,
417
+ org_id: opts.orgId ? parseInt(opts.orgId) : undefined,
418
+ stage_id: opts.stageId ? parseInt(opts.stageId) : undefined,
419
+ });
420
+ success('Deal created!');
421
+ print(result, getFormat(dealCmd));
422
+ } catch (err) {
423
+ error(String(err));
424
+ process.exit(1);
425
+ }
426
+ });
427
+
428
+ dealCmd
429
+ .command('delete <id>')
430
+ .description('Delete a deal')
431
+ .action(async (id: string) => {
432
+ try {
433
+ const client = getClient();
434
+ await client.deleteDeal(parseInt(id));
435
+ success(`Deal ${id} deleted`);
436
+ } catch (err) {
437
+ error(String(err));
438
+ process.exit(1);
439
+ }
440
+ });
441
+
442
+ dealCmd
443
+ .command('search <term>')
444
+ .description('Search deals')
445
+ .option('--limit <number>', 'Maximum results', '100')
446
+ .action(async (term: string, opts) => {
447
+ try {
448
+ const client = getClient();
449
+ const result = await client.searchDeals(term, { limit: parseInt(opts.limit) });
450
+ print(result, getFormat(dealCmd));
451
+ } catch (err) {
452
+ error(String(err));
453
+ process.exit(1);
454
+ }
455
+ });
456
+
457
+ // ============================================
458
+ // Lead Commands
459
+ // ============================================
460
+ const leadCmd = program
461
+ .command('lead')
462
+ .description('Lead management');
463
+
464
+ leadCmd
465
+ .command('list')
466
+ .description('List all leads')
467
+ .option('--limit <number>', 'Maximum results', '100')
468
+ .option('--archived', 'Show archived leads')
469
+ .action(async (opts) => {
470
+ try {
471
+ const client = getClient();
472
+ const result = await client.listLeads({
473
+ limit: parseInt(opts.limit),
474
+ archived: opts.archived,
475
+ });
476
+ print(result, getFormat(leadCmd));
477
+ } catch (err) {
478
+ error(String(err));
479
+ process.exit(1);
480
+ }
481
+ });
482
+
483
+ leadCmd
484
+ .command('get <id>')
485
+ .description('Get a lead by ID')
486
+ .action(async (id: string) => {
487
+ try {
488
+ const client = getClient();
489
+ const result = await client.getLead(id);
490
+ print(result, getFormat(leadCmd));
491
+ } catch (err) {
492
+ error(String(err));
493
+ process.exit(1);
494
+ }
495
+ });
496
+
497
+ leadCmd
498
+ .command('create')
499
+ .description('Create a new lead')
500
+ .requiredOption('--title <title>', 'Lead title')
501
+ .option('--person-id <id>', 'Person ID')
502
+ .option('--org-id <id>', 'Organization ID')
503
+ .action(async (opts) => {
504
+ try {
505
+ const client = getClient();
506
+ const result = await client.createLead({
507
+ title: opts.title,
508
+ person_id: opts.personId ? parseInt(opts.personId) : undefined,
509
+ organization_id: opts.orgId ? parseInt(opts.orgId) : undefined,
510
+ });
511
+ success('Lead created!');
512
+ print(result, getFormat(leadCmd));
513
+ } catch (err) {
514
+ error(String(err));
515
+ process.exit(1);
516
+ }
517
+ });
518
+
519
+ leadCmd
520
+ .command('delete <id>')
521
+ .description('Delete a lead')
522
+ .action(async (id: string) => {
523
+ try {
524
+ const client = getClient();
525
+ await client.deleteLead(id);
526
+ success(`Lead ${id} deleted`);
527
+ } catch (err) {
528
+ error(String(err));
529
+ process.exit(1);
530
+ }
531
+ });
532
+
533
+ // ============================================
534
+ // Activity Commands
535
+ // ============================================
536
+ const activityCmd = program
537
+ .command('activity')
538
+ .description('Activity management');
539
+
540
+ activityCmd
541
+ .command('list')
542
+ .description('List all activities')
543
+ .option('--limit <number>', 'Maximum results', '100')
544
+ .option('--done', 'Show only done activities')
545
+ .option('--type <type>', 'Filter by type')
546
+ .action(async (opts) => {
547
+ try {
548
+ const client = getClient();
549
+ const result = await client.listActivities({
550
+ limit: parseInt(opts.limit),
551
+ done: opts.done,
552
+ type: opts.type,
553
+ });
554
+ print(result, getFormat(activityCmd));
555
+ } catch (err) {
556
+ error(String(err));
557
+ process.exit(1);
558
+ }
559
+ });
560
+
561
+ activityCmd
562
+ .command('get <id>')
563
+ .description('Get an activity by ID')
564
+ .action(async (id: string) => {
565
+ try {
566
+ const client = getClient();
567
+ const result = await client.getActivity(parseInt(id));
568
+ print(result, getFormat(activityCmd));
569
+ } catch (err) {
570
+ error(String(err));
571
+ process.exit(1);
572
+ }
573
+ });
574
+
575
+ activityCmd
576
+ .command('create')
577
+ .description('Create a new activity')
578
+ .requiredOption('--type <type>', 'Activity type (call, meeting, task, deadline, email, lunch)')
579
+ .option('--subject <subject>', 'Subject')
580
+ .option('--due-date <date>', 'Due date (YYYY-MM-DD)')
581
+ .option('--due-time <time>', 'Due time (HH:MM)')
582
+ .option('--deal-id <id>', 'Deal ID')
583
+ .option('--person-id <id>', 'Person ID')
584
+ .option('--org-id <id>', 'Organization ID')
585
+ .option('--note <note>', 'Note')
586
+ .action(async (opts) => {
587
+ try {
588
+ const client = getClient();
589
+ const result = await client.createActivity({
590
+ type: opts.type,
591
+ subject: opts.subject,
592
+ due_date: opts.dueDate,
593
+ due_time: opts.dueTime,
594
+ deal_id: opts.dealId ? parseInt(opts.dealId) : undefined,
595
+ person_id: opts.personId ? parseInt(opts.personId) : undefined,
596
+ org_id: opts.orgId ? parseInt(opts.orgId) : undefined,
597
+ note: opts.note,
598
+ });
599
+ success('Activity created!');
600
+ print(result, getFormat(activityCmd));
601
+ } catch (err) {
602
+ error(String(err));
603
+ process.exit(1);
604
+ }
605
+ });
606
+
607
+ activityCmd
608
+ .command('delete <id>')
609
+ .description('Delete an activity')
610
+ .action(async (id: string) => {
611
+ try {
612
+ const client = getClient();
613
+ await client.deleteActivity(parseInt(id));
614
+ success(`Activity ${id} deleted`);
615
+ } catch (err) {
616
+ error(String(err));
617
+ process.exit(1);
618
+ }
619
+ });
620
+
621
+ // ============================================
622
+ // Pipeline Commands
623
+ // ============================================
624
+ const pipelineCmd = program
625
+ .command('pipeline')
626
+ .description('Pipeline management');
627
+
628
+ pipelineCmd
629
+ .command('list')
630
+ .description('List all pipelines')
631
+ .action(async () => {
632
+ try {
633
+ const client = getClient();
634
+ const result = await client.listPipelines();
635
+ print(result, getFormat(pipelineCmd));
636
+ } catch (err) {
637
+ error(String(err));
638
+ process.exit(1);
639
+ }
640
+ });
641
+
642
+ pipelineCmd
643
+ .command('get <id>')
644
+ .description('Get a pipeline by ID')
645
+ .action(async (id: string) => {
646
+ try {
647
+ const client = getClient();
648
+ const result = await client.getPipeline(parseInt(id));
649
+ print(result, getFormat(pipelineCmd));
650
+ } catch (err) {
651
+ error(String(err));
652
+ process.exit(1);
653
+ }
654
+ });
655
+
656
+ // ============================================
657
+ // Stage Commands
658
+ // ============================================
659
+ const stageCmd = program
660
+ .command('stage')
661
+ .description('Stage management');
662
+
663
+ stageCmd
664
+ .command('list')
665
+ .description('List all stages')
666
+ .option('--pipeline-id <id>', 'Filter by pipeline ID')
667
+ .action(async (opts) => {
668
+ try {
669
+ const client = getClient();
670
+ const result = await client.listStages(opts.pipelineId ? parseInt(opts.pipelineId) : undefined);
671
+ print(result, getFormat(stageCmd));
672
+ } catch (err) {
673
+ error(String(err));
674
+ process.exit(1);
675
+ }
676
+ });
677
+
678
+ stageCmd
679
+ .command('get <id>')
680
+ .description('Get a stage by ID')
681
+ .action(async (id: string) => {
682
+ try {
683
+ const client = getClient();
684
+ const result = await client.getStage(parseInt(id));
685
+ print(result, getFormat(stageCmd));
686
+ } catch (err) {
687
+ error(String(err));
688
+ process.exit(1);
689
+ }
690
+ });
691
+
692
+ // ============================================
693
+ // Note Commands
694
+ // ============================================
695
+ const noteCmd = program
696
+ .command('note')
697
+ .description('Note management');
698
+
699
+ noteCmd
700
+ .command('list')
701
+ .description('List all notes')
702
+ .option('--limit <number>', 'Maximum results', '100')
703
+ .option('--deal-id <id>', 'Filter by deal ID')
704
+ .option('--person-id <id>', 'Filter by person ID')
705
+ .option('--org-id <id>', 'Filter by organization ID')
706
+ .action(async (opts) => {
707
+ try {
708
+ const client = getClient();
709
+ const result = await client.listNotes({
710
+ limit: parseInt(opts.limit),
711
+ deal_id: opts.dealId ? parseInt(opts.dealId) : undefined,
712
+ person_id: opts.personId ? parseInt(opts.personId) : undefined,
713
+ org_id: opts.orgId ? parseInt(opts.orgId) : undefined,
714
+ });
715
+ print(result, getFormat(noteCmd));
716
+ } catch (err) {
717
+ error(String(err));
718
+ process.exit(1);
719
+ }
720
+ });
721
+
722
+ noteCmd
723
+ .command('get <id>')
724
+ .description('Get a note by ID')
725
+ .action(async (id: string) => {
726
+ try {
727
+ const client = getClient();
728
+ const result = await client.getNote(parseInt(id));
729
+ print(result, getFormat(noteCmd));
730
+ } catch (err) {
731
+ error(String(err));
732
+ process.exit(1);
733
+ }
734
+ });
735
+
736
+ noteCmd
737
+ .command('create')
738
+ .description('Create a new note')
739
+ .requiredOption('--content <content>', 'Note content')
740
+ .option('--deal-id <id>', 'Deal ID')
741
+ .option('--person-id <id>', 'Person ID')
742
+ .option('--org-id <id>', 'Organization ID')
743
+ .action(async (opts) => {
744
+ try {
745
+ const client = getClient();
746
+ const result = await client.createNote({
747
+ content: opts.content,
748
+ deal_id: opts.dealId ? parseInt(opts.dealId) : undefined,
749
+ person_id: opts.personId ? parseInt(opts.personId) : undefined,
750
+ org_id: opts.orgId ? parseInt(opts.orgId) : undefined,
751
+ });
752
+ success('Note created!');
753
+ print(result, getFormat(noteCmd));
754
+ } catch (err) {
755
+ error(String(err));
756
+ process.exit(1);
757
+ }
758
+ });
759
+
760
+ noteCmd
761
+ .command('delete <id>')
762
+ .description('Delete a note')
763
+ .action(async (id: string) => {
764
+ try {
765
+ const client = getClient();
766
+ await client.deleteNote(parseInt(id));
767
+ success(`Note ${id} deleted`);
768
+ } catch (err) {
769
+ error(String(err));
770
+ process.exit(1);
771
+ }
772
+ });
773
+
774
+ // ============================================
775
+ // User Commands
776
+ // ============================================
777
+ const userCmd = program
778
+ .command('user')
779
+ .description('User management');
780
+
781
+ userCmd
782
+ .command('list')
783
+ .description('List all users')
784
+ .action(async () => {
785
+ try {
786
+ const client = getClient();
787
+ const result = await client.listUsers();
788
+ print(result, getFormat(userCmd));
789
+ } catch (err) {
790
+ error(String(err));
791
+ process.exit(1);
792
+ }
793
+ });
794
+
795
+ userCmd
796
+ .command('get <id>')
797
+ .description('Get a user by ID')
798
+ .action(async (id: string) => {
799
+ try {
800
+ const client = getClient();
801
+ const result = await client.getUser(parseInt(id));
802
+ print(result, getFormat(userCmd));
803
+ } catch (err) {
804
+ error(String(err));
805
+ process.exit(1);
806
+ }
807
+ });
808
+
809
+ userCmd
810
+ .command('me')
811
+ .description('Get current user')
812
+ .action(async () => {
813
+ try {
814
+ const client = getClient();
815
+ const result = await client.getCurrentUser();
816
+ print(result, getFormat(userCmd));
817
+ } catch (err) {
818
+ error(String(err));
819
+ process.exit(1);
820
+ }
821
+ });
822
+
823
+ // Parse and execute
824
+ program.parse();