@fairmint/captable-ai 0.1.3 → 0.1.5

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +295 -56
  3. 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\|update\|patch\|revert\|versions\|delete` | Work with extracted OCF objects (`list` supports `--document`, `--stakeholder`, `--all`, `--max-confidence`) |
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
  {
@@ -1127,7 +1147,7 @@ var COMMAND_REGISTRY = [
1127
1147
  }
1128
1148
  ];
1129
1149
  async function runCommands(_args) {
1130
- printJson({ schemaVersion: "6", version: "0.0.1", commands: COMMAND_REGISTRY });
1150
+ printJson({ schemaVersion: "7", version: "0.0.1", commands: COMMAND_REGISTRY });
1131
1151
  }
1132
1152
 
1133
1153
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
@@ -16486,20 +16506,27 @@ Usage:
16486
16506
  captable-ai objects list [options]
16487
16507
 
16488
16508
  Filters:
16489
- --type TYPE Top-level OCF types (comma-separated)
16490
- --subtype STYPE TRANSACTION subtypes (comma-separated)
16491
- --status STATUS draft | committed
16492
- --q QUERY Full-text search
16493
- --from DATE YYYY-MM-DD (inclusive lower bound on object date)
16494
- --to DATE YYYY-MM-DD (inclusive upper bound on object date)
16495
- --ids ID,ID,... Batch fetch by object IDs
16509
+ --type TYPE Top-level OCF types (comma-separated)
16510
+ --subtype STYPE TRANSACTION subtypes (comma-separated)
16511
+ --status STATUS draft | committed
16512
+ --q QUERY Full-text search
16513
+ --from DATE YYYY-MM-DD (inclusive lower bound on object date)
16514
+ --to DATE YYYY-MM-DD (inclusive upper bound on object date)
16515
+ --ids ID,ID,... Batch fetch by object IDs
16516
+ --stakeholder ID Filter by OCF stakeholder id
16517
+ --document S3_ASSET_ID Filter by source document
16518
+ --max-confidence N Keep objects with confidence <= N (requires --all)
16496
16519
 
16497
16520
  Pagination:
16498
- --limit N Page size (1\u2013250; omit for server default, typically 100)
16499
- --cursor C Opaque continuation cursor from prior response
16521
+ --limit N Page size (1\u2013250; omit for server default, typically 100)
16522
+ --cursor C Opaque continuation cursor from prior response
16523
+ --all Follow cursors until every matching object is returned
16524
+
16525
+ Human table sorts lowest extraction confidence first. Conf markers:
16526
+ !N red (<65) ~N amber (65\u201384) N green (\u226585)
16500
16527
 
16501
16528
  Global:
16502
- --json Machine-readable JSON output`;
16529
+ --json Machine-readable JSON output (API order, not confidence-sorted)`;
16503
16530
  var HELP_OBJECTS_GET = `objects get \u2014 Show one OCF object
16504
16531
 
16505
16532
  Usage:
@@ -18953,6 +18980,60 @@ Object: ${obj.id}
18953
18980
  printLine();
18954
18981
  }
18955
18982
 
18983
+ // src/objects-pages.ts
18984
+ var OBJECTS_LIST_MAX_PAGES = 100;
18985
+ async function fetchAllObjectPages(portalId, query) {
18986
+ const objects = [];
18987
+ const documentsById = /* @__PURE__ */ new Map();
18988
+ let cursor = typeof query.cursor === "string" ? query.cursor : void 0;
18989
+ let total = 0;
18990
+ let pages = 0;
18991
+ while (true) {
18992
+ pages += 1;
18993
+ if (pages > OBJECTS_LIST_MAX_PAGES) {
18994
+ exitWithError(
18995
+ `Exceeded max object-list pages (${OBJECTS_LIST_MAX_PAGES}). Narrow the query or raise the page size.`,
18996
+ "ERROR",
18997
+ void 0,
18998
+ EXIT.SERVER_ERROR
18999
+ );
19000
+ }
19001
+ const pageQuery = { ...query };
19002
+ if (cursor !== void 0) pageQuery.cursor = cursor;
19003
+ else delete pageQuery.cursor;
19004
+ const res = await apiRequest(`/${portalId}/objects`, { query: pageQuery });
19005
+ const pageObjects = res.data?.objects ?? [];
19006
+ const pageDocs = res.data?.documents ?? [];
19007
+ objects.push(...pageObjects);
19008
+ for (const doc of pageDocs) {
19009
+ documentsById.set(doc.id, doc);
19010
+ }
19011
+ if (res.meta?.total != null) total = res.meta.total;
19012
+ if (!res.meta?.hasMore) break;
19013
+ if (!res.meta.cursor) {
19014
+ exitWithError(
19015
+ "Pagination response has more results but no continuation cursor.",
19016
+ "ERROR",
19017
+ void 0,
19018
+ EXIT.SERVER_ERROR
19019
+ );
19020
+ }
19021
+ if (cursor !== void 0 && res.meta.cursor === cursor) {
19022
+ exitWithError(
19023
+ "Pagination cursor did not advance; stopped draining object pages.",
19024
+ "ERROR",
19025
+ void 0,
19026
+ EXIT.SERVER_ERROR
19027
+ );
19028
+ }
19029
+ cursor = res.meta.cursor;
19030
+ }
19031
+ return {
19032
+ data: { objects, documents: Array.from(documentsById.values()) },
19033
+ meta: { cursor: null, total: total || objects.length, hasMore: false }
19034
+ };
19035
+ }
19036
+
18956
19037
  // src/validate.ts
