@haven_ai/connect 0.0.0-dev.202609031523.fd49e1a → 0.0.0-dev.202609031608.fceb089
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 +75 -1
- package/dist/cli.cjs +259 -44
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +260 -45
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +259 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -4
- package/dist/index.d.ts +102 -4
- package/dist/index.js +260 -45
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -377,7 +377,9 @@ npx @haven_ai/connect@alpha --doctor --repair --runtime codex-desktop
|
|
|
377
377
|
```
|
|
378
378
|
|
|
379
379
|
`--doctor` is read-only and needs NO setup token: it checks the runtime config,
|
|
380
|
-
the agent credential files, the pinned signer runtime install,
|
|
380
|
+
the agent credential files, the pinned signer runtime install (and, since
|
|
381
|
+
#2424, whether that install was made under a local runtime-spec override —
|
|
382
|
+
see the last section of this file), the hosted MCP
|
|
381
383
|
(authorized `tools/list`), and starts the local signer for a real stdio
|
|
382
384
|
handshake — reporting its advertised compat versions. Every failing check
|
|
383
385
|
prints one concrete repair action; the exit code is non-zero on any failure.
|
|
@@ -404,3 +406,75 @@ which.
|
|
|
404
406
|
`--repair` re-runs what setup already owns — reinstall the pinned signer
|
|
405
407
|
runtime, rewrite the wrapper + sidecar, and re-write the runtime config from
|
|
406
408
|
the STORED credentials. It never touches keys and never needs a new token.
|
|
409
|
+
|
|
410
|
+
## Installing an unpublished signer / SDK / MCP build (`HAVEN_SIGNER_SPEC`, #2424)
|
|
411
|
+
|
|
412
|
+
Setup installs the connector's **pinned** siblings — `@haven_ai/signer@<pin>`
|
|
413
|
+
and `@haven_ai/sdk@<pin>` into `~/.haven/signer-runtime/<pin>`, and for
|
|
414
|
+
`--local` also `@haven_ai/mcp@<pin>` into `~/.haven/mcp-runtime/<pin>`. That
|
|
415
|
+
is right for every user and wrong for the one developer iterating on the
|
|
416
|
+
signer or SDK, who otherwise has to publish to find out whether a change works
|
|
417
|
+
end to end. Three environment variables name a different spec:
|
|
418
|
+
|
|
419
|
+
| Variable | Replaces | Read by |
|
|
420
|
+
|---|---|---|
|
|
421
|
+
| `HAVEN_SIGNER_SPEC` | `@haven_ai/signer@<pin>` | the signer runtime (default topology) |
|
|
422
|
+
| `HAVEN_SDK_SPEC` | `@haven_ai/sdk@<pin>` | both runtimes — each installs the SDK |
|
|
423
|
+
| `HAVEN_MCP_SPEC` | `@haven_ai/mcp@<pin>` | the `--local` MCP runtime |
|
|
424
|
+
|
|
425
|
+
A value is anything `npm install` accepts for that package: a checkout
|
|
426
|
+
(`file:/abs/path/to/packages/signer`), a tarball from `npm pack`
|
|
427
|
+
(`/abs/haven_ai-signer-0.0.0.tgz`), or an explicit version
|
|
428
|
+
(`@haven_ai/signer@<version>`). Set it in the shell that runs the setup
|
|
429
|
+
command — the command itself is unchanged:
|
|
430
|
+
|
|
431
|
+
```bash
|
|
432
|
+
HAVEN_SIGNER_SPEC=file:$PWD/packages/signer npx @haven_ai/connect@alpha --setup <token> --runtime claude-code
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Environment variables rather than a flag, deliberately: the install runs from
|
|
436
|
+
three entry points (`--setup`, `--doctor --repair`, `--rekey-finish`) and all
|
|
437
|
+
three honour the same variables, so a re-key cannot silently reinstall the
|
|
438
|
+
registry build; and the setup command is minted by the dashboard and pasted
|
|
439
|
+
verbatim, often by an agent, so the override sits beside it instead of being
|
|
440
|
+
spliced into a line the developer did not write.
|
|
441
|
+
|
|
442
|
+
**What an active override changes:**
|
|
443
|
+
|
|
444
|
+
- The runtime directory is `~/.haven/signer-runtime/override-<hash>` (or
|
|
445
|
+
`mcp-runtime/override-<hash>`), keyed by a short hash of the **resolved**
|
|
446
|
+
specs — overridden and pinned alike — so it can never poison the
|
|
447
|
+
version-named directory the normal path reuses, and a pinned-sibling bump
|
|
448
|
+
gets a fresh one.
|
|
449
|
+
- The install is **never reused** from an earlier run: a rebuilt `file:`
|
|
450
|
+
package must not be shadowed by a cache hit.
|
|
451
|
+
- Setup prints `RUNTIME SPEC OVERRIDE ACTIVE …` first, naming each variable
|
|
452
|
+
and the pin it replaced; `--rekey-finish` prints the same line.
|
|
453
|
+
- `signer-runtime.json` / `mcp-runtime.json` record the override under
|
|
454
|
+
`runtime_spec_override`, and their `*_version` fields hold what npm actually
|
|
455
|
+
installed rather than the manifest pins.
|
|
456
|
+
- The wrapper the agent client launches carries a
|
|
457
|
+
`// HAVEN RUNTIME SPEC OVERRIDE (#2424): …` comment.
|
|
458
|
+
- `--doctor` reports a failing `runtime_spec_override` check — "runtime spec
|
|
459
|
+
overridden — not the pinned manifest" — whenever the sidecar says the
|
|
460
|
+
install ran under one **or** a `HAVEN_*_SPEC` variable is set in the shell
|
|
461
|
+
running the doctor (a `--repair` from that shell would install it). The
|
|
462
|
+
override is legitimate; the finding is its record. Under an override the
|
|
463
|
+
`signer_runtime` check compares the directory against the sidecar's own
|
|
464
|
+
record, not the manifest.
|
|
465
|
+
|
|
466
|
+
**What it never changes:** the post-setup handshake probe still requires
|
|
467
|
+
every tool in the manifest's `requiredTools` / `requiredSignerTools`, so a
|
|
468
|
+
local build that dropped a tool fails setup exactly like a bad registry
|
|
469
|
+
version would. A set-but-malformed value — empty, containing whitespace or a
|
|
470
|
+
shell metacharacter — is refused **before** npm runs and before anything is
|
|
471
|
+
written, with a message naming the variable. With no variable set, nothing
|
|
472
|
+
here runs: the install arguments, directory, sidecar and wrapper are
|
|
473
|
+
byte-for-byte what they were before the override existed (pinned by exact
|
|
474
|
+
characterization tests in `signer-runtime.test.ts` and
|
|
475
|
+
`local-mcp-runtime.test.ts`).
|
|
476
|
+
|
|
477
|
+
To return to the pinned manifest: unset the variables and run
|
|
478
|
+
`--doctor --repair --runtime <runtime>` (or re-run setup). The override
|
|
479
|
+
directories live under `~/.haven` like every other runtime directory, so the
|
|
480
|
+
same reset that removes `~/.haven` removes them.
|
package/dist/cli.cjs
CHANGED
|
@@ -535,9 +535,9 @@ var init_runtime_manifest = __esm({
|
|
|
535
535
|
mcpPackage: "@haven_ai/mcp",
|
|
536
536
|
mcpVersion: mcp.MCP_VERSION,
|
|
537
537
|
sdkPackage: "@haven_ai/sdk",
|
|
538
|
-
sdkVersion: "0.0.0-dev.
|
|
538
|
+
sdkVersion: "0.0.0-dev.202609031608.fceb089",
|
|
539
539
|
signerPackage: "@haven_ai/signer",
|
|
540
|
-
signerVersion: "0.0.0-dev.
|
|
540
|
+
signerVersion: "0.0.0-dev.202609031608.fceb089",
|
|
541
541
|
// Sourced from the SDK, never a literal (#1161). This field read '20.0.0'
|
|
542
542
|
// while every package's `engines` said `>=24` and the docs said `>=24.0.0`,
|
|
543
543
|
// so the guard that was supposed to enforce the floor waved Node v23 through
|
|
@@ -1608,32 +1608,129 @@ var init_probes = __esm({
|
|
|
1608
1608
|
"src/probes.ts"() {
|
|
1609
1609
|
}
|
|
1610
1610
|
});
|
|
1611
|
+
function resolveRuntimeSpecOverride(env) {
|
|
1612
|
+
const override = {};
|
|
1613
|
+
for (const pkg of Object.keys(RUNTIME_SPEC_ENV)) {
|
|
1614
|
+
const variable = RUNTIME_SPEC_ENV[pkg];
|
|
1615
|
+
const raw = env[variable];
|
|
1616
|
+
if (raw === void 0) continue;
|
|
1617
|
+
override[pkg] = validateSpec(variable, raw);
|
|
1618
|
+
}
|
|
1619
|
+
return Object.keys(override).length > 0 ? override : void 0;
|
|
1620
|
+
}
|
|
1621
|
+
function validateSpec(variable, raw) {
|
|
1622
|
+
if (raw.length === 0 || raw.trim().length === 0) {
|
|
1623
|
+
throw new RuntimeSpecOverrideError(variable, "it is empty");
|
|
1624
|
+
}
|
|
1625
|
+
if (/\s/.test(raw)) {
|
|
1626
|
+
throw new RuntimeSpecOverrideError(variable, "it contains whitespace");
|
|
1627
|
+
}
|
|
1628
|
+
if (/[\u0000-\u001f\u007f]/.test(raw)) {
|
|
1629
|
+
throw new RuntimeSpecOverrideError(variable, "it contains a control character");
|
|
1630
|
+
}
|
|
1631
|
+
const meta = SHELL_METACHARACTERS.exec(raw);
|
|
1632
|
+
if (meta) {
|
|
1633
|
+
throw new RuntimeSpecOverrideError(variable, `it contains the shell metacharacter ${JSON.stringify(meta[0])}`);
|
|
1634
|
+
}
|
|
1635
|
+
return raw;
|
|
1636
|
+
}
|
|
1637
|
+
function runtimeSpecOverrideDirectoryKey(resolvedSpecs) {
|
|
1638
|
+
const digest = crypto.createHash("sha256").update(resolvedSpecs.join("\n")).digest("hex");
|
|
1639
|
+
return `override-${digest.slice(0, 12)}`;
|
|
1640
|
+
}
|
|
1641
|
+
function overrideApplies(override, packages) {
|
|
1642
|
+
return override !== void 0 && packages.some((pkg) => override[pkg] !== void 0);
|
|
1643
|
+
}
|
|
1644
|
+
function runtimeSpecOverrideNotice(runtimeLabel, override, pinned, runtimeDirectory) {
|
|
1645
|
+
const lines = [`RUNTIME SPEC OVERRIDE ACTIVE for the local Haven ${runtimeLabel} \u2014 this is NOT the pinned manifest.`];
|
|
1646
|
+
for (const pkg of Object.keys(RUNTIME_SPEC_ENV)) {
|
|
1647
|
+
const spec = override[pkg];
|
|
1648
|
+
if (spec === void 0) continue;
|
|
1649
|
+
const pin = pinned[pkg];
|
|
1650
|
+
lines.push(` ${RUNTIME_SPEC_ENV[pkg]}=${spec}${pin ? ` (instead of ${pin})` : ""}`);
|
|
1651
|
+
}
|
|
1652
|
+
lines.push(` Installing into ${runtimeDirectory} \u2014 the pinned runtime directory is untouched.`);
|
|
1653
|
+
lines.push(" Unset the variable(s) and re-run to return to the pinned manifest.");
|
|
1654
|
+
return lines;
|
|
1655
|
+
}
|
|
1656
|
+
function describeRuntimeSpecOverride(override) {
|
|
1657
|
+
return Object.keys(RUNTIME_SPEC_ENV).filter((pkg) => override[pkg] !== void 0).map((pkg) => `${RUNTIME_SPEC_ENV[pkg]}=${override[pkg]}`).join(" ");
|
|
1658
|
+
}
|
|
1659
|
+
var RUNTIME_SPEC_ENV, SHELL_METACHARACTERS, RuntimeSpecOverrideError;
|
|
1660
|
+
var init_runtime_spec_override = __esm({
|
|
1661
|
+
"src/runtime-spec-override.ts"() {
|
|
1662
|
+
RUNTIME_SPEC_ENV = {
|
|
1663
|
+
signer: "HAVEN_SIGNER_SPEC",
|
|
1664
|
+
sdk: "HAVEN_SDK_SPEC",
|
|
1665
|
+
mcp: "HAVEN_MCP_SPEC"
|
|
1666
|
+
};
|
|
1667
|
+
SHELL_METACHARACTERS = /[;&|<>$`'"()!#*?[\]{}\\]/;
|
|
1668
|
+
RuntimeSpecOverrideError = class extends Error {
|
|
1669
|
+
code = "runtime_spec_override_invalid";
|
|
1670
|
+
variable;
|
|
1671
|
+
constructor(variable, reason) {
|
|
1672
|
+
super(`${variable} is set but not usable as an npm package spec: ${reason}. Unset it, or set it to a spec npm install accepts (file:/abs/path, a .tgz, or @haven_ai/<pkg>@<version>).`);
|
|
1673
|
+
this.name = "RuntimeSpecOverrideError";
|
|
1674
|
+
this.variable = variable;
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1611
1679
|
async function prepareSignerRuntime(input, deps = {}) {
|
|
1612
1680
|
const homeDir = input.homeDir ?? os.homedir();
|
|
1613
|
-
const
|
|
1681
|
+
const override = resolveSignerRuntimeOverride(deps.env ?? process.env);
|
|
1682
|
+
const signerSpec = override?.signer ?? signerPackageSpec();
|
|
1683
|
+
const sdkSpec = override?.sdk ?? sdkPackageSpec();
|
|
1684
|
+
const resolvedSpecs = [signerSpec, sdkSpec];
|
|
1685
|
+
const overrideRecord = override ? { specs: override, resolved_specs: resolvedSpecs, directory_key: runtimeSpecOverrideDirectoryKey(resolvedSpecs) } : void 0;
|
|
1686
|
+
const runtimeDirectory = path.resolve(
|
|
1687
|
+
homeDir,
|
|
1688
|
+
".haven",
|
|
1689
|
+
"signer-runtime",
|
|
1690
|
+
overrideRecord ? overrideRecord.directory_key : MCP_RUNTIME_MANIFEST.signerVersion
|
|
1691
|
+
);
|
|
1614
1692
|
const npmCacheDirectory = path.resolve(homeDir, ".haven", "npm-cache");
|
|
1615
1693
|
const cliPath = path.join(runtimeDirectory, "node_modules", "@haven_ai", "signer", "dist", "cli.js");
|
|
1616
1694
|
const messages = [];
|
|
1695
|
+
if (override) {
|
|
1696
|
+
messages.push(...runtimeSpecOverrideNotice(
|
|
1697
|
+
"signer runtime",
|
|
1698
|
+
override,
|
|
1699
|
+
{ signer: signerPackageSpec(), sdk: sdkPackageSpec() },
|
|
1700
|
+
runtimeDirectory
|
|
1701
|
+
));
|
|
1702
|
+
}
|
|
1617
1703
|
await promises.mkdir(runtimeDirectory, { recursive: true, mode: 448 });
|
|
1618
1704
|
await promises.chmod(runtimeDirectory, 448).catch(() => void 0);
|
|
1619
1705
|
await promises.mkdir(npmCacheDirectory, { recursive: true, mode: 448 });
|
|
1620
1706
|
await promises.chmod(npmCacheDirectory, 448).catch(() => void 0);
|
|
1621
|
-
if (
|
|
1707
|
+
if (override) {
|
|
1708
|
+
await installRuntimePackages(runtimeDirectory, npmCacheDirectory, resolvedSpecs, deps);
|
|
1709
|
+
messages.push(`Installed local Haven signer runtime from override (${resolvedSpecs.join(" ")}).`);
|
|
1710
|
+
} else if (await installedRuntimeMatches(runtimeDirectory, cliPath)) {
|
|
1622
1711
|
messages.push(`Using existing local Haven signer runtime ${signerPackageSpec()}.`);
|
|
1623
1712
|
} else {
|
|
1624
|
-
await installRuntimePackages(runtimeDirectory, npmCacheDirectory, deps);
|
|
1713
|
+
await installRuntimePackages(runtimeDirectory, npmCacheDirectory, resolvedSpecs, deps);
|
|
1625
1714
|
messages.push(`Installed local Haven signer runtime ${signerPackageSpec()}.`);
|
|
1626
1715
|
}
|
|
1627
1716
|
await assertFileExists(cliPath, "local Haven signer CLI");
|
|
1717
|
+
const installedVersions = override ? await readInstalledVersions(runtimeDirectory) : void 0;
|
|
1628
1718
|
const wrapperPath = path.join(input.credentialDirectory, "bin", "haven-signer.mjs");
|
|
1629
|
-
await writeWrapper({
|
|
1719
|
+
await writeWrapper({
|
|
1720
|
+
wrapperPath,
|
|
1721
|
+
cliPath,
|
|
1722
|
+
signerPath: input.signerPath,
|
|
1723
|
+
overrideComment: override ? describeRuntimeSpecOverride(override) : void 0
|
|
1724
|
+
});
|
|
1630
1725
|
await writeRuntimeSidecar({
|
|
1631
1726
|
path: path.join(input.credentialDirectory, "signer-runtime.json"),
|
|
1632
1727
|
wrapperPath,
|
|
1633
1728
|
runtimeDirectory,
|
|
1634
1729
|
npmCacheDirectory,
|
|
1635
1730
|
cliPath,
|
|
1636
|
-
serverName: input.serverName
|
|
1731
|
+
serverName: input.serverName,
|
|
1732
|
+
override: overrideRecord,
|
|
1733
|
+
installedVersions
|
|
1637
1734
|
});
|
|
1638
1735
|
messages.push(`Prepared stable local Haven signer wrapper: ${wrapperPath}`);
|
|
1639
1736
|
return {
|
|
@@ -1643,10 +1740,17 @@ async function prepareSignerRuntime(input, deps = {}) {
|
|
|
1643
1740
|
runtimeDirectory,
|
|
1644
1741
|
npmCacheDirectory,
|
|
1645
1742
|
cliPath,
|
|
1646
|
-
messages
|
|
1743
|
+
messages,
|
|
1744
|
+
...overrideRecord ? { runtimeSpecOverride: overrideRecord } : {}
|
|
1647
1745
|
};
|
|
1648
1746
|
}
|
|
1649
|
-
|
|
1747
|
+
function resolveSignerRuntimeOverride(env) {
|
|
1748
|
+
const override = resolveRuntimeSpecOverride(env);
|
|
1749
|
+
if (!overrideApplies(override, ["signer", "sdk"])) return void 0;
|
|
1750
|
+
const { signer, sdk } = override;
|
|
1751
|
+
return { ...signer !== void 0 ? { signer } : {}, ...sdk !== void 0 ? { sdk } : {} };
|
|
1752
|
+
}
|
|
1753
|
+
async function installRuntimePackages(runtimeDirectory, npmCacheDirectory, packageSpecs, deps) {
|
|
1650
1754
|
const { runCommand, onProgress } = deps;
|
|
1651
1755
|
const baseArgs = [
|
|
1652
1756
|
"install",
|
|
@@ -1656,8 +1760,7 @@ async function installRuntimePackages(runtimeDirectory, npmCacheDirectory, deps)
|
|
|
1656
1760
|
"--no-fund",
|
|
1657
1761
|
"--omit=dev",
|
|
1658
1762
|
"--prefer-offline",
|
|
1659
|
-
|
|
1660
|
-
sdkPackageSpec()
|
|
1763
|
+
...packageSpecs
|
|
1661
1764
|
];
|
|
1662
1765
|
const run = async (args) => {
|
|
1663
1766
|
const startedAt = Date.now();
|
|
@@ -1680,23 +1783,33 @@ async function installRuntimePackages(runtimeDirectory, npmCacheDirectory, deps)
|
|
|
1680
1783
|
await run([...baseArgs, "--cache", npmCacheDirectory]);
|
|
1681
1784
|
} catch (err) {
|
|
1682
1785
|
throw new Error(
|
|
1683
|
-
`Could not install local Haven signer runtime ${
|
|
1786
|
+
`Could not install local Haven signer runtime ${packageSpecs.join(" ")}: ${err instanceof Error ? err.message : String(err)}`
|
|
1684
1787
|
);
|
|
1685
1788
|
}
|
|
1686
1789
|
}
|
|
1687
1790
|
}
|
|
1688
1791
|
async function installedRuntimeMatches(runtimeDirectory, cliPath) {
|
|
1792
|
+
return installedRuntimeMatchesVersions(runtimeDirectory, cliPath, {
|
|
1793
|
+
signerVersion: MCP_RUNTIME_MANIFEST.signerVersion,
|
|
1794
|
+
sdkVersion: MCP_RUNTIME_MANIFEST.sdkVersion
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
async function installedRuntimeMatchesVersions(runtimeDirectory, cliPath, expected) {
|
|
1689
1798
|
try {
|
|
1690
1799
|
await assertFileExists(cliPath, "local Haven signer CLI");
|
|
1691
|
-
const
|
|
1692
|
-
|
|
1693
|
-
readPackageJson(path.join(runtimeDirectory, "node_modules", "@haven_ai", "sdk", "package.json"))
|
|
1694
|
-
]);
|
|
1695
|
-
return signerPackage.version === MCP_RUNTIME_MANIFEST.signerVersion && sdkPackage.version === MCP_RUNTIME_MANIFEST.sdkVersion;
|
|
1800
|
+
const installed = await readInstalledVersions(runtimeDirectory);
|
|
1801
|
+
return installed.signerVersion === expected.signerVersion && installed.sdkVersion === expected.sdkVersion;
|
|
1696
1802
|
} catch {
|
|
1697
1803
|
return false;
|
|
1698
1804
|
}
|
|
1699
1805
|
}
|
|
1806
|
+
async function readInstalledVersions(runtimeDirectory) {
|
|
1807
|
+
const [signerPackage, sdkPackage] = await Promise.all([
|
|
1808
|
+
readPackageJson(path.join(runtimeDirectory, "node_modules", "@haven_ai", "signer", "package.json")),
|
|
1809
|
+
readPackageJson(path.join(runtimeDirectory, "node_modules", "@haven_ai", "sdk", "package.json"))
|
|
1810
|
+
]);
|
|
1811
|
+
return { signerVersion: signerPackage.version ?? "", sdkVersion: sdkPackage.version ?? "" };
|
|
1812
|
+
}
|
|
1700
1813
|
async function readPackageJson(path) {
|
|
1701
1814
|
return JSON.parse(await promises.readFile(path, "utf8"));
|
|
1702
1815
|
}
|
|
@@ -1705,6 +1818,7 @@ async function writeWrapper(input) {
|
|
|
1705
1818
|
await promises.chmod(path.dirname(input.wrapperPath), 448).catch(() => void 0);
|
|
1706
1819
|
const source = [
|
|
1707
1820
|
"#!/usr/bin/env node",
|
|
1821
|
+
...input.overrideComment ? [`// HAVEN RUNTIME SPEC OVERRIDE (#2424): ${input.overrideComment} \u2014 this wrapper launches a NON-pinned signer build.`] : [],
|
|
1708
1822
|
"import { spawn } from 'node:child_process'",
|
|
1709
1823
|
"",
|
|
1710
1824
|
`const cliPath = ${JSON.stringify(input.cliPath)}`,
|
|
@@ -1736,13 +1850,14 @@ async function writeRuntimeSidecar(input) {
|
|
|
1736
1850
|
const value = {
|
|
1737
1851
|
...input.serverName ? { server_name: input.serverName } : {},
|
|
1738
1852
|
signer_package: MCP_RUNTIME_MANIFEST.signerPackage,
|
|
1739
|
-
signer_version: MCP_RUNTIME_MANIFEST.signerVersion,
|
|
1853
|
+
signer_version: input.installedVersions?.signerVersion ?? MCP_RUNTIME_MANIFEST.signerVersion,
|
|
1740
1854
|
sdk_package: MCP_RUNTIME_MANIFEST.sdkPackage,
|
|
1741
|
-
sdk_version: MCP_RUNTIME_MANIFEST.sdkVersion,
|
|
1855
|
+
sdk_version: input.installedVersions?.sdkVersion ?? MCP_RUNTIME_MANIFEST.sdkVersion,
|
|
1742
1856
|
wrapper_path: input.wrapperPath,
|
|
1743
1857
|
runtime_directory: input.runtimeDirectory,
|
|
1744
1858
|
npm_cache_directory: input.npmCacheDirectory,
|
|
1745
|
-
cli_path: input.cliPath
|
|
1859
|
+
cli_path: input.cliPath,
|
|
1860
|
+
...input.override ? { runtime_spec_override: input.override } : {}
|
|
1746
1861
|
};
|
|
1747
1862
|
await promises.writeFile(input.path, `${JSON.stringify(value, null, 2)}
|
|
1748
1863
|
`, { mode: 384 });
|
|
@@ -1759,6 +1874,7 @@ var execFileAsync, SIGNER_INSTALL_TIMEOUT_MS, SIGNER_INSTALL_HEARTBEAT_MS;
|
|
|
1759
1874
|
var init_signer_runtime = __esm({
|
|
1760
1875
|
"src/signer-runtime.ts"() {
|
|
1761
1876
|
init_runtime_manifest();
|
|
1877
|
+
init_runtime_spec_override();
|
|
1762
1878
|
execFileAsync = util.promisify(child_process.execFile);
|
|
1763
1879
|
SIGNER_INSTALL_TIMEOUT_MS = 6e5;
|
|
1764
1880
|
SIGNER_INSTALL_HEARTBEAT_MS = 15e3;
|
|
@@ -1767,27 +1883,50 @@ var init_signer_runtime = __esm({
|
|
|
1767
1883
|
async function prepareLocalMcpRuntime(input, deps = {}) {
|
|
1768
1884
|
assertSupportedNodeVersion(input.nodeVersion);
|
|
1769
1885
|
const homeDir = input.homeDir ?? os.homedir();
|
|
1770
|
-
const
|
|
1886
|
+
const override = resolveLocalMcpRuntimeOverride(deps.env ?? process.env);
|
|
1887
|
+
const mcpSpec = override?.mcp ?? mcpPackageSpec();
|
|
1888
|
+
const sdkSpec = override?.sdk ?? sdkPackageSpec();
|
|
1889
|
+
const resolvedSpecs = [mcpSpec, sdkSpec];
|
|
1890
|
+
const overrideRecord = override ? { specs: override, resolved_specs: resolvedSpecs, directory_key: runtimeSpecOverrideDirectoryKey(resolvedSpecs) } : void 0;
|
|
1891
|
+
const runtimeDirectory = path.resolve(
|
|
1892
|
+
homeDir,
|
|
1893
|
+
".haven",
|
|
1894
|
+
"mcp-runtime",
|
|
1895
|
+
overrideRecord ? overrideRecord.directory_key : MCP_RUNTIME_MANIFEST.mcpVersion
|
|
1896
|
+
);
|
|
1771
1897
|
const npmCacheDirectory = path.resolve(homeDir, ".haven", "npm-cache");
|
|
1772
1898
|
const cliPath = path.join(runtimeDirectory, "node_modules", "@haven_ai", "mcp", "dist", "cli.js");
|
|
1773
1899
|
const messages = [];
|
|
1900
|
+
if (override) {
|
|
1901
|
+
messages.push(...runtimeSpecOverrideNotice(
|
|
1902
|
+
"MCP runtime",
|
|
1903
|
+
override,
|
|
1904
|
+
{ mcp: mcpPackageSpec(), sdk: sdkPackageSpec() },
|
|
1905
|
+
runtimeDirectory
|
|
1906
|
+
));
|
|
1907
|
+
}
|
|
1774
1908
|
await promises.mkdir(runtimeDirectory, { recursive: true, mode: 448 });
|
|
1775
1909
|
await promises.chmod(runtimeDirectory, 448).catch(() => void 0);
|
|
1776
1910
|
await promises.mkdir(npmCacheDirectory, { recursive: true, mode: 448 });
|
|
1777
1911
|
await promises.chmod(npmCacheDirectory, 448).catch(() => void 0);
|
|
1778
|
-
if (
|
|
1912
|
+
if (override) {
|
|
1913
|
+
await installRuntimePackages2(runtimeDirectory, npmCacheDirectory, resolvedSpecs, deps);
|
|
1914
|
+
messages.push(`Installed local Haven MCP runtime from override (${resolvedSpecs.join(" ")}).`);
|
|
1915
|
+
} else if (await installedRuntimeMatches2(runtimeDirectory, cliPath)) {
|
|
1779
1916
|
messages.push(`Using existing local Haven MCP runtime ${mcpPackageSpec()}.`);
|
|
1780
1917
|
} else {
|
|
1781
|
-
await installRuntimePackages2(runtimeDirectory, npmCacheDirectory, deps);
|
|
1918
|
+
await installRuntimePackages2(runtimeDirectory, npmCacheDirectory, resolvedSpecs, deps);
|
|
1782
1919
|
messages.push(`Installed local Haven MCP runtime ${mcpPackageSpec()}.`);
|
|
1783
1920
|
}
|
|
1784
1921
|
await assertFileExists2(cliPath, "local Haven MCP CLI");
|
|
1922
|
+
const installedVersions = override ? await readInstalledVersions2(runtimeDirectory) : void 0;
|
|
1785
1923
|
const wrapperPath = path.join(input.credentialDirectory, "bin", "haven-mcp");
|
|
1786
1924
|
await writeWrapper2({
|
|
1787
1925
|
wrapperPath,
|
|
1788
1926
|
cliPath,
|
|
1789
1927
|
identityPath: input.identityPath,
|
|
1790
|
-
signerPath: input.signerPath
|
|
1928
|
+
signerPath: input.signerPath,
|
|
1929
|
+
overrideComment: override ? describeRuntimeSpecOverride(override) : void 0
|
|
1791
1930
|
});
|
|
1792
1931
|
await writeRuntimeSidecar2({
|
|
1793
1932
|
path: path.join(input.credentialDirectory, "mcp-runtime.json"),
|
|
@@ -1795,7 +1934,9 @@ async function prepareLocalMcpRuntime(input, deps = {}) {
|
|
|
1795
1934
|
runtimeDirectory,
|
|
1796
1935
|
npmCacheDirectory,
|
|
1797
1936
|
cliPath,
|
|
1798
|
-
serverName: input.serverName
|
|
1937
|
+
serverName: input.serverName,
|
|
1938
|
+
override: overrideRecord,
|
|
1939
|
+
installedVersions
|
|
1799
1940
|
});
|
|
1800
1941
|
messages.push(`Prepared stable local Haven MCP wrapper: ${wrapperPath}`);
|
|
1801
1942
|
return {
|
|
@@ -1805,7 +1946,8 @@ async function prepareLocalMcpRuntime(input, deps = {}) {
|
|
|
1805
1946
|
runtimeDirectory,
|
|
1806
1947
|
npmCacheDirectory,
|
|
1807
1948
|
cliPath,
|
|
1808
|
-
messages
|
|
1949
|
+
messages,
|
|
1950
|
+
...overrideRecord ? { runtimeSpecOverride: overrideRecord } : {}
|
|
1809
1951
|
};
|
|
1810
1952
|
}
|
|
1811
1953
|
function assertSupportedNodeVersion(nodeVersion = process.versions.node, minimumNodeVersion = MCP_RUNTIME_MANIFEST.minimumNodeVersion, subject = "Haven setup") {
|
|
@@ -1813,7 +1955,13 @@ function assertSupportedNodeVersion(nodeVersion = process.versions.node, minimum
|
|
|
1813
1955
|
throw new UnsupportedNodeVersionError(nodeVersion, minimumNodeVersion, subject);
|
|
1814
1956
|
}
|
|
1815
1957
|
}
|
|
1816
|
-
|
|
1958
|
+
function resolveLocalMcpRuntimeOverride(env) {
|
|
1959
|
+
const override = resolveRuntimeSpecOverride(env);
|
|
1960
|
+
if (!overrideApplies(override, ["mcp", "sdk"])) return void 0;
|
|
1961
|
+
const { mcp, sdk } = override;
|
|
1962
|
+
return { ...mcp !== void 0 ? { mcp } : {}, ...sdk !== void 0 ? { sdk } : {} };
|
|
1963
|
+
}
|
|
1964
|
+
async function installRuntimePackages2(runtimeDirectory, npmCacheDirectory, packageSpecs, deps) {
|
|
1817
1965
|
const { runCommand, onProgress } = deps;
|
|
1818
1966
|
const baseArgs = [
|
|
1819
1967
|
"install",
|
|
@@ -1823,8 +1971,7 @@ async function installRuntimePackages2(runtimeDirectory, npmCacheDirectory, deps
|
|
|
1823
1971
|
"--no-fund",
|
|
1824
1972
|
"--omit=dev",
|
|
1825
1973
|
"--prefer-offline",
|
|
1826
|
-
|
|
1827
|
-
sdkPackageSpec()
|
|
1974
|
+
...packageSpecs
|
|
1828
1975
|
];
|
|
1829
1976
|
const run = async (args) => {
|
|
1830
1977
|
const startedAt = Date.now();
|
|
@@ -1846,22 +1993,26 @@ async function installRuntimePackages2(runtimeDirectory, npmCacheDirectory, deps
|
|
|
1846
1993
|
try {
|
|
1847
1994
|
await run([...baseArgs, "--cache", npmCacheDirectory]);
|
|
1848
1995
|
} catch (err) {
|
|
1849
|
-
throw new Error(`Could not install local Haven MCP runtime ${
|
|
1996
|
+
throw new Error(`Could not install local Haven MCP runtime ${packageSpecs.join(" ")}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1850
1997
|
}
|
|
1851
1998
|
}
|
|
1852
1999
|
}
|
|
1853
2000
|
async function installedRuntimeMatches2(runtimeDirectory, cliPath) {
|
|
1854
2001
|
try {
|
|
1855
2002
|
await assertFileExists2(cliPath, "local Haven MCP CLI");
|
|
1856
|
-
const
|
|
1857
|
-
|
|
1858
|
-
readPackageJson2(path.join(runtimeDirectory, "node_modules", "@haven_ai", "sdk", "package.json"))
|
|
1859
|
-
]);
|
|
1860
|
-
return mcpPackage.version === MCP_RUNTIME_MANIFEST.mcpVersion && sdkPackage.version === MCP_RUNTIME_MANIFEST.sdkVersion;
|
|
2003
|
+
const installed = await readInstalledVersions2(runtimeDirectory);
|
|
2004
|
+
return installed.mcpVersion === MCP_RUNTIME_MANIFEST.mcpVersion && installed.sdkVersion === MCP_RUNTIME_MANIFEST.sdkVersion;
|
|
1861
2005
|
} catch {
|
|
1862
2006
|
return false;
|
|
1863
2007
|
}
|
|
1864
2008
|
}
|
|
2009
|
+
async function readInstalledVersions2(runtimeDirectory) {
|
|
2010
|
+
const [mcpPackage, sdkPackage] = await Promise.all([
|
|
2011
|
+
readPackageJson2(path.join(runtimeDirectory, "node_modules", "@haven_ai", "mcp", "package.json")),
|
|
2012
|
+
readPackageJson2(path.join(runtimeDirectory, "node_modules", "@haven_ai", "sdk", "package.json"))
|
|
2013
|
+
]);
|
|
2014
|
+
return { mcpVersion: mcpPackage.version ?? "", sdkVersion: sdkPackage.version ?? "" };
|
|
2015
|
+
}
|
|
1865
2016
|
async function readPackageJson2(path) {
|
|
1866
2017
|
return JSON.parse(await promises.readFile(path, "utf8"));
|
|
1867
2018
|
}
|
|
@@ -1870,6 +2021,7 @@ async function writeWrapper2(input) {
|
|
|
1870
2021
|
await promises.chmod(path.dirname(input.wrapperPath), 448).catch(() => void 0);
|
|
1871
2022
|
const source = [
|
|
1872
2023
|
"#!/usr/bin/env node",
|
|
2024
|
+
...input.overrideComment ? [`// HAVEN RUNTIME SPEC OVERRIDE (#2424): ${input.overrideComment} \u2014 this wrapper launches a NON-pinned MCP build.`] : [],
|
|
1873
2025
|
"import { spawn } from 'node:child_process'",
|
|
1874
2026
|
"",
|
|
1875
2027
|
`const cliPath = ${JSON.stringify(input.cliPath)}`,
|
|
@@ -1893,14 +2045,15 @@ async function writeRuntimeSidecar2(input) {
|
|
|
1893
2045
|
const value = {
|
|
1894
2046
|
...input.serverName ? { server_name: input.serverName } : {},
|
|
1895
2047
|
mcp_package: MCP_RUNTIME_MANIFEST.mcpPackage,
|
|
1896
|
-
mcp_version: MCP_RUNTIME_MANIFEST.mcpVersion,
|
|
2048
|
+
mcp_version: input.installedVersions?.mcpVersion ?? MCP_RUNTIME_MANIFEST.mcpVersion,
|
|
1897
2049
|
sdk_package: MCP_RUNTIME_MANIFEST.sdkPackage,
|
|
1898
|
-
sdk_version: MCP_RUNTIME_MANIFEST.sdkVersion,
|
|
2050
|
+
sdk_version: input.installedVersions?.sdkVersion ?? MCP_RUNTIME_MANIFEST.sdkVersion,
|
|
1899
2051
|
minimum_node_version: MCP_RUNTIME_MANIFEST.minimumNodeVersion,
|
|
1900
2052
|
wrapper_path: input.wrapperPath,
|
|
1901
2053
|
runtime_directory: input.runtimeDirectory,
|
|
1902
2054
|
npm_cache_directory: input.npmCacheDirectory,
|
|
1903
|
-
cli_path: input.cliPath
|
|
2055
|
+
cli_path: input.cliPath,
|
|
2056
|
+
...input.override ? { runtime_spec_override: input.override } : {}
|
|
1904
2057
|
};
|
|
1905
2058
|
await promises.writeFile(input.path, `${JSON.stringify(value, null, 2)}
|
|
1906
2059
|
`, { mode: 384 });
|
|
@@ -1918,6 +2071,7 @@ var init_local_mcp_runtime = __esm({
|
|
|
1918
2071
|
"src/local-mcp-runtime.ts"() {
|
|
1919
2072
|
init_signer_runtime();
|
|
1920
2073
|
init_runtime_manifest();
|
|
2074
|
+
init_runtime_spec_override();
|
|
1921
2075
|
execFileAsync2 = util.promisify(child_process.execFile);
|
|
1922
2076
|
UnsupportedNodeVersionError = class extends Error {
|
|
1923
2077
|
code = "local_mcp_unsupported_node_version";
|
|
@@ -2704,7 +2858,7 @@ function supportsLocalMcp(runtime) {
|
|
|
2704
2858
|
return runtime === "codex-cli" || runtime === "codex-desktop" || runtime === "claude-code";
|
|
2705
2859
|
}
|
|
2706
2860
|
async function prepareRuntimeForLocalMcp(input, deps) {
|
|
2707
|
-
const prepare = deps.prepareLocalMcpRuntime ?? ((runtimeInput) => prepareLocalMcpRuntime(runtimeInput, { runCommand: deps.runCommand, onProgress: deps.onProgress }));
|
|
2861
|
+
const prepare = deps.prepareLocalMcpRuntime ?? ((runtimeInput) => prepareLocalMcpRuntime(runtimeInput, { runCommand: deps.runCommand, onProgress: deps.onProgress, env: deps.env }));
|
|
2708
2862
|
return prepare({
|
|
2709
2863
|
credentialDirectory: input.credentialDirectory,
|
|
2710
2864
|
identityPath: input.identityPath,
|
|
@@ -2719,7 +2873,7 @@ async function prepareSignerForRuntime(input, deps) {
|
|
|
2719
2873
|
// install heartbeat was dead code in production and the console still
|
|
2720
2874
|
// went silent for the whole cold install — the exact symptom the issue
|
|
2721
2875
|
// set out to remove, at a longer timeout.
|
|
2722
|
-
prepareSignerRuntime(runtimeInput, { runCommand: deps.runCommand, onProgress: deps.onProgress })
|
|
2876
|
+
prepareSignerRuntime(runtimeInput, { runCommand: deps.runCommand, onProgress: deps.onProgress, env: deps.env })
|
|
2723
2877
|
));
|
|
2724
2878
|
return prepare({
|
|
2725
2879
|
credentialDirectory: input.credentialDirectory,
|
|
@@ -3167,7 +3321,7 @@ async function finishRekey(options, deps = {}) {
|
|
|
3167
3321
|
signerPath: `${stored.directory}/signer.json`,
|
|
3168
3322
|
homeDir: options.homeDir
|
|
3169
3323
|
},
|
|
3170
|
-
{ runCommand: deps.runCommand }
|
|
3324
|
+
{ runCommand: deps.runCommand, env: deps.env }
|
|
3171
3325
|
);
|
|
3172
3326
|
const result = await (deps.writeConfig ?? writeHostedRuntimeConfig)(
|
|
3173
3327
|
{ runCommand: deps.runCommand, homeDir: options.homeDir },
|
|
@@ -3183,6 +3337,11 @@ async function finishRekey(options, deps = {}) {
|
|
|
3183
3337
|
{ command: prepared.command, args: prepared.args }
|
|
3184
3338
|
);
|
|
3185
3339
|
configRewritten = result.hostedConfigured;
|
|
3340
|
+
if (prepared.runtimeSpecOverride) {
|
|
3341
|
+
messages.push(
|
|
3342
|
+
` Signer runtime: RUNTIME SPEC OVERRIDE ACTIVE \u2014 ${describeRuntimeSpecOverride(prepared.runtimeSpecOverride.specs)} (NOT the pinned manifest; installed into ${prepared.runtimeDirectory})`
|
|
3343
|
+
);
|
|
3344
|
+
}
|
|
3186
3345
|
messages.push(` Config: ${result.target}`);
|
|
3187
3346
|
messages.push(...result.messages.map((line) => ` ${line}`));
|
|
3188
3347
|
if (!configRewritten) {
|
|
@@ -3249,6 +3408,7 @@ var init_rekey = __esm({
|
|
|
3249
3408
|
init_api();
|
|
3250
3409
|
init_runtime_install();
|
|
3251
3410
|
init_signer_runtime();
|
|
3411
|
+
init_runtime_spec_override();
|
|
3252
3412
|
init_key();
|
|
3253
3413
|
init_redact();
|
|
3254
3414
|
init_rekey_messages();
|
|
@@ -3425,6 +3585,46 @@ function rekeyPendingCheck(status, hostedDelegateAddress, runtime, slug) {
|
|
|
3425
3585
|
detail: `A re-key started ${started} is still open (expires ${status.expiresAt ?? "unknown"}). Paste this address into "Replace signing key" on the Haven agent page: ${address}. Parked at ${status.path}. ` + wedgeNote
|
|
3426
3586
|
};
|
|
3427
3587
|
}
|
|
3588
|
+
async function runtimeSpecOverrideCheck(directory, sidecar, env) {
|
|
3589
|
+
const facts = [];
|
|
3590
|
+
const installed = sidecar?.runtime_spec_override;
|
|
3591
|
+
if (installed) {
|
|
3592
|
+
facts.push(
|
|
3593
|
+
`signer runtime installed under ${describeRuntimeSpecOverride(installed.specs)} (resolved: ${installed.resolved_specs.join(" ")}; directory key ${installed.directory_key})`
|
|
3594
|
+
);
|
|
3595
|
+
}
|
|
3596
|
+
const mcpInstalled = await readMcpSidecarOverride(directory);
|
|
3597
|
+
if (mcpInstalled) {
|
|
3598
|
+
facts.push(
|
|
3599
|
+
`local MCP runtime installed under ${describeRuntimeSpecOverride(mcpInstalled.specs)} (resolved: ${mcpInstalled.resolved_specs.join(" ")}; directory key ${mcpInstalled.directory_key})`
|
|
3600
|
+
);
|
|
3601
|
+
}
|
|
3602
|
+
let shell;
|
|
3603
|
+
try {
|
|
3604
|
+
const active = resolveRuntimeSpecOverride(env);
|
|
3605
|
+
if (active) shell = `set in this shell: ${describeRuntimeSpecOverride(active)} \u2014 a --repair from here installs these, not the pin`;
|
|
3606
|
+
} catch (err) {
|
|
3607
|
+
shell = err instanceof RuntimeSpecOverrideError ? `set in this shell but REFUSED: ${err.message}` : `set in this shell but unreadable: ${err instanceof Error ? err.message : String(err)}`;
|
|
3608
|
+
}
|
|
3609
|
+
if (shell) facts.push(shell);
|
|
3610
|
+
if (facts.length === 0) return void 0;
|
|
3611
|
+
const variables = Object.values(RUNTIME_SPEC_ENV).join(" / ");
|
|
3612
|
+
return {
|
|
3613
|
+
id: "runtime_spec_override",
|
|
3614
|
+
label: "Runtime spec override",
|
|
3615
|
+
ok: false,
|
|
3616
|
+
detail: `runtime spec overridden \u2014 not the pinned manifest (${MCP_RUNTIME_MANIFEST.signerPackage}@${MCP_RUNTIME_MANIFEST.signerVersion}, ${MCP_RUNTIME_MANIFEST.sdkPackage}@${MCP_RUNTIME_MANIFEST.sdkVersion}). ${facts.join(". ")}.`,
|
|
3617
|
+
repair: `Developer override (#2424). To return to the pinned manifest: unset ${variables}, then run ${RERUN} --doctor --repair --runtime <runtime>. If the override is intentional, this finding is the record of it.`
|
|
3618
|
+
};
|
|
3619
|
+
}
|
|
3620
|
+
async function readMcpSidecarOverride(directory) {
|
|
3621
|
+
try {
|
|
3622
|
+
const parsed = JSON.parse(await promises.readFile(path.join(directory, "mcp-runtime.json"), "utf8"));
|
|
3623
|
+
return parsed.runtime_spec_override;
|
|
3624
|
+
} catch {
|
|
3625
|
+
return void 0;
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3428
3628
|
async function readIdentity(directory) {
|
|
3429
3629
|
try {
|
|
3430
3630
|
return JSON.parse(await promises.readFile(path.join(directory, "identity.json"), "utf8"));
|
|
@@ -3459,6 +3659,18 @@ async function checksForAgent(entry, input, deps) {
|
|
|
3459
3659
|
detail: "No signer-runtime.json sidecar \u2014 the pinned signer runtime was never prepared (or a pre-#1586 npx config).",
|
|
3460
3660
|
repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}`
|
|
3461
3661
|
});
|
|
3662
|
+
} else if (sidecar.runtime_spec_override) {
|
|
3663
|
+
const matches = await installedRuntimeMatchesVersions(sidecar.runtime_directory, sidecar.cli_path, {
|
|
3664
|
+
signerVersion: sidecar.signer_version,
|
|
3665
|
+
sdkVersion: sidecar.sdk_version
|
|
3666
|
+
});
|
|
3667
|
+
checks.push({
|
|
3668
|
+
id: "signer_runtime",
|
|
3669
|
+
label: "Signer runtime (preinstalled wrapper)",
|
|
3670
|
+
ok: matches,
|
|
3671
|
+
detail: matches ? `Installed ${sidecar.signer_package}@${sidecar.signer_version} at ${sidecar.runtime_directory} (override install \u2014 see runtime_spec_override)` : `Override runtime directory is stale or empty (${sidecar.runtime_directory}) \u2014 the CLI or package versions are missing.`,
|
|
3672
|
+
...matches ? {} : { repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime} with the same HAVEN_*_SPEC variables set.` }
|
|
3673
|
+
});
|
|
3462
3674
|
} else {
|
|
3463
3675
|
const matches = await installedRuntimeMatches(sidecar.runtime_directory, sidecar.cli_path);
|
|
3464
3676
|
const versionOk = sidecar.signer_version === MCP_RUNTIME_MANIFEST.signerVersion;
|
|
@@ -3471,6 +3683,8 @@ async function checksForAgent(entry, input, deps) {
|
|
|
3471
3683
|
...ok ? {} : { repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}` }
|
|
3472
3684
|
});
|
|
3473
3685
|
}
|
|
3686
|
+
const overrideCheck = await runtimeSpecOverrideCheck(directory, sidecar, deps.env ?? process.env);
|
|
3687
|
+
if (overrideCheck) checks.push(overrideCheck);
|
|
3474
3688
|
const hostedUrl = identity?.hosted_mcp_url ?? (identity?.api_url ? `${identity.api_url}/mcp` : void 0);
|
|
3475
3689
|
if (identity?.api_key && hostedUrl) {
|
|
3476
3690
|
const probe = await (deps.probeHosted ?? probeHostedMcpTools)(identity.api_key, hostedUrl, deps.fetch);
|
|
@@ -3665,7 +3879,7 @@ async function runDoctor(input, deps = {}) {
|
|
|
3665
3879
|
signerCapabilities = result.signerCapabilities;
|
|
3666
3880
|
for (const check of result.checks) primaryChecksById.set(check.id, check);
|
|
3667
3881
|
}
|
|
3668
|
-
for (const id of ["credentials", "signer_runtime"]) {
|
|
3882
|
+
for (const id of ["credentials", "signer_runtime", "runtime_spec_override"]) {
|
|
3669
3883
|
const check = primaryChecksById.get(id);
|
|
3670
3884
|
if (check) checks.push(check);
|
|
3671
3885
|
}
|
|
@@ -3828,7 +4042,7 @@ async function runRepair(input, deps = {}) {
|
|
|
3828
4042
|
const signerPath = path.join(directory, "signer.json");
|
|
3829
4043
|
const prepared = await prepareSignerRuntime(
|
|
3830
4044
|
{ credentialDirectory: directory, signerPath, homeDir, serverName },
|
|
3831
|
-
{ runCommand: deps.runCommand }
|
|
4045
|
+
{ runCommand: deps.runCommand, env: deps.env }
|
|
3832
4046
|
);
|
|
3833
4047
|
messages.push(...prepared.messages);
|
|
3834
4048
|
const names = serverNamesFor(serverName);
|
|
@@ -3855,6 +4069,7 @@ var init_doctor = __esm({
|
|
|
3855
4069
|
init_runtime_manifest();
|
|
3856
4070
|
init_probes();
|
|
3857
4071
|
init_signer_runtime();
|
|
4072
|
+
init_runtime_spec_override();
|
|
3858
4073
|
init_config_writers();
|
|
3859
4074
|
init_runtime_registry();
|
|
3860
4075
|
init_signer_consent();
|
|
@@ -4055,7 +4270,7 @@ function defaultPromptIo() {
|
|
|
4055
4270
|
// src/runtime.ts
|
|
4056
4271
|
init_local_mcp_runtime();
|
|
4057
4272
|
init_runtime_manifest();
|
|
4058
|
-
var CONNECTOR_VERSION = "0.0.0-dev.
|
|
4273
|
+
var CONNECTOR_VERSION = "0.0.0-dev.202609031608.fceb089";
|
|
4059
4274
|
var CONNECT_OUTCOME_SCHEMA_VERSION = 1;
|
|
4060
4275
|
var failureOutcomesByError = /* @__PURE__ */ new WeakMap();
|
|
4061
4276
|
function failureOutcomeFor(runtimeHint, error) {
|