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