Use when the user asks to build, compile, rebuild, or clean a TuyaOS (tuyaos-legacy) app — including Chinese prompts like「编译 tuyaos xxx 应用」 「清理编译产物」「重新编译当前 app」, or English "build/compile/clean the TuyaOS app". Also use when adding custom .c/.h paths to apps/*/local.mk, wiring directories under software/TuyaOS/vendor/, or fixing missing headers / undefined references after adding sources. Runs build_app.sh/bat like Project Details Build / Clean. Do NOT use for TuyaOpen (tos.py) or flash/monitor.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Use when the user asks to build, compile, rebuild, or clean a TuyaOS (tuyaos-legacy) app — including Chinese prompts like「编译 tuyaos xxx 应用」 「清理编译产物」「重新编译当前 app」, or English "build/compile/clean the TuyaOS app". Also use when adding custom .c/.h paths to apps/*/local.mk, wiring directories under software/TuyaOS/vendor/, or fixing missing headers / undefined references after adding sources. Runs build_app.sh/bat like Project Details Build / Clean. Do NOT use for TuyaOpen (tos.py) or flash/monitor.
when_to_use
Trigger on: 编译/构建/清理 + tuyaos/应用; build/compile/clean TuyaOS app; 加入源文件/头文件/local.mk/vendor 路径; add .c/.h to TuyaOS build.
Compile or clean the active TuyaOS app with the same command the IDE
uses on Project Details → Build / Clean. Also guides custom source /
header paths in apps/<app>/local.mk (including files under
software/TuyaOS/vendor/).
Do not use tos.py — that is TuyaOpen only.
Canonical app local.mk reference:
software/TuyaOS/apps/tuyaos_demo_wukong_ai/local.mk (complex multi-dir
pattern). Simpler apps (e.g. tuyaos_demo_diy) use a single
find $(LOCAL_PATH)/src for sources and $(LOCAL_PATH)/include for headers.
Hard rules (read before any shell call)
build_app.sh lives only under software/TuyaOS/. Running
./build_app.sh from the workspace root, app dir, or home will fail with
exit 127 / no such file or directory: ./build_app.sh.
One shell invocation only. Agent shells do not keep cd across
tool calls. Never send cd ... as call 1 and ./build_app.sh ... as call 2.
Prefer the absolute-path form (safest). The cd && ./build_app.sh
form is allowed only if both halves are in the same command string.
Preflight before build/clean. If the script path does not exist, stop
and fix projectRoot — do not retry the same relative path.
Forbidden (causes exit 127)
# BAD — wrong cwd (workspace root / app folder / random)
./build_app.sh "apps/tuyaos_demo_diy""tuyaos_demo_diy""1.0.0"# BAD — cd in a previous tool call; cwd is lostcd"<projectRoot>/software/TuyaOS"# (later tool call)
./build_app.sh "apps/...""...""1.0.0"
Build fails with missing header / undefined ref after adding files outside default src/
When NOT to use
Situation
Use instead
TuyaOpen project (tos.py, source/embedded/)
tuyaopen-build / tos.py build
Flash firmware / serial monitor
tyutool-cli or Project Details Flash/Monitor
Create product / DP on cloud
tuya-iot-platform
End-to-end product orchestration
smart-product-dev
Project layout (quick check)
<projectRoot>/
tuya.json # sdk/chip metadata
software/TuyaOS/
build_app.sh | build_app.bat # required — ONLY valid cwd for ./ form
prepare_app.sh
Makefile
apps/
<appName>/ # e.g. tuyaos_demo_quickstart
local.mk # ★ source/header registration lives here
src/
include/
output/<version>/*.bin # build products (after success)
vendor/
<TARGET_PLATFORM>/ # e.g. T5 — platform kernel/toolchain
... optional .c/.h you may wire from app local.mk
.tuyaos/status.json # optional: { "activeApp": "..." }
Resolve parameters
1. projectRoot
Workspace folder that contains software/TuyaOS/ and preferably tuya.json.
If the open folder is already .../software/TuyaOS, then
projectRoot is its parent parent (../.. from TuyaOS), and the script is
still ./build_app.sh only when your shell cwd is that TuyaOS directory.
When unsure, resolve the absolute path to build_app.sh with a preflight.
2. appName (directory under apps/)
Priority:
Explicit in the user message — e.g.「编译 tuyaos_demo_quickstart」→ tuyaos_demo_quickstart.
Exactly one directory under software/TuyaOS/apps/ → use it.
Otherwise list apps/* and ask the user which app to build.
Verify: software/TuyaOS/apps/<appName>/ exists. If not, stop with a clear error.
3. version (semver x.y.z)
Same spirit as the IDE (normalizeFirmwareVersionForBuild):
Exact git tag at HEAD of the app directory (strip leading v).
Else version from app package.json / app.json if present.
Else user-stated version, or default 1.0.0.
Normalize: trim, strip leading v, keep first digits.digits.digits match;
if unparseable → 1.0.0.
Preflight (mandatory, same shell session as build if possible)
# 1) Prove the script exists (adjust projectRoot)test -f "<projectRoot>/software/TuyaOS/build_app.sh" \
|| test -f "<projectRoot>/software/TuyaOS/build_app.bat"# 2) Prove the app directory existstest -d "<projectRoot>/software/TuyaOS/apps/<appName>"# 3) Optional: list apps if app name is ambiguousls"<projectRoot>/software/TuyaOS/apps"
If step 1 fails: you are using the wrong projectRoot. Search for
build_app.sh under the workspace (e.g. find . -name build_app.sh -print -quit)
and retry with that directory as .../software/TuyaOS.
Commands (authoritative)
Mirror handleLegacyBuildAction in the IDE (src/tuyaos/legacyActions.ts).
cd /d "<projectRoot>\software\TuyaOS" && build_app.bat "apps\<appName>" "<appName>" "<version>"
cd /d "<projectRoot>\software\TuyaOS" && build_app.bat "apps\<appName>" "<appName>" "<version>" clean
Argument order (required):
#
Arg
Example
1
App path relative to software/TuyaOS
apps/tuyaos_demo_quickstart
2
App name
tuyaos_demo_quickstart
3
Firmware version
1.0.0
4
Optional user cmd
omit = build; clean = clean
Do not invent extra flags. Do not cd into apps/<appName> to run the script.
Arg 1 is always apps/<appName> relative to the TuyaOS tree, not an absolute path.
Custom sources & headers (local.mk)
When the user adds code outside the paths already listed in
apps/<app>/local.mk, the file will not compile until you register it.
Edit software/TuyaOS/apps/<appName>/local.mk only (do not invent a
top-level CMakeLists for TuyaOS apps).
Variable roles (from wukong / diy apps)
Variable
What it holds
Notes
LOCAL_PATH
App root (apps/<app>)
Always $(call my-dir) at top; do not reassign
LOCAL_SRC_FILES
.c / .cpp / .ccfiles to compile
Explicit paths and/or $(shell find ...)
LOCAL_TUYA_SDK_INC
Directories of public headers
Dirs only — build system may recurse for -I
LOCAL_TUYA_SDK_CFLAGS
Extra CFLAGS for this module
Use -I<path> when you need non-recursive includes; also -D...
Edit apps/tuyaos_demo_diy/local.mkbefore the TUYA_SDK_INC += export lines:
# --- my_lib from vendor (agent-added) ---
LOCAL_TUYA_SDK_INC += $(LOCAL_PATH)/../../vendor/T5/my_lib/include
LOCAL_SRC_FILES += $(shell find $(LOCAL_PATH)/../../vendor/T5/my_lib/src \
-name "*.c" -o -name "*.cpp" -o -name "*.cc")# if only one .c:# LOCAL_SRC_FILES += $(LOCAL_PATH)/../../vendor/T5/my_lib/src/my_lib.c
Rebuild with the absolute build_app.sh form (see Commands).
If fatal error: xxx.h: No such file or directory → add the parent
directory of that header via LOCAL_TUYA_SDK_INC or
LOCAL_TUYA_SDK_CFLAGS += -I..., then rebuild.
If undefined reference to ... → .c not in LOCAL_SRC_FILES; add it
and rebuild (clean first if the link line looks stale).
Agent workflow when user asks to “add custom paths”
Read current apps/<app>/local.mk end-to-end (or at least all
LOCAL_SRC_FILES / LOCAL_TUYA_SDK_INC / LOCAL_TUYA_SDK_CFLAGS lines).
Locate the real .c / .h on disk (find under app and/or vendor/).
Choose app-relative ($(LOCAL_PATH)/...) vs vendor
($(LOCAL_PATH)/../../vendor/...) prefixes.
Append with += near similar entries; never delete the export /
BUILD_* tail.
Prefer explicit file lists for vendor; use find only when the tree is
owned and free of tests/stubs — otherwise add -maxdepth or switch to
-I for headers.
Build; on missing header / undefined ref, fix local.mk again (do not
paper over with random -I to the workspace root).
Do / Don't
Do
Don't
Edit apps/<app>/local.mk
Expect files under vendor/ to auto-compile into the app
Use $(LOCAL_PATH)/../../vendor/...
Hardcode /home/user/.../vendor/...
Register both.c and header dirs
Add only sources and forget -I / LOCAL_TUYA_SDK_INC
After build: binaries under software/TuyaOS/apps/<appName>/output/<version>/ (or .../output/ if flat)
— look for *.bin. Report the path and names to the user.
After clean: that output tree is removed or emptied; say clean finished.
First-time builds may download vendor/toolchain (can take minutes). Let the
command run; do not kill it early unless the user aborts.
Common failures
Symptom
Likely cause
What to do
exit 127 / no such file or directory: ./build_app.sh
Ran ./build_app.sh outside software/TuyaOS, or cd was a separate tool call
Use absolute path to build_app.sh, or one-line cd ... && ./build_app.sh; re-run preflight
no app path! / no app name!
Wrong args or empty app
Re-check arg order and appName
App directory not found
Typo / wrong project root
ls "<projectRoot>/software/TuyaOS/apps"
Build script not found / preflight test -f fails
Not a TuyaOS tree / wrong root
find <workspace> -name build_app.sh and use that parent as TuyaOS dir
Toolchain / vendor download fail
Network
Retry; check vendor/ under TuyaOS
Build fails after code change
Stale objects
Run clean, then build
Used tos.py by mistake
TuyaOpen habit
Switch to build_app.sh as above
fatal error: *.h: No such file after adding code
Header dir not registered
Add dir to LOCAL_TUYA_SDK_INC or -I on LOCAL_TUYA_SDK_CFLAGS in app local.mk
undefined reference to ... after adding .c
Source not in LOCAL_SRC_FILES
+= the .c (or find its dir) in app local.mk
Vendor .c edited but not rebuilt into app
Never wired from app local.mk
Use $(LOCAL_PATH)/../../vendor/... recipes above
Agent checklist
Confirm TuyaOS project (not TuyaOpen).
Resolve absolute projectRoot and appName (user phrase > status.json > sole app > ask).
Resolve version → x.y.z.
If task is add sources/headers / vendor wire-up: edit apps/<app>/local.mk first (see Custom sources & headers), then build.
Preflight:test -f .../software/TuyaOS/build_app.sh and test -d .../apps/<appName>.
Run build/clean with absolute script path (or single-line cd &&) — never bare ./build_app.sh from unknown cwd.
On success, report output *.bin paths (build) or clean done.
On exit 127: do not repeat the same relative command; fix path first.
On missing header / undefined ref after custom paths: fix local.mk, then clean→build.
Related skills
tyutool-cli — flash / UART after a successful build
smart-product-dev — broader product workflow (not a substitute for this command card)
Maintained in the TuyaOpen IDE skills registry (tuyaopen-ide-manifests). Reinstall from the IDE Skills page after registry updates.