@thecorporation/cli 26.3.9 → 26.3.11
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 +15 -2
- package/dist/index.js +216 -50
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -15,12 +15,25 @@ npm install -g @thecorporation/cli
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
corp setup #
|
|
18
|
+
corp setup # authenticate via magic link
|
|
19
19
|
corp status # workspace summary
|
|
20
20
|
corp chat # AI assistant with full tool access
|
|
21
21
|
corp form --type llc --name "Acme" # form a new entity
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
## Authentication
|
|
25
|
+
|
|
26
|
+
`corp setup` authenticates via magic link:
|
|
27
|
+
|
|
28
|
+
1. Enter your name and email
|
|
29
|
+
2. Check your email for a sign-in link from TheCorporation
|
|
30
|
+
3. Copy the code from the link URL and paste it into the terminal
|
|
31
|
+
4. Credentials are saved to `~/.corp/config.json`
|
|
32
|
+
|
|
33
|
+
Your workspace is shared across the CLI, [MCP server](https://www.npmjs.com/package/@thecorporation/mcp-server), and [chat](https://humans.thecorporation.ai/chat) — all keyed on your email.
|
|
34
|
+
|
|
35
|
+
For self-hosted setups (`CORP_API_URL` pointing to your own server), `corp setup` provisions a workspace directly without requiring a magic link.
|
|
36
|
+
|
|
24
37
|
## Commands
|
|
25
38
|
|
|
26
39
|
### Core
|
|
@@ -204,7 +217,7 @@ Inside `corp chat`, these slash commands are available:
|
|
|
204
217
|
|
|
205
218
|
## Configuration
|
|
206
219
|
|
|
207
|
-
Config is stored at `~/.corp/config.json`.
|
|
220
|
+
Config is stored at `~/.corp/config.json`. `corp setup` populates it via magic link auth. You can also set values manually:
|
|
208
221
|
|
|
209
222
|
```bash
|
|
210
223
|
corp config set api_url https://api.thecorporation.ai
|
package/dist/index.js
CHANGED
|
@@ -430,12 +430,14 @@ function printBillingPanel(status, plans) {
|
|
|
430
430
|
const plan = s(status.plan ?? status.tier) || "free";
|
|
431
431
|
const subStatus = s(status.status) || "active";
|
|
432
432
|
const periodEnd = s(status.current_period_end);
|
|
433
|
+
const explanation = s(status.status_explanation);
|
|
433
434
|
console.log(chalk.green("\u2500".repeat(50)));
|
|
434
435
|
console.log(chalk.green.bold(" Billing Status"));
|
|
435
436
|
console.log(chalk.green("\u2500".repeat(50)));
|
|
436
437
|
console.log(` ${chalk.bold("Plan:")} ${plan}`);
|
|
437
438
|
console.log(` ${chalk.bold("Status:")} ${subStatus}`);
|
|
438
439
|
if (periodEnd) console.log(` ${chalk.bold("Current Period End:")} ${periodEnd}`);
|
|
440
|
+
if (explanation) console.log(` ${chalk.bold("Explanation:")} ${explanation}`);
|
|
439
441
|
console.log(chalk.dim(" Manage: corp billing portal"));
|
|
440
442
|
console.log(chalk.dim(" Upgrade: corp billing upgrade --plan <plan>"));
|
|
441
443
|
console.log(chalk.green("\u2500".repeat(50)));
|
|
@@ -477,25 +479,112 @@ __export(setup_exports, {
|
|
|
477
479
|
setupCommand: () => setupCommand
|
|
478
480
|
});
|
|
479
481
|
import { input, confirm } from "@inquirer/prompts";
|
|
482
|
+
async function requestMagicLink(apiUrl, email, tosAccepted) {
|
|
483
|
+
const resp = await fetch(`${apiUrl}/v1/auth/magic-link`, {
|
|
484
|
+
method: "POST",
|
|
485
|
+
headers: { "Content-Type": "application/json" },
|
|
486
|
+
body: JSON.stringify({ email, tos_accepted: tosAccepted })
|
|
487
|
+
});
|
|
488
|
+
if (!resp.ok) {
|
|
489
|
+
const data = await resp.json().catch(() => ({}));
|
|
490
|
+
const detail = data?.error ?? data?.message ?? resp.statusText;
|
|
491
|
+
throw new Error(
|
|
492
|
+
typeof detail === "string" ? detail : JSON.stringify(detail)
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
async function verifyMagicLinkCode(apiUrl, code) {
|
|
497
|
+
const resp = await fetch(`${apiUrl}/v1/auth/magic-link/verify`, {
|
|
498
|
+
method: "POST",
|
|
499
|
+
headers: { "Content-Type": "application/json" },
|
|
500
|
+
body: JSON.stringify({ code, client: "cli" })
|
|
501
|
+
});
|
|
502
|
+
const data = await resp.json().catch(() => ({}));
|
|
503
|
+
if (!resp.ok) {
|
|
504
|
+
const detail = data?.error ?? data?.message ?? resp.statusText;
|
|
505
|
+
throw new Error(
|
|
506
|
+
typeof detail === "string" ? detail : JSON.stringify(detail)
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (!data.api_key || !data.workspace_id) {
|
|
510
|
+
throw new Error("Unexpected response \u2014 missing api_key or workspace_id");
|
|
511
|
+
}
|
|
512
|
+
return {
|
|
513
|
+
api_key: data.api_key,
|
|
514
|
+
workspace_id: data.workspace_id
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function isCloudApi(url) {
|
|
518
|
+
return url.replace(/\/+$/, "").includes("thecorporation.ai");
|
|
519
|
+
}
|
|
520
|
+
async function magicLinkAuth(apiUrl, email) {
|
|
521
|
+
console.log("\nSending magic link to " + email + "...");
|
|
522
|
+
await requestMagicLink(apiUrl, email, true);
|
|
523
|
+
console.log("Check your email for a sign-in link from TheCorporation.");
|
|
524
|
+
console.log(
|
|
525
|
+
"Copy the code from the URL (the ?code=... part) and paste it below.\n"
|
|
526
|
+
);
|
|
527
|
+
const code = await input({ message: "Paste your magic link code" });
|
|
528
|
+
const trimmed = code.trim().replace(/^.*[?&]code=/, "");
|
|
529
|
+
if (!trimmed) {
|
|
530
|
+
throw new Error("No code provided");
|
|
531
|
+
}
|
|
532
|
+
console.log("Verifying...");
|
|
533
|
+
return verifyMagicLinkCode(apiUrl, trimmed);
|
|
534
|
+
}
|
|
480
535
|
async function setupCommand() {
|
|
481
536
|
const cfg = loadConfig();
|
|
482
537
|
console.log("Welcome to corp \u2014 corporate governance from the terminal.\n");
|
|
483
|
-
|
|
538
|
+
const customUrl = process.env.CORP_API_URL;
|
|
539
|
+
if (customUrl) {
|
|
540
|
+
cfg.api_url = customUrl.replace(/\/+$/, "");
|
|
541
|
+
console.log(`Using API: ${cfg.api_url}
|
|
542
|
+
`);
|
|
543
|
+
} else {
|
|
544
|
+
cfg.api_url = CLOUD_API_URL;
|
|
545
|
+
}
|
|
484
546
|
console.log("--- User Info ---");
|
|
485
547
|
const user = cfg.user ?? { name: "", email: "" };
|
|
486
|
-
user.name = await input({
|
|
487
|
-
|
|
548
|
+
user.name = await input({
|
|
549
|
+
message: "Your name",
|
|
550
|
+
default: user.name || void 0
|
|
551
|
+
});
|
|
552
|
+
user.email = await input({
|
|
553
|
+
message: "Your email",
|
|
554
|
+
default: user.email || void 0
|
|
555
|
+
});
|
|
488
556
|
cfg.user = user;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
557
|
+
const needsAuth = !cfg.api_key || !cfg.workspace_id;
|
|
558
|
+
const cloud = isCloudApi(cfg.api_url);
|
|
559
|
+
if (needsAuth) {
|
|
560
|
+
if (cloud) {
|
|
561
|
+
try {
|
|
562
|
+
const result = await magicLinkAuth(cfg.api_url, user.email);
|
|
563
|
+
cfg.api_key = result.api_key;
|
|
564
|
+
cfg.workspace_id = result.workspace_id;
|
|
565
|
+
printSuccess(`Authenticated. Workspace: ${result.workspace_id}`);
|
|
566
|
+
} catch (err) {
|
|
567
|
+
printError(`Authentication failed: ${err}`);
|
|
568
|
+
console.log(
|
|
569
|
+
"You can manually set credentials with: corp config set api_key <key>"
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
} else {
|
|
573
|
+
console.log("\nProvisioning workspace...");
|
|
574
|
+
try {
|
|
575
|
+
const result = await provisionWorkspace(
|
|
576
|
+
cfg.api_url,
|
|
577
|
+
`${user.name}'s workspace`
|
|
578
|
+
);
|
|
579
|
+
cfg.api_key = result.api_key;
|
|
580
|
+
cfg.workspace_id = result.workspace_id;
|
|
581
|
+
console.log(`Workspace provisioned: ${result.workspace_id}`);
|
|
582
|
+
} catch (err) {
|
|
583
|
+
printError(`Auto-provision failed: ${err}`);
|
|
584
|
+
console.log(
|
|
585
|
+
"You can manually set credentials with: corp config set api_key <key>"
|
|
586
|
+
);
|
|
587
|
+
}
|
|
499
588
|
}
|
|
500
589
|
} else {
|
|
501
590
|
console.log("\nVerifying existing credentials...");
|
|
@@ -512,21 +601,33 @@ async function setupCommand() {
|
|
|
512
601
|
console.log("Credentials OK.");
|
|
513
602
|
} else {
|
|
514
603
|
console.log("API key is no longer valid.");
|
|
515
|
-
const
|
|
516
|
-
message: "Provision a new workspace? (This will replace your current credentials)",
|
|
517
|
-
default:
|
|
604
|
+
const reauth = await confirm({
|
|
605
|
+
message: cloud ? "Re-authenticate via magic link?" : "Provision a new workspace? (This will replace your current credentials)",
|
|
606
|
+
default: true
|
|
518
607
|
});
|
|
519
|
-
if (
|
|
608
|
+
if (reauth) {
|
|
520
609
|
try {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
610
|
+
if (cloud) {
|
|
611
|
+
const result = await magicLinkAuth(cfg.api_url, user.email);
|
|
612
|
+
cfg.api_key = result.api_key;
|
|
613
|
+
cfg.workspace_id = result.workspace_id;
|
|
614
|
+
printSuccess(`Authenticated. Workspace: ${result.workspace_id}`);
|
|
615
|
+
} else {
|
|
616
|
+
const result = await provisionWorkspace(
|
|
617
|
+
cfg.api_url,
|
|
618
|
+
`${user.name}'s workspace`
|
|
619
|
+
);
|
|
620
|
+
cfg.api_key = result.api_key;
|
|
621
|
+
cfg.workspace_id = result.workspace_id;
|
|
622
|
+
console.log(`Workspace provisioned: ${result.workspace_id}`);
|
|
623
|
+
}
|
|
525
624
|
} catch (err) {
|
|
526
|
-
printError(`
|
|
625
|
+
printError(`Authentication failed: ${err}`);
|
|
527
626
|
}
|
|
528
627
|
} else {
|
|
529
|
-
console.log(
|
|
628
|
+
console.log(
|
|
629
|
+
"Keeping existing credentials. You can manually update with: corp config set api_key <key>"
|
|
630
|
+
);
|
|
530
631
|
}
|
|
531
632
|
}
|
|
532
633
|
}
|
|
@@ -534,14 +635,14 @@ async function setupCommand() {
|
|
|
534
635
|
console.log("\nConfig saved to ~/.corp/config.json");
|
|
535
636
|
console.log("Run 'corp status' to verify your connection.");
|
|
536
637
|
}
|
|
537
|
-
var
|
|
638
|
+
var CLOUD_API_URL;
|
|
538
639
|
var init_setup = __esm({
|
|
539
640
|
"src/commands/setup.ts"() {
|
|
540
641
|
"use strict";
|
|
541
642
|
init_config();
|
|
542
643
|
init_api_client();
|
|
543
644
|
init_output();
|
|
544
|
-
|
|
645
|
+
CLOUD_API_URL = "https://api.thecorporation.ai";
|
|
545
646
|
}
|
|
546
647
|
});
|
|
547
648
|
|
|
@@ -816,7 +917,14 @@ async function digestCommand(opts) {
|
|
|
816
917
|
try {
|
|
817
918
|
if (opts.trigger) {
|
|
818
919
|
const result = await client.triggerDigest();
|
|
819
|
-
|
|
920
|
+
const message = (() => {
|
|
921
|
+
const value = result.message;
|
|
922
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
923
|
+
})();
|
|
924
|
+
printSuccess(result.digest_count > 0 ? "Digest triggered." : "Digest trigger accepted.");
|
|
925
|
+
if (message) {
|
|
926
|
+
printWarning(message);
|
|
927
|
+
}
|
|
820
928
|
printJson(result);
|
|
821
929
|
} else if (opts.key) {
|
|
822
930
|
const result = await client.getDigest(opts.key);
|
|
@@ -1246,12 +1354,24 @@ __export(entities_exports, {
|
|
|
1246
1354
|
entitiesShowCommand: () => entitiesShowCommand
|
|
1247
1355
|
});
|
|
1248
1356
|
import chalk3 from "chalk";
|
|
1357
|
+
function wantsJsonOutput(opts) {
|
|
1358
|
+
if (opts && typeof opts === "object") {
|
|
1359
|
+
const json = opts.json;
|
|
1360
|
+
if (typeof json === "boolean") return json;
|
|
1361
|
+
const commandOpts = opts.opts;
|
|
1362
|
+
if (typeof commandOpts === "function") {
|
|
1363
|
+
return Boolean(commandOpts().json);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
return false;
|
|
1367
|
+
}
|
|
1249
1368
|
async function entitiesCommand(opts) {
|
|
1250
1369
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1251
1370
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1371
|
+
const jsonOutput = wantsJsonOutput(opts);
|
|
1252
1372
|
try {
|
|
1253
|
-
const entities = await withSpinner("Loading", () => client.listEntities(),
|
|
1254
|
-
if (
|
|
1373
|
+
const entities = await withSpinner("Loading", () => client.listEntities(), jsonOutput);
|
|
1374
|
+
if (jsonOutput) {
|
|
1255
1375
|
printJson(entities);
|
|
1256
1376
|
} else if (entities.length === 0) {
|
|
1257
1377
|
console.log("No entities found.");
|
|
@@ -1266,6 +1386,7 @@ async function entitiesCommand(opts) {
|
|
|
1266
1386
|
async function entitiesShowCommand(entityId, opts) {
|
|
1267
1387
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1268
1388
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1389
|
+
const jsonOutput = wantsJsonOutput(opts);
|
|
1269
1390
|
try {
|
|
1270
1391
|
const entities = await client.listEntities();
|
|
1271
1392
|
const entity = entities.find((e) => e.entity_id === entityId);
|
|
@@ -1273,7 +1394,7 @@ async function entitiesShowCommand(entityId, opts) {
|
|
|
1273
1394
|
printError(`Entity not found: ${entityId}`);
|
|
1274
1395
|
process.exit(1);
|
|
1275
1396
|
}
|
|
1276
|
-
if (
|
|
1397
|
+
if (jsonOutput) {
|
|
1277
1398
|
printJson(entity);
|
|
1278
1399
|
} else {
|
|
1279
1400
|
console.log(chalk3.blue("\u2500".repeat(40)));
|
|
@@ -1407,11 +1528,9 @@ async function contactsAddCommand(opts) {
|
|
|
1407
1528
|
category: opts.category ?? "employee"
|
|
1408
1529
|
};
|
|
1409
1530
|
if (opts.phone) data.phone = opts.phone;
|
|
1531
|
+
if (opts.notes) data.notes = opts.notes;
|
|
1410
1532
|
const result = await client.createContact(data);
|
|
1411
1533
|
printSuccess(`Contact created: ${result.contact_id ?? result.id ?? "OK"}`);
|
|
1412
|
-
if (opts.notes) {
|
|
1413
|
-
console.log(chalk4.dim(' Tip: To add notes, use: corp contacts edit <contact-id> --notes "..."'));
|
|
1414
|
-
}
|
|
1415
1534
|
} catch (err) {
|
|
1416
1535
|
printError(`Failed to create contact: ${err}`);
|
|
1417
1536
|
process.exit(1);
|
|
@@ -2272,12 +2391,9 @@ async function documentsSigningLinkCommand(docId, opts) {
|
|
|
2272
2391
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2273
2392
|
try {
|
|
2274
2393
|
const result = await client.getSigningLink(docId, eid);
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
console.log(` Share this URL with the signer:`);
|
|
2279
|
-
console.log(` https://humans.thecorporation.ai/sign/${docId}?token=${result.token}`);
|
|
2280
|
-
}
|
|
2394
|
+
const shareUrl = result.token ? `https://humans.thecorporation.ai/sign/${docId}?token=${result.token}` : result.signing_url ?? `https://humans.thecorporation.ai/sign/${docId}`;
|
|
2395
|
+
printSuccess("Signing link generated.");
|
|
2396
|
+
console.log(shareUrl);
|
|
2281
2397
|
} catch (err) {
|
|
2282
2398
|
printError(`Failed to get signing link: ${err}`);
|
|
2283
2399
|
process.exit(1);
|
|
@@ -2677,12 +2793,25 @@ function makeClient() {
|
|
|
2677
2793
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2678
2794
|
return new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2679
2795
|
}
|
|
2796
|
+
function enrichBillingStatus(status) {
|
|
2797
|
+
if (typeof status.status_explanation === "string" && status.status_explanation.trim()) {
|
|
2798
|
+
return status;
|
|
2799
|
+
}
|
|
2800
|
+
const plan = String(status.plan ?? status.tier ?? "").trim();
|
|
2801
|
+
const subStatus = String(status.status ?? "").trim();
|
|
2802
|
+
if (subStatus !== "pending_checkout") {
|
|
2803
|
+
return status;
|
|
2804
|
+
}
|
|
2805
|
+
const statusExplanation = plan ? `Checkout for the ${plan} plan has started, but billing will not become active until Stripe checkout is completed.` : "Checkout has started, but billing will not become active until Stripe checkout is completed.";
|
|
2806
|
+
return { ...status, status_explanation: statusExplanation };
|
|
2807
|
+
}
|
|
2680
2808
|
async function billingCommand(opts) {
|
|
2681
2809
|
const client = makeClient();
|
|
2682
2810
|
try {
|
|
2683
2811
|
const [status, plans] = await Promise.all([client.getBillingStatus(), client.getBillingPlans()]);
|
|
2684
|
-
|
|
2685
|
-
|
|
2812
|
+
const enrichedStatus = enrichBillingStatus(status);
|
|
2813
|
+
if (opts.json) printJson({ status: enrichedStatus, plans });
|
|
2814
|
+
else printBillingPanel(enrichedStatus, plans);
|
|
2686
2815
|
} catch (err) {
|
|
2687
2816
|
printError(`Failed to fetch billing info: ${err}`);
|
|
2688
2817
|
process.exit(1);
|
|
@@ -3017,6 +3146,14 @@ async function formCommand(opts) {
|
|
|
3017
3146
|
process.exit(1);
|
|
3018
3147
|
}
|
|
3019
3148
|
}
|
|
3149
|
+
function parseCsvAddress(raw) {
|
|
3150
|
+
if (!raw) return void 0;
|
|
3151
|
+
const parts = raw.split(",").map((p) => p.trim()).filter(Boolean);
|
|
3152
|
+
if (parts.length !== 4) {
|
|
3153
|
+
throw new Error(`Invalid address format: ${raw}. Expected 'street,city,state,zip'`);
|
|
3154
|
+
}
|
|
3155
|
+
return { street: parts[0], city: parts[1], state: parts[2], zip: parts[3] };
|
|
3156
|
+
}
|
|
3020
3157
|
async function formCreateCommand(opts) {
|
|
3021
3158
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
3022
3159
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
@@ -3027,6 +3164,15 @@ async function formCreateCommand(opts) {
|
|
|
3027
3164
|
legal_name: opts.name
|
|
3028
3165
|
};
|
|
3029
3166
|
if (opts.jurisdiction) payload.jurisdiction = opts.jurisdiction;
|
|
3167
|
+
if (opts.registeredAgentName) payload.registered_agent_name = opts.registeredAgentName;
|
|
3168
|
+
if (opts.registeredAgentAddress) payload.registered_agent_address = opts.registeredAgentAddress;
|
|
3169
|
+
if (opts.formationDate) payload.formation_date = opts.formationDate;
|
|
3170
|
+
if (opts.fiscalYearEnd) payload.fiscal_year_end = opts.fiscalYearEnd;
|
|
3171
|
+
if (opts.sCorp !== void 0) payload.s_corp_election = opts.sCorp;
|
|
3172
|
+
if (opts.transferRestrictions !== void 0) payload.transfer_restrictions = opts.transferRestrictions;
|
|
3173
|
+
if (opts.rofr !== void 0) payload.right_of_first_refusal = opts.rofr;
|
|
3174
|
+
const companyAddress = parseCsvAddress(opts.companyAddress);
|
|
3175
|
+
if (companyAddress) payload.company_address = companyAddress;
|
|
3030
3176
|
const result = await client.createPendingEntity(payload);
|
|
3031
3177
|
printSuccess(`Pending entity created: ${result.entity_id}`);
|
|
3032
3178
|
console.log(` Name: ${result.legal_name}`);
|
|
@@ -3052,6 +3198,8 @@ async function formAddFounderCommand(entityId, opts) {
|
|
|
3052
3198
|
};
|
|
3053
3199
|
if (opts.officerTitle) payload.officer_title = opts.officerTitle.toLowerCase();
|
|
3054
3200
|
if (opts.incorporator) payload.is_incorporator = true;
|
|
3201
|
+
const address = parseCsvAddress(opts.address);
|
|
3202
|
+
if (address) payload.address = address;
|
|
3055
3203
|
const result = await client.addFounder(entityId, payload);
|
|
3056
3204
|
printSuccess(`Founder added (${result.member_count} total)`);
|
|
3057
3205
|
const members = result.members ?? [];
|
|
@@ -3066,11 +3214,29 @@ async function formAddFounderCommand(entityId, opts) {
|
|
|
3066
3214
|
process.exit(1);
|
|
3067
3215
|
}
|
|
3068
3216
|
}
|
|
3069
|
-
async function formFinalizeCommand(entityId) {
|
|
3217
|
+
async function formFinalizeCommand(entityId, opts) {
|
|
3070
3218
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
3071
3219
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
3072
3220
|
try {
|
|
3073
|
-
const
|
|
3221
|
+
const payload = {};
|
|
3222
|
+
if (opts.authorizedShares) {
|
|
3223
|
+
const authorizedShares = parseInt(opts.authorizedShares, 10);
|
|
3224
|
+
if (!Number.isFinite(authorizedShares)) {
|
|
3225
|
+
throw new Error(`Invalid authorized shares: ${opts.authorizedShares}`);
|
|
3226
|
+
}
|
|
3227
|
+
payload.authorized_shares = authorizedShares;
|
|
3228
|
+
}
|
|
3229
|
+
if (opts.parValue) payload.par_value = opts.parValue;
|
|
3230
|
+
if (opts.registeredAgentName) payload.registered_agent_name = opts.registeredAgentName;
|
|
3231
|
+
if (opts.registeredAgentAddress) payload.registered_agent_address = opts.registeredAgentAddress;
|
|
3232
|
+
if (opts.formationDate) payload.formation_date = opts.formationDate;
|
|
3233
|
+
if (opts.fiscalYearEnd) payload.fiscal_year_end = opts.fiscalYearEnd;
|
|
3234
|
+
if (opts.sCorp !== void 0) payload.s_corp_election = opts.sCorp;
|
|
3235
|
+
if (opts.transferRestrictions !== void 0) payload.transfer_restrictions = opts.transferRestrictions;
|
|
3236
|
+
if (opts.rofr !== void 0) payload.right_of_first_refusal = opts.rofr;
|
|
3237
|
+
const companyAddress = parseCsvAddress(opts.companyAddress);
|
|
3238
|
+
if (companyAddress) payload.company_address = companyAddress;
|
|
3239
|
+
const result = await client.finalizeFormation(entityId, payload);
|
|
3074
3240
|
printSuccess(`Formation finalized: ${result.entity_id}`);
|
|
3075
3241
|
if (result.legal_entity_id) console.log(` Legal Entity ID: ${result.legal_entity_id}`);
|
|
3076
3242
|
if (result.instrument_id) console.log(` Instrument ID: ${result.instrument_id}`);
|
|
@@ -3372,9 +3538,9 @@ var entitiesCmd = program.command("entities").description("List entities, show d
|
|
|
3372
3538
|
const { entitiesCommand: entitiesCommand2 } = await Promise.resolve().then(() => (init_entities(), entities_exports));
|
|
3373
3539
|
await entitiesCommand2(opts);
|
|
3374
3540
|
});
|
|
3375
|
-
entitiesCmd.command("show <entity-id>").option("--json", "Output as JSON").description("Show entity detail").action(async (entityId, opts) => {
|
|
3541
|
+
entitiesCmd.command("show <entity-id>").option("--json", "Output as JSON").description("Show entity detail").action(async (entityId, opts, cmd) => {
|
|
3376
3542
|
const { entitiesShowCommand: entitiesShowCommand2 } = await Promise.resolve().then(() => (init_entities(), entities_exports));
|
|
3377
|
-
await entitiesShowCommand2(entityId, opts);
|
|
3543
|
+
await entitiesShowCommand2(entityId, { ...cmd.opts(), ...opts });
|
|
3378
3544
|
});
|
|
3379
3545
|
entitiesCmd.command("convert <entity-id>").requiredOption("--to <type>", "Target entity type (llc, c_corp)").option("--jurisdiction <jurisdiction>", "New jurisdiction").description("Convert entity to a different type").action(async (entityId, opts) => {
|
|
3380
3546
|
const { entitiesConvertCommand: entitiesConvertCommand2 } = await Promise.resolve().then(() => (init_entities(), entities_exports));
|
|
@@ -3585,10 +3751,10 @@ var documentsCmd = program.command("documents").description("Documents and signi
|
|
|
3585
3751
|
const { documentsListCommand: documentsListCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
3586
3752
|
await documentsListCommand2(opts);
|
|
3587
3753
|
});
|
|
3588
|
-
documentsCmd.command("signing-link <doc-id>").description("Get a signing link for a document").action(async (docId,
|
|
3754
|
+
documentsCmd.command("signing-link <doc-id>").option("--entity-id <id>", "Entity ID (overrides active entity and parent command)").description("Get a signing link for a document").action(async (docId, opts, cmd) => {
|
|
3589
3755
|
const parent = cmd.parent.opts();
|
|
3590
3756
|
const { documentsSigningLinkCommand: documentsSigningLinkCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
3591
|
-
await documentsSigningLinkCommand2(docId, { entityId: parent.entityId });
|
|
3757
|
+
await documentsSigningLinkCommand2(docId, { entityId: opts.entityId ?? parent.entityId });
|
|
3592
3758
|
});
|
|
3593
3759
|
documentsCmd.command("generate").requiredOption("--template <type>", "Template type (consulting_agreement, employment_offer, contractor_agreement, nda, custom)").requiredOption("--counterparty <name>", "Counterparty name").option("--effective-date <date>", "Effective date (ISO 8601, defaults to today)").description("Generate a contract from a template").action(async (opts, cmd) => {
|
|
3594
3760
|
const parent = cmd.parent.opts();
|
|
@@ -3701,17 +3867,17 @@ var formCmd = program.command("form").description("Form a new entity with founde
|
|
|
3701
3867
|
const { formCommand: formCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3702
3868
|
await formCommand2(opts);
|
|
3703
3869
|
});
|
|
3704
|
-
formCmd.command("create").description("Create a pending entity (staged flow step 1)").requiredOption("--type <type>", "Entity type (llc, c_corp)").requiredOption("--name <name>", "Legal name").option("--jurisdiction <jurisdiction>", "Jurisdiction (e.g. US-DE, US-WY)").action(async (opts) => {
|
|
3870
|
+
formCmd.command("create").description("Create a pending entity (staged flow step 1)").requiredOption("--type <type>", "Entity type (llc, c_corp)").requiredOption("--name <name>", "Legal name").option("--jurisdiction <jurisdiction>", "Jurisdiction (e.g. US-DE, US-WY)").option("--registered-agent-name <name>", "Registered agent legal name").option("--registered-agent-address <address>", "Registered agent address line").option("--formation-date <date>", "Formation date (RFC3339 or YYYY-MM-DD)").option("--fiscal-year-end <date>", "Fiscal year end (MM-DD)").option("--s-corp", "Elect S-Corp status").option("--transfer-restrictions", "Enable transfer restrictions").option("--rofr", "Enable right of first refusal").option("--company-address <address>", "Company address as 'street,city,state,zip'").action(async (opts) => {
|
|
3705
3871
|
const { formCreateCommand: formCreateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3706
3872
|
await formCreateCommand2(opts);
|
|
3707
3873
|
});
|
|
3708
|
-
formCmd.command("add-founder <entity-id>").description("Add a founder to a pending entity (staged flow step 2)").requiredOption("--name <name>", "Founder name").requiredOption("--email <email>", "Founder email").requiredOption("--role <role>", "Role: director|officer|manager|member|chair").requiredOption("--pct <pct>", "Ownership percentage").option("--officer-title <title>", "Officer title (corporations only)").option("--incorporator", "Mark as sole incorporator (corporations only)").action(async (entityId, opts) => {
|
|
3874
|
+
formCmd.command("add-founder <entity-id>").description("Add a founder to a pending entity (staged flow step 2)").requiredOption("--name <name>", "Founder name").requiredOption("--email <email>", "Founder email").requiredOption("--role <role>", "Role: director|officer|manager|member|chair").requiredOption("--pct <pct>", "Ownership percentage").option("--officer-title <title>", "Officer title (corporations only)").option("--incorporator", "Mark as sole incorporator (corporations only)").option("--address <address>", "Founder address as 'street,city,state,zip'").action(async (entityId, opts) => {
|
|
3709
3875
|
const { formAddFounderCommand: formAddFounderCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3710
3876
|
await formAddFounderCommand2(entityId, opts);
|
|
3711
3877
|
});
|
|
3712
|
-
formCmd.command("finalize <entity-id>").description("Finalize formation and generate documents + cap table (staged flow step 3)").action(async (entityId) => {
|
|
3878
|
+
formCmd.command("finalize <entity-id>").description("Finalize formation and generate documents + cap table (staged flow step 3)").option("--authorized-shares <count>", "Authorized shares for corporations").option("--par-value <value>", "Par value per share, e.g. 0.0001").option("--registered-agent-name <name>", "Registered agent legal name").option("--registered-agent-address <address>", "Registered agent address line").option("--formation-date <date>", "Formation date (RFC3339 or YYYY-MM-DD)").option("--fiscal-year-end <date>", "Fiscal year end (MM-DD)").option("--s-corp", "Elect S-Corp status").option("--transfer-restrictions", "Enable transfer restrictions").option("--rofr", "Enable right of first refusal").option("--company-address <address>", "Company address as 'street,city,state,zip'").action(async (entityId, opts) => {
|
|
3713
3879
|
const { formFinalizeCommand: formFinalizeCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3714
|
-
await formFinalizeCommand2(entityId);
|
|
3880
|
+
await formFinalizeCommand2(entityId, opts);
|
|
3715
3881
|
});
|
|
3716
3882
|
program.command("api-keys").description("List API keys").option("--json", "Output as JSON").action(async (opts) => {
|
|
3717
3883
|
const { apiKeysCommand: apiKeysCommand2 } = await Promise.resolve().then(() => (init_api_keys(), api_keys_exports));
|