Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions presets/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@
"updated_at": "2026-04-24T00:00:00Z",
"catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/presets/catalog.json",
"presets": {
"implement": {
"name": "Implement Workflow",
"id": "implement",
"version": "1.0.0",
"description": "Runs the implementation command through task handoff shards",
"author": "github",
"repository": "https://github.com/github/spec-kit",
"license": "MIT",
"bundled": true,
"requires": {
"speckit_version": ">=0.8.9.dev0"
},
"provides": {
"commands": 1,
"templates": 0
},
"tags": [
"implementation",
"workflow"
]
},
"lean": {
"name": "Lean Workflow",
"id": "lean",
Expand Down
27 changes: 27 additions & 0 deletions presets/implement/commands/speckit.implement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
description: Execute the implementation plan by splitting tasks.md into workflow handoff shards
---

## User Input

```text
$ARGUMENTS
```

If the user input references a handoff JSON file, execute that handoff directly:

1. Read the handoff JSON file.
2. Load only the listed `required_context_refs` plus any files needed inside `allowed_read_paths`.
3. Execute only the listed `task_ids`, respecting `allowed_write_paths` and `forbidden_actions`.
4. Mark only the completed listed tasks in `tasks.md`.
5. Run any `validation_commands` from the handoff, plus focused validation for changed files.

Do not run `specify workflow run` while executing a handoff JSON.

Otherwise, run the implementation workflow from the repository root:

```sh
specify workflow run speckit-implement -i integration=__AGENT__ -i args="$ARGUMENTS"
```

Wait for the workflow to complete. If it fails while building handoff shards, report the error and do not run `speckit.implement` manually. If a shard fails during fan-out, report the failing shard and preserve the generated handoff files for resume or debugging.
25 changes: 25 additions & 0 deletions presets/implement/preset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
schema_version: "1.0"

preset:
id: "implement"
name: "Implement Workflow"
version: "1.0.0"
description: "Runs the implementation command through task handoff shards"
author: "github"
repository: "https://github.com/github/spec-kit"
license: "MIT"

requires:
speckit_version: ">=0.8.9.dev0"

provides:
templates:
- type: "command"
name: "speckit.implement"
file: "commands/speckit.implement.md"
description: "Execute implementation through workflow-generated task handoffs"
replaces: "speckit.implement"

tags:
- "implementation"
- "workflow"
10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ packages = ["src/specify_cli"]
# Bundle core assets so `specify init` works without network access (air-gapped / enterprise)
# Page templates (exclude commands/ — bundled separately below to avoid duplication)
"templates/checklist-template.md" = "specify_cli/core_pack/templates/checklist-template.md"
"templates/architecture-development-template.md" = "specify_cli/core_pack/templates/architecture-development-template.md"
"templates/architecture-logical-template.md" = "specify_cli/core_pack/templates/architecture-logical-template.md"
"templates/architecture-physical-template.md" = "specify_cli/core_pack/templates/architecture-physical-template.md"
"templates/architecture-process-template.md" = "specify_cli/core_pack/templates/architecture-process-template.md"
"templates/architecture-scenario-template.md" = "specify_cli/core_pack/templates/architecture-scenario-template.md"
"templates/architecture-template.md" = "specify_cli/core_pack/templates/architecture-template.md"
"templates/agent-governance-template.md" = "specify_cli/core_pack/templates/agent-governance-template.md"
"templates/constitution-template.md" = "specify_cli/core_pack/templates/constitution-template.md"
"templates/plan-template.md" = "specify_cli/core_pack/templates/plan-template.md"
"templates/spec-template.md" = "specify_cli/core_pack/templates/spec-template.md"
Expand All @@ -42,7 +49,9 @@ packages = ["src/specify_cli"]
"extensions/git" = "specify_cli/core_pack/extensions/git"
# Bundled workflows (auto-installed during `specify init`)
"workflows/speckit" = "specify_cli/core_pack/workflows/speckit"
"workflows/speckit-implement" = "specify_cli/core_pack/workflows/speckit-implement"
# Bundled presets (installable via `specify preset add <name>` or `specify init --preset <name>`)
"presets/implement" = "specify_cli/core_pack/presets/implement"
"presets/lean" = "specify_cli/core_pack/presets/lean"

[project.optional-dependencies]
Expand Down Expand Up @@ -70,4 +79,3 @@ omit = ["*/tests/*", "*/__pycache__/*"]
precision = 2
show_missing = true
skip_covered = false

94 changes: 94 additions & 0 deletions scripts/bash/setup-arch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env bash

set -e

# Parse command line arguments
JSON_MODE=false

for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--help|-h)
echo "Usage: $0 [--json]"
echo " --json Output results in JSON format"
echo " --help Show this help message"
exit 0
;;
*)
;;
esac
done

