Skip to content

Commit 389c0e0

Browse files
committed
feat: update changelog for version 1.3.0 and enhance site-audit and PR review scripts with new sampling and inventory options
1 parent 8224ec2 commit 389c0e0

14 files changed

Lines changed: 252 additions & 29 deletions

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ All notable changes to the Specify CLI and templates are documented here.
77
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10+
## [1.3.0] - 2026-03-19
11+
12+
### Fixed
13+
14+
- **`/speckit.site-audit` performance on large repositories**: Reduced default PowerShell pre-scan JSON payload size by returning sampled file inventories and sampled pattern findings with full counts, while keeping full inventories available via an explicit opt-in switch (`--full-inventory` / `--include-full-inventory`).
15+
- **JSON rendering overhead in chat surfaces**: Switched site-audit pre-scan JSON output from compressed single-line output to multiline JSON to reduce UI/context processing pressure.
16+
- **Unbounded audit expansion risk**: Added explicit execution guardrails in the site-audit command template to limit findings, search breadth, and per-finding file reads, and to stop once high-signal evidence is sufficient.
17+
- **`/speckit.pr-review` large PR payload risk**: Added bounded file list output in PowerShell PR context pre-scan (`files_changed_total`, `files_changed_truncated`, sample limit) with an opt-in switch for full file inventory, and added prompt-level scope limits for deep file inspection.
18+
- **`/speckit.archive` large candidate-set expansion risk**: Added sampled candidate arrays with full counts and opt-in full inventory in PowerShell archive context output, plus prompt guardrails to avoid unbounded candidate reading in a single pass.
19+
- **Defensive JSON output standardization**: Converted remaining PowerShell context scripts from compressed single-line JSON to multiline JSON to reduce chat/UI rendering pressure and improve diagnostics readability.
20+
1021
## [1.2.4] - 2026-03-07
1122

