@thecorporation/cli 26.3.20 → 26.3.22
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 +46 -11
- package/dist/index.js +1275 -244
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -90,9 +90,13 @@ function allowUnsafeApiUrl() {
|
|
|
90
90
|
return process.env.CORP_UNSAFE_API_URL === "1";
|
|
91
91
|
}
|
|
92
92
|
function validateApiUrl(value) {
|
|
93
|
+
const trimmed = value.trim();
|
|
94
|
+
if (trimmed.startsWith("process://")) {
|
|
95
|
+
return trimmed;
|
|
96
|
+
}
|
|
93
97
|
let parsed;
|
|
94
98
|
try {
|
|
95
|
-
parsed = new URL(
|
|
99
|
+
parsed = new URL(trimmed);
|
|
96
100
|
} catch {
|
|
97
101
|
throw new Error("api_url must be a valid absolute URL");
|
|
98
102
|
}
|
|
@@ -217,6 +221,7 @@ function normalizeConfig(raw) {
|
|
|
217
221
|
cfg.workspace_id = normalizeString(raw.workspace_id) ?? cfg.workspace_id;
|
|
218
222
|
cfg.hosting_mode = normalizeString(raw.hosting_mode) ?? cfg.hosting_mode;
|
|
219
223
|
cfg.active_entity_id = normalizeString(raw.active_entity_id) ?? cfg.active_entity_id;
|
|
224
|
+
cfg.data_dir = normalizeString(raw.data_dir) ?? cfg.data_dir;
|
|
220
225
|
if (isObject(raw.llm)) {
|
|
221
226
|
cfg.llm.provider = normalizeString(raw.llm.provider) ?? cfg.llm.provider;
|
|
222
227
|
cfg.llm.api_key = normalizeString(raw.llm.api_key) ?? cfg.llm.api_key;
|
|
@@ -263,7 +268,8 @@ function serializeConfig(cfg) {
|
|
|
263
268
|
name: normalized.user.name,
|
|
264
269
|
email: normalized.user.email
|
|
265
270
|
},
|
|
266
|
-
active_entity_id: normalized.active_entity_id
|
|
271
|
+
active_entity_id: normalized.active_entity_id,
|
|
272
|
+
...normalized.data_dir ? { data_dir: normalized.data_dir } : {}
|
|
267
273
|
};
|
|
268
274
|
if (normalized.active_entity_ids && Object.keys(normalized.active_entity_ids).length > 0) {
|
|
269
275
|
serialized.active_entity_ids = normalized.active_entity_ids;
|
|
@@ -283,6 +289,20 @@ function serializeAuth(cfg) {
|
|
|
283
289
|
if (normalized.llm.api_key) {
|
|
284
290
|
serialized.llm = { api_key: normalized.llm.api_key };
|
|
285
291
|
}
|
|
292
|
+
const existingAuth = readJsonFile(AUTH_FILE);
|
|
293
|
+
if (isObject(existingAuth) && isObject(existingAuth.server_secrets)) {
|
|
294
|
+
const ss = existingAuth.server_secrets;
|
|
295
|
+
if (typeof ss.jwt_secret === "string" && typeof ss.secrets_master_key === "string" && typeof ss.internal_worker_token === "string") {
|
|
296
|
+
serialized.server_secrets = {
|
|
297
|
+
jwt_secret: ss.jwt_secret,
|
|
298
|
+
secrets_master_key: ss.secrets_master_key,
|
|
299
|
+
internal_worker_token: ss.internal_worker_token
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (cfg._server_secrets) {
|
|
304
|
+
serialized.server_secrets = cfg._server_secrets;
|
|
305
|
+
}
|
|
286
306
|
return JSON.stringify(serialized, null, 2) + "\n";
|
|
287
307
|
}
|
|
288
308
|
function requireSupportedConfigKey(dotPath) {
|
|
@@ -292,7 +312,9 @@ function requireSupportedConfigKey(dotPath) {
|
|
|
292
312
|
}
|
|
293
313
|
function validateSensitiveConfigUpdate(dotPath, forceSensitive = false) {
|
|
294
314
|
if (SENSITIVE_CONFIG_KEYS.has(dotPath) && !forceSensitive) {
|
|
295
|
-
throw new Error(
|
|
315
|
+
throw new Error(
|
|
316
|
+
`refusing to update security-sensitive key '${dotPath}' without --force; this key controls authentication or API routing, so explicit confirmation is required`
|
|
317
|
+
);
|
|
296
318
|
}
|
|
297
319
|
}
|
|
298
320
|
function setKnownConfigValue(cfg, dotPath, value) {
|
|
@@ -309,6 +331,9 @@ function setKnownConfigValue(cfg, dotPath, value) {
|
|
|
309
331
|
case "hosting_mode":
|
|
310
332
|
cfg.hosting_mode = value.trim();
|
|
311
333
|
return;
|
|
334
|
+
case "data_dir":
|
|
335
|
+
cfg.data_dir = value.trim();
|
|
336
|
+
return;
|
|
312
337
|
case "llm.provider":
|
|
313
338
|
cfg.llm.provider = value.trim();
|
|
314
339
|
return;
|
|
@@ -490,7 +515,8 @@ var init_config = __esm({
|
|
|
490
515
|
"llm.base_url",
|
|
491
516
|
"user.name",
|
|
492
517
|
"user.email",
|
|
493
|
-
"active_entity_id"
|
|
518
|
+
"active_entity_id",
|
|
519
|
+
"data_dir"
|
|
494
520
|
]);
|
|
495
521
|
SENSITIVE_CONFIG_KEYS = /* @__PURE__ */ new Set(["api_url", "api_key", "workspace_id"]);
|
|
496
522
|
DEFAULTS = {
|
|
@@ -505,7 +531,8 @@ var init_config = __esm({
|
|
|
505
531
|
base_url: process.env.CORP_LLM_BASE_URL || void 0
|
|
506
532
|
},
|
|
507
533
|
user: { name: "", email: "" },
|
|
508
|
-
active_entity_id: ""
|
|
534
|
+
active_entity_id: "",
|
|
535
|
+
data_dir: ""
|
|
509
536
|
};
|
|
510
537
|
}
|
|
511
538
|
});
|
|
@@ -656,7 +683,11 @@ function describeReferenceRecord(kind, record) {
|
|
|
656
683
|
idFields: ["share_class_id", "id"],
|
|
657
684
|
labelFields: ["class_code", "name", "share_class"]
|
|
658
685
|
},
|
|
659
|
-
round: { idFields: ["round_id", "equity_round_id", "id"], labelFields: ["name"] }
|
|
686
|
+
round: { idFields: ["round_id", "equity_round_id", "id"], labelFields: ["name"] },
|
|
687
|
+
service_request: {
|
|
688
|
+
idFields: ["request_id", "service_request_id", "id"],
|
|
689
|
+
labelFields: ["service_slug", "status"]
|
|
690
|
+
}
|
|
660
691
|
};
|
|
661
692
|
const spec = specs[kind];
|
|
662
693
|
const id = extractId(record, spec.idFields);
|
|
@@ -724,7 +755,8 @@ var init_references = __esm({
|
|
|
724
755
|
"safe_note",
|
|
725
756
|
"instrument",
|
|
726
757
|
"share_class",
|
|
727
|
-
"round"
|
|
758
|
+
"round",
|
|
759
|
+
"service_request"
|
|
728
760
|
];
|
|
729
761
|
VALID_RESOURCE_KINDS = new Set(RESOURCE_KINDS);
|
|
730
762
|
MAX_REFERENCE_INPUT_LEN = 256;
|
|
@@ -753,6 +785,7 @@ var init_references = __esm({
|
|
|
753
785
|
valuationsCache = /* @__PURE__ */ new Map();
|
|
754
786
|
safeNotesCache = /* @__PURE__ */ new Map();
|
|
755
787
|
roundsCache = /* @__PURE__ */ new Map();
|
|
788
|
+
serviceRequestsCache = /* @__PURE__ */ new Map();
|
|
756
789
|
capTableCache = /* @__PURE__ */ new Map();
|
|
757
790
|
agentsCache;
|
|
758
791
|
constructor(client, cfg) {
|
|
@@ -775,6 +808,29 @@ var init_references = __esm({
|
|
|
775
808
|
async resolveContact(entityId, ref) {
|
|
776
809
|
return this.resolve("contact", ref, { entityId });
|
|
777
810
|
}
|
|
811
|
+
async resolveWorkItemActor(entityId, ref) {
|
|
812
|
+
const trimmed = validateReferenceInput(ref, "actor reference");
|
|
813
|
+
const [contactResult, agentResult] = await Promise.allSettled([
|
|
814
|
+
this.resolveContact(entityId, trimmed),
|
|
815
|
+
this.resolveAgent(trimmed)
|
|
816
|
+
]);
|
|
817
|
+
const contactId = contactResult.status === "fulfilled" ? contactResult.value : void 0;
|
|
818
|
+
const agentId = agentResult.status === "fulfilled" ? agentResult.value : void 0;
|
|
819
|
+
if (contactId && agentId && contactId !== agentId) {
|
|
820
|
+
throw new Error(
|
|
821
|
+
`Actor reference '${trimmed}' is ambiguous between a contact and an agent. Use a unique ref or explicit @last:contact / @last:agent.`
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
if (contactId) {
|
|
825
|
+
return { actor_type: "contact", actor_id: contactId };
|
|
826
|
+
}
|
|
827
|
+
if (agentId) {
|
|
828
|
+
return { actor_type: "agent", actor_id: agentId };
|
|
829
|
+
}
|
|
830
|
+
throw new Error(
|
|
831
|
+
`No matching contact or agent found for '${trimmed}'. Try 'corp find contact <query>' or 'corp find agent <query>'.`
|
|
832
|
+
);
|
|
833
|
+
}
|
|
778
834
|
async resolveShareTransfer(entityId, ref) {
|
|
779
835
|
return this.resolve("share_transfer", ref, { entityId });
|
|
780
836
|
}
|
|
@@ -844,6 +900,9 @@ var init_references = __esm({
|
|
|
844
900
|
async resolveRound(entityId, ref) {
|
|
845
901
|
return this.resolve("round", ref, { entityId });
|
|
846
902
|
}
|
|
903
|
+
async resolveServiceRequest(entityId, ref) {
|
|
904
|
+
return this.resolve("service_request", ref, { entityId });
|
|
905
|
+
}
|
|
847
906
|
async find(kind, query, scope = {}) {
|
|
848
907
|
const trimmedQuery = validateReferenceInput(query, "query", { allowEmpty: true });
|
|
849
908
|
const records = await this.listRecords(kind, scope);
|
|
@@ -1031,6 +1090,8 @@ var init_references = __esm({
|
|
|
1031
1090
|
return this.listShareClasses(scope.entityId);
|
|
1032
1091
|
case "round":
|
|
1033
1092
|
return this.listRounds(scope.entityId);
|
|
1093
|
+
case "service_request":
|
|
1094
|
+
return this.listServiceRequestRecords(scope.entityId);
|
|
1034
1095
|
}
|
|
1035
1096
|
})();
|
|
1036
1097
|
return this.attachStableHandles(kind, records, scope.entityId);
|
|
@@ -1295,51 +1356,19 @@ var init_references = __esm({
|
|
|
1295
1356
|
const capTable = await this.getCapTable(entityId);
|
|
1296
1357
|
return Array.isArray(capTable.share_classes) ? capTable.share_classes : [];
|
|
1297
1358
|
}
|
|
1359
|
+
async listServiceRequestRecords(entityId) {
|
|
1360
|
+
if (!entityId) throw new Error("An entity context is required to resolve service requests.");
|
|
1361
|
+
const cached = this.serviceRequestsCache.get(entityId);
|
|
1362
|
+
if (cached) return cached;
|
|
1363
|
+
const requests = await this.client.listServiceRequests(entityId);
|
|
1364
|
+
this.serviceRequestsCache.set(entityId, requests);
|
|
1365
|
+
return requests;
|
|
1366
|
+
}
|
|
1298
1367
|
};
|
|
1299
1368
|
}
|
|
1300
1369
|
});
|
|
1301
1370
|
|
|
1302
1371
|
// 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
1372
|
import chalk from "chalk";
|
|
1344
1373
|
import Table from "cli-table3";
|
|
1345
1374
|
function printError(msg) {
|
|
@@ -1420,6 +1449,30 @@ function printStatusPanel(data) {
|
|
|
1420
1449
|
}
|
|
1421
1450
|
console.log(chalk.blue("\u2500".repeat(50)));
|
|
1422
1451
|
}
|
|
1452
|
+
function printFinanceSummaryPanel(data) {
|
|
1453
|
+
const invoices = data.invoices ?? {};
|
|
1454
|
+
const bankAccounts = data.bank_accounts ?? {};
|
|
1455
|
+
const payments = data.payments ?? {};
|
|
1456
|
+
const payrollRuns = data.payroll_runs ?? {};
|
|
1457
|
+
const distributions = data.distributions ?? {};
|
|
1458
|
+
const reconciliations = data.reconciliations ?? {};
|
|
1459
|
+
const classifications = data.contractor_classifications ?? {};
|
|
1460
|
+
console.log(chalk.green("\u2500".repeat(54)));
|
|
1461
|
+
console.log(chalk.green.bold(" Finance Summary"));
|
|
1462
|
+
console.log(chalk.green("\u2500".repeat(54)));
|
|
1463
|
+
console.log(` ${chalk.bold("Entity:")} ${s(data.entity_id) || "N/A"}`);
|
|
1464
|
+
console.log(` ${chalk.bold("Invoices:")} ${s(invoices.count)} total, ${s(invoices.open_count)} open, ${money(invoices.total_amount_cents)}`);
|
|
1465
|
+
if (invoices.latest_due_date) {
|
|
1466
|
+
console.log(` ${chalk.bold("Invoice Horizon:")} next due ${date(invoices.latest_due_date)}`);
|
|
1467
|
+
}
|
|
1468
|
+
console.log(` ${chalk.bold("Bank Accounts:")} ${s(bankAccounts.active_count)}/${s(bankAccounts.count)} active`);
|
|
1469
|
+
console.log(` ${chalk.bold("Payments:")} ${s(payments.count)} total, ${s(payments.pending_count)} pending, ${money(payments.total_amount_cents)}`);
|
|
1470
|
+
console.log(` ${chalk.bold("Payroll Runs:")} ${s(payrollRuns.count)} total${payrollRuns.latest_period_end ? `, latest ${date(payrollRuns.latest_period_end)}` : ""}`);
|
|
1471
|
+
console.log(` ${chalk.bold("Distributions:")} ${s(distributions.count)} total, ${money(distributions.total_amount_cents)}`);
|
|
1472
|
+
console.log(` ${chalk.bold("Reconciliations:")} ${s(reconciliations.balanced_count)}/${s(reconciliations.count)} balanced`);
|
|
1473
|
+
console.log(` ${chalk.bold("Contractors:")} ${s(classifications.count)} classifications, ${s(classifications.high_risk_count)} high risk`);
|
|
1474
|
+
console.log(chalk.green("\u2500".repeat(54)));
|
|
1475
|
+
}
|
|
1423
1476
|
function makeTable(title, columns) {
|
|
1424
1477
|
console.log(`
|
|
1425
1478
|
${chalk.bold(title)}`);
|
|
@@ -1443,6 +1496,17 @@ function date(val) {
|
|
|
1443
1496
|
const parsed = new Date(str);
|
|
1444
1497
|
return Number.isNaN(parsed.getTime()) ? str : parsed.toISOString().slice(0, 10);
|
|
1445
1498
|
}
|
|
1499
|
+
function actorLabel(record, field) {
|
|
1500
|
+
const actor = record[`${field}_actor`];
|
|
1501
|
+
if (actor && typeof actor === "object" && !Array.isArray(actor)) {
|
|
1502
|
+
const label = s(actor.label);
|
|
1503
|
+
const actorType = s(actor.actor_type);
|
|
1504
|
+
if (label) {
|
|
1505
|
+
return actorType ? `${label} (${actorType})` : label;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
return s(record[field]);
|
|
1509
|
+
}
|
|
1446
1510
|
function printEntitiesTable(entities) {
|
|
1447
1511
|
const table = makeTable("Entities", ["Ref", "Name", "Type", "Jurisdiction", "Status"]);
|
|
1448
1512
|
for (const e of entities) {
|
|
@@ -1848,7 +1912,7 @@ function printWorkItemsTable(items) {
|
|
|
1848
1912
|
s(w.category),
|
|
1849
1913
|
colored,
|
|
1850
1914
|
w.asap ? chalk.red.bold("ASAP") : s(w.deadline ?? ""),
|
|
1851
|
-
|
|
1915
|
+
actorLabel(w, "claimed_by")
|
|
1852
1916
|
]);
|
|
1853
1917
|
}
|
|
1854
1918
|
console.log(table.toString());
|
|
@@ -1862,17 +1926,29 @@ function printAgentsTable(agents) {
|
|
|
1862
1926
|
}
|
|
1863
1927
|
console.log(table.toString());
|
|
1864
1928
|
}
|
|
1865
|
-
function
|
|
1866
|
-
const table = makeTable("
|
|
1867
|
-
for (const
|
|
1868
|
-
let desc = s(a.description ?? a.summary);
|
|
1869
|
-
if (desc.length > 60) desc = desc.slice(0, 57) + "...";
|
|
1929
|
+
function printServiceCatalogTable(items) {
|
|
1930
|
+
const table = makeTable("Service Catalog", ["Slug", "Name", "Price", "Type"]);
|
|
1931
|
+
for (const item of items) {
|
|
1870
1932
|
table.push([
|
|
1871
|
-
s(
|
|
1872
|
-
s(
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1933
|
+
s(item.slug),
|
|
1934
|
+
s(item.name),
|
|
1935
|
+
money(item.amount_cents),
|
|
1936
|
+
s(item.price_type)
|
|
1937
|
+
]);
|
|
1938
|
+
}
|
|
1939
|
+
console.log(table.toString());
|
|
1940
|
+
}
|
|
1941
|
+
function printServiceRequestsTable(requests) {
|
|
1942
|
+
const table = makeTable("Service Requests", ["Ref", "Service", "Amount", "Status", "Created"]);
|
|
1943
|
+
for (const r of requests) {
|
|
1944
|
+
const status = s(r.status);
|
|
1945
|
+
const colored = status === "fulfilled" ? chalk.green(status) : status === "paid" ? chalk.cyan(status) : status === "checkout" ? chalk.yellow(status) : status === "failed" ? chalk.dim(status) : status;
|
|
1946
|
+
table.push([
|
|
1947
|
+
formatReferenceCell("service_request", r),
|
|
1948
|
+
s(r.service_slug),
|
|
1949
|
+
money(r.amount_cents),
|
|
1950
|
+
colored,
|
|
1951
|
+
date(r.created_at)
|
|
1876
1952
|
]);
|
|
1877
1953
|
}
|
|
1878
1954
|
console.log(table.toString());
|
|
@@ -1930,7 +2006,15 @@ var setup_exports = {};
|
|
|
1930
2006
|
__export(setup_exports, {
|
|
1931
2007
|
setupCommand: () => setupCommand
|
|
1932
2008
|
});
|
|
1933
|
-
import { input,
|
|
2009
|
+
import { input, select } from "@inquirer/prompts";
|
|
2010
|
+
import { homedir as homedir2 } from "os";
|
|
2011
|
+
import { join as join2 } from "path";
|
|
2012
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
2013
|
+
import {
|
|
2014
|
+
generateSecret,
|
|
2015
|
+
generateFernetKey,
|
|
2016
|
+
processRequest
|
|
2017
|
+
} from "@thecorporation/corp-tools";
|
|
1934
2018
|
async function requestMagicLink(apiUrl, email, tosAccepted) {
|
|
1935
2019
|
const resp = await fetch(`${apiUrl}/v1/auth/magic-link`, {
|
|
1936
2020
|
method: "POST",
|
|
@@ -1966,9 +2050,6 @@ async function verifyMagicLinkCode(apiUrl, code) {
|
|
|
1966
2050
|
workspace_id: data.workspace_id
|
|
1967
2051
|
};
|
|
1968
2052
|
}
|
|
1969
|
-
function isCloudApi(url) {
|
|
1970
|
-
return url.replace(/\/+$/, "").includes("thecorporation.ai");
|
|
1971
|
-
}
|
|
1972
2053
|
async function magicLinkAuth(apiUrl, email) {
|
|
1973
2054
|
console.log("\nSending magic link to " + email + "...");
|
|
1974
2055
|
await requestMagicLink(apiUrl, email, true);
|
|
@@ -1984,22 +2065,46 @@ async function magicLinkAuth(apiUrl, email) {
|
|
|
1984
2065
|
console.log("Verifying...");
|
|
1985
2066
|
return verifyMagicLinkCode(apiUrl, trimmed);
|
|
1986
2067
|
}
|
|
2068
|
+
function setupDataDir(dirPath) {
|
|
2069
|
+
if (!existsSync2(dirPath)) {
|
|
2070
|
+
mkdirSync2(dirPath, { recursive: true });
|
|
2071
|
+
return { isNew: true };
|
|
2072
|
+
}
|
|
2073
|
+
try {
|
|
2074
|
+
const entries = readdirSync(dirPath);
|
|
2075
|
+
if (entries.length > 0) {
|
|
2076
|
+
console.log("Found existing data, reusing.");
|
|
2077
|
+
return { isNew: false };
|
|
2078
|
+
}
|
|
2079
|
+
} catch {
|
|
2080
|
+
}
|
|
2081
|
+
return { isNew: true };
|
|
2082
|
+
}
|
|
2083
|
+
async function localProvision(dataDir, name) {
|
|
2084
|
+
const resp = processRequest(
|
|
2085
|
+
"process://",
|
|
2086
|
+
"POST",
|
|
2087
|
+
"/v1/workspaces/provision",
|
|
2088
|
+
{ "Content-Type": "application/json" },
|
|
2089
|
+
JSON.stringify({ name }),
|
|
2090
|
+
{ dataDir }
|
|
2091
|
+
);
|
|
2092
|
+
if (!resp.ok) {
|
|
2093
|
+
const detail = await resp.text();
|
|
2094
|
+
throw new Error(`Provision failed: HTTP ${resp.status} \u2014 ${detail}`);
|
|
2095
|
+
}
|
|
2096
|
+
const body = await resp.json();
|
|
2097
|
+
if (!body.api_key || !body.workspace_id) {
|
|
2098
|
+
throw new Error("Provision response missing api_key or workspace_id");
|
|
2099
|
+
}
|
|
2100
|
+
return {
|
|
2101
|
+
api_key: body.api_key,
|
|
2102
|
+
workspace_id: body.workspace_id
|
|
2103
|
+
};
|
|
2104
|
+
}
|
|
1987
2105
|
async function setupCommand() {
|
|
1988
2106
|
const cfg = loadConfig();
|
|
1989
2107
|
console.log("Welcome to corp \u2014 corporate governance from the terminal.\n");
|
|
1990
|
-
const customUrl = process.env.CORP_API_URL;
|
|
1991
|
-
if (customUrl) {
|
|
1992
|
-
try {
|
|
1993
|
-
cfg.api_url = validateApiUrl(customUrl);
|
|
1994
|
-
} catch (err) {
|
|
1995
|
-
printError(`Invalid CORP_API_URL: ${err}`);
|
|
1996
|
-
process.exit(1);
|
|
1997
|
-
}
|
|
1998
|
-
console.log(`Using API: ${cfg.api_url}
|
|
1999
|
-
`);
|
|
2000
|
-
} else {
|
|
2001
|
-
cfg.api_url = CLOUD_API_URL;
|
|
2002
|
-
}
|
|
2003
2108
|
console.log("--- User Info ---");
|
|
2004
2109
|
const user = cfg.user ?? { name: "", email: "" };
|
|
2005
2110
|
user.name = await input({
|
|
@@ -2011,10 +2116,53 @@ async function setupCommand() {
|
|
|
2011
2116
|
default: user.email || void 0
|
|
2012
2117
|
});
|
|
2013
2118
|
cfg.user = user;
|
|
2014
|
-
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
|
|
2119
|
+
console.log("\n--- Hosting Mode ---");
|
|
2120
|
+
const hostingMode = await select({
|
|
2121
|
+
message: "How would you like to run corp?",
|
|
2122
|
+
choices: [
|
|
2123
|
+
{ value: "local", name: "Local (your machine)" },
|
|
2124
|
+
{ value: "cloud", name: "TheCorporation cloud" },
|
|
2125
|
+
{ value: "self-hosted", name: "Self-hosted server (custom URL)" }
|
|
2126
|
+
],
|
|
2127
|
+
default: cfg.hosting_mode || "local"
|
|
2128
|
+
});
|
|
2129
|
+
cfg.hosting_mode = hostingMode;
|
|
2130
|
+
if (hostingMode === "local") {
|
|
2131
|
+
const dataDir = await input({
|
|
2132
|
+
message: "Data directory",
|
|
2133
|
+
default: cfg.data_dir || DEFAULT_DATA_DIR
|
|
2134
|
+
});
|
|
2135
|
+
cfg.data_dir = dataDir;
|
|
2136
|
+
cfg.api_url = "process://";
|
|
2137
|
+
const { isNew } = setupDataDir(dataDir);
|
|
2138
|
+
const serverSecrets = {
|
|
2139
|
+
jwt_secret: generateSecret(),
|
|
2140
|
+
secrets_master_key: generateFernetKey(),
|
|
2141
|
+
internal_worker_token: generateSecret()
|
|
2142
|
+
};
|
|
2143
|
+
process.env.JWT_SECRET = serverSecrets.jwt_secret;
|
|
2144
|
+
process.env.SECRETS_MASTER_KEY = serverSecrets.secrets_master_key;
|
|
2145
|
+
process.env.INTERNAL_WORKER_TOKEN = serverSecrets.internal_worker_token;
|
|
2146
|
+
cfg._server_secrets = serverSecrets;
|
|
2147
|
+
if (isNew || !cfg.workspace_id) {
|
|
2148
|
+
console.log("\nProvisioning workspace...");
|
|
2149
|
+
try {
|
|
2150
|
+
const result = await localProvision(dataDir, `${user.name}'s workspace`);
|
|
2151
|
+
cfg.api_key = result.api_key;
|
|
2152
|
+
cfg.workspace_id = result.workspace_id;
|
|
2153
|
+
printSuccess(`Local workspace ready: ${result.workspace_id}`);
|
|
2154
|
+
} catch (err) {
|
|
2155
|
+
printError(`Workspace provisioning failed: ${err}`);
|
|
2156
|
+
console.log("You can retry with 'corp setup'.");
|
|
2157
|
+
}
|
|
2158
|
+
} else {
|
|
2159
|
+
console.log("\nExisting workspace found.");
|
|
2160
|
+
}
|
|
2161
|
+
} else if (hostingMode === "cloud") {
|
|
2162
|
+
cfg.api_url = CLOUD_API_URL;
|
|
2163
|
+
cfg.data_dir = "";
|
|
2164
|
+
const needsAuth = !cfg.api_key || !cfg.workspace_id;
|
|
2165
|
+
if (needsAuth) {
|
|
2018
2166
|
try {
|
|
2019
2167
|
const result = await magicLinkAuth(cfg.api_url, user.email);
|
|
2020
2168
|
cfg.api_key = result.api_key;
|
|
@@ -2027,6 +2175,22 @@ async function setupCommand() {
|
|
|
2027
2175
|
);
|
|
2028
2176
|
}
|
|
2029
2177
|
} else {
|
|
2178
|
+
console.log("\nExisting credentials found. Run 'corp status' to verify.");
|
|
2179
|
+
}
|
|
2180
|
+
} else {
|
|
2181
|
+
const url = await input({
|
|
2182
|
+
message: "Server URL",
|
|
2183
|
+
default: cfg.api_url !== CLOUD_API_URL && !cfg.api_url.startsWith("process://") ? cfg.api_url : void 0
|
|
2184
|
+
});
|
|
2185
|
+
try {
|
|
2186
|
+
cfg.api_url = validateApiUrl(url);
|
|
2187
|
+
} catch (err) {
|
|
2188
|
+
printError(`Invalid URL: ${err}`);
|
|
2189
|
+
process.exit(1);
|
|
2190
|
+
}
|
|
2191
|
+
cfg.data_dir = "";
|
|
2192
|
+
const needsAuth = !cfg.api_key || !cfg.workspace_id;
|
|
2193
|
+
if (needsAuth) {
|
|
2030
2194
|
console.log("\nProvisioning workspace...");
|
|
2031
2195
|
try {
|
|
2032
2196
|
const result = await provisionWorkspace(
|
|
@@ -2043,57 +2207,13 @@ async function setupCommand() {
|
|
|
2043
2207
|
);
|
|
2044
2208
|
}
|
|
2045
2209
|
}
|
|
2046
|
-
} else {
|
|
2047
|
-
console.log("\nVerifying existing credentials...");
|
|
2048
|
-
let keyValid = false;
|
|
2049
|
-
try {
|
|
2050
|
-
const resp = await fetch(
|
|
2051
|
-
`${cfg.api_url.replace(/\/+$/, "")}/v1/workspaces/${cfg.workspace_id}/status`,
|
|
2052
|
-
{ headers: { Authorization: `Bearer ${cfg.api_key}` } }
|
|
2053
|
-
);
|
|
2054
|
-
keyValid = resp.status !== 401;
|
|
2055
|
-
} catch {
|
|
2056
|
-
}
|
|
2057
|
-
if (keyValid) {
|
|
2058
|
-
console.log("Credentials OK.");
|
|
2059
|
-
} else {
|
|
2060
|
-
console.log("API key is no longer valid.");
|
|
2061
|
-
const reauth = await confirm({
|
|
2062
|
-
message: cloud ? "Re-authenticate via magic link?" : "Provision a new workspace? (This will replace your current credentials)",
|
|
2063
|
-
default: true
|
|
2064
|
-
});
|
|
2065
|
-
if (reauth) {
|
|
2066
|
-
try {
|
|
2067
|
-
if (cloud) {
|
|
2068
|
-
const result = await magicLinkAuth(cfg.api_url, user.email);
|
|
2069
|
-
cfg.api_key = result.api_key;
|
|
2070
|
-
cfg.workspace_id = result.workspace_id;
|
|
2071
|
-
printSuccess(`Authenticated. Workspace: ${result.workspace_id}`);
|
|
2072
|
-
} else {
|
|
2073
|
-
const result = await provisionWorkspace(
|
|
2074
|
-
cfg.api_url,
|
|
2075
|
-
`${user.name}'s workspace`
|
|
2076
|
-
);
|
|
2077
|
-
cfg.api_key = result.api_key;
|
|
2078
|
-
cfg.workspace_id = result.workspace_id;
|
|
2079
|
-
console.log(`Workspace provisioned: ${result.workspace_id}`);
|
|
2080
|
-
}
|
|
2081
|
-
} catch (err) {
|
|
2082
|
-
printError(`Authentication failed: ${err}`);
|
|
2083
|
-
}
|
|
2084
|
-
} else {
|
|
2085
|
-
console.log(
|
|
2086
|
-
"Keeping existing credentials. You can manually update with: corp config set api_key <key>"
|
|
2087
|
-
);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
2210
|
}
|
|
2091
2211
|
saveConfig(cfg);
|
|
2092
2212
|
console.log("\nSettings saved to ~/.corp/config.json");
|
|
2093
2213
|
console.log("Credentials saved to ~/.corp/auth.json");
|
|
2094
2214
|
console.log("Run 'corp status' to verify your connection.");
|
|
2095
2215
|
}
|
|
2096
|
-
var CLOUD_API_URL;
|
|
2216
|
+
var CLOUD_API_URL, DEFAULT_DATA_DIR;
|
|
2097
2217
|
var init_setup = __esm({
|
|
2098
2218
|
"src/commands/setup.ts"() {
|
|
2099
2219
|
"use strict";
|
|
@@ -2101,6 +2221,7 @@ var init_setup = __esm({
|
|
|
2101
2221
|
init_api_client();
|
|
2102
2222
|
init_output();
|
|
2103
2223
|
CLOUD_API_URL = "https://api.thecorporation.ai";
|
|
2224
|
+
DEFAULT_DATA_DIR = join2(homedir2(), ".corp", "data");
|
|
2104
2225
|
}
|
|
2105
2226
|
});
|
|
2106
2227
|
|
|
@@ -3109,11 +3230,11 @@ import {
|
|
|
3109
3230
|
isWriteTool as _isWriteTool,
|
|
3110
3231
|
executeTool as _executeTool
|
|
3111
3232
|
} from "@thecorporation/corp-tools";
|
|
3112
|
-
import { join as
|
|
3113
|
-
import { homedir as
|
|
3233
|
+
import { join as join3 } from "path";
|
|
3234
|
+
import { homedir as homedir3 } from "os";
|
|
3114
3235
|
async function executeTool(name, args, client) {
|
|
3115
3236
|
return _executeTool(name, args, client, {
|
|
3116
|
-
dataDir:
|
|
3237
|
+
dataDir: join3(homedir3(), ".corp"),
|
|
3117
3238
|
onEntityFormed: (entityId) => {
|
|
3118
3239
|
try {
|
|
3119
3240
|
updateConfig((cfg) => {
|
|
@@ -3828,7 +3949,26 @@ async function fourOhNineACommand(opts) {
|
|
|
3828
3949
|
} catch (err) {
|
|
3829
3950
|
const msg = String(err);
|
|
3830
3951
|
if (msg.includes("404")) {
|
|
3831
|
-
|
|
3952
|
+
try {
|
|
3953
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
3954
|
+
const valuations = await client.getValuations(eid);
|
|
3955
|
+
const pending409a = valuations.filter((valuation) => valuation.valuation_type === "four_oh_nine_a").find((valuation) => valuation.status === "pending_approval");
|
|
3956
|
+
if (pending409a) {
|
|
3957
|
+
const effectiveDate = pending409a.effective_date ?? "unknown date";
|
|
3958
|
+
console.log(
|
|
3959
|
+
`No current approved 409A valuation found. A 409A valuation is pending approval (${effectiveDate}).
|
|
3960
|
+
Complete board approval, then re-run: corp cap-table 409a`
|
|
3961
|
+
);
|
|
3962
|
+
} else {
|
|
3963
|
+
console.log(
|
|
3964
|
+
"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>"
|
|
3965
|
+
);
|
|
3966
|
+
}
|
|
3967
|
+
} catch {
|
|
3968
|
+
console.log(
|
|
3969
|
+
"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>"
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3832
3972
|
} else {
|
|
3833
3973
|
printError(`Failed to fetch 409A valuation: ${err}`);
|
|
3834
3974
|
}
|
|
@@ -4361,8 +4501,112 @@ __export(finance_exports, {
|
|
|
4361
4501
|
financePayrollCommand: () => financePayrollCommand,
|
|
4362
4502
|
financePayrollRunsCommand: () => financePayrollRunsCommand,
|
|
4363
4503
|
financeReconcileCommand: () => financeReconcileCommand,
|
|
4364
|
-
financeReconciliationsCommand: () => financeReconciliationsCommand
|
|
4365
|
-
|
|
4504
|
+
financeReconciliationsCommand: () => financeReconciliationsCommand,
|
|
4505
|
+
financeSummaryCommand: () => financeSummaryCommand
|
|
4506
|
+
});
|
|
4507
|
+
function sumAmounts(records, candidates) {
|
|
4508
|
+
return records.reduce((sum, record) => {
|
|
4509
|
+
for (const key of candidates) {
|
|
4510
|
+
if (typeof record[key] === "number" && Number.isFinite(record[key])) {
|
|
4511
|
+
return sum + Number(record[key]);
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
return sum;
|
|
4515
|
+
}, 0);
|
|
4516
|
+
}
|
|
4517
|
+
function latestDate(records, candidates) {
|
|
4518
|
+
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);
|
|
4519
|
+
return values[0]?.raw;
|
|
4520
|
+
}
|
|
4521
|
+
function countByStatus(records, statuses) {
|
|
4522
|
+
const expected = new Set(statuses.map((status) => status.toLowerCase()));
|
|
4523
|
+
return records.filter((record) => expected.has(String(record.status ?? "").toLowerCase())).length;
|
|
4524
|
+
}
|
|
4525
|
+
function countByField(records, field, values) {
|
|
4526
|
+
const expected = new Set(values.map((value) => value.toLowerCase()));
|
|
4527
|
+
return records.filter((record) => expected.has(String(record[field] ?? "").toLowerCase())).length;
|
|
4528
|
+
}
|
|
4529
|
+
async function financeSummaryCommand(opts) {
|
|
4530
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
4531
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
4532
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
4533
|
+
try {
|
|
4534
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
4535
|
+
const [
|
|
4536
|
+
invoices,
|
|
4537
|
+
accounts,
|
|
4538
|
+
payments,
|
|
4539
|
+
payrollRuns,
|
|
4540
|
+
distributions,
|
|
4541
|
+
reconciliations,
|
|
4542
|
+
classifications
|
|
4543
|
+
] = await Promise.all([
|
|
4544
|
+
client.listInvoices(eid),
|
|
4545
|
+
client.listBankAccounts(eid),
|
|
4546
|
+
client.listPayments(eid),
|
|
4547
|
+
client.listPayrollRuns(eid),
|
|
4548
|
+
client.listDistributions(eid),
|
|
4549
|
+
client.listReconciliations(eid),
|
|
4550
|
+
client.listContractorClassifications(eid)
|
|
4551
|
+
]);
|
|
4552
|
+
await Promise.all([
|
|
4553
|
+
resolver.stabilizeRecords("invoice", invoices, eid),
|
|
4554
|
+
resolver.stabilizeRecords("bank_account", accounts, eid),
|
|
4555
|
+
resolver.stabilizeRecords("payment", payments, eid),
|
|
4556
|
+
resolver.stabilizeRecords("payroll_run", payrollRuns, eid),
|
|
4557
|
+
resolver.stabilizeRecords("distribution", distributions, eid),
|
|
4558
|
+
resolver.stabilizeRecords("reconciliation", reconciliations, eid),
|
|
4559
|
+
resolver.stabilizeRecords("classification", classifications, eid)
|
|
4560
|
+
]);
|
|
4561
|
+
const summary = {
|
|
4562
|
+
entity_id: eid,
|
|
4563
|
+
invoices: {
|
|
4564
|
+
count: invoices.length,
|
|
4565
|
+
open_count: invoices.length - countByStatus(invoices, ["paid", "cancelled", "void"]),
|
|
4566
|
+
overdue_count: countByStatus(invoices, ["overdue"]),
|
|
4567
|
+
total_amount_cents: sumAmounts(invoices, ["amount_cents", "total_amount_cents"]),
|
|
4568
|
+
latest_due_date: latestDate(invoices, ["due_date", "created_at"])
|
|
4569
|
+
},
|
|
4570
|
+
bank_accounts: {
|
|
4571
|
+
count: accounts.length,
|
|
4572
|
+
active_count: countByStatus(accounts, ["active", "approved", "open"])
|
|
4573
|
+
},
|
|
4574
|
+
payments: {
|
|
4575
|
+
count: payments.length,
|
|
4576
|
+
pending_count: countByStatus(payments, ["pending", "submitted", "queued"]),
|
|
4577
|
+
total_amount_cents: sumAmounts(payments, ["amount_cents"]),
|
|
4578
|
+
latest_submitted_at: latestDate(payments, ["submitted_at", "created_at"])
|
|
4579
|
+
},
|
|
4580
|
+
payroll_runs: {
|
|
4581
|
+
count: payrollRuns.length,
|
|
4582
|
+
latest_period_end: latestDate(payrollRuns, ["pay_period_end", "created_at"])
|
|
4583
|
+
},
|
|
4584
|
+
distributions: {
|
|
4585
|
+
count: distributions.length,
|
|
4586
|
+
total_amount_cents: sumAmounts(distributions, ["amount_cents", "distribution_amount_cents"]),
|
|
4587
|
+
latest_declared_at: latestDate(distributions, ["declared_at", "created_at"])
|
|
4588
|
+
},
|
|
4589
|
+
reconciliations: {
|
|
4590
|
+
count: reconciliations.length,
|
|
4591
|
+
balanced_count: reconciliations.filter((record) => record.is_balanced === true).length,
|
|
4592
|
+
latest_as_of_date: latestDate(reconciliations, ["as_of_date", "created_at"])
|
|
4593
|
+
},
|
|
4594
|
+
contractor_classifications: {
|
|
4595
|
+
count: classifications.length,
|
|
4596
|
+
high_risk_count: countByField(classifications, "risk_level", ["high"]),
|
|
4597
|
+
medium_risk_count: countByField(classifications, "risk_level", ["medium"])
|
|
4598
|
+
}
|
|
4599
|
+
};
|
|
4600
|
+
if (opts.json) {
|
|
4601
|
+
printJson(summary);
|
|
4602
|
+
return;
|
|
4603
|
+
}
|
|
4604
|
+
printFinanceSummaryPanel(summary);
|
|
4605
|
+
} catch (err) {
|
|
4606
|
+
printError(`Failed to fetch finance summary: ${err}`);
|
|
4607
|
+
process.exit(1);
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4366
4610
|
async function financeInvoicesCommand(opts) {
|
|
4367
4611
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
4368
4612
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
@@ -5102,12 +5346,206 @@ var init_governance = __esm({
|
|
|
5102
5346
|
}
|
|
5103
5347
|
});
|
|
5104
5348
|
|
|
5349
|
+
// src/formation-automation.ts
|
|
5350
|
+
function normalizeRole(value) {
|
|
5351
|
+
return String(value ?? "").trim().toLowerCase();
|
|
5352
|
+
}
|
|
5353
|
+
function fallbackSignerEmail(requirement) {
|
|
5354
|
+
const slug = String(requirement.signer_name ?? "signer").toLowerCase().replace(/[^a-z0-9]+/g, ".").replace(/^\.+|\.+$/g, "");
|
|
5355
|
+
return `${slug || "signer"}@example.com`;
|
|
5356
|
+
}
|
|
5357
|
+
function getSignatureRequirements(document) {
|
|
5358
|
+
const content = document.content;
|
|
5359
|
+
if (!content || typeof content !== "object" || Array.isArray(content)) {
|
|
5360
|
+
return [];
|
|
5361
|
+
}
|
|
5362
|
+
const requirements = content.signature_requirements;
|
|
5363
|
+
if (!Array.isArray(requirements)) {
|
|
5364
|
+
return [];
|
|
5365
|
+
}
|
|
5366
|
+
return requirements.filter((item) => typeof item === "object" && item !== null && !Array.isArray(item)).map((item) => ({
|
|
5367
|
+
role: String(item.role ?? "").trim(),
|
|
5368
|
+
signer_name: String(item.signer_name ?? "").trim(),
|
|
5369
|
+
signer_email: typeof item.signer_email === "string" && item.signer_email.trim() ? item.signer_email.trim() : void 0
|
|
5370
|
+
})).filter((item) => item.role.length > 0 && item.signer_name.length > 0);
|
|
5371
|
+
}
|
|
5372
|
+
function getSignedRoles(document) {
|
|
5373
|
+
const signatures = Array.isArray(document.signatures) ? document.signatures : [];
|
|
5374
|
+
return new Set(
|
|
5375
|
+
signatures.filter((item) => typeof item === "object" && item !== null && !Array.isArray(item)).map((item) => normalizeRole(item.signer_role)).filter(Boolean)
|
|
5376
|
+
);
|
|
5377
|
+
}
|
|
5378
|
+
function deterministicEin(entityId) {
|
|
5379
|
+
const digits = entityId.replace(/\D/g, "");
|
|
5380
|
+
const nineDigits = `${digits}123456789`.slice(0, 9).padEnd(9, "0");
|
|
5381
|
+
return `${nineDigits.slice(0, 2)}-${nineDigits.slice(2)}`;
|
|
5382
|
+
}
|
|
5383
|
+
function filingIdentifier(prefix, entityId) {
|
|
5384
|
+
const token = entityId.replace(/[^a-zA-Z0-9]/g, "").slice(0, 12).toLowerCase() || "formation";
|
|
5385
|
+
return `${prefix}-${token}`;
|
|
5386
|
+
}
|
|
5387
|
+
async function autoSignFormationDocument(client, entityId, documentId) {
|
|
5388
|
+
const document = await client.getDocument(documentId, entityId);
|
|
5389
|
+
const requiredSignatures = getSignatureRequirements(document);
|
|
5390
|
+
if (requiredSignatures.length === 0) {
|
|
5391
|
+
return { document, signatures_added: 0 };
|
|
5392
|
+
}
|
|
5393
|
+
const signedRoles = getSignedRoles(document);
|
|
5394
|
+
let signaturesAdded = 0;
|
|
5395
|
+
for (const requirement of requiredSignatures) {
|
|
5396
|
+
if (signedRoles.has(normalizeRole(requirement.role))) {
|
|
5397
|
+
continue;
|
|
5398
|
+
}
|
|
5399
|
+
await client.signDocument(documentId, entityId, {
|
|
5400
|
+
signer_name: requirement.signer_name,
|
|
5401
|
+
signer_role: requirement.role,
|
|
5402
|
+
signer_email: requirement.signer_email ?? fallbackSignerEmail(requirement),
|
|
5403
|
+
signature_text: requirement.signer_name,
|
|
5404
|
+
consent_text: DEFAULT_SIGNATURE_CONSENT
|
|
5405
|
+
});
|
|
5406
|
+
signedRoles.add(normalizeRole(requirement.role));
|
|
5407
|
+
signaturesAdded += 1;
|
|
5408
|
+
}
|
|
5409
|
+
const refreshed = await client.getDocument(documentId, entityId);
|
|
5410
|
+
return { document: refreshed, signatures_added: signaturesAdded };
|
|
5411
|
+
}
|
|
5412
|
+
async function autoSignFormationDocuments(client, resolver, entityId) {
|
|
5413
|
+
const summaries = await client.getEntityDocuments(entityId);
|
|
5414
|
+
await resolver.stabilizeRecords("document", summaries, entityId);
|
|
5415
|
+
let signaturesAdded = 0;
|
|
5416
|
+
let documentsSigned = 0;
|
|
5417
|
+
const documents = [];
|
|
5418
|
+
for (const summary of summaries) {
|
|
5419
|
+
const documentId = String(summary.document_id ?? "");
|
|
5420
|
+
if (!documentId) {
|
|
5421
|
+
continue;
|
|
5422
|
+
}
|
|
5423
|
+
const { document, signatures_added } = await autoSignFormationDocument(
|
|
5424
|
+
client,
|
|
5425
|
+
entityId,
|
|
5426
|
+
documentId
|
|
5427
|
+
);
|
|
5428
|
+
signaturesAdded += signatures_added;
|
|
5429
|
+
if (signatures_added > 0) {
|
|
5430
|
+
documentsSigned += 1;
|
|
5431
|
+
}
|
|
5432
|
+
documents.push(document);
|
|
5433
|
+
}
|
|
5434
|
+
return {
|
|
5435
|
+
documents_seen: summaries.length,
|
|
5436
|
+
documents_signed: documentsSigned,
|
|
5437
|
+
signatures_added: signaturesAdded,
|
|
5438
|
+
documents
|
|
5439
|
+
};
|
|
5440
|
+
}
|
|
5441
|
+
async function activateFormationEntity(client, resolver, entityId, options = {}) {
|
|
5442
|
+
let formation = await client.getFormation(entityId);
|
|
5443
|
+
const initialStatus = String(formation.formation_status ?? "");
|
|
5444
|
+
const steps = [];
|
|
5445
|
+
let signaturesAdded = 0;
|
|
5446
|
+
let documentsSigned = 0;
|
|
5447
|
+
for (let i = 0; i < 10; i += 1) {
|
|
5448
|
+
const status = String(formation.formation_status ?? "");
|
|
5449
|
+
if (status === "active") {
|
|
5450
|
+
return {
|
|
5451
|
+
entity_id: entityId,
|
|
5452
|
+
initial_status: initialStatus,
|
|
5453
|
+
final_status: status,
|
|
5454
|
+
signatures_added: signaturesAdded,
|
|
5455
|
+
documents_signed: documentsSigned,
|
|
5456
|
+
steps,
|
|
5457
|
+
formation
|
|
5458
|
+
};
|
|
5459
|
+
}
|
|
5460
|
+
if (status === "pending") {
|
|
5461
|
+
throw new Error("Formation is still pending. Finalize it before activation.");
|
|
5462
|
+
}
|
|
5463
|
+
if (status === "documents_generated") {
|
|
5464
|
+
const signed = await autoSignFormationDocuments(client, resolver, entityId);
|
|
5465
|
+
signaturesAdded += signed.signatures_added;
|
|
5466
|
+
documentsSigned += signed.documents_signed;
|
|
5467
|
+
await client.markFormationDocumentsSigned(entityId);
|
|
5468
|
+
steps.push(`signed ${signed.signatures_added} signatures across ${signed.documents_signed} documents`);
|
|
5469
|
+
formation = await client.getFormation(entityId);
|
|
5470
|
+
continue;
|
|
5471
|
+
}
|
|
5472
|
+
if (status === "documents_signed") {
|
|
5473
|
+
const gates = await client.getFormationGates(entityId);
|
|
5474
|
+
if (gates.requires_natural_person_attestation && !gates.attestation_recorded) {
|
|
5475
|
+
await client.recordFilingAttestation(entityId, {
|
|
5476
|
+
signer_name: gates.designated_attestor_name,
|
|
5477
|
+
signer_role: gates.designated_attestor_role,
|
|
5478
|
+
signer_email: gates.designated_attestor_email ?? fallbackSignerEmail({
|
|
5479
|
+
role: String(gates.designated_attestor_role ?? "attestor"),
|
|
5480
|
+
signer_name: String(gates.designated_attestor_name ?? "attestor")
|
|
5481
|
+
}),
|
|
5482
|
+
consent_text: DEFAULT_ATTESTATION_CONSENT,
|
|
5483
|
+
notes: "Recorded automatically by corp form activate"
|
|
5484
|
+
});
|
|
5485
|
+
steps.push("recorded filing attestation");
|
|
5486
|
+
}
|
|
5487
|
+
const gatesAfterAttestation = await client.getFormationGates(entityId);
|
|
5488
|
+
if (gatesAfterAttestation.requires_registered_agent_consent_evidence && Number(gatesAfterAttestation.registered_agent_consent_evidence_count ?? 0) === 0) {
|
|
5489
|
+
await client.addRegisteredAgentConsentEvidence(entityId, {
|
|
5490
|
+
evidence_uri: options.evidenceUri ?? `generated://registered-agent-consent/${entityId}`,
|
|
5491
|
+
evidence_type: options.evidenceType ?? "generated",
|
|
5492
|
+
notes: "Recorded automatically by corp form activate"
|
|
5493
|
+
});
|
|
5494
|
+
steps.push("recorded registered-agent consent evidence");
|
|
5495
|
+
}
|
|
5496
|
+
const finalGates = await client.getFormationGates(entityId);
|
|
5497
|
+
if (Array.isArray(finalGates.filing_submission_blockers) && finalGates.filing_submission_blockers.length > 0) {
|
|
5498
|
+
throw new Error(
|
|
5499
|
+
`Formation filing is still blocked: ${finalGates.filing_submission_blockers.join("; ")}`
|
|
5500
|
+
);
|
|
5501
|
+
}
|
|
5502
|
+
await client.submitFiling(entityId);
|
|
5503
|
+
steps.push("submitted filing");
|
|
5504
|
+
formation = await client.getFormation(entityId);
|
|
5505
|
+
continue;
|
|
5506
|
+
}
|
|
5507
|
+
if (status === "filing_submitted") {
|
|
5508
|
+
await client.confirmFiling(entityId, {
|
|
5509
|
+
external_filing_id: options.filingId ?? filingIdentifier("sim", entityId),
|
|
5510
|
+
receipt_reference: options.receiptReference ?? filingIdentifier("receipt", entityId)
|
|
5511
|
+
});
|
|
5512
|
+
steps.push("confirmed filing");
|
|
5513
|
+
formation = await client.getFormation(entityId);
|
|
5514
|
+
continue;
|
|
5515
|
+
}
|
|
5516
|
+
if (status === "filed") {
|
|
5517
|
+
await client.applyEin(entityId);
|
|
5518
|
+
steps.push("submitted EIN application");
|
|
5519
|
+
formation = await client.getFormation(entityId);
|
|
5520
|
+
continue;
|
|
5521
|
+
}
|
|
5522
|
+
if (status === "ein_applied") {
|
|
5523
|
+
await client.confirmEin(entityId, { ein: options.ein ?? deterministicEin(entityId) });
|
|
5524
|
+
steps.push("confirmed EIN");
|
|
5525
|
+
formation = await client.getFormation(entityId);
|
|
5526
|
+
continue;
|
|
5527
|
+
}
|
|
5528
|
+
throw new Error(`Unsupported formation status for activation: ${status || "unknown"}`);
|
|
5529
|
+
}
|
|
5530
|
+
throw new Error("Formation activation did not converge within 10 steps.");
|
|
5531
|
+
}
|
|
5532
|
+
var DEFAULT_SIGNATURE_CONSENT, DEFAULT_ATTESTATION_CONSENT;
|
|
5533
|
+
var init_formation_automation = __esm({
|
|
5534
|
+
"src/formation-automation.ts"() {
|
|
5535
|
+
"use strict";
|
|
5536
|
+
DEFAULT_SIGNATURE_CONSENT = "I agree to sign this document electronically.";
|
|
5537
|
+
DEFAULT_ATTESTATION_CONSENT = "I attest the filing information is accurate and authorized.";
|
|
5538
|
+
}
|
|
5539
|
+
});
|
|
5540
|
+
|
|
5105
5541
|
// src/commands/documents.ts
|
|
5106
5542
|
var documents_exports = {};
|
|
5107
5543
|
__export(documents_exports, {
|
|
5108
5544
|
documentsGenerateCommand: () => documentsGenerateCommand,
|
|
5109
5545
|
documentsListCommand: () => documentsListCommand,
|
|
5110
5546
|
documentsPreviewPdfCommand: () => documentsPreviewPdfCommand,
|
|
5547
|
+
documentsSignAllCommand: () => documentsSignAllCommand,
|
|
5548
|
+
documentsSignCommand: () => documentsSignCommand,
|
|
5111
5549
|
documentsSigningLinkCommand: () => documentsSigningLinkCommand
|
|
5112
5550
|
});
|
|
5113
5551
|
function formatSigningLink(docId, result) {
|
|
@@ -5213,7 +5651,78 @@ function coerceParamValue(raw) {
|
|
|
5213
5651
|
}
|
|
5214
5652
|
return raw;
|
|
5215
5653
|
}
|
|
5654
|
+
async function documentsSignCommand(docId, opts) {
|
|
5655
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
5656
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
5657
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
5658
|
+
try {
|
|
5659
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
5660
|
+
const resolvedDocumentId = await resolver.resolveDocument(eid, docId);
|
|
5661
|
+
if (opts.signerName || opts.signerRole || opts.signerEmail || opts.signatureText) {
|
|
5662
|
+
if (!opts.signerName || !opts.signerRole || !opts.signerEmail) {
|
|
5663
|
+
throw new Error("Manual signing requires --signer-name, --signer-role, and --signer-email.");
|
|
5664
|
+
}
|
|
5665
|
+
const result2 = await client.signDocument(resolvedDocumentId, eid, {
|
|
5666
|
+
signer_name: opts.signerName,
|
|
5667
|
+
signer_role: opts.signerRole,
|
|
5668
|
+
signer_email: opts.signerEmail,
|
|
5669
|
+
signature_text: opts.signatureText ?? opts.signerName
|
|
5670
|
+
});
|
|
5671
|
+
await resolver.stabilizeRecord("document", { document_id: resolvedDocumentId, title: docId }, eid);
|
|
5672
|
+
printWriteResult(result2, `Document ${resolvedDocumentId} signed.`, opts.json);
|
|
5673
|
+
return;
|
|
5674
|
+
}
|
|
5675
|
+
const result = await autoSignFormationDocument(client, eid, resolvedDocumentId);
|
|
5676
|
+
await resolver.stabilizeRecord("document", result.document, eid);
|
|
5677
|
+
resolver.rememberFromRecord("document", result.document, eid);
|
|
5678
|
+
if (opts.json) {
|
|
5679
|
+
printJson({
|
|
5680
|
+
document_id: resolvedDocumentId,
|
|
5681
|
+
signatures_added: result.signatures_added,
|
|
5682
|
+
document: result.document
|
|
5683
|
+
});
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
printSuccess(
|
|
5687
|
+
result.signatures_added > 0 ? `Applied ${result.signatures_added} signature(s) to ${resolvedDocumentId}.` : `No signatures were needed for ${resolvedDocumentId}.`
|
|
5688
|
+
);
|
|
5689
|
+
printReferenceSummary("document", result.document, { showReuseHint: true });
|
|
5690
|
+
printJson(result.document);
|
|
5691
|
+
} catch (err) {
|
|
5692
|
+
printError(`Failed to sign document: ${err}`);
|
|
5693
|
+
process.exit(1);
|
|
5694
|
+
}
|
|
5695
|
+
}
|
|
5696
|
+
async function documentsSignAllCommand(opts) {
|
|
5697
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
5698
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
5699
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
5700
|
+
try {
|
|
5701
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
5702
|
+
const result = await autoSignFormationDocuments(client, resolver, eid);
|
|
5703
|
+
if (opts.json) {
|
|
5704
|
+
printJson(result);
|
|
5705
|
+
return;
|
|
5706
|
+
}
|
|
5707
|
+
printSuccess(
|
|
5708
|
+
`Processed ${result.documents_seen} formation document(s); added ${result.signatures_added} signature(s) across ${result.documents_signed} document(s).`
|
|
5709
|
+
);
|
|
5710
|
+
printJson(result.documents.map((document) => ({
|
|
5711
|
+
document_id: document.document_id,
|
|
5712
|
+
title: document.title,
|
|
5713
|
+
status: document.status,
|
|
5714
|
+
signatures: Array.isArray(document.signatures) ? document.signatures.length : document.signatures
|
|
5715
|
+
})));
|
|
5716
|
+
} catch (err) {
|
|
5717
|
+
printError(`Failed to sign formation documents: ${err}`);
|
|
5718
|
+
process.exit(1);
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5216
5721
|
async function documentsPreviewPdfCommand(opts) {
|
|
5722
|
+
if (!opts.documentId || opts.documentId.trim().length === 0) {
|
|
5723
|
+
printError("preview-pdf requires --definition-id (or deprecated alias --document-id)");
|
|
5724
|
+
process.exit(1);
|
|
5725
|
+
}
|
|
5217
5726
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
5218
5727
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
5219
5728
|
const resolver = new ReferenceResolver(client, cfg);
|
|
@@ -5236,6 +5745,7 @@ var init_documents = __esm({
|
|
|
5236
5745
|
init_api_client();
|
|
5237
5746
|
init_output();
|
|
5238
5747
|
init_references();
|
|
5748
|
+
init_formation_automation();
|
|
5239
5749
|
HUMANS_APP_ORIGIN = "https://humans.thecorporation.ai";
|
|
5240
5750
|
}
|
|
5241
5751
|
});
|
|
@@ -5560,6 +6070,18 @@ __export(work_items_exports, {
|
|
|
5560
6070
|
workItemsShowCommand: () => workItemsShowCommand
|
|
5561
6071
|
});
|
|
5562
6072
|
import chalk10 from "chalk";
|
|
6073
|
+
function actorLabel2(record, key) {
|
|
6074
|
+
const actor = record[`${key}_actor`];
|
|
6075
|
+
if (actor && typeof actor === "object" && !Array.isArray(actor)) {
|
|
6076
|
+
const label = actor.label;
|
|
6077
|
+
const actorType = actor.actor_type;
|
|
6078
|
+
if (typeof label === "string" && label.trim()) {
|
|
6079
|
+
return typeof actorType === "string" && actorType.trim() ? `${label} (${actorType})` : label;
|
|
6080
|
+
}
|
|
6081
|
+
}
|
|
6082
|
+
const legacy = record[key];
|
|
6083
|
+
return typeof legacy === "string" && legacy.trim() ? legacy : void 0;
|
|
6084
|
+
}
|
|
5563
6085
|
async function workItemsListCommand(opts) {
|
|
5564
6086
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
5565
6087
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
@@ -5602,13 +6124,16 @@ async function workItemsShowCommand(workItemId, opts) {
|
|
|
5602
6124
|
if (w.description) console.log(` ${chalk10.bold("Description:")} ${w.description}`);
|
|
5603
6125
|
if (w.deadline) console.log(` ${chalk10.bold("Deadline:")} ${w.deadline}`);
|
|
5604
6126
|
if (w.asap) console.log(` ${chalk10.bold("Priority:")} ${chalk10.red.bold("ASAP")}`);
|
|
5605
|
-
|
|
6127
|
+
const claimedBy = actorLabel2(w, "claimed_by");
|
|
6128
|
+
const completedBy = actorLabel2(w, "completed_by");
|
|
6129
|
+
const createdBy = actorLabel2(w, "created_by");
|
|
6130
|
+
if (claimedBy) console.log(` ${chalk10.bold("Claimed by:")} ${claimedBy}`);
|
|
5606
6131
|
if (w.claimed_at) console.log(` ${chalk10.bold("Claimed at:")} ${w.claimed_at}`);
|
|
5607
6132
|
if (w.claim_ttl_seconds) console.log(` ${chalk10.bold("Claim TTL:")} ${w.claim_ttl_seconds}s`);
|
|
5608
|
-
if (
|
|
6133
|
+
if (completedBy) console.log(` ${chalk10.bold("Completed by:")} ${completedBy}`);
|
|
5609
6134
|
if (w.completed_at) console.log(` ${chalk10.bold("Completed at:")} ${w.completed_at}`);
|
|
5610
6135
|
if (w.result) console.log(` ${chalk10.bold("Result:")} ${w.result}`);
|
|
5611
|
-
if (
|
|
6136
|
+
if (createdBy) console.log(` ${chalk10.bold("Created by:")} ${createdBy}`);
|
|
5612
6137
|
console.log(` ${chalk10.bold("Created at:")} ${w.created_at ?? "N/A"}`);
|
|
5613
6138
|
console.log(chalk10.cyan("\u2500".repeat(40)));
|
|
5614
6139
|
} catch (err) {
|
|
@@ -5630,7 +6155,7 @@ async function workItemsCreateCommand(opts) {
|
|
|
5630
6155
|
if (opts.description) data.description = opts.description;
|
|
5631
6156
|
if (opts.deadline) data.deadline = opts.deadline;
|
|
5632
6157
|
if (opts.asap) data.asap = true;
|
|
5633
|
-
if (opts.createdBy) data.
|
|
6158
|
+
if (opts.createdBy) data.created_by_actor = await resolver.resolveWorkItemActor(eid, opts.createdBy);
|
|
5634
6159
|
const result = await client.createWorkItem(eid, data);
|
|
5635
6160
|
await resolver.stabilizeRecord("work_item", result, eid);
|
|
5636
6161
|
resolver.rememberFromRecord("work_item", result, eid);
|
|
@@ -5652,7 +6177,7 @@ async function workItemsClaimCommand(workItemId, opts) {
|
|
|
5652
6177
|
const eid = await resolver.resolveEntity(opts.entityId);
|
|
5653
6178
|
const resolvedWorkItemId = await resolver.resolveWorkItem(eid, workItemId);
|
|
5654
6179
|
const data = {
|
|
5655
|
-
|
|
6180
|
+
claimed_by_actor: await resolver.resolveWorkItemActor(eid, opts.claimedBy)
|
|
5656
6181
|
};
|
|
5657
6182
|
if (opts.ttl != null) data.ttl_seconds = opts.ttl;
|
|
5658
6183
|
const result = await client.claimWorkItem(eid, resolvedWorkItemId, data);
|
|
@@ -5670,7 +6195,7 @@ async function workItemsCompleteCommand(workItemId, opts) {
|
|
|
5670
6195
|
const eid = await resolver.resolveEntity(opts.entityId);
|
|
5671
6196
|
const resolvedWorkItemId = await resolver.resolveWorkItem(eid, workItemId);
|
|
5672
6197
|
const data = {
|
|
5673
|
-
|
|
6198
|
+
completed_by_actor: await resolver.resolveWorkItemActor(eid, opts.completedBy)
|
|
5674
6199
|
};
|
|
5675
6200
|
if (opts.result) data.result = opts.result;
|
|
5676
6201
|
const result = await client.completeWorkItem(eid, resolvedWorkItemId, data);
|
|
@@ -5718,6 +6243,171 @@ var init_work_items = __esm({
|
|
|
5718
6243
|
}
|
|
5719
6244
|
});
|
|
5720
6245
|
|
|
6246
|
+
// src/commands/services.ts
|
|
6247
|
+
var services_exports = {};
|
|
6248
|
+
__export(services_exports, {
|
|
6249
|
+
servicesBuyCommand: () => servicesBuyCommand,
|
|
6250
|
+
servicesCancelCommand: () => servicesCancelCommand,
|
|
6251
|
+
servicesCatalogCommand: () => servicesCatalogCommand,
|
|
6252
|
+
servicesFulfillCommand: () => servicesFulfillCommand,
|
|
6253
|
+
servicesListCommand: () => servicesListCommand,
|
|
6254
|
+
servicesShowCommand: () => servicesShowCommand
|
|
6255
|
+
});
|
|
6256
|
+
import chalk11 from "chalk";
|
|
6257
|
+
async function servicesCatalogCommand(opts) {
|
|
6258
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6259
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
6260
|
+
try {
|
|
6261
|
+
const items = await client.listServiceCatalog();
|
|
6262
|
+
if (opts.json) {
|
|
6263
|
+
printJson(items);
|
|
6264
|
+
return;
|
|
6265
|
+
}
|
|
6266
|
+
printServiceCatalogTable(items);
|
|
6267
|
+
} catch (err) {
|
|
6268
|
+
printError(`Failed to list service catalog: ${err}`);
|
|
6269
|
+
process.exit(1);
|
|
6270
|
+
}
|
|
6271
|
+
}
|
|
6272
|
+
async function servicesBuyCommand(slug, opts) {
|
|
6273
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6274
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
6275
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
6276
|
+
try {
|
|
6277
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
6278
|
+
const payload = { entity_id: eid, service_slug: slug };
|
|
6279
|
+
if (opts.dryRun) {
|
|
6280
|
+
printDryRun("services.create_request", payload);
|
|
6281
|
+
return;
|
|
6282
|
+
}
|
|
6283
|
+
const result = await client.createServiceRequest(payload);
|
|
6284
|
+
await resolver.stabilizeRecord("service_request", result, eid);
|
|
6285
|
+
resolver.rememberFromRecord("service_request", result, eid);
|
|
6286
|
+
const requestId = String(result.request_id ?? result.id ?? "");
|
|
6287
|
+
if (requestId) {
|
|
6288
|
+
const checkout = await client.beginServiceCheckout(requestId, { entity_id: eid });
|
|
6289
|
+
if (opts.json) {
|
|
6290
|
+
printJson(checkout);
|
|
6291
|
+
return;
|
|
6292
|
+
}
|
|
6293
|
+
printSuccess(`Service request created: ${requestId}`);
|
|
6294
|
+
printReferenceSummary("service_request", result, { showReuseHint: true });
|
|
6295
|
+
if (checkout.checkout_url) {
|
|
6296
|
+
console.log(`
|
|
6297
|
+
${chalk11.bold("Checkout URL:")} ${checkout.checkout_url}`);
|
|
6298
|
+
}
|
|
6299
|
+
console.log(chalk11.dim("\n Next steps:"));
|
|
6300
|
+
console.log(chalk11.dim(" Complete payment at the checkout URL above"));
|
|
6301
|
+
console.log(chalk11.dim(" corp services list --entity-id <id>"));
|
|
6302
|
+
} else {
|
|
6303
|
+
printWriteResult(result, "Service request created", {
|
|
6304
|
+
referenceKind: "service_request",
|
|
6305
|
+
showReuseHint: true
|
|
6306
|
+
});
|
|
6307
|
+
}
|
|
6308
|
+
} catch (err) {
|
|
6309
|
+
printError(`Failed to create service request: ${err}`);
|
|
6310
|
+
process.exit(1);
|
|
6311
|
+
}
|
|
6312
|
+
}
|
|
6313
|
+
async function servicesListCommand(opts) {
|
|
6314
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6315
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
6316
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
6317
|
+
try {
|
|
6318
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
6319
|
+
const requests = await client.listServiceRequests(eid);
|
|
6320
|
+
const stable = await resolver.stabilizeRecords("service_request", requests, eid);
|
|
6321
|
+
if (opts.json) {
|
|
6322
|
+
printJson(stable);
|
|
6323
|
+
return;
|
|
6324
|
+
}
|
|
6325
|
+
printServiceRequestsTable(stable);
|
|
6326
|
+
} catch (err) {
|
|
6327
|
+
printError(`Failed to list service requests: ${err}`);
|
|
6328
|
+
process.exit(1);
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
async function servicesShowCommand(ref_, opts) {
|
|
6332
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6333
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
6334
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
6335
|
+
try {
|
|
6336
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
6337
|
+
const requestId = await resolver.resolveServiceRequest(eid, ref_);
|
|
6338
|
+
const result = await client.getServiceRequest(requestId, eid);
|
|
6339
|
+
await resolver.stabilizeRecord("service_request", result, eid);
|
|
6340
|
+
resolver.rememberFromRecord("service_request", result, eid);
|
|
6341
|
+
if (opts.json) {
|
|
6342
|
+
printJson(result);
|
|
6343
|
+
return;
|
|
6344
|
+
}
|
|
6345
|
+
printReferenceSummary("service_request", result);
|
|
6346
|
+
printJson(result);
|
|
6347
|
+
} catch (err) {
|
|
6348
|
+
printError(`Failed to show service request: ${err}`);
|
|
6349
|
+
process.exit(1);
|
|
6350
|
+
}
|
|
6351
|
+
}
|
|
6352
|
+
async function servicesFulfillCommand(ref_, opts) {
|
|
6353
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6354
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
6355
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
6356
|
+
try {
|
|
6357
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
6358
|
+
const requestId = await resolver.resolveServiceRequest(eid, ref_);
|
|
6359
|
+
const result = await client.fulfillServiceRequest(requestId, {
|
|
6360
|
+
entity_id: eid,
|
|
6361
|
+
note: opts.note
|
|
6362
|
+
});
|
|
6363
|
+
await resolver.stabilizeRecord("service_request", result, eid);
|
|
6364
|
+
resolver.rememberFromRecord("service_request", result, eid);
|
|
6365
|
+
if (opts.json) {
|
|
6366
|
+
printJson(result);
|
|
6367
|
+
return;
|
|
6368
|
+
}
|
|
6369
|
+
printSuccess(`Service request fulfilled: ${requestId}`);
|
|
6370
|
+
printReferenceSummary("service_request", result, { showReuseHint: true });
|
|
6371
|
+
printJson(result);
|
|
6372
|
+
} catch (err) {
|
|
6373
|
+
printError(`Failed to fulfill service request: ${err}`);
|
|
6374
|
+
process.exit(1);
|
|
6375
|
+
}
|
|
6376
|
+
}
|
|
6377
|
+
async function servicesCancelCommand(ref_, opts) {
|
|
6378
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6379
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
6380
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
6381
|
+
try {
|
|
6382
|
+
const eid = await resolver.resolveEntity(opts.entityId);
|
|
6383
|
+
const requestId = await resolver.resolveServiceRequest(eid, ref_);
|
|
6384
|
+
const result = await client.cancelServiceRequest(requestId, {
|
|
6385
|
+
entity_id: eid
|
|
6386
|
+
});
|
|
6387
|
+
await resolver.stabilizeRecord("service_request", result, eid);
|
|
6388
|
+
resolver.rememberFromRecord("service_request", result, eid);
|
|
6389
|
+
if (opts.json) {
|
|
6390
|
+
printJson(result);
|
|
6391
|
+
return;
|
|
6392
|
+
}
|
|
6393
|
+
printSuccess(`Service request cancelled: ${requestId}`);
|
|
6394
|
+
printReferenceSummary("service_request", result, { showReuseHint: true });
|
|
6395
|
+
printJson(result);
|
|
6396
|
+
} catch (err) {
|
|
6397
|
+
printError(`Failed to cancel service request: ${err}`);
|
|
6398
|
+
process.exit(1);
|
|
6399
|
+
}
|
|
6400
|
+
}
|
|
6401
|
+
var init_services = __esm({
|
|
6402
|
+
"src/commands/services.ts"() {
|
|
6403
|
+
"use strict";
|
|
6404
|
+
init_config();
|
|
6405
|
+
init_api_client();
|
|
6406
|
+
init_output();
|
|
6407
|
+
init_references();
|
|
6408
|
+
}
|
|
6409
|
+
});
|
|
6410
|
+
|
|
5721
6411
|
// src/commands/billing.ts
|
|
5722
6412
|
var billing_exports = {};
|
|
5723
6413
|
__export(billing_exports, {
|
|
@@ -5794,16 +6484,42 @@ var init_billing = __esm({
|
|
|
5794
6484
|
}
|
|
5795
6485
|
});
|
|
5796
6486
|
|
|
6487
|
+
// src/commands/approvals.ts
|
|
6488
|
+
var approvals_exports = {};
|
|
6489
|
+
__export(approvals_exports, {
|
|
6490
|
+
approvalsListCommand: () => approvalsListCommand,
|
|
6491
|
+
approvalsRespondCommand: () => approvalsRespondCommand
|
|
6492
|
+
});
|
|
6493
|
+
async function approvalsListCommand(_opts) {
|
|
6494
|
+
printError(
|
|
6495
|
+
"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"
|
|
6496
|
+
);
|
|
6497
|
+
process.exit(1);
|
|
6498
|
+
}
|
|
6499
|
+
async function approvalsRespondCommand(_approvalId, _decision, _opts) {
|
|
6500
|
+
printError(
|
|
6501
|
+
"Approvals are managed through governance meetings.\n Use: corp governance vote <meeting-ref> <item-ref> --voter <contact-ref> --vote for"
|
|
6502
|
+
);
|
|
6503
|
+
process.exit(1);
|
|
6504
|
+
}
|
|
6505
|
+
var init_approvals = __esm({
|
|
6506
|
+
"src/commands/approvals.ts"() {
|
|
6507
|
+
"use strict";
|
|
6508
|
+
init_output();
|
|
6509
|
+
}
|
|
6510
|
+
});
|
|
6511
|
+
|
|
5797
6512
|
// src/commands/form.ts
|
|
5798
6513
|
var form_exports = {};
|
|
5799
6514
|
__export(form_exports, {
|
|
6515
|
+
formActivateCommand: () => formActivateCommand,
|
|
5800
6516
|
formAddFounderCommand: () => formAddFounderCommand,
|
|
5801
6517
|
formCommand: () => formCommand,
|
|
5802
6518
|
formCreateCommand: () => formCreateCommand,
|
|
5803
6519
|
formFinalizeCommand: () => formFinalizeCommand
|
|
5804
6520
|
});
|
|
5805
|
-
import { input as input2, select, confirm as confirm2, number } from "@inquirer/prompts";
|
|
5806
|
-
import
|
|
6521
|
+
import { input as input2, select as select2, confirm as confirm2, number } from "@inquirer/prompts";
|
|
6522
|
+
import chalk12 from "chalk";
|
|
5807
6523
|
import Table3 from "cli-table3";
|
|
5808
6524
|
import { readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
|
|
5809
6525
|
import { relative as relative2, resolve as resolve2 } from "path";
|
|
@@ -5813,9 +6529,9 @@ function isCorp(entityType) {
|
|
|
5813
6529
|
}
|
|
5814
6530
|
function sectionHeader(title) {
|
|
5815
6531
|
console.log();
|
|
5816
|
-
console.log(
|
|
5817
|
-
console.log(
|
|
5818
|
-
console.log(
|
|
6532
|
+
console.log(chalk12.blue("\u2500".repeat(50)));
|
|
6533
|
+
console.log(chalk12.blue.bold(` ${title}`));
|
|
6534
|
+
console.log(chalk12.blue("\u2500".repeat(50)));
|
|
5819
6535
|
}
|
|
5820
6536
|
function officerTitleLabel(title) {
|
|
5821
6537
|
switch (title) {
|
|
@@ -5975,7 +6691,7 @@ async function phaseEntityDetails(opts, serverCfg, scripted) {
|
|
|
5975
6691
|
if (scripted) {
|
|
5976
6692
|
entityType = "llc";
|
|
5977
6693
|
} else {
|
|
5978
|
-
entityType = await
|
|
6694
|
+
entityType = await select2({
|
|
5979
6695
|
message: "Entity type",
|
|
5980
6696
|
choices: [
|
|
5981
6697
|
{ value: "llc", name: "LLC" },
|
|
@@ -6034,13 +6750,13 @@ async function phasePeople(opts, entityType, scripted) {
|
|
|
6034
6750
|
}
|
|
6035
6751
|
const founderCount = await number({ message: "Number of founders (1-6)", default: 1 }) ?? 1;
|
|
6036
6752
|
for (let i = 0; i < founderCount; i++) {
|
|
6037
|
-
console.log(
|
|
6753
|
+
console.log(chalk12.dim(`
|
|
6038
6754
|
Founder ${i + 1} of ${founderCount}:`));
|
|
6039
6755
|
const name = await input2({ message: ` Name` });
|
|
6040
6756
|
const email = await input2({ message: ` Email` });
|
|
6041
6757
|
let role = "member";
|
|
6042
6758
|
if (isCorp(entityType)) {
|
|
6043
|
-
role = await
|
|
6759
|
+
role = await select2({
|
|
6044
6760
|
message: " Role",
|
|
6045
6761
|
choices: [
|
|
6046
6762
|
{ value: "director", name: "Director" },
|
|
@@ -6055,7 +6771,7 @@ async function phasePeople(opts, entityType, scripted) {
|
|
|
6055
6771
|
if (isCorp(entityType)) {
|
|
6056
6772
|
const wantOfficer = role === "officer" || await confirm2({ message: " Assign officer title?", default: i === 0 });
|
|
6057
6773
|
if (wantOfficer) {
|
|
6058
|
-
officerTitle = await
|
|
6774
|
+
officerTitle = await select2({
|
|
6059
6775
|
message: " Officer title",
|
|
6060
6776
|
choices: OfficerTitle.map((t) => ({
|
|
6061
6777
|
value: t,
|
|
@@ -6080,7 +6796,7 @@ async function phaseStock(opts, entityType, founders, scripted) {
|
|
|
6080
6796
|
const rofr = opts.rofr ?? (!scripted && isCorp(entityType) ? await confirm2({ message: "Right of first refusal?", default: true }) : isCorp(entityType));
|
|
6081
6797
|
if (!scripted) {
|
|
6082
6798
|
for (const f of founders) {
|
|
6083
|
-
console.log(
|
|
6799
|
+
console.log(chalk12.dim(`
|
|
6084
6800
|
Equity for ${f.name}:`));
|
|
6085
6801
|
if (isCorp(entityType)) {
|
|
6086
6802
|
const shares = await number({ message: ` Shares to purchase`, default: 0 });
|
|
@@ -6101,7 +6817,7 @@ async function phaseStock(opts, entityType, founders, scripted) {
|
|
|
6101
6817
|
if (wantVesting) {
|
|
6102
6818
|
const totalMonths = await number({ message: " Total vesting months", default: 48 }) ?? 48;
|
|
6103
6819
|
const cliffMonths = await number({ message: " Cliff months", default: 12 }) ?? 12;
|
|
6104
|
-
const acceleration = await
|
|
6820
|
+
const acceleration = await select2({
|
|
6105
6821
|
message: " Acceleration",
|
|
6106
6822
|
choices: [
|
|
6107
6823
|
{ value: "none", name: "None" },
|
|
@@ -6126,17 +6842,17 @@ async function phaseStock(opts, entityType, founders, scripted) {
|
|
|
6126
6842
|
}
|
|
6127
6843
|
function printSummary(entityType, name, jurisdiction, fiscalYearEnd, sCorpElection, founders, transferRestrictions, rofr) {
|
|
6128
6844
|
sectionHeader("Formation Summary");
|
|
6129
|
-
console.log(` ${
|
|
6130
|
-
console.log(` ${
|
|
6131
|
-
console.log(` ${
|
|
6132
|
-
console.log(` ${
|
|
6845
|
+
console.log(` ${chalk12.bold("Entity:")} ${name}`);
|
|
6846
|
+
console.log(` ${chalk12.bold("Type:")} ${entityType}`);
|
|
6847
|
+
console.log(` ${chalk12.bold("Jurisdiction:")} ${jurisdiction}`);
|
|
6848
|
+
console.log(` ${chalk12.bold("Fiscal Year End:")} ${fiscalYearEnd}`);
|
|
6133
6849
|
if (isCorp(entityType)) {
|
|
6134
|
-
console.log(` ${
|
|
6135
|
-
console.log(` ${
|
|
6136
|
-
console.log(` ${
|
|
6850
|
+
console.log(` ${chalk12.bold("S-Corp Election:")} ${sCorpElection ? "Yes" : "No"}`);
|
|
6851
|
+
console.log(` ${chalk12.bold("Transfer Restrictions:")} ${transferRestrictions ? "Yes" : "No"}`);
|
|
6852
|
+
console.log(` ${chalk12.bold("Right of First Refusal:")} ${rofr ? "Yes" : "No"}`);
|
|
6137
6853
|
}
|
|
6138
6854
|
const table = new Table3({
|
|
6139
|
-
head: [
|
|
6855
|
+
head: [chalk12.dim("Name"), chalk12.dim("Email"), chalk12.dim("Role"), chalk12.dim("Equity"), chalk12.dim("Officer")]
|
|
6140
6856
|
});
|
|
6141
6857
|
for (const f of founders) {
|
|
6142
6858
|
const equity = f.shares_purchased ? `${f.shares_purchased.toLocaleString()} shares` : f.ownership_pct ? `${f.ownership_pct}%` : "\u2014";
|
|
@@ -6163,7 +6879,7 @@ async function formCommand(opts) {
|
|
|
6163
6879
|
printSummary(entityType, name, jurisdiction, fiscalYearEnd, sCorpElection, founders, transferRestrictions, rofr);
|
|
6164
6880
|
const shouldProceed = scripted ? true : await confirm2({ message: "Proceed with formation?", default: true });
|
|
6165
6881
|
if (!shouldProceed) {
|
|
6166
|
-
console.log(
|
|
6882
|
+
console.log(chalk12.yellow("Formation cancelled."));
|
|
6167
6883
|
return;
|
|
6168
6884
|
}
|
|
6169
6885
|
const members = founders.map((f) => {
|
|
@@ -6219,17 +6935,17 @@ async function formCommand(opts) {
|
|
|
6219
6935
|
if (holders.length > 0) {
|
|
6220
6936
|
console.log();
|
|
6221
6937
|
const table = new Table3({
|
|
6222
|
-
head: [
|
|
6938
|
+
head: [chalk12.dim("Holder"), chalk12.dim("Shares"), chalk12.dim("Ownership %")]
|
|
6223
6939
|
});
|
|
6224
6940
|
for (const h of holders) {
|
|
6225
6941
|
const pct = typeof h.ownership_pct === "number" ? `${h.ownership_pct.toFixed(1)}%` : "\u2014";
|
|
6226
6942
|
table.push([String(h.name ?? "?"), String(h.shares ?? 0), pct]);
|
|
6227
6943
|
}
|
|
6228
|
-
console.log(
|
|
6944
|
+
console.log(chalk12.bold(" Cap Table:"));
|
|
6229
6945
|
console.log(table.toString());
|
|
6230
6946
|
}
|
|
6231
6947
|
if (result.next_action) {
|
|
6232
|
-
console.log(
|
|
6948
|
+
console.log(chalk12.yellow(`
|
|
6233
6949
|
Next: ${result.next_action}`));
|
|
6234
6950
|
}
|
|
6235
6951
|
} catch (err) {
|
|
@@ -6300,7 +7016,7 @@ async function formCreateCommand(opts) {
|
|
|
6300
7016
|
console.log(` Type: ${result.entity_type}`);
|
|
6301
7017
|
console.log(` Jurisdiction: ${result.jurisdiction}`);
|
|
6302
7018
|
console.log(` Status: ${result.formation_status}`);
|
|
6303
|
-
console.log(
|
|
7019
|
+
console.log(chalk12.yellow(`
|
|
6304
7020
|
Next: corp form add-founder @last:entity --name "..." --email "..." --role member --pct 50`));
|
|
6305
7021
|
} catch (err) {
|
|
6306
7022
|
printError(`Failed to create pending entity: ${err}`);
|
|
@@ -6338,7 +7054,7 @@ async function formAddFounderCommand(entityId, opts) {
|
|
|
6338
7054
|
const pct = typeof m.ownership_pct === "number" ? ` (${m.ownership_pct}%)` : "";
|
|
6339
7055
|
console.log(` - ${m.name} <${m.email ?? "no email"}> [${m.role ?? "member"}]${pct}`);
|
|
6340
7056
|
}
|
|
6341
|
-
console.log(
|
|
7057
|
+
console.log(chalk12.yellow(`
|
|
6342
7058
|
Next: add more founders or run: corp form finalize @last:entity`));
|
|
6343
7059
|
} catch (err) {
|
|
6344
7060
|
printError(`Failed to add founder: ${err}`);
|
|
@@ -6402,17 +7118,17 @@ async function formFinalizeCommand(entityId, opts) {
|
|
|
6402
7118
|
if (holders.length > 0) {
|
|
6403
7119
|
console.log();
|
|
6404
7120
|
const table = new Table3({
|
|
6405
|
-
head: [
|
|
7121
|
+
head: [chalk12.dim("Holder"), chalk12.dim("Shares"), chalk12.dim("Ownership %")]
|
|
6406
7122
|
});
|
|
6407
7123
|
for (const h of holders) {
|
|
6408
7124
|
const pct = typeof h.ownership_pct === "number" ? `${h.ownership_pct.toFixed(1)}%` : "\u2014";
|
|
6409
7125
|
table.push([String(h.name ?? "?"), String(h.shares ?? 0), pct]);
|
|
6410
7126
|
}
|
|
6411
|
-
console.log(
|
|
7127
|
+
console.log(chalk12.bold(" Cap Table:"));
|
|
6412
7128
|
console.log(table.toString());
|
|
6413
7129
|
}
|
|
6414
7130
|
if (result.next_action) {
|
|
6415
|
-
console.log(
|
|
7131
|
+
console.log(chalk12.yellow(`
|
|
6416
7132
|
Next: ${result.next_action}`));
|
|
6417
7133
|
}
|
|
6418
7134
|
} catch (err) {
|
|
@@ -6420,6 +7136,55 @@ async function formFinalizeCommand(entityId, opts) {
|
|
|
6420
7136
|
process.exit(1);
|
|
6421
7137
|
}
|
|
6422
7138
|
}
|
|
7139
|
+
async function formActivateCommand(entityId, opts) {
|
|
7140
|
+
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
7141
|
+
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
7142
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
7143
|
+
try {
|
|
7144
|
+
const resolvedEntityId = await resolveEntityRefForFormCommand(resolver, entityId, opts.dryRun);
|
|
7145
|
+
const payload = { entity_id: resolvedEntityId };
|
|
7146
|
+
if (opts.evidenceUri) payload.evidence_uri = opts.evidenceUri;
|
|
7147
|
+
if (opts.evidenceType) payload.evidence_type = opts.evidenceType;
|
|
7148
|
+
if (opts.filingId) payload.filing_id = opts.filingId;
|
|
7149
|
+
if (opts.receiptReference) payload.receipt_reference = opts.receiptReference;
|
|
7150
|
+
if (opts.ein) payload.ein = opts.ein;
|
|
7151
|
+
if (opts.dryRun) {
|
|
7152
|
+
printDryRun("formation.activate", payload);
|
|
7153
|
+
return;
|
|
7154
|
+
}
|
|
7155
|
+
const result = await activateFormationEntity(client, resolver, resolvedEntityId, {
|
|
7156
|
+
evidenceUri: opts.evidenceUri,
|
|
7157
|
+
evidenceType: opts.evidenceType,
|
|
7158
|
+
filingId: opts.filingId,
|
|
7159
|
+
receiptReference: opts.receiptReference,
|
|
7160
|
+
ein: opts.ein
|
|
7161
|
+
});
|
|
7162
|
+
const formation = await client.getFormation(resolvedEntityId);
|
|
7163
|
+
await resolver.stabilizeRecord("entity", formation);
|
|
7164
|
+
resolver.rememberFromRecord("entity", formation);
|
|
7165
|
+
if (opts.json) {
|
|
7166
|
+
printJson({
|
|
7167
|
+
...result,
|
|
7168
|
+
formation
|
|
7169
|
+
});
|
|
7170
|
+
return;
|
|
7171
|
+
}
|
|
7172
|
+
printSuccess(`Formation advanced to ${result.final_status}.`);
|
|
7173
|
+
printReferenceSummary("entity", formation, { showReuseHint: true });
|
|
7174
|
+
if (result.steps.length > 0) {
|
|
7175
|
+
console.log(" Steps:");
|
|
7176
|
+
for (const step of result.steps) {
|
|
7177
|
+
console.log(` - ${step}`);
|
|
7178
|
+
}
|
|
7179
|
+
}
|
|
7180
|
+
console.log(` Signatures added: ${result.signatures_added}`);
|
|
7181
|
+
console.log(` Documents updated: ${result.documents_signed}`);
|
|
7182
|
+
printJson(formation);
|
|
7183
|
+
} catch (err) {
|
|
7184
|
+
printError(`Failed to activate formation: ${err}`);
|
|
7185
|
+
process.exit(1);
|
|
7186
|
+
}
|
|
7187
|
+
}
|
|
6423
7188
|
var init_form = __esm({
|
|
6424
7189
|
"src/commands/form.ts"() {
|
|
6425
7190
|
"use strict";
|
|
@@ -6427,6 +7192,7 @@ var init_form = __esm({
|
|
|
6427
7192
|
init_api_client();
|
|
6428
7193
|
init_output();
|
|
6429
7194
|
init_references();
|
|
7195
|
+
init_formation_automation();
|
|
6430
7196
|
}
|
|
6431
7197
|
});
|
|
6432
7198
|
|
|
@@ -6435,7 +7201,7 @@ var api_keys_exports = {};
|
|
|
6435
7201
|
__export(api_keys_exports, {
|
|
6436
7202
|
apiKeysCommand: () => apiKeysCommand
|
|
6437
7203
|
});
|
|
6438
|
-
import
|
|
7204
|
+
import chalk13 from "chalk";
|
|
6439
7205
|
import Table4 from "cli-table3";
|
|
6440
7206
|
async function apiKeysCommand(opts) {
|
|
6441
7207
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
@@ -6455,9 +7221,9 @@ async function apiKeysCommand(opts) {
|
|
|
6455
7221
|
return;
|
|
6456
7222
|
}
|
|
6457
7223
|
console.log(`
|
|
6458
|
-
${
|
|
7224
|
+
${chalk13.bold("API Keys")}`);
|
|
6459
7225
|
const table = new Table4({
|
|
6460
|
-
head: [
|
|
7226
|
+
head: [chalk13.dim("ID"), chalk13.dim("Name"), chalk13.dim("Key"), chalk13.dim("Created")]
|
|
6461
7227
|
});
|
|
6462
7228
|
for (const k of keys) {
|
|
6463
7229
|
table.push([
|
|
@@ -6487,12 +7253,235 @@ var demo_exports = {};
|
|
|
6487
7253
|
__export(demo_exports, {
|
|
6488
7254
|
demoCommand: () => demoCommand
|
|
6489
7255
|
});
|
|
7256
|
+
function scenarioConfig(name, scenario) {
|
|
7257
|
+
switch (scenario) {
|
|
7258
|
+
case "llc":
|
|
7259
|
+
return {
|
|
7260
|
+
entity_type: "llc",
|
|
7261
|
+
legal_name: name,
|
|
7262
|
+
jurisdiction: "US-WY",
|
|
7263
|
+
members: [
|
|
7264
|
+
{
|
|
7265
|
+
name: "Alice Chen",
|
|
7266
|
+
email: "alice@example.com",
|
|
7267
|
+
role: "member",
|
|
7268
|
+
investor_type: "natural_person",
|
|
7269
|
+
ownership_pct: 60
|
|
7270
|
+
},
|
|
7271
|
+
{
|
|
7272
|
+
name: "Bob Martinez",
|
|
7273
|
+
email: "bob@example.com",
|
|
7274
|
+
role: "member",
|
|
7275
|
+
investor_type: "natural_person",
|
|
7276
|
+
ownership_pct: 40
|
|
7277
|
+
}
|
|
7278
|
+
],
|
|
7279
|
+
fiscal_year_end: "12-31",
|
|
7280
|
+
company_address: {
|
|
7281
|
+
street: "251 Little Falls Dr",
|
|
7282
|
+
city: "Wilmington",
|
|
7283
|
+
state: "DE",
|
|
7284
|
+
zip: "19808"
|
|
7285
|
+
}
|
|
7286
|
+
};
|
|
7287
|
+
case "restaurant":
|
|
7288
|
+
return {
|
|
7289
|
+
entity_type: "llc",
|
|
7290
|
+
legal_name: name,
|
|
7291
|
+
jurisdiction: "US-DE",
|
|
7292
|
+
members: [
|
|
7293
|
+
{
|
|
7294
|
+
name: "Rosa Alvarez",
|
|
7295
|
+
email: "rosa@example.com",
|
|
7296
|
+
role: "manager",
|
|
7297
|
+
investor_type: "natural_person",
|
|
7298
|
+
ownership_pct: 55
|
|
7299
|
+
},
|
|
7300
|
+
{
|
|
7301
|
+
name: "Noah Patel",
|
|
7302
|
+
email: "noah@example.com",
|
|
7303
|
+
role: "member",
|
|
7304
|
+
investor_type: "natural_person",
|
|
7305
|
+
ownership_pct: 45
|
|
7306
|
+
}
|
|
7307
|
+
],
|
|
7308
|
+
fiscal_year_end: "12-31",
|
|
7309
|
+
company_address: {
|
|
7310
|
+
street: "18 Market St",
|
|
7311
|
+
city: "Wilmington",
|
|
7312
|
+
state: "DE",
|
|
7313
|
+
zip: "19801"
|
|
7314
|
+
}
|
|
7315
|
+
};
|
|
7316
|
+
case "startup":
|
|
7317
|
+
default:
|
|
7318
|
+
return {
|
|
7319
|
+
entity_type: "c_corp",
|
|
7320
|
+
legal_name: name,
|
|
7321
|
+
jurisdiction: "US-DE",
|
|
7322
|
+
authorized_shares: 1e7,
|
|
7323
|
+
par_value: "0.0001",
|
|
7324
|
+
transfer_restrictions: true,
|
|
7325
|
+
right_of_first_refusal: true,
|
|
7326
|
+
members: [
|
|
7327
|
+
{
|
|
7328
|
+
name: "Alice Chen",
|
|
7329
|
+
email: "alice@example.com",
|
|
7330
|
+
role: "chair",
|
|
7331
|
+
investor_type: "natural_person",
|
|
7332
|
+
shares_purchased: 6e6,
|
|
7333
|
+
officer_title: "ceo",
|
|
7334
|
+
is_incorporator: true
|
|
7335
|
+
},
|
|
7336
|
+
{
|
|
7337
|
+
name: "Bob Martinez",
|
|
7338
|
+
email: "bob@example.com",
|
|
7339
|
+
role: "director",
|
|
7340
|
+
investor_type: "natural_person",
|
|
7341
|
+
shares_purchased: 4e6,
|
|
7342
|
+
officer_title: "cto"
|
|
7343
|
+
}
|
|
7344
|
+
],
|
|
7345
|
+
fiscal_year_end: "12-31",
|
|
7346
|
+
company_address: {
|
|
7347
|
+
street: "251 Little Falls Dr",
|
|
7348
|
+
city: "Wilmington",
|
|
7349
|
+
state: "DE",
|
|
7350
|
+
zip: "19808"
|
|
7351
|
+
}
|
|
7352
|
+
};
|
|
7353
|
+
}
|
|
7354
|
+
}
|
|
7355
|
+
function meetingTypeForBody(body) {
|
|
7356
|
+
return String(body.body_type) === "llc_member_vote" ? "member_meeting" : "board_meeting";
|
|
7357
|
+
}
|
|
6490
7358
|
async function demoCommand(opts) {
|
|
6491
7359
|
const cfg = requireConfig("api_url", "api_key", "workspace_id");
|
|
6492
7360
|
const client = new CorpAPIClient(cfg.api_url, cfg.api_key, cfg.workspace_id);
|
|
7361
|
+
const resolver = new ReferenceResolver(client, cfg);
|
|
7362
|
+
const scenario = opts.scenario ?? "startup";
|
|
6493
7363
|
try {
|
|
6494
|
-
|
|
6495
|
-
|
|
7364
|
+
if (opts.minimal) {
|
|
7365
|
+
const result2 = await withSpinner("Loading", () => client.seedDemo({
|
|
7366
|
+
name: opts.name,
|
|
7367
|
+
scenario
|
|
7368
|
+
}));
|
|
7369
|
+
if (opts.json) {
|
|
7370
|
+
printJson(result2);
|
|
7371
|
+
return;
|
|
7372
|
+
}
|
|
7373
|
+
printSuccess("Minimal demo seeded.");
|
|
7374
|
+
printJson(result2);
|
|
7375
|
+
return;
|
|
7376
|
+
}
|
|
7377
|
+
const formationPayload = scenarioConfig(opts.name, scenario);
|
|
7378
|
+
const created = await withSpinner(
|
|
7379
|
+
"Creating demo entity",
|
|
7380
|
+
() => client.createFormationWithCapTable(formationPayload)
|
|
7381
|
+
);
|
|
7382
|
+
const entityId = String(created.entity_id ?? created.formation_id ?? "");
|
|
7383
|
+
if (!entityId) {
|
|
7384
|
+
throw new Error("demo formation did not return an entity_id");
|
|
7385
|
+
}
|
|
7386
|
+
await resolver.stabilizeRecord("entity", created);
|
|
7387
|
+
resolver.rememberFromRecord("entity", created);
|
|
7388
|
+
const activation = await withSpinner(
|
|
7389
|
+
"Activating formation",
|
|
7390
|
+
() => activateFormationEntity(client, resolver, entityId)
|
|
7391
|
+
);
|
|
7392
|
+
const agent = await withSpinner(
|
|
7393
|
+
"Creating demo agent",
|
|
7394
|
+
() => client.createAgent({
|
|
7395
|
+
name: `${opts.name} Operator`,
|
|
7396
|
+
entity_id: entityId,
|
|
7397
|
+
system_prompt: `Operate ${opts.name} and keep the workspace data clean.`,
|
|
7398
|
+
scopes: []
|
|
7399
|
+
})
|
|
7400
|
+
);
|
|
7401
|
+
await resolver.stabilizeRecord("agent", agent);
|
|
7402
|
+
resolver.rememberFromRecord("agent", agent);
|
|
7403
|
+
const bodies = await client.listGovernanceBodies(entityId);
|
|
7404
|
+
await resolver.stabilizeRecords("body", bodies, entityId);
|
|
7405
|
+
let meeting;
|
|
7406
|
+
if (bodies.length > 0) {
|
|
7407
|
+
meeting = await client.scheduleMeeting({
|
|
7408
|
+
entity_id: entityId,
|
|
7409
|
+
body_id: bodies[0].body_id,
|
|
7410
|
+
meeting_type: meetingTypeForBody(bodies[0]),
|
|
7411
|
+
title: "Demo kickoff meeting",
|
|
7412
|
+
agenda_item_titles: [
|
|
7413
|
+
"Approve demo operating budget",
|
|
7414
|
+
"Review founder vesting and cap table"
|
|
7415
|
+
]
|
|
7416
|
+
});
|
|
7417
|
+
await resolver.stabilizeRecord("meeting", meeting, entityId);
|
|
7418
|
+
resolver.rememberFromRecord("meeting", meeting, entityId);
|
|
7419
|
+
}
|
|
7420
|
+
const workItem = await client.createWorkItem(entityId, {
|
|
7421
|
+
title: "Review demo workspace",
|
|
7422
|
+
description: "Check documents, governance, cap table, and treasury setup.",
|
|
7423
|
+
category: "ops",
|
|
7424
|
+
created_by_actor: {
|
|
7425
|
+
actor_type: "agent",
|
|
7426
|
+
actor_id: String(agent.agent_id)
|
|
7427
|
+
}
|
|
7428
|
+
});
|
|
7429
|
+
await resolver.stabilizeRecord("work_item", workItem, entityId);
|
|
7430
|
+
resolver.rememberFromRecord("work_item", workItem, entityId);
|
|
7431
|
+
const claimedWorkItem = await client.claimWorkItem(entityId, String(workItem.work_item_id), {
|
|
7432
|
+
claimed_by_actor: {
|
|
7433
|
+
actor_type: "agent",
|
|
7434
|
+
actor_id: String(agent.agent_id)
|
|
7435
|
+
}
|
|
7436
|
+
});
|
|
7437
|
+
const bankAccount = await client.openBankAccount({
|
|
7438
|
+
entity_id: entityId,
|
|
7439
|
+
bank_name: "Mercury"
|
|
7440
|
+
});
|
|
7441
|
+
await resolver.stabilizeRecord("bank_account", bankAccount, entityId);
|
|
7442
|
+
resolver.rememberFromRecord("bank_account", bankAccount, entityId);
|
|
7443
|
+
const invoice = await client.createInvoice({
|
|
7444
|
+
entity_id: entityId,
|
|
7445
|
+
customer_name: "Acme Customer",
|
|
7446
|
+
amount_cents: 25e4,
|
|
7447
|
+
due_date: "2026-04-01",
|
|
7448
|
+
description: "Demo advisory services"
|
|
7449
|
+
});
|
|
7450
|
+
await resolver.stabilizeRecord("invoice", invoice, entityId);
|
|
7451
|
+
resolver.rememberFromRecord("invoice", invoice, entityId);
|
|
7452
|
+
const contract = await client.generateContract({
|
|
7453
|
+
entity_id: entityId,
|
|
7454
|
+
template_type: "nda",
|
|
7455
|
+
counterparty_name: "Example Counterparty",
|
|
7456
|
+
effective_date: "2026-03-12",
|
|
7457
|
+
parameters: {}
|
|
7458
|
+
});
|
|
7459
|
+
await resolver.stabilizeRecord("document", contract, entityId);
|
|
7460
|
+
resolver.rememberFromRecord("document", contract, entityId);
|
|
7461
|
+
const result = {
|
|
7462
|
+
scenario,
|
|
7463
|
+
entity: created,
|
|
7464
|
+
activation,
|
|
7465
|
+
agent,
|
|
7466
|
+
meeting,
|
|
7467
|
+
work_item: claimedWorkItem,
|
|
7468
|
+
bank_account: bankAccount,
|
|
7469
|
+
invoice,
|
|
7470
|
+
contract
|
|
7471
|
+
};
|
|
7472
|
+
if (opts.json) {
|
|
7473
|
+
printJson(result);
|
|
7474
|
+
return;
|
|
7475
|
+
}
|
|
7476
|
+
printSuccess(`Demo environment created for ${opts.name}.`);
|
|
7477
|
+
printReferenceSummary("entity", created, { showReuseHint: true });
|
|
7478
|
+
printReferenceSummary("agent", agent, { showReuseHint: true });
|
|
7479
|
+
if (meeting) {
|
|
7480
|
+
printReferenceSummary("meeting", meeting, { showReuseHint: true });
|
|
7481
|
+
}
|
|
7482
|
+
printReferenceSummary("work_item", claimedWorkItem, { showReuseHint: true });
|
|
7483
|
+
printReferenceSummary("invoice", invoice, { showReuseHint: true });
|
|
7484
|
+
printReferenceSummary("bank_account", bankAccount, { showReuseHint: true });
|
|
6496
7485
|
printJson(result);
|
|
6497
7486
|
} catch (err) {
|
|
6498
7487
|
printError(`Failed to seed demo: ${err}`);
|
|
@@ -6506,6 +7495,8 @@ var init_demo = __esm({
|
|
|
6506
7495
|
init_api_client();
|
|
6507
7496
|
init_output();
|
|
6508
7497
|
init_spinner();
|
|
7498
|
+
init_references();
|
|
7499
|
+
init_formation_automation();
|
|
6509
7500
|
}
|
|
6510
7501
|
});
|
|
6511
7502
|
|
|
@@ -6514,7 +7505,7 @@ var feedback_exports = {};
|
|
|
6514
7505
|
__export(feedback_exports, {
|
|
6515
7506
|
feedbackCommand: () => feedbackCommand
|
|
6516
7507
|
});
|
|
6517
|
-
import
|
|
7508
|
+
import chalk14 from "chalk";
|
|
6518
7509
|
async function feedbackCommand(message, opts) {
|
|
6519
7510
|
if (!message || message.trim().length === 0) {
|
|
6520
7511
|
printError("Feedback message cannot be empty");
|
|
@@ -6533,9 +7524,17 @@ async function feedbackCommand(message, opts) {
|
|
|
6533
7524
|
return;
|
|
6534
7525
|
}
|
|
6535
7526
|
console.log(`
|
|
6536
|
-
${
|
|
7527
|
+
${chalk14.green("\u2713")} Feedback submitted (${chalk14.dim(result.feedback_id)})`);
|
|
6537
7528
|
} catch (err) {
|
|
6538
|
-
|
|
7529
|
+
const detail = String(err);
|
|
7530
|
+
if (detail.includes("404")) {
|
|
7531
|
+
printError(
|
|
7532
|
+
`Failed to submit feedback: ${detail}
|
|
7533
|
+
This server does not expose /v1/feedback. Local api-rs dev servers currently do not support feedback submission.`
|
|
7534
|
+
);
|
|
7535
|
+
} else {
|
|
7536
|
+
printError(`Failed to submit feedback: ${detail}`);
|
|
7537
|
+
}
|
|
6539
7538
|
process.exit(1);
|
|
6540
7539
|
}
|
|
6541
7540
|
}
|
|
@@ -6555,38 +7554,8 @@ var serve_exports = {};
|
|
|
6555
7554
|
__export(serve_exports, {
|
|
6556
7555
|
serveCommand: () => serveCommand
|
|
6557
7556
|
});
|
|
6558
|
-
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
|
|
6559
7557
|
import { resolve as resolve3 } from "path";
|
|
6560
|
-
import {
|
|
6561
|
-
function generateFernetKey() {
|
|
6562
|
-
return randomBytes(32).toString("base64url") + "=";
|
|
6563
|
-
}
|
|
6564
|
-
function generateSecret(length = 32) {
|
|
6565
|
-
return randomBytes(length).toString("hex");
|
|
6566
|
-
}
|
|
6567
|
-
function loadEnvFile(path) {
|
|
6568
|
-
if (!existsSync2(path)) return;
|
|
6569
|
-
const content = readFileSync4(path, "utf-8");
|
|
6570
|
-
for (const line of content.split("\n")) {
|
|
6571
|
-
const trimmed = line.trim();
|
|
6572
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
6573
|
-
const eqIdx = trimmed.indexOf("=");
|
|
6574
|
-
if (eqIdx === -1) continue;
|
|
6575
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
6576
|
-
const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
|
|
6577
|
-
if (!process.env[key]) {
|
|
6578
|
-
process.env[key] = value;
|
|
6579
|
-
}
|
|
6580
|
-
}
|
|
6581
|
-
}
|
|
6582
|
-
function ensureEnvFile(envPath) {
|
|
6583
|
-
if (existsSync2(envPath)) return;
|
|
6584
|
-
console.log("No .env file found. Generating one with dev defaults...\n");
|
|
6585
|
-
const content = ENV_TEMPLATE.replace("{{JWT_SECRET}}", generateSecret()).replace("{{SECRETS_MASTER_KEY}}", generateFernetKey()).replace("{{INTERNAL_WORKER_TOKEN}}", generateSecret());
|
|
6586
|
-
writeFileSync2(envPath, content, "utf-8");
|
|
6587
|
-
console.log(` Created ${envPath}
|
|
6588
|
-
`);
|
|
6589
|
-
}
|
|
7558
|
+
import { ensureEnvFile, loadEnvFile } from "@thecorporation/corp-tools";
|
|
6590
7559
|
async function serveCommand(opts) {
|
|
6591
7560
|
let server;
|
|
6592
7561
|
try {
|
|
@@ -6631,40 +7600,9 @@ async function serveCommand(opts) {
|
|
|
6631
7600
|
process.exit(code ?? 0);
|
|
6632
7601
|
});
|
|
6633
7602
|
}
|
|
6634
|
-
var ENV_TEMPLATE;
|
|
6635
7603
|
var init_serve = __esm({
|
|
6636
7604
|
"src/commands/serve.ts"() {
|
|
6637
7605
|
"use strict";
|
|
6638
|
-
ENV_TEMPLATE = `# Corporation API server configuration
|
|
6639
|
-
# Generated by: corp serve
|
|
6640
|
-
|
|
6641
|
-
# Required \u2014 secret for signing JWTs
|
|
6642
|
-
JWT_SECRET={{JWT_SECRET}}
|
|
6643
|
-
|
|
6644
|
-
# Required \u2014 Fernet key for encrypting secrets at rest (base64url, 32 bytes)
|
|
6645
|
-
SECRETS_MASTER_KEY={{SECRETS_MASTER_KEY}}
|
|
6646
|
-
|
|
6647
|
-
# Required \u2014 bearer token for internal worker-to-server auth
|
|
6648
|
-
INTERNAL_WORKER_TOKEN={{INTERNAL_WORKER_TOKEN}}
|
|
6649
|
-
|
|
6650
|
-
# Server port (default: 8000)
|
|
6651
|
-
# PORT=8000
|
|
6652
|
-
|
|
6653
|
-
# Data directory for git repos (default: ./data/repos)
|
|
6654
|
-
# DATA_DIR=./data/repos
|
|
6655
|
-
|
|
6656
|
-
# Redis URL for agent job queue (optional)
|
|
6657
|
-
# REDIS_URL=redis://localhost:6379/0
|
|
6658
|
-
|
|
6659
|
-
# LLM proxy upstream (default: https://openrouter.ai/api/v1)
|
|
6660
|
-
# LLM_UPSTREAM_URL=https://openrouter.ai/api/v1
|
|
6661
|
-
|
|
6662
|
-
# PEM-encoded Ed25519 key for signing git commits (optional)
|
|
6663
|
-
# COMMIT_SIGNING_KEY=
|
|
6664
|
-
|
|
6665
|
-
# Max agent queue depth (default: 1000)
|
|
6666
|
-
# MAX_QUEUE_DEPTH=1000
|
|
6667
|
-
`;
|
|
6668
7606
|
}
|
|
6669
7607
|
});
|
|
6670
7608
|
|
|
@@ -6699,6 +7637,12 @@ var TAX_DOCUMENT_TYPE_CHOICES = [
|
|
|
6699
7637
|
"w2",
|
|
6700
7638
|
"form_w2"
|
|
6701
7639
|
];
|
|
7640
|
+
var FINALIZE_ITEM_STATUS_CHOICES = [
|
|
7641
|
+
"discussed",
|
|
7642
|
+
"voted",
|
|
7643
|
+
"tabled",
|
|
7644
|
+
"withdrawn"
|
|
7645
|
+
];
|
|
6702
7646
|
var program = new Command();
|
|
6703
7647
|
program.name("corp").description("corp \u2014 Corporate governance from the terminal").version(pkg.version);
|
|
6704
7648
|
program.command("setup").description("Interactive setup wizard").action(async () => {
|
|
@@ -6949,7 +7893,10 @@ capTableCmd.command("approve-valuation <valuation-ref>").option("--resolution-id
|
|
|
6949
7893
|
json: inheritOption(opts.json, parent.json)
|
|
6950
7894
|
});
|
|
6951
7895
|
});
|
|
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")
|
|
7896
|
+
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) => {
|
|
7897
|
+
const { financeSummaryCommand: financeSummaryCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
|
|
7898
|
+
await financeSummaryCommand2(opts);
|
|
7899
|
+
});
|
|
6953
7900
|
financeCmd.command("invoices").option("--json", "Output as JSON").description("List invoices").action(async (opts, cmd) => {
|
|
6954
7901
|
const parent = cmd.parent.opts();
|
|
6955
7902
|
const { financeInvoicesCommand: financeInvoicesCommand2 } = await Promise.resolve().then(() => (init_finance(), finance_exports));
|
|
@@ -7173,7 +8120,12 @@ governanceCmd.command("agenda-items <meeting-ref>").description("List agenda ite
|
|
|
7173
8120
|
const { listAgendaItemsCommand: listAgendaItemsCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
7174
8121
|
await listAgendaItemsCommand2(meetingId, { entityId: parent.entityId, json: parent.json });
|
|
7175
8122
|
});
|
|
7176
|
-
governanceCmd.command("finalize-item <meeting-ref> <item-ref>").
|
|
8123
|
+
governanceCmd.command("finalize-item <meeting-ref> <item-ref>").addOption(
|
|
8124
|
+
new Option(
|
|
8125
|
+
"--status <status>",
|
|
8126
|
+
`Status (${FINALIZE_ITEM_STATUS_CHOICES.join(", ")})`
|
|
8127
|
+
).choices([...FINALIZE_ITEM_STATUS_CHOICES]).makeOptionMandatory()
|
|
8128
|
+
).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
8129
|
const parent = cmd.parent.opts();
|
|
7178
8130
|
const { finalizeAgendaItemCommand: finalizeAgendaItemCommand2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
7179
8131
|
await finalizeAgendaItemCommand2(meetingId, itemId, {
|
|
@@ -7209,6 +8161,24 @@ documentsCmd.command("signing-link <doc-ref>").option("--entity-id <ref>", "Enti
|
|
|
7209
8161
|
const { documentsSigningLinkCommand: documentsSigningLinkCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
7210
8162
|
await documentsSigningLinkCommand2(docId, { entityId: opts.entityId ?? parent.entityId });
|
|
7211
8163
|
});
|
|
8164
|
+
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) => {
|
|
8165
|
+
const parent = cmd.parent.opts();
|
|
8166
|
+
const { documentsSignCommand: documentsSignCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
8167
|
+
await documentsSignCommand2(docId, {
|
|
8168
|
+
...opts,
|
|
8169
|
+
entityId: opts.entityId ?? parent.entityId,
|
|
8170
|
+
json: inheritOption(opts.json, parent.json)
|
|
8171
|
+
});
|
|
8172
|
+
});
|
|
8173
|
+
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) => {
|
|
8174
|
+
const parent = cmd.parent.opts();
|
|
8175
|
+
const { documentsSignAllCommand: documentsSignAllCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
8176
|
+
await documentsSignAllCommand2({
|
|
8177
|
+
...opts,
|
|
8178
|
+
entityId: opts.entityId ?? parent.entityId,
|
|
8179
|
+
json: inheritOption(opts.json, parent.json)
|
|
8180
|
+
});
|
|
8181
|
+
});
|
|
7212
8182
|
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
8183
|
const parent = cmd.parent.opts();
|
|
7214
8184
|
const { documentsGenerateCommand: documentsGenerateCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
@@ -7218,7 +8188,7 @@ documentsCmd.command("generate").requiredOption("--template <type>", "Template t
|
|
|
7218
8188
|
json: inheritOption(opts.json, parent.json)
|
|
7219
8189
|
});
|
|
7220
8190
|
});
|
|
7221
|
-
documentsCmd.command("preview-pdf").
|
|
8191
|
+
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
8192
|
const parent = cmd.parent.opts();
|
|
7223
8193
|
const { documentsPreviewPdfCommand: documentsPreviewPdfCommand2 } = await Promise.resolve().then(() => (init_documents(), documents_exports));
|
|
7224
8194
|
await documentsPreviewPdfCommand2({
|
|
@@ -7390,6 +8360,59 @@ workItemsCmd.command("cancel <item-ref>").option("--json", "Output as JSON").des
|
|
|
7390
8360
|
json: inheritOption(opts.json, parent.json)
|
|
7391
8361
|
});
|
|
7392
8362
|
});
|
|
8363
|
+
var servicesCmd = program.command("services").description("Service catalog and fulfillment").option("--entity-id <ref>", "Entity reference (ID, short ID, @last, or unique name)").option("--json", "Output as JSON");
|
|
8364
|
+
servicesCmd.command("catalog").option("--json", "Output as JSON").description("List the service catalog").action(async (opts, cmd) => {
|
|
8365
|
+
const parent = cmd.parent.opts();
|
|
8366
|
+
const { servicesCatalogCommand: servicesCatalogCommand2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
8367
|
+
await servicesCatalogCommand2({
|
|
8368
|
+
json: inheritOption(opts.json, parent.json)
|
|
8369
|
+
});
|
|
8370
|
+
});
|
|
8371
|
+
servicesCmd.command("buy <slug>").option("--json", "Output as JSON").option("--dry-run", "Show the request without executing").description("Purchase a service from the catalog").action(async (slug, opts, cmd) => {
|
|
8372
|
+
const parent = cmd.parent.opts();
|
|
8373
|
+
const { servicesBuyCommand: servicesBuyCommand2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
8374
|
+
await servicesBuyCommand2(slug, {
|
|
8375
|
+
...opts,
|
|
8376
|
+
entityId: parent.entityId,
|
|
8377
|
+
json: inheritOption(opts.json, parent.json)
|
|
8378
|
+
});
|
|
8379
|
+
});
|
|
8380
|
+
servicesCmd.command("list").option("--json", "Output as JSON").description("List service requests for an entity").action(async (opts, cmd) => {
|
|
8381
|
+
const parent = cmd.parent.opts();
|
|
8382
|
+
const { servicesListCommand: servicesListCommand2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
8383
|
+
await servicesListCommand2({
|
|
8384
|
+
...opts,
|
|
8385
|
+
entityId: parent.entityId,
|
|
8386
|
+
json: inheritOption(opts.json, parent.json)
|
|
8387
|
+
});
|
|
8388
|
+
});
|
|
8389
|
+
servicesCmd.command("show <ref>").option("--json", "Output as JSON").description("Show service request detail").action(async (ref_, opts, cmd) => {
|
|
8390
|
+
const parent = cmd.parent.opts();
|
|
8391
|
+
const { servicesShowCommand: servicesShowCommand2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
8392
|
+
await servicesShowCommand2(ref_, {
|
|
8393
|
+
...opts,
|
|
8394
|
+
entityId: parent.entityId,
|
|
8395
|
+
json: inheritOption(opts.json, parent.json)
|
|
8396
|
+
});
|
|
8397
|
+
});
|
|
8398
|
+
servicesCmd.command("fulfill <ref>").option("--note <note>", "Fulfillment note").option("--json", "Output as JSON").description("Mark a service request as fulfilled (operator)").action(async (ref_, opts, cmd) => {
|
|
8399
|
+
const parent = cmd.parent.opts();
|
|
8400
|
+
const { servicesFulfillCommand: servicesFulfillCommand2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
8401
|
+
await servicesFulfillCommand2(ref_, {
|
|
8402
|
+
...opts,
|
|
8403
|
+
entityId: parent.entityId,
|
|
8404
|
+
json: inheritOption(opts.json, parent.json)
|
|
8405
|
+
});
|
|
8406
|
+
});
|
|
8407
|
+
servicesCmd.command("cancel <ref>").option("--json", "Output as JSON").description("Cancel a service request").action(async (ref_, opts, cmd) => {
|
|
8408
|
+
const parent = cmd.parent.opts();
|
|
8409
|
+
const { servicesCancelCommand: servicesCancelCommand2 } = await Promise.resolve().then(() => (init_services(), services_exports));
|
|
8410
|
+
await servicesCancelCommand2(ref_, {
|
|
8411
|
+
...opts,
|
|
8412
|
+
entityId: parent.entityId,
|
|
8413
|
+
json: inheritOption(opts.json, parent.json)
|
|
8414
|
+
});
|
|
8415
|
+
});
|
|
7393
8416
|
var billingCmd = program.command("billing").description("Billing status, plans, and subscription management").option("--json", "Output as JSON").action(async (opts) => {
|
|
7394
8417
|
const { billingCommand: billingCommand2 } = await Promise.resolve().then(() => (init_billing(), billing_exports));
|
|
7395
8418
|
await billingCommand2(opts);
|
|
@@ -7403,10 +8426,8 @@ billingCmd.command("upgrade").option("--plan <plan>", "Plan ID to upgrade to (fr
|
|
|
7403
8426
|
await billingUpgradeCommand2(opts);
|
|
7404
8427
|
});
|
|
7405
8428
|
program.command("approvals").description("Approvals are managed through governance meetings and execution intents").action(async () => {
|
|
7406
|
-
const {
|
|
7407
|
-
|
|
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
|
-
);
|
|
8429
|
+
const { approvalsListCommand: approvalsListCommand2 } = await Promise.resolve().then(() => (init_approvals(), approvals_exports));
|
|
8430
|
+
await approvalsListCommand2({});
|
|
7410
8431
|
});
|
|
7411
8432
|
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
8433
|
if (opts.entityType && !opts.type) opts.type = opts.entityType;
|
|
@@ -7415,11 +8436,13 @@ var formCmd = program.command("form").description("Form a new entity with founde
|
|
|
7415
8436
|
await formCommand2(opts);
|
|
7416
8437
|
});
|
|
7417
8438
|
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) => {
|
|
8439
|
+
const parent = cmd.parent.opts();
|
|
7418
8440
|
const { formCreateCommand: formCreateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
7419
8441
|
await formCreateCommand2({
|
|
7420
8442
|
...opts,
|
|
7421
|
-
|
|
7422
|
-
|
|
8443
|
+
jurisdiction: inheritOption(opts.jurisdiction, parent.jurisdiction),
|
|
8444
|
+
json: inheritOption(opts.json, parent.json),
|
|
8445
|
+
dryRun: inheritOption(opts.dryRun, parent.dryRun)
|
|
7423
8446
|
});
|
|
7424
8447
|
});
|
|
7425
8448
|
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 +8461,19 @@ formCmd.command("finalize <entity-ref>").description("Finalize formation and gen
|
|
|
7438
8461
|
dryRun: inheritOption(opts.dryRun, cmd.parent.opts().dryRun)
|
|
7439
8462
|
});
|
|
7440
8463
|
});
|
|
8464
|
+
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) => {
|
|
8465
|
+
const { formActivateCommand: formActivateCommand2 } = await Promise.resolve().then(() => (init_form(), form_exports));
|
|
8466
|
+
await formActivateCommand2(entityId, {
|
|
8467
|
+
...opts,
|
|
8468
|
+
json: inheritOption(opts.json, cmd.parent.opts().json),
|
|
8469
|
+
dryRun: inheritOption(opts.dryRun, cmd.parent.opts().dryRun)
|
|
8470
|
+
});
|
|
8471
|
+
});
|
|
7441
8472
|
program.command("api-keys").description("List API keys").option("--json", "Output as JSON").action(async (opts) => {
|
|
7442
8473
|
const { apiKeysCommand: apiKeysCommand2 } = await Promise.resolve().then(() => (init_api_keys(), api_keys_exports));
|
|
7443
8474
|
await apiKeysCommand2(opts);
|
|
7444
8475
|
});
|
|
7445
|
-
program.command("demo").description("
|
|
8476
|
+
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
8477
|
const { demoCommand: demoCommand2 } = await Promise.resolve().then(() => (init_demo(), demo_exports));
|
|
7447
8478
|
await demoCommand2(opts);
|
|
7448
8479
|
});
|