Extend coach proposal with allowed window classes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 16:49:06 -04:00
parent 83bae00e45
commit 75d31b5fa8
3 changed files with 42 additions and 8 deletions
+20 -7
View File
@@ -13,9 +13,10 @@ import (
// Proposal is the coach's structured suggestion for a commitment. It is not a
// domain.Commitment: the AI does not mint IDs, timestamps, or state.
type Proposal struct {
NextAction string
SuccessCondition string
TimeboxSecs int64
NextAction string
SuccessCondition string
TimeboxSecs int64
AllowedWindowClasses []string
}
var (
@@ -61,9 +62,10 @@ func extractJSON(s string) (string, error) {
}
type rawProposal struct {
NextAction string `json:"next_action"`
SuccessCondition string `json:"success_condition"`
TimeboxMinutes int64 `json:"timebox_minutes"`
NextAction string `json:"next_action"`
SuccessCondition string `json:"success_condition"`
TimeboxMinutes int64 `json:"timebox_minutes"`
AllowedWindowClasses []string `json:"allowed_window_classes"`
}
// parseProposal extracts and validates a Proposal from raw CLI output.
@@ -91,5 +93,16 @@ func parseProposal(s string) (Proposal, error) {
if na == "" || sc == "" || raw.TimeboxMinutes <= 0 {
return Proposal{}, ErrInvalidProposal
}
return Proposal{NextAction: na, SuccessCondition: sc, TimeboxSecs: raw.TimeboxMinutes * 60}, nil
classes := make([]string, 0, len(raw.AllowedWindowClasses))
for _, cls := range raw.AllowedWindowClasses {
if t := strings.TrimSpace(cls); t != "" {
classes = append(classes, t)
}
}
return Proposal{
NextAction: na,
SuccessCondition: sc,
TimeboxSecs: raw.TimeboxMinutes * 60,
AllowedWindowClasses: classes,
}, nil
}