@fairmint/captable-ai 0.1.14 → 0.1.15

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 (2) hide show
  1. package/dist/index.js +183 -78
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -526,10 +526,73 @@ var COMMAND_REGISTRY = [
526
526
  {
527
527
  name: "onboarding setup",
528
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]",
529
+ description: "Idempotently create the authenticated user's first production workspace. Only --accept-terms is required; the company profile is read from uploaded documents.",
530
+ usage: "captable-ai onboarding setup --accept-terms [--legal-name <name>] [--company-type <type>] [--country <code>] [--role <role>] [--other-role <role>] [--cap-table-source <source>] [--other-cap-table-source <source>] [--stakeholder-count <bucket>] [--json]",
531
531
  requiresAuth: true,
532
- requiresPortal: false
532
+ requiresPortal: false,
533
+ flags: [
534
+ {
535
+ name: "accept-terms",
536
+ description: "Confirm acceptance of Fairmint's Terms of Service (required).",
537
+ type: "boolean"
538
+ },
539
+ {
540
+ name: "legal-name",
541
+ description: "Company name. Left unset until you or document extraction supplies one.",
542
+ type: "string"
543
+ },
544
+ {
545
+ name: "company-type",
546
+ description: "Legal entity type. Left unrecorded when omitted.",
547
+ type: "string",
548
+ enum: ["us_c_corporation", "us_llc", "foreign_entity", "not_incorporated"]
549
+ },
550
+ {
551
+ name: "country",
552
+ description: "ISO 3166-1 alpha-2 code. Only with --company-type foreign_entity.",
553
+ type: "string"
554
+ },
555
+ {
556
+ name: "role",
557
+ description: "Your role at the company.",
558
+ type: "string",
559
+ enum: [
560
+ "CEO",
561
+ "COO",
562
+ "CMO",
563
+ "CFO",
564
+ "CTO",
565
+ "CRO",
566
+ "Director",
567
+ "Founder",
568
+ "co-founder",
569
+ "co-CEO",
570
+ "other"
571
+ ]
572
+ },
573
+ {
574
+ name: "other-role",
575
+ description: "Free-text role. Required when --role other.",
576
+ type: "string"
577
+ },
578
+ {
579
+ name: "cap-table-source",
580
+ description: "Where the cap table is maintained today.",
581
+ type: "string",
582
+ enum: ["none", "spreadsheet", "carta", "pulley", "angellist", "other"]
583
+ },
584
+ {
585
+ name: "other-cap-table-source",
586
+ description: "Free-text source. Required when --cap-table-source other.",
587
+ type: "string"
588
+ },
589
+ {
590
+ name: "stakeholder-count",
591
+ description: "Approximate number of stakeholders on the cap table.",
592
+ type: "string",
593
+ enum: ["1_10", "11_25", "26_50", "50_100", "100_plus"]
594
+ }
595
+ ]
533
596
  },
