@jqntn/agentdoctor 0.1.2 → 0.1.3
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/LICENSE +1 -1
- package/README.md +28 -16
- package/docs/agents.md +14 -9
- package/docs/getting-started.md +2 -2
- package/docs/privacy.md +60 -0
- package/docs/rules.md +2 -1
- package/package.json +2 -2
- package/plugin/.claude-plugin/plugin.json +21 -0
- package/plugin/README.md +10 -0
- package/{skills → plugin/skills}/config-audit/SKILL.md +2 -2
- package/src/adopt.js +4 -4
- package/src/index.js +1 -1
- package/src/report/terminal.js +4 -3
- /package/{skills → plugin/skills}/config-audit/references/fix-recipes.md +0 -0
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -63,17 +63,24 @@ CLAUDE.md
|
|
|
63
63
|
(~$25/month at 3,300 requests, assuming it stays prompt-cached).
|
|
64
64
|
cost/memory-file-too-large
|
|
65
65
|
|
|
66
|
-
Summary Grade F 3 errors, 1 warning
|
|
66
|
+
Summary Grade F 3 errors, 1 warning (72 rules, 41ms)
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
Zero dependencies. No network calls. Credential files are never opened. MIT — all of it.
|
|
70
70
|
|
|
71
71
|
## What it checks
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
Findings fall into five categories. The bar for a rule is that it catches a failure that
|
|
74
|
+
actually happens **and** stays quiet on legitimate config: a correctly configured project
|
|
75
|
+
reports nothing, which the test suite asserts against a fixture. False positives are treated
|
|
76
|
+
as more severe than missed findings, because a linter that cries wolf gets uninstalled and
|
|
77
|
+
then catches nothing at all.
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
Every rule states what is wrong, why it matters, and what to change instead, and every rule
|
|
80
|
+
has a test. There are 72 today; the current catalogue is always in the
|
|
81
|
+
[rule reference](docs/rules.md), or `agentdoctor --list-rules`.
|
|
82
|
+
|
|
83
|
+
### Security
|
|
77
84
|
|
|
78
85
|
The config surface is an execution surface. Blanket `Bash(*)` allows; destructive commands
|
|
79
86
|
pre-approved without confirmation (`sudo`, `rm -rf`, force push, `terraform destroy`,
|
|
@@ -83,7 +90,7 @@ Slack, Stripe keys, JWTs, private keys — always reported **redacted**); MCP se
|
|
|
83
90
|
unpinned packages or carrying tokens in URLs; `bypassPermissions` committed to shared repos;
|
|
84
91
|
loader-hijacking env vars; world-writable config.
|
|
85
92
|
|
|
86
|
-
### Correctness
|
|
93
|
+
### Correctness
|
|
87
94
|
|
|
88
95
|
Config that is silently ignored is worse than config that errors, because you believe it is
|
|
89
96
|
working. Invalid JSON (which voids the whole file, permission rules included); misspelled
|
|
@@ -92,7 +99,7 @@ that block nothing (an **error**, because it is a guardrail that only looks like
|
|
|
92
99
|
malformed hooks and invalid matcher regexes; duplicate agent/skill names; MCP servers with no
|
|
93
100
|
way to start.
|
|
94
101
|
|
|
95
|
-
### Cost
|
|
102
|
+
### Cost
|
|
96
103
|
|
|
97
104
|
Memory files and MCP tool schemas ride along on every request. Token counts for every memory
|
|
98
105
|
file with an estimated monthly cost — the estimate assumes the file stays prompt-cached
|
|
@@ -100,13 +107,13 @@ file with an estimated monthly cost — the estimate assumes the file stays prom
|
|
|
100
107
|
duplicated across files; pasted code blocks that belong behind a file path; skill
|
|
101
108
|
descriptions too vague for the model to ever load them.
|
|
102
109
|
|
|
103
|
-
### Hygiene
|
|
110
|
+
### Hygiene
|
|
104
111
|
|
|
105
112
|
`settings.local.json` not gitignored; machine-specific absolute paths in committed config;
|
|
106
113
|
local settings silently shadowing project settings; empty skill/agent bodies; duplicate
|
|
107
114
|
keybindings.
|
|
108
115
|
|
|
109
|
-
### Policy
|
|
116
|
+
### Policy
|
|
110
117
|
|
|
111
118
|
Team standards, enforced mechanically across every repo. Commit an
|
|
112
119
|
`agentdoctor.policy.json` and these activate — no flag, no account:
|
|
@@ -151,7 +158,7 @@ unrelated edits never invalidate them:
|
|
|
151
158
|
|
|
152
159
|
```sh
|
|
153
160
|
agentdoctor --write-baseline .agentdoctor-baseline.json # once
|
|
154
|
-
agentdoctor --baseline .agentdoctor-baseline.json
|
|
161
|
+
agentdoctor --baseline .agentdoctor-baseline.json # in CI
|
|
155
162
|
```
|
|
156
163
|
|
|
157
164
|
[CI guide](docs/ci.md) · [Baselines](docs/baselines.md)
|
|
@@ -164,13 +171,18 @@ deterministic ordering, redacted secrets safe for model context, pipe-safe outpu
|
|
|
164
171
|
site serves `llms.txt` and raw markdown.
|
|
165
172
|
|
|
166
173
|
The repo is also a **Claude Code plugin**: it ships the
|
|
167
|
-
[config-audit skill](skills/config-audit/SKILL.md) (audit -> fix loop, with fix recipes) and
|
|
168
|
-
|
|
174
|
+
[config-audit skill](plugin/skills/config-audit/SKILL.md) (audit -> fix loop, with fix recipes) and
|
|
175
|
+
invokable as `/agentdoctor:config-audit`. Install it any of three ways:
|
|
169
176
|
|
|
170
177
|
```
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
# in Claude Code, then: /plugin install agentdoctor
|
|
179
|
+
/plugin marketplace add jqntn/agentdoctor
|
|
180
|
+
|
|
181
|
+
# copies the skill into this project only
|
|
182
|
+
npx @jqntn/agentdoctor --init-skill
|
|
183
|
+
|
|
184
|
+
# by hand, from an installed package
|
|
185
|
+
cp -r node_modules/@jqntn/agentdoctor/plugin/skills/config-audit .claude/skills/
|
|
174
186
|
```
|
|
175
187
|
|
|
176
188
|
[Agent guide](docs/agents.md)
|
|
@@ -192,7 +204,7 @@ cp -r node_modules/@jqntn/agentdoctor/skills/config-audit .claude/skills/ # ma
|
|
|
192
204
|
|---|---|
|
|
193
205
|
| [Getting started](docs/getting-started.md) | Install, first run, reading findings, exit codes |
|
|
194
206
|
| [Configuration](docs/configuration.md) | Every flag, suppression, disabling rules |
|
|
195
|
-
| [Rule reference](docs/rules.md) |
|
|
207
|
+
| [Rule reference](docs/rules.md) | Every rule, with the reasoning behind it |
|
|
196
208
|
| [CI setup](docs/ci.md) | GitHub Actions, SARIF, exit-code gating |
|
|
197
209
|
| [Baselines](docs/baselines.md) | Adopting on an existing repo |
|
|
198
210
|
| [Team policy](docs/policy.md) | One standard across many repos |
|
|
@@ -212,4 +224,4 @@ invariants (every rule tested, zero findings on the clean fixture, zero dependen
|
|
|
212
224
|
|
|
213
225
|
## License
|
|
214
226
|
|
|
215
|
-
[MIT](LICENSE).
|
|
227
|
+
[MIT](LICENSE). Every rule, every output format, no accounts, no telemetry, no paid tier.
|
package/docs/agents.md
CHANGED
|
@@ -48,9 +48,11 @@ When an agent decides this tool belongs in a project (for example after an audit
|
|
|
48
48
|
findings), the full adoption is three non-interactive, idempotent-safe commands:
|
|
49
49
|
|
|
50
50
|
```sh
|
|
51
|
-
npx @jqntn/agentdoctor --init-ci
|
|
52
|
-
npx @jqntn/agentdoctor --init-skill
|
|
53
|
-
|
|
51
|
+
npx @jqntn/agentdoctor --init-ci # writes .github/workflows/agentdoctor.yml
|
|
52
|
+
npx @jqntn/agentdoctor --init-skill # writes .claude/skills/config-audit/SKILL.md
|
|
53
|
+
|
|
54
|
+
# only if the project already has findings today
|
|
55
|
+
npx @jqntn/agentdoctor --write-baseline .agentdoctor-baseline.json
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
Each `--init-*` command writes exactly one well-known file, refuses to overwrite, and exits 2
|
|
@@ -65,7 +67,7 @@ agent that can run a shell command can use agentdoctor. What differs per tool is
|
|
|
65
67
|
|
|
66
68
|
| Agent | Mechanism | Install |
|
|
67
69
|
|---|---|---|
|
|
68
|
-
| Claude Code | Skill + plugin (`/agentdoctor:audit`) | `/plugin marketplace add jqntn/agentdoctor` or `npx @jqntn/agentdoctor --init-skill` |
|
|
70
|
+
| Claude Code | Skill + plugin (`/agentdoctor:config-audit`) | `/plugin marketplace add jqntn/agentdoctor` or `npx @jqntn/agentdoctor --init-skill` |
|
|
69
71
|
| OpenAI Codex | `AGENTS.md` | `npx @jqntn/agentdoctor --init-agents` |
|
|
70
72
|
| Cursor | `AGENTS.md` | `npx @jqntn/agentdoctor --init-agents` |
|
|
71
73
|
| Gemini CLI / Jules | `AGENTS.md` | `npx @jqntn/agentdoctor --init-agents` |
|
|
@@ -87,13 +89,16 @@ across projects):
|
|
|
87
89
|
|
|
88
90
|
```sh
|
|
89
91
|
mkdir -p ~/.codex/prompts
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
# project instructions, read by Codex
|
|
93
|
+
npx @jqntn/agentdoctor --init-agents
|
|
94
|
+
|
|
95
|
+
# optional: a reusable /audit-config prompt, user-scoped across projects
|
|
96
|
+
cp node_modules/@jqntn/agentdoctor/plugin/skills/config-audit/SKILL.md ~/.codex/prompts/audit-config.md
|
|
92
97
|
```
|
|
93
98
|
|
|
94
99
|
## The standalone skill and plugin
|
|
95
100
|
|
|
96
|
-
The canonical skill lives at [`skills/config-audit/`](https://github.com/jqntn/agentdoctor/tree/main/skills/config-audit)
|
|
101
|
+
The canonical skill lives at [`plugin/skills/config-audit/`](https://github.com/jqntn/agentdoctor/tree/main/plugin/skills/config-audit)
|
|
97
102
|
in the repo and inside the npm package. It contains the audit -> fix workflow plus
|
|
98
103
|
`references/fix-recipes.md` with per-rule fix patterns, and its `description` frontmatter is
|
|
99
104
|
written to trigger on config-audit requests, edits to `.claude/` files, and "my hook isn't
|
|
@@ -103,9 +108,9 @@ Three ways to install it:
|
|
|
103
108
|
|
|
104
109
|
| Method | Command | Scope |
|
|
105
110
|
|---|---|---|
|
|
106
|
-
| Claude Code plugin | `/plugin marketplace add jqntn/agentdoctor` then `/plugin install agentdoctor` | everywhere
|
|
111
|
+
| Claude Code plugin | `/plugin marketplace add jqntn/agentdoctor` then `/plugin install agentdoctor` | everywhere, invokable as `/agentdoctor:config-audit` |
|
|
107
112
|
| CLI | `npx @jqntn/agentdoctor --init-skill` | this project |
|
|
108
|
-
| Manual | `cp -r node_modules/@jqntn/agentdoctor/skills/config-audit .claude/skills/` | anywhere |
|
|
113
|
+
| Manual | `cp -r node_modules/@jqntn/agentdoctor/plugin/skills/config-audit .claude/skills/` | anywhere |
|
|
109
114
|
|
|
110
115
|
All three install the same files - `--init-skill` copies them out of the package, so the
|
|
111
116
|
installed skill cannot drift from the published one (test-enforced).
|
package/docs/getting-started.md
CHANGED
|
@@ -16,7 +16,7 @@ npx @jqntn/agentdoctor
|
|
|
16
16
|
Or install it:
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
|
-
npm install -g @jqntn/agentdoctor
|
|
19
|
+
npm install -g @jqntn/agentdoctor # global CLI
|
|
20
20
|
npm install -D @jqntn/agentdoctor # per-project, for CI
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -96,4 +96,4 @@ score card (rule ids and counts only - safe to share from private repos), and
|
|
|
96
96
|
- [CI setup](ci.md) — SARIF annotations, exit-code gating
|
|
97
97
|
- [Baselines](baselines.md) — adopting agentdoctor on a repo that already has findings
|
|
98
98
|
- [Team policy](policy.md) — holding many repos to one standard
|
|
99
|
-
- [Rule reference](rules.md) —
|
|
99
|
+
- [Rule reference](rules.md) — every rule and the reasoning behind it
|
package/docs/privacy.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Privacy
|
|
2
|
+
|
|
3
|
+
**agentdoctor collects nothing, transmits nothing, and has no servers.**
|
|
4
|
+
|
|
5
|
+
That claim is easy to make and hard to trust, so here is exactly what the tool does, and how
|
|
6
|
+
you can verify each point yourself.
|
|
7
|
+
|
|
8
|
+
## What it reads
|
|
9
|
+
|
|
10
|
+
Only files in the project you point it at, plus your user-level configuration in `~/.claude`
|
|
11
|
+
unless you pass `--no-user`:
|
|
12
|
+
|
|
13
|
+
`.claude/settings.json`, `.claude/settings.local.json`, `~/.claude/settings.json`, `.mcp.json`,
|
|
14
|
+
`CLAUDE.md` / `CLAUDE.local.md` / `AGENTS.md`, `.claude/agents/*.md`,
|
|
15
|
+
`.claude/skills/*/SKILL.md`, `.claude/commands/*.md`, `.claude/hooks/*`,
|
|
16
|
+
`.claude/keybindings.json`, and `.gitignore`.
|
|
17
|
+
|
|
18
|
+
## What it never reads
|
|
19
|
+
|
|
20
|
+
Credential files are excluded **by path, before anything opens them**:
|
|
21
|
+
`.credentials.json`, `credentials.json`, `.netrc`, `id_rsa`, `id_ed25519`. The report tells you
|
|
22
|
+
how many files were skipped for this reason. A test in the suite plants a tripwire value inside
|
|
23
|
+
a credentials file and asserts it can never appear in any output.
|
|
24
|
+
|
|
25
|
+
## What leaves your machine
|
|
26
|
+
|
|
27
|
+
Nothing. There is no telemetry, no analytics, no crash reporting, no licence check, no update
|
|
28
|
+
check, and no phone-home of any kind. The tool makes **zero network requests**. You can confirm
|
|
29
|
+
this by running it with the network disabled, or by reading the source — there is no HTTP client
|
|
30
|
+
in it, and it has zero dependencies, so there is no transitive code that could add one.
|
|
31
|
+
|
|
32
|
+
## What it writes
|
|
33
|
+
|
|
34
|
+
Nothing, unless you explicitly ask:
|
|
35
|
+
|
|
36
|
+
- `--write-baseline <file>` writes a list of accepted finding fingerprints
|
|
37
|
+
- `--init-ci`, `--init-skill`, `--init-agents`, `--init-policy` each create one well-known file
|
|
38
|
+
and refuse to overwrite an existing one
|
|
39
|
+
|
|
40
|
+
It never edits your configuration. Findings tell you what to change; the change is yours.
|
|
41
|
+
|
|
42
|
+
## Secrets in output
|
|
43
|
+
|
|
44
|
+
When a rule detects a credential-shaped value, the finding shows a short prefix and suffix with
|
|
45
|
+
`(redacted)` — never the value. This holds in every output format, so reports are safe to paste
|
|
46
|
+
into an issue, a CI log, or a model's context.
|
|
47
|
+
|
|
48
|
+
`--share` goes further: it emits only rule ids and counts, never file paths, messages, or
|
|
49
|
+
snippets, so a score card is safe to post publicly from a private repository.
|
|
50
|
+
|
|
51
|
+
## This website
|
|
52
|
+
|
|
53
|
+
Static files served by GitHub Pages. No analytics, no cookies, no trackers, no fonts or scripts
|
|
54
|
+
loaded from third parties. The one exception is a linked badge image hosted by openhunts.com in
|
|
55
|
+
the footer; requesting it reveals your IP address to that host, as any remote image does.
|
|
56
|
+
|
|
57
|
+
## Contact
|
|
58
|
+
|
|
59
|
+
Questions or a discrepancy between this page and the code:
|
|
60
|
+
<https://github.com/jqntn/agentdoctor/issues>
|
package/docs/rules.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Rule reference
|
|
2
2
|
|
|
3
|
-
72
|
|
3
|
+
Every rule, with the reasoning behind it - 72 in total. `agentdoctor --explain <rule-id>`
|
|
4
|
+
prints any of these from the CLI, and `--list-rules` prints the catalogue.
|
|
4
5
|
|
|
5
6
|
## Correctness
|
|
6
7
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jqntn/agentdoctor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Lint and grade your AI coding-agent configuration: permissions, hooks, MCP servers, skills, subagents and CLAUDE.md. Catches silent failures, security holes and context waste, with fixes. Zero dependencies, no telemetry.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"LICENSE",
|
|
58
58
|
"docs",
|
|
59
59
|
"schemas",
|
|
60
|
-
"
|
|
60
|
+
"plugin"
|
|
61
61
|
],
|
|
62
62
|
"scripts": {
|
|
63
63
|
"test": "node --test",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentdoctor",
|
|
3
|
+
"description": "Audit and fix AI coding-agent configuration: permissions, hooks, MCP servers, skills and memory files. Adds the config-audit skill, invokable as /agentdoctor:config-audit. The linter itself runs via npx - nothing else to install.",
|
|
4
|
+
"version": "0.1.3",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Julien QUENTIN",
|
|
7
|
+
"url": "https://github.com/jqntn"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://jqntn.github.io/agentdoctor/",
|
|
10
|
+
"repository": "https://github.com/jqntn/agentdoctor",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"lint",
|
|
14
|
+
"audit",
|
|
15
|
+
"security",
|
|
16
|
+
"agent-config",
|
|
17
|
+
"mcp",
|
|
18
|
+
"hooks",
|
|
19
|
+
"permissions"
|
|
20
|
+
]
|
|
21
|
+
}
|
package/plugin/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# agentdoctor (Claude Code plugin)
|
|
2
|
+
|
|
3
|
+
This directory is the installable plugin: a manifest and the `config-audit` skill, and nothing
|
|
4
|
+
else. It is deliberately separate from the repository root so that installing the plugin fetches
|
|
5
|
+
only these files — not the linter's source, its test fixtures, or the site generator.
|
|
6
|
+
|
|
7
|
+
The skill shells out to `npx @jqntn/agentdoctor`, so the plugin itself installs no binary.
|
|
8
|
+
|
|
9
|
+
- Source and issues: <https://github.com/jqntn/agentdoctor>
|
|
10
|
+
- Documentation: <https://jqntn.github.io/agentdoctor/>
|
|
@@ -5,8 +5,8 @@ description: Audit and fix AI coding-agent configuration with agentdoctor. Use w
|
|
|
5
5
|
|
|
6
6
|
# Audit agent configuration with agentdoctor
|
|
7
7
|
|
|
8
|
-
agentdoctor is a zero-dependency linter for agent config
|
|
9
|
-
cost, hygiene
|
|
8
|
+
agentdoctor is a zero-dependency linter for agent config, covering security, correctness,
|
|
9
|
+
cost, hygiene and team policy. It makes no network calls and never opens credential files, so it
|
|
10
10
|
is safe to run unattended in any project.
|
|
11
11
|
|
|
12
12
|
## Run the audit
|
package/src/adopt.js
CHANGED
|
@@ -54,11 +54,11 @@ jobs:
|
|
|
54
54
|
export const SKILL_PATH = '.claude/skills/config-audit';
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* The canonical skill ships inside the package at skills/config-audit/ -
|
|
58
|
-
* same files
|
|
59
|
-
* never drift from the published one.
|
|
57
|
+
* The canonical skill ships inside the package at plugin/skills/config-audit/ -
|
|
58
|
+
* the same files the plugin marketplace serves - so a skill installed either
|
|
59
|
+
* way can never drift from the published one.
|
|
60
60
|
*/
|
|
61
|
-
const PACKAGED_SKILL = join(dirname(fileURLToPath(import.meta.url)), '..', 'skills', 'config-audit');
|
|
61
|
+
const PACKAGED_SKILL = join(dirname(fileURLToPath(import.meta.url)), '..', 'plugin', 'skills', 'config-audit');
|
|
62
62
|
|
|
63
63
|
/** Writes a file if absent. Returns a { written, path, message } outcome. */
|
|
64
64
|
function writeOnce(root, relative, contents) {
|
package/src/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { lint, fingerprint, helpers } from './engine.js';
|
|
|
3
3
|
import { allRules, CATEGORIES } from './rules/index.js';
|
|
4
4
|
import { loadPolicy } from './rules/policy.js';
|
|
5
5
|
|
|
6
|
-
export const VERSION = '0.1.
|
|
6
|
+
export const VERSION = '0.1.3';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* One-call entry point: discover config, load any team policy, run every rule.
|
package/src/report/terminal.js
CHANGED
|
@@ -120,7 +120,7 @@ function summaryLine(s, counts, input) {
|
|
|
120
120
|
const summary = parts.length ? parts.join(', ') : s.green('clean');
|
|
121
121
|
const grade = computeGrade(input.findings);
|
|
122
122
|
const gradeColor = grade.startsWith('A') ? s.green : (grade === 'B' || grade === 'C' ? s.yellow : s.red);
|
|
123
|
-
lines.push(`${s.bold('Summary')} ${s.bold(gradeColor(`Grade ${grade}`))} ${summary} ${s.dim(
|
|
123
|
+
lines.push(`${s.bold('Summary')} ${s.bold(gradeColor(`Grade ${grade}`))} ${summary} ${s.dim(`(${input.ran.length} rules, ${input.elapsedMs}ms)`)}`);
|
|
124
124
|
|
|
125
125
|
if (input.suppressed > 0) {
|
|
126
126
|
const word = input.suppressed === 1 ? 'finding' : 'findings';
|
|
@@ -128,8 +128,9 @@ function summaryLine(s, counts, input) {
|
|
|
128
128
|
}
|
|
129
129
|
const skipped = input.workspace.skipped ?? [];
|
|
130
130
|
if (skipped.length > 0) {
|
|
131
|
-
|
|
131
|
+
const fileWord = skipped.length === 1 ? 'file' : 'files';
|
|
132
|
+
lines.push(s.dim(` ${skipped.length} ${fileWord} skipped: credential files are never read`));
|
|
132
133
|
}
|
|
133
|
-
lines.push(s.dim(
|
|
134
|
+
lines.push(s.dim(' Share the grade with `agentdoctor --share`, or gate it in CI with `--init-ci`.'));
|
|
134
135
|
return lines.join('\n');
|
|
135
136
|
}
|
|
File without changes
|