Token导航 LogoToken导航

Agent Skill · 开发

erpnext-impl-hooks(erpnext impl 钩子)

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

erpnext-impl-hooks 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 12,891。

总安装 1,093周安装 46GitHub Stars 87下载 383核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/openaec-foundation/erpnext_anthropic_claude_development_skill_package --skill erpnext-impl-hooks

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

帮助确定 hooks.py 的具体实现方式,包括文档事件与定时任务的注册方法。适用于 Codex、Claude、Cursor、Gemini CLI 中响应其他应用的数据变更事件。可查阅原始文档了解 doc_events 与 scheduler_events 的配置格式和调度粒度。

使用前需评估事件频率和资源消耗,防止高频钩子拖慢系统性能。erpnext-impl-hooks 属于开发类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/erpnext-impl-hooks

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

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

常见问题

6 条

erpnext-impl-hooks 怎么安装?

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

erpnext-impl-hooks 支持哪些 AI 工具?

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

erpnext-impl-hooks 需要什么权限?

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

erpnext-impl-hooks 是免费的吗?

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

erpnext-impl-hooks 用的人多吗?

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

erpnext-impl-hooks 安全吗?

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

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

值得选的地方

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

先想清楚的地方

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

适不适合你

更适合

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

不太适合

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

开发类 Skill 对比

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

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
erpnext-impl-hooks

erpnext impl 钩子 · 本页

1,09387需要联网未明确通过

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

SKILL.md 原文

ERPNext Hooks - Implementation

This skill helps you determine HOW to implement hooks.py configurations. For exact syntax, see erpnext-syntax-hooks.

Version: v14/v15/v16 compatible (with V16-specific features noted)

Main Decision: What Are You Trying to Do?

┌─────────────────────────────────────────────────────────────────────────┐
│ WHAT DO YOU WANT TO ACHIEVE?                                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│ ► React to document events on OTHER apps' DocTypes?                     │
│   └── doc_events in hooks.py                                            │
│                                                                         │
│ ► Run code periodically (hourly, daily, custom schedule)?               │
│   └── scheduler_events                                                  │
│                                                                         │
│ ► Modify behavior of existing DocType controller?                       │
│   ├── V16+: extend_doctype_class (RECOMMENDED - multiple apps work)     │
│   └── V14/V15: override_doctype_class (last app wins)                   │
│                                                                         │
│ ► Modify existing API endpoint behavior?                                │
│   └── override_whitelisted_methods                                      │
│                                                                         │
│ ► Add custom permission logic?                                          │
│   ├── List filtering: permission_query_conditions                       │
│   └── Document-level: has_permission                                    │
│                                                                         │
│ ► Send data to client on page load?                                     │
│   └── extend_bootinfo                                                   │
│                                                                         │
│ ► Export/import configuration between sites?                            │
│   └── fixtures                                                          │
│                                                                         │
│ ► Add JS/CSS to desk or portal?                                         │
│   ├── Desk: app_include_js/css                                          │
│   ├── Portal: web_include_js/css                                        │
│   └── Specific form: doctype_js                                         │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Decision Tree: doc_events vs Controller Methods

WHERE IS THE DOCTYPE?
│
├─► DocType is in YOUR custom app?
│   └─► Use controller methods (doctype/xxx/xxx.py)
│       - Direct control over lifecycle
│       - Cleaner code organization
│
├─► DocType is in ANOTHER app (ERPNext, Frappe)?
│   └─► Use doc_events in hooks.py
│       - Only way to hook external DocTypes
│       - Can register multiple handlers
│
└─► Need to hook ALL DocTypes (logging, audit)?
    └─► Use doc_events with wildcard "*"

Rule: Controller methods for YOUR DocTypes, doc_events for OTHER apps' DocTypes.


Decision Tree: Which doc_event?

