From 06cd1c41c53a4e584471d6b8604aff383d1aed30 Mon Sep 17 00:00:00 2001 From: KeyInfo Bot Date: Thu, 18 Jun 2026 16:22:09 +0800 Subject: [PATCH] =?UTF-8?q?Publish=20AGENTS.md=E7=94=9F=E6=88=90=E5=99=A8?= =?UTF-8?q?=20skill=20to=20marketplace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed. --- .agents/plugins/marketplace.json | 12 ++ .../codex/.agents/plugins/marketplace.json | 12 ++ .../.codex-plugin/plugin.json | 39 +++++ .../generate-agents-md/assets/market-icon.svg | 1 + .../skills/generate-agents-md/SKILL.md | 65 +++++++ .../generate-agents-md/agents/openai.yaml | 4 + .../references/agents-md-reference.md | 133 +++++++++++++++ .../scripts/validate_agents_md.py | 158 ++++++++++++++++++ 8 files changed, 424 insertions(+) create mode 100644 plugins/codex/plugins/generate-agents-md/.codex-plugin/plugin.json create mode 100644 plugins/codex/plugins/generate-agents-md/assets/market-icon.svg create mode 100644 plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/SKILL.md create mode 100644 plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/agents/openai.yaml create mode 100644 plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/references/agents-md-reference.md create mode 100644 plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/scripts/validate_agents_md.py diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index e1a1b718f..6fbe5a843 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -303,6 +303,18 @@ "authentication": "ON_INSTALL" }, "category": "开发工具" + }, + { + "name": "generate-agents-md", + "source": { + "source": "local", + "path": "./plugins/codex/plugins/generate-agents-md" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "知识库与检索" } ] } diff --git a/plugins/codex/.agents/plugins/marketplace.json b/plugins/codex/.agents/plugins/marketplace.json index 7098920a5..8a2a488fb 100644 --- a/plugins/codex/.agents/plugins/marketplace.json +++ b/plugins/codex/.agents/plugins/marketplace.json @@ -303,6 +303,18 @@ "authentication": "ON_INSTALL" }, "category": "开发工具" + }, + { + "name": "generate-agents-md", + "source": { + "source": "local", + "path": "./plugins/generate-agents-md" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "知识库与检索" } ] } diff --git a/plugins/codex/plugins/generate-agents-md/.codex-plugin/plugin.json b/plugins/codex/plugins/generate-agents-md/.codex-plugin/plugin.json new file mode 100644 index 000000000..bdea21ffd --- /dev/null +++ b/plugins/codex/plugins/generate-agents-md/.codex-plugin/plugin.json @@ -0,0 +1,39 @@ +{ + "name": "generate-agents-md", + "version": "0.1.0", + "description": "当需要创建、更新、标准化、审核或迁移 AGENTS.md 文件以及仓库级的 AI 智能体配置时使用,这些配置包括顶层指南或嵌套指南、项目入门相关内容、与 Claude/Copilot/Cursor 的兼容性设置,以及冗余上下文的清理工作。", + "author": { + "name": "EAPIL", + "url": "https://git.playones.com/arechen/EapilSkillMarket" + }, + "homepage": "https://git.playones.com/arechen/EapilSkillMarket", + "repository": "https://git.playones.com/arechen/EapilSkillMarket", + "license": "Proprietary", + "keywords": [ + "eapil", + "codex-skill", + "generate-agents-md" + ], + "skills": "./skills/", + "interface": { + "displayName": "AGENTS.md生成器", + "shortDescription": "当需要创建、更新、标准化、审核或迁移 AGENTS.md 文件以及仓库级的 AI 智能体配置时使用,这些配置包括顶层指南或嵌套指南、项目入门相关内容、与 Claude/Copilot/Cursor 的兼容性设置,以及冗余上下文的清理工作。", + "longDescription": "当需要创建、更新、标准化、审核或迁移 AGENTS.md 文件以及仓库级的 AI 智能体配置时使用,这些配置包括顶层指南或嵌套指南、项目入门相关内容、与 Claude/Copilot/Cursor 的兼容性设置,以及冗余上下文的清理工作。", + "developerName": "EAPIL", + "category": "知识库与检索", + "capabilities": [ + "Read", + "Write" + ], + "defaultPrompt": [ + "使用 AGENTS.md生成器 帮我完成这个任务。" + ], + "websiteURL": "https://git.playones.com/arechen/EapilSkillMarket", + "privacyPolicyURL": "https://git.playones.com/arechen/EapilSkillMarket", + "termsOfServiceURL": "https://git.playones.com/arechen/EapilSkillMarket", + "brandColor": "#2563EB", + "screenshots": [], + "composerIcon": "./assets/market-icon.svg", + "logo": "./assets/market-icon.svg" + } +} diff --git a/plugins/codex/plugins/generate-agents-md/assets/market-icon.svg b/plugins/codex/plugins/generate-agents-md/assets/market-icon.svg new file mode 100644 index 000000000..0d234e6dd --- /dev/null +++ b/plugins/codex/plugins/generate-agents-md/assets/market-icon.svg @@ -0,0 +1 @@ +AGENTS.md生成器 diff --git a/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/SKILL.md b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/SKILL.md new file mode 100644 index 000000000..410889887 --- /dev/null +++ b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/SKILL.md @@ -0,0 +1,65 @@ +--- +name: generate-agents-md +description: Use when Codex needs to create, refresh, standardize, audit, or migrate AGENTS.md files or repository-level AI agent instructions, including root or nested guides, project onboarding context, Claude/Copilot/Cursor compatibility, and context-bloat cleanup. +--- + +# Generate AGENTS.md + +## Overview + +Create lean, scoped, verifiable `AGENTS.md` files from repository facts. Treat root `AGENTS.md` as always-on context: a map and guardrail, not an encyclopedia. + +## Workflow + +1. **Scan facts before drafting.** Inspect existing `AGENTS.md`, `CLAUDE.md`, `.github/copilot-instructions.md`, tool rules, manifests, CI, key directories, and docs. Use `rg --files` first. Record unknowns instead of guessing. +2. **Extract only verifiable facts.** Commands must come from files such as `package.json`, `Makefile`, `pyproject.toml`, `Cargo.toml`, `go.mod`, CI workflows, or repo docs. Paths must exist. +3. **Choose the scope model.** + - Use one root file for small repos with shared commands and conventions. + - Use root plus child `AGENTS.md` files for monorepos or directories with distinct commands, risks, or conventions. + - Keep complex task workflows in skills or references, not in always-on `AGENTS.md`. +4. **Draft with the standard contract.** Read `references/agents-md-reference.md` for root and child templates, section guidance, and validation criteria. +5. **Update conservatively.** If `AGENTS.md` already exists, merge rather than replace. Preserve user-written sections unless they are clearly stale or conflict with verified facts. Show conflicts before changing them when possible. +6. **Validate before finishing.** Run the bundled validator when applicable: + +```bash +python path/to/generate-agents-md/scripts/validate_agents_md.py --repo /path/to/repo --file /path/to/repo/AGENTS.md +``` + +Also run repo-native markdown/prose checks if they exist. + +## Content Placement + +| Content | Put it in | +|---|---| +| Global project purpose, key paths, commands, completion checks, risk boundaries | Root `AGENTS.md` | +| Directory-specific commands, naming, tests, generated files, local risks | Child `AGENTS.md` | +| Long release/migration/audit workflows, repeated procedures, tool recipes | Skill or reference file | +| Human contributor background, product explanation, broad docs | `README.md` or `docs/` | + +## Quality Bar + +- Keep root files concise, usually under 200 lines. +- Use exact commands, exact paths, and concrete rules. +- Prefer `Always`, `Ask first`, and `Never` boundaries for risk. +- State user instructions override repo guidance; child files override parent files for their directory. +- Do not include secrets, internal credentials, or unverifiable environment assumptions. +- Do not invent commands, paths, tests, package managers, ownership, or architecture. + +## Final Response + +Report: + +- Files created or updated. +- Evidence used for commands and key paths. +- Validation commands run and results. +- Unknowns or items that need human confirmation. + +## Common Mistakes + +| Mistake | Fix | +|---|---| +| Root file repeats docs or long workflows | Move detail to child guides, skills, or references | +| Commands are tool names instead of runnable commands | Use exact invocations like `pnpm test` or `make check` | +| Child guide repeats parent rules | Keep only local differences | +| Existing custom guidance is overwritten | Merge and preserve non-conflicting user content | +| Placeholder text remains | Replace with verified facts or write `Unknown` in review notes, not in final guide | diff --git a/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/agents/openai.yaml b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/agents/openai.yaml new file mode 100644 index 000000000..3e82ca99c --- /dev/null +++ b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Generate AGENTS.md" + short_description: "Create lean project agent guides" + default_prompt: "Use $generate-agents-md to create a lean, verified AGENTS.md for this repository." diff --git a/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/references/agents-md-reference.md b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/references/agents-md-reference.md new file mode 100644 index 000000000..d9e0260a1 --- /dev/null +++ b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/references/agents-md-reference.md @@ -0,0 +1,133 @@ +# AGENTS.md Reference + +Use this reference when drafting, updating, or auditing `AGENTS.md`. + +## Fact Sources + +| Need | Prefer these sources | +|---|---| +| Package manager and scripts | `package.json`, `pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`, `bun.lockb` | +| Python commands | `pyproject.toml`, `uv.lock`, `poetry.lock`, `requirements*.txt`, `tox.ini`, `noxfile.py` | +| Go/Rust/.NET/Java commands | `go.mod`, `Cargo.toml`, `*.csproj`, `pom.xml`, `build.gradle*` | +| CI expectations | `.github/workflows/*`, `.gitlab-ci.yml`, `azure-pipelines.yml`, `Jenkinsfile` | +| Architecture and boundaries | `README.md`, `CONTRIBUTING.md`, `docs/`, existing instruction files | +| Generated or dangerous paths | `.gitignore`, generator configs, migration dirs, infra dirs, lockfiles | + +Never promote a guessed command or path into final `AGENTS.md`. If a fact cannot be confirmed, omit it or list it as a final-response unknown. + +## Scope Decision + +Choose **root only** when: + +- The repo has one main stack and one set of commands. +- Directory conventions are uniform. +- A concise root guide can cover common tasks without local exceptions. + +Choose **root plus child guides** when: + +- The repo is a monorepo or has separate apps, services, docs, packages, or examples. +- Commands differ by directory. +- Generated files, migrations, security code, or public API contracts are localized. +- Parent guidance would become long because of local exceptions. + +Root files should orient. Child files should specialize. + +## Root Template + +```markdown +# Project Agent Guide + +## Project Overview +[1-3 factual sentences: project type, primary stack, most important working constraint.] + +## Scope +- This file applies to the whole repository. +- More specific `AGENTS.md` files in subdirectories override this file for their paths. +- User instructions in the current task override repository guidance. + +## Quick Commands +- Install: `[exact command]` +- Dev: `[exact command]` +- Test: `[exact command]` +- Lint: `[exact command]` +- Build: `[exact command]` +- Typecheck: `[exact command]` + +## Key Paths +- `path/` - purpose +- `path/file.ext` - purpose + +## Architecture Boundaries +- [Concrete boundary or dependency rule.] +- [High-risk area and why it matters.] + +## Conventions +- [Style, naming, formatting, import, or documentation rule that is specific to this repo.] +- [Testing expectation that is actually supported by the repo.] + +## Definition of Done +- Run `[exact command]` before finishing changes that touch [scope]. +- If a required command cannot run, report the reason and the expected follow-up. + +## Boundaries +- Always: [concrete safe behavior] +- Ask first: [dependency, schema, CI, public API, security, data migration, billing, destructive operation] +- Never: [secrets, generated/vendor edits, broad refactors without request] + +## Child Guides +- `subsystem/AGENTS.md` - local rules for [subsystem] + +## References +- `docs/file.md` - when to read it +``` + +Remove sections that have no verified content. Do not leave placeholder text. + +## Child Template + +```markdown +# Local Agent Guide + +## Local Purpose +[What this directory owns. Keep it factual.] + +## Inherits +- Follow the nearest parent `AGENTS.md` unless this file gives a more specific local rule. + +## Local Commands +- Test: `[exact command]` +- Lint: `[exact command]` + +## Local Conventions +- [Naming, code organization, generated files, docs, or test placement specific to this path.] + +## Local Risks +- Ask first: [local high-risk changes] +- Never: [local forbidden edits] +``` + +If a child directory has no distinct commands, omit `Local Commands` rather than inventing commands. + +## Scoring Checklist + +A strong guide passes these checks: + +- **Specific:** Every command and path is concrete. +- **Verified:** Commands and paths trace to repository files. +- **Scoped:** Root guidance stays global; child guidance contains only local differences. +- **Short:** Root is usually under 200 lines and avoids long procedures. +- **Actionable:** A new agent can find the right files, run the right checks, and avoid high-risk edits. +- **Compatible:** It states parent/child precedence and user-instruction precedence. +- **Maintainable:** It avoids duplicated docs and points to references for deep background. + +## Audit Signals + +Flag these during updates: + +- `TODO`, `TBD`, `FIXME`, bracket placeholders, or template language. +- Commands that do not exist in manifests, Makefiles, CI, or docs. +- Paths that no longer exist. +- Duplicated or conflicting parent/child rules. +- Long release, migration, or audit procedures in the root guide. +- Tool-specific assumptions presented as cross-tool rules. +- Secrets, internal credentials, or sensitive environment details. diff --git a/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/scripts/validate_agents_md.py b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/scripts/validate_agents_md.py new file mode 100644 index 000000000..b80d7d9e3 --- /dev/null +++ b/plugins/codex/plugins/generate-agents-md/skills/generate-agents-md/scripts/validate_agents_md.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +"""Lightweight AGENTS.md validator. + +Checks for common problems before an agent guide is treated as done: +missing sections, placeholders, nonexistent referenced paths, and package +manager commands that do not map to package.json scripts. +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from pathlib import Path + + +PLACEHOLDER_RE = re.compile( + r"\b(TODO|TBD|FIXME|XXX|REVIEW_NEEDED)\b|" + r"\{\{[^}]+\}\}|" + r"<[^>\n]+>|" + r"\[[^\]\n]*(exact command|path|project|真实|项目类型|关键)[^\]\n]*\]", + re.IGNORECASE, +) + +CODE_SPAN_RE = re.compile(r"`([^`\n]+)`") +HEADING_RE = re.compile(r"^##\s+(.+?)\s*$", re.MULTILINE) + +ROOT_REQUIRED_HEADINGS = { + "Project Overview", + "Scope", + "Quick Commands", + "Key Paths", + "Definition of Done", + "Boundaries", +} + +LOCAL_REQUIRED_HEADINGS = { + "Local Purpose", + "Inherits", + "Local Conventions", + "Local Risks", +} + +PATH_HINT_RE = re.compile(r"(^\.{1,2}[\\/]|[\\/]|^[\w.-]+\.[A-Za-z0-9]+$)") +COMMAND_PREFIX_RE = re.compile( + r"^(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?([\w:.-]+)(?:\s|$)" +) + + +def load_package_scripts(repo: Path) -> dict[str, set[str]]: + scripts: dict[str, set[str]] = {} + for package_file in repo.rglob("package.json"): + if "node_modules" in package_file.parts: + continue + try: + data = json.loads(package_file.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + continue + package_scripts = data.get("scripts") + if isinstance(package_scripts, dict): + scripts[str(package_file.relative_to(repo))] = set(package_scripts) + return scripts + + +def normalize_path_token(token: str) -> str | None: + if token.startswith(("http://", "https://", "$")): + return None + if any(part in token for part in ("&&", "||", " --", " -")): + return None + if token in {"AGENTS.md", "CLAUDE.md", "README.md"}: + return token + if PATH_HINT_RE.search(token): + return token.rstrip("/") + return None + + +def path_exists(repo: Path, token: str) -> bool: + candidate = (repo / token).resolve() + try: + candidate.relative_to(repo.resolve()) + except ValueError: + return False + return candidate.exists() + + +def validate(args: argparse.Namespace) -> tuple[list[str], list[str]]: + repo = Path(args.repo).resolve() + guide = Path(args.file).resolve() + errors: list[str] = [] + warnings: list[str] = [] + + if not repo.exists(): + return [f"Repository path does not exist: {repo}"], warnings + if not guide.exists(): + return [f"Guide file does not exist: {guide}"], warnings + + text = guide.read_text(encoding="utf-8") + headings = set(HEADING_RE.findall(text)) + + required = LOCAL_REQUIRED_HEADINGS if args.local else ROOT_REQUIRED_HEADINGS + missing = sorted(required - headings) + if missing: + errors.append("Missing recommended headings: " + ", ".join(missing)) + + placeholders = sorted(set(match.group(0) for match in PLACEHOLDER_RE.finditer(text))) + if placeholders: + errors.append("Placeholder or review marker remains: " + ", ".join(placeholders[:10])) + + code_spans = CODE_SPAN_RE.findall(text) + for token in code_spans: + path_token = normalize_path_token(token.strip()) + if path_token and not path_exists(repo, path_token): + warnings.append(f"Referenced path may not exist: `{token}`") + + package_scripts = load_package_scripts(repo) + known_scripts = set().union(*package_scripts.values()) if package_scripts else set() + for token in code_spans: + match = COMMAND_PREFIX_RE.match(token.strip()) + if not match: + continue + script_name = match.group(1) + if script_name in {"install", "add", "remove", "exec", "dlx", "create"}: + continue + if known_scripts and script_name not in known_scripts: + warnings.append( + f"Package command references missing package.json script: `{token}`" + ) + + return errors, warnings + + +def main() -> int: + parser = argparse.ArgumentParser(description="Validate AGENTS.md guardrails.") + parser.add_argument("--repo", required=True, help="Repository root to validate against.") + parser.add_argument("--file", required=True, help="AGENTS.md file to validate.") + parser.add_argument("--local", action="store_true", help="Validate a child/local guide.") + parser.add_argument( + "--warnings-as-errors", + action="store_true", + help="Exit nonzero when warnings are present.", + ) + args = parser.parse_args() + + errors, warnings = validate(args) + for error in errors: + print(f"ERROR: {error}", file=sys.stderr) + for warning in warnings: + print(f"WARNING: {warning}", file=sys.stderr) + + if errors or (args.warnings_as_errors and warnings): + return 1 + print("AGENTS.md validation passed") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())