{
  "categories": {
    "convert": "Convert a document",
    "pdf": "PDF page tools",
    "code": "Code converters",
    "image": "Images",
    "svg": "SVG",
    "audio": "Audio",
    "other": "Workflow"
  },
  "tools": [
    {
      "slug": "acrobat-for-teachers",
      "name": "Acrobat for teachers / test-prep creators",
      "category": "other",
      "one_liner": "Chat flagship #2",
      "replaces": "Acrobat + Express generic document tools",
      "primitive": "the teacher/test-prep workflow as the unit",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "ai_resume_builder",
      "name": "AI resume builder",
      "category": "other",
      "one_liner": "[mt4] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Adobe/Express resume",
      "primitive": "schema-first resume + render",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-album-art",
      "name": "Extract album art",
      "category": "audio",
      "one_liner": "Pull the embedded cover art out of any audio file at full resolution.",
      "replaces": "Screenshotting cover art out of a music player",
      "primitive": "Pull the embedded artwork stream directly (mutagen first, ffmpeg fallback) at original resolution",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-analyze",
      "name": "Analyze audio",
      "category": "audio",
      "one_liner": "Render a waveform or spectrogram image of the audio.",
      "replaces": "Analyzers that make you open a full DAW to see a waveform",
      "primitive": "One command for waveform, spectrogram, BPM, key, LUFS and peak",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-censor",
      "name": "Beep censor",
      "category": "audio",
      "one_liner": "Beep out listed time ranges, for profanity or anything you need gone.",
      "replaces": "Loading a full DAW to bleep three words in a podcast",
      "primitive": "Time-range list in, beeped copy out; tone frequency and padding are explicit flags",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-channels",
      "name": "Channel tools",
      "category": "audio",
      "one_liner": "Convert mono/stereo, swap, isolate or pan channels via an explicit matrix.",
      "replaces": "Mono/stereo toggles that silently drop a channel",
      "primitive": "Explicit pan-matrix ops for downmix, upmix, swap, isolate and pan",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-compress",
      "name": "Compress audio",
      "category": "audio",
      "one_liner": "Shrink audio for podcasts and uploads with visible voice/music/maximum tradeoffs.",
      "replaces": "Compressors that give you one opaque 'compress' button",
      "primitive": "Named intent presets (voice / music / maximum) that set sample rate, channels and bitrate explicitly",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-convert",
      "name": "Audio converter",
      "category": "audio",
      "one_liner": "Convert between MP3, WAV, FLAC, AAC, M4A, OGG, Opus, AIFF and WMA with quality-aware, loss-avoiding defaults.",
      "replaces": "Online audio converters that upload your file, cap size, and re-encode lossy to lossy blindly",
      "primitive": "Local ffmpeg with a lossy->lossy WAV intermediate so re-encoding never stacks generational loss",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-declick",
      "name": "Remove clicks and pops",
      "category": "audio",
      "one_liner": "Clean clicks and pops off vinyl transfers and damaged recordings.",
      "replaces": "Restoration suites priced for mastering studios",
      "primitive": "Three explicit methods (median, lowpass, FFT) with a strength dial instead of one magic button",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-dehum",
      "name": "Remove electrical hum",
      "category": "audio",
      "one_liner": "Notch out 50/60 Hz electrical hum and its harmonics without dulling the rest.",
      "replaces": "One-click denoise that smears the whole spectrum to kill a 60 Hz tone",
      "primitive": "Cascaded notch filters at the mains frequency and its harmonics, nothing else touched",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-denoise",
      "name": "Reduce noise",
      "category": "audio",
      "one_liner": "Reduce steady background noise using a sampled noise profile.",
      "replaces": "One-click 'remove noise' that guesses the noise profile for you",
      "primitive": "Sample a real noise clip from the file, then spectral-gate against it (ffmpeg afftdn fallback when the DSP lib is absent)",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-duck",
      "name": "Voice over music",
      "category": "audio",
      "one_liner": "Narration over music with auto-ducking, the podcast mix without the DAW.",
      "replaces": "Manually riding the music fader under every line of narration",
      "primitive": "Sidechain auto-ducking: music at full volume until voice is present, then it gets out of the way",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-dynamics",
      "name": "Dynamic range compressor",
      "category": "audio",
      "one_liner": "Even out loud and quiet parts with presets or full manual control.",
      "replaces": "Compressor plugins that assume you own a DAW to host them",
      "primitive": "FFmpeg acompressor with named presets (vocal, podcast, limiter) and full manual parameter override",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-eq",
      "name": "Parametric EQ",
      "category": "audio",
      "one_liner": "Shape the tone with EQ presets or your own multi-band curve.",
      "replaces": "EQ locked inside player apps that will not export the result",
      "primitive": "FFmpeg equalizer chains with tonal presets (bass boost, vocal clarity) and manual multi-band config",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-extract-from-video",
      "name": "Extract audio from video",
      "category": "audio",
      "one_liner": "Pull the audio track out of MP4, MKV, MOV, WebM and more into any audio format.",
      "replaces": "'Extract audio' web tools that upload the whole video just to strip the track",
      "primitive": "Decode only the audio stream locally; the video never leaves the machine",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-karaoke",
      "name": "Vocal remover (basic)",
      "category": "audio",
      "one_liner": "Remove center-panned vocals via phase cancellation (basic, honest about its limits).",
      "replaces": "'Remove vocals' tools that promise AI stems and deliver mush",
      "primitive": "Honest center-channel phase cancellation, labeled basic rather than sold as stem separation",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-loop",
      "name": "Loop audio",
      "category": "audio",
      "one_liner": "Loop a file N times or out to a target duration, seamless if you want.",
      "replaces": "Copy-pasting a track four times on a timeline to fill two minutes",
      "primitive": "Loop N times or to a target duration, with optional crossfade at the seams",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-merge",
      "name": "Merge audio",
      "category": "audio",
      "one_liner": "Join multiple audio files into one, with an optional crossfade.",
      "replaces": "Joiners that glue mismatched files and produce clicks at the seams",
      "primitive": "Normalize every input to a common format first, then concat (optionally crossfade)",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-metadata",
      "name": "Edit metadata",
      "category": "audio",
      "one_liner": "Set title, artist, album, year, genre and track tags.",
      "replaces": "Tag editors locked to a single container format",
      "primitive": "One tag interface over ID3, Vorbis comments and MP4 atoms",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-normalize",
      "name": "Normalize loudness",
      "category": "audio",
      "one_liner": "Normalize loudness to a target LUFS (or peak/RMS) via a measured two-pass pass.",
      "replaces": "'Normalize' buttons that only peak-normalize",
      "primitive": "Broadcast-standard two-pass EBU R128 loudnorm (LUFS), with peak and RMS as explicit alternatives",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-overlay",
      "name": "Overlay two tracks",
      "category": "audio",
      "one_liner": "Mix one track over another with volume, delay and fade control.",
      "replaces": "Opening an editor just to lay one sound over another",
      "primitive": "Two files in, one mix out; per-track volume, overlay delay and fade-in as flags",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-pitch",
      "name": "Change pitch",
      "category": "audio",
      "one_liner": "Shift pitch by semitones. Tempo shifts with pitch.",
      "replaces": "Pitch shifters that drag the tempo along with the pitch",
      "primitive": "Semitone-based shift with an optional tempo-preserving mode and an asetrate fallback",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-rearrange",
      "name": "Rearrange clips",
      "category": "audio",
      "one_liner": "Cut listed segments out of a file and rejoin them in any order.",
      "replaces": "Razor-blade editing for a simple reorder of known segments",
      "primitive": "A range list like 0-15,30-45,15-30 extracts and concatenates in that order, crossfade optional",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-reverse",
      "name": "Reverse audio",
      "category": "audio",
      "one_liner": "Play it backwards. Format preserved unless you say otherwise.",
      "replaces": "Web toys that upload your file to play it backwards",
      "primitive": "FFmpeg areverse, format preserved by default, re-encode only if you ask",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-ringtone",
      "name": "Make a ringtone",
      "category": "audio",
      "one_liner": "Cut a 30s iPhone (M4R) or Android (MP3) ringtone with fades.",
      "replaces": "Ringtone makers that upsell the export or the length",
      "primitive": "Length-clamped trim+fade encoded straight to M4R (iPhone) or MP3 (Android)",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-silence",
      "name": "Remove or insert silence",
      "category": "audio",
      "one_liner": "Remove or insert silence with explicit threshold and duration controls.",
      "replaces": "Silence removers stuck on one fixed threshold",
      "primitive": "Explicit threshold + min-duration for removal, and position + duration for insertion",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-speed",
      "name": "Change speed",
      "category": "audio",
      "one_liner": "Change playback speed. Pitch shifts with speed.",
      "replaces": "Speed changers that chipmunk the pitch up with the tempo",
      "primitive": "atempo with an optional pitch-preserving mode",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-split",
      "name": "Split audio",
      "category": "audio",
      "one_liner": "Split one file into many by duration, segment count, or detected silence.",
      "replaces": "Splitters that only cut by a single fixed duration",
      "primitive": "Three explicit split modes: equal duration, N segments, or silence-detected gaps",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-tone",
      "name": "Tone and noise generator",
      "category": "audio",
      "one_liner": "Generate test tones and noise at a chosen frequency, duration and level.",
      "replaces": "Ad-laden tone-generator websites",
      "primitive": "Local generation of sine/square/saw tones and white/pink/brown noise at exact parameters",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-trim",
      "name": "Trim audio",
      "category": "audio",
      "one_liner": "Cut audio to a start/end range with optional fade in and out.",
      "replaces": "Trimmers that re-encode the whole clip to cut two seconds",
      "primitive": "Timestamp-accurate atrim with optional fades, keeping the codec where possible",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-voice-enhance",
      "name": "Enhance voice",
      "category": "audio",
      "one_liner": "Clean up spoken-word audio with a podcast/broadcast/phone filter chain.",
      "replaces": "'Enhance voice' AI toggles you cannot see or adjust",
      "primitive": "A named EQ+compression chain (podcast/broadcast/phone) you can read and tweak",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "audio-volume",
      "name": "Change volume",
      "category": "audio",
      "one_liner": "Raise or lower volume by an exact dB or a linear factor.",
      "replaces": "Volume sliders with no numbers behind them",
      "primitive": "Exact dB gain or linear level, applied in a single filter pass",
      "status": "done",
      "runner": "audiotool",
      "script": null,
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "batch-renamer",
      "name": "Batch renamer",
      "category": "image",
      "one_liner": "Rename files as a previewable validated plan: dry-run by default, two-phase cycle-safe apply, undo journal.",
      "replaces": "Bridge batch rename",
      "primitive": "Rename as a previewable plan (mandatory dry-run), not a blind find-replace",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "18/18",
      "from": null,
      "to": null
    },
    {
      "slug": "catalog-generator",
      "name": "Catalog generator",
      "category": "image",
      "one_liner": "Generate a catalog/price-sheet as data-driven output from a CSV (the data is the source of truth).",
      "replaces": "InDesign/Express catalog + price-sheet layout",
      "primitive": "Catalog as data-driven output from a CSV (the data is the source of truth), not a hand-laid document",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "11/11",
      "from": null,
      "to": null
    },
    {
      "slug": "cc-commonjs-to-esm",
      "name": "commonjs-to-esm",
      "category": "code",
      "one_liner": "Converts CommonJS modules to ESM: require() → import, module.exports → export, exports.x → export const x, __dirname/__filename → import.meta.url helpers.",
      "replaces": "Manual require/import rewrites and copy-paste markdown conversion",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "module/commonjs-to-esm.js",
      "tests": "1/1",
      "from": "commonjs",
      "to": "esm"
    },
    {
      "slug": "cc-cra-to-vite",
      "name": "cra-to-vite",
      "category": "code",
      "one_liner": "Migrates Create React App (CRA) projects to Vite. Generates vite.config.js, updates env vars (REACT_APP_ → VITE_), and suggests package.json script changes.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "1/1",
      "from": "cra",
      "to": "vite"
    },
    {
      "slug": "cc-css-px-to-clamp",
      "name": "css-px-to-clamp",
      "category": "code",
      "one_liner": "Converts px font-size, padding, margin, and gap values to CSS clamp() for fluid responsive sizing. Uses viewport-width-based preferred value with rem min/max.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/css-px-to-clamp.js",
      "tests": "1/1",
      "from": "css-px",
      "to": "clamp"
    },
    {
      "slug": "cc-css-px-to-rem",
      "name": "css-px-to-rem",
      "category": "code",
      "one_liner": "Converts px units to rem in CSS. Preserves 0px as 0, optionally keeps 1px for borders, handles calc() expressions, var(), @media queries, @supports, and !important.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/css-px-to-rem.js",
      "tests": "1/1",
      "from": "css-px",
      "to": "rem"
    },
    {
      "slug": "cc-css-to-css-modules",
      "name": "css-to-css-modules",
      "category": "code",
      "one_liner": "Converts global CSS to CSS Modules format. Class selectors kept as-is (local by default). Element/tag and ID selectors converted to class equivalents with warnings. Global resets (html, body) wrapped in :global(). Generates optional JS import map with --with-map flag. Suggests moving @import rules to JS imports.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/css-to-css-modules.js",
      "tests": "1/1",
      "from": "css",
      "to": "css-modules"
    },
    {
      "slug": "cc-css-to-emotion",
      "name": "css-to-emotion",
      "category": "code",
      "one_liner": "Converts CSS rules to Emotion-compatible syntax. Supports css prop mode (--mode=prop) and styled mode (--mode=styled). Handles @media nesting, keyframes, and CSS variable → theme mapping.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/css-to-emotion.js",
      "tests": "1/1",
      "from": "css",
      "to": "emotion"
    },
    {
      "slug": "cc-css-to-scss",
      "name": "css-to-scss",
      "category": "code",
      "one_liner": "Converts flat CSS into nested SCSS by grouping related selectors, extracting repeated values to variables, and detecting BEM patterns. Simple nesting heuristics: shared prefix selectors get nested.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/css-to-scss.js",
      "tests": "1/1",
      "from": "css",
      "to": "scss"
    },
    {
      "slug": "cc-css-to-styled-components",
      "name": "css-to-styled-components",
      "category": "code",
      "one_liner": "Converts CSS rules to styled-components (React) syntax. Selector names become PascalCase component names. Nested selectors use & references or generate separate components.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/css-to-styled-components.js",
      "tests": "1/1",
      "from": "css",
      "to": "styled-components"
    },
    {
      "slug": "cc-css-to-tailwind",
      "name": "css-to-tailwind",
      "category": "code",
      "one_liner": "Converts CSS declarations to Tailwind CSS utility classes. Maps standard CSS properties to Tailwind utilities including colors, spacing, typography, layout, borders, and more. Outputs space-separated class strings or @apply blocks.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/css-to-tailwind.js",
      "tests": "1/1",
      "from": "css",
      "to": "tailwind"
    },
    {
      "slug": "cc-csv-to-json",
      "name": "csv-to-json",
      "category": "code",
      "one_liner": "Convert RFC 4180-style CSV text to formatted JSON through the CLI, browser workbench, and bounded local MCP. Preserve quoted fields and empty cells, report repaired rows, protect special object keys, and expose no arbitrary paths or flags.",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/csv-to-json.js",
      "tests": "6/6",
      "from": "csv",
      "to": "json"
    },
    {
      "slug": "cc-csv-to-sql",
      "name": "csv-to-sql",
      "category": "code",
      "one_liner": "Convert CSV data to SQL INSERT statements. Supports CREATE TABLE generation, type inference, batch inserts, and proper SQL escaping.",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/csv-to-sql.js",
      "tests": "1/1",
      "from": "csv",
      "to": "sql"
    },
    {
      "slug": "cc-csv-to-typescript",
      "name": "csv-to-typescript",
      "category": "code",
      "one_liner": "Convert CSV data to a TypeScript interface and typed const array. Infers types from data values and generates clean, exportable TypeScript code.",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/csv-to-typescript.js",
      "tests": "1/1",
      "from": "csv",
      "to": "typescript"
    },
    {
      "slug": "cc-curl-to-axios",
      "name": "curl-to-axios",
      "category": "code",
      "one_liner": "Convert cURL commands to Axios JavaScript code. Produces a ready-to-run script using axios with proper config for headers, body, auth, params, form data, file uploads, and redirect handling.",
      "replaces": "Hand-translating cURL snippets into client code",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "api/curl-to-axios.js",
      "tests": "1/1",
      "from": "curl",
      "to": "axios"
    },
    {
      "slug": "cc-curl-to-fetch",
      "name": "curl-to-fetch",
      "category": "code",
      "one_liner": "Convert cURL commands to JavaScript fetch() code. Handles headers, body data, JSON, form data, basic auth, cookies, file uploads, and insecure/redirect flags.",
      "replaces": "Hand-translating cURL snippets into client code",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "api/curl-to-fetch.js",
      "tests": "1/1",
      "from": "curl",
      "to": "fetch"
    },
    {
      "slug": "cc-curl-to-go",
      "name": "curl-to-go",
      "category": "code",
      "one_liner": "Convert cURL commands to Go net/http code. Generates idiomatic Go with http.NewRequest, proper header setting, strings.NewReader or bytes.NewBuffer for body, json.Marshal for JSON payloads, and the standard if err != nil error handling pattern.",
      "replaces": "Hand-translating cURL snippets into client code",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "api/curl-to-go.js",
      "tests": "1/1",
      "from": "curl",
      "to": "go"
    },
    {
      "slug": "cc-curl-to-php",
      "name": "curl-to-php",
      "category": "code",
      "one_liner": "Convert cURL commands to PHP code. By default generates native PHP cURL (curl_init/curl_setopt). Pass --guzzle to output Guzzle HTTP client code. Handles headers, body, JSON, form data, file uploads, basic auth, cookies, and SSL verification.",
      "replaces": "Hand-translating cURL snippets into client code",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "api/curl-to-php.js",
      "tests": "1/1",
      "from": "curl",
      "to": "php"
    },
    {
      "slug": "cc-curl-to-python",
      "name": "curl-to-python",
      "category": "code",
      "one_liner": "Convert cURL commands to Python requests code. Generates idiomatic Python using the requests library with proper dicts for headers, json= for JSON payloads, data= for form data, files= for uploads, and auth tuples for basic authentication.",
      "replaces": "Hand-translating cURL snippets into client code",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "api/curl-to-python.js",
      "tests": "1/1",
      "from": "curl",
      "to": "python"
    },
    {
      "slug": "cc-env-to-typed-config",
      "name": "env-to-typed-config",
      "category": "code",
      "one_liner": "Convert .env file to TypeScript config loader with validation. Generates a TypeScript interface, parse function, and validation with descriptive errors. Supports type coercion: PORT=number, ENABLED=boolean, DATABASE_URL=string. Includes Zod-style validation pattern using pure JS.",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/env-to-typed-config.js",
      "tests": "1/1",
      "from": "env",
      "to": "typed-config"
    },
    {
      "slug": "cc-esm-to-commonjs",
      "name": "esm-to-commonjs",
      "category": "code",
      "one_liner": "Converts ESM modules to CommonJS: import → require(), export → module.exports, default export → module.exports =, named exports → exports.x, import.meta.url → __filename.",
      "replaces": "Manual require/import rewrites and copy-paste markdown conversion",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "module/esm-to-commonjs.js",
      "tests": "1/1",
      "from": "esm",
      "to": "commonjs"
    },
    {
      "slug": "cc-eval-remover",
      "name": "eval-remover",
      "category": "code",
      "one_liner": "Finds and refactors eval() and new Function() calls to safer alternatives. Converts eval(\"...\") to JSON.parse where applicable, new Function() to inline arrow functions, and setTimeout/setInterval with strings to function wrappers. Adds warnings for cases requiring manual review.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/eval-remover.js",
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "cc-hardcoded-colors-to-tokens",
      "name": "hardcoded-colors-to-tokens",
      "category": "code",
      "one_liner": "Replaces hardcoded color values (hex, rgb, rgba, hsl, hsla) with design token references as CSS custom properties. Generates companion tokens file. Preserves alpha channels via rgba/hsla with token references.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/hardcoded-colors-to-tokens.js",
      "tests": "1/1",
      "from": "hardcoded-colors",
      "to": "tokens"
    },
    {
      "slug": "cc-html-to-jsx",
      "name": "html-to-jsx",
      "category": "code",
      "one_liner": "Converts HTML to JSX. Handles attributes (class→className, for→htmlFor, style strings→objects, event handlers→camelCase), self-closing tags, boolean attributes, HTML comments, and inline style camelCasing.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/html-to-jsx.js",
      "tests": "1/1",
      "from": "html",
      "to": "jsx"
    },
    {
      "slug": "cc-html-to-markdown",
      "name": "html-to-markdown",
      "category": "code",
      "one_liner": "Converts HTML to Markdown. Handles headings, paragraphs, links, images, lists, code blocks, blockquotes, bold, italic, tables, and more. Strips unsupported attributes with warnings.",
      "replaces": "Manual require/import rewrites and copy-paste markdown conversion",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "module/html-to-markdown.js",
      "tests": "1/1",
      "from": "html",
      "to": "markdown"
    },
    {
      "slug": "cc-html-to-svelte",
      "name": "html-to-svelte",
      "category": "code",
      "one_liner": "Converts HTML to a Svelte component. Maps event handlers to Svelte's on:click syntax, adds <script> section with reactive variable hints, and wraps output in a .svelte scaffold.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/html-to-svelte.js",
      "tests": "1/1",
      "from": "html",
      "to": "svelte"
    },
    {
      "slug": "cc-html-to-vue",
      "name": "html-to-vue",
      "category": "code",
      "one_liner": "Converts HTML to Vue SFC template syntax. Wraps content in a <template> block, converts common event and binding patterns to Vue directives (@click, :href, v-model), and sets up the SFC scaffold.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/html-to-vue.js",
      "tests": "1/1",
      "from": "html",
      "to": "vue"
    },
    {
      "slug": "cc-inline-styles-to-css",
      "name": "inline-styles-to-css",
      "category": "code",
      "one_liner": "Extracts inline style=\"...\" attributes from HTML and generates CSS classes. Detects repeated style values to suggest shared classes. Replaces inline styles with class attributes. Generates class names based on element context or --prefix flag.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/inline-styles-to-css.js",
      "tests": "1/1",
      "from": "inline-styles",
      "to": "css"
    },
    {
      "slug": "cc-innerhtml-to-safe-render",
      "name": "innerhtml-to-safe-render",
      "category": "code",
      "one_liner": "Converts dangerous element.innerHTML assignments to safe DOM methods like textContent, setAttribute, or createElement/appendChild patterns. Detects when HTML is being set vs plain text and chooses the appropriate safe method.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/innerhtml-to-safe-render.js",
      "tests": "1/1",
      "from": "innerhtml",
      "to": "safe-render"
    },
    {
      "slug": "cc-jquery-to-vanilla",
      "name": "jquery-to-vanilla",
      "category": "code",
      "one_liner": "Converts jQuery patterns to vanilla JavaScript: selectors, DOM manipulation, events, AJAX, utilities, and chained calls to native equivalents.",
      "replaces": "Manual require/import rewrites and copy-paste markdown conversion",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "module/jquery-to-vanilla.js",
      "tests": "1/1",
      "from": "jquery",
      "to": "vanilla"
    },
    {
      "slug": "cc-js-to-ts",
      "name": "js-to-ts",
      "category": "code",
      "one_liner": "Adds basic TypeScript annotations to JavaScript code. Infers types from JSDoc @param/@returns, default values, object shapes, and homogeneous arrays. Converts require() to import, adds .ts extensions.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/js-to-ts.js",
      "tests": "1/1",
      "from": "js",
      "to": "ts"
    },
    {
      "slug": "cc-json-schema-to-typescript",
      "name": "json-schema-to-typescript",
      "category": "code",
      "one_liner": "Converts JSON Schema (draft-07) to TypeScript interfaces. Handles: type, enum, anyOf, oneOf, allOf, $ref, array items, object properties, required fields, nested definitions.",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/json-schema-to-typescript.js",
      "tests": "1/1",
      "from": "json-schema",
      "to": "typescript"
    },
    {
      "slug": "cc-json-schema-to-zod",
      "name": "json-schema-to-zod",
      "category": "code",
      "one_liner": "Converts JSON Schema (draft-07) to Zod schema definitions. Handles: type, enum, anyOf, oneOf, allOf, $ref, array items, object properties, required fields, string formats, nested definitions.",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/json-schema-to-zod.js",
      "tests": "1/1",
      "from": "json-schema",
      "to": "zod"
    },
    {
      "slug": "cc-json-to-json-schema",
      "name": "json-to-json-schema",
      "category": "code",
      "one_liner": "Converts JSON data into JSON Schema (draft-07) with intelligent type inference. Adds human-readable descriptions derived from key names, handles nested objects, arrays, null values, and optional field detection.",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/json-to-json-schema.js",
      "tests": "1/1",
      "from": "json",
      "to": "json-schema"
    },
    {
      "slug": "cc-json-to-typescript",
      "name": "json-to-typescript",
      "category": "code",
      "one_liner": "Convert representative JSON text to valid TypeScript declarations through the CLI, browser workbench, and bounded local MCP. Preserve explicit root names, top-level scalars and arrays, unsafe keys, heterogeneous types, and collision-safe nested structure.",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/json-to-typescript.js",
      "tests": "6/6",
      "from": "json",
      "to": "typescript"
    },
    {
      "slug": "cc-json-to-yaml",
      "name": "json-to-yaml",
      "category": "code",
      "one_liner": "Convert JSON text to deterministic valid YAML through the CLI, browser workbench, and bounded local MCP. Preserve nested structure and scalar meaning for ambiguous, multiline, controlled, and Unicode strings.",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/json-to-yaml.js",
      "tests": "6/6",
      "from": "json",
      "to": "yaml"
    },
    {
      "slug": "cc-json-to-zod",
      "name": "json-to-zod",
      "category": "code",
      "one_liner": "Converts JSON data into Zod schema definitions with intelligent inference. Adds .optional() for missing keys, .nullable() for nulls, .email()/.url()/ .datetime() heuristics, and handles nested objects & arrays.",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/json-to-zod.js",
      "tests": "1/1",
      "from": "json",
      "to": "zod"
    },
    {
      "slug": "cc-jsx-to-html",
      "name": "jsx-to-html",
      "category": "code",
      "one_liner": "Converts JSX back to static HTML. Reverses JSX attribute naming (className→class, htmlFor→for), converts style objects to strings, removes event handlers with warning comments, and strips JSX expressions.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/jsx-to-html.js",
      "tests": "1/1",
      "from": "jsx",
      "to": "html"
    },
    {
      "slug": "cc-lodash-to-native",
      "name": "lodash-to-native",
      "category": "code",
      "one_liner": "Converts Lodash usage to native JavaScript ES2015+ equivalents. Handles 30+ methods with per-method mapping, optional chaining, and fallbacks.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/lodash-to-native.js",
      "tests": "1/1",
      "from": "lodash",
      "to": "native"
    },
    {
      "slug": "cc-markdown-to-html",
      "name": "markdown-to-html",
      "category": "code",
      "one_liner": "Converts Markdown to HTML. Supports headings, bold, italic, code, code blocks, links, images, blockquotes, lists, horizontal rules, tables, line breaks, and strikethrough. No external dependencies.",
      "replaces": "Manual require/import rewrites and copy-paste markdown conversion",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "module/markdown-to-html.js",
      "tests": "1/1",
      "from": "markdown",
      "to": "html"
    },
    {
      "slug": "cc-minified-to-readable",
      "name": "minified-to-readable",
      "category": "code",
      "one_liner": "Formats minified JavaScript, HTML, or CSS into readable, indented code. Handles proper indentation, brace placement, comment preservation, and optional attribute/property alignment.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/minified-to-readable.js",
      "tests": "1/1",
      "from": "minified",
      "to": "readable"
    },
    {
      "slug": "cc-moment-to-date-fns",
      "name": "moment-to-date-fns",
      "category": "code",
      "one_liner": "Converts Moment.js code to date-fns. Handles format, add, subtract, diff, startOf, endOf, isBefore, isAfter, isSame, fromNow, and more.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/moment-to-date-fns.js",
      "tests": "1/1",
      "from": "moment",
      "to": "date-fns"
    },
    {
      "slug": "cc-openapi-to-markdown",
      "name": "openapi-to-markdown",
      "category": "code",
      "one_liner": "Converts OpenAPI 3.x specifications (JSON or YAML) to comprehensive Markdown documentation. Generates endpoint sections with method badges, parameter tables, request body examples, and response documentation.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/openapi-to-markdown.js",
      "tests": "1/1",
      "from": "openapi",
      "to": "markdown"
    },
    {
      "slug": "cc-pretty-to-minified",
      "name": "pretty-to-minified",
      "category": "code",
      "one_liner": "Minifies JavaScript, CSS, or HTML by removing whitespace, comments, and optional variable name mangling.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/pretty-to-minified.js",
      "tests": "1/1",
      "from": "pretty",
      "to": "minified"
    },
    {
      "slug": "cc-react-class-to-function",
      "name": "react-class-to-function",
      "category": "code",
      "one_liner": "Converts React class components to function components with hooks. Handles constructor→useState, componentDidMount→useEffect, this.state→useState, this.props→props parameter, render() extraction, componentWillUnmount cleanup, and getDerivedStateFromProps warnings.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/react-class-to-function.js",
      "tests": "1/1",
      "from": "react-class",
      "to": "function"
    },
    {
      "slug": "cc-sass-variables-to-css-vars",
      "name": "sass-variables-to-css-vars",
      "category": "code",
      "one_liner": "Converts Sass/SCSS $variables to CSS custom properties. Moves definitions to a :root block, replaces $var usage with var(--var). Handles #{$var} interpolation, !default flags, and computed expressions.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/sass-variables-to-css-vars.js",
      "tests": "1/1",
      "from": "sass-variables",
      "to": "css-vars"
    },
    {
      "slug": "cc-scss-to-css",
      "name": "scss-to-css",
      "category": "code",
      "one_liner": "Flattens SCSS into plain CSS by resolving nesting, parent selectors (&), variables, mixins, imports, and control directives. Outputs flat selectors with BEM-style expansion for & variants.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/scss-to-css.js",
      "tests": "1/1",
      "from": "scss",
      "to": "css"
    },
    {
      "slug": "cc-sql-schema-to-typescript",
      "name": "sql-schema-to-typescript",
      "category": "code",
      "one_liner": "Converts SQL CREATE TABLE statements to TypeScript interfaces. Parses columns, types, constraints, primary keys, foreign keys, and nullability.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/sql-schema-to-typescript.js",
      "tests": "1/1",
      "from": "sql-schema",
      "to": "typescript"
    },
    {
      "slug": "cc-sql-to-parameterized",
      "name": "sql-to-parameterized",
      "category": "code",
      "one_liner": "Converts SQL queries with string concatenation/interpolation into parameterized queries with placeholder values (? or $1, $2, etc.) and a separate parameters array. Supports multiple SQL dialects.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/sql-to-parameterized.js",
      "tests": "1/1",
      "from": "sql",
      "to": "parameterized"
    },
    {
      "slug": "cc-static-values-to-css-vars",
      "name": "static-values-to-css-vars",
      "category": "code",
      "one_liner": "Extracts repeated CSS values (colors, font-sizes, spacing, border-radius) and replaces them with CSS custom properties in a :root block. Values appearing >= --threshold times are extracted. Smart naming based on value type.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/static-values-to-css-vars.js",
      "tests": "1/1",
      "from": "static-values",
      "to": "css-vars"
    },
    {
      "slug": "cc-svg-sanitizer",
      "name": "svg-sanitizer",
      "category": "code",
      "one_liner": "Sanitizes SVG files by removing dangerous content including script tags, javascript: handlers, foreignObject, XSL processing instructions, event handlers, and external resource references. Preserves pure vector graphics, gradients, filters, and SMIL animations.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/svg-sanitizer.js",
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "cc-svg-to-css-background",
      "name": "svg-to-css-background",
      "category": "code",
      "one_liner": "Convert SVG to CSS background-image data URI. Supports class-name customization, sizing, and color replacement (e.g., currentColor → #f00).",
      "replaces": "Hand-porting SVG markup into framework components",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "svg/svg-to-css-background.js",
      "tests": "1/1",
      "from": "svg",
      "to": "css-background"
    },
    {
      "slug": "cc-svg-to-html",
      "name": "svg-to-html",
      "category": "code",
      "one_liner": "Embed SVG inline into HTML with proper sizing. Supports responsive scaling (--responsive) and SVG sprite preparation (--sprite).",
      "replaces": "Hand-porting SVG markup into framework components",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "svg/svg-to-html.js",
      "tests": "1/1",
      "from": "svg",
      "to": "html"
    },
    {
      "slug": "cc-svg-to-react",
      "name": "svg-to-react",
      "category": "code",
      "one_liner": "Convert SVG to React JSX component with camelCased attributes, style-object conversion, optional TypeScript types, and automatic component-name detection.",
      "replaces": "Hand-porting SVG markup into framework components",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "svg/svg-to-react.js",
      "tests": "1/1",
      "from": "svg",
      "to": "react"
    },
    {
      "slug": "cc-svg-to-svelte",
      "name": "svg-to-svelte",
      "category": "code",
      "one_liner": "Convert SVG to Svelte component with `export let` prop declarations, class directive support, and event forwarding.",
      "replaces": "Hand-porting SVG markup into framework components",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "svg/svg-to-svelte.js",
      "tests": "1/1",
      "from": "svg",
      "to": "svelte"
    },
    {
      "slug": "cc-svg-to-vue",
      "name": "svg-to-vue",
      "category": "code",
      "one_liner": "Convert SVG to Vue 3 Single-File Component (SFC) with configurable props for width, height, fill, and other attributes.",
      "replaces": "Hand-porting SVG markup into framework components",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "svg/svg-to-vue.js",
      "tests": "1/1",
      "from": "svg",
      "to": "vue"
    },
    {
      "slug": "cc-tailwind-to-css",
      "name": "tailwind-to-css",
      "category": "code",
      "one_liner": "Converts Tailwind CSS utility classes to standard CSS declarations. Parses responsive prefixes (sm:, md:, lg:, xl:), state modifiers (hover:, focus:, active:), and arbitrary values (e.g., m-[17px]). Outputs grouped CSS rules with @media wrappers.",
      "replaces": "Manual CSS refactors and single-purpose style converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "css/tailwind-to-css.js",
      "tests": "1/1",
      "from": "tailwind",
      "to": "css"
    },
    {
      "slug": "cc-toml-to-json",
      "name": "toml-to-json",
      "category": "code",
      "one_liner": "Convert TOML to JSON. Handles key=value pairs, [sections], arrays, inline tables, strings (including multiline \"\"\" \"\"\"), numbers, booleans, dates, and dotted keys (flattened or nested).",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/toml-to-json.js",
      "tests": "1/1",
      "from": "toml",
      "to": "json"
    },
    {
      "slug": "cc-ts-to-js",
      "name": "ts-to-js",
      "category": "code",
      "one_liner": "Strips all TypeScript syntax from code. Removes type annotations, interfaces, type aliases, generics, 'as' casts, 'satisfies' operator, converts enums to plain objects, and handles 'declare module' / triple-slash directives. Preserves ESM imports/exports and removes .ts extensions.",
      "replaces": "Framework rewrite chores and one-off online HTML/JSX converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "core/ts-to-js.js",
      "tests": "1/1",
      "from": "ts",
      "to": "js"
    },
    {
      "slug": "cc-ts-to-json-schema",
      "name": "ts-to-json-schema",
      "category": "code",
      "one_liner": "Converts TypeScript interfaces and type aliases to JSON Schema (draft-07). Parses: interface, type alias, enum, arrays, unions, optional (?), Record, generics (with warning), nested objects, primitive types.",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/ts-to-json-schema.js",
      "tests": "1/1",
      "from": "ts",
      "to": "json-schema"
    },
    {
      "slug": "cc-ts-to-zod",
      "name": "ts-to-zod",
      "category": "code",
      "one_liner": "Converts TypeScript interfaces and type aliases to Zod schema definitions. Parses: interface, type alias, enum, arrays, unions, optional (?), Record, generics (with warning), nested objects. Complex conditional types → warn and use z.any().",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/ts-to-zod.js",
      "tests": "1/1",
      "from": "ts",
      "to": "zod"
    },
    {
      "slug": "cc-tsconfig-fixer",
      "name": "tsconfig-fixer",
      "category": "code",
      "one_liner": "Analyzes and repairs tsconfig.json files. Validates against JSON Schema, adds missing required fields, fixes deprecated options, and suggests strict settings.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/tsconfig-fixer.js",
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "cc-unsafe-html-sanitizer",
      "name": "unsafe-html-sanitizer",
      "category": "code",
      "one_liner": "Sanitizes HTML by removing dangerous content including script tags, javascript: URLs, event handlers, objects, embeds, iframes, and forms. Produces safe HTML for rendering untrusted content.",
      "replaces": "Ad-hoc sanitizing regexes and unsafe copy-paste fixes",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "security/unsafe-html-sanitizer.js",
      "tests": "1/1",
      "from": null,
      "to": null
    },
    {
      "slug": "cc-webpack-to-vite",
      "name": "webpack-to-vite",
      "category": "code",
      "one_liner": "Converts webpack configuration files to Vite configuration files. Handles entry, output, resolve aliases, devServer, and common plugins.",
      "replaces": "Tool migration guides followed by hand, file by file",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "config/webpack-to-vite.js",
      "tests": "1/1",
      "from": "webpack",
      "to": "vite"
    },
    {
      "slug": "cc-yaml-to-json",
      "name": "yaml-to-json",
      "category": "code",
      "one_liner": "Convert YAML to JSON. Handles scalars, sequences, mappings, nested structures, comments, quoted strings, and multiline strings (literal | and folded >). No external dependencies - pure Node.js YAML parser.",
      "replaces": "Ad-hoc format massaging in spreadsheets and converter sites",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "data/yaml-to-json.js",
      "tests": "1/1",
      "from": "yaml",
      "to": "json"
    },
    {
      "slug": "cc-zod-to-json-schema",
      "name": "zod-to-json-schema",
      "category": "code",
      "one_liner": "Converts Zod schema code to JSON Schema (draft-07). Handles: z.string(), z.number(), z.boolean(), z.array(), z.object(), z.enum(), z.union(), z.optional(), z.nullable(), z.literal(), z.record(), z.tuple(), z.date(), z.any(), z.unknown(), z.null(), z.undefined().",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/zod-to-json-schema.js",
      "tests": "1/1",
      "from": "zod",
      "to": "json-schema"
    },
    {
      "slug": "cc-zod-to-typescript",
      "name": "zod-to-typescript",
      "category": "code",
      "one_liner": "Parses Zod schema code and extracts TypeScript type definitions. Handles: z.string(), z.number(), z.boolean(), z.array(), z.object(), z.enum(), z.union(), z.optional(), z.nullable(), z.literal(), z.record(), z.tuple(), z.date(), z.any(), z.unknown(), z.null(), z.undefined().",
      "replaces": "Hand-written types and schemas that drift from the data they describe",
      "primitive": "Deterministic single-purpose text transform: a zero-dependency Node script, stdin/stdout pipeable, that suggests the right sibling tool on mismatched input",
      "status": "done",
      "runner": "converter",
      "script": "schema/zod-to-typescript.js",
      "tests": "1/1",
      "from": "zod",
      "to": "typescript"
    },
    {
      "slug": "cheat-sheet-converter",
      "name": "PDF/document -> clean output converter",
      "category": "other",
      "one_liner": "PDF/document converter with three intended output modes: replica mode for exact visual fidelity, hybrid mode for semantic regions over preserved visuals, and reflow mode for mobile/LMS-ready web-native content. The core product primitive is the region tree: blocks, figures, diagrams, reading order, bounding boxes, and confidence.",
      "replaces": "Acrobat PDF export (PDF->HTML/Word/etc.)",
      "primitive": "visual structure first, semantic document second",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "contact-sheet",
      "name": "Contact sheet",
      "category": "image",
      "one_liner": "One command turns a folder into print-ready proof sheets: paper size at DPI, captioned thumbnails, numbered pages.",
      "replaces": "Bridge contact sheet",
      "primitive": "A one-command proof sheet for reviewing a set of images",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "16/16",
      "from": null,
      "to": null
    },
    {
      "slug": "dupe-finder",
      "name": "Dupe finder",
      "category": "image",
      "one_liner": "Find byte-identical and visually similar images with an adjustable distance threshold; report and move, never delete.",
      "replaces": "Lightroom duplicate detection",
      "primitive": "Focused find-the-dupes with an adjustable similarity threshold, not a whole catalog system",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "15/15",
      "from": null,
      "to": null
    },
    {
      "slug": "dynamic_diagonal_watermark",
      "name": "Diagonal personalized watermark",
      "category": "other",
      "one_liner": "[mt4] Adaptive diagonal text grid personalized per buyer. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Per-copy diagonal that adapts to page size.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "favicon-generator",
      "name": "Favicon generator",
      "category": "image",
      "one_liner": "Take one source image, emit a complete favicon set (all sizes) + web manifest + paste-ready HTML snippet.",
      "replaces": "Express icon export / online favicon makers",
      "primitive": "Favicon as a complete deployment bundle (every size + manifest + paste-ready HTML), not a single resized PNG",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "14/14",
      "from": null,
      "to": null,
      "search_title": "Favicon Generator with Live Context Preview | Private",
      "search_description": "Build a complete favicon, Apple touch icon, maskable PWA icon, manifest, and install snippet locally. Preview browser, search, and device crops before export.",
      "search_intro": "A favicon is not one tiny square. The same artwork is reduced into browser tabs, search results, Apple touch icons, and Android masks, each with different cropping pressure. This workbench generates the actual files first, then previews those files in representative contexts so unsafe padding, weak contrast, and missing manifest fields can be caught before launch.",
      "how_it_works": [
        "Choose one source image and define the app name, launch path, scope, colors, and standard padding.",
        "Generate raster icons, a multi-size ICO, a separately declared maskable icon, the web manifest, and the install snippet in this tab.",
        "Review browser, search, Apple touch, and circular Android contexts, then download individual files or a complete ZIP with a versioned receipt."
      ],
      "use_cases": [
        "Prepare a consistent launch icon package for a website or progressive web app.",
        "Check whether logo detail survives at 32 and 48 pixels before deployment.",
        "Keep maskable artwork inside the recommended safe zone while preserving a separate ordinary icon."
      ],
      "limits": [
        "Context previews are representative; browsers, operating systems, launchers, and search engines can render or crop icons differently.",
        "Search engines decide whether to display a favicon and do not guarantee that a submitted icon will appear.",
        "The tool generates files and installation markup but does not publish them or verify that a live site's crawler can reach them."
      ],
      "faq": [
        {
          "q": "Are source images uploaded?",
          "a": "No. Decoding, resizing, previews, manifest creation, ZIP packaging, and downloads happen locally in this browser tab."
        },
        {
          "q": "Why is the maskable icon separate?",
          "a": "An icon declared as maskable may be cropped into many launcher shapes. This package gives it a protected inner safe zone instead of falsely declaring the ordinary full-bleed icon as safe."
        },
        {
          "q": "What gets downloaded?",
          "a": "The package includes 16, 32, 48, 180, 192, and 512 pixel PNGs, a 512 pixel maskable PNG, a multi-size ICO, a web manifest, an HTML snippet, and a versioned receipt."
        }
      ],
      "related": [
        "image-optimizer",
        "image-resizer",
        "image-diff"
      ]
    },
    {
      "slug": "flashcard_maker",
      "name": "Flashcard maker",
      "category": "other",
      "one_liner": "[mt4] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Adobe/Acrobat flashcard export",
      "primitive": "extraction + Q/A generation",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "forumala-translator",
      "name": "Formula translation tool",
      "category": "other",
      "one_liner": "Formula/notation conversion preserving semantic formula structure. Precedent proof.",
      "replaces": "generic formula/notation conversion",
      "primitive": "semantic formula structure",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "gallery-export",
      "name": "Gallery export",
      "category": "image",
      "one_liner": "Turn a folder of images into a shippable static gallery site (HTML/CSS/JS + lightbox) you own.",
      "replaces": "Lightroom/Bridge web-gallery export",
      "primitive": "Gallery as a shippable static site you own (HTML/CSS/JS + lightbox), not a proprietary export",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "9/9",
      "from": null,
      "to": null
    },
    {
      "slug": "icon-set-exporter",
      "name": "Icon Set Exporter",
      "category": "other",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Export-for-screens dialogs",
      "primitive": "one source -> explicit size/format matrix",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "image-export-matrix",
      "name": "Image Export Matrix",
      "category": "other",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Export As dialogs, one at a time",
      "primitive": "the variant matrix spec (sizes x formats x quality) as the unit",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "image-levels",
      "name": "Image levels",
      "category": "image",
      "one_liner": "Apply a reproducible, versionable JSON tone recipe (levels/curves) to images in batch.",
      "replaces": "Lightroom/Photoshop levels+curves (per-image slider session)",
      "primitive": "A reproducible, versionable tone recipe (JSON) applied in batch, not a manual slider pass",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "10/10",
      "from": null,
      "to": null
    },
    {
      "slug": "image-metadata-editor",
      "name": "Image Metadata Editor",
      "category": "other",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Bridge metadata panel",
      "primitive": "EXIF/IPTC as viewable, settable, strippable fields",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "image-optimizer",
      "name": "Image optimizer",
      "category": "image",
      "one_liner": "Compress images to a stated size/quality budget and report itemized before/after bytes per file.",
      "replaces": "Express / online \"compress image\" black box",
      "primitive": "Compression with a deterministic stated budget + itemized before/after byte report, not a black box",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "17/17",
      "from": null,
      "to": null,
      "search_title": "Batch Image Optimizer with Before and After Review | Private",
      "search_description": "Resize and re-encode up to 20 images locally as WebP, JPEG, or PNG. Review exact dimensions and bytes, verify output MIME, and export a batch receipt.",
      "search_intro": "Image optimization is a tradeoff, not a magic score. This workbench applies one explicit recipe to a bounded batch, then keeps the source and re-encoded image side by side with exact dimensions, bytes, and the decision to keep or skip a larger result. The full batch is preflighted before outputs are published, and browser format fallback is rejected instead of being mislabeled.",
      "how_it_works": [
        "Choose up to 20 images within the displayed byte and pixel limits, then set output format, quality, maximum dimensions, and JPEG background.",
        "Preflight the complete batch, re-encode locally, verify the actual output MIME and decoded dimensions, and hold every download if a file fails.",
        "Review source and output pixels and byte changes, then export verified images with a versioned JSON receipt."
      ],
      "use_cases": [
        "Prepare a group of website images with one reproducible size and format recipe.",
        "Inspect whether a WebP or JPEG quality setting produces acceptable visible artifacts before launch.",
        "Record which files became larger, failed, or were intentionally skipped instead of hiding batch exceptions."
      ],
      "limits": [
        "Quality values are encoder inputs, not comparable visual-quality scores across formats or browsers.",
        "Every kept output is re-encoded; EXIF and ancillary metadata are excluded, while color conversion is managed by the browser.",
        "The browser workbench is capped at 20 files, 50 MB input, 32 megapixels per file, 120 megapixels per batch, and 100 MB output."
      ],
      "faq": [
        {
          "q": "Are images uploaded?",
          "a": "No. Decode, resize, encode, review, ZIP packaging, and receipt generation happen in this browser tab."
        },
        {
          "q": "Why can an optimized file be larger?",
          "a": "Format, image content, dimensions, and metadata policy all affect byte size. You can keep larger re-encoded files or record them as explicit skips."
        },
        {
          "q": "Does the tool preserve metadata?",
          "a": "No. Kept browser outputs are re-encoded and exclude EXIF and ancillary metadata. Use the local CLI when you need its explicit ICC-preservation behavior."
        }
      ],
      "related": [
        "image-resizer",
        "favicon-generator",
        "image-diff"
      ]
    },
    {
      "slug": "image-resizer",
      "name": "Image resizer",
      "category": "image",
      "one_liner": "Resize images under an explicit fit rule (contain/cover/pad/stretch) with exact before/after geometry reported.",
      "replaces": "Express one-click resize",
      "primitive": "Explicit visible fit rules (pad/crop/contain) instead of a magic auto-resize",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "17/17",
      "from": null,
      "to": null
    },
    {
      "slug": "image_noise_watermark",
      "name": "Image-domain watermark",
      "category": "other",
      "one_liner": "[mt4] DCT-based invisible watermark for image-heavy PDFs. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Survives some recompression; paired detector.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "invisible_dot_fingerprint",
      "name": "Invisible dot fingerprint",
      "category": "other",
      "one_liner": "[mt4] Sparse dot pattern watermark with paired detector. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Seeded, reproducible, with extractor.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "leak_attribution_suite",
      "name": "Leak attribution suite",
      "category": "other",
      "one_liner": "[mt4] Canary tokens, integrity seal, redaction verify, expiring links. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Combined secure-delivery toolkit.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "legal-hr-pdf-cleanup",
      "name": "Legal/HR PDF cleanup tool",
      "category": "other",
      "one_liner": "Chat flagship #5",
      "replaces": "Acrobat compare/redact/split pieces",
      "primitive": "one office worker under time pressure as the unit",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "math-vocab-cards",
      "name": "Math Vocab Cards",
      "category": "other",
      "one_liner": "[batch-draft] CSV of terms -> printable duplex flashcards. Specced in batch-drafts; built in Kimi swarm, awaiting download to disk.",
      "replaces": "Canva flashcard templates",
      "primitive": "the vocab CSV is the unit; duplex-aligned card sheets out",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "microtext_watermark",
      "name": "PDF microtext watermark",
      "category": "other",
      "one_liner": "[mt4] Tiny readable text in margins/gutters; readability check. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Refuses unreadably tiny output.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "mindmap_from_doc",
      "name": "Mind map from document",
      "category": "other",
      "one_liner": "[mt4] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Adobe topic-graph",
      "primitive": "hierarchical topic extraction",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "office-to-pdf",
      "name": "Office To PDF",
      "category": "pdf",
      "one_liner": "Convert Word/Excel/PowerPoint/OpenDocument/text and images to PDF, one output per input.",
      "replaces": "Adobe Acrobat page tooling and the ilovepdf-class web utilities",
      "primitive": "Orchestration around existing render engines (soffice for documents, Pillow for images, cupsfilter fallback for text) instead of reimplementing layout.",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "3/3",
      "from": "office",
      "to": "pdf"
    },
    {
      "slug": "palette-extractor",
      "name": "Palette extractor",
      "category": "image",
      "one_liner": "Extract dominant colors as paste-ready code (CSS vars/SCSS/Tailwind/JSON/hex) with coverage share and WCAG ink per swatch.",
      "replaces": "Express color/palette pickers",
      "primitive": "Palette as code you paste (CSS vars/Tailwind/JSON), not a picture of swatches",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "15/15",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-accessibility-remediation",
      "name": "PDF accessibility remediation assistant",
      "category": "pdf",
      "one_liner": "Chat flagship #3",
      "replaces": "Acrobat accessibility checker",
      "primitive": "visual, semi-automatic remediation (reading order/tags/alt-text)",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-buyer-stamp",
      "name": "PDF Buyer Stamp",
      "category": "pdf",
      "one_liner": "[mt6] Per-row stamped PDF from a buyers CSV. First draft 2026-07-10; audited.",
      "replaces": "manual per-buyer watermarking",
      "primitive": "the order record (CSV row) as the unit, one stamped PDF per buyer",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-canary-link",
      "name": "PDF Canary Link",
      "category": "pdf",
      "one_liner": "[mt6] Unique per-copy tracking link annotation; --verify. First draft 2026-07-10; audited.",
      "replaces": "watermark-only leak tracing",
      "primitive": "a unique per-copy URL as the traceable primitive",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-certificate",
      "name": "PDF Certificate Generator",
      "category": "pdf",
      "one_liner": "[batch-draft] CSV -> certificates on a reportlab template. Specced in batch-drafts; built in Kimi swarm, awaiting download to disk.",
      "replaces": "Canva certificate templates",
      "primitive": "the roster CSV as the unit, batch PDFs out",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-dupe-pages",
      "name": "PDF Duplicate Pages",
      "category": "pdf",
      "one_liner": "[batch-draft] Content-hash duplicate pages; keep the first. Specced in batch-drafts; built in Kimi swarm, awaiting download to disk.",
      "replaces": "Eyeballing a merged packet or re-scanned stack for the same page appearing twice.",
      "primitive": "page-as-visual-fingerprint: sameness judged from a rendered thumbnail hash, catching dupes that differ only in metadata/object order.",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-form-fill",
      "name": "PDF Form Fill",
      "category": "pdf",
      "one_liner": "[mt6] Fill AcroForm fields from JSON/CSV; refuses XFA. First draft 2026-07-10; audited.",
      "replaces": "Acrobat Fill and Sign",
      "primitive": "AcroForm fields filled from data rows; personal signature stamp",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-hash-manifest",
      "name": "PDF Hash Manifest",
      "category": "pdf",
      "one_liner": "[mt6] SHA-256 file + per-page hashes as CSV/JSON. First draft 2026-07-10; audited.",
      "replaces": "ad-hoc checksum scripts",
      "primitive": "per-file and per-page SHA-256 as a manifest artifact",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-insert-pages",
      "name": "PDF Insert Pages",
      "category": "pdf",
      "one_liner": "Insert another PDF's pages (all or a spec) at a 1-based position or 'end'.",
      "replaces": "Adobe Acrobat page tooling and the ilovepdf-class web utilities",
      "primitive": "Positional merge with sub-document selection in one step, replacing split-then-merge round trips.",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-invoice",
      "name": "PDF Invoice Generator",
      "category": "pdf",
      "one_liner": "[batch-draft] CSV/JSON line items -> branded invoice PDF. Specced in batch-drafts; built in Kimi swarm, awaiting download to disk.",
      "replaces": "Express invoice templates",
      "primitive": "line items in, branded deterministic PDF out",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-js-audit",
      "name": "PDF JavaScript Audit",
      "category": "pdf",
      "one_liner": "[mt6] Find JS + launch/open actions; severity ranked. First draft 2026-07-10; audited.",
      "replaces": "enterprise PDF security suites",
      "primitive": "scripts/actions as first-class listable objects",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-link-audit",
      "name": "PDF Link Audit",
      "category": "pdf",
      "one_liner": "[mt6] List internal/external links; flag broken internal. First draft 2026-07-10; audited.",
      "replaces": "manual link QA",
      "primitive": "every link + destination validity as a report",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-metadata-fingerprint",
      "name": "PDF Metadata Fingerprint",
      "category": "pdf",
      "one_liner": "[mt6] Embed buyer/order values into XMP + info keys; --verify. First draft 2026-07-10; audited.",
      "replaces": "third-party licensing wrappers",
      "primitive": "buyer identity embedded in XMP, verifiable offline",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-metadata-view",
      "name": "PDF Metadata Viewer",
      "category": "pdf",
      "one_liner": "[batch-draft] Dump document info, XMP and hidden fields. Specced in batch-drafts; built in Kimi swarm, awaiting download to disk.",
      "replaces": "Acrobat properties dialog",
      "primitive": "every field incl XMP + hidden, one dump",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-print-safe",
      "name": "PDF Print Safe",
      "category": "pdf",
      "one_liner": "[batch-draft] Overlay trim/bleed/safe-zone guides for proofs. Specced in batch-drafts; built in Kimi swarm, awaiting download to disk.",
      "replaces": "Eyeballing a proof to guess whether content is too close to the trim edge.",
      "primitive": "margin-safety-as-measurement: content checked against a real safe rectangle per page, with optional drawn guides.",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-protect",
      "name": "PDF Protect",
      "category": "pdf",
      "one_liner": "Password-protect (AES-256 default) or strip protection with the current password.",
      "replaces": "Adobe Acrobat page tooling and the ilovepdf-class web utilities",
      "primitive": "Modern AES-256 default with explicit algorithm choice; commodity tools still default to RC4 or hide the cipher.",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-qr-stamp",
      "name": "PDF QR Stamp",
      "category": "pdf",
      "one_liner": "[mt6] Stamp a QR (template per file) on chosen pages. First draft 2026-07-10; audited.",
      "replaces": "mail-merge QR plugins",
      "primitive": "templated unique QR per file/page",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-separator-sheets",
      "name": "PDF Separator Sheets",
      "category": "pdf",
      "one_liner": "[mt6] Separator/routing coversheets with QR from a CSV. First draft 2026-07-10; audited.",
      "replaces": "manual batch-scan prep",
      "primitive": "the packet list (CSV) generates separators + routing covers",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-to-lms",
      "name": "PDF-to-LMS converter",
      "category": "pdf",
      "one_liner": "Chat flagship #1",
      "replaces": "Acrobat PDF->HTML + Express templates",
      "primitive": "composition pipeline: shells out to engine convert --use-ml (PDF->IR w/ docling T2 structure), then segments IR heading blocks into per-MPEP-section records -> structured JSON intermediate. Not a standalone extractor.",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "lms"
    },
    {
      "slug": "pdf_to_pdfa",
      "name": "PDF to PDF/A",
      "category": "other",
      "one_liner": "[mt4] Convert to PDF/A with strict validation. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Never claims success before validation passes.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "per_copy_layout_fingerprint",
      "name": "Per-copy layout fingerprint",
      "category": "other",
      "one_liner": "[mt4] Seeded spacing/position perturbations for traitor tracing. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Safe-variance grading; warns on forms.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pixel-canvas",
      "name": "Pixel-art controllable-output tool",
      "category": "other",
      "one_liner": "Controllable sprite output via a mathematical intermediary language (ratios/topology), not pixel guessing.",
      "replaces": "AI pixel-art / screenshot-to-pixel generators",
      "primitive": "ratios/topology/object-relationships, not pixels",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "presentation_from_doc",
      "name": "Presentation from doc",
      "category": "other",
      "one_liner": "[mt4] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Adobe PPT-from-doc",
      "primitive": "outline + slide generation",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "price-sheet-generator",
      "name": "Price Sheet Generator",
      "category": "other",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "InDesign catalog workflow",
      "primitive": "rows in, sectioned price-sheet PDF out (document compiler)",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pricing-table-builder",
      "name": "Pricing Table Builder",
      "category": "other",
      "one_liner": "[mt6] JSON/CSV tiers into a self-contained HTML pricing table. First draft 2026-07-10; audited.",
      "replaces": "web-builder pricing widgets",
      "primitive": "tier data -> one self-contained HTML artifact",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "qr-generator",
      "name": "QR generator",
      "category": "image",
      "one_liner": "QR codes as deployment artifacts: typed validated payloads, CSV batch runs, and millimeter print sizing with a module-size floor check.",
      "replaces": "Canva/Express one-off QR boxes",
      "primitive": "QR as a deployment artifact (typed payloads, batch, print-safe sizing), not a single image",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "17/17",
      "from": null,
      "to": null
    },
    {
      "slug": "quiz_maker",
      "name": "Quiz maker",
      "category": "other",
      "one_liner": "[mt4] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Adobe quiz generation",
      "primitive": "question generation + distractors",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "repair_pdf",
      "name": "PDF repair",
      "category": "other",
      "one_liner": "[mt4] 3-tier repair (qpdf/pikepdf/mutool) + health report. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Progressive salvage with a fidelity check.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "responsive-check",
      "name": "Responsive Check",
      "category": "other",
      "one_liner": "Answer one question a page cannot answer about itself: does it side-scroll at phone widths, and which element causes it. Renders the page inside an iframe of the target width (320/360/390/430 by default), reports scrollWidth vs viewport per width, and names the outermost unclipped element past the right edge. Takes a local HTML path or an http(s) URL. --strict exits non-zero so a layout regression fails a build.",
      "replaces": "Chrome DevTools device mode / BrowserStack-style responsive checking: one width at a time, judged by eye, on one page, with no exit code.",
      "primitive": "the iframe as the viewport, not the browser window: headless Chrome floors its window near 500px and silently ignores a smaller --window-size, so sub-500px probes measure 500px and report a false pass; an iframe of the target width has no floor, so media queries resolve honestly at 320/360/390/430 and the check can run as a CI gate.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "scan_to_pdf",
      "name": "Scan to PDF",
      "category": "other",
      "one_liner": "Drafted in the Suite micro-tool pack. OCR + scan cleanup -> searchable PDF.",
      "replaces": "",
      "primitive": "",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "schema-markup-generator",
      "name": "Schema Markup Generator",
      "category": "other",
      "one_liner": "[mt6] Page facts into validated JSON-LD blocks. First draft 2026-07-10; audited.",
      "replaces": "SEO plugin black boxes",
      "primitive": "page facts -> validated JSON-LD, refuses incomplete input",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "seller-asset-suite",
      "name": "Shopify/Etsy image-and-document utility suite",
      "category": "other",
      "one_liner": "Chat flagship #4",
      "replaces": "Express generic brand/design work",
      "primitive": "the seller's listing pipeline as the unit",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "sentence-reader",
      "name": "Sentence reader",
      "category": "other",
      "one_liner": "Turn an annotated passage into a self-contained interactive reader: hover to highlight a sentence, tap to see a plain-words restatement and an explanation, toggle the whole passage original/simplified.",
      "replaces": "Acrobat read-aloud and highlight-level PDF annotation (document- or highlight-level markup that cannot explain a specific sentence on demand)",
      "primitive": "The sentence is the addressable unit: each sentence carries its own tap-to-reveal restatement and explanation, over a passage that toggles between original and simplified wording",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "5/5",
      "from": null,
      "to": null
    },
    {
      "slug": "sprite-sheet-builder",
      "name": "Sprite Sheet Builder",
      "category": "other",
      "one_liner": "[mt6] Pack many images into one sheet + JSON/CSS coordinates. First draft 2026-07-10; audited.",
      "replaces": "TexturePacker basics",
      "primitive": "pack + coordinates artifact (JSON/CSS), deterministic",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "structural_fingerprint",
      "name": "Structural fingerprint",
      "category": "other",
      "one_liner": "[mt4] Low-level per-copy object perturbations for tracing. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Invisible structural differentiation.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-a11y-fixer",
      "name": "SVG Accessibility Fixer",
      "category": "svg",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "manual aria patching",
      "primitive": "title/desc/role injection as a batch pass",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-clean",
      "name": "SVG Clean",
      "category": "svg",
      "one_liner": "Clean, sanitize, and normalize exported SVG files for safe reuse in production pages, React components, icon systems, and asset pipelines.",
      "replaces": "The cleanup pass normally done manually after exporting SVG from Canva, Illustrator, Figma, or another design editor.",
      "primitive": "Single lxml-based pipeline: strip metadata, remove active content, sanitize URL refs, prefix IDs, normalize responsive sizing - opinionated defaults instead of chained tools.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "6/6",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-css-background",
      "name": "SVG CSS Background",
      "category": "svg",
      "one_liner": "Emit CSS background-image rules that inline each SVG as a percent-encoded data URL with sensible default background sizing.",
      "replaces": "The manual chore of base64-or-URL-encoding an SVG and pasting it into a CSS rule with the right background-* properties (or running a separate encoder tool and writing the CSS by hand).",
      "primitive": "Deterministic percent-encoded data URL (via urllib.parse.quote with safe=\"\") plus an opinionated fixed rule body (no-repeat, center, contain) and a slugified selector derived from the input filename.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-extract-images",
      "name": "SVG Extract Images",
      "category": "svg",
      "one_liner": "Extract embedded base64 PNG/JPEG/GIF/WebP payloads from SVG files, optionally rewriting the SVG to reference the externalized assets.",
      "replaces": "Manual base64 grep-and-decode and the asset-splitting step of commercial SVG optimizers / design-handoff tools.",
      "primitive": "lxml walk over <image> nodes with a strict data-URI matcher, deterministic image-NNN.<ext> naming, and an optional in-place href rewrite to produce a paired externalized SVG.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-id-prefix",
      "name": "SVG ID Prefix",
      "category": "svg",
      "one_liner": "Prefix every SVG id and rewrite matching url(#id), href=\"#id\", and ARIA idref references in one pass.",
      "replaces": "Manual find-and-replace of ids (or an editor's rename-and-relink) when inlining multiple SVGs on a single HTML page and avoiding id collisions.",
      "primitive": "Opinionated deterministic id-namespacing: safe-prefix normalization plus tree-wide rewrite of url(...), href, and aria-labelledby/aria-describedby idref lists in a single pass.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-inspect",
      "name": "SVG Inspect",
      "category": "svg",
      "one_liner": "Report SVG element counts, ID uniqueness, embedded raster payloads, and structural risk warnings.",
      "replaces": "The audit/reporting surface of SVGO stats, Inkscape's document properties dialog, and ad-hoc XML/lxml scripts teams write to triage exported SVGs.",
      "primitive": "lxml over a hardened parser (entities off, network off) with a fixed set of opinionated risk heuristics (no text nodes, raster-heavy, duplicate ids) surfaced through a stable JSON schema.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-minify",
      "name": "SVG Minify",
      "category": "svg",
      "one_liner": "Conservatively minify SVG files without changing geometry: strip comments, optionally strip metadata, convert legacy xlink:href, remove whitespace-only text nodes, and write compact XML.",
      "replaces": "SVGO / online SVG optimizers when the user wants a deterministic, geometry-preserving shrink rather than an opinionated path rewriter.",
      "primitive": "One lxml parse, in-place tree pruning of comments/metadata/blank text, compact tostring - no path decimation, no attribute mangling.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-ocr-labels",
      "name": "SVG OCR Labels",
      "category": "svg",
      "one_liner": "Rasterize an SVG and OCR the preview with Tesseract to recover visible labels not stored as <text> nodes.",
      "replaces": "The label-recovery slice of commercial CAD/floor-plan OCR tools and 'SVG to searchable' pipelines that bundle their own OCR.",
      "primitive": "PyMuPDF for high-scale rasterization piped into system Tesseract in TSV mode, with confidence + bbox parsed into a stable JSON schema.",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-optimizer",
      "name": "SVG optimizer",
      "category": "svg",
      "one_liner": "[kyle-autobuild b1 #9] opportunity_map: vector/SVG optimizer (easy)",
      "replaces": "Bloated editor-exported SVGs",
      "primitive": "A lossless-by-default minifier with a visible list of what it removed",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-recolor",
      "name": "SVG Recolor",
      "category": "svg",
      "one_liner": "Recolor SVG artwork from an explicit old-to-new color map applied to fills, strokes, gradient stops, inline styles, and <style> rules.",
      "replaces": "The 'recolor artwork' / swatch replacement feature of a vector editor (Illustrator, Inkscape), narrowed to a scriptable, versionable, reproducible palette remap.",
      "primitive": "Deterministic palette map (JSON or --map pairs) plus optional RGB-distance tolerance, with hex-shaped CSS selectors protected by parsing only inside {...} declaration bodies.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "10/10",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-remove-metadata",
      "name": "SVG Remove Metadata",
      "category": "svg",
      "one_liner": "Strip <metadata> elements and Canva/C2PA/XMP/Adobe provenance comments from SVG files while leaving all rendered content intact.",
      "replaces": "Manual editor scrub of Canva/Illustrator/Figma export metadata blocks and provenance comments before publishing.",
      "primitive": "Narrow lxml pass over the shared svg_core.remove_metadata: element and comment sweep only, no attribute or URL rewriting.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-render",
      "name": "SVG Render",
      "category": "svg",
      "one_liner": "Render SVG files to PNG and/or PDF via PyMuPDF.",
      "replaces": "The rasterization slice of Inkscape / CairoSVG / commercial SVG-to-PNG/PDF converters.",
      "primitive": "PyMuPDF (fitz) as the SVG-to-raster/PDF engine, driven by opinionated defaults (scale=2.0, format=png) and a batch directory pipeline.",
      "status": "done",
      "runner": "cli",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-responsive",
      "name": "SVG Responsive",
      "category": "svg",
      "one_liner": "Add a missing viewBox from numeric width/height and set root sizing (width=100%, height=auto, preserveAspectRatio, block display) for responsive layouts.",
      "replaces": "The manual editor step of opening each exported SVG to add a viewBox and CSS-friendly root sizing so it scales to its container.",
      "primitive": "Opinionated single-pass root normalization: viewBox synthesized from numeric root width/height, plus a fixed responsive style set merged into the root element.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-sanitize",
      "name": "SVG Sanitize",
      "category": "svg",
      "one_liner": "Remove active SVG content, event handlers, remote links, javascript: URLs, CSS imports, and unsafe CSS url(...) references while preserving internal fragment refs and data-image references.",
      "replaces": "Ad-hoc DOMPurify/regex passes people write to make third-party SVGs safe to inline in web pages.",
      "primitive": "Single svg_core.sanitize_tree walk with an allowlist for internal (#id) and data:image references and a denylist for on* attributes, script/foreignObject/iframe/etc., CSS expression, @import, and -moz-binding.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-sprite-builder",
      "name": "SVG Sprite Builder",
      "category": "svg",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Illustrator export + manual sprite assembly",
      "primitive": "many icons -> one symbol sheet + use refs",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "svg-stroke-to-path",
      "name": "SVG stroke to path",
      "category": "svg",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Illustrator outline-stroke",
      "primitive": "Geometric stroke outlining to filled shapes for cross-engine consistency",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": "svg-stroke",
      "to": "path"
    },
    {
      "slug": "svg-to-css",
      "name": "SVG to CSS",
      "category": "svg",
      "one_liner": "[kyle-autobuild b1 #8] opportunity_map: vector/Vector-to-CSS/HTML (easy)",
      "replaces": "Manual SVG-to-markup work",
      "primitive": "An SVG as front-end code you ship, not a design file you re-export",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": "svg",
      "to": "css"
    },
    {
      "slug": "svg-to-jpg-webp",
      "name": "SVG to JPG/WebP",
      "category": "svg",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Editor/online SVG raster export",
      "primitive": "Background-aware raster export at chosen sizes and formats; extends the PNG/PDF renderer",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": "svg",
      "to": "jpg-webp"
    },
    {
      "slug": "svg-to-react",
      "name": "SVG to React",
      "category": "svg",
      "one_liner": "Convert SVG files into React JSX component source with hyphenated attributes rewritten to camelCase, class to className, inline style parsed to a JSX object, and {...props} spread on the root.",
      "replaces": "Hand-porting an SVG into a React component (or reaching for a full transformer toolchain like SVGR) when a small, opinionated JSX conversion is all that is needed.",
      "primitive": "Deterministic AST walk over the parsed SVG with a fixed attribute rename table (class -> className, aria-*/data-* preserved, kebab -> camel elsewhere), style-string to JSX-object conversion, and {...props} on the root component.",
      "status": "done",
      "runner": "svgtool",
      "script": null,
      "tests": "3/3",
      "from": "svg",
      "to": "react"
    },
    {
      "slug": "text_level_fingerprint",
      "name": "Text-level fingerprint",
      "category": "other",
      "one_liner": "[mt4] Context-aware synonym substitution for narrative text. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Dry-run first; never on legally binding text.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "ticket-generator",
      "name": "Ticket Generator",
      "category": "other",
      "one_liner": "[mt6] CSV rows into tickets: unique IDs + QR, N-up. First draft 2026-07-10; audited.",
      "replaces": "Canva ticket templates",
      "primitive": "CSV rows -> unique-ID QR tickets, N-up",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "unlock_pdf",
      "name": "PDF unlock",
      "category": "other",
      "one_liner": "[mt4] Remove password/encryption from user-owned PDFs. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Preserves internals; owner/open password.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "video-compress",
      "name": "Video Compress",
      "category": "other",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Media Encoder presets",
      "primitive": "named honest targets (share/web/archive) over a CRF wrapper",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "video-remove-silence",
      "name": "Video Remove Silence",
      "category": "other",
      "one_liner": "[mt6] silencedetect + concat cuts with a dry-run cut list. First draft 2026-07-10; audited.",
      "replaces": "Premiere manual ripple cuts",
      "primitive": "silencedetect cut list, previewable before writing",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "video-slideshow",
      "name": "Video Slideshow",
      "category": "other",
      "one_liner": "[mt6] First draft returned 2026-07-10; audited by irp-o.",
      "replaces": "Express slideshow maker",
      "primitive": "images + durations CSV as the timeline",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "video-to-gif",
      "name": "Video to GIF",
      "category": "other",
      "one_liner": "[kyle-autobuild b1 #10] opportunity_map: express/video to GIF (easy)",
      "replaces": "Express video-to-GIF / clip actions",
      "primitive": "A wrapper that picks good ffmpeg flags (two-pass palettegen/paletteuse) for small clean GIFs",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": "video",
      "to": "gif"
    },
    {
      "slug": "visual-doc-converter",
      "name": "Visual converter for flattened documents",
      "category": "other",
      "one_liner": "Chat flagship #6",
      "replaces": "Acrobat multi-format PDF export",
      "primitive": "preserve visual alignment while making content usable",
      "status": "planned",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "watermark_pdf",
      "name": "PDF watermark",
      "category": "other",
      "one_liner": "[mt4] Vector text watermark with real opacity + adaptive placement. First draft 2026-07-10; audited.",
      "replaces": "Adobe/Acrobat",
      "primitive": "Occlusion-aware: auto above/below content.",
      "status": "in-progress",
      "runner": "cli",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "watermarker",
      "name": "Watermarker",
      "category": "image",
      "one_liner": "Batch-watermark images with text or a logo sized relative to each image, anchored on a 9-point grid or tiled.",
      "replaces": "Express watermarking",
      "primitive": "A batch protection workflow, not a single-image editor",
      "status": "done",
      "runner": "imgtool",
      "script": null,
      "tests": "15/15",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-to-html",
      "name": "PDF to HTML",
      "category": "convert",
      "one_liner": "A pixel-faithful copy of the page with real, selectable text.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "html",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "html"
    },
    {
      "slug": "pdf-to-webpage",
      "name": "PDF to web page",
      "category": "convert",
      "one_liner": "A clean, reflowing web page: read the structure, correct it, then build.",
      "replaces": "",
      "primitive": "",
      "status": "planned",
      "runner": "pdfwebpage",
      "op": null,
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "webpage"
    },
    {
      "slug": "pdf-to-word",
      "name": "PDF to Word",
      "category": "convert",
      "one_liner": "An editable .docx with headings, text and tables.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "docx",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "docx"
    },
    {
      "slug": "pdf-to-markdown",
      "name": "PDF to Markdown",
      "category": "convert",
      "one_liner": "Headings, lists and tables as plain markup.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "md",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "md"
    },
    {
      "slug": "pdf-to-text",
      "name": "PDF to text",
      "category": "convert",
      "one_liner": "Just the words, in reading order.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "txt",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "txt"
    },
    {
      "slug": "pdf-to-csv",
      "name": "PDF to CSV",
      "category": "convert",
      "one_liner": "Table-ish lines split into rows and cells.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "csv",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "csv"
    },
    {
      "slug": "pdf-to-excel",
      "name": "PDF to Excel",
      "category": "convert",
      "one_liner": "A .xlsx workbook built from detected rows.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "xlsx",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "xlsx"
    },
    {
      "slug": "pdf-to-epub",
      "name": "PDF to EPUB",
      "category": "convert",
      "one_liner": "A reflowable e-book for readers.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "epub",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "epub"
    },
    {
      "slug": "pdf-to-images",
      "name": "PDF to images",
      "category": "convert",
      "one_liner": "One PNG per page, zipped when there are many.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "png",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "png"
    },
    {
      "slug": "pdf-to-slides",
      "name": "PDF to slides",
      "category": "convert",
      "one_liner": "A .pptx with one full-page image per slide.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "docconv",
      "op": "pptx",
      "script": null,
      "tests": "",
      "from": "pdf",
      "to": "pptx"
    },
    {
      "slug": "html-editor",
      "name": "HTML Editor",
      "category": "code",
      "one_liner": "Open an HTML file, edit it as a rendered page, and save it back as real HTML. The source and the page stay in sync.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "editor",
      "op": null,
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "image-diff",
      "name": "Image Difference Checker",
      "category": "image",
      "one_liner": "Compare exact pixels and tolerated changes with swipe, overlay, heatmap, metrics, and evidence exports.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "imagediff",
      "op": null,
      "script": null,
      "tests": "18/18",
      "from": null,
      "to": null,
      "search_title": "Compare Images Online | Private Pixel Difference Checker",
      "search_description": "Compare two images privately with swipe, overlay, side-by-side and a pixel heatmap. Measure exact and thresholded changes and export PNG or JSON.",
      "search_intro": "A threshold can tell you that no change is large enough to matter, but it cannot make two different images identical. This comparison workbench keeps those answers separate. It measures exact visible-pixel changes and above-threshold changes, localizes them with an inclusive bounding box, and provides a transparent heatmap and versioned JSON report.",
      "how_it_works": [
        "Choose a reference image and candidate image; strict mode refuses silent dimension changes.",
        "Set the maximum tolerated sRGB channel delta and the background used to compare transparency.",
        "Inspect swipe, overlay, heatmap, or side-by-side views, then download the heatmap and metrics."
      ],
      "use_cases": [
        "Review a before-and-after edit without losing small changes in a visual slider.",
        "Check a visual regression screenshot and locate the region that changed.",
        "Measure whether a re-export or compression pass changed any visible pixels."
      ],
      "limits": [
        "This is deterministic pixel comparison, not perceptual similarity or a quality score.",
        "Images are not automatically aligned, cropped, rotated, or color-profile normalized.",
        "Animated frames, HDR content, and comparisons above 24 million output pixels are not supported."
      ],
      "faq": [
        {
          "q": "Are images uploaded?",
          "a": "No. Decoding, compositing, pixel measurement, preview, and downloads all happen in this browser tab."
        },
        {
          "q": "Why can a result be within threshold but not identical?",
          "a": "Exact identity means every visible channel is equal. Within threshold means differences exist, but none is larger than the tolerance you selected."
        },
        {
          "q": "What happens when dimensions differ?",
          "a": "Strict mode stops and explains the mismatch. You can explicitly choose Resize B to A, after which the report records both original dimensions and the resize."
        }
      ],
      "related": [
        "dupe-finder",
        "image-optimizer",
        "image-resizer"
      ]
    },
    {
      "slug": "pdf-merge",
      "name": "Merge PDFs",
      "category": "pdf",
      "one_liner": "Combine PDFs in the order you set.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "merge",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-split",
      "name": "Split PDF",
      "category": "pdf",
      "one_liner": "Review every output group and page before building private, manifest-verified PDF parts.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "split",
      "script": null,
      "tests": "",
      "from": null,
      "to": null,
      "search_title": "Split PDF by Page or Range | Private Visual Review",
      "search_description": "Split a PDF locally by page, fixed groups, or strict ranges. Review thumbnails, omissions, duplicates, filenames, and a SHA-256 manifest before download.",
      "search_intro": "A split instruction should never turn into a different successful-looking job. This workspace parses the same strict page language as the CLI, previews every output group, blocks malformed or out-of-range terms, and makes omitted or repeated pages an explicit decision. The resulting PDF files and manifest are built locally in a dedicated worker.",
      "how_it_works": [
        "Choose a PDF up to the tested 50 MiB and 60-page browser limits; low-resolution page previews render locally.",
        "Use every page, one file, every N pages, visual split boundaries, or advanced ranges where semicolons start new files and commas stay inside one file.",
        "Review group names, page order, omissions, duplicates, and page-copy caveats, then download one PDF or a manifest-bound ZIP."
      ],
      "use_cases": [
        "Separate a packet, scan, workbook, or exhibit set at visible page boundaries.",
        "Create exact noncontiguous or descending page groups with a deterministic range language.",
        "Produce locally processed parts with page sequences and SHA-256 hashes recorded for handoff."
      ],
      "limits": [
        "Browser input is capped at 50 MiB and 60 pages, and output at 250 MiB; larger jobs should use the local CLI.",
        "Page copying is not a complete PDF catalog clone and can lose or alter bookmarks, forms, attachments, labels, signatures, tags, actions, and other document-level features.",
        "The output is rearranged, not sanitized; page links or actions that survive copying may remain active."
      ],
      "faq": [
        {
          "q": "How do PDF split ranges work?",
          "a": "Commas join pages inside one output and semicolons start another output. For example, 1-3;4-6 makes two three-page PDFs, while 1-3,4-6 makes one six-page PDF. Invalid terms never fall back to another mode."
        },
        {
          "q": "Can a page appear in two split files?",
          "a": "Yes, but cross-output duplication is shown and requires a separate acknowledgement. Omitted pages require their own acknowledgement, and both reset whenever the plan changes."
        },
        {
          "q": "Is the PDF uploaded?",
          "a": "No. After the route loads, PDF reading, thumbnails, page copying, ZIP creation, hashing, and downloads happen in this browser tab with locally bundled runtime code."
        }
      ],
      "related": [
        "pdf-reorder",
        "pdf-extract-pages",
        "pdf-delete-pages"
      ]
    },
    {
      "slug": "pdf-delete-pages",
      "name": "Delete pages",
      "category": "pdf",
      "one_liner": "Remove the pages you list, keep the rest.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "delete",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-extract-pages",
      "name": "Extract pages",
      "category": "pdf",
      "one_liner": "Pull a page range into a new PDF.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "extract",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-crop",
      "name": "Crop PDF",
      "category": "pdf",
      "one_liner": "Drag a box on the page, crop every page to it.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "crop",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-compress",
      "name": "Compress PDF",
      "category": "pdf",
      "one_liner": "Screen, print or archive quality. You pick the tradeoff.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "compress",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-rotate",
      "name": "Rotate pages",
      "category": "pdf",
      "one_liner": "Rotate all pages or just the ones you list.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "rotate",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-page-numbers",
      "name": "Page numbers",
      "category": "pdf",
      "one_liner": "Stamp clean page numbers where you want them.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "pagenum",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "images-to-pdf",
      "name": "Images to PDF",
      "category": "pdf",
      "one_liner": "JPGs and PNGs into one PDF, one image per page.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "img2pdf",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-reorder",
      "name": "Reorder PDF Pages",
      "category": "pdf",
      "one_liner": "Move reviewed page thumbnails without silently dropping the rest of the document.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "reorder",
      "script": null,
      "tests": "",
      "from": null,
      "to": null,
      "search_title": "Reorder PDF Pages Privately | Visual Page Organizer",
      "search_description": "Reorder PDF pages locally with thumbnails and keyboard-ready move controls. Preserve every page by default, review exclusions, and export a SHA-256 manifest.",
      "search_intro": "Typing one page number should not silently discard every other page. This organizer starts with a complete document, keeps the immutable source number visible on every thumbnail, and provides native earlier, later, start, end, exclude, and restore controls. A strict text order can lead the sequence while unlisted pages remain appended unless exclusion is deliberately reviewed.",
      "how_it_works": [
        "Choose a PDF up to the tested 50 MiB and 60-page browser limits and review its locally rendered page thumbnails.",
        "Move pages with visible buttons or enter the strict page language; every unlisted page stays in the output unless it is explicitly excluded.",
        "Review the final sequence, any omissions, and page-copy caveats, then download the PDF and its hash-bound JSON manifest."
      ],
      "use_cases": [
        "Fix scanned pages that arrived out of order without uploading the document.",
        "Move a cover, appendix, signature page, or insert while keeping the rest intact.",
        "Reverse a document or create a reviewed subset with a durable source-to-result page map."
      ],
      "limits": [
        "Browser input is capped at 50 MiB and 60 pages, and output at 250 MiB; larger jobs should use the local CLI.",
        "Browser page copying can lose or alter bookmarks, forms, attachments, labels, signatures, tags, actions, and other document-level features, so the caveat always requires acknowledgement.",
        "Reordering modifies the PDF and invalidates cryptographic signatures; it does not sanitize links, annotations, or active content that may remain on copied pages."
      ],
      "faq": [
        {
          "q": "Will unlisted PDF pages be deleted?",
          "a": "No. In the browser, unlisted pages append in their original order. Excluding pages is a separate reviewed action, and the download stays disabled until that omission is acknowledged."
        },
        {
          "q": "Can I reorder pages without dragging?",
          "a": "Yes. Every page has native Move earlier, Move later, Move to start, Move to end, and Exclude controls designed for keyboard, click, and tap use."
        },
        {
          "q": "Is the PDF uploaded?",
          "a": "No. After the route loads, page rendering, reordering, hashing, verification, and downloads run locally with bundled browser code."
        }
      ],
      "related": [
        "pdf-split",
        "pdf-delete-pages",
        "pdf-rotate"
      ]
    },
    {
      "slug": "pdf-watermark",
      "name": "Watermark PDF",
      "category": "pdf",
      "one_liner": "A diagonal text watermark across every page, at the opacity you choose.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "watermark",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-bates",
      "name": "Bates numbering",
      "category": "pdf",
      "one_liner": "Legal Bates stamps: prefix, start number, zero-padded, one per page.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "bates",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-proof-stamp",
      "name": "Proof stamp",
      "category": "pdf",
      "one_liner": "DRAFT / APPROVED / CONFIDENTIAL and more, stamped big on every page.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "proofstamp",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-metadata-scrub",
      "name": "Scrub metadata",
      "category": "pdf",
      "one_liner": "Strip author, title, producer and other identifying metadata.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "scrub",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-nup",
      "name": "N-up imposition",
      "category": "pdf",
      "one_liner": "Print 2 or 4 pages on one sheet.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "nup",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-booklet",
      "name": "Booklet imposition",
      "category": "pdf",
      "one_liner": "Reorder pages into a foldable saddle-stitch booklet.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "booklet",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-add-margins",
      "name": "Add margins",
      "category": "pdf",
      "one_liner": "Add clean white margins around every page for binding or notes.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "margins",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-flatten-forms",
      "name": "Flatten form fields",
      "category": "pdf",
      "one_liner": "Bake filled form fields into the page so they cannot be changed.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "flattenforms",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-attach-file",
      "name": "Attach a file",
      "category": "pdf",
      "one_liner": "Embed any file inside the PDF so it travels with the document.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "attach",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-extract-attachments",
      "name": "Extract attachments",
      "category": "pdf",
      "one_liner": "Pull embedded file attachments back out of a PDF.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "getattach",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-exhibit-label",
      "name": "Exhibit labels",
      "category": "pdf",
      "one_liner": "Stamp legal exhibit labels in a box on the page.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "exhibit",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-dupe-page-remove",
      "name": "Remove duplicate pages",
      "category": "pdf",
      "one_liner": "Drop repeated pages and keep the first of each.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "dedupe",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-blank-pages",
      "name": "Remove blank pages from PDF",
      "category": "pdf",
      "one_liner": "Measure visible ink, review every page, and remove empty or near-blank sheets.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfpreflight",
      "op": "blank-pages",
      "script": null,
      "tests": "",
      "from": null,
      "to": null,
      "search_title": "Remove Blank Pages from PDF Automatically | Private",
      "search_description": "Find and remove blank or near-blank PDF pages in your browser. Review measured ink coverage and every page preview before downloading. No uploads.",
      "search_intro": "Automatic blank-page tools often miss the white back of a duplex scan because that page still contains a full-page image. This scan renders each page locally, measures how much visible ink remains, and selects likely blanks without deleting anything until the page previews are reviewed.",
      "how_it_works": [
        "Choose strict, scanner-dust, or loose sensitivity and scan the PDF locally.",
        "Review every page preview, its measured ink coverage, and the suggested decision.",
        "Click any mistaken suggestion to keep or remove it, then download the cleaned PDF and optional JSON report."
      ],
      "use_cases": [
        "Remove white backs produced by duplex document scanners.",
        "Clean trailing empty sheets and blank separators before printing or sharing.",
        "Audit a large PDF quickly without trusting an automatic delete decision."
      ],
      "limits": [
        "A page with a tiny intentional mark can resemble scanner dust; every suggestion should be reviewed.",
        "Higher sensitivity may select faint handwriting, pale watermarks, or lightly printed pages.",
        "Removing pages can change printed page references and internal links in the source document."
      ],
      "faq": [
        {
          "q": "Does it remove scanned blank pages?",
          "a": "Yes. It measures a rendered preview, so a white full-page scan can be detected even though the PDF technically contains an image."
        },
        {
          "q": "Can it delete a nonblank page by mistake?",
          "a": "The scan only preselects candidates. Every page remains visible and can be switched between keep and remove before the new PDF is built."
        },
        {
          "q": "Is the PDF uploaded?",
          "a": "No. Rendering, measurement, page removal, and download all happen in this browser tab."
        }
      ],
      "related": [
        "pdf-delete-pages",
        "pdf-dupe-page-remove",
        "pdf-split"
      ]
    },
    {
      "slug": "pdf-image-dpi-check",
      "name": "Check PDF image DPI",
      "category": "pdf",
      "one_liner": "Measure every raster image at its placed print size and flag low effective resolution.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfpreflight",
      "op": "image-dpi",
      "script": null,
      "tests": "",
      "from": null,
      "to": null,
      "search_title": "Check PDF Image DPI Online | Private Print Preflight",
      "search_description": "Check effective image DPI or PPI inside a PDF before printing. Measure every raster placement at final size and export CSV or JSON. No uploads.",
      "search_intro": "A 300-PPI image can become a 150-PPI image when it is enlarged to twice its intended size. This preflight reads each PDF image's native pixel dimensions and placement transform, then reports the effective resolution on both axes at the size it will actually print.",
      "how_it_works": [
        "Set the minimum resolution for screen, everyday print, or close-view print work.",
        "Inspect every raster placement by page, native pixels, placed size, axis resolution, and pass or low status.",
        "Download the complete preflight as CSV for a print job or JSON for another workflow."
      ],
      "use_cases": [
        "Catch blurry photographs before a brochure, worksheet, or book goes to print.",
        "Locate the page where an image was enlarged beyond its useful resolution.",
        "Add a deterministic low-resolution gate to a print-production handoff."
      ],
      "limits": [
        "Vector artwork and text are resolution-independent and are not listed as raster images.",
        "Resolution is one print-quality factor; bleed, color space, fonts, transparency, and compression need separate checks.",
        "The report measures source pixels at placement size and cannot restore missing detail."
      ],
      "faq": [
        {
          "q": "Is this DPI or PPI?",
          "a": "For a raster image, pixels per inch is the precise term. The phrase image DPI is commonly used in PDF and print searches, so the interface shows effective PPI while supporting that familiar name."
        },
        {
          "q": "What threshold should be used?",
          "a": "300 PPI is a common target for close-view quality print, 150 PPI can suit everyday print, and lower values may be acceptable for screen use or large-format work viewed from farther away."
        },
        {
          "q": "Does the PDF leave the browser?",
          "a": "No. The PDF operator list and image placement transforms are inspected locally; the site has no upload endpoint."
        }
      ],
      "related": [
        "pdf-size-analyzer",
        "pdf-compress",
        "pdf-print-safe"
      ]
    },
    {
      "slug": "pdf-size-analyzer",
      "name": "Analyze PDF file size",
      "category": "pdf",
      "one_liner": "Find image-heavy pages, oversized source pixels, and the most likely reason a PDF is large.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfassets",
      "op": "size-analyzer",
      "script": null,
      "tests": "7/7",
      "from": null,
      "to": null,
      "search_title": "Analyze PDF File Size | Find What Makes a PDF Large",
      "search_description": "Diagnose a large PDF privately in your browser. Measure decoded images, placements, source pixels, and effective PPI, then export a JSON report.",
      "search_intro": "A PDF compressor can make a file smaller without explaining what it changed. This analyzer starts with diagnosis: it counts unique decoded images, follows their page placements, measures source pixels and effective resolution, and points to likely scan or over-resolution problems. The companion CLI goes deeper by attributing exact stored bytes to image, font, page-content, form, and overhead categories.",
      "how_it_works": [
        "Choose the large PDF; PDF.js inspects its pages and raster image operators locally.",
        "Review unique images, repeat placements, decoded pixel memory, effective PPI, and focused suggestions.",
        "Download a JSON diagnosis, or run the CLI when an exact raw-stream byte budget is required."
      ],
      "use_cases": [
        "Find full-page scans or oversized photographs before choosing compression settings.",
        "Explain why a seemingly simple report is much larger than expected.",
        "Separate image problems from likely font, vector, attachment, revision, or structural overhead."
      ],
      "limits": [
        "Browser analysis measures decoded images and placements, not the compressed byte length of each stored PDF object.",
        "PDF.js may not expose every unusual image stream or malformed object.",
        "The analyzer diagnoses likely causes; it does not alter or compress the source file."
      ],
      "faq": [
        {
          "q": "Why is my PDF file so large?",
          "a": "Common causes include full-page scans, photographs stored at far more pixels than their placed size needs, embedded fonts, attachments, complex vector content, and incremental saved revisions. This browser report measures the image side; the CLI attributes exact stored bytes across all major stream categories."
        },
        {
          "q": "Does decoded pixel memory equal PDF file size?",
          "a": "No. Decoded memory estimates the working pixels required to display images. Stored streams may be much smaller because JPEG, PNG-style filters, and other PDF compression are applied."
        },
        {
          "q": "Is the PDF uploaded?",
          "a": "No. Inspection runs in this tab and the site has no file-upload endpoint."
        }
      ],
      "related": [
        "pdf-compress",
        "pdf-image-dpi-check",
        "pdf-extract-images"
      ]
    },
    {
      "slug": "pdf-extract-images",
      "name": "Extract images from PDF",
      "category": "pdf",
      "one_liner": "Recover each unique embedded image as a previewable PNG without rasterizing whole pages.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfassets",
      "op": "extract-images",
      "script": null,
      "tests": "8/8",
      "from": null,
      "to": null,
      "search_title": "Extract Images from PDF Privately | Download as PNG",
      "search_description": "Extract embedded images from a PDF in your browser, preview every unique asset, and download individual PNGs or one ZIP. No uploads.",
      "search_intro": "Converting PDF pages to pictures is not the same as recovering the pictures inside them. This tool reads the PDF image operators, deduplicates repeated assets, shows where each one appears, and exports the decoded pixels as PNG without surrounding page text or margins. The CLI can preserve the original embedded image stream instead.",
      "how_it_works": [
        "Choose a PDF and set the minimum shorter-side dimension to skip tiny icons or masks.",
        "Review every unique decoded image with pixel dimensions, page appearances, and placement count.",
        "Download one PNG, all matching images as a ZIP, and a JSON manifest."
      ],
      "use_cases": [
        "Recover photographs from a brochure, deck, report, or archived PDF.",
        "Locate and reuse an image repeated across several pages without saving duplicates.",
        "Audit the native pixel dimensions of source images separately from the rendered pages."
      ],
      "limits": [
        "Browser downloads are decoded PNGs, so original JPEG compression and embedded file bytes are not preserved.",
        "Masks, color profiles, or unusual PDF image encodings can render differently from their underlying stream.",
        "Vector drawings and page text are not embedded raster images and are not extracted."
      ],
      "faq": [
        {
          "q": "Does this extract the original image quality?",
          "a": "It preserves the decoded pixel dimensions, but the browser re-encodes those pixels as PNG. Use the CLI when the exact original embedded JPEG or PNG stream is required."
        },
        {
          "q": "Why is an image listed only once when it appears on many pages?",
          "a": "PDFs commonly reuse one image object. The tool deduplicates that object and reports every page and placement count."
        },
        {
          "q": "Does it turn each PDF page into an image?",
          "a": "No. It extracts raster assets placed inside pages. Use PDF to images when one complete image per page is wanted."
        }
      ],
      "related": [
        "pdf-to-images",
        "pdf-size-analyzer",
        "pdf-image-dpi-check"
      ]
    },
    {
      "slug": "pdf-redact",
      "name": "Securely redact a PDF",
      "category": "pdf",
      "one_liner": "Find sensitive text, review every region, and download an image-only PDF with no extractable source text.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfredact",
      "op": "secure-redact",
      "script": null,
      "tests": "13/13",
      "from": null,
      "to": null,
      "search_title": "Secure PDF Redaction Online | Remove Text, Not Cover It",
      "search_description": "Redact PDF text securely in your browser. Find phrases or sensitive-data patterns, add manual boxes, rasterize the result, and verify zero extractable text.",
      "search_intro": "A black rectangle is not a secure redaction when the words remain selectable underneath it. This workflow finds exact phrases and common sensitive-data patterns, makes every proposed region reviewable, supports manual boxes for scans, then rasterizes each page with the chosen areas burned to black. The downloaded PDF is reopened and must contain zero extractable text before it is released.",
      "how_it_works": [
        "Enter exact phrases or choose email, SSN, phone, Luhn-valid card, or IPv4 patterns.",
        "Review the highlighted pages, ignore false positives, and drag manual boxes over scans or split text runs.",
        "Download an image-only redacted PDF plus a JSON report after the browser verifies no text remains extractable."
      ],
      "use_cases": [
        "Remove account details, contact information, identifiers, or client names before sharing.",
        "Redact image-only scans by drawing manual regions directly on each page preview.",
        "Avoid the common failure where a visual black bar leaves the underlying text copyable or searchable."
      ],
      "limits": [
        "Secure browser output intentionally discards all source text, links, forms, attachments, metadata, and accessibility structure.",
        "A phrase split across separate PDF text runs may not match automatically and needs a manual box.",
        "Automated patterns can have false positives or miss unusual formats; every page must be reviewed."
      ],
      "faq": [
        {
          "q": "Is drawing a black box over PDF text secure?",
          "a": "Not by itself. An overlay can leave the original text or image data in the file. This browser tool creates new rasterized pages with the selected regions burned into their pixels, then verifies the result has no extractable text."
        },
        {
          "q": "Will the redacted PDF still be searchable?",
          "a": "No. Removing all source text is the browser workflow's security boundary. The local CLI performs object-level redaction and can preserve unredacted searchable text."
        },
        {
          "q": "Does the file leave my device?",
          "a": "No. Matching, page rendering, redaction, verification, and download happen locally in this tab."
        }
      ],
      "related": [
        "pdf-metadata-scrub",
        "pdf-flatten-forms",
        "pdf-extract-text"
      ]
    },
    {
      "slug": "pdf-split-by-size",
      "name": "Split by size",
      "category": "pdf",
      "one_liner": "Break a large PDF into parts under a size you set.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfop",
      "op": "splitsize",
      "script": null,
      "tests": "",
      "from": null,
      "to": null
    },
    {
      "slug": "pdf-ocr",
      "name": "OCR Evidence Workbench",
      "category": "pdf",
      "one_liner": "OCR images and scanned PDF pages locally, then review uncertain words against the raw engine evidence.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "ocrworkbench",
      "op": "ocr",
      "script": null,
      "tests": "153 CLI + 20 browser",
      "from": null,
      "to": null,
      "search_title": "OCR Images and Scanned PDFs Privately | Evidence Workbench",
      "search_description": "OCR images and scanned PDF pages locally in your browser. Review uncertain words, compare evidence, preserve punctuation, and export editable text or JSON.",
      "search_intro": "A successful-looking text box is not proof of a faithful transcription. This workbench runs a pinned Tesseract LSTM engine locally, keeps every observed pass, chooses one whole observed pass per page instead of inventing unseen text, and lets you correct the editable result without rewriting the raw evidence.",
      "how_it_works": [
        "Choose one PNG, JPEG, WebP, BMP, or PDF and select English, Spanish, or both languages.",
        "Run quick or redundant OCR; PDF pages are rendered locally, every scheduled pass retains its status, configuration, and warnings, and every valid completed pass retains text, TSV geometry, and hOCR.",
        "Review low-confidence words beside the source, edit the complete result, then export current text, canonical JSON, or a raw evidence ZIP."
      ],
      "use_cases": [
        "Recover English or Spanish text from screenshots, scans, photographed pages, and image-only PDFs.",
        "Inspect punctuation, accents, code-like spacing, and ambiguous words instead of hiding disagreement behind one output.",
        "Keep an auditable engine record separate from later human corrections."
      ],
      "limits": [
        "Browser input is capped at 25 MiB, 12 PDF pages, 12 million pixels per page, 48 million rendered pixels, 36 OCR passes, and 64 MiB of uncompressed evidence; balanced mode therefore accepts at most nine pages.",
        "Handwriting, equations, arbitrary scripts, exact reading order, tables, typography, bold or italic reconstruction, and universal font fidelity are not promised; review the source and uncertain tokens.",
        "The browser surface does not create searchable PDFs or ALTO and is intentionally narrower than the local CLI evidence pipeline."
      ],
      "faq": [
        {
          "q": "Does the image or recognized text leave this device?",
          "a": "No. The pinned worker, OCR core, English and Spanish models, and PDF support files are served as static same-origin assets; file bytes and recognized text stay in this tab and no OCR cache is persisted."
        },
        {
          "q": "Is the confidence score a probability that a word is correct?",
          "a": "No. It is raw engine evidence used to prioritize review, not a calibrated probability or a guarantee."
        },
        {
          "q": "Why preserve several passes?",
          "a": "Different preprocessing and page-segmentation assumptions expose different mistakes. The workbench retains those observations, while the canonical page remains one traceable engine pass."
        }
      ],
      "related": [
        "pdf-extract-text",
        "pdf-to-images",
        "pdf-image-dpi-check",
        "image-diff"
      ]
    },
    {
      "slug": "pdf-extract-text",
      "name": "Extract structured PDF text",
      "category": "pdf",
      "one_liner": "Rebuild selectable text in reading order, correct it against the source page, and export Markdown, text, or JSON locally.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfstructure",
      "op": "extract-text",
      "script": null,
      "tests": "4 CLI + 12 structure-editor",
      "from": null,
      "to": null,
      "search_title": "Extract and Edit PDF Text Privately | Markdown or JSON",
      "search_description": "Extract and edit a PDF text layer locally. Review source-linked blocks, fix reading order and headings, then export Markdown, text, or structured JSON.",
      "search_intro": "Use this when copy and paste scrambles a report, paper, manual, or two-column PDF. It reads positioned text already embedded in the file, reconstructs reading order, links every extracted block to its source-page box, and keeps the structured result editable before export.",
      "how_it_works": [
        "Choose a born-digital PDF and the pages you need.",
        "Review each editable block beside its highlighted source-page location; correct text, heading levels, and order with undo and redo.",
        "Find and replace, clean whitespace, then copy or download Markdown, plain text, or JSON generated from the current edits."
      ],
      "use_cases": [
        "Move a report into notes or a knowledge base without uploading it.",
        "Recover paragraph order from one- and two-column documents.",
        "Create page-referenced JSON for search, accessibility review, or another local tool."
      ],
      "limits": [
        "This extracts an existing text layer; it does not OCR image-only scans.",
        "Complex magazines, tables, equations, and decorative layouts may still need manual cleanup.",
        "The browser workbench accepts up to 50 MiB, 150 pages, 250,000 text runs, and 5 MiB per exported text artifact; larger work belongs in the CLI."
      ],
      "faq": [
        {
          "q": "Does this upload my PDF?",
          "a": "No. PDF.js reads the file in this browser tab; the site has no upload or conversion endpoint."
        },
        {
          "q": "Why is the result empty?",
          "a": "The chosen pages are probably scanned images without selectable text. Run OCR first, then extract the new text layer."
        },
        {
          "q": "What makes this different from copying all text?",
          "a": "It uses each text run's position and size to rebuild columns, paragraphs, headings, page references, and structured JSON."
        }
      ],
      "related": [
        "pdf-toc",
        "pdf-to-markdown",
        "pdf-to-webpage"
      ]
    },
    {
      "slug": "pdf-toc",
      "name": "Extract PDF bookmarks and table of contents",
      "category": "pdf",
      "one_liner": "Extract or infer PDF bookmarks, repair the hierarchy and destinations, then export a reviewed outline locally.",
      "replaces": "",
      "primitive": "",
      "status": "done",
      "runner": "pdfstructure",
      "op": "toc",
      "script": null,
      "tests": "6 CLI + 12 structure-editor",
      "from": null,
      "to": null,
      "search_title": "Extract and Edit PDF Bookmarks Privately | Outline Editor",
      "search_description": "Read and edit PDF bookmarks locally. Repair titles, hierarchy, order, and page destinations, then export Markdown, text, CSV, or JSON.",
      "search_intro": "A PDF's sidebar bookmarks are structured data, but most readers make them awkward to copy or correct. This workbench extracts the complete hierarchy, clearly separates embedded bookmarks from inferred heading suggestions, previews every page destination, and keeps the outline editable before export.",
      "how_it_works": [
        "Drop in a PDF and choose embedded bookmarks, automatic fallback, or heading inference.",
        "Preview destination pages and repair titles, levels, ordering, indentation, duplicates, and unresolved page numbers with undo and redo.",
        "Copy or download Markdown, text, CSV, or JSON generated from the current reviewed outline."
      ],
      "use_cases": [
        "Reuse a book or manual's bookmark tree in documentation or a website.",
        "Audit whether a long PDF has usable navigation and page destinations.",
        "Draft a contents list for a born-digital report that has no embedded outline."
      ],
      "limits": [
        "Inferred entries use typography, not semantic understanding, and must be reviewed.",
        "Scanned PDFs need OCR before headings can be inferred.",
        "This version edits exported outline data; it does not write bookmarks or arbitrary PDF actions back into the source file."
      ],
      "faq": [
        {
          "q": "Are PDF bookmarks the same as a table of contents?",
          "a": "Bookmarks are the hierarchical links shown in a PDF reader's navigation pane. They often mirror a printed contents page, but the two can differ."
        },
        {
          "q": "What happens when the PDF has no bookmarks?",
          "a": "Automatic mode can propose an outline from unusually large text. Every inferred result is labeled and includes a review warning."
        },
        {
          "q": "Does this upload the document?",
          "a": "No. Bookmark and text-layer analysis happens locally in this browser tab."
        }
      ],
      "related": [
        "pdf-extract-text",
        "pdf-to-markdown",
        "pdf-split"
      ]
    }
  ]
}
