@thecorporation/cli 26.3.9 → 26.3.10
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 +92 -25
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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)));
|
|
@@ -816,7 +818,14 @@ async function digestCommand(opts) {
|
|
|
816
818
|
try {
|
|
817
819
|
if (opts.trigger) {
|
|
818
820
|
const result = await client.triggerDigest();
|
|
819
|
-
|
|
821
|
+
const message = (() => {
|
|
822
|
+
const value = result.message;
|
|
823
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
824
|
+
})();
|
|
825
|
+
printSuccess(result.digest_count > 0 ? "Digest triggered." : "Digest trigger accepted.");
|
|
826
|
+
if (message) {
|
|
827
|
+
printWarning(message);
|
|
828
|
+
}
|
|
820
829
|
printJson(result);
|
|
821
830
|
} else if (opts.key) {
|
|
822
831
|
const result = await client.getDigest(opts.key);
|
|
@@ -1246,12 +1255,24 @@ __export(entities_exports, {
|
|
|
1246
1255
|
entitiesShowCommand: () => entitiesShowCommand
|
|
1247
1256
|
});
|
|
1248
1257
|
import chalk3 from "chalk";
|
|
1258
|
+
function wantsJsonOutput(opts) {
|
|
1259
|
+
if (opts && typeof opts === "object") {
|
|
1260
|
+
const json = opts.json;
|
|
1261
|
+
if (typeof json === "boolean") return json;
|
|
1262
|
+
const commandOpts = opts.opts;
|
|
1263
|
+
if (typeof commandOpts === "function") {
|
|
1264
|
+
return Boolean(commandOpts().json);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
return false;
|
|
1268
|
+
}
|
|
1249
1269
|
async function entitiesCommand(opts) {
|
|
1250
1270
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1251
1271
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1272
|
+
const jsonOutput = wantsJsonOutput(opts);
|
|
1252
1273
|
try {
|
|
1253
|
-
const entities = await withSpinner("Loading", () => client.listEntities(),
|
|
1254
|
-
if (
|
|
1274
|
+
const entities = await withSpinner("Loading", () => client.listEntities(), jsonOutput);
|
|
1275
|
+
if (jsonOutput) {
|
|
1255
1276
|
printJson(entities);
|
|
1256
1277
|
} else if (entities.length === 0) {
|
|
1257
1278
|
console.log("No entities found.");
|
|
@@ -1266,6 +1287,7 @@ async function entitiesCommand(opts) {
|
|
|
1266
1287
|
async function entitiesShowCommand(entityId, opts) {
|
|
1267
1288
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1268
1289
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1290
|
+
const jsonOutput = wantsJsonOutput(opts);
|
|
1269
1291
|
try {
|
|
1270
1292
|
const entities = await client.listEntities();
|
|
1271
1293
|
const entity = entities.find((e) => e.entity_id === entityId);
|
|
@@ -1273,7 +1295,7 @@ async function entitiesShowCommand(entityId, opts) {
|
|
|
1273
1295
|
printError(`Entity not found: ${entityId}`);
|
|
1274
1296
|
process.exit(1);
|
|
1275
1297
|
}
|
|
1276
|
-
if (
|
|
1298
|
+
if (jsonOutput) {
|
|
1277
1299
|
printJson(entity);
|
|
1278
1300
|
} else {
|
|
1279
1301
|
console.log(chalk3.blue("\u2500".repeat(40)));
|
|
@@ -1407,11 +1429,9 @@ async function contactsAddCommand(opts) {
|
|
|
1407
1429
|
category: opts.category ?? "employee"
|
|
1408
1430
|
};
|
|
1409
1431
|
if (opts.phone) data.phone = opts.phone;
|
|
1432
|
+
if (opts.notes) data.notes = opts.notes;
|
|
1410
1433
|
const result = await client.createContact(data);
|
|
1411
1434
|
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
1435
|
} catch (err) {
|
|
1416
1436
|
printError(`Failed to create contact: ${err}`);
|
|
1417
1437
|
process.exit(1);
|
|
@@ -2272,12 +2292,9 @@ async function documentsSigningLinkCommand(docId, opts) {
|
|
|
2272
2292
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2273
2293
|
try {
|
|
2274
2294
|
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
|
-
}
|
|
2295
|
+
const shareUrl = result.token ? `https://humans.thecorporation.ai/sign/${docId}?token=${result.token}` : result.signing_url ?? `https://humans.thecorporation.ai/sign/${docId}`;
|
|
2296
|
+
printSuccess("Signing link generated.");
|
|
2297
|
+
console.log(shareUrl);
|
|
2281
2298
|
} catch (err) {
|
|
2282
2299
|
printError(`Failed to get signing link: ${err}`);
|
|
2283
2300
|
process.exit(1);
|
|
@@ -2677,12 +2694,25 @@ function makeClient() {
|
|
|
2677
2694
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2678
2695
|
return new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2679
2696
|
}
|
|
2697
|
+
function enrichBillingStatus(status) {
|
|
2698
|
+
if (typeof status.status_explanation === "string" && status.status_explanation.trim()) {
|
|
2699
|
+
return status;
|
|
2700
|
+
}
|
|
2701
|
+
const plan = String(status.plan ?? status.tier ?? "").trim();
|
|
2702
|
+
const subStatus = String(status.status ?? "").trim();
|
|
2703
|
+
if (subStatus !== "pending_checkout") {
|
|
2704
|
+
return status;
|
|
2705
|
+
}
|
|
2706
|
+
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.";
|
|
2707
|
+
return { ...status, status_explanation: statusExplanation };
|
|
2708
|
+
}
|
|
2680
2709
|
async function billingCommand(opts) {
|
|
2681
2710
|
const client = makeClient();
|
|
2682
2711
|
try {
|
|
2683
2712
|
const [status, plans] = await Promise.all([client.getBillingStatus(), client.getBillingPlans()]);
|
|
2684
|
-
|
|
2685
|
-
|
|
2713
|
+
const enrichedStatus = enrichBillingStatus(status);
|
|
2714
|
+
if (opts.json) printJson({ status: enrichedStatus, plans });
|
|
2715
|
+
else printBillingPanel(enrichedStatus, plans);
|
|
2686
2716
|
} catch (err) {
|
|
2687
2717
|
printError(`Failed to fetch billing info: ${err}`);
|
|
2688
2718
|
process.exit(1);
|
|
@@ -3017,6 +3047,14 @@ async function formCommand(opts) {
|
|
|
3017
3047
|
process.exit(1);
|
|
3018
3048
|
}
|
|
3019
3049
|
}
|
|
3050
|
+
function parseCsvAddress(raw) {
|
|
3051
|
+
if (!raw) return void 0;
|
|
3052
|
+
const parts = raw.split(",").map((p) => p.trim()).filter(Boolean);
|
|
3053
|
+
if (parts.length !== 4) {
|
|
3054
|
+
throw new Error(`Invalid address format: ${raw}. Expected 'street,city,state,zip'`);
|
|
3055
|
+
}
|
|
3056
|
+
return { street: parts[0], city: parts[1], state: parts[2], zip: parts[3] };
|
|
3057
|
+
}
|
|
3020
3058
|
async function formCreateCommand(opts) {
|
|
3021
3059
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
3022
3060
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
@@ -3027,6 +3065,15 @@ async function formCreateCommand(opts) {
|
|
|
3027
3065
|
legal_name: opts.name
|
|
3028
3066
|
};
|
|
3029
3067
|
if (opts.jurisdiction) payload.jurisdiction = opts.jurisdiction;
|
|
3068
|
+
if (opts.registeredAgentName) payload.registered_agent_name = opts.registeredAgentName;
|
|
3069
|
+
if (opts.registeredAgentAddress) payload.registered_agent_address = opts.registeredAgentAddress;
|
|
3070
|
+
if (opts.formationDate) payload.formation_date = opts.formationDate;
|
|
3071
|
+
if (opts.fiscalYearEnd) payload.fiscal_year_end = opts.fiscalYearEnd;
|
|
3072
|
+
if (opts.sCorp !== void 0) payload.s_corp_election = opts.sCorp;
|
|
3073
|
+
if (opts.transferRestrictions !== void 0) payload.transfer_restrictions = opts.transferRestrictions;
|
|
3074
|
+
if (opts.rofr !== void 0) payload.right_of_first_refusal = opts.rofr;
|
|
3075
|
+
const companyAddress = parseCsvAddress(opts.companyAddress);
|
|
3076
|
+
if (companyAddress) payload.company_address = companyAddress;
|
|
3030
3077
|
const result = await client.createPendingEntity(payload);
|
|
3031
3078
|
printSuccess(`Pending entity created: ${result.entity_id}`);
|
|
3032
3079
|
console.log(` Name: ${result.legal_name}`);
|
|
@@ -3052,6 +3099,8 @@ async function formAddFounderCommand(entityId, opts) {
|
|
|
3052
3099
|
};
|
|
3053
3100
|
if (opts.officerTitle) payload.officer_title = opts.officerTitle.toLowerCase();
|
|
3054
3101
|
if (opts.incorporator) payload.is_incorporator = true;
|
|
3102
|
+
const address = parseCsvAddress(opts.address);
|
|
3103
|
+
if (address) payload.address = address;
|
|
3055
3104
|
const result = await client.addFounder(entityId, payload);
|
|
3056
3105
|
printSuccess(`Founder added (${result.member_count} total)`);
|
|
3057
3106
|
const members = result.members ?? [];
|
|
@@ -3066,11 +3115,29 @@ async function formAddFounderCommand(entityId, opts) {
|
|
|
3066
3115
|
process.exit(1);
|
|
3067
3116
|
}
|
|
3068
3117
|
}
|
|
3069
|
-
async function formFinalizeCommand(entityId) {
|
|
3118
|
+
async function formFinalizeCommand(entityId, opts) {
|
|
3070
3119
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
3071
3120
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
3072
3121
|
try {
|
|
3073
|
-
const
|
|
3122
|
+
const payload = {};
|
|
3123
|
+
if (opts.authorizedShares) {
|
|
3124
|
+
const authorizedShares = parseInt(opts.authorizedShares, 10);
|
|
3125
|
+
if (!Number.isFinite(authorizedShares)) {
|
|
3126
|
+
throw new Error(`Invalid authorized shares: ${opts.authorizedShares}`);
|
|
3127
|
+
}
|
|
3128
|
+
payload.authorized_shares = authorizedShares;
|
|
3129
|
+
}
|
|
3130
|
+
if (opts.parValue) payload.par_value = opts.parValue;
|
|
3131
|
+
if (opts.registeredAgentName) payload.registered_agent_name = opts.registeredAgentName;
|
|
3132
|
+
if (opts.registeredAgentAddress) payload.registered_agent_address = opts.registeredAgentAddress;
|
|
3133
|
+
if (opts.formationDate) payload.formation_date = opts.formationDate;
|
|
3134
|
+
if (opts.fiscalYearEnd) payload.fiscal_year_end = opts.fiscalYearEnd;
|
|
3135
|
+
if (opts.sCorp !== void 0) payload.s_corp_election = opts.sCorp;
|
|
3136
|
+
if (opts.transferRestrictions !== void 0) payload.transfer_restrictions = opts.transferRestrictions;
|
|
3137
|
+
if (opts.rofr !== void 0) payload.right_of_first_refusal = opts.rofr;
|
|
3138
|
+
const companyAddress = parseCsvAddress(opts.companyAddress);
|
|
3139
|
+
if (companyAddress) payload.company_address = companyAddress;
|
|
3140
|
+
const result = await client.finalizeFormation(entityId, payload);
|
|
3074
3141
|
printSuccess(`Formation finalized: ${result.entity_id}`);
|
|
3075
3142
|
if (result.legal_entity_id) console.log(` Legal Entity ID: ${result.legal_entity_id}`);
|
|
3076
3143
|
if (result.instrument_id) console.log(` Instrument ID: ${result.instrument_id}`);
|
|
@@ -3372,9 +3439,9 @@ var entitiesCmd = program.command("entities").description("List entities, show d
|
|
|
3372
3439
|
const { entitiesCommand: entitiesCommand2 } = await Promise.resolve().then(() => (init_entities(), entities_exports));
|
|
3373
3440
|
await entitiesCommand2(opts);
|
|
3374
3441
|
});
|
|
3375
|
-
entitiesCmd.command("show <entity-id>").option("--json", "Output as JSON").description("Show entity detail").action(async (entityId, opts) => {
|
|
3442
|
+
entitiesCmd.command("show <entity-id>").option("--json", "Output as JSON").description("Show entity detail").action(async (entityId, opts, cmd) => {
|
|
3376
3443
|
const { entitiesShowCommand: entitiesShowCommand2 } = await Promise.resolve().then(() => (init_entities(), entities_exports));
|
|
3377
|
-
await entitiesShowCommand2(entityId, opts);
|
|
3444
|
+
await entitiesShowCommand2(entityId, { ...cmd.opts(), ...opts });
|
|
3378
3445
|
});
|
|
3379
3446
|
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
3447
|
const { entitiesConvertCommand: entitiesConvertCommand2 } = await Promise.resolve().then(() => (init_entities(), entities_exports));
|
|
@@ -3585,10 +3652,10 @@ var documentsCmd = program.command("documents").description("Documents and signi
|
|
|
3585
3652
|
const { documentsListCommand: documentsListCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
3586
3653
|
await documentsListCommand2(opts);
|
|
3587
3654
|
});
|
|
3588
|
-
documentsCmd.command("signing-link <doc-id>").description("Get a signing link for a document").action(async (docId,
|
|
3655
|
+
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
3656
|
const parent = cmd.parent.opts();
|
|
3590
3657
|
const { documentsSigningLinkCommand: documentsSigningLinkCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
3591
|
-
await documentsSigningLinkCommand2(docId, { entityId: parent.entityId });
|
|
3658
|
+
await documentsSigningLinkCommand2(docId, { entityId: opts.entityId ?? parent.entityId });
|
|
3592
3659
|
});
|
|
3593
3660
|
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
3661
|
const parent = cmd.parent.opts();
|
|
@@ -3701,17 +3768,17 @@ var formCmd = program.command("form").description("Form a new entity with founde
|
|
|
3701
3768
|
const { formCommand: formCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3702
3769
|
await formCommand2(opts);
|
|
3703
3770
|
});
|
|
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) => {
|
|
3771
|
+
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
3772
|
const { formCreateCommand: formCreateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3706
3773
|
await formCreateCommand2(opts);
|
|
3707
3774
|
});
|
|
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) => {
|
|
3775
|
+
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
3776
|
const { formAddFounderCommand: formAddFounderCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3710
3777
|
await formAddFounderCommand2(entityId, opts);
|
|
3711
3778
|
});
|
|
3712
|
-
formCmd.command("finalize <entity-id>").description("Finalize formation and generate documents + cap table (staged flow step 3)").action(async (entityId) => {
|
|
3779
|
+
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
3780
|
const { formFinalizeCommand: formFinalizeCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3714
|
-
await formFinalizeCommand2(entityId);
|
|
3781
|
+
await formFinalizeCommand2(entityId, opts);
|
|
3715
3782
|
});
|
|
3716
3783
|
program.command("api-keys").description("List API keys").option("--json", "Output as JSON").action(async (opts) => {
|
|
3717
3784
|
const { apiKeysCommand: apiKeysCommand2 } = await Promise.resolve().then(() => (init_api_keys(), api_keys_exports));
|