Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/branding/teaser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Render outputs are reproducible from the tapes + crt.sh, and the video
# flavor may contain third-party footage — keep the recipe, not the renders.
*.mp4
*.gif
*.png
clip.*
raw*.mp4
26 changes: 26 additions & 0 deletions docs/branding/teaser/banner.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Launch-teaser recording — renders the chrome banner as terminal ANSI art,
# captured to raw.mp4. crt.sh then adds the CRT pass and exports gif + mp4.
#
# brew install vhs chafa
# cd docs/branding/teaser && vhs banner.tape && bash crt.sh
#
# Font: "Departure Mono" (https://departuremono.com) for brand parity; falls
# back to a system mono if not installed. The banner is image-rendered (chafa),
# so the font only affects any typed text.

Output raw.mp4

Set Shell "bash"
Set FontFamily "Menlo"
Set FontSize 20
Set Width 1100
Set Height 620
Set Padding 26
Set TypingSpeed 38ms
Set Theme '{ "name": "korgex-y2k", "background": "#060B16", "foreground": "#D6ECFF", "cursor": "#2DE2FF", "selection": "#16335C", "black": "#0A1120", "red": "#FF5566", "green": "#4DFFA6", "yellow": "#FFD23F", "blue": "#2D9BFF", "magenta": "#B48CFF", "cyan": "#2DE2FF", "white": "#D6ECFF", "brightBlack": "#3A4A63", "brightRed": "#FF7B88", "brightGreen": "#8EFFC4", "brightYellow": "#FFE27A", "brightBlue": "#6CC0FF", "brightMagenta": "#CFB0FF", "brightCyan": "#7DEFFF", "brightWhite": "#F2FAFF" }'

Sleep 500ms
Type "chafa -c full -f symbols --size=88x24 ../../images/banner.jpg"
Sleep 300ms
Enter
Sleep 3400ms
33 changes: 33 additions & 0 deletions docs/branding/teaser/crt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# CRT post-process for the launch teaser.
# Input : raw.mp4 (produced by `vhs banner.tape`)
# Output: teaser-crt.mp4 (CRT-shaded, social/README mp4)
# teaser.gif (palette-optimized GIF for the README)
#
# The CRT look = scanlines (darken every other row) + bloom (screen-blend a
# blurred copy) + a gentle barrel bulge + vignette. All in ffmpeg, no GUI.
set -euo pipefail
cd "$(dirname "$0")"

IN="${1:-raw.mp4}"
[ -f "$IN" ] || { echo "missing $IN — run: vhs banner.tape" >&2; exit 1; }

echo "→ CRT pass …"
ffmpeg -y -loglevel error -i "$IN" -filter_complex "
[0:v]format=rgb24,
geq=r='r(X,Y)*(0.82+0.18*mod(Y,2))':g='g(X,Y)*(0.82+0.18*mod(Y,2))':b='b(X,Y)*(0.82+0.18*mod(Y,2))'[sl];
[sl]split=2[base][bl];
[bl]gblur=sigma=3.5[bloom];
[base][bloom]blend=all_mode=screen:all_opacity=0.35[lit];
[lit]lenscorrection=k1=-0.04:k2=-0.008:fc=black@1.0,
vignette=angle=PI/5[out]
" -map "[out]" -c:v libx264 -pix_fmt yuv420p -crf 18 -movflags +faststart teaser-crt.mp4

echo "→ GIF (palette-optimized) …"
ffmpeg -y -loglevel error -i teaser-crt.mp4 -filter_complex "
fps=15,scale=800:-1:flags=lanczos,split[s0][s1];
[s0]palettegen=max_colors=128:stats_mode=diff[p];
[s1][p]paletteuse=dither=bayer:bayer_scale=4" teaser.gif

echo "done:"
ls -lh teaser-crt.mp4 teaser.gif
28 changes: 28 additions & 0 deletions docs/branding/teaser/video.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Video teaser — plays a local clip through tplay (video → ASCII), captured to
# raw-video.mp4. crt.sh then adds the CRT pass.
#
# yt-dlp --download-sections "*0:03-0:10.5" -f bv*[height<=720] --recode mp4 -o clip.mp4 <URL>
# vhs video.tape && bash crt.sh raw-video.mp4

Output raw-video.mp4

