@fairmint/captable-ai 0.1.13 → 0.1.14

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 +7 -1
  2. package/dist/index.js +480 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,8 +30,12 @@ the login code back into the terminal. Credentials are stored in `~/.captable-ai
30
30
 
31
31
  ```bash
32
32
  captable-ai login
33
- captable-ai company use "Acme Inc" # if you have more than one
33
+ captable-ai onboarding status
34
+ captable-ai onboarding setup ... # only when you have no workspace
35
+ captable-ai company use "Acme Inc" # if you have more than one
36
+ captable-ai import start
34
37
  captable-ai documents upload ./docs/*.pdf
38
+ captable-ai import status <session-id>
35
39
  captable-ai documents trigger-extraction # once all docs are CLASSIFIED
36
40
  captable-ai documents list # poll until PROCESSED
37
41
  captable-ai commit --dry-run # preview
@@ -84,6 +88,8 @@ automated, but a few habits make extraction faster and more accurate:
84
88
  |---------|-------------|
85
89
  | `login` / `logout` | Authenticate / clear stored credentials |
86
90
  | `auth status` | Show the current session |
91
+ | `onboarding status\|setup` | Inspect onboarding or create the first workspace |
92
+ | `import start\|status` | Start an import session and poll existing document processing |
87
93
  | `company list\|use\|current\|create\|delete` | Manage and select the active company |
88
94
  | `documents upload\|list\|download\|delete` | Manage source documents |
89
95
  | `documents trigger-extraction\|cancel-extraction\|restart-extraction\|reprocess` | Control the OCF extraction pipeline |
package/dist/index.js CHANGED
@@ -170,8 +170,8 @@ function parsePortals(body) {
170
170
  if (!portals.every(isStoredPortal)) return null;
171
171
  return portals;
172
172
  }
173
- async function refreshPortalsIfStale(creds) {
174
- if (creds.portalsLastFetchedAt && Date.now() - Date.parse(creds.portalsLastFetchedAt) < PORTALS_TTL_MS) {
173
+ async function refreshPortalsIfStale(creds, force = false) {
174
+ if (!force && creds.portalsLastFetchedAt && Date.now() - Date.parse(creds.portalsLastFetchedAt) < PORTALS_TTL_MS) {
175
175
  return creds;
176
176
  }
177
177
  if (isTokenExpired(creds.accessToken)) {
@@ -508,6 +508,45 @@ var COMMAND_REGISTRY = [
508
508
  requiresPortal: false,
509
509
  flags: [{ name: "yes", description: "Skip the confirmation prompt.", type: "boolean" }]
510
510
  },
511
+ {
512
+ name: "onboarding status",
513
+ group: "onboarding",
514
+ description: "Show the next first-workspace or import action. Works for authenticated users with zero companies.",
515
+ usage: "captable-ai onboarding status [--session <import-session-id>] [--json]",
516
+ requiresAuth: true,
517
+ requiresPortal: false,
518
+ flags: [
519
+ {
520
+ name: "session",
521
+ description: "Inspect this import session instead of local workspace state.",
522
+ type: "string"
523
+ }
524
+ ]
525
+ },
526
+ {
527
+ name: "onboarding setup",
528
+ group: "onboarding",
529
+ description: "Idempotently create the authenticated user's first production workspace.",
530
+ usage: "captable-ai onboarding setup --legal-name <name> --company-type <type> --role <role> --cap-table-source <source> --stakeholder-count <bucket> --accept-terms [--country <code>] [--other-role <role>] [--other-cap-table-source <source>] [--json]",
531
+ requiresAuth: true,
532
+ requiresPortal: false
533
+ },
534
+ {
535
+ name: "import start",
536
+ group: "onboarding",
537
+ description: "Start or reuse a secure import session for existing document upload APIs.",
538
+ usage: "captable-ai import start [--json]",
539
+ requiresAuth: true,
540
+ requiresPortal: true
541
+ },
542
+ {
543
+ name: "import status",
544
+ group: "onboarding",
545
+ description: "Show import processing progress and the next existing-pipeline action.",
546
+ usage: "captable-ai import status <session-id> [--json]",
547
+ requiresAuth: true,
548
+ requiresPortal: false
549
+ },
511
550
  {
512
551
  name: "summary",
513
552
  group: "captable",
@@ -1184,7 +1223,7 @@ var COMMAND_REGISTRY = [
1184
1223
  }
1185
1224
  ];
1186
1225
  async function runCommands(_args) {
1187
- printJson({ schemaVersion: "9", version: "0.0.1", commands: COMMAND_REGISTRY });
1226
+ printJson({ schemaVersion: "10", version: "0.0.1", commands: COMMAND_REGISTRY });
1188
1227
  }
1189
1228
 
1190
1229
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
@@ -16982,6 +17021,13 @@ async function refreshTokens(creds) {
16982
17021
  await writeCredentials(updated);
16983
17022
  return updated;
16984
17023
  }
17024
+ async function refreshSession() {
17025
+ const credentials = await readCredentials();
17026
+ if (!credentials) {
17027
+ exitWithError("Not logged in. Run: captable-ai login", "AUTH_REQUIRED", void 0, EXIT.AUTH);
17028
+ }
17029
+ return refreshTokens(credentials);
17030
+ }
16985
17031
  async function getAuthHeaders(softFail = false) {
16986
17032
  let creds = await readCredentials();
16987
17033
  if (!creds) return {};
@@ -17194,6 +17240,36 @@ function argvRequestsHelp(argv) {
17194
17240
  }
17195
17241
 
17196
17242
  // src/help-text.ts
17243
+ var HELP_ONBOARDING = `onboarding \u2014 Create a first workspace and inspect next steps
17244
+
17245
+ Usage:
17246
+ captable-ai onboarding status [--session <import-session-id>] [--json]
17247
+ captable-ai onboarding setup --legal-name <name> --company-type <type>
17248
+ --role <role> --cap-table-source <source> --stakeholder-count <bucket>
17249
+ --accept-terms [options] [--json]
17250
+
17251
+ Setup values:
17252
+ --company-type us_c_corporation | us_llc | foreign_entity | not_incorporated
17253
+ --country ISO country code (required for foreign_entity)
17254
+ --role CEO | COO | CMO | CFO | CTO | CRO | Director | Founder |
17255
+ co-founder | co-CEO | other
17256
+ --other-role Required when --role other
17257
+ --cap-table-source none | spreadsheet | carta | pulley | angellist | other
17258
+ --other-cap-table-source Required when --cap-table-source other
17259
+ --stakeholder-count 1_10 | 11_25 | 26_50 | 50_100 | 100_plus
17260
+ --accept-terms Confirm acceptance of Fairmint's Terms of Service`;
17261
+ var HELP_IMPORT = `import \u2014 Start and inspect a secure document-import session
17262
+
17263
+ Usage:
17264
+ captable-ai import start [--json]
17265
+ captable-ai import status <session-id> [--json]
17266
+
17267
+ For local files, the recommended data path remains:
17268
+ captable-ai documents upload <file...>
17269
+
17270
+ It performs prepare \u2192 direct presigned S3 PUT \u2192 confirm without routing file bytes
17271
+ through the CaptableAI API. After processing finishes, review drafts with
17272
+ \`objects list\` and commit with the existing \`commit --dry-run\` / \`commit --all\` commands.`;
17197
17273
  var HELP_AUTH = `auth \u2014 Session information
17198
17274
 
17199
17275
  Usage:
@@ -20767,6 +20843,355 @@ async function runObjectsVersions(args, rawArgv) {
20767
20843
  }
20768
20844
  }
20769
20845
 
20846
+ // src/commands/onboarding.ts
20847
+ function nextAction(id, label, command) {
20848
+ return command ? { id, label, required: true, command } : { id, label, required: true };
20849
+ }
20850
+ async function runOnboardingStatus(args) {
20851
+ validateFlags(args, { flags: ["session"], booleans: [] });
20852
+ const sessionId = typeof args.flags.session === "string" ? args.flags.session : void 0;
20853
+ if (sessionId) {
20854
+ await runImportStatus(parseArgs([sessionId]));
20855
+ return;
20856
+ }
20857
+ const credentials = await readCredentials();
20858
+ if (!credentials) {
20859
+ exitWithError("Not logged in. Run: captable-ai login", "AUTH_REQUIRED", void 0, EXIT.AUTH);
20860
+ }
20861
+ const active = resolveActiveCompany(await readConfig(), credentials.portals);
20862
+ const data = credentials.portals.length === 0 ? {
20863
+ state: ONBOARDING_STATES.NEEDS_COMPANY_SETUP,
20864
+ nextActions: [
20865
+ nextAction(
20866
+ "setup_workspace",
20867
+ "Create your first workspace",
20868
+ "captable-ai onboarding setup"
20869
+ )
20870
+ ],
20871
+ question: "What is your company's full legal name?"
20872
+ } : !active ? {
20873
+ state: ONBOARDING_STATES.NEEDS_COMPANY_SELECTION,
20874
+ companies: credentials.portals,
20875
+ nextActions: [
20876
+ nextAction(
20877
+ "select_company",
20878
+ "Choose the company to import into",
20879
+ "captable-ai company use <id-or-name>"
20880
+ )
20881
+ ],
20882
+ question: "Which company should receive this cap table import?"
20883
+ } : {
20884
+ state: ONBOARDING_STATES.READY_TO_IMPORT,
20885
+ company: active,
20886
+ nextActions: [
20887
+ nextAction(
20888
+ "start_import",
20889
+ "Start a secure import session",
20890
+ "captable-ai import start"
20891
+ ),
20892
+ nextAction(
20893
+ "upload_cli",
20894
+ "Upload local documents directly to S3",
20895
+ "captable-ai documents upload <file...>"
20896
+ )
20897
+ ],
20898
+ question: `Should I start a secure import session for ${active.name ?? active.id}?`
20899
+ };
20900
+ if (isJsonMode()) {
20901
+ printJson({ data });
20902
+ return;
20903
+ }
20904
+ printKeyValue([
20905
+ ["State", data.state],
20906
+ ["Question", data.question]
20907
+ ]);
20908
+ for (const action of data.nextActions) {
20909
+ printLine(` Next: ${String(action.command)}`);
20910
+ }
20911
+ }
20912
+ function setupInput(args) {
20913
+ const flagMap = {
20914
+ legalName: "legal-name",
20915
+ companyType: "company-type",
20916
+ country: "country",
20917
+ role: "role",
20918
+ otherRole: "other-role",
20919
+ capTableSource: "cap-table-source",
20920
+ otherCapTableSource: "other-cap-table-source",
20921
+ stakeholderCount: "stakeholder-count"
20922
+ };
20923
+ const input = {
20924
+ termsAccepted: hasFlag(args, "accept-terms")
20925
+ };
20926
+ for (const [field, flag] of Object.entries(flagMap)) {
20927
+ const value = args.flags[flag];
20928
+ if (typeof value === "string") input[field] = value;
20929
+ }
20930
+ return input;
20931
+ }
20932
+ function omitInapplicableOnboardingSetupFields(input) {
20933
+ const next = { ...input };
20934
+ if (next.companyType !== ONBOARDING_COMPANY_TYPES.FOREIGN_ENTITY) {
20935
+ delete next.country;
20936
+ }
20937
+ if (next.role !== ONBOARDING_OTHER_ROLE) {
20938
+ delete next.otherRole;
20939
+ }
20940
+ if (next.capTableSource !== ONBOARDING_CAP_TABLE_SOURCES.OTHER) {
20941
+ delete next.otherCapTableSource;
20942
+ }
20943
+ return next;
20944
+ }
20945
+ async function runOnboardingSetup(args) {
20946
+ validateFlags(args, {
20947
+ flags: [
20948
+ "legal-name",
20949
+ "company-type",
20950
+ "country",
20951
+ "role",
20952
+ "other-role",
20953
+ "cap-table-source",
20954
+ "other-cap-table-source",
20955
+ "stakeholder-count"
20956
+ ],
20957
+ booleans: ["accept-terms"]
20958
+ });
20959
+ const parsed = onboardingWorkspaceSetupInputSchema.safeParse(
20960
+ omitInapplicableOnboardingSetupFields(setupInput(args))
20961
+ );
20962
+ if (!parsed.success) {
20963
+ const details = parsed.error.issues.map((issue2) => ({
20964
+ path: issue2.path.join("."),
20965
+ message: issue2.message
20966
+ }));
20967
+ exitWithError(
20968
+ "Company setup answers are incomplete or invalid. Run `captable-ai onboarding setup --help` for accepted values.",
20969
+ "VALIDATION_FAILED",
20970
+ details,
20971
+ EXIT.VALIDATION
20972
+ );
20973
+ }
20974
+ const input = parsed.data;
20975
+ const response = await apiRequest("/onboarding/workspace", { method: "POST", body: input });
20976
+ const result = onboardingWorkspaceSetupResultSchema.safeParse(response.data ?? response);
20977
+ if (!result.success) {
20978
+ exitWithError(
20979
+ "Unexpected onboarding setup response from server.",
20980
+ "SERVER_ERROR",
20981
+ void 0,
20982
+ EXIT.SERVER_ERROR
20983
+ );
20984
+ }
20985
+ if (result.data.session.action === ONBOARDING_SESSION_ACTIONS.REFRESH) {
20986
+ const refreshed = await refreshSession();
20987
+ const withPortals = await refreshPortalsIfStale(refreshed, true);
20988
+ const portal = withPortals.portals.find(({ id }) => id === result.data.portalId);
20989
+ if (!portal) {
20990
+ exitWithError(
20991
+ "Workspace was created, but the refreshed session did not include it.",
20992
+ "SESSION_REFRESH_FAILED",
20993
+ void 0,
20994
+ EXIT.SERVER_ERROR
20995
+ );
20996
+ }
20997
+ await setActivePortal(portal);
20998
+ const data2 = {
20999
+ ...result.data,
21000
+ state: ONBOARDING_STATES.READY_TO_IMPORT,
21001
+ nextActions: [
21002
+ nextAction("start_import", "Start the secure document import", "captable-ai import start")
21003
+ ],
21004
+ question: "Your workspace is ready. Start the document import now?"
21005
+ };
21006
+ if (isJsonMode()) {
21007
+ printJson({ data: data2 });
21008
+ return;
21009
+ }
21010
+ printSuccess(`Workspace ready: ${input.legalName} (${result.data.portalId})`);
21011
+ printLine("Start the import: captable-ai import start");
21012
+ return;
21013
+ }
21014
+ const data = {
21015
+ ...result.data,
21016
+ nextActions: [
21017
+ nextAction("reconnect", "Reconnect to activate the workspace", "captable-ai login"),
21018
+ nextAction("start_import", "Start an import after reconnecting", "captable-ai import start")
21019
+ ],
21020
+ question: "Your workspace is ready. Please run `captable-ai login` again, then start the import."
21021
+ };
21022
+ if (isJsonMode()) {
21023
+ printJson({ data });
21024
+ return;
21025
+ }
21026
+ printSuccess(`Workspace ready: ${input.legalName} (${result.data.portalId})`);
21027
+ printLine("Reconnect so your session can access it: captable-ai login");
21028
+ }
21029
+ async function runImportStart(args) {
21030
+ validateFlags(args, { flags: [], booleans: [] });
21031
+ const portalId = await getActivePortalId();
21032
+ const response = await apiRequest(
21033
+ "/import-sessions",
21034
+ {
21035
+ method: "POST",
21036
+ body: { portalId }
21037
+ }
21038
+ );
21039
+ const session = response.data?.session;
21040
+ if (!session?.id) {
21041
+ exitWithError(
21042
+ "Unexpected import session response from server.",
21043
+ "SERVER_ERROR",
21044
+ void 0,
21045
+ EXIT.SERVER_ERROR
21046
+ );
21047
+ }
21048
+ const data = {
21049
+ ...response.data,
21050
+ nextActions: [
21051
+ nextAction(
21052
+ "upload_cli",
21053
+ "Upload local documents directly to S3",
21054
+ "captable-ai documents upload <file...>"
21055
+ ),
21056
+ nextAction(
21057
+ "check_status",
21058
+ "Check import progress",
21059
+ `captable-ai import status ${session.id}`
21060
+ )
21061
+ ],
21062
+ question: "Which cap table documents should be uploaded with `documents upload`?"
21063
+ };
21064
+ if (isJsonMode()) {
21065
+ printJson({ data });
21066
+ return;
21067
+ }
21068
+ printSuccess(`Import session ${response.data?.reused ? "reused" : "started"}: ${session.id}`);
21069
+ printLine("Upload documents: captable-ai documents upload <file...>");
21070
+ printLine(`Check progress: captable-ai import status ${session.id}`);
21071
+ }
21072
+ var TERMINAL_DOCUMENT_STATUSES = /* @__PURE__ */ new Set(["PROCESSED", "COMMITTED", "FAILED", "CANCELLED"]);
21073
+ function documentsForImportSession(documents, sessionCreatedAt) {
21074
+ if (typeof sessionCreatedAt !== "string" || sessionCreatedAt.length === 0) return [];
21075
+ return documents.filter(
21076
+ (document) => typeof document.lastActivityAt === "string" && document.lastActivityAt >= sessionCreatedAt
21077
+ );
21078
+ }
21079
+ function summarizeImportDocuments(documents) {
21080
+ const statuses = documents.map((document) => (document.status ?? "").toUpperCase());
21081
+ const failed = statuses.filter((status) => ["FAILED", "CANCELLED"].includes(status)).length;
21082
+ const classified = statuses.filter((status) => status === "CLASSIFIED").length;
21083
+ const pendingUpload = statuses.filter((status) => status === "PENDING_UPLOAD").length;
21084
+ const processing = statuses.filter(
21085
+ (status) => status !== "" && !TERMINAL_DOCUMENT_STATUSES.has(status) && status !== "CLASSIFIED" && status !== "PENDING_UPLOAD"
21086
+ ).length;
21087
+ return {
21088
+ total: documents.length,
21089
+ processing,
21090
+ classified,
21091
+ pendingUpload,
21092
+ failed,
21093
+ complete: documents.length - failed - processing - classified - pendingUpload
21094
+ };
21095
+ }
21096
+ async function runImportStatus(args) {
21097
+ validateFlags(args, { flags: [], booleans: [] });
21098
+ const sessionId = args.positional[0];
21099
+ if (!sessionId) {
21100
+ exitWithUsage(
21101
+ "Import session ID is required.",
21102
+ "Usage: captable-ai import status <session-id> [--json]"
21103
+ );
21104
+ }
21105
+ const response = await apiRequest(
21106
+ `/import-sessions/${encodeURIComponent(sessionId)}/status`
21107
+ );
21108
+ const documents = documentsForImportSession(
21109
+ response.data?.processing?.documents ?? [],
21110
+ response.data?.session?.createdAt
21111
+ );
21112
+ const summary = summarizeImportDocuments(documents);
21113
+ const sessionState = response.data?.session?.state;
21114
+ if (documents.length > 0 && summary.processing === 0 && summary.classified === 0 && summary.pendingUpload === 0 && summary.failed === 0 && sessionState !== "completed") {
21115
+ const completed = await apiRequest(
21116
+ `/import-sessions/${encodeURIComponent(sessionId)}/complete`,
21117
+ {
21118
+ method: "POST",
21119
+ body: {}
21120
+ }
21121
+ );
21122
+ if (response.data && completed.data?.session) {
21123
+ response.data.session = { ...response.data.session, ...completed.data.session };
21124
+ }
21125
+ }
21126
+ const state = documents.length === 0 ? ONBOARDING_STATES.READY_TO_IMPORT : summary.processing > 0 ? ONBOARDING_STATES.PROCESSING : summary.classified > 0 || summary.pendingUpload > 0 ? ONBOARDING_STATES.READY_TO_IMPORT : summary.failed > 0 ? ONBOARDING_STATES.BLOCKED : ONBOARDING_STATES.NEEDS_REVIEW;
21127
+ const nextActions = documents.length === 0 || summary.pendingUpload > 0 ? [
21128
+ nextAction(
21129
+ "upload_cli",
21130
+ "Upload local documents directly to S3",
21131
+ "captable-ai documents upload <file...>"
21132
+ ),
21133
+ ...summary.classified > 0 ? [
21134
+ nextAction(
21135
+ "trigger_extraction",
21136
+ "Start OCF extraction for classified documents",
21137
+ "captable-ai documents trigger-extraction"
21138
+ )
21139
+ ] : []
21140
+ ] : summary.classified > 0 ? [
21141
+ nextAction(
21142
+ "trigger_extraction",
21143
+ "Start OCF extraction for classified documents",
21144
+ "captable-ai documents trigger-extraction"
21145
+ )
21146
+ ] : summary.processing > 0 ? [
21147
+ nextAction(
21148
+ "check_status",
21149
+ "Check import progress again",
21150
+ `captable-ai import status ${sessionId}`
21151
+ )
21152
+ ] : summary.failed > 0 ? [
21153
+ nextAction(
21154
+ "review_failures",
21155
+ "Review failed documents",
21156
+ "captable-ai documents list --status FAILED"
21157
+ )
21158
+ ] : [
21159
+ nextAction(
21160
+ "review_drafts",
21161
+ "Review extracted drafts",
21162
+ "captable-ai objects list --status draft --all"
21163
+ ),
21164
+ nextAction(
21165
+ "preview_commit",
21166
+ "Preview the first commit",
21167
+ "captable-ai commit --dry-run"
21168
+ ),
21169
+ nextAction("confirm_commit", "Commit reviewed drafts", "captable-ai commit --all")
21170
+ ];
21171
+ const data = {
21172
+ ...response.data,
21173
+ state,
21174
+ summary,
21175
+ nextActions
21176
+ };
21177
+ if (isJsonMode()) {
21178
+ printJson({ data });
21179
+ return;
21180
+ }
21181
+ printKeyValue([
21182
+ ["Session", sessionId],
21183
+ ["State", data.state],
21184
+ ["Documents", summary.total],
21185
+ ["Classified", summary.classified],
21186
+ ["Processing", summary.processing],
21187
+ ["Complete", summary.complete],
21188
+ ["Failed", summary.failed]
21189
+ ]);
21190
+ for (const action of nextActions) {
21191
+ printLine(` Next: ${String(action.command)}`);
21192
+ }
21193
+ }
21194
+
20770
21195
  // src/commands/pro-forma.ts
