Skip to content

Upstream PR triage batch 2: 12 PRs with tests, fixes, and enhancements#368

Open
whitmo wants to merge 46 commits intodlorenc:mainfrom
whitmo:upstream-pr-triage-b2
Open

Upstream PR triage batch 2: 12 PRs with tests, fixes, and enhancements#368
whitmo wants to merge 46 commits intodlorenc:mainfrom
whitmo:upstream-pr-triage-b2

Conversation

@whitmo
Copy link
Copy Markdown

@whitmo whitmo commented Mar 12, 2026

Summary

Batch integration of 12 upstream PRs from dlorenc/multiclaude with additional test coverage, bug fixes, and enhancements. Cross-reviewed adversarially using Gemini Pro & Claude Opus 4.6.

Upstream PRs Included

PR Title
#289 docs: add extensibility hints to CLI, daemon, state
#308 fix: Standardize worker branch naming to multiclaude/ prefix
#333 feat: enhance repair command to recreate core agents and default workspace
#334 fix(cli): generate new session ID when no history exists
#335 feat: Add --json flag for LLM-friendly CLI help output
#336 fix: lowercase error messages to satisfy staticcheck ST1005
#337 feat(cli): improve help output with categorized commands
#338 feat: Improve CLI help and status display for token awareness
#339 feat: Improve multiclaude refresh with agent-context awareness
#340 feat: improve error messages with structured errors and suggestions
#341 feat: Add token efficiency guidance to worker template
#342 fix: Clean up acknowledged messages in message routing loop

Additional Fixes (not in upstream PRs)

Test plan

  • go test ./... passes
  • go test ./test/... E2E tests pass
  • make check-all passes (full CI equivalent)

🤖 Generated with Claude Code

aronchick and others added 30 commits January 24, 2026 01:12
Fixes branch naming inconsistency by standardizing on 'multiclaude/' prefix. Maintains backward compatibility for cleanup of legacy 'work/' branches.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The comment at internal/cli/cli.go:5128 referenced docs/EXTENSION_DOCUMENTATION_SUMMARY.md which doesn't exist. Updated the comment to reference the actual existing extension docs (docs/extending/SOCKET_API.md and docs/extending/STATE_FILE_INTEGRATION.md) that need to be kept in sync when CLI commands affecting extension surfaces change.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…space

Improve the repair command to be more comprehensive by ensuring core
agents and a default workspace exist after cleanup. This enhancement
aligns with ROADMAP.md P1 "Agent restart" by making repair more robust
and reducing the need for manual intervention.

Changes:
- CLI: Add ensureCoreAgents() and ensureDefaultWorkspace() helpers
- CLI: Update localRepair() to recreate missing core agents
- CLI: Create default workspace "my-default-2" if none exist
- Daemon: Add ensureCoreAgents() and ensureDefaultWorkspace() methods
- Daemon: Update handleRepairState() to recreate missing agents
- Both: Improve output to show what was removed and what was created
- Tests: Add comprehensive tests for all scenarios

Key Features:
1. Recreates missing supervisor agent if absent
2. Recreates missing merge-queue (non-fork) or pr-shepherd (fork)
3. Creates default workspace if no workspaces exist
4. Does not duplicate existing agents/workspaces
5. Provides detailed output showing:
   - Removed: dead agents
   - Cleaned: orphaned resources
   - Created: core agents and workspaces

Test Coverage:
- TestRepairEnsuringCoreAgents: Verifies core agents are created
- TestRepairEnsuringPRShepherdInForkMode: Fork mode verification
- TestRepairDoesNotDuplicateAgents: Prevents duplicates

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…tory

When running `multiclaude claude` and no session history exists, the
command now generates a new session ID instead of reusing the old one.
This fixes "Session ID is already in use" errors that occur when Claude
exits abnormally and leaves the session ID locked.

Also adds missing trigger_refresh socket command documentation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for machine-readable JSON output of the command tree:
- `multiclaude --json` outputs full command tree as JSON
- `multiclaude --help --json` same as above
- `multiclaude <cmd> --json` outputs that command's schema

This enables LLMs and automation tools to programmatically discover
available commands, their descriptions, usage patterns, and subcommands.

Includes CommandSchema struct for clean JSON serialization that filters
internal commands (prefixed with _) from output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…nflicts

The 'multiclaude claude' command was failing with "Session ID already in use"
error when Claude was already running in the agent context. This happened because
the command would attempt to restart Claude with --session-id or --resume flags
without checking if a Claude process was already active with that session ID.

