@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.d.cts
CHANGED
|
@@ -96,6 +96,8 @@ interface StoredCredentialPaths {
|
|
|
96
96
|
directory: string;
|
|
97
97
|
identityPath: string;
|
|
98
98
|
signerPath: string;
|
|
99
|
+
/** Non-secret orientation file (identity + configured budget, no keys). */
|
|
100
|
+
agentPath: string;
|
|
99
101
|
}
|
|
100
102
|
interface WriteCredentialInput {
|
|
101
103
|
baseDir?: string;
|
|
@@ -243,6 +245,14 @@ interface RuntimeInstallDeps {
|
|
|
243
245
|
env?: NodeJS.ProcessEnv;
|
|
244
246
|
homeDir?: string;
|
|
245
247
|
fetch?: typeof fetch;
|
|
248
|
+
/**
|
|
249
|
+
* Optional live progress callback. installRuntime's slowest steps (signer
|
|
250
|
+
* pre-install, runtime config write, MCP handshake probes) otherwise emit
|
|
251
|
+
* nothing until the caller flushes the collected `messages` after this
|
|
252
|
+
* returns — leaving the console silent through the longest part of setup.
|
|
253
|
+
* When provided, a few lightweight heartbeat lines are emitted as they run.
|
|
254
|
+
*/
|
|
255
|
+
onProgress?: (message: string) => void;
|
|
246
256
|
runCommand?: (command: string, args: string[]) => Promise<void>;
|
|
247
257
|
prepareLocalMcpRuntime?: (input: PrepareLocalMcpRuntimeInput) => Promise<PreparedLocalMcpRuntime>;
|
|
248
258
|
prepareSignerRuntime?: (input: PrepareSignerRuntimeInput) => Promise<PreparedSignerRuntime>;
|
|
@@ -254,7 +264,7 @@ declare function runtimeInstallCapabilities(runtime: string | undefined, env?: N
|
|
|
254
264
|
restartRequired: boolean;
|
|
255
265
|
};
|
|
256
266
|
|
|
257
|
-
declare const CONNECTOR_VERSION = "0.1.
|
|
267
|
+
declare const CONNECTOR_VERSION = "0.1.17-alpha.0";
|
|
258
268
|
interface ConnectOptions {
|
|
259
269
|
setupToken: string;
|
|
260
270
|
apiBaseUrl: string;
|
|
@@ -295,11 +305,11 @@ declare function shortAddress(address: string): string;
|
|
|
295
305
|
|
|
296
306
|
declare const MCP_RUNTIME_MANIFEST: {
|
|
297
307
|
readonly mcpPackage: "@haven_ai/mcp";
|
|
298
|
-
readonly mcpVersion: "0.1.
|
|
308
|
+
readonly mcpVersion: "0.1.17-alpha.0";
|
|
299
309
|
readonly sdkPackage: "@haven_ai/sdk";
|
|
300
|
-
readonly sdkVersion: "0.1.
|
|
310
|
+
readonly sdkVersion: "0.1.17-alpha.0";
|
|
301
311
|
readonly signerPackage: "@haven_ai/signer";
|
|
302
|
-
readonly signerVersion: "0.1.
|
|
312
|
+
readonly signerVersion: "0.1.17-alpha.0";
|
|
303
313
|
readonly minimumNodeVersion: "20.0.0";
|
|
304
314
|
readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
|
|
305
315
|
readonly requiredTools: readonly string[];
|
package/dist/index.d.ts
CHANGED
|
@@ -96,6 +96,8 @@ interface StoredCredentialPaths {
|
|
|
96
96
|
directory: string;
|
|
97
97
|
identityPath: string;
|
|
98
98
|
signerPath: string;
|
|
99
|
+
/** Non-secret orientation file (identity + configured budget, no keys). */
|
|
100
|
+
agentPath: string;
|
|
99
101
|
}
|
|
100
102
|
interface WriteCredentialInput {
|
|
101
103
|
baseDir?: string;
|
|
@@ -243,6 +245,14 @@ interface RuntimeInstallDeps {
|
|
|
243
245
|
env?: NodeJS.ProcessEnv;
|
|
244
246
|
homeDir?: string;
|
|
245
247
|
fetch?: typeof fetch;
|
|
248
|
+
/**
|
|
249
|
+
* Optional live progress callback. installRuntime's slowest steps (signer
|
|
250
|
+
* pre-install, runtime config write, MCP handshake probes) otherwise emit
|
|
251
|
+
* nothing until the caller flushes the collected `messages` after this
|
|
252
|
+
* returns — leaving the console silent through the longest part of setup.
|
|
253
|
+
* When provided, a few lightweight heartbeat lines are emitted as they run.
|
|
254
|
+
*/
|
|
255
|
+
onProgress?: (message: string) => void;
|
|
246
256
|
runCommand?: (command: string, args: string[]) => Promise<void>;
|
|
247
257
|
prepareLocalMcpRuntime?: (input: PrepareLocalMcpRuntimeInput) => Promise<PreparedLocalMcpRuntime>;
|
|
248
258
|
prepareSignerRuntime?: (input: PrepareSignerRuntimeInput) => Promise<PreparedSignerRuntime>;
|
|
@@ -254,7 +264,7 @@ declare function runtimeInstallCapabilities(runtime: string | undefined, env?: N
|
|
|
254
264
|
restartRequired: boolean;
|
|
255
265
|
};
|
|
256
266
|
|
|
257
|
-
declare const CONNECTOR_VERSION = "0.1.
|
|
267
|
+
declare const CONNECTOR_VERSION = "0.1.17-alpha.0";
|
|
258
268
|
interface ConnectOptions {
|
|
259
269
|
setupToken: string;
|
|
260
270
|
apiBaseUrl: string;
|
|
@@ -295,11 +305,11 @@ declare function shortAddress(address: string): string;
|
|
|
295
305
|
|
|
296
306
|
declare const MCP_RUNTIME_MANIFEST: {
|
|
297
307
|
readonly mcpPackage: "@haven_ai/mcp";
|
|
298
|
-
readonly mcpVersion: "0.1.
|
|
308
|
+
readonly mcpVersion: "0.1.17-alpha.0";
|
|
299
309
|
readonly sdkPackage: "@haven_ai/sdk";
|
|
300
|
-
readonly sdkVersion: "0.1.
|
|
310
|
+
readonly sdkVersion: "0.1.17-alpha.0";
|
|
301
311
|
readonly signerPackage: "@haven_ai/signer";
|
|
302
|
-
readonly signerVersion: "0.1.
|
|
312
|
+
readonly signerVersion: "0.1.17-alpha.0";
|
|
303
313
|
readonly minimumNodeVersion: "20.0.0";
|
|
304
314
|
readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
|
|
305
315
|
readonly requiredTools: readonly string[];
|
package/dist/index.js
CHANGED
|
@@ -130,8 +130,10 @@ async function writeCredentialFiles(input) {
|
|
|
130
130
|
await restrictPermissions(directory, 448, input.warn);
|
|
131
131
|
const identityPath = join(directory, "identity.json");
|
|
132
132
|
const signerPath = join(directory, "signer.json");
|
|
133
|
+
const agentPath = join(directory, "agent.json");
|
|
133
134
|
await assertDoesNotExist(identityPath);
|
|
134
135
|
await assertDoesNotExist(signerPath);
|
|
136
|
+
await assertDoesNotExist(agentPath);
|
|
135
137
|
await writeOwnerOnlyJson(
|
|
136
138
|
signerPath,
|
|
137
139
|
{
|
|
@@ -166,7 +168,26 @@ async function writeCredentialFiles(input) {
|
|
|
166
168
|
await rm(signerPath, { force: true }).catch(() => void 0);
|
|
167
169
|
throw err;
|
|
168
170
|
}
|
|
169
|
-
|
|
171
|
+
try {
|
|
172
|
+
await writeOwnerOnlyJson(
|
|
173
|
+
agentPath,
|
|
174
|
+
{
|
|
175
|
+
agent_id: input.agentId,
|
|
176
|
+
safe_address: input.safeAddress,
|
|
177
|
+
chain_id: input.chainId,
|
|
178
|
+
network: input.network,
|
|
179
|
+
agent_budget: input.agentBudget,
|
|
180
|
+
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."
|
|
181
|
+
},
|
|
182
|
+
input.warn
|
|
183
|
+
);
|
|
184
|
+
} catch (err) {
|
|
185
|
+
await rm(signerPath, { force: true }).catch(() => void 0);
|
|
186
|
+
await rm(identityPath, { force: true }).catch(() => void 0);
|
|
187
|
+
await rm(agentPath, { force: true }).catch(() => void 0);
|
|
188
|
+
throw err;
|
|
189
|
+
}
|
|
190
|
+
return { directory, identityPath, signerPath, agentPath };
|
|
170
191
|
}
|
|
171
192
|
function defaultAgentDirectory(agentId, baseDir = join(homedir(), ".haven", "agents")) {
|
|
172
193
|
return resolve(defaultCredentialRoot(baseDir), safePathPart(agentId));
|
|
@@ -208,9 +229,9 @@ var MCP_RUNTIME_MANIFEST = {
|
|
|
208
229
|
mcpPackage: "@haven_ai/mcp",
|
|
209
230
|
mcpVersion: MCP_VERSION,
|
|
210
231
|
sdkPackage: "@haven_ai/sdk",
|
|
211
|
-
sdkVersion: "0.1.
|
|
232
|
+
sdkVersion: "0.1.17-alpha.0",
|
|
212
233
|
signerPackage: "@haven_ai/signer",
|
|
213
|
-
signerVersion: "0.1.
|
|
234
|
+
signerVersion: "0.1.17-alpha.0",
|
|
214
235
|
minimumNodeVersion: "20.0.0",
|
|
215
236
|
supportedClients: ["codex-cli", "codex-desktop", "claude-code"],
|
|
216
237
|
requiredTools: registeredToolNames()
|
|
@@ -225,117 +246,6 @@ function signerPackageSpec() {
|
|
|
225
246
|
return `${MCP_RUNTIME_MANIFEST.signerPackage}@${MCP_RUNTIME_MANIFEST.signerVersion}`;
|
|
226
247
|
}
|
|
227
248
|
|
|
228
|
-
// src/runtime-registry.ts
|
|
229
|
-
var RUNTIME_PROFILES = {
|
|
230
|
-
"claude-code": {
|
|
231
|
-
id: "claude-code",
|
|
232
|
-
label: "Claude Code",
|
|
233
|
-
restartMode: "restart-session",
|
|
234
|
-
canWriteRuntimeConfig: true
|
|
235
|
-
},
|
|
236
|
-
"codex-cli": {
|
|
237
|
-
id: "codex-cli",
|
|
238
|
-
label: "Codex CLI",
|
|
239
|
-
restartMode: "restart-session",
|
|
240
|
-
canWriteRuntimeConfig: true
|
|
241
|
-
},
|
|
242
|
-
"codex-desktop": {
|
|
243
|
-
id: "codex-desktop",
|
|
244
|
-
label: "Codex Desktop",
|
|
245
|
-
restartMode: "restart-session",
|
|
246
|
-
canWriteRuntimeConfig: true
|
|
247
|
-
},
|
|
248
|
-
cursor: {
|
|
249
|
-
id: "cursor",
|
|
250
|
-
label: "Cursor",
|
|
251
|
-
restartMode: "hot-reload",
|
|
252
|
-
canWriteRuntimeConfig: true
|
|
253
|
-
},
|
|
254
|
-
vscode: {
|
|
255
|
-
id: "vscode",
|
|
256
|
-
label: "VS Code",
|
|
257
|
-
restartMode: "hot-reload",
|
|
258
|
-
canWriteRuntimeConfig: true
|
|
259
|
-
},
|
|
260
|
-
"vscode-insiders": {
|
|
261
|
-
id: "vscode-insiders",
|
|
262
|
-
label: "VS Code Insiders",
|
|
263
|
-
restartMode: "hot-reload",
|
|
264
|
-
canWriteRuntimeConfig: true
|
|
265
|
-
},
|
|
266
|
-
"claude-desktop": {
|
|
267
|
-
id: "claude-desktop",
|
|
268
|
-
label: "Claude Desktop",
|
|
269
|
-
restartMode: "restart-app",
|
|
270
|
-
canWriteRuntimeConfig: true
|
|
271
|
-
},
|
|
272
|
-
other: {
|
|
273
|
-
id: "other",
|
|
274
|
-
label: "Other agent runtime",
|
|
275
|
-
restartMode: "manual",
|
|
276
|
-
canWriteRuntimeConfig: false
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
var RUNTIME_ALIASES = {
|
|
280
|
-
claude: "claude-code",
|
|
281
|
-
"claude-code": "claude-code",
|
|
282
|
-
claudecode: "claude-code",
|
|
283
|
-
"claude_code": "claude-code",
|
|
284
|
-
codex: "codex-cli",
|
|
285
|
-
"codex-cli": "codex-cli",
|
|
286
|
-
codexcli: "codex-cli",
|
|
287
|
-
"codex_cli": "codex-cli",
|
|
288
|
-
"codex-desktop": "codex-desktop",
|
|
289
|
-
"codex_desktop": "codex-desktop",
|
|
290
|
-
codexdesktop: "codex-desktop",
|
|
291
|
-
"codex-app": "codex-desktop",
|
|
292
|
-
"codex_app": "codex-desktop",
|
|
293
|
-
codexapp: "codex-desktop",
|
|
294
|
-
cursor: "cursor",
|
|
295
|
-
vscode: "vscode",
|
|
296
|
-
"vs-code": "vscode",
|
|
297
|
-
"vs_code": "vscode",
|
|
298
|
-
code: "vscode",
|
|
299
|
-
"vscode-insiders": "vscode-insiders",
|
|
300
|
-
"vscode_insiders": "vscode-insiders",
|
|
301
|
-
vscodeinsiders: "vscode-insiders",
|
|
302
|
-
"vs-code-insiders": "vscode-insiders",
|
|
303
|
-
"code-insiders": "vscode-insiders",
|
|
304
|
-
insiders: "vscode-insiders",
|
|
305
|
-
"claude-desktop": "claude-desktop",
|
|
306
|
-
"claude_desktop": "claude-desktop",
|
|
307
|
-
claudesktop: "claude-desktop",
|
|
308
|
-
desktop: "claude-desktop",
|
|
309
|
-
other: "other",
|
|
310
|
-
manual: "other"
|
|
311
|
-
};
|
|
312
|
-
function runtimeProfile(runtime, env = process.env) {
|
|
313
|
-
return RUNTIME_PROFILES[normalizeRuntime(runtime, env)];
|
|
314
|
-
}
|
|
315
|
-
function normalizeRuntime(runtime, env = process.env) {
|
|
316
|
-
const explicit = normalizeRuntimeName(runtime);
|
|
317
|
-
if (explicit) return explicit;
|
|
318
|
-
return detectRuntime(env) ?? "other";
|
|
319
|
-
}
|
|
320
|
-
function restartRequiredForRuntime(runtime, env = process.env) {
|
|
321
|
-
const mode = runtimeProfile(runtime, env).restartMode;
|
|
322
|
-
return mode === "restart-session" || mode === "restart-app";
|
|
323
|
-
}
|
|
324
|
-
function runtimeRequiresHardRestart(runtime) {
|
|
325
|
-
return runtime === "claude-desktop" || runtime === "codex-desktop";
|
|
326
|
-
}
|
|
327
|
-
function normalizeRuntimeName(runtime) {
|
|
328
|
-
const key = runtime?.trim().toLowerCase();
|
|
329
|
-
if (!key) return null;
|
|
330
|
-
return RUNTIME_ALIASES[key.replace(/\s+/g, "-")] ?? null;
|
|
331
|
-
}
|
|
332
|
-
function detectRuntime(env) {
|
|
333
|
-
if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return "claude-code";
|
|
334
|
-
if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return "codex-cli";
|
|
335
|
-
if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === "vscode") return "vscode";
|
|
336
|
-
return null;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
249
|
// src/config-writers.ts
|
|
340
250
|
var InvalidCodexTomlError = class extends Error {
|
|
341
251
|
constructor(message) {
|
|
@@ -482,7 +392,6 @@ async function writeJsonRuntimeConfig(input, target, serverRoot) {
|
|
|
482
392
|
async function writeCodexConfig(input) {
|
|
483
393
|
const target = codexConfigPath(input.homeDir);
|
|
484
394
|
const local = input.mode === "local";
|
|
485
|
-
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.";
|
|
486
395
|
try {
|
|
487
396
|
const existing = await readOptional(target);
|
|
488
397
|
if (local) {
|
|
@@ -500,11 +409,7 @@ async function writeCodexConfig(input) {
|
|
|
500
409
|
changed: existing !== merged2,
|
|
501
410
|
restartRequired: true,
|
|
502
411
|
messages: [
|
|
503
|
-
`Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}
|
|
504
|
-
// Codex Desktop loads MCP servers at app launch; Codex CLI typically
|
|
505
|
-
// picks them up in the next session. Branch the copy so desktop users
|
|
506
|
-
// get the unambiguous instruction.
|
|
507
|
-
restartMessage
|
|
412
|
+
`Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}.`
|
|
508
413
|
]
|
|
509
414
|
};
|
|
510
415
|
}
|
|
@@ -519,8 +424,7 @@ async function writeCodexConfig(input) {
|
|
|
519
424
|
changed: existing !== merged,
|
|
520
425
|
restartRequired: true,
|
|
521
426
|
messages: [
|
|
522
|
-
`Updated Haven MCP entries in ${configTargetLabel(input.runtime)}
|
|
523
|
-
restartMessage
|
|
427
|
+
`Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`
|
|
524
428
|
]
|
|
525
429
|
};
|
|
526
430
|
} catch (err) {
|
|
@@ -1073,23 +977,29 @@ function parseNodeVersion(value) {
|
|
|
1073
977
|
];
|
|
1074
978
|
}
|
|
1075
979
|
async function installRuntimePackages(runtimeDirectory, npmCacheDirectory, runCommand) {
|
|
1076
|
-
const
|
|
980
|
+
const baseArgs = [
|
|
1077
981
|
"install",
|
|
1078
982
|
"--prefix",
|
|
1079
983
|
runtimeDirectory,
|
|
1080
|
-
"--cache",
|
|
1081
|
-
npmCacheDirectory,
|
|
1082
984
|
"--no-audit",
|
|
1083
985
|
"--no-fund",
|
|
1084
986
|
"--omit=dev",
|
|
987
|
+
"--prefer-offline",
|
|
1085
988
|
mcpPackageSpec(),
|
|
1086
989
|
sdkPackageSpec()
|
|
1087
990
|
];
|
|
1088
|
-
|
|
991
|
+
const run = async (args) => {
|
|
1089
992
|
if (runCommand) await runCommand("npm", args);
|
|
1090
993
|
else await execFileAsync("npm", args, { timeout: 12e4, maxBuffer: 1024 * 1024 });
|
|
1091
|
-
}
|
|
1092
|
-
|
|
994
|
+
};
|
|
995
|
+
try {
|
|
996
|
+
await run(baseArgs);
|
|
997
|
+
} catch {
|
|
998
|
+
try {
|
|
999
|
+
await run([...baseArgs, "--cache", npmCacheDirectory]);
|
|
1000
|
+
} catch (err) {
|
|
1001
|
+
throw new Error(`Could not install local Haven MCP runtime ${mcpPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1002
|
+
}
|
|
1093
1003
|
}
|
|
1094
1004
|
}
|
|
1095
1005
|
async function installedRuntimeMatches(runtimeDirectory, cliPath) {
|
|
@@ -1193,25 +1103,31 @@ async function prepareSignerRuntime(input, deps = {}) {
|
|
|
1193
1103
|
};
|
|
1194
1104
|
}
|
|
1195
1105
|
async function installRuntimePackages2(runtimeDirectory, npmCacheDirectory, runCommand) {
|
|
1196
|
-
const
|
|
1106
|
+
const baseArgs = [
|
|
1197
1107
|
"install",
|
|
1198
1108
|
"--prefix",
|
|
1199
1109
|
runtimeDirectory,
|
|
1200
|
-
"--cache",
|
|
1201
|
-
npmCacheDirectory,
|
|
1202
1110
|
"--no-audit",
|
|
1203
1111
|
"--no-fund",
|
|
1204
1112
|
"--omit=dev",
|
|
1113
|
+
"--prefer-offline",
|
|
1205
1114
|
signerPackageSpec(),
|
|
1206
1115
|
sdkPackageSpec()
|
|
1207
1116
|
];
|
|
1208
|
-
|
|
1117
|
+
const run = async (args) => {
|
|
1209
1118
|
if (runCommand) await runCommand("npm", args);
|
|
1210
1119
|
else await execFileAsync2("npm", args, { timeout: 12e4, maxBuffer: 1024 * 1024 });
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1120
|
+
};
|
|
1121
|
+
try {
|
|
1122
|
+
await run(baseArgs);
|
|
1123
|
+
} catch {
|
|
1124
|
+
try {
|
|
1125
|
+
await run([...baseArgs, "--cache", npmCacheDirectory]);
|
|
1126
|
+
} catch (err) {
|
|
1127
|
+
throw new Error(
|
|
1128
|
+
`Could not install local Haven signer runtime ${signerPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1215
1131
|
}
|
|
1216
1132
|
}
|
|
1217
1133
|
async function installedRuntimeMatches2(runtimeDirectory, cliPath) {
|
|
@@ -1274,6 +1190,117 @@ async function assertFileExists2(path, label) {
|
|
|
1274
1190
|
throw new Error(`Missing ${label}: ${path}`);
|
|
1275
1191
|
}
|
|
1276
1192
|
}
|
|
1193
|
+
|
|
1194
|
+
// src/runtime-registry.ts
|
|
1195
|
+
var RUNTIME_PROFILES = {
|
|
1196
|
+
"claude-code": {
|
|
1197
|
+
id: "claude-code",
|
|
1198
|
+
label: "Claude Code",
|
|
1199
|
+
restartMode: "restart-session",
|
|
1200
|
+
canWriteRuntimeConfig: true
|
|
1201
|
+
},
|
|
1202
|
+
"codex-cli": {
|
|
1203
|
+
id: "codex-cli",
|
|
1204
|
+
label: "Codex CLI",
|
|
1205
|
+
restartMode: "restart-session",
|
|
1206
|
+
canWriteRuntimeConfig: true
|
|
1207
|
+
},
|
|
1208
|
+
"codex-desktop": {
|
|
1209
|
+
id: "codex-desktop",
|
|
1210
|
+
label: "Codex Desktop",
|
|
1211
|
+
restartMode: "restart-session",
|
|
1212
|
+
canWriteRuntimeConfig: true
|
|
1213
|
+
},
|
|
1214
|
+
cursor: {
|
|
1215
|
+
id: "cursor",
|
|
1216
|
+
label: "Cursor",
|
|
1217
|
+
restartMode: "hot-reload",
|
|
1218
|
+
canWriteRuntimeConfig: true
|
|
1219
|
+
},
|
|
1220
|
+
vscode: {
|
|
1221
|
+
id: "vscode",
|
|
1222
|
+
label: "VS Code",
|
|
1223
|
+
restartMode: "hot-reload",
|
|
1224
|
+
canWriteRuntimeConfig: true
|
|
1225
|
+
},
|
|
1226
|
+
"vscode-insiders": {
|
|
1227
|
+
id: "vscode-insiders",
|
|
1228
|
+
label: "VS Code Insiders",
|
|
1229
|
+
restartMode: "hot-reload",
|
|
1230
|
+
canWriteRuntimeConfig: true
|
|
1231
|
+
},
|
|
1232
|
+
"claude-desktop": {
|
|
1233
|
+
id: "claude-desktop",
|
|
1234
|
+
label: "Claude Desktop",
|
|
1235
|
+
restartMode: "restart-app",
|
|
1236
|
+
canWriteRuntimeConfig: true
|
|
1237
|
+
},
|
|
1238
|
+
other: {
|
|
1239
|
+
id: "other",
|
|
1240
|
+
label: "Other agent runtime",
|
|
1241
|
+
restartMode: "manual",
|
|
1242
|
+
canWriteRuntimeConfig: false
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
var RUNTIME_ALIASES = {
|
|
1246
|
+
claude: "claude-code",
|
|
1247
|
+
"claude-code": "claude-code",
|
|
1248
|
+
claudecode: "claude-code",
|
|
1249
|
+
"claude_code": "claude-code",
|
|
1250
|
+
codex: "codex-cli",
|
|
1251
|
+
"codex-cli": "codex-cli",
|
|
1252
|
+
codexcli: "codex-cli",
|
|
1253
|
+
"codex_cli": "codex-cli",
|
|
1254
|
+
"codex-desktop": "codex-desktop",
|
|
1255
|
+
"codex_desktop": "codex-desktop",
|
|
1256
|
+
codexdesktop: "codex-desktop",
|
|
1257
|
+
"codex-app": "codex-desktop",
|
|
1258
|
+
"codex_app": "codex-desktop",
|
|
1259
|
+
codexapp: "codex-desktop",
|
|
1260
|
+
cursor: "cursor",
|
|
1261
|
+
vscode: "vscode",
|
|
1262
|
+
"vs-code": "vscode",
|
|
1263
|
+
"vs_code": "vscode",
|
|
1264
|
+
code: "vscode",
|
|
1265
|
+
"vscode-insiders": "vscode-insiders",
|
|
1266
|
+
"vscode_insiders": "vscode-insiders",
|
|
1267
|
+
vscodeinsiders: "vscode-insiders",
|
|
1268
|
+
"vs-code-insiders": "vscode-insiders",
|
|
1269
|
+
"code-insiders": "vscode-insiders",
|
|
1270
|
+
insiders: "vscode-insiders",
|
|
1271
|
+
"claude-desktop": "claude-desktop",
|
|
1272
|
+
"claude_desktop": "claude-desktop",
|
|
1273
|
+
claudesktop: "claude-desktop",
|
|
1274
|
+
desktop: "claude-desktop",
|
|
1275
|
+
other: "other",
|
|
1276
|
+
manual: "other"
|
|
1277
|
+
};
|
|
1278
|
+
function runtimeProfile(runtime, env = process.env) {
|
|
1279
|
+
return RUNTIME_PROFILES[normalizeRuntime(runtime, env)];
|
|
1280
|
+
}
|
|
1281
|
+
function normalizeRuntime(runtime, env = process.env) {
|
|
1282
|
+
const explicit = normalizeRuntimeName(runtime);
|
|
1283
|
+
if (explicit) return explicit;
|
|
1284
|
+
return detectRuntime(env) ?? "other";
|
|
1285
|
+
}
|
|
1286
|
+
function restartRequiredForRuntime(runtime, env = process.env) {
|
|
1287
|
+
const mode = runtimeProfile(runtime, env).restartMode;
|
|
1288
|
+
return mode === "restart-session" || mode === "restart-app";
|
|
1289
|
+
}
|
|
1290
|
+
function runtimeRequiresHardRestart(runtime) {
|
|
1291
|
+
return runtime === "claude-desktop" || runtime === "codex-desktop";
|
|
1292
|
+
}
|
|
1293
|
+
function normalizeRuntimeName(runtime) {
|
|
1294
|
+
const key = runtime?.trim().toLowerCase();
|
|
1295
|
+
if (!key) return null;
|
|
1296
|
+
return RUNTIME_ALIASES[key.replace(/\s+/g, "-")] ?? null;
|
|
1297
|
+
}
|
|
1298
|
+
function detectRuntime(env) {
|
|
1299
|
+
if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return "claude-code";
|
|
1300
|
+
if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return "codex-cli";
|
|
1301
|
+
if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === "vscode") return "vscode";
|
|
1302
|
+
return null;
|
|
1303
|
+
}
|
|
1277
1304
|
async function acknowledgeLocalSignerConsent(signerPath, log) {
|
|
1278
1305
|
try {
|
|
1279
1306
|
const input = await buildSignerConsentInput(signerPath);
|
|
@@ -1349,6 +1376,7 @@ var execFileAsync3 = promisify(execFile);
|
|
|
1349
1376
|
async function installRuntime(input, deps = {}) {
|
|
1350
1377
|
const runtime = normalizeRuntime(input.runtime, deps.env);
|
|
1351
1378
|
const profile = runtimeProfile(runtime, deps.env);
|
|
1379
|
+
const progress = deps.onProgress ?? (() => void 0);
|
|
1352
1380
|
const localRuntime = input.localMcp === true && supportsLocalMcp(runtime);
|
|
1353
1381
|
const consentMessages = [];
|
|
1354
1382
|
const localMcpConsent = localRuntime ? await resolveLocalMcpConsent(input, consentMessages) : void 0;
|
|
@@ -1408,6 +1436,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1408
1436
|
}
|
|
1409
1437
|
let signerCommand;
|
|
1410
1438
|
if (!localRuntime) {
|
|
1439
|
+
progress("Getting the signer ready\u2026");
|
|
1411
1440
|
try {
|
|
1412
1441
|
const signerRuntime = await prepareSignerForRuntime(input, deps);
|
|
1413
1442
|
signerCommand = { command: signerRuntime.command, args: signerRuntime.args };
|
|
@@ -1419,6 +1448,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1419
1448
|
}
|
|
1420
1449
|
}
|
|
1421
1450
|
const signerRuntimePrepared = localRuntime ? void 0 : signerCommand !== void 0;
|
|
1451
|
+
progress("Setting up your Haven tools\u2026");
|
|
1422
1452
|
const configResult = runtime === "claude-code" ? localRuntime ? await configureClaudeCode(deps, localRuntimeInstall?.command ?? "") : await configureClaudeCodeHosted(deps, input, signerCommand) : await writeRuntimeConfig({
|
|
1423
1453
|
runtime,
|
|
1424
1454
|
hostedMcpUrl: input.hostedMcpUrl,
|
|
@@ -1431,6 +1461,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1431
1461
|
homeDir: deps.homeDir,
|
|
1432
1462
|
mode: localRuntime ? "local" : "hosted"
|
|
1433
1463
|
});
|
|
1464
|
+
progress("Almost there \u2014 just confirming everything connects\u2026");
|
|
1434
1465
|
const localProbePromise = configResult.runtimeMcpMode === "local_stdio" && localRuntimeInstall ? runLocalMcpProbe(localRuntimeInstall, deps) : Promise.resolve(void 0);
|
|
1435
1466
|
const [hostedProbe, signerCredentialReady, localMcpProbe] = await Promise.all([
|
|
1436
1467
|
configResult.hostedConfigured ? probeHostedMcpTools(input.apiKey, input.hostedMcpUrl, deps.fetch) : Promise.resolve({ status: "bad_response" }),
|
|
@@ -1495,8 +1526,7 @@ async function configureClaudeCode(deps, localMcpCommand) {
|
|
|
1495
1526
|
restartRequired: true,
|
|
1496
1527
|
messages: [
|
|
1497
1528
|
"Updated local Haven MCP entry with Claude Code.",
|
|
1498
|
-
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1499
|
-
"After Haven approval, Haven tools should appear in your next Claude Code message. If they don't, restart the session to load them."
|
|
1529
|
+
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1500
1530
|
]
|
|
1501
1531
|
};
|
|
1502
1532
|
} catch (err) {
|
|
@@ -1545,8 +1575,7 @@ async function configureClaudeCodeHosted(deps, input, signerCommand) {
|
|
|
1545
1575
|
restartRequired: true,
|
|
1546
1576
|
messages: [
|
|
1547
1577
|
"Updated hosted Haven MCP and local signer entries with Claude Code.",
|
|
1548
|
-
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1549
|
-
"After Haven approval, Haven tools should appear in your next Claude Code message. If they don't, restart the session to load them."
|
|
1578
|
+
...verified ? ["Verified Claude Code MCP entry."] : []
|
|
1550
1579
|
]
|
|
1551
1580
|
};
|
|
1552
1581
|
} catch (err) {
|
|
@@ -1674,7 +1703,7 @@ function localRuntimePrepareErrorCode(err) {
|
|
|
1674
1703
|
}
|
|
1675
1704
|
|
|
1676
1705
|
// src/runtime.ts
|
|
1677
|
-
var CONNECTOR_VERSION = "0.1.
|
|
1706
|
+
var CONNECTOR_VERSION = "0.1.17-alpha.0";
|
|
1678
1707
|
async function runConnect(options, deps = {}) {
|
|
1679
1708
|
const connectorVersion = options.connectorVersion ?? CONNECTOR_VERSION;
|
|
1680
1709
|
const api = deps.api ?? createConnectApiClient(options.apiBaseUrl);
|
|
@@ -1694,6 +1723,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1694
1723
|
);
|
|
1695
1724
|
}
|
|
1696
1725
|
}
|
|
1726
|
+
log("Warming up your connection to Haven\u2026");
|
|
1697
1727
|
const setup = await api.resolveSetup({
|
|
1698
1728
|
setupToken: options.setupToken,
|
|
1699
1729
|
connectorVersion,
|
|
@@ -1701,12 +1731,12 @@ async function runConnect(options, deps = {}) {
|
|
|
1701
1731
|
});
|
|
1702
1732
|
printSetupSummary(setup, log);
|
|
1703
1733
|
await preflightStorage({ baseDir: options.credentialsDir, warn: log });
|
|
1704
|
-
log("Checked local credential storage.");
|
|
1734
|
+
log("Checked local credential storage \u2014 all clear.");
|
|
1705
1735
|
const localKey = generateKey();
|
|
1706
1736
|
const localApiKey = generateLocalApiKey();
|
|
1707
|
-
log("
|
|
1708
|
-
log("Generated local Haven API key.");
|
|
1737
|
+
log("Minting a fresh signing key and API key \u2014 both stay on this machine.");
|
|
1709
1738
|
const proofSignature = await localKey.signChallenge(setup.challenge.message);
|
|
1739
|
+
log("Introducing your agent to Haven\u2026");
|
|
1710
1740
|
const registration = await api.registerSetup({
|
|
1711
1741
|
setupToken: options.setupToken,
|
|
1712
1742
|
connectorVersion,
|
|
@@ -1723,6 +1753,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1723
1753
|
installCapabilities
|
|
1724
1754
|
});
|
|
1725
1755
|
log(`Registered signing address with Haven: ${shortAddress(registration.delegate_address)}.`);
|
|
1756
|
+
log("Tucking your credentials away safely on disk\u2026");
|
|
1726
1757
|
const credentialPaths = await writeCredentials({
|
|
1727
1758
|
baseDir: options.credentialsDir,
|
|
1728
1759
|
agentId: registration.agent_id,
|
|
@@ -1744,6 +1775,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1744
1775
|
});
|
|
1745
1776
|
log(`Stored Haven identity credential locally: ${credentialPaths.identityPath}`);
|
|
1746
1777
|
log(`Stored local signer credential locally: ${credentialPaths.signerPath}`);
|
|
1778
|
+
log(`Stored non-secret agent orientation locally: ${credentialPaths.agentPath}`);
|
|
1747
1779
|
if (setup.x402_binding_signer) {
|
|
1748
1780
|
log("Configured x402 binding signer for the local signer.");
|
|
1749
1781
|
} else {
|
|
@@ -1762,8 +1794,14 @@ async function runConnect(options, deps = {}) {
|
|
|
1762
1794
|
ackSigner: options.ackSigner,
|
|
1763
1795
|
ackLocalTools: options.ackLocalTools,
|
|
1764
1796
|
localMcp: options.localMcp
|
|
1765
|
-
});
|
|
1797
|
+
}, { onProgress: log });
|
|
1766
1798
|
printRuntimeInstall(runtimeInstall, log);
|
|
1799
|
+
if (runtimeInstall.errorCode) {
|
|
1800
|
+
log("Haven setup needs a couple more steps on this machine \u2014 see the notes above.");
|
|
1801
|
+
} else {
|
|
1802
|
+
log("Haven setup on this machine is complete.");
|
|
1803
|
+
}
|
|
1804
|
+
printNextSteps(runtimeInstall, log);
|
|
1767
1805
|
try {
|
|
1768
1806
|
await api.updateInstallStatus(registration.setup_id, localApiKey, {
|
|
1769
1807
|
runtime: runtimeInstall.runtime,
|
|
@@ -1786,14 +1824,6 @@ async function runConnect(options, deps = {}) {
|
|
|
1786
1824
|
} catch (err) {
|
|
1787
1825
|
log(`Could not report install status to Haven: ${err instanceof Error ? err.message : String(err)}`);
|
|
1788
1826
|
}
|
|
1789
|
-
log("Return to Haven to approve the agent rules.");
|
|
1790
|
-
if (runtimeInstall.restartRequired) {
|
|
1791
|
-
if (runtimeRequiresHardRestart(runtimeInstall.runtime)) {
|
|
1792
|
-
log("After approval, restart this agent so it can load Haven tools.");
|
|
1793
|
-
} else {
|
|
1794
|
-
log("After approval, Haven tools should appear in your next message. If they don't, restart this agent to load them.");
|
|
1795
|
-
}
|
|
1796
|
-
}
|
|
1797
1827
|
return {
|
|
1798
1828
|
setupId: registration.setup_id,
|
|
1799
1829
|
agentId: registration.agent_id,
|
|
@@ -1831,6 +1861,18 @@ function printRuntimeInstall(result, log) {
|
|
|
1831
1861
|
log("Local Haven signer still needs runtime setup.");
|
|
1832
1862
|
}
|
|
1833
1863
|
}
|
|
1864
|
+
function printNextSteps(result, log) {
|
|
1865
|
+
log("Next: approve the agent rules in Haven. No Haven tools appear until you approve \u2014 restart or not.");
|
|
1866
|
+
if (result.restartRequired) {
|
|
1867
|
+
if (runtimeRequiresHardRestart(result.runtime)) {
|
|
1868
|
+
log("After you approve, restart this agent so it can load Haven tools.");
|
|
1869
|
+
} else {
|
|
1870
|
+
log("After you approve, restart this agent \u2014 your current session won't load the Haven tools until you do.");
|
|
1871
|
+
}
|
|
1872
|
+
} else {
|
|
1873
|
+
log("After you approve, the Haven tools should appear in this runtime shortly.");
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1834
1876
|
|
|
1835
1877
|
// src/args.ts
|
|
1836
1878
|
function parseArgs(argv, env = process.env) {
|