WHAT DO YOU NEED TO DO?
│
├─► Validate data or calculate fields?
│   ├─► Before any save → validate
│   └─► Only on new documents → before_insert
│
├─► React after document is saved?
│   ├─► Only first save → after_insert
│   ├─► Every save → on_update
│   └─► ANY change (including db_set) → on_change
│
├─► Handle submittable documents?
│   ├─► Before submit → before_submit
│   ├─► After submit → on_submit (ledger entries here)
│   ├─► Before cancel → before_cancel
│   └─► After cancel → on_cancel (reverse entries here)
│
├─► Handle document deletion?
│   ├─► Before delete (can prevent) → on_trash
│   └─► After delete (cleanup) → after_delete
│
└─► Handle document rename?
    ├─► Before rename → before_rename
    └─► After rename → after_rename

Decision Tree: Scheduler Event Type

HOW LONG DOES YOUR TASK RUN?
│
├─► < 5 minutes
│   │
│   │ HOW OFTEN?
│   ├─► Every ~60 seconds → all
│   ├─► Every hour → hourly
│   ├─► Every day → daily
│   ├─► Every week → weekly
│   ├─► Every month → monthly
│   └─► Specific time → cron
│
└─► > 5 minutes (up to 25 minutes)
    │
    │ HOW OFTEN?
    ├─► Every hour → hourly_long
    ├─► Every day → daily_long
    ├─► Every week → weekly_long
    └─► Every month → monthly_long

⚠️ Tasks > 25 minutes: Split into chunks or use background jobs

Decision Tree: Override vs Extend (V16)

FRAPPE VERSION?
│
├─► V16+
│   │
│   │ WHAT DO YOU NEED?
│   ├─► Add methods/properties to DocType?
│   │   └─► extend_doctype_class (RECOMMENDED)
│   │       - Multiple apps can extend same DocType
│   │       - Safer, less breakage on updates
│   │
│   └─► Completely replace controller logic?
│       └─► override_doctype_class (use sparingly)
│
└─► V14/V15
    └─► override_doctype_class (only option)
        ⚠️ Last installed app wins!
        ⚠️ Always call super() in methods!

Implementation Workflow: doc_events

Step 1: Add to hooks.py

# myapp/hooks.py
doc_events = {
    "Sales Invoice": {
        "validate": "myapp.events.sales_invoice.validate",
        "on_submit": "myapp.events.sales_invoice.on_submit"
    }
}

Step 2: Create handler module

# myapp/events/sales_invoice.py
import frappe

def validate(doc, method=None):
    """
    Args:
        doc: The document object
        method: Event name ("validate")

    Changes to doc ARE saved (before save event)
    """
    if doc.grand_total < 0:
        frappe.throw("Total cannot be negative")

    # Calculate custom field
    doc.custom_margin = doc.grand_total - doc.total_cost

def on_submit(doc, method=None):
    """
    After submit - document already saved
    Use frappe.db.set_value for additional changes
    """
    create_external_record(doc)

Step 3: Deploy

bench --site sitename migrate

Implementation Workflow: scheduler_events

Step 1: Add to hooks.py

# myapp/hooks.py
scheduler_events = {
    "daily": ["myapp.tasks.daily_cleanup"],
    "daily_long": ["myapp.tasks.heavy_processing"],
    "cron": {
        "0 9 * * 1-5": ["myapp.tasks.weekday_report"]
    }
}

Step 2: Create task module

# myapp/tasks.py
import frappe

def daily_cleanup():
    """NO arguments - scheduler calls with no args"""
    old_logs = frappe.get_all(
        "Error Log",
        filters={"creation": ["<", frappe.utils.add_days(None, -30)]},
        pluck="name"
    )
    for name in old_logs:
        frappe.delete_doc("Error Log", name)

def heavy_processing():
    """Long task - use _long variant in hooks"""
    for batch in get_batches():
        process_batch(batch)
        frappe.db.commit()  # Commit per batch for long tasks

Step 3: Deploy and verify

bench --site sitename migrate
bench --site sitename scheduler enable
bench --site sitename scheduler status

Implementation Workflow: extend_doctype_class (V16+)

Step 1: Add to hooks.py

# myapp/hooks.py
extend_doctype_class = {
    "Sales Invoice": ["myapp.extensions.SalesInvoiceMixin"]
}

Step 2: Create mixin class

