neon-init 0.13.1 → 0.15.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.
Files changed (117) hide show
  1. package/dist/cli.js +368 -33
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.d.ts +15 -3
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +220 -41
  6. package/dist/index.js.map +1 -1
  7. package/dist/interactive.d.ts +12 -0
  8. package/dist/interactive.d.ts.map +1 -0
  9. package/dist/interactive.js +495 -0
  10. package/dist/interactive.js.map +1 -0
  11. package/dist/lib/agents.d.ts +23 -0
  12. package/dist/lib/agents.d.ts.map +1 -0
  13. package/dist/lib/agents.js +148 -0
  14. package/dist/lib/agents.js.map +1 -0
  15. package/dist/lib/auth.d.ts +10 -3
  16. package/dist/lib/auth.d.ts.map +1 -1
  17. package/dist/lib/auth.js +20 -13
  18. package/dist/lib/auth.js.map +1 -1
  19. package/dist/lib/bootstrap.d.ts +30 -0
  20. package/dist/lib/bootstrap.d.ts.map +1 -0
  21. package/dist/lib/bootstrap.js +61 -0
  22. package/dist/lib/bootstrap.js.map +1 -0
  23. package/dist/lib/build-config.d.ts +5 -0
  24. package/dist/lib/build-config.d.ts.map +1 -0
  25. package/dist/lib/build-config.js +6 -0
  26. package/dist/lib/build-config.js.map +1 -0
  27. package/dist/lib/detect-agent.d.ts +22 -0
  28. package/dist/lib/detect-agent.d.ts.map +1 -0
  29. package/dist/lib/detect-agent.js +65 -0
  30. package/dist/lib/detect-agent.js.map +1 -0
  31. package/dist/lib/editors.d.ts.map +1 -1
  32. package/dist/lib/editors.js +1 -2
  33. package/dist/lib/editors.js.map +1 -1
  34. package/dist/lib/extension.d.ts +11 -3
  35. package/dist/lib/extension.d.ts.map +1 -1
  36. package/dist/lib/extension.js +29 -9
  37. package/dist/lib/extension.js.map +1 -1
  38. package/dist/lib/inspect.d.ts +28 -0
  39. package/dist/lib/inspect.d.ts.map +1 -0
  40. package/dist/lib/inspect.js +190 -0
  41. package/dist/lib/inspect.js.map +1 -0
  42. package/dist/lib/install.d.ts +10 -4
  43. package/dist/lib/install.d.ts.map +1 -1
  44. package/dist/lib/install.js +74 -71
  45. package/dist/lib/install.js.map +1 -1
  46. package/dist/lib/neonctl.d.ts +32 -0
  47. package/dist/lib/neonctl.d.ts.map +1 -0
  48. package/dist/lib/neonctl.js +149 -0
  49. package/dist/lib/neonctl.js.map +1 -0
  50. package/dist/lib/phases/auth.d.ts +12 -0
  51. package/dist/lib/phases/auth.d.ts.map +1 -0
  52. package/dist/lib/phases/auth.js +188 -0
  53. package/dist/lib/phases/auth.js.map +1 -0
  54. package/dist/lib/phases/cleanup.d.ts +12 -0
  55. package/dist/lib/phases/cleanup.d.ts.map +1 -0
  56. package/dist/lib/phases/cleanup.js +29 -0
  57. package/dist/lib/phases/cleanup.js.map +1 -0
  58. package/dist/lib/phases/db.d.ts +17 -0
  59. package/dist/lib/phases/db.d.ts.map +1 -0
  60. package/dist/lib/phases/db.js +258 -0
  61. package/dist/lib/phases/db.js.map +1 -0
  62. package/dist/lib/phases/getting-started.d.ts +26 -0
  63. package/dist/lib/phases/getting-started.d.ts.map +1 -0
  64. package/dist/lib/phases/getting-started.js +195 -0
  65. package/dist/lib/phases/getting-started.js.map +1 -0
  66. package/dist/lib/phases/mcp.d.ts +15 -0
  67. package/dist/lib/phases/mcp.d.ts.map +1 -0
  68. package/dist/lib/phases/mcp.js +179 -0
  69. package/dist/lib/phases/mcp.js.map +1 -0
  70. package/dist/lib/phases/migrations.d.ts +14 -0
  71. package/dist/lib/phases/migrations.d.ts.map +1 -0
  72. package/dist/lib/phases/migrations.js +239 -0
  73. package/dist/lib/phases/migrations.js.map +1 -0
  74. package/dist/lib/phases/neon-auth.d.ts +13 -0
  75. package/dist/lib/phases/neon-auth.d.ts.map +1 -0
  76. package/dist/lib/phases/neon-auth.js +117 -0
  77. package/dist/lib/phases/neon-auth.js.map +1 -0
  78. package/dist/lib/phases/setup.d.ts +41 -0
  79. package/dist/lib/phases/setup.d.ts.map +1 -0
  80. package/dist/lib/phases/setup.js +689 -0
  81. package/dist/lib/phases/setup.js.map +1 -0
  82. package/dist/lib/phases/skills.d.ts +14 -0
  83. package/dist/lib/phases/skills.d.ts.map +1 -0
  84. package/dist/lib/phases/skills.js +80 -0
  85. package/dist/lib/phases/skills.js.map +1 -0
  86. package/dist/lib/phases/status.d.ts +10 -0
  87. package/dist/lib/phases/status.d.ts.map +1 -0
  88. package/dist/lib/phases/status.js +65 -0
  89. package/dist/lib/phases/status.js.map +1 -0
  90. package/dist/lib/resolve-context.d.ts +19 -0
  91. package/dist/lib/resolve-context.d.ts.map +1 -0
  92. package/dist/lib/resolve-context.js +112 -0
  93. package/dist/lib/resolve-context.js.map +1 -0
  94. package/dist/lib/route-command.d.ts +8 -0
  95. package/dist/lib/route-command.d.ts.map +1 -0
  96. package/dist/lib/route-command.js +195 -0
  97. package/dist/lib/route-command.js.map +1 -0
  98. package/dist/lib/skills.d.ts +21 -4
  99. package/dist/lib/skills.d.ts.map +1 -1
  100. package/dist/lib/skills.js +129 -22
  101. package/dist/lib/skills.js.map +1 -1
  102. package/dist/lib/types.d.ts +146 -13
  103. package/dist/lib/types.d.ts.map +1 -1
  104. package/dist/lib/types.js +1 -1
  105. package/dist/lib/vsix.d.ts +15 -0
  106. package/dist/lib/vsix.d.ts.map +1 -0
  107. package/dist/lib/vsix.js +91 -0
  108. package/dist/lib/vsix.js.map +1 -0
  109. package/dist/v2.d.ts +31 -0
  110. package/dist/v2.d.ts.map +1 -0
  111. package/dist/v2.js +147 -0
  112. package/dist/v2.js.map +1 -0
  113. package/package.json +9 -4
  114. package/dist/lib/mcp-config.d.ts +0 -24
  115. package/dist/lib/mcp-config.d.ts.map +0 -1
  116. package/dist/lib/mcp-config.js +0 -51
  117. package/dist/lib/mcp-config.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,73 +1,214 @@
