Skip to content

refactor(commands): complete handler migration from zeph-core to zeph-commands (phase 3) #2923

@bug-ops

Description

@bug-ops

Description

PR #2922 introduced the zeph-commands crate scaffold with generic types and the ChannelSink trait, but all concrete slash command handlers remain in zeph-core because they access 20+ internal agent state types via Agent<C>.

This issue tracks completing the extraction so that zeph-commands contains the actual handlers, not just scaffolding.

Current state (after #2922)

zeph-commands contains:

  • ChannelSink trait
  • CommandOutput, SlashCategory, CommandInfo, CommandError
  • CommandHandler<Ctx> and CommandRegistry<Ctx> generic types

Still in zeph-core:

  • All *_commands.rs handler files
  • CommandContext<C> (generic over C: Channel)
  • The concrete CommandRegistry<CommandContext<C>> instantiation

Blockers

Handlers access internal agent state directly: MemoryState, SkillState, ToolOrchestrator, LearningEngine, FocusState, SidequestState, and ~15 more types. Two approaches to unblock:

Option A — Trait-based decoupling (preferred)

Introduce a CommandState trait in zeph-commands:

pub trait CommandState: Send + Sync {
    fn memory(&self) -> &dyn MemoryAccess;
    fn skills(&self) -> &dyn SkillAccess;
    fn tools(&self) -> &dyn ToolAccess;
    // ...
}

zeph-core::Agent<C> implements CommandState. Handlers in zeph-commands receive &dyn CommandState instead of direct field access.

Option B — Move subsystem types to leaf crates

Extract MemoryState, SkillState, etc. to zeph-memory, zeph-skills, zeph-tools respectively (some may already be there). Handlers import from those crates without needing zeph-core.

Option A is lower-risk; Option B aligns better with the long-term decomposition plan (#2909).

Acceptance Criteria

  • All *_commands.rs files moved to crates/zeph-commands/src/handlers/
  • CommandContext is non-generic (no C: Channel) in zeph-commands
  • zeph-core does not define any command handlers
  • cargo build --workspace passes
  • All tests pass
  • A change in zeph-core internals does not recompile zeph-commands unless the CommandState interface changes

Related

Metadata

Metadata

Assignees

Labels

P2High value, medium complexityarchitectureArchitecture improvementscorezeph-core craterefactorCode refactoring without functional changes

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions