Skip to content

Commit fce66e0

Browse files
committed
chore: merge upstream and bump to v0.5.3
Synced with github/spec-kit (752683d): - Release 0.7.1 upstream changes - CI: Windows test matrix support - Docs cleanup (removed deprecated --skip-tls) Preserved fork customizations: - Package name: agentic-sdlc-specify-cli - Version: 0.5.3 - ACCENT_COLOR and BANNER_COLORS (tikalk orange theming) - adlc.* command namespace support - Bundled extensions (levelup, evals, architect, quick, product, tdd) - Bundled agentic-sdlc preset
2 parents 0757822 + 752683d commit fce66e0

12 files changed

Lines changed: 141 additions & 35 deletions

File tree

.github/workflows/test.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ jobs:
2727
run: uvx ruff check src/
2828

2929
pytest:
30-
runs-on: ubuntu-latest
30+
runs-on: ${{ matrix.os }}
3131
strategy:
3232
matrix:
33+
os: [ubuntu-latest, windows-latest]
3334
python-version: ["3.11", "3.12", "3.13"]
3435
steps:
3536
- name: Checkout
@@ -46,5 +47,9 @@ jobs:
4647
- name: Install dependencies
4748
run: uv sync --extra test
4849

50+
# On windows-latest, bash tests auto-skip unless Git-for-Windows
51+
# bash (MSYS2/MINGW) is detected. The WSL launcher is rejected
52+
# because it cannot handle native Windows paths in test fixtures.
53+
# See tests/conftest.py::_has_working_bash() for details.
4954
- name: Run tests
5055
run: uv run pytest

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to the Specify CLI and templates are documented here.
44

55
# [Unreleased]
66

7+
# [0.5.3] - 2026-04-16
8+
9+
### Changed
10+
11+
- **Upstream merge**: Synced with github/spec-kit (752683d)
12+
- Release 0.7.1 upstream changes
13+
- CI: Windows test matrix support
14+
- Docs cleanup (removed deprecated --skip-tls)
15+
- Merged cleanly with fork customizations preserved
16+
717
# [0.5.2] - 2026-04-16
818

919
### Fixed
@@ -1088,6 +1098,20 @@ This release migrates fork-specific customizations to a preset system to reduce
10881098

10891099
The following entries are from the upstream spec-kit project and are included for reference.
10901100

