Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions cmd/picoclaw/tui/tab_home.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ func (m *HomeModel) HandleExecDone(msg onboardExecDoneMsg) {
m.onboardStep = wizardService
case wizardService:
if msg.err != nil {
m.onboardResult = "Service install failed: " + msg.err.Error()
detail := strings.TrimSpace(msg.output)
if detail == "" {
detail = msg.err.Error()
}
m.onboardResult = "err:Service install failed: " + detail
} else {
m.onboardResult = "Service installed and started."
}
Expand Down Expand Up @@ -389,8 +393,14 @@ func (m HomeModel) viewWizard(snap *VMSnapshot, width int) string {
"\n" +
" " + styleDim.Render("This enables the background agent.") + "\n"
} else if m.onboardResult != "" {
icon := styleOK.Render("✓")
resultText := m.onboardResult
if strings.HasPrefix(m.onboardResult, "err:") {
icon = styleErr.Render("✗")
resultText = m.onboardResult[4:]
}
content = "\n" +
" " + styleOK.Render("✓") + " " + m.onboardResult + "\n" +
" " + icon + " " + resultText + "\n" +
"\n" +
" " + styleDim.Render("Press Enter to continue.") + "\n"
} else {
Expand Down
8 changes: 8 additions & 0 deletions pkg/service/launchd_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func (m *launchdManager) Install() error {
return err
}

// Clear any stale disabled state before bootstrap — a previous uninstall
// may have left the label in launchd's disabled overrides database, which
// causes bootstrap to fail with "Input/output error".
_, _ = runCommand(m.runner, 5*time.Second, "launchctl", "enable", m.serviceTarget)
_, _ = runCommand(m.runner, 10*time.Second, "launchctl", "bootout", m.serviceTarget)
if out, err := runCommand(m.runner, 10*time.Second, "launchctl", "bootstrap", m.domainTarget, m.plistPath); err != nil {
msg := strings.ToLower(string(out))
Expand All @@ -70,6 +74,8 @@ func (m *launchdManager) Install() error {

func (m *launchdManager) Uninstall() error {
_, _ = runCommand(m.runner, 10*time.Second, "launchctl", "bootout", m.serviceTarget)
// Clear the disabled override so a future install won't fail on bootstrap.
_, _ = runCommand(m.runner, 5*time.Second, "launchctl", "enable", m.serviceTarget)
if err := os.Remove(m.plistPath); err != nil && !os.IsNotExist(err) {
return err
}
Expand All @@ -84,6 +90,8 @@ func (m *launchdManager) Start() error {
return err
}

// Ensure the label isn't stuck in the disabled overrides database.
_, _ = runCommand(m.runner, 5*time.Second, "launchctl", "enable", m.serviceTarget)
if _, err := runCommand(m.runner, 3*time.Second, "launchctl", "print", m.serviceTarget); err != nil {
if out, err2 := runCommand(m.runner, 10*time.Second, "launchctl", "bootstrap", m.domainTarget, m.plistPath); err2 != nil {
msg := strings.ToLower(string(out))
Expand Down
Loading