its-magic 0.1.2-9 → 0.1.2

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.
Files changed (232) hide show
  1. package/README.md +1602 -755
  2. package/bin/its-magic.js +121 -11
  3. package/bin/postinstall.js +21 -0
  4. package/installer.ps1 +759 -0
  5. package/installer.py +981 -0
  6. package/installer.sh +649 -0
  7. package/package.json +18 -14
  8. package/scripts/check_intake_template_parity.py +284 -0
  9. package/scripts/doc_profile_lib.py +415 -0
  10. package/scripts/guard_installer_publish.py +88 -0
  11. package/scripts/intake_bug_routing_guard.py +67 -0
  12. package/scripts/intake_evidence_lib.py +802 -0
  13. package/scripts/intake_evidence_validate.py +73 -0
  14. package/scripts/materialize_codebase_map.py +184 -0
  15. package/scripts/remote_config_summary.py +243 -0
  16. package/template/.cursor/agents/curator.mdc +35 -0
  17. package/template/.cursor/agents/dev.mdc +29 -0
  18. package/template/.cursor/agents/po.mdc +141 -0
  19. package/template/.cursor/agents/qa.mdc +28 -0
  20. package/template/.cursor/agents/release.mdc +28 -0
  21. package/template/.cursor/agents/security.mdc +98 -0
  22. package/template/.cursor/agents/tech-lead.mdc +57 -0
  23. package/template/.cursor/commands/architecture.md +127 -0
  24. package/template/.cursor/commands/ask.md +55 -0
  25. package/template/.cursor/commands/auto.md +533 -0
  26. package/template/.cursor/commands/discovery.md +47 -0
  27. package/template/.cursor/commands/execute.md +343 -0
  28. package/template/.cursor/commands/intake.md +323 -0
  29. package/template/.cursor/commands/map-codebase.md +46 -0
  30. package/template/.cursor/commands/memory-audit.md +175 -0
  31. package/template/.cursor/commands/milestone-complete.md +51 -0
  32. package/template/.cursor/commands/milestone-start.md +59 -0
  33. package/template/.cursor/commands/pause.md +64 -0
  34. package/{.cursor/commands/gsd-phase-context.md → template/.cursor/commands/phase-context.md} +6 -2
  35. package/template/.cursor/commands/plan-verify.md +34 -0
  36. package/template/.cursor/commands/qa.md +226 -0
  37. package/template/.cursor/commands/quick.md +41 -0
  38. package/template/.cursor/commands/refresh-context.md +82 -0
  39. package/template/.cursor/commands/release.md +505 -0
  40. package/template/.cursor/commands/research.md +49 -0
  41. package/template/.cursor/commands/resume.md +67 -0
  42. package/template/.cursor/commands/security-review.md +81 -0
  43. package/template/.cursor/commands/sprint-plan.md +103 -0
  44. package/template/.cursor/commands/status-reconcile.md +95 -0
  45. package/template/.cursor/commands/verify-work.md +152 -0
  46. package/template/.cursor/dev-environment.json.example +22 -0
  47. package/{.cursor → template/.cursor}/hooks/README.md +3 -2
  48. package/{.cursor/hooks/gsd-hook.py → template/.cursor/hooks/hook.py} +15 -6
  49. package/template/.cursor/hooks.json +26 -0
  50. package/template/.cursor/remote.json +31 -0
  51. package/template/.cursor/rules/caveman.mdc +184 -0
  52. package/template/.cursor/rules/coding-standards.mdc +39 -0
  53. package/template/.cursor/rules/core.mdc +111 -0
  54. package/template/.cursor/rules/handoffs.mdc +27 -0
  55. package/template/.cursor/rules/quality.mdc +49 -0
  56. package/template/.cursor/scratchpad.local.example.md +323 -0
  57. package/template/.cursor/scratchpad.md +324 -0
  58. package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/SKILL.md +2 -2
  59. package/template/.cursorignore +6 -0
  60. package/template/.env.example +28 -0
  61. package/template/.github/workflows/ci.yml +194 -0
  62. package/{.github → template/.github}/workflows/deploy.yml +5 -2
  63. package/template/.its-magic-version +1 -0
  64. package/template/README.md +1602 -0
  65. package/template/decisions/DEC-0001.md +11 -0
  66. package/template/decisions/DEC-0002.md +11 -0
  67. package/template/docs/developer/README.md +44 -0
  68. package/template/docs/engineering/architecture.md +9 -0
  69. package/template/docs/engineering/artifact-ordering-policy.md +48 -0
  70. package/template/docs/engineering/artifact-ownership-policy.md +57 -0
  71. package/template/docs/engineering/auto-orchestration-reference.md +1211 -0
  72. package/{docs → template/docs}/engineering/codebase-map.md +0 -5
  73. package/template/docs/engineering/compatibility-report.md +20 -0
  74. package/template/docs/engineering/compatibility-signals.md +7 -0
  75. package/template/docs/engineering/component-scope-report.md +16 -0
  76. package/template/docs/engineering/component-scope.md +19 -0
  77. package/template/docs/engineering/context/installer-owned-paths.manifest +96 -0
  78. package/template/docs/engineering/context/readme-section-affinity.json +30 -0
  79. package/template/docs/engineering/decisions.md +16 -0
  80. package/template/docs/engineering/legacy-drift-audit.md +21 -0
  81. package/template/docs/engineering/manifests/components/api-gateway.manifest.yaml +12 -0
  82. package/template/docs/engineering/manifests/registry.manifest.yaml +20 -0
  83. package/template/docs/engineering/manifests/repo.manifest.yaml +11 -0
  84. package/template/docs/engineering/phase-context.md +16 -0
  85. package/template/docs/engineering/release-targets.json +123 -0
  86. package/template/docs/engineering/research.md +29 -0
  87. package/template/docs/engineering/runbook.md +2320 -0
  88. package/template/docs/engineering/runtime-connectivity.md +81 -0
  89. package/template/docs/engineering/security-review.md +33 -0
  90. package/template/docs/engineering/spec-pack/README.md +20 -0
  91. package/template/docs/engineering/state-archive/README.md +15 -0
  92. package/template/docs/engineering/state.md +20 -0
  93. package/template/docs/engineering/status-normalization-report.md +19 -0
  94. package/template/docs/engineering/token-cost-parity-manifest.md +16 -0
  95. package/template/docs/engineering/us-0084-remote-e2e.md +44 -0
  96. package/template/docs/product/acceptance.md +1 -0
  97. package/template/docs/product/backlog.md +5 -0
  98. package/template/docs/product/vision.md +11 -0
  99. package/template/docs/user-guides/README.md +40 -0
  100. package/{handoffs → template/handoffs}/dev_to_qa.md +0 -3
  101. package/{handoffs → template/handoffs}/po_to_tl.md +0 -3
  102. package/{handoffs → template/handoffs}/qa_to_dev.md +1 -2
  103. package/template/handoffs/release_notes.md +51 -0
  104. package/template/handoffs/release_queue.md +47 -0
  105. package/template/handoffs/release_to_dev.md +31 -0
  106. package/template/handoffs/releases/Sxxxx-release-notes.md +62 -0
  107. package/template/handoffs/resume_brief.md +14 -0
  108. package/{handoffs → template/handoffs}/tl_to_dev.md +0 -2
  109. package/template/handoffs/token_cost_runs/README.md +26 -0
  110. package/template/its_magic/.its-magic-version +1 -0
  111. package/template/its_magic/README.md +9 -0
  112. package/template/scripts/auto_outer_driver.py +521 -0
  113. package/template/scripts/caveman_compress_input.py +903 -0
  114. package/template/scripts/check_downstream_ci_guard.py +67 -0
  115. package/template/scripts/check_intake_template_parity.py +284 -0
  116. package/template/scripts/check_token_cost_parity.py +69 -0
  117. package/template/scripts/dev_environment_lib.py +463 -0
  118. package/template/scripts/doc_profile_lib.py +415 -0
  119. package/template/scripts/downstream_ci_guard_lib.py +222 -0
  120. package/template/scripts/enforce-triad-hot-surface.py +753 -0
  121. package/template/scripts/guard_installer_publish.py +88 -0
  122. package/template/scripts/intake_bug_resume_brief_refresh.py +303 -0
  123. package/template/scripts/intake_bug_routing_guard.py +67 -0
  124. package/template/scripts/intake_evidence_lib.py +802 -0
  125. package/template/scripts/intake_evidence_validate.py +73 -0
  126. package/template/scripts/materialize_codebase_map.py +184 -0
  127. package/template/scripts/pack_json_validate.py +130 -0
  128. package/template/scripts/project_readme_coverage_lib.py +417 -0
  129. package/template/scripts/readme_feature_coverage_lib.py +608 -0
  130. package/template/scripts/remote_config_summary.py +243 -0
  131. package/template/scripts/sync_push_gates.py +198 -0
  132. package/template/scripts/token_cost_compare.py +40 -0
  133. package/template/scripts/token_cost_lib.py +108 -0
  134. package/template/scripts/uat_probe_lib.py +868 -0
  135. package/template/scripts/validate-and-push.ps1 +280 -0
  136. package/template/scripts/validate-and-push.sh +243 -0
  137. package/template/scripts/validate_doc_profile.py +103 -0
  138. package/template/scripts/validate_project_readme_coverage.py +151 -0
  139. package/template/scripts/validate_readme_feature_coverage.py +140 -0
  140. package/template/sprints/S0001/progress.md +1 -0
  141. package/template/sprints/S0001/qa-findings.md +9 -0
  142. package/template/sprints/S0001/release-findings.md +24 -0
  143. package/template/sprints/S0001/sprint.md +9 -0
  144. package/template/sprints/S0001/summary.md +7 -0
  145. package/template/sprints/S0001/tasks.md +1 -0
  146. package/template/sprints/S0001/uat.json +6 -0
  147. package/template/sprints/S0001/uat.md +5 -0
  148. package/template/sprints/quick/Q0001/summary.md +1 -0
  149. package/{sprints → template/sprints}/quick/Q0001/task.json +0 -1
  150. package/.cursor/agents/curator.mdc +0 -21
  151. package/.cursor/agents/dev.mdc +0 -20
  152. package/.cursor/agents/po.mdc +0 -19
  153. package/.cursor/agents/qa.mdc +0 -19
  154. package/.cursor/agents/release.mdc +0 -19
  155. package/.cursor/agents/tech-lead.mdc +0 -21
  156. package/.cursor/commands/gsd-architecture.md +0 -29
  157. package/.cursor/commands/gsd-auto.md +0 -27
  158. package/.cursor/commands/gsd-discovery.md +0 -27
  159. package/.cursor/commands/gsd-execute.md +0 -32
  160. package/.cursor/commands/gsd-intake.md +0 -28
  161. package/.cursor/commands/gsd-map-codebase.md +0 -25
  162. package/.cursor/commands/gsd-milestone-complete.md +0 -24
  163. package/.cursor/commands/gsd-milestone-start.md +0 -26
  164. package/.cursor/commands/gsd-pause.md +0 -25
  165. package/.cursor/commands/gsd-plan-verify.md +0 -26
  166. package/.cursor/commands/gsd-qa.md +0 -28
  167. package/.cursor/commands/gsd-quick.md +0 -24
  168. package/.cursor/commands/gsd-refresh-context.md +0 -26
  169. package/.cursor/commands/gsd-release.md +0 -29
  170. package/.cursor/commands/gsd-research.md +0 -28
  171. package/.cursor/commands/gsd-resume.md +0 -26
  172. package/.cursor/commands/gsd-sprint-plan.md +0 -30
  173. package/.cursor/commands/gsd-verify-work.md +0 -25
  174. package/.cursor/hooks.json +0 -26
  175. package/.cursor/plans/cursor-gsd-team-kit_8cfee9b8.plan.md +0 -57
  176. package/.cursor/remote.json +0 -18
  177. package/.cursor/rules/gsd-core.mdc +0 -18
  178. package/.cursor/rules/gsd-handoffs.mdc +0 -10
  179. package/.cursor/rules/gsd-quality.mdc +0 -15
  180. package/.cursor/scratchpad.md +0 -34
  181. package/.github/workflows/ci.yml +0 -47
  182. package/decisions/DEC-0001.md +0 -21
  183. package/decisions/DEC-0002.md +0 -21
  184. package/docs/engineering/architecture.md +0 -354
  185. package/docs/engineering/decisions.md +0 -6
  186. package/docs/engineering/research.md +0 -11
  187. package/docs/engineering/runbook.md +0 -32
  188. package/docs/engineering/state.md +0 -33
  189. package/docs/product/acceptance.md +0 -6
  190. package/docs/product/backlog.md +0 -7
  191. package/docs/product/vision.md +0 -46
  192. package/gsd-installer.ps1 +0 -189
  193. package/gsd-installer.py +0 -195
  194. package/gsd-installer.sh +0 -201
  195. package/handoffs/release_notes.md +0 -14
  196. package/handoffs/resume_brief.md +0 -8
  197. package/milestones/M0001/milestone.json +0 -7
  198. package/milestones/M0001/phases.json +0 -9
  199. package/milestones/M0001/progress.md +0 -3
  200. package/milestones/M0001/summary.md +0 -3
  201. package/scripts/generate-release-notes.ps1 +0 -74
  202. package/scripts/generate-release-notes.sh +0 -63
  203. package/scripts/release-all.ps1 +0 -423
  204. package/scripts/release-all.sh +0 -226
  205. package/sprints/S0001/progress.md +0 -4
  206. package/sprints/S0001/qa-findings.md +0 -113
  207. package/sprints/S0001/sprint.md +0 -70
  208. package/sprints/S0001/summary.md +0 -46
  209. package/sprints/S0001/tasks.md +0 -35
  210. package/sprints/S0001/uat.json +0 -8
  211. package/sprints/S0001/uat.md +0 -8
  212. package/sprints/quick/Q0001/summary.md +0 -3
  213. /package/{.cursor/rules/gsd-escalation.mdc → template/.cursor/rules/escalation.mdc} +0 -0
  214. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/acceptance.json +0 -0
  215. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/acceptance.md +0 -0
  216. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/architecture.json +0 -0
  217. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/architecture.md +0 -0
  218. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/decision.json +0 -0
  219. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/decision.md +0 -0
  220. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/handoff.json +0 -0
  221. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/handoff.md +0 -0
  222. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/milestone.json +0 -0
  223. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/phase-context.json +0 -0
  224. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/plan-verify.json +0 -0
  225. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/sprint.json +0 -0
  226. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/sprint.md +0 -0
  227. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/story.json +0 -0
  228. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/story.md +0 -0
  229. /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/uat.json +0 -0
  230. /package/{docs → template/docs}/engineering/context/phase-template.json +0 -0
  231. /package/{docs → template/docs}/engineering/dependencies.json +0 -0
  232. /package/{sprints → template/sprints}/S0001/plan-verify.json +0 -0
