Skip to content

feat: default sandbox to enabled, polish CLI output, add sandbox CI build#455

Merged
Aureliolo merged 3 commits intomainfrom
feat/cli-sandbox-and-polish
Mar 15, 2026
Merged

feat: default sandbox to enabled, polish CLI output, add sandbox CI build#455
Aureliolo merged 3 commits intomainfrom
feat/cli-sandbox-and-polish

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Default sandbox to enabled: DefaultState() now returns Sandbox: true so the setup form pre-selects sandboxed code execution. Load() fallback (no config file) conservatively sets Sandbox: false — sandbox requires explicit user confirmation via synthorg init.
  • Polish CLI output: New cli/internal/ui package with lipgloss-styled output — branded ASCII logo with version display, colored status icons (✓ ● ! ✗ →), key-value formatting, and hint lines. Replaces all raw fmt.Fprintf in init.go and start.go.
  • Sandbox CI build: New build-sandbox job in docker.yml runs 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.
  • CLAUDE.md: Updated package structure (ui/), dependencies (lipgloss), and Docker CI description (sandbox).

Test plan

  • go test ./... — all packages pass (config, ui, compose, docker, health, diagnostics, selfupdate)
  • go vet ./... — clean
  • go build ./... — compiles
  • golangci-lint — passed (pre-commit + pre-push hooks)
  • UI output manually verified via test binary (logo + styled lines render correctly)
  • Verify build-sandbox job runs in CI on this PR (docker.yml triggers on docker/** 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:

  • Cached lipgloss styles in struct fields (idiomatic pattern)
  • Table-driven tests for UI output methods
  • Migrated init.go overwrite warning to ui.Warn
  • Conservative Load fallback (Sandbox=false without config)
  • CLAUDE.md docs alignment

🤖 Generated with Claude Code

…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
Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 15, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 ui package for modern, styled terminal output, making interactions more intuitive and visually appealing. Concurrently, it shifts the default behavior to enable sandboxed code execution, promoting a more secure environment while ensuring users explicitly opt-in when no prior configuration exists. Furthermore, the CI/CD pipeline has been extended to include a dedicated build for the sandbox image, reinforcing the project's commitment to secure and verifiable releases.

Highlights

  • Default Sandbox Enabled: The DefaultState() now sets Sandbox: true, pre-selecting sandboxed code execution in the setup form. However, Load() conservatively defaults Sandbox: false if no config file exists, requiring explicit user confirmation via synthorg init.
  • Polished CLI Output: A new cli/internal/ui package has been introduced, leveraging lipgloss for styled CLI output. This includes a branded ASCII logo with version display, colored status icons (✓ ● ! ✗ →), key-value formatting, and hint lines, replacing raw fmt.Fprintf calls in init.go and start.go.
  • Sandbox CI Build: A new build-sandbox job has been added to docker.yml, running in parallel with backend/web builds. It follows the same scan/sign/attest pipeline (Trivy + Grype + CIS + cosign + SLSA L3), and release notes have been updated to include the sandbox image.
  • Documentation Updates: CLAUDE.md has been updated to reflect the new ui/ package structure, the lipgloss dependency, and the inclusion of the sandbox image in the Docker CI description.
Changelog
  • CLAUDE.md
    • Added ui/ package description to the CLI structure.
    • Updated Docker CI description to include "sandbox images".
    • Added charmbracelet/lipgloss to CLI dependencies.
  • cli/cmd/init.go
    • Imported github.com/Aureliolo/synthorg/cli/internal/ui.
    • Replaced fmt.Fprintf warning messages with ui.Warn.
    • Replaced fmt.Fprintf success and info messages with ui.Logo, ui.Success, ui.KeyValue, ui.Warn, and ui.Hint.
    • Initialized sandbox field in setupAnswers with defaults.Sandbox.
  • cli/cmd/start.go
    • Imported github.com/Aureliolo/synthorg/cli/internal/ui.
    • Replaced fmt.Fprintf calls with ui.NewUI, ui.Success, ui.Warn, ui.Step, ui.Error, and ui.KeyValue.
  • cli/go.mod
    • Added github.com/charmbracelet/lipgloss v1.1.0 as a direct requirement.
    • Removed github.com/charmbracelet/lipgloss v1.1.0 // indirect from indirect dependencies.
  • cli/internal/config/state.go
    • Set Sandbox: true in DefaultState().
    • Added logic in Load() to set defaults.Sandbox = false if no config file exists, ensuring explicit user confirmation for sandbox.
  • cli/internal/config/state_test.go
    • Added a test if !s.Sandbox { t.Error("Sandbox should default to true") } to TestDefaultState.
  • cli/internal/ui/logo.go
    • New file created with package ui and a const logo containing ASCII art.
  • cli/internal/ui/ui.go
    • New file created defining the ui package, UI struct, NewUI constructor, and methods for styled output (Logo, Step, Success, Warn, Error, KeyValue, Hint).
  • cli/internal/ui/ui_test.go
    • New file created with TestLogo and TestOutputMethods for the ui package.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/docker.yml
Activity
  • The pull request underwent pre-review by 5 agents (go-reviewer, go-security-reviewer, go-conventions-enforcer, infra-reviewer, docs-consistency).
  • 8 findings were identified and subsequently addressed, including caching lipgloss styles, adding table-driven tests for UI output, migrating overwrite warnings to ui.Warn, and aligning CLAUDE.md documentation.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 64c0487d-77de-48ab-8551-7ee87fa21a2b

📥 Commits

Reviewing files that changed from the base of the PR and between ed9f8ce and 0a38075.

📒 Files selected for processing (9)
  • CLAUDE.md
  • cli/cmd/init.go
  • cli/cmd/start.go
  • cli/internal/compose/generate.go
  • cli/internal/config/state.go
  • cli/internal/config/state_test.go
  • cli/internal/ui/logo.go
  • cli/internal/ui/ui.go
  • cli/internal/ui/ui_test.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Styled CLI output (logo, progress, success/warn/error, key/value, hints) across init and start flows
    • Interactive sandbox option in setup and defaults
  • Release / CI

    • Release pipeline now builds, scans, signs, and verifies a Sandbox container image alongside existing images
  • Chores

    • Config defaults updated for sandbox behavior
    • CLI UI unit tests added

Walkthrough

Adds 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

Cohort / File(s) Summary
Docker Workflow
​.github/workflows/docker.yml
Adds build-sandbox job (checkout, buildx, GHCR login, metadata, sandbox build, SHA-tag, Trivy/Grype/CIS scans, push/sign/attest). Releases now depend on it; SANDBOX_DIGEST propagated into release notes and verification including cosign/attestation checks.
CLI UI Component
cli/internal/ui/ui.go, cli/internal/ui/ui_test.go, cli/internal/ui/logo.go
New lipgloss-based UI package exposing UI type, NewUI and output methods (Logo, Step, Success, Warn, Error, KeyValue, Hint) and icon constants; includes unit tests and a logo constant.
CLI Commands
cli/cmd/init.go, cli/cmd/start.go
Replaces raw fmt output with UI usage (styled messages, warnings, hints, key/value output). Integrates sandbox option into interactive init flow and displays styled start summaries.
CLI Configuration & Tests
cli/internal/config/state.go, cli/internal/config/state_test.go
Adds Sandbox default handling (defaults true; disabled when no config present), improves error wrapping and validation, and validates port ranges. Tests updated for Sandbox default/fallback behavior.
Dependencies & Docs
cli/go.mod, CLAUDE.md
Promotes github.com/charmbracelet/lipgloss to a direct dependency and documents the new UI and sandbox additions in project docs/manifest.
Compose helper
cli/internal/compose/generate.go
Escapes/removes null bytes in yamlStr output and adjusts escaping order for robust compose string generation.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the three main changes: enabling default sandbox, polishing CLI output, and adding sandbox CI build.
Description check ✅ Passed The description comprehensively covers all major changes in the PR with specific technical details and addresses the objectives clearly.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/cli-sandbox-and-polish
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/cli-sandbox-and-polish
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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 +.

Suggested change
out.Success("Docker " + info.DockerVersion + ", Compose " + info.ComposeVersion)
out.Success(fmt.Sprintf("Docker %s, Compose %s", info.DockerVersion, info.ComposeVersion))

Comment on lines +53 to +71
// 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)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🔵 Trivial

Add assertion for Sandbox fallback behavior in TestLoadMissing.

The Load() function now explicitly sets Sandbox = false when 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

📥 Commits

Reviewing files that changed from the base of the PR and between f60746a and ed9f8ce.

📒 Files selected for processing (10)
  • .github/workflows/docker.yml
  • CLAUDE.md
  • cli/cmd/init.go
  • cli/cmd/start.go
  • cli/go.mod
  • cli/internal/config/state.go
  • cli/internal/config/state_test.go
  • cli/internal/ui/logo.go
  • cli/internal/ui/ui.go
  • cli/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
Run golangci-lint, go vet, and go test -race before committing; these are enforced in pre-push hooks and CI
Use native testing.F fuzz functions (FuzzXxx) for property-based testing; run with go test -fuzz=FuzzName -fuzztime=30s ./...

Files:

  • cli/internal/config/state.go
  • cli/internal/config/state_test.go
  • cli/cmd/init.go
  • cli/internal/ui/ui_test.go
  • cli/cmd/start.go
  • cli/internal/ui/ui.go
  • cli/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.mod
  • cli/cmd/init.go
  • cli/cmd/start.go
  • cli/internal/ui/ui.go
  • cli/internal/ui/logo.go
  • 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 .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.yml
  • 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 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.yml
  • 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: Dependabot: auto-updates Docker image digests and versions daily.

Applied to files:

  • .github/workflows/docker.yml
  • 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 .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.yml
  • 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 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 lipgloss to a direct dependency is appropriate since the new cli/internal/ui package 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 Sandbox is true in DefaultState().

cli/internal/config/state.go (2)

32-32: LGTM!

Setting Sandbox: true in DefaultState() 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 logo constant is appropriately scoped for internal use by the Logo() 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-release job correctly adds build-sandbox to 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 verify command
  • Proper placeholder substitution

394-559: Well-structured sandbox build job.

The build-sandbox job correctly mirrors the existing build-backend and build-web jobs with consistent security practices: Trivy/Grype scans, CIS benchmark, cosign signing, and SLSA L3 attestation. The required docker/sandbox/Dockerfile exists.

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 ui package 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:

  • Success for completion states (Docker detection, running status)
  • Step for in-progress operations (pull, start, health wait)
  • Warn for version warnings (stderr)
  • Error/Hint for failure recovery guidance (stderr)
  • KeyValue for final URL display

Error 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 errOut instance 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 on DefaultState().

- 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
@Aureliolo Aureliolo merged commit a4869b6 into main Mar 15, 2026
42 of 43 checks passed
@Aureliolo Aureliolo deleted the feat/cli-sandbox-and-polish branch March 15, 2026 18:35
Aureliolo added a commit that referenced this pull request Mar 15, 2026
🤖 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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant