원클릭으로
add-repository
Add a new repository with interface, implementation, and test. Use when adding a new data source to a feature.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Add a new repository with interface, implementation, and test. Use when adding a new data source to a feature.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Convert acceptance criteria, Jira tickets, Gherkin scenarios, PRDs, or any product requirements into a structured spec template. Use when translating PM artifacts into actionable specs for add-*, update, migrate, or remove skills.
Scaffold a complete new feature module with all 6 submodules, source files, tests, fakes, and AGENTS.md. Use when adding an entirely new feature to the app.
Execute cross-cutting migrations — library swaps, pattern changes, API version upgrades, or architecture refactors. Handles phased rollout, coexistence, and rollback planning.
Reverse-engineer a spec from existing code — reconstructs presumed acceptance criteria, data flow, API contracts, UI states, and business rules by reading source, tests, and git history. Use when inheriting undocumented features, onboarding onto unfamiliar code, or preparing for a refactor.
Modify existing feature code across all affected layers — domain models, data, presentation, tests, and fakes. Use when changing behavior, adding fields, or enhancing existing features.
Verification pipeline with three scopes — diff (default, changed modules only), full (whole project lint + unit + arch + builds), and all (every test level + every variant + full assemble). Use after any code change.
| name | add-repository |
| description | Add a new repository with interface, implementation, and test. Use when adding a new data source to a feature. |
Create a repository interface, implementation, and test.
Parameters: feature name, repository name
The user may provide additional context in three ways — all are optional:
@file reference — e.g., /add-repository @specs/payment-repo.md. The CLI resolves the file and includes its content. Use it to populate repository methods, data types, DTO fields, endpoint paths, mapper logic, and test assertions instead of using placeholders. If no arguments are provided, extract feature and repository name from the spec's Overview / Repository section.When context is provided, replace placeholders with real values everywhere: interface methods, impl logic, DTOs, mappers, data source methods, and test cases. If context is partial, fill in what you can and leave // TODO only for genuinely unknown parts.
Templates are available in .agents/templates/new-spec.md for structured input.
When the user provides a spec via @file, scan it for unresolved markers before scaffolding (see the grill-me skill for the full marker list): <!-- TODO --> placeholders, empty - [ ] AC items, empty required header fields, raw template placeholder prose, ... table cells, or unconfirmed reverse-spec presumptions (presumably / appears to). If any are present, stop and run /grill-me @{spec} first, then resume this skill.
The conversion skills (/ac-to-spec, /reverse-spec) grill inline before producing output, so a marker-laden spec usually means the spec was hand-authored from a template or has gone stale. Skip the pre-flight only if the user explicitly says "skip the grill" — in that case, surface unresolved markers as // TODO comments in the generated code and call them out in the final summary.
.agents/standards/dependency-injection.mdfeatures/order/impl/domain/src/commonMain/.../OrderRepository.ktfeatures/order/impl/data/src/commonMain/.../OrderRepositoryImpl.ktfeatures/order/impl/data/src/commonTest/.../OrderRepositoryImplTest.ktimpl/domain/features/{feature}/impl/domain/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/domain/{Name}Repository.kt
package com.mockdonalds.app.features.{feature}.domain
import kotlinx.coroutines.flow.Flow
interface {Name}Repository {
fun getData(): Flow<{DataType}>
}
Repository functions should return Flow<T> for streaming data. Use suspend fun only for one-shot operations (rare).
impl/data/features/{feature}/impl/data/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/data/{Name}RepositoryImpl.kt
package com.mockdonalds.app.features.{feature}.data
import com.mockdonalds.app.features.{feature}.domain.{Name}Repository
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
@ContributesBinding(AppScope::class)
class {Name}RepositoryImpl : {Name}Repository {
override fun getData(): Flow<{DataType}> = flowOf(
// implementation
)
}
impl/data/commonTest/features/{feature}/impl/data/src/commonTest/kotlin/com/mockdonalds/app/features/{feature}/data/{Name}RepositoryImplTest.kt
package com.mockdonalds.app.features.{feature}.data
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.flow.first
class {Name}RepositoryImplTest : BehaviorSpec({
Given("a {Name}RepositoryImpl") {
val repository = {Name}RepositoryImpl()
When("fetching data") {
Then("it should return expected values") {
val result = repository.getData().first()
// assertions
}
}
}
})
impl/data/remote/features/{feature}/impl/data/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/data/remote/{Name}RemoteDataSource.kt
package com.mockdonalds.app.features.{feature}.data.remote
import kotlinx.coroutines.flow.Flow
interface {Name}RemoteDataSource {
fun getData(): Flow<{Name}Dto>
}
features/{feature}/impl/data/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/data/remote/{Name}RemoteDataSourceImpl.kt
package com.mockdonalds.app.features.{feature}.data.remote
import com.mockdonalds.app.core.buildconfig.AppBuildConfig
import com.mockdonalds.app.core.network.HttpClientFactory
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.ktor.client.HttpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
@ContributesBinding(AppScope::class)
@Inject
class {Name}RemoteDataSourceImpl(
httpClientFactory: HttpClientFactory,
appBuildConfig: AppBuildConfig,
) : {Name}RemoteDataSource {
private val client: HttpClient = httpClientFactory.create {
baseUrl = appBuildConfig.{service}BaseUrl // e.g., menuBaseUrl, orderBaseUrl — see AppBuildConfig
}
override fun getData(): Flow<{Name}Dto> = flow {
// client.get("{endpoint}").body<{Name}Dto>()
}
}
impl/data/remote/features/{feature}/impl/data/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/data/remote/{Name}Dto.kt
package com.mockdonalds.app.features.{feature}.data.remote
import kotlinx.serialization.Serializable
@Serializable
data class {Name}Dto(
// fields matching API response
)
DTOs must be @Serializable data classes with Dto suffix, located in remote/ package (Konsist enforces this).
impl/domain/ — visible to use cases in the same featureimpl/data/ — private, must have @ContributesBinding(AppScope::class)RepositoryImpl (Konsist enforces this)impl/data/remote/, local in impl/data/local/ (Konsist enforces this)@Serializable data classes with Dto suffix in remote/ (Konsist enforces this)impl/data modules may depend on core:network:api (Konsist enforces this)HttpClient via HttpClientFactory — no shared singletonWork is NEVER complete until verification passes. Run the verify skill to validate all changes. It will:
@ContributesBinding, layer isolation issuesIf ANY check fails, fix the issue and re-run. Do not declare the task complete until verification passes.