1
+ import { ALL_CONFIGURABLE_AGENTS } from "./lib/agents.js";
2
+ import { isAuthenticated } from "./lib/auth.js";
1
3
  import { detectAvailableEditors } from "./lib/editors.js";
2
4
  import { usesExtension } from "./lib/extension.js";
5
+ import { SKILL_REFERENCE_URLS, fetchSkillContent, installAgentSkills } from "./lib/skills.js";
6
+ import { interactiveInit } from "./interactive.js";
7
+ import { handleAuthPhase } from "./lib/phases/auth.js";
8
+ import { handleDbPhase } from "./lib/phases/db.js";
9
+ import { handleMcpPhase } from "./lib/phases/mcp.js";
10
+ import { handleMigrationsPhase } from "./lib/phases/migrations.js";
11
+ import { handleNeonAuthPhase } from "./lib/phases/neon-auth.js";
12
+ import { handleSkillsPhase } from "./lib/phases/skills.js";
13
+ import { handleStatusPhase } from "./lib/phases/status.js";
14
+ import { orchestrate } from "./v2.js";
3
15
  import { installNeon } from "./lib/install.js";
4
- import { installAgentSkills } from "./lib/skills.js";
5
- import { confirm, intro, isCancel, log, multiselect, note, outro } from "@clack/prompts";
16
+ import { intro, isCancel, log, multiselect, note, outro } from "@clack/prompts";
6
17
  import { bold, cyan } from "yoctocolors";
