multicorn-shield 1.0.0 → 1.1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.0] - 2026-05-06
9
+
10
+ ### Added
11
+
12
+ - Kilo Code as a hosted proxy platform
13
+ - GitHub Copilot as a hosted proxy platform
14
+ - Continue as a hosted proxy platform
15
+ - Goose as a hosted proxy platform
16
+ - Claude Desktop as a hosted proxy platform
17
+ - Prereq check step in CLI wizard for all hosted proxy platforms
18
+ - Platform filter and search in dashboard platform select
19
+
20
+ ### Changed
21
+
22
+ - GitHub Copilot moved from native plugin to hosted proxy section in CLI wizard
23
+ - Kilo Code config snippet now includes `"type": "streamable-http"`
24
+ - Goose config snippet uses `"type": "streamable_http"` and `"url"` (SSE deprecated)
25
+ - ProxySetup is now a stepped wizard (prereq check, OS selection, proxy form, snippet, completion)
26
+ - Short name prompt removed from CLI wizard (uses agent name automatically)
27
+
28
+ ### Removed
29
+
30
+ - Aider as a supported platform (no MCP client support)
31
+
32
+ ### Fixed
33
+
34
+ - Proxy ALLOW_PRIVATE_TARGETS env var not bypassing localhost validation
35
+ - Goose prereq URL updated (moved from Block to the Agentic AI Foundation (AAIF))
36
+ - Continue prereq URL updated
37
+ - ProxySetup form input contrast (WCAG AA fix)
38
+ - Governance disclosure now lists all four native plugin platforms
39
+
8
40
  ## [1.0.0] - 2026-05-02
9
41
 
10
42
  ### Changed
