Commit 1e0690bf862f
tools/claude-hooks/cmd/initialize-session/main.go
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
+ "os/exec"
"path/filepath"
"strconv"
"strings"
@@ -106,6 +107,31 @@ func loadCoreSkill() error {
return nil
}
+// isPiContext checks if we're running under pi coding agent
+func isPiContext() bool {
+ // Strategy 1: Check immediate parent process
+ ppid := os.Getppid()
+ cmdline := fmt.Sprintf("/proc/%d/comm", ppid)
+ data, err := os.ReadFile(cmdline)
+ if err == nil && strings.TrimSpace(string(data)) == "pi" {
+ return true
+ }
+
+ // Strategy 2: Check if "pi" is anywhere in the process tree
+ cmd := exec.Command("sh", "-c", fmt.Sprintf("ps -o comm= -p $(ps -o ppid= -p %d) 2>/dev/null || pstree -s %d 2>/dev/null", ppid, os.Getpid()))
+ output, err := cmd.Output()
+ if err == nil && strings.Contains(string(output), "pi") {
+ return true
+ }
+
+ // Strategy 3: Check PI_* environment variables (if pi sets any in future)
+ if os.Getenv("PI_AGENT") != "" || os.Getenv("PI_CODING_AGENT") != "" {
+ return true
+ }
+
+ return false
+}
+
func main() {
// Check if this is a subagent session
if isSubagentSession() {
@@ -119,8 +145,13 @@ func main() {
os.Exit(0)
}
- // Set initial tab title
+ // Detect context and set appropriate title
+ isPi := isPiContext()
tabTitle := "Claude Ready"
+ if isPi {
+ tabTitle = "π Ready"
+ }
+
setTerminalTitle(tabTitle)
fmt.Fprintf(os.Stderr, "📍 Session initialized: \"%s\"\n", tabTitle)
tools/claude-hooks/cmd/update-terminal-title/main.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
+ "os/exec"
"path/filepath"
"strings"
)
@@ -97,9 +98,42 @@ func getTodoProgress(todos []TodoItem) (string, bool) {
return "", false
}
+// isPiContext checks if we're running under pi coding agent
+func isPiContext() bool {
+ // Strategy 1: Check immediate parent process
+ ppid := os.Getppid()
+ cmdline := fmt.Sprintf("/proc/%d/comm", ppid)
+ data, err := os.ReadFile(cmdline)
+ if err == nil && strings.TrimSpace(string(data)) == "pi" {
+ return true
+ }
+
+ // Strategy 2: Check if "pi" is anywhere in the process tree
+ // Look at process tree via pstree or ps
+ cmd := exec.Command("sh", "-c", fmt.Sprintf("ps -o comm= -p $(ps -o ppid= -p %d) 2>/dev/null || pstree -s %d 2>/dev/null", ppid, os.Getpid()))
+ output, err := cmd.Output()
+ if err == nil && strings.Contains(string(output), "pi") {
+ return true
+ }
+
+ // Strategy 3: Check PI_* environment variables (if pi sets any in future)
+ if os.Getenv("PI_AGENT") != "" || os.Getenv("PI_CODING_AGENT") != "" {
+ return true
+ }
+
+ return false
+}
+
// buildTitle constructs the terminal title based on available context
func buildTitle(toolResult *ToolResult) string {
var parts []string
+ isPi := isPiContext()
+
+ // Determine prefix (π for pi, Claude for Claude Code)
+ prefix := "Claude"
+ if isPi {
+ prefix = "π"
+ }
// Priority 1: Check for active task from TodoWrite
if toolResult != nil && toolResult.ToolName == "TodoWrite" {
@@ -125,12 +159,17 @@ func buildTitle(toolResult *ToolResult) string {
parts = append(parts, projectName)
}
- // Build final title
- if len(parts) > 0 {
- return fmt.Sprintf("Claude: %s", strings.Join(parts, " • "))
+ // Priority 4: Always add working directory
+ if cwd, err := os.Getwd(); err == nil {
+ parts = append(parts, filepath.Base(cwd))
}
- return "Claude Ready"
+ // Build final title
+ if len(parts) > 0 {
+ return fmt.Sprintf("%s %s", prefix, strings.Join(parts, " • "))
+ }
+
+ return fmt.Sprintf("%s Ready", prefix)
}
func main() {