Assist: remap bead prefixes, add open/defer; orphan: skip user-claimed

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 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-14 21:21:25 +01:00
parent 9b8d7fba0c
commit 6ea87e1810
2 changed files with 42 additions and 4 deletions

View File

@ -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, "---") {

View File

@ -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