neon 3.4.0 → 3.5.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.
@@ -1,9 +1,10 @@
1
1
  import { FALLBACK_TEMPLATES, fetchTemplates, findTemplate, scaffoldTemplate } from "../bootstrap.js";
2
2
  import { detectIde, isCursorInstalled, isVSCodeInstalled } from "../detect_agent.js";
3
- import { resolveAddMcpAgentId } from "../agents.js";
3
+ import { agentSupportsProjectMcp, getSkillsAgentName, listMcpAgentIds, resolveAddMcpAgentId, supportsSkills, tryResolveAddMcpAgentId } from "../agents.js";
4
4
  import { NEON_EXTENSION_ID, downloadVsix } from "../vsix.js";
5
5
  import { findEditorCommand } from "../extension.js";
6
6
  import { inspectProject } from "../inspect.js";
7
+ import { installNeonMcpServer } from "../install_mcp.js";
7
8
  import { ensureNeonctl } from "../neonctl.js";
8
9
  import { ensureSkillsUpToDate } from "../skills.js";
9
10
  import { writeFileSync } from "node:fs";
@@ -105,7 +106,7 @@ async function buildBulkInspection(options) {
105
106
  "",
106
107
  "GROUPING: Preferences that share the same `group` field should be presented together in a single message (e.g. list all customize options at once and let the user answer them together). Preferences without a `group` must be asked individually.",
107
108
  "",
108
- detectedIde ? `The CLI has detected the IDE as: ${detectedIde.toLowerCase()}. Include this as the "ide" field in your reportBack data. IMPORTANT: The IDE and the agent are different — you may be Claude Code (agent) running inside Cursor (IDE). The extension installs into the IDE, so if the IDE is Cursor/VS Code/Windsurf, the extension IS applicable even if you are Claude Code.` : installedEditors.length > 0 ? `No IDE detected, but the following editors are installed: ${installedEditors.join(", ")}. The "installedEditors" field in this response lists them. If the user wants the extension installed, ask which editor to install it for and include that as the "ide" field in your reportBack data. If not, set "ide" to "none".` : `No IDE or supported editors detected. Set "ide" to "none" in your reportBack data.`,
109
+ detectedIde ? `The CLI has detected the IDE as: ${detectedIde.toLowerCase()}. Include this as the "ide" field in your reportBack data. IMPORTANT: The IDE and the agent are different — you may be Claude Code (agent) running inside Cursor (IDE). The extension installs into the IDE, so if the IDE is Cursor or VS Code, the extension IS applicable even if you are Claude Code.` : installedEditors.length > 0 ? `No IDE detected, but the following editors are installed: ${installedEditors.join(", ")}. The "installedEditors" field in this response lists them. If the user wants the extension installed, ask which editor to install it for and include that as the "ide" field in your reportBack data. If not, set "ide" to "none".` : `No IDE or supported editors detected. Set "ide" to "none" in your reportBack data.`,
109
110
  "",
110
111
  "After all questions are answered, call reportBack with a single --data JSON containing: agent, ide, mcpConfigured, and all preference answers. The CLI will inspect the project and merge results automatically."
111
112
  ].join("\n"),
