@datagrout/conduit 0.4.0 → 0.6.0

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
@@ -101,7 +101,9 @@ var init_oauth = __esm({
101
101
  }
102
102
  if (!response.ok) {
103
103
  const text = await response.text().catch(() => "");
104
- throw new Error(`OAuth token endpoint returned ${response.status}: ${text}`);
104
+ throw new Error(
105
+ `OAuth token endpoint returned ${response.status}: ${text}`
106
+ );
105
107
  }
106
108
  const data = await response.json();
107
109
  const expiresIn = data.expires_in ?? 3600;
@@ -136,7 +138,9 @@ async function fetchWithIdentity(url, init, identity) {
136
138
  port: parsedUrl.port || 443,
137
139
  path: parsedUrl.pathname + parsedUrl.search,
138
140
  method: (init.method ?? "GET").toUpperCase(),
139
- headers: flattenHeaders(init.headers),
141
+ headers: flattenHeaders(
142
+ init.headers
143
+ ),
140
144
  cert: identity.certPem,
141
145
  key: identity.keyPem,
142
146
  ...identity.caPem ? { ca: identity.caPem } : {}
@@ -220,7 +224,9 @@ var init_identity = __esm({
220
224
  */
221
225
  static fromPaths(certPath, keyPath, caPath) {
222
226
  if (typeof process === "undefined" || !process.versions?.node) {
223
- throw new Error("ConduitIdentity.fromPaths() is only available in Node.js environments");
227
+ throw new Error(
228
+ "ConduitIdentity.fromPaths() is only available in Node.js environments"
229
+ );
224
230
  }
225
231
  const fs2 = require("fs");
226
232
  const certPem = fs2.readFileSync(certPath, "utf8");
@@ -244,7 +250,9 @@ var init_identity = __esm({
244
250
  if (!certPem) return null;
245
251
  const keyPem = process.env.CONDUIT_MTLS_KEY;
246
252
  if (!keyPem) {
247
- throw new Error("CONDUIT_MTLS_CERT is set but CONDUIT_MTLS_KEY is missing");
253
+ throw new Error(
254
+ "CONDUIT_MTLS_CERT is set but CONDUIT_MTLS_KEY is missing"
255
+ );
248
256
  }
249
257
  const caPem = process.env.CONDUIT_MTLS_CA || void 0;
250
258
  return _ConduitIdentity.fromPem(certPem, keyPem, caPem);
@@ -334,7 +342,11 @@ var init_identity = __esm({
334
342
  const keyPath = `${dir}/identity_key.pem`;
335
343
  if (!fs2.existsSync(certPath) || !fs2.existsSync(keyPath)) return null;
336
344
  const caPath = `${dir}/ca.pem`;
337
- return _ConduitIdentity.fromPaths(certPath, keyPath, fs2.existsSync(caPath) ? caPath : void 0);
345
+ return _ConduitIdentity.fromPaths(
346
+ certPath,
347
+ keyPath,
348
+ fs2.existsSync(caPath) ? caPath : void 0
349
+ );
338
350
  } catch {
339
351
  return null;
340
352
  }
@@ -343,6 +355,83 @@ var init_identity = __esm({
343
355
  }
344
356
  });
345
357
 
358
+ // src/onramp.ts
359
+ var onramp_exports = {};
360
+ __export(onramp_exports, {
361
+ _doRegister: () => _doRegister,
362
+ _exchangeToken: () => _exchangeToken,
363
+ registerAndExchange: () => registerAndExchange,
364
+ registerOnly: () => registerOnly
365
+ });
366
+ async function _doRegister(opts) {
367
+ const base = opts.gateway.replace(/\/$/, "");
368
+ const body = { agent_name: opts.agentName };
369
+ if (opts.agentType) body["agent_type"] = opts.agentType;
370
+ if (opts.intendedUse) body["intended_use"] = opts.intendedUse;
371
+ if (opts.accessCode) body["access_code"] = opts.accessCode;
372
+ const initResp = await fetch(`${base}/onramp`, {
373
+ method: "POST",
374
+ headers: { "Content-Type": "application/json" },
375
+ body: JSON.stringify(body)
376
+ });
377
+ if (!initResp.ok) {
378
+ const text = await initResp.text();
379
+ throw new Error(`onramp init rejected (HTTP ${initResp.status}): ${text}`);
380
+ }
381
+ const initData = await initResp.json();
382
+ const sessionToken = initData.session_token;
383
+ const completeResp = await fetch(`${base}/onramp/complete`, {
384
+ method: "POST",
385
+ headers: { Authorization: `Bearer ${sessionToken}` }
386
+ });
387
+ if (!completeResp.ok) {
388
+ const text = await completeResp.text();
389
+ throw new Error(
390
+ `onramp complete rejected (HTTP ${completeResp.status}): ${text}`
391
+ );
392
+ }
393
+ const data = await completeResp.json();
394
+ return {
395
+ clientId: data["client_id"],
396
+ clientSecret: data["client_secret"],
397
+ tokenUrl: data["token_url"],
398
+ scopes: data["scopes"] ?? [],
399
+ expiresIn: data["expires_in"] ?? 0,
400
+ rpcUrl: data["rpc_url"],
401
+ mcpUrl: data["mcp_url"]
402
+ };
403
+ }
404
+ async function _exchangeToken(creds) {
405
+ const body = new URLSearchParams({
406
+ grant_type: "client_credentials",
407
+ client_id: creds.clientId,
408
+ client_secret: creds.clientSecret
409
+ });
410
+ const resp = await fetch(creds.tokenUrl, {
411
+ method: "POST",
412
+ body
413
+ });
414
+ if (!resp.ok) {
415
+ const text = await resp.text();
416
+ throw new Error(`token exchange failed (HTTP ${resp.status}): ${text}`);
417
+ }
418
+ const data = await resp.json();
419
+ return data.access_token;
420
+ }
421
+ async function registerOnly(opts) {
422
+ return _doRegister(opts);
423
+ }
424
+ async function registerAndExchange(opts) {
425
+ const creds = await _doRegister(opts);
426
+ const token = await _exchangeToken(creds);
427
+ return [creds, token];
428
+ }
429
+ var init_onramp = __esm({
430
+ "src/onramp.ts"() {
431
+ "use strict";
432
+ }
433
+ });
434
+
346
435
  // src/index.ts
347
436
  var index_exports = {};
348
437
  __export(index_exports, {
@@ -369,7 +458,9 @@ __export(index_exports, {
369
458
  generateKeypair: () => generateKeypair,
370
459
  isDgUrl: () => isDgUrl,
371
460
  refreshCaCert: () => refreshCaCert,
461
+ registerAndExchange: () => registerAndExchange,
372
462
  registerIdentity: () => registerIdentity,
463
+ registerOnly: () => registerOnly,
373
464
  rotateIdentity: () => rotateIdentity,
374
465
  saveIdentity: () => saveIdentity,
375
466
  version: () => version
@@ -488,6 +579,9 @@ var MCPTransport = class extends Transport {
488
579
  throw new Error("Not connected. Call connect() first.");
489
580
  }
490
581
  const result = await this.client.callTool({ name, arguments: args });
582
+ if (result?.structuredContent !== void 0) {
583
+ return result.structuredContent;
584
+ }
491
585
  const content = result?.content;
492
586
  if (Array.isArray(content) && content.length > 0) {
493
587
  const first = content[0];
@@ -498,6 +592,7 @@ var MCPTransport = class extends Transport {
498
592
  return { text: first.text };
499
593
  }
500
594
  }
595
+ return first;
501
596
  }
502
597
  return result;
503
598
  }
@@ -594,7 +689,11 @@ var InvalidConfigError = class extends ConduitError {
594
689
 
595
690
  // src/transports/jsonrpc.ts
596
691
  function unwrapContent(result) {
597
- if (result && Array.isArray(result.content) && result.content.length > 0) {
692
+ if (!result) return result;
693
+ if (result.structuredContent !== void 0) {
694
+ return result.structuredContent;
695
+ }
696
+ if (Array.isArray(result.content) && result.content.length > 0) {
598
697
  const first = result.content[0];
599
698
  if (first && typeof first.text === "string") {
600
699
  try {
@@ -603,6 +702,7 @@ function unwrapContent(result) {
603
702
  return { text: first.text };
604
703
  }
605
704
  }
705
+ return first;
606
706
  }
607
707
  return result;
608
708
  }
@@ -629,7 +729,9 @@ var JSONRPCTransport = class extends Transport {
629
729
  this.identity = identity;
630
730
  this.timeout = timeout;
631
731
  if (identity?.needsRotation(30)) {
632
- console.warn("[conduit] mTLS certificate expires within 30 days \u2014 consider rotating");
732
+ console.warn(
733
+ "[conduit] mTLS certificate expires within 30 days \u2014 consider rotating"
734
+ );
633
735
  }
634
736
  if (auth?.clientCredentials) {
635
737
  const cc = auth.clientCredentials;
@@ -662,7 +764,9 @@ var JSONRPCTransport = class extends Transport {
662
764
  } else if (this.auth?.bearer) {
663
765
  headers["Authorization"] = `Bearer ${this.auth.bearer}`;
664
766
  } else if (this.auth?.basic) {
665
- const credentials = btoa(`${this.auth.basic.username}:${this.auth.basic.password}`);
767
+ const credentials = btoa(
768
+ `${this.auth.basic.username}:${this.auth.basic.password}`
769
+ );
666
770
  headers["Authorization"] = `Basic ${credentials}`;
667
771
  } else if (this.auth?.custom) {
668
772
  Object.assign(headers, this.auth.custom);
@@ -801,7 +905,9 @@ var WsTransport = class extends Transport {
801
905
  super();
802
906
  const scheme = new URL(url).protocol.replace(":", "");
803
907
  if (scheme !== "ws" && scheme !== "wss") {
804
- throw new Error(`WS transport requires a ws:// or wss:// URL, got ${scheme}://`);
908
+ throw new Error(
909
+ `WS transport requires a ws:// or wss:// URL, got ${scheme}://`
910
+ );
805
911
  }
806
912
  this._url = url;
807
913
  this._auth = auth;
@@ -816,7 +922,9 @@ var WsTransport = class extends Transport {
816
922
  });
817
923
  await new Promise((resolve, reject) => {
818
924
  ws.onopen = () => resolve();
819
- ws.onerror = (ev) => reject(new Error(`WS connect failed: ${ev.message ?? "unknown"}`));
925
+ ws.onerror = (ev) => reject(
926
+ new Error(`WS connect failed: ${ev.message ?? "unknown"}`)
927
+ );
820
928
  });
821
929
  ws.onmessage = (ev) => this._handleMessage(ev.data);
822
930
  ws.onerror = (_ev) => this._failAll("WS connection error");
@@ -850,7 +958,12 @@ var WsTransport = class extends Transport {
850
958
  const id = this._mintId();
851
959
  return new Promise((resolve, reject) => {
852
960
  this._pendingSubscribe.set(id, { topic, resolve, reject });
853
- this._send({ jsonrpc: "2.0", id, method: "subscribe", params: { topic } });
961
+ this._send({
962
+ jsonrpc: "2.0",
963
+ id,
964
+ method: "subscribe",
965
+ params: { topic }
966
+ });
854
967
  });
855
968
  }
856
969
  /**
@@ -920,7 +1033,12 @@ var WsTransport = class extends Transport {
920
1033
  const id = this._mintId();
921
1034
  return new Promise((resolve, reject) => {
922
1035
  this._pending.set(id, { resolve, reject });
923
- this._send({ jsonrpc: "2.0", id, method, ...params !== void 0 ? { params } : {} });
1036
+ this._send({
1037
+ jsonrpc: "2.0",
1038
+ id,
1039
+ method,
1040
+ ...params !== void 0 ? { params } : {}
1041
+ });
924
1042
  });
925
1043
  }
926
1044
  _handleMessage(data) {
@@ -932,7 +1050,9 @@ var WsTransport = class extends Transport {
932
1050
  }
933
1051
  if (!("id" in msg)) {
934
1052
  if (msg["method"] === "notification") {
935
- this._routeNotification(msg["params"]);
1053
+ this._routeNotification(
1054
+ msg["params"]
1055
+ );
936
1056
  }
937
1057
  return;
938
1058
  }
@@ -942,7 +1062,9 @@ var WsTransport = class extends Transport {
942
1062
  this._pendingSubscribe.delete(msgId);
943
1063
  const err = msg["error"];
944
1064
  if (err !== void 0) {
945
- pendingSub.reject(new Error(String(err["message"] ?? "Subscribe failed")));
1065
+ pendingSub.reject(
1066
+ new Error(String(err["message"] ?? "Subscribe failed"))
1067
+ );
946
1068
  return;
947
1069
  }
948
1070
  const result = msg["result"] ?? {};
@@ -999,7 +1121,9 @@ function buildUpgradeHeaders(auth) {
999
1121
  } else if ("apiKey" in auth && auth.apiKey !== void 0) {
1000
1122
  headers["X-API-Key"] = auth.apiKey;
1001
1123
  } else if ("basic" in auth && auth.basic !== void 0) {
1002
- const encoded = Buffer.from(`${auth.basic.username}:${auth.basic.password}`).toString("base64");
1124
+ const encoded = Buffer.from(
1125
+ `${auth.basic.username}:${auth.basic.password}`
1126
+ ).toString("base64");
1003
1127
  headers["Authorization"] = `Basic ${encoded}`;
1004
1128
  }
1005
1129
  return headers;
@@ -1038,7 +1162,9 @@ async function fetchDgCaCert(url = DG_CA_URL) {
1038
1162
  }
1039
1163
  const pem = await resp.text();
1040
1164
  if (!pem.includes("-----BEGIN CERTIFICATE-----")) {
1041
- throw new Error(`Response from ${url} does not look like a PEM certificate`);
1165
+ throw new Error(
1166
+ `Response from ${url} does not look like a PEM certificate`
1167
+ );
1042
1168
  }
1043
1169
  return pem;
1044
1170
  }
@@ -1054,7 +1180,10 @@ function generateKeypair() {
1054
1180
  namedCurve: "P-256"
1055
1181
  });
1056
1182
  return {
1057
- privateKeyPem: privateKey.export({ type: "pkcs8", format: "pem" }),
1183
+ privateKeyPem: privateKey.export({
1184
+ type: "pkcs8",
1185
+ format: "pem"
1186
+ }),
1058
1187
  publicKeyPem: publicKey.export({ type: "spki", format: "pem" })
1059
1188
  };
1060
1189
  }
@@ -1094,9 +1223,17 @@ async function registerIdentity(keypair, opts) {
1094
1223
  };
1095
1224
  }
1096
1225
  async function rotateIdentity(opts) {
1097
- const { privateKey, publicKey } = crypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
1098
- const publicKeyPem = publicKey.export({ type: "spki", format: "pem" });
1099
- const privateKeyPem = privateKey.export({ type: "pkcs8", format: "pem" });
1226
+ const { privateKey, publicKey } = crypto.generateKeyPairSync("ec", {
1227
+ namedCurve: "P-256"
1228
+ });
1229
+ const publicKeyPem = publicKey.export({
1230
+ type: "spki",
1231
+ format: "pem"
1232
+ });
1233
+ const privateKeyPem = privateKey.export({
1234
+ type: "pkcs8",
1235
+ format: "pem"
1236
+ });
1100
1237
  const url = opts.endpoint.replace(/\/$/, "") + "/rotate";
1101
1238
  const https = await import("https");
1102
1239
  const urlModule = await import("url");
@@ -1111,7 +1248,10 @@ async function rotateIdentity(opts) {
1111
1248
  cert: opts.currentCertPem,
1112
1249
  key: opts.currentKeyPem
1113
1250
  };
1114
- const body = JSON.stringify({ public_key_pem: publicKeyPem, name: opts.name });
1251
+ const body = JSON.stringify({
1252
+ public_key_pem: publicKeyPem,
1253
+ name: opts.name
1254
+ });
1115
1255
  const req = https.request(reqOptions, (res) => {
1116
1256
  let data = "";
1117
1257
  res.on("data", (chunk) => {
@@ -1121,7 +1261,9 @@ async function rotateIdentity(opts) {
1121
1261
  if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
1122
1262
  resolve(data);
1123
1263
  } else {
1124
- reject(new Error(`Rotation failed (HTTP ${res.statusCode}): ${data}`));
1264
+ reject(
1265
+ new Error(`Rotation failed (HTTP ${res.statusCode}): ${data}`)
1266
+ );
1125
1267
  }
1126
1268
  });
1127
1269
  });
@@ -1221,8 +1363,12 @@ var PrismNamespace = class {
1221
1363
  data: options.data,
1222
1364
  source_type: options.sourceType,
1223
1365
  target_type: options.targetType,
1224
- ...options.sourceAnnotations && { source_annotations: options.sourceAnnotations },
1225
- ...options.targetAnnotations && { target_annotations: options.targetAnnotations },
1366
+ ...options.sourceAnnotations && {
1367
+ source_annotations: options.sourceAnnotations
1368
+ },
1369
+ ...options.targetAnnotations && {
1370
+ target_annotations: options.targetAnnotations
1371
+ },
1226
1372
  ...options.context && { context: options.context }
1227
1373
  };
1228
1374
  return this.callDg("prism.focus", params);
@@ -1247,7 +1393,9 @@ var LogicNamespace = class {
1247
1393
  statement = opts.statement;
1248
1394
  }
1249
1395
  if (!statement && !opts?.facts?.length) {
1250
- throw new InvalidConfigError("remember() requires either a statement or facts");
1396
+ throw new InvalidConfigError(
1397
+ "remember() requires either a statement or facts"
1398
+ );
1251
1399
  }
1252
1400
  const params = { tag: opts?.tag ?? "default" };
1253
1401
  if (opts?.facts) {
@@ -1268,7 +1416,9 @@ var LogicNamespace = class {
1268
1416
  question = opts.question;
1269
1417
  }
1270
1418
  if (!question && !opts?.patterns?.length) {
1271
- throw new InvalidConfigError("query() requires either a question or patterns");
1419
+ throw new InvalidConfigError(
1420
+ "query() requires either a question or patterns"
1421
+ );
1272
1422
  }
1273
1423
  const params = { limit: opts?.limit ?? 50 };
1274
1424
  if (opts?.patterns) {
@@ -1281,7 +1431,9 @@ var LogicNamespace = class {
1281
1431
  /** Retract facts from the logic cell (`data-grout/logic.forget`). */
1282
1432
  async forget(options) {
1283
1433
  if (!options.handles?.length && !options.pattern) {
1284
- throw new InvalidConfigError("forget() requires either handles or pattern");
1434
+ throw new InvalidConfigError(
1435
+ "forget() requires either handles or pattern"
1436
+ );
1285
1437
  }
1286
1438
  const params = {};
1287
1439
  if (options.handles) params.handles = options.handles;
@@ -1290,13 +1442,18 @@ var LogicNamespace = class {
1290
1442
  }
1291
1443
  /** Reflect on the logic cell (`data-grout/logic.reflect`). */
1292
1444
  async reflect(options) {
1293
- const params = { summary_only: options?.summaryOnly ?? false };
1445
+ const params = {
1446
+ summary_only: options?.summaryOnly ?? false
1447
+ };
1294
1448
  if (options?.entity) params.entity = options.entity;
1295
1449
  return this.callDg("logic.reflect", params);
1296
1450
  }
1297
1451
  /** Add a constraint rule (`data-grout/logic.constrain`). */
1298
1452
  async constrain(rule, options) {
1299
- const params = { rule, tag: options?.tag ?? "constraint" };
1453
+ const params = {
1454
+ rule,
1455
+ tag: options?.tag ?? "constraint"
1456
+ };
1300
1457
  return this.callDg("logic.constrain", params);
1301
1458
  }
1302
1459
  /** Hydrate the logic cell from external data (`data-grout/logic.hydrate`). */
@@ -1458,7 +1615,9 @@ var FlowNamespace = class {
1458
1615
  /** Get details for a specific execution (`data-grout/inspect.execution-details`). */
1459
1616
  async details(executionId) {
1460
1617
  this.warn("inspect.execution-details");
1461
- return this.callDg("inspect.execution-details", { execution_id: executionId });
1618
+ return this.callDg("inspect.execution-details", {
1619
+ execution_id: executionId
1620
+ });
1462
1621
  }
1463
1622
  };
1464
1623
 
@@ -1538,10 +1697,7 @@ var Client2 = class _Client {
1538
1697
  this.isDg = isDgUrl(this.url);
1539
1698
  this.useIntelligentInterface = options.useIntelligentInterface ?? this.isDg;
1540
1699
  this.maxRetries = options.maxRetries ?? 3;
1541
- let identity = options.identity ?? (options.identityAuto ? ConduitIdentity.tryDiscover(options.identityDir) ?? void 0 : void 0);
1542
- if (identity === void 0 && this.isDg && !options.disableMtls) {
1543
- identity = ConduitIdentity.tryDiscover(options.identityDir) ?? void 0;
1544
- }
1700
+ const identity = options.identity ?? (options.identityAuto ? ConduitIdentity.tryDiscover(options.identityDir) ?? void 0 : void 0);
1545
1701
  const transportType = options.transport || "mcp";
1546
1702
  if (transportType === "mcp") {
1547
1703
  this.transport = new MCPTransport(this.url, this.auth, identity);
@@ -1549,10 +1705,20 @@ var Client2 = class _Client {
1549
1705
  let wsUrl = this.url;
1550
1706
  if (wsUrl.startsWith("https://")) wsUrl = "wss://" + wsUrl.slice(8);
1551
1707
  else if (wsUrl.startsWith("http://")) wsUrl = "ws://" + wsUrl.slice(7);
1552
- this.transport = new WsTransport(wsUrl, this.auth, options.timeout, identity);
1708
+ this.transport = new WsTransport(
1709
+ wsUrl,
1710
+ this.auth,
1711
+ options.timeout,
1712
+ identity
1713
+ );
1553
1714
  } else {
1554
1715
  const rpcUrl = this.url.endsWith("/mcp") ? this.url.slice(0, -4) + "/rpc" : this.url;
1555
- this.transport = new JSONRPCTransport(rpcUrl, this.auth, options.timeout, identity);
1716
+ this.transport = new JSONRPCTransport(
1717
+ rpcUrl,
1718
+ this.auth,
1719
+ options.timeout,
1720
+ identity
1721
+ );
1556
1722
  }
1557
1723
  }
1558
1724
  // ===== Bootstrap / seamless mTLS =====
@@ -1626,6 +1792,66 @@ var Client2 = class _Client {
1626
1792
  substrateEndpoint: options.substrateEndpoint
1627
1793
  });
1628
1794
  }
1795
+ /**
1796
+ * Register autonomously with DG and bootstrap an mTLS identity.
1797
+ *
1798
+ * The all-in-one flow: onramp (no prior credentials required) →
1799
+ * OAuth token exchange → mTLS identity registration and persistence.
1800
+ *
1801
+ * On subsequent runs the saved mTLS identity is auto-discovered and
1802
+ * no credentials are needed.
1803
+ *
1804
+ * @param options.opts - Onramp registration options.
1805
+ * @param options.url - MCP server URL. Required if the onramp
1806
+ * response does not include `mcpUrl`.
1807
+ * @param options.identityDir - Custom identity storage directory.
1808
+ *
1809
+ * @example
1810
+ * ```ts
1811
+ * import { Client } from './client';
1812
+ * import type { OnrampOptions } from './onramp';
1813
+ *
1814
+ * const client = await Client.bootstrapOnramp({
1815
+ * opts: {
1816
+ * gateway: 'https://app.datagrout.ai',
1817
+ * agentName: 'my-research-agent',
1818
+ * agentType: 'claude-sonnet-4-6',
1819
+ * },
1820
+ * });
1821
+ * await client.connect();
1822
+ * ```
1823
+ */
1824
+ static async bootstrapOnramp(options) {
1825
+ const { _doRegister: _doRegister2, _exchangeToken: _exchangeToken2 } = await Promise.resolve().then(() => (init_onramp(), onramp_exports));
1826
+ const dir = options.identityDir || DEFAULT_IDENTITY_DIR;
1827
+ const existing = ConduitIdentity.tryDiscover(dir);
1828
+ if (existing && !existing.needsRotation(7)) {
1829
+ if (!options.url) {
1830
+ throw new Error(
1831
+ "'url' must be provided when an existing identity is reused"
1832
+ );
1833
+ }
1834
+ return new _Client({
1835
+ url: options.url,
1836
+ identity: existing,
1837
+ identityDir: dir
1838
+ });
1839
+ }
1840
+ const creds = await _doRegister2(options.opts);
1841
+ const token = await _exchangeToken2(creds);
1842
+ const url = creds.mcpUrl ?? options.url;
1843
+ if (!url) {
1844
+ throw new Error(
1845
+ "'url' must be provided when mcpUrl is absent from the onramp response"
1846
+ );
1847
+ }
1848
+ return _Client.bootstrapIdentity({
1849
+ url,
1850
+ authToken: token,
1851
+ name: options.opts.agentName,
1852
+ identityDir: options.identityDir
1853
+ });
1854
+ }
1629
1855
  // ===== Lifecycle =====
1630
1856
  /**
1631
1857
  * Establish the underlying transport connection.
@@ -1677,7 +1903,9 @@ var Client2 = class _Client {
1677
1903
  // ===== Namespace Accessors =====
1678
1904
  callDgTool = async (tool, params) => {
1679
1905
  this.ensureInitialized();
1680
- return this.sendWithRetry(() => this.transport.callTool(`data-grout/${tool}`, params));
1906
+ return this.sendWithRetry(
1907
+ () => this.transport.callTool(`data-grout/${tool}`, params)
1908
+ );
1681
1909
  };
1682
1910
  /** Data transformation, charting, rendering, and type bridging. */
1683
1911
  get prism() {
@@ -1693,7 +1921,10 @@ var Client2 = class _Client {
1693
1921
  }
1694
1922
  /** Work product registration, listing, and retrieval. */
1695
1923
  get deliverables() {
1696
- return new DeliverablesNamespace(this.callDgTool, (m) => this.warnIfNotDg(m));
1924
+ return new DeliverablesNamespace(
1925
+ this.callDgTool,
1926
+ (m) => this.warnIfNotDg(m)
1927
+ );
1697
1928
  }
1698
1929
  /** Cache listing and inspection. */
1699
1930
  get ephemerals() {
@@ -1782,7 +2013,9 @@ var Client2 = class _Client {
1782
2013
  */
1783
2014
  async getPrompt(name, args, options) {
1784
2015
  this.ensureInitialized();
1785
- return this.sendWithRetry(() => this.transport.getPrompt(name, args, options));
2016
+ return this.sendWithRetry(
2017
+ () => this.transport.getPrompt(name, args, options)
2018
+ );
1786
2019
  }
1787
2020
  // ===== WebSocket push subscriptions =====
1788
2021
  /**
@@ -1883,7 +2116,7 @@ var Client2 = class _Client {
1883
2116
  outputSchema: r.output_contract || r.output_schema || r.outputSchema
1884
2117
  })),
1885
2118
  total: result.total ?? tools.length,
1886
- limit: result.limit ?? (options.limit ?? 10)
2119
+ limit: result.limit ?? options.limit ?? 10
1887
2120
  };
1888
2121
  }
1889
2122
  /**
@@ -1999,8 +2232,10 @@ var Client2 = class _Client {
1999
2232
  if (options.k !== void 0) params.k = options.k;
2000
2233
  if (options.policy) params.policy = options.policy;
2001
2234
  if (options.have) params.have = options.have;
2002
- if (options.returnCallHandles !== void 0) params.return_call_handles = options.returnCallHandles;
2003
- if (options.exposeVirtualSkills !== void 0) params.expose_virtual_skills = options.exposeVirtualSkills;
2235
+ if (options.returnCallHandles !== void 0)
2236
+ params.return_call_handles = options.returnCallHandles;
2237
+ if (options.exposeVirtualSkills !== void 0)
2238
+ params.expose_virtual_skills = options.exposeVirtualSkills;
2004
2239
  if (options.modelOverrides) params.model_overrides = options.modelOverrides;
2005
2240
  return this.sendWithRetry(
2006
2241
  () => this.transport.callTool("data-grout/discovery.plan", params)
@@ -2118,7 +2353,8 @@ function buildToolMeta(raw) {
2118
2353
  }
2119
2354
 
2120
2355
  // src/index.ts
2121
- var version = "0.4.0";
2356
+ init_onramp();
2357
+ var version = "0.5.0";
2122
2358
  // Annotate the CommonJS export names for ESM import in node:
2123
2359
  0 && (module.exports = {
2124
2360
  AuthError,
@@ -2144,7 +2380,9 @@ var version = "0.4.0";
2144
2380
  generateKeypair,
2145
2381
  isDgUrl,
2146
2382
  refreshCaCert,
2383
+ registerAndExchange,
2147
2384
  registerIdentity,
2385
+ registerOnly,
2148
2386
  rotateIdentity,
2149
2387
  saveIdentity,
2150
2388
  version