nomoreide 0.1.41 → 0.1.43
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/core/agent-runtime.js +23 -0
- package/dist/core/agent-runtime.js.map +1 -1
- package/dist/core/repo-onboard.d.ts +295 -0
- package/dist/core/repo-onboard.js +643 -0
- package/dist/core/repo-onboard.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +1 -1
- package/dist/mcp/tools/index.js +3 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/onboard.d.ts +10 -0
- package/dist/mcp/tools/onboard.js +30 -0
- package/dist/mcp/tools/onboard.js.map +1 -0
- package/dist/web/client/assets/{code-editor-z1WxDN4v.js → code-editor-DZKblTe9.js} +1 -1
- package/dist/web/client/assets/index-Dj3f-wh2.css +1 -0
- package/dist/web/client/assets/index-WULLTGlU.js +156 -0
- package/dist/web/client/index.html +2 -2
- package/dist/web/routes/index.js +2 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/onboard-routes.d.ts +9 -0
- package/dist/web/routes/onboard-routes.js +145 -0
- package/dist/web/routes/onboard-routes.js.map +1 -0
- package/package.json +1 -1
- package/dist/web/client/assets/index-BAqAk-iR.css +0 -1
- package/dist/web/client/assets/index-BUxU98sL.js +0 -143
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { mkdir, readFile, readdir } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, relative, resolve } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import yaml from "js-yaml";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const UNSAFE_NAME = /[^a-zA-Z0-9._-]+/g;
|
|
10
|
+
const SCP_LIKE = /^(?:[\w.-]+@)?([\w.-]+):(.+)$/;
|
|
11
|
+
function sanitizeName(raw) {
|
|
12
|
+
return raw
|
|
13
|
+
.trim()
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/\.git$/, "")
|
|
16
|
+
.replace(UNSAFE_NAME, "-")
|
|
17
|
+
.replace(/^-+|-+$/g, "");
|
|
18
|
+
}
|
|
19
|
+
/** Parse https / ssh / scp-style git URLs and derive a safe service name. */
|
|
20
|
+
export function parseRepoUrl(input) {
|
|
21
|
+
const url = input.trim();
|
|
22
|
+
if (!url)
|
|
23
|
+
throw new Error("Repository URL is required.");
|
|
24
|
+
let host;
|
|
25
|
+
let path;
|
|
26
|
+
if (/^[a-zA-Z][\w+.-]*:\/\//.test(url)) {
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
parsed = new URL(url);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new Error(`Invalid repository URL: ${input}`);
|
|
33
|
+
}
|
|
34
|
+
if (!["http:", "https:", "ssh:", "git:", "file:"].includes(parsed.protocol)) {
|
|
35
|
+
throw new Error(`Unsupported repository URL scheme: ${parsed.protocol}`);
|
|
36
|
+
}
|
|
37
|
+
host = parsed.host;
|
|
38
|
+
path = parsed.pathname;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const scp = SCP_LIKE.exec(url);
|
|
42
|
+
if (!scp)
|
|
43
|
+
throw new Error(`Unrecognized repository URL: ${input}`);
|
|
44
|
+
host = scp[1];
|
|
45
|
+
path = scp[2];
|
|
46
|
+
}
|
|
47
|
+
const segments = path
|
|
48
|
+
.replace(/\.git\/?$/, "")
|
|
49
|
+
.split("/")
|
|
50
|
+
.filter(Boolean);
|
|
51
|
+
if (segments.length === 0) {
|
|
52
|
+
throw new Error(`Repository URL has no path: ${input}`);
|
|
53
|
+
}
|
|
54
|
+
const repo = segments[segments.length - 1];
|
|
55
|
+
const owner = segments.length >= 2 ? segments[segments.length - 2] : undefined;
|
|
56
|
+
const name = sanitizeName(repo);
|
|
57
|
+
if (!name) {
|
|
58
|
+
throw new Error(`Could not derive a service name from URL: ${input}`);
|
|
59
|
+
}
|
|
60
|
+
return { name, normalizedUrl: url, owner, host };
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Clone
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/** Where onboarded repos are cloned. Override with `NOMOREIDE_REPOS_DIR`. */
|
|
66
|
+
export function defaultReposDir() {
|
|
67
|
+
const override = process.env.NOMOREIDE_REPOS_DIR?.trim();
|
|
68
|
+
if (override)
|
|
69
|
+
return resolve(override);
|
|
70
|
+
return join(homedir(), ".nomoreide", "repos");
|
|
71
|
+
}
|
|
72
|
+
/** True when `path` resolves inside `root` (containment guard for endpoints). */
|
|
73
|
+
export function isInsideReposDir(path, root = defaultReposDir()) {
|
|
74
|
+
const rel = relative(resolve(root), resolve(path));
|
|
75
|
+
return rel === "" ? false : !rel.startsWith("..") && !resolve(path).includes("\0");
|
|
76
|
+
}
|
|
77
|
+
async function isNonEmptyDir(path) {
|
|
78
|
+
try {
|
|
79
|
+
const entries = await readdir(path);
|
|
80
|
+
return entries.length > 0;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error.code === "ENOENT")
|
|
84
|
+
return false;
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Shallow-clone a repository into `destRoot/<name>`. Refuses to overwrite a
|
|
90
|
+
* non-empty destination, and disables interactive credential prompts so a
|
|
91
|
+
* private repo fails fast instead of hanging.
|
|
92
|
+
*/
|
|
93
|
+
export async function cloneRepository(url, destRoot = defaultReposDir()) {
|
|
94
|
+
const parsed = parseRepoUrl(url);
|
|
95
|
+
const clonePath = join(destRoot, parsed.name);
|
|
96
|
+
if (await isNonEmptyDir(clonePath)) {
|
|
97
|
+
throw new Error(`Destination already exists and is not empty: ${clonePath}. Remove it or pick another repo.`);
|
|
98
|
+
}
|
|
99
|
+
await mkdir(destRoot, { recursive: true });
|
|
100
|
+
await execFileAsync("git", ["clone", "--depth", "1", parsed.normalizedUrl, clonePath], { env: { ...process.env, GIT_TERMINAL_PROMPT: "0" } });
|
|
101
|
+
return { name: parsed.name, clonePath, url: parsed.normalizedUrl };
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Scan → RepoProfile
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
const nodeSignalSchema = z.object({
|
|
107
|
+
packageManager: z.enum(["npm", "yarn", "pnpm", "bun"]),
|
|
108
|
+
scripts: z.record(z.string()),
|
|
109
|
+
hasDevScript: z.boolean(),
|
|
110
|
+
hasStartScript: z.boolean(),
|
|
111
|
+
});
|
|
112
|
+
const pythonSignalSchema = z.object({
|
|
113
|
+
hasRequirements: z.boolean(),
|
|
114
|
+
hasPyproject: z.boolean(),
|
|
115
|
+
hasManagePy: z.boolean(),
|
|
116
|
+
framework: z.enum(["django", "fastapi", "flask", "unknown"]),
|
|
117
|
+
});
|
|
118
|
+
const composeServiceDetailSchema = z.object({
|
|
119
|
+
name: z.string(),
|
|
120
|
+
image: z.string().optional(),
|
|
121
|
+
ports: z.array(z.string()),
|
|
122
|
+
environment: z.record(z.string()),
|
|
123
|
+
});
|
|
124
|
+
const dockerSignalSchema = z.object({
|
|
125
|
+
hasDockerfile: z.boolean(),
|
|
126
|
+
composeFile: z.string().optional(),
|
|
127
|
+
composeServices: z.array(z.string()),
|
|
128
|
+
/** Per-service compose details (image/ports/env), used for DB detection. */
|
|
129
|
+
services: z.array(composeServiceDetailSchema).optional(),
|
|
130
|
+
});
|
|
131
|
+
export const repoProfileSchema = z.object({
|
|
132
|
+
name: z.string(),
|
|
133
|
+
clonePath: z.string(),
|
|
134
|
+
languages: z.array(z.string()),
|
|
135
|
+
node: nodeSignalSchema.optional(),
|
|
136
|
+
python: pythonSignalSchema.optional(),
|
|
137
|
+
docker: dockerSignalSchema.optional(),
|
|
138
|
+
/** Env var names from `.env.example` (values intentionally dropped). */
|
|
139
|
+
envKeys: z.array(z.string()),
|
|
140
|
+
readmeExcerpt: z.string().optional(),
|
|
141
|
+
});
|
|
142
|
+
async function readTextIfPresent(path) {
|
|
143
|
+
try {
|
|
144
|
+
return await readFile(path, "utf8");
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function detectPackageManager(files) {
|
|
151
|
+
if (files.has("pnpm-lock.yaml"))
|
|
152
|
+
return "pnpm";
|
|
153
|
+
if (files.has("yarn.lock"))
|
|
154
|
+
return "yarn";
|
|
155
|
+
if (files.has("bun.lockb"))
|
|
156
|
+
return "bun";
|
|
157
|
+
return "npm";
|
|
158
|
+
}
|
|
159
|
+
async function scanNode(clonePath, files) {
|
|
160
|
+
if (!files.has("package.json"))
|
|
161
|
+
return undefined;
|
|
162
|
+
const raw = await readTextIfPresent(join(clonePath, "package.json"));
|
|
163
|
+
let scripts = {};
|
|
164
|
+
if (raw) {
|
|
165
|
+
try {
|
|
166
|
+
const parsed = JSON.parse(raw);
|
|
167
|
+
if (parsed.scripts && typeof parsed.scripts === "object") {
|
|
168
|
+
scripts = parsed.scripts;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// malformed package.json — treat as scriptless
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
packageManager: detectPackageManager(files),
|
|
177
|
+
scripts,
|
|
178
|
+
hasDevScript: typeof scripts.dev === "string",
|
|
179
|
+
hasStartScript: typeof scripts.start === "string",
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async function scanPython(clonePath, files) {
|
|
183
|
+
const hasRequirements = files.has("requirements.txt");
|
|
184
|
+
const hasPyproject = files.has("pyproject.toml");
|
|
185
|
+
const hasManagePy = files.has("manage.py");
|
|
186
|
+
if (!hasRequirements && !hasPyproject && !hasManagePy)
|
|
187
|
+
return undefined;
|
|
188
|
+
let framework = "unknown";
|
|
189
|
+
if (hasManagePy) {
|
|
190
|
+
framework = "django";
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const deps = (await readTextIfPresent(join(clonePath, "requirements.txt")))?.toLowerCase() ??
|
|
194
|
+
(await readTextIfPresent(join(clonePath, "pyproject.toml")))?.toLowerCase() ??
|
|
195
|
+
"";
|
|
196
|
+
if (deps.includes("fastapi") || deps.includes("uvicorn"))
|
|
197
|
+
framework = "fastapi";
|
|
198
|
+
else if (deps.includes("flask"))
|
|
199
|
+
framework = "flask";
|
|
200
|
+
else if (deps.includes("django"))
|
|
201
|
+
framework = "django";
|
|
202
|
+
}
|
|
203
|
+
return { hasRequirements, hasPyproject, hasManagePy, framework };
|
|
204
|
+
}
|
|
205
|
+
const COMPOSE_FILES = [
|
|
206
|
+
"docker-compose.yml",
|
|
207
|
+
"docker-compose.yaml",
|
|
208
|
+
"compose.yml",
|
|
209
|
+
"compose.yaml",
|
|
210
|
+
];
|
|
211
|
+
async function scanDocker(clonePath, files) {
|
|
212
|
+
const composeFile = COMPOSE_FILES.find((file) => files.has(file));
|
|
213
|
+
const hasDockerfile = files.has("Dockerfile");
|
|
214
|
+
if (!composeFile && !hasDockerfile)
|
|
215
|
+
return undefined;
|
|
216
|
+
let composeServices = [];
|
|
217
|
+
let services = [];
|
|
218
|
+
if (composeFile) {
|
|
219
|
+
const raw = await readTextIfPresent(join(clonePath, composeFile));
|
|
220
|
+
if (raw) {
|
|
221
|
+
services = parseComposeServiceDetails(raw);
|
|
222
|
+
composeServices = services.map((service) => service.name);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { hasDockerfile, composeFile, composeServices, services };
|
|
226
|
+
}
|
|
227
|
+
/** Parse top-level compose services with the details we use downstream. */
|
|
228
|
+
export function parseComposeServiceDetails(raw) {
|
|
229
|
+
try {
|
|
230
|
+
const doc = yaml.load(raw);
|
|
231
|
+
const services = doc?.services;
|
|
232
|
+
if (!services || typeof services !== "object")
|
|
233
|
+
return [];
|
|
234
|
+
return Object.entries(services).map(([name, def]) => {
|
|
235
|
+
const service = (def ?? {});
|
|
236
|
+
return {
|
|
237
|
+
name,
|
|
238
|
+
image: typeof service.image === "string" ? service.image : undefined,
|
|
239
|
+
ports: normalizeComposePorts(service.ports),
|
|
240
|
+
environment: normalizeComposeEnvironment(service.environment),
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// fall through to empty list on malformed YAML
|
|
246
|
+
}
|
|
247
|
+
return [];
|
|
248
|
+
}
|
|
249
|
+
/** Extract top-level service names from a compose file. */
|
|
250
|
+
export function parseComposeServices(raw) {
|
|
251
|
+
return parseComposeServiceDetails(raw).map((service) => service.name);
|
|
252
|
+
}
|
|
253
|
+
/** Normalize compose `ports` (short string, number, or long object form) to strings. */
|
|
254
|
+
function normalizeComposePorts(ports) {
|
|
255
|
+
if (!Array.isArray(ports))
|
|
256
|
+
return [];
|
|
257
|
+
const out = [];
|
|
258
|
+
for (const entry of ports) {
|
|
259
|
+
if (typeof entry === "number")
|
|
260
|
+
out.push(String(entry));
|
|
261
|
+
else if (typeof entry === "string")
|
|
262
|
+
out.push(entry);
|
|
263
|
+
else if (entry && typeof entry === "object") {
|
|
264
|
+
const target = entry.target;
|
|
265
|
+
const published = entry.published;
|
|
266
|
+
if (published != null && target != null)
|
|
267
|
+
out.push(`${published}:${target}`);
|
|
268
|
+
else if (target != null)
|
|
269
|
+
out.push(String(target));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return out;
|
|
273
|
+
}
|
|
274
|
+
/** Normalize compose `environment` (map or `KEY=value` list) to a record. */
|
|
275
|
+
function normalizeComposeEnvironment(env) {
|
|
276
|
+
const out = {};
|
|
277
|
+
if (Array.isArray(env)) {
|
|
278
|
+
for (const item of env) {
|
|
279
|
+
if (typeof item !== "string")
|
|
280
|
+
continue;
|
|
281
|
+
const eq = item.indexOf("=");
|
|
282
|
+
if (eq > 0)
|
|
283
|
+
out[item.slice(0, eq).trim()] = item.slice(eq + 1).trim();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else if (env && typeof env === "object") {
|
|
287
|
+
for (const [key, value] of Object.entries(env)) {
|
|
288
|
+
out[key] = value == null ? "" : String(value);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return out;
|
|
292
|
+
}
|
|
293
|
+
function parseEnvKeys(raw) {
|
|
294
|
+
const keys = [];
|
|
295
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
296
|
+
const trimmed = line.trim();
|
|
297
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
298
|
+
continue;
|
|
299
|
+
const match = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(trimmed);
|
|
300
|
+
if (match)
|
|
301
|
+
keys.push(match[1]);
|
|
302
|
+
}
|
|
303
|
+
return keys;
|
|
304
|
+
}
|
|
305
|
+
const README_FILES = ["README.md", "readme.md", "README.MD", "README"];
|
|
306
|
+
const README_HEADING = /^#{1,3}\s+.*(getting started|usage|quick\s?start|running|setup|develop|install)/i;
|
|
307
|
+
function extractReadmeExcerpt(raw) {
|
|
308
|
+
const lines = raw.split(/\r?\n/);
|
|
309
|
+
const start = lines.findIndex((line) => README_HEADING.test(line));
|
|
310
|
+
const slice = start >= 0 ? lines.slice(start, start + 40) : lines.slice(0, 30);
|
|
311
|
+
return slice.join("\n").slice(0, 2000).trim();
|
|
312
|
+
}
|
|
313
|
+
/** Read-only scan of a cloned repo into a structured profile. */
|
|
314
|
+
export async function scanRepo(clonePath) {
|
|
315
|
+
const entries = await readdir(clonePath).catch(() => {
|
|
316
|
+
throw new Error(`Cannot scan repository at ${clonePath}.`);
|
|
317
|
+
});
|
|
318
|
+
const files = new Set(entries);
|
|
319
|
+
const [node, python, docker] = await Promise.all([
|
|
320
|
+
scanNode(clonePath, files),
|
|
321
|
+
scanPython(clonePath, files),
|
|
322
|
+
scanDocker(clonePath, files),
|
|
323
|
+
]);
|
|
324
|
+
let envKeys = [];
|
|
325
|
+
for (const candidate of [".env.example", ".env.sample", ".env.template"]) {
|
|
326
|
+
if (files.has(candidate)) {
|
|
327
|
+
const raw = await readTextIfPresent(join(clonePath, candidate));
|
|
328
|
+
if (raw) {
|
|
329
|
+
envKeys = parseEnvKeys(raw);
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
let readmeExcerpt;
|
|
335
|
+
const readmeName = README_FILES.find((file) => files.has(file));
|
|
336
|
+
if (readmeName) {
|
|
337
|
+
const raw = await readTextIfPresent(join(clonePath, readmeName));
|
|
338
|
+
if (raw)
|
|
339
|
+
readmeExcerpt = extractReadmeExcerpt(raw);
|
|
340
|
+
}
|
|
341
|
+
const languages = [];
|
|
342
|
+
if (node)
|
|
343
|
+
languages.push("node");
|
|
344
|
+
if (python)
|
|
345
|
+
languages.push("python");
|
|
346
|
+
if (docker)
|
|
347
|
+
languages.push("docker");
|
|
348
|
+
return {
|
|
349
|
+
name: sanitizeName(clonePath.split(/[\\/]/).filter(Boolean).pop() ?? "service"),
|
|
350
|
+
clonePath,
|
|
351
|
+
languages,
|
|
352
|
+
node,
|
|
353
|
+
python,
|
|
354
|
+
docker,
|
|
355
|
+
envKeys,
|
|
356
|
+
readmeExcerpt,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
// Heuristic proposals
|
|
361
|
+
// ---------------------------------------------------------------------------
|
|
362
|
+
export const proposedServiceSchema = z.object({
|
|
363
|
+
name: z.string(),
|
|
364
|
+
kind: z.enum(["local", "docker-compose"]),
|
|
365
|
+
command: z.string().optional(),
|
|
366
|
+
cwd: z.string(),
|
|
367
|
+
port: z.number().int().positive().max(65535).optional(),
|
|
368
|
+
env: z.record(z.string()).optional(),
|
|
369
|
+
description: z.string().optional(),
|
|
370
|
+
composeFile: z.string().optional(),
|
|
371
|
+
composeService: z.string().optional(),
|
|
372
|
+
/** One-shot install step to run before first start (not persisted). */
|
|
373
|
+
installCommand: z.string().optional(),
|
|
374
|
+
confidence: z.enum(["high", "medium", "low"]),
|
|
375
|
+
reason: z.string(),
|
|
376
|
+
});
|
|
377
|
+
const PORT_PATTERNS = [
|
|
378
|
+
/--port[ =](\d{2,5})/i,
|
|
379
|
+
/-p[ =](\d{2,5})/i,
|
|
380
|
+
/\bport[ =:](\d{2,5})/i,
|
|
381
|
+
/:(\d{4,5})\b/,
|
|
382
|
+
];
|
|
383
|
+
function sniffPort(text) {
|
|
384
|
+
for (const pattern of PORT_PATTERNS) {
|
|
385
|
+
const match = pattern.exec(text);
|
|
386
|
+
if (match) {
|
|
387
|
+
const port = Number(match[1]);
|
|
388
|
+
if (port >= 1 && port <= 65535)
|
|
389
|
+
return port;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
394
|
+
function runScript(pm, script) {
|
|
395
|
+
switch (pm) {
|
|
396
|
+
case "pnpm":
|
|
397
|
+
return `pnpm ${script}`;
|
|
398
|
+
case "yarn":
|
|
399
|
+
return `yarn ${script}`;
|
|
400
|
+
case "bun":
|
|
401
|
+
return `bun run ${script}`;
|
|
402
|
+
default:
|
|
403
|
+
return `npm run ${script}`;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function installCmd(pm) {
|
|
407
|
+
switch (pm) {
|
|
408
|
+
case "pnpm":
|
|
409
|
+
return "pnpm install";
|
|
410
|
+
case "yarn":
|
|
411
|
+
return "yarn install";
|
|
412
|
+
case "bun":
|
|
413
|
+
return "bun install";
|
|
414
|
+
default:
|
|
415
|
+
return "npm install";
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Best-effort service proposals, ordered most-confident first. Docker Compose
|
|
420
|
+
* is the strongest signal (run command + ports are declared), so a compose
|
|
421
|
+
* repo yields one proposal per service; Node/Python yield a single proposal.
|
|
422
|
+
*/
|
|
423
|
+
export function proposeServices(profile) {
|
|
424
|
+
const proposals = [];
|
|
425
|
+
const { clonePath, name } = profile;
|
|
426
|
+
if (profile.docker?.composeFile && profile.docker.composeServices.length > 0) {
|
|
427
|
+
const services = profile.docker.composeServices;
|
|
428
|
+
const details = profile.docker.services ?? [];
|
|
429
|
+
const primary = services.find((service) => sanitizeName(service) === name) ?? services[0];
|
|
430
|
+
for (const service of services) {
|
|
431
|
+
const detail = details.find((entry) => entry.name === service);
|
|
432
|
+
proposals.push({
|
|
433
|
+
name: service === primary ? name : `${name}-${sanitizeName(service)}`,
|
|
434
|
+
kind: "docker-compose",
|
|
435
|
+
cwd: clonePath,
|
|
436
|
+
composeFile: profile.docker.composeFile,
|
|
437
|
+
composeService: service,
|
|
438
|
+
// Published host port (left side of a `5433:5432` mapping), not container.
|
|
439
|
+
port: detail ? firstHostPort(detail.ports) : undefined,
|
|
440
|
+
confidence: service === primary ? "high" : "low",
|
|
441
|
+
reason: `docker-compose service "${service}"`,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (profile.node) {
|
|
446
|
+
const { packageManager, scripts, hasDevScript, hasStartScript } = profile.node;
|
|
447
|
+
const script = hasDevScript ? "dev" : hasStartScript ? "start" : undefined;
|
|
448
|
+
if (script) {
|
|
449
|
+
proposals.push({
|
|
450
|
+
name,
|
|
451
|
+
kind: "local",
|
|
452
|
+
command: runScript(packageManager, script),
|
|
453
|
+
cwd: clonePath,
|
|
454
|
+
port: sniffPort(scripts[script] ?? ""),
|
|
455
|
+
installCommand: installCmd(packageManager),
|
|
456
|
+
confidence: hasDevScript ? "high" : "medium",
|
|
457
|
+
reason: `package.json "${script}" script (${packageManager})`,
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (profile.python) {
|
|
462
|
+
const command = pythonCommand(profile.python);
|
|
463
|
+
proposals.push({
|
|
464
|
+
name,
|
|
465
|
+
kind: "local",
|
|
466
|
+
command,
|
|
467
|
+
cwd: clonePath,
|
|
468
|
+
port: defaultPythonPort(profile.python),
|
|
469
|
+
installCommand: profile.python.hasRequirements
|
|
470
|
+
? "pip install -r requirements.txt"
|
|
471
|
+
: profile.python.hasPyproject
|
|
472
|
+
? "pip install ."
|
|
473
|
+
: undefined,
|
|
474
|
+
confidence: profile.python.framework === "unknown" ? "low" : "medium",
|
|
475
|
+
reason: `python ${profile.python.framework} project`,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
return dedupeByName(proposals).sort((a, b) => confidenceRank(b.confidence) - confidenceRank(a.confidence));
|
|
479
|
+
}
|
|
480
|
+
function pythonCommand(python) {
|
|
481
|
+
switch (python.framework) {
|
|
482
|
+
case "django":
|
|
483
|
+
return "python manage.py runserver";
|
|
484
|
+
case "fastapi":
|
|
485
|
+
return "uvicorn main:app --reload";
|
|
486
|
+
case "flask":
|
|
487
|
+
return "flask run";
|
|
488
|
+
default:
|
|
489
|
+
return "python main.py";
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function defaultPythonPort(python) {
|
|
493
|
+
if (python.framework === "django")
|
|
494
|
+
return 8000;
|
|
495
|
+
if (python.framework === "fastapi")
|
|
496
|
+
return 8000;
|
|
497
|
+
if (python.framework === "flask")
|
|
498
|
+
return 5000;
|
|
499
|
+
return undefined;
|
|
500
|
+
}
|
|
501
|
+
function confidenceRank(confidence) {
|
|
502
|
+
return confidence === "high" ? 2 : confidence === "medium" ? 1 : 0;
|
|
503
|
+
}
|
|
504
|
+
function dedupeByName(items) {
|
|
505
|
+
const seen = new Set();
|
|
506
|
+
const result = [];
|
|
507
|
+
for (const item of items) {
|
|
508
|
+
if (seen.has(item.name))
|
|
509
|
+
continue;
|
|
510
|
+
seen.add(item.name);
|
|
511
|
+
result.push(item);
|
|
512
|
+
}
|
|
513
|
+
return result;
|
|
514
|
+
}
|
|
515
|
+
// ---------------------------------------------------------------------------
|
|
516
|
+
// Database proposals (auto-register a DB when a compose service is one)
|
|
517
|
+
// ---------------------------------------------------------------------------
|
|
518
|
+
export const proposedDatabaseSchema = z.object({
|
|
519
|
+
name: z.string(),
|
|
520
|
+
engine: z.enum(["postgres", "mysql"]),
|
|
521
|
+
url: z.string(),
|
|
522
|
+
composeService: z.string().optional(),
|
|
523
|
+
confidence: z.enum(["high", "medium", "low"]),
|
|
524
|
+
reason: z.string(),
|
|
525
|
+
});
|
|
526
|
+
/** Recognise common database container images. */
|
|
527
|
+
function detectDbImage(image) {
|
|
528
|
+
if (!image)
|
|
529
|
+
return undefined;
|
|
530
|
+
if (/postgres|pgvector|postgis|timescale/i.test(image)) {
|
|
531
|
+
return { engine: "postgres", defaultPort: 5432 };
|
|
532
|
+
}
|
|
533
|
+
if (/mysql|mariadb|percona/i.test(image)) {
|
|
534
|
+
return { engine: "mysql", defaultPort: 3306 };
|
|
535
|
+
}
|
|
536
|
+
return undefined;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Propose a registrable DB connection for each compose service backed by a known
|
|
540
|
+
* database image — host port from the published mapping, credentials from the
|
|
541
|
+
* service environment. This is what lets onboarding light up the Database tab.
|
|
542
|
+
*/
|
|
543
|
+
export function proposeDatabases(profile) {
|
|
544
|
+
const details = profile.docker?.services ?? [];
|
|
545
|
+
const proposals = [];
|
|
546
|
+
for (const service of details) {
|
|
547
|
+
const match = detectDbImage(service.image);
|
|
548
|
+
if (!match)
|
|
549
|
+
continue;
|
|
550
|
+
const hostPort = publishedHostPort(service.ports, match.defaultPort) ?? match.defaultPort;
|
|
551
|
+
const { user, password, database } = dbCredentials(match.engine, service.environment);
|
|
552
|
+
proposals.push({
|
|
553
|
+
name: `${profile.name}-db`,
|
|
554
|
+
engine: match.engine,
|
|
555
|
+
url: buildDbUrl(match.engine, user, password, hostPort, database),
|
|
556
|
+
composeService: service.name,
|
|
557
|
+
confidence: database ? "high" : "medium",
|
|
558
|
+
reason: `${match.engine} database from compose service "${service.name}"${service.image ? ` (${service.image})` : ""}`,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
return dedupeByName(proposals);
|
|
562
|
+
}
|
|
563
|
+
/** The host port published for `containerPort` (e.g. 5433 from "5433:5432"). */
|
|
564
|
+
function publishedHostPort(ports, containerPort) {
|
|
565
|
+
for (const entry of ports) {
|
|
566
|
+
const parts = entry.split(":");
|
|
567
|
+
if (parts.length < 2)
|
|
568
|
+
continue;
|
|
569
|
+
const container = Number(parts[parts.length - 1].replace(/\/.*$/, ""));
|
|
570
|
+
const published = Number(parts[parts.length - 2]);
|
|
571
|
+
if (container === containerPort && Number.isFinite(published))
|
|
572
|
+
return published;
|
|
573
|
+
}
|
|
574
|
+
return firstHostPort(ports);
|
|
575
|
+
}
|
|
576
|
+
/** The host port of the first published mapping (left side of `host:container`). */
|
|
577
|
+
function firstHostPort(ports) {
|
|
578
|
+
for (const entry of ports) {
|
|
579
|
+
const parts = entry.split(":");
|
|
580
|
+
const raw = parts.length >= 2 ? parts[parts.length - 2] : parts[0];
|
|
581
|
+
const value = Number(String(raw).replace(/\/.*$/, ""));
|
|
582
|
+
if (Number.isFinite(value))
|
|
583
|
+
return value;
|
|
584
|
+
}
|
|
585
|
+
return undefined;
|
|
586
|
+
}
|
|
587
|
+
function dbCredentials(engine, env) {
|
|
588
|
+
if (engine === "postgres") {
|
|
589
|
+
const user = env.POSTGRES_USER ?? "postgres";
|
|
590
|
+
return { user, password: env.POSTGRES_PASSWORD ?? "", database: env.POSTGRES_DB ?? user };
|
|
591
|
+
}
|
|
592
|
+
return {
|
|
593
|
+
user: env.MYSQL_USER ?? "root",
|
|
594
|
+
password: env.MYSQL_PASSWORD ?? env.MYSQL_ROOT_PASSWORD ?? "",
|
|
595
|
+
database: env.MYSQL_DATABASE ?? "",
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function buildDbUrl(engine, user, password, port, database) {
|
|
599
|
+
const scheme = engine === "mysql" ? "mysql" : "postgres";
|
|
600
|
+
const auth = password
|
|
601
|
+
? `${encodeURIComponent(user)}:${encodeURIComponent(password)}`
|
|
602
|
+
: encodeURIComponent(user);
|
|
603
|
+
return `${scheme}://${auth}@127.0.0.1:${port}/${database}`;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Run a one-shot install command in `cwd`, streaming each output line to
|
|
607
|
+
* `onLine`. Modeled on the TestRunner spawn pattern (shell + line buffering)
|
|
608
|
+
* but stateless — the caller (an SSE route) owns delivery.
|
|
609
|
+
*/
|
|
610
|
+
export function runInstall(options) {
|
|
611
|
+
return new Promise((resolvePromise) => {
|
|
612
|
+
const child = spawn(options.command, {
|
|
613
|
+
cwd: options.cwd,
|
|
614
|
+
env: process.env,
|
|
615
|
+
shell: true,
|
|
616
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
617
|
+
});
|
|
618
|
+
const buffers = { stdout: "", stderr: "" };
|
|
619
|
+
const emit = (stream, text) => {
|
|
620
|
+
if (text.trim())
|
|
621
|
+
options.onLine?.({ stream, text });
|
|
622
|
+
};
|
|
623
|
+
const onChunk = (stream) => (chunk) => {
|
|
624
|
+
buffers[stream] += chunk.toString();
|
|
625
|
+
const lines = buffers[stream].split(/\r?\n/);
|
|
626
|
+
buffers[stream] = lines.pop() ?? "";
|
|
627
|
+
for (const line of lines)
|
|
628
|
+
emit(stream, line);
|
|
629
|
+
};
|
|
630
|
+
child.stdout?.on("data", onChunk("stdout"));
|
|
631
|
+
child.stderr?.on("data", onChunk("stderr"));
|
|
632
|
+
child.once("error", (error) => {
|
|
633
|
+
emit("stderr", error.message);
|
|
634
|
+
resolvePromise({ exitCode: null });
|
|
635
|
+
});
|
|
636
|
+
child.once("exit", (exitCode) => {
|
|
637
|
+
emit("stdout", buffers.stdout);
|
|
638
|
+
emit("stderr", buffers.stderr);
|
|
639
|
+
resolvePromise({ exitCode });
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
//# sourceMappingURL=repo-onboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-onboard.js","sourceRoot":"","sources":["../../src/core/repo-onboard.ts"],"names":[],"mappings":"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"}
|