feat: free-form sessions, rename/end from the panel, live Claude Context (0.2.0)
- Sessions no longer need a project folder: any name works and starts in DEVDESK_DEFAULT_DIR unless it matches a project; `devdesk new NAME [PROJECT]`. - Rename (✎) and end/forget (×) sessions from the Sessions panel, plus `devdesk rename`. The browser runs them as `devdesk attach --new|--rename|--end` through ttyd. Renames keep the running Claude and its recorded conversation: the hook, the run-wrapper and the statusline ask tmux for the current name. - Claude Context panel is live: devdesk-statusline snapshots model, context-window use, cost and edits per session, which --list reports; Claude's footer gets a one-line summary. The panel now sits under Sessions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+45
-18
@@ -11,6 +11,7 @@ if [ -r "$DEVDESK_ENV" ]; then
|
||||
fi
|
||||
|
||||
: "${DEVDESK_PROJECTS_ROOT:=/root/code}"
|
||||
: "${DEVDESK_DEFAULT_DIR:=$DEVDESK_PROJECTS_ROOT}"
|
||||
: "${DEVDESK_DEFAULT_SESSION:=main}"
|
||||
: "${DEVDESK_SOCKET:=/run/devdesk/tmux.sock}"
|
||||
: "${DEVDESK_STATE_DIR:=/var/lib/devdesk}"
|
||||
@@ -19,6 +20,7 @@ fi
|
||||
: "${DEVDESK_TMUX_UNIT:=devdesk-tmux.service}"
|
||||
|
||||
DEVDESK_REGISTRY="$DEVDESK_STATE_DIR/registry.json"
|
||||
DEVDESK_CONTEXT_DIR="$DEVDESK_STATE_DIR/context"
|
||||
DEVDESK_NAME_RE='^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$'
|
||||
|
||||
dd_die() {
|
||||
@@ -99,29 +101,30 @@ dd_registry_set_claude() {
|
||||
|
||||
dd_registry_remove() {
|
||||
dd_registry_update 'del(.sessions[$n])' --arg n "$1"
|
||||
rm -f "$DEVDESK_CONTEXT_DIR/$1.json"
|
||||
}
|
||||
|
||||
# Session name -> absolute project directory (must resolve inside the projects root).
|
||||
dd_resolve_dir() {
|
||||
dd_registry_rename() {
|
||||
dd_registry_update 'if .sessions[$old] then .sessions[$new] = .sessions[$old] | del(.sessions[$old]) else . end' \
|
||||
--arg old "$1" --arg new "$2"
|
||||
if [ -f "$DEVDESK_CONTEXT_DIR/$1.json" ]; then
|
||||
mv -f "$DEVDESK_CONTEXT_DIR/$1.json" "$DEVDESK_CONTEXT_DIR/$2.json"
|
||||
fi
|
||||
}
|
||||
|
||||
# Project name (directory or its slug) -> absolute directory inside the projects root.
|
||||
dd_project_dir() {
|
||||
local name=$1 dir="" d root
|
||||
if [ "$name" = "$DEVDESK_DEFAULT_SESSION" ]; then
|
||||
dir=$DEVDESK_PROJECTS_ROOT
|
||||
if [ -d "$DEVDESK_PROJECTS_ROOT/$name" ]; then
|
||||
dir="$DEVDESK_PROJECTS_ROOT/$name"
|
||||
else
|
||||
dir=$(dd_registry_get "$name" dir)
|
||||
if [ -z "$dir" ] || [ ! -d "$dir" ]; then
|
||||
dir=""
|
||||
if [ -d "$DEVDESK_PROJECTS_ROOT/$name" ]; then
|
||||
dir="$DEVDESK_PROJECTS_ROOT/$name"
|
||||
else
|
||||
for d in "$DEVDESK_PROJECTS_ROOT"/*/; do
|
||||
d=${d%/}
|
||||
if [ "$(dd_slugify "${d##*/}")" = "$name" ]; then
|
||||
dir=$d
|
||||
break
|
||||
fi
|
||||
done
|
||||
for d in "$DEVDESK_PROJECTS_ROOT"/*/; do
|
||||
d=${d%/}
|
||||
if [ "$(dd_slugify "${d##*/}")" = "$name" ]; then
|
||||
dir=$d
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
[ -n "$dir" ] || return 1
|
||||
dir=$(realpath -e -- "$dir" 2>/dev/null) || return 1
|
||||
@@ -132,6 +135,30 @@ dd_resolve_dir() {
|
||||
esac
|
||||
}
|
||||
|
||||
# Session name -> working directory. Sessions don't need a project: the
|
||||
# registry wins, then a project of the same name, then DEVDESK_DEFAULT_DIR.
|
||||
dd_resolve_dir() {
|
||||
local name=$1 dir
|
||||
dir=$(dd_registry_get "$name" dir)
|
||||
if [ -n "$dir" ] && [ -d "$dir" ]; then
|
||||
printf '%s\n' "$dir"
|
||||
elif [ "$name" != "$DEVDESK_DEFAULT_SESSION" ] && dir=$(dd_project_dir "$name"); then
|
||||
printf '%s\n' "$dir"
|
||||
else
|
||||
realpath -e -- "$DEVDESK_DEFAULT_DIR" 2>/dev/null || printf '%s\n' "$HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
# Name of the DevDesk session this process runs in. Asks tmux, so it stays
|
||||
# right after a rename; falls back to the DEVDESK_SESSION set at creation.
|
||||
dd_current_session() {
|
||||
local name=""
|
||||
if [ -n "${TMUX:-}" ] && [ -n "${TMUX_PANE:-}" ]; then
|
||||
name=$(tmux display-message -p -t "$TMUX_PANE" '#S' 2>/dev/null)
|
||||
fi
|
||||
printf '%s\n' "${name:-${DEVDESK_SESSION:-}}"
|
||||
}
|
||||
|
||||
# Arguments for `tmux new-session` that create session NAME in DIR running Claude.
|
||||
dd_new_session_args() {
|
||||
printf '%s\0' -s "$1" -c "$2" -n claude -e "DEVDESK_SESSION=$1" "$DEVDESK_LIBEXEC/devdesk-claude-run"
|
||||
|
||||
Reference in New Issue
Block a user