↑ ↓ 移动 · Enter 打开 · Esc 关闭点按一个结果

架构
agent · installer 类 · sonnet

mapstruct-installer

一次性记录项目的映射机制:写入手写映射器的说明段落,或接入 MapStruct 并转换所有现有映射器。

agent · installersonneteffort medium11 允许的路径
§ agent 的定义

mapstruct-installer.md,逐节说明

agent 自己文件的各节,为节选。把鼠标移到某一节上或点击它,可以看到它引用了哪些项目规则和模板。各节也是标签:点击即可跳转。

nerviz/.claude/agents/mapstruct-installer.md

## Why this is an agent (Form 3)

Preserves context. Same shape as commons-logging-installer: resolve two versions from Maven Central, merge a fixed fragment into the build, then — the part those two installers never had — rewrite every manual mapper of the project and the classes that call it, and run the test suite before and after. The file list, the diffs and two full build logs are the longest output an implement run can produce, and none of it is needed by the /new-feature-implement run that asked: it needs one summary line and the project fact this agent writes. Invariant 5 requires one reason; this is the one that applies.

No tool or model reason applies on its own — reads and writes stay inside the project, and the conversion follows a fixed table (.claude/rules/mapping.md § What MapStruct generates and what stays written), which sonnet already handles for java-spring-boot-developer.

omitClaudeMd: true: the root CLAUDE.md is a declared input, Read explicitly at step 1 and edited at the last step; auto-loading it too paid for the same file twice (@.claude/decisions/0083-unused-ecosystem-fields-and-real-allow-list.md).