18957
19038
  var ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
18958
19039
  function isValidCalendarIsoDate(s) {
@@ -19020,6 +19101,106 @@ function validateIsoDateRange(fromRaw, toRaw) {
19020
19101
  }
19021
19102
 
19022
19103
  // src/commands/objects-list.ts
19104
+ var CONFIDENCE_RED_MAX = 64;
19105
+ var CONFIDENCE_AMBER_MAX = 84;
19106
+ function isRecord5(value) {
19107
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19108
+ }
19109
+ function getValidatedMaxConfidence(raw) {
19110
+ if (raw === void 0) return void 0;
19111
+ const trimmed = raw.trim();
19112
+ if (!/^\d+$/.test(trimmed)) {
19113
+ exitWithError(
19114
+ "--max-confidence must be an integer between 0 and 100",
19115
+ "VALIDATION_FAILED",
19116
+ void 0,
19117
+ EXIT.VALIDATION
19118
+ );
19119
+ }
19120
+ const n = Number.parseInt(trimmed, 10);
19121
+ if (n < 0 || n > 100) {
19122
+ exitWithError(
19123
+ "--max-confidence must be an integer between 0 and 100",
19124
+ "VALIDATION_FAILED",
19125
+ void 0,
19126
+ EXIT.VALIDATION
19127
+ );
19128
+ }
19129
+ return n;
19130
+ }
19131
+ function objectConfidence(obj) {
19132
+ const n = obj.extraction?.confidence;
19133
+ return typeof n === "number" && Number.isFinite(n) ? n : void 0;
19134
+ }
19135
+ function formatConfidence(confidence) {
19136
+ if (confidence === void 0) return "\u2014";
19137
+ if (confidence <= CONFIDENCE_RED_MAX) return `!${confidence}`;
19138
+ if (confidence <= CONFIDENCE_AMBER_MAX) return `~${confidence}`;
19139
+ return String(confidence);
19140
+ }
19141
+ function stakeholderDisplayName(ocf) {
19142
+ if (!ocf) return null;
19143
+ if (typeof ocf.name === "string" && ocf.name.trim()) return ocf.name.trim();
19144
+ if (typeof ocf.legal_name === "string" && ocf.legal_name.trim()) return ocf.legal_name.trim();
19145
+ if (isRecord5(ocf.name)) {
19146
+ const legal = ocf.name.legal_name;
19147
+ if (typeof legal === "string" && legal.trim()) return legal.trim();
19148
+ const parts = [ocf.name.first_name, ocf.name.last_name].filter(
19149
+ (p) => typeof p === "string" && p.trim().length > 0
19150
+ );
19151
+ if (parts.length > 0) return parts.join(" ");
19152
+ }
19153
+ return null;
19154
+ }
19155
+ function stakeholderNamesById(objects) {
19156
+ const names = /* @__PURE__ */ new Map();
19157
+ for (const obj of objects) {
19158
+ if (obj.type !== "STAKEHOLDER") continue;
19159
+ const name = stakeholderDisplayName(obj.ocf);
19160
+ if (name) names.set(obj.id, name);
19161
+ }
19162
+ return names;
19163
+ }
19164
+ function compareConfidenceAsc(a, b) {
19165
+ const ca = objectConfidence(a);
19166
+ const cb = objectConfidence(b);
19167
+ if (ca === void 0 && cb === void 0) return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
19168
+ if (ca === void 0) return 1;
19169
+ if (cb === void 0) return -1;
19170
+ if (ca !== cb) return ca - cb;
19171
+ return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
19172
+ }
19173
+ function shellQuote3(value) {
19174
+ return `'${value.replace(/'/g, `'\\''`)}'`;
19175
+ }
19176
+ function nextPageHint(query, cursor) {
19177
+ const parts = ["captable-ai objects list"];
19178
+ const flagNames = [
19179
+ { queryKey: "type", flag: "type" },
19180
+ { queryKey: "subtype", flag: "subtype" },
19181
+ { queryKey: "status", flag: "status" },
19182
+ { queryKey: "q", flag: "q" },
19183
+ { queryKey: "from", flag: "from" },
19184
+ { queryKey: "to", flag: "to" },
19185
+ { queryKey: "ids", flag: "ids" },
19186
+ { queryKey: "stakeholderId", flag: "stakeholder" },
19187
+ { queryKey: "documentId", flag: "document" },
19188
+ { queryKey: "limit", flag: "limit" }
19189
+ ];
19190
+ for (const { queryKey, flag } of flagNames) {
19191
+ const value = query[queryKey];
19192
+ if (value !== void 0) parts.push(`--${flag} ${shellQuote3(String(value))}`);
19193
+ }
19194
+ parts.push(`--cursor ${shellQuote3(cursor)}`);
19195
+ return parts.join(" ");
19196
+ }
19197
+ function documentsReferencedBy(documents, objects) {
19198
+ const ids = /* @__PURE__ */ new Set();
19199
+ for (const obj of objects) {
19200
+ if (typeof obj.documentId === "string" && obj.documentId.length > 0) ids.add(obj.documentId);
19201
+ }
19202
+ return documents.filter((doc) => ids.has(doc.id));
19203
+ }
19023
19204
  async function runObjectsList(args, rawArgv) {
19024
19205
  if (argvRequestsHelp(rawArgv)) {
19025
19206
  process.stdout.write(`${HELP_OBJECTS_LIST}
@@ -19027,14 +19208,45 @@ async function runObjectsList(args, rawArgv) {
19027
19208
  process.exit(0);
19028
19209
  }
19029
19210
  validateFlags(args, {
19030
- flags: ["type", "subtype", "status", "limit", "cursor", "q", "from", "to", "ids"],
19031
- booleans: []
19211
+ flags: [
19212
+ "type",
19213
+ "subtype",
19214
+ "status",
19215
+ "limit",
19216
+ "cursor",
19217
+ "q",
19218
+ "from",
19219
+ "to",
19220
+ "ids",
19221
+ "stakeholder",
19222
+ "document",
19223
+ "max-confidence"
19224
+ ],
19225
+ booleans: ["all"]
19032
19226
  });
19227
+ if (args.positional.length > 0) {
19228
+ exitWithError(
19229
+ `Unexpected argument: ${args.positional[0]}. This command takes no positional arguments.`,
19230
+ "UNEXPECTED_ARGUMENT",
19231
+ void 0,
19232
+ EXIT.USAGE
19233
+ );
19234
+ }
19033
19235
  const portalId = await getActivePortalId();
19034
19236
  const from = getFlagValue(args, "from");
19035
19237
  const to = getFlagValue(args, "to");
19036
19238
  validateIsoDateRange(from, to);
19037
19239
  const limit = getValidatedLimit(getFlagValue(args, "limit"));
19240
+ const drainAll = hasFlag(args, "all");
19241
+ const maxConfidence = getValidatedMaxConfidence(getFlagValue(args, "max-confidence"));
19242
+ if (maxConfidence !== void 0 && !drainAll) {
19243
+ exitWithError(
19244
+ "--max-confidence requires --all so the review queue is not a single page.",
19245
+ "VALIDATION_FAILED",
19246
+ void 0,
19247
+ EXIT.VALIDATION
19248
+ );
19249
+ }
19038
19250
  const type = getFlagValue(args, "type");
19039
19251
  const subtype = getFlagValue(args, "subtype");
19040
19252
  const status = getFlagValue(args, "status");
@@ -19049,6 +19261,8 @@ async function runObjectsList(args, rawArgv) {
19049
19261
  const q = getFlagValue(args, "q");
19050
19262
  const cursor = getFlagValue(args, "cursor");
19051
19263
  const ids = getFlagValue(args, "ids");
19264
+ const stakeholderId = getFlagValue(args, "stakeholder");
19265
+ const documentId = getFlagValue(args, "document");
19052
19266
  const query = {
19053
19267
  type,
19054
19268
  subtype,
@@ -19058,51 +19272,75 @@ async function runObjectsList(args, rawArgv) {
19058
19272
  cursor,
19059
19273
  from,
19060
19274
  to,
19061
- ids
19275
+ ids,
19276
+ stakeholderId,
19277
+ documentId
19062
19278
  };
19063
- const res = await apiRequest(`/${portalId}/objects`, { query });
19279
+ let page;
19280
+ if (drainAll) {
19281
+ page = await fetchAllObjectPages(portalId, query);
19282
+ } else {
19283
+ const res = await apiRequest(`/${portalId}/objects`, { query });
19284
+ page = {
19285
+ data: { objects: res.data?.objects ?? [], documents: res.data?.documents ?? [] },
19286
+ meta: res.meta ?? {}
19287
+ };
19288
+ }
19289
+ let objects = page.data.objects;
19290
+ let documents = page.data.documents;
19291
+ if (maxConfidence !== void 0) {
19292
+ objects = objects.filter((obj) => {
19293
+ const confidence = objectConfidence(obj);
19294
+ return confidence !== void 0 && confidence <= maxConfidence;
19295
+ });
19296
+ documents = documentsReferencedBy(documents, objects);
19297
+ }
19064
19298
  if (isJsonMode()) {
19065
- const out = { data: res.data };
19066
- if (res.meta !== void 0) out.meta = res.meta;
19299
+ const out = {
19300
+ data: { objects, documents }
19301
+ };
19302
+ if (page.meta !== void 0) {
19303
+ out.meta = maxConfidence !== void 0 ? { ...page.meta, total: objects.length, hasMore: false, cursor: null } : page.meta;
19304
+ }
19067
19305
  printJson(out);
19068
19306
  return;
19069
19307
  }
19070
- const objects = res.data?.objects ?? [];
19071
- const meta3 = res.meta;
19308
+ const documentsById = new Map(documents.map((d) => [d.id, d.name]));
19309
+ const namesByStakeholderId = stakeholderNamesById(page.data.objects);
19310
+ const sorted = [...objects].sort(compareConfidenceAsc);
19311
+ const meta3 = page.meta;
19312
+ 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
19313
  printLine(`
19073
- Objects${meta3?.total != null ? ` (${meta3.total} total)` : ""}:
19314
+ Objects${totalLabel}:
19074
19315
  `);
19075
19316
  printTable(
19076
- objects.map((o) => ({
19077
- id: o.id,
19078
- type: o.subtype ?? o.type,
19079
- status: o.status,
19080
- date: o.date ?? "",
19081
- version: o.version
19082
- })),
19317
+ sorted.map((o) => {
19318
+ const stakeholderIdValue = o.type === "STAKEHOLDER" ? o.id : o.stakeholderId ?? "";
19319
+ const stakeholderName = stakeholderIdValue ? namesByStakeholderId.get(stakeholderIdValue) ?? stakeholderIdValue : "";
19320
+ return {
19321
+ id: o.id,
19322
+ type: o.subtype ?? o.type,
19323
+ status: o.status,
19324
+ conf: formatConfidence(objectConfidence(o)),
19325
+ document: o.documentId ? documentsById.get(o.documentId) ?? o.documentId : "",
19326
+ stakeholder: stakeholderName,
19327
+ date: o.date ?? ""
19328
+ };
19329
+ }),
19083
19330
  [
19084
19331
  { key: "id", label: "ID", width: 38 },
19085
- { key: "type", label: "Type", width: 30 },
19332
+ { key: "type", label: "Type", width: 28 },
19086
19333
  { key: "status", label: "Status", width: 10 },
19087
- { key: "date", label: "Date", width: 12 },
19088
- { key: "version", label: "Version", width: 8 }
19334
+ { key: "conf", label: "Conf", width: 6 },
19335
+ { key: "document", label: "Document", width: 24 },
19336
+ { key: "stakeholder", label: "Stakeholder", width: 22 },
19337
+ { key: "date", label: "Date", width: 12 }
19089
19338
  ]
19090
19339
  );
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)}`);
19340
+ if (!drainAll && meta3?.hasMore && meta3.cursor) {
19103
19341
  printLine(`
19104
19342
  More results available. Next page:
19105
- ${parts.join(" ")}`);
19343
+ ${nextPageHint(query, meta3.cursor)}`);
19106
19344
  }
