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