@thecorporation/corp-tools 26.3.23 → 26.3.25

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 CHANGED
@@ -343,6 +343,10 @@ var CorpAPIClient = class {
343
343
  const resp = await this.request("DELETE", path);
344
344
  await this.throwIfError(resp);
345
345
  }
346
+ /** Public generic GET for declarative/registry-driven commands. */
347
+ async fetchJSON(path, params) {
348
+ return this.get(path, params);
349
+ }
346
350
  // --- Workspace ---
347
351
  getStatus() {
348
352
  return this.get(`/v1/workspaces/${pathSegment(this.workspaceId)}/status`);
@@ -721,6 +725,13 @@ var CorpAPIClient = class {
721
725
  getSignerToken(obligationId) {
722
726
  return this.post(`/v1/human-obligations/${pathSegment(obligationId)}/signer-token`);
723
727
  }
728
+ // --- Next Steps ---
729
+ getEntityNextSteps(entityId) {
730
+ return this.get(`/v1/entities/${pathSegment(entityId)}/next-steps`);
731
+ }
732
+ getWorkspaceNextSteps() {
733
+ return this.get(`/v1/workspaces/${pathSegment(this.workspaceId)}/next-steps`);
734
+ }
724
735
  // --- Demo ---
725
736
  seedDemo(data) {
726
737
  return this.post("/v1/demo/seed", data);
@@ -2298,6 +2309,647 @@ var VotingMethod = ["per_capita", "per_unit"];
2298
2309
  var WorkItemActorTypeValue = ["contact", "agent"];
2299
2310
  var WorkItemStatus = ["open", "claimed", "completed", "cancelled"];
2300
2311
  var WorkflowType = ["transfer", "fundraising"];
2312
+
2313
+ // src/reference-tracker.ts
2314
+ var RESOURCE_KINDS = [
2315
+ "entity",
2316
+ "contact",
2317
+ "share_transfer",
2318
+ "invoice",
2319
+ "bank_account",
2320
+ "payment",
2321
+ "payroll_run",
2322
+ "distribution",
2323
+ "reconciliation",
2324
+ "tax_filing",
2325
+ "deadline",
2326
+ "classification",
2327
+ "body",
2328
+ "meeting",
2329
+ "seat",
2330
+ "agenda_item",
2331
+ "resolution",
2332
+ "document",
2333
+ "work_item",
2334
+ "agent",
2335
+ "valuation",
2336
+ "safe_note",
2337
+ "instrument",
2338
+ "share_class",
2339
+ "round",
2340
+ "service_request"
2341
+ ];
2342
+ var VALID_RESOURCE_KINDS = new Set(RESOURCE_KINDS);
2343
+ var MAX_REFERENCE_INPUT_LEN = 256;
2344
+ function normalize(value) {
2345
+ return value.trim().toLowerCase();
2346
+ }
2347
+ function validateReferenceInput(value, field, options = {}) {
2348
+ const trimmed = value.trim();
2349
+ if (!options.allowEmpty && trimmed.length === 0) {
2350
+ throw new Error(`${field} cannot be empty.`);
2351
+ }
2352
+ if (trimmed.length > MAX_REFERENCE_INPUT_LEN) {
2353
+ throw new Error(`${field} must be at most ${MAX_REFERENCE_INPUT_LEN} characters.`);
2354
+ }
2355
+ return trimmed;
2356
+ }
2357
+ function shortId(value) {
2358
+ return String(value ?? "").slice(0, 8);
2359
+ }
2360
+ function slugify(value) {
2361
+ return String(value ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
2362
+ }
2363
+ function isOpaqueUuid(value) {
2364
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
2365
+ value.trim()
2366
+ );
2367
+ }
2368
+ function isShortIdCandidate(value) {
2369
+ const trimmed = value.trim();
2370
+ return /^[0-9a-f-]{4,}$/i.test(trimmed) || /^[a-z]+_[a-z0-9_-]{3,}$/i.test(trimmed);
2371
+ }
2372
+ function parseLastReference(value) {
2373
+ const trimmed = validateReferenceInput(value, "reference", { allowEmpty: false }).toLowerCase();
2374
+ if (trimmed === "_" || trimmed === "@last") {
2375
+ return { isLast: true };
2376
+ }
2377
+ if (trimmed.startsWith("@last:")) {
2378
+ const kind = trimmed.slice(6);
2379
+ if (!VALID_RESOURCE_KINDS.has(kind)) {
2380
+ throw new Error(`Unknown reference kind: ${kind}`);
2381
+ }
2382
+ return { isLast: true, kind };
2383
+ }
2384
+ return { isLast: false };
2385
+ }
2386
+ function uniqueStrings(values) {
2387
+ const out = /* @__PURE__ */ new Set();
2388
+ for (const value of values) {
2389
+ if (!value) continue;
2390
+ const trimmed = value.trim();
2391
+ if (!trimmed) continue;
2392
+ out.add(normalize(trimmed));
2393
+ const slug = slugify(trimmed);
2394
+ if (slug) out.add(slug);
2395
+ }
2396
+ return out;
2397
+ }
2398
+ function kindLabel(kind) {
2399
+ return kind.replaceAll("_", " ");
2400
+ }
2401
+ function isEntityScopedKind(kind) {
2402
+ return kind !== "entity" && kind !== "agent";
2403
+ }
2404
+ function extractId(record, fields) {
2405
+ for (const field of fields) {
2406
+ const value = record[field];
2407
+ if (typeof value === "string" && value.trim()) {
2408
+ return value.trim();
2409
+ }
2410
+ }
2411
+ return void 0;
2412
+ }
2413
+ function isValidResourceKind(kind) {
2414
+ return VALID_RESOURCE_KINDS.has(kind);
2415
+ }
2416
+ function describeReferenceRecord(kind, record) {
2417
+ const specs = {
2418
+ entity: { idFields: ["entity_id", "id"], labelFields: ["legal_name", "name"] },
2419
+ contact: { idFields: ["contact_id", "id"], labelFields: ["name", "email"] },
2420
+ share_transfer: {
2421
+ idFields: ["transfer_id", "id"],
2422
+ labelFields: ["from_holder", "to_holder", "transfer_type", "status"]
2423
+ },
2424
+ invoice: {
2425
+ idFields: ["invoice_id", "id"],
2426
+ labelFields: ["customer_name", "description", "due_date"]
2427
+ },
2428
+ bank_account: {
2429
+ idFields: ["bank_account_id", "account_id", "id"],
2430
+ labelFields: ["bank_name", "account_type"]
2431
+ },
2432
+ payment: {
2433
+ idFields: ["payment_id", "id"],
2434
+ labelFields: ["recipient", "description", "payment_method"]
2435
+ },
2436
+ payroll_run: {
2437
+ idFields: ["payroll_run_id", "id"],
2438
+ labelFields: ["pay_period_start", "pay_period_end"]
2439
+ },
2440
+ distribution: {
2441
+ idFields: ["distribution_id", "id"],
2442
+ labelFields: ["description", "distribution_type"]
2443
+ },
2444
+ reconciliation: {
2445
+ idFields: ["reconciliation_id", "id"],
2446
+ labelFields: ["as_of_date", "status"]
2447
+ },
2448
+ tax_filing: {
2449
+ idFields: ["filing_id", "id"],
2450
+ labelFields: ["document_type", "tax_year"]
2451
+ },
2452
+ deadline: {
2453
+ idFields: ["deadline_id", "id"],
2454
+ labelFields: ["deadline_type", "description", "due_date"]
2455
+ },
2456
+ classification: {
2457
+ idFields: ["classification_id", "id"],
2458
+ labelFields: ["contractor_name", "state", "risk_level"]
2459
+ },
2460
+ body: { idFields: ["body_id", "id"], labelFields: ["name"] },
2461
+ meeting: { idFields: ["meeting_id", "id"], labelFields: ["title", "name"] },
2462
+ seat: {
2463
+ idFields: ["seat_id", "id"],
2464
+ labelFields: ["seat_name", "title", "holder_name", "holder", "holder_email"]
2465
+ },
2466
+ agenda_item: { idFields: ["agenda_item_id", "item_id", "id"], labelFields: ["title"] },
2467
+ resolution: { idFields: ["resolution_id", "id"], labelFields: ["title"] },
2468
+ document: { idFields: ["document_id", "id"], labelFields: ["title", "name"] },
2469
+ work_item: { idFields: ["work_item_id", "id"], labelFields: ["title"] },
2470
+ agent: { idFields: ["agent_id", "id"], labelFields: ["name"] },
2471
+ valuation: {
2472
+ idFields: ["valuation_id", "id"],
2473
+ labelFields: ["valuation_type", "effective_date", "date"]
2474
+ },
2475
+ safe_note: {
2476
+ idFields: ["safe_note_id", "safe_id", "id"],
2477
+ labelFields: ["investor_name", "investor", "safe_type"]
2478
+ },
2479
+ instrument: { idFields: ["instrument_id", "id"], labelFields: ["symbol", "kind", "name"] },
2480
+ share_class: {
2481
+ idFields: ["share_class_id", "id"],
2482
+ labelFields: ["class_code", "name", "share_class"]
2483
+ },
2484
+ round: { idFields: ["round_id", "equity_round_id", "id"], labelFields: ["name"] },
2485
+ service_request: {
2486
+ idFields: ["request_id", "service_request_id", "id"],
2487
+ labelFields: ["service_slug", "status"]
2488
+ }
2489
+ };
2490
+ const spec = specs[kind];
2491
+ const id = extractId(record, spec.idFields);
2492
+ if (!id) {
2493
+ return null;
2494
+ }
2495
+ const labels = spec.labelFields.map((field) => record[field]).filter((value) => typeof value === "string" && value.trim().length > 0);
2496
+ const persistedHandle = typeof record.handle === "string" && record.handle.trim().length > 0 ? record.handle.trim() : void 0;
2497
+ let label = labels[0] ?? id;
2498
+ if (kind === "share_transfer") {
2499
+ const fromHolder = typeof record.from_holder === "string" ? record.from_holder.trim() : "";
2500
+ const toHolder = typeof record.to_holder === "string" ? record.to_holder.trim() : "";
2501
+ const transferType = typeof record.transfer_type === "string" ? record.transfer_type.trim() : "";
2502
+ const composite = [
2503
+ fromHolder && toHolder ? `${fromHolder}-to-${toHolder}` : "",
2504
+ transferType
2505
+ ].filter(Boolean).join("-");
2506
+ if (composite) {
2507
+ label = composite;
2508
+ }
2509
+ }
2510
+ return {
2511
+ id,
2512
+ label,
2513
+ tokens: uniqueStrings([id, persistedHandle, ...labels]),
2514
+ raw: record
2515
+ };
2516
+ }
2517
+ function getReferenceId(kind, record) {
2518
+ return describeReferenceRecord(kind, record)?.id;
2519
+ }
2520
+ function getReferenceLabel(kind, record) {
2521
+ return describeReferenceRecord(kind, record)?.label;
2522
+ }
2523
+ function getReferenceAlias(kind, record) {
2524
+ if (typeof record.handle === "string" && record.handle.trim().length > 0) {
2525
+ return record.handle.trim();
2526
+ }
2527
+ const described = describeReferenceRecord(kind, record);
2528
+ if (!described) return void 0;
2529
+ const alias = slugify(described.label);
2530
+ return alias || shortId(described.id);
2531
+ }
2532
+ function matchRank(record, normalizedQuery) {
2533
+ if (!normalizedQuery || normalizedQuery === "*") {
2534
+ return 5;
2535
+ }
2536
+ if (normalize(record.id) === normalizedQuery) {
2537
+ return 0;
2538
+ }
2539
+ if (record.tokens.has(normalizedQuery)) {
2540
+ return 1;
2541
+ }
2542
+ if (normalize(record.id).startsWith(normalizedQuery)) {
2543
+ return 2;
2544
+ }
2545
+ if (Array.from(record.tokens).some((token) => token.startsWith(normalizedQuery))) {
2546
+ return 3;
2547
+ }
2548
+ return 4;
2549
+ }
2550
+ var ReferenceTracker = class {
2551
+ constructor(storage) {
2552
+ this.storage = storage;
2553
+ }
2554
+ /** Remember a reference for @last reuse. */
2555
+ remember(kind, id, entityId) {
2556
+ this.storage.setLastReference(kind, id, entityId);
2557
+ }
2558
+ /** Resolve @last / @last:kind references. */
2559
+ resolveLastReference(ref, kind, entityId) {
2560
+ const parsed = parseLastReference(ref);
2561
+ if (!parsed.isLast) return parsed;
2562
+ const lastKind = parsed.kind ?? kind;
2563
+ if (lastKind !== kind) {
2564
+ throw new Error(
2565
+ `@last:${lastKind} cannot be used where a ${kindLabel(kind)} reference is required.`
2566
+ );
2567
+ }
2568
+ const id = this.storage.getLastReference(lastKind, entityId);
2569
+ return { ...parsed, id };
2570
+ }
2571
+ /** Find the single best match for a query against a list of records. */
2572
+ findBestMatch(kind, query, records) {
2573
+ const matches = this.findMatches(kind, query, records);
2574
+ return matches.length > 0 ? matches[0] : null;
2575
+ }
2576
+ /** Find all matching records ranked by relevance. */
2577
+ findMatches(kind, query, records) {
2578
+ const trimmedQuery = validateReferenceInput(query, "query", { allowEmpty: true });
2579
+ const described = records.map((record) => describeReferenceRecord(kind, record)).filter((record) => record !== null);
2580
+ const normalizedQuery = normalize(trimmedQuery);
2581
+ const matches = described.filter((record) => {
2582
+ if (!normalizedQuery || normalizedQuery === "*") {
2583
+ return true;
2584
+ }
2585
+ if (normalize(record.id).startsWith(normalizedQuery)) {
2586
+ return true;
2587
+ }
2588
+ if (record.tokens.has(normalizedQuery)) {
2589
+ return true;
2590
+ }
2591
+ return Array.from(record.tokens).some((token) => token.includes(normalizedQuery));
2592
+ }).sort(
2593
+ (left, right) => matchRank(left, normalizedQuery) - matchRank(right, normalizedQuery) || left.label.localeCompare(right.label) || left.id.localeCompare(right.id)
2594
+ );
2595
+ return matches.map((record) => ({
2596
+ kind,
2597
+ id: record.id,
2598
+ short_id: shortId(record.id),
2599
+ label: record.label,
2600
+ alias: getReferenceAlias(kind, record.raw),
2601
+ raw: record.raw
2602
+ }));
2603
+ }
2604
+ };
2605
+
2606
+ // src/workflows/equity-helpers.ts
2607
+ function normalizedGrantType2(grantType) {
2608
+ return grantType.trim().toLowerCase().replaceAll("-", "_").replaceAll(" ", "_");
2609
+ }
2610
+ function expectedInstrumentKinds2(grantType) {
2611
+ switch (normalizedGrantType2(grantType)) {
2612
+ case "common":
2613
+ case "common_stock":
2614
+ return ["common_equity"];
2615
+ case "preferred":
2616
+ case "preferred_stock":
2617
+ return ["preferred_equity"];
2618
+ case "unit":
2619
+ case "membership_unit":
2620
+ return ["membership_unit"];
2621
+ case "option":
2622
+ case "options":
2623
+ case "stock_option":
2624
+ case "iso":
2625
+ case "nso":
2626
+ return ["option_grant"];
2627
+ case "rsa":
2628
+ return ["common_equity", "preferred_equity"];
2629
+ default:
2630
+ return [];
2631
+ }
2632
+ }
2633
+ function grantRequiresCurrent409a2(grantType, instrumentKind) {
2634
+ return instrumentKind?.toLowerCase() === "option_grant" || expectedInstrumentKinds2(grantType).includes("option_grant");
2635
+ }
2636
+ function buildInstrumentCreationHint(grantType) {
2637
+ const normalized = normalizedGrantType2(grantType);
2638
+ switch (normalized) {
2639
+ case "preferred":
2640
+ case "preferred_stock":
2641
+ return "Create one with: corp cap-table create-instrument --kind preferred_equity --symbol SERIES-A --authorized-units <shares>";
2642
+ case "option":
2643
+ case "options":
2644
+ case "stock_option":
2645
+ case "iso":
2646
+ case "nso":
2647
+ return "Create one with: corp cap-table create-instrument --kind option_grant --symbol OPTION-PLAN --authorized-units <shares>";
2648
+ case "membership_unit":
2649
+ case "unit":
2650
+ return "Create one with: corp cap-table create-instrument --kind membership_unit --symbol UNIT --authorized-units <units>";
2651
+ case "common":
2652
+ case "common_stock":
2653
+ return "Create one with: corp cap-table create-instrument --kind common_equity --symbol COMMON --authorized-units <shares>";
2654
+ default:
2655
+ return "Create a matching instrument first, then pass --instrument-id explicitly.";
2656
+ }
2657
+ }
2658
+ function resolveInstrumentForGrant2(instruments, grantType, explicitInstrumentId) {
2659
+ if (explicitInstrumentId) {
2660
+ const explicit = instruments.find(
2661
+ (instrument) => instrument.instrument_id === explicitInstrumentId
2662
+ );
2663
+ if (!explicit) {
2664
+ throw new Error(
2665
+ `Instrument ${explicitInstrumentId} was not found on the cap table.`
2666
+ );
2667
+ }
2668
+ return explicit;
2669
+ }
2670
+ const kinds = expectedInstrumentKinds2(grantType);
2671
+ if (kinds.length === 0) {
2672
+ throw new Error(
2673
+ `No default instrument mapping exists for grant type "${grantType}". ${buildInstrumentCreationHint(grantType)}`
2674
+ );
2675
+ }
2676
+ const match = instruments.find(
2677
+ (instrument) => kinds.includes(String(instrument.kind).toLowerCase())
2678
+ );
2679
+ if (!match) {
2680
+ throw new Error(
2681
+ `No instrument found for grant type "${grantType}". Expected one of: ${kinds.join(", ")}. ${buildInstrumentCreationHint(grantType)}`
2682
+ );
2683
+ }
2684
+ return match;
2685
+ }
2686
+ async function entityHasActiveBoard2(client, entityId) {
2687
+ const bodies = await client.listGovernanceBodies(entityId);
2688
+ return bodies.some(
2689
+ (body) => String(body.body_type ?? "").toLowerCase() === "board_of_directors" && String(body.status ?? "active").toLowerCase() === "active"
2690
+ );
2691
+ }
2692
+ async function ensureIssuancePreflight2(client, entityId, grantType, instrument, meetingId, resolutionId) {
2693
+ if (!meetingId || !resolutionId) {
2694
+ if (await entityHasActiveBoard2(client, entityId)) {
2695
+ throw new Error(
2696
+ "Board approval is required before issuing this round. Pass --meeting-id and --resolution-id from a passed board vote."
2697
+ );
2698
+ }
2699
+ }
2700
+ if (!grantRequiresCurrent409a2(grantType, instrument?.kind)) {
2701
+ return;
2702
+ }
2703
+ try {
2704
+ await client.getCurrent409a(entityId);
2705
+ } catch (err) {
2706
+ const msg = String(err);
2707
+ if (msg.includes("404") || msg.includes("Not found") || msg.includes("not found")) {
2708
+ throw new Error(
2709
+ "Stock option issuances require a current approved 409A valuation. Create and approve one first with: corp cap-table create-valuation --type four_oh_nine_a --date YYYY-MM-DD --methodology <method>; corp cap-table submit-valuation <valuation-ref>; corp cap-table approve-valuation <valuation-ref> --resolution-id <resolution-ref>"
2710
+ );
2711
+ }
2712
+ throw err;
2713
+ }
2714
+ }
2715
+
2716
+ // src/workflows/issue-equity.ts
2717
+ async function issueEquity(client, args) {
2718
+ const steps = [];
2719
+ try {
2720
+ const capTable = await client.getCapTable(args.entityId);
2721
+ const issuerLegalEntityId = capTable.issuer_legal_entity_id;
2722
+ if (!issuerLegalEntityId) {
2723
+ return {
2724
+ success: false,
2725
+ error: "No issuer legal entity found. Has this entity been formed with a cap table?",
2726
+ steps
2727
+ };
2728
+ }
2729
+ const instruments = capTable.instruments ?? [];
2730
+ if (!instruments.length) {
2731
+ return {
2732
+ success: false,
2733
+ error: "No instruments found on cap table. Create one with: corp cap-table create-instrument --kind common_equity --symbol COMMON --authorized-units <shares>",
2734
+ steps
2735
+ };
2736
+ }
2737
+ const instrument = resolveInstrumentForGrant2(
2738
+ instruments,
2739
+ args.grantType,
2740
+ args.instrumentId
2741
+ );
2742
+ const instrumentId = instrument.instrument_id;
2743
+ steps.push({
2744
+ name: "resolve_instrument",
2745
+ status: "ok",
2746
+ data: {
2747
+ instrument_id: instrumentId,
2748
+ symbol: instrument.symbol,
2749
+ kind: instrument.kind
2750
+ },
2751
+ detail: `Using instrument: ${instrument.symbol} (${instrument.kind})`
2752
+ });
2753
+ await ensureIssuancePreflight2(
2754
+ client,
2755
+ args.entityId,
2756
+ args.grantType,
2757
+ instrument,
2758
+ args.meetingId,
2759
+ args.resolutionId
2760
+ );
2761
+ steps.push({ name: "preflight", status: "ok" });
2762
+ const round = await client.startEquityRound({
2763
+ entity_id: args.entityId,
2764
+ name: `${args.grantType} grant \u2014 ${args.recipientName}`,
2765
+ issuer_legal_entity_id: issuerLegalEntityId
2766
+ });
2767
+ const roundId = round.round_id ?? round.equity_round_id;
2768
+ steps.push({
2769
+ name: "start_round",
2770
+ status: "ok",
2771
+ data: { round_id: roundId }
2772
+ });
2773
+ const securityData = {
2774
+ entity_id: args.entityId,
2775
+ instrument_id: instrumentId,
2776
+ quantity: args.shares,
2777
+ recipient_name: args.recipientName,
2778
+ grant_type: args.grantType
2779
+ };
2780
+ if (args.recipientEmail) securityData.email = args.recipientEmail;
2781
+ const existingHolders = capTable.holders ?? [];
2782
+ const matchingHolder = existingHolders.find((h) => {
2783
+ const nameMatch = String(h.name ?? "").toLowerCase() === args.recipientName.toLowerCase();
2784
+ const emailMatch = args.recipientEmail && String(h.email ?? "").toLowerCase() === args.recipientEmail.toLowerCase();
2785
+ return nameMatch || emailMatch;
2786
+ });
2787
+ if (matchingHolder) {
2788
+ const holderId = matchingHolder.holder_id ?? matchingHolder.contact_id ?? matchingHolder.id;
2789
+ if (holderId) securityData.holder_id = holderId;
2790
+ }
2791
+ await client.addRoundSecurity(roundId, securityData);
2792
+ steps.push({ name: "add_security", status: "ok" });
2793
+ const issuePayload = {
2794
+ entity_id: args.entityId
2795
+ };
2796
+ if (args.meetingId) issuePayload.meeting_id = args.meetingId;
2797
+ if (args.resolutionId) issuePayload.resolution_id = args.resolutionId;
2798
+ const result = await client.issueRound(roundId, issuePayload);
2799
+ steps.push({ name: "issue_round", status: "ok" });
2800
+ return {
2801
+ success: true,
2802
+ data: {
2803
+ ...result,
2804
+ round_id: roundId,
2805
+ round,
2806
+ shares: args.shares,
2807
+ grant_type: args.grantType,
2808
+ recipient: args.recipientName
2809
+ },
2810
+ steps
2811
+ };
2812
+ } catch (err) {
2813
+ steps.push({
2814
+ name: "error",
2815
+ status: "failed",
2816
+ detail: String(err)
2817
+ });
2818
+ return {
2819
+ success: false,
2820
+ error: err instanceof Error ? err.message : String(err),
2821
+ steps
2822
+ };
2823
+ }
2824
+ }
2825
+
2826
+ // src/workflows/issue-safe.ts
2827
+ async function issueSafe(client, args) {
2828
+ const steps = [];
2829
+ const safeType = args.safeType ?? "post_money";
2830
+ try {
2831
+ await ensureIssuancePreflight2(
2832
+ client,
2833
+ args.entityId,
2834
+ safeType,
2835
+ void 0,
2836
+ args.meetingId,
2837
+ args.resolutionId
2838
+ );
2839
+ steps.push({ name: "preflight", status: "ok" });
2840
+ const body = {
2841
+ entity_id: args.entityId,
2842
+ investor_name: args.investorName,
2843
+ principal_amount_cents: args.amountCents,
2844
+ valuation_cap_cents: args.valuationCapCents,
2845
+ safe_type: safeType
2846
+ };
2847
+ if (args.email) body.email = args.email;
2848
+ if (args.meetingId) body.meeting_id = args.meetingId;
2849
+ if (args.resolutionId) body.resolution_id = args.resolutionId;
2850
+ const result = await client.createSafeNote(body);
2851
+ steps.push({ name: "create_safe", status: "ok" });
2852
+ return {
2853
+ success: true,
2854
+ data: {
2855
+ ...result,
2856
+ investor_name: args.investorName,
2857
+ amount_cents: args.amountCents,
2858
+ valuation_cap_cents: args.valuationCapCents
2859
+ },
2860
+ steps
2861
+ };
2862
+ } catch (err) {
2863
+ steps.push({
2864
+ name: "error",
2865
+ status: "failed",
2866
+ detail: String(err)
2867
+ });
2868
+ return {
2869
+ success: false,
2870
+ error: err instanceof Error ? err.message : String(err),
2871
+ steps
2872
+ };
2873
+ }
2874
+ }
2875
+
2876
+ // src/workflows/written-consent.ts
2877
+ async function writtenConsent(client, args) {
2878
+ const steps = [];
2879
+ try {
2880
+ const payload = {
2881
+ entity_id: args.entityId,
2882
+ body_id: args.bodyId,
2883
+ title: args.title,
2884
+ description: args.description
2885
+ };
2886
+ const result = await client.writtenConsent(payload);
2887
+ const meetingId = String(result.meeting_id ?? "");
2888
+ steps.push({
2889
+ name: "create_written_consent",
2890
+ status: "ok",
2891
+ data: { meeting_id: meetingId || void 0 }
2892
+ });
2893
+ if (meetingId) {
2894
+ try {
2895
+ const seats = await client.getGovernanceSeats(
2896
+ args.bodyId,
2897
+ args.entityId
2898
+ );
2899
+ const seatIds = seats.map(
2900
+ (s) => String(
2901
+ s.seat_id ?? s.id ?? ""
2902
+ )
2903
+ ).filter((id) => id.length > 0);
2904
+ if (seatIds.length > 0) {
2905
+ await client.conveneMeeting(meetingId, args.entityId, {
2906
+ present_seat_ids: seatIds
2907
+ });
2908
+ steps.push({
2909
+ name: "auto_open",
2910
+ status: "ok",
2911
+ data: { seat_count: seatIds.length },
2912
+ detail: `Opened with ${seatIds.length} seat(s) present`
2913
+ });
2914
+ } else {
2915
+ steps.push({
2916
+ name: "auto_open",
2917
+ status: "skipped",
2918
+ detail: "No seats found on body"
2919
+ });
2920
+ }
2921
+ } catch {
2922
+ steps.push({
2923
+ name: "auto_open",
2924
+ status: "skipped",
2925
+ detail: "Failed to auto-open meeting (non-fatal)"
2926
+ });
2927
+ }
2928
+ } else {
2929
+ steps.push({
2930
+ name: "auto_open",
2931
+ status: "skipped",
2932
+ detail: "No meeting_id returned"
2933
+ });
2934
+ }
2935
+ return {
2936
+ success: true,
2937
+ data: { ...result, meeting_id: meetingId || void 0 },
2938
+ steps
2939
+ };
2940
+ } catch (err) {
2941
+ steps.push({
2942
+ name: "error",
2943
+ status: "failed",
2944
+ detail: String(err)
2945
+ });
2946
+ return {
2947
+ success: false,
2948
+ error: err instanceof Error ? err.message : String(err),
2949
+ steps
2950
+ };
2951
+ }
2952
+ }
2301
2953
  export {
2302
2954
  AccountType,
2303
2955
  AgendaItemStatus,
@@ -2366,10 +3018,12 @@ export {
2366
3018
  QuorumStatus,
2367
3019
  QuorumThreshold,
2368
3020
  READ_ONLY_TOOLS,
3021
+ RESOURCE_KINDS,
2369
3022
  ReceiptStatus,
2370
3023
  ReconciliationStatus,
2371
3024
  Recurrence,
2372
3025
  ReferenceKind,
3026
+ ReferenceTracker,
2373
3027
  ResolutionType,
2374
3028
  RiskLevel,
2375
3029
  SYSTEM_PROMPT_BASE,
@@ -2396,18 +3050,45 @@ export {
2396
3050
  WorkItemActorTypeValue,
2397
3051
  WorkItemStatus,
2398
3052
  WorkflowType,
3053
+ buildInstrumentCreationHint,
3054
+ describeReferenceRecord,
2399
3055
  describeToolCall,
2400
3056
  ensureEnvFile,
3057
+ ensureIssuancePreflight2 as ensureIssuancePreflight,
2401
3058
  ensureSafeInstrument,
3059
+ entityHasActiveBoard2 as entityHasActiveBoard,
2402
3060
  executeTool,
3061
+ expectedInstrumentKinds2 as expectedInstrumentKinds,
3062
+ extractId,
2403
3063
  formatConfigSection,
2404
3064
  generateFernetKey,
2405
3065
  generateSecret,
3066
+ getReferenceAlias,
3067
+ getReferenceId,
3068
+ getReferenceLabel,
3069
+ grantRequiresCurrent409a2 as grantRequiresCurrent409a,
3070
+ isEntityScopedKind,
3071
+ isOpaqueUuid,
3072
+ isShortIdCandidate,
3073
+ isValidResourceKind,
2406
3074
  isWriteTool,
3075
+ issueEquity,
3076
+ issueSafe,
3077
+ kindLabel,
2407
3078
  loadEnvFile,
3079
+ matchRank,
3080
+ normalize,
3081
+ normalizedGrantType2 as normalizedGrantType,
3082
+ parseLastReference,
2408
3083
  processRequest,
2409
3084
  provisionWorkspace,
2410
3085
  resetCache,
2411
- resolveBinaryPath
3086
+ resolveBinaryPath,
3087
+ resolveInstrumentForGrant2 as resolveInstrumentForGrant,
3088
+ shortId,
3089
+ slugify,
3090
+ uniqueStrings,
3091
+ validateReferenceInput,
3092
+ writtenConsent
2412
3093
  };
2413
3094
  //# sourceMappingURL=index.js.map