Borrowing it
Nothing to install: this file belongs to ArtisanCloud/PowerX. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/ArtisanCloud/PowerX/release/v1.0.0/.codex/skills/crud/handler-http/SKILL.mdgit clone --depth 1 https://github.com/ArtisanCloud/PowerXWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/artisancloud/powerx/handler-http)<a href="https://agentmods.dev/skills/artisancloud/powerx/handler-http"><img src="https://agentmods.dev/badge/skills/artisancloud/powerx/handler-http/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/artisancloud/powerx/handler-http"><img src="https://agentmods.dev/badge/skills/artisancloud/powerx/handler-http.svg" alt="Reviewed on agentmods" width="80" height="20"></a>- NVIDIA SkillSpector warn
SkillSpector: 2 findings, up to high
These are SkillSpector’s own severities. On a checked sample its high-severity flags on skills were ~96% false positives — a documented command, a public API, a “never do X” rule — so we show them as a caution to read, not a verdict. Why →
- high Tool Misuse · line 126 Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).Fix: Validate all tool parameters against an allowlist. Reject dangerous parameter values (shell=True, --force, -rf /) and use safe defaults.
- high Tool Misuse · line 204 Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).Fix: Validate all tool parameters against an allowlist. Reject dangerous parameter values (shell=True, --force, -rf /) and use safe defaults.
What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00023 | $0.02304 |
| Opus 5.5 | $0.00009 | $0.00922 |
| Sonnet 5.5 | $0.00005 | $0.00461 |
| Haiku 4.5 | $0.00002 | $0.00230 |
Grade A, and why
crud-handler-http scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 1mo ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 233 lines — stays where its author put it; the contents beside it link to each section on GitHub.
PowerX CRUD Handler HTTP
步骤
- 打开
本文件内嵌规则。 - 按规则执行实现/校对。
- 完成后按核对清单验收。
核对点
- 与 PowerX 当前代码结构、路径与命名一致。
- 仅在传输层/契约层做职责内改动,不跨层越界。
规则(内嵌)
handler_http.yaml
kind: ruleset
name: crud_handler_http
version: 1.0.0
owner: powerx
status: stable
meta:
intent: >
规范 HTTP Handler 的目录、职责与调用形态:参数绑定/校验 → 调用 Service → 统一回包/错误桥接,
禁止业务与 DB/外部 IO;分页、错误、SSE 事件与 REST 契约/DTO 对齐。
references:
- dev_crud_http_guides.md
- constitution.md
scope:
applies_to:
- "internal/transport/http/**/**_handler.go"
- "internal/transport/http/**/api.go"
principles:
- Handler 只做 绑定/校验 → 调 Service → 回包;禁止写业务、DB 或外部 IO。 # 指南·Handler职责
- DTO 独立于模型;参数绑定使用统一函数,错误使用 AppError 桥接返回。 # 指南·DTO/错误桥接
- 路由注册独立在 api.go;前缀使用 /api/v1/{admin|open|web}。 # 指南·路由与版本
- 多租户上下文来自中间件;缺失租户返回 400 语义,鉴权在 Service 落实。 # 宪章·多租户
checks:
# 目录 & 入口
- id: http.dir.shape
level: error
when:
glob: "internal/transport/http/**/api.go"
assert:
- must_define: "func Register*Routes(*gin.RouterGroup, *shared.Deps)"
- must_prefix_route_one_of: ["/api/v1/admin", "/api/v1/open", "/api/v1/web"]
# Handler 职责边界
- id: handler.no_db_or_io
level: error
when:
glob: "internal/transport/http/**/**_handler.go"
assert:
- must_not_import: ["database/sql","gorm.io/gorm","net/http"] # 允许 gin 但禁止直接 http client
- must_not_call: ["sql.DB","gorm.DB","http.DefaultClient.Do","os.Remove","ioutil.ReadAll"]
- must_define_like: "type *Handler struct { svc *service.* }" # 依赖仅指向 Service
- id: handler.ctor
level: error
when:
glob: "internal/transport/http/**/**_handler.go"
assert:
- must_define_like: "func New*Handler(*service.*) *"
- must_not_define: "func New*Handler(*gorm.DB)" # 禁止直注 DB
# 租户上下文与校验/绑定
- id: handler.binding_and_tenant
level: error
when:
glob: "internal/transport/http/**/**_handler.go"
assert:
- must_call_one_of: ["ValidateRequestWithContext(","ValidateAndBindWithContext("]
- must_call: ["reqctx.From(c)"] # 从中间件注入的上下文取 tenant/request_id
- on_missing_tenant_http: 400
# 统一回包与错误桥接
- id: handler.response_envelope
level: error
when:
glob: "internal/transport/http/**/**_handler.go"
assert:
- must_use_one_of: ["ResponseSuccess(","RespondOK(","RespondErrorFrom("]
- http_status_in: [200,201,204,400,401,403,404,409,429,500]
# 分页语义统一
- id: handler.pagination_contract
level: error
when:
glob: "internal/transport/http/**/**_handler.go"
assert:
- must_bind_dto: ["PaginationRequest"]
- must_return: ["ResponseList","PaginationResponse"]
# SSE/WS(若涉及)
- id: handler.sse_events
level: warn
when:
contains: "WriteToSSE("
assert:
- must_use_events:
["start","intent","plan","token","data","action","final","end","error","heartbeat"]
# 契约一致性(与 REST 资源路由)
- id: handler.crud_shape
level: error
when:
glob: "internal/transport/http/**/api.go"
assert:
- must_register_methods:
- 'POST ""'
- 'GET ""'
- 'GET "/:id"'
- 'PATCH "/:id"'
- 'DELETE "/:id"'
# 依赖注入(Deps)
- id: handler.deps_injection
level: error
when:
glob: "internal/transport/http/**/**_handler.go"
assert:
- must_reference: "*shared.Deps" # Handler 通过 Deps 链路拿到 svc(在 api.go 中)
- must_not_new_external_clients: true
acceptance:
checklist:
- "[ ] api.go 只做路由注册,使用 /api/v1/{admin|open|web} 前缀"
- "[ ] Handler 仅做绑定/校验/调用 Service/回包,不含 DB 与外部 IO"
- "[ ] 使用 ValidateRequestWithContext/RespondErrorFrom/ResponseSuccess 等统一工具"
- "[ ] 分页使用 PaginationRequest/PaginationResponse,列表用 ResponseList"
- "[ ] SSE 事件(若有)使用统一事件名"
- "[ ] 租户上下文来自中间件,缺失返回 400;鉴权/审计在 Service 层"
- "[ ] Handler 构造函数存在,依赖通过 *shared.Deps 提供 svc"
templates:
handler_go: |
package {{domain}}
import (
"github.com/gin-gonic/gin"
"github.com/ArtisanCloud/PowerX/internal/app/shared"
"github.com/ArtisanCloud/PowerX/internal/service/{{domain}}"
dto "{{module_path}}/internal/transport/http/{{layer}}/{{domain}}/dto"
"github.com/ArtisanCloud/PowerX/pkg/corex/iam/reqctx"
)
type {{Entity}}Handler struct {
svc *{{domain}}.{{Entity}}Service
}
func New{{Entity}}Handler(s *{{domain}}.{{Entity}}Service) *{{Entity}}Handler {
return &{{Entity}}Handler{svc: s}
}
// POST /{{domain}}/{{resource}}
func (h *{{Entity}}Handler) Create(c *gin.Context) {
ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}CreateReq{})
if err != nil { RespondErrorFrom(c, err); return }
out, err := h.svc.Create(ctx, rc.TenantID, rc.ActorID, rc.RequestID, rc.TraceID, rc.Payload)
if err != nil { RespondErrorFrom(c, err); return }
ResponseSuccess(c, out)
}
// GET /{{domain}}/{{resource}}
func (h *{{Entity}}Handler) List(c *gin.Context) {
ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}ListReq{})
if err != nil { RespondErrorFrom(c, err); return }
items, pg, err := h.svc.List(ctx, rc.TenantID, rc.Pagination, rc.Filters)
if err != nil { RespondErrorFrom(c, err); return }
ResponseSuccess(c, ResponseList{Items: items, Pagination: pg})
}
// GET /{{domain}}/{{resource}}/:id
func (h *{{Entity}}Handler) Get(c *gin.Context) {
ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}GetReq{})
if err != nil { RespondErrorFrom(c, err); return }
out, err := h.svc.Get(ctx, rc.TenantID, rc.ID)
if err != nil { RespondErrorFrom(c, err); return }
ResponseSuccess(c, out)
}
// PATCH /{{domain}}/{{resource}}/:id
func (h *{{Entity}}Handler) Update(c *gin.Context) {
ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}UpdateReq{})
if err != nil { RespondErrorFrom(c, err); return }
out, err := h.svc.Update(ctx, rc.TenantID, rc.ID, rc.Payload, rc.IfMatch) // 支持 If-Match/ETag(可选)
if err != nil { RespondErrorFrom(c, err); return }
ResponseSuccess(c, out)
}
// DELETE /{{domain}}/{{resource}}/:id
func (h *{{Entity}}Handler) Delete(c *gin.Context) {
ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}DeleteReq{})
if err != nil { RespondErrorFrom(c, err); return }
err = h.svc.Delete(ctx, rc.TenantID, rc.ID, rc.Force) // 默认为软删;Force 需权限
if err != nil { RespondErrorFrom(c, err); return }
ResponseSuccess(c, ResponseSuccess{OK: true})
}
api_go: |
package {{domain}}
import (
"github.com/gin-gonic/gin"
"github.com/ArtisanCloud/PowerX/internal/app/shared"
)
func Register{{Domain}}Routes(rg *gin.RouterGroup, deps *shared.Deps) {
h := New{{Entity}}Handler(deps.{{Entity}}Service)
g := rg.Group("/{{domain}}/{{resource}}")
{
g.POST("", h.Create)
g.GET("", h.List)
g.GET("/:id", h.Get)
g.PATCH("/:id", h.Update)
g.DELETE("/:id", h.Delete)
}
}
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 1mo ago First seen · 233 lines · 23 tokens per session scan A f15954fa42e9
crud-handler-http is a skill published in the GitHub repository ArtisanCloud/PowerX (382 stars, last pushed 2d ago), licensed Apache-2.0. It adds 23 tokens to every session and 2,304 once invoked, about $0.0001 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-04.
Other skills, from other repositories
fastapi
FastAPI best practices and conventions. Use when working with FastAPI APIs, Pydantic models, dependencies, streaming responses including Server-Sent Events (SSE), and serving frontend apps. Keeps FastAPI code clean and up to date with the latest features and patterns.
langbot-eba-adapter-dev
Build, refactor, and test LangBot platform adapters for the Event-Based Agents architecture. Use when adding or migrating Telegram, Discord, or other messaging platform adapters to the EBA adapter layout, validating unified event/message conversion, writing live adapter probes, or using standalone plugin runtime plus…
langbot-dev
Develop, build, and debug the LangBot core backend and web frontend. Use when working inside the LangBot repository — backend (Python/Quart, src/langbot/pkg), the Vite/React web UI, HTTP API controllers/services, Alembic migrations, or the MCP server. Covers the dev environment (uv, pnpm), repo layout, the API auth…
wxjava-module-selector
A decision guide for choosing the correct WxJava Maven module, dependency management file, and example for a WeChat use case. WxJava is a Java software development kit for services such as official accounts, mini programs, and payments.
wxjava-api-contributor
A contributor guide for adding or maintaining official WeChat API support in WxJava, a Java software development kit. It covers services, request and response data objects, data conversion, HTTP handling, starter configuration, and regression tests.
wxjava-integration-guide
A setup guide for connecting Java, Spring Boot, or Solon applications to WxJava, a Java software development kit for WeChat services. It covers choosing modules, adding dependencies, configuring accounts, and making an initial API call.