feat: default sandbox to enabled, polish CLI output, add sandbox CI build#455
feat: default sandbox to enabled, polish CLI output, add sandbox CI build#455
Conversation
…uild - Default Sandbox to true in DefaultState() and setup form so sandboxed code execution is on by default - Add cli/internal/ui package with lipgloss-styled output (Logo, Step, Success, Warn, Error, KeyValue, Hint) and box-drawing ASCII banner with version display - Replace plain fmt.Fprintf in init.go and start.go with styled UI - Promote charmbracelet/lipgloss from indirect to direct dependency - Add build-sandbox job to docker.yml (parallel with backend/web), with Trivy + Grype scans, cosign signing, and SLSA L3 attestation - Update update-release job with sandbox image row, digest, and verification commands
Pre-reviewed by 5 agents, 8 findings addressed: - Cache lipgloss styles in UI struct fields instead of per-call allocation - Convert 6 repetitive test functions to table-driven TestOutputMethods - Migrate init.go overwrite warning from raw fmt.Fprintf to ui.Warn - Remove duplicate comment in init.go - Replace fmt.Sprintf with string concatenation in start.go - Conservative Load fallback: Sandbox=false when no config file exists - Update CLAUDE.md: add ui/ package, lipgloss dep, sandbox CI build
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
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 user experience and security posture of the SynthOrg CLI. It introduces a new Highlights
Changelog
Ignored Files
Activity
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. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds a styled CLI UI package, integrates the UI into init/start commands, introduces a Sandbox Docker image and corresponding build-sandbox CI job with scanning/signing/attestation, and threads SANDBOX_DIGEST through release-note composition and verification. CLI config gains a Sandbox field with updated defaults and validation. Changes
Sequence Diagram(s)sequenceDiagram
participant GH as GitHub Actions
participant Buildx as Docker Buildx
participant GHCR as GitHub Container Registry
participant Scanner as Security Scanners (Trivy/Grype/CIS)
participant Cosign as Cosign (sign/verify)
participant Release as Release workflow
rect rgba(135,206,250,0.5)
GH->>Buildx: trigger build-sandbox (checkout, setup)
Buildx->>GHCR: build sandbox image + compute digest
Buildx->>GH: emit SANDBOX_DIGEST
end
rect rgba(144,238,144,0.5)
GH->>Scanner: run Trivy/Grype/CIS on sandbox image
Scanner-->>GH: scan results (fail on critical/high)
end
rect rgba(255,228,181,0.5)
GH->>Cosign: sign image and create attestation
Cosign-->>GHCR: push signature/attestation
end
rect rgba(221,160,221,0.5)
Release->>GH: depend on build-sandbox, receive SANDBOX_DIGEST
Release->>Cosign: verify sandbox signature/attestation using SANDBOX_DIGEST
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
✨ Simplify code
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a polished CLI output using the lipgloss library, which is a great improvement for user experience. It also correctly defaults the sandbox feature to be enabled during initial setup, with a safe fallback for non-interactive sessions. The changes are well-implemented, including updates to documentation and new tests for the UI components. I have a couple of suggestions to improve code consistency and maintainability in the new ui package and its usage.
cli/cmd/start.go
Outdated
| return err | ||
| } | ||
| _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Docker %s, Compose %s\n", info.DockerVersion, info.ComposeVersion) | ||
| out.Success("Docker " + info.DockerVersion + ", Compose " + info.ComposeVersion) |
There was a problem hiding this comment.
For consistency with other parts of the codebase (e.g., cli/cmd/init.go) and for better readability, it's preferable to use fmt.Sprintf for string formatting instead of concatenation with +.
| out.Success("Docker " + info.DockerVersion + ", Compose " + info.ComposeVersion) | |
| out.Success(fmt.Sprintf("Docker %s, Compose %s", info.DockerVersion, info.ComposeVersion)) |
| // Step prints an in-progress status line. | ||
| func (u *UI) Step(msg string) { | ||
| _, _ = fmt.Fprintf(u.w, "%s %s\n", u.brand.Render(IconInProgress), msg) | ||
| } | ||
|
|
||
| // Success prints a success status line. | ||
| func (u *UI) Success(msg string) { | ||
| _, _ = fmt.Fprintf(u.w, "%s %s\n", u.success.Render(IconSuccess), msg) | ||
| } | ||
|
|
||
| // Warn prints a warning status line. | ||
| func (u *UI) Warn(msg string) { | ||
| _, _ = fmt.Fprintf(u.w, "%s %s\n", u.warn.Render(IconWarning), msg) | ||
| } | ||
|
|
||
| // Error prints an error status line. | ||
| func (u *UI) Error(msg string) { | ||
| _, _ = fmt.Fprintf(u.w, "%s %s\n", u.err.Render(IconError), msg) | ||
| } |
There was a problem hiding this comment.
The methods Step, Success, Warn, and Error share a very similar implementation structure. To improve maintainability and reduce code duplication, you could introduce a private helper method to handle the common logic of printing a styled icon and a message.
For example, you could add:
// printLine prints a styled icon and a message.
func (u *UI) printLine(style lipgloss.Style, icon, msg string) {
_, _ = fmt.Fprintf(u.w, "%s %s\n", style.Render(icon), msg)
}And then refactor the methods like so:
// Step prints an in-progress status line.
func (u *UI) Step(msg string) {
u.printLine(u.brand, IconInProgress, msg)
}This would apply to Success, Warn, and Error as well.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cli/internal/config/state_test.go (1)
124-134: 🧹 Nitpick | 🔵 TrivialAdd assertion for
Sandboxfallback behavior inTestLoadMissing.The
Load()function now explicitly setsSandbox = falsewhen no config file exists (conservative fallback). This behavior should be tested here to ensure the invariant is maintained.🧪 Proposed test enhancement
func TestLoadMissing(t *testing.T) { tmp := t.TempDir() s, err := Load(tmp) if err != nil { t.Fatalf("Load missing file: %v", err) } // Should return defaults. if s.BackendPort != 8000 { t.Errorf("expected default BackendPort 8000, got %d", s.BackendPort) } + // Conservative fallback: sandbox disabled when no config exists. + if s.Sandbox { + t.Error("Sandbox should be false when config file is missing") + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/internal/config/state_test.go` around lines 124 - 134, Update TestLoadMissing to also assert the conservative Sandbox fallback: after calling Load(tmp) verify that s.Sandbox is false (in addition to the existing BackendPort check); locate the test function TestLoadMissing and add an assertion that s.Sandbox == false so the Load() behavior for missing config (Sandbox = false) is enforced.
🤖 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/internal/ui/ui.go`:
- Around line 37-42: Extract the inline ANSI color codes into clearly named
constants and use those constants in the style initializations; for example, add
constants (e.g., colorBrand, colorSuccess, colorWarn, colorErr, colorMuted,
colorLabel) and replace occurrences like
r.NewStyle().Foreground(lipgloss.Color("99")) in the
brand/success/warn/err/muted/label initializations with
r.NewStyle().Foreground(lipgloss.Color(colorBrand)) etc., leaving the existing
r.NewStyle().Foreground and lipgloss.Color usage intact so intent and
maintainability are improved.
---
Outside diff comments:
In `@cli/internal/config/state_test.go`:
- Around line 124-134: Update TestLoadMissing to also assert the conservative
Sandbox fallback: after calling Load(tmp) verify that s.Sandbox is false (in
addition to the existing BackendPort check); locate the test function
TestLoadMissing and add an assertion that s.Sandbox == false so the Load()
behavior for missing config (Sandbox = false) is enforced.
🪄 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: 65c30482-39cf-4c2b-9f21-b0a2cce2f03f
📒 Files selected for processing (10)
.github/workflows/docker.ymlCLAUDE.mdcli/cmd/init.gocli/cmd/start.gocli/go.modcli/internal/config/state.gocli/internal/config/state_test.gocli/internal/ui/logo.gocli/internal/ui/ui.gocli/internal/ui/ui_test.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). (4)
- GitHub Check: Build Web
- GitHub Check: Build Sandbox
- GitHub Check: Build Backend
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (1)
cli/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
cli/**/*.go: Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, or config examples — use generic names
Rungolangci-lint,go vet, andgo test -racebefore committing; these are enforced in pre-push hooks and CI
Use nativetesting.Ffuzz functions (FuzzXxx) for property-based testing; run withgo test -fuzz=FuzzName -fuzztime=30s ./...
Files:
cli/internal/config/state.gocli/internal/config/state_test.gocli/cmd/init.gocli/internal/ui/ui_test.gocli/cmd/start.gocli/internal/ui/ui.gocli/internal/ui/logo.go
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T11:48:14.867Z
Learning: Commits: <type>: <description> — types: feat, fix, refactor, docs, test, chore, perf, ci. Enforced by commitizen (commit-msg hook). Signed commits: required on main via branch protection — all commits must be GPG/SSH signed.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T11:48:14.867Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.
📚 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/go.modcli/cmd/init.gocli/cmd/start.gocli/internal/ui/ui.gocli/internal/ui/logo.goCLAUDE.md
📚 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 .github/workflows/docker.yml : CI Docker: build → scan → push to GHCR + cosign sign + SLSA L3 provenance via attest-build-provenance (images only pushed after Trivy/Grype scans pass).
Applied to files:
.github/workflows/docker.ymlCLAUDE.md
📚 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 docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.
Applied to files:
.github/workflows/docker.ymlCLAUDE.md
📚 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: Dependabot: auto-updates Docker image digests and versions daily.
Applied to files:
.github/workflows/docker.ymlCLAUDE.md
📚 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 .github/workflows/**/*.yml : Path filtering: dorny/paths-filter detects Python/dashboard/docker changes; jobs only run when their domain is affected. CLI has its own workflow (cli.yml).
Applied to files:
.github/workflows/docker.ymlCLAUDE.md
📚 Learning: 2026-03-15T12:05:56.884Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T12:05:56.884Z
Learning: Applies to docker/**/*.py : Backend Dockerfile must use 3-stage build (builder → setup → distroless runtime), Chainguard Python base, run as non-root (UID 65532), and apply CIS hardening
Applied to files:
.github/workflows/docker.yml
📚 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: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on cli/**/*.go) (fast gate before push, skipped in pre-commit.ci — dedicated CI jobs already run these).
Applied to files:
CLAUDE.md
📚 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: Pre-commit hooks: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks, hadolint (Dockerfile linting).
Applied to files:
CLAUDE.md
📚 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: Commits: <type>: <description> — types: feat, fix, refactor, docs, test, chore, perf, ci. Enforced by commitizen (commit-msg hook). Signed commits: required on main via branch protection — all commits must be GPG/SSH signed.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T12:05:56.884Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T12:05:56.884Z
Learning: Applies to cli/**/*.go : Run `golangci-lint`, `go vet`, and `go test -race` before committing; these are enforced in pre-push hooks and CI
Applied to files:
CLAUDE.md
📚 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 pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).
Applied to files:
CLAUDE.md
📚 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 web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).
Applied to files:
CLAUDE.md
🧬 Code graph analysis (2)
cli/cmd/init.go (4)
cli/internal/ui/ui.go (1)
NewUI(33-44)cli/internal/config/state.go (1)
StatePath(38-40)cli/internal/config/paths.go (1)
DataDir(18-31)cli/internal/version/version.go (1)
Version(9-9)
cli/internal/ui/ui_test.go (1)
cli/internal/ui/ui.go (7)
NewUI(33-44)UI(21-29)IconSuccess(13-13)IconInProgress(14-14)IconWarning(15-15)IconError(16-16)IconHint(17-17)
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~261-~261: The official name of this software platform is spelled with a capital “H”.
Context: ...le builds on rapid pushes - Docker: .github/workflows/docker.yml — builds backend ...
(GITHUB)
[uncategorized] ~261-~261: The official name of this software platform is spelled with a capital “H”.
Context: ...pliance (informational). CVE triage via .github/.trivyignore.yaml and `.github/.grype....
(GITHUB)
[uncategorized] ~261-~261: The official name of this software platform is spelled with a capital “H”.
Context: ...age via .github/.trivyignore.yaml and .github/.grype.yaml. Images only pushed after ...
(GITHUB)
🔇 Additional comments (21)
cli/go.mod (1)
7-7: LGTM!Promoting
lipglossto a direct dependency is appropriate since the newcli/internal/uipackage imports it directly for styled output.cli/internal/config/state_test.go (1)
25-27: LGTM!The test correctly validates the new default behavior where
SandboxistrueinDefaultState().cli/internal/config/state.go (2)
32-32: LGTM!Setting
Sandbox: trueinDefaultState()ensures the setup form pre-selects sandboxed code execution, which is the safer default for new configurations.
55-57: Good conservative fallback design.Disabling sandbox when no config file exists ensures sandbox mode requires explicit user confirmation via
synthorg init. This prevents unintended sandbox execution when a user runs commands before initialization.cli/internal/ui/logo.go (1)
1-6: LGTM!Clean implementation of the ASCII art banner using Unicode box-drawing characters. The non-exported
logoconstant is appropriately scoped for internal use by theLogo()method.CLAUDE.md (3)
155-155: LGTM!Documentation accurately describes the new
ui/package and its lipgloss-based styling capabilities.
261-261: LGTM!Documentation correctly reflects the addition of the sandbox image build job to the Docker workflow.
286-286: LGTM!CLI dependency list correctly updated to include
charmbracelet/lipgloss..github/workflows/docker.yml (3)
565-565: LGTM!The
update-releasejob correctly addsbuild-sandboxto its dependencies, ensuring release notes are only updated after all three images are successfully built and pushed.
578-646: LGTM!The release notes composition correctly includes the sandbox image with:
- Environment variable for
SANDBOX_DIGEST- Validation check for all three digests
- Sandbox row in the image table
- Digest pinning entry
- Cosign verification command
gh attestation verifycommand- Proper placeholder substitution
394-559: Well-structured sandbox build job.The
build-sandboxjob correctly mirrors the existingbuild-backendandbuild-webjobs with consistent security practices: Trivy/Grype scans, CIS benchmark, cosign signing, and SLSA L3 attestation. The requireddocker/sandbox/Dockerfileexists.cli/internal/ui/ui.go (2)
1-44: LGTM!Clean UI implementation with:
- Styles cached in struct fields for efficiency
- Renderer auto-detection from writer for terminal capability handling
- Well-documented public API
46-81: LGTM!All output methods follow a consistent pattern with proper icon/style rendering and newline termination.
cli/cmd/start.go (3)
15-15: LGTM!Import of the new
uipackage for styled CLI output.
47-48: LGTM!Creating separate UI instances for stdout and stderr is the correct approach, allowing warnings and errors to be routed appropriately while maintaining styled output.
54-84: LGTM!Consistent use of UI methods throughout the start flow:
Successfor completion states (Docker detection, running status)Stepfor in-progress operations (pull, start, health wait)Warnfor version warnings (stderr)Error/Hintfor failure recovery guidance (stderr)KeyValuefor final URL displayError handling and control flow remain intact.
cli/internal/ui/ui_test.go (2)
9-21: LGTM!Clean test structure. The assertions correctly validate that the logo output includes structural elements (box-drawing character) and the dynamic version string.
23-52: LGTM! Well-structured table-driven test.Good use of table-driven testing pattern with clear case names, function invocations, and expected content checks. The newline termination assertion ensures consistent output formatting across all methods.
cli/cmd/init.go (3)
49-63: LGTM!Clean integration of the UI package for stderr warnings. Using a separate
errOutinstance for the overwrite warning keeps the warning output properly directed to stderr while maintaining the styled formatting.
70-78: LGTM!Good use of the UI package for structured output. The flow (logo → success → key-values → warning → hint) provides clear, styled feedback to the user. Using stdout for this block, including the privacy warning, keeps the success output cohesive.
99-99: LGTM!The sandbox field correctly initializes from
defaults.Sandbox, aligning with the PR objective to pre-select sandbox in the setup form based onDefaultState().
- CLAUDE.md: add sandbox image description, fix "both" → "all" images - ui.go: extract color constants, DRY printLine helper, pre-compute brandBold, add stripControl sanitization, improve godoc comments - logo.go: fix "ASCII art" → "Unicode" terminology - state.go: wrap Load errors with context, add validate method for port ranges, improve DefaultState doc to note sandbox divergence - state_test.go: assert Sandbox=false in TestLoadMissing - init.go: scope errOut UI inside conditional, use string concat - start.go: use fmt.Sprintf for version display consistency - ui_test.go: assert version string placement in TestLogo - generate.go: handle null bytes in yamlStr YAML escaping
🤖 I have created a release *beep* *boop* --- ## [0.2.5](v0.2.4...v0.2.5) (2026-03-15) ### Features * default sandbox to enabled, polish CLI output, add sandbox CI build ([#455](#455)) ([a4869b6](a4869b6)) ### Bug Fixes * export .intoto.jsonl provenance for OpenSSF Scorecard ([#456](#456)) ([2feed09](2feed09)) ### Maintenance * add pyrightconfig.json and fix all pyright errors ([#448](#448)) ([f60746a](f60746a)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
DefaultState()now returnsSandbox: trueso the setup form pre-selects sandboxed code execution.Load()fallback (no config file) conservatively setsSandbox: false— sandbox requires explicit user confirmation viasynthorg init.cli/internal/uipackage with lipgloss-styled output — branded ASCII logo with version display, colored status icons (✓ ● ! ✗ →), key-value formatting, and hint lines. Replaces all rawfmt.Fprintfininit.goandstart.go.build-sandboxjob indocker.ymlruns in parallel with backend/web builds. Same scan/sign/attest pipeline (Trivy + Grype + CIS + cosign + SLSA L3). Release notes updated with sandbox image row, digest, and verification commands.Test plan
go test ./...— all packages pass (config, ui, compose, docker, health, diagnostics, selfupdate)go vet ./...— cleango build ./...— compilesbuild-sandboxjob runs in CI on this PR (docker.yml triggers ondocker/**changes — sandbox Dockerfile exists)Review coverage
Pre-reviewed by 5 agents (go-reviewer, go-security-reviewer, go-conventions-enforcer, infra-reviewer, docs-consistency). 8 findings identified and addressed:
🤖 Generated with Claude Code