neon-init 0.16.2 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -11,6 +11,7 @@ import { handleSetupPhase } from "./lib/phases/setup.js";
11
11
  import { handleSkillsPhase } from "./lib/phases/skills.js";
12
12
  import { handleStatusPhase } from "./lib/phases/status.js";
13
13
  import { orchestrate } from "./v2.js";
14
+ import { enrichResponse } from "./lib/enrich-output.js";
14
15
  import yargs from "yargs";
15
16
  import { hideBin } from "yargs/helpers";
16
17
  //#region src/cli.ts
@@ -25,7 +26,7 @@ const agentOption = { agent: {
25
26
  description: "Agent to configure (cursor, copilot, claude, etc.)."
26
27
  } };
27
28
  function outputJson(data) {
28
- console.log(JSON.stringify(data, null, 2));
29
+ console.log(JSON.stringify(enrichResponse(data), null, 2));
29
30
  }
30
31
  /**
31
32
  * Resolve the agent ID: use the explicit --agent value if provided,
@@ -37,24 +38,23 @@ function resolveAgent(explicit) {
37
38
  /**
38
39
  * Detects if an AI agent is invoking the CLI programmatically.
39
40
  *
40
- * Uses two signals:
41
- * 1. Agent-specific env vars (CLAUDECODE, CODEX, CLINE) unambiguous.
42
- * 2. IDE env vars (TERM_PROGRAM=cursor) + non-TTY stdin an IDE terminal
43
- * where stdin is piped means an agent spawned us via execa/subprocess.
44
- * A human typing in the same terminal would have isTTY=true.
41
+ * Agent-specific env vars (CLAUDECODE, CODEX, CLINE) are unambiguous.
42
+ * For IDE-based agents (Cursor, VS Code, Windsurf), we require non-TTY
43
+ * stdin to distinguish "agent spawned this" from "human typed this in
44
+ * the IDE's integrated terminal".
45
45
  */
46
46
  function detectAgentInvocation() {
47
47
  const env = process.env;
48
48
  if (env.CLAUDECODE === "1" || env.CLAUDE_CODE === "1" || env.CLAUDE_CLI === "1") return "claude-code";
49
49
  if (env.CODEX === "1") return "codex";
50
50
  if (env.CLINE === "1") return "cline";
51
- if (!process.stdin.isTTY) {
52
- const ide = detectAgent();
53
- if (ide) return ide;
54
- }
51
+ if (!process.stdin.isTTY) return detectAgent();
55
52
  return null;
56
53
  }