7
-
8
18
  //#region src/index.ts
19
+ const NEONCTL_COMMANDS = {
20
+ listOrgs: "npx neonctl orgs list --output json",
21
+ listProjects: "npx neonctl projects list --output json",
22
+ createProject: "npx neonctl projects create --name <project-name> --output json",
23
+ getConnectionString: "npx neonctl connection-string --project-id <project-id>"
24
+ };
25
+ const AUTH_INSTRUCTIONS = [
26
+ "YOU (the agent) must handle authentication. Do NOT ask the user to run commands themselves.",
27
+ "Do NOT write wrapper scripts (Python, shell, etc.) — use simple shell commands only.",
28
+ "IMPORTANT: Unset the CI environment variable for all neonctl commands below,",
29
+ "otherwise neonctl will refuse to open the browser.",
30
+ "",
31
+ "Step 1: Ask the user: \"Do you already have a Neon account, or do you need to create one?\"",
32
+ "",
33
+ "=== NEW ACCOUNT (sign up) ===",
34
+ "Step 2a: Open the Neon sign-up page in the user's browser:",
35
+ " On macOS: open https://console.neon.tech/signup",
36
+ " On Linux: xdg-open https://console.neon.tech/signup",
37
+ "Step 3a: Tell the user: \"I've opened the Neon sign-up page in your browser.",
38
+ " Create your account, then check your email for a verification link and click it.",
39
+ " Let me know when you have finished signing up and verifying your email.\"",
40
+ "Step 4a: Once the user confirms, run the OAuth login:",
41
+ " CI= npx -y neonctl auth",
42
+ " This opens a second browser tab for OAuth authorization. The user approves access.",
43
+ " If exit code 0: authentication succeeded.",
44
+ " If exit code 2 (timeout): ask the user to confirm they finished sign-up and",
45
+ " email verification, then retry the same command.",
46
+ "",
47
+ "=== EXISTING ACCOUNT (sign in) ===",
48
+ "Step 2b: Execute: CI= npx -y neonctl auth",
49
+ " This opens the OAuth login page directly. Sign-in is fast (60-second timeout).",
50
+ " If exit code 0: authentication succeeded.",
51
+ " If exit code 2 (timeout): ask the user to confirm they completed sign-in, then retry.",
52
+ "",
53
+ "=== AFTER SUCCESSFUL AUTH ===",
54
+ "Step 5: Verify by running: CI= npx -y neonctl me",
55
+ " This should print the user's account info and exit with code 0.",
56
+ "Step 6: Re-run neon-init with the same --agent and --json flags to complete setup."
57
+ ].join("\n");
58
+ function buildAgentInstructions(refs) {
59
+ return [
60
+ "IMPORTANT: Follow these steps to set up the Neon project. Do NOT skip steps.",
61
+ "",
62
+ "CRITICAL — SKILL REFERENCES: The URLs in skills.references are authoritative",
63
+ "implementation guides with exact import paths, component patterns, route structures,",
64
+ "and common mistakes to avoid. You MUST fetch and read the relevant skill reference",
65
+ "URL BEFORE writing any code that uses that Neon feature. Do NOT rely on general",
66
+ "documentation pages (e.g. /docs/guides/*) or guess at import paths — the skill",
67
+ "references are more accurate, complete, and agent-optimized.",
68
+ "",
69
+ `1. List organizations: ${NEONCTL_COMMANDS.listOrgs}`,
70
+ " - If one org, use it. If multiple, ask the user which to use.",
71
+ `2. List projects: ${NEONCTL_COMMANDS.listProjects} (add --org-id <org-id>)`,
72
+ " - No projects: ask if they want to create a new one.",
73
+ " - One project: ask if they want to use it or create new.",
74
+ " - Multiple: let the user choose.",
75
+ `3. Create project if needed: ${NEONCTL_COMMANDS.createProject} (add --org-id <org-id>)`,
76
+ `4. Get connection string: ${NEONCTL_COMMANDS.getConnectionString}`,
77
+ "5. Store in .env as DATABASE_URL (append, don't overwrite existing .env).",
78
+ "6. For apps with user login/auth: STOP. Before writing any auth code, fetch and",
79
+ ` read this skill reference: ${refs.neonAuth ?? ""}`,
80
+ " It contains the exact packages, imports, component layout, route patterns,",
81
+ " environment variables, and common mistakes. Follow it precisely.",
82
+ `7. For connection method/driver, fetch and read: ${refs.connectionMethods ?? ""}`,
83
+ "8. Refer to skills.gettingStarted for the full setup guide with additional details.",
84
+ "",
85
+ "Do NOT auto-create a project without asking the user first."
86
+ ].join("\n");
87
+ }
9
88
  /**
10
89
  * Initialize Neon projects with MCP Server
11
90
  */
