feat(v0.5.3): shared workspace-entry helper; resume + last delegate; fresh_remote prompt

This commit is contained in:
2026-05-08 13:59:53 -04:00
parent 08fb5bb1c3
commit f5746df314
8 changed files with 447 additions and 25 deletions
+36
View File
@@ -5,7 +5,9 @@ import (
"fmt"
"os"
"runtime"
"time"
"github.com/warrenronsiek/ctask/internal/session"
"github.com/warrenronsiek/ctask/internal/shell"
)
@@ -84,3 +86,37 @@ func preflightPersistentEntry(commandName string) (string, error) {
}
return tmuxPath, nil
}
// confirmFreshRemoteAdoption prompts the user to confirm adoption of a
// workspace whose lease is fresh but from a different host. Refuses on
// non-TTY environments — silent overwrite of a fresh remote lease is
// never appropriate.
func confirmFreshRemoteAdoption(wsPath string) error {
l, _ := session.ReadLease(session.LeasePath(wsPath))
hostStr := "unknown"
heartbeatAgo := "unknown"
if l != nil {
hostStr = l.Hostname
heartbeatAgo = session.FormatAgo(time.Since(l.LastHeartbeatAt))
}
if !isTTYCheck() {
return fmt.Errorf(
"ctask refused to adopt persistent session: lease is fresh from another host (%s, last heartbeat %s ago); rerun in an interactive terminal to confirm",
hostStr, heartbeatAgo)
}
fmt.Fprintf(os.Stderr,
"[ctask] tmux session exists, but a fresh lease from another host is present:\n"+
"[ctask] hostname: %s\n"+
"[ctask] last heartbeat: %s ago\n"+
"[ctask]\n"+
"[ctask] This may indicate another machine is actively using this workspace\n"+
"[ctask] (e.g., shared filesystem). Adopting will overwrite the remote lease\n"+
"[ctask] and may create conflicting workspace activity.\n"+
"[ctask]\n"+
"Adopt anyway? [y/N] ",
hostStr, heartbeatAgo)
if !session.ConfirmYN(os.Stdin, os.Stderr, "", false) {
return fmt.Errorf("[ctask] adoption refused; wait for the remote session to end or unset CTASK_SESSION_MODE")
}
return nil
}