chore: inicializacao agente auto-melhoria + nova-self-improver + .learnings/ + MEMORY.md

- Adiciona .learnings/ completo (LEARNINGS, ERRORS, FEATURE_REQUESTS, PATTERN_COUNTER)
- Cria MEMORY.md, SESSION-STATE.md, USER.md template
- Cria memory/2026-05-19.md (log diario)
- cria IDENTITY.md (Pulse )
- Atualiza AGENTS.md, SOUL.md, TOOLS.md com regras de auto-melhoria
- Instala nova-self-improver v1.0.0 via clawhub
- Skills totais: 6 instaladas
This commit is contained in:
Pulse
2026-05-19 20:42:04 -03:00
commit 483bcbf92e
53 changed files with 4914 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
{
"version": 1,
"registry": "https://clawhub.ai",
"slug": "vision",
"installedVersion": "3.5.0",
"installedAt": 1779229985873
}
+55
View File
@@ -0,0 +1,55 @@
---
name: "Vision — Image Processing, Resize, Convert & Watermark"
description: "Resize, crop, convert, and optimize images using ImageMagick. Use when processing photos, converting formats (PNG/WebP), compressing size, or adding watermarks."
version: "3.5.0"
author: BytesAgain
homepage: https://bytesagain.com
source: https://github.com/bytesagain/ai-skills
tags: ["vision", "image-processing", "resize", "crop", "convert", "optimize", "exif", "watermark", "图像处理"]
---
# vision
Image processing toolkit powered by ImageMagick.
## Quick Start / 快速开始
Just ask your AI assistant: / 直接告诉 AI 助手:
- "Resize photo.jpg to 800px width" (帮我把 photo.jpg 缩小到 800 宽)
- "Convert this PNG to WebP format" (把这张 PNG 图片转换成 WebP 格式)
- "Add watermark: © 2025 BytesAgain" (给这张图加个水印)
## Commands
### resize
Resize an image.
```bash
bash scripts/script.sh resize --input photo.jpg --width 800
bash scripts/script.sh resize --input photo.jpg --percent 50
```
### convert
Change image formats.
```bash
bash scripts/script.sh convert --input photo.png --to webp
bash scripts/script.sh convert --input photo.jpg --to png
```
### optimize
Compress file size without losing quality.
```bash
bash scripts/script.sh optimize --input photo.jpg --quality 80
```
### watermark
Add text watermark to images.
```bash
bash scripts/script.sh watermark --input photo.jpg --text "© 2025" --position southeast
```
## Requirements
- bash 4+
- ImageMagick (convert, identify)
## Feedback
https://bytesagain.com/feedback/
Powered by BytesAgain | bytesagain.com
+6
View File
@@ -0,0 +1,6 @@
{
"ownerId": "kn75xfx77qg22he2nw6wa5p64d82nvgx",
"slug": "vision",
"version": "3.5.0",
"publishedAt": 1774614216943
}
+520
View File
@@ -0,0 +1,520 @@
#!/usr/bin/env bash
set -euo pipefail
###############################################################################
# vision - Image Processing Toolkit
# Version: 3.0.0
# Author: BytesAgain
#
# Commands: resize, crop, convert, optimize, info, watermark
# Requires: ImageMagick (convert/identify/mogrify commands)
###############################################################################
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
JSON_OUTPUT=false
# ---------------------------------------------------------------------------
# Utilities
# ---------------------------------------------------------------------------
die() { echo "ERROR: $*" >&2; exit 1; }
log() { echo "[vision] $*" >&2; }
check_imagemagick() {
if ! command -v convert &>/dev/null && ! command -v magick &>/dev/null; then
die "ImageMagick is required but not installed. Install with: apt install imagemagick / brew install imagemagick"
fi
}
# Wrapper to handle both ImageMagick 6 (convert) and 7 (magick)
im_convert() {
if command -v magick &>/dev/null; then
magick "$@"
else
convert "$@"
fi
}
im_identify() {
if command -v magick &>/dev/null; then
magick identify "$@"
else
identify "$@"
fi
}
parse_global_flags() {
local args=()
for arg in "$@"; do
if [[ "$arg" == "--json" ]]; then
JSON_OUTPUT=true
else
args+=("$arg")
fi
done
REMAINING_ARGS=("${args[@]+"${args[@]}"}")
}
get_extension() {
local filename="$1"
echo "${filename##*.}" | tr '[:upper:]' '[:lower:]'
}
get_basename() {
local filename="$1"
local base
base=$(basename "$filename")
echo "${base%.*}"
}
get_dirname() {
dirname "$1"
}
auto_output_name() {
local input="$1"
local suffix="$2"
local ext="${3:-$(get_extension "$input")}"
local dir
dir=$(get_dirname "$input")
local base
base=$(get_basename "$input")
echo "${dir}/${base}_${suffix}.${ext}"
}
validate_input() {
local input="$1"
[[ -n "$input" ]] || die "No input file specified. Use --input"
[[ -f "$input" ]] || die "File not found: $input"
}
# ---------------------------------------------------------------------------
# cmd_help - List all commands
# ---------------------------------------------------------------------------
cmd_help() {
cat <<'EOF'
vision - Image Processing Toolkit
Usage: bash script.sh <command> [options]
Commands:
resize Resize image to dimensions or percentage
crop Crop image to a region
convert Convert between png, jpg, webp formats
optimize Compress image to reduce file size
info Read EXIF and image metadata
watermark Add text watermark to image
help Show this help message
Common options:
--input Input image file (required for all commands)
--output Output file path (auto-generated if omitted)
--json JSON output for info command
Requires: ImageMagick (apt install imagemagick)
Examples:
bash script.sh resize --input photo.jpg --width 800
bash script.sh convert --input photo.png --to webp
bash script.sh info --input photo.jpg --json
EOF
}
# ---------------------------------------------------------------------------
# cmd_resize - Resize image
# ---------------------------------------------------------------------------
cmd_resize() {
check_imagemagick
local input="" output="" width="" height="" percent=""
while [[ $# -gt 0 ]]; do
case "$1" in
--input) shift; input="$1" ;;
--output) shift; output="$1" ;;
--width) shift; width="$1" ;;
--height) shift; height="$1" ;;
--percent) shift; percent="$1" ;;
*) die "Unknown option for resize: $1" ;;
esac
shift
done
validate_input "$input"
[[ -n "$output" ]] || output=$(auto_output_name "$input" "resized")
local geometry=""
if [[ -n "$percent" ]]; then
geometry="${percent}%"
elif [[ -n "$width" && -n "$height" ]]; then
geometry="${width}x${height}!"
elif [[ -n "$width" ]]; then
geometry="${width}x"
elif [[ -n "$height" ]]; then
geometry="x${height}"
else
die "resize requires --width, --height, or --percent"
fi
im_convert "$input" -resize "$geometry" "$output"
# Report results
local orig_size new_size
orig_size=$(stat -c%s "$input" 2>/dev/null || stat -f%z "$input")
new_size=$(stat -c%s "$output" 2>/dev/null || stat -f%z "$output")
local orig_dims new_dims
orig_dims=$(im_identify -format "%wx%h" "$input")
new_dims=$(im_identify -format "%wx%h" "$output")
echo "Resized: $input$output"
echo " Original: ${orig_dims} ($(( orig_size / 1024 )) KB)"
echo " Resized: ${new_dims} ($(( new_size / 1024 )) KB)"
}
# ---------------------------------------------------------------------------
# cmd_crop - Crop image
# ---------------------------------------------------------------------------
cmd_crop() {
check_imagemagick
local input="" output="" width="" height="" x="0" y="0" gravity=""
while [[ $# -gt 0 ]]; do
case "$1" in
--input) shift; input="$1" ;;
--output) shift; output="$1" ;;
--width) shift; width="$1" ;;
--height) shift; height="$1" ;;
--x) shift; x="$1" ;;
--y) shift; y="$1" ;;
--gravity) shift; gravity="$1" ;;
*) die "Unknown option for crop: $1" ;;
esac
shift
done
validate_input "$input"
[[ -n "$width" ]] || die "crop requires --width"
[[ -n "$height" ]] || die "crop requires --height"
[[ -n "$output" ]] || output=$(auto_output_name "$input" "cropped")
if [[ -n "$gravity" ]]; then
im_convert "$input" -gravity "$gravity" -crop "${width}x${height}+0+0" +repage "$output"
else
im_convert "$input" -crop "${width}x${height}+${x}+${y}" +repage "$output"
fi
local new_dims
new_dims=$(im_identify -format "%wx%h" "$output")
echo "Cropped: $input$output"
echo " Region: ${width}x${height}+${x}+${y}"
echo " Result: ${new_dims}"
}
# ---------------------------------------------------------------------------
# cmd_convert - Format conversion
# ---------------------------------------------------------------------------
cmd_convert() {
check_imagemagick
local input="" output="" to="" quality=""
while [[ $# -gt 0 ]]; do
case "$1" in
--input) shift; input="$1" ;;
--output) shift; output="$1" ;;
--to) shift; to="$1" ;;
--quality) shift; quality="$1" ;;
*) die "Unknown option for convert: $1" ;;
esac
shift
done
validate_input "$input"
[[ -n "$to" ]] || die "convert requires --to (png, jpg, webp)"
# Normalize format name
case "$to" in
jpeg) to="jpg" ;;
esac
[[ "$to" =~ ^(png|jpg|webp)$ ]] || die "Supported formats: png, jpg, webp"
if [[ -z "$output" ]]; then
local dir base
dir=$(get_dirname "$input")
base=$(get_basename "$input")
output="${dir}/${base}.${to}"
fi
local cmd_args=("$input")
[[ -n "$quality" ]] && cmd_args+=(-quality "$quality")
cmd_args+=("$output")
im_convert "${cmd_args[@]}"
local orig_size new_size
orig_size=$(stat -c%s "$input" 2>/dev/null || stat -f%z "$input")
new_size=$(stat -c%s "$output" 2>/dev/null || stat -f%z "$output")
local orig_ext
orig_ext=$(get_extension "$input")
echo "Converted: $input ($orig_ext) → $output ($to)"
echo " Original: $(( orig_size / 1024 )) KB"
echo " Output: $(( new_size / 1024 )) KB"
local ratio
ratio=$(awk "BEGIN {printf \"%.1f\", $new_size * 100 / $orig_size}")
echo " Size: ${ratio}% of original"
}
# ---------------------------------------------------------------------------
# cmd_optimize - Compress image
# ---------------------------------------------------------------------------
cmd_optimize() {
check_imagemagick
local input="" output="" quality="85"
while [[ $# -gt 0 ]]; do
case "$1" in
--input) shift; input="$1" ;;
--output) shift; output="$1" ;;
--quality) shift; quality="$1" ;;
*) die "Unknown option for optimize: $1" ;;
esac
shift
done
validate_input "$input"
[[ -n "$output" ]] || output=$(auto_output_name "$input" "optimized")
local ext
ext=$(get_extension "$input")
local orig_size
orig_size=$(stat -c%s "$input" 2>/dev/null || stat -f%z "$input")
case "$ext" in
jpg|jpeg)
im_convert "$input" -quality "$quality" -sampling-factor 4:2:0 -strip \
-interlace JPEG "$output"
;;
png)
im_convert "$input" -quality "$quality" -strip -define png:compression-level=9 "$output"
;;
webp)
im_convert "$input" -quality "$quality" -define webp:method=6 "$output"
;;
*)
im_convert "$input" -quality "$quality" -strip "$output"
;;
esac
local new_size
new_size=$(stat -c%s "$output" 2>/dev/null || stat -f%z "$output")
local saved=$((orig_size - new_size))
local ratio
ratio=$(awk "BEGIN {printf \"%.1f\", $new_size * 100 / $orig_size}")
echo "Optimized: $input$output"
echo " Original: $(( orig_size / 1024 )) KB"
echo " Output: $(( new_size / 1024 )) KB"
echo " Saved: $(( saved / 1024 )) KB (${ratio}% of original)"
echo " Quality: $quality"
}
# ---------------------------------------------------------------------------
# cmd_info - Read EXIF and metadata
# ---------------------------------------------------------------------------
cmd_info() {
check_imagemagick
local input=""
while [[ $# -gt 0 ]]; do
case "$1" in
--input) shift; input="$1" ;;
*) die "Unknown option for info: $1" ;;
esac
shift
done
validate_input "$input"
local format width height colorspace depth filesize
format=$(im_identify -format "%m" "$input" 2>/dev/null | head -1)
width=$(im_identify -format "%w" "$input" 2>/dev/null | head -1)
height=$(im_identify -format "%h" "$input" 2>/dev/null | head -1)
colorspace=$(im_identify -format "%[colorspace]" "$input" 2>/dev/null | head -1)
depth=$(im_identify -format "%z" "$input" 2>/dev/null | head -1)
filesize=$(stat -c%s "$input" 2>/dev/null || stat -f%z "$input")
# Try to get EXIF data
local exif_make="" exif_model="" exif_date="" exif_exposure="" exif_iso="" exif_focal=""
if command -v exiftool &>/dev/null; then
exif_make=$(exiftool -Make -s3 "$input" 2>/dev/null || true)
exif_model=$(exiftool -Model -s3 "$input" 2>/dev/null || true)
exif_date=$(exiftool -DateTimeOriginal -s3 "$input" 2>/dev/null || true)
exif_exposure=$(exiftool -ExposureTime -s3 "$input" 2>/dev/null || true)
exif_iso=$(exiftool -ISO -s3 "$input" 2>/dev/null || true)
exif_focal=$(exiftool -FocalLength -s3 "$input" 2>/dev/null || true)
else
# Fallback: try ImageMagick verbose output
local verbose
verbose=$(im_identify -verbose "$input" 2>/dev/null || true)
exif_make=$(echo "$verbose" | grep -i "exif:Make:" | head -1 | sed 's/.*: *//' || true)
exif_model=$(echo "$verbose" | grep -i "exif:Model:" | head -1 | sed 's/.*: *//' || true)
exif_date=$(echo "$verbose" | grep -i "exif:DateTimeOriginal:" | head -1 | sed 's/.*: *//' || true)
exif_exposure=$(echo "$verbose" | grep -i "exif:ExposureTime:" | head -1 | sed 's/.*: *//' || true)
exif_iso=$(echo "$verbose" | grep -i "exif:ISOSpeedRatings:" | head -1 | sed 's/.*: *//' || true)
exif_focal=$(echo "$verbose" | grep -i "exif:FocalLength:" | head -1 | sed 's/.*: *//' || true)
fi
local filesize_kb=$(( filesize / 1024 ))
local filesize_mb=""
[[ $filesize -gt 1048576 ]] && filesize_mb=" ($(awk "BEGIN {printf \"%.1f\", $filesize / 1048576}") MB)"
if [[ "$JSON_OUTPUT" == true ]]; then
printf '{'
printf '"file":"%s",' "$(basename "$input")"
printf '"format":"%s",' "$format"
printf '"width":%s,' "$width"
printf '"height":%s,' "$height"
printf '"colorspace":"%s",' "$colorspace"
printf '"depth":%s,' "$depth"
printf '"filesize":%s,' "$filesize"
printf '"filesize_kb":%s,' "$filesize_kb"
printf '"exif":{'
printf '"make":"%s",' "${exif_make:-}"
printf '"model":"%s",' "${exif_model:-}"
printf '"date":"%s",' "${exif_date:-}"
printf '"exposure":"%s",' "${exif_exposure:-}"
printf '"iso":"%s",' "${exif_iso:-}"
printf '"focal_length":"%s"' "${exif_focal:-}"
printf '}}\n'
else
echo "=== Image Info ==="
echo ""
echo "File: $(basename "$input")"
echo "Format: $format"
echo "Dimensions: ${width}x${height}"
echo "Color space: $colorspace"
echo "Bit depth: $depth"
echo "File size: ${filesize_kb} KB${filesize_mb}"
echo ""
if [[ -n "$exif_make" || -n "$exif_model" || -n "$exif_date" ]]; then
echo "EXIF Data:"
[[ -n "$exif_make" ]] && echo " Camera make: $exif_make"
[[ -n "$exif_model" ]] && echo " Camera model: $exif_model"
[[ -n "$exif_date" ]] && echo " Date taken: $exif_date"
[[ -n "$exif_exposure" ]] && echo " Exposure: $exif_exposure"
[[ -n "$exif_iso" ]] && echo " ISO: $exif_iso"
[[ -n "$exif_focal" ]] && echo " Focal length: $exif_focal"
else
echo "EXIF Data: (none found)"
fi
fi
}
# ---------------------------------------------------------------------------
# cmd_watermark - Add text watermark
# ---------------------------------------------------------------------------
cmd_watermark() {
check_imagemagick
local input="" output="" text="" position="southeast" opacity="50" size="24" color="white"
while [[ $# -gt 0 ]]; do
case "$1" in
--input) shift; input="$1" ;;
--output) shift; output="$1" ;;
--text) shift; text="$1" ;;
--position) shift; position="$1" ;;
--opacity) shift; opacity="$1" ;;
--size) shift; size="$1" ;;
--color) shift; color="$1" ;;
*) die "Unknown option for watermark: $1" ;;
esac
shift
done
validate_input "$input"
[[ -n "$text" ]] || die "watermark requires --text"
[[ -n "$output" ]] || output=$(auto_output_name "$input" "watermarked")
# Map position to ImageMagick gravity
local gravity
case "$position" in
northwest|nw) gravity="NorthWest" ;;
north|n) gravity="North" ;;
northeast|ne) gravity="NorthEast" ;;
west|w) gravity="West" ;;
center|c) gravity="Center" ;;
east|e) gravity="East" ;;
southwest|sw) gravity="SouthWest" ;;
south|s) gravity="South" ;;
southeast|se) gravity="SouthEast" ;;
*) gravity="SouthEast" ;;
esac
# Calculate dissolve value (ImageMagick uses 0-100)
local dissolve="$opacity"
im_convert "$input" \
\( -size "$(im_identify -format '%w' "$input")x$(im_identify -format '%h' "$input")" xc:none \
-gravity "$gravity" \
-fill "$color" \
-pointsize "$size" \
-annotate +10+10 "$text" \) \
-gravity "$gravity" \
-compose dissolve -define "compose:args=${dissolve}" \
-composite "$output"
echo "Watermark added: $input$output"
echo " Text: \"$text\""
echo " Position: $position ($gravity)"
echo " Opacity: ${opacity}%"
echo " Size: ${size}pt"
echo " Color: $color"
}
# ---------------------------------------------------------------------------
# Main dispatch
# ---------------------------------------------------------------------------
main() {
[[ $# -ge 1 ]] || { cmd_help; exit 0; }
local command="$1"
shift
parse_global_flags "$@"
set -- "${REMAINING_ARGS[@]+"${REMAINING_ARGS[@]}"}"
case "$command" in
resize) cmd_resize "$@" ;;
crop) cmd_crop "$@" ;;
convert) cmd_convert "$@" ;;
optimize) cmd_optimize "$@" ;;
info) cmd_info "$@" ;;
watermark) cmd_watermark "$@" ;;
help) cmd_help ;;
*) die "Unknown command: $command. Run 'help' for usage." ;;
esac
}
main "$@"