SLOPSHOPPER

bdt-status

Shows the current branch's PR and the issue it closes above the prompt, with the build state (uses `bdt pr info`)

newbandprocesstimer
★ 2v0.1.0no licenseupdated 2026-10-09bmsuisse/skills/mods/bdt-status
A shopper browsing a rack in a slop shop
README
 ██████╗ ███╗   ███╗███████╗    ███████╗██╗  ██╗██╗██╗     ██╗     ███████╗
 ██╔══██╗████╗ ████║██╔════╝    ██╔════╝██║ ██╔╝██║██║     ██║     ██╔════╝
 ██████╔╝██╔████╔██║███████╗    ███████╗█████╔╝ ██║██║     ██║     ███████╗
 ██╔══██╗██║╚██╔╝██║╚════██║    ╚════██║██╔═██╗ ██║██║     ██║     ╚════██║
 ██████╔╝██║ ╚═╝ ██║███████║    ███████║██║  ██╗██║███████╗███████╗███████║
 ╚═════╝ ╚═╝     ╚═╝╚══════╝    ╚══════╝╚═╝  ╚═╝╚═╝╚══════╝╚══════╝╚══════╝

Reusable AI agent skills for our engineering team — composable instructions that extend coding agents (Claude Code, Cursor, Codex CLI, etc.) with company-specific workflows and best practices.

Skills are a last resort. Anything that can be enforced deterministically — a lint rule, a formatter setting, a pre-commit hook, a CLI check — belongs in linters or tooling, not in a skill. Put it in bmsuisse/devtools (bdt lint, bdt pr, …) so it is checked automatically instead of relying on an agent to remember it. Write a skill only for judgment, conventions and context that tooling cannot express, and link to the matching devtools check where one exists.


Available Skills

<!-- SKILLS_TABLE_START -->

