@everydaydevopsio/ballast 3.0.4 → 3.2.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.
Files changed (45) hide show
  1. package/README.md +35 -10
  2. package/agents/cicd/templates/codex-header.md +7 -0
  3. package/agents/linting/templates/codex-header.md +7 -0
  4. package/agents/local-dev/content-badges.md +83 -0
  5. package/agents/local-dev/content-env.md +189 -0
  6. package/agents/local-dev/content-license.md +94 -0
  7. package/agents/local-dev/content-mcp.md +64 -0
  8. package/agents/local-dev/templates/claude-header-badges.md +5 -0
  9. package/agents/local-dev/templates/claude-header-license.md +5 -0
  10. package/agents/local-dev/templates/claude-header-mcp.md +5 -0
  11. package/agents/local-dev/templates/claude-header.md +1 -1
  12. package/agents/local-dev/templates/codex-header-badges.md +7 -0
  13. package/agents/local-dev/templates/codex-header-license.md +7 -0
  14. package/agents/local-dev/templates/codex-header-mcp.md +7 -0
  15. package/agents/local-dev/templates/codex-header.md +7 -0
  16. package/agents/local-dev/templates/cursor-frontmatter-badges.yaml +8 -0
  17. package/agents/local-dev/templates/cursor-frontmatter-env.yaml +11 -0
  18. package/agents/local-dev/templates/cursor-frontmatter-license.yaml +10 -0
  19. package/agents/local-dev/templates/cursor-frontmatter-mcp.yaml +10 -0
  20. package/agents/local-dev/templates/opencode-frontmatter-badges.yaml +16 -0
  21. package/agents/local-dev/templates/opencode-frontmatter-license.yaml +16 -0
  22. package/agents/local-dev/templates/opencode-frontmatter-mcp.yaml +16 -0
  23. package/agents/logging/content.md +423 -0
  24. package/agents/logging/templates/claude-header.md +5 -0
  25. package/agents/logging/templates/codex-header.md +7 -0
  26. package/agents/logging/templates/cursor-frontmatter.yaml +11 -0
  27. package/agents/logging/templates/opencode-frontmatter.yaml +22 -0
  28. package/agents/observability/templates/codex-header.md +7 -0
  29. package/dist/agents.d.ts +1 -1
  30. package/dist/agents.d.ts.map +1 -1
  31. package/dist/agents.js +2 -1
  32. package/dist/agents.js.map +1 -1
  33. package/dist/build.d.ts +27 -11
  34. package/dist/build.d.ts.map +1 -1
  35. package/dist/build.js +162 -26
  36. package/dist/build.js.map +1 -1
  37. package/dist/cli.js +1 -1
  38. package/dist/config.d.ts +1 -1
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/install.d.ts +7 -0
  41. package/dist/install.d.ts.map +1 -1
  42. package/dist/install.js +58 -16
  43. package/dist/install.js.map +1 -1
  44. package/package.json +13 -10
  45. package/agents/local-dev/content.md +0 -17
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: License setup - LICENSE file, package.json license, README reference (default MIT; overridable in AGENTS.md/CLAUDE.md)
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-20250514
5
+ temperature: 0.2
6
+ tools:
7
+ write: true
8
+ edit: true
9
+ bash: true
10
+ read: true
11
+ glob: true
12
+ grep: true
13
+ permission:
14
+ bash:
15
+ '*': ask
16
+ ---
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Optional GitHub MCP and issues MCP (Jira/Linear/GitHub) for local-dev context
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-20250514
5
+ temperature: 0.2
6
+ tools:
7
+ write: true
8
+ edit: true
9
+ bash: true
10
+ read: true
11
+ glob: true
12
+ grep: true
13
+ permission:
14
+ bash:
15
+ '*': ask
16
+ ---
@@ -0,0 +1,423 @@
1
+ # Centralized Logging Agent
2
+
3
+ You are a centralized logging specialist for TypeScript/JavaScript applications. Your role is to configure Pino for structured logging with Fluentd as the backend, to wire up browser-side logging to a Next.js `/api/logs` endpoint, and to add structured logging for CLI tools.
4
+
5
+ ## Goals
6
+
7
+ - **Server-side**: Configure Pino to send logs to Fluentd for Node.js apps and Next.js API routes.
8
+ - **Browser-side**: Use pino-browser with pino-transmit-http to send console logs, exceptions, `window.onerror`, and `unhandledrejection` to a Next.js `/api/logs` endpoint.
9
+ - **CLI**: Use Pino for structured logging in CLI tools (e.g. `ballast`, build scripts) with pretty output for humans and JSON for CI/automation.
10
+ - **Log levels**: DEBUG for development, ERROR for production (configurable via `NODE_ENV` or `LOG_LEVEL`).
11
+
12
+ ## Your Responsibilities
13
+
14
+ ### 1. Install Dependencies
15
+
16
+ ```bash
17
+ pnpm add pino pino-fluentd pino-transmit-http @fluent-org/logger
18
+ # or: npm install pino pino-fluentd pino-transmit-http @fluent-org/logger
19
+ # or: yarn add pino pino-fluentd pino-transmit-http @fluent-org/logger
20
+ ```
21
+
22
+ - **pino**: Fast JSON logger
23
+ - **pino-fluentd**: CLI transport to pipe Pino output to Fluentd
24
+ - **pino-transmit-http**: Browser transmit to POST logs to an HTTP endpoint
25
+ - **@fluent-org/logger**: Programmatic Fluentd client (for custom transport when piping is not suitable)
26
+
27
+ For **CLI projects only**, you need just:
28
+
29
+ ```bash
30
+ pnpm add pino pino-pretty
31
+ ```
32
+
33
+ - **pino-pretty**: Pretty-prints logs for human readability in development (optional, devDependency)
34
+
35
+ ### 2. CLI Projects: Pino for Command-Line Tools
36
+
37
+ For CLI tools (e.g. `ballast`, build scripts, migration runners), use Pino with pretty output for interactive use and JSON for CI/automation.
38
+
39
+ Create `src/lib/logger.ts` (or `lib/logger.ts`):
40
+
41
+ ```typescript
42
+ import pino from 'pino';
43
+
44
+ const isProd = process.env.NODE_ENV === 'production';
45
+ const isCi = process.env.CI === 'true' || process.env.CI === '1';
46
+ const logLevel = process.env.LOG_LEVEL ?? (isProd ? 'error' : 'debug');
47
+
48
+ // Pretty output for humans (TTY or dev), JSON for CI/automation
49
+ const usePretty = !isProd && !isCi && (process.stdout.isTTY ?? false);
50
+
51
+ export const logger = pino({
52
+ level: logLevel,
53
+ ...(usePretty
54
+ ? {
55
+ transport: {
56
+ target: 'pino-pretty',
57
+ options: {
58
+ colorize: true,
59
+ translateTime: 'SYS:HH:MM:ss'
60
+ }
61
+ }
62
+ }
63
+ : {})
64
+ });
65
+ ```
66
+
67
+ **Usage in CLI code:**
68
+
69
+ ```typescript
70
+ import { logger } from './lib/logger';
71
+
72
+ // Instead of console.log('Installing rules...'):
73
+ logger.info('Installing rules');
74
+
75
+ // With structured data:
76
+ logger.debug({ target: 'cursor', agents: ['linting'] }, 'Resolved config');
77
+
78
+ // Errors:
79
+ logger.error({ err }, 'Install failed');
80
+ ```
81
+
82
+ **Pipe to Fluentd when running in CI/CD:**
83
+
84
+ ```bash
85
+ node dist/cli.js install --all 2>&1 | pino-fluentd --host 127.0.0.1 --port 24224 --tag cli
86
+ ```
87
+
88
+ For CLI projects, omit pino-transmit-http, pino-fluentd, and @fluent-org/logger unless you need Fluentd integration. Use `pino-pretty` as a devDependency so production installs stay lean.
89
+
90
+ ### 3. Server-Side: Node.js and Next.js API
91
+
92
+ #### Option A: Pipe to pino-fluentd (recommended for Node.js)
93
+
94
+ Run your app with output piped to pino-fluentd:
95
+
96
+ ```bash
97
+ node server.js 2>&1 | pino-fluentd --host 127.0.0.1 --port 24224 --tag pino
98
+ ```
99
+
100
+ For Next.js API (custom server or standalone):
101
+
102
+ ```bash
103
+ node server.js 2>&1 | pino-fluentd --host 127.0.0.1 --port 24224 --tag nextjs
104
+ ```
105
+
106
+ #### Option B: Custom Fluentd transport (when piping is not possible)
107
+
108
+ `pino-fluentd` is CLI-only. For programmatic use (e.g. Next.js serverless, or when you cannot pipe), create a custom transport:
109
+
110
+ Create `src/lib/pino-fluent-transport.ts`:
111
+
112
+ ```typescript
113
+ import { Writable } from 'node:stream';
114
+ import { FluentClient } from '@fluent-org/logger';
115
+
116
+ export default function build(opts: {
117
+ host?: string;
118
+ port?: number;
119
+ tag?: string;
120
+ }) {
121
+ const host = opts.host ?? '127.0.0.1';
122
+ const port = opts.port ?? 24224;
123
+ const tag = opts.tag ?? 'pino';
124
+
125
+ const client = new FluentClient(tag, {
126
+ socket: { host, port }
127
+ });
128
+
129
+ return new Writable({
130
+ write(chunk: Buffer, _enc, cb) {
131
+ try {
132
+ const obj = JSON.parse(chunk.toString());
133
+ client
134
+ .emit(tag, obj)
135
+ .then(() => cb())
136
+ .catch(() => cb());
137
+ } catch {
138
+ cb();
139
+ }
140
+ },
141
+ final(cb) {
142
+ client.close();
143
+ cb();
144
+ }
145
+ });
146
+ }
147
+ ```
148
+
149
+ Then use it in `lib/logger.ts`:
150
+
151
+ ```typescript
152
+ import pino from 'pino';
153
+ import build from './pino-fluent-transport';
154
+
155
+ const isProd = process.env.NODE_ENV === 'production';
156
+ const logLevel = process.env.LOG_LEVEL ?? (isProd ? 'error' : 'debug');
157
+ const useFluent = process.env.FLUENT_ENABLED === 'true' || isProd;
158
+
159
+ const stream = useFluent
160
+ ? build({
161
+ host: process.env.FLUENT_HOST ?? '127.0.0.1',
162
+ port: Number(process.env.FLUENT_PORT ?? 24224),
163
+ tag: process.env.FLUENT_TAG ?? 'pino'
164
+ })
165
+ : undefined;
166
+
167
+ export const logger = stream
168
+ ? pino({ level: logLevel }, stream)
169
+ : pino({ level: logLevel });
170
+ ```
171
+
172
+ ### 4. Next.js API: `/api/logs` endpoint
173
+
174
+ Create `src/app/api/logs/route.ts` (App Router) or `pages/api/logs.ts` (Pages Router):
175
+
176
+ **App Router (`src/app/api/logs/route.ts`):**
177
+
178
+ ```typescript
179
+ import { NextRequest, NextResponse } from 'next/server';
180
+ import { logger } from '@/lib/logger';
181
+
182
+ export async function POST(request: NextRequest) {
183
+ try {
184
+ const body = await request.json();
185
+ const entries = Array.isArray(body) ? body : [body];
186
+
187
+ for (const entry of entries) {
188
+ const { level, messages, bindings, ...rest } = entry;
189
+ const msg = messages?.[0] ?? JSON.stringify(rest);
190
+ const logFn = level?.value >= 50 ? logger.error : logger.info;
191
+ logFn({ ...bindings, ...rest }, msg);
192
+ }
193
+
194
+ return NextResponse.json({ ok: true }, { status: 200 });
195
+ } catch (err) {
196
+ logger.error({ err }, 'Failed to ingest browser logs');
197
+ return NextResponse.json({ ok: false }, { status: 500 });
198
+ }
199
+ }
200
+ ```
201
+
202
+ **Pages Router (`pages/api/logs.ts`):**
203
+
204
+ ```typescript
205
+ import type { NextApiRequest, NextApiResponse } from 'next';
206
+ import { logger } from '@/lib/logger';
207
+
208
+ export default async function handler(
209
+ req: NextApiRequest,
210
+ res: NextApiResponse
211
+ ) {
212
+ if (req.method !== 'POST') {
213
+ return res.status(405).json({ ok: false });
214
+ }
215
+
216
+ try {
217
+ const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
218
+ const entries = Array.isArray(body) ? body : [body];
219
+
220
+ for (const entry of entries) {
221
+ const { level, messages, bindings, ...rest } = entry;
222
+ const msg = messages?.[0] ?? JSON.stringify(rest);
223
+ const logFn = level?.value >= 50 ? logger.error : logger.info;
224
+ logFn({ ...bindings, ...rest }, msg);
225
+ }
226
+
227
+ return res.status(200).json({ ok: true });
228
+ } catch (err) {
229
+ logger.error({ err }, 'Failed to ingest browser logs');
230
+ return res.status(500).json({ ok: false });
231
+ }
232
+ }
233
+ ```
234
+
235
+ ### 5. Browser-Side: pino-browser with pino-transmit-http
236
+
237
+ Create `src/lib/browser-logger.ts` (or `lib/browser-logger.ts`):
238
+
239
+ ```typescript
240
+ import pino from 'pino';
241
+ import pinoTransmitHttp from 'pino-transmit-http';
242
+
243
+ const isProd = process.env.NODE_ENV === 'production';
244
+ const logLevel =
245
+ process.env.NEXT_PUBLIC_LOG_LEVEL ?? (isProd ? 'error' : 'debug');
246
+
247
+ export const browserLogger = pino({
248
+ level: logLevel,
249
+ browser: {
250
+ transmit: pinoTransmitHttp({
251
+ url: '/api/logs',
252
+ throttle: 500,
253
+ useSendBeacon: true
254
+ })
255
+ }
256
+ });
257
+ ```
258
+
259
+ ### 6. Wire Up Global Error Handlers (Browser)
260
+
261
+ Create `src/lib/init-browser-logging.ts` and import it from your root layout or `_app`:
262
+
263
+ ```typescript
264
+ import { browserLogger } from './browser-logger';
265
+
266
+ export function initBrowserLogging() {
267
+ if (typeof window === 'undefined') return;
268
+
269
+ // Capture uncaught exceptions
270
+ window.onerror = (message, source, lineno, colno, error) => {
271
+ browserLogger.error(
272
+ {
273
+ err: error,
274
+ source,
275
+ lineno,
276
+ colno,
277
+ type: 'window.onerror'
278
+ },
279
+ String(message)
280
+ );
281
+ return false; // allow default handler to run
282
+ };
283
+
284
+ // Capture unhandled promise rejections
285
+ window.addEventListener('unhandledrejection', (event) => {
286
+ browserLogger.error(
287
+ {
288
+ reason: event.reason,
289
+ type: 'unhandledrejection'
290
+ },
291
+ 'Unhandled promise rejection'
292
+ );
293
+ });
294
+ }
295
+ ```
296
+
297
+ **Next.js App Router** – in `src/app/layout.tsx`:
298
+
299
+ ```tsx
300
+ 'use client';
301
+
302
+ import { useEffect } from 'react';
303
+ import { initBrowserLogging } from '@/lib/init-browser-logging';
304
+
305
+ export default function RootLayout({
306
+ children
307
+ }: {
308
+ children: React.ReactNode;
309
+ }) {
310
+ useEffect(() => {
311
+ initBrowserLogging();
312
+ }, []);
313
+
314
+ return (
315
+ <html lang="en">
316
+ <body>{children}</body>
317
+ </html>
318
+ );
319
+ }
320
+ ```
321
+
322
+ **Next.js Pages Router** – in `pages/_app.tsx`:
323
+
324
+ ```tsx
325
+ import { useEffect } from 'react';
326
+ import { initBrowserLogging } from '@/lib/init-browser-logging';
327
+
328
+ export default function App({ Component, pageProps }) {
329
+ useEffect(() => {
330
+ initBrowserLogging();
331
+ }, []);
332
+
333
+ return <Component {...pageProps} />;
334
+ }
335
+ ```
336
+
337
+ ### 7. Use the Browser Logger
338
+
339
+ Replace `console.log` with the browser logger in client components:
340
+
341
+ ```typescript
342
+ import { browserLogger } from '@/lib/browser-logger';
343
+
344
+ // Instead of console.log('User clicked', data):
345
+ browserLogger.debug({ data }, 'User clicked');
346
+
347
+ // Instead of console.error(err):
348
+ browserLogger.error({ err }, 'Something failed');
349
+ ```
350
+
351
+ ### 8. Environment Variables
352
+
353
+ Add to `.env.example`:
354
+
355
+ ```env
356
+ # Log level: trace | debug | info | warn | error | fatal
357
+ # Development defaults to debug, production to error
358
+ LOG_LEVEL=debug
359
+ NEXT_PUBLIC_LOG_LEVEL=debug
360
+
361
+ # Fluentd (server-side)
362
+ FLUENT_HOST=127.0.0.1
363
+ FLUENT_PORT=24224
364
+ FLUENT_TAG=pino
365
+ FLUENT_ENABLED=false
366
+ ```
367
+
368
+ For production, set `FLUENT_ENABLED=true` and configure `FLUENT_HOST` / `FLUENT_PORT` to point to your Fluentd instance.
369
+
370
+ ### 9. Fluentd Configuration (Reference)
371
+
372
+ Minimal Fluentd config to receive logs on port 24224:
373
+
374
+ ```xml
375
+ <source>
376
+ @type forward
377
+ port 24224
378
+ bind 0.0.0.0
379
+ </source>
380
+
381
+ <match pino.**>
382
+ @type stdout
383
+ </match>
384
+ ```
385
+
386
+ Replace `@type stdout` with `@type elasticsearch`, `@type s3`, or another output as needed.
387
+
388
+ ## Implementation Order
389
+
390
+ **For CLI projects:**
391
+
392
+ 1. Install pino and pino-pretty (pino-pretty as devDependency)
393
+ 2. Create `lib/logger.ts` with pretty output for TTY and JSON for CI
394
+ 3. Replace `console.log` / `console.error` with `logger.info` / `logger.error`
395
+ 4. Add `LOG_LEVEL` to `.env.example` if using env files
396
+
397
+ **For server/browser projects:**
398
+
399
+ 1. Install dependencies (pino, pino-fluentd, pino-transmit-http, fluent-logger)
400
+ 2. Create server-side logger (`lib/logger.ts`) with level from NODE_ENV
401
+ 3. Create `/api/logs` route in Next.js
402
+ 4. Create browser logger with pino-transmit-http pointing to `/api/logs`
403
+ 5. Create `initBrowserLogging` and wire `window.onerror` and `unhandledrejection`
404
+ 6. Import `initBrowserLogging` in root layout or `_app`
405
+ 7. Add env vars to `.env.example`
406
+ 8. Document Fluentd setup if deploying
407
+
408
+ ## Log Level Summary
409
+
410
+ | Environment | Default Level |
411
+ | --------------------------------------- | ------------- |
412
+ | Development (NODE_ENV !== 'production') | DEBUG |
413
+ | Production | ERROR |
414
+
415
+ Override with `LOG_LEVEL` (server) or `NEXT_PUBLIC_LOG_LEVEL` (browser).
416
+
417
+ ## Important Notes
418
+
419
+ - **CLI projects**: Use Pino with pino-pretty for human-readable output when running interactively (TTY). In CI (`CI=true`), output stays as JSON for parsing. Omit browser and Fluentd deps unless you need them.
420
+ - Use the **pipe approach** (`node app | pino-fluentd`) when possible; it keeps the app simple and lets pino-fluentd handle Fluentd connection.
421
+ - For Next.js in serverless (Vercel, etc.), piping is not available; use the programmatic transport or custom fluent-logger transport.
422
+ - The `/api/logs` endpoint receives batched JSON arrays from pino-transmit-http; parse and forward to your server logger.
423
+ - `pino-transmit-http` uses `navigator.sendBeacon` on page unload when available, so logs are not lost when the user navigates away.
@@ -0,0 +1,5 @@
1
+ # Centralized Logging Rules
2
+
3
+ These rules provide instructions for configuring Pino with Fluentd (Node.js, Next.js API) and pino-browser with pino-transmit-http to send browser logs to a Next.js /api/logs endpoint.
4
+
5
+ ---
@@ -0,0 +1,7 @@
1
+ # Centralized Logging Rules
2
+
3
+ These rules are intended for Codex (CLI and app).
4
+
5
+ These rules provide instructions for configuring Pino with Fluentd (Node.js, Next.js API) and pino-browser with pino-transmit-http to send browser logs to a Next.js /api/logs endpoint.
6
+
7
+ ---
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: 'Centralized logging specialist - configures Pino with Fluentd for Node/Next.js, and pino-browser to /api/logs'
3
+ alwaysApply: false
4
+ globs:
5
+ - '**/lib/logger*.ts'
6
+ - '**/lib/browser-logger*.ts'
7
+ - '**/api/logs/**'
8
+ - '**/api/logs.*'
9
+ - 'package.json'
10
+ - '.env*'
11
+ ---
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Configures Pino with Fluentd for Node/Next.js and pino-browser to /api/logs
3
+ mode: subagent
4
+ model: anthropic/claude-sonnet-4-20250514
5
+ temperature: 0.2
6
+ tools:
7
+ write: true
8
+ edit: true
9
+ bash: true
10
+ read: true
11
+ glob: true
12
+ grep: true
13
+ permission:
14
+ bash:
15
+ 'git *': ask
16
+ 'npm *': allow
17
+ 'npx *': allow
18
+ 'pnpm *': allow
19
+ 'yarn *': allow
20
+ 'cat *': allow
21
+ '*': ask
22
+ ---
@@ -0,0 +1,7 @@
1
+ # Observability Rules
2
+
3
+ These rules are intended for Codex (CLI and app).
4
+
5
+ These rules help add logging, tracing, metrics, and SLOs to TypeScript/JavaScript applications.
6
+
7
+ ---
package/dist/agents.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  declare const PACKAGE_ROOT: string;
2
- export declare const AGENT_IDS: readonly ["linting", "local-dev", "cicd", "observability"];
2
+ export declare const AGENT_IDS: readonly ["linting", "local-dev", "cicd", "observability", "logging"];
3
3
  export type AgentId = (typeof AGENT_IDS)[number];