@@ -123,7 +124,7 @@ async function buildBulkInspection(options) {
123
124
  {
124
125
  id: "agent_type",
125
126
  description: "Identify which coding agent is running this command",
126
- lookFor: ["Determine which agent you are: cursor, claude-code, copilot, vscode, windsurf, codex, cline, gemini-cli, goose, opencode, or antigravity", "Report your own agent identifier — this is used to configure the MCP server for the correct tool"]
127
+ lookFor: [`Determine which agent you are: ${listMcpAgentIds().join(", ")}`, "Report your own agent identifier — this is used to configure the MCP server for the correct tool"]
127
128
  },
128
129
  ...detectedIde ? [{
129
130
  id: "extension_installed",
@@ -150,7 +151,7 @@ async function buildBulkInspection(options) {
150
151
  ...(() => {
151
152
  const isPartialSkills = String(options.skillsScope ?? "").includes("partial");
152
153
  const needsMcpChoice = !options.mcpConfigured;
153
- const needsSkillsChoice = !options.skillsInstalled && !isPartialSkills;
154
+ const needsSkillsChoice = !options.skillsInstalled && !isPartialSkills && !(options.agent && !supportsSkills(options.agent));
154
155
  if (!(needsMcpChoice || needsSkillsChoice)) return [];
155
156
  return [{
156
157
  id: "mode",
@@ -176,10 +177,14 @@ async function buildBulkInspection(options) {
176
177
  value: "global",
177
178
  label: "Global (available in all projects)"
178
179
  },
179
- {
180
- value: "project",
181
- label: "Project-level (scoped to this project only)"
182
- },
180
+ ...(() => {
181
+ const known = options.agent ? tryResolveAddMcpAgentId(options.agent) : void 0;
182
+ if (known && !agentSupportsProjectMcp(known)) return [];
183
+ return [{
184
+ value: "project",
185
+ label: "Project-level (scoped to this project only)"
186
+ }];
187
+ })(),
183
188
  {
184
189
  value: "none",
185
190
  label: "Skip — do not install the MCP server"
@@ -192,7 +197,7 @@ async function buildBulkInspection(options) {
192
197
  },
193
198
  group: "customize"
194
199
  },
195
- ...!options.skillsInstalled && !String(options.skillsScope ?? "").includes("partial") ? [{
200
+ ...!options.skillsInstalled && !String(options.skillsScope ?? "").includes("partial") && !(options.agent && !supportsSkills(options.agent)) ? [{
196
201
  id: "skillsScope",
197
202
  question: "Where should Neon agent skills be installed?",
198
203
  context: "Only ask if skills are not already installed.",
@@ -223,7 +228,7 @@ async function buildBulkInspection(options) {
223
228
  label: "No"
224
229
  }],
225
230
  default: "true",
226
- context: "The extension installs into the IDE, NOT the agent. If the CLI detected the IDE (see detectedIde field), use that — e.g. Claude Code running inside Cursor means the IDE is Cursor and the extension IS applicable. Only applicable for VS Code-based IDEs (VS Code, Cursor, Windsurf). SKIP this question if the user is NOT in a VS Code-based IDE, or if the extension_installed check found it is already installed. Set installExtension to false in reportBack if skipped.",
231
+ context: "The extension installs into the IDE, NOT the agent. If the CLI detected the IDE (see detectedIde field), use that — e.g. Claude Code running inside Cursor means the IDE is Cursor and the extension IS applicable. Only applicable for VS Code and Cursor. SKIP this question if the user is NOT in VS Code or Cursor, or if the extension_installed check found it is already installed. Set installExtension to false in reportBack if skipped.",
227
232
  condition: {
228
233
  preferenceId: "mode",
229
234
  equals: "customize"
@@ -245,7 +250,9 @@ async function buildBulkInspection(options) {
245
250
  const needsSkillsChoice = !options.skillsInstalled && !hasPartial;
246
251
  const hasModeQuestion = needsMcpChoice || needsSkillsChoice;
247
252
  const modeField = hasModeQuestion ? ", mode: string" : "";
248
- const mcpField = hasModeQuestion ? ", mcpScope?: 'global'|'project'|'none'" : "";
253
+ const knownAgent = options.agent ? tryResolveAddMcpAgentId(options.agent) : void 0;
254
+ const mcpScopeUnion = knownAgent && !agentSupportsProjectMcp(knownAgent) ? "'global'|'none'" : "'global'|'project'|'none'";
255
+ const mcpField = hasModeQuestion ? `, mcpScope?: ${mcpScopeUnion}` : "";
249
256
  const skillsField = needsSkillsChoice ? ", skillsScope?: string" : "";
250
257
  const extField = hasModeQuestion ? ", installExtension?: bool" : "";
251
258
  return `<json: { agent: string, ide: string, mcpConfigured: bool${options.skillsInstalled || hasPartial ? `, skillsScope: "${options.skillsInstalled ? options.skillsScope || "project" : partialScope}"` : skillsField}${previewFlag}${modeField}${mcpField}${extField}${hasApp ? ", features?: string" : ", template: string"} }>`;
@@ -332,22 +339,12 @@ async function executeBatchedInstallation(options) {
332
339
  status: "success"
333
340
  });
334
341
  else {
335
- const mcpArgs = [
336
- "-y",
337
- "add-mcp",
338
- "https://mcp.neon.tech/mcp",
339
- ...mcpScope === "global" ? ["-g"] : [],
340
- "-n",
341
- "Neon",
342
- "-y",
343
- "-a",
344
- mcpAgentId
345
- ];
346
- try {
347
- await execa("npx", mcpArgs, {
348
- stdio: "pipe",
349
- timeout: 6e4
350
- });
342
+ const installed = installNeonMcpServer({
343
+ agent: mcpAgentId,
344
+ scope: mcpScope === "project" ? "project" : "global",
345
+ cwd: process.cwd()
346
+ });
347
+ if (installed.ok) {
351
348
  results.push({
352
349
  id: "install_mcp",
353
350
  description: `Installed Neon MCP server (${mcpScope} scope)`,
@@ -366,20 +363,32 @@ async function executeBatchedInstallation(options) {
366
363
  status: "success",
367
364
  manualAction: true
368
365
  });
369
- } catch (err) {
366
+ } else if (installed.unsupported) {
367
+ const projectUnsupported = mcpScope === "project" && !agentSupportsProjectMcp(mcpAgentId);
370
368
  results.push({
371
369
  id: "install_mcp",
372
- description: "Failed to install Neon MCP server",
373
- status: "failed",
374
- error: err instanceof Error ? err.message : "Unknown error"
370
+ description: installed.error,
371
+ status: projectUnsupported ? "failed" : "success",
372
+ ...projectUnsupported ? { error: installed.error } : { manualAction: true }
375
373
  });
376
- }
374
+ } else results.push({
375
+ id: "install_mcp",
376
+ description: "Failed to install Neon MCP server",
377
+ status: "failed",
378
+ error: installed.error
379
+ });
377
380
  }
381
+ const skillsAgent = getSkillsAgentName(agentId);
378
382
  if (isBootstrap) results.push({
379
383
  id: "install_skills",
380
384
  description: "Neon agent skills included in template",
381
385
  status: "success"
382
386
  });
387
+ else if (!skillsAgent) results.push({
388
+ id: "skip_skills",
389
+ description: "No Neon agent skills target for this agent",
390
+ status: "success"
391
+ });
383
392
  else {
384
393
  const skillsScope = options.skillsScope ?? "project";
385
394
  if (await ensureSkillsUpToDate(agentId, skillsScope, options.preview)) results.push({
@@ -389,7 +398,7 @@ async function executeBatchedInstallation(options) {
389
398
  });
390
399
  else {
391
400
  const { getSkillList } = await import("../skills.js");
392
- const cmds = getSkillList(options.preview).map((s) => `skills add neondatabase/agent-skills --skill ${s} --agent ${agentId}${skillsScope === "global" ? " -g" : ""} -y`);
401
+ const cmds = getSkillList(options.preview).map((s) => `skills add neondatabase/agent-skills --skill ${s} --agent ${skillsAgent}${skillsScope === "global" ? " -g" : ""} -y`);
393
402
  results.push({
394
403
  id: "install_skills",
395
404
  description: "Failed to install Neon agent skills automatically. Run these commands to install manually:",
@@ -478,7 +487,7 @@ async function mergeCliInspection(options) {
478
487
  function isVscodeBasedIde(options) {
479
488
  if (options.ide) {
480
489
  const ide = options.ide.toLowerCase();
481
- return ide === "cursor" || ide === "vscode" || ide === "vs-code" || ide === "windsurf";
490
+ return ide === "cursor" || ide === "vscode" || ide === "vs-code";
482
491
  }
483
492
  return options.isVscodeIde === true;
484
493
  }
@@ -1,5 +1,5 @@
1
1
  import { getSkillsAgentName } from "../agents.js";
2
- import { SKILL_REFERENCE_URLS } from "../skills.js";
2
+ import { SKILL_REFERENCE_URLS, getSkillList } from "../skills.js";
3
3
  //#region src/init/phases/skills.ts
4
4
  async function handleSkillsPhase(options) {
5
5
  const agentArgs = options.agent ? [
@@ -8,6 +8,14 @@ async function handleSkillsPhase(options) {
8
8
  "--json"
9
9
  ] : ["--json"];
10
10
  const skillsAgent = options.agent ? getSkillsAgentName(options.agent) : "claude-code";
11
+ if (options.agent && !skillsAgent) return {
12
+ phase: "tooling",
13
+ status: "skipped",
14
+ nextAction: {
15
+ type: "run_neon_init",
16
+ args: agentArgs
17
+ }
18
+ };
11
19
  if (options.status) return {
12
20
  phase: "tooling",
13
21
  status: "skills_check",
@@ -34,7 +42,7 @@ async function handleSkillsPhase(options) {
34
42
  status: "installing_skills",
35
43
  nextAction: {
36
44
  type: "run_command",
37
- command: `npx -y skills add neondatabase/agent-skills --skill neon-postgres --agent ${skillsAgent} -y`,
45
+ command: getSkillList().map((skill) => `npx -y skills add neondatabase/agent-skills --skill ${skill} --agent ${skillsAgent ?? "claude-code"} -y`).join(" && "),
38
46
  description: `Installing Neon agent skills for ${skillsAgent}.`,
39
47
  timeout: 3e4,
40
48
  onSuccess: {
@@ -1,7 +1,8 @@
1
+ import { supportsSkills, tryResolveAddMcpAgentId } from "../agents.js";
1
2
  import { isAuthenticated } from "../auth.js";
2
3
  import { inspectProject } from "../inspect.js";
3
4
  //#region src/init/phases/status.ts
4
- async function handleStatusPhase(_options) {
5
+ async function handleStatusPhase(options) {
5
6
  const authed = await isAuthenticated();
6
7
  const inspection = await inspectProject([
7
8
  {
@@ -41,7 +42,8 @@ async function handleStatusPhase(_options) {
41
42
  message: "No DATABASE_URL found in .env",
42
43
  command: `neon init --agent --data '{"step":"db"}'`
43
44
  });
44
- if (!skillsInstalled) recommendations.push({
45
+ const statusAgent = options.agent ? tryResolveAddMcpAgentId(options.agent) : void 0;
46
+ if (!skillsInstalled && (!statusAgent || supportsSkills(statusAgent))) recommendations.push({
45
47
  priority: "medium",
46
48
  message: "Neon agent skills not detected in this project",
47
49
  command: `neon init --agent --data '{"step":"skills","install":true}'`
@@ -3,8 +3,8 @@ import { getSkillsAgentName } from "./agents.js";
3
3
  import { existsSync, statSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { log, spinner } from "@clack/prompts";
6
- import { execa } from "execa";
7
6
  import { dim } from "yoctocolors";
7
+ import { execa } from "execa";
8
8
  //#region src/init/skills.ts
9
9
  /**
10
10
  * Ensures the `skills` CLI is globally installed so npx doesn't need
@@ -51,41 +51,20 @@ const SKILL_REFERENCE_URLS = {
51
51
  neonJs: `${SKILL_BASE_URL}/neon-js.md`
52
52
  };
53
53
  /**
54
- * Maps Editor display names to the skills CLI agent name.
55
- */
56
- function editorToSkillsAgent(editor) {
57
- switch (editor) {
58
- case "Cursor": return "cursor";
59
- case "VS Code":
60
- case "GitHub Copilot CLI": return "github-copilot";
61
- case "Claude CLI": return "claude-code";
62
- case "Codex": return "codex";
63
- case "OpenCode": return "opencode";
64
- case "Antigravity": return "antigravity";
65
- case "Cline":
66
- case "Cline CLI": return "cline";
67
- case "Gemini CLI": return "gemini-cli";
68
- case "Goose": return "goose";
69
- case "Claude Desktop": return "claude-code";
70
- case "MCPorter": return "mcporter";
71
- case "Zed": return "zed";
72
- default: return "";
73
- }
74
- }
75
- /**
76
54
  * Installs Neon agent skills using Vercel's skills CLI.
77
55
  */
78
- async function installAgentSkills(selectedEditors, options) {
56
+ async function installAgentSkills(selectedAgents, options) {
79
57
  const quiet = options?.json === true;
80
- const editorsWithSkills = selectedEditors.filter((e) => editorToSkillsAgent(e) !== "");
81
- if (editorsWithSkills.length === 0) return true;
58
+ const agentsWithSkills = selectedAgents.filter((id) => getSkillsAgentName(id) !== void 0);
59
+ if (agentsWithSkills.length === 0) return true;
82
60
  const skillsSpinner = quiet ? null : spinner();
83
61
  skillsSpinner?.start("Installing agent skills for Neon in this project...");
84
62
  let anyFailed = false;
85
63
  await ensureSkillsCli();
86
64
  const skills = getSkillList(options?.preview);
87
- for (const editor of editorsWithSkills) {
88
- const agentName = editorToSkillsAgent(editor);
65
+ for (const agent of agentsWithSkills) {
66
+ const agentName = getSkillsAgentName(agent);
67
+ if (!agentName) continue;
89
68
  for (const skill of skills) try {
90
69
  await execa("skills", [
91
70
  "add",
@@ -101,7 +80,7 @@ async function installAgentSkills(selectedEditors, options) {
101
80
  timeout: 12e4
102
81
  });
103
82
  } catch (error) {
104
- if (!quiet) log.error(`Failed to install skill ${skill} for ${editor}: ${error instanceof Error ? error.message : "Unknown error"}`);
83
+ if (!quiet) log.error(`Failed to install skill ${skill} for ${agent}: ${error instanceof Error ? error.message : "Unknown error"}`);
105
84
  anyFailed = true;
106
85
  }
107
86
  }
@@ -126,9 +105,42 @@ const GLOBAL_SKILLS_DIRS = (() => {
126
105
  "claude-code": [resolve(home, ".claude", "skills"), agentsDir],
127
106
  "github-copilot": [resolve(home, ".vscode", "skills"), agentsDir],
128
107
  codex: [resolve(home, ".codex", "skills"), agentsDir],
129
- cline: [resolve(home, ".cline", "skills"), agentsDir]
108
+ cline: [resolve(home, ".cline", "skills"), agentsDir],
109
+ grok: [resolve(home, ".grok", "skills"), agentsDir]
130
110
  };
131
111
  })();
112
+ const PROJECT_SKILLS_DIRS = {
113
+ cursor: [".cursor/skills", ".agents/skills"],
114
+ "claude-code": [".claude/skills", ".agents/skills"],
115
+ "github-copilot": [".vscode/skills", ".agents/skills"],
116
+ codex: [".codex/skills", ".agents/skills"],
117
+ cline: [".cline/skills", ".agents/skills"],
118
+ grok: [".grok/skills", ".agents/skills"]
119
+ };
120
+ function skillDirsForAgent(skillsId, scope, cwd, home) {
121
+ if (scope === "global") return [.../* @__PURE__ */ new Set([...GLOBAL_SKILLS_DIRS[skillsId] ?? [], resolve(home, ".agents", "skills")])];
122
+ return [...new Set([...PROJECT_SKILLS_DIRS[skillsId] ?? [], ".agents/skills"].map((dir) => resolve(cwd, dir)))];
123
+ }
124
+ function missingSkillsForAgent(agent, options = {}) {
125
+ const skillsId = getSkillsAgentName(agent);
126
+ if (!skillsId) return [];
127
+ const cwd = options.cwd ?? process.cwd();
128
+ const home = process.env.HOME || process.env.USERPROFILE || "";
129
+ const dirs = skillDirsForAgent(skillsId, options.scope ?? "project", cwd, home);
130
+ return getSkillList(options.preview).filter((skill) => !dirs.some((dir) => existsSync(resolve(dir, skill, "SKILL.md"))));
131
+ }
132
+ function skillsInstalledForAgent(agent, cwd = process.cwd(), preview = false) {
133
+ if (!getSkillsAgentName(agent)) return true;
134
+ return missingSkillsForAgent(agent, {
135
+ cwd,
136
+ scope: "project",
137
+ preview
138
+ }).length === 0 || missingSkillsForAgent(agent, {
139
+ cwd,
140
+ scope: "global",
141
+ preview
142
+ }).length === 0;
143
+ }
132
144
  /**
133
145
  * Checks whether skills were recently updated (within the freshness window).
134
146
  * Checks both project-level (skills-lock.json mtime) and global (skills dir mtime).
@@ -136,18 +148,16 @@ const GLOBAL_SKILLS_DIRS = (() => {
136
148
  function skillsAreFresh(agent, requiredSkills) {
137
149
  const now = Date.now();
138
150
  const cwd = process.cwd();
139
- const projectSkillDirs = [
140
- ".agents",
141
- ".cursor",
142
- ".claude"
143
- ];
151
+ const skillsId = getSkillsAgentName(agent);
152
+ const projectDirs = (skillsId ? PROJECT_SKILLS_DIRS[skillsId] : void 0)?.map((dir) => resolve(cwd, dir)) ?? [];
144
153
  const lockPath = resolve(cwd, "skills-lock.json");
145
- if (existsSync(lockPath)) try {
154
+ if (existsSync(lockPath) && projectDirs.length > 0) try {
146
155
  if (now - statSync(lockPath).mtimeMs < SKILLS_FRESHNESS_MS) {
147
- if (requiredSkills.every((skill) => projectSkillDirs.some((dir) => existsSync(resolve(cwd, dir, "skills", skill, "SKILL.md"))))) return true;
156
+ if (requiredSkills.every((skill) => projectDirs.some((dir) => existsSync(resolve(dir, skill, "SKILL.md"))))) return true;
148
157
  }
149
158
  } catch {}
150
159
  const agentName = getSkillsAgentName(agent);
160
+ if (!agentName) return false;
151
161
  const globalDirs = GLOBAL_SKILLS_DIRS[agentName] ?? [];
152
162
  for (const dir of globalDirs) if (requiredSkills.every((skill) => existsSync(resolve(dir, skill, "SKILL.md")))) try {
153
163
  if (now - statSync(resolve(dir, requiredSkills[0], "SKILL.md")).mtimeMs < SKILLS_FRESHNESS_MS) return true;
@@ -163,23 +173,15 @@ function skillsAreFresh(agent, requiredSkills) {
163
173
  */
164
174
  async function ensureSkillsUpToDate(agent, scope, preview) {
165
175
  const resolvedAgent = agent || "cursor";
166
- const skills = getSkillList(preview);
167
- if (skillsAreFresh(resolvedAgent, skills)) return true;
168
- await ensureSkillsCli();
169
176
  const agentName = getSkillsAgentName(resolvedAgent);
177
+ if (!agentName) return true;
178
+ if (skillsAreFresh(resolvedAgent, getSkillList(preview))) return true;
179
+ await ensureSkillsCli();
170
180
  let allOk = true;
171
- const home = process.env.HOME || process.env.USERPROFILE || "";
172
- const cwd = process.cwd();
173
- const checkDirs = scope === "global" ? [
174
- resolve(home, ".cursor", "skills"),
175
- resolve(home, ".claude", "skills"),
176
- resolve(home, ".agents", "skills")
177
- ] : [
178
- resolve(cwd, ".cursor", "skills"),
179
- resolve(cwd, ".claude", "skills"),
180
- resolve(cwd, ".agents", "skills")
181
- ];
182
- const missingSkills = skills.filter((skill) => !checkDirs.some((dir) => existsSync(resolve(dir, skill, "SKILL.md"))));
181
+ const missingSkills = missingSkillsForAgent(resolvedAgent, {
182
+ scope: scope ?? "project",
183
+ preview
184
+ });
183
185
  if (missingSkills.length === 0) return true;
184
186
  for (const skill of missingSkills) try {
185
187
  await execa("skills", [
@@ -201,4 +203,4 @@ async function ensureSkillsUpToDate(agent, scope, preview) {
201
203
  return allOk;
202
204
  }
203
205
  //#endregion
204
- export { SKILL_REFERENCE_URLS, ensureSkillsUpToDate, getSkillList, installAgentSkills };
206
+ export { SKILL_REFERENCE_URLS, ensureSkillsUpToDate, getSkillList, installAgentSkills, missingSkillsForAgent, skillsInstalledForAgent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neon",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "CLI tool for Neon, the cloud backend primitives built around Lakebase Postgres",
5
5
  "keywords": [
6
6
  "neon",
@@ -46,6 +46,7 @@
46
46
  "@clack/prompts": "0.10.1",
47
47
  "@hono/node-server": "2.0.4",
48
48
  "@segment/analytics-node": "1.3.0",
49
+ "add-mcp": "2.0.0",
49
50
  "chalk": "5.3.0",
50
51
  "chokidar": "5.0.0",
51
52
  "cli-table": "0.3.11",
@@ -63,8 +64,8 @@
63
64
  "yaml": "^2.9.0",
64
65
  "yargs": "17.7.2",
65
66
  "yoctocolors": "^2.1.2",
66
- "@neon/config": "1.0.0",
67
67
  "@neon/sdk": "2.0.0",
68
+ "@neon/config": "1.0.0",
68
69
  "@neon/config-runtime": "1.0.0"
69
70
  },
70
71
  "optionalDependencies": {