@thecorporation/cli 1.0.5 → 26.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -2
- package/dist/index.js +670 -62
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -1154,7 +1154,7 @@ ${chalk2.bold("Chat Slash Commands")}
|
|
|
1154
1154
|
break;
|
|
1155
1155
|
}
|
|
1156
1156
|
for (const tc of response.tool_calls) {
|
|
1157
|
-
console.log(chalk2.dim(` ${isWriteTool(tc.name) ? "\u2699" : "\u2139"} ${tc.name}(${JSON.stringify(tc.arguments).slice(0, 80)})`));
|
|
1157
|
+
console.log(chalk2.dim(` ${isWriteTool(tc.name, tc.arguments) ? "\u2699" : "\u2139"} ${tc.name}(${JSON.stringify(tc.arguments).slice(0, 80)})`));
|
|
1158
1158
|
const result = await executeTool(tc.name, tc.arguments, client);
|
|
1159
1159
|
const short = result.length > 200 ? result.slice(0, 197) + "..." : result;
|
|
1160
1160
|
console.log(chalk2.dim(` => ${short}`));
|
|
@@ -1382,12 +1382,18 @@ var init_contacts = __esm({
|
|
|
1382
1382
|
// src/commands/cap-table.ts
|
|
1383
1383
|
var cap_table_exports = {};
|
|
1384
1384
|
__export(cap_table_exports, {
|
|
1385
|
+
addSecurityCommand: () => addSecurityCommand,
|
|
1386
|
+
approveValuationCommand: () => approveValuationCommand,
|
|
1385
1387
|
capTableCommand: () => capTableCommand,
|
|
1388
|
+
createValuationCommand: () => createValuationCommand,
|
|
1386
1389
|
distributeCommand: () => distributeCommand,
|
|
1387
1390
|
fourOhNineACommand: () => fourOhNineACommand,
|
|
1388
1391
|
issueEquityCommand: () => issueEquityCommand,
|
|
1392
|
+
issueRoundCommand: () => issueRoundCommand,
|
|
1389
1393
|
issueSafeCommand: () => issueSafeCommand,
|
|
1390
1394
|
safesCommand: () => safesCommand,
|
|
1395
|
+
startRoundCommand: () => startRoundCommand,
|
|
1396
|
+
submitValuationCommand: () => submitValuationCommand,
|
|
1391
1397
|
transferSharesCommand: () => transferSharesCommand,
|
|
1392
1398
|
transfersCommand: () => transfersCommand,
|
|
1393
1399
|
valuationsCommand: () => valuationsCommand
|
|
@@ -1547,6 +1553,108 @@ async function distributeCommand(opts) {
|
|
|
1547
1553
|
process.exit(1);
|
|
1548
1554
|
}
|
|
1549
1555
|
}
|
|
1556
|
+
async function startRoundCommand(opts) {
|
|
1557
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1558
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1559
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1560
|
+
try {
|
|
1561
|
+
const result = await client.startEquityRound({
|
|
1562
|
+
entity_id: eid,
|
|
1563
|
+
name: opts.name,
|
|
1564
|
+
issuer_legal_entity_id: opts.issuerLegalEntityId
|
|
1565
|
+
});
|
|
1566
|
+
printSuccess(`Round started: ${result.round_id ?? "OK"}`);
|
|
1567
|
+
printJson(result);
|
|
1568
|
+
} catch (err) {
|
|
1569
|
+
printError(`Failed to start round: ${err}`);
|
|
1570
|
+
process.exit(1);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
async function addSecurityCommand(opts) {
|
|
1574
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1575
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1576
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1577
|
+
try {
|
|
1578
|
+
const body = {
|
|
1579
|
+
entity_id: eid,
|
|
1580
|
+
instrument_id: opts.instrumentId,
|
|
1581
|
+
quantity: opts.quantity,
|
|
1582
|
+
recipient_name: opts.recipientName
|
|
1583
|
+
};
|
|
1584
|
+
if (opts.holderId) body.holder_id = opts.holderId;
|
|
1585
|
+
if (opts.email) body.email = opts.email;
|
|
1586
|
+
if (opts.principalCents) body.principal_cents = opts.principalCents;
|
|
1587
|
+
if (opts.grantType) body.grant_type = opts.grantType;
|
|
1588
|
+
const result = await client.addRoundSecurity(opts.roundId, body);
|
|
1589
|
+
printSuccess(`Security added for ${opts.recipientName}`);
|
|
1590
|
+
printJson(result);
|
|
1591
|
+
} catch (err) {
|
|
1592
|
+
printError(`Failed to add security: ${err}`);
|
|
1593
|
+
process.exit(1);
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
async function issueRoundCommand(opts) {
|
|
1597
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1598
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1599
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1600
|
+
try {
|
|
1601
|
+
const result = await client.issueRound(opts.roundId, { entity_id: eid });
|
|
1602
|
+
printSuccess("Round issued and closed");
|
|
1603
|
+
printJson(result);
|
|
1604
|
+
} catch (err) {
|
|
1605
|
+
printError(`Failed to issue round: ${err}`);
|
|
1606
|
+
process.exit(1);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
async function createValuationCommand(opts) {
|
|
1610
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1611
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1612
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1613
|
+
try {
|
|
1614
|
+
const body = {
|
|
1615
|
+
entity_id: eid,
|
|
1616
|
+
valuation_type: opts.type,
|
|
1617
|
+
effective_date: opts.date,
|
|
1618
|
+
methodology: opts.methodology
|
|
1619
|
+
};
|
|
1620
|
+
if (opts.fmv != null) body.fmv_per_share_cents = opts.fmv;
|
|
1621
|
+
if (opts.enterpriseValue != null) body.enterprise_value_cents = opts.enterpriseValue;
|
|
1622
|
+
const result = await client.createValuation(body);
|
|
1623
|
+
printSuccess(`Valuation created: ${result.valuation_id ?? "OK"}`);
|
|
1624
|
+
printJson(result);
|
|
1625
|
+
} catch (err) {
|
|
1626
|
+
printError(`Failed to create valuation: ${err}`);
|
|
1627
|
+
process.exit(1);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
async function submitValuationCommand(opts) {
|
|
1631
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1632
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1633
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1634
|
+
try {
|
|
1635
|
+
const result = await client.submitValuationForApproval(opts.valuationId, eid);
|
|
1636
|
+
printSuccess(`Valuation submitted for approval: ${result.valuation_id ?? "OK"}`);
|
|
1637
|
+
if (result.meeting_id) console.log(` Meeting: ${result.meeting_id}`);
|
|
1638
|
+
if (result.agenda_item_id) console.log(` Agenda Item: ${result.agenda_item_id}`);
|
|
1639
|
+
printJson(result);
|
|
1640
|
+
} catch (err) {
|
|
1641
|
+
printError(`Failed to submit valuation: ${err}`);
|
|
1642
|
+
process.exit(1);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
async function approveValuationCommand(opts) {
|
|
1646
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1647
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1648
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1649
|
+
try {
|
|
1650
|
+
const result = await client.approveValuation(opts.valuationId, eid, opts.resolutionId);
|
|
1651
|
+
printSuccess(`Valuation approved: ${result.valuation_id ?? "OK"}`);
|
|
1652
|
+
printJson(result);
|
|
1653
|
+
} catch (err) {
|
|
1654
|
+
printError(`Failed to approve valuation: ${err}`);
|
|
1655
|
+
process.exit(1);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1550
1658
|
function print409a(data) {
|
|
1551
1659
|
console.log(chalk5.green("\u2500".repeat(40)));
|
|
1552
1660
|
console.log(chalk5.green.bold(" 409A Valuation"));
|
|
@@ -1693,12 +1801,19 @@ var init_finance = __esm({
|
|
|
1693
1801
|
// src/commands/governance.ts
|
|
1694
1802
|
var governance_exports = {};
|
|
1695
1803
|
__export(governance_exports, {
|
|
1804
|
+
adjournMeetingCommand: () => adjournMeetingCommand,
|
|
1805
|
+
cancelMeetingCommand: () => cancelMeetingCommand,
|
|
1806
|
+
computeResolutionCommand: () => computeResolutionCommand,
|
|
1807
|
+
finalizeAgendaItemCommand: () => finalizeAgendaItemCommand,
|
|
1696
1808
|
governanceConveneCommand: () => governanceConveneCommand,
|
|
1697
1809
|
governanceListCommand: () => governanceListCommand,
|
|
1698
1810
|
governanceMeetingsCommand: () => governanceMeetingsCommand,
|
|
1699
1811
|
governanceResolutionsCommand: () => governanceResolutionsCommand,
|
|
1700
1812
|
governanceSeatsCommand: () => governanceSeatsCommand,
|
|
1701
|
-
governanceVoteCommand: () => governanceVoteCommand
|
|
1813
|
+
governanceVoteCommand: () => governanceVoteCommand,
|
|
1814
|
+
listAgendaItemsCommand: () => listAgendaItemsCommand,
|
|
1815
|
+
sendNoticeCommand: () => sendNoticeCommand,
|
|
1816
|
+
writtenConsentCommand: () => writtenConsentCommand
|
|
1702
1817
|
});
|
|
1703
1818
|
async function governanceListCommand(opts) {
|
|
1704
1819
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
@@ -1789,6 +1904,108 @@ async function governanceVoteCommand(meetingId, itemId, opts) {
|
|
|
1789
1904
|
process.exit(1);
|
|
1790
1905
|
}
|
|
1791
1906
|
}
|
|
1907
|
+
async function sendNoticeCommand(meetingId, opts) {
|
|
1908
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1909
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1910
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1911
|
+
try {
|
|
1912
|
+
const result = await client.sendNotice(meetingId, eid);
|
|
1913
|
+
printSuccess(`Notice sent for meeting ${meetingId}`);
|
|
1914
|
+
printJson(result);
|
|
1915
|
+
} catch (err) {
|
|
1916
|
+
printError(`Failed to send notice: ${err}`);
|
|
1917
|
+
process.exit(1);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
async function adjournMeetingCommand(meetingId, opts) {
|
|
1921
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1922
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1923
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1924
|
+
try {
|
|
1925
|
+
const result = await client.adjournMeeting(meetingId, eid);
|
|
1926
|
+
printSuccess(`Meeting ${meetingId} adjourned`);
|
|
1927
|
+
printJson(result);
|
|
1928
|
+
} catch (err) {
|
|
1929
|
+
printError(`Failed to adjourn meeting: ${err}`);
|
|
1930
|
+
process.exit(1);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
async function cancelMeetingCommand(meetingId, opts) {
|
|
1934
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1935
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1936
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1937
|
+
try {
|
|
1938
|
+
const result = await client.cancelMeeting(meetingId, eid);
|
|
1939
|
+
printSuccess(`Meeting ${meetingId} cancelled`);
|
|
1940
|
+
printJson(result);
|
|
1941
|
+
} catch (err) {
|
|
1942
|
+
printError(`Failed to cancel meeting: ${err}`);
|
|
1943
|
+
process.exit(1);
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
async function finalizeAgendaItemCommand(meetingId, itemId, opts) {
|
|
1947
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1948
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1949
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1950
|
+
try {
|
|
1951
|
+
const result = await client.finalizeAgendaItem(meetingId, itemId, {
|
|
1952
|
+
entity_id: eid,
|
|
1953
|
+
status: opts.status
|
|
1954
|
+
});
|
|
1955
|
+
printSuccess(`Agenda item ${itemId} finalized as ${opts.status}`);
|
|
1956
|
+
printJson(result);
|
|
1957
|
+
} catch (err) {
|
|
1958
|
+
printError(`Failed to finalize agenda item: ${err}`);
|
|
1959
|
+
process.exit(1);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
async function computeResolutionCommand(meetingId, itemId, opts) {
|
|
1963
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1964
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1965
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1966
|
+
try {
|
|
1967
|
+
const result = await client.computeResolution(meetingId, itemId, eid, {
|
|
1968
|
+
resolution_text: opts.text
|
|
1969
|
+
});
|
|
1970
|
+
printSuccess(`Resolution computed for agenda item ${itemId}`);
|
|
1971
|
+
printJson(result);
|
|
1972
|
+
} catch (err) {
|
|
1973
|
+
printError(`Failed to compute resolution: ${err}`);
|
|
1974
|
+
process.exit(1);
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
async function writtenConsentCommand(opts) {
|
|
1978
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1979
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1980
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1981
|
+
try {
|
|
1982
|
+
const result = await client.writtenConsent({
|
|
1983
|
+
entity_id: eid,
|
|
1984
|
+
body_id: opts.body,
|
|
1985
|
+
title: opts.title,
|
|
1986
|
+
description: opts.description
|
|
1987
|
+
});
|
|
1988
|
+
printSuccess(`Written consent created: ${result.meeting_id ?? "OK"}`);
|
|
1989
|
+
printJson(result);
|
|
1990
|
+
} catch (err) {
|
|
1991
|
+
printError(`Failed to create written consent: ${err}`);
|
|
1992
|
+
process.exit(1);
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
async function listAgendaItemsCommand(meetingId, opts) {
|
|
1996
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
1997
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
1998
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
1999
|
+
try {
|
|
2000
|
+
const items = await client.listAgendaItems(meetingId, eid);
|
|
2001
|
+
if (opts.json) printJson(items);
|
|
2002
|
+
else if (items.length === 0) console.log("No agenda items found.");
|
|
2003
|
+
else printJson(items);
|
|
2004
|
+
} catch (err) {
|
|
2005
|
+
printError(`Failed to list agenda items: ${err}`);
|
|
2006
|
+
process.exit(1);
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
1792
2009
|
var init_governance = __esm({
|
|
1793
2010
|
"src/commands/governance.ts"() {
|
|
1794
2011
|
"use strict";
|
|
@@ -1803,6 +2020,7 @@ var documents_exports = {};
|
|
|
1803
2020
|
__export(documents_exports, {
|
|
1804
2021
|
documentsGenerateCommand: () => documentsGenerateCommand,
|
|
1805
2022
|
documentsListCommand: () => documentsListCommand,
|
|
2023
|
+
documentsPreviewPdfCommand: () => documentsPreviewPdfCommand,
|
|
1806
2024
|
documentsSigningLinkCommand: () => documentsSigningLinkCommand
|
|
1807
2025
|
});
|
|
1808
2026
|
async function documentsListCommand(opts) {
|
|
@@ -1848,6 +2066,15 @@ async function documentsGenerateCommand(opts) {
|
|
|
1848
2066
|
process.exit(1);
|
|
1849
2067
|
}
|
|
1850
2068
|
}
|
|
2069
|
+
async function documentsPreviewPdfCommand(opts) {
|
|
2070
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2071
|
+
const eid = resolveEntityId(cfg, opts.entityId);
|
|
2072
|
+
const apiUrl = cfg.api_url.replace(/\/+$/, "");
|
|
2073
|
+
const qs = new URLSearchParams({ entity_id: eid, document_id: opts.documentId }).toString();
|
|
2074
|
+
const url = `${apiUrl}/v1/documents/preview/pdf?${qs}`;
|
|
2075
|
+
printSuccess(`Preview PDF URL: ${url}`);
|
|
2076
|
+
console.log("Use your API key to authenticate the download.");
|
|
2077
|
+
}
|
|
1851
2078
|
var init_documents = __esm({
|
|
1852
2079
|
"src/commands/documents.ts"() {
|
|
1853
2080
|
"use strict";
|
|
@@ -2200,9 +2427,215 @@ var init_approvals = __esm({
|
|
|
2200
2427
|
// src/commands/form.ts
|
|
2201
2428
|
var form_exports = {};
|
|
2202
2429
|
__export(form_exports, {
|
|
2203
|
-
|
|
2430
|
+
formAddFounderCommand: () => formAddFounderCommand,
|
|
2431
|
+
formCommand: () => formCommand,
|
|
2432
|
+
formCreateCommand: () => formCreateCommand,
|
|
2433
|
+
formFinalizeCommand: () => formFinalizeCommand
|
|
2204
2434
|
});
|
|
2205
|
-
import { input as input2, select } from "@inquirer/prompts";
|
|
2435
|
+
import { input as input2, select, confirm as confirm2, number } from "@inquirer/prompts";
|
|
2436
|
+
import chalk7 from "chalk";
|
|
2437
|
+
import Table3 from "cli-table3";
|
|
2438
|
+
function isCorp(entityType) {
|
|
2439
|
+
return entityType === "c_corp" || entityType === "s_corp" || entityType === "corporation";
|
|
2440
|
+
}
|
|
2441
|
+
function sectionHeader(title) {
|
|
2442
|
+
console.log();
|
|
2443
|
+
console.log(chalk7.blue("\u2500".repeat(50)));
|
|
2444
|
+
console.log(chalk7.blue.bold(` ${title}`));
|
|
2445
|
+
console.log(chalk7.blue("\u2500".repeat(50)));
|
|
2446
|
+
}
|
|
2447
|
+
async function promptAddress() {
|
|
2448
|
+
const street = await input2({ message: " Street address" });
|
|
2449
|
+
const city = await input2({ message: " City" });
|
|
2450
|
+
const state = await input2({ message: " State (2-letter)", default: "DE" });
|
|
2451
|
+
const zip = await input2({ message: " ZIP code" });
|
|
2452
|
+
return { street, city, state, zip };
|
|
2453
|
+
}
|
|
2454
|
+
async function phaseEntityDetails(opts, serverCfg, scripted) {
|
|
2455
|
+
if (!scripted) sectionHeader("Phase 1: Entity Details");
|
|
2456
|
+
let entityType = opts.type;
|
|
2457
|
+
if (!entityType) {
|
|
2458
|
+
if (scripted) {
|
|
2459
|
+
entityType = "llc";
|
|
2460
|
+
} else {
|
|
2461
|
+
const types = serverCfg.entity_types ?? ["llc", "c_corp"];
|
|
2462
|
+
entityType = await select({
|
|
2463
|
+
message: "Entity type",
|
|
2464
|
+
choices: types.map((t) => ({
|
|
2465
|
+
value: t,
|
|
2466
|
+
name: t === "c_corp" ? "C Corporation" : t === "s_corp" ? "S Corporation" : t.toUpperCase()
|
|
2467
|
+
}))
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
let name = opts.name;
|
|
2472
|
+
if (!name) {
|
|
2473
|
+
if (scripted) {
|
|
2474
|
+
printError("--name is required in scripted mode");
|
|
2475
|
+
process.exit(1);
|
|
2476
|
+
}
|
|
2477
|
+
name = await input2({ message: "Legal name" });
|
|
2478
|
+
}
|
|
2479
|
+
let jurisdiction = opts.jurisdiction;
|
|
2480
|
+
if (!jurisdiction) {
|
|
2481
|
+
const defaultJ = entityType === "llc" ? "US-WY" : "US-DE";
|
|
2482
|
+
if (scripted) {
|
|
2483
|
+
jurisdiction = defaultJ;
|
|
2484
|
+
} else {
|
|
2485
|
+
jurisdiction = await input2({ message: "Jurisdiction", default: defaultJ });
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
let companyAddress;
|
|
2489
|
+
if (opts.address) {
|
|
2490
|
+
const parts = opts.address.split(",").map((p) => p.trim());
|
|
2491
|
+
if (parts.length === 4) {
|
|
2492
|
+
companyAddress = { street: parts[0], city: parts[1], state: parts[2], zip: parts[3] };
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
if (!companyAddress && !scripted) {
|
|
2496
|
+
const wantAddress = await confirm2({ message: "Add company address?", default: false });
|
|
2497
|
+
if (wantAddress) {
|
|
2498
|
+
companyAddress = await promptAddress();
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
const fiscalYearEnd = opts.fiscalYearEnd ?? "12-31";
|
|
2502
|
+
let sCorpElection = opts.sCorp ?? false;
|
|
2503
|
+
if (!scripted && isCorp(entityType) && opts.sCorp === void 0) {
|
|
2504
|
+
sCorpElection = await confirm2({ message: "S-Corp election?", default: false });
|
|
2505
|
+
}
|
|
2506
|
+
return { entityType, name, jurisdiction, companyAddress, fiscalYearEnd, sCorpElection };
|
|
2507
|
+
}
|
|
2508
|
+
async function phasePeople(opts, entityType, scripted) {
|
|
2509
|
+
if (!scripted) sectionHeader("Phase 2: Founders & Officers");
|
|
2510
|
+
const founders = [];
|
|
2511
|
+
if (scripted) {
|
|
2512
|
+
for (const m of opts.member) {
|
|
2513
|
+
const parts = m.split(",").map((p) => p.trim());
|
|
2514
|
+
if (parts.length < 3) {
|
|
2515
|
+
printError(`Invalid member format: ${m}. Expected: name,email,role[,pct]`);
|
|
2516
|
+
process.exit(1);
|
|
2517
|
+
}
|
|
2518
|
+
const f = { name: parts[0], email: parts[1], role: parts[2] };
|
|
2519
|
+
if (parts.length >= 4) f.ownership_pct = parseFloat(parts[3]);
|
|
2520
|
+
founders.push(f);
|
|
2521
|
+
}
|
|
2522
|
+
return founders;
|
|
2523
|
+
}
|
|
2524
|
+
const founderCount = await number({ message: "Number of founders (1-6)", default: 1 }) ?? 1;
|
|
2525
|
+
for (let i = 0; i < founderCount; i++) {
|
|
2526
|
+
console.log(chalk7.dim(`
|
|
2527
|
+
Founder ${i + 1} of ${founderCount}:`));
|
|
2528
|
+
const name = await input2({ message: ` Name` });
|
|
2529
|
+
const email = await input2({ message: ` Email` });
|
|
2530
|
+
let role = "member";
|
|
2531
|
+
if (isCorp(entityType)) {
|
|
2532
|
+
role = await select({
|
|
2533
|
+
message: " Role",
|
|
2534
|
+
choices: [
|
|
2535
|
+
{ value: "director", name: "Director" },
|
|
2536
|
+
{ value: "officer", name: "Officer" },
|
|
2537
|
+
{ value: "member", name: "Shareholder only" }
|
|
2538
|
+
]
|
|
2539
|
+
});
|
|
2540
|
+
}
|
|
2541
|
+
const wantAddress = await confirm2({ message: " Add address?", default: false });
|
|
2542
|
+
const address = wantAddress ? await promptAddress() : void 0;
|
|
2543
|
+
let officerTitle;
|
|
2544
|
+
if (isCorp(entityType)) {
|
|
2545
|
+
const wantOfficer = role === "officer" || await confirm2({ message: " Assign officer title?", default: i === 0 });
|
|
2546
|
+
if (wantOfficer) {
|
|
2547
|
+
officerTitle = await select({
|
|
2548
|
+
message: " Officer title",
|
|
2549
|
+
choices: [
|
|
2550
|
+
{ value: "ceo", name: "CEO" },
|
|
2551
|
+
{ value: "cfo", name: "CFO" },
|
|
2552
|
+
{ value: "secretary", name: "Secretary" },
|
|
2553
|
+
{ value: "president", name: "President" },
|
|
2554
|
+
{ value: "vp", name: "VP" }
|
|
2555
|
+
]
|
|
2556
|
+
});
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
let isIncorporator = false;
|
|
2560
|
+
if (isCorp(entityType) && i === 0 && founderCount === 1) {
|
|
2561
|
+
isIncorporator = true;
|
|
2562
|
+
} else if (isCorp(entityType)) {
|
|
2563
|
+
isIncorporator = await confirm2({ message: " Designate as sole incorporator?", default: i === 0 });
|
|
2564
|
+
}
|
|
2565
|
+
founders.push({ name, email, role, address, officer_title: officerTitle, is_incorporator: isIncorporator });
|
|
2566
|
+
}
|
|
2567
|
+
return founders;
|
|
2568
|
+
}
|
|
2569
|
+
async function phaseStock(opts, entityType, founders, scripted) {
|
|
2570
|
+
if (!scripted) sectionHeader("Phase 3: Equity & Finalize");
|
|
2571
|
+
const transferRestrictions = opts.transferRestrictions ?? (!scripted && isCorp(entityType) ? await confirm2({ message: "Transfer restrictions on shares?", default: true }) : isCorp(entityType));
|
|
2572
|
+
const rofr = opts.rofr ?? (!scripted && isCorp(entityType) ? await confirm2({ message: "Right of first refusal?", default: true }) : isCorp(entityType));
|
|
2573
|
+
if (!scripted) {
|
|
2574
|
+
for (const f of founders) {
|
|
2575
|
+
console.log(chalk7.dim(`
|
|
2576
|
+
Equity for ${f.name}:`));
|
|
2577
|
+
if (isCorp(entityType)) {
|
|
2578
|
+
const shares = await number({ message: ` Shares to purchase`, default: 0 });
|
|
2579
|
+
f.shares_purchased = shares ?? 0;
|
|
2580
|
+
if (f.shares_purchased === 0) {
|
|
2581
|
+
const pct = await number({ message: ` Ownership % (1-100)`, default: founders.length === 1 ? 100 : 0 });
|
|
2582
|
+
f.ownership_pct = pct ?? 0;
|
|
2583
|
+
}
|
|
2584
|
+
} else {
|
|
2585
|
+
const pct = await number({
|
|
2586
|
+
message: ` Ownership % (1-100)`,
|
|
2587
|
+
default: founders.length === 1 ? 100 : 0
|
|
2588
|
+
});
|
|
2589
|
+
f.ownership_pct = pct ?? 0;
|
|
2590
|
+
}
|
|
2591
|
+
if (isCorp(entityType)) {
|
|
2592
|
+
const wantVesting = await confirm2({ message: " Add vesting schedule?", default: false });
|
|
2593
|
+
if (wantVesting) {
|
|
2594
|
+
const totalMonths = await number({ message: " Total vesting months", default: 48 }) ?? 48;
|
|
2595
|
+
const cliffMonths = await number({ message: " Cliff months", default: 12 }) ?? 12;
|
|
2596
|
+
const acceleration = await select({
|
|
2597
|
+
message: " Acceleration",
|
|
2598
|
+
choices: [
|
|
2599
|
+
{ value: "none", name: "None" },
|
|
2600
|
+
{ value: "single_trigger", name: "Single trigger" },
|
|
2601
|
+
{ value: "double_trigger", name: "Double trigger" }
|
|
2602
|
+
]
|
|
2603
|
+
});
|
|
2604
|
+
f.vesting = {
|
|
2605
|
+
total_months: totalMonths,
|
|
2606
|
+
cliff_months: cliffMonths,
|
|
2607
|
+
acceleration: acceleration === "none" ? void 0 : acceleration
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
const wantIp = await confirm2({ message: " Contributing IP?", default: false });
|
|
2612
|
+
if (wantIp) {
|
|
2613
|
+
f.ip_description = await input2({ message: " Describe IP being contributed" });
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
return { founders, transferRestrictions, rofr };
|
|
2618
|
+
}
|
|
2619
|
+
function printSummary(entityType, name, jurisdiction, fiscalYearEnd, sCorpElection, founders, transferRestrictions, rofr) {
|
|
2620
|
+
sectionHeader("Formation Summary");
|
|
2621
|
+
console.log(` ${chalk7.bold("Entity:")} ${name}`);
|
|
2622
|
+
console.log(` ${chalk7.bold("Type:")} ${entityType}`);
|
|
2623
|
+
console.log(` ${chalk7.bold("Jurisdiction:")} ${jurisdiction}`);
|
|
2624
|
+
console.log(` ${chalk7.bold("Fiscal Year End:")} ${fiscalYearEnd}`);
|
|
2625
|
+
if (isCorp(entityType)) {
|
|
2626
|
+
console.log(` ${chalk7.bold("S-Corp Election:")} ${sCorpElection ? "Yes" : "No"}`);
|
|
2627
|
+
console.log(` ${chalk7.bold("Transfer Restrictions:")} ${transferRestrictions ? "Yes" : "No"}`);
|
|
2628
|
+
console.log(` ${chalk7.bold("Right of First Refusal:")} ${rofr ? "Yes" : "No"}`);
|
|
2629
|
+
}
|
|
2630
|
+
const table = new Table3({
|
|
2631
|
+
head: [chalk7.dim("Name"), chalk7.dim("Email"), chalk7.dim("Role"), chalk7.dim("Equity"), chalk7.dim("Officer")]
|
|
2632
|
+
});
|
|
2633
|
+
for (const f of founders) {
|
|
2634
|
+
const equity = f.shares_purchased ? `${f.shares_purchased.toLocaleString()} shares` : f.ownership_pct ? `${f.ownership_pct}%` : "\u2014";
|
|
2635
|
+
table.push([f.name, f.email, f.role, equity, f.officer_title ?? "\u2014"]);
|
|
2636
|
+
}
|
|
2637
|
+
console.log(table.toString());
|
|
2638
|
+
}
|
|
2206
2639
|
async function formCommand(opts) {
|
|
2207
2640
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2208
2641
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
@@ -2212,69 +2645,159 @@ async function formCommand(opts) {
|
|
|
2212
2645
|
serverCfg = await client.getConfig();
|
|
2213
2646
|
} catch {
|
|
2214
2647
|
}
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2648
|
+
const scripted = !!(opts.member && opts.member.length > 0);
|
|
2649
|
+
const { entityType, name, jurisdiction, companyAddress, fiscalYearEnd, sCorpElection } = await phaseEntityDetails(opts, serverCfg, scripted);
|
|
2650
|
+
const founders = await phasePeople(opts, entityType, scripted);
|
|
2651
|
+
const { transferRestrictions, rofr } = await phaseStock(opts, entityType, founders, scripted);
|
|
2652
|
+
printSummary(entityType, name, jurisdiction, fiscalYearEnd, sCorpElection, founders, transferRestrictions, rofr);
|
|
2653
|
+
const shouldProceed = scripted ? true : await confirm2({ message: "Proceed with formation?", default: true });
|
|
2654
|
+
if (!shouldProceed) {
|
|
2655
|
+
console.log(chalk7.yellow("Formation cancelled."));
|
|
2656
|
+
return;
|
|
2219
2657
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2658
|
+
const members = founders.map((f) => {
|
|
2659
|
+
const m = {
|
|
2660
|
+
name: f.name,
|
|
2661
|
+
email: f.email,
|
|
2662
|
+
role: f.role,
|
|
2663
|
+
investor_type: "natural_person"
|
|
2664
|
+
};
|
|
2665
|
+
if (f.ownership_pct) m.ownership_pct = f.ownership_pct;
|
|
2666
|
+
if (f.shares_purchased) m.shares_purchased = f.shares_purchased;
|
|
2667
|
+
if (f.address) m.address = f.address;
|
|
2668
|
+
if (f.officer_title) m.officer_title = f.officer_title;
|
|
2669
|
+
if (f.is_incorporator) m.is_incorporator = true;
|
|
2670
|
+
if (f.vesting) m.vesting = f.vesting;
|
|
2671
|
+
if (f.ip_description) m.ip_description = f.ip_description;
|
|
2672
|
+
return m;
|
|
2673
|
+
});
|
|
2674
|
+
const payload = {
|
|
2675
|
+
entity_type: entityType,
|
|
2676
|
+
legal_name: name,
|
|
2677
|
+
jurisdiction,
|
|
2678
|
+
members,
|
|
2679
|
+
workspace_id: cfg.workspace_id,
|
|
2680
|
+
fiscal_year_end: fiscalYearEnd,
|
|
2681
|
+
s_corp_election: sCorpElection,
|
|
2682
|
+
transfer_restrictions: transferRestrictions,
|
|
2683
|
+
right_of_first_refusal: rofr
|
|
2684
|
+
};
|
|
2685
|
+
if (companyAddress) payload.company_address = companyAddress;
|
|
2686
|
+
const result = await client.createFormationWithCapTable(payload);
|
|
2687
|
+
printSuccess(`Formation created: ${result.formation_id ?? result.id ?? "OK"}`);
|
|
2688
|
+
if (result.entity_id) console.log(` Entity ID: ${result.entity_id}`);
|
|
2689
|
+
if (result.legal_entity_id) console.log(` Legal Entity ID: ${result.legal_entity_id}`);
|
|
2690
|
+
if (result.instrument_id) console.log(` Instrument ID: ${result.instrument_id}`);
|
|
2691
|
+
const docIds = result.document_ids ?? [];
|
|
2692
|
+
if (docIds.length > 0) {
|
|
2693
|
+
console.log(` Documents: ${docIds.length} generated`);
|
|
2223
2694
|
}
|
|
2224
|
-
|
|
2225
|
-
if (
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
choices: jurisdictions.map((j) => ({ value: j, name: j })),
|
|
2230
|
-
default: "DE"
|
|
2695
|
+
const holders = result.holders ?? [];
|
|
2696
|
+
if (holders.length > 0) {
|
|
2697
|
+
console.log();
|
|
2698
|
+
const table = new Table3({
|
|
2699
|
+
head: [chalk7.dim("Holder"), chalk7.dim("Shares"), chalk7.dim("Ownership %")]
|
|
2231
2700
|
});
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
for (const m of opts.member) {
|
|
2236
|
-
const parts = m.split(",").map((p) => p.trim());
|
|
2237
|
-
if (parts.length < 3) {
|
|
2238
|
-
printError(`Invalid member format: ${m}. Expected: name,email,role[,ownership_pct]`);
|
|
2239
|
-
process.exit(1);
|
|
2240
|
-
}
|
|
2241
|
-
const member = { name: parts[0], email: parts[1], role: parts[2] };
|
|
2242
|
-
if (parts.length >= 4) member.ownership_pct = parseFloat(parts[3]);
|
|
2243
|
-
parsedMembers.push(member);
|
|
2244
|
-
}
|
|
2245
|
-
} else {
|
|
2246
|
-
console.log("Add members (leave name blank to finish):");
|
|
2247
|
-
while (true) {
|
|
2248
|
-
const mname = await input2({ message: " Member name (blank to finish)", default: "" });
|
|
2249
|
-
if (!mname) break;
|
|
2250
|
-
const memail = await input2({ message: " Email" });
|
|
2251
|
-
const mrole = await input2({ message: " Role", default: "founder" });
|
|
2252
|
-
const mpctStr = await input2({ message: " Ownership %", default: "0" });
|
|
2253
|
-
parsedMembers.push({
|
|
2254
|
-
name: mname,
|
|
2255
|
-
email: memail,
|
|
2256
|
-
role: mrole,
|
|
2257
|
-
ownership_pct: parseFloat(mpctStr)
|
|
2258
|
-
});
|
|
2701
|
+
for (const h of holders) {
|
|
2702
|
+
const pct = typeof h.ownership_pct === "number" ? `${h.ownership_pct.toFixed(1)}%` : "\u2014";
|
|
2703
|
+
table.push([String(h.name ?? "?"), String(h.shares ?? 0), pct]);
|
|
2259
2704
|
}
|
|
2705
|
+
console.log(chalk7.bold(" Cap Table:"));
|
|
2706
|
+
console.log(table.toString());
|
|
2260
2707
|
}
|
|
2261
|
-
|
|
2262
|
-
|
|
2708
|
+
if (result.next_action) {
|
|
2709
|
+
console.log(chalk7.yellow(`
|
|
2710
|
+
Next: ${result.next_action}`));
|
|
2263
2711
|
}
|
|
2264
|
-
const result = await client.createFormation({
|
|
2265
|
-
entity_type: entityType,
|
|
2266
|
-
legal_name: name,
|
|
2267
|
-
jurisdiction,
|
|
2268
|
-
members: parsedMembers
|
|
2269
|
-
});
|
|
2270
|
-
printSuccess(`Formation created: ${result.formation_id ?? result.id ?? "OK"}`);
|
|
2271
|
-
if (result.entity_id) console.log(`Entity ID: ${result.entity_id}`);
|
|
2272
2712
|
} catch (err) {
|
|
2273
2713
|
if (err instanceof Error && err.message.includes("exit")) throw err;
|
|
2274
2714
|
printError(`Failed to create formation: ${err}`);
|
|
2275
2715
|
process.exit(1);
|
|
2276
2716
|
}
|
|
2277
2717
|
}
|
|
2718
|
+
async function formCreateCommand(opts) {
|
|
2719
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2720
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2721
|
+
try {
|
|
2722
|
+
const entityType = opts.type === "c_corp" || opts.type === "corporation" ? "corporation" : "llc";
|
|
2723
|
+
const payload = {
|
|
2724
|
+
entity_type: entityType,
|
|
2725
|
+
legal_name: opts.name
|
|
2726
|
+
};
|
|
2727
|
+
if (opts.jurisdiction) payload.jurisdiction = opts.jurisdiction;
|
|
2728
|
+
const result = await client.createPendingEntity(payload);
|
|
2729
|
+
printSuccess(`Pending entity created: ${result.entity_id}`);
|
|
2730
|
+
console.log(` Name: ${result.legal_name}`);
|
|
2731
|
+
console.log(` Type: ${result.entity_type}`);
|
|
2732
|
+
console.log(` Jurisdiction: ${result.jurisdiction}`);
|
|
2733
|
+
console.log(` Status: ${result.formation_status}`);
|
|
2734
|
+
console.log(chalk7.yellow(`
|
|
2735
|
+
Next: corp form add-founder ${result.entity_id} --name "..." --email "..." --role member --pct 50`));
|
|
2736
|
+
} catch (err) {
|
|
2737
|
+
printError(`Failed to create pending entity: ${err}`);
|
|
2738
|
+
process.exit(1);
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
async function formAddFounderCommand(entityId, opts) {
|
|
2742
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2743
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2744
|
+
try {
|
|
2745
|
+
const payload = {
|
|
2746
|
+
name: opts.name,
|
|
2747
|
+
email: opts.email,
|
|
2748
|
+
role: opts.role,
|
|
2749
|
+
ownership_pct: parseFloat(opts.pct)
|
|
2750
|
+
};
|
|
2751
|
+
if (opts.officerTitle) payload.officer_title = opts.officerTitle;
|
|
2752
|
+
if (opts.incorporator) payload.is_incorporator = true;
|
|
2753
|
+
const result = await client.addFounder(entityId, payload);
|
|
2754
|
+
printSuccess(`Founder added (${result.member_count} total)`);
|
|
2755
|
+
const members = result.members ?? [];
|
|
2756
|
+
for (const m of members) {
|
|
2757
|
+
const pct = typeof m.ownership_pct === "number" ? ` (${m.ownership_pct}%)` : "";
|
|
2758
|
+
console.log(` - ${m.name} <${m.email ?? "no email"}> [${m.role ?? "member"}]${pct}`);
|
|
2759
|
+
}
|
|
2760
|
+
console.log(chalk7.yellow(`
|
|
2761
|
+
Next: add more founders or run: corp form finalize ${entityId}`));
|
|
2762
|
+
} catch (err) {
|
|
2763
|
+
printError(`Failed to add founder: ${err}`);
|
|
2764
|
+
process.exit(1);
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
async function formFinalizeCommand(entityId) {
|
|
2768
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2769
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
2770
|
+
try {
|
|
2771
|
+
const result = await client.finalizeFormation(entityId);
|
|
2772
|
+
printSuccess(`Formation finalized: ${result.entity_id}`);
|
|
2773
|
+
if (result.legal_entity_id) console.log(` Legal Entity ID: ${result.legal_entity_id}`);
|
|
2774
|
+
if (result.instrument_id) console.log(` Instrument ID: ${result.instrument_id}`);
|
|
2775
|
+
const docIds = result.document_ids ?? [];
|
|
2776
|
+
if (docIds.length > 0) {
|
|
2777
|
+
console.log(` Documents: ${docIds.length} generated`);
|
|
2778
|
+
}
|
|
2779
|
+
const holders = result.holders ?? [];
|
|
2780
|
+
if (holders.length > 0) {
|
|
2781
|
+
console.log();
|
|
2782
|
+
const table = new Table3({
|
|
2783
|
+
head: [chalk7.dim("Holder"), chalk7.dim("Shares"), chalk7.dim("Ownership %")]
|
|
2784
|
+
});
|
|
2785
|
+
for (const h of holders) {
|
|
2786
|
+
const pct = typeof h.ownership_pct === "number" ? `${h.ownership_pct.toFixed(1)}%` : "\u2014";
|
|
2787
|
+
table.push([String(h.name ?? "?"), String(h.shares ?? 0), pct]);
|
|
2788
|
+
}
|
|
2789
|
+
console.log(chalk7.bold(" Cap Table:"));
|
|
2790
|
+
console.log(table.toString());
|
|
2791
|
+
}
|
|
2792
|
+
if (result.next_action) {
|
|
2793
|
+
console.log(chalk7.yellow(`
|
|
2794
|
+
Next: ${result.next_action}`));
|
|
2795
|
+
}
|
|
2796
|
+
} catch (err) {
|
|
2797
|
+
printError(`Failed to finalize formation: ${err}`);
|
|
2798
|
+
process.exit(1);
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2278
2801
|
var init_form = __esm({
|
|
2279
2802
|
"src/commands/form.ts"() {
|
|
2280
2803
|
"use strict";
|
|
@@ -2289,8 +2812,8 @@ var api_keys_exports = {};
|
|
|
2289
2812
|
__export(api_keys_exports, {
|
|
2290
2813
|
apiKeysCommand: () => apiKeysCommand
|
|
2291
2814
|
});
|
|
2292
|
-
import
|
|
2293
|
-
import
|
|
2815
|
+
import chalk8 from "chalk";
|
|
2816
|
+
import Table4 from "cli-table3";
|
|
2294
2817
|
async function apiKeysCommand(opts) {
|
|
2295
2818
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
2296
2819
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
@@ -2305,9 +2828,9 @@ async function apiKeysCommand(opts) {
|
|
|
2305
2828
|
return;
|
|
2306
2829
|
}
|
|
2307
2830
|
console.log(`
|
|
2308
|
-
${
|
|
2309
|
-
const table = new
|
|
2310
|
-
head: [
|
|
2831
|
+
${chalk8.bold("API Keys")}`);
|
|
2832
|
+
const table = new Table4({
|
|
2833
|
+
head: [chalk8.dim("ID"), chalk8.dim("Name"), chalk8.dim("Key"), chalk8.dim("Created"), chalk8.dim("Last Used")]
|
|
2311
2834
|
});
|
|
2312
2835
|
for (const k of keys) {
|
|
2313
2836
|
table.push([
|
|
@@ -2410,8 +2933,11 @@ var init_serve = __esm({
|
|
|
2410
2933
|
|
|
2411
2934
|
// src/index.ts
|
|
2412
2935
|
import { Command } from "commander";
|
|
2936
|
+
import { createRequire } from "module";
|
|
2937
|
+
var require2 = createRequire(import.meta.url);
|
|
2938
|
+
var pkg = require2("../package.json");
|
|
2413
2939
|
var program = new Command();
|
|
2414
|
-
program.name("corp").description("corp \u2014 Corporate governance from the terminal").version(
|
|
2940
|
+
program.name("corp").description("corp \u2014 Corporate governance from the terminal").version(pkg.version);
|
|
2415
2941
|
program.command("setup").description("Interactive setup wizard").action(async () => {
|
|
2416
2942
|
const { setupCommand: setupCommand2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
2417
2943
|
await setupCommand2();
|
|
@@ -2529,6 +3055,36 @@ capTableCmd.command("distribute").requiredOption("--amount <n>", "Total distribu
|
|
|
2529
3055
|
const { distributeCommand: distributeCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
2530
3056
|
await distributeCommand2({ ...opts, entityId: parent.entityId });
|
|
2531
3057
|
});
|
|
3058
|
+
capTableCmd.command("start-round").requiredOption("--name <name>", "Round name").requiredOption("--issuer-legal-entity-id <id>", "Issuer legal entity ID").description("Start a staged equity round").action(async (opts, cmd) => {
|
|
3059
|
+
const parent = cmd.parent.opts();
|
|
3060
|
+
const { startRoundCommand: startRoundCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
3061
|
+
await startRoundCommand2({ ...opts, entityId: parent.entityId });
|
|
3062
|
+
});
|
|
3063
|
+
capTableCmd.command("add-security").requiredOption("--round-id <id>", "Round ID").requiredOption("--instrument-id <id>", "Instrument ID").requiredOption("--quantity <n>", "Number of shares/units", parseInt).requiredOption("--recipient-name <name>", "Recipient display name").option("--holder-id <id>", "Existing holder ID").option("--email <email>", "Recipient email (to find or create holder)").option("--principal-cents <n>", "Principal amount in cents", parseInt).option("--grant-type <type>", "Grant type").description("Add a security to a staged equity round").action(async (opts, cmd) => {
|
|
3064
|
+
const parent = cmd.parent.opts();
|
|
3065
|
+
const { addSecurityCommand: addSecurityCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
3066
|
+
await addSecurityCommand2({ ...opts, entityId: parent.entityId });
|
|
3067
|
+
});
|
|
3068
|
+
capTableCmd.command("issue-round").requiredOption("--round-id <id>", "Round ID").description("Issue all securities and close a staged round").action(async (opts, cmd) => {
|
|
3069
|
+
const parent = cmd.parent.opts();
|
|
3070
|
+
const { issueRoundCommand: issueRoundCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
3071
|
+
await issueRoundCommand2({ ...opts, entityId: parent.entityId });
|
|
3072
|
+
});
|
|
3073
|
+
capTableCmd.command("create-valuation").requiredOption("--type <type>", "Valuation type (four_oh_nine_a, fair_market_value, etc.)").requiredOption("--date <date>", "Effective date (ISO 8601)").requiredOption("--methodology <method>", "Methodology (income, market, asset, backsolve, hybrid)").option("--fmv <cents>", "FMV per share in cents", parseInt).option("--enterprise-value <cents>", "Enterprise value in cents", parseInt).description("Create a valuation").action(async (opts, cmd) => {
|
|
3074
|
+
const parent = cmd.parent.opts();
|
|
3075
|
+
const { createValuationCommand: createValuationCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
3076
|
+
await createValuationCommand2({ ...opts, entityId: parent.entityId });
|
|
3077
|
+
});
|
|
3078
|
+
capTableCmd.command("submit-valuation <valuation-id>").description("Submit a valuation for board approval").action(async (valuationId, _opts, cmd) => {
|
|
3079
|
+
const parent = cmd.parent.opts();
|
|
3080
|
+
const { submitValuationCommand: submitValuationCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
3081
|
+
await submitValuationCommand2({ valuationId, entityId: parent.entityId });
|
|
3082
|
+
});
|
|
3083
|
+
capTableCmd.command("approve-valuation <valuation-id>").option("--resolution-id <id>", "Resolution ID from the board vote").description("Approve a valuation").action(async (valuationId, opts, cmd) => {
|
|
3084
|
+
const parent = cmd.parent.opts();
|
|
3085
|
+
const { approveValuationCommand: approveValuationCommand2 } = await Promise.resolve().then(() => (init_cap_table(), cap_table_exports));
|
|
3086
|
+
await approveValuationCommand2({ ...opts, valuationId, entityId: parent.entityId });
|
|
3087
|
+
});
|
|
2532
3088
|
var financeCmd = program.command("finance").description("Invoicing, payroll, payments, banking").option("--entity-id <id>", "Entity ID (overrides active entity)");
|
|
2533
3089
|
financeCmd.command("invoice").requiredOption("--customer <name>", "Customer name").requiredOption("--amount <n>", "Amount in cents", parseInt).requiredOption("--due-date <date>", "Due date (ISO 8601)").option("--description <desc>", "Description", "Services rendered").description("Create an invoice").action(async (opts, cmd) => {
|
|
2534
3090
|
const parent = cmd.parent.opts();
|
|
@@ -2588,6 +3144,41 @@ governanceCmd.command("vote <meeting-id> <item-id>").requiredOption("--voter <na
|
|
|
2588
3144
|
const { governanceVoteCommand: governanceVoteCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
2589
3145
|
await governanceVoteCommand2(meetingId, itemId, opts);
|
|
2590
3146
|
});
|
|
3147
|
+
governanceCmd.command("notice <meeting-id>").description("Send meeting notice").action(async (meetingId, _opts, cmd) => {
|
|
3148
|
+
const parent = cmd.parent.opts();
|
|
3149
|
+
const { sendNoticeCommand: sendNoticeCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3150
|
+
await sendNoticeCommand2(meetingId, { entityId: parent.entityId });
|
|
3151
|
+
});
|
|
3152
|
+
governanceCmd.command("adjourn <meeting-id>").description("Adjourn a meeting").action(async (meetingId, _opts, cmd) => {
|
|
3153
|
+
const parent = cmd.parent.opts();
|
|
3154
|
+
const { adjournMeetingCommand: adjournMeetingCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3155
|
+
await adjournMeetingCommand2(meetingId, { entityId: parent.entityId });
|
|
3156
|
+
});
|
|
3157
|
+
governanceCmd.command("cancel <meeting-id>").description("Cancel a meeting").action(async (meetingId, _opts, cmd) => {
|
|
3158
|
+
const parent = cmd.parent.opts();
|
|
3159
|
+
const { cancelMeetingCommand: cancelMeetingCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3160
|
+
await cancelMeetingCommand2(meetingId, { entityId: parent.entityId });
|
|
3161
|
+
});
|
|
3162
|
+
governanceCmd.command("agenda-items <meeting-id>").description("List agenda items for a meeting").action(async (meetingId, _opts, cmd) => {
|
|
3163
|
+
const parent = cmd.parent.opts();
|
|
3164
|
+
const { listAgendaItemsCommand: listAgendaItemsCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3165
|
+
await listAgendaItemsCommand2(meetingId, { entityId: parent.entityId, json: parent.json });
|
|
3166
|
+
});
|
|
3167
|
+
governanceCmd.command("finalize-item <meeting-id> <item-id>").requiredOption("--status <status>", "Status: Voted, Discussed, Tabled, or Withdrawn").description("Finalize an agenda item").action(async (meetingId, itemId, opts, cmd) => {
|
|
3168
|
+
const parent = cmd.parent.opts();
|
|
3169
|
+
const { finalizeAgendaItemCommand: finalizeAgendaItemCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3170
|
+
await finalizeAgendaItemCommand2(meetingId, itemId, { ...opts, entityId: parent.entityId });
|
|
3171
|
+
});
|
|
3172
|
+
governanceCmd.command("resolve <meeting-id> <item-id>").requiredOption("--text <resolution_text>", "Resolution text").description("Compute a resolution for an agenda item").action(async (meetingId, itemId, opts, cmd) => {
|
|
3173
|
+
const parent = cmd.parent.opts();
|
|
3174
|
+
const { computeResolutionCommand: computeResolutionCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3175
|
+
await computeResolutionCommand2(meetingId, itemId, { ...opts, entityId: parent.entityId });
|
|
3176
|
+
});
|
|
3177
|
+
governanceCmd.command("written-consent").requiredOption("--body <id>", "Governance body ID").requiredOption("--title <title>", "Title").requiredOption("--description <desc>", "Description").description("Create a written consent action").action(async (opts, cmd) => {
|
|
3178
|
+
const parent = cmd.parent.opts();
|
|
3179
|
+
const { writtenConsentCommand: writtenConsentCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
3180
|
+
await writtenConsentCommand2({ ...opts, entityId: parent.entityId });
|
|
3181
|
+
});
|
|
2591
3182
|
var documentsCmd = program.command("documents").description("Documents and signing").option("--entity-id <id>", "Entity ID (overrides active entity)").option("--json", "Output as JSON").action(async (opts) => {
|
|
2592
3183
|
const { documentsListCommand: documentsListCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
2593
3184
|
await documentsListCommand2(opts);
|
|
@@ -2601,6 +3192,11 @@ documentsCmd.command("generate").requiredOption("--template <type>", "Template t
|
|
|
2601
3192
|
const { documentsGenerateCommand: documentsGenerateCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
2602
3193
|
await documentsGenerateCommand2({ ...opts, entityId: parent.entityId });
|
|
2603
3194
|
});
|
|
3195
|
+
documentsCmd.command("preview-pdf").requiredOption("--document-id <id>", "AST document definition ID (e.g. 'bylaws')").description("Preview a governance document as PDF").action(async (opts, cmd) => {
|
|
3196
|
+
const parent = cmd.parent.opts();
|
|
3197
|
+
const { documentsPreviewPdfCommand: documentsPreviewPdfCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
3198
|
+
await documentsPreviewPdfCommand2({ ...opts, entityId: parent.entityId });
|
|
3199
|
+
});
|
|
2604
3200
|
var taxCmd = program.command("tax").description("Tax filings and deadline tracking").option("--entity-id <id>", "Entity ID (overrides active entity)");
|
|
2605
3201
|
taxCmd.command("file").requiredOption("--type <type>", "Document type").requiredOption("--year <year>", "Tax year", parseInt).description("File a tax document").action(async (opts, cmd) => {
|
|
2606
3202
|
const parent = cmd.parent.opts();
|
|
@@ -2672,10 +3268,22 @@ approvalsCmd.command("reject <approval-id>").option("--message <msg>", "Optional
|
|
|
2672
3268
|
const { approvalsRespondCommand: approvalsRespondCommand2 } = await Promise.resolve().then(() => (init_approvals(), approvals_exports));
|
|
2673
3269
|
await approvalsRespondCommand2(approvalId, "reject", opts);
|
|
2674
3270
|
});
|
|
2675
|
-
program.command("form").description("
|
|
3271
|
+
var formCmd = program.command("form").description("Form a new entity with founders and cap table (Cooley-style)").option("--type <type>", "Entity type (llc, c_corp)").option("--name <name>", "Legal name").option("--jurisdiction <jurisdiction>", "Jurisdiction (e.g. US-DE, US-WY)").option("--member <member>", "Member as 'name,email,role[,pct]' \u2014 role: director|officer|manager|member|chair (repeatable)", (v, a) => [...a, v], []).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").action(async (opts) => {
|
|
2676
3272
|
const { formCommand: formCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
2677
3273
|
await formCommand2(opts);
|
|
2678
3274
|
});
|
|
3275
|
+
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) => {
|
|
3276
|
+
const { formCreateCommand: formCreateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3277
|
+
await formCreateCommand2(opts);
|
|
3278
|
+
});
|
|
3279
|
+
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) => {
|
|
3280
|
+
const { formAddFounderCommand: formAddFounderCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3281
|
+
await formAddFounderCommand2(entityId, opts);
|
|
3282
|
+
});
|
|
3283
|
+
formCmd.command("finalize <entity-id>").description("Finalize formation and generate documents + cap table (staged flow step 3)").action(async (entityId) => {
|
|
3284
|
+
const { formFinalizeCommand: formFinalizeCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
3285
|
+
await formFinalizeCommand2(entityId);
|
|
3286
|
+
});
|
|
2679
3287
|
program.command("api-keys").description("List API keys").option("--json", "Output as JSON").action(async (opts) => {
|
|
2680
3288
|
const { apiKeysCommand: apiKeysCommand2 } = await Promise.resolve().then(() => (init_api_keys(), api_keys_exports));
|
|
2681
3289
|
await apiKeysCommand2(opts);
|