package focus import ( "path/filepath" "keel/internal/harness" "keel/internal/mode" ) // build constructs a focus Mode under the mode's namespaced dir and injects the // shared services through the existing setters (the same API tests use). func build(svc harness.Services) (*Mode, error) { m, err := New(filepath.Join(svc.Dir, "state.json")) if err != nil { return nil, err } if svc.Clock != nil { m.SetClock(svc.Clock) } m.SetCoach(svc.AI) m.SetReviewer(svc.AI) m.SetDriftJudge(svc.AI) m.SetNudge(svc.AI) m.SetTasks(svc.Tasks) m.SetKnowledge(svc.Knowledge) m.SetGuard(svc.Enforce) m.SetOnChange(svc.Notify) // harness fan-out becomes focus's change listener return m, nil } // Factory builds a fresh focus mode entering Planning (used by harness.Start). func Factory(svc harness.Services) mode.Mode { m, err := build(svc) if err != nil { m, _ = New("") // degrade to an in-memory Locked mode; EnterPlanning still works m.SetOnChange(svc.Notify) } _ = m.EnterPlanning() return m } // Restore loads a persisted focus session and reports whether one was live // (Planning/Active/Transition/Review). Used at startup to re-adopt a session. func Restore(svc harness.Services) (*Mode, bool, error) { m, err := build(svc) if err != nil { return nil, false, err } return m, m.Active(), nil }