app-commands
Provides direct access to GROWI-specific build, lint, and migration commands.
Install
mkdir -p .claude/skills/app-commands && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3360" && unzip -o skill.zip -d .claude/skills/app-commands && rm skill.zipInstalls to .claude/skills/app-commands
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
GROWI main application (apps/app) specific commands and scripts. Auto-invoked when working in apps/app.Key capabilities
- →Executes package-specific linting and typechecking for the main app
- →Triggers database migration status checks and rollbacks
- →Runs visual regression tests in isolated environments
- →Invokes local console REPLs for administrative tasks
How it works
Routes commands to either Turborepo for cached build tasks or local scripts for app-specific operations.
Inputs & outputs
When to use app-commands
- →Running database migrations
- →Executing typechecks and linting
- →Triggering build and test cycles
About this skill
App Commands (apps/app)
Commands specific to the main GROWI application. For global commands (turbo, pnpm), see the global tech-stack skill.
Quality Check Commands
IMPORTANT: Distinguish between Turborepo tasks and package-specific scripts.
Turbo Tasks vs Package Scripts
| Task | Turborepo (turbo.json) | Package Script (package.json) |
|---|---|---|
lint | ✅ Yes | ✅ Yes (runs all lint:*) |
test | ✅ Yes | ✅ Yes |
build | ✅ Yes | ✅ Yes |
lint:typecheck | ❌ No | ✅ Yes |
lint:biome | ❌ No | ✅ Yes |
lint:styles | ❌ No | ✅ Yes |
Recommended Commands
# Run ALL quality checks (uses Turborepo caching)
turbo run lint --filter @growi/app
turbo run test --filter @growi/app
turbo run build --filter @growi/app
# Run INDIVIDUAL lint checks (package-specific scripts, from apps/app directory)
pnpm run lint:typecheck # TypeScript only
pnpm run lint:biome # Biome only
pnpm run lint:styles # Stylelint only
Running individual test files: See the
testingrule (.claude/rules/testing.md).
Quick Reference
| Task | Command |
|---|---|
| Migration | pnpm run dev:migrate |
| OpenAPI generate | pnpm run openapi:generate-spec:apiv3 |
| REPL console | pnpm run console |
| Visual regression | pnpm run reg:run |
| Version bump | pnpm run version:patch |
Database Migration
# Run pending migrations
pnpm run dev:migrate
# Check migration status
pnpm run dev:migrate:status
# Apply migrations
pnpm run dev:migrate:up
# Rollback last migration
pnpm run dev:migrate:down
# Production migration
pnpm run migrate
Note: Migrations use migrate-mongo. Files are in config/migrate-mongo/.
Creating a New Migration
# Create migration file manually in config/migrate-mongo/
# Format: YYYYMMDDHHMMSS-migration-name.js
# Test migration cycle
pnpm run dev:migrate:up
pnpm run dev:migrate:down
pnpm run dev:migrate:up
OpenAPI Commands
# Generate OpenAPI spec for API v3
pnpm run openapi:generate-spec:apiv3
# Validate API v3 spec
pnpm run lint:openapi:apiv3
# Generate operation IDs
pnpm run openapi:build:generate-operation-ids
Generated specs output to tmp/openapi-spec-apiv3.json.
Style Pre-build (Vite)
# Development mode
pnpm run dev:pre:styles-commons
pnpm run dev:pre:styles-components
# Production mode
pnpm run pre:styles-commons
pnpm run pre:styles-commons-components
Pre-builds SCSS styles into CSS bundles using Vite.
Debug & Utility
REPL Console
pnpm run console
# or
pnpm run repl
Interactive Node.js REPL with Mongoose models loaded. Useful for debugging database queries.
Visual Regression Testing
pnpm run reg:run
Version Commands
# Bump patch version (e.g., 7.4.3 → 7.4.4)
pnpm run version:patch
# Create prerelease (e.g., 7.4.4 → 7.4.5-RC.0)
pnpm run version:prerelease
# Create preminor (e.g., 7.4.4 → 7.5.0-RC.0)
pnpm run version:preminor
Build Measurement
# Measure module count KPI (cleans .next, starts next dev, triggers compilation)
./bin/measure-chunk-stats.sh # default port 3099
./bin/measure-chunk-stats.sh 3001 # custom port
Output: [ChunkModuleStats] initial: N, async-only: N, total: N
For details on module optimization and baselines, see the build-optimization skill.
Production
# Start server (after build)
pnpm run server
# Start for CI environments
pnpm run server:ci
Note: preserver hook automatically runs migrations before starting.
CI/CD
# Launch dev server for CI
pnpm run launch-dev:ci
# Start production server for CI
pnpm run server:ci
Environment Variables
Development uses dotenv-flow:
.env- Default values.env.local- Local overrides (not committed).env.development- Development-specific.env.production- Production-specific
See .env.example for available variables.
Smoke Testing
The devcontainer always has MongoDB and other services running (see .claude/rules/devcontainer.md). The dev server can and should be started for smoke verification — never claim the runtime environment is unavailable.
Workflow
Step 1 — Override env vars without touching committed files
Create apps/app/.env.development.local (highest dotenv-flow priority; gitignored):
# Example: disable vault feature to test 404 behaviour
cat > apps/app/.env.development.local << 'EOF'
VAULT_ENABLED=false
EOF
dotenv-flow load order (first definition wins):
.env.development.local← your override.env.local.env.development← committed defaults.env
Note: nodemon watches
*.*but does not reliably pick up dotfile changes (files starting with.). After editing.env.development.local, kill the server process manually so nodemon restarts it with the new env:kill $(ss -tlnp | grep ':3000' | grep -o 'pid=[0-9]*' | cut -d= -f2)
Step 2 — Start the dev server in background
turbo run dev --filter @growi/app &
Wait for the ready message:
until curl -s http://localhost:3000/ > /dev/null 2>&1; do sleep 1; done
echo "Server ready"
Or watch the log for Express server is listening on port 3000.
Step 3 — Curl the endpoints
# Feature disabled → 404 (no Retry-After)
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/_vault/repo.git/info/refs?service=git-upload-pack
# Push attempt → always 403
curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:3000/_vault/repo.git/git-receive-pack
# Check response body
curl -s http://localhost:3000/_vault/repo.git/info/refs?service=git-upload-pack
# Check specific headers
curl -sI http://localhost:3000/_vault/repo.git/info/refs?service=git-upload-pack | grep -i retry-after
Step 4 — Switch env and retest
Edit .env.development.local, then kill and wait for nodemon to restart:
echo "VAULT_ENABLED=true" > apps/app/.env.development.local
kill $(ss -tlnp | grep ':3000' | grep -o 'pid=[0-9]*' | cut -d= -f2)
until curl -s http://localhost:3000/ > /dev/null 2>&1; do sleep 1; done
Step 5 — Manipulate MongoDB state if needed
node -e "
const { MongoClient } = require('/workspace/growi-vault/node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected]/node_modules/mongodb');
async function main() {
const client = new MongoClient('mongodb://mongo:27017/growi?replicaSet=rs0');
await client.connect();
// e.g. reset bootstrap state
await client.db('growi').collection('vault_sync_state').updateOne(
{ _id: 'singleton' },
{ \$set: { bootstrapState: 'pending' } },
{ upsert: true }
);
await client.close();
}
main().catch(console.error);
"
Step 6 — Stop the server
kill $(pgrep -f "nodemon|src/server/app.ts") 2>/dev/null
What counts as a passing smoke test
- The Express server starts without throwing on import (
Express server is listening on port 3000in logs) - Feature-flag–gated endpoints return the correct status code for each flag state (404 when disabled, 503 with the right message when bootstrap incomplete, 403 for read-only enforcement)
- No unhandled exception in server startup logs
Authorization Regression Check
Three capture tools freeze the apiv3 authorization surface so a refactor can be proven not
to have moved it. Run them when a change touches middleware order, route registration, the
auth chain, or after a large merge — a dropped guard is invisible to build, lint and unit
tests. Baselines are committed under tools/authz-matrix/baselines/.
cd apps/app # requires MongoDB (devcontainer) and a free port 3000
pnpm run authz:capture-routes # structural: (method, path, middlewareNames[]) per apiv3 leaf
pnpm run authz:capture-matrix # black-box: HTTP status per endpoint × 4 personas
pnpm run authz:capture-ws # WebSocket: /yjs + socket.io, 3 session cases each
Each writes to its default baseline path under tools/authz-matrix/baselines/; pass
-- --out=<path> to write elsewhere (authz:capture-matrix also takes -- --in=<path>
for the structural snapshot it derives its endpoint list from).
How to use it: capture on the base commit, apply your change, re-capture, and
git diff the baseline files. Any difference inside the entries / matrix arrays is
a potential authorization change and must be explained; the envelope metadata
(capturedAt, git, node) changes on every run and is not signal. Adding
-- --verify-determinism re-runs a capture twice and asserts the output is stable — do
that before trusting a diff.
Properties worth knowing:
- The structural walker fails if any middleware layer is anonymous, because an unnamed handler makes every slot look identical and destroys the diff. Fix the source (name the function the middleware factory returns); do not weaken the tool. The terminal route-body slot is exempt (~260 inline arrow handlers are pinned to their (path, method) slot), so "no anonymous" means no anonymous chain middleware slot.
- The black-box matrix records the observed status code, not business-logic validity — a 400 from a missing request body after the auth gate passed is fine and deterministic.
- Persona injection is mounted where
passport.session()sits, so the matrix exercises the route-level chain (accessTokenParser→loginRequired→adminRequired→ handler) but not passport's own cookie parsing. Cover that with E2E. - WebSocket endpoints never appear in
app._router.stack, which is why the third tool exists: the structural snapshot structurally cannot see/yjs/<pageId>or the socket.io namespace middleware.
External Plugin Install Smoke
GROWI installs third-party plugins as prebuilt assets (download
Content truncated.
When not to use it
- →Global tasks outside the scope of apps/app
- →Modifying packages outside the GROWI repository
Prerequisites
Limitations
- →Dependent on correct configuration of package.json scripts
- →Only relevant to the GROWI codebase
How it compares
It provides a context-aware interface that differentiates between repo-wide workflows and application-specific maintenance.
Compared to similar skills
app-commands side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| app-commands (this skill) | 1 | 2mo | Caution | Beginner |
| orchardcore-tester | 1 | 6mo | Review | Intermediate |
| replit-load-scale | 1 | 26d | Caution | Advanced |
| agent-sandbox | 1 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by growilabs
View all by growilabs →You might also like
orchardcore-tester
OrchardCMS
Tests OrchardCore CMS features through browser automation. Use when the user needs to build, run, setup, or test OrchardCore functionality including admin features, content management, media library, and module testing.
replit-load-scale
jeremylongshore
Implement Replit load testing, auto-scaling, and capacity planning strategies. Use when running performance tests, configuring horizontal scaling, or planning capacity for Replit integrations. Trigger with phrases like "replit load test", "replit scale", "replit performance test", "replit capacity", "replit k6", "replit benchmark".
agent-sandbox
ruvnet
Agent skill for sandbox - invoke with $agent-sandbox
dev
serithemage
Development workflow guide. Covers build, test, lint, format commands, package structure, Git hooks, TDD methodology, and coding conventions. Use when setting up dev environment, running tests, or following project conventions.
e2e-test-service-management
raphaelmansuy
Service management for E2E testing in EdgeQuake. Start, stop, and monitor PostgreSQL, backend API, and frontend services. Includes health checks and logging utilities for interactive testing workflows.
chaos-scenario
petercort
Use when authoring, running, or reviewing chaos engineering experiments in this monorepo. Covers steady-state hypothesis, fault injection (service kill, latency, network partition, overload), result recording to CSV, and cleanup/restore. Triggers: "add chaos scenario", "new chaos test", "inject faul