@melra/cli 0.3.0-alpha.11 → 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.
Files changed (43) hide show
  1. package/README.md +11 -6
  2. package/dist/activity.d.ts +26 -0
  3. package/dist/activity.d.ts.map +1 -0
  4. package/dist/activity.js +401 -0
  5. package/dist/activity.js.map +1 -0
  6. package/dist/client-status.d.ts +24 -0
  7. package/dist/client-status.d.ts.map +1 -0
  8. package/dist/client-status.js +273 -0
  9. package/dist/client-status.js.map +1 -0
  10. package/dist/clients.d.ts +32 -0
  11. package/dist/clients.d.ts.map +1 -0
  12. package/dist/clients.js +584 -0
  13. package/dist/clients.js.map +1 -0
  14. package/dist/conformance.d.ts.map +1 -1
  15. package/dist/conformance.js +4 -2
  16. package/dist/conformance.js.map +1 -1
  17. package/dist/demo-workflow.d.ts +46 -0
  18. package/dist/demo-workflow.d.ts.map +1 -0
  19. package/dist/demo-workflow.js +58 -0
  20. package/dist/demo-workflow.js.map +1 -0
  21. package/dist/environment.d.ts +3 -1
  22. package/dist/environment.d.ts.map +1 -1
  23. package/dist/environment.js +13 -1
  24. package/dist/environment.js.map +1 -1
  25. package/dist/human.d.ts +67 -0
  26. package/dist/human.d.ts.map +1 -0
  27. package/dist/human.js +257 -0
  28. package/dist/human.js.map +1 -0
  29. package/dist/index.js +236 -49
  30. package/dist/index.js.map +1 -1
  31. package/dist/isolation.d.ts +35 -0
  32. package/dist/isolation.d.ts.map +1 -0
  33. package/dist/isolation.js +66 -0
  34. package/dist/isolation.js.map +1 -0
  35. package/dist/jsonc.d.ts +24 -0
  36. package/dist/jsonc.d.ts.map +1 -0
  37. package/dist/jsonc.js +238 -0
  38. package/dist/jsonc.js.map +1 -0
  39. package/dist/output.d.ts +28 -0
  40. package/dist/output.d.ts.map +1 -0
  41. package/dist/output.js +77 -0
  42. package/dist/output.js.map +1 -0
  43. package/package.json +10 -10
@@ -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"}