- 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'
Remove the internal/supervisor Go package and cron-driven orphan check
script. Replace with a single anvillm-supervisor script invoked by cron
that handles both orphan bead recovery (--orphans, every 5m) and idle
worker nudging (--nudge, every 1m). Nudges use send_message.sh as user,
consistent with existing mail processing. anvilsrv no longer runs any
supervisor goroutine.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace dead assignWork() stub with nudgeIdleWorkers(), which sends a
prompt to any session whose role has worker: true in its front-matter
and has been idle for more than 15 seconds. A 15-second ticker drives
the checks. Bots that should be polling for beads will self-correct
after a brief idle period.
Add Worker bool to RoleMeta, parsed from "worker: true" front-matter,
and IsWorker() helper on RolesFS. Remove unused beads/mailbox/eventbus
deps from the supervisor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Claim now rejects anything not in status=open. Dead-assignee takeover
is handled by unclaiming the bead (which fires BeadReady), letting any
waiting bot claim it normally. Removes isAlive/SetSessionLiveness.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
claim now runs in a transaction: reads current status/assignee, allows
claim only if status=open or (status=in_progress and assignee is dead).
Returns ErrAlreadyClaimed if the current assignee is alive.
BeadsFS.SetSessionLiveness wires a func(agentID string) bool from the
session manager so the claim handler can check liveness without importing
the session package.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add EventBeadReady to eventbus, published by BeadsFS on open/reopen/unclaim
- Wire eventbus into BeadsFS via SetEventBus (called after server init)
- Supervisor now reacts to EventStateChange{idle} and EventBeadReady
instead of a 5s ticker; 60s fallback ticker retained for safety
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Every argument in every mcptools script is now a named flag (--mount,
--id, --agent-id, --session-id, --cwd, --child, --repo, --ticket, etc.).
No positional arguments remain. SKILL.md files updated to match.
Also updates cmd/Assist/main.go to pass --cwd flag to mount_beads.sh.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simplify: the optional friendly name parameter is removed. UUID first
segment is always the mount name; mtab provides the path mapping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use readFile() to fetch the script over the existing 9p connection,
then pipe it to bash -s. Removes dependency on the 9p CLI binary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace direct beads/ctl write with mount_beads.sh subprocess call.
UUID-based mount names are now generated by the script; the returned
name is captured and used as windowMount. Optional friendly name is
passed through for display only.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove dead streaming code: reader(), waitForReady(), StartupHandler, pipe-pane
- Switch recovery metadata from session-scoped set-environment to window-scoped set-option -w @key
- Sessions now start in idle state immediately (no startup wait)
- list_beads.sh/list_ready_beads.sh: filter to id,priority,title,status
- Add read_bead_comments.sh tool and Comments view in Assist
- Simplify Assist filters to All/Ready (was 6 status filters)
- Server-side filtering: list excludes closed at DB, ready uses GetReadyWork
- Default limit 100, DB-level filtering
- Atomic blockers= support in new command
- Parse args as JSON string fallback when LLM passes args incorrectly
- Update SKILLS_PROMPT and agent docs to use unquoted args syntax
- Install team-templates under $INSTALL_PATH/Teams instead of hardcoded $HOME/bin/Teams
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- roles/conductor.md: discover roster before planning; adapt workflow
to available roles (dev-only, dev+review, dev+review+test, etc.);
drive iterative cycles; parallelize across multiple same-role bots;
report skipped phases instead of blocking on missing roles
- team-templates/debug: new workflow with conductor+developer+tester;
blocks until all roles are idle before returning
- list format: replace model field with role (field 5) in agent/list;
update Assist, anvillm, anvilwebgw, list_sessions.sh accordingly
- Assist /AnviLLM/: replace Model column with Role in session list
Adds a third execution mode: pipe accepts an ordered array of stages
{tool?, args?, code?} and chains them as a Unix pipeline. Tool stages
are read from 9P (trusted); inline code stages are validated individually
before the pipeline is assembled, so the combined string always runs as
trusted regardless of mix. readTool moved from main.go to execute.go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add 'tool' param to read tool code from 9P namespace
- Add 'args' as array (passed as positional params via set --)
- Tools from 9P skip dangerous pattern validation (trusted)
- Add Go language support
- Update all skills to use tool/args syntax
Reuse the same layered config approach as anvilsrv:
- global.yaml provides base permissions (including /usr, /lib, /bin)
- sandbox/<name>.yaml adds sandbox-specific permissions
- Merge uses most-permissive-wins strategy
This fixes the fallback to default sandbox, which now has proper
system paths from global.yaml.
When sandbox is not explicitly specified, retry with 'default' sandbox
if the initial execution fails with permission denied or missing file errors.
This allows third-party skills designed for execute_bash to work without
modification while preserving isolation when sandbox is explicitly set.
- Add sandbox parameter to execute_code (default: anvilmcp)
- Load sandbox config from ~/.config/anvillm/sandbox/<name>.yaml
- Fallback to ./cfg/sandbox/<name>.yaml for development
- Add cwd config option: 'temp' for isolated workspace, '{CWD}' for caller's dir
- Create cfg/sandbox/anvilmcp.yaml with restricted defaults
- Update cfg/sandbox/default.yaml with cwd: '{CWD}'
Dangerous pattern fixes (bash, not JS/Python):
- Remove curl/wget block (network controlled by landrun)
- Remove chmod 777, eval(), exec() (wrong syntax)
- Allow /etc/passwd (world-readable, needed for user lookups)
- Fix /dev/ write check to only block /dev/sd* (not /dev/null)
- Fix eval pattern for actual bash usage
Update skills with explicit sandbox specifications:
- anvilmcp sandbox for normal operations
- default sandbox for spawn_agent.sh (needs full permissions)
- Add ClearHandler, CompactHandler, ResumeHandler callbacks to tmux.Config
- kiro-cli: clear/resume need 250ms delay + confirmation key
- claude: clear/compact are simple /command[ENTER], resume not implemented
- Add Resume tag and handler to Assist prompt window
- Update server.go to use new Session methods
Add w.Addr("0")/dot=addr/show after content writes in refreshList,
refreshMailboxWindow, refreshDaemonWindow, and refreshViewBeadWindow
so windows no longer scroll to the bottom on open or refresh.
Closes anv-hww
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Changed NewServer to accept *BeadsFS instead of bd.Storage
- BeadsFS is always created but with no initial mounts
- Each mount opens its own store on-demand
- Added nil check in supervisor to handle missing beads gracefully
The beads store was being opened unconditionally at startup, causing
crashes when the database was corrupted or incompatible. Now it's only
opened on-demand when actually needed.
- Add DISPLAY, WAYLAND_DISPLAY, USER to landrun env passthrough
- Mount /etc/passwd read-only for getuser() to work
- Update mcptools scripts to check /etc/shadow instead of /etc/passwd for sandbox detection
- Add mount management UI to all frontends (anvillm TUI, Assist, anvilwebgw, anvillm.el)
- Mount commands default to directory basename if name not specified
- Server validates directory exists before mounting
- Umount accepts either mount name or cwd path
- Fix server bug: all beads operations now use mount-specific store
- Remove currentMount global - all operations require explicit mount parameter
- Each Tasks window tracks its own windowMount independently
- Bead detail windows receive mount from parent window
- When no mounts exist, show instructions to mount a project
- When unmounting current mount, switch to first available or show empty state
- Mount validation: Select command checks mount exists before switching
- Database path: ~/.beads/<cwd-hyphenated> to prevent cross-contamination
- anvilwebgw: init logging in startCmd
- anvilweb: init logging in main
- anvillm: init logging in main
- Assist: init logging in main
Each program now creates its own timestamped log file
- Created internal/logging package with zap logger
- Added panic recovery to anvilsrv main loop, monitor goroutine, and mail processing
- Replaced log.Printf/Fatal with zap in debug, p9, tmux packages
- Fixed beads race condition: clear assignee before closing issue
- All errors and crashes now logged to ~/.config/anvillm/logs
- Include model in session list output (eliminates N+1 reads)
- Add jq error handling in Supervisor dispatch_ready_beads
- Use process substitution in Supervisor to avoid subshell variable scope
- Fix claude backend Execute to return error (commands go through PTY)
- Make createSubtask return childID (eliminates duplicate O(n) scan)
Fixes: bd-1z2, bd-73r, bd-cid, bd-viu, bd-vdi
- anvilsrv sets CLAUDE_CONFIG_DIR to ~/.config/anvillm/claude on start
if not already set in the environment
- Claude backend includes CLAUDE_CONFIG_DIR in its Environment map so
it is set in the tmux session and exported to the shell
- tmux backend now exports all b.cfg.Environment vars to the shell
(via sendKeys) in addition to setting them in the tmux environment,
both on CreateSession and Restart
- cfg/backends/claude.yaml adds CLAUDE_CONFIG_DIR to the sandbox env
whitelist so landrun passes it through to the Claude process
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add inline Put actions for sessions and tasks windows
Introduce a Put command to both the sessions list and tasks windows,
allowing inline edits via prefixed annotations in the body:
Sessions (cmd/Assist/main.go):
- `- <id>` Kill session
- `~ <id>` Stop session (graceful)
- `@ <id> <alias>` Set alias on session
- `+ <backend> <path> [alias]` Start new session
Tasks (cmd/Assist/main.go + internal/p9/beads.go):
- `- [idx]` Delete bead
- `~ [idx]` Claim bead as user
- `^ [idx]` Unclaim bead (clear assignee, reset to open)
- `x [idx]` Complete bead
- `f [idx]` Fail bead
- `+ <title>` Create new bead with title pre-filled
Also adds `unclaim` ctl command to BeadsFS and helper functions:
claimBeadAsUser, unclaimBead, completeBead, failBead,
openNewBeadWindowWithTitle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add [Failed] [PendingReview] [PendingApproval] filters to tasks window
Extends the tasks window filter bar with three new status filters:
- [Failed] closed beads whose close_reason != "completed"
- [PendingReview] beads with status "pending_review"
- [PendingApproval] beads with status "pending_approval"
Implementation details:
- Add CloseReason field (json:"close_reason") to Bead struct so
fail-vs-complete distinction is available after JSON decode.
- listBeadsWithFilter: add "failed" special case (closed beads with
non-"completed" close_reason); "pending_review" and
"pending_approval" fall through the existing status equality path.
- handleTasksWindow: wire Failed/PendingReview/PendingApproval cases
to set statusFilter and refresh the list.
- refreshTasksWindowWithBeads: update filter bar header line.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add bulk-archive via inline Put notation to inbox and archive windows
In the inbox window, lines prefixed with "- <shortID>" are parsed on Put
and each matching message is archived (moved to completed). In the archive
window the same notation permanently deletes the message from the archive.
Adds: parseMailEdits, mailEdit type, deleteArchivedMessage in Assist;
DeleteFromCompleted in mailbox.Manager; "delete <msg-id>" command on
user/ctl in the p9 server.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>