@thecorporation/cli 26.3.20 → 26.3.21

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
@@ -292,7 +292,9 @@ function requireSupportedConfigKey(dotPath) {
292
292
  }
293
293
  function validateSensitiveConfigUpdate(dotPath, forceSensitive = false) {
294
294
  if (SENSITIVE_CONFIG_KEYS.has(dotPath) && !forceSensitive) {
295
- throw new Error(`refusing to update security-sensitive key '${dotPath}' without --force`);
295
+ throw new Error(
296
+ `refusing to update security-sensitive key '${dotPath}' without --force; this key controls authentication or API routing, so explicit confirmation is required`
297
+ );
296
298
  }
297
299
  }
298
300
  function setKnownConfigValue(cfg, dotPath, value) {
@@ -775,6 +777,29 @@ var init_references = __esm({
775
777
  async resolveContact(entityId, ref) {
776
778
  return this.resolve("contact", ref, { entityId });
777
779
  }
780
+ async resolveWorkItemActor(entityId, ref) {
781
+ const trimmed = validateReferenceInput(ref, "actor reference");
782
+ const [contactResult, agentResult] = await Promise.allSettled([
783
+ this.resolveContact(entityId, trimmed),
784
+ this.resolveAgent(trimmed)
785
+ ]);
786
+ const contactId = contactResult.status === "fulfilled" ? contactResult.value : void 0;
787
+ const agentId = agentResult.status === "fulfilled" ? agentResult.value : void 0;
788
+ if (contactId && agentId && contactId !== agentId) {
789
+ throw new Error(
790
+ `Actor reference '${trimmed}' is ambiguous between a contact and an agent. Use a unique ref or explicit @last:contact / @last:agent.`
791
+ );
792
+ }
793
+ if (contactId) {
794
+ return { actor_type: "contact", actor_id: contactId };
795
+ }
796
+ if (agentId) {
797
+ return { actor_type: "agent", actor_id: agentId };
798
+ }
799
+ throw new Error(
800
+ `No matching contact or agent found for '${trimmed}'. Try 'corp find contact <query>' or 'corp find agent <query>'.`
801
+ );
802
+ }
778
803
  async resolveShareTransfer(entityId, ref) {
779
804
  return this.resolve("share_transfer", ref, { entityId });
780
805
  }
@@ -1300,46 +1325,6 @@ var init_references = __esm({
1300
1325
  });
1301
1326
 
1302
1327
  // src/output.ts
1303
- var output_exports = {};
1304
- __export(output_exports, {
1305
- printAgendaItemsTable: () => printAgendaItemsTable,
1306
- printAgentsTable: () => printAgentsTable,
1307
- printApprovalsTable: () => printApprovalsTable,
1308
- printBankAccountsTable: () => printBankAccountsTable,
1309
- printBillingPanel: () => printBillingPanel,
1310
- printCapTable: () => printCapTable,
1311
- printClassificationsTable: () => printClassificationsTable,
1312
- printContactsTable: () => printContactsTable,
1313
- printDeadlinesTable: () => printDeadlinesTable,
1314
- printDistributionsTable: () => printDistributionsTable,
1315
- printDocumentsTable: () => printDocumentsTable,
1316
- printDryRun: () => printDryRun,
1317
- printEntitiesTable: () => printEntitiesTable,
1318
- printError: () => printError,
1319
- printGovernanceTable: () => printGovernanceTable,
1320
- printInstrumentsTable: () => printInstrumentsTable,
1321
- printInvoicesTable: () => printInvoicesTable,
1322
- printJson: () => printJson,
1323
- printMeetingsTable: () => printMeetingsTable,
1324
- printObligationsTable: () => printObligationsTable,
1325
- printPaymentsTable: () => printPaymentsTable,
1326
- printPayrollRunsTable: () => printPayrollRunsTable,
1327
- printReconciliationsTable: () => printReconciliationsTable,
1328
- printReferenceSummary: () => printReferenceSummary,
1329
- printResolutionsTable: () => printResolutionsTable,
1330
- printRoundsTable: () => printRoundsTable,
1331
- printSafesTable: () => printSafesTable,
1332
- printSeatsTable: () => printSeatsTable,
1333
- printShareClassesTable: () => printShareClassesTable,
1334
- printStatusPanel: () => printStatusPanel,
1335
- printSuccess: () => printSuccess,
1336
- printTaxFilingsTable: () => printTaxFilingsTable,
1337
- printTransfersTable: () => printTransfersTable,
1338
- printValuationsTable: () => printValuationsTable,
1339
- printWarning: () => printWarning,
1340
- printWorkItemsTable: () => printWorkItemsTable,
1341
- printWriteResult: () => printWriteResult
1342
- });
1343
1328
  import chalk from "chalk";
1344
1329
  import Table from "cli-table3";
1345
1330
  function printError(msg) {
@@ -1420,6 +1405,30 @@ function printStatusPanel(data) {
1420
1405
  }
1421
1406
  console.log(chalk.blue("\u2500".repeat(50)));
1422
1407
  }
1408
+ function printFinanceSummaryPanel(data) {
1409
+ const invoices = data.invoices ?? {};
1410
+ const bankAccounts = data.bank_accounts ?? {};
1411
+ const payments = data.payments ?? {};
1412
+ const payrollRuns = data.payroll_runs ?? {};
1413
+ const distributions = data.distributions ?? {};
1414
+ const reconciliations = data.reconciliations ?? {};
1415
+ const classifications = data.contractor_classifications ?? {};
1416
+ console.log(chalk.green("\u2500".repeat(54)));
1417
+ console.log(chalk.green.bold(" Finance Summary"));
1418
+ console.log(chalk.green("\u2500".repeat(54)));
1419
+ console.log(` ${chalk.bold("Entity:")} ${s(data.entity_id) || "N/A"}`);
1420
+ console.log(` ${chalk.bold("Invoices:")} ${s(invoices.count)} total, ${s(invoices.open_count)} open, ${money(invoices.total_amount_cents)}`);
1421
+ if (invoices.latest_due_date) {
1422
+ console.log(` ${chalk.bold("Invoice Horizon:")} next due ${date(invoices.latest_due_date)}`);
1423
+ }
1424
+ console.log(` ${chalk.bold("Bank Accounts:")} ${s(bankAccounts.active_count)}/${s(bankAccounts.count)} active`);
1425
+ console.log(` ${chalk.bold("Payments:")} ${s(payments.count)} total, ${s(payments.pending_count)} pending, ${money(payments.total_amount_cents)}`);
1426
+ console.log(` ${chalk.bold("Payroll Runs:")} ${s(payrollRuns.count)} total${payrollRuns.latest_period_end ? `, latest ${date(payrollRuns.latest_period_end)}` : ""}`);
1427
+ console.log(` ${chalk.bold("Distributions:")} ${s(distributions.count)} total, ${money(distributions.total_amount_cents)}`);
1428
+ console.log(` ${chalk.bold("Reconciliations:")} ${s(reconciliations.balanced_count)}/${s(reconciliations.count)} balanced`);
1429
+ console.log(` ${chalk.bold("Contractors:")} ${s(classifications.count)} classifications, ${s(classifications.high_risk_count)} high risk`);
1430
+ console.log(chalk.green("\u2500".repeat(54)));
1431
+ }
1423
1432
  function makeTable(title, columns) {
1424
1433
  console.log(`
1425
1434
  ${chalk.bold(title)}`);
@@ -1443,6 +1452,17 @@ function date(val) {
1443
1452
  const parsed = new Date(str);
1444
1453
  return Number.isNaN(parsed.getTime()) ? str : parsed.toISOString().slice(0, 10);
1445
1454
  }
1455
+ function actorLabel(record, field) {
1456
+ const actor = record[`${field}_actor`];
1457
+ if (actor && typeof actor === "object" && !Array.isArray(actor)) {
1458
+ const label = s(actor.label);
1459
+ const actorType = s(actor.actor_type);
1460
+ if (label) {
1461
+ return actorType ? `${label} (${actorType})` : label;
1462
+ }
1463
+ }
1464
+ return s(record[field]);
1465
+ }
1446
1466
  function printEntitiesTable(entities) {
1447
1467
  const table = makeTable("Entities", ["Ref", "Name", "Type", "Jurisdiction", "Status"]);
1448
1468
  for (const e of entities) {
@@ -1848,7 +1868,7 @@ function printWorkItemsTable(items) {
1848
1868
  s(w.category),
1849
1869
  colored,
1850
1870
  w.asap ? chalk.red.bold("ASAP") : s(w.deadline ?? ""),
1851
- s(w.claimed_by ?? "")
1871
+ actorLabel(w, "claimed_by")
1852
1872
  ]);
1853
1873
  }
1854
1874
  console.log(table.toString());
@@ -1862,21 +1882,6 @@ function printAgentsTable(agents) {
1862
1882
  }
1863
1883
  console.log(table.toString());
1864
1884
  }
1865
- function printApprovalsTable(approvals) {
1866
- const table = makeTable("Pending Approvals", ["ID", "Type", "Requested By", "Description", "Created"]);
1867
- for (const a of approvals) {
1868
- let desc = s(a.description ?? a.summary);
1869
- if (desc.length > 60) desc = desc.slice(0, 57) + "...";
1870
- table.push([
1871
- s(a.approval_id ?? a.id, 12),
1872
- s(a.approval_type ?? a.type),
1873
- s(a.requested_by ?? a.requester),
1874
- desc,
1875
- s(a.created_at)
1876
- ]);
1877
- }
1878
- console.log(table.toString());
1879
- }
1880
1885
  function printBillingPanel(status, plans) {
1881
1886
  const plan = s(status.plan ?? status.tier) || "free";
1882
1887
  const subStatus = s(status.status) || "active";
@@ -3828,7 +3833,26 @@ async function fourOhNineACommand(opts) {
3828
3833
  } catch (err) {
3829
3834
  const msg = String(err);
3830
3835
  if (msg.includes("404")) {
3831
- console.log("No 409A valuation found for this entity. Create one with:\n corp cap-table create-valuation --type four_oh_nine_a --date YYYY-MM-DD --methodology <method>");
3836
+ try {
3837
+ const eid = await resolver.resolveEntity(opts.entityId);
3838
+ const valuations = await client.getValuations(eid);
3839
+ const pending409a = valuations.filter((valuation) => valuation.valuation_type === "four_oh_nine_a").find((valuation) => valuation.status === "pending_approval");
3840
+ if (pending409a) {
3841
+ const effectiveDate = pending409a.effective_date ?? "unknown date";
3842
+ console.log(
3843
+ `No current approved 409A valuation found. A 409A valuation is pending approval (${effectiveDate}).
3844
+ Complete board approval, then re-run: corp cap-table 409a`
3845
+ );
3846
+ } else {
3847
+ console.log(
3848
+ "No 409A valuation found for this entity. Create one with:\n corp cap-table create-valuation --type four_oh_nine_a --date YYYY-MM-DD --methodology <method>"
3849
+ );
3850
+ }
3851
+ } catch {
3852
+ console.log(
3853
+ "No 409A valuation found for this entity. Create one with:\n corp cap-table create-valuation --type four_oh_nine_a --date YYYY-MM-DD --methodology <method>"
3854
+ );
3855
+ }
3832
3856
  } else {
3833
3857
  printError(`Failed to fetch 409A valuation: ${err}`);
3834
3858
  }
@@ -4361,8 +4385,112 @@ __export(finance_exports, {
4361
4385
  financePayrollCommand: () => financePayrollCommand,
4362
4386
  financePayrollRunsCommand: () => financePayrollRunsCommand,
4363
4387
  financeReconcileCommand: () => financeReconcileCommand,
4364
- financeReconciliationsCommand: () => financeReconciliationsCommand
4365
- });
4388
+ financeReconciliationsCommand: () => financeReconciliationsCommand,
4389
+ financeSummaryCommand: () => financeSummaryCommand
4390
+ });
4391
+ function sumAmounts(records, candidates) {
4392
+ return records.reduce((sum, record) => {
4393
+ for (const key of candidates) {
4394
+ if (typeof record[key] === "number" && Number.isFinite(record[key])) {
4395
+ return sum + Number(record[key]);
4396
+ }
4397
+ }
4398
+ return sum;
4399
+ }, 0);
4400
+ }
4401
+ function latestDate(records, candidates) {
4402
+ const values = records.flatMap((record) => candidates.map((key) => record[key])).filter((value) => typeof value === "string" && value.trim().length > 0).map((value) => ({ raw: value, time: new Date(value).getTime() })).filter((value) => Number.isFinite(value.time)).sort((a, b) => b.time - a.time);
4403
+ return values[0]?.raw;
4404
+ }
4405
+ function countByStatus(records, statuses) {
4406
+ const expected = new Set(statuses.map((status) => status.toLowerCase()));
4407
+ return records.filter((record) => expected.has(String(record.status ?? "").toLowerCase())).length;
4408
+ }
4409
+ function countByField(records, field, values) {
4410
+ const expected = new Set(values.map((value) => value.toLowerCase()));
4411
+ return records.filter((record) => expected.has(String(record[field] ?? "").toLowerCase())).length;
4412
+ }
4413
+ async function financeSummaryCommand(opts) {
4414
+ const cfg = requireConfig("api_url", "api_key", "workspace_id");
4415
+ const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
4416
+ const resolver = new ReferenceResolver(client, cfg);
4417
+ try {
4418
+ const eid = await resolver.resolveEntity(opts.entityId);
4419
+ const [
4420
+ invoices,
4421
+ accounts,
4422
+ payments,
4423
+ payrollRuns,
4424
+ distributions,
4425
+ reconciliations,
4426
+ classifications
4427
+ ] = await Promise.all([
4428
+ client.listInvoices(eid),
4429
+ client.listBankAccounts(eid),
4430
+ client.listPayments(eid),
4431
+ client.listPayrollRuns(eid),
4432
+ client.listDistributions(eid),
4433
+ client.listReconciliations(eid),
4434
+ client.listContractorClassifications(eid)
4435
+ ]);
4436
+ await Promise.all([
4437
+ resolver.stabilizeRecords("invoice", invoices, eid),
4438
+ resolver.stabilizeRecords("bank_account", accounts, eid),
4439
+ resolver.stabilizeRecords("payment", payments, eid),
4440
+ resolver.stabilizeRecords("payroll_run", payrollRuns, eid),
4441
+ resolver.stabilizeRecords("distribution", distributions, eid),
4442
+ resolver.stabilizeRecords("reconciliation", reconciliations, eid),
4443
+ resolver.stabilizeRecords("classification", classifications, eid)
4444
+ ]);
4445
+ const summary = {
4446
+ entity_id: eid,
4447
+ invoices: {
4448
+ count: invoices.length,
4449
+ open_count: invoices.length - countByStatus(invoices, ["paid", "cancelled", "void"]),
4450
+ overdue_count: countByStatus(invoices, ["overdue"]),
4451
+ total_amount_cents: sumAmounts(invoices, ["amount_cents", "total_amount_cents"]),
4452
+ latest_due_date: latestDate(invoices, ["due_date", "created_at"])
4453
+ },
4454
+ bank_accounts: {
4455
+ count: accounts.length,
4456
+ active_count: countByStatus(accounts, ["active", "approved", "open"])
4457
+ },
4458
+ payments: {
4459
+ count: payments.length,
4460
+ pending_count: countByStatus(payments, ["pending", "submitted", "queued"]),
4461
+ total_amount_cents: sumAmounts(payments, ["amount_cents"]),
4462
+ latest_submitted_at: latestDate(payments, ["submitted_at", "created_at"])
4463
+ },
4464
+ payroll_runs: {
4465
+ count: payrollRuns.length,
4466
+ latest_period_end: latestDate(payrollRuns, ["pay_period_end", "created_at"])
4467
+ },
4468
+ distributions: {
4469
+ count: distributions.length,
4470
+ total_amount_cents: sumAmounts(distributions, ["amount_cents", "distribution_amount_cents"]),
4471
+ latest_declared_at: latestDate(distributions, ["declared_at", "created_at"])
4472
+ },
4473
+ reconciliations: {
4474
+ count: reconciliations.length,
4475
+ balanced_count: reconciliations.filter((record) => record.is_balanced === true).length,
4476
+ latest_as_of_date: latestDate(reconciliations, ["as_of_date", "created_at"])
4477
+ },
4478
+ contractor_classifications: {
4479
+ count: classifications.length,
4480
+ high_risk_count: countByField(classifications, "risk_level", ["high"]),
4481
+ medium_risk_count: countByField(classifications, "risk_level", ["medium"])
4482
+ }
4483
+ };
4484
+ if (opts.json) {
4485
+ printJson(summary);
4486
+ return;
4487
+ }
4488
+ printFinanceSummaryPanel(summary);
4489
+ } catch (err) {
4490
+ printError(`Failed to fetch finance summary: ${err}`);
4491
+ process.exit(1);
4492
+ }
4493
+ }
4366
4494
  async function financeInvoicesCommand(opts) {
4367
4495
  const cfg = requireConfig("api_url", "api_key", "workspace_id");
4368
4496
  const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
@@ -5102,12 +5230,206 @@ var init_governance = __esm({
5102
5230
  }
5103
5231
  });
5104
5232
 
5233
+ // src/formation-automation.ts
5234
+ function normalizeRole(value) {
5235
+ return String(value ?? "").trim().toLowerCase();
5236
+ }
5237
+ function fallbackSignerEmail(requirement) {
5238
+ const slug = String(requirement.signer_name ?? "signer").toLowerCase().replace(/[^a-z0-9]+/g, ".").replace(/^\.+|\.+$/g, "");
5239
+ return `${slug || "signer"}@example.com`;
5240
+ }
5241
+ function getSignatureRequirements(document) {
5242
+ const content = document.content;
5243
+ if (!content || typeof content !== "object" || Array.isArray(content)) {
5244
+ return [];
5245
+ }
5246
+ const requirements = content.signature_requirements;
5247
+ if (!Array.isArray(requirements)) {
5248
+ return [];
5249
+ }
5250
+ return requirements.filter((item) => typeof item === "object" && item !== null && !Array.isArray(item)).map((item) => ({
5251
+ role: String(item.role ?? "").trim(),
5252
+ signer_name: String(item.signer_name ?? "").trim(),
5253
+ signer_email: typeof item.signer_email === "string" && item.signer_email.trim() ? item.signer_email.trim() : void 0
5254
+ })).filter((item) => item.role.length > 0 && item.signer_name.length > 0);
5255
+ }
5256
+ function getSignedRoles(document) {
5257
+ const signatures = Array.isArray(document.signatures) ? document.signatures : [];
5258
+ return new Set(
5259
+ signatures.filter((item) => typeof item === "object" && item !== null && !Array.isArray(item)).map((item) => normalizeRole(item.signer_role)).filter(Boolean)
5260
+ );
5261
+ }
5262
+ function deterministicEin(entityId) {
5263
+ const digits = entityId.replace(/\D/g, "");
5264
+ const nineDigits = `${digits}123456789`.slice(0, 9).padEnd(9, "0");
5265
+ return `${nineDigits.slice(0, 2)}-${nineDigits.slice(2)}`;
5266
+ }
5267
+ function filingIdentifier(prefix, entityId) {
5268
+ const token = entityId.replace(/[^a-zA-Z0-9]/g, "").slice(0, 12).toLowerCase() || "formation";
5269
+ return `${prefix}-${token}`;
5270
+ }
5271
+ async function autoSignFormationDocument(client, entityId, documentId) {
5272
+ const document = await client.getDocument(documentId, entityId);
5273
+ const requiredSignatures = getSignatureRequirements(document);
5274
+ if (requiredSignatures.length === 0) {
5275
+ return { document, signatures_added: 0 };
5276
+ }
5277
+ const signedRoles = getSignedRoles(document);
5278
+ let signaturesAdded = 0;
5279
+ for (const requirement of requiredSignatures) {
5280
+ if (signedRoles.has(normalizeRole(requirement.role))) {
5281
+ continue;
5282
+ }
5283
+ await client.signDocument(documentId, entityId, {
5284
+ signer_name: requirement.signer_name,
5285
+ signer_role: requirement.role,
5286
+ signer_email: requirement.signer_email ?? fallbackSignerEmail(requirement),
5287
+ signature_text: requirement.signer_name,
5288
+ consent_text: DEFAULT_SIGNATURE_CONSENT
5289
+ });
5290
+ signedRoles.add(normalizeRole(requirement.role));
5291
+ signaturesAdded += 1;
5292
+ }
5293
+ const refreshed = await client.getDocument(documentId, entityId);
5294
+ return { document: refreshed, signatures_added: signaturesAdded };
5295
+ }
5296
+ async function autoSignFormationDocuments(client, resolver, entityId) {
5297
+ const summaries = await client.getEntityDocuments(entityId);
5298
+ await resolver.stabilizeRecords("document", summaries, entityId);
5299
+ let signaturesAdded = 0;
5300
+ let documentsSigned = 0;
5301
+ const documents = [];
5302
+ for (const summary of summaries) {
5303
+ const documentId = String(summary.document_id ?? "");
5304
+ if (!documentId) {
5305
+ continue;
5306
+ }
5307
+ const { document, signatures_added } = await autoSignFormationDocument(
5308
+ client,
5309
+ entityId,
5310
+ documentId
5311
+ );
5312
+ signaturesAdded += signatures_added;
5313
+ if (signatures_added > 0) {
5314
+ documentsSigned += 1;
5315
+ }
5316
+ documents.push(document);
5317
+ }
5318
+ return {
5319
+ documents_seen: summaries.length,
5320
+ documents_signed: documentsSigned,
5321
+ signatures_added: signaturesAdded,
5322
+ documents
5323
+ };
5324
+ }
5325
+ async function activateFormationEntity(client, resolver, entityId, options = {}) {
5326
+ let formation = await client.getFormation(entityId);
5327
+ const initialStatus = String(formation.formation_status ?? "");
5328
+ const steps = [];
5329
+ let signaturesAdded = 0;
5330
+ let documentsSigned = 0;
5331
+ for (let i = 0; i < 10; i += 1) {
5332
+ const status = String(formation.formation_status ?? "");
5333
+ if (status === "active") {
5334
+ return {
5335
+ entity_id: entityId,
5336
+ initial_status: initialStatus,
5337
+ final_status: status,
5338
+ signatures_added: signaturesAdded,
5339
+ documents_signed: documentsSigned,
5340
+ steps,
5341
+ formation
5342
+ };
5343
+ }
5344
+ if (status === "pending") {
5345
+ throw new Error("Formation is still pending. Finalize it before activation.");
5346
+ }
5347
+ if (status === "documents_generated") {
5348
+ const signed = await autoSignFormationDocuments(client, resolver, entityId);
5349
+ signaturesAdded += signed.signatures_added;
5350
+ documentsSigned += signed.documents_signed;
5351
+ await client.markFormationDocumentsSigned(entityId);
5352
+ steps.push(`signed ${signed.signatures_added} signatures across ${signed.documents_signed} documents`);
5353
+ formation = await client.getFormation(entityId);
5354
+ continue;
5355
+ }
5356
+ if (status === "documents_signed") {
5357
+ const gates = await client.getFormationGates(entityId);
5358
+ if (gates.requires_natural_person_attestation && !gates.attestation_recorded) {
5359
+ await client.recordFilingAttestation(entityId, {
5360
+ signer_name: gates.designated_attestor_name,
5361
+ signer_role: gates.designated_attestor_role,
5362
+ signer_email: gates.designated_attestor_email ?? fallbackSignerEmail({
5363
+ role: String(gates.designated_attestor_role ?? "attestor"),
5364
+ signer_name: String(gates.designated_attestor_name ?? "attestor")
5365
+ }),
5366
+ consent_text: DEFAULT_ATTESTATION_CONSENT,
5367
+ notes: "Recorded automatically by corp form activate"
5368
+ });
5369
+ steps.push("recorded filing attestation");
5370
+ }
5371
+ const gatesAfterAttestation = await client.getFormationGates(entityId);
5372
+ if (gatesAfterAttestation.requires_registered_agent_consent_evidence && Number(gatesAfterAttestation.registered_agent_consent_evidence_count ?? 0) === 0) {
5373
+ await client.addRegisteredAgentConsentEvidence(entityId, {
5374
+ evidence_uri: options.evidenceUri ?? `generated://registered-agent-consent/${entityId}`,
5375
+ evidence_type: options.evidenceType ?? "generated",
5376
+ notes: "Recorded automatically by corp form activate"
5377
+ });
5378
+ steps.push("recorded registered-agent consent evidence");
5379
+ }
5380
+ const finalGates = await client.getFormationGates(entityId);
5381
+ if (Array.isArray(finalGates.filing_submission_blockers) && finalGates.filing_submission_blockers.length > 0) {
5382
+ throw new Error(
5383
+ `Formation filing is still blocked: ${finalGates.filing_submission_blockers.join("; ")}`
5384
+ );
5385
+ }
5386
+ await client.submitFiling(entityId);
5387
+ steps.push("submitted filing");
5388
+ formation = await client.getFormation(entityId);
5389
+ continue;
5390
+ }
5391
+ if (status === "filing_submitted") {
5392
+ await client.confirmFiling(entityId, {
5393
+ external_filing_id: options.filingId ?? filingIdentifier("sim", entityId),
5394
+ receipt_reference: options.receiptReference ?? filingIdentifier("receipt", entityId)
5395
+ });
5396
+ steps.push("confirmed filing");
5397
+ formation = await client.getFormation(entityId);
5398
+ continue;
5399
+ }
5400
+ if (status === "filed") {
5401
+ await client.applyEin(entityId);
5402
+ steps.push("submitted EIN application");
5403
+ formation = await client.getFormation(entityId);
5404
+ continue;
5405
+ }
5406
+ if (status === "ein_applied") {
5407
+ await client.confirmEin(entityId, { ein: options.ein ?? deterministicEin(entityId) });
5408
+ steps.push("confirmed EIN");
5409
+ formation = await client.getFormation(entityId);
5410
+ continue;
5411
+ }
5412
+ throw new Error(`Unsupported formation status for activation: ${status || "unknown"}`);
5413
+ }
5414
+ throw new Error("Formation activation did not converge within 10 steps.");
5415
+ }
5416
+ var DEFAULT_SIGNATURE_CONSENT, DEFAULT_ATTESTATION_CONSENT;
5417
+ var init_formation_automation = __esm({
5418
+ "src/formation-automation.ts"() {
5419
+ "use strict";
5420
+ DEFAULT_SIGNATURE_CONSENT = "I agree to sign this document electronically.";
5421
+ DEFAULT_ATTESTATION_CONSENT = "I attest the filing information is accurate and authorized.";
5422
+ }
5423
+ });
5424
+
5105
5425
  // src/commands/documents.ts
5106
5426
  var documents_exports = {};
5107
5427
  __export(documents_exports, {
5108
5428
  documentsGenerateCommand: () => documentsGenerateCommand,
5109
5429
  documentsListCommand: () => documentsListCommand,
5110
5430
  documentsPreviewPdfCommand: () => documentsPreviewPdfCommand,
5431
+ documentsSignAllCommand: () => documentsSignAllCommand,
5432
+ documentsSignCommand: () => documentsSignCommand,
5111
5433
  documentsSigningLinkCommand: () => documentsSigningLinkCommand
5112
5434
  });
5113
5435
  function formatSigningLink(docId, result) {
@@ -5213,7 +5535,78 @@ function coerceParamValue(raw) {
5213
5535
  }
5214
5536
  return raw;
5215
5537
  }
5538
+ async function documentsSignCommand(docId, opts) {
5539
+ const cfg = requireConfig("api_url", "api_key", "workspace_id");
5540
+ const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
5541
+ const resolver = new ReferenceResolver(client, cfg);
5542
+ try {
5543
+ const eid = await resolver.resolveEntity(opts.entityId);
5544
+ const resolvedDocumentId = await resolver.resolveDocument(eid, docId);
5545
+ if (opts.signerName || opts.signerRole || opts.signerEmail || opts.signatureText) {
5546
+ if (!opts.signerName || !opts.signerRole || !opts.signerEmail) {
5547
+ throw new Error("Manual signing requires --signer-name, --signer-role, and --signer-email.");
5548
+ }
5549
+ const result2 = await client.signDocument(resolvedDocumentId, eid, {
5550
+ signer_name: opts.signerName,
5551
+ signer_role: opts.signerRole,
5552
+ signer_email: opts.signerEmail,
5553
+ signature_text: opts.signatureText ?? opts.signerName
5554
+ });
5555
+ await resolver.stabilizeRecord("document", { document_id: resolvedDocumentId, title: docId }, eid);
5556
+ printWriteResult(result2, `Document ${resolvedDocumentId} signed.`, opts.json);
5557
+ return;
5558
+ }
5559
+ const result = await autoSignFormationDocument(client, eid, resolvedDocumentId);
5560
+ await resolver.stabilizeRecord("document", result.document, eid);
5561
+ resolver.rememberFromRecord("document", result.document, eid);
5562
+ if (opts.json) {
5563
+ printJson({
5564
+ document_id: resolvedDocumentId,
5565
+ signatures_added: result.signatures_added,
5566
+ document: result.document
5567
+ });
5568
+ return;
5569
+ }
5570
+ printSuccess(
5571
+ result.signatures_added > 0 ? `Applied ${result.signatures_added} signature(s) to ${resolvedDocumentId}.` : `No signatures were needed for ${resolvedDocumentId}.`
5572
+ );
5573
+ printReferenceSummary("document", result.document, { showReuseHint: true });
5574
+ printJson(result.document);
5575
+ } catch (err) {
5576
+ printError(`Failed to sign document: ${err}`);
5577
+ process.exit(1);
5578
+ }
5579
+ }
5580
+ async function documentsSignAllCommand(opts) {
5581
+ const cfg = requireConfig("api_url", "api_key", "workspace_id");
5582
+ const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
5583
+ const resolver = new ReferenceResolver(client, cfg);
5584
+ try {
5585
+ const eid = await resolver.resolveEntity(opts.entityId);
5586
+ const result = await autoSignFormationDocuments(client, resolver, eid);
5587
+ if (opts.json) {
5588
+ printJson(result);
5589
+ return;
5590
+ }
5591
+ printSuccess(
5592
+ `Processed ${result.documents_seen} formation document(s); added ${result.signatures_added} signature(s) across ${result.documents_signed} document(s).`
5593
+ );
5594
+ printJson(result.documents.map((document) => ({
5595
+ document_id: document.document_id,
5596
+ title: document.title,
5597
+ status: document.status,
5598
+ signatures: Array.isArray(document.signatures) ? document.signatures.length : document.signatures
5599
+ })));
5600
+ } catch (err) {
5601
+ printError(`Failed to sign formation documents: ${err}`);
5602
+ process.exit(1);
5603
+ }
5604
+ }
5216
5605
  async function documentsPreviewPdfCommand(opts) {
5606
+ if (!opts.documentId || opts.documentId.trim().length === 0) {
5607
+ printError("preview-pdf requires --definition-id (or deprecated alias --document-id)");
5608
+ process.exit(1);
5609
+ }
5217
5610
  const cfg = requireConfig("api_url", "api_key", "workspace_id");
5218
5611
  const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
5219
5612
  const resolver = new ReferenceResolver(client, cfg);
@@ -5236,6 +5629,7 @@ var init_documents = __esm({
5236
5629
  init_api_client();
5237
5630
  init_output();
5238
5631
  init_references();
5632
+ init_formation_automation();
5239
5633
  HUMANS_APP_ORIGIN = "https://humans.thecorporation.ai";
5240
5634
  }
5241
5635
  });
@@ -5560,6 +5954,18 @@ __export(work_items_exports, {
5560
5954
  workItemsShowCommand: () => workItemsShowCommand
5561
5955
  });
5562
5956
  import chalk10 from "chalk";
5957
+ function actorLabel2(record, key) {
5958
+ const actor = record[`${key}_actor`];
5959
+ if (actor && typeof actor === "object" && !Array.isArray(actor)) {
5960
+ const label = actor.label;
5961
+ const actorType = actor.actor_type;
5962
+ if (typeof label === "string" && label.trim()) {
5963
+ return typeof actorType === "string" && actorType.trim() ? `${label} (${actorType})` : label;
5964
+ }
5965
+ }
5966
+ const legacy = record[key];
5967
+ return typeof legacy === "string" && legacy.trim() ? legacy : void 0;
5968
+ }
5563
5969
  async function workItemsListCommand(opts) {
5564
5970
  const cfg = requireConfig("api_url", "api_key", "workspace_id");
5565
5971
  const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
@@ -5602,13 +6008,16 @@ async function workItemsShowCommand(workItemId, opts) {
5602
6008
  if (w.description) console.log(` ${chalk10.bold("Description:")} ${w.description}`);
5603
6009
  if (w.deadline) console.log(` ${chalk10.bold("Deadline:")} ${w.deadline}`);
5604
6010
  if (w.asap) console.log(` ${chalk10.bold("Priority:")} ${chalk10.red.bold("ASAP")}`);
5605
- if (w.claimed_by) console.log(` ${chalk10.bold("Claimed by:")} ${w.claimed_by}`);
6011
+ const claimedBy = actorLabel2(w, "claimed_by");
6012
+ const completedBy = actorLabel2(w, "completed_by");
6013
+ const createdBy = actorLabel2(w, "created_by");
6014
+ if (claimedBy) console.log(` ${chalk10.bold("Claimed by:")} ${claimedBy}`);
5606
6015
  if (w.claimed_at) console.log(` ${chalk10.bold("Claimed at:")} ${w.claimed_at}`);
5607
6016
  if (w.claim_ttl_seconds) console.log(` ${chalk10.bold("Claim TTL:")} ${w.claim_ttl_seconds}s`);
5608
- if (w.completed_by) console.log(` ${chalk10.bold("Completed by:")} ${w.completed_by}`);
6017
+ if (completedBy) console.log(` ${chalk10.bold("Completed by:")} ${completedBy}`);
5609
6018
  if (w.completed_at) console.log(` ${chalk10.bold("Completed at:")} ${w.completed_at}`);
5610
6019
  if (w.result) console.log(` ${chalk10.bold("Result:")} ${w.result}`);
5611
- if (w.created_by) console.log(` ${chalk10.bold("Created by:")} ${w.created_by}`);
6020
+ if (createdBy) console.log(` ${chalk10.bold("Created by:")} ${createdBy}`);
5612
6021
  console.log(` ${chalk10.bold("Created at:")} ${w.created_at ?? "N/A"}`);
5613
6022
  console.log(chalk10.cyan("\u2500".repeat(40)));
5614
6023
  } catch (err) {
@@ -5630,7 +6039,7 @@ async function workItemsCreateCommand(opts) {
5630
6039
  if (opts.description) data.description = opts.description;
5631
6040
  if (opts.deadline) data.deadline = opts.deadline;
5632
6041
  if (opts.asap) data.asap = true;
5633
- if (opts.createdBy) data.created_by = await resolver.resolveContact(eid, opts.createdBy);
6042
+ if (opts.createdBy) data.created_by_actor = await resolver.resolveWorkItemActor(eid, opts.createdBy);
5634
6043
  const result = await client.createWorkItem(eid, data);
5635
6044
  await resolver.stabilizeRecord("work_item", result, eid);
5636
6045
  resolver.rememberFromRecord("work_item", result, eid);
@@ -5652,7 +6061,7 @@ async function workItemsClaimCommand(workItemId, opts) {
5652
6061
  const eid = await resolver.resolveEntity(opts.entityId);
5653
6062
  const resolvedWorkItemId = await resolver.resolveWorkItem(eid, workItemId);
5654
6063
  const data = {
5655
- claimed_by: await resolver.resolveContact(eid, opts.claimedBy)
6064
+ claimed_by_actor: await resolver.resolveWorkItemActor(eid, opts.claimedBy)
5656
6065
  };
5657
6066
  if (opts.ttl != null) data.ttl_seconds = opts.ttl;
5658
6067
  const result = await client.claimWorkItem(eid, resolvedWorkItemId, data);
@@ -5670,7 +6079,7 @@ async function workItemsCompleteCommand(workItemId, opts) {
5670
6079
  const eid = await resolver.resolveEntity(opts.entityId);
5671
6080
  const resolvedWorkItemId = await resolver.resolveWorkItem(eid, workItemId);
5672
6081
  const data = {
5673
- completed_by: await resolver.resolveContact(eid, opts.completedBy)
6082
+ completed_by_actor: await resolver.resolveWorkItemActor(eid, opts.completedBy)
5674
6083
  };
5675
6084
  if (opts.result) data.result = opts.result;
5676
6085
  const result = await client.completeWorkItem(eid, resolvedWorkItemId, data);
@@ -5794,9 +6203,35 @@ var init_billing = __esm({
5794
6203
  }
5795
6204
  });
5796
6205
 
6206
+ // src/commands/approvals.ts
6207
+ var approvals_exports = {};
6208
+ __export(approvals_exports, {
6209
+ approvalsListCommand: () => approvalsListCommand,
6210
+ approvalsRespondCommand: () => approvalsRespondCommand
6211
+ });
6212
+ async function approvalsListCommand(_opts) {
6213
+ printError(
6214
+ "Approvals are managed through governance meetings.\n Use: corp governance convene ... to schedule a board meeting\n Use: corp governance vote <meeting-ref> <item-ref> ... to cast votes"
6215
+ );
6216
+ process.exit(1);
6217
+ }
6218
+ async function approvalsRespondCommand(_approvalId, _decision, _opts) {
6219
+ printError(
6220
+ "Approvals are managed through governance meetings.\n Use: corp governance vote <meeting-ref> <item-ref> --voter <contact-ref> --vote for"
6221
+ );
6222
+ process.exit(1);
6223
+ }
6224
+ var init_approvals = __esm({
6225
+ "src/commands/approvals.ts"() {
6226
+ "use strict";
6227
+ init_output();
6228
+ }
6229
+ });
6230
+
5797
6231
  // src/commands/form.ts
5798
6232
  var form_exports = {};
5799
6233
  __export(form_exports, {
6234
+ formActivateCommand: () => formActivateCommand,
5800
6235
  formAddFounderCommand: () => formAddFounderCommand,
5801
6236
  formCommand: () => formCommand,
5802
6237
  formCreateCommand: () => formCreateCommand,
@@ -6420,6 +6855,55 @@ async function formFinalizeCommand(entityId, opts) {
6420
6855
  process.exit(1);
6421
6856
  }
6422
6857
  }
6858
+ async function formActivateCommand(entityId, opts) {
6859
+ const cfg = requireConfig("api_url", "api_key", "workspace_id");
6860
+ const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
6861
+ const resolver = new ReferenceResolver(client, cfg);
6862
+ try {
6863
+ const resolvedEntityId = await resolveEntityRefForFormCommand(resolver, entityId, opts.dryRun);
6864
+ const payload = { entity_id: resolvedEntityId };
6865
+ if (opts.evidenceUri) payload.evidence_uri = opts.evidenceUri;
6866
+ if (opts.evidenceType) payload.evidence_type = opts.evidenceType;
6867
+ if (opts.filingId) payload.filing_id = opts.filingId;
6868
+ if (opts.receiptReference) payload.receipt_reference = opts.receiptReference;
6869
+ if (opts.ein) payload.ein = opts.ein;
6870
+ if (opts.dryRun) {
6871
+ printDryRun("formation.activate", payload);
6872
+ return;
6873
+ }
6874
+ const result = await activateFormationEntity(client, resolver, resolvedEntityId, {
6875
+ evidenceUri: opts.evidenceUri,
6876
+ evidenceType: opts.evidenceType,
6877
+ filingId: opts.filingId,
6878
+ receiptReference: opts.receiptReference,
6879
+ ein: opts.ein
6880
+ });
6881
+ const formation = await client.getFormation(resolvedEntityId);
6882
+ await resolver.stabilizeRecord("entity", formation);
6883
+ resolver.rememberFromRecord("entity", formation);
6884
+ if (opts.json) {
6885
+ printJson({
6886
+ ...result,
6887
+ formation
6888
+ });
6889
+ return;
6890
+ }
6891
+ printSuccess(`Formation advanced to ${result.final_status}.`);
6892
+ printReferenceSummary("entity", formation, { showReuseHint: true });
6893
+ if (result.steps.length > 0) {
6894
+ console.log(" Steps:");
6895
+ for (const step of result.steps) {
6896
+ console.log(` - ${step}`);
6897
+ }
6898
+ }
6899
+ console.log(` Signatures added: ${result.signatures_added}`);
6900
+ console.log(` Documents updated: ${result.documents_signed}`);
6901
+ printJson(formation);
6902
+ } catch (err) {
6903
+ printError(`Failed to activate formation: ${err}`);
6904
+ process.exit(1);
6905
+ }
6906
+ }
6423
6907
  var init_form = __esm({
6424
6908
  "src/commands/form.ts"() {
6425
6909
  "use strict";
@@ -6427,6 +6911,7 @@ var init_form = __esm({
6427
6911
  init_api_client();
6428
6912
  init_output();
6429
6913
  init_references();
6914
+ init_formation_automation();
6430
6915
  }
6431
6916
  });
6432
6917
 
@@ -6487,12 +6972,235 @@ var demo_exports = {};
6487
6972
  __export(demo_exports, {
6488
6973
  demoCommand: () => demoCommand
6489
6974
  });
6975
+ function scenarioConfig(name, scenario) {
6976
+ switch (scenario) {
6977
+ case "llc":
6978
+ return {
6979
+ entity_type: "llc",
6980
+ legal_name: name,
6981
+ jurisdiction: "US-WY",
6982
+ members: [
6983
+ {
6984
+ name: "Alice Chen",
6985
+ email: "alice@example.com",
6986
+ role: "member",
6987
+ investor_type: "natural_person",
6988
+ ownership_pct: 60
6989
+ },
6990
+ {
6991
+ name: "Bob Martinez",
6992
+ email: "bob@example.com",
6993
+ role: "member",
6994
+ investor_type: "natural_person",
6995
+ ownership_pct: 40
6996
+ }
6997
+ ],
6998
+ fiscal_year_end: "12-31",
6999
+ company_address: {
7000
+ street: "251 Little Falls Dr",
7001
+ city: "Wilmington",
7002
+ state: "DE",
7003
+ zip: "19808"
7004
+ }
7005
+ };
7006
+ case "restaurant":
7007
+ return {
7008
+ entity_type: "llc",
7009
+ legal_name: name,
7010
+ jurisdiction: "US-DE",
7011
+ members: [
7012
+ {
7013
+ name: "Rosa Alvarez",
7014
+ email: "rosa@example.com",
7015
+ role: "manager",
7016
+ investor_type: "natural_person",
7017
+ ownership_pct: 55
7018
+ },
7019
+ {
7020
+ name: "Noah Patel",
7021
+ email: "noah@example.com",
7022
+ role: "member",
7023
+ investor_type: "natural_person",
7024
+ ownership_pct: 45
7025
+ }
7026
+ ],
7027
+ fiscal_year_end: "12-31",
7028
+ company_address: {
7029
+ street: "18 Market St",
7030
+ city: "Wilmington",
7031
+ state: "DE",
7032
+ zip: "19801"
7033
+ }
7034
+ };
7035
+ case "startup":
7036
+ default:
7037
+ return {
7038
+ entity_type: "c_corp",
7039
+ legal_name: name,
7040
+ jurisdiction: "US-DE",
7041
+ authorized_shares: 1e7,
7042
+ par_value: "0.0001",
7043
+ transfer_restrictions: true,
7044
+ right_of_first_refusal: true,
7045
+ members: [
7046
+ {
7047
+ name: "Alice Chen",
7048
+ email: "alice@example.com",
7049
+ role: "chair",
7050
+ investor_type: "natural_person",
7051
+ shares_purchased: 6e6,
7052
+ officer_title: "ceo",
7053
+ is_incorporator: true
7054
+ },
7055
+ {
7056
+ name: "Bob Martinez",
7057
+ email: "bob@example.com",
7058
+ role: "director",
7059
+ investor_type: "natural_person",
7060
+ shares_purchased: 4e6,
7061
+ officer_title: "cto"
7062
+ }
7063
+ ],
7064
+ fiscal_year_end: "12-31",
7065
+ company_address: {
7066
+ street: "251 Little Falls Dr",
7067
+ city: "Wilmington",
7068
+ state: "DE",
7069
+ zip: "19808"
7070
+ }
7071
+ };
7072
+ }
7073
+ }
7074
+ function meetingTypeForBody(body) {
7075
+ return String(body.body_type) === "llc_member_vote" ? "member_meeting" : "board_meeting";
7076
+ }
6490
7077
  async function demoCommand(opts) {
6491
7078
  const cfg = requireConfig("api_url", "api_key", "workspace_id");
6492
7079
  const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
7080
+ const resolver = new ReferenceResolver(client, cfg);
7081
+ const scenario = opts.scenario ?? "startup";
6493
7082
  try {
6494
- const result = await withSpinner("Loading", () => client.seedDemo(opts.name));
6495
- printSuccess(`Demo seeded: ${result.entity_id ?? "OK"}`);
7083
+ if (opts.minimal) {
7084
+ const result2 = await withSpinner("Loading", () => client.seedDemo({
7085
+ name: opts.name,
7086
+ scenario
7087
+ }));
7088
+ if (opts.json) {
7089
+ printJson(result2);
7090
+ return;
7091
+ }
7092
+ printSuccess("Minimal demo seeded.");
7093
+ printJson(result2);
7094
+ return;
7095
+ }
7096
+ const formationPayload = scenarioConfig(opts.name, scenario);
7097
+ const created = await withSpinner(
7098
+ "Creating demo entity",
7099
+ () => client.createFormationWithCapTable(formationPayload)
7100
+ );
7101
+ const entityId = String(created.entity_id ?? created.formation_id ?? "");
7102
+ if (!entityId) {
7103
+ throw new Error("demo formation did not return an entity_id");
7104
+ }
7105
+ await resolver.stabilizeRecord("entity", created);
7106
+ resolver.rememberFromRecord("entity", created);
7107
+ const activation = await withSpinner(
7108
+ "Activating formation",
7109
+ () => activateFormationEntity(client, resolver, entityId)
7110
+ );
7111
+ const agent = await withSpinner(
7112
+ "Creating demo agent",
7113
+ () => client.createAgent({
7114
+ name: `${opts.name} Operator`,
7115
+ entity_id: entityId,
7116
+ system_prompt: `Operate ${opts.name} and keep the workspace data clean.`,
7117
+ scopes: []
7118
+ })
7119
+ );
7120
+ await resolver.stabilizeRecord("agent", agent);
7121
+ resolver.rememberFromRecord("agent", agent);
7122
+ const bodies = await client.listGovernanceBodies(entityId);
7123
+ await resolver.stabilizeRecords("body", bodies, entityId);
7124
+ let meeting;
7125
+ if (bodies.length > 0) {
7126
+ meeting = await client.scheduleMeeting({
7127
+ entity_id: entityId,
7128
+ body_id: bodies[0].body_id,
7129
+ meeting_type: meetingTypeForBody(bodies[0]),
7130
+ title: "Demo kickoff meeting",
7131
+ agenda_item_titles: [
7132
+ "Approve demo operating budget",
7133
+ "Review founder vesting and cap table"
7134
+ ]
7135
+ });
7136
+ await resolver.stabilizeRecord("meeting", meeting, entityId);
7137
+ resolver.rememberFromRecord("meeting", meeting, entityId);
7138
+ }
7139
+ const workItem = await client.createWorkItem(entityId, {
7140
+ title: "Review demo workspace",
7141
+ description: "Check documents, governance, cap table, and treasury setup.",
7142
+ category: "ops",
7143
+ created_by_actor: {
7144
+ actor_type: "agent",
7145
+ actor_id: String(agent.agent_id)
7146
+ }
7147
+ });
7148
+ await resolver.stabilizeRecord("work_item", workItem, entityId);
7149
+ resolver.rememberFromRecord("work_item", workItem, entityId);
7150
+ const claimedWorkItem = await client.claimWorkItem(entityId, String(workItem.work_item_id), {
7151
+ claimed_by_actor: {
7152
+ actor_type: "agent",
7153
+ actor_id: String(agent.agent_id)
7154
+ }
7155
+ });
7156
+ const bankAccount = await client.openBankAccount({
7157
+ entity_id: entityId,
7158
+ bank_name: "Mercury"
7159
+ });
7160
+ await resolver.stabilizeRecord("bank_account", bankAccount, entityId);
7161
+ resolver.rememberFromRecord("bank_account", bankAccount, entityId);
7162
+ const invoice = await client.createInvoice({
7163
+ entity_id: entityId,
7164
+ customer_name: "Acme Customer",
7165
+ amount_cents: 25e4,
7166
+ due_date: "2026-04-01",
7167
+ description: "Demo advisory services"
7168
+ });
7169
+ await resolver.stabilizeRecord("invoice", invoice, entityId);
7170
+ resolver.rememberFromRecord("invoice", invoice, entityId);
7171
+ const contract = await client.generateContract({
7172
+ entity_id: entityId,
7173
+ template_type: "nda",
7174
+ counterparty_name: "Example Counterparty",
7175
+ effective_date: "2026-03-12",
7176
+ parameters: {}
7177
+ });
7178
+ await resolver.stabilizeRecord("document", contract, entityId);
7179
+ resolver.rememberFromRecord("document", contract, entityId);
7180
+ const result = {
7181
+ scenario,
7182
+ entity: created,
7183
+ activation,
7184
+ agent,
7185
+ meeting,
7186
+ work_item: claimedWorkItem,
7187
+ bank_account: bankAccount,
7188
+ invoice,
7189
+ contract
7190
+ };
7191
+ if (opts.json) {
7192
+ printJson(result);
7193
+ return;
7194
+ }
7195
+ printSuccess(`Demo environment created for ${opts.name}.`);
7196
+ printReferenceSummary("entity", created, { showReuseHint: true });
7197
+ printReferenceSummary("agent", agent, { showReuseHint: true });
7198
+ if (meeting) {
7199
+ printReferenceSummary("meeting", meeting, { showReuseHint: true });
7200
+ }
7201
+ printReferenceSummary("work_item", claimedWorkItem, { showReuseHint: true });
7202
+ printReferenceSummary("invoice", invoice, { showReuseHint: true });
7203
+ printReferenceSummary("bank_account", bankAccount, { showReuseHint: true });
6496
7204
  printJson(result);
6497
7205
  } catch (err) {
6498
7206
  printError(`Failed to seed demo: ${err}`);
@@ -6506,6 +7214,8 @@ var init_demo = __esm({
6506
7214
  init_api_client();
6507
7215
  init_output();
6508
7216
  init_spinner();
7217
+ init_references();
7218
+ init_formation_automation();
6509
7219
  }
6510
7220
  });
6511
7221
 
@@ -6535,7 +7245,15 @@ async function feedbackCommand(message, opts) {
6535
7245
  console.log(`
6536
7246
  ${chalk13.green("\u2713")} Feedback submitted (${chalk13.dim(result.feedback_id)})`);
6537
7247
  } catch (err) {
6538
- printError("Failed to submit feedback", err);
7248
+ const detail = String(err);
7249
+ if (detail.includes("404")) {
7250
+ printError(
7251
+ `Failed to submit feedback: ${detail}
7252
+ This server does not expose /v1/feedback. Local api-rs dev servers currently do not support feedback submission.`
7253
+ );
7254
+ } else {
7255
+ printError(`Failed to submit feedback: ${detail}`);
7256
+ }
6539
7257
  process.exit(1);
6540
7258
  }
6541
7259
  }
@@ -6699,6 +7417,12 @@ var TAX_DOCUMENT_TYPE_CHOICES = [
6699
7417
  "w2",
6700
7418
  "form_w2"
6701
7419
  ];
7420
+ var FINALIZE_ITEM_STATUS_CHOICES = [
7421
+ "discussed",
7422
+ "voted",
7423
+ "tabled",
7424
+ "withdrawn"
7425
+ ];
6702
7426
  var program = new Command();
6703
7427
  program.name("corp").description("corp \u2014 Corporate governance from the terminal").version(pkg.version);
6704
7428
  program.command("setup").description("Interactive setup wizard").action(async () => {
@@ -6949,7 +7673,10 @@ capTableCmd.command("approve-valuation <valuation-ref>").option("--resolution-id
6949
7673
  json: inheritOption(opts.json, parent.json)
6950
7674
  });
6951
7675
  });
6952
- var financeCmd = program.command("finance").description("Invoicing, payroll, payments, banking").option("--entity-id <ref>", "Entity reference (ID, short ID, @last, or unique name)").option("--json", "Output as JSON");
7676
+ var financeCmd = program.command("finance").description("Invoicing, payroll, payments, banking").option("--entity-id <ref>", "Entity reference (ID, short ID, @last, or unique name)").option("--json", "Output as JSON").action(async (opts) => {
7677
+ const { financeSummaryCommand: financeSummaryCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
7678
+ await financeSummaryCommand2(opts);
7679
+ });
6953
7680
  financeCmd.command("invoices").option("--json", "Output as JSON").description("List invoices").action(async (opts, cmd) => {
6954
7681
  const parent = cmd.parent.opts();
6955
7682
  const { financeInvoicesCommand: financeInvoicesCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
@@ -7173,7 +7900,12 @@ governanceCmd.command("agenda-items <meeting-ref>").description("List agenda ite
7173
7900
  const { listAgendaItemsCommand: listAgendaItemsCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
7174
7901
  await listAgendaItemsCommand2(meetingId, { entityId: parent.entityId, json: parent.json });
7175
7902
  });
7176
- governanceCmd.command("finalize-item <meeting-ref> <item-ref>").requiredOption("--status <status>", "Status: voted, discussed, tabled, withdrawn").option("--json", "Output as JSON").option("--dry-run", "Show the request without finalizing the item").description("Finalize an agenda item").action(async (meetingId, itemId, opts, cmd) => {
7903
+ governanceCmd.command("finalize-item <meeting-ref> <item-ref>").addOption(
7904
+ new Option(
7905
+ "--status <status>",
7906
+ `Status (${FINALIZE_ITEM_STATUS_CHOICES.join(", ")})`
7907
+ ).choices([...FINALIZE_ITEM_STATUS_CHOICES]).makeOptionMandatory()
7908
+ ).option("--json", "Output as JSON").option("--dry-run", "Show the request without finalizing the item").description("Finalize an agenda item").action(async (meetingId, itemId, opts, cmd) => {
7177
7909
  const parent = cmd.parent.opts();
7178
7910
  const { finalizeAgendaItemCommand: finalizeAgendaItemCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
7179
7911
  await finalizeAgendaItemCommand2(meetingId, itemId, {
@@ -7209,6 +7941,24 @@ documentsCmd.command("signing-link <doc-ref>").option("--entity-id <ref>", "Enti
7209
7941
  const { documentsSigningLinkCommand: documentsSigningLinkCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
7210
7942
  await documentsSigningLinkCommand2(docId, { entityId: opts.entityId ?? parent.entityId });
7211
7943
  });
7944
+ documentsCmd.command("sign <doc-ref>").option("--entity-id <ref>", "Entity reference (overrides active entity and parent command)").option("--signer-name <name>", "Manual signer name").option("--signer-role <role>", "Manual signer role").option("--signer-email <email>", "Manual signer email").option("--signature-text <text>", "Manual signature text (defaults to signer name)").option("--json", "Output as JSON").description("Sign a formation document, or auto-sign all missing required signatures").action(async (docId, opts, cmd) => {
7945
+ const parent = cmd.parent.opts();
7946
+ const { documentsSignCommand: documentsSignCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
7947
+ await documentsSignCommand2(docId, {
7948
+ ...opts,
7949
+ entityId: opts.entityId ?? parent.entityId,
7950
+ json: inheritOption(opts.json, parent.json)
7951
+ });
7952
+ });
7953
+ documentsCmd.command("sign-all").option("--entity-id <ref>", "Entity reference (overrides active entity and parent command)").option("--json", "Output as JSON").description("Auto-sign all outstanding formation documents for an entity").action(async (opts, cmd) => {
7954
+ const parent = cmd.parent.opts();
7955
+ const { documentsSignAllCommand: documentsSignAllCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
7956
+ await documentsSignAllCommand2({
7957
+ ...opts,
7958
+ entityId: opts.entityId ?? parent.entityId,
7959
+ json: inheritOption(opts.json, parent.json)
7960
+ });
7961
+ });
7212
7962
  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)").option("--base-salary <amount>", "Employment offer base salary (for employment_offer)").option("--param <key=value>", "Additional template parameter (repeatable)", (value, values) => [...values, value], []).option("--json", "Output as JSON").description("Generate a contract from a template").action(async (opts, cmd) => {
7213
7963
  const parent = cmd.parent.opts();
7214
7964
  const { documentsGenerateCommand: documentsGenerateCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
@@ -7218,7 +7968,7 @@ documentsCmd.command("generate").requiredOption("--template <type>", "Template t
7218
7968
  json: inheritOption(opts.json, parent.json)
7219
7969
  });
7220
7970
  });
7221
- documentsCmd.command("preview-pdf").requiredOption("--definition-id <id>", "AST document definition ID (e.g. 'bylaws')").option("--document-id <id>", "Deprecated alias for --definition-id").description("Validate and print the authenticated PDF preview URL for a governance document").action(async (opts, cmd) => {
7971
+ documentsCmd.command("preview-pdf").option("--definition-id <id>", "AST document definition ID (e.g. 'bylaws')").option("--document-id <id>", "Deprecated alias for --definition-id").description("Validate and print the authenticated PDF preview URL for a governance document").action(async (opts, cmd) => {
7222
7972
  const parent = cmd.parent.opts();
7223
7973
  const { documentsPreviewPdfCommand: documentsPreviewPdfCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
7224
7974
  await documentsPreviewPdfCommand2({
@@ -7403,10 +8153,8 @@ billingCmd.command("upgrade").option("--plan <plan>", "Plan ID to upgrade to (fr
7403
8153
  await billingUpgradeCommand2(opts);
7404
8154
  });
7405
8155
  program.command("approvals").description("Approvals are managed through governance meetings and execution intents").action(async () => {
7406
- const { printError: printError2 } = await Promise.resolve().then(() => (init_output(), output_exports));
7407
- printError2(
7408
- "Approvals are managed through governance meetings.\n Use: corp governance convene ... to schedule a board meeting\n Use: corp governance vote <meeting-ref> <item-ref> ... to cast votes"
7409
- );
8156
+ const { approvalsListCommand: approvalsListCommand2 } = await Promise.resolve().then(() => (init_approvals(), approvals_exports));
8157
+ await approvalsListCommand2({});
7410
8158
  });
7411
8159
  var formCmd = program.command("form").description("Form a new entity with founders and cap table").option("--entity-type <type>", "Entity type (llc, c_corp)").option("--legal-name <name>", "Legal name").option("--jurisdiction <jurisdiction>", "Jurisdiction (e.g. US-DE, US-WY)").option("--member <member>", "Founder as 'name,email,role[,pct[,address[,officer_title[,is_incorporator]]]]' with address as street|city|state|zip, or key=value pairs like 'name=...,email=...,role=...,officer_title=cto,is_incorporator=true,address=street|city|state|zip' (repeatable)", (v, a) => [...a, v], []).option("--member-json <json>", "Founder JSON object (repeatable)", (v, a) => [...a, v], []).option("--members-file <path>", 'Path to a JSON array of founders or {"members": [...]}').option("--address <address>", "Company address as 'street,city,state,zip'").option("--fiscal-year-end <date>", "Fiscal year end (MM-DD)", "12-31").option("--s-corp", "Elect S-Corp status").option("--transfer-restrictions", "Enable transfer restrictions").option("--rofr", "Enable right of first refusal").option("--json", "Output as JSON").option("--dry-run", "Show the request without creating the entity").action(async (opts) => {
7412
8160
  if (opts.entityType && !opts.type) opts.type = opts.entityType;
@@ -7415,11 +8163,13 @@ var formCmd = program.command("form").description("Form a new entity with founde
7415
8163
  await formCommand2(opts);
7416
8164
  });
7417
8165
  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'").option("--json", "Output as JSON").option("--dry-run", "Show the request without creating the pending entity").action(async (opts, cmd) => {
8166
+ const parent = cmd.parent.opts();
7418
8167
  const { formCreateCommand: formCreateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
7419
8168
  await formCreateCommand2({
7420
8169
  ...opts,
7421
- json: inheritOption(opts.json, cmd.parent.opts().json),
7422
- dryRun: inheritOption(opts.dryRun, cmd.parent.opts().dryRun)
8170
+ jurisdiction: inheritOption(opts.jurisdiction, parent.jurisdiction),
8171
+ json: inheritOption(opts.json, parent.json),
8172
+ dryRun: inheritOption(opts.dryRun, parent.dryRun)
7423
8173
  });
7424
8174
  });
7425
8175
  formCmd.command("add-founder <entity-ref>").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").addOption(new Option("--officer-title <title>", "Officer title (corporations only)").choices(["ceo", "cfo", "cto", "coo", "secretary", "treasurer", "president", "vp", "other"])).option("--incorporator", "Mark as sole incorporator (corporations only)").option("--address <address>", "Founder address as 'street,city,state,zip'").option("--json", "Output as JSON").option("--dry-run", "Show the request without adding the founder").action(async (entityId, opts, cmd) => {
@@ -7438,11 +8188,19 @@ formCmd.command("finalize <entity-ref>").description("Finalize formation and gen
7438
8188
  dryRun: inheritOption(opts.dryRun, cmd.parent.opts().dryRun)
7439
8189
  });
7440
8190
  });
8191
+ formCmd.command("activate <entity-ref>").description("Programmatically sign formation documents and advance an entity to active").option("--evidence-uri <uri>", "Registered-agent consent evidence URI placeholder").option("--evidence-type <type>", "Registered-agent consent evidence type", "generated").option("--filing-id <id>", "External filing identifier to record").option("--receipt-reference <ref>", "External receipt reference to record").option("--ein <ein>", "EIN to confirm (defaults to a deterministic simulated EIN)").option("--json", "Output as JSON").option("--dry-run", "Show the activation plan without mutating").action(async (entityId, opts, cmd) => {
8192
+ const { formActivateCommand: formActivateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
8193
+ await formActivateCommand2(entityId, {
8194
+ ...opts,
8195
+ json: inheritOption(opts.json, cmd.parent.opts().json),
8196
+ dryRun: inheritOption(opts.dryRun, cmd.parent.opts().dryRun)
8197
+ });
8198
+ });
7441
8199
  program.command("api-keys").description("List API keys").option("--json", "Output as JSON").action(async (opts) => {
7442
8200
  const { apiKeysCommand: apiKeysCommand2 } = await Promise.resolve().then(() => (init_api_keys(), api_keys_exports));
7443
8201
  await apiKeysCommand2(opts);
7444
8202
  });
7445
- program.command("demo").description("Seed a fully-populated demo corporation").requiredOption("--name <name>", "Corporation name").action(async (opts) => {
8203
+ program.command("demo").description("Create a usable demo workspace environment").requiredOption("--name <name>", "Corporation name").option("--scenario <scenario>", "Scenario to create (startup, llc, restaurant)", "startup").option("--minimal", "Use the minimal server-side demo seed instead of the full CLI workflow").option("--json", "Output as JSON").action(async (opts) => {
7446
8204
  const { demoCommand: demoCommand2 } = await Promise.resolve().then(() => (init_demo(), demo_exports));
7447
8205
  await demoCommand2(opts);
7448
8206
  });