Skip to content

Conversation

@pmarsceill
Copy link
Owner

@pmarsceill pmarsceill commented Jan 23, 2026

Summary

Enable agents to request user input by posting comments to the originating GitHub issue, with automatic detection and response delivery.

  • GitHubPoller: Background goroutine that polls GitHub issues for new comments and delivers responses to agent tmux sessions
  • InputMonitor: Monitors tmux sessions for idle agents with question patterns and automatically posts questions to GitHub
  • New CLI commands: map task input-needed and map task my-task
  • Schema changes: GitHub source tracking fields on tasks (owner, repo, issue number, waiting state)
  • Proto changes: WAITING_INPUT status, RequestInput and GetCurrentTask RPCs

Flow

  1. Sync issues with map task sync gh-project "Project" - GitHub metadata is stored with each task
  2. Agent works on the task and asks a question (detected automatically via InputMonitor or manually via map task input-needed)
  3. Question is posted to GitHub issue with prefix **My agent needs more input:**
  4. User responds on GitHub
  5. GitHubPoller detects response and sends to agent's tmux session
  6. Agent continues working

Additional fixes

  • Fixed long prompt submission by adding 300ms delay before Enter key to handle collapsed paste previews ([Pasted text #1 +N lines]) in Claude Code

Test plan

  • Sync a GitHub project with map task sync gh-project "Test"
  • Verify tasks have GitHub metadata stored
  • Spawn an agent and assign a GitHub-sourced task
  • Verify question detection works when agent asks a question
  • Verify comment appears on GitHub issue with correct prefix
  • Post a response on GitHub and verify it's delivered to agent
  • Test manual map task input-needed command
  • Test map task my-task from agent worktree

Closes #21

🤖 Generated with Claude Code

pmarsceill and others added 3 commits January 23, 2026 16:09
Enable agents to request user input by posting comments to the
originating GitHub issue, with automatic detection and response
delivery.

Components:
- GitHubPoller: polls GitHub issues for new comments and delivers
  responses to agent tmux sessions
- InputMonitor: monitors tmux sessions for idle agents with question
  patterns and automatically posts questions to GitHub
- New CLI commands: `map task input-needed` and `map task my-task`
- Schema changes: GitHub source tracking fields on tasks
- Proto changes: WAITING_INPUT status, new RPCs

Flow:
1. Sync issues with `map task sync gh-project` (stores GitHub metadata)
2. Agent works and asks a question (detected automatically via
   InputMonitor or manually via `map task input-needed`)
3. Question posted to GitHub issue with bot prefix
4. User responds on GitHub
5. GitHubPoller detects response and sends to agent's tmux session
6. Agent continues working

Also fixes long prompt submission by adding delay before Enter key
to handle collapsed paste previews in Claude Code.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
After merging main, the socketPath variable was replaced with the
getSocketPath() function from the new Viper configuration system.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Owner Author

@pmarsceill pmarsceill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Overall

Well-structured feature with clean separation of concerns. The GitHubPoller and InputMonitor components are nicely isolated, and the database migrations are handled gracefully. All CI checks pass.

Issues

1. ghComment.Author won't parse correctly

File: internal/daemon/github_poller.go:33-36

The gh issue view --json comments returns author as a nested object:

{"comments": [{"author": {"login": "user"}, ...}]}

But the struct expects a string:

type ghComment struct {
    Author string `json:"author"`  // Will always be empty
}

This only affects logging (line 449), but it's misleading. Consider:

type ghComment struct {
    Author    struct{ Login string } `json:"author"`
    // ...
}

2. Hardcoded 300ms delay in 3 places

Files: process.go:231, process.go:476, github_poller.go:516

Consider extracting to a constant:

const tmuxPasteDelay = 300 * time.Millisecond

3. Potential memory leak in InputMonitor

File: internal/daemon/input_monitor.go:600-602

The lastContent and lastChangeTime maps are only cleared when a question is detected and posted. If an agent is killed without asking a question, entries remain forever. Consider cleaning up entries for agents that no longer exist:

func (m *InputMonitor) checkAllAgents() {
    m.mu.Lock()
    defer m.mu.Unlock()

    agents := m.processes.List()
    activeIDs := make(map[string]bool)
    
    for _, agent := range agents {
        activeIDs[agent.AgentID] = true
        m.checkAgent(agent)
    }
    
    // Clean up stale entries
    for id := range m.lastContent {
        if !activeIDs[id] {
            delete(m.lastContent, id)
            delete(m.lastChangeTime, id)
        }
    }
}

4. Response formatting loses structure

File: internal/daemon/github_poller.go:506-507

singleLineMessage := strings.ReplaceAll(message, "\n", " ")

Multi-paragraph GitHub responses become a wall of text. This might make complex responses hard to read for the agent.

Suggestions (Non-blocking)

  1. Make polling intervals configurable - The 30s (GitHubPoller) and 5s (InputMonitor) intervals could be Viper config options

  2. Use net/url for URL parsing - parseGitHubURL() uses string splitting which is fragile for edge cases

  3. Add tests - The question detection logic (extractQuestion, isActivelyWorking) and URL parsing would benefit from unit tests

Summary

The feature is well-implemented and ready for use. The Author parsing bug is minor (logging only), but the memory leak in InputMonitor should be addressed. Consider the suggestions as follow-up improvements.

pmarsceill and others added 2 commits January 23, 2026 16:37
- Fix ghComment.Author to parse nested object (login field)
- Extract tmuxPasteDelay constant (300ms) used in 3 places
- Fix memory leak in InputMonitor by cleaning up stale agent entries

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add repo_root filtering to all list commands (map task ls, map agent ls,
map worktree ls) so they only show results for the current git repository.

Changes:
- Add repo_root field to proto messages for filtering and tracking
- Add repo_root column to tasks and spawned_agents tables with migration
- Update CLI commands to detect current repo and pass filter
- Update daemon handlers to filter results by repo_root
- Track repo_root when creating tasks, agents, and worktrees

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@pmarsceill pmarsceill merged commit 5d2cb28 into main Jan 24, 2026
5 checks passed
@pmarsceill pmarsceill deleted the feat/bidirectional-github-issue-sync branch January 24, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow the agent to comment back on GH issues if that is where the task originated from.

2 participants