@ytspar/sweetlink 1.26.0 → 1.26.1-canary.0a1121a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,10 +17,10 @@ Resize images to optimal dimensions for Claude's vision capabilities. Claude pro
17
17
 
18
18
  ## How It Works
19
19
 
20
- The script at `scripts/resize-for-claude` (in the tools repo):
20
+ The `resize-for-claude` script **bundled in this skill's directory** (next to this SKILL.md):
21
21
 
22
22
  1. Reads the image dimensions
23
- 2. If the image aspect ratio is < 3:1, resizes proportionally so the longest side = 1568px
23
+ 2. If the image aspect ratio is < 3:1, resizes proportionally so the longest side is 1568px (downscale only — already-small images are copied unchanged, never upscaled)
24
24
  3. If the image is very tall (≥ 3:1 height:width), splits into overlapping tiles before resizing each
25
25
  4. Outputs to a `<filename>-claude/` directory next to the original
26
26
 
@@ -37,20 +37,25 @@ Images exceeding these dimensions get downscaled by Claude anyway, wasting token
37
37
  ## Usage
38
38
 
39
39
  ```bash
40
- # Find the script (works from any project linked to tools)
41
- TOOLS_ROOT="$(readlink -f .claude/skills/../../)"
40
+ # The script ships WITH this skill — invoke it from the skill's own base
41
+ # directory (announced when the skill loads). No tools-repo lookup, no
42
+ # project-root derivation: the skill and its script are one unit, so this
43
+ # works identically from any repo the skill is linked into.
44
+ # Always invoke via `bash` (as below): npm packing does not preserve the
45
+ # executable bit, so `./resize-for-claude` breaks for package consumers.
46
+ SKILL_DIR="<this skill's base directory>"
42
47
 
43
48
  # Basic usage — resize to 1568px longest side
44
- "$TOOLS_ROOT/scripts/resize-for-claude" ~/Downloads/mockup.jpg
49
+ bash "$SKILL_DIR/resize-for-claude" ~/Downloads/mockup.jpg
45
50
 
46
51
  # Custom max side
47
- "$TOOLS_ROOT/scripts/resize-for-claude" ~/Downloads/mockup.png 1200
52
+ bash "$SKILL_DIR/resize-for-claude" ~/Downloads/mockup.png 1200
48
53
  ```
49
54
 
50
- ### Direct invocation (if you know the tools path)
55
+ ### Direct invocation (absolute path)
51
56
 
52
57
  ```bash
53
- $TOOLS_ROOT/scripts/resize-for-claude ~/Downloads/image.jpg
58
+ bash /path/to/<skill-dir>/resize-for-claude ~/Downloads/image.jpg
54
59
  ```
55
60
 
56
61
  ## Output
@@ -72,11 +77,12 @@ Input: ~/Downloads/full-page.png
72
77
  Size: 1440x8640 (4200KB)
73
78
 
74
79
  Image is very tall (6:1 ratio). Splitting into tiles...
75
- Part 1: 1440x1568 (180KB) -> ~/Downloads/full-page-claude/full-page-part1.png
76
- Part 2: 1440x1568 (165KB) -> ~/Downloads/full-page-claude/full-page-part2.png
77
- Part 3: 1440x1568 (172KB) -> ~/Downloads/full-page-claude/full-page-part3.png
80
+ Part 1: 784x1568 (180KB) -> ~/Downloads/full-page-claude/full-page-part1.png
81
+ Part 2: 784x1568 (165KB) -> ~/Downloads/full-page-claude/full-page-part2.png
82
+ Part 3: 784x1568 (172KB) -> ~/Downloads/full-page-claude/full-page-part3.png
83
+ Part 4: 261x1568 (48KB) -> ~/Downloads/full-page-claude/full-page-part4.png
78
84
 
