一键导入
add-use-case
Add a new use case interactor with abstraction, implementation, fake, and test. Use when adding new business logic to a feature.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Add a new use case interactor with abstraction, implementation, fake, and test. Use when adding new business logic 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-use-case |
| description | Add a new use case interactor with abstraction, implementation, fake, and test. Use when adding new business logic to a feature. |
Create a new interactor with all four required files.
Parameters: feature name, use case name, type (CenterPostInteractor for one-shot, CenterPostSubjectInteractor for streaming)
The user may provide additional context in three ways — all are optional:
@file reference — e.g., /add-use-case @specs/submit-order.md. The CLI resolves the file and includes its content. Use it to populate param/result types, repository calls, business logic, fake defaults, and test assertions instead of using placeholders. If no arguments are provided, extract feature name, use case name, and type from the spec's Overview / Use Cases section.When context is provided, replace placeholders with real values everywhere: abstract type params, impl logic, fake defaults, 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.md.agents/standards/centerpost.mdfeatures/order/api/domain/src/commonMain/.../GetOrderContent.ktfeatures/order/impl/domain/src/commonMain/.../GetOrderContentImpl.ktfeatures/order/test/src/commonMain/.../FakeGetOrderContent.ktfeatures/order/impl/domain/src/commonTest/.../GetOrderContentImplTest.ktapi/domain/features/{feature}/api/domain/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/api/domain/{Name}.kt
package com.mockdonalds.app.features.{feature}.api.domain
import com.mockdonalds.app.core.centerpost.CenterPostSubjectInteractor
abstract class {Name} : CenterPostSubjectInteractor<Unit, {ResultType}>()
For one-shot use cases, use CenterPostInteractor instead:
abstract class {Name} : CenterPostInteractor<{Params}, {ResultType}>()
impl/domain/features/{feature}/impl/domain/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/domain/{Name}Impl.kt
package com.mockdonalds.app.features.{feature}.domain
import com.mockdonalds.app.features.{feature}.api.domain.{Name}
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import kotlinx.coroutines.flow.Flow
@ContributesBinding(AppScope::class)
class {Name}Impl(
private val repository: {Feature}Repository,
) : {Name}() {
override fun createObservable(params: Unit): Flow<{ResultType}> {
return repository.getData()
}
}
test/features/{feature}/test/src/commonMain/kotlin/com/mockdonalds/app/features/{feature}/test/Fake{Name}.kt
package com.mockdonalds.app.features.{feature}.test
import com.mockdonalds.app.features.{feature}.api.domain.{Name}
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
class Fake{Name}(
initial: {ResultType} = DEFAULT,
) : {Name}() {
private val _content = MutableStateFlow(initial)
override fun createObservable(params: Unit): Flow<{ResultType}> = _content
fun emit(content: {ResultType}) {
_content.value = content
}
companion object {
val DEFAULT = // test default data
}
}
impl/domain/commonTest/features/{feature}/impl/domain/src/commonTest/kotlin/com/mockdonalds/app/features/{feature}/domain/{Name}ImplTest.kt
package com.mockdonalds.app.features.{feature}.domain
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.flow.first
class {Name}ImplTest : BehaviorSpec({
Given("a {Name}Impl") {
val repository = // test repository instance
val impl = {Name}Impl(repository)
When("observing data") {
Then("it should return expected content") {
val result = impl.createObservable(Unit).first()
// assertions
}
}
}
})
api/domain/ — public contractimpl/domain/ — private, must have @ContributesBinding(AppScope::class)test/src/commonMain/ — NOT in commonTestWork is NEVER complete until verification passes. Run the verify skill to validate all changes. It will:
@ContributesBinding, abstract/impl pairing issuesIf ANY check fails, fix the issue and re-run. Do not declare the task complete until verification passes.