kastell 2.2.4 → 2.2.6
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/.claude-plugin/marketplace.json +18 -18
- package/.claude-plugin/plugin.json +45 -38
- package/CHANGELOG.md +1313 -1266
- package/LICENSE +201 -201
- package/NOTICE +5 -5
- package/README.md +1 -1
- package/README.tr.md +1 -1
- package/bin/kastell +2 -2
- package/bin/kastell-mcp +5 -5
- package/dist/adapters/coolify.js +92 -92
- package/dist/adapters/dokploy.js +99 -99
- package/dist/commands/fix.d.ts +2 -0
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +26 -1
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/interactive/plugins.d.ts.map +1 -1
- package/dist/commands/interactive/plugins.js +26 -2
- package/dist/commands/interactive/plugins.js.map +1 -1
- package/dist/commands/plugin.d.ts.map +1 -1
- package/dist/commands/plugin.js +6 -2
- package/dist/commands/plugin.js.map +1 -1
- package/dist/core/audit/commands.d.ts +13 -2
- package/dist/core/audit/commands.d.ts.map +1 -1
- package/dist/core/audit/commands.js +39 -2
- package/dist/core/audit/commands.js.map +1 -1
- package/dist/core/audit/explainCheck.d.ts +1 -0
- package/dist/core/audit/explainCheck.d.ts.map +1 -1
- package/dist/core/audit/explainCheck.js +1 -1
- package/dist/core/audit/explainCheck.js.map +1 -1
- package/dist/core/audit/fix-history.d.ts +3 -1
- package/dist/core/audit/fix-history.d.ts.map +1 -1
- package/dist/core/audit/fix-history.js +6 -2
- package/dist/core/audit/fix-history.js.map +1 -1
- package/dist/core/audit/fix.d.ts.map +1 -1
- package/dist/core/audit/fix.js +22 -0
- package/dist/core/audit/fix.js.map +1 -1
- package/dist/core/audit/formatters/badge.js +20 -20
- package/dist/core/audit/index.d.ts.map +1 -1
- package/dist/core/audit/index.js +12 -3
- package/dist/core/audit/index.js.map +1 -1
- package/dist/core/audit/listChecks.d.ts.map +1 -1
- package/dist/core/audit/listChecks.js +24 -0
- package/dist/core/audit/listChecks.js.map +1 -1
- package/dist/core/audit/pluginAudit.d.ts +8 -0
- package/dist/core/audit/pluginAudit.d.ts.map +1 -0
- package/dist/core/audit/pluginAudit.js +134 -0
- package/dist/core/audit/pluginAudit.js.map +1 -0
- package/dist/core/audit/pluginFix.d.ts +19 -0
- package/dist/core/audit/pluginFix.d.ts.map +1 -0
- package/dist/core/audit/pluginFix.js +122 -0
- package/dist/core/audit/pluginFix.js.map +1 -0
- package/dist/core/audit/snapshot.d.ts +4 -4
- package/dist/core/audit/types.d.ts +2 -1
- package/dist/core/audit/types.d.ts.map +1 -1
- package/dist/core/completions.js +631 -631
- package/dist/core/plugin.d.ts +6 -0
- package/dist/core/plugin.d.ts.map +1 -1
- package/dist/core/plugin.js +2 -0
- package/dist/core/plugin.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/pluginTools.d.ts +5 -0
- package/dist/mcp/pluginTools.d.ts.map +1 -0
- package/dist/mcp/pluginTools.js +54 -0
- package/dist/mcp/pluginTools.js.map +1 -0
- package/dist/mcp/prompts/workflows.d.ts +17 -0
- package/dist/mcp/prompts/workflows.d.ts.map +1 -0
- package/dist/mcp/prompts/workflows.js +73 -0
- package/dist/mcp/prompts/workflows.js.map +1 -0
- package/dist/mcp/resources/checks.d.ts +4 -0
- package/dist/mcp/resources/checks.d.ts.map +1 -0
- package/dist/mcp/resources/checks.js +49 -0
- package/dist/mcp/resources/checks.js.map +1 -0
- package/dist/mcp/resources/servers.d.ts +4 -0
- package/dist/mcp/resources/servers.d.ts.map +1 -0
- package/dist/mcp/resources/servers.js +59 -0
- package/dist/mcp/resources/servers.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +68 -35
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/serverAudit.d.ts +1 -1
- package/dist/mcp/tools/serverExplain.d.ts.map +1 -1
- package/dist/mcp/tools/serverExplain.js.map +1 -1
- package/dist/mcp/tools/serverFix.d.ts.map +1 -1
- package/dist/mcp/tools/serverFix.js +7 -1
- package/dist/mcp/tools/serverFix.js.map +1 -1
- package/dist/mcp/tools/serverFleet.d.ts.map +1 -1
- package/dist/mcp/tools/serverFleet.js.map +1 -1
- package/dist/mcp/tools/serverInfo.d.ts +1 -1
- package/dist/mcp/tools/serverInfo.js +1 -1
- package/dist/mcp/tools/serverManage.d.ts +2 -1
- package/dist/mcp/tools/serverManage.d.ts.map +1 -1
- package/dist/mcp/tools/serverManage.js +50 -5
- package/dist/mcp/tools/serverManage.js.map +1 -1
- package/dist/mcp/tools/serverPlugin.d.ts +3 -0
- package/dist/mcp/tools/serverPlugin.d.ts.map +1 -1
- package/dist/mcp/tools/serverPlugin.js +11 -1
- package/dist/mcp/tools/serverPlugin.js.map +1 -1
- package/dist/mcp/tools/serverProvision.d.ts +5 -5
- package/dist/mcp/tools/serverProvision.d.ts.map +1 -1
- package/dist/mcp/tools/serverProvision.js +31 -9
- package/dist/mcp/tools/serverProvision.js.map +1 -1
- package/dist/mcp/tools/serverSecure.d.ts.map +1 -1
- package/dist/mcp/tools/serverSecure.js +30 -1
- package/dist/mcp/tools/serverSecure.js.map +1 -1
- package/dist/mcp/utils.d.ts +25 -0
- package/dist/mcp/utils.d.ts.map +1 -1
- package/dist/mcp/utils.js +36 -0
- package/dist/mcp/utils.js.map +1 -1
- package/dist/mcp-bundle.mjs +102301 -0
- package/dist/plugin/handlerResolver.d.ts +2 -0
- package/dist/plugin/handlerResolver.d.ts.map +1 -0
- package/dist/plugin/handlerResolver.js +16 -0
- package/dist/plugin/handlerResolver.js.map +1 -0
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +41 -4
- package/dist/plugin/loader.js.map +1 -1
- package/dist/plugin/registerCommands.d.ts +4 -0
- package/dist/plugin/registerCommands.d.ts.map +1 -0
- package/dist/plugin/registerCommands.js +45 -0
- package/dist/plugin/registerCommands.js.map +1 -0
- package/dist/plugin/registry.d.ts +20 -1
- package/dist/plugin/registry.d.ts.map +1 -1
- package/dist/plugin/registry.js +51 -1
- package/dist/plugin/registry.js.map +1 -1
- package/dist/plugin/sdk/constants.d.ts +2 -0
- package/dist/plugin/sdk/constants.d.ts.map +1 -1
- package/dist/plugin/sdk/constants.js +2 -0
- package/dist/plugin/sdk/constants.js.map +1 -1
- package/dist/plugin/sdk/types.d.ts +74 -1
- package/dist/plugin/sdk/types.d.ts.map +1 -1
- package/dist/plugin/validate.d.ts +2 -1
- package/dist/plugin/validate.d.ts.map +1 -1
- package/dist/plugin/validate.js +106 -1
- package/dist/plugin/validate.js.map +1 -1
- package/dist/utils/cloudInit.js +58 -58
- package/dist/utils/fileLock.d.ts +5 -1
- package/dist/utils/fileLock.d.ts.map +1 -1
- package/dist/utils/fileLock.js +70 -15
- package/dist/utils/fileLock.js.map +1 -1
- package/dist/utils/paths.d.ts +0 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +1 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/secureWrite.d.ts.map +1 -1
- package/dist/utils/secureWrite.js +3 -38
- package/dist/utils/secureWrite.js.map +1 -1
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +19 -4
- package/dist/utils/version.js.map +1 -1
- package/kastell-plugin/.claude-plugin/plugin.json +20 -20
- package/kastell-plugin/.mcp.json +15 -8
- package/kastell-plugin/README.md +113 -113
- package/kastell-plugin/agents/kastell-auditor.md +77 -77
- package/kastell-plugin/agents/scripts/bucket_mapper.sh +101 -101
- package/kastell-plugin/agents/scripts/trend_report.sh +91 -91
- package/kastell-plugin/hooks/destroy-block.cjs +31 -31
- package/kastell-plugin/hooks/hooks.json +57 -57
- package/kastell-plugin/hooks/pre-commit-audit-guard.cjs +75 -75
- package/kastell-plugin/hooks/session-audit.cjs +86 -86
- package/kastell-plugin/hooks/session-log.cjs +56 -56
- package/kastell-plugin/hooks/stop-quality-check.cjs +72 -72
- package/kastell-plugin/skills/kastell-careful/SKILL.md +64 -64
- package/kastell-plugin/skills/kastell-ops/SKILL.md +139 -139
- package/kastell-plugin/skills/kastell-ops/references/commands.md +45 -45
- package/kastell-plugin/skills/kastell-ops/references/mcp-tools.md +50 -50
- package/kastell-plugin/skills/kastell-ops/references/patterns.md +145 -145
- package/kastell-plugin/skills/kastell-ops/references/pitfalls.md +136 -136
- package/kastell-plugin/skills/kastell-ops/scripts/check_coverage.sh +101 -101
- package/kastell-plugin/skills/kastell-ops/scripts/fleet_report.sh +73 -73
- package/kastell-plugin/skills/kastell-ops/scripts/parse_audit.sh +76 -76
- package/kastell-plugin/skills/kastell-research/SKILL.md +90 -90
- package/kastell-plugin/skills/kastell-scaffold/SKILL.md +104 -104
- package/kastell-plugin/skills/kastell-scaffold/references/template-audit-check.md +150 -150
- package/kastell-plugin/skills/kastell-scaffold/references/template-command.md +80 -80
- package/kastell-plugin/skills/kastell-scaffold/references/template-mcp-tool.md +72 -72
- package/kastell-plugin/skills/kastell-scaffold/references/template-provider.md +67 -67
- package/kastell-plugin/skills/kastell-scaffold/scripts/scaffold.sh +180 -180
- package/kastell-plugin/skills/kastell-scaffold/templates/check-test.ts.tpl +27 -27
- package/kastell-plugin/skills/kastell-scaffold/templates/check.ts.tpl +50 -50
- package/kastell-plugin/skills/kastell-scaffold/templates/command-core.ts.tpl +18 -18
- package/kastell-plugin/skills/kastell-scaffold/templates/command-test.ts.tpl +17 -17
- package/kastell-plugin/skills/kastell-scaffold/templates/command.ts.tpl +25 -25
- package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool-test.ts.tpl +30 -30
- package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool.ts.tpl +29 -29
- package/kastell-plugin/skills/kastell-scaffold/templates/provider-test.ts.tpl +34 -34
- package/kastell-plugin/skills/kastell-scaffold/templates/provider.ts.tpl +32 -32
- package/package.json +125 -122
- package/dist/commands/interactive.d.ts +0 -11
- package/dist/commands/interactive.d.ts.map +0 -1
- package/dist/commands/interactive.js +0 -1079
- package/dist/commands/interactive.js.map +0 -1
- package/dist/core/lock.d.ts +0 -66
- package/dist/core/lock.d.ts.map +0 -1
- package/dist/core/lock.js +0 -556
- package/dist/core/lock.js.map +0 -1
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: kastell-ops
|
|
3
|
-
description: Kastell CLI patterns, architecture, anti-patterns, and decision trees. Use automatically when working in Kastell codebase or when asked about Kastell server infrastructure, security audit, hardening, lock, provision, or provider management.
|
|
4
|
-
user-invocable: false
|
|
5
|
-
allowed-tools: Bash, Read, Glob, Grep
|
|
6
|
-
effort: medium
|
|
7
|
-
memory: project
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Kastell Architecture
|
|
11
|
-
|
|
12
|
-
Kastell is a CLI toolkit for provisioning, securing, and managing self-hosted servers. TypeScript, ESM, strict mode. 31 CLI commands, 13 MCP tools, 4 cloud providers (hetzner, digitalocean, vultr, linode), 2 platform adapters (coolify, dokploy).
|
|
13
|
-
|
|
14
|
-
## Live Context
|
|
15
|
-
|
|
16
|
-
**Version:** !`node -e "import('fs').then(f=>console.log(JSON.parse(f.readFileSync('package.json','utf8')).version)).catch(()=>console.log('unknown'))"`
|
|
17
|
-
**Registered servers:**
|
|
18
|
-
!`kastell list 2>/dev/null || echo "No servers registered"`
|
|
19
|
-
|
|
20
|
-
## Architecture File Map
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
src/
|
|
24
|
-
commands/ # 31 thin CLI wrappers (parse args + delegate only)
|
|
25
|
-
core/ # Business logic (ALL computation here)
|
|
26
|
-
providers/ # Cloud API: hetzner, digitalocean, vultr, linode
|
|
27
|
-
adapters/ # Platform abstraction: coolify, dokploy
|
|
28
|
-
interface.ts # PlatformAdapter contract
|
|
29
|
-
factory.ts # getAdapter(), detectPlatform(), resolvePlatform()
|
|
30
|
-
mcp/
|
|
31
|
-
server.ts # 13 tool registrations
|
|
32
|
-
tools/ # Handler files (Zod schema + handler per tool)
|
|
33
|
-
utils/ # ssh, config, cloudInit, modeGuard, migration
|
|
34
|
-
types/ # ServerMode, ServerRecord, Platform
|
|
35
|
-
constants.ts # PROVIDER_REGISTRY (single source of truth)
|
|
36
|
-
index.ts # CLI entry point
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Layer Rules
|
|
40
|
-
|
|
41
|
-
| Layer | Path | Responsibility | Rule |
|
|
42
|
-
|----------|-----------------|-----------------------------------------|-----------------------------|
|
|
43
|
-
| Commands | src/commands/ | Parse CLI args, call core, display output | ZERO business logic |
|
|
44
|
-
| Core | src/core/ | All business logic, orchestration | No UI/chalk/ora imports |
|
|
45
|
-
| Providers| src/providers/ | Cloud API calls per provider | Implements cloud CRUD |
|
|
46
|
-
| Adapters | src/adapters/ | Platform-specific ops (Coolify/Dokploy) | Via PlatformAdapter interface |
|
|
47
|
-
| MCP | src/mcp/ | MCP server + tool handlers | Delegates to core |
|
|
48
|
-
| Utils | src/utils/ | SSH, config, modeGuard, errorMapper | Shared infrastructure |
|
|
49
|
-
|
|
50
|
-
## Adapter Contract
|
|
51
|
-
|
|
52
|
-
Access adapters via `getAdapter(platform)` from `src/adapters/factory.ts`. Never import `CoolifyAdapter` or `DokployAdapter` directly in commands.
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
interface PlatformAdapter {
|
|
56
|
-
readonly name: string; // "coolify" | "dokploy"
|
|
57
|
-
readonly port: number; // 8000 (Coolify) | 3000 (Dokploy)
|
|
58
|
-
readonly defaultLogService: string; // matches platform name
|
|
59
|
-
readonly platformPorts: readonly number[]; // ports protected from firewall removal
|
|
60
|
-
getCloudInit(serverName: string): string;
|
|
61
|
-
healthCheck(ip: string, domain?: string): Promise<HealthResult>;
|
|
62
|
-
createBackup(ip: string, serverName: string, provider: string): Promise<PlatformBackupResult>;
|
|
63
|
-
getStatus(ip: string): Promise<PlatformStatusResult>;
|
|
64
|
-
update(ip: string): Promise<UpdateResult>;
|
|
65
|
-
restoreBackup?(ip, backupPath, manifest): Promise<PlatformRestoreResult>; // optional
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Factory exports:** `getAdapter(platform)`, `detectPlatform(ip)`, `resolvePlatform(server)`
|
|
70
|
-
|
|
71
|
-
## Provider Registry
|
|
72
|
-
|
|
73
|
-
| Provider | Env Key | Display Name |
|
|
74
|
-
|--------------|---------------------|------------------|
|
|
75
|
-
| hetzner | HETZNER_TOKEN | Hetzner Cloud |
|
|
76
|
-
| digitalocean | DIGITALOCEAN_TOKEN | DigitalOcean |
|
|
77
|
-
| vultr | VULTR_TOKEN | Vultr |
|
|
78
|
-
| linode | LINODE_TOKEN | Linode (Akamai) |
|
|
79
|
-
|
|
80
|
-
`PROVIDER_REGISTRY` in `src/constants.ts` is the single source of truth for providers.
|
|
81
|
-
|
|
82
|
-
## What Do I Want to Add?
|
|
83
|
-
|
|
84
|
-
### New CLI command
|
|
85
|
-
1. `src/commands/<name>.ts` — thin wrapper (parse + delegate, no logic)
|
|
86
|
-
2. `src/core/<name>.ts` — all business logic here
|
|
87
|
-
3. `src/index.ts` — register with `program`
|
|
88
|
-
4. `src/__tests__/` — test core, not command
|
|
89
|
-
|
|
90
|
-
### New audit check
|
|
91
|
-
1. `src/core/audit/<category>/` — add to existing category
|
|
92
|
-
2. Update check catalog in `src/core/audit/catalog.ts`
|
|
93
|
-
3. No new command file needed — runs through `kastell audit`
|
|
94
|
-
|
|
95
|
-
### New provider
|
|
96
|
-
1. `src/providers/<name>.ts` — implements base.ts contract
|
|
97
|
-
2. `src/constants.ts` — add to PROVIDER_REGISTRY
|
|
98
|
-
3. No adapter changes — providers handle cloud API only
|
|
99
|
-
|
|
100
|
-
### New MCP tool
|
|
101
|
-
1. `src/mcp/tools/server<Name>.ts` — Zod schema + handler
|
|
102
|
-
2. `src/mcp/server.ts` — import + `registerTool()`
|
|
103
|
-
3. Annotations: `readOnlyHint` / `destructiveHint` / `idempotentHint`
|
|
104
|
-
|
|
105
|
-
## Key Conventions
|
|
106
|
-
|
|
107
|
-
- ESM project (`"type": "module"`) — `import`, not `require`
|
|
108
|
-
- `KASTELL_SAFE_MODE` + `isSafeMode()` = destructive operation guard
|
|
109
|
-
- `assertValidIp()` before every SSH operation
|
|
110
|
-
- `sanitizedEnv` for subprocess calls
|
|
111
|
-
- `sanitizeResponseData()` whitelist approach for API error responses
|
|
112
|
-
- Config dir: user home `kastell/` directory (auto-migrated from legacy name)
|
|
113
|
-
- `PROVIDER_REGISTRY` = single source of truth for providers
|
|
114
|
-
- `withProviderErrorHandling` HOF for consistent provider error handling
|
|
115
|
-
- `describe.each` with `jest.resetAllMocks()` (not `clearAllMocks()`)
|
|
116
|
-
|
|
117
|
-
## Scripts (Deterministic)
|
|
118
|
-
|
|
119
|
-
Run without LLM — deterministic analysis scripts:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
# Parse audit JSON into 5 security domain summaries
|
|
123
|
-
kastell audit --server myserver --json > /tmp/audit.json
|
|
124
|
-
scripts/parse_audit.sh /tmp/audit.json
|
|
125
|
-
|
|
126
|
-
# Generate fleet-wide server score table
|
|
127
|
-
kastell fleet --json > /tmp/fleet.json
|
|
128
|
-
scripts/fleet_report.sh /tmp/fleet.json
|
|
129
|
-
|
|
130
|
-
# Compare audit check count vs test coverage
|
|
131
|
-
scripts/check_coverage.sh
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Reference Files
|
|
135
|
-
|
|
136
|
-
- 31 CLI commands — see [references/commands.md](references/commands.md)
|
|
137
|
-
- 13 MCP tools — see [references/mcp-tools.md](references/mcp-tools.md)
|
|
138
|
-
- Patterns and test templates — see [references/patterns.md](references/patterns.md)
|
|
139
|
-
- Known pitfalls — see [references/pitfalls.md](references/pitfalls.md)
|
|
1
|
+
---
|
|
2
|
+
name: kastell-ops
|
|
3
|
+
description: Kastell CLI patterns, architecture, anti-patterns, and decision trees. Use automatically when working in Kastell codebase or when asked about Kastell server infrastructure, security audit, hardening, lock, provision, or provider management.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
allowed-tools: Bash, Read, Glob, Grep
|
|
6
|
+
effort: medium
|
|
7
|
+
memory: project
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Kastell Architecture
|
|
11
|
+
|
|
12
|
+
Kastell is a CLI toolkit for provisioning, securing, and managing self-hosted servers. TypeScript, ESM, strict mode. 31 CLI commands, 13 MCP tools, 4 cloud providers (hetzner, digitalocean, vultr, linode), 2 platform adapters (coolify, dokploy).
|
|
13
|
+
|
|
14
|
+
## Live Context
|
|
15
|
+
|
|
16
|
+
**Version:** !`node -e "import('fs').then(f=>console.log(JSON.parse(f.readFileSync('package.json','utf8')).version)).catch(()=>console.log('unknown'))"`
|
|
17
|
+
**Registered servers:**
|
|
18
|
+
!`kastell list 2>/dev/null || echo "No servers registered"`
|
|
19
|
+
|
|
20
|
+
## Architecture File Map
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
src/
|
|
24
|
+
commands/ # 31 thin CLI wrappers (parse args + delegate only)
|
|
25
|
+
core/ # Business logic (ALL computation here)
|
|
26
|
+
providers/ # Cloud API: hetzner, digitalocean, vultr, linode
|
|
27
|
+
adapters/ # Platform abstraction: coolify, dokploy
|
|
28
|
+
interface.ts # PlatformAdapter contract
|
|
29
|
+
factory.ts # getAdapter(), detectPlatform(), resolvePlatform()
|
|
30
|
+
mcp/
|
|
31
|
+
server.ts # 13 tool registrations
|
|
32
|
+
tools/ # Handler files (Zod schema + handler per tool)
|
|
33
|
+
utils/ # ssh, config, cloudInit, modeGuard, migration
|
|
34
|
+
types/ # ServerMode, ServerRecord, Platform
|
|
35
|
+
constants.ts # PROVIDER_REGISTRY (single source of truth)
|
|
36
|
+
index.ts # CLI entry point
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Layer Rules
|
|
40
|
+
|
|
41
|
+
| Layer | Path | Responsibility | Rule |
|
|
42
|
+
|----------|-----------------|-----------------------------------------|-----------------------------|
|
|
43
|
+
| Commands | src/commands/ | Parse CLI args, call core, display output | ZERO business logic |
|
|
44
|
+
| Core | src/core/ | All business logic, orchestration | No UI/chalk/ora imports |
|
|
45
|
+
| Providers| src/providers/ | Cloud API calls per provider | Implements cloud CRUD |
|
|
46
|
+
| Adapters | src/adapters/ | Platform-specific ops (Coolify/Dokploy) | Via PlatformAdapter interface |
|
|
47
|
+
| MCP | src/mcp/ | MCP server + tool handlers | Delegates to core |
|
|
48
|
+
| Utils | src/utils/ | SSH, config, modeGuard, errorMapper | Shared infrastructure |
|
|
49
|
+
|
|
50
|
+
## Adapter Contract
|
|
51
|
+
|
|
52
|
+
Access adapters via `getAdapter(platform)` from `src/adapters/factory.ts`. Never import `CoolifyAdapter` or `DokployAdapter` directly in commands.
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
interface PlatformAdapter {
|
|
56
|
+
readonly name: string; // "coolify" | "dokploy"
|
|
57
|
+
readonly port: number; // 8000 (Coolify) | 3000 (Dokploy)
|
|
58
|
+
readonly defaultLogService: string; // matches platform name
|
|
59
|
+
readonly platformPorts: readonly number[]; // ports protected from firewall removal
|
|
60
|
+
getCloudInit(serverName: string): string;
|
|
61
|
+
healthCheck(ip: string, domain?: string): Promise<HealthResult>;
|
|
62
|
+
createBackup(ip: string, serverName: string, provider: string): Promise<PlatformBackupResult>;
|
|
63
|
+
getStatus(ip: string): Promise<PlatformStatusResult>;
|
|
64
|
+
update(ip: string): Promise<UpdateResult>;
|
|
65
|
+
restoreBackup?(ip, backupPath, manifest): Promise<PlatformRestoreResult>; // optional
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Factory exports:** `getAdapter(platform)`, `detectPlatform(ip)`, `resolvePlatform(server)`
|
|
70
|
+
|
|
71
|
+
## Provider Registry
|
|
72
|
+
|
|
73
|
+
| Provider | Env Key | Display Name |
|
|
74
|
+
|--------------|---------------------|------------------|
|
|
75
|
+
| hetzner | HETZNER_TOKEN | Hetzner Cloud |
|
|
76
|
+
| digitalocean | DIGITALOCEAN_TOKEN | DigitalOcean |
|
|
77
|
+
| vultr | VULTR_TOKEN | Vultr |
|
|
78
|
+
| linode | LINODE_TOKEN | Linode (Akamai) |
|
|
79
|
+
|
|
80
|
+
`PROVIDER_REGISTRY` in `src/constants.ts` is the single source of truth for providers.
|
|
81
|
+
|
|
82
|
+
## What Do I Want to Add?
|
|
83
|
+
|
|
84
|
+
### New CLI command
|
|
85
|
+
1. `src/commands/<name>.ts` — thin wrapper (parse + delegate, no logic)
|
|
86
|
+
2. `src/core/<name>.ts` — all business logic here
|
|
87
|
+
3. `src/index.ts` — register with `program`
|
|
88
|
+
4. `src/__tests__/` — test core, not command
|
|
89
|
+
|
|
90
|
+
### New audit check
|
|
91
|
+
1. `src/core/audit/<category>/` — add to existing category
|
|
92
|
+
2. Update check catalog in `src/core/audit/catalog.ts`
|
|
93
|
+
3. No new command file needed — runs through `kastell audit`
|
|
94
|
+
|
|
95
|
+
### New provider
|
|
96
|
+
1. `src/providers/<name>.ts` — implements base.ts contract
|
|
97
|
+
2. `src/constants.ts` — add to PROVIDER_REGISTRY
|
|
98
|
+
3. No adapter changes — providers handle cloud API only
|
|
99
|
+
|
|
100
|
+
### New MCP tool
|
|
101
|
+
1. `src/mcp/tools/server<Name>.ts` — Zod schema + handler
|
|
102
|
+
2. `src/mcp/server.ts` — import + `registerTool()`
|
|
103
|
+
3. Annotations: `readOnlyHint` / `destructiveHint` / `idempotentHint`
|
|
104
|
+
|
|
105
|
+
## Key Conventions
|
|
106
|
+
|
|
107
|
+
- ESM project (`"type": "module"`) — `import`, not `require`
|
|
108
|
+
- `KASTELL_SAFE_MODE` + `isSafeMode()` = destructive operation guard
|
|
109
|
+
- `assertValidIp()` before every SSH operation
|
|
110
|
+
- `sanitizedEnv` for subprocess calls
|
|
111
|
+
- `sanitizeResponseData()` whitelist approach for API error responses
|
|
112
|
+
- Config dir: user home `kastell/` directory (auto-migrated from legacy name)
|
|
113
|
+
- `PROVIDER_REGISTRY` = single source of truth for providers
|
|
114
|
+
- `withProviderErrorHandling` HOF for consistent provider error handling
|
|
115
|
+
- `describe.each` with `jest.resetAllMocks()` (not `clearAllMocks()`)
|
|
116
|
+
|
|
117
|
+
## Scripts (Deterministic)
|
|
118
|
+
|
|
119
|
+
Run without LLM — deterministic analysis scripts:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Parse audit JSON into 5 security domain summaries
|
|
123
|
+
kastell audit --server myserver --json > /tmp/audit.json
|
|
124
|
+
scripts/parse_audit.sh /tmp/audit.json
|
|
125
|
+
|
|
126
|
+
# Generate fleet-wide server score table
|
|
127
|
+
kastell fleet --json > /tmp/fleet.json
|
|
128
|
+
scripts/fleet_report.sh /tmp/fleet.json
|
|
129
|
+
|
|
130
|
+
# Compare audit check count vs test coverage
|
|
131
|
+
scripts/check_coverage.sh
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Reference Files
|
|
135
|
+
|
|
136
|
+
- 31 CLI commands — see [references/commands.md](references/commands.md)
|
|
137
|
+
- 13 MCP tools — see [references/mcp-tools.md](references/mcp-tools.md)
|
|
138
|
+
- Patterns and test templates — see [references/patterns.md](references/patterns.md)
|
|
139
|
+
- Known pitfalls — see [references/pitfalls.md](references/pitfalls.md)
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# Kastell CLI Commands (31)
|
|
2
|
-
|
|
3
|
-
All commands follow the thin wrapper pattern: parse args in `src/commands/`, delegate to `src/core/`.
|
|
4
|
-
|
|
5
|
-
| Command | Description | Key Arguments |
|
|
6
|
-
|-------------|------------------------------------------------------|--------------------------------------------|
|
|
7
|
-
| add | Add existing server to kastell config | --ip, --provider, --platform |
|
|
8
|
-
| audit | Security audit (30 categories, 457 checks) | --server, --category, --format, --explain |
|
|
9
|
-
| auth | Authenticate with a cloud provider | --provider |
|
|
10
|
-
| backup | Create a platform backup (DB + config files) | --server |
|
|
11
|
-
| completions | Generate shell completions | --shell (bash/zsh/fish) |
|
|
12
|
-
| config | View or edit kastell configuration | --edit |
|
|
13
|
-
| destroy | Destroy a cloud server permanently | --server, --force |
|
|
14
|
-
| doctor | Proactive health analysis and recommendations | --server |
|
|
15
|
-
| domain | Manage custom domains and SSL certificates | --server, --domain |
|
|
16
|
-
| evidence | Collect forensic evidence from server | --server |
|
|
17
|
-
| firewall | Manage server firewall rules | --server, --add, --remove, --list |
|
|
18
|
-
| fleet | Fleet-wide server visibility and status | --format |
|
|
19
|
-
| guard | Start/stop autonomous security daemon | --server, --start, --stop, --status |
|
|
20
|
-
| health | Check server and platform health | --server |
|
|
21
|
-
| init | Initialize kastell and provision first server | (interactive prompts) |
|
|
22
|
-
| interactive | Launch interactive TUI menu | (none) |
|
|
23
|
-
| list | List all configured servers | --format |
|
|
24
|
-
| lock | One-shot 24-step server hardening | --server |
|
|
25
|
-
| logs | View server or platform logs | --server, --lines, --service |
|
|
26
|
-
| maintain | Run maintenance tasks (updates, cleanup) | --server |
|
|
27
|
-
| monitor | Real-time server monitoring | --server |
|
|
28
|
-
| notify | Send notifications via configured channels | --channel, --message |
|
|
29
|
-
| remove | Remove server from kastell config | --server |
|
|
30
|
-
| restart | Restart server or platform services | --server |
|
|
31
|
-
| restore | Restore server from a previous backup | --server, --backup |
|
|
32
|
-
| secure | Set up SSH keys and firewall rules | --server |
|
|
33
|
-
| snapshot | Create, list, or restore server snapshots | --server, --list, --restore |
|
|
34
|
-
| ssh | Open interactive SSH session to server | --server |
|
|
35
|
-
| status | Display server status overview | --server |
|
|
36
|
-
| transfer | Transfer server configuration between providers | --server, --target-provider |
|
|
37
|
-
| update | Update server packages and platform | --server |
|
|
38
|
-
|
|
39
|
-
## Notes
|
|
40
|
-
|
|
41
|
-
- All commands validate input and delegate to `src/core/` — no business logic in commands
|
|
42
|
-
- Destructive commands (`destroy`, `lock`, `restore`) check `isSafeMode()` before executing
|
|
43
|
-
- Commands that need SSH call `assertValidIp()` before any SSH operation
|
|
44
|
-
- `--format` accepts `table` (default) and `json` for machine-readable output
|
|
45
|
-
- Provider-specific commands (`auth`, `list`, `fleet`) use `PROVIDER_REGISTRY` from `constants.ts`
|
|
1
|
+
# Kastell CLI Commands (31)
|
|
2
|
+
|
|
3
|
+
All commands follow the thin wrapper pattern: parse args in `src/commands/`, delegate to `src/core/`.
|
|
4
|
+
|
|
5
|
+
| Command | Description | Key Arguments |
|
|
6
|
+
|-------------|------------------------------------------------------|--------------------------------------------|
|
|
7
|
+
| add | Add existing server to kastell config | --ip, --provider, --platform |
|
|
8
|
+
| audit | Security audit (30 categories, 457 checks) | --server, --category, --format, --explain |
|
|
9
|
+
| auth | Authenticate with a cloud provider | --provider |
|
|
10
|
+
| backup | Create a platform backup (DB + config files) | --server |
|
|
11
|
+
| completions | Generate shell completions | --shell (bash/zsh/fish) |
|
|
12
|
+
| config | View or edit kastell configuration | --edit |
|
|
13
|
+
| destroy | Destroy a cloud server permanently | --server, --force |
|
|
14
|
+
| doctor | Proactive health analysis and recommendations | --server |
|
|
15
|
+
| domain | Manage custom domains and SSL certificates | --server, --domain |
|
|
16
|
+
| evidence | Collect forensic evidence from server | --server |
|
|
17
|
+
| firewall | Manage server firewall rules | --server, --add, --remove, --list |
|
|
18
|
+
| fleet | Fleet-wide server visibility and status | --format |
|
|
19
|
+
| guard | Start/stop autonomous security daemon | --server, --start, --stop, --status |
|
|
20
|
+
| health | Check server and platform health | --server |
|
|
21
|
+
| init | Initialize kastell and provision first server | (interactive prompts) |
|
|
22
|
+
| interactive | Launch interactive TUI menu | (none) |
|
|
23
|
+
| list | List all configured servers | --format |
|
|
24
|
+
| lock | One-shot 24-step server hardening | --server |
|
|
25
|
+
| logs | View server or platform logs | --server, --lines, --service |
|
|
26
|
+
| maintain | Run maintenance tasks (updates, cleanup) | --server |
|
|
27
|
+
| monitor | Real-time server monitoring | --server |
|
|
28
|
+
| notify | Send notifications via configured channels | --channel, --message |
|
|
29
|
+
| remove | Remove server from kastell config | --server |
|
|
30
|
+
| restart | Restart server or platform services | --server |
|
|
31
|
+
| restore | Restore server from a previous backup | --server, --backup |
|
|
32
|
+
| secure | Set up SSH keys and firewall rules | --server |
|
|
33
|
+
| snapshot | Create, list, or restore server snapshots | --server, --list, --restore |
|
|
34
|
+
| ssh | Open interactive SSH session to server | --server |
|
|
35
|
+
| status | Display server status overview | --server |
|
|
36
|
+
| transfer | Transfer server configuration between providers | --server, --target-provider |
|
|
37
|
+
| update | Update server packages and platform | --server |
|
|
38
|
+
|
|
39
|
+
## Notes
|
|
40
|
+
|
|
41
|
+
- All commands validate input and delegate to `src/core/` — no business logic in commands
|
|
42
|
+
- Destructive commands (`destroy`, `lock`, `restore`) check `isSafeMode()` before executing
|
|
43
|
+
- Commands that need SSH call `assertValidIp()` before any SSH operation
|
|
44
|
+
- `--format` accepts `table` (default) and `json` for machine-readable output
|
|
45
|
+
- Provider-specific commands (`auth`, `list`, `fleet`) use `PROVIDER_REGISTRY` from `constants.ts`
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
# Kastell MCP Tools (13)
|
|
2
|
-
|
|
3
|
-
All MCP tools are registered in `src/mcp/server.ts` and delegate to `src/core/` functions.
|
|
4
|
-
|
|
5
|
-
| Tool | File | Purpose | Key Parameters |
|
|
6
|
-
|------------------|----------------------|--------------------------------------------|---------------------------------------------|
|
|
7
|
-
| server_info | serverInfo.ts | Server list, status, health, sizes | action: list/status/health/sizes, server? |
|
|
8
|
-
| server_logs | serverLogs.ts | Logs and system metrics via SSH | server, lines?, service? |
|
|
9
|
-
| server_manage | serverManage.ts | Add/remove/destroy servers | action: add/remove/destroy, server |
|
|
10
|
-
| server_maintain | serverMaintain.ts | Update, restart, maintenance tasks | action: update/restart/maintain, server |
|
|
11
|
-
| server_secure | serverSecure.ts | SSH setup, firewall, domain management | action: secure/firewall/domain, server |
|
|
12
|
-
| server_backup | serverBackup.ts | Backup creation and snapshot management | action: backup/snapshot/restore, server |
|
|
13
|
-
| server_provision | serverProvision.ts | New server provisioning | provider, name, size, region |
|
|
14
|
-
| server_audit | serverAudit.ts | Security audit (30 categories, 457 checks) | server, category?, format? |
|
|
15
|
-
| server_lock | serverLock.ts | 24-step one-shot server hardening | server |
|
|
16
|
-
| server_evidence | serverEvidence.ts | Forensic evidence collection | server |
|
|
17
|
-
| server_guard | serverGuard.ts | Autonomous security daemon control | server, action: start/stop/status |
|
|
18
|
-
| server_doctor | serverDoctor.ts | Proactive health analysis | server |
|
|
19
|
-
| server_fleet | serverFleet.ts | Fleet-wide server visibility | format? |
|
|
20
|
-
|
|
21
|
-
## Routing Rules
|
|
22
|
-
|
|
23
|
-
All MCP tools follow this delegation chain:
|
|
24
|
-
```
|
|
25
|
-
MCP Client -> tool handler (Zod validation) -> src/core/ function -> result
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
**Tool handlers NEVER contain business logic.** They:
|
|
29
|
-
1. Validate input with Zod schema
|
|
30
|
-
2. Delegate to the corresponding `src/core/` function
|
|
31
|
-
3. Format the result as `{ content: [{ type: 'text', text: ... }] }`
|
|
32
|
-
|
|
33
|
-
## Annotations
|
|
34
|
-
|
|
35
|
-
Each tool registration in `server.ts` includes MCP annotations:
|
|
36
|
-
|
|
37
|
-
| Annotation | When to use | Examples |
|
|
38
|
-
|------------------|-----------------------------------------------------|-----------------------------------|
|
|
39
|
-
| readOnlyHint | Tool reads data, no side effects | server_info (list/status/health) |
|
|
40
|
-
| destructiveHint | Tool causes irreversible changes | server_manage (destroy), server_lock |
|
|
41
|
-
| idempotentHint | Safe to call multiple times with same result | server_audit, server_health |
|
|
42
|
-
|
|
43
|
-
## Error Handling
|
|
44
|
-
|
|
45
|
-
On error, tools return:
|
|
46
|
-
```typescript
|
|
47
|
-
{ content: [{ type: 'text', text: errorMessage }], isError: true }
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Never throw from tool handlers — all errors must be caught and returned as structured error content.
|
|
1
|
+
# Kastell MCP Tools (13)
|
|
2
|
+
|
|
3
|
+
All MCP tools are registered in `src/mcp/server.ts` and delegate to `src/core/` functions.
|
|
4
|
+
|
|
5
|
+
| Tool | File | Purpose | Key Parameters |
|
|
6
|
+
|------------------|----------------------|--------------------------------------------|---------------------------------------------|
|
|
7
|
+
| server_info | serverInfo.ts | Server list, status, health, sizes | action: list/status/health/sizes, server? |
|
|
8
|
+
| server_logs | serverLogs.ts | Logs and system metrics via SSH | server, lines?, service? |
|
|
9
|
+
| server_manage | serverManage.ts | Add/remove/destroy servers | action: add/remove/destroy, server |
|
|
10
|
+
| server_maintain | serverMaintain.ts | Update, restart, maintenance tasks | action: update/restart/maintain, server |
|
|
11
|
+
| server_secure | serverSecure.ts | SSH setup, firewall, domain management | action: secure/firewall/domain, server |
|
|
12
|
+
| server_backup | serverBackup.ts | Backup creation and snapshot management | action: backup/snapshot/restore, server |
|
|
13
|
+
| server_provision | serverProvision.ts | New server provisioning | provider, name, size, region |
|
|
14
|
+
| server_audit | serverAudit.ts | Security audit (30 categories, 457 checks) | server, category?, format? |
|
|
15
|
+
| server_lock | serverLock.ts | 24-step one-shot server hardening | server |
|
|
16
|
+
| server_evidence | serverEvidence.ts | Forensic evidence collection | server |
|
|
17
|
+
| server_guard | serverGuard.ts | Autonomous security daemon control | server, action: start/stop/status |
|
|
18
|
+
| server_doctor | serverDoctor.ts | Proactive health analysis | server |
|
|
19
|
+
| server_fleet | serverFleet.ts | Fleet-wide server visibility | format? |
|
|
20
|
+
|
|
21
|
+
## Routing Rules
|
|
22
|
+
|
|
23
|
+
All MCP tools follow this delegation chain:
|
|
24
|
+
```
|
|
25
|
+
MCP Client -> tool handler (Zod validation) -> src/core/ function -> result
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Tool handlers NEVER contain business logic.** They:
|
|
29
|
+
1. Validate input with Zod schema
|
|
30
|
+
2. Delegate to the corresponding `src/core/` function
|
|
31
|
+
3. Format the result as `{ content: [{ type: 'text', text: ... }] }`
|
|
32
|
+
|
|
33
|
+
## Annotations
|
|
34
|
+
|
|
35
|
+
Each tool registration in `server.ts` includes MCP annotations:
|
|
36
|
+
|
|
37
|
+
| Annotation | When to use | Examples |
|
|
38
|
+
|------------------|-----------------------------------------------------|-----------------------------------|
|
|
39
|
+
| readOnlyHint | Tool reads data, no side effects | server_info (list/status/health) |
|
|
40
|
+
| destructiveHint | Tool causes irreversible changes | server_manage (destroy), server_lock |
|
|
41
|
+
| idempotentHint | Safe to call multiple times with same result | server_audit, server_health |
|
|
42
|
+
|
|
43
|
+
## Error Handling
|
|
44
|
+
|
|
45
|
+
On error, tools return:
|
|
46
|
+
```typescript
|
|
47
|
+
{ content: [{ type: 'text', text: errorMessage }], isError: true }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Never throw from tool handlers — all errors must be caught and returned as structured error content.
|