# myapp/extensions.py
import frappe
from frappe.model.document import Document

class SalesInvoiceMixin(Document):
    """Mixin that extends Sales Invoice"""

    @property
    def profit_margin(self):
        """Add computed property"""
        if self.grand_total:
            return ((self.grand_total - self.total_cost) / self.grand_total) * 100
        return 0

    def validate(self):
        """Extend validation - ALWAYS call super()"""
        super().validate()
        self.validate_margin()

    def validate_margin(self):
        """Custom validation logic"""
        if self.profit_margin < 10:
            frappe.msgprint("Warning: Low margin invoice")

Step 3: Deploy

bench --site sitename migrate

Implementation Workflow: Permission Hooks

Step 1: Add to hooks.py

# myapp/hooks.py
permission_query_conditions = {
    "Sales Invoice": "myapp.permissions.si_query"
}
has_permission = {
    "Sales Invoice": "myapp.permissions.si_permission"
}

Step 2: Create permission handlers

# myapp/permissions.py
import frappe

def si_query(user):
    """
    Returns SQL WHERE clause for list filtering.
    ONLY works with get_list, NOT get_all!
    """
    if not user:
        user = frappe.session.user

    if "Sales Manager" in frappe.get_roles(user):
        return ""  # No filter - see all

    # Regular users see only their own
    return f"`tabSales Invoice`.owner = {frappe.db.escape(user)}"

def si_permission(doc, user=None, permission_type=None):
    """
    Document-level permission check.
    Return: True (allow), False (deny), None (use default)

    NOTE: Can only DENY, not grant additional permissions!
    """
    if permission_type == "write" and doc.status == "Closed":
        return False  # Deny write on closed invoices

    return None  # Use default permission system

Quick Reference: Handler Signatures

HookSignature
doc_eventsdef handler(doc, method=None):
rename eventsdef handler(doc, method, old, new, merge):
scheduler_eventsdef handler(): (no args)
extend_bootinfodef handler(bootinfo):
permission_querydef handler(user): → returns SQL string
has_permissiondef handler(doc, user=None, permission_type=None): → True/False/None
override methodsMust match original signature exactly

Critical Rules

1. Never commit in doc_events

# ❌ WRONG - breaks transaction
def on_update(doc, method=None):
    frappe.db.commit()

# ✅ CORRECT - Frappe commits automatically
def on_update(doc, method=None):
    update_related(doc)

2. Use db_set_value after on_update

# ❌ WRONG - change is lost
def on_update(doc, method=None):
    doc.status = "Processed"

# ✅ CORRECT
def on_update(doc, method=None):
    frappe.db.set_value(doc.doctype, doc.name, "status", "Processed")

3. Always call super() in overrides

# ❌ WRONG - breaks core functionality
class CustomInvoice(SalesInvoice):
    def validate(self):
        self.my_validation()

# ✅ CORRECT
class CustomInvoice(SalesInvoice):
    def validate(self):
        super().validate()  # FIRST!
        self.my_validation()

4. Always migrate after hooks changes

# Required after ANY hooks.py change
bench --site sitename migrate

5. permission_query only works with get_list

# ❌ NOT filtered by permission_query_conditions
frappe.db.get_all("Sales Invoice", filters={})

# ✅ Filtered by permission_query_conditions
frappe.db.get_list("Sales Invoice", filters={})

Version Differences

FeatureV14V15V16
doc_events✅✅✅
scheduler_events✅✅✅
override_doctype_class✅✅✅
extend_doctype_class❌❌✅
permission hooks✅✅✅
Scheduler tick4 min4 min60 sec

Reference Files

FileContents
decision-tree.mdComplete hook selection flowcharts
workflows.mdStep-by-step implementation patterns
examples.mdWorking code examples
anti-patterns.mdCommon mistakes and solutions

平台分布

Codex

33.96%
按下载量换算130

Claude

29.69%
按下载量换算114

Cursor

17.69%
按下载量换算68

Gemini CLI

9.2%
按下载量换算35

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

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

安装前确认

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

继续浏览同类 Skills