Skip to content

Commit 614915b

Browse files
Initial public release v1.0.0
Build, test, and deploy Lua AI agents from inside Claude Code. Wraps the lua-cli toolchain with single-permission slash commands, hook-gated deploy safety, an MCP server exposing 5 read-only platform tools, and 5 task- specific subagents. Highlights: - 14 slash commands (lua-init, lua-new, lua-test, lua-chat, lua-push, lua-deploy, lua-doctor, lua-auth, lua-sync, lua-logs, lua-architect, lua-qa, lua-update, lua-docs) - 5 subagents with restricted tool allowlists (lua-architect, lua-debug, lua-deploy-pilot, lua-qa, lua-skill-builder) - 9 hooks: SessionStart probes (Node/lua-cli/auth), UserPromptSubmit context injection, PreToolUse deploy gates, PostToolUse smoke tests - MCP server with read-only platform tools (list_agents, get_agent, list_primitive_versions, get_deployment_status, tail_logs) - 16 structural lints + 2 check scripts, 100% coverage on hooks/, ≥90% on lib/, 299 tests across plugin + MCP suites - §3.7 single-permission contract enforced per slash - §3.3 deploy-safety gates (deny bare lua deploy + --auto-deploy at the permissions layer; defence-in-depth via PreToolUse hooks) Closes 78 documented bugs across 13 audit iterations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 parents  commit 614915b

117 files changed

Lines changed: 17635 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/plugin.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "lua-agent-builder",
3+
"version": "1.0.0",
4+
"description": "Build, test, and deploy Lua AI agents from inside Claude Code",
5+
"author": {
6+
"name": "Lua AI",
7+
"email": "support@heylua.ai",
8+
"url": "https://heylua.ai"
9+
},
10+
"homepage": "https://docs.heylua.ai/claude-code-plugin",
11+
"repository": "https://github.com/lua-ai-global/claude-code-lua-plugin.git",
12+
"license": "MIT",
13+
"keywords": ["lua", "ai-agents", "deployment", "lua-cli"]
14+
}

.eslintignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# MCP server build output (esbuild-bundled, minified)
2+
mcp/*/dist/
3+
4+
# MCP server's own node_modules and tests (linted by their own pipeline)
5+
mcp/*/node_modules/
6+
mcp/*/coverage/
7+
8+
# Coverage output
9+
coverage/
10+
11+
# Plugin node_modules (default, but explicit)
12+
node_modules/

.eslintrc.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"root": true,
3+
"parserOptions": { "ecmaVersion": 2022, "sourceType": "module" },
4+
"env": { "node": true, "jest": true, "es2022": true },
5+
"extends": ["eslint:recommended"],
6+
"rules": {
7+
"no-console": ["error", { "allow": ["warn", "error"] }],
8+
"no-throw-literal": "error",
9+
"prefer-const": "error",
10+
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
11+
},
12+
"overrides": [
13+
{
14+
"files": ["hooks/**/*.mjs", "scripts/**/*.mjs"],
15+
"rules": { "no-console": "off" }
16+
},
17+
{
18+
"files": ["test/**/*.mjs"],
19+
"rules": { "no-console": "off" }
20+
}
21+
]
22+
}

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* text=auto eol=lf
2+
*.mjs text eol=lf
3+
*.md text eol=lf
4+
*.json text eol=lf

