pi-shit 0.1.0

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.
Files changed (42) hide show
  1. package/README.md +44 -0
  2. package/extensions/README.md +23 -0
  3. package/extensions/deep-review/README.md +56 -0
  4. package/extensions/deep-review/index.test.ts +97 -0
  5. package/extensions/deep-review/index.ts +1541 -0
  6. package/extensions/pi-notify/LICENSE +21 -0
  7. package/extensions/pi-notify/README.md +84 -0
  8. package/extensions/pi-notify/index.ts +75 -0
  9. package/extensions/pi-notify/package.json +28 -0
  10. package/extensions/plan-mode/README.md +69 -0
  11. package/extensions/plan-mode/index.ts +345 -0
  12. package/extensions/plan-mode/utils.test.ts +261 -0
  13. package/extensions/plan-mode/utils.ts +168 -0
  14. package/package.json +35 -0
  15. package/skills/README.md +70 -0
  16. package/skills/brave-search/SKILL.md +83 -0
  17. package/skills/brave-search/content.js +86 -0
  18. package/skills/brave-search/package-lock.json +623 -0
  19. package/skills/brave-search/package.json +14 -0
  20. package/skills/brave-search/search.js +199 -0
  21. package/skills/code-review/SKILL.md +97 -0
  22. package/skills/code-simplifier/SKILL.md +55 -0
  23. package/skills/context-packer/SKILL.md +77 -0
  24. package/skills/context-packer/prepare-context.sh +490 -0
  25. package/skills/image-compress/SKILL.md +53 -0
  26. package/skills/image-compress/compress.sh +172 -0
  27. package/skills/markdown-converter/SKILL.md +71 -0
  28. package/skills/multi-review/SKILL.md +143 -0
  29. package/skills/package.json +26 -0
  30. package/skills/pr-context-packer/SKILL.md +76 -0
  31. package/skills/pr-context-packer/prepare-pr-context.sh +941 -0
  32. package/skills/session-analyzer/IDEAS.md +42 -0
  33. package/skills/session-analyzer/SKILL.md +81 -0
  34. package/skills/session-analyzer/analyze.js +460 -0
  35. package/skills/session-analyzer/package-lock.json +3943 -0
  36. package/skills/session-analyzer/package.json +7 -0
  37. package/skills/video-compress/SKILL.md +43 -0
  38. package/skills/video-compress/compress.sh +107 -0
  39. package/skills/youtube-transcript/SKILL.md +59 -0
  40. package/skills/youtube-transcript/transcript.sh +46 -0
  41. package/themes/rose-pine-dawn.json +102 -0
  42. package/themes/rose-pine.json +102 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "session-analyzer",
