feat: v0.10.0 quieter Matrix, worktrees, usage pace, repo diffs, copy reply, turn timer, compact
build-deb / Notify on failure (push) Successful in 4s
build-deb / Lint, test, package (push) Failing after 2m22s
build-deb / Deploy to CT 126 (push) Skipped

- Matrix "needs you": ignore Claude's idle reminder (no red, no post); post
  only when no tab is in view, after 60 s, once per session per 10 min, and
  say what is asked. Closes #50
- devdesk new NAME PROJECT --worktree: own checkout on devdesk/NAME,
  cleaned up on end when clean/merged. Closes #44
- Usage meters: reset time, pace warning; Matrix ping past 90% when away.
  Closes #45
- Repo panel lists changed files; click opens the diff. Closes #46
- Copy Claude's last reply (--last-reply). Closes #47
- Turn timer in chip, title and cards. Closes #48
- Compact button at 80% context when idle. Closes #49

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHRLCCdXYm41Qx5kNhehaP
This commit is contained in:
2026-10-11 23:28:11 -04:00
co-authored by Claude Opus 5.5
parent bf8821f3f9
commit a2edec966a
17 changed files with 556 additions and 78 deletions
+21
View File
@@ -111,3 +111,24 @@ cmd_reply() {
rm -f "$tmp"
trap - HUP INT TERM
}
# --last-reply SESSION (devdesk#47): Claude's whole answer to your last message,
# every text part of it (between tool calls), as the Markdown Claude wrote.
cmd_last_reply() {
[ $# -eq 1 ] || dd_die "usage: devdesk attach --last-reply SESSION"
local session=$1 transcript
dd_valid_name "$session" || dd_die "invalid session name: $session"
transcript=$(dd_transcript "$session") || transcript=""
{ [ -n "$transcript" ] && [ -r "$transcript" ]; } || dd_die "no conversation recorded for '$session' yet"
tail -n 3000 -- "$transcript" | jq -cMs --arg s "$session" '
def text: if type == "string" then . else ([.[]? | select(.type == "text") | .text] | join("\n")) end;
[.[] | select(.isSidechain != true and .isMeta != true)] as $all
# Your last message: a user entry with text of its own, not a tool result.
| ([range(0; $all | length) | select($all[.] as $e | $e.type == "user"
and ($e.message.content | type == "string" or any(.[]?; .type == "text"))
and ($e.message.content | text | startswith("<") | not))] | last // -1) as $u
| [$all[($u + 1):][] | select(.type == "assistant") | .message.content | text | select(length > 0)] as $parts
| if ($parts | length) == 0 then {session: $s, text: null}
else {session: $s, text: ($parts | join("\n\n")), at: ([$all[] | select(.type == "assistant")] | last | .timestamp)} end' 2>/dev/null ||
dd_die "could not read the conversation of '$session'"
}