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.
- package/dist/cli.js +368 -33
- 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 +220 -41
- 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 +23 -0
- package/dist/lib/agents.d.ts.map +1 -0
- package/dist/lib/agents.js +148 -0
- package/dist/lib/agents.js.map +1 -0
- package/dist/lib/auth.d.ts +10 -3
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +20 -13
- 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 +1 -2
- 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 +29 -9
- 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 +74 -71
- package/dist/lib/install.js.map +1 -1
- package/dist/lib/neonctl.d.ts +32 -0
- package/dist/lib/neonctl.d.ts.map +1 -0
- package/dist/lib/neonctl.js +149 -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 +188 -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 +258 -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 +195 -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 +117 -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 +21 -4
- package/dist/lib/skills.d.ts.map +1 -1
- package/dist/lib/skills.js +129 -22
- package/dist/lib/skills.js.map +1 -1
- package/dist/lib/types.d.ts +146 -13
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +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 +9 -4
- package/dist/lib/mcp-config.d.ts +0 -24
- package/dist/lib/mcp-config.d.ts.map +0 -1
- package/dist/lib/mcp-config.js +0 -51
- package/dist/lib/mcp-config.js.map +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/lib/vsix.d.ts
|
|
2
|
+
declare const NEON_EXTENSION_ID = "databricks.neon-local-connect";
|
|
3
|
+
/**
|
|
4
|
+
* Downloads a .vsix file for the Neon extension.
|
|
5
|
+
*
|
|
6
|
+
* Strategy:
|
|
7
|
+
* 1. If NEON_VSX_GALLERY_URL is set, download from the corporate proxy gallery
|
|
8
|
+
* 2. Otherwise, download from the public Open VSX API
|
|
9
|
+
*
|
|
10
|
+
* Returns the path to the temp .vsix file, or null on failure.
|
|
11
|
+
*/
|
|
12
|
+
declare function downloadVsix(): Promise<string | null>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { NEON_EXTENSION_ID, downloadVsix };
|
|
15
|
+
//# sourceMappingURL=vsix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vsix.d.ts","names":[],"sources":["../../src/lib/vsix.ts"],"mappings":";cASa,iBAAA;AAAb;AAYA;;;;;;;;iBAAsB,YAAA,CAAA,GAAgB"}
|
package/dist/lib/vsix.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createWriteStream } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { pipeline } from "node:stream/promises";
|
|
5
|
+
//#region src/lib/vsix.ts
|
|
6
|
+
/**
|
|
7
|
+
* Shared VSIX download utilities for extension installation.
|
|
8
|
+
* Supports corporate proxy via NEON_VSX_GALLERY_URL env var.
|
|
9
|
+
*/
|
|
10
|
+
const NEON_EXTENSION_ID = "databricks.neon-local-connect";
|
|
11
|
+
const OPEN_VSX_API = "https://open-vsx.org/api";
|
|
12
|
+
/**
|
|
13
|
+
* Downloads a .vsix file for the Neon extension.
|
|
14
|
+
*
|
|
15
|
+
* Strategy:
|
|
16
|
+
* 1. If NEON_VSX_GALLERY_URL is set, download from the corporate proxy gallery
|
|
17
|
+
* 2. Otherwise, download from the public Open VSX API
|
|
18
|
+
*
|
|
19
|
+
* Returns the path to the temp .vsix file, or null on failure.
|
|
20
|
+
*/
|
|
21
|
+
async function downloadVsix() {
|
|
22
|
+
const { INTERNAL_VSX_GALLERY } = await import("./build-config.js");
|
|
23
|
+
const proxyGallery = process.env.NEON_VSX_GALLERY_URL || INTERNAL_VSX_GALLERY || "";
|
|
24
|
+
if (proxyGallery) return downloadFromGallery(proxyGallery);
|
|
25
|
+
return downloadFromOpenVsx();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Downloads from a VS Code marketplace-compatible gallery API (corporate proxy).
|
|
29
|
+
* Uses the VS Code extensionquery POST API to find the VSIX download URL.
|
|
30
|
+
*/
|
|
31
|
+
async function downloadFromGallery(galleryUrl) {
|
|
32
|
+
const [publisher, name] = NEON_EXTENSION_ID.split(".");
|
|
33
|
+
const queryUrl = `${galleryUrl.replace(/\/+$/, "")}/extensionquery`;
|
|
34
|
+
try {
|
|
35
|
+
const queryRes = await fetch(queryUrl, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: {
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
Accept: "application/json;api-version=6.1-preview.1"
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify({
|
|
42
|
+
filters: [{ criteria: [{
|
|
43
|
+
filterType: 7,
|
|
44
|
+
value: `${publisher}.${name}`
|
|
45
|
+
}] }],
|
|
46
|
+
flags: 914
|
|
47
|
+
}),
|
|
48
|
+
signal: AbortSignal.timeout(15e3)
|
|
49
|
+
});
|
|
50
|
+
if (!queryRes.ok) return null;
|
|
51
|
+
const vsixFile = (((await queryRes.json()).results?.[0]?.extensions?.[0])?.versions?.[0])?.files?.find((f) => f.assetType === "Microsoft.VisualStudio.Services.VSIXPackage");
|
|
52
|
+
if (!vsixFile?.source) return null;
|
|
53
|
+
const vsixRes = await fetch(vsixFile.source, {
|
|
54
|
+
signal: AbortSignal.timeout(3e4),
|
|
55
|
+
redirect: "follow"
|
|
56
|
+
});
|
|
57
|
+
if (!vsixRes.ok || !vsixRes.body) return null;
|
|
58
|
+
const tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-proxy.vsix`);
|
|
59
|
+
const fileStream = createWriteStream(tmpPath);
|
|
60
|
+
await pipeline(vsixRes.body, fileStream);
|
|
61
|
+
return tmpPath;
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Downloads from the public Open VSX API.
|
|
68
|
+
*/
|
|
69
|
+
async function downloadFromOpenVsx() {
|
|
70
|
+
const [publisher, name] = NEON_EXTENSION_ID.split(".");
|
|
71
|
+
const metaUrl = `${OPEN_VSX_API}/${publisher}/${name}/latest`;
|
|
72
|
+
try {
|
|
73
|
+
const metaRes = await fetch(metaUrl, { signal: AbortSignal.timeout(1e4) });
|
|
74
|
+
if (!metaRes.ok) return null;
|
|
75
|
+
const meta = await metaRes.json();
|
|
76
|
+
const downloadUrl = meta.files?.download;
|
|
77
|
+
if (!downloadUrl) return null;
|
|
78
|
+
const vsixRes = await fetch(downloadUrl, { signal: AbortSignal.timeout(3e4) });
|
|
79
|
+
if (!vsixRes.ok || !vsixRes.body) return null;
|
|
80
|
+
const tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-${meta.version ?? "latest"}.vsix`);
|
|
81
|
+
const fileStream = createWriteStream(tmpPath);
|
|
82
|
+
await pipeline(vsixRes.body, fileStream);
|
|
83
|
+
return tmpPath;
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { NEON_EXTENSION_ID, downloadVsix };
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=vsix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vsix.js","names":[],"sources":["../../src/lib/vsix.ts"],"sourcesContent":["/**\n * Shared VSIX download utilities for extension installation.\n * Supports corporate proxy via NEON_VSX_GALLERY_URL env var.\n */\nimport { createWriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\n\nexport const NEON_EXTENSION_ID = \"databricks.neon-local-connect\";\nconst OPEN_VSX_API = \"https://open-vsx.org/api\";\n\n/**\n * Downloads a .vsix file for the Neon extension.\n *\n * Strategy:\n * 1. If NEON_VSX_GALLERY_URL is set, download from the corporate proxy gallery\n * 2. Otherwise, download from the public Open VSX API\n *\n * Returns the path to the temp .vsix file, or null on failure.\n */\nexport async function downloadVsix(): Promise<string | null> {\n\t// Runtime env var takes priority, then build-time baked value\n\tconst { INTERNAL_VSX_GALLERY } = await import(\"./build-config.js\");\n\tconst proxyGallery =\n\t\tprocess.env.NEON_VSX_GALLERY_URL || INTERNAL_VSX_GALLERY || \"\";\n\tif (proxyGallery) {\n\t\treturn downloadFromGallery(proxyGallery);\n\t}\n\treturn downloadFromOpenVsx();\n}\n\n/**\n * Downloads from a VS Code marketplace-compatible gallery API (corporate proxy).\n * Uses the VS Code extensionquery POST API to find the VSIX download URL.\n */\nasync function downloadFromGallery(galleryUrl: string): Promise<string | null> {\n\tconst [publisher, name] = NEON_EXTENSION_ID.split(\".\");\n\tconst baseUrl = galleryUrl.replace(/\\/+$/, \"\");\n\tconst queryUrl = `${baseUrl}/extensionquery`;\n\n\ttry {\n\t\t// Query the marketplace API for the extension\n\t\tconst queryRes = await fetch(queryUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAccept: \"application/json;api-version=6.1-preview.1\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcriteria: [\n\t\t\t\t\t\t\t{ filterType: 7, value: `${publisher}.${name}` },\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tflags: 914,\n\t\t\t}),\n\t\t\tsignal: AbortSignal.timeout(15000),\n\t\t});\n\n\t\tif (!queryRes.ok) return null;\n\n\t\tconst data = (await queryRes.json()) as {\n\t\t\tresults?: {\n\t\t\t\textensions?: {\n\t\t\t\t\tversions?: {\n\t\t\t\t\t\tfiles?: { assetType: string; source: string }[];\n\t\t\t\t\t}[];\n\t\t\t\t}[];\n\t\t\t}[];\n\t\t};\n\n\t\t// Find the VSIX download URL from the response\n\t\tconst extension = data.results?.[0]?.extensions?.[0];\n\t\tconst latestVersion = extension?.versions?.[0];\n\t\tconst vsixFile = latestVersion?.files?.find(\n\t\t\t(f) =>\n\t\t\t\tf.assetType === \"Microsoft.VisualStudio.Services.VSIXPackage\",\n\t\t);\n\n\t\tif (!vsixFile?.source) return null;\n\n\t\t// Download the VSIX\n\t\tconst vsixRes = await fetch(vsixFile.source, {\n\t\t\tsignal: AbortSignal.timeout(30000),\n\t\t\tredirect: \"follow\",\n\t\t});\n\t\tif (!vsixRes.ok || !vsixRes.body) return null;\n\n\t\tconst tmpPath = join(tmpdir(), `${NEON_EXTENSION_ID}-proxy.vsix`);\n\t\tconst fileStream = createWriteStream(tmpPath);\n\t\tawait pipeline(\n\t\t\tvsixRes.body as unknown as NodeJS.ReadableStream,\n\t\t\tfileStream,\n\t\t);\n\t\treturn tmpPath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Downloads from the public Open VSX API.\n */\nasync function downloadFromOpenVsx(): Promise<string | null> {\n\tconst [publisher, name] = NEON_EXTENSION_ID.split(\".\");\n\tconst metaUrl = `${OPEN_VSX_API}/${publisher}/${name}/latest`;\n\n\ttry {\n\t\tconst metaRes = await fetch(metaUrl, {\n\t\t\tsignal: AbortSignal.timeout(10000),\n\t\t});\n\t\tif (!metaRes.ok) return null;\n\n\t\tconst meta = (await metaRes.json()) as {\n\t\t\tfiles?: { download?: string };\n\t\t\tversion?: string;\n\t\t};\n\t\tconst downloadUrl = meta.files?.download;\n\t\tif (!downloadUrl) return null;\n\n\t\tconst vsixRes = await fetch(downloadUrl, {\n\t\t\tsignal: AbortSignal.timeout(30000),\n\t\t});\n\t\tif (!vsixRes.ok || !vsixRes.body) return null;\n\n\t\tconst tmpPath = join(\n\t\t\ttmpdir(),\n\t\t\t`${NEON_EXTENSION_ID}-${meta.version ?? \"latest\"}.vsix`,\n\t\t);\n\t\tconst fileStream = createWriteStream(tmpPath);\n\t\tawait pipeline(\n\t\t\tvsixRes.body as unknown as NodeJS.ReadableStream,\n\t\t\tfileStream,\n\t\t);\n\t\treturn tmpPath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,oBAAoB;AACjC,MAAM,eAAe;;;;;;;;;;AAWrB,eAAsB,eAAuC;CAE5D,MAAM,EAAE,yBAAyB,MAAM,OAAO;CAC9C,MAAM,eACL,QAAQ,IAAI,wBAAwB,wBAAwB;CAC7D,IAAI,cACH,OAAO,oBAAoB,YAAY;CAExC,OAAO,oBAAoB;AAC5B;;;;;AAMA,eAAe,oBAAoB,YAA4C;CAC9E,MAAM,CAAC,WAAW,QAAQ,kBAAkB,MAAM,GAAG;CAErD,MAAM,WAAW,GADD,WAAW,QAAQ,QAAQ,EACjB,EAAE;CAE5B,IAAI;EAEH,MAAM,WAAW,MAAM,MAAM,UAAU;GACtC,QAAQ;GACR,SAAS;IACR,gBAAgB;IAChB,QAAQ;GACT;GACA,MAAM,KAAK,UAAU;IACpB,SAAS,CACR,EACC,UAAU,CACT;KAAE,YAAY;KAAG,OAAO,GAAG,UAAU,GAAG;IAAO,CAChD,EACD,CACD;IACA,OAAO;GACR,CAAC;GACD,QAAQ,YAAY,QAAQ,IAAK;EAClC,CAAC;EAED,IAAI,CAAC,SAAS,IAAI,OAAO;EAezB,MAAM,cAFY,MAXE,SAAS,KAAK,EAAA,CAWX,UAAU,EAAE,EAAE,aAAa,EAAE,GACnB,WAAW,EAAE,GACd,OAAO,MACrC,MACA,EAAE,cAAc,6CAClB;EAEA,IAAI,CAAC,UAAU,QAAQ,OAAO;EAG9B,MAAM,UAAU,MAAM,MAAM,SAAS,QAAQ;GAC5C,QAAQ,YAAY,QAAQ,GAAK;GACjC,UAAU;EACX,CAAC;EACD,IAAI,CAAC,QAAQ,MAAM,CAAC,QAAQ,MAAM,OAAO;EAEzC,MAAM,UAAU,KAAK,OAAO,GAAG,GAAG,kBAAkB,YAAY;EAChE,MAAM,aAAa,kBAAkB,OAAO;EAC5C,MAAM,SACL,QAAQ,MACR,UACD;EACA,OAAO;CACR,QAAQ;EACP,OAAO;CACR;AACD;;;;AAKA,eAAe,sBAA8C;CAC5D,MAAM,CAAC,WAAW,QAAQ,kBAAkB,MAAM,GAAG;CACrD,MAAM,UAAU,GAAG,aAAa,GAAG,UAAU,GAAG,KAAK;CAErD,IAAI;EACH,MAAM,UAAU,MAAM,MAAM,SAAS,EACpC,QAAQ,YAAY,QAAQ,GAAK,EAClC,CAAC;EACD,IAAI,CAAC,QAAQ,IAAI,OAAO;EAExB,MAAM,OAAQ,MAAM,QAAQ,KAAK;EAIjC,MAAM,cAAc,KAAK,OAAO;EAChC,IAAI,CAAC,aAAa,OAAO;EAEzB,MAAM,UAAU,MAAM,MAAM,aAAa,EACxC,QAAQ,YAAY,QAAQ,GAAK,EAClC,CAAC;EACD,IAAI,CAAC,QAAQ,MAAM,CAAC,QAAQ,MAAM,OAAO;EAEzC,MAAM,UAAU,KACf,OAAO,GACP,GAAG,kBAAkB,GAAG,KAAK,WAAW,SAAS,MAClD;EACA,MAAM,aAAa,kBAAkB,OAAO;EAC5C,MAAM,SACL,QAAQ,MACR,UACD;EACA,OAAO;CACR,QAAQ;EACP,OAAO;CACR;AACD"}
|
package/dist/v2.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PhaseResponse } from "./lib/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/v2.d.ts
|
|
4
|
+
interface OrchestratorOptions {
|
|
5
|
+
agent?: string;
|
|
6
|
+
skipNeonAuth?: boolean;
|
|
7
|
+
skipMigrations?: boolean;
|
|
8
|
+
/** Enable preview features (e.g. project bootstrapping from templates) */
|
|
9
|
+
preview?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* v2 orchestrator: checks phases in order and returns the first that needs attention.
|
|
13
|
+
*
|
|
14
|
+
* Phase order:
|
|
15
|
+
* auth -> setup (if tooling not installed)
|
|
16
|
+
* -> getting-started (if tooling installed but no Neon connection string)
|
|
17
|
+
* -> resolve .neon context (if connection string exists but no .neon file)
|
|
18
|
+
* -> neon_auth (optional) -> complete
|
|
19
|
+
*
|
|
20
|
+
* Each call is stateless — it re-checks everything from the file system and credentials.
|
|
21
|
+
*
|
|
22
|
+
* The orchestrator uses filesystem inspection to decide what to do:
|
|
23
|
+
* - No app detected → bootstrap phase (scaffold from template)
|
|
24
|
+
* - MCP not configured → full setup flow (inspect → install → getting-started)
|
|
25
|
+
* - MCP configured, no connection string → skip install, go to getting-started
|
|
26
|
+
* - MCP configured + connection string → fall through to neon-auth/migrations/complete
|
|
27
|
+
*/
|
|
28
|
+
declare function orchestrate(options: OrchestratorOptions): Promise<PhaseResponse>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { OrchestratorOptions, orchestrate };
|
|
31
|
+
//# sourceMappingURL=v2.d.ts.map
|
package/dist/v2.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.d.ts","names":[],"sources":["../src/v2.ts"],"mappings":";;;UAYiB,mBAAA;;EAAA,YAAA,CAAA,EAAA,OAAmB;EAyBd,cAAW,CAAA,EAAA,OAAA;EAAA;SACvB,CAAA,EAAA,OAAA;;;AACA;;;;;;;;;;;;;;;;iBAFY,WAAA,UACZ,sBACP,QAAQ"}
|
package/dist/v2.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { isAuthenticated } from "./lib/auth.js";
|
|
2
|
+
import { inspectProject } from "./lib/inspect.js";
|
|
3
|
+
import { handleAuthPhase } from "./lib/phases/auth.js";
|
|
4
|
+
import { handleGettingStartedPhase } from "./lib/phases/getting-started.js";
|
|
5
|
+
import { handleMigrationsPhase } from "./lib/phases/migrations.js";
|
|
6
|
+
import { handleNeonAuthPhase } from "./lib/phases/neon-auth.js";
|
|
7
|
+
import { handleSetupPhase } from "./lib/phases/setup.js";
|
|
8
|
+
import { resolveNeonContext } from "./lib/resolve-context.js";
|
|
9
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { resolve } from "node:path";
|
|
11
|
+
//#region src/v2.ts
|
|
12
|
+
/**
|
|
13
|
+
* v2 orchestrator: checks phases in order and returns the first that needs attention.
|
|
14
|
+
*
|
|
15
|
+
* Phase order:
|
|
16
|
+
* auth -> setup (if tooling not installed)
|
|
17
|
+
* -> getting-started (if tooling installed but no Neon connection string)
|
|
18
|
+
* -> resolve .neon context (if connection string exists but no .neon file)
|
|
19
|
+
* -> neon_auth (optional) -> complete
|
|
20
|
+
*
|
|
21
|
+
* Each call is stateless — it re-checks everything from the file system and credentials.
|
|
22
|
+
*
|
|
23
|
+
* The orchestrator uses filesystem inspection to decide what to do:
|
|
24
|
+
* - No app detected → bootstrap phase (scaffold from template)
|
|
25
|
+
* - MCP not configured → full setup flow (inspect → install → getting-started)
|
|
26
|
+
* - MCP configured, no connection string → skip install, go to getting-started
|
|
27
|
+
* - MCP configured + connection string → fall through to neon-auth/migrations/complete
|
|
28
|
+
*/
|
|
29
|
+
async function orchestrate(options) {
|
|
30
|
+
if (!await isAuthenticated()) return handleAuthPhase({ agent: options.agent });
|
|
31
|
+
const cwd = process.cwd();
|
|
32
|
+
const inspection = await inspectProject([
|
|
33
|
+
{
|
|
34
|
+
id: "has_app",
|
|
35
|
+
description: "",
|
|
36
|
+
lookFor: []
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "mcp_server",
|
|
40
|
+
description: "",
|
|
41
|
+
lookFor: []
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "skills",
|
|
45
|
+
description: "",
|
|
46
|
+
lookFor: []
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "connection_string",
|
|
50
|
+
description: "",
|
|
51
|
+
lookFor: []
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "project_stack",
|
|
55
|
+
description: "",
|
|
56
|
+
lookFor: []
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "migrations",
|
|
60
|
+
description: "",
|
|
61
|
+
lookFor: []
|
|
62
|
+
}
|
|
63
|
+
]);
|
|
64
|
+
const hasApp = options.preview ? inspection.hasApp === true : true;
|
|
65
|
+
const toolingInstalled = inspection.mcpConfigured && inspection.skillsInstalled;
|
|
66
|
+
const hasNeonConnection = inspection.connectionString === true;
|
|
67
|
+
if (!hasApp || !toolingInstalled) {
|
|
68
|
+
cleanupInitState(resolve(cwd, ".neon"));
|
|
69
|
+
return handleSetupPhase({
|
|
70
|
+
agent: options.agent,
|
|
71
|
+
hasApp
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const neonContextPath = resolve(cwd, ".neon");
|
|
75
|
+
const neonContext = readNeonContext(neonContextPath);
|
|
76
|
+
const initState = typeof neonContext._init === "object" && neonContext._init !== null ? neonContext._init : {};
|
|
77
|
+
const features = Array.isArray(initState.features) ? initState.features : [];
|
|
78
|
+
if (!hasNeonConnection) return handleGettingStartedPhase({
|
|
79
|
+
agent: options.agent,
|
|
80
|
+
hasConnectionString: false,
|
|
81
|
+
framework: inspection.framework,
|
|
82
|
+
orm: inspection.orm,
|
|
83
|
+
migrationTool: inspection.migrationTool,
|
|
84
|
+
migrationDir: inspection.migrationDir,
|
|
85
|
+
features,
|
|
86
|
+
preview: options.preview
|
|
87
|
+
});
|
|
88
|
+
if (!neonContext.projectId) try {
|
|
89
|
+
const resolved = await resolveNeonContext(cwd);
|
|
90
|
+
if (resolved) {
|
|
91
|
+
const merged = { ...neonContext };
|
|
92
|
+
if (resolved.orgId) merged.orgId = resolved.orgId;
|
|
93
|
+
if (resolved.projectId) merged.projectId = resolved.projectId;
|
|
94
|
+
writeFileSync(neonContextPath, `${JSON.stringify(merged, null, 2)}\n`);
|
|
95
|
+
}
|
|
96
|
+
} catch {}
|
|
97
|
+
const hasFeatureRequirements = features.length > 0;
|
|
98
|
+
if (hasFeatureRequirements ? features.includes("auth") : !options.skipNeonAuth) {
|
|
99
|
+
if (!checkNeonAuth(cwd)) return handleNeonAuthPhase({
|
|
100
|
+
agent: options.agent,
|
|
101
|
+
setup: hasFeatureRequirements
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (!options.skipMigrations) return handleMigrationsPhase({ agent: options.agent });
|
|
105
|
+
cleanupInitState(neonContextPath);
|
|
106
|
+
return {
|
|
107
|
+
phase: "setup",
|
|
108
|
+
status: "complete",
|
|
109
|
+
nextAction: {
|
|
110
|
+
type: "complete",
|
|
111
|
+
message: "Neon setup is complete. Your database is configured and your agent has the Neon MCP server and skills available."
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** Remove the ephemeral _init key from .neon, preserving other fields. */
|
|
116
|
+
function cleanupInitState(neonContextPath) {
|
|
117
|
+
if (!existsSync(neonContextPath)) return;
|
|
118
|
+
try {
|
|
119
|
+
const context = JSON.parse(readFileSync(neonContextPath, "utf-8"));
|
|
120
|
+
if (context._init !== void 0) {
|
|
121
|
+
delete context._init;
|
|
122
|
+
writeFileSync(neonContextPath, `${JSON.stringify(context, null, 2)}\n`);
|
|
123
|
+
}
|
|
124
|
+
} catch {}
|
|
125
|
+
}
|
|
126
|
+
function readNeonContext(neonContextPath) {
|
|
127
|
+
if (!existsSync(neonContextPath)) return {};
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(readFileSync(neonContextPath, "utf-8"));
|
|
130
|
+
} catch {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function checkNeonAuth(cwd) {
|
|
135
|
+
const envPath = resolve(cwd, ".env");
|
|
136
|
+
if (!existsSync(envPath)) return false;
|
|
137
|
+
try {
|
|
138
|
+
const content = readFileSync(envPath, "utf-8");
|
|
139
|
+
return /^NEON_AUTH_/m.test(content);
|
|
140
|
+
} catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { orchestrate };
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=v2.js.map
|
package/dist/v2.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.js","names":[],"sources":["../src/v2.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { isAuthenticated } from \"./lib/auth.js\";\nimport { inspectProject } from \"./lib/inspect.js\";\nimport { handleAuthPhase } from \"./lib/phases/auth.js\";\nimport { handleGettingStartedPhase } from \"./lib/phases/getting-started.js\";\nimport { handleMigrationsPhase } from \"./lib/phases/migrations.js\";\nimport { handleNeonAuthPhase } from \"./lib/phases/neon-auth.js\";\nimport { handleSetupPhase } from \"./lib/phases/setup.js\";\nimport { resolveNeonContext } from \"./lib/resolve-context.js\";\nimport type { PhaseResponse } from \"./lib/types.js\";\n\nexport interface OrchestratorOptions {\n\tagent?: string;\n\tskipNeonAuth?: boolean;\n\tskipMigrations?: boolean;\n\t/** Enable preview features (e.g. project bootstrapping from templates) */\n\tpreview?: boolean;\n}\n\n/**\n * v2 orchestrator: checks phases in order and returns the first that needs attention.\n *\n * Phase order:\n * auth -> setup (if tooling not installed)\n * -> getting-started (if tooling installed but no Neon connection string)\n * -> resolve .neon context (if connection string exists but no .neon file)\n * -> neon_auth (optional) -> complete\n *\n * Each call is stateless — it re-checks everything from the file system and credentials.\n *\n * The orchestrator uses filesystem inspection to decide what to do:\n * - No app detected → bootstrap phase (scaffold from template)\n * - MCP not configured → full setup flow (inspect → install → getting-started)\n * - MCP configured, no connection string → skip install, go to getting-started\n * - MCP configured + connection string → fall through to neon-auth/migrations/complete\n */\nexport async function orchestrate(\n\toptions: OrchestratorOptions,\n): Promise<PhaseResponse> {\n\t// Phase 1: Auth\n\tconst authed = await isAuthenticated();\n\tif (!authed) {\n\t\treturn handleAuthPhase({ agent: options.agent });\n\t}\n\n\tconst cwd = process.cwd();\n\n\t// Phase 2: Inspect what's already in place\n\tconst inspection = await inspectProject([\n\t\t{ id: \"has_app\", description: \"\", lookFor: [] },\n\t\t{ id: \"mcp_server\", description: \"\", lookFor: [] },\n\t\t{ id: \"skills\", description: \"\", lookFor: [] },\n\t\t{ id: \"connection_string\", description: \"\", lookFor: [] },\n\t\t{ id: \"project_stack\", description: \"\", lookFor: [] },\n\t\t{ id: \"migrations\", description: \"\", lookFor: [] },\n\t]);\n\n\t// Only detect empty projects when --preview is enabled\n\tconst hasApp = options.preview ? inspection.hasApp === true : true;\n\tconst toolingInstalled =\n\t\tinspection.mcpConfigured && inspection.skillsInstalled;\n\tconst hasNeonConnection = inspection.connectionString === true;\n\n\t// Phase 3a: No app or tooling not installed → setup flow\n\t// When !hasApp (preview mode), setup will offer template selection before asking about tooling.\n\t// Clean up any stale _init state from a previous run.\n\tif (!hasApp || !toolingInstalled) {\n\t\tcleanupInitState(resolve(cwd, \".neon\"));\n\t\treturn handleSetupPhase({ agent: options.agent, hasApp });\n\t}\n\n\t// Read .neon context early — needed for feature-based routing\n\tconst neonContextPath = resolve(cwd, \".neon\");\n\tconst neonContext = readNeonContext(neonContextPath);\n\tconst initState =\n\t\ttypeof neonContext._init === \"object\" && neonContext._init !== null\n\t\t\t? (neonContext._init as Record<string, unknown>)\n\t\t\t: {};\n\tconst features: string[] = Array.isArray(initState.features)\n\t\t? initState.features\n\t\t: [];\n\n\t// Phase 3b: Tooling installed but no Neon connection string → getting-started\n\tif (!hasNeonConnection) {\n\t\treturn handleGettingStartedPhase({\n\t\t\tagent: options.agent,\n\t\t\thasConnectionString: false,\n\t\t\tframework: inspection.framework as string | undefined,\n\t\t\torm: inspection.orm as string | undefined,\n\t\t\tmigrationTool: inspection.migrationTool as string | undefined,\n\t\t\tmigrationDir: inspection.migrationDir as string | undefined,\n\t\t\tfeatures,\n\t\t\tpreview: options.preview,\n\t\t});\n\t}\n\n\t// Phase 3c: Neon connection exists but no .neon context file → resolve project\n\n\tif (!neonContext.projectId) {\n\t\t// Resolve the project from the connection string and merge into .neon\n\t\ttry {\n\t\t\tconst resolved = await resolveNeonContext(cwd);\n\t\t\tif (resolved) {\n\t\t\t\tconst merged = { ...neonContext };\n\t\t\t\tif (resolved.orgId) merged.orgId = resolved.orgId;\n\t\t\t\tif (resolved.projectId) merged.projectId = resolved.projectId;\n\t\t\t\twriteFileSync(\n\t\t\t\t\tneonContextPath,\n\t\t\t\t\t`${JSON.stringify(merged, null, 2)}\\n`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Continue the flow regardless — missing .neon is not a blocker\n\t\t}\n\t}\n\n\t// Phase 4: Neon Auth — skip if template/user doesn't require it\n\tconst hasFeatureRequirements = features.length > 0;\n\tconst needsAuth = hasFeatureRequirements\n\t\t? features.includes(\"auth\")\n\t\t: !options.skipNeonAuth;\n\tif (needsAuth) {\n\t\tconst hasNeonAuth = checkNeonAuth(cwd);\n\t\tif (!hasNeonAuth) {\n\t\t\t// If auth was already selected via features, go straight to setup\n\t\t\t// (don't re-ask the user)\n\t\t\treturn handleNeonAuthPhase({\n\t\t\t\tagent: options.agent,\n\t\t\t\tsetup: hasFeatureRequirements,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Phase 5: Migrations\n\tif (!options.skipMigrations) {\n\t\treturn handleMigrationsPhase({ agent: options.agent });\n\t}\n\n\t// All done — clean up ephemeral _init state from .neon\n\tcleanupInitState(neonContextPath);\n\n\treturn {\n\t\tphase: \"setup\",\n\t\tstatus: \"complete\",\n\t\tnextAction: {\n\t\t\ttype: \"complete\",\n\t\t\tmessage:\n\t\t\t\t\"Neon setup is complete. Your database is configured and your agent has the Neon MCP server and skills available.\",\n\t\t},\n\t};\n}\n\n/** Remove the ephemeral _init key from .neon, preserving other fields. */\nfunction cleanupInitState(neonContextPath: string): void {\n\tif (!existsSync(neonContextPath)) return;\n\ttry {\n\t\tconst context = JSON.parse(readFileSync(neonContextPath, \"utf-8\"));\n\t\tif (context._init !== undefined) {\n\t\t\tdelete context._init;\n\t\t\twriteFileSync(\n\t\t\t\tneonContextPath,\n\t\t\t\t`${JSON.stringify(context, null, 2)}\\n`,\n\t\t\t);\n\t\t}\n\t} catch {}\n}\n\nfunction readNeonContext(neonContextPath: string): Record<string, unknown> {\n\tif (!existsSync(neonContextPath)) return {};\n\ttry {\n\t\treturn JSON.parse(readFileSync(neonContextPath, \"utf-8\"));\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction checkNeonAuth(cwd: string): boolean {\n\tconst envPath = resolve(cwd, \".env\");\n\tif (!existsSync(envPath)) return false;\n\ttry {\n\t\tconst content = readFileSync(envPath, \"utf-8\");\n\t\treturn /^NEON_AUTH_/m.test(content);\n\t} catch {\n\t\treturn false;\n\t}\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neon-init",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Initialize Neon projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"neon",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
],
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "git+https://github.com/neondatabase/
|
|
13
|
+
"url": "git+https://github.com/neondatabase/neon-pkgs.git"
|
|
14
14
|
},
|
|
15
15
|
"license": "Apache-2.0",
|
|
16
16
|
"author": {
|
|
@@ -44,7 +44,10 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@clack/prompts": "0.10.1",
|
|
47
|
+
"add-mcp": "^1.5.1",
|
|
47
48
|
"execa": "^9.5.2",
|
|
49
|
+
"picocolors": "^1.1.1",
|
|
50
|
+
"yaml": "^2.9.0",
|
|
48
51
|
"yargs": "^18.0.0",
|
|
49
52
|
"yoctocolors": "^2.1.2"
|
|
50
53
|
},
|
|
@@ -55,9 +58,11 @@
|
|
|
55
58
|
"provenance": false
|
|
56
59
|
},
|
|
57
60
|
"scripts": {
|
|
58
|
-
"build": "tsc --noEmit && tsdown",
|
|
61
|
+
"build": "node scripts/set-vsx-gallery.mjs && tsc --noEmit && tsdown",
|
|
62
|
+
"build:internal": "node scripts/set-vsx-gallery.mjs https://cursor-vsx-proxy.cloud.databricks.com/gallery && tsc --noEmit && tsdown",
|
|
63
|
+
"pretest": "node scripts/set-vsx-gallery.mjs",
|
|
59
64
|
"test": "vitest --passWithNoTests",
|
|
60
65
|
"test:ci": "vitest run --passWithNoTests",
|
|
61
|
-
"tsc": "tsc"
|
|
66
|
+
"tsc": "node scripts/set-vsx-gallery.mjs && tsc"
|
|
62
67
|
}
|
|
63
68
|
}
|
package/dist/lib/mcp-config.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Editor, MCPConfig } from "./types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/lib/mcp-config.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Gets or creates the MCP configuration for a specific editor
|
|
7
|
-
* - Cursor: Global config at ~/.cursor/mcp.json
|
|
8
|
-
* - VS Code: Try global config first, then workspace
|
|
9
|
-
* - Claude CLI: Global config at ~/.claude.json
|
|
10
|
-
*/
|
|
11
|
-
declare function getMCPConfig(homeDir: string, workspaceDir: string, editor: Editor): {
|
|
12
|
-
config: MCPConfig;
|
|
13
|
-
configPath: string;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Writes the MCP configuration to the appropriate location
|
|
17
|
-
* - Cursor: Global config at ~/.cursor/mcp.json
|
|
18
|
-
* - VS Code: Global config (preferred) or workspace config (fallback)
|
|
19
|
-
* - Claude CLI: Global config at ~/.claude.json
|
|
20
|
-
*/
|
|
21
|
-
declare function writeMCPConfig(configPath: string, config: MCPConfig): void;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { getMCPConfig, writeMCPConfig };
|
|
24
|
-
//# sourceMappingURL=mcp-config.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config.d.ts","names":[],"sources":["../../src/lib/mcp-config.ts"],"sourcesContent":[],"mappings":";;;;;;AAWA;;;;AAIsB,iBAJN,YAAA,CAIM,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,MAAA,EADb,MACa,CAAA,EAAA;EAgDN,MAAA,EAhDH,SAgDiB;;;;;;;;;iBAAd,cAAA,6BAA2C"}
|
package/dist/lib/mcp-config.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { getVSCodeGlobalConfigDir } from "./editors.js";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname, resolve } from "node:path";
|
|
4
|
-
|
|
5
|
-
//#region src/lib/mcp-config.ts
|
|
6
|
-
/**
|
|
7
|
-
* Gets or creates the MCP configuration for a specific editor
|
|
8
|
-
* - Cursor: Global config at ~/.cursor/mcp.json
|
|
9
|
-
* - VS Code: Try global config first, then workspace
|
|
10
|
-
* - Claude CLI: Global config at ~/.claude.json
|
|
11
|
-
*/
|
|
12
|
-
function getMCPConfig(homeDir, workspaceDir, editor) {
|
|
13
|
-
let mcpConfigPath;
|
|
14
|
-
if (editor === "VS Code") {
|
|
15
|
-
const vscodeGlobalDir = getVSCodeGlobalConfigDir(homeDir);
|
|
16
|
-
if (vscodeGlobalDir && existsSync(vscodeGlobalDir)) mcpConfigPath = resolve(vscodeGlobalDir, "mcp.json");
|
|
17
|
-
else mcpConfigPath = resolve(workspaceDir, ".vscode", "mcp.json");
|
|
18
|
-
} else if (editor === "Claude CLI") mcpConfigPath = resolve(homeDir, ".claude.json");
|
|
19
|
-
else mcpConfigPath = resolve(homeDir, ".cursor", "mcp.json");
|
|
20
|
-
if (existsSync(mcpConfigPath)) try {
|
|
21
|
-
const content = readFileSync(mcpConfigPath, "utf-8");
|
|
22
|
-
return {
|
|
23
|
-
config: JSON.parse(content),
|
|
24
|
-
configPath: mcpConfigPath
|
|
25
|
-
};
|
|
26
|
-
} catch (_error) {
|
|
27
|
-
return {
|
|
28
|
-
config: editor === "VS Code" ? { servers: {} } : { mcpServers: {} },
|
|
29
|
-
configPath: mcpConfigPath
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
config: editor === "VS Code" ? { servers: {} } : { mcpServers: {} },
|
|
34
|
-
configPath: mcpConfigPath
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Writes the MCP configuration to the appropriate location
|
|
39
|
-
* - Cursor: Global config at ~/.cursor/mcp.json
|
|
40
|
-
* - VS Code: Global config (preferred) or workspace config (fallback)
|
|
41
|
-
* - Claude CLI: Global config at ~/.claude.json
|
|
42
|
-
*/
|
|
43
|
-
function writeMCPConfig(configPath, config) {
|
|
44
|
-
const editorDir = dirname(configPath);
|
|
45
|
-
if (!existsSync(editorDir)) mkdirSync(editorDir, { recursive: true });
|
|
46
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
//#endregion
|
|
50
|
-
export { getMCPConfig, writeMCPConfig };
|
|
51
|
-
//# sourceMappingURL=mcp-config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config.js","names":[],"sources":["../../src/lib/mcp-config.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { getVSCodeGlobalConfigDir } from \"./editors.js\";\nimport type { Editor, MCPConfig } from \"./types.js\";\n\n/**\n * Gets or creates the MCP configuration for a specific editor\n * - Cursor: Global config at ~/.cursor/mcp.json\n * - VS Code: Try global config first, then workspace\n * - Claude CLI: Global config at ~/.claude.json\n */\nexport function getMCPConfig(\n\thomeDir: string,\n\tworkspaceDir: string,\n\teditor: Editor,\n): { config: MCPConfig; configPath: string } {\n\tlet mcpConfigPath: string;\n\n\tif (editor === \"VS Code\") {\n\t\t// Try global config first\n\t\tconst vscodeGlobalDir = getVSCodeGlobalConfigDir(homeDir);\n\t\tif (vscodeGlobalDir && existsSync(vscodeGlobalDir)) {\n\t\t\tmcpConfigPath = resolve(vscodeGlobalDir, \"mcp.json\");\n\t\t} else {\n\t\t\t// Fall back to workspace\n\t\t\tmcpConfigPath = resolve(workspaceDir, \".vscode\", \"mcp.json\");\n\t\t}\n\t} else if (editor === \"Claude CLI\") {\n\t\t// Claude CLI uses ~/.claude.json\n\t\tmcpConfigPath = resolve(homeDir, \".claude.json\");\n\t} else {\n\t\t// Cursor uses ~/.cursor/mcp.json\n\t\tmcpConfigPath = resolve(homeDir, \".cursor\", \"mcp.json\");\n\t}\n\n\tif (existsSync(mcpConfigPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(mcpConfigPath, \"utf-8\");\n\t\t\treturn {\n\t\t\t\tconfig: JSON.parse(content),\n\t\t\t\tconfigPath: mcpConfigPath,\n\t\t\t};\n\t\t} catch (_error) {\n\t\t\treturn {\n\t\t\t\tconfig:\n\t\t\t\t\teditor === \"VS Code\" ? { servers: {} } : { mcpServers: {} },\n\t\t\t\tconfigPath: mcpConfigPath,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tconfig: editor === \"VS Code\" ? { servers: {} } : { mcpServers: {} },\n\t\tconfigPath: mcpConfigPath,\n\t};\n}\n\n/**\n * Writes the MCP configuration to the appropriate location\n * - Cursor: Global config at ~/.cursor/mcp.json\n * - VS Code: Global config (preferred) or workspace config (fallback)\n * - Claude CLI: Global config at ~/.claude.json\n */\nexport function writeMCPConfig(configPath: string, config: MCPConfig): void {\n\tconst editorDir = dirname(configPath);\n\n\tif (!existsSync(editorDir)) {\n\t\tmkdirSync(editorDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,aACf,SACA,cACA,QAC4C;CAC5C,IAAI;AAEJ,KAAI,WAAW,WAAW;EAEzB,MAAM,kBAAkB,yBAAyB,QAAQ;AACzD,MAAI,mBAAmB,WAAW,gBAAgB,CACjD,iBAAgB,QAAQ,iBAAiB,WAAW;MAGpD,iBAAgB,QAAQ,cAAc,WAAW,WAAW;YAEnD,WAAW,aAErB,iBAAgB,QAAQ,SAAS,eAAe;KAGhD,iBAAgB,QAAQ,SAAS,WAAW,WAAW;AAGxD,KAAI,WAAW,cAAc,CAC5B,KAAI;EACH,MAAM,UAAU,aAAa,eAAe,QAAQ;AACpD,SAAO;GACN,QAAQ,KAAK,MAAM,QAAQ;GAC3B,YAAY;GACZ;UACO,QAAQ;AAChB,SAAO;GACN,QACC,WAAW,YAAY,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE;GAC5D,YAAY;GACZ;;AAIH,QAAO;EACN,QAAQ,WAAW,YAAY,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE;EACnE,YAAY;EACZ;;;;;;;;AASF,SAAgB,eAAe,YAAoB,QAAyB;CAC3E,MAAM,YAAY,QAAQ,WAAW;AAErC,KAAI,CAAC,WAAW,UAAU,CACzB,WAAU,WAAW,EAAE,WAAW,MAAM,CAAC;AAG1C,eAAc,YAAY,KAAK,UAAU,QAAQ,MAAM,EAAE,EAAE,QAAQ"}
|