diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d4907ef21..1e01ff8fad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ _In development — bullets added per PR; finalized at release._ ### ✨ New Features - **feat(api): `x-omniroute-no-memory` request header — per-request opt-out of memory/skills injection** — clients that manage their own context (e.g. their own RAG/memory) can send `x-omniroute-no-memory: true` (mirrors the existing `x-omniroute-no-cache` convention) to skip the gateway injecting up to `memorySettings.maxTokens` (~2k) tokens of memory **and** skills context into that chat request — avoiding the token/cost inflation it otherwise adds on every call. Absent the header, behavior is unchanged. (PRD-2026-06-19-no-memory-header) +- **feat(dashboard): MITM tool card lists the exact hosts-file entries to add manually** — the CLI-tools MITM card's "How it works" section now lists the full set of `127.0.0.1 ` lines for the selected tool (sourced from the canonical MITM target registry) instead of a single example domain. Users on locked-down machines — where the automatic, sudo-gated hosts-file edit isn't available — can now copy every required entry by hand. (thanks @mrcyclo) ### 🔧 Changed diff --git a/src/app/(dashboard)/dashboard/cli-code/components/AntigravityToolCard.tsx b/src/app/(dashboard)/dashboard/cli-code/components/AntigravityToolCard.tsx index 7dfb0781c9..b385f09385 100644 --- a/src/app/(dashboard)/dashboard/cli-code/components/AntigravityToolCard.tsx +++ b/src/app/(dashboard)/dashboard/cli-code/components/AntigravityToolCard.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from "react"; import { Card, Button, Badge, Modal, Input, ModelSelectModal } from "@/shared/components"; +import { MITM_TOOL_HOSTS } from "@/shared/constants/mitmToolHosts"; import { useTranslations } from "next-intl"; import ProviderIcon from "@/shared/components/ProviderIcon"; @@ -364,13 +365,11 @@ export default function AntigravityToolCard({ {/* When stopped: how it works */} {!isRunning && (() => { - // Dynamic MITM instructions per tool (#505) - const mitmDomains: Record = { - antigravity: "daily-cloudcode-pa.googleapis.com", - kiro: "api.anthropic.com", - }; + // Per-tool MITM hosts redirected to 127.0.0.1 (#505, 9router#788). List every + // host so users on locked-down machines can add the entries to their hosts file + // manually when the automatic (sudo-gated) edit isn't available. const toolName = tool.name || tool.id; - const domain = mitmDomains[tool.id] || mitmDomains.antigravity; + const hosts = MITM_TOOL_HOSTS[tool.id] ?? MITM_TOOL_HOSTS.antigravity; return (

@@ -379,11 +378,15 @@ export default function AntigravityToolCard({

{t("mitmStep1")} - - {t("mitmStep2Prefix")}{" "} - {domain}{" "} - {t("mitmStep2Suffix")} - + {t("mitmStep2Prefix")} +
    + {hosts.map((host) => ( +
  • + 127.0.0.1 {host} +
  • + ))} +
+ {t("mitmStep2Suffix")} {t("mitmStep3", { toolName })}
diff --git a/src/shared/constants/mitmToolHosts.ts b/src/shared/constants/mitmToolHosts.ts new file mode 100644 index 0000000000..f5634e53bd --- /dev/null +++ b/src/shared/constants/mitmToolHosts.ts @@ -0,0 +1,31 @@ +/** + * Per-tool MITM DNS hosts — the domains redirected to 127.0.0.1 when a tool's MITM DNS + * routing is enabled. Surfaced in the dashboard so users on locked-down machines (where the + * automatic hosts-file edit needs admin/sudo) can add the entries manually. + * + * This is a CLIENT-SAFE projection of the canonical server-side registry in + * `src/mitm/targets/`. The MITM target modules pull in node-only handler logic, so the + * dashboard cannot import them directly — this plain-data map is kept in lock-step with + * `ALL_TARGETS` by `tests/unit/mitm-tool-hosts.test.ts` (a drift here fails that test). + */ +export const MITM_TOOL_HOSTS: Record = { + antigravity: [ + "daily-cloudcode-pa.googleapis.com", + "cloudcode-pa.googleapis.com", + "daily-cloudcode-pa.sandbox.googleapis.com", + "autopush-cloudcode-pa.sandbox.googleapis.com", + ], + kiro: ["api.anthropic.com"], + copilot: ["api.githubcopilot.com", "copilot-proxy.githubusercontent.com"], + codex: ["chatgpt.com"], + cursor: ["api2.cursor.sh"], + zed: ["api.zed.dev"], + "claude-code": ["api.anthropic.com"], + "open-code": ["opencode.ai"], + trae: ["trae.invalid"], +}; + +/** Hosts for a tool id, falling back to an empty list for unknown ids. */ +export function getMitmToolHosts(toolId: string): string[] { + return MITM_TOOL_HOSTS[toolId] ?? []; +} diff --git a/tests/unit/mitm-tool-hosts.test.ts b/tests/unit/mitm-tool-hosts.test.ts new file mode 100644 index 0000000000..9023cfabf7 --- /dev/null +++ b/tests/unit/mitm-tool-hosts.test.ts @@ -0,0 +1,26 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +import { ALL_TARGETS } from "../../src/mitm/targets/index.ts"; +import { MITM_TOOL_HOSTS, getMitmToolHosts } from "../../src/shared/constants/mitmToolHosts.ts"; + +// The dashboard cannot import the node-only MITM target modules, so MITM_TOOL_HOSTS is a +// client-safe copy of each target's hosts. This guards against the copy drifting from the +// canonical registry (port from 9router#788). +test("MITM_TOOL_HOSTS stays in sync with the canonical MITM target registry", () => { + const fromRegistry: Record = {}; + for (const target of ALL_TARGETS) { + fromRegistry[target.id] = target.hosts; + } + + assert.deepEqual( + MITM_TOOL_HOSTS, + fromRegistry, + "MITM_TOOL_HOSTS must exactly match ALL_TARGETS hosts — update src/shared/constants/mitmToolHosts.ts" + ); +}); + +test("getMitmToolHosts returns the hosts for a known tool and [] for unknown ids", () => { + assert.ok(getMitmToolHosts("antigravity").includes("cloudcode-pa.googleapis.com")); + assert.deepEqual(getMitmToolHosts("does-not-exist"), []); +});