@thecorporation/corp-tools 26.3.20 → 26.3.22

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
@@ -1,3 +1,235 @@
1
+ // src/process-transport.ts
2
+ import { execFileSync } from "child_process";
3
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
4
+ import { resolve, join } from "path";
5
+ import { homedir } from "os";
6
+ import { createRequire } from "module";
7
+
8
+ // src/env.ts
9
+ import { readFileSync, writeFileSync, existsSync } from "fs";
10
+ import { randomBytes } from "crypto";
11
+ var ENV_TEMPLATE = `# Corporation API server configuration
12
+ # Generated by: corp serve
13
+
14
+ # Required \u2014 secret for signing JWTs
15
+ JWT_SECRET={{JWT_SECRET}}
16
+
17
+ # Required \u2014 Fernet key for encrypting secrets at rest (base64url, 32 bytes)
18
+ SECRETS_MASTER_KEY={{SECRETS_MASTER_KEY}}
19
+
20
+ # Required \u2014 bearer token for internal worker-to-server auth
21
+ INTERNAL_WORKER_TOKEN={{INTERNAL_WORKER_TOKEN}}
22
+
23
+ # Server port (default: 8000)
24
+ # PORT=8000
25
+
26
+ # Data directory for git repos (default: ./data/repos)
27
+ # DATA_DIR=./data/repos
28
+
29
+ # Redis URL for agent job queue (optional)
30
+ # REDIS_URL=redis://localhost:6379/0
31
+
32
+ # LLM proxy upstream (default: https://openrouter.ai/api/v1)
33
+ # LLM_UPSTREAM_URL=https://openrouter.ai/api/v1
34
+
35
+ # PEM-encoded Ed25519 key for signing git commits (optional)
36
+ # COMMIT_SIGNING_KEY=
37
+
38
+ # Max agent queue depth (default: 1000)
39
+ # MAX_QUEUE_DEPTH=1000
40
+ `;
41
+ function generateFernetKey() {
42
+ return randomBytes(32).toString("base64url") + "=";
43
+ }
44
+ function generateSecret(length = 32) {
45
+ return randomBytes(length).toString("hex");
46
+ }
47
+ function loadEnvFile(path) {
48
+ if (!existsSync(path)) return;
49
+ const content = readFileSync(path, "utf-8");
50
+ for (const line of content.split("\n")) {
51
+ const trimmed = line.trim();
52
+ if (!trimmed || trimmed.startsWith("#")) continue;
53
+ const eqIdx = trimmed.indexOf("=");
54
+ if (eqIdx === -1) continue;
55
+ const key = trimmed.slice(0, eqIdx).trim();
56
+ const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
57
+ if (!process.env[key]) {
58
+ process.env[key] = value;
59
+ }
60
+ }
61
+ }
62
+ function ensureEnvFile(envPath) {
63
+ if (existsSync(envPath)) return;
64
+ console.log("No .env file found. Generating one with dev defaults...\n");
65
+ const content = ENV_TEMPLATE.replace("{{JWT_SECRET}}", generateSecret()).replace("{{SECRETS_MASTER_KEY}}", generateFernetKey()).replace("{{INTERNAL_WORKER_TOKEN}}", generateSecret());
66
+ writeFileSync(envPath, content, "utf-8");
67
+ console.log(` Created ${envPath}
68
+ `);
69
+ }
70
+
71
+ // src/process-transport.ts
72
+ var require2 = createRequire(import.meta.url);
73
+ var cachedBinaryPath;
74
+ function resolveBinaryPath(processUrl) {
75
+ if (cachedBinaryPath !== void 0) return cachedBinaryPath;
76
+ const parsed = new URL(processUrl);
77
+ if (parsed.pathname && parsed.pathname !== "/") {
78
+ cachedBinaryPath = parsed.pathname;
79
+ return cachedBinaryPath;
80
+ }
81
+ const envBin = process.env.CORP_SERVER_BIN;
82
+ if (envBin && existsSync2(envBin)) {
83
+ cachedBinaryPath = envBin;
84
+ return cachedBinaryPath;
85
+ }
86
+ try {
87
+ const server = require2("@thecorporation/server");
88
+ const pkgPath = server.getBinaryPath?.();
89
+ if (pkgPath) {
90
+ cachedBinaryPath = pkgPath;
91
+ return pkgPath;
92
+ }
93
+ } catch {
94
+ }
95
+ cachedBinaryPath = resolve("services/api-rs/target/release/api-rs");
96
+ return cachedBinaryPath;
97
+ }
98
+ function parseStatusFromStderr(stderr) {
99
+ const lines = stderr.split("\n");
100
+ for (let i = lines.length - 1; i >= 0; i--) {
101
+ const match = lines[i].match(/^HTTP (\d+)$/);
102
+ if (match) return parseInt(match[1], 10);
103
+ }
104
+ return null;
105
+ }
106
+ var STATUS_TEXT = {
107
+ 200: "OK",
108
+ 201: "Created",
109
+ 204: "No Content",
110
+ 400: "Bad Request",
111
+ 401: "Unauthorized",
112
+ 403: "Forbidden",
113
+ 404: "Not Found",
114
+ 409: "Conflict",
115
+ 422: "Unprocessable Entity",
116
+ 500: "Internal Server Error"
117
+ };
118
+ function buildProcessResponse(status, body) {
119
+ return {
120
+ status,
121
+ ok: status >= 200 && status < 300,
122
+ statusText: STATUS_TEXT[status] ?? String(status),
123
+ headers: new Headers({ "content-type": "application/json" }),
124
+ json: async () => JSON.parse(body),
125
+ text: async () => body,
126
+ body: null,
127
+ bodyUsed: false,
128
+ redirected: false,
129
+ type: "basic",
130
+ url: "",
131
+ clone: () => buildProcessResponse(status, body),
132
+ arrayBuffer: async () => new TextEncoder().encode(body).buffer,
133
+ blob: async () => new Blob([body]),
134
+ formData: async () => {
135
+ throw new Error("not supported");
136
+ },
137
+ bytes: async () => new TextEncoder().encode(body)
138
+ };
139
+ }
140
+ var CORP_CONFIG_DIR = process.env.CORP_CONFIG_DIR || join(homedir(), ".corp");
141
+ function readJsonFileSafe(path) {
142
+ try {
143
+ if (!existsSync2(path)) return null;
144
+ return JSON.parse(readFileSync2(path, "utf-8"));
145
+ } catch {
146
+ return null;
147
+ }
148
+ }
149
+ function loadServerSecretsFromAuth() {
150
+ const auth = readJsonFileSafe(join(CORP_CONFIG_DIR, "auth.json"));
151
+ if (!auth) return null;
152
+ const ss = auth.server_secrets;
153
+ if (!ss || typeof ss !== "object") return null;
154
+ const s = ss;
155
+ if (typeof s.jwt_secret === "string" && typeof s.secrets_master_key === "string" && typeof s.internal_worker_token === "string") {
156
+ return { jwt_secret: s.jwt_secret, secrets_master_key: s.secrets_master_key, internal_worker_token: s.internal_worker_token };
157
+ }
158
+ return null;
159
+ }
160
+ function loadDataDirFromConfig() {
161
+ const cfg = readJsonFileSafe(join(CORP_CONFIG_DIR, "config.json"));
162
+ if (!cfg) return void 0;
163
+ const dataDir = typeof cfg.data_dir === "string" ? cfg.data_dir : void 0;
164
+ return dataDir || void 0;
165
+ }
166
+ var envLoaded = false;
167
+ function ensureEnv() {
168
+ if (envLoaded) return;
169
+ const secrets = loadServerSecretsFromAuth();
170
+ if (secrets) {
171
+ if (!process.env.JWT_SECRET) process.env.JWT_SECRET = secrets.jwt_secret;
172
+ if (!process.env.SECRETS_MASTER_KEY) process.env.SECRETS_MASTER_KEY = secrets.secrets_master_key;
173
+ if (!process.env.INTERNAL_WORKER_TOKEN) process.env.INTERNAL_WORKER_TOKEN = secrets.internal_worker_token;
174
+ envLoaded = true;
175
+ return;
176
+ }
177
+ const envPath = resolve(process.cwd(), ".env");
178
+ ensureEnvFile(envPath);
179
+ loadEnvFile(envPath);
180
+ envLoaded = true;
181
+ }
182
+ function processRequest(processUrl, method, pathWithQuery, headers, body, options) {
183
+ ensureEnv();
184
+ const binPath = resolveBinaryPath(processUrl);
185
+ const args = ["--skip-validation", "call"];
186
+ const dataDir = options?.dataDir ?? loadDataDirFromConfig();
187
+ if (dataDir) {
188
+ args.push("--data-dir", dataDir);
189
+ }
190
+ args.push(method, pathWithQuery);
191
+ for (const [key, value] of Object.entries(headers)) {
192
+ args.push("-H", `${key}: ${value}`);
193
+ }
194
+ if (body) {
195
+ args.push("--stdin");
196
+ }
197
+ try {
198
+ const stdout = execFileSync(binPath, args, {
199
+ input: body ?? void 0,
200
+ stdio: ["pipe", "pipe", "pipe"],
201
+ maxBuffer: 10 * 1024 * 1024,
202
+ env: process.env
203
+ });
204
+ return buildProcessResponse(200, stdout.toString("utf-8"));
205
+ } catch (err) {
206
+ const execErr = err;
207
+ if (execErr.stdout === void 0 && execErr.stderr === void 0) {
208
+ throw new Error(
209
+ `No api-rs binary found. Install @thecorporation/server or set CORP_SERVER_BIN.
210
+ Attempted: ${binPath}
211
+ Error: ${execErr.message ?? String(err)}`
212
+ );
213
+ }
214
+ const stderr = execErr.stderr?.toString("utf-8") ?? "";
215
+ const stdout = execErr.stdout?.toString("utf-8") ?? "";
216
+ const status = parseStatusFromStderr(stderr);
217
+ if (status !== null) {
218
+ return buildProcessResponse(status, stdout);
219
+ }
220
+ const isConfigError = stderr.includes("panic") || stderr.includes("INTERNAL_WORKER_TOKEN") || stderr.includes("JWT_SECRET") || stderr.includes("SECRETS_MASTER_KEY");
221
+ if (isConfigError) {
222
+ throw new Error("Server configuration incomplete. Run 'corp setup' to configure local mode.");
223
+ }
224
+ throw new Error(`api-rs process failed:
225
+ ${stderr || stdout || String(err)}`);
226
+ }
227
+ }
228
+ function resetCache() {
229
+ cachedBinaryPath = void 0;
230
+ envLoaded = false;
231
+ }
232
+
1
233
  // src/api-client.ts
