neon-init 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;AA6bA;;iBAAsB,IAAA,CAAA,GAAQ"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;AAueA;;iBAAsB,IAAA,CAAA,GAAQ"}
package/dist/index.js CHANGED
@@ -18,12 +18,15 @@ async function ensureNeonctlAuth() {
18
18
  await new Promise((resolve$1, reject) => {
19
19
  const meProcess = spawn("npx", [
20
20
  "-y",
21
- "neon",
21
+ "neonctl",
22
22
  "me",
23
23
  "--output",
24
24
  "json",
25
25
  "--no-analytics"
26
- ], { stdio: "inherit" });
26
+ ], {
27
+ stdio: "inherit",
28
+ shell: true
29
+ });
27
30
  meProcess.on("close", (code) => {
28
31
  if (code === 0) resolve$1();
29
32
  else reject(/* @__PURE__ */ new Error(`Authentication failed with exit code ${code}`));
@@ -82,7 +85,7 @@ async function createApiKeyFromNeonctl() {
82
85
  }
83
86
  async function fetchOrganizations() {
84
87
  try {
85
- const { stdout } = await execAsync("npx -y neon orgs list --output json --no-analytics", { maxBuffer: 1024 * 1024 });
88
+ const { stdout } = await execAsync("npx -y neonctl orgs list --output json --no-analytics", { maxBuffer: 1024 * 1024 });
86
89
  const data = JSON.parse(stdout);
87
90
  return Array.isArray(data) ? data.map((org) => ({
88
91
  id: org.id,
@@ -116,13 +119,13 @@ function writeMCPConfig(cursorDir, config) {
116
119
  writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2), "utf-8");
117
120
  }
118
121
  /**
119
- * Gets the AGENTS.md template with Neon-specific best practices
122
+ * Gets the neon.md template with Neon-specific best practices
120
123
  */
121
- function getAgentsMdTemplate() {
124
+ function getNeonMdTemplate() {
122
125
  return readFileSync(resolve(__dirname, "../src/agents-template.md"), "utf-8");
123
126
  }
124
127
  /**
125
- * Generates the organization configuration section for AGENTS.md
128
+ * Generates the organization configuration section for neon.md
126
129
  */
127
130
  function getOrgConfigSection(orgId) {
128
131
  return `## Neon Project Configuration
@@ -142,35 +145,66 @@ When using any Neon MCP tools or API calls, always pass this \`org_id\` paramete
142
145
  `;
143
146
  }
144
147
  /**
145
- * Creates or updates AGENTS.md with Neon-specific best practices
148
+ * Gets the reference text to add to AGENTS.md
149
+ */
150
+ function getAgentsNeonReference() {
151
+ return `## Working with Neon Database
152
+
153
+ When the user asks to **"Get started with Neon"** or something similar, refer to the detailed guidelines in \`neon.md\`.`;
154
+ }
155
+ /**
156
+ * Creates or updates neon.md with detailed Neon guidelines
157
+ */
158
+ async function createNeonMd(orgId) {
159
+ const neonMdPath = resolve(process.cwd(), "neon.md");
160
+ try {
161
+ if (existsSync(neonMdPath)) {
162
+ log.info("neon.md already exists");
163
+ const response = await confirm({
164
+ message: "Replace existing neon.md with updated guidelines? (suggested)",
165
+ initialValue: true
166
+ });
167
+ if (isCancel(response)) return false;
168
+ if (!response) {
169
+ log.info("Keeping existing neon.md");
170
+ return true;
171
+ }
172
+ }
173
+ let content = "";
174
+ if (orgId) content += getOrgConfigSection(orgId);
175
+ content += getNeonMdTemplate();
176
+ writeFileSync(neonMdPath, content, "utf-8");
177
+ log.success(`Created neon.md with detailed guidelines at ${neonMdPath}`);
178
+ return true;
179
+ } catch (error) {
180
+ log.error(`Failed to create neon.md: ${error instanceof Error ? error.message : "Unknown error"}`);
181
+ return false;
182
+ }
183
+ }
184
+ /**
185
+ * Creates or updates AGENTS.md with a reference to neon.md
146
186
  */
147
- async function createAgentsMd(orgId) {
187
+ async function createAgentsMd() {
148
188
  const agentsPath = resolve(process.cwd(), "AGENTS.md");
149
189
  try {
190
+ const neonReference = getAgentsNeonReference();
150
191
  if (existsSync(agentsPath)) {
151
192
  const existingContent = readFileSync(agentsPath, "utf-8");
152
- if (existingContent.includes("## Neon Database Guidelines")) {
153
- log.info("Neon guidelines already exist in AGENTS.md");
193
+ if (existingContent.includes("## Working with Neon Database")) {
194
+ log.info("Neon reference already exists in AGENTS.md");
154
195
  return true;
155
196
  }
156
- const separator = "\n\n---\n\n";
157
- let content = "";
158
- if (orgId) content += getOrgConfigSection(orgId);
159
- content += getAgentsMdTemplate();
160
- writeFileSync(agentsPath, existingContent + separator + content, "utf-8");
161
- log.success(`Appended Neon best practices to existing AGENTS.md at ${agentsPath}`);
197
+ writeFileSync(agentsPath, existingContent + "\n\n---\n\n" + neonReference, "utf-8");
198
+ log.success(`Appended Neon reference to existing AGENTS.md at ${agentsPath}`);
162
199
  } else {
163
- let content = "";
164
- if (orgId) content += getOrgConfigSection(orgId);
165
- content += getAgentsMdTemplate();
166
200
  writeFileSync(agentsPath, `# AGENTS.md
167
201
 
168
202
  This file provides guidance to AI coding assistants when working with code in this project.
169
203
 
170
204
  ---
171
205
 
172
- ${content}`, "utf-8");
173
- log.success(`Created AGENTS.md with Neon best practices at ${agentsPath}`);
206
+ ${neonReference}`, "utf-8");
207
+ log.success(`Created AGENTS.md with Neon reference at ${agentsPath}`);
174
208
  }
175
209
  return true;
176
210
  } catch (error) {
@@ -195,8 +229,8 @@ async function installMCPServer() {
195
229
  if (alreadyConfigured) {
196
230
  log.info("Neon MCP Server is already configured globally");
197
231
  const response = await confirm({
198
- message: "Would you like to reconfigure it?",
199
- initialValue: false
232
+ message: "Would you like to reconfigure it? (suggested)",
233
+ initialValue: true
200
234
  });
201
235
  if (isCancel(response)) return { success: false };
202
236
  shouldReconfigure = response;
@@ -274,24 +308,40 @@ async function installMCPServer() {
274
308
  */
275
309
  async function init() {
276
310
  intro("🚀 Neon Project Initialization");
311
+ const homeDir = process.env.HOME || process.env.USERPROFILE;
312
+ if (!homeDir) {
313
+ log.error("Could not determine home directory");
314
+ process.exit(1);
315
+ }
316
+ if (!existsSync(resolve(homeDir, ".cursor"))) {
317
+ log.warn("This tool currently only supports Cursor IDE.");
318
+ log.info("We'd love to hear which IDE you're using!");
319
+ log.info("");
320
+ log.info("Please send your feedback to: init-feedback@neon.tech");
321
+ log.info("");
322
+ outro("❌ Cursor IDE is required to continue.");
323
+ process.exit(1);
324
+ }
277
325
  log.info("This will set up your project with Neon's MCP Server and AI coding best practices.");
278
- log.step("Step 1/2: Configuring Neon MCP Server");
326
+ log.step("Step 1/3: Configuring Neon MCP Server...");
279
327
  const { success: mcpSuccess, orgId } = await installMCPServer();
280
328
  if (!mcpSuccess) {
281
329
  outro("❌ Initialization cancelled or failed.");
282
330
  process.exit(1);
283
331
  }
284
- log.step("Step 2/2: Creating AGENTS.md with Neon best practices");
285
- if (!await createAgentsMd(orgId)) log.warn("Failed to create AGENTS.md, but MCP Server is configured.");
332
+ log.step("Step 2/3: Creating neon.md with detailed guidelines...");
333
+ if (!await createNeonMd(orgId)) log.warn("Failed to create neon.md, but MCP Server is configured.");
334
+ log.step("Step 3/3: Creating AGENTS.md for Cursor...");
335
+ if (!await createAgentsMd()) log.warn("Failed to create AGENTS.md, but MCP Server is configured.");
286
336
  outro("Success! Neon project initialized.");
287
337
  console.log("");
288
338
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
289
339
  console.log("");
290
340
  console.log("Next steps:");
291
341
  console.log("");
292
- console.log(" 1. Restart your AI coding assistant (Cursor, Windsurf, etc.)");
342
+ console.log(" 1. Restart Cursor");
293
343
  console.log("");
294
- console.log(" 2. Type this in your AI chat to begin:");
344
+ console.log(" 2. Type this in your Cursor chat to begin:");
295
345
  console.log("");
296
346
  console.log(" ┌──────────────────────────────────────┐");
297
347
  console.log(" │ │");
@@ -299,7 +349,8 @@ async function init() {
299
349
  console.log(" │ │");
300
350
  console.log(" └──────────────────────────────────────┘");
301
351
  console.log("");
302
- console.log("Your AI assistant now has access to Neon best practices via AGENTS.md");
352
+ console.log("Your AI assistant now has access to Neon best practices via neon.md");
353
+ console.log("(referenced in AGENTS.md for easy discovery)");
303
354
  console.log("");
304
355
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
305
356
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["selectedOrgId: string | undefined"],"sources":["../src/index.ts"],"sourcesContent":["import { exec } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { promisify } from \"node:util\";\nimport {\n\tconfirm,\n\tintro,\n\tisCancel,\n\tlog,\n\toutro,\n\tselect,\n\tspinner,\n} from \"@clack/prompts\";\n\nconst execAsync = promisify(exec);\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface MCPConfig {\n\tmcpServers: {\n\t\t[key: string]: {\n\t\t\tcommand: string;\n\t\t\targs: string[];\n\t\t\tenv?: Record<string, string>;\n\t\t};\n\t};\n}\n\ninterface NeonOrganization {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Ensures neonctl is authenticated by running a command that triggers auth if needed\n * This will automatically start the OAuth flow if the user isn't already authenticated\n */\nasync function ensureNeonctlAuth(): Promise<boolean> {\n\ttry {\n\t\t// Use spawn to show OAuth URL if authentication is needed\n\t\tconst { spawn } = await import(\"node:child_process\");\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst meProcess = spawn(\n\t\t\t\t\"npx\",\n\t\t\t\t[\"-y\", \"neon\", \"me\", \"--output\", \"json\", \"--no-analytics\"],\n\t\t\t\t{\n\t\t\t\t\tstdio: \"inherit\", // Shows OAuth URL and prompts to the user\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tmeProcess.on(\"close\", (code) => {\n\t\t\t\tif (code === 0) {\n\t\t\t\t\tresolve();\n\t\t\t\t} else {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`Authentication failed with exit code ${code}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmeProcess.on(\"error\", reject);\n\t\t});\n\n\t\treturn true;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Authentication failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn false;\n\t}\n}\n\n/**\n * Gets the OAuth access token from neonctl's stored credentials\n */\nasync function getNeonctlAccessToken(): Promise<string | null> {\n\ttry {\n\t\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\t\tif (!homeDir) return null;\n\n\t\tconst credentialsPath = resolve(\n\t\t\thomeDir,\n\t\t\t\".config\",\n\t\t\t\"neonctl\",\n\t\t\t\"credentials.json\",\n\t\t);\n\t\tif (!existsSync(credentialsPath)) return null;\n\n\t\tconst credentials = JSON.parse(readFileSync(credentialsPath, \"utf-8\"));\n\t\treturn credentials.access_token || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Creates an API key using the Neon API with the OAuth token from neonctl\n */\nasync function createApiKeyFromNeonctl(): Promise<string | null> {\n\ttry {\n\t\tconst accessToken = await getNeonctlAccessToken();\n\t\tif (!accessToken) {\n\t\t\tlog.error(\"Could not find OAuth token from neonctl\");\n\t\t\treturn null;\n\t\t}\n\n\t\t// Generate a unique key name with timestamp\n\t\tconst timestamp = new Date()\n\t\t\t.toISOString()\n\t\t\t.replace(/[:.]/g, \"-\")\n\t\t\t.slice(0, -5); // e.g., 2024-10-08T15-30-45\n\t\tconst keyName = `neonctl-init-${timestamp}`;\n\n\t\t// Call Neon API to create an API key\n\t\tconst response = await fetch(\n\t\t\t\"https://console.neon.tech/api/v2/api_keys\",\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tkey_name: keyName,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tlog.error(\n\t\t\t\t`Failed to create API key: ${response.status} ${errorText}`,\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = await response.json();\n\t\treturn data.key || null;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to create API key: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn null;\n\t}\n}\n\nasync function fetchOrganizations(): Promise<NeonOrganization[]> {\n\ttry {\n\t\tconst { stdout } = await execAsync(\n\t\t\t\"npx -y neon orgs list --output json --no-analytics\",\n\t\t\t{ maxBuffer: 1024 * 1024 },\n\t\t);\n\n\t\tconst data = JSON.parse(stdout);\n\n\t\t// The neon CLI returns an array of organizations\n\t\tconst organizations: NeonOrganization[] = Array.isArray(data)\n\t\t\t? data.map((org: { id: string; name?: string }) => ({\n\t\t\t\t\tid: org.id,\n\t\t\t\t\tname: org.name || org.id,\n\t\t\t\t}))\n\t\t\t: [];\n\n\t\treturn organizations;\n\t} catch (error) {\n\t\tlog.warn(\n\t\t\t`Unable to fetch organizations: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn [];\n\t}\n}\n\n/**\n * Gets or creates the .cursor/mcp.json configuration\n */\nfunction getMCPConfig(cursorDir: string): MCPConfig {\n\tconst mcpConfigPath = resolve(cursorDir, \"mcp.json\");\n\n\tif (existsSync(mcpConfigPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(mcpConfigPath, \"utf-8\");\n\t\t\treturn JSON.parse(content);\n\t\t} catch (_error) {\n\t\t\tlog.warn(\n\t\t\t\t\"Failed to parse existing mcp.json. Creating a new configuration.\",\n\t\t\t);\n\t\t\treturn { mcpServers: {} };\n\t\t}\n\t}\n\n\treturn { mcpServers: {} };\n}\n\n/**\n * Writes the MCP configuration to .cursor/mcp.json\n */\nfunction writeMCPConfig(cursorDir: string, config: MCPConfig): void {\n\tconst mcpConfigPath = resolve(cursorDir, \"mcp.json\");\n\n\tif (!existsSync(cursorDir)) {\n\t\tmkdirSync(cursorDir, { recursive: true });\n\t}\n\n\twriteFileSync(mcpConfigPath, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\n/**\n * Gets the AGENTS.md template with Neon-specific best practices\n */\nfunction getAgentsMdTemplate(): string {\n\tconst templatePath = resolve(__dirname, \"../src/agents-template.md\");\n\treturn readFileSync(templatePath, \"utf-8\");\n}\n\n/**\n * Generates the organization configuration section for AGENTS.md\n */\nfunction getOrgConfigSection(orgId: string): string {\n\treturn `## Neon Project Configuration\n\n> **🔴 IMPORTANT: You MUST use this organization for all Neon operations in this project.**\n\n**Organization ID:** \\`${orgId}\\`\n\nWhen using any Neon MCP tools or API calls, always pass this \\`org_id\\` parameter. The MCP server is pre-configured with this organization.\n\n**Example:**\n- When listing projects: Use \\`mcp_Neon_list_projects\\` with \\`org_id: \"${orgId}\"\\`\n- When creating resources: Always include \\`org_id: \"${orgId}\"\\` in your tool calls\n\n---\n\n`;\n}\n\n/**\n * Creates or updates AGENTS.md with Neon-specific best practices\n */\nasync function createAgentsMd(orgId?: string): Promise<boolean> {\n\tconst agentsPath = resolve(process.cwd(), \"AGENTS.md\");\n\n\ttry {\n\t\t// Check if AGENTS.md already exists\n\t\tif (existsSync(agentsPath)) {\n\t\t\t// Append to existing file\n\t\t\tconst existingContent = readFileSync(agentsPath, \"utf-8\");\n\n\t\t\t// Check if Neon section already exists to avoid duplicates\n\t\t\tif (existingContent.includes(\"## Neon Database Guidelines\")) {\n\t\t\t\tlog.info(\"Neon guidelines already exist in AGENTS.md\");\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst separator = \"\\n\\n---\\n\\n\";\n\t\t\tlet content = \"\";\n\n\t\t\t// Add org ID context if provided\n\t\t\tif (orgId) {\n\t\t\t\tcontent += getOrgConfigSection(orgId);\n\t\t\t}\n\n\t\t\tcontent += getAgentsMdTemplate();\n\n\t\t\tconst updatedContent = existingContent + separator + content;\n\t\t\twriteFileSync(agentsPath, updatedContent, \"utf-8\");\n\t\t\tlog.success(\n\t\t\t\t`Appended Neon best practices to existing AGENTS.md at ${agentsPath}`,\n\t\t\t);\n\t\t} else {\n\t\t\t// Create new file with proper header\n\t\t\tlet content = \"\";\n\n\t\t\t// Add org ID context if provided\n\t\t\tif (orgId) {\n\t\t\t\tcontent += getOrgConfigSection(orgId);\n\t\t\t}\n\n\t\t\tcontent += getAgentsMdTemplate();\n\n\t\t\tconst newContent = `# AGENTS.md\n\nThis file provides guidance to AI coding assistants when working with code in this project.\n\n---\n\n${content}`;\n\t\t\twriteFileSync(agentsPath, newContent, \"utf-8\");\n\t\t\tlog.success(\n\t\t\t\t`Created AGENTS.md with Neon best practices at ${agentsPath}`,\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to create/update AGENTS.md: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn false;\n\t}\n}\n\n/**\n * Installs Neon's MCP Server by configuring it globally in ~/.cursor/mcp.json\n * Returns the selected organization ID if one was chosen\n */\nasync function installMCPServer(): Promise<{\n\tsuccess: boolean;\n\torgId?: string;\n}> {\n\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\tif (!homeDir) {\n\t\tlog.error(\"Could not determine home directory\");\n\t\treturn { success: false };\n\t}\n\tconst cursorDir = resolve(homeDir, \".cursor\");\n\tconst config = getMCPConfig(cursorDir);\n\n\t// Check if already configured\n\tconst alreadyConfigured = Boolean(config.mcpServers.Neon);\n\tlet shouldReconfigure = false;\n\n\tif (alreadyConfigured) {\n\t\tlog.info(\"Neon MCP Server is already configured globally\");\n\t\tconst response = await confirm({\n\t\t\tmessage: \"Would you like to reconfigure it?\",\n\t\t\tinitialValue: false,\n\t\t});\n\n\t\tif (isCancel(response)) {\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tshouldReconfigure = response as boolean;\n\n\t\tif (!shouldReconfigure) {\n\t\t\tlog.info(\"Keeping existing global configuration.\");\n\t\t}\n\t}\n\n\t// Step 1: Ensure authentication (will trigger OAuth if needed)\n\tlog.step(\"Authenticating with Neon...\");\n\tlog.info(\"The authentication URL will be displayed below if needed.\");\n\tlog.info(\"\");\n\n\tconst authSpinner = spinner();\n\tauthSpinner.start(\"Waiting for authentication...\");\n\n\tconst authSuccess = await ensureNeonctlAuth();\n\n\tif (!authSuccess) {\n\t\tauthSpinner.stop(\"Authentication failed\");\n\t\treturn { success: false };\n\t}\n\n\tauthSpinner.stop(\"Authentication successful ✓\");\n\n\t// Step 2: Fetch organizations and let user select\n\tlet selectedOrgId: string | undefined;\n\n\tconst orgSpinner = spinner();\n\torgSpinner.start(\"Fetching your organizations...\");\n\tconst organizations = await fetchOrganizations();\n\torgSpinner.stop(\n\t\t`Found ${organizations.length} organization${organizations.length !== 1 ? \"s\" : \"\"}`,\n\t);\n\n\tif (organizations.length > 1) {\n\t\tconst orgChoice = await select({\n\t\t\tmessage: \"Select an organization for this project:\",\n\t\t\toptions: organizations.map((org) => ({\n\t\t\t\tvalue: org.id,\n\t\t\t\tlabel: org.name,\n\t\t\t})),\n\t\t});\n\n\t\tif (isCancel(orgChoice)) {\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tselectedOrgId = orgChoice.toString();\n\t\tconst selectedOrg = organizations.find(\n\t\t\t(org) => org.id === selectedOrgId,\n\t\t);\n\t\tlog.success(`Selected organization: ${selectedOrg?.name}`);\n\t} else if (organizations.length === 1) {\n\t\t// Only one org, auto-select it\n\t\tselectedOrgId = organizations[0].id;\n\t\tlog.info(`Using organization: ${organizations[0].name}`);\n\t} else {\n\t\t// No organizations found (personal account)\n\t\tlog.info(\"Using personal account\");\n\t}\n\n\t// If user chose not to reconfigure, we're done (but we still return the org ID)\n\tif (alreadyConfigured && !shouldReconfigure) {\n\t\treturn { success: true, orgId: selectedOrgId };\n\t}\n\n\t// Step 3: Create API key using the OAuth token\n\tconst s = spinner();\n\ts.start(\"Creating API key...\");\n\tconst apiKey = await createApiKeyFromNeonctl();\n\ts.stop(\n\t\tapiKey ? \"API key created successfully ✓\" : \"Failed to create API key\",\n\t);\n\n\tif (!apiKey) {\n\t\tlog.error(\"Could not create API key after authentication.\");\n\t\tlog.info(\n\t\t\t\"You can manually create one at: https://console.neon.tech/app/settings/api-keys\",\n\t\t);\n\t\treturn { success: false };\n\t}\n\n\t// Step 4: Configure Neon MCP Server\n\tconst args = [\"-y\", \"@neondatabase/mcp-server-neon\", \"start\", apiKey];\n\n\tconfig.mcpServers.Neon = {\n\t\tcommand: \"npx\",\n\t\targs,\n\t};\n\n\t// Write configuration\n\ttry {\n\t\twriteMCPConfig(cursorDir, config);\n\t\tlog.success(\n\t\t\t`Neon MCP Server configured globally at ${resolve(cursorDir, \"mcp.json\")}`,\n\t\t);\n\t\tlog.info(\"This configuration will be available in all your projects.\");\n\t\treturn { success: true, orgId: selectedOrgId };\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to write global configuration: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn { success: false };\n\t}\n}\n\n/**\n * Initialize Neon projects with MCP Server and AI assistant rules\n */\nexport async function init(): Promise<void> {\n\tintro(\"🚀 Neon Project Initialization\");\n\n\tlog.info(\n\t\t\"This will set up your project with Neon's MCP Server and AI coding best practices.\",\n\t);\n\n\tlog.step(\"Step 1/2: Configuring Neon MCP Server\");\n\tconst { success: mcpSuccess, orgId } = await installMCPServer();\n\n\tif (!mcpSuccess) {\n\t\toutro(\"❌ Initialization cancelled or failed.\");\n\t\tprocess.exit(1);\n\t}\n\n\tlog.step(\"Step 2/2: Creating AGENTS.md with Neon best practices\");\n\tconst agentsSuccess = await createAgentsMd(orgId);\n\n\tif (!agentsSuccess) {\n\t\tlog.warn(\"Failed to create AGENTS.md, but MCP Server is configured.\");\n\t}\n\n\toutro(\"Success! Neon project initialized.\");\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n\t);\n\tconsole.log(\"\");\n\tconsole.log(\"Next steps:\");\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\" 1. Restart your AI coding assistant (Cursor, Windsurf, etc.)\",\n\t);\n\tconsole.log(\"\");\n\tconsole.log(\" 2. Type this in your AI chat to begin:\");\n\tconsole.log(\"\");\n\tconsole.log(\" ┌──────────────────────────────────────┐\");\n\tconsole.log(\" │ │\");\n\tconsole.log(\" │ Get started with Neon │\");\n\tconsole.log(\" │ │\");\n\tconsole.log(\" └──────────────────────────────────────┘\");\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\"Your AI assistant now has access to Neon best practices via AGENTS.md\",\n\t);\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["selectedOrgId: string | undefined"],"sources":["../src/index.ts"],"sourcesContent":["import { exec } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { promisify } from \"node:util\";\nimport {\n\tconfirm,\n\tintro,\n\tisCancel,\n\tlog,\n\toutro,\n\tselect,\n\tspinner,\n} from \"@clack/prompts\";\n\nconst execAsync = promisify(exec);\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface MCPConfig {\n\tmcpServers: {\n\t\t[key: string]: {\n\t\t\tcommand: string;\n\t\t\targs: string[];\n\t\t\tenv?: Record<string, string>;\n\t\t};\n\t};\n}\n\ninterface NeonOrganization {\n\tid: string;\n\tname: string;\n}\n\n/**\n * Ensures neonctl is authenticated by running a command that triggers auth if needed\n * This will automatically start the OAuth flow if the user isn't already authenticated\n */\nasync function ensureNeonctlAuth(): Promise<boolean> {\n\ttry {\n\t\t// Use spawn to show OAuth URL if authentication is needed\n\t\tconst { spawn } = await import(\"node:child_process\");\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst meProcess = spawn(\n\t\t\t\t\"npx\",\n\t\t\t\t[\"-y\", \"neonctl\", \"me\", \"--output\", \"json\", \"--no-analytics\"],\n\t\t\t\t{\n\t\t\t\t\tstdio: \"inherit\", // Shows OAuth URL and prompts to the user\n\t\t\t\t\tshell: true, // Run through cmd.exe on Windows for proper npm command resolution\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tmeProcess.on(\"close\", (code) => {\n\t\t\t\tif (code === 0) {\n\t\t\t\t\tresolve();\n\t\t\t\t} else {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`Authentication failed with exit code ${code}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmeProcess.on(\"error\", reject);\n\t\t});\n\n\t\treturn true;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Authentication failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn false;\n\t}\n}\n\n/**\n * Gets the OAuth access token from neonctl's stored credentials\n */\nasync function getNeonctlAccessToken(): Promise<string | null> {\n\ttry {\n\t\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\t\tif (!homeDir) return null;\n\n\t\tconst credentialsPath = resolve(\n\t\t\thomeDir,\n\t\t\t\".config\",\n\t\t\t\"neonctl\",\n\t\t\t\"credentials.json\",\n\t\t);\n\t\tif (!existsSync(credentialsPath)) return null;\n\n\t\tconst credentials = JSON.parse(readFileSync(credentialsPath, \"utf-8\"));\n\t\treturn credentials.access_token || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Creates an API key using the Neon API with the OAuth token from neonctl\n */\nasync function createApiKeyFromNeonctl(): Promise<string | null> {\n\ttry {\n\t\tconst accessToken = await getNeonctlAccessToken();\n\t\tif (!accessToken) {\n\t\t\tlog.error(\"Could not find OAuth token from neonctl\");\n\t\t\treturn null;\n\t\t}\n\n\t\t// Generate a unique key name with timestamp\n\t\tconst timestamp = new Date()\n\t\t\t.toISOString()\n\t\t\t.replace(/[:.]/g, \"-\")\n\t\t\t.slice(0, -5); // e.g., 2024-10-08T15-30-45\n\t\tconst keyName = `neonctl-init-${timestamp}`;\n\n\t\t// Call Neon API to create an API key\n\t\tconst response = await fetch(\n\t\t\t\"https://console.neon.tech/api/v2/api_keys\",\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tkey_name: keyName,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tlog.error(\n\t\t\t\t`Failed to create API key: ${response.status} ${errorText}`,\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = await response.json();\n\t\treturn data.key || null;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to create API key: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn null;\n\t}\n}\n\nasync function fetchOrganizations(): Promise<NeonOrganization[]> {\n\ttry {\n\t\tconst { stdout } = await execAsync(\n\t\t\t\"npx -y neonctl orgs list --output json --no-analytics\",\n\t\t\t{ maxBuffer: 1024 * 1024 },\n\t\t);\n\n\t\tconst data = JSON.parse(stdout);\n\n\t\t// The neon CLI returns an array of organizations\n\t\tconst organizations: NeonOrganization[] = Array.isArray(data)\n\t\t\t? data.map((org: { id: string; name?: string }) => ({\n\t\t\t\t\tid: org.id,\n\t\t\t\t\tname: org.name || org.id,\n\t\t\t\t}))\n\t\t\t: [];\n\n\t\treturn organizations;\n\t} catch (error) {\n\t\tlog.warn(\n\t\t\t`Unable to fetch organizations: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn [];\n\t}\n}\n\n/**\n * Gets or creates the .cursor/mcp.json configuration\n */\nfunction getMCPConfig(cursorDir: string): MCPConfig {\n\tconst mcpConfigPath = resolve(cursorDir, \"mcp.json\");\n\n\tif (existsSync(mcpConfigPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(mcpConfigPath, \"utf-8\");\n\t\t\treturn JSON.parse(content);\n\t\t} catch (_error) {\n\t\t\tlog.warn(\n\t\t\t\t\"Failed to parse existing mcp.json. Creating a new configuration.\",\n\t\t\t);\n\t\t\treturn { mcpServers: {} };\n\t\t}\n\t}\n\n\treturn { mcpServers: {} };\n}\n\n/**\n * Writes the MCP configuration to .cursor/mcp.json\n */\nfunction writeMCPConfig(cursorDir: string, config: MCPConfig): void {\n\tconst mcpConfigPath = resolve(cursorDir, \"mcp.json\");\n\n\tif (!existsSync(cursorDir)) {\n\t\tmkdirSync(cursorDir, { recursive: true });\n\t}\n\n\twriteFileSync(mcpConfigPath, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\n/**\n * Gets the neon.md template with Neon-specific best practices\n */\nfunction getNeonMdTemplate(): string {\n\tconst templatePath = resolve(__dirname, \"../src/agents-template.md\");\n\treturn readFileSync(templatePath, \"utf-8\");\n}\n\n/**\n * Generates the organization configuration section for neon.md\n */\nfunction getOrgConfigSection(orgId: string): string {\n\treturn `## Neon Project Configuration\n\n> **🔴 IMPORTANT: You MUST use this organization for all Neon operations in this project.**\n\n**Organization ID:** \\`${orgId}\\`\n\nWhen using any Neon MCP tools or API calls, always pass this \\`org_id\\` parameter. The MCP server is pre-configured with this organization.\n\n**Example:**\n- When listing projects: Use \\`mcp_Neon_list_projects\\` with \\`org_id: \"${orgId}\"\\`\n- When creating resources: Always include \\`org_id: \"${orgId}\"\\` in your tool calls\n\n---\n\n`;\n}\n\n/**\n * Gets the reference text to add to AGENTS.md\n */\nfunction getAgentsNeonReference(): string {\n\treturn `## Working with Neon Database\n\nWhen the user asks to **\"Get started with Neon\"** or something similar, refer to the detailed guidelines in \\`neon.md\\`.`;\n}\n\n/**\n * Creates or updates neon.md with detailed Neon guidelines\n */\nasync function createNeonMd(orgId?: string): Promise<boolean> {\n\tconst neonMdPath = resolve(process.cwd(), \"neon.md\");\n\n\ttry {\n\t\t// Check if neon.md already exists\n\t\tif (existsSync(neonMdPath)) {\n\t\t\tlog.info(\"neon.md already exists\");\n\t\t\tconst response = await confirm({\n\t\t\t\tmessage:\n\t\t\t\t\t\"Replace existing neon.md with updated guidelines? (suggested)\",\n\t\t\t\tinitialValue: true,\n\t\t\t});\n\n\t\t\tif (isCancel(response)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (!response) {\n\t\t\t\tlog.info(\"Keeping existing neon.md\");\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tlet content = \"\";\n\n\t\t// Add org ID context if provided\n\t\tif (orgId) {\n\t\t\tcontent += getOrgConfigSection(orgId);\n\t\t}\n\n\t\tcontent += getNeonMdTemplate();\n\n\t\twriteFileSync(neonMdPath, content, \"utf-8\");\n\t\tlog.success(\n\t\t\t`Created neon.md with detailed guidelines at ${neonMdPath}`,\n\t\t);\n\t\treturn true;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to create neon.md: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn false;\n\t}\n}\n\n/**\n * Creates or updates AGENTS.md with a reference to neon.md\n */\nasync function createAgentsMd(): Promise<boolean> {\n\tconst agentsPath = resolve(process.cwd(), \"AGENTS.md\");\n\n\ttry {\n\t\tconst neonReference = getAgentsNeonReference();\n\n\t\t// Check if AGENTS.md already exists\n\t\tif (existsSync(agentsPath)) {\n\t\t\t// Append to existing file\n\t\t\tconst existingContent = readFileSync(agentsPath, \"utf-8\");\n\n\t\t\t// Check if Neon section already exists to avoid duplicates\n\t\t\tif (existingContent.includes(\"## Working with Neon Database\")) {\n\t\t\t\tlog.info(\"Neon reference already exists in AGENTS.md\");\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst separator = \"\\n\\n---\\n\\n\";\n\t\t\tconst updatedContent = existingContent + separator + neonReference;\n\t\t\twriteFileSync(agentsPath, updatedContent, \"utf-8\");\n\t\t\tlog.success(\n\t\t\t\t`Appended Neon reference to existing AGENTS.md at ${agentsPath}`,\n\t\t\t);\n\t\t} else {\n\t\t\t// Create new file with proper header\n\t\t\tconst newContent = `# AGENTS.md\n\nThis file provides guidance to AI coding assistants when working with code in this project.\n\n---\n\n${neonReference}`;\n\t\t\twriteFileSync(agentsPath, newContent, \"utf-8\");\n\t\t\tlog.success(\n\t\t\t\t`Created AGENTS.md with Neon reference at ${agentsPath}`,\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to create/update AGENTS.md: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn false;\n\t}\n}\n\n/**\n * Installs Neon's MCP Server by configuring it globally in ~/.cursor/mcp.json\n * Returns the selected organization ID if one was chosen\n */\nasync function installMCPServer(): Promise<{\n\tsuccess: boolean;\n\torgId?: string;\n}> {\n\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\tif (!homeDir) {\n\t\tlog.error(\"Could not determine home directory\");\n\t\treturn { success: false };\n\t}\n\tconst cursorDir = resolve(homeDir, \".cursor\");\n\tconst config = getMCPConfig(cursorDir);\n\n\t// Check if already configured\n\tconst alreadyConfigured = Boolean(config.mcpServers.Neon);\n\tlet shouldReconfigure = false;\n\n\tif (alreadyConfigured) {\n\t\tlog.info(\"Neon MCP Server is already configured globally\");\n\t\tconst response = await confirm({\n\t\t\tmessage: \"Would you like to reconfigure it? (suggested)\",\n\t\t\tinitialValue: true,\n\t\t});\n\n\t\tif (isCancel(response)) {\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tshouldReconfigure = response as boolean;\n\n\t\tif (!shouldReconfigure) {\n\t\t\tlog.info(\"Keeping existing global configuration.\");\n\t\t}\n\t}\n\n\t// Step 1: Ensure authentication (will trigger OAuth if needed)\n\tlog.step(\"Authenticating with Neon...\");\n\tlog.info(\"The authentication URL will be displayed below if needed.\");\n\tlog.info(\"\");\n\n\tconst authSpinner = spinner();\n\tauthSpinner.start(\"Waiting for authentication...\");\n\n\tconst authSuccess = await ensureNeonctlAuth();\n\n\tif (!authSuccess) {\n\t\tauthSpinner.stop(\"Authentication failed\");\n\t\treturn { success: false };\n\t}\n\n\tauthSpinner.stop(\"Authentication successful ✓\");\n\n\t// Step 2: Fetch organizations and let user select\n\tlet selectedOrgId: string | undefined;\n\n\tconst orgSpinner = spinner();\n\torgSpinner.start(\"Fetching your organizations...\");\n\tconst organizations = await fetchOrganizations();\n\torgSpinner.stop(\n\t\t`Found ${organizations.length} organization${organizations.length !== 1 ? \"s\" : \"\"}`,\n\t);\n\n\tif (organizations.length > 1) {\n\t\tconst orgChoice = await select({\n\t\t\tmessage: \"Select an organization for this project:\",\n\t\t\toptions: organizations.map((org) => ({\n\t\t\t\tvalue: org.id,\n\t\t\t\tlabel: org.name,\n\t\t\t})),\n\t\t});\n\n\t\tif (isCancel(orgChoice)) {\n\t\t\treturn { success: false };\n\t\t}\n\n\t\tselectedOrgId = orgChoice.toString();\n\t\tconst selectedOrg = organizations.find(\n\t\t\t(org) => org.id === selectedOrgId,\n\t\t);\n\t\tlog.success(`Selected organization: ${selectedOrg?.name}`);\n\t} else if (organizations.length === 1) {\n\t\t// Only one org, auto-select it\n\t\tselectedOrgId = organizations[0].id;\n\t\tlog.info(`Using organization: ${organizations[0].name}`);\n\t} else {\n\t\t// No organizations found (personal account)\n\t\tlog.info(\"Using personal account\");\n\t}\n\n\t// If user chose not to reconfigure, we're done (but we still return the org ID)\n\tif (alreadyConfigured && !shouldReconfigure) {\n\t\treturn { success: true, orgId: selectedOrgId };\n\t}\n\n\t// Step 3: Create API key using the OAuth token\n\tconst s = spinner();\n\ts.start(\"Creating API key...\");\n\tconst apiKey = await createApiKeyFromNeonctl();\n\ts.stop(\n\t\tapiKey ? \"API key created successfully ✓\" : \"Failed to create API key\",\n\t);\n\n\tif (!apiKey) {\n\t\tlog.error(\"Could not create API key after authentication.\");\n\t\tlog.info(\n\t\t\t\"You can manually create one at: https://console.neon.tech/app/settings/api-keys\",\n\t\t);\n\t\treturn { success: false };\n\t}\n\n\t// Step 4: Configure Neon MCP Server\n\tconst args = [\"-y\", \"@neondatabase/mcp-server-neon\", \"start\", apiKey];\n\n\tconfig.mcpServers.Neon = {\n\t\tcommand: \"npx\",\n\t\targs,\n\t};\n\n\t// Write configuration\n\ttry {\n\t\twriteMCPConfig(cursorDir, config);\n\t\tlog.success(\n\t\t\t`Neon MCP Server configured globally at ${resolve(cursorDir, \"mcp.json\")}`,\n\t\t);\n\t\tlog.info(\"This configuration will be available in all your projects.\");\n\t\treturn { success: true, orgId: selectedOrgId };\n\t} catch (error) {\n\t\tlog.error(\n\t\t\t`Failed to write global configuration: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t\treturn { success: false };\n\t}\n}\n\n/**\n * Initialize Neon projects with MCP Server and AI assistant rules\n */\nexport async function init(): Promise<void> {\n\tintro(\"🚀 Neon Project Initialization\");\n\n\t// Check if Cursor is installed\n\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\tif (!homeDir) {\n\t\tlog.error(\"Could not determine home directory\");\n\t\tprocess.exit(1);\n\t}\n\n\tconst cursorDir = resolve(homeDir, \".cursor\");\n\tif (!existsSync(cursorDir)) {\n\t\tlog.warn(\"This tool currently only supports Cursor IDE.\");\n\t\tlog.info(\"We'd love to hear which IDE you're using!\");\n\t\tlog.info(\"\");\n\t\tlog.info(\"Please send your feedback to: init-feedback@neon.tech\");\n\t\tlog.info(\"\");\n\t\toutro(\"❌ Cursor IDE is required to continue.\");\n\t\tprocess.exit(1);\n\t}\n\n\tlog.info(\n\t\t\"This will set up your project with Neon's MCP Server and AI coding best practices.\",\n\t);\n\n\tlog.step(\"Step 1/3: Configuring Neon MCP Server...\");\n\tconst { success: mcpSuccess, orgId } = await installMCPServer();\n\n\tif (!mcpSuccess) {\n\t\toutro(\"❌ Initialization cancelled or failed.\");\n\t\tprocess.exit(1);\n\t}\n\n\tlog.step(\"Step 2/3: Creating neon.md with detailed guidelines...\");\n\tconst neonMdSuccess = await createNeonMd(orgId);\n\n\tif (!neonMdSuccess) {\n\t\tlog.warn(\"Failed to create neon.md, but MCP Server is configured.\");\n\t}\n\n\tlog.step(\"Step 3/3: Creating AGENTS.md for Cursor...\");\n\tconst agentsSuccess = await createAgentsMd();\n\n\tif (!agentsSuccess) {\n\t\tlog.warn(\"Failed to create AGENTS.md, but MCP Server is configured.\");\n\t}\n\n\toutro(\"Success! Neon project initialized.\");\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n\t);\n\tconsole.log(\"\");\n\tconsole.log(\"Next steps:\");\n\tconsole.log(\"\");\n\tconsole.log(\" 1. Restart Cursor\");\n\tconsole.log(\"\");\n\tconsole.log(\" 2. Type this in your Cursor chat to begin:\");\n\tconsole.log(\"\");\n\tconsole.log(\" ┌──────────────────────────────────────┐\");\n\tconsole.log(\" │ │\");\n\tconsole.log(\" │ Get started with Neon │\");\n\tconsole.log(\" │ │\");\n\tconsole.log(\" └──────────────────────────────────────┘\");\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\"Your AI assistant now has access to Neon best practices via neon.md\",\n\t);\n\tconsole.log(\"(referenced in AGENTS.md for easy discovery)\");\n\tconsole.log(\"\");\n\tconsole.log(\n\t\t\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\",\n\t);\n}\n"],"mappings":";;;;;;;;AAeA,MAAM,YAAY,UAAU,KAAK;AAGjC,MAAM,YAAY,QADC,cAAc,OAAO,KAAK,IAAI,CACZ;;;;;AAqBrC,eAAe,oBAAsC;AACpD,KAAI;EAEH,MAAM,EAAE,UAAU,MAAM,OAAO;AAE/B,QAAM,IAAI,SAAe,WAAS,WAAW;GAC5C,MAAM,YAAY,MACjB,OACA;IAAC;IAAM;IAAW;IAAM;IAAY;IAAQ;IAAiB,EAC7D;IACC,OAAO;IACP,OAAO;IACP,CACD;AAED,aAAU,GAAG,UAAU,SAAS;AAC/B,QAAI,SAAS,EACZ,YAAS;QAET,wBACC,IAAI,MACH,wCAAwC,OACxC,CACD;KAED;AAEF,aAAU,GAAG,SAAS,OAAO;IAC5B;AAEF,SAAO;UACC,OAAO;AACf,MAAI,MACH,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,kBACnE;AACD,SAAO;;;;;;AAOT,eAAe,wBAAgD;AAC9D,KAAI;EACH,MAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ,IAAI;AAChD,MAAI,CAAC,QAAS,QAAO;EAErB,MAAM,kBAAkB,QACvB,SACA,WACA,WACA,mBACA;AACD,MAAI,CAAC,WAAW,gBAAgB,CAAE,QAAO;AAGzC,SADoB,KAAK,MAAM,aAAa,iBAAiB,QAAQ,CAAC,CACnD,gBAAgB;SAC5B;AACP,SAAO;;;;;;AAOT,eAAe,0BAAkD;AAChE,KAAI;EACH,MAAM,cAAc,MAAM,uBAAuB;AACjD,MAAI,CAAC,aAAa;AACjB,OAAI,MAAM,0CAA0C;AACpD,UAAO;;EAQR,MAAM,UAAU,iCAJE,IAAI,MAAM,EAC1B,aAAa,CACb,QAAQ,SAAS,IAAI,CACrB,MAAM,GAAG,GAAG;EAId,MAAM,WAAW,MAAM,MACtB,6CACA;GACC,QAAQ;GACR,SAAS;IACR,eAAe,UAAU;IACzB,gBAAgB;IAChB;GACD,MAAM,KAAK,UAAU,EACpB,UAAU,SACV,CAAC;GACF,CACD;AAED,MAAI,CAAC,SAAS,IAAI;GACjB,MAAM,YAAY,MAAM,SAAS,MAAM;AACvC,OAAI,MACH,6BAA6B,SAAS,OAAO,GAAG,YAChD;AACD,UAAO;;AAIR,UADa,MAAM,SAAS,MAAM,EACtB,OAAO;UACX,OAAO;AACf,MAAI,MACH,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,kBACtE;AACD,SAAO;;;AAIT,eAAe,qBAAkD;AAChE,KAAI;EACH,MAAM,EAAE,WAAW,MAAM,UACxB,yDACA,EAAE,WAAW,OAAO,MAAM,CAC1B;EAED,MAAM,OAAO,KAAK,MAAM,OAAO;AAU/B,SAP0C,MAAM,QAAQ,KAAK,GAC1D,KAAK,KAAK,SAAwC;GAClD,IAAI,IAAI;GACR,MAAM,IAAI,QAAQ,IAAI;GACtB,EAAE,GACF,EAAE;UAGG,OAAO;AACf,MAAI,KACH,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,kBAC3E;AACD,SAAO,EAAE;;;;;;AAOX,SAAS,aAAa,WAA8B;CACnD,MAAM,gBAAgB,QAAQ,WAAW,WAAW;AAEpD,KAAI,WAAW,cAAc,CAC5B,KAAI;EACH,MAAM,UAAU,aAAa,eAAe,QAAQ;AACpD,SAAO,KAAK,MAAM,QAAQ;UAClB,QAAQ;AAChB,MAAI,KACH,mEACA;AACD,SAAO,EAAE,YAAY,EAAE,EAAE;;AAI3B,QAAO,EAAE,YAAY,EAAE,EAAE;;;;;AAM1B,SAAS,eAAe,WAAmB,QAAyB;CACnE,MAAM,gBAAgB,QAAQ,WAAW,WAAW;AAEpD,KAAI,CAAC,WAAW,UAAU,CACzB,WAAU,WAAW,EAAE,WAAW,MAAM,CAAC;AAG1C,eAAc,eAAe,KAAK,UAAU,QAAQ,MAAM,EAAE,EAAE,QAAQ;;;;;AAMvE,SAAS,oBAA4B;AAEpC,QAAO,aADc,QAAQ,WAAW,4BAA4B,EAClC,QAAQ;;;;;AAM3C,SAAS,oBAAoB,OAAuB;AACnD,QAAO;;;;yBAIiB,MAAM;;;;;0EAK2C,MAAM;uDACzB,MAAM;;;;;;;;;AAU7D,SAAS,yBAAiC;AACzC,QAAO;;;;;;;AAQR,eAAe,aAAa,OAAkC;CAC7D,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,UAAU;AAEpD,KAAI;AAEH,MAAI,WAAW,WAAW,EAAE;AAC3B,OAAI,KAAK,yBAAyB;GAClC,MAAM,WAAW,MAAM,QAAQ;IAC9B,SACC;IACD,cAAc;IACd,CAAC;AAEF,OAAI,SAAS,SAAS,CACrB,QAAO;AAGR,OAAI,CAAC,UAAU;AACd,QAAI,KAAK,2BAA2B;AACpC,WAAO;;;EAIT,IAAI,UAAU;AAGd,MAAI,MACH,YAAW,oBAAoB,MAAM;AAGtC,aAAW,mBAAmB;AAE9B,gBAAc,YAAY,SAAS,QAAQ;AAC3C,MAAI,QACH,+CAA+C,aAC/C;AACD,SAAO;UACC,OAAO;AACf,MAAI,MACH,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,kBACtE;AACD,SAAO;;;;;;AAOT,eAAe,iBAAmC;CACjD,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,YAAY;AAEtD,KAAI;EACH,MAAM,gBAAgB,wBAAwB;AAG9C,MAAI,WAAW,WAAW,EAAE;GAE3B,MAAM,kBAAkB,aAAa,YAAY,QAAQ;AAGzD,OAAI,gBAAgB,SAAS,gCAAgC,EAAE;AAC9D,QAAI,KAAK,6CAA6C;AACtD,WAAO;;AAKR,iBAAc,YADS,kBADL,gBACmC,eACX,QAAQ;AAClD,OAAI,QACH,oDAAoD,aACpD;SACK;AASN,iBAAc,YAPK;;;;;;EAMpB,iBACuC,QAAQ;AAC9C,OAAI,QACH,4CAA4C,aAC5C;;AAEF,SAAO;UACC,OAAO;AACf,MAAI,MACH,sCAAsC,iBAAiB,QAAQ,MAAM,UAAU,kBAC/E;AACD,SAAO;;;;;;;AAQT,eAAe,mBAGZ;CACF,MAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ,IAAI;AAChD,KAAI,CAAC,SAAS;AACb,MAAI,MAAM,qCAAqC;AAC/C,SAAO,EAAE,SAAS,OAAO;;CAE1B,MAAM,YAAY,QAAQ,SAAS,UAAU;CAC7C,MAAM,SAAS,aAAa,UAAU;CAGtC,MAAM,oBAAoB,QAAQ,OAAO,WAAW,KAAK;CACzD,IAAI,oBAAoB;AAExB,KAAI,mBAAmB;AACtB,MAAI,KAAK,iDAAiD;EAC1D,MAAM,WAAW,MAAM,QAAQ;GAC9B,SAAS;GACT,cAAc;GACd,CAAC;AAEF,MAAI,SAAS,SAAS,CACrB,QAAO,EAAE,SAAS,OAAO;AAG1B,sBAAoB;AAEpB,MAAI,CAAC,kBACJ,KAAI,KAAK,yCAAyC;;AAKpD,KAAI,KAAK,8BAA8B;AACvC,KAAI,KAAK,4DAA4D;AACrE,KAAI,KAAK,GAAG;CAEZ,MAAM,cAAc,SAAS;AAC7B,aAAY,MAAM,gCAAgC;AAIlD,KAAI,CAFgB,MAAM,mBAAmB,EAE3B;AACjB,cAAY,KAAK,wBAAwB;AACzC,SAAO,EAAE,SAAS,OAAO;;AAG1B,aAAY,KAAK,8BAA8B;CAG/C,IAAIA;CAEJ,MAAM,aAAa,SAAS;AAC5B,YAAW,MAAM,iCAAiC;CAClD,MAAM,gBAAgB,MAAM,oBAAoB;AAChD,YAAW,KACV,SAAS,cAAc,OAAO,eAAe,cAAc,WAAW,IAAI,MAAM,KAChF;AAED,KAAI,cAAc,SAAS,GAAG;EAC7B,MAAM,YAAY,MAAM,OAAO;GAC9B,SAAS;GACT,SAAS,cAAc,KAAK,SAAS;IACpC,OAAO,IAAI;IACX,OAAO,IAAI;IACX,EAAE;GACH,CAAC;AAEF,MAAI,SAAS,UAAU,CACtB,QAAO,EAAE,SAAS,OAAO;AAG1B,kBAAgB,UAAU,UAAU;EACpC,MAAM,cAAc,cAAc,MAChC,QAAQ,IAAI,OAAO,cACpB;AACD,MAAI,QAAQ,0BAA0B,aAAa,OAAO;YAChD,cAAc,WAAW,GAAG;AAEtC,kBAAgB,cAAc,GAAG;AACjC,MAAI,KAAK,uBAAuB,cAAc,GAAG,OAAO;OAGxD,KAAI,KAAK,yBAAyB;AAInC,KAAI,qBAAqB,CAAC,kBACzB,QAAO;EAAE,SAAS;EAAM,OAAO;EAAe;CAI/C,MAAM,IAAI,SAAS;AACnB,GAAE,MAAM,sBAAsB;CAC9B,MAAM,SAAS,MAAM,yBAAyB;AAC9C,GAAE,KACD,SAAS,mCAAmC,2BAC5C;AAED,KAAI,CAAC,QAAQ;AACZ,MAAI,MAAM,iDAAiD;AAC3D,MAAI,KACH,kFACA;AACD,SAAO,EAAE,SAAS,OAAO;;CAI1B,MAAM,OAAO;EAAC;EAAM;EAAiC;EAAS;EAAO;AAErE,QAAO,WAAW,OAAO;EACxB,SAAS;EACT;EACA;AAGD,KAAI;AACH,iBAAe,WAAW,OAAO;AACjC,MAAI,QACH,0CAA0C,QAAQ,WAAW,WAAW,GACxE;AACD,MAAI,KAAK,6DAA6D;AACtE,SAAO;GAAE,SAAS;GAAM,OAAO;GAAe;UACtC,OAAO;AACf,MAAI,MACH,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,kBAClF;AACD,SAAO,EAAE,SAAS,OAAO;;;;;;AAO3B,eAAsB,OAAsB;AAC3C,OAAM,iCAAiC;CAGvC,MAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ,IAAI;AAChD,KAAI,CAAC,SAAS;AACb,MAAI,MAAM,qCAAqC;AAC/C,UAAQ,KAAK,EAAE;;AAIhB,KAAI,CAAC,WADa,QAAQ,SAAS,UAAU,CACnB,EAAE;AAC3B,MAAI,KAAK,gDAAgD;AACzD,MAAI,KAAK,4CAA4C;AACrD,MAAI,KAAK,GAAG;AACZ,MAAI,KAAK,wDAAwD;AACjE,MAAI,KAAK,GAAG;AACZ,QAAM,wCAAwC;AAC9C,UAAQ,KAAK,EAAE;;AAGhB,KAAI,KACH,qFACA;AAED,KAAI,KAAK,2CAA2C;CACpD,MAAM,EAAE,SAAS,YAAY,UAAU,MAAM,kBAAkB;AAE/D,KAAI,CAAC,YAAY;AAChB,QAAM,wCAAwC;AAC9C,UAAQ,KAAK,EAAE;;AAGhB,KAAI,KAAK,yDAAyD;AAGlE,KAAI,CAFkB,MAAM,aAAa,MAAM,CAG9C,KAAI,KAAK,0DAA0D;AAGpE,KAAI,KAAK,6CAA6C;AAGtD,KAAI,CAFkB,MAAM,gBAAgB,CAG3C,KAAI,KAAK,4DAA4D;AAGtE,OAAM,qCAAqC;AAC3C,SAAQ,IAAI,GAAG;AACf,SAAQ,IACP,sEACA;AACD,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,cAAc;AAC1B,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,wBAAwB;AACpC,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,iDAAiD;AAC7D,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,kDAAkD;AAC9D,SAAQ,IAAI,kDAAkD;AAC9D,SAAQ,IAAI,kDAAkD;AAC9D,SAAQ,IAAI,kDAAkD;AAC9D,SAAQ,IAAI,kDAAkD;AAC9D,SAAQ,IAAI,GAAG;AACf,SAAQ,IACP,sEACA;AACD,SAAQ,IAAI,+CAA+C;AAC3D,SAAQ,IAAI,GAAG;AACf,SAAQ,IACP,sEACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neon-init",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "Initialize Neon projects",
5
5
  "keywords": [
6
6
  "neon",