534
597
  {
535
598
  name: "import start",
@@ -16637,60 +16700,109 @@ var hasControlCharacter = (value) => Array.from(value).some((character) => {
16637
16700
  });
16638
16701
  var legalNameSchema = shortTextSchema(255).refine((value) => !hasControlCharacter(value), "Legal name cannot contain control characters").describe("Confirmed legal name of the company.");
16639
16702
  var countryCodeSchema = external_exports.string().trim().transform((value) => value.toUpperCase()).pipe(external_exports.string().regex(/^[A-Z]{2}$/, "Must be an ISO 3166-1 alpha-2 country code")).describe("ISO 3166-1 alpha-2 country of incorporation. Required for foreign entities.");
16640
- var roleSchema = external_exports.discriminatedUnion("role", [
16641
- external_exports.object({
16642
- role: external_exports.enum(ONBOARDING_ROLES).describe("Founder's role at the company."),
16643
- otherRole: external_exports.never().optional().describe("Omit unless role is other.")
16644
- }),
16645
- external_exports.object({
16646
- role: external_exports.literal(ONBOARDING_OTHER_ROLE).describe("Founder's role at the company."),
16647
- otherRole: shortTextSchema(100).describe("Free-text role when role is other.")
16648
- })
16649
- ]);
16650
- var capTableSourceSchema = external_exports.discriminatedUnion("capTableSource", [
16651
- external_exports.object({
16652
- capTableSource: external_exports.enum([
16653
- ONBOARDING_CAP_TABLE_SOURCES.NONE,
16654
- ONBOARDING_CAP_TABLE_SOURCES.SPREADSHEET,
16655
- ONBOARDING_CAP_TABLE_SOURCES.CARTA,
16656
- ONBOARDING_CAP_TABLE_SOURCES.PULLEY,
16657
- ONBOARDING_CAP_TABLE_SOURCES.ANGELLIST
16658
- ]).describe("Where the current cap table is maintained."),
16659
- otherCapTableSource: external_exports.never().optional().describe("Omit unless capTableSource is other.")
16660
- }),
16661
- external_exports.object({
16662
- capTableSource: external_exports.literal(ONBOARDING_CAP_TABLE_SOURCES.OTHER).describe("Where the current cap table is maintained."),
16663
- otherCapTableSource: shortTextSchema(100).describe("Free-text cap table tool when capTableSource is other.")
16664
- })
16665
- ]);
16666
- var commonSetupSchema = external_exports.object({
16667
- legalName: legalNameSchema,
16668
- stakeholderCount: external_exports.enum(ONBOARDING_STAKEHOLDER_COUNT_BUCKETS).describe("Approximate number of stakeholders on the cap table."),
16669
- termsAccepted: external_exports.literal(true).describe("Whether the user accepted Fairmint's Terms of Service; must be true.")
16670
- }).and(roleSchema).and(capTableSourceSchema);
16671
- var companySchema = external_exports.discriminatedUnion("companyType", [
16672
- external_exports.object({
16673
- companyType: external_exports.enum([ONBOARDING_COMPANY_TYPES.US_C_CORPORATION, ONBOARDING_COMPANY_TYPES.US_LLC]).describe("Confirmed company type."),
16674
- country: external_exports.never().optional().describe("Omit for US companies.")
16675
- }),
16676
- external_exports.object({
16677
- companyType: external_exports.literal(ONBOARDING_COMPANY_TYPES.FOREIGN_ENTITY).describe("Confirmed company type."),
16678
- country: countryCodeSchema.refine((country) => country !== "US", {
16679
- message: "Foreign entities must use a non-US country"
16680
- }).describe("ISO 3166-1 alpha-2 country of incorporation. Required for foreign entities.")
16681
- }),
16682
- external_exports.object({
16683
- companyType: external_exports.literal(ONBOARDING_COMPANY_TYPES.NOT_INCORPORATED).describe("Confirmed company type."),
16684
- country: external_exports.never().optional().describe("Omit until the company is incorporated.")
16685
- })
16686
- ]);
16687
- var onboardingWorkspaceSetupInputSchema = commonSetupSchema.and(companySchema);
16703
+ var onboardingWorkspaceSetupInputSchema = external_exports.object({
16704
+ termsAccepted: external_exports.literal(true).describe("Whether the user accepted Fairmint's Terms of Service; must be true."),
16705
+ legalName: legalNameSchema.optional(),
16706
+ companyType: external_exports.enum([
16707
+ ONBOARDING_COMPANY_TYPES.US_C_CORPORATION,
16708
+ ONBOARDING_COMPANY_TYPES.US_LLC,
16709
+ ONBOARDING_COMPANY_TYPES.FOREIGN_ENTITY,
16710
+ ONBOARDING_COMPANY_TYPES.NOT_INCORPORATED
16711
+ ]).optional().describe("Confirmed company type. Left unrecorded when omitted."),
16712
+ country: countryCodeSchema.optional(),
16713
+ role: external_exports.enum([...ONBOARDING_ROLES, ONBOARDING_OTHER_ROLE]).optional().describe("Founder's role at the company."),
16714
+ otherRole: shortTextSchema(100).optional().describe("Free-text role when role is other."),
16715
+ capTableSource: external_exports.enum([
16716
+ ONBOARDING_CAP_TABLE_SOURCES.NONE,
16717
+ ONBOARDING_CAP_TABLE_SOURCES.SPREADSHEET,
16718
+ ONBOARDING_CAP_TABLE_SOURCES.CARTA,
16719
+ ONBOARDING_CAP_TABLE_SOURCES.PULLEY,
16720
+ ONBOARDING_CAP_TABLE_SOURCES.ANGELLIST,
16721
+ ONBOARDING_CAP_TABLE_SOURCES.OTHER
16722
+ ]).optional().describe("Where the current cap table is maintained."),
16723
+ otherCapTableSource: shortTextSchema(100).optional().describe("Free-text cap table tool when capTableSource is other."),
16724
+ stakeholderCount: external_exports.enum(ONBOARDING_STAKEHOLDER_COUNT_BUCKETS).optional().describe("Approximate number of stakeholders on the cap table.")
16725
+ }).superRefine((value, ctx) => {
16726
+ if (value.companyType === ONBOARDING_COMPANY_TYPES.FOREIGN_ENTITY) {
16727
+ if (value.country === void 0) {
16728
+ ctx.addIssue({
16729
+ code: "custom",
16730
+ path: ["country"],
16731
+ message: "Foreign entities must provide a country of incorporation"
16732
+ });
16733
+ } else if (value.country === "US") {
16734
+ ctx.addIssue({
16735
+ code: "custom",
16736
+ path: ["country"],
16737
+ message: "Foreign entities must use a non-US country"
16738
+ });
16739
+ }
16740
+ } else if (value.country !== void 0) {
16741
+ ctx.addIssue({
16742
+ code: "custom",
16743
+ path: ["country"],
16744
+ message: "Omit country unless companyType is foreign_entity"
16745
+ });
16746
+ }
16747
+ if (value.role === ONBOARDING_OTHER_ROLE) {
16748
+ if (value.otherRole === void 0) {
16749
+ ctx.addIssue({
16750
+ code: "custom",
16751
+ path: ["otherRole"],
16752
+ message: "Describe the role when role is other"
16753
+ });
16754
+ }
16755
+ } else if (value.otherRole !== void 0) {
16756
+ ctx.addIssue({
16757
+ code: "custom",
16758
+ path: ["otherRole"],
16759
+ message: "Omit otherRole unless role is other"
16760
+ });
16761
+ }
16762
+ if (value.capTableSource === ONBOARDING_CAP_TABLE_SOURCES.OTHER) {
16763
+ if (value.otherCapTableSource === void 0) {
16764
+ ctx.addIssue({
16765
+ code: "custom",
16766
+ path: ["otherCapTableSource"],
16767
+ message: "Describe the cap table source when capTableSource is other"
16768
+ });
16769
+ }
16770
+ } else if (value.otherCapTableSource !== void 0) {
16771
+ ctx.addIssue({
16772
+ code: "custom",
16773
+ path: ["otherCapTableSource"],
16774
+ message: "Omit otherCapTableSource unless capTableSource is other"
16775
+ });
16776
+ }
16777
+ });
16778
+ function dropOrphanOnboardingSetupDetails(input) {
16779
+ const next = { ...input };
16780
+ if (next.companyType !== void 0 && next.companyType !== ONBOARDING_COMPANY_TYPES.FOREIGN_ENTITY) {
16781
+ delete next.country;
16782
+ }
16783
+ if (next.role !== void 0 && next.role !== ONBOARDING_OTHER_ROLE) {
16784
+ delete next.otherRole;
16785
+ }
16786
+ if (next.capTableSource !== void 0 && next.capTableSource !== ONBOARDING_CAP_TABLE_SOURCES.OTHER) {
16787
+ delete next.otherCapTableSource;
16788
+ }
16789
+ return next;
16790
+ }
16791
+ function resolveOnboardingCompanyProfile(input) {
16792
+ const companyType = input.companyType ?? null;
16793
+ const country = companyType === null ? null : companyType === ONBOARDING_COMPANY_TYPES.FOREIGN_ENTITY ? input.country ?? null : ONBOARDING_COMPANY_TYPE_TO_ISSUER[companyType].countryOfFormation;
16794
+ return {
16795
+ legalName: input.legalName ?? null,
16796
+ companyType,
16797
+ country
16798
+ };
16799
+ }
16688
16800
  var onboardingWorkspaceSetupResultSchema = external_exports.object({
16689
16801
  portalId: external_exports.uuid().describe("ID of the user's first production workspace."),
16690
16802
  state: external_exports.literal(ONBOARDING_WORKSPACE_STATES.WORKSPACE_READY).describe("Workspace is created or reused and ready for import."),
16691
16803
  created: external_exports.boolean().describe("True when this request inserted a new portal."),
16692
- commitReady: external_exports.boolean().describe("True when the draft issuer has formation date and country of formation."),
16693
- commitBlockers: external_exports.array(external_exports.enum(["formation_date", "country_of_formation"])).describe("Issuer fields that still block a live commit."),
16804
+ commitReady: external_exports.boolean().describe("True when the draft issuer has legal name, formation date, and country of formation."),
16805
+ commitBlockers: external_exports.array(external_exports.enum(["legal_name", "formation_date", "country_of_formation"])).describe("Issuer fields that still block a live commit."),
16694
16806
  session: external_exports.object({
16695
16807
  action: external_exports.enum([
16696
16808
  ONBOARDING_SESSION_ACTIONS.NONE,
@@ -17244,20 +17356,24 @@ var HELP_ONBOARDING = `onboarding \u2014 Create a first workspace and inspect ne
17244
17356
 
17245
17357
  Usage:
17246
17358
  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]
17359
+ captable-ai onboarding setup --accept-terms [--legal-name <name>] [options] [--json]
17360
+
17361
+ Accepting the Terms is all that is required. The legal name, entity type, and
17362
+ country are read from the documents you upload, so you can skip them here and
17363
+ start importing right away.
17250
17364
 
17251
17365
  Setup values:
17366
+ --accept-terms Confirm acceptance of Fairmint's Terms of Service (required)
17367
+ --legal-name Company name. Left unset until you or document
17368
+ extraction supplies one; commit stays blocked until then.
17252
17369
  --company-type us_c_corporation | us_llc | foreign_entity | not_incorporated
17253
- --country ISO country code (required for foreign_entity)
17370
+ --country ISO country code (only with --company-type foreign_entity)
17254
17371
  --role CEO | COO | CMO | CFO | CTO | CRO | Director | Founder |
17255
17372
  co-founder | co-CEO | other
17256
17373
  --other-role Required when --role other
17257
17374
  --cap-table-source none | spreadsheet | carta | pulley | angellist | other
17258
17375
  --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`;
17376
+ --stakeholder-count 1_10 | 11_25 | 26_50 | 50_100 | 100_plus`;
17261
17377
  var HELP_IMPORT = `import \u2014 Start and inspect a secure document-import session
17262
17378
 
17263
17379
  Usage:
@@ -20865,10 +20981,10 @@ async function runOnboardingStatus(args) {
20865
20981
  nextAction(
20866
20982
  "setup_workspace",
20867
20983
  "Create your first workspace",
20868
- "captable-ai onboarding setup"
20984
+ "captable-ai onboarding setup --accept-terms"
20869
20985
  )
20870
20986
  ],
20871
- question: "What is your company's full legal name?"
20987
+ question: "Do you accept Fairmint's Terms of Service? That is all we need to open your workspace."
20872
20988
  } : !active ? {
20873
20989
  state: ONBOARDING_STATES.NEEDS_COMPANY_SELECTION,
20874
20990
  companies: credentials.portals,
@@ -20929,19 +21045,6 @@ function setupInput(args) {
20929
21045
  }
20930
21046
  return input;
20931
21047
  }
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
21048
  async function runOnboardingSetup(args) {
20946
21049
  validateFlags(args, {
20947
21050
  flags: [
@@ -20957,7 +21060,7 @@ async function runOnboardingSetup(args) {
20957
21060
  booleans: ["accept-terms"]
20958
21061
  });
20959
21062
  const parsed = onboardingWorkspaceSetupInputSchema.safeParse(
20960
- omitInapplicableOnboardingSetupFields(setupInput(args))
21063
+ dropOrphanOnboardingSetupDetails(setupInput(args))
20961
21064
  );
20962
21065
  if (!parsed.success) {
20963
21066
  const details = parsed.error.issues.map((issue2) => ({
@@ -20965,13 +21068,15 @@ async function runOnboardingSetup(args) {
20965
21068
  message: issue2.message
20966
21069
  }));
20967
21070
  exitWithError(
20968
- "Company setup answers are incomplete or invalid. Run `captable-ai onboarding setup --help` for accepted values.",
21071
+ "Company setup answers are invalid. Only `--accept-terms` is required on its own, but some answers require a partner flag: `--company-type foreign_entity` needs `--country`, `--role other` needs `--other-role`, and `--cap-table-source other` needs `--other-cap-table-source`. Run `captable-ai onboarding setup --help` for accepted values.",
20969
21072
  "VALIDATION_FAILED",
20970
21073
  details,
20971
21074
  EXIT.VALIDATION
20972
21075
  );
20973
21076
  }
20974
21077
  const input = parsed.data;
21078
+ const { legalName } = resolveOnboardingCompanyProfile(input);
21079
+ const workspaceLabel = legalName ?? "your new workspace";
20975
21080
  const response = await apiRequest("/onboarding/workspace", { method: "POST", body: input });
20976
21081
  const result = onboardingWorkspaceSetupResultSchema.safeParse(response.data ?? response);
20977
21082
  if (!result.success) {
@@ -21007,7 +21112,7 @@ async function runOnboardingSetup(args) {
21007
21112
  printJson({ data: data2 });
21008
21113
  return;
21009
21114
  }
21010
- printSuccess(`Workspace ready: ${input.legalName} (${result.data.portalId})`);
21115
+ printSuccess(`Workspace ready: ${workspaceLabel} (${result.data.portalId})`);
21011
21116
  printLine("Start the import: captable-ai import start");
21012
21117
  return;
21013
21118
  }
@@ -21023,7 +21128,7 @@ async function runOnboardingSetup(args) {
21023
21128
  printJson({ data });
21024
21129
  return;
21025
21130
  }
21026
- printSuccess(`Workspace ready: ${input.legalName} (${result.data.portalId})`);
21131
+ printSuccess(`Workspace ready: ${workspaceLabel} (${result.data.portalId})`);
21027
21132
  printLine("Reconnect so your session can access it: captable-ai login");
21028
21133
  }
21029
21134
  async function runImportStart(args) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fairmint/captable-ai",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
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",