@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.cjs CHANGED
@@ -252,9 +252,9 @@ var MCP_RUNTIME_MANIFEST = {
252
252
  mcpPackage: "@haven_ai/mcp",
253
253
  mcpVersion: mcp.MCP_VERSION,
254
254
  sdkPackage: "@haven_ai/sdk",
255
- sdkVersion: "0.1.23-alpha.2",
255
+ sdkVersion: "0.1.25-alpha.0",
256
256
  signerPackage: "@haven_ai/signer",
257
- signerVersion: "0.1.23-alpha.2",
257
+ signerVersion: "0.1.25-alpha.0",
258
258
  // Sourced from the SDK, never a literal (#1161). This field read '20.0.0'
259
259
  // while every package's `engines` said `>=24` and the docs said `>=24.0.0`,
260
260
  // so the guard that was supposed to enforce the floor waved Node v23 through
@@ -1409,6 +1409,109 @@ async function assertFileExists2(path, label) {
1409
1409
  throw new Error(`Missing ${label}: ${path}`);
1410
1410
  }
1411
1411
  }
1412
+ var CODEX_AGENTS_BEGIN_MARKER = "<!-- BEGIN haven-pay (managed by @haven_ai/connect; edits inside this section are overwritten on re-setup) -->";
1413
+ var CODEX_AGENTS_END_MARKER = "<!-- END haven-pay -->";
1414
+ async function installSkillForRuntime(runtime, deps = {}) {
1415
+ switch (runtime) {
1416
+ case "claude-code":
1417
+ return installSkillFile(
1418
+ path.resolve(deps.homeDir ?? os.homedir(), ".claude", "skills", sdk.SKILL_FOLDER_NAME),
1419
+ "~/.claude/skills/haven-pay"
1420
+ );
1421
+ case "hermes":
1422
+ return installSkillFile(
1423
+ path.join(hermesHome(deps), "skills", sdk.SKILL_FOLDER_NAME),
1424
+ "the Hermes skills folder"
1425
+ );
1426
+ case "codex-cli":
1427
+ case "codex-desktop":
1428
+ return installCodexAgentsSection(deps);
1429
+ default:
1430
+ return void 0;
1431
+ }
1432
+ }
1433
+ async function installSkillFile(skillDir, label) {
1434
+ try {
1435
+ await promises.mkdir(skillDir, { recursive: true });
1436
+ const target = path.join(skillDir, "SKILL.md");
1437
+ await promises.writeFile(target, sdk.HAVEN_SKILL_MD, "utf8");
1438
+ return {
1439
+ installed: true,
1440
+ target,
1441
+ messages: [`Installed the generic Haven payment skill (${label}). It contains no secrets.`]
1442
+ };
1443
+ } catch (err) {
1444
+ return {
1445
+ installed: false,
1446
+ messages: [
1447
+ `Could not install the Haven payment skill: ${err instanceof Error ? err.message : String(err)}. Download it from the Haven dashboard instead.`
1448
+ ]
1449
+ };
1450
+ }
1451
+ }
1452
+ async function installCodexAgentsSection(deps) {
1453
+ try {
1454
+ const codexDir = path.resolve(deps.homeDir ?? os.homedir(), ".codex");
1455
+ const target = path.join(codexDir, "AGENTS.md");
1456
+ await promises.mkdir(codexDir, { recursive: true });
1457
+ const existing = await promises.readFile(target, "utf8").catch(() => null);
1458
+ const next = upsertManagedSection(existing, codexManagedSection());
1459
+ if (next !== existing) {
1460
+ await promises.writeFile(target, next, "utf8");
1461
+ }
1462
+ return {
1463
+ installed: true,
1464
+ target,
1465
+ messages: [
1466
+ "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."
1467
+ ]
1468
+ };
1469
+ } catch (err) {
1470
+ return {
1471
+ installed: false,
1472
+ messages: [
1473
+ `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.`
1474
+ ]
1475
+ };
1476
+ }
1477
+ }
1478
+ function codexManagedSection() {
1479
+ return `${CODEX_AGENTS_BEGIN_MARKER}
1480
+
1481
+ ${sdk.HAVEN_SKILL_BODY_MD.trimEnd()}
1482
+
1483
+ ${CODEX_AGENTS_END_MARKER}
1484
+ `;
1485
+ }
1486
+ function upsertManagedSection(existing, section) {
1487
+ if (existing === null || existing.trim() === "") return section;
1488
+ const begins = markerLineIndexes(existing, CODEX_AGENTS_BEGIN_MARKER);
1489
+ const ends = markerLineIndexes(existing, CODEX_AGENTS_END_MARKER);
1490
+ if (begins.length === 1 && ends.length === 1 && ends[0] > begins[0]) {
1491
+ const afterEnd = ends[0] + CODEX_AGENTS_END_MARKER.length;
1492
+ const tail = existing.startsWith("\r\n", afterEnd) ? existing.slice(afterEnd + 2) : existing.startsWith("\n", afterEnd) ? existing.slice(afterEnd + 1) : existing.slice(afterEnd);
1493
+ return existing.slice(0, begins[0]) + section + tail;
1494
+ }
1495
+ if (begins.length > 0 || ends.length > 0) {
1496
+ throw new Error(
1497
+ "found a damaged Haven marker section (orphaned or duplicated markers); remove the leftover marker lines and re-run setup"
1498
+ );
1499
+ }
1500
+ return `${existing.replace(/\n*$/, "\n\n")}${section}`;
1501
+ }
1502
+ function markerLineIndexes(text, marker) {
1503
+ const indexes = [];
1504
+ for (let from = 0; ; ) {
1505
+ const at = text.indexOf(marker, from);
1506
+ if (at === -1) return indexes;
1507
+ if (at === 0 || text[at - 1] === "\n") indexes.push(at);
1508
+ from = at + marker.length;
1509
+ }
1510
+ }
1511
+ function hermesHome(deps) {
1512
+ const env = deps.env ?? process.env;
1513
+ return env.HERMES_HOME ?? path.join(deps.homeDir ?? os.homedir(), ".hermes");
1514
+ }
1412
1515
 
