Skip to main content

Arborito Python SDK

Build Pygame games, bots, kiosks, validators, and offline trainers from any .arborito course. Same capabilities as browser Arcade cartridges (window.arborito).

arborito-games is only the HTML Arcade catalog (like Flathub). This repo is for Python and native apps.

Version: 0.2.6

Naming: camelCase vs snake_case

The browser injects window.arborito with camelCase methods (fromLesson, buildCard, tasksFromLesson). The Python SDK keeps those same names on the Arcade surface so a cartridge and a Pygame game share one vocabulary.

Python-only helpers use snake_case (grade_answer, matches_any, branch_profile, from_course). CamelCase aliases exist where useful (gradeAnswer, matchesAny, branchProfile, fromCourse, lessonAction, plainText / plain_text).

Install

pip install arborito-sdk
# Rich terminal lesson editor (F2 Quiz, forms, block list):
pip install 'arborito-sdk[tui]'
# Nostr account + publish:
pip install 'arborito-sdk[nostr]'

Package name: arborito-sdk · CLI command: arborito-cli · Python import: arborito_sdk

Mental model

list → go → read | edit | quiz | ask

Library: branch (full courses) and tree (composed playlists).

Python games: use static quiz helpers without an AI server; use dynamic mode for ask.speak / reply / scene gates. Advanced is only when you write the prompt yourself.

CLI commands

Run arborito-cli. Interactive: arborito-cli course.arborito (REPL with breadcrumb prompt).

Area Commands
Interactive shell or arborito-cli course.arborito (REPL); help; exit / quit
Navigate list, go N, go back, go where, go "name" (back / where shortcuts)
Lesson read (enriched), edit (TUI / F2 Quiz), edit --raw, games, info
Study quiz, ask
Search search QUERY, search --courses QUERY
Branches branch list, branch add CODE, branch open "Name", branch import, branch new, branch publish, branch export, branch remove (alias: forest / bosque)
Trees tree list, tree open "Name", tree import, tree export, tree remove
Copy cp branch "Name" / cp tree "Name"
Favorites fav list, fav add, fav remove
Account session register, session login, session logout, session whoami
Memory memory due, memory report (Care pull/push runs automatically when logged in)
Config config relay list|set|reset, config ai list|set …
Scripts script / run / batch

Network: only share codes XXXX-XXXX or local .arborito files, no manual nostr:// URLs. Sync and refresh run automatically when loading from the network. Full keys: CLI.md.

Quick start

pip install 'arborito-sdk[tui]'
arborito-cli course.arborito
branch import course.arborito
branch open "My Course"
list
go 1
read # enriched blocks (not raw @quiz)
edit # F2 Quiz, Ctrl+S save
quiz --rounds 5

Lesson editor (terminal)

Command Behaviour
read Structured view: Quiz · concept, question, answer
edit Block list + forms (requires [tui] for full UI)
edit --raw Open lesson markdown in $EDITOR

Details: CLI.md. Full WYSIWYG editing is in Arborito Construction mode.

Lesson outline (construct TOC)

Syllabus rows use an @section fence with index (path) and title. Nest depth is the path segment count (max 8). Indexes are rewritten on every save/move:

@section
index: 1
title: Introduction
@/section

Text of the first section.

@section
index: 1.1
title: Concepts
@/section

Detail.

@section
index: 1.2
title: Exercise
@/section

More practice.

@section
index: 1.2.1
title: Extra
@/section

Nested.

@section
index: 2
title: Practice
@/section

Second root section.
  • Nesting = index segment count.
  • Humans and the machine share one coordinate (index:).
  • ←→↑↓ operate on that geometry; apply_toc_section_move returns {ok, body, selectedIndex} where ok is path math (not whether the markdown bytes changed).
  • Normal ## / ### without a path are content titles once the lesson already has index: rows.
  • Titles may repeat; indexes stay unique after prepare_construct_outline_body.

API surface (static vs dynamic mode)

Same contract as browser Arcade (window.arborito). Static needs no AI server. Dynamic mode needs local llama.cpp (ai_mode="dynamic"). Prefer the scene helpers in dynamic mode; open advanced only when you own the prompt.

All Python API commands

Mode Call Role
Dynamic ask.fromCourse(topic) / from_course Practice card from the open course (greeting, origin, purpose, goodbye)
Dynamic ask.speak(who, text) Paraphrase an authored line (no course quizzes in the prompt)
Dynamic ask.reply(who, playerSaid, facts) NPC answers using only facts
Dynamic ask.check(playerSaid, card) Grade against a fromCourse card (local match, then optional AI judge; local match also works static)
Dynamic ask.tutor(lesson, text, opts?) Study chat grounded in course questionnaires (aliases: lesson_action, lessonAction)
Static lesson.at / by_id / byId / plainText Load lesson prose for HUD / NPC
Static lesson.context_for_ai / branch_profile Lesson / branch text for prompts
Static challenge.fromLesson → modes.buildCard Static challenge cards
Static challenge.tasksFromLesson Mission list from questionnaires
Static quiz / matchPairs Classroom Q/A and Memory pairs
Static quiz.matches_any / matchesAny Local answer match
Static quiz.grade_answer / gradeAnswer Grade (local; LLM only in dynamic mode)
Static quiz.pick / find_code_replay Pick pool item / code replay
Static memory.due / report / isDue / getStatus Care / SM-2 local
Both memory.pull / push / sync Care sync with Arborito (needs [nostr] + login)
Advanced ask.json(prompt) Raw JSON from your prompt
Advanced ask.chat(messages) Raw chat turn
Advanced ask.with_context(query) Short answer grounded in indexed course context
Advanced ask.npc(...) Legacy narrative helper — prefer speak / reply for new scene code
Advanced narrative.start / advance YAML scene runner (programmatic; no CLI command)
Advanced ai.persona / ai.arborito Tutor voice strings
lesson → challenge → your UI → memory (optional)
from arborito_sdk import Arborito