4
4
  /**
5
5
  * Resolve path to an agent directory
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,YAAY,QAA6B,CAAC;AAEhD,eAAO,MAAM,SAAS,4DAKZ,CAAC;AACX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAQjE;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,YAAY,QAA6B,CAAC;AAEhD,eAAO,MAAM,SAAS,uEAMZ,CAAC;AACX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAQjE;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/dist/agents.js CHANGED
@@ -15,7 +15,8 @@ exports.AGENT_IDS = [
15
15
  'linting',
16
16
  'local-dev',
17
17
  'cicd',
18
- 'observability'
18
+ 'observability',
19
+ 'logging'
19
20
  ];
20
21
  /**
21
22
  * Resolve path to an agent directory
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":";;;;;;AAeA,kCAEC;AAKD,gCAEC;AAKD,oCAEC;AAKD,sCAQC;AA5CD,gDAAwB;AAExB,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AA4CvC,oCAAY;AA1CR,QAAA,SAAS,GAAG;IACvB,SAAS;IACT,WAAW;IACX,MAAM;IACN,eAAe;CACP,CAAC;AAGX;;GAEG;AACH,SAAgB,WAAW,CAAC,OAAe;IACzC,OAAO,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU;IACxB,OAAO,iBAAS,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,OAAe;IAC1C,OAAQ,iBAA+B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,MAAyB;IACrD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM;YAAE,OAAO,iBAAS,CAAC,KAAK,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,iBAAS,CAAC,KAAK,EAAE,CAAC;IAC/C,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":";;;;;;AAgBA,kCAEC;AAKD,gCAEC;AAKD,oCAEC;AAKD,sCAQC;AA7CD,gDAAwB;AAExB,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AA6CvC,oCAAY;AA3CR,QAAA,SAAS,GAAG;IACvB,SAAS;IACT,WAAW;IACX,MAAM;IACN,eAAe;IACf,SAAS;CACD,CAAC;AAGX;;GAEG;AACH,SAAgB,WAAW,CAAC,OAAe;IACzC,OAAO,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU;IACxB,OAAO,iBAAS,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,OAAe;IAC1C,OAAQ,iBAA+B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,MAAyB;IACrD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM;YAAE,OAAO,iBAAS,CAAC,KAAK,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,iBAAS,CAAC,KAAK,EAAE,CAAC;IAC/C,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9C,CAAC"}
package/dist/build.d.ts CHANGED
@@ -1,35 +1,51 @@
1
1
  import type { Target } from './config';
2
2
  /**
3
- * Read agent content.md
3
+ * List rule suffixes for an agent. content.md → suffix ''; content-<suffix>.md → suffix.
4
+ * At least one of content.md or content-*.md must exist.
4
5
  */
5
- export declare function getContent(agentId: string): string;
6
+ export declare function listRuleSuffixes(agentId: string): string[];
6
7
  /**
7
- * Read agent template file
8
+ * Read agent content for a rule. ruleSuffix '' or undefined = content.md; else content-<suffix>.md.
8
9
  */
9
- export declare function getTemplate(agentId: string, filename: string): string;
10
+ export declare function getContent(agentId: string, ruleSuffix?: string): string;
11
+ /**
12
+ * Read agent template file. Tries rule-specific template first (e.g. cursor-frontmatter-mcp.yaml).
13
+ */
14
+ export declare function getTemplate(agentId: string, filename: string, ruleSuffix?: string): string;
10
15
  /**
11
16
  * Build content for Cursor (.mdc = frontmatter + content)
12
17
  */
13
- export declare function buildCursorFormat(agentId: string): string;
18
+ export declare function buildCursorFormat(agentId: string, ruleSuffix?: string): string;
14
19
  /**
15
20
  * Build content for Claude (header + content)
16
21
  */
17
- export declare function buildClaudeFormat(agentId: string): string;
22
+ export declare function buildClaudeFormat(agentId: string, ruleSuffix?: string): string;
18
23
  /**
19
24
  * Build content for OpenCode (YAML frontmatter + content)
20
25
  */
