Assist: add Comment tag to leave comments on beads
- Add Comment tag to bead view window tagline
- New /AnviLLM/Tasks/{bead-id}/comment window with Put handler
- Fix comments display: JSON field is 'text' not 'body'
This commit is contained in:
parent
8ddb7f28b9
commit
2d908c6dcd
|
|
@ -2301,7 +2301,7 @@ func openViewBeadWindow(beadID string, mount string) error {
|
|||
}
|
||||
|
||||
w.Name(fmt.Sprintf("/AnviLLM/Tasks/%s", beadID))
|
||||
w.Write("tag", []byte("Get Put New Blocks Comments "))
|
||||
w.Write("tag", []byte("Get Put New Blocks Comments Comment "))
|
||||
|
||||
go handleViewBeadWindow(w, beadID, mount)
|
||||
return nil
|
||||
|
|
@ -2360,6 +2360,10 @@ func handleViewBeadWindow(w *acme.Win, beadID string, mount string) {
|
|||
if err := openCommentsWindow(beadID, mount); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error opening comments window: %v\n", err)
|
||||
}
|
||||
case "Comment":
|
||||
if err := openCommentWindow(beadID, mount); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error opening comment window: %v\n", err)
|
||||
}
|
||||
default:
|
||||
w.WriteEvent(e)
|
||||
}
|
||||
|
|
@ -2429,6 +2433,50 @@ func openCommentsWindow(beadID string, mount string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func openCommentWindow(beadID string, mount string) error {
|
||||
w, err := acme.New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Name(fmt.Sprintf("/AnviLLM/Tasks/%s/comment", beadID))
|
||||
w.Write("tag", []byte("Put "))
|
||||
|
||||
go handleCommentWindow(w, beadID, mount)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleCommentWindow(w *acme.Win, beadID string, mount string) {
|
||||
defer w.CloseFiles()
|
||||
for e := range w.EventChan() {
|
||||
switch e.C2 {
|
||||
case 'x', 'X':
|
||||
if string(e.Text) == "Put" {
|
||||
body, err := w.ReadAll("body")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error reading body: %v\n", err)
|
||||
continue
|
||||
}
|
||||
text := strings.TrimSpace(string(body))
|
||||
if text == "" {
|
||||
continue
|
||||
}
|
||||
cmd := fmt.Sprintf("comment %s '%s'", beadID, text)
|
||||
if err := writeFile(filepath.Join("beads", mount, "ctl"), []byte(cmd)); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error adding comment: %v\n", err)
|
||||
} else {
|
||||
w.Addr(",")
|
||||
w.Write("data", nil)
|
||||
w.Ctl("clean")
|
||||
}
|
||||
} else {
|
||||
w.WriteEvent(e)
|
||||
}
|
||||
default:
|
||||
w.WriteEvent(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleCommentsWindow(w *acme.Win, beadID string, mount string) {
|
||||
defer w.CloseFiles()
|
||||
refreshCommentsWindow(w, beadID, mount)
|
||||
|
|
@ -2458,7 +2506,7 @@ func refreshCommentsWindow(w *acme.Win, beadID string, mount string) {
|
|||
|
||||
var comments []struct {
|
||||
Author string `json:"author"`
|
||||
Body string `json:"body"`
|
||||
Text string `json:"text"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &comments); err != nil {
|
||||
|
|
@ -2473,7 +2521,7 @@ func refreshCommentsWindow(w *acme.Win, beadID string, mount string) {
|
|||
buf.WriteString("No comments.\n")
|
||||
} else {
|
||||
for _, c := range comments {
|
||||
buf.WriteString(fmt.Sprintf("--- %s (%s) ---\n%s\n\n", c.Author, c.CreatedAt, c.Body))
|
||||
buf.WriteString(fmt.Sprintf("--- %s (%s) ---\n%s\n\n", c.Author, c.CreatedAt, c.Text))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"time"
|
||||
|
||||
bd "github.com/steveyegge/beads"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
|
@ -337,7 +338,7 @@ func (b *BeadsFS) Write(path string, data []byte, sessionID string) error {
|
|||
return fmt.Errorf("usage: mount <cwd> [name]")
|
||||
}
|
||||
cwd := args[0]
|
||||
name := filepath.Base(cwd)
|
||||
name := uuid.New().String()[:8]
|
||||
if len(args) >= 2 {
|
||||
name = args[1]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,43 @@
|
|||
#!/bin/bash
|
||||
# Periodic worker health check: orphan bead recovery and idle worker nudging.
|
||||
# Usage: anvillm-worker-check [--orphans] [--nudge]
|
||||
# Periodic worker health check: orphan bead recovery, idle worker nudging, auto-mount.
|
||||
# Usage: anvillm-supervisor [--orphans] [--nudge] [--auto-mount <workdir>]
|
||||
set -euo pipefail
|
||||
|
||||
LOG_PREFIX="[worker-check $(date '+%Y-%m-%d %H:%M:%S')]"
|
||||
LOG_PREFIX="[supervisor $(date '+%Y-%m-%d %H:%M:%S')]"
|
||||
log() { echo "$LOG_PREFIX $*"; }
|
||||
|
||||
DO_ORPHANS=0
|
||||
DO_NUDGE=0
|
||||
AUTO_MOUNT_DIR=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--orphans) DO_ORPHANS=1; shift ;;
|
||||
--nudge) DO_NUDGE=1; shift ;;
|
||||
--auto-mount) AUTO_MOUNT_DIR="$2"; shift 2 ;;
|
||||
*) echo "unknown argument: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$DO_ORPHANS" -eq 0 ] && [ "$DO_NUDGE" -eq 0 ]; then
|
||||
echo "usage: anvillm-worker-check [--orphans] [--nudge]" >&2
|
||||
if [ "$DO_ORPHANS" -eq 0 ] && [ "$DO_NUDGE" -eq 0 ] && [ -z "$AUTO_MOUNT_DIR" ]; then
|
||||
echo "usage: anvillm-supervisor [--orphans] [--nudge] [--auto-mount <workdir>]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Auto-mount beads for workdir ---
|
||||
if [ -n "$AUTO_MOUNT_DIR" ]; then
|
||||
MTAB=$(9p read anvillm/beads/mtab 2>/dev/null || true)
|
||||
EXISTING=$(echo "$MTAB" | awk -F'\t' -v dir="$AUTO_MOUNT_DIR" '$2 == dir {print $1; exit}')
|
||||
if [ -n "$EXISTING" ]; then
|
||||
echo "error: already mounted as $EXISTING" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "mount $AUTO_MOUNT_DIR" | 9p write anvillm/beads/ctl
|
||||
# Read back the mount name from mtab
|
||||
9p read anvillm/beads/mtab 2>/dev/null | awk -F'\t' -v dir="$AUTO_MOUNT_DIR" '$2 == dir {print $1; exit}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
SESSIONS=$(9p read anvillm/list 2>/dev/null || true)
|
||||
|
||||
# --- Orphan recovery ---
|
||||
|
|
|
|||
Reference in New Issue