1223
### Added

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 = "1.2.4"
3+
version = "1.3.0"
44
description = "Specify CLI, part of Spec Kit Spark. A community extension with constitution-powered commands for Spec-Driven Development (SDD)."
55
requires-python = ">=3.11"
66
dependencies = [

scripts/powershell/archive-context.ps1

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
param(
77
[Parameter(Position = 0, ValueFromRemainingArguments)]
88
[string[]]$Arguments,
9-
[switch]$Json
9+
[switch]$Json,
10+
[switch]$IncludeFullInventory,
11+
[int]$SampleLimit = 50
1012
)
1113

1214
. (Join-Path $PSScriptRoot 'common.ps1')
@@ -31,6 +33,23 @@ function Get-RelativeMdFiles {
3133
Sort-Object
3234
}
3335

36+
function Get-SampledItems {
37+
param(
38+
[array]$Items,
39+
[int]$Limit
40+
)
41+
42+
if (-not $Items) {
43+
return @()
44+
}
45+
46+
return @($Items | Select-Object -First $Limit)
47+
}
48+
49+
if ($SampleLimit -lt 1) {
50+
$SampleLimit = 50
51+
}
52+
3453
# Candidate categories
3554
$drafts = Get-RelativeMdFiles '.documentation/drafts'
3655
$sessionDocs = Get-RelativeMdFiles '.documentation/copilot'
@@ -68,26 +87,59 @@ $guideExists = Test-Path (Join-Path $repoRoot $guidePath)
6887
$changelogExists = Test-Path (Join-Path $repoRoot $changelogPath)
6988

7089
if ($Json) {
90+
$candidateCounts = @{
91+
drafts = $drafts.Count
92+
session_docs = $sessionDocs.Count
93+
implementation_plans = $implPlans.Count
94+
release_docs = $releaseDocs.Count
95+
quickfix_records = $quickfixRecords.Count
96+
pr_reviews = $prReviews.Count
97+
}
98+
99+
$currentDocsCount = $currentDocs.Count
100+
71101
@{
72102
REPO_ROOT = $repoRoot
73103
TIMESTAMP = $timestamp
74104
ARCHIVE_DIR = $archiveDir
75105
ARCHIVE_EXISTS = $archiveExists
76-
EXISTING_ARCHIVES = $existingArchives
106+
EXISTING_ARCHIVES = Get-SampledItems -Items $existingArchives -Limit $SampleLimit
107+
EXISTING_ARCHIVES_COUNT = $existingArchives.Count
77108
GUIDE_PATH = $guidePath
78109
GUIDE_EXISTS = $guideExists
79110
CHANGELOG_PATH = $changelogPath
80111
CHANGELOG_EXISTS = $changelogExists
112+
SAMPLE_LIMIT = $SampleLimit
113+
INCLUDE_FULL_INVENTORY = [bool]$IncludeFullInventory
114+
CANDIDATE_COUNTS = $candidateCounts
81115
CANDIDATES = @{
82-
drafts = $drafts
83-
session_docs = $sessionDocs
84-
implementation_plans = $implPlans
85-
release_docs = $releaseDocs
86-
quickfix_records = $quickfixRecords
87-
pr_reviews = $prReviews
116+
drafts = Get-SampledItems -Items $drafts -Limit $SampleLimit
117+
session_docs = Get-SampledItems -Items $sessionDocs -Limit $SampleLimit
118+
implementation_plans = Get-SampledItems -Items $implPlans -Limit $SampleLimit
119+
release_docs = Get-SampledItems -Items $releaseDocs -Limit $SampleLimit
120+
quickfix_records = Get-SampledItems -Items $quickfixRecords -Limit $SampleLimit
121+
pr_reviews = Get-SampledItems -Items $prReviews -Limit $SampleLimit
88122
}
89-
CURRENT_DOCS = $currentDocs
90-
} | ConvertTo-Json -Depth 5 -Compress
123+
CURRENT_DOCS = Get-SampledItems -Items $currentDocs -Limit $SampleLimit
124+
CURRENT_DOCS_COUNT = $currentDocsCount
125+
126+
FULL_INVENTORY = $(if ($IncludeFullInventory) {
127+
@{
128+
existing_archives = $existingArchives
129+
candidates = @{
130+
drafts = $drafts
131+
session_docs = $sessionDocs
132+
implementation_plans = $implPlans
133+
release_docs = $releaseDocs
134+
quickfix_records = $quickfixRecords
135+
pr_reviews = $prReviews
136+
}
137+
current_docs = $currentDocs
138+
}
139+
} else {
140+
$null
141+
})
142+
} | ConvertTo-Json -Depth 8
91143
}
92144
else {
93145
Write-Output "Archive Context"

scripts/powershell/check-prerequisites.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ if ($PathsOnly) {
7373
FEATURE_SPEC = $paths.FEATURE_SPEC
7474
IMPL_PLAN = $paths.IMPL_PLAN
7575
TASKS = $paths.TASKS
76-
} | ConvertTo-Json -Compress
76+
} | ConvertTo-Json
7777
} else {
7878
Write-Output "REPO_ROOT: $($paths.REPO_ROOT)"
7979
Write-Output "BRANCH: $($paths.CURRENT_BRANCH)"
@@ -130,7 +130,7 @@ if ($Json) {
130130
[PSCustomObject]@{
131131
FEATURE_DIR = $paths.FEATURE_DIR
132132
AVAILABLE_DOCS = $docs
133-
} | ConvertTo-Json -Compress
133+
} | ConvertTo-Json
134134
} else {
135135
# Text output
136136
Write-Output "FEATURE_DIR:$($paths.FEATURE_DIR)"

scripts/powershell/create-new-feature.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ if ($Json) {
272272
FEATURE_NUM = $featureNum
273273
HAS_GIT = $hasGit
274274
}
275-
$obj | ConvertTo-Json -Compress
275+
$obj | ConvertTo-Json
276276
} else {
277277
Write-Output "BRANCH_NAME: $branchName"
278278
Write-Output "SPEC_FILE: $specFile"

scripts/powershell/evolution-context.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ if ($Json) {
145145
FROM_AUDIT = $fromAudit
146146
SUGGESTION = $suggestion
147147
TIMESTAMP = $timestamp
148-
} | ConvertTo-Json -Compress
148+
} | ConvertTo-Json
149149
}
150150
else {
151151
Write-Output "Constitution Evolution Context"

scripts/powershell/get-pr-context.ps1

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,20 @@
88
# ./get-pr-context.ps1 -Json # Auto-detect PR from current branch
99
# ./get-pr-context.ps1 123 -Json # Specific PR number
1010
# ./get-pr-context.ps1 "#123" -Json # Also accepts # prefix
11+
# ./get-pr-context.ps1 123 -Json -IncludeAllFiles
1112

1213
param(
1314
[Parameter(Position=0)]
1415
[string]$PrNumber,
1516

1617
[Parameter()]
17-
[switch]$Json
18+
[switch]$Json,
19+
20+
[Parameter()]
21+
[switch]$IncludeAllFiles,
22+
23+
[Parameter()]
24+
[int]$FileSampleLimit = 200
1825
)
1926

2027
$ErrorActionPreference = "Stop"
@@ -41,7 +48,7 @@ function Write-JsonError {
4148
error = $true
4249
message = $Message
4350
details = $Details
44-
} | ConvertTo-Json -Compress
51+
} | ConvertTo-Json
4552
Write-Output $errorObj
4653
} else {
4754
Write-Error $Message
@@ -51,6 +58,10 @@ function Write-JsonError {
5158
}
5259
}
5360

