exponential-cli 1.4.0 → 1.5.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/index.js +150 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command14 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -499,6 +499,60 @@ function outputInteractionPretty(interaction) {
|
|
|
499
499
|
if (interaction.notes) console.log(` ${chalk3.gray("Notes:")} ${interaction.notes}`);
|
|
500
500
|
console.log();
|
|
501
501
|
}
|
|
502
|
+
function transformOrganization(org) {
|
|
503
|
+
return {
|
|
504
|
+
id: org.id,
|
|
505
|
+
workspaceId: org.workspaceId,
|
|
506
|
+
name: org.name,
|
|
507
|
+
websiteUrl: org.websiteUrl,
|
|
508
|
+
logoUrl: org.logoUrl,
|
|
509
|
+
description: org.description,
|
|
510
|
+
industry: org.industry,
|
|
511
|
+
size: org.size,
|
|
512
|
+
contactCount: org._count?.contacts ?? null,
|
|
513
|
+
createdAt: new Date(org.createdAt).toISOString(),
|
|
514
|
+
updatedAt: new Date(org.updatedAt).toISOString()
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function outputOrganizationJson(org) {
|
|
518
|
+
console.log(JSON.stringify(transformOrganization(org), null, 2));
|
|
519
|
+
}
|
|
520
|
+
function outputOrganizationPretty(org) {
|
|
521
|
+
console.log(chalk3.gray("\u2500".repeat(50)));
|
|
522
|
+
console.log(`
|
|
523
|
+
${chalk3.bold(org.name)}`);
|
|
524
|
+
console.log(chalk3.gray(` ID: ${org.id}`));
|
|
525
|
+
if (org.industry) console.log(` ${chalk3.magenta("Industry:")} ${org.industry}`);
|
|
526
|
+
if (org.size) console.log(` ${chalk3.cyan("Size:")} ${org.size}`);
|
|
527
|
+
if (org.websiteUrl) console.log(` ${chalk3.cyan("Website:")} ${org.websiteUrl}`);
|
|
528
|
+
if (org.description) console.log(` ${chalk3.gray("About:")} ${org.description.substring(0, 120)}${org.description.length > 120 ? "..." : ""}`);
|
|
529
|
+
if (org._count?.contacts != null) console.log(` ${chalk3.green("Contacts:")} ${org._count.contacts}`);
|
|
530
|
+
console.log();
|
|
531
|
+
}
|
|
532
|
+
function outputOrganizationsJson(organizations, nextCursor) {
|
|
533
|
+
console.log(JSON.stringify({
|
|
534
|
+
organizations: organizations.map(transformOrganization),
|
|
535
|
+
total: organizations.length,
|
|
536
|
+
nextCursor: nextCursor ?? null
|
|
537
|
+
}, null, 2));
|
|
538
|
+
}
|
|
539
|
+
function outputOrganizationsPretty(organizations) {
|
|
540
|
+
if (organizations.length === 0) {
|
|
541
|
+
console.log(chalk3.gray("No organizations found."));
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
console.log(chalk3.bold(`
|
|
545
|
+
Organizations (${organizations.length} total)`));
|
|
546
|
+
console.log(chalk3.gray("\u2500".repeat(50)));
|
|
547
|
+
for (const org of organizations) {
|
|
548
|
+
console.log(`
|
|
549
|
+
${chalk3.bold(org.name)}`);
|
|
550
|
+
console.log(chalk3.gray(` ID: ${org.id}`));
|
|
551
|
+
if (org.industry) console.log(` ${chalk3.magenta("Industry:")} ${org.industry}`);
|
|
552
|
+
if (org._count?.contacts != null) console.log(` ${chalk3.green("Contacts:")} ${org._count.contacts}`);
|
|
553
|
+
}
|
|
554
|
+
console.log();
|
|
555
|
+
}
|
|
502
556
|
function outputDealJson(deal) {
|
|
503
557
|
console.log(JSON.stringify(transformDeal(deal), null, 2));
|
|
504
558
|
}
|
|
@@ -1417,7 +1471,7 @@ function createContactsCommand() {
|
|
|
1417
1471
|
handleError(error, useJson);
|
|
1418
1472
|
}
|
|
1419
1473
|
});
|
|
1420
|
-
contacts.command("create").description("Create a new contact").requiredOption("--workspace <id>", "Workspace ID").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--email <email>", "Email address").option("--phone <phone>", "Phone number").option("--linkedin <url>", "LinkedIn URL").option("--telegram <handle>", "Telegram handle").option("--twitter <handle>", "Twitter/X handle").option("--github <handle>", "GitHub username").option("--bluesky <handle>", "Bluesky handle").option("--about <text>", "About / bio").option("--profile-type <type>", "Profile type").option("--skills <skills>", "Skills (comma-separated)").option("--tags <tags>", "Tags (comma-separated)").option("--organization <id>", "Organization ID").action(async (options, cmd) => {
|
|
1474
|
+
contacts.command("create").description("Create a new contact").requiredOption("--workspace <id>", "Workspace ID").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--email <email>", "Email address").option("--phone <phone>", "Phone number").option("--linkedin <url>", "LinkedIn URL").option("--telegram <handle>", "Telegram handle").option("--twitter <handle>", "Twitter/X handle").option("--github <handle>", "GitHub username").option("--bluesky <handle>", "Bluesky handle").option("--about <text>", "About / bio").option("--profile-type <type>", "Profile type").option("--skills <skills>", "Skills (comma-separated)").option("--tags <tags>", "Tags (comma-separated)").option("--organization <id>", "Organization ID").option("--organization-name <name>", "Organization name (find-or-create; ignored if --organization is set)").action(async (options, cmd) => {
|
|
1421
1475
|
const globalOpts = cmd.optsWithGlobals();
|
|
1422
1476
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
1423
1477
|
try {
|
|
@@ -1437,7 +1491,8 @@ function createContactsCommand() {
|
|
|
1437
1491
|
profileType: options.profileType,
|
|
1438
1492
|
skills: options.skills?.split(",").map((s) => s.trim()),
|
|
1439
1493
|
tags: options.tags?.split(",").map((t) => t.trim()),
|
|
1440
|
-
organizationId: options.organization
|
|
1494
|
+
organizationId: options.organization,
|
|
1495
|
+
organizationName: options.organizationName
|
|
1441
1496
|
});
|
|
1442
1497
|
if (useJson) {
|
|
1443
1498
|
outputContactJson(contact);
|
|
@@ -1449,7 +1504,7 @@ function createContactsCommand() {
|
|
|
1449
1504
|
handleError(error, useJson);
|
|
1450
1505
|
}
|
|
1451
1506
|
});
|
|
1452
|
-
contacts.command("update").description("Update an existing contact").requiredOption("--id <id>", "Contact ID").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--email <email>", 'Email (use "null" to clear)').option("--phone <phone>", 'Phone (use "null" to clear)').option("--linkedin <url>", 'LinkedIn URL (use "null" to clear)').option("--telegram <handle>", 'Telegram handle (use "null" to clear)').option("--twitter <handle>", 'Twitter/X handle (use "null" to clear)').option("--github <handle>", 'GitHub username (use "null" to clear)').option("--bluesky <handle>", 'Bluesky handle (use "null" to clear)').option("--about <text>", "About / bio").option("--profile-type <type>", "Profile type").option("--skills <skills>", "Skills (comma-separated)").option("--tags <tags>", "Tags (comma-separated)").option("--organization <id>", 'Organization ID (use "null" to clear)').action(async (options, cmd) => {
|
|
1507
|
+
contacts.command("update").description("Update an existing contact").requiredOption("--id <id>", "Contact ID").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--email <email>", 'Email (use "null" to clear)').option("--phone <phone>", 'Phone (use "null" to clear)').option("--linkedin <url>", 'LinkedIn URL (use "null" to clear)').option("--telegram <handle>", 'Telegram handle (use "null" to clear)').option("--twitter <handle>", 'Twitter/X handle (use "null" to clear)').option("--github <handle>", 'GitHub username (use "null" to clear)').option("--bluesky <handle>", 'Bluesky handle (use "null" to clear)').option("--about <text>", "About / bio").option("--profile-type <type>", "Profile type").option("--skills <skills>", "Skills (comma-separated)").option("--tags <tags>", "Tags (comma-separated)").option("--organization <id>", 'Organization ID (use "null" to clear)').option("--organization-name <name>", "Organization name (find-or-create; ignored if --organization is set)").action(async (options, cmd) => {
|
|
1453
1508
|
const globalOpts = cmd.optsWithGlobals();
|
|
1454
1509
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
1455
1510
|
const nullable = (v) => v === "null" ? null : v;
|
|
@@ -1470,7 +1525,8 @@ function createContactsCommand() {
|
|
|
1470
1525
|
profileType: options.profileType,
|
|
1471
1526
|
skills: options.skills?.split(",").map((s) => s.trim()),
|
|
1472
1527
|
tags: options.tags?.split(",").map((t) => t.trim()),
|
|
1473
|
-
organizationId: nullable(options.organization)
|
|
1528
|
+
organizationId: nullable(options.organization),
|
|
1529
|
+
organizationName: options.organizationName
|
|
1474
1530
|
});
|
|
1475
1531
|
if (useJson) {
|
|
1476
1532
|
outputContactJson(contact);
|
|
@@ -2253,10 +2309,88 @@ function createLabelsCommand() {
|
|
|
2253
2309
|
return labels;
|
|
2254
2310
|
}
|
|
2255
2311
|
|
|
2256
|
-
// src/commands/
|
|
2312
|
+
// src/commands/organizations.ts
|
|
2257
2313
|
import { Command as Command9 } from "commander";
|
|
2314
|
+
var VALID_SIZES = [
|
|
2315
|
+
"1-10",
|
|
2316
|
+
"11-50",
|
|
2317
|
+
"51-200",
|
|
2318
|
+
"201-500",
|
|
2319
|
+
"501-1000",
|
|
2320
|
+
"1000+"
|
|
2321
|
+
];
|
|
2322
|
+
function createOrganizationsCommand() {
|
|
2323
|
+
const organizations = new Command9("organizations").alias("orgs").description("Manage CRM organizations");
|
|
2324
|
+
organizations.command("list").description("List organizations").requiredOption("--workspace <id>", "Workspace ID").option("--search <query>", "Search by name or description").option("--industry <industry>", "Filter by industry").option("--limit <n>", "Max results to return", parseInt).option("--cursor <cursor>", "Pagination cursor").action(async (options, cmd) => {
|
|
2325
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
2326
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
2327
|
+
try {
|
|
2328
|
+
const client = getClient();
|
|
2329
|
+
const result = await client.organizations.list({
|
|
2330
|
+
workspaceId: options.workspace,
|
|
2331
|
+
search: options.search,
|
|
2332
|
+
industry: options.industry,
|
|
2333
|
+
limit: options.limit,
|
|
2334
|
+
cursor: options.cursor
|
|
2335
|
+
});
|
|
2336
|
+
if (useJson) {
|
|
2337
|
+
outputOrganizationsJson(result.organizations, result.nextCursor);
|
|
2338
|
+
} else {
|
|
2339
|
+
outputOrganizationsPretty(result.organizations);
|
|
2340
|
+
}
|
|
2341
|
+
} catch (error) {
|
|
2342
|
+
handleError(error, useJson);
|
|
2343
|
+
}
|
|
2344
|
+
});
|
|
2345
|
+
organizations.command("get").description("Get an organization by ID").argument("<id>", "Organization ID").action(async (id, _options, cmd) => {
|
|
2346
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
2347
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
2348
|
+
try {
|
|
2349
|
+
const client = getClient();
|
|
2350
|
+
const org = await client.organizations.get(id);
|
|
2351
|
+
if (useJson) {
|
|
2352
|
+
outputOrganizationJson(org);
|
|
2353
|
+
} else {
|
|
2354
|
+
outputOrganizationPretty(org);
|
|
2355
|
+
}
|
|
2356
|
+
} catch (error) {
|
|
2357
|
+
handleError(error, useJson);
|
|
2358
|
+
}
|
|
2359
|
+
});
|
|
2360
|
+
organizations.command("create").description("Create a new organization").requiredOption("--workspace <id>", "Workspace ID").requiredOption("--name <name>", "Organization name").option("--website-url <url>", "Website URL").option("--logo-url <url>", "Logo URL").option("--description <text>", "Description").option("--industry <industry>", "Industry").option("--size <size>", `Company size (${VALID_SIZES.join(", ")})`).action(async (options, cmd) => {
|
|
2361
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
2362
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
2363
|
+
try {
|
|
2364
|
+
if (options.size && !VALID_SIZES.includes(options.size)) {
|
|
2365
|
+
throw new Error(`Invalid size "${options.size}". Valid: ${VALID_SIZES.join(", ")}`);
|
|
2366
|
+
}
|
|
2367
|
+
const client = getClient();
|
|
2368
|
+
const org = await client.organizations.create({
|
|
2369
|
+
workspaceId: options.workspace,
|
|
2370
|
+
name: options.name,
|
|
2371
|
+
websiteUrl: options.websiteUrl,
|
|
2372
|
+
logoUrl: options.logoUrl,
|
|
2373
|
+
description: options.description,
|
|
2374
|
+
industry: options.industry,
|
|
2375
|
+
size: options.size
|
|
2376
|
+
});
|
|
2377
|
+
if (useJson) {
|
|
2378
|
+
outputOrganizationJson(org);
|
|
2379
|
+
} else {
|
|
2380
|
+
console.log("\n\u2713 Organization created successfully");
|
|
2381
|
+
outputOrganizationPretty(org);
|
|
2382
|
+
}
|
|
2383
|
+
} catch (error) {
|
|
2384
|
+
handleError(error, useJson);
|
|
2385
|
+
}
|
|
2386
|
+
});
|
|
2387
|
+
return organizations;
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
// src/commands/products.ts
|
|
2391
|
+
import { Command as Command10 } from "commander";
|
|
2258
2392
|
function createProductsCommand() {
|
|
2259
|
-
const products = new
|
|
2393
|
+
const products = new Command10("products").description(
|
|
2260
2394
|
"Manage products. A workspace contains products; a product holds features and tickets."
|
|
2261
2395
|
);
|
|
2262
2396
|
products.command("list").description("List products in a workspace").option("--workspace <slug|id>", "Workspace slug or CUID (defaults to configured workspace)").action(async (options, cmd) => {
|
|
@@ -2319,9 +2453,9 @@ function createProductsCommand() {
|
|
|
2319
2453
|
}
|
|
2320
2454
|
|
|
2321
2455
|
// src/commands/projects.ts
|
|
2322
|
-
import { Command as
|
|
2456
|
+
import { Command as Command11 } from "commander";
|
|
2323
2457
|
function createProjectsCommand() {
|
|
2324
|
-
const projects = new
|
|
2458
|
+
const projects = new Command11("projects").description("Manage projects");
|
|
2325
2459
|
projects.command("list").description("List all projects").option("--workspace <id>", "Filter by workspace ID").option("--include-actions", "Include actions in output").action(async (options, cmd) => {
|
|
2326
2460
|
const globalOpts = cmd.optsWithGlobals();
|
|
2327
2461
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -2344,7 +2478,7 @@ function createProjectsCommand() {
|
|
|
2344
2478
|
}
|
|
2345
2479
|
|
|
2346
2480
|
// src/commands/tickets.ts
|
|
2347
|
-
import { Command as
|
|
2481
|
+
import { Command as Command12 } from "commander";
|
|
2348
2482
|
function collectRepeatable(value, previous) {
|
|
2349
2483
|
return [...previous, value];
|
|
2350
2484
|
}
|
|
@@ -2387,7 +2521,7 @@ function validateTicketType(value) {
|
|
|
2387
2521
|
return value;
|
|
2388
2522
|
}
|
|
2389
2523
|
function createTicketsCommand() {
|
|
2390
|
-
const tickets = new
|
|
2524
|
+
const tickets = new Command12("tickets").description(
|
|
2391
2525
|
"Manage product backlog tickets. Tickets live under a product, link to features/epics, depend on each other, and can be implemented via actions."
|
|
2392
2526
|
);
|
|
2393
2527
|
tickets.command("list").description(
|
|
@@ -2700,7 +2834,7 @@ function createTicketsCommand() {
|
|
|
2700
2834
|
handleError(error, useJson);
|
|
2701
2835
|
}
|
|
2702
2836
|
});
|
|
2703
|
-
const comment = new
|
|
2837
|
+
const comment = new Command12("comment").description("Manage comments on a ticket");
|
|
2704
2838
|
comment.command("add").description("Add a comment to a ticket").requiredOption("--id <id>", "Ticket CUID").requiredOption("-m, --message <text>", "Comment content (markdown supported)").action(async (options, cmd) => {
|
|
2705
2839
|
const globalOpts = cmd.optsWithGlobals();
|
|
2706
2840
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -2739,10 +2873,10 @@ function createTicketsCommand() {
|
|
|
2739
2873
|
}
|
|
2740
2874
|
|
|
2741
2875
|
// src/commands/workspaces.ts
|
|
2742
|
-
import { Command as
|
|
2876
|
+
import { Command as Command13 } from "commander";
|
|
2743
2877
|
import chalk5 from "chalk";
|
|
2744
2878
|
function createWorkspacesCommand() {
|
|
2745
|
-
const workspaces = new
|
|
2879
|
+
const workspaces = new Command13("workspaces").description("Manage workspaces");
|
|
2746
2880
|
workspaces.command("list").description("List all workspaces").action(async (_options, cmd) => {
|
|
2747
2881
|
const globalOpts = cmd.optsWithGlobals();
|
|
2748
2882
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -2788,7 +2922,7 @@ function createWorkspacesCommand() {
|
|
|
2788
2922
|
}
|
|
2789
2923
|
|
|
2790
2924
|
// src/index.ts
|
|
2791
|
-
var program = new
|
|
2925
|
+
var program = new Command14();
|
|
2792
2926
|
program.name("exponential").description(
|
|
2793
2927
|
[
|
|
2794
2928
|
"CLI to interact with Exponential productivity app.",
|
|
@@ -2805,6 +2939,7 @@ program.addCommand(createDealsCommand());
|
|
|
2805
2939
|
program.addCommand(createEpicsCommand());
|
|
2806
2940
|
program.addCommand(createFeaturesCommand());
|
|
2807
2941
|
program.addCommand(createLabelsCommand());
|
|
2942
|
+
program.addCommand(createOrganizationsCommand());
|
|
2808
2943
|
program.addCommand(createProductsCommand());
|
|
2809
2944
|
program.addCommand(createProjectsCommand());
|
|
2810
2945
|
program.addCommand(createTicketsCommand());
|