3
+ "type": "module",
4
+ "dependencies": {
5
+ "@mariozechner/pi-coding-agent": "*"
6
+ }
7
+ }
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: video-compress
3
+ description: Compress videos to a target file size using ffmpeg two-pass encoding. Useful for Discord/Slack upload limits.
4
+ ---
5
+
6
+ # Video Compress Skill
7
+
8
+ Compress videos to a target file size using ffmpeg two-pass encoding.
9
+
10
+ ## Usage
11
+
12
+ ```bash
13
+ ~/.pi/repos/pi-skills/video-compress/compress.sh <input> <output> [options]
14
+ ```
15
+
16
+ **Options:**
17
+
18
+ - `--target MB` - Target size in MB (default: 10)
19
+ - `--scale WIDTH` - Scale to width, 0 to disable (default: 1920)
20
+ - `--no-audio` - Remove audio track (good for screen recordings)
21
+
22
+ ## Examples
23
+
24
+ ```bash
25
+ # Discord upload (10MB, no audio)
26
+ compress.sh recording.mov out.mp4 --no-audio
27
+
28
+ # Slack (25MB with audio)
29
+ compress.sh video.mov out.mp4 --target 25
30
+
31
+ # Keep original resolution
32
+ compress.sh video.mov out.mp4 --scale 0
33
+
34
+ # Lower res for very long videos
35
+ compress.sh long.mov out.mp4 --target 10 --scale 1280
36
+ ```
37
+
38
+ ## How it works
39
+
40
+ 1. Gets video duration via ffprobe
41
+ 2. Calculates target bitrate at 95% of target (to stay safely under)
42
+ 3. Runs two-pass x264 encoding
43
+ 4. Scales to 1920px width and 30fps by default
@@ -0,0 +1,107 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Defaults
5
+ TARGET_MB=10
6
+ SCALE=1920
7
+ NO_AUDIO=false
8
+
9
+ # Parse args
10
+ while [[ $# -gt 0 ]]; do
11
+ case $1 in
12
+ --no-audio) NO_AUDIO=true; shift ;;
13
+ --scale) SCALE="$2"; shift 2 ;;
14
+ --target) TARGET_MB="$2"; shift 2 ;;
15
+ -*) echo "Unknown option: $1"; exit 1 ;;
16
+ *)
17
+ if [[ -z "$INPUT" ]]; then INPUT="$1"
18
+ elif [[ -z "$OUTPUT" ]]; then OUTPUT="$1"
19
+ else echo "Too many arguments"; exit 1
20
+ fi
21
+ shift ;;
22
+ esac
23
+ done
24
+
25
+ if [[ -z "$INPUT" || -z "$OUTPUT" ]]; then
26
+ echo "Usage: compress.sh <input> <output> [options]"
27
+ echo ""
28
+ echo "Options:"
29
+ echo " --target MB Target size in MB (default: 10)"
30
+ echo " --scale WIDTH Scale to width, 0 to disable (default: 1920)"
31
+ echo " --no-audio Remove audio track"
32
+ echo ""
33
+ echo "Examples:"
34
+ echo " compress.sh video.mov out.mp4 # 10MB default"
35
+ echo " compress.sh video.mov out.mp4 --target 25 # 25MB for Slack"
36
+ echo " compress.sh video.mov out.mp4 --no-audio # No audio"
37
+ echo " compress.sh video.mov out.mp4 --scale 1280 # Lower res"
38
+ exit 1
39
+ fi
40
+
41
+ if [[ ! -f "$INPUT" ]]; then
42
+ echo "Error: Input file not found: $INPUT"
43
+ exit 1
44
+ fi
45
+
46
+ # Get duration
47
+ DURATION=$(ffprobe -v quiet -show_entries format=duration -of csv=p=0 "$INPUT")
48
+ DURATION_INT=${DURATION%.*}
49
+
50
+ echo "Input: $INPUT"
51
+ echo "Duration: ${DURATION_INT}s"
52
+ echo "Target: ${TARGET_MB}MB"
53
+
54
+ # Calculate bitrate (use 95% of target to stay safely under)
55
+ SAFE_TARGET=$(echo "$TARGET_MB * 0.95" | bc)
56
+ TARGET_KBITS=$(echo "$SAFE_TARGET * 8000 / 1" | bc)
57
+
58
+ if [[ "$NO_AUDIO" == "true" ]]; then
59
+ VIDEO_BITRATE=$((TARGET_KBITS / DURATION_INT))
60
+ AUDIO_OPTS="-an"
61
+ echo "Audio: disabled"
62
+ else
63
+ AUDIO_BITRATE=64
64
+ VIDEO_BITRATE=$((TARGET_KBITS / DURATION_INT - AUDIO_BITRATE))
65
+ AUDIO_OPTS="-c:a aac -b:a ${AUDIO_BITRATE}k"
66
+ echo "Audio: ${AUDIO_BITRATE}k"
67
+ fi
68
+
69
+ # Ensure minimum bitrate
70
+ if [[ $VIDEO_BITRATE -lt 100 ]]; then
71
+ echo "Warning: Target too small for duration, using minimum bitrate"
72
+ VIDEO_BITRATE=100
73
+ fi
74
+
75
+ # Build video filter
76
+ if [[ "$SCALE" == "0" ]]; then
77
+ VF="fps=30"
78
+ echo "Scale: original"
79
+ else
80
+ VF="scale=${SCALE}:-2,fps=30"
81
+ echo "Scale: ${SCALE}px width"
82
+ fi
83
+
84
+ echo "Video: ${VIDEO_BITRATE}k"
85
+ echo ""
86
+
87
+ # Two-pass encoding
88
+ echo "Pass 1/2..."
89
+ ffmpeg -y -i "$INPUT" \
90
+ -vf "$VF" \
91
+ -c:v libx264 -b:v "${VIDEO_BITRATE}k" -pass 1 \
92
+ -an -f null /dev/null 2>/dev/null
93
+
94
+ echo "Pass 2/2..."
95
+ ffmpeg -y -i "$INPUT" \
96
+ -vf "$VF" \
97
+ -c:v libx264 -b:v "${VIDEO_BITRATE}k" -pass 2 \
98
+ $AUDIO_OPTS \
99
+ "$OUTPUT" 2>/dev/null
100
+
101
+ # Cleanup
102
+ rm -f ffmpeg2pass-0.log ffmpeg2pass-0.log.mbtree 2>/dev/null
103
+
104
+ # Report
105
+ FINAL_SIZE=$(ls -lh "$OUTPUT" | awk '{print $5}')
106
+ echo ""
107
+ echo "Done: $OUTPUT ($FINAL_SIZE)"
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: youtube-transcript
3
+ description: Fetch transcripts from YouTube videos using yt-dlp. Supports any language with auto-generated or manual captions. Use for summarization, analysis, or translation tasks.
4
+ ---
5
+
6
+ # YouTube Transcript
7
+
8
+ Fetch transcripts from YouTube videos using `yt-dlp`.
9
+
10
+ ## Requirements
11
+
12
+ ```bash
13
+ brew install yt-dlp jq
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```bash
19
+ {baseDir}/transcript.sh <video-url-or-id> [language]
20
+ ```
21
+
22
+ ## Examples
23
+
24
+ ```bash
25
+ # English (default)
26
+ {baseDir}/transcript.sh "https://youtu.be/dQw4w9WgXcQ"
27
+
28
+ # Polish
29
+ {baseDir}/transcript.sh "https://youtu.be/ksWAT3uqlWA" pl
30
+
31
+ # German
32
+ {baseDir}/transcript.sh "https://www.youtube.com/watch?v=VIDEO_ID" de
33
+
34
+ # Just video ID works too
35
+ {baseDir}/transcript.sh dQw4w9WgXcQ
36
+ ```
37
+
38
+ ## Output
39
+
40
+ Timestamped transcript:
41
+
42
+ ```
43
+ [0:00] [Music]
44
+ [0:18] We're no strangers to
45
+ [0:21] love. You know the rules...
46
+ [1:23] Never gonna give you up
47
+ ```
48
+
49
+ ## Supported Languages
50
+
51
+ Any language code: `en`, `pl`, `de`, `es`, `ja`, `pt`, `fr`, `it`, etc.
52
+
53
+ Use `yt-dlp --list-subs <url>` to see available languages for a video.
54
+
55
+ ## Notes
56
+
57
+ - Works with auto-generated and manual captions
58
+ - Falls back to auto-subs if manual not available
59
+ - No npm/node required - just yt-dlp and jq
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ # Extract YouTube transcript using yt-dlp
3
+
4
+ set -e
5
+
6
+ if [ -z "$1" ]; then
7
+ echo "Usage: transcript.sh <video-url-or-id> [language]"
8
+ echo " language: en (default), pl, de, es, ja, etc."
9
+ exit 1
10
+ fi
11
+
12
+ URL="$1"
13
+ LANG="${2:-en}"
14
+ TMPFILE="/tmp/yt-transcript-$$"
15
+
16
+ trap "rm -f ${TMPFILE}.*.json3" EXIT
17
+
18
+ # Download subtitles (suppress all output)
19
+ yt-dlp --skip-download --write-auto-subs --sub-lang "$LANG" --sub-format json3 \
20
+ -o "$TMPFILE" "$URL" >/dev/null 2>&1
21
+
22
+ SUBFILE=$(ls ${TMPFILE}.*.json3 2>/dev/null | head -1)
23
+
24
+ if [ -z "$SUBFILE" ]; then
25
+ echo "Error: No subtitles found for language '$LANG'" >&2
26
+ exit 1
27
+ fi
28
+
29
+ # Extract text with timestamps
30
+ jq -r '
31
+ .events[]
32
+ | select(.segs)
33
+ | {
34
+ time: (.tStartMs / 1000 | floor),
35
+ text: ([.segs[].utf8 // ""] | join(""))
36
+ }
37
+ | select(.text | test("^\\s*$") | not)
38
+ | "[\(.time | tostring |
39
+ if (. | tonumber) >= 3600 then
40
+ "\((. | tonumber) / 3600 | floor):\(((. | tonumber) % 3600 / 60) | floor | tostring | if length == 1 then "0" + . else . end):\(((. | tonumber) % 60) | tostring | if length == 1 then "0" + . else . end)"
41
+ elif (. | tonumber) >= 60 then
42
+ "\((. | tonumber) / 60 | floor):\(((. | tonumber) % 60) | tostring | if length == 1 then "0" + . else . end)"
43
+ else
44
+ "0:\(. | if length == 1 then "0" + . else . end)"
45
+ end)] \(.text)"
46
+ ' "$SUBFILE"
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "rose-pine-dawn",
3
+ "vars": {
4
+ "base": "#faf4ed",
5
+ "baseDark1": "#f6ecdf",
6
+ "baseLight1": "#fcf9f6",
7
+ "surface": "#fffaf3",
8
+ "surfaceDark1": "#fff2de",
9
+ "surfaceLight1": "#ffffff",
10
+ "overlay": "#f2e9e1",
11
+ "overlayDark1": "#eadcce",
12
+ "overlayLight1": "#f7f2ed",
13
+ "muted": "#9893a5",
14
+ "mutedDark1": "#7f798f",
15
+ "mutedLight1": "#a8a3b3",
16
+ "subtle": "#797593",
17
+ "subtleDark1": "#5c5872",
18
+ "subtleLight1": "#8f8ba3",
19
+ "text": "#575279",
20
+ "textDark1": "#2f2c42",
21
+ "textLight1": "#7b7b7b",
22
+ "love": "#b4637a",
23
+ "loveDark1": "#8e4459",
24
+ "loveLight1": "#c28093",
25
+ "gold": "#ea9d34",
26
+ "goldDark1": "#c17814",
27
+ "goldLight1": "#efb25d",
28
+ "rose": "#d7827e",
29
+ "roseDark1": "#c54943",
30
+ "roseLight1": "#e2a6a3",
31
+ "pine": "#286983",
32
+ "pineDark1": "#1d4c5f",
33
+ "pineLight1": "#2f7b9a",
34
+ "foam": "#56949f",
35
+ "foamDark1": "#3c676f",
36
+ "foamLight1": "#71a8b2",
37
+ "iris": "#907aa9",
38
+ "irisDark1": "#685380",
39
+ "irisLight1": "#a998bd",
40
+ "highlightLow": "#f4ede8",
41
+ "highlightMed": "#dfdad9",
42
+ "highlightHigh": "#cecacd"
43
+ },
44
+ "colors": {
45
+ "accent": "irisDark1",
46
+ "border": "overlayDark1",
47
+ "borderAccent": "iris",
48
+ "borderMuted": "overlay",
49
+ "success": "foamDark1",
50
+ "error": "loveDark1",
51
+ "warning": "goldDark1",
52
+ "muted": "muted",
53
+ "dim": "mutedLight1",
54
+ "text": "text",
55
+ "thinkingText": "loveDark1",
56
+ "selectedBg": "highlightMed",
57
+ "userMessageBg": "overlay",
58
+ "userMessageText": "text",
59
+ "customMessageBg": "surface",
60
+ "customMessageText": "foamDark1",
61
+ "customMessageLabel": "irisDark1",
62
+ "toolPendingBg": "highlightLow",
63
+ "toolSuccessBg": "highlightLow",
64
+ "toolErrorBg": "highlightLow",
65
+ "toolTitle": "pineDark1",
66
+ "toolOutput": "subtleDark1",
67
+ "mdHeading": "irisDark1",
68
+ "mdLink": "pine",
69
+ "mdLinkUrl": "muted",
70
+ "mdCode": "roseDark1",
71
+ "mdCodeBlock": "text",
72
+ "mdCodeBlockBorder": "overlayDark1",
73
+ "mdQuote": "subtle",
74
+ "mdQuoteBorder": "overlayDark1",
75
+ "mdHr": "overlayDark1",
76
+ "mdListBullet": "foamDark1",
77
+ "toolDiffAdded": "foamDark1",
78
+ "toolDiffRemoved": "loveDark1",
79
+ "toolDiffContext": "subtle",
80
+ "syntaxComment": "muted",
81
+ "syntaxKeyword": "pineDark1",
82
+ "syntaxFunction": "foamDark1",
83
+ "syntaxVariable": "text",
84
+ "syntaxString": "goldDark1",
85
+ "syntaxNumber": "rose",
86
+ "syntaxType": "irisDark1",
87
+ "syntaxOperator": "subtle",
88
+ "syntaxPunctuation": "muted",
89
+ "thinkingOff": "overlayDark1",
90
+ "thinkingMinimal": "pineDark1",
91
+ "thinkingLow": "foamDark1",
92
+ "thinkingMedium": "irisDark1",
93
+ "thinkingHigh": "roseDark1",
94
+ "thinkingXhigh": "loveDark1",
95
+ "bashMode": "goldDark1"
96
+ },
97
+ "export": {
98
+ "pageBg": "base",
99
+ "cardBg": "surface",
100
+ "infoBg": "highlightLow"
101
+ }
102
+ }
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "rose-pine",
3
+ "vars": {
4
+ "base": "#191724",
5
+ "baseDark1": "#131019",
6
+ "baseLight1": "#1e1b2b",
7
+ "surface": "#1f1d2e",
8
+ "surfaceDark1": "#171521",
9
+ "surfaceLight1": "#24223a",
10
+ "overlay": "#26233a",
11
+ "overlayDark1": "#1e1b2d",
12
+ "overlayLight1": "#2d2a44",
13
+ "muted": "#6e6a86",
14
+ "mutedDark1": "#58556b",
15
+ "mutedLight1": "#7d7995",
16
+ "subtle": "#908caa",
17
+ "subtleDark1": "#6e698f",
18
+ "subtleLight1": "#a6a2ba",
19
+ "text": "#e0def4",
20
+ "textDark1": "#9e98dd",
21
+ "textLight1": "#ffffff",
22
+ "love": "#eb6f92",
23
+ "loveDark1": "#e33264",
24
+ "loveLight1": "#f095af",
25
+ "gold": "#f6c177",
26
+ "goldDark1": "#f1a233",
27
+ "goldLight1": "#f9d5a2",
28
+ "rose": "#ebbcba",
29
+ "roseDark1": "#e07f7c",
30
+ "roseLight1": "#f3d7d5",
31
+ "pine": "#31748f",
32
+ "pineDark1": "#265a6e",
33
+ "pineLight1": "#3d8ba9",
34
+ "foam": "#9ccfd8",
35
+ "foamDark1": "#67b5c3",
36
+ "foamLight1": "#bddfe5",
37
+ "iris": "#c4a7e7",
38
+ "irisDark1": "#9a68d6",
39
+ "irisLight1": "#decef2",
40
+ "highlightLow": "#21202e",
41
+ "highlightMed": "#403d52",
42
+ "highlightHigh": "#524f67"
43
+ },
44
+ "colors": {
45
+ "accent": "iris",
46
+ "border": "overlayDark1",
47
+ "borderAccent": "irisDark1",
48
+ "borderMuted": "overlayDark1",
49
+ "success": "foam",
50
+ "error": "love",
51
+ "warning": "gold",
52
+ "muted": "muted",
53
+ "dim": "subtleDark1",
54
+ "text": "text",
55
+ "thinkingText": "loveLight1",
56
+ "selectedBg": "loveDark1",
57
+ "userMessageBg": "surfaceLight1",
58
+ "userMessageText": "roseLight1",
59
+ "customMessageBg": "surfaceDark1",
60
+ "customMessageText": "foamLight1",
61
+ "customMessageLabel": "irisLight1",
62
+ "toolPendingBg": "overlayDark1",
63
+ "toolSuccessBg": "overlayDark1",
64
+ "toolErrorBg": "overlayDark1",
65
+ "toolTitle": "pineLight1",
66
+ "toolOutput": "textDark1",
67
+ "mdHeading": "irisLight1",
68
+ "mdLink": "foam",
69
+ "mdLinkUrl": "pineDark1",
70
+ "mdCode": "roseLight1",
71
+ "mdCodeBlock": "textDark1",
72
+ "mdCodeBlockBorder": "overlayLight1",
73
+ "mdQuote": "subtleDark1",
74
+ "mdQuoteBorder": "overlayDark1",
75
+ "mdHr": "overlayDark1",
76
+ "mdListBullet": "foamDark1",
77
+ "toolDiffAdded": "foamLight1",
78
+ "toolDiffRemoved": "loveLight1",
79
+ "toolDiffContext": "subtleDark1",
80
+ "syntaxComment": "mutedDark1",
81
+ "syntaxKeyword": "pine",
82
+ "syntaxFunction": "foamLight1",
83
+ "syntaxVariable": "textDark1",
84
+ "syntaxString": "goldLight1",
85
+ "syntaxNumber": "rose",
86
+ "syntaxType": "irisLight1",
87
+ "syntaxOperator": "subtleDark1",
88
+ "syntaxPunctuation": "mutedDark1",
89
+ "thinkingOff": "mutedDark1",
90
+ "thinkingMinimal": "pineDark1",
91
+ "thinkingLow": "foamDark1",
92
+ "thinkingMedium": "iris",
93
+ "thinkingHigh": "roseLight1",
94
+ "thinkingXhigh": "love",
95
+ "bashMode": "gold"
96
+ },
97
+ "export": {
98
+ "pageBg": "base",
99
+ "cardBg": "surface",
100
+ "infoBg": "highlightLow"
101
+ }
102
+ }