57
- 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("skip-neon-auth", {
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
+ type: "string",
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
58
  type: "boolean",
59
59
  default: false,
60
60
  description: "Skip the Neon Auth setup phase."
@@ -69,7 +69,24 @@ yargs(hideBin(process.argv)).scriptName("neon-init").usage("$0 [command] [option
69
69
  }), async (argv) => {
70
70
  const detectedAgent = detectAgentInvocation();
71
71
  const agent = resolveAgent(argv.agent ?? detectedAgent ?? void 0);
72
- if (argv.json || argv.agent !== void 0 || detectedAgent !== null) {
72
+ const jsonMode = argv.json || argv.agent !== void 0 || detectedAgent !== null;
73
+ if (argv.data && jsonMode) {
74
+ const { routeDataStep } = await import("./lib/route-command.js");
75
+ let data;
76
+ try {
77
+ data = JSON.parse(argv.data);
78
+ } catch {
79
+ console.error("Invalid JSON in --data flag. Expected a JSON object.");
80
+ process.exit(1);
81
+ return;
82
+ }
83
+ if (typeof data.step === "string") {
84
+ outputJson(await routeDataStep(data, agent));
85
+ process.exit(0);
86
+ return;
87
+ }
88
+ }
89
+ if (jsonMode) {
73
90
  outputJson(await orchestrate({
74
91
  agent,
75
92
  skipNeonAuth: argv.skipNeonAuth,
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\nfunction outputJson(data: unknown): void {\n\tconsole.log(JSON.stringify(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 * Uses two signals:\n * 1. Agent-specific env vars (CLAUDECODE, CODEX, CLINE) — unambiguous.\n * 2. IDE env vars (TERM_PROGRAM=cursor) + non-TTY stdin — an IDE terminal\n * where stdin is piped means an agent spawned us via execa/subprocess.\n * A human typing in the same terminal would have isTTY=true.\n */\nfunction detectAgentInvocation(): string | null {\n\tconst env = process.env;\n\n\t// Agent-specific env vars (always definitive)\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\tif (!process.stdin.isTTY) {\n\t\tconst ide = detectAgent();\n\t\tif (ide) return ide;\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(\"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\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: \"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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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { AgentActionAction, AgentCheck, AgentCheckAction, AgentStep, AskUserAction, CompleteAction, Editor, InitResult, NextAction, Phase, PhaseResponse, RestartRequiredAction, RunCommandAction, RunNeonInitAction, StatusResponse } from "./lib/types.js";
2
2
  import { InteractiveInitOptions, interactiveInit } from "./interactive.js";
3
+ import { detectAgent } from "./lib/detect-agent.js";
4
+ import { enrichResponse } from "./lib/enrich-output.js";
3
5
  import { handleAuthPhase } from "./lib/phases/auth.js";
4
6
  import { handleDbPhase } from "./lib/phases/db.js";
5
7
  import { handleMcpPhase } from "./lib/phases/mcp.js";
@@ -7,6 +9,7 @@ import { handleMigrationsPhase } from "./lib/phases/migrations.js";
7
9
  import { handleNeonAuthPhase } from "./lib/phases/neon-auth.js";
8
10
  import { handleSkillsPhase } from "./lib/phases/skills.js";
9
11
  import { handleStatusPhase } from "./lib/phases/status.js";
12
+ import { routeDataStep } from "./lib/route-command.js";
10
13
  import { OrchestratorOptions, orchestrate } from "./v2.js";
11
14
 
12
15
  //#region src/index.d.ts
@@ -22,5 +25,5 @@ interface InitOptions {
22
25
  */
23
26
  declare function init(options?: InitOptions): Promise<InitResult>;
24
27
  //#endregion
25
- export { type AgentActionAction, type AgentCheck, type AgentCheckAction, type AgentStep, type AskUserAction, type CompleteAction, InitOptions, type InitResult, type InteractiveInitOptions, type NextAction, type OrchestratorOptions, type Phase, type PhaseResponse, type RestartRequiredAction, type RunCommandAction, type RunNeonInitAction, type StatusResponse, handleAuthPhase, handleDbPhase, handleMcpPhase, handleMigrationsPhase, handleNeonAuthPhase, handleSkillsPhase, handleStatusPhase, init, interactiveInit, orchestrate };
28
+ export { type AgentActionAction, type AgentCheck, type AgentCheckAction, type AgentStep, type AskUserAction, type CompleteAction, InitOptions, type InitResult, type InteractiveInitOptions, type NextAction, type OrchestratorOptions, type Phase, type PhaseResponse, type RestartRequiredAction, type RunCommandAction, type RunNeonInitAction, type StatusResponse, detectAgent, enrichResponse, handleAuthPhase, handleDbPhase, handleMcpPhase, handleMigrationsPhase, handleNeonAuthPhase, handleSkillsPhase, handleStatusPhase, init, interactiveInit, orchestrate, routeDataStep };
26
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;AAyIsB,UA7FL,WAAA,CA6FS;EAAA;OAAW,CAAA,EA3F5B,MA2F4B;;MAAc,CAAA,EAAA,OAAA;AAAO;;;;iBAApC,IAAA,WAAe,cAAc,QAAQ"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;AA0IsB,UA3FL,WAAA,CA2FS;EAAA;OAAW,CAAA,EAzF5B,MAyF4B;;MAAc,CAAA,EAAA,OAAA;AAAO;;;;iBAApC,IAAA,WAAe,cAAc,QAAQ"}
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { ALL_CONFIGURABLE_AGENTS } from "./lib/agents.js";
2
2
  import { isAuthenticated } from "./lib/auth.js";
3
+ import { detectAgent } from "./lib/detect-agent.js";
3
4
  import { detectAvailableEditors } from "./lib/editors.js";
4
5
  import { usesExtension } from "./lib/extension.js";
5
- import { getNeonctlApiFlags, neonctlCmd } from "./lib/neonctl.js";
6
+ import { neonctlCmd } from "./lib/neonctl.js";
6
7
  import { SKILL_REFERENCE_URLS, fetchSkillContent, installAgentSkills } from "./lib/skills.js";
7
8
  import { interactiveInit } from "./interactive.js";
8
9
  import { handleAuthPhase } from "./lib/phases/auth.js";
@@ -13,13 +14,14 @@ import { handleNeonAuthPhase } from "./lib/phases/neon-auth.js";
13
14
  import { handleSkillsPhase } from "./lib/phases/skills.js";
14
15
  import { handleStatusPhase } from "./lib/phases/status.js";
15
16
  import { orchestrate } from "./v2.js";
17
+ import { enrichResponse } from "./lib/enrich-output.js";
16
18
  import { installNeon } from "./lib/install.js";
19
+ import { routeDataStep } from "./lib/route-command.js";
17
20
  import { intro, isCancel, log, multiselect, note, outro } from "@clack/prompts";
18
21
  import { bold, cyan } from "yoctocolors";
19
22
  //#region src/index.ts
20
23
  function getNeonctlCommands() {
21
- const flags = getNeonctlApiFlags();
22
- const base = flags ? `npx neonctl ${flags}` : "npx neonctl";
24
+ const base = "npx neonctl";
23
25
  return {
24
26
  listOrgs: `${base} orgs list --output json`,
25
27
  listProjects: `${base} projects list --output json`,
@@ -29,8 +31,7 @@ function getNeonctlCommands() {
29
31
  }
30
32
  function getAuthInstructions() {
31
33
  const cmd = neonctlCmd();
32
- const apiBase = process.env.NEON_API_HOST?.replace(/\/+$/, "");
33
- const signupUrl = apiBase ? `${apiBase}/signup` : "https://console.neon.tech/signup";
34
+ const signupUrl = process.env.NEON_API_HOST ? `${new URL(process.env.NEON_API_HOST).origin}/signup` : "https://console.neon.tech/signup";
34
35
  return [
35
36
  "YOU (the agent) must handle authentication. Do NOT ask the user to run commands themselves.",
36
37
  "Do NOT write wrapper scripts (Python, shell, etc.) — use simple shell commands only.",
@@ -62,7 +63,7 @@ function getAuthInstructions() {
62
63
  "=== AFTER SUCCESSFUL AUTH ===",
63
64
  `Step 5: Verify by running: ${cmd} me`,
64
65
  " This should print the user's account info and exit with code 0.",
65
- "Step 6: Re-run neon-init with the same --agent and --json flags to complete setup."
66
+ "Step 6: Re-run neonctl init with the same --agent and --json flags to complete setup."
66
67
  ].join("\n");
67
68
  }
68
69
  function buildAgentInstructions(refs) {
@@ -286,6 +287,6 @@ async function init(options) {
286
287
  };
287
288
  }
288
289
  //#endregion
289
- export { handleAuthPhase, handleDbPhase, handleMcpPhase, handleMigrationsPhase, handleNeonAuthPhase, handleSkillsPhase, handleStatusPhase, init, interactiveInit, orchestrate };
290
+ export { detectAgent, enrichResponse, handleAuthPhase, handleDbPhase, handleMcpPhase, handleMigrationsPhase, handleNeonAuthPhase, handleSkillsPhase, handleStatusPhase, init, interactiveInit, orchestrate, routeDataStep };
290
291
 
291
292
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { intro, isCancel, log, multiselect, note, outro } from \"@clack/prompts\";\nimport { bold, cyan } from \"yoctocolors\";\nimport { ALL_CONFIGURABLE_AGENTS } from \"./lib/agents.js\";\nimport { isAuthenticated } from \"./lib/auth.js\";\nimport { detectAvailableEditors } from \"./lib/editors.js\";\nimport { usesExtension } from \"./lib/extension.js\";\nimport { installNeon } from \"./lib/install.js\";\nimport { getNeonctlApiFlags, neonctlCmd } from \"./lib/neonctl.js\";\nimport {\n\tfetchSkillContent,\n\tinstallAgentSkills,\n\tSKILL_REFERENCE_URLS,\n} from \"./lib/skills.js\";\nimport type { Editor, InitResult } from \"./lib/types.js\";\n\nexport type { InteractiveInitOptions } from \"./interactive.js\";\nexport { interactiveInit } from \"./interactive.js\";\nexport { handleAuthPhase } from \"./lib/phases/auth.js\";\nexport { handleDbPhase } from \"./lib/phases/db.js\";\nexport { handleMcpPhase } from \"./lib/phases/mcp.js\";\nexport { handleMigrationsPhase } from \"./lib/phases/migrations.js\";\nexport { handleNeonAuthPhase } from \"./lib/phases/neon-auth.js\";\nexport { handleSkillsPhase } from \"./lib/phases/skills.js\";\nexport { handleStatusPhase } from \"./lib/phases/status.js\";\n// v2 exports\nexport type {\n\tAgentActionAction,\n\tAgentCheck,\n\tAgentCheckAction,\n\tAgentStep,\n\tAskUserAction,\n\tCompleteAction,\n\tInitResult,\n\tNextAction,\n\tPhase,\n\tPhaseResponse,\n\tRestartRequiredAction,\n\tRunCommandAction,\n\tRunNeonInitAction,\n\tStatusResponse,\n} from \"./lib/types.js\";\nexport type { OrchestratorOptions } from \"./v2.js\";\nexport { orchestrate } from \"./v2.js\";\n\nexport interface InitOptions {\n\t/** When set, configures only this agent and skips the editor selection prompt. */\n\tagent?: Editor;\n\t/** When true, suppresses interactive UI and returns structured JSON-friendly output. */\n\tjson?: boolean;\n}\n\nfunction getNeonctlCommands() {\n\tconst flags = getNeonctlApiFlags();\n\tconst base = flags ? `npx neonctl ${flags}` : \"npx neonctl\";\n\treturn {\n\t\tlistOrgs: `${base} orgs list --output json`,\n\t\tlistProjects: `${base} projects list --output json`,\n\t\tcreateProject: `${base} projects create --name <project-name> --output json`,\n\t\tgetConnectionString: `${base} connection-string --project-id <project-id>`,\n\t};\n}\n\nfunction getAuthInstructions(): string {\n\tconst cmd = neonctlCmd();\n\tconst apiBase = process.env.NEON_API_HOST?.replace(/\\/+$/, \"\");\n\tconst signupUrl = apiBase\n\t\t? `${apiBase}/signup`\n\t\t: \"https://console.neon.tech/signup\";\n\treturn [\n\t\t\"YOU (the agent) must handle authentication. Do NOT ask the user to run commands themselves.\",\n\t\t\"Do NOT write wrapper scripts (Python, shell, etc.) — use simple shell commands only.\",\n\t\t\"IMPORTANT: Unset the CI environment variable for all neonctl commands below,\",\n\t\t\"otherwise neonctl will refuse to open the browser.\",\n\t\t\"\",\n\t\t'Step 1: Ask the user: \"Do you already have a Neon account, or do you need to create one?\"',\n\t\t\"\",\n\t\t\"=== NEW ACCOUNT (sign up) ===\",\n\t\t\"Step 2a: Open the Neon sign-up page in the user's browser:\",\n\t\t` On macOS: open ${signupUrl}`,\n\t\t` On Linux: xdg-open ${signupUrl}`,\n\t\t\"Step 3a: Tell the user: \\\"I've opened the Neon sign-up page in your browser.\",\n\t\t\" Create your account, then check your email for a verification link and click it.\",\n\t\t' Let me know when you have finished signing up and verifying your email.\"',\n\t\t\"Step 4a: Once the user confirms, run the OAuth login:\",\n\t\t` ${cmd} auth`,\n\t\t\" This opens a second browser tab for OAuth authorization. The user approves access.\",\n\t\t\" If exit code 0: authentication succeeded.\",\n\t\t\" If exit code 2 (timeout): ask the user to confirm they finished sign-up and\",\n\t\t\" email verification, then retry the same command.\",\n\t\t\"\",\n\t\t\"=== EXISTING ACCOUNT (sign in) ===\",\n\t\t`Step 2b: Execute: ${cmd} auth`,\n\t\t\" This opens the OAuth login page directly. Sign-in is fast (60-second timeout).\",\n\t\t\" If exit code 0: authentication succeeded.\",\n\t\t\" If exit code 2 (timeout): ask the user to confirm they completed sign-in, then retry.\",\n\t\t\"\",\n\t\t\"=== AFTER SUCCESSFUL AUTH ===\",\n\t\t`Step 5: Verify by running: ${cmd} me`,\n\t\t\" This should print the user's account info and exit with code 0.\",\n\t\t\"Step 6: Re-run neon-init with the same --agent and --json flags to complete setup.\",\n\t].join(\"\\n\");\n}\n\nfunction buildAgentInstructions(refs: Record<string, string>): string {\n\treturn [\n\t\t\"IMPORTANT: Follow these steps to set up the Neon project. Do NOT skip steps.\",\n\t\t\"\",\n\t\t\"CRITICAL — SKILL REFERENCES: The URLs in skills.references are authoritative\",\n\t\t\"implementation guides with exact import paths, component patterns, route structures,\",\n\t\t\"and common mistakes to avoid. You MUST fetch and read the relevant skill reference\",\n\t\t\"URL BEFORE writing any code that uses that Neon feature. Do NOT rely on general\",\n\t\t\"documentation pages (e.g. /docs/guides/*) or guess at import paths — the skill\",\n\t\t\"references are more accurate, complete, and agent-optimized.\",\n\t\t\"\",\n\t\t`1. List organizations: ${getNeonctlCommands().listOrgs}`,\n\t\t\" - If one org, use it. If multiple, ask the user which to use.\",\n\t\t`2. List projects: ${getNeonctlCommands().listProjects} (add --org-id <org-id>)`,\n\t\t\" - No projects: ask if they want to create a new one.\",\n\t\t\" - One project: ask if they want to use it or create new.\",\n\t\t\" - Multiple: let the user choose.\",\n\t\t`3. Create project if needed: ${getNeonctlCommands().createProject} (add --org-id <org-id>)`,\n\t\t`4. Get connection string: ${getNeonctlCommands().getConnectionString}`,\n\t\t\"5. Store in .env as DATABASE_URL (append, don't overwrite existing .env).\",\n\t\t\"6. For apps with user login/auth: STOP. Before writing any auth code, fetch and\",\n\t\t` read this skill reference: ${refs.neonAuth ?? \"\"}`,\n\t\t\" It contains the exact packages, imports, component layout, route patterns,\",\n\t\t\" environment variables, and common mistakes. Follow it precisely.\",\n\t\t`7. For connection method/driver, fetch and read: ${refs.connectionMethods ?? \"\"}`,\n\t\t\"8. Refer to skills.gettingStarted for the full setup guide with additional details.\",\n\t\t\"\",\n\t\t\"Do NOT auto-create a project without asking the user first.\",\n\t].join(\"\\n\");\n}\n\n/**\n * Initialize Neon projects with MCP Server\n */\nexport async function init(options?: InitOptions): Promise<InitResult> {\n\tconst jsonMode = options?.json === true;\n\n\tconst makeFailedResult = (auth: boolean): InitResult => ({\n\t\tsuccess: false,\n\t\tauth,\n\t\teditors: [],\n\t\tskills: {\n\t\t\tinstalled: false,\n\t\t\tgettingStarted: null,\n\t\t\treferences: {},\n\t\t},\n\t\tneonctl: {\n\t\t\tauthenticated: auth,\n\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t},\n\t\tmcpServer: {\n\t\t\tconfigured: false,\n\t\t\trequiresRestart: false,\n\t\t},\n\t});\n\n\tif (!jsonMode) {\n\t\tif (options?.agent !== undefined) {\n\t\t\tif (usesExtension(options.agent)) {\n\t\t\t\tintro(\n\t\t\t\t\t`Adding Neon extension (includes MCP server) and agent skills for ${options.agent}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tintro(\n\t\t\t\t\t`Adding Neon MCP server and agent skills for ${options.agent}`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tintro(\n\t\t\t\t\"Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills\",\n\t\t\t);\n\t\t}\n\t}\n\n\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\tif (!homeDir) {\n\t\tif (!jsonMode) {\n\t\t\tlog.error(\"Could not determine home directory\");\n\t\t\toutro(\"📣 Is this unexpected? Email us at feedback@neon.tech\");\n\t\t}\n\t\treturn makeFailedResult(false);\n\t}\n\n\tlet selectedEditors: Editor[];\n\n\tif (options?.agent !== undefined) {\n\t\tselectedEditors = [options.agent];\n\t} else {\n\t\tif (jsonMode) {\n\t\t\treturn makeFailedResult(false);\n\t\t}\n\n\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\n\t\tconst response = await multiselect({\n\t\t\tmessage:\n\t\t\t\t\"Which editor(s) would you like to configure? (Space to toggle each option, Enter to confirm your selection)\",\n\t\t\toptions: ALL_CONFIGURABLE_AGENTS.map((agent) => ({\n\t\t\t\tvalue: agent.editor,\n\t\t\t\tlabel: agent.editor,\n\t\t\t\thint: agent.hint,\n\t\t\t})),\n\t\t\tinitialValues: availableEditors,\n\t\t\trequired: true,\n\t\t});\n\n\t\tif (isCancel(response)) {\n\t\t\toutro(\"Installation cancelled\");\n\t\t\treturn makeFailedResult(false);\n\t\t}\n\n\t\tselectedEditors = response as Editor[];\n\t}\n\n\tif (selectedEditors.length === 0) {\n\t\tif (!jsonMode) {\n\t\t\tlog.warn(\"No editors selected.\");\n\t\t\toutro(\"Installation cancelled\");\n\t\t}\n\t\treturn makeFailedResult(false);\n\t}\n\n\t// In JSON mode, check for existing credentials before attempting OAuth.\n\t// neonctl's OAuth has a 60s timeout and email verification breaks the redirect,\n\t// so we let the agent handle auth as a separate step.\n\tif (jsonMode) {\n\t\tconst hasCredentials = await isAuthenticated();\n\t\tif (!hasCredentials) {\n\t\t\tconst { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;\n\t\t\tconst gettingStartedContent = await fetchSkillContent();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tauth: false,\n\t\t\t\tauthRequired: true,\n\t\t\t\tauthInstructions: getAuthInstructions(),\n\t\t\t\teditors: [],\n\t\t\t\tskills: {\n\t\t\t\t\tinstalled: false,\n\t\t\t\t\tgettingStarted: gettingStartedContent,\n\t\t\t\t\treferences: otherRefs,\n\t\t\t\t},\n\t\t\t\tneonctl: {\n\t\t\t\t\tauthenticated: false,\n\t\t\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t\t\t},\n\t\t\t\tmcpServer: {\n\t\t\t\t\tconfigured: false,\n\t\t\t\t\trequiresRestart: false,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\tconst { results, authSuccess } = await installNeon(selectedEditors, {\n\t\tjson: jsonMode,\n\t});\n\n\tconst successful: Editor[] = [];\n\tconst failed: Editor[] = [];\n\n\tfor (const [editor, status] of results.entries()) {\n\t\tif (status === \"success\") {\n\t\t\tsuccessful.push(editor);\n\t\t} else {\n\t\t\tfailed.push(editor);\n\t\t}\n\t}\n\n\tlet skillsInstalled = false;\n\tif (successful.length > 0) {\n\t\tskillsInstalled = await installAgentSkills(successful, {\n\t\t\tjson: jsonMode,\n\t\t});\n\t}\n\n\t// Build the editors array for InitResult\n\tconst editorsResult: InitResult[\"editors\"] = [];\n\tfor (const [editor, status] of results.entries()) {\n\t\teditorsResult.push({\n\t\t\teditor,\n\t\t\tstatus,\n\t\t\ttype: usesExtension(editor) ? \"extension\" : \"mcp\",\n\t\t});\n\t}\n\n\tconst mcpConfigured = successful.some((e) => !usesExtension(e));\n\n\tif (jsonMode) {\n\t\tconst { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;\n\n\t\tconst gettingStartedContent = await fetchSkillContent();\n\n\t\treturn {\n\t\t\tsuccess: successful.length > 0,\n\t\t\tauth: authSuccess,\n\t\t\tagentInstructions: buildAgentInstructions(otherRefs),\n\t\t\teditors: editorsResult,\n\t\t\tskills: {\n\t\t\t\tinstalled: skillsInstalled,\n\t\t\t\tgettingStarted: gettingStartedContent,\n\t\t\t\treferences: otherRefs,\n\t\t\t},\n\t\t\tneonctl: {\n\t\t\t\tauthenticated: authSuccess,\n\t\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t\t},\n\t\t\tmcpServer: {\n\t\t\t\tconfigured: mcpConfigured,\n\t\t\t\trequiresRestart: mcpConfigured,\n\t\t\t},\n\t\t};\n\t}\n\n\t// Interactive UI output (non-json mode)\n\tconst extensionEditors = successful.filter(usesExtension);\n\tconst mcpEditors = successful.filter((e) => !usesExtension(e));\n\tconst failedExtensionEditors = failed.filter(usesExtension);\n\tconst failedMcpEditors = failed.filter((e) => !usesExtension(e));\n\n\tif (extensionEditors.length > 0) {\n\t\tconst extSuccessList = extensionEditors.join(\" / \");\n\t\tlog.step(\n\t\t\t`Neon Local Connect extension installed for ${extSuccessList}.\\n`,\n\t\t);\n\t}\n\n\tif (mcpEditors.length > 0) {\n\t\tconst mcpSuccessList = mcpEditors.join(\" / \");\n\t\tlog.step(\n\t\t\t`Neon MCP Server is now ready to use with ${mcpSuccessList}.\\n`,\n\t\t);\n\t}\n\n\tif (failedExtensionEditors.length > 0) {\n\t\tlog.info(\n\t\t\t\"Failed to install extension. For the best local development experience, install Neon Local Connect manually:\",\n\t\t);\n\t\tfor (const editor of failedExtensionEditors) {\n\t\t\tif (editor === \"VS Code\") {\n\t\t\t\tlog.info(\n\t\t\t\t\t\" • VS Code: https://marketplace.visualstudio.com/items?itemName=databricks.neon-local-connect\",\n\t\t\t\t);\n\t\t\t} else if (editor === \"Cursor\") {\n\t\t\t\tlog.info(\n\t\t\t\t\t\" • Cursor: https://open-vsx.org/extension/databricks/neon-local-connect\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (failedMcpEditors.length > 0) {\n\t\tlog.error(\n\t\t\t`Failed to configure MCP Server for ${failedMcpEditors.join(\" / \")}`,\n\t\t);\n\t\tlog.info(\n\t\t\t\"You can manually configure the MCP server by running: npx add-mcp https://mcp.neon.tech/mcp\",\n\t\t);\n\t}\n\n\tif (successful.length === 0) {\n\t\toutro(\n\t\t\t\"Installation cancelled or failed. Please check the output above and try again.\",\n\t\t);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tauth: authSuccess,\n\t\t\teditors: editorsResult,\n\t\t\tskills: { installed: false, gettingStarted: null, references: {} },\n\t\t\tneonctl: {\n\t\t\t\tauthenticated: authSuccess,\n\t\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t\t},\n\t\t\tmcpServer: { configured: false, requiresRestart: false },\n\t\t};\n\t}\n\n\tif (extensionEditors.length > 0 && mcpEditors.length === 0) {\n\t\tconst extSuccessList = extensionEditors.join(\" / \");\n\t\tnote(\n\t\t\t`\\x1b[0mRestart ${extSuccessList}, open the Neon extension and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in your agent chat`,\n\t\t\t\"What's next?\",\n\t\t);\n\t} else if (mcpEditors.length > 0 && extensionEditors.length === 0) {\n\t\tconst mcpSuccessList = mcpEditors.join(\" / \");\n\t\tnote(\n\t\t\t`\\x1b[0mRestart ${mcpSuccessList} and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in the chat`,\n\t\t\t\"What's next?\",\n\t\t);\n\t} else {\n\t\tnote(\n\t\t\t`\\x1b[0mFor ${extensionEditors.join(\" / \")}: Restart, open the Neon extension and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in your agent chat\\n\\x1b[0mFor ${mcpEditors.join(\" / \")}: Restart and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in the chat`,\n\t\t\t\"What's next?\",\n\t\t);\n\t}\n\n\toutro(\"Have feedback? Email us at feedback@neon.tech\");\n\n\treturn {\n\t\tsuccess: true,\n\t\tauth: authSuccess,\n\t\teditors: editorsResult,\n\t\tskills: {\n\t\t\tinstalled: skillsInstalled,\n\t\t\tgettingStarted: null,\n\t\t\treferences: {},\n\t\t},\n\t\tneonctl: {\n\t\t\tauthenticated: authSuccess,\n\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t},\n\t\tmcpServer: {\n\t\t\tconfigured: mcpConfigured,\n\t\t\trequiresRestart: mcpConfigured,\n\t\t},\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { intro, isCancel, log, multiselect, note, outro } from \"@clack/prompts\";\nimport { bold, cyan } from \"yoctocolors\";\nimport { ALL_CONFIGURABLE_AGENTS } from \"./lib/agents.js\";\nimport { isAuthenticated } from \"./lib/auth.js\";\nimport { detectAvailableEditors } from \"./lib/editors.js\";\nimport { usesExtension } from \"./lib/extension.js\";\nimport { installNeon } from \"./lib/install.js\";\nimport { neonctlCmd } from \"./lib/neonctl.js\";\nimport {\n\tfetchSkillContent,\n\tinstallAgentSkills,\n\tSKILL_REFERENCE_URLS,\n} from \"./lib/skills.js\";\nimport type { Editor, InitResult } from \"./lib/types.js\";\n\nexport type { InteractiveInitOptions } from \"./interactive.js\";\nexport { interactiveInit } from \"./interactive.js\";\nexport { detectAgent } from \"./lib/detect-agent.js\";\nexport { enrichResponse } from \"./lib/enrich-output.js\";\nexport { handleAuthPhase } from \"./lib/phases/auth.js\";\nexport { handleDbPhase } from \"./lib/phases/db.js\";\nexport { handleMcpPhase } from \"./lib/phases/mcp.js\";\nexport { handleMigrationsPhase } from \"./lib/phases/migrations.js\";\nexport { handleNeonAuthPhase } from \"./lib/phases/neon-auth.js\";\nexport { handleSkillsPhase } from \"./lib/phases/skills.js\";\nexport { handleStatusPhase } from \"./lib/phases/status.js\";\nexport { routeDataStep } from \"./lib/route-command.js\";\n// v2 exports\nexport type {\n\tAgentActionAction,\n\tAgentCheck,\n\tAgentCheckAction,\n\tAgentStep,\n\tAskUserAction,\n\tCompleteAction,\n\tInitResult,\n\tNextAction,\n\tPhase,\n\tPhaseResponse,\n\tRestartRequiredAction,\n\tRunCommandAction,\n\tRunNeonInitAction,\n\tStatusResponse,\n} from \"./lib/types.js\";\nexport type { OrchestratorOptions } from \"./v2.js\";\nexport { orchestrate } from \"./v2.js\";\n\nexport interface InitOptions {\n\t/** When set, configures only this agent and skips the editor selection prompt. */\n\tagent?: Editor;\n\t/** When true, suppresses interactive UI and returns structured JSON-friendly output. */\n\tjson?: boolean;\n}\n\nfunction getNeonctlCommands() {\n\tconst base = \"npx neonctl\";\n\treturn {\n\t\tlistOrgs: `${base} orgs list --output json`,\n\t\tlistProjects: `${base} projects list --output json`,\n\t\tcreateProject: `${base} projects create --name <project-name> --output json`,\n\t\tgetConnectionString: `${base} connection-string --project-id <project-id>`,\n\t};\n}\n\nfunction getAuthInstructions(): string {\n\tconst cmd = neonctlCmd();\n\tconst signupUrl = process.env.NEON_API_HOST\n\t\t? `${new URL(process.env.NEON_API_HOST).origin}/signup`\n\t\t: \"https://console.neon.tech/signup\";\n\treturn [\n\t\t\"YOU (the agent) must handle authentication. Do NOT ask the user to run commands themselves.\",\n\t\t\"Do NOT write wrapper scripts (Python, shell, etc.) — use simple shell commands only.\",\n\t\t\"IMPORTANT: Unset the CI environment variable for all neonctl commands below,\",\n\t\t\"otherwise neonctl will refuse to open the browser.\",\n\t\t\"\",\n\t\t'Step 1: Ask the user: \"Do you already have a Neon account, or do you need to create one?\"',\n\t\t\"\",\n\t\t\"=== NEW ACCOUNT (sign up) ===\",\n\t\t\"Step 2a: Open the Neon sign-up page in the user's browser:\",\n\t\t` On macOS: open ${signupUrl}`,\n\t\t` On Linux: xdg-open ${signupUrl}`,\n\t\t\"Step 3a: Tell the user: \\\"I've opened the Neon sign-up page in your browser.\",\n\t\t\" Create your account, then check your email for a verification link and click it.\",\n\t\t' Let me know when you have finished signing up and verifying your email.\"',\n\t\t\"Step 4a: Once the user confirms, run the OAuth login:\",\n\t\t` ${cmd} auth`,\n\t\t\" This opens a second browser tab for OAuth authorization. The user approves access.\",\n\t\t\" If exit code 0: authentication succeeded.\",\n\t\t\" If exit code 2 (timeout): ask the user to confirm they finished sign-up and\",\n\t\t\" email verification, then retry the same command.\",\n\t\t\"\",\n\t\t\"=== EXISTING ACCOUNT (sign in) ===\",\n\t\t`Step 2b: Execute: ${cmd} auth`,\n\t\t\" This opens the OAuth login page directly. Sign-in is fast (60-second timeout).\",\n\t\t\" If exit code 0: authentication succeeded.\",\n\t\t\" If exit code 2 (timeout): ask the user to confirm they completed sign-in, then retry.\",\n\t\t\"\",\n\t\t\"=== AFTER SUCCESSFUL AUTH ===\",\n\t\t`Step 5: Verify by running: ${cmd} me`,\n\t\t\" This should print the user's account info and exit with code 0.\",\n\t\t\"Step 6: Re-run neonctl init with the same --agent and --json flags to complete setup.\",\n\t].join(\"\\n\");\n}\n\nfunction buildAgentInstructions(refs: Record<string, string>): string {\n\treturn [\n\t\t\"IMPORTANT: Follow these steps to set up the Neon project. Do NOT skip steps.\",\n\t\t\"\",\n\t\t\"CRITICAL — SKILL REFERENCES: The URLs in skills.references are authoritative\",\n\t\t\"implementation guides with exact import paths, component patterns, route structures,\",\n\t\t\"and common mistakes to avoid. You MUST fetch and read the relevant skill reference\",\n\t\t\"URL BEFORE writing any code that uses that Neon feature. Do NOT rely on general\",\n\t\t\"documentation pages (e.g. /docs/guides/*) or guess at import paths — the skill\",\n\t\t\"references are more accurate, complete, and agent-optimized.\",\n\t\t\"\",\n\t\t`1. List organizations: ${getNeonctlCommands().listOrgs}`,\n\t\t\" - If one org, use it. If multiple, ask the user which to use.\",\n\t\t`2. List projects: ${getNeonctlCommands().listProjects} (add --org-id <org-id>)`,\n\t\t\" - No projects: ask if they want to create a new one.\",\n\t\t\" - One project: ask if they want to use it or create new.\",\n\t\t\" - Multiple: let the user choose.\",\n\t\t`3. Create project if needed: ${getNeonctlCommands().createProject} (add --org-id <org-id>)`,\n\t\t`4. Get connection string: ${getNeonctlCommands().getConnectionString}`,\n\t\t\"5. Store in .env as DATABASE_URL (append, don't overwrite existing .env).\",\n\t\t\"6. For apps with user login/auth: STOP. Before writing any auth code, fetch and\",\n\t\t` read this skill reference: ${refs.neonAuth ?? \"\"}`,\n\t\t\" It contains the exact packages, imports, component layout, route patterns,\",\n\t\t\" environment variables, and common mistakes. Follow it precisely.\",\n\t\t`7. For connection method/driver, fetch and read: ${refs.connectionMethods ?? \"\"}`,\n\t\t\"8. Refer to skills.gettingStarted for the full setup guide with additional details.\",\n\t\t\"\",\n\t\t\"Do NOT auto-create a project without asking the user first.\",\n\t].join(\"\\n\");\n}\n\n/**\n * Initialize Neon projects with MCP Server\n */\nexport async function init(options?: InitOptions): Promise<InitResult> {\n\tconst jsonMode = options?.json === true;\n\n\tconst makeFailedResult = (auth: boolean): InitResult => ({\n\t\tsuccess: false,\n\t\tauth,\n\t\teditors: [],\n\t\tskills: {\n\t\t\tinstalled: false,\n\t\t\tgettingStarted: null,\n\t\t\treferences: {},\n\t\t},\n\t\tneonctl: {\n\t\t\tauthenticated: auth,\n\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t},\n\t\tmcpServer: {\n\t\t\tconfigured: false,\n\t\t\trequiresRestart: false,\n\t\t},\n\t});\n\n\tif (!jsonMode) {\n\t\tif (options?.agent !== undefined) {\n\t\t\tif (usesExtension(options.agent)) {\n\t\t\t\tintro(\n\t\t\t\t\t`Adding Neon extension (includes MCP server) and agent skills for ${options.agent}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tintro(\n\t\t\t\t\t`Adding Neon MCP server and agent skills for ${options.agent}`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tintro(\n\t\t\t\t\"Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills\",\n\t\t\t);\n\t\t}\n\t}\n\n\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\tif (!homeDir) {\n\t\tif (!jsonMode) {\n\t\t\tlog.error(\"Could not determine home directory\");\n\t\t\toutro(\"📣 Is this unexpected? Email us at feedback@neon.tech\");\n\t\t}\n\t\treturn makeFailedResult(false);\n\t}\n\n\tlet selectedEditors: Editor[];\n\n\tif (options?.agent !== undefined) {\n\t\tselectedEditors = [options.agent];\n\t} else {\n\t\tif (jsonMode) {\n\t\t\treturn makeFailedResult(false);\n\t\t}\n\n\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\n\t\tconst response = await multiselect({\n\t\t\tmessage:\n\t\t\t\t\"Which editor(s) would you like to configure? (Space to toggle each option, Enter to confirm your selection)\",\n\t\t\toptions: ALL_CONFIGURABLE_AGENTS.map((agent) => ({\n\t\t\t\tvalue: agent.editor,\n\t\t\t\tlabel: agent.editor,\n\t\t\t\thint: agent.hint,\n\t\t\t})),\n\t\t\tinitialValues: availableEditors,\n\t\t\trequired: true,\n\t\t});\n\n\t\tif (isCancel(response)) {\n\t\t\toutro(\"Installation cancelled\");\n\t\t\treturn makeFailedResult(false);\n\t\t}\n\n\t\tselectedEditors = response as Editor[];\n\t}\n\n\tif (selectedEditors.length === 0) {\n\t\tif (!jsonMode) {\n\t\t\tlog.warn(\"No editors selected.\");\n\t\t\toutro(\"Installation cancelled\");\n\t\t}\n\t\treturn makeFailedResult(false);\n\t}\n\n\t// In JSON mode, check for existing credentials before attempting OAuth.\n\t// neonctl's OAuth has a 60s timeout and email verification breaks the redirect,\n\t// so we let the agent handle auth as a separate step.\n\tif (jsonMode) {\n\t\tconst hasCredentials = await isAuthenticated();\n\t\tif (!hasCredentials) {\n\t\t\tconst { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;\n\t\t\tconst gettingStartedContent = await fetchSkillContent();\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tauth: false,\n\t\t\t\tauthRequired: true,\n\t\t\t\tauthInstructions: getAuthInstructions(),\n\t\t\t\teditors: [],\n\t\t\t\tskills: {\n\t\t\t\t\tinstalled: false,\n\t\t\t\t\tgettingStarted: gettingStartedContent,\n\t\t\t\t\treferences: otherRefs,\n\t\t\t\t},\n\t\t\t\tneonctl: {\n\t\t\t\t\tauthenticated: false,\n\t\t\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t\t\t},\n\t\t\t\tmcpServer: {\n\t\t\t\t\tconfigured: false,\n\t\t\t\t\trequiresRestart: false,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\tconst { results, authSuccess } = await installNeon(selectedEditors, {\n\t\tjson: jsonMode,\n\t});\n\n\tconst successful: Editor[] = [];\n\tconst failed: Editor[] = [];\n\n\tfor (const [editor, status] of results.entries()) {\n\t\tif (status === \"success\") {\n\t\t\tsuccessful.push(editor);\n\t\t} else {\n\t\t\tfailed.push(editor);\n\t\t}\n\t}\n\n\tlet skillsInstalled = false;\n\tif (successful.length > 0) {\n\t\tskillsInstalled = await installAgentSkills(successful, {\n\t\t\tjson: jsonMode,\n\t\t});\n\t}\n\n\t// Build the editors array for InitResult\n\tconst editorsResult: InitResult[\"editors\"] = [];\n\tfor (const [editor, status] of results.entries()) {\n\t\teditorsResult.push({\n\t\t\teditor,\n\t\t\tstatus,\n\t\t\ttype: usesExtension(editor) ? \"extension\" : \"mcp\",\n\t\t});\n\t}\n\n\tconst mcpConfigured = successful.some((e) => !usesExtension(e));\n\n\tif (jsonMode) {\n\t\tconst { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;\n\n\t\tconst gettingStartedContent = await fetchSkillContent();\n\n\t\treturn {\n\t\t\tsuccess: successful.length > 0,\n\t\t\tauth: authSuccess,\n\t\t\tagentInstructions: buildAgentInstructions(otherRefs),\n\t\t\teditors: editorsResult,\n\t\t\tskills: {\n\t\t\t\tinstalled: skillsInstalled,\n\t\t\t\tgettingStarted: gettingStartedContent,\n\t\t\t\treferences: otherRefs,\n\t\t\t},\n\t\t\tneonctl: {\n\t\t\t\tauthenticated: authSuccess,\n\t\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t\t},\n\t\t\tmcpServer: {\n\t\t\t\tconfigured: mcpConfigured,\n\t\t\t\trequiresRestart: mcpConfigured,\n\t\t\t},\n\t\t};\n\t}\n\n\t// Interactive UI output (non-json mode)\n\tconst extensionEditors = successful.filter(usesExtension);\n\tconst mcpEditors = successful.filter((e) => !usesExtension(e));\n\tconst failedExtensionEditors = failed.filter(usesExtension);\n\tconst failedMcpEditors = failed.filter((e) => !usesExtension(e));\n\n\tif (extensionEditors.length > 0) {\n\t\tconst extSuccessList = extensionEditors.join(\" / \");\n\t\tlog.step(\n\t\t\t`Neon Local Connect extension installed for ${extSuccessList}.\\n`,\n\t\t);\n\t}\n\n\tif (mcpEditors.length > 0) {\n\t\tconst mcpSuccessList = mcpEditors.join(\" / \");\n\t\tlog.step(\n\t\t\t`Neon MCP Server is now ready to use with ${mcpSuccessList}.\\n`,\n\t\t);\n\t}\n\n\tif (failedExtensionEditors.length > 0) {\n\t\tlog.info(\n\t\t\t\"Failed to install extension. For the best local development experience, install Neon Local Connect manually:\",\n\t\t);\n\t\tfor (const editor of failedExtensionEditors) {\n\t\t\tif (editor === \"VS Code\") {\n\t\t\t\tlog.info(\n\t\t\t\t\t\" • VS Code: https://marketplace.visualstudio.com/items?itemName=databricks.neon-local-connect\",\n\t\t\t\t);\n\t\t\t} else if (editor === \"Cursor\") {\n\t\t\t\tlog.info(\n\t\t\t\t\t\" • Cursor: https://open-vsx.org/extension/databricks/neon-local-connect\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (failedMcpEditors.length > 0) {\n\t\tlog.error(\n\t\t\t`Failed to configure MCP Server for ${failedMcpEditors.join(\" / \")}`,\n\t\t);\n\t\tlog.info(\n\t\t\t\"You can manually configure the MCP server by running: npx add-mcp https://mcp.neon.tech/mcp\",\n\t\t);\n\t}\n\n\tif (successful.length === 0) {\n\t\toutro(\n\t\t\t\"Installation cancelled or failed. Please check the output above and try again.\",\n\t\t);\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tauth: authSuccess,\n\t\t\teditors: editorsResult,\n\t\t\tskills: { installed: false, gettingStarted: null, references: {} },\n\t\t\tneonctl: {\n\t\t\t\tauthenticated: authSuccess,\n\t\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t\t},\n\t\t\tmcpServer: { configured: false, requiresRestart: false },\n\t\t};\n\t}\n\n\tif (extensionEditors.length > 0 && mcpEditors.length === 0) {\n\t\tconst extSuccessList = extensionEditors.join(\" / \");\n\t\tnote(\n\t\t\t`\\x1b[0mRestart ${extSuccessList}, open the Neon extension and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in your agent chat`,\n\t\t\t\"What's next?\",\n\t\t);\n\t} else if (mcpEditors.length > 0 && extensionEditors.length === 0) {\n\t\tconst mcpSuccessList = mcpEditors.join(\" / \");\n\t\tnote(\n\t\t\t`\\x1b[0mRestart ${mcpSuccessList} and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in the chat`,\n\t\t\t\"What's next?\",\n\t\t);\n\t} else {\n\t\tnote(\n\t\t\t`\\x1b[0mFor ${extensionEditors.join(\" / \")}: Restart, open the Neon extension and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in your agent chat\\n\\x1b[0mFor ${mcpEditors.join(\" / \")}: Restart and type in \"${bold(cyan(\"Get started with Neon\"))}\\x1b[0m\" in the chat`,\n\t\t\t\"What's next?\",\n\t\t);\n\t}\n\n\toutro(\"Have feedback? Email us at feedback@neon.tech\");\n\n\treturn {\n\t\tsuccess: true,\n\t\tauth: authSuccess,\n\t\teditors: editorsResult,\n\t\tskills: {\n\t\t\tinstalled: skillsInstalled,\n\t\t\tgettingStarted: null,\n\t\t\treferences: {},\n\t\t},\n\t\tneonctl: {\n\t\t\tauthenticated: authSuccess,\n\t\t\tcommands: { ...getNeonctlCommands() },\n\t\t},\n\t\tmcpServer: {\n\t\t\tconfigured: mcpConfigured,\n\t\t\trequiresRestart: mcpConfigured,\n\t\t},\n\t};\n}\n"],"mappings":"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"}
@@ -190,7 +190,7 @@ async function interactiveInitInner(options) {
190
190
  const mcpAlready = inspection.mcpConfigured === true;
191
191
  const skillsAlready = inspection.skillsInstalled === true || selectedTemplate !== null;
192
192
  const hasNeonConnection = inspection.connectionString === true;
193
- const needsMcp = !mcpAlready;
193
+ let needsMcp = !mcpAlready;
194
194
  const needsSkills = !skillsAlready;
195
195
  const needsInstall = needsMcp || needsSkills;
196
196
  const neonContextPath = resolve(process.cwd(), ".neon");
@@ -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: neon-init neon-auth --agent --json"));
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"}'`));
239
239
  return;
240
240
  }
241
241
  let projectId = null;
@@ -353,19 +353,27 @@ async function interactiveInitInner(options) {
353
353
  if (needsMcp) {
354
354
  const scopeResult = await select({
355
355
  message: "Where should the Neon MCP server be configured?",
356
- options: [{
357
- value: "global",
358
- label: "Global (available in all projects)"
359
- }, {
360
- value: "project",
361
- label: "Project-level (this project only)"
362
- }]
356
+ options: [
357
+ {
358
+ value: "global",
359
+ label: "Global (available in all projects)"
360
+ },
361
+ {
362
+ value: "project",
363
+ label: "Project-level (this project only)"
364
+ },
365
+ {
366
+ value: "none",
367
+ label: "Skip — do not install the MCP server"
368
+ }
369
+ ]
363
370
  });
364
371
  if (isCancel(scopeResult)) {
365
372
  outro("Setup cancelled.");
366
373
  return;
367
374
  }
368
375
  mcpScope = scopeResult;
376
+ if (mcpScope === "none") needsMcp = false;
369
377
  }
370
378
  if (needsSkills) {
371
379
  const skillsScopeResult = await select({
@@ -466,10 +474,11 @@ async function interactiveInitInner(options) {
466
474
  if (inspection.migrationDir && inspection.migrationDir !== "none") gettingStartedData.migrationDir = inspection.migrationDir;
467
475
  if (selectedFeatures.length > 0) gettingStartedData.features = selectedFeatures;
468
476
  if (options.preview) gettingStartedData.preview = true;
469
- const dataJson = JSON.stringify(gettingStartedData);
470
- const apiHost = process.env.NEON_API_HOST;
471
- const cmd = `${apiHost ? `NEON_API_HOST=${apiHost} ` : ""}neon-init getting-started --agent --json --data '${dataJson}'`;
472
- const cols = process.stdout.columns || 80;
477
+ const cmd = `neonctl init --agent --json --data '${JSON.stringify({
478
+ step: "getting-started",
479
+ ...gettingStartedData
480
+ })}'`;
481
+ const cols = (process.stdout.columns || 80) - 3;
473
482
  const promptText = `To finish setting up Neon using Neon's agent-guided onboarding experience, have your agent run this shell command: ${cmd}`;
474
483
  log.step("Next steps");
475
484
  log.message(dim("Copy the following into your agent chat:"));