Add `markitect helper <QUESTION>` CLI command that answers questions about markitect using its own documentation as LLM context. Uses OpenRouter with openrouter/aurora-alpha by default; model is configurable via --model flag or MARKITECT_HELPER_MODEL env var. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
4.4 KiB
Markdown
96 lines
4.4 KiB
Markdown
# Plan: `markitect helper` CLI Command
|
|
|
|
## Context
|
|
|
|
Add an interactive Q&A facility to markitect that answers questions about markitect itself using its own documentation as knowledge context. Uses the existing LLM adapter infrastructure with OpenRouter and `openrouter/aurora-alpha` as default.
|
|
|
|
## New Files
|
|
|
|
### 1. `markitect/helper/__init__.py`
|
|
Empty package init.
|
|
|
|
### 2. `markitect/helper/knowledge.py` — Knowledge Loader
|
|
|
|
- `collect_knowledge() -> str` function that:
|
|
- Finds markitect's documentation directory relative to the package root (`Path(__file__).resolve().parent.parent.parent`)
|
|
- Reads key markdown files in priority order:
|
|
1. `INTRODUCTION.md`
|
|
2. `docs/CLI_TUTORIAL.md`
|
|
3. `docs/PROJECT_STRUCTURE.md`
|
|
4. `docs/SCHEMA_MANAGEMENT_GUIDE.md`
|
|
5. `docs/PLUGIN_SYSTEM.md`
|
|
6. `docs/ERROR_HANDLING_STRATEGY.md`
|
|
7. `docs/architecture/CAPABILITIES_ARCHITECTURE.md`
|
|
8. `docs/architecture/caching-system.md`
|
|
9. `docs/user-guides/*.md` (all files)
|
|
10. `examples/content-generator/TUTORIAL.md`
|
|
11. `examples/infospace-with-history/TUTORIAL.md`
|
|
12. Module docstrings from `markitect/prompts/__init__.py` and `markitect/llm/__init__.py`
|
|
- Concatenates with `## <filename>` section headers between each doc
|
|
- Skips missing files gracefully (log warning if verbose)
|
|
- Returns the combined knowledge string
|
|
|
|
### 3. `markitect/helper/cli.py` — Click Command
|
|
|
|
```python
|
|
@click.command("helper")
|
|
@click.argument("question", nargs=-1, required=True) # accepts multi-word questions without quotes
|
|
@click.option("--provider", "-p", default="openrouter",
|
|
type=click.Choice(["openrouter", "claude-code", "gemini", "openai"]),
|
|
help="LLM provider")
|
|
@click.option("--model", "-m", default=None,
|
|
help="Model name (overrides MARKITECT_HELPER_MODEL env var and default)")
|
|
```
|
|
|
|
Logic:
|
|
1. Join `question` tuple into a single string
|
|
2. Resolve model: CLI `--model` flag → `MARKITECT_HELPER_MODEL` env var → `openrouter/aurora-alpha`
|
|
3. Call `collect_knowledge()` to build the knowledge context
|
|
4. Build system prompt: `"You are a markitect expert assistant. Answer questions based on the following markitect documentation:\n\n{knowledge}"`
|
|
5. Call `create_adapter(provider, model=model, system_prompt=system_prompt)`
|
|
6. Call `adapter.execute_prompt(question, RunConfig(max_tokens=4000, temperature=0.3))`
|
|
7. Print `response.content` to stdout
|
|
8. Handle errors: `LLMConfigurationError` → helpful message about API key, other `LLMError` → stderr message
|
|
|
|
## Modified Files
|
|
|
|
### 4. `markitect/cli.py` — Register the Command
|
|
|
|
At the bottom with the other `cli.add_command()` calls, add:
|
|
|
|
```python
|
|
try:
|
|
from markitect.helper.cli import helper_command
|
|
cli.add_command(helper_command)
|
|
except ImportError:
|
|
pass # Helper module not available
|
|
```
|
|
|
|
This follows the existing pattern used for prompts, finance, etc.
|
|
|
|
## Configuration
|
|
|
|
- **Default provider**: `openrouter`
|
|
- **Default model**: `openrouter/aurora-alpha`
|
|
- **Environment variable**: `MARKITECT_HELPER_MODEL` — overrides the default model
|
|
- **CLI flag**: `--model` / `-m` — overrides both env var and default
|
|
- **Precedence**: `--model` flag > `MARKITECT_HELPER_MODEL` env var > `openrouter/aurora-alpha`
|
|
|
|
## Key Reference Files
|
|
|
|
- `markitect/cli.py` — main CLI (Click-based, `@cli.command()` pattern, register via `cli.add_command()`)
|
|
- `markitect/llm/factory.py` — `create_adapter(provider, model, api_key, system_prompt)`
|
|
- `markitect/llm/openrouter.py` — OpenRouterAdapter (default)
|
|
- `markitect/prompts/execution/models.py` — `RunConfig`, `LLMResponse`
|
|
- `markitect/prompts/execution/llm_adapter.py` — `LLMAdapter` base class (method: `execute_prompt(prompt, config) -> LLMResponse`)
|
|
- `markitect/llm/exceptions.py` — `LLMError`, `LLMConfigurationError`, `LLMAPIError`, `LLMRateLimitError`
|
|
- API key resolution: env var `OPENROUTER_API_KEY` or file `apikey-openrouter.txt` in project root
|
|
|
|
## Verification
|
|
|
|
1. `markitect helper "What is markitect?"` — should return a knowledge-based answer
|
|
2. `markitect helper --model anthropic/claude-sonnet-4 "How do schemas work?"` — uses different model
|
|
3. `MARKITECT_HELPER_MODEL=google/gemini-2.5-flash markitect helper "What are templates?"` — env var override
|
|
4. `markitect helper --provider claude-code "Explain the plugin system"` — uses Claude CLI
|
|
5. `markitect helper --help` — shows usage with all options
|