Blocks (.lnb)

A Blocks bundle is a folder whose name ends in .lnb, treated as a single item in the tree (double-click opens it). Each block is a real file on disk; the order lives in a blocks.json at the bundle root. It works like a notebook: stacked cells of code or text. A Jupyter notebook comes in this way: right-click an .ipynb in the tree and choose Import as Blocks (.lnb). Each cell becomes a real file — versionable and read by search — and the .ipynb stays where it was, because importing is not converting. The outputs stored in the notebook do not come along: running the cell here produces the real result, with its time and command. If blocks.json is unreadable (a Git conflict or an interrupted write), the notebook warns you and does not rewrite it: the order, the connection and the session are saved again only after you fix it.

Cells, notebook bar and shortcuts

Each cell has a name, a type button (markdown, python, javascript, sql, shell, powershell, bat, r, julia, http, ai, mermaid, latex and the text types) and buttons to copy, insert (click: below; the arrow: above and duplicate), delete, move up and down and run (the arrow offers Run up to here). A new cell inherits the type of its neighbour. The button on the right collapses the cell, leaving only its first line in the header, and the [n] counter tells the order in which the cells ran in this session. Create a notebook from the tree (New) or via File → New.

The notebook bar, at the top, acts on the whole notebook: Run all runs the code cells in order; Stop interrupts the running one and empties the queue (the run goes to the history with exit code -1); Clear outputs closes the panels without deleting anything; the More menu exports the notebook and deletes the history. The timeoutSec key in blocks.json sets a time limit per cell (0, the default, is no limit).

Shortcuts, with the focus in a cell: Ctrl+Enter runs and stays; Shift+Enter runs and moves to the next cell (on the last one, it creates a new one); Alt+Enter runs and inserts a cell right below. In a text cell, running means rendering: it opens rendered when it has content, and a double-click (or Enter on it) goes back to editing.

Saved results, attachments and history

Results are saved (like a lab notebook): when a run finishes it becomes a .md file under saida/<cell>/ inside the bundle — with the timestamp, exit code, duration, command and the output itself. Being Markdown, it reads in any editor, versions in Git alongside the notebook, and is picked up by AI Chat. Reopening the bundle brings back the Last run strip above the panel: click it to see the result without running again.

Attachments: each run gets a folder of its own, next to the .md, and its path reaches the program in the LN_RUN_DIR environment variable. Whatever the cell writes there — a matplotlib chart, a CSV — appears below the output (images drawn, the rest as a link to the folder) and is listed in the history file. Output that is already Markdown (the table of a SELECT, the AI answer, a diagram) opens rendered; the Text/Render button on the strip switches.

History: the History button next to that strip lists the previous runs of that cell (timestamp and exit code) — handy to compare what the same cell returned over time. We keep the 10 most recent per cell; to change that, edit the historyLimit key in the bundle's blocks.json (0 turns saving off, and attachments with it). Very large output is cut (the file says truncated: true). Renaming a cell or changing its type takes the history along; deleting the cell sends its history to the Recycle Bin.

Persistent session

By default each cell is a new process: what one defines, the next does not see. With the persistent session on (the Session button on the bar; the session key in blocks.json), Python, JavaScript, shell and PowerShell cells run in a process that stays alive between runs — variables, functions and imports from one cell are valid in the next, as in Jupyter. In Python, matplotlib figures left open at the end of the cell are saved to the attachments folder on their own. Restart session forgets everything; so does Stop, because interrupting means ending the process. In JavaScript, declare with var (or with no declaration): top-level let, const and class cannot be declared again — not even by running the same cell twice.

SQL cells

With no connection set, an sql cell runs on the notebook's own DuckDB (in memory): tables created in one cell are valid in the next, and read_csv('data/sales.csv') reads the files in the notebook folder — keep the data in a subfolder, because every loose file in the notebook folder is a cell. For a real database, point the notebook at an .lnc connection from the connection strip (it lists the workspace connections): the cells start running on the database, through the same connection as the Connections panel — remembered password, SSH tunnel, re-reading of the .lnc and the production confirmation before any write. A SELECT result becomes a table in the output file; INSERT/UPDATE and friends report how many rows changed, and an error stops the script and records the statement that failed. We fetch up to 100 rows per query (sqlMaxRows in blocks.json; the file says when there were more).

@set name = value defines a variable with notebook scope, and :name (or ?) is a parameter asked at run time, as in the SQL editor. The last SELECT also writes resultado.csv to the attachments folder (the same rows as the table, up to sqlMaxRows), and the following cells receive its path in LN_LAST_SQL — in Python, pd.read_csv(os.environ["LN_LAST_SQL"]). The connection lives in blocks.json as a relative path; an .lnc kept inside the bundle counts as configuration, not as a cell.

HTTP, AI, Mermaid and LaTeX

Four types run inside LightNote itself, with no interpreter: the http cell is an .lnh test executed by the same runner as the API tester (the report goes to the history; the environment is the one named by the httpEnv key in blocks.json, and a file the request sends must be inside the workspace); the ai cell sends the prompt to the default assistant with the notebook context — the source of the previous cells and the last output of each, except the http cells, which may carry credentials — and the answer arrives rendered; the mermaid and latex cells draw the diagram or the formula into an image in the attachments. Stop cancels the first two.

Exporting the notebook

The More menu on the bar exports the whole notebook: as Markdown (text cells inline, code in fences with the language, the last output right below and the images linked) or as a Jupyter notebook (.ipynb, with the last output of each cell and the images embedded; a cell of another language carries the mark that VS Code reads). It is a copy to share — the notebook is still the folder.