Token导航 LogoToken导航

Agent Skill · 研究检索

service-layer-extractor(服务层提取器)

service-layer-extractor 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

service-layer-extractor 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描有未通过项,按安装量在研究检索类的 73,675 个 Skill 里排第 72,323。

总安装 188周安装 8GitHub Stars 2下载 66核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:service-layer-extractor(服务层提取器)
来源仓库:https://github.com/monkey1sai/openai-cli
仓库路径:skills/service-layer-extractor
安装命令:
npx skills add https://github.com/monkey1sai/openai-cli --skill service-layer-extractor
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/monkey1sai/openai-cli --skill service-layer-extractor

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于查找、检索和筛选相关信息,根据关键词或任务场景定位候选结果。适合在需要快速定位来源线索时使用,可结合原始 README 核验用法。建议确认权限范围和维护状态,注意是否会触发联网或文件读写。

安装命令:npx skills add https://github.com/monkey1sai/openai-cli --skill service-layer-extractor 适用于 Codex、Claude、Cursor、Gemini CLI,通过 GitHub 安装

来源仓库内路径:skills/service-layer-extractor

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/monkey1sai/openai-cli --skill service-layer-ex…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

service-layer-extractor 怎么安装?

在终端执行 npx skills add https://github.com/monkey1sai/openai-cli --skill service-layer-extractor。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

service-layer-extractor 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

service-layer-extractor 需要什么权限?

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

service-layer-extractor 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

service-layer-extractor 用的人多吗?

公开数据是累计安装 188 次,近一周安装 8 次,下载 66 次,GitHub 2 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

service-layer-extractor 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
service-layer-extractor

服务层提取器 · 本页

1882需要联网未明确未通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Service Layer Extractor

Extract business logic from controllers into a testable service layer.

Architecture Layers

routes/          → Define endpoints, parse requests
controllers/     → Validate input, call services, format responses
services/        → Business logic, orchestration
repositories/    → Database queries
models/          → Data structures

Before: Fat Controller