Set Shell "bash"
Set FontFamily "Menlo"
Set FontSize 14
Set Width 1280
Set Height 720
Set Padding 0
Set Theme '{ "name": "blk", "background": "#000000", "foreground": "#FFFFFF", "black": "#000000", "red": "#FF5555", "green": "#55FF55", "yellow": "#FFFF55", "blue": "#5555FF", "magenta": "#FF55FF", "cyan": "#55FFFF", "white": "#FFFFFF", "brightBlack": "#555555", "brightRed": "#FF7777", "brightGreen": "#77FF77", "brightYellow": "#FFFF77", "brightBlue": "#7777FF", "brightMagenta": "#FF77FF", "brightCyan": "#77FFFF", "brightWhite": "#FFFFFF" }'

Hide
Type "export PATH=$HOME/.cargo/bin:/opt/homebrew/bin:$PATH"
Enter
Type "clear"
Enter
Show

Sleep 400ms
Type "tplay clip.mp4 -f 24"
Sleep 200ms
Enter
Sleep 12000ms
50 changes: 50 additions & 0 deletions src/skills_builtin/summarize/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: summarize
description: Use this skill to summarize ANY content at a chosen length — web pages, articles, YouTube/podcasts, PDFs, audio/video, RSS, or piped text — and record the summary with a verifiable link to its source. Triggers: "summarize this", "tl;dr", a URL/file/video/podcast to condense, "what's in this <link/pdf/episode>", "give me the gist".
origin: adapted from steipete/summarize (MIT) — media pipeline delegated to that CLI; provenance + compression are korgex-native
---

# Summarize — content extraction + summarization, with provenance

Summarize anything into a length the user asked for, then make the summary **traceable to its
exact source** (the korgex value-add over a plain summarizer). Pick the lightest path that
handles the input — don't reach for heavy media tooling when a fetch will do.

## When to Use
- The user shares a URL, file, video, podcast, or PDF and wants the gist.
- Condensing a long transcript / article / thread before acting on it.
- "tl;dr", "summarize", "what's in this".

## Routing — lightest path first
1. **Plain text / stdin / a file already in context** → summarize directly with the model. No tools.
2. **Web page / article URL** → korgex `WebFetch`; if the page is JS-heavy or blocked, fall back to the **browser** tool (`browser.py`) to render, then extract the main content and summarize.
3. **Media** — YouTube, podcasts, Spotify/Apple episodes, audio/video files, image/PDF needing OCR, RSS → **delegate to the `summarize` CLI** (steipete/summarize) if it's installed (`command -v summarize`). It owns yt-dlp / Whisper transcription / ffmpeg / tesseract — do **not** reimplement that. Run e.g. `summarize "<url-or-file>" --length <len> --format markdown`. If the CLI is absent, say so and ask for a transcript/text, or offer to summarize a text fallback.

## Options (match `summarize`'s ergonomics)
- **length**: `short` · `medium` (default) · `long` · `xl`
- **format**: `markdown` (default) · `json` · `text`
- **language**: default = the source's language unless asked otherwise
- **smart default**: if the source is already shorter than the requested summary, **return it unchanged** (don't pad) unless the user forces a summary.

## korgex value-add — what makes this more than running a summarizer
1. **Provenance as a verifiable event.** After summarizing, emit a ledger event recording
`{ source (URL or content hash), length, format, model, timestamp }`. Any summary is then
traceable to the exact source it came from — "this summary was produced from this input,"
checkable later. This is the korg-native bit: a summary is a cognition event, not a throwaway.
2. **Never lose the source (context compression).** Seal the *full* extracted content once as a
content-ref; the summary is the compact in-context view; the agent can `Retrieve(ref)` the exact
bytes when a detail is needed. The summary saves tokens without discarding the original.
3. **Report cost + timing** of the run (extraction + LLM) so the user sees what it took.

## Steps
1. **Classify** the input: text / web-url / media.
2. **Extract** via the lightest path above (model-only → WebFetch → browser → `summarize` CLI).
3. **Summarize** at the requested length + format (honor the smart default).
4. **Seal** the full source as a content-ref and **record** the `summary.created` ledger event.
5. **Return** the summary, plus the source ref so the user (or a later turn) can verify or expand it.

## Notes
- Prefer the model directly for short text — invoking media tooling on a paragraph is waste.
- For paywalled/blocked pages, the browser tool or the CLI's Firecrawl fallback is the escalation.
- Keep summaries faithful: a summary preserves proportions of the source; it is not a fold or a
cherry-pick. If the user wants only the load-bearing point, that's a different ask (use logic-folding).