neon-init 0.16.3 → 0.17.1

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/dist/cli.js CHANGED
@@ -22,18 +22,18 @@ const jsonOption = { json: {
22
22
  } };
23
23
  const agentOption = { agent: {
24
24
  alias: "a",
25
- type: "string",
26
- description: "Agent to configure (cursor, copilot, claude, etc.)."
25
+ type: "boolean",
26
+ default: false,
27
+ description: "Enable agent/JSON mode (agent type is auto-detected)."
27
28
  } };
28
29
  function outputJson(data) {
29
30
  console.log(JSON.stringify(enrichResponse(data), null, 2));
30
31
  }
31
32
  /**
32
- * Resolve the agent ID: use the explicit --agent value if provided,
33
- * otherwise auto-detect from the environment.
33
+ * Resolve the agent ID from the environment.
34
34
  */
35
- function resolveAgent(explicit) {
36
- return explicit ?? detectAgent() ?? void 0;
35
+ function resolveAgent() {
36
+ return detectAgent() ?? void 0;
37
37
  }
38
38
  /**
39
39
  * Detects if an AI agent is invoking the CLI programmatically.
@@ -54,10 +54,6 @@ function detectAgentInvocation() {
54
54
  yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [options]").command("$0", "Initialize Neon for your project", (y) => y.options(jsonOption).options(agentOption).option("data", {
55
55
  type: "string",
56
56
  description: "JSON object with a \"step\" field to route to a specific phase (auth, db, setup, getting-started, mcp, skills, migrations, neon-auth, status, finalize) and phase-specific options."
57
- }).option("skip-neon-auth", {
58
- type: "boolean",
59
- default: false,
60
- description: "Skip the Neon Auth setup phase."
61
57
  }).option("skip-migrations", {
62
58
  type: "boolean",
63
59
  default: false,
@@ -68,8 +64,24 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
68
64
  description: "Enable preview features (e.g. project bootstrapping from templates)."
69
65
  }), async (argv) => {
70
66
  const detectedAgent = detectAgentInvocation();
71
- const agent = resolveAgent(argv.agent ?? detectedAgent ?? void 0);
72
- const jsonMode = argv.json || argv.agent !== void 0 || detectedAgent !== null;
67
+ const agent = resolveAgent();
68
+ const jsonMode = argv.json || argv.agent || detectedAgent !== null;
69
+ if (argv.data && jsonMode) {
70
+ const { routeDataStep } = await import("./lib/route-command.js");
71
+ let data;
72
+ try {
73
+ data = JSON.parse(argv.data);
74
+ } catch {
75
+ console.error("Invalid JSON in --data flag. Expected a JSON object.");
76
+ process.exit(1);
77
+ return;
78
+ }
79
+ if (typeof data.step === "string") {
80
+ outputJson(await routeDataStep(data, agent));
81
+ process.exit(0);
82
+ return;
83
+ }
84
+ }
73
85
  if (argv.data && jsonMode) {
74
86
  const { routeDataStep } = await import("./lib/route-command.js");
75
87
  let data;
@@ -89,7 +101,6 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
89
101
  if (jsonMode) {
90
102
  outputJson(await orchestrate({
91
103
  agent,
92
- skipNeonAuth: argv.skipNeonAuth,
93
104
  skipMigrations: argv.skipMigrations,
94
105
  preview: argv.preview
95
106
  }));
@@ -107,7 +118,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
107
118
  description: "Just check if authentication is valid, don't initiate a flow."
108
119
  }), async (argv) => {
109
120
  outputJson(await handleAuthPhase({
110
- agent: resolveAgent(argv.agent),
121
+ agent: resolveAgent(),
111
122
  method: argv.method,
112
123
  verify: argv.verify
113
124
  }));
@@ -137,7 +148,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
137
148
  if (argv.mcpConfigured === "true") mcpConfigured = true;
138
149
  else if (argv.mcpConfigured === "false") mcpConfigured = false;
139
150
  outputJson(await handleMcpPhase({
140
- agent: resolveAgent(argv.agent),
151
+ agent: resolveAgent(),
141
152
  status: argv.status,
142
153
  install: argv.install || argv.update,
143
154
  scope: argv.scope,
@@ -158,7 +169,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
158
169
  description: "Update agent skills to latest."
159
170
  }), async (argv) => {
160
171
  outputJson(await handleSkillsPhase({
161
- agent: resolveAgent(argv.agent),
172
+ agent: resolveAgent(),
162
173
  status: argv.status,
163
174
  install: argv.install,
164
175
  update: argv.update
@@ -229,7 +240,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
229
240
  ]) if (data[key] === "true") data[key] = true;
230
241
  else if (data[key] === "false") data[key] = false;
231
242
  outputJson(await handleSetupPhase({
232
- agent: resolveAgent(argv.agent),
243
+ agent: resolveAgent(),
233
244
  ...data
234
245
  }));
235
246
  process.exit(0);
@@ -245,7 +256,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
245
256
  if (argv.isVscodeIde === "true") isVscodeIde = true;
246
257
  else if (argv.isVscodeIde === "false") isVscodeIde = false;
247
258
  outputJson(await handleSetupPhase({
248
- agent: resolveAgent(argv.agent),
259
+ agent: resolveAgent(),
249
260
  mcpConfigured,
250
261
  connectionString,
251
262
  connectionParams: argv.connectionParams,
@@ -291,14 +302,14 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
291
302
  return;
292
303
  }
293
304
  outputJson(await handleGettingStartedPhase({
294
- agent: resolveAgent(argv.agent),
305
+ agent: resolveAgent(),
295
306
  ...data
296
307
  }));
297
308
  process.exit(0);
298
309
  return;
299
310
  }
300
311
  outputJson(await handleGettingStartedPhase({
301
- agent: resolveAgent(argv.agent),
312
+ agent: resolveAgent(),
302
313
  hasConnectionString: argv.hasConnectionString,
303
314
  framework: argv.framework,
304
315
  orm: argv.orm,
@@ -329,7 +340,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
329
340
  description: "Error from a previous step."
330
341
  }), async (argv) => {
331
342
  outputJson(await handleDbPhase({
332
- agent: resolveAgent(argv.agent),
343
+ agent: resolveAgent(),
333
344
  orgId: argv.orgId,
334
345
  projectId: argv.projectId,
335
346
  orgsResult: argv.orgsResult,
@@ -352,7 +363,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
352
363
  description: "Neon project ID to configure."
353
364
  }), async (argv) => {
354
365
  outputJson(await handleNeonAuthPhase({
355
- agent: resolveAgent(argv.agent),
366
+ agent: resolveAgent(),
356
367
  setup: argv.setup,
357
368
  info: argv.info,
358
369
  projectId: argv.projectId
@@ -374,7 +385,7 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
374
385
  description: "Apply pending migrations."
375
386
  }), async (argv) => {
376
387
  outputJson(await handleMigrationsPhase({
377
- agent: resolveAgent(argv.agent),
388
+ agent: resolveAgent(),
378
389
  tool: argv.tool,
379
390
  migrationDir: argv.migrationDir,
380
391
  scaffold: argv.scaffold,
@@ -385,8 +396,8 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
385
396
  const { handleCleanup } = await import("./lib/phases/cleanup.js");
386
397
  outputJson(handleCleanup());
387
398
  process.exit(0);
388
- }).command("status", "Check the status of your Neon setup", (y) => y.options(jsonOption).options(agentOption), async (argv) => {
389
- outputJson(await handleStatusPhase({ agent: resolveAgent(argv.agent) }));
399
+ }).command("status", "Check the status of your Neon setup", (y) => y.options(jsonOption).options(agentOption), async (_argv) => {
400
+ outputJson(await handleStatusPhase({ agent: resolveAgent() }));
390
401
  process.exit(0);
391
402
  }).help().strict().parse();
392
403
  //#endregion
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { interactiveInit } from \"./interactive.js\";\nimport { detectAgent } from \"./lib/detect-agent.js\";\nimport { handleAuthPhase } from \"./lib/phases/auth.js\";\nimport { handleDbPhase } from \"./lib/phases/db.js\";\nimport { handleGettingStartedPhase } from \"./lib/phases/getting-started.js\";\nimport { handleMcpPhase } from \"./lib/phases/mcp.js\";\nimport { handleMigrationsPhase } from \"./lib/phases/migrations.js\";\nimport { handleNeonAuthPhase } from \"./lib/phases/neon-auth.js\";\nimport { handleSetupPhase } from \"./lib/phases/setup.js\";\nimport { handleSkillsPhase } from \"./lib/phases/skills.js\";\nimport { handleStatusPhase } from \"./lib/phases/status.js\";\nimport { orchestrate } from \"./v2.js\";\n\n// ---------------------------------------------------------------------------\n// Shared options\n// ---------------------------------------------------------------------------\n\nconst jsonOption = {\n\tjson: {\n\t\ttype: \"boolean\" as const,\n\t\tdefault: false,\n\t\tdescription:\n\t\t\t\"Output structured JSON for agent consumption. Suppresses interactive UI.\",\n\t},\n};\n\nconst agentOption = {\n\tagent: {\n\t\talias: \"a\",\n\t\ttype: \"string\" as const,\n\t\tdescription: \"Agent to configure (cursor, copilot, claude, etc.).\",\n\t},\n};\n\n// ---------------------------------------------------------------------------\n// Output helper\n// ---------------------------------------------------------------------------\n\nimport { enrichResponse } from \"./lib/enrich-output.js\";\n\nfunction outputJson(data: unknown): void {\n\tconsole.log(JSON.stringify(enrichResponse(data), null, 2));\n}\n\n/**\n * Resolve the agent ID: use the explicit --agent value if provided,\n * otherwise auto-detect from the environment.\n */\nfunction resolveAgent(explicit: string | undefined): string | undefined {\n\treturn explicit ?? detectAgent() ?? undefined;\n}\n\n/**\n * Detects if an AI agent is invoking the CLI programmatically.\n *\n * Agent-specific env vars (CLAUDECODE, CODEX, CLINE) are unambiguous.\n * For IDE-based agents (Cursor, VS Code, Windsurf), we require non-TTY\n * stdin to distinguish \"agent spawned this\" from \"human typed this in\n * the IDE's integrated terminal\".\n */\nfunction detectAgentInvocation(): string | null {\n\tconst env = process.env;\n\n\t// Agent-specific env vars (always definitive, regardless of TTY)\n\tif (\n\t\tenv.CLAUDECODE === \"1\" ||\n\t\tenv.CLAUDE_CODE === \"1\" ||\n\t\tenv.CLAUDE_CLI === \"1\"\n\t)\n\t\treturn \"claude-code\";\n\tif (env.CODEX === \"1\") return \"codex\";\n\tif (env.CLINE === \"1\") return \"cline\";\n\n\t// IDE detected + non-interactive stdin = agent spawned us\n\t// (a human typing in the same terminal would have isTTY=true)\n\tif (!process.stdin.isTTY) {\n\t\treturn detectAgent();\n\t}\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// CLI definition\n// ---------------------------------------------------------------------------\n\nconst cli = yargs(hideBin(process.argv))\n\t.scriptName(\"neon-init\")\n\t.usage(\"$0 [command] [options]\")\n\n\t// -----------------------------------------------------------------------\n\t// Default command: orchestrator (v2 json) or v1 interactive\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"$0\",\n\t\t\"Initialize Neon for your project\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"data\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'JSON object with a \"step\" field to route to a specific phase (auth, db, setup, getting-started, mcp, skills, migrations, neon-auth, status, finalize) and phase-specific options.',\n\t\t\t\t})\n\t\t\t\t.option(\"skip-neon-auth\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Skip the Neon Auth setup phase.\",\n\t\t\t\t})\n\t\t\t\t.option(\"skip-migrations\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Skip the migrations phase.\",\n\t\t\t\t})\n\t\t\t\t.option(\"preview\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Enable preview features (e.g. project bootstrapping from templates).\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst detectedAgent = detectAgentInvocation();\n\t\t\tconst agent = resolveAgent(\n\t\t\t\targv.agent ?? detectedAgent ?? undefined,\n\t\t\t);\n\t\t\tconst jsonMode =\n\t\t\t\targv.json || argv.agent !== undefined || detectedAgent !== null;\n\n\t\t\t// --data with a \"step\" field routes to the appropriate phase\n\t\t\tif (argv.data && jsonMode) {\n\t\t\t\tconst { routeDataStep } = await import(\n\t\t\t\t\t\"./lib/route-command.js\"\n\t\t\t\t);\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Invalid JSON in --data flag. Expected a JSON object.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (typeof data.step === \"string\") {\n\t\t\t\t\tconst result = await routeDataStep(data, agent);\n\t\t\t\t\toutputJson(result);\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (jsonMode) {\n\t\t\t\t// v2: agent-driven state machine\n\t\t\t\tconst result = await orchestrate({\n\t\t\t\t\tagent,\n\t\t\t\t\tskipNeonAuth: argv.skipNeonAuth,\n\t\t\t\t\tskipMigrations: argv.skipMigrations,\n\t\t\t\t\tpreview: argv.preview,\n\t\t\t\t});\n\t\t\t\toutputJson(result);\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\t// v2 interactive mode — same phase logic, driven by terminal prompts\n\t\t\tawait interactiveInit({ preview: argv.preview });\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// auth\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"auth\",\n\t\t\"Manage Neon platform authentication\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"method\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"existing\", \"new\"] as const,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Auth method: \"existing\" for OAuth sign-in, \"new\" for sign-up flow.',\n\t\t\t\t})\n\t\t\t\t.option(\"verify\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Just check if authentication is valid, don't initiate a flow.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleAuthPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\tmethod: argv.method as \"existing\" | \"new\" | undefined,\n\t\t\t\tverify: argv.verify,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// mcp\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"mcp\",\n\t\t\"Manage the Neon MCP server\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"status\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Check if the MCP server is configured.\",\n\t\t\t\t})\n\t\t\t\t.option(\"install\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Install or update the MCP server.\",\n\t\t\t\t})\n\t\t\t\t.option(\"update\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Alias for --install.\",\n\t\t\t\t})\n\t\t\t\t.option(\"scope\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"global\", \"project\"] as const,\n\t\t\t\t\tdefault: \"global\",\n\t\t\t\t\tdescription: \"Where to configure the MCP server.\",\n\t\t\t\t})\n\t\t\t\t.option(\"mcp-configured\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports MCP detection result (true|false).\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tlet mcpConfigured: boolean | null = null;\n\t\t\tif (argv.mcpConfigured === \"true\") mcpConfigured = true;\n\t\t\telse if (argv.mcpConfigured === \"false\") mcpConfigured = false;\n\n\t\t\tconst result = await handleMcpPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\tstatus: argv.status,\n\t\t\t\tinstall: argv.install || argv.update,\n\t\t\t\tscope: argv.scope as \"global\" | \"project\",\n\t\t\t\tmcpConfigured,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// skills\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"skills\",\n\t\t\"Manage Neon agent skills\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"status\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Check if skills are installed.\",\n\t\t\t\t})\n\t\t\t\t.option(\"install\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Install agent skills.\",\n\t\t\t\t})\n\t\t\t\t.option(\"update\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Update agent skills to latest.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleSkillsPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\tstatus: argv.status,\n\t\t\t\tinstall: argv.install,\n\t\t\t\tupdate: argv.update,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// setup (comprehensive inspection + batched install)\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"setup\",\n\t\t\"Inspect project and batch-install Neon tooling (MCP, skills, extension)\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"data\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON object with inspection results and user preferences (replaces individual flags).\",\n\t\t\t\t})\n\t\t\t\t.option(\"mcp-configured\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports MCP detection result (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"connection-string\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports if a connection string was found (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"connection-params\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON with connection parameters found by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"framework\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Framework detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orm\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"ORM detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-tool\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Migration tool detected by agent (prisma|drizzle|knex|none).\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-dir\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration directory detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"is-vscode-ide\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports if user is in a VS Code-based IDE (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"mode\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"defaults\", \"customize\"] as const,\n\t\t\t\t\tdescription: \"Installation mode chosen by user.\",\n\t\t\t\t})\n\t\t\t\t.option(\"mcp-scope\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"global\", \"project\"] as const,\n\t\t\t\t\tdescription: \"Where to install MCP server.\",\n\t\t\t\t})\n\t\t\t\t.option(\"skills-scope\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"global\", \"project\"] as const,\n\t\t\t\t\tdescription: \"Where to install skills.\",\n\t\t\t\t})\n\t\t\t\t.option(\"install-extension\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Whether to install VS Code extension (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"execute\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Execute the batched installation with given options.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\t// --data JSON path: parse and pass directly to handleSetupPhase\n\t\t\tif (argv.data) {\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Invalid JSON in --data flag. Expected a JSON object.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Normalize string booleans from preference answers (e.g. \"true\" → true)\n\t\t\t\tfor (const key of [\n\t\t\t\t\t\"mcpConfigured\",\n\t\t\t\t\t\"connectionString\",\n\t\t\t\t\t\"isVscodeIde\",\n\t\t\t\t\t\"installExtension\",\n\t\t\t\t\t\"execute\",\n\t\t\t\t]) {\n\t\t\t\t\tif (data[key] === \"true\") data[key] = true;\n\t\t\t\t\telse if (data[key] === \"false\") data[key] = false;\n\t\t\t\t}\n\n\t\t\t\tconst result = await handleSetupPhase({\n\t\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\t\t...data,\n\t\t\t\t} as import(\"./lib/phases/setup.js\").SetupPhaseOptions);\n\t\t\t\toutputJson(result);\n\t\t\t\tprocess.exit(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Legacy individual flags path\n\t\t\tlet mcpConfigured: boolean | null = null;\n\t\t\tif (argv.mcpConfigured === \"true\") mcpConfigured = true;\n\t\t\telse if (argv.mcpConfigured === \"false\") mcpConfigured = false;\n\n\t\t\tlet connectionString: boolean | null = null;\n\t\t\tif (argv.connectionString === \"true\") connectionString = true;\n\t\t\telse if (argv.connectionString === \"false\")\n\t\t\t\tconnectionString = false;\n\n\t\t\tlet isVscodeIde: boolean | null = null;\n\t\t\tif (argv.isVscodeIde === \"true\") isVscodeIde = true;\n\t\t\telse if (argv.isVscodeIde === \"false\") isVscodeIde = false;\n\n\t\t\tconst result = await handleSetupPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\tmcpConfigured,\n\t\t\t\tconnectionString,\n\t\t\t\tconnectionParams: argv.connectionParams,\n\t\t\t\tframework: argv.framework,\n\t\t\t\torm: argv.orm,\n\t\t\t\tmigrationTool: argv.migrationTool,\n\t\t\t\tmigrationDir: argv.migrationDir,\n\t\t\t\tisVscodeIde,\n\t\t\t\tmode: argv.mode as \"defaults\" | \"customize\" | undefined,\n\t\t\t\tmcpScope: argv.mcpScope as \"global\" | \"project\" | undefined,\n\t\t\t\tskillsScope: argv.skillsScope as\n\t\t\t\t\t| \"global\"\n\t\t\t\t\t| \"project\"\n\t\t\t\t\t| undefined,\n\t\t\t\tinstallExtension: argv.installExtension === \"true\",\n\t\t\t\texecute: argv.execute,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// getting-started\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"getting-started\",\n\t\t\"Start the Get Started with Neon workflow\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"data\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON object with project context (hasConnectionString, framework, orm, migrationTool, migrationDir).\",\n\t\t\t\t})\n\t\t\t\t.option(\"has-connection-string\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Whether a connection string was found.\",\n\t\t\t\t})\n\t\t\t\t.option(\"framework\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Framework detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orm\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"ORM detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-tool\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration tool in use.\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-dir\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration directory path.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tif (argv.data) {\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\"Invalid JSON in --data flag.\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = await handleGettingStartedPhase({\n\t\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\t\t...data,\n\t\t\t\t} as import(\"./lib/phases/getting-started.js\").GettingStartedPhaseOptions);\n\t\t\t\toutputJson(result);\n\t\t\t\tprocess.exit(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = await handleGettingStartedPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\thasConnectionString: argv.hasConnectionString,\n\t\t\t\tframework: argv.framework,\n\t\t\t\torm: argv.orm,\n\t\t\t\tmigrationTool: argv.migrationTool,\n\t\t\t\tmigrationDir: argv.migrationDir,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// db\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"db\",\n\t\t\"Set up a Neon database project\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"org-id\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Pre-select a Neon organization.\",\n\t\t\t\t})\n\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Pre-select a Neon project.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orgs-result\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON output from neonctl orgs list (agent passes back).\",\n\t\t\t\t})\n\t\t\t\t.option(\"projects-result\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON output from neonctl projects list (agent passes back).\",\n\t\t\t\t})\n\t\t\t\t.option(\"framework\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Framework detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orm\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"ORM detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"error\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Error from a previous step.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleDbPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\torgId: argv.orgId,\n\t\t\t\tprojectId: argv.projectId,\n\t\t\t\torgsResult: argv.orgsResult,\n\t\t\t\tprojectsResult: argv.projectsResult,\n\t\t\t\tframework: argv.framework,\n\t\t\t\torm: argv.orm,\n\t\t\t\terror: argv.error,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// neon-auth\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"neon-auth\",\n\t\t\"Set up Neon Auth (user authentication for your app)\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"setup\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Begin the Neon Auth setup flow.\",\n\t\t\t\t})\n\t\t\t\t.option(\"info\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Return information about Neon Auth without setting it up.\",\n\t\t\t\t})\n\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Neon project ID to configure.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleNeonAuthPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\tsetup: argv.setup,\n\t\t\t\tinfo: argv.info,\n\t\t\t\tprojectId: argv.projectId,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// migrations\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"migrations\",\n\t\t\"Detect and manage database migrations\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"tool\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Migration tool detected by agent (prisma|drizzle|knex|none).\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-dir\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration directory detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"scaffold\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"prisma\", \"drizzle\"] as const,\n\t\t\t\t\tdescription: \"Scaffold a new migration setup.\",\n\t\t\t\t})\n\t\t\t\t.option(\"apply\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Apply pending migrations.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleMigrationsPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t\ttool: argv.tool,\n\t\t\t\tmigrationDir: argv.migrationDir,\n\t\t\t\tscaffold: argv.scaffold as \"prisma\" | \"drizzle\" | undefined,\n\t\t\t\tapply: argv.apply,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// finalize (internal — called at the end of feature chains)\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"finalize\",\n\t\tfalse, // hidden from help\n\t\t(y) => y.options(jsonOption).options(agentOption),\n\t\tasync () => {\n\t\t\tconst { handleCleanup } = await import(\"./lib/phases/cleanup.js\");\n\t\t\tconst result = handleCleanup();\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// status\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"status\",\n\t\t\"Check the status of your Neon setup\",\n\t\t(y) => y.options(jsonOption).options(agentOption),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleStatusPhase({\n\t\t\t\tagent: resolveAgent(argv.agent),\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t.help()\n\t.strict();\n\n// Parse and execute\ncli.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { interactiveInit } from \"./interactive.js\";\nimport { detectAgent } from \"./lib/detect-agent.js\";\nimport { handleAuthPhase } from \"./lib/phases/auth.js\";\nimport { handleDbPhase } from \"./lib/phases/db.js\";\nimport { handleGettingStartedPhase } from \"./lib/phases/getting-started.js\";\nimport { handleMcpPhase } from \"./lib/phases/mcp.js\";\nimport { handleMigrationsPhase } from \"./lib/phases/migrations.js\";\nimport { handleNeonAuthPhase } from \"./lib/phases/neon-auth.js\";\nimport { handleSetupPhase } from \"./lib/phases/setup.js\";\nimport { handleSkillsPhase } from \"./lib/phases/skills.js\";\nimport { handleStatusPhase } from \"./lib/phases/status.js\";\nimport { orchestrate } from \"./v2.js\";\n\n// ---------------------------------------------------------------------------\n// Shared options\n// ---------------------------------------------------------------------------\n\nconst jsonOption = {\n\tjson: {\n\t\ttype: \"boolean\" as const,\n\t\tdefault: false,\n\t\tdescription:\n\t\t\t\"Output structured JSON for agent consumption. Suppresses interactive UI.\",\n\t},\n};\n\nconst agentOption = {\n\tagent: {\n\t\talias: \"a\",\n\t\ttype: \"boolean\" as const,\n\t\tdefault: false,\n\t\tdescription: \"Enable agent/JSON mode (agent type is auto-detected).\",\n\t},\n};\n\n// ---------------------------------------------------------------------------\n// Output helper\n// ---------------------------------------------------------------------------\n\nimport { enrichResponse } from \"./lib/enrich-output.js\";\n\nfunction outputJson(data: unknown): void {\n\tconsole.log(JSON.stringify(enrichResponse(data), null, 2));\n}\n\n/**\n * Resolve the agent ID from the environment.\n */\nfunction resolveAgent(): string | undefined {\n\treturn detectAgent() ?? undefined;\n}\n\n/**\n * Detects if an AI agent is invoking the CLI programmatically.\n *\n * Agent-specific env vars (CLAUDECODE, CODEX, CLINE) are unambiguous.\n * For IDE-based agents (Cursor, VS Code, Windsurf), we require non-TTY\n * stdin to distinguish \"agent spawned this\" from \"human typed this in\n * the IDE's integrated terminal\".\n */\nfunction detectAgentInvocation(): string | null {\n\tconst env = process.env;\n\n\t// Agent-specific env vars (always definitive, regardless of TTY)\n\tif (\n\t\tenv.CLAUDECODE === \"1\" ||\n\t\tenv.CLAUDE_CODE === \"1\" ||\n\t\tenv.CLAUDE_CLI === \"1\"\n\t)\n\t\treturn \"claude-code\";\n\tif (env.CODEX === \"1\") return \"codex\";\n\tif (env.CLINE === \"1\") return \"cline\";\n\n\t// IDE detected + non-interactive stdin = agent spawned us\n\t// (a human typing in the same terminal would have isTTY=true)\n\tif (!process.stdin.isTTY) {\n\t\treturn detectAgent();\n\t}\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// CLI definition\n// ---------------------------------------------------------------------------\n\nconst cli = yargs(hideBin(process.argv))\n\t.scriptName(\"neon-init\")\n\t.usage(\"$0 [command] [options]\")\n\n\t// -----------------------------------------------------------------------\n\t// Default command: orchestrator (v2 json) or v1 interactive\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"$0\",\n\t\t\"Initialize Neon for your project\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"data\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'JSON object with a \"step\" field to route to a specific phase (auth, db, setup, getting-started, mcp, skills, migrations, neon-auth, status, finalize) and phase-specific options.',\n\t\t\t\t})\n\t\t\t\t.option(\"skip-migrations\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Skip the migrations phase.\",\n\t\t\t\t})\n\t\t\t\t.option(\"preview\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Enable preview features (e.g. project bootstrapping from templates).\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst detectedAgent = detectAgentInvocation();\n\t\t\tconst agent = resolveAgent();\n\t\t\tconst jsonMode = argv.json || argv.agent || detectedAgent !== null;\n\n\t\t\t// --data with a \"step\" field routes to the appropriate phase\n\t\t\tif (argv.data && jsonMode) {\n\t\t\t\tconst { routeDataStep } = await import(\n\t\t\t\t\t\"./lib/route-command.js\"\n\t\t\t\t);\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Invalid JSON in --data flag. Expected a JSON object.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (typeof data.step === \"string\") {\n\t\t\t\t\tconst result = await routeDataStep(data, agent);\n\t\t\t\t\toutputJson(result);\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --data with a \"step\" field routes to the appropriate phase\n\t\t\tif (argv.data && jsonMode) {\n\t\t\t\tconst { routeDataStep } = await import(\n\t\t\t\t\t\"./lib/route-command.js\"\n\t\t\t\t);\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Invalid JSON in --data flag. Expected a JSON object.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (typeof data.step === \"string\") {\n\t\t\t\t\tconst result = await routeDataStep(data, agent);\n\t\t\t\t\toutputJson(result);\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (jsonMode) {\n\t\t\t\t// v2: agent-driven state machine\n\t\t\t\tconst result = await orchestrate({\n\t\t\t\t\tagent,\n\t\t\t\t\tskipMigrations: argv.skipMigrations,\n\t\t\t\t\tpreview: argv.preview,\n\t\t\t\t});\n\t\t\t\toutputJson(result);\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\t// v2 interactive mode — same phase logic, driven by terminal prompts\n\t\t\tawait interactiveInit({ preview: argv.preview });\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// auth\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"auth\",\n\t\t\"Manage Neon platform authentication\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"method\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"existing\", \"new\"] as const,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Auth method: \"existing\" for OAuth sign-in, \"new\" for sign-up flow.',\n\t\t\t\t})\n\t\t\t\t.option(\"verify\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Just check if authentication is valid, don't initiate a flow.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleAuthPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\tmethod: argv.method as \"existing\" | \"new\" | undefined,\n\t\t\t\tverify: argv.verify,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// mcp\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"mcp\",\n\t\t\"Manage the Neon MCP server\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"status\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Check if the MCP server is configured.\",\n\t\t\t\t})\n\t\t\t\t.option(\"install\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Install or update the MCP server.\",\n\t\t\t\t})\n\t\t\t\t.option(\"update\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Alias for --install.\",\n\t\t\t\t})\n\t\t\t\t.option(\"scope\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"global\", \"project\"] as const,\n\t\t\t\t\tdefault: \"global\",\n\t\t\t\t\tdescription: \"Where to configure the MCP server.\",\n\t\t\t\t})\n\t\t\t\t.option(\"mcp-configured\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports MCP detection result (true|false).\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tlet mcpConfigured: boolean | null = null;\n\t\t\tif (argv.mcpConfigured === \"true\") mcpConfigured = true;\n\t\t\telse if (argv.mcpConfigured === \"false\") mcpConfigured = false;\n\n\t\t\tconst result = await handleMcpPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\tstatus: argv.status,\n\t\t\t\tinstall: argv.install || argv.update,\n\t\t\t\tscope: argv.scope as \"global\" | \"project\",\n\t\t\t\tmcpConfigured,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// skills\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"skills\",\n\t\t\"Manage Neon agent skills\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"status\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Check if skills are installed.\",\n\t\t\t\t})\n\t\t\t\t.option(\"install\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Install agent skills.\",\n\t\t\t\t})\n\t\t\t\t.option(\"update\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Update agent skills to latest.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleSkillsPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\tstatus: argv.status,\n\t\t\t\tinstall: argv.install,\n\t\t\t\tupdate: argv.update,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// setup (comprehensive inspection + batched install)\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"setup\",\n\t\t\"Inspect project and batch-install Neon tooling (MCP, skills, extension)\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"data\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON object with inspection results and user preferences (replaces individual flags).\",\n\t\t\t\t})\n\t\t\t\t.option(\"mcp-configured\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports MCP detection result (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"connection-string\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports if a connection string was found (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"connection-params\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON with connection parameters found by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"framework\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Framework detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orm\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"ORM detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-tool\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Migration tool detected by agent (prisma|drizzle|knex|none).\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-dir\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration directory detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"is-vscode-ide\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Agent reports if user is in a VS Code-based IDE (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"mode\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"defaults\", \"customize\"] as const,\n\t\t\t\t\tdescription: \"Installation mode chosen by user.\",\n\t\t\t\t})\n\t\t\t\t.option(\"mcp-scope\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"global\", \"project\"] as const,\n\t\t\t\t\tdescription: \"Where to install MCP server.\",\n\t\t\t\t})\n\t\t\t\t.option(\"skills-scope\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"global\", \"project\"] as const,\n\t\t\t\t\tdescription: \"Where to install skills.\",\n\t\t\t\t})\n\t\t\t\t.option(\"install-extension\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Whether to install VS Code extension (true|false).\",\n\t\t\t\t})\n\t\t\t\t.option(\"execute\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Execute the batched installation with given options.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\t// --data JSON path: parse and pass directly to handleSetupPhase\n\t\t\tif (argv.data) {\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Invalid JSON in --data flag. Expected a JSON object.\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Normalize string booleans from preference answers (e.g. \"true\" → true)\n\t\t\t\tfor (const key of [\n\t\t\t\t\t\"mcpConfigured\",\n\t\t\t\t\t\"connectionString\",\n\t\t\t\t\t\"isVscodeIde\",\n\t\t\t\t\t\"installExtension\",\n\t\t\t\t\t\"execute\",\n\t\t\t\t]) {\n\t\t\t\t\tif (data[key] === \"true\") data[key] = true;\n\t\t\t\t\telse if (data[key] === \"false\") data[key] = false;\n\t\t\t\t}\n\n\t\t\t\tconst result = await handleSetupPhase({\n\t\t\t\t\tagent: resolveAgent(),\n\t\t\t\t\t...data,\n\t\t\t\t} as import(\"./lib/phases/setup.js\").SetupPhaseOptions);\n\t\t\t\toutputJson(result);\n\t\t\t\tprocess.exit(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Legacy individual flags path\n\t\t\tlet mcpConfigured: boolean | null = null;\n\t\t\tif (argv.mcpConfigured === \"true\") mcpConfigured = true;\n\t\t\telse if (argv.mcpConfigured === \"false\") mcpConfigured = false;\n\n\t\t\tlet connectionString: boolean | null = null;\n\t\t\tif (argv.connectionString === \"true\") connectionString = true;\n\t\t\telse if (argv.connectionString === \"false\")\n\t\t\t\tconnectionString = false;\n\n\t\t\tlet isVscodeIde: boolean | null = null;\n\t\t\tif (argv.isVscodeIde === \"true\") isVscodeIde = true;\n\t\t\telse if (argv.isVscodeIde === \"false\") isVscodeIde = false;\n\n\t\t\tconst result = await handleSetupPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\tmcpConfigured,\n\t\t\t\tconnectionString,\n\t\t\t\tconnectionParams: argv.connectionParams,\n\t\t\t\tframework: argv.framework,\n\t\t\t\torm: argv.orm,\n\t\t\t\tmigrationTool: argv.migrationTool,\n\t\t\t\tmigrationDir: argv.migrationDir,\n\t\t\t\tisVscodeIde,\n\t\t\t\tmode: argv.mode as \"defaults\" | \"customize\" | undefined,\n\t\t\t\tmcpScope: argv.mcpScope as \"global\" | \"project\" | undefined,\n\t\t\t\tskillsScope: argv.skillsScope as\n\t\t\t\t\t| \"global\"\n\t\t\t\t\t| \"project\"\n\t\t\t\t\t| undefined,\n\t\t\t\tinstallExtension: argv.installExtension === \"true\",\n\t\t\t\texecute: argv.execute,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// getting-started\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"getting-started\",\n\t\t\"Start the Get Started with Neon workflow\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"data\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON object with project context (hasConnectionString, framework, orm, migrationTool, migrationDir).\",\n\t\t\t\t})\n\t\t\t\t.option(\"has-connection-string\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Whether a connection string was found.\",\n\t\t\t\t})\n\t\t\t\t.option(\"framework\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Framework detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orm\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"ORM detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-tool\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration tool in use.\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-dir\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration directory path.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tif (argv.data) {\n\t\t\t\tlet data: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(argv.data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\"Invalid JSON in --data flag.\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = await handleGettingStartedPhase({\n\t\t\t\t\tagent: resolveAgent(),\n\t\t\t\t\t...data,\n\t\t\t\t} as import(\"./lib/phases/getting-started.js\").GettingStartedPhaseOptions);\n\t\t\t\toutputJson(result);\n\t\t\t\tprocess.exit(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = await handleGettingStartedPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\thasConnectionString: argv.hasConnectionString,\n\t\t\t\tframework: argv.framework,\n\t\t\t\torm: argv.orm,\n\t\t\t\tmigrationTool: argv.migrationTool,\n\t\t\t\tmigrationDir: argv.migrationDir,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// db\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"db\",\n\t\t\"Set up a Neon database project\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"org-id\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Pre-select a Neon organization.\",\n\t\t\t\t})\n\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Pre-select a Neon project.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orgs-result\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON output from neonctl orgs list (agent passes back).\",\n\t\t\t\t})\n\t\t\t\t.option(\"projects-result\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"JSON output from neonctl projects list (agent passes back).\",\n\t\t\t\t})\n\t\t\t\t.option(\"framework\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Framework detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"orm\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"ORM detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"error\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Error from a previous step.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleDbPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\torgId: argv.orgId,\n\t\t\t\tprojectId: argv.projectId,\n\t\t\t\torgsResult: argv.orgsResult,\n\t\t\t\tprojectsResult: argv.projectsResult,\n\t\t\t\tframework: argv.framework,\n\t\t\t\torm: argv.orm,\n\t\t\t\terror: argv.error,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// neon-auth\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"neon-auth\",\n\t\t\"Set up Neon Auth (user authentication for your app)\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"setup\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Begin the Neon Auth setup flow.\",\n\t\t\t\t})\n\t\t\t\t.option(\"info\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Return information about Neon Auth without setting it up.\",\n\t\t\t\t})\n\t\t\t\t.option(\"project-id\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Neon project ID to configure.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleNeonAuthPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\tsetup: argv.setup,\n\t\t\t\tinfo: argv.info,\n\t\t\t\tprojectId: argv.projectId,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// migrations\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"migrations\",\n\t\t\"Detect and manage database migrations\",\n\t\t(y) =>\n\t\t\ty\n\t\t\t\t.options(jsonOption)\n\t\t\t\t.options(agentOption)\n\t\t\t\t.option(\"tool\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Migration tool detected by agent (prisma|drizzle|knex|none).\",\n\t\t\t\t})\n\t\t\t\t.option(\"migration-dir\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Migration directory detected by agent.\",\n\t\t\t\t})\n\t\t\t\t.option(\"scaffold\", {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tchoices: [\"prisma\", \"drizzle\"] as const,\n\t\t\t\t\tdescription: \"Scaffold a new migration setup.\",\n\t\t\t\t})\n\t\t\t\t.option(\"apply\", {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\tdefault: false,\n\t\t\t\t\tdescription: \"Apply pending migrations.\",\n\t\t\t\t}),\n\t\tasync (argv) => {\n\t\t\tconst result = await handleMigrationsPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t\ttool: argv.tool,\n\t\t\t\tmigrationDir: argv.migrationDir,\n\t\t\t\tscaffold: argv.scaffold as \"prisma\" | \"drizzle\" | undefined,\n\t\t\t\tapply: argv.apply,\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// finalize (internal — called at the end of feature chains)\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"finalize\",\n\t\tfalse, // hidden from help\n\t\t(y) => y.options(jsonOption).options(agentOption),\n\t\tasync () => {\n\t\t\tconst { handleCleanup } = await import(\"./lib/phases/cleanup.js\");\n\t\t\tconst result = handleCleanup();\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t// -----------------------------------------------------------------------\n\t// status\n\t// -----------------------------------------------------------------------\n\t.command(\n\t\t\"status\",\n\t\t\"Check the status of your Neon setup\",\n\t\t(y) => y.options(jsonOption).options(agentOption),\n\t\tasync (_argv) => {\n\t\t\tconst result = await handleStatusPhase({\n\t\t\t\tagent: resolveAgent(),\n\t\t\t});\n\t\t\toutputJson(result);\n\t\t\tprocess.exit(0);\n\t\t},\n\t)\n\n\t.help()\n\t.strict();\n\n// Parse and execute\ncli.parse();\n"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { ALL_CONFIGURABLE_AGENTS, getAddMcpAgentId } from "./lib/agents.js";
2
2
  import { ensureNeonctlAuth, isAuthenticated } from "./lib/auth.js";
3
3
  import { FALLBACK_TEMPLATES, fetchTemplates } from "./lib/bootstrap.js";
4
- import { detectAgent } from "./lib/detect-agent.js";
4
+ import { detectAgent, detectIde } from "./lib/detect-agent.js";
5
5
  import { detectAvailableEditors } from "./lib/editors.js";
6
6
  import { installExtension, isExtensionInstalled, usesExtension } from "./lib/extension.js";
7
7
  import { inspectProject } from "./lib/inspect.js";
8
8
  import { ensureNeonctl } from "./lib/neonctl.js";
9
- import { installAgentSkills } from "./lib/skills.js";
9
+ import { ensureSkillsUpToDate, installAgentSkills } from "./lib/skills.js";
10
10
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
11
11
  import { resolve } from "node:path";
12
12
  import { confirm, isCancel, log, multiselect, outro, select, spinner } from "@clack/prompts";
@@ -214,8 +214,8 @@ async function interactiveInitInner(options) {
214
214
  let extensionAlready = false;
215
215
  if (detectedEditor && usesExtension(detectedEditor)) extensionAlready = await isExtensionInstalled(detectedEditor);
216
216
  if (mcpAlready && skillsAlready && hasNeonConnection && hasNeonContext) {
217
- log.step(dim("Neon MCP server already configured "));
218
- log.step(dim("Neon agent skills already installed "));
217
+ log.step(dim(`Neon MCP server already configured (${inspection.mcpScope || "detected"}) ✓`));
218
+ log.step(dim(`Neon agent skills already installed (${inspection.skillsScope || "detected"}) ✓`));
219
219
  if (extensionAlready) log.step(dim("Neon editor extension installed ✓"));
220
220
  log.step(dim("Neon database connected ✓"));
221
221
  if (hasNeonAuth) {
@@ -235,7 +235,7 @@ async function interactiveInitInner(options) {
235
235
  initialValue: "no"
236
236
  });
237
237
  if (isCancel(authResult) || authResult === "no") {
238
- outro(dim(`Your project is configured with Neon. You can set up Neon Auth later by having your agent run: neonctl init --agent --json --data '{"step":"neon-auth"}'`));
238
+ outro(dim(`Your project is configured with Neon. You can set up Neon Auth later by having your agent run: neonctl init --agent --data '{"step":"neon-auth"}'`));
239
239
  return;
240
240
  }
241
241
  let projectId = null;
@@ -250,8 +250,8 @@ async function interactiveInitInner(options) {
250
250
  outro(dim("Have feedback? Email us at feedback@neon.tech"));
251
251
  return;
252
252
  }
253
- if (mcpAlready) log.step(dim("Neon MCP server already configured "));
254
- if (skillsAlready) log.step(dim("Neon agent skills already installed "));
253
+ if (mcpAlready) log.step(dim(`Neon MCP server already configured (${inspection.mcpScope || "detected"}) ✓`));
254
+ if (skillsAlready) log.step(dim(`Neon agent skills already installed (${inspection.skillsScope || "detected"}) ✓`));
255
255
  if (needsInstall) {
256
256
  const homeDir = process.env.HOME || process.env.USERPROFILE;
257
257
  if (!homeDir) {
@@ -457,7 +457,10 @@ async function interactiveInitInner(options) {
457
457
  log.error(msg);
458
458
  }
459
459
  }
460
- if (needsSkills) await installAgentSkills([editor], { scope: skillsScope });
460
+ if (needsSkills) await installAgentSkills([editor], {
461
+ scope: skillsScope,
462
+ preview: options.preview
463
+ });
461
464
  if (doInstallExtension && usesExtension(editor)) {
462
465
  const extS = spinner();
463
466
  extS.start(`Installing Neon extension for ${editor}...`);
@@ -466,6 +469,9 @@ async function interactiveInitInner(options) {
466
469
  }
467
470
  }
468
471
  }
472
+ const ide = detectIde();
473
+ const agentForSkills = detectAgent() ?? (ide === "Cursor" ? "cursor" : ide === "VS Code" ? "vscode" : ide === "Windsurf" ? "windsurf" : null);
474
+ if (agentForSkills) await ensureSkillsUpToDate(agentForSkills, inspection.skillsScope === "global" ? "global" : void 0, options.preview);
469
475
  const gettingStartedData = {};
470
476
  if (hasNeonConnection) gettingStartedData.hasConnectionString = true;
471
477
  if (inspection.framework && inspection.framework !== "none") gettingStartedData.framework = inspection.framework;
@@ -474,7 +480,7 @@ async function interactiveInitInner(options) {
474
480
  if (inspection.migrationDir && inspection.migrationDir !== "none") gettingStartedData.migrationDir = inspection.migrationDir;
475
481
  if (selectedFeatures.length > 0) gettingStartedData.features = selectedFeatures;
476
482
  if (options.preview) gettingStartedData.preview = true;
477
- const cmd = `neonctl init --agent --json --data '${JSON.stringify({
483
+ const cmd = `neonctl init --agent --data '${JSON.stringify({
478
484
  step: "getting-started",
479
485
  ...gettingStartedData
480
486
  })}'`;
@@ -1 +1 @@
1
- {"version":3,"file":"interactive.js","names":[],"sources":["../src/interactive.ts"],"sourcesContent":["/**\n * Interactive v2 CLI — purpose-built guided flow for humans.\n * Uses the same underlying install functions but with a clean clack-based UX.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport {\n\tconfirm,\n\tisCancel,\n\tlog,\n\tmultiselect,\n\toutro,\n\tselect,\n\tspinner,\n} from \"@clack/prompts\";\nimport { execa } from \"execa\";\nimport { bold, dim } from \"yoctocolors\";\nimport { ALL_CONFIGURABLE_AGENTS, getAddMcpAgentId } from \"./lib/agents.js\";\nimport { ensureNeonctlAuth, isAuthenticated } from \"./lib/auth.js\";\nimport {\n\ttype BootstrapTemplate,\n\tFALLBACK_TEMPLATES,\n\tfetchTemplates,\n\ttype NeonFeature,\n} from \"./lib/bootstrap.js\";\nimport { detectAgent } from \"./lib/detect-agent.js\";\nimport { detectAvailableEditors } from \"./lib/editors.js\";\nimport {\n\tinstallExtension,\n\tisExtensionInstalled,\n\tusesExtension,\n} from \"./lib/extension.js\";\nimport { inspectProject } from \"./lib/inspect.js\";\nimport { ensureNeonctl } from \"./lib/neonctl.js\";\nimport { installAgentSkills } from \"./lib/skills.js\";\nimport type { Editor } from \"./lib/types.js\";\n\nfunction wordWrap(text: string, width: number): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => {\n\t\t\tif (line.length <= width) return line;\n\t\t\tconst words = line.split(\" \");\n\t\t\tconst lines: string[] = [];\n\t\t\tlet current = \"\";\n\t\t\tfor (const word of words) {\n\t\t\t\tif (\n\t\t\t\t\tcurrent.length + word.length + 1 > width &&\n\t\t\t\t\tcurrent.length > 0\n\t\t\t\t) {\n\t\t\t\t\tlines.push(current);\n\t\t\t\t\tcurrent = word;\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = current.length > 0 ? `${current} ${word}` : word;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (current.length > 0) lines.push(current);\n\t\t\treturn lines.join(\"\\n\");\n\t\t})\n\t\t.join(\"\\n\");\n}\n\n// Patch picocolors (used by @clack/prompts) to use Neon green instead of cyan/magenta.\n// clack hardcodes picocolors.cyan() with no theme API, so this is the least invasive override.\nimport picocolors from \"picocolors\";\n\nconst neonGreenFn = (s: string) => `\\x1b[38;2;75;181;120m${s}\\x1b[39m`;\nconst originalCyan = picocolors.cyan;\nconst originalMagenta = picocolors.magenta;\n\nfunction patchClackColors(): () => void {\n\tconst pc = picocolors as unknown as Record<string, unknown>;\n\tpc.cyan = neonGreenFn;\n\tpc.magenta = neonGreenFn;\n\treturn () => {\n\t\tpc.cyan = originalCyan;\n\t\tpc.magenta = originalMagenta;\n\t};\n}\n\nexport interface InteractiveInitOptions {\n\tpreview?: boolean;\n}\n\nexport async function interactiveInit(\n\toptions: InteractiveInitOptions = {},\n): Promise<void> {\n\tconst restoreColors = patchClackColors();\n\ttry {\n\t\tawait interactiveInitInner(options);\n\t} finally {\n\t\trestoreColors();\n\t}\n}\n\nasync function interactiveInitInner(\n\toptions: InteractiveInitOptions,\n): Promise<void> {\n\tconsole.log();\n\tconsole.log(\n\t\t\"\\x1b[38;2;75;181;120m\" +\n\t\t\t[\n\t\t\t\t\" ██╗ ██╗██████╗ ██████╗ ██╗ ██╗\",\n\t\t\t\t\" ███╗ ██║██╔═══╝ ██╔═══██╗███╗ ██║\",\n\t\t\t\t\" ████╗██║██████╗ ██║ ██║████╗██║\",\n\t\t\t\t\" ██╔████║██╔═══╝ ██║ ██║██╔████║\",\n\t\t\t\t\" ██║╚███║██████╗ ╚██████╔╝██║╚███║\",\n\t\t\t\t\" ╚═╝ ╚══╝╚═════╝ ╚═════╝ ╚═╝ ╚══╝\",\n\t\t\t].join(\"\\n\") +\n\t\t\t\"\\x1b[0m\",\n\t);\n\tconsole.log(\n\t\tdim(\n\t\t\twordWrap(\n\t\t\t\t\"\\nLet's get your project set up with Neon. We'll install the MCP server, agent skills, and IDE extension, then connect your app to a database.\\n\",\n\t\t\t\tprocess.stdout.columns || 80,\n\t\t\t),\n\t\t),\n\t);\n\n\tconst detectedAgentId = detectAgent();\n\tconst detectedEditor = detectedAgentId\n\t\t? agentIdToEditor(detectedAgentId)\n\t\t: null;\n\n\t// -----------------------------------------------------------------------\n\t// Step 1: Inspect what's already in place\n\t// -----------------------------------------------------------------------\n\tconst inspectSpinner = spinner();\n\tinspectSpinner.start(\"Checking existing configuration...\");\n\tconst inspection = await inspectProject([\n\t\t{ id: \"has_app\", description: \"\", lookFor: [] },\n\t\t{ id: \"mcp_server\", description: \"\", lookFor: [] },\n\t\t{ id: \"skills\", description: \"\", lookFor: [] },\n\t\t{ id: \"connection_string\", description: \"\", lookFor: [] },\n\t\t{ id: \"project_stack\", description: \"\", lookFor: [] },\n\t\t{ id: \"migrations\", description: \"\", lookFor: [] },\n\t\t{ id: \"ide_type\", description: \"\", lookFor: [] },\n\t]);\n\tinspectSpinner.stop(dim(\"Configuration checked ✓\"));\n\n\tconst hasApp = inspection.hasApp === true;\n\tlet selectedFeatures: NeonFeature[] = [];\n\tlet selectedTemplate: BootstrapTemplate | null = null;\n\n\t// Preview mode: bootstrap from template if no app detected\n\tif (options.preview && !hasApp) {\n\t\tlet templates = FALLBACK_TEMPLATES;\n\t\ttry {\n\t\t\tconst fetched = await fetchTemplates();\n\t\t\tif (fetched && fetched.length > 0) templates = fetched;\n\t\t} catch {}\n\n\t\tconst templateResult = await select({\n\t\t\tmessage:\n\t\t\t\t\"No application detected. Would you like to scaffold a new project from a template?\",\n\t\t\toptions: [\n\t\t\t\t...templates.map((t) => ({\n\t\t\t\t\tvalue: t.id,\n\t\t\t\t\tlabel: t.title,\n\t\t\t\t\thint: t.description,\n\t\t\t\t})),\n\t\t\t\t{\n\t\t\t\t\tvalue: \"none\",\n\t\t\t\t\tlabel: \"No thanks — continue without scaffolding\",\n\t\t\t\t},\n\t\t\t],\n\t\t\tinitialValue: templates[0]?.id ?? \"none\",\n\t\t});\n\t\tif (isCancel(templateResult)) {\n\t\t\toutro(\"Setup cancelled.\");\n\t\t\treturn;\n\t\t}\n\t\tif (templateResult !== \"none\") {\n\t\t\tselectedTemplate =\n\t\t\t\ttemplates.find((t) => t.id === templateResult) ?? null;\n\t\t\tif (selectedTemplate) {\n\t\t\t\tselectedFeatures = selectedTemplate.requires;\n\t\t\t\tconst bootstrapS = spinner();\n\t\t\t\tbootstrapS.start(\n\t\t\t\t\t`Scaffolding project from template \"${selectedTemplate.title}\"...`,\n\t\t\t\t);\n\t\t\t\ttry {\n\t\t\t\t\t// Pin @latest (and -y) so a stale globally-installed neonctl\n\t\t\t\t\t// can't be picked up by npx — bootstrap's rate-limit fix lives\n\t\t\t\t\t// in recent neonctl.\n\t\t\t\t\tawait execa(\n\t\t\t\t\t\t\"npx\",\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"-y\",\n\t\t\t\t\t\t\t\"neonctl@latest\",\n\t\t\t\t\t\t\t\"bootstrap\",\n\t\t\t\t\t\t\t\".\",\n\t\t\t\t\t\t\t\"--template\",\n\t\t\t\t\t\t\tselectedTemplate.id,\n\t\t\t\t\t\t\t\"--force\",\n\t\t\t\t\t\t],\n\t\t\t\t\t\t{ stdio: \"pipe\", timeout: 120000 },\n\t\t\t\t\t);\n\t\t\t\t\tbootstrapS.stop(\n\t\t\t\t\t\tdim(\n\t\t\t\t\t\t\t`Scaffolded project from \"${selectedTemplate.title}\" ✓`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst msg =\n\t\t\t\t\t\terr instanceof Error ? err.message : \"Unknown error\";\n\t\t\t\t\tbootstrapS.stop(\"Failed to scaffold project\");\n\t\t\t\t\tlog.error(msg);\n\t\t\t\t\toutro(\"Setup failed.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// For brownfield flows (existing app), ask which features to enable\n\tif (!selectedTemplate && hasApp) {\n\t\tconst featuresResult = await select({\n\t\t\tmessage:\n\t\t\t\t\"Which Neon features would you like to enable for this project?\",\n\t\t\toptions: [\n\t\t\t\t{ value: \"database\", label: \"Database\" },\n\t\t\t\t{\n\t\t\t\t\tvalue: \"database,auth\",\n\t\t\t\t\tlabel: \"Database + Neon Auth (adds authentication via Neon)\",\n\t\t\t\t},\n\t\t\t],\n\t\t\tinitialValue: \"database\",\n\t\t});\n\t\tif (isCancel(featuresResult)) {\n\t\t\toutro(\"Setup cancelled.\");\n\t\t\treturn;\n\t\t}\n\t\tselectedFeatures = (featuresResult as string).split(\n\t\t\t\",\",\n\t\t) as NeonFeature[];\n\t}\n\n\t// Write _init metadata to .neon\n\tif (selectedFeatures.length > 0) {\n\t\tconst neonPath = resolve(process.cwd(), \".neon\");\n\t\tlet existing: Record<string, unknown> = {};\n\t\tif (existsSync(neonPath)) {\n\t\t\ttry {\n\t\t\t\texisting = JSON.parse(readFileSync(neonPath, \"utf-8\"));\n\t\t\t} catch {}\n\t\t}\n\t\texisting._init = { features: selectedFeatures };\n\t\twriteFileSync(neonPath, `${JSON.stringify(existing, null, 2)}\\n`);\n\t}\n\n\tconst mcpAlready = inspection.mcpConfigured === true;\n\t// If we bootstrapped, skills come from the template\n\tconst skillsAlready =\n\t\tinspection.skillsInstalled === true || selectedTemplate !== null;\n\tconst hasNeonConnection = inspection.connectionString === true;\n\tlet needsMcp = !mcpAlready;\n\tconst needsSkills = !skillsAlready;\n\tconst needsInstall = needsMcp || needsSkills;\n\n\t// Check if .neon context file exists\n\tconst neonContextPath = resolve(process.cwd(), \".neon\");\n\tconst hasNeonContext =\n\t\texistsSync(neonContextPath) &&\n\t\t(() => {\n\t\t\ttry {\n\t\t\t\tconst content = JSON.parse(\n\t\t\t\t\treadFileSync(neonContextPath, \"utf-8\"),\n\t\t\t\t);\n\t\t\t\treturn !!content.projectId;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t})();\n\n\t// Check if Neon Auth is configured\n\tconst hasNeonAuth = (() => {\n\t\tfor (const envFile of [\".env\", \".env.local\"]) {\n\t\t\tconst envPath = resolve(process.cwd(), envFile);\n\t\t\tif (existsSync(envPath)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst content = readFileSync(envPath, \"utf-8\");\n\t\t\t\t\tif (/^NEON_AUTH_/m.test(content)) return true;\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t})();\n\n\t// Check if extension is installed for the detected editor\n\tlet extensionAlready = false;\n\tif (detectedEditor && usesExtension(detectedEditor)) {\n\t\textensionAlready = await isExtensionInstalled(detectedEditor);\n\t}\n\n\t// If tooling + database are configured, check if there's anything left to do\n\tif (mcpAlready && skillsAlready && hasNeonConnection && hasNeonContext) {\n\t\tlog.step(dim(\"Neon MCP server already configured ✓\"));\n\t\tlog.step(dim(\"Neon agent skills already installed ✓\"));\n\t\tif (extensionAlready)\n\t\t\tlog.step(dim(\"Neon editor extension installed ✓\"));\n\t\tlog.step(dim(\"Neon database connected ✓\"));\n\n\t\tif (hasNeonAuth) {\n\t\t\tlog.step(dim(\"Neon Auth configured ✓\"));\n\t\t\toutro(\n\t\t\t\tdim(\n\t\t\t\t\t\"Your project is fully configured with Neon. Nothing to do.\",\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Neon Auth not configured — ask if they want it\n\t\tconst authResult = await select({\n\t\t\tmessage:\n\t\t\t\t\"Would you like to set up Neon Auth for user authentication?\",\n\t\t\toptions: [\n\t\t\t\t{ value: \"yes\", label: \"Yes, set up Neon Auth\" },\n\t\t\t\t{ value: \"no\", label: \"No, skip for now\" },\n\t\t\t],\n\t\t\tinitialValue: \"no\",\n\t\t});\n\n\t\tif (isCancel(authResult) || authResult === \"no\") {\n\t\t\toutro(\n\t\t\t\tdim(\n\t\t\t\t\t`Your project is configured with Neon. You can set up Neon Auth later by having your agent run: neonctl init --agent --json --data '{\"step\":\"neon-auth\"}'`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Read .neon for project context\n\t\tlet projectId: string | null = null;\n\t\ttry {\n\t\t\tconst neonCtx = JSON.parse(readFileSync(neonContextPath, \"utf-8\"));\n\t\t\tprojectId = neonCtx.projectId ?? null;\n\t\t} catch {}\n\n\t\tlog.step(\"Next steps\");\n\t\tconst promptLines = [\"Set up Neon Auth for this project.\"];\n\t\tif (projectId) promptLines.push(`Project ID: ${projectId}.`);\n\t\tlog.message(dim(\"Copy the following into your agent chat:\"));\n\t\tlog.message(\n\t\t\tpromptLines.map((line) => bold(neonGreenFn(line))).join(\"\\n\"),\n\t\t);\n\t\toutro(dim(\"Have feedback? Email us at feedback@neon.tech\"));\n\t\treturn;\n\t}\n\n\t// Log what's already in place\n\tif (mcpAlready) log.step(dim(\"Neon MCP server already configured ✓\"));\n\tif (skillsAlready) log.step(dim(\"Neon agent skills already installed ✓\"));\n\n\t// -----------------------------------------------------------------------\n\t// Step 3–5: Install what's missing (skip entirely if everything is configured)\n\t// -----------------------------------------------------------------------\n\tif (needsInstall) {\n\t\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\t\tif (!homeDir) {\n\t\t\tlog.error(\"Could not determine home directory.\");\n\t\t\toutro(\"Setup failed.\");\n\t\t\treturn;\n\t\t}\n\n\t\tlet selectedEditors: Editor[];\n\t\tif (detectedEditor) {\n\t\t\tselectedEditors = [detectedEditor];\n\t\t} else {\n\t\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\t\t\tconst editorResponse = await multiselect({\n\t\t\t\tmessage: \"Which editor(s) would you like to configure?\",\n\t\t\t\toptions: ALL_CONFIGURABLE_AGENTS.map((agent) => ({\n\t\t\t\t\tvalue: agent.editor,\n\t\t\t\t\tlabel: agent.editor,\n\t\t\t\t\thint: agent.hint,\n\t\t\t\t})),\n\t\t\t\tinitialValues: availableEditors,\n\t\t\t\trequired: true,\n\t\t\t});\n\t\t\tif (isCancel(editorResponse)) {\n\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tselectedEditors = editorResponse as Editor[];\n\t\t\tif (selectedEditors.length === 0) {\n\t\t\t\tlog.warn(\"No editors selected.\");\n\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Check extension status\n\t\tconst vscodeEditors = selectedEditors.filter(usesExtension);\n\t\tlet extensionAlreadyInstalled = false;\n\t\tif (vscodeEditors.length > 0) {\n\t\t\tconst checks = await Promise.all(\n\t\t\t\tvscodeEditors.map((e) => isExtensionInstalled(e)),\n\t\t\t);\n\t\t\textensionAlreadyInstalled = checks.every(Boolean);\n\t\t\tif (extensionAlreadyInstalled) {\n\t\t\t\tlog.step(dim(\"Neon editor extension already installed ✓\"));\n\t\t\t}\n\t\t}\n\t\tlet doInstallExtension =\n\t\t\tvscodeEditors.length > 0 && !extensionAlreadyInstalled;\n\n\t\t// Build hint showing only what needs installing\n\t\tconst hintParts: string[] = [];\n\t\tif (needsMcp) hintParts.push(\"MCP server (global)\");\n\t\tif (needsSkills) hintParts.push(\"agent skills (project)\");\n\t\tif (doInstallExtension) hintParts.push(\"editor extension\");\n\n\t\t// Installation preferences\n\t\tlet mcpScope: \"global\" | \"project\" | \"none\" = \"global\";\n\t\tlet skillsScope: \"global\" | \"project\" = \"project\";\n\n\t\tlet modeResult: string;\n\t\twhile (true) {\n\t\t\tconst editorName = selectedEditors.join(\", \");\n\t\t\tconst result = await select({\n\t\t\t\tmessage: `Configure ${editorName} for Neon:`,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: \"defaults\",\n\t\t\t\t\t\tlabel: \"Install with defaults\",\n\t\t\t\t\t\thint: hintParts.join(\", \"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: \"customize\",\n\t\t\t\t\t\tlabel: \"Customize installation\",\n\t\t\t\t\t\thint: \"choose scopes and options\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: \"change_editor\",\n\t\t\t\t\t\tlabel: \"Configure a different editor\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tinitialValue: \"defaults\",\n\t\t\t});\n\n\t\t\tif (isCancel(result)) {\n\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (result === \"change_editor\") {\n\t\t\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\t\t\t\tconst editorResponse = await multiselect({\n\t\t\t\t\tmessage: \"Which editor(s) would you like to configure?\",\n\t\t\t\t\toptions: ALL_CONFIGURABLE_AGENTS.map((agent) => ({\n\t\t\t\t\t\tvalue: agent.editor,\n\t\t\t\t\t\tlabel: agent.editor,\n\t\t\t\t\t\thint: agent.hint,\n\t\t\t\t\t})),\n\t\t\t\t\tinitialValues: availableEditors,\n\t\t\t\t\trequired: true,\n\t\t\t\t});\n\t\t\t\tif (isCancel(editorResponse)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tselectedEditors = editorResponse as Editor[];\n\t\t\t\tif (selectedEditors.length === 0) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmodeResult = result as string;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (modeResult === \"customize\") {\n\t\t\tif (needsMcp) {\n\t\t\t\tconst scopeResult = await select({\n\t\t\t\t\tmessage: \"Where should the Neon MCP server be configured?\",\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"global\",\n\t\t\t\t\t\t\tlabel: \"Global (available in all projects)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"project\",\n\t\t\t\t\t\t\tlabel: \"Project-level (this project only)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"none\",\n\t\t\t\t\t\t\tlabel: \"Skip — do not install the MCP server\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t\tif (isCancel(scopeResult)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmcpScope = scopeResult as \"global\" | \"project\" | \"none\";\n\t\t\t\tif (mcpScope === \"none\") needsMcp = false;\n\t\t\t}\n\n\t\t\tif (needsSkills) {\n\t\t\t\tconst skillsScopeResult = await select({\n\t\t\t\t\tmessage: \"Where should Neon agent skills be installed?\",\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"global\",\n\t\t\t\t\t\t\tlabel: \"Global (available in all projects)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"project\",\n\t\t\t\t\t\t\tlabel: \"Project-level (this project only)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tinitialValue: \"project\",\n\t\t\t\t});\n\t\t\t\tif (isCancel(skillsScopeResult)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tskillsScope = skillsScopeResult as \"global\" | \"project\";\n\t\t\t}\n\n\t\t\tif (doInstallExtension) {\n\t\t\t\tconst extResult = await confirm({\n\t\t\t\t\tmessage: `Install the Neon extension for ${vscodeEditors.join(\", \")}?`,\n\t\t\t\t});\n\t\t\t\tif (isCancel(extResult)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tdoInstallExtension = extResult;\n\t\t\t}\n\t\t}\n\n\t\t// Auth check before install\n\t\tconst installAuthed = await isAuthenticated();\n\t\tif (!installAuthed) {\n\t\t\tconst authS = spinner();\n\t\t\tauthS.start(\"Authenticating with Neon...\");\n\t\t\tconst authSuccess = await ensureNeonctlAuth();\n\t\t\tif (!authSuccess) {\n\t\t\t\tauthS.stop(\"Authentication failed.\");\n\t\t\t\toutro(\"Run neon-init again after signing in.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauthS.stop(\"Authenticated.\");\n\t\t}\n\n\t\t// Ensure neonctl CLI is installed and up to date\n\t\tconst nctlS = spinner();\n\t\tnctlS.start(\"Checking neonctl CLI...\");\n\t\tconst nctlResult = await ensureNeonctl();\n\t\tswitch (nctlResult.status) {\n\t\t\tcase \"already_current\":\n\t\t\t\tnctlS.stop(\n\t\t\t\t\tdim(`neonctl CLI is up to date (v${nctlResult.version}) ✓`),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"installed\":\n\t\t\t\tnctlS.stop(\n\t\t\t\t\tdim(`Installed neonctl CLI (v${nctlResult.version}) ✓`),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"updated\":\n\t\t\t\tnctlS.stop(\n\t\t\t\t\tdim(`Updated neonctl CLI to v${nctlResult.version} ✓`),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"failed\":\n\t\t\t\tnctlS.stop(\"Failed to install neonctl CLI\");\n\t\t\t\tlog.warn(\n\t\t\t\t\t\"neonctl could not be installed automatically. The setup will continue using npx.\",\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Install only what's missing\n\t\tfor (const editor of selectedEditors) {\n\t\t\tif (needsMcp) {\n\t\t\t\tconst mcpAgentId = getAddMcpAgentId(editor);\n\t\t\t\tconst mcpArgs = [\n\t\t\t\t\t\"-y\",\n\t\t\t\t\t\"add-mcp\",\n\t\t\t\t\t\"https://mcp.neon.tech/mcp\",\n\t\t\t\t\t\"-n\",\n\t\t\t\t\t\"Neon\",\n\t\t\t\t\t\"-y\",\n\t\t\t\t\t\"-a\",\n\t\t\t\t\tmcpAgentId,\n\t\t\t\t];\n\t\t\t\tif (mcpScope === \"global\") mcpArgs.splice(5, 0, \"-g\");\n\n\t\t\t\tconst mcpS = spinner();\n\t\t\t\tmcpS.start(`Installing Neon MCP server for ${editor}...`);\n\t\t\t\ttry {\n\t\t\t\t\tawait execa(\"npx\", mcpArgs, {\n\t\t\t\t\t\tstdio: \"pipe\",\n\t\t\t\t\t\ttimeout: 60000,\n\t\t\t\t\t});\n\t\t\t\t\tmcpS.stop(\n\t\t\t\t\t\tdim(\n\t\t\t\t\t\t\t`Neon MCP server configured for ${editor} (${mcpScope}) ✓`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst msg =\n\t\t\t\t\t\terr instanceof Error ? err.message : \"Unknown error\";\n\t\t\t\t\tmcpS.stop(`Failed to configure MCP server for ${editor}`);\n\t\t\t\t\tlog.error(msg);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (needsSkills) {\n\t\t\t\tawait installAgentSkills([editor], { scope: skillsScope });\n\t\t\t}\n\n\t\t\tif (doInstallExtension && usesExtension(editor)) {\n\t\t\t\tconst extS = spinner();\n\t\t\t\textS.start(`Installing Neon extension for ${editor}...`);\n\t\t\t\tconst extOk = await installExtension(editor);\n\t\t\t\tif (extOk) {\n\t\t\t\t\textS.stop(dim(`Neon extension installed for ${editor} ✓`));\n\t\t\t\t} else {\n\t\t\t\t\textS.stop(\n\t\t\t\t\t\t`Extension install failed — install manually from the extensions panel.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Step 6: Done — build prompt for the agent to continue\n\t// -----------------------------------------------------------------------\n\n\t// Build the getting-started data payload (same as agent mode)\n\tconst gettingStartedData: Record<string, unknown> = {};\n\tif (hasNeonConnection) gettingStartedData.hasConnectionString = true;\n\tif (inspection.framework && inspection.framework !== \"none\")\n\t\tgettingStartedData.framework = inspection.framework;\n\tif (inspection.orm && inspection.orm !== \"none\")\n\t\tgettingStartedData.orm = inspection.orm;\n\tif (inspection.migrationTool && inspection.migrationTool !== \"none\")\n\t\tgettingStartedData.migrationTool = inspection.migrationTool;\n\tif (inspection.migrationDir && inspection.migrationDir !== \"none\")\n\t\tgettingStartedData.migrationDir = inspection.migrationDir;\n\tif (selectedFeatures.length > 0)\n\t\tgettingStartedData.features = selectedFeatures;\n\tif (options.preview) gettingStartedData.preview = true;\n\n\t// Build a prompt for the user to paste into their agent chat\n\tconst cmd = `neonctl init --agent --json --data '${JSON.stringify({ step: \"getting-started\", ...gettingStartedData })}'`;\n\t// Account for clack's \"│ \" prefix (3 chars) when wrapping\n\tconst cols = (process.stdout.columns || 80) - 3;\n\tconst promptText = `To finish setting up Neon using Neon's agent-guided onboarding experience, have your agent run this shell command: ${cmd}`;\n\n\tlog.step(\"Next steps\");\n\tlog.message(dim(\"Copy the following into your agent chat:\"));\n\tlog.message(\n\t\twordWrap(promptText, cols)\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => bold(neonGreenFn(line)))\n\t\t\t.join(\"\\n\"),\n\t);\n\toutro(dim(\"Have feedback? Email us at feedback@neon.tech\"));\n}\n\nfunction agentIdToEditor(agentId: string): Editor | null {\n\tswitch (agentId) {\n\t\tcase \"cursor\":\n\t\t\treturn \"Cursor\";\n\t\tcase \"vscode\":\n\t\t\treturn \"VS Code\";\n\t\tcase \"claude-code\":\n\t\t\treturn \"Claude CLI\";\n\t\tcase \"windsurf\":\n\t\t\t// Windsurf not in Editor type yet — fall back to prompt\n\t\t\treturn null;\n\t\tcase \"codex\":\n\t\t\treturn \"Codex\";\n\t\tcase \"cline\":\n\t\t\treturn \"Cline\";\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"interactive.js","names":[],"sources":["../src/interactive.ts"],"sourcesContent":["/**\n * Interactive v2 CLI — purpose-built guided flow for humans.\n * Uses the same underlying install functions but with a clean clack-based UX.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport {\n\tconfirm,\n\tisCancel,\n\tlog,\n\tmultiselect,\n\toutro,\n\tselect,\n\tspinner,\n} from \"@clack/prompts\";\nimport { execa } from \"execa\";\nimport { bold, dim } from \"yoctocolors\";\nimport { ALL_CONFIGURABLE_AGENTS, getAddMcpAgentId } from \"./lib/agents.js\";\nimport { ensureNeonctlAuth, isAuthenticated } from \"./lib/auth.js\";\nimport {\n\ttype BootstrapTemplate,\n\tFALLBACK_TEMPLATES,\n\tfetchTemplates,\n\ttype NeonFeature,\n} from \"./lib/bootstrap.js\";\nimport { detectAgent, detectIde } from \"./lib/detect-agent.js\";\nimport { detectAvailableEditors } from \"./lib/editors.js\";\nimport {\n\tinstallExtension,\n\tisExtensionInstalled,\n\tusesExtension,\n} from \"./lib/extension.js\";\nimport { inspectProject } from \"./lib/inspect.js\";\nimport { ensureNeonctl } from \"./lib/neonctl.js\";\nimport { ensureSkillsUpToDate, installAgentSkills } from \"./lib/skills.js\";\nimport type { Editor } from \"./lib/types.js\";\n\nfunction wordWrap(text: string, width: number): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => {\n\t\t\tif (line.length <= width) return line;\n\t\t\tconst words = line.split(\" \");\n\t\t\tconst lines: string[] = [];\n\t\t\tlet current = \"\";\n\t\t\tfor (const word of words) {\n\t\t\t\tif (\n\t\t\t\t\tcurrent.length + word.length + 1 > width &&\n\t\t\t\t\tcurrent.length > 0\n\t\t\t\t) {\n\t\t\t\t\tlines.push(current);\n\t\t\t\t\tcurrent = word;\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = current.length > 0 ? `${current} ${word}` : word;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (current.length > 0) lines.push(current);\n\t\t\treturn lines.join(\"\\n\");\n\t\t})\n\t\t.join(\"\\n\");\n}\n\n// Patch picocolors (used by @clack/prompts) to use Neon green instead of cyan/magenta.\n// clack hardcodes picocolors.cyan() with no theme API, so this is the least invasive override.\nimport picocolors from \"picocolors\";\n\nconst neonGreenFn = (s: string) => `\\x1b[38;2;75;181;120m${s}\\x1b[39m`;\nconst originalCyan = picocolors.cyan;\nconst originalMagenta = picocolors.magenta;\n\nfunction patchClackColors(): () => void {\n\tconst pc = picocolors as unknown as Record<string, unknown>;\n\tpc.cyan = neonGreenFn;\n\tpc.magenta = neonGreenFn;\n\treturn () => {\n\t\tpc.cyan = originalCyan;\n\t\tpc.magenta = originalMagenta;\n\t};\n}\n\nexport interface InteractiveInitOptions {\n\tpreview?: boolean;\n}\n\nexport async function interactiveInit(\n\toptions: InteractiveInitOptions = {},\n): Promise<void> {\n\tconst restoreColors = patchClackColors();\n\ttry {\n\t\tawait interactiveInitInner(options);\n\t} finally {\n\t\trestoreColors();\n\t}\n}\n\nasync function interactiveInitInner(\n\toptions: InteractiveInitOptions,\n): Promise<void> {\n\tconsole.log();\n\tconsole.log(\n\t\t\"\\x1b[38;2;75;181;120m\" +\n\t\t\t[\n\t\t\t\t\" ██╗ ██╗██████╗ ██████╗ ██╗ ██╗\",\n\t\t\t\t\" ███╗ ██║██╔═══╝ ██╔═══██╗███╗ ██║\",\n\t\t\t\t\" ████╗██║██████╗ ██║ ██║████╗██║\",\n\t\t\t\t\" ██╔████║██╔═══╝ ██║ ██║██╔████║\",\n\t\t\t\t\" ██║╚███║██████╗ ╚██████╔╝██║╚███║\",\n\t\t\t\t\" ╚═╝ ╚══╝╚═════╝ ╚═════╝ ╚═╝ ╚══╝\",\n\t\t\t].join(\"\\n\") +\n\t\t\t\"\\x1b[0m\",\n\t);\n\tconsole.log(\n\t\tdim(\n\t\t\twordWrap(\n\t\t\t\t\"\\nLet's get your project set up with Neon. We'll install the MCP server, agent skills, and IDE extension, then connect your app to a database.\\n\",\n\t\t\t\tprocess.stdout.columns || 80,\n\t\t\t),\n\t\t),\n\t);\n\n\tconst detectedAgentId = detectAgent();\n\tconst detectedEditor = detectedAgentId\n\t\t? agentIdToEditor(detectedAgentId)\n\t\t: null;\n\n\t// -----------------------------------------------------------------------\n\t// Step 1: Inspect what's already in place\n\t// -----------------------------------------------------------------------\n\tconst inspectSpinner = spinner();\n\tinspectSpinner.start(\"Checking existing configuration...\");\n\tconst inspection = await inspectProject([\n\t\t{ id: \"has_app\", description: \"\", lookFor: [] },\n\t\t{ id: \"mcp_server\", description: \"\", lookFor: [] },\n\t\t{ id: \"skills\", description: \"\", lookFor: [] },\n\t\t{ id: \"connection_string\", description: \"\", lookFor: [] },\n\t\t{ id: \"project_stack\", description: \"\", lookFor: [] },\n\t\t{ id: \"migrations\", description: \"\", lookFor: [] },\n\t\t{ id: \"ide_type\", description: \"\", lookFor: [] },\n\t]);\n\tinspectSpinner.stop(dim(\"Configuration checked ✓\"));\n\n\tconst hasApp = inspection.hasApp === true;\n\tlet selectedFeatures: NeonFeature[] = [];\n\tlet selectedTemplate: BootstrapTemplate | null = null;\n\n\t// Preview mode: bootstrap from template if no app detected\n\tif (options.preview && !hasApp) {\n\t\tlet templates = FALLBACK_TEMPLATES;\n\t\ttry {\n\t\t\tconst fetched = await fetchTemplates();\n\t\t\tif (fetched && fetched.length > 0) templates = fetched;\n\t\t} catch {}\n\n\t\tconst templateResult = await select({\n\t\t\tmessage:\n\t\t\t\t\"No application detected. Would you like to scaffold a new project from a template?\",\n\t\t\toptions: [\n\t\t\t\t...templates.map((t) => ({\n\t\t\t\t\tvalue: t.id,\n\t\t\t\t\tlabel: t.title,\n\t\t\t\t\thint: t.description,\n\t\t\t\t})),\n\t\t\t\t{\n\t\t\t\t\tvalue: \"none\",\n\t\t\t\t\tlabel: \"No thanks — continue without scaffolding\",\n\t\t\t\t},\n\t\t\t],\n\t\t\tinitialValue: templates[0]?.id ?? \"none\",\n\t\t});\n\t\tif (isCancel(templateResult)) {\n\t\t\toutro(\"Setup cancelled.\");\n\t\t\treturn;\n\t\t}\n\t\tif (templateResult !== \"none\") {\n\t\t\tselectedTemplate =\n\t\t\t\ttemplates.find((t) => t.id === templateResult) ?? null;\n\t\t\tif (selectedTemplate) {\n\t\t\t\tselectedFeatures = selectedTemplate.requires;\n\t\t\t\tconst bootstrapS = spinner();\n\t\t\t\tbootstrapS.start(\n\t\t\t\t\t`Scaffolding project from template \"${selectedTemplate.title}\"...`,\n\t\t\t\t);\n\t\t\t\ttry {\n\t\t\t\t\t// Pin @latest (and -y) so a stale globally-installed neonctl\n\t\t\t\t\t// can't be picked up by npx — bootstrap's rate-limit fix lives\n\t\t\t\t\t// in recent neonctl.\n\t\t\t\t\tawait execa(\n\t\t\t\t\t\t\"npx\",\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"-y\",\n\t\t\t\t\t\t\t\"neonctl@latest\",\n\t\t\t\t\t\t\t\"bootstrap\",\n\t\t\t\t\t\t\t\".\",\n\t\t\t\t\t\t\t\"--template\",\n\t\t\t\t\t\t\tselectedTemplate.id,\n\t\t\t\t\t\t\t\"--force\",\n\t\t\t\t\t\t],\n\t\t\t\t\t\t{ stdio: \"pipe\", timeout: 120000 },\n\t\t\t\t\t);\n\t\t\t\t\tbootstrapS.stop(\n\t\t\t\t\t\tdim(\n\t\t\t\t\t\t\t`Scaffolded project from \"${selectedTemplate.title}\" ✓`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst msg =\n\t\t\t\t\t\terr instanceof Error ? err.message : \"Unknown error\";\n\t\t\t\t\tbootstrapS.stop(\"Failed to scaffold project\");\n\t\t\t\t\tlog.error(msg);\n\t\t\t\t\toutro(\"Setup failed.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// For brownfield flows (existing app), ask which features to enable\n\tif (!selectedTemplate && hasApp) {\n\t\tconst featuresResult = await select({\n\t\t\tmessage:\n\t\t\t\t\"Which Neon features would you like to enable for this project?\",\n\t\t\toptions: [\n\t\t\t\t{ value: \"database\", label: \"Database\" },\n\t\t\t\t{\n\t\t\t\t\tvalue: \"database,auth\",\n\t\t\t\t\tlabel: \"Database + Neon Auth (adds authentication via Neon)\",\n\t\t\t\t},\n\t\t\t],\n\t\t\tinitialValue: \"database\",\n\t\t});\n\t\tif (isCancel(featuresResult)) {\n\t\t\toutro(\"Setup cancelled.\");\n\t\t\treturn;\n\t\t}\n\t\tselectedFeatures = (featuresResult as string).split(\n\t\t\t\",\",\n\t\t) as NeonFeature[];\n\t}\n\n\t// Write _init metadata to .neon\n\tif (selectedFeatures.length > 0) {\n\t\tconst neonPath = resolve(process.cwd(), \".neon\");\n\t\tlet existing: Record<string, unknown> = {};\n\t\tif (existsSync(neonPath)) {\n\t\t\ttry {\n\t\t\t\texisting = JSON.parse(readFileSync(neonPath, \"utf-8\"));\n\t\t\t} catch {}\n\t\t}\n\t\texisting._init = { features: selectedFeatures };\n\t\twriteFileSync(neonPath, `${JSON.stringify(existing, null, 2)}\\n`);\n\t}\n\n\tconst mcpAlready = inspection.mcpConfigured === true;\n\t// If we bootstrapped, skills come from the template\n\tconst skillsAlready =\n\t\tinspection.skillsInstalled === true || selectedTemplate !== null;\n\tconst hasNeonConnection = inspection.connectionString === true;\n\tlet needsMcp = !mcpAlready;\n\tconst needsSkills = !skillsAlready;\n\tconst needsInstall = needsMcp || needsSkills;\n\n\t// Check if .neon context file exists\n\tconst neonContextPath = resolve(process.cwd(), \".neon\");\n\tconst hasNeonContext =\n\t\texistsSync(neonContextPath) &&\n\t\t(() => {\n\t\t\ttry {\n\t\t\t\tconst content = JSON.parse(\n\t\t\t\t\treadFileSync(neonContextPath, \"utf-8\"),\n\t\t\t\t);\n\t\t\t\treturn !!content.projectId;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t})();\n\n\t// Check if Neon Auth is configured\n\tconst hasNeonAuth = (() => {\n\t\tfor (const envFile of [\".env\", \".env.local\"]) {\n\t\t\tconst envPath = resolve(process.cwd(), envFile);\n\t\t\tif (existsSync(envPath)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst content = readFileSync(envPath, \"utf-8\");\n\t\t\t\t\tif (/^NEON_AUTH_/m.test(content)) return true;\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t})();\n\n\t// Check if extension is installed for the detected editor\n\tlet extensionAlready = false;\n\tif (detectedEditor && usesExtension(detectedEditor)) {\n\t\textensionAlready = await isExtensionInstalled(detectedEditor);\n\t}\n\n\t// If tooling + database are configured, check if there's anything left to do\n\tif (mcpAlready && skillsAlready && hasNeonConnection && hasNeonContext) {\n\t\tlog.step(\n\t\t\tdim(\n\t\t\t\t`Neon MCP server already configured (${inspection.mcpScope || \"detected\"}) ✓`,\n\t\t\t),\n\t\t);\n\t\tlog.step(\n\t\t\tdim(\n\t\t\t\t`Neon agent skills already installed (${inspection.skillsScope || \"detected\"}) ✓`,\n\t\t\t),\n\t\t);\n\t\tif (extensionAlready)\n\t\t\tlog.step(dim(\"Neon editor extension installed ✓\"));\n\t\tlog.step(dim(\"Neon database connected ✓\"));\n\n\t\tif (hasNeonAuth) {\n\t\t\tlog.step(dim(\"Neon Auth configured ✓\"));\n\t\t\toutro(\n\t\t\t\tdim(\n\t\t\t\t\t\"Your project is fully configured with Neon. Nothing to do.\",\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Neon Auth not configured — ask if they want it\n\t\tconst authResult = await select({\n\t\t\tmessage:\n\t\t\t\t\"Would you like to set up Neon Auth for user authentication?\",\n\t\t\toptions: [\n\t\t\t\t{ value: \"yes\", label: \"Yes, set up Neon Auth\" },\n\t\t\t\t{ value: \"no\", label: \"No, skip for now\" },\n\t\t\t],\n\t\t\tinitialValue: \"no\",\n\t\t});\n\n\t\tif (isCancel(authResult) || authResult === \"no\") {\n\t\t\toutro(\n\t\t\t\tdim(\n\t\t\t\t\t`Your project is configured with Neon. You can set up Neon Auth later by having your agent run: neonctl init --agent --data '{\"step\":\"neon-auth\"}'`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Read .neon for project context\n\t\tlet projectId: string | null = null;\n\t\ttry {\n\t\t\tconst neonCtx = JSON.parse(readFileSync(neonContextPath, \"utf-8\"));\n\t\t\tprojectId = neonCtx.projectId ?? null;\n\t\t} catch {}\n\n\t\tlog.step(\"Next steps\");\n\t\tconst promptLines = [\"Set up Neon Auth for this project.\"];\n\t\tif (projectId) promptLines.push(`Project ID: ${projectId}.`);\n\t\tlog.message(dim(\"Copy the following into your agent chat:\"));\n\t\tlog.message(\n\t\t\tpromptLines.map((line) => bold(neonGreenFn(line))).join(\"\\n\"),\n\t\t);\n\t\toutro(dim(\"Have feedback? Email us at feedback@neon.tech\"));\n\t\treturn;\n\t}\n\n\t// Log what's already in place\n\tif (mcpAlready)\n\t\tlog.step(\n\t\t\tdim(\n\t\t\t\t`Neon MCP server already configured (${inspection.mcpScope || \"detected\"}) ✓`,\n\t\t\t),\n\t\t);\n\tif (skillsAlready)\n\t\tlog.step(\n\t\t\tdim(\n\t\t\t\t`Neon agent skills already installed (${inspection.skillsScope || \"detected\"}) ✓`,\n\t\t\t),\n\t\t);\n\n\t// -----------------------------------------------------------------------\n\t// Step 3–5: Install what's missing (skip entirely if everything is configured)\n\t// -----------------------------------------------------------------------\n\tif (needsInstall) {\n\t\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\t\tif (!homeDir) {\n\t\t\tlog.error(\"Could not determine home directory.\");\n\t\t\toutro(\"Setup failed.\");\n\t\t\treturn;\n\t\t}\n\n\t\tlet selectedEditors: Editor[];\n\t\tif (detectedEditor) {\n\t\t\tselectedEditors = [detectedEditor];\n\t\t} else {\n\t\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\t\t\tconst editorResponse = await multiselect({\n\t\t\t\tmessage: \"Which editor(s) would you like to configure?\",\n\t\t\t\toptions: ALL_CONFIGURABLE_AGENTS.map((agent) => ({\n\t\t\t\t\tvalue: agent.editor,\n\t\t\t\t\tlabel: agent.editor,\n\t\t\t\t\thint: agent.hint,\n\t\t\t\t})),\n\t\t\t\tinitialValues: availableEditors,\n\t\t\t\trequired: true,\n\t\t\t});\n\t\t\tif (isCancel(editorResponse)) {\n\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tselectedEditors = editorResponse as Editor[];\n\t\t\tif (selectedEditors.length === 0) {\n\t\t\t\tlog.warn(\"No editors selected.\");\n\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Check extension status\n\t\tconst vscodeEditors = selectedEditors.filter(usesExtension);\n\t\tlet extensionAlreadyInstalled = false;\n\t\tif (vscodeEditors.length > 0) {\n\t\t\tconst checks = await Promise.all(\n\t\t\t\tvscodeEditors.map((e) => isExtensionInstalled(e)),\n\t\t\t);\n\t\t\textensionAlreadyInstalled = checks.every(Boolean);\n\t\t\tif (extensionAlreadyInstalled) {\n\t\t\t\tlog.step(dim(\"Neon editor extension already installed ✓\"));\n\t\t\t}\n\t\t}\n\t\tlet doInstallExtension =\n\t\t\tvscodeEditors.length > 0 && !extensionAlreadyInstalled;\n\n\t\t// Build hint showing only what needs installing\n\t\tconst hintParts: string[] = [];\n\t\tif (needsMcp) hintParts.push(\"MCP server (global)\");\n\t\tif (needsSkills) hintParts.push(\"agent skills (project)\");\n\t\tif (doInstallExtension) hintParts.push(\"editor extension\");\n\n\t\t// Installation preferences\n\t\tlet mcpScope: \"global\" | \"project\" | \"none\" = \"global\";\n\t\tlet skillsScope: \"global\" | \"project\" = \"project\";\n\n\t\tlet modeResult: string;\n\t\twhile (true) {\n\t\t\tconst editorName = selectedEditors.join(\", \");\n\t\t\tconst result = await select({\n\t\t\t\tmessage: `Configure ${editorName} for Neon:`,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: \"defaults\",\n\t\t\t\t\t\tlabel: \"Install with defaults\",\n\t\t\t\t\t\thint: hintParts.join(\", \"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: \"customize\",\n\t\t\t\t\t\tlabel: \"Customize installation\",\n\t\t\t\t\t\thint: \"choose scopes and options\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: \"change_editor\",\n\t\t\t\t\t\tlabel: \"Configure a different editor\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tinitialValue: \"defaults\",\n\t\t\t});\n\n\t\t\tif (isCancel(result)) {\n\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (result === \"change_editor\") {\n\t\t\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\t\t\t\tconst editorResponse = await multiselect({\n\t\t\t\t\tmessage: \"Which editor(s) would you like to configure?\",\n\t\t\t\t\toptions: ALL_CONFIGURABLE_AGENTS.map((agent) => ({\n\t\t\t\t\t\tvalue: agent.editor,\n\t\t\t\t\t\tlabel: agent.editor,\n\t\t\t\t\t\thint: agent.hint,\n\t\t\t\t\t})),\n\t\t\t\t\tinitialValues: availableEditors,\n\t\t\t\t\trequired: true,\n\t\t\t\t});\n\t\t\t\tif (isCancel(editorResponse)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tselectedEditors = editorResponse as Editor[];\n\t\t\t\tif (selectedEditors.length === 0) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmodeResult = result as string;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (modeResult === \"customize\") {\n\t\t\tif (needsMcp) {\n\t\t\t\tconst scopeResult = await select({\n\t\t\t\t\tmessage: \"Where should the Neon MCP server be configured?\",\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"global\",\n\t\t\t\t\t\t\tlabel: \"Global (available in all projects)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"project\",\n\t\t\t\t\t\t\tlabel: \"Project-level (this project only)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"none\",\n\t\t\t\t\t\t\tlabel: \"Skip — do not install the MCP server\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t\tif (isCancel(scopeResult)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmcpScope = scopeResult as \"global\" | \"project\" | \"none\";\n\t\t\t\tif (mcpScope === \"none\") needsMcp = false;\n\t\t\t}\n\n\t\t\tif (needsSkills) {\n\t\t\t\tconst skillsScopeResult = await select({\n\t\t\t\t\tmessage: \"Where should Neon agent skills be installed?\",\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"global\",\n\t\t\t\t\t\t\tlabel: \"Global (available in all projects)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: \"project\",\n\t\t\t\t\t\t\tlabel: \"Project-level (this project only)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tinitialValue: \"project\",\n\t\t\t\t});\n\t\t\t\tif (isCancel(skillsScopeResult)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tskillsScope = skillsScopeResult as \"global\" | \"project\";\n\t\t\t}\n\n\t\t\tif (doInstallExtension) {\n\t\t\t\tconst extResult = await confirm({\n\t\t\t\t\tmessage: `Install the Neon extension for ${vscodeEditors.join(\", \")}?`,\n\t\t\t\t});\n\t\t\t\tif (isCancel(extResult)) {\n\t\t\t\t\toutro(\"Setup cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tdoInstallExtension = extResult;\n\t\t\t}\n\t\t}\n\n\t\t// Auth check before install\n\t\tconst installAuthed = await isAuthenticated();\n\t\tif (!installAuthed) {\n\t\t\tconst authS = spinner();\n\t\t\tauthS.start(\"Authenticating with Neon...\");\n\t\t\tconst authSuccess = await ensureNeonctlAuth();\n\t\t\tif (!authSuccess) {\n\t\t\t\tauthS.stop(\"Authentication failed.\");\n\t\t\t\toutro(\"Run neon-init again after signing in.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauthS.stop(\"Authenticated.\");\n\t\t}\n\n\t\t// Ensure neonctl CLI is installed and up to date\n\t\tconst nctlS = spinner();\n\t\tnctlS.start(\"Checking neonctl CLI...\");\n\t\tconst nctlResult = await ensureNeonctl();\n\t\tswitch (nctlResult.status) {\n\t\t\tcase \"already_current\":\n\t\t\t\tnctlS.stop(\n\t\t\t\t\tdim(`neonctl CLI is up to date (v${nctlResult.version}) ✓`),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"installed\":\n\t\t\t\tnctlS.stop(\n\t\t\t\t\tdim(`Installed neonctl CLI (v${nctlResult.version}) ✓`),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"updated\":\n\t\t\t\tnctlS.stop(\n\t\t\t\t\tdim(`Updated neonctl CLI to v${nctlResult.version} ✓`),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"failed\":\n\t\t\t\tnctlS.stop(\"Failed to install neonctl CLI\");\n\t\t\t\tlog.warn(\n\t\t\t\t\t\"neonctl could not be installed automatically. The setup will continue using npx.\",\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Install only what's missing\n\t\tfor (const editor of selectedEditors) {\n\t\t\tif (needsMcp) {\n\t\t\t\tconst mcpAgentId = getAddMcpAgentId(editor);\n\t\t\t\tconst mcpArgs = [\n\t\t\t\t\t\"-y\",\n\t\t\t\t\t\"add-mcp\",\n\t\t\t\t\t\"https://mcp.neon.tech/mcp\",\n\t\t\t\t\t\"-n\",\n\t\t\t\t\t\"Neon\",\n\t\t\t\t\t\"-y\",\n\t\t\t\t\t\"-a\",\n\t\t\t\t\tmcpAgentId,\n\t\t\t\t];\n\t\t\t\tif (mcpScope === \"global\") mcpArgs.splice(5, 0, \"-g\");\n\n\t\t\t\tconst mcpS = spinner();\n\t\t\t\tmcpS.start(`Installing Neon MCP server for ${editor}...`);\n\t\t\t\ttry {\n\t\t\t\t\tawait execa(\"npx\", mcpArgs, {\n\t\t\t\t\t\tstdio: \"pipe\",\n\t\t\t\t\t\ttimeout: 60000,\n\t\t\t\t\t});\n\t\t\t\t\tmcpS.stop(\n\t\t\t\t\t\tdim(\n\t\t\t\t\t\t\t`Neon MCP server configured for ${editor} (${mcpScope}) ✓`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst msg =\n\t\t\t\t\t\terr instanceof Error ? err.message : \"Unknown error\";\n\t\t\t\t\tmcpS.stop(`Failed to configure MCP server for ${editor}`);\n\t\t\t\t\tlog.error(msg);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (needsSkills) {\n\t\t\t\tawait installAgentSkills([editor], {\n\t\t\t\t\tscope: skillsScope,\n\t\t\t\t\tpreview: options.preview,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (doInstallExtension && usesExtension(editor)) {\n\t\t\t\tconst extS = spinner();\n\t\t\t\textS.start(`Installing Neon extension for ${editor}...`);\n\t\t\t\tconst extOk = await installExtension(editor);\n\t\t\t\tif (extOk) {\n\t\t\t\t\textS.stop(dim(`Neon extension installed for ${editor} ✓`));\n\t\t\t\t} else {\n\t\t\t\t\textS.stop(\n\t\t\t\t\t\t`Extension install failed — install manually from the extensions panel.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Ensure all required skills are present (fills in any missing ones).\n\t// detectAgent() returns null in a human terminal (TTY), so fall back\n\t// to IDE detection which works regardless of TTY.\n\tconst ide = detectIde();\n\tconst agentForSkills =\n\t\tdetectAgent() ??\n\t\t(ide === \"Cursor\"\n\t\t\t? \"cursor\"\n\t\t\t: ide === \"VS Code\"\n\t\t\t\t? \"vscode\"\n\t\t\t\t: ide === \"Windsurf\"\n\t\t\t\t\t? \"windsurf\"\n\t\t\t\t\t: null);\n\tif (agentForSkills) {\n\t\tconst detectedSkillsScope =\n\t\t\tinspection.skillsScope === \"global\" ? \"global\" : undefined;\n\t\tawait ensureSkillsUpToDate(\n\t\t\tagentForSkills,\n\t\t\tdetectedSkillsScope,\n\t\t\toptions.preview,\n\t\t);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Step 6: Done — build prompt for the agent to continue\n\t// -----------------------------------------------------------------------\n\n\t// Build the getting-started data payload (same as agent mode)\n\tconst gettingStartedData: Record<string, unknown> = {};\n\tif (hasNeonConnection) gettingStartedData.hasConnectionString = true;\n\tif (inspection.framework && inspection.framework !== \"none\")\n\t\tgettingStartedData.framework = inspection.framework;\n\tif (inspection.orm && inspection.orm !== \"none\")\n\t\tgettingStartedData.orm = inspection.orm;\n\tif (inspection.migrationTool && inspection.migrationTool !== \"none\")\n\t\tgettingStartedData.migrationTool = inspection.migrationTool;\n\tif (inspection.migrationDir && inspection.migrationDir !== \"none\")\n\t\tgettingStartedData.migrationDir = inspection.migrationDir;\n\tif (selectedFeatures.length > 0)\n\t\tgettingStartedData.features = selectedFeatures;\n\tif (options.preview) gettingStartedData.preview = true;\n\n\t// Build a prompt for the user to paste into their agent chat\n\tconst cmd = `neonctl init --agent --data '${JSON.stringify({ step: \"getting-started\", ...gettingStartedData })}'`;\n\t// Account for clack's \"│ \" prefix (3 chars) when wrapping\n\tconst cols = (process.stdout.columns || 80) - 3;\n\tconst promptText = `To finish setting up Neon using Neon's agent-guided onboarding experience, have your agent run this shell command: ${cmd}`;\n\n\tlog.step(\"Next steps\");\n\tlog.message(dim(\"Copy the following into your agent chat:\"));\n\tlog.message(\n\t\twordWrap(promptText, cols)\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => bold(neonGreenFn(line)))\n\t\t\t.join(\"\\n\"),\n\t);\n\toutro(dim(\"Have feedback? Email us at feedback@neon.tech\"));\n}\n\nfunction agentIdToEditor(agentId: string): Editor | null {\n\tswitch (agentId) {\n\t\tcase \"cursor\":\n\t\t\treturn \"Cursor\";\n\t\tcase \"vscode\":\n\t\t\treturn \"VS Code\";\n\t\tcase \"claude-code\":\n\t\t\treturn \"Claude CLI\";\n\t\tcase \"windsurf\":\n\t\t\t// Windsurf not in Editor type yet — fall back to prompt\n\t\t\treturn null;\n\t\tcase \"codex\":\n\t\t\treturn \"Codex\";\n\t\tcase \"cline\":\n\t\t\treturn \"Cline\";\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n"],"mappings":"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"}
@@ -139,7 +139,7 @@ function getSkillsAgentName(agent) {
139
139
  case "github-copilot-cli": return "github-copilot";
140
140
  case "mcporter": return "mcporter";
141
141
  case "zed": return "zed";
142
- default: throw new Error(`Unknown agent for skills: "${agent}". Use a known agent identifier.`);
142
+ default: return "cursor";
143
143
  }
144
144
  }
145
145
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","names":[],"sources":["../../src/lib/agents.ts"],"sourcesContent":["import type { Editor } from \"./types.js\";\n\nexport interface AgentConfig {\n\teditor: Editor;\n\taddMcpId: string;\n\thint: string;\n}\n\n/**\n * All agents that can be configured via neon-init.\n * Aligns with add-mcp's supported agents table.\n * https://github.com/neondatabase/add-mcp#supported-agents\n */\nexport const ALL_CONFIGURABLE_AGENTS: AgentConfig[] = [\n\t{\n\t\teditor: \"Cursor\",\n\t\taddMcpId: \"cursor\",\n\t\thint: \"Neon Local Connect extension\",\n\t},\n\t{\n\t\teditor: \"VS Code\",\n\t\taddMcpId: \"vscode\",\n\t\thint: \"Neon Local Connect extension\",\n\t},\n\t{ editor: \"Claude CLI\", addMcpId: \"claude-code\", hint: \"MCP Server\" },\n\t{\n\t\teditor: \"Claude Desktop\",\n\t\taddMcpId: \"claude-desktop\",\n\t\thint: \"MCP Server\",\n\t},\n\t{ editor: \"Codex\", addMcpId: \"codex\", hint: \"MCP Server\" },\n\t{ editor: \"OpenCode\", addMcpId: \"opencode\", hint: \"MCP Server\" },\n\t{ editor: \"Antigravity\", addMcpId: \"antigravity\", hint: \"MCP Server\" },\n\t{ editor: \"Cline\", addMcpId: \"cline\", hint: \"MCP Server\" },\n\t{ editor: \"Cline CLI\", addMcpId: \"cline-cli\", hint: \"MCP Server\" },\n\t{ editor: \"Gemini CLI\", addMcpId: \"gemini-cli\", hint: \"MCP Server\" },\n\t{\n\t\teditor: \"GitHub Copilot CLI\",\n\t\taddMcpId: \"github-copilot-cli\",\n\t\thint: \"MCP Server\",\n\t},\n\t{ editor: \"Goose\", addMcpId: \"goose\", hint: \"MCP Server\" },\n\t{ editor: \"MCPorter\", addMcpId: \"mcporter\", hint: \"MCP Server\" },\n\t{ editor: \"Zed\", addMcpId: \"zed\", hint: \"MCP Server\" },\n];\n\nexport function getAddMcpAgentId(editor: Editor): string {\n\tconst agent = ALL_CONFIGURABLE_AGENTS.find((a) => a.editor === editor);\n\tif (!agent) {\n\t\tthrow new Error(`No add-mcp agent ID found for editor: ${editor}`);\n\t}\n\treturn agent.addMcpId;\n}\n\n/**\n * Maps a raw agent identifier (as reported by agents or passed via --agent)\n * to the add-mcp compatible agent ID.\n *\n * This handles aliases like \"copilot\" → \"vscode\", \"claude\" → \"claude-code\", etc.\n */\nconst AGENT_ALIAS_TO_MCP_ID: Record<string, string> = {\n\tcursor: \"cursor\",\n\tcopilot: \"vscode\",\n\t\"github-copilot\": \"vscode\",\n\t\"vs-code\": \"vscode\",\n\tvscode: \"vscode\",\n\tclaude: \"claude-code\",\n\t\"claude-code\": \"claude-code\",\n\t\"claude-desktop\": \"claude-desktop\",\n\tcodex: \"codex\",\n\topencode: \"opencode\",\n\tantigravity: \"antigravity\",\n\tcline: \"cline\",\n\t\"cline-cli\": \"cline-cli\",\n\t\"gemini-cli\": \"gemini-cli\",\n\tgemini: \"gemini-cli\",\n\tgoose: \"goose\",\n\twindsurf: \"windsurf\",\n\t\"github-copilot-cli\": \"github-copilot-cli\",\n\tmcporter: \"mcporter\",\n\tzed: \"zed\",\n};\n\nexport function resolveAddMcpAgentId(rawAgent: string): string {\n\tconst resolved = AGENT_ALIAS_TO_MCP_ID[rawAgent.toLowerCase()];\n\tif (!resolved) {\n\t\tthrow new Error(\n\t\t\t`Unknown agent: \"${rawAgent}\". Supported agents: ${Object.keys(AGENT_ALIAS_TO_MCP_ID).join(\", \")}`,\n\t\t);\n\t}\n\treturn resolved;\n}\n\n/**\n * Maps a raw agent identifier to the skills CLI agent name.\n */\nexport function getSkillsAgentName(agent: string): string {\n\tswitch (agent.toLowerCase()) {\n\t\tcase \"cursor\":\n\t\t\treturn \"cursor\";\n\t\tcase \"copilot\":\n\t\tcase \"vscode\":\n\t\tcase \"vs-code\":\n\t\tcase \"github-copilot\":\n\t\t\treturn \"github-copilot\";\n\t\tcase \"claude\":\n\t\tcase \"claude-code\":\n\t\t\treturn \"claude-code\";\n\t\tcase \"codex\":\n\t\t\treturn \"codex\";\n\t\tcase \"opencode\":\n\t\t\treturn \"opencode\";\n\t\tcase \"antigravity\":\n\t\t\treturn \"antigravity\";\n\t\tcase \"cline\":\n\t\t\treturn \"cline\";\n\t\tcase \"gemini-cli\":\n\t\t\treturn \"gemini-cli\";\n\t\tcase \"goose\":\n\t\t\treturn \"goose\";\n\t\tcase \"claude-desktop\":\n\t\t\treturn \"claude-code\";\n\t\tcase \"cline-cli\":\n\t\t\treturn \"cline\";\n\t\tcase \"gemini\":\n\t\t\treturn \"gemini-cli\";\n\t\tcase \"windsurf\":\n\t\t\treturn \"windsurf\";\n\t\tcase \"github-copilot-cli\":\n\t\t\treturn \"github-copilot\";\n\t\tcase \"mcporter\":\n\t\t\treturn \"mcporter\";\n\t\tcase \"zed\":\n\t\t\treturn \"zed\";\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown agent for skills: \"${agent}\". Use a known agent identifier.`,\n\t\t\t);\n\t}\n}\n"],"mappings":";;;;;;AAaA,MAAa,0BAAyC;CACrD;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EAAE,QAAQ;EAAc,UAAU;EAAe,MAAM;CAAa;CACpE;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EAAE,QAAQ;EAAS,UAAU;EAAS,MAAM;CAAa;CACzD;EAAE,QAAQ;EAAY,UAAU;EAAY,MAAM;CAAa;CAC/D;EAAE,QAAQ;EAAe,UAAU;EAAe,MAAM;CAAa;CACrE;EAAE,QAAQ;EAAS,UAAU;EAAS,MAAM;CAAa;CACzD;EAAE,QAAQ;EAAa,UAAU;EAAa,MAAM;CAAa;CACjE;EAAE,QAAQ;EAAc,UAAU;EAAc,MAAM;CAAa;CACnE;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EAAE,QAAQ;EAAS,UAAU;EAAS,MAAM;CAAa;CACzD;EAAE,QAAQ;EAAY,UAAU;EAAY,MAAM;CAAa;CAC/D;EAAE,QAAQ;EAAO,UAAU;EAAO,MAAM;CAAa;AACtD;AAEA,SAAgB,iBAAiB,QAAwB;CACxD,MAAM,QAAQ,wBAAwB,MAAM,MAAM,EAAE,WAAW,MAAM;CACrE,IAAI,CAAC,OACJ,MAAM,IAAI,MAAM,yCAAyC,QAAQ;CAElE,OAAO,MAAM;AACd;;;;;;;AAQA,MAAM,wBAAgD;CACrD,QAAQ;CACR,SAAS;CACT,kBAAkB;CAClB,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,eAAe;CACf,kBAAkB;CAClB,OAAO;CACP,UAAU;CACV,aAAa;CACb,OAAO;CACP,aAAa;CACb,cAAc;CACd,QAAQ;CACR,OAAO;CACP,UAAU;CACV,sBAAsB;CACtB,UAAU;CACV,KAAK;AACN;AAEA,SAAgB,qBAAqB,UAA0B;CAC9D,MAAM,WAAW,sBAAsB,SAAS,YAAY;CAC5D,IAAI,CAAC,UACJ,MAAM,IAAI,MACT,mBAAmB,SAAS,uBAAuB,OAAO,KAAK,qBAAqB,CAAC,CAAC,KAAK,IAAI,GAChG;CAED,OAAO;AACR;;;;AAKA,SAAgB,mBAAmB,OAAuB;CACzD,QAAQ,MAAM,YAAY,GAA1B;EACC,KAAK,UACJ,OAAO;EACR,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,kBACJ,OAAO;EACR,KAAK;EACL,KAAK,eACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,eACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,cACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,kBACJ,OAAO;EACR,KAAK,aACJ,OAAO;EACR,KAAK,UACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,sBACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,SACC,MAAM,IAAI,MACT,8BAA8B,MAAM,iCACrC;CACF;AACD"}
1
+ {"version":3,"file":"agents.js","names":[],"sources":["../../src/lib/agents.ts"],"sourcesContent":["import type { Editor } from \"./types.js\";\n\nexport interface AgentConfig {\n\teditor: Editor;\n\taddMcpId: string;\n\thint: string;\n}\n\n/**\n * All agents that can be configured via neon-init.\n * Aligns with add-mcp's supported agents table.\n * https://github.com/neondatabase/add-mcp#supported-agents\n */\nexport const ALL_CONFIGURABLE_AGENTS: AgentConfig[] = [\n\t{\n\t\teditor: \"Cursor\",\n\t\taddMcpId: \"cursor\",\n\t\thint: \"Neon Local Connect extension\",\n\t},\n\t{\n\t\teditor: \"VS Code\",\n\t\taddMcpId: \"vscode\",\n\t\thint: \"Neon Local Connect extension\",\n\t},\n\t{ editor: \"Claude CLI\", addMcpId: \"claude-code\", hint: \"MCP Server\" },\n\t{\n\t\teditor: \"Claude Desktop\",\n\t\taddMcpId: \"claude-desktop\",\n\t\thint: \"MCP Server\",\n\t},\n\t{ editor: \"Codex\", addMcpId: \"codex\", hint: \"MCP Server\" },\n\t{ editor: \"OpenCode\", addMcpId: \"opencode\", hint: \"MCP Server\" },\n\t{ editor: \"Antigravity\", addMcpId: \"antigravity\", hint: \"MCP Server\" },\n\t{ editor: \"Cline\", addMcpId: \"cline\", hint: \"MCP Server\" },\n\t{ editor: \"Cline CLI\", addMcpId: \"cline-cli\", hint: \"MCP Server\" },\n\t{ editor: \"Gemini CLI\", addMcpId: \"gemini-cli\", hint: \"MCP Server\" },\n\t{\n\t\teditor: \"GitHub Copilot CLI\",\n\t\taddMcpId: \"github-copilot-cli\",\n\t\thint: \"MCP Server\",\n\t},\n\t{ editor: \"Goose\", addMcpId: \"goose\", hint: \"MCP Server\" },\n\t{ editor: \"MCPorter\", addMcpId: \"mcporter\", hint: \"MCP Server\" },\n\t{ editor: \"Zed\", addMcpId: \"zed\", hint: \"MCP Server\" },\n];\n\nexport function getAddMcpAgentId(editor: Editor): string {\n\tconst agent = ALL_CONFIGURABLE_AGENTS.find((a) => a.editor === editor);\n\tif (!agent) {\n\t\tthrow new Error(`No add-mcp agent ID found for editor: ${editor}`);\n\t}\n\treturn agent.addMcpId;\n}\n\n/**\n * Maps a raw agent identifier (as reported by agents or passed via --agent)\n * to the add-mcp compatible agent ID.\n *\n * This handles aliases like \"copilot\" → \"vscode\", \"claude\" → \"claude-code\", etc.\n */\nconst AGENT_ALIAS_TO_MCP_ID: Record<string, string> = {\n\tcursor: \"cursor\",\n\tcopilot: \"vscode\",\n\t\"github-copilot\": \"vscode\",\n\t\"vs-code\": \"vscode\",\n\tvscode: \"vscode\",\n\tclaude: \"claude-code\",\n\t\"claude-code\": \"claude-code\",\n\t\"claude-desktop\": \"claude-desktop\",\n\tcodex: \"codex\",\n\topencode: \"opencode\",\n\tantigravity: \"antigravity\",\n\tcline: \"cline\",\n\t\"cline-cli\": \"cline-cli\",\n\t\"gemini-cli\": \"gemini-cli\",\n\tgemini: \"gemini-cli\",\n\tgoose: \"goose\",\n\twindsurf: \"windsurf\",\n\t\"github-copilot-cli\": \"github-copilot-cli\",\n\tmcporter: \"mcporter\",\n\tzed: \"zed\",\n};\n\nexport function resolveAddMcpAgentId(rawAgent: string): string {\n\tconst resolved = AGENT_ALIAS_TO_MCP_ID[rawAgent.toLowerCase()];\n\tif (!resolved) {\n\t\tthrow new Error(\n\t\t\t`Unknown agent: \"${rawAgent}\". Supported agents: ${Object.keys(AGENT_ALIAS_TO_MCP_ID).join(\", \")}`,\n\t\t);\n\t}\n\treturn resolved;\n}\n\n/**\n * Maps a raw agent identifier to the skills CLI agent name.\n */\nexport function getSkillsAgentName(agent: string): string {\n\tswitch (agent.toLowerCase()) {\n\t\tcase \"cursor\":\n\t\t\treturn \"cursor\";\n\t\tcase \"copilot\":\n\t\tcase \"vscode\":\n\t\tcase \"vs-code\":\n\t\tcase \"github-copilot\":\n\t\t\treturn \"github-copilot\";\n\t\tcase \"claude\":\n\t\tcase \"claude-code\":\n\t\t\treturn \"claude-code\";\n\t\tcase \"codex\":\n\t\t\treturn \"codex\";\n\t\tcase \"opencode\":\n\t\t\treturn \"opencode\";\n\t\tcase \"antigravity\":\n\t\t\treturn \"antigravity\";\n\t\tcase \"cline\":\n\t\t\treturn \"cline\";\n\t\tcase \"gemini-cli\":\n\t\t\treturn \"gemini-cli\";\n\t\tcase \"goose\":\n\t\t\treturn \"goose\";\n\t\tcase \"claude-desktop\":\n\t\t\treturn \"claude-code\";\n\t\tcase \"cline-cli\":\n\t\t\treturn \"cline\";\n\t\tcase \"gemini\":\n\t\t\treturn \"gemini-cli\";\n\t\tcase \"windsurf\":\n\t\t\treturn \"windsurf\";\n\t\tcase \"github-copilot-cli\":\n\t\t\treturn \"github-copilot\";\n\t\tcase \"mcporter\":\n\t\t\treturn \"mcporter\";\n\t\tcase \"zed\":\n\t\t\treturn \"zed\";\n\t\tdefault:\n\t\t\t// Fall back to \"cursor\" as a safe default — skills CLI uses the\n\t\t\t// agent name to pick the output directory (.agents/skills, .cursor/skills, etc.)\n\t\t\t// and \"cursor\" uses .agents/skills which works for all agents.\n\t\t\treturn \"cursor\";\n\t}\n}\n"],"mappings":";;;;;;AAaA,MAAa,0BAAyC;CACrD;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EAAE,QAAQ;EAAc,UAAU;EAAe,MAAM;CAAa;CACpE;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EAAE,QAAQ;EAAS,UAAU;EAAS,MAAM;CAAa;CACzD;EAAE,QAAQ;EAAY,UAAU;EAAY,MAAM;CAAa;CAC/D;EAAE,QAAQ;EAAe,UAAU;EAAe,MAAM;CAAa;CACrE;EAAE,QAAQ;EAAS,UAAU;EAAS,MAAM;CAAa;CACzD;EAAE,QAAQ;EAAa,UAAU;EAAa,MAAM;CAAa;CACjE;EAAE,QAAQ;EAAc,UAAU;EAAc,MAAM;CAAa;CACnE;EACC,QAAQ;EACR,UAAU;EACV,MAAM;CACP;CACA;EAAE,QAAQ;EAAS,UAAU;EAAS,MAAM;CAAa;CACzD;EAAE,QAAQ;EAAY,UAAU;EAAY,MAAM;CAAa;CAC/D;EAAE,QAAQ;EAAO,UAAU;EAAO,MAAM;CAAa;AACtD;AAEA,SAAgB,iBAAiB,QAAwB;CACxD,MAAM,QAAQ,wBAAwB,MAAM,MAAM,EAAE,WAAW,MAAM;CACrE,IAAI,CAAC,OACJ,MAAM,IAAI,MAAM,yCAAyC,QAAQ;CAElE,OAAO,MAAM;AACd;;;;;;;AAQA,MAAM,wBAAgD;CACrD,QAAQ;CACR,SAAS;CACT,kBAAkB;CAClB,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,eAAe;CACf,kBAAkB;CAClB,OAAO;CACP,UAAU;CACV,aAAa;CACb,OAAO;CACP,aAAa;CACb,cAAc;CACd,QAAQ;CACR,OAAO;CACP,UAAU;CACV,sBAAsB;CACtB,UAAU;CACV,KAAK;AACN;AAEA,SAAgB,qBAAqB,UAA0B;CAC9D,MAAM,WAAW,sBAAsB,SAAS,YAAY;CAC5D,IAAI,CAAC,UACJ,MAAM,IAAI,MACT,mBAAmB,SAAS,uBAAuB,OAAO,KAAK,qBAAqB,CAAC,CAAC,KAAK,IAAI,GAChG;CAED,OAAO;AACR;;;;AAKA,SAAgB,mBAAmB,OAAuB;CACzD,QAAQ,MAAM,YAAY,GAA1B;EACC,KAAK,UACJ,OAAO;EACR,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,kBACJ,OAAO;EACR,KAAK;EACL,KAAK,eACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,eACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,cACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,kBACJ,OAAO;EACR,KAAK,aACJ,OAAO;EACR,KAAK,UACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,sBACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,SAIC,OAAO;CACT;AACD"}