From 7aefdbd330baedf7a1f2ec7da93dbfc45e65d6f9 Mon Sep 17 00:00:00 2001 From: lingyuzeng Date: Sun, 1 Mar 2026 14:29:45 +0800 Subject: [PATCH] docs: add AGENTS.md - comprehensive reference for AI agents --- docs/AGENTS.md | 601 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 601 insertions(+) create mode 100644 docs/AGENTS.md diff --git a/docs/AGENTS.md b/docs/AGENTS.md new file mode 100644 index 0000000..5d5f388 --- /dev/null +++ b/docs/AGENTS.md @@ -0,0 +1,601 @@ +# AGENTS.md - AI Agent Reference Guide for openwrt-ci-ipq60xx + +> This document is a comprehensive reference for AI agents working with this repository. +> Last updated: 2026-03-01 + +--- + +## Project Overview + +This is a **build-orchestration repository** for OpenWrt/ImmortalWrt IPQ60XX firmware using Woodpecker CI. + +### Key Characteristics + +| Aspect | Description | +|--------|-------------| +| Type | CI pipeline configuration (NOT a source code repo) | +| Target Platform | Qualcomm IPQ60XX routers | +| Firmware Source | `VIKINGYFY/immortalwrt.git` (main branch) | +| CI System | Woodpecker | +| Config Source | VIKINGYFY/OpenWRT-CI + davidtall/OpenWRT-CI | + +--- + +## Architecture: Three-Layer Model + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Layer 1: SOURCE (Firmware Code) │ +├─────────────────────────────────────────────────────────────────┤ +│ Repository: VIKINGYFY/immortalwrt │ +│ Branch: main │ +│ Cloned: During CI build (git clone) │ +│ Purpose: Provides OpenWrt/ImmortalWrt source code │ +└─────────────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────────┐ +│ Layer 2: CI-TEMPLATE (Config Templates) │ +├─────────────────────────────────────────────────────────────────┤ +│ Device Sets (Fixed files in repo): │ +│ - Config/IPQ60XX-WIFI-YES.txt (VIKINGYFY source) │ +│ - Config/IPQ60XX-WIFI.txt (davidtall source) │ +│ │ +│ General Config (Dynamic, fetched at build time): │ +│ - Config/GENERAL.upstream.txt (from davidtall/OpenWRT-CI) │ +│ Downloaded by Scripts/sync_upstream_config.sh │ +└─────────────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────────┐ +│ Layer 3: YOUR-DELTA (Local Customizations) │ +├─────────────────────────────────────────────────────────────────┤ +│ Config/GENERAL.local.txt - Your package additions │ +│ Scripts/Packages.sh - Custom package cloning │ +│ Scripts/Handles.sh - Package tweaks/fixes │ +│ Scripts/Settings.sh - kconfig/custom settings │ +│ files/ - Rootfs overlay files │ +│ │ +│ IMPORTANT: Only edit files in this layer! │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Woodpecker Build Flow + +### Build Steps (.woodpecker/ipq60xx.yml) + +``` +1. init-env + └─> Install build dependencies + └─> Run ImmortalWrt init script + +2. sync-configs + └─> Execute Scripts/sync_upstream_config.sh + └─> Download Config/GENERAL.upstream.txt + +3. build-ipq60xx-wifi-yes + ├─> Clone firmware source (VIKINGYFY/immortalwrt) + ├─> feeds update -a && feeds install -a + ├─> Execute Scripts/Packages.sh Handles.sh + ├─> Merge configs: IPQ60XX-WIFI-YES.txt + GENERAL.upstream.txt + GENERAL.local.txt + ├─> Execute Scripts/Settings.sh + ├─> make defconfig -> make download -> make + └─> Copy output to artifacts/ipq60xx-wifi-yes/ + +4. build-ipq60xx-wifi + └─> Same as above, using IPQ60XX-WIFI.txt + └─> Copy output to artifacts/ipq60xx-wifi/ +``` + +### Config Merging Order + +During build, `.config` is assembled by concatenating in this order: + +```bash +cat Config/IPQ60XX-WIFI-*.txt \ + Config/GENERAL.upstream.txt \ + Config/GENERAL.local.txt > .config +``` + +**Rule**: Later entries override earlier ones. +- Device config settings have lowest priority +- Upstream GENERAL can override device config +- Your LOCAL overrides have highest priority + +--- + +## File Structure Reference + +``` +openwrt-ci-ipq60xx/ +│ +├── .woodpecker/ +│ └── ipq60xx.yml # Woodpecker pipeline definition +│ +├── Config/ +│ ├── IPQ60XX-WIFI-YES.txt # Device set A (static, 21 devices) +│ ├── IPQ60XX-WIFI.txt # Device set B (static, 9 devices) +│ ├── GENERAL.upstream.txt # Fetched at build time (DO NOT EDIT) +│ └── GENERAL.local.txt # YOUR package additions (EDIT THIS) +│ +├── Scripts/ +│ ├── sync_upstream_config.sh # Fetch GENERAL.txt from upstream +│ ├── Packages.sh # Clone custom GitHub packages +│ ├── Handles.sh # Apply fixes to packages +│ └── Settings.sh # kconfig and customization +│ +├── files/ # Rootfs overlay (optional) +├── artifacts/ # Build outputs (gitignored) +├── docs/ +│ ├── SKILLS.md # User-facing documentation +│ └── AGENTS.md # THIS FILE - Agent reference +│ +├── README.md # Project README +└── .gitignore +``` + +--- + +## Scripts Detailed Reference + +### Scripts/sync_upstream_config.sh + +**Purpose**: Download GENERAL.txt from upstream davidtall/OpenWRT-CI + +**Functions**: +```bash +# Variable: COMMIT to pin to specific version (optional, defaults to 'main') +UPSTREAM_GENERAL_REF="${UPSTREAM_GENERAL_REF:-main}" + +# Download target +https://raw.githubusercontent.com/davidtall/OpenWRT-CI/${UPSTREAM_GENERAL_REF}/Config/GENERAL.txt +``` + +**When to modify**: +- If upstream repository changes +- If you want to change default branch + +--- + +### Scripts/Packages.sh + +**Purpose**: Clone custom GitHub packages to override feed packages + +**Key Function**: `UPDATE_PACKAGE` + +```bash +UPDATE_PACKAGE "PKG_NAME" "USER/REPO" "BRANCH" ["MODE"] ["ALIAS_LIST"] +``` + +**Parameters**: +| Parameter | Description | Example | +|-----------|-------------|---------| +| PKG_NAME | Package name to find/delete | "argon" | +| USER/REPO | GitHub repo | "sbwml/luci-theme-argon" | +| BRANCH | Git branch | "openwrt-25.12" | +| MODE | Optional: "pkg" or "name" | "pkg" | +| ALIAS_LIST | Optional: space-separated aliases | "appfilter oaf" | + +**Modes**: +- `pkg`: Extract package from multi-package repo +- `name`: Rename cloned directory to PKG_NAME +- (empty): Use repo name as-is + +**Current Packages** (lines 48-76): +- Themes: argon, aurora, kucat (+ configs) +- Proxy: homeproxy, momo, nikki, openclash, passwall, passwall2 +- Network: tailscale, easytier, vnt +- Tools: ddns-go, diskman, fancontrol, partexp, quickfile +- Storage: qbittorrent, gecoosac +- DNS: mosdns, openlist2 +- Misc: qmodem, viking (timewol, wolplus) +- Speedtest: netspeedtest (+ homebox, speedtest) + +**Function**: `UPDATE_VERSION` (lines 79-117) + +Updates package version from GitHub releases: +```bash +UPDATE_VERSION "PKG_NAME" [false] # false=stable only, true=includes prerelease +``` + +Currently updates: `sing-box` + +--- + +### Scripts/Handles.sh + +**Purpose**: Apply various fixes and customizations to packages + +**Handles** (in order): + +| Handle | Target | Action | +|--------|--------|--------| +| homeproxy | `$PKG_PATH/homeproxy` | Clone surge-rules, generate IP lists | +| luci-theme-argon | Theme colors | Set primary color, font weight | +| luci-app-aurora-config | Menu style | Set nav_submenu_type to boxed-dropdown | +| qca-nss-drv | Init script | Set START=85 | +| qca-nss-pbuf | Init script | Set START=86 | +| tailscale | Makefile | Remove /files to avoid config conflict | +| rust | Makefile | Disable ci-llvm (fix compile fail) | +| diskman | Makefile | Remove ntfs-3g-utils dependency | +| netspeedtest | Defaults/speedttest | Add exit 0, fix cert bundle | + +**Variable Dependency**: Uses `$PKG_PATH` (expected to be `$GITHUB_WORKSPACE/wrt/package/`) + +**Note**: Some handles check directory presence with `if [ -d *"name"* ]` glob pattern + +--- + +### Scripts/Settings.sh + +**Purpose**: Apply kconfig settings and custom modifications + +**Areas Modified**: + +1. **LuCI**: + - Remove luci-app-attendedsysupgrade + - Change default theme (via `$WRT_THEME`) + - Set immortalwrt.lan IP (via `$WRT_IP`) + - Add build date marker (via `$WRT_MARK, $WRT_DATE`) + +2. **WiFi** (auto-detect): + - Files: `set-wireless.sh` or `mac80211.uc` + - Set SSID (`$WRT_SSID`) + - Set password (`$WRT_WORD`) + - Set country: CN + - Set encryption: psk2+ccmp + +3. **Network** (via `config_generate`): + - Default IP (`$WRT_IP`) + - Hostname (`$WRT_NAME`) + +4. **General Config additions**: + - `CONFIG_PACKAGE_luci=y` + - `CONFIG_LUCI_LANG_zh_Hans=y` + - Theme packages (via `$WRT_THEME`) + +5. **Custom packages** (via `$WRT_PACKAGE`): + - If non-empty, append line by line to .config + +6. **Qualcomm IPQ60XX specific** (via `$WRT_TARGET, $WRT_CONFIG`): + - Disable NSS feeds + - Enable sqm-nss + - Set NSS firmware version (11.4=n, 12.2 for IPQ50xx, 12.5 for others) + - Handle "nowifi" variants by modifying DTS includes + - Enable `kmod-usb-serial-qualcomm` + +**Environment Variables Expected**: +- `$WRT_THEME`, `$WRT_IP`, `$WRT_MARK`, `$WRT_DATE` +- `$WRT_SSID`, `$WRT_WORD`, `$WRT_NAME` +- `$WRT_PACKAGE`, `$WRT_TARGET`, `$WRT_CONFIG` + +**Important**: This script does NOT declare these variables - they must be set before calling. + +--- + +## How to Modify Packages + +### Step 1: Check if package exists in feeds + +If yes → Add to `Config/GENERAL.local.txt`: +```makefile +CONFIG_PACKAGE_luci-app-mypackage=y +``` + +If no or needs specific version → Edit `Scripts/Packages.sh` + +### Step 2: Add package in Scripts/Packages.sh + +**Basic clone**: +```bash +UPDATE_PACKAGE "mypackage" "username/mypackage-repo" "main" +``` + +**With aliases (to delete conflicting packages)**: +```bash +UPDATE_PACKAGE "open-app-filter" "destan19/OpenAppFilter" "master" "" "luci-app-appfilter oaf" +``` + +**Extract from multi-package repo**: +```bash +UPDATE_PACKAGE "openclash" "vernesong/OpenClash" "dev" "pkg" +``` + +**Rename cloned directory**: +```bash +UPDATE_PACKAGE "custom-name" "user/repo" "branch" "name" +``` + +### Step 3: Add fixes in Scripts/Handles.sh (if needed) + +Create a handle block: +```bash +if [ -d *"mypackage"* ]; then + echo " " + cd ./mypackage/ + # Apply fixes here with sed/cp/mv + cd $PKG_PATH && echo "mypackage has been fixed!" +fi +``` + +### Step 4: Add config in Settings.sh (optional) + +If package needs kconfig flags, add after custom packages section: + +```bash +# My package specific settings +echo "CONFIG_PACKAGE_kmod-mymodule=y" >> ./.config +``` + +--- + +## Common Tasks for Agents + +### Task: Add a new LuCI app from feeds + +```bash +# 1. Edit Config/GENERAL.local.txt +echo "CONFIG_PACKAGE_luci-app-newapp=y" >> Config/GENERAL.local.txt + +# 2. Commit changes +git add Config/GENERAL.local.txt +git commit -m "add: luci-app-newapp" +git push +``` + +### Task: Add a custom package from GitHub + +```bash +# 1. Edit Scripts/Packages.sh (Add line 48-76 area) +# Add: +# UPDATE_PACKAGE "newpackage" "user/newpackage-repo" "main" + +# 2. If needed, add fix to Scripts/Handles.sh +# 3. Commit and push +``` + +### Task: Update an existing package version + +```bash +# 1. Edit Scripts/Settings.sh if version needs kconfig change +# 2. Edit Scripts/Packages.sh UPDATE_VERSION call +# 3. OR add new UPDATE_VERSION call: +# UPDATE_VERSION "newpackage" +# 4. Commit and push +``` + +### Task: Pin GENERAL.txt to specific commit + +```bash +# Option A: Add to Woodpecker CI variables +# Variable: UPSTREAM_GENERAL_REF = + +# Option B: Modify sync_upstream_config.sh default +# Edit line 6: UPSTREAM_GENERAL_REF="${UPSTREAM_GENERAL_REF:-main}" +# Change 'main' to commit hash +``` + +### Task: Add a specific device configuration + +```bash +# 1. Find the device target from openwrt menuconfig +# 2. Add to appropriate config file (IPQ60XX-WIFI-YES.txt or IPQ60XX-WIFI.txt): +# CONFIG_TARGET_DEVICE_qualcommax_ipq60xx_DEVICE_=y +# 3. Commit and push +``` + +### Task: Debug build failure + +```bash +# 1. Check Woodpecker logs +# 2. Identify failing step +# 3. Review error messages in CI log +# 4. Check if upstream GENERAL.upstream.txt has breaking changes +# 5. Try pinning to previous commit with UPSTREAM_GENERAL_REF +# 6. Add custom override in GENERAL.local.txt +``` + +--- + +## Build Targets Reference + +### IPQ60XX-WIFI-YES (21 devices) + +Source: VIKINGYFY/OpenWRT-CI + +Devices: +- anysafe_e1, cmiot_ax18, glinet_gl-ax1800, glinet_gl-axt1800 +- jdcloud_re-cs-02, jdcloud_re-ss-01 +- link_nn6000-v1, link_nn6000-v2, linksys_mr7350, linksys_mr7500 +- philips_ly1800, qihoo_360v6 +- redmi_ax5, redmi_ax5-jdcloud +- sy_y6010, xiaomi_ax1800 +- zn_m2 + +### IPQ60XX-WIFI (9 devices) + +Source: davidtall/OpenWRT-CI + +Devices: +- cmiot_ax18, jdcloud_re-ss-01, jdcloud_re-cs-02 +- qihoo_360v6, redmi_ax5-jdcloud, redmi_ax5 +- xiaomi_ax1800, zn_m2 + +Includes: +- Kernel cgroup configs +- NSS configurations (disabled feeds, sqm-nss enabled) +- Memory profiles (512MB) + +--- + +## Environment Variables Reference + +### Woodpecker Pipeline Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| WRT_REPO | https://github.com/VIKINGYFY/immortalwrt.git | Firmware source repo | +| WRT_BRANCH | main | Firmware source branch | +| UPSTREAM_GENERAL_REF | main | GENERAL.txt version | + +### Scripts Settings.sh Variables + +| Variable | Purpose | Example | +|----------|---------|---------| +| WRT_THEME | LuCI theme name | argon | +| WRT_IP | Default IP | 192.168.1.1 | +| WRT_MARK | Build marker | Custom | +| WRT_DATE | Build date | Date string | +| WRT_SSID | WiFi SSID | MyRouter | +| WRT_WORD | WiFi password | password123 | +| WRT_NAME | Hostname | OpenWrt | +| WRT_PACKAGE | Custom packages | Multi-line string | +| WRT_TARGET | Target platform | QUALCOMMAX | +| WRT_CONFIG | Config variant | ipq60xx | + +### Scripts Handles.sh Variables + +| Variable | Purpose | Expected | +|----------|---------|----------| +| PKG_PATH | Package path | `$GITHUB_WORKSPACE/wrt/package/` | +| GITHUB_WORKSPACE | CI workspace | Set by Woodpecker | + +--- + +## Troubleshooting Guide + +### Issue: Build fails after upstream GENERAL.txt update + +**Symptoms**: New errors appeared without local changes + +**Causes**: +1. Upstream added conflicting config +2. Upstream removed a package you depended on + +**Solutions**: +```bash +# Fast fix - Pin to previous working commit +UPSTREAM_GENERAL_REF= + +# Permanent fix - Override in GENERAL.local.txt +# Add the conflicting option with your desired value +``` + +### Issue: $4: unbound variable error + +**Symptoms**: Packages.sh fails with unbound variable + +**Cause**: UPDATE_PACKAGE called without 4th/5th parameter using set -u + +**Solution**: Already fixed in current version using `${4:-}` default + +### Issue: Package not found despite being in Packages.sh + +**Symptoms**: Package missing in final firmware + +**Checklist**: +1. Verify UPDATE_PACKAGE has correct repo URL +2. Check if branch exists +3. Look for error in Woodpecker git clone logs +4. Verify package name matches expected directory + +### Issue: Handles.sh not applying fix + +**Symptoms**: Expected modifications not present + +**Checklist**: +1. Verify `$PKG_PATH` is set correctly +2. Check glob pattern matches: `if [ -d *"packagename"* ]` +3. Verify handle is in correct directory after cd + +--- + +## CI/CD Operations + +### Triggering Builds + +| Trigger | Command/UI | +|---------|------------| +| Manual | Woodpecker UI > Run Pipeline | +| Push | git push to main branch | +| Cron | Woodpecker UI > Schedules (configured separately) | + +### Artifact Locations + +After successful build: +- `artifacts/ipq60xx-wifi-yes/targets/qualcommax/ipq60xx/` +- `artifacts/ipq60xx-wifi/targets/qualcommax/ipq60xx/` + +Contains: +- `*-sysupgrade.bin` - Main firmware image +- `*-factory.bin` - Factory flash image (if available) +- Other device-specific files + +--- + +## Maintenance Guidelines + +### When upstream changes break builds + +1. **Enable debug**: Add `V=s` to make command (already present) +2. **Identify failure**: Check Woodpecker logs step by step +3. **Pin version**: Set `UPSTREAM_GENERAL_REF` to last known good commit +4. **Report issue**: Document in this AGENTS.md +5. **Create fix**: Add override or modify scripts + +### Adding new package categories + +1. Group related packages in Packages.sh with comments +2. Document in this file under "Current Packages" +3. Update README.md if user-facing + +### Updating this document + +When making changes that affect this doc: +1. Update relevant sections +2. Increment Last Updated date at top +3. Commit with message: `docs: update AGENTS.md` + +--- + +## Version History + +| Date | Change | +|------|--------| +| 2026-03-01 | Initial document created with full project reference | + +--- + +## Quick Command Reference + +```bash +# Sync upstream config locally (test) +cd Scripts && ./sync_upstream_config.sh + +# Test config merge +cat Config/IPQ60XX-WIFI-YES.txt Config/GENERAL.upstream.txt Config/GENERAL.local.txt > test.config + +# Fix a package in Handles.sh pattern +if [ -d *"packagename"* ]; then + echo " " + cd ./packagename/ + # Your fix here + cd $PKG_PATH && echo "fixed!" +fi + +# Add package in Packages.sh format +UPDATE_PACKAGE "name" "user/repo" "branch" ["mode"] ["alias1 alias2"] + +# Add feed package to config +echo "CONFIG_PACKAGE_luci-app-pkgname=y" >> Config/GENERAL.local.txt +``` + +--- + +## External References + +- [VIKINGYFY/immortalwrt](https://github.com/VIKINGYFY/immortalwrt) +- [VIKINGYFY/OpenWRT-CI](https://github.com/VIKINGYFY/OpenWRT-CI) +- [davidtall/OpenWRT-CI](https://github.com/davidtall/OpenWRT-CI) +- [Woodpecker CI Docs](https://woodpecker-ci.org/docs) +- [ImmortalWrt Build Scripts](https://build-scripts.immortalwrt.org)