Token导航 LogoToken导航TokenDH.com
运维和基础设施需要联网github未标认证来源可访问clear审计提醒

viper-architecture-rambler毒蛇架构漫步者

Agent Skill

viper-architecture-rambler 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

449

周安装

18

GitHub Stars

3

下载量

145
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:viper-architecture-rambler(毒蛇架构漫步者)
来源仓库:https://github.com/dagba/ios-mcp
仓库路径:skills/viper-architecture-rambler
安装命令:
npx skills add https://github.com/dagba/ios-mcp --skill viper-architecture-rambler
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/dagba/ios-mcp --skill viper-architecture-rambler

简介

viper-architecture-rambler 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。

  • 适合围绕仓库状态、代码变更或协作事项进行整理和使用。
  • 通过 npx skills add 命令从 GitHub 仓库安装,需指定技能名称和仓库地址。
  • 安装前建议确认权限范围、维护状态,以及是否会触发联网或文件读写操作。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

VIPER Architecture (Rambler Team)

Overview

VIPER enforces Single Responsibility Principle through five protocol-based components: View, Interactor, Presenter, Entity, Router. Created and documented by Rambler&Co iOS Team.

Core Principle: Entities never reach the Presentation layer. Simple data structures transfer between Interactor and Presenter, preventing business logic pollution in UI.

When to Use VIPER

digraph viper_decision {
    "Complex app?" [shape=diamond];
    "Multiple features?" [shape=diamond];
    "Long-term project?" [shape=diamond];
    "Team size > 2?" [shape=diamond];
    "High testability need?" [shape=diamond];
    "Use VIPER" [shape=box, style=filled, fillcolor=lightgreen];
    "Use MVC/MVVM" [shape=box, style=filled, fillcolor=lightcoral];

    "Complex app?" -> "Multiple features?" [label="yes"];
    "Complex app?" -> "Use MVC/MVVM" [label="no"];
    "Multiple features?" -> "Long-term project?" [label="yes"];
    "Multiple features?" -> "Use MVC/MVVM" [label="no"];
    "Long-term project?" -> "Team size > 2?" [label="yes"];
    "Long-term project?" -> "High testability need?" [label="no"];
    "Team size > 2?" -> "Use VIPER" [label="yes"];
    "Team size > 2?" -> "High testability need?" [label="no"];
    "High testability need?" -> "Use VIPER" [label="yes"];
    "High testability need?" -> "Use MVC/MVVM" [label="no"];
}

Use VIPER for:

  • Multi-feature apps (authentication, payments, user profiles, etc.)
  • Long-term projects (6+ months)
  • Teams with 3+ developers
  • Apps requiring extensive unit test coverage
  • Multi-platform code sharing (iOS/iPadOS/macOS)

Avoid VIPER for:

  • Single-screen utilities
  • Rapid prototypes with unclear requirements
  • Weekend projects or proof-of-concepts
  • Small teams with tight deadlines

Component Responsibilities

ComponentResponsibilityWhat It Must NOT Do
ViewDisplay content, relay user input (passive)Request data, format data, navigation, business logic
InteractorBusiness logic, use cases (platform-independent)UI updates, formatting, routing, direct Core Data access
PresenterView logic, data formatting (bridges logic & display)Business logic, network calls, data persistence
EntityPlain model objects (PONSOs - no behavior)Logic, formatting, self-persistence
RouterNavigation, module assemblyBusiness logic, data management, UI updates

VIPER Data Flow

Critical Rule: Entities never pass to Presentation layer.

User Action → View → Presenter → Interactor → Entity/DataStore
           ↓
      Display ← Presenter ← Simple Data ← Interactor

Example: Weather Feature

User taps refresh
→ View calls presenter.didTapRefresh()
→ Presenter calls interactor.refreshWeather()
→ Interactor fetches from DataManager/API
→ Interactor validates, transforms Entity to simple WeatherData
→ Interactor calls presenter.didReceiveWeather(WeatherData)
→ Presenter formats: "72°F, Sunny"
→ Presenter calls view.display(temperature: "72°F")
→ View updates UILabel

Violations to Reject:

  • ✗ Passing NSManagedObject/Entity to Presenter
  • ✗ Presenter accessing Core Data directly
  • ✗ Presenter making network calls
  • ✗ View calling Interactor directly
  • ✗ ViewController instantiating other ViewControllers

Protocol-Based Communication

Rambler's ViperMcFlurry Pattern:

// Module Input (parent → child communication)
protocol WeatherModuleInput: RamblerViperModuleInput {
    func configureWithLocation(_ location: String)
}

// Module Output (child → parent communication)
protocol WeatherModuleOutput: RamblerViperModuleOutput {
    func weatherModuleDidSelectLocation(_ location: String)
}

// Presenter implements both
class WeatherPresenter: WeatherModuleInput {
    weak var view: WeatherViewInput?
    var interactor: WeatherInteractorInput?
    var router: WeatherRouterInput?
    var moduleOutput: WeatherModuleOutput?

    // From module input
    func configureWithLocation(_ location: String) {
        interactor?.fetchWeather(for: location)
    }
}

// View Protocol
protocol WeatherViewInput: AnyObject {
    func displayTemperature(_ text: String)
    func showLoading()
    func showError(_ message: String)
}

protocol WeatherViewOutput: AnyObject {
    func viewDidLoad()
    func didTapRefresh()
}

// Interactor Protocols
protocol WeatherInteractorInput: AnyObject {
    func fetchWeather(for location: String)
}

protocol WeatherInteractorOutput: AnyObject {
    func didFetchWeather(_ data: WeatherData)
    func didFailWithError(_ error: Error)
}

Rambler Ecosystem Tools

Generamba - Code generator for VIPER modules

gem install generamba
generamba setup
generamba gen WeatherModule rviper_controller

Creates consistent module structure with all protocols and classes.

ViperMcFlurry - Framework for module assembly

  • Provides RamblerViperModuleInput and RamblerViperModuleOutput base protocols
  • Enables factory-based and segue-based module creation
  • Handles module configuration through chaining pattern

Typhoon - Dependency injection (used in Rambler's three-layer architecture)

  • Presentation layer: VIPER
  • BusinessLogic layer: Service-Oriented Architecture
  • Core layer: Compound operations

Testing Strategy (TDD-Friendly)

Order: Interactor → Presenter → View

1. Test Interactor First (pure business logic, no UI):

func testFetchWeatherRequestsDataFromCorrectLocation() {
    let mockDataManager = MockWeatherDataManager()
    interactor.dataManager = mockDataManager

    interactor.fetchWeather(for: "San Francisco")

    XCTAssertEqual(mockDataManager.requestedLocation, "San Francisco")
}

2. Then Test Presenter (data formatting):

func testDidFetchWeatherFormatsTemperatureCorrectly() {
    let mockView = MockWeatherView()
    presenter.view = mockView

    presenter.didFetchWeather(WeatherData(temperature: 20))

    XCTAssertEqual(mockView.displayedTemperature, "68°F")
}

3. Finally Test View (UI state):

func testDisplayTemperatureUpdatesLabel() {
    view.displayTemperature("72°F")

    XCTAssertEqual(view.temperatureLabel.text, "72°F")
}

Common Anti-Patterns

Anti-PatternWhy It's WrongCorrect Approach
Presenter accesses Core DataViolates layer separation, untestableMove to Interactor, use DataManager abstraction
View calls Interactor directlyBreaks mediation patternAll communication through Presenter
Passing NSManagedObject to PresenterEntity reaches Presentation layerTransform to simple struct/PONSO in Interactor
ViewController instantiates other VCsTight coupling, hard to test navigationRouter handles all navigation
Business logic in PresenterWrong layer, duplicates testing effortMove to Interactor

Example: Refactoring MVC to VIPER

Before (MVC - Massive View Controller):

class WeatherViewController: UIViewController {
    var weatherService = WeatherAPIService()

    func loadWeather() {
        weatherService.fetchWeather { weather in
            self.temperatureLabel.text = "\(weather.temperature)°"
        }
    }
}

After (VIPER - Proper Separation):

// View - Displays only
class WeatherViewController: UIViewController {
    var output: WeatherViewOutput?

    override func viewDidLoad() {
        output?.viewDidLoad()
    }
}

extension WeatherViewController: WeatherViewInput {
    func displayTemperature(_ text: String) {
        temperatureLabel.text = text
    }
}

// Presenter - Formats data
class WeatherPresenter: WeatherViewOutput {
    weak var view: WeatherViewInput?
    var interactor: WeatherInteractorInput?

    func viewDidLoad() {
        interactor?.fetchWeather()
    }

    func didFetchWeather(_ data: WeatherData) {
        let formatted = "\(Int(data.temperature))°F"
        view?.displayTemperature(formatted)
    }
}

// Interactor - Business logic
class WeatherInteractor: WeatherInteractorInput {
    weak var output: WeatherInteractorOutput?
    var dataManager: WeatherDataManager?

    func fetchWeather() {
        dataManager?.fetch { [weak self] result in
            switch result {
            case .success(let weather):
                self?.output?.didFetchWeather(weather)
            case .failure(let error):
                self?.output?.didFailWithError(error)
            }
        }
    }
}

Real-World Impact

Testability: Each layer testable in isolation without mocks for adjacent layers Maintainability: Clear boundaries prevent feature creep in components Team Scalability: Multiple developers can work on different modules without conflicts Code Reuse: Interactor logic works on iOS, iPadOS, macOS identically

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

29.3%
按下载量换算42

OpenCode

24.77%
按下载量换算36

Antigravity

18.02%
按下载量换算26

Codex

11.42%
按下载量换算17

Gemini CLI

7.81%
按下载量换算11

windsurf

3.39%
按下载量换算5

安全审计

Gen Agent Trust Hub

可疑

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。

来源信息

继续浏览同类 Skills