# Get script directory and load common functions
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"

REPO_ROOT=$(get_repo_root)
ARCH_DIR="$REPO_ROOT/.specify/memory"
ARCH_FILE="$ARCH_DIR/architecture.md"
SCENARIO_VIEW="$ARCH_DIR/architecture-scenario-view.md"
LOGICAL_VIEW="$ARCH_DIR/architecture-logical-view.md"
PROCESS_VIEW="$ARCH_DIR/architecture-process-view.md"
DEVELOPMENT_VIEW="$ARCH_DIR/architecture-development-view.md"
PHYSICAL_VIEW="$ARCH_DIR/architecture-physical-view.md"

mkdir -p "$ARCH_DIR"

copy_template_if_missing() {
local template_name="$1"
local destination="$2"

if [[ -f "$destination" ]]; then
return 0
fi

local template
template=$(resolve_template "$template_name" "$REPO_ROOT") || true
if [[ -n "$template" ]] && [[ -f "$template" ]]; then
cp "$template" "$destination"
echo "Copied $template_name template to $destination"
else
echo "Warning: $template_name template not found"
touch "$destination"
fi
}

copy_template_if_missing "architecture-template" "$ARCH_FILE"
copy_template_if_missing "architecture-scenario-template" "$SCENARIO_VIEW"
copy_template_if_missing "architecture-logical-template" "$LOGICAL_VIEW"
copy_template_if_missing "architecture-process-template" "$PROCESS_VIEW"
copy_template_if_missing "architecture-development-template" "$DEVELOPMENT_VIEW"
copy_template_if_missing "architecture-physical-template" "$PHYSICAL_VIEW"

if $JSON_MODE; then
if has_jq; then
jq -cn \
--arg arch_file "$ARCH_FILE" \
--arg arch_dir "$ARCH_DIR" \
--arg scenario_view "$SCENARIO_VIEW" \
--arg logical_view "$LOGICAL_VIEW" \
--arg process_view "$PROCESS_VIEW" \
--arg development_view "$DEVELOPMENT_VIEW" \
--arg physical_view "$PHYSICAL_VIEW" \
'{ARCH_FILE:$arch_file,ARCH_DIR:$arch_dir,SCENARIO_VIEW:$scenario_view,LOGICAL_VIEW:$logical_view,PROCESS_VIEW:$process_view,DEVELOPMENT_VIEW:$development_view,PHYSICAL_VIEW:$physical_view}'
else
printf '{"ARCH_FILE":"%s","ARCH_DIR":"%s","SCENARIO_VIEW":"%s","LOGICAL_VIEW":"%s","PROCESS_VIEW":"%s","DEVELOPMENT_VIEW":"%s","PHYSICAL_VIEW":"%s"}\n' \
"$(json_escape "$ARCH_FILE")" \
"$(json_escape "$ARCH_DIR")" \
"$(json_escape "$SCENARIO_VIEW")" \
"$(json_escape "$LOGICAL_VIEW")" \
"$(json_escape "$PROCESS_VIEW")" \
"$(json_escape "$DEVELOPMENT_VIEW")" \
"$(json_escape "$PHYSICAL_VIEW")"
fi
else
echo "ARCH_FILE: $ARCH_FILE"
echo "ARCH_DIR: $ARCH_DIR"
echo "SCENARIO_VIEW: $SCENARIO_VIEW"
echo "LOGICAL_VIEW: $LOGICAL_VIEW"
echo "PROCESS_VIEW: $PROCESS_VIEW"
echo "DEVELOPMENT_VIEW: $DEVELOPMENT_VIEW"
echo "PHYSICAL_VIEW: $PHYSICAL_VIEW"
fi
86 changes: 86 additions & 0 deletions scripts/powershell/setup-arch.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env pwsh
# Setup project-level 4+1 architecture artifacts

