@awolve/myoffice 1.6.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 (94) hide show
  1. package/README.md +271 -0
  2. package/dist/auth/cache-plugin.d.ts +20 -0
  3. package/dist/auth/cache-plugin.d.ts.map +1 -0
  4. package/dist/auth/cache-plugin.js +49 -0
  5. package/dist/auth/cache-plugin.js.map +1 -0
  6. package/dist/auth/config.d.ts +40 -0
  7. package/dist/auth/config.d.ts.map +1 -0
  8. package/dist/auth/config.js +135 -0
  9. package/dist/auth/config.js.map +1 -0
  10. package/dist/auth/device-code.d.ts +2 -0
  11. package/dist/auth/device-code.d.ts.map +1 -0
  12. package/dist/auth/device-code.js +40 -0
  13. package/dist/auth/device-code.js.map +1 -0
  14. package/dist/auth/index.d.ts +4 -0
  15. package/dist/auth/index.d.ts.map +1 -0
  16. package/dist/auth/index.js +4 -0
  17. package/dist/auth/index.js.map +1 -0
  18. package/dist/auth/login.d.ts +7 -0
  19. package/dist/auth/login.d.ts.map +1 -0
  20. package/dist/auth/login.js +22 -0
  21. package/dist/auth/login.js.map +1 -0
  22. package/dist/auth/token-manager.d.ts +4 -0
  23. package/dist/auth/token-manager.d.ts.map +1 -0
  24. package/dist/auth/token-manager.js +85 -0
  25. package/dist/auth/token-manager.js.map +1 -0
  26. package/dist/cli/formatter.d.ts +5 -0
  27. package/dist/cli/formatter.d.ts.map +1 -0
  28. package/dist/cli/formatter.js +317 -0
  29. package/dist/cli/formatter.js.map +1 -0
  30. package/dist/cli.d.ts +3 -0
  31. package/dist/cli.d.ts.map +1 -0
  32. package/dist/cli.js +973 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/core/handler.d.ts +8 -0
  35. package/dist/core/handler.d.ts.map +1 -0
  36. package/dist/core/handler.js +327 -0
  37. package/dist/core/handler.js.map +1 -0
  38. package/dist/index.d.ts +3 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +924 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/tools/calendar.d.ts +124 -0
  43. package/dist/tools/calendar.d.ts.map +1 -0
  44. package/dist/tools/calendar.js +129 -0
  45. package/dist/tools/calendar.js.map +1 -0
  46. package/dist/tools/chats.d.ts +66 -0
  47. package/dist/tools/chats.d.ts.map +1 -0
  48. package/dist/tools/chats.js +102 -0
  49. package/dist/tools/chats.js.map +1 -0
  50. package/dist/tools/contacts.d.ts +138 -0
  51. package/dist/tools/contacts.d.ts.map +1 -0
  52. package/dist/tools/contacts.js +189 -0
  53. package/dist/tools/contacts.js.map +1 -0
  54. package/dist/tools/index.d.ts +10 -0
  55. package/dist/tools/index.d.ts.map +1 -0
  56. package/dist/tools/index.js +10 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/mail.d.ts +138 -0
  59. package/dist/tools/mail.d.ts.map +1 -0
  60. package/dist/tools/mail.js +187 -0
  61. package/dist/tools/mail.js.map +1 -0
  62. package/dist/tools/onedrive.d.ts +125 -0
  63. package/dist/tools/onedrive.d.ts.map +1 -0
  64. package/dist/tools/onedrive.js +203 -0
  65. package/dist/tools/onedrive.js.map +1 -0
  66. package/dist/tools/planner.d.ts +390 -0
  67. package/dist/tools/planner.d.ts.map +1 -0
  68. package/dist/tools/planner.js +693 -0
  69. package/dist/tools/planner.js.map +1 -0
  70. package/dist/tools/sharepoint.d.ts +138 -0
  71. package/dist/tools/sharepoint.d.ts.map +1 -0
  72. package/dist/tools/sharepoint.js +156 -0
  73. package/dist/tools/sharepoint.js.map +1 -0
  74. package/dist/tools/tasks.d.ts +107 -0
  75. package/dist/tools/tasks.d.ts.map +1 -0
  76. package/dist/tools/tasks.js +131 -0
  77. package/dist/tools/tasks.js.map +1 -0
  78. package/dist/tools/teams.d.ts +66 -0
  79. package/dist/tools/teams.d.ts.map +1 -0
  80. package/dist/tools/teams.js +69 -0
  81. package/dist/tools/teams.js.map +1 -0
  82. package/dist/utils/graph-client.d.ts +15 -0
  83. package/dist/utils/graph-client.d.ts.map +1 -0
  84. package/dist/utils/graph-client.js +126 -0
  85. package/dist/utils/graph-client.js.map +1 -0
  86. package/dist/utils/signature.d.ts +2 -0
  87. package/dist/utils/signature.d.ts.map +1 -0
  88. package/dist/utils/signature.js +17 -0
  89. package/dist/utils/signature.js.map +1 -0
  90. package/dist/utils/version.d.ts +2 -0
  91. package/dist/utils/version.d.ts.map +1 -0
  92. package/dist/utils/version.js +20 -0
  93. package/dist/utils/version.js.map +1 -0
  94. package/package.json +55 -0
