@fairmint/captable-ai 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +266 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -602,7 +602,7 @@ var COMMAND_REGISTRY = [
|
|
|
602
602
|
{
|
|
603
603
|
name: "objects get",
|
|
604
604
|
group: "captable",
|
|
605
|
-
description: "Get a single OCF object with document and
|
|
605
|
+
description: "Get a single OCF object with document, extraction details, and a vesting summary when present.",
|
|
606
606
|
usage: "captable-ai objects get <object-id> [--json]",
|
|
607
607
|
requiresAuth: true,
|
|
608
608
|
requiresPortal: true
|
|
@@ -1168,7 +1168,7 @@ var COMMAND_REGISTRY = [
|
|
|
1168
1168
|
}
|
|
1169
1169
|
];
|
|
1170
1170
|
async function runCommands(_args) {
|
|
1171
|
-
printJson({ schemaVersion: "
|
|
1171
|
+
printJson({ schemaVersion: "9", version: "0.0.1", commands: COMMAND_REGISTRY });
|
|
1172
1172
|
}
|
|
1173
1173
|
|
|
1174
1174
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
@@ -15260,7 +15260,10 @@ var LEGAL_DOCUMENTS_MAPPING = {
|
|
|
15260
15260
|
"Founder Stock Purchase Agreement",
|
|
15261
15261
|
"Notice of Stock Purchase Exercise",
|
|
15262
15262
|
"Notice of RSA Exercise",
|
|
15263
|
-
"Share Grant Exercise"
|
|
15263
|
+
"Share Grant Exercise",
|
|
15264
|
+
"Restricted Stock Award Agreement",
|
|
15265
|
+
"Restricted Stock Award",
|
|
15266
|
+
"RSA Agreement"
|
|
15264
15267
|
]
|
|
15265
15268
|
},
|
|
15266
15269
|
"Rolling SAFE": {
|
|
@@ -16064,6 +16067,176 @@ var exportResultSchema = external_exports.object({
|
|
|
16064
16067
|
}).optional().describe("Present when pro-forma sheets were requested but engine refused.")
|
|
16065
16068
|
});
|
|
16066
16069
|
|
|
16070
|
+
// ../captable-ai-core/dist/format-vesting-summary.js
|
|
16071
|
+
function asRecord(value) {
|
|
16072
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
16073
|
+
return null;
|
|
16074
|
+
const out = {};
|
|
16075
|
+
for (const [key, val] of Object.entries(value)) {
|
|
16076
|
+
out[key] = val;
|
|
16077
|
+
}
|
|
16078
|
+
return out;
|
|
16079
|
+
}
|
|
16080
|
+
function gcd(a, b) {
|
|
16081
|
+
let x = Math.abs(Math.trunc(a));
|
|
16082
|
+
let y = Math.abs(Math.trunc(b));
|
|
16083
|
+
while (y !== 0) {
|
|
16084
|
+
const t = y;
|
|
16085
|
+
y = x % y;
|
|
16086
|
+
x = t;
|
|
16087
|
+
}
|
|
16088
|
+
return x || 1;
|
|
16089
|
+
}
|
|
16090
|
+
function reduceFraction(numerator, denominator) {
|
|
16091
|
+
const divisor = gcd(numerator, denominator);
|
|
16092
|
+
return { numerator: numerator / divisor, denominator: denominator / divisor };
|
|
16093
|
+
}
|
|
16094
|
+
function asConditions(value) {
|
|
16095
|
+
if (!Array.isArray(value))
|
|
16096
|
+
return [];
|
|
16097
|
+
return value.filter((item) => asRecord(item) !== null);
|
|
16098
|
+
}
|
|
16099
|
+
function portionFraction(condition) {
|
|
16100
|
+
const portion = asRecord(condition.portion);
|
|
16101
|
+
if (!portion)
|
|
16102
|
+
return null;
|
|
16103
|
+
const numerator = Number(portion.numerator);
|
|
16104
|
+
const denominator = Number(portion.denominator);
|
|
16105
|
+
if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0)
|
|
16106
|
+
return null;
|
|
16107
|
+
if (numerator <= 0)
|
|
16108
|
+
return null;
|
|
16109
|
+
return { numerator, denominator };
|
|
16110
|
+
}
|
|
16111
|
+
function formatPercent(numerator, denominator) {
|
|
16112
|
+
const reduced = reduceFraction(numerator, denominator);
|
|
16113
|
+
const pct = reduced.numerator / reduced.denominator * 100;
|
|
16114
|
+
if (Number.isInteger(pct) && pct >= 1 && pct <= 100)
|
|
16115
|
+
return `${pct}%`;
|
|
16116
|
+
return `${reduced.numerator}/${reduced.denominator}`;
|
|
16117
|
+
}
|
|
16118
|
+
function periodLabel(period) {
|
|
16119
|
+
if (!period)
|
|
16120
|
+
return null;
|
|
16121
|
+
let occurrences = 1;
|
|
16122
|
+
if (period.occurrences != null && period.occurrences !== "") {
|
|
16123
|
+
occurrences = Number(period.occurrences);
|
|
16124
|
+
if (!Number.isInteger(occurrences) || occurrences <= 0)
|
|
16125
|
+
return null;
|
|
16126
|
+
}
|
|
16127
|
+
let length = 1;
|
|
16128
|
+
if (period.length != null && period.length !== "") {
|
|
16129
|
+
const suppliedLength = Number(period.length);
|
|
16130
|
+
if (!Number.isFinite(suppliedLength) || suppliedLength < 0)
|
|
16131
|
+
return null;
|
|
16132
|
+
length = suppliedLength;
|
|
16133
|
+
}
|
|
16134
|
+
if (length === 0)
|
|
16135
|
+
return { cadence: "immediately", occurrences };
|
|
16136
|
+
const unit = String(period.type ?? "").toUpperCase();
|
|
16137
|
+
if (unit === "MONTHS") {
|
|
16138
|
+
return { cadence: length === 1 ? "monthly" : `every ${length} months`, occurrences };
|
|
16139
|
+
}
|
|
16140
|
+
if (unit === "DAYS") {
|
|
16141
|
+
return { cadence: length === 1 ? "daily" : `every ${length} days`, occurrences };
|
|
16142
|
+
}
|
|
16143
|
+
if (unit === "WEEKS") {
|
|
16144
|
+
return { cadence: length === 1 ? "weekly" : `every ${length} weeks`, occurrences };
|
|
16145
|
+
}
|
|
16146
|
+
if (unit === "YEARS") {
|
|
16147
|
+
return { cadence: length === 1 ? "yearly" : `every ${length} years`, occurrences };
|
|
16148
|
+
}
|
|
16149
|
+
return null;
|
|
16150
|
+
}
|
|
16151
|
+
function quantityLabel(condition) {
|
|
16152
|
+
const raw = condition.quantity;
|
|
16153
|
+
if (raw == null || raw === "")
|
|
16154
|
+
return null;
|
|
16155
|
+
const quantity = Number(raw);
|
|
16156
|
+
if (!Number.isFinite(quantity) || quantity <= 0)
|
|
16157
|
+
return null;
|
|
16158
|
+
return quantity === 1 ? "1 share" : `${quantity} shares`;
|
|
16159
|
+
}
|
|
16160
|
+
function trancheAmount(condition) {
|
|
16161
|
+
const fraction = portionFraction(condition);
|
|
16162
|
+
if (fraction)
|
|
16163
|
+
return formatPercent(fraction.numerator, fraction.denominator);
|
|
16164
|
+
return quantityLabel(condition);
|
|
16165
|
+
}
|
|
16166
|
+
function formatVestingSummary(ocf) {
|
|
16167
|
+
const record2 = asRecord(ocf);
|
|
16168
|
+
const conditions = asConditions(record2?.vesting_conditions);
|
|
16169
|
+
if (conditions.length === 0)
|
|
16170
|
+
return null;
|
|
16171
|
+
const parts = [];
|
|
16172
|
+
for (const condition of conditions) {
|
|
16173
|
+
const trigger = asRecord(condition.trigger);
|
|
16174
|
+
const triggerType = String(trigger?.type ?? "").toUpperCase();
|
|
16175
|
+
if (triggerType === "VESTING_EVENT") {
|
|
16176
|
+
const portion = asRecord(condition.portion);
|
|
16177
|
+
const remainder = portion?.remainder === true || portion?.remainder === "true";
|
|
16178
|
+
const hasAllocation = Boolean(trancheAmount(condition) || remainder);
|
|
16179
|
+
if (portion && !hasAllocation)
|
|
16180
|
+
continue;
|
|
16181
|
+
parts.push("event-based (see conditions)");
|
|
16182
|
+
continue;
|
|
16183
|
+
}
|
|
16184
|
+
const amount = trancheAmount(condition);
|
|
16185
|
+
if (!amount)
|
|
16186
|
+
continue;
|
|
16187
|
+
if (triggerType === "VESTING_START_DATE") {
|
|
16188
|
+
parts.push(`${amount} at grant`);
|
|
16189
|
+
continue;
|
|
16190
|
+
}
|
|
16191
|
+
if (triggerType === "VESTING_SCHEDULE_ABSOLUTE") {
|
|
16192
|
+
const date5 = typeof trigger?.date === "string" && trigger.date.length > 0 ? trigger.date : null;
|
|
16193
|
+
parts.push(date5 ? `${amount} on ${date5}` : `${amount} on a fixed date`);
|
|
16194
|
+
continue;
|
|
16195
|
+
}
|
|
16196
|
+
if (triggerType === "VESTING_SCHEDULE_RELATIVE") {
|
|
16197
|
+
const period = periodLabel(asRecord(trigger?.period));
|
|
16198
|
+
if (!period)
|
|
16199
|
+
continue;
|
|
16200
|
+
if (period.cadence === "immediately" && period.occurrences === 1) {
|
|
16201
|
+
parts.push(`${amount} immediately`);
|
|
16202
|
+
continue;
|
|
16203
|
+
}
|
|
16204
|
+
const fraction = portionFraction(condition);
|
|
16205
|
+
if (fraction) {
|
|
16206
|
+
const reduced = reduceFraction(fraction.numerator, fraction.denominator);
|
|
16207
|
+
parts.push(`${reduced.numerator}/${reduced.denominator} ${period.cadence} \xD7 ${period.occurrences}`);
|
|
16208
|
+
continue;
|
|
16209
|
+
}
|
|
16210
|
+
parts.push(`${amount} ${period.cadence} \xD7 ${period.occurrences}`);
|
|
16211
|
+
}
|
|
16212
|
+
}
|
|
16213
|
+
if (parts.length === 0)
|
|
16214
|
+
return null;
|
|
16215
|
+
return `Vesting: ${parts.join(", then ")}`;
|
|
16216
|
+
}
|
|
16217
|
+
function unresolvedVestingTermsId(ocf) {
|
|
16218
|
+
const record2 = asRecord(ocf);
|
|
16219
|
+
if (!record2)
|
|
16220
|
+
return null;
|
|
16221
|
+
if (Array.isArray(record2.vesting_conditions) && record2.vesting_conditions.length > 0) {
|
|
16222
|
+
return null;
|
|
16223
|
+
}
|
|
16224
|
+
return typeof record2.vesting_terms_id === "string" && record2.vesting_terms_id.length > 0 ? record2.vesting_terms_id : null;
|
|
16225
|
+
}
|
|
16226
|
+
async function resolveVestingSummary(ocf, fetchTermsOcf) {
|
|
16227
|
+
const direct = formatVestingSummary(ocf);
|
|
16228
|
+
if (direct)
|
|
16229
|
+
return direct;
|
|
16230
|
+
const termsId = unresolvedVestingTermsId(ocf);
|
|
16231
|
+
if (!termsId)
|
|
16232
|
+
return null;
|
|
16233
|
+
try {
|
|
16234
|
+
return formatVestingSummary(await fetchTermsOcf(termsId));
|
|
16235
|
+
} catch {
|
|
16236
|
+
return null;
|
|
16237
|
+
}
|
|
16238
|
+
}
|
|
16239
|
+
|
|
16067
16240
|
// ../captable-ai-core/dist/objects-dump.js
|
|
16068
16241
|
var DumpAssemblyError = class extends Error {
|
|
16069
16242
|
constructor(message) {
|
|
@@ -16469,12 +16642,19 @@ function coerceDetails(raw) {
|
|
|
16469
16642
|
return details.length > 0 ? details : void 0;
|
|
16470
16643
|
}
|
|
16471
16644
|
var REQUEST_TIMEOUT_MS2 = 3e4;
|
|
16472
|
-
function exitForRefreshFailure(err) {
|
|
16645
|
+
function exitForRefreshFailure(err, softFail = false) {
|
|
16473
16646
|
if (err instanceof Error && err.name === "AuthError") {
|
|
16474
|
-
|
|
16647
|
+
failRequest(
|
|
16648
|
+
softFail,
|
|
16649
|
+
"Session expired. Run: captable-ai login",
|
|
16650
|
+
"AUTH_EXPIRED",
|
|
16651
|
+
void 0,
|
|
16652
|
+
EXIT.AUTH
|
|
16653
|
+
);
|
|
16475
16654
|
}
|
|
16476
16655
|
if (err instanceof Error && (err.name === "NetworkError" || isTransportError(err))) {
|
|
16477
|
-
|
|
16656
|
+
failRequest(
|
|
16657
|
+
softFail,
|
|
16478
16658
|
"Network error while refreshing session. Check your connection and try again.",
|
|
16479
16659
|
"REFRESH_TRANSPORT",
|
|
16480
16660
|
void 0,
|
|
@@ -16482,7 +16662,8 @@ function exitForRefreshFailure(err) {
|
|
|
16482
16662
|
);
|
|
16483
16663
|
}
|
|
16484
16664
|
const detail = err instanceof Error ? err.message : String(err);
|
|
16485
|
-
|
|
16665
|
+
failRequest(
|
|
16666
|
+
softFail,
|
|
16486
16667
|
`Token refresh failed: ${detail}. Run: captable-ai login`,
|
|
16487
16668
|
"REFRESH_FAILED",
|
|
16488
16669
|
void 0,
|
|
@@ -16496,6 +16677,22 @@ function isTransportError(err) {
|
|
|
16496
16677
|
if (!(err instanceof Error)) return false;
|
|
16497
16678
|
return err.name === "TimeoutError" || err.name === "AbortError" || err.name === "TypeError" || /network|timeout|fetch|ECONNRESET|ENOTFOUND|ETIMEDOUT/i.test(err.message);
|
|
16498
16679
|
}
|
|
16680
|
+
var ApiRequestError = class extends Error {
|
|
16681
|
+
code;
|
|
16682
|
+
details;
|
|
16683
|
+
constructor(message, code, details) {
|
|
16684
|
+
super(message);
|
|
16685
|
+
this.name = "ApiRequestError";
|
|
16686
|
+
if (code !== void 0) this.code = code;
|
|
16687
|
+
if (details !== void 0) this.details = details;
|
|
16688
|
+
}
|
|
16689
|
+
};
|
|
16690
|
+
function failRequest(softFail, message, code, details, exitCode) {
|
|
16691
|
+
if (softFail) {
|
|
16692
|
+
throw new ApiRequestError(message, code, details);
|
|
16693
|
+
}
|
|
16694
|
+
exitWithError(message, code, details, exitCode);
|
|
16695
|
+
}
|
|
16499
16696
|
async function refreshTokens(creds) {
|
|
16500
16697
|
const baseUrl = getApiUrl();
|
|
16501
16698
|
let res;
|
|
@@ -16539,20 +16736,20 @@ async function refreshTokens(creds) {
|
|
|
16539
16736
|
await writeCredentials(updated);
|
|
16540
16737
|
return updated;
|
|
16541
16738
|
}
|
|
16542
|
-
async function getAuthHeaders() {
|
|
16739
|
+
async function getAuthHeaders(softFail = false) {
|
|
16543
16740
|
let creds = await readCredentials();
|
|
16544
16741
|
if (!creds) return {};
|
|
16545
16742
|
if (isTokenExpired(creds.accessToken)) {
|
|
16546
16743
|
try {
|
|
16547
16744
|
creds = await refreshTokens(creds);
|
|
16548
16745
|
} catch (err) {
|
|
16549
|
-
exitForRefreshFailure(err);
|
|
16746
|
+
exitForRefreshFailure(err, softFail);
|
|
16550
16747
|
}
|
|
16551
16748
|
}
|
|
16552
16749
|
return { Authorization: `Bearer ${creds.accessToken}` };
|
|
16553
16750
|
}
|
|
16554
16751
|
async function apiRequest(path, opts = {}) {
|
|
16555
|
-
const { method = "GET", body, query, skipAuth = false } = opts;
|
|
16752
|
+
const { method = "GET", body, query, skipAuth = false, softFail = false } = opts;
|
|
16556
16753
|
const baseUrl = getApiUrl();
|
|
16557
16754
|
const url2 = new URL(`${baseUrl}${path}`);
|
|
16558
16755
|
if (query) {
|
|
@@ -16562,7 +16759,7 @@ async function apiRequest(path, opts = {}) {
|
|
|
16562
16759
|
}
|
|
16563
16760
|
const headers = { "Content-Type": "application/json" };
|
|
16564
16761
|
if (!skipAuth) {
|
|
16565
|
-
Object.assign(headers, await getAuthHeaders());
|
|
16762
|
+
Object.assign(headers, await getAuthHeaders(softFail));
|
|
16566
16763
|
}
|
|
16567
16764
|
const buildFetchOpts = () => ({
|
|
16568
16765
|
method,
|
|
@@ -16575,14 +16772,16 @@ async function apiRequest(path, opts = {}) {
|
|
|
16575
16772
|
res = await fetch(url2.toString(), buildFetchOpts());
|
|
16576
16773
|
} catch (err) {
|
|
16577
16774
|
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
16578
|
-
|
|
16775
|
+
failRequest(
|
|
16776
|
+
softFail,
|
|
16579
16777
|
"Request timed out. Check your network connection and try again.",
|
|
16580
16778
|
"TIMEOUT",
|
|
16581
16779
|
void 0,
|
|
16582
16780
|
EXIT.NETWORK
|
|
16583
16781
|
);
|
|
16584
16782
|
}
|
|
16585
|
-
|
|
16783
|
+
failRequest(
|
|
16784
|
+
softFail,
|
|
16586
16785
|
`Network error: ${err instanceof Error ? err.message : "connection failed"}`,
|
|
16587
16786
|
"NETWORK",
|
|
16588
16787
|
void 0,
|
|
@@ -16596,23 +16795,25 @@ async function apiRequest(path, opts = {}) {
|
|
|
16596
16795
|
try {
|
|
16597
16796
|
refreshed = await refreshTokens(creds);
|
|
16598
16797
|
} catch (refreshErr) {
|
|
16599
|
-
exitForRefreshFailure(refreshErr);
|
|
16798
|
+
exitForRefreshFailure(refreshErr, softFail);
|
|
16600
16799
|
}
|
|
16601
16800
|
if (refreshed) {
|
|
16602
16801
|
headers.Authorization = `Bearer ${refreshed.accessToken}`;
|
|
16603
16802
|
try {
|
|
16604
16803
|
const retryRes = await fetch(url2.toString(), buildFetchOpts());
|
|
16605
|
-
return handleResponse(retryRes);
|
|
16804
|
+
return handleResponse(retryRes, softFail);
|
|
16606
16805
|
} catch (retryErr) {
|
|
16607
16806
|
if (retryErr instanceof DOMException && retryErr.name === "TimeoutError") {
|
|
16608
|
-
|
|
16807
|
+
failRequest(
|
|
16808
|
+
softFail,
|
|
16609
16809
|
"Request timed out. Check your network connection and try again.",
|
|
16610
16810
|
"TIMEOUT",
|
|
16611
16811
|
void 0,
|
|
16612
16812
|
EXIT.NETWORK
|
|
16613
16813
|
);
|
|
16614
16814
|
}
|
|
16615
|
-
|
|
16815
|
+
failRequest(
|
|
16816
|
+
softFail,
|
|
16616
16817
|
`Network error: ${retryErr instanceof Error ? retryErr.message : "connection failed"}`,
|
|
16617
16818
|
"NETWORK",
|
|
16618
16819
|
void 0,
|
|
@@ -16622,7 +16823,7 @@ async function apiRequest(path, opts = {}) {
|
|
|
16622
16823
|
}
|
|
16623
16824
|
}
|
|
16624
16825
|
}
|
|
16625
|
-
return handleResponse(res);
|
|
16826
|
+
return handleResponse(res, softFail);
|
|
16626
16827
|
}
|
|
16627
16828
|
function exitCodeForStatus(status) {
|
|
16628
16829
|
if (status === 400) return EXIT.VALIDATION;
|
|
@@ -16633,14 +16834,26 @@ function exitCodeForStatus(status) {
|
|
|
16633
16834
|
if (status >= 500) return EXIT.SERVER_ERROR;
|
|
16634
16835
|
return EXIT.SERVER_ERROR;
|
|
16635
16836
|
}
|
|
16636
|
-
async function handleResponse(res) {
|
|
16637
|
-
|
|
16837
|
+
async function handleResponse(res, softFail = false) {
|
|
16838
|
+
let text;
|
|
16839
|
+
try {
|
|
16840
|
+
text = await res.text();
|
|
16841
|
+
} catch (err) {
|
|
16842
|
+
failRequest(
|
|
16843
|
+
softFail,
|
|
16844
|
+
`Network error: ${err instanceof Error ? err.message : "connection failed"}`,
|
|
16845
|
+
"NETWORK",
|
|
16846
|
+
void 0,
|
|
16847
|
+
EXIT.NETWORK
|
|
16848
|
+
);
|
|
16849
|
+
}
|
|
16638
16850
|
let parsed;
|
|
16639
16851
|
try {
|
|
16640
16852
|
parsed = JSON.parse(text);
|
|
16641
16853
|
} catch {
|
|
16642
16854
|
if (!res.ok) {
|
|
16643
|
-
|
|
16855
|
+
failRequest(
|
|
16856
|
+
softFail,
|
|
16644
16857
|
`HTTP ${res.status}: ${text.slice(0, 200)}`,
|
|
16645
16858
|
`HTTP_${res.status}`,
|
|
16646
16859
|
void 0,
|
|
@@ -16656,14 +16869,26 @@ async function handleResponse(res) {
|
|
|
16656
16869
|
if (isRecord2(nested)) {
|
|
16657
16870
|
const code = typeof nested.code === "string" && nested.code.trim() ? nested.code : void 0;
|
|
16658
16871
|
const details = coerceDetails(nested.details);
|
|
16659
|
-
|
|
16872
|
+
failRequest(
|
|
16873
|
+
softFail,
|
|
16874
|
+
String(nested.message ?? `HTTP ${res.status}`),
|
|
16875
|
+
code,
|
|
16876
|
+
details,
|
|
16877
|
+
exitCode
|
|
16878
|
+
);
|
|
16660
16879
|
}
|
|
16661
16880
|
if (typeof nested === "string") {
|
|
16662
16881
|
const code = typeof obj.code === "string" && obj.code.trim() ? obj.code : `HTTP_${res.status}`;
|
|
16663
16882
|
const details = coerceDetails(obj.details);
|
|
16664
|
-
|
|
16883
|
+
failRequest(softFail, nested, code, details, exitCode);
|
|
16665
16884
|
}
|
|
16666
|
-
|
|
16885
|
+
failRequest(
|
|
16886
|
+
softFail,
|
|
16887
|
+
`HTTP ${res.status}: ${text.slice(0, 200)}`,
|
|
16888
|
+
void 0,
|
|
16889
|
+
void 0,
|
|
16890
|
+
exitCode
|
|
16891
|
+
);
|
|
16667
16892
|
}
|
|
16668
16893
|
return parsed;
|
|
16669
16894
|
}
|
|
@@ -16779,6 +17004,10 @@ Global:
|
|
|
16779
17004
|
--json Machine-readable JSON output (API order, not confidence-sorted)`;
|
|
16780
17005
|
var HELP_OBJECTS_GET = `objects get \u2014 Show one OCF object
|
|
16781
17006
|
|
|
17007
|
+
After the OCF payload, prints a one-line vesting summary when the object (or
|
|
17008
|
+
its vesting_terms_id target) has a condition graph. --json adds vestingSummary
|
|
17009
|
+
as a sibling of data \u2014 not inside ocf.
|
|
17010
|
+
|
|
16782
17011
|
Usage:
|
|
16783
17012
|
captable-ai objects get <object-id> [--json]`;
|
|
16784
17013
|
var HELP_OBJECTS_DUMP = `objects dump \u2014 Engine-shaped ocf.json
|
|
@@ -19314,9 +19543,17 @@ async function runObjectsGet(args, rawArgv) {
|
|
|
19314
19543
|
if (!obj) {
|
|
19315
19544
|
exitWithError("Object not found", "OBJECT_NOT_FOUND", void 0, EXIT.NOT_FOUND);
|
|
19316
19545
|
}
|
|
19546
|
+
const vestingSummary = await resolveVestingSummary(obj.ocf, async (termsId) => {
|
|
19547
|
+
const terms = await apiRequest(
|
|
19548
|
+
`/${portalId}/objects/${encodeURIComponent(termsId)}`,
|
|
19549
|
+
{ softFail: true }
|
|
19550
|
+
);
|
|
19551
|
+
return terms.data?.ocf ?? null;
|
|
19552
|
+
});
|
|
19317
19553
|
if (isJsonMode()) {
|
|
19318
19554
|
const out = { data: obj };
|
|
19319
19555
|
if (res.meta !== void 0) out.meta = res.meta;
|
|
19556
|
+
if (vestingSummary) out.vestingSummary = vestingSummary;
|
|
19320
19557
|
printJson(out);
|
|
19321
19558
|
return;
|
|
19322
19559
|
}
|
|
@@ -19351,7 +19588,10 @@ Object: ${obj.id}
|
|
|
19351
19588
|
}
|
|
19352
19589
|
printLine("\nOCF data:\n");
|
|
19353
19590
|
printJson(obj.ocf);
|
|
19354
|
-
printLine(
|
|
19591
|
+
if (vestingSummary) printLine(`
|
|
19592
|
+
${vestingSummary}
|
|
19593
|
+
`);
|
|
19594
|
+
else printLine();
|
|
19355
19595
|
}
|
|
19356
19596
|
|
|
19357
19597
|
// src/validate.ts
|
|
@@ -20990,7 +21230,7 @@ Cap Table (read):
|
|
|
20990
21230
|
Review: --stakeholder, --document, --max-confidence N (requires --all)
|
|
20991
21231
|
Pagination: --limit (1-250), --cursor, --all
|
|
20992
21232
|
Dates: --from / --to as YYYY-MM-DD
|
|
20993
|
-
objects get <id> Show a single OCF object
|
|
21233
|
+
objects get <id> Show a single OCF object (vesting summary when present)
|
|
20994
21234
|
objects dump Engine-shaped ocf.json (default --status committed; --output path)
|
|
20995
21235
|
schemas list List OCF object types
|
|
20996
21236
|
schemas get <type> Show schema for an OCF type
|
package/package.json
CHANGED