@caddis/cli 0.4.25 → 0.4.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "caddis",
3
- "version": "1.3.114",
3
+ "version": "1.3.115",
4
4
  "description": "caddis — agent-agnostic dev harness as an Antigravity (agy) plugin: TDD skills + commands, single-sourced with the Claude Code plugin."
5
5
  }
@@ -146,6 +146,7 @@ $script:AdoptScanBlock = {
146
146
  healthHits = @()
147
147
  totalFiles = 0
148
148
  totalMB = 0.0
149
+ trackedKnown = $false
149
150
  probed = 0
150
151
  git = @{ isRepo = $false }
151
152
  }
@@ -232,6 +233,22 @@ $script:AdoptScanBlock = {
232
233
  else { $g.upstream = $null; $g.unpushed = $null }
233
234
  }
234
235
 
236
+ # ---- which files git actually tracks ---------------------------------------------
237
+ # PER FILE, not per folder. A folder is routinely BOTH: `reports/` carried 40 committed
238
+ # markdown documents and a gigabyte of correctly-ignored run output, and attributing the
239
+ # folder's whole size to its folder-level state reported "1018 MB of data exports are
240
+ # committed" when the real figure was 0.15 MB. That is not a rounding error, it is a
241
+ # different finding - and it would have sent someone to rewrite history for nothing.
242
+ $trackedSet = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::OrdinalIgnoreCase)
243
+ $trackedKnown = $false
244
+ if ($result.git.isRepo -and $gitAvailable) {
245
+ $ls = @(& git -c safe.directory=* -C $root ls-files 2>&1)
246
+ if ($LASTEXITCODE -eq 0) {
247
+ $trackedKnown = $true
248
+ foreach ($f in $ls) { [void]$trackedSet.Add(("$f" -replace '/', '\')) }
249
+ }
250
+ }
251
+
235
252
  # ---- one bounded walk per top-level folder --------------------------------------
236
253
  $tops = @()
237
254
  try { $tops = @(Get-ChildItem -LiteralPath $root -Force -ErrorAction Stop | Where-Object { $_.PSIsContainer }) }
@@ -301,7 +318,7 @@ $script:AdoptScanBlock = {
301
318
 
302
319
  foreach ($spec in $ExcludableSpecs) {
303
320
  if ($rel -match $spec.pattern) {
304
- $result.excludable += @{ path = $rel; category = $spec.category; bytes = $file.Length }
321
+ $result.excludable += @{ path = $rel; category = $spec.category; bytes = $file.Length; tracked = $trackedSet.Contains($rel) }
305
322
  break
306
323
  }
307
324
  }
@@ -345,7 +362,7 @@ $script:AdoptScanBlock = {
345
362
  if ($rel -notmatch $SkipPattern) { & $classify $k $rel }
346
363
  else {
347
364
  foreach ($spec in $ExcludableSpecs) {
348
- if ($rel -match $spec.pattern) { $result.excludable += @{ path = $rel; category = $spec.category; bytes = $k.Length }; break }
365
+ if ($rel -match $spec.pattern) { $result.excludable += @{ path = $rel; category = $spec.category; bytes = $k.Length; tracked = $trackedSet.Contains($rel) }; break }
349
366
  }
350
367
  }
351
368
 
@@ -416,6 +433,7 @@ $script:AdoptScanBlock = {
416
433
  }
417
434
  }
418
435
  $result.totalMB = [math]::Round($result.totalMB, 2)
436
+ $result.trackedKnown = $trackedKnown
419
437
  $result.paths = @($detectPaths)
420
438
  if ($detectPaths.Count -ge $DetectPathCap) {
421
439
  $result.partial = $true
@@ -116,17 +116,23 @@ $inventory = [ordered]@{
116
116
 
117
117
  # Roll the excludable file list up per top folder. A list of 40,000 paths is unreadable and
118
118
  # the decision is taken per folder anyway.
119
+ # Grouped by folder, category AND whether git tracks the file. A folder is routinely both:
120
+ # committed documents beside a gigabyte of correctly-ignored output. Rolling those together
121
+ # and labelling the total with the folder's state turned 0.15 MB of committed markdown into
122
+ # a report of "1018 MB of data exports are committed".
119
123
  $byFolder = @{}
120
124
  foreach ($e in @($scan.excludable)) {
121
125
  $top = ($e.path -split '[\\/]')[0]
122
- $key = "$top|$($e.category)"
123
- if (-not $byFolder.ContainsKey($key)) { $byFolder[$key] = @{ folder = $top; category = $e.category; files = 0; bytes = [long]0 } }
126
+ $isTracked = [bool](Get-AdoptProp $e 'tracked' $false)
127
+ $key = "$top|$($e.category)|$isTracked"
128
+ if (-not $byFolder.ContainsKey($key)) { $byFolder[$key] = @{ folder = $top; category = $e.category; tracked = $isTracked; files = 0; bytes = [long]0 } }
124
129
  $byFolder[$key].files++
125
130
  $byFolder[$key].bytes += [long]$e.bytes
126
131
  }
127
132
  $inventory.excludableSummary = @($byFolder.Values |
128
- ForEach-Object { [ordered]@{ folder = $_.folder; category = $_.category; files = $_.files; mb = [math]::Round($_.bytes / 1MB, 2) } } |
133
+ ForEach-Object { [ordered]@{ folder = $_.folder; category = $_.category; tracked = $_.tracked; files = $_.files; mb = [math]::Round($_.bytes / 1MB, 2) } } |
129
134
  Sort-Object { -1 * $_.mb })
135
+ $inventory.trackedKnown = [bool](Get-AdoptProp $scan 'trackedKnown' $false)
130
136
 
131
137
  $out = Write-AdoptArtifact -Dir $dir -FileName 'inventory.json' -Object $inventory
132
138
 
@@ -181,8 +187,12 @@ if ($ignoredBig.Count -gt 0) {
181
187
  Write-AdoptHeading 'What the repository must not carry'
182
188
  if ($inventory.excludableSummary.Count -eq 0) { Write-Host " nothing found" }
183
189
  foreach ($e in @($inventory.excludableSummary | Select-Object -First 15)) {
184
- Write-Host (" {0,10:N1} MB {1,7} files {2,-13} {3}" -f $e.mb, $e.files, $e.category, $e.folder)
190
+ $state = if ($e.tracked) { 'COMMITTED' } else { 'not committed' }
191
+ $colour = if ($e.tracked) { 'Yellow' } else { 'Gray' }
192
+ Write-Host (" {0,10:N1} MB {1,7} files {2,-13} {3,-14} {4}" -f $e.mb, $e.files, $e.category, $state, $e.folder) -ForegroundColor $colour
185
193
  }
194
+ Write-Host " Only the COMMITTED rows need a history rewrite. The rest need a .gitignore line," -ForegroundColor DarkGray
195
+ Write-Host " or already have one." -ForegroundColor DarkGray
186
196
 
187
197
  Write-AdoptHeading 'Possible credentials'
188
198
  if ($inventory.secretsSuspected.Count -eq 0) { Write-Host " none found by the heuristics - which is not the same as none present" }
@@ -73,10 +73,8 @@ if ($so -and $so.verdict -eq 'GAP') {
73
73
  $lines += "$($f.path) - $($f.mb) MB, neither committed nor ignored: commit it, ignore it, or move it out of the tree"
74
74
  }
75
75
  foreach ($e in @($inv.excludableSummary | Select-Object -First 10)) {
76
- $g = @($inv.size.folders | Where-Object { $_.path -eq $e.folder })
77
- if ($g.Count -gt 0 -and $g[0].git -eq 'tracked') {
78
- $lines += "$($e.folder) - $($e.mb) MB of $($e.category) is COMMITTED: needs a history rewrite, not a .gitignore line"
79
- }
76
+ if (-not (Get-AdoptProp $e 'tracked' $false)) { continue }
77
+ $lines += "$($e.folder) - $($e.files) file(s), $($e.mb) MB of $($e.category) is COMMITTED: a .gitignore line does not remove it, only a history rewrite does"
80
78
  }
81
79
  Add-Step 'content-policy' 'Settle what the repository may hold' @('answers') `
82
80
  'A .gitignore added later does not remove what is already committed, and a folder that is neither committed nor ignored is one careless command away from being permanent.' `
@@ -72,10 +72,12 @@ $componentProfiles = @($prof.components | ForEach-Object { $_.profile })
72
72
  $isBatchOnly = ($componentProfiles.Count -gt 0) -and (@($componentProfiles | Where-Object { $_ -notmatch 'batch' }).Count -eq 0)
73
73
 
74
74
  $untrackedBig = @($folders | Where-Object { $_.git -eq 'untracked' -and $_.path -ne '.git' -and $_.mb -ge $UntrackedThresholdMB })
75
+ # Per FILE, from git itself - not "this folder is tracked, so all of its bytes are".
75
76
  $trackedJunk = @()
76
77
  foreach ($e in @($inv.excludableSummary)) {
77
- $f = @($folders | Where-Object { $_.path -eq $e.folder })
78
- if ($f.Count -gt 0 -and $f[0].git -eq 'tracked' -and $e.category -ne 'log') { $trackedJunk += $e }
78
+ if (-not (Get-AdoptProp $e 'tracked' $false)) { continue }
79
+ if ($e.category -eq 'log') { continue }
80
+ $trackedJunk += $e
79
81
  }
80
82
  $ignoredHeavy = @($folders | Where-Object { $_.git -eq 'ignored' -and $_.mb -ge 100 })
81
83
 
@@ -146,6 +146,7 @@ $script:AdoptScanBlock = {
146
146
  healthHits = @()
147
147
  totalFiles = 0
148
148
  totalMB = 0.0
149
+ trackedKnown = $false
149
150
  probed = 0
150
151
  git = @{ isRepo = $false }
151
152
  }
@@ -232,6 +233,22 @@ $script:AdoptScanBlock = {
232
233
  else { $g.upstream = $null; $g.unpushed = $null }
233
234
  }
234
235
 
236
+ # ---- which files git actually tracks ---------------------------------------------
237
+ # PER FILE, not per folder. A folder is routinely BOTH: `reports/` carried 40 committed
238
+ # markdown documents and a gigabyte of correctly-ignored run output, and attributing the
239
+ # folder's whole size to its folder-level state reported "1018 MB of data exports are
240
+ # committed" when the real figure was 0.15 MB. That is not a rounding error, it is a
241
+ # different finding - and it would have sent someone to rewrite history for nothing.
242
+ $trackedSet = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::OrdinalIgnoreCase)
243
+ $trackedKnown = $false
244
+ if ($result.git.isRepo -and $gitAvailable) {
245
+ $ls = @(& git -c safe.directory=* -C $root ls-files 2>&1)
246
+ if ($LASTEXITCODE -eq 0) {
247
+ $trackedKnown = $true
248
+ foreach ($f in $ls) { [void]$trackedSet.Add(("$f" -replace '/', '\')) }
249
+ }
250
+ }
251
+
235
252
  # ---- one bounded walk per top-level folder --------------------------------------
236
253
  $tops = @()
237
254
  try { $tops = @(Get-ChildItem -LiteralPath $root -Force -ErrorAction Stop | Where-Object { $_.PSIsContainer }) }
@@ -301,7 +318,7 @@ $script:AdoptScanBlock = {
301
318
 
302
319
  foreach ($spec in $ExcludableSpecs) {
303
320
  if ($rel -match $spec.pattern) {
304
- $result.excludable += @{ path = $rel; category = $spec.category; bytes = $file.Length }
321
+ $result.excludable += @{ path = $rel; category = $spec.category; bytes = $file.Length; tracked = $trackedSet.Contains($rel) }
305
322
  break
306
323
  }
307
324
  }
@@ -345,7 +362,7 @@ $script:AdoptScanBlock = {
345
362
  if ($rel -notmatch $SkipPattern) { & $classify $k $rel }
346
363
  else {
347
364
  foreach ($spec in $ExcludableSpecs) {
348
- if ($rel -match $spec.pattern) { $result.excludable += @{ path = $rel; category = $spec.category; bytes = $k.Length }; break }
365
+ if ($rel -match $spec.pattern) { $result.excludable += @{ path = $rel; category = $spec.category; bytes = $k.Length; tracked = $trackedSet.Contains($rel) }; break }
349
366
  }
350
367
  }
351
368
 
@@ -416,6 +433,7 @@ $script:AdoptScanBlock = {
416
433
  }
417
434
  }
418
435
  $result.totalMB = [math]::Round($result.totalMB, 2)
436
+ $result.trackedKnown = $trackedKnown
419
437
  $result.paths = @($detectPaths)
420
438
  if ($detectPaths.Count -ge $DetectPathCap) {
421
439
  $result.partial = $true
@@ -116,17 +116,23 @@ $inventory = [ordered]@{
116
116
 
117
117
  # Roll the excludable file list up per top folder. A list of 40,000 paths is unreadable and
118
118
  # the decision is taken per folder anyway.
119
+ # Grouped by folder, category AND whether git tracks the file. A folder is routinely both:
120
+ # committed documents beside a gigabyte of correctly-ignored output. Rolling those together
121
+ # and labelling the total with the folder's state turned 0.15 MB of committed markdown into
122
+ # a report of "1018 MB of data exports are committed".
119
123
  $byFolder = @{}
120
124
  foreach ($e in @($scan.excludable)) {
121
125
  $top = ($e.path -split '[\\/]')[0]
122
- $key = "$top|$($e.category)"
123
- if (-not $byFolder.ContainsKey($key)) { $byFolder[$key] = @{ folder = $top; category = $e.category; files = 0; bytes = [long]0 } }
126
+ $isTracked = [bool](Get-AdoptProp $e 'tracked' $false)
127
+ $key = "$top|$($e.category)|$isTracked"
128
+ if (-not $byFolder.ContainsKey($key)) { $byFolder[$key] = @{ folder = $top; category = $e.category; tracked = $isTracked; files = 0; bytes = [long]0 } }
124
129
  $byFolder[$key].files++
125
130
  $byFolder[$key].bytes += [long]$e.bytes
126
131
  }
127
132
  $inventory.excludableSummary = @($byFolder.Values |
128
- ForEach-Object { [ordered]@{ folder = $_.folder; category = $_.category; files = $_.files; mb = [math]::Round($_.bytes / 1MB, 2) } } |
133
+ ForEach-Object { [ordered]@{ folder = $_.folder; category = $_.category; tracked = $_.tracked; files = $_.files; mb = [math]::Round($_.bytes / 1MB, 2) } } |
129
134
  Sort-Object { -1 * $_.mb })
135
+ $inventory.trackedKnown = [bool](Get-AdoptProp $scan 'trackedKnown' $false)
130
136
 
131
137
  $out = Write-AdoptArtifact -Dir $dir -FileName 'inventory.json' -Object $inventory
132
138
 
@@ -181,8 +187,12 @@ if ($ignoredBig.Count -gt 0) {
181
187
  Write-AdoptHeading 'What the repository must not carry'
182
188
  if ($inventory.excludableSummary.Count -eq 0) { Write-Host " nothing found" }
183
189
  foreach ($e in @($inventory.excludableSummary | Select-Object -First 15)) {
184
- Write-Host (" {0,10:N1} MB {1,7} files {2,-13} {3}" -f $e.mb, $e.files, $e.category, $e.folder)
190
+ $state = if ($e.tracked) { 'COMMITTED' } else { 'not committed' }
191
+ $colour = if ($e.tracked) { 'Yellow' } else { 'Gray' }
192
+ Write-Host (" {0,10:N1} MB {1,7} files {2,-13} {3,-14} {4}" -f $e.mb, $e.files, $e.category, $state, $e.folder) -ForegroundColor $colour
185
193
  }
194
+ Write-Host " Only the COMMITTED rows need a history rewrite. The rest need a .gitignore line," -ForegroundColor DarkGray
195
+ Write-Host " or already have one." -ForegroundColor DarkGray
186
196
 
187
197
  Write-AdoptHeading 'Possible credentials'
188
198
  if ($inventory.secretsSuspected.Count -eq 0) { Write-Host " none found by the heuristics - which is not the same as none present" }
@@ -73,10 +73,8 @@ if ($so -and $so.verdict -eq 'GAP') {
73
73
  $lines += "$($f.path) - $($f.mb) MB, neither committed nor ignored: commit it, ignore it, or move it out of the tree"
74
74
  }
75
75
  foreach ($e in @($inv.excludableSummary | Select-Object -First 10)) {
76
- $g = @($inv.size.folders | Where-Object { $_.path -eq $e.folder })
77
- if ($g.Count -gt 0 -and $g[0].git -eq 'tracked') {
78
- $lines += "$($e.folder) - $($e.mb) MB of $($e.category) is COMMITTED: needs a history rewrite, not a .gitignore line"
79
- }
76
+ if (-not (Get-AdoptProp $e 'tracked' $false)) { continue }
77
+ $lines += "$($e.folder) - $($e.files) file(s), $($e.mb) MB of $($e.category) is COMMITTED: a .gitignore line does not remove it, only a history rewrite does"
80
78
  }
81
79
  Add-Step 'content-policy' 'Settle what the repository may hold' @('answers') `
82
80
  'A .gitignore added later does not remove what is already committed, and a folder that is neither committed nor ignored is one careless command away from being permanent.' `
@@ -72,10 +72,12 @@ $componentProfiles = @($prof.components | ForEach-Object { $_.profile })
72
72
  $isBatchOnly = ($componentProfiles.Count -gt 0) -and (@($componentProfiles | Where-Object { $_ -notmatch 'batch' }).Count -eq 0)
73
73
 
74
74
  $untrackedBig = @($folders | Where-Object { $_.git -eq 'untracked' -and $_.path -ne '.git' -and $_.mb -ge $UntrackedThresholdMB })
75
+ # Per FILE, from git itself - not "this folder is tracked, so all of its bytes are".
75
76
  $trackedJunk = @()
76
77
  foreach ($e in @($inv.excludableSummary)) {
77
- $f = @($folders | Where-Object { $_.path -eq $e.folder })
78
- if ($f.Count -gt 0 -and $f[0].git -eq 'tracked' -and $e.category -ne 'log') { $trackedJunk += $e }
78
+ if (-not (Get-AdoptProp $e 'tracked' $false)) { continue }
79
+ if ($e.category -eq 'log') { continue }
80
+ $trackedJunk += $e
79
81
  }
80
82
  $ignoredHeavy = @($folders | Where-Object { $_.git -eq 'ignored' -and $_.mb -ge 100 })
81
83
 
@@ -1,7 +1,7 @@
1
1
  {
2
- "poolVersion": "1.3.114",
2
+ "poolVersion": "1.3.115",
3
3
  "bundles": {
4
- "antigravity-plugin": "1.3.114",
4
+ "antigravity-plugin": "1.3.115",
5
5
  "antigravity-plugin-extras": "1.3.35",
6
6
  "codex": "unknown"
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caddis/cli",
3
- "version": "0.4.25",
3
+ "version": "0.4.26",
4
4
  "description": "Install, update and diagnose the caddis dev harness across every coding agent you use (Claude Code, agy/Antigravity, and more).",
5
5
  "keywords": [
6
6
  "caddis",