@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.
- package/README.md +271 -0
- package/dist/auth/cache-plugin.d.ts +20 -0
- package/dist/auth/cache-plugin.d.ts.map +1 -0
- package/dist/auth/cache-plugin.js +49 -0
- package/dist/auth/cache-plugin.js.map +1 -0
- package/dist/auth/config.d.ts +40 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/config.js +135 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/device-code.d.ts +2 -0
- package/dist/auth/device-code.d.ts.map +1 -0
- package/dist/auth/device-code.js +40 -0
- package/dist/auth/device-code.js.map +1 -0
- package/dist/auth/index.d.ts +4 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +4 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/login.d.ts +7 -0
- package/dist/auth/login.d.ts.map +1 -0
- package/dist/auth/login.js +22 -0
- package/dist/auth/login.js.map +1 -0
- package/dist/auth/token-manager.d.ts +4 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +85 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/cli/formatter.d.ts +5 -0
- package/dist/cli/formatter.d.ts.map +1 -0
- package/dist/cli/formatter.js +317 -0
- package/dist/cli/formatter.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +973 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/handler.d.ts +8 -0
- package/dist/core/handler.d.ts.map +1 -0
- package/dist/core/handler.js +327 -0
- package/dist/core/handler.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +924 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/calendar.d.ts +124 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +129 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/chats.d.ts +66 -0
- package/dist/tools/chats.d.ts.map +1 -0
- package/dist/tools/chats.js +102 -0
- package/dist/tools/chats.js.map +1 -0
- package/dist/tools/contacts.d.ts +138 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +189 -0
- package/dist/tools/contacts.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mail.d.ts +138 -0
- package/dist/tools/mail.d.ts.map +1 -0
- package/dist/tools/mail.js +187 -0
- package/dist/tools/mail.js.map +1 -0
- package/dist/tools/onedrive.d.ts +125 -0
- package/dist/tools/onedrive.d.ts.map +1 -0
- package/dist/tools/onedrive.js +203 -0
- package/dist/tools/onedrive.js.map +1 -0
- package/dist/tools/planner.d.ts +390 -0
- package/dist/tools/planner.d.ts.map +1 -0
- package/dist/tools/planner.js +693 -0
- package/dist/tools/planner.js.map +1 -0
- package/dist/tools/sharepoint.d.ts +138 -0
- package/dist/tools/sharepoint.d.ts.map +1 -0
- package/dist/tools/sharepoint.js +156 -0
- package/dist/tools/sharepoint.js.map +1 -0
- package/dist/tools/tasks.d.ts +107 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +131 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/teams.d.ts +66 -0
- package/dist/tools/teams.d.ts.map +1 -0
- package/dist/tools/teams.js +69 -0
- package/dist/tools/teams.js.map +1 -0
- package/dist/utils/graph-client.d.ts +15 -0
- package/dist/utils/graph-client.d.ts.map +1 -0
- package/dist/utils/graph-client.js +126 -0
- package/dist/utils/graph-client.js.map +1 -0
- package/dist/utils/signature.d.ts +2 -0
- package/dist/utils/signature.d.ts.map +1 -0
- package/dist/utils/signature.js +17 -0
- package/dist/utils/signature.js.map +1 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +20 -0
- package/dist/utils/version.js.map +1 -0
- 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
|