1101+
## [0.7.1] - 2026-04-15
1102+
1103+
### Changed
1104+
1105+
- ci: add windows-latest to test matrix (#2233)
1106+
- docs: remove deprecated --skip-tls references from local-development guide (#2231)
1107+
- fix: allow Claude to chain skills for hook execution (#2227)
1108+
- docs: merge TESTING.md into CONTRIBUTING.md, remove TESTING.md (#2228)
1109+
- Add agent-assign extension to community catalog (#2030)
1110+
- fix: unofficial PyPI warning (#1982) and legacy extension command name auto-correction (#2017) (#2027)
1111+
- feat: register architect-preview in community catalog (#2214)
1112+
- chore: deprecate --ai flag in favor of --integration on specify init (#2218)
1113+
- chore: release 0.7.0, begin 0.7.1.dev0 development (#2217)
1114+
10911115
## [0.7.0] - 2026-04-14
10921116

10931117
### Changed

docs/local-development.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,14 @@ python -m src.specify_cli init --here --ai claude --ignore-agent-tools --script
128128

129129
Or copy only the modified CLI portion if you want a lighter sandbox.
130130

131-
## 9. Debug Network / TLS Skips
131+
## 9. Debug Network / TLS Issues
132132

133-
If you need to bypass TLS validation while experimenting:
134-
135-
```bash
136-
specify check --skip-tls
137-
specify init demo --skip-tls --ai gemini --ignore-agent-tools --script ps
138-
```
139-
140-
(Use only for local experimentation.)
133+
> **Deprecated:** The `--skip-tls` flag is a no-op and has no effect.
134+
> It was previously used to bypass TLS validation during local testing.
135+
> If you encounter TLS errors (e.g., on a corporate network), configure your
136+
> environment's certificate store or proxy instead.
137+
>
138+
> For example, set `SSL_CERT_FILE` or configure `HTTPS_PROXY` / `HTTP_PROXY`.
141139
142140
## 10. Rapid Edit Loop Summary
143141

@@ -166,7 +164,7 @@ rm -rf .venv dist build *.egg-info
166164
| Scripts not executable (Linux) | Re-run init or `chmod +x scripts/*.sh` |
167165
| Git step skipped | You passed `--no-git` or Git not installed |
168166
| Wrong script type downloaded | Pass `--script sh` or `--script ps` explicitly |
169-
| TLS errors on corporate network | Try `--skip-tls` (not for production) |
167+
| TLS errors on corporate network | Configure your environment's certificate store or proxy. The `--skip-tls` flag is deprecated and has no effect. |
170168

171169
## 13. Next Steps
172170

evals/README.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,7 @@ uv run pytest tests/ -v
8787

8888
Each suite sends a prompt to the LLM and evaluates the output against structured assertions and custom Python graders.
8989

90-
<<<<<<< HEAD
9190
#### Spec Template (12 tests)
92-
=======
93-
#### Spec Template (10 tests)
94-
>>>>>>> main
9591
- **Basic Structure** — required sections present (Overview, Requirements, User Stories, etc.)
9692
- **No Premature Tech Stack** — spec focuses on WHAT, not HOW
9793
- **Quality User Stories** — proper format with acceptance criteria
@@ -101,12 +97,9 @@ Each suite sends a prompt to the LLM and evaluates the output against structured
10197
- **Completeness** — complex features have comprehensive requirements
10298
- **Regression** — simple features still maintain proper structure
10399
- **Rename Regression** — post-rename output matches quality bar
104-
<<<<<<< HEAD
105100
- **Fork Sections** — Goal, Demo Sentence, Boundary Map present (agentic-sdlc preset)
106101
- **Boundary Map Structure** — Produces and Consumes subsections
107102
- **Constraints Extraction** — key limitations documented
108-
=======
109-
>>>>>>> main
110103

111104
#### Plan Template (2 tests)
112105

@@ -133,15 +126,12 @@ Each suite sends a prompt to the LLM and evaluates the output against structured
133126
- **Structure** — session metadata, decisions, and artifacts sections present
134127
- **Validation Accuracy** — validator correctly scores incomplete traces
135128

136-
<<<<<<< HEAD
137129
#### Mission Brief (4 tests) — Fork-specific
138130
- **Completeness** — Goal, Success Criteria, Constraints, Demo Sentence present
139131
- **Quality** — Goal is concise, criteria are measurable, demo is observable
140132
- **Constraint Extraction** — technical, business, regulatory constraints captured
141133
- **Approval Flow** — includes "Proceed with this Mission Brief?" prompt
142134

143-
=======
144-
>>>>>>> main
145135
### Security Graders (run on every LLM test)
146136

147137
Four graders apply automatically to every test output via `defaultTest.assert`:
@@ -152,12 +142,9 @@ Four graders apply automatically to every test output via `defaultTest.assert`:
152142
| **`check_prompt_injection`** | "Ignore previous instructions", DAN mode, embedded role markers, base64 payloads |
153143
| **`check_hallucination_signals`** | Overconfident metrics, dangling references, self-contradictions, fabricated RFCs |
154144
| **`check_misinformation`** | MD5/SHA-1 for passwords, plaintext HTTP, unsafe APIs (eval/pickle/yaml.load), impossible performance claims |
155-
<<<<<<< HEAD
156145
| **`check_mission_brief_completeness`** | Mission Brief has Goal, Success Criteria, Constraints, Demo Sentence |
157146
| **`check_mission_brief_quality`** | Goal is concise, criteria are measurable, demo is observable |
158147
| **`check_fork_spec_sections`** | Spec includes fork-specific sections (Goal, Demo Sentence, Boundary Map) |
159-
=======
160-
>>>>>>> main
161148

162149
### Unit Tests (pytest)
163150

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "agentic-sdlc-specify-cli"
3-
version = "0.5.2"
3+
version = "0.5.3"
44
description = "Specify CLI (tikalk fork). Agentic SDLC toolkit for Spec-Driven Development with pre-installed extensions and AI integrations."
55
requires-python = ">=3.11"
66
dependencies = [

templates/commands/specify.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,11 @@ Given that feature description, do this:
7272
7373
2. **Branch creation** (optional, via hook):
7474
75-
<<<<<<< HEAD
76-
If a `before_specify` hook ran successfully in the Pre-Execution Checks above, it will have created/switched to a git branch and output JSON containing `BRANCH_NAME` and `FEATURE_NUM`. Note these values for reference, but the branch name does **not** dictate the spec directory name.
77-
=======
7875
**Branch numbering mode**: Before running the script, check if `{REPO_ROOT}/.specify/init-options.json` exists and read the `branch_numbering` value.
7976
- If `"timestamp"`, add `--timestamp` (Bash) or `-Timestamp` (PowerShell) to the script invocation
8077
- If `"sequential"` or absent, do not add any extra flag (default behavior)
81-
>>>>>>> backup-main-20260413
78+
79+
If a `before_specify` hook ran successfully in the Pre-Execution Checks above, it will have created/switched to a git branch and output JSON containing `BRANCH_NAME` and `FEATURE_NUM`. Note these values for reference, but the branch name does **not** dictate the spec directory name.
8280
8381
If the user explicitly provided `GIT_BRANCH_NAME`, pass it through to the hook so the branch script uses the exact value as the branch name (bypassing all prefix/suffix generation).
8482

tests/conftest.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,68 @@
11
"""Shared test helpers for the Spec Kit test suite."""
22

3+
import os
34
import re
5+
import shutil
6+
import subprocess
7+
import sys
8+
9+
import pytest
410

511
_ANSI_ESCAPE_RE = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]")
612

713

14+
def _has_working_bash() -> bool:
15+
"""Check whether a functional native bash is available.
16+
17+
On Windows, ``subprocess.run(["bash", ...])`` uses CreateProcess,
18+
which searches System32 *before* PATH — so it may find the WSL
19+
launcher even when Git-for-Windows bash appears first in PATH via
20+
``shutil.which``. We therefore probe with bare ``"bash"`` (the
21+
same way test helpers invoke it) to get an accurate result.
22+
23+
On Windows, only Git-for-Windows bash (MSYS2/MINGW) is accepted.
24+
The WSL launcher is rejected because it runs in a separate Linux
25+
filesystem and cannot handle native Windows paths used by the
26+
test fixtures.
27+
28+
Set SPECKIT_TEST_BASH=1 to force-enable bash tests regardless.
29+
"""
30+
if os.environ.get("SPECKIT_TEST_BASH") == "1":
31+
return True
32+
if shutil.which("bash") is None:
33+
return False
34+
# Probe with bare "bash" — same as the test helpers — so that
35+
# Windows CreateProcess resolution order is respected.
36+
try:
37+
r = subprocess.run(
38+
["bash", "-c", "echo ok"],
39+
capture_output=True, text=True, timeout=5,
40+
)
41+
if r.returncode != 0 or "ok" not in r.stdout:
42+
return False
43+
except (OSError, subprocess.TimeoutExpired):
44+
return False
45+
# On Windows, verify we have MSYS/MINGW bash (Git for Windows),
46+
# not the WSL launcher which can't handle native paths.
47+
if sys.platform == "win32":
48+
try:
49+
u = subprocess.run(
50+
["bash", "-c", "uname -s"],
51+
capture_output=True, text=True, timeout=5,
52+
)
53+
kernel = u.stdout.strip().upper()
54+
if not any(k in kernel for k in ("MSYS", "MINGW", "CYGWIN")):
55+
return False
56+
except (OSError, subprocess.TimeoutExpired):
57+
return False
58+
return True
59+
60+
61+
requires_bash = pytest.mark.skipif(
62+
not _has_working_bash(), reason="working bash not available"
63+
)
64+
65+
866
def strip_ansi(text: str) -> str:
967
"""Remove ANSI escape codes from Rich-formatted CLI output."""
1068
return _ANSI_ESCAPE_RE.sub("", text)

tests/extensions/git/test_git_extension.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import pytest
2020

21+
from tests.conftest import requires_bash
22+
2123
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent
2224
EXT_DIR = PROJECT_ROOT / "extensions" / "git"
2325
EXT_BASH = EXT_DIR / "scripts" / "bash"
@@ -211,6 +213,7 @@ def test_bundled_extension_locator(self):
211213
# ── initialize-repo.sh Tests ─────────────────────────────────────────────────
212214

213215

216+
@requires_bash
214217
class TestInitializeRepoBash:
215218
def test_initializes_git_repo(self, tmp_path: Path):
216219
"""initialize-repo.sh creates a git repo with initial commit."""
@@ -269,6 +272,7 @@ def test_skips_if_already_git_repo(self, tmp_path: Path):
269272
# ── create-new-feature.sh Tests ──────────────────────────────────────────────
270273

271274

275+
@requires_bash
272276
class TestCreateFeatureBash:
273277
def test_creates_branch_sequential(self, tmp_path: Path):
274278
"""Extension create-new-feature.sh creates sequential branch."""
@@ -376,6 +380,7 @@ def test_no_git_graceful_degradation(self, tmp_path: Path):
376380
# ── auto-commit.sh Tests ─────────────────────────────────────────────────────
377381

378382

383+
@requires_bash
379384
class TestAutoCommitBash:
380385
def test_disabled_by_default(self, tmp_path: Path):
381386
"""auto-commit.sh exits silently when config is all false."""
@@ -583,6 +588,7 @@ def test_success_message_no_unicode_checkmark(self, tmp_path: Path):
583588
# ── git-common.sh Tests ──────────────────────────────────────────────────────
584589

585590

591+
@requires_bash
586592
class TestGitCommonBash:
587593
def test_has_git_true(self, tmp_path: Path):
588594
"""has_git returns 0 in a git repo."""

tests/integrations/test_manifest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import hashlib
44
import json
5+
import sys
56

67
import pytest
78

@@ -41,8 +42,9 @@ def test_record_file_rejects_parent_traversal(self, tmp_path):
4142

4243
def test_record_file_rejects_absolute_path(self, tmp_path):
4344
m = IntegrationManifest("test", tmp_path)
45+
abs_path = "C:\\tmp\\escape.txt" if sys.platform == "win32" else "/tmp/escape.txt"
4446
with pytest.raises(ValueError, match="Absolute paths"):
45-
m.record_file("/tmp/escape.txt", "bad")
47+
m.record_file(abs_path, "bad")
4648

4749
def test_record_existing_rejects_parent_traversal(self, tmp_path):
4850
escape = tmp_path.parent / "escape.txt"

tests/test_cursor_frontmatter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import pytest
1414

15+
from tests.conftest import requires_bash
16+
1517
SCRIPT_PATH = os.path.join(
1618
os.path.dirname(__file__),
1719
os.pardir,
@@ -73,6 +75,7 @@ def test_powershell_script_has_mdc_frontmatter_logic(self):
7375

7476

7577
@requires_git
78+
@requires_bash
7679
class TestCursorFrontmatterIntegration:
7780
"""Integration tests using a real git repo."""
7881

0 commit comments

Comments
 (0)