api = Arborito.from_arborito("course.arborito", lang="EN")
lesson = api.lesson.at(0)
cards = api.challenge.fromLesson(lesson)
card = api.challenge.modes.buildCard(cards[0], "cloze", lang="EN")
prose = api.lesson.plainText(lesson)  # NPC / HUD (strips @section, @quiz, …)
api.memory.report(lesson["id"], quality=4)

Care sync with the Arborito app (Nostr tree + account):

api = Arborito.from_share_code("ABCD-EF23", lang="EN")
api.login("player", "their-sync-secret")  # restores network identity escrow
api.memory.pull()  # merge Care from relays
api.memory.report(lesson["id"], quality=4)
api.memory.push()  # or api.memory.sync() = pull+push

Requires pip install 'arborito-sdk[nostr]'. CLI: session login (Care syncs automatically while logged in).

Quiz helpers (detail)

lesson = api.lesson.by_id(pool_item["lessonId"])
ctx = api.lesson.context_for_ai(lesson)
ok = api.quiz.grade_answer(lesson, {"q": "…", "correct": "…"}, player_text)
match = api.quiz.matches_any(player_text, ["answer", "synonym"])
picked = api.quiz.pick(pool, session={})  # session["used"] persists
tasks = api.challenge.tasksFromLesson(lesson, {"max": 10})
replay = api.quiz.find_code_replay("echo hi", lesson=lesson)

In static mode, grade_answer only uses local matching (no LLM). Browser cartridges use the same helpers under camelCase (gradeAnswer, matchesAny, tasksFromLesson, findCodeReplay, …), see sdk-spec.md.

Loaders

Method Use
Arborito.from_arborito(path) Local export (recommended)
Arborito.from_share_code("ABCD-EF23") Public share code
Arborito.from_nostr(pub, universe_id) Direct Nostr reference
Arborito.from_library(...) / from_static_data(...) Library / in-memory trees

Docs

Test

cd arborito-sdk && pip install -e ".[dev,nostr]" && python -m unittest discover -s tests -q

Example

# Static quiz (no AI server)
python examples/minimal_quiz.py path/to/course.arborito EN

# Scene + course speaking gate (needs llama.cpp)
python examples/ai_scene.py path/to/course.arborito EN

# Study tutor (needs llama.cpp)
python examples/ai_tutor.py path/to/course.arborito EN

Dynamic scene in a few lines

print(api.ask.speak("Mike, strict boss", "Julius is missing. Hotel Pentfive.")["line"])
print(api.ask.reply("Mike. Wants accept.", player_said, ["Julius disappeared"])["line"])
card = api.ask.from_course("greeting")
ok = api.ask.check(player_said, card)["ok"]

Study tutor: api.ask.tutor(lesson, player_said, {"persona": "Guide"}) (alias: lesson_action).

Contributing

CONTRIBUTING.md

Chat: Matrix #arborito:matrix.org · treesys.org

License

GPL-3.0-or-later, LICENSE

Metadata

Release files for arborito-sdk 0.2.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for arborito-sdk 0.2.6
File Size Uploaded Provenance
arborito_sdk-0.2.6.tar.gz 172.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for arborito-sdk 0.2.6
File Interpreter ABI Platform
arborito_sdk-0.2.6-py3-none-any.whl Python 3 none any Details

Total release size: 343.8 kB

Release files / arborito_sdk-0.2.6.tar.gz

Download URL arborito_sdk-0.2.6.tar.gz
Size 172.7 kB
Tags Source
SHA-256 checksum
How to use checksums
6fcc5776d2b97846e8ebf7285e3ced824238d20b47dff8b29a8475e10a7ee744
BLAKE2b-256 checksum
How to use checksums
edd6a1a4d4ec7b397500d793bd6c67324aeee915d406fbe74b044f9bd31c4657
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Release files / arborito_sdk-0.2.6-py3-none-any.whl

Download URL arborito_sdk-0.2.6-py3-none-any.whl
Size 171.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f201c7c3ea9aef39595a9c077e73d152a47a89124f4c5415ce361c426d03c3c1
BLAKE2b-256 checksum
How to use checksums
a53a816140b82a9e5505431e8907da1b5ca773faa15a5908359e9df627f1eb8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Security for arborito-sdk 0.2.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for arborito_sdk-0.2.6.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page