From 6ea87e1810285c0e8b199855667ab454da024f52 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Sat, 14 Mar 2026 21:21:25 +0100 Subject: [PATCH] Assist: remap bead prefixes, add open/defer; orphan: skip user-claimed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tasks window Put handler prefix changes: ~ → c (claim) ^ → u (unclaim) o (open/promote deferred) d (defer) x, f, -, + unchanged Orphan check now skips beads claimed by "user" — human-held beads are not orphans. Co-Authored-By: Claude Sonnet 4.6 --- cmd/Assist/main.go | 42 ++++++++++++++++++++++++++++++++---- scripts/anvillm-orphan-check | 4 ++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/cmd/Assist/main.go b/cmd/Assist/main.go index fa9bee7..ff5cd7e 100644 --- a/cmd/Assist/main.go +++ b/cmd/Assist/main.go @@ -1838,8 +1838,10 @@ type beadEdit struct { // Recognized prefixes (by 1-based index shown in the list): // // - [idx] Delete bead at that index -// ~ [idx] Claim bead at that index (assign to user) -// ^ [idx] Unclaim bead: clear assignee, reset status to open +// c [idx] Claim bead at that index (assign to user) +// u [idx] Unclaim bead: clear assignee, reset status to open +// o [idx] Open (promote deferred bead to ready) +// d [idx] Defer bead // x [idx] Close/complete bead at that index // f [idx] Fail bead at that index with reason 'user-closed' // + [title] Create new bead with that title @@ -1856,16 +1858,26 @@ func parseBeadEdits(content string, beads []Bead) []beadEdit { if idx := parseIndex(rest); idx > 0 && idx <= len(beads) { edits = append(edits, beadEdit{action: "delete", beadID: beads[idx-1].ID}) } - case strings.HasPrefix(line, "~ "): + case strings.HasPrefix(line, "c "): rest := strings.TrimSpace(line[2:]) if idx := parseIndex(rest); idx > 0 && idx <= len(beads) { edits = append(edits, beadEdit{action: "claim", beadID: beads[idx-1].ID}) } - case strings.HasPrefix(line, "^ "): + case strings.HasPrefix(line, "u "): rest := strings.TrimSpace(line[2:]) if idx := parseIndex(rest); idx > 0 && idx <= len(beads) { edits = append(edits, beadEdit{action: "unclaim", beadID: beads[idx-1].ID}) } + case strings.HasPrefix(line, "o "): + rest := strings.TrimSpace(line[2:]) + if idx := parseIndex(rest); idx > 0 && idx <= len(beads) { + edits = append(edits, beadEdit{action: "open", beadID: beads[idx-1].ID}) + } + case strings.HasPrefix(line, "d "): + rest := strings.TrimSpace(line[2:]) + if idx := parseIndex(rest); idx > 0 && idx <= len(beads) { + edits = append(edits, beadEdit{action: "defer", beadID: beads[idx-1].ID}) + } case strings.HasPrefix(line, "x "): rest := strings.TrimSpace(line[2:]) if idx := parseIndex(rest); idx > 0 && idx <= len(beads) { @@ -1907,6 +1919,14 @@ func applyBeadEdits(w *acme.Win, edits []beadEdit, beads *[]Bead, filter string, if err := unclaimBead(edit.beadID, mount); err != nil { errs = append(errs, fmt.Sprintf("unclaim %s: %v", edit.beadID, err)) } + case "open": + if err := openBead(edit.beadID, mount); err != nil { + errs = append(errs, fmt.Sprintf("open %s: %v", edit.beadID, err)) + } + case "defer": + if err := deferBead(edit.beadID, mount); err != nil { + errs = append(errs, fmt.Sprintf("defer %s: %v", edit.beadID, err)) + } case "complete": if err := completeBead(edit.beadID, mount); err != nil { errs = append(errs, fmt.Sprintf("complete %s: %v", edit.beadID, err)) @@ -2537,6 +2557,20 @@ func failBead(beadID, reason string, mount string) error { return writeFile(filepath.Join("beads", mount, "ctl"), []byte(fmt.Sprintf("fail %s %s", beadID, reason))) } +func openBead(beadID string, mount string) error { + if !isConnected() { + return fmt.Errorf("not connected to anvilsrv") + } + return writeFile(filepath.Join("beads", mount, "ctl"), []byte(fmt.Sprintf("open %s", beadID))) +} + +func deferBead(beadID string, mount string) error { + if !isConnected() { + return fmt.Errorf("not connected to anvilsrv") + } + return writeFile(filepath.Join("beads", mount, "ctl"), []byte(fmt.Sprintf("defer %s", beadID))) +} + func updateBead(beadID, content string, origBlockers []string, mount string) error { content = strings.TrimSpace(content) if !strings.HasPrefix(content, "---") { diff --git a/scripts/anvillm-orphan-check b/scripts/anvillm-orphan-check index c62c3f1..8527734 100644 --- a/scripts/anvillm-orphan-check +++ b/scripts/anvillm-orphan-check @@ -29,6 +29,10 @@ while IFS=$'\t' read -r MOUNT CWD; do while IFS=$'\t' read -r BEAD_ID ASSIGNEE; do [ -z "$BEAD_ID" ] && continue + # Skip if claimed by user (human in the loop — not an orphan) + [ "$ASSIGNEE" = "user" ] && continue + + # Skip if assignee session is still alive if [ -n "$ASSIGNEE" ] && echo "$LIVE_SESSIONS" | grep -qx "$ASSIGNEE"; then continue fi