@maz-ui/node 5.0.0-canary.ef64a02.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 +3 -1
- package/dist/index.d.mts +164 -9
- package/dist/index.d.ts +164 -9
- package/dist/index.mjs +297 -10
- package/package.json +9 -6
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,11 +365,12 @@ 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
|
|
370
372
|
|
|
371
|
-
- Node.js >=
|
|
373
|
+
- Node.js >= 22.12.0
|
|
372
374
|
- TypeScript support included
|
|
373
375
|
|
|
374
376
|
## Contributing
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ExecOptions } from 'node:child_process';
|
|
1
2
|
import * as consola from 'consola';
|
|
2
3
|
import { ConsolaOptions, InputLogObject, ConsolaReporter, ConsolaInstance } from 'consola';
|
|
3
4
|
export { ConsolaOptions } from 'consola';
|
|
@@ -51,28 +52,88 @@ interface CustomLogger {
|
|
|
51
52
|
warn: (message: string, ...args: any[]) => void;
|
|
52
53
|
debug: (message: string, ...args: any[]) => void;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Options for {@link execPromise}.
|
|
57
|
+
*
|
|
58
|
+
* The following fields are forwarded as-is to `child_process.exec`:
|
|
59
|
+
* - `cwd` - working directory of the command. Defaults to the current one.
|
|
60
|
+
* - `env` - environment variables, **merged on top of `process.env`**.
|
|
61
|
+
* - `timeout` - maximum run time in milliseconds before the command is killed. No timeout by default.
|
|
62
|
+
* - `maxBuffer` - maximum bytes allowed on stdout/stderr before the command is killed. Defaults to `1024 * 1024` (1 MiB).
|
|
63
|
+
* - `killSignal` - signal used to kill the command on timeout or abort. Defaults to `'SIGTERM'`.
|
|
64
|
+
* - `shell` - shell used to run the command. Defaults to `/bin/sh` (Unix) or `cmd.exe` (Windows).
|
|
65
|
+
* - `signal` - an `AbortSignal` that, once aborted, kills the command and rejects the promise.
|
|
66
|
+
*/
|
|
67
|
+
type ExecPromiseOptions = Pick<ExecOptions, 'cwd' | 'timeout' | 'env' | 'maxBuffer' | 'killSignal' | 'shell' | 'signal'> & {
|
|
68
|
+
/**
|
|
69
|
+
* Custom logger used for every output. Falls back to the package logger.
|
|
70
|
+
*/
|
|
55
71
|
logger?: CustomLogger;
|
|
72
|
+
/**
|
|
73
|
+
* Prefix added to every log line, formatted as `[packageName]: `.
|
|
74
|
+
*/
|
|
56
75
|
packageName?: string;
|
|
57
76
|
/**
|
|
58
|
-
* Don't log success message
|
|
77
|
+
* Don't log the success message.
|
|
78
|
+
* @default false
|
|
59
79
|
*/
|
|
60
80
|
noSuccess?: boolean;
|
|
61
81
|
/**
|
|
62
|
-
* Don't log stdout
|
|
82
|
+
* Don't log stdout.
|
|
83
|
+
* @default false
|
|
63
84
|
*/
|
|
64
85
|
noStdout?: boolean;
|
|
65
86
|
/**
|
|
66
|
-
* Don't log stderr
|
|
87
|
+
* Don't log stderr.
|
|
88
|
+
* @default false
|
|
67
89
|
*/
|
|
68
90
|
noStderr?: boolean;
|
|
69
91
|
/**
|
|
70
|
-
* Don't log error
|
|
92
|
+
* Don't log the error when the command fails.
|
|
93
|
+
* @default false
|
|
71
94
|
*/
|
|
72
95
|
noError?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Logging level applied to the default logger before running the command.
|
|
98
|
+
*/
|
|
73
99
|
logLevel?: LogLevel;
|
|
74
|
-
|
|
75
|
-
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Runs a shell command and resolves with its `stdout` and `stderr`.
|
|
103
|
+
*
|
|
104
|
+
* Secrets (npm auth tokens, `--token`/`--password` flags, provider tokens,
|
|
105
|
+
* JWTs, basic-auth URLs) are automatically masked in every log line and in the
|
|
106
|
+
* rejected error via {@link redactSecrets}. The resolved `stdout`/`stderr` are
|
|
107
|
+
* returned untouched.
|
|
108
|
+
*
|
|
109
|
+
* @param command - The shell command to execute.
|
|
110
|
+
* @returns A promise resolving with the command `stdout` and `stderr`.
|
|
111
|
+
* @throws If the command exits with a non-zero code, times out, is aborted, or
|
|
112
|
+
* exceeds `maxBuffer`. The rejected error is redacted.
|
|
113
|
+
*
|
|
114
|
+
* @example Basic usage
|
|
115
|
+
* ```ts
|
|
116
|
+
* const { stdout } = await execPromise('node --version')
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @example Fail the command after 5 seconds
|
|
120
|
+
* ```ts
|
|
121
|
+
* await execPromise('pnpm install', { timeout: 5000 })
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @example Inject environment variables (merged on top of `process.env`)
|
|
125
|
+
* ```ts
|
|
126
|
+
* await execPromise('node build.mjs', { env: { NODE_ENV: 'production' } })
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example Cancel the command with an `AbortController`
|
|
130
|
+
* ```ts
|
|
131
|
+
* const controller = new AbortController()
|
|
132
|
+
* const promise = execPromise('long-task', { signal: controller.signal })
|
|
133
|
+
* controller.abort()
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function execPromise(command: string, { logger, packageName, noSuccess, noStdout, noStderr, noError, logLevel, cwd, timeout, env, maxBuffer, killSignal, shell, signal, }?: ExecPromiseOptions): Promise<{
|
|
76
137
|
stdout: string;
|
|
77
138
|
stderr: string;
|
|
78
139
|
}>;
|
|
@@ -88,5 +149,99 @@ declare function printBanner({ name, version, options, }: {
|
|
|
88
149
|
};
|
|
89
150
|
}): void;
|
|
90
151
|
|
|
91
|
-
|
|
92
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Masks secrets that have a recognizable syntactic context inside a string.
|
|
154
|
+
*
|
|
155
|
+
* Only deterministic patterns are redacted (npm auth tokens, named secret flags
|
|
156
|
+
* such as `--token`/`--password`, prefixed provider tokens like `npm_`/`ghp_`,
|
|
157
|
+
* JWTs, and basic-auth credentials in URLs). Context-free random strings are left
|
|
158
|
+
* untouched because they cannot be detected without false positives.
|
|
159
|
+
*
|
|
160
|
+
* Tokens long enough (>= 16 chars) keep their first and last 4 characters visible
|
|
161
|
+
* (e.g. `npm_***J1iF`) so the right credential can still be recognized; shorter
|
|
162
|
+
* secrets are fully masked.
|
|
163
|
+
*/
|
|
164
|
+
declare function redactSecrets(input: string): string;
|
|
165
|
+
/**
|
|
166
|
+
* Returns the given error with its `message`, `cmd` and `stack` redacted via
|
|
167
|
+
* {@link redactSecrets}, so a thrown command never carries secrets to callers.
|
|
168
|
+
*/
|
|
169
|
+
declare function redactError<T>(error: T): T;
|
|
170
|
+
|
|
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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ExecOptions } from 'node:child_process';
|
|
1
2
|
import * as consola from 'consola';
|
|
2
3
|
import { ConsolaOptions, InputLogObject, ConsolaReporter, ConsolaInstance } from 'consola';
|
|
3
4
|
export { ConsolaOptions } from 'consola';
|
|
@@ -51,28 +52,88 @@ interface CustomLogger {
|
|
|
51
52
|
warn: (message: string, ...args: any[]) => void;
|
|
52
53
|
debug: (message: string, ...args: any[]) => void;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Options for {@link execPromise}.
|
|
57
|
+
*
|
|
58
|
+
* The following fields are forwarded as-is to `child_process.exec`:
|
|
59
|
+
* - `cwd` - working directory of the command. Defaults to the current one.
|
|
60
|
+
* - `env` - environment variables, **merged on top of `process.env`**.
|
|
61
|
+
* - `timeout` - maximum run time in milliseconds before the command is killed. No timeout by default.
|
|
62
|
+
* - `maxBuffer` - maximum bytes allowed on stdout/stderr before the command is killed. Defaults to `1024 * 1024` (1 MiB).
|
|
63
|
+
* - `killSignal` - signal used to kill the command on timeout or abort. Defaults to `'SIGTERM'`.
|
|
64
|
+
* - `shell` - shell used to run the command. Defaults to `/bin/sh` (Unix) or `cmd.exe` (Windows).
|
|
65
|
+
* - `signal` - an `AbortSignal` that, once aborted, kills the command and rejects the promise.
|
|
66
|
+
*/
|
|
67
|
+
type ExecPromiseOptions = Pick<ExecOptions, 'cwd' | 'timeout' | 'env' | 'maxBuffer' | 'killSignal' | 'shell' | 'signal'> & {
|
|
68
|
+
/**
|
|
69
|
+
* Custom logger used for every output. Falls back to the package logger.
|
|
70
|
+
*/
|
|
55
71
|
logger?: CustomLogger;
|
|
72
|
+
/**
|
|
73
|
+
* Prefix added to every log line, formatted as `[packageName]: `.
|
|
74
|
+
*/
|
|
56
75
|
packageName?: string;
|
|
57
76
|
/**
|
|
58
|
-
* Don't log success message
|
|
77
|
+
* Don't log the success message.
|
|
78
|
+
* @default false
|
|
59
79
|
*/
|
|
60
80
|
noSuccess?: boolean;
|
|
61
81
|
/**
|
|
62
|
-
* Don't log stdout
|
|
82
|
+
* Don't log stdout.
|
|
83
|
+
* @default false
|
|
63
84
|
*/
|
|
64
85
|
noStdout?: boolean;
|
|
65
86
|
/**
|
|
66
|
-
* Don't log stderr
|
|
87
|
+
* Don't log stderr.
|
|
88
|
+
* @default false
|
|
67
89
|
*/
|
|
68
90
|
noStderr?: boolean;
|
|
69
91
|
/**
|
|
70
|
-
* Don't log error
|
|
92
|
+
* Don't log the error when the command fails.
|
|
93
|
+
* @default false
|
|
71
94
|
*/
|
|
72
95
|
noError?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Logging level applied to the default logger before running the command.
|
|
98
|
+
*/
|
|
73
99
|
logLevel?: LogLevel;
|
|
74
|
-
|
|
75
|
-
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Runs a shell command and resolves with its `stdout` and `stderr`.
|
|
103
|
+
*
|
|
104
|
+
* Secrets (npm auth tokens, `--token`/`--password` flags, provider tokens,
|
|
105
|
+
* JWTs, basic-auth URLs) are automatically masked in every log line and in the
|
|
106
|
+
* rejected error via {@link redactSecrets}. The resolved `stdout`/`stderr` are
|
|
107
|
+
* returned untouched.
|
|
108
|
+
*
|
|
109
|
+
* @param command - The shell command to execute.
|
|
110
|
+
* @returns A promise resolving with the command `stdout` and `stderr`.
|
|
111
|
+
* @throws If the command exits with a non-zero code, times out, is aborted, or
|
|
112
|
+
* exceeds `maxBuffer`. The rejected error is redacted.
|
|
113
|
+
*
|
|
114
|
+
* @example Basic usage
|
|
115
|
+
* ```ts
|
|
116
|
+
* const { stdout } = await execPromise('node --version')
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @example Fail the command after 5 seconds
|
|
120
|
+
* ```ts
|
|
121
|
+
* await execPromise('pnpm install', { timeout: 5000 })
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @example Inject environment variables (merged on top of `process.env`)
|
|
125
|
+
* ```ts
|
|
126
|
+
* await execPromise('node build.mjs', { env: { NODE_ENV: 'production' } })
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example Cancel the command with an `AbortController`
|
|
130
|
+
* ```ts
|
|
131
|
+
* const controller = new AbortController()
|
|
132
|
+
* const promise = execPromise('long-task', { signal: controller.signal })
|
|
133
|
+
* controller.abort()
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function execPromise(command: string, { logger, packageName, noSuccess, noStdout, noStderr, noError, logLevel, cwd, timeout, env, maxBuffer, killSignal, shell, signal, }?: ExecPromiseOptions): Promise<{
|
|
76
137
|
stdout: string;
|
|
77
138
|
stderr: string;
|
|
78
139
|
}>;
|
|
@@ -88,5 +149,99 @@ declare function printBanner({ name, version, options, }: {
|
|
|
88
149
|
};
|
|
89
150
|
}): void;
|
|
90
151
|
|
|
91
|
-
|
|
92
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Masks secrets that have a recognizable syntactic context inside a string.
|
|
154
|
+
*
|
|
155
|
+
* Only deterministic patterns are redacted (npm auth tokens, named secret flags
|
|
156
|
+
* such as `--token`/`--password`, prefixed provider tokens like `npm_`/`ghp_`,
|
|
157
|
+
* JWTs, and basic-auth credentials in URLs). Context-free random strings are left
|
|
158
|
+
* untouched because they cannot be detected without false positives.
|
|
159
|
+
*
|
|
160
|
+
* Tokens long enough (>= 16 chars) keep their first and last 4 characters visible
|
|
161
|
+
* (e.g. `npm_***J1iF`) so the right credential can still be recognized; shorter
|
|
162
|
+
* secrets are fully masked.
|
|
163
|
+
*/
|
|
164
|
+
declare function redactSecrets(input: string): string;
|
|
165
|
+
/**
|
|
166
|
+
* Returns the given error with its `message`, `cmd` and `stack` redacted via
|
|
167
|
+
* {@link redactSecrets}, so a thrown command never carries secrets to callers.
|
|
168
|
+
*/
|
|
169
|
+
declare function redactError<T>(error: T): T;
|
|
170
|
+
|
|
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,
|
|
@@ -53,6 +56,43 @@ function createLogger(options) {
|
|
|
53
56
|
}
|
|
54
57
|
const logger = createLogger();
|
|
55
58
|
|
|
59
|
+
const MASK = "***";
|
|
60
|
+
const VISIBLE_PREFIX = 4;
|
|
61
|
+
const MIN_LENGTH_TO_REVEAL = 16;
|
|
62
|
+
const SECRET_FLAG_NAMES = "password|passwd|pwd|pass|token|api[-_]?key|secret|authorization|auth[-_]?token|access[-_]?token|refresh[-_]?token|client[-_]?secret|private[-_]?key|credentials?|auth";
|
|
63
|
+
const keepEnds = (value) => value.length < MIN_LENGTH_TO_REVEAL ? MASK : `${value.slice(0, VISIBLE_PREFIX)}${MASK}${value.slice(-4)}`;
|
|
64
|
+
const keepPrefix = (_match, prefix, value) => `${prefix}${keepEnds(value)}`;
|
|
65
|
+
const REDACTION_RULES = [
|
|
66
|
+
[/(:?_authToken=)([^\s&]+)/gi, keepPrefix],
|
|
67
|
+
[new RegExp(`(--(?:${SECRET_FLAG_NAMES})=)(\\S+)`, "gi"), keepPrefix],
|
|
68
|
+
[new RegExp(`(--(?:${SECRET_FLAG_NAMES})\\s+)(?!-)(\\S+)`, "gi"), keepPrefix],
|
|
69
|
+
[/(\/\/[^/:@\s]+:)([^/@\s]+)@/g, (_match, prefix, value) => `${prefix}${keepEnds(value)}@`],
|
|
70
|
+
[/npm_[A-Za-z0-9]{10,}/g, keepEnds],
|
|
71
|
+
[/gh[posru]_[A-Za-z0-9]{20,}/g, keepEnds],
|
|
72
|
+
[/github_pat_\w{20,}/g, keepEnds],
|
|
73
|
+
[/glpat-[\w-]{15,}/g, keepEnds],
|
|
74
|
+
[/xox[baprs]-[A-Za-z0-9-]{10,}/g, keepEnds],
|
|
75
|
+
[/AKIA[0-9A-Z]{16}/g, keepEnds],
|
|
76
|
+
[/sk-[\w-]{16,}/g, keepEnds],
|
|
77
|
+
[/eyJ[\w-]+\.eyJ[\w-]+\.[\w-]+/g, keepEnds]
|
|
78
|
+
];
|
|
79
|
+
const REDACTABLE_ERROR_KEYS = ["message", "cmd", "stack"];
|
|
80
|
+
function redactSecrets(input) {
|
|
81
|
+
return REDACTION_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), input);
|
|
82
|
+
}
|
|
83
|
+
function redactError(error) {
|
|
84
|
+
if (!error || typeof error !== "object") {
|
|
85
|
+
return error;
|
|
86
|
+
}
|
|
87
|
+
for (const key of REDACTABLE_ERROR_KEYS) {
|
|
88
|
+
const value = error[key];
|
|
89
|
+
if (typeof value === "string") {
|
|
90
|
+
error[key] = redactSecrets(value);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return error;
|
|
94
|
+
}
|
|
95
|
+
|
|
56
96
|
async function execPromise(command, {
|
|
57
97
|
logger: logger$1,
|
|
58
98
|
packageName,
|
|
@@ -61,35 +101,52 @@ async function execPromise(command, {
|
|
|
61
101
|
noStderr = false,
|
|
62
102
|
noError = false,
|
|
63
103
|
logLevel,
|
|
64
|
-
cwd
|
|
104
|
+
cwd,
|
|
105
|
+
timeout,
|
|
106
|
+
env,
|
|
107
|
+
maxBuffer,
|
|
108
|
+
killSignal,
|
|
109
|
+
shell,
|
|
110
|
+
signal
|
|
65
111
|
} = {}) {
|
|
66
112
|
if (logLevel) {
|
|
67
113
|
logger.setLevel(logLevel);
|
|
68
114
|
}
|
|
69
115
|
const internalLogger = logger$1 ?? logger;
|
|
70
116
|
const packageNameStr = packageName ? `[${packageName}]: ` : "";
|
|
117
|
+
const safeCommand = redactSecrets(command);
|
|
71
118
|
return await new Promise((resolve, reject) => {
|
|
72
|
-
exec(command, {
|
|
119
|
+
exec(command, {
|
|
120
|
+
cwd,
|
|
121
|
+
timeout,
|
|
122
|
+
maxBuffer,
|
|
123
|
+
killSignal,
|
|
124
|
+
shell,
|
|
125
|
+
signal,
|
|
126
|
+
env: env ? { ...process$1.env, ...env } : void 0
|
|
127
|
+
}, (error, stdout, stderr) => {
|
|
73
128
|
if (stdout) {
|
|
74
|
-
internalLogger.debug(`${
|
|
129
|
+
internalLogger.debug(`${safeCommand} - stdout output:`, redactSecrets(stdout));
|
|
75
130
|
}
|
|
76
131
|
if (stderr) {
|
|
77
|
-
internalLogger.debug(`${
|
|
132
|
+
internalLogger.debug(`${safeCommand} - stderr output:`, redactSecrets(stderr));
|
|
78
133
|
}
|
|
79
134
|
if (stdout && !noStdout) {
|
|
80
|
-
internalLogger.log(`${packageNameStr}stdout -`, stdout.trim());
|
|
135
|
+
internalLogger.log(`${packageNameStr}stdout -`, redactSecrets(stdout.trim()));
|
|
81
136
|
}
|
|
82
137
|
if (stderr && !noStderr) {
|
|
83
|
-
internalLogger.log(`${packageNameStr}stderr -`, stderr.trim());
|
|
138
|
+
internalLogger.log(`${packageNameStr}stderr -`, redactSecrets(stderr.trim()));
|
|
84
139
|
}
|
|
85
140
|
if (error) {
|
|
141
|
+
const safeError = redactError(error);
|
|
86
142
|
if (!noError) {
|
|
87
|
-
|
|
143
|
+
const reason = error.killed && timeout ? `timed out after ${timeout}ms` : "failed";
|
|
144
|
+
internalLogger.error(`${packageNameStr}${safeCommand} ${reason}`, safeError);
|
|
88
145
|
}
|
|
89
|
-
reject(
|
|
146
|
+
reject(safeError);
|
|
90
147
|
} else {
|
|
91
148
|
if (!noSuccess) {
|
|
92
|
-
internalLogger.info(`${packageNameStr}${
|
|
149
|
+
internalLogger.info(`${packageNameStr}${safeCommand} - Success!`);
|
|
93
150
|
}
|
|
94
151
|
resolve({ stdout, stderr });
|
|
95
152
|
}
|
|
@@ -126,4 +183,234 @@ function printBanner({
|
|
|
126
183
|
logger.break();
|
|
127
184
|
}
|
|
128
185
|
|
|
129
|
-
|
|
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.
|
|
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": {
|
|
@@ -25,7 +27,8 @@
|
|
|
25
27
|
".": {
|
|
26
28
|
"monorepo:dev": "./src/index.ts",
|
|
27
29
|
"types": "./dist/index.d.ts",
|
|
28
|
-
"import": "./dist/index.mjs"
|
|
30
|
+
"import": "./dist/index.mjs",
|
|
31
|
+
"default": "./dist/index.mjs"
|
|
29
32
|
}
|
|
30
33
|
},
|
|
31
34
|
"main": "./dist/index.mjs",
|
|
@@ -36,12 +39,13 @@
|
|
|
36
39
|
"dist"
|
|
37
40
|
],
|
|
38
41
|
"engines": {
|
|
39
|
-
"node": ">=
|
|
42
|
+
"node": ">=22.12.0"
|
|
40
43
|
},
|
|
41
44
|
"dependencies": {
|
|
42
45
|
"colorette": "^2.0.20",
|
|
43
46
|
"consola": "^3.4.2",
|
|
44
|
-
"figlet": "^1.
|
|
47
|
+
"figlet": "^1.12.0",
|
|
48
|
+
"jsonc-parser": "^3.3.1"
|
|
45
49
|
},
|
|
46
50
|
"devDependencies": {
|
|
47
51
|
"unbuild": "^3.6.1"
|
|
@@ -52,7 +56,6 @@
|
|
|
52
56
|
]
|
|
53
57
|
},
|
|
54
58
|
"scripts": {
|
|
55
|
-
"codegen": "nx build",
|
|
56
59
|
"build": "unbuild",
|
|
57
60
|
"dev": "unbuild --stub",
|
|
58
61
|
"typecheck": "tsc --noEmit --skipLibCheck",
|