neon 6.0.0 → 6.2.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/README.md +5 -1
- package/dist/_chunks/{env-DRpFX-_d.js → env-CtOH9xsl.js} +2 -1
- package/dist/_chunks/{env_services-DlXECBPi.js → env-N19A7qND.js} +13 -120
- package/dist/commands/auth.js +3 -1
- package/dist/commands/bootstrap.js +19 -17
- package/dist/commands/checkout.js +76 -6
- package/dist/commands/config.js +41 -0
- package/dist/commands/dev.js +3 -3
- package/dist/commands/env.js +3 -2
- package/dist/commands/git.js +356 -0
- package/dist/commands/index.js +5 -3
- package/dist/commands/init.js +2 -4
- package/dist/commands/link.js +2 -1
- package/dist/commands/mcp.js +67 -25
- package/dist/commands/plugins.js +54 -23
- package/dist/commands/skills.js +54 -23
- package/dist/commands/snapshots.js +23 -7
- package/dist/context.js +92 -3
- package/dist/dev/env.js +1 -1
- package/dist/env_services.js +120 -1
- package/dist/init/auth.js +84 -0
- package/dist/init/cancelled.js +26 -1
- package/dist/init/chrome.js +2 -19
- package/dist/init/detect.js +1 -1
- package/dist/init/plan.js +85 -63
- package/dist/init/run.js +30 -26
- package/dist/init/tooling.js +103 -21
- package/dist/init/wizard.js +1 -1
- package/dist/mcp/plan.js +1 -1
- package/dist/plugins/plan.js +1 -1
- package/dist/skills/plan.js +1 -1
- package/dist/utils/branch_name.js +29 -0
- package/dist/utils/git.js +220 -0
- package/dist/utils/hooks.js +230 -0
- package/package.json +5 -5
- package/dist/init/child.js +0 -49
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { isNeonApiError } from "../api.js";
|
|
2
|
+
import { r as defaultDir } from "../_chunks/paths-DMq0Lt7a.js";
|
|
3
|
+
import "../config.js";
|
|
4
|
+
import "../auth.js";
|
|
5
|
+
import { ensureAuth } from "../commands/auth.js";
|
|
6
|
+
import { recoverFrom401 } from "../auth_recovery.js";
|
|
7
|
+
import { pull } from "../commands/env.js";
|
|
8
|
+
import { setupNeonMcp } from "../commands/mcp.js";
|
|
9
|
+
//#region src/init/auth.ts
|
|
10
|
+
const isUnauthorized = (error) => isNeonApiError(error) && error.status === 401;
|
|
11
|
+
const authenticationFailed = () => /* @__PURE__ */ new Error("Authentication failed.");
|
|
12
|
+
/**
|
|
13
|
+
* Fills in the fields `ensureAuth` requires beyond `InitAuthOptions`, and sets `_` so
|
|
14
|
+
* `ensureAuth`'s per-command branches (`isMcpCommand`, `isSkillsCommand`, ...) treat this
|
|
15
|
+
* exactly like the standalone command it names — mirrors `init/link.ts`'s `runAuthenticatedLink`.
|
|
16
|
+
*/
|
|
17
|
+
const authContext = (options, command) => ({
|
|
18
|
+
...options,
|
|
19
|
+
_: [...command],
|
|
20
|
+
configDir: options.configDir ?? defaultDir,
|
|
21
|
+
oauthHost: options.oauthHost ?? process.env.NEON_OAUTH_HOST ?? "https://oauth2.neon.tech",
|
|
22
|
+
clientId: options.clientId ?? "neonctl",
|
|
23
|
+
help: false
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Resolves Neon auth the same way a standalone `neon mcp` invocation would, then runs
|
|
27
|
+
* `setupNeonMcp`. `init`/`bootstrap` never resolve a shared `apiClient` of their own for
|
|
28
|
+
* this (see `InitAuthOptions` above), so this is what does it, per call.
|
|
29
|
+
*
|
|
30
|
+
* Skips `ensureAuth` entirely when `options.oauth` is true: `setupNeonMcp`'s oauth branch
|
|
31
|
+
* never reads `apiClient`/`apiKey`, and `ensureAuth`'s own `isMcpOauth` skip reads the real
|
|
32
|
+
* `process.argv` for `--oauth` (documented there as required because that middleware runs
|
|
33
|
+
* before flag parsing) — which never contains it for a `neon init`/`bootstrap` process, so
|
|
34
|
+
* `ensureAuth` would otherwise try to resolve credentials it doesn't need and can fail on
|
|
35
|
+
* an unrelated bad profile or expired session.
|
|
36
|
+
*/
|
|
37
|
+
const runAuthenticatedMcp = async (options) => {
|
|
38
|
+
if (options.oauth === true) return setupNeonMcp(options);
|
|
39
|
+
const authenticated = authContext(options, ["mcp"]);
|
|
40
|
+
await ensureAuth(authenticated);
|
|
41
|
+
try {
|
|
42
|
+
return await setupNeonMcp(authenticated);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (!isUnauthorized(error)) throw error;
|
|
45
|
+
if (!await recoverFrom401(true)) throw authenticationFailed();
|
|
46
|
+
}
|
|
47
|
+
await ensureAuth(authenticated);
|
|
48
|
+
try {
|
|
49
|
+
return await setupNeonMcp(authenticated);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if (!isUnauthorized(error)) throw error;
|
|
52
|
+
await recoverFrom401(false);
|
|
53
|
+
throw authenticationFailed();
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Resolves Neon auth the same way a standalone `neon env pull` invocation would, then runs
|
|
58
|
+
* `pull` — the same function `link`/`checkout` already call directly via
|
|
59
|
+
* `autoPullEnvAfterPin` (see `commands/env.ts`).
|
|
60
|
+
*/
|
|
61
|
+
const pullInitEnv = async (props) => {
|
|
62
|
+
const authenticated = authContext(props, ["env", "pull"]);
|
|
63
|
+
await ensureAuth(authenticated);
|
|
64
|
+
const opts = {
|
|
65
|
+
announce: true,
|
|
66
|
+
implyAiGateway: true
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
return await pull(authenticated, opts);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (!isUnauthorized(error)) throw error;
|
|
72
|
+
if (!await recoverFrom401(true)) throw authenticationFailed();
|
|
73
|
+
}
|
|
74
|
+
await ensureAuth(authenticated);
|
|
75
|
+
try {
|
|
76
|
+
return await pull(authenticated, opts);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (!isUnauthorized(error)) throw error;
|
|
79
|
+
await recoverFrom401(false);
|
|
80
|
+
throw authenticationFailed();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
export { pullInitEnv, runAuthenticatedMcp };
|
package/dist/init/cancelled.js
CHANGED
|
@@ -5,6 +5,31 @@ var InitCancelled = class extends Error {
|
|
|
5
5
|
this.name = "InitCancelled";
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Rejects with {@link InitCancelled} on SIGINT while `work` is pending, so a step that runs
|
|
10
|
+
* fully in-process (no spawned child of its own to die and report the signal back) still
|
|
11
|
+
* unwinds through `runInit`'s normal cancellation handling — the "Neon setup cancelled."
|
|
12
|
+
* summary and the funnel's final telemetry — instead of Node's default SIGINT disposition
|
|
13
|
+
* killing the process with no chance to run either.
|
|
14
|
+
*
|
|
15
|
+
* Does not cancel `work` itself: there is no cooperative cancellation to ask for here, so a
|
|
16
|
+
* lost race leaves it running in the background, its eventual settlement discarded. That is
|
|
17
|
+
* fine — the process is already unwinding to exit on the `InitCancelled` path.
|
|
18
|
+
*/
|
|
19
|
+
const raceSigint = (work) => new Promise((resolve, reject) => {
|
|
20
|
+
const onSigint = () => reject(new InitCancelled());
|
|
21
|
+
process.once("SIGINT", onSigint);
|
|
22
|
+
const stop = () => {
|
|
23
|
+
process.removeListener("SIGINT", onSigint);
|
|
24
|
+
};
|
|
25
|
+
work.then((value) => {
|
|
26
|
+
stop();
|
|
27
|
+
resolve(value);
|
|
28
|
+
}, (error) => {
|
|
29
|
+
stop();
|
|
30
|
+
reject(error);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
8
33
|
const restoreCursor = () => {
|
|
9
34
|
process.stdout.write("\x1B[?25h");
|
|
10
35
|
process.stdout.write("\n");
|
|
@@ -13,4 +38,4 @@ const restoreCursorVisibilityOnAbort = (state) => {
|
|
|
13
38
|
if (state.aborted) process.stdout.write("\x1B[?25h");
|
|
14
39
|
};
|
|
15
40
|
//#endregion
|
|
16
|
-
export { InitCancelled, restoreCursor, restoreCursorVisibilityOnAbort };
|
|
41
|
+
export { InitCancelled, raceSigint, restoreCursor, restoreCursorVisibilityOnAbort };
|
package/dist/init/chrome.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isCi } from "../env.js";
|
|
2
|
-
import { HEADING_CANCELLED, HEADING_COMPLETE, HEADING_FAILED, HEADING_PENDING, INIT_SUBTITLE
|
|
2
|
+
import { HEADING_CANCELLED, HEADING_COMPLETE, HEADING_FAILED, HEADING_PENDING, INIT_SUBTITLE } from "./copy.js";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
//#region src/init/chrome.ts
|
|
5
5
|
const NEON_GREEN = "#4BB578";
|
|
@@ -89,23 +89,6 @@ const configRowValue = (config, filename) => {
|
|
|
89
89
|
if (config === "skipped" || config === null) return "skipped";
|
|
90
90
|
return config;
|
|
91
91
|
};
|
|
92
|
-
const INIT_STEP_LABELS = {
|
|
93
|
-
bootstrap: "Creating the app from the selected template...",
|
|
94
|
-
plugins: PROGRESS.plugins,
|
|
95
|
-
skills: PROGRESS.skills,
|
|
96
|
-
mcp: PROGRESS.mcp,
|
|
97
|
-
auth: PROGRESS.auth,
|
|
98
|
-
link: PROGRESS.link,
|
|
99
|
-
claim: PROGRESS.claim,
|
|
100
|
-
config: PROGRESS.config,
|
|
101
|
-
env: PROGRESS.env
|
|
102
|
-
};
|
|
103
|
-
const initStepLabel = (step) => {
|
|
104
|
-
const command = step[0];
|
|
105
|
-
if (command === void 0) return;
|
|
106
|
-
if (command === "config") return INIT_STEP_LABELS.config;
|
|
107
|
-
return INIT_STEP_LABELS[command];
|
|
108
|
-
};
|
|
109
92
|
const headingForKind = (kind) => {
|
|
110
93
|
switch (kind) {
|
|
111
94
|
case "success": return HEADING_COMPLETE;
|
|
@@ -116,4 +99,4 @@ const headingForKind = (kind) => {
|
|
|
116
99
|
}
|
|
117
100
|
};
|
|
118
101
|
//#endregion
|
|
119
|
-
export { INIT_BANNER_LINES,
|
|
102
|
+
export { INIT_BANNER_LINES, NEON_GREEN, agentSetupDoneLabel, agentSetupLabel, agentsRowValue, configRowValue, configSummaryLabel, formatInitBanner, formatInitDone, headingForKind, printInitBanner, printInitDone, printInitProgress, projectRowValue, shouldPrintInitBanner };
|
package/dist/init/detect.js
CHANGED
|
@@ -5,8 +5,8 @@ import { i as selectCredential, t as credentialInputs } from "../_chunks/auth_se
|
|
|
5
5
|
import { detectInstalledAgents, uniqueAgentIds } from "../mcp/agents.js";
|
|
6
6
|
import "./agents.js";
|
|
7
7
|
import { directoryIsEmpty } from "./plan.js";
|
|
8
|
-
import { canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
9
8
|
import { detectAgent } from "./detect_host.js";
|
|
9
|
+
import { canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
10
10
|
import { existsSync, readdirSync } from "node:fs";
|
|
11
11
|
import { detectProjectAgents } from "add-mcp";
|
|
12
12
|
//#region src/init/detect.ts
|
package/dist/init/plan.js
CHANGED
|
@@ -36,21 +36,47 @@ const postScaffoldActions = (input) => {
|
|
|
36
36
|
return actions;
|
|
37
37
|
};
|
|
38
38
|
const planAgentSteps = (input) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
if (input.agentSetup === "plugin") return [{
|
|
40
|
+
kind: "plugins",
|
|
41
|
+
options: { yes: input.yes }
|
|
42
|
+
}];
|
|
43
|
+
if (input.agentSetup === "skills-mcp") return [{
|
|
44
|
+
kind: "skills",
|
|
45
|
+
options: { yes: input.yes }
|
|
46
|
+
}, {
|
|
47
|
+
kind: "mcp",
|
|
48
|
+
options: { yes: input.yes }
|
|
49
|
+
}];
|
|
42
50
|
return [];
|
|
43
51
|
};
|
|
44
52
|
const planToolingSteps = (tooling, options) => {
|
|
45
|
-
const
|
|
46
|
-
const
|
|
53
|
+
const agentsFor = (ids) => options.named ? { agents: ids } : {};
|
|
54
|
+
const agentFor = (ids) => options.named ? { agent: [...ids] } : {};
|
|
47
55
|
switch (tooling.setup) {
|
|
48
56
|
case "skip": return [];
|
|
49
|
-
case "plugin": return [
|
|
57
|
+
case "plugin": return [{
|
|
58
|
+
kind: "plugins",
|
|
59
|
+
options: {
|
|
60
|
+
yes: options.yes,
|
|
61
|
+
...agentsFor(tooling.agents)
|
|
62
|
+
}
|
|
63
|
+
}];
|
|
50
64
|
case "skills-mcp": {
|
|
51
65
|
const steps = [];
|
|
52
|
-
if (tooling.skillsAgents.length > 0) steps.push(
|
|
53
|
-
|
|
66
|
+
if (tooling.skillsAgents.length > 0) steps.push({
|
|
67
|
+
kind: "skills",
|
|
68
|
+
options: {
|
|
69
|
+
yes: options.yes,
|
|
70
|
+
...agentsFor(tooling.skillsAgents)
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (tooling.mcpAgents.length > 0) steps.push({
|
|
74
|
+
kind: "mcp",
|
|
75
|
+
options: {
|
|
76
|
+
yes: options.yes,
|
|
77
|
+
...agentFor(tooling.mcpAgents)
|
|
78
|
+
}
|
|
79
|
+
});
|
|
54
80
|
return steps;
|
|
55
81
|
}
|
|
56
82
|
default: return tooling;
|
|
@@ -209,46 +235,63 @@ const recommendedTooling = (detected) => {
|
|
|
209
235
|
return split;
|
|
210
236
|
};
|
|
211
237
|
const planInitToolingSteps = (input) => {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
"
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
...input.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
...
|
|
228
|
-
...input.
|
|
229
|
-
|
|
230
|
-
...input.mcpProjectId !== void 0 ? ["--project-id", input.mcpProjectId] : []
|
|
231
|
-
];
|
|
232
|
-
const named = (ids) => agentArgv(ids);
|
|
238
|
+
const pluginOptions = (agents) => ({
|
|
239
|
+
yes: input.yes,
|
|
240
|
+
global: input.pluginScope === "global",
|
|
241
|
+
agents
|
|
242
|
+
});
|
|
243
|
+
const skillsOptions = (agents) => ({
|
|
244
|
+
yes: input.yes,
|
|
245
|
+
global: input.skillsGlobal,
|
|
246
|
+
agents,
|
|
247
|
+
...input.skills !== void 0 ? { skills: input.skills } : {}
|
|
248
|
+
});
|
|
249
|
+
const mcpOptions = (agents) => ({
|
|
250
|
+
yes: input.yes,
|
|
251
|
+
oauth: input.mcpOauth,
|
|
252
|
+
project: input.mcpProject === true,
|
|
253
|
+
agent: [...agents],
|
|
254
|
+
...input.mcpProjectId !== void 0 ? { projectId: input.mcpProjectId } : {}
|
|
255
|
+
});
|
|
233
256
|
switch (input.tooling.setup) {
|
|
234
257
|
case "skip": return [];
|
|
235
|
-
case "plugin": return [
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
258
|
+
case "plugin": return [{
|
|
259
|
+
kind: "plugins",
|
|
260
|
+
options: pluginOptions(input.tooling.agents)
|
|
261
|
+
}];
|
|
262
|
+
case "skills": return [{
|
|
263
|
+
kind: "skills",
|
|
264
|
+
options: {
|
|
265
|
+
yes: input.yes,
|
|
266
|
+
agents: input.tooling.agents,
|
|
267
|
+
...input.skills !== void 0 ? { skills: input.skills } : {}
|
|
268
|
+
}
|
|
269
|
+
}];
|
|
242
270
|
case "skills-mcp": {
|
|
243
271
|
const steps = [];
|
|
244
|
-
if (input.tooling.skillsAgents.length > 0) steps.push(
|
|
245
|
-
|
|
272
|
+
if (input.tooling.skillsAgents.length > 0) steps.push({
|
|
273
|
+
kind: "skills",
|
|
274
|
+
options: skillsOptions(input.tooling.skillsAgents)
|
|
275
|
+
});
|
|
276
|
+
if (input.tooling.mcpAgents.length > 0) steps.push({
|
|
277
|
+
kind: "mcp",
|
|
278
|
+
options: mcpOptions(input.tooling.mcpAgents)
|
|
279
|
+
});
|
|
246
280
|
return steps;
|
|
247
281
|
}
|
|
248
282
|
case "mixed": {
|
|
249
|
-
const steps = [
|
|
250
|
-
|
|
251
|
-
|
|
283
|
+
const steps = [{
|
|
284
|
+
kind: "plugins",
|
|
285
|
+
options: pluginOptions(input.tooling.pluginAgents)
|
|
286
|
+
}];
|
|
287
|
+
if (input.tooling.skillsAgents.length > 0) steps.push({
|
|
288
|
+
kind: "skills",
|
|
289
|
+
options: skillsOptions(input.tooling.skillsAgents)
|
|
290
|
+
});
|
|
291
|
+
if (input.tooling.mcpAgents.length > 0) steps.push({
|
|
292
|
+
kind: "mcp",
|
|
293
|
+
options: mcpOptions(input.tooling.mcpAgents)
|
|
294
|
+
});
|
|
252
295
|
return steps;
|
|
253
296
|
}
|
|
254
297
|
default: return input.tooling;
|
|
@@ -333,30 +376,9 @@ const linkInputArgv = (input) => {
|
|
|
333
376
|
if (input.branch) args.push("--branch", input.branch);
|
|
334
377
|
return args;
|
|
335
378
|
};
|
|
336
|
-
const planExistingInit = (input) => {
|
|
337
|
-
const steps = [...planAgentSteps(input)];
|
|
338
|
-
if (!input.linked) steps.push(planLinkStep({
|
|
339
|
-
yes: input.yes,
|
|
340
|
-
extra: input.linkExtra
|
|
341
|
-
}));
|
|
342
|
-
if (input.config.kind === "write") steps.push(planConfigInitStep({
|
|
343
|
-
yes: input.yes,
|
|
344
|
-
services: input.config.services
|
|
345
|
-
}));
|
|
346
|
-
return steps;
|
|
347
|
-
};
|
|
348
379
|
const resolveInitAgentSetup = async (input) => {
|
|
349
380
|
if (input.interactive) return input.pick();
|
|
350
381
|
throw new Error(INIT_NEEDS_YES_OR_TERMINAL);
|
|
351
382
|
};
|
|
352
|
-
const childArgv = (step, forward) => {
|
|
353
|
-
const args = [...step];
|
|
354
|
-
if (forward.configDir) args.push("--config-dir", forward.configDir);
|
|
355
|
-
if (forward.profile) args.push("--profile", forward.profile);
|
|
356
|
-
args.push("--api-host", forward.apiHost);
|
|
357
|
-
args.push("--context-file", forward.contextFile);
|
|
358
|
-
if (forward.analytics === false) args.push("--no-analytics");
|
|
359
|
-
return args;
|
|
360
|
-
};
|
|
361
383
|
//#endregion
|
|
362
|
-
export { FALLBACK_SKILLS_AGENTS, INIT_NEEDS_YES_OR_TERMINAL, NAMED_AGENTS_MIXED, NAMED_AGENTS_UNSUPPORTED, assertNamedAgentTooling, bootstrapInitStep,
|
|
384
|
+
export { FALLBACK_SKILLS_AGENTS, INIT_NEEDS_YES_OR_TERMINAL, NAMED_AGENTS_MIXED, NAMED_AGENTS_UNSUPPORTED, assertNamedAgentTooling, bootstrapInitStep, chooseYesAgentTooling, collectYesAgents, directoryIsEmpty, funnelAgentSetup, initPluginAgents, initSkillsMcpAgents, initYesSupportedAgents, linkInputArgv, namedAgentsMixedMessage, namedAgentsNeedSplit, noDetectedAgentsMessage, planAgentSteps, planConfigInitStep, planInitToolingSteps, planLinkStep, planToolingSteps, planYesAgentSteps, postScaffoldActions, projectContextFile, recommendedTooling, resolveInitAgentSetup, resolveNamedAgents, resolveYesAgentList, rewriteUnknownAgentArg, splitInitTooling };
|
package/dist/init/run.js
CHANGED
|
@@ -3,14 +3,11 @@ import { r as defaultDir } from "../_chunks/paths-DMq0Lt7a.js";
|
|
|
3
3
|
import "../config.js";
|
|
4
4
|
import { contextBranch, readContextFile } from "../context.js";
|
|
5
5
|
import { recordCommandSuccessExtras, takeCommandSuccessExtras } from "../analytics.js";
|
|
6
|
-
import { t as credentialInputs } from "../_chunks/auth_selection-pitMFzDe.js";
|
|
7
6
|
import "../claimable/api.js";
|
|
8
7
|
import { readLinkedClaimableCredentials } from "../claimable/state.js";
|
|
9
8
|
import { getCliName } from "../utils/cli_name.js";
|
|
10
9
|
import { deprecatedServiceMessage, parseServices, servicesFlagValue } from "../neon_services.js";
|
|
11
10
|
import { CONFIG_INIT_NONE_MEANS, CONFIG_INIT_SERVICES, CONFIG_INIT_UNAVAILABLE } from "../config_template.js";
|
|
12
|
-
import { InitCancelled, restoreCursor } from "./cancelled.js";
|
|
13
|
-
import { initChildEnv, spawnCliChild } from "./child.js";
|
|
14
11
|
import { CANCELLED_BODY, CLAIMABLE_ACCOUNT_FLAGS, CLAIMABLE_ALREADY_LINKED, CLAIMABLE_MCP_API_KEY, CLAIMABLE_NO_LINK, MCP_SCOPED_NEEDS_PROJECT, NON_TTY_LINK_NEEDS_AUTH, NO_AGENTS_FALLBACK_STATUS, PROGRESS, YES_LINK_NEEDS_AUTH, claimableNext, claimableThenServicesNext, envPullFailedNext, existingConfigNext, extraServicesNext, installFailedNext, mcpConfigLocationSkipped, mcpConfigLocationUnavailable, namedAgentsUnavailable, skippedLinkNext, unattendedUnauthedNext } from "./copy.js";
|
|
15
12
|
import { agentsRowValue, configRowValue, formatInitDone, headingForKind, printInitBanner, printInitDone, printInitProgress, projectRowValue, shouldPrintInitBanner } from "./chrome.js";
|
|
16
13
|
import { inferPackageManager, resolvePackageManager } from "../utils/package_manager.js";
|
|
@@ -20,8 +17,10 @@ import { mcpInstallableAgents } from "../mcp/targets.js";
|
|
|
20
17
|
import { pluginsInstallableAgents } from "../plugins/targets.js";
|
|
21
18
|
import { skillsInstallableAgents } from "../skills/targets.js";
|
|
22
19
|
import { FALLBACK_SKILLS_AGENTS, assertNamedAgentTooling, funnelAgentSetup, planInitToolingSteps, recommendedTooling, resolveNamedAgents, splitInitTooling } from "./plan.js";
|
|
20
|
+
import { pullInitEnv } from "./auth.js";
|
|
21
|
+
import { InitCancelled, raceSigint, restoreCursor } from "./cancelled.js";
|
|
23
22
|
import { pickAgentSetupInteractively, pickInitAgentsInteractively, pickInitConfigInteractively, pickInitMcpAuthInteractively, pickInitMcpConfigLocationInteractively, pickInitModeInteractively, pickInitPackageManagerInteractively, pickInitProjectSetupInteractively, pickInitServicesInteractively, pickInitSkillsInteractively } from "./wizard.js";
|
|
24
|
-
import {
|
|
23
|
+
import { runToolingSteps } from "./tooling.js";
|
|
25
24
|
import { create } from "../commands/claim.js";
|
|
26
25
|
import { INIT_CONFIG_SERVICES_CONFLICT, configPlanFromResolution, isBareInitServices, resolveInitConfigChoice, shouldPullEnvAfterInitConfig } from "./choices.js";
|
|
27
26
|
import { detectInitEnvironment } from "./detect.js";
|
|
@@ -153,16 +152,18 @@ const runInit = async (props) => {
|
|
|
153
152
|
...props.mcpAuth !== void 0 ? { mcpAuth: props.mcpAuth } : {},
|
|
154
153
|
...props.mcpProjectScoped === true ? { mcpProjectScoped: true } : {}
|
|
155
154
|
});
|
|
156
|
-
const run = props.run ?? spawnCliChild;
|
|
157
|
-
const explicitKey = props.profile ? "" : credentialInputs().apiKeyFlag;
|
|
158
|
-
const authEnv = explicitKey ? { NEON_API_KEY: explicitKey } : void 0;
|
|
159
155
|
const configDir = props.configDir ?? defaultDir;
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
const auth = {
|
|
157
|
+
apiClient: props.apiClient,
|
|
158
|
+
apiKey: props.apiKey,
|
|
163
159
|
apiHost: props.apiHost,
|
|
164
160
|
contextFile,
|
|
165
|
-
...props.
|
|
161
|
+
...props.configDir ? { configDir: props.configDir } : {},
|
|
162
|
+
...props.profile ? { profile: props.profile } : {},
|
|
163
|
+
...props.oauthHost ? { oauthHost: props.oauthHost } : {},
|
|
164
|
+
...props.clientId ? { clientId: props.clientId } : {},
|
|
165
|
+
...props.forceAuth !== void 0 ? { forceAuth: props.forceAuth } : {},
|
|
166
|
+
...props.allowUnsafeTls !== void 0 ? { allowUnsafeTls: props.allowUnsafeTls } : {}
|
|
166
167
|
};
|
|
167
168
|
const servicesFlag = parsedInitServices(props.services);
|
|
168
169
|
if (props.config === false && servicesFlag !== void 0) throw new Error(INIT_CONFIG_SERVICES_CONFLICT);
|
|
@@ -320,11 +321,11 @@ const runInit = async (props) => {
|
|
|
320
321
|
...selectedSkills !== void 0 ? { skills: selectedSkills } : {}
|
|
321
322
|
});
|
|
322
323
|
if (toolingSteps.length > 0) {
|
|
323
|
-
await
|
|
324
|
+
await runToolingSteps(toolingSteps, {
|
|
324
325
|
cwd,
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
output: props.output,
|
|
327
|
+
auth,
|
|
328
|
+
operations: props.operations,
|
|
328
329
|
narrate: "human"
|
|
329
330
|
});
|
|
330
331
|
funnel.agentsInstalled = agentsFromTooling(earlyTooling);
|
|
@@ -420,11 +421,11 @@ const runInit = async (props) => {
|
|
|
420
421
|
...pinId !== void 0 ? { mcpProjectId: pinId } : {}
|
|
421
422
|
});
|
|
422
423
|
if (mcpSteps.length > 0) {
|
|
423
|
-
await
|
|
424
|
+
await runToolingSteps(mcpSteps, {
|
|
424
425
|
cwd,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
426
|
+
output: props.output,
|
|
427
|
+
auth,
|
|
428
|
+
operations: props.operations,
|
|
428
429
|
narrate: "human"
|
|
429
430
|
});
|
|
430
431
|
funnel.agentsInstalled = uniqueAgents([...funnel.agentsInstalled, ...agentsFromTooling(mcpOnly)]);
|
|
@@ -509,14 +510,17 @@ const runInit = async (props) => {
|
|
|
509
510
|
...typeof context.projectId === "string" ? { projectId: context.projectId } : {},
|
|
510
511
|
...branch !== void 0 ? { branch } : {}
|
|
511
512
|
})) try {
|
|
512
|
-
|
|
513
|
+
if (typeof context.projectId !== "string" || typeof branch !== "string") throw new Error("Env pull requires a linked project and branch.");
|
|
514
|
+
printInitProgress(PROGRESS.env);
|
|
515
|
+
await raceSigint((props.envPull ?? pullInitEnv)({
|
|
516
|
+
...auth,
|
|
517
|
+
output: props.output,
|
|
513
518
|
cwd,
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
narrate: "human"
|
|
518
|
-
});
|
|
519
|
+
projectId: context.projectId,
|
|
520
|
+
branch
|
|
521
|
+
}));
|
|
519
522
|
} catch (error) {
|
|
523
|
+
if (error instanceof InitCancelled) throw error;
|
|
520
524
|
const failed = envPullFailedNext();
|
|
521
525
|
printInitDone(formatInitDone({
|
|
522
526
|
heading: failed.heading,
|
|
@@ -638,4 +642,4 @@ const agentsFromTooling = (tooling) => {
|
|
|
638
642
|
}
|
|
639
643
|
};
|
|
640
644
|
//#endregion
|
|
641
|
-
export {
|
|
645
|
+
export { runInit };
|
package/dist/init/tooling.js
CHANGED
|
@@ -1,23 +1,109 @@
|
|
|
1
1
|
import { log } from "../log.js";
|
|
2
2
|
import { getCliName } from "../utils/cli_name.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { assertNamedAgentTooling, childArgv, chooseYesAgentTooling, collectYesAgents, initYesSupportedAgents, noDetectedAgentsMessage, planAgentSteps, planToolingSteps, planYesAgentSteps, resolveInitAgentSetup } from "./plan.js";
|
|
6
|
-
import { canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
3
|
+
import { PROGRESS } from "./copy.js";
|
|
4
|
+
import { assertNamedAgentTooling, chooseYesAgentTooling, collectYesAgents, initYesSupportedAgents, noDetectedAgentsMessage, planAgentSteps, planToolingSteps, planYesAgentSteps, resolveInitAgentSetup } from "./plan.js";
|
|
7
5
|
import { detectAgent } from "./detect_host.js";
|
|
6
|
+
import { canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
7
|
+
import { mcpInstallError, reportMcpInstall } from "../commands/mcp.js";
|
|
8
|
+
import { installPlugins, pluginsInstallError, reportPluginsInstall } from "../commands/plugins.js";
|
|
9
|
+
import { installSkills, reportSkillsInstall, skillsInstallError } from "../commands/skills.js";
|
|
10
|
+
import { runAuthenticatedMcp } from "./auth.js";
|
|
11
|
+
import { raceSigint } from "./cancelled.js";
|
|
8
12
|
import { pickAgentSetupInteractively } from "./wizard.js";
|
|
9
13
|
import { detectProjectAgents } from "add-mcp";
|
|
10
14
|
//#region src/init/tooling.ts
|
|
11
15
|
const defaultProjectAgents = (cwd) => detectProjectAgents(cwd);
|
|
12
|
-
const
|
|
16
|
+
const TOOLING_STEP_LABELS = {
|
|
17
|
+
plugins: PROGRESS.plugins,
|
|
18
|
+
skills: PROGRESS.skills,
|
|
19
|
+
mcp: PROGRESS.mcp
|
|
20
|
+
};
|
|
21
|
+
/** Reconstructs a display-only, `neon <command> <flags>` style string for a step. Never executed — only ever logged. */
|
|
22
|
+
const toolingStepCommandText = (step) => {
|
|
23
|
+
const flags = [];
|
|
24
|
+
switch (step.kind) {
|
|
25
|
+
case "plugins": {
|
|
26
|
+
const { options } = step;
|
|
27
|
+
if (options.yes) flags.push("-y");
|
|
28
|
+
if (options.global) flags.push("--global");
|
|
29
|
+
for (const agent of options.agents ?? []) flags.push("--agent", agent);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case "skills": {
|
|
33
|
+
const { options } = step;
|
|
34
|
+
if (options.yes) flags.push("-y");
|
|
35
|
+
if (options.global) flags.push("--global");
|
|
36
|
+
for (const skill of options.skills ?? []) flags.push("--skill", skill);
|
|
37
|
+
for (const agent of options.agents ?? []) flags.push("--agent", agent);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "mcp": {
|
|
41
|
+
const { options } = step;
|
|
42
|
+
if (options.yes) flags.push("-y");
|
|
43
|
+
if (options.oauth) flags.push("--oauth");
|
|
44
|
+
if (options.project) flags.push("--project");
|
|
45
|
+
if (options.projectId !== void 0) flags.push("--project-id", options.projectId);
|
|
46
|
+
for (const agent of options.agent ?? []) flags.push("--agent", agent);
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
default: return step;
|
|
50
|
+
}
|
|
51
|
+
return [step.kind, ...flags].join(" ");
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Runs plugins/skills/mcp installs in-process, in order, via {@link ToolingOperations}. This
|
|
55
|
+
* replaces re-executing the `neon` binary as a child process (`neon plugins`, `neon skills`,
|
|
56
|
+
* `neon mcp`) to reuse those commands — see `packages/cli/AGENTS.md`.
|
|
57
|
+
*/
|
|
58
|
+
const runToolingSteps = async (steps, options) => {
|
|
59
|
+
const ops = {
|
|
60
|
+
installPlugins,
|
|
61
|
+
installSkills,
|
|
62
|
+
installMcp: (stepOptions) => runAuthenticatedMcp({
|
|
63
|
+
...stepOptions,
|
|
64
|
+
...options.auth
|
|
65
|
+
}),
|
|
66
|
+
...options.operations
|
|
67
|
+
};
|
|
68
|
+
const reportProps = { output: options.output };
|
|
13
69
|
for (const step of steps) {
|
|
14
|
-
const label = options.narrate === "human" ?
|
|
70
|
+
const label = options.narrate === "human" ? TOOLING_STEP_LABELS[step.kind] : void 0;
|
|
15
71
|
if (label !== void 0) process.stdout.write(`${label}\n`);
|
|
16
|
-
else log.info("Running `%s %s`", getCliName(), step
|
|
17
|
-
log.debug("Running `%s %s`", getCliName(), step
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
72
|
+
else log.info("Running `%s %s`", getCliName(), toolingStepCommandText(step));
|
|
73
|
+
log.debug("Running `%s %s`", getCliName(), toolingStepCommandText(step));
|
|
74
|
+
switch (step.kind) {
|
|
75
|
+
case "plugins": {
|
|
76
|
+
const outcome = await raceSigint(ops.installPlugins({
|
|
77
|
+
...step.options,
|
|
78
|
+
cwd: options.cwd
|
|
79
|
+
}));
|
|
80
|
+
reportPluginsInstall(reportProps, outcome);
|
|
81
|
+
const error = pluginsInstallError(outcome);
|
|
82
|
+
if (error) throw error;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case "skills": {
|
|
86
|
+
const outcome = await raceSigint(ops.installSkills({
|
|
87
|
+
...step.options,
|
|
88
|
+
cwd: options.cwd
|
|
89
|
+
}));
|
|
90
|
+
reportSkillsInstall(reportProps, outcome);
|
|
91
|
+
const error = skillsInstallError(outcome);
|
|
92
|
+
if (error) throw error;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "mcp": {
|
|
96
|
+
const outcome = await raceSigint(ops.installMcp({
|
|
97
|
+
...step.options,
|
|
98
|
+
cwd: options.cwd
|
|
99
|
+
}));
|
|
100
|
+
reportMcpInstall(reportProps, outcome);
|
|
101
|
+
const error = mcpInstallError(outcome);
|
|
102
|
+
if (error) throw error;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
default: return step;
|
|
106
|
+
}
|
|
21
107
|
}
|
|
22
108
|
};
|
|
23
109
|
const yesAgentsFromOptions = async (options) => collectYesAgents({
|
|
@@ -36,14 +122,14 @@ const runAgentTooling = async (options) => {
|
|
|
36
122
|
if (named.length > 0) {
|
|
37
123
|
assertNamedAgentTooling(named, options.command ?? "init");
|
|
38
124
|
const tooling = chooseYesAgentTooling(named);
|
|
39
|
-
await
|
|
125
|
+
await runToolingSteps(planToolingSteps(tooling, {
|
|
40
126
|
yes,
|
|
41
127
|
named: true
|
|
42
128
|
}), options);
|
|
43
129
|
return tooling.setup;
|
|
44
130
|
}
|
|
45
131
|
if (options.agentSetup !== void 0) {
|
|
46
|
-
await
|
|
132
|
+
await runToolingSteps(planAgentSteps({
|
|
47
133
|
yes,
|
|
48
134
|
agentSetup: options.agentSetup
|
|
49
135
|
}), options);
|
|
@@ -52,7 +138,7 @@ const runAgentTooling = async (options) => {
|
|
|
52
138
|
if (yes) {
|
|
53
139
|
if (options.hasProjectPlugins !== void 0) {
|
|
54
140
|
const agentSetup = await options.hasProjectPlugins(options.cwd) ? "plugin" : "skills-mcp";
|
|
55
|
-
await
|
|
141
|
+
await runToolingSteps(planAgentSteps({
|
|
56
142
|
yes: true,
|
|
57
143
|
agentSetup
|
|
58
144
|
}), options);
|
|
@@ -61,7 +147,7 @@ const runAgentTooling = async (options) => {
|
|
|
61
147
|
const agents = await yesAgentsFromOptions(options);
|
|
62
148
|
const tooling = chooseYesAgentTooling(agents);
|
|
63
149
|
if (tooling.setup === "skip") throw yesMiss();
|
|
64
|
-
await
|
|
150
|
+
await runToolingSteps(planYesAgentSteps(tooling), options);
|
|
65
151
|
return tooling.setup;
|
|
66
152
|
}
|
|
67
153
|
const interactive = options.pickAgentSetup !== void 0 || canPickAgentsInteractively();
|
|
@@ -69,15 +155,11 @@ const runAgentTooling = async (options) => {
|
|
|
69
155
|
interactive,
|
|
70
156
|
pick: options.pickAgentSetup ?? pickAgentSetupInteractively
|
|
71
157
|
});
|
|
72
|
-
await
|
|
158
|
+
await runToolingSteps(planAgentSteps({
|
|
73
159
|
yes,
|
|
74
160
|
agentSetup
|
|
75
161
|
}), options);
|
|
76
162
|
return agentSetup;
|
|
77
163
|
};
|
|
78
|
-
const runScaffoldFollowUp = async (options) => {
|
|
79
|
-
if (!options.skipAgentSetup) await runAgentTooling(options);
|
|
80
|
-
if (options.shouldLink) await runInitSteps([options.linkYes ? ["link", "--yes"] : ["link"]], options);
|
|
81
|
-
};
|
|
82
164
|
//#endregion
|
|
83
|
-
export { runAgentTooling,
|
|
165
|
+
export { runAgentTooling, runToolingSteps };
|
package/dist/init/wizard.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { CONFIG_INIT_SERVICES } from "../config_template.js";
|
|
2
|
-
import { InitCancelled, restoreCursorVisibilityOnAbort } from "./cancelled.js";
|
|
3
2
|
import { AGENT_DETECTED_DESCRIPTION, AGENT_OTHER_DESCRIPTION, AGENT_PICKER_MESSAGE, AGENT_SETUP_MESSAGE, AGENT_SETUP_PLUGIN_DESCRIPTION, AGENT_SETUP_PLUGIN_TITLE, AGENT_SETUP_SKILLS_DESCRIPTION, AGENT_SETUP_SKILLS_TITLE, AGENT_SETUP_SKIP_DESCRIPTION, AGENT_SETUP_SKIP_TITLE, CONFIG_CONFIRM_HINT, CONFIG_CONFIRM_MESSAGE, MCP_AUTH_API_KEY_DESCRIPTION, MCP_AUTH_API_KEY_TITLE, MCP_AUTH_MESSAGE, MCP_AUTH_OAUTH_DESCRIPTION, MCP_AUTH_OAUTH_TITLE, MCP_SCOPE_GLOBAL_DESCRIPTION, MCP_SCOPE_GLOBAL_TITLE, MCP_SCOPE_MESSAGE, MCP_SCOPE_PROJECT_DESCRIPTION, MCP_SCOPE_PROJECT_TITLE, MODE_CUSTOM_DESCRIPTION, MODE_CUSTOM_TITLE, MODE_MESSAGE, MODE_RECOMMENDED_DESCRIPTION, MODE_RECOMMENDED_TITLE, PACKAGE_MANAGER_MESSAGE, PROJECT_SETUP_CLAIMABLE_DESCRIPTION, PROJECT_SETUP_CLAIMABLE_TITLE, PROJECT_SETUP_LINK_DESCRIPTION, PROJECT_SETUP_LINK_TITLE, PROJECT_SETUP_MESSAGE, SERVICES_HINT, SERVICES_MESSAGE, SKILLS_PICKER_MESSAGE } from "./copy.js";
|
|
4
3
|
import { installedPackageManagers } from "../utils/package_manager.js";
|
|
5
4
|
import { POSTGRES_SERVICE_CHOICE, keepPostgresSelected } from "../utils/service_picker.js";
|
|
@@ -7,6 +6,7 @@ import { getAgentDisplayName, listMcpAgentIds } from "../mcp/agents.js";
|
|
|
7
6
|
import { INIT_NEEDS_YES_OR_TERMINAL } from "./plan.js";
|
|
8
7
|
import { canPickAgentsInteractively } from "../utils/agent_picker.js";
|
|
9
8
|
import { NEON_SKILL_CATALOG, listSkillIds } from "../skills/catalog.js";
|
|
9
|
+
import { InitCancelled, restoreCursorVisibilityOnAbort } from "./cancelled.js";
|
|
10
10
|
import chalk from "chalk";
|
|
11
11
|
import prompts from "prompts";
|
|
12
12
|
//#region src/init/wizard.ts
|