19107
19345
  printLine();
19108
19346
  }
@@ -19116,7 +19354,7 @@ async function readStdin() {
19116
19354
  }
19117
19355
  return Buffer.concat(chunks).toString("utf-8");
19118
19356
  }
19119
- function isRecord5(value) {
19357
+ function isRecord6(value) {
19120
19358
  return typeof value === "object" && value !== null && !Array.isArray(value);
19121
19359
  }
19122
19360
  function parsePatchPayload(raw) {
@@ -19131,7 +19369,7 @@ function parsePatchPayload(raw) {
19131
19369
  EXIT.VALIDATION
19132
19370
  );
19133
19371
  }
19134
- if (!isRecord5(parsed)) {
19372
+ if (!isRecord6(parsed)) {
19135
19373
  exitWithError(
19136
19374
  "OCF patch payload must be a JSON object.",
19137
19375
  "VALIDATION_FAILED",
@@ -19351,7 +19589,7 @@ async function readStdin2() {
19351
19589
  }
19352
19590
  return Buffer.concat(chunks).toString("utf-8");
19353
19591
  }
19354
- function isRecord6(value) {
19592
+ function isRecord7(value) {
19355
19593
  return typeof value === "object" && value !== null && !Array.isArray(value);
19356
19594
  }
19357
19595
  function parseOcfPayload(raw) {
@@ -19366,7 +19604,7 @@ function parseOcfPayload(raw) {
19366
19604
  EXIT.VALIDATION
19367
19605
  );
19368
19606
  }
19369
- if (!isRecord6(parsed)) {
19607
+ if (!isRecord7(parsed)) {
19370
19608
  exitWithError(
19371
19609
  "OCF payload must be a JSON object.",
19372
19610
  "VALIDATION_FAILED",
@@ -19376,7 +19614,7 @@ function parseOcfPayload(raw) {
19376
19614
  }
19377
19615
  return parsed;
19378
19616
  }
19379
- function shellQuote3(value) {
19617
+ function shellQuote4(value) {
19380
19618
  return `'${value.replace(/'/g, `'\\''`)}'`;
19381
19619
  }
19382
19620
  async function runObjectsUpdate(args, rawArgv) {
@@ -19501,7 +19739,7 @@ Updated object: ${obj.id}
19501
19739
  printKeyValue([["Key", obj.schemaKey]]);
19502
19740
  printLine(
19503
19741
  `
19504
- Run: captable-ai schemas get ${shellQuote3(obj.schemaKey)} to view the exact schema.`
19742
+ Run: captable-ai schemas get ${shellQuote4(obj.schemaKey)} to view the exact schema.`
19505
19743
  );
19506
19744
  }
19507
19745
  printLine();
@@ -19735,20 +19973,20 @@ import { homedir as homedir4 } from "os";
19735
19973
  import { join as join4 } from "path";
19736
19974
  var CONFIG_DIR4 = join4(homedir4(), ".captable-ai");
19737
19975
  var PROFILES_FILE = join4(CONFIG_DIR4, "profiles.json");
19738
- function isRecord7(value) {
19976
+ function isRecord8(value) {
19739
19977
  return typeof value === "object" && value !== null && !Array.isArray(value);
19740
19978
  }
19741
19979
  function isErrno3(err, code) {
19742
- return isRecord7(err) && err.code === code;
19980
+ return isRecord8(err) && err.code === code;
19743
19981
  }
19744
19982
  function parseProfiles(raw) {
19745
19983
  const parsed = JSON.parse(raw);
19746
- if (!isRecord7(parsed) || !isRecord7(parsed.profiles)) {
19984
+ if (!isRecord8(parsed) || !isRecord8(parsed.profiles)) {
19747
19985
  throw new Error("profiles.json must contain a profiles object.");
19748
19986
  }
19749
19987
  const profiles = {};
19750
19988
  for (const [name, value] of Object.entries(parsed.profiles)) {
19751
- if (!isRecord7(value) || typeof value.company !== "string" || !value.company.trim()) {
19989
+ if (!isRecord8(value) || typeof value.company !== "string" || !value.company.trim()) {
19752
19990
  throw new Error(`Profile "${name}" must include a non-empty company string.`);
19753
19991
  }
19754
19992
  const stage = typeof value.stage === "string" && value.stage.trim() ? value.stage : void 0;
@@ -20429,7 +20667,8 @@ Cap Table (read):
20429
20667
  Options: --as-of, --include-pending, --skip-stakeholders, --page
20430
20668
  objects list List OCF objects
20431
20669
  Filters: --type, --subtype, --status, --q, --from, --to, --ids
20432
- Pagination: --limit (1-250), --cursor
20670
+ Review: --stakeholder, --document, --max-confidence N (requires --all)
20671
+ Pagination: --limit (1-250), --cursor, --all
20433
20672
  Dates: --from / --to as YYYY-MM-DD
20434
20673
  objects get <id> Show a single OCF object
20435
20674
  schemas list List OCF object types
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fairmint/captable-ai",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Agent-native CLI for Captable AI — manage companies, upload documents, run OCF extraction, and commit cap tables from the terminal.",
5
5
  "keywords": [
6
6
  "captable",