agentsmd-medic 0.0.0-stage → 0.1.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 (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +305 -2
  3. package/bin/agentsmd-medic.js +12 -0
  4. package/dist/agents.d.ts +36 -0
  5. package/dist/agents.js +67 -0
  6. package/dist/agents.js.map +1 -0
  7. package/dist/cli.d.ts +16 -0
  8. package/dist/cli.js +248 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +12 -0
  11. package/dist/config.js +77 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/discover.d.ts +14 -0
  14. package/dist/discover.js +84 -0
  15. package/dist/discover.js.map +1 -0
  16. package/dist/doctor.d.ts +53 -0
  17. package/dist/doctor.js +486 -0
  18. package/dist/doctor.js.map +1 -0
  19. package/dist/format.d.ts +17 -0
  20. package/dist/format.js +113 -0
  21. package/dist/format.js.map +1 -0
  22. package/dist/index.d.ts +11 -0
  23. package/dist/index.js +10 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/linter.d.ts +23 -0
  26. package/dist/linter.js +201 -0
  27. package/dist/linter.js.map +1 -0
  28. package/dist/markdown.d.ts +9 -0
  29. package/dist/markdown.js +88 -0
  30. package/dist/markdown.js.map +1 -0
  31. package/dist/rules/index.d.ts +3 -0
  32. package/dist/rules/index.js +21 -0
  33. package/dist/rules/index.js.map +1 -0
  34. package/dist/rules/links.d.ts +2 -0
  35. package/dist/rules/links.js +70 -0
  36. package/dist/rules/links.js.map +1 -0
  37. package/dist/rules/package-managers.d.ts +2 -0
  38. package/dist/rules/package-managers.js +76 -0
  39. package/dist/rules/package-managers.js.map +1 -0
  40. package/dist/rules/paths.d.ts +2 -0
  41. package/dist/rules/paths.js +86 -0
  42. package/dist/rules/paths.js.map +1 -0
  43. package/dist/rules/scripts.d.ts +2 -0
  44. package/dist/rules/scripts.js +249 -0
  45. package/dist/rules/scripts.js.map +1 -0
  46. package/dist/rules/secrets.d.ts +2 -0
  47. package/dist/rules/secrets.js +100 -0
  48. package/dist/rules/secrets.js.map +1 -0
  49. package/dist/rules/structure.d.ts +18 -0
  50. package/dist/rules/structure.js +151 -0
  51. package/dist/rules/structure.js.map +1 -0
  52. package/dist/rules/util.d.ts +16 -0
  53. package/dist/rules/util.js +63 -0
  54. package/dist/rules/util.js.map +1 -0
  55. package/dist/types.d.ts +80 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +67 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 weugit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,306 @@
1
- # Temporary Holding Version
1
+ # agentsmd-medic
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Lint [AGENTS.md](https://agents.md) files: the instruction files AI coding agents read from a repository.
4
+
5
+ [![CI](https://github.com/weugit/agentsmd-medic/actions/workflows/ci.yml/badge.svg)](https://github.com/weugit/agentsmd-medic/actions/workflows/ci.yml)
6
+ [![npm version](https://img.shields.io/npm/v/agentsmd-medic)](https://www.npmjs.com/package/agentsmd-medic)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+
9
+ agentsmd-medic checks those instructions before an agent follows them. It flags empty files, broken links, paths and commands that are not in the repo, mixed package managers, unfinished placeholders, and credential-shaped strings. It is a TypeScript ESM CLI with no runtime dependencies.
10
+
11
+ The npm package is not published yet. See [Install](#install).
12
+
13
+ ## Why
14
+
15
+ [AGENTS.md](https://agents.md) is the open format read by OpenAI Codex, Cursor, GitHub Copilot, and others. Codex merges `AGENTS.md` files from the repository root down to the working directory. A closer file takes precedence. `AGENTS.override.md` overrides. Project docs are capped at 32 KiB by default via `project_doc_max_bytes`.
16
+
17
+ Stale paths, stale commands, leaked secrets, and contradictions do not fail the agent run. They silently degrade what the agent does. This linter checks the files on your machine and prints a report. It does not upload them.
18
+
19
+ ## Install
20
+
21
+ After the package is on npm:
22
+
23
+ ```bash
24
+ npx agentsmd-medic
25
+ npm install -D agentsmd-medic
26
+ ```
27
+
28
+ It is not published yet. Until then, clone the repository and run the built CLI:
29
+
30
+ ```bash
31
+ git clone https://github.com/weugit/agentsmd-medic.git
32
+ cd agentsmd-medic
33
+ npm ci && npm run build && node bin/agentsmd-medic.js
34
+ ```
35
+
36
+ Node.js 20 or newer is required.
37
+
38
+ ## Usage
39
+
40
+ ```text
41
+ agentsmd-medic [options] [path...]
42
+ ```
43
+
44
+ A path that is a file is linted directly. A path that is a directory is searched recursively for `AGENTS.md` and `AGENTS.override.md`. The default path is `.`.
45
+
46
+ ```text
47
+ agentsmd-medic doctor [options] [dir]
48
+ ```
49
+
50
+ `doctor` reports which instruction files each agent actually loads for `dir` (default: the working directory). It walks from that directory up to the git root: the nearest ancestor that contains `.git`, or `dir` itself when there is none. Home-directory files (`~/.codex`, `~/.claude`, and similar) are not scanned. The first positional argument `doctor` selects the subcommand. A path such as `./doctor` is still linted.
51
+
52
+ | Agent | What doctor reports |
53
+ | --- | --- |
54
+ | OpenAI Codex | For each directory from the git root down to `dir`, `AGENTS.override.md` if it is present, otherwise `AGENTS.md`. Files are concatenated from the root toward the leaf. The report notes the default 32 KiB cap (`project_doc_max_bytes`) and warns when the combined size exceeds it. |
55
+ | Claude Code | `CLAUDE.md` and `CLAUDE.local.md` on that path. Claude Code does not read `AGENTS.md` unless a `CLAUDE.md` imports it with an `@AGENTS.md`, `@./AGENTS.md`, or other relative `@` path. The report warns `AGENTS.md is ignored by Claude Code: no CLAUDE.md imports it` when `AGENTS.md` exists and no `CLAUDE.md` imports it, including when there is no `CLAUDE.md` at all. `CLAUDE.local.md` is called out as personal, git-ignored, and able to override shared instructions. |
56
+ | Cursor | `AGENTS.md` at the root and in nested directories, `.cursor/rules/*.mdc`, and legacy `.cursorrules` (deprecated). |
57
+ | GitHub Copilot | `.github/copilot-instructions.md`, `.github/instructions/*.instructions.md`, and `AGENTS.md`. |
58
+ | Gemini CLI | `GEMINI.md` by default. `AGENTS.md` only when `context.fileName` includes it. The report warns when only `AGENTS.md` exists. |
59
+
60
+ Text output is grouped per agent and uses `✔` and `⚠` markers. `--color` and `--no-color` apply the same way as for lint output. `--json` (or `--format json`) prints a versioned document (`version`, `command`, `directory`, `root`, and one entry per agent with `files`, `notes`, and `warnings`). `--format github` is a usage error. `doctor` exits 0 when the directory can be read, including when the report contains warnings. A missing path, a file path, or more than one directory exits 2.
61
+
62
+ Behaviors change as agents ship updates. The snapshot and the doc links live in `src/agents.ts`.
63
+
64
+ | Flag | Meaning |
65
+ | --- | --- |
66
+ | `-c, --config <file>` | Config file. When omitted, the working directory is searched for `.agentsmd-medic.json`, then `agentsmd-medic.config.json`. |
67
+ | `--format <format>` | `text` (default), `json`, or `github`. |
68
+ | `--json` | Alias for `--format json`. When both are set, the last one wins. |
69
+ | `--max-warnings <n>` | Exit 1 when the warning count is greater than `<n>`. `<n>` is an integer ≥ 0. Without this flag, warnings do not change the exit code. |
70
+ | `--color` | Force colored text output. |
71
+ | `--no-color` | Disable colored text output. |
72
+ | `-q, --quiet` | Hide warnings in text output. Hidden warnings are left out of the summary. They still count toward the exit code. |
73
+ | `--list-rules` | Print each rule id, its default severity, and its description, then exit. |
74
+ | `-h, --help` | Show help and exit. |
75
+ | `-v, --version` | Show the version number and exit. |
76
+
77
+ Color defaults to on when stdout is a TTY and `NO_COLOR` is unset. `--color` and `--no-color` override that, and the last one wins. Color applies to text output only.
78
+
79
+ `--format github` prints one [GitHub Actions workflow command](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions) per diagnostic (`::error` or `::warning` with `file`, `line`, `col`, and `title`). `--format json` prints a versioned document (`version`, `root`, counts, and per-file diagnostics) for editors and scripts.
80
+
81
+ ### Exit codes
82
+
83
+ | Code | Meaning |
84
+ | --- | --- |
85
+ | 0 | No errors, and warnings do not exceed `--max-warnings`. `doctor` exits 0 when the directory can be read, including when the report contains warnings. |
86
+ | 1 | One or more errors, or more warnings than `--max-warnings`. |
87
+ | 2 | Usage error, invalid config, or a path that does not exist. The message is written to stderr and prefixed with `agentsmd-medic: `. |
88
+
89
+ ## Example output
90
+
91
+ This report is the real output of `node bin/agentsmd-medic.js --no-color` in a temporary directory (exit code 1). The directory contained only the two files below.
92
+
93
+ `package.json`:
94
+
95
+ ```json
96
+ {
97
+ "name": "example",
98
+ "private": true,
99
+ "scripts": {
100
+ "test": "node --test"
101
+ }
102
+ }
103
+ ```
104
+
105
+ `AGENTS.md`:
106
+
107
+ ```md
108
+ # Project notes
109
+
110
+ Install dependencies with `npm run compile`, then start `pnpm dev`.
111
+
112
+ The schema is in `src/schema.ts`.
113
+
114
+ Read [the missing guide](docs/guide.md) and jump to [Setup](#setup).
115
+
116
+ ## Tasks
117
+
118
+ ## Tasks
119
+
120
+ TODO: describe the tasks.
121
+
122
+ api_key: "correcthorsebatterystaple"
123
+ ```
124
+
125
+ ```text
126
+ AGENTS.md
127
+ 3:28 warning Script `compile` is not defined in package.json. no-missing-scripts
128
+ 3:58 warning Instructions mix npm and pnpm; agents may run the wrong one. consistent-package-manager
129
+ 3:58 warning Script `dev` is not defined in package.json. no-missing-scripts
130
+ 5:19 warning Referenced path `src/schema.ts` does not exist no-missing-paths
131
+ 7:6 error Broken link: "docs/guide.md" (resolved to docs/guide.md) does not exist. no-broken-links
132
+ 7:53 error Anchor "#setup" does not match any heading in this file. no-broken-links
133
+ 9:1 warning Section "Tasks" is empty. no-empty-section
134
+ 11:1 warning Duplicate heading "Tasks" (first defined on line 9); merge the sections to avoid conflicting instructions. no-duplicate-heading
135
+ 13:1 warning Placeholder text "TODO" found; agents may follow it literally. no-placeholder
136
+ 15:1 error Possible API key found ("corr…"); remove it and rotate the credential. no-secrets
137
+
138
+ ✖ 10 problems (3 errors, 7 warnings)
139
+ ```
140
+
141
+ ## Rules
142
+
143
+ Default severities come from the rule objects in `src/rules/`. Override them in config with `error`, `warn`, or `off`.
144
+
145
+ | Rule | Default | Description |
146
+ | --- | --- | --- |
147
+ | `no-empty-file` | error | The file must contain some instructions. |
148
+ | `require-heading` | warn | Use at least one Markdown heading so agents (and humans) can navigate sections. |
149
+ | `max-size` | warn | Keep the file within the size agents actually read, using a CJK-aware token estimate. |
150
+ | `no-empty-section` | warn | Headings should be followed by content before the next heading of the same or higher level. |
151
+ | `no-duplicate-heading` | warn | Sibling sections should not share a heading; duplicated sections often carry conflicting instructions. |
152
+ | `no-placeholder` | warn | Flag unfinished placeholder text (TODO, TBD, lorem ipsum, &lt;insert ...&gt;). |
153
+ | `no-broken-links` | error | Relative links and in-page anchors must resolve. |
154
+ | `no-missing-paths` | warn | File paths in inline code should exist in the repository. |
155
+ | `no-missing-scripts` | warn | Package scripts and Make targets mentioned in commands should exist. |
156
+ | `no-secrets` | error | Instruction files must not embed credentials or secret tokens. |
157
+ | `consistent-package-manager` | warn | Commands should use one package manager, the one the repository locks. |
158
+
159
+ `no-broken-links` checks relative links and in-page anchors. External URLs are left alone. `no-missing-paths` checks inline code that looks like a repository path. `no-missing-scripts` checks `npm run` scripts (and `pnpm` / `yarn` / `bun` script invocations) against the nearest `package.json`, and `make` targets against a Makefile. `no-secrets` reports a short prefix of a match and asks you to rotate the credential. `max-size` compares UTF-8 bytes with `maxBytes` (default 32768) and a token estimate with `maxTokens` (default 8000). Each Han, Hiragana, Katakana, Hangul, and fullwidth character counts as one token. Other text counts as characters / 4. When those characters are more than 20% of the non-whitespace characters and the file exceeds `maxBytes`, the message notes that CJK text uses 3 bytes per character in UTF-8 and reaches the 32 KiB cap with ~11k characters.
160
+
161
+ Discovery always skips these directory names: `.git`, `node_modules`, `.hg`, `.svn`, `dist`, `build`, `coverage`, `.next`, `.turbo`, `vendor`, `.venv`, `venv`, `__pycache__`, and `target`.
162
+
163
+ ## Configuration
164
+
165
+ Put one of these files in the working directory. The first match wins:
166
+
167
+ 1. `.agentsmd-medic.json`
168
+ 2. `agentsmd-medic.config.json`
169
+
170
+ ```json
171
+ {
172
+ "rules": {
173
+ "no-secrets": "error",
174
+ "max-size": "warn",
175
+ "no-placeholder": "off"
176
+ },
177
+ "ignore": ["fixtures", "docs/drafts"],
178
+ "maxBytes": 32768,
179
+ "maxTokens": 8000
180
+ }
181
+ ```
182
+
183
+ | Field | Meaning |
184
+ | --- | --- |
185
+ | `rules` | Map of rule id to `error`, `warn`, or `off`. Unknown ids are a usage error (exit 2). |
186
+ | `ignore` | Directory names or path prefixes, relative to the lint root, to skip while searching. A value without a slash matches any path segment. A value with a slash matches that path or anything under it. |
187
+ | `maxBytes` | Soft size limit in bytes. Default `32768` (32 KiB). Must be a positive number. |
188
+ | `maxTokens` | Soft token budget. CJK and fullwidth characters count as one token; other text is characters / 4. Default `8000`. Must be a positive number. |
189
+
190
+ Pass `-c` / `--config` to use a different file. If that path cannot be read, the CLI exits 2.
191
+
192
+ ### Inline disable comments
193
+
194
+ In an `AGENTS.md` file:
195
+
196
+ ```text
197
+ <!-- agentsmd-medic-disable -->
198
+ <!-- agentsmd-medic-disable rule-a, rule-b -->
199
+ <!-- agentsmd-medic-disable-next-line -->
200
+ <!-- agentsmd-medic-disable-next-line rule-a, rule-b -->
201
+ ```
202
+
203
+ `agentsmd-medic-disable` disables every rule, or the named rules, for the whole file. `agentsmd-medic-disable-next-line` does the same for the next non-blank line. Comments inside fenced code blocks are not treated as directives, so an example in a fence does not silence a real finding.
204
+
205
+ ## Use in CI
206
+
207
+ The composite action in this repository checks out its own source, installs it, builds it, and lints the caller workspace. Pin `v0` after the first release. That tag is force-moved onto each 0.x release. Leaving `version` empty (the default) builds the action's checked-out source, so the action does not need the npm package.
208
+
209
+ ```yaml
210
+ name: AGENTS.md
211
+ on: [push, pull_request]
212
+ permissions:
213
+ contents: read
214
+ jobs:
215
+ agentsmd:
216
+ runs-on: ubuntu-latest
217
+ steps:
218
+ - uses: actions/checkout@v4
219
+ - uses: weugit/agentsmd-medic@v0
220
+ with:
221
+ path: .
222
+ # config: .agentsmd-medic.json
223
+ # max-warnings: "0" # -1, the default, does not fail on warnings
224
+ format: github
225
+ # version: "0.1.0" # empty builds the checked-out action source
226
+ ```
227
+
228
+ | Input | Default | Meaning |
229
+ | --- | --- | --- |
230
+ | `path` | `.` | File or directory to lint. |
231
+ | `config` | empty | Config file. Empty uses the default search. |
232
+ | `max-warnings` | `-1` | Fail when warnings exceed this integer. `-1` means unlimited. |
233
+ | `format` | `github` | `text`, `json`, or `github`. |
234
+ | `version` | empty | npm version to run. Empty builds the action source. |
235
+
236
+ The same check after the package is published, without the action:
237
+
238
+ ```yaml
239
+ - uses: actions/checkout@v4
240
+ - uses: actions/setup-node@v4
241
+ with:
242
+ node-version: 22
243
+ - run: npx agentsmd-medic --format github
244
+ ```
245
+
246
+ `npx agentsmd-medic` works only once the package is on npm. Until then, use the action with an empty `version`, or the clone-and-build install above.
247
+
248
+ ## Programmatic API
249
+
250
+ The package is ESM. Import it after `npm run build`, or from the published package once that exists. Types are in `dist/index.d.ts`.
251
+
252
+ ```js
253
+ import { formatText, lint } from "agentsmd-medic";
254
+
255
+ const result = await lint({ cwd: process.cwd(), paths: ["."] });
256
+ process.stdout.write(formatText(result, { color: false }));
257
+ if (result.errorCount > 0) process.exitCode = 1;
258
+ ```
259
+
260
+ | Export | Role |
261
+ | --- | --- |
262
+ | `lint({ cwd, paths?, configPath? })` | Load config, discover files, and return a `LintResult`. `configPath` is set on the result when a config file was read. Missing paths throw. Unknown rule ids throw `ConfigError`. |
263
+ | `lintFiles(files, root, config)` | Lint already-resolved files. |
264
+ | `lintText(source, { file, root, config })` | Lint one document from a string. Returns `Diagnostic[]`. |
265
+ | `formatText(result, { color?, quiet? })` | Text report. |
266
+ | `formatJson(result)` | JSON report (`version: 1`). |
267
+ | `formatGithub(result, cwd)` | GitHub Actions workflow commands. Paths are relative to `cwd`. |
268
+ | `loadConfig(root, explicitPath?)` | Returns `{ config, path? }`. |
269
+ | `DEFAULT_CONFIG` | `{ rules: {}, ignore: [], maxBytes: 32768, maxTokens: 8000 }`. |
270
+ | `CONFIG_FILE_NAMES` | `[".agentsmd-medic.json", "agentsmd-medic.config.json"]`. |
271
+ | `AGENT_FILE_NAMES` | `["AGENTS.md", "AGENTS.override.md"]`. |
272
+ | `findAgentFiles(root, ignore?)` | Recursive discovery. |
273
+ | `rules`, `ruleMap` | Built-in rules, in report order, and a map keyed by id. |
274
+ | `parseMarkdown(source)`, `slugify(text)` | The small Markdown scan the rules use. |
275
+ | `main(argv, io?)` | CLI entry. Resolves to exit code 0, 1, or 2. |
276
+ | `diagnose(dir, displayPath?)` | Build a doctor report for `dir`. |
277
+ | `formatDoctorText(report, { color? })` | Text doctor report. |
278
+ | `formatDoctorJson(report)` | JSON doctor report (`version: 1`, `command: "doctor"`). |
279
+ | `AGENTS` | Documented agent behaviors and documentation URLs. |
280
+ | `CODEX_PROJECT_DOC_MAX_BYTES` | Default Codex cap, `32768`. |
281
+ | `ConfigError` | Thrown for invalid config. |
282
+ | `DoctorUsageError` | Thrown when `doctor` is given a missing path or a file. |
283
+
284
+ Types exported from the package include `Severity`, `RuleSetting`, `Diagnostic`, `Config`, `Rule`, `RuleContext`, `LintResult`, and `FileResult`.
285
+
286
+ ## Roadmap
287
+
288
+ `agentsmd-medic doctor` reports which instruction files Codex, Claude Code, Cursor, GitHub Copilot, and Gemini CLI load, including nested `AGENTS.md` files and `AGENTS.override.md`. See [Usage](#usage).
289
+
290
+ Not implemented yet:
291
+
292
+ - Autofix.
293
+ - SARIF output.
294
+ - A pre-commit hook.
295
+ - Editor integration.
296
+ - Semantic conflict detection (instructions that disagree, beyond duplicate headings and mixed package managers).
297
+
298
+ ## Contributing
299
+
300
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, scripts, and how to add a rule. The code of conduct is [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). Security reports go through [private advisories](https://github.com/weugit/agentsmd-medic/security/advisories/new) ([SECURITY.md](SECURITY.md)).
301
+
302
+ This repository's own [AGENTS.md](AGENTS.md) is linted in CI. `README.md` and `CONTRIBUTING.md` are not.
303
+
304
+ ## License
305
+
306
+ [MIT](LICENSE). Copyright (c) 2026 weugit.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "../dist/cli.js";
3
+
4
+ main(process.argv.slice(2)).then(
5
+ (code) => {
6
+ process.exitCode = code;
7
+ },
8
+ (err) => {
9
+ console.error(err instanceof Error ? err.message : err);
10
+ process.exitCode = 2;
11
+ },
12
+ );
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Documented instruction-file behavior for coding agents.
3
+ *
4
+ * These behaviors change as agents ship updates. Treat this module as a snapshot
5
+ * of the public docs, not a guarantee of what a future release reads. Check the
6
+ * linked page when a doctor report looks wrong. Doctor does not read home-directory
7
+ * files (`~/.codex`, `~/.claude`, `~/.gemini`, and similar).
8
+ *
9
+ * - OpenAI Codex: https://developers.openai.com/codex/guides/agents-md
10
+ * - Claude Code: https://code.claude.com/docs/en/memory
11
+ * - Cursor: https://cursor.com/docs/rules
12
+ * - GitHub Copilot: https://docs.github.com/en/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot
13
+ * - Gemini CLI: https://geminicli.com/docs/cli/gemini-md
14
+ */
15
+ /** Default `project_doc_max_bytes`. Codex stops adding project docs at this size. */
16
+ export declare const CODEX_PROJECT_DOC_MAX_BYTES: number;
17
+ /** Printed when AGENTS.md is present and no CLAUDE.md imports it. */
18
+ export declare const CLAUDE_AGENTS_IGNORED = "AGENTS.md is ignored by Claude Code: no CLAUDE.md imports it";
19
+ /** Printed when CLAUDE.local.md is on the path from the repo root to the directory. */
20
+ export declare const CLAUDE_LOCAL_WARNING = "CLAUDE.local.md exists (personal, git-ignored, may override shared instructions).";
21
+ /** Printed when a legacy .cursorrules file is present. */
22
+ export declare const CURSOR_LEGACY_WARNING = "Legacy .cursorrules is deprecated. Cursor recommends .cursor/rules/*.mdc instead.";
23
+ /**
24
+ * Printed when the directory has AGENTS.md and Gemini would not load it.
25
+ * Gemini reads GEMINI.md unless `context.fileName` says otherwise.
26
+ */
27
+ export declare const GEMINI_ONLY_AGENTS_WARNING = "Gemini CLI reads GEMINI.md by default and loads AGENTS.md only when context.fileName includes it. Only AGENTS.md exists here.";
28
+ export interface AgentInfo {
29
+ id: "codex" | "claude" | "cursor" | "copilot" | "gemini";
30
+ name: string;
31
+ docsUrl: string;
32
+ /** What doctor checks, in one sentence. */
33
+ loads: string;
34
+ }
35
+ export declare const AGENTS: readonly AgentInfo[];
36
+ export declare function agentInfo(id: AgentInfo["id"]): AgentInfo;
package/dist/agents.js ADDED
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Documented instruction-file behavior for coding agents.
3
+ *
4
+ * These behaviors change as agents ship updates. Treat this module as a snapshot
5
+ * of the public docs, not a guarantee of what a future release reads. Check the
6
+ * linked page when a doctor report looks wrong. Doctor does not read home-directory
7
+ * files (`~/.codex`, `~/.claude`, `~/.gemini`, and similar).
8
+ *
9
+ * - OpenAI Codex: https://developers.openai.com/codex/guides/agents-md
10
+ * - Claude Code: https://code.claude.com/docs/en/memory
11
+ * - Cursor: https://cursor.com/docs/rules
12
+ * - GitHub Copilot: https://docs.github.com/en/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot
13
+ * - Gemini CLI: https://geminicli.com/docs/cli/gemini-md
14
+ */
15
+ /** Default `project_doc_max_bytes`. Codex stops adding project docs at this size. */
16
+ export const CODEX_PROJECT_DOC_MAX_BYTES = 32 * 1024;
17
+ /** Printed when AGENTS.md is present and no CLAUDE.md imports it. */
18
+ export const CLAUDE_AGENTS_IGNORED = "AGENTS.md is ignored by Claude Code: no CLAUDE.md imports it";
19
+ /** Printed when CLAUDE.local.md is on the path from the repo root to the directory. */
20
+ export const CLAUDE_LOCAL_WARNING = "CLAUDE.local.md exists (personal, git-ignored, may override shared instructions).";
21
+ /** Printed when a legacy .cursorrules file is present. */
22
+ export const CURSOR_LEGACY_WARNING = "Legacy .cursorrules is deprecated. Cursor recommends .cursor/rules/*.mdc instead.";
23
+ /**
24
+ * Printed when the directory has AGENTS.md and Gemini would not load it.
25
+ * Gemini reads GEMINI.md unless `context.fileName` says otherwise.
26
+ */
27
+ export const GEMINI_ONLY_AGENTS_WARNING = "Gemini CLI reads GEMINI.md by default and loads AGENTS.md only when context.fileName includes it. Only AGENTS.md exists here.";
28
+ export const AGENTS = [
29
+ {
30
+ id: "codex",
31
+ name: "OpenAI Codex",
32
+ docsUrl: "https://developers.openai.com/codex/guides/agents-md",
33
+ loads: "From the git root down to the directory, AGENTS.override.md if that directory has one, otherwise AGENTS.md. Files are concatenated from the root toward the leaf and capped by project_doc_max_bytes (32 KiB by default).",
34
+ },
35
+ {
36
+ id: "claude",
37
+ name: "Claude Code",
38
+ docsUrl: "https://code.claude.com/docs/en/memory",
39
+ loads: "CLAUDE.md and CLAUDE.local.md on the path from the git root to the directory. AGENTS.md is included only when a CLAUDE.md line imports it (@AGENTS.md, @./AGENTS.md, or another relative path to AGENTS.md).",
40
+ },
41
+ {
42
+ id: "cursor",
43
+ name: "Cursor",
44
+ docsUrl: "https://cursor.com/docs/rules",
45
+ loads: "AGENTS.md at the repo root and in nested directories, .cursor/rules/*.mdc files, and legacy .cursorrules (deprecated).",
46
+ },
47
+ {
48
+ id: "copilot",
49
+ name: "GitHub Copilot",
50
+ docsUrl: "https://docs.github.com/en/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot",
51
+ loads: ".github/copilot-instructions.md, .github/instructions/*.instructions.md, and AGENTS.md.",
52
+ },
53
+ {
54
+ id: "gemini",
55
+ name: "Gemini CLI",
56
+ docsUrl: "https://geminicli.com/docs/cli/gemini-md",
57
+ loads: "GEMINI.md by default. AGENTS.md only when settings set context.fileName to include it.",
58
+ },
59
+ ];
60
+ const AGENT_BY_ID = new Map(AGENTS.map((agent) => [agent.id, agent]));
61
+ export function agentInfo(id) {
62
+ const info = AGENT_BY_ID.get(id);
63
+ if (!info)
64
+ throw new Error(`Unknown agent: ${id}`);
65
+ return info;
66
+ }
67
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qFAAqF;AACrF,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,IAAI,CAAC;AAErD,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,8DAA8D,CAAC;AAEpG,uFAAuF;AACvF,MAAM,CAAC,MAAM,oBAAoB,GAAG,mFAAmF,CAAC;AAExH,0DAA0D;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG,mFAAmF,CAAC;AAEzH;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GACrC,+HAA+H,CAAC;AAUlI,MAAM,CAAC,MAAM,MAAM,GAAyB;IAC1C;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,sDAAsD;QAC/D,KAAK,EACH,2NAA2N;KAC9N;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,wCAAwC;QACjD,KAAK,EACH,8MAA8M;KACjN;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,+BAA+B;QACxC,KAAK,EAAE,wHAAwH;KAChI;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,sGAAsG;QAC/G,KAAK,EAAE,yFAAyF;KACjG;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,0CAA0C;QACnD,KAAK,EAAE,wFAAwF;KAChG;CACF,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAEtE,MAAM,UAAU,SAAS,CAAC,EAAmB;IAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ interface Io {
2
+ stdout: {
3
+ write(s: string): unknown;
4
+ isTTY?: boolean;
5
+ };
6
+ stderr: {
7
+ write(s: string): unknown;
8
+ };
9
+ cwd: string;
10
+ env?: Record<string, string | undefined>;
11
+ }
12
+ /**
13
+ * Run the CLI. Returns a process exit code: 0 ok, 1 findings, 2 usage or config error.
14
+ */
15
+ export declare function main(argv: string[], io?: Io): Promise<number>;
16
+ export {};