@thecorporation/cli 26.3.23 → 26.3.24
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 +282 -35
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
package/dist/index.js
CHANGED
|
@@ -3077,8 +3077,15 @@ async function digestCommand(opts) {
|
|
|
3077
3077
|
printJson(result);
|
|
3078
3078
|
} else {
|
|
3079
3079
|
const digests = await client.listDigests();
|
|
3080
|
-
if (digests.length === 0)
|
|
3081
|
-
|
|
3080
|
+
if (digests.length === 0) {
|
|
3081
|
+
if (opts.json) {
|
|
3082
|
+
printJson([]);
|
|
3083
|
+
} else {
|
|
3084
|
+
console.log("No digest history found.");
|
|
3085
|
+
}
|
|
3086
|
+
} else {
|
|
3087
|
+
printJson(digests);
|
|
3088
|
+
}
|
|
3082
3089
|
}
|
|
3083
3090
|
} catch (err) {
|
|
3084
3091
|
printError2(`Failed: ${err}`);
|
|
@@ -3128,6 +3135,12 @@ __export(claim_exports, {
|
|
|
3128
3135
|
async function claimCommand(code) {
|
|
3129
3136
|
const cfg = loadConfig();
|
|
3130
3137
|
const apiUrl = (cfg.api_url || "https://api.thecorporation.ai").replace(/\/+$/, "");
|
|
3138
|
+
if (apiUrl.startsWith("process://")) {
|
|
3139
|
+
printError2(
|
|
3140
|
+
"Claim codes require a remote API server.\n Run: npx corp config set api_url https://api.thecorporation.ai --force\n Or use: npx corp setup"
|
|
3141
|
+
);
|
|
3142
|
+
process.exit(1);
|
|
3143
|
+
}
|
|
3131
3144
|
try {
|
|
3132
3145
|
const resp = await fetch(`${apiUrl}/v1/workspaces/claim`, {
|
|
3133
3146
|
method: "POST",
|
|
@@ -4125,6 +4138,16 @@ async function issueEquityCommand(opts) {
|
|
|
4125
4138
|
grant_type: opts.grantType
|
|
4126
4139
|
};
|
|
4127
4140
|
if (opts.email) securityData.email = opts.email;
|
|
4141
|
+
const existingHolders = capTable.holders ?? [];
|
|
4142
|
+
const matchingHolder = existingHolders.find((h) => {
|
|
4143
|
+
const nameMatch = String(h.name ?? "").toLowerCase() === opts.recipient.toLowerCase();
|
|
4144
|
+
const emailMatch = opts.email && String(h.email ?? "").toLowerCase() === opts.email.toLowerCase();
|
|
4145
|
+
return nameMatch || emailMatch;
|
|
4146
|
+
});
|
|
4147
|
+
if (matchingHolder) {
|
|
4148
|
+
const holderId = matchingHolder.holder_id ?? matchingHolder.contact_id ?? matchingHolder.id;
|
|
4149
|
+
if (holderId) securityData.holder_id = holderId;
|
|
4150
|
+
}
|
|
4128
4151
|
await client.addRoundSecurity(roundId, securityData);
|
|
4129
4152
|
const issuePayload = { entity_id: eid };
|
|
4130
4153
|
if (meetingId) issuePayload.meeting_id = meetingId;
|
|
@@ -4613,6 +4636,10 @@ async function dilutionPreviewCommand(opts) {
|
|
|
4613
4636
|
printJson(result);
|
|
4614
4637
|
return;
|
|
4615
4638
|
}
|
|
4639
|
+
if (result.round_status === "closed" || result.round_status === "issued") {
|
|
4640
|
+
console.log(chalk7.yellow("Note: This round is already closed. Dilution preview reflects the finalized state, not a scenario model."));
|
|
4641
|
+
console.log(chalk7.dim(" For scenario modeling, create a new round with: corp cap-table start-round --name '...' --issuer-legal-entity-id '...'"));
|
|
4642
|
+
}
|
|
4616
4643
|
printJson(result);
|
|
4617
4644
|
} catch (err) {
|
|
4618
4645
|
printError2(`Failed to preview dilution: ${err}`);
|
|
@@ -4626,14 +4653,42 @@ async function controlMapCommand(opts) {
|
|
|
4626
4653
|
try {
|
|
4627
4654
|
const eid = await resolver.resolveEntity(opts.entityId);
|
|
4628
4655
|
const rootEntityId = opts.rootEntityId ? await resolver.resolveEntity(opts.rootEntityId) : eid;
|
|
4629
|
-
|
|
4656
|
+
let result;
|
|
4657
|
+
try {
|
|
4658
|
+
result = await client.getControlMap(eid, rootEntityId);
|
|
4659
|
+
} catch (firstErr) {
|
|
4660
|
+
const msg = String(firstErr);
|
|
4661
|
+
if (msg.includes("404") && !opts.rootEntityId) {
|
|
4662
|
+
try {
|
|
4663
|
+
const capTable = await client.getCapTable(eid);
|
|
4664
|
+
const issuerLegalEntityId = capTable.issuer_legal_entity_id;
|
|
4665
|
+
if (issuerLegalEntityId && issuerLegalEntityId !== eid) {
|
|
4666
|
+
result = await client.getControlMap(eid, issuerLegalEntityId);
|
|
4667
|
+
} else {
|
|
4668
|
+
throw firstErr;
|
|
4669
|
+
}
|
|
4670
|
+
} catch {
|
|
4671
|
+
throw firstErr;
|
|
4672
|
+
}
|
|
4673
|
+
} else {
|
|
4674
|
+
throw firstErr;
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4630
4677
|
if (opts.json) {
|
|
4631
4678
|
printJson(result);
|
|
4632
4679
|
return;
|
|
4633
4680
|
}
|
|
4634
4681
|
printJson(result);
|
|
4635
4682
|
} catch (err) {
|
|
4636
|
-
|
|
4683
|
+
const msg = String(err);
|
|
4684
|
+
if (msg.includes("404") && (msg.includes("root_entity_id") || msg.includes("not found"))) {
|
|
4685
|
+
printError2(
|
|
4686
|
+
`Control map: entity not found. Ensure the entity is active and has a cap table.
|
|
4687
|
+
Try: corp cap-table control-map --root-entity-id <legal-entity-id>`
|
|
4688
|
+
);
|
|
4689
|
+
} else {
|
|
4690
|
+
printError2(`Failed to fetch control map: ${err}`);
|
|
4691
|
+
}
|
|
4637
4692
|
process.exit(1);
|
|
4638
4693
|
}
|
|
4639
4694
|
}
|
|
@@ -5521,12 +5576,22 @@ async function writtenConsentCommand(opts) {
|
|
|
5521
5576
|
const result = await client.writtenConsent(payload);
|
|
5522
5577
|
await resolver.stabilizeRecord("meeting", result, eid);
|
|
5523
5578
|
resolver.rememberFromRecord("meeting", result, eid);
|
|
5524
|
-
const meetingId = result.meeting_id ?? "
|
|
5579
|
+
const meetingId = String(result.meeting_id ?? "");
|
|
5580
|
+
if (meetingId) {
|
|
5581
|
+
try {
|
|
5582
|
+
const seats = await client.getGovernanceSeats(resolvedBodyId, eid);
|
|
5583
|
+
const seatIds = seats.map((s2) => String(s2.seat_id ?? s2.id ?? "")).filter((id) => id.length > 0);
|
|
5584
|
+
if (seatIds.length > 0) {
|
|
5585
|
+
await client.conveneMeeting(meetingId, eid, { present_seat_ids: seatIds });
|
|
5586
|
+
}
|
|
5587
|
+
} catch {
|
|
5588
|
+
}
|
|
5589
|
+
}
|
|
5525
5590
|
if (opts.json) {
|
|
5526
5591
|
printJson(result);
|
|
5527
5592
|
return;
|
|
5528
5593
|
}
|
|
5529
|
-
printSuccess(`Written consent created: ${meetingId}`);
|
|
5594
|
+
printSuccess(`Written consent created: ${meetingId || "OK"}`);
|
|
5530
5595
|
printReferenceSummary("meeting", result, { showReuseHint: true });
|
|
5531
5596
|
console.log(chalk8.dim("\n Next steps:"));
|
|
5532
5597
|
console.log(chalk8.dim(` corp governance agenda-items @last:meeting`));
|
|
@@ -5895,7 +5960,17 @@ async function documentsSigningLinkCommand(docId, opts) {
|
|
|
5895
5960
|
const resolver = new ReferenceResolver(client, cfg);
|
|
5896
5961
|
try {
|
|
5897
5962
|
const eid = await resolver.resolveEntity(opts.entityId);
|
|
5898
|
-
|
|
5963
|
+
let resolvedDocumentId;
|
|
5964
|
+
try {
|
|
5965
|
+
resolvedDocumentId = await resolver.resolveDocument(eid, docId);
|
|
5966
|
+
} catch {
|
|
5967
|
+
printError2(
|
|
5968
|
+
`Could not resolve '${docId}' as a document. If you just generated a contract, use the document_id from the generate output, not @last (which may reference the contract_id).
|
|
5969
|
+
List documents with: corp documents`
|
|
5970
|
+
);
|
|
5971
|
+
process.exit(1);
|
|
5972
|
+
return;
|
|
5973
|
+
}
|
|
5899
5974
|
const result = await client.getSigningLink(resolvedDocumentId, eid);
|
|
5900
5975
|
const shareUrl = formatSigningLink(resolvedDocumentId, result);
|
|
5901
5976
|
if (process.stdout.isTTY) {
|
|
@@ -5940,13 +6015,33 @@ async function documentsGenerateCommand(opts) {
|
|
|
5940
6015
|
});
|
|
5941
6016
|
await resolver.stabilizeRecord("document", result, eid);
|
|
5942
6017
|
resolver.rememberFromRecord("document", result, eid);
|
|
6018
|
+
if (result.document_id) {
|
|
6019
|
+
resolver.remember("document", String(result.document_id), eid);
|
|
6020
|
+
}
|
|
5943
6021
|
printWriteResult(result, `Contract generated: ${result.contract_id ?? "OK"}`, {
|
|
5944
6022
|
jsonOnly: opts.json,
|
|
5945
6023
|
referenceKind: "document",
|
|
5946
6024
|
showReuseHint: true
|
|
5947
6025
|
});
|
|
5948
6026
|
} catch (err) {
|
|
5949
|
-
|
|
6027
|
+
const msg = String(err);
|
|
6028
|
+
if (opts.template === "employment_offer" && (msg.includes("department") || msg.includes("required"))) {
|
|
6029
|
+
printError2(
|
|
6030
|
+
`Failed to generate employment_offer: ${msg}
|
|
6031
|
+
Hint: employment_offer requires additional parameters. Use --param for each:
|
|
6032
|
+
--param department=Engineering --param dispute_resolution_terms=arbitration
|
|
6033
|
+
--param equity_grant_type=stock_option --param equity_shares=10000
|
|
6034
|
+
Or pass --base-salary 150000`
|
|
6035
|
+
);
|
|
6036
|
+
} else if (opts.template === "safe_agreement" && (msg.includes("purchase_amount") || msg.includes("required"))) {
|
|
6037
|
+
printError2(
|
|
6038
|
+
`Failed to generate safe_agreement: ${msg}
|
|
6039
|
+
Hint: safe_agreement requires purchase_amount. Use:
|
|
6040
|
+
--param purchase_amount=50000000`
|
|
6041
|
+
);
|
|
6042
|
+
} else {
|
|
6043
|
+
printError2(`Failed to generate contract: ${err}`);
|
|
6044
|
+
}
|
|
5950
6045
|
process.exit(1);
|
|
5951
6046
|
}
|
|
5952
6047
|
}
|
|
@@ -6283,7 +6378,15 @@ async function agentsCreateCommand(opts) {
|
|
|
6283
6378
|
showReuseHint: true
|
|
6284
6379
|
});
|
|
6285
6380
|
} catch (err) {
|
|
6286
|
-
|
|
6381
|
+
const msg = String(err);
|
|
6382
|
+
if (msg.includes("409") || msg.includes("conflict") || msg.includes("already exists")) {
|
|
6383
|
+
printError2(
|
|
6384
|
+
`Agent name '${opts.name}' is already in use (deleted agents still reserve their name).
|
|
6385
|
+
Choose a different name, e.g.: corp agents create --name '...-v2' --prompt '...'`
|
|
6386
|
+
);
|
|
6387
|
+
} else {
|
|
6388
|
+
printError2(`Failed to create agent: ${err}`);
|
|
6389
|
+
}
|
|
6287
6390
|
process.exit(1);
|
|
6288
6391
|
}
|
|
6289
6392
|
}
|
|
@@ -6309,7 +6412,16 @@ async function agentsResumeCommand(agentId, opts) {
|
|
|
6309
6412
|
const result = await client.updateAgent(resolvedAgentId, { status: "active" });
|
|
6310
6413
|
printWriteResult(result, `Agent ${resolvedAgentId} resumed.`, opts.json);
|
|
6311
6414
|
} catch (err) {
|
|
6312
|
-
|
|
6415
|
+
const msg = String(err);
|
|
6416
|
+
if (msg.includes("409") || msg.includes("disabled") || msg.includes("deleted")) {
|
|
6417
|
+
printError2(
|
|
6418
|
+
`Cannot resume agent ${agentId}: the agent may be disabled or deleted.
|
|
6419
|
+
Disabled/deleted agents cannot be resumed. Create a new agent instead:
|
|
6420
|
+
corp agents create --name '...' --prompt '...'`
|
|
6421
|
+
);
|
|
6422
|
+
} else {
|
|
6423
|
+
printError2(`Failed to resume agent: ${err}`);
|
|
6424
|
+
}
|
|
6313
6425
|
process.exit(1);
|
|
6314
6426
|
}
|
|
6315
6427
|
}
|
|
@@ -6372,7 +6484,15 @@ async function agentsMessageCommand(agentId, opts) {
|
|
|
6372
6484
|
const result = await client.sendAgentMessage(resolvedAgentId, body);
|
|
6373
6485
|
printWriteResult(result, `Message sent. Execution: ${result.execution_id ?? "OK"}`, opts.json);
|
|
6374
6486
|
} catch (err) {
|
|
6375
|
-
|
|
6487
|
+
const msg = String(err);
|
|
6488
|
+
if (msg.includes("409")) {
|
|
6489
|
+
printError2(
|
|
6490
|
+
`Cannot message agent: the agent must be active or paused (not disabled/deleted).
|
|
6491
|
+
Check agent status: corp agents show ` + agentId + "\n Resume a paused agent: corp agents resume " + agentId
|
|
6492
|
+
);
|
|
6493
|
+
} else {
|
|
6494
|
+
printError2(`Failed to send message: ${err}`);
|
|
6495
|
+
}
|
|
6376
6496
|
process.exit(1);
|
|
6377
6497
|
}
|
|
6378
6498
|
}
|
|
@@ -7297,18 +7417,33 @@ async function formCommand(opts) {
|
|
|
7297
7417
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
7298
7418
|
const resolver = new ReferenceResolver(client, cfg);
|
|
7299
7419
|
try {
|
|
7420
|
+
if (opts.type && !SUPPORTED_ENTITY_TYPES.includes(opts.type)) {
|
|
7421
|
+
printError2(`Unsupported entity type '${opts.type}'. Supported types: ${SUPPORTED_ENTITY_TYPES.join(", ")}`);
|
|
7422
|
+
process.exit(1);
|
|
7423
|
+
}
|
|
7424
|
+
if (opts.name != null && !opts.name.trim()) {
|
|
7425
|
+
printError2("--name cannot be empty or whitespace");
|
|
7426
|
+
process.exit(1);
|
|
7427
|
+
}
|
|
7300
7428
|
let serverCfg = {};
|
|
7301
7429
|
try {
|
|
7302
7430
|
serverCfg = await client.getConfig();
|
|
7303
7431
|
} catch {
|
|
7304
7432
|
}
|
|
7305
|
-
const
|
|
7433
|
+
const hasMembers = Boolean(
|
|
7306
7434
|
opts.member && opts.member.length > 0 || opts.memberJson && opts.memberJson.length > 0 || opts.membersFile
|
|
7307
7435
|
);
|
|
7436
|
+
const scripted = hasMembers || opts.json || opts.dryRun || !process.stdout.isTTY;
|
|
7437
|
+
if (scripted && !hasMembers) {
|
|
7438
|
+
printError2("At least one --member, --member-json, or --members-file is required in non-interactive mode.");
|
|
7439
|
+
process.exit(1);
|
|
7440
|
+
}
|
|
7308
7441
|
const { entityType, name, jurisdiction, companyAddress, fiscalYearEnd, sCorpElection } = await phaseEntityDetails(opts, serverCfg, scripted);
|
|
7309
7442
|
const founders = await phasePeople(opts, entityType, scripted);
|
|
7310
7443
|
const { transferRestrictions, rofr } = await phaseStock(opts, entityType, founders, scripted);
|
|
7311
|
-
|
|
7444
|
+
if (!opts.quiet) {
|
|
7445
|
+
printSummary(entityType, name, jurisdiction, fiscalYearEnd, sCorpElection, founders, transferRestrictions, rofr);
|
|
7446
|
+
}
|
|
7312
7447
|
const shouldProceed = scripted ? true : await confirm6({ message: "Proceed with formation?", default: true });
|
|
7313
7448
|
if (!shouldProceed) {
|
|
7314
7449
|
console.log(chalk13.yellow("Formation cancelled."));
|
|
@@ -7354,6 +7489,11 @@ async function formCommand(opts) {
|
|
|
7354
7489
|
saveConfig(cfg);
|
|
7355
7490
|
console.log(chalk13.dim(` Active entity set to ${result.entity_id}`));
|
|
7356
7491
|
}
|
|
7492
|
+
if (opts.quiet) {
|
|
7493
|
+
const id = result.entity_id ?? result.formation_id;
|
|
7494
|
+
if (id) console.log(String(id));
|
|
7495
|
+
return;
|
|
7496
|
+
}
|
|
7357
7497
|
if (opts.json) {
|
|
7358
7498
|
printJson(result);
|
|
7359
7499
|
return;
|
|
@@ -7387,7 +7527,17 @@ async function formCommand(opts) {
|
|
|
7387
7527
|
}
|
|
7388
7528
|
} catch (err) {
|
|
7389
7529
|
if (err instanceof Error && err.message.includes("exit")) throw err;
|
|
7390
|
-
|
|
7530
|
+
const msg = String(err);
|
|
7531
|
+
if (msg.includes("officers_list") || msg.includes("officer")) {
|
|
7532
|
+
printError2(
|
|
7533
|
+
`Formation failed: ${msg}
|
|
7534
|
+
Hint: C-Corp directors need an officer_title. Use --member with officer_title field, e.g.:
|
|
7535
|
+
--member 'name=Alice,email=a@co.com,role=director,officer_title=ceo,pct=100'
|
|
7536
|
+
Or use --member-json with {"officer_title": "ceo"}`
|
|
7537
|
+
);
|
|
7538
|
+
} else {
|
|
7539
|
+
printError2(`Failed to create formation: ${err}`);
|
|
7540
|
+
}
|
|
7391
7541
|
process.exit(1);
|
|
7392
7542
|
}
|
|
7393
7543
|
}
|
|
@@ -7447,6 +7597,11 @@ async function formCreateCommand(opts) {
|
|
|
7447
7597
|
setActiveEntityId(cfg, String(result.entity_id));
|
|
7448
7598
|
saveConfig(cfg);
|
|
7449
7599
|
}
|
|
7600
|
+
if (opts.quiet) {
|
|
7601
|
+
const id = result.entity_id;
|
|
7602
|
+
if (id) console.log(String(id));
|
|
7603
|
+
return;
|
|
7604
|
+
}
|
|
7450
7605
|
if (opts.json) {
|
|
7451
7606
|
printJson(result);
|
|
7452
7607
|
return;
|
|
@@ -7573,7 +7728,16 @@ async function formFinalizeCommand(entityId, opts) {
|
|
|
7573
7728
|
Next: ${result.next_action}`));
|
|
7574
7729
|
}
|
|
7575
7730
|
} catch (err) {
|
|
7576
|
-
|
|
7731
|
+
const msg = String(err);
|
|
7732
|
+
if (msg.includes("officers_list") || msg.includes("officer")) {
|
|
7733
|
+
printError2(
|
|
7734
|
+
`Finalization failed: ${msg}
|
|
7735
|
+
Hint: C-Corp entities require at least one founder with an officer_title.
|
|
7736
|
+
Add a founder with: corp form add-founder @last:entity --name '...' --email '...' --role director --pct 100 --officer-title ceo`
|
|
7737
|
+
);
|
|
7738
|
+
} else {
|
|
7739
|
+
printError2(`Failed to finalize formation: ${err}`);
|
|
7740
|
+
}
|
|
7577
7741
|
process.exit(1);
|
|
7578
7742
|
}
|
|
7579
7743
|
}
|
|
@@ -7625,6 +7789,7 @@ async function formActivateCommand(entityId, opts) {
|
|
|
7625
7789
|
process.exit(1);
|
|
7626
7790
|
}
|
|
7627
7791
|
}
|
|
7792
|
+
var SUPPORTED_ENTITY_TYPES;
|
|
7628
7793
|
var init_form = __esm({
|
|
7629
7794
|
"src/commands/form.ts"() {
|
|
7630
7795
|
"use strict";
|
|
@@ -7633,6 +7798,7 @@ var init_form = __esm({
|
|
|
7633
7798
|
init_output();
|
|
7634
7799
|
init_references();
|
|
7635
7800
|
init_formation_automation();
|
|
7801
|
+
SUPPORTED_ENTITY_TYPES = ["llc", "c_corp", "s_corp", "corporation"];
|
|
7636
7802
|
}
|
|
7637
7803
|
});
|
|
7638
7804
|
|
|
@@ -7750,14 +7916,26 @@ function scenarioConfig(name, scenario) {
|
|
|
7750
7916
|
email: "alice@example.com",
|
|
7751
7917
|
role: "member",
|
|
7752
7918
|
investor_type: "natural_person",
|
|
7753
|
-
ownership_pct: 60
|
|
7919
|
+
ownership_pct: 60,
|
|
7920
|
+
address: {
|
|
7921
|
+
street: "251 Little Falls Dr",
|
|
7922
|
+
city: "Wilmington",
|
|
7923
|
+
state: "DE",
|
|
7924
|
+
zip: "19808"
|
|
7925
|
+
}
|
|
7754
7926
|
},
|
|
7755
7927
|
{
|
|
7756
7928
|
name: "Bob Martinez",
|
|
7757
7929
|
email: "bob@example.com",
|
|
7758
7930
|
role: "member",
|
|
7759
7931
|
investor_type: "natural_person",
|
|
7760
|
-
ownership_pct: 40
|
|
7932
|
+
ownership_pct: 40,
|
|
7933
|
+
address: {
|
|
7934
|
+
street: "251 Little Falls Dr",
|
|
7935
|
+
city: "Wilmington",
|
|
7936
|
+
state: "DE",
|
|
7937
|
+
zip: "19808"
|
|
7938
|
+
}
|
|
7761
7939
|
}
|
|
7762
7940
|
],
|
|
7763
7941
|
fiscal_year_end: "12-31",
|
|
@@ -7779,14 +7957,26 @@ function scenarioConfig(name, scenario) {
|
|
|
7779
7957
|
email: "rosa@example.com",
|
|
7780
7958
|
role: "manager",
|
|
7781
7959
|
investor_type: "natural_person",
|
|
7782
|
-
ownership_pct: 55
|
|
7960
|
+
ownership_pct: 55,
|
|
7961
|
+
address: {
|
|
7962
|
+
street: "18 Market St",
|
|
7963
|
+
city: "Wilmington",
|
|
7964
|
+
state: "DE",
|
|
7965
|
+
zip: "19801"
|
|
7966
|
+
}
|
|
7783
7967
|
},
|
|
7784
7968
|
{
|
|
7785
7969
|
name: "Noah Patel",
|
|
7786
7970
|
email: "noah@example.com",
|
|
7787
7971
|
role: "member",
|
|
7788
7972
|
investor_type: "natural_person",
|
|
7789
|
-
ownership_pct: 45
|
|
7973
|
+
ownership_pct: 45,
|
|
7974
|
+
address: {
|
|
7975
|
+
street: "18 Market St",
|
|
7976
|
+
city: "Wilmington",
|
|
7977
|
+
state: "DE",
|
|
7978
|
+
zip: "19801"
|
|
7979
|
+
}
|
|
7790
7980
|
}
|
|
7791
7981
|
],
|
|
7792
7982
|
fiscal_year_end: "12-31",
|
|
@@ -7815,7 +8005,13 @@ function scenarioConfig(name, scenario) {
|
|
|
7815
8005
|
investor_type: "natural_person",
|
|
7816
8006
|
shares_purchased: 6e6,
|
|
7817
8007
|
officer_title: "ceo",
|
|
7818
|
-
is_incorporator: true
|
|
8008
|
+
is_incorporator: true,
|
|
8009
|
+
address: {
|
|
8010
|
+
street: "251 Little Falls Dr",
|
|
8011
|
+
city: "Wilmington",
|
|
8012
|
+
state: "DE",
|
|
8013
|
+
zip: "19808"
|
|
8014
|
+
}
|
|
7819
8015
|
},
|
|
7820
8016
|
{
|
|
7821
8017
|
name: "Bob Martinez",
|
|
@@ -7823,7 +8019,13 @@ function scenarioConfig(name, scenario) {
|
|
|
7823
8019
|
role: "director",
|
|
7824
8020
|
investor_type: "natural_person",
|
|
7825
8021
|
shares_purchased: 4e6,
|
|
7826
|
-
officer_title: "cto"
|
|
8022
|
+
officer_title: "cto",
|
|
8023
|
+
address: {
|
|
8024
|
+
street: "251 Little Falls Dr",
|
|
8025
|
+
city: "Wilmington",
|
|
8026
|
+
state: "DE",
|
|
8027
|
+
zip: "19808"
|
|
8028
|
+
}
|
|
7827
8029
|
}
|
|
7828
8030
|
],
|
|
7829
8031
|
fiscal_year_end: "12-31",
|
|
@@ -8134,8 +8336,11 @@ var FINALIZE_ITEM_STATUS_CHOICES = [
|
|
|
8134
8336
|
"withdrawn"
|
|
8135
8337
|
];
|
|
8136
8338
|
var program = new Command();
|
|
8137
|
-
program.name("corp").description("corp \u2014 Corporate governance from the terminal").version(pkg.version);
|
|
8339
|
+
program.name("corp").description("corp \u2014 Corporate governance from the terminal").version(pkg.version).enablePositionalOptions();
|
|
8138
8340
|
program.option("-q, --quiet", "Only output the resource ID (for scripting)");
|
|
8341
|
+
program.action(() => {
|
|
8342
|
+
program.outputHelp();
|
|
8343
|
+
});
|
|
8139
8344
|
program.command("setup").description("Interactive setup wizard").action(async () => {
|
|
8140
8345
|
const { setupCommand: setupCommand2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
8141
8346
|
await setupCommand2();
|
|
@@ -8181,7 +8386,7 @@ program.command("obligations").description("List obligations with urgency tiers"
|
|
|
8181
8386
|
const { obligationsCommand: obligationsCommand2 } = await Promise.resolve().then(() => (init_obligations(), obligations_exports));
|
|
8182
8387
|
await obligationsCommand2(opts);
|
|
8183
8388
|
});
|
|
8184
|
-
program.command("digest").description("View or trigger daily digests").option("--trigger", "Trigger digest now").option("--key <key>", "Get specific digest by key").option("--json", "Output as JSON").action(async (opts) => {
|
|
8389
|
+
program.command("digest").description("View or trigger daily digests").option("--trigger", "Trigger digest now").option("--key <key>", "Get specific digest by key").option("--entity-id <ref>", "Entity reference (ID, short ID, @last, or unique name)").option("--json", "Output as JSON").action(async (opts) => {
|
|
8185
8390
|
const { digestCommand: digestCommand2 } = await Promise.resolve().then(() => (init_digest(), digest_exports));
|
|
8186
8391
|
await digestCommand2(opts);
|
|
8187
8392
|
});
|
|
@@ -8469,12 +8674,17 @@ financeCmd.command("invoices").option("--json", "Output as JSON").description("L
|
|
|
8469
8674
|
json: inheritOption(opts.json, parent.json)
|
|
8470
8675
|
});
|
|
8471
8676
|
});
|
|
8472
|
-
financeCmd.command("invoice").requiredOption("--customer <name>", "Customer name").
|
|
8677
|
+
financeCmd.command("invoice").requiredOption("--customer <name>", "Customer name").option("--amount-cents <n>", "Amount in cents (e.g. 500000 = $5,000.00)", parseInt).option("--amount <n>", "Amount in dollars (converted to cents)", parseInt).requiredOption("--due-date <date>", "Due date (ISO 8601)").option("--description <desc>", "Description", "Services rendered").option("--json", "Output as JSON").description("Create an invoice").action(async (opts, cmd) => {
|
|
8473
8678
|
const parent = cmd.parent.opts();
|
|
8679
|
+
const amountCents = opts.amountCents ?? (opts.amount != null ? opts.amount * 100 : void 0);
|
|
8680
|
+
if (amountCents == null) {
|
|
8681
|
+
cmd.error("required option '--amount-cents <n>' or '--amount <n>' not specified");
|
|
8682
|
+
return;
|
|
8683
|
+
}
|
|
8474
8684
|
const { financeInvoiceCommand: financeInvoiceCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
|
|
8475
8685
|
await financeInvoiceCommand2({
|
|
8476
8686
|
...opts,
|
|
8477
|
-
amountCents
|
|
8687
|
+
amountCents,
|
|
8478
8688
|
entityId: parent.entityId,
|
|
8479
8689
|
json: inheritOption(opts.json, parent.json)
|
|
8480
8690
|
});
|
|
@@ -8506,12 +8716,17 @@ financeCmd.command("payments").option("--json", "Output as JSON").description("L
|
|
|
8506
8716
|
json: inheritOption(opts.json, parent.json)
|
|
8507
8717
|
});
|
|
8508
8718
|
});
|
|
8509
|
-
financeCmd.command("pay").
|
|
8719
|
+
financeCmd.command("pay").option("--amount-cents <n>", "Amount in cents (e.g. 500000 = $5,000.00)", parseInt).option("--amount <n>", "Amount in dollars (converted to cents)", parseInt).requiredOption("--recipient <name>", "Recipient name").option("--method <method>", "Payment method", "ach").option("--json", "Output as JSON").description("Submit a payment").action(async (opts, cmd) => {
|
|
8510
8720
|
const parent = cmd.parent.opts();
|
|
8721
|
+
const amountCents = opts.amountCents ?? (opts.amount != null ? opts.amount * 100 : void 0);
|
|
8722
|
+
if (amountCents == null) {
|
|
8723
|
+
cmd.error("required option '--amount-cents <n>' or '--amount <n>' not specified");
|
|
8724
|
+
return;
|
|
8725
|
+
}
|
|
8511
8726
|
const { financePayCommand: financePayCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
|
|
8512
8727
|
await financePayCommand2({
|
|
8513
8728
|
...opts,
|
|
8514
|
-
amountCents
|
|
8729
|
+
amountCents,
|
|
8515
8730
|
entityId: parent.entityId,
|
|
8516
8731
|
json: inheritOption(opts.json, parent.json)
|
|
8517
8732
|
});
|
|
@@ -8570,7 +8785,7 @@ financeCmd.command("reconciliations").option("--json", "Output as JSON").descrip
|
|
|
8570
8785
|
json: inheritOption(opts.json, parent.json)
|
|
8571
8786
|
});
|
|
8572
8787
|
});
|
|
8573
|
-
financeCmd.command("reconcile").requiredOption("--start-date <date>", "Period start").requiredOption("--end-date <date>", "Period end").option("--json", "Output as JSON").description("Reconcile ledger").action(async (opts, cmd) => {
|
|
8788
|
+
financeCmd.command("reconcile").requiredOption("--start-date <date>", "Period start (required, ISO 8601)").requiredOption("--end-date <date>", "Period end (required, ISO 8601)").option("--json", "Output as JSON").description("Reconcile ledger (requires --start-date and --end-date)").action(async (opts, cmd) => {
|
|
8574
8789
|
const parent = cmd.parent.opts();
|
|
8575
8790
|
const { financeReconcileCommand: financeReconcileCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
|
|
8576
8791
|
await financeReconcileCommand2({
|
|
@@ -8872,11 +9087,16 @@ taxCmd.command("deadlines").option("--json", "Output as JSON").description("List
|
|
|
8872
9087
|
json: inheritOption(opts.json, parent.json)
|
|
8873
9088
|
});
|
|
8874
9089
|
});
|
|
8875
|
-
taxCmd.command("deadline").requiredOption("--type <type>", "Deadline type").requiredOption("--due-date <date>", "Due date (ISO 8601)").requiredOption("--description <desc>", "Description").option("--recurrence <recurrence>", "Recurrence (e.g. annual; 'yearly' is normalized)").option("--json", "Output as JSON").description("Track a compliance deadline").action(async (opts, cmd) => {
|
|
9090
|
+
taxCmd.command("deadline").requiredOption("--type <type>", "Deadline type").requiredOption("--due-date <date>", "Due date (ISO 8601)").requiredOption("--description <desc>", "Description").option("--recurrence <recurrence>", "Recurrence (e.g. annual; 'yearly' is normalized). Required for annual_report type.").option("--json", "Output as JSON").description("Track a compliance deadline").action(async (opts, cmd) => {
|
|
8876
9091
|
const parent = cmd.parent.opts();
|
|
9092
|
+
let recurrence = opts.recurrence;
|
|
9093
|
+
if (!recurrence && opts.type === "annual_report") {
|
|
9094
|
+
recurrence = "annual";
|
|
9095
|
+
}
|
|
8877
9096
|
const { taxDeadlineCommand: taxDeadlineCommand2 } = await Promise.resolve().then(() => (init_tax(), tax_exports));
|
|
8878
9097
|
await taxDeadlineCommand2({
|
|
8879
9098
|
...opts,
|
|
9099
|
+
recurrence,
|
|
8880
9100
|
entityId: parent.entityId,
|
|
8881
9101
|
json: inheritOption(opts.json, parent.json)
|
|
8882
9102
|
});
|
|
@@ -8983,12 +9203,17 @@ workItemsCmd.command("show <item-ref>").option("--json", "Output as JSON").descr
|
|
|
8983
9203
|
json: inheritOption(opts.json, parent.json)
|
|
8984
9204
|
});
|
|
8985
9205
|
});
|
|
8986
|
-
workItemsCmd.command("create").requiredOption("--title <title>", "Work item title").
|
|
9206
|
+
workItemsCmd.command("create").requiredOption("--title <title>", "Work item title").option("--category <category>", "Work item category").option("--description <desc>", "Description").option("--deadline <date>", "Deadline (YYYY-MM-DD)").option("--asap", "Mark as ASAP priority").option("--created-by <name>", "Creator identifier").option("--json", "Output as JSON").description("Create a new work item").action(async (opts, cmd) => {
|
|
8987
9207
|
const parent = cmd.parent.opts();
|
|
9208
|
+
const resolvedCategory = inheritOption(opts.category, parent.category);
|
|
9209
|
+
if (!resolvedCategory) {
|
|
9210
|
+
cmd.error("required option '--category <category>' not specified");
|
|
9211
|
+
return;
|
|
9212
|
+
}
|
|
8988
9213
|
const { workItemsCreateCommand: workItemsCreateCommand2 } = await Promise.resolve().then(() => (init_work_items(), work_items_exports));
|
|
8989
9214
|
await workItemsCreateCommand2({
|
|
8990
9215
|
...opts,
|
|
8991
|
-
category:
|
|
9216
|
+
category: resolvedCategory,
|
|
8992
9217
|
entityId: parent.entityId,
|
|
8993
9218
|
json: inheritOption(opts.json, parent.json)
|
|
8994
9219
|
});
|
|
@@ -9119,22 +9344,44 @@ program.command("approvals").description("Approvals are managed through governan
|
|
|
9119
9344
|
const { approvalsListCommand: approvalsListCommand2 } = await Promise.resolve().then(() => (init_approvals(), approvals_exports));
|
|
9120
9345
|
await approvalsListCommand2({});
|
|
9121
9346
|
});
|
|
9122
|
-
var formCmd = program.command("form").description("Form a new entity with founders and cap table").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>", "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) => {
|
|
9347
|
+
var formCmd = program.command("form").enablePositionalOptions().passThroughOptions().description("Form a new entity with founders and cap table").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>", "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, cmd) => {
|
|
9123
9348
|
const { formCommand: formCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
9124
|
-
await formCommand2(opts);
|
|
9349
|
+
await formCommand2({ ...opts, quiet: program.opts().quiet });
|
|
9125
9350
|
});
|
|
9126
|
-
formCmd.command("create").description("Create a pending entity (staged flow step 1)").
|
|
9351
|
+
formCmd.command("create").description("Create a pending entity (staged flow step 1)").option("--type <type>", "Entity type (llc, c_corp)").option("--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) => {
|
|
9127
9352
|
const parent = cmd.parent.opts();
|
|
9353
|
+
const resolvedType = inheritOption(opts.type, parent.type);
|
|
9354
|
+
const resolvedName = inheritOption(opts.name, parent.name);
|
|
9355
|
+
if (!resolvedType) {
|
|
9356
|
+
cmd.error("required option '--type <type>' not specified");
|
|
9357
|
+
return;
|
|
9358
|
+
}
|
|
9359
|
+
const SUPPORTED_ENTITY_TYPES2 = ["llc", "c_corp", "s_corp", "corporation"];
|
|
9360
|
+
if (!SUPPORTED_ENTITY_TYPES2.includes(resolvedType)) {
|
|
9361
|
+
cmd.error(`unsupported entity type '${resolvedType}'. Supported types: ${SUPPORTED_ENTITY_TYPES2.join(", ")}`);
|
|
9362
|
+
return;
|
|
9363
|
+
}
|
|
9364
|
+
if (!resolvedName) {
|
|
9365
|
+
cmd.error("required option '--name <name>' not specified");
|
|
9366
|
+
return;
|
|
9367
|
+
}
|
|
9368
|
+
if (!resolvedName.trim()) {
|
|
9369
|
+
cmd.error("--name cannot be empty or whitespace");
|
|
9370
|
+
return;
|
|
9371
|
+
}
|
|
9128
9372
|
const { formCreateCommand: formCreateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
9129
9373
|
await formCreateCommand2({
|
|
9130
9374
|
...opts,
|
|
9375
|
+
type: resolvedType,
|
|
9376
|
+
name: resolvedName,
|
|
9131
9377
|
jurisdiction: inheritOption(opts.jurisdiction, parent.jurisdiction),
|
|
9132
9378
|
fiscalYearEnd: inheritOption(opts.fiscalYearEnd, parent.fiscalYearEnd),
|
|
9133
9379
|
sCorp: inheritOption(opts.sCorp, parent.sCorp),
|
|
9134
9380
|
transferRestrictions: inheritOption(opts.transferRestrictions, parent.transferRestrictions),
|
|
9135
9381
|
rofr: inheritOption(opts.rofr, parent.rofr),
|
|
9136
9382
|
json: inheritOption(opts.json, parent.json),
|
|
9137
|
-
dryRun: inheritOption(opts.dryRun, parent.dryRun)
|
|
9383
|
+
dryRun: inheritOption(opts.dryRun, parent.dryRun),
|
|
9384
|
+
quiet: program.opts().quiet
|
|
9138
9385
|
});
|
|
9139
9386
|
});
|
|
9140
9387
|
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) => {
|