@intercom/cli 0.1.0 → 0.2.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 +128 -0
- package/dist/chunk-QEXGKXTU.js +109 -0
- package/dist/chunk-QEXGKXTU.js.map +1 -0
- package/dist/index.js +761 -153
- package/dist/index.js.map +1 -1
- package/dist/json-TDEGGEUF.js +10 -0
- package/dist/json-TDEGGEUF.js.map +1 -0
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -1,116 +1,43 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
AuthError,
|
|
4
|
+
CLIError,
|
|
5
|
+
NotFoundError,
|
|
6
|
+
PermissionError,
|
|
7
|
+
RateLimitError,
|
|
8
|
+
TimeoutError,
|
|
9
|
+
applyJq,
|
|
10
|
+
detectAuthType,
|
|
11
|
+
formatJson
|
|
12
|
+
} from "./chunk-QEXGKXTU.js";
|
|
2
13
|
|
|
3
14
|
// src/index.ts
|
|
4
15
|
import { Command } from "commander";
|
|
5
16
|
|
|
6
|
-
// src/types.ts
|
|
7
|
-
var CLIError = class extends Error {
|
|
8
|
-
constructor(message, exitCode = 1, error) {
|
|
9
|
-
super(message);
|
|
10
|
-
this.exitCode = exitCode;
|
|
11
|
-
this.error = error;
|
|
12
|
-
this.name = "CLIError";
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
var AuthError = class extends CLIError {
|
|
16
|
-
constructor(message) {
|
|
17
|
-
super(message, 2);
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
var RateLimitError = class extends CLIError {
|
|
21
|
-
constructor(message, retryAfter) {
|
|
22
|
-
super(message, 3);
|
|
23
|
-
this.retryAfter = retryAfter;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var NotFoundError = class extends CLIError {
|
|
27
|
-
constructor(message) {
|
|
28
|
-
super(message, 4);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
var PermissionError = class extends CLIError {
|
|
32
|
-
constructor(message) {
|
|
33
|
-
super(message, 5);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var TimeoutError = class extends CLIError {
|
|
37
|
-
constructor(message) {
|
|
38
|
-
super(message, 6);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
function detectAuthType(token) {
|
|
42
|
-
try {
|
|
43
|
-
const decoded = Buffer.from(token, "base64").toString("utf-8");
|
|
44
|
-
if (decoded.startsWith("tok:")) {
|
|
45
|
-
return "oauth";
|
|
46
|
-
}
|
|
47
|
-
} catch {
|
|
48
|
-
}
|
|
49
|
-
return "api_key";
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// src/output/json.ts
|
|
53
|
-
function formatJson(data) {
|
|
54
|
-
return JSON.stringify(data, null, 2);
|
|
55
|
-
}
|
|
56
|
-
function applyJq(data, expr) {
|
|
57
|
-
if (expr === ".") return data;
|
|
58
|
-
if (!expr.startsWith(".")) {
|
|
59
|
-
throw new CLIError(
|
|
60
|
-
`Unsupported jq expression: "${expr}". Supported: ".", ".field", ".field.nested", ".field[].nested"`
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
if (/[|(){},;]/.test(expr)) {
|
|
64
|
-
throw new CLIError(
|
|
65
|
-
`Unsupported jq expression: "${expr}". Supported: ".", ".field", ".field.nested", ".field[].nested"`
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
const parts = expr.replace(/^\.\s*/, "").split(/\./).filter(Boolean);
|
|
69
|
-
for (const part of parts) {
|
|
70
|
-
if (!/^\w+(\[\])?$/.test(part)) {
|
|
71
|
-
throw new CLIError(
|
|
72
|
-
`Unsupported jq expression: "${expr}". Supported: ".", ".field", ".field.nested", ".field[].nested"`
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
let current = data;
|
|
77
|
-
for (const part of parts) {
|
|
78
|
-
const arrayMatch = part.match(/^(\w+)\[\]$/);
|
|
79
|
-
if (arrayMatch) {
|
|
80
|
-
const key = arrayMatch[1];
|
|
81
|
-
if (current && typeof current === "object" && key in current) {
|
|
82
|
-
const arr = current[key];
|
|
83
|
-
if (!Array.isArray(arr)) return void 0;
|
|
84
|
-
current = arr;
|
|
85
|
-
} else {
|
|
86
|
-
return void 0;
|
|
87
|
-
}
|
|
88
|
-
} else if (Array.isArray(current)) {
|
|
89
|
-
current = current.map(
|
|
90
|
-
(item) => item && typeof item === "object" ? item[part] : void 0
|
|
91
|
-
);
|
|
92
|
-
} else if (current && typeof current === "object") {
|
|
93
|
-
current = current[part];
|
|
94
|
-
} else {
|
|
95
|
-
return void 0;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return current;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// src/commands/api.ts
|
|
102
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
103
|
-
|
|
104
17
|
// src/api/timeouts.ts
|
|
105
18
|
var API_TIMEOUT_MS = 3e4;
|
|
19
|
+
var SIMULATION_POLL_TIMEOUT_MS = 6e5;
|
|
20
|
+
|
|
21
|
+
// src/version.ts
|
|
22
|
+
import { createRequire } from "module";
|
|
23
|
+
var require2 = createRequire(import.meta.url);
|
|
24
|
+
var pkg = require2("../package.json");
|
|
25
|
+
var VERSION = pkg.version;
|
|
106
26
|
|
|
107
27
|
// src/api/fetch.ts
|
|
108
|
-
var USER_AGENT =
|
|
28
|
+
var USER_AGENT = `IntercomCLI/${VERSION}`;
|
|
29
|
+
var _cliCommand = "";
|
|
30
|
+
function setCliCommand(name) {
|
|
31
|
+
_cliCommand = name;
|
|
32
|
+
}
|
|
109
33
|
async function fetchWithTimeout(url, init, options) {
|
|
110
34
|
const headers = new Headers(init.headers);
|
|
111
35
|
if (!headers.has("User-Agent")) {
|
|
112
36
|
headers.set("User-Agent", USER_AGENT);
|
|
113
37
|
}
|
|
38
|
+
if (_cliCommand) {
|
|
39
|
+
headers.set("X-CLI-Command", _cliCommand);
|
|
40
|
+
}
|
|
114
41
|
if (options.verbose) {
|
|
115
42
|
console.error(`> ${init.method ?? "GET"} ${url}`);
|
|
116
43
|
}
|
|
@@ -560,11 +487,16 @@ async function resolveClient(options = {}) {
|
|
|
560
487
|
'Not authenticated. Run "intercom auth login" to get started.'
|
|
561
488
|
);
|
|
562
489
|
}
|
|
490
|
+
if (!options.workspace && config.default && !config.workspaces[appId]) {
|
|
491
|
+
throw new AuthError(
|
|
492
|
+
`Default workspace "${appId}" is not in configured workspaces. Run "intercom auth bootstrap" or "intercom auth login --token <token>" to re-authenticate.`
|
|
493
|
+
);
|
|
494
|
+
}
|
|
563
495
|
const store = new CredentialStore(createDefaultBackend(configDir));
|
|
564
496
|
const cred = await store.get(appId);
|
|
565
497
|
if (!cred) {
|
|
566
498
|
throw new AuthError(
|
|
567
|
-
`No credentials found for workspace ${appId}. Run "intercom auth login".`
|
|
499
|
+
`No credentials found for workspace "${appId}". Run "intercom auth bootstrap" or "intercom auth login --token <token>" to authenticate.`
|
|
568
500
|
);
|
|
569
501
|
}
|
|
570
502
|
return new IntercomClient({
|
|
@@ -614,6 +546,20 @@ function render(data, opts, humanRenderer, listItems) {
|
|
|
614
546
|
console.log(formatJson(data));
|
|
615
547
|
return;
|
|
616
548
|
}
|
|
549
|
+
if (opts.agent) {
|
|
550
|
+
if (listItems) {
|
|
551
|
+
for (const item of listItems) {
|
|
552
|
+
console.log(JSON.stringify(item));
|
|
553
|
+
}
|
|
554
|
+
} else {
|
|
555
|
+
console.log(JSON.stringify(data));
|
|
556
|
+
}
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (opts.human) {
|
|
560
|
+
console.log(humanRenderer());
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
617
563
|
if (!process.stdout.isTTY) {
|
|
618
564
|
if (listItems) {
|
|
619
565
|
for (const item of listItems) {
|
|
@@ -627,8 +573,9 @@ function render(data, opts, humanRenderer, listItems) {
|
|
|
627
573
|
console.log(humanRenderer());
|
|
628
574
|
}
|
|
629
575
|
|
|
630
|
-
// src/
|
|
631
|
-
|
|
576
|
+
// src/utils/fields.ts
|
|
577
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
578
|
+
function parseTypedFields(fields, typed) {
|
|
632
579
|
const result = {};
|
|
633
580
|
for (const field of fields) {
|
|
634
581
|
const eqIndex = field.indexOf("=");
|
|
@@ -654,8 +601,18 @@ function parseFields(fields, typed) {
|
|
|
654
601
|
}
|
|
655
602
|
return result;
|
|
656
603
|
}
|
|
604
|
+
|
|
605
|
+
// src/commands/api.ts
|
|
657
606
|
function registerApiCommand(program) {
|
|
658
|
-
program.command("api").description("Make an authenticated API request (like gh api)").argument("<endpoint>", "API endpoint path (e.g., /articles)").
|
|
607
|
+
program.command("api").description("Make an authenticated API request (like gh api)").argument("<endpoint>", "API endpoint path (e.g., /articles)").addHelpText(
|
|
608
|
+
"after",
|
|
609
|
+
`
|
|
610
|
+
Examples:
|
|
611
|
+
intercom api /me
|
|
612
|
+
intercom api /articles --paginate
|
|
613
|
+
intercom api /contacts -X POST -f email=test@example.com -f role=user
|
|
614
|
+
intercom api /articles/123 --jq '.title'`
|
|
615
|
+
).option("-X, --method <method>", "HTTP method").option("-f, --field <key=value...>", "String field").option(
|
|
659
616
|
"-F, --typed-field <key=value...>",
|
|
660
617
|
"Typed field (bools, numbers, file reads)"
|
|
661
618
|
).option("--jq <expr>", "Filter response with jq expression").option("--json", "Output as JSON").option("--paginate", "Auto-paginate through all pages").option("--verbose", "Show full HTTP request/response").action(async function(endpoint) {
|
|
@@ -664,8 +621,8 @@ function registerApiCommand(program) {
|
|
|
664
621
|
const stringFields = options.field ?? [];
|
|
665
622
|
const typedFields = options.typedField ?? [];
|
|
666
623
|
const body = {
|
|
667
|
-
...
|
|
668
|
-
...
|
|
624
|
+
...parseTypedFields(stringFields, false),
|
|
625
|
+
...parseTypedFields(typedFields, true)
|
|
669
626
|
};
|
|
670
627
|
const hasBody = stringFields.length > 0 || typedFields.length > 0;
|
|
671
628
|
const method = options.method ?? (hasBody ? "POST" : "GET");
|
|
@@ -810,7 +767,6 @@ async function signup(options) {
|
|
|
810
767
|
email_submission: {},
|
|
811
768
|
sign_up_locale: "en",
|
|
812
769
|
new_app_feature_flags: [
|
|
813
|
-
"synchronously-create-subscription-on-signup",
|
|
814
770
|
"fin-sdk",
|
|
815
771
|
"messenger-public-api"
|
|
816
772
|
]
|
|
@@ -911,6 +867,13 @@ async function findOrCreateAppPackage(baseUrl, cookies, appId, appPackageId, tim
|
|
|
911
867
|
{ timeoutMs }
|
|
912
868
|
);
|
|
913
869
|
if (!listResponse.ok) {
|
|
870
|
+
if (listResponse.status === 403) {
|
|
871
|
+
throw new Error(
|
|
872
|
+
`Developer Hub access denied (403). This usually means the admin email has not been verified.
|
|
873
|
+
Verify your email first: intercom auth verify-email --url <url-from-verification-email>
|
|
874
|
+
Then retry this command.`
|
|
875
|
+
);
|
|
876
|
+
}
|
|
914
877
|
throw new Error(`Failed to list app packages: ${listResponse.status}`);
|
|
915
878
|
}
|
|
916
879
|
const data = await listResponse.json();
|
|
@@ -952,13 +915,20 @@ async function findOrCreateAppPackage(baseUrl, cookies, appId, appPackageId, tim
|
|
|
952
915
|
{ timeoutMs }
|
|
953
916
|
);
|
|
954
917
|
if (!createResponse.ok) {
|
|
918
|
+
if (createResponse.status === 403) {
|
|
919
|
+
throw new Error(
|
|
920
|
+
`Developer Hub access denied (403). This usually means the admin email has not been verified.
|
|
921
|
+
Verify your email first: intercom auth verify-email --url <url-from-verification-email>
|
|
922
|
+
Then retry this command.`
|
|
923
|
+
);
|
|
924
|
+
}
|
|
955
925
|
throw new Error(`Failed to create app package: ${createResponse.status}`);
|
|
956
926
|
}
|
|
957
927
|
const created = await createResponse.json();
|
|
958
|
-
const
|
|
928
|
+
const pkg2 = created.app_package ?? created;
|
|
959
929
|
return {
|
|
960
|
-
id: String(
|
|
961
|
-
name:
|
|
930
|
+
id: String(pkg2.id),
|
|
931
|
+
name: pkg2.name ?? "CLI Access Token",
|
|
962
932
|
created: true
|
|
963
933
|
};
|
|
964
934
|
}
|
|
@@ -1168,6 +1138,25 @@ function registerSignupCommand(auth) {
|
|
|
1168
1138
|
URL: `${baseUrl}/a/apps/${workspace.id}`
|
|
1169
1139
|
})
|
|
1170
1140
|
);
|
|
1141
|
+
try {
|
|
1142
|
+
const { token, appId } = await getToken({
|
|
1143
|
+
baseUrl,
|
|
1144
|
+
email: options.email,
|
|
1145
|
+
password,
|
|
1146
|
+
appId: workspace.id
|
|
1147
|
+
});
|
|
1148
|
+
const configDir = process.env.INTERCOM_CONFIG_DIR;
|
|
1149
|
+
const store = new CredentialStore(createDefaultBackend(configDir));
|
|
1150
|
+
await store.set(appId, { token, auth_type: "oauth", app_id: appId });
|
|
1151
|
+
await addWorkspace(configDir, { app_id: appId, name: workspace.name });
|
|
1152
|
+
console.log(`
|
|
1153
|
+
Authenticated to workspace ${appId}`);
|
|
1154
|
+
} catch {
|
|
1155
|
+
console.error(
|
|
1156
|
+
`
|
|
1157
|
+
Warning: Workspace created but auto-login failed. Run "intercom auth bootstrap --email ${options.email} --app-id ${workspace.id}" to authenticate.`
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1171
1160
|
} catch (err) {
|
|
1172
1161
|
if (err instanceof CLIError) throw err;
|
|
1173
1162
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -1207,7 +1196,14 @@ function registerVerifyEmailCommand(auth) {
|
|
|
1207
1196
|
|
|
1208
1197
|
// src/commands/auth/index.ts
|
|
1209
1198
|
function registerAuthCommand(program) {
|
|
1210
|
-
const auth = program.command("auth").description("Manage authentication credentials")
|
|
1199
|
+
const auth = program.command("auth").description("Manage authentication credentials").addHelpText(
|
|
1200
|
+
"after",
|
|
1201
|
+
`
|
|
1202
|
+
Examples:
|
|
1203
|
+
intercom auth login --token <api-token>
|
|
1204
|
+
intercom auth status
|
|
1205
|
+
intercom auth logout`
|
|
1206
|
+
);
|
|
1211
1207
|
registerLoginCommand(auth);
|
|
1212
1208
|
registerBootstrapCommand(auth);
|
|
1213
1209
|
registerStatusCommand(auth);
|
|
@@ -1249,7 +1245,16 @@ function htmlToText(html) {
|
|
|
1249
1245
|
|
|
1250
1246
|
// src/commands/articles.ts
|
|
1251
1247
|
function registerArticlesCommand(program) {
|
|
1252
|
-
const articles = program.command("articles").description("Manage help center articles")
|
|
1248
|
+
const articles = program.command("articles").description("Manage help center articles").addHelpText(
|
|
1249
|
+
"after",
|
|
1250
|
+
`
|
|
1251
|
+
Examples:
|
|
1252
|
+
intercom articles list
|
|
1253
|
+
intercom articles get 123
|
|
1254
|
+
intercom articles create -f title="Getting Started" -F body=@article.md
|
|
1255
|
+
intercom articles update 123 -f state=published
|
|
1256
|
+
intercom articles delete 123`
|
|
1257
|
+
);
|
|
1253
1258
|
articles.command("list").description("List help center articles").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").option("--limit <n>", "Max results to return", "25").option("--all", "Auto-paginate all pages").action(async function() {
|
|
1254
1259
|
const opts = this.optsWithGlobals();
|
|
1255
1260
|
const client = await resolveClient(opts);
|
|
@@ -1302,10 +1307,18 @@ ${body}` : meta;
|
|
|
1302
1307
|
"Field to set (repeatable)",
|
|
1303
1308
|
(v, acc) => [...acc, v],
|
|
1304
1309
|
[]
|
|
1310
|
+
).option(
|
|
1311
|
+
"-F, --typed-field <key=value>",
|
|
1312
|
+
"Typed field: bools, numbers, @file reads (repeatable)",
|
|
1313
|
+
(v, acc) => [...acc, v],
|
|
1314
|
+
[]
|
|
1305
1315
|
).option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1306
1316
|
const opts = this.optsWithGlobals();
|
|
1307
1317
|
const client = await resolveClient(opts);
|
|
1308
|
-
const body =
|
|
1318
|
+
const body = {
|
|
1319
|
+
...parseFieldArgs(opts.field ?? []),
|
|
1320
|
+
...parseTypedFields(opts.typedField ?? [], true)
|
|
1321
|
+
};
|
|
1309
1322
|
if (body.author_id && typeof body.author_id === "string") {
|
|
1310
1323
|
const parsed = parseInt(body.author_id, 10);
|
|
1311
1324
|
if (!isNaN(parsed)) body.author_id = parsed;
|
|
@@ -1326,10 +1339,18 @@ ${body}` : meta;
|
|
|
1326
1339
|
"Field to set (repeatable)",
|
|
1327
1340
|
(v, acc) => [...acc, v],
|
|
1328
1341
|
[]
|
|
1342
|
+
).option(
|
|
1343
|
+
"-F, --typed-field <key=value>",
|
|
1344
|
+
"Typed field: bools, numbers, @file reads (repeatable)",
|
|
1345
|
+
(v, acc) => [...acc, v],
|
|
1346
|
+
[]
|
|
1329
1347
|
).option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function(id) {
|
|
1330
1348
|
const opts = this.optsWithGlobals();
|
|
1331
1349
|
const client = await resolveClient(opts);
|
|
1332
|
-
const body =
|
|
1350
|
+
const body = {
|
|
1351
|
+
...parseFieldArgs(opts.field ?? []),
|
|
1352
|
+
...parseTypedFields(opts.typedField ?? [], true)
|
|
1353
|
+
};
|
|
1333
1354
|
if (body.author_id && typeof body.author_id === "string") {
|
|
1334
1355
|
const parsed = parseInt(body.author_id, 10);
|
|
1335
1356
|
if (!isNaN(parsed)) body.author_id = parsed;
|
|
@@ -1356,7 +1377,15 @@ ${body}` : meta;
|
|
|
1356
1377
|
|
|
1357
1378
|
// src/commands/contacts.ts
|
|
1358
1379
|
function registerContactsCommand(program) {
|
|
1359
|
-
const contacts = program.command("contacts").description("Manage contacts")
|
|
1380
|
+
const contacts = program.command("contacts").description("Manage contacts").addHelpText(
|
|
1381
|
+
"after",
|
|
1382
|
+
`
|
|
1383
|
+
Examples:
|
|
1384
|
+
intercom contacts list --limit 10
|
|
1385
|
+
intercom contacts get abc123
|
|
1386
|
+
intercom contacts create -f email=user@example.com -f role=user
|
|
1387
|
+
intercom contacts delete abc123`
|
|
1388
|
+
);
|
|
1360
1389
|
contacts.command("list").description("List contacts").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").option("--limit <n>", "Max results to return", "25").option("--all", "Auto-paginate all pages").action(async function() {
|
|
1361
1390
|
const opts = this.optsWithGlobals();
|
|
1362
1391
|
const client = await resolveClient(opts);
|
|
@@ -1533,7 +1562,14 @@ function renderConversationStream(result) {
|
|
|
1533
1562
|
return parts.join("\n");
|
|
1534
1563
|
}
|
|
1535
1564
|
function registerConversationsCommand(program) {
|
|
1536
|
-
const conversations = program.command("conversations").description("Manage conversations")
|
|
1565
|
+
const conversations = program.command("conversations").description("Manage conversations").addHelpText(
|
|
1566
|
+
"after",
|
|
1567
|
+
`
|
|
1568
|
+
Examples:
|
|
1569
|
+
intercom conversations list
|
|
1570
|
+
intercom conversations get 123
|
|
1571
|
+
intercom conversations reply 123 -f body="Thanks!" -f message_type=comment -f type=admin -f admin_id=456`
|
|
1572
|
+
);
|
|
1537
1573
|
conversations.command("list").description("List conversations").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").option("--limit <n>", "Max results to return", "25").option("--all", "Auto-paginate all pages").action(async function() {
|
|
1538
1574
|
const opts = this.optsWithGlobals();
|
|
1539
1575
|
const client = await resolveClient(opts);
|
|
@@ -1604,7 +1640,14 @@ function registerConversationsCommand(program) {
|
|
|
1604
1640
|
|
|
1605
1641
|
// src/commands/help-center.ts
|
|
1606
1642
|
function registerHelpCenterCommand(program) {
|
|
1607
|
-
const helpCenter = program.command("help-center").description("Manage help center collections")
|
|
1643
|
+
const helpCenter = program.command("help-center").description("Manage help center collections").addHelpText(
|
|
1644
|
+
"after",
|
|
1645
|
+
`
|
|
1646
|
+
Examples:
|
|
1647
|
+
intercom help-center list
|
|
1648
|
+
intercom help-center get 123
|
|
1649
|
+
intercom help-center create -f name="FAQ"`
|
|
1650
|
+
);
|
|
1608
1651
|
helpCenter.command("list").description("List help center collections").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").option("--limit <n>", "Max results to return", "25").option("--all", "Auto-paginate all pages").action(async function() {
|
|
1609
1652
|
const opts = this.optsWithGlobals();
|
|
1610
1653
|
const client = await resolveClient(opts);
|
|
@@ -1699,7 +1742,14 @@ export function IntercomWidget() {
|
|
|
1699
1742
|
}`;
|
|
1700
1743
|
}
|
|
1701
1744
|
function registerMessengerCommand(program) {
|
|
1702
|
-
const messenger = program.command("messenger").description("Manage Intercom Messenger settings")
|
|
1745
|
+
const messenger = program.command("messenger").description("Manage Intercom Messenger settings").addHelpText(
|
|
1746
|
+
"after",
|
|
1747
|
+
`
|
|
1748
|
+
Examples:
|
|
1749
|
+
intercom messenger get
|
|
1750
|
+
intercom messenger update -f alignment=right -f theme_mode=dark
|
|
1751
|
+
intercom messenger snippet --format react`
|
|
1752
|
+
);
|
|
1703
1753
|
messenger.command("get").description("Get Messenger settings").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1704
1754
|
const opts = this.optsWithGlobals();
|
|
1705
1755
|
const client = await resolveClient(opts);
|
|
@@ -1766,6 +1816,111 @@ function registerMessengerCommand(program) {
|
|
|
1766
1816
|
});
|
|
1767
1817
|
}
|
|
1768
1818
|
|
|
1819
|
+
// src/commands/fin.ts
|
|
1820
|
+
import { writeFile as writeFile2 } from "fs/promises";
|
|
1821
|
+
|
|
1822
|
+
// src/commands/fin/procedures.ts
|
|
1823
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1824
|
+
import { basename } from "path";
|
|
1825
|
+
import AdmZip from "adm-zip";
|
|
1826
|
+
function registerProceduresCommand(fin) {
|
|
1827
|
+
const procedures = fin.command("procedures").description("Manage Fin SDK procedures");
|
|
1828
|
+
procedures.command("list").description("List procedures from the Fin SDK manifest").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1829
|
+
const opts = this.optsWithGlobals();
|
|
1830
|
+
const client = await resolveClient(opts);
|
|
1831
|
+
const result = await client.get("/fin-sdk/manifest");
|
|
1832
|
+
const manifest = result;
|
|
1833
|
+
const items = manifest.procedures ?? [];
|
|
1834
|
+
render(items, opts, () => {
|
|
1835
|
+
if (items.length === 0) {
|
|
1836
|
+
return "No procedures found.";
|
|
1837
|
+
}
|
|
1838
|
+
const rows = items.map((item) => ({
|
|
1839
|
+
ID: String(item.id ?? ""),
|
|
1840
|
+
NAME: String(item.name ?? "")
|
|
1841
|
+
}));
|
|
1842
|
+
return table({ columns: ["ID", "NAME"], rows });
|
|
1843
|
+
}, items);
|
|
1844
|
+
});
|
|
1845
|
+
procedures.command("get <id>").description("Download a procedure by ID and print its YAML content").option("--verbose", "Show HTTP request/response details").action(async function(id) {
|
|
1846
|
+
const opts = this.optsWithGlobals();
|
|
1847
|
+
const client = await resolveClient(opts);
|
|
1848
|
+
const buffer = await client.getBuffer(`/fin-sdk/procedures/${id}/download`);
|
|
1849
|
+
const zip = new AdmZip(buffer);
|
|
1850
|
+
const entry = zip.getEntries().find((e) => e.entryName.endsWith("procedure.yaml"));
|
|
1851
|
+
if (!entry) {
|
|
1852
|
+
throw new Error("procedure.yaml not found in downloaded ZIP");
|
|
1853
|
+
}
|
|
1854
|
+
console.log(zip.readAsText(entry));
|
|
1855
|
+
});
|
|
1856
|
+
procedures.command("upload <file>").description("Upload a procedure file to Fin SDK").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function(filePath) {
|
|
1857
|
+
const opts = this.optsWithGlobals();
|
|
1858
|
+
const client = await resolveClient(opts);
|
|
1859
|
+
const fileContent = await readFile2(filePath);
|
|
1860
|
+
const formData = new FormData();
|
|
1861
|
+
const blob = new Blob([fileContent], { type: "application/x-yaml" });
|
|
1862
|
+
formData.append("file_data", blob, basename(filePath));
|
|
1863
|
+
const result = await client.postFormData("/fin-sdk/upload", formData);
|
|
1864
|
+
render(result, opts, () => formatJson(result));
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
// src/commands/fin/data-connectors.ts
|
|
1869
|
+
function registerDataConnectorsCommand(fin) {
|
|
1870
|
+
const dataConnectors = fin.command("data-connectors").description("Manage Fin SDK data connectors");
|
|
1871
|
+
dataConnectors.command("list").description("List data connectors from the Fin SDK manifest").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1872
|
+
const opts = this.optsWithGlobals();
|
|
1873
|
+
const client = await resolveClient(opts);
|
|
1874
|
+
const result = await client.get("/fin-sdk/manifest");
|
|
1875
|
+
const manifest = result;
|
|
1876
|
+
const items = manifest.data_connectors ?? [];
|
|
1877
|
+
render(items, opts, () => {
|
|
1878
|
+
if (items.length === 0) {
|
|
1879
|
+
return "No data connectors found.";
|
|
1880
|
+
}
|
|
1881
|
+
const rows = items.map((item) => ({
|
|
1882
|
+
ID: String(item.id ?? ""),
|
|
1883
|
+
NAME: String(item.name ?? "")
|
|
1884
|
+
}));
|
|
1885
|
+
return table({ columns: ["ID", "NAME"], rows });
|
|
1886
|
+
}, items);
|
|
1887
|
+
});
|
|
1888
|
+
dataConnectors.command("create").description("Create a data connector").requiredOption("-f, --field <key=value>", "Field to set (e.g. name=<name>)", (v, acc) => [...acc, v], []).option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1889
|
+
const opts = this.optsWithGlobals();
|
|
1890
|
+
const client = await resolveClient(opts);
|
|
1891
|
+
const fields = opts.field ?? [];
|
|
1892
|
+
const body = {};
|
|
1893
|
+
for (const f of fields) {
|
|
1894
|
+
const eq = f.indexOf("=");
|
|
1895
|
+
if (eq === -1) throw new Error(`Invalid field format: ${f}. Expected key=value`);
|
|
1896
|
+
body[f.slice(0, eq)] = f.slice(eq + 1);
|
|
1897
|
+
}
|
|
1898
|
+
const result = await client.post("/fin-sdk/data-connectors", body);
|
|
1899
|
+
render(
|
|
1900
|
+
result,
|
|
1901
|
+
opts,
|
|
1902
|
+
() => detail({
|
|
1903
|
+
"ID": String(result.id ?? ""),
|
|
1904
|
+
"Name": String(result.name ?? ""),
|
|
1905
|
+
"Status": result.status != null ? String(result.status) : void 0
|
|
1906
|
+
})
|
|
1907
|
+
);
|
|
1908
|
+
});
|
|
1909
|
+
dataConnectors.command("get <id>").description("Download a data connector by ID").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function(id) {
|
|
1910
|
+
const opts = this.optsWithGlobals();
|
|
1911
|
+
const client = await resolveClient(opts);
|
|
1912
|
+
const result = await client.get(`/fin-sdk/data-connectors/${id}/download`);
|
|
1913
|
+
render(
|
|
1914
|
+
result,
|
|
1915
|
+
opts,
|
|
1916
|
+
() => detail({
|
|
1917
|
+
"ID": String(result.id ?? ""),
|
|
1918
|
+
"Name": String(result.name ?? "")
|
|
1919
|
+
})
|
|
1920
|
+
);
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1769
1924
|
// src/commands/fin/guidance.ts
|
|
1770
1925
|
function registerGuidanceCommand(fin) {
|
|
1771
1926
|
const guidance = fin.command("guidance").description("Manage Fin SDK guidance");
|
|
@@ -1794,6 +1949,169 @@ function registerGuidanceCommand(fin) {
|
|
|
1794
1949
|
});
|
|
1795
1950
|
}
|
|
1796
1951
|
|
|
1952
|
+
// src/commands/fin/attributes.ts
|
|
1953
|
+
function registerAttributesCommand(fin) {
|
|
1954
|
+
const attributes = fin.command("attributes").description("Manage Fin SDK attributes");
|
|
1955
|
+
attributes.command("list").description("List Fin SDK attributes").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1956
|
+
const opts = this.optsWithGlobals();
|
|
1957
|
+
const client = await resolveClient(opts);
|
|
1958
|
+
const result = await client.get("/fin-sdk/attributes");
|
|
1959
|
+
const items = Array.isArray(result) ? result : result.attributes ?? [];
|
|
1960
|
+
render(items, opts, () => {
|
|
1961
|
+
if (items.length === 0) {
|
|
1962
|
+
return "No attributes found.";
|
|
1963
|
+
}
|
|
1964
|
+
const rows = items.map((item) => ({
|
|
1965
|
+
NAME: String(item.name ?? ""),
|
|
1966
|
+
TYPE: String(item.type ?? ""),
|
|
1967
|
+
DESCRIPTION: String(item.description ?? "")
|
|
1968
|
+
}));
|
|
1969
|
+
return table({ columns: ["NAME", "TYPE", "DESCRIPTION"], rows });
|
|
1970
|
+
}, items);
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
// src/commands/fin/audiences.ts
|
|
1975
|
+
function registerAudiencesCommand(fin) {
|
|
1976
|
+
const audiences = fin.command("audiences").description("Manage Fin SDK audiences");
|
|
1977
|
+
audiences.command("list").description("List Fin SDK audiences").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1978
|
+
const opts = this.optsWithGlobals();
|
|
1979
|
+
const client = await resolveClient(opts);
|
|
1980
|
+
const result = await client.get("/fin-sdk/audiences");
|
|
1981
|
+
const items = Array.isArray(result) ? result : result.audiences ?? [];
|
|
1982
|
+
render(items, opts, () => {
|
|
1983
|
+
if (items.length === 0) {
|
|
1984
|
+
return "No audiences found.";
|
|
1985
|
+
}
|
|
1986
|
+
const rows = items.map((item) => ({
|
|
1987
|
+
ID: String(item.id ?? ""),
|
|
1988
|
+
NAME: String(item.name ?? "")
|
|
1989
|
+
}));
|
|
1990
|
+
return table({ columns: ["ID", "NAME"], rows });
|
|
1991
|
+
}, items);
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
// src/commands/fin/workflows.ts
|
|
1996
|
+
function registerWorkflowsCommand(fin) {
|
|
1997
|
+
const workflows = fin.command("workflows").description("Manage Fin SDK workflows");
|
|
1998
|
+
workflows.command("list").description("List Fin SDK workflows").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1999
|
+
const opts = this.optsWithGlobals();
|
|
2000
|
+
const client = await resolveClient(opts);
|
|
2001
|
+
const result = await client.get("/fin-sdk/workflows");
|
|
2002
|
+
const items = Array.isArray(result) ? result : result.workflows ?? [];
|
|
2003
|
+
render(items, opts, () => {
|
|
2004
|
+
if (items.length === 0) {
|
|
2005
|
+
return "No workflows found.";
|
|
2006
|
+
}
|
|
2007
|
+
const rows = items.map((item) => ({
|
|
2008
|
+
ID: String(item.id ?? ""),
|
|
2009
|
+
TITLE: String(item.title ?? ""),
|
|
2010
|
+
STATE: String(item.state ?? ""),
|
|
2011
|
+
TRIGGER: String(item.trigger_type ?? "")
|
|
2012
|
+
}));
|
|
2013
|
+
return table({ columns: ["ID", "TITLE", "STATE", "TRIGGER"], rows });
|
|
2014
|
+
}, items);
|
|
2015
|
+
});
|
|
2016
|
+
workflows.command("get <id>").description("Get a workflow by ID").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function(id) {
|
|
2017
|
+
const opts = this.optsWithGlobals();
|
|
2018
|
+
const client = await resolveClient(opts);
|
|
2019
|
+
const result = await client.get(`/fin-sdk/workflows/${id}`);
|
|
2020
|
+
const r = result;
|
|
2021
|
+
render(
|
|
2022
|
+
result,
|
|
2023
|
+
opts,
|
|
2024
|
+
() => detail({
|
|
2025
|
+
"ID": String(r.id ?? ""),
|
|
2026
|
+
"Title": String(r.title ?? ""),
|
|
2027
|
+
"State": String(r.state ?? ""),
|
|
2028
|
+
"Trigger": r.trigger_type != null ? String(r.trigger_type) : void 0
|
|
2029
|
+
})
|
|
2030
|
+
);
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
// src/commands/fin/simulations.ts
|
|
2035
|
+
function registerSimulationsCommand(fin) {
|
|
2036
|
+
const simulations = fin.command("simulations").description("Manage Fin SDK simulations");
|
|
2037
|
+
simulations.command("list <procedure_id>").description("List simulations for a procedure (displays YAML)").option("--verbose", "Show HTTP request/response details").action(async function(procedureId) {
|
|
2038
|
+
const opts = this.optsWithGlobals();
|
|
2039
|
+
const client = await resolveClient(opts);
|
|
2040
|
+
const text = await client.getText(`/fin-sdk/procedures/${procedureId}/simulations`);
|
|
2041
|
+
console.log(text);
|
|
2042
|
+
});
|
|
2043
|
+
simulations.command("run <procedure_id> [test_id]").description("Run one or all simulations for a procedure").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function(procedureId, testId) {
|
|
2044
|
+
const opts = this.optsWithGlobals();
|
|
2045
|
+
const client = await resolveClient(opts);
|
|
2046
|
+
let result;
|
|
2047
|
+
if (testId) {
|
|
2048
|
+
result = await client.post(`/fin-sdk/procedures/${procedureId}/simulations/${testId}/run`, {});
|
|
2049
|
+
} else {
|
|
2050
|
+
result = await client.post(`/fin-sdk/procedures/${procedureId}/simulations/run`, {});
|
|
2051
|
+
}
|
|
2052
|
+
const r = result;
|
|
2053
|
+
render(result, opts, () => {
|
|
2054
|
+
if (r.enqueued && Array.isArray(r.enqueued) && r.enqueued.length > 0) {
|
|
2055
|
+
const rows = r.enqueued.map((e) => ({
|
|
2056
|
+
RUN_ID: String(e.run_id ?? ""),
|
|
2057
|
+
TEST_ID: String(e.test_id ?? ""),
|
|
2058
|
+
NAME: String(e.simulation_name ?? ""),
|
|
2059
|
+
STATUS: String(e.status ?? "")
|
|
2060
|
+
}));
|
|
2061
|
+
return table({ columns: ["RUN_ID", "TEST_ID", "NAME", "STATUS"], rows });
|
|
2062
|
+
} else {
|
|
2063
|
+
const runId = r.run_id;
|
|
2064
|
+
if (runId !== void 0) {
|
|
2065
|
+
return `run_id: ${runId}`;
|
|
2066
|
+
} else {
|
|
2067
|
+
return detail({
|
|
2068
|
+
"Procedure ID": String(r.procedure_id ?? "")
|
|
2069
|
+
});
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
});
|
|
2073
|
+
});
|
|
2074
|
+
simulations.command("result <run_id>").description("Get the result of a simulation run").option("--json", "Output as JSON").option("--wait", "Poll until run completes").option("--verbose", "Show HTTP request/response details").action(async function(runId) {
|
|
2075
|
+
const opts = this.optsWithGlobals();
|
|
2076
|
+
const client = await resolveClient(opts);
|
|
2077
|
+
let result = await client.get(`/fin-sdk/runs/${runId}`);
|
|
2078
|
+
if (opts.wait) {
|
|
2079
|
+
const deadline = Date.now() + SIMULATION_POLL_TIMEOUT_MS;
|
|
2080
|
+
while (result.status === "pending" || result.status === "running") {
|
|
2081
|
+
if (Date.now() > deadline) {
|
|
2082
|
+
throw new TimeoutError(
|
|
2083
|
+
`Simulation polling timed out after ${SIMULATION_POLL_TIMEOUT_MS / 1e3}s. Last status: ${result.status}. Run "intercom fin simulations result ${runId}" to check later.`
|
|
2084
|
+
);
|
|
2085
|
+
}
|
|
2086
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
2087
|
+
result = await client.get(`/fin-sdk/runs/${runId}`);
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
render(
|
|
2091
|
+
result,
|
|
2092
|
+
opts,
|
|
2093
|
+
() => detail({
|
|
2094
|
+
"Run ID": String(result.run_id ?? ""),
|
|
2095
|
+
"Status": String(result.status ?? "")
|
|
2096
|
+
})
|
|
2097
|
+
);
|
|
2098
|
+
});
|
|
2099
|
+
simulations.command("generate <procedure_id>").description("Generate simulations for a procedure").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function(procedureId) {
|
|
2100
|
+
const opts = this.optsWithGlobals();
|
|
2101
|
+
const client = await resolveClient(opts);
|
|
2102
|
+
const result = await client.post(`/fin-sdk/procedures/${procedureId}/simulations/generate`, {});
|
|
2103
|
+
const r = result;
|
|
2104
|
+
render(
|
|
2105
|
+
result,
|
|
2106
|
+
opts,
|
|
2107
|
+
() => detail({
|
|
2108
|
+
"Status": String(r.status ?? ""),
|
|
2109
|
+
"Procedure ID": String(r.procedure_id ?? "")
|
|
2110
|
+
})
|
|
2111
|
+
);
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
|
|
1797
2115
|
// src/auth/ember-session.ts
|
|
1798
2116
|
async function getEmberSession(options) {
|
|
1799
2117
|
const { email, password, appId, verifyEmailUrl, timeoutMs = API_TIMEOUT_MS } = options;
|
|
@@ -1964,7 +2282,14 @@ function renderResourceTable(label, items) {
|
|
|
1964
2282
|
${table({ columns: ["ID", "NAME"], rows })}`;
|
|
1965
2283
|
}
|
|
1966
2284
|
function registerFinCommand(program) {
|
|
1967
|
-
const fin = program.command("fin").description("Manage Fin SDK resources")
|
|
2285
|
+
const fin = program.command("fin").description("Manage Fin AI Agent and SDK resources").addHelpText(
|
|
2286
|
+
"after",
|
|
2287
|
+
`
|
|
2288
|
+
Examples:
|
|
2289
|
+
intercom fin manifest
|
|
2290
|
+
intercom fin enable --email admin@company.com
|
|
2291
|
+
intercom fin guidance list`
|
|
2292
|
+
);
|
|
1968
2293
|
fin.command("manifest").description("Show the Fin SDK manifest for this workspace").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
1969
2294
|
const opts = this.optsWithGlobals();
|
|
1970
2295
|
const client = await resolveClient(opts);
|
|
@@ -1990,12 +2315,26 @@ function registerFinCommand(program) {
|
|
|
1990
2315
|
});
|
|
1991
2316
|
});
|
|
1992
2317
|
registerFinEnableCommand(fin);
|
|
2318
|
+
registerProceduresCommand(fin);
|
|
2319
|
+
registerDataConnectorsCommand(fin);
|
|
1993
2320
|
registerGuidanceCommand(fin);
|
|
2321
|
+
registerAttributesCommand(fin);
|
|
2322
|
+
registerAudiencesCommand(fin);
|
|
2323
|
+
registerWorkflowsCommand(fin);
|
|
2324
|
+
registerSimulationsCommand(fin);
|
|
2325
|
+
fin.command("download").description("Download Fin SDK resources as a ZIP file").option("-o, --output <path>", "Output file path", "./fin-resources.zip").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
2326
|
+
const opts = this.optsWithGlobals();
|
|
2327
|
+
const outputPath = opts.output ?? "./fin-resources.zip";
|
|
2328
|
+
const client = await resolveClient(opts);
|
|
2329
|
+
const buffer = await client.getBuffer("/fin-sdk/download");
|
|
2330
|
+
await writeFile2(outputPath, buffer);
|
|
2331
|
+
console.log(`Downloaded ${buffer.length} bytes to ${outputPath}`);
|
|
2332
|
+
});
|
|
1994
2333
|
}
|
|
1995
2334
|
|
|
1996
2335
|
// src/commands/setup.ts
|
|
1997
2336
|
import { readdirSync, readFileSync as readFileSync3, statSync } from "fs";
|
|
1998
|
-
import { join as join3, basename } from "path";
|
|
2337
|
+
import { join as join3, basename as basename2 } from "path";
|
|
1999
2338
|
function isGreenfield(opts) {
|
|
2000
2339
|
return !!(opts.email && opts.name && (process.env.INTERCOM_PASSWORD || opts.passwordStdin));
|
|
2001
2340
|
}
|
|
@@ -2003,6 +2342,11 @@ function hasPartialGreenfieldFlags(opts) {
|
|
|
2003
2342
|
const hasPassword = !!(process.env.INTERCOM_PASSWORD || opts.passwordStdin);
|
|
2004
2343
|
return !!(opts.email && hasPassword && !opts.name);
|
|
2005
2344
|
}
|
|
2345
|
+
async function hasExistingAuth() {
|
|
2346
|
+
const configDir = process.env.INTERCOM_CONFIG_DIR;
|
|
2347
|
+
const config = await readConfig(configDir);
|
|
2348
|
+
return !!config.default;
|
|
2349
|
+
}
|
|
2006
2350
|
function buildPlan(opts) {
|
|
2007
2351
|
const steps = [];
|
|
2008
2352
|
let stepNum = 1;
|
|
@@ -2024,23 +2368,6 @@ function buildPlan(opts) {
|
|
|
2024
2368
|
]
|
|
2025
2369
|
});
|
|
2026
2370
|
}
|
|
2027
|
-
if (opts.companyName) {
|
|
2028
|
-
steps.push({
|
|
2029
|
-
step: stepNum++,
|
|
2030
|
-
description: "Configure Messenger branding",
|
|
2031
|
-
commands: [
|
|
2032
|
-
`intercom messenger update -f name="${opts.companyName}"`
|
|
2033
|
-
]
|
|
2034
|
-
});
|
|
2035
|
-
} else {
|
|
2036
|
-
steps.push({
|
|
2037
|
-
step: stepNum++,
|
|
2038
|
-
description: "Configure Messenger branding",
|
|
2039
|
-
commands: [
|
|
2040
|
-
`intercom messenger update -f name="<your-company-name>"`
|
|
2041
|
-
]
|
|
2042
|
-
});
|
|
2043
|
-
}
|
|
2044
2371
|
steps.push({
|
|
2045
2372
|
step: stepNum++,
|
|
2046
2373
|
description: "Get Messenger install snippet",
|
|
@@ -2065,8 +2392,8 @@ function buildPlan(opts) {
|
|
|
2065
2392
|
}
|
|
2066
2393
|
if (mdFiles.length > 0) {
|
|
2067
2394
|
const articleCommands = mdFiles.map((file) => {
|
|
2068
|
-
const title =
|
|
2069
|
-
return `intercom articles create -f title="${title}" -F body=@${join3(opts.articlesFrom, file)}`;
|
|
2395
|
+
const title = basename2(file, ".md").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
2396
|
+
return `intercom articles create -f title="${title}" -F body=@${join3(opts.articlesFrom, file)} -f author_id=$(intercom me --json | jq -r .id)`;
|
|
2070
2397
|
});
|
|
2071
2398
|
steps.push({
|
|
2072
2399
|
step: stepNum++,
|
|
@@ -2078,7 +2405,7 @@ function buildPlan(opts) {
|
|
|
2078
2405
|
step: stepNum++,
|
|
2079
2406
|
description: `Create articles from ${opts.articlesFrom}`,
|
|
2080
2407
|
commands: [
|
|
2081
|
-
`intercom articles create -f title="<article-title>" -F body=@${opts.articlesFrom}/<file>.md`
|
|
2408
|
+
`intercom articles create -f title="<article-title>" -F body=@${opts.articlesFrom}/<file>.md -f author_id=$(intercom me --json | jq -r .id)`
|
|
2082
2409
|
]
|
|
2083
2410
|
});
|
|
2084
2411
|
}
|
|
@@ -2103,19 +2430,21 @@ function formatPlanText(steps) {
|
|
|
2103
2430
|
return lines.join("\n");
|
|
2104
2431
|
}
|
|
2105
2432
|
async function runPostAuthSteps(client, opts, results, appId) {
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
results.push(`\u2713 Messenger configured${opts.companyName ? ` (${opts.companyName})` : ""}`);
|
|
2433
|
+
results.push(`\u2713 Messenger configured`);
|
|
2434
|
+
const me = await client.get("/me");
|
|
2435
|
+
const authorId = me.id != null ? Number(me.id) : void 0;
|
|
2110
2436
|
const helpCenterName = opts.companyName ? `${opts.companyName} Help` : "Help Center";
|
|
2111
2437
|
const collections = await client.paginate("/help_center/collections");
|
|
2112
2438
|
const existingCollection = collections.find(
|
|
2113
2439
|
(c) => String(c.name ?? "") === helpCenterName
|
|
2114
2440
|
);
|
|
2441
|
+
let collectionId;
|
|
2115
2442
|
if (existingCollection) {
|
|
2443
|
+
collectionId = String(existingCollection.id);
|
|
2116
2444
|
results.push(`\u2713 Help center already exists (${helpCenterName})`);
|
|
2117
2445
|
} else {
|
|
2118
|
-
await client.post("/help_center/collections", { name: helpCenterName });
|
|
2446
|
+
const created = await client.post("/help_center/collections", { name: helpCenterName });
|
|
2447
|
+
collectionId = created.id != null ? String(created.id) : void 0;
|
|
2119
2448
|
results.push(`\u2713 Help center created (${helpCenterName})`);
|
|
2120
2449
|
}
|
|
2121
2450
|
if (opts.articlesFrom) {
|
|
@@ -2130,12 +2459,18 @@ async function runPostAuthSteps(client, opts, results, appId) {
|
|
|
2130
2459
|
let created = 0;
|
|
2131
2460
|
let skipped = 0;
|
|
2132
2461
|
for (const file of mdFiles) {
|
|
2133
|
-
const title =
|
|
2462
|
+
const title = basename2(file, ".md").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
2134
2463
|
const body = readFileSync3(join3(opts.articlesFrom, file), "utf-8");
|
|
2135
2464
|
if (existingTitles.has(title)) {
|
|
2136
2465
|
skipped++;
|
|
2137
2466
|
} else {
|
|
2138
|
-
|
|
2467
|
+
const articleBody = { title, body, state: "published" };
|
|
2468
|
+
if (authorId != null) articleBody.author_id = authorId;
|
|
2469
|
+
if (collectionId != null) {
|
|
2470
|
+
articleBody.parent_id = collectionId;
|
|
2471
|
+
articleBody.parent_type = "collection";
|
|
2472
|
+
}
|
|
2473
|
+
await client.post("/articles", articleBody);
|
|
2139
2474
|
created++;
|
|
2140
2475
|
}
|
|
2141
2476
|
}
|
|
@@ -2237,7 +2572,19 @@ async function runPostAuthSteps(client, opts, results, appId) {
|
|
|
2237
2572
|
console.log("Setup complete!");
|
|
2238
2573
|
}
|
|
2239
2574
|
function registerSetupCommand(program) {
|
|
2240
|
-
program.command("setup").description("Set up a complete Intercom installation").
|
|
2575
|
+
program.command("setup").description("Set up a complete Intercom installation").addHelpText(
|
|
2576
|
+
"after",
|
|
2577
|
+
`
|
|
2578
|
+
Examples:
|
|
2579
|
+
# Existing workspace (already authenticated)
|
|
2580
|
+
intercom setup --company-name "Acme Inc" --articles-from ./docs
|
|
2581
|
+
|
|
2582
|
+
# New workspace (greenfield)
|
|
2583
|
+
INTERCOM_PASSWORD=*** intercom setup --email admin@acme.com --name "Admin" --company-name "Acme Inc"
|
|
2584
|
+
|
|
2585
|
+
# Preview steps without executing
|
|
2586
|
+
intercom setup --plan`
|
|
2587
|
+
).option("--company-name <name>", "Company name for Messenger branding").option("--articles-from <dir>", "Directory of markdown files to create as articles").option("--plan", "Output setup steps as CLI commands without executing").option("--dry-run", "Show what would happen without executing").option("--json", "Output as JSON (for --plan mode)").option("--verbose", "Show HTTP request/response details").option("--email <email>", "Admin email address (for new workspace signup)").option("--password-stdin", "Read password from stdin (or set INTERCOM_PASSWORD env var)").option("--name <name>", "Admin name (for new workspace signup)").option("--plan-tier <tier>", "Trial plan tier: essential, advanced, expert (default: advanced)").option("--enable-fin", "Enable Fin AI Agent (default: true for greenfield setup)", true).option("--no-enable-fin", "Skip Fin enablement").option("--verify-email-url <url>", "Email verification URL (needed for Fin on fresh workspaces)").action(async function() {
|
|
2241
2588
|
const opts = this.optsWithGlobals();
|
|
2242
2589
|
if (hasPartialGreenfieldFlags(opts)) {
|
|
2243
2590
|
throw new CLIError(
|
|
@@ -2288,7 +2635,8 @@ function registerSetupCommand(program) {
|
|
|
2288
2635
|
return;
|
|
2289
2636
|
}
|
|
2290
2637
|
const results = [];
|
|
2291
|
-
|
|
2638
|
+
const alreadyAuthed = await hasExistingAuth();
|
|
2639
|
+
if (isGreenfield(opts) && !alreadyAuthed) {
|
|
2292
2640
|
const password = await resolvePassword({ passwordStdin: opts.passwordStdin });
|
|
2293
2641
|
const baseUrl = getAppBaseUrl();
|
|
2294
2642
|
const planTier = opts.planTier ?? "advanced";
|
|
@@ -2302,6 +2650,13 @@ function registerSetupCommand(program) {
|
|
|
2302
2650
|
plan: planTier
|
|
2303
2651
|
});
|
|
2304
2652
|
results.push(`\u2713 Workspace created: ${workspace.name} (${workspace.id})`);
|
|
2653
|
+
if (opts.verifyEmailUrl) {
|
|
2654
|
+
try {
|
|
2655
|
+
await fetchWithTimeout(opts.verifyEmailUrl, { redirect: "manual" }, { timeoutMs: API_TIMEOUT_MS });
|
|
2656
|
+
results.push(`\u2713 Email verified`);
|
|
2657
|
+
} catch {
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2305
2660
|
let token;
|
|
2306
2661
|
try {
|
|
2307
2662
|
const result = await getToken({
|
|
@@ -2316,9 +2671,17 @@ function registerSetupCommand(program) {
|
|
|
2316
2671
|
console.error(`\u2713 Workspace created: ${workspace.name} (${workspace.id})`);
|
|
2317
2672
|
console.error(`
|
|
2318
2673
|
Authentication failed after workspace creation: ${message}`);
|
|
2319
|
-
|
|
2674
|
+
if (message.includes("403")) {
|
|
2675
|
+
console.error(`
|
|
2676
|
+
This is likely because the email has not been verified.`);
|
|
2677
|
+
console.error(`Verify your email first, then bootstrap:`);
|
|
2678
|
+
console.error(` intercom auth verify-email --url <url-from-verification-email>`);
|
|
2679
|
+
} else {
|
|
2680
|
+
console.error(`
|
|
2320
2681
|
Your workspace exists but credentials were not saved.`);
|
|
2321
|
-
|
|
2682
|
+
}
|
|
2683
|
+
console.error(`
|
|
2684
|
+
To complete setup, run:
|
|
2322
2685
|
`);
|
|
2323
2686
|
console.error(` INTERCOM_PASSWORD=*** intercom auth bootstrap --email ${opts.email} --app-id ${workspace.id}`);
|
|
2324
2687
|
console.error(`
|
|
@@ -2352,10 +2715,246 @@ Then re-run setup without signup flags:
|
|
|
2352
2715
|
});
|
|
2353
2716
|
}
|
|
2354
2717
|
|
|
2718
|
+
// src/commands/completion.ts
|
|
2719
|
+
function binName() {
|
|
2720
|
+
const argv1 = process.argv[1] ?? "";
|
|
2721
|
+
if (argv1.endsWith("/fin") || argv1.endsWith("\\fin")) return "fin";
|
|
2722
|
+
return "intercom";
|
|
2723
|
+
}
|
|
2724
|
+
var COMMANDS = {
|
|
2725
|
+
api: [],
|
|
2726
|
+
auth: ["login", "logout", "status", "bootstrap", "signup", "verify-email"],
|
|
2727
|
+
me: [],
|
|
2728
|
+
articles: ["list", "get", "create", "update", "delete"],
|
|
2729
|
+
contacts: ["list", "get", "create", "update", "delete"],
|
|
2730
|
+
conversations: ["list", "get", "reply"],
|
|
2731
|
+
"help-center": ["list", "get", "create"],
|
|
2732
|
+
messenger: ["get", "update", "snippet"],
|
|
2733
|
+
fin: ["manifest", "enable", "guidance"],
|
|
2734
|
+
setup: [],
|
|
2735
|
+
pricing: [],
|
|
2736
|
+
completion: ["bash", "zsh", "fish"]
|
|
2737
|
+
};
|
|
2738
|
+
var GLOBAL_FLAGS = [
|
|
2739
|
+
"--json",
|
|
2740
|
+
"--jq",
|
|
2741
|
+
"--workspace",
|
|
2742
|
+
"--verbose",
|
|
2743
|
+
"--no-retry",
|
|
2744
|
+
"--timeout",
|
|
2745
|
+
"--agent",
|
|
2746
|
+
"--human",
|
|
2747
|
+
"--help",
|
|
2748
|
+
"--version"
|
|
2749
|
+
];
|
|
2750
|
+
function bashScript(name = binName()) {
|
|
2751
|
+
const commandNames = Object.keys(COMMANDS).join(" ");
|
|
2752
|
+
const fnName = `_${name}`;
|
|
2753
|
+
const subcommandCases = Object.entries(COMMANDS).filter(([, subs]) => subs.length > 0).map(([cmd, subs]) => ` ${cmd}) COMPREPLY=( $(compgen -W "${subs.join(" ")}" -- "$cur") ) ;;`).join("\n");
|
|
2754
|
+
return `# bash completion for ${name} CLI
|
|
2755
|
+
# Add to ~/.bashrc: eval "$(${name} completion bash)"
|
|
2756
|
+
|
|
2757
|
+
${fnName}() {
|
|
2758
|
+
local cur prev commands
|
|
2759
|
+
COMPREPLY=()
|
|
2760
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
2761
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
2762
|
+
commands="${commandNames}"
|
|
2763
|
+
|
|
2764
|
+
if [[ "$cur" == -* ]]; then
|
|
2765
|
+
COMPREPLY=( $(compgen -W "${GLOBAL_FLAGS.join(" ")}" -- "$cur") )
|
|
2766
|
+
return 0
|
|
2767
|
+
fi
|
|
2768
|
+
|
|
2769
|
+
case "\${COMP_WORDS[1]}" in
|
|
2770
|
+
${subcommandCases}
|
|
2771
|
+
*)
|
|
2772
|
+
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
2773
|
+
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
|
2774
|
+
fi
|
|
2775
|
+
;;
|
|
2776
|
+
esac
|
|
2777
|
+
return 0
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
complete -F ${fnName} ${name}
|
|
2781
|
+
`;
|
|
2782
|
+
}
|
|
2783
|
+
function zshScript(name = binName()) {
|
|
2784
|
+
const fnName = `_${name}`;
|
|
2785
|
+
const commandDescs = [
|
|
2786
|
+
"api:'Make an authenticated API request'",
|
|
2787
|
+
"auth:'Manage authentication credentials'",
|
|
2788
|
+
"me:'Show current admin and workspace info'",
|
|
2789
|
+
"articles:'Manage help center articles'",
|
|
2790
|
+
"contacts:'Manage contacts'",
|
|
2791
|
+
"conversations:'Manage conversations'",
|
|
2792
|
+
"help-center:'Manage help center collections'",
|
|
2793
|
+
"messenger:'Manage Messenger settings'",
|
|
2794
|
+
"fin:'Manage Fin AI Agent'",
|
|
2795
|
+
"setup:'Set up a complete Intercom installation'",
|
|
2796
|
+
"pricing:'Show current Intercom pricing information'",
|
|
2797
|
+
"completion:'Generate shell completion scripts'"
|
|
2798
|
+
];
|
|
2799
|
+
const subcommandFunctions = Object.entries(COMMANDS).filter(([, subs]) => subs.length > 0).map(([cmd, subs]) => {
|
|
2800
|
+
const subFnName = cmd.replace(/-/g, "_");
|
|
2801
|
+
const subLines = subs.map((s) => `'${s}'`).join(" ");
|
|
2802
|
+
return `${fnName}_${subFnName}() {
|
|
2803
|
+
local -a subcommands
|
|
2804
|
+
subcommands=(${subLines})
|
|
2805
|
+
_describe 'subcommand' subcommands
|
|
2806
|
+
}`;
|
|
2807
|
+
}).join("\n\n");
|
|
2808
|
+
return `#compdef ${name}
|
|
2809
|
+
# zsh completion for ${name} CLI
|
|
2810
|
+
# Add to ~/.zshrc: eval "$(${name} completion zsh)"
|
|
2811
|
+
|
|
2812
|
+
${fnName}() {
|
|
2813
|
+
local -a commands global_flags
|
|
2814
|
+
commands=(
|
|
2815
|
+
${commandDescs.join("\n ")}
|
|
2816
|
+
)
|
|
2817
|
+
global_flags=(
|
|
2818
|
+
${GLOBAL_FLAGS.map((f) => `'${f}'`).join("\n ")}
|
|
2819
|
+
)
|
|
2820
|
+
|
|
2821
|
+
_arguments -C \\
|
|
2822
|
+
'1:command:->command' \\
|
|
2823
|
+
'*::arg:->args'
|
|
2824
|
+
|
|
2825
|
+
case $state in
|
|
2826
|
+
command)
|
|
2827
|
+
_describe 'command' commands
|
|
2828
|
+
;;
|
|
2829
|
+
args)
|
|
2830
|
+
case $words[1] in
|
|
2831
|
+
${Object.entries(COMMANDS).filter(([, subs]) => subs.length > 0).map(([cmd]) => ` ${cmd}) ${fnName}_${cmd.replace(/-/g, "_")} ;;`).join("\n")}
|
|
2832
|
+
esac
|
|
2833
|
+
;;
|
|
2834
|
+
esac
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
${subcommandFunctions}
|
|
2838
|
+
|
|
2839
|
+
${fnName} "$@"
|
|
2840
|
+
`;
|
|
2841
|
+
}
|
|
2842
|
+
function fishScript(name = binName()) {
|
|
2843
|
+
const lines = [
|
|
2844
|
+
`# fish completion for ${name} CLI`,
|
|
2845
|
+
`# Add to fish config: ${name} completion fish | source`,
|
|
2846
|
+
"",
|
|
2847
|
+
"# Disable file completions",
|
|
2848
|
+
`complete -c ${name} -f`,
|
|
2849
|
+
"",
|
|
2850
|
+
"# Top-level commands"
|
|
2851
|
+
];
|
|
2852
|
+
const commandDescs = {
|
|
2853
|
+
api: "Make an authenticated API request",
|
|
2854
|
+
auth: "Manage authentication credentials",
|
|
2855
|
+
me: "Show current admin and workspace info",
|
|
2856
|
+
articles: "Manage help center articles",
|
|
2857
|
+
contacts: "Manage contacts",
|
|
2858
|
+
conversations: "Manage conversations",
|
|
2859
|
+
"help-center": "Manage help center collections",
|
|
2860
|
+
messenger: "Manage Messenger settings",
|
|
2861
|
+
fin: "Manage Fin AI Agent",
|
|
2862
|
+
setup: "Set up a complete Intercom installation",
|
|
2863
|
+
pricing: "Show current Intercom pricing information",
|
|
2864
|
+
completion: "Generate shell completion scripts"
|
|
2865
|
+
};
|
|
2866
|
+
for (const [cmd, desc] of Object.entries(commandDescs)) {
|
|
2867
|
+
lines.push(
|
|
2868
|
+
`complete -c ${name} -n '__fish_use_subcommand' -a '${cmd}' -d '${desc}'`
|
|
2869
|
+
);
|
|
2870
|
+
}
|
|
2871
|
+
lines.push("");
|
|
2872
|
+
lines.push("# Subcommands");
|
|
2873
|
+
for (const [cmd, subs] of Object.entries(COMMANDS)) {
|
|
2874
|
+
for (const sub of subs) {
|
|
2875
|
+
lines.push(
|
|
2876
|
+
`complete -c ${name} -n '__fish_seen_subcommand_from ${cmd}' -a '${sub}'`
|
|
2877
|
+
);
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2880
|
+
lines.push("");
|
|
2881
|
+
lines.push("# Global flags");
|
|
2882
|
+
for (const flag of GLOBAL_FLAGS) {
|
|
2883
|
+
lines.push(`complete -c ${name} -l '${flag.replace(/^--/, "")}'`);
|
|
2884
|
+
}
|
|
2885
|
+
lines.push("");
|
|
2886
|
+
return lines.join("\n");
|
|
2887
|
+
}
|
|
2888
|
+
function registerCompletionCommand(program) {
|
|
2889
|
+
const name = binName();
|
|
2890
|
+
const completion = program.command("completion").description("Generate shell completion scripts").addHelpText(
|
|
2891
|
+
"after",
|
|
2892
|
+
`
|
|
2893
|
+
Examples:
|
|
2894
|
+
# Bash (add to ~/.bashrc)
|
|
2895
|
+
eval "$(${name} completion bash)"
|
|
2896
|
+
|
|
2897
|
+
# Zsh (add to ~/.zshrc)
|
|
2898
|
+
eval "$(${name} completion zsh)"
|
|
2899
|
+
|
|
2900
|
+
# Fish (add to fish config)
|
|
2901
|
+
${name} completion fish | source`
|
|
2902
|
+
);
|
|
2903
|
+
completion.command("bash").description("Generate bash completion script").action(() => {
|
|
2904
|
+
console.log(bashScript());
|
|
2905
|
+
});
|
|
2906
|
+
completion.command("zsh").description("Generate zsh completion script").action(() => {
|
|
2907
|
+
console.log(zshScript());
|
|
2908
|
+
});
|
|
2909
|
+
completion.command("fish").description("Generate fish completion script").action(() => {
|
|
2910
|
+
console.log(fishScript());
|
|
2911
|
+
});
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
// src/commands/pricing.ts
|
|
2915
|
+
var PRICING_URL = "https://www.intercom.com/pricing.md";
|
|
2916
|
+
function registerPricingCommand(program) {
|
|
2917
|
+
program.command("pricing").description("Show current Intercom pricing information").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
2918
|
+
const opts = this.optsWithGlobals();
|
|
2919
|
+
const response = await fetchWithTimeout(
|
|
2920
|
+
PRICING_URL,
|
|
2921
|
+
{ headers: { Accept: "text/markdown, text/plain, */*" } },
|
|
2922
|
+
{ timeoutMs: API_TIMEOUT_MS, verbose: opts.verbose }
|
|
2923
|
+
);
|
|
2924
|
+
if (!response.ok) {
|
|
2925
|
+
throw new CLIError(`Failed to fetch pricing: ${response.status} ${response.statusText}`);
|
|
2926
|
+
}
|
|
2927
|
+
const markdown = await response.text();
|
|
2928
|
+
if (opts.json) {
|
|
2929
|
+
const { formatJson: formatJson2 } = await import("./json-TDEGGEUF.js");
|
|
2930
|
+
console.log(formatJson2({ url: PRICING_URL, content: markdown }));
|
|
2931
|
+
} else {
|
|
2932
|
+
console.log(markdown);
|
|
2933
|
+
}
|
|
2934
|
+
});
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2355
2937
|
// src/index.ts
|
|
2938
|
+
function detectBinaryName() {
|
|
2939
|
+
const argv1 = process.argv[1] ?? "";
|
|
2940
|
+
if (argv1.endsWith("/fin") || argv1.endsWith("\\fin")) return "fin";
|
|
2941
|
+
return "intercom";
|
|
2942
|
+
}
|
|
2943
|
+
function fullCommandName(cmd) {
|
|
2944
|
+
const parts = [];
|
|
2945
|
+
const rootNames = /* @__PURE__ */ new Set(["intercom", "fin"]);
|
|
2946
|
+
let current = cmd;
|
|
2947
|
+
while (current) {
|
|
2948
|
+
const name = current.name();
|
|
2949
|
+
if (name && !rootNames.has(name)) parts.unshift(name);
|
|
2950
|
+
current = current.parent;
|
|
2951
|
+
}
|
|
2952
|
+
return parts.join(" ");
|
|
2953
|
+
}
|
|
2356
2954
|
function createProgram() {
|
|
2357
2955
|
const program = new Command();
|
|
2358
|
-
|
|
2956
|
+
const binName2 = detectBinaryName();
|
|
2957
|
+
program.name(binName2).description("CLI tool for managing Intercom workspaces").version(VERSION).option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output").option("--workspace <id>", "Override default workspace").option("--verbose", "Show HTTP request/response details").option("--no-retry", "Disable automatic rate limit retry").option("--timeout <seconds>", "Request timeout in seconds").option("--agent", "Force machine-readable output (JSON/NDJSON)").option("--human", "Force human-readable output even when piped");
|
|
2359
2958
|
registerApiCommand(program);
|
|
2360
2959
|
registerAuthCommand(program);
|
|
2361
2960
|
registerMeCommand(program);
|
|
@@ -2366,10 +2965,19 @@ function createProgram() {
|
|
|
2366
2965
|
registerMessengerCommand(program);
|
|
2367
2966
|
registerFinCommand(program);
|
|
2368
2967
|
registerSetupCommand(program);
|
|
2968
|
+
registerPricingCommand(program);
|
|
2969
|
+
registerCompletionCommand(program);
|
|
2970
|
+
program.hook("preAction", (thisCommand, actionCommand) => {
|
|
2971
|
+
const rootOpts = thisCommand.opts();
|
|
2972
|
+
if (rootOpts.agent && rootOpts.human) {
|
|
2973
|
+
throw new CLIError("--agent and --human are mutually exclusive");
|
|
2974
|
+
}
|
|
2975
|
+
setCliCommand(fullCommandName(actionCommand));
|
|
2976
|
+
});
|
|
2369
2977
|
return program;
|
|
2370
2978
|
}
|
|
2371
2979
|
function handleError(err) {
|
|
2372
|
-
const isJson = process.argv.includes("--json");
|
|
2980
|
+
const isJson = process.argv.includes("--json") || process.argv.includes("--agent");
|
|
2373
2981
|
if (err instanceof CLIError) {
|
|
2374
2982
|
if (isJson) {
|
|
2375
2983
|
console.error(formatJson({
|
|
@@ -2387,7 +2995,7 @@ function handleError(err) {
|
|
|
2387
2995
|
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
2388
2996
|
process.exit(1);
|
|
2389
2997
|
}
|
|
2390
|
-
var isMainModule = process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("intercom");
|
|
2998
|
+
var isMainModule = process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("intercom") || process.argv[1]?.endsWith("fin");
|
|
2391
2999
|
if (isMainModule) {
|
|
2392
3000
|
const program = createProgram();
|
|
2393
3001
|
try {
|