feat(infra): modelo de datos del meta-orquestador de flota (flow 0012)
Fase 1, piezas 1+2: - ClaudeFleet + list_claude_fleet ganan DodContract/DodStatus/Role, leidos de goals/<sessionId>.json (.dod_contract/.dod_status/.role). Aditivo: fleetview sigue compilando. - classify_fleet_termination (pura): clasifica el estado de terminacion de un agente (RECLAMA/MAL_LANZADO/DICE_TERMINADO/ESTANCADO/TRABAJANDO) con precedencia fija, para que un watcher sin LLM decida. 34 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,10 +25,13 @@ type sessionFile struct {
|
||||
|
||||
// goalFile mirrors the on-disk shape of ~/.claude/goals/<sessionId>.json.
|
||||
type goalFile struct {
|
||||
Goal string `json:"goal"`
|
||||
Phase string `json:"phase"`
|
||||
Emojis string `json:"emojis"`
|
||||
Rename string `json:"rename"`
|
||||
Goal string `json:"goal"`
|
||||
Phase string `json:"phase"`
|
||||
Emojis string `json:"emojis"`
|
||||
Rename string `json:"rename"`
|
||||
DodContract string `json:"dod_contract"`
|
||||
DodStatus string `json:"dod_status"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
// runtimeFile mirrors ~/.claude/runtime/<sessionId>.json written by statusline.sh
|
||||
@@ -104,8 +107,9 @@ func ListClaudeFleetFrom(claudeDir string) ([]ClaudeFleet, error) {
|
||||
// KITTY_PID from the process environ (0 if unreadable / absent).
|
||||
f.KittyPID = readKittyPID(sess.PID)
|
||||
|
||||
// Join goal/phase/emojis/name from goals/<sessionId>.json (optional).
|
||||
f.Goal, f.Phase, f.Emojis, f.Name = readGoal(goalsDir, sess.SessionID)
|
||||
// Join goal/phase/emojis/name + DoD contract/status from
|
||||
// goals/<sessionId>.json (optional).
|
||||
f.Goal, f.Phase, f.Emojis, f.Name, f.DodContract, f.DodStatus, f.Role = readGoal(goalsDir, sess.SessionID)
|
||||
|
||||
// Context usage from runtime/<sessionId>.json (written by statusline).
|
||||
f.CtxPct = readCtxPct(runtimeDir, sess.SessionID)
|
||||
@@ -179,18 +183,19 @@ func readKittyPID(pid int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// readGoal reads goals/<sessionID>.json and returns its goal, phase, emojis and
|
||||
// manual rename. If the file is absent or unparseable, all are "".
|
||||
func readGoal(goalsDir, sessionID string) (goal, phase, emojis, rename string) {
|
||||
// readGoal reads goals/<sessionID>.json and returns its goal, phase, emojis,
|
||||
// manual rename, DoD contract, DoD status and role. If the file is absent or
|
||||
// unparseable, all are "".
|
||||
func readGoal(goalsDir, sessionID string) (goal, phase, emojis, rename, dodContract, dodStatus, role string) {
|
||||
raw, err := os.ReadFile(filepath.Join(goalsDir, sessionID+".json"))
|
||||
if err != nil {
|
||||
return "", "", "", ""
|
||||
return "", "", "", "", "", "", ""
|
||||
}
|
||||
var g goalFile
|
||||
if json.Unmarshal(raw, &g) != nil {
|
||||
return "", "", "", ""
|
||||
return "", "", "", "", "", "", ""
|
||||
}
|
||||
return g.Goal, g.Phase, g.Emojis, g.Rename
|
||||
return g.Goal, g.Phase, g.Emojis, g.Rename, g.DodContract, g.DodStatus, g.Role
|
||||
}
|
||||
|
||||
// readCtxPct reads runtime/<sessionID>.json and returns the context-window used
|
||||
|
||||
Reference in New Issue
Block a user