nomoreide 0.1.40 → 0.1.42
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/repo-onboard.d.ts +186 -0
- package/dist/core/repo-onboard.js +442 -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 +29 -0
- package/dist/mcp/tools/onboard.js.map +1 -0
- package/dist/web/client/assets/{code-editor-CIQMI6TY.js → code-editor-DE2X-4w8.js} +1 -1
- package/dist/web/client/assets/index-BpRNFLMS.js +145 -0
- package/dist/web/client/assets/index-DDdHKSWq.css +1 -0
- package/dist/web/client/index.html +16 -3
- package/package.json +1 -1
- package/dist/web/client/assets/index-CFGCUh46.js +0 -139
- package/dist/web/client/assets/index-D8bZZCIa.css +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Onboard a repository from just a URL: clone it, scan it into a structured
|
|
4
|
+
* {@link RepoProfile}, and heuristically propose how to install + run it as a
|
|
5
|
+
* managed service. The reasoning here is deterministic and read-safe; an AI
|
|
6
|
+
* agent can read the profile and refine the proposal (the "hybrid" brain).
|
|
7
|
+
*
|
|
8
|
+
* Cloning lives here rather than in GitManager on purpose — GitManager stays
|
|
9
|
+
* read-safe (no network writes / no clone), so the additive clone-into-a-fresh
|
|
10
|
+
* -dir operation is guarded in this dedicated module instead.
|
|
11
|
+
*/
|
|
12
|
+
export interface ParsedRepoUrl {
|
|
13
|
+
/** Sanitised service name derived from the repo path. */
|
|
14
|
+
name: string;
|
|
15
|
+
/** The URL as given (trimmed), suitable to hand to `git clone`. */
|
|
16
|
+
normalizedUrl: string;
|
|
17
|
+
owner?: string;
|
|
18
|
+
host?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Parse https / ssh / scp-style git URLs and derive a safe service name. */
|
|
21
|
+
export declare function parseRepoUrl(input: string): ParsedRepoUrl;
|
|
22
|
+
/** Where onboarded repos are cloned. Override with `NOMOREIDE_REPOS_DIR`. */
|
|
23
|
+
export declare function defaultReposDir(): string;
|
|
24
|
+
export interface CloneResult {
|
|
25
|
+
name: string;
|
|
26
|
+
clonePath: string;
|
|
27
|
+
url: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Shallow-clone a repository into `destRoot/<name>`. Refuses to overwrite a
|
|
31
|
+
* non-empty destination, and disables interactive credential prompts so a
|
|
32
|
+
* private repo fails fast instead of hanging.
|
|
33
|
+
*/
|
|
34
|
+
export declare function cloneRepository(url: string, destRoot?: string): Promise<CloneResult>;
|
|
35
|
+
export declare const repoProfileSchema: z.ZodObject<{
|
|
36
|
+
name: z.ZodString;
|
|
37
|
+
clonePath: z.ZodString;
|
|
38
|
+
languages: z.ZodArray<z.ZodString, "many">;
|
|
39
|
+
node: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
packageManager: z.ZodEnum<["npm", "yarn", "pnpm", "bun"]>;
|
|
41
|
+
scripts: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
42
|
+
hasDevScript: z.ZodBoolean;
|
|
43
|
+
hasStartScript: z.ZodBoolean;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
packageManager: "npm" | "yarn" | "pnpm" | "bun";
|
|
46
|
+
scripts: Record<string, string>;
|
|
47
|
+
hasDevScript: boolean;
|
|
48
|
+
hasStartScript: boolean;
|
|
49
|
+
}, {
|
|
50
|
+
packageManager: "npm" | "yarn" | "pnpm" | "bun";
|
|
51
|
+
scripts: Record<string, string>;
|
|
52
|
+
hasDevScript: boolean;
|
|
53
|
+
hasStartScript: boolean;
|
|
54
|
+
}>>;
|
|
55
|
+
python: z.ZodOptional<z.ZodObject<{
|
|
56
|
+
hasRequirements: z.ZodBoolean;
|
|
57
|
+
hasPyproject: z.ZodBoolean;
|
|
58
|
+
hasManagePy: z.ZodBoolean;
|
|
59
|
+
framework: z.ZodEnum<["django", "fastapi", "flask", "unknown"]>;
|
|
60
|
+
}, "strip", z.ZodTypeAny, {
|
|
61
|
+
hasRequirements: boolean;
|
|
62
|
+
hasPyproject: boolean;
|
|
63
|
+
hasManagePy: boolean;
|
|
64
|
+
framework: "unknown" | "django" | "fastapi" | "flask";
|
|
65
|
+
}, {
|
|
66
|
+
hasRequirements: boolean;
|
|
67
|
+
hasPyproject: boolean;
|
|
68
|
+
hasManagePy: boolean;
|
|
69
|
+
framework: "unknown" | "django" | "fastapi" | "flask";
|
|
70
|
+
}>>;
|
|
71
|
+
docker: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
hasDockerfile: z.ZodBoolean;
|
|
73
|
+
composeFile: z.ZodOptional<z.ZodString>;
|
|
74
|
+
composeServices: z.ZodArray<z.ZodString, "many">;
|
|
75
|
+
}, "strip", z.ZodTypeAny, {
|
|
76
|
+
hasDockerfile: boolean;
|
|
77
|
+
composeServices: string[];
|
|
78
|
+
composeFile?: string | undefined;
|
|
79
|
+
}, {
|
|
80
|
+
hasDockerfile: boolean;
|
|
81
|
+
composeServices: string[];
|
|
82
|
+
composeFile?: string | undefined;
|
|
83
|
+
}>>;
|
|
84
|
+
/** Env var names from `.env.example` (values intentionally dropped). */
|
|
85
|
+
envKeys: z.ZodArray<z.ZodString, "many">;
|
|
86
|
+
readmeExcerpt: z.ZodOptional<z.ZodString>;
|
|
87
|
+
}, "strip", z.ZodTypeAny, {
|
|
88
|
+
name: string;
|
|
89
|
+
clonePath: string;
|
|
90
|
+
languages: string[];
|
|
91
|
+
envKeys: string[];
|
|
92
|
+
docker?: {
|
|
93
|
+
hasDockerfile: boolean;
|
|
94
|
+
composeServices: string[];
|
|
95
|
+
composeFile?: string | undefined;
|
|
96
|
+
} | undefined;
|
|
97
|
+
node?: {
|
|
98
|
+
packageManager: "npm" | "yarn" | "pnpm" | "bun";
|
|
99
|
+
scripts: Record<string, string>;
|
|
100
|
+
hasDevScript: boolean;
|
|
101
|
+
hasStartScript: boolean;
|
|
102
|
+
} | undefined;
|
|
103
|
+
python?: {
|
|
104
|
+
hasRequirements: boolean;
|
|
105
|
+
hasPyproject: boolean;
|
|
106
|
+
hasManagePy: boolean;
|
|
107
|
+
framework: "unknown" | "django" | "fastapi" | "flask";
|
|
108
|
+
} | undefined;
|
|
109
|
+
readmeExcerpt?: string | undefined;
|
|
110
|
+
}, {
|
|
111
|
+
name: string;
|
|
112
|
+
clonePath: string;
|
|
113
|
+
languages: string[];
|
|
114
|
+
envKeys: string[];
|
|
115
|
+
docker?: {
|
|
116
|
+
hasDockerfile: boolean;
|
|
117
|
+
composeServices: string[];
|
|
118
|
+
composeFile?: string | undefined;
|
|
119
|
+
} | undefined;
|
|
120
|
+
node?: {
|
|
121
|
+
packageManager: "npm" | "yarn" | "pnpm" | "bun";
|
|
122
|
+
scripts: Record<string, string>;
|
|
123
|
+
hasDevScript: boolean;
|
|
124
|
+
hasStartScript: boolean;
|
|
125
|
+
} | undefined;
|
|
126
|
+
python?: {
|
|
127
|
+
hasRequirements: boolean;
|
|
128
|
+
hasPyproject: boolean;
|
|
129
|
+
hasManagePy: boolean;
|
|
130
|
+
framework: "unknown" | "django" | "fastapi" | "flask";
|
|
131
|
+
} | undefined;
|
|
132
|
+
readmeExcerpt?: string | undefined;
|
|
133
|
+
}>;
|
|
134
|
+
export type RepoProfile = z.infer<typeof repoProfileSchema>;
|
|
135
|
+
/** Extract top-level service names from a compose file. */
|
|
136
|
+
export declare function parseComposeServices(raw: string): string[];
|
|
137
|
+
/** Read-only scan of a cloned repo into a structured profile. */
|
|
138
|
+
export declare function scanRepo(clonePath: string): Promise<RepoProfile>;
|
|
139
|
+
export declare const proposedServiceSchema: z.ZodObject<{
|
|
140
|
+
name: z.ZodString;
|
|
141
|
+
kind: z.ZodEnum<["local", "docker-compose"]>;
|
|
142
|
+
command: z.ZodOptional<z.ZodString>;
|
|
143
|
+
cwd: z.ZodString;
|
|
144
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
145
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
146
|
+
description: z.ZodOptional<z.ZodString>;
|
|
147
|
+
composeFile: z.ZodOptional<z.ZodString>;
|
|
148
|
+
composeService: z.ZodOptional<z.ZodString>;
|
|
149
|
+
/** One-shot install step to run before first start (not persisted). */
|
|
150
|
+
installCommand: z.ZodOptional<z.ZodString>;
|
|
151
|
+
confidence: z.ZodEnum<["high", "medium", "low"]>;
|
|
152
|
+
reason: z.ZodString;
|
|
153
|
+
}, "strip", z.ZodTypeAny, {
|
|
154
|
+
name: string;
|
|
155
|
+
kind: "local" | "docker-compose";
|
|
156
|
+
cwd: string;
|
|
157
|
+
confidence: "high" | "medium" | "low";
|
|
158
|
+
reason: string;
|
|
159
|
+
port?: number | undefined;
|
|
160
|
+
command?: string | undefined;
|
|
161
|
+
description?: string | undefined;
|
|
162
|
+
env?: Record<string, string> | undefined;
|
|
163
|
+
composeFile?: string | undefined;
|
|
164
|
+
composeService?: string | undefined;
|
|
165
|
+
installCommand?: string | undefined;
|
|
166
|
+
}, {
|
|
167
|
+
name: string;
|
|
168
|
+
kind: "local" | "docker-compose";
|
|
169
|
+
cwd: string;
|
|
170
|
+
confidence: "high" | "medium" | "low";
|
|
171
|
+
reason: string;
|
|
172
|
+
port?: number | undefined;
|
|
173
|
+
command?: string | undefined;
|
|
174
|
+
description?: string | undefined;
|
|
175
|
+
env?: Record<string, string> | undefined;
|
|
176
|
+
composeFile?: string | undefined;
|
|
177
|
+
composeService?: string | undefined;
|
|
178
|
+
installCommand?: string | undefined;
|
|
179
|
+
}>;
|
|
180
|
+
export type ProposedService = z.infer<typeof proposedServiceSchema>;
|
|
181
|
+
/**
|
|
182
|
+
* Best-effort service proposals, ordered most-confident first. Docker Compose
|
|
183
|
+
* is the strongest signal (run command + ports are declared), so a compose
|
|
184
|
+
* repo yields one proposal per service; Node/Python yield a single proposal.
|
|
185
|
+
*/
|
|
186
|
+
export declare function proposeServices(profile: RepoProfile): ProposedService[];
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { mkdir, readFile, readdir } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, 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
|
+
async function isNonEmptyDir(path) {
|
|
73
|
+
try {
|
|
74
|
+
const entries = await readdir(path);
|
|
75
|
+
return entries.length > 0;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error.code === "ENOENT")
|
|
79
|
+
return false;
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Shallow-clone a repository into `destRoot/<name>`. Refuses to overwrite a
|
|
85
|
+
* non-empty destination, and disables interactive credential prompts so a
|
|
86
|
+
* private repo fails fast instead of hanging.
|
|
87
|
+
*/
|
|
88
|
+
export async function cloneRepository(url, destRoot = defaultReposDir()) {
|
|
89
|
+
const parsed = parseRepoUrl(url);
|
|
90
|
+
const clonePath = join(destRoot, parsed.name);
|
|
91
|
+
if (await isNonEmptyDir(clonePath)) {
|
|
92
|
+
throw new Error(`Destination already exists and is not empty: ${clonePath}. Remove it or pick another repo.`);
|
|
93
|
+
}
|
|
94
|
+
await mkdir(destRoot, { recursive: true });
|
|
95
|
+
await execFileAsync("git", ["clone", "--depth", "1", parsed.normalizedUrl, clonePath], { env: { ...process.env, GIT_TERMINAL_PROMPT: "0" } });
|
|
96
|
+
return { name: parsed.name, clonePath, url: parsed.normalizedUrl };
|
|
97
|
+
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Scan → RepoProfile
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
const nodeSignalSchema = z.object({
|
|
102
|
+
packageManager: z.enum(["npm", "yarn", "pnpm", "bun"]),
|
|
103
|
+
scripts: z.record(z.string()),
|
|
104
|
+
hasDevScript: z.boolean(),
|
|
105
|
+
hasStartScript: z.boolean(),
|
|
106
|
+
});
|
|
107
|
+
const pythonSignalSchema = z.object({
|
|
108
|
+
hasRequirements: z.boolean(),
|
|
109
|
+
hasPyproject: z.boolean(),
|
|
110
|
+
hasManagePy: z.boolean(),
|
|
111
|
+
framework: z.enum(["django", "fastapi", "flask", "unknown"]),
|
|
112
|
+
});
|
|
113
|
+
const dockerSignalSchema = z.object({
|
|
114
|
+
hasDockerfile: z.boolean(),
|
|
115
|
+
composeFile: z.string().optional(),
|
|
116
|
+
composeServices: z.array(z.string()),
|
|
117
|
+
});
|
|
118
|
+
export const repoProfileSchema = z.object({
|
|
119
|
+
name: z.string(),
|
|
120
|
+
clonePath: z.string(),
|
|
121
|
+
languages: z.array(z.string()),
|
|
122
|
+
node: nodeSignalSchema.optional(),
|
|
123
|
+
python: pythonSignalSchema.optional(),
|
|
124
|
+
docker: dockerSignalSchema.optional(),
|
|
125
|
+
/** Env var names from `.env.example` (values intentionally dropped). */
|
|
126
|
+
envKeys: z.array(z.string()),
|
|
127
|
+
readmeExcerpt: z.string().optional(),
|
|
128
|
+
});
|
|
129
|
+
async function readTextIfPresent(path) {
|
|
130
|
+
try {
|
|
131
|
+
return await readFile(path, "utf8");
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function detectPackageManager(files) {
|
|
138
|
+
if (files.has("pnpm-lock.yaml"))
|
|
139
|
+
return "pnpm";
|
|
140
|
+
if (files.has("yarn.lock"))
|
|
141
|
+
return "yarn";
|
|
142
|
+
if (files.has("bun.lockb"))
|
|
143
|
+
return "bun";
|
|
144
|
+
return "npm";
|
|
145
|
+
}
|
|
146
|
+
async function scanNode(clonePath, files) {
|
|
147
|
+
if (!files.has("package.json"))
|
|
148
|
+
return undefined;
|
|
149
|
+
const raw = await readTextIfPresent(join(clonePath, "package.json"));
|
|
150
|
+
let scripts = {};
|
|
151
|
+
if (raw) {
|
|
152
|
+
try {
|
|
153
|
+
const parsed = JSON.parse(raw);
|
|
154
|
+
if (parsed.scripts && typeof parsed.scripts === "object") {
|
|
155
|
+
scripts = parsed.scripts;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// malformed package.json — treat as scriptless
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
packageManager: detectPackageManager(files),
|
|
164
|
+
scripts,
|
|
165
|
+
hasDevScript: typeof scripts.dev === "string",
|
|
166
|
+
hasStartScript: typeof scripts.start === "string",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async function scanPython(clonePath, files) {
|
|
170
|
+
const hasRequirements = files.has("requirements.txt");
|
|
171
|
+
const hasPyproject = files.has("pyproject.toml");
|
|
172
|
+
const hasManagePy = files.has("manage.py");
|
|
173
|
+
if (!hasRequirements && !hasPyproject && !hasManagePy)
|
|
174
|
+
return undefined;
|
|
175
|
+
let framework = "unknown";
|
|
176
|
+
if (hasManagePy) {
|
|
177
|
+
framework = "django";
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const deps = (await readTextIfPresent(join(clonePath, "requirements.txt")))?.toLowerCase() ??
|
|
181
|
+
(await readTextIfPresent(join(clonePath, "pyproject.toml")))?.toLowerCase() ??
|
|
182
|
+
"";
|
|
183
|
+
if (deps.includes("fastapi") || deps.includes("uvicorn"))
|
|
184
|
+
framework = "fastapi";
|
|
185
|
+
else if (deps.includes("flask"))
|
|
186
|
+
framework = "flask";
|
|
187
|
+
else if (deps.includes("django"))
|
|
188
|
+
framework = "django";
|
|
189
|
+
}
|
|
190
|
+
return { hasRequirements, hasPyproject, hasManagePy, framework };
|
|
191
|
+
}
|
|
192
|
+
const COMPOSE_FILES = [
|
|
193
|
+
"docker-compose.yml",
|
|
194
|
+
"docker-compose.yaml",
|
|
195
|
+
"compose.yml",
|
|
196
|
+
"compose.yaml",
|
|
197
|
+
];
|
|
198
|
+
async function scanDocker(clonePath, files) {
|
|
199
|
+
const composeFile = COMPOSE_FILES.find((file) => files.has(file));
|
|
200
|
+
const hasDockerfile = files.has("Dockerfile");
|
|
201
|
+
if (!composeFile && !hasDockerfile)
|
|
202
|
+
return undefined;
|
|
203
|
+
let composeServices = [];
|
|
204
|
+
if (composeFile) {
|
|
205
|
+
const raw = await readTextIfPresent(join(clonePath, composeFile));
|
|
206
|
+
if (raw)
|
|
207
|
+
composeServices = parseComposeServices(raw);
|
|
208
|
+
}
|
|
209
|
+
return { hasDockerfile, composeFile, composeServices };
|
|
210
|
+
}
|
|
211
|
+
/** Extract top-level service names from a compose file. */
|
|
212
|
+
export function parseComposeServices(raw) {
|
|
213
|
+
try {
|
|
214
|
+
const doc = yaml.load(raw);
|
|
215
|
+
if (doc && typeof doc === "object" && doc.services && typeof doc.services === "object") {
|
|
216
|
+
return Object.keys(doc.services);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// fall through to empty list on malformed YAML
|
|
221
|
+
}
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
function parseEnvKeys(raw) {
|
|
225
|
+
const keys = [];
|
|
226
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
227
|
+
const trimmed = line.trim();
|
|
228
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
229
|
+
continue;
|
|
230
|
+
const match = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(trimmed);
|
|
231
|
+
if (match)
|
|
232
|
+
keys.push(match[1]);
|
|
233
|
+
}
|
|
234
|
+
return keys;
|
|
235
|
+
}
|
|
236
|
+
const README_FILES = ["README.md", "readme.md", "README.MD", "README"];
|
|
237
|
+
const README_HEADING = /^#{1,3}\s+.*(getting started|usage|quick\s?start|running|setup|develop|install)/i;
|
|
238
|
+
function extractReadmeExcerpt(raw) {
|
|
239
|
+
const lines = raw.split(/\r?\n/);
|
|
240
|
+
const start = lines.findIndex((line) => README_HEADING.test(line));
|
|
241
|
+
const slice = start >= 0 ? lines.slice(start, start + 40) : lines.slice(0, 30);
|
|
242
|
+
return slice.join("\n").slice(0, 2000).trim();
|
|
243
|
+
}
|
|
244
|
+
/** Read-only scan of a cloned repo into a structured profile. */
|
|
245
|
+
export async function scanRepo(clonePath) {
|
|
246
|
+
const entries = await readdir(clonePath).catch(() => {
|
|
247
|
+
throw new Error(`Cannot scan repository at ${clonePath}.`);
|
|
248
|
+
});
|
|
249
|
+
const files = new Set(entries);
|
|
250
|
+
const [node, python, docker] = await Promise.all([
|
|
251
|
+
scanNode(clonePath, files),
|
|
252
|
+
scanPython(clonePath, files),
|
|
253
|
+
scanDocker(clonePath, files),
|
|
254
|
+
]);
|
|
255
|
+
let envKeys = [];
|
|
256
|
+
for (const candidate of [".env.example", ".env.sample", ".env.template"]) {
|
|
257
|
+
if (files.has(candidate)) {
|
|
258
|
+
const raw = await readTextIfPresent(join(clonePath, candidate));
|
|
259
|
+
if (raw) {
|
|
260
|
+
envKeys = parseEnvKeys(raw);
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
let readmeExcerpt;
|
|
266
|
+
const readmeName = README_FILES.find((file) => files.has(file));
|
|
267
|
+
if (readmeName) {
|
|
268
|
+
const raw = await readTextIfPresent(join(clonePath, readmeName));
|
|
269
|
+
if (raw)
|
|
270
|
+
readmeExcerpt = extractReadmeExcerpt(raw);
|
|
271
|
+
}
|
|
272
|
+
const languages = [];
|
|
273
|
+
if (node)
|
|
274
|
+
languages.push("node");
|
|
275
|
+
if (python)
|
|
276
|
+
languages.push("python");
|
|
277
|
+
if (docker)
|
|
278
|
+
languages.push("docker");
|
|
279
|
+
return {
|
|
280
|
+
name: sanitizeName(clonePath.split(/[\\/]/).filter(Boolean).pop() ?? "service"),
|
|
281
|
+
clonePath,
|
|
282
|
+
languages,
|
|
283
|
+
node,
|
|
284
|
+
python,
|
|
285
|
+
docker,
|
|
286
|
+
envKeys,
|
|
287
|
+
readmeExcerpt,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
// ---------------------------------------------------------------------------
|
|
291
|
+
// Heuristic proposals
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
export const proposedServiceSchema = z.object({
|
|
294
|
+
name: z.string(),
|
|
295
|
+
kind: z.enum(["local", "docker-compose"]),
|
|
296
|
+
command: z.string().optional(),
|
|
297
|
+
cwd: z.string(),
|
|
298
|
+
port: z.number().int().positive().max(65535).optional(),
|
|
299
|
+
env: z.record(z.string()).optional(),
|
|
300
|
+
description: z.string().optional(),
|
|
301
|
+
composeFile: z.string().optional(),
|
|
302
|
+
composeService: z.string().optional(),
|
|
303
|
+
/** One-shot install step to run before first start (not persisted). */
|
|
304
|
+
installCommand: z.string().optional(),
|
|
305
|
+
confidence: z.enum(["high", "medium", "low"]),
|
|
306
|
+
reason: z.string(),
|
|
307
|
+
});
|
|
308
|
+
const PORT_PATTERNS = [
|
|
309
|
+
/--port[ =](\d{2,5})/i,
|
|
310
|
+
/-p[ =](\d{2,5})/i,
|
|
311
|
+
/\bport[ =:](\d{2,5})/i,
|
|
312
|
+
/:(\d{4,5})\b/,
|
|
313
|
+
];
|
|
314
|
+
function sniffPort(text) {
|
|
315
|
+
for (const pattern of PORT_PATTERNS) {
|
|
316
|
+
const match = pattern.exec(text);
|
|
317
|
+
if (match) {
|
|
318
|
+
const port = Number(match[1]);
|
|
319
|
+
if (port >= 1 && port <= 65535)
|
|
320
|
+
return port;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return undefined;
|
|
324
|
+
}
|
|
325
|
+
function runScript(pm, script) {
|
|
326
|
+
switch (pm) {
|
|
327
|
+
case "pnpm":
|
|
328
|
+
return `pnpm ${script}`;
|
|
329
|
+
case "yarn":
|
|
330
|
+
return `yarn ${script}`;
|
|
331
|
+
case "bun":
|
|
332
|
+
return `bun run ${script}`;
|
|
333
|
+
default:
|
|
334
|
+
return `npm run ${script}`;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function installCmd(pm) {
|
|
338
|
+
switch (pm) {
|
|
339
|
+
case "pnpm":
|
|
340
|
+
return "pnpm install";
|
|
341
|
+
case "yarn":
|
|
342
|
+
return "yarn install";
|
|
343
|
+
case "bun":
|
|
344
|
+
return "bun install";
|
|
345
|
+
default:
|
|
346
|
+
return "npm install";
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Best-effort service proposals, ordered most-confident first. Docker Compose
|
|
351
|
+
* is the strongest signal (run command + ports are declared), so a compose
|
|
352
|
+
* repo yields one proposal per service; Node/Python yield a single proposal.
|
|
353
|
+
*/
|
|
354
|
+
export function proposeServices(profile) {
|
|
355
|
+
const proposals = [];
|
|
356
|
+
const { clonePath, name } = profile;
|
|
357
|
+
if (profile.docker?.composeFile && profile.docker.composeServices.length > 0) {
|
|
358
|
+
const services = profile.docker.composeServices;
|
|
359
|
+
const primary = services.find((service) => sanitizeName(service) === name) ?? services[0];
|
|
360
|
+
for (const service of services) {
|
|
361
|
+
proposals.push({
|
|
362
|
+
name: service === primary ? name : `${name}-${sanitizeName(service)}`,
|
|
363
|
+
kind: "docker-compose",
|
|
364
|
+
cwd: clonePath,
|
|
365
|
+
composeFile: profile.docker.composeFile,
|
|
366
|
+
composeService: service,
|
|
367
|
+
confidence: service === primary ? "high" : "low",
|
|
368
|
+
reason: `docker-compose service "${service}"`,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (profile.node) {
|
|
373
|
+
const { packageManager, scripts, hasDevScript, hasStartScript } = profile.node;
|
|
374
|
+
const script = hasDevScript ? "dev" : hasStartScript ? "start" : undefined;
|
|
375
|
+
if (script) {
|
|
376
|
+
proposals.push({
|
|
377
|
+
name,
|
|
378
|
+
kind: "local",
|
|
379
|
+
command: runScript(packageManager, script),
|
|
380
|
+
cwd: clonePath,
|
|
381
|
+
port: sniffPort(scripts[script] ?? ""),
|
|
382
|
+
installCommand: installCmd(packageManager),
|
|
383
|
+
confidence: hasDevScript ? "high" : "medium",
|
|
384
|
+
reason: `package.json "${script}" script (${packageManager})`,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (profile.python) {
|
|
389
|
+
const command = pythonCommand(profile.python);
|
|
390
|
+
proposals.push({
|
|
391
|
+
name,
|
|
392
|
+
kind: "local",
|
|
393
|
+
command,
|
|
394
|
+
cwd: clonePath,
|
|
395
|
+
port: defaultPythonPort(profile.python),
|
|
396
|
+
installCommand: profile.python.hasRequirements
|
|
397
|
+
? "pip install -r requirements.txt"
|
|
398
|
+
: profile.python.hasPyproject
|
|
399
|
+
? "pip install ."
|
|
400
|
+
: undefined,
|
|
401
|
+
confidence: profile.python.framework === "unknown" ? "low" : "medium",
|
|
402
|
+
reason: `python ${profile.python.framework} project`,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
return dedupeByName(proposals).sort((a, b) => confidenceRank(b.confidence) - confidenceRank(a.confidence));
|
|
406
|
+
}
|
|
407
|
+
function pythonCommand(python) {
|
|
408
|
+
switch (python.framework) {
|
|
409
|
+
case "django":
|
|
410
|
+
return "python manage.py runserver";
|
|
411
|
+
case "fastapi":
|
|
412
|
+
return "uvicorn main:app --reload";
|
|
413
|
+
case "flask":
|
|
414
|
+
return "flask run";
|
|
415
|
+
default:
|
|
416
|
+
return "python main.py";
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function defaultPythonPort(python) {
|
|
420
|
+
if (python.framework === "django")
|
|
421
|
+
return 8000;
|
|
422
|
+
if (python.framework === "fastapi")
|
|
423
|
+
return 8000;
|
|
424
|
+
if (python.framework === "flask")
|
|
425
|
+
return 5000;
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
428
|
+
function confidenceRank(confidence) {
|
|
429
|
+
return confidence === "high" ? 2 : confidence === "medium" ? 1 : 0;
|
|
430
|
+
}
|
|
431
|
+
function dedupeByName(proposals) {
|
|
432
|
+
const seen = new Set();
|
|
433
|
+
const result = [];
|
|
434
|
+
for (const proposal of proposals) {
|
|
435
|
+
if (seen.has(proposal.name))
|
|
436
|
+
continue;
|
|
437
|
+
seen.add(proposal.name);
|
|
438
|
+
result.push(proposal);
|
|
439
|
+
}
|
|
440
|
+
return result;
|
|
441
|
+
}
|
|
442
|
+
//# 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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"}
|
|
@@ -9,7 +9,7 @@ import { type ToolContext } from "./context.js";
|
|
|
9
9
|
* a new domain module and register it below. This aggregator never grows a
|
|
10
10
|
* per-tool branch.
|
|
11
11
|
*/
|
|
12
|
-
export declare const NOMOREIDE_TOOL_NAMES: readonly ["nomoreide_list_services", "nomoreide_register_service", "nomoreide_start_service", "nomoreide_stop_service", "nomoreide_restart_service", "nomoreide_read_logs", "nomoreide_register_bundle", "nomoreide_start_bundle", "nomoreide_stop_bundle", "nomoreide_status", "nomoreide_service_context", "nomoreide_service_health", "nomoreide_timeline", "nomoreide_git_status", "nomoreide_git_branches", "nomoreide_git_switch_branch", "nomoreide_git_create_branch", "nomoreide_git_fetch", "nomoreide_git_diff", "nomoreide_git_staged_diff", "nomoreide_git_log", "nomoreide_git_stage", "nomoreide_git_unstage", "nomoreide_git_commit", "nomoreide_git_register_repository", "nomoreide_git_select_repository", "nomoreide_list_errors", "nomoreide_error_prompt", "nomoreide_list_databases", "nomoreide_db_tables", "nomoreide_db_sample", "nomoreide_open_ui", "nomoreide_close_ui"];
|
|
12
|
+
export declare const NOMOREIDE_TOOL_NAMES: readonly ["nomoreide_list_services", "nomoreide_register_service", "nomoreide_start_service", "nomoreide_stop_service", "nomoreide_restart_service", "nomoreide_read_logs", "nomoreide_register_bundle", "nomoreide_start_bundle", "nomoreide_stop_bundle", "nomoreide_status", "nomoreide_service_context", "nomoreide_service_health", "nomoreide_timeline", "nomoreide_onboard_repo", "nomoreide_git_status", "nomoreide_git_branches", "nomoreide_git_switch_branch", "nomoreide_git_create_branch", "nomoreide_git_fetch", "nomoreide_git_diff", "nomoreide_git_staged_diff", "nomoreide_git_log", "nomoreide_git_stage", "nomoreide_git_unstage", "nomoreide_git_commit", "nomoreide_git_register_repository", "nomoreide_git_select_repository", "nomoreide_list_errors", "nomoreide_error_prompt", "nomoreide_list_databases", "nomoreide_db_tables", "nomoreide_db_sample", "nomoreide_open_ui", "nomoreide_close_ui"];
|
|
13
13
|
interface RegisterNoMoreIdeToolsOptions extends ToolContext {
|
|
14
14
|
server: FastMCP;
|
|
15
15
|
toolCallStore?: ToolCallStore;
|