package/dist/cli.js ADDED
@@ -0,0 +1,973 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { getVersion } from './utils/version.js';
4
+ import { executeCommand } from './core/handler.js';
5
+ import { isAuthenticated, authenticateWithDeviceCode } from './auth/index.js';
6
+ import { formatOutput } from './cli/formatter.js';
7
+ import { saveStoredConfig, getStoredConfig } from './auth/config.js';
8
+ const program = new Command();
9
+ // Global state for JSON output mode
10
+ let jsonOutput = false;
11
+ let currentToolName;
12
+ function output(data) {
13
+ if (jsonOutput) {
14
+ console.log(JSON.stringify(data, null, 2));
15
+ }
16
+ else {
17
+ console.log(formatOutput(data, currentToolName));
18
+ }
19
+ }
20
+ function outputError(message, code) {
21
+ if (jsonOutput) {
22
+ console.error(JSON.stringify({ error: message, code: code || 'ERROR' }));
23
+ }
24
+ else {
25
+ console.error(`Error: ${message}`);
26
+ }
27
+ process.exit(1);
28
+ }
29
+ async function requireAuth() {
30
+ const authenticated = await isAuthenticated();
31
+ if (!authenticated) {
32
+ outputError('Not authenticated. Run: myoffice login', 'AUTH_REQUIRED');
33
+ }
34
+ }
35
+ async function runCommand(toolName, args = {}) {
36
+ await requireAuth();
37
+ currentToolName = toolName;
38
+ const result = await executeCommand(toolName, args);
39
+ if (result.success) {
40
+ output(result.data);
41
+ }
42
+ else {
43
+ outputError(result.error || 'Unknown error', result.code);
44
+ }
45
+ }
46
+ // Main program setup
47
+ program
48
+ .name('myoffice')
49
+ .description('Access your Microsoft 365 data from the command line')
50
+ .version(getVersion())
51
+ .option('--json', 'Output as JSON')
52
+ .hook('preAction', (thisCommand) => {
53
+ const opts = thisCommand.opts();
54
+ jsonOutput = opts.json || false;
55
+ });
56
+ // Login command
57
+ program
58
+ .command('login')
59
+ .description('Authenticate with Microsoft 365')
60
+ .option('--client-id <id>', 'Azure AD client ID (saved for future use)')
61
+ .option('--tenant-id <id>', 'Azure AD tenant ID (default: common)')
62
+ .action(async (opts) => {
63
+ try {
64
+ // Save client-id and tenant-id if provided
65
+ if (opts.clientId || opts.tenantId) {
66
+ const configToSave = {};
67
+ if (opts.clientId)
68
+ configToSave.clientId = opts.clientId;
69
+ if (opts.tenantId)
70
+ configToSave.tenantId = opts.tenantId;
71
+ saveStoredConfig(configToSave);
72
+ console.log('Configuration saved.');
73
+ // Reload config for this session
74
+ if (opts.clientId) {
75
+ // Set environment variable for this process so auth picks it up
76
+ process.env.M365_CLIENT_ID = opts.clientId;
77
+ }
78
+ if (opts.tenantId) {
79
+ process.env.M365_TENANT_ID = opts.tenantId;
80
+ }
81
+ }
82
+ // Check if we have a client ID
83
+ const storedConfig = getStoredConfig();
84
+ const clientId = process.env.M365_CLIENT_ID || storedConfig.clientId;
85
+ if (!clientId) {
86
+ outputError('No client ID configured. Run: myoffice login --client-id <your-azure-app-client-id>', 'CONFIG_REQUIRED');
87
+ }
88
+ console.log('Starting authentication...');
89
+ console.log('');
90
+ await authenticateWithDeviceCode();
91
+ console.log('');
92
+ console.log('Authentication successful!');
93
+ }
94
+ catch (error) {
95
+ const message = error instanceof Error ? error.message : String(error);
96
+ outputError(`Authentication failed: ${message}`, 'AUTH_FAILED');
97
+ }
98
+ });
99
+ // Status command
100
+ program
101
+ .command('status')
102
+ .description('Check authentication status')
103
+ .action(async () => {
104
+ currentToolName = 'auth_status';
105
+ const result = await executeCommand('auth_status', {});
106
+ if (result.success) {
107
+ output(result.data);
108
+ }
109
+ else {
110
+ outputError(result.error || 'Failed to get status', result.code);
111
+ }
112
+ });
113
+ // Debug command
114
+ program
115
+ .command('debug')
116
+ .description('Show debug information')
117
+ .action(async () => {
118
+ currentToolName = 'debug_info';
119
+ const result = await executeCommand('debug_info', {});
120
+ if (result.success) {
121
+ output(result.data);
122
+ }
123
+ else {
124
+ outputError(result.error || 'Failed to get debug info', result.code);
125
+ }
126
+ });
127
+ // Config command
128
+ const configCmd = program
129
+ .command('config')
130
+ .description('View or set configuration');
131
+ configCmd
132
+ .command('show')
133
+ .description('Show current configuration')
134
+ .action(() => {
135
+ const stored = getStoredConfig();
136
+ const envClientId = process.env.M365_CLIENT_ID;
137
+ const envTenantId = process.env.M365_TENANT_ID;
138
+ const config = {
139
+ clientId: {
140
+ value: envClientId || stored.clientId || null,
141
+ source: envClientId ? 'environment' : stored.clientId ? 'config file' : 'not set',
142
+ },
143
+ tenantId: {
144
+ value: envTenantId || stored.tenantId || 'common',
145
+ source: envTenantId ? 'environment' : stored.tenantId ? 'config file' : 'default',
146
+ },
147
+ configFile: '~/.config/myoffice-mcp/config.json',
148
+ };
149
+ output(config);
150
+ });
151
+ configCmd
152
+ .command('set')
153
+ .description('Set configuration values')
154
+ .option('--client-id <id>', 'Azure AD client ID')
155
+ .option('--tenant-id <id>', 'Azure AD tenant ID')
156
+ .action((opts) => {
157
+ if (!opts.clientId && !opts.tenantId) {
158
+ outputError('Specify --client-id and/or --tenant-id to set', 'MISSING_ARGS');
159
+ }
160
+ const configToSave = {};
161
+ if (opts.clientId)
162
+ configToSave.clientId = opts.clientId;
163
+ if (opts.tenantId)
164
+ configToSave.tenantId = opts.tenantId;
165
+ saveStoredConfig(configToSave);
166
+ console.log('Configuration saved to ~/.config/myoffice-mcp/config.json');
167
+ if (opts.clientId)
168
+ console.log(` Client ID: ${opts.clientId.substring(0, 8)}...`);
169
+ if (opts.tenantId)
170
+ console.log(` Tenant ID: ${opts.tenantId}`);
171
+ });
172
+ // Mail commands
173
+ const mailCmd = program
174
+ .command('mail')
175
+ .description('Email operations (list, read, send, reply, search, delete, mark)');
176
+ mailCmd
177
+ .command('list')
178
+ .description('List emails from a folder')
179
+ .option('--folder <name>', 'Folder name (default: inbox)')
180
+ .option('--limit <n>', 'Maximum emails to return', '25')
181
+ .option('--unread', 'Only show unread emails')
182
+ .action(async (opts) => {
183
+ await runCommand('mail_list', {
184
+ folder: opts.folder,
185
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
186
+ unreadOnly: opts.unread || undefined,
187
+ });
188
+ });
189
+ mailCmd
190
+ .command('read')
191
+ .description('Read a specific email')
192
+ .requiredOption('--id <messageId>', 'The message ID')
193
+ .action(async (opts) => {
194
+ await runCommand('mail_read', { messageId: opts.id });
195
+ });
196
+ mailCmd
197
+ .command('search')
198
+ .description('Search emails')
199
+ .requiredOption('--query <query>', 'Search query')
200
+ .option('--limit <n>', 'Maximum results', '25')
201
+ .action(async (opts) => {
202
+ await runCommand('mail_search', {
203
+ query: opts.query,
204
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
205
+ });
206
+ });
207
+ mailCmd
208
+ .command('send')
209
+ .description('Send an email')
210
+ .requiredOption('--to <emails...>', 'Recipient emails')
211
+ .requiredOption('--subject <subject>', 'Email subject')
212
+ .requiredOption('--body <body>', 'Email body')
213
+ .option('--cc <emails...>', 'CC recipients')
214
+ .option('--bcc <emails...>', 'BCC recipients')
215
+ .option('--no-html', 'Send as plain text')
216
+ .option('--no-signature', 'Do not append signature')
217
+ .action(async (opts) => {
218
+ await runCommand('mail_send', {
219
+ to: opts.to,
220
+ subject: opts.subject,
221
+ body: opts.body,
222
+ cc: opts.cc,
223
+ bcc: opts.bcc,
224
+ isHtml: opts.html !== false,
225
+ useSignature: opts.signature !== false,
226
+ });
227
+ });
228
+ mailCmd
229
+ .command('reply')
230
+ .description('Reply to an email')
231
+ .requiredOption('--id <messageId>', 'The message ID to reply to')
232
+ .requiredOption('--body <body>', 'Reply body')
233
+ .option('--all', 'Reply to all recipients')
234
+ .option('--no-html', 'Send as plain text')
235
+ .option('--signature', 'Append signature')
236
+ .action(async (opts) => {
237
+ await runCommand('mail_reply', {
238
+ messageId: opts.id,
239
+ body: opts.body,
240
+ replyAll: opts.all || false,
241
+ isHtml: opts.html !== false,
242
+ useSignature: opts.signature || false,
243
+ });
244
+ });
245
+ mailCmd
246
+ .command('delete')
247
+ .description('Delete an email')
248
+ .requiredOption('--id <messageId>', 'The message ID to delete')
249
+ .action(async (opts) => {
250
+ await runCommand('mail_delete', { messageId: opts.id });
251
+ });
252
+ mailCmd
253
+ .command('mark')
254
+ .description('Mark an email as read or unread')
255
+ .requiredOption('--id <messageId>', 'The message ID')
256
+ .option('--unread', 'Mark as unread (default: mark as read)')
257
+ .action(async (opts) => {
258
+ await runCommand('mail_mark_read', {
259
+ messageId: opts.id,
260
+ isRead: !opts.unread,
261
+ });
262
+ });
263
+ // Calendar commands
264
+ const calendarCmd = program
265
+ .command('calendar')
266
+ .description('Calendar events (list, get, create, update, delete)');
267
+ calendarCmd
268
+ .command('list')
269
+ .description('List calendar events')
270
+ .option('--start <date>', 'Start date (ISO format)')
271
+ .option('--end <date>', 'End date (ISO format)')
272
+ .option('--limit <n>', 'Maximum events', '50')
273
+ .action(async (opts) => {
274
+ await runCommand('calendar_list', {
275
+ startDate: opts.start,
276
+ endDate: opts.end,
277
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
278
+ });
279
+ });
280
+ calendarCmd
281
+ .command('get')
282
+ .description('Get details of a calendar event')
283
+ .requiredOption('--id <eventId>', 'The event ID')
284
+ .action(async (opts) => {
285
+ await runCommand('calendar_get', { eventId: opts.id });
286
+ });
287
+ calendarCmd
288
+ .command('create')
289
+ .description('Create a calendar event')
290
+ .requiredOption('--subject <subject>', 'Event title')
291
+ .requiredOption('--start <datetime>', 'Start datetime (ISO)')
292
+ .requiredOption('--end <datetime>', 'End datetime (ISO)')
293
+ .option('--timezone <tz>', 'Timezone (default: UTC)')
294
+ .option('--location <location>', 'Event location')
295
+ .option('--body <body>', 'Event description')
296
+ .option('--attendees <emails...>', 'Attendee emails')
297
+ .option('--online', 'Create Teams meeting')
298
+ .action(async (opts) => {
299
+ await runCommand('calendar_create', {
300
+ subject: opts.subject,
301
+ start: opts.start,
302
+ end: opts.end,
303
+ timeZone: opts.timezone,
304
+ location: opts.location,
305
+ body: opts.body,
306
+ attendees: opts.attendees,
307
+ isOnlineMeeting: opts.online || false,
308
+ });
309
+ });
310
+ calendarCmd
311
+ .command('update')
312
+ .description('Update a calendar event')
313
+ .requiredOption('--id <eventId>', 'The event ID')
314
+ .option('--subject <subject>', 'New title')
315
+ .option('--start <datetime>', 'New start datetime')
316
+ .option('--end <datetime>', 'New end datetime')
317
+ .option('--location <location>', 'New location')
318
+ .option('--body <body>', 'New description')
319
+ .action(async (opts) => {
320
+ await runCommand('calendar_update', {
321
+ eventId: opts.id,
322
+ subject: opts.subject,
323
+ start: opts.start,
324
+ end: opts.end,
325
+ location: opts.location,
326
+ body: opts.body,
327
+ });
328
+ });
329
+ calendarCmd
330
+ .command('delete')
331
+ .description('Delete a calendar event')
332
+ .requiredOption('--id <eventId>', 'The event ID to delete')
333
+ .action(async (opts) => {
334
+ await runCommand('calendar_delete', { eventId: opts.id });
335
+ });
336
+ // Tasks commands
337
+ const tasksCmd = program
338
+ .command('tasks')
339
+ .description('Microsoft To Do (lists, list, create, update, complete, delete)');
340
+ tasksCmd
341
+ .command('lists')
342
+ .description('List all task lists')
343
+ .action(async () => {
344
+ await runCommand('tasks_list_lists', {});
345
+ });
346
+ tasksCmd
347
+ .command('list')
348
+ .description('List tasks from a task list')
349
+ .option('--list-id <listId>', 'Task list ID (default: default list)')
350
+ .option('--include-completed', 'Include completed tasks')
351
+ .option('--limit <n>', 'Maximum tasks', '50')
352
+ .action(async (opts) => {
353
+ await runCommand('tasks_list', {
354
+ listId: opts.listId,
355
+ includeCompleted: opts.includeCompleted || false,
356
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
357
+ });
358
+ });
359
+ tasksCmd
360
+ .command('create')
361
+ .description('Create a new task')
362
+ .requiredOption('--title <title>', 'Task title')
363
+ .option('--list-id <listId>', 'Task list ID')
364
+ .option('--due <date>', 'Due date (ISO)')
365
+ .option('--importance <level>', 'Importance: low, normal, high')
366
+ .option('--body <body>', 'Task notes')
367
+ .action(async (opts) => {
368
+ await runCommand('tasks_create', {
369
+ title: opts.title,
370
+ listId: opts.listId,
371
+ dueDate: opts.due,
372
+ importance: opts.importance,
373
+ body: opts.body,
374
+ });
375
+ });
376
+ tasksCmd
377
+ .command('update')
378
+ .description('Update a task')
379
+ .requiredOption('--id <taskId>', 'Task ID')
380
+ .option('--list-id <listId>', 'Task list ID')
381
+ .option('--title <title>', 'New title')
382
+ .option('--due <date>', 'New due date')
383
+ .option('--importance <level>', 'New importance: low, normal, high')
384
+ .option('--body <body>', 'New notes')
385
+ .action(async (opts) => {
386
+ await runCommand('tasks_update', {
387
+ taskId: opts.id,
388
+ listId: opts.listId,
389
+ title: opts.title,
390
+ dueDate: opts.due,
391
+ importance: opts.importance,
392
+ body: opts.body,
393
+ });
394
+ });
395
+ tasksCmd
396
+ .command('complete')
397
+ .description('Mark a task as completed')
398
+ .requiredOption('--id <taskId>', 'Task ID')
399
+ .option('--list-id <listId>', 'Task list ID')
400
+ .action(async (opts) => {
401
+ await runCommand('tasks_complete', {
402
+ taskId: opts.id,
403
+ listId: opts.listId,
404
+ });
405
+ });
406
+ tasksCmd
407
+ .command('delete')
408
+ .description('Delete a task')
409
+ .requiredOption('--id <taskId>', 'Task ID')
410
+ .option('--list-id <listId>', 'Task list ID')
411
+ .action(async (opts) => {
412
+ await runCommand('tasks_delete', {
413
+ taskId: opts.id,
414
+ listId: opts.listId,
415
+ });
416
+ });
417
+ // Files (OneDrive) commands
418
+ const filesCmd = program
419
+ .command('files')
420
+ .description('OneDrive files (list, get, search, read, mkdir, shared, upload)');
421
+ filesCmd
422
+ .command('list')
423
+ .description('List files and folders')
424
+ .option('--path <path>', 'Folder path (default: root)')
425
+ .option('--limit <n>', 'Maximum items', '50')
426
+ .action(async (opts) => {
427
+ await runCommand('onedrive_list', {
428
+ path: opts.path,
429
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
430
+ });
431
+ });
432
+ filesCmd
433
+ .command('get')
434
+ .description('Get metadata for a file or folder')
435
+ .requiredOption('--path <path>', 'File/folder path')
436
+ .action(async (opts) => {
437
+ await runCommand('onedrive_get', { path: opts.path });
438
+ });
439
+ filesCmd
440
+ .command('search')
441
+ .description('Search for files')
442
+ .requiredOption('--query <query>', 'Search query')
443
+ .option('--limit <n>', 'Maximum results', '25')
444
+ .action(async (opts) => {
445
+ await runCommand('onedrive_search', {
446
+ query: opts.query,
447
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
448
+ });
449
+ });
450
+ filesCmd
451
+ .command('read')
452
+ .description('Read content of a text file')
453
+ .requiredOption('--path <path>', 'File path')
454
+ .action(async (opts) => {
455
+ await runCommand('onedrive_read', { path: opts.path });
456
+ });
457
+ filesCmd
458
+ .command('mkdir')
459
+ .description('Create a new folder')
460
+ .requiredOption('--name <name>', 'Folder name')
461
+ .option('--parent <path>', 'Parent path (default: root)')
462
+ .action(async (opts) => {
463
+ await runCommand('onedrive_create_folder', {
464
+ name: opts.name,
465
+ parentPath: opts.parent,
466
+ });
467
+ });
468
+ filesCmd
469
+ .command('shared')
470
+ .description('List files shared with you')
471
+ .option('--limit <n>', 'Maximum items', '50')
472
+ .action(async (opts) => {
473
+ await runCommand('onedrive_shared_with_me', {
474
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
475
+ });
476
+ });
477
+ filesCmd
478
+ .command('upload')
479
+ .description('Upload a local file to OneDrive')
480
+ .requiredOption('--file <path>', 'Local file path to upload')
481
+ .option('--dest <path>', 'Destination path in OneDrive')
482
+ .action(async (opts) => {
483
+ await runCommand('onedrive_upload', {
484
+ localPath: opts.file,
485
+ remotePath: opts.dest,
486
+ });
487
+ });
488
+ // SharePoint commands
489
+ const sharepointCmd = program
490
+ .command('sharepoint')
491
+ .description('SharePoint sites and document libraries');
492
+ sharepointCmd
493
+ .command('sites')
494
+ .description('List SharePoint sites')
495
+ .option('--search <query>', 'Search query to find sites')
496
+ .option('--limit <n>', 'Maximum sites', '50')
497
+ .action(async (opts) => {
498
+ await runCommand('sharepoint_list_sites', {
499
+ search: opts.search,
500
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
501
+ });
502
+ });
503
+ sharepointCmd
504
+ .command('site')
505
+ .description('Get details of a SharePoint site')
506
+ .requiredOption('--id <siteId>', 'Site ID or hostname:path')
507
+ .action(async (opts) => {
508
+ await runCommand('sharepoint_get_site', { siteId: opts.id });
509
+ });
510
+ sharepointCmd
511
+ .command('drives')
512
+ .description('List document libraries in a site')
513
+ .requiredOption('--site-id <siteId>', 'Site ID')
514
+ .option('--limit <n>', 'Maximum drives', '50')
515
+ .action(async (opts) => {
516
+ await runCommand('sharepoint_list_drives', {
517
+ siteId: opts.siteId,
518
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
519
+ });
520
+ });
521
+ sharepointCmd
522
+ .command('files')
523
+ .description('List files in a document library')
524
+ .requiredOption('--drive-id <driveId>', 'Drive ID')
525
+ .option('--path <path>', 'Folder path (default: root)')
526
+ .option('--limit <n>', 'Maximum items', '50')
527
+ .action(async (opts) => {
528
+ await runCommand('sharepoint_list_files', {
529
+ driveId: opts.driveId,
530
+ path: opts.path,
531
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
532
+ });
533
+ });
534
+ sharepointCmd
535
+ .command('file')
536
+ .description('Get metadata for a file')
537
+ .requiredOption('--drive-id <driveId>', 'Drive ID')
538
+ .requiredOption('--path <path>', 'File path')
539
+ .action(async (opts) => {
540
+ await runCommand('sharepoint_get_file', {
541
+ driveId: opts.driveId,
542
+ path: opts.path,
543
+ });
544
+ });
545
+ sharepointCmd
546
+ .command('read')
547
+ .description('Read content of a text file')
548
+ .requiredOption('--drive-id <driveId>', 'Drive ID')
549
+ .requiredOption('--path <path>', 'File path')
550
+ .action(async (opts) => {
551
+ await runCommand('sharepoint_read_file', {
552
+ driveId: opts.driveId,
553
+ path: opts.path,
554
+ });
555
+ });
556
+ sharepointCmd
557
+ .command('search')
558
+ .description('Search for files in a document library')
559
+ .requiredOption('--drive-id <driveId>', 'Drive ID')
560
+ .requiredOption('--query <query>', 'Search query')
561
+ .option('--limit <n>', 'Maximum results', '25')
562
+ .action(async (opts) => {
563
+ await runCommand('sharepoint_search_files', {
564
+ driveId: opts.driveId,
565
+ query: opts.query,
566
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
567
+ });
568
+ });
569
+ // Contacts commands
570
+ const contactsCmd = program
571
+ .command('contacts')
572
+ .description('Contacts (list, search, get, create, update)');
573
+ contactsCmd
574
+ .command('list')
575
+ .description('List contacts')
576
+ .option('--limit <n>', 'Maximum contacts', '50')
577
+ .action(async (opts) => {
578
+ await runCommand('contacts_list', {
579
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
580
+ });
581
+ });
582
+ contactsCmd
583
+ .command('search')
584
+ .description('Search contacts')
585
+ .requiredOption('--query <query>', 'Search query')
586
+ .option('--limit <n>', 'Maximum results', '25')
587
+ .action(async (opts) => {
588
+ await runCommand('contacts_search', {
589
+ query: opts.query,
590
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
591
+ });
592
+ });
593
+ contactsCmd
594
+ .command('get')
595
+ .description('Get details of a contact')
596
+ .requiredOption('--id <contactId>', 'Contact ID')
597
+ .action(async (opts) => {
598
+ await runCommand('contacts_get', { contactId: opts.id });
599
+ });
600
+ contactsCmd
601
+ .command('create')
602
+ .description('Create a new contact')
603
+ .option('--given-name <name>', 'First name')
604
+ .option('--surname <name>', 'Last name')
605
+ .option('--email <email>', 'Email address')
606
+ .option('--mobile <phone>', 'Mobile phone')
607
+ .option('--business-phone <phone>', 'Business phone')
608
+ .option('--company <name>', 'Company name')
609
+ .option('--job-title <title>', 'Job title')
610
+ .option('--notes <text>', 'Personal notes about the contact')
611
+ .option('--birthday <date>', 'Birthday (ISO date, e.g., 1990-05-15)')
612
+ .action(async (opts) => {
613
+ await runCommand('contacts_create', {
614
+ givenName: opts.givenName,
615
+ surname: opts.surname,
616
+ email: opts.email,
617
+ mobilePhone: opts.mobile,
618
+ businessPhone: opts.businessPhone,
619
+ companyName: opts.company,
620
+ jobTitle: opts.jobTitle,
621
+ notes: opts.notes,
622
+ birthday: opts.birthday,
623
+ });
624
+ });
625
+ contactsCmd
626
+ .command('update')
627
+ .description('Update an existing contact')
628
+ .requiredOption('--id <contactId>', 'Contact ID')
629
+ .option('--given-name <name>', 'First name')
630
+ .option('--surname <name>', 'Last name')
631
+ .option('--email <email>', 'Email address')
632
+ .option('--mobile <phone>', 'Mobile phone')
633
+ .option('--business-phone <phone>', 'Business phone')
634
+ .option('--company <name>', 'Company name')
635
+ .option('--job-title <title>', 'Job title')
636
+ .option('--notes <text>', 'Personal notes about the contact')
637
+ .option('--birthday <date>', 'Birthday (ISO date, e.g., 1990-05-15)')
638
+ .action(async (opts) => {
639
+ await runCommand('contacts_update', {
640
+ contactId: opts.id,
641
+ givenName: opts.givenName,
642
+ surname: opts.surname,
643
+ email: opts.email,
644
+ mobilePhone: opts.mobile,
645
+ businessPhone: opts.businessPhone,
646
+ companyName: opts.company,
647
+ jobTitle: opts.jobTitle,
648
+ notes: opts.notes,
649
+ birthday: opts.birthday,
650
+ });
651
+ });
652
+ // Teams commands
653
+ const teamsCmd = program
654
+ .command('teams')
655
+ .description('Teams channels and messages');
656
+ teamsCmd
657
+ .command('list')
658
+ .description('List Teams you are a member of')
659
+ .option('--limit <n>', 'Maximum teams', '50')
660
+ .action(async (opts) => {
661
+ await runCommand('teams_list', {
662
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
663
+ });
664
+ });
665
+ teamsCmd
666
+ .command('channels')
667
+ .description('List channels in a Team')
668
+ .requiredOption('--team-id <teamId>', 'Team ID')
669
+ .action(async (opts) => {
670
+ await runCommand('teams_channels', { teamId: opts.teamId });
671
+ });
672
+ teamsCmd
673
+ .command('messages')
674
+ .description('Read messages from a channel')
675
+ .requiredOption('--team-id <teamId>', 'Team ID')
676
+ .requiredOption('--channel-id <channelId>', 'Channel ID')
677
+ .option('--limit <n>', 'Maximum messages', '25')
678
+ .action(async (opts) => {
679
+ await runCommand('teams_channel_messages', {
680
+ teamId: opts.teamId,
681
+ channelId: opts.channelId,
682
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
683
+ });
684
+ });
685
+ teamsCmd
686
+ .command('post')
687
+ .description('Post a message to a channel')
688
+ .requiredOption('--team-id <teamId>', 'Team ID')
689
+ .requiredOption('--channel-id <channelId>', 'Channel ID')
690
+ .requiredOption('--content <content>', 'Message content')
691
+ .action(async (opts) => {
692
+ await runCommand('teams_channel_post', {
693
+ teamId: opts.teamId,
694
+ channelId: opts.channelId,
695
+ content: opts.content,
696
+ });
697
+ });
698
+ // Chats commands
699
+ const chatsCmd = program
700
+ .command('chats')
701
+ .description('1:1 and group chats');
702
+ chatsCmd
703
+ .command('list')
704
+ .description('List your chats')
705
+ .option('--limit <n>', 'Maximum chats', '25')
706
+ .action(async (opts) => {
707
+ await runCommand('chats_list', {
708
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
709
+ });
710
+ });
711
+ chatsCmd
712
+ .command('messages')
713
+ .description('Read messages from a chat')
714
+ .requiredOption('--chat-id <chatId>', 'Chat ID')
715
+ .option('--limit <n>', 'Maximum messages', '25')
716
+ .action(async (opts) => {
717
+ await runCommand('chats_messages', {
718
+ chatId: opts.chatId,
719
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
720
+ });
721
+ });
722
+ chatsCmd
723
+ .command('send')
724
+ .description('Send a message in a chat')
725
+ .requiredOption('--chat-id <chatId>', 'Chat ID')
726
+ .requiredOption('--content <content>', 'Message content')
727
+ .action(async (opts) => {
728
+ await runCommand('chats_send', {
729
+ chatId: opts.chatId,
730
+ content: opts.content,
731
+ });
732
+ });
733
+ chatsCmd
734
+ .command('create')
735
+ .description('Create a new chat')
736
+ .requiredOption('--members <emails...>', 'Email addresses of chat members')
737
+ .option('--topic <topic>', 'Chat topic/title (for group chats)')
738
+ .action(async (opts) => {
739
+ await runCommand('chats_create', {
740
+ members: opts.members,
741
+ topic: opts.topic,
742
+ });
743
+ });
744
+ // Planner commands
745
+ const plannerCmd = program
746
+ .command('planner')
747
+ .description('Planner plans, buckets, tasks, and attachments');
748
+ plannerCmd
749
+ .command('plans')
750
+ .description('List all Planner plans')
751
+ .option('--limit <n>', 'Maximum plans', '50')
752
+ .action(async (opts) => {
753
+ await runCommand('planner_list_plans', {
754
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
755
+ });
756
+ });
757
+ plannerCmd
758
+ .command('plan')
759
+ .description('Get details of a plan')
760
+ .requiredOption('--id <planId>', 'Plan ID')
761
+ .action(async (opts) => {
762
+ await runCommand('planner_get_plan', { planId: opts.id });
763
+ });
764
+ plannerCmd
765
+ .command('buckets')
766
+ .description('List buckets in a plan')
767
+ .requiredOption('--plan-id <planId>', 'Plan ID')
768
+ .action(async (opts) => {
769
+ await runCommand('planner_list_buckets', { planId: opts.planId });
770
+ });
771
+ plannerCmd
772
+ .command('bucket-create')
773
+ .description('Create a new bucket')
774
+ .requiredOption('--plan-id <planId>', 'Plan ID')
775
+ .requiredOption('--name <name>', 'Bucket name')
776
+ .action(async (opts) => {
777
+ await runCommand('planner_create_bucket', {
778
+ planId: opts.planId,
779
+ name: opts.name,
780
+ });
781
+ });
782
+ plannerCmd
783
+ .command('bucket-update')
784
+ .description('Update a bucket')
785
+ .requiredOption('--id <bucketId>', 'Bucket ID')
786
+ .requiredOption('--name <name>', 'New bucket name')
787
+ .action(async (opts) => {
788
+ await runCommand('planner_update_bucket', {
789
+ bucketId: opts.id,
790
+ name: opts.name,
791
+ });
792
+ });
793
+ plannerCmd
794
+ .command('bucket-delete')
795
+ .description('Delete a bucket')
796
+ .requiredOption('--id <bucketId>', 'Bucket ID')
797
+ .action(async (opts) => {
798
+ await runCommand('planner_delete_bucket', { bucketId: opts.id });
799
+ });
800
+ plannerCmd
801
+ .command('tasks')
802
+ .description('List tasks in a plan')
803
+ .requiredOption('--plan-id <planId>', 'Plan ID')
804
+ .option('--bucket-id <bucketId>', 'Filter by bucket')
805
+ .option('--limit <n>', 'Maximum tasks', '100')
806
+ .action(async (opts) => {
807
+ await runCommand('planner_list_tasks', {
808
+ planId: opts.planId,
809
+ bucketId: opts.bucketId,
810
+ maxItems: opts.limit ? parseInt(opts.limit, 10) : undefined,
811
+ });
812
+ });
813
+ plannerCmd
814
+ .command('task')
815
+ .description('Get details of a task')
816
+ .requiredOption('--id <taskId>', 'Task ID')
817
+ .action(async (opts) => {
818
+ await runCommand('planner_get_task', { taskId: opts.id });
819
+ });
820
+ plannerCmd
821
+ .command('task-create')
822
+ .description('Create a new task')
823
+ .requiredOption('--plan-id <planId>', 'Plan ID')
824
+ .requiredOption('--title <title>', 'Task title')
825
+ .option('--bucket-id <bucketId>', 'Bucket ID')
826
+ .option('--assignments <emails...>', 'Assign to users (emails)')
827
+ .option('--due <datetime>', 'Due date (ISO)')
828
+ .option('--start <datetime>', 'Start date (ISO)')
829
+ .option('--priority <level>', 'Priority: urgent, important, medium, low')
830
+ .option('--progress <status>', 'Progress: notStarted, inProgress, completed')
831
+ .action(async (opts) => {
832
+ await runCommand('planner_create_task', {
833
+ planId: opts.planId,
834
+ title: opts.title,
835
+ bucketId: opts.bucketId,
836
+ assignments: opts.assignments,
837
+ dueDateTime: opts.due,
838
+ startDateTime: opts.start,
839
+ priority: opts.priority,
840
+ progress: opts.progress,
841
+ });
842
+ });
843
+ plannerCmd
844
+ .command('task-update')
845
+ .description('Update a task')
846
+ .requiredOption('--id <taskId>', 'Task ID')
847
+ .option('--title <title>', 'New title')
848
+ .option('--bucket-id <bucketId>', 'Move to bucket')
849
+ .option('--assignments <emails...>', 'Assign to users (replaces existing)')
850
+ .option('--clear-assignments', 'Remove all assignments')
851
+ .option('--due <datetime>', 'New due date')
852
+ .option('--clear-due', 'Remove due date')
853
+ .option('--start <datetime>', 'New start date')
854
+ .option('--priority <level>', 'New priority')
855
+ .option('--progress <status>', 'New progress')
856
+ .action(async (opts) => {
857
+ await runCommand('planner_update_task', {
858
+ taskId: opts.id,
859
+ title: opts.title,
860
+ bucketId: opts.bucketId,
861
+ assignments: opts.assignments,
862
+ clearAssignments: opts.clearAssignments,
863
+ dueDateTime: opts.due,
864
+ clearDue: opts.clearDue,
865
+ startDateTime: opts.start,
866
+ priority: opts.priority,
867
+ progress: opts.progress,
868
+ });
869
+ });
870
+ plannerCmd
871
+ .command('task-delete')
872
+ .description('Delete a task')
873
+ .requiredOption('--id <taskId>', 'Task ID')
874
+ .action(async (opts) => {
875
+ await runCommand('planner_delete_task', { taskId: opts.id });
876
+ });
877
+ plannerCmd
878
+ .command('task-details')
879
+ .description('Get task details (description, checklist)')
880
+ .requiredOption('--id <taskId>', 'Task ID')
881
+ .action(async (opts) => {
882
+ await runCommand('planner_get_task_details', { taskId: opts.id });
883
+ });
884
+ plannerCmd
885
+ .command('task-details-update')
886
+ .description('Update task description and checklist')
887
+ .requiredOption('--id <taskId>', 'Task ID')
888
+ .option('--description <text>', 'Task description')
889
+ .action(async (opts) => {
890
+ await runCommand('planner_update_task_details', {
891
+ taskId: opts.id,
892
+ description: opts.description,
893
+ });
894
+ });
895
+ plannerCmd
896
+ .command('attach')
897
+ .description('Add a link/attachment to a task')
898
+ .requiredOption('--id <taskId>', 'Task ID')
899
+ .requiredOption('--url <url>', 'URL to attach (file URL or web link)')
900
+ .option('--alias <name>', 'Display name for the attachment')
901
+ .option('--type <type>', 'File type: Word, Excel, PowerPoint, OneNote, SharePoint, OneDrive, Pdf, Other')
902
+ .action(async (opts) => {
903
+ await runCommand('planner_add_reference', {
904
+ taskId: opts.id,
905
+ url: opts.url,
906
+ alias: opts.alias,
907
+ type: opts.type,
908
+ });
909
+ });
910
+ plannerCmd
911
+ .command('detach')
912
+ .description('Remove an attachment/link from a task')
913
+ .requiredOption('--id <taskId>', 'Task ID')
914
+ .requiredOption('--url <url>', 'URL to remove')
915
+ .action(async (opts) => {
916
+ await runCommand('planner_remove_reference', {
917
+ taskId: opts.id,
918
+ url: opts.url,
919
+ });
920
+ });
921
+ plannerCmd
922
+ .command('upload')
923
+ .description('Upload a local file and attach it to a task')
924
+ .requiredOption('--id <taskId>', 'Task ID')
925
+ .requiredOption('--file <path>', 'Local file path to upload')
926
+ .option('--dest <path>', 'Destination path in OneDrive (default: "Planner Attachments/<filename>")')
927
+ .option('--alias <name>', 'Display name for the attachment')
928
+ .action(async (opts) => {
929
+ await runCommand('planner_upload_attach', {
930
+ taskId: opts.id,
931
+ localPath: opts.file,
932
+ remotePath: opts.dest,
933
+ alias: opts.alias,
934
+ });
935
+ });
936
+ plannerCmd
937
+ .command('checklist-add')
938
+ .description('Add a checklist item to a task')
939
+ .requiredOption('--id <taskId>', 'Task ID')
940
+ .requiredOption('--title <title>', 'Checklist item title')
941
+ .option('--checked', 'Mark item as checked')
942
+ .action(async (opts) => {
943
+ await runCommand('planner_checklist_add', {
944
+ taskId: opts.id,
945
+ title: opts.title,
946
+ isChecked: opts.checked || false,
947
+ });
948
+ });
949
+ plannerCmd
950
+ .command('checklist-remove')
951
+ .description('Remove a checklist item from a task')
952
+ .requiredOption('--id <taskId>', 'Task ID')
953
+ .requiredOption('--item <itemId>', 'Checklist item ID')
954
+ .action(async (opts) => {
955
+ await runCommand('planner_checklist_remove', {
956
+ taskId: opts.id,
957
+ itemId: opts.item,
958
+ });
959
+ });
960
+ plannerCmd
961
+ .command('checklist-toggle')
962
+ .description('Toggle the checked state of a checklist item')
963
+ .requiredOption('--id <taskId>', 'Task ID')
964
+ .requiredOption('--item <itemId>', 'Checklist item ID')
965
+ .action(async (opts) => {
966
+ await runCommand('planner_checklist_toggle', {
967
+ taskId: opts.id,
968
+ itemId: opts.item,
969
+ });
970
+ });
971
+ // Parse and execute
972
+ program.parse();
973
+ //# sourceMappingURL=cli.js.map