neon 8.15.0 → 8.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/dist/_chunks/{checkout-BpOcFaAi.js → checkout-CNBIS3gA.js} +3 -3
- package/dist/_chunks/{claim-DlLZmcq0.js → claim-m5sIJdm5.js} +1 -1
- package/dist/_chunks/{config-BjCm5cfr.js → config-CgtJH8xE.js} +1 -1
- package/dist/_chunks/{databases-DC2h6IW2.js → databases-B2Yapqme.js} +9 -4
- package/dist/_chunks/{deploy-DmEEhux0.js → deploy-Bs5gmi4Q.js} +1 -1
- package/dist/_chunks/{dev-DlUJFzRs.js → dev-DxiIp4c9.js} +3 -3
- package/dist/_chunks/{docs-CClmgj_Z.js → docs-BpLiSTmm.js} +1 -1
- package/dist/_chunks/{functions-3ypiRwZK.js → functions-PHaU-kRb.js} +1 -1
- package/dist/_chunks/{git-j6xSVo3e.js → git-DRUZBCmZ.js} +2 -2
- package/dist/_chunks/{link-nAiuWKfg.js → link-CNO-HxHN.js} +2 -2
- package/dist/_chunks/{mcp-BznTRK3w.js → mcp-SvqWzHnT.js} +6 -4
- package/dist/_chunks/{plugins-CKOcBuuP.js → plugins-7cxVcgay.js} +5 -5
- package/dist/_chunks/{roles-xRuu0462.js → roles-BVc69rjG.js} +9 -4
- package/dist/_chunks/{status-BC4XXuuE.js → status-BlrzeKyA.js} +1 -1
- package/dist/analytics.js +4 -2
- package/dist/commands/bootstrap.js +1 -1
- package/dist/commands/checkout.js +1 -1
- package/dist/commands/claim.js +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/databases.js +1 -1
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/env.js +1 -1
- package/dist/commands/functions.js +1 -1
- package/dist/commands/functions_new.js +3 -4
- package/dist/commands/git.js +1 -1
- package/dist/commands/index.js +17 -17
- package/dist/commands/link.js +1 -1
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/plugins.js +1 -1
- package/dist/commands/roles.js +1 -1
- package/dist/commands/skills.js +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/subscribe.js +1 -1
- package/dist/env.js +19 -4
- package/dist/index.js +1 -1
- package/dist/init/agents.js +11 -3
- package/dist/init/auth.js +2 -2
- package/dist/init/copy.js +3 -2
- package/dist/init/detect.js +1 -2
- package/dist/init/link.js +1 -1
- package/dist/init/plan.js +2 -63
- package/dist/init/run.js +29 -20
- package/dist/init/tooling.js +5 -5
- package/dist/init/unknown_agent_arg.js +63 -0
- package/dist/init/wizard.js +6 -6
- package/dist/mcp/agents.js +25 -5
- package/dist/mcp/install.js +95 -30
- package/dist/mcp/targets.js +2 -3
- package/dist/plugins/child_env.js +10 -0
- package/dist/plugins/plan.js +14 -14
- package/dist/plugins/run.js +2 -8
- package/dist/plugins/targets.js +134 -15
- package/dist/skills/targets.js +1 -2
- package/dist/update_notifier.js +8 -5
- package/dist/utils/ai_gateway_notice.js +1 -1
- package/package.json +6 -5
- package/dist/_chunks/{bootstrap-BDkvsAVJ.js → bootstrap-vAtWRZXa.js} +2 -2
- package/dist/_chunks/{env-BOt9AZ1j.js → env-BtG4vH55.js} +1 -1
- package/dist/_chunks/{skills-DKgafm65.js → skills-Bv8oKKwE.js} +3 -3
package/dist/init/copy.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getCliName } from "../utils/cli_name.js";
|
|
2
|
+
import { pluginsCommandProblemText } from "../plugins/targets.js";
|
|
2
3
|
// src/init/copy.ts
|
|
3
4
|
const INIT_SUBTITLE = "Set up coding agents and this directory for Neon.";
|
|
4
5
|
const MODE_MESSAGE = "How would you like to set up Neon?";
|
|
@@ -16,7 +17,7 @@ const AGENT_SETUP_SKIP_DESCRIPTION = "Continue to project setup without changing
|
|
|
16
17
|
const AGENT_PICKER_MESSAGE = "Which coding agents should receive Neon tooling? (space to toggle, enter to confirm)";
|
|
17
18
|
const AGENT_DETECTED_DESCRIPTION = "Detected on this machine or in this directory.";
|
|
18
19
|
const AGENT_OTHER_DESCRIPTION = "Install for this agent.";
|
|
19
|
-
const
|
|
20
|
+
const agentUnusableCommandDescription = (row) => `Detected, but "${row.command.name}" ${pluginsCommandProblemText(row)}. Its plugin cannot install.`;
|
|
20
21
|
const AGENT_PLUGIN_SKIP_MESSAGE = "No agents selected. Continue without installing the Neon plugin?";
|
|
21
22
|
const AGENT_SKILLS_PICKER_MESSAGE = "Which coding agents should receive Neon skills? (space to toggle, enter to confirm)";
|
|
22
23
|
const AGENT_MCP_PICKER_MESSAGE = "Which coding agents should receive the Neon MCP server? (space to toggle, enter to confirm)";
|
|
@@ -184,4 +185,4 @@ const headingForOutcome = (outcome) => {
|
|
|
184
185
|
default: return outcome;
|
|
185
186
|
}
|
|
186
187
|
};
|
|
187
|
-
export { AGENTS_NOT_INSTALLED, AGENT_DETECTED_DESCRIPTION, AGENT_MCP_PICKER_MESSAGE, AGENT_MCP_SKIP_MESSAGE, AGENT_OTHER_DESCRIPTION, AGENT_PICKER_MESSAGE, AGENT_PLUGIN_SKIP_MESSAGE, AGENT_SETUP_MESSAGE, AGENT_SETUP_PLUGIN_DESCRIPTION, AGENT_SETUP_PLUGIN_TITLE, AGENT_SETUP_SKILLS_DESCRIPTION, AGENT_SETUP_SKILLS_TITLE, AGENT_SETUP_SKIP_DESCRIPTION, AGENT_SETUP_SKIP_TITLE, AGENT_SKILLS_PICKER_MESSAGE, AGENT_SKILLS_SKIP_MESSAGE, CANCELLED_BODY, CLAIMABLE_ACCOUNT_FLAGS, CLAIMABLE_ALREADY_LINKED, CLAIMABLE_MCP_API_KEY, CLAIMABLE_NO_LINK, CONFIG_CONFIRM_HINT, CONFIG_CONFIRM_MESSAGE, HEADING_CANCELLED, HEADING_COMPLETE, HEADING_FAILED, HEADING_PENDING, INIT_NEEDS_YES, INIT_SUBTITLE, MCP_API_KEY_NEEDS_AUTH, MCP_AUTH_API_KEY_DESCRIPTION, MCP_AUTH_API_KEY_TITLE, MCP_AUTH_MESSAGE, MCP_AUTH_OAUTH_DESCRIPTION, MCP_AUTH_OAUTH_TITLE, MCP_OAUTH_FALLBACK, MCP_SCOPED_NEEDS_PROJECT, MCP_SCOPE_GLOBAL_DESCRIPTION, MCP_SCOPE_GLOBAL_TITLE, MCP_SCOPE_MESSAGE, MCP_SCOPE_PROJECT_DESCRIPTION, MCP_SCOPE_PROJECT_TITLE, MODE_CUSTOM_DESCRIPTION, MODE_CUSTOM_TITLE, MODE_MESSAGE, MODE_RECOMMENDED_DESCRIPTION, MODE_RECOMMENDED_TITLE, NON_TTY_AGENT_SETUP, NON_TTY_LINK_NEEDS_AUTH, NO_AGENTS_FALLBACK_STATUS, NO_AGENT_SETUP_CONFLICT, PACKAGE_MANAGER_MESSAGE, PROGRESS, PROJECT_PINNED_OFFLINE, PROJECT_SETUP_CLAIMABLE_DESCRIPTION, PROJECT_SETUP_CLAIMABLE_TITLE, PROJECT_SETUP_LINK_DESCRIPTION, PROJECT_SETUP_LINK_TITLE, PROJECT_SETUP_MESSAGE, SERVICES_HINT, SERVICES_MESSAGE, SKILLS_PICKER_MESSAGE,
|
|
188
|
+
export { AGENTS_NOT_INSTALLED, AGENT_DETECTED_DESCRIPTION, AGENT_MCP_PICKER_MESSAGE, AGENT_MCP_SKIP_MESSAGE, AGENT_OTHER_DESCRIPTION, AGENT_PICKER_MESSAGE, AGENT_PLUGIN_SKIP_MESSAGE, AGENT_SETUP_MESSAGE, AGENT_SETUP_PLUGIN_DESCRIPTION, AGENT_SETUP_PLUGIN_TITLE, AGENT_SETUP_SKILLS_DESCRIPTION, AGENT_SETUP_SKILLS_TITLE, AGENT_SETUP_SKIP_DESCRIPTION, AGENT_SETUP_SKIP_TITLE, AGENT_SKILLS_PICKER_MESSAGE, AGENT_SKILLS_SKIP_MESSAGE, CANCELLED_BODY, CLAIMABLE_ACCOUNT_FLAGS, CLAIMABLE_ALREADY_LINKED, CLAIMABLE_MCP_API_KEY, CLAIMABLE_NO_LINK, CONFIG_CONFIRM_HINT, CONFIG_CONFIRM_MESSAGE, HEADING_CANCELLED, HEADING_COMPLETE, HEADING_FAILED, HEADING_PENDING, INIT_NEEDS_YES, INIT_SUBTITLE, MCP_API_KEY_NEEDS_AUTH, MCP_AUTH_API_KEY_DESCRIPTION, MCP_AUTH_API_KEY_TITLE, MCP_AUTH_MESSAGE, MCP_AUTH_OAUTH_DESCRIPTION, MCP_AUTH_OAUTH_TITLE, MCP_OAUTH_FALLBACK, MCP_SCOPED_NEEDS_PROJECT, MCP_SCOPE_GLOBAL_DESCRIPTION, MCP_SCOPE_GLOBAL_TITLE, MCP_SCOPE_MESSAGE, MCP_SCOPE_PROJECT_DESCRIPTION, MCP_SCOPE_PROJECT_TITLE, MODE_CUSTOM_DESCRIPTION, MODE_CUSTOM_TITLE, MODE_MESSAGE, MODE_RECOMMENDED_DESCRIPTION, MODE_RECOMMENDED_TITLE, NON_TTY_AGENT_SETUP, NON_TTY_LINK_NEEDS_AUTH, NO_AGENTS_FALLBACK_STATUS, NO_AGENT_SETUP_CONFLICT, PACKAGE_MANAGER_MESSAGE, PROGRESS, PROJECT_PINNED_OFFLINE, PROJECT_SETUP_CLAIMABLE_DESCRIPTION, PROJECT_SETUP_CLAIMABLE_TITLE, PROJECT_SETUP_LINK_DESCRIPTION, PROJECT_SETUP_LINK_TITLE, PROJECT_SETUP_MESSAGE, SERVICES_HINT, SERVICES_MESSAGE, SKILLS_PICKER_MESSAGE, agentUnusableCommandDescription, claimableNext, claimableThenServicesNext, configInitNext, envPullFailedNext, existingConfigNext, headingForOutcome, installFailedNext, mcpAfterLinkNext, mcpConfigLocationSkipped, mcpConfigLocationUnavailable, mcpKeyFailedNext, namedAgentsUnavailable, newConfigNext, offlinePinNext, skippedLinkNext, toolingFailedNext, unattendedUnauthedNext };
|
package/dist/init/detect.js
CHANGED
|
@@ -2,13 +2,12 @@ import { t as storeFor } from "../_chunks/credential_io-DbeSh3Pl.js";
|
|
|
2
2
|
import { isCi } from "../env.js";
|
|
3
3
|
import { h as resolveProfile, u as locationOf } from "../_chunks/profiles-DTazQtjK.js";
|
|
4
4
|
import { i as selectCredential, t as credentialInputs } from "../_chunks/auth_selection-CwGLN9Qz.js";
|
|
5
|
-
import { detectInstalledAgents, uniqueAgentIds } from "../mcp/agents.js";
|
|
5
|
+
import { detectInstalledAgents, detectProjectAgents, uniqueAgentIds } from "../mcp/agents.js";
|
|
6
6
|
import "./agents.js";
|
|
7
7
|
import { directoryIsEmpty } from "./plan.js";
|
|
8
8
|
import { detectAgent } from "./detect_host.js";
|
|
9
9
|
import { canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
10
10
|
import { existsSync, readdirSync } from "node:fs";
|
|
11
|
-
import { detectProjectAgents } from "add-mcp";
|
|
12
11
|
// src/init/detect.ts
|
|
13
12
|
const listingHasCredentials = (configDir, profile) => {
|
|
14
13
|
try {
|
package/dist/init/link.js
CHANGED
|
@@ -4,7 +4,7 @@ import "../config.js";
|
|
|
4
4
|
import "../auth.js";
|
|
5
5
|
import { c as ensureAuth } from "../_chunks/auth-rup6nemJ.js";
|
|
6
6
|
import { recoverFrom401 } from "../auth_recovery.js";
|
|
7
|
-
import { s as runLink } from "../_chunks/link-
|
|
7
|
+
import { s as runLink } from "../_chunks/link-CNO-HxHN.js";
|
|
8
8
|
// src/init/link.ts
|
|
9
9
|
const isUnauthorized = (error) => isNeonApiError(error) && error.status === 401;
|
|
10
10
|
const authenticationFailed = () => /* @__PURE__ */ new Error("Authentication failed.");
|
package/dist/init/plan.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getCliName } from "../utils/cli_name.js";
|
|
2
2
|
import { tryResolveAddMcpAgentId, uniqueAgentIds } from "../mcp/agents.js";
|
|
3
|
-
import { mcpInstallableAgents } from "../mcp/targets.js";
|
|
4
3
|
import { supportsSkills } from "./agents.js";
|
|
5
4
|
import { pluginsInstallableAgents } from "../plugins/targets.js";
|
|
5
|
+
import { mcpInstallableAgents } from "../mcp/targets.js";
|
|
6
6
|
import { skillsInstallableAgents } from "../skills/targets.js";
|
|
7
7
|
import { agentArgv } from "../utils/agent_flag.js";
|
|
8
8
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
@@ -92,67 +92,6 @@ const noDetectedAgentsMessage = (input) => {
|
|
|
92
92
|
return `${lead} ${hint} Supported agents: ${input.supported.join(", ")}`;
|
|
93
93
|
};
|
|
94
94
|
const INIT_NEEDS_YES_OR_TERMINAL = "No interactive terminal. Pass -y to use defaults, or run this command in a terminal to pick.";
|
|
95
|
-
const UNKNOWN_AGENT_COMMANDS = ["link"];
|
|
96
|
-
const unknownAgentArgHint = (command, cliName) => `${cliName} ${command} has no --agent. Pass --project-id <id> to link without a TTY, or run ${cliName} ${command} in a terminal.`;
|
|
97
|
-
const BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
98
|
-
"-y",
|
|
99
|
-
"--yes",
|
|
100
|
-
"--default",
|
|
101
|
-
"--force",
|
|
102
|
-
"-h",
|
|
103
|
-
"--help",
|
|
104
|
-
"-v",
|
|
105
|
-
"--version",
|
|
106
|
-
"--color",
|
|
107
|
-
"--no-color",
|
|
108
|
-
"--analytics",
|
|
109
|
-
"--no-analytics",
|
|
110
|
-
"--oauth",
|
|
111
|
-
"--project",
|
|
112
|
-
"--global",
|
|
113
|
-
"--read-only",
|
|
114
|
-
"--readonly",
|
|
115
|
-
"--clear",
|
|
116
|
-
"--checks",
|
|
117
|
-
"--no-checks",
|
|
118
|
-
"--env-pull",
|
|
119
|
-
"--no-env-pull",
|
|
120
|
-
"--no-agent-setup",
|
|
121
|
-
"--no-link",
|
|
122
|
-
"--no-config",
|
|
123
|
-
"--claimable",
|
|
124
|
-
"--config",
|
|
125
|
-
"--list",
|
|
126
|
-
"--list-templates",
|
|
127
|
-
"--force-auth",
|
|
128
|
-
"--no-force-auth"
|
|
129
|
-
]);
|
|
130
|
-
const isUnknownAgentCommand = (token) => {
|
|
131
|
-
for (const command of UNKNOWN_AGENT_COMMANDS) if (command === token) return true;
|
|
132
|
-
return false;
|
|
133
|
-
};
|
|
134
|
-
const commandFromArgv = (argv) => {
|
|
135
|
-
let skipValue = false;
|
|
136
|
-
for (const token of argv) {
|
|
137
|
-
if (skipValue) {
|
|
138
|
-
skipValue = false;
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
if (token === "--") break;
|
|
142
|
-
if (token.startsWith("-")) {
|
|
143
|
-
const flag = token.split("=")[0];
|
|
144
|
-
if (flag !== void 0 && !token.includes("=") && !BOOLEAN_FLAGS.has(flag)) skipValue = true;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (isUnknownAgentCommand(token)) return token;
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
const rewriteUnknownAgentArg = (input) => {
|
|
151
|
-
if (input.message !== "Unknown argument: agent" && input.message !== "Unknown argument: a") return;
|
|
152
|
-
const command = commandFromArgv(input.argv);
|
|
153
|
-
if (command === void 0) return;
|
|
154
|
-
return unknownAgentArgHint(command, input.cliName);
|
|
155
|
-
};
|
|
156
95
|
const initYesSupportedAgents = () => uniqueAgentIds([
|
|
157
96
|
...pluginsInstallableAgents("project"),
|
|
158
97
|
...skillsInstallableAgents(),
|
|
@@ -385,4 +324,4 @@ const resolveInitAgentSetup = async (input) => {
|
|
|
385
324
|
if (input.interactive) return input.pick();
|
|
386
325
|
throw new Error(INIT_NEEDS_YES_OR_TERMINAL);
|
|
387
326
|
};
|
|
388
|
-
export { FALLBACK_SKILLS_AGENTS, INIT_NEEDS_YES_OR_TERMINAL, NAMED_AGENTS_MIXED, NAMED_AGENTS_UNSUPPORTED, assertNamedAgentTooling, bootstrapInitStep, chooseYesAgentTooling, collectYesAgents, directoryIsEmpty, funnelAgentSetup, initPluginAgents, initSkillsMcpAgents, initYesSupportedAgents, linkInputArgv, namedAgentsMixedMessage, namedAgentsNeedSplit, noDetectedAgentsMessage, planAgentSteps, planConfigInitStep, planInitToolingSteps, planLinkStep, planToolingSteps, planYesAgentSteps, postScaffoldActions, projectContextFile, recommendedTooling, resolveInitAgentSetup, resolveNamedAgents, resolveYesAgentList,
|
|
327
|
+
export { FALLBACK_SKILLS_AGENTS, INIT_NEEDS_YES_OR_TERMINAL, NAMED_AGENTS_MIXED, NAMED_AGENTS_UNSUPPORTED, assertNamedAgentTooling, bootstrapInitStep, chooseYesAgentTooling, collectYesAgents, directoryIsEmpty, funnelAgentSetup, initPluginAgents, initSkillsMcpAgents, initYesSupportedAgents, linkInputArgv, namedAgentsMixedMessage, namedAgentsNeedSplit, noDetectedAgentsMessage, planAgentSteps, planConfigInitStep, planInitToolingSteps, planLinkStep, planToolingSteps, planYesAgentSteps, postScaffoldActions, projectContextFile, recommendedTooling, resolveInitAgentSetup, resolveNamedAgents, resolveYesAgentList, splitInitTooling };
|
package/dist/init/run.js
CHANGED
|
@@ -9,23 +9,23 @@ import { getCliName } from "../utils/cli_name.js";
|
|
|
9
9
|
import { servicesFlagValue } from "../neon_services.js";
|
|
10
10
|
import { CONFIG_INIT_SERVICES, parseConfigInitServices } from "../config_template.js";
|
|
11
11
|
import { hasNeonConfigFile, neonConfigFilename } from "../project.js";
|
|
12
|
-
import { getAgentDisplayName } from "../mcp/agents.js";
|
|
13
|
-
import { mcpInstallableAgents } from "../mcp/targets.js";
|
|
14
|
-
import { missingPluginsCommands, pluginsInstallableAgents } from "../plugins/targets.js";
|
|
15
|
-
import { skillsInstallableAgents } from "../skills/targets.js";
|
|
16
|
-
import { FALLBACK_SKILLS_AGENTS, assertNamedAgentTooling, funnelAgentSetup, planInitToolingSteps, recommendedTooling, resolveNamedAgents, splitInitTooling } from "./plan.js";
|
|
17
12
|
import { inferPackageManager, resolvePackageManager } from "../utils/package_manager.js";
|
|
13
|
+
import { getAgentDisplayName } from "../mcp/agents.js";
|
|
14
|
+
import { missingPluginsCommands, pluginsCommandProblemText, pluginsInstallableAgents, unusablePluginsCommands } from "../plugins/targets.js";
|
|
18
15
|
import { AGENTS_NOT_INSTALLED, CANCELLED_BODY, CLAIMABLE_ACCOUNT_FLAGS, CLAIMABLE_ALREADY_LINKED, CLAIMABLE_MCP_API_KEY, CLAIMABLE_NO_LINK, MCP_API_KEY_NEEDS_AUTH, MCP_SCOPED_NEEDS_PROJECT, NON_TTY_LINK_NEEDS_AUTH, NO_AGENTS_FALLBACK_STATUS, PROGRESS, PROJECT_PINNED_OFFLINE, claimableNext, claimableThenServicesNext, configInitNext, envPullFailedNext, existingConfigNext, installFailedNext, mcpAfterLinkNext, mcpConfigLocationSkipped, mcpConfigLocationUnavailable, mcpKeyFailedNext, namedAgentsUnavailable, newConfigNext, offlinePinNext, skippedLinkNext, toolingFailedNext, unattendedUnauthedNext } from "./copy.js";
|
|
19
16
|
import { agentsRowValue, configRowValue, formatInitDone, headingForKind, printInitBanner, printInitDone, printInitProgress, projectRowValue, shouldPrintInitBanner } from "./chrome.js";
|
|
20
|
-
import { h as initCmd, t as ConfigInstallFailed } from "../_chunks/config-
|
|
21
|
-
import { o as quoteFlagValue, s as runLink } from "../_chunks/link-
|
|
17
|
+
import { h as initCmd, t as ConfigInstallFailed } from "../_chunks/config-CgtJH8xE.js";
|
|
18
|
+
import { o as quoteFlagValue, s as runLink } from "../_chunks/link-CNO-HxHN.js";
|
|
22
19
|
import { runAuthenticatedLink } from "./link.js";
|
|
20
|
+
import { mcpInstallableAgents } from "../mcp/targets.js";
|
|
21
|
+
import { skillsInstallableAgents } from "../skills/targets.js";
|
|
22
|
+
import { FALLBACK_SKILLS_AGENTS, assertNamedAgentTooling, funnelAgentSetup, planInitToolingSteps, recommendedTooling, resolveNamedAgents, splitInitTooling } from "./plan.js";
|
|
23
23
|
import { CannotMintApiKeyError } from "../mcp/mint.js";
|
|
24
24
|
import { pullInitEnv, resolveInitConfigApi } from "./auth.js";
|
|
25
25
|
import { InitCancelled, raceSigint, restoreCursor } from "./cancelled.js";
|
|
26
26
|
import { pickAgentSetupInteractively, pickInitAgentsInteractively, pickInitConfigInteractively, pickInitMcpAuthInteractively, pickInitMcpConfigLocationInteractively, pickInitModeInteractively, pickInitPackageManagerInteractively, pickInitProjectSetupInteractively, pickInitServicesInteractively, pickInitSkillsInteractively } from "./wizard.js";
|
|
27
27
|
import { runToolingSteps, toolingStepCommandText } from "./tooling.js";
|
|
28
|
-
import { l as create } from "../_chunks/claim-
|
|
28
|
+
import { l as create } from "../_chunks/claim-m5sIJdm5.js";
|
|
29
29
|
import { INIT_CONFIG_SERVICES_CONFLICT, configPlanFromResolution, initEnvPullAfterConfig, resolveInitConfigChoice } from "./choices.js";
|
|
30
30
|
import { detectInitEnvironment } from "./detect.js";
|
|
31
31
|
import { createInitFunnel, emitInitStart, finishInitFunnel, initStartProperties, recordInitError, recordInitExit } from "./funnel.js";
|
|
@@ -67,10 +67,10 @@ const pluginScopeFor = (agents, preferred) => {
|
|
|
67
67
|
const project = new Set(pluginsInstallableAgents("project"));
|
|
68
68
|
return agents.some((id) => !project.has(id) && pluginsInstallableAgents("global").includes(id)) ? "global" : "project";
|
|
69
69
|
};
|
|
70
|
-
const
|
|
70
|
+
const warnUnusablePluginCommands = (unusable, tooling) => {
|
|
71
71
|
if (tooling.setup !== "skills-mcp" && tooling.setup !== "mixed") return;
|
|
72
72
|
const routed = /* @__PURE__ */ new Set([...tooling.skillsAgents, ...tooling.mcpAgents]);
|
|
73
|
-
for (const
|
|
73
|
+
for (const row of unusable) if (routed.has(row.agent)) log.warning("%s: \"%s\" %s, so its plugin cannot install. Installing Neon skills and MCP instead.", getAgentDisplayName(row.agent), row.command.name, pluginsCommandProblemText(row));
|
|
74
74
|
};
|
|
75
75
|
const nonEmptyAgents = (ids, fallback) => {
|
|
76
76
|
const [first, ...rest] = ids;
|
|
@@ -124,7 +124,7 @@ const pickOrDetectAgents = async (input) => {
|
|
|
124
124
|
available: [...input.available],
|
|
125
125
|
detected,
|
|
126
126
|
preselected,
|
|
127
|
-
...input.
|
|
127
|
+
...input.unusableCommands !== void 0 ? { unusableCommands: input.unusableCommands } : {},
|
|
128
128
|
setup: input.setup
|
|
129
129
|
});
|
|
130
130
|
return detected;
|
|
@@ -265,9 +265,18 @@ const runInit = async (props) => {
|
|
|
265
265
|
}
|
|
266
266
|
const recommended = mode === "recommended";
|
|
267
267
|
const targets = named.length > 0 ? named : detection.detectedAgents;
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
|
|
268
|
+
let probedPluginCommands;
|
|
269
|
+
const unusablePluginCommands = () => {
|
|
270
|
+
probedPluginCommands ??= unusablePluginsCommands(targets, { cwd });
|
|
271
|
+
return probedPluginCommands;
|
|
272
|
+
};
|
|
273
|
+
let missingCommands;
|
|
274
|
+
const missingPluginCommands = () => {
|
|
275
|
+
missingCommands ??= missingPluginsCommands(targets, { cwd });
|
|
276
|
+
return missingCommands;
|
|
277
|
+
};
|
|
278
|
+
const unavailablePluginAgents = () => unusablePluginCommands().map((row) => row.agent);
|
|
279
|
+
const pluginReady = (agents) => agents.filter((id) => !unavailablePluginAgents().includes(id));
|
|
271
280
|
let tooling = { setup: "skip" };
|
|
272
281
|
let mcpAuth = props.mcpAuth;
|
|
273
282
|
let mcpAuthChosen = props.mcpAuth !== void 0;
|
|
@@ -277,9 +286,9 @@ const runInit = async (props) => {
|
|
|
277
286
|
let pluginScope = recommended ? "global" : "project";
|
|
278
287
|
if (recommended) {
|
|
279
288
|
pluginScope = "global";
|
|
280
|
-
tooling = named.length > 0 ? splitInitTooling(named, "global", "global", unavailablePluginAgents) : recommendedTooling(detection.detectedAgents, unavailablePluginAgents);
|
|
289
|
+
tooling = named.length > 0 ? splitInitTooling(named, "global", "global", unavailablePluginAgents()) : recommendedTooling(detection.detectedAgents, unavailablePluginAgents());
|
|
281
290
|
if (named.length === 0 && detection.detectedAgents.length === 0) printInitProgress(NO_AGENTS_FALLBACK_STATUS);
|
|
282
|
-
|
|
291
|
+
warnUnusablePluginCommands(unusablePluginCommands(), tooling);
|
|
283
292
|
mcpAuth = !detection.authenticated && (tooling.setup === "skills-mcp" || tooling.setup === "mixed") ? "oauth" : mcpAuth;
|
|
284
293
|
} else {
|
|
285
294
|
const inferred = inferInitAgentSetup({
|
|
@@ -294,8 +303,8 @@ const runInit = async (props) => {
|
|
|
294
303
|
else if (inferred.kind === "auto") {
|
|
295
304
|
const autoAgents = named.length > 0 ? named : detection.detectedAgents;
|
|
296
305
|
pluginScope = pluginScopeFor(pluginReady(autoAgents), "project");
|
|
297
|
-
tooling = splitInitTooling(autoAgents, pluginScope, mcpConfigLocation, unavailablePluginAgents);
|
|
298
|
-
|
|
306
|
+
tooling = splitInitTooling(autoAgents, pluginScope, mcpConfigLocation, unavailablePluginAgents());
|
|
307
|
+
warnUnusablePluginCommands(unusablePluginCommands(), tooling);
|
|
299
308
|
if (tooling.setup === "skip" && yes && named.length === 0) {
|
|
300
309
|
tooling = recommendedTooling([]);
|
|
301
310
|
printInitProgress(NO_AGENTS_FALLBACK_STATUS);
|
|
@@ -310,8 +319,8 @@ const runInit = async (props) => {
|
|
|
310
319
|
available,
|
|
311
320
|
detected: detection.detectedAgents,
|
|
312
321
|
...setup === "plugin" ? {
|
|
313
|
-
preselected:
|
|
314
|
-
|
|
322
|
+
preselected: detection.detectedAgents.filter((id) => !missingPluginCommands().some((row) => row.agent === id)),
|
|
323
|
+
unusableCommands: missingPluginCommands()
|
|
315
324
|
} : {},
|
|
316
325
|
interactive: detection.interactive,
|
|
317
326
|
setup,
|
package/dist/init/tooling.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { log } from "../log.js";
|
|
2
2
|
import { getCliName } from "../utils/cli_name.js";
|
|
3
|
-
import {
|
|
3
|
+
import { detectProjectAgents } from "../mcp/agents.js";
|
|
4
4
|
import { MCP_OAUTH_FALLBACK, PROGRESS } from "./copy.js";
|
|
5
|
+
import { assertNamedAgentTooling, chooseYesAgentTooling, collectYesAgents, initYesSupportedAgents, noDetectedAgentsMessage, planAgentSteps, planToolingSteps, planYesAgentSteps, resolveInitAgentSetup } from "./plan.js";
|
|
5
6
|
import { CannotMintApiKeyError } from "../mcp/mint.js";
|
|
6
7
|
import { detectAgent } from "./detect_host.js";
|
|
7
8
|
import { AgentSelectionSkipped, canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
8
|
-
import { a as mcpInstallError, s as reportMcpInstall } from "../_chunks/mcp-
|
|
9
|
-
import { l as reportPluginsInstall, o as installPlugins, s as pluginsInstallError } from "../_chunks/plugins-
|
|
10
|
-
import { c as skillsInstallError, o as installSkills, s as reportSkillsInstall } from "../_chunks/skills-
|
|
9
|
+
import { a as mcpInstallError, s as reportMcpInstall } from "../_chunks/mcp-SvqWzHnT.js";
|
|
10
|
+
import { l as reportPluginsInstall, o as installPlugins, s as pluginsInstallError } from "../_chunks/plugins-7cxVcgay.js";
|
|
11
|
+
import { c as skillsInstallError, o as installSkills, s as reportSkillsInstall } from "../_chunks/skills-Bv8oKKwE.js";
|
|
11
12
|
import { runAuthenticatedMcp } from "./auth.js";
|
|
12
13
|
import { raceSigint } from "./cancelled.js";
|
|
13
14
|
import { pickAgentSetupInteractively } from "./wizard.js";
|
|
14
|
-
import { detectProjectAgents } from "add-mcp";
|
|
15
15
|
// src/init/tooling.ts
|
|
16
16
|
const defaultProjectAgents = (cwd) => detectProjectAgents(cwd);
|
|
17
17
|
const TOOLING_STEP_LABELS = {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/init/unknown_agent_arg.ts
|
|
2
|
+
const UNKNOWN_AGENT_COMMANDS = ["link"];
|
|
3
|
+
const unknownAgentArgHint = (command, cliName) => `${cliName} ${command} has no --agent. Pass --project-id <id> to link without a TTY, or run ${cliName} ${command} in a terminal.`;
|
|
4
|
+
const BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
5
|
+
"-y",
|
|
6
|
+
"--yes",
|
|
7
|
+
"--default",
|
|
8
|
+
"--force",
|
|
9
|
+
"-h",
|
|
10
|
+
"--help",
|
|
11
|
+
"-v",
|
|
12
|
+
"--version",
|
|
13
|
+
"--color",
|
|
14
|
+
"--no-color",
|
|
15
|
+
"--analytics",
|
|
16
|
+
"--no-analytics",
|
|
17
|
+
"--oauth",
|
|
18
|
+
"--project",
|
|
19
|
+
"--global",
|
|
20
|
+
"--read-only",
|
|
21
|
+
"--readonly",
|
|
22
|
+
"--clear",
|
|
23
|
+
"--checks",
|
|
24
|
+
"--no-checks",
|
|
25
|
+
"--env-pull",
|
|
26
|
+
"--no-env-pull",
|
|
27
|
+
"--no-agent-setup",
|
|
28
|
+
"--no-link",
|
|
29
|
+
"--no-config",
|
|
30
|
+
"--claimable",
|
|
31
|
+
"--config",
|
|
32
|
+
"--list",
|
|
33
|
+
"--list-templates",
|
|
34
|
+
"--force-auth",
|
|
35
|
+
"--no-force-auth"
|
|
36
|
+
]);
|
|
37
|
+
const isUnknownAgentCommand = (token) => {
|
|
38
|
+
for (const command of UNKNOWN_AGENT_COMMANDS) if (command === token) return true;
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
const commandFromArgv = (argv) => {
|
|
42
|
+
let skipValue = false;
|
|
43
|
+
for (const token of argv) {
|
|
44
|
+
if (skipValue) {
|
|
45
|
+
skipValue = false;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (token === "--") break;
|
|
49
|
+
if (token.startsWith("-")) {
|
|
50
|
+
const flag = token.split("=")[0];
|
|
51
|
+
if (flag !== void 0 && !token.includes("=") && !BOOLEAN_FLAGS.has(flag)) skipValue = true;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (isUnknownAgentCommand(token)) return token;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const rewriteUnknownAgentArg = (input) => {
|
|
58
|
+
if (input.message !== "Unknown argument: agent" && input.message !== "Unknown argument: a") return;
|
|
59
|
+
const command = commandFromArgv(input.argv);
|
|
60
|
+
if (command === void 0) return;
|
|
61
|
+
return unknownAgentArgHint(command, input.cliName);
|
|
62
|
+
};
|
|
63
|
+
export { rewriteUnknownAgentArg };
|
package/dist/init/wizard.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CONFIG_INIT_SERVICES } from "../config_template.js";
|
|
2
|
-
import { getAgentDisplayName, listMcpAgentIds } from "../mcp/agents.js";
|
|
3
|
-
import { INIT_NEEDS_YES_OR_TERMINAL } from "./plan.js";
|
|
4
2
|
import { installedPackageManagers } from "../utils/package_manager.js";
|
|
5
|
-
import {
|
|
3
|
+
import { getAgentDisplayName, listMcpAgentIds } from "../mcp/agents.js";
|
|
4
|
+
import { AGENT_DETECTED_DESCRIPTION, AGENT_MCP_PICKER_MESSAGE, AGENT_MCP_SKIP_MESSAGE, AGENT_OTHER_DESCRIPTION, AGENT_PICKER_MESSAGE, AGENT_PLUGIN_SKIP_MESSAGE, AGENT_SETUP_MESSAGE, AGENT_SETUP_PLUGIN_DESCRIPTION, AGENT_SETUP_PLUGIN_TITLE, AGENT_SETUP_SKILLS_DESCRIPTION, AGENT_SETUP_SKILLS_TITLE, AGENT_SETUP_SKIP_DESCRIPTION, AGENT_SETUP_SKIP_TITLE, AGENT_SKILLS_PICKER_MESSAGE, AGENT_SKILLS_SKIP_MESSAGE, CONFIG_CONFIRM_HINT, CONFIG_CONFIRM_MESSAGE, MCP_AUTH_API_KEY_DESCRIPTION, MCP_AUTH_API_KEY_TITLE, MCP_AUTH_MESSAGE, MCP_AUTH_OAUTH_DESCRIPTION, MCP_AUTH_OAUTH_TITLE, MCP_SCOPE_GLOBAL_DESCRIPTION, MCP_SCOPE_GLOBAL_TITLE, MCP_SCOPE_MESSAGE, MCP_SCOPE_PROJECT_DESCRIPTION, MCP_SCOPE_PROJECT_TITLE, MODE_CUSTOM_DESCRIPTION, MODE_CUSTOM_TITLE, MODE_MESSAGE, MODE_RECOMMENDED_DESCRIPTION, MODE_RECOMMENDED_TITLE, PACKAGE_MANAGER_MESSAGE, PROJECT_SETUP_CLAIMABLE_DESCRIPTION, PROJECT_SETUP_CLAIMABLE_TITLE, PROJECT_SETUP_LINK_DESCRIPTION, PROJECT_SETUP_LINK_TITLE, PROJECT_SETUP_MESSAGE, SERVICES_HINT, SERVICES_MESSAGE, SKILLS_PICKER_MESSAGE, agentUnusableCommandDescription } from "./copy.js";
|
|
6
5
|
import { POSTGRES_SERVICE_CHOICE, keepPostgresSelected } from "../utils/service_picker.js";
|
|
6
|
+
import { INIT_NEEDS_YES_OR_TERMINAL } from "./plan.js";
|
|
7
7
|
import { canPickAgentsInteractively, pickAgentsInteractively } from "../utils/agent_picker.js";
|
|
8
8
|
import { NEON_SKILL_CATALOG, listSkillIds } from "../skills/catalog.js";
|
|
9
9
|
import { InitCancelled, restoreCursorVisibilityOnAbort } from "./cancelled.js";
|
|
@@ -72,18 +72,18 @@ const pickAgentSetupInteractively = async () => {
|
|
|
72
72
|
const pickInitAgentsInteractively = async (input) => {
|
|
73
73
|
requireInteractive();
|
|
74
74
|
const detected = new Set(input.detected);
|
|
75
|
-
const
|
|
75
|
+
const unusable = new Map((input.unusableCommands ?? []).map((row) => [row.agent, row]));
|
|
76
76
|
const selected = await pickAgentsInteractively({
|
|
77
77
|
onCancel: aborted,
|
|
78
78
|
message: input.setup === "skills" ? AGENT_SKILLS_PICKER_MESSAGE : input.setup === "mcp" ? AGENT_MCP_PICKER_MESSAGE : AGENT_PICKER_MESSAGE,
|
|
79
79
|
skipMessage: input.setup === "plugin" ? AGENT_PLUGIN_SKIP_MESSAGE : input.setup === "skills" ? AGENT_SKILLS_SKIP_MESSAGE : AGENT_MCP_SKIP_MESSAGE,
|
|
80
80
|
selected: input.preselected ?? input.detected,
|
|
81
81
|
choices: input.available.map((id) => {
|
|
82
|
-
const
|
|
82
|
+
const row = unusable.get(id);
|
|
83
83
|
return {
|
|
84
84
|
id,
|
|
85
85
|
title: `${getAgentDisplayName(id)} (${id})`,
|
|
86
|
-
description:
|
|
86
|
+
description: row !== void 0 ? agentUnusableCommandDescription(row) : detected.has(id) ? AGENT_DETECTED_DESCRIPTION : AGENT_OTHER_DESCRIPTION
|
|
87
87
|
};
|
|
88
88
|
})
|
|
89
89
|
});
|
package/dist/mcp/agents.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { agents, detectGlobalAgents, getAgentTypes } from "add-mcp";
|
|
1
|
+
import { agents, detectGlobalAgents, detectProjectAgents as detectProjectAgents$1, getAgentTypes } from "add-mcp";
|
|
2
2
|
// src/mcp/agents.ts
|
|
3
|
+
const UNSUPPORTED_AGENTS = /* @__PURE__ */ new Set(["mastracode"]);
|
|
4
|
+
const isSupportedAgent = (id) => !UNSUPPORTED_AGENTS.has(id);
|
|
3
5
|
const AGENT_ALIASES = {
|
|
4
6
|
cursor: "cursor",
|
|
5
7
|
copilot: "vscode",
|
|
@@ -25,10 +27,25 @@ const AGENT_ALIASES = {
|
|
|
25
27
|
mcporter: "mcporter",
|
|
26
28
|
zed: "zed",
|
|
27
29
|
grok: "grok-build",
|
|
28
|
-
"grok-build": "grok-build"
|
|
30
|
+
"grok-build": "grok-build",
|
|
31
|
+
"factory-droid": "factory-droid",
|
|
32
|
+
droid: "factory-droid",
|
|
33
|
+
factory: "factory-droid",
|
|
34
|
+
fx: "fx",
|
|
35
|
+
hermes: "hermes",
|
|
36
|
+
"hermes-agent": "hermes",
|
|
37
|
+
junie: "junie",
|
|
38
|
+
"kilo-code": "kilo-code",
|
|
39
|
+
kilo: "kilo-code",
|
|
40
|
+
"kimi-code": "kimi-code",
|
|
41
|
+
kimi: "kimi-code",
|
|
42
|
+
"kimi-code-cli": "kimi-code",
|
|
43
|
+
"kiro-cli": "kiro-cli",
|
|
44
|
+
kiro: "kiro-cli",
|
|
45
|
+
pi: "pi"
|
|
29
46
|
};
|
|
30
47
|
function listMcpAgentIds() {
|
|
31
|
-
return getAgentTypes();
|
|
48
|
+
return getAgentTypes().filter(isSupportedAgent);
|
|
32
49
|
}
|
|
33
50
|
function getAgentDisplayName(id) {
|
|
34
51
|
return agents[id].displayName;
|
|
@@ -48,7 +65,10 @@ function resolveAddMcpAgentId(rawAgent) {
|
|
|
48
65
|
return resolved;
|
|
49
66
|
}
|
|
50
67
|
async function detectInstalledAgents() {
|
|
51
|
-
return detectGlobalAgents();
|
|
68
|
+
return (await detectGlobalAgents()).filter(isSupportedAgent);
|
|
69
|
+
}
|
|
70
|
+
function detectProjectAgents(cwd) {
|
|
71
|
+
return detectProjectAgents$1(cwd).filter(isSupportedAgent);
|
|
52
72
|
}
|
|
53
73
|
function uniqueAgentIds(ids) {
|
|
54
74
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -60,4 +80,4 @@ function uniqueAgentIds(ids) {
|
|
|
60
80
|
}
|
|
61
81
|
return out;
|
|
62
82
|
}
|
|
63
|
-
export { agentSupportsHttpMcp, agentSupportsProjectMcp, detectInstalledAgents, getAgentDisplayName, listMcpAgentIds, resolveAddMcpAgentId, tryResolveAddMcpAgentId, uniqueAgentIds };
|
|
83
|
+
export { agentSupportsHttpMcp, agentSupportsProjectMcp, detectInstalledAgents, detectProjectAgents, getAgentDisplayName, listMcpAgentIds, resolveAddMcpAgentId, tryResolveAddMcpAgentId, uniqueAgentIds };
|
package/dist/mcp/install.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getCliName } from "../utils/cli_name.js";
|
|
2
|
+
import { chmodSync, existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { basename, dirname, join, relative } from "node:path";
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { agents, upsertServer } from "add-mcp";
|
|
6
|
+
import { parse } from "jsonc-parser";
|
|
5
7
|
// src/mcp/install.ts
|
|
6
8
|
const NEON_MCP_URL = "https://mcp.neon.tech/mcp";
|
|
7
9
|
const NEON_MCP_NAME = "Neon";
|
|
@@ -45,6 +47,7 @@ function neonMcpUrl(options = {}) {
|
|
|
45
47
|
}
|
|
46
48
|
const BEARER_RE = /Bearer\s+([^\s"]+)/i;
|
|
47
49
|
function nestedValue(root, key) {
|
|
50
|
+
if (key === "") return root;
|
|
48
51
|
let current = root;
|
|
49
52
|
for (const part of key.split(".")) {
|
|
50
53
|
if (!current || typeof current !== "object" || Array.isArray(current)) return;
|
|
@@ -77,35 +80,50 @@ function neonApiKeyFromFile(path, configKey) {
|
|
|
77
80
|
} catch {
|
|
78
81
|
return;
|
|
79
82
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
const errors = [];
|
|
84
|
+
const parsed = parse(raw, errors, { allowTrailingComma: true });
|
|
85
|
+
if (errors.length === 0) return bearerFromNeonMcpConfig(neonServers(nestedValue(parsed, configKey)));
|
|
86
|
+
const neonBlock = raw.match(/\[mcp_servers\.Neon\][\s\S]*?(?=\n\[|$)/)?.[0];
|
|
87
|
+
if (!neonBlock) return;
|
|
88
|
+
const url = neonBlock.match(/^url\s*=\s*"([^"]*)"/m)?.[1];
|
|
89
|
+
if (!url || !isNeonMcpUrl(url)) return;
|
|
90
|
+
return BEARER_RE.exec(neonBlock)?.[1];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Claude Code installs first so that a GitHub Copilot CLI install in the same run resolves to
|
|
94
|
+
* the `.mcp.json` Claude Code creates, rather than to `.github/mcp.json`.
|
|
95
|
+
*/
|
|
96
|
+
function mcpInstallOrder(selected) {
|
|
97
|
+
return [...selected.filter((agent) => agent === "claude-code"), ...selected.filter((agent) => agent !== "claude-code")];
|
|
89
98
|
}
|
|
90
|
-
|
|
99
|
+
/** The file add-mcp's `upsertServer` writes for this agent when `selected` install in `mcpInstallOrder`. */
|
|
100
|
+
function configPathFor(agent, scope, cwd, selected) {
|
|
91
101
|
const spec = agents[agent];
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
const local = scope === "project";
|
|
103
|
+
if (local && !spec.localConfigPath) return;
|
|
104
|
+
if (local && agent === "github-copilot-cli" && selected.includes("claude-code")) return join(cwd, ".mcp.json");
|
|
105
|
+
if (spec.resolveConfigPath) return spec.resolveConfigPath(spec, {
|
|
106
|
+
local,
|
|
107
|
+
cwd
|
|
108
|
+
});
|
|
109
|
+
return local && spec.localConfigPath ? join(cwd, spec.localConfigPath) : spec.configPath;
|
|
97
110
|
}
|
|
98
|
-
|
|
111
|
+
/** Where an existing Neon entry can sit, depending on the file's current layout. */
|
|
112
|
+
function configKeysFor(agent, scope) {
|
|
99
113
|
const spec = agents[agent];
|
|
100
|
-
if (
|
|
101
|
-
return
|
|
114
|
+
if (agent === "opencode") return ["mcp.servers", "mcp"];
|
|
115
|
+
if (agent === "github-copilot-cli" && scope === "project") return ["mcpServers", ""];
|
|
116
|
+
if (scope === "project" && spec.localConfigKey) return [spec.localConfigKey];
|
|
117
|
+
return [spec.configKey];
|
|
102
118
|
}
|
|
103
119
|
function existingNeonApiKey(options) {
|
|
104
120
|
for (const agent of options.agents) {
|
|
105
|
-
const path = configPathFor(agent, options.scope, options.cwd);
|
|
121
|
+
const path = configPathFor(agent, options.scope, options.cwd, options.agents);
|
|
106
122
|
if (!path) continue;
|
|
107
|
-
const
|
|
108
|
-
|
|
123
|
+
for (const configKey of configKeysFor(agent, options.scope)) {
|
|
124
|
+
const key = neonApiKeyFromFile(path, configKey);
|
|
125
|
+
if (key) return key;
|
|
126
|
+
}
|
|
109
127
|
}
|
|
110
128
|
}
|
|
111
129
|
function isTrackedByGit(cwd, relativePath) {
|
|
@@ -129,15 +147,31 @@ function isTrackedByGit(cwd, relativePath) {
|
|
|
129
147
|
}
|
|
130
148
|
function trackedProjectMcpConfig(options) {
|
|
131
149
|
for (const agent of options.agents) {
|
|
132
|
-
const
|
|
133
|
-
if (!
|
|
150
|
+
const path = configPathFor(agent, "project", options.cwd, options.agents);
|
|
151
|
+
if (!path) continue;
|
|
152
|
+
const relativePath = relative(options.cwd, path);
|
|
134
153
|
if (isTrackedByGit(options.cwd, relativePath)) return relativePath;
|
|
135
154
|
}
|
|
136
155
|
}
|
|
137
|
-
function mcpUnsupportedReason(agent, scope) {
|
|
156
|
+
function mcpUnsupportedReason(agent, scope, auth) {
|
|
138
157
|
const spec = agents[agent];
|
|
139
158
|
if (!spec.supportedTransports.includes("http")) return spec.unsupportedTransportMessage ?? `${spec.displayName} does not support remote HTTP MCP servers.`;
|
|
140
159
|
if (scope === "project" && !spec.localConfigPath) return `${spec.displayName} does not support project-level MCP config.`;
|
|
160
|
+
if (agent === "fx" && auth === "api-key") return `fx does not accept an API key in its MCP config. Run \`${getCliName()} mcp --oauth --agent fx\`.`;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* add-mcp refuses a project-level Claude Code install while `.github/mcp.json` exists without
|
|
164
|
+
* `.mcp.json`, because GitHub Copilot CLI reads `.mcp.json` first once it exists. Neon writes
|
|
165
|
+
* Claude Code's file anyway, so it creates `.mcp.json` before calling add-mcp.
|
|
166
|
+
*/
|
|
167
|
+
function createClaudeProjectConfig(cwd) {
|
|
168
|
+
const path = join(cwd, ".mcp.json");
|
|
169
|
+
if (existsSync(path) || !existsSync(join(cwd, ".github", "mcp.json"))) return;
|
|
170
|
+
writeFileSync(path, "{\n \"mcpServers\": {}\n}\n");
|
|
171
|
+
return path;
|
|
172
|
+
}
|
|
173
|
+
function errorMessage(err) {
|
|
174
|
+
return err instanceof Error ? err.message : String(err);
|
|
141
175
|
}
|
|
142
176
|
function gitignoreProjectConfig(path) {
|
|
143
177
|
const dir = dirname(path);
|
|
@@ -171,7 +205,7 @@ function redactSecrets(text) {
|
|
|
171
205
|
function installNeonMcpServer(options) {
|
|
172
206
|
const auth = options.auth ?? { kind: "oauth" };
|
|
173
207
|
const url = options.url ?? "https://mcp.neon.tech/mcp";
|
|
174
|
-
const unsupported = mcpUnsupportedReason(options.agent, options.scope);
|
|
208
|
+
const unsupported = mcpUnsupportedReason(options.agent, options.scope, auth.kind);
|
|
175
209
|
if (unsupported) return {
|
|
176
210
|
ok: false,
|
|
177
211
|
unsupported: true,
|
|
@@ -185,10 +219,41 @@ function installNeonMcpServer(options) {
|
|
|
185
219
|
type: "http",
|
|
186
220
|
url
|
|
187
221
|
};
|
|
222
|
+
const cwd = options.cwd ?? process.cwd();
|
|
223
|
+
let created;
|
|
224
|
+
if (options.agent === "claude-code" && options.scope === "project") try {
|
|
225
|
+
created = createClaudeProjectConfig(cwd);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
return {
|
|
228
|
+
ok: false,
|
|
229
|
+
unsupported: false,
|
|
230
|
+
error: `Could not create ${join(cwd, ".mcp.json")}: ${errorMessage(err)}`
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
if (options.scope === "project" && auth.kind === "api-key") {
|
|
234
|
+
const tracked = trackedProjectMcpConfig({
|
|
235
|
+
agents: [options.agent],
|
|
236
|
+
cwd
|
|
237
|
+
});
|
|
238
|
+
if (tracked) return {
|
|
239
|
+
ok: false,
|
|
240
|
+
unsupported: false,
|
|
241
|
+
error: `${tracked} is tracked by git. Untrack it before writing an API key, or pass --oauth.`
|
|
242
|
+
};
|
|
243
|
+
}
|
|
188
244
|
const result = upsertServer(options.agent, NEON_MCP_NAME, server, {
|
|
189
245
|
local: options.scope === "project",
|
|
190
|
-
cwd
|
|
246
|
+
cwd
|
|
191
247
|
});
|
|
248
|
+
if (!result.success && created) try {
|
|
249
|
+
rmSync(created, { force: true });
|
|
250
|
+
} catch (err) {
|
|
251
|
+
return {
|
|
252
|
+
ok: false,
|
|
253
|
+
unsupported: false,
|
|
254
|
+
error: `${redactSecrets(result.error ?? "Failed to write Neon MCP server config")} Could not remove ${created}: ${errorMessage(err)}`
|
|
255
|
+
};
|
|
256
|
+
}
|
|
192
257
|
if (result.success) {
|
|
193
258
|
if (auth.kind === "api-key") {
|
|
194
259
|
const paths = [result.path, ...result.extraPaths ?? []];
|
|
@@ -212,4 +277,4 @@ function installNeonMcpServer(options) {
|
|
|
212
277
|
error: redactSecrets(result.error ?? "Failed to write Neon MCP server config")
|
|
213
278
|
};
|
|
214
279
|
}
|
|
215
|
-
export { NEON_MCP_CATEGORIES, NEON_MCP_NAME, NEON_MCP_URL, existingNeonApiKey, installNeonMcpServer, isMcpCategory, isNeonMcpUrl, mcpUnsupportedReason, neonMcpUrl, parseMcpCategories, trackedProjectMcpConfig };
|
|
280
|
+
export { NEON_MCP_CATEGORIES, NEON_MCP_NAME, NEON_MCP_URL, existingNeonApiKey, installNeonMcpServer, isMcpCategory, isNeonMcpUrl, mcpInstallOrder, mcpUnsupportedReason, neonMcpUrl, parseMcpCategories, trackedProjectMcpConfig };
|
package/dist/mcp/targets.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { detectInstalledAgents, listMcpAgentIds, resolveAddMcpAgentId, uniqueAgentIds } from "./agents.js";
|
|
1
|
+
import { detectInstalledAgents, detectProjectAgents, listMcpAgentIds, resolveAddMcpAgentId, uniqueAgentIds } from "./agents.js";
|
|
2
2
|
import { mcpUnsupportedReason } from "./install.js";
|
|
3
|
-
import { detectProjectAgents } from "add-mcp";
|
|
4
3
|
// src/mcp/targets.ts
|
|
5
4
|
function mcpInstallableAgents(scope) {
|
|
6
5
|
return listMcpAgentIds().filter((id) => mcpUnsupportedReason(id, scope) === void 0);
|
|
@@ -14,7 +13,7 @@ function resolveInstallTargets(options) {
|
|
|
14
13
|
const install = [];
|
|
15
14
|
const skipped = [];
|
|
16
15
|
for (const agent of requested) {
|
|
17
|
-
const error = mcpUnsupportedReason(agent, options.scope);
|
|
16
|
+
const error = mcpUnsupportedReason(agent, options.scope, options.auth);
|
|
18
17
|
if (error) skipped.push({
|
|
19
18
|
agent,
|
|
20
19
|
error
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/plugins/child_env.ts
|
|
2
|
+
const TELEMETRY_BLOCKERS = ["DISABLE_TELEMETRY", "DO_NOT_TRACK"];
|
|
3
|
+
/** The env the plugins CLI and the agent CLIs it calls run with. */
|
|
4
|
+
const pluginsChildEnv = (base = process.env) => {
|
|
5
|
+
const env = { ...base };
|
|
6
|
+
for (const key of TELEMETRY_BLOCKERS) delete env[key];
|
|
7
|
+
for (const key of Object.keys(env)) if (key.toUpperCase() === "NEON_API_KEY") delete env[key];
|
|
8
|
+
return env;
|
|
9
|
+
};
|
|
10
|
+
export { pluginsChildEnv };
|