fix(cli): auto-delete binary on Windows, prune images, fix GoReleaser#590
fix(cli): auto-delete binary on Windows, prune images, fix GoReleaser#590
Conversation
Three uninstall gaps fixed: 1. Windows binary self-deletion: spawn a detached cmd.exe process that polls tasklist until the CLI exits, then deletes the binary and empty parent dirs (replaces manual PowerShell instruction) 2. Docker image pruning: new confirmAndRemoveImages step lists all ghcr.io/aureliolo/synthorg-* images with sizes, asks to remove, then runs docker rmi --force by ID 3. Fix em-dashes in error messages (non-ASCII punctuation) Also fixes GoReleaser v2.14.3 archive failure: - ../LICENSE path resolution broke (stat invalid argument) - Changed to copy LICENSE into cli/ during CI, reference as LICENSE - Added cli/.gitignore to exclude the CI-only copy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🧰 Additional context used📓 Path-based instructions (1)cli/**/*.go📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (5)📓 Common learnings📚 Learning: 2026-03-19T13:34:44.305ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-15T11:48:14.867ZApplied to files:
📚 Learning: 2026-03-19T13:34:44.305ZApplied to files:
🧬 Code graph analysis (1)cli/cmd/uninstall.go (2)
🔇 Additional comments (8)
WalkthroughAdded CI step to copy the repository 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
📝 Coding Plan
Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds some excellent quality-of-life improvements to the uninstall command, particularly the automatic binary cleanup on Windows and the option to prune container images. The GoReleaser fix is also a necessary correction. My review focuses on a potential bug in the image pruning logic that could affect users with older docker-compose versions, and a suggestion to improve the readability of the new Windows cleanup script.
cli/cmd/uninstall.go
Outdated
| listOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images", | ||
| "--filter", "reference="+imageRef+"*", | ||
| "--format", "{{.Repository}}:{{.Tag}} ({{.Size}})", | ||
| ) |
There was a problem hiding this comment.
The docker images command is being executed using info.ComposeCmd[0], which could be docker-compose. However, docker-compose images (v1) does not support the --filter and --format arguments used here, which will cause this call to fail. This should be a direct docker images call to ensure it works correctly regardless of the Compose version detected.
| listOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images", | |
| "--filter", "reference="+imageRef+"*", | |
| "--format", "{{.Repository}}:{{.Tag}} ({{.Size}})", | |
| ) | |
| listOut, err := docker.RunCmd(ctx, "docker", "images", | |
| "--filter", "reference="+imageRef+"*", | |
| "--format", "{{.Repository}}:{{.Tag}} ({{.Size}})", | |
| ) |
cli/cmd/uninstall.go
Outdated
| idsOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images", | ||
| "--filter", "reference="+imageRef+"*", | ||
| "--format", "{{.ID}}", | ||
| ) |
There was a problem hiding this comment.
For the same reason as the previous comment, getting image IDs should also use the docker command directly. The docker-compose images (v1) command does not support the required arguments, and this call will fail in environments where it is present.
| idsOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images", | |
| "--filter", "reference="+imageRef+"*", | |
| "--format", "{{.ID}}", | |
| ) | |
| idsOut, err := docker.RunCmd(ctx, "docker", "images", | |
| "--filter", "reference="+imageRef+"*", | |
| "--format", "{{.ID}}", | |
| ) |
cli/cmd/uninstall.go
Outdated
|
|
||
| _, _ = fmt.Fprintln(out, "Removing SynthOrg images...") | ||
| rmiArgs := append([]string{"rmi", "--force"}, ids...) | ||
| if _, rmiErr := docker.RunCmd(ctx, info.ComposeCmd[0], rmiArgs...); rmiErr != nil { |
There was a problem hiding this comment.
The rmi command is a docker engine command. docker-compose v1 does not have a top-level rmi command. This call will fail if info.ComposeCmd[0] resolves to docker-compose. It should be an explicit call to docker rmi.
| if _, rmiErr := docker.RunCmd(ctx, info.ComposeCmd[0], rmiArgs...); rmiErr != nil { | |
| if _, rmiErr := docker.RunCmd(ctx, "docker", rmiArgs...); rmiErr != nil { |
cli/cmd/uninstall.go
Outdated
| script := fmt.Sprintf( | ||
| `for /L %%i in (1,1,30) do (`+ | ||
| `tasklist /fi "PID eq %d" 2>nul | find "%d" >nul || goto :cleanup & `+ | ||
| `ping -n 2 127.0.0.1 >nul`+ | ||
| `) & goto :done`+ | ||
| ` & :cleanup`+ | ||
| ` & del /f /q "%s"`+ | ||
| ` & rmdir "%s" 2>nul`+ | ||
| ` & rmdir "%s" 2>nul`+ | ||
| ` & :done`, | ||
| pid, pid, | ||
| execPath, | ||
| binDir, | ||
| dataDir, | ||
| ) |
There was a problem hiding this comment.
The use of ping for a delay is a classic technique, but using the timeout command is more explicit and clearer about the intent. timeout is a standard command in modern Windows versions (Vista and later), making it a safe and more readable choice for creating a 1-second delay. This suggestion also refactors the script to use standard double-quoted strings to avoid issues with backticks in code suggestions.
| script := fmt.Sprintf( | |
| `for /L %%i in (1,1,30) do (`+ | |
| `tasklist /fi "PID eq %d" 2>nul | find "%d" >nul || goto :cleanup & `+ | |
| `ping -n 2 127.0.0.1 >nul`+ | |
| `) & goto :done`+ | |
| ` & :cleanup`+ | |
| ` & del /f /q "%s"`+ | |
| ` & rmdir "%s" 2>nul`+ | |
| ` & rmdir "%s" 2>nul`+ | |
| ` & :done`, | |
| pid, pid, | |
| execPath, | |
| binDir, | |
| dataDir, | |
| ) | |
| script := fmt.Sprintf( | |
| "for /L %%%%i in (1,1,30) do ("+ | |
| "tasklist /fi \"PID eq %d\" 2>nul | find \"%d\" >nul || goto :cleanup & "+ | |
| "timeout /t 1 /nobreak >nul"+ | |
| ") & goto :done"+ | |
| " & :cleanup"+ | |
| " & del /f /q \"%s\""+ | |
| " & rmdir \"%s\" 2>nul"+ | |
| " & rmdir \"%s\" 2>nul"+ | |
| " & :done", | |
| pid, pid, | |
| execPath, | |
| binDir, | |
| dataDir, | |
| ) |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/cmd/uninstall.go`:
- Around line 347-348: Replace the use of the parent's context when spawning the
detached cleanup process: instead of exec.CommandContext(cmd.Context(),
"cmd.exe", "/c", script) use exec.CommandContext(context.Background(),
"cmd.exe", "/c", script) so the child is not cancelled if the parent's context
is cancelled; keep c.SysProcAttr = windowsDetachedProcAttr() and the subsequent
Start()/Release() logic unchanged to ensure the process is detached and allowed
to outlive the parent.
- Around line 131-134: Replace uses of info.ComposeCmd[0] when invoking
docker.RunCmd for listing/removing images with info.DockerPath so the Docker CLI
(not docker-compose) is used; specifically update the docker.RunCmd calls that
pass info.ComposeCmd[0], e.g. the calls that build the "images" command with
"--filter reference="+imageRef and any subsequent docker.RunCmd invocations that
remove or inspect images, to use info.DockerPath instead while keeping the same
args (imageRef, "--format", etc.); apply the same change for the other
occurrences in uninstall.go where docker.RunCmd is called with
info.ComposeCmd[0] (the additional calls referenced in the review).
- Around line 331-345: The Windows uninstall command string built in
uninstall.go (the script variable that interpolates pid, execPath, binDir,
dataDir) incorrectly uses batch labels and goto (":cleanup", ":done", "goto
:cleanup") inside a single-line cmd /c which will fail; replace this approach by
either (A) rewriting the script to use conditional execution operators (&& and
||) and proper command grouping so the wait-and-clean logic doesn't rely on
labels/goto, or (B) generate a temporary .bat file containing the labeled block
and run that .bat from cmd.exe, ensuring you still pass pid, execPath, binDir,
dataDir into the temp file and delete it after execution; update the code that
builds the script variable and the exec invocation accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: a5171a57-c46d-441c-a26e-b5727303da22
📒 Files selected for processing (6)
.github/workflows/cli.ymlcli/.gitignorecli/.goreleaser.ymlcli/cmd/procattr_other.gocli/cmd/procattr_windows.gocli/cmd/uninstall.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: CLI Test (macos-latest)
- GitHub Check: CLI Test (windows-latest)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (2)
.github/workflows/*.yml
📄 CodeRabbit inference engine (CLAUDE.md)
.github/workflows/*.yml: GitHub Actions workflows must use SHA-pinned action versions (not@vor@main) for supply chain security
All commits must be GPG/SSH signed on main branch — enforced via branch protection
Files:
.github/workflows/cli.yml
cli/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
cli/**/*.go: Go CLI binary uses Cobra for command routing, charmbracelet libraries (huh, lipgloss) for interactive prompts and styled output, sigstore-go for cryptographic verification, go-containerregistry for Docker image operations
Cross-platform build matrix: linux/darwin/windows × amd64/arm64 via GoReleaser
Go code must passgolangci-lint run,go vet, andgo test -race— vulnerability check viagovulncheck
Use nativetesting.Ffuzz functions (Fuzz*) for property-based testing of Go CLI packages
Files:
cli/cmd/procattr_other.gocli/cmd/procattr_windows.gocli/cmd/uninstall.go
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T13:34:44.305Z
Learning: Applies to cli/**/*.go : Cross-platform build matrix: linux/darwin/windows × amd64/arm64 via GoReleaser
📚 Learning: 2026-03-19T13:34:44.305Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T13:34:44.305Z
Learning: Applies to cli/**/*.go : Cross-platform build matrix: linux/darwin/windows × amd64/arm64 via GoReleaser
Applied to files:
cli/.gitignorecli/.goreleaser.yml.github/workflows/cli.ymlcli/cmd/procattr_other.go
📚 Learning: 2026-03-15T11:48:14.867Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T11:48:14.867Z
Learning: Applies to cli/** : CLI: Go 1.26+, dependencies in cli/go.mod (Cobra, charmbracelet/huh).
Applied to files:
cli/.gitignore.github/workflows/cli.ymlcli/cmd/procattr_other.gocli/cmd/uninstall.go
📚 Learning: 2026-03-19T13:34:44.305Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T13:34:44.305Z
Learning: Applies to .github/workflows/release.yml : Release workflow must auto-create draft GitHub releases via Release Please, tag with semver, and set BSL Change Date to 3 years ahead
Applied to files:
.github/workflows/cli.yml
📚 Learning: 2026-03-19T13:34:44.305Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T13:34:44.305Z
Learning: Applies to cli/**/*.go : Go CLI binary uses Cobra for command routing, charmbracelet libraries (huh, lipgloss) for interactive prompts and styled output, sigstore-go for cryptographic verification, go-containerregistry for Docker image operations
Applied to files:
cli/cmd/uninstall.go
📚 Learning: 2026-03-15T11:48:14.867Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T11:48:14.867Z
Learning: Shell commands: for Go CLI work, cd cli is an exception because Go tooling requires working directory to be the module root. Go commands require `cd cli` for other work, never use `cd`.
Applied to files:
cli/cmd/uninstall.go
🧬 Code graph analysis (1)
cli/cmd/uninstall.go (2)
cli/internal/docker/client.go (2)
Info(22-29)RunCmd(110-119)cli/internal/verify/identity.go (2)
RegistryHost(27-27)ImageRepoPrefix(30-30)
🔇 Additional comments (7)
cli/.gitignore (1)
1-2: LGTM!The comment clearly explains why LICENSE is gitignored, and this properly prevents the CI-copied file from being accidentally committed to the repository.
cli/.goreleaser.yml (1)
34-37: LGTM!The path change from
../LICENSEtoLICENSEcorrectly aligns with the new CI workflow step that copies the root LICENSE into thecli/directory before GoReleaser runs. This resolves the archive failure with GoReleaser v2.14.3 while keeping the same destination and timestamp metadata..github/workflows/cli.yml (1)
284-286: LGTM!The LICENSE copy step is correctly positioned before GoReleaser execution and aligns with the corresponding changes in
cli/.goreleaser.ymlandcli/.gitignore. All actions in this workflow remain SHA-pinned, compliant with supply chain security guidelines.cli/cmd/procattr_windows.go (1)
1-11: LGTM!The Windows-specific implementation correctly uses
CREATE_NEW_PROCESS_GROUPto detach the child process, allowing it to survive after the parent exits. The_windows.gofilename suffix correctly constrains the build to Windows.cli/cmd/procattr_other.go (1)
1-12: LGTM!The build constraint
//go:build !windowscorrectly gates this stub for non-Windows platforms. Returningnilis appropriate sinceexec.Cmd.SysProcAttr = nilis a no-op on Unix systems.cli/cmd/uninstall.go (2)
268-302: LGTM!The refactored function cleanly separates platform-specific logic with appropriate delegation to
removeUnixBinaryandscheduleWindowsCleanup. Symlink resolution ensures the actual binary is targeted.
304-312: LGTM!Graceful degradation with clear manual instructions if removal fails. Returning
nilon error is appropriate since the uninstall should complete even if binary removal requires manual intervention.
cli/cmd/uninstall.go
Outdated
| listOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images", | ||
| "--filter", "reference="+imageRef+"*", | ||
| "--format", "{{.Repository}}:{{.Tag}} ({{.Size}})", | ||
| ) |
There was a problem hiding this comment.
Bug: Using ComposeCmd[0] instead of DockerPath for docker image commands.
When Compose V1 is installed, info.ComposeCmd is ["docker-compose"], so ComposeCmd[0] would be "docker-compose". The command docker-compose images behaves differently from docker images—it lists images used by compose services, not local images by reference filter.
Use info.DockerPath instead, which always points to the Docker CLI binary.
🐛 Proposed fix
- listOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images",
+ listOut, err := docker.RunCmd(ctx, info.DockerPath, "images",
"--filter", "reference="+imageRef+"*",
"--format", "{{.Repository}}:{{.Tag}} ({{.Size}})",
)Also apply the same fix at lines 167-170 and 183:
- idsOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images",
+ idsOut, err := docker.RunCmd(ctx, info.DockerPath, "images",- if _, rmiErr := docker.RunCmd(ctx, info.ComposeCmd[0], rmiArgs...); rmiErr != nil {
+ if _, rmiErr := docker.RunCmd(ctx, info.DockerPath, rmiArgs...); rmiErr != nil {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| listOut, err := docker.RunCmd(ctx, info.ComposeCmd[0], "images", | |
| "--filter", "reference="+imageRef+"*", | |
| "--format", "{{.Repository}}:{{.Tag}} ({{.Size}})", | |
| ) | |
| listOut, err := docker.RunCmd(ctx, info.DockerPath, "images", | |
| "--filter", "reference="+imageRef+"*", | |
| "--format", "{{.Repository}}:{{.Tag}} ({{.Size}})", | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@cli/cmd/uninstall.go` around lines 131 - 134, Replace uses of
info.ComposeCmd[0] when invoking docker.RunCmd for listing/removing images with
info.DockerPath so the Docker CLI (not docker-compose) is used; specifically
update the docker.RunCmd calls that pass info.ComposeCmd[0], e.g. the calls that
build the "images" command with "--filter reference="+imageRef and any
subsequent docker.RunCmd invocations that remove or inspect images, to use
info.DockerPath instead while keeping the same args (imageRef, "--format",
etc.); apply the same change for the other occurrences in uninstall.go where
docker.RunCmd is called with info.ComposeCmd[0] (the additional calls referenced
in the review).
Address review findings from CodeRabbit and Gemini: - Replace broken goto/labels in cmd /c with temp .bat file approach (labels don't work in single-line cmd /c commands) - Use info.DockerPath instead of info.ComposeCmd[0] for docker images and docker rmi (docker-compose doesn't support --filter/--format) - Use context.Background() for detached cleanup process (parent context cancellation shouldn't kill the cleanup) - Use timeout /t 1 instead of ping for delay - Replace em-dashes with ASCII dashes in error messages - .bat self-deletes via del "%%~f0" as final step Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@coderabbitai review |
## Summary Reverts the Release Please commit for v0.3.7 (`bf58779`) because the CLI GoReleaser step failed during the release workflow (LICENSE path resolution error). The draft release and tag have been deleted. **What this reverts:** - `.github/.release-please-manifest.json`: 0.3.7 -> 0.3.6 - `.github/CHANGELOG.md`: removes 0.3.7 entry - `pyproject.toml`: 0.3.7 -> 0.3.6 - `src/synthorg/__init__.py`: 0.3.7 -> 0.3.6 **What was already cleaned up:** - Deleted draft GitHub Release for v0.3.7 - Deleted remote tag v0.3.7 **Next steps:** 1. Merge this PR (resets version to 0.3.6) 2. Merge #590 (fixes GoReleaser LICENSE path + uninstall improvements) 3. Release Please will auto-create a new release PR for 0.3.7 that includes all fixes 4. Merging that release PR will re-trigger Docker + CLI workflows with the GoReleaser fix in place :robot: Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Version updated from 0.3.7 to 0.3.6 across configuration and version metadata files. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **cli:** auto-delete binary on Windows, prune images, fix GoReleaser ([#590](#590)) ([eb7c691](eb7c691)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) ### Maintenance * **main:** release 0.3.7 ([#583](#583)) ([bf58779](bf58779)) * reset failed v0.3.7 release ([#591](#591)) ([b69000d](b69000d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added engine Hybrid Plan + ReAct execution loop * Added first-run setup wizard * **Bug Fixes** * Addressed ZAP DAST scan issues * Fixed CLI Windows/image/update issues * **Maintenance** * Added SBOM generation for Docker/CLI releases * General maintenance updates <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary Two issues caused the v0.3.7 CLI release to fail: 1. **GoReleaser LICENSE path** -- fixed in #590 (already merged) 2. **Syft SBOM scan** -- syft tried to auto-detect `.tar.gz`/`.zip` archives as container images and failed. Fix: prefix `$artifact` with `file:` scheme so syft knows to scan as a local file archive This PR: - Reverts the Release Please v0.3.7 commit (`2e8e633`) to reset version back to 0.3.6 - Fixes the syft scan command in `.goreleaser.yml` - v0.3.7 draft release and tag already deleted After merge, Release Please will auto-create a new 0.3.7 release PR with both fixes in place. ## Changes - **`.github/.release-please-manifest.json`**: 0.3.7 -> 0.3.6 - **`.github/CHANGELOG.md`**: remove 0.3.7 entry - **`pyproject.toml`**: 0.3.7 -> 0.3.6 - **`src/synthorg/__init__.py`**: 0.3.7 -> 0.3.6 - **`cli/.goreleaser.yml`**: `scan $artifact` -> `scan file:$artifact` :robot: Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **ci:** reset failed v0.3.7 release and fix syft SBOM scan ([#593](#593)) ([d1508c2](d1508c2)) * **cli:** auto-delete binary on Windows, prune images, fix GoReleaser ([#590](#590)) ([eb7c691](eb7c691)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
## Summary Syft cannot scan Go binary archives (`.tar.gz`/`.zip`) -- it tries to interpret them as container images and fails. Since CLI binaries are statically linked with `CGO_ENABLED=0`, there are no runtime dependencies to catalog. Docker image SBOMs (generated by the Docker workflow via syft on actual container images) remain unchanged. This is the third v0.3.7 release attempt. Previous failures: 1. GoReleaser `../LICENSE` path resolution (fixed in #590) 2. Syft `file:$artifact` still failed on archive auto-detection (this PR removes it) ## Changes - **`cli/.goreleaser.yml`**: Remove `sboms:` stanza entirely - **`.github/workflows/cli.yml`**: Remove `*.cdx.json` from upload glob, remove `CLI_SBOM_DATA` HTML comment block - **`.github/workflows/finalize-release.yml`**: Remove `CLI_SBOM` extraction, simplify SBOM rendering to container-only - **`CLAUDE.md`**: Remove CLI SBOM references from CI documentation - Reverts Release Please v0.3.7 commit, tag + release already deleted ## Test plan - [x] All pre-commit and pre-push hooks pass - [x] GoReleaser config validates (no sboms stanza) - [ ] Next v0.3.7 release: GoReleaser should complete without syft errors :robot: Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🤖 I have created a release *beep* *boop* --- ## [0.3.7](v0.3.6...v0.3.7) (2026-03-19) ### Features * **engine:** implement Hybrid Plan + ReAct execution loop ([#582](#582)) ([008147c](008147c)) * implement first-run setup wizard ([#584](#584)) ([dfed931](dfed931)) ### Bug Fixes * **api:** address ZAP DAST scan findings ([#579](#579)) ([ce9a3e0](ce9a3e0)) * **ci:** remove CLI SBOM generation, reset failed v0.3.7 ([#595](#595)) ([d0f4992](d0f4992)) * **ci:** reset failed v0.3.7 release and fix syft SBOM scan ([#593](#593)) ([d1508c2](d1508c2)) * **cli:** auto-delete binary on Windows, prune images, fix GoReleaser ([#590](#590)) ([eb7c691](eb7c691)) * **cli:** regenerate compose and re-exec binary on update ([#576](#576)) ([3f226eb](3f226eb)) ### CI/CD * add SBOM generation to Docker and CLI releases ([#580](#580)) ([db459cf](db459cf)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
synthorg uninstallon Windows now auto-deletes the binary after exit (spawns a detached cmd.exe that polls tasklist, then cleans up binary + empty dirs)ghcr.io/aureliolo/synthorg-*container images, showing image list with sizes before confirmation../LICENSEpath resolution failure on v2.14.3 (first tag release exposed latent bug -- copy LICENSE into cli/ during CI instead)Changes
cli/cmd/uninstall.go: AddconfirmAndRemoveImages(lists + removes SynthOrg Docker images),scheduleWindowsCleanup(detached PID-polling cmd.exe for binary + dir cleanup), refactorconfirmAndRemoveBinaryto dispatch per-platform. Fix em-dashes in error messages.cli/cmd/procattr_windows.go:windowsDetachedProcAttrreturnsCREATE_NEW_PROCESS_GROUPSysProcAttr.cli/cmd/procattr_other.go: No-op stub for non-Windows (build tag!windows).cli/.goreleaser.yml: Changesrc: ../LICENSEtosrc: LICENSE(relative to workdir)..github/workflows/cli.yml: Copy LICENSE into cli/ before GoReleaser runs.cli/.gitignore: Exclude the CI-only LICENSE copy.Test plan
go build ./...cleango vet ./...cleangolangci-lint runclean (noctx fixed)go test ./...all passsynthorg uninstallon Windows -- verify binary auto-deleted after exitsynthorg uninstall-- verify image removal prompt appears and worksCloses #581
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes