Skip to content

Integration Agent

Ali Sadeghi edited this page May 18, 2026 · 4 revisions

Integration Agent

Completes the 4 integration points and generates the living specification. Invoked by creating-kmp-feature skill in Phase 3, after data + UI agents finish.

Model: sonnet · Color: green · Allowed tools: Read, Write, Edit, Glob, Grep, ./gradlew

The 4 Integration Points (all required)

# Point File Pattern
1 Gradle Include settings.gradle.kts include(":feature:{featurename}")
2 Gradle Dependency composeApp/build.gradle.kts implementation(project(":feature:{featurename}"))
3 DI Init {INIT_KOIN_PATH} {Feature}Modules.initialize()
4 Navigation {NAV_HOST_PATH} {featurename}(onBackClick = {...})

Workflow

  1. Create DI module (di/{Feature}Modules.kt).
  2. Integration Point 1 — Gradle Include.
  3. Integration Point 2 — Gradle Dependency.
  4. Integration Point 3 — DI Initialization.
  5. Integration Point 4 — Navigation (reads Screen for callback signatures).
  6. Validate: ./gradlew assembleDebug && ./gradlew ktlintFormat.
  7. Generate spec.md using the template from _shared/spec-template.md.

DI Module Pattern

The DI module is an object extending BaseFeature. This is the only correct pattern.

package {PKG_PREFIX}.{featurename}.di

import org.koin.core.module.Module
import org.koin.core.module.dsl.singleOf
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.bind
import org.koin.dsl.module
import {CORE_COMMON_PKG}.di.base.BaseFeature
// (datasource + repository + viewmodel imports)

object DashboardModules : BaseFeature(DashboardModules::class.simpleName.toString()) {
    override fun getKoinModules(): List<Module> =
        listOf(
            module {
                // Data layer
                singleOf(::DashboardLocalDataSourceImpl).bind<DashboardLocalDataSource>()
                singleOf(::DashboardRemoteDataSourceImpl).bind<DashboardRemoteDataSource>()
                singleOf(::DashboardRepositoryImpl).bind<DashboardRepository>()

                // Presentation layer
                viewModelOf(::DashboardViewModel)
            },
        )

    override fun initialize() {
        DashboardModules
    }
}

Integration Point 4 — Navigation

The feature's nav extension is invoked by BaseAppNavHost.kt. The host never writes a composable<Route> { ... } block for the feature.

// composeApp/.../BaseAppNavHost.kt
@Composable
fun BaseAppNavHost(modifier: Modifier) {
    val navController = rememberNavController()
    XNavHost(
        modifier = modifier,
        navController = navController,
        startDestination = DashboardRoute,
    ) {
        dashboard(
            onActionClick = { actionId ->
                if (actionId == "send") navController.navigate(SendRoute)
                if (actionId == "receive") navController.navigate(ReceiveRoute)
            },
            onBackToDashboard = {
                navController.popBackStack(DashboardRoute, inclusive = false)
            },
        )
        send(onBackClick = { navController.popBackStack() })
        receive(onBackClick = { navController.popBackStack() })
    }
}

Integration Point 3 — DI Init

initKoin.kt registers every feature module's .initialize():

private fun initializeFeatures() {
    CommonModules.initialize()
    DataModules.initialize()
    DashboardModules.initialize()
    SendModules.initialize()
    ReceiveModules.initialize()
}

fun initKoin(appDeclaration: KoinAppDeclaration = {}): KoinApplication {
    initializeFeatures()
    return startKoin {
        appDeclaration()
        modules(getAllModules())  // FeatureRegistry collects them
    }
}

The agent appends {Feature}Modules.initialize() to the existing initializeFeatures() block.

Spec Generation

Critical: Copy WHY content from the PRD before Phase 4 deletes it:

  • Goals
  • Non-Goals
  • Background & Rationale
  • Design Decisions

Template lives at .claude/skills/_shared/spec-template.md.

Output Report

## Integration Complete: {featurename}

### Files Created/Modified
- di/{Feature}Modules.kt (created)
- settings.gradle.kts (modified)
- composeApp/build.gradle.kts (modified)
- {INIT_KOIN_PATH} (modified)
- {NAV_HOST_PATH} (modified)

### Integration Points
✅ 1. Gradle Include
✅ 2. Gradle Dependency
✅ 3. DI Initialization
✅ 4. Navigation Wiring

### Validation
✅ ./gradlew assembleDebug
✅ ./gradlew ktlintFormat

### Spec Generated
✅ .claude/docs/{featurename}/spec.md

Next: navController.navigate({Feature}Route)

Back to Feature-Development-Agents | Agents

Clone this wiki locally