Files

74 lines
2.1 KiB
Go

package session
import (
"fmt"
"sort"
"strings"
)
// DetectExternalChanges compares the current workspace state against the
// EndManifest recorded in .ctask/last-session-summary.json.
//
// Returns (nil, nil) if no summary exists (pre-v0.4 workspace or first
// session ever) — callers should treat this as "silently skip the warning".
//
// Returns a non-nil diff with empty slices when nothing changed outside a
// ctask session.
func DetectExternalChanges(wsDir string) (*ManifestDiff, error) {
summary, err := ReadSummary(SummaryPath(wsDir))
if err != nil {
return nil, err
}
if summary == nil {
return nil, nil
}
previous := &Manifest{
CapturedAt: summary.EndedAt,
Files: append([]FileEntry{}, summary.EndManifest...),
}
current, err := CaptureManifest(wsDir)
if err != nil {
return nil, err
}
return DiffManifests(previous, current), nil
}
// FormatStaleWarning renders the Layer-3 warning shown when the workspace
// was modified outside a ctask session since the last session ended.
func FormatStaleWarning(summary *SessionSummary, diff *ManifestDiff) string {
var b strings.Builder
b.WriteString("[ctask] Workspace modified since last session ended:\n\n")
fmt.Fprintf(&b, " Last session: %s (%s, %s)\n\n",
summary.EndedAt.Local().Format("2006-01-02 15:04"),
summary.Hostname, summary.Agent)
b.WriteString(" Modified since then:\n")
lines := append([]string{}, diff.Modified...)
sort.Strings(lines)
for _, f := range lines {
fmt.Fprintf(&b, " %s (modified)\n", f)
}
added := append([]string{}, diff.Added...)
sort.Strings(added)
for _, f := range added {
fmt.Fprintf(&b, " %s (new file)\n", f)
}
deleted := append([]string{}, diff.Deleted...)
sort.Strings(deleted)
for _, f := range deleted {
fmt.Fprintf(&b, " %s (deleted)\n", f)
}
b.WriteString("\n These changes were not made during a ctask session.\n")
b.WriteString(" Review before continuing? [Y/n] ")
return b.String()
}
// HasChanges returns true if diff reports any added/modified/deleted entries.
func HasChanges(d *ManifestDiff) bool {
if d == nil {
return false
}
return len(d.Added) > 0 || len(d.Modified) > 0 || len(d.Deleted) > 0
}