Compare commits

..

1 Commits

Author SHA1 Message Date
github-actions[bot]
da4f095a49 chore: bump version to 0.7.3 2026-04-17 19:30:46 +00:00
14 changed files with 49 additions and 428 deletions

View File

@@ -1,29 +0,0 @@
{
"title": "Spec Kit",
"description": "Spec Kit is an open source toolkit for Spec-Driven Development (SDD) — a methodology that helps software teams build high-quality software faster by focusing on product scenarios and predictable outcomes. It provides the Specify CLI, slash-command templates, extensions, presets, workflows, and integrations for popular AI coding agents.",
"creators": [
{
"name": "Delimarsky, Den"
},
{
"name": "Riem, Manfred"
}
],
"license": "MIT",
"upload_type": "software",
"keywords": [
"spec-driven development",
"ai coding agents",
"software engineering",
"cli",
"copilot",
"specification"
],
"related_identifiers": [
{
"identifier": "https://github.com/github/spec-kit",
"relation": "isSupplementTo",
"scheme": "url"
}
]
}

View File

@@ -2,22 +2,6 @@
<!-- insert new changelog below this comment --> <!-- insert new changelog below this comment -->
## [0.7.4] - 2026-04-21
### Changed
- fix(copilot): use --yolo to grant all permissions in non-interactive mode (#2298)
- feat: add CITATION.cff and .zenodo.json for academic citation support (#2291)
- Add spec-validate to community catalog (#2274)
- feat: register Ripple in community catalog (#2272)
- Add version-guard to community catalog (#2286)
- Add spec-reference-loader to community catalog (#2285)
- Add memory-loader to community catalog (#2284)
- fix(integrations): strip UTF-8 BOM when reading agent context files (#2283)
- Preset fiction book writing1.6 (#2270)
- fix(integrations): migrate Antigravity (agy) layout to .agents/ and deprecate --skills (#2276)
- chore: release 0.7.3, begin 0.7.4.dev0 development (#2263)
## [0.7.3] - 2026-04-17 ## [0.7.3] - 2026-04-17
### Changed ### Changed

View File

@@ -1,31 +0,0 @@
cff-version: 1.2.0
message: >-
If you use Spec Kit in your research or reference it in a paper,
please cite it using the metadata below.
type: software
title: "Spec Kit"
abstract: >-
Spec Kit is an open source toolkit for Spec-Driven Development (SDD) —
a methodology that helps software teams build high-quality software faster
by focusing on product scenarios and predictable outcomes. It provides the
Specify CLI, slash-command templates, extensions, presets, workflows, and
integrations for popular AI coding agents.
authors:
- given-names: Den
family-names: Delimarsky
alias: localden
- given-names: Manfred
family-names: Riem
alias: mnriem
repository-code: "https://github.com/github/spec-kit"
url: "https://github.github.io/spec-kit/"
license: MIT
version: "0.7.3"
date-released: "2026-04-17"
keywords:
- spec-driven development
- ai coding agents
- software engineering
- cli
- copilot
- specification

View File

@@ -223,7 +223,6 @@ The following community-contributed extensions are available in [`catalog.commun
| MAQA Jira Integration | Jira integration for MAQA — syncs Stories and Subtasks as features progress through the board | `integration` | Read+Write | [spec-kit-maqa-jira](https://github.com/GenieRobot/spec-kit-maqa-jira) | | MAQA Jira Integration | Jira integration for MAQA — syncs Stories and Subtasks as features progress through the board | `integration` | Read+Write | [spec-kit-maqa-jira](https://github.com/GenieRobot/spec-kit-maqa-jira) |
| MAQA Linear Integration | Linear integration for MAQA — syncs issues and sub-issues across workflow states as features progress | `integration` | Read+Write | [spec-kit-maqa-linear](https://github.com/GenieRobot/spec-kit-maqa-linear) | | MAQA Linear Integration | Linear integration for MAQA — syncs issues and sub-issues across workflow states as features progress | `integration` | Read+Write | [spec-kit-maqa-linear](https://github.com/GenieRobot/spec-kit-maqa-linear) |
| MAQA Trello Integration | Trello board integration for MAQA — populates board from specs, moves cards, real-time checklist ticking | `integration` | Read+Write | [spec-kit-maqa-trello](https://github.com/GenieRobot/spec-kit-maqa-trello) | | MAQA Trello Integration | Trello board integration for MAQA — populates board from specs, moves cards, real-time checklist ticking | `integration` | Read+Write | [spec-kit-maqa-trello](https://github.com/GenieRobot/spec-kit-maqa-trello) |
| Memory Loader | Loads .specify/memory/ files before lifecycle commands so LLM agents have project governance context | `docs` | Read-only | [spec-kit-memory-loader](https://github.com/KevinBrown5280/spec-kit-memory-loader) |
| MemoryLint | Agent memory governance tool: Automatically audits and fixes boundary conflicts between AGENTS.md and the constitution. | `process` | Read+Write | [memorylint](https://github.com/RbBtSn0w/spec-kit-extensions/tree/main/memorylint) | | MemoryLint | Agent memory governance tool: Automatically audits and fixes boundary conflicts between AGENTS.md and the constitution. | `process` | Read+Write | [memorylint](https://github.com/RbBtSn0w/spec-kit-extensions/tree/main/memorylint) |
| Onboard | Contextual onboarding and progressive growth for developers new to spec-kit projects. Explains specs, maps dependencies, validates understanding, and guides the next step | `process` | Read+Write | [spec-kit-onboard](https://github.com/dmux/spec-kit-onboard) | | Onboard | Contextual onboarding and progressive growth for developers new to spec-kit projects. Explains specs, maps dependencies, validates understanding, and guides the next step | `process` | Read+Write | [spec-kit-onboard](https://github.com/dmux/spec-kit-onboard) |
| Optimize | Audit and optimize AI governance for context efficiency — token budgets, rule health, interpretability, compression, coherence, and echo detection | `process` | Read+Write | [spec-kit-optimize](https://github.com/sakitA/spec-kit-optimize) | | Optimize | Audit and optimize AI governance for context efficiency — token budgets, rule health, interpretability, compression, coherence, and echo detection | `process` | Read+Write | [spec-kit-optimize](https://github.com/sakitA/spec-kit-optimize) |
@@ -240,18 +239,15 @@ The following community-contributed extensions are available in [`catalog.commun
| Retro Extension | Sprint retrospective analysis with metrics, spec accuracy assessment, and improvement suggestions | `process` | Read+Write | [spec-kit-retro](https://github.com/arunt14/spec-kit-retro) | | Retro Extension | Sprint retrospective analysis with metrics, spec accuracy assessment, and improvement suggestions | `process` | Read+Write | [spec-kit-retro](https://github.com/arunt14/spec-kit-retro) |
| Retrospective Extension | Post-implementation retrospective with spec adherence scoring, drift analysis, and human-gated spec updates | `docs` | Read+Write | [spec-kit-retrospective](https://github.com/emi-dm/spec-kit-retrospective) | | Retrospective Extension | Post-implementation retrospective with spec adherence scoring, drift analysis, and human-gated spec updates | `docs` | Read+Write | [spec-kit-retrospective](https://github.com/emi-dm/spec-kit-retrospective) |
| Review Extension | Post-implementation comprehensive code review with specialized agents for code quality, comments, tests, error handling, type design, and simplification | `code` | Read-only | [spec-kit-review](https://github.com/ismaelJimenez/spec-kit-review) | | Review Extension | Post-implementation comprehensive code review with specialized agents for code quality, comments, tests, error handling, type design, and simplification | `code` | Read-only | [spec-kit-review](https://github.com/ismaelJimenez/spec-kit-review) |
| Ripple | Detect side effects that tests can't catch after implementation — delta-anchored analysis across 9 domain-agnostic categories | `code` | Read+Write | [spec-kit-ripple](https://github.com/chordpli/spec-kit-ripple) |
| SDD Utilities | Resume interrupted workflows, validate project health, and verify spec-to-task traceability | `process` | Read+Write | [speckit-utils](https://github.com/mvanhorn/speckit-utils) | | SDD Utilities | Resume interrupted workflows, validate project health, and verify spec-to-task traceability | `process` | Read+Write | [speckit-utils](https://github.com/mvanhorn/speckit-utils) |
| Security Review | Comprehensive security audit of codebases using AI-powered DevSecOps analysis | `code` | Read-only | [spec-kit-security-review](https://github.com/DyanGalih/spec-kit-security-review) | | Security Review | Comprehensive security audit of codebases using AI-powered DevSecOps analysis | `code` | Read-only | [spec-kit-security-review](https://github.com/DyanGalih/spec-kit-security-review) |
| SFSpeckit | Enterprise Salesforce SDLC with 18 commands for the full SDD lifecycle. | `process` | Read+Write | [spec-kit-sf](https://github.com/ysumanth06/spec-kit-sf) | | SFSpeckit | Enterprise Salesforce SDLC with 18 commands for the full SDD lifecycle. | `process` | Read+Write | [spec-kit-sf](https://github.com/ysumanth06/spec-kit-sf) |
| Ship Release Extension | Automates release pipeline: pre-flight checks, branch sync, changelog generation, CI verification, and PR creation | `process` | Read+Write | [spec-kit-ship](https://github.com/arunt14/spec-kit-ship) | | Ship Release Extension | Automates release pipeline: pre-flight checks, branch sync, changelog generation, CI verification, and PR creation | `process` | Read+Write | [spec-kit-ship](https://github.com/arunt14/spec-kit-ship) |
| Spec Reference Loader | Reads the ## References section from the feature spec and loads only the listed docs into context | `docs` | Read-only | [spec-kit-spec-reference-loader](https://github.com/KevinBrown5280/spec-kit-spec-reference-loader) |
| Spec Critique Extension | Dual-lens critical review of spec and plan from product strategy and engineering risk perspectives | `docs` | Read-only | [spec-kit-critique](https://github.com/arunt14/spec-kit-critique) | | Spec Critique Extension | Dual-lens critical review of spec and plan from product strategy and engineering risk perspectives | `docs` | Read-only | [spec-kit-critique](https://github.com/arunt14/spec-kit-critique) |
| Spec Diagram | Auto-generate Mermaid diagrams of SDD workflow state, feature progress, and task dependencies | `visibility` | Read-only | [spec-kit-diagram-](https://github.com/Quratulain-bilal/spec-kit-diagram-) | | Spec Diagram | Auto-generate Mermaid diagrams of SDD workflow state, feature progress, and task dependencies | `visibility` | Read-only | [spec-kit-diagram-](https://github.com/Quratulain-bilal/spec-kit-diagram-) |
| Spec Refine | Update specs in-place, propagate changes to plan and tasks, and diff impact across artifacts | `process` | Read+Write | [spec-kit-refine](https://github.com/Quratulain-bilal/spec-kit-refine) | | Spec Refine | Update specs in-place, propagate changes to plan and tasks, and diff impact across artifacts | `process` | Read+Write | [spec-kit-refine](https://github.com/Quratulain-bilal/spec-kit-refine) |
| Spec Scope | Effort estimation and scope tracking — estimate work, detect creep, and budget time per phase | `process` | Read-only | [spec-kit-scope-](https://github.com/Quratulain-bilal/spec-kit-scope-) | | Spec Scope | Effort estimation and scope tracking — estimate work, detect creep, and budget time per phase | `process` | Read-only | [spec-kit-scope-](https://github.com/Quratulain-bilal/spec-kit-scope-) |
| Spec Sync | Detect and resolve drift between specs and implementation. AI-assisted resolution with human approval | `docs` | Read+Write | [spec-kit-sync](https://github.com/bgervin/spec-kit-sync) | | Spec Sync | Detect and resolve drift between specs and implementation. AI-assisted resolution with human approval | `docs` | Read+Write | [spec-kit-sync](https://github.com/bgervin/spec-kit-sync) |
| Spec Validate | Comprehension validation, review gating, and approval state for spec-kit artifacts — staged quizzes, peer review SLA, and a hard gate before /speckit.implement | `process` | Read+Write | [spec-kit-spec-validate](https://github.com/aeltayeb/spec-kit-spec-validate) |
| SpecTest | Auto-generate test scaffolds from spec criteria, map coverage, and find untested requirements | `code` | Read+Write | [spec-kit-spectest](https://github.com/Quratulain-bilal/spec-kit-spectest) | | SpecTest | Auto-generate test scaffolds from spec criteria, map coverage, and find untested requirements | `code` | Read+Write | [spec-kit-spectest](https://github.com/Quratulain-bilal/spec-kit-spectest) |
| 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) | | 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) |
| 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) | | 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) |
@@ -260,7 +256,6 @@ The following community-contributed extensions are available in [`catalog.commun
| 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) | | 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) |
| 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) | | 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) |
| 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) | | 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) |
| 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) |
| 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) | | 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) |
| Worktree Isolation | Spawn isolated git worktrees for parallel feature development without checkout switching | `process` | Read+Write | [spec-kit-worktree](https://github.com/Quratulain-bilal/spec-kit-worktree) | | Worktree Isolation | Spawn isolated git worktrees for parallel feature development without checkout switching | `process` | Read+Write | [spec-kit-worktree](https://github.com/Quratulain-bilal/spec-kit-worktree) |
| Worktrees | Default-on worktree isolation for parallel agents — sibling or nested layout | `process` | Read+Write | [spec-kit-worktree-parallel](https://github.com/dango85/spec-kit-worktree-parallel) | | Worktrees | Default-on worktree isolation for parallel agents — sibling or nested layout | `process` | Read+Write | [spec-kit-worktree-parallel](https://github.com/dango85/spec-kit-worktree-parallel) |
@@ -279,7 +274,7 @@ The following community-contributed presets customize how Spec Kit behaves — o
| AIDE In-Place Migration | Adapts the AIDE extension workflow for in-place technology migrations (X → Y pattern) — adds migration objectives, verification gates, knowledge documents, and behavioral equivalence criteria | 2 templates, 8 commands | AIDE extension | [spec-kit-presets](https://github.com/mnriem/spec-kit-presets) | | AIDE In-Place Migration | Adapts the AIDE extension workflow for in-place technology migrations (X → Y pattern) — adds migration objectives, verification gates, knowledge documents, and behavioral equivalence criteria | 2 templates, 8 commands | AIDE extension | [spec-kit-presets](https://github.com/mnriem/spec-kit-presets) |
| Canon Core | Adapts original Spec Kit workflow to work together with Canon extension | 2 templates, 8 commands | — | [spec-kit-canon](https://github.com/maximiliamus/spec-kit-canon) | | Canon Core | Adapts original Spec Kit workflow to work together with Canon extension | 2 templates, 8 commands | — | [spec-kit-canon](https://github.com/maximiliamus/spec-kit-canon) |
| Explicit Task Dependencies | Adds explicit `(depends on T###)` dependency declarations and an Execution Wave DAG to tasks.md for parallel scheduling | 1 template, 1 command | — | [spec-kit-preset-explicit-task-dependencies](https://github.com/Quratulain-bilal/spec-kit-preset-explicit-task-dependencies) | | Explicit Task Dependencies | Adds explicit `(depends on T###)` dependency declarations and an Execution Wave DAG to tasks.md for parallel scheduling | 1 template, 1 command | — | [spec-kit-preset-explicit-task-dependencies](https://github.com/Quratulain-bilal/spec-kit-preset-explicit-task-dependencies) |
| Fiction Book Writing | It adapts the Spec-Driven Development workflow for storytelling to create books or audiobooks (with annotations) in 12 languages: features become story elements, specs become story briefs, plans become story structures, and tasks become scene-by-scene writing tasks. Supports single and multi-POV, all major plot structure frameworks, and two style modes: an author voice sample or humanized AI prose. Supports interactive elements like brainstorming, interview, roleplay and extras like statistics, cover builder and bio command. Export with templates for KDP, D2D etc. | 22 templates, 27 commands | — | [spec-kit-preset-fiction-book-writing](https://github.com/adaumann/speckit-preset-fiction-book-writing) | | Fiction Book Writing | It adapts the Spec-Driven Development workflow for storytelling to create books or audiobooks (with annotations): features become story elements, specs become story briefs, plans become story structures, and tasks become scene-by-scene writing tasks. Supports single and multi-POV, all major plot structure frameworks, and two style modes: an author voice sample or humanized AI prose with 5 prose profiles. Supports interactive elements like brainstorming, interview, roleplay. | 21 templates, 26 commands | — | [spec-kit-preset-fiction-book-writing](https://github.com/adaumann/speckit-preset-fiction-book-writing) |
| Multi-Repo Branching | Coordinates feature branch creation across multiple git repositories (independent repos and submodules) during plan and tasks phases | 2 commands | — | [spec-kit-preset-multi-repo-branching](https://github.com/sakitA/spec-kit-preset-multi-repo-branching) | | Multi-Repo Branching | Coordinates feature branch creation across multiple git repositories (independent repos and submodules) during plan and tasks phases | 2 commands | — | [spec-kit-preset-multi-repo-branching](https://github.com/sakitA/spec-kit-preset-multi-repo-branching) |
| Pirate Speak (Full) | Transforms all Spec Kit output into pirate speak — specs become "Voyage Manifests", plans become "Battle Plans", tasks become "Crew Assignments" | 6 templates, 9 commands | — | [spec-kit-presets](https://github.com/mnriem/spec-kit-presets) | | Pirate Speak (Full) | Transforms all Spec Kit output into pirate speak — specs become "Voyage Manifests", plans become "Battle Plans", tasks become "Crew Assignments" | 6 templates, 9 commands | — | [spec-kit-presets](https://github.com/mnriem/spec-kit-presets) |
| Table of Contents Navigation | Adds a navigable Table of Contents to generated spec.md, plan.md, and tasks.md documents | 3 templates, 3 commands | — | [spec-kit-preset-toc-navigation](https://github.com/Quratulain-bilal/spec-kit-preset-toc-navigation) | | Table of Contents Navigation | Adds a navigable Table of Contents to generated spec.md, plan.md, and tasks.md documents | 3 templates, 3 commands | — | [spec-kit-preset-toc-navigation](https://github.com/Quratulain-bilal/spec-kit-preset-toc-navigation) |

View File

@@ -1,6 +1,6 @@
{ {
"schema_version": "1.0", "schema_version": "1.0",
"updated_at": "2026-04-21T00:00:00Z", "updated_at": "2026-04-17T02:00:00Z",
"catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json", "catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
"extensions": { "extensions": {
"aide": { "aide": {
@@ -1167,37 +1167,6 @@
"created_at": "2026-03-26T00:00:00Z", "created_at": "2026-03-26T00:00:00Z",
"updated_at": "2026-03-26T00:00:00Z" "updated_at": "2026-03-26T00:00:00Z"
}, },
"memory-loader": {
"name": "Memory Loader",
"id": "memory-loader",
"description": "Loads .specify/memory/ files before spec-kit lifecycle commands so LLM agents have project governance context",
"author": "KevinBrown5280",
"version": "1.0.0",
"download_url": "https://github.com/KevinBrown5280/spec-kit-memory-loader/archive/refs/tags/v1.0.0.zip",
"repository": "https://github.com/KevinBrown5280/spec-kit-memory-loader",
"homepage": "https://github.com/KevinBrown5280/spec-kit-memory-loader",
"documentation": "https://github.com/KevinBrown5280/spec-kit-memory-loader/blob/main/README.md",
"changelog": "https://github.com/KevinBrown5280/spec-kit-memory-loader/blob/main/CHANGELOG.md",
"license": "MIT",
"requires": {
"speckit_version": ">=0.6.0"
},
"provides": {
"commands": 1,
"hooks": 7
},
"tags": [
"context",
"memory",
"governance",
"hooks"
],
"verified": false,
"downloads": 0,
"stars": 0,
"created_at": "2026-04-20T00:00:00Z",
"updated_at": "2026-04-20T00:00:00Z"
},
"memorylint": { "memorylint": {
"name": "MemoryLint", "name": "MemoryLint",
"id": "memorylint", "id": "memorylint",
@@ -1688,38 +1657,6 @@
"created_at": "2026-03-06T00:00:00Z", "created_at": "2026-03-06T00:00:00Z",
"updated_at": "2026-04-09T00:00:00Z" "updated_at": "2026-04-09T00:00:00Z"
}, },
"ripple": {
"name": "Ripple",
"id": "ripple",
"description": "Detect side effects that tests can't catch after implementation — delta-anchored analysis across 9 domain-agnostic categories with fix-induced side effect detection",
"author": "chordpli",
"version": "1.0.0",
"download_url": "https://github.com/chordpli/spec-kit-ripple/archive/refs/tags/v1.0.0.zip",
"repository": "https://github.com/chordpli/spec-kit-ripple",
"homepage": "https://github.com/chordpli/spec-kit-ripple",
"documentation": "https://github.com/chordpli/spec-kit-ripple/blob/main/README.md",
"changelog": "https://github.com/chordpli/spec-kit-ripple/blob/main/CHANGELOG.md",
"license": "MIT",
"requires": {
"speckit_version": ">=0.2.0"
},
"provides": {
"commands": 3,
"hooks": 1
},
"tags": [
"side-effects",
"post-implementation",
"analysis",
"quality",
"risk-detection"
],
"verified": false,
"downloads": 0,
"stars": 0,
"created_at": "2026-04-20T00:00:00Z",
"updated_at": "2026-04-20T00:00:00Z"
},
"scope": { "scope": {
"name": "Spec Scope", "name": "Spec Scope",
"id": "scope", "id": "scope",
@@ -1859,69 +1796,6 @@
"created_at": "2026-04-01T00:00:00Z", "created_at": "2026-04-01T00:00:00Z",
"updated_at": "2026-04-01T00:00:00Z" "updated_at": "2026-04-01T00:00:00Z"
}, },
"spec-reference-loader": {
"name": "Spec Reference Loader",
"id": "spec-reference-loader",
"description": "Reads the ## References section from the current feature spec and loads the listed files into context",
"author": "KevinBrown5280",
"version": "1.0.0",
"download_url": "https://github.com/KevinBrown5280/spec-kit-spec-reference-loader/archive/refs/tags/v1.0.0.zip",
"repository": "https://github.com/KevinBrown5280/spec-kit-spec-reference-loader",
"homepage": "https://github.com/KevinBrown5280/spec-kit-spec-reference-loader",
"documentation": "https://github.com/KevinBrown5280/spec-kit-spec-reference-loader/blob/main/README.md",
"changelog": "https://github.com/KevinBrown5280/spec-kit-spec-reference-loader/blob/main/CHANGELOG.md",
"license": "MIT",
"requires": {
"speckit_version": ">=0.6.0"
},
"provides": {
"commands": 1,
"hooks": 6
},
"tags": [
"context",
"references",
"docs",
"hooks"
],
"verified": false,
"downloads": 0,
"stars": 0,
"created_at": "2026-04-20T00:00:00Z",
"updated_at": "2026-04-20T00:00:00Z"
},
"spec-validate": {
"name": "Spec Validate",
"id": "spec-validate",
"description": "Comprehension validation, review gating, and approval state for spec-kit artifacts — staged-reveal quizzes, peer review SLA, and a hard gate before /speckit.implement.",
"author": "Ahmed Eltayeb",
"version": "1.0.1",
"download_url": "https://github.com/aeltayeb/spec-kit-spec-validate/archive/refs/tags/v1.0.1.zip",
"repository": "https://github.com/aeltayeb/spec-kit-spec-validate",
"homepage": "https://github.com/aeltayeb/spec-kit-spec-validate",
"documentation": "https://github.com/aeltayeb/spec-kit-spec-validate/blob/main/README.md",
"changelog": "https://github.com/aeltayeb/spec-kit-spec-validate/blob/main/CHANGELOG.md",
"license": "MIT",
"requires": {
"speckit_version": ">=0.5.0"
},
"provides": {
"commands": 6,
"hooks": 3
},
"tags": [
"validation",
"review",
"quality",
"workflow",
"process"
],
"verified": false,
"downloads": 0,
"stars": 0,
"created_at": "2026-04-20T00:00:00Z",
"updated_at": "2026-04-21T00:00:00Z"
},
"speckit-utils": { "speckit-utils": {
"name": "SDD Utilities", "name": "SDD Utilities",
"id": "speckit-utils", "id": "speckit-utils",
@@ -2281,37 +2155,6 @@
"created_at": "2026-03-16T00:00:00Z", "created_at": "2026-03-16T00:00:00Z",
"updated_at": "2026-03-16T00:00:00Z" "updated_at": "2026-03-16T00:00:00Z"
}, },
"version-guard": {
"name": "Version Guard",
"id": "version-guard",
"description": "Verify tech stack versions against live registries before planning and implementation",
"author": "KevinBrown5280",
"version": "1.0.0",
"download_url": "https://github.com/KevinBrown5280/spec-kit-version-guard/archive/refs/tags/v1.0.0.zip",
"repository": "https://github.com/KevinBrown5280/spec-kit-version-guard",
"homepage": "https://github.com/KevinBrown5280/spec-kit-version-guard",
"documentation": "https://github.com/KevinBrown5280/spec-kit-version-guard/blob/main/README.md",
"changelog": "https://github.com/KevinBrown5280/spec-kit-version-guard/blob/main/CHANGELOG.md",
"license": "MIT",
"requires": {
"speckit_version": ">=0.2.0"
},
"provides": {
"commands": 1,
"hooks": 2
},
"tags": [
"versioning",
"npm",
"validation",
"hooks"
],
"verified": false,
"downloads": 0,
"stars": 0,
"created_at": "2026-04-20T00:00:00Z",
"updated_at": "2026-04-20T00:00:00Z"
},
"whatif": { "whatif": {
"name": "What-if Analysis", "name": "What-if Analysis",
"id": "whatif", "id": "whatif",

View File

@@ -108,11 +108,11 @@
"fiction-book-writing": { "fiction-book-writing": {
"name": "Fiction Book Writing", "name": "Fiction Book Writing",
"id": "fiction-book-writing", "id": "fiction-book-writing",
"version": "1.6.0", "version": "1.5.0",
"description": "Spec-Driven Development for novel and long-form fiction. 27 AI commands from idea to submission: story bible governance, 9 POV modes, all major plot structure frameworks, scene-by-scene drafting with quality gates, audiobook pipeline (SSML/ElevenLabs), cover design, sensitivity review, pacing and prose statistics, and pandoc-based export to DOCX/EPUB/LaTeX. Two style modes: author voice sample extraction or humanized-AI prose with 5 craft profiles. 12 languages supported.", "description": "Spec-Driven Development for novel and long-form fiction. Replaces software engineering terminology with storytelling craft: specs become story briefs, plans become story structures, and tasks become scene-by-scene writing tasks. Supports 8 POV modes, all major plot structure frameworks, 5 humanized-AI prose profiles, and exports to DOCX/EPUB/LaTeX via pandoc.",
"author": "Andreas Daumann", "author": "Andreas Daumann",
"repository": "https://github.com/adaumann/speckit-preset-fiction-book-writing", "repository": "https://github.com/adaumann/speckit-preset-fiction-book-writing",
"download_url": "https://github.com/adaumann/speckit-preset-fiction-book-writing/archive/refs/tags/v1.6.0.zip", "download_url": "https://github.com/adaumann/speckit-preset-fiction-book-writing/archive/refs/tags/v1.5.0.zip",
"homepage": "https://github.com/adaumann/speckit-preset-fiction-book-writing", "homepage": "https://github.com/adaumann/speckit-preset-fiction-book-writing",
"documentation": "https://github.com/adaumann/speckit-preset-fiction-book-writing/blob/main/fiction-book-writing/README.md", "documentation": "https://github.com/adaumann/speckit-preset-fiction-book-writing/blob/main/fiction-book-writing/README.md",
"license": "MIT", "license": "MIT",
@@ -120,9 +120,8 @@
"speckit_version": ">=0.5.0" "speckit_version": ">=0.5.0"
}, },
"provides": { "provides": {
"templates": 22, "templates": 21,
"commands": 27, "commands": 26
"scripts": 1
}, },
"tags": [ "tags": [
"writing", "writing",
@@ -136,12 +135,11 @@
"book", "book",
"brainstorming", "brainstorming",
"roleplay", "roleplay",
"audiobook", "audiobook"
"language-support"
], ],
"created_at": "2026-04-09T08:00:00Z", "created_at": "2026-04-09T08:00:00Z",
"updated_at": "2026-04-19T08:00:00Z" "updated_at": "2026-04-16T08:00:00Z"
}, },
"multi-repo-branching": { "multi-repo-branching": {
"name": "Multi-Repo Branching", "name": "Multi-Repo Branching",
"id": "multi-repo-branching", "id": "multi-repo-branching",

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "specify-cli" name = "specify-cli"
version = "0.7.4" version = "0.7.3"
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)." description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
requires-python = ">=3.11" requires-python = ">=3.11"
dependencies = [ dependencies = [

View File

@@ -1,18 +1,13 @@
"""Antigravity (agy) integration — skills-based agent. """Antigravity (agy) integration — skills-based agent.
Antigravity uses ``.agents/skills/speckit-<name>/SKILL.md`` layout (enforced since v1.20.5). Antigravity uses ``.agent/skills/speckit-<name>/SKILL.md`` layout.
Explicit command support was deprecated in version 1.20.5;
``--skills`` defaults to ``True``.
""" """
from __future__ import annotations from __future__ import annotations
from pathlib import Path from ..base import IntegrationOption, SkillsIntegration
from typing import TYPE_CHECKING, Any
from ..base import SkillsIntegration
if TYPE_CHECKING:
from ..manifest import IntegrationManifest
class AgyIntegration(SkillsIntegration): class AgyIntegration(SkillsIntegration):
@@ -21,32 +16,26 @@ class AgyIntegration(SkillsIntegration):
key = "agy" key = "agy"
config = { config = {
"name": "Antigravity", "name": "Antigravity",
"folder": ".agents/", "folder": ".agent/",
"commands_subdir": "skills", "commands_subdir": "skills",
"install_url": None, "install_url": None,
"requires_cli": False, "requires_cli": False,
} }
registrar_config = { registrar_config = {
"dir": ".agents/skills", "dir": ".agent/skills",
"format": "markdown", "format": "markdown",
"args": "$ARGUMENTS", "args": "$ARGUMENTS",
"extension": "/SKILL.md", "extension": "/SKILL.md",
} }
context_file = "AGENTS.md" context_file = "AGENTS.md"
def setup( @classmethod
self, def options(cls) -> list[IntegrationOption]:
project_root: Path, return [
manifest: IntegrationManifest, IntegrationOption(
parsed_options: dict[str, Any] | None = None, "--skills",
**opts: Any, is_flag=True,
) -> list[Path]: default=True,
import click help="Install as agent skills (default for Antigravity since v1.20.5)",
),
click.secho( ]
"Warning: The .agents/ layout requires Antigravity v1.20.5 or newer. "
"Please ensure your agy installation is up to date.",
fg="yellow",
err=True,
)
return super().setup(project_root, manifest, parsed_options=parsed_options, **opts)

View File

@@ -482,7 +482,7 @@ class IntegrationBase(ABC):
) )
if ctx_path.exists(): if ctx_path.exists():
content = ctx_path.read_text(encoding="utf-8-sig") content = ctx_path.read_text(encoding="utf-8")
start_idx = content.find(self.CONTEXT_MARKER_START) start_idx = content.find(self.CONTEXT_MARKER_START)
end_idx = content.find( end_idx = content.find(
self.CONTEXT_MARKER_END, self.CONTEXT_MARKER_END,
@@ -547,7 +547,7 @@ class IntegrationBase(ABC):
if not ctx_path.exists(): if not ctx_path.exists():
return False return False
content = ctx_path.read_text(encoding="utf-8-sig") content = ctx_path.read_text(encoding="utf-8")
start_idx = content.find(self.CONTEXT_MARKER_START) start_idx = content.find(self.CONTEXT_MARKER_START)
end_idx = content.find( end_idx = content.find(
self.CONTEXT_MARKER_END, self.CONTEXT_MARKER_END,

View File

@@ -10,9 +10,7 @@ Copilot has several unique behaviors compared to standard markdown agents:
from __future__ import annotations from __future__ import annotations
import json import json
import os
import shutil import shutil
import warnings
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@@ -20,30 +18,6 @@ from ..base import IntegrationBase
from ..manifest import IntegrationManifest from ..manifest import IntegrationManifest
def _allow_all() -> bool:
"""Return True if the Copilot CLI should run with full permissions.
Checks ``SPECKIT_COPILOT_ALLOW_ALL_TOOLS`` first (new canonical name).
Falls back to the deprecated ``SPECKIT_ALLOW_ALL_TOOLS`` if set,
emitting a deprecation warning. Default when neither is set: enabled.
"""
new_var = os.environ.get("SPECKIT_COPILOT_ALLOW_ALL_TOOLS")
if new_var is not None:
return new_var != "0"
old_var = os.environ.get("SPECKIT_ALLOW_ALL_TOOLS")
if old_var is not None:
warnings.warn(
"SPECKIT_ALLOW_ALL_TOOLS is deprecated; "
"use SPECKIT_COPILOT_ALLOW_ALL_TOOLS instead.",
UserWarning,
stacklevel=2,
)
return old_var != "0"
return True
class CopilotIntegration(IntegrationBase): class CopilotIntegration(IntegrationBase):
"""Integration for GitHub Copilot (VS Code IDE + CLI). """Integration for GitHub Copilot (VS Code IDE + CLI).
@@ -76,15 +50,13 @@ class CopilotIntegration(IntegrationBase):
output_json: bool = True, output_json: bool = True,
) -> list[str] | None: ) -> list[str] | None:
# GitHub Copilot CLI uses ``copilot -p "prompt"`` for # GitHub Copilot CLI uses ``copilot -p "prompt"`` for
# non-interactive mode. --yolo enables all permissions # non-interactive mode. --allow-all-tools is required for the
# (tools, paths, and URLs) so the agent can perform file # agent to perform file edits and shell commands. Controlled
# edits and shell commands without interactive prompts. # by SPECKIT_ALLOW_ALL_TOOLS env var (default: enabled).
# Controlled by SPECKIT_COPILOT_ALLOW_ALL_TOOLS env var import os
# (default: enabled). The deprecated SPECKIT_ALLOW_ALL_TOOLS
# is also honoured as a fallback.
args = ["copilot", "-p", prompt] args = ["copilot", "-p", prompt]
if _allow_all(): if os.environ.get("SPECKIT_ALLOW_ALL_TOOLS", "1") != "0":
args.append("--yolo") args.append("--allow-all-tools")
if model: if model:
args.extend(["--model", model]) args.extend(["--model", model])
if output_json: if output_json:
@@ -119,12 +91,13 @@ class CopilotIntegration(IntegrationBase):
agent_name = f"speckit.{stem}" agent_name = f"speckit.{stem}"
prompt = args or "" prompt = args or ""
import os
cli_args = [ cli_args = [
"copilot", "-p", prompt, "copilot", "-p", prompt,
"--agent", agent_name, "--agent", agent_name,
] ]
if _allow_all(): if os.environ.get("SPECKIT_ALLOW_ALL_TOOLS", "1") != "0":
cli_args.append("--yolo") cli_args.append("--allow-all-tools")
if model: if model:
cli_args.extend(["--model", model]) cli_args.extend(["--model", model])
if not stream: if not stream:

View File

@@ -5,17 +5,12 @@ from .test_integration_base_skills import SkillsIntegrationTests
class TestAgyIntegration(SkillsIntegrationTests): class TestAgyIntegration(SkillsIntegrationTests):
KEY = "agy" KEY = "agy"
FOLDER = ".agents/" FOLDER = ".agent/"
COMMANDS_SUBDIR = "skills" COMMANDS_SUBDIR = "skills"
REGISTRAR_DIR = ".agents/skills" REGISTRAR_DIR = ".agent/skills"
CONTEXT_FILE = "AGENTS.md" CONTEXT_FILE = "AGENTS.md"
def test_options_include_skills_flag(self):
"""Override inherited test: AgyIntegration should not expose a --skills flag because .agents/ is its only layout."""
from specify_cli.integrations import get_integration
i = get_integration(self.KEY)
skills_opts = [o for o in i.options() if o.name == "--skills"]
assert len(skills_opts) == 0
class TestAgyAutoPromote: class TestAgyAutoPromote:
"""--ai agy auto-promotes to integration path.""" """--ai agy auto-promotes to integration path."""
@@ -29,17 +24,4 @@ class TestAgyAutoPromote:
result = runner.invoke(app, ["init", str(target), "--ai", "agy", "--no-git", "--script", "sh"]) result = runner.invoke(app, ["init", str(target), "--ai", "agy", "--no-git", "--script", "sh"])
assert result.exit_code == 0, f"init --ai agy failed: {result.output}" assert result.exit_code == 0, f"init --ai agy failed: {result.output}"
assert (target / ".agents" / "skills" / "speckit-plan" / "SKILL.md").exists() assert (target / ".agent" / "skills" / "speckit-plan" / "SKILL.md").exists()
def test_agy_setup_warning(self, tmp_path):
"""Agy integration should print a warning about v1.20.5 requirement during setup."""
from typer.testing import CliRunner
from specify_cli import app
# Click >= 8.2 separates stdout and stderr natively, mix_stderr is removed
runner = CliRunner()
target = tmp_path / "test-proj2"
result = runner.invoke(app, ["init", str(target), "--ai", "agy", "--no-git", "--script", "sh"])
assert result.exit_code == 0
assert "Warning: The .agents/ layout requires Antigravity v1.20.5 or newer" in result.stderr

View File

@@ -1,6 +1,5 @@
"""Tests for ClaudeIntegration.""" """Tests for ClaudeIntegration."""
import codecs
import json import json
import os import os
from unittest.mock import patch from unittest.mock import patch
@@ -75,46 +74,6 @@ class TestClaudeIntegration:
assert "<!-- SPECKIT END -->" in content assert "<!-- SPECKIT END -->" in content
assert "read the current plan" in content assert "read the current plan" in content
def test_upsert_context_section_strips_bom(self, tmp_path):
"""Existing context file with UTF-8 BOM must be cleaned up on upsert."""
integration = get_integration("claude")
ctx_path = tmp_path / integration.context_file
# Write a file that starts with a UTF-8 BOM (as the old PowerShell script did)
bom = codecs.BOM_UTF8
ctx_path.write_bytes(bom + b"# CLAUDE.md\n\nSome existing content.\n")
integration.upsert_context_section(tmp_path)
result = ctx_path.read_bytes()
assert not result.startswith(bom), "BOM must be stripped after upsert"
content = result.decode("utf-8")
assert "<!-- SPECKIT START -->" in content
assert "Some existing content." in content
def test_remove_context_section_strips_bom(self, tmp_path):
"""remove_context_section must clean BOM from context file on Windows-authored files."""
integration = get_integration("claude")
ctx_path = tmp_path / integration.context_file
marker_content = (
"# CLAUDE.md\n\n"
"<!-- SPECKIT START -->\n"
"For additional context about technologies to be used, project structure,\n"
"shell commands, and other important information, read the current plan\n"
"<!-- SPECKIT END -->\n"
)
ctx_path.write_bytes(codecs.BOM_UTF8 + marker_content.encode("utf-8"))
result = integration.remove_context_section(tmp_path)
assert result is True
assert ctx_path.exists(), "File should exist (non-empty content remains)"
remaining = ctx_path.read_bytes()
assert not remaining.startswith(codecs.BOM_UTF8), "BOM must be stripped after remove"
assert b"<!-- SPECKIT" not in remaining
assert b"# CLAUDE.md" in remaining
def test_ai_flag_auto_promotes_and_enables_skills(self, tmp_path): def test_ai_flag_auto_promotes_and_enables_skills(self, tmp_path):
from typer.testing import CliRunner from typer.testing import CliRunner
from specify_cli import app from specify_cli import app

View File

@@ -2447,7 +2447,7 @@ class TestPresetSkills:
def test_agy_skill_restored_on_preset_remove(self, project_dir, temp_dir): def test_agy_skill_restored_on_preset_remove(self, project_dir, temp_dir):
"""Agy preset removal should restore native skills instead of deleting them.""" """Agy preset removal should restore native skills instead of deleting them."""
self._write_init_options(project_dir, ai="agy", ai_skills=True) self._write_init_options(project_dir, ai="agy", ai_skills=True)
skills_dir = project_dir / ".agents" / "skills" skills_dir = project_dir / ".agent" / "skills"
self._create_skill(skills_dir, "speckit-specify", body="before override") self._create_skill(skills_dir, "speckit-specify", body="before override")
core_command = project_dir / ".specify" / "templates" / "commands" / "specify.md" core_command = project_dir / ".specify" / "templates" / "commands" / "specify.md"

View File

@@ -367,49 +367,15 @@ class TestBuildExecArgs:
assert args[2] == "do stuff" assert args[2] == "do stuff"
assert "--json" in args assert "--json" in args
def test_copilot_exec_args(self, monkeypatch): def test_copilot_exec_args(self):
monkeypatch.delenv("SPECKIT_COPILOT_ALLOW_ALL_TOOLS", raising=False)
monkeypatch.delenv("SPECKIT_ALLOW_ALL_TOOLS", raising=False)
from specify_cli.integrations.copilot import CopilotIntegration from specify_cli.integrations.copilot import CopilotIntegration
impl = CopilotIntegration() impl = CopilotIntegration()
args = impl.build_exec_args("do stuff", model="claude-sonnet-4-20250514") args = impl.build_exec_args("do stuff", model="claude-sonnet-4-20250514")
assert args[0] == "copilot" assert args[0] == "copilot"
assert "-p" in args assert "-p" in args
assert "--yolo" in args assert "--allow-all-tools" in args
assert "--model" in args assert "--model" in args
def test_copilot_new_env_var_disables_yolo(self, monkeypatch):
monkeypatch.setenv("SPECKIT_COPILOT_ALLOW_ALL_TOOLS", "0")
monkeypatch.delenv("SPECKIT_ALLOW_ALL_TOOLS", raising=False)
from specify_cli.integrations.copilot import CopilotIntegration
impl = CopilotIntegration()
args = impl.build_exec_args("do stuff")
assert "--yolo" not in args
def test_copilot_deprecated_env_var_still_honoured(self, monkeypatch):
monkeypatch.delenv("SPECKIT_COPILOT_ALLOW_ALL_TOOLS", raising=False)
monkeypatch.setenv("SPECKIT_ALLOW_ALL_TOOLS", "0")
import warnings
from specify_cli.integrations.copilot import CopilotIntegration
impl = CopilotIntegration()
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
args = impl.build_exec_args("do stuff")
assert "--yolo" not in args
assert any(
"SPECKIT_ALLOW_ALL_TOOLS is deprecated" in str(x.message)
and issubclass(x.category, UserWarning)
for x in w
)
def test_copilot_new_env_var_takes_precedence(self, monkeypatch):
monkeypatch.setenv("SPECKIT_COPILOT_ALLOW_ALL_TOOLS", "1")
monkeypatch.setenv("SPECKIT_ALLOW_ALL_TOOLS", "0")
from specify_cli.integrations.copilot import CopilotIntegration
impl = CopilotIntegration()
args = impl.build_exec_args("do stuff")
assert "--yolo" in args
def test_ide_only_returns_none(self): def test_ide_only_returns_none(self):
from specify_cli.integrations.windsurf import WindsurfIntegration from specify_cli.integrations.windsurf import WindsurfIntegration
impl = WindsurfIntegration() impl = WindsurfIntegration()
@@ -434,7 +400,6 @@ class TestCommandStep:
"""Test the command step type.""" """Test the command step type."""
def test_execute_basic(self): def test_execute_basic(self):
from unittest.mock import patch
from specify_cli.workflows.steps.command import CommandStep from specify_cli.workflows.steps.command import CommandStep
from specify_cli.workflows.base import StepContext, StepStatus from specify_cli.workflows.base import StepContext, StepStatus
@@ -448,8 +413,7 @@ class TestCommandStep:
"command": "speckit.specify", "command": "speckit.specify",
"input": {"args": "{{ inputs.name }}"}, "input": {"args": "{{ inputs.name }}"},
} }
with patch("specify_cli.workflows.steps.command.shutil.which", return_value=None): result = step.execute(config, ctx)
result = step.execute(config, ctx)
assert result.status == StepStatus.FAILED assert result.status == StepStatus.FAILED
assert result.output["command"] == "speckit.specify" assert result.output["command"] == "speckit.specify"
assert result.output["integration"] == "claude" assert result.output["integration"] == "claude"
@@ -510,7 +474,6 @@ class TestCommandStep:
def test_dispatch_not_attempted_without_cli(self): def test_dispatch_not_attempted_without_cli(self):
"""When the CLI tool is not installed, step should fail.""" """When the CLI tool is not installed, step should fail."""
from unittest.mock import patch
from specify_cli.workflows.steps.command import CommandStep from specify_cli.workflows.steps.command import CommandStep
from specify_cli.workflows.base import StepContext, StepStatus from specify_cli.workflows.base import StepContext, StepStatus
@@ -525,8 +488,7 @@ class TestCommandStep:
"command": "speckit.specify", "command": "speckit.specify",
"input": {"args": "{{ inputs.name }}"}, "input": {"args": "{{ inputs.name }}"},
} }
with patch("specify_cli.workflows.steps.command.shutil.which", return_value=None): result = step.execute(config, ctx)
result = step.execute(config, ctx)
assert result.status == StepStatus.FAILED assert result.status == StepStatus.FAILED
assert result.output["dispatched"] is False assert result.output["dispatched"] is False
assert result.error is not None assert result.error is not None
@@ -604,7 +566,6 @@ class TestPromptStep:
"""Test the prompt step type.""" """Test the prompt step type."""
def test_execute_basic(self): def test_execute_basic(self):
from unittest.mock import patch
from specify_cli.workflows.steps.prompt import PromptStep from specify_cli.workflows.steps.prompt import PromptStep
from specify_cli.workflows.base import StepContext, StepStatus from specify_cli.workflows.base import StepContext, StepStatus
@@ -618,8 +579,7 @@ class TestPromptStep:
"type": "prompt", "type": "prompt",
"prompt": "Review {{ inputs.file }} for security issues", "prompt": "Review {{ inputs.file }} for security issues",
} }
with patch("specify_cli.workflows.steps.prompt.shutil.which", return_value=None): result = step.execute(config, ctx)
result = step.execute(config, ctx)
assert result.status == StepStatus.FAILED assert result.status == StepStatus.FAILED
assert result.output["prompt"] == "Review auth.py for security issues" assert result.output["prompt"] == "Review auth.py for security issues"
assert result.output["integration"] == "claude" assert result.output["integration"] == "claude"
@@ -1351,7 +1311,6 @@ class TestWorkflowEngine:
engine.load_workflow("nonexistent") engine.load_workflow("nonexistent")
def test_execute_simple_workflow(self, project_dir): def test_execute_simple_workflow(self, project_dir):
from unittest.mock import patch
from specify_cli.workflows.engine import WorkflowEngine, WorkflowDefinition from specify_cli.workflows.engine import WorkflowEngine, WorkflowDefinition
from specify_cli.workflows.base import RunStatus from specify_cli.workflows.base import RunStatus
@@ -1374,8 +1333,7 @@ steps:
""" """
definition = WorkflowDefinition.from_string(yaml_str) definition = WorkflowDefinition.from_string(yaml_str)
engine = WorkflowEngine(project_dir) engine = WorkflowEngine(project_dir)
with patch("specify_cli.workflows.steps.command.shutil.which", return_value=None): state = engine.execute(definition, {"name": "login"})
state = engine.execute(definition, {"name": "login"})
assert state.status == RunStatus.FAILED assert state.status == RunStatus.FAILED
assert "step-one" in state.step_results assert "step-one" in state.step_results