@circleback/cli 0.1.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/dist/auth/oauth.js +162 -0
- package/dist/auth/server.js +89 -0
- package/dist/auth/tokenStorage.js +51 -0
- package/dist/client/jsonRpc.js +128 -0
- package/dist/commands/auth.js +40 -0
- package/dist/commands/calendar.js +46 -0
- package/dist/commands/domains.js +28 -0
- package/dist/commands/emails.js +38 -0
- package/dist/commands/meetings.js +83 -0
- package/dist/commands/profiles.js +28 -0
- package/dist/commands/registry.js +61 -0
- package/dist/commands/support.js +30 -0
- package/dist/commands/transcripts.js +61 -0
- package/dist/commands/upgrade.js +35 -0
- package/dist/constants.js +39 -0
- package/dist/helpers/date.js +25 -0
- package/dist/helpers/error.js +59 -0
- package/dist/helpers/formatter.js +49 -0
- package/dist/helpers/help.js +42 -0
- package/dist/helpers/parse.js +34 -0
- package/dist/helpers/string.js +9 -0
- package/dist/helpers/style.js +21 -0
- package/dist/helpers/table.js +211 -0
- package/dist/helpers/update.js +105 -0
- package/dist/index.js +35 -0
- package/dist/types.js +34 -0
- package/package.json +45 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.searchProfilesCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const jsonRpc_1 = require("../client/jsonRpc");
|
|
10
|
+
const error_1 = require("../helpers/error");
|
|
11
|
+
const formatter_1 = require("../helpers/formatter");
|
|
12
|
+
exports.searchProfilesCommand = new commander_1.Command('search')
|
|
13
|
+
.description('Search people by name.')
|
|
14
|
+
.argument('<names...>', 'Names to search for')
|
|
15
|
+
.action(async (names) => {
|
|
16
|
+
try {
|
|
17
|
+
const jsonMode = exports.searchProfilesCommand.parent?.parent?.opts().json ?? false;
|
|
18
|
+
const result = await (0, jsonRpc_1.callTool)('FindProfiles', {
|
|
19
|
+
searchTerms: names,
|
|
20
|
+
});
|
|
21
|
+
(0, formatter_1.formatOutput)('FindProfiles', result, jsonMode);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const message = error instanceof Error ? error.message : 'People search failed.';
|
|
25
|
+
console.error(chalk_1.default.red((0, error_1.formatMcpError)(message) ?? message));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAllCommands = exports.commandGroups = exports.standaloneCommands = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const auth_1 = require("./auth");
|
|
6
|
+
const calendar_1 = require("./calendar");
|
|
7
|
+
const domains_1 = require("./domains");
|
|
8
|
+
const emails_1 = require("./emails");
|
|
9
|
+
const meetings_1 = require("./meetings");
|
|
10
|
+
const profiles_1 = require("./profiles");
|
|
11
|
+
const support_1 = require("./support");
|
|
12
|
+
const transcripts_1 = require("./transcripts");
|
|
13
|
+
const upgrade_1 = require("./upgrade");
|
|
14
|
+
exports.standaloneCommands = [
|
|
15
|
+
auth_1.loginCommand,
|
|
16
|
+
auth_1.logoutCommand,
|
|
17
|
+
upgrade_1.updateCommand,
|
|
18
|
+
];
|
|
19
|
+
exports.commandGroups = [
|
|
20
|
+
{
|
|
21
|
+
name: 'meetings',
|
|
22
|
+
description: 'Search and read meetings.',
|
|
23
|
+
subcommands: [meetings_1.searchMeetingsCommand, meetings_1.readMeetingsCommand],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'transcripts',
|
|
27
|
+
description: 'Search and read transcripts.',
|
|
28
|
+
subcommands: [transcripts_1.searchTranscriptsCommand, transcripts_1.getTranscriptsCommand],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'calendar',
|
|
32
|
+
description: 'Search calendar events.',
|
|
33
|
+
subcommands: [calendar_1.searchCalendarCommand],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'people',
|
|
37
|
+
description: 'Search people.',
|
|
38
|
+
subcommands: [profiles_1.searchProfilesCommand],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'companies',
|
|
42
|
+
description: 'Search companies.',
|
|
43
|
+
subcommands: [domains_1.searchDomainsCommand],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'support',
|
|
47
|
+
description: 'Search support articles.',
|
|
48
|
+
subcommands: [support_1.searchSupportCommand],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'emails',
|
|
52
|
+
description: 'Search emails.',
|
|
53
|
+
subcommands: [emails_1.searchEmailsCommand],
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
const buildCommandGroup = (definition) => definition.subcommands.reduce((group, command, index) => group.addCommand(command, index === 0 ? { isDefault: true } : undefined), new commander_1.Command(definition.name).description(definition.description));
|
|
57
|
+
const getAllCommands = () => [
|
|
58
|
+
...exports.standaloneCommands,
|
|
59
|
+
...exports.commandGroups.map(buildCommandGroup),
|
|
60
|
+
];
|
|
61
|
+
exports.getAllCommands = getAllCommands;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.searchSupportCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const jsonRpc_1 = require("../client/jsonRpc");
|
|
10
|
+
const error_1 = require("../helpers/error");
|
|
11
|
+
const formatter_1 = require("../helpers/formatter");
|
|
12
|
+
exports.searchSupportCommand = new commander_1.Command('search')
|
|
13
|
+
.description('Search Circleback support articles.')
|
|
14
|
+
.argument('[search]', 'Search term')
|
|
15
|
+
.action(async (query) => {
|
|
16
|
+
try {
|
|
17
|
+
const jsonMode = exports.searchSupportCommand.parent?.parent?.opts().json ?? false;
|
|
18
|
+
const arguments_ = {
|
|
19
|
+
intent: query ?? 'Listing support articles.',
|
|
20
|
+
};
|
|
21
|
+
arguments_['searchTerm'] = query ?? '';
|
|
22
|
+
const result = await (0, jsonRpc_1.callTool)('SearchSupportArticles', arguments_);
|
|
23
|
+
(0, formatter_1.formatOutput)('SearchSupportArticles', result, jsonMode);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const message = error instanceof Error ? error.message : 'Support search failed.';
|
|
27
|
+
console.error(chalk_1.default.red((0, error_1.formatMcpError)(message) ?? message));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getTranscriptsCommand = exports.searchTranscriptsCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const jsonRpc_1 = require("../client/jsonRpc");
|
|
10
|
+
const error_1 = require("../helpers/error");
|
|
11
|
+
const formatter_1 = require("../helpers/formatter");
|
|
12
|
+
const parse_1 = require("../helpers/parse");
|
|
13
|
+
exports.searchTranscriptsCommand = new commander_1.Command('search')
|
|
14
|
+
.description('Search meeting transcripts.')
|
|
15
|
+
.argument('[search]', 'Search term')
|
|
16
|
+
.option('--tags <ids>', 'Comma-separated tag IDs')
|
|
17
|
+
.option('--profiles <ids>', 'Comma-separated profile IDs')
|
|
18
|
+
.option('--domains <domains>', 'Comma-separated domains')
|
|
19
|
+
.action(async (query, options) => {
|
|
20
|
+
try {
|
|
21
|
+
const jsonMode = exports.searchTranscriptsCommand.parent?.parent?.opts().json ?? false;
|
|
22
|
+
const arguments_ = {
|
|
23
|
+
intent: query ?? 'Listing recent transcripts.',
|
|
24
|
+
};
|
|
25
|
+
if (query)
|
|
26
|
+
arguments_['searchTerm'] = query;
|
|
27
|
+
if (options.tags)
|
|
28
|
+
arguments_['tags'] = (0, parse_1.parseNumericIds)(options.tags, 'tag ID');
|
|
29
|
+
if (options.profiles)
|
|
30
|
+
arguments_['profiles'] = (0, parse_1.parseNumericIds)(options.profiles, 'profile ID');
|
|
31
|
+
if (options.domains)
|
|
32
|
+
arguments_['domains'] = options.domains.split(',');
|
|
33
|
+
const result = await (0, jsonRpc_1.callTool)('SearchTranscripts', arguments_);
|
|
34
|
+
(0, formatter_1.formatOutput)('SearchTranscripts', result, jsonMode);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const message = error instanceof Error ? error.message : 'Transcript search failed.';
|
|
38
|
+
console.error(chalk_1.default.red((0, error_1.formatMcpError)(message) ?? message));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
exports.getTranscriptsCommand = new commander_1.Command('read')
|
|
43
|
+
.description('Get full transcripts for meetings.')
|
|
44
|
+
.argument('<meetingId…>', 'Meeting IDs (max 50)')
|
|
45
|
+
.showHelpAfterError(true)
|
|
46
|
+
.action(async (ids) => {
|
|
47
|
+
try {
|
|
48
|
+
const jsonMode = exports.getTranscriptsCommand.parent?.parent?.opts().json ?? false;
|
|
49
|
+
const meetingIds = (0, parse_1.validateNumericIds)(ids, 'meeting ID');
|
|
50
|
+
const result = await (0, jsonRpc_1.callTool)('GetTranscriptsForMeetings', {
|
|
51
|
+
intent: `Getting transcripts for meeting IDs: ${meetingIds.join(', ')}.`,
|
|
52
|
+
meetingIds,
|
|
53
|
+
});
|
|
54
|
+
(0, formatter_1.formatOutput)('GetTranscriptsForMeetings', result, jsonMode);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const message = error instanceof Error ? error.message : 'Transcript retrieval failed.';
|
|
58
|
+
console.error(chalk_1.default.red((0, error_1.formatMcpError)(message) ?? message));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const constants_1 = require("../constants");
|
|
11
|
+
const update_1 = require("../helpers/update");
|
|
12
|
+
exports.updateCommand = new commander_1.Command('update')
|
|
13
|
+
.description('Update Circleback CLI to the latest version.')
|
|
14
|
+
.action(async () => {
|
|
15
|
+
console.log(chalk_1.default.dim(`Current version: ${constants_1.CLIENT_VERSION}`));
|
|
16
|
+
console.log(chalk_1.default.dim('Checking for updates…'));
|
|
17
|
+
const result = await (0, update_1.checkForUpdate)(constants_1.CLIENT_PACKAGE_NAME);
|
|
18
|
+
if (!result.updateAvailable) {
|
|
19
|
+
console.log(chalk_1.default.green('Already on the latest version.'));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log(chalk_1.default.yellow(`New version available: ${result.currentVersion} → ${result.latestVersion}`));
|
|
23
|
+
console.log(chalk_1.default.dim(`Running: npm install -g ${constants_1.CLIENT_PACKAGE_NAME}@latest`));
|
|
24
|
+
try {
|
|
25
|
+
(0, node_child_process_1.execSync)(`npm install -g ${constants_1.CLIENT_PACKAGE_NAME}@latest`, {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
});
|
|
28
|
+
console.log(chalk_1.default.green(`\nSuccessfully updated to ${result.latestVersion}.`));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
console.error(chalk_1.default.red('\nUpdate failed. Try running manually with sudo:'));
|
|
32
|
+
console.error(chalk_1.default.cyan(` sudo npm install -g ${constants_1.CLIENT_PACKAGE_NAME}@latest`));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CALLBACK_TIMEOUT_MILLISECONDS = exports.OAUTH_SCOPE = exports.TOKENS_FILE = exports.CONFIG_DIRECTORY = exports.ASCII_LOGO = exports.SECONDARY_COLOR = exports.BRAND_COLOR = exports.CLIENT_VERSION = exports.CLIENT_PACKAGE_NAME = exports.CLIENT_NAME = exports.BASE_URL = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
10
|
+
const packageJson = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
11
|
+
exports.BASE_URL = 'https://app.circleback.ai';
|
|
12
|
+
exports.CLIENT_NAME = 'Circleback CLI';
|
|
13
|
+
exports.CLIENT_PACKAGE_NAME = '@circleback/cli';
|
|
14
|
+
exports.CLIENT_VERSION = packageJson.version;
|
|
15
|
+
exports.BRAND_COLOR = '#F24E1D';
|
|
16
|
+
exports.SECONDARY_COLOR = '#4262FF';
|
|
17
|
+
exports.ASCII_LOGO = `
|
|
18
|
+
==============
|
|
19
|
+
====================
|
|
20
|
+
========================
|
|
21
|
+
==========================
|
|
22
|
+
========== =========
|
|
23
|
+
========= =====
|
|
24
|
+
========
|
|
25
|
+
========
|
|
26
|
+
=======
|
|
27
|
+
=======
|
|
28
|
+
========
|
|
29
|
+
========
|
|
30
|
+
======== ======
|
|
31
|
+
========= =========
|
|
32
|
+
========================== +++++
|
|
33
|
+
======================== +++++++
|
|
34
|
+
=================== +++++++
|
|
35
|
+
============= +++++`;
|
|
36
|
+
exports.CONFIG_DIRECTORY = node_path_1.default.join(node_os_1.default.homedir(), '.config', 'circleback');
|
|
37
|
+
exports.TOKENS_FILE = node_path_1.default.join(exports.CONFIG_DIRECTORY, 'tokens.json');
|
|
38
|
+
exports.OAUTH_SCOPE = 'user';
|
|
39
|
+
exports.CALLBACK_TIMEOUT_MILLISECONDS = 120_000;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatDateTime = exports.formatDate = exports.getStartDateFromDaysAgo = void 0;
|
|
4
|
+
const getStartDateFromDaysAgo = (days) => new Date(Date.now() - days * 86400000).toISOString().slice(0, 10);
|
|
5
|
+
exports.getStartDateFromDaysAgo = getStartDateFromDaysAgo;
|
|
6
|
+
const formatDate = (dateString) => {
|
|
7
|
+
const date = new Date(dateString);
|
|
8
|
+
return date.toLocaleDateString('en-US', {
|
|
9
|
+
month: 'short',
|
|
10
|
+
day: 'numeric',
|
|
11
|
+
year: 'numeric',
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
exports.formatDate = formatDate;
|
|
15
|
+
const formatDateTime = (dateString) => {
|
|
16
|
+
const date = new Date(dateString);
|
|
17
|
+
return date.toLocaleString('en-US', {
|
|
18
|
+
month: 'short',
|
|
19
|
+
day: 'numeric',
|
|
20
|
+
year: 'numeric',
|
|
21
|
+
hour: 'numeric',
|
|
22
|
+
minute: '2-digit',
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
exports.formatDateTime = formatDateTime;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatMcpError = void 0;
|
|
4
|
+
const VALIDATION_ERROR_PATTERN = /Input validation error: Invalid arguments for tool (\w+): (\[.*\])/s;
|
|
5
|
+
const TOOL_EXAMPLES = {
|
|
6
|
+
SearchMeetings: 'cb meetings search "standup" --last 7',
|
|
7
|
+
ReadMeetings: 'cb meetings read 123',
|
|
8
|
+
SearchCalendarEvents: 'cb calendar search --last 7',
|
|
9
|
+
SearchTranscripts: 'cb transcripts search "action items"',
|
|
10
|
+
GetTranscriptsForMeetings: 'cb transcripts read 123',
|
|
11
|
+
SearchEmails: 'cb emails search "invoice"',
|
|
12
|
+
FindProfiles: 'cb people search "John"',
|
|
13
|
+
FindDomains: 'cb companies search "acme"',
|
|
14
|
+
SearchSupportArticles: 'cb support "recording"',
|
|
15
|
+
};
|
|
16
|
+
const isValidationIssue = (value) => {
|
|
17
|
+
if (typeof value !== 'object' || value === null)
|
|
18
|
+
return false;
|
|
19
|
+
if (!('path' in value) || !Array.isArray(value.path))
|
|
20
|
+
return false;
|
|
21
|
+
if (!('message' in value) || typeof value.message !== 'string')
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
24
|
+
};
|
|
25
|
+
const formatIssue = (issue) => {
|
|
26
|
+
const field = issue.path.join('.');
|
|
27
|
+
if (issue.code === 'invalid_type' && issue.expected) {
|
|
28
|
+
return ` Missing required field: ${field} (expected ${issue.expected}).`;
|
|
29
|
+
}
|
|
30
|
+
return ` ${field}: ${issue.message}.`;
|
|
31
|
+
};
|
|
32
|
+
const formatMcpError = (message) => {
|
|
33
|
+
const match = message.match(VALIDATION_ERROR_PATTERN);
|
|
34
|
+
if (!match)
|
|
35
|
+
return;
|
|
36
|
+
const toolName = match[1];
|
|
37
|
+
const issuesJson = match[2];
|
|
38
|
+
if (!toolName || !issuesJson)
|
|
39
|
+
return;
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = JSON.parse(issuesJson);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (!Array.isArray(parsed) || !parsed.every(isValidationIssue))
|
|
48
|
+
return;
|
|
49
|
+
const lines = [
|
|
50
|
+
`Invalid arguments for ${toolName}:`,
|
|
51
|
+
...parsed.map(formatIssue),
|
|
52
|
+
];
|
|
53
|
+
const example = TOOL_EXAMPLES[toolName];
|
|
54
|
+
if (example) {
|
|
55
|
+
lines.push('', `Example: ${example}`);
|
|
56
|
+
}
|
|
57
|
+
return lines.join('\n');
|
|
58
|
+
};
|
|
59
|
+
exports.formatMcpError = formatMcpError;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatOutput = void 0;
|
|
4
|
+
const table_1 = require("./table");
|
|
5
|
+
const safeParse = (rawText) => {
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(rawText);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return rawText;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const stringify = (value) => typeof value === 'string' ? value : JSON.stringify(value, null, 2);
|
|
14
|
+
const formatArrayForTool = (toolName, data) => {
|
|
15
|
+
if (!Array.isArray(data))
|
|
16
|
+
return;
|
|
17
|
+
switch (toolName) {
|
|
18
|
+
case 'SearchMeetings':
|
|
19
|
+
return (0, table_1.formatMeetingsList)(data);
|
|
20
|
+
case 'ReadMeetings':
|
|
21
|
+
return (0, table_1.formatMeetingDetails)(data);
|
|
22
|
+
case 'GetTranscriptsForMeetings':
|
|
23
|
+
return (0, table_1.formatTranscripts)(data);
|
|
24
|
+
case 'SearchTranscripts':
|
|
25
|
+
return (0, table_1.formatTranscriptSearchResults)(data);
|
|
26
|
+
case 'SearchCalendarEvents':
|
|
27
|
+
return (0, table_1.formatCalendarEvents)(data);
|
|
28
|
+
case 'FindProfiles':
|
|
29
|
+
return (0, table_1.formatProfiles)(data);
|
|
30
|
+
case 'FindDomains':
|
|
31
|
+
return (0, table_1.formatDomains)(data);
|
|
32
|
+
case 'SearchSupportArticles':
|
|
33
|
+
return (0, table_1.formatSupportArticles)(data);
|
|
34
|
+
case 'SearchEmails':
|
|
35
|
+
return (0, table_1.formatEmails)(data);
|
|
36
|
+
default:
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const formatOutput = (toolName, rawText, jsonMode) => {
|
|
41
|
+
const parsed = safeParse(rawText);
|
|
42
|
+
if (jsonMode) {
|
|
43
|
+
console.log(stringify(parsed));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const formatted = formatArrayForTool(toolName, parsed);
|
|
47
|
+
console.log(formatted ?? stringify(parsed));
|
|
48
|
+
};
|
|
49
|
+
exports.formatOutput = formatOutput;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.styleHelpOutput = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const SECTION_HEADERS = {
|
|
9
|
+
'Options:': 'options',
|
|
10
|
+
'Commands:': 'commands',
|
|
11
|
+
'Arguments:': 'arguments',
|
|
12
|
+
};
|
|
13
|
+
const styleLine = (line, section) => {
|
|
14
|
+
if (/^Usage:/.test(line)) {
|
|
15
|
+
return [line.replace(/^Usage:/, chalk_1.default.bold('Usage:')), 'none'];
|
|
16
|
+
}
|
|
17
|
+
const nextSection = SECTION_HEADERS[line];
|
|
18
|
+
if (nextSection) {
|
|
19
|
+
return [chalk_1.default.bold(line), nextSection];
|
|
20
|
+
}
|
|
21
|
+
if (line.trim() === '')
|
|
22
|
+
return [line, section];
|
|
23
|
+
const isStyledSection = section === 'options' || section === 'commands' || section === 'arguments';
|
|
24
|
+
if (isStyledSection && /^\s+\S/.test(line)) {
|
|
25
|
+
const match = line.match(/^(\s+)(.+?)( +)(.*)$/);
|
|
26
|
+
if (match) {
|
|
27
|
+
return [
|
|
28
|
+
`${match[1]}${chalk_1.default.bold(match[2])}${match[3]}${match[4]}`,
|
|
29
|
+
section,
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return [line, section];
|
|
34
|
+
};
|
|
35
|
+
const styleHelpOutput = (text) => text
|
|
36
|
+
.split('\n')
|
|
37
|
+
.reduce(({ section, lines }, line) => {
|
|
38
|
+
const [styled, nextSection] = styleLine(line, section);
|
|
39
|
+
return { section: nextSection, lines: [...lines, styled] };
|
|
40
|
+
}, { section: 'none', lines: [] })
|
|
41
|
+
.lines.join('\n');
|
|
42
|
+
exports.styleHelpOutput = styleHelpOutput;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateNumericIds = exports.parseNumericIds = exports.parseIntOption = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const parseIntOption = (value, flagName) => {
|
|
9
|
+
const parsed = parseInt(value, 10);
|
|
10
|
+
if (isNaN(parsed)) {
|
|
11
|
+
console.error(chalk_1.default.red(`Invalid number for ${flagName}.`));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
return parsed;
|
|
15
|
+
};
|
|
16
|
+
exports.parseIntOption = parseIntOption;
|
|
17
|
+
const parseNumericIds = (value, label) => {
|
|
18
|
+
const ids = value.split(',').map(Number);
|
|
19
|
+
if (ids.some(isNaN)) {
|
|
20
|
+
console.error(chalk_1.default.red(`Invalid ${label}. Expected numeric IDs.`));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
return ids;
|
|
24
|
+
};
|
|
25
|
+
exports.parseNumericIds = parseNumericIds;
|
|
26
|
+
const validateNumericIds = (values, label) => {
|
|
27
|
+
const ids = values.map(Number);
|
|
28
|
+
if (ids.some(isNaN)) {
|
|
29
|
+
console.error(chalk_1.default.red(`Invalid ${label}. Expected numeric IDs.`));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
return ids;
|
|
33
|
+
};
|
|
34
|
+
exports.validateNumericIds = validateNumericIds;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pluralize = exports.link = exports.truncate = void 0;
|
|
4
|
+
const truncate = (text, maxLength) => text.length > maxLength ? `${text.slice(0, maxLength - 1)}…` : text;
|
|
5
|
+
exports.truncate = truncate;
|
|
6
|
+
const link = (text, url) => `\u001B]8;;${url}\u0007${text}\u001B]8;;\u0007`;
|
|
7
|
+
exports.link = link;
|
|
8
|
+
const pluralize = (count, singular, plural) => `${count} ${count === 1 ? singular : plural}`;
|
|
9
|
+
exports.pluralize = pluralize;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BANNER = exports.tableStyle = exports.secondary = exports.brand = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
exports.brand = chalk_1.default.hex(constants_1.BRAND_COLOR);
|
|
10
|
+
exports.secondary = chalk_1.default.hex(constants_1.SECONDARY_COLOR);
|
|
11
|
+
exports.tableStyle = { head: [], border: [] };
|
|
12
|
+
exports.BANNER = [
|
|
13
|
+
'',
|
|
14
|
+
` ${exports.brand.bold(constants_1.CLIENT_PACKAGE_NAME)} ${chalk_1.default.dim(`v${constants_1.CLIENT_VERSION}`)}`,
|
|
15
|
+
constants_1.ASCII_LOGO.split('\n')
|
|
16
|
+
.map((line) => line
|
|
17
|
+
.replace(/=+/g, (match) => (0, exports.brand)(match))
|
|
18
|
+
.replace(/\++/g, (match) => (0, exports.secondary)(match)))
|
|
19
|
+
.join('\n'),
|
|
20
|
+
'',
|
|
21
|
+
].join('\n');
|