

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Reading and inspection

Readable notebook views plus implementation-oriented context for
co-creation.

The public read API is the unified `context(target, scope=".")`. It
covers repository orientation, one notebook, one chapter, one cell id,
or one concrete implementation without exposing raw notebook JSON. Its
filters choose the useful slice: summary, full source, chapter, cell
type, query, regular expressions, and nearby context lines.

Notebook chapters use a code-first rhythm: exported code, trailing
Markdown explanation, example cells, focused test cells, then the next
exported code. The reader preserves that source order and associates a
symbol with the cells that follow it.

Reading is the first problem to solve for notebook automation. An agent
should not have to inspect raw `.ipynb` JSON just to learn what a
project, notebook, chapter, or implementation contains, and a human
reviewer should not have to scroll through outputs and metadata to find
the code.

This notebook builds compact context views for four common questions:
what project is this, what is in this file, what belongs to this
chapter, and what should I know before changing this symbol.

For a chapter, read the story in this order:

    ## Chapter
    - exported code
    - trailing explanation
    - example(s)
    - test(s)
    - exported code
    - trailing explanation
    - example(s)
    - test(s)
    - ...

Symbol readers use the same rhythm: implementation first, then trailing
Docs, then the following example and test cells. They stop the local
group at the next exported code cell so one symbol’s explanation does
not leak into the next one.

The reader is intentionally a triage tool before it is a renderer. Start
with `context(target, scope=".")`; use `target="project"`, a notebook
path/name, a chapter title, a cell id, or a Python symbol.

``` python
context("project", scope="nbs")
context("nbs/02_write.ipynb")
context("write_nb", scope="nbs/02_write.ipynb")
```

## Reader API

Start with the unified
[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context)
reader. Select the target and add only the filters needed for the
agent’s next action.

#### Production contract

The unified
[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context)
reader is the production entry point. It preserves stable notebook paths
and cell ids, supports compact summaries and full source, and narrows
the same result by chapter, cell type, query, or regular expressions.
Lower-level helpers are implementation details, not additional
agent-facing read surfaces.

``` python
with write_demo_notebook("01_read_example.ipynb") as path:
    write_nb(new_nb([
        mk_cell("# Reader\nFile preamble.", cell_type="markdown"),
        mk_cell("preamble = True", cell_type="code"),
        mk_cell("## Demo", cell_type="markdown"),
        mk_cell("#| export\ndef answer():\n    \"\"\"Return the demo answer.\"\"\"\n    return 42", cell_type="code"),
        mk_cell("This explains why the demo answer exists.", cell_type="markdown"),
        mk_cell("answer()", cell_type="code"),
        mk_cell("assert answer() == 42", cell_type="code"),
    ]), path)
    print("project_context")
    _example_project_context(str(path))
    print("\nfile_context")
    _example_file_context(str(path), include_re="answer")
    print("\nchapter_context")
    _example_chapter_context(str(path), name="Demo")
    print("\ncontext symbol")
    _example_context(f"{path}#answer", scope=str(path), mode="review")
```

#### Output shapes

The unified
[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context)
reader serves the useful attention levels: `view="summary"` maps cells
compactly, `view="full"` keeps source in order, and chapter, cell-type,
query, and regex arguments narrow the same notebook-aware result. A
qualified target such as `notebook.ipynb#cell-id` hands an agent an
exact stable cell.

Use the smallest view that answers the next question: summary to orient,
a filtered full view to implement, and a qualified cell target to edit.
Structured returns keep cell ids and indexes so an edit can target the
exact source cell.

## Query and selection

Selectors turn short human queries into stable notebook, chapter, cell,
and symbol matches.

#### A small query language

Automation needs stable selectors, but humans need short commands. The
query helpers accept aliases like `id`, `type`, `chapter`, and
`contains`, then normalize them into one internal selection shape.

## Public notebook context

This is the main notebook-facing surface: it combines the smaller
readers and returns a structured result while optionally printing the
rendered text.

#### The public notebook reader

The public reader is `context(target, scope=".")`. The target can be
`project`, a notebook path, a cell id, a chapter title, a Python symbol,
or a literal search string when no structured target resolves. Add
`view`, `chapter`, `cell_type`, `query`, `include_re`, or `exclude_re`
to shape the same result.

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L537"
target="_blank" style="float:right; font-size:smaller">source</a>

### project_context

``` python
def project_context(
    path:str='.', # Project directory, notebook path, or notebook glob root
    verbose:bool=True, # Print rendered context; pass False to only return structured data
):
```

