feat: add Builder background service#167
Conversation
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThis pull request introduces a platform-specific background service management system for Builder, enabling users to run a persistent local server process via Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e2b7b3152
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ca448f6a2a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (9)
scripts/sandbox-serve.sh (1)
165-172: Optional: probe without sending a stray newline.
echo >/dev/tcp/127.0.0.1/"$host_port"opens the TCP connection and writes a newline byte to whoever owns the port. For most listeners that's harmless, but custom/binary protocols may log it as a malformed request. A read-only open is sufficient to detect listening:♻️ Suggested refactor
require_host_port_available() { if [ "$dry_run" = "true" ]; then return 0 fi - if (echo >/dev/tcp/127.0.0.1/"$host_port") >/dev/null 2>&1; then + if (: </dev/tcp/127.0.0.1/"$host_port") >/dev/null 2>&1; then die "host port ${host_port} is already in use. Stop the owner or pass --host-port <free-port>." fi }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/sandbox-serve.sh` around lines 165 - 172, In require_host_port_available(), the check currently uses "echo >/dev/tcp/127.0.0.1/$host_port" which opens the TCP socket and writes a newline; change this to open the socket read-only to avoid sending data: replace the echo write with a read-only redirection (for example use "</dev/tcp/127.0.0.1/$host_port" with the same >/dev/null 2>&1 capture) so the function still detects a listener but does not send a stray byte; update the conditional in require_host_port_available to use the read-only open and keep the dry_run and die behavior unchanged.scripts/scripts_test.go (1)
104-134: Optional: a Go raw string literal makes the fakedockerscript easier to audit.The escape-laden single-line bash payload is functionally fine but hard to scan/diff. A backtick raw string literal preserves shell quoting verbatim and matches how
bash -cstyle snippets are typically written elsewhere.♻️ Suggested refactor
- fakeDocker := filepath.Join(binDir, "docker") - if err := os.WriteFile(fakeDocker, []byte("#!/usr/bin/env bash\nif [ \"${1:-}\" = info ]; then exit 0; fi\nif [ \"${1:-}\" = container ] && [ \"${2:-}\" = inspect ]; then exit 1; fi\necho unexpected docker \"$@\" >&2\nexit 1\n"), 0o755); err != nil { + fakeDocker := filepath.Join(binDir, "docker") + fakeDockerScript := `#!/usr/bin/env bash +if [ "${1:-}" = info ]; then exit 0; fi +if [ "${1:-}" = container ] && [ "${2:-}" = inspect ]; then exit 1; fi +echo unexpected docker "$@" >&2 +exit 1 +` + if err := os.WriteFile(fakeDocker, []byte(fakeDockerScript), 0o755); err != nil { t.Fatalf("write fake docker: %v", err) }The two golangci-lint hints (
errcheckondefer listener.Close()andnoctxonnet.Listen) are standard test-file false positives and don't need addressing here unless the linter is configured to gate this package.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/scripts_test.go` around lines 104 - 134, The test TestSandboxServeUpReportsHostPortInUse uses an escaped single-line shell payload when writing the fakeDocker script, which is hard to read; replace the current escaped string in the os.WriteFile call that writes fakeDocker with a Go raw string literal (backticks) containing the same bash script so the shell quoting is preserved and the script is easier to audit, leaving the file mode (0o755) and the surrounding logic (listener, port, cmd setup) unchanged; keep the function name TestSandboxServeUpReportsHostPortInUse and the fakeDocker variable so the rest of the test continues to reference the same symbols.README.md (1)
48-50: Optional: minor wording fixes flagged by LanguageTool.
- Line 48: consider "On-the-fly changing of toolsets or models" (hyphenate the prenominal compound).
- Line 50: "java etc" → "java etc." (period after the abbreviation).
📝 Proposed wording tweaks
-- On the fly changing of toolsets or models. Changing models at runtime hurts model performance and invalidates caches, which can cost up to 10x more per invalidation. +- On-the-fly changing of toolsets or models. Changing models at runtime hurts model performance and invalidates caches, which can cost up to 10x more per invalidation. @@ -- Sandboxing - Codex's sandbox is annoying, doesn't work with many tools (gradle, java etc), junie's sandbox can be bypassed, claude code's sandbox is brittle and can also be bypassed. Builder can be easily sandboxed in a true, fully isolated Docker container with remote connection (no ssh hacks). +- Sandboxing - Codex's sandbox is annoying, doesn't work with many tools (gradle, java, etc.), junie's sandbox can be bypassed, claude code's sandbox is brittle and can also be bypassed. Builder can be easily sandboxed in a true, fully isolated Docker container with remote connection (no ssh hacks).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 48 - 50, Update the README phrase "On the fly changing of toolsets or models" to the hyphenated prenominal compound "On-the-fly changing of toolsets or models" and add a period to the abbreviation in "java etc" so it reads "java etc."; locate these phrases in the block containing "On the fly changing of toolsets or models" and "Sandboxing - Codex's sandbox..." and make the two small wording edits.cli/builder/service_backend_windows.go (1)
54-59: Useerrors.Joinso both errors stay unwrappable.
fmt.Errorf("%w; startup fallback failed: %v", err, fallbackErr)only makes the schtasks error unwrappable.errors.Join(err, fmt.Errorf("startup fallback failed: %w", fallbackErr))preserves both for callers that may want to introspect either failure (e.g., to surface a clearer hint when only the fallback path is broken).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/builder/service_backend_windows.go` around lines 54 - 59, Replace the composite error formatting so both errors remain unwrappable: in the block where runServiceCommand(...) returns an error and you call installWindowsStartupItem(...), use errors.Join(err, fmt.Errorf("startup fallback failed: %w", fallbackErr)) instead of fmt.Errorf("%w; startup fallback failed: %v", err, fallbackErr) and ensure the errors package is imported; this keeps both the schtasks error and the fallback error available for callers inspecting runServiceCommand and installWindowsStartupItem.cli/builder/service_types.go (2)
132-149: Preferos.Executable()overos.Args[0]for service-registration paths.
os.Args[0]is the string the parent process passed in theargvvector and is not guaranteed to be the path of the running binary (it can be set to anything viaexec/syscall.Exec, and isn't resolved againstPATHuntil you do it explicitly here). For something that gets persisted into a launchd plist / systemd unit / scheduled-task script and re-executed at every login,os.Executable()is the more reliable boundary value, matching this file's coding-guideline expectation of validating invariants at boundaries.♻️ Suggested approach
func defaultServiceExecutablePath() (string, error) { - raw := strings.TrimSpace(os.Args[0]) - if raw == "" { - return "", errors.New("resolve executable path: argv[0] is empty") - } - if strings.ContainsAny(raw, `/\`) { - abs, err := filepath.Abs(raw) - if err != nil { - return "", fmt.Errorf("resolve executable path: %w", err) - } - return abs, nil - } - path, err := exec.LookPath(raw) - if err != nil { - return "", fmt.Errorf("resolve executable path: %w", err) - } - return path, nil + exe, err := os.Executable() + if err != nil { + return "", fmt.Errorf("resolve executable path: %w", err) + } + resolved, err := filepath.EvalSymlinks(exe) + if err != nil { + return exe, nil + } + return resolved, nil }As per coding guidelines: "Validate invariants at boundaries (input, filesystem, process execution, API responses) in Go code".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/builder/service_types.go` around lines 132 - 149, The function defaultServiceExecutablePath currently uses os.Args[0]; replace that logic to call os.Executable() to obtain the actual running binary path, check the returned value for empty and return a wrapped error, then use filepath.Abs (and optionally filepath.EvalSymlinks) on the executable path and return the resolved absolute path; update defaultServiceExecutablePath to remove the os.Args[0] branches and ensure all errors from os.Executable, filepath.EvalSymlinks (if used), and filepath.Abs are wrapped with the same "resolve executable path: %w" formatting used elsewhere.
89-104: Prefererrors.Asover a raw type assertion for*exec.ExitError.Idiomatic Go uses
errors.Asso a wrapped*exec.ExitError(e.g., from a future helper) still unwraps correctly.♻️ Proposed refactor
- if exitErr, ok := err.(*exec.ExitError); ok { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { result.Stderr = string(exitErr.Stderr) result.Code = exitErr.ExitCode() return result, serviceCommandError{Name: name, Args: args, Result: result} }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/builder/service_types.go` around lines 89 - 104, The runServiceCommand function currently uses a raw type assertion to detect *exec.ExitError; replace that with errors.As to correctly unwrap wrapped errors: in runServiceCommand, import the errors package and use var exitErr *exec.ExitError and if errors.As(err, &exitErr) { set result.Stderr = string(exitErr.Stderr), result.Code = exitErr.ExitCode(), and return serviceCommandError{Name: name, Args: args, Result: result} } while keeping the fallback that sets result.Stderr = err.Error() and result.Code = 1 and returns serviceCommandError; keep all uses of serviceCommandResult and serviceCommandError unchanged.cli/builder/service_command.go (1)
268-297: Replace the"ok"magic string with aprotocolconstant.The health status
"ok"is hardcoded inserver/serve/serve.go:148and compared directly incli/builder/service_types.go:204andservice_command.go:274. Sinceprotocol.HealthPathis already used to define the health endpoint path, define a corresponding constant (e.g.,protocol.HealthStatusOK) to keep the client-server contract type-safe and prevent drift if the status value ever changes.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/builder/service_command.go` around lines 268 - 297, Replace the hardcoded "ok" health string with a typed constant: add a constant (e.g., HealthStatusOK) to the protocol package alongside protocol.HealthPath and use that constant wherever health responses are compared; specifically update ensureNoUnmanagedServerConflict to set healthRunning := healthStatus == protocol.HealthStatusOK and update any other comparisons in service_types.go (where "ok" is checked). Ensure the new protocol constant is documented, exported, and imported where needed so the client/server contract uses protocol.HealthStatusOK instead of the magic "ok" string.cli/builder/service_backend_linux.go (2)
24-55: Consider rolling back the written unit file ifdaemon-reload/enable/restartfails.If
os.WriteFilesucceeds but a subsequentsystemctlstep fails (line 43, 46, or 50), the unit file is left on disk while the install is reported as failed. A subsequentInstallwithout--forcewill then succeed silently when content matches, or hit the “already installed” path even though no service is actually enabled. Removing the freshly-written file on error (or only writing it after a dry-run/validation) keeps install state consistent.Optional — happy to defer if the current behavior is intentional given users can always re-run with
--force.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/builder/service_backend_linux.go` around lines 24 - 55, The Install method on systemdServiceBackend currently writes the unit file (os.WriteFile(renderSystemdUnit)) before running systemctl steps, so if runServiceCommand("systemctl", "--user", "daemon-reload"/"enable"/"restart") fails the file is left behind; update Install to rollback the written unit on error by either (a) deferring deletion of path and removing it if any subsequent runServiceCommand call returns an error, or (b) move the write to after a successful daemon-reload/enable/restart validation step; reference the Install function, the os.WriteFile call that writes renderSystemdUnit(spec), the systemdUnitPath()/path variable, runServiceCommand invocations for "daemon-reload"/"enable"/"restart", and the serviceSystemdUnitName so the cleanup targets the correct unit file when rolling back.
92-95:Restartdoes not validate that the unit is installed (inconsistent withStart).
Start(lines 73–82) returns a friendly “not installed; runbuilder service install” error when the unit file is missing, butRestartskips the check and letssystemctl restartproduce a generic failure instead. For UX consistency, mirror the same precondition.🔧 Suggested change
func (systemdServiceBackend) Restart(ctx context.Context, spec serviceSpec) error { + path, err := systemdUnitPath() + if err != nil { + return err + } + if _, err := os.Stat(path); err != nil { + if errors.Is(err, os.ErrNotExist) { + return errors.New("Builder background service is not installed; run `builder service install`") + } + return fmt.Errorf("stat systemd unit: %w", err) + } _, err := runServiceCommand(ctx, "systemctl", "--user", "restart", serviceSystemdUnitName) return err }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/builder/service_backend_linux.go` around lines 92 - 95, The Restart method in systemdServiceBackend should perform the same "unit installed" precondition check as Start to return the friendly "not installed; run `builder service install`" error instead of letting systemctl produce a generic failure; update Restart (in systemdServiceBackend) to call the same installation-check logic used by Start before invoking runServiceCommand("systemctl", "--user", "restart", serviceSystemdUnitName) and return the same explanatory error when the unit is missing.
🤖 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/builder/service_backend_linux.go`:
- Around line 73-82: The code calls mustSystemdUnitPath() in Start which hides
UserHomeDir errors and returns "" leading to a misleading "not installed"
message; replace calls to mustSystemdUnitPath() with systemdUnitPath() and
propagate its error (i.e., check err from systemdUnitPath() and return
fmt.Errorf("determine systemd unit path: %w", err) before calling os.Stat or
runServiceCommand), and remove the mustSystemdUnitPath helper if unused; apply
the same change to the other service methods that currently call
mustSystemdUnitPath (e.g., the methods around the Status/Stop/Enable logic) so
all callers properly surface home-dir resolution errors.
- Around line 84-90: Replace the substring error check in
systemdServiceBackend.Stop with a structural pre-check: call systemctl --user
show <serviceSystemdUnitName> --property=LoadState --value (via
runServiceCommand or a small helper) to read the unit's LoadState, and if the
LoadState indicates the unit is not present/not loaded (e.g. "not-found" or any
value other than "loaded") return nil; only invoke runServiceCommand(ctx,
"systemctl", "--user", "stop", serviceSystemdUnitName) when the LoadState shows
the unit is loaded (or otherwise eligible to be stopped), and propagate any
error from that stop invocation. Ensure you add/rename helper(s) if needed so
the logic is in Stop (and reference serviceSystemdUnitName and
runServiceCommand).
- Around line 97-127: The Status method in systemdServiceBackend incorrectly
derives Loaded from the is-active call; change it to query LoadState separately
by calling runServiceCommand(ctx, "systemctl", "--user", "show",
serviceSystemdUnitName, "--property=LoadState", "--value"), parse and trim the
output and set Loaded = (loadState == "loaded") (keep Running derived from
is-active as before), while still using the existing show call for MainPID via
parsePositiveInt; update references in systemdServiceBackend.Status and ensure
any error handling around runServiceCommand for the LoadState call mirrors the
pattern used for other systemctl calls.
In `@cli/builder/service_backend_windows.go`:
- Around line 111-135: The Status method uses a brittle substring check
(strings.Contains on taskOutput) to detect "running" which can produce false
positives; update scheduledTaskServiceBackend.Status to stop using
strings.Contains(..., "running") and instead rely solely on the reliable
PID-based liveness from windowsTaskScriptPIDs (already called) to set Running
and PID (i.e., Running = len(taskScriptPIDs) > 0 and PID = first PID when
present), and remove the taskOutput-based running determination (or if you
prefer to keep schtasks parsing, replace the /FO LIST usage with /FO CSV and
parse the Status column deterministically); change the code in Status around the
variables taskOutput, running, pid and the call sites using
windowsTaskScriptPIDs and windowsScheduledTaskInstalled accordingly.
- Around line 249-263: In windowsTaskScriptPIDs, the PowerShell -like pattern
uses unescaped user-controlled needle from windowsTaskScriptPath causing
failures if the path contains [ or ]; change the generated script (created
before calling runServiceCommand) to perform a literal, case-insensitive
substring match instead of -like — e.g., keep the needle assignment but replace
the Where-Object clause with a containment check using IndexOf/Contains with
[StringComparison]::OrdinalIgnoreCase (or call .ToLower() on both sides) and
ensure you still select ProcessId in the ForEach-Object; this ensures literal
matching even when spec.Config.PersistenceRoot includes brackets.
In `@cli/builder/service_types.go`:
- Around line 213-235: The function probeServiceHealth currently returns the
parsed health.Status and PID even for non-2xx responses; change its behavior so
that after decoding the JSON (the block using json.NewDecoder on resp.Body) you
check resp.StatusCode and if it's not in the 200..299 range return empty string
and 0 (discarding health and PID), otherwise return
strings.TrimSpace(health.Status) and health.PID; update the branches in
probeServiceHealth (around http.NewRequestWithContext, serviceHTTPClient.Do and
the Decode call) so non-2xx responses yield "", 0 to avoid false-positive health
detection used by ensureNoUnmanagedServerConflict and applyHealthProbe.
---
Nitpick comments:
In `@cli/builder/service_backend_linux.go`:
- Around line 24-55: The Install method on systemdServiceBackend currently
writes the unit file (os.WriteFile(renderSystemdUnit)) before running systemctl
steps, so if runServiceCommand("systemctl", "--user",
"daemon-reload"/"enable"/"restart") fails the file is left behind; update
Install to rollback the written unit on error by either (a) deferring deletion
of path and removing it if any subsequent runServiceCommand call returns an
error, or (b) move the write to after a successful daemon-reload/enable/restart
validation step; reference the Install function, the os.WriteFile call that
writes renderSystemdUnit(spec), the systemdUnitPath()/path variable,
runServiceCommand invocations for "daemon-reload"/"enable"/"restart", and the
serviceSystemdUnitName so the cleanup targets the correct unit file when rolling
back.
- Around line 92-95: The Restart method in systemdServiceBackend should perform
the same "unit installed" precondition check as Start to return the friendly
"not installed; run `builder service install`" error instead of letting
systemctl produce a generic failure; update Restart (in systemdServiceBackend)
to call the same installation-check logic used by Start before invoking
runServiceCommand("systemctl", "--user", "restart", serviceSystemdUnitName) and
return the same explanatory error when the unit is missing.
In `@cli/builder/service_backend_windows.go`:
- Around line 54-59: Replace the composite error formatting so both errors
remain unwrappable: in the block where runServiceCommand(...) returns an error
and you call installWindowsStartupItem(...), use errors.Join(err,
fmt.Errorf("startup fallback failed: %w", fallbackErr)) instead of
fmt.Errorf("%w; startup fallback failed: %v", err, fallbackErr) and ensure the
errors package is imported; this keeps both the schtasks error and the fallback
error available for callers inspecting runServiceCommand and
installWindowsStartupItem.
In `@cli/builder/service_command.go`:
- Around line 268-297: Replace the hardcoded "ok" health string with a typed
constant: add a constant (e.g., HealthStatusOK) to the protocol package
alongside protocol.HealthPath and use that constant wherever health responses
are compared; specifically update ensureNoUnmanagedServerConflict to set
healthRunning := healthStatus == protocol.HealthStatusOK and update any other
comparisons in service_types.go (where "ok" is checked). Ensure the new protocol
constant is documented, exported, and imported where needed so the client/server
contract uses protocol.HealthStatusOK instead of the magic "ok" string.
In `@cli/builder/service_types.go`:
- Around line 132-149: The function defaultServiceExecutablePath currently uses
os.Args[0]; replace that logic to call os.Executable() to obtain the actual
running binary path, check the returned value for empty and return a wrapped
error, then use filepath.Abs (and optionally filepath.EvalSymlinks) on the
executable path and return the resolved absolute path; update
defaultServiceExecutablePath to remove the os.Args[0] branches and ensure all
errors from os.Executable, filepath.EvalSymlinks (if used), and filepath.Abs are
wrapped with the same "resolve executable path: %w" formatting used elsewhere.
- Around line 89-104: The runServiceCommand function currently uses a raw type
assertion to detect *exec.ExitError; replace that with errors.As to correctly
unwrap wrapped errors: in runServiceCommand, import the errors package and use
var exitErr *exec.ExitError and if errors.As(err, &exitErr) { set result.Stderr
= string(exitErr.Stderr), result.Code = exitErr.ExitCode(), and return
serviceCommandError{Name: name, Args: args, Result: result} } while keeping the
fallback that sets result.Stderr = err.Error() and result.Code = 1 and returns
serviceCommandError; keep all uses of serviceCommandResult and
serviceCommandError unchanged.
In `@README.md`:
- Around line 48-50: Update the README phrase "On the fly changing of toolsets
or models" to the hyphenated prenominal compound "On-the-fly changing of
toolsets or models" and add a period to the abbreviation in "java etc" so it
reads "java etc."; locate these phrases in the block containing "On the fly
changing of toolsets or models" and "Sandboxing - Codex's sandbox..." and make
the two small wording edits.
In `@scripts/sandbox-serve.sh`:
- Around line 165-172: In require_host_port_available(), the check currently
uses "echo >/dev/tcp/127.0.0.1/$host_port" which opens the TCP socket and writes
a newline; change this to open the socket read-only to avoid sending data:
replace the echo write with a read-only redirection (for example use
"</dev/tcp/127.0.0.1/$host_port" with the same >/dev/null 2>&1 capture) so the
function still detects a listener but does not send a stray byte; update the
conditional in require_host_port_available to use the read-only open and keep
the dry_run and die behavior unchanged.
In `@scripts/scripts_test.go`:
- Around line 104-134: The test TestSandboxServeUpReportsHostPortInUse uses an
escaped single-line shell payload when writing the fakeDocker script, which is
hard to read; replace the current escaped string in the os.WriteFile call that
writes fakeDocker with a Go raw string literal (backticks) containing the same
bash script so the shell quoting is preserved and the script is easier to audit,
leaving the file mode (0o755) and the surrounding logic (listener, port, cmd
setup) unchanged; keep the function name TestSandboxServeUpReportsHostPortInUse
and the fakeDocker variable so the rest of the test continues to reference the
same symbols.
🪄 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: CHILL
Plan: Pro
Run ID: bf854a06-6f83-41f4-9afe-38706dce1533
📒 Files selected for processing (21)
README.mdcli/builder/help.gocli/builder/main.gocli/builder/service_backend_darwin.gocli/builder/service_backend_linux.gocli/builder/service_backend_other.gocli/builder/service_backend_windows.gocli/builder/service_backend_windows_test.gocli/builder/service_command.gocli/builder/service_command_test.gocli/builder/service_types.godocs/astro.config.mjsdocs/src/content/docs/headless.mddocs/src/content/docs/quickstart.mddocs/src/content/docs/server.mddocs/src/content/docs/service.mdscripts/sandbox-serve.shscripts/sandbox/builder-sandbox-entrypoint.shscripts/sandbox/builder-sandbox.Dockerfilescripts/scripts_test.goscripts/update-brew-tap.sh
💤 Files with no reviewable changes (1)
- scripts/sandbox/builder-sandbox.Dockerfile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 677e9318ca
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 041583a1df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 62cdeafbf6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
# Conflicts: # docs/src/content/docs/quickstart.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a350718e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
feat: add Builder background service
Summary
builder servicelifecycle commands for the Builder server background serviceVerification
go test ./...GOOS=linux GOARCH=arm64 go test -c ./cli/builder -o /tmp/builder-cli-linux.testGOOS=windows GOARCH=amd64 go test -c ./cli/builder -o /tmp/builder-cli-windows.test.exe./scripts/test.sh ./..../scripts/build.sh --output ./bin/builderpnpm --dir docs testpnpm --dir docs buildSummary by CodeRabbit
New Features
builder servicecommand for installing, starting, stopping, and managing a shared Builder background server.Documentation