Skip to content

feat: portable AGENTS.md output (--agents, --all) + non-interactive --yes#2

Merged
Kabi10 merged 3 commits into
mainfrom
feat/agents-md
Jul 1, 2026
Merged

feat: portable AGENTS.md output (--agents, --all) + non-interactive --yes#2
Kabi10 merged 3 commits into
mainfrom
feat/agents-md

Conversation

@Kabi10

@Kabi10 Kabi10 commented Jun 27, 2026

Copy link
Copy Markdown
Owner

What

Adds portable AGENTS.md output so one source produces rules for Cursor, GitHub Copilot, Codex, and Claude Code — alongside the existing .cursor/rules/*.mdc and .cursorrules. Also adds a non-interactive mode for scripting/CI and the project's first CI workflow.

Flags

Flag Output
(default) per-module .cursor/rules/*.mdc (unchanged)
--agents AGENTS.md at repo root (portable, cross-tool)
--all both .mdc and AGENTS.md, one pass
--legacy .cursorrules (unchanged)
--yes, -y non-interactive: use detected modules, no prompts
-h, --help usage

--agents, --legacy, --all are mutually exclusive (clear error otherwise).

Design notes

  • AGENTS.md is plain markdown — deliberately not the Cursor .mdc YAML frontmatter (globs/alwaysApply are Cursor-specific). Module # Titles are demoted to ## so the file has a single H1.
  • Managed-block markers (<!-- cursor-compose:start/end -->): regenerating only replaces the managed block, so hand-edits outside it are preserved. A pre-existing AGENTS.md without markers is appended to (or, interactively, overwrite/cancel) — never silently clobbered.
  • Size guard: warns when the always-on AGENTS.md exceeds ~2000 estimated tokens.

Tests / CI

  • New tests/agents.test.js: create, regenerate-preserves-user-content, foreign-file handling, and a plain-markdown assertion (no globs:/alwaysApply:). Suite now 21 tests, all passing.
  • Fixed the npm test glob to tests/*.test.js so it runs without bash globstar (the old ** matched nothing under GitHub Actions' default shell).
  • Added GitHub Actions CI: test matrix on Node 18/20/22 + a non-interactive --yes smoke test that asserts both outputs and that no frontmatter leaks into AGENTS.md.

Docs / meta

  • README: AGENTS.md moved from roadmap to a documented feature; full flag matrix; managed-block explanation.
  • package.json: bumped to 1.2.0, broadened description + keywords (agents-md, claude, copilot, codex, …). Not published to npm — version bump only.

Verification

npm test green (21/21). Manual smoke in a sample Next.js project confirmed: --all --yes writes 3 .mdc + AGENTS.md; regeneration preserves a hand-added section; --help and mutual-exclusion error behave as expected.

Summary by CodeRabbit

  • New Features
    • Added support for generating/updating a root AGENTS.md with safe managed sections.
    • Introduced new CLI modes for AGENTS.md, legacy rules, or both, including non-interactive --yes.
    • Updated README with revised usage, output locations, and detection documentation.
  • Bug Fixes
    • Regenerations preserve any user-authored content outside the managed AGENTS.md block.
    • Ensures generated AGENTS.md is plain markdown (no unwanted frontmatter).
  • Tests / CI
    • Added CI workflow and expanded test coverage, including CLI non-interactive smoke/regression checks.
  • Docs
    • Added a scripted demo tape and included an MIT LICENSE.

…ve --yes

- compose.js: buildAgentsBlock/writeRulesAgentsMd emit AGENTS.md as plain
  markdown (Cursor, Copilot, Codex, Claude Code) with a single H1; module
  headings demoted to ##. Managed-block markers preserve hand-edited content
  on regeneration; foreign files are appended to, not clobbered.
- cli.js: --agents, --all, --yes/-y, -h/--help, mutual-exclusion check, and an
  always-on token size warning (>~2000 tokens).
- tests/agents.test.js: create / regen-preserves-user-content / foreign-file /
  plain-markdown (no globs/alwaysApply) coverage.
- package.json: fix test glob to tests/*.test.js (CI needs no bash globstar),
  bump to 1.2.0, broaden description + keywords (agents-md, claude, copilot...).
- CI: GitHub Actions test matrix (Node 18/20/22) + non-interactive smoke test.
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds managed AGENTS.md generation alongside .mdc rules, expands the CLI with --agents, --all, --legacy, and --yes, updates docs and package metadata, and adds tests plus CI coverage for the new flow.

Changes

Managed AGENTS.md workflow

Layer / File(s) Summary
Managed block primitives
src/compose.js
Adds managed markers, heading demotion, managed-block detection, and the functions that build and write the root AGENTS.md block.
CLI modes and selection
src/cli.js
Adds CLI help, mode parsing, module selection, token warning handling, and branching for the new output modes.
Docs and package metadata
README.md, package.json, LICENSE, docs/demo.tape
Updates the README usage, managed-block guidance, detection table, module overview, package metadata, license text, and demo script.
Tests and CI
tests/agents.test.js, tests/fixes.test.js, .github/workflows/ci.yml
Adds tests for managed creation, regeneration, foreign-file handling, CLI regressions, and a CI workflow with matrix tests and a smoke run.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant src_cli_js as src/cli.js
  participant src_compose_js as src/compose.js
  participant modules as modules
  participant AGENTS_md as AGENTS.md

  User->>src_cli_js: run --agents or --all
  src_cli_js->>src_compose_js: writeRulesAgentsMd(moduleIds, cwd, opts)
  src_compose_js->>modules: read selected module markdown
  src_compose_js->>AGENTS_md: create, replace, or append managed block
  src_compose_js-->>src_cli_js: write result and status
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the main change: new AGENTS.md output modes and non-interactive --yes support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/agents-md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kilo-code-bot

kilo-code-bot Bot commented Jun 27, 2026

Copy link
Copy Markdown

Kilo Code Review could not run — your account is out of credits.

Add credits or switch to a free model to enable reviews on this change.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for generating a portable AGENTS.md file compatible with multiple AI editors, adding new CLI flags (--agents, --all, --yes), token estimation warnings, and safe block-based updates. The review feedback highlights critical improvements: skipping interactive prompts entirely in non-interactive mode (--yes) to prevent CI hangs, validating both start and end markers in AGENTS.md to avoid silent data loss, and demoting all markdown heading levels incrementally to preserve document hierarchy.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/cli.js
return tokens;
};

// --legacy: single .cursorrules file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

In non-interactive mode (--yes / -y), the CLI should not prompt the user. Currently, if --legacy and --yes are both used and .cursorrules already exists, the tool will still prompt the user to overwrite, causing scripts or CI pipelines to hang indefinitely.

Please update the check on line 134 to skip the prompt when isYes is true:

if (existsSync(outFile) && !isYes) {

Note: The same issue exists for the default mode prompt on line 191 (if (existingMdc.length > 0) {), which is outside the current diff hunks. Please also update that line to skip the prompt when isYes is true:

if (existingMdc.length > 0 && !isYes) {

Comment thread src/cli.js Outdated
async function resolveForeignDecision(isYes) {
const p = join(process.cwd(), 'AGENTS.md');
if (!existsSync(p)) return () => 'append';
if (readFileSync(p, 'utf8').includes(AGENTS_START)) return () => 'append';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If AGENTS.md contains AGENTS_START but is missing AGENTS_END (or they are out of order), the file is malformed. Currently, resolveForeignDecision only checks for the presence of AGENTS_START, which means it will bypass the prompt and return 'append'. On the next run, writeRulesAgentsMd will find the first AGENTS_START and the newly appended AGENTS_END, and replace everything in between—silently deleting any user content that was added between them.

We should ensure both markers are present and valid before bypassing the prompt.

  const content = readFileSync(p, 'utf8');
  const startIdx = content.indexOf(AGENTS_START);
  const endIdx = content.indexOf(AGENTS_END);
  const hasValidMarkers = startIdx !== -1 && endIdx !== -1 && endIdx > startIdx;
  if (hasValidMarkers) return () => 'append';

Comment thread src/cli.js Outdated
Comment on lines +13 to +14
AGENTS_START,
} from './compose.js';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

We need to import AGENTS_END from ./compose.js to use it in resolveForeignDecision for validating the presence of both markers.

Suggested change
AGENTS_START,
} from './compose.js';
AGENTS_START,
AGENTS_END,
} from './compose.js';

Comment thread src/compose.js Outdated
Comment on lines +111 to +112
// Demote module headings so AGENTS.md has a single top-level H1.
return content.replace(/^# /gm, '## ');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Currently, only top-level # headings are demoted to ##. This breaks the heading hierarchy within the module (e.g., any existing ## sub-headings in the module file will now be at the same level as the demoted top-level heading, becoming sibling headings instead of child headings).

We should demote all headings by shifting their levels down by one (e.g., # -> ##, ## -> ###, etc.) using a regex that matches any heading level followed by a space.

Suggested change
// Demote module headings so AGENTS.md has a single top-level H1.
return content.replace(/^# /gm, '## ');
// Demote all module headings by one level to preserve document hierarchy.
return content.replace(/^(#+)(?=\s)/gm, '#$1');

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (2)
package.json (1)

3-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add engines field to enforce Node 18+ at install time.

The README and CLI both require Node 18+, but package.json lacks an engines field. Adding "engines": { "node": ">=18" } would let npm warn users before runtime.

"engines": {
  "node": ">=18"
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 3 - 4, Add an engines constraint to package.json
so installs warn early for unsupported runtimes. Update the package metadata to
include an engines field with Node set to >=18, keeping it alongside the
existing version/description entries so the CLI and README’s Node 18+
requirement is enforced at install time.
README.md (1)

99-121: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add language specifier to the src/ tree code block.

Line 112's fenced code block has no language tag, triggering markdownlint MD040. Add text after the opening backticks.

- ```
+ ```text
  src/
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 99 - 121, The fenced code block under the “How it
works” section is missing a language specifier and triggers markdownlint MD040.
Update that `src/` tree block to use a `text` fence so the Markdown is
explicitly typed. Locate the block near the “How it works” heading and adjust
the opening backticks accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 17-20: The workflow uses mutable action tags for actions/checkout
and actions/setup-node, so update both jobs to pin these third-party actions to
immutable full commit SHAs instead of `@v4`. Keep the existing steps in the ci
workflow, but replace the version tags for checkout and setup-node everywhere
they appear so the job definitions are locked to specific revisions.
- Around line 1-8: Add an explicit workflow-level least-privilege permissions
block in the CI workflow so the default GITHUB_TOKEN does not get broader access
than needed. Update the workflow definition near the existing
on/push/pull_request configuration to include a permissions setting that limits
the job to read-only repository contents, and keep the change scoped at the
workflow level since the jobs only need to check out code and run local
commands.
- Line 17: Update both actions/checkout usages in the CI workflow to disable
token persistence by setting persist-credentials to false. The issue affects
each checkout step in the workflow, so adjust both invocations consistently to
avoid storing repo credentials in the local git config when the jobs only read
code.

In `@src/cli.js`:
- Line 44: The --yes flag in src/cli.js only skips module selection today, but
it still allows later prompts in the legacy .cursorrules flow and the default
.cursor/rules/ flow. Update the prompt guards around the relevant CLI branches
so that the --yes/non-interactive path bypasses every confirmation, including
the legacy .cursorrules prompt and the .cursor/rules/ overwrite/selection
prompt. Use the existing CLI flag handling and prompt sites in the main command
flow to ensure --legacy --yes and plain --yes both run fully non-interactively.
- Around line 172-180: In the `isAll` flow inside `src/cli.js`, the AGENTS
foreign-file decision is resolved after `writeRulesMdc(selected)`, which can
leave `.cursor/rules` modified even when the user cancels. Move the
`resolveForeignDecision(isYes)` / `writeRulesAgentsMd(...)` decision ahead of
`writeRulesMdc(selected)`, and only proceed to write any `.mdc` files when the
AGENTS action is not cancelled; keep the existing `actionVerb`,
`writeRulesAgentsMd`, and `writeRulesMdc` behavior otherwise unchanged.
- Around line 220-224: resolveForeignDecision currently suppresses the prompt
based only on AGENTS_START, so a partial or stray marker can be misclassified as
a managed block. Update the AGENTS.md check in resolveForeignDecision to verify
a complete managed block by requiring both the start and end markers before
returning append, and keep the existing isYes fallback behavior unchanged.

In `@src/compose.js`:
- Around line 149-152: The managed-block lookup in compose.js should find the
end marker only after the start marker, not by searching the whole file first.
Update the existing.indexOf logic in the block that uses AGENTS_START and
AGENTS_END so the AGENTS_END search begins after startIdx, and keep the existing
update path in compose.js from misclassifying content when user text contains
the end marker string.

---

Nitpick comments:
In `@package.json`:
- Around line 3-4: Add an engines constraint to package.json so installs warn
early for unsupported runtimes. Update the package metadata to include an
engines field with Node set to >=18, keeping it alongside the existing
version/description entries so the CLI and README’s Node 18+ requirement is
enforced at install time.

In `@README.md`:
- Around line 99-121: The fenced code block under the “How it works” section is
missing a language specifier and triggers markdownlint MD040. Update that `src/`
tree block to use a `text` fence so the Markdown is explicitly typed. Locate the
block near the “How it works” heading and adjust the opening backticks
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 780882e4-70d9-47f1-b31a-c0c3c867dbe3

📥 Commits

Reviewing files that changed from the base of the PR and between 3ccc3be and 41a25b0.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • README.md
  • package.json
  • src/cli.js
  • src/compose.js
  • tests/agents.test.js

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread src/cli.js
Comment thread src/cli.js
Comment thread src/cli.js
Comment thread src/compose.js Outdated
Kabi10 and others added 2 commits June 27, 2026 07:46
…ning

Addresses the review findings on this PR (Gemini / CodeRabbit / Kilo):

- --yes now skips every prompt. --legacy --yes and the default mode no
  longer block on the overwrite prompt, so non-interactive/CI runs can't
  hang (the flag's whole purpose).
- --all resolves the AGENTS.md decision and writes it first, so cancelling
  aborts before any .mdc files are written (no half-done state).
- AGENTS.md updates require a valid, ordered start/end marker pair
  (findManagedBlock); an orphaned start marker is treated as a foreign file
  instead of being silently corrupted, and the end marker is matched after
  the start.
- Heading demotion is incremental (h1->h2 ... capped at h6) and skips fenced
  code blocks (demoteHeadings), preserving each module's hierarchy.

Hardening & hygiene:
- CI: least-privilege permissions, persist-credentials:false, actions pinned
  to commit SHAs.
- Add MIT LICENSE (package.json already declares MIT).
- tests/fixes.test.js: 10 regression tests incl. CLI subprocess checks that
  fail if --yes ever blocks on a prompt. Suite now 31/31 green.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
docs/demo.tape (1)

12-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hardcoded absolute path limits portability.

/workspaces/cursor-rules/src/cli.js only resolves inside a specific devcontainer layout; regenerating the demo elsewhere will break this shell override.

♻️ Suggested fix using a relative path
-Type 'npx() { shift; node /workspaces/cursor-rules/src/cli.js "$@"; }'
+Type 'npx() { shift; node "$(pwd)/../../src/cli.js" "$@"; }'
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/demo.tape` at line 12, The npx shell override in the demo uses a
hardcoded absolute path, which makes the example non-portable. Update the
override in the demo script to invoke the CLI through a relative path from the
repository root instead of `/workspaces/cursor-rules/src/cli.js`, so the `npx()`
wrapper continues to work regardless of the local checkout location.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@docs/demo.tape`:
- Line 12: The npx shell override in the demo uses a hardcoded absolute path,
which makes the example non-portable. Update the override in the demo script to
invoke the CLI through a relative path from the repository root instead of
`/workspaces/cursor-rules/src/cli.js`, so the `npx()` wrapper continues to work
regardless of the local checkout location.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dbc41c6b-4ca4-4149-9ef0-1dd3abebfd33

📥 Commits

Reviewing files that changed from the base of the PR and between 41a25b0 and d93ebb5.

⛔ Files ignored due to path filters (1)
  • docs/demo.gif is excluded by !**/*.gif
📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • LICENSE
  • docs/demo.tape
  • src/cli.js
  • src/compose.js
  • tests/fixes.test.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/ci.yml
  • src/compose.js
  • src/cli.js

@Kabi10 Kabi10 merged commit a1a642e into main Jul 1, 2026
6 of 7 checks passed
@Kabi10 Kabi10 deleted the feat/agents-md branch July 1, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant