@melra/cli 0.3.0-alpha.10 → 0.3.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/dist/activity.d.ts +26 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +401 -0
- package/dist/activity.js.map +1 -0
- package/dist/client-status.d.ts +24 -0
- package/dist/client-status.d.ts.map +1 -0
- package/dist/client-status.js +273 -0
- package/dist/client-status.js.map +1 -0
- package/dist/clients.d.ts +32 -0
- package/dist/clients.d.ts.map +1 -0
- package/dist/clients.js +584 -0
- package/dist/clients.js.map +1 -0
- package/dist/conformance.d.ts.map +1 -1
- package/dist/conformance.js +47 -7
- package/dist/conformance.js.map +1 -1
- package/dist/demo-workflow.d.ts +46 -0
- package/dist/demo-workflow.d.ts.map +1 -0
- package/dist/demo-workflow.js +58 -0
- package/dist/demo-workflow.js.map +1 -0
- package/dist/environment.d.ts +5 -1
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +15 -1
- package/dist/environment.js.map +1 -1
- package/dist/human.d.ts +67 -0
- package/dist/human.d.ts.map +1 -0
- package/dist/human.js +257 -0
- package/dist/human.js.map +1 -0
- package/dist/index.js +316 -72
- package/dist/index.js.map +1 -1
- package/dist/isolation.d.ts +35 -0
- package/dist/isolation.d.ts.map +1 -0
- package/dist/isolation.js +66 -0
- package/dist/isolation.js.map +1 -0
- package/dist/jsonc.d.ts +24 -0
- package/dist/jsonc.d.ts.map +1 -0
- package/dist/jsonc.js +238 -0
- package/dist/jsonc.js.map +1 -0
- package/dist/output.d.ts +28 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +77 -0
- package/dist/output.js.map +1 -0
- package/package.json +10 -9
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// Copyright 2026 XAGI Labs Private Limited
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { accessSync, constants, existsSync, statSync } from "node:fs";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { delimiter, dirname, extname, join } from "node:path";
|
|
7
|
+
import { PRODUCT_VERSION } from "@melra/protocol";
|
|
8
|
+
import { CLIENTS, isObject } from "./clients.js";
|
|
9
|
+
import { parseJsonc } from "./jsonc.js";
|
|
10
|
+
// Where each JSON shape keeps its servers, matching what `clientConfig` writes.
|
|
11
|
+
const SERVER_KEYS = {
|
|
12
|
+
mcpServers: ["mcpServers"],
|
|
13
|
+
vscode: ["servers"],
|
|
14
|
+
zed: ["context_servers"],
|
|
15
|
+
opencode: ["mcp"],
|
|
16
|
+
amp: ["amp.mcpServers"],
|
|
17
|
+
openclaw: ["mcp", "servers"],
|
|
18
|
+
copilot: ["mcpServers"],
|
|
19
|
+
droid: ["mcpServers"],
|
|
20
|
+
kilo: ["mcp"],
|
|
21
|
+
};
|
|
22
|
+
// The top-level YAML map each YAML shape keeps its servers under.
|
|
23
|
+
const YAML_KEYS = { goose: "extensions", hermes: "mcp_servers" };
|
|
24
|
+
function isExecutable(path) {
|
|
25
|
+
try {
|
|
26
|
+
// Windows has no execute bit; X_OK there is F_OK, so the extension is
|
|
27
|
+
// what makes a file runnable and PATHEXT below decides that.
|
|
28
|
+
accessSync(path, constants.X_OK);
|
|
29
|
+
return statSync(path).isFile();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// What the client would find when it spawns `command`. This sees doctor's own
|
|
36
|
+
// PATH, which a GUI client started from the dock may not share, so a hit is
|
|
37
|
+
// necessary rather than sufficient.
|
|
38
|
+
export function resolvesOnPath(command) {
|
|
39
|
+
if (/[\\/]/.test(command))
|
|
40
|
+
return isExecutable(command);
|
|
41
|
+
// Windows spawns `melra` as `melra.cmd`: a bare name is tried with every
|
|
42
|
+
// PATHEXT extension, a name that already has one is tried as written.
|
|
43
|
+
const extensions = process.platform === "win32" && extname(command) === ""
|
|
44
|
+
? (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean)
|
|
45
|
+
: [""];
|
|
46
|
+
return (process.env.PATH ?? "")
|
|
47
|
+
.split(delimiter)
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
.some((directory) => extensions.some((extension) => isExecutable(join(directory, command + extension))));
|
|
50
|
+
}
|
|
51
|
+
const strings = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
52
|
+
function launchOf(entry) {
|
|
53
|
+
if (!isObject(entry))
|
|
54
|
+
return undefined;
|
|
55
|
+
// OpenCode keeps the whole argv in `command`.
|
|
56
|
+
if (Array.isArray(entry.command))
|
|
57
|
+
return strings(entry.command);
|
|
58
|
+
return typeof entry.command === "string" ? [entry.command, ...strings(entry.args)] : undefined;
|
|
59
|
+
}
|
|
60
|
+
// Line-based rather than a TOML parser, to stay dependency-free: it reads the
|
|
61
|
+
// single-line `command =` / `args =` inside [mcp_servers.melra] that `setup`
|
|
62
|
+
// writes, and leaves anything fancier unchecked instead of guessing.
|
|
63
|
+
function codexLaunch(toml) {
|
|
64
|
+
let inside = false;
|
|
65
|
+
let command;
|
|
66
|
+
let args = [];
|
|
67
|
+
for (const line of toml.split(/\r?\n/)) {
|
|
68
|
+
const header = /^\s*\[\[?\s*([^\]]+?)\s*\]\]?\s*(#.*)?$/.exec(line);
|
|
69
|
+
if (header !== null) {
|
|
70
|
+
inside = header[1] === "mcp_servers.melra";
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (!inside)
|
|
74
|
+
continue;
|
|
75
|
+
const value = /^\s*(command|args)\s*=\s*(.+?)\s*$/.exec(line);
|
|
76
|
+
try {
|
|
77
|
+
// TOML basic strings and arrays of them are valid JSON.
|
|
78
|
+
if (value?.[1] === "command")
|
|
79
|
+
command = JSON.parse(value[2] ?? "");
|
|
80
|
+
if (value?.[1] === "args")
|
|
81
|
+
args = strings(JSON.parse(value[2] ?? ""));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// A literal string or multi-line array: leave it unchecked.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return typeof command === "string" ? [command, ...args] : undefined;
|
|
88
|
+
}
|
|
89
|
+
// The `cmd:`/`command:` and `args:` lines `setup` writes into Goose's,
|
|
90
|
+
// Hermes's, and Continue's YAML, whose values are JSON-quoted. Anything written another way
|
|
91
|
+
// is left unchecked rather than guessed at.
|
|
92
|
+
function yamlLaunch(lines) {
|
|
93
|
+
let command;
|
|
94
|
+
let args = [];
|
|
95
|
+
for (const line of lines) {
|
|
96
|
+
const value = /^\s*(?:-\s+)?(cmd|command|args)\s*:\s*(.+?)\s*$/.exec(line);
|
|
97
|
+
try {
|
|
98
|
+
if (value?.[1] === "args")
|
|
99
|
+
args = strings(JSON.parse(value[2] ?? ""));
|
|
100
|
+
else if (value !== null)
|
|
101
|
+
command = JSON.parse(value[2] ?? "");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// A plain or single-quoted scalar: leave it unchecked.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return typeof command === "string" ? [command, ...args] : undefined;
|
|
108
|
+
}
|
|
109
|
+
// The lines of the `<map>.melra` block (Goose's `extensions`, Hermes's
|
|
110
|
+
// `mcp_servers`), or undefined when there is none.
|
|
111
|
+
function yamlBlock(yaml, map) {
|
|
112
|
+
const lines = yaml.split(/\r?\n/);
|
|
113
|
+
const start = lines.findIndex((line) => line.replace(/\s*(#.*)?$/, "") === `${map}:`);
|
|
114
|
+
if (start < 0)
|
|
115
|
+
return undefined;
|
|
116
|
+
let block;
|
|
117
|
+
let depth = 0;
|
|
118
|
+
for (const line of lines.slice(start + 1)) {
|
|
119
|
+
if (/^\S/.test(line))
|
|
120
|
+
break; // the next top-level key
|
|
121
|
+
if (line.trim() === "")
|
|
122
|
+
continue;
|
|
123
|
+
const indent = /^ */.exec(line)?.[0].length ?? 0;
|
|
124
|
+
if (block !== undefined && indent <= depth)
|
|
125
|
+
break;
|
|
126
|
+
if (block !== undefined)
|
|
127
|
+
block.push(line);
|
|
128
|
+
else if (/^\s+["']?melra["']?:\s*(#.*)?$/.test(line)) {
|
|
129
|
+
block = [];
|
|
130
|
+
depth = indent;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return block;
|
|
134
|
+
}
|
|
135
|
+
function configured(base, launch) {
|
|
136
|
+
const [command] = launch ?? [];
|
|
137
|
+
if (command === undefined) {
|
|
138
|
+
return { ...base, state: "configured", note: "no command to check", problems: [] };
|
|
139
|
+
}
|
|
140
|
+
const problems = [];
|
|
141
|
+
if (!resolvesOnPath(command))
|
|
142
|
+
problems.push(`'${command}' not found on PATH`);
|
|
143
|
+
const pin = launch?.map((arg) => /^@melra\/cli@(\d\S*)$/.exec(arg)?.[1]).find(Boolean);
|
|
144
|
+
// A pin is what keeps an npx launch on one version, so after an upgrade it
|
|
145
|
+
// keeps launching the old server until the config is rewritten.
|
|
146
|
+
if (pin !== undefined && pin !== PRODUCT_VERSION) {
|
|
147
|
+
problems.push(`pinned to @melra/cli@${pin}, this is ${PRODUCT_VERSION}; fix: melra setup --client ${base.client} --write`);
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
...base,
|
|
151
|
+
state: "configured",
|
|
152
|
+
command,
|
|
153
|
+
...(pin === undefined ? {} : { pin }),
|
|
154
|
+
problems,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function inspect(client, shape, path, text) {
|
|
158
|
+
const base = { client, path };
|
|
159
|
+
const map = YAML_KEYS[shape];
|
|
160
|
+
if (map !== undefined) {
|
|
161
|
+
const block = yamlBlock(text, map);
|
|
162
|
+
return block === undefined
|
|
163
|
+
? { ...base, state: "not configured", problems: [] }
|
|
164
|
+
: configured(base, yamlLaunch(block));
|
|
165
|
+
}
|
|
166
|
+
// MELRA owns this file outright, so its existence is the configuration.
|
|
167
|
+
if (shape === "continue")
|
|
168
|
+
return configured(base, yamlLaunch(text.split(/\r?\n/)));
|
|
169
|
+
if (shape === "codex") {
|
|
170
|
+
return /^\s*\[\s*mcp_servers\.melra\s*\]/m.test(text)
|
|
171
|
+
? configured(base, codexLaunch(text))
|
|
172
|
+
: { ...base, state: "not configured", problems: [] };
|
|
173
|
+
}
|
|
174
|
+
const key = SERVER_KEYS[shape];
|
|
175
|
+
if (key === undefined) {
|
|
176
|
+
return { ...base, state: "not inspected", note: `present; ${shape} format not inspected`, problems: [] };
|
|
177
|
+
}
|
|
178
|
+
let parsed;
|
|
179
|
+
try {
|
|
180
|
+
// JSONC, because Zed and VS Code settings usually carry comments and
|
|
181
|
+
// trailing commas; read with the same parser `setup --write` edits with.
|
|
182
|
+
parsed = parseJsonc(text).value;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Not even JSONC. A text search still answers the question people ask,
|
|
186
|
+
// just not what the entry launches.
|
|
187
|
+
return /"melra"\s*:/.test(text)
|
|
188
|
+
? { ...base, state: "configured", note: "not valid JSONC, found by text search; command not checked", problems: [] }
|
|
189
|
+
: { ...base, state: "not configured", note: "not valid JSONC, searched as text", problems: [] };
|
|
190
|
+
}
|
|
191
|
+
const servers = key.reduce((at, step) => (isObject(at) ? at[step] : undefined), parsed);
|
|
192
|
+
const entry = isObject(servers) ? servers.melra : undefined;
|
|
193
|
+
return entry === undefined
|
|
194
|
+
? { ...base, state: "not configured", problems: [] }
|
|
195
|
+
: configured(base, launchOf(entry));
|
|
196
|
+
}
|
|
197
|
+
// Read-only by construction: this only ever reads the files `setup --write`
|
|
198
|
+
// would write, so doctor can run against a machine without changing it.
|
|
199
|
+
export async function clientStatuses(workspace) {
|
|
200
|
+
const statuses = [];
|
|
201
|
+
for (const [client, { shape, path: pathOf }] of Object.entries(CLIENTS)) {
|
|
202
|
+
const path = pathOf?.(workspace);
|
|
203
|
+
if (path === undefined)
|
|
204
|
+
continue;
|
|
205
|
+
let text;
|
|
206
|
+
try {
|
|
207
|
+
text = await readFile(path, "utf8");
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
const code = error.code;
|
|
211
|
+
if (code === "ENOENT" || code === "ENOTDIR")
|
|
212
|
+
continue;
|
|
213
|
+
statuses.push({ client, path, state: "unreadable", problems: [`unreadable: ${code ?? String(error)}`] });
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
statuses.push(inspect(client, shape, path, text));
|
|
217
|
+
}
|
|
218
|
+
return statuses;
|
|
219
|
+
}
|
|
220
|
+
// Which clients look installed: a config file, the directory it would go in,
|
|
221
|
+
// or the client's own executable on PATH. Any one is enough — a fresh install
|
|
222
|
+
// has a directory and no file, and a CLI client may have neither yet. The
|
|
223
|
+
// directory test is skipped where it is the workspace itself, which always
|
|
224
|
+
// exists and so says nothing about Claude Code.
|
|
225
|
+
// `/Applications` or `~/Applications`, where drag-installed apps go.
|
|
226
|
+
function macAppInstalled(app) {
|
|
227
|
+
return (process.platform === "darwin" &&
|
|
228
|
+
[join("/Applications", app), join(homedir(), "Applications", app)].some((path) => existsSync(path)));
|
|
229
|
+
}
|
|
230
|
+
export function detectClients(workspace) {
|
|
231
|
+
return Object.entries(CLIENTS).flatMap(([client, { label, path: pathOf, bin, app }]) => {
|
|
232
|
+
if (client === "generic")
|
|
233
|
+
return [];
|
|
234
|
+
const path = pathOf?.(workspace);
|
|
235
|
+
const detected = path !== undefined && existsSync(path)
|
|
236
|
+
? "config file found"
|
|
237
|
+
: path !== undefined && dirname(path) !== workspace && existsSync(dirname(path))
|
|
238
|
+
? "config folder found"
|
|
239
|
+
: bin !== undefined && resolvesOnPath(bin)
|
|
240
|
+
? `'${bin}' on PATH`
|
|
241
|
+
: app !== undefined && macAppInstalled(app)
|
|
242
|
+
? `${app} installed`
|
|
243
|
+
: undefined;
|
|
244
|
+
return [
|
|
245
|
+
{
|
|
246
|
+
client,
|
|
247
|
+
label,
|
|
248
|
+
...(path === undefined ? {} : { path }),
|
|
249
|
+
...(detected === undefined ? {} : { detected }),
|
|
250
|
+
},
|
|
251
|
+
];
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// `warn` at worst: a machine with no client configured is how SDK users run,
|
|
255
|
+
// and a client problem never stops MELRA itself from working.
|
|
256
|
+
export function clientsCheck(statuses) {
|
|
257
|
+
const hint = "run 'melra setup --client <name> --write' to add MELRA to one";
|
|
258
|
+
if (statuses.length === 0) {
|
|
259
|
+
return { name: "clients", status: "pass", detail: `no MCP client config files found; ${hint}` };
|
|
260
|
+
}
|
|
261
|
+
const lines = statuses.map(({ client, state, note, problems }) => {
|
|
262
|
+
const extra = [...(note === undefined ? [] : [note]), ...problems];
|
|
263
|
+
return `${client}: ${state}${extra.length === 0 ? "" : ` (${extra.join("; ")})`}`;
|
|
264
|
+
});
|
|
265
|
+
if (!statuses.some((status) => status.state === "configured"))
|
|
266
|
+
lines.push(hint);
|
|
267
|
+
return {
|
|
268
|
+
name: "clients",
|
|
269
|
+
status: statuses.some((status) => status.problems.length > 0) ? "warn" : "pass",
|
|
270
|
+
detail: lines.join("; "),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=client-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-status.js","sourceRoot":"","sources":["../src/client-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ServerEntry {
|
|
2
|
+
command: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
env: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
type Shape = "mcpServers" | "vscode" | "zed" | "opencode" | "codex" | "goose" | "continue" | "amp" | "openclaw" | "hermes" | "copilot" | "droid" | "kilo";
|
|
7
|
+
interface Client {
|
|
8
|
+
label: string;
|
|
9
|
+
shape: Shape;
|
|
10
|
+
path?: (workspace: string) => string;
|
|
11
|
+
bin?: string;
|
|
12
|
+
app?: string;
|
|
13
|
+
next?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const CLIENTS: Record<string, Client>;
|
|
16
|
+
export declare function resolveClient(name: string): string;
|
|
17
|
+
export declare function clientConfig(name: string, entry: ServerEntry): Record<string, unknown> | string;
|
|
18
|
+
export declare function clientConfigPath(name: string, workspace: string): string | undefined;
|
|
19
|
+
export declare const isObject: (value: unknown) => value is Record<string, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Merge MELRA into the client's own config file, keeping everything else in
|
|
22
|
+
* it. The previous file is copied to `<file>.bak` first. JSON and JSONC files
|
|
23
|
+
* are edited in place by `withMelraJson`, so comments, trailing commas, and
|
|
24
|
+
* formatting outside MELRA's own entry survive; a file that is not valid JSONC
|
|
25
|
+
* is refused. Continue's file is MELRA's alone, so it is replaced whole.
|
|
26
|
+
*/
|
|
27
|
+
export declare function writeClientConfig(path: string, config: Record<string, unknown> | string, name: string): Promise<{
|
|
28
|
+
backup?: string;
|
|
29
|
+
unchanged?: true;
|
|
30
|
+
}>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=clients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../src/clients.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAMD,KAAK,KAAK,GACN,YAAY,GACZ,QAAQ,GACR,KAAK,GACL,UAAU,GACV,OAAO,GACP,OAAO,GACP,UAAU,GACV,KAAK,GACL,UAAU,GACV,QAAQ,GACR,SAAS,GACT,OAAO,GACP,MAAM,CAAC;AAEX,UAAU,MAAM;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IAEb,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAGrC,GAAG,CAAC,EAAE,MAAM,CAAC;IAGb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAgBD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2O1C,CAAC;AAoBF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQlD;AAuED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAoDlC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpF;AAED,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACH,CAAC;AAgKvE;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EACxC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CA4BhD"}
|