neon-init 0.14.0 → 0.16.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 +366 -30
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +15 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +218 -13
- package/dist/index.js.map +1 -1
- package/dist/interactive.d.ts +12 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +495 -0
- package/dist/interactive.js.map +1 -0
- package/dist/lib/agents.d.ts +6 -1
- package/dist/lib/agents.d.ts.map +1 -1
- package/dist/lib/agents.js +62 -1
- package/dist/lib/agents.js.map +1 -1
- package/dist/lib/auth.d.ts +10 -3
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +21 -12
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/bootstrap.d.ts +30 -0
- package/dist/lib/bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap.js +61 -0
- package/dist/lib/bootstrap.js.map +1 -0
- package/dist/lib/build-config.d.ts +5 -0
- package/dist/lib/build-config.d.ts.map +1 -0
- package/dist/lib/build-config.js +6 -0
- package/dist/lib/build-config.js.map +1 -0
- package/dist/lib/detect-agent.d.ts +22 -0
- package/dist/lib/detect-agent.d.ts.map +1 -0
- package/dist/lib/detect-agent.js +65 -0
- package/dist/lib/detect-agent.js.map +1 -0
- package/dist/lib/editors.d.ts.map +1 -1
- package/dist/lib/editors.js.map +1 -1
- package/dist/lib/extension.d.ts +11 -3
- package/dist/lib/extension.d.ts.map +1 -1
- package/dist/lib/extension.js +28 -7
- package/dist/lib/extension.js.map +1 -1
- package/dist/lib/inspect.d.ts +28 -0
- package/dist/lib/inspect.d.ts.map +1 -0
- package/dist/lib/inspect.js +190 -0
- package/dist/lib/inspect.js.map +1 -0
- package/dist/lib/install.d.ts +10 -4
- package/dist/lib/install.d.ts.map +1 -1
- package/dist/lib/install.js +37 -20
- package/dist/lib/install.js.map +1 -1
- package/dist/lib/neonctl.d.ts +51 -0
- package/dist/lib/neonctl.d.ts.map +1 -0
- package/dist/lib/neonctl.js +184 -0
- package/dist/lib/neonctl.js.map +1 -0
- package/dist/lib/phases/auth.d.ts +12 -0
- package/dist/lib/phases/auth.d.ts.map +1 -0
- package/dist/lib/phases/auth.js +197 -0
- package/dist/lib/phases/auth.js.map +1 -0
- package/dist/lib/phases/cleanup.d.ts +12 -0
- package/dist/lib/phases/cleanup.d.ts.map +1 -0
- package/dist/lib/phases/cleanup.js +29 -0
- package/dist/lib/phases/cleanup.js.map +1 -0
- package/dist/lib/phases/db.d.ts +17 -0
- package/dist/lib/phases/db.d.ts.map +1 -0
- package/dist/lib/phases/db.js +259 -0
- package/dist/lib/phases/db.js.map +1 -0
- package/dist/lib/phases/getting-started.d.ts +26 -0
- package/dist/lib/phases/getting-started.d.ts.map +1 -0
- package/dist/lib/phases/getting-started.js +196 -0
- package/dist/lib/phases/getting-started.js.map +1 -0
- package/dist/lib/phases/mcp.d.ts +15 -0
- package/dist/lib/phases/mcp.d.ts.map +1 -0
- package/dist/lib/phases/mcp.js +179 -0
- package/dist/lib/phases/mcp.js.map +1 -0
- package/dist/lib/phases/migrations.d.ts +14 -0
- package/dist/lib/phases/migrations.d.ts.map +1 -0
- package/dist/lib/phases/migrations.js +239 -0
- package/dist/lib/phases/migrations.js.map +1 -0
- package/dist/lib/phases/neon-auth.d.ts +13 -0
- package/dist/lib/phases/neon-auth.d.ts.map +1 -0
- package/dist/lib/phases/neon-auth.js +118 -0
- package/dist/lib/phases/neon-auth.js.map +1 -0
- package/dist/lib/phases/setup.d.ts +41 -0
- package/dist/lib/phases/setup.d.ts.map +1 -0
- package/dist/lib/phases/setup.js +689 -0
- package/dist/lib/phases/setup.js.map +1 -0
- package/dist/lib/phases/skills.d.ts +14 -0
- package/dist/lib/phases/skills.d.ts.map +1 -0
- package/dist/lib/phases/skills.js +80 -0
- package/dist/lib/phases/skills.js.map +1 -0
- package/dist/lib/phases/status.d.ts +10 -0
- package/dist/lib/phases/status.d.ts.map +1 -0
- package/dist/lib/phases/status.js +65 -0
- package/dist/lib/phases/status.js.map +1 -0
- package/dist/lib/resolve-context.d.ts +19 -0
- package/dist/lib/resolve-context.d.ts.map +1 -0
- package/dist/lib/resolve-context.js +112 -0
- package/dist/lib/resolve-context.js.map +1 -0
- package/dist/lib/route-command.d.ts +8 -0
- package/dist/lib/route-command.d.ts.map +1 -0
- package/dist/lib/route-command.js +195 -0
- package/dist/lib/route-command.js.map +1 -0
- package/dist/lib/skills.d.ts +20 -3
- package/dist/lib/skills.d.ts.map +1 -1
- package/dist/lib/skills.js +116 -12
- package/dist/lib/skills.js.map +1 -1
- package/dist/lib/types.d.ts +150 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/vsix.d.ts +15 -0
- package/dist/lib/vsix.d.ts.map +1 -0
- package/dist/lib/vsix.js +91 -0
- package/dist/lib/vsix.js.map +1 -0
- package/dist/v2.d.ts +31 -0
- package/dist/v2.d.ts.map +1 -0
- package/dist/v2.js +147 -0
- package/dist/v2.js.map +1 -0
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -1,27 +1,138 @@
|
|
|
1
1
|
import { ALL_CONFIGURABLE_AGENTS } from "./lib/agents.js";
|
|
2
|
+
import { isAuthenticated } from "./lib/auth.js";
|
|
2
3
|
import { detectAvailableEditors } from "./lib/editors.js";
|
|
3
4
|
import { usesExtension } from "./lib/extension.js";
|
|
5
|
+
import { getNeonctlApiFlags, neonctlCmd } from "./lib/neonctl.js";
|
|
6
|
+
import { SKILL_REFERENCE_URLS, fetchSkillContent, installAgentSkills } from "./lib/skills.js";
|
|
7
|
+
import { interactiveInit } from "./interactive.js";
|
|
8
|
+
import { handleAuthPhase } from "./lib/phases/auth.js";
|
|
9
|
+
import { handleDbPhase } from "./lib/phases/db.js";
|
|
10
|
+
import { handleMcpPhase } from "./lib/phases/mcp.js";
|
|
11
|
+
import { handleMigrationsPhase } from "./lib/phases/migrations.js";
|
|
12
|
+
import { handleNeonAuthPhase } from "./lib/phases/neon-auth.js";
|
|
13
|
+
import { handleSkillsPhase } from "./lib/phases/skills.js";
|
|
14
|
+
import { handleStatusPhase } from "./lib/phases/status.js";
|
|
15
|
+
import { orchestrate } from "./v2.js";
|
|
4
16
|
import { installNeon } from "./lib/install.js";
|
|
5
|
-
import { installAgentSkills } from "./lib/skills.js";
|
|
6
17
|
import { intro, isCancel, log, multiselect, note, outro } from "@clack/prompts";
|
|
7
18
|
import { bold, cyan } from "yoctocolors";
|
|
8
19
|
//#region src/index.ts
|
|
20
|
+
function getNeonctlCommands() {
|
|
21
|
+
const flags = getNeonctlApiFlags();
|
|
22
|
+
const base = flags ? `npx neonctl ${flags}` : "npx neonctl";
|
|
23
|
+
return {
|
|
24
|
+
listOrgs: `${base} orgs list --output json`,
|
|
25
|
+
listProjects: `${base} projects list --output json`,
|
|
26
|
+
createProject: `${base} projects create --name <project-name> --output json`,
|
|
27
|
+
getConnectionString: `${base} connection-string --project-id <project-id>`
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function getAuthInstructions() {
|
|
31
|
+
const cmd = neonctlCmd();
|
|
32
|
+
const apiBase = process.env.NEON_API_HOST?.replace(/\/+$/, "");
|
|
33
|
+
const signupUrl = apiBase ? `${apiBase}/signup` : "https://console.neon.tech/signup";
|
|
34
|
+
return [
|
|
35
|
+
"YOU (the agent) must handle authentication. Do NOT ask the user to run commands themselves.",
|
|
36
|
+
"Do NOT write wrapper scripts (Python, shell, etc.) — use simple shell commands only.",
|
|
37
|
+
"IMPORTANT: Unset the CI environment variable for all neonctl commands below,",
|
|
38
|
+
"otherwise neonctl will refuse to open the browser.",
|
|
39
|
+
"",
|
|
40
|
+
"Step 1: Ask the user: \"Do you already have a Neon account, or do you need to create one?\"",
|
|
41
|
+
"",
|
|
42
|
+
"=== NEW ACCOUNT (sign up) ===",
|
|
43
|
+
"Step 2a: Open the Neon sign-up page in the user's browser:",
|
|
44
|
+
` On macOS: open ${signupUrl}`,
|
|
45
|
+
` On Linux: xdg-open ${signupUrl}`,
|
|
46
|
+
"Step 3a: Tell the user: \"I've opened the Neon sign-up page in your browser.",
|
|
47
|
+
" Create your account, then check your email for a verification link and click it.",
|
|
48
|
+
" Let me know when you have finished signing up and verifying your email.\"",
|
|
49
|
+
"Step 4a: Once the user confirms, run the OAuth login:",
|
|
50
|
+
` ${cmd} auth`,
|
|
51
|
+
" This opens a second browser tab for OAuth authorization. The user approves access.",
|
|
52
|
+
" If exit code 0: authentication succeeded.",
|
|
53
|
+
" If exit code 2 (timeout): ask the user to confirm they finished sign-up and",
|
|
54
|
+
" email verification, then retry the same command.",
|
|
55
|
+
"",
|
|
56
|
+
"=== EXISTING ACCOUNT (sign in) ===",
|
|
57
|
+
`Step 2b: Execute: ${cmd} auth`,
|
|
58
|
+
" This opens the OAuth login page directly. Sign-in is fast (60-second timeout).",
|
|
59
|
+
" If exit code 0: authentication succeeded.",
|
|
60
|
+
" If exit code 2 (timeout): ask the user to confirm they completed sign-in, then retry.",
|
|
61
|
+
"",
|
|
62
|
+
"=== AFTER SUCCESSFUL AUTH ===",
|
|
63
|
+
`Step 5: Verify by running: ${cmd} me`,
|
|
64
|
+
" 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
|
+
].join("\n");
|
|
67
|
+
}
|
|
68
|
+
function buildAgentInstructions(refs) {
|
|
69
|
+
return [
|
|
70
|
+
"IMPORTANT: Follow these steps to set up the Neon project. Do NOT skip steps.",
|
|
71
|
+
"",
|
|
72
|
+
"CRITICAL — SKILL REFERENCES: The URLs in skills.references are authoritative",
|
|
73
|
+
"implementation guides with exact import paths, component patterns, route structures,",
|
|
74
|
+
"and common mistakes to avoid. You MUST fetch and read the relevant skill reference",
|
|
75
|
+
"URL BEFORE writing any code that uses that Neon feature. Do NOT rely on general",
|
|
76
|
+
"documentation pages (e.g. /docs/guides/*) or guess at import paths — the skill",
|
|
77
|
+
"references are more accurate, complete, and agent-optimized.",
|
|
78
|
+
"",
|
|
79
|
+
`1. List organizations: ${getNeonctlCommands().listOrgs}`,
|
|
80
|
+
" - If one org, use it. If multiple, ask the user which to use.",
|
|
81
|
+
`2. List projects: ${getNeonctlCommands().listProjects} (add --org-id <org-id>)`,
|
|
82
|
+
" - No projects: ask if they want to create a new one.",
|
|
83
|
+
" - One project: ask if they want to use it or create new.",
|
|
84
|
+
" - Multiple: let the user choose.",
|
|
85
|
+
`3. Create project if needed: ${getNeonctlCommands().createProject} (add --org-id <org-id>)`,
|
|
86
|
+
`4. Get connection string: ${getNeonctlCommands().getConnectionString}`,
|
|
87
|
+
"5. Store in .env as DATABASE_URL (append, don't overwrite existing .env).",
|
|
88
|
+
"6. For apps with user login/auth: STOP. Before writing any auth code, fetch and",
|
|
89
|
+
` read this skill reference: ${refs.neonAuth ?? ""}`,
|
|
90
|
+
" It contains the exact packages, imports, component layout, route patterns,",
|
|
91
|
+
" environment variables, and common mistakes. Follow it precisely.",
|
|
92
|
+
`7. For connection method/driver, fetch and read: ${refs.connectionMethods ?? ""}`,
|
|
93
|
+
"8. Refer to skills.gettingStarted for the full setup guide with additional details.",
|
|
94
|
+
"",
|
|
95
|
+
"Do NOT auto-create a project without asking the user first."
|
|
96
|
+
].join("\n");
|
|
97
|
+
}
|
|
9
98
|
/**
|
|
10
99
|
* Initialize Neon projects with MCP Server
|
|
11
100
|
*/
|
|
12
101
|
async function init(options) {
|
|
13
|
-
|
|
102
|
+
const jsonMode = options?.json === true;
|
|
103
|
+
const makeFailedResult = (auth) => ({
|
|
104
|
+
success: false,
|
|
105
|
+
auth,
|
|
106
|
+
editors: [],
|
|
107
|
+
skills: {
|
|
108
|
+
installed: false,
|
|
109
|
+
gettingStarted: null,
|
|
110
|
+
references: {}
|
|
111
|
+
},
|
|
112
|
+
neonctl: {
|
|
113
|
+
authenticated: auth,
|
|
114
|
+
commands: { ...getNeonctlCommands() }
|
|
115
|
+
},
|
|
116
|
+
mcpServer: {
|
|
117
|
+
configured: false,
|
|
118
|
+
requiresRestart: false
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
if (!jsonMode) if (options?.agent !== void 0) if (usesExtension(options.agent)) intro(`Adding Neon extension (includes MCP server) and agent skills for ${options.agent}`);
|
|
14
122
|
else intro(`Adding Neon MCP server and agent skills for ${options.agent}`);
|
|
15
123
|
else intro("Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills");
|
|
16
124
|
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
17
125
|
if (!homeDir) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
126
|
+
if (!jsonMode) {
|
|
127
|
+
log.error("Could not determine home directory");
|
|
128
|
+
outro("📣 Is this unexpected? Email us at feedback@neon.tech");
|
|
129
|
+
}
|
|
130
|
+
return makeFailedResult(false);
|
|
21
131
|
}
|
|
22
132
|
let selectedEditors;
|
|
23
133
|
if (options?.agent !== void 0) selectedEditors = [options.agent];
|
|
24
134
|
else {
|
|
135
|
+
if (jsonMode) return makeFailedResult(false);
|
|
25
136
|
const availableEditors = await detectAvailableEditors(homeDir);
|
|
26
137
|
const response = await multiselect({
|
|
27
138
|
message: "Which editor(s) would you like to configure? (Space to toggle each option, Enter to confirm your selection)",
|
|
@@ -35,21 +146,80 @@ async function init(options) {
|
|
|
35
146
|
});
|
|
36
147
|
if (isCancel(response)) {
|
|
37
148
|
outro("Installation cancelled");
|
|
38
|
-
|
|
149
|
+
return makeFailedResult(false);
|
|
39
150
|
}
|
|
40
151
|
selectedEditors = response;
|
|
41
152
|
}
|
|
42
153
|
if (selectedEditors.length === 0) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
154
|
+
if (!jsonMode) {
|
|
155
|
+
log.warn("No editors selected.");
|
|
156
|
+
outro("Installation cancelled");
|
|
157
|
+
}
|
|
158
|
+
return makeFailedResult(false);
|
|
159
|
+
}
|
|
160
|
+
if (jsonMode) {
|
|
161
|
+
if (!await isAuthenticated()) {
|
|
162
|
+
const { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;
|
|
163
|
+
const gettingStartedContent = await fetchSkillContent();
|
|
164
|
+
return {
|
|
165
|
+
success: false,
|
|
166
|
+
auth: false,
|
|
167
|
+
authRequired: true,
|
|
168
|
+
authInstructions: getAuthInstructions(),
|
|
169
|
+
editors: [],
|
|
170
|
+
skills: {
|
|
171
|
+
installed: false,
|
|
172
|
+
gettingStarted: gettingStartedContent,
|
|
173
|
+
references: otherRefs
|
|
174
|
+
},
|
|
175
|
+
neonctl: {
|
|
176
|
+
authenticated: false,
|
|
177
|
+
commands: { ...getNeonctlCommands() }
|
|
178
|
+
},
|
|
179
|
+
mcpServer: {
|
|
180
|
+
configured: false,
|
|
181
|
+
requiresRestart: false
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
46
185
|
}
|
|
47
|
-
const results = await installNeon(selectedEditors);
|
|
186
|
+
const { results, authSuccess } = await installNeon(selectedEditors, { json: jsonMode });
|
|
48
187
|
const successful = [];
|
|
49
188
|
const failed = [];
|
|
50
189
|
for (const [editor, status] of results.entries()) if (status === "success") successful.push(editor);
|
|
51
190
|
else failed.push(editor);
|
|
52
|
-
|
|
191
|
+
let skillsInstalled = false;
|
|
192
|
+
if (successful.length > 0) skillsInstalled = await installAgentSkills(successful, { json: jsonMode });
|
|
193
|
+
const editorsResult = [];
|
|
194
|
+
for (const [editor, status] of results.entries()) editorsResult.push({
|
|
195
|
+
editor,
|
|
196
|
+
status,
|
|
197
|
+
type: usesExtension(editor) ? "extension" : "mcp"
|
|
198
|
+
});
|
|
199
|
+
const mcpConfigured = successful.some((e) => !usesExtension(e));
|
|
200
|
+
if (jsonMode) {
|
|
201
|
+
const { gettingStarted: _gs, ...otherRefs } = SKILL_REFERENCE_URLS;
|
|
202
|
+
const gettingStartedContent = await fetchSkillContent();
|
|
203
|
+
return {
|
|
204
|
+
success: successful.length > 0,
|
|
205
|
+
auth: authSuccess,
|
|
206
|
+
agentInstructions: buildAgentInstructions(otherRefs),
|
|
207
|
+
editors: editorsResult,
|
|
208
|
+
skills: {
|
|
209
|
+
installed: skillsInstalled,
|
|
210
|
+
gettingStarted: gettingStartedContent,
|
|
211
|
+
references: otherRefs
|
|
212
|
+
},
|
|
213
|
+
neonctl: {
|
|
214
|
+
authenticated: authSuccess,
|
|
215
|
+
commands: { ...getNeonctlCommands() }
|
|
216
|
+
},
|
|
217
|
+
mcpServer: {
|
|
218
|
+
configured: mcpConfigured,
|
|
219
|
+
requiresRestart: mcpConfigured
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
53
223
|
const extensionEditors = successful.filter(usesExtension);
|
|
54
224
|
const mcpEditors = successful.filter((e) => !usesExtension(e));
|
|
55
225
|
const failedExtensionEditors = failed.filter(usesExtension);
|
|
@@ -73,14 +243,49 @@ async function init(options) {
|
|
|
73
243
|
}
|
|
74
244
|
if (successful.length === 0) {
|
|
75
245
|
outro("Installation cancelled or failed. Please check the output above and try again.");
|
|
76
|
-
|
|
246
|
+
return {
|
|
247
|
+
success: false,
|
|
248
|
+
auth: authSuccess,
|
|
249
|
+
editors: editorsResult,
|
|
250
|
+
skills: {
|
|
251
|
+
installed: false,
|
|
252
|
+
gettingStarted: null,
|
|
253
|
+
references: {}
|
|
254
|
+
},
|
|
255
|
+
neonctl: {
|
|
256
|
+
authenticated: authSuccess,
|
|
257
|
+
commands: { ...getNeonctlCommands() }
|
|
258
|
+
},
|
|
259
|
+
mcpServer: {
|
|
260
|
+
configured: false,
|
|
261
|
+
requiresRestart: false
|
|
262
|
+
}
|
|
263
|
+
};
|
|
77
264
|
}
|
|
78
265
|
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?");
|
|
79
266
|
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?");
|
|
80
267
|
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?");
|
|
81
268
|
outro("Have feedback? Email us at feedback@neon.tech");
|
|
269
|
+
return {
|
|
270
|
+
success: true,
|
|
271
|
+
auth: authSuccess,
|
|
272
|
+
editors: editorsResult,
|
|
273
|
+
skills: {
|
|
274
|
+
installed: skillsInstalled,
|
|
275
|
+
gettingStarted: null,
|
|
276
|
+
references: {}
|
|
277
|
+
},
|
|
278
|
+
neonctl: {
|
|
279
|
+
authenticated: authSuccess,
|
|
280
|
+
commands: { ...getNeonctlCommands() }
|
|
281
|
+
},
|
|
282
|
+
mcpServer: {
|
|
283
|
+
configured: mcpConfigured,
|
|
284
|
+
requiresRestart: mcpConfigured
|
|
285
|
+
}
|
|
286
|
+
};
|
|
82
287
|
}
|
|
83
288
|
//#endregion
|
|
84
|
-
export { init };
|
|
289
|
+
export { handleAuthPhase, handleDbPhase, handleMcpPhase, handleMigrationsPhase, handleNeonAuthPhase, handleSkillsPhase, handleStatusPhase, init, interactiveInit, orchestrate };
|
|
85
290
|
|
|
86
291
|
//# 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 { 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\tif (options?.agent !== undefined) {\n\t\tif (usesExtension(options.agent)) {\n\t\t\tintro(\n\t\t\t\t`Adding Neon extension (includes MCP server) and agent skills for ${options.agent}`,\n\t\t\t);\n\t\t} else {\n\t\t\tintro(\n\t\t\t\t`Adding Neon MCP server and agent skills for ${options.agent}`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tintro(\n\t\t\t\"Adding Neon MCP server, extension (for VS Code and Cursor) and agent skills\",\n\t\t);\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\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// 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: 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, // 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(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\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\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":";;;;;;;;;;;AAiBA,eAAsB,KAAK,SAAsC;AAChE,KAAI,SAAS,UAAU,KAAA,EACtB,KAAI,cAAc,QAAQ,MAAM,CAC/B,OACC,oEAAoE,QAAQ,QAC5E;KAED,OACC,+CAA+C,QAAQ,QACvD;KAGF,OACC,8EACA;CAIF,MAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ,IAAI;AAChD,KAAI,CAAC,SAAS;AACb,MAAI,MAAM,qCAAqC;AAC/C,QAAM,wDAAwD;AAC9D,UAAQ,KAAK,EAAE;;CAGhB,IAAI;AAEJ,KAAI,SAAS,UAAU,KAAA,EACtB,mBAAkB,CAAC,QAAQ,MAAM;MAC3B;EAEN,MAAM,mBAAmB,MAAM,uBAAuB,QAAQ;EAG9D,MAAM,WAAW,MAAM,YAAY;GAClC,SACC;GACD,SAAS,wBAAwB,KAAK,WAAW;IAChD,OAAO,MAAM;IACb,OAAO,MAAM;IACb,MAAM,MAAM;IACZ,EAAE;GACH,eAAe;GACf,UAAU;GACV,CAAC;AAEF,MAAI,SAAS,SAAS,EAAE;AACvB,SAAM,yBAAyB;AAC/B,WAAQ,KAAK,EAAE;;AAGhB,oBAAkB;;AAGnB,KAAI,gBAAgB,WAAW,GAAG;AACjC,MAAI,KAAK,uBAAuB;AAChC,QAAM,yBAAyB;AAC/B,UAAQ,KAAK,EAAE;;CAIhB,MAAM,UAAU,MAAM,YAAY,gBAAgB;CAElD,MAAM,aAAuB,EAAE;CAC/B,MAAM,SAAmB,EAAE;AAE3B,MAAK,MAAM,CAAC,QAAQ,WAAW,QAAQ,SAAS,CAC/C,KAAI,WAAW,UACd,YAAW,KAAK,OAAO;KAEvB,QAAO,KAAK,OAAO;AAKrB,KAAI,WAAW,SAAS,EACvB,OAAM,mBAAmB,WAAW;CAIrC,MAAM,mBAAmB,WAAW,OAAO,cAAc;CACzD,MAAM,aAAa,WAAW,QAAQ,MAAM,CAAC,cAAc,EAAE,CAAC;CAC9D,MAAM,yBAAyB,OAAO,OAAO,cAAc;CAC3D,MAAM,mBAAmB,OAAO,QAAQ,MAAM,CAAC,cAAc,EAAE,CAAC;AAEhE,KAAI,iBAAiB,SAAS,GAAG;EAChC,MAAM,iBAAiB,iBAAiB,KAAK,MAAM;AACnD,MAAI,KACH,8CAA8C,eAAe,KAC7D;;AAGF,KAAI,WAAW,SAAS,GAAG;EAC1B,MAAM,iBAAiB,WAAW,KAAK,MAAM;AAC7C,MAAI,KACH,4CAA4C,eAAe,KAC3D;;AAIF,KAAI,uBAAuB,SAAS,GAAG;AACtC,MAAI,KACH,+GACA;AACD,OAAK,MAAM,UAAU,uBACpB,KAAI,WAAW,UACd,KAAI,KACH,iGACA;WACS,WAAW,SACrB,KAAI,KACH,2EACA;;AAKJ,KAAI,iBAAiB,SAAS,GAAG;AAChC,MAAI,MACH,sCAAsC,iBAAiB,KAAK,MAAM,GAClE;AACD,MAAI,KACH,8FACA;;AAIF,KAAI,WAAW,WAAW,GAAG;AAC5B,QACC,iFACA;AACD,UAAQ,KAAK,EAAE;;AAGhB,KAAI,iBAAiB,SAAS,KAAK,WAAW,WAAW,EAGxD,MACC,kBAFsB,iBAAiB,KAAK,MAAM,CAEjB,yCAAyC,KAAK,KAAK,wBAAwB,CAAC,CAAC,8BAC9G,eACA;UACS,WAAW,SAAS,KAAK,iBAAiB,WAAW,EAG/D,MACC,kBAFsB,WAAW,KAAK,MAAM,CAEX,gBAAgB,KAAK,KAAK,wBAAwB,CAAC,CAAC,uBACrF,eACA;KAGD,MACC,cAAc,iBAAiB,KAAK,MAAM,CAAC,kDAAkD,KAAK,KAAK,wBAAwB,CAAC,CAAC,0CAA0C,WAAW,KAAK,MAAM,CAAC,yBAAyB,KAAK,KAAK,wBAAwB,CAAC,CAAC,uBAC/P,eACA;AAGF,OAAM,gDAAgD"}
|
|
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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"}
|
|
@@ -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"}
|