feat(cli-tools): replace copilot mitm with vscode extension setup guide
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ import { getModelsByProviderId, PROVIDER_ID_TO_ALIAS } from "@/shared/constants/
|
|||||||
import {
|
import {
|
||||||
ClaudeToolCard, CodexToolCard, DroidToolCard, OpenClawToolCard,
|
ClaudeToolCard, CodexToolCard, DroidToolCard, OpenClawToolCard,
|
||||||
HermesToolCard, DefaultToolCard, OpenCodeToolCard, CoworkToolCard,
|
HermesToolCard, DefaultToolCard, OpenCodeToolCard, CoworkToolCard,
|
||||||
CopilotToolCard, ClineToolCard, KiloToolCard, DeepSeekTuiToolCard,
|
ClineToolCard, KiloToolCard, DeepSeekTuiToolCard,
|
||||||
JcodeToolCard, GrokBuildToolCard,
|
JcodeToolCard, GrokBuildToolCard,
|
||||||
} from "../components";
|
} from "../components";
|
||||||
|
|
||||||
@@ -156,8 +156,6 @@ export default function ToolDetailClient({ toolId, machineId }) {
|
|||||||
return <OpenClawToolCard {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
|
return <OpenClawToolCard {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
|
||||||
case "hermes":
|
case "hermes":
|
||||||
return <HermesToolCard {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
|
return <HermesToolCard {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
|
||||||
case "copilot":
|
|
||||||
return <CopilotToolCard {...commonProps} activeProviders={getActiveProviders()} cloudEnabled={cloudEnabled} />;
|
|
||||||
case "cline":
|
case "cline":
|
||||||
return <ClineToolCard {...commonProps} activeProviders={getActiveProviders()} cloudEnabled={cloudEnabled} />;
|
return <ClineToolCard {...commonProps} activeProviders={getActiveProviders()} cloudEnabled={cloudEnabled} />;
|
||||||
case "kilo":
|
case "kilo":
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import Image from "next/image";
|
|||||||
import { Card } from "@/shared/components";
|
import { Card } from "@/shared/components";
|
||||||
|
|
||||||
// Derive simple connected/configured/not-installed status from API payload
|
// Derive simple connected/configured/not-installed status from API payload
|
||||||
function getStatus(status) {
|
function getStatus(status, tool) {
|
||||||
|
if (tool?.configType === "guide") return { label: "Guide", cls: "bg-blue-500/10 text-blue-600 dark:text-blue-400" };
|
||||||
if (!status) return { label: "Unknown", cls: "bg-gray-500/10 text-gray-500" };
|
if (!status) return { label: "Unknown", cls: "bg-gray-500/10 text-gray-500" };
|
||||||
if (!status.installed) return { label: "Not installed", cls: "bg-gray-500/10 text-gray-500" };
|
if (!status.installed) return { label: "Not installed", cls: "bg-gray-500/10 text-gray-500" };
|
||||||
if (status.has9Router) return { label: "Connected", cls: "bg-green-500/10 text-green-600 dark:text-green-400" };
|
if (status.has9Router) return { label: "Connected", cls: "bg-green-500/10 text-green-600 dark:text-green-400" };
|
||||||
@@ -13,7 +14,7 @@ function getStatus(status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ToolSummaryCard({ toolId, tool, status }) {
|
export default function ToolSummaryCard({ toolId, tool, status }) {
|
||||||
const s = getStatus(status);
|
const s = getStatus(status, tool);
|
||||||
return (
|
return (
|
||||||
<Link href={`/dashboard/cli-tools/${toolId}`} className="block">
|
<Link href={`/dashboard/cli-tools/${toolId}`} className="block">
|
||||||
<Card padding="sm" className="h-full overflow-hidden hover:border-primary/50 transition-colors cursor-pointer">
|
<Card padding="sm" className="h-full overflow-hidden hover:border-primary/50 transition-colors cursor-pointer">
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { GET as droidGet } from "../droid-settings/route";
|
|||||||
import { GET as openclawGet } from "../openclaw-settings/route";
|
import { GET as openclawGet } from "../openclaw-settings/route";
|
||||||
import { GET as hermesGet } from "../hermes-settings/route";
|
import { GET as hermesGet } from "../hermes-settings/route";
|
||||||
import { GET as coworkGet } from "../cowork-settings/route";
|
import { GET as coworkGet } from "../cowork-settings/route";
|
||||||
import { GET as copilotGet } from "../copilot-settings/route";
|
|
||||||
import { GET as clineGet } from "../cline-settings/route";
|
import { GET as clineGet } from "../cline-settings/route";
|
||||||
import { GET as kiloGet } from "../kilo-settings/route";
|
import { GET as kiloGet } from "../kilo-settings/route";
|
||||||
import { GET as deepseekTuiGet } from "../deepseek-tui-settings/route";
|
import { GET as deepseekTuiGet } from "../deepseek-tui-settings/route";
|
||||||
@@ -24,7 +23,6 @@ const STATUS_GETTERS = {
|
|||||||
openclaw: openclawGet,
|
openclaw: openclawGet,
|
||||||
hermes: hermesGet,
|
hermes: hermesGet,
|
||||||
cowork: coworkGet,
|
cowork: coworkGet,
|
||||||
copilot: copilotGet,
|
|
||||||
cline: clineGet,
|
cline: clineGet,
|
||||||
kilo: kiloGet,
|
kilo: kiloGet,
|
||||||
"deepseek-tui": deepseekTuiGet,
|
"deepseek-tui": deepseekTuiGet,
|
||||||
|
|||||||
@@ -30,32 +30,6 @@ export const MITM_TOOLS = {
|
|||||||
{ id: "gemini-3-flash", name: "Gemini 3 Flash (Command)", alias: "gemini-3-flash" },
|
{ id: "gemini-3-flash", name: "Gemini 3 Flash (Command)", alias: "gemini-3-flash" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
copilot: {
|
|
||||||
id: "copilot",
|
|
||||||
name: "GitHub Copilot",
|
|
||||||
image: "/providers/copilot.png",
|
|
||||||
color: "#1F6FEB",
|
|
||||||
description: "GitHub Copilot IDE with MITM",
|
|
||||||
configType: "mitm",
|
|
||||||
mitmDomain: "api.individual.githubcopilot.com",
|
|
||||||
modelAliases: ["gpt-5-mini", "gpt-5.4-nano", "claude-haiku-4.5", "gpt-4o", "gpt-4.1"],
|
|
||||||
defaultModels: [
|
|
||||||
// Verified via live MITM passthrough capture of the GitHub Copilot CLI: its model
|
|
||||||
// picker offers "GPT-5 mini" (default → wire id "gpt-5-mini"), "Claude Haiku 4.5"
|
|
||||||
// ("claude-haiku-4.5") and "Auto". "Auto" is NOT a wire id — Copilot dispatches
|
|
||||||
// concrete models dynamically (observed "gpt-5.4-nano" for light tasks and
|
|
||||||
// "claude-haiku-4.5"), so it needs no slot of its own. Without a slot for
|
|
||||||
// gpt-5-mini / gpt-5.4-nano, getMappedModel returns null and the /chat/completions
|
|
||||||
// call is passed through to GitHub Copilot instead of the configured provider —
|
|
||||||
// and gpt-5-mini is the CLI default, so the primary turn leaks (same class as the
|
|
||||||
// Kiro "auto" misrouting). gpt-4o / gpt-4.1 are kept for the VS Code Copilot Chat picker.
|
|
||||||
{ id: "gpt-5-mini", name: "GPT-5 mini", alias: "gpt-5-mini" },
|
|
||||||
{ id: "gpt-5.4-nano", name: "GPT-5.4 nano", alias: "gpt-5.4-nano" },
|
|
||||||
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5", alias: "claude-haiku-4.5" },
|
|
||||||
{ id: "gpt-4o", name: "GPT-4o", alias: "gpt-4o" },
|
|
||||||
{ id: "gpt-4.1", name: "GPT-4.1", alias: "gpt-4.1" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
kiro: {
|
kiro: {
|
||||||
id: "kiro",
|
id: "kiro",
|
||||||
name: "Kiro",
|
name: "Kiro",
|
||||||
@@ -140,6 +114,34 @@ export const CLI_TOOLS = {
|
|||||||
description: "OpenAI Codex CLI",
|
description: "OpenAI Codex CLI",
|
||||||
configType: "custom",
|
configType: "custom",
|
||||||
},
|
},
|
||||||
|
copilot: {
|
||||||
|
id: "copilot",
|
||||||
|
name: "GitHub Copilot",
|
||||||
|
image: "/providers/copilot.png",
|
||||||
|
color: "#1F6FEB",
|
||||||
|
description: "GitHub Copilot in VS Code via 9Router extension",
|
||||||
|
configType: "guide",
|
||||||
|
docsUrl: "https://marketplace.visualstudio.com/items?itemName=hotrungnhan.9router-for-github-copilot",
|
||||||
|
guideSteps: [
|
||||||
|
{
|
||||||
|
step: 1,
|
||||||
|
title: "Install Extension",
|
||||||
|
desc: "In VS Code, open Extensions (Ctrl+Shift+X or Cmd+Shift+X), search for '9Router for Github Copilot' and click Install.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 2,
|
||||||
|
title: "Configure Server",
|
||||||
|
desc: "Press Cmd+Shift+P (or Ctrl+Shift+P), run '9Router: Configure Server', then enter your Server URL and API Key:",
|
||||||
|
value: "{{baseUrl}}",
|
||||||
|
copyable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 3,
|
||||||
|
title: "Select Model in Copilot Chat",
|
||||||
|
desc: "Open Copilot Chat, click the model picker at the bottom → 'Manage Models...' → check the 9Router models to use.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
opencode: {
|
opencode: {
|
||||||
id: "opencode",
|
id: "opencode",
|
||||||
name: "OpenCode",
|
name: "OpenCode",
|
||||||
|
|||||||
Reference in New Issue
Block a user