@haven_ai/connect 0.1.5-alpha → 0.1.10-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/README.md +1 -1
- package/dist/cli.cjs +146 -22
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +146 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +150 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +147 -23
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -31,6 +31,7 @@ interface UpdateInstallStatusInput {
|
|
|
31
31
|
signerAcknowledged?: boolean;
|
|
32
32
|
localMcpAcknowledged?: boolean;
|
|
33
33
|
activationCommandAvailable?: boolean;
|
|
34
|
+
skillInstalled?: boolean;
|
|
34
35
|
probeResult: string;
|
|
35
36
|
restartRequired: boolean;
|
|
36
37
|
nextUserAction: string;
|
|
@@ -167,6 +168,12 @@ interface RuntimeInstallInput {
|
|
|
167
168
|
environmentLabel?: string;
|
|
168
169
|
ackSigner?: boolean;
|
|
169
170
|
ackLocalTools?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Explicit opt-in to the local-stdio MCP topology (zero hosted dependency).
|
|
173
|
+
* Default is hosted MCP + local signer for every runtime; local MCP is only
|
|
174
|
+
* used when this is true and the runtime supports it.
|
|
175
|
+
*/
|
|
176
|
+
localMcp?: boolean;
|
|
170
177
|
}
|
|
171
178
|
interface RuntimeInstallResult {
|
|
172
179
|
runtime: RuntimeId;
|
|
@@ -183,6 +190,7 @@ interface RuntimeInstallResult {
|
|
|
183
190
|
signerAcknowledged?: boolean;
|
|
184
191
|
localMcpAcknowledged?: boolean;
|
|
185
192
|
activationCommand?: string;
|
|
193
|
+
skillInstalled?: boolean;
|
|
186
194
|
messages: string[];
|
|
187
195
|
}
|
|
188
196
|
interface RuntimeInstallDeps {
|
|
@@ -209,6 +217,7 @@ interface ConnectOptions {
|
|
|
209
217
|
connectorVersion?: string;
|
|
210
218
|
ackSigner?: boolean;
|
|
211
219
|
ackLocalTools?: boolean;
|
|
220
|
+
localMcp?: boolean;
|
|
212
221
|
}
|
|
213
222
|
interface ConnectDeps {
|
|
214
223
|
api?: ConnectApiClient;
|
|
@@ -237,4 +246,19 @@ declare function helpText(): string;
|
|
|
237
246
|
declare function redactSecrets(value: string): string;
|
|
238
247
|
declare function shortAddress(address: string): string;
|
|
239
248
|
|
|
240
|
-
|
|
249
|
+
declare const MCP_RUNTIME_MANIFEST: {
|
|
250
|
+
readonly mcpPackage: "@haven_ai/mcp";
|
|
251
|
+
readonly mcpVersion: "0.1.10-alpha.0";
|
|
252
|
+
readonly sdkPackage: "@haven_ai/sdk";
|
|
253
|
+
readonly sdkVersion: "0.1.10-alpha.0";
|
|
254
|
+
readonly signerPackage: "@haven_ai/signer";
|
|
255
|
+
readonly signerVersion: "0.1.10-alpha.0";
|
|
256
|
+
readonly minimumNodeVersion: "20.0.0";
|
|
257
|
+
readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
|
|
258
|
+
readonly requiredTools: readonly string[];
|
|
259
|
+
};
|
|
260
|
+
declare function mcpPackageSpec(): string;
|
|
261
|
+
declare function sdkPackageSpec(): string;
|
|
262
|
+
declare function signerPackageSpec(): string;
|
|
263
|
+
|
|
264
|
+
export { CONNECTOR_VERSION, type ConnectApiClient, type ConnectDeps, type ConnectOptions, type ConnectResult, type LocalDelegateKey, MCP_RUNTIME_MANIFEST, type RegisterSetupInput, type RegisterSetupResponse, type ResolveSetupInput, type ResolvedSetup, type RuntimeId, type RuntimeInstallInput, type RuntimeInstallResult, type RuntimeProfile, type StoredCredentialPaths, type UpdateInstallStatusInput, type WriteCredentialInput, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, generateDelegateKey, helpText, installRuntime, mcpPackageSpec, normalizeRuntime, parseArgs, redactSecrets, runConnect, runtimeInstallCapabilities, runtimeProfile, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ interface UpdateInstallStatusInput {
|
|
|
31
31
|
signerAcknowledged?: boolean;
|
|
32
32
|
localMcpAcknowledged?: boolean;
|
|
33
33
|
activationCommandAvailable?: boolean;
|
|
34
|
+
skillInstalled?: boolean;
|
|
34
35
|
probeResult: string;
|
|
35
36
|
restartRequired: boolean;
|
|
36
37
|
nextUserAction: string;
|
|
@@ -167,6 +168,12 @@ interface RuntimeInstallInput {
|
|
|
167
168
|
environmentLabel?: string;
|
|
168
169
|
ackSigner?: boolean;
|
|
169
170
|
ackLocalTools?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Explicit opt-in to the local-stdio MCP topology (zero hosted dependency).
|
|
173
|
+
* Default is hosted MCP + local signer for every runtime; local MCP is only
|
|
174
|
+
* used when this is true and the runtime supports it.
|
|
175
|
+
*/
|
|
176
|
+
localMcp?: boolean;
|
|
170
177
|
}
|
|
171
178
|
interface RuntimeInstallResult {
|
|
172
179
|
runtime: RuntimeId;
|
|
@@ -183,6 +190,7 @@ interface RuntimeInstallResult {
|
|
|
183
190
|
signerAcknowledged?: boolean;
|
|
184
191
|
localMcpAcknowledged?: boolean;
|
|
185
192
|
activationCommand?: string;
|
|
193
|
+
skillInstalled?: boolean;
|
|
186
194
|
messages: string[];
|
|
187
195
|
}
|
|
188
196
|
interface RuntimeInstallDeps {
|
|
@@ -209,6 +217,7 @@ interface ConnectOptions {
|
|
|
209
217
|
connectorVersion?: string;
|
|
210
218
|
ackSigner?: boolean;
|
|
211
219
|
ackLocalTools?: boolean;
|
|
220
|
+
localMcp?: boolean;
|
|
212
221
|
}
|
|
213
222
|
interface ConnectDeps {
|
|
214
223
|
api?: ConnectApiClient;
|
|
@@ -237,4 +246,19 @@ declare function helpText(): string;
|
|
|
237
246
|
declare function redactSecrets(value: string): string;
|
|
238
247
|
declare function shortAddress(address: string): string;
|
|
239
248
|
|
|
240
|
-
|
|
249
|
+
declare const MCP_RUNTIME_MANIFEST: {
|
|
250
|
+
readonly mcpPackage: "@haven_ai/mcp";
|
|
251
|
+
readonly mcpVersion: "0.1.10-alpha.0";
|
|
252
|
+
readonly sdkPackage: "@haven_ai/sdk";
|
|
253
|
+
readonly sdkVersion: "0.1.10-alpha.0";
|
|
254
|
+
readonly signerPackage: "@haven_ai/signer";
|
|
255
|
+
readonly signerVersion: "0.1.10-alpha.0";
|
|
256
|
+
readonly minimumNodeVersion: "20.0.0";
|
|
257
|
+
readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
|
|
258
|
+
readonly requiredTools: readonly string[];
|
|
259
|
+
};
|
|
260
|
+
declare function mcpPackageSpec(): string;
|
|
261
|
+
declare function sdkPackageSpec(): string;
|
|
262
|
+
declare function signerPackageSpec(): string;
|
|
263
|
+
|
|
264
|
+
export { CONNECTOR_VERSION, type ConnectApiClient, type ConnectDeps, type ConnectOptions, type ConnectResult, type LocalDelegateKey, MCP_RUNTIME_MANIFEST, type RegisterSetupInput, type RegisterSetupResponse, type ResolveSetupInput, type ResolvedSetup, type RuntimeId, type RuntimeInstallInput, type RuntimeInstallResult, type RuntimeProfile, type StoredCredentialPaths, type UpdateInstallStatusInput, type WriteCredentialInput, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, generateDelegateKey, helpText, installRuntime, mcpPackageSpec, normalizeRuntime, parseArgs, redactSecrets, runConnect, runtimeInstallCapabilities, runtimeProfile, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { join, resolve, dirname } from 'path';
|
|
|
6
6
|
import { execFile, spawn } from 'child_process';
|
|
7
7
|
import { promisify } from 'util';
|
|
8
8
|
import { registeredToolNames, MCP_VERSION, ensureConsent, computeConsentHash, loadCredentials, consentInputFromClient } from '@haven_ai/mcp';
|
|
9
|
+
import { SKILL_FOLDER_NAME, HAVEN_SKILL_MD } from '@haven_ai/sdk';
|
|
9
10
|
import { ensureSignerConsent, computeSignerConsentHash, loadSignerCredentials, createEdgeSigner, toolSchemas } from '@haven_ai/signer';
|
|
10
11
|
|
|
11
12
|
// src/api.ts
|
|
@@ -53,6 +54,7 @@ function createConnectApiClient(baseUrl, fetchImpl = fetch) {
|
|
|
53
54
|
signer_acknowledged: input.signerAcknowledged,
|
|
54
55
|
local_mcp_acknowledged: input.localMcpAcknowledged,
|
|
55
56
|
activation_command_available: input.activationCommandAvailable,
|
|
57
|
+
skill_installed: input.skillInstalled,
|
|
56
58
|
probe_result: input.probeResult,
|
|
57
59
|
restart_required: input.restartRequired,
|
|
58
60
|
next_user_action: input.nextUserAction,
|
|
@@ -205,9 +207,9 @@ var MCP_RUNTIME_MANIFEST = {
|
|
|
205
207
|
mcpPackage: "@haven_ai/mcp",
|
|
206
208
|
mcpVersion: MCP_VERSION,
|
|
207
209
|
sdkPackage: "@haven_ai/sdk",
|
|
208
|
-
sdkVersion: "0.1.
|
|
210
|
+
sdkVersion: "0.1.10-alpha.0",
|
|
209
211
|
signerPackage: "@haven_ai/signer",
|
|
210
|
-
signerVersion: "0.1.
|
|
212
|
+
signerVersion: "0.1.10-alpha.0",
|
|
211
213
|
minimumNodeVersion: "20.0.0",
|
|
212
214
|
supportedClients: ["codex-cli", "codex-desktop", "claude-code"],
|
|
213
215
|
requiredTools: registeredToolNames()
|
|
@@ -412,6 +414,26 @@ function mergeCodexToml(existingToml, localMcpCommand) {
|
|
|
412
414
|
validateCodexToml(block, "Generated Codex Haven config");
|
|
413
415
|
const merged = `${next ? `${next}
|
|
414
416
|
|
|
417
|
+
` : ""}${block}
|
|
418
|
+
`;
|
|
419
|
+
return merged;
|
|
420
|
+
}
|
|
421
|
+
function mergeCodexTomlHosted(existingToml, hostedMcpUrl, apiKey, signerPath) {
|
|
422
|
+
let next = removeTomlTableTree(removeTomlTableTree(existingToml, "mcp_servers.haven"), "mcp_servers.haven_signer");
|
|
423
|
+
next = next.trimEnd();
|
|
424
|
+
const block = [
|
|
425
|
+
"[mcp_servers.haven]",
|
|
426
|
+
`url = ${tomlString(hostedMcpUrl)}`,
|
|
427
|
+
`http_headers = { "Authorization" = ${tomlString(`Bearer ${apiKey}`)} }`,
|
|
428
|
+
"",
|
|
429
|
+
"[mcp_servers.haven_signer]",
|
|
430
|
+
'command = "npx"',
|
|
431
|
+
`args = ["-y", ${tomlString(signerPackageSpec())}, "--credentials", ${tomlString(signerPath)}]`,
|
|
432
|
+
"startup_timeout_sec = 120"
|
|
433
|
+
].join("\n");
|
|
434
|
+
validateCodexToml(block, "Generated Codex Haven config");
|
|
435
|
+
const merged = `${next ? `${next}
|
|
436
|
+
|
|
415
437
|
` : ""}${block}
|
|
416
438
|
`;
|
|
417
439
|
return merged;
|
|
@@ -452,27 +474,46 @@ async function writeJsonRuntimeConfig(input, target, serverRoot) {
|
|
|
452
474
|
}
|
|
453
475
|
async function writeCodexConfig(input) {
|
|
454
476
|
const target = codexConfigPath(input.homeDir);
|
|
477
|
+
const local = input.mode === "local";
|
|
478
|
+
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.";
|
|
455
479
|
try {
|
|
456
480
|
const existing = await readOptional(target);
|
|
457
|
-
if (
|
|
458
|
-
|
|
481
|
+
if (local) {
|
|
482
|
+
if (!input.localMcpCommand) {
|
|
483
|
+
throw new Error("local MCP wrapper command is required");
|
|
484
|
+
}
|
|
485
|
+
const merged2 = mergeCodexToml(existing ?? "", input.localMcpCommand);
|
|
486
|
+
await writeOwnerOnlyText(target, merged2);
|
|
487
|
+
return {
|
|
488
|
+
hostedConfigured: false,
|
|
489
|
+
signerConfigured: true,
|
|
490
|
+
localMcpConfigured: true,
|
|
491
|
+
runtimeMcpMode: "local_stdio",
|
|
492
|
+
target: configTargetLabel(input.runtime),
|
|
493
|
+
changed: existing !== merged2,
|
|
494
|
+
restartRequired: true,
|
|
495
|
+
messages: [
|
|
496
|
+
`Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}.`,
|
|
497
|
+
// Codex Desktop loads MCP servers at app launch; Codex CLI typically
|
|
498
|
+
// picks them up in the next session. Branch the copy so desktop users
|
|
499
|
+
// get the unambiguous instruction.
|
|
500
|
+
restartMessage
|
|
501
|
+
]
|
|
502
|
+
};
|
|
459
503
|
}
|
|
460
|
-
const merged =
|
|
504
|
+
const merged = mergeCodexTomlHosted(existing ?? "", input.hostedMcpUrl, input.apiKey, input.signerPath);
|
|
461
505
|
await writeOwnerOnlyText(target, merged);
|
|
462
506
|
return {
|
|
463
|
-
hostedConfigured:
|
|
507
|
+
hostedConfigured: true,
|
|
464
508
|
signerConfigured: true,
|
|
465
|
-
localMcpConfigured:
|
|
466
|
-
runtimeMcpMode: "
|
|
509
|
+
localMcpConfigured: false,
|
|
510
|
+
runtimeMcpMode: "hosted_plus_signer",
|
|
467
511
|
target: configTargetLabel(input.runtime),
|
|
468
512
|
changed: existing !== merged,
|
|
469
513
|
restartRequired: true,
|
|
470
514
|
messages: [
|
|
471
|
-
`Updated
|
|
472
|
-
|
|
473
|
-
// picks them up in the next session. Branch the copy so desktop users
|
|
474
|
-
// get the unambiguous instruction.
|
|
475
|
-
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."
|
|
515
|
+
`Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`,
|
|
516
|
+
restartMessage
|
|
476
517
|
]
|
|
477
518
|
};
|
|
478
519
|
} catch (err) {
|
|
@@ -481,7 +522,7 @@ async function writeCodexConfig(input) {
|
|
|
481
522
|
hostedConfigured: false,
|
|
482
523
|
signerConfigured: false,
|
|
483
524
|
localMcpConfigured: false,
|
|
484
|
-
runtimeMcpMode: "local_stdio",
|
|
525
|
+
runtimeMcpMode: local ? "local_stdio" : "hosted_plus_signer",
|
|
485
526
|
target: configTargetLabel(input.runtime),
|
|
486
527
|
changed: false,
|
|
487
528
|
restartRequired: true,
|
|
@@ -861,7 +902,7 @@ async function probeLocalSignerCredential(signerPath) {
|
|
|
861
902
|
}
|
|
862
903
|
}
|
|
863
904
|
async function probeLocalMcpTools(command, args, requiredTools, timeoutMs = 1e4) {
|
|
864
|
-
return new Promise((
|
|
905
|
+
return new Promise((resolve7) => {
|
|
865
906
|
const child = spawn(command, args, { stdio: ["pipe", "pipe", "ignore"] });
|
|
866
907
|
let stdout = "";
|
|
867
908
|
let settled = false;
|
|
@@ -871,7 +912,7 @@ async function probeLocalMcpTools(command, args, requiredTools, timeoutMs = 1e4)
|
|
|
871
912
|
settled = true;
|
|
872
913
|
clearTimeout(timeout);
|
|
873
914
|
child.kill();
|
|
874
|
-
|
|
915
|
+
resolve7(result);
|
|
875
916
|
};
|
|
876
917
|
const timeout = setTimeout(() => finish({ status: "timeout" }), timeoutMs);
|
|
877
918
|
child.on("error", () => finish({ status: "process_error" }));
|
|
@@ -1184,7 +1225,7 @@ var execFileAsync2 = promisify(execFile);
|
|
|
1184
1225
|
async function installRuntime(input, deps = {}) {
|
|
1185
1226
|
const runtime = normalizeRuntime(input.runtime, deps.env);
|
|
1186
1227
|
const profile = runtimeProfile(runtime, deps.env);
|
|
1187
|
-
const localRuntime =
|
|
1228
|
+
const localRuntime = input.localMcp === true && supportsLocalMcp(runtime);
|
|
1188
1229
|
const consentMessages = [];
|
|
1189
1230
|
const localMcpConsent = localRuntime ? await resolveLocalMcpConsent(input, consentMessages) : void 0;
|
|
1190
1231
|
const signerConsent = localRuntime ? void 0 : await resolveSignerConsent(input, consentMessages);
|
|
@@ -1241,7 +1282,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1241
1282
|
]
|
|
1242
1283
|
};
|
|
1243
1284
|
}
|
|
1244
|
-
const configResult = runtime === "claude-code" ? await configureClaudeCode(deps, localRuntimeInstall?.command ?? "") : await writeRuntimeConfig({
|
|
1285
|
+
const configResult = runtime === "claude-code" ? localRuntime ? await configureClaudeCode(deps, localRuntimeInstall?.command ?? "") : await configureClaudeCodeHosted(deps, input) : await writeRuntimeConfig({
|
|
1245
1286
|
runtime,
|
|
1246
1287
|
hostedMcpUrl: input.hostedMcpUrl,
|
|
1247
1288
|
apiKey: input.apiKey,
|
|
@@ -1249,7 +1290,8 @@ async function installRuntime(input, deps = {}) {
|
|
|
1249
1290
|
signerPath: input.signerPath,
|
|
1250
1291
|
credentialDirectory: input.credentialDirectory,
|
|
1251
1292
|
localMcpCommand: localRuntimeInstall?.command,
|
|
1252
|
-
homeDir: deps.homeDir
|
|
1293
|
+
homeDir: deps.homeDir,
|
|
1294
|
+
mode: localRuntime ? "local" : "hosted"
|
|
1253
1295
|
});
|
|
1254
1296
|
const localProbePromise = configResult.runtimeMcpMode === "local_stdio" && localRuntimeInstall ? runLocalMcpProbe(localRuntimeInstall, deps) : Promise.resolve(void 0);
|
|
1255
1297
|
const [hostedProbe, signerCredentialReady, localMcpProbe] = await Promise.all([
|
|
@@ -1263,6 +1305,7 @@ async function installRuntime(input, deps = {}) {
|
|
|
1263
1305
|
const restartRequired = configResult.restartRequired || restartRequiredForRuntime(runtime, deps.env);
|
|
1264
1306
|
const errorCode = configResult.errorCode ?? (configResult.runtimeMcpMode === "local_stdio" ? localMcpErrorCode(signerCredentialReady, localMcpConsent, localMcpProbe?.status) : signerConsentErrorCode(signerCredentialReady, signerConsent));
|
|
1265
1307
|
const localProbeMessages = localMcpProbe && localMcpProbe.status !== "ok" ? [`Local Haven MCP handshake failed: ${localMcpProbe.status}.`] : localMcpProbe?.status === "ok" ? ["Verified local Haven MCP tools with a stdio handshake."] : [];
|
|
1308
|
+
const skillInstall = runtime === "claude-code" && !configResult.errorCode ? await installClaudeSkill(deps.homeDir) : void 0;
|
|
1266
1309
|
return {
|
|
1267
1310
|
runtime,
|
|
1268
1311
|
runtimeMcpMode: configResult.runtimeMcpMode,
|
|
@@ -1277,7 +1320,8 @@ async function installRuntime(input, deps = {}) {
|
|
|
1277
1320
|
signerAcknowledged: signerConsent?.acknowledged,
|
|
1278
1321
|
localMcpAcknowledged: localMcpConsent?.acknowledged,
|
|
1279
1322
|
activationCommand: configResult.activationCommand,
|
|
1280
|
-
|
|
1323
|
+
skillInstalled: skillInstall?.installed,
|
|
1324
|
+
messages: [...consentMessages, ...localRuntimeInstall?.messages ?? [], ...configResult.messages, ...localProbeMessages, ...skillInstall?.messages ?? []]
|
|
1281
1325
|
};
|
|
1282
1326
|
}
|
|
1283
1327
|
function runtimeInstallCapabilities(runtime, env = process.env) {
|
|
@@ -1333,9 +1377,75 @@ async function configureClaudeCode(deps, localMcpCommand) {
|
|
|
1333
1377
|
};
|
|
1334
1378
|
}
|
|
1335
1379
|
}
|
|
1380
|
+
async function configureClaudeCodeHosted(deps, input) {
|
|
1381
|
+
const runCommand = deps.runCommand ?? defaultRunCommand;
|
|
1382
|
+
const hostedJson = JSON.stringify({
|
|
1383
|
+
type: "http",
|
|
1384
|
+
url: input.hostedMcpUrl,
|
|
1385
|
+
headers: { Authorization: `Bearer ${input.apiKey}` }
|
|
1386
|
+
});
|
|
1387
|
+
const signerJson = JSON.stringify({
|
|
1388
|
+
type: "stdio",
|
|
1389
|
+
command: "npx",
|
|
1390
|
+
args: ["-y", signerPackageSpec(), "--credentials", input.signerPath],
|
|
1391
|
+
env: {}
|
|
1392
|
+
});
|
|
1393
|
+
try {
|
|
1394
|
+
await runCommand("claude", ["mcp", "remove", "haven"]).catch(() => void 0);
|
|
1395
|
+
await runCommand("claude", ["mcp", "remove", "haven-signer"]).catch(() => void 0);
|
|
1396
|
+
await runCommand("claude", ["mcp", "add-json", "haven", hostedJson, "--scope", "user"]);
|
|
1397
|
+
await runCommand("claude", ["mcp", "add-json", "haven-signer", signerJson, "--scope", "user"]);
|
|
1398
|
+
const verified = await runCommand("claude", ["mcp", "get", "haven"]).then(() => true).catch(() => false);
|
|
1399
|
+
return {
|
|
1400
|
+
hostedConfigured: true,
|
|
1401
|
+
signerConfigured: true,
|
|
1402
|
+
localMcpConfigured: false,
|
|
1403
|
+
runtimeMcpMode: "hosted_plus_signer",
|
|
1404
|
+
target: "Claude Code MCP config",
|
|
1405
|
+
changed: true,
|
|
1406
|
+
restartRequired: true,
|
|
1407
|
+
messages: [
|
|
1408
|
+
"Updated hosted Haven MCP and local signer entries with Claude Code.",
|
|
1409
|
+
...verified ? ["Verified Claude Code MCP entry."] : [],
|
|
1410
|
+
"After Haven approval, Haven tools should appear in your next Claude Code message. If they don't, restart the session to load them."
|
|
1411
|
+
]
|
|
1412
|
+
};
|
|
1413
|
+
} catch (err) {
|
|
1414
|
+
return {
|
|
1415
|
+
hostedConfigured: false,
|
|
1416
|
+
signerConfigured: false,
|
|
1417
|
+
localMcpConfigured: false,
|
|
1418
|
+
runtimeMcpMode: "hosted_plus_signer",
|
|
1419
|
+
target: "Claude Code MCP config",
|
|
1420
|
+
changed: false,
|
|
1421
|
+
restartRequired: true,
|
|
1422
|
+
messages: [
|
|
1423
|
+
`Could not update Claude Code MCP config: ${err instanceof Error ? err.message : String(err)}`,
|
|
1424
|
+
"Install Claude Code or rerun the Haven setup command inside a Claude Code terminal."
|
|
1425
|
+
],
|
|
1426
|
+
errorCode: "claude_code_config_failed"
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1336
1430
|
async function defaultRunCommand(command, args) {
|
|
1337
1431
|
await execFileAsync2(command, args, { timeout: 1e4 });
|
|
1338
1432
|
}
|
|
1433
|
+
async function installClaudeSkill(homeDir) {
|
|
1434
|
+
try {
|
|
1435
|
+
const skillDir = resolve(homeDir ?? homedir(), ".claude", "skills", SKILL_FOLDER_NAME);
|
|
1436
|
+
await mkdir(skillDir, { recursive: true });
|
|
1437
|
+
await writeFile(join(skillDir, "SKILL.md"), HAVEN_SKILL_MD, "utf8");
|
|
1438
|
+
return {
|
|
1439
|
+
installed: true,
|
|
1440
|
+
messages: ["Installed the generic Haven payment skill (~/.claude/skills/haven-pay). It contains no secrets."]
|
|
1441
|
+
};
|
|
1442
|
+
} catch (err) {
|
|
1443
|
+
return {
|
|
1444
|
+
installed: false,
|
|
1445
|
+
messages: [`Could not install the Haven payment skill: ${err instanceof Error ? err.message : String(err)}. Download it from the Haven dashboard instead.`]
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1339
1449
|
function buildProbeResult(mode, hostedConfigured, hostedStatus, signerReady, localMcpReady, localMcpProbeStatus) {
|
|
1340
1450
|
if (mode === "local_stdio") {
|
|
1341
1451
|
if (localMcpReady) return "local_stdio_mcp_ready";
|
|
@@ -1389,7 +1499,7 @@ function nextAction(runtime, restartMode, errorCode) {
|
|
|
1389
1499
|
if (restartMode === "restart-session") return "return_to_haven_for_wallet_approval_then_restart_agent_session";
|
|
1390
1500
|
return "return_to_haven_for_wallet_approval_then_configure_runtime";
|
|
1391
1501
|
}
|
|
1392
|
-
function
|
|
1502
|
+
function supportsLocalMcp(runtime) {
|
|
1393
1503
|
return runtime === "codex-cli" || runtime === "codex-desktop" || runtime === "claude-code";
|
|
1394
1504
|
}
|
|
1395
1505
|
async function prepareRuntimeForLocalMcp(input, deps) {
|
|
@@ -1429,6 +1539,14 @@ async function runConnect(options, deps = {}) {
|
|
|
1429
1539
|
const generateKey = deps.generateKey ?? generateDelegateKey;
|
|
1430
1540
|
const generateLocalApiKey = deps.generateApiKey ?? generateAgentApiKey;
|
|
1431
1541
|
const installCapabilities = runtimeInstallCapabilities(options.runtime);
|
|
1542
|
+
if (options.localMcp) {
|
|
1543
|
+
const resolvedRuntime = normalizeRuntime(options.runtime);
|
|
1544
|
+
if (!supportsLocalMcp(resolvedRuntime)) {
|
|
1545
|
+
throw new Error(
|
|
1546
|
+
`--local (fully-local Haven MCP) is only available for Claude Code and Codex. The detected runtime is ${runtimeProfile(resolvedRuntime).label}. Re-run without --local to use the default hosted MCP + local signer setup.`
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1432
1550
|
const setup = await api.resolveSetup({
|
|
1433
1551
|
setupToken: options.setupToken,
|
|
1434
1552
|
connectorVersion,
|
|
@@ -1487,7 +1605,8 @@ async function runConnect(options, deps = {}) {
|
|
|
1487
1605
|
credentialDirectory: credentialPaths.directory,
|
|
1488
1606
|
environmentLabel: options.environmentLabel ?? "Local workspace",
|
|
1489
1607
|
ackSigner: options.ackSigner,
|
|
1490
|
-
ackLocalTools: options.ackLocalTools
|
|
1608
|
+
ackLocalTools: options.ackLocalTools,
|
|
1609
|
+
localMcp: options.localMcp
|
|
1491
1610
|
});
|
|
1492
1611
|
printRuntimeInstall(runtimeInstall, log);
|
|
1493
1612
|
try {
|
|
@@ -1502,6 +1621,7 @@ async function runConnect(options, deps = {}) {
|
|
|
1502
1621
|
signerAcknowledged: runtimeInstall.signerAcknowledged,
|
|
1503
1622
|
localMcpAcknowledged: runtimeInstall.localMcpAcknowledged,
|
|
1504
1623
|
activationCommandAvailable: Boolean(runtimeInstall.activationCommand),
|
|
1624
|
+
skillInstalled: runtimeInstall.skillInstalled,
|
|
1505
1625
|
probeResult: runtimeInstall.probeResult,
|
|
1506
1626
|
restartRequired: runtimeInstall.restartRequired,
|
|
1507
1627
|
nextUserAction: runtimeInstall.nextUserAction,
|
|
@@ -1583,6 +1703,8 @@ function parseArgs(argv, env = process.env) {
|
|
|
1583
1703
|
} else if (arg === "--ack-signer") {
|
|
1584
1704
|
options.ackSigner = true;
|
|
1585
1705
|
options.ackLocalTools = true;
|
|
1706
|
+
} else if (arg === "--local" || arg === "--local-mcp") {
|
|
1707
|
+
options.localMcp = true;
|
|
1586
1708
|
} else if (arg === "--version") {
|
|
1587
1709
|
process.stdout.write(`${CONNECTOR_VERSION}
|
|
1588
1710
|
`);
|
|
@@ -1621,6 +1743,8 @@ function helpText() {
|
|
|
1621
1743
|
" --environment-label <text> Non-sensitive label shown in Haven setup review.",
|
|
1622
1744
|
" --ack-local-tools Write the one-time local Haven tools acknowledgement during setup.",
|
|
1623
1745
|
" --ack-signer Backward-compatible alias for --ack-local-tools.",
|
|
1746
|
+
" --local Advanced: install the fully-local Haven MCP (no hosted dependency).",
|
|
1747
|
+
" Only available for Claude Code and Codex. Default is hosted MCP + local signer.",
|
|
1624
1748
|
" --help Show this help.",
|
|
1625
1749
|
"",
|
|
1626
1750
|
"The connector never prints the private key and never sends it to Haven."
|
|
@@ -1634,6 +1758,6 @@ function requireValue(argv, index, option) {
|
|
|
1634
1758
|
return value;
|
|
1635
1759
|
}
|
|
1636
1760
|
|
|
1637
|
-
export { CONNECTOR_VERSION, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, generateDelegateKey, helpText, installRuntime, normalizeRuntime, parseArgs, redactSecrets, runConnect, runtimeInstallCapabilities, runtimeProfile, shortAddress, writeCredentialFiles };
|
|
1761
|
+
export { CONNECTOR_VERSION, MCP_RUNTIME_MANIFEST, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, generateDelegateKey, helpText, installRuntime, mcpPackageSpec, normalizeRuntime, parseArgs, redactSecrets, runConnect, runtimeInstallCapabilities, runtimeProfile, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|
|
1638
1762
|
//# sourceMappingURL=index.js.map
|
|
1639
1763
|
//# sourceMappingURL=index.js.map
|