20771
21196
  var SCENARIO_TYPES2 = ["financing", "convertible", "warrant", "option-pool"];
20772
21197
  function buildScenarioBody(type, args) {
@@ -21597,7 +22022,9 @@ var PROFILE_AWARE_COMMANDS = /* @__PURE__ */ new Set([
21597
22022
  "company",
21598
22023
  "documents",
21599
22024
  "export",
22025
+ "import",
21600
22026
  "objects",
22027
+ "onboarding",
21601
22028
  "pro-forma",
21602
22029
  "register",
21603
22030
  "logs",
@@ -21621,6 +22048,12 @@ Company:
21621
22048
  company create Create a test portal (super admin)
21622
22049
  company delete <id> Delete a test portal (dev only, super admin)
21623
22050
 
22051
+ Onboarding:
22052
+ onboarding status Show the next setup/import action (works with zero companies)
22053
+ onboarding setup Create the first production workspace
22054
+ import start Start or reuse a document import session
22055
+ import status <id> Check import processing via existing document APIs
22056
+
21624
22057
  Cap Table (read):
21625
22058
  summary Full cap table snapshot (capitalization, stakeholders, metrics)
21626
22059
  Options: --as-of, --include-pending, --skip-stakeholders, --page
@@ -21897,6 +22330,50 @@ async function main() {
21897
22330
  case "company":
21898
22331
  await routeCompany(positionalArgs);
21899
22332
  break;
22333
+ case "onboarding":
22334
+ if (isHelpToken(sub) || argvRequestsHelp(positionalArgs.slice(2))) {
22335
+ process.stdout.write(`${HELP_ONBOARDING}
22336
+ `);
22337
+ process.exit(0);
22338
+ }
22339
+ switch (sub) {
22340
+ case "status":
22341
+ await runOnboardingStatus(parseArgs(positionalArgs.slice(2)));
22342
+ break;
22343
+ case "setup":
22344
+ await runOnboardingSetup(parseArgs(positionalArgs.slice(2)));
22345
+ break;
22346
+ default:
22347
+ exitWithError(
22348
+ `Unknown onboarding command: ${sub ?? "(none)"}. Try: onboarding status | setup`,
22349
+ "UNKNOWN_COMMAND",
22350
+ void 0,
22351
+ EXIT.USAGE
22352
+ );
22353
+ }
22354
+ break;
22355
+ case "import":
22356
+ if (isHelpToken(sub) || argvRequestsHelp(positionalArgs.slice(2))) {
22357
+ process.stdout.write(`${HELP_IMPORT}
22358
+ `);
22359
+ process.exit(0);
22360
+ }
22361
+ switch (sub) {
22362
+ case "start":
22363
+ await runImportStart(parseArgs(positionalArgs.slice(2)));
22364
+ break;
22365
+ case "status":
22366
+ await runImportStatus(parseArgs(positionalArgs.slice(2)));
22367
+ break;
22368
+ default:
22369
+ exitWithError(
22370
+ `Unknown import command: ${sub ?? "(none)"}. Try: import start | status`,
22371
+ "UNKNOWN_COMMAND",
22372
+ void 0,
22373
+ EXIT.USAGE
22374
+ );
22375
+ }
22376
+ break;
21900
22377
  case "summary":
21901
22378
  if (argvRequestsHelp(positionalArgs.slice(1))) {
21902
22379
  process.stdout.write(`${HELP_SUMMARY}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fairmint/captable-ai",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
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",