.github/workflows/ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [main, staging]
6+
pull_request:
7+
branches: [main, staging]
8+
9+
# Runs on every PR and every push to main/staging.
10+
# Lints + tests the plugin only — no real lua-cli, no staging agents,
11+
# no secrets needed. Fork PRs run cleanly.
12+
#
13+
# NOTE: these workflow files are designed for the eventual public repo
14+
# `lua-ai-global/claude-code-lua-plugin` where this directory IS the repo
15+
# root. While the plugin lives in the monorepo at
16+
# `packages/claude-code-lua-plugin/`, GitHub Actions does NOT pick up nested
17+
# `.github/workflows/` — only the repo-root one — so these don't fire here.
18+
# When extracted, they will fire as-is.
19+
#
20+
# Cross-platform matrix because the plugin must work on macOS, Linux, and
21+
# Windows (per §3.8 of the feature doc — Node ESM hooks, AbortSignal.timeout,
22+
# path handling all need verification per cell).
23+
24+
jobs:
25+
plugin:
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
os: [macos-14, ubuntu-22.04, windows-2022]
30+
node: [18, 20]
31+
runs-on: ${{ matrix.os }}
32+
steps:
33+
- uses: actions/checkout@v4
34+
- uses: actions/setup-node@v4
35+
with:
36+
node-version: ${{ matrix.node }}
37+
- run: npm ci
38+
- run: npm run lint
39+
- run: npm test -- --coverage
40+
- run: node scripts/check-coverage.mjs
41+
- if: matrix.os == 'ubuntu-22.04' && matrix.node == '20'
42+
uses: actions/upload-artifact@v4
43+
with:
44+
name: coverage
45+
path: coverage/
46+
retention-days: 7
47+
48+
mcp:
49+
runs-on: ubuntu-22.04
50+
steps:
51+
- uses: actions/checkout@v4
52+
- uses: actions/setup-node@v4
53+
with:
54+
node-version: 20
55+
- name: Install MCP deps
56+
working-directory: mcp/lua-platform
57+
run: npm ci
58+
- name: Test MCP
59+
working-directory: mcp/lua-platform
60+
run: npm test
61+
- name: Build MCP bundle
62+
working-directory: mcp/lua-platform
63+
run: npm run build
64+
- name: Verify bundle size
65+
run: node scripts/check-bundle-size.mjs

.github/workflows/release-beta.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: release-beta
2+
3+
on:
4+
push:
5+
branches: [staging]
6+
7+
# Beta release: every merge to `staging` produces a uniquely-versioned
8+
# pre-release tarball attached to a GitHub Release marked as prerelease.
9+
#
10+
# Versioning: ${packageVersion}-beta.${runNumber}
11+
# Example: package.json version 1.0.0 + run 42 → tag v1.0.0-beta.42
12+
#
13+
# No manual version bump needed for betas — the run number gives uniqueness.
14+
# Bump package.json's base version when you intentionally start a new beta cycle.
15+
16+
permissions:
17+
contents: write # Required for creating GitHub Releases and pushing tags
18+
19+
jobs:
20+
release:
21+
runs-on: ubuntu-22.04
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
27+
- uses: actions/setup-node@v4
28+
with:
29+
node-version: 20
30+
31+
- name: Install plugin deps
32+
run: npm ci
33+
34+
- name: Lint
35+
run: npm run lint
36+
37+
- name: Test plugin
38+
run: npm test -- --coverage
39+
40+
- name: Verify per-file coverage gate
41+
run: node scripts/check-coverage.mjs
42+
43+
- name: Install MCP deps
44+
working-directory: mcp/lua-platform
45+
run: npm ci
46+
47+
- name: Test MCP
48+
working-directory: mcp/lua-platform
49+
run: npm test
50+
51+
- name: Build MCP bundle
52+
working-directory: mcp/lua-platform
53+
run: npm run build
54+
55+
- name: Verify bundle size
56+
run: node scripts/check-bundle-size.mjs
57+
58+
- name: Compute beta version
59+
id: version
60+
run: |
61+
BASE=$(node -p "require('./package.json').version")
62+
BETA_VERSION="${BASE}-beta.${{ github.run_number }}"
63+
echo "tag=v${BETA_VERSION}" >> "$GITHUB_OUTPUT"
64+
echo "version=${BETA_VERSION}" >> "$GITHUB_OUTPUT"
65+
echo "Beta version: ${BETA_VERSION}"
66+
67+
- name: Build release tarball
68+
# scripts/pack.mjs handles the MCP dist/ inclusion (gitignored —
69+
# has to be added after `git archive`). PLUGIN_VERSION_OVERRIDE
70+
# forces the tarball name to the beta version (package.json still
71+
# holds the base version).
72+
env:
73+
PLUGIN_VERSION_OVERRIDE: ${{ steps.version.outputs.version }}
74+
run: |
75+
node scripts/pack.mjs
76+
TARBALL="claude-code-lua-plugin-${{ steps.version.outputs.version }}.tar.gz"
77+
ls -lh "${TARBALL}"
78+
echo "TARBALL=${TARBALL}" >> "$GITHUB_ENV"
79+
80+
- name: Create GitHub prerelease
81+
uses: softprops/action-gh-release@v2
82+
with:
83+
tag_name: ${{ steps.version.outputs.tag }}
84+
name: ${{ steps.version.outputs.tag }}
85+
prerelease: true
86+
generate_release_notes: true
87+
target_commitish: staging
88+
files: ${{ env.TARBALL }}