12
91
  async function init(options) {
13
- intro("Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills");
92
+ const jsonMode = options?.json === true;
93
+ const makeFailedResult = (auth) => ({
94
+ success: false,
95
+ auth,
96
+ editors: [],
97
+ skills: {
98
+ installed: false,
99
+ gettingStarted: null,
100
+ references: {}
101
+ },
102
+ neonctl: {
103
+ authenticated: auth,
104
+ commands: { ...NEONCTL_COMMANDS }
105
+ },
106
+ mcpServer: {
107
+ configured: false,
108
+ requiresRestart: false
109
+ }
110
+ });
111
+ if (!jsonMode) if (options?.agent !== void 0) if (usesExtension(options.agent)) intro(`Adding Neon extension (includes MCP server) and agent skills for ${options.agent}`);
112
+ else intro(`Adding Neon MCP server and agent skills for ${options.agent}`);
113
+ else intro("Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills");
14
114
  const homeDir = process.env.HOME || process.env.USERPROFILE;
15
115
  if (!homeDir) {
16
- log.error("Could not determine home directory");
17
- outro("📣 Is this unexpected? Email us at feedback@neon.tech");
18
- process.exit(1);
116
+ if (!jsonMode) {
117
+ log.error("Could not determine home directory");
118
+ outro("📣 Is this unexpected? Email us at feedback@neon.tech");
119
+ }
120
+ return makeFailedResult(false);
19
121
  }
20
- const workspaceDir = process.cwd();
21
122
  let selectedEditors;
22
123
  if (options?.agent !== void 0) selectedEditors = [options.agent];
23
124
  else {
125
+ if (jsonMode) return makeFailedResult(false);
24
126
  const availableEditors = await detectAvailableEditors(homeDir);
25
- if (availableEditors.length === 0) {
26
- log.warn("No supported editors detected on your system.");
27
- log.info("Supported editors:");
28
- log.info(" • VS Code (with Neon Local Connect extension)");
29
- log.info(" • Cursor (with Neon Local Connect extension)");
30
- log.info(" • Claude CLI (with MCP Server)");
31
- const continueAnyway = await confirm({
32
- message: "Would you like to configure Neon anyway? (You can manually select your editor)",
33
- initialValue: true
34
- });
35
- if (isCancel(continueAnyway) || !continueAnyway) {
36
- outro("Installation cancelled");
37
- process.exit(0);
38
- }
39
- }
40
127
  const response = await multiselect({
41
128
  message: "Which editor(s) would you like to configure? (Space to toggle each option, Enter to confirm your selection)",
42
- options: [
43
- "Cursor",
44
- "VS Code",
45
- "Claude CLI"
46
- ].map((editor) => ({
47
- value: editor,
48
- label: editor,
49
- hint: editor === "Claude CLI" ? "MCP Server" : "Neon Local Connect extension"
129
+ options: ALL_CONFIGURABLE_AGENTS.map((agent) => ({
130
+ value: agent.editor,
131
+ label: agent.editor,
132
+ hint: agent.hint
50
133
  })),
51
134
  initialValues: availableEditors,
52
135
  required: true
53
136
  });
54
137
  if (isCancel(response)) {
55
138
  outro("Installation cancelled");
56
- process.exit(0);
139
+ return makeFailedResult(false);
57
140
  }
58
141
  selectedEditors = response;
59
142
  }
60
143
  if (selectedEditors.length === 0) {
61
- log.warn("No editors selected.");
62
- outro("Installation cancelled");
63
- process.exit(0);
144
+ if (!jsonMode) {
145
+ log.warn("No editors selected.");
146
+ outro("Installation cancelled");
147
+ }
148
+ return makeFailedResult(false);
64
149
  }
65
- const results = await installNeon(homeDir, workspaceDir, selectedEditors);
150
+ if (jsonMode) {
151
+ if (!await isAuthenticated()) {
152
+ const { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;
153
+ return {
154
+ success: false,
155
+ auth: false,
156
+ authRequired: true,
157
+ authInstructions: AUTH_INSTRUCTIONS,
158
+ editors: [],
159
+ skills: {
160
+ installed: false,
161
+ gettingStarted: await fetchSkillContent(),
162
+ references: otherRefs
163
+ },
164
+ neonctl: {
165
+ authenticated: false,
166
+ commands: { ...NEONCTL_COMMANDS }
167
+ },
168
+ mcpServer: {
169
+ configured: false,
170
+ requiresRestart: false
171
+ }
172
+ };
173
+ }
174
+ }
175
+ const { results, authSuccess } = await installNeon(selectedEditors, { json: jsonMode });
66
176
  const successful = [];
67
177
  const failed = [];
68
178
  for (const [editor, status] of results.entries()) if (status === "success") successful.push(editor);
69
179
  else failed.push(editor);
70
- if (successful.length > 0) await installAgentSkills(successful);
180
+ let skillsInstalled = false;
181
+ if (successful.length > 0) skillsInstalled = await installAgentSkills(successful, { json: jsonMode });
182
+ const editorsResult = [];
183
+ for (const [editor, status] of results.entries()) editorsResult.push({
184
+ editor,
185
+ status,
186
+ type: usesExtension(editor) ? "extension" : "mcp"
187
+ });
188
+ const mcpConfigured = successful.some((e) => !usesExtension(e));
189
+ if (jsonMode) {
190
+ const { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;
191
+ const gettingStartedContent = await fetchSkillContent();
192
+ return {
193
+ success: successful.length > 0,
194
+ auth: authSuccess,
195
+ agentInstructions: buildAgentInstructions(otherRefs),
196
+ editors: editorsResult,
197
+ skills: {
198
+ installed: skillsInstalled,
199
+ gettingStarted: gettingStartedContent,
200
+ references: otherRefs
201
+ },
202
+ neonctl: {
203
+ authenticated: authSuccess,
204
+ commands: { ...NEONCTL_COMMANDS }
205
+ },
206
+ mcpServer: {
207
+ configured: mcpConfigured,
208
+ requiresRestart: mcpConfigured
209
+ }
210
+ };
211
+ }
71
212
  const extensionEditors = successful.filter(usesExtension);
72
213
  const mcpEditors = successful.filter((e) => !usesExtension(e));
73
214
  const failedExtensionEditors = failed.filter(usesExtension);
@@ -85,17 +226,55 @@ async function init(options) {
85
226
  for (const editor of failedExtensionEditors) if (editor === "VS Code") log.info(" • VS Code: https://marketplace.visualstudio.com/items?itemName=databricks.neon-local-connect");
86
227
  else if (editor === "Cursor") log.info(" • Cursor: https://open-vsx.org/extension/databricks/neon-local-connect");
87
228
  }
88
- if (failedMcpEditors.length > 0) log.error(`Failed to configure MCP Server for ${failedMcpEditors.join(" / ")}`);
229
+ if (failedMcpEditors.length > 0) {
230
+ log.error(`Failed to configure MCP Server for ${failedMcpEditors.join(" / ")}`);
231
+ log.info("You can manually configure the MCP server by running: npx add-mcp https://mcp.neon.tech/mcp");
232
+ }
89
233
  if (successful.length === 0) {
90
234
  outro("Installation cancelled or failed. Please check the output above and try again.");
91
- process.exit(1);
235
+ return {
236
+ success: false,
237
+ auth: authSuccess,
238
+ editors: editorsResult,
239
+ skills: {
240
+ installed: false,
241
+ gettingStarted: null,
242
+ references: {}
243
+ },
244
+ neonctl: {
245
+ authenticated: authSuccess,
246
+ commands: { ...NEONCTL_COMMANDS }
247
+ },
248
+ mcpServer: {
249
+ configured: false,
250
+ requiresRestart: false
251
+ }
252
+ };
92
253
  }
93
254
  if (extensionEditors.length > 0 && mcpEditors.length === 0) note(`\x1b[0mRestart ${extensionEditors.join(" / ")}, open the Neon extension and type in "${bold(cyan("Get started with Neon"))}\x1b[0m" in your agent chat`, "What's next?");
94
255
  else if (mcpEditors.length > 0 && extensionEditors.length === 0) note(`\x1b[0mRestart ${mcpEditors.join(" / ")} and type in "${bold(cyan("Get started with Neon"))}\x1b[0m" in the chat`, "What's next?");
95
256
  else note(`\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`, "What's next?");
96
257
  outro("Have feedback? Email us at feedback@neon.tech");
258
+ return {
259
+ success: true,
260
+ auth: authSuccess,
261
+ editors: editorsResult,
262
+ skills: {
263
+ installed: skillsInstalled,
264
+ gettingStarted: null,
265
+ references: {}
266
+ },
267
+ neonctl: {
268
+ authenticated: authSuccess,
269
+ commands: { ...NEONCTL_COMMANDS }
270
+ },
271
+ mcpServer: {
272
+ configured: mcpConfigured,
273
+ requiresRestart: mcpConfigured
274
+ }
275
+ };
97
276
  }
98
-
99
277
  //#endregion
100
- export { init };
278
+ export { handleAuthPhase, handleDbPhase, handleMcpPhase, handleMigrationsPhase, handleNeonAuthPhase, handleSkillsPhase, handleStatusPhase, init, interactiveInit, orchestrate };
279
+
101
280
  //# 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 {\n\tconfirm,\n\tintro,\n\tisCancel,\n\tlog,\n\tmultiselect,\n\tnote,\n\toutro,\n} from \"@clack/prompts\";\nimport { bold, cyan } from \"yoctocolors\";\nimport { detectAvailableEditors } from \"./lib/editors.js\";\nimport { usesExtension } from \"./lib/extension.js\";\nimport { installNeon } from \"./lib/install.js\";\nimport { installAgentSkills } from \"./lib/skills.js\";\nimport type { Editor } from \"./lib/types.js\";\n\nexport interface InitOptions {\n\t/** When set, configures only this agent and skips the editor selection prompt. */\n\tagent?: Editor;\n}\n\n/**\n * Initialize Neon projects with MCP Server\n */\nexport async function init(options?: InitOptions): Promise<void> {\n\tintro(\n\t\t\"Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills\",\n\t);\n\n\t// Get the home directory\n\tconst homeDir = process.env.HOME || process.env.USERPROFILE;\n\tif (!homeDir) {\n\t\tlog.error(\"Could not determine home directory\");\n\t\toutro(\"📣 Is this unexpected? Email us at feedback@neon.tech\");\n\t\tprocess.exit(1);\n\t}\n\n\t// Get the current workspace directory\n\tconst workspaceDir = process.cwd();\n\n\tlet selectedEditors: Editor[];\n\n\tif (options?.agent !== undefined) {\n\t\tselectedEditors = [options.agent];\n\t} else {\n\t\t// Detect available editors\n\t\tconst availableEditors = await detectAvailableEditors(homeDir);\n\n\t\t// If no editors detected, offer to continue anyway\n\t\tif (availableEditors.length === 0) {\n\t\t\tlog.warn(\"No supported editors detected on your system.\");\n\t\t\tlog.info(\"Supported editors:\");\n\t\t\tlog.info(\" • VS Code (with Neon Local Connect extension)\");\n\t\t\tlog.info(\" • Cursor (with Neon Local Connect extension)\");\n\t\t\tlog.info(\" • Claude CLI (with MCP Server)\");\n\n\t\t\tconst continueAnyway = await confirm({\n\t\t\t\tmessage:\n\t\t\t\t\t\"Would you like to configure Neon anyway? (You can manually select your editor)\",\n\t\t\t\tinitialValue: true,\n\t\t\t});\n\n\t\t\tif (isCancel(continueAnyway) || !continueAnyway) {\n\t\t\t\toutro(\"Installation cancelled\");\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\n\t\t// Determine which editors to configure\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: [\"Cursor\", \"VS Code\", \"Claude CLI\"].map((editor) => ({\n\t\t\t\tvalue: editor,\n\t\t\t\tlabel: editor,\n\t\t\t\thint:\n\t\t\t\t\teditor === \"Claude CLI\"\n\t\t\t\t\t\t? \"MCP Server\"\n\t\t\t\t\t\t: \"Neon Local Connect extension\",\n\t\t\t})),\n\t\t\tinitialValues: availableEditors, // Select detected editors by default\n\t\t\trequired: true,\n\t\t});\n\n\t\tif (isCancel(response)) {\n\t\t\toutro(\"Installation cancelled\");\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\tselectedEditors = response as Editor[];\n\t}\n\n\tif (selectedEditors.length === 0) {\n\t\tlog.warn(\"No editors selected.\");\n\t\toutro(\"Installation cancelled\");\n\t\tprocess.exit(0);\n\t}\n\n\t// Install Neon for selected editors\n\tconst results = await installNeon(homeDir, workspaceDir, selectedEditors);\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\t// Install agent skills for successful installations\n\tif (successful.length > 0) {\n\t\tawait installAgentSkills(successful);\n\t}\n\n\t// Show different messages based on what was installed\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\t// Show helpful installation links for failed extension installations\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}\n\n\t// Exit with error if all installations failed\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\tprocess.exit(1);\n\t}\n\n\tif (extensionEditors.length > 0 && mcpEditors.length === 0) {\n\t\t// Only extension editors (VS Code/Cursor)\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\t// Only MCP editors (Claude CLI)\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\t// Mixed editors\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"],"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 {\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\nconst NEONCTL_COMMANDS = {\n\tlistOrgs: \"npx neonctl orgs list --output json\",\n\tlistProjects: \"npx neonctl projects list --output json\",\n\tcreateProject:\n\t\t\"npx neonctl projects create --name <project-name> --output json\",\n\tgetConnectionString:\n\t\t\"npx neonctl connection-string --project-id <project-id>\",\n} as const;\n\nconst AUTH_INSTRUCTIONS = [\n\t\"YOU (the agent) must handle authentication. Do NOT ask the user to run commands themselves.\",\n\t\"Do NOT write wrapper scripts (Python, shell, etc.) — use simple shell commands only.\",\n\t\"IMPORTANT: Unset the CI environment variable for all neonctl commands below,\",\n\t\"otherwise neonctl will refuse to open the browser.\",\n\t\"\",\n\t'Step 1: Ask the user: \"Do you already have a Neon account, or do you need to create one?\"',\n\t\"\",\n\t\"=== NEW ACCOUNT (sign up) ===\",\n\t\"Step 2a: Open the Neon sign-up page in the user's browser:\",\n\t\" On macOS: open https://console.neon.tech/signup\",\n\t\" On Linux: xdg-open https://console.neon.tech/signup\",\n\t\"Step 3a: Tell the user: \\\"I've opened the Neon sign-up page in your browser.\",\n\t\" Create your account, then check your email for a verification link and click it.\",\n\t' Let me know when you have finished signing up and verifying your email.\"',\n\t\"Step 4a: Once the user confirms, run the OAuth login:\",\n\t\" CI= npx -y neonctl auth\",\n\t\" This opens a second browser tab for OAuth authorization. The user approves access.\",\n\t\" If exit code 0: authentication succeeded.\",\n\t\" If exit code 2 (timeout): ask the user to confirm they finished sign-up and\",\n\t\" email verification, then retry the same command.\",\n\t\"\",\n\t\"=== EXISTING ACCOUNT (sign in) ===\",\n\t\"Step 2b: Execute: CI= npx -y neonctl auth\",\n\t\" This opens the OAuth login page directly. Sign-in is fast (60-second timeout).\",\n\t\" If exit code 0: authentication succeeded.\",\n\t\" If exit code 2 (timeout): ask the user to confirm they completed sign-in, then retry.\",\n\t\"\",\n\t\"=== AFTER SUCCESSFUL AUTH ===\",\n\t\"Step 5: Verify by running: CI= npx -y neonctl me\",\n\t\" This should print the user's account info and exit with code 0.\",\n\t\"Step 6: Re-run neon-init with the same --agent and --json flags to complete setup.\",\n].join(\"\\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: ${NEONCTL_COMMANDS.listOrgs}`,\n\t\t\" - If one org, use it. If multiple, ask the user which to use.\",\n\t\t`2. List projects: ${NEONCTL_COMMANDS.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: ${NEONCTL_COMMANDS.createProject} (add --org-id <org-id>)`,\n\t\t`4. Get connection string: ${NEONCTL_COMMANDS.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: { ...NEONCTL_COMMANDS },\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: AUTH_INSTRUCTIONS,\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: { ...NEONCTL_COMMANDS },\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: { ...NEONCTL_COMMANDS },\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: { ...NEONCTL_COMMANDS },\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: { ...NEONCTL_COMMANDS },\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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"}
@@ -0,0 +1,12 @@
1
+ //#region src/interactive.d.ts
2
+ /**
3
+ * Interactive v2 CLI — purpose-built guided flow for humans.
4
+ * Uses the same underlying install functions but with a clean clack-based UX.
5
+ */
6
+ interface InteractiveInitOptions {
7
+ preview?: boolean;
8
+ }
9
+ declare function interactiveInit(options?: InteractiveInitOptions): Promise<void>;
10
+ //#endregion
11
+ export { InteractiveInitOptions, interactiveInit };
12
+ //# sourceMappingURL=interactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.d.ts","names":[],"sources":["../src/interactive.ts"],"mappings":";;AAiFA;AAIA;;AACU,UALO,sBAAA,CAKP;SACP,CAAA,EAAA,OAAA;AAAO;iBAFY,eAAA,WACZ,yBACP"}