SkillDescription
aiochannel-pythonCorrect patterns for channel-based asyncio concurrency in Python using the aiochannel library. Use this skill wheneve…
autoresearchAutonomous iterative optimization loop for Python, SQL, ML, and Spark/Databricks. Define a measurable goal; the skill…
azure-costQuery, analyze, and reduce Azure spending via the Cost Management REST API and Azure CLI. Covers cost breakdowns by s…
bmsMaster skill for the bmsuisse platform — routes to the relevant skills based on sub-command. Always enables caveman c…
bms-code-reviewBMS code review that fans out one focused subagent per concern (architecture, duplication, security, correctness, age…
bms-frontend-designThe BMS visual identity for internal web apps, built on the shared @bmsuisse/ui (sidebar/nav, form, dialog, and oth…
bms-plan-reviewReview an implementation plan before any code is written: checks it against BMS conventions and the existing skills (…
clockifyQuery and log time entries in Clockify via its REST API — check a timesheet, look up the workspace/user/project, crea…
code-commentsWrite and review code comments so they earn their place instead of adding noise. Use this whenever writing new code (…
codeunit-analyzerComprehensive C-AL performance analyzer for Classic Microsoft Dynamics NAV (Navision). Targets Classic NAV anti-patte…
coding-guidelines-pythonApply and enforce Python-specific coding standards. Use alongside coding-guidelines for any Python file — covers typi…
coding-guidelines-sqlSQL and data warehouse coding guidelines for the BME data platform. Use whenever writing, reviewing, or refactoring S…
coding-guidelines-typescriptApply and enforce TypeScript-specific coding standards. Use alongside coding-guidelines for any TypeScript file — cov…
cross-repo-discoveryFind where a repo lives — locally or in the Azure DevOps org — before assuming a piece of functionality doesn't exist…
data-modeling-dimensionalDimensional data modeling guide for the Fabricks platform — covers the full pipeline from staging through raw, transf…
databricks-cliDatabricks CLI operations: auth, profiles, data exploration, bundles, and notebook execution. Use this skill for ANY…
databricks-sql-autotunerDatabricks SQL query optimizer and error fixer: analyzes a slow or broken SQL query, rewrites it for speed using SQL-…
design-reviewReview a web app or page for visual design quality — layout, spacing, typography, colour/contrast, visual hierarchy,…
deslopRemove AI slop from code and pull requests. Use this skill whenever the user wants to clean up AI-generated code, rev…
dev-workflowEnd-to-end workflow for non-trivial coding tasks: worktree, draft PR early, implement, review, test, publish. Trigger…
duckdbGuide for working with DuckDB — CLI usage, SQL execution, reading files (CSV, Parquet, JSON, Excel), extensions (http…
ducklakeGuide for working with DuckLake — the open lakehouse format and DuckDB extension that pairs a SQL catalog (metadata,…
fabricks-devops-issuesOrchestrates Azure DevOps "Issue" work-item workflows in the Fabricks.Runtime repo — listing open issues so the user…
fabricks-devops-issues-resolverEnd-to-end resolver for Fabricks.Runtime DevOps issues that have already been diagnosed and locally fixed by the fabr…
fabricks-glossaryUse this skill whenever company-specific jargon, acronyms, or domain terminology is needed to answer correctly.
fabricks-sql-analyzerAnalyzes all SQL files in the Fabricks.Runtime repository, builds a dependency DAG, runs performance heuristics, and…
fastapi-azure-authAzure Entra ID SSO for FastAPI using cookie-based sessions (MSAL, /login → /callback → session). Trigger on: Azure AD…
fastapi-guidelineUse this skill whenever working with FastAPI — building APIs, adding routes, structuring projects, streaming response…
init-app-stackUse this skill whenever the user wants to bootstrap, scaffold, or initialize a new full-stack app with a Vite + React…
inter-without-ai-slopUse Inter as a UI typeface in data-dense B2B apps (dashboards, tables, cockpits) without triggering the "generic AI d…
kendo-ui-angularUse this skill whenever the user is working with Kendo UI for Angular — including the Data Grid, TreeList, TreeView,…
kendo-ui-reactKendoReact component library patterns and best practices for React developers. Trigger whenever the user works with K…
kendo-ui-vueUse this skill whenever the user is working with Kendo UI for Vue — including the Data Grid, DropDownList, ComboBox,…
kull-generic-backendKull.GenericBackend — an ASP.NET Core middleware (Kull-AG/kull-generic-backend, NuGet package Kull.GenericBackend) th…
maintenancePeriodic repo upkeep for BMS Python (uv) and JS/TS (bun) repos, as one skill with a mode argument: dead-code (find/…
niceguiBuild Python web UIs with NiceGUI — covering layout, widgets, data binding, routing, and the AgGrid data grid. Use th…
playwright-pythonBrowser automation and visual verification with Playwright in Python. Use this whenever the user wants to drive a bro…
prekSet up code formatting and pre-commit hooks using prek (fast Rust-based alternative to pre-commit) with prek.toml con…
procrastinatePostgreSQL-based async task queue for Python using Procrastinate. Use this skill whenever the user is working with Pr…
python-autotunerPython code optimizer and error fixer: analyzes a Python file or function, rewrites it for speed and quality one chan…
remove-ai-writing"Detect and surgically fix AI writing patterns in English, German, French, or Italian text. Use this skill whenever t…
rich-data-tablesUse whenever building a UI table, list view, or dashboard panel showing records with amounts, dates, or statuses (inv…
scientific-revisionUse this skill whenever the user wants to verify, revise, or improve a scientific essay, academic paper, or any writt…
spark-connectGuide for running PySpark code locally against a remote Databricks cluster via Spark Connect (databricks-connect). Us…
sql-optimization"Universal SQL performance optimization assistant for comprehensive query tuning, indexing strategies, and database p…
tanstack-best-practicesComprehensive best practices for TanStack libraries in React applications — covering TanStack Query (React Query) dat…
testing-strategyDecide what kind of test to write and in what order for a backend feature: HTTP-level first, then Playwright e2e for…

<!-- SKILLS_TABLE_END -->


Installation

Claude Code Plugin

Add to ~/.claude/settings.json to install all plugins:

{
  "extraKnownMarketplaces": {
    "bmsuisse-skills": {
      "source": {
        "source": "github",
        "repo": "bmsuisse/skills"
      }
    }
  },
  "enabledPlugins": {
    "coding@bmsuisse-skills": true,
    "onetrade@bmsuisse-skills": true,
    "databricks@bmsuisse-skills": true,
    "fabricks-data@bmsuisse-skills": true,
    "writing@bmsuisse-skills": true,
    "ui@bmsuisse-skills": true,
    "caveman@bmsuisse-skills": true,
    "azure-deploy@bmsuisse-skills": true,
    "azure-diagnostics@bmsuisse-skills": true
  }
}
PluginContents
coding@bmsuisse-skillsPython, TypeScript, FastAPI, Postgres, TanStack, and general coding skills
ui@bmsuisse-skillsData tables, visual design/QA review, and writing style
onetrade@bmsuisse-skillsC-AL / Classic NAV codeunit analysis
databricks@bmsuisse-skillsDatabricks CLI + Spark Connect local execution
fabricks-data@bmsuisse-skillsFabricks / Databricks data skills
writing@bmsuisse-skillsScientific and academic writing revision
bms@bmsuisse-skillsBMsuisse master skill (/bms, /bms sql, /bms python, /bms data)
caveman@bmsuisse-skillsUltra-compressed caveman communication mode (~75% token reduction)
azure-deploy@bmsuisse-skillsAzure deployments via azd/terraform/az with validation and RBAC checks
azure-diagnostics@bmsuisse-skillsAzure production diagnostics via AppLens, Monitor, and resource health

Then run these commands in Claude Code to apply the configuration:

# Add the marketplace (one-time setup — alternative to editing settings.json manually)
/plugin marketplace add bmsuisse/skills

# Install the plugins you want (or install all of them, as below)
/plugin install coding@bmsuisse-skills
/plugin install ui@bmsuisse-skills
/plugin install onetrade@bmsuisse-skills
/plugin install databricks@bmsuisse-skills
/plugin install fabricks-data@bmsuisse-skills
/plugin install writing@bmsuisse-skills
/plugin install bms@bmsuisse-skills
/plugin install caveman@bmsuisse-skills
/plugin install azure-deploy@bmsuisse-skills
/plugin install azure-diagnostics@bmsuisse-skills

# After any config change, reload without restarting
/reload-plugins
CommandDescription
/pluginOpen the interactive plugin manager (browse, install, enable/disable)
/plugin install <name>@bmsuisse-skillsInstall a specific plugin
/plugin uninstall <name>@bmsuisse-skillsRemove a plugin
/plugin enable <name>@bmsuisse-skillsRe-enable a disabled plugin
/plugin disable <name>@bmsuisse-skillsDisable without uninstalling
/reload-pluginsReload all active plugins without restarting Claude Code

Using the Plugin

Once installed, skills are available as slash commands in Claude Code. Type / to see all available commands, or invoke them directly:

/coding-guidelines-python      # activate Python coding standards
/fastapi-guideline             # load FastAPI best practices
/init-app-stack                # scaffold a Vite+React+TanStack+shadcn / FastAPI+asyncpg app
/databricks-cli                # Databricks CLI operations
/autoresearch                  # start an autonomous research loop
/deslop                        # clean AI slop from code or PRs

Skills also auto-trigger based on context — if a skill's description matches what you're doing, Claude Code may load it automatically without a slash command.

Hooks (automatic tool remapping)

The plugin ships with PreToolUse hooks that automatically rewrite shell commands to use preferred tooling:

You typeGets remapped to
python script.pyuv run python script.py
python -m pytestuv run -m pytest
pip install foouv add foo
pytest, ruff, tyuv run pytest, uv run ruff, ...
npm installbun install
npm install foobun add foo
npx foobunx foo
yarn add foobun add foo
pnpm run devbun run dev

This happens transparently — no config needed. The hooks activate for any plugin that includes them (coding, bms, etc.).

Plugin contents

Each plugin bundles a curated set of skills:

PluginSkills includedUse case
codingautoresearch, coding-guidelines-python, coding-guidelines-typescript, deslop, fastapi-guideline, init-app-stack, postgres-best-practices, postgres-test-setup, sql-optimization, tanstack-best-practicesGeneral dev work
uirich-data-tables, inter-without-ai-slop, design-reviewData tables, writing style, visual QA
onetradecodeunit-analyzerClassic NAV / C-AL analysis
databricksdatabricks-cli, spark-connectDatabricks & Spark
fabricks-datafabricks-glossary, fabricks-sql-analyzerFabricks data platform
writingremove-ai-writing, scientific-revisionWriting & docs
bmsbms (master), coding-guidelines-sql, coding-guidelines-python, coding-guidelines-typescript, sql-optimization, data-modeling-dimensional, fabricks-glossaryAll BMSuisse standards via /bms
cavemancaveman, caveman-review, caveman-commit, caveman-help (from JuliusBrussee/caveman)Token-efficient communication
azure-deployazure-deploy (from microsoft/azure-skills)Azure deployments
azure-diagnosticsazure-diagnostics (from microsoft/azure-skills)Azure production diagnostics

Highly recommended: Caveman mode

We highly recommend Caveman by Julius Brussee. It cuts token usage ~75% by having the agent respond in ultra-compressed style while keeping full technical accuracy. Less noise, faster, cheaper.

bun x skills add https://github.com/JuliusBrussee/caveman

Or via the marketplace:

"caveman@bmsuisse-skills": true

Full credit to Julius for creating and maintaining this — outstanding contribution to the community.


skills CLI

The skills CLI reads directly from GitHub — no registration needed.

Install a specific skill

# recommended
bun x skills add https://github.com/bmsuisse/skills --skill <skill-name>
# alternative
npx skills add https://github.com/bmsuisse/skills --skill <skill-name>

Install all skills

# recommended
bun x skills add https://github.com/bmsuisse/skills
# alternative
npx skills add https://github.com/bmsuisse/skills

The CLI auto-detects your agent platform and installs into the right directory:

PlatformDirectory
Claude Code.claude/skills/
Cursor.cursor/rules/
Codex CLI~/.codex/skills/
Antigravity.agents/skills/ or .agent/skills/
Gemini CLIauto-detected

Browse on skills.sh

https://skills.sh/bmsuisse/skills/<skill-name>

Skills appear on the skills.sh leaderboard automatically based on install telemetry — no manual registration required.

Verify installation

Start a new session and ask your agent something that should trigger the skill.


BMS Master Skill

/bms is a master skill that activates the full bmsuisse coding context in one command. It routes to the relevant sub-skills based on a sub-command and always enables caveman communication style.

Sub-commands

CommandLoadsGood for
/bmscoding-guidelines-sql · coding-guidelines-python · coding-guidelines-typescript · fabricks-glossaryGeneral session — all core standards active
/bms sqlcoding-guidelines-sql · sql-optimization · fabricks-glossarySQL authoring, reviews, refactoring
/bms pythoncoding-guidelines-pythonPython development, PR reviews
/bms datadata-modeling-dimensional · fabricks-glossaryDesigning or reviewing fact/dim tables

For deep optimization work, chain with the specialized skills:

  • SQL benchmarking → /databricks-sql-autotuner
  • Python benchmarking → /python-autotuner

How it works

/bms sql
  │
  ├─ reads bms/SKILL.md          (master router, ~2.5k chars)
  │
  ├─ runs load_skills.py sql     (helper script)
  │     └─ concatenates:
  │           coding-guidelines-sql/SKILL.md
  │           sql-optimization/SKILL.md
  │           fabricks-glossary/SKILL.md
  │
  └─ applies all rules + caveman mode → "BMS SQL active."

The helper script at skills/bms/scripts/load_skills.py concatenates the relevant SKILL.md files and prints them as combined content. Each sub-skill remains the single source of truth — no duplication.

Install

Plugin (recommended) — installs bms + all sub-skills as a self-contained plugin:

claude plugin marketplace add bmsuisse/skills
claude plugin install bms@bmsuisse-skills

skills CLI — installs the bms skill only (sub-skills must already be installed):

bun x skills add https://github.com/bmsuisse/skills --skill bms  # recommended
npx  skills add https://github.com/bmsuisse/skills --skill bms  # alternative

Plugin path resolution

When installed as a plugin, load_skills.py resolves sub-skill paths via the CLAUDE_PLUGIN_ROOT environment variable that Claude Code injects at runtime. In the repo, it falls back to the repo-relative path. This means the script works correctly in both contexts without configuration.


Adding a Skill

Use skill-creator to guide you through the full lifecycle — drafting, test cases, evaluation, and iteration:

bun x skills add https://github.com/anthropics/skills --skill skill-creator  # recommended
# npx skills add https://github.com/anthropics/skills --skill skill-creator

Then ask your agent: "Help me create a skill for X" and it will walk you through intent capture, writing the SKILL.md, running test cases, reviewing results, and iterating until the skill is ready.

Also helpful is the playwright-cli skill, which you can install like this:

bun install -g @playwright/cli@latest
bunx playwright-cli install --skills

You can give a hint to the agent to use playwright cli to query complex web pages with javascript.

Structure

Each skill lives in its own directory under skills/:

skills/
└── your-skill-name/
    ├── SKILL.md          ← required: instructions + YAML frontmatter
    ├── scripts/          ← optional: helper scripts
    ├── references/       ← optional: reference documentation
    └── assets/           ← optional: templates, icons, etc.

SKILL.md format

---
name: your-skill-name
description: What the skill does and when to trigger it. Be specific — this is how the agent decides whether to use it.
---

# Your Skill

Instructions for the agent to follow...

Workflow

  1. Create a branch: git checkout -b skill/<skill-name>

2.

Source 1 files
hooks/register.js 116 lines
1// Shows "PR #69 ✓ · closes #68" (clickable links) in the band above the prompt, from `bdt pr info --json`.
2// Needs `bdt` on PATH; with no PR for the current branch (or no bdt) the band is left alone.
3
4const REFRESH_MS = 30_000;
5
6// Single-width symbols, not emoji, so the band lines up in every terminal
7const BUILD = {
8  passing: { symbol: "✓", color: "green" },
9  failing: { symbol: "✗", color: "red" },
10  pending: { symbol: "…", color: "yellow" },
11  waiting: { symbol: "⏸", color: "yellow" },
12};
13
14// The last `bdt pr info --json` result, or null when the branch has no PR
15let info = null;
16let isRefreshing = false;
17let timer = null;
18
19const LINK = /^https:\/\/(github\.com|dev\.azure\.com)\/[^\s\x00-\x1f]*$/;
20
21// `bdt` output only if it has the shape `bdt pr info --json` produces, so a shadowing or outdated `bdt` on PATH
22// can't make the band render an arbitrary link
23function validated(i) {
24  const isLink = (x) =>
25    typeof x.number === "number" &&
26    typeof x.url === "string" &&
27    LINK.test(x.url);
28  return isLink(i) && Array.isArray(i.issues) && i.issues.every(isLink)
29    ? i
30    : undefined;
31}
32
33// `undefined`: couldn't ask (bdt missing or timed out, unusable output) -- keep showing the last answer.
34// `null`: bdt answered that there is no PR for this branch.
35async function readInfo($) {
36  try {
37    const r = await $.process.run(["bdt", "pr", "info", "--json"]);
38    return r.exitCode === 0 ? validated(JSON.parse(r.stdout)) : null;
39  } catch {
40    return undefined;
41  }
42}
43
44async function refresh($) {
45  // A slow `gh` call must not stack up behind the timer
46  if (isRefreshing) return;
47  isRefreshing = true;
48  try {
49    const next = await readInfo($);
50    if (next !== undefined && JSON.stringify(next) !== JSON.stringify(info)) {
51      info = next;
52      $.ui.invalidate("ui.render");
53    }
54  } catch {
55    // a failed redraw must not become an unhandled rejection in a timer callback
56  } finally {
57    isRefreshing = false;
58  }
59}
60
61export function register(on) {
62  on("session.start", async ($, e, next) => {
63    // once per module load, not per session.start
64    timer ??= $.clock.every(REFRESH_MS, () => refresh($));
65    // Not awaited: the session starts right away, and the band fills in when bdt answers
66    refresh($);
67    return next(e);
68  });
69
70  // A turn is when the branch is most likely to have been pushed or a PR opened
71  on("turn.complete", async ($, e, next) => {
72    refresh($);
73    return next(e);
74  });
75
76  on("ui.render", { component: "AbovePrompt" }, async ($, e, next) => {
77    // Keep whatever Claude Code or other mods draw in the band
78    const theirs = await next(e);
79    if (!info) return theirs;
80
81    const { Box, Text, Link } = $.ui.resolve(e);
82    const build = BUILD[info.build];
83    const state = info.draft
84      ? "draft"
85      : info.state === "open"
86        ? ""
87        : info.state;
88
89    const line = Box({
90      flexDirection: "row",
91      columnGap: 1,
92      children: [
93        Link({ href: info.url, label: "PR #" + info.number }),
94        ...(build
95          ? [
96              Text({
97                color: build.color,
98                children: [build.symbol + " " + info.build],
99              }),
100            ]
101          : []),
102        ...(state ? [Text({ dimColor: true, children: [state] })] : []),
103        ...info.issues.flatMap((issue) => [
104          Text({ dimColor: true, children: ["· closes"] }),
105          Link({ href: issue.url, label: "#" + issue.number }),
106        ]),
107      ],
108    });
109
110    return Box({
111      flexDirection: "column",
112      children: theirs ? [line, theirs] : [line],
113    });
114  });
115}
116