[CmdletBinding()]
param(
[switch]$Json,
[switch]$Help
)

$ErrorActionPreference = 'Stop'

if ($Help) {
Write-Output "Usage: ./setup-arch.ps1 [-Json] [-Help]"
Write-Output " -Json Output results in JSON format"
Write-Output " -Help Show this help message"
exit 0
}

. "$PSScriptRoot/common.ps1"

function Convert-ToPlainPath {
param([Parameter(Mandatory = $true)][string]$Path)

if ($Path -like 'Microsoft.PowerShell.Core\FileSystem::*') {
return $Path.Substring('Microsoft.PowerShell.Core\FileSystem::'.Length)
}
return $Path
}

$repoRoot = Convert-ToPlainPath (Get-RepoRoot)
$archDir = Join-Path $repoRoot ".specify/memory"
$archFile = Join-Path $archDir "architecture.md"
$scenarioView = Join-Path $archDir "architecture-scenario-view.md"
$logicalView = Join-Path $archDir "architecture-logical-view.md"
$processView = Join-Path $archDir "architecture-process-view.md"
$developmentView = Join-Path $archDir "architecture-development-view.md"
$physicalView = Join-Path $archDir "architecture-physical-view.md"

New-Item -ItemType Directory -Path $archDir -Force | Out-Null

function Copy-TemplateIfMissing {
param(
[Parameter(Mandatory = $true)][string]$TemplateName,
[Parameter(Mandatory = $true)][string]$Destination
)

if (Test-Path -LiteralPath $Destination -PathType Leaf) {
return
}

$template = Resolve-Template -TemplateName $TemplateName -RepoRoot $repoRoot
if ($template -and (Test-Path -LiteralPath $template -PathType Leaf)) {
Copy-Item -LiteralPath $template -Destination $Destination -Force
Write-Output "Copied $TemplateName template to $Destination"
} else {
Write-Warning "$TemplateName template not found"
New-Item -ItemType File -Path $Destination -Force | Out-Null
}
}

Copy-TemplateIfMissing -TemplateName "architecture-template" -Destination $archFile
Copy-TemplateIfMissing -TemplateName "architecture-scenario-template" -Destination $scenarioView
Copy-TemplateIfMissing -TemplateName "architecture-logical-template" -Destination $logicalView
Copy-TemplateIfMissing -TemplateName "architecture-process-template" -Destination $processView
Copy-TemplateIfMissing -TemplateName "architecture-development-template" -Destination $developmentView
Copy-TemplateIfMissing -TemplateName "architecture-physical-template" -Destination $physicalView

if ($Json) {
[PSCustomObject]@{
ARCH_FILE = $archFile
ARCH_DIR = $archDir
SCENARIO_VIEW = $scenarioView
LOGICAL_VIEW = $logicalView
PROCESS_VIEW = $processView
DEVELOPMENT_VIEW = $developmentView
PHYSICAL_VIEW = $physicalView
} | ConvertTo-Json -Compress
} else {
Write-Output "ARCH_FILE: $archFile"
Write-Output "ARCH_DIR: $archDir"
Write-Output "SCENARIO_VIEW: $scenarioView"
Write-Output "LOGICAL_VIEW: $logicalView"
Write-Output "PROCESS_VIEW: $processView"
Write-Output "DEVELOPMENT_VIEW: $developmentView"
Write-Output "PHYSICAL_VIEW: $physicalView"
}
Loading