@haven_ai/connect 0.1.16-alpha.0 → 0.1.18-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.js CHANGED
@@ -230,9 +230,9 @@ var MCP_RUNTIME_MANIFEST = {
230
230
  mcpPackage: "@haven_ai/mcp",
231
231
  mcpVersion: MCP_VERSION,
232
232
  sdkPackage: "@haven_ai/sdk",
233
- sdkVersion: "0.1.16-alpha.0",
233
+ sdkVersion: "0.1.18-alpha.0",
234
234
  signerPackage: "@haven_ai/signer",
235
- signerVersion: "0.1.16-alpha.0",
235
+ signerVersion: "0.1.18-alpha.0",
236
236
  minimumNodeVersion: "20.0.0",
237
237
  supportedClients: ["codex-cli", "codex-desktop", "claude-code"],
238
238
  requiredTools: registeredToolNames()
@@ -247,117 +247,6 @@ function signerPackageSpec() {
247
247
  return `${MCP_RUNTIME_MANIFEST.signerPackage}@${MCP_RUNTIME_MANIFEST.signerVersion}`;
248
248
  }
249
249
 
250
- // src/runtime-registry.ts
251
- var RUNTIME_PROFILES = {
252
- "claude-code": {
253
- id: "claude-code",
254
- label: "Claude Code",
255
- restartMode: "restart-session",
256
- canWriteRuntimeConfig: true
257
- },
258
- "codex-cli": {
259
- id: "codex-cli",
260
- label: "Codex CLI",
261
- restartMode: "restart-session",
262
- canWriteRuntimeConfig: true
263
- },
264
- "codex-desktop": {
265
- id: "codex-desktop",
266
- label: "Codex Desktop",
267
- restartMode: "restart-session",
268
- canWriteRuntimeConfig: true
269
- },
270
- cursor: {
271
- id: "cursor",
272
- label: "Cursor",
273
- restartMode: "hot-reload",
274
- canWriteRuntimeConfig: true
275
- },
276
- vscode: {
277
- id: "vscode",
278
- label: "VS Code",
279
- restartMode: "hot-reload",
280
- canWriteRuntimeConfig: true
281
- },
282
- "vscode-insiders": {
283
- id: "vscode-insiders",
284
- label: "VS Code Insiders",
285
- restartMode: "hot-reload",
286
- canWriteRuntimeConfig: true
287
- },
288
- "claude-desktop": {
289
- id: "claude-desktop",
290
- label: "Claude Desktop",
291
- restartMode: "restart-app",
292
- canWriteRuntimeConfig: true
293
- },
294
- other: {
295
- id: "other",
296
- label: "Other agent runtime",
297
- restartMode: "manual",
298
- canWriteRuntimeConfig: false
299
- }
300
- };
301
- var RUNTIME_ALIASES = {
302
- claude: "claude-code",
303
- "claude-code": "claude-code",
304
- claudecode: "claude-code",
305
- "claude_code": "claude-code",
306
- codex: "codex-cli",
307
- "codex-cli": "codex-cli",
308
- codexcli: "codex-cli",
309
- "codex_cli": "codex-cli",
310
- "codex-desktop": "codex-desktop",
311
- "codex_desktop": "codex-desktop",
312
- codexdesktop: "codex-desktop",
313
- "codex-app": "codex-desktop",
314
- "codex_app": "codex-desktop",
315
- codexapp: "codex-desktop",
316
- cursor: "cursor",
317
- vscode: "vscode",
318
- "vs-code": "vscode",
319
- "vs_code": "vscode",
320
- code: "vscode",
321
- "vscode-insiders": "vscode-insiders",
322
- "vscode_insiders": "vscode-insiders",
323
- vscodeinsiders: "vscode-insiders",
324
- "vs-code-insiders": "vscode-insiders",
325
- "code-insiders": "vscode-insiders",
326
- insiders: "vscode-insiders",
327
- "claude-desktop": "claude-desktop",
328
- "claude_desktop": "claude-desktop",
329
- claudesktop: "claude-desktop",
330
- desktop: "claude-desktop",
331
- other: "other",
332
- manual: "other"
333
- };
334
- function runtimeProfile(runtime, env = process.env) {
335
- return RUNTIME_PROFILES[normalizeRuntime(runtime, env)];
336
- }
337
- function normalizeRuntime(runtime, env = process.env) {
338
- const explicit = normalizeRuntimeName(runtime);
339
- if (explicit) return explicit;
340
- return detectRuntime(env) ?? "other";
341
- }
342
- function restartRequiredForRuntime(runtime, env = process.env) {
343
- const mode = runtimeProfile(runtime, env).restartMode;
344
- return mode === "restart-session" || mode === "restart-app";
345
- }
346
- function runtimeRequiresHardRestart(runtime) {
347
- return runtime === "claude-desktop" || runtime === "codex-desktop";
348
- }
349
- function normalizeRuntimeName(runtime) {
350
- const key = runtime?.trim().toLowerCase();
351
- if (!key) return null;
352
- return RUNTIME_ALIASES[key.replace(/\s+/g, "-")] ?? null;
353
- }
354
- function detectRuntime(env) {
355
- if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return "claude-code";
356
- if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return "codex-cli";
357
- if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === "vscode") return "vscode";
358
- return null;
359
- }
360
-
361
250
  // src/config-writers.ts
