inanimate-tech/resident/validate-app

Claude Code and agent skill by inanimate-tech/resident

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Use to validate a Resident Lua app locally before pushing to a device. Runs the app through a local lua interpreter with auto-deduced stubs and checks for compile errors, missing lifecycle functions, and runtime errors during a few simulated ticks. Triggered by /resident:validate-app or when the user asks "validate this app".

Install

npx vskill@latest install inanimate-tech/resident/validate-app

SKILL.md

validate-app

Run a Resident Lua app file through the local lua interpreter with permissive stubs to catch compile errors, missing lifecycle, and obvious runtime bugs before sending it to a device.

What you need

  1. A Lua app file — pass as positional arg, or pipe via stdin.
  2. A DEVICE-SKILL.md — read from the firmware project root (cwd by

default). Used to deduce which device modules to stub. Optional: if absent, only sandbox-generic stubs are applied.

  1. `lua` — the Lua interpreter must be on PATH. If missing, the skill

exits with a clear hint to install it (brew install lua).

  1. Optional `--ref <path>` flags — additional Markdown files

describing extra modules. validate-app processes each ref file the same way as DEVICE-SKILL.md: deduces module names from fenced Lua code blocks and appends any ## Validation stubs block. Repeatable. Plain .lua refs (no Markdown structure) are silently ignored. Useful when an app uses sandbox extensions documented outside DEVICE-SKILL.md.

Usage

bash
"${CLAUDE_PLUGIN_ROOT}/skills/validate-app/tools/validate.sh" path/to/app.lua
cat app.lua | "${CLAUDE_PLUGIN_ROOT}/skills/validate-app/tools/validate.sh"
"${CLAUDE_PLUGIN_ROOT}/skills/validate-app/tools/validate.sh" --device-skill path/to/DEVICE-SKILL.md path/to/app.lua
"${CLAUDE_PLUGIN_ROOT}/skills/validate-app/tools/validate.sh" --device-skill path/to/DEVICE-SKILL.md --ref path/to/extensions.md path/to/app.lua

${CLAUDE_PLUGIN_ROOT} is set by Claude Code to the absolute path of the installed plugin — always use it to reference bundled tools; the CWD is the user's project, not the skill directory.

Exit codes:

  • 0 — passed (compile + lifecycle + 5 ticks all OK)
  • 1 — validation failed (single-line error to stderr)
  • 2 — environment error (lua missing, file not found, etc.)

Scope

The validator does NOT run the actual device firmware. It uses loose stubs:

  • Sandbox built-ins (log.*, time.*) are hardcoded with neutral return

values; time.* has the real module's shape (time.localtime() returns a full struct_time table, time.ticks_ms() an integer, etc.).

  • datetime is the device's own module (tools/datetime.lua, a verbatim

copy of Resident's), over a fixed clock: synced, 2026-10-03 12:00:00 UTC, zone UTC. Its arithmetic, comparisons and argument errors are real; strftime returns the format unchanged.

  • There are no bare math globals (floor, sin, …) and no

rgb/fract/beat/noise2d, because the sandbox has none: an app calling one fails validation. Apps use math.*.

  • Device modules (whatever DEVICE-SKILL.md mentions) get a permissive

metatable that returns a no-op function for any access.

This catches: syntax errors, missing lifecycle, obvious type errors and nil-dereferences. It does not catch: hardware-specific behavior, timing issues, or modules referenced in code but absent from DEVICE-SKILL.md (those will fall back to a global __index no-op trap).

Optional: validation stubs in DEVICE-SKILL.md

If auto-deduced stubs are too loose for your apps (e.g. apps do arithmetic on the result of screen.width()), add a ## Validation stubs section to your DEVICE-SKILL.md with a Lua block that provides concrete return values for getter-style functions. validate-app injects that block after the auto-deduced stubs, so it overrides them.

Example (m5stick-demo's DEVICE-SKILL.md):

lua
screen = setmetatable({
width = function() return 240 end,
height = function() return 135 end,
}, { __index = function() return function() end end })
imu = setmetatable({
accel = function() return 0, 0, 1 end,
gyro = function() return 0, 0, 0 end,
}, { __index = function() return function() end end })

Composing with other skills

validate-app is independent. The expected pattern is:

  1. create-app --out apps/foo.lua "<description>"
  2. validate-app apps/foo.lua → if fails, re-prompt create-app with the

error and iterate.

  1. push-app --base-url <url> --device-id <id> apps/foo.lua

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
94
Repository forks
4
7-day trend score
23

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/inanimate-tech/resident/validate-app/badge)](https://verified-skill.com/skills/inanimate-tech/resident/validate-app)

Something wrong with this skill or its page? Tell us.