From d85851a8c8d4d97ec4d29845d94c24d41fe72bb0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:07:32 +0000 Subject: [PATCH 1/4] Add Figma Starter extension to community catalog Add figma-starter extension submitted by @vibhus to: - extensions/catalog.community.json (alphabetical order) - docs/community/extensions.md community extensions table Closes #3545 Assisted-by: GitHub Copilot (model: claude-sonnet-4.6, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/community/extensions.md | 1 + extensions/catalog.community.json | 37 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/docs/community/extensions.md b/docs/community/extensions.md index ebd49f380d..23c0e20cd5 100644 --- a/docs/community/extensions.md +++ b/docs/community/extensions.md @@ -54,6 +54,7 @@ The following community-contributed extensions are available in [`catalog.commun | DocGuard — CDD Enforcement | Doc-integrity engine with MCP server, SARIF output, and zero-LLM core. Validates, scores, and traces documentation against code — 24 validators, stable finding codes, spec-kit hooks. Pure Node.js. | `docs` | Read+Write | [spec-kit-docguard](https://github.com/raccioly/docguard) | | EARS Requirements Syntax | Author, lint, and convert requirements using EARS - the five industry-standard sentence patterns for unambiguous, testable requirements | `docs` | Read+Write | [spec-kit-ears](https://github.com/dhruv-15-03/spec-kit-ears) | | Extensify | Create and validate extensions and extension catalogs | `process` | Read+Write | [extensify](https://github.com/mnriem/spec-kit-extensions/tree/main/extensify) | +| Figma Starter | Turns a Figma section's screens into per-screen spec.md files, an app-level user-stories.md, and a build-order.md, then hands off to /speckit.specify | `integration` | Read+Write | [spec-kit-figma-starter](https://github.com/wavemaker/spec-kit-figma-starter) | | Fix Findings | Automated analyze-fix-reanalyze loop that resolves spec findings until clean | `code` | Read+Write | [spec-kit-fix-findings](https://github.com/Quratulain-bilal/spec-kit-fix-findings) | | FixIt Extension | Spec-aware bug fixing — maps bugs to spec artifacts, proposes a plan, applies minimal changes | `code` | Read+Write | [spec-kit-fixit](https://github.com/speckit-community/spec-kit-fixit) | | Fleet Orchestrator | Orchestrate a full feature lifecycle with human-in-the-loop gates across all SpecKit phases | `process` | Read+Write | [spec-kit-fleet](https://github.com/sharathsatish/spec-kit-fleet) | diff --git a/extensions/catalog.community.json b/extensions/catalog.community.json index 845be8e8a4..bf55014185 100644 --- a/extensions/catalog.community.json +++ b/extensions/catalog.community.json @@ -1295,6 +1295,43 @@ "created_at": "2026-07-08T00:00:00Z", "updated_at": "2026-07-08T00:00:00Z" }, + "figma-starter": { + "name": "Figma Starter", + "id": "figma-starter", + "description": "Turns a Figma section's screens into per-screen spec.md files, an app-level user-stories.md, and a build-order.md, then hands off to /speckit.specify.", + "author": "WaveMaker", + "version": "1.0.0", + "download_url": "https://github.com/wavemaker/spec-kit-figma-starter/archive/refs/tags/v1.0.0.zip", + "repository": "https://github.com/wavemaker/spec-kit-figma-starter", + "homepage": "https://github.com/wavemaker/spec-kit-figma-starter", + "documentation": "https://github.com/wavemaker/spec-kit-figma-starter/blob/main/README.md", + "changelog": "https://github.com/wavemaker/spec-kit-figma-starter/blob/main/CHANGELOG.md", + "license": "MIT", + "category": "integration", + "effect": "read-write", + "requires": { + "speckit_version": ">=0.1.0", + "tools": [ + { "name": "python3", "required": true } + ] + }, + "provides": { + "commands": 1, + "hooks": 1 + }, + "tags": [ + "figma", + "design", + "design-to-spec", + "ui", + "frontend" + ], + "verified": false, + "downloads": 0, + "stars": 0, + "created_at": "2026-07-15T00:00:00Z", + "updated_at": "2026-07-15T00:00:00Z" + }, "fix-findings": { "name": "Fix Findings", "id": "fix-findings", From 615ea0b930f872fef1bcb20958829e563ec50177 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:19:59 +0000 Subject: [PATCH 2/4] fix: add missing python3 >=3.8 version constraint in figma-starter catalog entry Assisted-by: GitHub Copilot (model: claude-sonnet-4.5, autonomous) --- extensions/catalog.community.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/catalog.community.json b/extensions/catalog.community.json index bf55014185..553efab025 100644 --- a/extensions/catalog.community.json +++ b/extensions/catalog.community.json @@ -1312,7 +1312,7 @@ "requires": { "speckit_version": ">=0.1.0", "tools": [ - { "name": "python3", "required": true } + { "name": "python3", "version": ">=3.8", "required": true } ] }, "provides": { From 92c1d367ec5af2373bfe9db0e46f35d541a178a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:52:55 +0000 Subject: [PATCH 3/4] fix(agent-context): reduce Python subprocess overhead in PS 5.1 YAML fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PowerShell update-agent-context.ps1 script falls back to Python when PS 5.1 (which lacks ConvertFrom-Yaml and cannot parse YAML as JSON) reads the extension config. It previously launched Python twice: once to verify that Python 3 + PyYAML were available, and once to run a temp script file that parsed the YAML and printed JSON. On Windows CI each Python startup—plus potential Windows Defender scanning of a freshly-created .tmp file—can take several seconds. With two launches plus PS 5.1's own startup time the subprocess.run(timeout=30) threshold in test_powershell_script_discovers_nested_plan was regularly exceeded, causing the CI job to fail. Replace the two-phase approach with a single Python -c one-liner that verifies PyYAML availability, parses the YAML file, and emits JSON in one process. This halves the number of Python launches and eliminates the temp file entirely, keeping total execution time well under 30 s. Assisted-by: GitHub Copilot (model: claude-sonnet-4.5, autonomous) --- .../powershell/update-agent-context.ps1 | 67 +++++-------------- 1 file changed, 17 insertions(+), 50 deletions(-) diff --git a/extensions/agent-context/scripts/powershell/update-agent-context.ps1 b/extensions/agent-context/scripts/powershell/update-agent-context.ps1 index 91d067cc41..967fbb4bf0 100644 --- a/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +++ b/extensions/agent-context/scripts/powershell/update-agent-context.ps1 @@ -200,63 +200,30 @@ if ($null -eq $Options) { if ($null -eq $Options) { # ConvertFrom-Yaml/Json unavailable or failed; fall back to Python+PyYAML. - $pythonCmd = $null + # Combine verification and parsing into one Python invocation: a single process + # launch instead of two (verify then run a temp script file). On Windows + # PowerShell 5.1 each Python startup—plus any AV scan of a freshly-created temp + # file—can take several seconds, making two launches easy to exceed a 30 s + # test timeout. The -c one-liner avoids the temp file entirely. $pythonCandidates = @() if ($env:SPECKIT_PYTHON) { $pythonCandidates += $env:SPECKIT_PYTHON } $pythonCandidates += @('python3', 'python') + $pyOneLiner = "import sys,json,yaml; d=yaml.safe_load(open(sys.argv[1],'r',encoding='utf-8').read()); d=d if isinstance(d,dict) else {}; print(json.dumps(d))" foreach ($candidate in $pythonCandidates) { if (Get-Command $candidate -ErrorAction SilentlyContinue) { - # Verify it is Python 3 with PyYAML available. - $null = & $candidate -c "import sys; import yaml; sys.exit(0 if sys.version_info[0] == 3 else 1)" 2>$null - if ($LASTEXITCODE -eq 0) { - $pythonCmd = $candidate - break - } - } - } - - if ($pythonCmd) { - $pyScript = $null - try { - $pyScript = [System.IO.Path]::GetTempFileName() - Set-Content -LiteralPath $pyScript -Encoding UTF8 -Value @' -import json -import sys -try: - import yaml -except ImportError: - print( - "agent-context: PyYAML is required to parse extension config; cannot update context.", - file=sys.stderr, - ) - sys.exit(2) - -try: - with open(sys.argv[1], "r", encoding="utf-8") as fh: - data = yaml.safe_load(fh) -except Exception as exc: - print( - f"agent-context: unable to parse {sys.argv[1]} ({exc}); cannot update context.", - file=sys.stderr, - ) - sys.exit(2) - -if not isinstance(data, dict): - data = {} - -print(json.dumps(data)) -'@ - $jsonOut = & $pythonCmd $pyScript $ExtConfig - if ($LASTEXITCODE -eq 0 -and $jsonOut) { - $Options = $jsonOut | ConvertFrom-Json -ErrorAction Stop - } - } catch { - $Options = $null - } finally { - if ($pyScript -and (Test-Path -LiteralPath $pyScript)) { - Remove-Item -LiteralPath $pyScript -Force -ErrorAction SilentlyContinue + try { + $jsonOut = & $candidate -c $pyOneLiner $ExtConfig 2>$null + if ($LASTEXITCODE -eq 0 -and $jsonOut) { + $parsed = $jsonOut | ConvertFrom-Json -ErrorAction Stop + if (Test-ConfigObject -Object $parsed) { + $Options = $parsed + break + } + } + } catch { + # ConvertFrom-Json failed; try next candidate. } } } From 24d7b56299e0110d963f9e507e38ac591cb5f214 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:18:46 +0000 Subject: [PATCH 4/4] revert(agent-context): restore update-agent-context.ps1 to pre-optimization state The runtime optimization (one-liner Python fallback, stderr suppression) was unrelated to the Figma Starter catalog addition (issue #3545) and removed the actionable PyYAML/parse diagnostic messages. Revert the file so the PR only contains the catalog-entry and documentation changes. Assisted-by: GitHub Copilot (model: claude-sonnet-4.6, autonomous) --- .../powershell/update-agent-context.ps1 | 67 ++++++++++++++----- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/extensions/agent-context/scripts/powershell/update-agent-context.ps1 b/extensions/agent-context/scripts/powershell/update-agent-context.ps1 index 967fbb4bf0..91d067cc41 100644 --- a/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +++ b/extensions/agent-context/scripts/powershell/update-agent-context.ps1 @@ -200,30 +200,63 @@ if ($null -eq $Options) { if ($null -eq $Options) { # ConvertFrom-Yaml/Json unavailable or failed; fall back to Python+PyYAML. - # Combine verification and parsing into one Python invocation: a single process - # launch instead of two (verify then run a temp script file). On Windows - # PowerShell 5.1 each Python startup—plus any AV scan of a freshly-created temp - # file—can take several seconds, making two launches easy to exceed a 30 s - # test timeout. The -c one-liner avoids the temp file entirely. + $pythonCmd = $null $pythonCandidates = @() if ($env:SPECKIT_PYTHON) { $pythonCandidates += $env:SPECKIT_PYTHON } $pythonCandidates += @('python3', 'python') - $pyOneLiner = "import sys,json,yaml; d=yaml.safe_load(open(sys.argv[1],'r',encoding='utf-8').read()); d=d if isinstance(d,dict) else {}; print(json.dumps(d))" foreach ($candidate in $pythonCandidates) { if (Get-Command $candidate -ErrorAction SilentlyContinue) { - try { - $jsonOut = & $candidate -c $pyOneLiner $ExtConfig 2>$null - if ($LASTEXITCODE -eq 0 -and $jsonOut) { - $parsed = $jsonOut | ConvertFrom-Json -ErrorAction Stop - if (Test-ConfigObject -Object $parsed) { - $Options = $parsed - break - } - } - } catch { - # ConvertFrom-Json failed; try next candidate. + # Verify it is Python 3 with PyYAML available. + $null = & $candidate -c "import sys; import yaml; sys.exit(0 if sys.version_info[0] == 3 else 1)" 2>$null + if ($LASTEXITCODE -eq 0) { + $pythonCmd = $candidate + break + } + } + } + + if ($pythonCmd) { + $pyScript = $null + try { + $pyScript = [System.IO.Path]::GetTempFileName() + Set-Content -LiteralPath $pyScript -Encoding UTF8 -Value @' +import json +import sys +try: + import yaml +except ImportError: + print( + "agent-context: PyYAML is required to parse extension config; cannot update context.", + file=sys.stderr, + ) + sys.exit(2) + +try: + with open(sys.argv[1], "r", encoding="utf-8") as fh: + data = yaml.safe_load(fh) +except Exception as exc: + print( + f"agent-context: unable to parse {sys.argv[1]} ({exc}); cannot update context.", + file=sys.stderr, + ) + sys.exit(2) + +if not isinstance(data, dict): + data = {} + +print(json.dumps(data)) +'@ + $jsonOut = & $pythonCmd $pyScript $ExtConfig + if ($LASTEXITCODE -eq 0 -and $jsonOut) { + $Options = $jsonOut | ConvertFrom-Json -ErrorAction Stop + } + } catch { + $Options = $null + } finally { + if ($pyScript -and (Test-Path -LiteralPath $pyScript)) { + Remove-Item -LiteralPath $pyScript -Force -ErrorAction SilentlyContinue } } }