@haven_ai/connect 0.1.23-alpha.2 → 0.1.25-alpha.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.d.cts CHANGED
@@ -285,7 +285,7 @@ declare function runtimeInstallCapabilities(runtime: string | undefined, env?: N
285
285
  restartRequired: boolean;
286
286
  };
287
287
 
288
- declare const CONNECTOR_VERSION = "0.1.23-alpha.2";
288
+ declare const CONNECTOR_VERSION = "0.1.25-alpha.0";
289
289
  interface ConnectOptions {
290
290
  setupToken: string;
291
291
  apiBaseUrl: string;
@@ -402,11 +402,11 @@ declare function shortAddress(address: string): string;
402
402
 
403
403
  declare const MCP_RUNTIME_MANIFEST: {
404
404
  readonly mcpPackage: "@haven_ai/mcp";
405
- readonly mcpVersion: "0.1.23-alpha.2";
405
+ readonly mcpVersion: "0.1.25-alpha.0";
406
406
  readonly sdkPackage: "@haven_ai/sdk";
407
- readonly sdkVersion: "0.1.23-alpha.2";
407
+ readonly sdkVersion: "0.1.25-alpha.0";
408
408
  readonly signerPackage: "@haven_ai/signer";
409
- readonly signerVersion: "0.1.23-alpha.2";
409
+ readonly signerVersion: "0.1.25-alpha.0";
410
410
  readonly minimumNodeVersion: "22.0.0";
411
411
  readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
412
412
  readonly requiredTools: readonly string[];
package/dist/index.d.ts CHANGED
@@ -285,7 +285,7 @@ declare function runtimeInstallCapabilities(runtime: string | undefined, env?: N
285
285
  restartRequired: boolean;
286
286
  };
287
287
 
288
- declare const CONNECTOR_VERSION = "0.1.23-alpha.2";
288
+ declare const CONNECTOR_VERSION = "0.1.25-alpha.0";
289
289
  interface ConnectOptions {
290
290
  setupToken: string;
291
291
  apiBaseUrl: string;
@@ -402,11 +402,11 @@ declare function shortAddress(address: string): string;
402
402
 
403
403
  declare const MCP_RUNTIME_MANIFEST: {
404
404
  readonly mcpPackage: "@haven_ai/mcp";
405
- readonly mcpVersion: "0.1.23-alpha.2";
405
+ readonly mcpVersion: "0.1.25-alpha.0";
406
406
  readonly sdkPackage: "@haven_ai/sdk";
407
- readonly sdkVersion: "0.1.23-alpha.2";
407
+ readonly sdkVersion: "0.1.25-alpha.0";
408
408
  readonly signerPackage: "@haven_ai/signer";
409
- readonly signerVersion: "0.1.23-alpha.2";
409
+ readonly signerVersion: "0.1.25-alpha.0";
410
410
  readonly minimumNodeVersion: "22.0.0";
411
411
  readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
412
412
  readonly requiredTools: readonly string[];
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { HAVEN_MINIMUM_NODE_VERSION, isSupportedNodeVersion, unsupportedNodeVersionMessage, SKILL_FOLDER_NAME, HAVEN_SKILL_MD, resolveTokenFromAddress } from '@haven_ai/sdk';
1
+ import { HAVEN_MINIMUM_NODE_VERSION, isSupportedNodeVersion, unsupportedNodeVersionMessage, SKILL_FOLDER_NAME, resolveTokenFromAddress, HAVEN_SKILL_MD, HAVEN_SKILL_BODY_MD } from '@haven_ai/sdk';
2
2
  import crypto from 'crypto';
3
3
  import { Wallet } from 'ethers';
4
4
  import { mkdir, rm, chmod, access, writeFile, readFile, unlink } from 'fs/promises';
@@ -245,9 +245,9 @@ var MCP_RUNTIME_MANIFEST = {
245
245
  mcpPackage: "@haven_ai/mcp",
246
246
  mcpVersion: MCP_VERSION,
247
247
  sdkPackage: "@haven_ai/sdk",
248
- sdkVersion: "0.1.23-alpha.2",
248
+ sdkVersion: "0.1.25-alpha.0",
249
249
  signerPackage: "@haven_ai/signer",
250
- signerVersion: "0.1.23-alpha.2",
250
+ signerVersion: "0.1.25-alpha.0",
251
251
  // Sourced from the SDK, never a literal (#1161). This field read '20.0.0'
252
252
  // while every package's `engines` said `>=24` and the docs said `>=24.0.0`,
253
253
  // so the guard that was supposed to enforce the floor waved Node v23 through
@@ -1402,6 +1402,109 @@ async function assertFileExists2(path, label) {
1402
1402
  throw new Error(`Missing ${label}: ${path}`);
1403
1403
  }
1404
1404
  }
1405
+ var CODEX_AGENTS_BEGIN_MARKER = "<!-- BEGIN haven-pay (managed by @haven_ai/connect; edits inside this section are overwritten on re-setup) -->";
1406
+ var CODEX_AGENTS_END_MARKER = "<!-- END haven-pay -->";
1407
+ async function installSkillForRuntime(runtime, deps = {}) {
1408
+ switch (runtime) {
1409
+ case "claude-code":
1410
+ return installSkillFile(
1411
+ resolve(deps.homeDir ?? homedir(), ".claude", "skills", SKILL_FOLDER_NAME),
1412
+ "~/.claude/skills/haven-pay"
1413
+ );
1414
+ case "hermes":
1415
+ return installSkillFile(
1416
+ join(hermesHome(deps), "skills", SKILL_FOLDER_NAME),
1417
+ "the Hermes skills folder"
1418
+ );
1419
+ case "codex-cli":
1420
+ case "codex-desktop":
1421
+ return installCodexAgentsSection(deps);
1422
+ default:
1423
+ return void 0;
1424
+ }
1425
+ }
1426
+ async function installSkillFile(skillDir, label) {
1427
+ try {
1428
+ await mkdir(skillDir, { recursive: true });
1429
+ const target = join(skillDir, "SKILL.md");
1430
+ await writeFile(target, HAVEN_SKILL_MD, "utf8");
1431
+ return {
1432
+ installed: true,
1433
+ target,
1434
+ messages: [`Installed the generic Haven payment skill (${label}). It contains no secrets.`]
1435
+ };
1436
+ } catch (err) {
1437
+ return {
1438
+ installed: false,
1439
+ messages: [
1440
+ `Could not install the Haven payment skill: ${err instanceof Error ? err.message : String(err)}. Download it from the Haven dashboard instead.`
1441
+ ]
1442
+ };
1443
+ }
1444
+ }
1445
+ async function installCodexAgentsSection(deps) {
1446
+ try {
1447
+ const codexDir = resolve(deps.homeDir ?? homedir(), ".codex");
1448
+ const target = join(codexDir, "AGENTS.md");
1449
+ await mkdir(codexDir, { recursive: true });
1450
+ const existing = await readFile(target, "utf8").catch(() => null);
1451
+ const next = upsertManagedSection(existing, codexManagedSection());
1452
+ if (next !== existing) {
1453
+ await writeFile(target, next, "utf8");
1454
+ }
1455
+ return {
1456
+ installed: true,
1457
+ target,
1458
+ messages: [
1459
+ "Installed the generic Haven payment guidance as a managed section in ~/.codex/AGENTS.md (Codex reads it as global instructions). It contains no secrets; your own content in that file is untouched."
1460
+ ]
1461
+ };
1462
+ } catch (err) {
1463
+ return {
1464
+ installed: false,
1465
+ messages: [
1466
+ `Could not install the Haven payment guidance into ~/.codex/AGENTS.md: ${err instanceof Error ? err.message : String(err)}. Download the skill from the Haven dashboard instead.`
1467
+ ]
1468
+ };
1469
+ }
1470
+ }
1471
+ function codexManagedSection() {
1472
+ return `${CODEX_AGENTS_BEGIN_MARKER}
1473
+
1474
+ ${HAVEN_SKILL_BODY_MD.trimEnd()}
1475
+
1476
+ ${CODEX_AGENTS_END_MARKER}
1477
+ `;
1478
+ }
1479
+ function upsertManagedSection(existing, section) {
1480
+ if (existing === null || existing.trim() === "") return section;
1481
+ const begins = markerLineIndexes(existing, CODEX_AGENTS_BEGIN_MARKER);
1482
+ const ends = markerLineIndexes(existing, CODEX_AGENTS_END_MARKER);
1483
+ if (begins.length === 1 && ends.length === 1 && ends[0] > begins[0]) {
1484
+ const afterEnd = ends[0] + CODEX_AGENTS_END_MARKER.length;
1485
+ const tail = existing.startsWith("\r\n", afterEnd) ? existing.slice(afterEnd + 2) : existing.startsWith("\n", afterEnd) ? existing.slice(afterEnd + 1) : existing.slice(afterEnd);
1486
+ return existing.slice(0, begins[0]) + section + tail;
1487
+ }
1488
+ if (begins.length > 0 || ends.length > 0) {
1489
+ throw new Error(
1490
+ "found a damaged Haven marker section (orphaned or duplicated markers); remove the leftover marker lines and re-run setup"
1491
+ );
1492
+ }
1493
+ return `${existing.replace(/\n*$/, "\n\n")}${section}`;
1494
+ }
1495
+ function markerLineIndexes(text, marker) {
1496
+ const indexes = [];
1497
+ for (let from = 0; ; ) {
1498
+ const at = text.indexOf(marker, from);
1499
+ if (at === -1) return indexes;
1500
+ if (at === 0 || text[at - 1] === "\n") indexes.push(at);
1501
+ from = at + marker.length;
1502
+ }
1503
+ }
1504
+ function hermesHome(deps) {
1505
+ const env = deps.env ?? process.env;
1506
+ return env.HERMES_HOME ?? join(deps.homeDir ?? homedir(), ".hermes");
1507
+ }
1405
1508
 
1406
1509
  // src/runtime-registry.ts
1407
1510
  var RUNTIME_PROFILES = {
@@ -1713,7 +1816,7 @@ async function installRuntime(input, deps = {}) {
1713
1816
  const errorCode = configResult.errorCode ?? (configResult.runtimeMcpMode === "local_stdio" ? localMcpErrorCode(signerCredentialReady, localMcpConsent, localMcpProbe?.status) : hostedMcpErrorCode(configResult.hostedConfigured, hostedProbe.status) ?? signerConsentErrorCode(signerCredentialReady, signerConsent));
1714
1817
  const hostedProbeMessages = configResult.hostedConfigured && hostedProbe.status !== "ok" ? [`Hosted Haven MCP probe failed: ${hostedProbe.status}.`] : configResult.hostedConfigured ? ["Verified hosted Haven MCP tools with a read-only handshake."] : [];
1715
1818
  const localProbeMessages = localMcpProbe && localMcpProbe.status !== "ok" ? [`Local Haven MCP handshake failed: ${localMcpProbe.status}.`] : localMcpProbe?.status === "ok" ? ["Verified local Haven MCP tools with a stdio handshake."] : [];
1716
- const skillInstall = runtime === "claude-code" && !configResult.errorCode ? await installClaudeSkill(deps.homeDir) : void 0;
1819
+ const skillInstall = !configResult.errorCode ? await installSkillForRuntime(runtime, { homeDir: deps.homeDir, env: deps.env }) : void 0;
1717
1820
  return {
1718
1821
  runtime,
1719
1822
  runtimeMcpMode: configResult.runtimeMcpMode,
@@ -1837,22 +1940,6 @@ async function configureClaudeCodeHosted(deps, input, signerCommand) {
1837
1940
  async function defaultRunCommand(command, args) {
1838
1941
  await execFileAsync3(command, args, { timeout: 1e4 });
1839
1942
  }
1840
- async function installClaudeSkill(homeDir) {
1841
- try {
1842
- const skillDir = resolve(homeDir ?? homedir(), ".claude", "skills", SKILL_FOLDER_NAME);
1843
- await mkdir(skillDir, { recursive: true });
1844
- await writeFile(join(skillDir, "SKILL.md"), HAVEN_SKILL_MD, "utf8");
1845
- return {
1846
- installed: true,
1847
- messages: ["Installed the generic Haven payment skill (~/.claude/skills/haven-pay). It contains no secrets."]
1848
- };
1849
- } catch (err) {
1850
- return {
1851
- installed: false,
1852
- messages: [`Could not install the Haven payment skill: ${err instanceof Error ? err.message : String(err)}. Download it from the Haven dashboard instead.`]
1853
- };
1854
- }
1855
- }
1856
1943
  function buildProbeResult(mode, hostedConfigured, hostedStatus, signerReady, localMcpReady, localMcpProbeStatus) {
1857
1944
  if (mode === "local_stdio") {
1858
1945
  if (localMcpReady) return "local_stdio_mcp_ready";
@@ -1946,7 +2033,7 @@ function localRuntimePrepareErrorCode(err) {
1946
2033
  }
1947
2034
 
1948
2035
  // src/runtime.ts
1949
- var CONNECTOR_VERSION = "0.1.23-alpha.2";
2036
+ var CONNECTOR_VERSION = "0.1.25-alpha.0";
1950
2037
  var CONNECT_OUTCOME_SCHEMA_VERSION = 1;
1951
2038
  async function runConnect(options, deps = {}) {
1952
2039
  assertSupportedNodeVersion(deps.nodeVersion, MCP_RUNTIME_MANIFEST.minimumNodeVersion);
@@ -2209,9 +2296,11 @@ function formatAtomicAmount(atomic, decimals) {
2209
2296
  }
2210
2297
  function describeResetPeriod(resetPeriodMin) {
2211
2298
  if (resetPeriodMin === 1440) return "per day";
2299
+ if (resetPeriodMin === 10080) return "per week";
2300
+ if (resetPeriodMin === 43200) return "per month";
2212
2301
  if (resetPeriodMin === 60) return "per hour";
2213
- if (resetPeriodMin === 0) return "with no automatic reset";
2214
- return `per ${resetPeriodMin} minutes`;
2302
+ if (resetPeriodMin === 0) return "in total";
2303
+ return `every ${resetPeriodMin} minutes`;
2215
2304
  }
2216
2305
  function describeApprovedBudget(budget) {
2217
2306
  const token = resolveTokenFromAddress(budget.token_address);