61+
if ($FileSampleLimit -lt 1) {
62+
$FileSampleLimit = 200
63+
}
64+
5465
#==============================================================================
5566
# PR Number Detection
5667
#==============================================================================
@@ -148,7 +159,14 @@ try {
148159
}
149160

150161
# Extract file list
151-
$filesChanged = $prData.files | ForEach-Object { $_.path }
162+
$allFilesChanged = @($prData.files | ForEach-Object { $_.path })
163+
$filesChangedTotal = $allFilesChanged.Count
164+
$filesChangedTruncated = $false
165+
$filesChanged = $allFilesChanged
166+
if (-not $IncludeAllFiles -and $filesChangedTotal -gt $FileSampleLimit) {
167+
$filesChanged = @($allFilesChanged | Select-Object -First $FileSampleLimit)
168+
$filesChangedTruncated = $true
169+
}
152170

153171
# Check for constitution
154172
$constitutionPath = Join-Path $repoRoot.Path ".documentation\memory\constitution.md"
@@ -173,16 +191,20 @@ if ($Json) {
173191
commit_sha = $commitSha
174192
commit_count = $prData.commits.Count
175193
files_changed = $filesChanged
194+
files_changed_total = $filesChangedTotal
195+
files_changed_truncated = $filesChangedTruncated
176196
lines_added = $prData.additions ?? 0
177197
lines_deleted = $prData.deletions ?? 0
178198
created_at = $prData.createdAt
179199
updated_at = $prData.updatedAt
180200
diff_available = $diffAvailable
201+
file_sample_limit = $FileSampleLimit
202+
include_all_files = [bool]$IncludeAllFiles
181203
}
182204
CONSTITUTION_PATH = $constitutionPath
183205
CONSTITUTION_EXISTS = $constitutionExists
184206
REVIEW_DIR = $reviewDir
185-
} | ConvertTo-Json -Depth 10 -Compress
207+
} | ConvertTo-Json -Depth 10
186208

187209
Write-Output $output
188210
} else {

scripts/powershell/quickfix-context.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ if ($Json) {
121121
RISK_LEVEL = $riskLevel
122122
MAX_EFFORT = $maxEffort
123123
QUICKFIXES = $quickfixes
124-
} | ConvertTo-Json -Compress
124+
} | ConvertTo-Json
125125
}
126126
else {
127127
Write-Output "Quickfix Context"

scripts/powershell/release-context.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ if ($Json) {
196196
DRY_RUN = [bool]$DryRun
197197
SPECKIT_VERSION_PATH = $specKitVersionPath
198198
INSTALLED_VERSION = $installedVersion
199-
} | ConvertTo-Json -Compress
199+
} | ConvertTo-Json
200200
}
201201
else {
202202
Write-Output "Release Context"

scripts/powershell/setup-plan.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ if ($Json) {
5151
BRANCH = $paths.CURRENT_BRANCH
5252
HAS_GIT = $paths.HAS_GIT
5353
}
54-
$result | ConvertTo-Json -Compress
54+
$result | ConvertTo-Json
5555
} else {
5656
Write-Output "FEATURE_SPEC: $($paths.FEATURE_SPEC)"
5757
Write-Output "IMPL_PLAN: $($paths.IMPL_PLAN)"

0 commit comments

Comments
 (0)