Skip to content

Commit 000481b

Browse files
committed
Merge origin/main into security audit workflow
2 parents 181cd61 + ac2cb5d commit 000481b

20 files changed

Lines changed: 4040 additions & 146 deletions

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,24 @@ specify init my-project --integration copilot
5959
cd my-project
6060
```
6161

62+
To check for updates or upgrade the installed CLI, use the self-management commands. See the [Upgrade Guide](./docs/upgrade.md) for detailed scenarios and customization options.
63+
64+
```bash
65+
# Check whether a newer release is available (read-only — does not modify anything)
66+
specify self check
67+
68+
# Preview what would run, without actually upgrading
69+
specify self upgrade --dry-run
70+
71+
# Upgrade in place to the latest stable release (auto-detects uv tool vs pipx install)
72+
specify self upgrade
73+
74+
# Or pin a specific release tag (replace vX.Y.Z[suffix] with your desired release tag)
75+
specify self upgrade --tag vX.Y.Z[suffix]
76+
```
77+
78+
Bare `specify self upgrade` executes immediately, matching the no-prompt behavior of commands like `pip install -U` and `npm update`. For `uv tool` installs, it runs `uv tool install specify-cli --force --from <git ref>` under the hood so pinned release tags work, including dev, alpha/beta/rc, or build metadata suffixes. `uvx` (ephemeral) runs and source checkouts are detected and produce path-specific guidance instead of running an installer. Set `SPECIFY_UPGRADE_TIMEOUT_SECS` to cap how long the installer subprocess may run (default: no timeout — interrupt with `Ctrl+C` if needed).
79+
6280
### 3. Establish project principles
6381

6482
Launch your coding agent in the project directory. Most agents expose spec-kit as `/speckit.*` slash commands; Codex CLI in skills mode uses `$speckit-*` instead.
@@ -133,7 +151,7 @@ Run `specify integration list` to see all available integrations in your install
133151

134152
After running `specify init`, your AI coding agent will have access to these slash commands for structured development. For integrations that support skills mode, passing `--integration <agent> --integration-options="--skills"` installs agent skills instead of slash-command prompt files.
135153

136-
#### Core Commands
154+
### Core Commands
137155

138156
Essential commands for the Spec-Driven Development workflow:
139157

@@ -146,7 +164,7 @@ Essential commands for the Spec-Driven Development workflow:
146164
| `/speckit.taskstoissues` | `speckit-taskstoissues`| Convert generated task lists into GitHub issues for tracking and execution |
147165
| `/speckit.implement` | `speckit-implement` | Execute all tasks to build the feature according to the plan |
148166

149-
#### Optional Commands
167+
### Optional Commands
150168

151169
Additional commands for enhanced quality and validation:
152170

docs/community/extensions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ The following community-contributed extensions are available in [`catalog.commun
114114
| Staff Review Extension | Staff-engineer-level code review that validates implementation against spec, checks security, performance, and test coverage | `code` | Read-only | [spec-kit-staff-review](https://github.com/arunt14/spec-kit-staff-review) |
115115
| Status Report | Project status, feature progress, and next-action recommendations for spec-driven workflows | `visibility` | Read-only | [Open-Agent-Tools/spec-kit-status](https://github.com/Open-Agent-Tools/spec-kit-status) |
116116
| Superpowers Bridge | Orchestrates obra/superpowers skills within the spec-kit SDD workflow across the full lifecycle (clarification, TDD, review, verification, critique, debugging, branch completion) | `process` | Read+Write | [superpowers-bridge](https://github.com/RbBtSn0w/spec-kit-extensions/tree/main/superpowers-bridge) |
117-
| Superpowers Bridge (WangX0111) | Bridges spec-kit with obra/superpowers (brainstorming, TDD, subagent, code-review) into a unified, resumable workflow with graceful degradation and session progress tracking | `process` | Read+Write | [superspec](https://github.com/WangX0111/superspec) |
118117
| Superpowers Implementation Bridge | Thin orchestrator between Spec Kit (design) and Superpowers (implementation). Cross-agent. | `process` | Read+Write | [speckit-superpowers-bridge](https://github.com/lihan3238/speckit-superpowers-bridge) |
118+
| Superspec | Bridges spec-kit with obra/superpowers (brainstorming, TDD, subagent, code-review) into a unified, resumable workflow with graceful degradation and session progress tracking | `process` | Read+Write | [superspec](https://github.com/WangX0111/superspec) |
119119
| Team Assign | Assign tasks.md items to human engineers, split into subtasks, and generate a per-engineer workboard | `process` | Read+Write | [spec-kit-team-assign](https://github.com/tarunkumarbhati/spec-kit-team-assign) |
120120
| Time Machine | Retroactively apply the full SDD workflow to existing codebases — analyse, spec, and ship feature-by-feature | `process` | Read+Write | [spec-kit-time-machine](https://github.com/teeyo/spec-kit-time-machine) |
121121
| TinySpec | Lightweight single-file workflow for small tasks — skip the heavy multi-step SDD process | `process` | Read+Write | [spec-kit-tinyspec](https://github.com/Quratulain-bilal/spec-kit-tinyspec) |

docs/installation.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ specify version
8888

8989
This helps verify you are running the official Spec Kit build from GitHub, not an unrelated package with the same name.
9090

91+
**Stay current:** Run `specify self check` periodically to learn whether a newer release is available — it is read-only and never modifies your installation. When you are ready to upgrade, follow the [Upgrade Guide](./upgrade.md).
92+
9193
After initialization, you should see the following commands available in your coding agent:
9294

9395
- `/speckit.specify` - Create specifications

docs/reference/workflows.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,18 @@ specify workflow run speckit -i spec="Build a kanban board with drag-and-drop ta
2828
specify workflow resume <run_id>
2929
```
3030

31+
| Option | Description |
32+
| ------------------- | -------------------------------------------------------- |
33+
| `-i` / `--input` | Updated input values as `key=value` (repeatable) |
34+
3135
Resumes a paused or failed workflow run from the exact step where it stopped. Useful after responding to a gate step or fixing an issue that caused a failure.
3236

37+
Supplied `--input` values are merged over the run's stored inputs and re-validated against the workflow's input types, then the blocked step is re-run with the updated values. This lets a run continue with information that only became available after it paused, or with a corrected value after a failure:
38+
39+
```bash
40+
specify workflow resume <run_id> --input cmd="exit 0"
41+
```
42+
3343
## Workflow Status
3444

3545
```bash

docs/upgrade.md

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88

99
| What to Upgrade | Command | When to Use |
1010
|----------------|---------|-------------|
11-
| **CLI Tool Only** | `uv tool install specify-cli --force --from git+https://github.com/github/spec-kit.git@vX.Y.Z` | Get latest CLI features without touching project files |
12-
| **CLI Tool Only (pipx)** | `pipx install --force git+https://github.com/github/spec-kit.git@vX.Y.Z` | Reinstall/upgrade a pipx-installed CLI to a specific release |
11+
| **CLI Tool (recommended)** | `specify self upgrade` | Latest stable release, in place. Auto-detects whether you installed via `uv tool` or `pipx`. |
12+
| **CLI Tool — pin a version** | `specify self upgrade --tag vX.Y.Z[suffix]` | Upgrade to a specific release tag instead of the latest stable. Suffixes are limited to dev, alpha/beta/rc, and/or build metadata forms. |
13+
| **CLI Tool — manual fallback** | `uv tool install specify-cli --force --from git+https://github.com/github/spec-kit.git@vX.Y.Z` | When `specify self upgrade` isn't available (older installs) or when you want explicit control. |
14+
| **CLI Tool — manual fallback (pipx)** | `pipx install --force git+https://github.com/github/spec-kit.git@vX.Y.Z` | Same as above, for pipx installs. |
1315
| **Project Files** | `specify init --here --force --integration <your-agent>` | Update slash commands, templates, and scripts in your project |
1416
| **Both** | Run CLI upgrade, then project update | Recommended for major version updates |
1517

@@ -19,12 +21,32 @@
1921

2022
The CLI tool (`specify`) is separate from your project files. Upgrade it to get the latest features and bug fixes.
2123

22-
Before upgrading, you can check whether a newer released version is available:
24+
### Recommended: `specify self upgrade`
25+
26+
The CLI ships with two self-management commands that handle the common case automatically:
2327

2428
```bash
29+
# Check whether a newer release is available (read-only — does not modify anything)
2530
specify self check
31+
32+
# Preview what would run, without actually upgrading
33+
specify self upgrade --dry-run
34+
35+
# Upgrade in place to the latest stable release (auto-detects uv tool vs pipx install)
36+
specify self upgrade
37+
38+
# Or pin a specific release tag (replace vX.Y.Z[suffix] with the tag you want)
39+
specify self upgrade --tag vX.Y.Z[suffix]
2640
```
2741

42+
Bare `specify self upgrade` executes immediately, matching the no-prompt behavior of commands like `pip install -U` and `npm update`. The CLI classifies your runtime into one of: `uv tool`, `pipx`, `uvx (ephemeral)`, source checkout, or unsupported. Only `uv tool` and `pipx` are upgraded automatically; for `uv tool` installs, it runs `uv tool install specify-cli --force --from <git ref>` under the hood so pinned release tags work. The other paths print path-specific guidance and exit 0 without touching anything.
43+
44+
Pinned tags must start with `vMAJOR.MINOR.PATCH`. Optional suffixes are limited to dev, alpha/beta/rc, and/or build metadata forms such as `v1.0.0-rc1`, `v0.8.0.dev0`, `v0.8.0+build.42`, or the combination `v1.0.0-rc1+build.42`; branch names, hash refs, `latest`, and bare versions without `v` are rejected.
45+
46+
Set `SPECIFY_UPGRADE_TIMEOUT_SECS` to cap how long the installer subprocess may run (default: no timeout — interrupt with `Ctrl+C` if needed). If that internal timeout fires, `specify self upgrade` exits 124 and reports that it timed out while waiting for the installer subprocess, including the configured timeout and manual retry command. A real installer exit code 124 is propagated with `Upgrade failed. Installer exit code: 124.`, so scripts should treat exit 124 as ambiguous and inspect the message when they need to distinguish the two cases.
47+
48+
If your installed CLI is older than the release that introduced `specify self upgrade`, use the manual equivalents below. These commands are also useful when you want explicit control over the installer command.
49+
2850
### If you installed with `uv tool install`
2951

3052
Upgrade to a specific release (check [Releases](https://github.com/github/spec-kit/releases) for the latest tag):
@@ -54,10 +76,14 @@ pipx install --force git+https://github.com/github/spec-kit.git@vX.Y.Z
5476
### Verify the upgrade
5577

5678
```bash
79+
# Confirms the CLI is working and shows installed tools
5780
specify check
81+
82+
# Confirms the installed version against the latest GitHub release
83+
specify self check
5884
```
5985

60-
This shows installed tools and confirms the CLI is working. Use `specify version` to confirm which persistent CLI version is currently on your `PATH`.
86+
`specify check` shows the surrounding tool environment; `specify self check` is read-only and tells you whether you're now on the latest release (`Up to date: X.Y.Z`) or if a newer one became available between releases.
6187

6288
---
6389

@@ -186,8 +212,8 @@ Restart your IDE to refresh the command list.
186212
### Scenario 1: "I just want new slash commands"
187213

188214
```bash
189-
# Upgrade CLI (if using persistent install)
190-
uv tool install specify-cli --force --from git+https://github.com/github/spec-kit.git
215+
# Upgrade CLI (auto-detects uv tool vs pipx install)
216+
specify self upgrade
191217

192218
# Update project files to get new commands
193219
specify init --here --force --integration copilot
@@ -204,7 +230,7 @@ cp .specify/memory/constitution.md /tmp/constitution-backup.md
204230
cp -r .specify/templates /tmp/templates-backup
205231

206232
# 2. Upgrade CLI
207-
uv tool install specify-cli --force --from git+https://github.com/github/spec-kit.git
233+
specify self upgrade
208234

209235
# 3. Update project
210236
specify init --here --force --integration copilot
@@ -388,15 +414,19 @@ Only Spec Kit infrastructure files:
388414

389415
### "CLI upgrade doesn't seem to work"
390416

391-
If a command behaves like an older Spec Kit version, first check for local CLI drift:
417+
If a command behaves like an older Spec Kit version, first ask the CLI itself:
392418

393419
```bash
420+
# Read-only — prints "Up to date: X.Y.Z" or "Update available: X.Y.Z → vY.Z.W"
394421
specify self check
422+
423+
# Preview the install method, current version, and target tag the upgrade would use
424+
specify self upgrade --dry-run
395425
```
396426

397427
`specify check` is an offline environment scan; `specify self check` is the CLI version lookup.
398428

399-
Verify the installation:
429+
If `self check` shows the wrong version, verify the installation:
400430

401431
```bash
402432
# Check installed tools

extensions/catalog.community.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3039,13 +3039,13 @@
30393039
"created_at": "2026-03-30T00:00:00Z",
30403040
"updated_at": "2026-05-24T01:07:34Z"
30413041
},
3042-
"superpowers-bridge": {
3043-
"name": "Superpowers Bridge",
3044-
"id": "superpowers-bridge",
3042+
"superspec": {
3043+
"name": "Superspec",
3044+
"id": "superspec",
30453045
"description": "Bridges spec-kit workflows with obra/superpowers capabilities for brainstorming, TDD, code review, and resumable execution.",
30463046
"author": "WangX0111",
3047-
"version": "1.0.0",
3048-
"download_url": "https://github.com/WangX0111/superspec/archive/refs/tags/v1.0.0.zip",
3047+
"version": "1.0.1",
3048+
"download_url": "https://github.com/WangX0111/superspec/archive/refs/tags/v1.0.1.zip",
30493049
"repository": "https://github.com/WangX0111/superspec",
30503050
"homepage": "https://github.com/WangX0111/superspec",
30513051
"documentation": "https://github.com/WangX0111/superspec/blob/main/README.md",
@@ -3070,7 +3070,7 @@
30703070
"downloads": 0,
30713071
"stars": 0,
30723072
"created_at": "2026-04-22T00:00:00Z",
3073-
"updated_at": "2026-04-22T00:00:00Z"
3073+
"updated_at": "2026-05-30T00:00:00Z"
30743074
},
30753075
"sync": {
30763076
"name": "Spec Sync",
@@ -3607,4 +3607,4 @@
36073607
"updated_at": "2026-04-13T00:00:00Z"
36083608
}
36093609
}
3610-
}
3610+
}

src/specify_cli/__init__.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2744,6 +2744,22 @@ def extension_set_priority(
27442744
workflow_app.add_typer(workflow_catalog_app, name="catalog")
27452745

27462746

2747+
def _parse_input_values(input_values: list[str] | None) -> dict[str, Any]:
2748+
"""Parse repeated ``key=value`` CLI inputs into a dict.
2749+
2750+
Shared by ``workflow run`` and ``workflow resume``. Exits with an error
2751+
on any entry missing ``=``.
2752+
"""
2753+
inputs: dict[str, Any] = {}
2754+
for kv in input_values or []:
2755+
if "=" not in kv:
2756+
console.print(f"[red]Error:[/red] Invalid input format: {kv!r} (expected key=value)")
2757+
raise typer.Exit(1)
2758+
key, _, value = kv.partition("=")
2759+
inputs[key.strip()] = value.strip()
2760+
return inputs
2761+
2762+
27472763
@workflow_app.command("run")
27482764
def workflow_run(
27492765
source: str = typer.Argument(..., help="Workflow ID or YAML file path"),
@@ -2776,14 +2792,7 @@ def workflow_run(
27762792
raise typer.Exit(1)
27772793

27782794
# Parse inputs
2779-
inputs: dict[str, Any] = {}
2780-
if input_values:
2781-
for kv in input_values:
2782-
if "=" not in kv:
2783-
console.print(f"[red]Error:[/red] Invalid input format: {kv!r} (expected key=value)")
2784-
raise typer.Exit(1)
2785-
key, _, value = kv.partition("=")
2786-
inputs[key.strip()] = value.strip()
2795+
inputs = _parse_input_values(input_values)
27872796

27882797
console.print(f"\n[bold cyan]Running workflow:[/bold cyan] {definition.name} ({definition.id})")
27892798
console.print(f"[dim]Version: {definition.version}[/dim]\n")
@@ -2814,6 +2823,9 @@ def workflow_run(
28142823
@workflow_app.command("resume")
28152824
def workflow_resume(
28162825
run_id: str = typer.Argument(..., help="Run ID to resume"),
2826+
input_values: list[str] | None = typer.Option(
2827+
None, "--input", "-i", help="Updated input values as key=value pairs"
2828+
),
28172829
):
28182830
"""Resume a paused or failed workflow run."""
28192831
from .workflows.engine import WorkflowEngine
@@ -2822,8 +2834,10 @@ def workflow_resume(
28222834
engine = WorkflowEngine(project_root)
28232835
engine.on_step_start = lambda sid, label: console.print(f" \u25b8 [{sid}] {label} \u2026")
28242836

2837+
inputs = _parse_input_values(input_values)
2838+
28252839
try:
2826-
state = engine.resume(run_id)
2840+
state = engine.resume(run_id, inputs or None)
28272841
except FileNotFoundError:
28282842
console.print(f"[red]Error:[/red] Run not found: {run_id}")
28292843
raise typer.Exit(1)
@@ -3352,6 +3366,17 @@ def workflow_catalog_remove(
33523366

33533367

33543368
def main():
3369+
# On Windows the default stdout/stderr code page (e.g. cp1252) cannot encode
3370+
# the Rich banner and box-drawing glyphs, so the CLI crashes with
3371+
# UnicodeEncodeError whenever output is not a UTF-8 TTY (piped, redirected to
3372+
# a file, or running under a legacy code page). Force UTF-8 with graceful
3373+
# replacement so output degrades instead of aborting. No-op on POSIX.
3374+
if sys.platform == "win32":
3375+
for _stream in (sys.stdout, sys.stderr):
3376+
try:
3377+
_stream.reconfigure(encoding="utf-8", errors="replace")
3378+
except (AttributeError, ValueError, OSError):
3379+
pass
33553380
app()
33563381

33573382
if __name__ == "__main__":

0 commit comments

Comments
 (0)