agentsclimarketplace

Bau begleiter

Skill andy-builds-ai/claude-code-skills/bau-begleiter

A small collection of Claude Code skills for Python development.

Install
npx -y skills add andy-builds-ai/claude-code-skills --skill bau-begleiter

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

While actively writing code. Write block by block, one function one responsibility, check assumptions at the function's inputs.

SKILL.md

8.2 KB, as published. Nobody here has run it

bau-begleiter

When this skill triggers

When writing code that passes through the user's hands. Functions, small modules, scripts — whether for a learning chapter, a test script, or a production project. The skill triggers the moment code is being written, not before (architecture) and not after (limit review).

Not active during system design. Not active on finished code.

One function, one responsibility

Every function does exactly one thing. No function that "fetches data AND validates AND stores AND reports". If the word "and" shows up in the function's description, the function is too big.

What this means while writing: before a function exists, you must be able to say what it does in one sentence. No list, no conjunction. One sentence with one verb.

Examples that fit:

  • get_node_status() — asks for the node status
  • validate_response(data) — checks whether the response is plausible
  • format_alert(level, message) — builds an alert text

Examples that don't fit:

  • check_and_alert() — two responsibilities, "and" in the name
  • process_data() — no concrete verb, collects things that get unclear later
  • do_everything() — wrong in an obvious way

When you notice while writing that the function splits into two jobs, that's the signal to cut. Don't keep building, split it.

Block-by-block mechanics

Code grows in readable units, not in blocks the user didn't build up themselves. A unit is one function plus a call with a concrete value. First write the function, then right away a call that runs it with real data. Only when the call returns the expected result does the next function follow.

Concretely:

  1. Define one function — signature, docstring, implementation
  2. Call it in the console or an if __name__ == "__main__" block with a concrete value
  3. Look at the output, compare it with what you expected
  4. Only then the next function

What "call" means here: no pytest, no unittest, no test framework. Just run the function with a real value and see what comes out. For a function validate_response(data) that means: call it once with a valid dict, once with an empty dict, once with None. Three console calls, thirty seconds, done.

What doesn't happen here: generate 200 lines in one go and run it at the end. If something is wrong at the end, it's not clear where. If every function was called on its own, then with a bug you know which block was just added.

This way is slower in the first half hour and faster over the whole session. Typos show up right away, logic errors in a small function are found in 30 seconds.

Check assumptions before code (function level)

Before a function is written, a quick check: what does this function assume about its inputs? Three questions, every time:

What if the input is missing? None, empty string, empty list. Does the function raise an error, or does it quietly return a wrong value? An explicit if value is None: raise ValueError(...) at the top is usually better than hidden behavior further down.

What if the input is an edge value? Zero, a negative number, a very large value, an empty collection. Does the logic still hold there? For numeric functions it's worth a quick thought about whether 0, -1, and a very large value produce sensible answers.

What if the input has an unexpected type? A string where a number is expected, a list where a dict is expected. Python often throws a confusing error deep inside the function here. A short type check at the top makes the error readable.

These questions are at the function level, not the system level. It's not about whether the external API goes down or the network drops — that belongs in the architecture. It's about whether this one function handles the input it gets cleanly.

In practice the check takes 30 seconds per function. It doesn't replace the call with a concrete value, it steers the writing.

Gotchas

The function grows while you write it. You start with "it just fetches the status", and by the end it fetches the status, formats it, and writes it to the log. This happens because one thought leads to the next while writing. What happens: the function gets unclear, the name no longer matches the implementation, calls get hard. How to avoid: when a second job shows up while writing, make a second function right away — even if it's only three lines.

The call gets skipped because "it's obvious". A small function looks so simple that the console call to verify it seems pointless. What happens: a typo in a variable, a swapped argument, a wrong bracket stays hidden until a confusing error shows up five functions later. How to avoid: call every function at least once with a concrete value before the next one exists. Even if the call is just one line in the console.

The assumption check turns into a defensive wall. "I check whether the input is None" becomes "I check everything, always, everywhere". What happens: the code gets unreadable, every function starts with ten lines of validation, the actual logic disappears. How to avoid: the three questions are a filter for thinking, not mandatory boilerplate. Not every function needs all three checks spelled out in code — some are already covered by the caller.

Copy-paste instead of typing it out. A similar function already exists and gets copied. What happens: variable names from the source function stay in, the logic isn't thought through because "it already runs". Three versions later nobody knows why three nearly identical functions exist. How to avoid: type similar functions out instead of copying them. While typing it out you notice what has to be different. When three nearly identical functions appear, that's the signal for a shared helper function.

"Get it running first, clean up later." Code gets written quick-and-dirty with the intent to clean up later. What happens: later is never. The code runs, the cleanup never gets prioritized, the next person builds on the messy state. How to avoid: cleanup is part of building, not a later step. If something is messy, fix it now. If there's no time for now, it doesn't belong in this build session.

Example run

The user writes a function that makes a Bitcoin RPC call and checks the result.

First version the user sketches:

def check_node():
    response = rpc_call("getblockchaininfo")
    if response["blocks"] < 800000:
        send_alert("Node is falling behind")
    return response

The skill triggers with three observations:

1. One function, one responsibility. check_node does three things: RPC call, comparison, alert. The name fits none of the three. Cut:

def get_blockchain_info():
    return rpc_call("getblockchaininfo")

def is_node_behind(info, threshold=800000):
    return info["blocks"] < threshold

def check_node():
    info = get_blockchain_info()
    if is_node_behind(info):
        send_alert("Node is falling behind")
    return info

2. Check assumptions. What if info is None (RPC error)? What if info["blocks"] is missing (old Bitcoin Core version)? Both cases currently lead to a KeyError deep inside is_node_behind. An explicit check at the top makes the error readable:

def is_node_behind(info, threshold=800000):
    if info is None:
        raise ValueError("info is None — RPC call failed?")
    if "blocks" not in info:
        raise KeyError("info has no 'blocks' key")
    return info["blocks"] < threshold

3. Block by block. First write get_blockchain_info() and call it in the console:

>>> get_blockchain_info()
{'chain': 'main', 'blocks': 875432, ...}

Output looks right, move on. Then call is_node_behind() with three concrete values:

>>> is_node_behind({'blocks': 875432})
False
>>> is_node_behind({'blocks': 700000})
True
>>> is_node_behind(None)
ValueError: info is None — RPC call failed?

Three calls, three expected results. Only then write check_node() as the composition and call it once.

End result: three small functions, each verified on its own in the console, each with one clear job. When extending later, each can be replaced on its own.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.