Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"name": "lua-agent-builder",
"source": "./plugins/lua-agent-builder",
"description": "Build, test, and deploy Lua AI agents from inside Claude Code",
"version": "1.2.2",
"version": "1.3.0",
"homepage": "https://github.com/lua-ai-global/claude-code-lua-plugin#readme",
"repository": "https://github.com/lua-ai-global/claude-code-lua-plugin.git",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Then `/lua-auth`: an existing credential is kept; a new login runs `lua auth con

| Plugin | Description |
|---|---|
| [`lua-agent-builder`](./plugins/lua-agent-builder/) | 20 slash commands, 5 subagents, 10 hooks, a 5-file knowledge base verified against lua-cli 3.33.0 source, a local read-only platform MCP server and the public docs MCP |
| [`lua-agent-builder`](./plugins/lua-agent-builder/) | 20 slash commands, 5 subagents, 10 hooks, a 5-file knowledge base verified against lua-cli source (3.33.0 base; 1.3.0 adds per-step model classes and the workflow autonomy envelope from lua-cli 3.36.0, read from `main` / `feat/workflow-autonomy`), a local read-only platform MCP server and the public docs MCP |

## Quick walkthrough

Expand Down
24 changes: 15 additions & 9 deletions docs/USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A complete walkthrough of the [`lua-agent-builder`](https://github.com/lua-ai-global/claude-code-lua-plugin) Claude Code plugin — what it does, how to install it, the canonical build loops (tools, integrations, workflows, templates), the safety model, and what to do when things go wrong.

The plugin wraps **lua-cli 3.33.0**, the TypeScript SDK/CLI for the Lua agent platform. It has nothing to do with the Lua programming language. Everything in this guide (command shapes, SDK types, API routes) was verified against the lua-cli and lua-api source, not only the public docs.
The plugin wraps **lua-cli 3.36.0** (the pinned minimum: the 3.33.0 base plus the 3.36.0 workflow verbs, marked ⏳ in the knowledge base), the TypeScript SDK/CLI for the Lua agent platform. It has nothing to do with the Lua programming language. Everything in this guide (command shapes, SDK types, API routes) was verified against the lua-cli and lua-api source, not only the public docs.

If you just want to start: [Installation](#installation) → [Your first agent](#your-first-agent).

Expand Down Expand Up @@ -34,7 +34,7 @@ If you just want to start: [Installation](#installation) → [Your first agent](

- **Slash commands** wrap every `lua` command you need (`/lua-init`, `/lua-new`, `/lua-test`, `/lua-workflow`, `/lua-push`, `/lua-deploy`, `/lua-status`, …), collect the inputs up-front in one prompt, and surface errors with the CLI's typed exit codes explained.
- **Subagents** do the heavy lifting in their own context with restricted tools: the architect plans, the skill-builder scaffolds and tests any primitive (including workflows, triggers, devices and voices), the debug agent diagnoses failures, the deploy pilot runs the gated ship sequence, the QA agent runs conversational and offline-workflow suites.
- **A knowledge base** (`lib/knowledge/`) gives those agents the exact SDK shapes, workflow builder, CLI matrix, integration patterns and decision trees — checked against lua-cli 3.33.0 source.
- **A knowledge base** (`lib/knowledge/`) gives those agents the exact SDK shapes, workflow builder, CLI matrix, integration patterns and decision trees — checked against lua-cli source (3.33.0 base; the ⏳ additions against the `main` / `feat/workflow-autonomy` refs lua-cli 3.36.0 is cut from).
- **Hooks** probe your environment, inject the current agent into Claude's context, and gate every production-affecting verb.
- **Two MCP servers**: a local read-only platform server (what's deployed, versions, logs) and the public docs MCP.

Expand All @@ -45,12 +45,14 @@ If you just want to start: [Installation](#installation) → [Your first agent](
| Requirement | Why | How |
|---|---|---|
| **Node.js ≥ 18** | hooks and the MCP server are Node ESM | macOS `brew install node@20` · Windows `winget install OpenJS.NodeJS.LTS` · Linux NodeSource / `nvm install 20` |
| **lua-cli ≥ 3.33.0** | the command shapes the plugin emits | `npm install -g lua-cli` (or `/lua-update`) |
| **lua-cli ≥ 3.36.0** | the command shapes the plugin emits (3.36.0 adds the workflow policy, clear-gate and recompose verbs the knowledge base describes) | `npm install -g lua-cli` (or `/lua-update`) |
| **Claude Code** | the host | https://claude.com/claude-code |
| **A Lua account** | to talk to `api.heylua.ai` | https://admin.heylua.ai — `/lua-auth` guides the login |

`/lua-doctor` checks all of these and offers consent-gated fixes. Platforms: macOS 14+, Ubuntu 22.04+, Windows 11; CI runs the suite on all three with Node 18 and 20.

Two platform features are new in the 1.3.0 knowledge base: **per-step model classes** (`taskClass`, `model: 'class/fast|balanced|strong'`, `requires`, `effort`, `lua models list --workflows`, `lua workflows policy models`, `lua push workflow --apply-effort`, `clear-gate`, `recompose`) and the **workflow autonomy envelope** (`lua workflows policy autonomy`, the `Consent: auto (policy)` line). They need **lua-cli 3.36.0 or later** — the plugin's pinned minimum since 1.3.0; the knowledge files mark them ⏳ and were read from the lua-cli source on `main` / `feat/workflow-autonomy`, the refs 3.36.0 is cut from, so the slashes tell you when your CLI predates a verb (exit 2) instead of guessing.

---

## Installation
Expand Down Expand Up @@ -117,8 +119,10 @@ Workflows are durable multi-step graphs with approvals, signals, fan-out, retrie
3. `/lua-push workflow` — a server version (not live). Missing `env.template()` keys are refused at push.
4. `/lua-deploy` → target `workflow` — `LUA_DEPLOY_CONFIRMED=1 lua workflows deploy reply-approval -v latest`, plus `activate` if it has a schedule.
5. `/lua-workflow start reply-approval --input @in.json` (one confirmation) → `/lua-workflow status <runId>` → `/lua-workflow approve <runId> <wfa_…>` / `signal` / `resume` / `cancel`.
6. ⏳ **A model per step** (lua-cli 3.36.0 or later): give each `agentStep` a `taskClass` (`classify extract transform draft research reason code judge`) and `model: 'class/fast' | 'class/balanced' | 'class/strong'` — the platform resolves the class through your organization's policy (`/lua-workflow policy models get`; an admin sets `maxClass`, `classMap`, `allow`, `pins`, `fallback`, `consent-actions`), `requires: ['structured']` when the step has an `outputSchema`, and an `effort` that is recorded but only applied once you push with `--apply-effort`. `/lua-workflow models` shows the catalog as a step sees it (class, best for, speed, cost). A step whose class cannot be served parks instead of failing — `/lua-workflow clear-gate <runId>` once the policy is fixed.
7. ⏳ **Will it start without asking?** A run the agent composes or starts from chat above 15 steps · 20 credits · 1 h parks `gated` until someone consents from the desktop (`status` exits 6 under `--strict`). An organization can pre-consent to a bounded envelope — `/lua-workflow policy autonomy get` shows it; an admin sets it with `lua workflows policy autonomy set --enabled on --max-credits <n> --max-steps <n> --max-duration <seconds> --max-actions <n> --max-runs-per-hour <n> --forms graph,static` (the plugin asks before that org-wide write). Such a start shows `Consent: auto (policy) — ≤ …` on `status`. Goal runs and batch starts always ask; a refusal (`askAboveThresholds: false`) is never turned into an auto-start.

Chat-composed workflows can't be deployed from the CLI (`WORKFLOW_DYNAMIC`); `/lua-workflow export <name>` brings one into source.
Chat-composed workflows can't be deployed from the CLI (`WORKFLOW_DYNAMIC`); `/lua-workflow export <name>` brings one into source, and ⏳ `/lua-workflow recompose <name>` rewrites its task classes into `class/<c>` as a new version.

---

Expand All @@ -137,7 +141,7 @@ Chat-composed workflows can't be deployed from the CLI (`WORKFLOW_DYNAMIC`); `/l
| `/lua-architect <goal>` | subagent | plan + next-step menu |
| `/lua-new <type> [name]` | subagent → `lua compile`, `lua test` | 13 primitive types (incl. `workflow-script`) |
| `/lua-test [type]` | `lua test --ci <type> --name … --input …` | failures → debug subagent |
| `/lua-workflow <verb>` | `lua workflows …`, `lua test workflow` | read-only verbs run at once; start/approve/signal/resume/cancel confirm once; deploy → `/lua-deploy` |
| `/lua-workflow <verb>` | `lua workflows …`, `lua test workflow` | read-only verbs run at once (⏳ incl. `policy models\|autonomy get`, `models`); start/approve/signal/resume/cancel (⏳ `clear-gate`, `policy … set`, `recompose`) confirm once; deploy → `/lua-deploy` |
| `/lua-chat` | `lua chat --ci -e … -m … -t` | always an explicit thread |
| `/lua-logs` | `lua logs --ci --type … --json` | real `--type` list (`mastra` is not valid) |
| `/lua-env` | `lua env <sandbox\|production> --list \| -k KEY -v VALUE \| -k KEY --delete` | environment + key + value collected once; the Bash prompt is the confirmation; the value is never echoed, listings show masked values |
Expand Down Expand Up @@ -181,7 +185,7 @@ Subagents never ask questions; the slash that spawned them already collected the

| Event | Hook | What it does |
|---|---|---|
| SessionStart | `check-lua-version` | warns (never blocks) if lua-cli < 3.33.0 |
| SessionStart | `check-lua-version` | warns (never blocks) if lua-cli < 3.36.0, pointing at `/lua-update` / `npm i -g lua-cli@latest` |
| SessionStart | `detect-project` | "✓ Lua agent project detected: <agentId>" from `lua.skill.yaml` |
| SessionStart | `check-lua-auth` | probes `lua models list --json --ci` (1–2 s); exit 9 → recommends `/lua-auth`, exit 11 → API-unreachable note, timeout → "could not confirm" |
| UserPromptSubmit | `inject-context` | `[lua] agent: <id> / org: <id>` every prompt |
Expand Down Expand Up @@ -233,7 +237,7 @@ The rules `/lua-doctor` merges (`lib/permissions-template.json`):

- **deny** — anything with `--auto-deploy`, `lua auth configure|key|logout*`, and the alternative binaries `heylua *` / `lua-ai *` wholesale (same program; the plugin only ever emits `lua`). The bare production verbs (`lua deploy`, `lua version promote`, …) are **deliberately not in `deny` or `ask`**: Claude Code evaluates those two tiers past a leading env assignment, so a `Bash(lua deploy*)` deny would also block the confirmed `LUA_DEPLOY_CONFIRMED=1 lua deploy …` form and no deploy could ever run (this is documented at code.claude.com/docs/en/permissions and was confirmed live). The bare forms are blocked by the `confirm-deploy` hook instead — see below.
- **allow** — the prefixed production verbs (`LUA_DEPLOY_CONFIRMED=1 lua deploy*`, `… lua skills|webhooks|jobs|preprocessors|postprocessors deploy*`, `… lua workflows deploy|activate*`, `… lua version promote*`, `… lua persona production deploy*`, `… lua mcp activate*`, `… lua marketplace template publish|apply*`), every read-only `lua` verb the slashes and subagents use, `lua push * --ci --force*`, `lua sync --check|--pull|--push`, `lua version create*` (a snapshot; nothing goes live until `promote`), and read-only git.
- **ask** — deletes, `lua env *`, `lua pull`, `lua chat clear`, `lua source rollback`, `lua version delete`, workflow run control (`start`, `cancel`, `approve`, `signal`, `resume`, `retry-step`, `resolve-step`, `raise-budget`, `deactivate`, `schedules`, `goals`, `export`, `archive-runs`), `lua devices enable|disable`, `lua marketplace skill publish|unpublish|unlist|transfer`, integration connects/changes, `npm install -g lua-cli`, system installs. For the workflow run-control verbs this prompt **is** the single confirmation: `/lua-workflow` shows you the exact command in the permission prompt and does not ask a second time. `/lua-env` (`lua env *` — kept in `ask` even for `--list`, because the CLI prints masked values) and `/lua-integrations` (connect/update/disconnect/convert, webhook create/pause/resume/delete, MCP activate/deactivate) rely on the same prompt.
- **ask** — deletes, `lua env *`, `lua pull`, `lua chat clear`, `lua source rollback`, `lua version delete`, workflow run control (`start`, `cancel`, `approve`, `signal`, `resume`, `retry-step`, `resolve-step`, `raise-budget`, `deactivate`, `schedules`, `goals`, `export`, `archive-runs`, ⏳ `clear-gate`, `recompose`), ⏳ the org-wide policy writes `lua workflows policy models|autonomy set` (`policy … get` is allowed), `lua devices enable|disable`, `lua marketplace skill publish|unpublish|unlist|transfer`, integration connects/changes, `npm install -g lua-cli`, system installs. For the workflow run-control verbs this prompt **is** the single confirmation: `/lua-workflow` shows you the exact command in the permission prompt and does not ask a second time. `/lua-env` (`lua env *` — kept in `ask` even for `--list`, because the CLI prints masked values) and `/lua-integrations` (connect/update/disconnect/convert, webhook create/pause/resume/delete, MCP activate/deactivate) rely on the same prompt.

