Commit Graph

148 Commits

Author SHA1 Message Date
Levi Neely fc6cca01a8 Remove Go language support from execute_code (go run lacks stdin)
Keep code extensible for future language support.
2026-03-06 14:15:51 +01:00
Levi Neely 9643a9a034 Flatten tools 9P, restore SKILLS_PROMPT, remove role/tool discovery
- Flatten agent/tools/ to serve tools directly (no capability subdirs)
- Restore SKILLS_PROMPT.md with proactive skill discovery
- Remove discover_role.sh and discover_tool.sh
- Remove help endpoint from roles and tools
- Update all SKILL.md files to use flat tool paths
- Clear agent prompt in anvillm-agent.json
2026-03-06 13:43:57 +01:00
Levi Neely 57cd96fc6c supervisor: require claimable label for bead assignment 2026-03-06 10:21:24 +01:00
Levi Neely b21c56b960 anvilmcp: use layered sandbox config from sandbox package
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.
2026-03-06 10:18:31 +01:00
Levi Neely b51bbf7e72 working on a different approach for roles 2026-03-06 08:54:44 +01:00
Levi Neely ec880544df fix skill prompt commands 2026-03-05 22:31:21 +01:00
Levi Neely d0c596dcaa Add mail_history.sh script for parsing agent message history 2026-03-05 17:08:55 +01:00
Levi Neely 6475b9f216 Add maildir messaging support for agent communication 2026-03-05 14:33:47 +01:00
Levi Neely c0d09125ca Add backend-specific handlers for clear, compact, resume commands
- 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
2026-03-05 09:41:05 +01:00
Levi Neely e3a63dedd8 tmux backend and p9 server improvements 2026-03-05 09:32:07 +01:00
Levi Neely 948e23156a refine skills prompt 2026-03-04 22:07:24 +01:00
Levi Neely 485016127d Add roles 9P endpoint to server and support multiple tool directories
- Wire up roles filesystem in server.go
- Add /agent/roles directory with focus areas and help
- Support ANVILLM_TOOLS_DIR env var for multiple tool directories
- Update pcloudcc-testing skill documentation
2026-03-04 21:15:23 +01:00
Levi Neely 65e5081134 Use physical filenames in roles 9P endpoint
- Add DisplayName field to RoleMeta for frontmatter name
- Name field now always contains physical filename (never overwritten)
- Use physical filename for 9P paths and deduplication
- Use DisplayName in help output for discovery
- Add unique filtering (sort -u) to discover_role/skill/tool scripts
2026-03-04 21:14:42 +01:00
Levi Neely d0e3ff2cd8 Rename role to sandbox in layered sandbox config
- cfg/roles/ → cfg/sandbox/
- DefaultRole → DefaultSandbox, LoadRole → LoadSandbox
- SessionOptions.Role → Sandbox, Session.Role() → Sandbox()
- p9 file: role → sandbox
- Remove tasks from layered sandbox config
- Update create_session.sh and SKILL.md docs
2026-03-04 13:10:10 +01:00
Levi Neely 12d446d748 Add comment_count field to bead list and json outputs
- Add CommentCount field to BeadWithBlockers struct in readListFromStore and readBeadPropertyFromStore
- Call GetIssueComments to populate comment count when > 0
- Update beads skill documentation to guide checking comment_count and reading comments for additional context
2026-03-03 11:05:08 +01:00
Levi Neely bde53a7389 perf: reduce mail idle guard from 15s to 5s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 16:51:34 +01:00
Levi Neely 2c32295094 fix: inject session context into first prompt only
Context was prepended to every Send() call. Now it is consumed
on the first Send() and cleared, acting as a one-shot spawn
initialization rather than a per-prompt overhead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 16:49:22 +01:00
Levi Neely ba5fd04025 fix: make beads mount work with lazy initialization
- 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
2026-03-01 00:47:13 +01:00
Levi Neely cb77f3d3f2 Fix supervisor task assignment: only assign when session CWD is exactly or under task mountpoint 2026-03-01 00:15:18 +01:00
Levi Neely 04d3616819 fix: require mount parameter for all bead tools
- Add mount param to github_to_beads.sh, jira_to_beads.sh, batch_create_beads.sh, sync_beads.sh
- Update all 9p paths to use mount-specific paths (agent/beads/<mount>/...)
- Fix SKILLS_PROMPT.md to correctly document mount requirements
- Only exceptions: mount_beads.sh, umount_beads.sh, list_mounts.sh
2026-02-28 23:40:24 +01:00
Levi Neely 495136c70c Remove BeadsFS.store field, fix subtask creation to use mounted project stores 2026-02-28 22:52:14 +01:00
Levi Neely 7db743483b Fix recursive bead directory structure in 9P filesystem
- Distinguish control files from bead IDs in mount walk logic
- Add bead directories to mount listings via Read(mountName/list)
- Verify mount exists before allowing walk into it
- Add encoding/json import to server.go
2026-02-28 22:15:55 +01:00
Levi Neely 5e36e672a9 fix: remove broken check blocking beads/ctl writes when mounts exist 2026-02-28 21:55:25 +01:00
Levi Neely afe13afba2 Fix 9p tool access in execute_code sandbox
- 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
2026-02-28 20:49:42 +01:00
Levi Neely 8a5d9e8518 Allow bot assignment for subdirectories of project mount 2026-02-28 18:43:21 +01:00
Levi Neely 95efd907fb Add frontend support for mountable beads and remove global mount state
- 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
2026-02-28 13:35:46 +01:00
Levi Neely 1e3623920e Add mountable beads projects with per-project databases
- Mount projects: echo "mount /path/to/project name" | 9p write agent/beads/ctl
- Unmount: echo "umount name" | 9p write agent/beads/ctl
- All beads endpoints work in mounts (list, ready, pending, blocked, etc.)
- Add agent/beads/mtab for mount discovery (mount→cwd mappings)
- Store databases at ~/.beads/<cwd-hyphenated> to prevent cross-contamination
- Supervisor auto-assigns claimable beads to idle bots with matching cwd
- Fix supervisor duplicate messages (track assigned beads, filter by assignee)
- Update beads skill with mtab discovery pattern
- Fix race conditions and add proper locking for mount access
2026-02-28 11:35:19 +01:00
Levi Neely 425fa53877 Update beads and p9 implementation 2026-02-27 21:16:03 +01:00
Levi Neely cbace3407c Update changes 2026-02-27 12:12:08 +01:00
Levi Neely 521f785313 Use timestamped log files: ~/.config/anvillm/logs/<timestamp>-<progname>.log 2026-02-27 11:48:35 +01:00
Levi Neely 2111f19e9f Add zap logging to ~/.config/anvillm/logs with panic recovery
- 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
2026-02-27 11:46:49 +01:00
Levi Neely 1f42297107 Fix skills help path: prepend 'agent/' when reading /skills/ paths 2026-02-26 23:51:41 +01:00
Levi Neely 5b567ba5b3 Fix all linting issues in internal/p9
- Replace interface{} with any
- Use strings.CutPrefix instead of HasPrefix+TrimPrefix
- Use strings.SplitSeq for efficiency
- Use slices.Contains instead of manual loops
- Use tagged switches for clarity
- Remove debug logging
2026-02-26 23:12:15 +01:00
Levi Neely 83c9136bdf fix: p9 unused parameter and containsBdRef bounds check 2026-02-26 22:58:32 +01:00
Levi Neely e064f926bf fix: p9 race condition, duplicate handlers, bounds checks, path validation 2026-02-26 22:56:58 +01:00
Levi Neely ccc80eabc7 fix: path inconsistency in skills.go and race conditions in server.go 2026-02-26 22:53:09 +01:00
Levi Neely 631c9fb47e Fix race conditions and path traversal bugs in internal/p9
- Fix race in open(): hold lock during fid modification
- Fix race in write(): copy path before unlock
- Fix race in remove(): read sessionID under lock
- Fix panic in walk(): guard empty qids slice
- Fix sessionID tracking: always update to current session
- Fix path traversal in skills.go: use filepath.Clean + bounds check
- Fix path traversal in tools.go: use filepath.Clean + separator check
- Fix repeated array access in beads.go: extract beadID variable
2026-02-26 22:40:56 +01:00
Levi Neely 2b5e739014 fix: resolve 6 bugs in internal/p9
- Fix race condition in server.go defer cleanup
- Add nil check after GetIssue in beads.go
- Replace strings.Trim with TrimPrefix to fix path traversal (beads.go, skills.go, tools.go)
- Remove unused role parameter in readReady
- Use RLock instead of Lock in read operation
- Add error check for os.Getwd
2026-02-26 22:34:43 +01:00
Levi Neely addcf0a978 Fix crash bugs: remove impossible nil checks, add bounds check for strings.Fields
- mailManager guaranteed non-nil by constructor, removed defensive checks
- Added bounds check for strings.Fields()[0] in slash command validation
- Removed impossible nil check in processMailboxes()
2026-02-26 22:28:16 +01:00
Levi Neely a6b85b6970 skills: add uncategorized intent for skills without intents 2026-02-26 15:08:03 +01:00
Levi Neely 031de8e240 p9: intent-based skills discovery
- Add SkillsFS with intent-based virtual directories
- /skills/help aggregated index: intent/skill-name<tab>description
- Parse YAML front-matter for intent: field
- Add intent: to all existing skills
2026-02-26 14:56:00 +01:00
Levi Neely 8a55b99864 p9: capability-based tools discovery
- Add front-matter parsing for capabilities/description in tool scripts
- Virtual capability directories: tools appear in multiple caps
- /tools/help aggregated one-liner index
- Update walk/readDir for /tools/<capability>/<tool.sh> paths
2026-02-26 14:36:30 +01:00
Levi Neely 5f8c41b576
Implement MCP code execution pattern (#20)
* Implement MCP code execution pattern

- Add execute_code tool for bash execution in landrun sandbox
- Remove redundant MCP tools (read_inbox, send_message, etc.)
- Implement dynamic tool discovery from ~/.config/anvillm/mcptools/
- Add workspace isolation (~/.cache/anvillm/exec)
- Add security: output limits, concurrency limits, validation, path traversal protection
- Update bot templates (Conductor, Taskmaster) with bash examples
- Update anvillm-communication skill to use execute_code pattern
- Create comprehensive documentation (user guide, migration guide, security guide)
- Add test suite for validation and limitedWriter
- Fix landrun flags: --rox for executables, --env for AGENT_ID passthrough
- Network blocked by default (no --connect-tcp or --unrestricted-network)

Token reduction: 80-99% via progressive tool discovery and subprocess data processing

* Fix code review issues in MCP code execution pattern

- Security: Change security.jsonl permissions from 0644 to 0600
- Bug: Fix limitedWriter to return correct byte count for io.Copy
- Bug: Fix tool schema inconsistency (execute_code requires only 'code')
- Performance: Move whitespace regex to package-level var
- Security: Improve validateCode with regex patterns and normalization
- Cleanup: Remove dead code from main.go and tools.go
- Cleanup: Rewrite shell scripts to use jq for safe JSON construction
- Docs: Fix duplicate sections and JavaScript syntax in bash examples

* Improve code validation security patterns

- Fix rm -rf bypass: allow optional whitespace before /
- Expand rm -rf to block sensitive paths (/home, /var, /usr, etc.)
- Block all network protocols in curl/wget (not just http/https)
- Add test for regex pattern compilation
- Add test cases for tabs, sensitive paths, ftp/file protocols

* Harden shell scripts and improve rate limiting

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Levi Neely <lneely@pascom.net>
2026-02-26 14:02:54 +01:00
Levi Neely 2418f12012 Fix review findings from code review
- 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
2026-02-26 12:05:28 +01:00
Levi Neely 439faf3e98 Add review gate, researcher routing, and slash command support
- Conductor: spawn per-worktree researcher, route worker QUERY_REQUESTs
  through researcher, add post-completion review gate with Reviewer bot,
  auto-approve trivial/docs/config beads
- Taskmaster: handle review rejection by parsing findings into new beads
- claude.go: enable slash command support (pass through to Claude CLI)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 19:17:50 +01:00
Levi Neely 5bcaa38ad7 cost / usage optimization, phase 1 2026-02-25 19:17:50 +01:00
Levi Neely 18a6448b37 Add extended linting rules and Acme file addressing (bd-9y4, bd-iti)
Extends lintDescription() with 8 new rules: Acme address format correction
(file:N-N → file:N,N), imperative verb start, vague language detection, how
signal, no first-person voice, forbidden vague phrases, inline code (backticks),
and cross-reference on long descriptions (>150 chars). Updates containsLineRef()
to also recognise #N char-position addresses; adds containsAcmeRegexAddr(),
containsHyphenRange(), and containsBdRef() helpers. Adds 32 tests covering every
rule in beads_lint_test.go.

Updates bot-templates/Conductor (6-question cold-completion gate, File Addressing
section), bot-templates/Taskmaster (File Addressing section with grammar
reference), and skills/beads/SKILL.md (Description Quality section with full lint
rule table and Acme addressing guide).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:07:52 +01:00
Levi Neely 312276582b Optimize bead description quality (bd-3bu)
- Add description lint check to beads new command (bd-3bu.3):
  warns to stderr on missing file path, function/line ref, short
  description, or missing acceptance criterion; --no-lint and
  IDEA:-prefixed titles bypass lint

- Add post-completion write-back convention to beads SKILL.md
  (bd-3bu.2): quality ratings good/missing-location/missing-pattern/
  too-vague, plus anti-pattern for closing without a quality comment

- Update Taskmaster prompt with five-field schema, KB query
  requirement, and type-specific templates bug/feature/refactor/idea
  (bd-3bu.1, bd-3bu.4)

- Add P1/P2 cold-completion gate to Conductor prompt (bd-3bu.5):
  five-question checklist before assigning high-priority beads to bots

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:07:51 +01:00
Levi Neely 572ac91d86 Set CLAUDE_CONFIG_DIR at startup and propagate to tmux/shell/sandbox
- 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>
2026-02-24 11:49:02 +01:00
Levi Neely 065e4a3295
Add bulk-archive via inline Put notation to inbox and archive windows (#12)
* 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>
2026-02-23 19:58:37 +01:00