@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 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
- printSuccess("Digest triggered.");
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(), opts.json);
1254
- if (opts.json) {
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 (opts.json) {
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
- printSuccess(`Signing link: ${result.signing_url}`);
2276
- if (result.token) {
2277
- console.log(` Token: ${result.token}`);
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
- if (opts.json) printJson({ status, plans });
2685
- else printBillingPanel(status, plans);
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 result = await client.finalizeFormation(entityId);
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, _opts, cmd) => {
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));