Precedence is deny → ask → allow. **The production gate is the `confirm-deploy` hook**: it runs on every Bash call, classifies the command with `lib/tokenizer.mjs` (every canonical spelling, every lua-cli alias — `publish`, `on`, `enable`, `submit`, `rollout`, `prod` … — and all three binaries), and blocks a bare production verb with exit 2. A hook block takes precedence over any allow rule, including a broad `Bash(lua *)` you may have in your own settings, so the gate holds even without the template. It refuses shell wrappers and pipes even with the prefix. Only the deploy pilot and `/lua-template` emit the prefix, and only after your one confirmation; the template's allow rules let that confirmed command run without a second prompt. A test (`test/lib/permissions-mirror.test.mjs`) and a lint fail if a deny/ask rule would ever shadow a confirmed form or an allow rule admit a bare one.

Expand All @@ -250,7 +254,9 @@ Precedence is deny → ask → allow. **The production gate is the `confirm-depl
- **Exit 9 / 10 / 11 / 12** — not authenticated / the credential's agent-or-role scope excludes this action / the Lua API is unreachable / the model provider refused (key, model, quota).
- **`/lua-deploy` aborts on "server is ahead"** — someone pushed a newer version; `/lua-sync` pull, review, retry.
- **Compile: "No skills found" or a primitive is missing from the manifest** — it isn't referenced from the `LuaAgent` arrays in `src/index.ts`.
- **Workflow push refused** — `unplaced_step`, `tool_unbundled`, `env-template-missing`, `WORKFLOW_NAME_TAKEN`; the debug subagent maps each to a fix (`lib/knowledge/workflows.md` §9).
- **Workflow push refused** — `unplaced_step`, `tool_unbundled`, `env-template-missing`, `WORKFLOW_NAME_TAKEN`; ⏳ `task-class-without-model`, `model-class-unknown` (and the other vocabulary codes), `model-class-resolution-off`; the debug subagent maps each to a fix (`lib/knowledge/workflows.md` §9).
- **A workflow run sits `gated` / exit 6** — a consent gate is a person's to clear from the desktop or the approvals inbox (`lua workflows approve` needs a `wfa_` id and cannot); ⏳ on lua-cli 3.36.0 or later `status --strict` exits 6 on it (below 3.36.0 it exits 0). A `model_policy` park (⏳) is cleared with `/lua-workflow clear-gate <runId>` once the org's model policy serves the class.
- **`lua push all` made a workflow live** — ⏳ lua-cli 3.36.0 or newer pushes and activates workflows in stage-all (`lib/knowledge/cli-reference.md` §4); push per type, or use `/lua-deploy` for workflows, when that is not what you want.

---

Expand All @@ -268,6 +274,6 @@ Precedence is deny → ask → allow. **The production gate is the `confirm-depl

