You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ce301f4
Browse filesBrowse the repository at this point in the historyBrowse files
* feat: add --prompt-only flag and skill-mode auto-detect to forerunner generate
In skill mode (Claude Code, Codex, Gemini CLI, etc.) the host agent IS the
model — calling forerunner generate should output the assembled prompt bundle
for the agent to process, not make a provider API call.
Changes:
- `forerunner generate --prompt-only <task>`: outputs the assembled prompt
bundle to stdout and exits; no API key or provider needed. This is the
correct command for skill-mode use in all SKILL.md Execute sections.
- Auto-detect skill context: when no explicit provider is configured, no API
key is set, and Ollama is not running, cmd_generate now emits the prompt
bundle directly (exit 0) instead of erroring. On a TTY, adds a brief stderr
hint; on piped stdout, emits cleanly with no extra output.
- `forerunner doctor`: "no API key" is now [ok] when a managed skill
destination is installed (skill mode active) rather than [warn].
- All 26 per-task SKILL.md Execute sections updated:
`forerunner doc <task>` → `forerunner generate --prompt-only <task>`
- Canonical skill body (agent/codeforerunner.skill.md) updated with skill-mode
explanation and synced to both distribution copies.
- 194 tests pass (7 updated to reflect new behavior).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(doctor): always warn on missing provider key; hint --prompt-only in skill mode
doctor was returning [ok] when skill mode active + provider configured +
key missing. forerunner generate (without --prompt-only) still refuses to
run in that case, so the ok was misleading. Now always emits warn; appends
a --prompt-only hint when skill mode is detected so the user knows the
key-free path exists.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* security: fix H1-H3 + M1-M7 + L1-L9 from security review
H1: gate _load_script_module behind --run-scripts flag (off by default)
H2: pin npm/GitHub fallback to v0.4.1 in install.sh and install.ps1
H3: document Google API key-in-URL risk with comment in google.py
M1: fix enabled_rules YAML placement (root→tasks.check) in config and dogfood yaml
M2: validate MCP tools/call name against path traversal + resolve check
M3: eliminate thread-unsafe sys.stdout swap in cmd_generate; use _get_bundle()
M4: add timeout=120 to all provider urlopen calls
M5: fix dead any_error flag in install_all_skills; propagate write failures
M6: wrap int() in _to_int() raising ConfigError with descriptive message
M7: validate OLLAMA_HOST scheme and reject 169.254.* metadata endpoints
L1: replace assert in overlay() with RuntimeError
L2: remove unused output_dir/context_max_files/context_max_lines_per_file fields
L3: use UUID suffix in _load_script_module to prevent stale sys.modules cache
L4: use line-by-line read in _description_for instead of loading full file
L5: use direct dict access in format_report (drop redundant .get())
L6: enforce initialize-first in MCP server; return -32002 if skipped
L7: replace new RegExp(needle) with includes() in vscodeExtPresent/cursorExtPresent
L8: add test_generate_stream_flag_yields_chunks covering --stream branch
L9: limit find_prompts_root walk to 10 parent directories
Bump version to 0.4.2.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+27Lines changed: 27 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,33 @@ All notable changes to `codeforerunner` are documented here.
5
5
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
6
6
this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
8
+
## [Unreleased]
9
+
10
+
### Security
11
+
12
+
-**H1** — `forerunner doctor` no longer executes Python scripts from the target repo by default. Script-based checks (`skill-body-parity`, `codex-marketplace`) now emit `[warn] skipping script validation` unless `--run-scripts` is passed explicitly. (`doctor.py`, `cli.py`)
13
+
-**H2** — `install.sh` and `install.ps1` now pin the npm package to `codeforerunner@0.4.1` and the GitHub fallback to `github:derek-palmer/codeforerunner#v0.4.1`, preventing arbitrary code execution in `curl|bash` one-liner installs.
14
+
-**H3** — Added comment in `providers/google.py` documenting that the API key appears in the URL query string (Google REST API requirement; key may appear in proxy logs).
15
+
-**M2** — MCP server `tools/call` validates that the tool `name` contains no path separators or `..` components, and checks the resolved path is inside `prompts/tasks/` before executing. (`mcp_server.py`)
16
+
-**M7** — `OllamaProvider` and `is_available` now validate the base URL scheme (`http`/`https`) and reject `169.254.*` link-local addresses to prevent SSRF via `OLLAMA_HOST`. (`providers/ollama.py`)
17
+
18
+
### Fixed
19
+
20
+
-**M1** — `forerunner.config.yaml` and `_STARTER_CONFIG` in `doctor.py` had `enabled_rules` at the YAML root instead of under `tasks.check`. This was a functional bug causing the field to be silently ignored. Both the dogfood config and the `--fix` template are corrected.
21
+
-**M3** — `cmd_generate` no longer swaps `sys.stdout` globally (thread-unsafe). Bundle resolution now goes through `_get_bundle()` which returns a string directly. (`cli.py`)
22
+
-**M4** — All provider `urlopen` calls now pass `timeout=120` to prevent indefinite hangs. (`providers/anthropic.py`, `openai.py`, `google.py`, `ollama.py`)
23
+
-**M5** — `install_all_skills` now correctly sets `any_error = True` when a source file is missing or a write fails, so install failures propagate to the return code. (`installer.py`)
24
+
-**M6** — `int()` calls in `config.py` are now wrapped in `_to_int()` which raises `ConfigError` with a descriptive message instead of bare `ValueError`. (`config.py`)
25
+
-**L1** — Replaced `assert span is not None` in `overlay()` with `RuntimeError`. (`installer.py`)
26
+
-**L2** — Removed unused `output_dir`, `context_max_files`, `context_max_lines_per_file` fields from `ForerunnerConfig` and the YAML parser. (`config.py`)
27
+
-**L3** — `_load_script_module` now uses a UUID-suffixed module name to prevent stale cached modules on repeated calls. (`doctor.py`)
28
+
-**L4** — `_description_for` in MCP server now reads line-by-line instead of loading the entire file into memory. (`mcp_server.py`)
29
+
-**L5** — `format_report` uses direct dict access (`counts['ok']`) instead of redundant `.get()` calls. (`doctor.py`)
30
+
-**L6** — MCP server now enforces `initialize` as the first call; `tools/list` and `tools/call` before `initialize` return JSON-RPC error `-32002 Server not initialized`. (`mcp_server.py`)
31
+
-**L7** — `vscodeExtPresent` and `cursorExtPresent` in `bin/install.js` now use `includes()` instead of `new RegExp(needle)`, preventing extension ID metacharacters from being interpreted as regex. (`bin/install.js`)
32
+
-**L8** — Added unit test `test_generate_stream_flag_yields_chunks` covering the `--stream` branch of `cmd_generate`. (`tests/test_cli.py`)
33
+
-**L9** — `find_prompts_root` now stops walking after 10 parent directories to avoid traversing to the filesystem root. (`bundle.py`)
Copy file name to clipboardExpand all lines: agent/codeforerunner.skill.md
+7-5Lines changed: 7 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,9 @@ description: Routes a coding agent through the tracked codeforerunner prompt pac
7
7
8
8
The authoritative canonical source for this skill body is `agent/codeforerunner.skill.md` (see the `SPEC.md` I.agent-skill entry). Distribution copies are not independent sources; maintainers should edit the canonical file, then sync the post-frontmatter body into Codex and Claude copies. Downstream packages must preserve this post-frontmatter Markdown content verbatim (`SPEC.md` V10); per-agent YAML frontmatter may differ, but the body cannot.
9
9
10
-
This skill does not bundle a runtime. It routes the host agent into the codeforerunner prompt pack (`src/codeforerunner/prompts/` in the source repo, or retrieved via `forerunner doc <task>` from the installed CLI). The `forerunner` CLI, MCP server, pre-commit hook, CI workflow, and PyPI package are all live. Docker image and Makefile are not present.
10
+
This skill does not bundle a runtime. It routes the host agent into the codeforerunner prompt pack (`src/codeforerunner/prompts/` in the source repo, or retrieved via `forerunner generate --prompt-only <task>` from the installed CLI). The `forerunner` CLI, MCP server, pre-commit hook, CI workflow, and PyPI package are all live. Docker image and Makefile are not present.
11
+
12
+
**Skill mode:** When invoked via a host agent (Claude Code, Codex, Gemini CLI, etc.), the agent itself is the model — no API key or external provider is needed. Use `forerunner generate --prompt-only <task>` to output the assembled prompt bundle, then act on it directly. Reserve `forerunner generate <task>` (without `--prompt-only`) for standalone CLI use with a configured provider.
11
13
12
14
## When To Activate
13
15
@@ -40,7 +42,7 @@ If inputs are missing, the host agent may ask once **before starting** a task to
40
42
41
43
## Context Layers
42
44
43
-
These compose once into the prompt sent to the host model. They are not per-task steps. Retrieve each via `forerunner doc <task>` or read directly from `src/codeforerunner/prompts/`.
45
+
These compose once into the prompt sent to the host model. They are not per-task steps. Retrieve each via `forerunner generate --prompt-only <task>` or read directly from `src/codeforerunner/prompts/`.
44
46
45
47
-**System rules.**`system/base.md` — governing role and accuracy contract. Every output must obey it.
46
48
-**Context shape.**`partials/context-format.md` — target-repo context shape and file-selection rules.
@@ -51,11 +53,11 @@ These compose once into the prompt sent to the host model. They are not per-task
51
53
52
54
Per-run, in this order:
53
55
54
-
1.**Scan first.** Run `forerunner doc scan` (or use the `scan` task prompt directly) and capture its YAML output. All documentation-generation and check workflows depend on the scan result. **Exception:**`init-agent-onboarding` may run without a prior scan because it derives onboarding guidance directly from repo evidence and existing instruction files.
55
-
2.**Run the matching task prompt.** See `docs/prompt-guide.md` section 3 for the authoritative task → input → output table. Pick the task that matches the user's request and pass the scan result plus any task-specific inputs.
56
+
1.**Scan first.** Run `forerunner generate --prompt-only scan` and capture its YAML output. All documentation-generation and check workflows depend on the scan result. **Exception:**`init-agent-onboarding` may run without a prior scan because it derives onboarding guidance directly from repo evidence and existing instruction files.
57
+
2.**Run the matching task prompt.** See `docs/prompt-guide.md` section 3 for the authoritative task → input → output table. Run `forerunner generate --prompt-only <task>` to get the assembled prompt bundle, then execute it. Pass the scan result plus any task-specific inputs.
56
58
3.**Honor task output contracts.** When a task prompt specifies `<!-- output: path/to/file.md -->`, write the artifact to that path. When it does not, return Markdown for the user to place. Append a `## Gaps` section whenever evidence was insufficient — never silently invent content.
57
59
58
-
Call a provider directly with `forerunner generate <task>` (add `--stream` for token-by-token output). Check drift using`forerunner check`. Get a health report via `forerunner doctor`.
60
+
In skill mode the host agent handles generation — no API key needed. For standalone CLI use with a configured provider: `forerunner generate <task>` (add `--stream` for streaming). Check drift with`forerunner check`. Health report via `forerunner doctor`.
Copy file name to clipboardExpand all lines: plugins/codeforerunner/skills/codeforerunner/SKILL.md
+7-5Lines changed: 7 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,9 @@ description: Routes a coding agent through the tracked codeforerunner prompt pac
7
7
8
8
The authoritative canonical source for this skill body is `agent/codeforerunner.skill.md` (see the `SPEC.md` I.agent-skill entry). Distribution copies are not independent sources; maintainers should edit the canonical file, then sync the post-frontmatter body into Codex and Claude copies. Downstream packages must preserve this post-frontmatter Markdown content verbatim (`SPEC.md` V10); per-agent YAML frontmatter may differ, but the body cannot.
9
9
10
-
This skill does not bundle a runtime. It routes the host agent into the codeforerunner prompt pack (`src/codeforerunner/prompts/` in the source repo, or retrieved via `forerunner doc <task>` from the installed CLI). The `forerunner` CLI, MCP server, pre-commit hook, CI workflow, and PyPI package are all live. Docker image and Makefile are not present.
10
+
This skill does not bundle a runtime. It routes the host agent into the codeforerunner prompt pack (`src/codeforerunner/prompts/` in the source repo, or retrieved via `forerunner generate --prompt-only <task>` from the installed CLI). The `forerunner` CLI, MCP server, pre-commit hook, CI workflow, and PyPI package are all live. Docker image and Makefile are not present.
11
+
12
+
**Skill mode:** When invoked via a host agent (Claude Code, Codex, Gemini CLI, etc.), the agent itself is the model — no API key or external provider is needed. Use `forerunner generate --prompt-only <task>` to output the assembled prompt bundle, then act on it directly. Reserve `forerunner generate <task>` (without `--prompt-only`) for standalone CLI use with a configured provider.
11
13
12
14
## When To Activate
13
15
@@ -40,7 +42,7 @@ If inputs are missing, the host agent may ask once **before starting** a task to
40
42
41
43
## Context Layers
42
44
43
-
These compose once into the prompt sent to the host model. They are not per-task steps. Retrieve each via `forerunner doc <task>` or read directly from `src/codeforerunner/prompts/`.
45
+
These compose once into the prompt sent to the host model. They are not per-task steps. Retrieve each via `forerunner generate --prompt-only <task>` or read directly from `src/codeforerunner/prompts/`.
44
46
45
47
-**System rules.**`system/base.md` — governing role and accuracy contract. Every output must obey it.
46
48
-**Context shape.**`partials/context-format.md` — target-repo context shape and file-selection rules.
@@ -51,11 +53,11 @@ These compose once into the prompt sent to the host model. They are not per-task
51
53
52
54
Per-run, in this order:
53
55
54
-
1.**Scan first.** Run `forerunner doc scan` (or use the `scan` task prompt directly) and capture its YAML output. All documentation-generation and check workflows depend on the scan result. **Exception:**`init-agent-onboarding` may run without a prior scan because it derives onboarding guidance directly from repo evidence and existing instruction files.
55
-
2.**Run the matching task prompt.** See `docs/prompt-guide.md` section 3 for the authoritative task → input → output table. Pick the task that matches the user's request and pass the scan result plus any task-specific inputs.
56
+
1.**Scan first.** Run `forerunner generate --prompt-only scan` and capture its YAML output. All documentation-generation and check workflows depend on the scan result. **Exception:**`init-agent-onboarding` may run without a prior scan because it derives onboarding guidance directly from repo evidence and existing instruction files.
57
+
2.**Run the matching task prompt.** See `docs/prompt-guide.md` section 3 for the authoritative task → input → output table. Run `forerunner generate --prompt-only <task>` to get the assembled prompt bundle, then execute it. Pass the scan result plus any task-specific inputs.
56
58
3.**Honor task output contracts.** When a task prompt specifies `<!-- output: path/to/file.md -->`, write the artifact to that path. When it does not, return Markdown for the user to place. Append a `## Gaps` section whenever evidence was insufficient — never silently invent content.
57
59
58
-
Call a provider directly with `forerunner generate <task>` (add `--stream` for token-by-token output). Check drift using`forerunner check`. Get a health report via `forerunner doctor`.
60
+
In skill mode the host agent handles generation — no API key needed. For standalone CLI use with a configured provider: `forerunner generate <task>` (add `--stream` for streaming). Check drift with`forerunner check`. Health report via `forerunner doctor`.
Copy file name to clipboardExpand all lines: plugins/codeforerunner/skills/forerunner-api-docs/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ User asks to: document the API, generate API reference, write endpoint docs, cre
21
21
22
22
## Execute
23
23
24
-
Run `forerunner doc api-docs`to compose the full prompt with system rules, then execute it.
24
+
Run `forerunner generate --prompt-only api-docs`— outputs the assembled prompt bundle to stdout. Read this output and execute the documentation task it describes.
0 commit comments