Commit Graph
13 Commits
Author SHA1 Message Date
Thomas SharedInboxandClaude Sonnet 4.6 d72df5086c feat: close issues in Python loop after CI passes, not in agent (#134)
Previously issue agents were instructed to close the issue via prompt text
immediately after pushing. If CI then failed, the issue was already closed.

Now the loop tracks a pending_issue across cron ticks:
- When an agent finishes (issue or ci-fix), the issue number is extracted
  from state before it is cleared.
- If CI is still running, a "pending-ci" state preserves the issue number.
- If CI fails, the ci-fix agent is started with the issue number in state
  so it survives the fix cycle.
- Once CI passes, _close_issue() is called from Python — never by the agent.

The agent prompt no longer instructs the agent to close the issue.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:02:16 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 e46dc2961f feat(agent-loop): improve output format with header, URLs, and no prefix (#133)
- Add `---------------------- Starting YYYY-MM-DD HH:MMZ` header at each run
- Remove `[agent_loop]` prefix from all output lines
- Show full Codeberg URL for CI runs instead of bare run ID
- Show full issue URL and title when referencing issues
- Store issue_title in state file so "still running" messages include the title

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 11:50:30 +02:00
Thomas SharedInbox c4e7042430 agent-loop: pick Prio/High issues first among Ready issues 2026-05-22 10:54:27 +02:00
Thomas SharedInbox f315c21c9a add "list" sub-command to agent-loop to resume via UUID. 2026-05-21 11:49:32 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 92cc725913 refactor: simplify .daggerignore and fix hardcoded path after repo move to sharedinbox/
.daggerignore no longer needs to exclude $HOME dirs (fvm/, go/, .pub-cache/,
.claude/, snap/, etc.) since the project root is now sharedinbox/, not $HOME.
agent_loop.py: replace hardcoded /home/si with Path.home().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 13:43:29 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 666c42ce1c refactor(agent-loop): remove tmux, run claude directly via Popen (#120)
Replace the tmux-based agent launcher with a direct subprocess.Popen
call. Claude sessions can't be attached to anyway, so the tmux layer
added complexity with no benefit. State now tracks a PID instead of a
tmux session name; liveness is checked with os.kill(pid, 0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 08:00:39 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 6d4a1a0586 fix(agent-loop): answer workspace-trust dialog by piping a newline to stdin
The new Claude Code trust dialog appeared inside the tmux PTY despite -p
mode and stdout being piped, blocking the agent indefinitely.  With
< /dev/null the dialog could never be answered.

Replace < /dev/null with printf '\n' | so the Enter keypress confirms the
default "Yes, I trust this folder" option.  After that single newline stdin
reaches EOF, which -p mode ignores.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 07:24:06 +02:00
Thomas SharedInbox 130fbbe699 Revert "fix: run agent in TUI mode so tmux attach shows live progress (#118)"
This reverts commit 81fd03102b.
2026-05-17 06:24:45 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 81fd03102b fix: run agent in TUI mode so tmux attach shows live progress (#118)
Previously claude was launched with -p (print mode) which produces no
visible TUI.  Attaching to the session with `tmux attach -t issue-NNN`
showed a blank terminal.  Removing -p makes Claude run its interactive
TUI inside the tmux pane, so the session is fully watchable.

Add scripts/test_agent_loop.py covering _start_agent command
construction and state file round-trips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 23:26:58 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 cc052db6c7 fix(agent-loop): redirect stdin from /dev/null to prevent tmux PTY blocking
Without `< /dev/null`, claude detects the tmux PTY as stdin and blocks
waiting for user input that never arrives (the PTY never sends EOF).
The 3-second stdin-timeout only fires for pipe stdin, not TTY stdin.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 18:11:56 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 4d56bd331b feat(agent-loop): run agents in tmux for reliability and resumability (#100)
- Replace bare subprocess.Popen with `tmux new-session -d` so each agent
  runs in a detached tmux session that inherits the tmux server's environment
  (including ANTHROPIC_API_KEY / keychain access, which cron's minimal env
  lacks — the root cause of intermittent empty log files).
- Track agents by tmux session name instead of PID; age is derived from the
  state-file `started_at` timestamp rather than /proc/<pid>/stat.
- `_kill_agent` terminates via `tmux kill-session`; backward compat preserved
  for old state files that stored a `pid`.
- Operators can now `tmux attach -t issue-<N>` to watch live output, or
  `claude --resume issue-<N>` to continue the conversation afterward.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:54:21 +02:00
Thomas SharedInbox 451aceaeed fix(cron): prepend Nix profile to PATH so tea and claude are found
Cron runs with a minimal environment that doesn't include ~/.nix-profile/bin,
causing every invocation to crash with FileNotFoundError on 'tea'.

Closes #93
2026-05-15 14:14:20 +02:00
Thomas SharedInboxandClaude Sonnet 4.6 b22f450326 feat(dev): add agent_loop.py cron script for autonomous issue processing (#91)
Polls Codeberg CI and State/Ready issues every 10 minutes, launching
Claude Code agents for CI fixes and issue work, with PID-based liveness
tracking and automatic timeout after 1 hour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 13:07:47 +02:00