79
- Output: ~/Downloads/full-page-claude/ (3 parts)
85
+ Output: ~/Downloads/full-page-claude/ (4 parts)
80
86
  ```
81
87
 
82
88
  ## Requirements
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env bash
2
+ # Resize an image for optimal Claude vision consumption.
3
+ # Claude works best with images where the longest side is ≤1568px.
4
+ # For very tall images, splits into multiple parts to preserve detail.
5
+ #
6
+ # Usage: resize-for-claude <image-path> [max-long-side]
7
+ #
8
+ # Examples:
9
+ # resize-for-claude ~/Downloads/mockup.jpg
10
+ # resize-for-claude ~/Downloads/mockup.png 1200
11
+ #
12
+ # Requires: macOS (uses sips)
13
+
14
+ set -euo pipefail
15
+
16
+ if [[ "${1:-}" == "" ]]; then
17
+ echo "Usage: resize-for-claude <image-path> [max-long-side]" >&2
18
+ echo "" >&2
19
+ echo " max-long-side Maximum pixel length of longest side (default: 1568)" >&2
20
+ exit 1
21
+ fi
22
+
23
+ MAX_SIDE="${2:-1568}"
24
+ INPUT="$1"
25
+
26
+ if [[ ! -f "$INPUT" ]]; then
27
+ echo "Error: File not found: $INPUT" >&2
28
+ exit 1
29
+ fi
30
+
31
+ # Get image dimensions
32
+ WIDTH=$(sips -g pixelWidth "$INPUT" | tail -1 | awk '{print $2}')
33
+ HEIGHT=$(sips -g pixelHeight "$INPUT" | tail -1 | awk '{print $2}')
34
+ FILESIZE=$(stat -f "%z" "$INPUT")
35
+
36
+ # A non-image (or a format sips can't read) yields empty/zero dimensions,
37
+ # which would otherwise surface as a cryptic arithmetic abort below.
38
+ if ! [[ "$WIDTH" =~ ^[0-9]+$ && "$HEIGHT" =~ ^[0-9]+$ ]] || [[ "$WIDTH" -eq 0 || "$HEIGHT" -eq 0 ]]; then
39
+ echo "Error: Could not read image dimensions from $INPUT (not an image, or a format sips can't read)" >&2
40
+ exit 1
41
+ fi
42
+
43
+ echo "Input: $INPUT"
44
+ echo "Size: ${WIDTH}x${HEIGHT} ($(( FILESIZE / 1024 ))KB)"
45
+
46
+ # Determine output path
47
+ DIR=$(dirname "$INPUT")
48
+ BASE=$(basename "$INPUT")
49
+ EXT="${BASE##*.}"
50
+ NAME="${BASE%.*}"
51
+ OUTDIR="$DIR/${NAME}-claude"
52
+ mkdir -p "$OUTDIR"
53
+
54
+ # Aspect ratio: if height > 3x width, split into tiles to preserve detail
55
+ RATIO=$(( HEIGHT / WIDTH ))
56
+
57
+ if [[ "$RATIO" -ge 3 ]]; then
58
+ # Very tall image — split into overlapping tiles then resize each
59
+ TILE_HEIGHT=$(( WIDTH * 2 )) # Each tile is ~2:1 aspect ratio
60
+ OVERLAP=$(( TILE_HEIGHT / 10 ))
61
+ STEP=$(( TILE_HEIGHT - OVERLAP ))
62
+ PART=1
63
+ Y=0
64
+
65
+ # A re-run can produce fewer tiles than the previous run left behind;
66
+ # clear stale parts so the output dir never mixes runs.
67
+ rm -f "$OUTDIR/${NAME}-part"*."$EXT"
68
+
69
+ echo ""
70
+ echo "Image is very tall (${RATIO}:1 ratio). Splitting into tiles..."
71
+
72
+ while [[ "$Y" -lt "$HEIGHT" ]]; do
73
+ REMAINING=$(( HEIGHT - Y ))
74
+ CROP_H=$(( REMAINING < TILE_HEIGHT ? REMAINING : TILE_HEIGHT ))
75
+
76
+ OUTFILE="$OUTDIR/${NAME}-part${PART}.${EXT}"
77
+
78
+ # Crop tile
79
+ sips -c "$CROP_H" "$WIDTH" --cropOffset "$Y" 0 "$INPUT" --out "$OUTFILE" >/dev/null 2>&1 || {
80
+ TMPFILE=$(mktemp "/tmp/resize-claude-XXXX.$EXT")
81
+ cp "$INPUT" "$TMPFILE"
82
+ sips -c "$CROP_H" "$WIDTH" --cropOffset "$Y" 0 "$TMPFILE" --out "$OUTFILE" >/dev/null 2>&1
83
+ rm -f "$TMPFILE"
84
+ }
85
+
86
+ # Resize tile to fit within max side
87
+ TILE_W=$(sips -g pixelWidth "$OUTFILE" | tail -1 | awk '{print $2}')
88
+ TILE_H=$(sips -g pixelHeight "$OUTFILE" | tail -1 | awk '{print $2}')
89
+
90
+ if [[ "$TILE_W" -gt "$MAX_SIDE" || "$TILE_H" -gt "$MAX_SIDE" ]]; then
91
+ if [[ "$TILE_W" -ge "$TILE_H" ]]; then
92
+ sips --resampleWidth "$MAX_SIDE" "$OUTFILE" --out "$OUTFILE" >/dev/null 2>&1
93
+ else
94
+ sips --resampleHeight "$MAX_SIDE" "$OUTFILE" --out "$OUTFILE" >/dev/null 2>&1
95
+ fi
96
+ fi
97
+
98
+ NEW_W=$(sips -g pixelWidth "$OUTFILE" | tail -1 | awk '{print $2}')
99
+ NEW_H=$(sips -g pixelHeight "$OUTFILE" | tail -1 | awk '{print $2}')
100
+ NEW_SIZE=$(stat -f "%z" "$OUTFILE")
101
+ echo " Part $PART: ${NEW_W}x${NEW_H} ($(( NEW_SIZE / 1024 ))KB) -> $OUTFILE"
102
+
103
+ Y=$(( Y + STEP ))
104
+ PART=$(( PART + 1 ))
105
+ done
106
+
107
+ echo ""
108
+ echo "Output: $OUTDIR/ ($(( PART - 1 )) parts)"
109
+ else
110
+ # Single image — just resize
111
+ OUTFILE="$OUTDIR/${NAME}.${EXT}"
112
+ cp "$INPUT" "$OUTFILE"
113
+
114
+ if [[ "$WIDTH" -ge "$HEIGHT" ]]; then
115
+ LONG="$WIDTH"
116
+ else
117
+ LONG="$HEIGHT"
118
+ fi
119
+
120
+ if [[ "$LONG" -gt "$MAX_SIDE" ]]; then
121
+ if [[ "$WIDTH" -ge "$HEIGHT" ]]; then
122
+ sips --resampleWidth "$MAX_SIDE" "$OUTFILE" --out "$OUTFILE" >/dev/null 2>&1
123
+ else
124
+ sips --resampleHeight "$MAX_SIDE" "$OUTFILE" --out "$OUTFILE" >/dev/null 2>&1
125
+ fi
126
+ fi
127
+
128
+ NEW_W=$(sips -g pixelWidth "$OUTFILE" | tail -1 | awk '{print $2}')
129
+ NEW_H=$(sips -g pixelHeight "$OUTFILE" | tail -1 | awk '{print $2}')
130
+ NEW_SIZE=$(stat -f "%z" "$OUTFILE")
131
+
132
+ echo ""
133
+ echo "Output: $OUTFILE"
134
+ echo "Size: ${NEW_W}x${NEW_H} ($(( NEW_SIZE / 1024 ))KB)"
135
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ytspar/sweetlink",
3
- "version": "1.26.0",
3
+ "version": "1.26.1-canary.0a1121a",
4
4
  "description": "Autonomous development toolkit for AI agents - screenshots, DOM queries, console logs, and JavaScript execution via WebSocket and Chrome DevTools Protocol",
5
5
  "keywords": [
6
6
  "autonomous-development",