Course To Appimage logo

Course To Appimage

Community
sebastianhaba
course-to-appimage

Package an existing interactive course generated by the book-to-course skill (a folder with index.html, assets/ and course/data.js, or its .zip) into a self-contained Linux AppImage — one file that carries its own WebView engine (Electron), so it runs on any desktop distro without installing anything, keeps progress in a file and can run code exercises' tests. Checks the build tools on the machine (appimagetool, Electron, AppImage runtime), tells the user exactly what is missing and where to get it, and can download it for them. Use this whenever the user wants a course "na Linuxa", "jako aplikację na pulpit/desktop", "w menu aplikacji", "zrób z kursu AppImage", "course to appimage", wants a course app they can copy to another Linux computer, wants to open their generated course like a normal program instead of start.sh, or wants to rebuild/update the course app after adding chapters — even if they don't say "AppImage" explicitly. Do NOT use for building a course from a book (that is book-to-course), for Android (course-to-apk), Windows/macOS installers, Flatpak/Snap/.deb packaging, or general Linux/Electron app development.

Overview

Publishersebastianhaba
Repositorybook-to-course-skill
Skill namecourse-to-appimage
Stars
73
Forks
16
Bundled files
8
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 8 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by sebastianhaba on GitHub. Read the source before you install it.

Installation

Install the Course To Appimage AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/sebastianhaba/book-to-course-skill/tree/main/course-to-appimage
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/sebastianhaba/book-to-course-skill.git /tmp/book-to-course-skill
mkdir -p .claude/skills
cp -r /tmp/book-to-course-skill/course-to-appimage .claude/skills/course-to-appimage
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Course To Appimage in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Course To Appimage on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Course To Appimage is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Course → Linux AppImage

Wraps a finished book-to-course course into one executable file for Linux, self-contained like the APK: copy it to any desktop Linux computer and start it — no Python, no WebKitGTK, nothing to install. Inside: the official Electron build (Chromium + Node), a small main.js, the course, an icon and the Noto Color Emoji font (the player's UI uses emoji, and many distros ship no emoji font). main.js does what the course's serve.py does — serves the page on 127.0.0.1, saves progress to a file and runs code exercises' tests — so the "Run tests" button works on the desktop (unlike the phone app). Nothing is compiled; the AppImage is ~105 MB + the course (that's Chromium; unused Chromium translations are left out) + ~9 MB for the emoji font.

Why Electron and not the system WebView: Linux has no WebView every computer is guaranteed to have, and bundling this machine's WebKitGTK would tie the file to this distro's glibc. Official Electron builds run on any current desktop distro.

The wrapper and the scripts are fixed and tested — your job is the conversation around them: find the course, get the toolchain in place with the user's consent, build, and explain how to start and install the app.

script (in scripts/)purpose
toolchain.py [--json]what is installed, what is missing, where to download it; exit 0 = ready
setup_toolchain.py --dry-runlist exactly what would be downloaded (name, size, URL) — downloads nothing
setup_toolchain.py --downloaddownload only the missing parts into ~/.local/share/course-to-appimage (no sudo, SHA-256 verified)
build_appimage.py COURSE_DIR [--install]build the AppImage into <COURSE_DIR>-appimage/; --install adds it to the app menu
build_appimage.py COURSE_DIR --uninstallremove the menu entry, icon and ~/Applications copy (progress stays)

All scripts are Python 3 standard library only (Python is needed on the build machine, not in the app).

Workflow

1. Find the course

A course folder has index.html, assets/app.js and course/data.js. Look where the user points, in the current directory, or among recent book-to-course output. If they give a .zip (from pack_course.py), unzip it next to the zip first — it contains one top folder named after the course; that folder is COURSE_DIR. If content/ exists but course/data.js is missing or older than the lessons, the course was not rebuilt — run book-to-course's build_course.py COURSE_DIR first (when that skill is available), otherwise ask the user to.

2. Check the toolchain

bash
python3 scripts/toolchain.py

Needed: appimagetool (packs the file), Electron 30+ (the engine, ~115 MB official zip — an unpacked folder or the zip itself, found in Downloads, ~/.cache/electron, $ELECTRON_DIST or the skill's own folder) and the Noto Color Emoji font (taken from the system's fonts when installed — usually it is — otherwise a pinned ~10 MB download). The runtime file is optional. It checks that appimagetool actually starts. If it prints READY, go to step 4 (if only the runtime is missing, mention in one line that the build will fetch it from GitHub — don't stop for it).

3. Something is missing → ask, don't assume

Tell the user, in their language, what is missing — use the report's lines, they already contain the official download links (GitHub releases of AppImage/appimagetool, electron/electron and AppImage/type2-runtime, googlefonts/noto-emoji) and package-manager commands. Run setup_toolchain.py --dry-run so you can quote the real sizes, versions and URLs, then ask them to choose (AskUserQuestion works well here):

  • "I'll install it myself" — give a short checklist: what to download, from where, and where to put it (appimagetool: chmod +x, e.g. as ~/.local/bin/appimagetool; Electron: the electron-vX.Y.Z-linux-x64.zip — arm64 on ARM — can simply stay in Downloads, the build unpacks it). Warn that the distro's electron package is not suitable (built against this system's libraries). Then stop and wait — end your turn. Do not poll, do not build, do not download anything. When they write that it's done, rerun toolchain.py; if something is still missing or "found but unusable", say exactly what and wait again.
  • "Download it for me" — run python3 scripts/setup_toolchain.py --download (~140 MB when everything is missing; official GitHub releases — MIT, the font OFL — checksums verified; installs only into ~/.local/share/course-to-appimage, no sudo). It is a one-time download — later builds reuse it.

