Preserve holistic multiplexer titles
This commit is contained in:
@@ -3,16 +3,18 @@
|
|||||||
## Multiplexer session titling
|
## Multiplexer session titling
|
||||||
- If the `TMUX` or `ZELLIJ` environment variable is set, treat this chat as the controller for the current tmux or zellij session.
|
- If the `TMUX` or `ZELLIJ` environment variable is set, treat this chat as the controller for the current tmux or zellij session.
|
||||||
- Use `set_multiplexer_title '<project> - <task>'` to update the title. The command detects tmux vs. zellij internally, prefers tmux when both are present, and no-ops outside a multiplexer.
|
- Use `set_multiplexer_title '<project> - <task>'` to update the title. The command detects tmux vs. zellij internally, prefers tmux when both are present, and no-ops outside a multiplexer.
|
||||||
- Maintain a session/window/pane title that updates when the task focus changes substantially.
|
- Maintain a session/window/pane title that describes the durable purpose of the overall exchange.
|
||||||
- Prefer automatic titling: infer a concise <task> from the current user request and context without asking.
|
- Prefer automatic titling: infer a concise <task> from the current user request and the existing chat context without asking.
|
||||||
|
- Choose holistic titles over granular turn summaries. The title should answer "what has this chat been for?" rather than describe the latest command, substep, clarification, or follow-up message.
|
||||||
|
- Preserve the existing <task> when the new user turn is a continuation, status check, refinement, or implementation detail within the same broader objective.
|
||||||
- Title format: "<project> - <task>".
|
- Title format: "<project> - <task>".
|
||||||
- <project> is the basename of the current project directory.
|
- <project> is the basename of the current project directory.
|
||||||
- Prefer git repo root basename if available; otherwise use basename of the current working directory.
|
- Prefer git repo root basename if available; otherwise use basename of the current working directory.
|
||||||
- <task> is a short, user-friendly description of what we are doing.
|
- <task> is a short, user-friendly description of what we are doing.
|
||||||
- Ask for a short descriptive <task> only when the task is ambiguous or you are not confident in an inferred title.
|
- Ask for a short descriptive <task> only when the task is ambiguous or you are not confident in an inferred title.
|
||||||
- When the task changes substantially, update the <task> automatically if clear; otherwise ask for an updated <task>.
|
- When the broader objective changes substantially, update the <task> automatically if clear; otherwise ask for an updated <task>.
|
||||||
- When a title is provided or updated, immediately run `set_multiplexer_title '<project> - <task>'`; do not call raw tmux or zellij rename commands unless debugging the helper itself.
|
- When a title is provided or updated, immediately run `set_multiplexer_title '<project> - <task>'`; do not call raw tmux or zellij rename commands unless debugging the helper itself.
|
||||||
- For Claude Code sessions, a UserPromptSubmit hook will also update titles automatically based on the latest prompt.
|
- For Claude Code sessions, a UserPromptSubmit hook may initialize titles automatically from the first substantive prompt, but it should not keep overwriting an established same-project title with the latest prompt.
|
||||||
|
|
||||||
## Pane usage
|
## Pane usage
|
||||||
- Do not create extra panes or windows unless the user asks.
|
- Do not create extra panes or windows unless the user asks.
|
||||||
|
|||||||
@@ -16,10 +16,13 @@ sys.stdout.write(cwd)
|
|||||||
sys.stdout.write("\0")
|
sys.stdout.write("\0")
|
||||||
sys.stdout.write(prompt)
|
sys.stdout.write(prompt)
|
||||||
sys.stdout.write("\0")
|
sys.stdout.write("\0")
|
||||||
|
sys.stdout.write(str(data.get("session_id") or ""))
|
||||||
|
sys.stdout.write("\0")
|
||||||
PY
|
PY
|
||||||
)
|
)
|
||||||
cwd="${parsed[0]:-}"
|
cwd="${parsed[0]:-}"
|
||||||
prompt="${parsed[1]:-}"
|
prompt="${parsed[1]:-}"
|
||||||
|
session_id="${parsed[2]:-}"
|
||||||
|
|
||||||
if [[ -z "${cwd}" ]]; then
|
if [[ -z "${cwd}" ]]; then
|
||||||
cwd="$PWD"
|
cwd="$PWD"
|
||||||
@@ -46,6 +49,17 @@ if [[ -z "$task" ]]; then
|
|||||||
task="work"
|
task="work"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
explicit_retitle=false
|
||||||
|
case "$lower" in
|
||||||
|
"new task:"*|"new topic:"*|"switch topic:"*|"switch context:"*|"rename title:"*|"title:"*)
|
||||||
|
explicit_retitle=true
|
||||||
|
task=$(printf '%s' "$prompt_first_line" | sed -E 's/^[^:]+:[[:space:]]*//')
|
||||||
|
if [[ -z "$task" ]]; then
|
||||||
|
task="work"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Trim to a reasonable length for multiplexer UI labels.
|
# Trim to a reasonable length for multiplexer UI labels.
|
||||||
if [[ ${#task} -gt 60 ]]; then
|
if [[ ${#task} -gt 60 ]]; then
|
||||||
task="${task:0:57}..."
|
task="${task:0:57}..."
|
||||||
@@ -53,9 +67,42 @@ fi
|
|||||||
|
|
||||||
title="$project - $task"
|
title="$project - $task"
|
||||||
|
|
||||||
|
# The hook only sees the newest prompt, not the full conversation. Avoid
|
||||||
|
# degrading a useful same-project title into a granular follow-up summary.
|
||||||
|
if [[ -n "${TMUX:-}" ]]; then
|
||||||
|
multiplexer="tmux"
|
||||||
|
elif [[ -n "${ZELLIJ:-}" ]]; then
|
||||||
|
multiplexer="zellij"
|
||||||
|
else
|
||||||
|
multiplexer=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
hook_state_file=""
|
||||||
|
if [[ -n "$multiplexer" ]]; then
|
||||||
|
state_dir="${HOME}/.agents/state"
|
||||||
|
if [[ -n "$session_id" ]]; then
|
||||||
|
safe_session_id=$(printf '%s' "$session_id" | tr -c '[:alnum:]_.-' '_')
|
||||||
|
hook_state_file="${state_dir}/${multiplexer}-title-hook-${safe_session_id}"
|
||||||
|
else
|
||||||
|
hook_state_file="${state_dir}/${multiplexer}-title"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$hook_state_file" ]]; then
|
||||||
|
established_title=$(cat "$hook_state_file" 2>/dev/null || true)
|
||||||
|
if [[ "$established_title" == "$project - "* && "$established_title" != "$title" && "$explicit_retitle" != true ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if command -v set_multiplexer_title >/dev/null 2>&1; then
|
if command -v set_multiplexer_title >/dev/null 2>&1; then
|
||||||
set_multiplexer_title "$title"
|
set_multiplexer_title "$title"
|
||||||
else
|
else
|
||||||
hook_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
hook_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||||
"$hook_dir/../../lib/functions/set_multiplexer_title" "$title"
|
"$hook_dir/../../lib/functions/set_multiplexer_title" "$title"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$hook_state_file" ]]; then
|
||||||
|
mkdir -p "$(dirname "$hook_state_file")"
|
||||||
|
printf '%s' "$title" > "$hook_state_file"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -7,14 +7,16 @@
|
|||||||
## Multiplexer session titling
|
## Multiplexer session titling
|
||||||
- If the `TMUX` or `ZELLIJ` environment variable is set, treat this chat as the controller for the current tmux or zellij session.
|
- If the `TMUX` or `ZELLIJ` environment variable is set, treat this chat as the controller for the current tmux or zellij session.
|
||||||
- Use `set_multiplexer_title '<project> - <task>'` to update the title. The command detects tmux vs. zellij internally, prefers tmux when both are present, and no-ops outside a multiplexer.
|
- Use `set_multiplexer_title '<project> - <task>'` to update the title. The command detects tmux vs. zellij internally, prefers tmux when both are present, and no-ops outside a multiplexer.
|
||||||
- Maintain a session/window/pane title that updates when the task focus changes substantially.
|
- Maintain a session/window/pane title that describes the durable purpose of the overall exchange.
|
||||||
- Prefer automatic titling: infer a concise <task> from the current user request and context without asking.
|
- Prefer automatic titling: infer a concise <task> from the current user request and the existing chat context without asking.
|
||||||
|
- Choose holistic titles over granular turn summaries. The title should answer "what has this chat been for?" rather than describe the latest command, substep, clarification, or follow-up message.
|
||||||
|
- Preserve the existing <task> when the new user turn is a continuation, status check, refinement, or implementation detail within the same broader objective.
|
||||||
- Title format: "<project> - <task>".
|
- Title format: "<project> - <task>".
|
||||||
- <project> is the basename of the current project directory.
|
- <project> is the basename of the current project directory.
|
||||||
- Prefer git repo root basename if available; otherwise use basename of the current working directory.
|
- Prefer git repo root basename if available; otherwise use basename of the current working directory.
|
||||||
- <task> is a short, user-friendly description of what we are doing.
|
- <task> is a short, user-friendly description of what we are doing.
|
||||||
- Ask for a short descriptive <task> only when the task is ambiguous or you are not confident in an inferred title.
|
- Ask for a short descriptive <task> only when the task is ambiguous or you are not confident in an inferred title.
|
||||||
- When the task changes substantially, update the <task> automatically if clear; otherwise ask for an updated <task>.
|
- When the broader objective changes substantially, update the <task> automatically if clear; otherwise ask for an updated <task>.
|
||||||
- When a title is provided or updated, immediately run `set_multiplexer_title '<project> - <task>'`; do not call raw tmux or zellij rename commands unless debugging the helper itself.
|
- When a title is provided or updated, immediately run `set_multiplexer_title '<project> - <task>'`; do not call raw tmux or zellij rename commands unless debugging the helper itself.
|
||||||
|
|
||||||
## Pane usage
|
## Pane usage
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Low-level setter only. Callers should pass a holistic, conversation-level
|
||||||
|
# title; this helper intentionally does not infer titles from prompts.
|
||||||
set_multiplexer_title() {
|
set_multiplexer_title() {
|
||||||
if [ "$#" -lt 1 ]; then
|
if [ "$#" -lt 1 ]; then
|
||||||
echo "usage: set_multiplexer_title <title>" >&2
|
echo "usage: set_multiplexer_title <title>" >&2
|
||||||
|
|||||||
Reference in New Issue
Block a user