@thecorporation/corp-tools 26.3.24 → 26.3.32

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