### Mode `manual`

  1. Read the root CLAUDE.md. A **Mappers: paragraph already there → report "already decided",
  2. Insert, right after the **Bounded context: paragraph (or after the first paragraph under the
    1. Return the summary. No build runs: nothing compiled changed.

    ### Mode `install`

    1. Preconditions — stop on any, having changed nothing:
        1. Baseline. Run the project's test command once — ./mvnw -q verify (Gradle:
        1. Resolve the two versions on Maven Central, never from memory:

          … 此处截断,其余见文件

          ## Failure mode

          Already decided: `` ℹ️ mapstruct-installer — nothing to do: the root CLAUDE.md already says "Mappers: manual." ``

          Dirty source tree: `` ❌ mapstruct-installer stopped — uncommitted changes under src/ or in a build file src/main/java/.../OrderController.java (modified) The conversion must be revertible with git restore. Commit or stash, then run /new-feature-implement again. ``

          Red baseline: `` ❌ mapstruct-installer stopped — the test suite is red before any change OrderPersistenceIT.updatesTotal: expected 120.00 but was 100.00 Nothing installed. ``

          Red after conversion: `` ❌ UserRestMapperImpl: Unmapped target property: "departmentId" Conversion red after 2 fixes. Revert: git restore src pom.xml ``

          No rollback by the agent itself — the precondition makes the revert one command for the user.

          … 此处截断,其余见文件

          ## Summary format returned to the caller

          ✅ mapstruct-installer complete — Mappers: MapStruct
          - Build: maven · mapstruct 1.6.3 · lombok-mapstruct-binding 0.2.0 (resolved from Maven Central)
          - Processor path: lombok, lombok-mapstruct-binding, mapstruct-processor, spring-boot-configuration-processor
          - Options: defaultComponentModel=spring, defaultInjectionStrategy=constructor, unmappedTargetPolicy=ERROR
          - Converted: 4 mappers (UserRestMapper, UserPersistenceMapper, OrderPersistenceMapper, PaymentClientMapper) — 3 default methods kept written (rehydrate ×2, OrderEntity update)
          - Callers changed: 3 · tests changed: 2
          - Left as is: JacksonObjectMapper (not a mapper)
          - Suite: green before and after · doctor gate: green

          Mode manual: `` ✅ mapstruct-installer complete — Mappers: manual (paragraph written, no build run) ``

          ---

          ## References

          • Invariant 5 — agent only for one of three reasons (context, tools, model)
          • @.claude/agents/commons-logging-installer.md — same shape, same pre-flight trigger
          • @.claude/rules/mapping.md — the norm every converted mapper follows
          • @.claude/decisions/0160-mapstruct-as-a-per-project-mapper-choice.md — why MapStruct is a
          在 GitHub 上打开完整文件 →
          § 行为

          它读什么、写什么、拒绝什么

          skill 自己的契约,取自 SKILL.md,保留原文。

          Class

          installer — the territory is agent_classes.installer.overrides.mapstruct-installer in @.claude/schemas/extensions.json: the build files (pom.xml, build.gradle, build.gradle.kts, root and modules), the root CLAUDE.md, and src/main/java/ plus src/test/java/. The source trees are there for one reason — converting a manual mapper changes its callers (a static RestMapper.toX(...) becomes an injected bean) and the tests that built it. It is the widest installer territory in this repository on purpose, and the procedure narrows it in practice: only mapper files, their callers and their tests are touched. ArchHook.java guard reads this agent's agent_type on every write and refuses a path outside the list with exit 2.

          Executor

          yes — writes under src/ while a design phase may still be open. The class grants it (executor: true), and ArchHook.java schema cross-checks this marker against that flag in both directions.

          Pattern catalog

          not injected — follows a fixed conversion table, designs no code (agent_classes.installer.pattern_catalog: false; schema cross-checks this line).

          Input (required)

          project root and a mode — manual or install. The caller (/new-feature-implement's pre-flight) asked the user which; this agent never asks.

          Reads

          the root CLAUDE.md, the build files, the active blueprint's YAML (its forbidden_imports per module and packages.map), .claude/rules/mapping.md, .claude/rules/lombok.md, .claude/skills/new-feature-implement/templates/mapstruct/*.example (the build fragments), and, for the conversion, the *MapStructMapper.java.example exemplar of each layer it converts — rest-api-architect, graphql-api-architect, persistence-architect, http-client-architect, messaging-architect.

          Writes

          mode manual — the Mappers: manual. paragraph in the root CLAUDE.md, nothing else. Mode install — the build fragment (properties, dependencyManagement, the processor path, the three processor options in the root build; the org.mapstruct:mapstruct dependency in every module that may hold a mapper); every manual mapper rewritten as a MapStruct interface, plus the uses = conversion class an adapter needs; the callers and tests those conversions change; and the Mappers: MapStruct. paragraph.

          Does not write

          docs/** (an approved spec stays as it is — it never named a mechanism), a class that neither is a mapper nor calls one, docker-compose.yml, application*.yml, any version from memory. Never adds a test of its own: a mapper has none (.claude/rules/mapping.md § Common to both mechanisms).

          Does not invoke other agents or skills — no `Agent` tool

          A red baseline, a dirty source tree or an unreachable Maven Central is reported, and the caller decides.

          Returns

          one structured summary (shape at the bottom), not the raw ./mvnw or curl output.

          来源:agent 的 § Contract(nerviz e4cae27)。

          § guard 与 hook

          guard 如何处理它

          installer 是这个 agent 的类。ArchHook 在每次写入时读取它的 agent_type,并按左侧的列表判断路径;它调用的 skill 没有自己的领地。右侧文字是 hook 自己的输出。

          mapstruct-installer 类的 write_allow

          • ✓pom.xml
          • ✓**/pom.xml
          • ✓build.gradle
          • ✓**/build.gradle
          • ✓build.gradle.kts
          • ✓**/build.gradle.kts
          • ✓CLAUDE.md
          • ✓src/main/java/**
          • ✓**/src/main/java/**
          • ✓src/test/java/**
          • ✓**/src/test/java/**
          • 列表之外的任何路径:拒绝,退出码 2

          拒绝以退出码 2 结束,消息回到模型。

          PreToolUse  Agent(mapstruct-installer)
            audit call                       exit 0
            guard call                       exit 0
          SubagentStart
            context subagent                 exit 0
            tests agent-start                exit 0
          # installer · sonnet · write_allow: pom.xml, **/pom.xml, build.gradle, **/build.gradle, build.gradle.kts, **/build.gradle.kts, CLAUDE.md, src/main/java/**, **/src/main/java/**, src/test/java/**, **/src/test/java/**
          
          § 编排

          它在轨道上的位置

          每张卡片是 /new-feature-implement 的一步。执行器运行三次,每次一组块;两组之间由编排器带着上一组的报告继续。虚线的步骤仅在 spec 需要时运行。

          ← 返回链路