From 0d511d9a03c659e1b73169590ed1158f4c096a6b Mon Sep 17 00:00:00 2001 From: zeaslity Date: Thu, 22 Jan 2026 10:26:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9ESHELL=E5=BE=97SKILL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../developing-project-management/SKILL.md | 2 +- 1-AgentSkills/writing-bash-scripts/SKILL.md | 204 ++++++++++ .../examples/minimal-template.sh | 362 ++++++++++++++++++ .../reference/code-structure.md | 121 ++++++ .../reference/exit-codes.md | 99 +++++ .../reference/function-template.md | 187 +++++++++ .../scripts/shellcheck-wrapper.sh | 79 ++++ 13-SHELL脚本/shell-prompt-2.md | 81 ++++ 13-SHELL脚本/shell-prompt.md | 18 + 2-需求转换专业设计/Prompt转换AgentSkill.md | 3 +- ProjectAGiPrompt.iml | 1 + 11 files changed, 1154 insertions(+), 3 deletions(-) create mode 100644 1-AgentSkills/writing-bash-scripts/SKILL.md create mode 100644 1-AgentSkills/writing-bash-scripts/examples/minimal-template.sh create mode 100644 1-AgentSkills/writing-bash-scripts/reference/code-structure.md create mode 100644 1-AgentSkills/writing-bash-scripts/reference/exit-codes.md create mode 100644 1-AgentSkills/writing-bash-scripts/reference/function-template.md create mode 100644 1-AgentSkills/writing-bash-scripts/scripts/shellcheck-wrapper.sh create mode 100644 13-SHELL脚本/shell-prompt-2.md create mode 100644 13-SHELL脚本/shell-prompt.md diff --git a/1-AgentSkills/developing-project-management/SKILL.md b/1-AgentSkills/developing-project-management/SKILL.md index 1ba8754..e33177e 100644 --- a/1-AgentSkills/developing-project-management/SKILL.md +++ b/1-AgentSkills/developing-project-management/SKILL.md @@ -1,6 +1,6 @@ --- name: developing-project-management -description: Guides development of rmdc-project-management module including project lifecycle management, version control (Git-like), ACL permissions, TOTP authorization, and workflow integration. Triggered when modifying project CRUD, draft/version APIs, permission grants, or authorization features. Keywords: project lifecycle, version snapshot, ACL, TOTP, workflow callback, SuperAdmin. +description: Guides development of rmdc-project-management module including project lifecycle management, version control (Git-like), ACL permissions, TOTP authorization, and workflow integration. Triggered when modifying project CRUD, draft/version APIs, permission grants, or authorization features. Keywords: project mangement, project lifecycle, version snapshot, ACL, TOTP, workflow callback, SuperAdmin. argument-hint: " [target]" where change-type is one of: api|entity|service|migration|frontend|auth. Example: "api draft-submit" or "migration add-field" allowed-tools: - Read diff --git a/1-AgentSkills/writing-bash-scripts/SKILL.md b/1-AgentSkills/writing-bash-scripts/SKILL.md new file mode 100644 index 0000000..976281d --- /dev/null +++ b/1-AgentSkills/writing-bash-scripts/SKILL.md @@ -0,0 +1,204 @@ +--- +name: writing-bash-scripts +description: Generates production-grade Bash scripts with strict mode, modular structure, unified logging, error handling, and ShellCheck compliance. Triggered by requests like "write a bash script", "create shell script", "generate CLI tool in bash". Keywords: bash, shell, script, devops. +argument-hint: "" +allowed-tools: + - Read + - Write + - Bash + - Glob + - Grep +--- + +# Writing Production-Grade Bash Scripts + +## Purpose +Transform functional requirements into a single, deployable Bash script following engineering best practices. + +## Arguments +`$ARGUMENTS` = functional requirement description (目标、输入/输出、流程、约束、示例数据等) + +If `$ARGUMENTS` is empty, prompt user for: +- Target functionality +- Input/output specification +- Constraints (OS, permissions, dependencies) + +## Dynamic Context + +!`echo "Current working directory: $(pwd)"` + +!`bash --version | head -1` + +--- + +## Plan Phase + +### Deliverables Checklist +- [ ] Single `.sh` file with shebang `#!/usr/bin/env bash` +- [ ] Bash >= 5.0 requirement documented +- [ ] ASCII call graph at script top +- [ ] usage/help function (-h/--help) +- [ ] Parameter parsing (getopts) +- [ ] Exit code documentation +- [ ] --dry-run support +- [ ] --verbose/--quiet support +- [ ] Cleanup trap for temp files + +### Decision Points +| Decision | Default | Override Condition | +|----------|---------|-------------------| +| POSIX vs Bash-specific | POSIX preferred | Use Bash features only when necessary (arrays, `[[ ]]`, mapfile); comment reason | +| Destructive ops | Require `--force` | Never auto-delete without confirmation | +| Temp file location | `mktemp -d` | User-specified via `--tmp-dir` | + +--- + +## Execute Phase + +### Script Structure (固定顺序) + +``` +1. Shebang + Metadata +2. ASCII Call Graph +3. Global Constants (readonly) +4. Strict Mode Setup +5. Dependency/Environment Checks +6. Logging & Error Handling Functions +7. Business Functions +8. main() + Entry Point +9. Self-test Examples (comments) +``` + +### Strict Mode (必须) +```bash +set -Eeuo pipefail +IFS=$' \t\n' +``` + +### Required Functions + +| Function | Purpose | +|----------|---------| +| `usage` | Print help with examples | +| `die` | `die ` - unified error exit | +| `log_debug/info/warn/error` | Timestamped logging with LOG_LEVEL control | +| `run_cmd` | Command wrapper: dry-run, retry, error capture | +| `cleanup` | Remove temp files/locks on EXIT/ERR/INT/TERM | + +### Function Documentation Format +```bash +### +### @param +### @return +### @require +### @side_effect +function_name() { + ... +} +``` + +### Exit Codes +| Code | Meaning | +|------|---------| +| 0 | Success | +| 1 | General error | +| 2 | Invalid arguments | +| 3 | Missing dependency | +| 4 | Permission denied | +| 5 | File/resource not found | +| 126 | Command not executable | +| 127 | Command not found | + +> See `reference/exit-codes.md` for extended codes. + +### Logging Format +``` +[YYYY-MM-DD HH:MM:SS] [LEVEL] message +``` + +--- + +## Verify Phase + +### Pre-Delivery Checklist + +#### Frontmatter & Structure +- [ ] Shebang is `#!/usr/bin/env bash` +- [ ] Bash version requirement stated +- [ ] ASCII call graph present +- [ ] Sections in correct order + +#### Safety & Defaults +- [ ] `set -Eeuo pipefail` enabled +- [ ] All variables double-quoted (except intentional word splitting with comment) +- [ ] No unquoted `$@` or `$*` +- [ ] No unsafe `eval` +- [ ] `--dry-run` implemented +- [ ] `--force` required for destructive ops +- [ ] `mktemp` used for temp files +- [ ] trap covers EXIT/ERR/INT/TERM + +#### Functions +- [ ] Every function has `###` doc block +- [ ] `@param`, `@return`, `@require` present +- [ ] snake_case naming +- [ ] Input validation on all external inputs + +#### Logging & Errors +- [ ] `log_*` functions implemented +- [ ] LOG_LEVEL controls output +- [ ] `die` includes line number and function stack +- [ ] `run_cmd` wrapper used for external commands + +#### Quality +- [ ] Passes ShellCheck (or disables with `# shellcheck disable=SCxxxx` + reason) +- [ ] 3+ self-test examples in comments (normal, error, dry-run) +- [ ] No hardcoded paths without override option + +### ShellCheck Validation +```bash +shellcheck -x -s bash +``` + +> Use `scripts/shellcheck-wrapper.sh` for automated checking. + +--- + +## Common Pitfalls + +| Pitfall | Fix | +|---------|-----| +| Unquoted variables in paths with spaces | Always `"$var"` | +| Missing `local` in functions | Declare with `local var=...` | +| Assuming GNU tools on macOS | Check `uname` or use portable flags | +| Ignoring exit code of piped commands | `set -o pipefail` + check `${PIPESTATUS[@]}` | +| Temp files left on error | Trap cleanup on ERR/EXIT | + +--- + +## Reference Files + +| When | Read | +|------|------| +| Need detailed code structure | `reference/code-structure.md` | +| Writing function docs | `reference/function-template.md` | +| Defining custom exit codes | `reference/exit-codes.md` | +| Starting from scratch | `examples/minimal-template.sh` | + +--- + +## Minimal Self-Test Commands + +```bash +# 1. Help +./script.sh --help + +# 2. Dry-run +./script.sh --dry-run + +# 3. Invalid argument (expect exit 2) +./script.sh --invalid-option + +# 4. Verbose mode +./script.sh --verbose +``` diff --git a/1-AgentSkills/writing-bash-scripts/examples/minimal-template.sh b/1-AgentSkills/writing-bash-scripts/examples/minimal-template.sh new file mode 100644 index 0000000..e1ba58e --- /dev/null +++ b/1-AgentSkills/writing-bash-scripts/examples/minimal-template.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash +#=============================================================================== +# Script Name : minimal-template.sh +# Description : Minimal production-grade Bash script template +# Author : +# Version : 1.0.0 +# License : MIT +# Last Updated : +# Bash Version : >= 5.0 +# +# Assumptions: +# - Running on Linux/macOS with GNU coreutils +# - UTF-8 locale available +#=============================================================================== + +#=============================================================================== +# ASCII CALL GRAPH +#=============================================================================== +# main() +# ├── parse_args() +# ├── check_dependencies() +# ├── setup_temp() +# ├── do_work() +# │ └── helper_function() +# └── cleanup() [via trap] +#=============================================================================== + +#=============================================================================== +# GLOBAL CONSTANTS +#=============================================================================== +readonly VERSION="1.0.0" +readonly SCRIPT_NAME="${0##*/}" +readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Exit codes +readonly E_SUCCESS=0 +readonly E_GENERAL=1 +readonly E_ARGS=2 +readonly E_DEPS=3 +readonly E_PERM=4 +readonly E_NOTFOUND=5 + +#=============================================================================== +# STRICT MODE +#=============================================================================== +set -Eeuo pipefail +IFS=$' \t\n' + +#=============================================================================== +# CONFIGURABLE DEFAULTS +#=============================================================================== +LOG_LEVEL="${LOG_LEVEL:-INFO}" +DRY_RUN=false +VERBOSE=false +FORCE=false +TEMP_DIR="" + +#=============================================================================== +# LOGGING & ERROR HANDLING +#=============================================================================== + +### Log message at DEBUG level +### @param message string Message to log +### @return 0 Always +log_debug() { + [[ "${LOG_LEVEL}" == "DEBUG" ]] || return 0 + printf '[%s] [DEBUG] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Log message at INFO level +### @param message string Message to log +### @return 0 Always +log_info() { + [[ "${LOG_LEVEL}" =~ ^(DEBUG|INFO)$ ]] || return 0 + printf '[%s] [INFO] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Log message at WARN level +### @param message string Message to log +### @return 0 Always +log_warn() { + [[ "${LOG_LEVEL}" =~ ^(DEBUG|INFO|WARN)$ ]] || return 0 + printf '[%s] [WARN] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Log message at ERROR level +### @param message string Message to log +### @return 0 Always +log_error() { + printf '[%s] [ERROR] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Exit with error message, location info, and exit code +### @param message string Error message +### @param exit_code int Exit code (default: 1) +### @return never Exits script +### @side_effect Terminates script +die() { + local message="$1" + local exit_code="${2:-$E_GENERAL}" + local caller_info="" + + # > Build caller info for debugging + if [[ "${BASH_LINENO[0]:-0}" -gt 0 ]]; then + caller_info=" (${FUNCNAME[1]:-main}:${BASH_LINENO[0]:-?})" + fi + + log_error "${message}${caller_info}" + exit "$exit_code" +} + +### Execute command with dry-run support +### @param cmd array Command and arguments +### @return 0 Success +### @return 1 Command failed +### @side_effect Executes external command +run_cmd() { + local -a cmd=("$@") + + if [[ "${DRY_RUN}" == "true" ]]; then + log_info "[DRY-RUN] Would execute: ${cmd[*]}" + return 0 + fi + + [[ "${VERBOSE}" == "true" ]] && log_debug "Executing: ${cmd[*]}" + + if ! "${cmd[@]}"; then + log_error "Command failed: ${cmd[*]}" + return 1 + fi +} + +### Cleanup temporary resources +### @return 0 Always +### @side_effect Removes temp directory +cleanup() { + local exit_code=$? + + if [[ -n "${TEMP_DIR:-}" && -d "${TEMP_DIR}" ]]; then + rm -rf "${TEMP_DIR}" + log_debug "Cleaned up temp dir: ${TEMP_DIR}" + fi + + exit "$exit_code" +} + +# > Set traps for cleanup on exit/error/interrupt +trap cleanup EXIT ERR INT TERM + +#=============================================================================== +# DEPENDENCY & ENVIRONMENT CHECKS +#=============================================================================== + +### Check Bash version meets minimum requirement +### @return 0 Version OK +### @return 1 Version too old +### @require Bash >= 5.0 +check_bash_version() { + local required_major=5 + local required_minor=0 + local current_major="${BASH_VERSINFO[0]}" + local current_minor="${BASH_VERSINFO[1]}" + + if (( current_major < required_major )) || \ + (( current_major == required_major && current_minor < required_minor )); then + die "Bash >= ${required_major}.${required_minor} required (current: ${current_major}.${current_minor})" "$E_DEPS" + fi +} + +### Check required external commands exist +### @return 0 All dependencies present +### @return 3 Missing dependency +check_dependencies() { + local -a required_cmds=("date" "mktemp" "rm") # > Add your dependencies here + local cmd + + for cmd in "${required_cmds[@]}"; do + if ! command -v "$cmd" &>/dev/null; then + die "Required command not found: $cmd" "$E_DEPS" + fi + done + + log_debug "All dependencies satisfied" +} + +#=============================================================================== +# HELPER FUNCTIONS +#=============================================================================== + +### Create temporary directory +### @return 0 Success +### @side_effect Sets TEMP_DIR global +setup_temp() { + TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/${SCRIPT_NAME}.XXXXXX")" + readonly TEMP_DIR + log_debug "Created temp dir: ${TEMP_DIR}" +} + +### Display usage information +### @return 0 Always +usage() { + cat < + +Description: + Brief description of what this script does. + +Options: + -h, --help Show this help message + -v, --verbose Enable verbose output + -q, --quiet Suppress non-error output + -n, --dry-run Show what would be done without executing + -f, --force Force operation (skip confirmations) + --version Show version information + +Arguments: + Description of required argument + +Examples: + ${SCRIPT_NAME} --help + ${SCRIPT_NAME} --dry-run input.txt + ${SCRIPT_NAME} --verbose --force input.txt + +Exit Codes: + 0 Success + 1 General error + 2 Invalid arguments + 3 Missing dependency + 4 Permission denied + 5 Resource not found + +EOF +} + +#=============================================================================== +# BUSINESS FUNCTIONS +#=============================================================================== + +### Main business logic (replace with actual implementation) +### @param input string Input to process +### @return 0 Success +### @return 1 Processing failed +do_work() { + local input="$1" + + log_info "Processing: ${input}" + + # > Replace with actual business logic + run_cmd echo "Working on: ${input}" + + log_info "Done" +} + +#=============================================================================== +# ARGUMENT PARSING +#=============================================================================== + +### Parse command line arguments +### @param args array Command line arguments +### @return 0 Success +### @return 2 Invalid argument +parse_args() { + local positional=() + + while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) + usage + exit "$E_SUCCESS" + ;; + --version) + echo "${SCRIPT_NAME} version ${VERSION}" + exit "$E_SUCCESS" + ;; + -v|--verbose) + VERBOSE=true + LOG_LEVEL="DEBUG" + shift + ;; + -q|--quiet) + LOG_LEVEL="ERROR" + shift + ;; + -n|--dry-run) + DRY_RUN=true + shift + ;; + -f|--force) + FORCE=true + shift + ;; + --) + shift + positional+=("$@") + break + ;; + -*) + die "Unknown option: $1" "$E_ARGS" + ;; + *) + positional+=("$1") + shift + ;; + esac + done + + # > Restore positional parameters + set -- "${positional[@]}" + + # > Validate required arguments + if [[ $# -lt 1 ]]; then + die "Missing required argument. Use --help for usage." "$E_ARGS" + fi + + # > Export parsed values for main() + INPUT_ARG="$1" +} + +#=============================================================================== +# MAIN +#=============================================================================== + +### Main entry point - orchestrates script execution +### @param args array Command line arguments +### @return 0 Success +main() { + check_bash_version + parse_args "$@" + check_dependencies + setup_temp + + log_info "Starting ${SCRIPT_NAME} v${VERSION}" + [[ "${DRY_RUN}" == "true" ]] && log_warn "Running in dry-run mode" + + do_work "${INPUT_ARG}" + + log_info "Completed successfully" +} + +# > Entry point +main "$@" + +#=============================================================================== +# SELF-TEST EXAMPLES +#=============================================================================== +# Run these commands to verify script behavior: +# +# 1. Show help: +# ./minimal-template.sh --help +# +# 2. Dry-run mode: +# ./minimal-template.sh --dry-run test-input +# +# 3. Invalid argument (expect exit 2): +# ./minimal-template.sh --invalid-option +# +# 4. Missing argument (expect exit 2): +# ./minimal-template.sh +# +# 5. Verbose mode: +# ./minimal-template.sh --verbose test-input +#=============================================================================== diff --git a/1-AgentSkills/writing-bash-scripts/reference/code-structure.md b/1-AgentSkills/writing-bash-scripts/reference/code-structure.md new file mode 100644 index 0000000..de0c6c9 --- /dev/null +++ b/1-AgentSkills/writing-bash-scripts/reference/code-structure.md @@ -0,0 +1,121 @@ +# Bash Script Code Structure Reference + +## Section Order (固定顺序,不可打乱) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 1. SHEBANG + METADATA │ +│ #!/usr/bin/env bash │ +│ # Author / Version / License / Last Updated │ +├─────────────────────────────────────────────────────────────┤ +│ 2. ASCII CALL GRAPH │ +│ # main() │ +│ # ├── parse_args() │ +│ # ├── check_dependencies() │ +│ # ├── business_function_1() │ +│ # │ └── helper_function() │ +│ # └── cleanup() │ +├─────────────────────────────────────────────────────────────┤ +│ 3. GLOBAL CONSTANTS │ +│ readonly VERSION="1.0.0" │ +│ readonly SCRIPT_NAME="${0##*/}" │ +│ readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" │ +├─────────────────────────────────────────────────────────────┤ +│ 4. STRICT MODE │ +│ set -Eeuo pipefail │ +│ IFS=$' \t\n' │ +├─────────────────────────────────────────────────────────────┤ +│ 5. CONFIGURABLE DEFAULTS │ +│ LOG_LEVEL="${LOG_LEVEL:-INFO}" │ +│ DRY_RUN=false │ +│ VERBOSE=false │ +│ FORCE=false │ +├─────────────────────────────────────────────────────────────┤ +│ 6. DEPENDENCY & ENVIRONMENT CHECKS │ +│ check_bash_version() │ +│ check_dependencies() │ +│ check_permissions() │ +├─────────────────────────────────────────────────────────────┤ +│ 7. LOGGING & ERROR HANDLING │ +│ log_debug() / log_info() / log_warn() / log_error() │ +│ die() │ +│ run_cmd() │ +│ cleanup() │ +│ trap setup │ +├─────────────────────────────────────────────────────────────┤ +│ 8. BUSINESS FUNCTIONS │ +│ (grouped by domain, each <50 lines) │ +├─────────────────────────────────────────────────────────────┤ +│ 9. MAIN + ENTRY │ +│ main() { parse_args; check_deps; do_work; } │ +│ main "$@" │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Strict Mode Explained + +```bash +set -E # ERR trap inherited by functions +set -e # Exit on error +set -u # Error on unset variables +set -o pipefail # Pipe fails if any command fails +``` + +Combined: `set -Eeuo pipefail` + +## IFS Safety + +```bash +# Default safe IFS +IFS=$' \t\n' + +# When processing CSV or custom delimiter, use local override: +local IFS=',' +read -ra fields <<< "$line" +``` + +## Variable Quoting Rules + +| Context | Correct | Wrong | +|---------|---------|-------| +| Assignment | `var="$value"` | `var=$value` | +| Command arg | `cmd "$file"` | `cmd $file` | +| Array expansion | `"${arr[@]}"` | `${arr[@]}` | +| Intentional splitting | `$unquoted # > reason` | (must comment) | + +## Readonly Constants Pattern + +```bash +# Script metadata +readonly VERSION="1.0.0" +readonly SCRIPT_NAME="${0##*/}" +readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Exit codes +readonly E_SUCCESS=0 +readonly E_GENERAL=1 +readonly E_ARGS=2 +readonly E_DEPS=3 +readonly E_PERM=4 +readonly E_NOTFOUND=5 +``` + +## Temp Directory Pattern + +```bash +# Create temp dir with automatic cleanup +TEMP_DIR="" + +setup_temp() { + TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/${SCRIPT_NAME}.XXXXXX")" + readonly TEMP_DIR +} + +cleanup() { + if [[ -n "${TEMP_DIR:-}" && -d "$TEMP_DIR" ]]; then + rm -rf "$TEMP_DIR" + fi +} + +trap cleanup EXIT ERR INT TERM +``` diff --git a/1-AgentSkills/writing-bash-scripts/reference/exit-codes.md b/1-AgentSkills/writing-bash-scripts/reference/exit-codes.md new file mode 100644 index 0000000..f2ca812 --- /dev/null +++ b/1-AgentSkills/writing-bash-scripts/reference/exit-codes.md @@ -0,0 +1,99 @@ +# Exit Codes Reference + +## Standard Exit Codes (必须遵循) + +| Code | Constant | Meaning | Use Case | +|------|----------|---------|----------| +| 0 | `E_SUCCESS` | Success | Normal completion | +| 1 | `E_GENERAL` | General error | Catch-all for unspecified errors | +| 2 | `E_ARGS` | Invalid arguments | Wrong number, invalid format, unknown option | +| 3 | `E_DEPS` | Missing dependency | Required command not found | +| 4 | `E_PERM` | Permission denied | Cannot read/write/execute required resource | +| 5 | `E_NOTFOUND` | Resource not found | File, directory, or resource doesn't exist | + +## Extended Exit Codes (按需选用) + +| Code | Constant | Meaning | Use Case | +|------|----------|---------|----------| +| 6 | `E_CONFIG` | Configuration error | Invalid or missing config file | +| 7 | `E_NETWORK` | Network error | Connection failed, timeout | +| 8 | `E_TIMEOUT` | Operation timeout | Command exceeded time limit | +| 9 | `E_LOCK` | Lock acquisition failed | Cannot acquire file/process lock | +| 10 | `E_STATE` | Invalid state | Precondition not met | + +## Reserved Exit Codes (不要使用) + +| Code | Reserved By | Meaning | +|------|-------------|---------| +| 126 | Shell | Command found but not executable | +| 127 | Shell | Command not found | +| 128 | Shell | Invalid exit code (exit only takes 0-255) | +| 128+N | Shell | Fatal signal N (e.g., 130 = SIGINT, 137 = SIGKILL, 143 = SIGTERM) | +| 255 | Shell | Exit code out of range | + +## Declaration Pattern + +```bash +# Exit codes (declare at top, after shebang) +readonly E_SUCCESS=0 +readonly E_GENERAL=1 +readonly E_ARGS=2 +readonly E_DEPS=3 +readonly E_PERM=4 +readonly E_NOTFOUND=5 +readonly E_CONFIG=6 +readonly E_NETWORK=7 +readonly E_TIMEOUT=8 +readonly E_LOCK=9 +readonly E_STATE=10 +``` + +## Usage Examples + +```bash +# Argument validation +[[ $# -ge 1 ]] || die "Missing required argument" "$E_ARGS" + +# Dependency check +command -v jq &>/dev/null || die "jq is required" "$E_DEPS" + +# Permission check +[[ -w "$output_dir" ]] || die "Cannot write to: $output_dir" "$E_PERM" + +# File existence +[[ -f "$config_file" ]] || die "Config not found: $config_file" "$E_NOTFOUND" + +# Network error (with retry) +curl -sf "$url" || die "Failed to fetch: $url" "$E_NETWORK" +``` + +## Exit Code Ranges by Category + +| Range | Category | Description | +|-------|----------|-------------| +| 0 | Success | All operations completed | +| 1-10 | Application errors | Defined by script | +| 11-63 | Reserved | For future application use | +| 64-78 | BSD sysexits.h | Standard Unix exit codes | +| 79-125 | Reserved | For future use | +| 126-255 | Shell reserved | Do not use | + +## sysexits.h Reference (可选,用于更严格的标准化) + +| Code | Name | Meaning | +|------|------|---------| +| 64 | EX_USAGE | Command line usage error | +| 65 | EX_DATAERR | Data format error | +| 66 | EX_NOINPUT | Cannot open input | +| 67 | EX_NOUSER | Addressee unknown | +| 68 | EX_NOHOST | Host name unknown | +| 69 | EX_UNAVAILABLE | Service unavailable | +| 70 | EX_SOFTWARE | Internal software error | +| 71 | EX_OSERR | System error | +| 72 | EX_OSFILE | Critical OS file missing | +| 73 | EX_CANTCREAT | Can't create output file | +| 74 | EX_IOERR | I/O error | +| 75 | EX_TEMPFAIL | Temporary failure; retry | +| 76 | EX_PROTOCOL | Protocol error | +| 77 | EX_NOPERM | Permission denied | +| 78 | EX_CONFIG | Configuration error | diff --git a/1-AgentSkills/writing-bash-scripts/reference/function-template.md b/1-AgentSkills/writing-bash-scripts/reference/function-template.md new file mode 100644 index 0000000..fe3897f --- /dev/null +++ b/1-AgentSkills/writing-bash-scripts/reference/function-template.md @@ -0,0 +1,187 @@ +# Function Documentation Template + +## Required Doc Block Format + +Every function MUST have this header (缺一不可): + +```bash +### +### @param <用途说明> +### @param <用途说明> +### @return <状态描述> +### @require <依赖项/命令/权限/环境变量> +### @side_effect <对文件/网络/系统的影响> (可选,有副作用时必填) +function_name() { + local param1="$1" + local param2="${2:-default}" + + # Implementation +} +``` + +## Type Annotations + +| Type | Description | Example | +|------|-------------|---------| +| `string` | Any text | `@param name string User's name` | +| `int` | Integer number | `@param count int Number of retries` | +| `bool` | true/false | `@param verbose bool Enable verbose mode` | +| `path` | File/directory path | `@param config path Path to config file` | +| `array` | Bash array | `@param files array List of input files` | +| `fd` | File descriptor | `@param logfd fd File descriptor for logging` | + +## Complete Example + +```bash +### Validate that a file exists and is readable +### @param file_path path Absolute or relative path to validate +### @param allow_empty bool Whether empty files are valid (default: false) +### @return 0 File is valid and readable +### @return 1 File does not exist +### @return 2 File is not readable +### @return 3 File is empty (when allow_empty=false) +### @require read permission on file_path +validate_file() { + local file_path="$1" + local allow_empty="${2:-false}" + + # > Check existence first (most common failure) + if [[ ! -e "$file_path" ]]; then + log_error "File not found: $file_path" + return 1 + fi + + # > Check readability + if [[ ! -r "$file_path" ]]; then + log_error "File not readable: $file_path" + return 2 + fi + + # > Check empty (only if not allowed) + if [[ "$allow_empty" != "true" && ! -s "$file_path" ]]; then + log_error "File is empty: $file_path" + return 3 + fi + + return 0 +} +``` + +## Logging Functions Template + +```bash +### Log message at DEBUG level +### @param message string Message to log +### @return 0 Always succeeds +log_debug() { + [[ "${LOG_LEVEL:-INFO}" == "DEBUG" ]] || return 0 + printf '[%s] [DEBUG] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Log message at INFO level +### @param message string Message to log +### @return 0 Always succeeds +log_info() { + [[ "${LOG_LEVEL:-INFO}" =~ ^(DEBUG|INFO)$ ]] || return 0 + printf '[%s] [INFO] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Log message at WARN level +### @param message string Message to log +### @return 0 Always succeeds +log_warn() { + [[ "${LOG_LEVEL:-INFO}" =~ ^(DEBUG|INFO|WARN)$ ]] || return 0 + printf '[%s] [WARN] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} + +### Log message at ERROR level +### @param message string Message to log +### @return 0 Always succeeds +log_error() { + printf '[%s] [ERROR] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 +} +``` + +## Die Function Template + +```bash +### Exit with error message and code, including location info +### @param message string Error message +### @param exit_code int Exit code (default: 1) +### @return never Returns (exits script) +### @side_effect Terminates script execution +die() { + local message="$1" + local exit_code="${2:-1}" + local caller_info="" + + # > Build stack trace for debugging + if [[ "${BASH_LINENO[0]:-0}" -gt 0 ]]; then + caller_info=" (${FUNCNAME[1]:-main}:${BASH_LINENO[0]:-?})" + fi + + log_error "${message}${caller_info}" + exit "$exit_code" +} +``` + +## Run Command Wrapper Template + +```bash +### Execute command with dry-run support and error handling +### @param cmd string Command to execute (as array: "${cmd[@]}") +### @return 0 Command succeeded +### @return 1 Command failed +### @side_effect Executes external command (unless DRY_RUN=true) +run_cmd() { + local -a cmd=("$@") + + if [[ "${DRY_RUN:-false}" == "true" ]]; then + log_info "[DRY-RUN] Would execute: ${cmd[*]}" + return 0 + fi + + if [[ "${VERBOSE:-false}" == "true" ]]; then + log_debug "Executing: ${cmd[*]}" + fi + + if ! "${cmd[@]}"; then + log_error "Command failed: ${cmd[*]}" + return 1 + fi + + return 0 +} +``` + +## Input Validation Pattern + +```bash +### Validate path argument +### @param path path Path to validate +### @param must_exist bool Path must exist (default: true) +### @param must_be_writable bool Path must be writable (default: false) +validate_path() { + local path="$1" + local must_exist="${2:-true}" + local must_be_writable="${3:-false}" + + # > Reject empty paths + [[ -n "$path" ]] || die "Path cannot be empty" 2 + + # > Resolve to absolute path + if [[ "$path" != /* ]]; then + path="$(cd "$(dirname "$path")" 2>/dev/null && pwd)/$(basename "$path")" + fi + + if [[ "$must_exist" == "true" && ! -e "$path" ]]; then + die "Path does not exist: $path" 5 + fi + + if [[ "$must_be_writable" == "true" && ! -w "$path" ]]; then + die "Path not writable: $path" 4 + fi + + printf '%s' "$path" +} +``` diff --git a/1-AgentSkills/writing-bash-scripts/scripts/shellcheck-wrapper.sh b/1-AgentSkills/writing-bash-scripts/scripts/shellcheck-wrapper.sh new file mode 100644 index 0000000..bd801e9 --- /dev/null +++ b/1-AgentSkills/writing-bash-scripts/scripts/shellcheck-wrapper.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +#=============================================================================== +# Script Name : shellcheck-wrapper.sh +# Description : Wrapper for ShellCheck with project defaults +# Version : 1.0.0 +#=============================================================================== + +set -Eeuo pipefail + +readonly SCRIPT_NAME="${0##*/}" + +### Display usage +usage() { + cat < [shellcheck-options...] + +Runs ShellCheck with recommended settings for production Bash scripts. + +Default flags applied: + -x Follow source statements + -s bash Shell dialect: bash + -S style Minimum severity: style (catch everything) + +Examples: + ${SCRIPT_NAME} myscript.sh + ${SCRIPT_NAME} myscript.sh -S warning # Only warnings and above + ${SCRIPT_NAME} *.sh # Check multiple files + +EOF +} + +### Check ShellCheck is installed +check_shellcheck() { + if ! command -v shellcheck &>/dev/null; then + echo "ERROR: shellcheck not found. Install with:" >&2 + echo " Ubuntu/Debian: apt install shellcheck" >&2 + echo " macOS: brew install shellcheck" >&2 + echo " Windows: scoop install shellcheck" >&2 + exit 3 + fi +} + +main() { + if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then + usage + exit 0 + fi + + check_shellcheck + + local script="$1" + shift + + if [[ ! -f "$script" ]]; then + echo "ERROR: File not found: $script" >&2 + exit 5 + fi + + echo "Running ShellCheck on: $script" + echo "========================================" + + # > Run with defaults + any user-provided options + # shellcheck disable=SC2086 + shellcheck -x -s bash -S style "$@" "$script" + + local exit_code=$? + + if [[ $exit_code -eq 0 ]]; then + echo "========================================" + echo "✓ No issues found" + else + echo "========================================" + echo "✗ ShellCheck found issues (exit code: $exit_code)" + fi + + exit $exit_code +} + +main "$@" diff --git a/13-SHELL脚本/shell-prompt-2.md b/13-SHELL脚本/shell-prompt-2.md new file mode 100644 index 0000000..06faded --- /dev/null +++ b/13-SHELL脚本/shell-prompt-2.md @@ -0,0 +1,81 @@ +你是一名资深 Bash Shell 工程师。请基于【功能需求】输出一份“可直接落地”的生产级脚本(单文件),并严格遵循以下工程规范与交付要求。 + +【功能需求】 +- (在此粘贴:目标、输入/输出、流程、约束、示例数据、成功/失败判定、是否需要远程执行/并发/幂等、目标系统等) + +======================== +一、交付物与输出格式(必须满足) +======================== +1) 交付物为“一个可运行的 Bash 脚本”,放在一个代码块中输出,包含: + - shebang:#!/usr/bin/env bash + - Bash 版本要求:Bash >= 5.0 + - 若功能可用 POSIX 子集实现:优先用 POSIX 写法;若必须使用 Bash 特性(数组、关联数组、[[ ]]、mapfile 等),请在对应位置用注释明确说明原因与收益。 +2) 脚本必须提供: + - usage/help(-h/--help),包含示例 + - 参数解析(getopts 或等效安全方案),参数缺失/非法时给出可读错误 + - 清晰的退出码约定(0 成功;非 0 表示失败并可区分类型) +3) 默认行为要求: + - 安全默认值(不破坏系统、不覆盖关键文件;涉及写入/删除必须显式确认或提供 --force) + - 支持 --dry-run(只打印将执行的动作,不实际执行) + - 支持 --verbose / --quiet(或 LOG_LEVEL) +4) 文档与可读性: + - 关键步骤用 “# >” 行内注释解释意图(不是复述代码) + - 在脚本顶部提供 ASCII 调用关系/流程图(call graph) + +======================== +二、代码结构与工程规范(必须满足) +======================== +1) 严格模式与防御性编程 + - set -Eeuo pipefail,并启用 errtrace(set -E)保证函数内错误可追踪 + - IFS 安全设置(如 IFS=$' \t\n' 或在局部处理输入时显式设定) + - 禁止未引用变量、禁止不安全的 eval;所有变量引用必须加双引号(除非明确需要 word splitting,并解释原因) +2) 模块化组织(建议分区,且顺序固定) + - 元数据区(作者/版本/许可证/最后更新) + - 全局常量区(readonly 常量;可配置项集中) + - 依赖与环境检查区(命令存在性、权限、OS/发行版识别如需要) + - 日志与错误处理区(统一 logger、die、assert、run_cmd) + - 业务函数区(按领域分组,函数短小) + - main() 与入口区(只做流程编排,不堆业务细节) +3) 错误处理机制 + - 统一错误出口:die + - trap:至少覆盖 ERR / INT / TERM / EXIT + - cleanup:退出时清理临时文件/锁(用 mktemp 创建临时目录) + - 错误信息必须包含:失败命令、行号、函数栈(尽可能) + +======================== +三、函数设计标准(必须满足) +======================== +1) 每个函数必须带“### 注释块”,格式如下(缺一不可): + ### <一句话功能描述> + ### @param <用途说明> + ### @return <状态描述> + ### @require <依赖项/命令/权限/环境> + ### @side_effect <可选:对文件/网络/系统的影响> +2) 命名规范 + - 函数与变量使用 snake_case + - 全局常量使用全大写 + 下划线(readonly) +3) 输入校验 + - 所有外部输入(参数、文件、环境变量、命令输出)必须校验 + - 涉及路径:必须处理空值、相对/绝对、是否存在、是否可写、是否为符号链接(按需求决定策略) + +======================== +四、日志与可观测性(必须满足) +======================== +1) 统一日志函数:log_debug/log_info/log_warn/log_error + - 日志格式包含:时间戳、级别、消息 + - 支持 LOG_LEVEL 控制输出(DEBUG/INFO/WARN/ERROR) +2) run_cmd 包装器 + - 所有外部命令执行通过 run_cmd,支持 dry-run、错误捕获、可选重试(如需求涉及网络/不稳定操作) + +======================== +五、质量保障与自检(必须满足) +======================== +1) 脚本需满足 ShellCheck(如必须禁用某条规则,必须用 # shellcheck disable=SCxxxx 并解释原因) +2) 在脚本末尾或注释区给出“最小自测方法” + - 至少给出 3 条示例命令覆盖:正常路径、参数错误、dry-run + +======================== +六、输出要求(强约束) +======================== +- 只输出脚本代码(一个代码块),不要输出额外解释性长文;必要说明写在脚本注释里 +- 若【功能需求】存在歧义:请做“合理默认”,并把假设写在脚本头部的 Assumptions 注释段 diff --git a/13-SHELL脚本/shell-prompt.md b/13-SHELL脚本/shell-prompt.md new file mode 100644 index 0000000..2b3d29e --- /dev/null +++ b/13-SHELL脚本/shell-prompt.md @@ -0,0 +1,18 @@ +请以Bash Shell脚本高级开发工程师的身份,严格遵循以下编程规范实现指定功能: + +1. 代码结构规范 +- 符合POSIX标准与Bash最佳实践(v5.0+) +- 实现清晰的模块划分和函数封装 +- 采用防御性编程策略处理异常情况 +- 包含完善的错误处理机制(trap、set -euo pipefail) +2. 函数设计标准 +- 函数声明需包含: 功能描述段(使用###注释块) 参数说明:@param <变量名> <数据类型> <用途说明> 返回值说明:@return <退出码> <状态描述> 环境依赖:@require <依赖项> +- 函数参数命名采用snake_case格式,体现语义化特征 +3. 文档规范 +- 主脚本头部包含: 元数据声明(作者、版本、许可证) 全局常量定义区 模块依赖说明 +- 关键算法步骤添加行内注释(# > 开头) +- 维护完整的函数调用关系图(使用ASCII流程图) +4. 质量保障 +- 通过ShellCheck进行静态检测 +- 统一的日志函数,实现详细的日志分级输出(DEBUG/INFO/WARN/ERROR) + diff --git a/2-需求转换专业设计/Prompt转换AgentSkill.md b/2-需求转换专业设计/Prompt转换AgentSkill.md index db7f741..b627abd 100644 --- a/2-需求转换专业设计/Prompt转换AgentSkill.md +++ b/2-需求转换专业设计/Prompt转换AgentSkill.md @@ -2,8 +2,7 @@ ## 输入 - 源文档路径(用于动态注入内容): - @C:\Users\wddsh\Documents\IdeaProjects\ProjectAGiPrompt\1-Vue3项目\vue3-typescript-style-v2.md - @C:\Users\wddsh\Documents\IdeaProjects\ProjectAGiPrompt\1-Vue3项目\frontend-design-skill.md 请重点参考此SKILL的写法 + @C:\Users\wddsh\Documents\IdeaProjects\ProjectAGiPrompt\13-SHELL脚本\shell-prompt-2.md - 你将从该源文档中提炼“领域特定规则、具体操作步骤、可执行检查清单”,删除常识性解释。 > 若无法读取文件,则明确指出“缺少源文档内容”,并输出你需要用户提供的最小信息清单(不要继续臆造细节)。 diff --git a/ProjectAGiPrompt.iml b/ProjectAGiPrompt.iml index 9a5cfce..638b4ac 100644 --- a/ProjectAGiPrompt.iml +++ b/ProjectAGiPrompt.iml @@ -1,5 +1,6 @@ +