Skip to content

Repository files navigation

PackWrt — Build OpenWrt packages with confidence

CI MIT License Python 3.8+ Zero dependencies OpenWrt 24.10 and 25.12+

Scaffold. Validate. Build. Test.
A zero-dependency AI skill for reliable OpenWrt package development.

Quick start · Install · 简体中文 · Contribute

An AI skill for developing, packaging and testing OpenWrt packages — CLI tools, daemons, kernel modules and LuCI web apps — with as few moving parts as possible.

Give a coding agent this skill and the sentence "write me a LuCI app that shows interface traffic and build it" becomes: correct package tree, correct Makefile, working ACL wiring, a static check that catches the mistakes before a build, and an artifact you can install.

中文文档见 README.zh-CN.md.

Why this exists

Three things routinely break OpenWrt package development, and all three are invisible until a build or a device tells you the hard way:

  1. The package manager changed. OpenWrt 24.10 and older uses opkg and produces .ipk. OpenWrt 25.12 and newer uses apk and produces .apk. The same Makefile drives both; picking the wrong target release invalidates the whole effort.
  2. Recipe lines must be indented with a real TAB. Spaces give missing separator and, worse, sometimes appear to work.
  3. Windows and macOS cannot compile OpenWrt packages. There is no way around a Linux toolchain — but scaffolding, static validation and artifact inspection need none of it, and the actual compile can run in Docker or in CI.

This skill encodes all of that, plus the licence metadata rules, plus a validator that catches roughly 25 real failure modes before you spend build time.

Requirements

Component Requirement
Python 3.8 or newer, standard library only
The skill's own tooling works on Windows, macOS, Linux — no Docker, no network
Compiling packages any one of: Docker, GitHub Actions, or a native Linux host

Nothing is installed by this project. There is no pip install step.

Measured on Windows with Python 3.13, where the interpreter startup alone is ~0.32 s: scaffold_package.py takes ~0.31 s, validate_package.py over 20 packages takes ~0.32 s, and the whole 44-test suite takes ~6 s. In other words runtime is dominated by Python process startup, not by this tooling.

Install

The complete install reference - every platform, verification, update, uninstall and troubleshooting - lives in INSTALL.md. AI agents should read AGENTS.md instead: it has the same commands plus the rules for not inventing facts.

A — skills directory (recommended; the agent picks it up automatically)

git clone https://github.com/cndoin/packwrt.git
cp -r REPO ~/.workbuddy/skills/packwrt

On Windows PowerShell:

git clone https://github.com/cndoin/packwrt.git
Copy-Item -Recurse REPO "$HOME\.workbuddy\skills\packwrt"

B — from the packaged zip (unzip into ~/.workbuddy/skills/)

make package     # writes dist/packwrt.zip

C — clone straight in

git clone https://github.com/cndoin/packwrt.git ~/.workbuddy/skills/packwrt

Verify the install:

python ~/.workbuddy/skills/packwrt/scripts/check_env.py

Quick start

# 1. What can this machine actually do?
python scripts/check_env.py

# 2. Generate a package tree (pick a type)
python scripts/scaffold_package.py \
    --type luci-app --name luci-app-myapp --title "MyApp" \
    --version 1.0.0 --license GPL-2.0-only \
    --maintainer "Your Name <you@example.com>" \
    --out ./my-feed

# 3. Catch the mistakes before spending build time
python scripts/validate_package.py ./my-feed

# 4. Compile it — Linux/macOS/WSL/Git-Bash
./my-feed/build-in-docker.sh
#    or Windows PowerShell
.\my-feed\build-in-docker.ps1
#    or, with no Docker at all: push and let the generated CI workflow build it

# 5. Check the artifact without a device
python scripts/inspect_artifact.py my-feed/bin/packages/*/*/*.apk

Generated package types:

--type Produces
luci-app LuCI app: JS views, menu.d, acl.d, ucode rpcd backend, uci-defaults, config
c-binary Plain C CLI tool built from bundled source
c-daemon C daemon + procd init script + UCI config + uci-defaults + postinst wiring
script Shell/Python script package (PKGARCH:=all)
library Shared library with Build/InstallDev so other packages can link it
kernel-module kmod package (requires a full buildroot, not the SDK)

Tooling

Script What it does Needs Docker?
scripts/check_env.py Reports which build route this machine can use no
scripts/scaffold_package.py Generates the whole package tree from 27 templates no
scripts/validate_package.py Static analysis; exits non-zero on real problems no
scripts/inspect_artifact.py Parses a built .ipk/.apk, runs the upstream CI checks no
scripts/fix_exec_bits.py Fixes the executable bit on filesystem and git index no

Every script is standard-library Python and writes LF-only UTF-8.

Build routes

Route Use when Cost
Docker SDK container Docker available (any OS) first run pulls 1–2 GB
GitHub Actions no Docker / no Linux host needs a GitHub repo
native Linux buildroot/SDK repeated builds on Linux large disk, toolchain build

scaffold_package.py emits a working example of each: build-in-docker.sh (Linux/macOS/WSL/Git Bash), build-in-docker.ps1 (Windows), and .github/workflows/build-package.yml (GitHub Actions, uses openwrt/gh-action-sdk).

Cross-platform notes

These are the things that actually differ between systems, and how the skill handles them:

Hazard Handling
Console codepage crashes on non-ASCII paths every script reconfigures stdout/stderr to UTF-8 with errors="replace"
CRLF sneaking into generated Makefiles/scripts all output is written with newline="\n"; .gitattributes normalises the repo; a test asserts the repo has no CRLF
Windows has no POSIX mode bits fix_exec_bits.py sets the bit in the git index (update-index --chmod=+x), which is what travels to GitHub
LuCI root/ payloads are copied with cp -pR a missing exec bit means an init or uci-defaults script silently does not run — hence the check above
Windows path separators in reports and mounts reports print POSIX paths; build-in-docker.sh converts the mount path via cygpath under MSYS/Cygwin
macOS/Windows cannot run a Linux toolchain check_env.py says so explicitly and points at CI instead of failing later
docker present but the engine not running detected specifically, because a bare which docker check passes and every build then fails

Repository layout

.
├── SKILL.md                     # the agent-facing skill (five-phase workflow)
├── references/                  # loaded on demand
│   ├── makefile-reference.md
│   ├── luci-app-guide.md
│   ├── build-and-test.md
│   ├── licensing.md
│   └── troubleshooting.md
├── scripts/                     # standard-library Python tools
├── samples/                     # reference packages (luci-app-netmon, netmon-agent)
├── tests/test_skill.py          # 44 checks, runs on all three platforms
├── assets/templates/            # 27 templates; the single source of packaging truth
└── .github/workflows/ci.yml     # Ubuntu + macOS + Windows, Python 3.10 and 3.13

Design invariants

Contributions must preserve these — CI enforces most of them:

  • Standard library only; no pip install, no network access at runtime.
  • Templates are pure ASCII and LF-only; they are copied verbatim into packages.
  • Makefile recipe lines use TABs.
  • SKILL.md stays lean; detail lives in references/.
  • The validator has no false positives on freshly scaffolded output, and every rule has a negative test.

See CONTRIBUTING.md.

Scope and honesty

  • Verified against OpenWrt 24.10 (opkg/.ipk) and 25.12+ (apk/.apk).
  • Kernel modules require a full buildroot; the standalone SDK cannot build them.
  • The tooling performs static checks and artifact inspection. It does not replace installing the package on a real device — treat a green validator as "worth building", not "proven working".

Licence

MIT.

About

AI skill and zero-dependency toolkit for scaffolding, validating, building, and testing OpenWrt packages.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages