Add gt role command group for env-based role detection (gt-1xsah)
- New gt role subcommands: show, home, detect, list, env - Role detection now checks GT_ROLE env var first, falls back to cwd - gt prime shows warning when role/cwd mismatch detected - gt mol status uses env-aware role detection - gt handoff injects GT_ROLE and resets to role canonical home - Fixed witness/refinery home paths (was missing /rig suffix) This prevents role confusion when agents wander to wrong directories. After handoff, agents are always restored to their canonical home.
This commit is contained in:
@@ -260,13 +260,23 @@ func buildRestartCommand(sessionName string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// For respawn-pane, we cd to the right directory then run claude.
|
||||
// Determine GT_ROLE value for this session
|
||||
gtRole := sessionToGTRole(sessionName)
|
||||
|
||||
// For respawn-pane, we:
|
||||
// 1. cd to the right directory (role's canonical home)
|
||||
// 2. export GT_ROLE so role detection works correctly
|
||||
// 3. run claude
|
||||
// The SessionStart hook will run gt prime.
|
||||
// Use exec to ensure clean process replacement.
|
||||
if gtRole != "" {
|
||||
return fmt.Sprintf("cd %s && export GT_ROLE=%s && exec claude --dangerously-skip-permissions", workDir, gtRole), nil
|
||||
}
|
||||
return fmt.Sprintf("cd %s && exec claude --dangerously-skip-permissions", workDir), nil
|
||||
}
|
||||
|
||||
// sessionWorkDir returns the correct working directory for a session.
|
||||
// This is the canonical home for each role type.
|
||||
func sessionWorkDir(sessionName, townRoot string) (string, error) {
|
||||
switch {
|
||||
case sessionName == "gt-mayor":
|
||||
@@ -292,22 +302,53 @@ func sessionWorkDir(sessionName, townRoot string) (string, error) {
|
||||
return "", fmt.Errorf("cannot parse crew session name: %s", sessionName)
|
||||
|
||||
case strings.HasSuffix(sessionName, "-witness"):
|
||||
// gt-<rig>-witness -> <townRoot>/<rig>/witness
|
||||
// gt-<rig>-witness -> <townRoot>/<rig>/witness/rig
|
||||
rig := strings.TrimPrefix(sessionName, "gt-")
|
||||
rig = strings.TrimSuffix(rig, "-witness")
|
||||
return fmt.Sprintf("%s/%s/witness", townRoot, rig), nil
|
||||
return fmt.Sprintf("%s/%s/witness/rig", townRoot, rig), nil
|
||||
|
||||
case strings.HasSuffix(sessionName, "-refinery"):
|
||||
// gt-<rig>-refinery -> <townRoot>/<rig>/refinery
|
||||
// gt-<rig>-refinery -> <townRoot>/<rig>/refinery/rig
|
||||
rig := strings.TrimPrefix(sessionName, "gt-")
|
||||
rig = strings.TrimSuffix(rig, "-refinery")
|
||||
return fmt.Sprintf("%s/%s/refinery", townRoot, rig), nil
|
||||
return fmt.Sprintf("%s/%s/refinery/rig", townRoot, rig), nil
|
||||
|
||||
default:
|
||||
return "", fmt.Errorf("unknown session type: %s (try specifying role explicitly)", sessionName)
|
||||
}
|
||||
}
|
||||
|
||||
// sessionToGTRole converts a session name to a GT_ROLE value.
|
||||
func sessionToGTRole(sessionName string) string {
|
||||
switch {
|
||||
case sessionName == "gt-mayor":
|
||||
return "mayor"
|
||||
case sessionName == "gt-deacon":
|
||||
return "deacon"
|
||||
case strings.Contains(sessionName, "-crew-"):
|
||||
// gt-<rig>-crew-<name> -> <rig>/crew/<name>
|
||||
parts := strings.Split(sessionName, "-")
|
||||
for i, p := range parts {
|
||||
if p == "crew" && i > 1 && i < len(parts)-1 {
|
||||
rig := strings.Join(parts[1:i], "-")
|
||||
name := strings.Join(parts[i+1:], "-")
|
||||
return fmt.Sprintf("%s/crew/%s", rig, name)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
case strings.HasSuffix(sessionName, "-witness"):
|
||||
rig := strings.TrimPrefix(sessionName, "gt-")
|
||||
rig = strings.TrimSuffix(rig, "-witness")
|
||||
return fmt.Sprintf("%s/witness", rig)
|
||||
case strings.HasSuffix(sessionName, "-refinery"):
|
||||
rig := strings.TrimPrefix(sessionName, "gt-")
|
||||
rig = strings.TrimSuffix(rig, "-refinery")
|
||||
return fmt.Sprintf("%s/refinery", rig)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// detectTownRootFromCwd walks up from the current directory to find the town root.
|
||||
func detectTownRootFromCwd() string {
|
||||
cwd, err := os.Getwd()
|
||||
|
||||
Reference in New Issue
Block a user