@maz-ui/node 5.0.0 → 5.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.d.mts +77 -2
- package/dist/index.d.ts +77 -2
- package/dist/index.mjs +234 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ npm install @maz-ui/node
|
|
|
18
18
|
- 🔧 **Highly configurable** - custom loggers with different levels and reporters
|
|
19
19
|
- 🛡️ **Error handling** - comprehensive error management
|
|
20
20
|
- 🎯 **Multiple log types** - info, debug, trace, start, ready, fail, box
|
|
21
|
+
- 🤖 **AI agents setup** - `setupAgents` configures the AI coding agents of a project for maz-ui (rules and MCP server), as `npx @maz-ui/mcp init` does: [documentation](https://maz-ui.com/ecosystem/node/setup-agents)
|
|
21
22
|
|
|
22
23
|
## Usage
|
|
23
24
|
|
|
@@ -364,6 +365,7 @@ All logger methods automatically handle error objects using `getErrorMessage` ut
|
|
|
364
365
|
|
|
365
366
|
- **consola** - Elegant console logging with fancy formatting
|
|
366
367
|
- **@maz-ui/utils** - Error message formatting
|
|
368
|
+
- **jsonc-parser** - Edits the MCP config files of `setupAgents` while keeping their formatting and comments
|
|
367
369
|
- **Node.js built-ins** - child_process for command execution
|
|
368
370
|
|
|
369
371
|
## Requirements
|
package/dist/index.d.mts
CHANGED
|
@@ -168,5 +168,80 @@ declare function redactSecrets(input: string): string;
|
|
|
168
168
|
*/
|
|
169
169
|
declare function redactError<T>(error: T): T;
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
/**
|
|
172
|
+
* AI coding agents supported by `setupAgents`.
|
|
173
|
+
*
|
|
174
|
+
* - `claude`: Claude Code rule (`.claude/rules/maz-ui.md`) and MCP server (`.mcp.json`)
|
|
175
|
+
* - `agents-md`: section in `AGENTS.md` (Codex, Cursor, Copilot, Windsurf, Zed, Gemini...)
|
|
176
|
+
* - `cursor`: MCP server in `.cursor/mcp.json` (rules come from `AGENTS.md`)
|
|
177
|
+
* - `vscode`: MCP server in `.vscode/mcp.json` for GitHub Copilot (rules come from `AGENTS.md`)
|
|
178
|
+
*/
|
|
179
|
+
type AgentTarget = 'claude' | 'agents-md' | 'cursor' | 'vscode';
|
|
180
|
+
declare const AGENT_TARGETS: AgentTarget[];
|
|
181
|
+
interface SetupAgentsOptions {
|
|
182
|
+
/** Root of the project (where `AGENTS.md`, `.claude/`, `.mcp.json` live) */
|
|
183
|
+
rootDir: string;
|
|
184
|
+
/** Agents to configure. Default: the agents detected in the project */
|
|
185
|
+
targets?: AgentTarget[];
|
|
186
|
+
/** Write the maz-ui rules (Claude Code rule, `AGENTS.md` section). Default `true` */
|
|
187
|
+
rules?: boolean;
|
|
188
|
+
/** Register the maz-ui MCP server. Default `true` */
|
|
189
|
+
mcp?: boolean;
|
|
190
|
+
/** Compute the changes without writing anything */
|
|
191
|
+
dryRun?: boolean;
|
|
192
|
+
/** Remove everything `setupAgents` added */
|
|
193
|
+
remove?: boolean;
|
|
194
|
+
/** Folder of the maz-ui agent docs. Default: `docs/` of the maz-ui package installed in `rootDir` */
|
|
195
|
+
docsDir?: string;
|
|
196
|
+
/** Command used to start the MCP server */
|
|
197
|
+
mcpServer?: {
|
|
198
|
+
command: string;
|
|
199
|
+
args: string[];
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
type SetupAgentsAction = 'create' | 'update' | 'remove' | 'unchanged' | 'skip';
|
|
203
|
+
interface SetupAgentsChange {
|
|
204
|
+
/** Path relative to `rootDir` */
|
|
205
|
+
file: string;
|
|
206
|
+
action: SetupAgentsAction;
|
|
207
|
+
reason?: string;
|
|
208
|
+
}
|
|
209
|
+
interface SetupAgentsResult {
|
|
210
|
+
targets: AgentTarget[];
|
|
211
|
+
version: string;
|
|
212
|
+
changes: SetupAgentsChange[];
|
|
213
|
+
}
|
|
214
|
+
declare const MANAGED_MARKER = "Managed by maz-ui";
|
|
215
|
+
declare const AGENTS_MD_BEGIN = "<!-- BEGIN:maz-ui -->";
|
|
216
|
+
declare const AGENTS_MD_END = "<!-- END:maz-ui -->";
|
|
217
|
+
declare const MCP_SERVER_NAME = "maz-ui";
|
|
218
|
+
declare const DEFAULT_MCP_SERVER: {
|
|
219
|
+
command: string;
|
|
220
|
+
args: string[];
|
|
221
|
+
};
|
|
222
|
+
/** Detects the AI agents configured in a project */
|
|
223
|
+
declare function detectAgentTargets(rootDir: string): AgentTarget[];
|
|
224
|
+
interface AgentDocs {
|
|
225
|
+
directory: string;
|
|
226
|
+
version: string;
|
|
227
|
+
claudeRule: string;
|
|
228
|
+
agentsMdSection: string;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Finds `node_modules/<name>` from a directory up to the filesystem root, like
|
|
232
|
+
* the Node resolution but without the global folders (`NODE_PATH`), so only a
|
|
233
|
+
* package installed for the project is found.
|
|
234
|
+
*/
|
|
235
|
+
declare function findInstalledPackage(fromDir: string, name: string): string | undefined;
|
|
236
|
+
/** Reads the agent files shipped in `maz-ui/docs/agents` */
|
|
237
|
+
declare function readAgentDocs(rootDir: string, docsDir?: string): AgentDocs;
|
|
238
|
+
/**
|
|
239
|
+
* Configures the AI coding agents of a project to use maz-ui: rules (version
|
|
240
|
+
* matched with the installed maz-ui) and the maz-ui MCP server. Idempotent and
|
|
241
|
+
* conservative: it only writes files it owns, a delimited section of
|
|
242
|
+
* `AGENTS.md` and its own entry of the MCP config files.
|
|
243
|
+
*/
|
|
244
|
+
declare function setupAgents(options: SetupAgentsOptions): SetupAgentsResult;
|
|
245
|
+
|
|
246
|
+
export { AGENTS_MD_BEGIN, AGENTS_MD_END, AGENT_TARGETS, DEFAULT_MCP_SERVER, MANAGED_MARKER, MCP_SERVER_NAME, createLogger, detectAgentTargets, execPromise, findInstalledPackage, logger, printBanner, readAgentDocs, redactError, redactSecrets, setupAgents };
|
|
247
|
+
export type { AgentDocs, AgentTarget, ExecPromiseOptions, LogLevel, Logger, LoggerOptions, SetupAgentsAction, SetupAgentsChange, SetupAgentsOptions, SetupAgentsResult };
|
package/dist/index.d.ts
CHANGED
|
@@ -168,5 +168,80 @@ declare function redactSecrets(input: string): string;
|
|
|
168
168
|
*/
|
|
169
169
|
declare function redactError<T>(error: T): T;
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
/**
|
|
172
|
+
* AI coding agents supported by `setupAgents`.
|
|
173
|
+
*
|
|
174
|
+
* - `claude`: Claude Code rule (`.claude/rules/maz-ui.md`) and MCP server (`.mcp.json`)
|
|
175
|
+
* - `agents-md`: section in `AGENTS.md` (Codex, Cursor, Copilot, Windsurf, Zed, Gemini...)
|
|
176
|
+
* - `cursor`: MCP server in `.cursor/mcp.json` (rules come from `AGENTS.md`)
|
|
177
|
+
* - `vscode`: MCP server in `.vscode/mcp.json` for GitHub Copilot (rules come from `AGENTS.md`)
|
|
178
|
+
*/
|
|
179
|
+
type AgentTarget = 'claude' | 'agents-md' | 'cursor' | 'vscode';
|
|
180
|
+
declare const AGENT_TARGETS: AgentTarget[];
|
|
181
|
+
interface SetupAgentsOptions {
|
|
182
|
+
/** Root of the project (where `AGENTS.md`, `.claude/`, `.mcp.json` live) */
|
|
183
|
+
rootDir: string;
|
|
184
|
+
/** Agents to configure. Default: the agents detected in the project */
|
|
185
|
+
targets?: AgentTarget[];
|
|
186
|
+
/** Write the maz-ui rules (Claude Code rule, `AGENTS.md` section). Default `true` */
|
|
187
|
+
rules?: boolean;
|
|
188
|
+
/** Register the maz-ui MCP server. Default `true` */
|
|
189
|
+
mcp?: boolean;
|
|
190
|
+
/** Compute the changes without writing anything */
|
|
191
|
+
dryRun?: boolean;
|
|
192
|
+
/** Remove everything `setupAgents` added */
|
|
193
|
+
remove?: boolean;
|
|
194
|
+
/** Folder of the maz-ui agent docs. Default: `docs/` of the maz-ui package installed in `rootDir` */
|
|
195
|
+
docsDir?: string;
|
|
196
|
+
/** Command used to start the MCP server */
|
|
197
|
+
mcpServer?: {
|
|
198
|
+
command: string;
|
|
199
|
+
args: string[];
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
type SetupAgentsAction = 'create' | 'update' | 'remove' | 'unchanged' | 'skip';
|
|
203
|
+
interface SetupAgentsChange {
|
|
204
|
+
/** Path relative to `rootDir` */
|
|
205
|
+
file: string;
|
|
206
|
+
action: SetupAgentsAction;
|
|
207
|
+
reason?: string;
|
|
208
|
+
}
|
|
209
|
+
interface SetupAgentsResult {
|
|
210
|
+
targets: AgentTarget[];
|
|
211
|
+
version: string;
|
|
212
|
+
changes: SetupAgentsChange[];
|
|
213
|
+
}
|
|
214
|
+
declare const MANAGED_MARKER = "Managed by maz-ui";
|
|
215
|
+
declare const AGENTS_MD_BEGIN = "<!-- BEGIN:maz-ui -->";
|
|
216
|
+
declare const AGENTS_MD_END = "<!-- END:maz-ui -->";
|
|
217
|
+
declare const MCP_SERVER_NAME = "maz-ui";
|
|
218
|
+
declare const DEFAULT_MCP_SERVER: {
|
|
219
|
+
command: string;
|
|
220
|
+
args: string[];
|
|
221
|
+
};
|
|
222
|
+
/** Detects the AI agents configured in a project */
|
|
223
|
+
declare function detectAgentTargets(rootDir: string): AgentTarget[];
|
|
224
|
+
interface AgentDocs {
|
|
225
|
+
directory: string;
|
|
226
|
+
version: string;
|
|
227
|
+
claudeRule: string;
|
|
228
|
+
agentsMdSection: string;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Finds `node_modules/<name>` from a directory up to the filesystem root, like
|
|
232
|
+
* the Node resolution but without the global folders (`NODE_PATH`), so only a
|
|
233
|
+
* package installed for the project is found.
|
|
234
|
+
*/
|
|
235
|
+
declare function findInstalledPackage(fromDir: string, name: string): string | undefined;
|
|
236
|
+
/** Reads the agent files shipped in `maz-ui/docs/agents` */
|
|
237
|
+
declare function readAgentDocs(rootDir: string, docsDir?: string): AgentDocs;
|
|
238
|
+
/**
|
|
239
|
+
* Configures the AI coding agents of a project to use maz-ui: rules (version
|
|
240
|
+
* matched with the installed maz-ui) and the maz-ui MCP server. Idempotent and
|
|
241
|
+
* conservative: it only writes files it owns, a delimited section of
|
|
242
|
+
* `AGENTS.md` and its own entry of the MCP config files.
|
|
243
|
+
*/
|
|
244
|
+
declare function setupAgents(options: SetupAgentsOptions): SetupAgentsResult;
|
|
245
|
+
|
|
246
|
+
export { AGENTS_MD_BEGIN, AGENTS_MD_END, AGENT_TARGETS, DEFAULT_MCP_SERVER, MANAGED_MARKER, MCP_SERVER_NAME, createLogger, detectAgentTargets, execPromise, findInstalledPackage, logger, printBanner, readAgentDocs, redactError, redactSecrets, setupAgents };
|
|
247
|
+
export type { AgentDocs, AgentTarget, ExecPromiseOptions, LogLevel, Logger, LoggerOptions, SetupAgentsAction, SetupAgentsChange, SetupAgentsOptions, SetupAgentsResult };
|
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,9 @@ import process$1 from 'node:process';
|
|
|
3
3
|
import { blueBright } from 'colorette';
|
|
4
4
|
import { createConsola } from 'consola';
|
|
5
5
|
import figlet from 'figlet';
|
|
6
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
7
|
+
import { join, dirname } from 'node:path';
|
|
8
|
+
import { parse, applyEdits, modify } from 'jsonc-parser';
|
|
6
9
|
|
|
7
10
|
const LogLevelMap = {
|
|
8
11
|
silent: Number.NEGATIVE_INFINITY,
|
|
@@ -180,4 +183,234 @@ function printBanner({
|
|
|
180
183
|
logger.break();
|
|
181
184
|
}
|
|
182
185
|
|
|
183
|
-
|
|
186
|
+
const AGENT_TARGETS = ["claude", "agents-md", "cursor", "vscode"];
|
|
187
|
+
const MANAGED_MARKER = "Managed by maz-ui";
|
|
188
|
+
const AGENTS_MD_BEGIN = "<!-- BEGIN:maz-ui -->";
|
|
189
|
+
const AGENTS_MD_END = "<!-- END:maz-ui -->";
|
|
190
|
+
const MCP_SERVER_NAME = "maz-ui";
|
|
191
|
+
const DEFAULT_MCP_SERVER = { command: "npx", args: ["-y", "@maz-ui/mcp@latest"] };
|
|
192
|
+
const CLAUDE_RULE_FILE = ".claude/rules/maz-ui.md";
|
|
193
|
+
const CLAUDE_MEMORY_FILES = ["CLAUDE.md", ".claude/CLAUDE.md", "CLAUDE.local.md"];
|
|
194
|
+
function managedHeader(version) {
|
|
195
|
+
return `<!-- ${MANAGED_MARKER} ${version}: generated by \`npx @maz-ui/mcp init\` (or the \`mazUi.agents\` Nuxt option). Do not edit, your changes would be overwritten: write your own rules elsewhere. -->`;
|
|
196
|
+
}
|
|
197
|
+
function detectAgentTargets(rootDir) {
|
|
198
|
+
const has = (path) => existsSync(join(rootDir, path));
|
|
199
|
+
const targets = /* @__PURE__ */ new Set();
|
|
200
|
+
if (has(".claude") || CLAUDE_MEMORY_FILES.some(has) || has(".mcp.json"))
|
|
201
|
+
targets.add("claude");
|
|
202
|
+
if (has(".cursor") || has(".cursorrules"))
|
|
203
|
+
targets.add("cursor");
|
|
204
|
+
if (has(".vscode/mcp.json") || has(".github/copilot-instructions.md") || has(".github/instructions"))
|
|
205
|
+
targets.add("vscode");
|
|
206
|
+
if (has("AGENTS.md") || targets.has("cursor") || targets.has("vscode") || has(".codex") || has(".windsurf") || has(".devin") || has(".windsurfrules") || has("GEMINI.md"))
|
|
207
|
+
targets.add("agents-md");
|
|
208
|
+
return AGENT_TARGETS.filter((target) => targets.has(target));
|
|
209
|
+
}
|
|
210
|
+
function findInstalledPackage(fromDir, name) {
|
|
211
|
+
let directory = fromDir;
|
|
212
|
+
for (; ; ) {
|
|
213
|
+
const candidate = join(directory, "node_modules", name);
|
|
214
|
+
if (existsSync(join(candidate, "package.json")))
|
|
215
|
+
return candidate;
|
|
216
|
+
const parent = dirname(directory);
|
|
217
|
+
if (parent === directory)
|
|
218
|
+
return void 0;
|
|
219
|
+
directory = parent;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function readAgentDocs(rootDir, docsDir) {
|
|
223
|
+
let directory = docsDir;
|
|
224
|
+
if (!directory) {
|
|
225
|
+
const packageDir = findInstalledPackage(rootDir, "maz-ui");
|
|
226
|
+
if (!packageDir)
|
|
227
|
+
throw new Error(`maz-ui is not installed in ${rootDir}: install it first (\`npm install maz-ui\`).`);
|
|
228
|
+
directory = join(packageDir, "docs");
|
|
229
|
+
}
|
|
230
|
+
const manifestFile = join(directory, "manifest.json");
|
|
231
|
+
const claudeRuleFile = join(directory, "agents/claude-rule.md");
|
|
232
|
+
const agentsMdFile = join(directory, "agents/agents-md.md");
|
|
233
|
+
if (!existsSync(manifestFile) || !existsSync(claudeRuleFile) || !existsSync(agentsMdFile)) {
|
|
234
|
+
throw new Error(`The installed maz-ui does not ship the agent docs (${directory}): upgrade maz-ui to the latest version.`);
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
directory,
|
|
238
|
+
version: JSON.parse(readFileSync(manifestFile, "utf8")).version,
|
|
239
|
+
claudeRule: readFileSync(claudeRuleFile, "utf8").trim(),
|
|
240
|
+
agentsMdSection: readFileSync(agentsMdFile, "utf8").trim()
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
class ChangeSet {
|
|
244
|
+
constructor(rootDir, dryRun) {
|
|
245
|
+
this.rootDir = rootDir;
|
|
246
|
+
this.dryRun = dryRun;
|
|
247
|
+
}
|
|
248
|
+
changes = [];
|
|
249
|
+
absolute(file) {
|
|
250
|
+
return join(this.rootDir, file);
|
|
251
|
+
}
|
|
252
|
+
read(file) {
|
|
253
|
+
const path = this.absolute(file);
|
|
254
|
+
return existsSync(path) ? readFileSync(path, "utf8") : void 0;
|
|
255
|
+
}
|
|
256
|
+
write(file, content, current) {
|
|
257
|
+
if (current === content) {
|
|
258
|
+
this.changes.push({ file, action: "unchanged" });
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
this.changes.push({ file, action: current === void 0 ? "create" : "update" });
|
|
262
|
+
if (!this.dryRun) {
|
|
263
|
+
mkdirSync(dirname(this.absolute(file)), { recursive: true });
|
|
264
|
+
writeFileSync(this.absolute(file), content);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
delete(file) {
|
|
268
|
+
this.changes.push({ file, action: "remove" });
|
|
269
|
+
if (!this.dryRun)
|
|
270
|
+
rmSync(this.absolute(file), { force: true });
|
|
271
|
+
}
|
|
272
|
+
skip(file, reason) {
|
|
273
|
+
this.changes.push({ file, action: "skip", reason });
|
|
274
|
+
}
|
|
275
|
+
unchanged(file, reason) {
|
|
276
|
+
this.changes.push({ file, action: "unchanged", reason });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function isOwned(content) {
|
|
280
|
+
return content === void 0 || content.includes(MANAGED_MARKER);
|
|
281
|
+
}
|
|
282
|
+
function syncOwnedFile(changes, file, content) {
|
|
283
|
+
const current = changes.read(file);
|
|
284
|
+
if (!isOwned(current)) {
|
|
285
|
+
changes.skip(file, "file exists and was not generated by maz-ui: left untouched");
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (content === void 0) {
|
|
289
|
+
if (current !== void 0)
|
|
290
|
+
changes.delete(file);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
changes.write(file, content, current);
|
|
294
|
+
}
|
|
295
|
+
function syncAgentsMd(changes, section) {
|
|
296
|
+
const file = "AGENTS.md";
|
|
297
|
+
const current = changes.read(file);
|
|
298
|
+
const begin = current?.indexOf(AGENTS_MD_BEGIN) ?? -1;
|
|
299
|
+
const end = current?.indexOf(AGENTS_MD_END) ?? -1;
|
|
300
|
+
const hasBlock = begin !== -1 && end > begin;
|
|
301
|
+
if (section === void 0) {
|
|
302
|
+
if (!current || !hasBlock)
|
|
303
|
+
return;
|
|
304
|
+
const remaining = `${current.slice(0, begin)}${current.slice(end + AGENTS_MD_END.length)}`.replace(/\n{3,}/g, "\n\n").trim();
|
|
305
|
+
if (remaining)
|
|
306
|
+
changes.write(file, `${remaining}
|
|
307
|
+
`, current);
|
|
308
|
+
else
|
|
309
|
+
changes.delete(file);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const block = `${AGENTS_MD_BEGIN}
|
|
313
|
+
|
|
314
|
+
${section}
|
|
315
|
+
|
|
316
|
+
${AGENTS_MD_END}`;
|
|
317
|
+
if (!current) {
|
|
318
|
+
changes.write(file, `${block}
|
|
319
|
+
`, current);
|
|
320
|
+
} else if (hasBlock) {
|
|
321
|
+
changes.write(file, `${current.slice(0, begin)}${block}${current.slice(end + AGENTS_MD_END.length)}`, current);
|
|
322
|
+
} else {
|
|
323
|
+
changes.write(file, `${current.trimEnd()}
|
|
324
|
+
|
|
325
|
+
${block}
|
|
326
|
+
`, current);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const MCP_FILES = {
|
|
330
|
+
claude: { file: ".mcp.json", rootKey: "mcpServers", withType: true },
|
|
331
|
+
cursor: { file: ".cursor/mcp.json", rootKey: "mcpServers", withType: false },
|
|
332
|
+
vscode: { file: ".vscode/mcp.json", rootKey: "servers", withType: true }
|
|
333
|
+
};
|
|
334
|
+
function referencesMazUiMcp(server) {
|
|
335
|
+
const serialized = JSON.stringify(server);
|
|
336
|
+
return serialized.includes("@maz-ui/mcp") || serialized.includes("maz-ui-mcp");
|
|
337
|
+
}
|
|
338
|
+
function detectFormatting(content) {
|
|
339
|
+
const indent = /^( +|\t)"/m.exec(content)?.[1] ?? " ";
|
|
340
|
+
return { insertSpaces: !indent.includes(" "), tabSize: indent.includes(" ") ? 1 : indent.length, eol: content.includes("\r\n") ? "\r\n" : "\n" };
|
|
341
|
+
}
|
|
342
|
+
function isJsonObject(value) {
|
|
343
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
344
|
+
}
|
|
345
|
+
function syncMcpConfig(changes, config, server, remove) {
|
|
346
|
+
const current = changes.read(config.file);
|
|
347
|
+
const errors = [];
|
|
348
|
+
const parsed = current === void 0 ? {} : parse(current, errors, { allowTrailingComma: true });
|
|
349
|
+
if (errors.length > 0 || !isJsonObject(parsed) || parsed[config.rootKey] !== void 0 && !isJsonObject(parsed[config.rootKey])) {
|
|
350
|
+
changes.skip(config.file, "invalid JSON: left untouched");
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const servers = parsed[config.rootKey] ?? {};
|
|
354
|
+
const existing = Object.entries(servers).find(([, value2]) => referencesMazUiMcp(value2));
|
|
355
|
+
const base = current ?? "{}\n";
|
|
356
|
+
const formatting = detectFormatting(base);
|
|
357
|
+
if (remove) {
|
|
358
|
+
if (existing?.[0] === MCP_SERVER_NAME) {
|
|
359
|
+
const content2 = applyEdits(base, modify(base, [config.rootKey, MCP_SERVER_NAME], void 0, { formattingOptions: formatting }));
|
|
360
|
+
const remaining = parse(content2);
|
|
361
|
+
const isEmpty = Object.keys(remaining).length === 1 && Object.keys(remaining[config.rootKey]).length === 0;
|
|
362
|
+
if (isEmpty)
|
|
363
|
+
changes.delete(config.file);
|
|
364
|
+
else
|
|
365
|
+
changes.write(config.file, content2, current);
|
|
366
|
+
}
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (existing) {
|
|
370
|
+
changes.unchanged(config.file, `maz-ui MCP server already registered as "${existing[0]}"`);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (servers[MCP_SERVER_NAME] !== void 0) {
|
|
374
|
+
changes.skip(config.file, `a "${MCP_SERVER_NAME}" server already exists with another command: left untouched`);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
const value = config.withType ? { type: "stdio", ...server } : { ...server };
|
|
378
|
+
const content = applyEdits(base, modify(base, [config.rootKey, MCP_SERVER_NAME], value, { formattingOptions: formatting }));
|
|
379
|
+
changes.write(config.file, content.endsWith("\n") ? content : `${content}
|
|
380
|
+
`, current);
|
|
381
|
+
}
|
|
382
|
+
function syncRules(changes, rootDir, targets, docs) {
|
|
383
|
+
const version = docs?.version ?? "";
|
|
384
|
+
const hasClaudeMemory = CLAUDE_MEMORY_FILES.some((file) => existsSync(join(rootDir, file)));
|
|
385
|
+
const claudeReadsAgentsMd = targets.includes("agents-md") && !hasClaudeMemory;
|
|
386
|
+
if (targets.includes("claude")) {
|
|
387
|
+
const rule = docs && !claudeReadsAgentsMd ? `${managedHeader(version)}
|
|
388
|
+
|
|
389
|
+
${docs.claudeRule}
|
|
390
|
+
` : void 0;
|
|
391
|
+
syncOwnedFile(changes, CLAUDE_RULE_FILE, rule);
|
|
392
|
+
}
|
|
393
|
+
if (targets.includes("agents-md"))
|
|
394
|
+
syncAgentsMd(changes, docs ? `${managedHeader(version)}
|
|
395
|
+
|
|
396
|
+
${docs.agentsMdSection}` : void 0);
|
|
397
|
+
}
|
|
398
|
+
function setupAgents(options) {
|
|
399
|
+
const { rootDir, rules = true, mcp = true, dryRun = false, remove = false } = options;
|
|
400
|
+
const targets = options.targets ?? detectAgentTargets(rootDir);
|
|
401
|
+
const docs = remove || !rules ? void 0 : readAgentDocs(rootDir, options.docsDir);
|
|
402
|
+
const version = docs?.version ?? "";
|
|
403
|
+
const changes = new ChangeSet(rootDir, dryRun);
|
|
404
|
+
const server = options.mcpServer ?? DEFAULT_MCP_SERVER;
|
|
405
|
+
if (rules || remove)
|
|
406
|
+
syncRules(changes, rootDir, targets, docs);
|
|
407
|
+
if (mcp || remove) {
|
|
408
|
+
for (const target of ["claude", "cursor", "vscode"]) {
|
|
409
|
+
if (targets.includes(target))
|
|
410
|
+
syncMcpConfig(changes, MCP_FILES[target], server, remove);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return { targets, version, changes: changes.changes };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export { AGENTS_MD_BEGIN, AGENTS_MD_END, AGENT_TARGETS, DEFAULT_MCP_SERVER, MANAGED_MARKER, MCP_SERVER_NAME, createLogger, detectAgentTargets, execPromise, findInstalledPackage, logger, printBanner, readAgentDocs, redactError, redactSecrets, setupAgents };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maz-ui/node",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.0.0",
|
|
4
|
+
"version": "5.1.0-beta.0",
|
|
5
5
|
"description": "Node utilities for Maz-UI library",
|
|
6
6
|
"author": "Louis Mazel <me@loicmazuel.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"utilities",
|
|
16
16
|
"maz-ui",
|
|
17
17
|
"promise",
|
|
18
|
-
"logger"
|
|
18
|
+
"logger",
|
|
19
|
+
"ai",
|
|
20
|
+
"agents"
|
|
19
21
|
],
|
|
20
22
|
"sideEffects": false,
|
|
21
23
|
"publishConfig": {
|
|
@@ -42,7 +44,8 @@
|
|
|
42
44
|
"dependencies": {
|
|
43
45
|
"colorette": "^2.0.20",
|
|
44
46
|
"consola": "^3.4.2",
|
|
45
|
-
"figlet": "^1.12.0"
|
|
47
|
+
"figlet": "^1.12.0",
|
|
48
|
+
"jsonc-parser": "^3.3.1"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
51
|
"unbuild": "^3.6.1"
|