Block a user
devloop-components (0.2.0)
Published 2026-05-31 14:24:51 -05:00 by joe
Installation
[registry]
default = "gitea"
[registries.gitea]
index = "sparse+ " # Sparse index
# index = " " # Git
[net]
git-fetch-with-cli = truecargo add devloop-components@0.2.0About this package
devloop-components
Pure domain layer for devloop — models, ports, and services with no infrastructure dependencies.
This crate is the hexagonal architecture core of devloop. It defines all domain types (branch
summaries, timeline entries, AI insights), port traits that infrastructure adapters implement, and
domain services that orchestrate analysis. Adapters in crates/cli and crates/devloop-cli
implement these traits using git2, BAML, and GKG; this crate contains none of those details.
Key Types
Domain Models (domain.rs)
| Type | Description |
|---|---|
BranchSummary |
Branch name, commit count, session count, last activity |
TimelineEntry |
A single git commit or Claude session with timestamp and branch |
EntryKind |
Commit { hash, message, author, insertions, deletions } or Session { id, first_message } |
BranchInsight |
AI-generated health score, summary, recommendations, patterns |
CitedFinding |
An observation paired with a structured source reference |
CodeDefinition / CodeReference |
Code structure from a knowledge graph |
RepoMap / RepoMapEntry |
Repository file tree with symbol lists |
DomainError |
Sanitized error variants; no infrastructure detail exposed |
Ports — Timeline and Branch (domain.rs)
| Trait | Purpose |
|---|---|
TimelineProvider |
fetch_timeline(), filter_by_branch() |
BranchAggregator |
list_branches(), get_branch() |
InsightProvider |
analyze_branch(), is_available() |
CodeAnalyzer |
Composite: DefinitionSearcher + ReferenceAnalyzer + RepoMapper + ProjectIndexer |
Ports — Analysis (domain/ports_v2.rs)
| Trait | Purpose |
|---|---|
BranchAnalyzer |
Async analyze(&AnalysisContext) -> BranchInsight |
StreamingAnalyzer |
Extends BranchAnalyzer with partial-update channel |
AsyncBranchAnalyzer |
Composite: StreamingAnalyzer + ServiceAvailability |
UnifiedAnalyzer |
Combines timeline + code structure context |
CouncilAnalyzer |
Multi-role parallel analysis with progress channel |
TimelineFormatter |
Formats commits/sessions for LLM consumption |
CodeStructureFormatter |
Formats definitions, references, repo map for LLM |
DomainLogger |
Dependency-injected logging; NoOpLogger provided |
Result Types (domain/ports_v2.rs)
| Type | Description |
|---|---|
CouncilInsight |
Meta-synthesis + per-role insights + action items |
RoleInsight |
Single council role output (health score, concerns, recommendations) |
ActionItem |
Prioritized action with Priority (P0–P3) and source citation |
UnifiedBranchInsight |
Branch insight enriched with architectural analysis |
Services (domain/services/)
BranchAnalysisService— orchestrates single-role analysis using injected portsCouncilService— coordinates multi-role council runs with progress reporting
Utilities
cite!(finding, source)macro — ergonomicCitedFindingconstructormessage_parser— parses raw Claude session message texttimeline_deduplicator— removes duplicate timeline entries across sourcestest_support— mock implementations of all ports for use in downstream crate tests
Example
use devloop_components::{cite, domain::{CitedFinding, BranchInsight}};
let finding = cite!(
"no error handling on DB write",
"crates/kg/src/store.rs::write_insight:84"
);
let insight = BranchInsight {
branch_name: "feature/kg-persistence".into(),
health_score: 0.72,
summary: "Adds SQLite persistence for council insights.".into(),
recommendations: vec![finding],
patterns: vec!["missing error propagation".into()],
};
Source citation formats: path/to/file.rs::Symbol:line, commit::sha, session::name,
baml::Type.field, or a URL.
Dependencies
| ID | Version |
|---|---|
| anyhow | ^1.0 |
| async-trait | ^0.1 |
| chrono | ^0.4 |
| serde | ^1.0 |
| serde_json | ^1.0 |
| thiserror | ^1.0 |
| tokio | ^1.38 |
| tokio-util | ^0.7 |
| proptest | ^1.4 |
| serde_json | ^1.0 |
| tempfile | ^3 |