Manage the user's global Claude config in the Module
Bring the declarative half of ~/.claude into modules/claude-code and apply
it when the Module is enabled: the global agent instructions (context =
./CLAUDE.md), the skills tree (skills = ./skills), the attention-bell hook,
and settings.json (model = opus plus the Stop/Notification/SessionStart
hook wiring).
Runtime state (projects, plugins, cache, history, sessions) and the
.credentials.json secret are left out, so login survives rebuilds and no
secret enters the repo. Verified against the built home-files that
~/.claude/{CLAUDE.md,settings.json,skills,hooks/attention-bell.sh} are
generated, the hook executable.
This commit is contained in:
152
modules/claude-code/skills/library/nbdev/SKILL.md
Normal file
152
modules/claude-code/skills/library/nbdev/SKILL.md
Normal file
@@ -0,0 +1,152 @@
|
||||
---
|
||||
name: nbdev
|
||||
description: nbdev conventions for notebooks — directives, cell structure, docments, tests, execution. Use for any .ipynb operation — including reads — in an nbdev project.
|
||||
---
|
||||
|
||||
# nbdev
|
||||
|
||||
## Tool Preference
|
||||
|
||||
- Use the **Jupyter MCP** for all `.ipynb` operations — read, edit, insert, delete, execute
|
||||
- Do **not** use the built-in `NotebookEdit` tool; it writes cell source as a single JSON string which breaks standard Jupyter formatting and produces noisy diffs
|
||||
- Re-read the notebook before editing if it may have changed since your last read — cell indices/IDs can shift under concurrent edits (e.g. via JupyterLab's real-time collaboration), and editing by a stale index can hit the wrong cell
|
||||
|
||||
## nbdev Directives
|
||||
|
||||
Directives are comments at the top of a cell that control how nbdev processes it:
|
||||
|
||||
- `#| export` — include this cell in the exported Python module and in the docs
|
||||
- `#| hide` — exclude this cell from both the module and the docs
|
||||
- `#| hide_input` — show cell output in docs but hide the source code
|
||||
- `#| default_exp module_name` — set which module this notebook exports to (second cell)
|
||||
- `#| exporti` — export to module but do not show in docs (for internal helpers)
|
||||
- `#| eval: false` — include in docs but do not execute during `nbdev-test`
|
||||
|
||||
Imports needed only for tests or examples should **not** be exported.
|
||||
|
||||
Never hand-edit the exported `.py` module files — they're build artifacts regenerated from the notebook by `nbdev_export`. All edits go through the source notebook in `nbs/`.
|
||||
|
||||
## Notebook Structure
|
||||
|
||||
Every notebook must follow this structure:
|
||||
|
||||
**Cell 1 — Markdown frontmatter:**
|
||||
```markdown
|
||||
# Module Title
|
||||
|
||||
> A one-line description of what this module does
|
||||
```
|
||||
The H1 becomes the page title in docs. The blockquote becomes the subtitle.
|
||||
|
||||
**Cell 2 — Default export:**
|
||||
```python
|
||||
#| default_exp module_name
|
||||
```
|
||||
|
||||
**Body cells** — alternating between exported code, demonstrations, and markdown explanations (see Cell Structure below).
|
||||
|
||||
**Last cell:**
|
||||
```python
|
||||
#| hide
|
||||
import nbdev; nbdev.nbdev_export()
|
||||
```
|
||||
|
||||
Before declaring any notebook task complete, restart the kernel and run all cells top-to-bottom to verify it is fully reproducible.
|
||||
|
||||
## Cell Structure
|
||||
|
||||
Keep cells short. Each exported function gets its own cell, immediately followed by a demonstration. Do not write long functions with comments interspersed — split them into small separate cells with explanations and working examples after each.
|
||||
|
||||
The pattern per concept:
|
||||
|
||||
1. *(Optional)* A markdown cell explaining what comes next
|
||||
2. A `#| export` code cell with the function
|
||||
3. One or more plain code cells demonstrating usage
|
||||
4. Assertions that double as tests
|
||||
|
||||
Example:
|
||||
```python
|
||||
#| export
|
||||
def slugify(text: str) -> str:
|
||||
"Convert text to a URL-safe slug"
|
||||
return re.sub(r"[^a-z0-9]+", "-", text.lower()).strip("-")
|
||||
```
|
||||
```python
|
||||
slug = slugify("Hello, World!")
|
||||
assert slug == "hello-world"
|
||||
slug
|
||||
```
|
||||
|
||||
## Docstrings and Parameter Documentation
|
||||
|
||||
Keep docstrings short — a single-line summary is sufficient for most functions. Elaborate in separate markdown or code cells below, where you can use real examples.
|
||||
|
||||
Use **docments** (inline parameter comments) instead of verbose docstring parameter sections:
|
||||
|
||||
```python
|
||||
#| export
|
||||
def greet(
|
||||
name: str, # Person to greet
|
||||
greeting: str="Hi", # Greeting word to use
|
||||
) -> str: # The composed greeting
|
||||
"Compose a greeting for name"
|
||||
return f"{greeting}, {name}!"
|
||||
```
|
||||
|
||||
This renders as a clean parameter table in the docs automatically — no need to repeat type information in the docstring body.
|
||||
|
||||
Use backticks around symbol names in docstrings and markdown — nbdev automatically converts these to hyperlinks to the relevant reference page.
|
||||
|
||||
## Code Style
|
||||
|
||||
- **Prefer composition**: write small functions that do one thing well
|
||||
- Each exported function should be focused enough to fit naturally in a single notebook cell — one cell, one idea
|
||||
- Use type hints on all exported functions
|
||||
- Avoid classes unless state is genuinely needed — prefer functions that take and return data
|
||||
- If you do write a class, use `fastcore`'s `@patch` decorator to define each method in its own cell, immediately followed by a demonstration. This avoids long class definitions and keeps examples close to the code
|
||||
|
||||
When a class is needed, document its methods with `show_doc`:
|
||||
```python
|
||||
from nbdev.showdoc import show_doc
|
||||
show_doc(MyClass.my_method)
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
Every code cell is run as a test by nbdev unless explicitly marked otherwise — any exception fails the test.
|
||||
|
||||
- Turn demonstrations into tests by adding `assert` statements
|
||||
- Use `fastcore.test` helpers for better error messages:
|
||||
```python
|
||||
from fastcore.test import test_eq, test_fail
|
||||
test_eq(slugify("Hello World"), "hello-world")
|
||||
```
|
||||
- Document expected error cases with `test_fail`:
|
||||
```python
|
||||
test_fail(lambda: slugify(""), contains="empty")
|
||||
```
|
||||
- Each test/demo cell should import what it needs directly — don't rely on a name imported in a later cell just because it happened to be in scope during a prior run
|
||||
|
||||
## Execution
|
||||
|
||||
- Always execute cells after writing them to verify they work
|
||||
- If a cell errors, read the full traceback before attempting a fix — do not guess
|
||||
- When installing packages, use `%pip install` inside the notebook (not `!pip install`) so they install into the running kernel
|
||||
- Use autoreload at the top of notebooks that import from other modules in the project:
|
||||
```python
|
||||
%load_ext autoreload
|
||||
%autoreload 2
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- Use H2 (`##`) markdown cells to group related symbols within a notebook
|
||||
- Use H4 (`####`) markdown cells to split long explanations within a symbol's section (notes, examples, edge cases, etc.)
|
||||
- Add rich representations to classes via `_repr_markdown_` where it aids understanding
|
||||
- Include real code examples, plots, and diagrams — notebooks support rich output, use it
|
||||
|
||||
## Outputs
|
||||
|
||||
- Never print secrets, tokens, passwords, or API keys into cell output — notebook outputs get committed to git and published in docs, unlike transient script output
|
||||
- Prefer summaries over dumping large data structures (`.head()`, `len()`, `[:5]`, etc.)
|
||||
- Large outputs consume context window — keep them concise
|
||||
Reference in New Issue
Block a user