Support full session paths in gt handoff (gt-tocb)
resolveRoleToSession now accepts paths like <rig>/crew/<name>, <rig>/witness, and <rig>/refinery in addition to role shortcuts. For example: 'gt handoff gastown/crew/max' now works. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -136,9 +136,19 @@ func getCurrentTmuxSession() (string, error) {
|
|||||||
return strings.TrimSpace(string(out)), nil
|
return strings.TrimSpace(string(out)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveRoleToSession converts a role name to a tmux session name.
|
// resolveRoleToSession converts a role name or path to a tmux session name.
|
||||||
// For roles that need context (crew, witness, refinery), it auto-detects from environment.
|
// Accepts:
|
||||||
|
// - Role shortcuts: "crew", "witness", "refinery", "mayor", "deacon"
|
||||||
|
// - Full paths: "<rig>/crew/<name>", "<rig>/witness", "<rig>/refinery"
|
||||||
|
// - Direct session names (passed through)
|
||||||
|
//
|
||||||
|
// For role shortcuts that need context (crew, witness, refinery), it auto-detects from environment.
|
||||||
func resolveRoleToSession(role string) (string, error) {
|
func resolveRoleToSession(role string) (string, error) {
|
||||||
|
// First, check if it's a path format (contains /)
|
||||||
|
if strings.Contains(role, "/") {
|
||||||
|
return resolvePathToSession(role)
|
||||||
|
}
|
||||||
|
|
||||||
switch strings.ToLower(role) {
|
switch strings.ToLower(role) {
|
||||||
case "mayor", "may":
|
case "mayor", "may":
|
||||||
return "gt-mayor", nil
|
return "gt-mayor", nil
|
||||||
@@ -178,11 +188,44 @@ func resolveRoleToSession(role string) (string, error) {
|
|||||||
return fmt.Sprintf("gt-%s-refinery", rig), nil
|
return fmt.Sprintf("gt-%s-refinery", rig), nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Assume it's a direct session name
|
// Assume it's a direct session name (e.g., gt-gastown-crew-max)
|
||||||
return role, nil
|
return role, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolvePathToSession converts a path like "<rig>/crew/<name>" to a session name.
|
||||||
|
// Supported formats:
|
||||||
|
// - <rig>/crew/<name> -> gt-<rig>-crew-<name>
|
||||||
|
// - <rig>/witness -> gt-<rig>-witness
|
||||||
|
// - <rig>/refinery -> gt-<rig>-refinery
|
||||||
|
func resolvePathToSession(path string) (string, error) {
|
||||||
|
parts := strings.Split(path, "/")
|
||||||
|
|
||||||
|
// Handle <rig>/crew/<name> format
|
||||||
|
if len(parts) == 3 && parts[1] == "crew" {
|
||||||
|
rig := parts[0]
|
||||||
|
name := parts[2]
|
||||||
|
return fmt.Sprintf("gt-%s-crew-%s", rig, name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle <rig>/<role> format (witness, refinery)
|
||||||
|
if len(parts) == 2 {
|
||||||
|
rig := parts[0]
|
||||||
|
role := strings.ToLower(parts[1])
|
||||||
|
switch role {
|
||||||
|
case "witness":
|
||||||
|
return fmt.Sprintf("gt-%s-witness", rig), nil
|
||||||
|
case "refinery":
|
||||||
|
return fmt.Sprintf("gt-%s-refinery", rig), nil
|
||||||
|
case "crew":
|
||||||
|
// Just "<rig>/crew" without a name - need more info
|
||||||
|
return "", fmt.Errorf("crew path requires name: %s/crew/<name>", rig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("cannot parse path '%s' - expected <rig>/crew/<name>, <rig>/witness, or <rig>/refinery", path)
|
||||||
|
}
|
||||||
|
|
||||||
// buildRestartCommand creates the command to run when respawning a session's pane.
|
// buildRestartCommand creates the command to run when respawning a session's pane.
|
||||||
// This needs to be the actual command to execute (e.g., claude), not a session attach command.
|
// This needs to be the actual command to execute (e.g., claude), not a session attach command.
|
||||||
// The command includes a cd to the correct working directory for the role.
|
// The command includes a cd to the correct working directory for the role.
|
||||||
|
|||||||
Reference in New Issue
Block a user