@@ -1,423 +0,0 @@
1
- <#
2
- .SYNOPSIS
3
- Unified release: npm + Chocolatey + Homebrew (all three at once).
4
- .DESCRIPTION
5
- 1. Bumps version in package.json (patch|minor|major|explicit)
6
- 2. Publishes to npm
7
- 3. Creates a GitHub release with a source zip (for Homebrew/Chocolatey URLs)
8
- 4. Updates Chocolatey nuspec + pushes to chocolatey.org
9
- 5. Updates Homebrew formula with new URL + sha256
10
- .PARAMETER Bump
11
- Version bump type: patch, minor, major, or an explicit semver (e.g. 1.2.3).
12
- Default: patch
13
- .PARAMETER NpmTag
14
- npm dist-tag (e.g. latest, beta, rc). Default: latest
15
- .PARAMETER SkipNpm
16
- Skip npm publish.
17
- .PARAMETER SkipChoco
18
- Skip Chocolatey push.
19
- .PARAMETER SkipBrew
20
- Skip Homebrew formula update.
21
- .PARAMETER DryRun
22
- Print what would happen without executing.
23
- #>
24
- param(
25
- [string]$Bump = "patch",
26
- [string]$NpmTag = "latest",
27
- [switch]$SkipNpm,
28
- [switch]$SkipChoco,
29
- [switch]$SkipBrew,
30
- [switch]$DryRun,
31
- [switch]$SkipBrewPush,
32
- [string]$BrewTapRepo = "",
33
- [string]$BrewTapBranch = "main",
34
- [string]$BrewTapDir = "",
35
- [bool]$CreateBrewTapIfMissing = $true
36
- )
37
-
38
- $ErrorActionPreference = 'Stop'
39
- $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
40
- if (-not (Test-Path (Join-Path $repoRoot 'package.json'))) {
41
- $repoRoot = Split-Path -Parent $PSScriptRoot
42
- }
43
- Push-Location $repoRoot
44
-
45
- # ── Helpers ──────────────────────────────────────────────────────────
46
- function Log($msg) { Write-Host "[release] $msg" -ForegroundColor Cyan }
47
- function Warn($msg){ Write-Host "[release] $msg" -ForegroundColor Yellow }
48
- function Err($msg) { Write-Host "[release] $msg" -ForegroundColor Red; Pop-Location; exit 1 }
49
-
50
- # Quote char for building regex patterns (avoids PS 5.1 parser issues)
51
- $DQ = [char]34
52
- $chocoFailed = $false
53
- $brewTapFailed = $false
54
- $brewTapPushed = $false
55
-
56
- # ── 1. Version bump ─────────────────────────────────────────────────
57
- Log "Bumping version ($Bump) ..."
58
- if ($DryRun) {
59
- Log "(dry-run) would run: npm version $Bump --no-git-tag-version"
60
- $newVersion = "0.0.0-dryrun"
61
- } else {
62
- npm version $Bump --no-git-tag-version | Out-Null
63
- $pkg = Get-Content package.json -Raw | ConvertFrom-Json
64
- $newVersion = $pkg.version
65
- }
66
- Log "New version: $newVersion"
67
-
68
- # ── 2. npm publish ───────────────────────────────────────────────────
69
- if (-not $SkipNpm) {
70
- Log "Publishing to npm (tag=$NpmTag) ..."
71
- if ($DryRun) {
72
- Log "(dry-run) would run: npm publish --tag $NpmTag"
73
- } else {
74
- npm publish --tag $NpmTag
75
- if ($LASTEXITCODE -ne 0) { Err "npm publish failed" }
76
- Log "npm publish OK"
77
- }
78
- } else {
79
- Warn "Skipping npm"
80
- }
81
-
82
- # ── 3. GitHub release (needed by Homebrew + Chocolatey) ──────────────
83
- $ghAvailable = $null -ne (Get-Command gh -ErrorAction SilentlyContinue)
84
- $tagName = "v$newVersion"
85
- $zipUrl = ""
86
- $tarUrl = ""
87
-
88
- $isPrerelease = $newVersion -match '-'
89
- $chocoVersion = $newVersion
90
- if ($newVersion -match '^(\d+\.\d+\.\d+)-(\d+)$') {
91
- # Old Chocolatey/NuGet rejects numeric-only prerelease labels (e.g. 0.1.1-1).
92
- # Convert to a compatible label for nuspec only.
93
- $chocoVersion = "$($Matches[1])-beta$($Matches[2])"
94
- }
95
- if ($chocoVersion -ne $newVersion) {
96
- Log "Chocolatey version normalized: $newVersion -> $chocoVersion"
97
- }
98
-
99
- if ($ghAvailable) {
100
- Log "Creating GitHub release $tagName ..."
101
- if ($DryRun) {
102
- Log "(dry-run) would run: gh release create $tagName --generate-notes"
103
- $zipUrl = "https://github.com/USER/its-magic/archive/refs/tags/$tagName.zip"
104
- $tarUrl = "https://github.com/USER/its-magic/archive/refs/tags/$tagName.tar.gz"
105
- } else {
106
- $ghArgs = @("release", "create", $tagName, "--generate-notes", "--title", $tagName)
107
- if ($isPrerelease) { $ghArgs += "--prerelease" }
108
- & gh @ghArgs
109
- if ($LASTEXITCODE -ne 0) { Warn "gh release create failed - continuing anyway" }
110
- # Derive archive URL from current remote
111
- $remoteUrl = git remote get-url origin 2>$null
112
- if ($remoteUrl -match 'github\.com[:/](.+?)(\.git)?$') {
113
- $repoSlug = $Matches[1]
114
- $zipUrl = "https://github.com/$repoSlug/archive/refs/tags/$tagName.zip"
115
- $tarUrl = "https://github.com/$repoSlug/archive/refs/tags/$tagName.tar.gz"
116
- }
117
- Log "GitHub release created: $tagName"
118
- }
119
- } else {
120
- Warn "gh CLI not found - skipping GitHub release"
121
- $zipUrl = "https://github.com/USER/its-magic/archive/refs/tags/$tagName.zip"
122
- $tarUrl = "https://github.com/USER/its-magic/archive/refs/tags/$tagName.tar.gz"
123
- }
124
-
125
- # ── 4. Chocolatey ───────────────────────────────────────────────────
126
- if (-not $SkipChoco) {
127
- $chocoDir = Join-Path $repoRoot 'packaging\chocolatey'
128
- $nuspec = Join-Path $chocoDir 'its-magic.nuspec'
129
- $chocoInstall = Join-Path $chocoDir 'tools\chocolateyInstall.ps1'
130
-
131
- if (Test-Path $nuspec) {
132
- Log "Updating Chocolatey nuspec to $chocoVersion ..."
133
- if (-not $DryRun) {
134
- # Update version in nuspec
135
- $xml = [xml](Get-Content $nuspec -Raw)
136
- $xml.package.metadata.version = $chocoVersion
137
- $xml.Save($nuspec)
138
-
139
- # Update URL in install script
140
- $installContent = Get-Content $chocoInstall -Raw
141
- if ($zipUrl) {
142
- $installContent = $installContent -replace "\`$url\s*=\s*'[^']+'", "`$url = '$zipUrl'"
143
- }
144
- Set-Content -Path $chocoInstall -Value $installContent
145
- }
146
-
147
- # Compute checksum if we have the zip
148
- if ($zipUrl -and -not $DryRun) {
149
- Log "Downloading zip for checksum ..."
150
- $tmpZip = Join-Path $env:TEMP "gsd-$tagName.zip"
151
- try {
152
- Invoke-WebRequest -Uri $zipUrl -OutFile $tmpZip -UseBasicParsing
153
- $sha = (Get-FileHash -Path $tmpZip -Algorithm SHA256).Hash.ToLower()
154
- $installContent = Get-Content $chocoInstall -Raw
155
- $installContent = $installContent -replace "\`$checksum\s*=\s*'[^']+'", "`$checksum = '$sha'"
156
- Set-Content -Path $chocoInstall -Value $installContent
157
- Remove-Item $tmpZip -Force
158
- Log "Checksum: $sha"
159
- } catch {
160
- Warn "Could not download zip for checksum - set PLACEHOLDER manually"
161
- }
162
- }
163
-
164
- $chocoAvailable = $null -ne (Get-Command choco -ErrorAction SilentlyContinue)
165
- if ($chocoAvailable) {
166
- Log "Packing + pushing Chocolatey package ..."
167
- if ($DryRun) {
168
- Log "(dry-run) would run: choco pack + choco push"
169
- } else {
170
- Push-Location $chocoDir
171
- choco pack
172
- if ($LASTEXITCODE -ne 0) {
173
- $chocoFailed = $true
174
- Warn "choco pack failed"
175
- } else {
176
- $nupkg = Get-ChildItem "*.nupkg" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
177
- if ($nupkg) {
178
- choco push $nupkg.Name --source https://push.chocolatey.org/
179
- if ($LASTEXITCODE -ne 0) {
180
- $chocoFailed = $true
181
- Warn "choco push failed"
182
- }
183
- else { Log "Chocolatey push OK" }
184
- } else {
185
- $chocoFailed = $true
186
- Warn "No .nupkg created by choco pack"
187
- }
188
- }
189
- Pop-Location
190
- }
191
- } else {
192
- $chocoFailed = $true
193
- Warn "choco not found - nuspec updated but not pushed. Run choco pack and choco push manually."
194
- }
195
- } else {
196
- $chocoFailed = $true
197
- Warn "nuspec not found at $nuspec - skipping Chocolatey"
198
- }
199
- } else {
200
- Warn "Skipping Chocolatey"
201
- }
202
-
203
- # ── 5. Homebrew ─────────────────────────────────────────────────────
204
- if (-not $SkipBrew) {
205
- # Detect pre-release: anything with a hyphen
206
- if ($isPrerelease) {
207
- $formulaPath = Join-Path $repoRoot 'packaging\homebrew\its-magic-beta.rb'
208
- Log "Pre-release detected - using beta formula"
209
- } else {
210
- $formulaPath = Join-Path $repoRoot 'packaging\homebrew\its-magic.rb'
211
- }
212
-
213
- if (Test-Path $formulaPath) {
214
- $formulaName = Split-Path -Leaf $formulaPath
215
- Log "Updating Homebrew formula ($formulaName) to $newVersion ..."
216
- if (-not $DryRun) {
217
- $formula = Get-Content $formulaPath -Raw
218
-
219
- # Update version in URL
220
- if ($tarUrl) {
221
- $urlPattern = 'url ' + $DQ + 'https://github\.com/[^' + $DQ + ']+\.tar\.gz' + $DQ
222
- $urlReplace = 'url ' + $DQ + $tarUrl + $DQ
223
- $formula = $formula -replace $urlPattern, $urlReplace
224
- } else {
225
- $formula = $formula -replace 'vVERSION', $tagName
226
- }
227
-
228
- # Update explicit version line for beta formula
229
- if ($isPrerelease) {
230
- $verPattern = 'version ' + $DQ + '[^' + $DQ + ']*' + $DQ
231
- $verReplace = 'version ' + $DQ + $newVersion + $DQ
232
- $formula = $formula -replace $verPattern, $verReplace
233
- }
234
-
235
- # Compute tar.gz sha256 if possible
236
- if ($tarUrl) {
237
- $tmpTar = Join-Path $env:TEMP "gsd-$tagName.tar.gz"
238
- try {
239
- Invoke-WebRequest -Uri $tarUrl -OutFile $tmpTar -UseBasicParsing
240
- $sha = (Get-FileHash -Path $tmpTar -Algorithm SHA256).Hash.ToLower()
241
- $shaPattern = 'sha256 ' + $DQ + '[^' + $DQ + ']*' + $DQ
242
- $shaReplace = 'sha256 ' + $DQ + $sha + $DQ
243
- $formula = $formula -replace $shaPattern, $shaReplace
244
- Remove-Item $tmpTar -Force
245
- Log "Homebrew sha256: $sha"
246
- } catch {
247
- Warn "Could not download tar.gz - set sha256 manually in the formula"
248
- }
249
- }
250
-
251
- Set-Content -Path $formulaPath -Value $formula
252
- Log "Homebrew formula updated: $formulaName"
253
- if ($isPrerelease) {
254
- Log "Users install beta with: brew install USER/tap/its-magic-beta"
255
- } else {
256
- Log "Users install stable with: brew install USER/tap/its-magic"
257
- }
258
- } else {
259
- $formulaName = Split-Path -Leaf $formulaPath
260
- Log "(dry-run) would update $formulaName"
261
- }
262
- } else {
263
- Warn "Formula not found at $formulaPath - skipping Homebrew"
264
- }
265
-
266
- # Optional: publish formulas to Homebrew tap repository
267
- if (-not $SkipBrewPush) {
268
- if ($DryRun) {
269
- Log "(dry-run) would publish formulas to Homebrew tap"
270
- } else {
271
- $gitAvailable = $null -ne (Get-Command git -ErrorAction SilentlyContinue)
272
- $ghAvailableForTap = $null -ne (Get-Command gh -ErrorAction SilentlyContinue)
273
- if (-not $gitAvailable) {
274
- $brewTapFailed = $true
275
- Warn "git not found - cannot push Homebrew formulas to tap"
276
- } else {
277
- if (-not $BrewTapRepo) {
278
- $originUrl = git remote get-url origin 2>$null
279
- if ($originUrl -match 'github\.com[:/](.+?)/(.+?)(\.git)?$') {
280
- $owner = $Matches[1]
281
- $BrewTapRepo = "$owner/homebrew-tap"
282
- }
283
- }
284
-
285
- if (-not $BrewTapRepo) {
286
- $brewTapFailed = $true
287
- Warn "Could not infer Homebrew tap repo. Pass -BrewTapRepo owner/homebrew-tap"
288
- } else {
289
- if (-not $BrewTapDir) {
290
- $safeTap = ($BrewTapRepo -replace '[^a-zA-Z0-9_-]', '-')
291
- $BrewTapDir = Join-Path $env:TEMP "its-magic-$safeTap"
292
- }
293
-
294
- Log "Publishing formulas to tap $BrewTapRepo (branch: $BrewTapBranch) ..."
295
-
296
- # Use a child scope with relaxed error handling for git commands
297
- # that write to stderr even on success (e.g. empty repo warnings).
298
- $tapReady = $true
299
- $prevEAP = $ErrorActionPreference
300
- $ErrorActionPreference = 'Continue'
301
-
302
- # ── Step A: Ensure we have a local clone ──
303
- $tapGitDir = Join-Path $BrewTapDir ".git"
304
-
305
- # Clean up non-git directory leftovers
306
- if ((Test-Path $BrewTapDir) -and -not (Test-Path $tapGitDir)) {
307
- Warn "Tap directory exists but is not a git repo. Removing: $BrewTapDir"
308
- Remove-Item -Recurse -Force $BrewTapDir
309
- }
310
-
311
- if (Test-Path $tapGitDir) {
312
- # Already cloned - fetch latest
313
- git -C $BrewTapDir fetch origin 2>&1 | Out-Null
314
- } else {
315
- # Clone (try gh first, then git)
316
- $cloneOk = $false
317
- if ($ghAvailableForTap) {
318
- & gh repo clone $BrewTapRepo $BrewTapDir 2>&1 | Out-Null
319
- if ($LASTEXITCODE -eq 0) { $cloneOk = $true }
320
- }
321
- if (-not $cloneOk) {
322
- git clone "https://github.com/$BrewTapRepo.git" $BrewTapDir 2>&1 | Out-Null
323
- if ($LASTEXITCODE -eq 0) { $cloneOk = $true }
324
- }
325
- if (-not $cloneOk -and $CreateBrewTapIfMissing -and $ghAvailableForTap) {
326
- Warn "Tap repo not found. Creating $BrewTapRepo on GitHub ..."
327
- & gh repo create $BrewTapRepo --public --description "Homebrew tap for its-magic" 2>&1 | Out-Null
328
- if ($LASTEXITCODE -eq 0) {
329
- Log "Tap repo created: https://github.com/$BrewTapRepo"
330
- if (Test-Path $BrewTapDir) { Remove-Item -Recurse -Force $BrewTapDir }
331
- & gh repo clone $BrewTapRepo $BrewTapDir 2>&1 | Out-Null
332
- if ($LASTEXITCODE -eq 0) { $cloneOk = $true }
333
- }
334
- }
335
- if (-not $cloneOk) {
336
- $tapReady = $false; $brewTapFailed = $true
337
- Warn "Failed to clone/create tap repo $BrewTapRepo"
338
- }
339
- }
340
-
341
- # ── Step B: Ensure branch exists ──
342
- if ($tapReady) {
343
- # Check if repo has any commits at all
344
- $hasCommits = $false
345
- git -C $BrewTapDir log --oneline -1 2>&1 | Out-Null
346
- if ($LASTEXITCODE -eq 0) { $hasCommits = $true }
347
-
348
- if ($hasCommits) {
349
- git -C $BrewTapDir checkout $BrewTapBranch 2>&1 | Out-Null
350
- if ($LASTEXITCODE -ne 0) {
351
- git -C $BrewTapDir checkout -b $BrewTapBranch 2>&1 | Out-Null
352
- }
353
- # Try to pull if remote branch exists
354
- git -C $BrewTapDir pull origin $BrewTapBranch 2>&1 | Out-Null
355
- } else {
356
- Log "Empty tap repo detected - creating initial branch $BrewTapBranch"
357
- git -C $BrewTapDir checkout --orphan $BrewTapBranch 2>&1 | Out-Null
358
- }
359
- }
360
-
361
- # ── Step C: Copy formulas, commit, push ──
362
- if ($tapReady) {
363
- $tapFormulaDir = Join-Path $BrewTapDir "Formula"
364
- if (-not (Test-Path $tapFormulaDir)) {
365
- New-Item -ItemType Directory -Path $tapFormulaDir -Force | Out-Null
366
- }
367
-
368
- Copy-Item (Join-Path $repoRoot "packaging\homebrew\its-magic.rb") (Join-Path $tapFormulaDir "its-magic.rb") -Force
369
- Copy-Item (Join-Path $repoRoot "packaging\homebrew\its-magic-beta.rb") (Join-Path $tapFormulaDir "its-magic-beta.rb") -Force
370
-
371
- git -C $BrewTapDir add Formula/its-magic.rb Formula/its-magic-beta.rb
372
-
373
- $tapChanges = git -C $BrewTapDir status --porcelain
374
- if ($tapChanges) {
375
- git -C $BrewTapDir commit -m "chore: update its-magic formulas for $newVersion" 2>&1 | Out-Null
376
- if ($LASTEXITCODE -ne 0) {
377
- $brewTapFailed = $true
378
- Warn "Failed to commit Homebrew tap changes"
379
- } else {
380
- git -C $BrewTapDir push -u origin $BrewTapBranch 2>&1 | Out-Null
381
- if ($LASTEXITCODE -ne 0) {
382
- $brewTapFailed = $true
383
- Warn "Failed to push Homebrew tap changes"
384
- } else {
385
- $brewTapPushed = $true
386
- Log "Homebrew tap updated: https://github.com/$BrewTapRepo"
387
- }
388
- }
389
- } else {
390
- Log "No Homebrew formula changes to push"
391
- }
392
- }
393
-
394
- $ErrorActionPreference = $prevEAP
395
- }
396
- }
397
- }
398
- } else {
399
- Warn "Skipping Homebrew tap push"
400
- }
401
- } else {
402
- Warn "Skipping Homebrew"
403
- }
404
-
405
- # ── Done ─────────────────────────────────────────────────────────────
406
- Pop-Location
407
- $npmStatus = "OK"
408
- if ($SkipNpm) { $npmStatus = "SKIPPED" }
409
- $chocoStatus = "OK"
410
- if ($SkipChoco) { $chocoStatus = "SKIPPED" }
411
- elseif ($DryRun) { $chocoStatus = "DRY-RUN" }
412
- elseif ($chocoFailed) { $chocoStatus = "FAILED - check log" }
413
- $brewStatus = "OK - formula updated"
414
- if ($SkipBrew) { $brewStatus = "SKIPPED" }
415
- elseif ($brewTapFailed) { $brewStatus = "FORMULA OK - TAP PUSH FAILED" }
416
- elseif ($brewTapPushed) { $brewStatus = "OK - formula updated + tap pushed" }
417
-
418
- Log "=========================================="
419
- Log "Release $newVersion complete!"
420
- Log " npm: $npmStatus"
421
- Log " Chocolatey: $chocoStatus"
422
- Log " Homebrew: $brewStatus"
423
- Log "=========================================="
@@ -1,226 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ─────────────────────────────────────────────────────────────────
3
- # Unified release: npm + Chocolatey + Homebrew (all three at once)
4
- # ─────────────────────────────────────────────────────────────────
5
- set -euo pipefail
6
-
7
- BUMP="patch"
8
- NPM_TAG="latest"
9
- SKIP_NPM=false
10
- SKIP_CHOCO=false
11
- SKIP_BREW=false
12
- DRY_RUN=false
13
-
14
- usage() {
15
- cat <<EOF
16
- Usage: $0 [options]
17
- --bump <patch|minor|major|x.y.z> Version bump (default: patch)
18
- --npm-tag <tag> npm dist-tag (default: latest)
19
- --skip-npm Skip npm publish
20
- --skip-choco Skip Chocolatey push
21
- --skip-brew Skip Homebrew formula update
22
- --dry-run Print actions without executing
23
- -h|--help Show this help
24
- EOF
25
- exit 0
26
- }
27
-
28
- while [[ $# -gt 0 ]]; do
29
- case "$1" in
30
- --bump) BUMP="$2"; shift 2;;
31
- --npm-tag) NPM_TAG="$2"; shift 2;;
32
- --skip-npm) SKIP_NPM=true; shift;;
33
- --skip-choco)SKIP_CHOCO=true; shift;;
34
- --skip-brew) SKIP_BREW=true; shift;;
35
- --dry-run) DRY_RUN=true; shift;;
36
- -h|--help) usage;;
37
- *) echo "Unknown option: $1"; usage;;
38
- esac
39
- done
40
-
41
- REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
42
- cd "$REPO_ROOT"
43
-
44
- log() { echo -e "\033[36m[release]\033[0m $1"; }
45
- warn() { echo -e "\033[33m[release]\033[0m $1"; }
46
- err() { echo -e "\033[31m[release]\033[0m $1"; exit 1; }
47
-
48
- # ── 1. Version bump ─────────────────────────────────────────────────
49
- log "Bumping version ($BUMP) ..."
50
- if $DRY_RUN; then
51
- log "(dry-run) would run: npm version $BUMP --no-git-tag-version"
52
- NEW_VERSION="0.0.0-dryrun"
53
- else
54
- npm version "$BUMP" --no-git-tag-version >/dev/null
55
- NEW_VERSION=$(node -p "require('./package.json').version")
56
- fi
57
- TAG_NAME="v$NEW_VERSION"
58
- log "New version: $NEW_VERSION (tag: $TAG_NAME)"
59
- CHOCO_VERSION="$NEW_VERSION"
60
- if [[ "$NEW_VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)-([0-9]+)$ ]]; then
61
- # Old Chocolatey/NuGet rejects numeric-only prerelease labels (e.g. 0.1.1-1).
62
- # Convert to a compatible label for nuspec only.
63
- CHOCO_VERSION="${BASH_REMATCH[1]}-beta${BASH_REMATCH[2]}"
64
- fi
65
- if [[ "$CHOCO_VERSION" != "$NEW_VERSION" ]]; then
66
- log "Chocolatey version normalized: $NEW_VERSION -> $CHOCO_VERSION"
67
- fi
68
-
69
- # ── 2. npm publish ──────────────────────────────────────────────────
70
- if ! $SKIP_NPM; then
71
- log "Publishing to npm (tag=$NPM_TAG) ..."
72
- if $DRY_RUN; then
73
- log "(dry-run) would run: npm publish --tag $NPM_TAG"
74
- else
75
- npm publish --tag "$NPM_TAG"
76
- log "npm publish OK"
77
- fi
78
- else
79
- warn "Skipping npm"
80
- fi
81
-
82
- # ── 3. GitHub release ───────────────────────────────────────────────
83
- ZIP_URL=""
84
- TAR_URL=""
85
-
86
- GH_PRERELEASE=""
87
- if [[ "$NEW_VERSION" == *-* ]]; then
88
- GH_PRERELEASE="--prerelease"
89
- fi
90
-
91
- if command -v gh &>/dev/null; then
92
- log "Creating GitHub release $TAG_NAME ..."
93
- if $DRY_RUN; then
94
- log "(dry-run) would run: gh release create $TAG_NAME --generate-notes $GH_PRERELEASE"
95
- else
96
- gh release create "$TAG_NAME" --generate-notes --title "$TAG_NAME" $GH_PRERELEASE || warn "gh release create failed – continuing"
97
- fi
98
- REMOTE_URL=$(git remote get-url origin 2>/dev/null || true)
99
- if [[ "$REMOTE_URL" =~ github\.com[:/](.+?)(\.git)?$ ]]; then
100
- REPO_SLUG="${BASH_REMATCH[1]}"
101
- REPO_SLUG="${REPO_SLUG%.git}"
102
- ZIP_URL="https://github.com/$REPO_SLUG/archive/refs/tags/$TAG_NAME.zip"
103
- TAR_URL="https://github.com/$REPO_SLUG/archive/refs/tags/$TAG_NAME.tar.gz"
104
- fi
105
- else
106
- warn "gh CLI not found – skipping GitHub release"
107
- ZIP_URL="https://github.com/USER/its-magic/archive/refs/tags/$TAG_NAME.zip"
108
- TAR_URL="https://github.com/USER/its-magic/archive/refs/tags/$TAG_NAME.tar.gz"
109
- fi
110
-
111
- # ── 4. Chocolatey ───────────────────────────────────────────────────
112
- if ! $SKIP_CHOCO; then
113
- NUSPEC="$REPO_ROOT/packaging/chocolatey/its-magic.nuspec"
114
- CHOCO_INSTALL="$REPO_ROOT/packaging/chocolatey/tools/chocolateyInstall.ps1"
115
-
116
- if [[ -f "$NUSPEC" ]]; then
117
- log "Updating Chocolatey nuspec to $CHOCO_VERSION ..."
118
- if ! $DRY_RUN; then
119
- # Update version in nuspec (simple sed)
120
- sed -i.bak "s|<version>[^<]*</version>|<version>$CHOCO_VERSION</version>|" "$NUSPEC"
121
- rm -f "${NUSPEC}.bak"
122
-
123
- # Update URL in install script
124
- if [[ -n "$ZIP_URL" ]]; then
125
- sed -i.bak "s|^\\$url[[:space:]]*=.*$|\\$url = '$ZIP_URL'|" "$CHOCO_INSTALL"
126
- rm -f "${CHOCO_INSTALL}.bak"
127
- fi
128
-
129
- # Compute checksum
130
- if [[ -n "$ZIP_URL" ]]; then
131
- TMP_ZIP="/tmp/gsd-$TAG_NAME.zip"
132
- if curl -fsSL "$ZIP_URL" -o "$TMP_ZIP" 2>/dev/null; then
133
- SHA=$(shasum -a 256 "$TMP_ZIP" | awk '{print $1}')
134
- sed -i.bak "s|^\\$checksum[[:space:]]*=.*$|\\$checksum = '$SHA'|" "$CHOCO_INSTALL"
135
- rm -f "${CHOCO_INSTALL}.bak" "$TMP_ZIP"
136
- log "Chocolatey checksum: $SHA"
137
- else
138
- warn "Could not download zip for checksum – set PLACEHOLDER manually"
139
- fi
140
- fi
141
- fi
142
-
143
- if command -v choco &>/dev/null; then
144
- log "Packing + pushing Chocolatey package ..."
145
- if ! $DRY_RUN; then
146
- (cd "$REPO_ROOT/packaging/chocolatey" && choco pack && \
147
- NUPKG=$(ls -1t *.nupkg 2>/dev/null | head -1) && \
148
- choco push "$NUPKG" --source https://push.chocolatey.org/ || warn "choco push failed")
149
- fi
150
- else
151
- warn "choco not found – nuspec updated but not pushed"
152
- fi
153
- else
154
- warn "nuspec not found – skipping Chocolatey"
155
- fi
156
- else
157
- warn "Skipping Chocolatey"
158
- fi
159
-
160
- # ── 5. Homebrew ─────────────────────────────────────────────────────
161
- if ! $SKIP_BREW; then
162
- # Detect pre-release: anything with a hyphen (e.g. 0.2.0-beta.1, 1.0.0-rc.1)
163
- IS_PRERELEASE=false
164
- if [[ "$NEW_VERSION" == *-* ]]; then
165
- IS_PRERELEASE=true
166
- fi
167
-
168
- if $IS_PRERELEASE; then
169
- FORMULA="$REPO_ROOT/packaging/homebrew/its-magic-beta.rb"
170
- log "Pre-release detected – using beta formula"
171
- else
172
- FORMULA="$REPO_ROOT/packaging/homebrew/its-magic.rb"
173
- fi
174
-
175
- if [[ -f "$FORMULA" ]]; then
176
- FORMULA_NAME=$(basename "$FORMULA")
177
- log "Updating Homebrew formula ($FORMULA_NAME) to $NEW_VERSION ..."
178
- if ! $DRY_RUN; then
179
- if [[ -n "$TAR_URL" ]]; then
180
- sed -i.bak "s|url \"https://github.com/[^\"]*\.tar\.gz\"|url \"$TAR_URL\"|" "$FORMULA"
181
- rm -f "${FORMULA}.bak"
182
- else
183
- sed -i.bak "s|vVERSION|$TAG_NAME|g" "$FORMULA"
184
- rm -f "${FORMULA}.bak"
185
- fi
186
-
187
- # Update explicit version line for beta formula
188
- if $IS_PRERELEASE; then
189
- sed -i.bak "s|version \"[^\"]*\"|version \"$NEW_VERSION\"|" "$FORMULA"
190
- rm -f "${FORMULA}.bak"
191
- fi
192
-
193
- # Compute sha256
194
- if [[ -n "$TAR_URL" ]]; then
195
- TMP_TAR="/tmp/gsd-$TAG_NAME.tar.gz"
196
- if curl -fsSL "$TAR_URL" -o "$TMP_TAR" 2>/dev/null; then
197
- SHA=$(shasum -a 256 "$TMP_TAR" | awk '{print $1}')
198
- # Replace both PLACEHOLDER and any previous sha256 value
199
- sed -i.bak "s|sha256 \"[^\"]*\"|sha256 \"$SHA\"|" "$FORMULA"
200
- rm -f "${FORMULA}.bak" "$TMP_TAR"
201
- log "Homebrew sha256: $SHA"
202
- else
203
- warn "Could not download tar.gz – set sha256 manually"
204
- fi
205
- fi
206
- log "Homebrew formula updated: $FORMULA_NAME"
207
- if $IS_PRERELEASE; then
208
- log "Users install beta with: brew install USER/tap/its-magic-beta"
209
- else
210
- log "Users install stable with: brew install USER/tap/its-magic"
211
- fi
212
- fi
213
- else
214
- warn "Formula not found – skipping Homebrew"
215
- fi
216
- else
217
- warn "Skipping Homebrew"
218
- fi
219
-
220
- # ── Done ─────────────────────────────────────────────────────────────
221
- log "=========================================="
222
- log "Release $NEW_VERSION complete!"
223
- log " npm: $(if $SKIP_NPM; then echo 'SKIPPED'; else echo 'OK'; fi)"
224
- log " Chocolatey: $(if $SKIP_CHOCO; then echo 'SKIPPED'; else echo 'OK (check warnings)'; fi)"
225
- log " Homebrew: $(if $SKIP_BREW; then echo 'SKIPPED'; else echo 'OK (formula updated)'; fi)"
226
- log "=========================================="
@@ -1,4 +0,0 @@
1
- # Progress
2
-
3
- - ...
4
-