362
251
  var InvalidCodexTomlError = class extends Error {
363
252
  constructor(message) {
@@ -504,7 +393,6 @@ async function writeJsonRuntimeConfig(input, target, serverRoot) {
504
393
  async function writeCodexConfig(input) {
505
394
  const target = codexConfigPath(input.homeDir);
506
395
  const local = input.mode === "local";
507
- 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.";
508
396
  try {
509
397
  const existing = await readOptional(target);
510
398
  if (local) {
@@ -522,11 +410,7 @@ async function writeCodexConfig(input) {
522
410
  changed: existing !== merged2,
523
411
  restartRequired: true,
524
412
  messages: [
525
- `Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}.`,
526
- // Codex Desktop loads MCP servers at app launch; Codex CLI typically
527
- // picks them up in the next session. Branch the copy so desktop users
528
- // get the unambiguous instruction.
529
- restartMessage
413
+ `Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}.`
530
414
  ]
531
415
  };
532
416
  }
@@ -541,8 +425,7 @@ async function writeCodexConfig(input) {
541
425
  changed: existing !== merged,
542
426
  restartRequired: true,
543
427
  messages: [
544
- `Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`,
545
- restartMessage
428
+ `Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`
546
429
  ]
547
430
  };
548
431
  } catch (err) {
@@ -1095,23 +978,29 @@ function parseNodeVersion(value) {
1095
978
  ];
1096
979
  }
1097
980
  async function installRuntimePackages(runtimeDirectory, npmCacheDirectory, runCommand) {
1098
- const args = [
981
+ const baseArgs = [
1099
982
  "install",
1100
983
  "--prefix",
1101
984
  runtimeDirectory,
1102
- "--cache",
1103
- npmCacheDirectory,
1104
985
  "--no-audit",
1105
986
  "--no-fund",
1106
987
  "--omit=dev",
988
+ "--prefer-offline",
1107
989
  mcpPackageSpec(),
1108
990
  sdkPackageSpec()
1109
991
  ];
1110
- try {
992
+ const run = async (args) => {
1111
993
  if (runCommand) await runCommand("npm", args);
1112
994
  else await execFileAsync("npm", args, { timeout: 12e4, maxBuffer: 1024 * 1024 });
1113
- } catch (err) {
1114
- throw new Error(`Could not install local Haven MCP runtime ${mcpPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`);
995
+ };
996
+ try {
997
+ await run(baseArgs);
998
+ } catch {
999
+ try {
1000
+ await run([...baseArgs, "--cache", npmCacheDirectory]);
1001
+ } catch (err) {
1002
+ throw new Error(`Could not install local Haven MCP runtime ${mcpPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`);
1003
+ }
1115
1004
  }
1116
1005
  }
1117
1006
  async function installedRuntimeMatches(runtimeDirectory, cliPath) {
@@ -1215,25 +1104,31 @@ async function prepareSignerRuntime(input, deps = {}) {
1215
1104
  };
1216
1105
  }
1217
1106
  async function installRuntimePackages2(runtimeDirectory, npmCacheDirectory, runCommand) {
1218
- const args = [
1107
+ const baseArgs = [
1219
1108
  "install",
1220
1109
  "--prefix",
1221
1110
  runtimeDirectory,
1222
- "--cache",
1223
- npmCacheDirectory,
1224
1111
  "--no-audit",
1225
1112
  "--no-fund",
1226
1113
  "--omit=dev",
1114
+ "--prefer-offline",
1227
1115
  signerPackageSpec(),
1228
1116
  sdkPackageSpec()
1229
1117
  ];
1230
- try {
1118
+ const run = async (args) => {
1231
1119
  if (runCommand) await runCommand("npm", args);
1232
1120
  else await execFileAsync2("npm", args, { timeout: 12e4, maxBuffer: 1024 * 1024 });
1233
- } catch (err) {
1234
- throw new Error(
1235
- `Could not install local Haven signer runtime ${signerPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`
1236
- );
1121
+ };
1122
+ try {
1123
+ await run(baseArgs);
1124
+ } catch {
1125
+ try {
1126
+ await run([...baseArgs, "--cache", npmCacheDirectory]);
1127
+ } catch (err) {
1128
+ throw new Error(
1129
+ `Could not install local Haven signer runtime ${signerPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`
1130
+ );
1131
+ }
1237
1132
  }
1238
1133
  }
1239
1134
  async function installedRuntimeMatches2(runtimeDirectory, cliPath) {
@@ -1296,6 +1191,117 @@ async function assertFileExists2(path, label) {
1296
1191
  throw new Error(`Missing ${label}: ${path}`);
1297
1192
  }
1298
1193
  }
1194
+
1195
+ // src/runtime-registry.ts
1196
+ var RUNTIME_PROFILES = {
1197
+ "claude-code": {
1198
+ id: "claude-code",
1199
+ label: "Claude Code",
1200
+ restartMode: "restart-session",
1201
+ canWriteRuntimeConfig: true
1202
+ },
1203
+ "codex-cli": {
1204
+ id: "codex-cli",
1205
+ label: "Codex CLI",
1206
+ restartMode: "restart-session",
1207
+ canWriteRuntimeConfig: true
1208
+ },
1209
+ "codex-desktop": {
1210
+ id: "codex-desktop",
1211
+ label: "Codex Desktop",
1212
+ restartMode: "restart-session",
1213
+ canWriteRuntimeConfig: true
1214
+ },
1215
+ cursor: {
1216
+ id: "cursor",
1217
+ label: "Cursor",
1218
+ restartMode: "hot-reload",
1219
+ canWriteRuntimeConfig: true
1220
+ },
1221
+ vscode: {
1222
+ id: "vscode",
1223
+ label: "VS Code",
1224
+ restartMode: "hot-reload",
1225
+ canWriteRuntimeConfig: true
1226
+ },
1227
+ "vscode-insiders": {
1228
+ id: "vscode-insiders",
1229
+ label: "VS Code Insiders",
1230
+ restartMode: "hot-reload",
1231
+ canWriteRuntimeConfig: true
1232
+ },
1233
+ "claude-desktop": {
1234
+ id: "claude-desktop",
1235
+ label: "Claude Desktop",
1236
+ restartMode: "restart-app",
1237
+ canWriteRuntimeConfig: true
1238
+ },
1239
+ other: {
1240
+ id: "other",
1241
+ label: "Other agent runtime",
1242
+ restartMode: "manual",
1243
+ canWriteRuntimeConfig: false
1244
+ }
1245
+ };
1246
+ var RUNTIME_ALIASES = {
1247
+ claude: "claude-code",
1248
+ "claude-code": "claude-code",
1249
+ claudecode: "claude-code",
1250
+ "claude_code": "claude-code",
1251
+ codex: "codex-cli",
1252
+ "codex-cli": "codex-cli",
1253
+ codexcli: "codex-cli",
1254
+ "codex_cli": "codex-cli",
1255
+ "codex-desktop": "codex-desktop",
1256
+ "codex_desktop": "codex-desktop",
1257
+ codexdesktop: "codex-desktop",
1258
+ "codex-app": "codex-desktop",
1259
+ "codex_app": "codex-desktop",
1260
+ codexapp: "codex-desktop",
1261
+ cursor: "cursor",
1262
+ vscode: "vscode",
1263
+ "vs-code": "vscode",
1264
+ "vs_code": "vscode",
1265
+ code: "vscode",
1266
+ "vscode-insiders": "vscode-insiders",
1267
+ "vscode_insiders": "vscode-insiders",
1268
+ vscodeinsiders: "vscode-insiders",
1269
+ "vs-code-insiders": "vscode-insiders",
1270
+ "code-insiders": "vscode-insiders",
1271
+ insiders: "vscode-insiders",
1272
+ "claude-desktop": "claude-desktop",
1273
+ "claude_desktop": "claude-desktop",
1274
+ claudesktop: "claude-desktop",
1275
+ desktop: "claude-desktop",
1276
+ other: "other",
1277
+ manual: "other"
1278
+ };
1279
+ function runtimeProfile(runtime, env = process.env) {
1280
+ return RUNTIME_PROFILES[normalizeRuntime(runtime, env)];
1281
+ }
1282
+ function normalizeRuntime(runtime, env = process.env) {
1283
+ const explicit = normalizeRuntimeName(runtime);
1284
+ if (explicit) return explicit;
1285
+ return detectRuntime(env) ?? "other";
1286
+ }
1287
+ function restartRequiredForRuntime(runtime, env = process.env) {
1288
+ const mode = runtimeProfile(runtime, env).restartMode;
1289
+ return mode === "restart-session" || mode === "restart-app";
1290
+ }
1291
+ function runtimeRequiresHardRestart(runtime) {
1292
+ return runtime === "claude-desktop" || runtime === "codex-desktop";
1293
+ }
1294
+ function normalizeRuntimeName(runtime) {
1295
+ const key = runtime?.trim().toLowerCase();
1296
+ if (!key) return null;
1297
+ return RUNTIME_ALIASES[key.replace(/\s+/g, "-")] ?? null;
1298
+ }
1299
+ function detectRuntime(env) {
1300
+ if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return "claude-code";
1301
+ if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return "codex-cli";
1302
+ if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === "vscode") return "vscode";
1303
+ return null;
1304
+ }
1299
1305
  async function acknowledgeLocalSignerConsent(signerPath, log) {
1300
1306
  try {
1301
1307
  const input = await buildSignerConsentInput(signerPath);
@@ -1371,6 +1377,7 @@ var execFileAsync3 = promisify(execFile);
1371
1377
  async function installRuntime(input, deps = {}) {
1372
1378
  const runtime = normalizeRuntime(input.runtime, deps.env);
1373
1379
  const profile = runtimeProfile(runtime, deps.env);
1380
+ const progress = deps.onProgress ?? (() => void 0);
1374
1381
  const localRuntime = input.localMcp === true && supportsLocalMcp(runtime);
1375
1382
  const consentMessages = [];
1376
1383
  const localMcpConsent = localRuntime ? await resolveLocalMcpConsent(input, consentMessages) : void 0;
@@ -1393,7 +1400,12 @@ async function installRuntime(input, deps = {}) {
1393
1400
  localMcpAcknowledged: false,
1394
1401
  messages: [
1395
1402
  ...consentMessages,
1396
- "Runtime was not recognized. Keep the local credentials and add Haven MCP entries manually after wallet approval."
1403
+ "Custom runtime: Haven did not auto-configure it. Your credentials are on disk (chmod 600) \u2014 read them at runtime; never paste a key into the agent prompt, memory, or logs.",
1404
+ ` identity (hosted MCP Bearer): ${input.identityPath}`,
1405
+ ` signer (local signing key): ${input.signerPath}`,
1406
+ "After wallet approval, wire the runtime to Haven by reference:",
1407
+ ` Hosted MCP + local signer: point your MCP client at ${input.hostedMcpUrl} with the api_key from identity.json, then run npx -y ${signerPackageSpec()} --credentials ${input.signerPath}`,
1408
+ ` Fully local MCP (no hosted dependency): npx -y ${mcpPackageSpec()} --identity ${input.identityPath} --signer ${input.signerPath}`
1397
1409
  ]
1398
1410
  };
1399
1411
  }
@@ -1430,6 +1442,7 @@ async function installRuntime(input, deps = {}) {
1430
1442
  }
1431
1443
  let signerCommand;
1432
1444
  if (!localRuntime) {
1445
+ progress("Getting the signer ready\u2026");
1433
1446
  try {
1434
1447
  const signerRuntime = await prepareSignerForRuntime(input, deps);
1435
1448
  signerCommand = { command: signerRuntime.command, args: signerRuntime.args };
@@ -1441,6 +1454,7 @@ async function installRuntime(input, deps = {}) {
1441
1454
  }
1442
1455
  }
1443
1456
  const signerRuntimePrepared = localRuntime ? void 0 : signerCommand !== void 0;
1457
+ progress("Setting up your Haven tools\u2026");
1444
1458
  const configResult = runtime === "claude-code" ? localRuntime ? await configureClaudeCode(deps, localRuntimeInstall?.command ?? "") : await configureClaudeCodeHosted(deps, input, signerCommand) : await writeRuntimeConfig({
1445
1459
  runtime,
1446
1460
  hostedMcpUrl: input.hostedMcpUrl,
@@ -1453,6 +1467,7 @@ async function installRuntime(input, deps = {}) {
1453
1467
  homeDir: deps.homeDir,
1454
1468
  mode: localRuntime ? "local" : "hosted"
1455
1469
  });
1470
+ progress("Almost there \u2014 just confirming everything connects\u2026");
1456
1471
  const localProbePromise = configResult.runtimeMcpMode === "local_stdio" && localRuntimeInstall ? runLocalMcpProbe(localRuntimeInstall, deps) : Promise.resolve(void 0);
1457
1472
  const [hostedProbe, signerCredentialReady, localMcpProbe] = await Promise.all([
1458
1473
  configResult.hostedConfigured ? probeHostedMcpTools(input.apiKey, input.hostedMcpUrl, deps.fetch) : Promise.resolve({ status: "bad_response" }),
@@ -1517,8 +1532,7 @@ async function configureClaudeCode(deps, localMcpCommand) {
1517
1532
  restartRequired: true,
1518
1533
  messages: [
1519
1534
  "Updated local Haven MCP entry with Claude Code.",
1520
- ...verified ? ["Verified Claude Code MCP entry."] : [],
1521
- "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."] : []
1522
1536
  ]
1523
1537
  };
1524
1538
  } catch (err) {
@@ -1567,8 +1581,7 @@ async function configureClaudeCodeHosted(deps, input, signerCommand) {
1567
1581
  restartRequired: true,
1568
1582
  messages: [
1569
1583
  "Updated hosted Haven MCP and local signer entries with Claude Code.",
1570
- ...verified ? ["Verified Claude Code MCP entry."] : [],
1571
- "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."] : []
1572
1585
  ]
1573
1586
  };
1574
1587
  } catch (err) {
@@ -1696,7 +1709,7 @@ function localRuntimePrepareErrorCode(err) {
1696
1709
  }
1697
1710
 
1698
1711
  // src/runtime.ts
1699
- var CONNECTOR_VERSION = "0.1.16-alpha.0";
1712
+ var CONNECTOR_VERSION = "0.1.18-alpha.0";
1700
1713
  async function runConnect(options, deps = {}) {
1701
1714
  const connectorVersion = options.connectorVersion ?? CONNECTOR_VERSION;
1702
1715
  const api = deps.api ?? createConnectApiClient(options.apiBaseUrl);
@@ -1716,6 +1729,7 @@ async function runConnect(options, deps = {}) {
1716
1729
  );
1717
1730
  }
1718
1731
  }
1732
+ log("Warming up your connection to Haven\u2026");
1719
1733
  const setup = await api.resolveSetup({
1720
1734
  setupToken: options.setupToken,
1721
1735
  connectorVersion,
@@ -1723,12 +1737,12 @@ async function runConnect(options, deps = {}) {
1723
1737
  });
1724
1738
  printSetupSummary(setup, log);
1725
1739
  await preflightStorage({ baseDir: options.credentialsDir, warn: log });
1726
- log("Checked local credential storage.");
1740
+ log("Checked local credential storage \u2014 all clear.");
1727
1741
  const localKey = generateKey();
1728
1742
  const localApiKey = generateLocalApiKey();
1729
- log("Generated local signing key.");
1730
- log("Generated local Haven API key.");
1743
+ log("Minting a fresh signing key and API key \u2014 both stay on this machine.");
1731
1744
  const proofSignature = await localKey.signChallenge(setup.challenge.message);
1745
+ log("Introducing your agent to Haven\u2026");
1732
1746
  const registration = await api.registerSetup({
1733
1747
  setupToken: options.setupToken,
1734
1748
  connectorVersion,
@@ -1745,6 +1759,7 @@ async function runConnect(options, deps = {}) {
1745
1759
  installCapabilities
1746
1760
  });
1747
1761
  log(`Registered signing address with Haven: ${shortAddress(registration.delegate_address)}.`);
1762
+ log("Tucking your credentials away safely on disk\u2026");
1748
1763
  const credentialPaths = await writeCredentials({
1749
1764
  baseDir: options.credentialsDir,
1750
1765
  agentId: registration.agent_id,
@@ -1785,8 +1800,14 @@ async function runConnect(options, deps = {}) {
1785
1800
  ackSigner: options.ackSigner,
1786
1801
  ackLocalTools: options.ackLocalTools,
1787
1802
  localMcp: options.localMcp
1788
- });
1803
+ }, { onProgress: log });
1789
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);
1790
1811
  try {
1791
1812
  await api.updateInstallStatus(registration.setup_id, localApiKey, {
1792
1813
  runtime: runtimeInstall.runtime,
@@ -1809,14 +1830,6 @@ async function runConnect(options, deps = {}) {
1809
1830
  } catch (err) {
1810
1831
  log(`Could not report install status to Haven: ${err instanceof Error ? err.message : String(err)}`);
1811
1832
  }
1812
- log("Return to Haven to approve the agent rules.");
1813
- if (runtimeInstall.restartRequired) {
1814
- if (runtimeRequiresHardRestart(runtimeInstall.runtime)) {
1815
- log("After approval, restart this agent so it can load Haven tools.");
1816
- } else {
1817
- log("After approval, Haven tools should appear in your next message. If they don't, restart this agent to load them.");
1818
- }
1819
- }
1820
1833
  return {
1821
1834
  setupId: registration.setup_id,
1822
1835
  agentId: registration.agent_id,
@@ -1854,6 +1867,18 @@ function printRuntimeInstall(result, log) {
1854
1867
  log("Local Haven signer still needs runtime setup.");
1855
1868
  }
1856
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
+ }
1857
1882
 
1858
1883
  // src/args.ts
1859
1884
  function parseArgs(argv, env = process.env) {