mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 12:28:06 +08:00
* feat(dev): add integration scaffolder * fix(dev): address integration scaffold review feedback * fix(dev): address scaffold follow-up review * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix(dev): default scaffolded integrations to multi_install_safe = False The scaffold template emitted `multi_install_safe = True` alongside a placeholder `context_file = "AGENTS.md"`. Registered as-is, that violates the registry contract (test_safe_integrations_have_distinct_context_files): codex already pairs AGENTS.md with multi_install_safe = True, so the generated boilerplate would collide on first registration. Default the scaffold to False (matching IntegrationBase) so generated code is registry-test-friendly out of the box; contributors opt in once they pick a unique context_file. Aligns the generated test skeleton and both scaffold tests, which previously contradicted each other (one expected True, one False). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(dev): harden scaffold writes and accept case-insensitive --type - Guard scaffold_integration() against symlinked target directories: walk each path component under the repo root and refuse symlinked dirs, then confirm the write destination resolves inside the repo (mirrors the manifest directory guard). Prevents scaffolding outside the repo when a contributor's integrations/tests path is symlinked. - Make the `--type` click.Choice case-insensitive so `--type YAML` is accepted, matching scaffold_integration()'s strip()/lower() normalization instead of rejecting at the CLI layer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(dev): report scaffold filesystem failures as a clean CLI error The `dev integration scaffold` command only caught FileExistsError/ValueError, so an OSError raised during mkdir()/write_text() (permission denied, read-only checkout, a path component that is a file, ...) bubbled up as a traceback instead of a clean error + exit code. Broaden the handler to OSError (which also covers FileExistsError) and add coverage for the filesystem-error path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(dev): move scaffold command under integration * fix(dev): roll back partial scaffold writes * fix(dev): correct lint docs and generated test docstring - local-development.md: ruff check src/ is enforced in CI, not absent - scaffolded test docstring: drop misleading 'scaffold' wording * fix(scaffold): create only leaf integration directory --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
200 lines
5.8 KiB
Markdown
200 lines
5.8 KiB
Markdown
# Local Development Guide
|
|
|
|
This guide shows how to iterate on the `specify` CLI locally without publishing a release or committing to `main` first.
|
|
|
|
> Scripts now have both Bash (`.sh`) and PowerShell (`.ps1`) variants. The CLI auto-selects based on OS unless you pass `--script sh|ps`.
|
|
|
|
## 1. Clone and Switch Branches
|
|
|
|
```bash
|
|
git clone https://github.com/github/spec-kit.git
|
|
cd spec-kit
|
|
# Work on a feature branch
|
|
git checkout -b your-feature-branch
|
|
```
|
|
|
|
## 2. Run the CLI Directly (Fastest Feedback)
|
|
|
|
You can execute the CLI via the module entrypoint without installing anything:
|
|
|
|
```bash
|
|
# From repo root
|
|
python -m src.specify_cli --help
|
|
python -m src.specify_cli init demo-project --integration claude --ignore-agent-tools --script sh
|
|
```
|
|
|
|
If you prefer invoking the script file style (uses shebang):
|
|
|
|
```bash
|
|
python src/specify_cli/__init__.py init demo-project --script ps
|
|
```
|
|
|
|
## 3. Use Editable Install (Isolated Environment)
|
|
|
|
Create an isolated environment using `uv` so dependencies resolve exactly like end users get them:
|
|
|
|
```bash
|
|
# Create & activate virtual env (uv auto-manages .venv)
|
|
uv venv
|
|
source .venv/bin/activate # or on Windows PowerShell: .venv\Scripts\Activate.ps1
|
|
|
|
# Install project in editable mode
|
|
uv pip install -e .
|
|
|
|
# Now 'specify' entrypoint is available
|
|
specify --help
|
|
```
|
|
|
|
Re-running after code edits requires no reinstall because of editable mode.
|
|
|
|
## 4. Invoke with uvx Directly From Git (Current Branch)
|
|
|
|
`uvx` can run from a local path (or a Git ref) to simulate user flows:
|
|
|
|
```bash
|
|
uvx --from . specify init demo-uvx --integration copilot --ignore-agent-tools --script sh
|
|
```
|
|
|
|
You can also point uvx at a specific branch without merging:
|
|
|
|
```bash
|
|
# Push your working branch first
|
|
git push origin your-feature-branch
|
|
uvx --from git+https://github.com/github/spec-kit.git@your-feature-branch specify init demo-branch-test --script ps
|
|
```
|
|
|
|
### 4a. Absolute Path uvx (Run From Anywhere)
|
|
|
|
If you're in another directory, use an absolute path instead of `.`:
|
|
|
|
```bash
|
|
uvx --from /mnt/c/GitHub/spec-kit specify --help
|
|
uvx --from /mnt/c/GitHub/spec-kit specify init demo-anywhere --integration copilot --ignore-agent-tools --script sh
|
|
```
|
|
|
|
Set an environment variable for convenience:
|
|
|
|
```bash
|
|
export SPEC_KIT_SRC=/mnt/c/GitHub/spec-kit
|
|
uvx --from "$SPEC_KIT_SRC" specify init demo-env --integration copilot --ignore-agent-tools --script ps
|
|
```
|
|
|
|
(Optional) Define a shell function:
|
|
|
|
```bash
|
|
specify-dev() { uvx --from /mnt/c/GitHub/spec-kit specify "$@"; }
|
|
# Then
|
|
specify-dev --help
|
|
```
|
|
|
|
## 5. Testing Script Permission Logic
|
|
|
|
After running an `init`, check that shell scripts are executable on POSIX systems:
|
|
|
|
```bash
|
|
ls -l scripts | grep .sh
|
|
# Expect owner execute bit (e.g. -rwxr-xr-x)
|
|
```
|
|
|
|
On Windows you will instead use the `.ps1` scripts (no chmod needed).
|
|
|
|
## 6. Scaffold a Built-In Integration
|
|
|
|
Use the integration scaffold command to create the initial Python package and
|
|
test skeleton for a new built-in integration:
|
|
|
|
```bash
|
|
specify integration scaffold my-agent --type markdown
|
|
specify integration scaffold my-agent --type toml
|
|
specify integration scaffold my-agent --type yaml
|
|
specify integration scaffold my-agent --type skills
|
|
```
|
|
|
|
Hyphenated keys are converted to Python-safe package names, for example
|
|
`my-agent` creates `src/specify_cli/integrations/my_agent/` and
|
|
`tests/integrations/test_integration_my_agent.py`.
|
|
|
|
The scaffold does not register the integration automatically. Review the
|
|
generated metadata, then add the import and `_register()` call in
|
|
`src/specify_cli/integrations/__init__.py`.
|
|
|
|
## 7. Run Lint / Basic Checks
|
|
|
|
CI enforces `ruff check src/` (see `.github/workflows/test.yml`), so run it locally before pushing:
|
|
|
|
```bash
|
|
uvx ruff check src/
|
|
```
|
|
|
|
You can also quickly sanity check importability:
|
|
|
|
```bash
|
|
python -c "import specify_cli; print('Import OK')"
|
|
```
|
|
|
|
## 8. Build a Wheel Locally (Optional)
|
|
|
|
Validate packaging before publishing:
|
|
|
|
```bash
|
|
uv build
|
|
ls dist/
|
|
```
|
|
|
|
Install the built artifact into a fresh throwaway environment if needed.
|
|
|
|
## 9. Using a Temporary Workspace
|
|
|
|
When testing `init --here` in a dirty directory, create a temp workspace:
|
|
|
|
```bash
|
|
mkdir /tmp/spec-test && cd /tmp/spec-test
|
|
python -m src.specify_cli init --here --integration claude --ignore-agent-tools --script sh # if repo copied here
|
|
```
|
|
|
|
Or copy only the modified CLI portion if you want a lighter sandbox.
|
|
|
|
## 10. Debug Network / TLS Issues
|
|
|
|
> **Deprecated:** The `--skip-tls` flag is a no-op and has no effect.
|
|
> It was previously used to bypass TLS validation during local testing.
|
|
> If you encounter TLS errors (e.g., on a corporate network), configure your
|
|
> environment's certificate store or proxy instead.
|
|
>
|
|
> For example, set `SSL_CERT_FILE` or configure `HTTPS_PROXY` / `HTTP_PROXY`.
|
|
|
|
## 11. Rapid Edit Loop Summary
|
|
|
|
| Action | Command |
|
|
|--------|---------|
|
|
| Run CLI directly | `python -m src.specify_cli --help` |
|
|
| Editable install | `uv pip install -e .` then `specify ...` |
|
|
| Local uvx run (repo root) | `uvx --from . specify ...` |
|
|
| Local uvx run (abs path) | `uvx --from /mnt/c/GitHub/spec-kit specify ...` |
|
|
| Git branch uvx | `uvx --from git+URL@branch specify ...` |
|
|
| Build wheel | `uv build` |
|
|
|
|
## 12. Cleaning Up
|
|
|
|
Remove build artifacts / virtual env quickly:
|
|
|
|
```bash
|
|
rm -rf .venv dist build *.egg-info
|
|
```
|
|
|
|
## 13. Common Issues
|
|
|
|
| Symptom | Fix |
|
|
|---------|-----|
|
|
| `ModuleNotFoundError: typer` | Run `uv pip install -e .` |
|
|
| Scripts not executable (Linux) | Re-run init or `chmod +x scripts/*.sh` |
|
|
| Git commands unavailable | Install the git extension with `specify extension add git` |
|
|
| Wrong script type downloaded | Pass `--script sh` or `--script ps` explicitly |
|
|
| TLS errors on corporate network | Configure your environment's certificate store or proxy. The `--skip-tls` flag is deprecated and has no effect. |
|
|
|
|
## 14. Next Steps
|
|
|
|
- Update docs and run through Quick Start using your modified CLI
|
|
- Open a PR when satisfied
|
|
- (Optional) Tag a release once changes land in `main`
|