Token导航 LogoToken导航

Agent Skill · 待分类

services(services 命令行)

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

services 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 8,989。

总安装 267周安装 11GitHub Stars 101下载 87核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/dvf/opinionated-django --skill services

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

services 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。

安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。services 属于待分类类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/services

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/dvf/opinionated-django --skill services;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

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

常见问题

6 条

services 怎么安装?

在终端执行 npx skills add https://github.com/dvf/opinionated-django --skill services。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

services 支持哪些 AI 工具?

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

services 需要什么权限?

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

services 是免费的吗?

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

services 用的人多吗?

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

services 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

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

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

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

不太适合

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

待分类类 Skill 对比

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

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
services

services 命令行 · 本页

267101需要联网未明确通过

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

SKILL.md 原文

Services + svcs Dependency Injection

This project separates Django's framework concerns from business logic using a plain service layer, wired with the svcs service locator. The result:

  • Views are one-liners. They pull a wired service and call a method.
  • Services contain the business logic. They take repositories (and other services) via __init__, call methods on them, and return DTOs.
  • Services never import Django ORM or models. Every test can run without a database.
  • One registry, one get[T]() helper. The same call works in views, tasks, commands, anywhere.

Why svcs Instead of Module-Level Singletons or a Custom Container

  • svcs is a tiny, typed, well-maintained service locator — no metaclasses, no decorators, no framework coupling.
  • Factories are lazy: a service is constructed only when something asks for it.
  • Generic get[T](type[T]) -> T preserves types through IDE/type-checker inference.
  • Swapping an implementation in tests is a one-line factory override.
  • No import-order gymnastics: the registry is populated once at startup and then used by name.

The Registry — src/project/services.py

import svcs

from products.repositories.product import ProductRepository
from products.services.product import ProductService
from orders.repositories.order import OrderRepository
from orders.services.order import OrderService

registry = svcs.Registry()

# --- Repositories ---------------------------------------------------------
registry.register_factory(ProductRepository, ProductRepository)
registry.register_factory(OrderRepository, OrderRepository)

# --- Services (factories pull repos from the container) ------------------
def _product_service_factory(container: svcs.Container) -> ProductService:
    repo = container.get(ProductRepository)
    return ProductService(repo)

def _order_service_factory(container: svcs.Container) -> OrderService:
    repo = container.get(OrderRepository)
    product_repo = container.get(ProductRepository)
    return OrderService(repo, product_repo)

registry.register_factory(ProductService, _product_service_factory)
registry.register_factory(OrderService, _order_service_factory)

def get[T](service_type: type[T]) -> T:
    """Resolve a service from the registry. Works anywhere — views, tasks, commands, tests."""
    return svcs.Container(registry).get(service_type)

Patterns to follow:

  • Repositories register themselves. Use register_factory(Repo, Repo) — the class is its own factory because repositories take no constructor arguments.
  • Services register via a named factory. _<entity>_service_factory(container) resolves every dependency from the container and hands it to the service's __init__. No hidden imports, no module-level singletons.
  • Register in dependency order. Repos before services, lower-level services before higher-level ones. svcs doesn't enforce this, but it keeps the file readable.
  • One registry per project. Don't create ad-hoc registries — everything goes through project.services.registry.

Writing a Service

File: src/<app>/services/<entity>.py

from decimal import Decimal
from typing import List

from ..dtos.product import ProductDTO
from ..repositories.product import ProductRepository

class ProductService:
    def __init__(self, repo: ProductRepository):
        self.repo = repo

    def create_product(self, name: str, price: Decimal, stock: int) -> ProductDTO:
        return self.repo.create(name=name, price=price, stock=stock)

    def get_product(self, product_id: str) -> ProductDTO:
        return self.repo.get_by_id(product_id)

    def list_products(self) -> List[ProductDTO]:
        return self.repo.list_all()

Rules:

  • Dependencies come in through __init__. The service never instantiates its own repositories or services. If a service needs another service, pass it in.
  • Zero ORM. No .objects, no F() / Q(), no model imports, no select_related. All database access goes through a repository.
  • Every public method returns a DTO or list[DTO]. Never a model instance, never a queryset.
  • ID arguments are str. See the prefixed-ulids skill.
  • Business rules live here. Validation, orchestration across repositories, invariant checks, error raising — all of it.
  • Services are stateless. They hold references to their dependencies and nothing else. No caches, no counters, no module-level state.
  • Raise plain exceptions. Use ValueError, PermissionError, domain-specific exceptions — not Http404 or anything Django-flavored. The view layer turns them into HTTP responses.

Cross-Entity Logic

When a service method touches more than one aggregate — e.g. creating an order that decrements product stock — inject both repositories and orchestrate them. Example from OrderService:

class OrderService:
    def __init__(self, repo: OrderRepository, product_repo: ProductRepository):
        self.repo = repo
        self.product_repo = product_repo

    def create_order(self, items: List[Dict[str, Any]]) -> OrderDTO:
        for item in items:
            product = self.product_repo.get_by_id(item["product_id"])
            if product.stock < item["quantity"]:
                raise ValueError(
                    f"Insufficient stock for product {product.name}: "
                    f"requested {item['quantity']}, available {product.stock}"
                )

        order = self.repo.create(items=items)

        for item in items:
            self.product_repo.decrement_stock(item["product_id"], item["quantity"])

        return order

Notes:

  • The service orchestrates two repositories but touches zero ORM.
  • If a multi-repo write needs atomicity, wrap it in with transaction.atomic(): — that's one of the very few django.db imports allowed in a service.
  • Never call another service from inside a service unless that service is explicitly injected. No hidden get(...) calls inside service methods.

Resolving a Service

From a view (django-ninja)

from project.services import get
from project.types import AuthedRequest

@products_router.post("/", response={201: ProductDTO})
def create_product(request: AuthedRequest, payload: CreateProductIn):
    service = get(ProductService)
    return Status(201, service.create_product(**payload.dict()))

Annotating request as AuthedRequest (defined in src/project/types.py) makes the auth contract explicit and narrows request.user to a guaranteed-authenticated Django User. This is a typing contract, not runtime enforcement — auth is still expected to be wired via middleware or ninja's auth= parameter.

From a Celery task

from celery import shared_task

from project.services import get
from products.services.product import ProductService

@shared_task
def reprice_product(product_id: str, new_price: str) -> None:
    service = get(ProductService)
    service.update_price(product_id, Decimal(new_price))

From a management command

from django.core.management.base import BaseCommand

from project.services import get
from products.services.product import ProductService

class Command(BaseCommand):
    def handle(self, *args, **options):
        service = get(ProductService)
        for dto in service.list_products():
            self.stdout.write(dto.name)

The same get() call works in all three contexts because the registry is global and the container is cheap to construct.

Testing

Services are tested without a database. Pass in a MagicMock for each repository, configure its return values, and assert on the service's behavior.

from decimal import Decimal
from unittest.mock import MagicMock

import pytest

from products.dtos.product import ProductDTO
from products.services.product import ProductService

def test_create_product_delegates_to_repo():
    repo = MagicMock()
    expected = ProductDTO(id="prd_fake", name="Widget", price=Decimal("9.99"), stock=5)
    repo.create.return_value = expected

    service = ProductService(repo)
    result = service.create_product(name="Widget", price=Decimal("9.99"), stock=5)

    assert result is expected
    repo.create.assert_called_once_with(name="Widget", price=Decimal("9.99"), stock=5)

def test_create_order_rejects_insufficient_stock():
    order_repo = MagicMock()
    product_repo = MagicMock()
    product_repo.get_by_id.return_value = ProductDTO(
        id="prd_fake", name="Widget", price=Decimal("9.99"), stock=1
    )

    service = OrderService(order_repo, product_repo)

    with pytest.raises(ValueError, match="Insufficient stock"):
        service.create_order(items=[{"product_id": "prd_fake", "quantity": 5}])

    order_repo.create.assert_not_called()

This is the most important test layer — it proves the business logic is correct independently of Django, migrations, fixtures, or the database. If a service's tests need @pytest.mark.django_db, something has leaked: find the ORM call and push it back into a repository.

Overriding a Service in Tests

For integration tests that go through the API, override a factory to substitute a fake or a stub:

from project.services import registry
from products.services.product import ProductService

@pytest.fixture
def fake_product_service():
    fake = MagicMock(spec=ProductService)
    registry.register_factory(ProductService, lambda _: fake)
    yield fake
    # svcs re-registers on next call; reset to the real factory if other tests need it.

Common Mistakes

  • Importing models in a service. If you see from app.models import X, the service is doing ORM work. Move it to the repository.
  • Calling SomeRepository() inside a service method. Inject it via __init__ and hold the reference.
  • Returning querysets or model instances from a service. Always return DTOs.
  • Putting business logic in the view. The view should only decode input, call get(SomeService).method(...), and pass the result back.
  • Registering a service with register_factory(Service, Service). That only works for repositories because they take no arguments. Services need a factory that resolves their dependencies.
  • Reaching into request.user from the service. Pass the caller's identity as an explicit argument (user_id: str) so the service stays framework-agnostic.

Verify

  • Every service under src/<app>/services/ has an __init__ that takes its dependencies explicitly.
  • No file under src/<app>/services/ imports from django.db.models, <app>.models, or uses .objects.
  • Every service in the project is registered in src/project/services.py with a factory that resolves its dependencies from the container.
  • Service tests do not use @pytest.mark.django_db.
uv run ruff check src
uv run pyrefly check src
uv run pytest

平台分布

Codex

34.69%
按下载量换算30

Claude

30.74%
按下载量换算27

Cursor

19.73%
按下载量换算17

Gemini CLI

10.13%
按下载量换算9

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

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

安装前确认

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

继续浏览同类 Skills