// ❌ Business logic mixed with HTTP concerns
router.post("/users", async (req, res) => {
  try {
    // Validation
    if (!req.body.email) {
      return res.status(400).json({ error: "Email required" });
    }

    // Check duplicate
    const existing = await db.query("SELECT * FROM users WHERE email = $1", [
      req.body.email,
    ]);
    if (existing.rows.length > 0) {
      return res.status(409).json({ error: "Email already exists" });
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(req.body.password, 10);

    // Create user
    const result = await db.query(
      "INSERT INTO users (email, password, name) VALUES ($1, $2, $3) RETURNING *",
      [req.body.email, hashedPassword, req.body.name]
    );

    // Send welcome email
    await sendEmail(req.body.email, "Welcome!", "Thanks for joining");

    res.status(201).json(result.rows[0]);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

After: Service Layer

// ✅ Separated concerns

// services/user.service.ts
export class UserService {
  constructor(
    private userRepository: UserRepository,
    private emailService: EmailService
  ) {}

  async createUser(dto: CreateUserDto): Promise<User> {
    // Business logic only
    const existing = await this.userRepository.findByEmail(dto.email);
    if (existing) {
      throw new ConflictError("Email already exists");
    }

    const hashedPassword = await bcrypt.hash(dto.password, 10);

    const user = await this.userRepository.create({
      ...dto,
      password: hashedPassword,
    });

    await this.emailService.sendWelcome(user.email);

    return user;
  }
}

// controllers/user.controller.ts
export class UserController {
  constructor(private userService: UserService) {}

  create = asyncHandler(async (req, res) => {
    const user = await this.userService.createUser(req.body);
    res.status(201).json({ success: true, data: user });
  });
}

// repositories/user.repository.ts
export class UserRepository {
  async create(data: CreateUserData): Promise<User> {
    const result = await db.query(
      "INSERT INTO users (email, password, name) VALUES ($1, $2, $3) RETURNING *",
      [data.email, data.password, data.name]
    );
    return result.rows[0];
  }

  async findByEmail(email: string): Promise<User | null> {
    const result = await db.query("SELECT * FROM users WHERE email = $1", [
      email,
    ]);
    return result.rows[0] || null;
  }
}

Dependency Injection

// container.ts (using tsyringe or manual)
import { UserService } from "./services/user.service";
import { UserRepository } from "./repositories/user.repository";
import { EmailService } from "./services/email.service";

export class Container {
  private static instances = new Map();

  static get<T>(constructor: new (...args: any[]) => T): T {
    if (!this.instances.has(constructor)) {
      // Create dependencies
      const deps = this.resolveDependencies(constructor);
      this.instances.set(constructor, new constructor(...deps));
    }
    return this.instances.get(constructor);
  }

  private static resolveDependencies(constructor: any): any[] {
    // Resolve constructor dependencies
    return [];
  }
}

// Usage
const userService = Container.get(UserService);

Testing Services

// user.service.test.ts
describe("UserService", () => {
  let service: UserService;
  let mockRepository: jest.Mocked<UserRepository>;
  let mockEmailService: jest.Mocked<EmailService>;

  beforeEach(() => {
    mockRepository = {
      create: jest.fn(),
      findByEmail: jest.fn(),
    } as any;

    mockEmailService = {
      sendWelcome: jest.fn(),
    } as any;

    service = new UserService(mockRepository, mockEmailService);
  });

  it("creates user successfully", async () => {
    mockRepository.findByEmail.mockResolvedValue(null);
    mockRepository.create.mockResolvedValue({
      id: "1",
      email: "test@example.com",
    });

    const user = await service.createUser({
      email: "test@example.com",
      password: "password123",
      name: "Test User",
    });

    expect(user.id).toBe("1");
    expect(mockEmailService.sendWelcome).toHaveBeenCalled();
  });

  it("throws error if email exists", async () => {
    mockRepository.findByEmail.mockResolvedValue({ id: "1" } as User);

    await expect(
      service.createUser({
        email: "existing@example.com",
        password: "pass",
        name: "Test",
      })
    ).rejects.toThrow(ConflictError);
  });
});

Folder Structure

src/
├── routes/
│   └── users.routes.ts
├── controllers/
│   └── user.controller.ts
├── services/
│   ├── user.service.ts
│   ├── email.service.ts
│   └── payment.service.ts
├── repositories/
│   └── user.repository.ts
├── models/
│   └── user.model.ts
├── types/
│   └── user.types.ts
└── middleware/
    └── validate.ts

Migration Strategy

## Phase 1: Create Service Layer (Week 1-2)

- [ ] Create service classes
- [ ] Move business logic to services
- [ ] Keep controllers thin
- [ ] No breaking changes

## Phase 2: Add Tests (Week 3-4)

- [ ] Write service unit tests
- [ ] Mock dependencies
- [ ] Achieve 80%+ coverage

## Phase 3: Extract Repositories (Week 5-6)

- [ ] Create repository layer
- [ ] Move DB queries from services
- [ ] Services depend on repositories

## Phase 4: Dependency Injection (Week 7-8)

- [ ] Set up DI container
- [ ] Remove manual instantiation
- [ ] Wire up dependencies

Benefits

  • Testability: Services testable without HTTP
  • Reusability: Logic reused across endpoints
  • Separation: Clear boundaries between layers
  • Maintainability: Easier to locate and modify logic

Output Checklist

  • Service classes created
  • Business logic extracted from controllers
  • Repository layer for data access
  • Dependency injection setup
  • Unit tests for services
  • Folder structure reorganized
  • Migration plan documented
  • Team trained on new patterns

平台分布

Codex

36.61%
按下载量换算24

Claude

27.41%
按下载量换算18

Cursor

17.99%
按下载量换算12

Gemini CLI

10.47%
按下载量换算7

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

需要联网

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

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills