@circleback/cli 0.8.0 → 1.0.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 CHANGED
@@ -40,34 +40,33 @@ cb meetings --json
40
40
 
41
41
  ## Commands
42
42
 
43
- | Command | Description |
44
- | -------------------------------------- | --------------------------------------------------------------- |
45
- | `cb auth login` | Log in to Circleback with your browser |
46
- | `cb auth login --api-key` | Log in with an API key |
47
- | `cb auth logout` | Sign out on this device |
48
- | `cb update` | Update CLI to the latest version |
49
- | `cb meetings [search]` | Search meetings |
50
- | `cb meetings read <ids...>` | Read detailed meeting info, notes, and action items (max 50) |
51
- | `cb meetings update <id>` | Update a meeting's name, notes, or private notes |
52
- | `cb meetings share <id>` | Share a meeting or remove access |
53
- | `cb transcripts <search>` | Search transcript content |
54
- | `cb transcripts read <ids...>` | Read full transcripts (max 50) |
55
- | `cb calendar` | Search calendar events |
56
- | `cb calendar update <id>` | Update private notes for a meeting before it starts |
57
- | `cb people <names...>` | Search people by name |
58
- | `cb companies <terms...>` | Search companies by name or domain |
59
- | `cb emails [search]` | Search connected email accounts |
60
- | `cb support [search]` | Search Circleback support articles |
61
- | `cb action-items [search]` | Search action items |
62
- | `cb action-items create <title>` | Create an action item |
63
- | `cb action-items update <id>` | Update an action item's title, description, status, or assignee |
64
- | `cb action-items delete <id>` | Delete an action item |
65
- | `cb tags` | List tags |
66
- | `cb tags create <name>` | Create a tag |
67
- | `cb tags update <id>` | Update a tag's name, description, or color |
68
- | `cb tags delete <id>` | Delete a tag |
69
- | `cb tags apply <id> <meetingIds...>` | Add a tag to meetings |
70
- | `cb tags unapply <id> <meetingIds...>` | Remove a tag from meetings |
43
+ | Command | Description |
44
+ | -------------------------------- | ------------------------------------------------------------ |
45
+ | `cb auth login` | Log in to Circleback with your browser |
46
+ | `cb auth login --api-key` | Log in with an API key |
47
+ | `cb auth logout` | Sign out on this device |
48
+ | `cb update` | Update CLI to the latest version |
49
+ | `cb meetings [search]` | Search meetings |
50
+ | `cb meetings read <ids...>` | Read detailed meeting info, notes, and action items (max 50) |
51
+ | `cb meetings update <id>` | Update a meeting |
52
+ | `cb meetings share <id>` | Share a meeting or remove access |
53
+ | `cb transcripts <search>` | Search transcript content |
54
+ | `cb transcripts read <ids...>` | Read full transcripts (max 50) |
55
+ | `cb calendar` | Search calendar events |
56
+ | `cb calendar update <id>` | Update a calendar event |
57
+ | `cb people <names...>` | Search people by name |
58
+ | `cb companies <terms...>` | Search companies by name or domain |
59
+ | `cb emails [search]` | Search connected email accounts |
60
+ | `cb support [search]` | Search Circleback support articles |
61
+ | `cb action-items [search]` | Search action items |
62
+ | `cb action-items create <title>` | Create an action item |
63
+ | `cb action-items update <id>` | Update an action item |
64
+ | `cb action-items delete <id>` | Delete an action item |
65
+ | `cb teams` | List your workspace and teams |
66
+ | `cb tags` | List tags |
67
+ | `cb tags create <name>` | Create a tag |
68
+ | `cb tags update <id>` | Update a tag |
69
+ | `cb tags delete <id>` | Delete a tag |
71
70
 
72
71
  Run `cb --help` or `cb <command> --help` for full usage details.
73
72
 
@@ -7,6 +7,7 @@ const command_1 = require("../helpers/command");
7
7
  const date_1 = require("../helpers/date");