2
234
  var SessionExpiredError = class extends Error {
3
235
  constructor() {
@@ -51,7 +283,7 @@ var CorpAPIClient = class {
51
283
  apiKey;
52
284
  workspaceId;
53
285
  constructor(apiUrl, apiKey, workspaceId) {
54
- this.apiUrl = apiUrl.replace(/\/+$/, "");
286
+ this.apiUrl = apiUrl.startsWith("process://") ? apiUrl : apiUrl.replace(/\/+$/, "");
55
287
  this.apiKey = apiKey;
56
288
  this.workspaceId = workspaceId;
57
289
  }
@@ -63,11 +295,17 @@ var CorpAPIClient = class {
63
295
  };
64
296
  }
65
297
  async request(method, path, body, params) {
66
- let url = `${this.apiUrl}${path}`;
298
+ let fullPath = path;
67
299
  if (params) {
68
300
  const qs = new URLSearchParams(params).toString();
69
- if (qs) url += `?${qs}`;
301
+ if (qs) fullPath += `?${qs}`;
70
302
  }
303
+ if (this.apiUrl.startsWith("process://")) {
304
+ const hdrs = this.headers();
305
+ const bodyStr = body !== void 0 ? JSON.stringify(body) : void 0;
306
+ return processRequest(this.apiUrl, method, fullPath, hdrs, bodyStr);
307
+ }
308
+ const url = `${this.apiUrl}${fullPath}`;
71
309
  const opts = { method, headers: this.headers() };
72
310
  if (body !== void 0) opts.body = JSON.stringify(body);
73
311
  return fetch(url, opts);
@@ -295,6 +533,12 @@ var CorpAPIClient = class {
295
533
  getEntityDocuments(entityId) {
296
534
  return this.get(`/v1/formations/${pathSegment(entityId)}/documents`);
297
535
  }
536
+ getDocument(documentId, entityId) {
537
+ return this.get(`/v1/documents/${pathSegment(documentId)}`, { entity_id: entityId });
538
+ }
539
+ signDocument(documentId, entityId, data) {
540
+ return this.postWithParams(`/v1/documents/${pathSegment(documentId)}/sign`, data, { entity_id: entityId });
541
+ }
298
542
  generateContract(data) {
299
543
  return this.post("/v1/contracts", data);
300
544
  }
@@ -307,6 +551,9 @@ var CorpAPIClient = class {
307
551
  return { entity_id: entityId, document_id: documentId };
308
552
  }
309
553
  getPreviewPdfUrl(entityId, documentId) {
554
+ if (this.apiUrl.startsWith("process://")) {
555
+ throw new Error("getPreviewPdfUrl is not available in process transport mode \u2014 use validatePreviewPdf() and fetch the PDF via the API instead");
556
+ }
310
557
  const qs = new URLSearchParams({ entity_id: entityId, document_id: documentId }).toString();
311
558
  return `${this.apiUrl}/v1/documents/preview/pdf?${qs}`;
312
559
  }
@@ -405,6 +652,30 @@ var CorpAPIClient = class {
405
652
  finalizeFormation(entityId, data = {}) {
406
653
  return this.post(`/v1/formations/${pathSegment(entityId)}/finalize`, data);
407
654
  }
655
+ markFormationDocumentsSigned(entityId) {
656
+ return this.post(`/v1/formations/${pathSegment(entityId)}/mark-documents-signed`);
657
+ }
658
+ getFormationGates(entityId) {
659
+ return this.get(`/v1/formations/${pathSegment(entityId)}/gates`);
660
+ }
661
+ recordFilingAttestation(entityId, data) {
662
+ return this.post(`/v1/formations/${pathSegment(entityId)}/filing-attestation`, data);
663
+ }
664
+ addRegisteredAgentConsentEvidence(entityId, data) {
665
+ return this.post(`/v1/formations/${pathSegment(entityId)}/registered-agent-consent-evidence`, data);
666
+ }
667
+ submitFiling(entityId) {
668
+ return this.post(`/v1/formations/${pathSegment(entityId)}/submit-filing`);
669
+ }
670
+ confirmFiling(entityId, data) {
671
+ return this.post(`/v1/formations/${pathSegment(entityId)}/filing-confirmation`, data);
672
+ }
673
+ applyEin(entityId) {
674
+ return this.post(`/v1/formations/${pathSegment(entityId)}/apply-ein`);
675
+ }
676
+ confirmEin(entityId, data) {
677
+ return this.post(`/v1/formations/${pathSegment(entityId)}/ein-confirmation`, data);
678
+ }
408
679
  // --- Human obligations ---
409
680
  getHumanObligations() {
410
681
  return this.get(`/v1/workspaces/${pathSegment(this.workspaceId)}/human-obligations`);
@@ -413,8 +684,8 @@ var CorpAPIClient = class {
413
684
  return this.post(`/v1/human-obligations/${pathSegment(obligationId)}/signer-token`);
414
685
  }
415
686
  // --- Demo ---
416
- seedDemo(name) {
417
- return this.post("/v1/demo/seed", { name, workspace_id: this.workspaceId });
687
+ seedDemo(data) {
688
+ return this.post("/v1/demo/seed", data);
418
689
  }
419
690
  // --- Entities writes ---
420
691
  convertEntity(entityId, data) {
@@ -494,6 +765,28 @@ var CorpAPIClient = class {
494
765
  getConfig() {
495
766
  return this.get("/v1/config");
496
767
  }
768
+ // --- Services ---
769
+ listServiceCatalog() {
770
+ return this.get("/v1/services/catalog");
771
+ }
772
+ createServiceRequest(data) {
773
+ return this.post("/v1/services/requests", data);
774
+ }
775
+ getServiceRequest(id, entityId) {
776
+ return this.get(`/v1/services/requests/${pathSegment(id)}`, { entity_id: entityId });
777
+ }
778
+ listServiceRequests(entityId) {
779
+ return this.get(`/v1/entities/${pathSegment(entityId)}/service-requests`);
780
+ }
781
+ beginServiceCheckout(id, data) {
782
+ return this.post(`/v1/services/requests/${pathSegment(id)}/checkout`, data);
783
+ }
784
+ fulfillServiceRequest(id, data) {
785
+ return this.post(`/v1/services/requests/${pathSegment(id)}/fulfill`, data);
786
+ }
787
+ cancelServiceRequest(id, data) {
788
+ return this.post(`/v1/services/requests/${pathSegment(id)}/cancel`, data);
789
+ }
497
790
  // --- Feedback ---
498
791
  submitFeedback(message, category, email) {
499
792
  return this.post("/v1/feedback", { message, category, email });
@@ -510,8 +803,8 @@ var CorpAPIClient = class {
510
803
  };
511
804
 
512
805
  // src/tools.ts
513
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
514
- import { join } from "path";
806
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, existsSync as existsSync3 } from "fs";
807
+ import { join as join2 } from "path";
515
808
 
516
809
  // src/tool-defs.generated.ts
517
810
  var GENERATED_TOOL_DEFINITIONS = [
@@ -1442,14 +1735,14 @@ var documentActions = {
1442
1735
  };
1443
1736
  var checklistActions = {
1444
1737
  get: async (_args, _client, ctx) => {
1445
- const path = join(ctx.dataDir, "checklist.md");
1446
- if (existsSync(path)) return { checklist: readFileSync(path, "utf-8") };
1738
+ const path = join2(ctx.dataDir, "checklist.md");
1739
+ if (existsSync3(path)) return { checklist: readFileSync3(path, "utf-8") };
1447
1740
  return { checklist: null, message: "No checklist yet." };
1448
1741
  },
1449
1742
  update: async (args, _client, ctx) => {
1450
- const path = join(ctx.dataDir, "checklist.md");
1743
+ const path = join2(ctx.dataDir, "checklist.md");
1451
1744
  mkdirSync(ctx.dataDir, { recursive: true });
1452
- writeFileSync(path, args.checklist);
1745
+ writeFileSync2(path, args.checklist);
1453
1746
  return { status: "updated", checklist: args.checklist };
1454
1747
  }
1455
1748
  };
@@ -1921,8 +2214,11 @@ var QuorumThreshold = ["majority", "supermajority", "unanimous"];
1921
2214
  var ReceiptStatus = ["pending", "executed", "failed"];
1922
2215
  var ReconciliationStatus = ["balanced", "discrepancy"];
1923
2216
  var Recurrence = ["one_time", "monthly", "quarterly", "annual"];
2217
+ var ReferenceKind = ["entity", "contact", "share_transfer", "invoice", "bank_account", "payment", "payroll_run", "distribution", "reconciliation", "tax_filing", "deadline", "classification", "body", "meeting", "seat", "agenda_item", "resolution", "document", "work_item", "agent", "valuation", "safe_note", "instrument", "share_class", "round"];
1924
2218
  var ResolutionType = ["ordinary", "special", "unanimous_written_consent"];
1925
2219
  var RiskLevel = ["low", "medium", "high"];
2220
+ var SafeStatus = ["issued", "converted", "cancelled"];
2221
+ var SafeType = ["post_money", "pre_money", "mfn"];
1926
2222
  var Scope = ["formation_create", "formation_read", "formation_sign", "equity_read", "equity_write", "equity_transfer", "governance_read", "governance_write", "governance_vote", "treasury_read", "treasury_write", "treasury_approve", "contacts_read", "contacts_write", "execution_read", "execution_write", "branch_create", "branch_merge", "branch_delete", "admin", "internal_worker_read", "internal_worker_write", "secrets_manage", "all"];
1927
2223
  var SeatRole = ["chair", "member", "officer", "observer"];
1928
2224
  var SeatStatus = ["active", "resigned", "expired"];
@@ -1938,6 +2234,7 @@ var ValuationStatus = ["draft", "pending_approval", "approved", "expired", "supe
1938
2234
  var ValuationType = ["four_oh_nine_a", "llc_profits_interest", "fair_market_value", "gift", "estate", "other"];
1939
2235
  var VoteValue = ["for", "against", "abstain", "recusal"];
1940
2236
  var VotingMethod = ["per_capita", "per_unit"];
2237
+ var WorkItemActorTypeValue = ["contact", "agent"];
1941
2238
  var WorkItemStatus = ["open", "claimed", "completed", "cancelled"];
1942
2239
  var WorkflowType = ["transfer", "fundraising"];
1943
2240
  export {
@@ -2011,9 +2308,12 @@ export {
2011
2308
  ReceiptStatus,
2012
2309
  ReconciliationStatus,
2013
2310
  Recurrence,
2311
+ ReferenceKind,
2014
2312
  ResolutionType,
2015
2313
  RiskLevel,
2016
2314
  SYSTEM_PROMPT_BASE,
2315
+ SafeStatus,
2316
+ SafeType,
2017
2317
  Scope,
2018
2318
  SeatRole,
2019
2319
  SeatStatus,
@@ -2032,13 +2332,21 @@ export {
2032
2332
  ValuationType,
2033
2333
  VoteValue,
2034
2334
  VotingMethod,
2335
+ WorkItemActorTypeValue,
2035
2336
  WorkItemStatus,
2036
2337
  WorkflowType,
2037
2338
  describeToolCall,
2339
+ ensureEnvFile,
2038
2340
  ensureSafeInstrument,
2039
2341
  executeTool,
2040
2342
  formatConfigSection,
2343
+ generateFernetKey,
2344
+ generateSecret,
2041
2345
  isWriteTool,
2042
- provisionWorkspace
2346
+ loadEnvFile,
2347
+ processRequest,
2348
+ provisionWorkspace,
2349
+ resetCache,
2350
+ resolveBinaryPath
2043
2351
  };
2044
2352
  //# sourceMappingURL=index.js.map