Changes:
- Add process alive check for stored agent PID before restarting
- Add double-check for any running process in the tmux pane
- Provide helpful error messages with steps to exit and restart
- Import syscall package for signal-based process detection

The fix detects:
1. If the stored agent PID is still running
2. If a different process is running in the tmux pane

Users now get clear instructions on how to properly restart Claude or attach
to the existing session.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed two error messages to start with lowercase to comply with
Go's error formatting conventions (staticcheck rule ST1005):

- "Claude is already running..." → "claude is already running..."
- "A process..." → "a process..."

These are multi-line user-facing error messages that remain helpful
while following Go's convention that error strings should not be
capitalized (since they may be wrapped in other error contexts).

Fixes lint failures in PR dlorenc#321

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Restructures the CLI help output to be more user-friendly:

- Add QUICK START section showing the 4 most common commands
- Group commands into 6 categories: DAEMON, REPOSITORIES, AGENTS,
  COMMUNICATION, MAINTENANCE, META
- Hide 7 redundant aliases from help (still functional, just not displayed)
- Add Hidden and Category fields to Command struct for flexibility

The help output now shows 21 focused commands instead of 28 scattered
entries, making it much easier for new users to understand what to do.

Also adds CLI_RESTRUCTURE_PROPOSAL.md documenting the analysis and
future restructuring options for v2.0.

Aligns with ROADMAP P2 "Better onboarding".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LongDescription field to Command struct for detailed help text
- Add comprehensive help for 'repo hibernate' explaining token consumption
- Show specific active agents in 'multiclaude status' (supervisor, merge-queue, etc.)
  instead of just 'X core, Y workers'
- Add token consumption warning when agents are active
- Point users to 'hibernate --all' to stop token usage

This makes hibernate more discoverable and helps users understand that
running agents continuously consume API tokens.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When run inside an agent worktree, `multiclaude refresh` now syncs just
that worktree directly instead of triggering a global refresh via daemon.
This gives agents immediate feedback and control over their sync process.

Changes:
- Add context detection: automatically identifies agent worktree from cwd
- Add direct refresh: syncs single worktree using worktree.RefreshWorktree()
- Add --all flag: explicitly triggers global refresh (previous behavior)
- Update /refresh slash command to recommend CLI method
- Provide detailed output: fetch status, rebase info, conflict handling

Behavior:
- Inside agent worktree: refreshes that worktree directly with feedback
- Outside agent context: triggers daemon-based global refresh
- With --all flag: always triggers daemon-based global refresh

P0 Roadmap item: Worktree sync

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
P0 Roadmap item: Clear error messages

This change ensures every user-facing error tells users:
1. What went wrong (clear, categorized message)
2. How to fix it (actionable suggestion)

Changes:
- Add 17 new error constructors to internal/errors for common failure modes
- Update ~50 error handling locations in CLI to use structured errors
- Replace raw fmt.Errorf calls with CLIError providing suggestions

New error types added:
- RepoAlreadyExists, DirectoryAlreadyExists, WorkspaceAlreadyExists
- InvalidWorkspaceName, InvalidTmuxSessionName
- LogFileNotFound, InvalidDuration, NoDefaultRepo
- StateLoadFailed, SessionIDGenerationFailed, PromptWriteFailed
- ClaudeStartFailed, AgentRegistrationFailed
- WorktreeCleanupNeeded, TmuxWindowCleanupNeeded, TmuxSessionCleanupNeeded
- WorkerNotFound, AgentNoSessionID

Before:
  Error: failed to register worker: connection refused

After:
  Error: failed to register worker with daemon: connection refused

  Try: multiclaude daemon status

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Workers now receive guidance to use /sc:index-repo for large codebase
exploration, achieving 94% token reduction (58K → 3K tokens). This
improves memory usage and search efficiency for complex tasks.

The guidance is embedded in the worker template and will be included
in system prompts for all new worker agents.

Task: If a skill is provided such as QMD that enables better memory
and tokens and searching, make sure that Multiclaude uses it.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## Problem
Messages were piling up in the filesystem because acknowledged messages
were never deleted. The messages.Manager had a DeleteAcked() method, but
it was never called by the daemon's message routing loop.

Evidence:
- 128 message files accumulated in production
- 17 acked messages that should have been deleted
- 111 delivered messages never acknowledged

## Root Cause
The messageRouterLoop delivered messages and marked them as "delivered",
but had no cleanup mechanism. The DeleteAcked() method existed but was
only used in tests.

## Solution
Added automatic cleanup of acknowledged messages to the routeMessages()
function. After delivering pending messages to each agent, the loop now
calls DeleteAcked() to remove any messages that have been acknowledged.