Why the care: downloading over 100 MB and running a binary are the user's decisions, not yours, and a user who said they'd install it themselves is mid-installation — building or downloading behind their back collides with that.

4. Build

bash
python3 scripts/build_appimage.py "<COURSE_DIR>"

Takes a few seconds. Defaults that are right for almost everyone — mention them, don't ask:

  • Output <COURSE_DIR>-appimage/<course-id>-<arch>.AppImage, next to the course folder; appimage.json there remembers the app id, name, icon colour and an auto-incremented version.
  • App id net.booktocourse.<course_id>, name = course title. Override with --app-id / --name only when asked — the app id names the learner's data folder, so changing it later starts with empty progress.
  • Built for this machine's architecture (x86_64 or aarch64 — Electron has no 32-bit Linux build).

Offer --install (copies the AppImage to ~/Applications, adds a menu entry with icon under Education, no sudo) — ask in the same message as the hand-over if the user hasn't said; it's quick to do afterwards by rerunning with --install. Once installed, every later build refreshes the installed copy automatically.

The build ends with a self-test (it starts the AppImage with --paths, which loads Electron and main.js). If the build or the self-test fails, the output says what failed; see references/troubleshooting.md.

5. Hand it over

Tell the user in a few lines: where the AppImage is (absolute path), its size, and how to start it:

  • double-click it in the file manager, or ./<file>.AppImage in a terminal. On another computer: copy the one file (USB stick, cloud drive, network); if it lost the executable bit, chmod +x / Properties → "Allow executing as program".
  • with --install: from the application menu (Education), with its own icon.

Also say, briefly:

  • Progress lives in ~/.local/share/<app-id>/progress/progress.json of whoever runs the app (not in the course folder's progress/ — the page's footer wording comes from the folder version). It survives updates: rebuild after adding chapters and start the new file.
  • Code exercises (if the course has them) work fully, unlike on the phone: the AppImage is an ordinary program on the computer, so "Run tests" runs the exercise's command (e.g. go test) with the compiler installed there — exactly like start.sh. The learner edits the files in their own editor; editable copies live in ~/.local/share/<app-id>/exercises/, and each exercise in the app shows that full path, an "Open folder" button and a ready cd … command. The language toolchain (e.g. Go) must be installed on that computer — without it the page says the program is not installed. Bundling compilers is not done: hundreds of MB per language. Lessons, quizzes, tests and flashcards need nothing.
  • Requirements of the target: a desktop Linux (x86_64/arm64 as built) — the usual desktop libraries (GTK 3, NSS, X11/ Wayland, ALSA) that every GNOME/KDE/XFCE/Cinnamon install has, as for any Electron app. A bare server/container without a desktop lacks them.

What the app does (so you can answer questions)

  • AppRun starts the bundled Electron; where unprivileged user namespaces are blocked (e.g. Ubuntu 24.04's AppArmor default) or when run as root, it adds --no-sandbox, because an AppImage cannot carry Chromium's setuid sandbox helper. The window only shows the bundled course; links to other sites open in the user's own browser.
  • main.js serves the course on 127.0.0.1 with the same API as serve.py (/api/ping, /api/progress, /api/run-tests; host check; the test command comes from exercise.json, only the folder name from the page), on a port derived from the app id so the page's localStorage (theme) survives restarts.
  • In exercise blocks it replaces the player's relative "exercises//" and "cd exercises/" (meant for the course folder) with the real path, adds an "Open folder" button (/api/open-exercise) and makes the copy button copy the fixed command.
  • AppRun points fontconfig at a config that includes the system's /etc/fonts/fonts.conf plus the bundled emoji font as a fallback; the system's own emoji font still wins where installed.
  • On start it copies new exercises and refreshes each exercise's exercise.json and test files; the learner's own files are never overwritten. _solution/ folders are not packed, and the starter files are taken from course/data.js (what the page shows as start files), because the course folder's exercises/ may hold someone's solved versions. It adds common toolchain dirs (~/go/bin, /usr/local/go/bin, ~/.cargo/bin, …) to PATH, since a desktop session's PATH often lacks them.
  • One instance per app (a second start focuses the window). Ctrl +/−/0 zoom, Ctrl+R reload, F11 full screen; window size and zoom are remembered. Chromium's data lives in ~/.local/share/<app-id>/electron.
  • Options: --paths, --open-exercises.

To change the wrapper, edit assets/app/main.js (Electron main process, Node standard library only — there is no npm step) or assets/appdir/AppRun.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Course To Appimage AI skill do?

Package an existing interactive course generated by the book-to-course skill (a folder with index.html, assets/ and course/data.js, or its .zip) into a self-contained Linux AppImage — one file that carries its own WebView engine (Electron), so it runs on any desktop distro without installing anything, keeps progress in a file and can run code exercises' tests. Checks the build tools on the machine (appimagetool, Electron, AppImage runtime), tells the user exactly what is missing and where to get it, and can download it for them. Use this whenever the user wants a course "na Linuxa", "jako a...

Why use Course To Appimage on TypingMind?

Because you install it once and use it with any model. Course To Appimage is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Course To Appimage in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/sebastianhaba/book-to-course-skill/tree/main/course-to-appimage. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Course To Appimage?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Course To Appimage?

As many as you like. As long as a model supports skills, you can use Course To Appimage with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Course To Appimage AI skill free?

Yes. It is published on GitHub by sebastianhaba under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