mitsupi 1.0.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.
- package/LICENSE +201 -0
- package/README.md +95 -0
- package/TODO.md +11 -0
- package/commands/handoff.md +100 -0
- package/commands/make-release.md +75 -0
- package/commands/pickup.md +30 -0
- package/commands/update-changelog.md +78 -0
- package/package.json +22 -0
- package/pi-extensions/answer.ts +527 -0
- package/pi-extensions/codex-tuning.ts +632 -0
- package/pi-extensions/commit.ts +248 -0
- package/pi-extensions/cwd-history.ts +237 -0
- package/pi-extensions/issues.ts +548 -0
- package/pi-extensions/loop.ts +446 -0
- package/pi-extensions/qna.ts +167 -0
- package/pi-extensions/reveal.ts +689 -0
- package/pi-extensions/review.ts +807 -0
- package/pi-themes/armin.json +81 -0
- package/pi-themes/nightowl.json +82 -0
- package/skills/anachb/SKILL.md +183 -0
- package/skills/anachb/departures.sh +79 -0
- package/skills/anachb/disruptions.sh +53 -0
- package/skills/anachb/route.sh +87 -0
- package/skills/anachb/search.sh +43 -0
- package/skills/ghidra/SKILL.md +254 -0
- package/skills/ghidra/scripts/find-ghidra.sh +54 -0
- package/skills/ghidra/scripts/ghidra-analyze.sh +239 -0
- package/skills/ghidra/scripts/ghidra_scripts/ExportAll.java +278 -0
- package/skills/ghidra/scripts/ghidra_scripts/ExportCalls.java +148 -0
- package/skills/ghidra/scripts/ghidra_scripts/ExportDecompiled.java +84 -0
- package/skills/ghidra/scripts/ghidra_scripts/ExportFunctions.java +114 -0
- package/skills/ghidra/scripts/ghidra_scripts/ExportStrings.java +123 -0
- package/skills/ghidra/scripts/ghidra_scripts/ExportSymbols.java +135 -0
- package/skills/github/SKILL.md +47 -0
- package/skills/improve-skill/SKILL.md +155 -0
- package/skills/improve-skill/scripts/extract-session.js +349 -0
- package/skills/oebb-scotty/SKILL.md +429 -0
- package/skills/oebb-scotty/arrivals.sh +83 -0
- package/skills/oebb-scotty/departures.sh +83 -0
- package/skills/oebb-scotty/disruptions.sh +33 -0
- package/skills/oebb-scotty/search-station.sh +36 -0
- package/skills/oebb-scotty/trip.sh +119 -0
- package/skills/openscad/SKILL.md +232 -0
- package/skills/openscad/examples/parametric_box.scad +92 -0
- package/skills/openscad/examples/phone_stand.scad +95 -0
- package/skills/openscad/tools/common.sh +50 -0
- package/skills/openscad/tools/export-stl.sh +56 -0
- package/skills/openscad/tools/extract-params.sh +147 -0
- package/skills/openscad/tools/multi-preview.sh +68 -0
- package/skills/openscad/tools/preview.sh +74 -0
- package/skills/openscad/tools/render-with-params.sh +91 -0
- package/skills/openscad/tools/validate.sh +46 -0
- package/skills/pi-share/SKILL.md +105 -0
- package/skills/pi-share/fetch-session.mjs +322 -0
- package/skills/sentry/SKILL.md +239 -0
- package/skills/sentry/lib/auth.js +99 -0
- package/skills/sentry/scripts/fetch-event.js +329 -0
- package/skills/sentry/scripts/fetch-issue.js +356 -0
- package/skills/sentry/scripts/list-issues.js +239 -0
- package/skills/sentry/scripts/search-events.js +291 -0
- package/skills/sentry/scripts/search-logs.js +240 -0
- package/skills/tmux/SKILL.md +105 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/web-browser/SKILL.md +91 -0
- package/skills/web-browser/scripts/cdp.js +210 -0
- package/skills/web-browser/scripts/dismiss-cookies.js +373 -0
- package/skills/web-browser/scripts/eval.js +68 -0
- package/skills/web-browser/scripts/logs-tail.js +69 -0
- package/skills/web-browser/scripts/nav.js +65 -0
- package/skills/web-browser/scripts/net-summary.js +94 -0
- package/skills/web-browser/scripts/package-lock.json +33 -0
- package/skills/web-browser/scripts/package.json +6 -0
- package/skills/web-browser/scripts/pick.js +165 -0
- package/skills/web-browser/scripts/screenshot.js +52 -0
- package/skills/web-browser/scripts/start.js +80 -0
- package/skills/web-browser/scripts/watch.js +266 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Extract customizable parameters from an OpenSCAD file
|
|
3
|
+
# Usage: extract-params.sh input.scad [--json]
|
|
4
|
+
#
|
|
5
|
+
# Parses parameter declarations with special comments:
|
|
6
|
+
# param = value; // [min:max] Description
|
|
7
|
+
# param = value; // [min:step:max] Description
|
|
8
|
+
# param = value; // [opt1, opt2] Description
|
|
9
|
+
# param = value; // Description only
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
if [ $# -lt 1 ]; then
|
|
14
|
+
echo "Usage: $0 input.scad [--json]"
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
INPUT="$1"
|
|
19
|
+
JSON_OUTPUT=false
|
|
20
|
+
|
|
21
|
+
if [ "$2" = "--json" ]; then
|
|
22
|
+
JSON_OUTPUT=true
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ ! -f "$INPUT" ]; then
|
|
26
|
+
echo "Error: File not found: $INPUT"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Extract parameters using Python for better parsing
|
|
31
|
+
extract_params() {
|
|
32
|
+
python3 -c '
|
|
33
|
+
import sys
|
|
34
|
+
import re
|
|
35
|
+
|
|
36
|
+
filename = sys.argv[1]
|
|
37
|
+
in_block = 0
|
|
38
|
+
|
|
39
|
+
with open(filename, "r") as f:
|
|
40
|
+
for line in f:
|
|
41
|
+
# Track block depth (skip params inside modules/functions)
|
|
42
|
+
in_block += line.count("{") - line.count("}")
|
|
43
|
+
if in_block > 0:
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
# Match: varname = value; // comment
|
|
47
|
+
match = re.match(r"^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*([^;]+);\s*(?://\s*(.*))?", line)
|
|
48
|
+
if not match:
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
var_name = match.group(1)
|
|
52
|
+
value = match.group(2).strip()
|
|
53
|
+
comment = match.group(3) or ""
|
|
54
|
+
|
|
55
|
+
# Determine type
|
|
56
|
+
if value in ("true", "false"):
|
|
57
|
+
var_type = "boolean"
|
|
58
|
+
elif re.match(r"^-?\d+$", value):
|
|
59
|
+
var_type = "integer"
|
|
60
|
+
elif re.match(r"^-?\d*\.?\d+$", value):
|
|
61
|
+
var_type = "number"
|
|
62
|
+
elif value.startswith("\"") and value.endswith("\""):
|
|
63
|
+
var_type = "string"
|
|
64
|
+
value = value[1:-1] # Remove quotes
|
|
65
|
+
elif value.startswith("["):
|
|
66
|
+
var_type = "array"
|
|
67
|
+
else:
|
|
68
|
+
var_type = "expression"
|
|
69
|
+
|
|
70
|
+
# Parse comment for range/options
|
|
71
|
+
range_val = ""
|
|
72
|
+
options_val = ""
|
|
73
|
+
description = comment
|
|
74
|
+
|
|
75
|
+
range_match = re.match(r"\[([^\]]+)\]\s*(.*)", comment)
|
|
76
|
+
if range_match:
|
|
77
|
+
bracket_content = range_match.group(1)
|
|
78
|
+
description = range_match.group(2)
|
|
79
|
+
|
|
80
|
+
# Check if numeric range (contains :) or options (contains ,)
|
|
81
|
+
if ":" in bracket_content and not "," in bracket_content:
|
|
82
|
+
range_val = bracket_content
|
|
83
|
+
else:
|
|
84
|
+
options_val = bracket_content
|
|
85
|
+
|
|
86
|
+
# Output pipe-delimited
|
|
87
|
+
print(f"{var_name}|{value}|{var_type}|{range_val}|{options_val}|{description}")
|
|
88
|
+
' "$INPUT"
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if [ "$JSON_OUTPUT" = true ]; then
|
|
92
|
+
echo "["
|
|
93
|
+
first=true
|
|
94
|
+
while IFS='|' read -r name value type range options description; do
|
|
95
|
+
if [ "$first" = true ]; then
|
|
96
|
+
first=false
|
|
97
|
+
else
|
|
98
|
+
echo ","
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Escape quotes in values
|
|
102
|
+
value=$(echo "$value" | sed 's/"/\\"/g')
|
|
103
|
+
description=$(echo "$description" | sed 's/"/\\"/g')
|
|
104
|
+
|
|
105
|
+
# Build JSON object
|
|
106
|
+
printf ' {\n'
|
|
107
|
+
printf ' "name": "%s",\n' "$name"
|
|
108
|
+
printf ' "value": "%s",\n' "$value"
|
|
109
|
+
printf ' "type": "%s"' "$type"
|
|
110
|
+
|
|
111
|
+
if [ -n "$range" ]; then
|
|
112
|
+
printf ',\n "range": "%s"' "$range"
|
|
113
|
+
fi
|
|
114
|
+
if [ -n "$options" ]; then
|
|
115
|
+
printf ',\n "options": "%s"' "$options"
|
|
116
|
+
fi
|
|
117
|
+
if [ -n "$description" ]; then
|
|
118
|
+
printf ',\n "description": "%s"' "$description"
|
|
119
|
+
fi
|
|
120
|
+
printf '\n }'
|
|
121
|
+
done < <(extract_params)
|
|
122
|
+
echo ""
|
|
123
|
+
echo "]"
|
|
124
|
+
else
|
|
125
|
+
echo "Parameters in: $INPUT"
|
|
126
|
+
echo "==============================================="
|
|
127
|
+
printf "%-20s %-15s %-10s %s\n" "NAME" "VALUE" "TYPE" "CONSTRAINT/DESC"
|
|
128
|
+
echo "-----------------------------------------------"
|
|
129
|
+
|
|
130
|
+
while IFS='|' read -r name value type range options description; do
|
|
131
|
+
constraint=""
|
|
132
|
+
if [ -n "$range" ]; then
|
|
133
|
+
constraint="[$range]"
|
|
134
|
+
elif [ -n "$options" ]; then
|
|
135
|
+
constraint="[$options]"
|
|
136
|
+
fi
|
|
137
|
+
if [ -n "$description" ]; then
|
|
138
|
+
if [ -n "$constraint" ]; then
|
|
139
|
+
constraint="$constraint $description"
|
|
140
|
+
else
|
|
141
|
+
constraint="$description"
|
|
142
|
+
fi
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
printf "%-20s %-15s %-10s %s\n" "$name" "$value" "$type" "$constraint"
|
|
146
|
+
done < <(extract_params)
|
|
147
|
+
fi
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Generate preview images from multiple angles
|
|
3
|
+
# Usage: multi-preview.sh input.scad output_dir/ [-D 'var=value']
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
source "$SCRIPT_DIR/common.sh"
|
|
9
|
+
|
|
10
|
+
check_openscad
|
|
11
|
+
|
|
12
|
+
if [ $# -lt 2 ]; then
|
|
13
|
+
echo "Usage: $0 input.scad output_dir/ [-D 'var=value' ...]"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
INPUT="$1"
|
|
18
|
+
OUTPUT_DIR="$2"
|
|
19
|
+
shift 2
|
|
20
|
+
|
|
21
|
+
# Collect -D parameters
|
|
22
|
+
DEFINES=()
|
|
23
|
+
while [ $# -gt 0 ]; do
|
|
24
|
+
case "$1" in
|
|
25
|
+
-D)
|
|
26
|
+
shift
|
|
27
|
+
DEFINES+=("-D" "$1")
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
shift
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
mkdir -p "$OUTPUT_DIR"
|
|
34
|
+
|
|
35
|
+
# Get base name without extension
|
|
36
|
+
BASENAME=$(basename "$INPUT" .scad)
|
|
37
|
+
|
|
38
|
+
echo "Generating multi-angle previews for: $INPUT"
|
|
39
|
+
echo "Output directory: $OUTPUT_DIR"
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
# Define angles as name:camera pairs
|
|
43
|
+
# Camera format: translate_x,translate_y,translate_z,rot_x,rot_y,rot_z,distance
|
|
44
|
+
ANGLES="iso:0,0,0,55,0,25,0
|
|
45
|
+
front:0,0,0,90,0,0,0
|
|
46
|
+
back:0,0,0,90,0,180,0
|
|
47
|
+
left:0,0,0,90,0,90,0
|
|
48
|
+
right:0,0,0,90,0,-90,0
|
|
49
|
+
top:0,0,0,0,0,0,0"
|
|
50
|
+
|
|
51
|
+
echo "$ANGLES" | while IFS=: read -r angle camera; do
|
|
52
|
+
output="$OUTPUT_DIR/${BASENAME}_${angle}.png"
|
|
53
|
+
|
|
54
|
+
echo " Rendering $angle view..."
|
|
55
|
+
$OPENSCAD \
|
|
56
|
+
--camera="$camera" \
|
|
57
|
+
--imgsize="800,600" \
|
|
58
|
+
--colorscheme="Tomorrow Night" \
|
|
59
|
+
--autocenter \
|
|
60
|
+
--viewall \
|
|
61
|
+
"${DEFINES[@]}" \
|
|
62
|
+
-o "$output" \
|
|
63
|
+
"$INPUT" 2>/dev/null
|
|
64
|
+
done
|
|
65
|
+
|
|
66
|
+
echo ""
|
|
67
|
+
echo "Generated previews:"
|
|
68
|
+
ls -la "$OUTPUT_DIR"/${BASENAME}_*.png
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Generate a preview PNG from an OpenSCAD file
|
|
3
|
+
# Usage: preview.sh input.scad output.png [options]
|
|
4
|
+
#
|
|
5
|
+
# Options:
|
|
6
|
+
# --camera=x,y,z,rx,ry,rz,dist Camera position
|
|
7
|
+
# --size=WxH Image size (default: 800x600)
|
|
8
|
+
# -D 'var=value' Set parameter value
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
+
source "$SCRIPT_DIR/common.sh"
|
|
14
|
+
|
|
15
|
+
check_openscad
|
|
16
|
+
|
|
17
|
+
if [ $# -lt 2 ]; then
|
|
18
|
+
echo "Usage: $0 input.scad output.png [--camera=...] [--size=WxH] [-D 'var=val']"
|
|
19
|
+
echo ""
|
|
20
|
+
echo "Camera format: x,y,z,rotx,roty,rotz,distance"
|
|
21
|
+
echo "Common cameras:"
|
|
22
|
+
echo " Isometric: --camera=0,0,0,55,0,25,200"
|
|
23
|
+
echo " Front: --camera=0,0,0,90,0,0,200"
|
|
24
|
+
echo " Top: --camera=0,0,0,0,0,0,200"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
INPUT="$1"
|
|
29
|
+
OUTPUT="$2"
|
|
30
|
+
shift 2
|
|
31
|
+
|
|
32
|
+
# Defaults
|
|
33
|
+
CAMERA="0,0,0,55,0,25,0"
|
|
34
|
+
SIZE="800,600"
|
|
35
|
+
DEFINES=()
|
|
36
|
+
|
|
37
|
+
# Parse options
|
|
38
|
+
while [ $# -gt 0 ]; do
|
|
39
|
+
case "$1" in
|
|
40
|
+
--camera=*)
|
|
41
|
+
CAMERA="${1#--camera=}"
|
|
42
|
+
;;
|
|
43
|
+
--size=*)
|
|
44
|
+
SIZE="${1#--size=}"
|
|
45
|
+
SIZE="${SIZE/x/,}"
|
|
46
|
+
;;
|
|
47
|
+
-D)
|
|
48
|
+
shift
|
|
49
|
+
DEFINES+=("-D" "$1")
|
|
50
|
+
;;
|
|
51
|
+
*)
|
|
52
|
+
echo "Unknown option: $1"
|
|
53
|
+
exit 1
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
shift
|
|
57
|
+
done
|
|
58
|
+
|
|
59
|
+
# Ensure output directory exists
|
|
60
|
+
mkdir -p "$(dirname "$OUTPUT")"
|
|
61
|
+
|
|
62
|
+
# Run OpenSCAD
|
|
63
|
+
echo "Rendering preview: $INPUT -> $OUTPUT"
|
|
64
|
+
$OPENSCAD \
|
|
65
|
+
--camera="$CAMERA" \
|
|
66
|
+
--imgsize="${SIZE}" \
|
|
67
|
+
--colorscheme="Tomorrow Night" \
|
|
68
|
+
--autocenter \
|
|
69
|
+
--viewall \
|
|
70
|
+
"${DEFINES[@]}" \
|
|
71
|
+
-o "$OUTPUT" \
|
|
72
|
+
"$INPUT"
|
|
73
|
+
|
|
74
|
+
echo "Preview saved to: $OUTPUT"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Render OpenSCAD with parameters from a JSON file
|
|
3
|
+
# Usage: render-with-params.sh input.scad params.json output.stl|output.png
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
source "$SCRIPT_DIR/common.sh"
|
|
9
|
+
|
|
10
|
+
check_openscad
|
|
11
|
+
|
|
12
|
+
if [ $# -lt 3 ]; then
|
|
13
|
+
echo "Usage: $0 input.scad params.json output.[stl|png]"
|
|
14
|
+
echo ""
|
|
15
|
+
echo "params.json format:"
|
|
16
|
+
echo ' {"width": 60, "height": 40, "include_lid": true}'
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
INPUT="$1"
|
|
21
|
+
PARAMS_FILE="$2"
|
|
22
|
+
OUTPUT="$3"
|
|
23
|
+
|
|
24
|
+
if [ ! -f "$INPUT" ]; then
|
|
25
|
+
echo "Error: Input file not found: $INPUT"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if [ ! -f "$PARAMS_FILE" ]; then
|
|
30
|
+
echo "Error: Params file not found: $PARAMS_FILE"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Build -D arguments from JSON
|
|
35
|
+
DEFINES=()
|
|
36
|
+
while IFS= read -r line; do
|
|
37
|
+
# Parse each key-value pair
|
|
38
|
+
key=$(echo "$line" | cut -d'=' -f1)
|
|
39
|
+
value=$(echo "$line" | cut -d'=' -f2-)
|
|
40
|
+
|
|
41
|
+
if [ -n "$key" ]; then
|
|
42
|
+
DEFINES+=("-D" "$key=$value")
|
|
43
|
+
fi
|
|
44
|
+
done < <(
|
|
45
|
+
# Use python or jq to parse JSON to key=value lines
|
|
46
|
+
if command -v python3 &> /dev/null; then
|
|
47
|
+
python3 -c "
|
|
48
|
+
import json
|
|
49
|
+
with open('$PARAMS_FILE') as f:
|
|
50
|
+
params = json.load(f)
|
|
51
|
+
for k, v in params.items():
|
|
52
|
+
if isinstance(v, bool):
|
|
53
|
+
print(f'{k}={str(v).lower()}')
|
|
54
|
+
elif isinstance(v, str):
|
|
55
|
+
print(f'{k}=\"{v}\"')
|
|
56
|
+
else:
|
|
57
|
+
print(f'{k}={v}')
|
|
58
|
+
"
|
|
59
|
+
elif command -v jq &> /dev/null; then
|
|
60
|
+
jq -r 'to_entries | .[] | "\(.key)=\(.value)"' "$PARAMS_FILE"
|
|
61
|
+
else
|
|
62
|
+
echo "Error: Requires python3 or jq to parse JSON"
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
echo "Rendering with parameters from: $PARAMS_FILE"
|
|
68
|
+
echo "Parameters: ${DEFINES[*]}"
|
|
69
|
+
|
|
70
|
+
# Determine output type and set appropriate options
|
|
71
|
+
EXT="${OUTPUT##*.}"
|
|
72
|
+
case "$EXT" in
|
|
73
|
+
stl|STL)
|
|
74
|
+
$OPENSCAD "${DEFINES[@]}" -o "$OUTPUT" "$INPUT"
|
|
75
|
+
;;
|
|
76
|
+
png|PNG)
|
|
77
|
+
$OPENSCAD "${DEFINES[@]}" \
|
|
78
|
+
--camera="0,0,0,55,0,25,0" \
|
|
79
|
+
--imgsize="800,600" \
|
|
80
|
+
--colorscheme="Tomorrow Night" \
|
|
81
|
+
--autocenter --viewall \
|
|
82
|
+
-o "$OUTPUT" "$INPUT"
|
|
83
|
+
;;
|
|
84
|
+
*)
|
|
85
|
+
echo "Unsupported output format: $EXT"
|
|
86
|
+
echo "Supported: stl, png"
|
|
87
|
+
exit 1
|
|
88
|
+
;;
|
|
89
|
+
esac
|
|
90
|
+
|
|
91
|
+
echo "Output saved: $OUTPUT"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Validate an OpenSCAD file for syntax errors
|
|
3
|
+
# Usage: validate.sh input.scad
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
source "$SCRIPT_DIR/common.sh"
|
|
9
|
+
|
|
10
|
+
check_openscad
|
|
11
|
+
|
|
12
|
+
if [ $# -lt 1 ]; then
|
|
13
|
+
echo "Usage: $0 input.scad"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
INPUT="$1"
|
|
18
|
+
|
|
19
|
+
if [ ! -f "$INPUT" ]; then
|
|
20
|
+
echo "Error: File not found: $INPUT"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
echo "Validating: $INPUT"
|
|
25
|
+
|
|
26
|
+
# Create temp file for output
|
|
27
|
+
TEMP_OUTPUT=$(mktemp /tmp/openscad_validate.XXXXXX.echo)
|
|
28
|
+
trap "rm -f $TEMP_OUTPUT" EXIT
|
|
29
|
+
|
|
30
|
+
# Run OpenSCAD with echo output (fastest way to check syntax)
|
|
31
|
+
# Using --export-format=echo just parses and evaluates without rendering
|
|
32
|
+
if $OPENSCAD -o "$TEMP_OUTPUT" --export-format=echo "$INPUT" 2>&1; then
|
|
33
|
+
echo "✓ Syntax OK"
|
|
34
|
+
|
|
35
|
+
# Check for warnings in stderr
|
|
36
|
+
if [ -s "$TEMP_OUTPUT" ]; then
|
|
37
|
+
echo ""
|
|
38
|
+
echo "Echo output:"
|
|
39
|
+
cat "$TEMP_OUTPUT"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
exit 0
|
|
43
|
+
else
|
|
44
|
+
echo "✗ Validation failed"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-share
|
|
3
|
+
description: "Load and parse session transcripts from shittycodingagent.ai/buildwithpi.ai/buildwithpi.com (pi-share) URLs. Fetches gists, decodes embedded session data, and extracts conversation history."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pi-share / buildwithpi Session Loader
|
|
7
|
+
|
|
8
|
+
Load and parse session transcripts from pi-share URLs (shittycodingagent.ai, buildwithpi.ai, buildwithpi.com).
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
**Loading sessions:** Use this skill when the user provides a URL like:
|
|
13
|
+
- `https://shittycodingagent.ai/session/?<gist_id>`
|
|
14
|
+
- `https://buildwithpi.ai/session/?<gist_id>`
|
|
15
|
+
- `https://buildwithpi.com/session/?<gist_id>`
|
|
16
|
+
- Or just a gist ID like `46aee35206aefe99257bc5d5e60c6121`
|
|
17
|
+
|
|
18
|
+
**Human summaries:** Use `--human-summary` when the user asks you to:
|
|
19
|
+
- Summarize what a human did in a pi/coding agent session
|
|
20
|
+
- Understand how a user interacted with an agent
|
|
21
|
+
- Analyze user behavior, steering patterns, or prompting style
|
|
22
|
+
- Get a human-centric view of a session (not what the agent did, but what the human did)
|
|
23
|
+
|
|
24
|
+
The human summary focuses on: initial goals, re-prompts, steering/corrections, interventions, and overall prompting style.
|
|
25
|
+
|
|
26
|
+
## How It Works
|
|
27
|
+
|
|
28
|
+
1. Session exports are stored as GitHub Gists
|
|
29
|
+
2. The URL contains a gist ID after the `?`
|
|
30
|
+
3. The gist contains a `session.html` file with base64-encoded session data
|
|
31
|
+
4. The helper script fetches and decodes this to extract the full conversation
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Get full session data (default)
|
|
37
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs "<url-or-gist-id>"
|
|
38
|
+
|
|
39
|
+
# Get just the header
|
|
40
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs <gist-id> --header
|
|
41
|
+
|
|
42
|
+
# Get entries as JSON lines (one entry per line)
|
|
43
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs <gist-id> --entries
|
|
44
|
+
|
|
45
|
+
# Get the system prompt
|
|
46
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs <gist-id> --system
|
|
47
|
+
|
|
48
|
+
# Get tool definitions
|
|
49
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs <gist-id> --tools
|
|
50
|
+
|
|
51
|
+
# Get human-centric summary (what did the human do in this session?)
|
|
52
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs <gist-id> --human-summary
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Human Summary
|
|
56
|
+
|
|
57
|
+
The `--human-summary` flag generates a ~300 word summary focused on the human's experience:
|
|
58
|
+
- What was their initial goal?
|
|
59
|
+
- How often did they re-prompt or steer the agent?
|
|
60
|
+
- What kind of interventions did they make? (corrections, clarifications, frustration)
|
|
61
|
+
- How specific or vague were their instructions?
|
|
62
|
+
|
|
63
|
+
This uses claude-haiku-4-5 via `pi -p` to analyze the condensed session transcript.
|
|
64
|
+
|
|
65
|
+
## Session Data Structure
|
|
66
|
+
|
|
67
|
+
The decoded session contains:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface SessionData {
|
|
71
|
+
header: {
|
|
72
|
+
type: "session";
|
|
73
|
+
version: number;
|
|
74
|
+
id: string; // Session UUID
|
|
75
|
+
timestamp: string; // ISO timestamp
|
|
76
|
+
cwd: string; // Working directory
|
|
77
|
+
};
|
|
78
|
+
entries: SessionEntry[]; // Conversation entries (JSON lines format)
|
|
79
|
+
leafId: string | null; // Current branch leaf
|
|
80
|
+
systemPrompt?: string; // System prompt text
|
|
81
|
+
tools?: { name: string; description: string }[];
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Entry types include:
|
|
86
|
+
- `message` - User/assistant/toolResult messages with content blocks
|
|
87
|
+
- `model_change` - Model switches
|
|
88
|
+
- `thinking_level_change` - Thinking mode changes
|
|
89
|
+
- `compaction` - Context compaction events
|
|
90
|
+
|
|
91
|
+
Message content block types:
|
|
92
|
+
- `text` - Text content
|
|
93
|
+
- `toolCall` - Tool invocation with `toolName` and `args`
|
|
94
|
+
- `thinking` - Model thinking content
|
|
95
|
+
- `image` - Embedded images
|
|
96
|
+
|
|
97
|
+
## Example: Analyze a Session
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Pipe entries through jq to filter
|
|
101
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs "<url>" --entries | jq 'select(.type == "message" and .message.role == "user")'
|
|
102
|
+
|
|
103
|
+
# Count tool calls
|
|
104
|
+
node ~/.pi/agent/skills/pi-share/fetch-session.mjs "<url>" --entries | jq -s '[.[] | select(.type == "message") | .message.content[]? | select(.type == "toolCall")] | length'
|
|
105
|
+
```
|