package/dist/index.cjs CHANGED
@@ -22,6 +22,10 @@ var AGENT_PLATFORM_SLUGS = [
22
22
  "windsurf",
23
23
  "cline",
24
24
  "gemini-cli",
25
+ "continue-dev",
26
+ "github-copilot",
27
+ "goose",
28
+ "kilo-code",
25
29
  "other-mcp",
26
30
  "github-actions",
27
31
  "unknown"
package/dist/index.d.cts CHANGED
@@ -12,7 +12,7 @@ import { LitElement, PropertyValues, HTMLTemplateResult } from 'lit';
12
12
  /**
13
13
  * Agent client platforms supported by hosted proxy and native hooks (aligned with API validation).
14
14
  */
15
- declare const AGENT_PLATFORM_SLUGS: readonly ["openclaw", "claude-code", "claude-desktop", "cursor", "windsurf", "cline", "gemini-cli", "other-mcp", "github-actions", "unknown"];
15
+ declare const AGENT_PLATFORM_SLUGS: readonly ["openclaw", "claude-code", "claude-desktop", "cursor", "windsurf", "cline", "gemini-cli", "continue-dev", "github-copilot", "goose", "kilo-code", "other-mcp", "github-actions", "unknown"];
16
16
  type AgentPlatformSlug = (typeof AGENT_PLATFORM_SLUGS)[number];
17
17
  /**
18
18
  * Possible operational states for an agent.
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ import { LitElement, PropertyValues, HTMLTemplateResult } from 'lit';
12
12
  /**
13
13
  * Agent client platforms supported by hosted proxy and native hooks (aligned with API validation).
14
14
  */
15
- declare const AGENT_PLATFORM_SLUGS: readonly ["openclaw", "claude-code", "claude-desktop", "cursor", "windsurf", "cline", "gemini-cli", "other-mcp", "github-actions", "unknown"];
15
+ declare const AGENT_PLATFORM_SLUGS: readonly ["openclaw", "claude-code", "claude-desktop", "cursor", "windsurf", "cline", "gemini-cli", "continue-dev", "github-copilot", "goose", "kilo-code", "other-mcp", "github-actions", "unknown"];
16
16
  type AgentPlatformSlug = (typeof AGENT_PLATFORM_SLUGS)[number];
17
17
  /**
18
18
  * Possible operational states for an agent.
package/dist/index.js CHANGED
@@ -20,6 +20,10 @@ var AGENT_PLATFORM_SLUGS = [
20
20
  "windsurf",
21
21
  "cline",
22
22
  "gemini-cli",
23
+ "continue-dev",
24
+ "github-copilot",
25
+ "goose",
26
+ "kilo-code",
23
27
  "other-mcp",
24
28
  "github-actions",
25
29
  "unknown"
@@ -752,31 +752,73 @@ function getClaudeDesktopConfigPath() {
752
752
  );
753
753
  }
754
754
  }
755
+ function platformMenuLabelForSelection(sel) {
756
+ const slug = PLATFORM_BY_SELECTION[sel];
757
+ if (slug === void 0) return "Unknown";
758
+ const entry = INIT_WIZARD_PLATFORM_REGISTRY.find((e) => e.slug === slug);
759
+ return entry?.displayName ?? slug;
760
+ }
761
+ async function promptHostedProxyInstallPrereq(ask, platformLabel, prereqUrl) {
762
+ process.stderr.write("\n");
763
+ process.stderr.write(
764
+ style.bold("Before continuing, make sure you have ") + platformLabel + style.bold(" installed.") + "\n"
765
+ );
766
+ process.stderr.write(" \u2192 " + style.cyan(prereqUrl) + "\n\n");
767
+ const answer = await ask("Ready to continue? (Y/n) ");
768
+ return answer.trim().toLowerCase() !== "n";
769
+ }
770
+ function isPlatformDetectedForMenu(slug) {
771
+ switch (slug) {
772
+ case "openclaw":
773
+ return isOpenClawConnected();
774
+ case "claude-code":
775
+ return Promise.resolve(isClaudeCodeConnected());
776
+ case "cursor":
777
+ return isCursorConnected();
778
+ case "windsurf":
779
+ return isWindsurfConnected();
780
+ default:
781
+ return Promise.resolve(false);
782
+ }
783
+ }
755
784
  async function promptPlatformSelection(ask) {
756
785
  process.stderr.write(
757
- "\n" + style.bold(style.violet("Which platform are you connecting?")) + "\n"
786
+ "\n" + style.bold(style.violet("Which platform are you connecting?")) + "\n\n"
758
787
  );
759
- const connectedFlags = [
760
- await isOpenClawConnected(),
761
- isClaudeCodeConnected(),
762
- await isCursorConnected(),
763
- await isWindsurfConnected()
764
- ];
765
- for (let i = 0; i < PLATFORM_LABELS.length; i++) {
766
- const marker = i < connectedFlags.length && connectedFlags[i] ? " " + style.dim("\u25CF detected locally") : "";
767
- process.stderr.write(
768
- ` ${style.violet(String(i + 1))}. ${PLATFORM_LABELS[i] ?? ""}${marker}
788
+ const detectionSlugs = INIT_WIZARD_PLATFORM_REGISTRY.filter((e) => e.detectable).map(
789
+ (e) => e.slug
790
+ );
791
+ const connectedFlags = await Promise.all(
792
+ detectionSlugs.map((slug) => isPlatformDetectedForMenu(slug))
793
+ );
794
+ function markerFor(platform) {
795
+ const idx = detectionSlugs.indexOf(platform);
796
+ if (idx === -1) return "";
797
+ if (!connectedFlags[idx]) return "";
798
+ return " " + style.dim("\u25CF detected locally");
799
+ }
800
+ let optionNum = 1;
801
+ for (const section of INIT_WIZARD_MENU_SECTIONS) {
802
+ process.stderr.write(" " + style.dim(section.title) + "\n");
803
+ for (const item of section.items) {
804
+ const indent = optionNum >= 10 ? " " : " ";
805
+ process.stderr.write(
806
+ `${indent}${style.violet(String(optionNum))}. ${item.label}${markerFor(item.platform)}
769
807
  `
770
- );
808
+ );
809
+ optionNum++;
810
+ }
771
811
  }
772
812
  process.stderr.write(
773
- style.dim(" Pick 8 if you want to wrap a local MCP server with multicorn-shield --wrap.") + "\n"
813
+ "\n" + style.dim(
814
+ ` Pick ${String(INIT_WIZARD_SELECTION_MAX)} to wrap a local MCP server with multicorn-shield --wrap.`
815
+ ) + "\n"
774
816
  );
775
817
  let selection = 0;
776
818
  while (selection === 0) {
777
- const input = await ask("Select (1-8): ");
819
+ const input = await ask(`Select (1-${String(INIT_WIZARD_SELECTION_MAX)}): `);
778
820
  const num = parseInt(input.trim(), 10);
779
- if (num >= 1 && num <= 8) {
821
+ if (num >= 1 && num <= INIT_WIZARD_SELECTION_MAX) {
780
822
  selection = num;
781
823
  }
782
824
  }
@@ -847,12 +889,7 @@ async function promptProxyConfig(ask, agentName) {
847
889
  }
848
890
  targetUrl = input.trim();
849
891
  }
850
- const defaultShortName = normalizeAgentName(agentName) || "shield-mcp";
851
- const shortNameInput = await ask(
852
- `
853
- Short name (a nickname for this connection, used in your proxy URL): ${style.dim(`(${defaultShortName})`)} `
854
- );
855
- const shortName = shortNameInput.trim().length > 0 ? normalizeAgentName(shortNameInput.trim()) || defaultShortName : defaultShortName;
892
+ const shortName = normalizeAgentName(agentName) || "shield-mcp";
856
893
  return { targetUrl, shortName };
857
894
  }
858
895
  async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverName, platform) {
@@ -896,24 +933,84 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
896
933
  const data = envelope["data"];
897
934
  return typeof data?.["proxy_url"] === "string" ? data["proxy_url"] : "";
898
935
  }
936
+ function gooseHostedProxyYaml(shortName, proxyUrl, bearerHeader) {
937
+ return `extensions:
938
+ ${shortName}:
939
+ type: streamable_http
940
+ url: ${proxyUrl}
941
+ headers:
942
+ Authorization: ${bearerHeader}
943
+ enabled: true
944
+ timeout: 300
945
+ `;
946
+ }
899
947
  function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
900
- const usesInlineKey = platform === "cursor" || platform === "claude-desktop" || platform === "windsurf" || platform === "cline" || platform === "gemini-cli";
948
+ const hostedInlinePlatforms = /* @__PURE__ */ new Set([
949
+ "cursor",
950
+ "claude-desktop",
951
+ "windsurf",
952
+ "cline",
953
+ "gemini-cli",
954
+ "kilo-code",
955
+ "github-copilot",
956
+ "continue-dev",
957
+ "goose"
958
+ ]);
959
+ const usesInlineKey = hostedInlinePlatforms.has(platform);
901
960
  const authHeader = usesInlineKey ? `Bearer ${apiKey}` : "Bearer YOUR_SHIELD_API_KEY";
902
- const urlKey = platform === "windsurf" ? "serverUrl" : platform === "gemini-cli" ? "httpUrl" : "url";
903
- const mcpSnippet = JSON.stringify(
904
- {
905
- mcpServers: {
906
- [shortName]: {
907
- [urlKey]: routingToken,
908
- headers: {
909
- Authorization: authHeader
961
+ let snippetText;
962
+ if (platform === "github-copilot") {
963
+ snippetText = JSON.stringify(
964
+ {
965
+ mcp: {
966
+ servers: {
967
+ [shortName]: {
968
+ type: "http",
969
+ url: routingToken,
970
+ headers: {
971
+ Authorization: authHeader
972
+ }
973
+ }
910
974
  }
911
975
  }
912
- }
913
- },
914
- null,
915
- 2
916
- );
976
+ },
977
+ null,
978
+ 2
979
+ );
980
+ } else if (platform === "goose") {
981
+ snippetText = gooseHostedProxyYaml(shortName, routingToken, authHeader);
982
+ } else if (platform === "gemini-cli") {
983
+ snippetText = JSON.stringify(
984
+ {
985
+ mcpServers: {
986
+ [shortName]: {
987
+ httpUrl: routingToken,
988
+ headers: {
989
+ Authorization: authHeader
990
+ }
991
+ }
992
+ }
993
+ },
994
+ null,
995
+ 2
996
+ );
997
+ } else {
998
+ const urlKey = platform === "windsurf" ? "serverUrl" : "url";
999
+ snippetText = JSON.stringify(
1000
+ {
1001
+ mcpServers: {
1002
+ [shortName]: {
1003
+ [urlKey]: routingToken,
1004
+ headers: {
1005
+ Authorization: authHeader
1006
+ }
1007
+ }
1008
+ }
1009
+ },
1010
+ null,
1011
+ 2
1012
+ );
1013
+ }
917
1014
  if (platform === "openclaw") {
918
1015
  process.stderr.write("\n" + style.dim("Add this to your OpenClaw agent config:") + "\n\n");
919
1016
  } else if (platform === "claude-code") {
@@ -947,10 +1044,28 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
947
1044
  "Add this to ~/.gemini/settings.json (create the file if it does not exist). For project-specific config, use .gemini/settings.json in your project root. Restart Gemini CLI after saving. Run /mcp to verify the server is connected."
948
1045
  ) + "\n\n"
949
1046
  );
1047
+ } else if (platform === "kilo-code") {
1048
+ process.stderr.write(
1049
+ "\n" + style.dim("Add this to .kilocode/mcp.json in your project root.") + "\n\n"
1050
+ );
1051
+ } else if (platform === "github-copilot") {
1052
+ process.stderr.write(
1053
+ "\n" + style.dim(
1054
+ "Open VS Code Settings (JSON) and merge this under the mcp key. If you do not have an mcp section yet, add one. Copilot picks up MCP servers when you use Agent mode."
1055
+ ) + "\n\n"
1056
+ );
1057
+ } else if (platform === "continue-dev") {
1058
+ process.stderr.write(
1059
+ "\n" + style.dim("Save this as .continue/mcpServers/shield.json in your workspace root.") + "\n\n"
1060
+ );
1061
+ } else if (platform === "goose") {
1062
+ process.stderr.write(
1063
+ "\n" + style.dim("Add this to ~/.config/goose/config.yaml under the extensions key.") + "\n\n"
1064
+ );
950
1065
  } else {
951
1066
  process.stderr.write("\n" + style.dim("Add this to ~/.cursor/mcp.json:") + "\n\n");
952
1067
  }
953
- process.stderr.write(style.cyan(mcpSnippet) + "\n\n");
1068
+ process.stderr.write(style.cyan(snippetText) + "\n\n");
954
1069
  if (!usesInlineKey) {
955
1070
  process.stderr.write(
956
1071
  style.dim(
@@ -988,6 +1103,14 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
988
1103
  ) + "\n"
989
1104
  );
990
1105
  }
1106
+ if (platform === "github-copilot" || platform === "continue-dev") {
1107
+ process.stderr.write(
1108
+ style.dim("Reload the editor window if the MCP server does not appear immediately.") + "\n"
1109
+ );
1110
+ }
1111
+ if (platform === "goose") {
1112
+ process.stderr.write(style.dim("Start a new Goose session after updating config.") + "\n");
1113
+ }
991
1114
  }
