Skip to content

Commit de72fdb

Browse files
committed
Initial docs and docs deployment
1 parent 0526f4d commit de72fdb

14 files changed

Lines changed: 1653 additions & 0 deletions

.github/workflows/docs.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Deploy docs
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
jobs:
10+
deploy:
11+
runs-on: ubuntu-24.04
12+
13+
steps:
14+
- uses: actions/checkout@v5
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: '3.13'
20+
21+
- name: Install docs dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
# TODO: prepare_env docs
25+
python -m venv .venvs/docs
26+
source .venvs/docs/bin/activate
27+
python -m pip install --group="docs"
28+
29+
- name: Build docs
30+
env:
31+
MKDOCS_SITE_URL: https://finecode-dev.github.io
32+
run: |
33+
source .venvs/docs/bin/activate
34+
mkdocs build
35+
36+
- name: Deploy to finecode.github.io
37+
uses: peaceiris/actions-gh-pages@v4
38+
with:
39+
personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }}
40+
external_repository: finecode-dev/finecode.github.io
41+
publish_branch: main
42+
publish_dir: ./site

docs/cli.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# CLI Reference
2+
3+
All commands are run from the workspace or project root directory, inside the `dev_workspace` virtual environment.
4+
5+
```bash
6+
source .venvs/dev_workspace/bin/activate
7+
python -m finecode <command> [options]
8+
```
9+
10+
---
11+
12+
## `run`
13+
14+
Run one or more actions across projects.
15+
16+
```
17+
python -m finecode run [options] <action> [<action> ...] [payload] [--config.<key>=<value> ...]
18+
```
19+
20+
### Options
21+
22+
| Option | Description |
23+
|---|---|
24+
| `--workdir=<path>` | Use `<path>` as the workspace root instead of `cwd` |
25+
| `--project=<name>` | Run only in this project. Repeatable for multiple projects. |
26+
| `--concurrently` | Run actions concurrently within each project |
27+
| `--trace` | Enable verbose (trace-level) logging |
28+
| `--no-env-config` | Ignore `FINECODE_CONFIG_*` environment variables |
29+
| `--no-save-results` | Do not write action results to the cache directory |
30+
31+
### Payload
32+
33+
Named parameters passed to the action payload. All must use `--<name>=<value>` form:
34+
35+
```bash
36+
python -m finecode run format --save=true
37+
python -m finecode run lint --target=files --file-paths='["src/main.py"]'
38+
```
39+
40+
### Config overrides
41+
42+
Override handler configuration inline:
43+
44+
```bash
45+
# Action-level (applies to all handlers)
46+
python -m finecode run lint --config.line_length=120
47+
48+
# Handler-specific
49+
python -m finecode run lint --config.ruff.line_length=120 --config.mypy.strict=true
50+
```
51+
52+
See [Configuration](configuration.md) for full details on config precedence.
53+
54+
### Behavior
55+
56+
- With no `--project`: FineCode treats `cwd` (or `--workdir`) as the workspace root, discovers all projects, and runs the action in each project that defines it.
57+
- With `--project`: the action must exist in every specified project.
58+
- Action results are saved to `<venv>/cache/finecode/results/<action>.json` (one entry per project path).
59+
60+
### Examples
61+
62+
```bash
63+
# Lint all projects
64+
python -m finecode run lint
65+
66+
# Lint and check_formatting concurrently
67+
python -m finecode run --concurrently lint check_formatting
68+
69+
# Run only in two specific projects
70+
python -m finecode run --project=fine_python_mypy --project=fine_python_ruff run lint
71+
72+
# Run from a different directory
73+
python -m finecode --workdir=./finecode_extension_api run lint
74+
75+
# Override ruff line length
76+
python -m finecode run lint --config.ruff.line_length=120
77+
```
78+
79+
---
80+
81+
## `prepare-envs`
82+
83+
Create and populate virtual environments for all handler dependencies.
84+
85+
```
86+
python -m finecode prepare-envs [--recreate] [--trace] [--debug]
87+
```
88+
89+
Must be run from the workspace or project root. Creates venvs under `.venvs/<env_name>/` and installs each handler's declared dependencies.
90+
91+
| Option | Description |
92+
|---|---|
93+
| `--recreate` | Delete and recreate all venvs from scratch |
94+
| `--trace` | Enable verbose logging |
95+
| `--debug` | Wait for a debugpy client on port 5680 before starting |
96+
97+
---
98+
99+
## `dump-config`
100+
101+
Dump the fully resolved configuration for a project to disk, useful for debugging preset and config merging.
102+
103+
```
104+
python -m finecode dump-config --project=<name> [--trace] [--debug]
105+
```
106+
107+
Output is written to `<cwd>/finecode_config_dump/`.
108+
109+
| Option | Description |
110+
|---|---|
111+
| `--project=<name>` | **(Required)** Project to dump config for |
112+
| `--trace` | Enable verbose logging |
113+
| `--debug` | Wait for a debugpy client on port 5680 |
114+
115+
---
116+
117+
## `start-api`
118+
119+
Start the FineCode LSP server. Used by the IDE extension — you typically don't call this directly.
120+
121+
```
122+
python -m finecode start-api --stdio | --socket <port> | --ws [--host <host>] [--port <port>]
123+
```
124+
125+
| Option | Description |
126+
|---|---|
127+
| `--stdio` | Communicate over stdin/stdout |
128+
| `--socket <port>` | Start a TCP server on the given port |
129+
| `--ws` | Start a WebSocket server |
130+
| `--host <host>` | Host for TCP/WS server (default: 127.0.0.1 for TCP) |
131+
| `--port <port>` | Port for TCP/WS server |
132+
| `--mcp` | Also start an MCP server |
133+
| `--mcp-port <port>` | Port for the MCP server |
134+
| `--trace` | Enable verbose logging |
135+
| `--debug` | Wait for a debugpy client on port 5680 |

