@haven_ai/connect 0.1.23-alpha.0 → 0.1.23-alpha.2
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 +94 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +8 -1
- package/dist/cli.d.ts +8 -1
- package/dist/cli.js +95 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +93 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -4
- package/dist/index.d.ts +43 -4
- package/dist/index.js +94 -12
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var sdk = require('@haven_ai/sdk');
|
|
3
4
|
var crypto = require('crypto');
|
|
4
5
|
var ethers = require('ethers');
|
|
5
6
|
var promises = require('fs/promises');
|
|
@@ -9,8 +10,8 @@ var child_process = require('child_process');
|
|
|
9
10
|
var util = require('util');
|
|
10
11
|
var yaml = require('yaml');
|
|
11
12
|
var mcp = require('@haven_ai/mcp');
|
|
12
|
-
var sdk = require('@haven_ai/sdk');
|
|
13
13
|
var signer = require('@haven_ai/signer');
|
|
14
|
+
var fs = require('fs');
|
|
14
15
|
var url = require('url');
|
|
15
16
|
|
|
16
17
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -48,6 +49,10 @@ function createConnectApiClient(baseUrl, fetchImpl = fetch) {
|
|
|
48
49
|
}
|
|
49
50
|
})
|
|
50
51
|
}),
|
|
52
|
+
getConnectorStatus: (setupId, apiKey) => request(fetchImpl, `${root}/agent-connection-setups/${encodeURIComponent(setupId)}/connector-status`, {
|
|
53
|
+
method: "GET",
|
|
54
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
55
|
+
}),
|
|
51
56
|
updateInstallStatus: async (setupId, apiKey, input) => {
|
|
52
57
|
await request(fetchImpl, `${root}/agent-connection-setups/${encodeURIComponent(setupId)}/install-status`, {
|
|
53
58
|
method: "POST",
|
|
@@ -74,6 +79,14 @@ function createConnectApiClient(baseUrl, fetchImpl = fetch) {
|
|
|
74
79
|
}
|
|
75
80
|
};
|
|
76
81
|
}
|
|
82
|
+
var ConnectRequestError = class extends Error {
|
|
83
|
+
constructor(message, status) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.status = status;
|
|
86
|
+
this.name = "ConnectRequestError";
|
|
87
|
+
}
|
|
88
|
+
status;
|
|
89
|
+
};
|
|
77
90
|
async function request(fetchImpl, url, init) {
|
|
78
91
|
const response = await fetchImpl(url, {
|
|
79
92
|
...init,
|
|
@@ -86,7 +99,7 @@ async function request(fetchImpl, url, init) {
|
|
|
86
99
|
const body = text ? JSON.parse(text) : null;
|
|
87
100
|
if (!response.ok) {
|
|
88
101
|
const message = body?.error ?? body?.message ?? `${response.status} ${response.statusText}`;
|
|
89
|
-
throw new
|
|
102
|
+
throw new ConnectRequestError(`Haven setup request failed: ${message}`, response.status);
|
|
90
103
|
}
|
|
91
104
|
return body;
|
|
92
105
|
}
|
|
@@ -239,9 +252,9 @@ var MCP_RUNTIME_MANIFEST = {
|
|
|
239
252
|
mcpPackage: "@haven_ai/mcp",
|
|
240
253
|
mcpVersion: mcp.MCP_VERSION,
|
|
241
254
|
sdkPackage: "@haven_ai/sdk",
|
|
242
|
-
sdkVersion: "0.1.23-alpha.
|
|
255
|
+
sdkVersion: "0.1.23-alpha.2",
|
|
243
256
|
signerPackage: "@haven_ai/signer",
|
|
244
|
-
signerVersion: "0.1.23-alpha.
|
|
257
|
+
signerVersion: "0.1.23-alpha.2",
|
|
245
258
|
// Sourced from the SDK, never a literal (#1161). This field read '20.0.0'
|
|
246
259
|
// while every package's `engines` said `>=24` and the docs said `>=24.0.0`,
|
|
247
260
|
// so the guard that was supposed to enforce the floor waved Node v23 through
|
|
@@ -1940,7 +1953,7 @@ function localRuntimePrepareErrorCode(err) {
|
|
|
1940
1953
|
}
|
|
1941
1954
|
|
|
1942
1955
|
// src/runtime.ts
|
|
1943
|
-
var CONNECTOR_VERSION = "0.1.23-alpha.
|
|
1956
|
+
var CONNECTOR_VERSION = "0.1.23-alpha.2";
|
|
1944
1957
|
var CONNECT_OUTCOME_SCHEMA_VERSION = 1;
|
|
1945
1958
|
async function runConnect(options, deps = {}) {
|
|
1946
1959
|
assertSupportedNodeVersion(deps.nodeVersion, MCP_RUNTIME_MANIFEST.minimumNodeVersion);
|
|
@@ -2054,7 +2067,6 @@ async function runConnect(options, deps = {}) {
|
|
|
2054
2067
|
} else {
|
|
2055
2068
|
log("Haven setup on this machine is complete.");
|
|
2056
2069
|
}
|
|
2057
|
-
printNextSteps(runtimeInstall, log);
|
|
2058
2070
|
try {
|
|
2059
2071
|
await api.updateInstallStatus(registration.setup_id, localApiKey, {
|
|
2060
2072
|
runtime: runtimeInstall.runtime,
|
|
@@ -2077,6 +2089,10 @@ async function runConnect(options, deps = {}) {
|
|
|
2077
2089
|
} catch (err) {
|
|
2078
2090
|
log(`Could not report install status to Haven: ${err instanceof Error ? err.message : String(err)}`);
|
|
2079
2091
|
}
|
|
2092
|
+
if (options.waitForApproval !== false && !runtimeInstall.errorCode) {
|
|
2093
|
+
await waitForBudgetApproval(api, registration.setup_id, localApiKey, log, options.approvalWait);
|
|
2094
|
+
}
|
|
2095
|
+
printNextSteps(runtimeInstall, log);
|
|
2080
2096
|
return {
|
|
2081
2097
|
setupId: registration.setup_id,
|
|
2082
2098
|
agentId: registration.agent_id,
|
|
@@ -2192,6 +2208,61 @@ function printRuntimeInstall(result, log) {
|
|
|
2192
2208
|
log("Local Haven signer still needs runtime setup.");
|
|
2193
2209
|
}
|
|
2194
2210
|
}
|
|
2211
|
+
function formatAtomicAmount(atomic, decimals) {
|
|
2212
|
+
const s = atomic.toString().padStart(decimals + 1, "0");
|
|
2213
|
+
const intPart = s.slice(0, s.length - decimals) || "0";
|
|
2214
|
+
const fracPart = s.slice(s.length - decimals).replace(/0+$/, "");
|
|
2215
|
+
return fracPart ? `${intPart}.${fracPart}` : intPart;
|
|
2216
|
+
}
|
|
2217
|
+
function describeResetPeriod(resetPeriodMin) {
|
|
2218
|
+
if (resetPeriodMin === 1440) return "per day";
|
|
2219
|
+
if (resetPeriodMin === 60) return "per hour";
|
|
2220
|
+
if (resetPeriodMin === 0) return "with no automatic reset";
|
|
2221
|
+
return `per ${resetPeriodMin} minutes`;
|
|
2222
|
+
}
|
|
2223
|
+
function describeApprovedBudget(budget) {
|
|
2224
|
+
const token = sdk.resolveTokenFromAddress(budget.token_address);
|
|
2225
|
+
const amount = token ? `${formatAtomicAmount(BigInt(budget.amount), token.decimals)} ${budget.token_symbol}` : `${budget.amount} ${budget.token_symbol} (atomic units)`;
|
|
2226
|
+
return `${amount} ${describeResetPeriod(budget.reset_period_min)}`;
|
|
2227
|
+
}
|
|
2228
|
+
async function waitForBudgetApproval(api, setupId, apiKey, log, options = {}) {
|
|
2229
|
+
const intervalMs = options.intervalMs ?? 5e3;
|
|
2230
|
+
const timeoutMs = options.timeoutMs ?? 18e4;
|
|
2231
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms)));
|
|
2232
|
+
const maxPolls = Math.max(1, Math.floor(timeoutMs / intervalMs));
|
|
2233
|
+
const remindEvery = Math.max(1, Math.floor(3e4 / intervalMs));
|
|
2234
|
+
log("Registered with Haven \u2014 waiting for you to approve the budget in the dashboard\u2026");
|
|
2235
|
+
for (let i = 0; i < maxPolls; i++) {
|
|
2236
|
+
await sleep(intervalMs);
|
|
2237
|
+
let status;
|
|
2238
|
+
try {
|
|
2239
|
+
status = await api.getConnectorStatus(setupId, apiKey);
|
|
2240
|
+
} catch (err) {
|
|
2241
|
+
if (err instanceof ConnectRequestError && (err.status === 401 || err.status === 404)) {
|
|
2242
|
+
log("This setup ended in Haven \u2014 start a fresh connection from the dashboard when ready.");
|
|
2243
|
+
return "ended";
|
|
2244
|
+
}
|
|
2245
|
+
continue;
|
|
2246
|
+
}
|
|
2247
|
+
if (status.status === "active") {
|
|
2248
|
+
log(
|
|
2249
|
+
status.approved_budget ? `Budget approved \u{1F389} \u2014 I can now spend up to ${describeApprovedBudget(status.approved_budget)} from your Haven wallet.` : "Budget approved \u{1F389} \u2014 the agent can now spend within its Haven rules."
|
|
2250
|
+
);
|
|
2251
|
+
return "approved";
|
|
2252
|
+
}
|
|
2253
|
+
if (status.status === "cancelled" || status.status === "expired" || status.status === "failed") {
|
|
2254
|
+
log(`This setup ended in Haven (${status.status}) \u2014 start a fresh connection from the dashboard when ready.`);
|
|
2255
|
+
return "ended";
|
|
2256
|
+
}
|
|
2257
|
+
if ((i + 1) % remindEvery === 0) {
|
|
2258
|
+
log("Still waiting for budget approval in Haven\u2026");
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
log(
|
|
2262
|
+
"Budget approval is still pending in Haven. Approve it in the dashboard whenever you are ready \u2014 the agent tools unlock the moment you do. Verify later with the read-only haven_get_agent tool."
|
|
2263
|
+
);
|
|
2264
|
+
return "pending";
|
|
2265
|
+
}
|
|
2195
2266
|
function completionHandoffLines(result) {
|
|
2196
2267
|
if (result.errorCode === "manual_runtime_setup_required") {
|
|
2197
2268
|
return [
|
|
@@ -2326,11 +2397,14 @@ async function runCli(argv, io = {
|
|
|
2326
2397
|
return 0;
|
|
2327
2398
|
}
|
|
2328
2399
|
try {
|
|
2329
|
-
const result = await runConnect(
|
|
2330
|
-
|
|
2400
|
+
const result = await runConnect(
|
|
2401
|
+
{ ...parsed.options, waitForApproval: !parsed.json },
|
|
2402
|
+
{
|
|
2403
|
+
log: (message) => (parsed.json ? io.stderr : io.stdout)(`${message}
|
|
2331
2404
|
`),
|
|
2332
|
-
|
|
2333
|
-
|
|
2405
|
+
redactPaths: parsed.json
|
|
2406
|
+
}
|
|
2407
|
+
);
|
|
2334
2408
|
if (parsed.json) io.stdout(`${JSON.stringify(result.outcome)}
|
|
2335
2409
|
`);
|
|
2336
2410
|
return 0;
|
|
@@ -2349,7 +2423,15 @@ async function main() {
|
|
|
2349
2423
|
const exitCode = await runCli(process.argv.slice(2));
|
|
2350
2424
|
if (exitCode !== 0) process.exitCode = exitCode;
|
|
2351
2425
|
}
|
|
2352
|
-
|
|
2426
|
+
function isCliEntrypoint(argvPath = process.argv[1], moduleUrl = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))) {
|
|
2427
|
+
if (!argvPath) return false;
|
|
2428
|
+
try {
|
|
2429
|
+
return fs.realpathSync(argvPath) === fs.realpathSync(url.fileURLToPath(moduleUrl));
|
|
2430
|
+
} catch {
|
|
2431
|
+
return url.pathToFileURL(argvPath).href === moduleUrl;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
if (isCliEntrypoint()) void main();
|
|
2353
2435
|
|
|
2354
2436
|
exports.CONNECTOR_VERSION = CONNECTOR_VERSION;
|
|
2355
2437
|
exports.CONNECT_OUTCOME_SCHEMA_VERSION = CONNECT_OUTCOME_SCHEMA_VERSION;
|