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.
Files changed (56) hide show
  1. {codeforerunner-0.4.3/src/codeforerunner.egg-info → codeforerunner-0.4.4}/PKG-INFO +57 -77
  2. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/README.md +56 -76
  3. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/pyproject.toml +1 -1
  4. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/bundle.py +1 -0
  5. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/check.py +7 -0
  6. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/cli.py +14 -91
  7. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/config.py +17 -41
  8. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/doctor.py +7 -91
  9. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/installer.py +4 -0
  10. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/mcp_server.py +5 -0
  11. codeforerunner-0.4.4/src/codeforerunner/prompts/tasks/refresh.md +23 -0
  12. {codeforerunner-0.4.3 → codeforerunner-0.4.4/src/codeforerunner.egg-info}/PKG-INFO +57 -77
  13. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/SOURCES.txt +1 -7
  14. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_check.py +3 -3
  15. codeforerunner-0.4.4/tests/test_cli.py +249 -0
  16. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_config.py +16 -43
  17. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_doctor.py +3 -178
  18. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_installer.py +9 -9
  19. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_workflows_yaml.py +44 -0
  20. codeforerunner-0.4.3/src/codeforerunner/providers/__init__.py +0 -38
  21. codeforerunner-0.4.3/src/codeforerunner/providers/anthropic.py +0 -122
  22. codeforerunner-0.4.3/src/codeforerunner/providers/base.py +0 -47
  23. codeforerunner-0.4.3/src/codeforerunner/providers/google.py +0 -118
  24. codeforerunner-0.4.3/src/codeforerunner/providers/ollama.py +0 -139
  25. codeforerunner-0.4.3/src/codeforerunner/providers/openai.py +0 -117
  26. codeforerunner-0.4.3/tests/test_cli.py +0 -627
  27. codeforerunner-0.4.3/tests/test_providers.py +0 -669
  28. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/LICENSE.md +0 -0
  29. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/setup.cfg +0 -0
  30. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/__init__.py +0 -0
  31. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/partials/context-format.md +0 -0
  32. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/partials/output-rules.md +0 -0
  33. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/partials/stack-hints.md +0 -0
  34. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/system/base.md +0 -0
  35. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/api-docs.md +0 -0
  36. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/audit.md +0 -0
  37. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/changelog.md +0 -0
  38. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/check.md +0 -0
  39. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/diagrams.md +0 -0
  40. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/flows.md +0 -0
  41. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/init-agent-onboarding.md +0 -0
  42. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/readme.md +0 -0
  43. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/review.md +0 -0
  44. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/scan.md +0 -0
  45. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/stack-docs.md +0 -0
  46. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner/prompts/tasks/version-audit.md +0 -0
  47. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/dependency_links.txt +0 -0
  48. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/entry_points.txt +0 -0
  49. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/requires.txt +0 -0
  50. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/src/codeforerunner.egg-info/top_level.txt +0 -0
  51. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_bundle.py +0 -0
  52. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_check_config_integration.py +0 -0
  53. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_examples.py +0 -0
  54. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_hooks_manifest.py +0 -0
  55. {codeforerunner-0.4.3 → codeforerunner-0.4.4}/tests/test_mcp_server.py +0 -0
  56. {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
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
- 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.
32
+ [![Socket Badge](https://badge.socket.dev/npm/package/codeforerunner/0.4.3)](https://badge.socket.dev/npm/package/codeforerunner/0.4.3)
33
33
 
34
- ## Two modes
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
- ### Mode A — Agent skill (recommended, no API key required)
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 12 commands after install.
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 generate <task>` | Call configured provider directly. Add `--stream` for token-by-token output. Falls back to Ollama automatically when no API key is configured. |
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
- ## Prompt pack
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 → scans your repo
156
- # /forerunner-readme → generates README.md
157
- # /forerunner-check checks for doc drift
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
- ## Quick start (direct API mode)
161
-
162
- ```bash
163
- # 1. Install and configure
164
- pip install codeforerunner
165
- export ANTHROPIC_API_KEY=sk-...
128
+ ## GitHub Action
166
129
 
167
- # 2. Run a task
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
- # 3. Enable drift detection
171
- forerunner doctor --fix # writes forerunner.config.yaml
172
- forerunner check # run any time or as pre-commit hook
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
- ## GitHub Action
147
+ No-op when `forerunner.config.yaml` is absent — safe to add before configuring rules.
176
148
 
177
- ```yaml
178
- - uses: derek-palmer/codeforerunner@v0.4.2
179
- ```
149
+ **Inputs**
180
150
 
181
- No-op when `forerunner.config.yaml` is absent.
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
- provider: anthropic # anthropic | openai | google | ollama
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
- ## Providers
212
+ ## Prompt pack
241
213
 
242
- `forerunner generate` supports four providers. When no provider is explicitly configured and no API key is found, forerunner probes `localhost:11434` and falls back to Ollama automatically.
214
+ Prompts are bundled inside the package at `src/codeforerunner/prompts/`.
243
215
 
244
- | Provider | Env var | Default model |
245
- |----------|---------|---------------|
246
- | `anthropic` | `ANTHROPIC_API_KEY` | `claude-opus-4-7` |
247
- | `openai` | `OPENAI_API_KEY` | `gpt-4o` |
248
- | `google` | `GOOGLE_API_KEY` | `gemini-2.5-pro` |
249
- | `ollama` | `OLLAMA_HOST` (optional) | `llama3` |
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
- 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.
5
+ [![Socket Badge](https://badge.socket.dev/npm/package/codeforerunner/0.4.3)](https://badge.socket.dev/npm/package/codeforerunner/0.4.3)
6
6
 
7
- ## Two modes
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
- ### Mode A — Agent skill (recommended, no API key required)
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 12 commands after install.
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 generate <task>` | Call configured provider directly. Add `--stream` for token-by-token output. Falls back to Ollama automatically when no API key is configured. |
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
- ## Prompt pack
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 → scans your repo
129
- # /forerunner-readme → generates README.md
130
- # /forerunner-check checks for doc drift
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
- ## Quick start (direct API mode)
134
-
135
- ```bash
136
- # 1. Install and configure
137
- pip install codeforerunner
138
- export ANTHROPIC_API_KEY=sk-...
101
+ ## GitHub Action
139
102
 
140
- # 2. Run a task
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
- # 3. Enable drift detection
144
- forerunner doctor --fix # writes forerunner.config.yaml
145
- forerunner check # run any time or as pre-commit hook
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
- ## GitHub Action
120
+ No-op when `forerunner.config.yaml` is absent — safe to add before configuring rules.
149
121
 
150
- ```yaml
151
- - uses: derek-palmer/codeforerunner@v0.4.2
152
- ```
122
+ **Inputs**
153
123
 
154
- No-op when `forerunner.config.yaml` is absent.
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
- provider: anthropic # anthropic | openai | google | ollama
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
- ## Providers
185
+ ## Prompt pack
214
186
 
215
- `forerunner generate` supports four providers. When no provider is explicitly configured and no API key is found, forerunner probes `localhost:11434` and falls back to Ollama automatically.
187
+ Prompts are bundled inside the package at `src/codeforerunner/prompts/`.
216
188
 
217
- | Provider | Env var | Default model |
218
- |----------|---------|---------------|
219
- | `anthropic` | `ANTHROPIC_API_KEY` | `claude-opus-4-7` |
220
- | `openai` | `OPENAI_API_KEY` | `gpt-4o` |
221
- | `google` | `GOOGLE_API_KEY` | `gemini-2.5-pro` |
222
- | `ollama` | `OLLAMA_HOST` (optional) | `llama3` |
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
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codeforerunner"
7
- version = "0.4.3"
7
+ version = "0.4.4"
8
8
  description = "Model-agnostic repository documentation tooling (prompt-first; thin CLI)."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
 
6
6
 
7
7
  def _package_prompts() -> Path:
8
+ """Return the path to the bundled prompts directory inside the package."""
8
9
  return Path(__file__).parent / "prompts"
9
10
 
10
11
 
@@ -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 cmd_generate(args: argparse.Namespace) -> int:
117
- """Resolve the bundle for <task> and send it to the configured provider.
118
-
119
- With --prompt-only (or when no provider/key/Ollama is reachable), outputs
120
- the assembled prompt bundle to stdout for the calling agent to process.
121
- """
122
- from codeforerunner import providers as _providers
123
- from codeforerunner.config import load_from_repo
124
-
125
- repo_root = Path(args.repo).resolve() if args.repo else Path.cwd()
126
- cfg = load_from_repo(repo_root)
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
- s_gen = sub.add_parser("generate", help="resolve bundle for <task> and call the configured provider")
274
- s_gen.add_argument("task", help="task basename under prompts/tasks/")
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)