Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ Every change a user would notice, newest first ([Keep a Changelog](https://keepa
follow [Semantic Versioning](https://semver.org/); before 1.0, a minor version may change what a command does.
## [Unreleased]

### Added

- `code-node -i` picks the file to start from in the terminal: move through the folders with the arrow keys, or type
to search every file by its path, then pick the function. Files an entry point is in have a ★, and a wide terminal
shows a file's functions or a function's code beside the list. Tab switches to the entry points found.

### Changed

- Where the command asks which entry point to start from, it opens the same picker instead of a numbered list, and
when it finds none in a terminal it lets you pick a file instead of stopping. `--list`, `--plugins` and what it
prints are drawn with rich, which is now a dependency.

## [0.7.0] - 2026-10-21

### Changed
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Slash commands in `.claude/commands/`: `/check` (lint, tests, docs, package), `/
| `src/code_node/platforms/` | **Pure, no I/O.** `Platform` (plain Python: the base a plugin overrides), the registry (`register_platform`, `get_platform`, the `code_node.platforms` entry point group), `aws_lambda.py` (`LambdaPlatform`: handlers, the event, its findings and wording, IAM drift against a `Deployment`), and `web.py` (`WebPlatform`: FastAPI, Flask and Django apps and URL confs, a route's parameters and `flask.request` as the request, blocking calls in async routes) |
| `src/code_node/libraries/` | **Pure, no I/O.** `Library` (a library's clients: `make`, `attribute`, `item`, `call`), `Handle` (what a name holds), `Use` (what a call does), `Call` (the call as a plugin sees it), the registry (`code_node.libraries`), and `redis.py`, `sql.py`, `mongo.py`, `llm.py` |
| `src/code_node/deploys/` | **Pure, no I/O.** `Deploy` (a kind of deploy file: `deployments(files, code)` → `Deployment`s, `grant`), the registry (`code_node.deploys`), YAML with CloudFormation tags, IAM policy helpers, and `sam.py`, `serverless.py` |
| `src/code_node/browse.py`, `terminal.py` | The picker (`-i`, and wherever the command asks): `browse` draws `_Picker` full screen with rich `Live`; `terminal.py` has the rich consoles and `keys()`, one key at a time (termios, or msvcrt on Windows) |
| `src/code_node/pages.py` | `PageOptions`, `make_page` / `make_mermaid`: read the folder, map, draw (what the command and the server share) |
| `src/code_node/history.py` | What git says about each function shown (`read_history`: `git blame` once per file, onto `CodeFunction.history`). Read-only git, with no file system monitor or text conversion, and none at all when the folder's own config names a filter command |
| `src/code_node/serve.py` | `--serve`: `LivePage` (the latest page, a version, a Condition), a polling watcher thread, `ThreadingHTTPServer` with `/` and `/events` (Server-Sent Events) |
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ cd your/repo && code-node

```bash
code-node # find entry points and pick one
code-node -i # walk the folder (arrow keys, or type to search) and pick a file
code-node --list # just list them
code-node src/app/main.py:run # start from a function
code-node src/app/store.py:Store.save # ...or a method
Expand All @@ -78,6 +79,7 @@ string is flagged.
| --- | --- |
| `path` | Folder to read, or a file to start from (`main.py`, `main.py:function`) |
| `-e`, `--entry` | `module.function`, `module.Class.method`, `file.py[:function]`, or part of a name |
| `-i`, `--interactive` | Pick the file in the terminal: arrow keys through the folders, or type to search every file |
| `-l`, `--list` | List entry points and stop |
| `--plugins` | List platforms, libraries and deploy files and stop |
| `--all` | Draw every function (default: 14 functions, 5 calls deep) |
Expand Down
25 changes: 25 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,37 @@ in your browser.
| You type | It starts at |
| --- | --- |
| `code-node` | Wherever you pick from what it finds |
| `code-node -i` | The file you pick by walking the folder |
| `code-node app/main.py` | That file's `main()` |
| `code-node app/main.py:run` | `run()` in that file |
| `code-node app/store.py:Store.save` | A method |
| `code-node -e pkg.cli.main` | A dotted name |
| `code-node -e save` | Anything with "save" in its name |
| `code-node --list` | Nowhere: it lists the entry points it found |

## Pick a file in the terminal { #interactive }

```bash
code-node -i
```

This opens a picker in the terminal. It lists the folder's Python files and the folders that hold them, with a ★ on
each file an entry point is in. A terminal at least 110 columns wide also shows what's under the cursor: a file's
functions, or a function's code.

| Key | Does |
| --- | --- |
| ↑ ↓, PgUp PgDn, Home End | Move |
| → or Enter | Open a folder; pick a file, then the function in it to start from |
| ← or Backspace | Go up a folder, or back from a file's functions |
| Any letters | Search every file by path: `ordhan` finds `orders/handler.py` |
| Tab | Switch between the files and the entry points found |
| Esc | Clear the search, go back, or quit |

!!! tip "Worth knowing"
Plain `code-node` opens the same picker on the entry points it found when there are several, and on the files
when it found none. Press Tab there to see the files.

??? more "What it finds on its own"
In this order:

Expand Down Expand Up @@ -103,6 +127,7 @@ to see its commit. The gear in the panel's head turns that off. It's read with `
| --- | --- |
| `path` | A folder, or a file to start from |
| `-e`, `--entry` | Where to start |
| `-i`, `--interactive` | Pick the file in the terminal |
| `-l`, `--list` | List the starts |
| `--plugins` | List the plugins |
| `--serve`, `--port` | Live page (8765, or the next free port) |
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ classifiers = [
]
# botocore names AWS operations and their IAM actions from its own service models (no AWS call is ever made). PyYAML
# reads deploy files (template.yaml, serverless.yml).
dependencies = ["botocore>=1.35.72", "pyyaml>=6.0"]
dependencies = [
"botocore>=1.35.72",
"pyyaml>=6.0",
"rich>=13.7",
]

# What working on code-node needs. None of it ships in the wheel. `uv sync` installs every group into .venv at the
# versions in uv.lock, and Dependabot proposes upgrades to both.
Expand Down
Loading
Loading