8
8
  const parse_1 = require("../helpers/parse");
9
9
  const tag_1 = require("../helpers/tag");
10
+ const value_1 = require("../helpers/value");
10
11
  const types_1 = require("../types");
11
12
  const DEFAULT_ACTION_ITEMS_SEARCH_LAST_DAYS = 30;
12
13
  exports.searchActionItemsCommand = (0, command_1.defineToolCommand)(new commander_1.Command('search')
@@ -35,10 +36,12 @@ exports.createActionItemCommand = (0, command_1.defineToolCommand)(new commander
35
36
  .description('Create an action item.')
36
37
  .argument('<title>', 'Action item title')
37
38
  .option('--description <description>', 'Set the description')
38
- .option('--assignee <id>', 'Assign to a profile ID'), types_1.ToolName.CreateActionItem, (title, options) => ({
39
+ .option('--assignee <id|none>', 'Assign to a profile ID, or none to leave unassigned (defaults to you)'), types_1.ToolName.CreateActionItem, (title, options) => ({
39
40
  title,
40
41
  description: options.description,
41
- assigneeProfileId: (0, parse_1.parseOptionalIntOption)(options.assignee, '--assignee'),
42
+ assigneeProfileId: options.assignee === 'none'
43
+ ? null
44
+ : (0, parse_1.parseOptionalIntOption)(options.assignee, '--assignee'),
42
45
  }));
43
46
  exports.updateActionItemCommand = (0, command_1.defineToolCommand)(new commander_1.Command('update')
44
47
  .description('Update an action item.')
@@ -47,14 +50,13 @@ exports.updateActionItemCommand = (0, command_1.defineToolCommand)(new commander
47
50
  .option('--description <description>', 'Set the description')
48
51
  .addOption(new commander_1.Option('--status <status>', 'Set completion status').choices(Object.values(types_1.ActionItemStatus)))
49
52
  .option('--assignee <id|none>', 'Set or remove the assignee'), types_1.ToolName.UpdateActionItem, (identifier, { assignee, ...fields }) => {
50
- if (assignee === undefined &&
51
- !Object.values(fields).some((value) => value !== undefined)) {
53
+ if (!(0, value_1.isPresent)(assignee) && !Object.values(fields).some(value_1.isPresent)) {
52
54
  throw new Error('Provide at least one field to update.');
53
55
  }
54
56
  return {
55
57
  actionItemId: (0, parse_1.parseIntOption)(identifier, 'id'),
56
58
  ...fields,
57
- ...(assignee !== undefined && {
59
+ ...((0, value_1.isPresent)(assignee) && {
58
60
  assigneeProfileId: assignee === 'none' ? null : (0, parse_1.parseIntOption)(assignee, '--assignee'),
59
61
  }),
60
62
  };
@@ -5,6 +5,8 @@ const commander_1 = require("commander");
5
5
  const constants_1 = require("../constants");
6
6
  const command_1 = require("../helpers/command");
7
7
  const date_1 = require("../helpers/date");
8
+ const tag_1 = require("../helpers/tag");
9
+ const value_1 = require("../helpers/value");
8
10
  const types_1 = require("../types");
9
11
  exports.searchCalendarCommand = (0, command_1.defineToolCommand)(new commander_1.Command('search')
10
12
  .description('Search calendar events.')
@@ -17,9 +19,16 @@ exports.searchCalendarCommand = (0, command_1.defineToolCommand)(new commander_1
17
19
  endDate: options.to || undefined,
18
20
  }));
19
21
  exports.updateCalendarEventCommand = (0, command_1.defineToolCommand)(new commander_1.Command('update')
20
- .description('Update private notes for a meeting before it starts. Replaces the current notes.')
22
+ .description('Update private notes or tags for a meeting before it starts. Each option replaces the current value when provided.')
21
23
  .argument('<id>', 'Event ID from `cb calendar`')
22
- .requiredOption('--private-notes <notes>', 'Your private notes (Markdown)'), types_1.ToolName.UpdateCalendarEvent, (calendarMeetingId, { privateNotes }) => ({
23
- calendarMeetingId,
24
- privateNotes,
25
- }));
24
+ .option('--private-notes <notes>', constants_1.PRIVATE_NOTES_UPDATE_OPTION_DESCRIPTION)
25
+ .option('--tags <tags>', constants_1.TAGS_UPDATE_OPTION_DESCRIPTION), types_1.ToolName.UpdateCalendarEvent, async (calendarMeetingId, { privateNotes, tags }) => {
26
+ if (!(0, value_1.isPresent)(privateNotes) && !(0, value_1.isPresent)(tags)) {
27
+ throw new Error('Provide --private-notes or --tags.');
28
+ }
29
+ return {
30
+ calendarMeetingId,
31
+ privateNotes,
32
+ ...((0, value_1.isPresent)(tags) && { tagIds: await (0, tag_1.resolveTagValues)(tags) }),
33
+ };
34
+ });
@@ -7,6 +7,7 @@ const command_1 = require("../helpers/command");
7
7
  const date_1 = require("../helpers/date");
8
8
  const parse_1 = require("../helpers/parse");
9
9
  const tag_1 = require("../helpers/tag");
10
+ const value_1 = require("../helpers/value");
10
11
  const types_1 = require("../types");
11
12
  const DEFAULT_MEETINGS_SEARCH_LAST_DAYS = 7;
12
13
  exports.searchMeetingsCommand = (0, command_1.defineToolCommand)(new commander_1.Command('search')
@@ -62,7 +63,7 @@ exports.shareMeetingCommand = (0, command_1.defineToolCommand)(new commander_1.C
62
63
  options.workspace,
63
64
  options.link,
64
65
  ];
65
- if (targets.every((target) => target === undefined)) {
66
+ if (!targets.some(value_1.isPresent)) {
66
67
  throw new Error('Set at least one of --email, --profile, --team, --workspace, or --link.');
67
68
  }
68
69
  if ((options.email || options.profile) && !options.access) {
@@ -98,19 +99,19 @@ exports.shareMeetingCommand = (0, command_1.defineToolCommand)(new commander_1.C
98
99
  ],
99
100
  };
100
101
  });
101
- const addMeetingFieldOptions = (command) => command
102
- .option('--name <name>', 'Set the name')
103
- .option('--notes <notes>', 'Set the notes (Markdown)')
104
- .option('--private-notes <notes>', 'Set your private notes (Markdown)');
105
- const getMeetingFields = (fields) => {
106
- if (!Object.values(fields).some((value) => value !== undefined)) {
102
+ exports.updateMeetingCommand = (0, command_1.defineToolCommand)(new commander_1.Command('update')
103
+ .description('Update a meeting. Each option replaces the current value when provided.')
104
+ .argument('<id>', 'Meeting ID')
105
+ .option('--name <name>', 'Update the meeting name')
106
+ .option('--notes <notes>', 'Update the meeting notes (supports Markdown)')
107
+ .option('--private-notes <notes>', constants_1.PRIVATE_NOTES_UPDATE_OPTION_DESCRIPTION)
108
+ .option('--tags <tags>', constants_1.TAGS_UPDATE_OPTION_DESCRIPTION), types_1.ToolName.UpdateMeeting, async (meetingId, { tags, ...fields }) => {
109
+ if (!(0, value_1.isPresent)(tags) && !Object.values(fields).some(value_1.isPresent)) {
107
110
  throw new Error('Provide at least one field to update.');
108
111
  }
109
- return fields;
110
- };
111
- exports.updateMeetingCommand = (0, command_1.defineToolCommand)(addMeetingFieldOptions(new commander_1.Command('update')
112
- .description('Update a meeting. Each option replaces the current value.')
113
- .argument('<id>', 'Meeting ID')), types_1.ToolName.UpdateMeeting, (meetingId, fields) => ({
114
- meetingId,
115
- ...getMeetingFields(fields),
116
- }));
112
+ return {
113
+ meetingId,
114
+ ...fields,
115
+ ...((0, value_1.isPresent)(tags) && { tagIds: await (0, tag_1.resolveTagValues)(tags) }),
116
+ };
117
+ });
@@ -11,6 +11,7 @@ const meetings_1 = require("./meetings");
11
11
  const profiles_1 = require("./profiles");
12
12
  const support_1 = require("./support");
13
13
  const tags_1 = require("./tags");
14
+ const teams_1 = require("./teams");
14
15
  const transcripts_1 = require("./transcripts");
15
16
  const update_1 = require("./update");
16
17
  const standaloneCommands = [auth_1.authCommand, update_1.updateCommand];
@@ -55,6 +56,11 @@ const commandGroups = [
55
56
  description: 'Search emails.',
56
57
  subcommands: [emails_1.searchEmailsCommand],
57
58
  },
59
+ {
60
+ name: 'teams',
61
+ description: 'List your workspace and teams.',
62
+ subcommands: [teams_1.listTeamsCommand],
63
+ },
58
64
  {
59
65
  name: 'action-items',
60
66
  description: 'Search, create, update, and delete action items.',
@@ -73,8 +79,6 @@ const commandGroups = [
73
79
  tags_1.createTagCommand,
74
80
  tags_1.updateTagCommand,
75
81
  tags_1.deleteTagCommand,
76
- tags_1.applyTagCommand,
77
- tags_1.unapplyTagCommand,
78
82
  ],
79
83
  },
80
84
  ];
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.unapplyTagCommand = exports.applyTagCommand = exports.deleteTagCommand = exports.updateTagCommand = exports.createTagCommand = exports.listTagsCommand = void 0;
3
+ exports.deleteTagCommand = exports.updateTagCommand = exports.createTagCommand = exports.listTagsCommand = void 0;
4
4
  const commander_1 = require("commander");
5
5
  const command_1 = require("../helpers/command");
6
6
  const parse_1 = require("../helpers/parse");
7
+ const value_1 = require("../helpers/value");
7
8
  const types_1 = require("../types");
8
9
  const createColorOption = () => new commander_1.Option('--color <color>', 'Set the display color').choices([
9
10
  'neutral',
@@ -18,10 +19,6 @@ const createColorOption = () => new commander_1.Option('--color <color>', 'Set t
18
19
  'purple',
19
20
  ]);
20
21
  const getTagColor = (color) => color ? `bg-tag-${color}` : undefined;
21
- const getTagAssignment = (identifier, meetingIds) => ({
22
- tagId: (0, parse_1.parseIntOption)(identifier, 'id'),
23
- meetingIds,
24
- });
25
22
  exports.listTagsCommand = (0, command_1.defineToolCommand)(new commander_1.Command('list').description('List all tags.'), types_1.ToolName.ListTags, () => ({ intent: 'Listing all tags.' }));
26
23
  exports.createTagCommand = (0, command_1.defineToolCommand)(new commander_1.Command('create')
27
24
  .description('Create a tag.')
@@ -38,7 +35,7 @@ exports.updateTagCommand = (0, command_1.defineToolCommand)(new commander_1.Comm
38
35
  .option('--name <name>', 'Set the name')
39
36
  .option('--description <description>', 'Set the description')
40
37
  .addOption(createColorOption()), types_1.ToolName.UpdateTag, (identifier, options) => {
41
- if (!Object.values(options).some((value) => value !== undefined)) {
38
+ if (!Object.values(options).some(value_1.isPresent)) {
42
39
  throw new Error('Provide at least one field to update.');
43
40
  }
44
41
  return {
@@ -49,11 +46,3 @@ exports.updateTagCommand = (0, command_1.defineToolCommand)(new commander_1.Comm
49
46
  };
50
47
  });
51
48
  exports.deleteTagCommand = (0, command_1.defineToolCommand)(new commander_1.Command('delete').description('Delete a tag.').argument('<id>', 'Tag ID'), types_1.ToolName.DeleteTag, (identifier) => ({ tagId: (0, parse_1.parseIntOption)(identifier, 'id') }));
52
- exports.applyTagCommand = (0, command_1.defineToolCommand)(new commander_1.Command('apply')
53
- .description('Add a tag to meetings.')
54
- .argument('<id>', 'Tag ID')
55
- .argument('<meetingIds...>', 'Meeting IDs'), types_1.ToolName.AddTagToMeetings, getTagAssignment);
56
- exports.unapplyTagCommand = (0, command_1.defineToolCommand)(new commander_1.Command('unapply')
57
- .description('Remove a tag from meetings.')
58
- .argument('<id>', 'Tag ID')
59
- .argument('<meetingIds...>', 'Meeting IDs'), types_1.ToolName.RemoveTagFromMeetings, getTagAssignment);
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listTeamsCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const command_1 = require("../helpers/command");
6
+ const types_1 = require("../types");
7
+ exports.listTeamsCommand = (0, command_1.defineToolCommand)(new commander_1.Command('list').description('List your workspace and teams.'), types_1.ToolName.ListTeams, () => ({}));
package/dist/constants.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DOMAINS_OPTION_DESCRIPTION = exports.PROFILES_OPTION_DESCRIPTION = exports.TAGS_OPTION_DESCRIPTION = exports.END_DATE_OPTION_DESCRIPTION = exports.START_DATE_OPTION_DESCRIPTION = exports.PAGE_OPTION_DESCRIPTION = exports.UNASSIGNED_ACTION_ITEM_ASSIGNEE_LABEL = exports.DEFAULT_MEETING_NAME = exports.MAX_READ_MEETING_IDENTIFIERS = exports.CALLBACK_TIMEOUT_MILLISECONDS = exports.OAUTH_SCOPE = exports.TOKENS_FILE = exports.CONFIG_DIRECTORY = exports.ASCII_LOGO = exports.SECONDARY_COLOR = exports.BRAND_COLOR = exports.API_KEY_SETTINGS_URL = exports.API_KEY_ENVIRONMENT_VARIABLE = exports.API_KEY_PREFIX = exports.CLIENT_VERSION_HEADER = exports.CLIENT_VERSION = exports.CLIENT_PACKAGE_NAME = exports.CLIENT_NAME = exports.BASE_URL = void 0;
6
+ exports.DOMAINS_OPTION_DESCRIPTION = exports.PROFILES_OPTION_DESCRIPTION = exports.PRIVATE_NOTES_UPDATE_OPTION_DESCRIPTION = exports.TAGS_UPDATE_OPTION_DESCRIPTION = exports.TAGS_OPTION_DESCRIPTION = exports.END_DATE_OPTION_DESCRIPTION = exports.START_DATE_OPTION_DESCRIPTION = exports.PAGE_OPTION_DESCRIPTION = exports.UNASSIGNED_ACTION_ITEM_ASSIGNEE_LABEL = exports.DEFAULT_MEETING_NAME = exports.MAX_READ_MEETING_IDENTIFIERS = exports.CALLBACK_TIMEOUT_MILLISECONDS = exports.OAUTH_SCOPE = exports.TOKENS_FILE = exports.CONFIG_DIRECTORY = exports.ASCII_LOGO = exports.SECONDARY_COLOR = exports.BRAND_COLOR = exports.API_KEY_SETTINGS_URL = exports.API_KEY_ENVIRONMENT_VARIABLE = exports.API_KEY_PREFIX = exports.CLIENT_VERSION_HEADER = exports.CLIENT_VERSION = exports.CLIENT_PACKAGE_NAME = exports.CLIENT_NAME = exports.BASE_URL = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const node_os_1 = __importDefault(require("node:os"));
@@ -52,5 +52,7 @@ exports.PAGE_OPTION_DESCRIPTION = 'Page index (starts at 0)';
52
52
  exports.START_DATE_OPTION_DESCRIPTION = 'Start date (YYYY-MM-DD)';
53
53
  exports.END_DATE_OPTION_DESCRIPTION = 'End date (YYYY-MM-DD)';
54
54
  exports.TAGS_OPTION_DESCRIPTION = 'Comma-separated tag names or IDs';
55
+ exports.TAGS_UPDATE_OPTION_DESCRIPTION = 'Update the tags (comma-separated names or IDs, or "" to remove all)';
56
+ exports.PRIVATE_NOTES_UPDATE_OPTION_DESCRIPTION = 'Update your private notes (supports Markdown)';
55
57
  exports.PROFILES_OPTION_DESCRIPTION = 'Comma-separated profile IDs';
56
58
  exports.DOMAINS_OPTION_DESCRIPTION = 'Comma-separated domains';
@@ -86,8 +86,7 @@ const formatForTool = (toolName, data) => {
86
86
  return (0, table_1.formatActionItems)(data);
87
87
  case types_1.ToolName.ListTags:
88
88
  return (0, table_1.formatTags)(data);
89
- case types_1.ToolName.AddTagToMeetings:
90
- case types_1.ToolName.RemoveTagFromMeetings:
89
+ case types_1.ToolName.ListTeams:
91
90
  case types_1.ToolName.UpdateMeeting:
92
91
  case types_1.ToolName.UpdateCalendarEvent:
93
92
  return;
@@ -22,10 +22,8 @@ const resolveTagValues = async (value) => {
22
22
  .split(',')
23
23
  .map((part) => part.trim())
24
24
  .filter((part) => part.length > 0);
25
- if (parts.length === 0) {
26
- (0, output_1.printText)('No tag values provided.', output_1.TextType.Error);
27
- process.exit(1);
28
- }
25
+ if (parts.length === 0)
26
+ return [];
29
27
  const tagList = await fetchUserTags();
30
28
  if (typeof tagList === 'string') {
31
29
  (0, output_1.printText)('Failed to fetch tags.', output_1.TextType.Error);
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPresent = void 0;
4
+ const isPresent = (value) => value !== null && value !== undefined;
5
+ exports.isPresent = isPresent;
package/dist/types.js CHANGED
@@ -25,14 +25,13 @@ var ToolName;
25
25
  ToolName["SearchEmails"] = "SearchEmails";
26
26
  ToolName["SearchActionItems"] = "SearchActionItems";
27
27
  ToolName["ListTags"] = "ListTags";
28
+ ToolName["ListTeams"] = "ListTeams";
28
29
  ToolName["CreateActionItem"] = "CreateActionItem";
29
30
  ToolName["UpdateActionItem"] = "UpdateActionItem";
30
31
  ToolName["DeleteActionItem"] = "DeleteActionItem";
31
32
  ToolName["CreateTag"] = "CreateTag";
32
33
  ToolName["UpdateTag"] = "UpdateTag";
33
34
  ToolName["DeleteTag"] = "DeleteTag";
34
- ToolName["AddTagToMeetings"] = "AddTagToMeetings";
35
- ToolName["RemoveTagFromMeetings"] = "RemoveTagFromMeetings";
36
35
  ToolName["ShareMeeting"] = "ShareMeeting";
37
36
  ToolName["UpdateMeeting"] = "UpdateMeeting";
38
37
  ToolName["UpdateCalendarEvent"] = "UpdateCalendarEvent";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circleback/cli",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "description": "Circleback CLI. Search and access meetings, emails, calendar events, and more.",
5
5
  "license": "MIT",
6
6
  "author": "Circleback <support@circleback.ai> (https://circleback.ai)",