992
1115
  async function runInit(explicitBaseUrl) {
993
1116
  if (!process.stdin.isTTY) {
@@ -1076,8 +1199,8 @@ async function runInit(explicitBaseUrl) {
1076
1199
  let postSaveNativeSkipNote = null;
1077
1200
  const selection = await promptPlatformSelection(ask);
1078
1201
  const selectedPlatform = PLATFORM_BY_SELECTION[selection] ?? "cursor";
1079
- const selectedLabel = PLATFORM_LABELS[selection - 1] ?? "Cursor";
1080
- if (selection === 8) {
1202
+ const selectedLabel = platformMenuLabelForSelection(selection);
1203
+ if (selectedPlatform === "other-mcp") {
1081
1204
  const raw = existing !== null ? { ...existing } : {};
1082
1205
  raw["apiKey"] = apiKey;
1083
1206
  raw["baseUrl"] = resolvedBaseUrl;
@@ -1127,9 +1250,24 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1127
1250
  continue;
1128
1251
  }
1129
1252
  }
1253
+ const prereqEntry = INIT_WIZARD_PLATFORM_REGISTRY.find((e) => e.slug === selectedPlatform);
1254
+ if (prereqEntry?.prereqUrl !== void 0) {
1255
+ const proceed = await promptHostedProxyInstallPrereq(
1256
+ ask,
1257
+ prereqEntry.displayName,
1258
+ prereqEntry.prereqUrl
1259
+ );
1260
+ if (!proceed) {
1261
+ const another2 = await ask("\nConnect another agent? (Y/n) ");
1262
+ if (another2.trim().toLowerCase() === "n") {
1263
+ configuring = false;
1264
+ }
1265
+ continue;
1266
+ }
1267
+ }
1130
1268
  const agentName = await promptAgentName(ask, selectedPlatform);
1131
1269
  let setupSucceeded = false;
1132
- if (selection === 1) {
1270
+ if (selectedPlatform === "openclaw") {
1133
1271
  let detection;
1134
1272
  try {
1135
1273
  detection = await detectOpenClaw();
@@ -1209,7 +1347,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1209
1347
  agentName
1210
1348
  });
1211
1349
  setupSucceeded = true;
1212
- } else if (selection === 2) {
1350
+ } else if (selectedPlatform === "claude-code") {
1213
1351
  process.stderr.write("\nTo connect Claude Code to Shield:\n\n");
1214
1352
  process.stderr.write(
1215
1353
  " " + style.bold("Step 1") + " - Add the Multicorn marketplace:\n " + style.cyan("claude plugin marketplace add Multicorn-AI/multicorn-shield") + "\n\n"
@@ -1227,7 +1365,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1227
1365
  agentName
1228
1366
  });
1229
1367
  setupSucceeded = true;
1230
- } else if (selection === 4) {
1368
+ } else if (selectedPlatform === "windsurf") {
1231
1369
  const windsurfMode = await promptWindsurfIntegrationMode(ask);
1232
1370
  if (windsurfMode === "native") {
1233
1371
  try {
@@ -1315,7 +1453,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1315
1453
  setupSucceeded = true;
1316
1454
  }
1317
1455
  }
1318
- } else if (selection === 7) {
1456
+ } else if (selectedPlatform === "gemini-cli") {
1319
1457
  const geminiMode = await promptGeminiCliIntegrationMode(ask);
1320
1458
  if (geminiMode === "native") {
1321
1459
  try {
@@ -1400,7 +1538,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1400
1538
  setupSucceeded = true;
1401
1539
  }
1402
1540
  }
1403
- } else if (selection === 5) {
1541
+ } else if (selectedPlatform === "cline") {
1404
1542
  const clineMode = await promptClineIntegrationMode(ask);
1405
1543
  if (clineMode === "native") {
1406
1544
  try {
@@ -1586,6 +1724,26 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1586
1724
  "\n" + style.bold("To complete your Cursor setup:") + "\n 1. If you don't have Cursor yet, download it from " + style.cyan("https://cursor.com/downloads") + "\n 2. Open " + style.cyan("~/.cursor/mcp.json") + " and paste the config snippet shown above\n 3. Restart Cursor (or launch it for the first time) to load the new MCP server\n"
1587
1725
  );
1588
1726
  }
1727
+ if (configuredPlatforms.has("kilo-code")) {
1728
+ blocks.push(
1729
+ "\n" + style.bold("To complete your Kilo Code setup:") + "\n 1. Save the snippet to " + style.cyan(".kilocode/mcp.json") + " in your project root, or under the mcp key in " + style.cyan("kilo.jsonc") + "\n 2. Run your next task in Kilo Code so it picks up the MCP server\n"
1730
+ );
1731
+ }
1732
+ if (configuredPlatforms.has("github-copilot")) {
1733
+ blocks.push(
1734
+ "\n" + style.bold("GitHub Copilot MCP:") + "\n 1. Open VS Code Command Palette: Preferences: Open User Settings (JSON)\n 2. Merge the snippet under the " + style.cyan("mcp") + " key and save\n 3. Use Copilot Agent mode and verify the MCP server connects\n"
1735
+ );
1736
+ }
1737
+ if (configuredPlatforms.has("continue-dev")) {
1738
+ blocks.push(
1739
+ "\n" + style.bold("Continue MCP:") + "\n 1. If you don't have Continue yet, install from " + style.cyan("https://docs.continue.dev/ide-extensions/install") + "\n 2. Save JSON as " + style.cyan(".continue/mcpServers/shield.json") + " in your workspace, or add to " + style.cyan("~/.continue/config.yaml") + "\n 3. Reload VS Code and open Continue agent mode\n"
1740
+ );
1741
+ }
1742
+ if (configuredPlatforms.has("goose")) {
1743
+ blocks.push(
1744
+ "\n" + style.bold("Goose MCP extension:") + "\n 1. Edit " + style.cyan("~/.config/goose/config.yaml") + " (or use goose configure)\n 2. Restart Goose CLI or Desktop\n"
1745
+ );
1746
+ }
1589
1747
  const windsurfNativeConfigured = configuredAgents.some(
1590
1748
  (a) => a.platform === "windsurf" && a.windsurfIntegration === "native"
1591
1749
  );
@@ -1641,7 +1799,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1641
1799
  }
1642
1800
  return lastConfig;
1643
1801
  }
1644
- var style, BANNER, NativePluginPrerequisiteMissingError, CONFIG_DIR, CONFIG_PATH, OPENCLAW_CONFIG_PATH, ANSI_PATTERN, OPENCLAW_MIN_VERSION, PLATFORM_LABELS, PLATFORM_BY_SELECTION, DEFAULT_AGENT_NAMES, DEFAULT_SHIELD_API_BASE_URL;
1802
+ var style, BANNER, NativePluginPrerequisiteMissingError, CONFIG_DIR, CONFIG_PATH, OPENCLAW_CONFIG_PATH, ANSI_PATTERN, OPENCLAW_MIN_VERSION, INIT_WIZARD_PLATFORM_REGISTRY, INIT_WIZARD_MENU_SECTIONS, INIT_WIZARD_SELECTION_MAX, PLATFORM_BY_SELECTION, DEFAULT_AGENT_NAMES, DEFAULT_SHIELD_API_BASE_URL;
1645
1803
  var init_config = __esm({
1646
1804
  "src/proxy/config.ts"() {
1647
1805
  style = {
@@ -1672,26 +1830,70 @@ var init_config = __esm({
1672
1830
  OPENCLAW_CONFIG_PATH = join(homedir(), ".openclaw", "openclaw.json");
1673
1831
  ANSI_PATTERN = new RegExp(String.fromCharCode(27) + "\\[[0-9;]*[a-zA-Z]", "g");
1674
1832
  OPENCLAW_MIN_VERSION = "2026.2.26";
1675
- PLATFORM_LABELS = [
1676
- "OpenClaw",
1677
- "Claude Code",
1678
- "Cursor",
1679
- "Windsurf",
1680
- "Cline",
1681
- "Claude Desktop",
1682
- "Gemini CLI",
1683
- "Local MCP / Other"
1833
+ INIT_WIZARD_PLATFORM_REGISTRY = [
1834
+ { slug: "openclaw", displayName: "OpenClaw", section: "native", detectable: true },
1835
+ { slug: "claude-code", displayName: "Claude Code", section: "native", detectable: true },
1836
+ { slug: "windsurf", displayName: "Windsurf", section: "native", detectable: true },
1837
+ { slug: "cline", displayName: "Cline", section: "native", detectable: false },
1838
+ { slug: "gemini-cli", displayName: "Gemini CLI", section: "native", detectable: false },
1839
+ {
1840
+ slug: "cursor",
1841
+ displayName: "Cursor",
1842
+ section: "hosted",
1843
+ prereqUrl: "https://www.cursor.com/downloads",
1844
+ detectable: true
1845
+ },
1846
+ {
1847
+ slug: "claude-desktop",
1848
+ displayName: "Claude Desktop",
1849
+ section: "hosted",
1850
+ prereqUrl: "https://claude.ai/download",
1851
+ detectable: false
1852
+ },
1853
+ {
1854
+ slug: "github-copilot",
1855
+ displayName: "GitHub Copilot",
1856
+ section: "hosted",
1857
+ prereqUrl: "https://docs.github.com/en/copilot/get-started",
1858
+ detectable: false
1859
+ },
1860
+ {
1861
+ slug: "kilo-code",
1862
+ displayName: "Kilo Code",
1863
+ section: "hosted",
1864
+ prereqUrl: "https://kilocode.ai/docs/getting-started",
1865
+ detectable: false
1866
+ },
1867
+ {
1868
+ slug: "continue-dev",
1869
+ displayName: "Continue",
1870
+ section: "hosted",
1871
+ prereqUrl: "https://docs.continue.dev/ide-extensions/install",
1872
+ detectable: false
1873
+ },
1874
+ {
1875
+ slug: "goose",
1876
+ displayName: "Goose",
1877
+ section: "hosted",
1878
+ prereqUrl: "https://goose-docs.ai/docs/quickstart/",
1879
+ detectable: false
1880
+ },
1881
+ { slug: "other-mcp", displayName: "Local MCP / Other", section: "hosted", detectable: false }
1684
1882
  ];
1685
- PLATFORM_BY_SELECTION = {
1686
- 1: "openclaw",
1687
- 2: "claude-code",
1688
- 3: "cursor",
1689
- 4: "windsurf",
1690
- 5: "cline",
1691
- 6: "claude-desktop",
1692
- 7: "gemini-cli",
1693
- 8: "other-mcp"
1694
- };
1883
+ INIT_WIZARD_MENU_SECTIONS = (() => {
1884
+ const itemsFor = (section) => INIT_WIZARD_PLATFORM_REGISTRY.filter((e) => e.section === section).map((e) => ({
1885
+ platform: e.slug,
1886
+ label: e.displayName
1887
+ }));
1888
+ return [
1889
+ { title: "Recommended (native plugin)", items: itemsFor("native") },
1890
+ { title: "Hosted proxy (MCP only)", items: itemsFor("hosted") }
1891
+ ];
1892
+ })();
1893
+ INIT_WIZARD_SELECTION_MAX = INIT_WIZARD_PLATFORM_REGISTRY.length;
1894
+ PLATFORM_BY_SELECTION = Object.fromEntries(
1895
+ INIT_WIZARD_PLATFORM_REGISTRY.map((e, i) => [i + 1, e.slug])
1896
+ );
1695
1897
  DEFAULT_AGENT_NAMES = {
1696
1898
  openclaw: "my-openclaw-agent",
1697
1899
  "claude-code": "my-claude-code-agent",
@@ -1699,7 +1901,11 @@ var init_config = __esm({
1699
1901
  windsurf: "my-windsurf-agent",
1700
1902
  cline: "my-cline-agent",
1701
1903
  "claude-desktop": "my-claude-desktop-agent",
1702
- "gemini-cli": "my-gemini-cli-agent"
1904
+ "gemini-cli": "my-gemini-cli-agent",
1905
+ "kilo-code": "my-kilo-code-agent",
1906
+ "github-copilot": "my-github-copilot-agent",
1907
+ "continue-dev": "my-continue-agent",
1908
+ goose: "my-goose-agent"
1703
1909
  };
1704
1910
  DEFAULT_SHIELD_API_BASE_URL = "https://api.multicorn.ai";
1705
1911
  }
@@ -771,26 +771,99 @@ function getClaudeDesktopConfigPath() {
771
771
  );
772
772
  }
773
773
  }
774
- var PLATFORM_LABELS = [
775
- "OpenClaw",
776
- "Claude Code",
777
- "Cursor",
778
- "Windsurf",
779
- "Cline",
780
- "Claude Desktop",
781
- "Gemini CLI",
782
- "Local MCP / Other"
774
+ var INIT_WIZARD_PLATFORM_REGISTRY = [
775
+ { slug: "openclaw", displayName: "OpenClaw", section: "native", detectable: true },
776
+ { slug: "claude-code", displayName: "Claude Code", section: "native", detectable: true },
777
+ { slug: "windsurf", displayName: "Windsurf", section: "native", detectable: true },
778
+ { slug: "cline", displayName: "Cline", section: "native", detectable: false },
779
+ { slug: "gemini-cli", displayName: "Gemini CLI", section: "native", detectable: false },
780
+ {
781
+ slug: "cursor",
782
+ displayName: "Cursor",
783
+ section: "hosted",
784
+ prereqUrl: "https://www.cursor.com/downloads",
785
+ detectable: true
786
+ },
787
+ {
788
+ slug: "claude-desktop",
789
+ displayName: "Claude Desktop",
790
+ section: "hosted",
791
+ prereqUrl: "https://claude.ai/download",
792
+ detectable: false
793
+ },
794
+ {
795
+ slug: "github-copilot",
796
+ displayName: "GitHub Copilot",
797
+ section: "hosted",
798
+ prereqUrl: "https://docs.github.com/en/copilot/get-started",
799
+ detectable: false
800
+ },
801
+ {
802
+ slug: "kilo-code",
803
+ displayName: "Kilo Code",
804
+ section: "hosted",
805
+ prereqUrl: "https://kilocode.ai/docs/getting-started",
806
+ detectable: false
807
+ },
808
+ {
809
+ slug: "continue-dev",
810
+ displayName: "Continue",
811
+ section: "hosted",
812
+ prereqUrl: "https://docs.continue.dev/ide-extensions/install",
813
+ detectable: false
814
+ },
815
+ {
816
+ slug: "goose",
817
+ displayName: "Goose",
818
+ section: "hosted",
819
+ prereqUrl: "https://goose-docs.ai/docs/quickstart/",
820
+ detectable: false
821
+ },
822
+ { slug: "other-mcp", displayName: "Local MCP / Other", section: "hosted", detectable: false }
783
823
  ];
784
- var PLATFORM_BY_SELECTION = {
785
- 1: "openclaw",
786
- 2: "claude-code",
787
- 3: "cursor",
788
- 4: "windsurf",
789
- 5: "cline",
790
- 6: "claude-desktop",
791
- 7: "gemini-cli",
792
- 8: "other-mcp"
793
- };
824
+ var INIT_WIZARD_MENU_SECTIONS = (() => {
825
+ const itemsFor = (section) => INIT_WIZARD_PLATFORM_REGISTRY.filter((e) => e.section === section).map((e) => ({
826
+ platform: e.slug,
827
+ label: e.displayName
828
+ }));
829
+ return [
830
+ { title: "Recommended (native plugin)", items: itemsFor("native") },
831
+ { title: "Hosted proxy (MCP only)", items: itemsFor("hosted") }
832
+ ];
833
+ })();
834
+ var INIT_WIZARD_SELECTION_MAX = INIT_WIZARD_PLATFORM_REGISTRY.length;
835
+ var PLATFORM_BY_SELECTION = Object.fromEntries(
836
+ INIT_WIZARD_PLATFORM_REGISTRY.map((e, i) => [i + 1, e.slug])
837
+ );
838
+ function platformMenuLabelForSelection(sel) {
839
+ const slug = PLATFORM_BY_SELECTION[sel];
840
+ if (slug === void 0) return "Unknown";
841
+ const entry = INIT_WIZARD_PLATFORM_REGISTRY.find((e) => e.slug === slug);
842
+ return entry?.displayName ?? slug;
843
+ }
844
+ async function promptHostedProxyInstallPrereq(ask, platformLabel, prereqUrl) {
845
+ process.stderr.write("\n");
846
+ process.stderr.write(
847
+ style.bold("Before continuing, make sure you have ") + platformLabel + style.bold(" installed.") + "\n"
848
+ );
849
+ process.stderr.write(" \u2192 " + style.cyan(prereqUrl) + "\n\n");
850
+ const answer = await ask("Ready to continue? (Y/n) ");
851
+ return answer.trim().toLowerCase() !== "n";
852
+ }
853
+ function isPlatformDetectedForMenu(slug) {
854
+ switch (slug) {
855
+ case "openclaw":
856
+ return isOpenClawConnected();
857
+ case "claude-code":
858
+ return Promise.resolve(isClaudeCodeConnected());
859
+ case "cursor":
860
+ return isCursorConnected();
861
+ case "windsurf":
862
+ return isWindsurfConnected();
863
+ default:
864
+ return Promise.resolve(false);
865
+ }
866
+ }
794
867
  var DEFAULT_AGENT_NAMES = {
795
868
  openclaw: "my-openclaw-agent",
796
869
  "claude-code": "my-claude-code-agent",
@@ -798,33 +871,50 @@ var DEFAULT_AGENT_NAMES = {
798
871
  windsurf: "my-windsurf-agent",
799
872
  cline: "my-cline-agent",
800
873
  "claude-desktop": "my-claude-desktop-agent",
801
- "gemini-cli": "my-gemini-cli-agent"
874
+ "gemini-cli": "my-gemini-cli-agent",
875
+ "kilo-code": "my-kilo-code-agent",
876
+ "github-copilot": "my-github-copilot-agent",
877
+ "continue-dev": "my-continue-agent",
878
+ goose: "my-goose-agent"
802
879
  };
803
880
  async function promptPlatformSelection(ask) {
804
881
  process.stderr.write(
805
- "\n" + style.bold(style.violet("Which platform are you connecting?")) + "\n"
882
+ "\n" + style.bold(style.violet("Which platform are you connecting?")) + "\n\n"
806
883
  );
807
- const connectedFlags = [
808
- await isOpenClawConnected(),
809
- isClaudeCodeConnected(),
810
- await isCursorConnected(),
811
- await isWindsurfConnected()
812
- ];
813
- for (let i = 0; i < PLATFORM_LABELS.length; i++) {
814
- const marker = i < connectedFlags.length && connectedFlags[i] ? " " + style.dim("\u25CF detected locally") : "";
815
- process.stderr.write(
816
- ` ${style.violet(String(i + 1))}. ${PLATFORM_LABELS[i] ?? ""}${marker}
884
+ const detectionSlugs = INIT_WIZARD_PLATFORM_REGISTRY.filter((e) => e.detectable).map(
885
+ (e) => e.slug
886
+ );
887
+ const connectedFlags = await Promise.all(
888
+ detectionSlugs.map((slug) => isPlatformDetectedForMenu(slug))
889
+ );
890
+ function markerFor(platform) {
891
+ const idx = detectionSlugs.indexOf(platform);
892
+ if (idx === -1) return "";
893
+ if (!connectedFlags[idx]) return "";
894
+ return " " + style.dim("\u25CF detected locally");
895
+ }
896
+ let optionNum = 1;
897
+ for (const section of INIT_WIZARD_MENU_SECTIONS) {
898
+ process.stderr.write(" " + style.dim(section.title) + "\n");
899
+ for (const item of section.items) {
900
+ const indent = optionNum >= 10 ? " " : " ";
901
+ process.stderr.write(
902
+ `${indent}${style.violet(String(optionNum))}. ${item.label}${markerFor(item.platform)}
817
903
  `
818
- );
904
+ );
905
+ optionNum++;
906
+ }
819
907
  }
820
908
  process.stderr.write(
821
- style.dim(" Pick 8 if you want to wrap a local MCP server with multicorn-shield --wrap.") + "\n"
909
+ "\n" + style.dim(
910
+ ` Pick ${String(INIT_WIZARD_SELECTION_MAX)} to wrap a local MCP server with multicorn-shield --wrap.`
911
+ ) + "\n"
822
912
  );
823
913
  let selection = 0;
824
914
  while (selection === 0) {
825
- const input = await ask("Select (1-8): ");
915
+ const input = await ask(`Select (1-${String(INIT_WIZARD_SELECTION_MAX)}): `);
826
916
  const num = parseInt(input.trim(), 10);
827
- if (num >= 1 && num <= 8) {
917
+ if (num >= 1 && num <= INIT_WIZARD_SELECTION_MAX) {
828
918
  selection = num;
829
919
  }
830
920
  }
@@ -895,12 +985,7 @@ async function promptProxyConfig(ask, agentName) {
895
985
  }
896
986
  targetUrl = input.trim();
897
987
  }
898
- const defaultShortName = normalizeAgentName(agentName) || "shield-mcp";
899
- const shortNameInput = await ask(
900
- `
901
- Short name (a nickname for this connection, used in your proxy URL): ${style.dim(`(${defaultShortName})`)} `
902
- );
903
- const shortName = shortNameInput.trim().length > 0 ? normalizeAgentName(shortNameInput.trim()) || defaultShortName : defaultShortName;
988
+ const shortName = normalizeAgentName(agentName) || "shield-mcp";
904
989
  return { targetUrl, shortName };
905
990
  }
906
991
  async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverName, platform) {
@@ -944,24 +1029,84 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
944
1029
  const data = envelope["data"];
945
1030
  return typeof data?.["proxy_url"] === "string" ? data["proxy_url"] : "";
946
1031
  }
1032
+ function gooseHostedProxyYaml(shortName, proxyUrl, bearerHeader) {
1033
+ return `extensions:
1034
+ ${shortName}:
1035
+ type: streamable_http
1036
+ url: ${proxyUrl}
1037
+ headers:
1038
+ Authorization: ${bearerHeader}
1039
+ enabled: true
1040
+ timeout: 300
1041
+ `;
1042
+ }
947
1043
  function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
948
- const usesInlineKey = platform === "cursor" || platform === "claude-desktop" || platform === "windsurf" || platform === "cline" || platform === "gemini-cli";
1044
+ const hostedInlinePlatforms = /* @__PURE__ */ new Set([
1045
+ "cursor",
1046
+ "claude-desktop",
1047
+ "windsurf",
1048
+ "cline",
1049
+ "gemini-cli",
1050
+ "kilo-code",
1051
+ "github-copilot",
1052
+ "continue-dev",
1053
+ "goose"
1054
+ ]);
1055
+ const usesInlineKey = hostedInlinePlatforms.has(platform);
949
1056
  const authHeader = usesInlineKey ? `Bearer ${apiKey}` : "Bearer YOUR_SHIELD_API_KEY";
950
- const urlKey = platform === "windsurf" ? "serverUrl" : platform === "gemini-cli" ? "httpUrl" : "url";
951
- const mcpSnippet = JSON.stringify(
952
- {
953
- mcpServers: {
954
- [shortName]: {
955
- [urlKey]: routingToken,
956
- headers: {
957
- Authorization: authHeader
1057
+ let snippetText;
1058
+ if (platform === "github-copilot") {
1059
+ snippetText = JSON.stringify(
1060
+ {
1061
+ mcp: {
1062
+ servers: {
1063
+ [shortName]: {
1064
+ type: "http",
1065
+ url: routingToken,
1066
+ headers: {
1067
+ Authorization: authHeader
1068
+ }
1069
+ }
958
1070
  }
959
1071
  }
960
- }
961
- },
962
- null,
963
- 2
964
- );
1072
+ },
1073
+ null,
1074
+ 2
1075
+ );
1076
+ } else if (platform === "goose") {
1077
+ snippetText = gooseHostedProxyYaml(shortName, routingToken, authHeader);
1078
+ } else if (platform === "gemini-cli") {
1079
+ snippetText = JSON.stringify(
1080
+ {
1081
+ mcpServers: {
1082
+ [shortName]: {
1083
+ httpUrl: routingToken,
1084
+ headers: {
1085
+ Authorization: authHeader
1086
+ }
1087
+ }
1088
+ }
1089
+ },
1090
+ null,
1091
+ 2
1092
+ );
1093
+ } else {
1094
+ const urlKey = platform === "windsurf" ? "serverUrl" : "url";
1095
+ snippetText = JSON.stringify(
1096
+ {
1097
+ mcpServers: {
1098
+ [shortName]: {
1099
+ [urlKey]: routingToken,
1100
+ headers: {
1101
+ Authorization: authHeader
1102
+ }
1103
+ }
1104
+ }
1105
+ },
1106
+ null,
1107
+ 2
1108
+ );
1109
+ }
965
1110
  if (platform === "openclaw") {
966
1111
  process.stderr.write("\n" + style.dim("Add this to your OpenClaw agent config:") + "\n\n");
967
1112
  } else if (platform === "claude-code") {
@@ -995,10 +1140,28 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
995
1140
  "Add this to ~/.gemini/settings.json (create the file if it does not exist). For project-specific config, use .gemini/settings.json in your project root. Restart Gemini CLI after saving. Run /mcp to verify the server is connected."
996
1141
  ) + "\n\n"
997
1142
  );
1143
+ } else if (platform === "kilo-code") {
1144
+ process.stderr.write(
1145
+ "\n" + style.dim("Add this to .kilocode/mcp.json in your project root.") + "\n\n"
1146
+ );
1147
+ } else if (platform === "github-copilot") {
1148
+ process.stderr.write(
1149
+ "\n" + style.dim(
1150
+ "Open VS Code Settings (JSON) and merge this under the mcp key. If you do not have an mcp section yet, add one. Copilot picks up MCP servers when you use Agent mode."
1151
+ ) + "\n\n"
1152
+ );
1153
+ } else if (platform === "continue-dev") {
1154
+ process.stderr.write(
1155
+ "\n" + style.dim("Save this as .continue/mcpServers/shield.json in your workspace root.") + "\n\n"
1156
+ );
1157
+ } else if (platform === "goose") {
1158
+ process.stderr.write(
1159
+ "\n" + style.dim("Add this to ~/.config/goose/config.yaml under the extensions key.") + "\n\n"
1160
+ );
998
1161
  } else {
999
1162
  process.stderr.write("\n" + style.dim("Add this to ~/.cursor/mcp.json:") + "\n\n");
1000
1163
  }
1001
- process.stderr.write(style.cyan(mcpSnippet) + "\n\n");
1164
+ process.stderr.write(style.cyan(snippetText) + "\n\n");
1002
1165
  if (!usesInlineKey) {
1003
1166
  process.stderr.write(
1004
1167
  style.dim(
@@ -1036,6 +1199,14 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
1036
1199
  ) + "\n"
1037
1200
  );
1038
1201
  }
1202
+ if (platform === "github-copilot" || platform === "continue-dev") {
1203
+ process.stderr.write(
1204
+ style.dim("Reload the editor window if the MCP server does not appear immediately.") + "\n"
1205
+ );
1206
+ }
1207
+ if (platform === "goose") {
1208
+ process.stderr.write(style.dim("Start a new Goose session after updating config.") + "\n");
1209
+ }
1039
1210
  }
1040
1211
  var DEFAULT_SHIELD_API_BASE_URL = "https://api.multicorn.ai";
1041
1212
  async function runInit(explicitBaseUrl) {
@@ -1125,8 +1296,8 @@ async function runInit(explicitBaseUrl) {
1125
1296
  let postSaveNativeSkipNote = null;
1126
1297
  const selection = await promptPlatformSelection(ask);
1127
1298
  const selectedPlatform = PLATFORM_BY_SELECTION[selection] ?? "cursor";
1128
- const selectedLabel = PLATFORM_LABELS[selection - 1] ?? "Cursor";
1129
- if (selection === 8) {
1299
+ const selectedLabel = platformMenuLabelForSelection(selection);
1300
+ if (selectedPlatform === "other-mcp") {
1130
1301
  const raw = existing !== null ? { ...existing } : {};
1131
1302
  raw["apiKey"] = apiKey;
1132
1303
  raw["baseUrl"] = resolvedBaseUrl;
@@ -1176,9 +1347,24 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1176
1347
  continue;
1177
1348
  }
1178
1349
  }
1350
+ const prereqEntry = INIT_WIZARD_PLATFORM_REGISTRY.find((e) => e.slug === selectedPlatform);
1351
+ if (prereqEntry?.prereqUrl !== void 0) {
1352
+ const proceed = await promptHostedProxyInstallPrereq(
1353
+ ask,
1354
+ prereqEntry.displayName,
1355
+ prereqEntry.prereqUrl
1356
+ );
1357
+ if (!proceed) {
1358
+ const another2 = await ask("\nConnect another agent? (Y/n) ");
1359
+ if (another2.trim().toLowerCase() === "n") {
1360
+ configuring = false;
1361
+ }
1362
+ continue;
1363
+ }
1364
+ }
1179
1365
  const agentName = await promptAgentName(ask, selectedPlatform);
1180
1366
  let setupSucceeded = false;
1181
- if (selection === 1) {
1367
+ if (selectedPlatform === "openclaw") {
1182
1368
  let detection;
1183
1369
  try {
1184
1370
  detection = await detectOpenClaw();
@@ -1258,7 +1444,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1258
1444
  agentName
1259
1445
  });
1260
1446
  setupSucceeded = true;
1261
- } else if (selection === 2) {
1447
+ } else if (selectedPlatform === "claude-code") {
1262
1448
  process.stderr.write("\nTo connect Claude Code to Shield:\n\n");
1263
1449
  process.stderr.write(
1264
1450
  " " + style.bold("Step 1") + " - Add the Multicorn marketplace:\n " + style.cyan("claude plugin marketplace add Multicorn-AI/multicorn-shield") + "\n\n"
@@ -1276,7 +1462,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1276
1462
  agentName
1277
1463
  });
1278
1464
  setupSucceeded = true;
1279
- } else if (selection === 4) {
1465
+ } else if (selectedPlatform === "windsurf") {
1280
1466
  const windsurfMode = await promptWindsurfIntegrationMode(ask);
1281
1467
  if (windsurfMode === "native") {
1282
1468
  try {
@@ -1364,7 +1550,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1364
1550
  setupSucceeded = true;
1365
1551
  }
1366
1552
  }
1367
- } else if (selection === 7) {
1553
+ } else if (selectedPlatform === "gemini-cli") {
1368
1554
  const geminiMode = await promptGeminiCliIntegrationMode(ask);
1369
1555
  if (geminiMode === "native") {
1370
1556
  try {
@@ -1449,7 +1635,7 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1449
1635
  setupSucceeded = true;
1450
1636
  }
1451
1637
  }
1452
- } else if (selection === 5) {
1638
+ } else if (selectedPlatform === "cline") {
1453
1639
  const clineMode = await promptClineIntegrationMode(ask);
1454
1640
  if (clineMode === "native") {
1455
1641
  try {
@@ -1635,6 +1821,26 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
1635
1821
  "\n" + style.bold("To complete your Cursor setup:") + "\n 1. If you don't have Cursor yet, download it from " + style.cyan("https://cursor.com/downloads") + "\n 2. Open " + style.cyan("~/.cursor/mcp.json") + " and paste the config snippet shown above\n 3. Restart Cursor (or launch it for the first time) to load the new MCP server\n"
1636
1822
  );
1637
1823
  }
1824
+ if (configuredPlatforms.has("kilo-code")) {
1825
+ blocks.push(
1826
+ "\n" + style.bold("To complete your Kilo Code setup:") + "\n 1. Save the snippet to " + style.cyan(".kilocode/mcp.json") + " in your project root, or under the mcp key in " + style.cyan("kilo.jsonc") + "\n 2. Run your next task in Kilo Code so it picks up the MCP server\n"
1827
+ );
1828
+ }
1829
+ if (configuredPlatforms.has("github-copilot")) {
1830
+ blocks.push(
1831
+ "\n" + style.bold("GitHub Copilot MCP:") + "\n 1. Open VS Code Command Palette: Preferences: Open User Settings (JSON)\n 2. Merge the snippet under the " + style.cyan("mcp") + " key and save\n 3. Use Copilot Agent mode and verify the MCP server connects\n"
1832
+ );
1833
+ }
1834
+ if (configuredPlatforms.has("continue-dev")) {
1835
+ blocks.push(
1836
+ "\n" + style.bold("Continue MCP:") + "\n 1. If you don't have Continue yet, install from " + style.cyan("https://docs.continue.dev/ide-extensions/install") + "\n 2. Save JSON as " + style.cyan(".continue/mcpServers/shield.json") + " in your workspace, or add to " + style.cyan("~/.continue/config.yaml") + "\n 3. Reload VS Code and open Continue agent mode\n"
1837
+ );
1838
+ }
1839
+ if (configuredPlatforms.has("goose")) {
1840
+ blocks.push(
1841
+ "\n" + style.bold("Goose MCP extension:") + "\n 1. Edit " + style.cyan("~/.config/goose/config.yaml") + " (or use goose configure)\n 2. Restart Goose CLI or Desktop\n"
1842
+ );
1843
+ }
1638
1844
  const windsurfNativeConfigured = configuredAgents.some(
1639
1845
  (a) => a.platform === "windsurf" && a.windsurfIntegration === "native"
1640
1846
  );
@@ -22259,6 +22259,69 @@ function getClaudeDesktopConfigPath() {
22259
22259
  );
22260
22260
  }
22261
22261
  }
22262
+ var INIT_WIZARD_PLATFORM_REGISTRY = [
22263
+ { slug: "openclaw", displayName: "OpenClaw", section: "native", detectable: true },
22264
+ { slug: "claude-code", displayName: "Claude Code", section: "native", detectable: true },
22265
+ { slug: "windsurf", displayName: "Windsurf", section: "native", detectable: true },
22266
+ { slug: "cline", displayName: "Cline", section: "native", detectable: false },
22267
+ { slug: "gemini-cli", displayName: "Gemini CLI", section: "native", detectable: false },
22268
+ {
22269
+ slug: "cursor",
22270
+ displayName: "Cursor",
22271
+ section: "hosted",
22272
+ prereqUrl: "https://www.cursor.com/downloads",
22273
+ detectable: true
22274
+ },
22275
+ {
22276
+ slug: "claude-desktop",
22277
+ displayName: "Claude Desktop",
22278
+ section: "hosted",
22279
+ prereqUrl: "https://claude.ai/download",
22280
+ detectable: false
22281
+ },
22282
+ {
22283
+ slug: "github-copilot",
22284
+ displayName: "GitHub Copilot",
22285
+ section: "hosted",
22286
+ prereqUrl: "https://docs.github.com/en/copilot/get-started",
22287
+ detectable: false
22288
+ },
22289
+ {
22290
+ slug: "kilo-code",
22291
+ displayName: "Kilo Code",
22292
+ section: "hosted",
22293
+ prereqUrl: "https://kilocode.ai/docs/getting-started",
22294
+ detectable: false
22295
+ },
22296
+ {
22297
+ slug: "continue-dev",
22298
+ displayName: "Continue",
22299
+ section: "hosted",
22300
+ prereqUrl: "https://docs.continue.dev/ide-extensions/install",
22301
+ detectable: false
22302
+ },
22303
+ {
22304
+ slug: "goose",
22305
+ displayName: "Goose",
22306
+ section: "hosted",
22307
+ prereqUrl: "https://goose-docs.ai/docs/quickstart/",
22308
+ detectable: false
22309
+ },
22310
+ { slug: "other-mcp", displayName: "Local MCP / Other", section: "hosted", detectable: false }
22311
+ ];
22312
+ (() => {
22313
+ const itemsFor = (section) => INIT_WIZARD_PLATFORM_REGISTRY.filter((e) => e.section === section).map((e) => ({
22314
+ platform: e.slug,
22315
+ label: e.displayName
22316
+ }));
22317
+ return [
22318
+ { title: "Recommended (native plugin)", items: itemsFor("native") },
22319
+ { title: "Hosted proxy (MCP only)", items: itemsFor("hosted") }
22320
+ ];
22321
+ })();
22322
+ Object.fromEntries(
22323
+ INIT_WIZARD_PLATFORM_REGISTRY.map((e, i) => [i + 1, e.slug])
22324
+ );
22262
22325
 
22263
22326
  // src/extension/config-reader.ts
22264
22327
  var EXTENSION_BACKUP_FILENAME = "extension-backup.json";
@@ -22359,7 +22422,7 @@ async function writeExtensionBackup(claudeDesktopConfigPath, mcpServers) {
22359
22422
 
22360
22423
  // package.json
22361
22424
  var package_default = {
22362
- version: "1.0.0"};
22425
+ version: "1.1.0"};
22363
22426
 
22364
22427
  // src/package-meta.ts
22365
22428
  var PACKAGE_VERSION = package_default.version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multicorn-shield",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "The control layer for AI agents: permissions, consent, spending limits, and audit logging.",
5
5
  "license": "MIT",
6
6
  "author": "Multicorn AI Pty Ltd",