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