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