*Show README sections, notebook filenames, and notebook file
docstrings.*

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L567"
target="_blank" style="float:right; font-size:smaller">source</a>

### chapter_context

``` python
def chapter_context(
    path:str, # Notebook path
    query:str | None=None, # Query for any cell inside the chapter
    name:str | None=None, # Chapter title string or regex
    any_cell_id:str | None=None, # Any cell id inside the chapter
    verbose:bool=True, # Print rendered context; pass False to only return structured data
    overview:bool=False, # Show only notebook head and chapter intro markdown
    cell_type:str | None=None, # Optional cell type or semantic type filter for deep dives
    include_re:str | None=None, # Optional regex that matched cell source must include
    exclude_re:str | None=None, # Optional regex that matched cell source must not include
):
```

*Show one chapter in source order, with optional overview and cell
filters.*

## Python source context

Notebook work often crosses into generated modules. The AST readers keep
that handoff compact and navigable.

Python files get a compact AST-backed reader too.
[`python_file_context`](https://MorsCerta-crypto.github.io/nbskill/read.html#python_file_context)
summarizes public definitions without dumping full source, while
[`python_symbol_context`](https://MorsCerta-crypto.github.io/nbskill/read.html#python_symbol_context)
opens one symbol and shows the local callers and callees that matter for
an edit.

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L700"
target="_blank" style="float:right; font-size:smaller">source</a>

### python_file_context

``` python
def python_file_context(
    path:str, # Python file path
    include_private:bool=False, # Include private definitions in the summary
    verbose:bool=True, # Print rendered context; pass False to only return structured data
):
```

*Show a compact AST summary for one Python file.*

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L720"
target="_blank" style="float:right; font-size:smaller">source</a>

### python_symbol_context

``` python
def python_symbol_context(
    path:str, # Python file path
    symbol:str, # Function, class, method, or assignment symbol to inspect
    verbose:bool=True, # Print rendered context; pass False to only return structured data
):
```

*Show source, local callers, and callees for one Python-file symbol.*

``` python
with write_demo_notebook("01_read_python_context_example.py") as path:
    path.write_text(
        "PUBLIC_VALUE = 1\n\n"
        "def helper(value):\n"
        "    \"\"\"Prepare a value.\n\n    Hidden detail.\"\"\"\n"
        "    return value + PUBLIC_VALUE\n\n"
        "def add(a, b):\n"
        "    \"\"\"Add two values.\n\n    Hidden detail.\"\"\"\n"
        "    return helper(a) + b\n\n"
        "def uses_add(value):\n"
        "    return add(value, 1)\n",
        encoding="utf-8",
    )
    py_file = python_file_context(str(path), verbose=False)
    py_symbol = python_symbol_context(str(path), "add", verbose=False)
py_file["public_symbols"][0]["symbol"], py_file["definitions"][1]["docstring"], py_symbol["callers"][0]["symbol"], py_symbol["callees"]
```

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L778"
target="_blank" style="float:right; font-size:smaller">source</a>

### file_context

``` python
def file_context(
    path:str, # Notebook or Python file path
    include_re:str | None=None, # Optional regex for markdown and definition items to include
    exclude_re:str | None=None, # Optional regex for markdown and definition items to exclude
    verbose:bool=True, # Print rendered context; pass False to only return structured data
):
```

*Show compact context for one notebook or Python file; notebook cells
stay in source order.*

Filtered context is the project-wide escape hatch for questions that are
too broad for one target but still need notebook-aware cells instead of
raw JSON. It searches notebooks in `scope`, keeps stable cell ids in the
result, and caps both the number of matches and each source snippet so
agents can ask broad questions without flooding their context.

[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context)
combines discovery and reading. Use `context(path, view="summary")` for
one compact row per cell, `cell_type="markdown"` or `cell_type="code"`
for role-specific slices, `chapter="Name"` for one section, and
`query="regex=term"` or `include_re="term"` for targeted search.
`context_lines=1` adds neighboring cell summaries without opening the
whole notebook.

``` python
def _write_read_sample_notebook(path):
    double_example = mk_cell("double(3)", cell_type="code")
    double_example.outputs = [{
        "output_type": "execute_result",
        "execution_count": 1,
        "metadata": {},
        "data": {"text/plain": "6"},
    }]
    add_example = mk_cell("add(2, 3)", cell_type="code")
    add_example.outputs = [{
        "output_type": "execute_result",
        "execution_count": 1,
        "metadata": {},
        "data": {"text/plain": "5"},
    }]
    calculator_example = mk_cell("Calculator(10).total(2)", cell_type="code")
    calculator_example.outputs = [{
        "output_type": "execute_result",
        "execution_count": 1,
        "metadata": {},
        "data": {"text/plain": "22"},
    }]
    error_cell = mk_cell("raise RuntimeError('boom')", cell_type="code")
    error_cell.outputs = [{
        "output_type": "error",
        "ename": "RuntimeError",
        "evalue": "boom",
        "traceback": ["RuntimeError: boom"],
    }]
    nb = new_nb([
        mk_cell("# Sample tool\nNotebook-level note.", cell_type="markdown"),
        mk_cell("More file-level context.", cell_type="markdown"),
        mk_cell("import math", cell_type="code"),
        mk_cell("## Math\nThis chapter demonstrates code-first groups.", cell_type="markdown"),
        mk_cell(
            "#| export\ndef double(value):\n"
            "    \"\"\"Double a value.\"\"\"\n"
            "    return value * 2",
            cell_type="code",
        ),
        mk_cell("Double a value by multiplying it by two.", cell_type="markdown"),
        double_example,
        mk_cell("assert double(3) == 6", cell_type="code"),
        mk_cell(
            "#| export\ndef add(a, b):\n"
            "    \"\"\"Add values.\"\"\"\n"
            "    return double(a) + b",
            cell_type="code",
        ),
        mk_cell("Add the doubled first value to the second.", cell_type="markdown"),
        add_example,
        mk_cell("assert add(1, 2) == 4", cell_type="code"),
        mk_cell(
            "#| export\nclass Calculator:\n"
            "    \"\"\"Calculate values.\"\"\"\n"
            "    def __init__(self, base):\n"
            "        \"\"\"Store the base value.\"\"\"\n"
            "        self.base = base\n\n"
            "    def total(self, value):\n"
            "        \"\"\"Add value to the base.\"\"\"\n"
            "        return add(self.base, value)",
            cell_type="code",
        ),
        mk_cell("Calculator keeps a base and adds a value.", cell_type="markdown"),
        calculator_example,
        mk_cell("assert Calculator(10).total(2) == 22", cell_type="code"),
        mk_cell("### Detail\nNested rationale mentioning add.", cell_type="markdown"),
        mk_cell("detail_value = add(2, 4)", cell_type="code"),
        error_cell,
    ])
    write_nb(nb, path)
    return nb
```

``` python
with write_demo_notebook("01_read_filter_context_example.ipynb") as path:
    nb = new_nb([mk_cell("detail_value = 6"), mk_cell("other_value = 1")])
    write_nb(nb, path)
    filtered = _context_filtered(str(path), query="type=code regex=detail_value", verbose=False)
filtered["total_matches"], filtered["matches"][0]["cell_id"]
```

Use `view="cell"` when the selected source needs stable line numbers.
Queries such as `errors`, `export`, `headers`, `chapter=Name`, and
`regex=term` retain the existing notebook selectors while keeping the
public surface on
[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context).

## Exact cell context

Use `context("notebook.ipynb#cell-id", mode="exact")` when an edit needs
the complete selected cell without docs, callers, or truncation.

``` python
with write_demo_notebook("01_read_cell_search_examples.ipynb") as path:
    nb = _write_read_sample_notebook(path)
    summary = _context_filtered(str(path), view="summary", verbose=False)
    numbered = _context_filtered(str(path), query=f"id={nb.cells[8].id}", view="cell", verbose=False)
    errors = _context_filtered(str(path), query="errors", verbose=False)
    exports = _context_filtered(str(path), query="export", view="summary", verbose=False)
    outline = _context_filtered(str(path), query="headers", view="summary", verbose=False)
    section = _context_filtered(str(path), query="chapter=Detail", verbose=False)
    grep = _context_filtered(str(path), query="regex=detail_value", view="summary", before=1, after=1, verbose=False)
summary["matches"][0]["summary"], numbered["text"].splitlines()[10], errors["matches"][0]["error"], len(exports["matches"]), len(outline["matches"]), section["total_matches"], grep["matches"][0]["before"][0]["cell_id"]
```

### Reading through the model

[`Notebook.context`](https://MorsCerta-crypto.github.io/nbskill/read.html#notebook.context)
and
[`Notebook.symbol`](https://MorsCerta-crypto.github.io/nbskill/read.html#notebook.symbol)
remain convenience methods, while the module-level
[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context)
function is the canonical reader and filter surface.

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L1201"
target="_blank" style="float:right; font-size:smaller">source</a>

### Notebook.context

``` python
def context(
    **kw
):
```

*Read this notebook through the canonical context reader.*

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L1207"
target="_blank" style="float:right; font-size:smaller">source</a>

### Notebook.symbol

``` python
def symbol(
    symbol, **kw
):
```

*Read implementation context through the canonical context reader.*

------------------------------------------------------------------------

<a
href="https://github.com/MorsCerta-crypto/nbskill/blob/main/nbskill/read.py#L1899"
target="_blank" style="float:right; font-size:smaller">source</a>

### context

``` python
def context(
    target:str='project', scope:str='.', targets:list[str] | None=None, mode:str='auto', around:int=0,
    view:str | None=None, query:NoneType=None, include_re:str | None=None, exclude_re:str | None=None,
    max_matches:int=50, max_chars_per_cell:int=1200, context_lines:int=0, chapter:str | None=None,
    cell_type:str | None=None, include_output:bool=False, line_numbers:bool=False, verbose:bool=True
):
```

*Read one notebook-aware target, optionally narrowed by notebook
filters.*

``` python
with write_demo_notebook(
    "01_read_context_filters.ipynb",
    cells=[
        mk_cell("# Notebook", cell_type="markdown"),
        mk_cell("## Addition", cell_type="markdown"),
        mk_cell("#| export\ndef add(a, b):\n    return a + b"),
        mk_cell("Add two values.", cell_type="markdown"),
        mk_cell("add(1, 2)"),
    ],
) as path:
    summary = context(str(path), scope=str(path), view="summary", verbose=False)
    markdown = context(str(path), scope=str(path), view="full", cell_type="markdown", verbose=False)
    code = context(str(path), scope=str(path), view="full", cell_type="code", verbose=False)
    chapter = context(str(path), scope=str(path), view="full", chapter="Addition", verbose=False)

assert summary["selection"]["view"] == "summary"
assert len(summary["selection"]["matches"]) == 5
assert all(item["cell_type"] == "markdown" for item in markdown["selection"]["matches"])
assert all(item["cell_type"] == "code" for item in code["selection"]["matches"])
assert all(item["cell_type"] in {"markdown", "code"} for item in chapter["selection"]["matches"])
assert any("def add" in item["source"] for item in code["selection"]["matches"])
```

### Context modes and edit handoff

Use `mode="auto"`, `"overview"`, `"edit"`, or `"review"`; use
`resolution` to choose summary, implementation, or full depth. Overview
returns notebook identity, headings, counts, and a next action.

`mode="edit"` is the bounded handoff for a named symbol: the exact
source and `expected_hash`, followed by its trailing Docs, local
examples/tests, and direct caller/callee metadata. These sections are
tied to the resolved symbol, so an agent can prepare an edit without
widening the search. Use `around` only when physical neighbor cells are
also needed.

``` python
with write_demo_notebook(
    "01_read_context_example.ipynb",
    cells=[
        mk_cell("#| export\ndef add(a, b):\n    return a + b"),
        mk_cell("Add two values.", cell_type="markdown"),
        mk_cell("add(2, 3)"),
    ],
) as path:
    result = context(f"{path}#add", scope=str(path), mode="edit")
    selection = result["selection"]
    print(selection["cell_id"], selection["expected_hash"])
    print(selection["docs"][0]["source"], selection["examples"][0]["source"])
```

#### A compact context result

The public reader returns structured data and can also render the first
useful line for a human.

``` python
with write_demo_notebook("01_read_output.ipynb") as path:
    result = context("project", scope=str(path))
    print(result["kind"])
    print(result["text"].splitlines()[0])
```

[`context`](https://MorsCerta-crypto.github.io/nbskill/read.html#context)
keeps the common call useful for implementation work. For example,
`context("add", scope="nbs/01_read.ipynb")` resolves the symbol and
prints the implementation, trailing Docs, examples/tests, callers, and
callees; `mode="overview"` keeps only the implementation source. A
notebook target such as `context("nbs/01_read.ipynb")` prints every cell
in source order, while `mode="overview"` keeps the main notebook
description, chapter headings, and function signatures.

``` python
context("add", scope="nbs/01_read.ipynb")
```

### Symbol documentation

`context(path + "#" + symbol, mode="review")` answers the symbol-first
question: “what should I know before changing this implementation?” It
returns the implementation, nearby Docs and examples/tests, plus caller
and callee summaries in one structured result.