docs/concepts.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Concepts
2+
3+
Understanding a few core concepts makes the rest of FineCode straightforward.
4+
5+
## Action
6+
7+
An **Action** is a named operation — `lint`, `format`, `build_artifact`, etc. It is defined as a Python class that declares the types of its payload, execution context, and result:
8+
9+
```python
10+
class LintAction(code_action.Action[LintRunPayload, LintRunContext, LintRunResult]):
11+
PAYLOAD_TYPE = LintRunPayload
12+
RUN_CONTEXT_TYPE = LintRunContext
13+
RESULT_TYPE = LintRunResult
14+
```
15+
16+
Actions are identified by their **import path** (e.g. `finecode_extension_api.actions.lint.LintAction`), not by the name used in config. The config name is just a human-readable alias.
17+
18+
Actions can be called from:
19+
20+
- the CLI (`python -m finecode run lint`)
21+
- the IDE via the LSP server (diagnostics, code actions, formatting)
22+
- other handlers
23+
24+
## ActionHandler
25+
26+
An **ActionHandler** is a concrete implementation of an action. Multiple handlers can be registered for a single action. For example, the `lint` action might have handlers for ruff, flake8, and mypy — each independently checking the code.
27+
28+
Each handler:
29+
30+
- specifies which **virtual environment** (`env`) it runs in
31+
- declares its own **dependencies** (installed automatically by `prepare-envs`)
32+
- receives the action payload and returns a result
33+
34+
### Sequential vs. concurrent execution
35+
36+
Handlers for an action run either **sequentially** (default) or **concurrently**.
37+
38+
```mermaid
39+
flowchart LR
40+
subgraph Sequential
41+
direction TB
42+
P1[payload] --> H1[handler 1]
43+
H1 -->|current_result| H2[handler 2]
44+
H2 -->|current_result| H3[handler 3]
45+
H3 --> R1[result]
46+
end
47+
48+
subgraph Concurrent
49+
direction TB
50+
P2[payload] --> H4[handler 1]
51+
P2 --> H5[handler 2]
52+
P2 --> H6[handler 3]
53+
H4 --> M[merge]
54+
H5 --> M
55+
H6 --> M
56+
M --> R2[result]
57+
end
58+
```
59+
60+
**Sequential mode** (default): handlers run one after another. Each handler can read the accumulated result so far via `context.current_result`. Useful when handlers depend on each other's output (e.g. formatter → save-to-disk).
61+
62+
**Concurrent mode** (`run_handlers_concurrently: true`): all handlers run in parallel and results are merged afterward. Accessing `context.current_result` in concurrent mode raises `RuntimeError`. Useful for independent linters.
63+
64+
## Preset
65+
66+
A **Preset** is a Python package that bundles action and handler declarations into a reusable, distributable configuration. Users install a preset as a `dev_workspace` dependency and reference it in `pyproject.toml`:
67+
68+
```toml
69+
[tool.finecode]
70+
presets = [{ source = "fine_python_recommended" }]
71+
```
72+
73+
A preset contains a `preset.toml` file that declares which handlers to activate for which actions. The user's `pyproject.toml` configuration is merged on top of the preset, giving the user full control to override, extend, or disable individual handlers.
74+
75+
### Handler modes
76+
77+
When configuring an action in `pyproject.toml`, you can control how your configuration relates to preset handlers:
78+
79+
- **Default (additive):** your handlers are added to the preset's handlers.
80+
- **`handlers_mode = "replace"`:** your handler list completely replaces the preset's handlers for that action.
81+
- **`disabled = true` on a handler entry:** disables that specific inherited handler.
82+
83+
## Project
84+
85+
A **Project** is any directory containing a `pyproject.toml` with a `[tool.finecode]` section. FineCode discovers all projects under the workspace root automatically.
86+
87+
A project may belong to a **workspace** — a directory containing multiple projects. FineCode handles multi-project workspaces transparently: running `python -m finecode run lint` from the workspace root runs lint in all projects that define it.
88+
89+
## Workspace Manager and Extension Runner
90+
91+
FineCode has two runtime components:
92+
93+
### Workspace Manager (WM)
94+
95+
The `finecode` package. It:
96+
97+
- discovers projects and resolves merged configuration
98+
- manages virtual environments (`prepare-envs`)
99+
- exposes an **LSP server** to the IDE
100+
- delegates action execution to Extension Runners
101+
102+
### Extension Runner (ER)
103+
104+
The `finecode_extension_runner` package. It:
105+
106+
- runs inside an isolated virtual environment (e.g. `.venvs/dev_no_runtime`)
107+
- imports and executes handler code
108+
- communicates results back to the WM via LSP/JSON-RPC
109+
110+
The WM/ER split means handler dependencies never pollute the workspace Python environment.
111+
112+
## Environments
113+
114+
Each handler declares an `env` (e.g. `dev_no_runtime`, `runtime`). FineCode creates a separate virtualenv for each env name it encounters, and installs the handler's declared `dependencies` into it. `prepare-envs` automates this.
115+
116+
```toml
117+
# Example: handler in pyproject.toml
118+
[[tool.finecode.action.lint.handlers]]
119+
name = "ruff"
120+
source = "fine_python_ruff.RuffLintFilesHandler"
121+
env = "dev_no_runtime"
122+
dependencies = ["fine_python_ruff~=0.2.0"]
123+
```
124+
125+
The env name is arbitrary — it's just a label FineCode uses to group handlers that share a virtualenv.

0 commit comments

Comments
 (0)