@fairmint/captable-ai 0.1.4 → 0.1.6
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 +1 -1
- package/dist/index.js +631 -68
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ automated, but a few habits make extraction faster and more accurate:
|
|
|
88
88
|
| `documents upload\|list\|download\|delete` | Manage source documents |
|
|
89
89
|
| `documents trigger-extraction\|cancel-extraction\|restart-extraction\|reprocess` | Control the OCF extraction pipeline |
|
|
90
90
|
| `documents processing-status\|classification-types\|classification-update` | Inspect document status / classification |
|
|
91
|
-
| `objects list\|get\|update\|patch\|revert\|versions\|delete` | Work with extracted OCF objects |
|
|
91
|
+
| `objects list\|get\|dump\|update\|patch\|revert\|versions\|delete` | Work with extracted OCF objects (`list` supports `--document`, `--stakeholder`, `--all`, `--max-confidence`; `dump` writes engine-shaped `ocf.json`) |
|
|
92
92
|
| `schemas list\|get` | Browse the OCF object-type registry |
|
|
93
93
|
| `commit` | Commit drafts to the cap table — `--all` or `--objects id1,id2` (`--dry-run` to preview) |
|
|
94
94
|
| `summary` | Full cap table snapshot |
|
package/dist/index.js
CHANGED
|
@@ -543,7 +543,7 @@ var COMMAND_REGISTRY = [
|
|
|
543
543
|
name: "objects list",
|
|
544
544
|
group: "captable",
|
|
545
545
|
description: "List OCF objects with filtering and pagination.",
|
|
546
|
-
usage: "captable-ai objects list [--type TYPE] [--subtype SUBTYPE] [--status STATUS] [--limit N] [--cursor C] [--q QUERY] [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--ids IDS] [--json]",
|
|
546
|
+
usage: "captable-ai objects list [--type TYPE] [--subtype SUBTYPE] [--status STATUS] [--limit N] [--cursor C] [--q QUERY] [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--ids IDS] [--stakeholder ID] [--document ID] [--all] [--max-confidence N] [--json]",
|
|
547
547
|
requiresAuth: true,
|
|
548
548
|
requiresPortal: true,
|
|
549
549
|
flags: [
|
|
@@ -576,7 +576,27 @@ var COMMAND_REGISTRY = [
|
|
|
576
576
|
description: "Filter objects with date <= (YYYY-MM-DD, inclusive).",
|
|
577
577
|
type: "string"
|
|
578
578
|
},
|
|
579
|
-
{ name: "ids", description: "Batch fetch by comma-separated IDs.", type: "string" }
|
|
579
|
+
{ name: "ids", description: "Batch fetch by comma-separated IDs.", type: "string" },
|
|
580
|
+
{
|
|
581
|
+
name: "stakeholder",
|
|
582
|
+
description: "Filter by OCF stakeholder id.",
|
|
583
|
+
type: "string"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
name: "document",
|
|
587
|
+
description: "Filter by source document s3 asset id.",
|
|
588
|
+
type: "string"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
name: "all",
|
|
592
|
+
description: "Follow pagination cursors until every matching object is returned.",
|
|
593
|
+
type: "boolean"
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
name: "max-confidence",
|
|
597
|
+
description: "Keep objects with extraction confidence <= N. Requires --all.",
|
|
598
|
+
type: "number"
|
|
599
|
+
}
|
|
580
600
|
]
|
|
581
601
|
},
|
|
582
602
|
{
|
|
@@ -587,6 +607,27 @@ var COMMAND_REGISTRY = [
|
|
|
587
607
|
requiresAuth: true,
|
|
588
608
|
requiresPortal: true
|
|
589
609
|
},
|
|
610
|
+
{
|
|
611
|
+
name: "objects dump",
|
|
612
|
+
group: "captable",
|
|
613
|
+
description: "Write engine-shaped ocf.json from object ocf payloads.",
|
|
614
|
+
usage: "captable-ai objects dump [--status committed|draft] [--output path]",
|
|
615
|
+
requiresAuth: true,
|
|
616
|
+
requiresPortal: true,
|
|
617
|
+
flags: [
|
|
618
|
+
{
|
|
619
|
+
name: "status",
|
|
620
|
+
description: "Filter by status: draft or committed. Default committed.",
|
|
621
|
+
type: "string",
|
|
622
|
+
enum: ["draft", "committed"]
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
name: "output",
|
|
626
|
+
description: "Write JSON to this file (global --output; implies --json).",
|
|
627
|
+
type: "string"
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
},
|
|
590
631
|
{
|
|
591
632
|
name: "schemas list",
|
|
592
633
|
group: "captable",
|
|
@@ -1127,7 +1168,7 @@ var COMMAND_REGISTRY = [
|
|
|
1127
1168
|
}
|
|
1128
1169
|
];
|
|
1129
1170
|
async function runCommands(_args) {
|
|
1130
|
-
printJson({ schemaVersion: "
|
|
1171
|
+
printJson({ schemaVersion: "8", version: "0.0.1", commands: COMMAND_REGISTRY });
|
|
1131
1172
|
}
|
|
1132
1173
|
|
|
1133
1174
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
@@ -16023,6 +16064,235 @@ var exportResultSchema = external_exports.object({
|
|
|
16023
16064
|
}).optional().describe("Present when pro-forma sheets were requested but engine refused.")
|
|
16024
16065
|
});
|
|
16025
16066
|
|
|
16067
|
+
// ../captable-ai-core/dist/objects-dump.js
|
|
16068
|
+
var DumpAssemblyError = class extends Error {
|
|
16069
|
+
constructor(message) {
|
|
16070
|
+
super(message);
|
|
16071
|
+
this.name = "DumpAssemblyError";
|
|
16072
|
+
}
|
|
16073
|
+
};
|
|
16074
|
+
var ISSUANCE_TYPES = /* @__PURE__ */ new Set([
|
|
16075
|
+
"TX_STOCK_ISSUANCE",
|
|
16076
|
+
"TX_CONVERTIBLE_ISSUANCE",
|
|
16077
|
+
"TX_WARRANT_ISSUANCE",
|
|
16078
|
+
"TX_EQUITY_COMPENSATION_ISSUANCE",
|
|
16079
|
+
"TX_PLAN_SECURITY_ISSUANCE"
|
|
16080
|
+
]);
|
|
16081
|
+
var CONVERSION_PARENT_TYPES = /* @__PURE__ */ new Set([
|
|
16082
|
+
"TX_CONVERTIBLE_CONVERSION",
|
|
16083
|
+
"TX_WARRANT_EXERCISE",
|
|
16084
|
+
"TX_EQUITY_COMPENSATION_EXERCISE",
|
|
16085
|
+
"TX_EQUITY_COMPENSATION_RELEASE",
|
|
16086
|
+
"TX_PLAN_SECURITY_RELEASE",
|
|
16087
|
+
"TX_STOCK_TRANSFER",
|
|
16088
|
+
"TX_STOCK_CONVERSION",
|
|
16089
|
+
"TX_CONVERTIBLE_TRANSFER",
|
|
16090
|
+
"TX_WARRANT_TRANSFER",
|
|
16091
|
+
"TX_EQUITY_COMPENSATION_TRANSFER",
|
|
16092
|
+
"TX_PLAN_SECURITY_TRANSFER",
|
|
16093
|
+
"TX_STOCK_REISSUANCE"
|
|
16094
|
+
]);
|
|
16095
|
+
function isRecord(value) {
|
|
16096
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16097
|
+
}
|
|
16098
|
+
function canonicalType(obj) {
|
|
16099
|
+
const type = String(obj.type ?? "").toUpperCase();
|
|
16100
|
+
if (type === "OBJECT")
|
|
16101
|
+
return String(obj.subtype ?? "").toUpperCase();
|
|
16102
|
+
return type;
|
|
16103
|
+
}
|
|
16104
|
+
function issuerForEngine(payload) {
|
|
16105
|
+
if (payload.initial_shares_authorized == null && payload.authorized_shares != null) {
|
|
16106
|
+
return { ...payload, initial_shares_authorized: payload.authorized_shares };
|
|
16107
|
+
}
|
|
16108
|
+
return payload;
|
|
16109
|
+
}
|
|
16110
|
+
function payloadId(payload, fallback) {
|
|
16111
|
+
return typeof payload.id === "string" && payload.id.length > 0 ? payload.id : fallback;
|
|
16112
|
+
}
|
|
16113
|
+
function pushByOcfId(bucket, payload, fallback) {
|
|
16114
|
+
bucket.set(payloadId(payload, fallback), payload);
|
|
16115
|
+
}
|
|
16116
|
+
function timestampMs(input, defaultValue) {
|
|
16117
|
+
if (input == null)
|
|
16118
|
+
return defaultValue;
|
|
16119
|
+
const ms = typeof input === "number" ? input : new Date(String(input)).getTime();
|
|
16120
|
+
return Number.isNaN(ms) ? defaultValue : ms;
|
|
16121
|
+
}
|
|
16122
|
+
function dumpTxWeight(tx, conversionResultSecurityIds) {
|
|
16123
|
+
const objectType = String(tx.object_type ?? "");
|
|
16124
|
+
if (conversionResultSecurityIds.size > 0 && ISSUANCE_TYPES.has(objectType) && typeof tx.security_id === "string" && conversionResultSecurityIds.has(tx.security_id)) {
|
|
16125
|
+
return 36;
|
|
16126
|
+
}
|
|
16127
|
+
switch (objectType) {
|
|
16128
|
+
case "TX_ISSUER_AUTHORIZED_SHARES_ADJUSTMENT":
|
|
16129
|
+
case "TX_STOCK_CLASS_AUTHORIZED_SHARES_ADJUSTMENT":
|
|
16130
|
+
case "TX_STOCK_PLAN_POOL_ADJUSTMENT":
|
|
16131
|
+
return 5;
|
|
16132
|
+
case "TX_STOCK_REISSUANCE":
|
|
16133
|
+
return 9;
|
|
16134
|
+
case "TX_STOCK_ISSUANCE":
|
|
16135
|
+
case "TX_EQUITY_COMPENSATION_ISSUANCE":
|
|
16136
|
+
case "TX_WARRANT_ISSUANCE":
|
|
16137
|
+
case "TX_CONVERTIBLE_ISSUANCE":
|
|
16138
|
+
case "TX_PLAN_SECURITY_ISSUANCE":
|
|
16139
|
+
return 10;
|
|
16140
|
+
case "TX_STOCK_ACCEPTANCE":
|
|
16141
|
+
case "TX_WARRANT_ACCEPTANCE":
|
|
16142
|
+
case "TX_EQUITY_COMPENSATION_ACCEPTANCE":
|
|
16143
|
+
case "TX_PLAN_SECURITY_ACCEPTANCE":
|
|
16144
|
+
return 11;
|
|
16145
|
+
case "TX_VESTING_START":
|
|
16146
|
+
return 12;
|
|
16147
|
+
case "TX_VESTING_EVENT":
|
|
16148
|
+
return 13;
|
|
16149
|
+
case "TX_VESTING_ACCELERATION":
|
|
16150
|
+
return 14;
|
|
16151
|
+
case "TX_STOCK_CLASS_SPLIT":
|
|
16152
|
+
return 15;
|
|
16153
|
+
case "TX_STOCK_RETRACTION":
|
|
16154
|
+
case "TX_CONVERTIBLE_RETRACTION":
|
|
16155
|
+
case "TX_WARRANT_RETRACTION":
|
|
16156
|
+
case "TX_EQUITY_COMPENSATION_RETRACTION":
|
|
16157
|
+
return 16;
|
|
16158
|
+
case "TX_STOCK_CONSOLIDATION":
|
|
16159
|
+
return 17;
|
|
16160
|
+
case "TX_STOCK_CLASS_CONVERSION_RATIO_ADJUSTMENT":
|
|
16161
|
+
return 18;
|
|
16162
|
+
case "TX_EQUITY_COMPENSATION_REPRICING":
|
|
16163
|
+
return 19;
|
|
16164
|
+
case "TX_STOCK_TRANSFER":
|
|
16165
|
+
case "TX_WARRANT_TRANSFER":
|
|
16166
|
+
case "TX_CONVERTIBLE_TRANSFER":
|
|
16167
|
+
case "TX_EQUITY_COMPENSATION_TRANSFER":
|
|
16168
|
+
case "TX_PLAN_SECURITY_TRANSFER":
|
|
16169
|
+
return 20;
|
|
16170
|
+
case "TX_CONVERTIBLE_ACCEPTANCE":
|
|
16171
|
+
return 22;
|
|
16172
|
+
case "TX_EQUITY_COMPENSATION_EXERCISE":
|
|
16173
|
+
case "TX_WARRANT_EXERCISE":
|
|
16174
|
+
return 30;
|
|
16175
|
+
case "TX_CONVERTIBLE_CONVERSION":
|
|
16176
|
+
return 35;
|
|
16177
|
+
case "TX_STOCK_REPURCHASE":
|
|
16178
|
+
case "TX_STOCK_CANCELLATION":
|
|
16179
|
+
case "TX_EQUITY_COMPENSATION_CANCELLATION":
|
|
16180
|
+
case "TX_WARRANT_CANCELLATION":
|
|
16181
|
+
case "TX_CONVERTIBLE_CANCELLATION":
|
|
16182
|
+
case "TX_EQUITY_COMPENSATION_RETURN_TO_POOL":
|
|
16183
|
+
return 40;
|
|
16184
|
+
default:
|
|
16185
|
+
return 50;
|
|
16186
|
+
}
|
|
16187
|
+
}
|
|
16188
|
+
function dumpTransactionSortKey(tx, issuanceDates, conversionResultSecurityIds) {
|
|
16189
|
+
let day = new Date(timestampMs(tx.date, 0) ?? 0).toISOString().slice(0, 10);
|
|
16190
|
+
const objectType = String(tx.object_type ?? "");
|
|
16191
|
+
if (objectType === "TX_VESTING_START" && typeof tx.security_id === "string") {
|
|
16192
|
+
const issuanceDate = issuanceDates.get(tx.security_id);
|
|
16193
|
+
if (issuanceDate && String(tx.date) < issuanceDate) {
|
|
16194
|
+
day = new Date(timestampMs(issuanceDate, 0) ?? 0).toISOString().slice(0, 10);
|
|
16195
|
+
}
|
|
16196
|
+
}
|
|
16197
|
+
const weight = String(dumpTxWeight(tx, conversionResultSecurityIds)).padStart(3, "0");
|
|
16198
|
+
const group = typeof tx.security_id === "string" && tx.security_id ? tx.security_id : "_no_security_";
|
|
16199
|
+
const createdMs = timestampMs(tx.createdAt ?? tx.created_at, null);
|
|
16200
|
+
const created = createdMs !== null ? new Date(createdMs).toISOString() : "9999-12-31T23:59:59.999Z";
|
|
16201
|
+
const id = String(tx._id ?? tx.id ?? "");
|
|
16202
|
+
return `${day}|${weight}|${group}|${created}|${id}`;
|
|
16203
|
+
}
|
|
16204
|
+
function sortDumpTransactions(transactions) {
|
|
16205
|
+
const issuanceDates = /* @__PURE__ */ new Map();
|
|
16206
|
+
const conversionResultSecurityIds = /* @__PURE__ */ new Set();
|
|
16207
|
+
for (const tx of transactions) {
|
|
16208
|
+
const objectType = String(tx.object_type ?? "");
|
|
16209
|
+
if (ISSUANCE_TYPES.has(objectType) && typeof tx.security_id === "string" && typeof tx.date === "string") {
|
|
16210
|
+
issuanceDates.set(tx.security_id, tx.date);
|
|
16211
|
+
}
|
|
16212
|
+
if (!CONVERSION_PARENT_TYPES.has(objectType))
|
|
16213
|
+
continue;
|
|
16214
|
+
if (Array.isArray(tx.resulting_security_ids)) {
|
|
16215
|
+
for (const id of tx.resulting_security_ids) {
|
|
16216
|
+
if (typeof id === "string" && id)
|
|
16217
|
+
conversionResultSecurityIds.add(id);
|
|
16218
|
+
}
|
|
16219
|
+
}
|
|
16220
|
+
if (typeof tx.balance_security_id === "string" && tx.balance_security_id) {
|
|
16221
|
+
conversionResultSecurityIds.add(tx.balance_security_id);
|
|
16222
|
+
}
|
|
16223
|
+
}
|
|
16224
|
+
return [...transactions].sort((a, b) => {
|
|
16225
|
+
const ka = dumpTransactionSortKey(a, issuanceDates, conversionResultSecurityIds);
|
|
16226
|
+
const kb = dumpTransactionSortKey(b, issuanceDates, conversionResultSecurityIds);
|
|
16227
|
+
if (ka < kb)
|
|
16228
|
+
return -1;
|
|
16229
|
+
if (ka > kb)
|
|
16230
|
+
return 1;
|
|
16231
|
+
return 0;
|
|
16232
|
+
});
|
|
16233
|
+
}
|
|
16234
|
+
function assembleEngineOcfDump(objects) {
|
|
16235
|
+
const issuers = [];
|
|
16236
|
+
const stockClasses = /* @__PURE__ */ new Map();
|
|
16237
|
+
const stockPlans = /* @__PURE__ */ new Map();
|
|
16238
|
+
const stakeholders = /* @__PURE__ */ new Map();
|
|
16239
|
+
const transactions = /* @__PURE__ */ new Map();
|
|
16240
|
+
const vestingTerms = /* @__PURE__ */ new Map();
|
|
16241
|
+
let index = 0;
|
|
16242
|
+
for (const obj of objects) {
|
|
16243
|
+
if (!isRecord(obj))
|
|
16244
|
+
continue;
|
|
16245
|
+
const type = canonicalType(obj);
|
|
16246
|
+
const payload = isRecord(obj.ocf) ? obj.ocf : null;
|
|
16247
|
+
index += 1;
|
|
16248
|
+
switch (type) {
|
|
16249
|
+
case "ISSUER":
|
|
16250
|
+
if (!payload) {
|
|
16251
|
+
throw new DumpAssemblyError("ISSUER object is missing an ocf payload.");
|
|
16252
|
+
}
|
|
16253
|
+
issuers.push(issuerForEngine(payload));
|
|
16254
|
+
break;
|
|
16255
|
+
case "STOCK_CLASS":
|
|
16256
|
+
if (payload)
|
|
16257
|
+
pushByOcfId(stockClasses, payload, `anon-stock-class-${index}`);
|
|
16258
|
+
break;
|
|
16259
|
+
case "STOCK_PLAN":
|
|
16260
|
+
if (payload)
|
|
16261
|
+
pushByOcfId(stockPlans, payload, `anon-stock-plan-${index}`);
|
|
16262
|
+
break;
|
|
16263
|
+
case "STAKEHOLDER":
|
|
16264
|
+
if (payload)
|
|
16265
|
+
pushByOcfId(stakeholders, payload, `anon-stakeholder-${index}`);
|
|
16266
|
+
break;
|
|
16267
|
+
case "TRANSACTION":
|
|
16268
|
+
if (payload)
|
|
16269
|
+
pushByOcfId(transactions, payload, `anon-transaction-${index}`);
|
|
16270
|
+
break;
|
|
16271
|
+
case "VESTING_TERMS":
|
|
16272
|
+
if (payload)
|
|
16273
|
+
pushByOcfId(vestingTerms, payload, `anon-vesting-terms-${index}`);
|
|
16274
|
+
break;
|
|
16275
|
+
default:
|
|
16276
|
+
break;
|
|
16277
|
+
}
|
|
16278
|
+
}
|
|
16279
|
+
if (issuers.length === 0) {
|
|
16280
|
+
throw new DumpAssemblyError("Dump requires exactly one ISSUER object; none found.");
|
|
16281
|
+
}
|
|
16282
|
+
if (issuers.length > 1) {
|
|
16283
|
+
throw new DumpAssemblyError(`Dump requires exactly one ISSUER object; found ${issuers.length}.`);
|
|
16284
|
+
}
|
|
16285
|
+
return {
|
|
16286
|
+
issuer: issuers[0],
|
|
16287
|
+
stockClasses: [...stockClasses.values()],
|
|
16288
|
+
stockPlans: [...stockPlans.values()],
|
|
16289
|
+
stakeholders: [...stakeholders.values()],
|
|
16290
|
+
transactions: sortDumpTransactions([...transactions.values()]),
|
|
16291
|
+
vestingTerms: [...vestingTerms.values()],
|
|
16292
|
+
sharePrices: []
|
|
16293
|
+
};
|
|
16294
|
+
}
|
|
16295
|
+
|
|
16026
16296
|
// ../captable-ai-core/dist/scopes.js
|
|
16027
16297
|
var CAPTABLE_AI_SCOPES = {
|
|
16028
16298
|
READ: "read",
|
|
@@ -16183,14 +16453,14 @@ var summarySchema = external_exports.object({
|
|
|
16183
16453
|
});
|
|
16184
16454
|
|
|
16185
16455
|
// src/api.ts
|
|
16186
|
-
function
|
|
16456
|
+
function isRecord2(value) {
|
|
16187
16457
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16188
16458
|
}
|
|
16189
16459
|
function coerceDetails(raw) {
|
|
16190
16460
|
if (!Array.isArray(raw)) return void 0;
|
|
16191
16461
|
const details = [];
|
|
16192
16462
|
for (const entry of raw) {
|
|
16193
|
-
if (!
|
|
16463
|
+
if (!isRecord2(entry)) continue;
|
|
16194
16464
|
const message = typeof entry.message === "string" ? entry.message : void 0;
|
|
16195
16465
|
if (!message) continue;
|
|
16196
16466
|
const path = typeof entry.path === "string" ? entry.path : void 0;
|
|
@@ -16381,9 +16651,9 @@ async function handleResponse(res) {
|
|
|
16381
16651
|
}
|
|
16382
16652
|
if (!res.ok) {
|
|
16383
16653
|
const exitCode = exitCodeForStatus(res.status);
|
|
16384
|
-
const obj =
|
|
16654
|
+
const obj = isRecord2(parsed) ? parsed : {};
|
|
16385
16655
|
const nested = obj.error;
|
|
16386
|
-
if (
|
|
16656
|
+
if (isRecord2(nested)) {
|
|
16387
16657
|
const code = typeof nested.code === "string" && nested.code.trim() ? nested.code : void 0;
|
|
16388
16658
|
const details = coerceDetails(nested.details);
|
|
16389
16659
|
exitWithError(String(nested.message ?? `HTTP ${res.status}`), code, details, exitCode);
|
|
@@ -16486,24 +16756,54 @@ Usage:
|
|
|
16486
16756
|
captable-ai objects list [options]
|
|
16487
16757
|
|
|
16488
16758
|
Filters:
|
|
16489
|
-
--type TYPE
|
|
16490
|
-
--subtype STYPE
|
|
16491
|
-
--status STATUS
|
|
16492
|
-
--q QUERY
|
|
16493
|
-
--from DATE
|
|
16494
|
-
--to DATE
|
|
16495
|
-
--ids ID,ID,...
|
|
16759
|
+
--type TYPE Top-level OCF types (comma-separated)
|
|
16760
|
+
--subtype STYPE TRANSACTION subtypes (comma-separated)
|
|
16761
|
+
--status STATUS draft | committed
|
|
16762
|
+
--q QUERY Full-text search
|
|
16763
|
+
--from DATE YYYY-MM-DD (inclusive lower bound on object date)
|
|
16764
|
+
--to DATE YYYY-MM-DD (inclusive upper bound on object date)
|
|
16765
|
+
--ids ID,ID,... Batch fetch by object IDs
|
|
16766
|
+
--stakeholder ID Filter by OCF stakeholder id
|
|
16767
|
+
--document S3_ASSET_ID Filter by source document
|
|
16768
|
+
--max-confidence N Keep objects with confidence <= N (requires --all)
|
|
16496
16769
|
|
|
16497
16770
|
Pagination:
|
|
16498
|
-
--limit N
|
|
16499
|
-
--cursor C
|
|
16771
|
+
--limit N Page size (1\u2013250; omit for server default, typically 100)
|
|
16772
|
+
--cursor C Opaque continuation cursor from prior response
|
|
16773
|
+
--all Follow cursors until every matching object is returned
|
|
16774
|
+
|
|
16775
|
+
Human table sorts lowest extraction confidence first. Conf markers:
|
|
16776
|
+
!N red (<65) ~N amber (65\u201384) N green (\u226585)
|
|
16500
16777
|
|
|
16501
16778
|
Global:
|
|
16502
|
-
--json
|
|
16779
|
+
--json Machine-readable JSON output (API order, not confidence-sorted)`;
|
|
16503
16780
|
var HELP_OBJECTS_GET = `objects get \u2014 Show one OCF object
|
|
16504
16781
|
|
|
16505
16782
|
Usage:
|
|
16506
16783
|
captable-ai objects get <object-id> [--json]`;
|
|
16784
|
+
var HELP_OBJECTS_DUMP = `objects dump \u2014 Engine-shaped ocf.json
|
|
16785
|
+
|
|
16786
|
+
Assembles each row's ocf payload into the shape processCapTable consumes:
|
|
16787
|
+
{ issuer, stockClasses, stockPlans, stakeholders, transactions, vestingTerms, sharePrices }
|
|
16788
|
+
|
|
16789
|
+
Fails if ISSUER is missing or duplicated. Not an OCF zip and not expected.json.
|
|
16790
|
+
Drains up to 400 pages (100,000 objects). Large tables: write a file with --output.
|
|
16791
|
+
|
|
16792
|
+
The list API picks the latest row per object id, then optionally filters status.
|
|
16793
|
+
--status committed therefore omits an object when a newer draft exists.
|
|
16794
|
+
--status draft dumps that latest-row working set (drafts win) so the engine
|
|
16795
|
+
still sees the committed ISSUER and other unchanged baseline objects.
|
|
16796
|
+
|
|
16797
|
+
Usage:
|
|
16798
|
+
captable-ai objects dump [--status committed|draft] [--output path]
|
|
16799
|
+
|
|
16800
|
+
Flags:
|
|
16801
|
+
--status STATUS committed = latest committed-only rows (default).
|
|
16802
|
+
draft = pending working set (latest row per object).
|
|
16803
|
+
--output PATH Write JSON to file (global flag; implies --json)
|
|
16804
|
+
|
|
16805
|
+
Global:
|
|
16806
|
+
--json Machine-readable JSON (dump is always JSON)`;
|
|
16507
16807
|
var HELP_OBJECTS_UPDATE = `objects update \u2014 Update an OCF object
|
|
16508
16808
|
|
|
16509
16809
|
Usage:
|
|
@@ -16592,6 +16892,8 @@ ${HELP_OBJECTS_LIST}
|
|
|
16592
16892
|
|
|
16593
16893
|
${HELP_OBJECTS_GET}
|
|
16594
16894
|
|
|
16895
|
+
${HELP_OBJECTS_DUMP}
|
|
16896
|
+
|
|
16595
16897
|
${HELP_OBJECTS_UPDATE}
|
|
16596
16898
|
|
|
16597
16899
|
${HELP_OBJECTS_PATCH}
|
|
@@ -17686,11 +17988,11 @@ var JOBS_FILE = join2(CONFIG_DIR2, "jobs.jsonl");
|
|
|
17686
17988
|
var LOCK_DIR = join2(CONFIG_DIR2, "jobs.lock");
|
|
17687
17989
|
var VALID_JOB_STATUSES = /* @__PURE__ */ new Set(["submitted", "running", "complete", "failed"]);
|
|
17688
17990
|
var VALID_JOB_KINDS = /* @__PURE__ */ new Set(["extraction"]);
|
|
17689
|
-
function
|
|
17991
|
+
function isRecord3(v) {
|
|
17690
17992
|
return typeof v === "object" && v !== null;
|
|
17691
17993
|
}
|
|
17692
17994
|
function isJobEntry(value) {
|
|
17693
|
-
if (!
|
|
17995
|
+
if (!isRecord3(value)) return false;
|
|
17694
17996
|
return typeof value.id === "string" && typeof value.kind === "string" && VALID_JOB_KINDS.has(value.kind) && typeof value.portalId === "string" && typeof value.submittedAt === "string" && typeof value.status === "string" && VALID_JOB_STATUSES.has(value.status);
|
|
17695
17997
|
}
|
|
17696
17998
|
async function ensureDir() {
|
|
@@ -18241,11 +18543,11 @@ async function readEntries() {
|
|
|
18241
18543
|
}
|
|
18242
18544
|
return entries;
|
|
18243
18545
|
}
|
|
18244
|
-
function
|
|
18546
|
+
function isRecord4(v) {
|
|
18245
18547
|
return typeof v === "object" && v !== null;
|
|
18246
18548
|
}
|
|
18247
18549
|
function isFeedbackEntry(value) {
|
|
18248
|
-
if (!
|
|
18550
|
+
if (!isRecord4(value)) return false;
|
|
18249
18551
|
return typeof value.ts === "string" && typeof value.text === "string" && typeof value.sent === "boolean";
|
|
18250
18552
|
}
|
|
18251
18553
|
|
|
@@ -18462,7 +18764,7 @@ function successHtml() {
|
|
|
18462
18764
|
h1{font-size:1.5rem;color:#111}p{color:#666}</style></head>
|
|
18463
18765
|
<body><div class="card"><h1>Login successful</h1><p>You can close this window and return to the terminal.</p></div></body></html>`;
|
|
18464
18766
|
}
|
|
18465
|
-
function
|
|
18767
|
+
function isRecord5(value) {
|
|
18466
18768
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18467
18769
|
}
|
|
18468
18770
|
function readStr(obj, ...keys) {
|
|
@@ -18483,7 +18785,7 @@ function parsePortalsFromExchange(raw) {
|
|
|
18483
18785
|
}
|
|
18484
18786
|
if (!Array.isArray(parsed)) return [];
|
|
18485
18787
|
return parsed.flatMap((p) => {
|
|
18486
|
-
if (!
|
|
18788
|
+
if (!isRecord5(p)) return [];
|
|
18487
18789
|
if (typeof p.id !== "string" || p.id.length === 0) return [];
|
|
18488
18790
|
return [
|
|
18489
18791
|
{
|
|
@@ -18527,7 +18829,7 @@ function tryParseLoginPaste(line, expectedState) {
|
|
|
18527
18829
|
} catch {
|
|
18528
18830
|
return null;
|
|
18529
18831
|
}
|
|
18530
|
-
if (!
|
|
18832
|
+
if (!isRecord5(obj)) return null;
|
|
18531
18833
|
if (typeof obj.state !== "string" || !pastedStateMatches(expectedState, obj.state)) return null;
|
|
18532
18834
|
const accessToken = readStr(obj, "access_token", "accessToken");
|
|
18533
18835
|
const refreshToken = readStr(obj, "refresh_token", "refreshToken");
|
|
@@ -18892,6 +19194,105 @@ async function runObjectsDelete(args, rawArgv) {
|
|
|
18892
19194
|
);
|
|
18893
19195
|
}
|
|
18894
19196
|
|
|
19197
|
+
// src/objects-pages.ts
|
|
19198
|
+
var OBJECTS_LIST_MAX_PAGES = 100;
|
|
19199
|
+
var OBJECTS_DUMP_MAX_PAGES = 400;
|
|
19200
|
+
async function fetchAllObjectPages(portalId, query, options) {
|
|
19201
|
+
const maxPages = options?.maxPages ?? OBJECTS_LIST_MAX_PAGES;
|
|
19202
|
+
const objects = [];
|
|
19203
|
+
const documentsById = /* @__PURE__ */ new Map();
|
|
19204
|
+
let cursor = typeof query.cursor === "string" ? query.cursor : void 0;
|
|
19205
|
+
let total = 0;
|
|
19206
|
+
let pages = 0;
|
|
19207
|
+
while (true) {
|
|
19208
|
+
pages += 1;
|
|
19209
|
+
if (pages > maxPages) {
|
|
19210
|
+
exitWithError(
|
|
19211
|
+
`Exceeded max object-list pages (${maxPages}). Narrow the query or raise the page size.`,
|
|
19212
|
+
"ERROR",
|
|
19213
|
+
void 0,
|
|
19214
|
+
EXIT.SERVER_ERROR
|
|
19215
|
+
);
|
|
19216
|
+
}
|
|
19217
|
+
const pageQuery = { ...query };
|
|
19218
|
+
if (cursor !== void 0) pageQuery.cursor = cursor;
|
|
19219
|
+
else delete pageQuery.cursor;
|
|
19220
|
+
const res = await apiRequest(`/${portalId}/objects`, { query: pageQuery });
|
|
19221
|
+
const pageObjects = res.data?.objects ?? [];
|
|
19222
|
+
const pageDocs = res.data?.documents ?? [];
|
|
19223
|
+
objects.push(...pageObjects);
|
|
19224
|
+
for (const doc of pageDocs) {
|
|
19225
|
+
documentsById.set(doc.id, doc);
|
|
19226
|
+
}
|
|
19227
|
+
if (res.meta?.total != null) total = res.meta.total;
|
|
19228
|
+
if (!res.meta?.hasMore) break;
|
|
19229
|
+
if (!res.meta.cursor) {
|
|
19230
|
+
exitWithError(
|
|
19231
|
+
"Pagination response has more results but no continuation cursor.",
|
|
19232
|
+
"ERROR",
|
|
19233
|
+
void 0,
|
|
19234
|
+
EXIT.SERVER_ERROR
|
|
19235
|
+
);
|
|
19236
|
+
}
|
|
19237
|
+
if (cursor !== void 0 && res.meta.cursor === cursor) {
|
|
19238
|
+
exitWithError(
|
|
19239
|
+
"Pagination cursor did not advance; stopped draining object pages.",
|
|
19240
|
+
"ERROR",
|
|
19241
|
+
void 0,
|
|
19242
|
+
EXIT.SERVER_ERROR
|
|
19243
|
+
);
|
|
19244
|
+
}
|
|
19245
|
+
cursor = res.meta.cursor;
|
|
19246
|
+
}
|
|
19247
|
+
return {
|
|
19248
|
+
data: { objects, documents: Array.from(documentsById.values()) },
|
|
19249
|
+
meta: { cursor: null, total: total || objects.length, hasMore: false }
|
|
19250
|
+
};
|
|
19251
|
+
}
|
|
19252
|
+
|
|
19253
|
+
// src/commands/objects-dump.ts
|
|
19254
|
+
var DUMP_PAGE_LIMIT = 250;
|
|
19255
|
+
function dumpStatus(raw) {
|
|
19256
|
+
const status = raw ?? "committed";
|
|
19257
|
+
if (status === "committed" || status === "draft") return status;
|
|
19258
|
+
exitWithError(
|
|
19259
|
+
`--status must be one of: draft, committed (got: "${status}")`,
|
|
19260
|
+
"VALIDATION_FAILED",
|
|
19261
|
+
void 0,
|
|
19262
|
+
EXIT.VALIDATION
|
|
19263
|
+
);
|
|
19264
|
+
}
|
|
19265
|
+
async function runObjectsDump(args, rawArgv) {
|
|
19266
|
+
if (argvRequestsHelp(rawArgv)) {
|
|
19267
|
+
process.stdout.write(`${HELP_OBJECTS_DUMP}
|
|
19268
|
+
`);
|
|
19269
|
+
process.exit(0);
|
|
19270
|
+
}
|
|
19271
|
+
validateFlags(args, { flags: ["status"], booleans: [] });
|
|
19272
|
+
if (args.positional.length > 0) {
|
|
19273
|
+
exitWithError(
|
|
19274
|
+
`Unexpected argument: ${args.positional[0]}. objects dump takes flags only.`,
|
|
19275
|
+
"USAGE",
|
|
19276
|
+
void 0,
|
|
19277
|
+
EXIT.USAGE
|
|
19278
|
+
);
|
|
19279
|
+
}
|
|
19280
|
+
const status = dumpStatus(getFlagValue(args, "status"));
|
|
19281
|
+
const portalId = await getActivePortalId();
|
|
19282
|
+
const query = { limit: DUMP_PAGE_LIMIT };
|
|
19283
|
+
if (status === "committed") query.status = "committed";
|
|
19284
|
+
const page = await fetchAllObjectPages(portalId, query, { maxPages: OBJECTS_DUMP_MAX_PAGES });
|
|
19285
|
+
try {
|
|
19286
|
+
const objects = Array.isArray(page.data?.objects) ? page.data.objects : [];
|
|
19287
|
+
printJson(assembleEngineOcfDump(objects));
|
|
19288
|
+
} catch (err) {
|
|
19289
|
+
if (err instanceof DumpAssemblyError) {
|
|
19290
|
+
exitWithError(err.message, "VALIDATION_FAILED", void 0, EXIT.VALIDATION);
|
|
19291
|
+
}
|
|
19292
|
+
throw err;
|
|
19293
|
+
}
|
|
19294
|
+
}
|
|
19295
|
+
|
|
18895
19296
|
// src/commands/objects-get.ts
|
|
18896
19297
|
function shellQuote2(value) {
|
|
18897
19298
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
@@ -19020,6 +19421,106 @@ function validateIsoDateRange(fromRaw, toRaw) {
|
|
|
19020
19421
|
}
|
|
19021
19422
|
|
|
19022
19423
|
// src/commands/objects-list.ts
|
|
19424
|
+
var CONFIDENCE_RED_MAX = 64;
|
|
19425
|
+
var CONFIDENCE_AMBER_MAX = 84;
|
|
19426
|
+
function isRecord6(value) {
|
|
19427
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19428
|
+
}
|
|
19429
|
+
function getValidatedMaxConfidence(raw) {
|
|
19430
|
+
if (raw === void 0) return void 0;
|
|
19431
|
+
const trimmed = raw.trim();
|
|
19432
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
19433
|
+
exitWithError(
|
|
19434
|
+
"--max-confidence must be an integer between 0 and 100",
|
|
19435
|
+
"VALIDATION_FAILED",
|
|
19436
|
+
void 0,
|
|
19437
|
+
EXIT.VALIDATION
|
|
19438
|
+
);
|
|
19439
|
+
}
|
|
19440
|
+
const n = Number.parseInt(trimmed, 10);
|
|
19441
|
+
if (n < 0 || n > 100) {
|
|
19442
|
+
exitWithError(
|
|
19443
|
+
"--max-confidence must be an integer between 0 and 100",
|
|
19444
|
+
"VALIDATION_FAILED",
|
|
19445
|
+
void 0,
|
|
19446
|
+
EXIT.VALIDATION
|
|
19447
|
+
);
|
|
19448
|
+
}
|
|
19449
|
+
return n;
|
|
19450
|
+
}
|
|
19451
|
+
function objectConfidence(obj) {
|
|
19452
|
+
const n = obj.extraction?.confidence;
|
|
19453
|
+
return typeof n === "number" && Number.isFinite(n) ? n : void 0;
|
|
19454
|
+
}
|
|
19455
|
+
function formatConfidence(confidence) {
|
|
19456
|
+
if (confidence === void 0) return "\u2014";
|
|
19457
|
+
if (confidence <= CONFIDENCE_RED_MAX) return `!${confidence}`;
|
|
19458
|
+
if (confidence <= CONFIDENCE_AMBER_MAX) return `~${confidence}`;
|
|
19459
|
+
return String(confidence);
|
|
19460
|
+
}
|
|
19461
|
+
function stakeholderDisplayName(ocf) {
|
|
19462
|
+
if (!ocf) return null;
|
|
19463
|
+
if (typeof ocf.name === "string" && ocf.name.trim()) return ocf.name.trim();
|
|
19464
|
+
if (typeof ocf.legal_name === "string" && ocf.legal_name.trim()) return ocf.legal_name.trim();
|
|
19465
|
+
if (isRecord6(ocf.name)) {
|
|
19466
|
+
const legal = ocf.name.legal_name;
|
|
19467
|
+
if (typeof legal === "string" && legal.trim()) return legal.trim();
|
|
19468
|
+
const parts = [ocf.name.first_name, ocf.name.last_name].filter(
|
|
19469
|
+
(p) => typeof p === "string" && p.trim().length > 0
|
|
19470
|
+
);
|
|
19471
|
+
if (parts.length > 0) return parts.join(" ");
|
|
19472
|
+
}
|
|
19473
|
+
return null;
|
|
19474
|
+
}
|
|
19475
|
+
function stakeholderNamesById(objects) {
|
|
19476
|
+
const names = /* @__PURE__ */ new Map();
|
|
19477
|
+
for (const obj of objects) {
|
|
19478
|
+
if (obj.type !== "STAKEHOLDER") continue;
|
|
19479
|
+
const name = stakeholderDisplayName(obj.ocf);
|
|
19480
|
+
if (name) names.set(obj.id, name);
|
|
19481
|
+
}
|
|
19482
|
+
return names;
|
|
19483
|
+
}
|
|
19484
|
+
function compareConfidenceAsc(a, b) {
|
|
19485
|
+
const ca = objectConfidence(a);
|
|
19486
|
+
const cb = objectConfidence(b);
|
|
19487
|
+
if (ca === void 0 && cb === void 0) return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
19488
|
+
if (ca === void 0) return 1;
|
|
19489
|
+
if (cb === void 0) return -1;
|
|
19490
|
+
if (ca !== cb) return ca - cb;
|
|
19491
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
19492
|
+
}
|
|
19493
|
+
function shellQuote3(value) {
|
|
19494
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
19495
|
+
}
|
|
19496
|
+
function nextPageHint(query, cursor) {
|
|
19497
|
+
const parts = ["captable-ai objects list"];
|
|
19498
|
+
const flagNames = [
|
|
19499
|
+
{ queryKey: "type", flag: "type" },
|
|
19500
|
+
{ queryKey: "subtype", flag: "subtype" },
|
|
19501
|
+
{ queryKey: "status", flag: "status" },
|
|
19502
|
+
{ queryKey: "q", flag: "q" },
|
|
19503
|
+
{ queryKey: "from", flag: "from" },
|
|
19504
|
+
{ queryKey: "to", flag: "to" },
|
|
19505
|
+
{ queryKey: "ids", flag: "ids" },
|
|
19506
|
+
{ queryKey: "stakeholderId", flag: "stakeholder" },
|
|
19507
|
+
{ queryKey: "documentId", flag: "document" },
|
|
19508
|
+
{ queryKey: "limit", flag: "limit" }
|
|
19509
|
+
];
|
|
19510
|
+
for (const { queryKey, flag } of flagNames) {
|
|
19511
|
+
const value = query[queryKey];
|
|
19512
|
+
if (value !== void 0) parts.push(`--${flag} ${shellQuote3(String(value))}`);
|
|
19513
|
+
}
|
|
19514
|
+
parts.push(`--cursor ${shellQuote3(cursor)}`);
|
|
19515
|
+
return parts.join(" ");
|
|
19516
|
+
}
|
|
19517
|
+
function documentsReferencedBy(documents, objects) {
|
|
19518
|
+
const ids = /* @__PURE__ */ new Set();
|
|
19519
|
+
for (const obj of objects) {
|
|
19520
|
+
if (typeof obj.documentId === "string" && obj.documentId.length > 0) ids.add(obj.documentId);
|
|
19521
|
+
}
|
|
19522
|
+
return documents.filter((doc) => ids.has(doc.id));
|
|
19523
|
+
}
|
|
19023
19524
|
async function runObjectsList(args, rawArgv) {
|
|
19024
19525
|
if (argvRequestsHelp(rawArgv)) {
|
|
19025
19526
|
process.stdout.write(`${HELP_OBJECTS_LIST}
|
|
@@ -19027,14 +19528,45 @@ async function runObjectsList(args, rawArgv) {
|
|
|
19027
19528
|
process.exit(0);
|
|
19028
19529
|
}
|
|
19029
19530
|
validateFlags(args, {
|
|
19030
|
-
flags: [
|
|
19031
|
-
|
|
19531
|
+
flags: [
|
|
19532
|
+
"type",
|
|
19533
|
+
"subtype",
|
|
19534
|
+
"status",
|
|
19535
|
+
"limit",
|
|
19536
|
+
"cursor",
|
|
19537
|
+
"q",
|
|
19538
|
+
"from",
|
|
19539
|
+
"to",
|
|
19540
|
+
"ids",
|
|
19541
|
+
"stakeholder",
|
|
19542
|
+
"document",
|
|
19543
|
+
"max-confidence"
|
|
19544
|
+
],
|
|
19545
|
+
booleans: ["all"]
|
|
19032
19546
|
});
|
|
19547
|
+
if (args.positional.length > 0) {
|
|
19548
|
+
exitWithError(
|
|
19549
|
+
`Unexpected argument: ${args.positional[0]}. This command takes no positional arguments.`,
|
|
19550
|
+
"UNEXPECTED_ARGUMENT",
|
|
19551
|
+
void 0,
|
|
19552
|
+
EXIT.USAGE
|
|
19553
|
+
);
|
|
19554
|
+
}
|
|
19033
19555
|
const portalId = await getActivePortalId();
|
|
19034
19556
|
const from = getFlagValue(args, "from");
|
|
19035
19557
|
const to = getFlagValue(args, "to");
|
|
19036
19558
|
validateIsoDateRange(from, to);
|
|
19037
19559
|
const limit = getValidatedLimit(getFlagValue(args, "limit"));
|
|
19560
|
+
const drainAll = hasFlag(args, "all");
|
|
19561
|
+
const maxConfidence = getValidatedMaxConfidence(getFlagValue(args, "max-confidence"));
|
|
19562
|
+
if (maxConfidence !== void 0 && !drainAll) {
|
|
19563
|
+
exitWithError(
|
|
19564
|
+
"--max-confidence requires --all so the review queue is not a single page.",
|
|
19565
|
+
"VALIDATION_FAILED",
|
|
19566
|
+
void 0,
|
|
19567
|
+
EXIT.VALIDATION
|
|
19568
|
+
);
|
|
19569
|
+
}
|
|
19038
19570
|
const type = getFlagValue(args, "type");
|
|
19039
19571
|
const subtype = getFlagValue(args, "subtype");
|
|
19040
19572
|
const status = getFlagValue(args, "status");
|
|
@@ -19049,6 +19581,8 @@ async function runObjectsList(args, rawArgv) {
|
|
|
19049
19581
|
const q = getFlagValue(args, "q");
|
|
19050
19582
|
const cursor = getFlagValue(args, "cursor");
|
|
19051
19583
|
const ids = getFlagValue(args, "ids");
|
|
19584
|
+
const stakeholderId = getFlagValue(args, "stakeholder");
|
|
19585
|
+
const documentId = getFlagValue(args, "document");
|
|
19052
19586
|
const query = {
|
|
19053
19587
|
type,
|
|
19054
19588
|
subtype,
|
|
@@ -19058,51 +19592,75 @@ async function runObjectsList(args, rawArgv) {
|
|
|
19058
19592
|
cursor,
|
|
19059
19593
|
from,
|
|
19060
19594
|
to,
|
|
19061
|
-
ids
|
|
19595
|
+
ids,
|
|
19596
|
+
stakeholderId,
|
|
19597
|
+
documentId
|
|
19062
19598
|
};
|
|
19063
|
-
|
|
19599
|
+
let page;
|
|
19600
|
+
if (drainAll) {
|
|
19601
|
+
page = await fetchAllObjectPages(portalId, query);
|
|
19602
|
+
} else {
|
|
19603
|
+
const res = await apiRequest(`/${portalId}/objects`, { query });
|
|
19604
|
+
page = {
|
|
19605
|
+
data: { objects: res.data?.objects ?? [], documents: res.data?.documents ?? [] },
|
|
19606
|
+
meta: res.meta ?? {}
|
|
19607
|
+
};
|
|
19608
|
+
}
|
|
19609
|
+
let objects = page.data.objects;
|
|
19610
|
+
let documents = page.data.documents;
|
|
19611
|
+
if (maxConfidence !== void 0) {
|
|
19612
|
+
objects = objects.filter((obj) => {
|
|
19613
|
+
const confidence = objectConfidence(obj);
|
|
19614
|
+
return confidence !== void 0 && confidence <= maxConfidence;
|
|
19615
|
+
});
|
|
19616
|
+
documents = documentsReferencedBy(documents, objects);
|
|
19617
|
+
}
|
|
19064
19618
|
if (isJsonMode()) {
|
|
19065
|
-
const out = {
|
|
19066
|
-
|
|
19619
|
+
const out = {
|
|
19620
|
+
data: { objects, documents }
|
|
19621
|
+
};
|
|
19622
|
+
if (page.meta !== void 0) {
|
|
19623
|
+
out.meta = maxConfidence !== void 0 ? { ...page.meta, total: objects.length, hasMore: false, cursor: null } : page.meta;
|
|
19624
|
+
}
|
|
19067
19625
|
printJson(out);
|
|
19068
19626
|
return;
|
|
19069
19627
|
}
|
|
19070
|
-
const
|
|
19071
|
-
const
|
|
19628
|
+
const documentsById = new Map(documents.map((d) => [d.id, d.name]));
|
|
19629
|
+
const namesByStakeholderId = stakeholderNamesById(page.data.objects);
|
|
19630
|
+
const sorted = [...objects].sort(compareConfidenceAsc);
|
|
19631
|
+
const meta3 = page.meta;
|
|
19632
|
+
const totalLabel = maxConfidence !== void 0 ? ` (${objects.length} matching)` : meta3?.total != null && objects.length !== meta3.total ? ` (${objects.length} shown, ${meta3.total} total)` : meta3?.total != null ? ` (${meta3.total} total)` : "";
|
|
19072
19633
|
printLine(`
|
|
19073
|
-
Objects${
|
|
19634
|
+
Objects${totalLabel}:
|
|
19074
19635
|
`);
|
|
19075
19636
|
printTable(
|
|
19076
|
-
|
|
19077
|
-
id: o.
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19637
|
+
sorted.map((o) => {
|
|
19638
|
+
const stakeholderIdValue = o.type === "STAKEHOLDER" ? o.id : o.stakeholderId ?? "";
|
|
19639
|
+
const stakeholderName = stakeholderIdValue ? namesByStakeholderId.get(stakeholderIdValue) ?? stakeholderIdValue : "";
|
|
19640
|
+
return {
|
|
19641
|
+
id: o.id,
|
|
19642
|
+
type: o.subtype ?? o.type,
|
|
19643
|
+
status: o.status,
|
|
19644
|
+
conf: formatConfidence(objectConfidence(o)),
|
|
19645
|
+
document: o.documentId ? documentsById.get(o.documentId) ?? o.documentId : "",
|
|
19646
|
+
stakeholder: stakeholderName,
|
|
19647
|
+
date: o.date ?? ""
|
|
19648
|
+
};
|
|
19649
|
+
}),
|
|
19083
19650
|
[
|
|
19084
19651
|
{ key: "id", label: "ID", width: 38 },
|
|
19085
|
-
{ key: "type", label: "Type", width:
|
|
19652
|
+
{ key: "type", label: "Type", width: 28 },
|
|
19086
19653
|
{ key: "status", label: "Status", width: 10 },
|
|
19087
|
-
{ key: "
|
|
19088
|
-
{ key: "
|
|
19654
|
+
{ key: "conf", label: "Conf", width: 6 },
|
|
19655
|
+
{ key: "document", label: "Document", width: 24 },
|
|
19656
|
+
{ key: "stakeholder", label: "Stakeholder", width: 22 },
|
|
19657
|
+
{ key: "date", label: "Date", width: 12 }
|
|
19089
19658
|
]
|
|
19090
19659
|
);
|
|
19091
|
-
if (meta3?.hasMore && meta3.cursor) {
|
|
19092
|
-
const shQ = (v) => `'${v.replace(/'/g, `'\\''`)}'`;
|
|
19093
|
-
const parts = ["captable-ai objects list"];
|
|
19094
|
-
if (type !== void 0) parts.push(`--type ${shQ(type)}`);
|
|
19095
|
-
if (subtype !== void 0) parts.push(`--subtype ${shQ(subtype)}`);
|
|
19096
|
-
if (status !== void 0) parts.push(`--status ${shQ(status)}`);
|
|
19097
|
-
if (q !== void 0) parts.push(`--q ${shQ(q)}`);
|
|
19098
|
-
if (from !== void 0) parts.push(`--from ${shQ(from)}`);
|
|
19099
|
-
if (to !== void 0) parts.push(`--to ${shQ(to)}`);
|
|
19100
|
-
if (ids !== void 0) parts.push(`--ids ${shQ(ids)}`);
|
|
19101
|
-
if (limit !== void 0) parts.push(`--limit ${shQ(String(limit))}`);
|
|
19102
|
-
parts.push(`--cursor ${shQ(meta3.cursor)}`);
|
|
19660
|
+
if (!drainAll && meta3?.hasMore && meta3.cursor) {
|
|
19103
19661
|
printLine(`
|
|
19104
19662
|
More results available. Next page:
|
|
19105
|
-
${
|
|
19663
|
+
${nextPageHint(query, meta3.cursor)}`);
|
|
19106
19664
|
}
|
|
19107
19665
|
printLine();
|
|
19108
19666
|
}
|
|
@@ -19116,7 +19674,7 @@ async function readStdin() {
|
|
|
19116
19674
|
}
|
|
19117
19675
|
return Buffer.concat(chunks).toString("utf-8");
|
|
19118
19676
|
}
|
|
19119
|
-
function
|
|
19677
|
+
function isRecord7(value) {
|
|
19120
19678
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19121
19679
|
}
|
|
19122
19680
|
function parsePatchPayload(raw) {
|
|
@@ -19131,7 +19689,7 @@ function parsePatchPayload(raw) {
|
|
|
19131
19689
|
EXIT.VALIDATION
|
|
19132
19690
|
);
|
|
19133
19691
|
}
|
|
19134
|
-
if (!
|
|
19692
|
+
if (!isRecord7(parsed)) {
|
|
19135
19693
|
exitWithError(
|
|
19136
19694
|
"OCF patch payload must be a JSON object.",
|
|
19137
19695
|
"VALIDATION_FAILED",
|
|
@@ -19351,7 +19909,7 @@ async function readStdin2() {
|
|
|
19351
19909
|
}
|
|
19352
19910
|
return Buffer.concat(chunks).toString("utf-8");
|
|
19353
19911
|
}
|
|
19354
|
-
function
|
|
19912
|
+
function isRecord8(value) {
|
|
19355
19913
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19356
19914
|
}
|
|
19357
19915
|
function parseOcfPayload(raw) {
|
|
@@ -19366,7 +19924,7 @@ function parseOcfPayload(raw) {
|
|
|
19366
19924
|
EXIT.VALIDATION
|
|
19367
19925
|
);
|
|
19368
19926
|
}
|
|
19369
|
-
if (!
|
|
19927
|
+
if (!isRecord8(parsed)) {
|
|
19370
19928
|
exitWithError(
|
|
19371
19929
|
"OCF payload must be a JSON object.",
|
|
19372
19930
|
"VALIDATION_FAILED",
|
|
@@ -19376,7 +19934,7 @@ function parseOcfPayload(raw) {
|
|
|
19376
19934
|
}
|
|
19377
19935
|
return parsed;
|
|
19378
19936
|
}
|
|
19379
|
-
function
|
|
19937
|
+
function shellQuote4(value) {
|
|
19380
19938
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
19381
19939
|
}
|
|
19382
19940
|
async function runObjectsUpdate(args, rawArgv) {
|
|
@@ -19501,7 +20059,7 @@ Updated object: ${obj.id}
|
|
|
19501
20059
|
printKeyValue([["Key", obj.schemaKey]]);
|
|
19502
20060
|
printLine(
|
|
19503
20061
|
`
|
|
19504
|
-
Run: captable-ai schemas get ${
|
|
20062
|
+
Run: captable-ai schemas get ${shellQuote4(obj.schemaKey)} to view the exact schema.`
|
|
19505
20063
|
);
|
|
19506
20064
|
}
|
|
19507
20065
|
printLine();
|
|
@@ -19735,20 +20293,20 @@ import { homedir as homedir4 } from "os";
|
|
|
19735
20293
|
import { join as join4 } from "path";
|
|
19736
20294
|
var CONFIG_DIR4 = join4(homedir4(), ".captable-ai");
|
|
19737
20295
|
var PROFILES_FILE = join4(CONFIG_DIR4, "profiles.json");
|
|
19738
|
-
function
|
|
20296
|
+
function isRecord9(value) {
|
|
19739
20297
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19740
20298
|
}
|
|
19741
20299
|
function isErrno3(err, code) {
|
|
19742
|
-
return
|
|
20300
|
+
return isRecord9(err) && err.code === code;
|
|
19743
20301
|
}
|
|
19744
20302
|
function parseProfiles(raw) {
|
|
19745
20303
|
const parsed = JSON.parse(raw);
|
|
19746
|
-
if (!
|
|
20304
|
+
if (!isRecord9(parsed) || !isRecord9(parsed.profiles)) {
|
|
19747
20305
|
throw new Error("profiles.json must contain a profiles object.");
|
|
19748
20306
|
}
|
|
19749
20307
|
const profiles = {};
|
|
19750
20308
|
for (const [name, value] of Object.entries(parsed.profiles)) {
|
|
19751
|
-
if (!
|
|
20309
|
+
if (!isRecord9(value) || typeof value.company !== "string" || !value.company.trim()) {
|
|
19752
20310
|
throw new Error(`Profile "${name}" must include a non-empty company string.`);
|
|
19753
20311
|
}
|
|
19754
20312
|
const stage = typeof value.stage === "string" && value.stage.trim() ? value.stage : void 0;
|
|
@@ -20429,9 +20987,11 @@ Cap Table (read):
|
|
|
20429
20987
|
Options: --as-of, --include-pending, --skip-stakeholders, --page
|
|
20430
20988
|
objects list List OCF objects
|
|
20431
20989
|
Filters: --type, --subtype, --status, --q, --from, --to, --ids
|
|
20432
|
-
|
|
20990
|
+
Review: --stakeholder, --document, --max-confidence N (requires --all)
|
|
20991
|
+
Pagination: --limit (1-250), --cursor, --all
|
|
20433
20992
|
Dates: --from / --to as YYYY-MM-DD
|
|
20434
20993
|
objects get <id> Show a single OCF object
|
|
20994
|
+
objects dump Engine-shaped ocf.json (default --status committed; --output path)
|
|
20435
20995
|
schemas list List OCF object types
|
|
20436
20996
|
schemas get <type> Show schema for an OCF type
|
|
20437
20997
|
|
|
@@ -20718,6 +21278,9 @@ async function main() {
|
|
|
20718
21278
|
case "get":
|
|
20719
21279
|
await runObjectsGet(parseArgs(positionalArgs.slice(2)), positionalArgs.slice(2));
|
|
20720
21280
|
break;
|
|
21281
|
+
case "dump":
|
|
21282
|
+
await runObjectsDump(parseArgs(positionalArgs.slice(2)), positionalArgs.slice(2));
|
|
21283
|
+
break;
|
|
20721
21284
|
case "update":
|
|
20722
21285
|
await runObjectsUpdate(parseArgs(positionalArgs.slice(2)), positionalArgs.slice(2));
|
|
20723
21286
|
break;
|
|
@@ -20735,7 +21298,7 @@ async function main() {
|
|
|
20735
21298
|
break;
|
|
20736
21299
|
default:
|
|
20737
21300
|
exitWithError(
|
|
20738
|
-
`Unknown objects command: ${sub ?? "(none)"}. Try: objects list | get | update | patch | revert | versions | delete`,
|
|
21301
|
+
`Unknown objects command: ${sub ?? "(none)"}. Try: objects list | get | dump | update | patch | revert | versions | delete`,
|
|
20739
21302
|
"UNKNOWN_COMMAND",
|
|
20740
21303
|
void 0,
|
|
20741
21304
|
EXIT.USAGE
|
package/package.json
CHANGED