.github/workflows/release-prod.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: release-prod
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
# Production release: every merge to `main` cuts a stable release.
8+
#
9+
# Versioning: uses package.json version EXACTLY. The developer must bump
10+
# package.json on the staging→main PR before merging. If the tag already
11+
# exists (i.e. version wasn't bumped), the workflow fails — explicit, not
12+
# silent.
13+
#
14+
# This is a deliberate gate: production releases require a thoughtful
15+
# version bump, not auto-numbering. Beta releases auto-version because
16+
# they're meant to be many; prod releases should be intentional.
17+
18+
permissions:
19+
contents: write
20+
21+
jobs:
22+
release:
23+
runs-on: ubuntu-22.04
24+
steps:
25+
- uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- uses: actions/setup-node@v4
30+
with:
31+
node-version: 20
32+
33+
- name: Install plugin deps
34+
run: npm ci
35+
36+
- name: Lint
37+
run: npm run lint
38+
39+
- name: Test plugin
40+
run: npm test -- --coverage
41+
42+
- name: Verify per-file coverage gate
43+
run: node scripts/check-coverage.mjs
44+
45+
- name: Install MCP deps
46+
working-directory: mcp/lua-platform
47+
run: npm ci
48+
49+
- name: Test MCP
50+
working-directory: mcp/lua-platform
51+
run: npm test
52+
53+
- name: Build MCP bundle
54+
working-directory: mcp/lua-platform
55+
run: npm run build
56+
57+
- name: Verify bundle size
58+
run: node scripts/check-bundle-size.mjs
59+
60+
- name: Read version from package.json
61+
id: version
62+
run: |
63+
VERSION=$(node -p "require('./package.json').version")
64+
if [[ "${VERSION}" == *"-beta"* || "${VERSION}" == *"-rc"* || "${VERSION}" == *"-alpha"* ]]; then
65+
echo "::error::Production release requires a stable version in package.json (no -beta/-rc/-alpha suffix). Got: ${VERSION}"
66+
exit 1
67+
fi
68+
echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT"
69+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
70+
echo "Production version: ${VERSION}"
71+
72+
- name: Verify tag does not already exist
73+
run: |
74+
if git rev-parse "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
75+
echo "::error::Tag ${{ steps.version.outputs.tag }} already exists. Bump package.json version before merging to main."
76+
exit 1
77+
fi
78+
79+
- name: Build release tarball
80+
# scripts/pack.mjs handles the MCP dist/ inclusion. Production
81+
# tags use the package.json version verbatim — no override needed.
82+
run: |
83+
node scripts/pack.mjs
84+
TARBALL="claude-code-lua-plugin-${{ steps.version.outputs.version }}.tar.gz"
85+
ls -lh "${TARBALL}"
86+
echo "TARBALL=${TARBALL}" >> "$GITHUB_ENV"
87+
88+
- name: Create GitHub release
89+
uses: softprops/action-gh-release@v2
90+
with:
91+
tag_name: ${{ steps.version.outputs.tag }}
92+
name: ${{ steps.version.outputs.tag }}
93+
prerelease: false
94+
generate_release_notes: true
95+
target_commitish: main
96+
files: ${{ env.TARBALL }}

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
node_modules/
2+
coverage/
3+
*.log
4+
.DS_Store
5+
*.tar.gz
6+
7+
# mcp/*/dist/ is intentionally NOT gitignored.
8+
# Public-marketplace consumers install the plugin via Claude Code, which
9+
# copies the directory verbatim — no build step runs. The bundled MCP
10+
# server (mcp/lua-platform/dist/server.js) MUST be committed so the plugin
11+
# works on install. Run `cd mcp/lua-platform && npm run build` after any
12+
# change to src/ and commit the updated dist/ alongside.

.mcp.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"mcpServers": {
3+
"lua-platform": {
4+
"command": "node",
5+
"args": ["${CLAUDE_PLUGIN_ROOT}/mcp/lua-platform/dist/server.js"],
6+
"env": {
7+
"LUA_API_KEY": "${LUA_API_KEY}"
8+
}
9+
}
10+
}
11+
}

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
engine-strict=true

0 commit comments

Comments
 (0)