@lifestreamdynamics/vault-cli 1.3.5 → 1.3.6

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.
@@ -2,12 +2,27 @@ import chalk from 'chalk';
2
2
  import { getClientAsync } from '../client.js';
3
3
  import { addGlobalFlags, resolveFlags } from '../utils/flags.js';
4
4
  import { createOutput, handleError } from '../utils/output.js';
5
+ import { resolveVaultId } from '../utils/resolve-vault.js';
6
+ const NAMED_COLORS = {
7
+ red: '#ff0000', green: '#00ff00', blue: '#0000ff', yellow: '#ffff00',
8
+ orange: '#ff8c00', purple: '#800080', pink: '#ff69b4', cyan: '#00ffff',
9
+ white: '#ffffff', black: '#000000', gray: '#808080', grey: '#808080',
10
+ };
11
+ /** Resolve a color value to #RRGGBB hex format. Pass through if already hex. */
12
+ function resolveColor(value) {
13
+ if (!value)
14
+ return undefined;
15
+ const hex = NAMED_COLORS[value.toLowerCase()];
16
+ if (hex)
17
+ return hex;
18
+ return value; // pass through (API validates the format)
19
+ }
5
20
  export function registerCalendarCommands(program) {
6
21
  const calendar = program.command('calendar').description('Document calendar and due date management');
7
22
  // calendar view
8
23
  addGlobalFlags(calendar.command('view')
9
24
  .description('View calendar activity for a vault')
10
- .argument('<vaultId>', 'Vault ID')
25
+ .argument('<vaultId>', 'Vault ID or slug')
11
26
  .option('--start <date>', 'Start date (YYYY-MM-DD)')
12
27
  .option('--end <date>', 'End date (YYYY-MM-DD)'))
13
28
  .action(async (vaultId, _opts) => {
@@ -15,6 +30,7 @@ export function registerCalendarCommands(program) {
15
30
  const out = createOutput(flags);
16
31
  out.startSpinner('Loading calendar...');
17
32
  try {
33
+ vaultId = await resolveVaultId(vaultId);
18
34
  const client = await getClientAsync();
19
35
  const response = await client.calendar.getActivity(vaultId, {
20
36
  start: _opts.start ?? getDefaultStart(),
@@ -53,7 +69,7 @@ export function registerCalendarCommands(program) {
53
69
  const VALID_DUE_STATUSES = ['overdue', 'upcoming', 'all'];
54
70
  addGlobalFlags(calendar.command('due')
55
71
  .description('List documents with due dates')
56
- .argument('<vaultId>', 'Vault ID')
72
+ .argument('<vaultId>', 'Vault ID or slug')
57
73
  .option('--status <status>', 'Filter: overdue, upcoming, all', 'all'))
58
74
  .action(async (vaultId, _opts) => {
59
75
  const flags = resolveFlags(_opts);
@@ -66,6 +82,7 @@ export function registerCalendarCommands(program) {
66
82
  }
67
83
  out.startSpinner('Loading due dates...');
68
84
  try {
85
+ vaultId = await resolveVaultId(vaultId);
69
86
  const client = await getClientAsync();
70
87
  const docs = await client.calendar.getDueDates(vaultId, {
71
88
  status: (statusVal ?? 'all'),
@@ -98,7 +115,7 @@ export function registerCalendarCommands(program) {
98
115
  // calendar set-due
99
116
  addGlobalFlags(calendar.command('set-due')
100
117
  .description('Set due date on a document')
101
- .argument('<vaultId>', 'Vault ID')
118
+ .argument('<vaultId>', 'Vault ID or slug')
102
119
  .argument('<path>', 'Document path')
103
120
  .requiredOption('--date <date>', 'Due date (YYYY-MM-DD or "clear")')
104
121
  .option('--priority <priority>', 'Priority (low/medium/high)')
@@ -108,6 +125,7 @@ export function registerCalendarCommands(program) {
108
125
  const out = createOutput(flags);
109
126
  out.startSpinner('Setting due date...');
110
127
  try {
128
+ vaultId = await resolveVaultId(vaultId);
111
129
  const client = await getClientAsync();
112
130
  const dateStr = _opts.date;
113
131
  await client.calendar.setDocumentDue(vaultId, path, {
@@ -126,8 +144,8 @@ export function registerCalendarCommands(program) {
126
144
  });
127
145
  // calendar events (list)
128
146
  addGlobalFlags(calendar.command('events')
129
- .description('List calendar events')
130
- .argument('<vaultId>', 'Vault ID')
147
+ .description('Full CRUD management for calendar events (list, create, update, delete)')
148
+ .argument('<vaultId>', 'Vault ID or slug')
131
149
  .option('--start <date>', 'Start date')
132
150
  .option('--end <date>', 'End date'))
133
151
  .action(async (vaultId, _opts) => {
@@ -135,6 +153,7 @@ export function registerCalendarCommands(program) {
135
153
  const out = createOutput(flags);
136
154
  out.startSpinner('Loading events...');
137
155
  try {
156
+ vaultId = await resolveVaultId(vaultId);
138
157
  const client = await getClientAsync();
139
158
  const events = await client.calendar.listEvents(vaultId, {
140
159
  start: _opts.start,
@@ -168,7 +187,7 @@ export function registerCalendarCommands(program) {
168
187
  // calendar event create
169
188
  addGlobalFlags(event.command('create')
170
189
  .description('Create a new calendar event')
171
- .argument('<vaultId>', 'Vault ID')
190
+ .argument('<vaultId>', 'Vault ID or slug')
172
191
  .requiredOption('--title <title>', 'Event title')
173
192
  .requiredOption('--start <date>', 'Start date/time (YYYY-MM-DD or ISO 8601)')
174
193
  .option('--end <date>', 'End date/time (YYYY-MM-DD or ISO 8601)')
@@ -181,6 +200,7 @@ export function registerCalendarCommands(program) {
181
200
  const out = createOutput(flags);
182
201
  out.startSpinner('Creating event...');
183
202
  try {
203
+ vaultId = await resolveVaultId(vaultId);
184
204
  const client = await getClientAsync();
185
205
  const created = await client.calendar.createEvent(vaultId, {
186
206
  title: _opts.title,
@@ -188,7 +208,7 @@ export function registerCalendarCommands(program) {
188
208
  endDate: _opts.end,
189
209
  allDay: Boolean(_opts.allDay),
190
210
  priority: _opts.priority,
191
- color: _opts.color,
211
+ color: resolveColor(_opts.color),
192
212
  description: _opts.description,
193
213
  });
194
214
  out.stopSpinner();
@@ -206,7 +226,7 @@ export function registerCalendarCommands(program) {
206
226
  // calendar event update
207
227
  addGlobalFlags(event.command('update')
208
228
  .description('Update an existing calendar event')
209
- .argument('<vaultId>', 'Vault ID')
229
+ .argument('<vaultId>', 'Vault ID or slug')
210
230
  .argument('<eventId>', 'Event ID')
211
231
  .option('--title <title>', 'Event title')
212
232
  .option('--start <date>', 'Start date/time (YYYY-MM-DD or ISO 8601)')
@@ -220,6 +240,7 @@ export function registerCalendarCommands(program) {
220
240
  const out = createOutput(flags);
221
241
  out.startSpinner('Updating event...');
222
242
  try {
243
+ vaultId = await resolveVaultId(vaultId);
223
244
  const client = await getClientAsync();
224
245
  const data = {};
225
246
  if (_opts.title)
@@ -233,7 +254,7 @@ export function registerCalendarCommands(program) {
233
254
  if (_opts.priority)
234
255
  data.priority = _opts.priority;
235
256
  if (_opts.color)
236
- data.color = _opts.color;
257
+ data.color = resolveColor(_opts.color);
237
258
  if (_opts.description)
238
259
  data.description = _opts.description;
239
260
  const updated = await client.calendar.updateEvent(vaultId, eventId, data);
@@ -252,18 +273,20 @@ export function registerCalendarCommands(program) {
252
273
  // calendar event delete
253
274
  addGlobalFlags(event.command('delete')
254
275
  .description('Delete a calendar event')
255
- .argument('<vaultId>', 'Vault ID')
276
+ .argument('<vaultId>', 'Vault ID or slug')
256
277
  .argument('<eventId>', 'Event ID')
257
- .option('--confirm', 'Skip confirmation prompt'))
278
+ .option('-y, --yes', 'Skip confirmation prompt')
279
+ .option('--confirm', 'Alias for --yes (deprecated)'))
258
280
  .action(async (vaultId, eventId, _opts) => {
259
281
  const flags = resolveFlags(_opts);
260
282
  const out = createOutput(flags);
261
- if (!_opts.confirm) {
262
- out.status(chalk.yellow(`Pass --confirm to delete event ${eventId}`));
283
+ if (!_opts.yes && !_opts.confirm) {
284
+ out.status(chalk.yellow(`Pass -y/--yes to delete event ${eventId}`));
263
285
  return;
264
286
  }
265
287
  out.startSpinner('Deleting event...');
266
288
  try {
289
+ vaultId = await resolveVaultId(vaultId);
267
290
  const client = await getClientAsync();
268
291
  await client.calendar.deleteEvent(vaultId, eventId);
269
292
  out.stopSpinner();
@@ -276,13 +299,14 @@ export function registerCalendarCommands(program) {
276
299
  // calendar event get
277
300
  addGlobalFlags(event.command('get')
278
301
  .description('Get a single calendar event by ID')
279
- .argument('<vaultId>', 'Vault ID')
302
+ .argument('<vaultId>', 'Vault ID or slug')
280
303
  .argument('<eventId>', 'Event ID'))
281
304
  .action(async (vaultId, eventId, _opts) => {
282
305
  const flags = resolveFlags(_opts);
283
306
  const out = createOutput(flags);
284
307
  out.startSpinner('Loading event...');
285
308
  try {
309
+ vaultId = await resolveVaultId(vaultId);
286
310
  const client = await getClientAsync();
287
311
  const ev = await client.calendar.getEvent(vaultId, eventId);
288
312
  out.stopSpinner();
@@ -301,15 +325,20 @@ export function registerCalendarCommands(program) {
301
325
  // calendar timeline
302
326
  // ---------------------------------------------------------------------------
303
327
  addGlobalFlags(calendar.command('timeline')
304
- .description('View chronological event timeline for a vault')
305
- .argument('<vaultId>', 'Vault ID')
328
+ .description('Cursor-paginated event feed with before/after navigation')
329
+ .argument('<vaultId>', 'Vault ID or slug')
306
330
  .option('--limit <n>', 'Number of items to return')
307
- .option('--cursor <cursor>', 'Pagination cursor'))
331
+ .option('--cursor <cursor>', 'Pagination cursor')
332
+ .addHelpText('after', `
333
+ NOTE
334
+ Use "events" for CRUD operations on calendar events.
335
+ Use "timeline" for a cursor-paginated event feed across all event types.`))
308
336
  .action(async (vaultId, _opts) => {
309
337
  const flags = resolveFlags(_opts);
310
338
  const out = createOutput(flags);
311
339
  out.startSpinner('Loading timeline...');
312
340
  try {
341
+ vaultId = await resolveVaultId(vaultId);
313
342
  const client = await getClientAsync();
314
343
  const timeline = await client.calendar.getTimeline(vaultId, {
315
344
  limit: _opts.limit ? Number(_opts.limit) : undefined,
@@ -341,12 +370,13 @@ export function registerCalendarCommands(program) {
341
370
  // ---------------------------------------------------------------------------
342
371
  addGlobalFlags(calendar.command('upcoming')
343
372
  .description('Show upcoming events and due items for a vault')
344
- .argument('<vaultId>', 'Vault ID'))
373
+ .argument('<vaultId>', 'Vault ID or slug'))
345
374
  .action(async (vaultId, _opts) => {
346
375
  const flags = resolveFlags(_opts);
347
376
  const out = createOutput(flags);
348
377
  out.startSpinner('Loading upcoming items...');
349
378
  try {
379
+ vaultId = await resolveVaultId(vaultId);
350
380
  const client = await getClientAsync();
351
381
  const upcoming = await client.calendar.getUpcoming(vaultId);
352
382
  out.stopSpinner();
@@ -386,12 +416,13 @@ export function registerCalendarCommands(program) {
386
416
  // calendar ical-token generate
387
417
  addGlobalFlags(icalToken.command('generate')
388
418
  .description('Generate a new iCal subscription token for a vault')
389
- .argument('<vaultId>', 'Vault ID'))
419
+ .argument('<vaultId>', 'Vault ID or slug'))
390
420
  .action(async (vaultId, _opts) => {
391
421
  const flags = resolveFlags(_opts);
392
422
  const out = createOutput(flags);
393
423
  out.startSpinner('Generating iCal token...');
394
424
  try {
425
+ vaultId = await resolveVaultId(vaultId);
395
426
  const client = await getClientAsync();
396
427
  const result = await client.calendar.generateICalToken(vaultId);
397
428
  out.stopSpinner();
@@ -410,17 +441,19 @@ export function registerCalendarCommands(program) {
410
441
  // calendar ical-token revoke
411
442
  addGlobalFlags(icalToken.command('revoke')
412
443
  .description('Revoke the iCal subscription token for a vault')
413
- .argument('<vaultId>', 'Vault ID')
414
- .option('--confirm', 'Skip confirmation prompt'))
444
+ .argument('<vaultId>', 'Vault ID or slug')
445
+ .option('-y, --yes', 'Skip confirmation prompt')
446
+ .option('--confirm', 'Alias for --yes (deprecated)'))
415
447
  .action(async (vaultId, _opts) => {
416
448
  const flags = resolveFlags(_opts);
417
449
  const out = createOutput(flags);
418
- if (!_opts.confirm) {
419
- out.status(chalk.yellow('Pass --confirm to revoke the iCal token. All subscribers will lose access.'));
450
+ if (!_opts.yes && !_opts.confirm) {
451
+ out.status(chalk.yellow('Pass -y/--yes to revoke the iCal token. All subscribers will lose access.'));
420
452
  return;
421
453
  }
422
454
  out.startSpinner('Revoking iCal token...');
423
455
  try {
456
+ vaultId = await resolveVaultId(vaultId);
424
457
  const client = await getClientAsync();
425
458
  await client.calendar.revokeICalToken(vaultId);
426
459
  out.stopSpinner();
@@ -435,7 +468,7 @@ export function registerCalendarCommands(program) {
435
468
  // ---------------------------------------------------------------------------
436
469
  addGlobalFlags(calendar.command('complete')
437
470
  .description('Toggle completed state for a document')
438
- .argument('<vaultId>', 'Vault ID')
471
+ .argument('<vaultId>', 'Vault ID or slug')
439
472
  .argument('<documentPath>', 'Document path')
440
473
  .option('--completed', 'Mark as complete (default)', true)
441
474
  .option('--no-completed', 'Mark as incomplete'))
@@ -444,6 +477,7 @@ export function registerCalendarCommands(program) {
444
477
  const out = createOutput(flags);
445
478
  out.startSpinner('Toggling completion...');
446
479
  try {
480
+ vaultId = await resolveVaultId(vaultId);
447
481
  const client = await getClientAsync();
448
482
  const completed = _opts.completed !== false;
449
483
  const result = await client.calendar.toggleComplete(vaultId, documentPath, completed);
@@ -464,19 +498,23 @@ export function registerCalendarCommands(program) {
464
498
  // ---------------------------------------------------------------------------
465
499
  addGlobalFlags(calendar.command('agenda')
466
500
  .description('View due-date agenda grouped by time period')
467
- .argument('<vaultId>', 'Vault ID')
501
+ .argument('<vaultId>', 'Vault ID or slug')
468
502
  .option('--status <status>', 'Filter by status')
469
- .option('--range <range>', 'Time range (e.g., week, month)')
503
+ .option('--range <range>', 'Time range: number of days, or week (7), month (30), quarter (90), year (365)')
470
504
  .option('--group-by <groupBy>', 'Group by field'))
471
505
  .action(async (vaultId, _opts) => {
472
506
  const flags = resolveFlags(_opts);
473
507
  const out = createOutput(flags);
474
508
  out.startSpinner('Fetching agenda...');
475
509
  try {
510
+ vaultId = await resolveVaultId(vaultId);
476
511
  const client = await getClientAsync();
512
+ const rangeMap = { week: '7', month: '30', quarter: '90', year: '365' };
513
+ const rawRange = _opts.range;
514
+ const resolvedRange = rawRange ? (rangeMap[rawRange.toLowerCase()] ?? rawRange) : undefined;
477
515
  const agenda = await client.calendar.getAgenda(vaultId, {
478
516
  status: _opts.status,
479
- range: _opts.range,
517
+ range: resolvedRange,
480
518
  groupBy: _opts.groupBy,
481
519
  });
482
520
  out.stopSpinner();
@@ -502,13 +540,14 @@ export function registerCalendarCommands(program) {
502
540
  // ---------------------------------------------------------------------------
503
541
  addGlobalFlags(calendar.command('ical')
504
542
  .description('Output iCal feed for a vault to stdout')
505
- .argument('<vaultId>', 'Vault ID')
543
+ .argument('<vaultId>', 'Vault ID or slug')
506
544
  .option('--include <types>', 'Types to include'))
507
545
  .action(async (vaultId, _opts) => {
508
546
  const flags = resolveFlags(_opts);
509
547
  const out = createOutput(flags);
510
548
  out.startSpinner('Fetching iCal feed...');
511
549
  try {
550
+ vaultId = await resolveVaultId(vaultId);
512
551
  const client = await getClientAsync();
513
552
  const ical = await client.calendar.getIcalFeed(vaultId, {
514
553
  include: _opts.include,
@@ -527,12 +566,13 @@ export function registerCalendarCommands(program) {
527
566
  // calendar connector list
528
567
  addGlobalFlags(connector.command('list')
529
568
  .description('List calendar connectors for a vault')
530
- .argument('<vaultId>', 'Vault ID'))
569
+ .argument('<vaultId>', 'Vault ID or slug'))
531
570
  .action(async (vaultId, _opts) => {
532
571
  const flags = resolveFlags(_opts);
533
572
  const out = createOutput(flags);
534
573
  out.startSpinner('Loading connectors...');
535
574
  try {
575
+ vaultId = await resolveVaultId(vaultId);
536
576
  const client = await getClientAsync();
537
577
  const connectors = await client.calendar.listConnectors(vaultId);
538
578
  out.stopSpinner();
@@ -559,13 +599,14 @@ export function registerCalendarCommands(program) {
559
599
  // calendar connector sync
560
600
  addGlobalFlags(connector.command('sync')
561
601
  .description('Trigger a manual sync for a calendar connector')
562
- .argument('<vaultId>', 'Vault ID')
602
+ .argument('<vaultId>', 'Vault ID or slug')
563
603
  .argument('<connectorId>', 'Connector ID'))
564
604
  .action(async (vaultId, connectorId, _opts) => {
565
605
  const flags = resolveFlags(_opts);
566
606
  const out = createOutput(flags);
567
607
  out.startSpinner('Syncing connector...');
568
608
  try {
609
+ vaultId = await resolveVaultId(vaultId);
569
610
  const client = await getClientAsync();
570
611
  const result = await client.calendar.syncConnector(vaultId, connectorId);
571
612
  out.stopSpinner();
@@ -583,18 +624,20 @@ export function registerCalendarCommands(program) {
583
624
  // calendar connector disconnect
584
625
  addGlobalFlags(connector.command('disconnect')
585
626
  .description('Disconnect a calendar connector from a vault')
586
- .argument('<vaultId>', 'Vault ID')
627
+ .argument('<vaultId>', 'Vault ID or slug')
587
628
  .argument('<connectorId>', 'Connector ID')
588
- .option('--confirm', 'Skip confirmation prompt'))
629
+ .option('-y, --yes', 'Skip confirmation prompt')
630
+ .option('--confirm', 'Alias for --yes (deprecated)'))
589
631
  .action(async (vaultId, connectorId, _opts) => {
590
632
  const flags = resolveFlags(_opts);
591
633
  const out = createOutput(flags);
592
- if (!_opts.confirm) {
593
- out.status(chalk.yellow(`Pass --confirm to disconnect connector ${connectorId}.`));
634
+ if (!_opts.yes && !_opts.confirm) {
635
+ out.status(chalk.yellow(`Pass -y/--yes to disconnect connector ${connectorId}.`));
594
636
  return;
595
637
  }
596
638
  out.startSpinner('Disconnecting connector...');
597
639
  try {
640
+ vaultId = await resolveVaultId(vaultId);
598
641
  const client = await getClientAsync();
599
642
  await client.calendar.disconnectConnector(vaultId, connectorId);
600
643
  out.stopSpinner();
@@ -607,7 +650,7 @@ export function registerCalendarCommands(program) {
607
650
  // calendar connector connect
608
651
  addGlobalFlags(connector.command('connect')
609
652
  .description('Connect a Google or Outlook calendar to a vault via OAuth')
610
- .argument('<vaultId>', 'Vault ID')
653
+ .argument('<vaultId>', 'Vault ID or slug')
611
654
  .requiredOption('--provider <provider>', 'Calendar provider: google or outlook'))
612
655
  .action(async (vaultId, _opts) => {
613
656
  const flags = resolveFlags(_opts);
@@ -620,6 +663,7 @@ export function registerCalendarCommands(program) {
620
663
  }
621
664
  out.startSpinner(`Connecting ${provider} calendar...`);
622
665
  try {
666
+ vaultId = await resolveVaultId(vaultId);
623
667
  const client = await getClientAsync();
624
668
  const result = provider === 'google'
625
669
  ? await client.calendar.connectGoogleCalendar(vaultId)
@@ -643,13 +687,14 @@ export function registerCalendarCommands(program) {
643
687
  // calendar participants list <vaultId> <eventId>
644
688
  addGlobalFlags(participants.command('list')
645
689
  .description('List participants for a calendar event')
646
- .argument('<vaultId>', 'Vault ID')
690
+ .argument('<vaultId>', 'Vault ID or slug')
647
691
  .argument('<eventId>', 'Calendar event ID'))
648
692
  .action(async (vaultId, eventId, _opts) => {
649
693
  const flags = resolveFlags(_opts);
650
694
  const out = createOutput(flags);
651
695
  out.startSpinner('Loading participants...');
652
696
  try {
697
+ vaultId = await resolveVaultId(vaultId);
653
698
  const client = await getClientAsync();
654
699
  const items = await client.calendar.listParticipants(vaultId, eventId);
655
700
  out.stopSpinner();
@@ -685,7 +730,7 @@ export function registerCalendarCommands(program) {
685
730
  // calendar participants add <vaultId> <eventId> --email <email> [--name <name>] [--role <role>]
686
731
  addGlobalFlags(participants.command('add')
687
732
  .description('Add a participant to a calendar event')
688
- .argument('<vaultId>', 'Vault ID')
733
+ .argument('<vaultId>', 'Vault ID or slug')
689
734
  .argument('<eventId>', 'Calendar event ID')
690
735
  .requiredOption('--email <email>', 'Participant email address')
691
736
  .option('--name <name>', 'Participant display name')
@@ -695,6 +740,7 @@ export function registerCalendarCommands(program) {
695
740
  const out = createOutput(flags);
696
741
  out.startSpinner('Adding participant...');
697
742
  try {
743
+ vaultId = await resolveVaultId(vaultId);
698
744
  const client = await getClientAsync();
699
745
  const participant = await client.calendar.addParticipant(vaultId, eventId, {
700
746
  email: _opts.email,
@@ -716,7 +762,7 @@ export function registerCalendarCommands(program) {
716
762
  // calendar participants update <vaultId> <eventId> <participantId> --status <status>
717
763
  addGlobalFlags(participants.command('update')
718
764
  .description('Update a participant status')
719
- .argument('<vaultId>', 'Vault ID')
765
+ .argument('<vaultId>', 'Vault ID or slug')
720
766
  .argument('<eventId>', 'Calendar event ID')
721
767
  .argument('<participantId>', 'Participant ID')
722
768
  .requiredOption('--status <status>', 'New status: accepted, declined, tentative'))
@@ -725,6 +771,7 @@ export function registerCalendarCommands(program) {
725
771
  const out = createOutput(flags);
726
772
  out.startSpinner('Updating participant...');
727
773
  try {
774
+ vaultId = await resolveVaultId(vaultId);
728
775
  const client = await getClientAsync();
729
776
  const participant = await client.calendar.updateParticipant(vaultId, eventId, participantId, {
730
777
  status: _opts.status,
@@ -744,19 +791,21 @@ export function registerCalendarCommands(program) {
744
791
  // calendar participants remove <vaultId> <eventId> <participantId>
745
792
  addGlobalFlags(participants.command('remove')
746
793
  .description('Remove a participant from a calendar event')
747
- .argument('<vaultId>', 'Vault ID')
794
+ .argument('<vaultId>', 'Vault ID or slug')
748
795
  .argument('<eventId>', 'Calendar event ID')
749
796
  .argument('<participantId>', 'Participant ID')
750
- .option('--confirm', 'Skip confirmation prompt'))
797
+ .option('-y, --yes', 'Skip confirmation prompt')
798
+ .option('--confirm', 'Alias for --yes (deprecated)'))
751
799
  .action(async (vaultId, eventId, participantId, _opts) => {
752
800
  const flags = resolveFlags(_opts);
753
801
  const out = createOutput(flags);
754
- if (!_opts.confirm) {
755
- out.status(chalk.yellow(`Pass --confirm to remove participant ${participantId}.`));
802
+ if (!_opts.yes && !_opts.confirm) {
803
+ out.status(chalk.yellow(`Pass -y/--yes to remove participant ${participantId}.`));
756
804
  return;
757
805
  }
758
806
  out.startSpinner('Removing participant...');
759
807
  try {
808
+ vaultId = await resolveVaultId(vaultId);
760
809
  const client = await getClientAsync();
761
810
  await client.calendar.removeParticipant(vaultId, eventId, participantId);
762
811
  out.stopSpinner();
@@ -773,12 +822,13 @@ export function registerCalendarCommands(program) {
773
822
  // calendar templates list
774
823
  addGlobalFlags(templates.command('list')
775
824
  .description('List event templates for a vault')
776
- .argument('<vaultId>', 'Vault ID'))
825
+ .argument('<vaultId>', 'Vault ID or slug'))
777
826
  .action(async (vaultId, _opts) => {
778
827
  const flags = resolveFlags(_opts);
779
828
  const out = createOutput(flags);
780
829
  out.startSpinner('Loading templates...');
781
830
  try {
831
+ vaultId = await resolveVaultId(vaultId);
782
832
  const client = await getClientAsync();
783
833
  const items = await client.calendar.listTemplates(vaultId);
784
834
  out.stopSpinner();
@@ -805,7 +855,7 @@ export function registerCalendarCommands(program) {
805
855
  // calendar templates create
806
856
  addGlobalFlags(templates.command('create')
807
857
  .description('Create a new event template for a vault')
808
- .argument('<vaultId>', 'Vault ID')
858
+ .argument('<vaultId>', 'Vault ID or slug')
809
859
  .requiredOption('--name <name>', 'Template name')
810
860
  .requiredOption('--duration <minutes>', 'Duration in minutes')
811
861
  .option('--description <description>', 'Template description')
@@ -816,13 +866,14 @@ export function registerCalendarCommands(program) {
816
866
  const out = createOutput(flags);
817
867
  out.startSpinner('Creating template...');
818
868
  try {
869
+ vaultId = await resolveVaultId(vaultId);
819
870
  const client = await getClientAsync();
820
871
  const created = await client.calendar.createTemplate(vaultId, {
821
872
  name: _opts.name,
822
873
  duration: Number(_opts.duration),
823
874
  description: _opts.description,
824
875
  location: _opts.location,
825
- color: _opts.color,
876
+ color: resolveColor(_opts.color),
826
877
  });
827
878
  out.stopSpinner();
828
879
  if (flags.output === 'json') {
@@ -839,13 +890,14 @@ export function registerCalendarCommands(program) {
839
890
  // calendar templates get
840
891
  addGlobalFlags(templates.command('get')
841
892
  .description('Get a single event template by ID')
842
- .argument('<vaultId>', 'Vault ID')
893
+ .argument('<vaultId>', 'Vault ID or slug')
843
894
  .argument('<templateId>', 'Template ID'))
844
895
  .action(async (vaultId, templateId, _opts) => {
845
896
  const flags = resolveFlags(_opts);
846
897
  const out = createOutput(flags);
847
898
  out.startSpinner('Loading template...');
848
899
  try {
900
+ vaultId = await resolveVaultId(vaultId);
849
901
  const client = await getClientAsync();
850
902
  const t = await client.calendar.getTemplate(vaultId, templateId);
851
903
  out.stopSpinner();
@@ -865,7 +917,7 @@ export function registerCalendarCommands(program) {
865
917
  // calendar templates update
866
918
  addGlobalFlags(templates.command('update')
867
919
  .description('Update an event template')
868
- .argument('<vaultId>', 'Vault ID')
920
+ .argument('<vaultId>', 'Vault ID or slug')
869
921
  .argument('<templateId>', 'Template ID')
870
922
  .option('--name <name>', 'New template name')
871
923
  .option('--duration <minutes>', 'New duration in minutes')
@@ -877,6 +929,7 @@ export function registerCalendarCommands(program) {
877
929
  const out = createOutput(flags);
878
930
  out.startSpinner('Updating template...');
879
931
  try {
932
+ vaultId = await resolveVaultId(vaultId);
880
933
  const client = await getClientAsync();
881
934
  const data = {};
882
935
  if (_opts.name)
@@ -888,7 +941,7 @@ export function registerCalendarCommands(program) {
888
941
  if (_opts.location)
889
942
  data.location = _opts.location;
890
943
  if (_opts.color)
891
- data.color = _opts.color;
944
+ data.color = resolveColor(_opts.color);
892
945
  const updated = await client.calendar.updateTemplate(vaultId, templateId, data);
893
946
  out.stopSpinner();
894
947
  if (flags.output === 'json') {
@@ -905,18 +958,20 @@ export function registerCalendarCommands(program) {
905
958
  // calendar templates delete
906
959
  addGlobalFlags(templates.command('delete')
907
960
  .description('Delete an event template')
908
- .argument('<vaultId>', 'Vault ID')
961
+ .argument('<vaultId>', 'Vault ID or slug')
909
962
  .argument('<templateId>', 'Template ID')
910
- .option('--confirm', 'Skip confirmation prompt'))
963
+ .option('-y, --yes', 'Skip confirmation prompt')
964
+ .option('--confirm', 'Alias for --yes (deprecated)'))
911
965
  .action(async (vaultId, templateId, _opts) => {
912
966
  const flags = resolveFlags(_opts);
913
967
  const out = createOutput(flags);
914
- if (!_opts.confirm) {
915
- out.status(chalk.yellow(`Pass --confirm to delete template ${templateId}`));
968
+ if (!_opts.yes && !_opts.confirm) {
969
+ out.status(chalk.yellow(`Pass -y/--yes or --confirm to delete template ${templateId}`));
916
970
  return;
917
971
  }
918
972
  out.startSpinner('Deleting template...');
919
973
  try {
974
+ vaultId = await resolveVaultId(vaultId);
920
975
  const client = await getClientAsync();
921
976
  await client.calendar.deleteTemplate(vaultId, templateId);
922
977
  out.stopSpinner();
@@ -2,6 +2,7 @@ import chalk from 'chalk';
2
2
  import { getClientAsync } from '../client.js';
3
3
  import { addGlobalFlags, resolveFlags } from '../utils/flags.js';
4
4
  import { createOutput, handleError } from '../utils/output.js';
5
+ import { resolveVaultId } from '../utils/resolve-vault.js';
5
6
  const VALID_PROVIDERS = ['google_drive', 'dropbox', 'onedrive'];
6
7
  export function registerConnectorCommands(program) {
7
8
  const connectors = program.command('connectors').description('Manage external service connectors (e.g., Google Drive)');
@@ -13,6 +14,8 @@ export function registerConnectorCommands(program) {
13
14
  const out = createOutput(flags);
14
15
  out.startSpinner('Fetching connectors...');
15
16
  try {
17
+ if (_opts.vault)
18
+ _opts.vault = await resolveVaultId(String(_opts.vault));
16
19
  const client = await getClientAsync();
17
20
  const connectorList = await client.connectors.list(_opts.vault);
18
21
  out.stopSpinner();
@@ -76,7 +79,12 @@ export function registerConnectorCommands(program) {
76
79
  .argument('<name>', 'Connector name')
77
80
  .requiredOption('--vault <vaultId>', 'Vault ID')
78
81
  .requiredOption('-d, --direction <direction>', 'Sync direction (pull, push, bidirectional)')
79
- .option('-p, --sync-path <path>', 'Sync path prefix'))
82
+ .option('-p, --sync-path <path>', 'Sync path prefix')
83
+ .addHelpText('after', `
84
+ VALID PROVIDERS
85
+ google_drive Google Drive
86
+ dropbox Dropbox
87
+ onedrive Microsoft OneDrive`))
80
88
  .action(async (provider, name, _opts) => {
81
89
  const flags = resolveFlags(_opts);
82
90
  const out = createOutput(flags);
@@ -85,8 +93,20 @@ export function registerConnectorCommands(program) {
85
93
  process.exitCode = 1;
86
94
  return;
87
95
  }
96
+ if (flags.dryRun) {
97
+ out.success(`[dry-run] Would create ${provider} connector "${name}" in vault ${String(_opts.vault)}`, {
98
+ dryRun: true,
99
+ provider,
100
+ name,
101
+ vaultId: String(_opts.vault),
102
+ syncDirection: String(_opts.direction),
103
+ });
104
+ return;
105
+ }
88
106
  out.startSpinner('Creating connector...');
89
107
  try {
108
+ if (_opts.vault)
109
+ _opts.vault = await resolveVaultId(String(_opts.vault));
90
110
  const client = await getClientAsync();
91
111
  const connector = await client.connectors.create({
92
112
  provider: provider,