1413
1516
  // src/runtime-registry.ts
1414
1517
  var RUNTIME_PROFILES = {
@@ -1720,7 +1823,7 @@ async function installRuntime(input, deps = {}) {
1720
1823
  const errorCode = configResult.errorCode ?? (configResult.runtimeMcpMode === "local_stdio" ? localMcpErrorCode(signerCredentialReady, localMcpConsent, localMcpProbe?.status) : hostedMcpErrorCode(configResult.hostedConfigured, hostedProbe.status) ?? signerConsentErrorCode(signerCredentialReady, signerConsent));
1721
1824
  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."] : [];
1722
1825
  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."] : [];
1723
- const skillInstall = runtime === "claude-code" && !configResult.errorCode ? await installClaudeSkill(deps.homeDir) : void 0;
1826
+ const skillInstall = !configResult.errorCode ? await installSkillForRuntime(runtime, { homeDir: deps.homeDir, env: deps.env }) : void 0;
1724
1827
  return {
1725
1828
  runtime,
1726
1829
  runtimeMcpMode: configResult.runtimeMcpMode,
@@ -1844,22 +1947,6 @@ async function configureClaudeCodeHosted(deps, input, signerCommand) {
1844
1947
  async function defaultRunCommand(command, args) {
1845
1948
  await execFileAsync3(command, args, { timeout: 1e4 });
1846
1949
  }
1847
- async function installClaudeSkill(homeDir) {
1848
- try {
1849
- const skillDir = path.resolve(homeDir ?? os.homedir(), ".claude", "skills", sdk.SKILL_FOLDER_NAME);
1850
- await promises.mkdir(skillDir, { recursive: true });
1851
- await promises.writeFile(path.join(skillDir, "SKILL.md"), sdk.HAVEN_SKILL_MD, "utf8");
1852
- return {
1853
- installed: true,
1854
- messages: ["Installed the generic Haven payment skill (~/.claude/skills/haven-pay). It contains no secrets."]
1855
- };
1856
- } catch (err) {
1857
- return {
1858
- installed: false,
1859
- messages: [`Could not install the Haven payment skill: ${err instanceof Error ? err.message : String(err)}. Download it from the Haven dashboard instead.`]
1860
- };
1861
- }
1862
- }
1863
1950
  function buildProbeResult(mode, hostedConfigured, hostedStatus, signerReady, localMcpReady, localMcpProbeStatus) {
1864
1951
  if (mode === "local_stdio") {
1865
1952
  if (localMcpReady) return "local_stdio_mcp_ready";
@@ -1953,7 +2040,7 @@ function localRuntimePrepareErrorCode(err) {
1953
2040
  }
1954
2041
 
1955
2042
  // src/runtime.ts
1956
- var CONNECTOR_VERSION = "0.1.23-alpha.2";
2043
+ var CONNECTOR_VERSION = "0.1.25-alpha.0";
1957
2044
  var CONNECT_OUTCOME_SCHEMA_VERSION = 1;
1958
2045
  async function runConnect(options, deps = {}) {
1959
2046
  assertSupportedNodeVersion(deps.nodeVersion, MCP_RUNTIME_MANIFEST.minimumNodeVersion);
@@ -2216,9 +2303,11 @@ function formatAtomicAmount(atomic, decimals) {
2216
2303
  }
2217
2304
  function describeResetPeriod(resetPeriodMin) {
2218
2305
  if (resetPeriodMin === 1440) return "per day";
2306
+ if (resetPeriodMin === 10080) return "per week";
2307
+ if (resetPeriodMin === 43200) return "per month";
2219
2308
  if (resetPeriodMin === 60) return "per hour";
2220
- if (resetPeriodMin === 0) return "with no automatic reset";
2221
- return `per ${resetPeriodMin} minutes`;
2309
+ if (resetPeriodMin === 0) return "in total";
2310
+ return `every ${resetPeriodMin} minutes`;
2222
2311
  }
2223
2312
  function describeApprovedBudget(budget) {
2224
2313
  const token = sdk.resolveTokenFromAddress(budget.token_address);