{
  "markdown": "<p align=\"center\">\n  <img src=\"https://img.shields.io/badge/Claude_Code-Plugin-blueviolet?style=for-the-badge\" alt=\"Claude Code Plugin\" />\n  <img src=\"https://img.shields.io/badge/Preset-Dashboard_Toolkit-orange?style=for-the-badge\" alt=\"Preset Dashboard Toolkit\" />\n  <img src=\"https://img.shields.io/badge/version-0.11.0-green?style=for-the-badge\" alt=\"Version 0.11.0\" />\n  <img src=\"https://img.shields.io/badge/tests-391_passing-brightgreen?style=for-the-badge\" alt=\"391 Tests Passing\" />\n  <img src=\"https://img.shields.io/badge/license-BUSL_1.1-blue?style=for-the-badge\" alt=\"License\" />\n</p>\n\n# preset-toolkit\n\n**Stop breaking dashboards.** A Claude Code plugin that makes Preset/Superset dashboard management safe, collaborative, and mistake-proof.\n\nOne command — `/preset-toolkit:preset` — gives your team pull, push, validation, screenshots, visual regression, and ownership guardrails. No more pushing stale data, overwriting someone's work, or losing CSS.\n\n---\n\n## Install\n\n```bash\n# From the Claude Code official marketplace\n/plugin install preset-toolkit\n\n# Or install directly from GitHub\n/plugin install github:rishav1305/preset-toolkit\n```\n\n**Prerequisites:** Python 3.8+ and [Claude Code](https://claude.ai/code) with plugin support.\n\n---\n\n## How It Works\n\n```\nYou say:                              preset-toolkit does:\n───────────────────────────────────── ──────────────────────────────────────\n/preset-toolkit:preset pull           Pull → Dedup → Fingerprint check\n/preset-toolkit:preset push           Validate → Markers → Push → CSS → Verify\n/preset-toolkit:preset screenshot     Launch browser → Capture → Save PNGs\n/preset-toolkit:preset diff           Compare screenshots → Flag regressions\n/preset-toolkit:preset \"push my       NLP routing → Same safe workflow\n  revenue edits\"\n```\n\n### The Safety Net\n\n```mermaid\ngraph LR\n    U[\"User: /preset push\"] --> R[\"Router Skill\"]\n    R --> V[\"Validate\"]\n    V --> FP[\"Fingerprint Check\"]\n    FP -->|stale| W[\"Warn & Abort\"]\n    FP -->|fresh| P1[\"CLI Push (data)\"]\n    P1 --> P2[\"REST Push (CSS/position)\"]\n    P2 --> VR[\"Visual Regression\"]\n    VR -->|regression| DIFF[\"Show Diff\"]\n    VR -->|clean| OK[\"Done\"]\n    \n    style R fill:#6366f1,color:#fff\n    style V fill:#f59e0b,color:#000\n    style FP fill:#f59e0b,color:#000\n    style W fill:#ef4444,color:#fff\n    style OK fill:#22c55e,color:#fff\n```\n\n```\n                    ┌─────────────────────────────────────────┐\n                    │         /preset-toolkit:preset push      │\n                    └────────────────┬────────────────────────┘\n                                     │\n                    ┌────────────────▼────────────────────────┐\n                    │  1. Validate (sup sync --dry-run)        │\n                    │  2. Check markers in SQL                 │\n                    │  3. Fingerprint check (stale data?)      │\n                    │  4. Ownership warnings                   │\n                    └────────────────┬────────────────────────┘\n                                     │ All clear?\n                          ┌──────────┴──────────┐\n                          │                     │\n                    ┌─────▼──────┐       ┌──────▼─────┐\n                    │ sup sync   │       │  REST API  │\n                    │ (charts +  │       │  (CSS +    │\n                    │  datasets) │       │  position) │\n                    └─────┬──────┘       └──────┬─────┘\n                          │                     │\n                    ┌─────▼─────────────────────▼─────┐\n                    │  5. Post-push verify              │\n                    │     (pull-back + marker recheck)  │\n                    └──────────────────────────────────┘\n```\n\n> **Why two-stage push?** `sup sync` overwrites dashboard CSS. preset-toolkit pushes charts/datasets via CLI, then CSS/position via REST API separately — so your styles are never lost.\n\n---\n\n## Quick Start\n\n```bash\n# 1. Install the plugin\n/plugin install preset-toolkit\n\n# 2. Create a project folder and set up\nmkdir my-dashboard && cd my-dashboard\n/preset-toolkit:preset-setup\n\n# 3. Pull, edit, push\n/preset-toolkit:preset pull\n# ... make your changes ...\n/preset-toolkit:preset push\n```\n\nSetup handles everything: virtual environment, dependencies (`superset-sup`, Playwright + Chromium), auth configuration, and `sync_config.yml` creation.\n\n---\n\n## Features\n\n| Feature | What it does |\n|---------|-------------|\n| **Smart routing** | `/preset-toolkit:preset` + anything — natural language or direct commands |\n| **Content fingerprinting** | Per-file SHA-256 map detects stale pulls before you push |\n| **Marker validation** | Required strings must exist in SQL — catches accidental deletions |\n| **Visual regression** | Pixel-diff screenshots catch layout changes invisible in code |\n| **Section ownership** | Advisory warnings when you touch someone else's tiles |\n| **Deduplication** | Auto-removes duplicate chart/dataset YAMLs by UUID |\n| **Safe YAML** | Never uses `yaml.dump()` — string replacement preserves formatting |\n| **Post-push verify** | Automatic pull-back and recheck after every push |\n| **Zero-login screenshots** | Auto-extracts cookies from Chrome/Firefox/Edge/Arc — falls back to interactive login |\n\n---\n\n## Skills (21)\n\n| # | Skill | Invoke with | Purpose |\n|---|-------|-------------|---------|\n| 1 | Router | `/preset-toolkit:preset` | Interactive menu + NLP routing |\n| 2 | Setup | `/preset-toolkit:preset-setup` | First-time project wizard |\n| 3 | Pull | `/preset-toolkit:preset-sync-pull` | Pull + dedup + fingerprint |\n| 4 | Push | `/preset-toolkit:preset-sync-push` | Validate + push + CSS + verify |\n| 5 | Validate | `/preset-toolkit:preset-validate` | Health check (markers + dry-run) |\n| 6 | Screenshot | `/preset-toolkit:preset-screenshot` | Capture dashboard screenshots |\n| 7 | Visual Diff | `/preset-toolkit:preset-visual-regression` | Pixel-level regression comparison |\n| 8 | Code Review | `/preset-toolkit:preset-code-review` | Change review checklist |\n| 9 | Ownership | `/preset-toolkit:preset-ownership` | Section ownership warnings |\n| 10 | Troubleshoot | `/preset-toolkit:preset-troubleshoot` | Decision tree for common issues |\n| 11 | Checkpoint | `/preset-toolkit:preset-checkpoint` | Daily pull + validate + screenshot + diff |\n| 12 | Brainstorm | `/preset-toolkit:preset-brainstorming` | Plan dashboard changes conversationally |\n| 13 | Write Plans | `/preset-toolkit:preset-writing-plans` | Break changes into safe execution steps |\n| 14 | Execute Plans | `/preset-toolkit:preset-executing-plans` | Execute plans with validation checkpoints |\n| 15 | Testing | `/preset-toolkit:preset-testing` | TDD loop: change → validate → push → verify |\n| 16 | Debugging | `/preset-toolkit:preset-debugging` | Systematic debugging with known failure modes |\n| 17 | Chart Ops | `/preset-toolkit:preset-chart` | List, inspect, query, pull, push charts |\n| 18 | Dataset Ops | `/preset-toolkit:preset-dataset` | List, inspect, query, pull, push datasets |\n| 19 | SQL Execution | `/preset-toolkit:preset-sql` | Execute SQL queries against Preset databases |\n| 20 | Dashboard Ops | `/preset-toolkit:preset-dashboard` | List, inspect, and pull dashboards |\n| 21 | Jinja Validation | `/preset-toolkit:preset-jinja` | Validate Jinja2 syntax in SQL fields |\n\nOr just describe what you want:\n\n```\n/preset-toolkit:preset I want to push my revenue changes\n/preset-toolkit:preset what's the current state of the dashboard?\n/preset-toolkit:preset something looks wrong with the tiles\n```\n\n---\n\n## Visual Regression\n\nCatch what code review can't — visual changes to your dashboard layout.\n\n```\n  Baseline (last push)          Current (after changes)         Diff (auto-generated)\n┌──────────────────────┐    ┌──────────────────────┐    ┌──────────────────────┐\n│  ┌──────┐ ┌──────┐   │    │  ┌──────┐ ┌──────┐   │    │  ┌──────┐ ┌──────┐   │\n│  │ Rev  │ │ DAU  │   │    │  │ Rev  │ │ DAU  │   │    │  │      │ │      │   │\n│  └──────┘ └──────┘   │    │  └──────┘ └──────┘   │    │  └──────┘ └──────┘   │\n│  ┌────────────────┐   │    │  ┌─────┐ ┌────────┐  │    │  ┌─────┐ ┌────────┐  │\n│  │    Chart A     │   │    │  │  A  │ │   B    │  │    │  │█████│ │████████│  │\n│  └────────────────┘   │    │  └─────┘ └────────┘  │    │  └─────┘ └────────┘  │\n└──────────────────────┘    └──────────────────────┘    └──────────────────────┘\n                                                          █ = changed pixels\n```\n\n```bash\n/preset-toolkit:preset screenshot   # Capture baselines\n# ... make changes ...\n/preset-toolkit:preset diff         # Compare — flags >1% pixel difference\n```\n\nUses Pillow for pixel comparison with configurable color tolerance for anti-aliasing.\n\n---\n\n## Section Ownership\n\nDefine who owns what. Get warnings — never blocks.\n\n```yaml\n# .preset-toolkit/ownership.yaml\nsections:\n  revenue:\n    owner: \"alice@company.com\"\n    charts: [2085, 2088]\n  audience:\n    owner: \"bob@company.com\"\n    charts: [2084]\nshared_datasets:\n  - name: \"Main_Dataset\"\n    owners: [\"alice@company.com\", \"bob@company.com\"]\n    advisory: \"Notify all owners before editing.\"\n```\n\n```\n  Chart 2085 belongs to 'revenue' (owned by alice@company.com).\n  Notify them before pushing.\n```\n\n---\n\n## Auth\n\nThe plugin uses two CLIs with separate auth:\n\n**sup CLI** (for all sync operations — pull/push/validate/CSS):\n```bash\n# Interactive setup — stores credentials locally\n.venv/bin/sup config\n```\n\n**Environment variables** (for REST API CSS push):\n```bash\nexport PRESET_API_TOKEN=\"your-token\"\nexport PRESET_API_SECRET=\"your-secret\"\n```\n\nGet API keys from **Preset > Settings > API Keys**.\n\n> HTTPS is enforced — the toolkit refuses to send credentials over plaintext HTTP.\n\n---\n\n## Configuration\n\nCreated by `/preset-toolkit:preset-setup` at `.preset-toolkit/config.yaml`:\n\n```yaml\nversion: 1\n\nworkspace:\n  url: \"https://your-workspace.us2a.app.preset.io\"\n  id: \"your-workspace-id\"\n\ndashboard:\n  id: 76\n  name: \"My Dashboard\"\n\nsync:\n  folder: \"sync\"\n\nscreenshots:\n  folder: \"screenshots\"\n  navigation_timeout: 60\n\nvalidation:\n  markers_file: \".preset-toolkit/markers.txt\"\n\ncss:\n  max_length: 30000        # Preset truncates at ~33K\n  push_via_api: true\n```\n\nSetup also creates `sync/sync_config.yml` (required by the `sup` CLI):\n\n```yaml\nsource:\n  workspace_id: 2194154     # Numeric workspace ID\n  assets:\n    dashboards:\n      selection: ids\n      ids: [76]\n      include_dependencies: true\ntarget_defaults:\n  overwrite: true\ntargets:\n- workspace_id: 2194154\n  name: my_dashboard\n```\n\n<details>\n<summary><strong>Telemetry (optional)</strong></summary>\n\nAnonymous, opt-in usage telemetry via PostHog. Inert unless configured:\n\n```bash\nexport POSTHOG_API_KEY=\"your-posthog-project-key\"\n```\n\nAlso requires `telemetry.enabled: true` in config. No data is ever sent without both conditions met.\n\n</details>\n\n---\n\n## Architecture\n\n```\npreset-toolkit/\n├── .claude-plugin/           Plugin metadata (plugin.json, marketplace.json)\n├── hooks/                    Session auto-detection\n├── skills/                   21 skills (each with SKILL.md)\n│   ├── preset/               Router — single entry point\n│   ├── preset-setup/         First-time wizard\n│   ├── preset-sync-pull/     Pull + dedup + fingerprint\n│   ├── preset-sync-push/     Validate + push + CSS + verify\n│   ├── preset-validate/      Health checks\n│   ├── preset-screenshot/    Playwright browser capture\n│   ├── preset-visual-regression/  Pixel-diff comparison\n│   ├── preset-chart/         Individual chart operations\n│   ├── preset-dataset/       Individual dataset operations\n│   ├── preset-sql/           SQL query execution\n│   ├── preset-dashboard/     Individual dashboard operations\n│   ├── preset-jinja/         Jinja2 syntax validation\n│   ├── preset-code-review/   Change review checklist\n│   ├── preset-ownership/     Section ownership warnings\n│   ├── preset-troubleshoot/  Diagnostic decision tree\n│   ├── preset-checkpoint/    Daily pull + validate + screenshot\n│   ├── preset-brainstorming/ Change planning\n│   ├── preset-writing-plans/ Execution step breakdown\n│   ├── preset-executing-plans/  Plan execution with checkpoints\n│   ├── preset-testing/       TDD loop\n│   └── preset-debugging/     Systematic debugging\n├── agents/                   Visual diff + conflict check agents\n├── references/               Preset knowledge base (7 docs)\n├── scripts/                  Python automation (18 modules)\n│   ├── sync.py               Pull/push orchestrator (uses sup CLI)\n│   ├── chart.py              Chart operations (list/info/sql/data/pull/push)\n│   ├── dataset.py            Dataset operations (list/info/sql/data/pull/push)\n│   ├── sql.py                SQL execution (execute_sql + database ID resolution)\n│   ├── dashboard.py          Dashboard operations (list/info/pull)\n│   ├── jinja_check.py        Jinja2 syntax validation + expression extraction\n│   ├── push_dashboard.py     REST API push (CSS/position)\n│   ├── screenshot.py         Playwright browser capture + auth fallback\n│   ├── browser_cookies.py    Cookie extraction from Chrome/Firefox/Edge/Arc\n│   ├── visual_diff.py        Pixel comparison (Pillow)\n│   ├── fingerprint.py        Per-file SHA-256 content hashing\n│   ├── dedup.py              UUID duplicate removal\n│   ├── ownership.py          Section ownership checks\n│   ├── config.py             Config reader + validation\n│   ├── http.py               Retry with exponential backoff + jitter\n│   ├── deps.py               Dependency management\n│   ├── telemetry.py          Anonymous opt-in telemetry\n│   ├── logger.py             Structured logging + secret sanitization\n│   └── bootstrap.sh          Venv + dependency installer\n├── templates/                Project scaffolding files\n└── tests/                    391 tests (unit + integration + E2E)\n```\n\n### Dependencies\n\nInstalled automatically by setup into a project-local `.venv/`:\n\n| Package | Purpose |\n|---------|---------|\n| `superset-sup` | `sup` CLI — sync pull/push/validate |\n| `playwright` + Chromium | Browser-based screenshot capture |\n| `PyYAML` | YAML parsing |\n| `Pillow` | Image comparison for visual regression |\n| `httpx` | HTTP client with retry support |\n| `cryptography` | AES decryption for Chromium cookie extraction |\n\n---\n\n## For Contributors\n\n### Running tests\n\n```bash\npip install -e \".[dev]\"\npytest tests/ -v\n```\n\nAll 391 tests pass in ~4 seconds.\n\n### Design Principles\n\n- **Never `yaml.dump()`** — string replacement preserves YAML formatting\n- **Two-stage push** — CLI for data, REST API for presentation\n- **Advisory ownership** — warns, never blocks\n- **Business questions only** — skills never ask technical/infra questions\n- **Fail safe** — every external call has retries, timeouts, and error handling\n- **No auto-install outside setup** — pull/push/screenshot fail fast if deps are missing\n\n### Adding a skill\n\n1. Create `skills/your-skill/SKILL.md` with `name` and `description` frontmatter\n2. Follow the Conversation Principles (never ask technical questions)\n3. Add routing logic to `skills/preset/SKILL.md`\n4. Reference relevant `references/*.md` docs\n\n---\n\n## Related Projects\n\n| Project | Relationship | Link |\n|---------|-------------|------|\n| **soul** | AI platform that hosts preset-toolkit as a product server | [github.com/rishav1305/soul](https://github.com/rishav1305/soul) |\n| **dbt-toolkit** | Sister plugin for dbt workflows (same architecture pattern) | [github.com/rishav1305/dbt-toolkit](https://github.com/rishav1305/dbt-toolkit) |\n| **soul-team** | Multi-agent runtime that uses preset-toolkit for dashboard ops | [github.com/rishav1305/soul-team](https://github.com/rishav1305/soul-team) |\n| **soul-bench** | CARS benchmark — LLM evaluation framework | [github.com/rishav1305/soul-bench](https://github.com/rishav1305/soul-bench) |\n| **SoulGraph** | Multi-agent RAG framework (LangGraph + ChromaDB) | [github.com/rishav1305/soulgraph](https://github.com/rishav1305/soulgraph) |\n\n## Author\n\n**Rishav Chatterjee** — Senior AI Architect\n\n- Portfolio: [rishavchatterjee.com](https://rishavchatterjee.com)\n- GitHub: [github.com/rishav1305](https://github.com/rishav1305)\n- LinkedIn: [linkedin.com/in/rishavchatterjee](https://linkedin.com/in/rishavchatterjee)\n\n---\n\n## License\n\nBusiness Source License 1.1 — see [LICENSE](LICENSE) for details.\nConverts to Apache License 2.0 on 2030-03-13.\n",
  "bytes": 16333,
  "sha": "1bd03911cbeb10d006a886ff3ee99f35866bed7dcc11b7317633fcf3870a1187",
  "repo_slug": "rishav1305/preset-toolkit",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_rishav1305_preset_toolkit_preset_toolkit_3cd71dc0/readme"
}