**Where does my code go?** From lua-cli to `api.heylua.ai` (and `webhook.heylua.ai`, `cdn.heylua.ai`). The MCP server talks to `api.heylua.ai` and, for a session login, to Google's token endpoint to refresh the session. Claude Code sends the conversation to Anthropic per its own policy.

**How do I update the plugin?** `/plugin marketplace update claude-code-lua-plugin` then reinstall; 1.2.2 targets lua-cli 3.33.0.
**How do I update the plugin?** `/plugin marketplace update claude-code-lua-plugin` then reinstall; 1.3.0 targets lua-cli 3.36.0 (the pin; it carries the per-step model classes and workflow autonomy verbs the plugin describes).

**Where do I report bugs?** Plugin: https://github.com/lua-ai-global/claude-code-lua-plugin/issues · Security: security@heylua.ai · lua-cli: https://github.com/lua-ai-global/lua-cli/issues · Docs: https://docs.heylua.ai (and `mcp__plugin_lua-agent-builder_lua-docs__submit_feedback` for a wrong page).
2 changes: 1 addition & 1 deletion plugins/lua-agent-builder/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lua-agent-builder",
"version": "1.2.2",
"version": "1.3.0",
"description": "Build, test, and deploy Lua AI agents from inside Claude Code",
"author": {
"name": "Lua AI",
Expand Down
Loading
Loading