@haven_ai/connect 0.1.15-alpha.0 → 0.1.17-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 +195 -153
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +195 -153
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +195 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -4
- package/dist/index.d.ts +14 -4
- package/dist/index.js +195 -153
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
package/dist/cli.cjs
CHANGED
|
@@ -137,8 +137,10 @@ async function writeCredentialFiles(input) {
|
|
|
137
137
|
await restrictPermissions(directory, 448, input.warn);
|
|
138
138
|
const identityPath = path.join(directory, "identity.json");
|
|
139
139
|
const signerPath = path.join(directory, "signer.json");
|
|
140
|
+
const agentPath = path.join(directory, "agent.json");
|
|
140
141
|
await assertDoesNotExist(identityPath);
|
|
141
142
|
await assertDoesNotExist(signerPath);
|
|
143
|
+
await assertDoesNotExist(agentPath);
|
|
142
144
|
await writeOwnerOnlyJson(
|
|
143
145
|
signerPath,
|
|
144
146
|
{
|
|
@@ -173,7 +175,26 @@ async function writeCredentialFiles(input) {
|
|
|
173
175
|
await promises.rm(signerPath, { force: true }).catch(() => void 0);
|
|
174
176
|
throw err;
|
|
175
177
|
}
|
|
176
|
-
|
|
178
|
+
try {
|
|
179
|
+
await writeOwnerOnlyJson(
|
|
180
|
+
agentPath,
|
|
181
|
+
{
|
|
182
|
+
agent_id: input.agentId,
|
|
183
|
+
safe_address: input.safeAddress,
|
|
184
|
+
chain_id: input.chainId,
|
|
185
|
+
network: input.network,
|
|
186
|
+
agent_budget: input.agentBudget,
|
|
187
|
+
note: "Non-secret orientation for the agent: identity + configured budget. Contains no API key or signing key. For the live remaining budget, call haven_get_allowances."
|
|
188
|
+
},
|
|
189
|
+
input.warn
|
|
190
|
+
);
|
|
191
|
+
} catch (err) {
|
|
192
|
+
await promises.rm(signerPath, { force: true }).catch(() => void 0);
|
|
193
|
+
await promises.rm(identityPath, { force: true }).catch(() => void 0);
|
|
194
|
+
await promises.rm(agentPath, { force: true }).catch(() => void 0);
|
|
195
|
+
throw err;
|
|
196
|
+
}
|
|
197
|
+
return { directory, identityPath, signerPath, agentPath };
|
|
177
198
|
}
|
|
178
199
|
function defaultAgentDirectory(agentId, baseDir = path.join(os.homedir(), ".haven", "agents")) {
|
|
179
200
|
return path.resolve(defaultCredentialRoot(baseDir), safePathPart(agentId));
|
|
@@ -215,9 +236,9 @@ var MCP_RUNTIME_MANIFEST = {
|
|
|
215
236
|
mcpPackage: "@haven_ai/mcp",
|
|
216
237
|
mcpVersion: mcp.MCP_VERSION,
|
|
217
238
|
sdkPackage: "@haven_ai/sdk",
|
|
218
|
-
sdkVersion: "0.1.
|
|
239
|
+
sdkVersion: "0.1.17-alpha.0",
|
|
219
240
|
signerPackage: "@haven_ai/signer",
|
|
220
|
-
signerVersion: "0.1.
|
|
241
|
+
signerVersion: "0.1.17-alpha.0",
|
|
221
242
|
minimumNodeVersion: "20.0.0",
|
|
222
243
|
supportedClients: ["codex-cli", "codex-desktop", "claude-code"],
|
|
223
244
|
requiredTools: mcp.registeredToolNames()
|
|
@@ -232,117 +253,6 @@ function signerPackageSpec() {
|
|
|
232
253
|
return `${MCP_RUNTIME_MANIFEST.signerPackage}@${MCP_RUNTIME_MANIFEST.signerVersion}`;
|
|
233
254
|
}
|
|
234
255
|
|
|
235
|
-
// src/runtime-registry.ts
|
|
236
|
-
var RUNTIME_PROFILES = {
|
|
237
|
-
"claude-code": {
|
|
238
|
-
id: "claude-code",
|
|
239
|
-
label: "Claude Code",
|
|
240
|
-
restartMode: "restart-session",
|
|
241
|
-
canWriteRuntimeConfig: true
|
|
242
|
-
},
|
|
243
|
-
"codex-cli": {
|
|
244
|
-
id: "codex-cli",
|
|
245
|
-
label: "Codex CLI",
|
|
246
|
-
restartMode: "restart-session",
|
|
247
|
-
canWriteRuntimeConfig: true
|
|
248
|
-
},
|
|
249
|
-
"codex-desktop": {
|
|
250
|
-
id: "codex-desktop",
|
|
251
|
-
label: "Codex Desktop",
|
|
252
|
-
restartMode: "restart-session",
|
|
253
|
-
canWriteRuntimeConfig: true
|
|
254
|
-
},
|
|
255
|
-
cursor: {
|
|
256
|
-
id: "cursor",
|
|
257
|
-
label: "Cursor",
|
|
258
|
-
restartMode: "hot-reload",
|
|
259
|
-
canWriteRuntimeConfig: true
|
|
260
|
-
},
|
|
261
|
-
vscode: {
|
|
262
|
-
id: "vscode",
|
|
263
|
-
label: "VS Code",
|
|
264
|
-
restartMode: "hot-reload",
|
|
265
|
-
canWriteRuntimeConfig: true
|
|
266
|
-
},
|
|
267
|
-
"vscode-insiders": {
|
|
268
|
-
id: "vscode-insiders",
|
|
269
|
-
label: "VS Code Insiders",
|
|
270
|
-
restartMode: "hot-reload",
|
|
271
|
-
canWriteRuntimeConfig: true
|
|
272
|
-
},
|
|
273
|
-
"claude-desktop": {
|
|
274
|
-
id: "claude-desktop",
|
|
275
|
-
label: "Claude Desktop",
|
|
276
|
-
restartMode: "restart-app",
|
|
277
|
-
canWriteRuntimeConfig: true
|
|
278
|
-
},
|
|
279
|
-
other: {
|
|
280
|
-
id: "other",
|
|
281
|
-
label: "Other agent runtime",
|
|
282
|
-
restartMode: "manual",
|
|
283
|
-
canWriteRuntimeConfig: false
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
var RUNTIME_ALIASES = {
|
|
287
|
-
claude: "claude-code",
|
|
288
|
-
"claude-code": "claude-code",
|
|
289
|
-
claudecode: "claude-code",
|
|
290
|
-
"claude_code": "claude-code",
|
|
291
|
-
codex: "codex-cli",
|
|
292
|
-
"codex-cli": "codex-cli",
|
|
293
|
-
codexcli: "codex-cli",
|
|
294
|
-
"codex_cli": "codex-cli",
|
|
295
|
-
"codex-desktop": "codex-desktop",
|
|
296
|
-
"codex_desktop": "codex-desktop",
|
|
297
|
-
codexdesktop: "codex-desktop",
|
|
298
|
-
"codex-app": "codex-desktop",
|
|
299
|
-
"codex_app": "codex-desktop",
|
|
300
|
-
codexapp: "codex-desktop",
|
|
301
|
-
cursor: "cursor",
|
|
302
|
-
vscode: "vscode",
|
|
303
|
-
"vs-code": "vscode",
|
|
304
|
-
"vs_code": "vscode",
|
|
305
|
-
code: "vscode",
|
|
306
|
-
"vscode-insiders": "vscode-insiders",
|
|
307
|
-
"vscode_insiders": "vscode-insiders",
|
|
308
|
-
vscodeinsiders: "vscode-insiders",
|
|
309
|
-
"vs-code-insiders": "vscode-insiders",
|
|
310
|
-
"code-insiders": "vscode-insiders",
|
|
311
|
-
insiders: "vscode-insiders",
|
|
312
|
-
"claude-desktop": "claude-desktop",
|
|
313
|
-
"claude_desktop": "claude-desktop",
|
|
314
|
-
claudesktop: "claude-desktop",
|
|
315
|
-
desktop: "claude-desktop",
|
|
316
|
-
other: "other",
|
|
317
|
-
manual: "other"
|
|
318
|
-
};
|
|
319
|
-
function runtimeProfile(runtime, env = process.env) {
|
|
320
|
-
return RUNTIME_PROFILES[normalizeRuntime(runtime, env)];
|
|
321
|
-
}
|
|
322
|
-
function normalizeRuntime(runtime, env = process.env) {
|
|
323
|
-
const explicit = normalizeRuntimeName(runtime);
|
|
324
|
-
if (explicit) return explicit;
|
|
325
|
-
return detectRuntime(env) ?? "other";
|
|
326
|
-
}
|
|
327
|
-
function restartRequiredForRuntime(runtime, env = process.env) {
|
|
328
|
-
const mode = runtimeProfile(runtime, env).restartMode;
|
|
329
|
-
return mode === "restart-session" || mode === "restart-app";
|
|
330
|
-
}
|
|
331
|
-
function runtimeRequiresHardRestart(runtime) {
|
|
332
|
-
return runtime === "claude-desktop" || runtime === "codex-desktop";
|
|
333
|
-
}
|
|
334
|
-
function normalizeRuntimeName(runtime) {
|
|
335
|
-
const key = runtime?.trim().toLowerCase();
|
|
336
|
-
if (!key) return null;
|
|
337
|
-
return RUNTIME_ALIASES[key.replace(/\s+/g, "-")] ?? null;
|
|
338
|
-
}
|
|
339
|
-
function detectRuntime(env) {
|
|
340
|
-
if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return "claude-code";
|
|
341
|
-
if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return "codex-cli";
|
|
342
|
-
if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === "vscode") return "vscode";
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
256
|
// src/config-writers.ts
|
|
347
257
|
var InvalidCodexTomlError = class extends Error {
|
|
348
258
|
constructor(message) {
|
|
@@ -489,7 +399,6 @@ async function writeJsonRuntimeConfig(input, target, serverRoot) {
|
|
|
489
399
|
async function writeCodexConfig(input) {
|
|
490
400
|
const target = codexConfigPath(input.homeDir);
|
|
491
401
|
const local = input.mode === "local";
|
|
492
|
-
const restartMessage = runtimeRequiresHardRestart(input.runtime) ? "After Haven approval, restart Codex Desktop so it can load Haven tools." : "After Haven approval, Haven tools should appear in your next Codex message. If they don't, restart Codex to load them.";
|
|
493
402
|
try {
|
|
494
403
|
const existing = await readOptional(target);
|
|
495
404
|
if (local) {
|
|
@@ -507,11 +416,7 @@ async function writeCodexConfig(input) {
|
|
|
507
416
|
changed: existing !== merged2,
|
|
508
417
|
restartRequired: true,
|
|
509
418
|
messages: [
|
|
510
|
-
`Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}
|
|
511
|
-
// Codex Desktop loads MCP servers at app launch; Codex CLI typically
|
|
512
|
-
// picks them up in the next session. Branch the copy so desktop users
|
|
513
|
-
// get the unambiguous instruction.
|
|
514
|
-
restartMessage
|
|
419
|
+
`Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}.`
|
|
515
420
|
]
|
|
516
421
|
};
|
|
517
422
|
}
|
|
@@ -526,8 +431,7 @@ async function writeCodexConfig(input) {
|
|
|
526
431
|
changed: existing !== merged,
|
|
527
432
|
restartRequired: true,
|
|
528
433
|
messages: [
|
|
529
|
-
`Updated Haven MCP entries in ${configTargetLabel(input.runtime)}
|
|
530
|
-
restartMessage
|
|
434
|
+
`Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`
|
|
531
435
|
]
|
|
532
436
|
};
|
|
533
437
|
} catch (err) {
|
|
@@ -1080,23 +984,29 @@ function parseNodeVersion(value) {
|
|
|
1080
984
|
];
|
|
1081
985
|
}
|
|
1082
986
|
async function installRuntimePackages(runtimeDirectory, npmCacheDirectory, runCommand) {
|
|
1083
|
-
const
|
|
987
|
+
const baseArgs = [
|
|
1084
988
|
"install",
|
|
1085
989
|
"--prefix",
|
|
1086
990
|
runtimeDirectory,
|
|
1087
|
-
"--cache",
|
|
1088
|
-
npmCacheDirectory,
|
|
1089
991
|
"--no-audit",
|
|
1090
992
|
"--no-fund",
|
|
1091
993
|
"--omit=dev",
|
|
994
|
+
"--prefer-offline",
|
|
1092
995
|
mcpPackageSpec(),
|
|
1093
996
|
sdkPackageSpec()
|
|
1094
997
|
];
|
|
1095
|
-
|
|
998
|
+
const run = async (args) => {
|
|
1096
999
|
if (runCommand) await runCommand("npm", args);
|
|
1097
1000
|
else await execFileAsync("npm", args, { timeout: 12e4, maxBuffer: 1024 * 1024 });
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1001
|
+
};
|
|
1002
|
+
try {
|
|
1003
|
+
await run(baseArgs);
|
|
1004
|
+
} catch {
|
|
1005
|
+
try {
|
|
1006
|
+
await run([...baseArgs, "--cache", npmCacheDirectory]);
|
|
1007
|
+
} catch (err) {
|
|
1008
|
+
throw new Error(`Could not install local Haven MCP runtime ${mcpPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1009
|
+
}
|
|
1100
1010
|
}
|
|
1101
1011
|
}
|
|
1102
1012
|
async function installedRuntimeMatches(runtimeDirectory, cliPath) {
|
|
@@ -1200,25 +1110,31 @@ async function prepareSignerRuntime(input, deps = {}) {
|
|
|
1200
1110
|
};
|
|
1201
1111
|
}
|
|
1202
1112
|
async function installRuntimePackages2(runtimeDirectory, npmCacheDirectory, runCommand) {
|
|
1203
|
-
const
|
|
1113
|
+
const baseArgs = [
|
|
1204
1114
|
"install",
|
|
1205
1115
|
"--prefix",
|
|
1206
1116
|
runtimeDirectory,
|
|
1207
|
-
"--cache",
|
|
1208
|
-
npmCacheDirectory,
|
|
1209
1117
|
"--no-audit",
|
|
1210
1118
|
"--no-fund",
|
|
1211
1119
|
"--omit=dev",
|
|
1120
|
+
"--prefer-offline",
|
|
1212
1121
|
signerPackageSpec(),
|
|
1213
1122
|
sdkPackageSpec()
|
|
1214
1123
|
];
|
|
1215
|
-
|
|
1124
|
+
const run = async (args) => {
|
|
1216
1125
|
if (runCommand) await runCommand("npm", args);
|
|
1217
1126
|
else await execFileAsync2("npm", args, { timeout: 12e4, maxBuffer: 1024 * 1024 });
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1127
|
+
};
|
|
1128
|
+
try {
|
|
1129
|
+
await run(baseArgs);
|
|
1130
|
+
} catch {
|
|
1131
|
+
try {
|
|
1132
|
+
await run([...baseArgs, "--cache", npmCacheDirectory]);
|
|
1133
|
+
} catch (err) {
|
|
1134
|
+
throw new Error(
|
|
1135
|
+
`Could not install local Haven signer runtime ${signerPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1222
1138
|
}
|
|
1223
1139
|
}
|
|
1224
1140
|
async function installedRuntimeMatches2(runtimeDirectory, cliPath) {
|
|
@@ -1281,6 +1197,117 @@ async function assertFileExists2(path, label) {
|
|
|
1281
1197
|
throw new Error(`Missing ${label}: ${path}`);
|
|
1282
1198
|
}
|
|
1283
1199
|
}
|
|
1200
|
+
|
|
1201
|
+
// src/runtime-registry.ts
|
|
1202
|
+
var RUNTIME_PROFILES = {
|
|
1203
|
+
"claude-code": {
|
|
1204
|
+
id: "claude-code",
|
|
1205
|
+
label: "Claude Code",
|
|
1206
|
+
restartMode: "restart-session",
|
|
1207
|
+
canWriteRuntimeConfig: true
|
|
1208
|
+
},
|
|
1209
|
+
"codex-cli": {
|
|
1210
|
+
id: "codex-cli",
|
|
1211
|
+
label: "Codex CLI",
|
|
1212
|
+
restartMode: "restart-session",
|
|
1213
|
+
canWriteRuntimeConfig: true
|
|
1214
|
+
},
|
|
1215
|
+
"codex-desktop": {
|
|
1216
|
+
id: "codex-desktop",
|
|
1217
|
+
label: "Codex Desktop",
|
|
1218
|
+
restartMode: "restart-session",
|
|
1219
|
+
canWriteRuntimeConfig: true
|
|
1220
|
+
},
|
|
1221
|
+
cursor: {
|
|
1222
|
+
id: "cursor",
|
|
1223
|
+
label: "Cursor",
|
|
1224
|
+
restartMode: "hot-reload",
|
|
1225
|
+
canWriteRuntimeConfig: true
|
|
1226
|
+
},
|
|
1227
|
+
vscode: {
|
|
1228
|
+
id: "vscode",
|
|
1229
|
+
label: "VS Code",
|
|
1230
|
+
restartMode: "hot-reload",
|
|
1231
|
+
canWriteRuntimeConfig: true
|
|
1232
|
+
},
|
|
1233
|
+
"vscode-insiders": {
|
|
1234
|
+
id: "vscode-insiders",
|
|
1235
|
+
label: "VS Code Insiders",
|
|
1236
|
+
restartMode: "hot-reload",
|
|
1237
|
+
canWriteRuntimeConfig: true
|
|
1238
|
+
},
|
|
1239
|
+
"claude-desktop": {
|
|
1240
|
+
id: "claude-desktop",
|
|
1241
|
+
label: "Claude Desktop",
|
|
1242
|
+
restartMode: "restart-app",
|
|
1243
|
+
canWriteRuntimeConfig: true
|
|
1244
|
+
},
|
|
1245
|
+
other: {
|
|
1246
|
+
id: "other",
|
|
1247
|
+
label: "Other agent runtime",
|
|
1248
|
+
restartMode: "manual",
|
|
1249
|
+
canWriteRuntimeConfig: false
|
|
1250
|
+
}
|
|
1251
|
+
};
|
|
1252
|
+
var RUNTIME_ALIASES = {
|
|
1253
|
+
claude: "claude-code",
|
|
1254
|
+
"claude-code": "claude-code",
|
|
1255
|
+
claudecode: "claude-code",
|
|
1256
|
+
"claude_code": "claude-code",
|
|
1257
|
+
codex: "codex-cli",
|
|
1258
|
+
"codex-cli": "codex-cli",
|
|
1259
|
+
codexcli: "codex-cli",
|
|
1260
|
+
"codex_cli": "codex-cli",
|
|
1261
|
+
"codex-desktop": "codex-desktop",
|
|
1262
|
+
"codex_desktop": "codex-desktop",
|
|
1263
|
+
codexdesktop: "codex-desktop",
|
|
1264
|
+
"codex-app": "codex-desktop",
|
|
1265
|
+
"codex_app": "codex-desktop",
|
|
1266
|
+
codexapp: "codex-desktop",
|
|
1267
|
+
cursor: "cursor",
|
|
1268
|
+
vscode: "vscode",
|
|
1269
|
+
"vs-code": "vscode",
|
|
1270
|
+
"vs_code": "vscode",
|
|
1271
|
+
code: "vscode",
|
|
1272
|
+
"vscode-insiders": "vscode-insiders",
|
|
1273
|
+
"vscode_insiders": "vscode-insiders",
|
|
1274
|
+
vscodeinsiders: "vscode-insiders",
|
|
1275
|
+
"vs-code-insiders": "vscode-insiders",
|
|
1276
|
+
"code-insiders": "vscode-insiders",
|
|
1277
|
+
insiders: "vscode-insiders",
|
|
1278
|
+
"claude-desktop": "claude-desktop",
|
|
1279
|
+
"claude_desktop": "claude-desktop",
|
|
1280
|
+
claudesktop: "claude-desktop",
|
|
1281
|
+
desktop: "claude-desktop",
|
|
1282
|
+
other: "other",
|
|
1283
|
+
manual: "other"
|
|
1284
|
+
};
|
|
1285
|
+
function runtimeProfile(runtime, env = process.env) {
|
|
1286
|
+
return RUNTIME_PROFILES[normalizeRuntime(runtime, env)];
|
|
1287
|
+
}
|
|
1288
|
+
function normalizeRuntime(runtime, env = process.env) {
|
|
1289
|
+
const explicit = normalizeRuntimeName(runtime);
|
|
1290
|
+
if (explicit) return explicit;
|
|
1291
|
+
return detectRuntime(env) ?? "other";
|
|
1292
|
+
}
|
|
1293
|
+
function restartRequiredForRuntime(runtime, env = process.env) {
|
|
1294
|
+
const mode = runtimeProfile(runtime, env).restartMode;
|
|
1295
|
+
return mode === "restart-session" || mode === "restart-app";
|
|
1296
|
+
}
|
|
1297
|
+
function runtimeRequiresHardRestart(runtime) {
|
|
1298
|
+
return runtime === "claude-desktop" || runtime === "codex-desktop";
|
|
1299
|
+
}
|
|
1300
|
+
function normalizeRuntimeName(runtime) {
|
|
1301
|
+
const key = runtime?.trim().toLowerCase();
|
|
1302
|
+
if (!key) return null;
|
|
1303
|
+
return RUNTIME_ALIASES[key.replace(/\s+/g, "-")] ?? null;
|
|
1304
|
+
}
|
|
1305
|
+
function detectRuntime(env) {
|
|
1306
|
+
if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return "claude-code";
|
|
1307
|
+
if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return "codex-cli";
|
|
1308
|
+
if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === "vscode") return "vscode";
|
|
1309
|
+
return null;
|
|
1310
|
+
}
|
|
1284
1311
|
async function acknowledgeLocalSignerConsent(signerPath, log) {
|
|
1285
1312
|
try {
|
|
1286
1313
|
const input = await buildSignerConsentInput(signerPath);
|
|
@@ -1356,6 +1383,7 @@ var execFileAsync3 = util.promisify(child_process.execFile);
|
|
|
1356
1383
|
async function installRuntime(input, deps = {}) {
|
|
1357
1384
|
const runtime = normalizeRuntime(input.runtime, deps.env);
|
|
1358
1385
|
const profile = runtimeProfile(runtime, deps.env);
|
|
1386
|
+
const progress = deps.onProgress ?? (() => void 0);
|
|
1359
1387
|
const localRuntime = input.localMcp === true && supportsLocalMcp(runtime);
|
|
1360
1388
|
const consentMessages = [];
|
|
1361
1389
|
const localMcpConsent = localRuntime ? await resolveLocalMcpConsent(input, consentMessages) : void 0;
|
|
@@ -1415,6 +1443,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1415
1443
|
}
|
|
1416
1444
|
let signerCommand;
|
|
1417
1445
|
if (!localRuntime) {
|
|
1446
|
+
progress("Getting the signer ready\u2026");
|
|
1418
1447
|
try {
|
|
1419
1448
|
const signerRuntime = await prepareSignerForRuntime(input, deps);
|
|
1420
1449
|
signerCommand = { command: signerRuntime.command, args: signerRuntime.args };
|
|
@@ -1426,6 +1455,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1426
1455
|
}
|
|
1427
1456
|
}
|
|
1428
1457
|
const signerRuntimePrepared = localRuntime ? void 0 : signerCommand !== void 0;
|
|
1458
|
+
progress("Setting up your Haven tools\u2026");
|
|
1429
1459
|
const configResult = runtime === "claude-code" ? localRuntime ? await configureClaudeCode(deps, localRuntimeInstall?.command ?? "") : await configureClaudeCodeHosted(deps, input, signerCommand) : await writeRuntimeConfig({
|
|
1430
1460
|
runtime,
|
|
1431
1461
|
hostedMcpUrl: input.hostedMcpUrl,
|
|
@@ -1438,6 +1468,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1438
1468
|
homeDir: deps.homeDir,
|
|
1439
1469
|
mode: localRuntime ? "local" : "hosted"
|
|
1440
1470
|
});
|
|
1471
|
+
progress("Almost there \u2014 just confirming everything connects\u2026");
|
|
1441
1472
|
const localProbePromise = configResult.runtimeMcpMode === "local_stdio" && localRuntimeInstall ? runLocalMcpProbe(localRuntimeInstall, deps) : Promise.resolve(void 0);
|
|
1442
1473
|
const [hostedProbe, signerCredentialReady, localMcpProbe] = await Promise.all([
|
|
1443
1474
|
configResult.hostedConfigured ? probeHostedMcpTools(input.apiKey, input.hostedMcpUrl, deps.fetch) : Promise.resolve({ status: "bad_response" }),
|
|
@@ -1502,8 +1533,7 @@ async function configureClaudeCode(deps, localMcpCommand) {
|
|
|
1502
1533
|
restartRequired: true,
|
|
1503
1534
|
messages: [
|
|
1504
1535
|
"Updated local Haven MCP entry with Claude Code.",
|
|
1505
|
-
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1506
|
-
"After Haven approval, Haven tools should appear in your next Claude Code message. If they don't, restart the session to load them."
|
|
1536
|
+
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1507
1537
|
]
|
|
1508
1538
|
};
|
|
1509
1539
|
} catch (err) {
|
|
@@ -1552,8 +1582,7 @@ async function configureClaudeCodeHosted(deps, input, signerCommand) {
|
|
|
1552
1582
|
restartRequired: true,
|
|
1553
1583
|
messages: [
|
|
1554
1584
|
"Updated hosted Haven MCP and local signer entries with Claude Code.",
|
|
1555
|
-
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1556
|
-
"After Haven approval, Haven tools should appear in your next Claude Code message. If they don't, restart the session to load them."
|
|
1585
|
+
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1557
1586
|
]
|
|
1558
1587
|
};
|
|
1559
1588
|
} catch (err) {
|
|
@@ -1681,7 +1710,7 @@ function localRuntimePrepareErrorCode(err) {
|
|
|
1681
1710
|
}
|
|
1682
1711
|
|
|
1683
1712
|
// src/runtime.ts
|
|
1684
|
-
var CONNECTOR_VERSION = "0.1.
|
|
1713
|
+
var CONNECTOR_VERSION = "0.1.17-alpha.0";
|
|
1685
1714
|
async function runConnect(options, deps = {}) {
|
|
1686
1715
|
const connectorVersion = options.connectorVersion ?? CONNECTOR_VERSION;
|
|
1687
1716
|
const api = deps.api ?? createConnectApiClient(options.apiBaseUrl);
|
|
@@ -1701,6 +1730,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1701
1730
|
);
|
|
1702
1731
|
}
|
|
1703
1732
|
}
|
|
1733
|
+
log("Warming up your connection to Haven\u2026");
|
|
1704
1734
|
const setup = await api.resolveSetup({
|
|
1705
1735
|
setupToken: options.setupToken,
|
|
1706
1736
|
connectorVersion,
|
|
@@ -1708,12 +1738,12 @@ async function runConnect(options, deps = {}) {
|
|
|
1708
1738
|
});
|
|
1709
1739
|
printSetupSummary(setup, log);
|
|
1710
1740
|
await preflightStorage({ baseDir: options.credentialsDir, warn: log });
|
|
1711
|
-
log("Checked local credential storage.");
|
|
1741
|
+
log("Checked local credential storage \u2014 all clear.");
|
|
1712
1742
|
const localKey = generateKey();
|
|
1713
1743
|
const localApiKey = generateLocalApiKey();
|
|
1714
|
-
log("
|
|
1715
|
-
log("Generated local Haven API key.");
|
|
1744
|
+
log("Minting a fresh signing key and API key \u2014 both stay on this machine.");
|
|
1716
1745
|
const proofSignature = await localKey.signChallenge(setup.challenge.message);
|
|
1746
|
+
log("Introducing your agent to Haven\u2026");
|
|
1717
1747
|
const registration = await api.registerSetup({
|
|
1718
1748
|
setupToken: options.setupToken,
|
|
1719
1749
|
connectorVersion,
|
|
@@ -1730,6 +1760,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1730
1760
|
installCapabilities
|
|
1731
1761
|
});
|
|
1732
1762
|
log(`Registered signing address with Haven: ${shortAddress(registration.delegate_address)}.`);
|
|
1763
|
+
log("Tucking your credentials away safely on disk\u2026");
|
|
1733
1764
|
const credentialPaths = await writeCredentials({
|
|
1734
1765
|
baseDir: options.credentialsDir,
|
|
1735
1766
|
agentId: registration.agent_id,
|
|
@@ -1751,6 +1782,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1751
1782
|
});
|
|
1752
1783
|
log(`Stored Haven identity credential locally: ${credentialPaths.identityPath}`);
|
|
1753
1784
|
log(`Stored local signer credential locally: ${credentialPaths.signerPath}`);
|
|
1785
|
+
log(`Stored non-secret agent orientation locally: ${credentialPaths.agentPath}`);
|
|
1754
1786
|
if (setup.x402_binding_signer) {
|
|
1755
1787
|
log("Configured x402 binding signer for the local signer.");
|
|
1756
1788
|
} else {
|
|
@@ -1769,8 +1801,14 @@ async function runConnect(options, deps = {}) {
|
|
|
1769
1801
|
ackSigner: options.ackSigner,
|
|
1770
1802
|
ackLocalTools: options.ackLocalTools,
|
|
1771
1803
|
localMcp: options.localMcp
|
|
1772
|
-
});
|
|
1804
|
+
}, { onProgress: log });
|
|
1773
1805
|
printRuntimeInstall(runtimeInstall, log);
|
|
1806
|
+
if (runtimeInstall.errorCode) {
|
|
1807
|
+
log("Haven setup needs a couple more steps on this machine \u2014 see the notes above.");
|
|
1808
|
+
} else {
|
|
1809
|
+
log("Haven setup on this machine is complete.");
|
|
1810
|
+
}
|
|
1811
|
+
printNextSteps(runtimeInstall, log);
|
|
1774
1812
|
try {
|
|
1775
1813
|
await api.updateInstallStatus(registration.setup_id, localApiKey, {
|
|
1776
1814
|
runtime: runtimeInstall.runtime,
|
|
@@ -1793,14 +1831,6 @@ async function runConnect(options, deps = {}) {
|
|
|
1793
1831
|
} catch (err) {
|
|
1794
1832
|
log(`Could not report install status to Haven: ${err instanceof Error ? err.message : String(err)}`);
|
|
1795
1833
|
}
|
|
1796
|
-
log("Return to Haven to approve the agent rules.");
|
|
1797
|
-
if (runtimeInstall.restartRequired) {
|
|
1798
|
-
if (runtimeRequiresHardRestart(runtimeInstall.runtime)) {
|
|
1799
|
-
log("After approval, restart this agent so it can load Haven tools.");
|
|
1800
|
-
} else {
|
|
1801
|
-
log("After approval, Haven tools should appear in your next message. If they don't, restart this agent to load them.");
|
|
1802
|
-
}
|
|
1803
|
-
}
|
|
1804
1834
|
return {
|
|
1805
1835
|
setupId: registration.setup_id,
|
|
1806
1836
|
agentId: registration.agent_id,
|
|
@@ -1838,6 +1868,18 @@ function printRuntimeInstall(result, log) {
|
|
|
1838
1868
|
log("Local Haven signer still needs runtime setup.");
|
|
1839
1869
|
}
|
|
1840
1870
|
}
|
|
1871
|
+
function printNextSteps(result, log) {
|
|
1872
|
+
log("Next: approve the agent rules in Haven. No Haven tools appear until you approve \u2014 restart or not.");
|
|
1873
|
+
if (result.restartRequired) {
|
|
1874
|
+
if (runtimeRequiresHardRestart(result.runtime)) {
|
|
1875
|
+
log("After you approve, restart this agent so it can load Haven tools.");
|
|
1876
|
+
} else {
|
|
1877
|
+
log("After you approve, restart this agent \u2014 your current session won't load the Haven tools until you do.");
|
|
1878
|
+
}
|
|
1879
|
+
} else {
|
|
1880
|
+
log("After you approve, the Haven tools should appear in this runtime shortly.");
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1841
1883
|
|
|
1842
1884
|
// src/args.ts
|
|
1843
1885
|
function parseArgs(argv, env = process.env) {
|