codeforerunner 0.4.3__tar.gz → 0.4.4__tar.gz
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.
- {codeforerunner-0.4.3/src/codeforerunner.egg-info → codeforerunner-0.4.4}/PKG-INFO +57 -77
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/README.md +56 -76
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/pyproject.toml +1 -1
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/bundle.py +1 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/check.py +7 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/cli.py +14 -91
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/config.py +17 -41
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/doctor.py +7 -91
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/installer.py +4 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/mcp_server.py +5 -0
- codeforerunner-0.4.4/src/codeforerunner/prompts/tasks/refresh.md +23 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4/src/codeforerunner.egg-info}/PKG-INFO +57 -77
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/SOURCES.txt +1 -7
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_check.py +3 -3
- codeforerunner-0.4.4/tests/test_cli.py +249 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_config.py +16 -43
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_doctor.py +3 -178
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_installer.py +9 -9
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_workflows_yaml.py +44 -0
- codeforerunner-0.4.3/src/codeforerunner/providers/__init__.py +0 -38
- codeforerunner-0.4.3/src/codeforerunner/providers/anthropic.py +0 -122
- codeforerunner-0.4.3/src/codeforerunner/providers/base.py +0 -47
- codeforerunner-0.4.3/src/codeforerunner/providers/google.py +0 -118
- codeforerunner-0.4.3/src/codeforerunner/providers/ollama.py +0 -139
- codeforerunner-0.4.3/src/codeforerunner/providers/openai.py +0 -117
- codeforerunner-0.4.3/tests/test_cli.py +0 -627
- codeforerunner-0.4.3/tests/test_providers.py +0 -669
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/LICENSE.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/setup.cfg +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/__init__.py +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/partials/context-format.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/partials/output-rules.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/partials/stack-hints.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/system/base.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/api-docs.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/audit.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/changelog.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/check.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/diagrams.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/flows.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/init-agent-onboarding.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/readme.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/review.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/scan.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/stack-docs.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/version-audit.md +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/dependency_links.txt +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/entry_points.txt +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/requires.txt +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/top_level.txt +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_bundle.py +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_check_config_integration.py +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_examples.py +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_hooks_manifest.py +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_mcp_server.py +0 -0
- {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_validate_codex_marketplace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeforerunner
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Model-agnostic repository documentation tooling (prompt-first; thin CLI).
|
|
5
5
|
Author: Derek Palmer
|
|
6
6
|
License-Expression: LicenseRef-Codeforerunner-SAL-0.1
|
|
@@ -29,11 +29,11 @@ Dynamic: license-file
|
|
|
29
29
|
|
|
30
30
|
# codeForerunner
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
[](https://badge.socket.dev/npm/package/codeforerunner/0.4.3)
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Model-agnostic repository documentation tooling. Ships a prompt pack for codebase analysis and doc generation, a thin Python CLI, an MCP server, drift-detection rules that keep docs honest — and native slash-command skills for Claude Code, Codex, Gemini CLI, and other agent CLIs.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
## Install
|
|
37
37
|
|
|
38
38
|
Install forerunner's prompt pack as skills into your agent CLI. Each documentation task becomes a slash command (`/forerunner-readme`, `/forerunner-check`, etc.) available inside Claude Code, Codex, Gemini CLI, and other agents. Authentication is handled by your existing agent subscription — no separate API key needed.
|
|
39
39
|
|
|
@@ -58,26 +58,9 @@ Then in your agent:
|
|
|
58
58
|
/forerunner-scan ← scan the repo first
|
|
59
59
|
/forerunner-readme ← generate README
|
|
60
60
|
/forerunner-check ← detect doc drift
|
|
61
|
+
/forerunner-refresh ← scan + update all stale docs
|
|
61
62
|
```
|
|
62
63
|
|
|
63
|
-
### Mode B — Direct API (needs API key or Ollama)
|
|
64
|
-
|
|
65
|
-
Install the Python CLI and call your provider directly. Works without any agent CLI installed.
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
pipx install codeforerunner # recommended
|
|
69
|
-
pip install codeforerunner # alternative
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Configure a provider (or start Ollama for keyless local generation):
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
export ANTHROPIC_API_KEY=sk-...
|
|
76
|
-
forerunner generate readme --stream
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
If no API key and no `--provider` flag, forerunner auto-detects Ollama at `localhost:11434` and falls back to local mode.
|
|
80
|
-
|
|
81
64
|
## Slash commands
|
|
82
65
|
|
|
83
66
|
| Command | Task | Purpose |
|
|
@@ -94,14 +77,17 @@ If no API key and no `--provider` flag, forerunner auto-detects Ollama at `local
|
|
|
94
77
|
| `/forerunner-audit` | `audit` | Security and dependency audit |
|
|
95
78
|
| `/forerunner-changelog` | `changelog` | Generate changelog from git log |
|
|
96
79
|
| `/forerunner-init` | `init-agent-onboarding` | Bootstrap or refresh AGENTS.md |
|
|
80
|
+
| `/forerunner-refresh` | `refresh` | Scan + check + update all stale docs in one pass |
|
|
97
81
|
|
|
98
|
-
Slash command availability depends on the agent CLI. Claude Code, Codex, and Gemini CLI support all
|
|
82
|
+
Slash command availability depends on the agent CLI. Claude Code, Codex, and Gemini CLI support all commands after install.
|
|
99
83
|
|
|
100
84
|
## Skill install options
|
|
101
85
|
|
|
102
86
|
| Flag | Effect |
|
|
103
87
|
|------|--------|
|
|
104
|
-
| `./install.sh` | Auto-detect all agents, install all skills |
|
|
88
|
+
| `./install.sh` | Auto-detect all agents, prompt global vs local, install all skills |
|
|
89
|
+
| `./install.sh --global` | Skip prompt, install to global agent dirs (all projects) |
|
|
90
|
+
| `./install.sh --local` | Skip prompt, install to `.claude/skills/` and `.agents/skills/` in cwd |
|
|
105
91
|
| `./install.sh --only claude` | Claude Code only |
|
|
106
92
|
| `./install.sh --only codex` | Codex only |
|
|
107
93
|
| `./install.sh --only gemini` | Gemini CLI only |
|
|
@@ -120,65 +106,54 @@ pip install codeforerunner
|
|
|
120
106
|
| `forerunner init` | Resolve agent-onboarding bundle to stdout. |
|
|
121
107
|
| `forerunner scan` | Resolve scan bundle to stdout. |
|
|
122
108
|
| `forerunner doc <task>` | Resolve `base + partials + task` bundle to stdout. |
|
|
109
|
+
| `forerunner refresh` | Output scan + check + all doc-task bundles in sequence for a full doc refresh. |
|
|
123
110
|
| `forerunner check` | Run drift-detection rules; no-op without `forerunner.config.yaml`. |
|
|
124
|
-
| `forerunner
|
|
125
|
-
| `forerunner doctor` | Health report: skill parity, config, provider key, local-mode status. Add `--fix` to write a starter config. |
|
|
111
|
+
| `forerunner doctor` | Health report: skill parity, config. Add `--fix` to write a starter config. |
|
|
126
112
|
| `forerunner mcp-server` | Serve prompt bundles as MCP tools over stdio (JSON-RPC 2.0). |
|
|
127
113
|
| `forerunner install <agent>` | Install canonical skill into agent-specific directory. Add `--all` for all per-task skills. |
|
|
128
114
|
|
|
129
|
-
##
|
|
130
|
-
|
|
131
|
-
Prompts are bundled inside the package at `src/codeforerunner/prompts/`.
|
|
132
|
-
|
|
133
|
-
```text
|
|
134
|
-
prompts/
|
|
135
|
-
├── system/base.md
|
|
136
|
-
├── partials/
|
|
137
|
-
│ ├── context-format.md
|
|
138
|
-
│ ├── output-rules.md
|
|
139
|
-
│ └── stack-hints.md
|
|
140
|
-
└── tasks/
|
|
141
|
-
├── scan.md api-docs.md audit.md
|
|
142
|
-
├── readme.md diagrams.md changelog.md
|
|
143
|
-
├── check.md flows.md version-audit.md
|
|
144
|
-
├── review.md stack-docs.md
|
|
145
|
-
└── init-agent-onboarding.md
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Quick start (agent skill mode)
|
|
115
|
+
## Quick start
|
|
149
116
|
|
|
150
117
|
```bash
|
|
151
118
|
# Install skills into Claude Code
|
|
152
119
|
curl -fsSL https://raw.githubusercontent.com/derek-palmer/codeforerunner/main/install.sh | bash
|
|
153
120
|
|
|
154
121
|
# In Claude Code:
|
|
155
|
-
# /forerunner-scan
|
|
156
|
-
# /forerunner-readme
|
|
157
|
-
# /forerunner-
|
|
122
|
+
# /forerunner-scan → scans your repo
|
|
123
|
+
# /forerunner-readme → generates README.md
|
|
124
|
+
# /forerunner-refresh → updates all stale docs
|
|
125
|
+
# /forerunner-check → checks for doc drift
|
|
158
126
|
```
|
|
159
127
|
|
|
160
|
-
##
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
# 1. Install and configure
|
|
164
|
-
pip install codeforerunner
|
|
165
|
-
export ANTHROPIC_API_KEY=sk-...
|
|
128
|
+
## GitHub Action
|
|
166
129
|
|
|
167
|
-
|
|
168
|
-
forerunner generate readme --stream
|
|
130
|
+
Add doc-drift detection to any repo's CI — fails the PR if docs contradict repo state.
|
|
169
131
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
132
|
+
```yaml
|
|
133
|
+
# .github/workflows/doc-check.yml
|
|
134
|
+
name: Doc Check
|
|
135
|
+
on: [push, pull_request]
|
|
136
|
+
|
|
137
|
+
jobs:
|
|
138
|
+
doc-check:
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
steps:
|
|
141
|
+
- uses: actions/checkout@v6.0.2
|
|
142
|
+
- uses: derek-palmer/codeforerunner@v0.4.3
|
|
143
|
+
with:
|
|
144
|
+
fail-on-drift: "true" # set "false" to warn-only
|
|
173
145
|
```
|
|
174
146
|
|
|
175
|
-
|
|
147
|
+
No-op when `forerunner.config.yaml` is absent — safe to add before configuring rules.
|
|
176
148
|
|
|
177
|
-
|
|
178
|
-
- uses: derek-palmer/codeforerunner@v0.4.2
|
|
179
|
-
```
|
|
149
|
+
**Inputs**
|
|
180
150
|
|
|
181
|
-
|
|
151
|
+
| Input | Default | Description |
|
|
152
|
+
|-------|---------|-------------|
|
|
153
|
+
| `version` | `latest` | `codeforerunner` version to install |
|
|
154
|
+
| `python-version` | `3.11` | Python version |
|
|
155
|
+
| `repo` | workspace root | Path to check |
|
|
156
|
+
| `fail-on-drift` | `true` | Exit non-zero on drift |
|
|
182
157
|
|
|
183
158
|
## Configuration
|
|
184
159
|
|
|
@@ -191,10 +166,7 @@ forerunner doctor --fix
|
|
|
191
166
|
### Config fields
|
|
192
167
|
|
|
193
168
|
```yaml
|
|
194
|
-
|
|
195
|
-
model: claude-opus-4-7
|
|
196
|
-
api_key_env:
|
|
197
|
-
anthropic: ANTHROPIC_API_KEY
|
|
169
|
+
approaching_eol_threshold_months: 6
|
|
198
170
|
|
|
199
171
|
tasks:
|
|
200
172
|
check:
|
|
@@ -237,16 +209,24 @@ tasks:
|
|
|
237
209
|
|
|
238
210
|
See `examples/mcp/` for Claude Desktop and mcp-cli wiring examples.
|
|
239
211
|
|
|
240
|
-
##
|
|
212
|
+
## Prompt pack
|
|
241
213
|
|
|
242
|
-
|
|
214
|
+
Prompts are bundled inside the package at `src/codeforerunner/prompts/`.
|
|
243
215
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
216
|
+
```text
|
|
217
|
+
prompts/
|
|
218
|
+
├── system/base.md
|
|
219
|
+
├── partials/
|
|
220
|
+
│ ├── context-format.md
|
|
221
|
+
│ ├── output-rules.md
|
|
222
|
+
│ └── stack-hints.md
|
|
223
|
+
└── tasks/
|
|
224
|
+
├── scan.md api-docs.md audit.md
|
|
225
|
+
├── readme.md diagrams.md changelog.md
|
|
226
|
+
├── check.md flows.md version-audit.md
|
|
227
|
+
├── review.md stack-docs.md refresh.md
|
|
228
|
+
└── init-agent-onboarding.md
|
|
229
|
+
```
|
|
250
230
|
|
|
251
231
|
## Docs and spec
|
|
252
232
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# codeForerunner
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://badge.socket.dev/npm/package/codeforerunner/0.4.3)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Model-agnostic repository documentation tooling. Ships a prompt pack for codebase analysis and doc generation, a thin Python CLI, an MCP server, drift-detection rules that keep docs honest — and native slash-command skills for Claude Code, Codex, Gemini CLI, and other agent CLIs.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Install
|
|
10
10
|
|
|
11
11
|
Install forerunner's prompt pack as skills into your agent CLI. Each documentation task becomes a slash command (`/forerunner-readme`, `/forerunner-check`, etc.) available inside Claude Code, Codex, Gemini CLI, and other agents. Authentication is handled by your existing agent subscription — no separate API key needed.
|
|
12
12
|
|
|
@@ -31,26 +31,9 @@ Then in your agent:
|
|
|
31
31
|
/forerunner-scan ← scan the repo first
|
|
32
32
|
/forerunner-readme ← generate README
|
|
33
33
|
/forerunner-check ← detect doc drift
|
|
34
|
+
/forerunner-refresh ← scan + update all stale docs
|
|
34
35
|
```
|
|
35
36
|
|
|
36
|
-
### Mode B — Direct API (needs API key or Ollama)
|
|
37
|
-
|
|
38
|
-
Install the Python CLI and call your provider directly. Works without any agent CLI installed.
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
pipx install codeforerunner # recommended
|
|
42
|
-
pip install codeforerunner # alternative
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Configure a provider (or start Ollama for keyless local generation):
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
export ANTHROPIC_API_KEY=sk-...
|
|
49
|
-
forerunner generate readme --stream
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
If no API key and no `--provider` flag, forerunner auto-detects Ollama at `localhost:11434` and falls back to local mode.
|
|
53
|
-
|
|
54
37
|
## Slash commands
|
|
55
38
|
|
|
56
39
|
| Command | Task | Purpose |
|
|
@@ -67,14 +50,17 @@ If no API key and no `--provider` flag, forerunner auto-detects Ollama at `local
|
|
|
67
50
|
| `/forerunner-audit` | `audit` | Security and dependency audit |
|
|
68
51
|
| `/forerunner-changelog` | `changelog` | Generate changelog from git log |
|
|
69
52
|
| `/forerunner-init` | `init-agent-onboarding` | Bootstrap or refresh AGENTS.md |
|
|
53
|
+
| `/forerunner-refresh` | `refresh` | Scan + check + update all stale docs in one pass |
|
|
70
54
|
|
|
71
|
-
Slash command availability depends on the agent CLI. Claude Code, Codex, and Gemini CLI support all
|
|
55
|
+
Slash command availability depends on the agent CLI. Claude Code, Codex, and Gemini CLI support all commands after install.
|
|
72
56
|
|
|
73
57
|
## Skill install options
|
|
74
58
|
|
|
75
59
|
| Flag | Effect |
|
|
76
60
|
|------|--------|
|
|
77
|
-
| `./install.sh` | Auto-detect all agents, install all skills |
|
|
61
|
+
| `./install.sh` | Auto-detect all agents, prompt global vs local, install all skills |
|
|
62
|
+
| `./install.sh --global` | Skip prompt, install to global agent dirs (all projects) |
|
|
63
|
+
| `./install.sh --local` | Skip prompt, install to `.claude/skills/` and `.agents/skills/` in cwd |
|
|
78
64
|
| `./install.sh --only claude` | Claude Code only |
|
|
79
65
|
| `./install.sh --only codex` | Codex only |
|
|
80
66
|
| `./install.sh --only gemini` | Gemini CLI only |
|
|
@@ -93,65 +79,54 @@ pip install codeforerunner
|
|
|
93
79
|
| `forerunner init` | Resolve agent-onboarding bundle to stdout. |
|
|
94
80
|
| `forerunner scan` | Resolve scan bundle to stdout. |
|
|
95
81
|
| `forerunner doc <task>` | Resolve `base + partials + task` bundle to stdout. |
|
|
82
|
+
| `forerunner refresh` | Output scan + check + all doc-task bundles in sequence for a full doc refresh. |
|
|
96
83
|
| `forerunner check` | Run drift-detection rules; no-op without `forerunner.config.yaml`. |
|
|
97
|
-
| `forerunner
|
|
98
|
-
| `forerunner doctor` | Health report: skill parity, config, provider key, local-mode status. Add `--fix` to write a starter config. |
|
|
84
|
+
| `forerunner doctor` | Health report: skill parity, config. Add `--fix` to write a starter config. |
|
|
99
85
|
| `forerunner mcp-server` | Serve prompt bundles as MCP tools over stdio (JSON-RPC 2.0). |
|
|
100
86
|
| `forerunner install <agent>` | Install canonical skill into agent-specific directory. Add `--all` for all per-task skills. |
|
|
101
87
|
|
|
102
|
-
##
|
|
103
|
-
|
|
104
|
-
Prompts are bundled inside the package at `src/codeforerunner/prompts/`.
|
|
105
|
-
|
|
106
|
-
```text
|
|
107
|
-
prompts/
|
|
108
|
-
├── system/base.md
|
|
109
|
-
├── partials/
|
|
110
|
-
│ ├── context-format.md
|
|
111
|
-
│ ├── output-rules.md
|
|
112
|
-
│ └── stack-hints.md
|
|
113
|
-
└── tasks/
|
|
114
|
-
├── scan.md api-docs.md audit.md
|
|
115
|
-
├── readme.md diagrams.md changelog.md
|
|
116
|
-
├── check.md flows.md version-audit.md
|
|
117
|
-
├── review.md stack-docs.md
|
|
118
|
-
└── init-agent-onboarding.md
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Quick start (agent skill mode)
|
|
88
|
+
## Quick start
|
|
122
89
|
|
|
123
90
|
```bash
|
|
124
91
|
# Install skills into Claude Code
|
|
125
92
|
curl -fsSL https://raw.githubusercontent.com/derek-palmer/codeforerunner/main/install.sh | bash
|
|
126
93
|
|
|
127
94
|
# In Claude Code:
|
|
128
|
-
# /forerunner-scan
|
|
129
|
-
# /forerunner-readme
|
|
130
|
-
# /forerunner-
|
|
95
|
+
# /forerunner-scan → scans your repo
|
|
96
|
+
# /forerunner-readme → generates README.md
|
|
97
|
+
# /forerunner-refresh → updates all stale docs
|
|
98
|
+
# /forerunner-check → checks for doc drift
|
|
131
99
|
```
|
|
132
100
|
|
|
133
|
-
##
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
# 1. Install and configure
|
|
137
|
-
pip install codeforerunner
|
|
138
|
-
export ANTHROPIC_API_KEY=sk-...
|
|
101
|
+
## GitHub Action
|
|
139
102
|
|
|
140
|
-
|
|
141
|
-
forerunner generate readme --stream
|
|
103
|
+
Add doc-drift detection to any repo's CI — fails the PR if docs contradict repo state.
|
|
142
104
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
105
|
+
```yaml
|
|
106
|
+
# .github/workflows/doc-check.yml
|
|
107
|
+
name: Doc Check
|
|
108
|
+
on: [push, pull_request]
|
|
109
|
+
|
|
110
|
+
jobs:
|
|
111
|
+
doc-check:
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
steps:
|
|
114
|
+
- uses: actions/checkout@v6.0.2
|
|
115
|
+
- uses: derek-palmer/codeforerunner@v0.4.3
|
|
116
|
+
with:
|
|
117
|
+
fail-on-drift: "true" # set "false" to warn-only
|
|
146
118
|
```
|
|
147
119
|
|
|
148
|
-
|
|
120
|
+
No-op when `forerunner.config.yaml` is absent — safe to add before configuring rules.
|
|
149
121
|
|
|
150
|
-
|
|
151
|
-
- uses: derek-palmer/codeforerunner@v0.4.2
|
|
152
|
-
```
|
|
122
|
+
**Inputs**
|
|
153
123
|
|
|
154
|
-
|
|
124
|
+
| Input | Default | Description |
|
|
125
|
+
|-------|---------|-------------|
|
|
126
|
+
| `version` | `latest` | `codeforerunner` version to install |
|
|
127
|
+
| `python-version` | `3.11` | Python version |
|
|
128
|
+
| `repo` | workspace root | Path to check |
|
|
129
|
+
| `fail-on-drift` | `true` | Exit non-zero on drift |
|
|
155
130
|
|
|
156
131
|
## Configuration
|
|
157
132
|
|
|
@@ -164,10 +139,7 @@ forerunner doctor --fix
|
|
|
164
139
|
### Config fields
|
|
165
140
|
|
|
166
141
|
```yaml
|
|
167
|
-
|
|
168
|
-
model: claude-opus-4-7
|
|
169
|
-
api_key_env:
|
|
170
|
-
anthropic: ANTHROPIC_API_KEY
|
|
142
|
+
approaching_eol_threshold_months: 6
|
|
171
143
|
|
|
172
144
|
tasks:
|
|
173
145
|
check:
|
|
@@ -210,16 +182,24 @@ tasks:
|
|
|
210
182
|
|
|
211
183
|
See `examples/mcp/` for Claude Desktop and mcp-cli wiring examples.
|
|
212
184
|
|
|
213
|
-
##
|
|
185
|
+
## Prompt pack
|
|
214
186
|
|
|
215
|
-
|
|
187
|
+
Prompts are bundled inside the package at `src/codeforerunner/prompts/`.
|
|
216
188
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
189
|
+
```text
|
|
190
|
+
prompts/
|
|
191
|
+
├── system/base.md
|
|
192
|
+
├── partials/
|
|
193
|
+
│ ├── context-format.md
|
|
194
|
+
│ ├── output-rules.md
|
|
195
|
+
│ └── stack-hints.md
|
|
196
|
+
└── tasks/
|
|
197
|
+
├── scan.md api-docs.md audit.md
|
|
198
|
+
├── readme.md diagrams.md changelog.md
|
|
199
|
+
├── check.md flows.md version-audit.md
|
|
200
|
+
├── review.md stack-docs.md refresh.md
|
|
201
|
+
└── init-agent-onboarding.md
|
|
202
|
+
```
|
|
223
203
|
|
|
224
204
|
## Docs and spec
|
|
225
205
|
|
|
@@ -21,6 +21,8 @@ class Violation:
|
|
|
21
21
|
|
|
22
22
|
@dataclass(frozen=True)
|
|
23
23
|
class _Rule:
|
|
24
|
+
"""Drift detection rule: pattern to match, trigger files, and violation message."""
|
|
25
|
+
|
|
24
26
|
id: str
|
|
25
27
|
pattern: re.Pattern
|
|
26
28
|
triggers: tuple[str, ...]
|
|
@@ -124,6 +126,7 @@ _CHANGELOG_FILENAME = "CHANGELOG.md"
|
|
|
124
126
|
|
|
125
127
|
|
|
126
128
|
def _trigger_exists(repo: Path, patterns: tuple[str, ...]) -> bool:
|
|
129
|
+
"""Return True if any pattern matches an existing file in repo."""
|
|
127
130
|
for pat in patterns:
|
|
128
131
|
if "*" in pat:
|
|
129
132
|
parent = repo / Path(pat).parent
|
|
@@ -137,6 +140,7 @@ def _trigger_exists(repo: Path, patterns: tuple[str, ...]) -> bool:
|
|
|
137
140
|
|
|
138
141
|
|
|
139
142
|
def _scanned_docs(repo: Path) -> list[Path]:
|
|
143
|
+
"""Collect README.md and all *.md files under docs/ from repo."""
|
|
140
144
|
docs: list[Path] = []
|
|
141
145
|
readme = repo / "README.md"
|
|
142
146
|
if readme.is_file():
|
|
@@ -148,6 +152,7 @@ def _scanned_docs(repo: Path) -> list[Path]:
|
|
|
148
152
|
|
|
149
153
|
|
|
150
154
|
def _path_ignored(repo: Path, doc: Path, ignore_patterns: tuple[str, ...]) -> bool:
|
|
155
|
+
"""Return True if doc's repo-relative path matches any ignore pattern."""
|
|
151
156
|
if not ignore_patterns:
|
|
152
157
|
return False
|
|
153
158
|
try:
|
|
@@ -158,6 +163,7 @@ def _path_ignored(repo: Path, doc: Path, ignore_patterns: tuple[str, ...]) -> bo
|
|
|
158
163
|
|
|
159
164
|
|
|
160
165
|
def _current_version(repo: Path) -> str | None:
|
|
166
|
+
"""Extract the package version from pyproject.toml, or None if absent/unparseable."""
|
|
161
167
|
pyproject = repo / "pyproject.toml"
|
|
162
168
|
if not pyproject.is_file():
|
|
163
169
|
return None
|
|
@@ -175,6 +181,7 @@ def _check_version_drift(
|
|
|
175
181
|
ignore_patterns: tuple[str, ...],
|
|
176
182
|
enabled: set[str] | None,
|
|
177
183
|
) -> list[Violation]:
|
|
184
|
+
"""Scan docs for pinned version strings that don't match pyproject.toml."""
|
|
178
185
|
if enabled is not None and "RV1-version-drift" not in enabled:
|
|
179
186
|
return []
|
|
180
187
|
current = _current_version(repo)
|
|
@@ -56,6 +56,7 @@ def cmd_doc(args: argparse.Namespace) -> int:
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def _doc_for(args: argparse.Namespace, task: str) -> int:
|
|
59
|
+
"""Emit bundle for *task* by delegating to cmd_doc with a synthetic Namespace."""
|
|
59
60
|
ns = argparse.Namespace(repo=getattr(args, "repo", None), task=task)
|
|
60
61
|
return cmd_doc(ns)
|
|
61
62
|
|
|
@@ -113,85 +114,17 @@ def cmd_mcp_server(args: argparse.Namespace) -> int:
|
|
|
113
114
|
return mcp_server.serve(prompts_root)
|
|
114
115
|
|
|
115
116
|
|
|
116
|
-
def
|
|
117
|
-
"""
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
ns = argparse.Namespace(repo=getattr(args, "repo", None), task=args.task)
|
|
129
|
-
|
|
130
|
-
# --prompt-only: output the bundle and stop; the calling agent is the model.
|
|
131
|
-
if getattr(args, "prompt_only", False):
|
|
132
|
-
return cmd_doc(ns)
|
|
133
|
-
|
|
134
|
-
bundle, rc = _get_bundle(ns)
|
|
135
|
-
if rc != 0:
|
|
136
|
-
return rc
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
explicit_provider = args.provider or (cfg.provider if cfg else None)
|
|
140
|
-
provider_name = explicit_provider or "anthropic"
|
|
141
|
-
model = args.model or (cfg.model if cfg else None)
|
|
142
|
-
provider_cls = _providers.get(provider_name)
|
|
143
|
-
provider = provider_cls()
|
|
144
|
-
model = model or provider.default_model
|
|
145
|
-
|
|
146
|
-
env_var = (cfg.api_key_env.get(provider_name) if cfg else None) or provider.default_env_var
|
|
147
|
-
api_key = os.environ.get(env_var)
|
|
148
|
-
if api_key is None and provider_name != "ollama":
|
|
149
|
-
if explicit_provider is None and _providers.ollama_available():
|
|
150
|
-
provider_name = "ollama"
|
|
151
|
-
provider_cls = _providers.get("ollama")
|
|
152
|
-
provider = provider_cls()
|
|
153
|
-
if not args.model:
|
|
154
|
-
model = provider.default_model
|
|
155
|
-
print("info: no API key; falling back to Ollama (local mode)", file=sys.stderr)
|
|
156
|
-
elif explicit_provider is None:
|
|
157
|
-
# Skill-mode auto-detect: no provider configured, no Ollama — output
|
|
158
|
-
# the prompt bundle for the calling agent to process directly.
|
|
159
|
-
sys.stdout.write(bundle)
|
|
160
|
-
if sys.stdout.isatty():
|
|
161
|
-
print(
|
|
162
|
-
"\ninfo: no provider configured and Ollama not running.\n"
|
|
163
|
-
" Prompt bundle written above — paste into your agent,\n"
|
|
164
|
-
" or run: forerunner generate --prompt-only "
|
|
165
|
-
f"{args.task}",
|
|
166
|
-
file=sys.stderr,
|
|
167
|
-
)
|
|
168
|
-
return 0
|
|
169
|
-
else:
|
|
170
|
-
print(f"error: missing API key; set ${env_var}", file=sys.stderr)
|
|
171
|
-
return 3
|
|
172
|
-
|
|
173
|
-
if getattr(args, "stream", False):
|
|
174
|
-
try:
|
|
175
|
-
for chunk in provider.stream(prompt=bundle, model=model, api_key=api_key):
|
|
176
|
-
sys.stdout.write(chunk)
|
|
177
|
-
sys.stdout.flush()
|
|
178
|
-
except _providers.ProviderError as e:
|
|
179
|
-
print(f"error: {provider_name} provider failed: {e}", file=sys.stderr)
|
|
180
|
-
return 4
|
|
181
|
-
sys.stdout.write("\n")
|
|
182
|
-
return 0
|
|
183
|
-
|
|
184
|
-
try:
|
|
185
|
-
result = provider.complete(prompt=bundle, model=model, api_key=api_key)
|
|
186
|
-
except _providers.ProviderError as e:
|
|
187
|
-
print(f"error: {provider_name} provider failed: {e}", file=sys.stderr)
|
|
188
|
-
return 4
|
|
189
|
-
|
|
190
|
-
sys.stdout.write(result.text.rstrip() + "\n")
|
|
191
|
-
print(
|
|
192
|
-
f"# {provider_name} {result.model} {result.usage or ''}".rstrip(),
|
|
193
|
-
file=sys.stderr,
|
|
194
|
-
)
|
|
117
|
+
def cmd_refresh(args: argparse.Namespace) -> int:
|
|
118
|
+
"""Emit scan + check + all doc-task bundles to stdout for a full doc refresh."""
|
|
119
|
+
tasks = ["scan", "check", "readme", "api-docs", "stack-docs",
|
|
120
|
+
"diagrams", "flows", "version-audit", "audit"]
|
|
121
|
+
for i, task in enumerate(tasks):
|
|
122
|
+
ns = argparse.Namespace(repo=getattr(args, "repo", None), task=task)
|
|
123
|
+
rc = cmd_doc(ns)
|
|
124
|
+
if rc != 0:
|
|
125
|
+
return rc
|
|
126
|
+
if i < len(tasks) - 1:
|
|
127
|
+
sys.stdout.write("\n---\n\n")
|
|
195
128
|
return 0
|
|
196
129
|
|
|
197
130
|
|
|
@@ -270,18 +203,8 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
270
203
|
)
|
|
271
204
|
s_doctor.set_defaults(func=cmd_doctor)
|
|
272
205
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
s_gen.add_argument("--provider", help="override config provider")
|
|
276
|
-
s_gen.add_argument("--model", help="override config model")
|
|
277
|
-
s_gen.add_argument("--stream", action="store_true", help="stream output token-by-token")
|
|
278
|
-
s_gen.add_argument(
|
|
279
|
-
"--prompt-only",
|
|
280
|
-
dest="prompt_only",
|
|
281
|
-
action="store_true",
|
|
282
|
-
help="output the assembled prompt bundle to stdout; do not call a model (skill mode)",
|
|
283
|
-
)
|
|
284
|
-
s_gen.set_defaults(func=cmd_generate)
|
|
206
|
+
s_refresh = sub.add_parser("refresh", help="output all doc-refresh bundles in sequence (scan + check + all tasks)")
|
|
207
|
+
s_refresh.set_defaults(func=cmd_refresh)
|
|
285
208
|
|
|
286
209
|
from codeforerunner import installer
|
|
287
210
|
installer.add_subparser(sub)
|