The cleanup:
- Runs every 2 minutes as part of the normal message routing cycle
- Only deletes messages with status "acked"
- Logs cleanup activity at debug level for visibility
- Handles errors gracefully without disrupting message delivery

## Testing
- Added TestMessageRoutingCleansUpAckedMessages to verify cleanup works
- All existing daemon tests pass
- Verified in production: 17 acked messages cleaned up after daemon restart

## Impact
- Prevents unbounded growth of message files
- Reduces filesystem clutter
- Makes the message system more reliable
- No breaking changes to message API or behavior

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…c#333 on pr-triage-b2

Tests from multiclaude workers (silly-otter, lively-otter, clever-bear):
- PR dlorenc#338: Token-aware status display, hibernate help, rich list_repos response
- PR dlorenc#339: Context-aware refresh, worktree path detection, --all flag parsing
- PR dlorenc#337: Categorized help (worker report captured, tests via CLI assertions)
- PR dlorenc#333: Enhanced repair (worker report captured, daemon handler tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The "Token Efficiency" section referenced a non-existent sc:index-repo
slash command with fabricated claims (94% token reduction, 58K->3K tokens).
This confused workers into trying to run a command that doesn't exist.

Introduced by PR dlorenc#341, the skill was likely hallucinated by the agent.

Also investigated the reported format.Dimmed bug in systemStatus
(cli.go:1081) - confirmed it is NOT a bug. format.Dimmed is a void
function that already prints via Dim.Printf, so the code works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This draft proposal is obsolete — key recommendations have already
been implemented:
- Categorized help output (PR dlorenc#337)
- Hidden command field concept in Command struct
- agents command restructuring

The remaining suggestions (deprecation warnings, guide command,
templates rename) can be revisited as standalone issues if needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
whitmo and others added 16 commits February 28, 2026 19:50
…lRepair

Previously, localRepair logged errors from ensureCoreAgents and
ensureDefaultWorkspace as warnings (only visible with --verbose) but
returned nil, implying success. Callers had no way to know repair
had issues.

Now errors are accumulated in a slice and returned as a combined
error message so callers can detect partial repair failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…faultWorkspace, spawnCoreAgent

These functions (from PR dlorenc#333) had zero test coverage. Adds 8 tests covering:
- ensureCoreAgents with empty state, missing tmux session, existing agents, fork mode
- ensureDefaultWorkspace with empty state, existing workspace, missing tmux session
- spawnCoreAgent error message includes resp.Error details

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract shared core agent decision logic into state.MissingCoreAgents()
to eliminate ~60 lines of duplicated fork-mode detection and config
defaulting. Fix daemon ensureDefaultWorkspace to use writePromptFile()
helper and claudeRunner.Start() instead of raw os.WriteFile/exec.Command,
making it consistent with all other agent creation paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… to restart

handleRestartAgent requires the agent to already exist in state, causing a
chicken-and-egg failure when repair tries to create missing core agents like
merge-queue. Now spawnCoreAgent does full creation: tmux window, prompt file,
Claude process, and state registration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved conflicts with dlorenc#337 categorized help: kept categorized output
and added JSON hint line. showCommandHelp now supports both outputJSON
parameter and root command redirect to categorized help.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nc#336, dlorenc#340, dlorenc#342

Add 659 lines of tests covering:
- All 18 structured error constructors from PR dlorenc#340 (individual + bulk format test)
- JSON CLI output edge cases from PR dlorenc#335 (empty/nested/all-internal subcommands)
- Structured CLIError validation for workspace names from PR dlorenc#340 integration
- Message routing edge cases from PR dlorenc#342 (no acked, mixed ack status)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mark completed items (Hidden field, categorized help, aliases hidden)
and preserve remaining proposals (guide command, agents→templates rename,
deprecation warnings, v2.0 alias removal). Trimmed redundant sections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s, fixes, and enhancements

PR triage: merge 12 upstream PRs that passed CI
@whitmo
Copy link
Copy Markdown
Author

whitmo commented Mar 13, 2026

CI Status

This PR is from a fork. GitHub Actions requires maintainer approval before CI workflows will run on fork PRs.

Local verification (2026-03-13):

  • go build ./cmd/multiclaude — passes
  • go test ./internal/... ./pkg/... — all 23 packages pass
  • ✅ Branch is up-to-date with upstream/main (0 commits behind)

Ready for maintainer review once CI workflows are approved.

@whitmo whitmo marked this pull request as ready for review March 14, 2026 13:24
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.

2 participants