Skip to content

Commit 044e79a

Browse files
authored
Merge remote-tracking branch 'origin/main' into add-gates-extension-15a986e3d153da1e
# Conflicts: # extensions/catalog.community.json
2 parents 6ef83f2 + 9d96c62 commit 044e79a

22 files changed

Lines changed: 510 additions & 66 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
<!-- insert new changelog below this comment -->
44

5+
## [0.12.11] - 2026-07-10
6+
7+
### Changed
8+
9+
- fix(agent-context): discover nested plan.md in scoped layouts (#3024) (#3301)
10+
- fix(auth): return no matches, not raw ValueError, for a malformed URL (#3437)
11+
- fix(catalogs): raise catalog error, not raw ValueError, on a malformed URL (#3435)
12+
- fix(bundler): raise BundlerError, not raw ValueError, on a malformed catalog URL (#3433)
13+
- chore: add pre-commit config and fix trailing whitespace/end-of-file (#3430)
14+
- Add EARS Requirements Syntax extension to community catalog (#3407)
15+
- Add Spec Kit Figma extension to community catalog (#3408)
16+
- fix(workflows): report validation errors instead of crashing on non-string workflow.yml scalars (#3421)
17+
- fix(templates): remove self-referencing path in plan-template.md note (#3417)
18+
- chore: release 0.12.10, begin 0.12.11.dev0 development (#3453)
19+
520
## [0.12.10] - 2026-07-10
621

722
### Changed

docs/community/extensions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ The following community-contributed extensions are available in [`catalog.commun
149149
| Token Economy | Token routing, measured savings, and context audit workflows | `process` | Read+Write | [spec-kit-token-economy](https://github.com/formin/spec-kit-token-economy) |
150150
| V-Model Extension Pack | Enforces V-Model paired generation of development specs and test specs with full traceability | `docs` | Read+Write | [spec-kit-v-model](https://github.com/leocamello/spec-kit-v-model) |
151151
| Verify Extension | Post-implementation quality gate that validates implemented code against specification artifacts | `code` | Read-only | [spec-kit-verify](https://github.com/ismaelJimenez/spec-kit-verify) |
152+
| Verify Review Ship | Adds post-implementation verify, review, and ship readiness gates to Spec Kit workflows | `process` | Read-only | [spec-kit-verify-review-ship](https://github.com/cadugevaerd/spec-kit-verify-review-ship) |
152153
| Verify Tasks Extension | Detect phantom completions: tasks marked [X] in tasks.md with no real implementation | `code` | Read-only | [spec-kit-verify-tasks](https://github.com/datastone-inc/spec-kit-verify-tasks) |
153154
| Version Guard | Verify tech stack versions against live npm registries before planning and implementation | `process` | Read-only | [spec-kit-version-guard](https://github.com/KevinBrown5280/spec-kit-version-guard) |
154155
| What-if Analysis | Preview the downstream impact (complexity, effort, tasks, risks) of requirement changes before committing to them | `visibility` | Read-only | [spec-kit-whatif](https://github.com/DevAbdullah90/spec-kit-whatif) |

docs/reference/bundles.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ If the current directory is not yet a Spec Kit project, `install` initializes on
5151
specify bundle update [<bundle_id>]
5252
```
5353

54-
| Option | Description |
55-
| ------------ | ------------------------------------ |
56-
| `--all` | Update every installed bundle |
57-
| `--offline` | Do not access the network |
54+
| Option | Description |
55+
| ---------------- | --------------------------------------------------------------------------------------------------------------------- |
56+
| `--all` | Update every installed bundle |
57+
| `--integration` | Override the integration used when refreshing components; applied only when the project's active integration can't be determined |
58+
| `--offline` | Do not access the network |
5859

5960
Re-resolves a bundle and **refreshes** its components through each primitive's update path, bringing already-installed components up to the bundle's newly pinned versions while preserving primitive-level overrides (such as preset priority). Provide a bundle id, or use `--all` to update everything installed.
6061

docs/reference/integrations.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The Specify CLI supports a wide range of AI coding agents. When you run `specify
1818
| [Firebender](https://firebender.com/) | `firebender` | IDE-based agent for Android Studio / IntelliJ |
1919
| [Forge](https://forgecode.dev/) | `forge` | |
2020
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini` | |
21-
| [GitHub Copilot](https://code.visualstudio.com/) | `copilot` | |
21+
| [GitHub Copilot](https://code.visualstudio.com/) | `copilot` | Defaults to legacy markdown mode: `.agent.md` command files under `.github/agents/`, companion `.prompt.md` files under `.github/prompts/`, and a `.vscode/settings.json` merge. Pass `--integration-options="--skills"` to scaffold skills as `speckit-<command>/SKILL.md` under `.github/skills/` instead. Legacy markdown mode is deprecated and will stop being the default in a future release. |
2222
| [Goose](https://goose-docs.ai/) | `goose` | Uses YAML recipe format in `.goose/recipes/` |
2323
| [Hermes](https://github.com/NousResearch/hermes-agent) | `hermes` | Skills-based integration; installs skills globally into `~/.hermes/skills/` |
2424
| [IBM Bob](https://www.ibm.com/products/bob) | `bob` | IDE-based agent |
@@ -219,6 +219,7 @@ Some integrations accept additional options via `--integration-options`:
219219
| ----------- | ------------------- | -------------------------------------------------------------- |
220220
| `generic` | `--commands-dir` | Required. Directory for command files |
221221
| `kimi` | `--migrate-legacy` | Migrate legacy `.kimi/skills/` installs to `.kimi-code/skills/` (including dotted→hyphenated skill naming, e.g. `speckit.xxx``speckit-xxx`) |
222+
| `copilot` | `--skills` | Scaffold commands as agent skills (`speckit-<command>/SKILL.md` under `.github/skills/`, invoked as `/speckit-<command>`) instead of the default legacy markdown mode (`.github/agents/*.agent.md` plus `.github/prompts/*.prompt.md` and a `.vscode/settings.json` merge). Without this flag, install warns that legacy markdown mode is deprecated. |
222223

223224
Example:
224225

extensions/agent-context/commands/speckit.agent-context.update.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The script reads the agent-context extension config at
1515
- `context_files` — optional project-relative paths for multiple coding agent context files. When non-empty, the script updates each listed file and the list takes precedence over `context_file`.
1616
- `context_markers.start` / `.end` — the delimiters surrounding the managed section. Defaults to `<!-- SPECKIT START -->` and `<!-- SPECKIT END -->` when the field is missing.
1717

18-
It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (`specs/**/plan.md`, any depth).
18+
It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (any `plan.md` under `specs/`, including nested scoped layouts such as `specs/<scope>/<feature>/plan.md`).
1919

2020
If `context_files` and `context_file` are empty, the command reports nothing to do and exits successfully. Context file paths must stay project-relative; absolute paths, Windows drive paths, backslash separators, and `..` path segments are rejected.
2121

@@ -24,4 +24,4 @@ If `context_files` and `context_file` are empty, the command reports nothing to
2424
- **Bash**: `.specify/extensions/agent-context/scripts/bash/update-agent-context.sh [plan_path]`
2525
- **PowerShell**: `.specify/extensions/agent-context/scripts/powershell/update-agent-context.ps1 [plan_path]`
2626

27-
When `plan_path` is omitted, the script auto-detects the most recently modified `specs/**/plan.md` (any depth, so scoped layouts like `specs/<scope>/<feature>/plan.md` are found).
27+
When `plan_path` is omitted, the script auto-detects the most recently modified `specs/**/plan.md` (searched recursively, so nested scoped layouts are discovered).

extensions/agent-context/scripts/bash/update-agent-context.sh

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,16 +307,28 @@ import sys
307307
from pathlib import Path
308308
root = Path(sys.argv[1]).resolve()
309309
specs = root / "specs"
310-
plan = max(
311-
specs.glob("**/plan.md"),
312-
key=lambda p: p.stat().st_mtime,
313-
default=None,
314-
)
315-
if plan:
310+
311+
def _resolved_rel(p):
312+
# Resolve symlinks before checking containment: relative_to() is lexical
313+
# and would otherwise accept a plan reached through a specs/ symlink that
314+
# points outside the project, emitting an in-project-looking path for an
315+
# out-of-project file (or picking it as "most recent").
316316
try:
317-
print(plan.relative_to(root).as_posix())
318-
except ValueError:
319-
print("")
317+
return p.resolve().relative_to(root)
318+
except (OSError, ValueError):
319+
return None
320+
321+
# Recurse (rather than the old one-level specs/*/plan.md glob) so scoped layouts
322+
# created via SPECIFY_FEATURE_DIRECTORY, e.g. specs/<scope>/<feature>/plan.md,
323+
# are still discovered when feature.json is absent (#3024).
324+
candidates = []
325+
for p in specs.rglob("plan.md"):
326+
rel = _resolved_rel(p)
327+
if rel:
328+
candidates.append((p, rel))
329+
candidates.sort(key=lambda pr: pr[0].stat().st_mtime, reverse=True)
330+
if candidates:
331+
print(candidates[0][1].as_posix())
320332
else:
321333
print("")
322334
PY

extensions/agent-context/scripts/powershell/update-agent-context.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,11 @@ if (-not $PlanPath) {
426426
if (-not $PlanPath) {
427427
try {
428428
$specsDir = Join-Path $ProjectRoot 'specs'
429-
$candidate = Get-ChildItem -Path $specsDir -Recurse -File -Filter 'plan.md' -ErrorAction SilentlyContinue |
429+
# Recurse (rather than the old one-level specs/*/plan.md scan) so scoped
430+
# layouts created via SPECIFY_FEATURE_DIRECTORY, e.g.
431+
# specs/<scope>/<feature>/plan.md, are still discovered when
432+
# feature.json is absent (#3024).
433+
$candidate = Get-ChildItem -Path $specsDir -Filter 'plan.md' -File -Recurse -ErrorAction SilentlyContinue |
430434
Sort-Object LastWriteTime -Descending |
431435
Select-Object -First 1
432436
if ($candidate) {

extensions/catalog.community.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4407,6 +4407,40 @@
44074407
"created_at": "2026-03-03T00:00:00Z",
44084408
"updated_at": "2026-04-09T00:00:00Z"
44094409
},
4410+
"verify-review-ship": {
4411+
"name": "Verify Review Ship",
4412+
"id": "verify-review-ship",
4413+
"description": "Adds post-implementation verify, review, and ship readiness gates to Spec Kit workflows.",
4414+
"author": "Carlos Eduardo Gevaerd Araujo",
4415+
"version": "0.1.0",
4416+
"download_url": "https://github.com/cadugevaerd/spec-kit-verify-review-ship/archive/refs/tags/v0.1.0.zip",
4417+
"repository": "https://github.com/cadugevaerd/spec-kit-verify-review-ship",
4418+
"homepage": "https://github.com/cadugevaerd/spec-kit-verify-review-ship",
4419+
"documentation": "https://github.com/cadugevaerd/spec-kit-verify-review-ship/blob/main/README.md",
4420+
"changelog": "https://github.com/cadugevaerd/spec-kit-verify-review-ship/blob/main/CHANGELOG.md",
4421+
"license": "MIT",
4422+
"category": "process",
4423+
"effect": "read-only",
4424+
"requires": {
4425+
"speckit_version": ">=0.1.0"
4426+
},
4427+
"provides": {
4428+
"commands": 3,
4429+
"hooks": 1
4430+
},
4431+
"tags": [
4432+
"quality",
4433+
"review",
4434+
"shipping",
4435+
"workflow",
4436+
"testing"
4437+
],
4438+
"verified": false,
4439+
"downloads": 0,
4440+
"stars": 0,
4441+
"created_at": "2026-07-10T00:00:00Z",
4442+
"updated_at": "2026-07-10T00:00:00Z"
4443+
},
44104444
"verify-tasks": {
44114445
"name": "Verify Tasks Extension",
44124446
"id": "verify-tasks",

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "specify-cli"
3-
version = "0.12.11.dev0"
3+
version = "0.12.12.dev0"
44
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
55
readme = "README.md"
66
requires-python = ">=3.11"

src/specify_cli/authentication/config.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,15 @@ def find_entries_for_url(
196196
url: str, entries: list[AuthConfigEntry]
197197
) -> list[AuthConfigEntry]:
198198
"""Return entries whose ``hosts`` match the hostname of *url*."""
199-
hostname = (urlparse(url).hostname or "").lower()
199+
# A malformed authority (e.g. an unterminated IPv6 bracket "https://[::1")
200+
# makes urlparse/hostname raise ValueError. Treat that the same as a
201+
# host-less URL: no entry can match, so return no matches rather than
202+
# leaking a raw ValueError out of the shared HTTP client (build_request /
203+
# open_url call this before any URL validation).
204+
try:
205+
hostname = (urlparse(url).hostname or "").lower()
206+
except ValueError:
207+
return []
200208
if not hostname:
201209
return []
202210
return [

0 commit comments

Comments
 (0)