@circleback/cli 0.1.6 → 0.1.8
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 +27 -15
- package/dist/commands/meetings.js +3 -3
- package/dist/commands/registry.js +4 -4
- package/dist/commands/transcripts.js +3 -3
- package/dist/commands/{upgrade.js → update.js} +1 -1
- package/dist/helpers/parse.js +12 -1
- package/dist/helpers/update.js +9 -8
- package/dist/index.js +13 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,9 +22,12 @@ cb meetings
|
|
|
22
22
|
# Search by keyword
|
|
23
23
|
cb meetings "product review"
|
|
24
24
|
|
|
25
|
-
# Read full meeting details
|
|
25
|
+
# Read full meeting details by numeric ID
|
|
26
26
|
cb meetings read 12345
|
|
27
27
|
|
|
28
|
+
# Read by linkId (from the meeting URL, e.g. circleback.ai/meetings/Vd6Pz_kWqLm3xY-c8RhTn)
|
|
29
|
+
cb meetings read Vd6Pz_kWqLm3xY-c8RhTn
|
|
30
|
+
|
|
28
31
|
# Search transcripts
|
|
29
32
|
cb transcripts "pricing discussion"
|
|
30
33
|
|
|
@@ -37,23 +40,32 @@ cb meetings --json
|
|
|
37
40
|
|
|
38
41
|
## Commands
|
|
39
42
|
|
|
40
|
-
| Command | Description
|
|
41
|
-
| ------------------------------ |
|
|
42
|
-
| `cb login` | Authenticate with Circleback via browser
|
|
43
|
-
| `cb logout` | Clear stored authentication tokens
|
|
44
|
-
| `cb update` | Update CLI to the latest version
|
|
45
|
-
| `cb meetings [search]` | Search meetings
|
|
46
|
-
| `cb meetings read <ids...>` | Read detailed meeting info, notes, and action items |
|
|
47
|
-
| `cb transcripts <search>` | Search transcript content
|
|
48
|
-
| `cb transcripts read <ids...>` | Read full transcripts |
|
|
49
|
-
| `cb calendar` | Search calendar events
|
|
50
|
-
| `cb people <names...>` | Search people by name
|
|
51
|
-
| `cb companies <terms...>` | Search companies by domain
|
|
52
|
-
| `cb emails [search]` | Search connected email accounts
|
|
53
|
-
| `cb support [search]` | Search Circleback support articles
|
|
43
|
+
| Command | Description |
|
|
44
|
+
| ------------------------------ | ------------------------------------------------------------------------------------ |
|
|
45
|
+
| `cb login` | Authenticate with Circleback via browser |
|
|
46
|
+
| `cb logout` | Clear stored authentication tokens |
|
|
47
|
+
| `cb update` | Update CLI to the latest version |
|
|
48
|
+
| `cb meetings [search]` | Search meetings |
|
|
49
|
+
| `cb meetings read <ids...>` | Read detailed meeting info, notes, and action items (numeric IDs or linkIds, max 50) |
|
|
50
|
+
| `cb transcripts <search>` | Search transcript content |
|
|
51
|
+
| `cb transcripts read <ids...>` | Read full transcripts (numeric IDs or linkIds, max 50) |
|
|
52
|
+
| `cb calendar` | Search calendar events |
|
|
53
|
+
| `cb people <names...>` | Search people by name |
|
|
54
|
+
| `cb companies <terms...>` | Search companies by domain |
|
|
55
|
+
| `cb emails [search]` | Search connected email accounts |
|
|
56
|
+
| `cb support [search]` | Search Circleback support articles |
|
|
54
57
|
|
|
55
58
|
Run `cb --help` or `cb <command> --help` for full usage details.
|
|
56
59
|
|
|
60
|
+
## Meeting identifiers
|
|
61
|
+
|
|
62
|
+
`cb meetings read` and `cb transcripts read` accept up to 50 IDs in either form:
|
|
63
|
+
|
|
64
|
+
- **Numeric ID** — the integer ID returned in search results (e.g. `12345`)
|
|
65
|
+
- **linkId** — the short alphanumeric slug from a meeting URL (e.g. `Vd6Pz_kWqLm3xY-c8RhTn` from `circleback.ai/meetings/Vd6Pz_kWqLm3xY-c8RhTn`)
|
|
66
|
+
|
|
67
|
+
Both forms can be mixed in a single call: `cb meetings read 12345 Vd6Pz_kWqLm3xY-c8RhTn`
|
|
68
|
+
|
|
57
69
|
## Filtering
|
|
58
70
|
|
|
59
71
|
Meeting, transcript, and calendar searches support filtering by date range. Meeting and transcript searches also support filtering by tag, person, and company:
|
|
@@ -67,13 +67,13 @@ exports.searchMeetingsCommand = new commander_1.Command('search')
|
|
|
67
67
|
});
|
|
68
68
|
exports.readMeetingsCommand = new commander_1.Command('read')
|
|
69
69
|
.description('Get detailed meeting information.')
|
|
70
|
-
.argument('<ids...>', 'Meeting IDs')
|
|
70
|
+
.argument('<ids...>', 'Meeting numeric IDs or linkIds (max 50)')
|
|
71
71
|
.action(async (ids) => {
|
|
72
72
|
try {
|
|
73
73
|
const jsonMode = exports.readMeetingsCommand.parent?.parent?.opts().json ?? false;
|
|
74
|
-
const meetingIds = (0, parse_1.
|
|
74
|
+
const meetingIds = (0, parse_1.validateMeetingIdentifiers)(ids);
|
|
75
75
|
const result = await (0, jsonRpc_1.callTool)('ReadMeetings', {
|
|
76
|
-
intent: `Reading meeting details for IDs: ${meetingIds.join(', ')}.`,
|
|
76
|
+
intent: `Reading meeting details for IDs or linkIds: ${meetingIds.join(', ')}.`,
|
|
77
77
|
meetingIds,
|
|
78
78
|
});
|
|
79
79
|
(0, formatter_1.formatOutput)('ReadMeetings', result, jsonMode);
|
|
@@ -12,21 +12,21 @@ const profiles_1 = require("./profiles");
|
|
|
12
12
|
const support_1 = require("./support");
|
|
13
13
|
const tags_1 = require("./tags");
|
|
14
14
|
const transcripts_1 = require("./transcripts");
|
|
15
|
-
const
|
|
15
|
+
const update_1 = require("./update");
|
|
16
16
|
exports.standaloneCommands = [
|
|
17
17
|
auth_1.loginCommand,
|
|
18
18
|
auth_1.logoutCommand,
|
|
19
|
-
|
|
19
|
+
update_1.updateCommand,
|
|
20
20
|
];
|
|
21
21
|
exports.commandGroups = [
|
|
22
22
|
{
|
|
23
23
|
name: 'meetings',
|
|
24
|
-
description: 'Search and read meetings
|
|
24
|
+
description: 'Search meetings with `cb meetings search [term]` and read them with `cb meetings read <id>`.',
|
|
25
25
|
subcommands: [meetings_1.searchMeetingsCommand, meetings_1.readMeetingsCommand],
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
name: 'transcripts',
|
|
29
|
-
description: 'Search and read transcripts
|
|
29
|
+
description: 'Search transcripts with `cb transcripts search <term>` and read them with `cb transcripts read <id>`.',
|
|
30
30
|
subcommands: [transcripts_1.searchTranscriptsCommand, transcripts_1.getTranscriptsCommand],
|
|
31
31
|
},
|
|
32
32
|
{
|
|
@@ -44,14 +44,14 @@ exports.searchTranscriptsCommand = new commander_1.Command('search')
|
|
|
44
44
|
});
|
|
45
45
|
exports.getTranscriptsCommand = new commander_1.Command('read')
|
|
46
46
|
.description('Get full meeting transcripts.')
|
|
47
|
-
.argument('<meetingId...>', 'Meeting IDs (max 50)')
|
|
47
|
+
.argument('<meetingId...>', 'Meeting numeric IDs or linkIds (max 50)')
|
|
48
48
|
.showHelpAfterError(true)
|
|
49
49
|
.action(async (ids) => {
|
|
50
50
|
try {
|
|
51
51
|
const jsonMode = exports.getTranscriptsCommand.parent?.parent?.opts().json ?? false;
|
|
52
|
-
const meetingIds = (0, parse_1.
|
|
52
|
+
const meetingIds = (0, parse_1.validateMeetingIdentifiers)(ids);
|
|
53
53
|
const result = await (0, jsonRpc_1.callTool)('GetTranscriptsForMeetings', {
|
|
54
|
-
intent: `Getting transcripts for
|
|
54
|
+
intent: `Getting transcripts for meetings with IDs or linkIds: ${meetingIds.join(', ')}.`,
|
|
55
55
|
meetingIds,
|
|
56
56
|
});
|
|
57
57
|
(0, formatter_1.formatOutput)('GetTranscriptsForMeetings', result, jsonMode);
|
|
@@ -14,7 +14,7 @@ exports.updateCommand = new commander_1.Command('update')
|
|
|
14
14
|
.action(async () => {
|
|
15
15
|
console.log(chalk_1.default.dim(`Current version: ${constants_1.CLIENT_VERSION}`));
|
|
16
16
|
console.log(chalk_1.default.dim('Checking for updates…'));
|
|
17
|
-
const result = await (0, update_1.
|
|
17
|
+
const result = await (0, update_1.getUpdateCheckResult)(constants_1.CLIENT_PACKAGE_NAME);
|
|
18
18
|
if (!result.updateAvailable) {
|
|
19
19
|
console.log(chalk_1.default.green('Already on the latest version.'));
|
|
20
20
|
return;
|
package/dist/helpers/parse.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.validateNumericIds = exports.parseNumericIds = exports.parseIntOption = exports.extractAndValidateObjectFromString = void 0;
|
|
6
|
+
exports.validateMeetingIdentifiers = exports.validateNumericIds = exports.parseNumericIds = exports.parseIntOption = exports.extractAndValidateObjectFromString = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const zod_1 = require("zod");
|
|
9
9
|
const extractAndValidateObjectFromString = (rawText, schema) => {
|
|
@@ -49,3 +49,14 @@ const validateNumericIds = (values, label) => {
|
|
|
49
49
|
return result.data;
|
|
50
50
|
};
|
|
51
51
|
exports.validateNumericIds = validateNumericIds;
|
|
52
|
+
const validateMeetingIdentifiers = (values) => {
|
|
53
|
+
const cleanedValues = values.map((value) => value.trim()).filter(Boolean);
|
|
54
|
+
const isValidIdentifier = /^[A-Za-z0-9_-]{1,64}$/;
|
|
55
|
+
if (cleanedValues.length === 0 ||
|
|
56
|
+
cleanedValues.some((value) => !isValidIdentifier.test(value))) {
|
|
57
|
+
console.error(chalk_1.default.red('Invalid meeting identifiers. Expected one or more numeric IDs or linkIds.'));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
return cleanedValues;
|
|
61
|
+
};
|
|
62
|
+
exports.validateMeetingIdentifiers = validateMeetingIdentifiers;
|
package/dist/helpers/update.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.printUpdateNotification = exports.
|
|
6
|
+
exports.printUpdateNotification = exports.getUpdateCheckResult = 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 chalk_1 = __importDefault(require("chalk"));
|
|
@@ -62,15 +62,16 @@ const isNewerVersion = (latest, current) => {
|
|
|
62
62
|
const firstDifference = Array.from({ length }, (_, index) => (latestParts[index] ?? 0) - (currentParts[index] ?? 0)).find((difference) => difference !== 0);
|
|
63
63
|
return (firstDifference ?? 0) > 0;
|
|
64
64
|
};
|
|
65
|
-
const
|
|
65
|
+
const resultFromCache = (cached) => ({
|
|
66
|
+
updateAvailable: isNewerVersion(cached.latestVersion, constants_1.CLIENT_VERSION),
|
|
67
|
+
currentVersion: constants_1.CLIENT_VERSION,
|
|
68
|
+
latestVersion: cached.latestVersion,
|
|
69
|
+
});
|
|
70
|
+
const getUpdateCheckResult = async (packageName) => {
|
|
66
71
|
const cached = loadCache();
|
|
67
72
|
const now = Date.now();
|
|
68
73
|
if (cached && now - cached.checkedAt < CHECK_INTERVAL_MILLISECONDS) {
|
|
69
|
-
return
|
|
70
|
-
updateAvailable: isNewerVersion(cached.latestVersion, constants_1.CLIENT_VERSION),
|
|
71
|
-
currentVersion: constants_1.CLIENT_VERSION,
|
|
72
|
-
latestVersion: cached.latestVersion,
|
|
73
|
-
};
|
|
74
|
+
return resultFromCache(cached);
|
|
74
75
|
}
|
|
75
76
|
try {
|
|
76
77
|
const latestVersion = await fetchLatestVersion(packageName);
|
|
@@ -90,7 +91,7 @@ const checkForUpdate = async (packageName) => {
|
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
93
|
};
|
|
93
|
-
exports.
|
|
94
|
+
exports.getUpdateCheckResult = getUpdateCheckResult;
|
|
94
95
|
const printUpdateNotification = (result) => {
|
|
95
96
|
if (!result.updateAvailable)
|
|
96
97
|
return;
|
package/dist/index.js
CHANGED
|
@@ -8,28 +8,30 @@ const help_1 = require("./helpers/help");
|
|
|
8
8
|
const style_1 = require("./helpers/style");
|
|
9
9
|
const update_1 = require("./helpers/update");
|
|
10
10
|
const program = new commander_1.Command();
|
|
11
|
+
const updateCheck = (0, update_1.getUpdateCheckResult)(constants_1.CLIENT_PACKAGE_NAME);
|
|
11
12
|
program
|
|
12
13
|
.name('circleback')
|
|
13
14
|
.description('Search and access meetings, emails, calendar events, and more.')
|
|
14
15
|
.version(constants_1.CLIENT_VERSION)
|
|
15
16
|
.option('--json', 'Output raw JSON instead of formatted text')
|
|
16
17
|
.addHelpText('before', style_1.BANNER)
|
|
18
|
+
.exitOverride()
|
|
17
19
|
.configureOutput({
|
|
18
20
|
writeOut: (text) => process.stdout.write((0, help_1.styleHelpOutput)(text)),
|
|
19
21
|
writeErr: (text) => process.stderr.write((0, help_1.styleHelpOutput)(text)),
|
|
20
22
|
});
|
|
21
23
|
(0, registry_1.getAllCommands)().reduce((p, command) => p.addCommand(command), program);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const updateCheckPromise = (0, update_1.checkForUpdate)(constants_1.CLIENT_PACKAGE_NAME);
|
|
26
|
-
program.hook('postAction', async () => {
|
|
24
|
+
program.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
25
|
+
if (actionCommand.name() === 'update')
|
|
26
|
+
return;
|
|
27
27
|
try {
|
|
28
|
-
|
|
29
|
-
(0, update_1.printUpdateNotification)(result);
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
// Never let the update check interfere with normal CLI operation.
|
|
28
|
+
(0, update_1.printUpdateNotification)(await updateCheck);
|
|
33
29
|
}
|
|
30
|
+
catch { }
|
|
31
|
+
});
|
|
32
|
+
program.parseAsync().catch((error) => {
|
|
33
|
+
if (error instanceof commander_1.CommanderError)
|
|
34
|
+
process.exit(error.exitCode);
|
|
35
|
+
console.error(error);
|
|
36
|
+
process.exit(1);
|
|
34
37
|
});
|
|
35
|
-
program.parse();
|
package/package.json
CHANGED