Appsudo Framework LLM Reference Source: https://appsudo.com/doc Self-contained aggregate reference based on `https://appsudo.com/doc`. Verified against the Appsudo documentation in this repository on 2026-08-28. How To Use This File - Use the section index below to jump to the part you want. - Each major docs section is included inline below so this file can be used on its own. - The final verification section summarizes what was checked against the documentation in this repository. Section Index - `introduction` - `setup` - `app-structure` - `app-conventions` - `app-lifecycle` - `components` - `custom-components` - `using-llms-for-development` - `pygame-to-mini-game` - `html-mini-app` - `examples` - `css-framework` - `core-features` - `verification` ===== SECTION: introduction ===== Introduction Source section: `https://appsudo.com/doc#introduction` What Appsudo is - Appsudo is a lightweight cross-platform framework for building mini apps. - Logic is written in Python. - UI is described in ASXML, an XML-like view language. - Styling is applied inline or through ASCSS files. Core mental model - An app is a Python class that subclasses `App`. - The docs use `ViewInflater` to inflate views from files in `view/`. - The docs recommend a `self.data` object for UI state in Appsudo UI apps. - ASXML binds to that state with expressions like `{data.title}`. - Components are a mix of containers, form inputs, media surfaces, and control primitives. What the docs emphasize - Write-once, cross-platform UI composition. - Declarative layout plus imperative Python callbacks. - A relatively rich built-in component catalog. - Special support for three app shapes: normal ASXML apps, reusable custom components, and game/HTML mini apps. Practical references surfaced elsewhere in the docs - `App` is the base class for apps. - `ViewInflater` is used in the examples and structure walkthrough to inflate ASXML views. - `self.data` plus `{data.field}` bindings are the recommended pattern for UI apps. Detailed Coverage Map - The entries below were derived from the section structure in `appsudo.com/doc`. ===== SECTION: setup ===== Development Environment Setup Source section: `https://appsudo.com/doc#setup` Docs-recommended environment - Use Visual Studio Code. - Install Android Studio or equivalent Android SDK/emulator tooling. - Ensure `adb` and emulator tools are available on `PATH`. - Install the VS Code extension `Appsudo App Runner`. How apps are run during development - Open the Appsudo project in VS Code. - Open the command palette. - Run `Appsudo App Runner`. - Select the target device or emulator. Code Snippets From Docs - The blocks below were extracted from the corresponding section of `appsudo.com/doc`. Snippet 1 ``` ANDROID_SDK_ROOT=C:\Users\YourUsername\AppData\Local\Android\Sdk PATH=%PATH%;%ANDROID_SDK_ROOT%\platform-tools;%ANDROID_SDK_ROOT%\emulator ``` Snippet 2 ``` adb --version emulator -help ``` Snippet 3 ``` export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator ``` Snippet 4 ``` source ~/.zshrc # or source ~/.bash_profile ``` Snippet 5 ``` adb --version emulator -help ``` Snippet 6 ``` sudo apt update && sudo apt install adb android-emulator ``` Snippet 7 ``` export ANDROID_SDK_ROOT=$HOME/Android/Sdk export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator ``` Snippet 8 ``` source ~/.bashrc ``` Snippet 9 ``` adb --version emulator -help ``` Detailed Coverage Map - The entries below were derived from the section structure in `appsudo.com/doc`. ===== SECTION: app-structure ===== Appsudo App Structure Source section: `https://appsudo.com/doc#app-structure` Canonical project layout ```text myapp/ ├── myapp.py ├── data/ │ └── config.json ├── view/ │ └── main_view.asxml ├── style/ │ └── styles.ascss ├── res/ │ ├── images/ │ └── icons/ ├── metadata.json └── secrets.json ``` Meaning of each part - `myapp.py`: main application entry point. - `data/`: JSON files for app data/configuration. - `view/`: ASXML layouts inflated into live view trees. - `style/`: ASCSS style definitions referenced from ASXML. - `res/`: static assets like images and icons. - `metadata.json`: app metadata such as icon, type, tags, keywords, scope, display name, version, author. - `secrets.json`: secret values for runtime use. Common file behaviors from the docs - `ViewInflater(self).inflate("view_name", data)` loads `view/view_name.asxml`. - The examples use relative resource paths such as `res/images/...` and `res/icons/...`. Detailed Coverage Map - The entries below were derived from the section structure in `appsudo.com/doc`. ===== SECTION: app-conventions ===== General Guidance And Naming Conventions Source section: `https://appsudo.com/doc#app-conventions` Hard rules - App folder names must be lowercase. - Folder names must not contain spaces, hyphens, or special characters. - The main class must subclass `App`. - The main class name should follow `App`, for example `SportGameApp`. - The `App` constructor identifier should be a single runtime name string with no extra wording. Constructor pattern ```python def __init__(self, application_path): super().__init__("SportGame", application_path) ``` Render rule - `self.render(...)` may be called only once per app. - That single call must happen in `run()` or in a helper that `run()` invokes. - Extra render calls are documented as runtime errors that crash the app. Recommended state pattern - For non-pygame UI apps, create `self.data` in `__init__`. - Bind ASXML against that object with `{data.field}`. - Keep UI declarative and state centralized on the data object. Code Snippets From Docs - The blocks below were extracted from the corresponding section of `appsudo.com/doc`. Snippet 1 ``` class SportGameApp(App): ... ``` Snippet 2 ``` def __init__(self, application_path): super().__init__("SportGame", application_path) ``` Snippet 3 ``` def run(self): self._show_main_view() def _show_main_view(self): # Allowed: render() lives in a helper, but it is only reached via run(). self.render(self.ui_view) ``` Snippet 4 ``` def __init__(self, application_path): super().__init__("SportGame", application_path) self.data = SportGameData(application_path) ``` Detailed Coverage Map - The entries below were derived from the section structure in `appsudo.com/doc`. Categories - Folder name - App class name - Constructor identifier - One render per app - Data binding (recommended) ===== SECTION: app-lifecycle ===== App Lifecycle Source section: `https://appsudo.com/doc#app-lifecycle` Lifecycle hooks (`#app-lifecycle-hooks`) Hook order 1. `on_launch` 2. `set_data(metadata)` 3. `run` 4. `on_ready` 5. `on_app_mode_change(app_mode)` on each later mode change Hook meanings - `on_launch`: pre-render setup and preloading. - `set_data(metadata)`: receives runtime metadata before render. - `run`: the place where the app renders itself. - `on_ready`: called after the app is fully ready. - `on_app_mode_change(app_mode)`: mode transition handler. Metadata described by the docs - `config` - decrypted secrets - `profileId` - `profileUserName` - `profileAvatar` - `appId` - `appName` - `appVersion` App modes (`#app-lifecycle-modes`) - `FULLSCREEN`: default. - `WIDGET`: small centered window. - `POPUP`: bottom dialog style view using most of the screen. - `MINIMIZE`: docked into a feed post. Mode-related rules - In `on_app_mode_change(app_mode)`, `app_mode` is the new mode. - `self.get_app_mode()` returns the previous mode. - `self.set_app_mode(mode)` can be used to change modes, except `MINIMIZE`. - Override `get_allowed_mode()` to limit supported modes. Two-way Binding (`#app-lifecycle-two-way-binding`) - Manual component updates can require assigning the same value in several places and calling methods such as `refresh()`. - Import `State` from `runtime` when one value or array needs to drive multiple components. - Create the initial `State` values in the app's data class or other class exposed through the existing inflater. - Bind a state in ASXML with expressions such as `{data.value}` and `{data.array}`. - A `State` can also be passed directly to the matching component method in Python. - Call `state.set(new_value)` to update every bound component and perform the required component refresh. - State binding keeps conditional update logic, repeated assignments, and manual refresh calls out of unrelated app code. Game Controller (`#app-lifecycle-game-controller`) - Gamepad selection applies when `metadata.json` sets `"type": "Game"`. - Override `get_gamepad()` on the `App` subclass to hide the controller or load a different controller component. - Without an override, or when `get_gamepad()` returns `"default"`, Appsudo loads the existing `sudogamepad` component. - Return `None` to completely hide the gamepad. - Return an existing component name to dynamically load that component for the game. - A custom return value must exactly match an existing component name. - Browse available component names in the Appsudo Store: `https://store.appsudo.com`. Screen Size (`#app-lifecycle-screen-size`) - Read the current display size with `AppContext.current().displaySize()`. - Use the result only for broad checks, such as determining whether the width is larger than the height for a rotated device or tablet-style layout. - Do not build complex application logic around exact dimensions. - The documentation does not prescribe width or height accessor syntax. Light/Dark Mode (`#app-lifecycle-display-mode`) - Read the current display mode from `AppRuntime.IS_DARK_MODE`. - Use it to choose theme-appropriate colors, assets, and presentation. Running Platform (`#app-lifecycle-platform`) - Detect web, Android, or iOS with the `AppRuntime` methods shown below. - Keep rendering and UI behavior platform agnostic. - Limit platform values to non-UI uses such as API request context or app-specific statistics. - Platform information is already available in the Appsudo developer portal, so most apps do not need to collect it themselves. Sharing & Data (`#app-lifecycle-sharing`) - Override `get_shareable()` to allow or block sharing to feed/DM. - Override `get_data()` to return serializable state for sharing/continuation. - Shared state is later delivered back through `set_data(metadata)`. Code Snippets From Docs - The blocks below were extracted from the corresponding section of `appsudo.com/doc`. Snippet 1 ``` def on_launch(self): # App not rendered yet. Initialize or preload data here. self.pending_user_id = None def set_data(self, metadata): # Pre-render. metadata includes config, decrypted secrets, # profileId, profileUserName, profileAvatar, appId, appName, appVersion. # Store at runtime to register users in an external DB, build a profile, etc. self.profile_id = metadata.get("profileId") self.profile_user_name = metadata.get("profileUserName") self.app_id = metadata.get("appId") def run(self): # Renders the app to the device (mobile and web). self.render() goes here. self.render(self.ui_view) def on_ready(self): # App is fully ready to perform actions. self._load_initial_state() def on_app_mode_change(self, app_mode): # app_mode = the NEW mode the app is transitioning to. # self.get_app_mode() = the PREVIOUS mode, prior to this change. # Use both to decide how to transition the visualization. self._transition(from_mode=self.get_app_mode(), to_mode=app_mode) ``` Snippet 2 ``` def on_app_mode_change(self, app_mode): # app_mode = NEW mode transitioning to # self.get_app_mode() = PREVIOUS mode, prior to this change if app_mode == "WIDGET": self._render_compact(from_mode=self.get_app_mode()) elif app_mode == "POPUP": self._render_sheet(from_mode=self.get_app_mode()) elif app_mode == "MINIMIZE": self._render_docked(from_mode=self.get_app_mode()) ``` Snippet 3 ``` def get_allowed_mode(self): return ["FULLSCREEN", "WIDGET", "POPUP"] ``` Snippet 4 ``` # Single value value = "newvalue" self.text = f"{value} - something" self.text2 = value # Array self.repeat_view.set_items(newarray) self.repeat_view.refresh() ``` Snippet 5 ``` from runtime import State # Initial state self.value = State("initial value") self.array = State([1, 2, 3]) ``` Snippet 6 ```