@shiva-fw/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +38 -0
- package/.gitattributes +18 -0
- package/.nvmrc +1 -0
- package/README.md +179 -0
- package/bin/shiva.js +4 -0
- package/package.json +44 -0
- package/recipes/full-rp.json +77 -0
- package/recipes/minimal.json +30 -0
- package/recipes/standard.json +46 -0
- package/src/commands/ai/context.js +89 -0
- package/src/commands/ai/link.js +38 -0
- package/src/commands/ai/mcp.js +39 -0
- package/src/commands/config/validate.js +65 -0
- package/src/commands/docs/api.js +81 -0
- package/src/commands/docs/build.js +14 -0
- package/src/commands/docs/deploy.js +14 -0
- package/src/commands/docs/serve.js +14 -0
- package/src/commands/init.js +167 -0
- package/src/commands/install.js +108 -0
- package/src/commands/locale/missing.js +83 -0
- package/src/commands/make/contract.js +45 -0
- package/src/commands/make/migration.js +69 -0
- package/src/commands/make/model.js +63 -0
- package/src/commands/make/module.js +115 -0
- package/src/commands/make/seed.js +51 -0
- package/src/commands/make/service.js +60 -0
- package/src/commands/make/test.js +53 -0
- package/src/commands/mcp.js +26 -0
- package/src/commands/migrate/rollback.js +155 -0
- package/src/commands/migrate/run.js +159 -0
- package/src/commands/migrate/status.js +137 -0
- package/src/commands/module/list.js +46 -0
- package/src/commands/module/status.js +64 -0
- package/src/commands/outdated.js +59 -0
- package/src/commands/remove.js +61 -0
- package/src/commands/seed.js +108 -0
- package/src/commands/test.js +88 -0
- package/src/commands/update.js +90 -0
- package/src/generators/index.js +78 -0
- package/src/generators/templates/contract.lua.tpl +12 -0
- package/src/generators/templates/migration.lua.tpl +15 -0
- package/src/generators/templates/model.lua.tpl +14 -0
- package/src/generators/templates/module/client/init.lua.tpl +5 -0
- package/src/generators/templates/module/config/config.lua.tpl +4 -0
- package/src/generators/templates/module/fxmanifest.lua.tpl +41 -0
- package/src/generators/templates/module/locales/en.lua.tpl +4 -0
- package/src/generators/templates/module/module.lua.tpl +10 -0
- package/src/generators/templates/module/server/init.lua.tpl +2 -0
- package/src/generators/templates/module/shared/init.lua.tpl +5 -0
- package/src/generators/templates/seed.lua.tpl +10 -0
- package/src/generators/templates/service.lua.tpl +7 -0
- package/src/generators/templates/test.lua.tpl +39 -0
- package/src/index.js +113 -0
- package/src/mcp/resources/contracts.js +68 -0
- package/src/mcp/resources/docs.js +56 -0
- package/src/mcp/resources/examples.js +235 -0
- package/src/mcp/server.js +121 -0
- package/src/mcp/tools/config.js +53 -0
- package/src/mcp/tools/contracts.js +37 -0
- package/src/mcp/tools/database.js +93 -0
- package/src/mcp/tools/docs.js +38 -0
- package/src/mcp/tools/events.js +26 -0
- package/src/mcp/tools/items.js +280 -0
- package/src/mcp/tools/modules.js +25 -0
- package/src/packages/lockfile.js +53 -0
- package/src/packages/registry.js +99 -0
- package/src/packages/resolver.js +83 -0
- package/src/utils/config-reader.js +74 -0
- package/src/utils/lua-annotations.js +319 -0
- package/src/utils/lua-parser.js +119 -0
- package/src/utils/server-root.js +66 -0
package/.editorconfig
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
indent_size = 4
|
|
7
|
+
indent_style = space
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
|
|
11
|
+
[*.md]
|
|
12
|
+
trim_trailing_whitespace = false
|
|
13
|
+
|
|
14
|
+
[*.{yml,yaml}]
|
|
15
|
+
indent_size = 2
|
|
16
|
+
|
|
17
|
+
[*.{json,xml}]
|
|
18
|
+
indent_size = 2
|
|
19
|
+
|
|
20
|
+
[*.{js,ts,jsx,tsx}]
|
|
21
|
+
indent_size = 2
|
|
22
|
+
|
|
23
|
+
[*.{css,scss}]
|
|
24
|
+
indent_size = 2
|
|
25
|
+
|
|
26
|
+
[*.lua]
|
|
27
|
+
indent_size = 4
|
|
28
|
+
|
|
29
|
+
[*.lua.tpl]
|
|
30
|
+
indent_size = 4
|
|
31
|
+
|
|
32
|
+
[*.{sh,bash}]
|
|
33
|
+
indent_style = tab
|
|
34
|
+
indent_size = 4
|
|
35
|
+
|
|
36
|
+
[{Makefile,**.mk}]
|
|
37
|
+
indent_style = tab
|
|
38
|
+
indent_size = 4
|
package/.gitattributes
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
2
|
+
|
|
3
|
+
*.css diff=css
|
|
4
|
+
*.html diff=html
|
|
5
|
+
*.md diff=markdown
|
|
6
|
+
*.lua diff=lua
|
|
7
|
+
*.tsx diff=typescriptreact
|
|
8
|
+
*.ts diff=typescript
|
|
9
|
+
*.yml diff=yaml
|
|
10
|
+
*.sh diff=bash
|
|
11
|
+
*.js diff=javascript
|
|
12
|
+
*.json diff=json
|
|
13
|
+
|
|
14
|
+
# Mark generated files
|
|
15
|
+
package-lock.json linguist-generated=true
|
|
16
|
+
|
|
17
|
+
/.github export-ignore
|
|
18
|
+
CHANGELOG.md export-ignore
|
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# shiva-cli
|
|
2
|
+
|
|
3
|
+
> Developer CLI for the [Shiva](https://github.com/adrianmejias/shiva-core) FiveM framework — scaffolding, migrations, package management, AI integration, and an MCP server.
|
|
4
|
+
|
|
5
|
+
Think of it as Artisan for FiveM. Generate modules, run database migrations, manage packages with lockfile support, produce AI context files, and expose live framework data to AI tools via the Model Context Protocol.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @shiva-fw/cli
|
|
11
|
+
# or run without installing
|
|
12
|
+
npx @shiva-fw/cli init
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
After installing, the `shiva` command is available globally.
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Initialise a new server project
|
|
21
|
+
shiva init
|
|
22
|
+
|
|
23
|
+
# Scaffold a module
|
|
24
|
+
shiva make:module fishing
|
|
25
|
+
shiva make:service FishingService --module shiva-fishing
|
|
26
|
+
shiva make:model Fish --module shiva-fishing
|
|
27
|
+
shiva make:migration create_fish_table --module shiva-fishing
|
|
28
|
+
|
|
29
|
+
# Run migrations
|
|
30
|
+
shiva migrate
|
|
31
|
+
|
|
32
|
+
# Start the MCP server (for Claude Code, Cursor, etc.)
|
|
33
|
+
shiva mcp start
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
### Scaffolding
|
|
39
|
+
```bash
|
|
40
|
+
shiva init # Interactive setup
|
|
41
|
+
shiva init --recipe full-rp # Use a preset recipe (minimal | standard | full-rp)
|
|
42
|
+
|
|
43
|
+
shiva make:module <name> # Scaffold a new module
|
|
44
|
+
shiva make:service <name> --module <module> # Add a service
|
|
45
|
+
shiva make:model <name> --module <module> # Add a model
|
|
46
|
+
shiva make:migration <name> --module <module> # Add a migration
|
|
47
|
+
shiva make:seed <name> --module <module> # Add a seeder
|
|
48
|
+
shiva make:test <name> --module <module> # Add a test spec
|
|
49
|
+
shiva make:contract <name> # Add a shared contract
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Database
|
|
53
|
+
```bash
|
|
54
|
+
shiva migrate # Run all pending migrations
|
|
55
|
+
shiva migrate:rollback # Roll back the last batch
|
|
56
|
+
shiva migrate:rollback --steps=3 # Roll back 3 batches
|
|
57
|
+
shiva migrate:status # Show migration status table
|
|
58
|
+
shiva seed # Run all seeders
|
|
59
|
+
shiva seed --module shiva-economy # Seed a specific module
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Modules
|
|
63
|
+
```bash
|
|
64
|
+
shiva module:list # List all installed modules with status
|
|
65
|
+
shiva module:status # Detailed view (version, deps, health)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Packages
|
|
69
|
+
```bash
|
|
70
|
+
shiva install shiva-fishing # Install from registry
|
|
71
|
+
shiva install shiva-fishing@1.2.0 # Install a specific version
|
|
72
|
+
shiva update # Update all modules
|
|
73
|
+
shiva update shiva-economy # Update one module
|
|
74
|
+
shiva outdated # Show available updates
|
|
75
|
+
shiva remove shiva-fishing # Remove a module
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Testing
|
|
79
|
+
```bash
|
|
80
|
+
shiva test # Run all module test suites
|
|
81
|
+
shiva test --module shiva-economy # Test a specific module
|
|
82
|
+
shiva test --filter "transfer" # Filter by test name
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Config & Locale
|
|
86
|
+
```bash
|
|
87
|
+
shiva config:validate # Validate all module configs
|
|
88
|
+
shiva locale:missing # Find missing translation keys
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### AI Integration
|
|
92
|
+
```bash
|
|
93
|
+
shiva ai:context # Generate AGENTS.md from installed modules
|
|
94
|
+
shiva ai:context --module economy # For a specific module
|
|
95
|
+
shiva ai:link # Create CLAUDE.md and GEMINI.md symlinks
|
|
96
|
+
shiva ai:mcp # Generate .mcp.json for AI tool connections
|
|
97
|
+
shiva mcp start # Start the MCP server (stdio)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Documentation
|
|
101
|
+
```bash
|
|
102
|
+
shiva docs:api # Generate API reference from LuaLS annotations
|
|
103
|
+
shiva docs:build # Build docs site (delegates to shiva-docs)
|
|
104
|
+
shiva docs:serve # Local dev server (delegates to shiva-docs)
|
|
105
|
+
shiva docs:deploy # Deploy docs (delegates to shiva-docs)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Package Management
|
|
109
|
+
|
|
110
|
+
Projects use `shiva.json` (like `package.json`) and `shiva.lock`:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"name": "my-rp-server",
|
|
115
|
+
"framework": "shiva-core@1.0.0",
|
|
116
|
+
"modules": {
|
|
117
|
+
"shiva-player": "^1.0.0",
|
|
118
|
+
"shiva-economy": "^1.0.0",
|
|
119
|
+
"shiva-police": "^1.0.0",
|
|
120
|
+
"my-fishing": "file:./custom-modules/fishing"
|
|
121
|
+
},
|
|
122
|
+
"database": {
|
|
123
|
+
"host": "127.0.0.1",
|
|
124
|
+
"user": "root",
|
|
125
|
+
"password": "",
|
|
126
|
+
"database": "shiva"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Version constraints follow semver: `^1.0.0` (compatible), `~1.0.0` (patch only), `1.0.0` (exact), `>=1.0.0 <2.0.0` (range).
|
|
132
|
+
|
|
133
|
+
## MCP Server
|
|
134
|
+
|
|
135
|
+
The MCP server exposes live framework context to AI assistants (Claude Code, Cursor, Windsurf, etc.):
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
shiva mcp start
|
|
139
|
+
# Listening on stdio — add to your editor's MCP config
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
| Tool | Description |
|
|
143
|
+
|------|-------------|
|
|
144
|
+
| `shiva:getContractMethods` | Methods, args, and return types for a contract |
|
|
145
|
+
| `shiva:getModuleConfig` | Config schema with defaults and current values |
|
|
146
|
+
| `shiva:getRegisteredEvents` | All events across modules with payload shapes |
|
|
147
|
+
| `shiva:getInstalledModules` | Installed modules, versions, dependency tree |
|
|
148
|
+
| `shiva:getServiceMethods` | Service methods including extensions |
|
|
149
|
+
| `shiva:getDatabaseSchema` | All tables, columns, and types |
|
|
150
|
+
| `shiva:getMigrationStatus` | Which migrations have run |
|
|
151
|
+
| `shiva:getAvailableCommands` | Registered commands with args and permissions |
|
|
152
|
+
| `shiva:getItemDefinitions` | All registered inventory items |
|
|
153
|
+
| `shiva:getJobDefinitions` | All jobs, grades, and salaries |
|
|
154
|
+
| `shiva:searchDocs` | Full-text search across framework docs |
|
|
155
|
+
|
|
156
|
+
## Requirements
|
|
157
|
+
|
|
158
|
+
- Node.js 18+
|
|
159
|
+
- Lua 5.4 (for `shiva test`)
|
|
160
|
+
- MySQL/MariaDB (for migration commands)
|
|
161
|
+
|
|
162
|
+
## Related Repositories
|
|
163
|
+
|
|
164
|
+
| Repo | Purpose |
|
|
165
|
+
|------|---------|
|
|
166
|
+
| [shiva-core](https://github.com/adrianmejias/shiva-core) | FiveM framework engine |
|
|
167
|
+
| [shiva-fw](https://github.com/adrianmejias/shiva-fw) | Shared Lua foundation |
|
|
168
|
+
| [shiva-modules](https://github.com/adrianmejias/shiva-modules) | 71 default RP modules |
|
|
169
|
+
| [shiva-test](https://github.com/adrianmejias/shiva-test) | Lua testing framework |
|
|
170
|
+
| [shiva-api](https://github.com/adrianmejias/shiva-api) | External REST API server |
|
|
171
|
+
| [shiva-docs](https://github.com/adrianmejias/shiva-docs) | Documentation site |
|
|
172
|
+
| [shiva-panel](https://github.com/adrianmejias/shiva-panel) | Admin panel |
|
|
173
|
+
| [shiva](https://github.com/adrianmejias/shiva) | FiveM Docker boilerplate |
|
|
174
|
+
| [shiva-boot](https://github.com/adrianmejias/shiva-boot) | Server boot scripts |
|
|
175
|
+
| [shiva-db](https://github.com/adrianmejias/shiva-db) | Database utilities |
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT
|
package/bin/shiva.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shiva-fw/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Developer CLI for the Shiva FiveM framework",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"shiva": "bin/shiva.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "jest",
|
|
11
|
+
"lint": "eslint src/**/*.js bin/**/*.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"fivem",
|
|
15
|
+
"shiva",
|
|
16
|
+
"cli",
|
|
17
|
+
"framework"
|
|
18
|
+
],
|
|
19
|
+
"author": "Adrian Mejias",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"type": "commonjs",
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18.0.0"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
27
|
+
"chalk": "^4.1.2",
|
|
28
|
+
"commander": "^12.1.0",
|
|
29
|
+
"glob": "^8.1.0",
|
|
30
|
+
"inquirer": "^8.2.6",
|
|
31
|
+
"mysql2": "^3.9.7",
|
|
32
|
+
"semver": "^7.6.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"eslint": "^8.57.1",
|
|
36
|
+
"jest": "^29.7.0"
|
|
37
|
+
},
|
|
38
|
+
"jest": {
|
|
39
|
+
"testMatch": [
|
|
40
|
+
"**/tests/**/*.test.js"
|
|
41
|
+
],
|
|
42
|
+
"testEnvironment": "node"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "full-rp",
|
|
3
|
+
"description": "Full RP experience — 71 modules",
|
|
4
|
+
"modules": {
|
|
5
|
+
"shiva-player": "^1.0.0",
|
|
6
|
+
"shiva-identity": "^1.0.0",
|
|
7
|
+
"shiva-jobs": "^1.0.0",
|
|
8
|
+
"shiva-economy": "^1.0.0",
|
|
9
|
+
"shiva-inventory": "^1.0.0",
|
|
10
|
+
"shiva-vehicles": "^1.0.0",
|
|
11
|
+
"shiva-housing": "^1.0.0",
|
|
12
|
+
"shiva-phone": "^1.0.0",
|
|
13
|
+
"shiva-hud": "^1.0.0",
|
|
14
|
+
"shiva-map": "^1.0.0",
|
|
15
|
+
"shiva-chat": "^1.0.0",
|
|
16
|
+
"shiva-permissions": "^1.0.0",
|
|
17
|
+
"shiva-admin": "^1.0.0",
|
|
18
|
+
"shiva-ban": "^1.0.0",
|
|
19
|
+
"shiva-logs": "^1.0.0",
|
|
20
|
+
"shiva-spawn": "^1.0.0",
|
|
21
|
+
"shiva-death": "^1.0.0",
|
|
22
|
+
"shiva-hunger": "^1.0.0",
|
|
23
|
+
"shiva-shops": "^1.0.0",
|
|
24
|
+
"shiva-garage": "^1.0.0",
|
|
25
|
+
"shiva-fuel": "^1.0.0",
|
|
26
|
+
"shiva-atm": "^1.0.0",
|
|
27
|
+
"shiva-crafting": "^1.0.0",
|
|
28
|
+
"shiva-notifications": "^1.0.0",
|
|
29
|
+
"shiva-police": "^1.0.0",
|
|
30
|
+
"shiva-ems": "^1.0.0",
|
|
31
|
+
"shiva-mechanic": "^1.0.0",
|
|
32
|
+
"shiva-trucker": "^1.0.0",
|
|
33
|
+
"shiva-taxi": "^1.0.0",
|
|
34
|
+
"shiva-restaurant": "^1.0.0",
|
|
35
|
+
"shiva-drugs": "^1.0.0",
|
|
36
|
+
"shiva-robbery": "^1.0.0",
|
|
37
|
+
"shiva-casino": "^1.0.0",
|
|
38
|
+
"shiva-racing": "^1.0.0",
|
|
39
|
+
"shiva-fishing": "^1.0.0",
|
|
40
|
+
"shiva-hunting": "^1.0.0",
|
|
41
|
+
"shiva-farming": "^1.0.0",
|
|
42
|
+
"shiva-realtor": "^1.0.0",
|
|
43
|
+
"shiva-tattoo": "^1.0.0",
|
|
44
|
+
"shiva-barbershop": "^1.0.0",
|
|
45
|
+
"shiva-cardealer": "^1.0.0",
|
|
46
|
+
"shiva-weapons": "^1.0.0",
|
|
47
|
+
"shiva-ammo": "^1.0.0",
|
|
48
|
+
"shiva-shooting-range": "^1.0.0",
|
|
49
|
+
"shiva-prison": "^1.0.0",
|
|
50
|
+
"shiva-court": "^1.0.0",
|
|
51
|
+
"shiva-lawyer": "^1.0.0",
|
|
52
|
+
"shiva-judge": "^1.0.0",
|
|
53
|
+
"shiva-bank": "^1.0.0",
|
|
54
|
+
"shiva-loan": "^1.0.0",
|
|
55
|
+
"shiva-insurance": "^1.0.0",
|
|
56
|
+
"shiva-business": "^1.0.0",
|
|
57
|
+
"shiva-billboard": "^1.0.0",
|
|
58
|
+
"shiva-news": "^1.0.0",
|
|
59
|
+
"shiva-radio": "^1.0.0",
|
|
60
|
+
"shiva-mayor": "^1.0.0",
|
|
61
|
+
"shiva-election": "^1.0.0",
|
|
62
|
+
"shiva-gang": "^1.0.0",
|
|
63
|
+
"shiva-turf": "^1.0.0",
|
|
64
|
+
"shiva-black-market": "^1.0.0",
|
|
65
|
+
"shiva-carjack": "^1.0.0",
|
|
66
|
+
"shiva-heist": "^1.0.0",
|
|
67
|
+
"shiva-kidnap": "^1.0.0",
|
|
68
|
+
"shiva-hitman": "^1.0.0",
|
|
69
|
+
"shiva-taxi-dispatch": "^1.0.0",
|
|
70
|
+
"shiva-ambulance-dispatch": "^1.0.0",
|
|
71
|
+
"shiva-police-dispatch": "^1.0.0",
|
|
72
|
+
"shiva-towing": "^1.0.0",
|
|
73
|
+
"shiva-impound": "^1.0.0",
|
|
74
|
+
"shiva-evidence": "^1.0.0",
|
|
75
|
+
"shiva-forensics": "^1.0.0"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "minimal",
|
|
3
|
+
"description": "Essential modules for a minimal FiveM server — 24 modules",
|
|
4
|
+
"modules": {
|
|
5
|
+
"shiva-player": "^1.0.0",
|
|
6
|
+
"shiva-identity": "^1.0.0",
|
|
7
|
+
"shiva-jobs": "^1.0.0",
|
|
8
|
+
"shiva-economy": "^1.0.0",
|
|
9
|
+
"shiva-inventory": "^1.0.0",
|
|
10
|
+
"shiva-vehicles": "^1.0.0",
|
|
11
|
+
"shiva-housing": "^1.0.0",
|
|
12
|
+
"shiva-phone": "^1.0.0",
|
|
13
|
+
"shiva-hud": "^1.0.0",
|
|
14
|
+
"shiva-map": "^1.0.0",
|
|
15
|
+
"shiva-chat": "^1.0.0",
|
|
16
|
+
"shiva-permissions": "^1.0.0",
|
|
17
|
+
"shiva-admin": "^1.0.0",
|
|
18
|
+
"shiva-ban": "^1.0.0",
|
|
19
|
+
"shiva-logs": "^1.0.0",
|
|
20
|
+
"shiva-spawn": "^1.0.0",
|
|
21
|
+
"shiva-death": "^1.0.0",
|
|
22
|
+
"shiva-hunger": "^1.0.0",
|
|
23
|
+
"shiva-shops": "^1.0.0",
|
|
24
|
+
"shiva-garage": "^1.0.0",
|
|
25
|
+
"shiva-fuel": "^1.0.0",
|
|
26
|
+
"shiva-atm": "^1.0.0",
|
|
27
|
+
"shiva-crafting": "^1.0.0",
|
|
28
|
+
"shiva-notifications": "^1.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "standard",
|
|
3
|
+
"description": "Standard RP server — 40 modules (recommended starting point)",
|
|
4
|
+
"modules": {
|
|
5
|
+
"shiva-player": "^1.0.0",
|
|
6
|
+
"shiva-identity": "^1.0.0",
|
|
7
|
+
"shiva-jobs": "^1.0.0",
|
|
8
|
+
"shiva-economy": "^1.0.0",
|
|
9
|
+
"shiva-inventory": "^1.0.0",
|
|
10
|
+
"shiva-vehicles": "^1.0.0",
|
|
11
|
+
"shiva-housing": "^1.0.0",
|
|
12
|
+
"shiva-phone": "^1.0.0",
|
|
13
|
+
"shiva-hud": "^1.0.0",
|
|
14
|
+
"shiva-map": "^1.0.0",
|
|
15
|
+
"shiva-chat": "^1.0.0",
|
|
16
|
+
"shiva-permissions": "^1.0.0",
|
|
17
|
+
"shiva-admin": "^1.0.0",
|
|
18
|
+
"shiva-ban": "^1.0.0",
|
|
19
|
+
"shiva-logs": "^1.0.0",
|
|
20
|
+
"shiva-spawn": "^1.0.0",
|
|
21
|
+
"shiva-death": "^1.0.0",
|
|
22
|
+
"shiva-hunger": "^1.0.0",
|
|
23
|
+
"shiva-shops": "^1.0.0",
|
|
24
|
+
"shiva-garage": "^1.0.0",
|
|
25
|
+
"shiva-fuel": "^1.0.0",
|
|
26
|
+
"shiva-atm": "^1.0.0",
|
|
27
|
+
"shiva-crafting": "^1.0.0",
|
|
28
|
+
"shiva-notifications": "^1.0.0",
|
|
29
|
+
"shiva-police": "^1.0.0",
|
|
30
|
+
"shiva-ems": "^1.0.0",
|
|
31
|
+
"shiva-mechanic": "^1.0.0",
|
|
32
|
+
"shiva-trucker": "^1.0.0",
|
|
33
|
+
"shiva-taxi": "^1.0.0",
|
|
34
|
+
"shiva-restaurant": "^1.0.0",
|
|
35
|
+
"shiva-drugs": "^1.0.0",
|
|
36
|
+
"shiva-robbery": "^1.0.0",
|
|
37
|
+
"shiva-casino": "^1.0.0",
|
|
38
|
+
"shiva-racing": "^1.0.0",
|
|
39
|
+
"shiva-fishing": "^1.0.0",
|
|
40
|
+
"shiva-hunting": "^1.0.0",
|
|
41
|
+
"shiva-farming": "^1.0.0",
|
|
42
|
+
"shiva-realtor": "^1.0.0",
|
|
43
|
+
"shiva-tattoo": "^1.0.0",
|
|
44
|
+
"shiva-barbershop": "^1.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
const { requireServerRoot, getResourcesDir } = require('../../utils/server-root');
|
|
8
|
+
const { scanModules } = require('../../utils/lua-parser');
|
|
9
|
+
const { normalizeModuleName } = require('../../generators/index');
|
|
10
|
+
|
|
11
|
+
function aiContextCommand(program) {
|
|
12
|
+
program
|
|
13
|
+
.command('ai:context')
|
|
14
|
+
.description('Generate AGENTS.md from installed modules')
|
|
15
|
+
.option('-m, --module <module>', 'Generate context for a specific module only')
|
|
16
|
+
.option('-o, --output <path>', 'Output file path', 'AGENTS.md')
|
|
17
|
+
.action((options) => { run(options); });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function run(options) {
|
|
21
|
+
const serverRoot = requireServerRoot();
|
|
22
|
+
const resourcesDir = getResourcesDir(serverRoot);
|
|
23
|
+
let modules = scanModules(resourcesDir);
|
|
24
|
+
|
|
25
|
+
if (options.module) {
|
|
26
|
+
const name = normalizeModuleName(options.module);
|
|
27
|
+
modules = modules.filter(m => m.name === name);
|
|
28
|
+
if (modules.length === 0) {
|
|
29
|
+
console.error(chalk.red(`✖ Module not found: ${name}`));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const lines = [];
|
|
35
|
+
lines.push('# Shiva Server — AI Agent Context');
|
|
36
|
+
lines.push('');
|
|
37
|
+
lines.push('> Auto-generated by `shiva ai:context`. Do not edit manually.');
|
|
38
|
+
lines.push('');
|
|
39
|
+
lines.push(`Generated: ${new Date().toISOString()}`);
|
|
40
|
+
lines.push('');
|
|
41
|
+
lines.push('## Installed Modules');
|
|
42
|
+
lines.push('');
|
|
43
|
+
lines.push(`${modules.length} module(s) installed.`);
|
|
44
|
+
lines.push('');
|
|
45
|
+
|
|
46
|
+
for (const mod of modules) {
|
|
47
|
+
const m = mod.manifest;
|
|
48
|
+
lines.push(`### ${mod.name}`);
|
|
49
|
+
lines.push('');
|
|
50
|
+
if (m.description) lines.push(m.description);
|
|
51
|
+
lines.push('');
|
|
52
|
+
lines.push(`- **Version**: ${m.version || '?'}`);
|
|
53
|
+
if ((m.dependencies || []).length > 0) {
|
|
54
|
+
lines.push(`- **Dependencies**: ${m.dependencies.join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
if ((m.provides || []).length > 0) {
|
|
57
|
+
lines.push(`- **Provides**: ${m.provides.join(', ')}`);
|
|
58
|
+
}
|
|
59
|
+
if ((m.events || []).length > 0) {
|
|
60
|
+
lines.push('- **Events**:');
|
|
61
|
+
m.events.forEach(e => lines.push(` - \`${e}\``));
|
|
62
|
+
}
|
|
63
|
+
if ((m.migrations || []).length > 0) {
|
|
64
|
+
lines.push(`- **Migrations**: ${m.migrations.length}`);
|
|
65
|
+
}
|
|
66
|
+
lines.push('');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const contractsDir = path.join(serverRoot, 'shared', 'contracts');
|
|
70
|
+
if (fs.existsSync(contractsDir)) {
|
|
71
|
+
const contracts = fs.readdirSync(contractsDir).filter(f => f.endsWith('.lua'));
|
|
72
|
+
if (contracts.length > 0) {
|
|
73
|
+
lines.push('## Contracts');
|
|
74
|
+
lines.push('');
|
|
75
|
+
contracts.forEach(f => lines.push(`- \`${f.replace('.lua', '')}\``));
|
|
76
|
+
lines.push('');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const outPath = path.resolve(serverRoot, options.output);
|
|
81
|
+
fs.writeFileSync(outPath, lines.join('\n'), 'utf-8');
|
|
82
|
+
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log(chalk.green(`✔ Generated ${path.relative(process.cwd(), outPath)}`));
|
|
85
|
+
console.log(chalk.gray(` ${modules.length} modules documented.`));
|
|
86
|
+
console.log('');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = aiContextCommand;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const { requireServerRoot } = require('../../utils/server-root');
|
|
7
|
+
|
|
8
|
+
function aiLinkCommand(program) {
|
|
9
|
+
program
|
|
10
|
+
.command('ai:link')
|
|
11
|
+
.description('Create CLAUDE.md and GEMINI.md symlinks pointing at AGENTS.md')
|
|
12
|
+
.action(() => { run(); });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function run() {
|
|
16
|
+
const serverRoot = requireServerRoot();
|
|
17
|
+
const agentsFile = path.join(serverRoot, 'AGENTS.md');
|
|
18
|
+
const targets = ['CLAUDE.md', 'GEMINI.md'];
|
|
19
|
+
|
|
20
|
+
if (!fs.existsSync(agentsFile)) {
|
|
21
|
+
console.error(chalk.red('✖ AGENTS.md not found. Run `shiva ai:context` first.'));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log('');
|
|
26
|
+
for (const target of targets) {
|
|
27
|
+
const linkPath = path.join(serverRoot, target);
|
|
28
|
+
try {
|
|
29
|
+
const stat = fs.lstatSync(linkPath);
|
|
30
|
+
if (stat) fs.unlinkSync(linkPath);
|
|
31
|
+
} catch {}
|
|
32
|
+
fs.symlinkSync('AGENTS.md', linkPath);
|
|
33
|
+
console.log(chalk.green(`✔ ${target} → AGENTS.md`));
|
|
34
|
+
}
|
|
35
|
+
console.log('');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = aiLinkCommand;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const { requireServerRoot } = require('../../utils/server-root');
|
|
7
|
+
const { readShivaConfig } = require('../../utils/config-reader');
|
|
8
|
+
|
|
9
|
+
function aiMcpCommand(program) {
|
|
10
|
+
program
|
|
11
|
+
.command('ai:mcp')
|
|
12
|
+
.description('Generate .mcp.json for AI tool integrations')
|
|
13
|
+
.option('-p, --port <port>', 'MCP server port', '3100')
|
|
14
|
+
.action((options) => { run(options); });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function run(options) {
|
|
18
|
+
const serverRoot = requireServerRoot();
|
|
19
|
+
const mcpJson = {
|
|
20
|
+
mcpServers: {
|
|
21
|
+
shiva: {
|
|
22
|
+
command: 'shiva',
|
|
23
|
+
args: ['mcp', 'start'],
|
|
24
|
+
env: {},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const outPath = path.join(serverRoot, '.mcp.json');
|
|
30
|
+
fs.writeFileSync(outPath, JSON.stringify(mcpJson, null, 2) + '\n', 'utf-8');
|
|
31
|
+
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(chalk.green('✔ Created .mcp.json'));
|
|
34
|
+
console.log(chalk.gray(' Add this to your Claude Code / Cursor / Windsurf MCP config.'));
|
|
35
|
+
console.log(chalk.gray(' Start the server with: shiva mcp start'));
|
|
36
|
+
console.log('');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = aiMcpCommand;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
const { requireServerRoot, getResourcesDir } = require('../../utils/server-root');
|
|
8
|
+
const { scanModules } = require('../../utils/lua-parser');
|
|
9
|
+
|
|
10
|
+
function configValidateCommand(program) {
|
|
11
|
+
program
|
|
12
|
+
.command('config:validate')
|
|
13
|
+
.description('Validate module configuration files')
|
|
14
|
+
.action(() => { run(); });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function run() {
|
|
18
|
+
const serverRoot = requireServerRoot();
|
|
19
|
+
const resourcesDir = getResourcesDir(serverRoot);
|
|
20
|
+
const modules = scanModules(resourcesDir);
|
|
21
|
+
|
|
22
|
+
let passed = 0;
|
|
23
|
+
let warned = 0;
|
|
24
|
+
let failed = 0;
|
|
25
|
+
|
|
26
|
+
console.log('');
|
|
27
|
+
console.log(chalk.bold('Config Validation'));
|
|
28
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
29
|
+
|
|
30
|
+
for (const mod of modules) {
|
|
31
|
+
const configFile = path.join(mod.path, 'config', 'config.lua');
|
|
32
|
+
|
|
33
|
+
if (!fs.existsSync(configFile)) {
|
|
34
|
+
console.log(chalk.yellow(` ⚠ ${mod.name.padEnd(28)} no config/config.lua`));
|
|
35
|
+
warned++;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const content = fs.readFileSync(configFile, 'utf-8');
|
|
40
|
+
|
|
41
|
+
if (!content.includes('Config.register(')) {
|
|
42
|
+
console.log(chalk.yellow(` ⚠ ${mod.name.padEnd(28)} Config.register() not found`));
|
|
43
|
+
warned++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const hasPlaceholder = /--\s*TODO/.test(content) && !/Config\.register\([^)]+,\s*\{[^}]+\}/.test(content);
|
|
48
|
+
if (hasPlaceholder) {
|
|
49
|
+
console.log(chalk.yellow(` ⚠ ${mod.name.padEnd(28)} config appears to be a stub`));
|
|
50
|
+
warned++;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log(chalk.green(` ✔ ${mod.name}`));
|
|
55
|
+
passed++;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
59
|
+
console.log(` ${chalk.green(passed + ' passed')} · ${chalk.yellow(warned + ' warnings')} · ${chalk.red(failed + ' failed')}`);
|
|
60
|
+
console.log('');
|
|
61
|
+
|
|
62
|
+
if (failed > 0) process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = configValidateCommand;
|