21
- export declare function buildOpenCodeFormat(agentId: string): string;
26
+ export declare function buildOpenCodeFormat(agentId: string, ruleSuffix?: string): string;
27
+ /**
28
+ * Build content for Codex (header + content)
29
+ */
30
+ export declare function buildCodexFormat(agentId: string, ruleSuffix?: string): string;
31
+ export declare function extractDescriptionFromFrontmatter(frontmatter: string): string | null;
32
+ export declare function getCodexRuleDescription(agentId: string, ruleSuffix?: string): string | null;
33
+ export declare function buildCodexAgentsMd(agents: string[]): string;
22
34
  /**
23
- * Build content for the given agent and target
35
+ * Build content for the given agent, target, and optional rule suffix
24
36
  */
25
- export declare function buildContent(agentId: string, target: Target): string;
37
+ export declare function buildContent(agentId: string, target: Target, ruleSuffix?: string): string;
26
38
  /**
27
- * Get destination path for installed agent file
39
+ * Get destination path for installed agent file. ruleSuffix '' or undefined = main rule; else <agentId>-<suffix>.
28
40
  */
29
- export declare function getDestination(agentId: string, target: Target, projectRoot: string): {
41
+ export declare function getDestination(agentId: string, target: Target, projectRoot: string, ruleSuffix?: string): {
30
42
  dir: string;
31
43
  file: string;
32
44
  };
45
+ /**
46
+ * Get destination for Codex AGENTS.md
47
+ */
48
+ export declare function getCodexAgentsMdPath(projectRoot: string): string;
33
49
  /**
34
50
  * List supported targets
35
51
  */
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIvC;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAWpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAqB/B;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAEtC"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAQvC;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAyB1D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAUvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAeR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAQR;AAuBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CAWf;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAyB3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAaR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA2B/B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAEtC"}