finalize
Finalize orphaned recordings - stop processes, compress, push to orphan branch. TRIGGERS - finalize recording, stop asciinema, orphaned recording
What this skill does
# /asciinema-tools:finalize
Finalize orphaned asciinema recordings: stop running processes gracefully, compress, and push to the orphan branch.
> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
## Arguments
| Argument | Description |
| -------------- | ------------------------------------------ |
| `file` | Specific .cast file to finalize |
| `--all` | Finalize all unhandled .cast files |
| `--force` | Use SIGKILL if graceful stop fails |
| `--no-push` | Skip pushing to orphan branch (local only) |
| `--keep-local` | Keep local .cast after compression |
## Workflow
1. **Discovery**: Find running asciinema processes and unhandled .cast files
2. **Selection**: AskUserQuestion for which files to process
3. **Stop**: Gracefully stop running processes (SIGTERM → SIGINT → SIGKILL)
4. **Verify**: Check file integrity after stop
5. **Compress**: zstd compress .cast files
6. **Push**: Push to orphan branch (if configured)
7. **Cleanup**: Remove local .cast (optional)
## Execution
### Phase 1: Discovery
```bash
/usr/bin/env bash << 'DISCOVER_EOF'
echo "=== Running asciinema processes ==="
PROCS=$(ps aux | grep -E "asciinema rec" | grep -v grep)
if [[ -n "$PROCS" ]]; then
echo "$PROCS" | while read -r line; do
PID=$(echo "$line" | awk '{print $2}')
CAST_FILE=$(echo "$line" | grep -oE '[^ ]+\.cast' | head -1)
if [[ -n "$CAST_FILE" ]]; then
SIZE=$(ls -lh "$CAST_FILE" 2>/dev/null | awk '{print $5}' || echo "?")
echo "PID $PID: $CAST_FILE ($SIZE)"
else
echo "PID $PID: (no file detected)"
fi
done
else
echo "No running asciinema processes"
fi
echo ""
echo "=== Unhandled .cast files ==="
find ~/eon -name "*.cast" -size +1M -mtime -30 2>/dev/null | while read -r f; do
SIZE=$(ls -lh "$f" | awk '{print $5}')
echo "$f ($SIZE)"
done
DISCOVER_EOF
```
### Phase 2: Selection
```yaml
AskUserQuestion:
question: "Which recordings should be finalized?"
header: "Select"
multiSelect: true
options:
- label: "All running processes"
description: "Stop all asciinema rec processes and finalize their files"
- label: "All unhandled files"
description: "Finalize all .cast files found in ~/eon"
- label: "Specific file"
description: "Enter path to specific .cast file"
```
### Phase 3: Stop Running Processes
```bash
/usr/bin/env bash << 'STOP_EOF'
# Arguments: PID list
PIDS="$@"
for PID in $PIDS; do
echo "Stopping PID $PID..."
# Try SIGTERM first (graceful)
kill -TERM "$PID" 2>/dev/null
sleep 2
if kill -0 "$PID" 2>/dev/null; then
echo " SIGTERM ignored, trying SIGINT..."
kill -INT "$PID" 2>/dev/null
sleep 2
fi
if kill -0 "$PID" 2>/dev/null; then
echo " Process still running. Use --force for SIGKILL"
# Only SIGKILL with --force flag
if [[ "$FORCE" == "true" ]]; then
echo " Sending SIGKILL (file may be truncated)..."
kill -9 "$PID" 2>/dev/null
sleep 1
fi
fi
if ! kill -0 "$PID" 2>/dev/null; then
echo " ✓ Process stopped"
else
echo " ✗ Process still running"
fi
done
STOP_EOF
```
### Phase 4: File Integrity Check
```bash
/usr/bin/env bash << 'CHECK_EOF'
CAST_FILE="$1"
echo "Checking file integrity: $CAST_FILE"
# Check if file exists
if [[ ! -f "$CAST_FILE" ]]; then
echo " ✗ File not found"
exit 1
fi
# Check file size
SIZE=$(stat -f%z "$CAST_FILE" 2>/dev/null || stat -c%s "$CAST_FILE")
echo " Size: $(numfmt --to=iec-i "$SIZE" 2>/dev/null || echo "$SIZE bytes")"
# Check last line (NDJSON should have complete JSON arrays)
LAST_LINE=$(tail -c 500 "$CAST_FILE" | tail -1)
if [[ "$LAST_LINE" == *"]"* ]]; then
echo " ✓ File appears complete (ends with JSON array)"
else
echo " ⚠ File may be truncated (incomplete JSON)"
echo " Note: asciinema 2.0+ streams to disk, so most data is preserved"
fi
# Test with asciinema cat (quick validation)
if timeout 5 asciinema cat "$CAST_FILE" > /dev/null 2>&1; then
echo " ✓ File is playable"
else
echo " ⚠ File may have issues (but often still usable)"
fi
CHECK_EOF
```
### Phase 5: Compress
```bash
/usr/bin/env bash << 'COMPRESS_EOF'
CAST_FILE="$1"
ZSTD_LEVEL="${2:-6}"
echo "Compressing: $CAST_FILE"
OUTPUT="${CAST_FILE}.zst"
if zstd -"$ZSTD_LEVEL" -f "$CAST_FILE" -o "$OUTPUT"; then
ORIG_SIZE=$(stat -f%z "$CAST_FILE" 2>/dev/null || stat -c%s "$CAST_FILE")
COMP_SIZE=$(stat -f%z "$OUTPUT" 2>/dev/null || stat -c%s "$OUTPUT")
RATIO=$(echo "scale=1; $ORIG_SIZE / $COMP_SIZE" | bc 2>/dev/null || echo "?")
echo " ✓ Compressed: $(basename "$OUTPUT")"
echo " Compression ratio: ${RATIO}:1"
else
echo " ✗ Compression failed"
exit 1
fi
COMPRESS_EOF
```
### Phase 6: Push to Orphan Branch
```bash
/usr/bin/env bash << 'PUSH_EOF'
COMPRESSED_FILE="$1"
RECORDINGS_DIR="$HOME/asciinema_recordings"
# Find the local recordings clone
REPO_DIR=$(find "$RECORDINGS_DIR" -maxdepth 1 -type d -name "*" | head -1)
if [[ -z "$REPO_DIR" ]] || [[ ! -d "$REPO_DIR/.git" ]]; then
echo " ⚠ No orphan branch clone found at $RECORDINGS_DIR"
echo " Run /asciinema-tools:bootstrap to set up orphan branch"
exit 1
fi
echo "Pushing to orphan branch..."
# Copy compressed file
BASENAME=$(basename "$COMPRESSED_FILE")
DEST="$REPO_DIR/recordings/$BASENAME"
mkdir -p "$(dirname "$DEST")"
cp "$COMPRESSED_FILE" "$DEST"
# Commit and push
cd "$REPO_DIR"
git add -A
git commit -m "finalize: $BASENAME" 2>/dev/null || true
# Push with token (prefer env var to avoid process spawning)
GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-$(gh auth token 2>/dev/null || echo "")}}"
if [[ -n "$GH_TOKEN" ]]; then
REMOTE_URL=$(git remote get-url origin)
# Convert to token-authenticated URL
TOKEN_URL=$(echo "$REMOTE_URL" | sed "s|https://github.com|https://[email protected]|")
if git push "$TOKEN_URL" HEAD 2>/dev/null; then
echo " ✓ Pushed to orphan branch"
else
echo " ✗ Push failed (check credentials)"
fi
else
echo " ⚠ No GitHub token, skipping push"
fi
PUSH_EOF
```
### Phase 7: Cleanup Confirmation
```yaml
AskUserQuestion:
question: "Delete local .cast file after successful compression/push?"
header: "Cleanup"
options:
- label: "Yes, delete local .cast"
description: "Remove original .cast file (compressed version preserved)"
- label: "No, keep local"
description: "Keep both .cast and .cast.zst files"
```
## Example Usage
```bash
# Interactive mode - discover and select
/asciinema-tools:finalize
# Finalize specific file
/asciinema-tools:finalize ~/eon/project/tmp/session.cast
# Finalize all with force stop
/asciinema-tools:finalize --all --force
# Local only (no push)
/asciinema-tools:finalize session.cast --no-push
```
## Troubleshooting
| Issue | Cause | Solution |
| --------------------- | ---------------------------- | -------------------------------------- |
| Process won't stop | Hung asciinema process | Use `--force` flag for SIGKILL |
| File may be truncated | Forced stop interrupted file | Most data preserved, try playing it |
| zstd not found | zstd not installed | `brew install zstd` |
| Push failed | No GitHub token | Set GH_TOKEN or run `gh auth login` |
| No orphan branch | Clone not configured | Run `/asciinema-tools:bootstrap` first |
| File not found | Wrong path or already moved | Check with `/daemon-status` |
## Related Commands
- `/asciinema-tools:daemon-status` - View status and find unhandled files
- `/asciinema-tools:convert` - Convert .cast to .txt for analysis
- `/asciinema-tools:summarize` - AI-powered analysis of recordings
## Post-Execution Reflection
After this skill completes, Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.